123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $TOG: MMDb.c /main/19 1998/10/23 13:48:52 mgreess $ */
- /*
- * +SNOTICE
- *
- * Copyright 1995 Sun Microsystems, Inc. All rights reserved.
- *
- * +ENOTICE
- */
- #include <stdio.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <sys/utsname.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdint.h>
- #ifdef NLS16
- #include <limits.h>
- #endif
- #include <sys/stat.h>
- #include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
- #define X_INCLUDE_DIRENT_H
- #define XOS_USE_XT_LOCKING
- #include <X11/Xos_r.h>
- #include <Dt/DbReader.h>
- #include <Dt/DtsDb.h>
- #include <Dt/DtsMM.h>
- #include <Dt/DtShmDb.h>
- #include <Dt/Dts.h>
- #include <Dt/ActionP.h>
- #include <Dt/ActionDbP.h>
- #include <Dt/ActionUtilP.h>
- #include <Dt/DtNlUtils.h>
- #include <Dt/UserMsg.h>
- #include "myassertP.h"
- #include "DtSvcLock.h"
- static void build_file_list(DtShmProtoIntList, DtDirPaths *,
- DtDtsMMHeader *, const char *);
- extern int cde_dc_field_compare(DtDtsDbField **, DtDtsDbField **);
- extern int cde_dc_compare(DtDtsDbRecord **, DtDtsDbRecord **);
- static void _DtMMSortDataTypes(DtShmProtoStrtab str_handle);
- static void _DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr);
- static int write_db(DtDtsMMHeader *header, void *index, int size,
- const char *CacheFile);
- static int build_new_db(DtShmProtoStrtab, DtShmProtoIntList, int, DtDtsDbDatabase **);
- static int build_name_list(DtDtsDbDatabase *, DtShmProtoIntList, DtDtsMMHeader *);
- static DtShmProtoStrtab shm_handle = 0;
- static DtShmProtoIntList int_handle = 0;
- #define QtB(a) _DtShmProtoAddStrtab(shm_handle, XrmQuarkToString(a), &isnew)
- /* DtsMM.c */
- extern int _DtDtsMMPathHash(DtDirPaths *dirs);
- int
- _MMWriteDb(DtDirPaths *dirs, int num_db, DtDtsDbDatabase **db_list,
- const char *CacheFile)
- {
- DtDtsMMHeader header;
- char *suffix = ".dt";
- int tbl_size;
- void *tbl_data;
- DtDtsDbDatabase *db;
- int returnCode;
- _DtSvcProcessLock();
- memset(&header, '\0', sizeof(header));
- int_handle = _DtShmProtoInitIntLst(50000);
- shm_handle = _DtShmProtoInitStrtab(10000);
- build_file_list(int_handle, dirs, &header, suffix);
- _DtMMSortDataTypes(shm_handle);
- db = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
- _DtMMAddActionsToDataAttribute(db);
- header.pathhash = _DtDtsMMPathHash(dirs);
- header.num_db = num_db;
- header.db_offset = build_new_db(shm_handle, int_handle, num_db,
- db_list);
- db = (DtDtsDbDatabase *) _DtDtsDbGet("DATA_CRITERIA");
- build_name_list(db, int_handle, &header);
- tbl_size = _DtShmProtoSizeStrtab(shm_handle);
- tbl_data = (void *) _DtShmProtoAddIntLst(int_handle,
- tbl_size/sizeof(int), &header.str_tbl_offset);
- _DtShmProtoCopyStrtab(shm_handle, tbl_data);
- tbl_size = _DtShmProtoSizeIntLst(int_handle);
- tbl_data = (void *)malloc(tbl_size);
- memset(tbl_data, '\0', tbl_size);
- tbl_data = (void *)_DtShmProtoCopyIntLst(int_handle, tbl_data);
- returnCode = write_db(&header, tbl_data, tbl_size, CacheFile);
- _DtShmProtoDestroyStrtab(shm_handle);
- _DtShmProtoDestroyIntLst(int_handle);
- _DtSvcProcessUnlock();
- free(tbl_data);
- return returnCode;
- }
- static void
- build_file_list(DtShmProtoIntList int_handle, DtDirPaths *dirs,
- DtDtsMMHeader *header, const char *suffix)
- {
- DIR *dirp;
- struct dirent *dp = NULL;
- struct stat buf;
- char cur_path[MAXPATHLEN+1];
- void *data;
- int size = sizeof(buf.st_mtime);
- int i;
- int isnew;
- DtShmBoson *boson_list = 0;
- time_t *mtime_list = 0;
- int count = 0;
- _Xreaddirparams dirEntryBuf;
- struct dirent *result;
- /* Theses here to make sure it gets into the string tables
- because actions uses it in its "types" field. */
- _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_UNKNOWN, &isnew);
- _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_RECURSIVE_LINK, &isnew);
- _DtShmProtoAddStrtab(shm_handle, DtDTS_DT_BROKEN_LINK, &isnew);
- getcwd(cur_path, sizeof(cur_path));
- for(i = 0; dirs->paths[i]; i++)
- {
- chdir(dirs->paths[i]);
- stat(".", &buf);
- count++;
- boson_list = (int *)realloc(boson_list, count*sizeof(int));
- mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
- mtime_list[count-1] = buf.st_mtime;
- boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle, dirs->paths[i], &isnew);
- dirp = opendir(".");
- while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
- {
- char *c = strrchr(result->d_name, suffix[0]);
- if(c && strcmp(c, suffix) == 0)
- {
- char *pathname = malloc(MAXPATHLEN+1);
- sprintf(pathname, "%s/%s", dirs->paths[i], result->d_name);
- stat(result->d_name, &buf);
- count++;
- boson_list = (int *)realloc(boson_list, count*sizeof(int));
- mtime_list = (time_t *)realloc(mtime_list, count*sizeof(time_t));
- mtime_list[count-1] = buf.st_mtime;
- boson_list[count-1] = _DtShmProtoAddStrtab(shm_handle,
- pathname, &isnew);
- free(pathname);
- continue;
- }
- }
- (void)closedir( dirp );
- }
- chdir(cur_path);
- data = _DtShmProtoAddIntLst(int_handle, count, &header->files_offset);
- memcpy(data, boson_list, count*sizeof(int));
- data = _DtShmProtoAddIntLst(int_handle, count*sizeof(time_t)/sizeof(int), &header->mtimes_offset);
- memcpy(data, mtime_list, count*sizeof(time_t));
- header->files_count = count;
- free(boson_list);
- free(mtime_list);
- return;
- }
- static int
- db_table_size(int num_db, DtDtsDbDatabase **db_list)
- {
- int db;
- DtDtsDbDatabase *db_ptr;
- int rec;
- DtDtsDbRecord *rec_ptr;
- int fld;
- DtDtsDbField *fld_ptr;
- int size = 0;
- size += num_db*sizeof(DtDtsMMDatabase);
- for(db = 0; db < num_db; db++)
- {
- db_ptr = db_list[db];
- size += db_ptr->recordCount * sizeof(DtDtsMMRecord);
- for(rec = 0; rec < db_ptr->recordCount; rec++)
- {
- rec_ptr = db_ptr->recordList[rec];
- size += rec_ptr->fieldCount * sizeof(DtDtsMMField);
- }
- }
- return(size/sizeof(int));
- }
- static void
- _DtMMSortDataTypes(DtShmProtoStrtab str_handle)
- {
- DtDtsDbDatabase *dc;
- DtDtsDbDatabase *da;
- int i;
- _DtSvcProcessLock();
- dc = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DC_NAME);
- da = (DtDtsDbDatabase *) _DtDtsDbGet(DtDTS_DA_NAME);
- /*_DtDtsDbPrintRecords(dc, stdout);*/
- for(i = 0; i < dc->recordCount; i++)
- {
- if(dc->recordList[i]->compare != cde_dc_field_compare)
- {
- _DtDtsDbFieldSort(dc->recordList[i],
- cde_dc_field_compare);
- }
- }
- _DtDtsDbRecordSort(dc, cde_dc_compare);
- for(i = 0; i < da->recordCount; i++)
- {
- if(da->recordList[i]->compare !=
- _DtDtsDbCompareFieldNames)
- {
- _DtDtsDbFieldSort(da->recordList[i],
- _DtDtsDbCompareFieldNames);
- }
- }
- _DtDtsDbRecordSort(da, _DtDtsDbCompareRecordNames);
- /*_DtDtsDbPrintRecords(dc, stdout);*/
- _DtSvcProcessUnlock();
- }
- static void
- add_if_missing(DtDtsDbRecord *rec_ptr, XrmQuark name, char *value)
- {
- DtDtsDbField *fld_ptr;
- int fld;
- int found = 0;
- for(fld = 0; fld < rec_ptr->fieldCount; fld++)
- {
- fld_ptr = rec_ptr->fieldList[fld];
- if(name == fld_ptr->fieldName)
- {
- found = 1;
- break;
- }
- }
- if(found)
- {
- return;
- }
- fld_ptr = _DtDtsDbAddField(rec_ptr);
- fld_ptr->fieldName = name;
- fld_ptr->fieldValue = value;
- _DtDtsDbFieldSort(rec_ptr, 0);
- return;
- }
- static void
- _DtMMAddActionsToDataAttribute(DtDtsDbDatabase *db_ptr)
- {
- int rec;
- DtDtsDbRecord *rec_ptr;
- int action_flag = 0;
- int sort_flag = 0;
- int found_flag = 0;
- int n;
- const char *tmp;
- XrmQuark desc_qrk = XrmStringToQuark(DtDTS_DA_DESCRIPTION);
- XrmQuark icon_qrk = XrmStringToQuark(DtDTS_DA_ICON);
- XrmQuark label_qrk = XrmStringToQuark(DtDTS_DA_LABEL);
- for(rec = 0; rec < db_ptr->recordCount; rec++)
- {
- int found_des = 0;
- int found_icon = 0;
- int found_label = 0;
- char *obj_type;
- rec_ptr = db_ptr->recordList[rec];
- obj_type = XrmQuarkToString(rec_ptr->recordName);
- if ( _DtDtsDbGetFieldByName(rec_ptr,
- DtDTS_DA_IS_ACTION) == 0 )
- {
- continue;
- }
- add_if_missing(rec_ptr, desc_qrk,
- DtActionDescription(obj_type));
- add_if_missing(rec_ptr, icon_qrk, DtActionIcon(obj_type));
- add_if_missing(rec_ptr, label_qrk, DtActionLabel(obj_type));
- }
- }
- static int
- build_new_db(DtShmProtoStrtab shm_handle, DtShmProtoIntList int_handle, int num_db, DtDtsDbDatabase **db_list)
- {
- DtDtsMMDatabase *new_db_list;
- int db;
- DtDtsDbDatabase *db_ptr;
- DtDtsMMDatabase *new_db_ptr;
- int rec;
- DtDtsDbRecord *rec_ptr;
- DtDtsMMRecord *new_rec_ptr;
- DtDtsMMRecord *new_rec_ptr_list;
- int fld;
- DtDtsDbField *fld_ptr;
- DtDtsMMField *new_fld_ptr;
- DtDtsMMField *new_fld_ptr_list;
- int index;
- int db_index;
- int isnew;
- char *tmp;
- /* create a space to hold the list of database structures */
- new_db_list = (DtDtsMMDatabase *)_DtShmProtoAddIntLst(int_handle,
- num_db*sizeof(DtDtsMMDatabase)/sizeof(int),
- &db_index);
- for(db = 0; db < num_db; db++)
- {
- int last_boson = -1;
- int list_count = 0;
- DtShmProtoInttab nameIndex;
- int size;
- int *idx;
- new_db_ptr = &new_db_list[db];
- db_ptr = db_list[db];
- new_db_ptr->databaseName = _DtShmProtoAddStrtab(shm_handle, db_ptr->databaseName, &isnew);
- new_db_ptr->recordCount = db_ptr->recordCount;
- /* create space to hold record list */
- new_rec_ptr_list = (DtDtsMMRecord *)_DtShmProtoAddIntLst(int_handle,
- db_ptr->recordCount*sizeof(DtDtsMMRecord)/sizeof(int),
- &index);
- new_db_ptr->recordList = index;
- /* create index to names list */
- nameIndex = _DtShmProtoInitInttab(db_ptr->recordCount);
- for(rec = 0; rec < db_ptr->recordCount; rec++)
- {
- new_rec_ptr = &new_rec_ptr_list[rec];
- rec_ptr = db_ptr->recordList[rec];
- new_rec_ptr->recordName = QtB(rec_ptr->recordName);
- if(new_rec_ptr->recordName != last_boson)
- {
- /* save name position */
- _DtShmProtoAddInttab(nameIndex, new_rec_ptr->recordName, rec);
- last_boson = new_rec_ptr->recordName;
- }
- new_rec_ptr->pathId = _DtShmProtoAddStrtab(shm_handle,
- tmp = _DtDbPathIdToString(rec_ptr->pathId),
- &isnew);
- XtFree(tmp);
- new_rec_ptr->seq = rec_ptr->seq;
- new_rec_ptr->fieldCount = rec_ptr->fieldCount;
- /* create space for field list */
- new_fld_ptr_list = (DtDtsMMField *)_DtShmProtoAddIntLst(int_handle,
- rec_ptr->fieldCount*sizeof(DtDtsMMField)/sizeof(int),
- &index);
- new_rec_ptr->fieldList = index;
- for(fld = 0; fld < rec_ptr->fieldCount; fld++)
- {
- new_fld_ptr = &new_fld_ptr_list[fld];
- fld_ptr = rec_ptr->fieldList[fld];
- new_fld_ptr->fieldName = QtB(fld_ptr->fieldName);
- new_fld_ptr->fieldValue = fld_ptr->fieldValue?_DtShmProtoAddStrtab(shm_handle,
- fld_ptr->fieldValue, &isnew):0;
- }
- }
- /* create table for index and save it */
- size = _DtShmProtoSizeInttab(nameIndex);
- idx = _DtShmProtoAddIntLst(int_handle, size/sizeof(int), &new_db_ptr->nameIndex);
- _DtShmProtoCopyInttab(nameIndex, (void *)idx);
- _DtShmProtoDestroyInttab(nameIndex);
- }
- return(db_index);
- }
- struct list
- {
- DtShmBoson boson;
- int rec;
- };
- static int
- srch(const void *a, const void *b)
- {
- int results = ((struct list *)a)->boson - ((struct list *)b)->boson;
- if(results == 0)
- {
- results = ((struct list *)a)->rec - ((struct list *)b)->rec;
- }
- return(results);
- }
- static void
- showtable(
- DtDtsDbDatabase *db,
- struct list *name_index,
- struct list *other,
- DtDtsMMHeader *head,
- int other_break)
- {
- int i;
- printf("============== names =====================\n");
- for(i = 0; name_index[i].boson; i++)
- {
- printf("%20s -> %s\n",
- XrmQuarkToString(db->recordList[name_index[i].rec]->recordName),
- _DtShmProtoLookUpStrtab(shm_handle,
- name_index[i].boson));
- }
- printf("%d entries\n", i);
-
- printf("============= other ======================\n");
- for(i = 0; i < other_break; i++)
- {
- printf("%s\n",
- XrmQuarkToString(db->recordList[other[i].rec]->recordName));
- }
- printf("%d entries\n", i);
- }
- static int
- build_name_list(DtDtsDbDatabase *db,
- DtShmProtoIntList int_handle,
- DtDtsMMHeader *head)
- {
- struct list *other;
- int i;
- char *c;
- int isnew;
- struct list *name_index;
- int next = 0;
- int other_break = 0;
- DtShmProtoInttab indexList = 0;
- DtShmBoson last_boson = -1;
- int *list_of_recs = 0;
- int list_count = 0;
- int index = 0;
- int size;
- void *space;
- /* create tmp space for two lists */
- name_index = (struct list *)calloc(db->recordCount*2,
- sizeof(struct list));
- other = (struct list *)calloc(db->recordCount, sizeof(struct list));
- /* step through all records */
- for(i = 0; i < db->recordCount; i++)
- {
- DtShmBoson boson;
- char *attr;
- char *t;
- /* see if a name pattern exist */
- attr = _DtDtsDbGetFieldByName(db->recordList[i],
- DtDTS_NAME_PATTERN);
- if(!attr)
- {
- /* it didn't so check path pattern */
- attr = _DtDtsDbGetFieldByName(db->recordList[i],
- DtDTS_PATH_PATTERN);
- if(!attr)
- {
- /* neither exist so save it as plain buffer */
- if(!head->buffer_start_index)
- {
- head->buffer_start_index = other_break;
- }
- other[other_break++].rec = i;
- continue; /* go to next record */
- }
- }
- /* we have a name now find its final component */
- c = strrchr(attr, '/');
- if(c)
- {
- c++;
- }
- if(!c)
- {
- c = attr;
- }
- else
- {
- attr = c;
- }
- /* now see if that final component has any *,?,[ */
- while(c && *c &&
- !(*c == '*' ||
- *c == '[' ||
- *c == '?' ||
- *c == '$' ))
- {
- c++;
- }
- if(c && *c == '\0')
- {
- /* it doesn't so save it in the name index */
- name_index[next].boson =
- _DtShmProtoAddStrtab(shm_handle,
- (const char *)attr, &isnew);
- name_index[next++].rec = i;
- continue; /* next record */
- }
- /* the name had something in it now lets get the suffix */
- c = strrchr(attr, '.');
- attr = c;
- /* lets see if the suffix has any *,?,[ */
- while(c && *c &&
- !(*c == '*' ||
- *c == '[' ||
- *c == '?' ||
- *c == '$' ))
- {
- c++;
- }
- if(c && *c == '\0')
- {
- /* it doesn't so save it in the name index */
- name_index[next].boson =
- _DtShmProtoAddStrtab(shm_handle,
- (const char *)attr, &isnew);
- name_index[next++].rec = i;
- }
- else
- {
- /* couldn't find any thing so save it as other */
- other[other_break++].rec = i;
- }
- }
- if (next > 0)
- {
- qsort(name_index, next, sizeof(struct list), srch);
- }
- /*
- showtable(db, name_index, other, head, other_break);
- printf(" next = %d\n", next);
- printf(" other_break = %d\n", other_break);
- printf("head->buffer_start_index = %d\n", head->buffer_start_index);
- */
- /* create a table and add the records to it. However
- duplicates need to be in separate lists.
- */
- indexList = _DtShmProtoInitInttab(next+3);
- for(i = 0; i <= next; i++)
- {
- if(i != next && (last_boson == -1 || name_index[i].boson == last_boson))
- {
- /* this a new list of records or an addition to one */
- list_of_recs = (int *)realloc(list_of_recs,
- ++list_count*sizeof(int));
- last_boson = name_index[i].boson;
- list_of_recs[list_count-1] = name_index[i].rec;
- }
- else
- {
- /* we reached the end of a list now we check how many
- are in the list.
- */
- if(list_count == 1)
- {
- /* if just one just add it in the index */
- _DtShmProtoAddInttab(indexList,
- last_boson, list_of_recs[0]);
- }
- else
- {
- /* if there are multiple items in the list
- create a table for them */
- int *list = _DtShmProtoAddIntLst(int_handle,
- list_count, &index);
- /* write the list to the to the table */
- memcpy(list, list_of_recs,
- list_count*sizeof(int));
- /* then index on the negative of the boson
- so that we know it is a list */
- _DtShmProtoAddInttab(indexList,
- last_boson, -index);
- list_count = 0;
- list_of_recs = (int *)realloc(list_of_recs,
- ++list_count*sizeof(int));
- }
- if ( i != next )
- {
- /* reset for the next set */
- last_boson = name_index[i].boson;
- list_of_recs[list_count-1] = name_index[i].rec;
- }
- }
- }
- /* same thing but they all go into a separate list */
- if(other_break > 0)
- {
- /* create the space */
- int *list = _DtShmProtoAddIntLst(int_handle,
- other_break, &head->no_name_offset);
- /* copy it into the list */
- for(i = 0; i < other_break; i++)
- {
- list[i] = other[i].rec;
- }
- }
- else
- {
- head->no_name_offset = -1;
- }
- /* make the real space */
- size = _DtShmProtoSizeInttab(indexList);
- space = _DtShmProtoAddIntLst(int_handle, size/sizeof(int),
- &head->name_list_offset);
- _DtShmProtoCopyInttab(indexList, space);
- _DtShmProtoDestroyInttab(indexList);
- free(name_index);
- free(list_of_recs);
- free(other);
- return(index);
- }
- static int
- write_db(DtDtsMMHeader *header, void *index, int size, const char *CacheFile)
- {
- int fd;
- mode_t cmask = umask((mode_t)077);
- char *tmpfile;
- if ((tmpfile = malloc(sizeof(_DTDTSMMTEMPDIR) +
- sizeof(_DTDTSMMTEMPFILE) + 7)) == NULL) {
- _DtSimpleError(DtProgName, DtError, NULL, tmpfile, NULL);
- return 0;
- }
- sprintf(tmpfile, "%s/%sXXXXXX", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE);
- fd = mkstemp(tmpfile);
- umask(cmask);
- if(fd == -1)
- {
- _DtSimpleError(
- DtProgName, DtError, NULL,
- (char*) tmpfile, NULL);
- free(tmpfile);
- return(0);
- }
- /* Remove file on write failure - we don't */
- /* want a partial dtdbcache file. */
- if ((write(fd, header, sizeof(DtDtsMMHeader))
- != sizeof(DtDtsMMHeader)) ||
- (write(fd, index, size) != size))
- {
- close(fd);
- unlink(tmpfile);
- free(tmpfile);
- return(0);
- }
- close(fd);
- if(rename((const char *)tmpfile, CacheFile) == -1)
- {
- _DtSimpleError(
- DtProgName, DtError, NULL,
- (char*) CacheFile, NULL);
- unlink(CacheFile); /* Just in case? */
- unlink(tmpfile);
- free(tmpfile);
- return(0);
- }
- free(tmpfile);
- return(1);
- }
- intptr_t _DtActionCompareRecordBoson(
- DtDtsMMRecord *record1,
- DtDtsMMRecord *record2 )
- {
- int results = (int)record1->recordName - (int)record2->recordName;
- if (results)
- return(results);
- return((intptr_t)record1 - (intptr_t)record2);
- }
|