PageRenderTime 56ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/ATF2/control-software/epics-3.14.10/extensions/src/edm/edmMain/main.cc

http://atf2flightsim.googlecode.com/
C++ | 2467 lines | 1781 code | 596 blank | 90 comment | 408 complexity | 9c8f39cdf27c166d681935769ad7d4ef MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. // edm - extensible display manager
  2. // Copyright (C) 1999 John W. Sinclair
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program; if not, write to the Free Software
  13. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. #include <sys/types.h>
  15. #include <sys/ioctl.h>
  16. #include <sys/socket.h>
  17. #include <arpa/inet.h>
  18. #include <netinet/in.h>
  19. #include <netdb.h>
  20. #include <errno.h>
  21. #include <signal.h>
  22. #include <setjmp.h>
  23. #include <unistd.h>
  24. #include <sys/types.h>
  25. #include <sys/ioctl.h>
  26. #include <sys/socket.h>
  27. #include <arpa/inet.h>
  28. #include <netinet/in.h>
  29. #include <netinet/tcp.h>
  30. #define FD_TABLE_SIZE getdtablesize()
  31. #include <X11/Xlib.h>
  32. #include <X11/Xlocale.h>
  33. #include <Xm/Xm.h>
  34. #include <Xm/MainW.h>
  35. #include <Xm/BulletinB.h>
  36. #include <Xm/DrawingA.h>
  37. #include <Xm/PushB.h>
  38. #include <Xm/Label.h>
  39. #include <Xm/Frame.h>
  40. #include <Xm/RowColumn.h>
  41. #include "pv_factory.h"
  42. #include "color_pkg.h"
  43. #include "color_button.h"
  44. #include "font_pkg.h"
  45. #include "font_menu.h"
  46. #include "gc_pkg.h"
  47. #include "entry_form.h"
  48. #include "process.h"
  49. #include "app_pkg.h"
  50. #include "act_win.h"
  51. #include "act_grf.h"
  52. #include "bindings.h"
  53. #include "utility.h"
  54. #include "crawler.h"
  55. #include "lookup.h"
  56. #include "sys_types.h"
  57. #include "thread.h"
  58. #include "main.str"
  59. void setServerSocketFd (
  60. int fd
  61. );
  62. typedef struct main_node_tag { /* locked queue node */
  63. void *flink;
  64. void *blink;
  65. char msg[255+1];
  66. } MAIN_NODE_TYPE, *MAIN_NODE_PTR;
  67. typedef struct main_que_tag { /* locked queue header */
  68. void *flink;
  69. void *blink;
  70. void *lock;
  71. char msg[255+1];
  72. } MAIN_QUE_TYPE, *MAIN_QUE_PTR;
  73. #define REMQHI( queue, buf, flag )\
  74. sys_remqh( (void *) (queue), (void **) (buf), (int) (flag) )
  75. #define INSQTI( buf, queue, flag )\
  76. sys_insqt( (void *) (buf), (void *) (queue), (int) (flag) )
  77. #define QUEWASEMP SYS_QUEWASEMP
  78. #define ONEENTQUE SYS_ONEENTQUE
  79. #define MAIN_QUEUE_SIZE 200
  80. #define DONE -1
  81. #define SWITCHES 1
  82. #define FILES 2
  83. // remote one-byte command type
  84. // (no future command type value may be 10 - '\n' is control char)
  85. #define QUERY_LOAD 1
  86. #define CONNECT 2
  87. #define OPEN_INITIAL 3
  88. #define OPEN 4
  89. typedef struct argsTag {
  90. int argc;
  91. char **argv;
  92. appContextClass *appCtxPtr;
  93. } argsType, *argsPtr;
  94. typedef struct appListTag {
  95. struct appListTag *flink;
  96. struct appListTag *blink;
  97. argsPtr appArgs;
  98. } appListType, *appListPtr;
  99. static MAIN_QUE_TYPE g_mainFreeQueue, g_mainActiveQueue;
  100. static MAIN_NODE_TYPE g_mainNodes[MAIN_QUEUE_SIZE];
  101. static int g_numClients = 0;
  102. static int g_pidNum = 0;
  103. static char g_restartId[31+1];
  104. //#include "alloc.h"
  105. #ifdef DIAGNOSTIC_ALLOC
  106. int z=2, zz=0;
  107. #endif
  108. #define MAX_X_ERRORS 100
  109. static int xErrorHandler (
  110. Display *d,
  111. XErrorEvent *err )
  112. {
  113. char msg[80];
  114. static int num = 0;
  115. if ( num > MAX_X_ERRORS ) {
  116. return 0;
  117. }
  118. else if ( num == MAX_X_ERRORS ) {
  119. num++;
  120. fprintf( stderr, "Too many X errors\n" );
  121. return 0;
  122. }
  123. num++;
  124. if ( err->error_code != BadAccess ) {
  125. XGetErrorText( d, err->error_code, msg, 80 );
  126. fprintf( stderr, main_str1, err->error_code, msg );
  127. }
  128. return 0;
  129. }
  130. void xtErrorHandler (
  131. char *msg )
  132. {
  133. static int num = 0;
  134. if ( num > MAX_X_ERRORS ) {
  135. return;
  136. }
  137. else if ( num == MAX_X_ERRORS ) {
  138. num++;
  139. fprintf( stderr, "Too many Xt errors\n" );
  140. return;
  141. }
  142. num++;
  143. if ( !strcmp( msg,
  144. "XtPopdown requires a subclass of shellWidgetClass" ) ) {
  145. return;
  146. }
  147. fprintf( stderr, "xtErrorHandler - %s\n", msg );
  148. }
  149. static void getCheckPointFileNamefromPID (
  150. char *checkPointFileName
  151. ) {
  152. char procIdName[31+1], *envPtr;
  153. SYS_PROC_ID_TYPE procId;
  154. envPtr = getenv( environment_str8 );
  155. if ( envPtr ) {
  156. strncpy( checkPointFileName, envPtr, 255 );
  157. if ( envPtr[strlen(envPtr)] != '/' ) {
  158. Strncat( checkPointFileName, "/", 255 );
  159. }
  160. }
  161. else {
  162. strncpy( checkPointFileName, "/tmp/", 255 );
  163. }
  164. Strncat( checkPointFileName, "edmCheckPointFile_", 255 );
  165. sys_get_proc_id( &procId );
  166. sprintf( procIdName, "%-d", (int) procId.id );
  167. Strncat( checkPointFileName, procIdName, 255 );
  168. //fprintf( stderr, "[%s]\n", checkPointFileName );
  169. }
  170. static void getCheckPointFileName (
  171. char *checkPointFileName,
  172. char *procIdName
  173. ) {
  174. char *envPtr;
  175. envPtr = getenv( environment_str8 );
  176. if ( envPtr ) {
  177. strncpy( checkPointFileName, envPtr, 255 );
  178. if ( envPtr[strlen(envPtr)] != '/' ) {
  179. Strncat( checkPointFileName, "/", 255 );
  180. }
  181. }
  182. else {
  183. strncpy( checkPointFileName, "/tmp/", 255 );
  184. }
  185. Strncat( checkPointFileName, "edmCheckPointFile_", 255 );
  186. Strncat( checkPointFileName, procIdName, 255 );
  187. //fprintf( stderr, "%-d, [%s]\n", g_pidNum, checkPointFileName );
  188. }
  189. static int getMainCheckPointParams (
  190. FILE *f,
  191. int *server,
  192. int *oneInstance,
  193. char *displayName,
  194. int *noEdit,
  195. int *numCheckPointMacros,
  196. char *checkPointMacros
  197. ) {
  198. char *cptr, *tk, *buf1;
  199. char text[1023+1];
  200. int i, tmp;
  201. *server = 0;
  202. *oneInstance = 0;
  203. strcpy( displayName, "" );
  204. *numCheckPointMacros = 0;
  205. strcpy( checkPointMacros, "" );
  206. cptr = fgets( text, 1023, f );
  207. text[1024] = 0;
  208. if ( !cptr ) return 2; // fail
  209. if ( strcmp( text, "<<<EOD>>>\n" ) == 0 ) return 3; // no more data
  210. tmp = atol( text );
  211. *server = tmp & 0xf;
  212. *oneInstance = ( tmp >> 8 );
  213. readStringFromFile( displayName, 127, f );
  214. cptr = fgets( text, 1023, f );
  215. text[1024] = 0;
  216. if ( !cptr ) return 2; // fail
  217. *noEdit = atol( text );
  218. cptr = fgets( text, 1023, f );
  219. text[1024] = 0;
  220. if ( !cptr ) return 2; // fail
  221. *numCheckPointMacros = atol( text );
  222. for ( i=0; i<*numCheckPointMacros; i++ ) {
  223. cptr = fgets( text, 1023, f );
  224. text[1024] = 0;
  225. if ( !cptr ) return 2; // fail
  226. buf1 = NULL;
  227. tk = strtok_r( text, "\n \t", &buf1 );
  228. if ( i > 0 ) {
  229. Strncat( checkPointMacros, ",", 1023 );
  230. checkPointMacros[1023] = 0;
  231. }
  232. Strncat( checkPointMacros, tk, 1023 );
  233. checkPointMacros[1023] = 0;
  234. }
  235. return 1;
  236. }
  237. static int getNumCheckPointScreens (
  238. FILE *f
  239. ) {
  240. char text[32], *cptr;
  241. int n;
  242. cptr = fgets( text, 31, f );
  243. if ( !cptr ) return 0; // fail
  244. text[31] = 0;
  245. n = atol( text );
  246. return n;
  247. }
  248. static int getScreenCheckPointParams (
  249. FILE *f,
  250. char *screenName,
  251. int *x,
  252. int *y,
  253. int *icon,
  254. int *noEdit,
  255. int *numCheckPointMacros,
  256. char *checkPointMacros
  257. ) {
  258. char *cptr, *tk, *buf1;
  259. char text[1023+1];
  260. int i;
  261. strcpy( screenName, "" );
  262. *x = 0;
  263. *y = 0;
  264. *icon = 0;
  265. *numCheckPointMacros = 0;
  266. strcpy( checkPointMacros, "" );
  267. readStringFromFile( screenName, 255, f );
  268. cptr = fgets( text, 1023, f );
  269. text[1024] = 0;
  270. if ( !cptr ) return 2; // fail
  271. *x = atol( text );
  272. cptr = fgets( text, 1023, f );
  273. text[1024] = 0;
  274. if ( !cptr ) return 2; // fail
  275. *y = atol( text );
  276. cptr = fgets( text, 1023, f );
  277. text[1024] = 0;
  278. if ( !cptr ) return 2; // fail
  279. *icon = atol( text );
  280. cptr = fgets( text, 1023, f );
  281. text[1024] = 0;
  282. if ( !cptr ) return 2; // fail
  283. *noEdit = atol( text );
  284. cptr = fgets( text, 1023, f );
  285. text[1024] = 0;
  286. if ( !cptr ) return 2; // fail
  287. *numCheckPointMacros = atol( text );
  288. for ( i=0; i<*numCheckPointMacros; i++ ) {
  289. cptr = fgets( text, 1023, f );
  290. text[1024] = 0;
  291. if ( !cptr ) return 2; // fail
  292. buf1 = NULL;
  293. tk = strtok_r( text, "\n \t", &buf1 );
  294. if ( i > 0 ) {
  295. Strncat( checkPointMacros, ",", 1023 );
  296. checkPointMacros[1023] = 0;
  297. }
  298. Strncat( checkPointMacros, tk, 1023 );
  299. checkPointMacros[1023] = 0;
  300. }
  301. return 1;
  302. }
  303. static int sendCmd (
  304. int socketFd,
  305. char *msg,
  306. int len
  307. ) {
  308. struct timeval timeout;
  309. int more, fd, i, remain;
  310. fd_set fds;
  311. timeout.tv_sec = 5;
  312. timeout.tv_usec = 0;
  313. more = 1;
  314. i = 0;
  315. remain = len;
  316. while ( more ) {
  317. FD_ZERO( &fds );
  318. FD_SET( socketFd, &fds );
  319. fd = select( getdtablesize(), (fd_set *) NULL, &fds,
  320. (fd_set *) NULL, &timeout );
  321. if ( fd == 0 ) { /* timeout */
  322. /* fprintf( stderr, "timeout\n" ); */
  323. return 0;
  324. }
  325. if ( fd < 0 ) { /* error */
  326. //perror( "select" );
  327. return 0;
  328. }
  329. len = write( socketFd, &msg[i], remain );
  330. if ( len < 1 ) return len;
  331. remain -= len;
  332. i += len;
  333. if ( remain < 1 ) more = 0;
  334. } while ( more );
  335. return i;
  336. }
  337. static int getReply (
  338. int socketFd,
  339. char *msg,
  340. int maxLen
  341. ) {
  342. struct timeval timeout;
  343. int more, fd, i, ii, remain, len;
  344. fd_set fds;
  345. timeout.tv_sec = 10;
  346. timeout.tv_usec = 0;
  347. more = 1;
  348. i = 0;
  349. remain = maxLen;
  350. while ( more ) {
  351. FD_ZERO( &fds );
  352. FD_SET( socketFd, &fds );
  353. fd = select( getdtablesize(), &fds, (fd_set *) NULL,
  354. (fd_set *) NULL, &timeout );
  355. if ( fd == 0 ) { /* timeout */
  356. return 0;
  357. }
  358. if ( fd < 0 ) { /* error */
  359. //perror( "select" );
  360. return 0;
  361. }
  362. strcpy( msg, "" );
  363. len = read( socketFd, &msg[i], remain );
  364. if ( len < 0 ) return len; // error
  365. if ( len == 0 ) return i; // return total chars read
  366. msg[len] = 0;
  367. for ( ii=0; ii<len; ii++ ) {
  368. if ( msg[i+ii] == '\n' ) {
  369. msg[i+ii] = 0;
  370. len = strlen(msg);
  371. i += len;
  372. more = 0;
  373. break;
  374. }
  375. }
  376. if ( more ) {
  377. remain -= len;
  378. i += len;
  379. if ( remain <= 0 ) return 0;
  380. }
  381. } while ( more );
  382. return i;
  383. }
  384. int getHostAddr (
  385. char *name,
  386. int *addr )
  387. {
  388. struct hostent *entry;
  389. char *tk, *buf;
  390. *addr = 0;
  391. tk = strtok_r( name, ":,", &buf );
  392. if ( !tk ) tk = name;
  393. entry = gethostbyname( tk );
  394. if ( entry->h_length != 4 ) return -1;
  395. *addr = *( (int *) (entry->h_addr_list)[0] );
  396. return 0;
  397. }
  398. void checkForServer (
  399. int argc,
  400. char **argv,
  401. int portNum,
  402. int appendDisplay,
  403. char *displayName,
  404. int oneInstance,
  405. int openCmd )
  406. {
  407. char chkHost[31+1], host[31+1], buf[511+1];
  408. int i, len, pos, max, argCount, stat, item, useItem;
  409. const int MAX_MSG_LEN = 256;
  410. char msg[MAX_MSG_LEN+1];
  411. SYS_TIME_TYPE timeout;
  412. char *envPtr, *tk1, *tk2, *buf1, *buf2;
  413. double merit, min, num;
  414. struct sockaddr_in s;
  415. int ip_addr, sockfd;
  416. unsigned short port_num;
  417. int value, n, nIn, nOut;
  418. envPtr = getenv( "EDMSERVERS" );
  419. if ( !envPtr ) {
  420. stat = gethostname( host, 31 );
  421. if ( stat ) return;
  422. envPtr = host;
  423. }
  424. if ( appendDisplay ) {
  425. argCount = argc + 2; // we will add two parameters below
  426. }
  427. else {
  428. argCount = argc;
  429. }
  430. stat = sys_cvt_seconds_to_timeout( 10.0, &timeout );
  431. if ( !( stat & 1 ) ) {
  432. fprintf( stderr, main_str3 );
  433. return;
  434. }
  435. // do simple load balancing
  436. strncpy( buf, envPtr, 511 );
  437. buf[511] = 0;
  438. tk1 = strtok_r( buf, ",", &buf1 );
  439. if ( tk1 ) {
  440. strncpy( host, tk1, 31 );
  441. host[31] = 0;
  442. min = -1;
  443. useItem = 1;
  444. }
  445. item = 1;
  446. while ( tk1 ) {
  447. strncpy( chkHost, tk1, 31 );
  448. chkHost[31] = 0;
  449. merit = 1.0;
  450. // use msg as a tmp buffer
  451. strncpy( msg, tk1, 254 );
  452. msg[254] = 0;
  453. tk2 = strtok_r( msg, ":", &buf2 );
  454. if ( tk2 ) {
  455. strncpy( chkHost, tk2, 31 );
  456. tk2 = strtok_r( NULL, ":", &buf2 );
  457. if ( tk2 ) {
  458. merit = atof( tk2 );
  459. if ( merit <= 0.0 ) merit = 1.0;
  460. }
  461. }
  462. //fprintf( stderr, "Checking host [%s], merit = %-f\n", chkHost, merit );
  463. stat = getHostAddr( chkHost, &ip_addr );
  464. if ( stat ) return;
  465. sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  466. if ( sockfd == -1 ) {
  467. //perror( "" );
  468. return;
  469. }
  470. {
  471. int flags, status;
  472. flags = fcntl( sockfd, F_GETFD );
  473. if ( flags >= 0 ) {
  474. status = fcntl( sockfd, F_SETFD, flags | FD_CLOEXEC );
  475. }
  476. }
  477. value = 1;
  478. len = sizeof(value);
  479. stat = setsockopt( sockfd, SOL_SOCKET, SO_KEEPALIVE,
  480. &value, len );
  481. port_num = (unsigned short) portNum;
  482. port_num = htons( port_num );
  483. memset( (char *) &s, 0, sizeof(s) );
  484. s.sin_family = AF_INET;
  485. s.sin_addr.s_addr = ip_addr;
  486. s.sin_port = port_num;
  487. stat = connect( sockfd, (struct sockaddr *) &s, sizeof(s) );
  488. if ( stat ) {
  489. //perror( "connect" );
  490. close( sockfd );
  491. goto abortClose;
  492. }
  493. //fprintf( stderr, "connected\n" );
  494. msg[0] = (char) QUERY_LOAD;
  495. msg[1] = '\n';
  496. msg[2] = 0;
  497. nOut = sendCmd( sockfd, msg, 2 );
  498. if ( !nOut ) {
  499. goto nextHost;
  500. }
  501. strcpy( msg, "" );
  502. nIn = getReply( sockfd, msg, 255 );
  503. sscanf( msg, "%d", &n );
  504. //fprintf( stderr, "nIn = %-d, reply = %-d\n", nIn, n );
  505. if ( !nIn ) {
  506. goto nextHost;
  507. }
  508. num = (double) n / merit;
  509. if ( ( num < min ) || ( min == -1 ) ) {
  510. min = num;
  511. strncpy( host, chkHost, 31 );
  512. host[31] = 0;
  513. useItem = item;
  514. }
  515. //fprintf( stderr, "min = %-f, adj num = %-f\n", min, num );
  516. nextHost:
  517. // don't check status, we're probably already disconnected
  518. stat = shutdown( sockfd, 2 );
  519. stat = close( sockfd );
  520. item++;
  521. tk1 = strtok_r( NULL, ",", &buf1 );
  522. }
  523. //fprintf( stderr, "Using host [%s], item %-d\n", host, useItem );
  524. stat = getHostAddr( host, &ip_addr );
  525. if ( stat ) return;
  526. sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  527. if ( sockfd == -1 ) {
  528. //perror( "" );
  529. return;
  530. }
  531. {
  532. int flags, status;
  533. flags = fcntl( sockfd, F_GETFD );
  534. if ( flags >= 0 ) {
  535. status = fcntl( sockfd, F_SETFD, flags | FD_CLOEXEC );
  536. }
  537. }
  538. value = 1;
  539. len = sizeof(value);
  540. stat = setsockopt( sockfd, SOL_SOCKET, SO_KEEPALIVE,
  541. &value, len );
  542. port_num = (unsigned short) portNum;
  543. port_num = htons( port_num );
  544. memset( (char *) &s, 0, sizeof(s) );
  545. s.sin_family = AF_INET;
  546. s.sin_addr.s_addr = ip_addr;
  547. s.sin_port = port_num;
  548. stat = connect( sockfd, (struct sockaddr *) &s, sizeof(s) );
  549. if ( stat ) {
  550. //perror( "connect" );
  551. close( sockfd );
  552. goto abortClose;
  553. }
  554. //fprintf( stderr, "connected\n" );
  555. msg[MAX_MSG_LEN] = 0;
  556. if ( oneInstance ) {
  557. if ( openCmd ) {
  558. msg[0] = (char) OPEN;
  559. pos = 1;
  560. max = MAX_MSG_LEN - pos;
  561. strncpy( &msg[pos], "*OPN*|", max );
  562. pos = strlen(msg);
  563. max = MAX_MSG_LEN - pos;
  564. }
  565. else {
  566. msg[0] = (char) OPEN_INITIAL;
  567. pos = 1;
  568. max = MAX_MSG_LEN - pos;
  569. strncpy( &msg[pos], "*OIS*|", max );
  570. pos = strlen(msg);
  571. max = MAX_MSG_LEN - pos;
  572. }
  573. strncpy( &msg[pos], displayName, max );
  574. pos = strlen(msg);
  575. max = MAX_MSG_LEN - pos;
  576. strncpy( &msg[pos], "|", max );
  577. pos = strlen(msg);
  578. max = MAX_MSG_LEN - pos;
  579. snprintf( &msg[pos], max, "%-d|", argCount );
  580. pos = strlen(msg);
  581. max = MAX_MSG_LEN - pos;
  582. strncpy( &msg[pos], "edm|", max );
  583. pos = strlen(msg);
  584. max = MAX_MSG_LEN - pos;
  585. if ( appendDisplay ) {
  586. strncpy( &msg[pos], global_str56, max );
  587. pos = strlen(msg);
  588. max = MAX_MSG_LEN - pos;
  589. strncpy( &msg[pos], displayName, max );
  590. pos = strlen(msg);
  591. max = MAX_MSG_LEN - pos;
  592. Strncat( &msg[pos], "|", max );
  593. pos = strlen(msg);
  594. max = MAX_MSG_LEN - pos;
  595. }
  596. for ( i=1; i<argc; i++ ) {
  597. strncpy( &msg[pos], argv[i], max );
  598. pos = strlen(msg);
  599. max = MAX_MSG_LEN - pos;
  600. Strncat( &msg[pos], "|", max );
  601. pos = strlen(msg);
  602. max = MAX_MSG_LEN - pos;
  603. }
  604. }
  605. else {
  606. msg[0] = (char) CONNECT;
  607. pos = 1;
  608. max = MAX_MSG_LEN - pos;
  609. snprintf( &msg[pos], max, "%-d|", argCount );
  610. pos = strlen(msg);
  611. max = MAX_MSG_LEN - pos;
  612. strncpy( &msg[pos], "edm|", max );
  613. pos = strlen(msg);
  614. max = MAX_MSG_LEN - pos;
  615. if ( appendDisplay ) {
  616. strncpy( &msg[pos], global_str56, max );
  617. pos = strlen(msg);
  618. max = MAX_MSG_LEN - pos;
  619. strncpy( &msg[pos], displayName, max );
  620. pos = strlen(msg);
  621. max = MAX_MSG_LEN - pos;
  622. Strncat( &msg[pos], "|", max );
  623. pos = strlen(msg);
  624. max = MAX_MSG_LEN - pos;
  625. }
  626. for ( i=1; i<argc; i++ ) {
  627. strncpy( &msg[pos], argv[i], max );
  628. pos = strlen(msg);
  629. max = MAX_MSG_LEN - pos;
  630. Strncat( &msg[pos], "|", max );
  631. pos = strlen(msg);
  632. max = MAX_MSG_LEN - pos;
  633. }
  634. }
  635. Strncat( msg, "\n", MAX_MSG_LEN );
  636. if ( strlen(msg) == MAX_MSG_LEN ) {
  637. fprintf( stderr, "Message length exceeded - abort\n" );
  638. stat = shutdown( sockfd, 2 );
  639. stat = close( sockfd );
  640. exit(1);
  641. }
  642. nOut = sendCmd( sockfd, msg, strlen(msg) );
  643. if ( !nOut ) {
  644. goto abort;
  645. }
  646. // don't check status, we're probably already disconnected
  647. stat = shutdown( sockfd, 2 );
  648. stat = close( sockfd );
  649. exit(0);
  650. abort:
  651. stat = shutdown( sockfd, 2 );
  652. abortClose:
  653. stat = close( sockfd );
  654. return;
  655. }
  656. static int reply (
  657. int socketFd,
  658. char *msg,
  659. int len
  660. ) {
  661. struct timeval timeout;
  662. int more, fd, i, remain;
  663. fd_set fds;
  664. timeout.tv_sec = 5;
  665. timeout.tv_usec = 0;
  666. more = 1;
  667. i = 0;
  668. remain = len;
  669. while ( more ) {
  670. FD_ZERO( &fds );
  671. FD_SET( socketFd, &fds );
  672. fd = select( FD_TABLE_SIZE, (fd_set *) NULL, &fds,
  673. (fd_set *) NULL, &timeout );
  674. if ( fd == 0 ) { /* timeout */
  675. /* fprintf( stderr, "timeout\n" ); */
  676. return 0;
  677. }
  678. if ( fd < 0 ) { /* error */
  679. perror( "select" );
  680. return 0;
  681. }
  682. len = write( socketFd, &msg[i], remain );
  683. if ( len < 1 ) return len; /* error */
  684. remain -= len;
  685. i += len;
  686. if ( remain < 1 ) more = 0;
  687. } while ( more );
  688. return i;
  689. }
  690. static int getCommand (
  691. int socketFd,
  692. char *msg,
  693. int maxLen
  694. ) {
  695. struct timeval timeout;
  696. int more, i, ii, remain, len, count, n;
  697. fd_set fds;
  698. timeout.tv_sec = 5;
  699. timeout.tv_usec = 0;
  700. more = 1;
  701. i = count = 0;
  702. remain = maxLen;
  703. while ( more ) {
  704. /* fprintf( stderr, "socketFd = %-d\n", socketFd ); */
  705. FD_ZERO( &fds );
  706. FD_SET( socketFd, &fds );
  707. n = select( FD_TABLE_SIZE, &fds, (fd_set *) NULL,
  708. (fd_set *) NULL, &timeout );
  709. if ( n == 0 ) { /* timeout */
  710. return 0;
  711. }
  712. if ( n < 0 ) { /* error */
  713. perror( "select" );
  714. return n;
  715. }
  716. strcpy( msg, "" );
  717. len = read( socketFd, &msg[i], remain );
  718. if ( len < 0 ) return len; // error
  719. if ( len == 0 ) return i; // return total chars read
  720. for ( ii=0; ii<len; ii++ ) {
  721. if ( msg[i+ii] == '\n' ) {
  722. msg[i+ii] = 0;
  723. len = strlen(msg);
  724. more = 0;
  725. break;
  726. }
  727. }
  728. if ( more ) {
  729. remain -= len;
  730. i += len;
  731. if ( remain <= 0 ) return 0;
  732. }
  733. } while ( more );
  734. return len;
  735. }
  736. #ifdef __linux__
  737. void *caPendThread (
  738. THREAD_HANDLE h )
  739. {
  740. #endif
  741. #ifdef darwin
  742. void *caPendThread (
  743. THREAD_HANDLE h )
  744. {
  745. #endif
  746. #ifdef __solaris__
  747. void *caPendThread (
  748. THREAD_HANDLE h )
  749. {
  750. #endif
  751. #ifdef __osf__
  752. void caPendThread (
  753. THREAD_HANDLE h )
  754. {
  755. #endif
  756. #ifdef HP_UX
  757. void *caPendThread (
  758. THREAD_HANDLE h )
  759. {
  760. #endif
  761. int stat;
  762. do {
  763. stat = pend_io( 5.0 );
  764. stat = pend_event( 0.05 );
  765. } while ( 1 );
  766. return 0;
  767. }
  768. #ifdef __linux__
  769. void *serverThread (
  770. THREAD_HANDLE h )
  771. {
  772. #endif
  773. #ifdef darwin
  774. void *serverThread (
  775. THREAD_HANDLE h )
  776. {
  777. #endif
  778. #ifdef __solaris__
  779. void *serverThread (
  780. THREAD_HANDLE h )
  781. {
  782. #endif
  783. #ifdef __osf__
  784. void serverThread (
  785. THREAD_HANDLE h )
  786. {
  787. #endif
  788. #ifdef HP_UX
  789. void *serverThread (
  790. THREAD_HANDLE h )
  791. {
  792. #endif
  793. int value, stat, n, n_in, q_stat_r, q_stat_i;
  794. THREAD_HANDLE delayH;
  795. MAIN_NODE_PTR node;
  796. SYS_TIME_TYPE timeout;
  797. int len, num, cmd;
  798. char msg[255+1], msg1[255+1];
  799. struct sockaddr_in s, cli_s;
  800. int sockfd, newsockfd, more;
  801. unsigned short port_num;
  802. #ifdef HPUX
  803. int cliLen;
  804. #else
  805. socklen_t cliLen;
  806. #endif
  807. int *portNumPtr = (int *) thread_get_app_data( h );
  808. stat = thread_create_handle( &delayH, NULL );
  809. stat = sys_cvt_seconds_to_timeout( 10.0, &timeout );
  810. if ( !( stat & 1 ) ) {
  811. fprintf( stderr, main_str3 );
  812. goto err_return;
  813. }
  814. n = 0;
  815. while ( 1 ) {
  816. sockfd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  817. if ( sockfd == -1 ) {
  818. perror( "socket" );
  819. goto err_return;
  820. }
  821. {
  822. int flags, status;
  823. flags = fcntl( sockfd, F_GETFD );
  824. if ( flags >= 0 ) {
  825. status = fcntl( sockfd, F_SETFD, flags | FD_CLOEXEC );
  826. }
  827. }
  828. value = 1;
  829. len = sizeof(value);
  830. stat = setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR,
  831. &value, len );
  832. if ( sockfd == -1 ) {
  833. perror( "setsockopt" );
  834. goto err_return;
  835. }
  836. port_num = (unsigned short) *portNumPtr;
  837. port_num = htons( port_num );
  838. memset( (char *) &s, 0, sizeof(s) );
  839. s.sin_family = AF_INET;
  840. s.sin_addr.s_addr = htonl(INADDR_ANY);
  841. s.sin_port = port_num;
  842. /* do bind and listen */
  843. stat = bind( sockfd, (struct sockaddr*) &s, sizeof(s) );
  844. if ( stat < 0 ) {
  845. perror( "bind" );
  846. goto err_return;
  847. }
  848. stat = listen( sockfd, 5 );
  849. if ( stat < 0 ) {
  850. perror( "listen" );
  851. goto err_return;
  852. }
  853. setServerSocketFd( sockfd );
  854. more = 1;
  855. while ( more ) {
  856. /*fprintf( stderr, "sockfd = %-d\n", sockfd ); */
  857. /* accept connection */
  858. cliLen = sizeof(cli_s);
  859. newsockfd = accept( sockfd, (struct sockaddr *) &cli_s,
  860. &cliLen );
  861. if ( newsockfd < 0 ) {
  862. perror( "accept" );
  863. goto err_branch;
  864. }
  865. n = getCommand( newsockfd, msg, 255 );
  866. if ( n ) {
  867. cmd = (int) msg[0];
  868. switch ( cmd ) {
  869. case OPEN_INITIAL:
  870. case OPEN:
  871. stat = thread_lock_master( h );
  872. q_stat_r = REMQHI( (void *) &g_mainFreeQueue, (void **) &node, 0 );
  873. if ( q_stat_r & 1 ) {
  874. strncpy( node->msg, &msg[1], 254 );
  875. q_stat_i = INSQTI( (void *) node, (void *) &g_mainActiveQueue, 0 );
  876. if ( !( q_stat_i & 1 ) ) {
  877. fprintf( stderr, main_str17 );
  878. }
  879. }
  880. else {
  881. fprintf( stderr, main_str18 );
  882. }
  883. stat = thread_unlock_master( h );
  884. break;
  885. case QUERY_LOAD:
  886. stat = thread_lock_master( h );
  887. num = g_numClients;
  888. stat = thread_unlock_master( h );
  889. snprintf( msg1, 255, "%-d\n", num );
  890. n_in = reply( newsockfd, msg1, strlen(msg1) );
  891. if ( n_in < 1 ) {
  892. fprintf( stderr, main_str44 );
  893. }
  894. break;
  895. case CONNECT:
  896. stat = thread_lock_master( h );
  897. q_stat_r = REMQHI( (void *) &g_mainFreeQueue, (void **) &node, 0 );
  898. if ( q_stat_r & 1 ) {
  899. n++;
  900. strncpy( node->msg, &msg[1], 254 );
  901. q_stat_i = INSQTI( (void *) node, (void *) &g_mainActiveQueue, 0 );
  902. if ( !( q_stat_i & 1 ) ) {
  903. fprintf( stderr, main_str17 );
  904. }
  905. }
  906. else {
  907. fprintf( stderr, main_str18 );
  908. }
  909. stat = thread_unlock_master( h );
  910. break;
  911. }
  912. }
  913. //disconnect asychronously
  914. stat = shutdown( newsockfd, 2 );
  915. stat = close( newsockfd );
  916. }
  917. err_branch:
  918. stat = shutdown( sockfd, 2 );
  919. stat = close( sockfd );
  920. if ( cmd == CONNECT ) {
  921. thread_delay( delayH, 0.5 );
  922. }
  923. }
  924. err_return:
  925. stat = 0;
  926. #ifdef __linux__
  927. return NULL;
  928. #endif
  929. #ifdef darwin
  930. return NULL;
  931. #endif
  932. #ifdef __solaris__
  933. return NULL;
  934. #endif
  935. #ifdef HP_UX
  936. return NULL;
  937. #endif
  938. }
  939. static void checkParams (
  940. int argc,
  941. char **argv,
  942. int *local,
  943. int *server,
  944. int *appendDisplay,
  945. char *displayName,
  946. int *portNum,
  947. int *restart,
  948. int *oneInstance,
  949. int *openCmd,
  950. int *convertOnly,
  951. int *crawl,
  952. int *verbose
  953. ) {
  954. char buf[1023+1], mac[1023+1], exp[1023+1];
  955. int state = SWITCHES;
  956. int stat, l, nm = 0, n = 1;
  957. char *envPtr, *tk, *buf1;
  958. Display *testDisplay;
  959. strcpy( displayName, "" );
  960. *local = 0;
  961. *server = 0;
  962. *oneInstance = 0;
  963. *openCmd = 0;
  964. *appendDisplay = 1;
  965. *portNum = 19000;
  966. *restart = 0;
  967. *convertOnly = 0;
  968. *crawl = 0;
  969. *verbose = 0;
  970. // check first for component management commands
  971. if ( argc > 1 ) {
  972. if ( ( strcmp( argv[1], global_str6 ) == 0 ) ||
  973. ( strcmp( argv[1], global_str7 ) == 0 ) ||
  974. ( strcmp( argv[1], global_str8 ) == 0 ) ) {
  975. *local = 1;
  976. return;
  977. }
  978. }
  979. while ( n < argc ) {
  980. switch ( state ) {
  981. case SWITCHES:
  982. if ( argv[n][0] == '-' ) {
  983. if ( strcmp( argv[n], global_str9 ) == 0 ) {
  984. *local = 1;
  985. }
  986. else if ( strcmp( argv[n], global_str91 ) == 0 ) {
  987. *convertOnly = 1;
  988. *oneInstance = 0;
  989. *server = 0;
  990. *local = 1;
  991. }
  992. else if ( strcmp( argv[n], global_str102 ) == 0 ) {
  993. *convertOnly = 0;
  994. *oneInstance = 0;
  995. *server = 0;
  996. *local = 1;
  997. *crawl = 1;
  998. }
  999. else if ( strcmp( argv[n], global_str104 ) == 0 ) {
  1000. *verbose = 1;
  1001. }
  1002. else if ( strcmp( argv[n], global_str10 ) == 0 ) {
  1003. *server = 1;
  1004. *local = 0;
  1005. }
  1006. else if ( strcmp( argv[n], global_str89 ) == 0 ) {
  1007. *oneInstance = 1;
  1008. *server = 1;
  1009. *local = 0;
  1010. }
  1011. else if ( strcmp( argv[n], global_str93 ) == 0 ) {
  1012. *oneInstance = 1;
  1013. *server = 1;
  1014. *local = 0;
  1015. *openCmd = 1;
  1016. }
  1017. else if ( strcmp( argv[n], global_str86 ) == 0 ) {
  1018. n++;
  1019. if ( n >= argc ) { // missing pid num
  1020. return;
  1021. }
  1022. *restart = 1;
  1023. g_pidNum = atol( argv[n] );
  1024. l = strlen( argv[n] );
  1025. if ( l > 31 ) l = 31;
  1026. strncpy( g_restartId, argv[n], l );
  1027. }
  1028. else if ( strcmp( argv[n], global_str11 ) == 0 ) {
  1029. *local = 1;
  1030. return;
  1031. }
  1032. else if ( strcmp( argv[n], global_str12 ) == 0 ) {
  1033. *local = 1;
  1034. return;
  1035. }
  1036. else if ( strcmp( argv[n], global_str13 ) == 0 ) {
  1037. *local = 1;
  1038. return;
  1039. }
  1040. else if ( strcmp( argv[n], global_str14 ) == 0 ) {
  1041. *local = 1;
  1042. return;
  1043. }
  1044. else if ( strcmp( argv[n], global_str15 ) == 0 ) {
  1045. *local = 1;
  1046. return;
  1047. }
  1048. else if ( strcmp( argv[n], global_str16 ) == 0 ) {
  1049. *local = 1;
  1050. return;
  1051. }
  1052. else if ( strcmp( argv[n], global_str17 ) == 0 ) {
  1053. }
  1054. else if ( strcmp( argv[n], global_str18 ) == 0 ) {
  1055. }
  1056. else if ( strcmp( argv[n], global_str19 ) == 0 ) {
  1057. n++;
  1058. if ( n >= argc ) { // missing macro arg
  1059. *local = 1;
  1060. return;
  1061. }
  1062. strncpy( buf, argv[n], 1023 );
  1063. buf1 = NULL;
  1064. tk = strtok_r( buf, "=,", &buf1 );
  1065. while ( tk ) {
  1066. strncpy( mac, tk, 1023 );
  1067. tk = strtok_r( NULL, "=,", &buf1 );
  1068. if ( tk ) {
  1069. strncpy( exp, tk, 1023 );
  1070. }
  1071. else {
  1072. *local = 1;
  1073. return;
  1074. }
  1075. nm++;
  1076. tk = strtok_r( NULL, "=,", &buf1 );
  1077. }
  1078. if ( nm == 0 ) {
  1079. *local = 1;
  1080. return;
  1081. }
  1082. }
  1083. else if ( strcmp( argv[n], global_str20 ) == 0 ) {
  1084. n++;
  1085. if ( n >= argc ) {
  1086. *local = 1;
  1087. return;
  1088. }
  1089. }
  1090. else if ( strcmp( argv[n], global_str21 ) == 0 ) {
  1091. *appendDisplay = 0;
  1092. n++;
  1093. if ( n >= argc ) {
  1094. *local = 1;
  1095. return;
  1096. }
  1097. strncpy( displayName, argv[n], 127 );
  1098. }
  1099. else if ( strcmp( argv[n], global_str73 ) == 0 ) {
  1100. n++;
  1101. if ( n >= argc ) { // missing port num
  1102. *local = 1;
  1103. return;
  1104. }
  1105. *portNum = atol( argv[n] );
  1106. }
  1107. else if ( strcmp( argv[n], global_str76 ) == 0 ) {
  1108. }
  1109. else if ( strcmp( argv[n], global_str79 ) == 0 ) {
  1110. }
  1111. else if ( strcmp( argv[n], global_str96 ) == 0 ) {
  1112. }
  1113. else if ( strcmp( argv[n], global_str98 ) == 0 ) { //readonly
  1114. setReadOnly();
  1115. }
  1116. else if ( strcmp( argv[n], global_str100 ) == 0 ) {
  1117. }
  1118. else if ( strcmp( argv[n], global_str106 ) == 0 ) { //noautomsg
  1119. }
  1120. else {
  1121. *local = 1;
  1122. return;
  1123. }
  1124. n++;
  1125. }
  1126. else {
  1127. state = FILES;
  1128. }
  1129. break;
  1130. case FILES:
  1131. if ( argv[n][0] == '-' ) {
  1132. *local = 1;
  1133. return;
  1134. }
  1135. else {
  1136. n++;
  1137. }
  1138. break;
  1139. }
  1140. }
  1141. if ( strcmp( displayName, "" ) == 0 ) {
  1142. envPtr = getenv("DISPLAY");
  1143. if ( envPtr ) strncpy( displayName, envPtr, 127 );
  1144. if ( strcmp( displayName, "" ) == 0 ) {
  1145. stat = gethostname( displayName, 127 );
  1146. if ( stat ) {
  1147. fprintf( stderr, main_str35 );
  1148. exit(0);
  1149. }
  1150. Strncat( displayName, ":0.0", 127 );
  1151. }
  1152. }
  1153. testDisplay = XOpenDisplay( displayName );
  1154. if ( !testDisplay ) {
  1155. fprintf( stderr, main_str36 );
  1156. exit(0);
  1157. }
  1158. XCloseDisplay( testDisplay );
  1159. return;
  1160. }
  1161. extern int main (
  1162. int argc,
  1163. char **argv )
  1164. {
  1165. int i, j, stat, numAppsRemaining, exitProg, shutdown, q_stat_r, q_stat_i,
  1166. local, server, portNum, restart, n, x, y, icon, sessionNoEdit, screenNoEdit,
  1167. oneInstance, openCmd, convertOnly, crawl, verbose, needConnect;
  1168. THREAD_HANDLE delayH, serverH; //, caPendH;
  1169. argsPtr args;
  1170. appListPtr cur, next, appArgsHead, newOne, first;
  1171. processClass proc;
  1172. objBindingClass *obj;
  1173. pvBindingClass *pvObj;
  1174. char *tk, *buf1;
  1175. MAIN_NODE_PTR node;
  1176. char **argArray, displayName[255+1];
  1177. int appendDisplay;
  1178. float hours, seconds;
  1179. char checkPointFileName[255+1], screenName[255+1], tmpMsg[255+1];
  1180. Display *oneDisplay;
  1181. XtAppContext oneAppCtx;
  1182. FILE *f = NULL;
  1183. int primaryServerFlag, oneInstanceFlag, numCheckPointMacros;
  1184. char checkPointMacros[1023+1];
  1185. char *envPtr;
  1186. int doXSync = 0;
  1187. appListPtr primary;
  1188. int primaryServerWantsExit;
  1189. int numLocaleFailures = 0;
  1190. if ( diagnosticMode() ) {
  1191. logDiagnostic( "edm started\n" );
  1192. }
  1193. do {
  1194. if ( numLocaleFailures == 0 ) {
  1195. if ( setlocale( LC_ALL, "C" ) == NULL ) {
  1196. if ( setlocale( LC_ALL, "" ) == NULL ) {
  1197. fprintf( stderr, "Cannot set locale - abort\n" );
  1198. exit(1);
  1199. }
  1200. }
  1201. }
  1202. else if ( numLocaleFailures == 1 ) {
  1203. if ( setlocale( LC_ALL, "C" ) == NULL ) {
  1204. fprintf( stderr, "Cannot set locale - abort\n" );
  1205. exit(1);
  1206. }
  1207. }
  1208. if ( !XSupportsLocale() ) {
  1209. numLocaleFailures++;
  1210. if ( numLocaleFailures > 1 ) {
  1211. fprintf( stderr, "X does not support locale \"%s\" - abort\n",
  1212. setlocale( LC_ALL, NULL ) );
  1213. exit(1);
  1214. }
  1215. }
  1216. else {
  1217. numLocaleFailures = 0;
  1218. }
  1219. } while ( numLocaleFailures );
  1220. if ( XSetLocaleModifiers( "" ) == NULL ) {
  1221. fprintf( stderr, "Cannot set locale modifiers - abort\n" );
  1222. exit(1);
  1223. }
  1224. // fprintf( stderr, "locale is \"%s\"\n", setlocale( LC_ALL, NULL ) );
  1225. envPtr = getenv( "EDMXSYNC" );
  1226. if ( envPtr ) doXSync = 1;
  1227. g_numClients = 1;
  1228. checkParams( argc, argv, &local, &server, &appendDisplay, displayName,
  1229. &portNum, &restart, &oneInstance, &openCmd, &convertOnly, &crawl,
  1230. &verbose );
  1231. // if doing a restart, read in check point file
  1232. if ( restart ) {
  1233. //fprintf( stderr, "restart\n" );
  1234. getCheckPointFileName( checkPointFileName, g_restartId );
  1235. f = fopen( checkPointFileName, "r" );
  1236. if ( f ) {
  1237. stat = getMainCheckPointParams( f, &primaryServerFlag, &oneInstanceFlag,
  1238. displayName, &sessionNoEdit, &numCheckPointMacros, checkPointMacros );
  1239. if ( !( stat & 1 ) ) { // couldn't read file
  1240. restart = 0;
  1241. }
  1242. if ( primaryServerFlag == 2 ) {
  1243. server = 1;
  1244. appendDisplay = 1;
  1245. local = 0;
  1246. }
  1247. else {
  1248. server = 0;
  1249. local = 1;
  1250. }
  1251. if ( oneInstanceFlag ) {
  1252. oneInstance = 1;
  1253. openCmd = 0;
  1254. server = 1;
  1255. appendDisplay = 1;
  1256. local = 0;
  1257. }
  1258. //fprintf( stderr, "primaryServerFlag = %-d\n", primaryServerFlag );
  1259. //fprintf( stderr, "oneInstanceFlag = %-d\n", oneInstanceFlag );
  1260. //fprintf( stderr, "server = %-d\n", server );
  1261. //fprintf( stderr, "displayName = [%s]\n", displayName );
  1262. //fprintf( stderr, "sessionNoEdit = %-d\n", sessionNoEdit );
  1263. //fprintf( stderr, "numCheckPointMacros = %-d\n", numCheckPointMacros );
  1264. //fprintf( stderr, "checkPointMacros = [%s]\n", checkPointMacros );
  1265. }
  1266. else {
  1267. restart = 0;
  1268. }
  1269. }
  1270. if ( server ) {
  1271. checkForServer( argc, argv, portNum, appendDisplay, displayName,
  1272. oneInstance, openCmd );
  1273. }
  1274. if ( server ) {
  1275. // If openCmd is true, we want the server to open some screens;
  1276. // if no server is running, we do not want to launch an instance of edm
  1277. if ( openCmd ) {
  1278. fprintf( stderr, main_str46 );
  1279. exit(0);
  1280. }
  1281. stat = sys_iniq( &g_mainFreeQueue );
  1282. if ( !( stat & 1 ) ) {
  1283. fprintf( stderr, main_str37 );
  1284. exit(0);
  1285. }
  1286. stat = sys_iniq( &g_mainActiveQueue );
  1287. if ( !( stat & 1 ) ) {
  1288. fprintf( stderr, main_str38 );
  1289. exit(0);
  1290. }
  1291. g_mainFreeQueue.flink = NULL;
  1292. g_mainFreeQueue.blink = NULL;
  1293. g_mainActiveQueue.flink = NULL;
  1294. g_mainActiveQueue.blink = NULL;
  1295. for ( i=0; i<MAIN_QUEUE_SIZE; i++ ) {
  1296. stat = INSQTI( (void *) &g_mainNodes[i], (void *) &g_mainFreeQueue,
  1297. 0 );
  1298. if ( !( stat & 1 ) ) {
  1299. fprintf( stderr, main_str39 );
  1300. exit(0);
  1301. }
  1302. }
  1303. }
  1304. appArgsHead = new appListType;
  1305. appArgsHead->flink = appArgsHead;
  1306. appArgsHead->blink = appArgsHead;
  1307. XSetErrorHandler( xErrorHandler );
  1308. stat = thread_init();
  1309. obj = new objBindingClass;
  1310. pvObj = new pvBindingClass;
  1311. stat = thread_create_handle( &serverH, (void *) &portNum );
  1312. stat = thread_create_handle( &delayH, NULL );
  1313. if ( server ) stat = thread_create_proc( serverH, serverThread );
  1314. #if 0
  1315. stat = thread_create_handle( &caPendH, NULL );
  1316. stat = thread_create_proc( caPendH, caPendThread );
  1317. #endif
  1318. args = new argsType;
  1319. if ( restart ) { // append display name and macros to args
  1320. //fprintf( stderr, "adjust args for restart\n" );
  1321. //fprintf( stderr, "argc = %-d\n", argc );
  1322. n = 0;
  1323. if ( !blank(displayName) ) n += 2;
  1324. if ( numCheckPointMacros ) n += 2;
  1325. if ( sessionNoEdit ) n++;
  1326. n++; // add -x (execute)
  1327. argArray = new char*[argc+n];
  1328. i = 0;
  1329. argArray[i] = new char[strlen(argv[i])+1];
  1330. strcpy( argArray[i], argv[i] );
  1331. i++;
  1332. argArray[i] = new char[strlen("-x")+1];
  1333. strcpy( argArray[i], "-x" );
  1334. i++;
  1335. if ( sessionNoEdit ) {
  1336. argArray[i] = new char[strlen("-noedit")+1];
  1337. strcpy( argArray[i], "-noedit" );
  1338. i++;
  1339. }
  1340. if ( !blank(displayName) ) {
  1341. argArray[i] = new char[strlen("-display")+1];
  1342. strcpy( argArray[i], "-display" );
  1343. i++;
  1344. argArray[i] = new char[strlen(displayName)+1];
  1345. strcpy( argArray[i], displayName );
  1346. i++;
  1347. }
  1348. if ( numCheckPointMacros ) {
  1349. argArray[i] = new char[strlen("-m")+1];
  1350. strcpy( argArray[i], "-m" );
  1351. i++;
  1352. argArray[i] = new char[strlen(checkPointMacros)+1];
  1353. strcpy( argArray[i], checkPointMacros );
  1354. i++;
  1355. }
  1356. for ( j=1; j<argc; j++ ) {
  1357. argArray[i] = new char[strlen(argv[j])+1];
  1358. strcpy( argArray[i], argv[j] );
  1359. i++;
  1360. }
  1361. args->argc = argc + n;
  1362. }
  1363. else {
  1364. argArray = new char*[argc];
  1365. for ( i=0; i<argc; i++ ) {
  1366. argArray[i] = new char[strlen(argv[i])+1];
  1367. strcpy( argArray[i], argv[i] );
  1368. }
  1369. args->argc = argc;
  1370. }
  1371. args->argv = argArray;
  1372. cur = new appListType;
  1373. cur->appArgs = args;
  1374. cur->blink = appArgsHead->blink;
  1375. appArgsHead->blink->flink = cur;
  1376. cur->flink = appArgsHead;
  1377. appArgsHead->blink = cur;
  1378. args->appCtxPtr = new appContextClass;
  1379. args->appCtxPtr->proc = &proc;
  1380. //fprintf( stderr, "argc = %-d\n", args->argc );
  1381. //for ( i=0; i<args->argc; i++ ) {
  1382. // fprintf( stderr, "argv[%-d] = [%s]\n", i, args->argv[i] );
  1383. //}
  1384. if ( server ) {
  1385. stat = args->appCtxPtr->startApplication( args->argc, args->argv, 2,
  1386. oneInstance, convertOnly );
  1387. }
  1388. else {
  1389. stat = args->appCtxPtr->startApplication( args->argc, args->argv, 1,
  1390. oneInstance, convertOnly );
  1391. }
  1392. if ( !( stat & 1 ) ) exit( 0 );
  1393. if ( stat & 1 ) { // success
  1394. oneAppCtx = args->appCtxPtr->appContext();
  1395. XtAppSetErrorHandler( oneAppCtx, xtErrorHandler );
  1396. XtAppSetWarningHandler( oneAppCtx, xtErrorHandler );
  1397. }
  1398. if ( crawl ) {
  1399. {
  1400. macroListPtr cur;
  1401. fileListPtr curFile;
  1402. crawlListPtr crawlList;
  1403. int i, l, numMacros, found;
  1404. char *fname;
  1405. char **symbols;
  1406. char **values;
  1407. char crawlFileName[255+1];
  1408. setCrawlVerbose( verbose );
  1409. args->appCtxPtr->useStdErr( 1 );
  1410. args->appCtxPtr->setErrMsgPrefix( "displayCrawlerStatus: " );
  1411. numMacros = 0;
  1412. cur = args->appCtxPtr->macroHead->flink;
  1413. while ( cur != args->appCtxPtr->macroHead ) {
  1414. numMacros++;
  1415. cur = cur->flink;
  1416. }
  1417. symbols = new char*[numMacros];
  1418. values = new char*[numMacros];
  1419. i = 0;
  1420. cur = args->appCtxPtr->macroHead->flink;
  1421. while ( cur != args->appCtxPtr->macroHead ) {
  1422. //fprintf( stderr, "[%s] = [%s]\n", cur->macro, cur->expansion );
  1423. l = strlen( cur->macro );
  1424. symbols[i] = new char[l+1];
  1425. strcpy( symbols[i], cur->macro );
  1426. l = strlen( cur->expansion );
  1427. values[i] = new char[l+1];
  1428. strcpy( values[i], cur->expansion );
  1429. i++;
  1430. cur = cur->flink;
  1431. }
  1432. curFile = args->appCtxPtr->fileHead->flink;
  1433. while ( curFile != args->appCtxPtr->fileHead ) {
  1434. getFirstFile( curFile->file, 255, crawlFileName, &found );
  1435. if ( found ) {
  1436. while ( found ) {
  1437. //fprintf( stderr, "file = [%s]\n", crawlFileName );
  1438. fname = new char[strlen(crawlFileName)+1];
  1439. strcpy( fname, crawlFileName );
  1440. initCrawlList( &crawlList );
  1441. setCrawlListBaseMacros( numMacros, symbols, values );
  1442. addCrawlNode( crawlList, fname, numMacros,
  1443. symbols, values );
  1444. stat = crawlEdlFiles( args->appCtxPtr, crawlList );
  1445. getNextFile( curFile->file, 255, crawlFileName, &found );
  1446. }
  1447. }
  1448. else {
  1449. //fprintf( stderr, "one file = [%s]\n", curFile->file );
  1450. initCrawlList( &crawlList );
  1451. setCrawlListBaseMacros( numMacros, symbols, values );
  1452. addCrawlNode( crawlList, curFile->file, numMacros,
  1453. symbols, values );
  1454. stat = crawlEdlFiles( args->appCtxPtr, crawlList );
  1455. }
  1456. curFile = curFile->flink;
  1457. }
  1458. stat = displayCrawlerResults();
  1459. }
  1460. exit( 0 );
  1461. }
  1462. if ( restart ) { // open all displays
  1463. n = getNumCheckPointScreens( f );
  1464. //fprintf( stderr, "%-d screen(s)\n", n );
  1465. for ( i=0; i<n; i++ ) {
  1466. stat = getScreenCheckPointParams( f, screenName, &x, &y, &icon,
  1467. &screenNoEdit, &numCheckPointMacros, checkPointMacros );
  1468. if ( stat & 1 ) {
  1469. stat = args->appCtxPtr->openCheckPointScreen( screenName, x, y, icon,
  1470. screenNoEdit, numCheckPointMacros, checkPointMacros );
  1471. }
  1472. }
  1473. }
  1474. if ( restart ) {
  1475. // now, get all client display checkpoint info
  1476. do {
  1477. stat = getMainCheckPointParams( f, &primaryServerFlag, &oneInstanceFlag,
  1478. displayName, &sessionNoEdit, &numCheckPointMacros, checkPointMacros );
  1479. if ( !( stat & 1 ) ) { // couldn't read file
  1480. break;
  1481. }
  1482. if ( stat != 3 ) { // end of data
  1483. n = 0;
  1484. if ( !blank(displayName) ) n += 2;
  1485. if ( numCheckPointMacros ) n += 2;
  1486. if ( sessionNoEdit ) n++;
  1487. n++; // add -x (execute)
  1488. argArray = new char*[argc+n];
  1489. i = 0;
  1490. argArray[i] = new char[strlen(argv[i])+1];
  1491. strcpy( argArray[i], argv[i] );
  1492. i++;
  1493. argArray[i] = new char[strlen("-x")+1];
  1494. strcpy( argArray[i], "-x" );
  1495. i++;
  1496. if ( sessionNoEdit ) {
  1497. argArray[i] = new char[strlen("-noedit")+1];
  1498. strcpy( argArray[i], "-noedit" );
  1499. i++;
  1500. }
  1501. if ( !blank(displayName) ) {
  1502. argArray[i] = new char[strlen("-display")+1];
  1503. strcpy( argArray[i], "-display" );
  1504. i++;
  1505. argArray[i] = new char[strlen(displayName)+1];
  1506. strcpy( argArray[i], displayName );
  1507. i++;
  1508. }
  1509. if ( numCheckPointMacros ) {
  1510. argArray[i] = new char[strlen("-m")+1];
  1511. strcpy( argArray[i], "-m" );
  1512. i++;
  1513. argArray[i] = new char[strlen(checkPointMacros)+1];
  1514. strcpy( argArray[i], checkPointMacros );
  1515. i++;
  1516. }
  1517. for ( j=1; j<argc; j++ ) {
  1518. argArray[i] = new char[strlen(argv[j])+1];
  1519. strcpy( argArray[i], argv[j] );
  1520. i++;
  1521. }
  1522. args = new argsType;
  1523. args->argc = argc + n;
  1524. args->argv = argArray;
  1525. newOne = new appListType;
  1526. newOne->appArgs = args;
  1527. newOne->blink = appArgsHead->blink;
  1528. appArgsHead->blink->flink = newOne;
  1529. newOne->flink = appArgsHead;
  1530. appArgsHead->blink = newOne;
  1531. args->appCtxPtr = new appContextClass;
  1532. args->appCtxPtr->proc = &proc;
  1533. stat = args->appCtxPtr->startApplication( args->argc, args->argv, 0,
  1534. 0, 0 );
  1535. if ( stat & 1 ) { // success
  1536. oneAppCtx = args->appCtxPtr->appContext();
  1537. XtAppSetErrorHandler( oneAppCtx, xtErrorHandler );
  1538. XtAppSetWarningHandler( oneAppCtx, xtErrorHandler );
  1539. }
  1540. g_numClients++;
  1541. n = getNumCheckPointScreens( f );
  1542. //fprintf( stderr, "%-d screen(s)\n", n );
  1543. for ( i=0; i<n; i++ ) {
  1544. stat = getScreenCheckPointParams( f, screenName, &x, &y, &icon,
  1545. &screenNoEdit, &numCheckPointMacros, checkPointMacros );
  1546. if ( stat & 1 ) {
  1547. stat = args->appCtxPtr->openCheckPointScreen( screenName, x, y,
  1548. icon, screenNoEdit, numCheckPointMacros, checkPointMacros );
  1549. }
  1550. }
  1551. }
  1552. } while ( stat != 3 );
  1553. }
  1554. if ( f ) {
  1555. fclose( f );
  1556. if ( g_pidNum != 0 ) {
  1557. unlink( checkPointFileName ); // delete checkpoint file
  1558. }
  1559. }
  1560. proc.timeCount = 0;
  1561. proc.cycleTimeFactor = 1.0;
  1562. proc.halfSecCount = 5;
  1563. stat = sys_get_time( &proc.tim0 );
  1564. stat = thread_init_timer( delayH, 0.1 );
  1565. exitProg = 0;
  1566. shutdown = 0;
  1567. primaryServerWantsExit = 0;
  1568. while ( !exitProg ) {
  1569. #ifdef DIAGNOSTIC_ALLOC
  1570. if ( z ) z--;
  1571. if ( z == 1 ) {
  1572. //args->appCtxPtr->xSynchronize( 1 );
  1573. memTrackOn();
  1574. zz = 200;
  1575. }
  1576. if ( zz ) zz--;
  1577. if ( zz == 1 ) {
  1578. //zz = 200;
  1579. fprintf( stderr, "reset\n" );
  1580. memTrackReset();
  1581. }
  1582. showMem();
  1583. fprintf( stderr, "[%-d]\n", zz );
  1584. #endif
  1585. numAppsRemaining = 0;
  1586. cur = appArgsHead->flink;
  1587. while ( cur != appArgsHead ) {
  1588. if ( doXSync ) {
  1589. if ( cur->appArgs->appCtxPtr->syncOnce ) {
  1590. cur->appArgs->appCtxPtr->syncOnce = 0;
  1591. cur->appArgs->appCtxPtr->xSynchronize( 1 );
  1592. }
  1593. }
  1594. next = cur->flink; // cur might get deleted
  1595. cur->appArgs->appCtxPtr->applicationLoop();
  1596. if ( cur->appArgs->appCtxPtr->shutdownFlag ) {
  1597. if ( !shutdown ) {
  1598. getCheckPointFileNamefromPID( checkPointFileName );
  1599. f = fopen( checkPointFileName, "w" );
  1600. }
  1601. shutdown = 1;
  1602. }
  1603. if ( cur->appArgs->appCtxPtr->exitFlag &&
  1604. !cur->appArgs->appCtxPtr->objDelFlag ) {
  1605. if ( !cur->appArgs->appCtxPtr->okToExit() ) {
  1606. cur->appArgs->appCtxPtr->postMessage( main_str45 );
  1607. cur->appArgs->appCtxPtr->exitFlag = 0;
  1608. }
  1609. }
  1610. if ( cur->appArgs->appCtxPtr->exitFlag &&
  1611. !cur->appArgs->appCtxPtr->objDelFlag ) {
  1612. cur->appArgs->appCtxPtr->objDelFlag = 5;
  1613. numAppsRemaining++;
  1614. if ( cur->appArgs->appCtxPtr->primaryServer != 2 ) {
  1615. cur->appArgs->appCtxPtr->closeDownAppCtx();
  1616. // blank display name
  1617. strcpy( cur->appArgs->appCtxPtr->displayName, "" );
  1618. stat = thread_lock_master( serverH );
  1619. g_numClients--;
  1620. stat = thread_unlock_master( serverH );
  1621. }
  1622. }
  1623. else if ( cur->appArgs->appCtxPtr->exitFlag &&
  1624. cur->appArgs->appCtxPtr->objDelFlag > 1 ) {
  1625. //fprintf( stderr, "decrement\n" );
  1626. (cur->appArgs->appCtxPtr->objDelFlag)--;
  1627. numAppsRemaining++;
  1628. }
  1629. else if ( cur->appArgs->appCtxPtr->exitFlag &&
  1630. cur->appArgs->appCtxPtr->objDelFlag == 1 ) {
  1631. if ( cur->appArgs->appCtxPtr->primaryServer == 2 ) {
  1632. primaryServerWantsExit = 1;
  1633. primary = cur;
  1634. numAppsRemaining++;
  1635. }
  1636. else {
  1637. //fprintf( stderr, "delete\n" );
  1638. // unlink and delete
  1639. cur->blink->flink = cur->flink;
  1640. cur->flink->blink = cur->blink;
  1641. oneAppCtx = cur->appArgs->appCtxPtr->appContext();
  1642. oneDisplay = cur->appArgs->appCtxPtr->getDisplay();
  1643. delete cur->appArgs->appCtxPtr;
  1644. for ( i=0; i<cur->appArgs->argc; i++ )
  1645. delete[] cur->appArgs->argv[i];
  1646. delete[] cur->appArgs->argv;
  1647. delete cur->appArgs;
  1648. delete cur;
  1649. // Can't execute the next two lines; program crashes. Have to live
  1650. // with memory leak. This only applies to the case where one server
  1651. // is managing multiple app ctx's / displays.
  1652. //XtCloseDisplay( oneDisplay );
  1653. //XtDestroyApplicationContext( oneAppCtx );
  1654. }
  1655. }
  1656. else if ( shutdown ) {
  1657. cur->appArgs->appCtxPtr->performShutdown( f );
  1658. numAppsRemaining++;
  1659. }
  1660. else {
  1661. numAppsRemaining++;
  1662. }
  1663. cur = next;
  1664. needConnect = 0;
  1665. if ( server ) {
  1666. do {
  1667. stat = thread_lock_master( serverH );
  1668. q_stat_r = REMQHI( (void *) &g_mainActiveQueue, (void **) &node, 0 );
  1669. if ( q_stat_r & 1 ) {
  1670. strncpy( tmpMsg, node->msg, 255 );
  1671. tmpMsg[255] = 0;
  1672. buf1 = NULL;
  1673. tk = strtok_r( tmpMsg, "|", &buf1 );
  1674. if ( !tk ) goto parse_error;
  1675. if ( strcmp( tk, "*OPN*" ) == 0 ) {
  1676. needConnect = 1;
  1677. tk = strtok_r( NULL, "|", &buf1 ); // should contain display name
  1678. // make 1st app ctx open/deiconify/raise initial files
  1679. // and deiconify/raise main window so things look like
  1680. // a new instance of edm is starting
  1681. first = appArgsHead->flink;
  1682. while ( first != appArgsHead ) {
  1683. if ( ( strcmp( tk, ":0.0" ) == 0 ) ||
  1684. ( strcmp( tk,
  1685. first->appArgs->appCtxPtr->displayName ) == 0 ) ) {
  1686. tk = strtok_r( NULL, "|", &buf1 );
  1687. first->appArgs->appCtxPtr->openFiles( node->msg );
  1688. needConnect = 0;
  1689. break;
  1690. }
  1691. first = first->flink;
  1692. }
  1693. }
  1694. else if ( strcmp( tk, "*OIS*" ) == 0 ) {
  1695. needConnect = 1;
  1696. tk = strtok_r( NULL, "|", &buf1 ); // should contain display name
  1697. // make 1st app ctx open/deiconify/raise initial files
  1698. // and deiconify/raise main window so things look like
  1699. // a new instance of edm is starting
  1700. first = appArgsHead->flink;
  1701. while ( first != appArgsHead ) {
  1702. if ( ( strcmp( tk, ":0.0" ) == 0 ) ||
  1703. ( strcmp( tk,
  1704. first->appArgs->appCtxPtr->displayName ) == 0 ) ) {
  1705. first->appArgs->appCtxPtr->openInitialFiles();
  1706. first->appArgs->appCtxPtr->findTop();
  1707. needConnect = 0;
  1708. break;
  1709. }
  1710. first = first->flink;
  1711. }
  1712. }
  1713. strncpy( tmpMsg, node->msg, 255 );
  1714. tmpMsg[255] = 0;
  1715. buf1 = NULL;
  1716. tk = strtok_r( tmpMsg, "|", &buf1 );
  1717. if ( !tk ) goto parse_error;
  1718. if ( ( ( strcmp( tk, "*OIS*" ) != 0 ) &&
  1719. ( strcmp( tk, "*OPN*" ) != 0 ) ) ||
  1720. needConnect ) {
  1721. args = new argsType;
  1722. if ( needConnect ) {
  1723. strncpy( tmpMsg, node->msg, 255 );
  1724. tmpMsg[255] = 0;
  1725. buf1 = NULL;
  1726. tk = strtok_r( tmpMsg, "|", &buf1 ); // discard two
  1727. if ( !tk ) goto parse_error;
  1728. tk = strtok_r( NULL, "|", &buf1 );
  1729. if ( !tk ) goto parse_error;
  1730. tk = strtok_r( NULL, "|", &buf1 );
  1731. if ( !tk ) goto parse_error;
  1732. }
  1733. else {
  1734. strncpy( tmpMsg, node->msg, 255 );
  1735. tmpMsg[255] = 0;
  1736. buf1 = NULL;
  1737. tk = strtok_r( tmpMsg, "|", &buf1 );
  1738. if ( !tk ) goto parse_error;
  1739. }
  1740. argc = (int) atol( tk );
  1741. if ( argc == 0 ) goto parse_error;
  1742. argArray = new char*[argc];
  1743. for ( i=0; i<argc; i++ ) {
  1744. tk = strtok_r( NULL, "|", &buf1 );
  1745. if ( !tk ) goto parse_error;
  1746. argArray[i] = new char[strlen(tk)+1];
  1747. strcpy( argArray[i], tk );
  1748. }
  1749. args->argc = argc;
  1750. args->argv = argArray;
  1751. newOne = new appListType;
  1752. newOne->appArgs = args;
  1753. newOne->blink = appArgsHead->blink;
  1754. appArgsHead->blink->flink = newOne;
  1755. newOne->flink = appArgsHead;
  1756. appArgsHead->blink = newOne;
  1757. args->appCtxPtr = new appContextClass;
  1758. args->appCtxPtr->proc = &proc;
  1759. stat = args->appCtxPtr->startApplication( ar

Large files files are truncated, but you can click here to view the full file