MMDb.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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: MMDb.c /main/19 1998/10/23 13:48:52 mgreess $ */
  24. /*
  25. * +SNOTICE
  26. *
  27. * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
  28. *
  29. * +ENOTICE
  30. */
  31. #include <stdio.h>
  32. #include <sys/types.h>
  33. #include <unistd.h>
  34. #include <sys/utsname.h>
  35. #include <stdlib.h>
  36. #include <ctype.h>
  37. #include <string.h>
  38. #include <stdint.h>
  39. #ifdef NLS16
  40. #include <limits.h>
  41. #endif
  42. #include <sys/stat.h>
  43. #include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
  44. #define X_INCLUDE_DIRENT_H
  45. #define XOS_USE_XT_LOCKING
  46. #include <X11/Xos_r.h>
  47. #include <Dt/DbReader.h>
  48. #include <Dt/DtsDb.h>
  49. #include <Dt/DtsMM.h>
  50. #include <Dt/DtShmDb.h>
  51. #include <Dt/Dts.h>
  52. #include <Dt/ActionP.h>
  53. #include <Dt/ActionDbP.h>
  54. #include <Dt/ActionUtilP.h>
  55. #include <Dt/DtNlUtils.h>
  56. #include <Dt/UserMsg.h>
  57. #include "myassertP.h"
  58. #include "DtSvcLock.h"
  59. static void build_file_list(DtShmProtoIntList, DtDirPaths *,
  60. DtDtsMMHeader *, const char *);
  61. extern int cde_dc_field_compare(DtDtsDbField **, DtDtsDbField **);
  62. extern int cde_dc_compare(DtDtsDbRecord **, DtDtsDbRecord **);
  63. static void _DtMMSortDataTypes(DtShmProtoStrtab str_handle);
  64. static void _DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr);
  65. static int write_db(DtDtsMMHeader *header, void *index, int size,
  66. const char *CacheFile);
  67. static int build_new_db(DtShmProtoStrtab, DtShmProtoIntList, int, DtDtsDbDatabase **);
  68. static int build_name_list(DtDtsDbDatabase *, DtShmProtoIntList, DtDtsMMHeader *);
  69. static DtShmProtoStrtab shm_handle = 0;
  70. static DtShmProtoIntList int_handle = 0;
  71. #define QtB(a) _DtShmProtoAddStrtab(shm_handle, XrmQuarkToString(a), &isnew)
  72. /* DtsMM.c */
  73. extern int _DtDtsMMPathHash(DtDirPaths *dirs);
  74. int
  75. _MMWriteDb(DtDirPaths *dirs, int num_db, DtDtsDbDatabase **db_list,
  76. const char *CacheFile)
  77. {
  78. DtDtsMMHeader header;
  79. char *suffix = ".dt";
  80. int tbl_size;
  81. void *tbl_data;
  82. DtDtsDbDatabase *db;
  83. int returnCode;
  84. _DtSvcProcessLock();
  85. memset(&header, '\0', sizeof(header));
  86. int_handle = _DtShmProtoInitIntLst(50000);
  87. shm_handle = _DtShmProtoInitStrtab(10000);
  88. build_file_list(int_handle, dirs, &header, suffix);
  89. _DtMMSortDataTypes(shm_handle);
  90. db = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
  91. _DtMMAddActionsToDataAttribute(db);
  92. header.pathhash = _DtDtsMMPathHash(dirs);
  93. header.num_db = num_db;
  94. header.db_offset = build_new_db(shm_handle, int_handle, num_db,
  95. db_list);
  96. db = (DtDtsDbDatabase *) _DtDtsDbGet("DATA_CRITERIA");
  97. build_name_list(db, int_handle, &header);
  98. tbl_size = _DtShmProtoSizeStrtab(shm_handle);
  99. tbl_data = (void *) _DtShmProtoAddIntLst(int_handle,
  100. tbl_size/sizeof(int), &header.str_tbl_offset);
  101. _DtShmProtoCopyStrtab(shm_handle, tbl_data);
  102. tbl_size = _DtShmProtoSizeIntLst(int_handle);
  103. tbl_data = (void *)malloc(tbl_size);
  104. memset(tbl_data, '\0', tbl_size);
  105. tbl_data = (void *)_DtShmProtoCopyIntLst(int_handle, tbl_data);
  106. returnCode = write_db(&header, tbl_data, tbl_size, CacheFile);
  107. _DtShmProtoDestroyStrtab(shm_handle);
  108. _DtShmProtoDestroyIntLst(int_handle);
  109. _DtSvcProcessUnlock();
  110. free(tbl_data);
  111. return returnCode;
  112. }
  113. static void
  114. build_file_list(DtShmProtoIntList int_handle, DtDirPaths *dirs,
  115. DtDtsMMHeader *header, const char *suffix)
  116. {
  117. DIR *dirp;
  118. struct dirent *dp = NULL;
  119. struct stat buf;
  120. char cur_path[MAXPATHLEN+1];
  121. void *data;
  122. int size = sizeof(buf.st_mtime);
  123. int i;
  124. int isnew;
  125. DtShmBoson *boson_list = 0;
  126. time_t *mtime_list = 0;
  127. int count = 0;
  128. _Xreaddirparams dirEntryBuf;
  129. struct dirent *result;
  130. /* Theses here to make sure it gets into the string tables
  131. because actions uses it in its "types" field. */
  132. _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_UNKNOWN, &isnew);
  133. _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_RECURSIVE_LINK, &isnew);
  134. _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_BROKEN_LINK, &isnew);
  135. getcwd(cur_path, sizeof(cur_path));
  136. for(i = 0; dirs->paths[i]; i++)
  137. {
  138. chdir(dirs->paths[i]);
  139. stat(".", &buf);
  140. count++;
  141. boson_list = (int *)realloc(boson_list, count*sizeof(int));
  142. mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
  143. mtime_list[count-1] = buf.st_mtime;
  144. boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle, dirs->paths[i], &isnew);
  145. dirp = opendir(".");
  146. while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
  147. {
  148. char *c = strrchr(result->d_name, suffix[0]);
  149. if(c && strcmp(c, suffix) == 0)
  150. {
  151. char *pathname = malloc(MAXPATHLEN+1);
  152. sprintf(pathname, "%s/%s", dirs->paths[i], result->d_name);
  153. stat(result->d_name, &buf);
  154. count++;
  155. boson_list = (int *)realloc(boson_list, count*sizeof(int));
  156. mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
  157. mtime_list[count-1] = buf.st_mtime;
  158. boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle,
  159. pathname, &isnew);
  160. free(pathname);
  161. continue;
  162. }
  163. }
  164. (void)closedir( dirp );
  165. }
  166. chdir(cur_path);
  167. data = _DtShmProtoAddIntLst(int_handle, count, &header->files_offset);
  168. memcpy(data, boson_list, count*sizeof(int));
  169. data = _DtShmProtoAddIntLst(int_handle, count*sizeof(time_t)/sizeof(int), &header->mtimes_offset);
  170. memcpy(data, mtime_list, count*sizeof(time_t));
  171. header->files_count = count;
  172. free(boson_list);
  173. free(mtime_list);
  174. return;
  175. }
  176. static int
  177. db_table_size(int num_db, DtDtsDbDatabase **db_list)
  178. {
  179. int db;
  180. DtDtsDbDatabase *db_ptr;
  181. int rec;
  182. DtDtsDbRecord *rec_ptr;
  183. int fld;
  184. DtDtsDbField *fld_ptr;
  185. int size = 0;
  186. size += num_db*sizeof(DtDtsMMDatabase);
  187. for(db = 0; db < num_db; db++)
  188. {
  189. db_ptr = db_list[db];
  190. size += db_ptr->recordCount * sizeof(DtDtsMMRecord);
  191. for(rec = 0; rec < db_ptr->recordCount; rec++)
  192. {
  193. rec_ptr = db_ptr->recordList[rec];
  194. size += rec_ptr->fieldCount * sizeof(DtDtsMMField);
  195. }
  196. }
  197. return(size/sizeof(int));
  198. }
  199. static void
  200. _DtMMSortDataTypes(DtShmProtoStrtab str_handle)
  201. {
  202. DtDtsDbDatabase *dc;
  203. DtDtsDbDatabase *da;
  204. int i;
  205. _DtSvcProcessLock();
  206. dc = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DC_NAME);
  207. da = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
  208. /*_DtDtsDbPrintRecords(dc, stdout);*/
  209. for(i = 0; i < dc->recordCount; i++)
  210. {
  211. if(dc->recordList[i]->compare != cde_dc_field_compare)
  212. {
  213. _DtDtsDbFieldSort(dc->recordList[i],
  214. cde_dc_field_compare);
  215. }
  216. }
  217. _DtDtsDbRecordSort(dc, cde_dc_compare);
  218. for(i = 0; i < da->recordCount; i++)
  219. {
  220. if(da->recordList[i]->compare !=
  221. _DtDtsDbCompareFieldNames)
  222. {
  223. _DtDtsDbFieldSort(da->recordList[i],
  224. _DtDtsDbCompareFieldNames);
  225. }
  226. }
  227. _DtDtsDbRecordSort(da, _DtDtsDbCompareRecordNames);
  228. /*_DtDtsDbPrintRecords(dc, stdout);*/
  229. _DtSvcProcessUnlock();
  230. }
  231. static void
  232. add_if_missing(DtDtsDbRecord *rec_ptr, XrmQuark name, char *value)
  233. {
  234. DtDtsDbField *fld_ptr;
  235. int fld;
  236. int found = 0;
  237. for(fld = 0; fld < rec_ptr->fieldCount; fld++)
  238. {
  239. fld_ptr = rec_ptr->fieldList[fld];
  240. if(name == fld_ptr->fieldName)
  241. {
  242. found = 1;
  243. break;
  244. }
  245. }
  246. if(found)
  247. {
  248. return;
  249. }
  250. fld_ptr = _DtDtsDbAddField(rec_ptr);
  251. fld_ptr->fieldName = name;
  252. fld_ptr->fieldValue = value;
  253. _DtDtsDbFieldSort(rec_ptr, 0);
  254. return;
  255. }
  256. static void
  257. _DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr)
  258. {
  259. int rec;
  260. DtDtsDbRecord *rec_ptr;
  261. int action_flag = 0;
  262. int sort_flag = 0;
  263. int found_flag = 0;
  264. int n;
  265. const char *tmp;
  266. XrmQuark desc_qrk = XrmStringToQuark(DtDTS_DA_DESCRIPTION);
  267. XrmQuark icon_qrk = XrmStringToQuark(DtDTS_DA_ICON);
  268. XrmQuark label_qrk = XrmStringToQuark(DtDTS_DA_LABEL);
  269. for(rec = 0; rec < db_ptr->recordCount; rec++)
  270. {
  271. int found_des = 0;
  272. int found_icon = 0;
  273. int found_label = 0;
  274. char *obj_type;
  275. rec_ptr = db_ptr->recordList[rec];
  276. obj_type = XrmQuarkToString(rec_ptr->recordName);
  277. if ( _DtDtsDbGetFieldByName(rec_ptr,
  278. DtDTS_DA_IS_ACTION) == 0 )
  279. {
  280. continue;
  281. }
  282. add_if_missing(rec_ptr, desc_qrk,
  283. DtActionDescription(obj_type));
  284. add_if_missing(rec_ptr, icon_qrk, DtActionIcon(obj_type));
  285. add_if_missing(rec_ptr, label_qrk, DtActionLabel(obj_type));
  286. }
  287. }
  288. static int
  289. build_new_db(DtShmProtoStrtab shm_handle, DtShmProtoIntList int_handle, int num_db, DtDtsDbDatabase **db_list)
  290. {
  291. DtDtsMMDatabase *new_db_list;
  292. int db;
  293. DtDtsDbDatabase *db_ptr;
  294. DtDtsMMDatabase *new_db_ptr;
  295. int rec;
  296. DtDtsDbRecord *rec_ptr;
  297. DtDtsMMRecord *new_rec_ptr;
  298. DtDtsMMRecord *new_rec_ptr_list;
  299. int fld;
  300. DtDtsDbField *fld_ptr;
  301. DtDtsMMField *new_fld_ptr;
  302. DtDtsMMField *new_fld_ptr_list;
  303. int index;
  304. int db_index;
  305. int isnew;
  306. char *tmp;
  307. /* create a space to hold the list of database structures */
  308. new_db_list = (DtDtsMMDatabase *)_DtShmProtoAddIntLst(int_handle,
  309. num_db*sizeof(DtDtsMMDatabase)/sizeof(int),
  310. &db_index);
  311. for(db = 0; db < num_db; db++)
  312. {
  313. int last_boson = -1;
  314. int list_count = 0;
  315. DtShmProtoInttab nameIndex;
  316. int size;
  317. int *idx;
  318. new_db_ptr = &new_db_list[db];
  319. db_ptr = db_list[db];
  320. new_db_ptr->databaseName = _DtShmProtoAddStrtab(shm_handle, db_ptr->databaseName, &isnew);
  321. new_db_ptr->recordCount = db_ptr->recordCount;
  322. /* create space to hold record list */
  323. new_rec_ptr_list = (DtDtsMMRecord *)_DtShmProtoAddIntLst(int_handle,
  324. db_ptr->recordCount*sizeof(DtDtsMMRecord)/sizeof(int),
  325. &index);
  326. new_db_ptr->recordList = index;
  327. /* create index to names list */
  328. nameIndex = _DtShmProtoInitInttab(db_ptr->recordCount);
  329. for(rec = 0; rec < db_ptr->recordCount; rec++)
  330. {
  331. new_rec_ptr = &new_rec_ptr_list[rec];
  332. rec_ptr = db_ptr->recordList[rec];
  333. new_rec_ptr->recordName = QtB(rec_ptr->recordName);
  334. if(new_rec_ptr->recordName != last_boson)
  335. {
  336. /* save name position */
  337. _DtShmProtoAddInttab(nameIndex, new_rec_ptr->recordName, rec);
  338. last_boson = new_rec_ptr->recordName;
  339. }
  340. new_rec_ptr->pathId = _DtShmProtoAddStrtab(shm_handle,
  341. tmp = _DtDbPathIdToString(rec_ptr->pathId),
  342. &isnew);
  343. XtFree(tmp);
  344. new_rec_ptr->seq = rec_ptr->seq;
  345. new_rec_ptr->fieldCount = rec_ptr->fieldCount;
  346. /* create space for field list */
  347. new_fld_ptr_list = (DtDtsMMField *)_DtShmProtoAddIntLst(int_handle,
  348. rec_ptr->fieldCount*sizeof(DtDtsMMField)/sizeof(int),
  349. &index);
  350. new_rec_ptr->fieldList = index;
  351. for(fld = 0; fld < rec_ptr->fieldCount; fld++)
  352. {
  353. new_fld_ptr = &new_fld_ptr_list[fld];
  354. fld_ptr = rec_ptr->fieldList[fld];
  355. new_fld_ptr->fieldName = QtB(fld_ptr->fieldName);
  356. new_fld_ptr->fieldValue = fld_ptr->fieldValue?_DtShmProtoAddStrtab(shm_handle,
  357. fld_ptr->fieldValue, &isnew):0;
  358. }
  359. }
  360. /* create table for index and save it */
  361. size = _DtShmProtoSizeInttab(nameIndex);
  362. idx = _DtShmProtoAddIntLst(int_handle, size/sizeof(int), &new_db_ptr->nameIndex);
  363. _DtShmProtoCopyInttab(nameIndex, (void *)idx);
  364. _DtShmProtoDestroyInttab(nameIndex);
  365. }
  366. return(db_index);
  367. }
  368. struct list
  369. {
  370. DtShmBoson boson;
  371. int rec;
  372. };
  373. static int
  374. srch(const void *a, const void *b)
  375. {
  376. int results = ((struct list *)a)->boson - ((struct list *)b)->boson;
  377. if(results == 0)
  378. {
  379. results = ((struct list *)a)->rec - ((struct list *)b)->rec;
  380. }
  381. return(results);
  382. }
  383. static void
  384. showtable(
  385. DtDtsDbDatabase *db,
  386. struct list *name_index,
  387. struct list *other,
  388. DtDtsMMHeader *head,
  389. int other_break)
  390. {
  391. int i;
  392. printf("============== names =====================\n");
  393. for(i = 0; name_index[i].boson; i++)
  394. {
  395. printf("%20s -> %s\n",
  396. XrmQuarkToString(db->recordList[name_index[i].rec]->recordName),
  397. _DtShmProtoLookUpStrtab(shm_handle,
  398. name_index[i].boson));
  399. }
  400. printf("%d entries\n", i);
  401. printf("============= other ======================\n");
  402. for(i = 0; i < other_break; i++)
  403. {
  404. printf("%s\n",
  405. XrmQuarkToString(db->recordList[other[i].rec]->recordName));
  406. }
  407. printf("%d entries\n", i);
  408. }
  409. static int
  410. build_name_list(DtDtsDbDatabase *db,
  411. DtShmProtoIntList int_handle,
  412. DtDtsMMHeader *head)
  413. {
  414. struct list *other;
  415. int i;
  416. char *c;
  417. int isnew;
  418. struct list *name_index;
  419. int next = 0;
  420. int other_break = 0;
  421. DtShmProtoInttab indexList = 0;
  422. DtShmBoson last_boson = -1;
  423. int *list_of_recs = 0;
  424. int list_count = 0;
  425. int index = 0;
  426. int size;
  427. void *space;
  428. /* create tmp space for two lists */
  429. name_index = (struct list *)calloc(db->recordCount*2,
  430. sizeof(struct list));
  431. other = (struct list *)calloc(db->recordCount, sizeof(struct list));
  432. /* step through all records */
  433. for(i = 0; i < db->recordCount; i++)
  434. {
  435. DtShmBoson boson;
  436. char *attr;
  437. char *t;
  438. /* see if a name pattern exist */
  439. attr = _DtDtsDbGetFieldByName(db->recordList[i],
  440. DtDTS_NAME_PATTERN);
  441. if(!attr)
  442. {
  443. /* it didn't so check path pattern */
  444. attr = _DtDtsDbGetFieldByName(db->recordList[i],
  445. DtDTS_PATH_PATTERN);
  446. if(!attr)
  447. {
  448. /* neither exist so save it as plain buffer */
  449. if(!head->buffer_start_index)
  450. {
  451. head->buffer_start_index = other_break;
  452. }
  453. other[other_break++].rec = i;
  454. continue; /* go to next record */
  455. }
  456. }
  457. /* we have a name now find its final component */
  458. c = strrchr(attr, '/');
  459. if(c)
  460. {
  461. c++;
  462. }
  463. if(!c)
  464. {
  465. c = attr;
  466. }
  467. else
  468. {
  469. attr = c;
  470. }
  471. /* now see if that final component has any *,?,[ */
  472. while(c && *c &&
  473. !(*c == '*' ||
  474. *c == '[' ||
  475. *c == '?' ||
  476. *c == '$' ))
  477. {
  478. c++;
  479. }
  480. if(c && *c == '\0')
  481. {
  482. /* it doesn't so save it in the name index */
  483. name_index[next].boson =
  484. _DtShmProtoAddStrtab(shm_handle,
  485. (const char *)attr, &isnew);
  486. name_index[next++].rec = i;
  487. continue; /* next record */
  488. }
  489. /* the name had something in it now lets get the suffix */
  490. c = strrchr(attr, '.');
  491. attr = c;
  492. /* lets see if the suffix has any *,?,[ */
  493. while(c && *c &&
  494. !(*c == '*' ||
  495. *c == '[' ||
  496. *c == '?' ||
  497. *c == '$' ))
  498. {
  499. c++;
  500. }
  501. if(c && *c == '\0')
  502. {
  503. /* it doesn't so save it in the name index */
  504. name_index[next].boson =
  505. _DtShmProtoAddStrtab(shm_handle,
  506. (const char *)attr, &isnew);
  507. name_index[next++].rec = i;
  508. }
  509. else
  510. {
  511. /* couldn't find any thing so save it as other */
  512. other[other_break++].rec = i;
  513. }
  514. }
  515. if (next > 0)
  516. {
  517. qsort(name_index, next, sizeof(struct list), srch);
  518. }
  519. /*
  520. showtable(db, name_index, other, head, other_break);
  521. printf(" next = %d\n", next);
  522. printf(" other_break = %d\n", other_break);
  523. printf("head->buffer_start_index = %d\n", head->buffer_start_index);
  524. */
  525. /* create a table and add the records to it. However
  526. duplicates need to be in separate lists.
  527. */
  528. indexList = _DtShmProtoInitInttab(next+3);
  529. for(i = 0; i <= next; i++)
  530. {
  531. if(i != next && (last_boson == -1 || name_index[i].boson == last_boson))
  532. {
  533. /* this a new list of records or an addition to one */
  534. list_of_recs = (int *)realloc(list_of_recs,
  535. ++list_count*sizeof(int));
  536. last_boson = name_index[i].boson;
  537. list_of_recs[list_count-1] = name_index[i].rec;
  538. }
  539. else
  540. {
  541. /* we reached the end of a list now we check how many
  542. are in the list.
  543. */
  544. if(list_count == 1)
  545. {
  546. /* if just one just add it in the index */
  547. _DtShmProtoAddInttab(indexList,
  548. last_boson, list_of_recs[0]);
  549. }
  550. else
  551. {
  552. /* if there are multiple items in the list
  553. create a table for them */
  554. int *list = _DtShmProtoAddIntLst(int_handle,
  555. list_count, &index);
  556. /* write the list to the to the table */
  557. memcpy(list, list_of_recs,
  558. list_count*sizeof(int));
  559. /* then index on the negative of the boson
  560. so that we know it is a list */
  561. _DtShmProtoAddInttab(indexList,
  562. last_boson, -index);
  563. list_count = 0;
  564. list_of_recs = (int *)realloc(list_of_recs,
  565. ++list_count*sizeof(int));
  566. }
  567. if ( i != next )
  568. {
  569. /* reset for the next set */
  570. last_boson = name_index[i].boson;
  571. list_of_recs[list_count-1] = name_index[i].rec;
  572. }
  573. }
  574. }
  575. /* same thing but they all go into a separate list */
  576. if(other_break > 0)
  577. {
  578. /* create the space */
  579. int *list = _DtShmProtoAddIntLst(int_handle,
  580. other_break, &head->no_name_offset);
  581. /* copy it into the list */
  582. for(i = 0; i < other_break; i++)
  583. {
  584. list[i] = other[i].rec;
  585. }
  586. }
  587. else
  588. {
  589. head->no_name_offset = -1;
  590. }
  591. /* make the real space */
  592. size = _DtShmProtoSizeInttab(indexList);
  593. space = _DtShmProtoAddIntLst(int_handle, size/sizeof(int),
  594. &head->name_list_offset);
  595. _DtShmProtoCopyInttab(indexList, space);
  596. _DtShmProtoDestroyInttab(indexList);
  597. free(name_index);
  598. free(list_of_recs);
  599. free(other);
  600. return(index);
  601. }
  602. static int
  603. write_db(DtDtsMMHeader *header, void *index, int size, const char *CacheFile)
  604. {
  605. int fd;
  606. mode_t cmask = umask((mode_t)077);
  607. char *tmpfile;
  608. if ((tmpfile = malloc(sizeof(_DTDTSMMTEMPDIR) +
  609. sizeof(_DTDTSMMTEMPFILE) + 7)) == NULL) {
  610. _DtSimpleError(DtProgName, DtError, NULL, tmpfile, NULL);
  611. return 0;
  612. }
  613. sprintf(tmpfile, "%s/%sXXXXXX", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE);
  614. fd = mkstemp(tmpfile);
  615. umask(cmask);
  616. if(fd == -1)
  617. {
  618. _DtSimpleError(
  619. DtProgName, DtError, NULL,
  620. (char*) tmpfile, NULL);
  621. free(tmpfile);
  622. return(0);
  623. }
  624. /* Remove file on write failure - we don't */
  625. /* want a partial dtdbcache file. */
  626. if ((write(fd, header, sizeof(DtDtsMMHeader))
  627. != sizeof(DtDtsMMHeader)) ||
  628. (write(fd, index, size) != size))
  629. {
  630. close(fd);
  631. unlink(tmpfile);
  632. free(tmpfile);
  633. return(0);
  634. }
  635. close(fd);
  636. if(rename((const char *)tmpfile, CacheFile) == -1)
  637. {
  638. _DtSimpleError(
  639. DtProgName, DtError, NULL,
  640. (char*) CacheFile, NULL);
  641. unlink(CacheFile); /* Just in case? */
  642. unlink(tmpfile);
  643. free(tmpfile);
  644. return(0);
  645. }
  646. free(tmpfile);
  647. return(1);
  648. }
  649. intptr_t _DtActionCompareRecordBoson(
  650. DtDtsMMRecord *record1,
  651. DtDtsMMRecord *record2 )
  652. {
  653. int results = (int)record1->recordName - (int)record2->recordName;
  654. if (results)
  655. return(results);
  656. return((intptr_t)record1 - (intptr_t)record2);
  657. }