SmDB.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: SmDB.c /main/5 1998/07/23 18:11:31 mgreess $ */
  24. /*
  25. * (c) Copyright 1996 Digital Equipment Corporation.
  26. * (c) Copyright 1996 Hewlett-Packard Company.
  27. * (c) Copyright 1996 International Business Machines Corp.
  28. * (c) Copyright 1996 Sun Microsystems, Inc.
  29. * (c) Copyright 1996 Novell, Inc.
  30. * (c) Copyright 1996 FUJITSU LIMITED.
  31. * (c) Copyright 1996 Hitachi.
  32. */
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <unistd.h>
  36. #include <errno.h>
  37. #include "SmDB.h"
  38. #define RESOURCE_BUF_SZ 1024
  39. #define CLIENT_ID_SZ 20
  40. typedef struct _ClientDBRec
  41. {
  42. XrmDatabase xrmDB; /* Xrm resource database. */
  43. Boolean openForInput; /* True if input, False if output. */
  44. char *xrmDBFileName; /* Filename, for openForInput == False. */
  45. char *tmpDBFileName;
  46. FILE *xrmDBFile;
  47. /* Below used if openForInput. */
  48. char **XSMPClients; /* malloc'd array of XSMP client IDs. */
  49. int nXSMPClients; /* number of XSMP clients. */
  50. int nextXSMPClientIndex; /* index of next XSMP client to Get;
  51. * also used as sequence # for Put. */
  52. char **proxyClients; /* malloc'd array of Proxy client IDs. */
  53. int nProxyClients; /* number of Proxy clients. */
  54. int nextProxyClientIndex; /* index of next Proxy client to Get;
  55. * also used as sequence # for Put. */
  56. } ClientDBRec;
  57. static Boolean xrmInitialized = False;
  58. static XrmName XSMPName[2];
  59. static XrmClass XSMPClass[2];
  60. static XrmName proxyName[2];
  61. static XrmClass proxyClass[2];
  62. static XrmQuark anyQuark;
  63. static char *resourceBuf = NULL;
  64. static char *clientIDBuf = NULL;
  65. /* Public strings */
  66. char *versionStr = ".version";
  67. char *dtsessionIDStr = ".dtsessionID";
  68. /* Strings for XSMP clients. */
  69. static char *clientStr = "!\nClient.%s";
  70. static char *programStr = "%s.Program";
  71. static char *cwdStr = "%s.Cwd";
  72. static char *restartCmdStr = "%s.RestartCommand";
  73. static char *cloneCmdStr = "%s.CloneCommand";
  74. static char *discardCmdStr = "%s.DiscardCommand";
  75. static char *environmentStr = "%s.Environment";
  76. static char *restartHintStr = "%s.RestartHint";
  77. static char *sessionIDStr = "%s.SessionID";
  78. /* Strings for Proxy clients. */
  79. static char *proxyStr = "!\nProxyClient.%s";
  80. static char *commandStr = "%s.Command";
  81. /* Common resources (XSMP and Proxy). */
  82. static char *clientHostStr = "%s.ClientHost";
  83. static char *screenNumStr = "%s.ScreenNum";
  84. static void _initXrm(void);
  85. static Bool _countProc(XrmDatabase *, XrmBindingList, XrmQuarkList,
  86. XrmRepresentation *, XrmValue *, XPointer);
  87. static Bool _fillClientIDProc(XrmDatabase *, XrmBindingList, XrmQuarkList,
  88. XrmRepresentation *, XrmValue *, XPointer);
  89. static Bool _fillStringArrayProc(XrmDatabase *, XrmBindingList, XrmQuarkList,
  90. XrmRepresentation *, XrmValue *, XPointer);
  91. static Boolean _getStringResource(XrmDatabase, char *,
  92. char *, char **, char *);
  93. static Boolean _getIntResource(XrmDatabase, char *, char *, int *, int);
  94. static Boolean _getStringArrayResource(XrmDatabase, char *, char *,
  95. char ***, char **);
  96. static void _freeStringArray(char **);
  97. static Boolean _putStringResource(ClientDBRec *, char *, char *, char *);
  98. static Boolean _putIntResource(ClientDBRec *, char *, char *, int);
  99. static Boolean _putStringArrayResource(ClientDBRec *, char *, char *, char **);
  100. static char *_tmpFileName(char *);
  101. static void
  102. _initXrm(void)
  103. {
  104. if (!xrmInitialized)
  105. {
  106. XrmInitialize(); /* Just in case. */
  107. anyQuark = XrmStringToQuark("?");
  108. XSMPName[0] = proxyName[0] = anyQuark;
  109. XSMPClass[0] = XrmStringToClass("Client");
  110. proxyClass[0] = XrmStringToClass("ProxyClient");
  111. XSMPName[1] = XSMPClass[1] =
  112. proxyName[1] = proxyClass[1] = NULLQUARK;
  113. xrmInitialized = True;
  114. }
  115. }
  116. static Bool
  117. _countProc(XrmDatabase *clientDB, XrmBindingList bindingList,
  118. XrmQuarkList quarkList, XrmRepresentation *reps,
  119. XrmValue *value, XPointer uData)
  120. {
  121. int *countP = (int *)uData;
  122. (*countP)++;
  123. return FALSE;
  124. }
  125. static Bool
  126. _fillClientIDProc(XrmDatabase *clientDB, XrmBindingList bindingList,
  127. XrmQuarkList quarkList, XrmRepresentation *reps,
  128. XrmValue *value, XPointer uData)
  129. {
  130. char ***idListPtr = (char ***)uData;
  131. char **clientIDPtr = *idListPtr;
  132. *clientIDPtr = (char *)value->addr;
  133. (*idListPtr)++;
  134. return FALSE;
  135. }
  136. static Bool
  137. _fillStringArrayProc(XrmDatabase *clientDB, XrmBindingList bindingList,
  138. XrmQuarkList quarkList, XrmRepresentation *reps,
  139. XrmValue *value, XPointer uData)
  140. {
  141. char **stringsPtr = (char **)uData;
  142. char *indexStr;
  143. /* Our index into this string array is at quarkList[2]. */
  144. if ((indexStr = XrmQuarkToString(quarkList[2])) == (char *)NULL)
  145. return True;
  146. if ((stringsPtr[atoi(indexStr)] = XtNewString((char *)value->addr))
  147. == (char *)NULL)
  148. return True;
  149. return FALSE;
  150. }
  151. static Boolean
  152. _getStringResource(XrmDatabase xrmDB, char *fmtStr,
  153. char *clientID, char **resourcePtr, char *defaultVal)
  154. {
  155. char *resourceType;
  156. XrmValue resourceValue;
  157. if (NULL == resourceBuf) resourceBuf = XtMalloc(RESOURCE_BUF_SZ);
  158. sprintf(resourceBuf, fmtStr, clientID);
  159. if (XrmGetResource(xrmDB, resourceBuf, resourceBuf,
  160. &resourceType, &resourceValue))
  161. {
  162. if ((*resourcePtr = XtNewString(resourceValue.addr)) == (char *)NULL)
  163. return False;
  164. return True;
  165. }
  166. *resourcePtr = defaultVal;
  167. return True;
  168. }
  169. static Boolean
  170. _getIntResource(XrmDatabase xrmDB, char *fmtStr,
  171. char *clientID, int *resourcePtr, int defaultVal)
  172. {
  173. char *resourceType;
  174. XrmValue resourceValue;
  175. if (NULL == resourceBuf) resourceBuf = XtMalloc(RESOURCE_BUF_SZ);
  176. sprintf(resourceBuf, fmtStr, clientID);
  177. *resourcePtr = (XrmGetResource(xrmDB, resourceBuf, resourceBuf,
  178. &resourceType, &resourceValue)) ?
  179. atoi(resourceValue.addr) : defaultVal;
  180. return True;
  181. }
  182. static Boolean
  183. _getStringArrayResource(XrmDatabase xrmDB, char *fmtStr,
  184. char *clientID, char ***resourcePtr,
  185. char **defaultVal)
  186. {
  187. XrmQuark resourceName[3];
  188. XrmQuark resourceClass[3];
  189. char *resourceType;
  190. XrmValue resourceValue;
  191. int nStrings;
  192. resourceName[0] = resourceName[1] = anyQuark;
  193. resourceName[2] = NULLQUARK;
  194. if (NULL == resourceBuf) resourceBuf = XtMalloc(RESOURCE_BUF_SZ);
  195. sprintf(resourceBuf, fmtStr, clientID);
  196. XrmStringToQuarkList(resourceBuf, resourceClass);
  197. nStrings = 0;
  198. XrmEnumerateDatabase(xrmDB, resourceName, resourceClass,
  199. XrmEnumOneLevel, _countProc,
  200. (XPointer)&nStrings);
  201. if (nStrings > 0)
  202. {
  203. char **stringsPtr;
  204. int i;
  205. if ((stringsPtr = (char **)XtMalloc((nStrings + 1) * sizeof(char *)))
  206. == (char **)NULL)
  207. return False;
  208. /* Initialize array entries to NULL so free can work. */
  209. /* NOTE: Final entry (nStrings) will remain NULL. */
  210. for (i = 0; i <= nStrings; i++)
  211. stringsPtr[i] = (char *)NULL;
  212. if (XrmEnumerateDatabase(xrmDB,
  213. resourceName, resourceClass,
  214. XrmEnumOneLevel, _fillStringArrayProc,
  215. (XPointer)stringsPtr))
  216. {
  217. for (i = 0; i < nStrings; i++)
  218. XtFree(stringsPtr[i]);
  219. XtFree((char *)stringsPtr);
  220. return False;
  221. }
  222. *resourcePtr = stringsPtr;
  223. return True;
  224. }
  225. *resourcePtr = defaultVal;
  226. return True;
  227. }
  228. static void
  229. _freeStringArray(char **stringsPtr)
  230. {
  231. if (stringsPtr)
  232. {
  233. int i;
  234. for (i = 0; stringsPtr[i] != (char *)NULL; i++)
  235. XtFree(stringsPtr[i]);
  236. XtFree((char *)stringsPtr);
  237. }
  238. }
  239. static Boolean
  240. _putStringResource(ClientDBRec *clientDB, char *fmtStr, char *clientID,
  241. char *resourceVal)
  242. {
  243. if (resourceVal != (char *)NULL)
  244. {
  245. if (NULL == clientIDBuf) clientIDBuf = XtMalloc(RESOURCE_BUF_SZ);
  246. sprintf(clientIDBuf, fmtStr, clientID);
  247. if (fprintf(clientDB->xrmDBFile, "%s: %s\n", clientIDBuf, resourceVal)
  248. < 0)
  249. return False;
  250. }
  251. return True;
  252. }
  253. static Boolean
  254. _putIntResource(ClientDBRec *clientDB, char *fmtStr, char *clientID,
  255. int resourceVal)
  256. {
  257. if (NULL == clientIDBuf) clientIDBuf = XtMalloc(RESOURCE_BUF_SZ);
  258. sprintf(clientIDBuf, fmtStr, clientID);
  259. if (fprintf(clientDB->xrmDBFile, "%s: %d\n", clientIDBuf, resourceVal)
  260. < 0)
  261. return False;
  262. return True;
  263. }
  264. static Boolean
  265. _putStringArrayResource(ClientDBRec *clientDB, char *fmtStr, char *clientID,
  266. char **resourceVal)
  267. {
  268. int i;
  269. if (resourceVal != (char **)NULL)
  270. {
  271. for (i = 0; resourceVal[i] != (char *)NULL; i++)
  272. {
  273. if (NULL == clientIDBuf) clientIDBuf = XtMalloc(RESOURCE_BUF_SZ);
  274. sprintf(clientIDBuf, fmtStr, clientID);
  275. if (fprintf(clientDB->xrmDBFile, "%s.%d: %s\n",
  276. clientIDBuf, i, resourceVal[i]) < 0)
  277. return False;
  278. }
  279. }
  280. return True;
  281. }
  282. static char *
  283. _tmpFileName(char *fileName)
  284. {
  285. int fileNameLen = strlen(fileName);
  286. char *newFileName =
  287. (char *)XtMalloc((fileNameLen + 20) * sizeof(char));
  288. if (newFileName != (char *)NULL)
  289. {
  290. int i;
  291. char *ptr = &(newFileName[fileNameLen]);
  292. strcpy(newFileName, fileName);
  293. /* Hm. I suppose if a couple billion versions of this file exist */
  294. /* we could loop forever, but that's not likely. */
  295. for (i = 0; ; i++)
  296. {
  297. sprintf(ptr, "%d", i);
  298. if (access(newFileName, F_OK) != 0)
  299. break;
  300. }
  301. }
  302. return newFileName;
  303. }
  304. ClientDB
  305. OpenInputClientDB(char *fileName,
  306. char **version,
  307. char **dtsessionID)
  308. {
  309. ClientDBRec *inputDB;
  310. char **tmpPtr;
  311. char *resourceType;
  312. XrmValue resourceValue;
  313. *version = (char *)NULL;
  314. *dtsessionID = (char *)NULL;
  315. _initXrm();
  316. if ((fileName == (char *)NULL) ||
  317. ((inputDB = (ClientDBRec *)XtMalloc(sizeof(ClientDBRec)))
  318. == (ClientDBRec *)NULL))
  319. return (ClientDB)NULL;
  320. if ((inputDB->xrmDB = XrmGetFileDatabase(fileName))
  321. == (XrmDatabase)NULL)
  322. {
  323. XtFree((char *)inputDB);
  324. return (ClientDB)NULL;
  325. }
  326. inputDB->openForInput = True;
  327. inputDB->XSMPClients = inputDB->proxyClients = (char **)NULL;
  328. inputDB->nXSMPClients = inputDB->nProxyClients = 0;
  329. inputDB->nextXSMPClientIndex = inputDB->nextProxyClientIndex = 0;
  330. /* Count the number of XSMP and Proxy clients. */
  331. XrmEnumerateDatabase(inputDB->xrmDB, XSMPName, XSMPClass,
  332. XrmEnumOneLevel, _countProc,
  333. (XPointer)&inputDB->nXSMPClients);
  334. XrmEnumerateDatabase(inputDB->xrmDB, proxyName, proxyClass,
  335. XrmEnumOneLevel, _countProc,
  336. (XPointer)&inputDB->nProxyClients);
  337. /* Allocate space for the client IDs and fill from database. */
  338. if (inputDB->nXSMPClients > 0)
  339. {
  340. if ((inputDB->XSMPClients =
  341. (char **)XtMalloc(inputDB->nXSMPClients * sizeof(char *)))
  342. == (char **)NULL)
  343. {
  344. XrmDestroyDatabase(inputDB->xrmDB);
  345. XtFree((char *)inputDB);
  346. return (ClientDB)NULL;
  347. }
  348. tmpPtr = inputDB->XSMPClients;
  349. XrmEnumerateDatabase(inputDB->xrmDB, XSMPName, XSMPClass,
  350. XrmEnumOneLevel, _fillClientIDProc,
  351. (XPointer)&tmpPtr);
  352. }
  353. if (inputDB->nProxyClients > 0)
  354. {
  355. if ((inputDB->proxyClients =
  356. (char **)XtMalloc(inputDB->nProxyClients * sizeof(char *)))
  357. == (char **)NULL)
  358. {
  359. XrmDestroyDatabase(inputDB->xrmDB);
  360. XtFree((char *)inputDB->XSMPClients);
  361. XtFree((char *)inputDB);
  362. return (ClientDB)NULL;
  363. }
  364. tmpPtr = inputDB->proxyClients;
  365. XrmEnumerateDatabase(inputDB->xrmDB, proxyName, proxyClass,
  366. XrmEnumOneLevel, _fillClientIDProc,
  367. (XPointer)&tmpPtr);
  368. }
  369. if ((!XrmGetResource(inputDB->xrmDB, versionStr, versionStr,
  370. &resourceType, &resourceValue)) ||
  371. ((*version = XtNewString(resourceValue.addr)) == (char *)NULL) ||
  372. (!XrmGetResource(inputDB->xrmDB, dtsessionIDStr, dtsessionIDStr,
  373. &resourceType, &resourceValue)) ||
  374. ((*dtsessionID = XtNewString(resourceValue.addr)) == (char *)NULL))
  375. {
  376. if (*version)
  377. {
  378. XtFree(*version);
  379. *version = (char *)NULL;
  380. }
  381. XrmDestroyDatabase(inputDB->xrmDB);
  382. XtFree((char *)inputDB->XSMPClients);
  383. XtFree((char *)inputDB->proxyClients);
  384. XtFree((char *)inputDB);
  385. return (ClientDB)NULL;
  386. }
  387. return (ClientDB)inputDB;
  388. }
  389. ClientDB
  390. OpenOutputClientDB(char *fileName,
  391. char *version,
  392. char *dtsessionID)
  393. {
  394. ClientDBRec *outputDB;
  395. _initXrm();
  396. if ((fileName == (char *)NULL) ||
  397. (version == (char *)NULL) ||
  398. (dtsessionID == (char *)NULL) ||
  399. ((outputDB = (ClientDBRec *)XtMalloc(sizeof(ClientDBRec)))
  400. == (ClientDBRec *)NULL))
  401. return (ClientDB)NULL;
  402. outputDB->xrmDB = (XrmDatabase)NULL;
  403. outputDB->openForInput = False;
  404. outputDB->nextXSMPClientIndex = 0;
  405. outputDB->nextProxyClientIndex = 0;
  406. /* Save current DB to tmp file in case we need to restore later. */
  407. if (((outputDB->xrmDBFileName = XtNewString(fileName)) == (char *)NULL) ||
  408. ((outputDB->tmpDBFileName = _tmpFileName(fileName)) == (char *)NULL))
  409. {
  410. if (outputDB->xrmDBFileName != (char *)NULL)
  411. XtFree(outputDB->xrmDBFileName);
  412. XtFree((char *)outputDB);
  413. return (ClientDB)NULL;
  414. }
  415. if ((rename(fileName, outputDB->tmpDBFileName) != 0) &&
  416. (errno != ENOENT))
  417. {
  418. XtFree(outputDB->xrmDBFileName);
  419. XtFree(outputDB->tmpDBFileName);
  420. XtFree((char *)outputDB);
  421. return (ClientDB)NULL;
  422. }
  423. /* Open fileName for writing. */
  424. if ((outputDB->xrmDBFile = fopen(fileName, "w")) == (FILE *)NULL)
  425. {
  426. int rv;
  427. rv = rename(outputDB->tmpDBFileName, fileName);
  428. XtFree(outputDB->xrmDBFileName);
  429. XtFree(outputDB->tmpDBFileName);
  430. XtFree((char *)outputDB);
  431. return (ClientDB)NULL;
  432. }
  433. /* Store version and session ID. */
  434. fprintf(outputDB->xrmDBFile, "! dtsession.db\n!\n%s: %s\n",
  435. versionStr, version);
  436. fprintf(outputDB->xrmDBFile, "%s: %s\n", dtsessionIDStr, dtsessionID);
  437. return (ClientDB)outputDB;
  438. }
  439. XSMPClientDBRecPtr
  440. GetXSMPClientDBRec(ClientDB inputDBPtr)
  441. {
  442. ClientDBRec *inputDB = (ClientDBRec *)inputDBPtr;
  443. XSMPClientDBRecPtr clientPtr;
  444. char *clientID;
  445. if ((inputDB == (ClientDBRec *)NULL) ||
  446. (!inputDB->openForInput) ||
  447. (inputDB->nextXSMPClientIndex >= inputDB->nXSMPClients) ||
  448. ((clientPtr = (XSMPClientDBRecPtr)XtMalloc(sizeof(XSMPClientDBRec)))
  449. == (XSMPClientDBRecPtr)NULL))
  450. {
  451. return (XSMPClientDBRecPtr)NULL;
  452. }
  453. clientID = inputDB->XSMPClients[inputDB->nextXSMPClientIndex];
  454. /* Initialize pointers so Free is easy. */
  455. clientPtr->clientId = (char *)NULL;
  456. clientPtr->clientHost = clientPtr->program =
  457. clientPtr->cwd = (char *)NULL;
  458. clientPtr->restartCommand = clientPtr->cloneCommand =
  459. clientPtr->discardCommand = clientPtr->environment = (char **)NULL;
  460. /* Retrieve resources from the database. */
  461. if (!_getStringResource(inputDB->xrmDB, sessionIDStr, clientID,
  462. &clientPtr->clientId, (char *)NULL) ||
  463. !_getStringResource(inputDB->xrmDB, clientHostStr, clientID,
  464. &clientPtr->clientHost, (char *)NULL) ||
  465. !_getStringResource(inputDB->xrmDB, programStr, clientID,
  466. &clientPtr->program, (char *)NULL) ||
  467. !_getStringResource(inputDB->xrmDB, cwdStr, clientID,
  468. &clientPtr->cwd, (char *)NULL) ||
  469. !_getIntResource(inputDB->xrmDB, screenNumStr, clientID,
  470. &clientPtr->screenNum, 0) ||
  471. !_getStringArrayResource(inputDB->xrmDB, restartCmdStr, clientID,
  472. &clientPtr->restartCommand, (char **)NULL) ||
  473. !_getStringArrayResource(inputDB->xrmDB, cloneCmdStr, clientID,
  474. &clientPtr->cloneCommand, (char **)NULL) ||
  475. !_getStringArrayResource(inputDB->xrmDB, discardCmdStr, clientID,
  476. &clientPtr->discardCommand, (char **)NULL) ||
  477. !_getStringArrayResource(inputDB->xrmDB, environmentStr, clientID,
  478. &clientPtr->environment, (char **)NULL) ||
  479. !_getIntResource(inputDB->xrmDB, restartHintStr, clientID,
  480. (int *)&clientPtr->restartHint, 0))
  481. {
  482. FreeXSMPClientDBRec(clientPtr);
  483. return (XSMPClientDBRecPtr)NULL;
  484. }
  485. clientPtr->next = (XSMPClientDBRec *)NULL;
  486. inputDB->nextXSMPClientIndex++;
  487. return clientPtr;
  488. }
  489. ProxyClientDBRecPtr
  490. GetProxyClientDBRec(ClientDB inputDBPtr)
  491. {
  492. ClientDBRec *inputDB = (ClientDBRec *)inputDBPtr;
  493. ProxyClientDBRecPtr clientPtr;
  494. char *clientID;
  495. if ((inputDB == (ClientDBRec *)NULL) ||
  496. (!inputDB->openForInput) ||
  497. (inputDB->nextProxyClientIndex >= inputDB->nProxyClients) ||
  498. ((clientPtr = (ProxyClientDBRecPtr)XtMalloc(sizeof(ProxyClientDBRec)))
  499. == (ProxyClientDBRecPtr)NULL))
  500. {
  501. return (ProxyClientDBRecPtr)NULL;
  502. }
  503. clientID = inputDB->proxyClients[inputDB->nextProxyClientIndex];
  504. /* Initialize pointers so Free is easy. */
  505. clientPtr->clientHost = (char *)NULL;
  506. clientPtr->command = (char **)NULL;
  507. /* Retrieve resources from the database. */
  508. if (!_getStringResource(inputDB->xrmDB, clientHostStr, clientID,
  509. &clientPtr->clientHost, (char *)NULL) ||
  510. !_getStringArrayResource(inputDB->xrmDB, commandStr, clientID,
  511. &clientPtr->command, (char **)NULL) ||
  512. !_getIntResource(inputDB->xrmDB, screenNumStr, clientID,
  513. &clientPtr->screenNum, 0))
  514. {
  515. FreeProxyClientDBRec(clientPtr);
  516. return (ProxyClientDBRecPtr)NULL;
  517. }
  518. inputDB->nextProxyClientIndex++;
  519. return clientPtr;
  520. }
  521. Boolean
  522. PutXSMPClientDBRec(ClientDB outputDBPtr,
  523. XSMPClientDBRecPtr clientPtr)
  524. {
  525. ClientDBRec *outputDB = (ClientDBRec *)outputDBPtr;
  526. char clientID[CLIENT_ID_SZ];
  527. if ((outputDB == (ClientDBRec *)NULL) ||
  528. (outputDB->openForInput) ||
  529. (clientPtr == (XSMPClientDBRecPtr)NULL) ||
  530. (clientPtr->clientId == (char *)NULL))
  531. return False;
  532. sprintf(clientID, "C%d", outputDB->nextXSMPClientIndex++);
  533. if (!_putStringResource(outputDB, clientStr, clientID, clientID) ||
  534. !_putStringResource(outputDB, sessionIDStr, clientID,
  535. clientPtr->clientId) ||
  536. !_putStringResource(outputDB, clientHostStr, clientID,
  537. clientPtr->clientHost) ||
  538. !_putStringResource(outputDB, programStr, clientID,
  539. clientPtr->program) ||
  540. !_putStringResource(outputDB, cwdStr, clientID,
  541. clientPtr->cwd) ||
  542. !_putIntResource(outputDB, screenNumStr, clientID,
  543. clientPtr->screenNum) ||
  544. !_putStringArrayResource(outputDB, restartCmdStr, clientID,
  545. clientPtr->restartCommand) ||
  546. !_putStringArrayResource(outputDB, cloneCmdStr, clientID,
  547. clientPtr->cloneCommand) ||
  548. !_putStringArrayResource(outputDB, discardCmdStr, clientID,
  549. clientPtr->discardCommand) ||
  550. !_putStringArrayResource(outputDB, environmentStr, clientID,
  551. clientPtr->environment) ||
  552. !_putIntResource(outputDB, restartHintStr, clientID,
  553. (int)clientPtr->restartHint))
  554. return False;
  555. return True;
  556. }
  557. Boolean
  558. PutProxyClientDBRec(ClientDB outputDBPtr,
  559. ProxyClientDBRecPtr clientPtr)
  560. {
  561. ClientDBRec *outputDB = (ClientDBRec *)outputDBPtr;
  562. char clientID[CLIENT_ID_SZ];
  563. if ((outputDB == (ClientDBRec *)NULL) ||
  564. (outputDB->openForInput) ||
  565. (clientPtr == (ProxyClientDBRecPtr)NULL))
  566. return False;
  567. sprintf(clientID, "PC%d", outputDB->nextProxyClientIndex++);
  568. if (!_putStringResource(outputDB, proxyStr, clientID, clientID) ||
  569. !_putStringResource(outputDB, clientHostStr, clientID,
  570. clientPtr->clientHost) ||
  571. !_putStringArrayResource(outputDB, commandStr, clientID,
  572. clientPtr->command) ||
  573. !_putIntResource(outputDB, screenNumStr, clientID,
  574. clientPtr->screenNum))
  575. return False;
  576. return True;
  577. }
  578. Boolean
  579. CloseClientDB(ClientDB clientDBPtr, Boolean writeDB)
  580. {
  581. ClientDBRec *clientDB = (ClientDBRec *)clientDBPtr;
  582. if (clientDB == (ClientDBRec *)NULL)
  583. return False;
  584. /* Input? */
  585. if (clientDB->openForInput)
  586. {
  587. XtFree((char *)clientDB->XSMPClients);
  588. XtFree((char *)clientDB->proxyClients);
  589. XrmDestroyDatabase(clientDB->xrmDB);
  590. XtFree((char *)clientDB);
  591. return True;
  592. }
  593. /* Otherwise, output. */
  594. if (writeDB)
  595. {
  596. /* Close file and remove temp DB. */
  597. fclose(clientDB->xrmDBFile);
  598. unlink(clientDB->tmpDBFileName);
  599. }
  600. else
  601. {
  602. int rv;
  603. /* Close file and remove it; restore original DB. */
  604. fclose(clientDB->xrmDBFile);
  605. rv = rename(clientDB->tmpDBFileName, clientDB->xrmDBFileName);
  606. }
  607. XtFree(clientDB->xrmDBFileName);
  608. XtFree(clientDB->tmpDBFileName);
  609. XtFree((char *)clientDB);
  610. return True;
  611. }
  612. void
  613. FreeXSMPClientDBRec(XSMPClientDBRecPtr clientPtr)
  614. {
  615. if (clientPtr != (XSMPClientDBRecPtr)NULL)
  616. {
  617. XtFree(clientPtr->clientId);
  618. XtFree(clientPtr->clientHost);
  619. XtFree(clientPtr->program);
  620. XtFree(clientPtr->cwd);
  621. _freeStringArray(clientPtr->restartCommand);
  622. _freeStringArray(clientPtr->cloneCommand);
  623. _freeStringArray(clientPtr->discardCommand);
  624. _freeStringArray(clientPtr->environment);
  625. XtFree((char *)clientPtr);
  626. }
  627. }
  628. void
  629. FreeProxyClientDBRec(ProxyClientDBRecPtr clientPtr)
  630. {
  631. if (clientPtr != (ProxyClientDBRecPtr)NULL)
  632. {
  633. XtFree(clientPtr->clientHost);
  634. _freeStringArray(clientPtr->command);
  635. XtFree((char *)clientPtr);
  636. }
  637. }