2 * $TOG: DtsMM.c /main/16 1998/10/23 13:48:28 mgreess $
4 * RESTRICTED CONFIDENTIAL INFORMATION:
6 * (c) Copyright 1993,1994,1995 Sun Microsystems, Inc.
13 #include <sys/types.h>
18 #include <sys/utsname.h>
21 #include <sys/param.h>
24 #define X_INCLUDE_DIRENT_H
25 #define XOS_USE_XT_LOCKING
26 #include <X11/Xos_r.h>
27 #include <Dt/DbReader.h>
29 #include "Dt/DtNlUtils.h"
30 #include <Dt/UserMsg.h>
31 #include "DtSvcLock.h"
33 extern char *strdup(const char *);
34 static int MMValidateDb(DtDirPaths *dirs, char *suffix);
35 static int _debug_print_name(char *name, char *label);
37 typedef int (*genfunc)(const void *, const void *);
39 static DtDtsMMDatabase *db_list;
40 static caddr_t mmaped_db = 0;
41 static size_t mmaped_size = 0;
42 static int mmaped_fd = 0;
43 static DtDtsMMHeader *head = 0;
46 _DtDtsMMGetPtr(int index)
48 DtShmIntList int_list;
55 int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
56 _DtSvcProcessUnlock();
57 return((void *)&int_list[index]);
61 _DtDtsMMGetPtrSize(int index)
63 DtShmIntList int_list;
70 int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
71 _DtSvcProcessUnlock();
72 return(int_list[index-1]);
76 _DtDtsMMGetDCNameIndex(int *size)
81 *size = _DtDtsMMGetPtrSize(head->name_list_offset);
82 result = (int*) _DtDtsMMGetPtr(head->name_list_offset);
83 _DtSvcProcessUnlock();
88 _DtDtsMMGetDbName(DtDtsMMDatabase *db, DtShmBoson boson)
90 DtShmInttab tab = (DtShmInttab)_DtDtsMMGetPtr(db->nameIndex);
91 return((int *)_DtShmFindIntTabEntry(tab, boson));
95 _DtDtsMMGetNoNameIndex(int *size)
101 if(head->no_name_offset == -1)
104 _DtSvcProcessUnlock();
107 *size = _DtDtsMMGetPtrSize(head->no_name_offset);
108 result = (int *) _DtDtsMMGetPtr(head->no_name_offset);
109 _DtSvcProcessUnlock();
113 /* returns the pointer to buffer only name list */
115 _DtDtsMMGetBufferIndex(int *size)
117 int *list = (int*)_DtDtsMMGetNoNameIndex(size);
121 *size -= head->buffer_start_index;
122 bufferIndex = &list[head->buffer_start_index];
123 _DtSvcProcessUnlock();
129 _DtDtsMMGetFileList(void)
131 DtShmInttab file_index;
134 file_index = (DtShmStrtab)_DtDtsMMGetPtr(head->files_offset);
135 _DtSvcProcessUnlock();
140 _DtDtsMMBosonToString(DtShmBoson boson)
142 DtShmStrtab str_table;
153 str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
154 _DtSvcProcessUnlock();
156 return(_DtShmBosonToString(str_table, boson));
160 _DtDtsMMStringToBoson(const char *string)
162 DtShmStrtab str_table;
164 if ((string == (char *)NULL) || (*string == '\0'))
173 str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
174 _DtSvcProcessUnlock();
176 return(_DtShmStringToBoson(str_table, string));
180 _DtDtsMMPrintFld(int fld, DtDtsMMField *fld_ptr, FILE *fd_in)
188 tmp = _DtDtsMMBosonToString(fld_ptr->fieldName);
189 tmpv = _DtDtsMMBosonToString(fld_ptr->fieldValue);
190 fprintf(fd, "\t\t[%d]\t%s(%d)\t%s(%d)\n", fld, tmp,fld_ptr->fieldName,
191 tmpv?tmpv:"(NULL)", fld_ptr->fieldValue);
195 _DtDtsMMPrintRec(int rec, DtDtsMMRecord *rec_ptr, FILE *fd_in)
198 DtDtsMMField *fld_ptr;
199 DtDtsMMField *fld_ptr_list;
205 tmp = _DtDtsMMBosonToString(rec_ptr->recordName);
206 fprintf(fd, "\tRec[%d] name = %s(%d)\n\t%d Fields\n", rec,
207 tmp, rec_ptr->recordName,
208 rec_ptr->fieldCount);
209 fld_ptr_list = _DtDtsMMGetPtr(rec_ptr->fieldList);
210 for(fld = 0; fld < rec_ptr->fieldCount; fld++)
212 fld_ptr = &fld_ptr_list[fld];
213 _DtDtsMMPrintFld(fld, fld_ptr, fd);
218 _DtDtsMMPrintDb(int db, DtDtsMMDatabase *db_ptr, FILE *fd_in)
221 DtDtsMMRecord *rec_ptr;
222 DtDtsMMRecord *rec_ptr_list;
228 fprintf(fd, "DB[%d] ", db);
229 tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
230 fprintf(fd, "name = %s(%d)\n", tmp, db_ptr->databaseName);
231 fprintf(fd, "%d Records\n", db_ptr->recordCount);
232 rec_ptr_list = _DtDtsMMGetPtr(db_ptr->recordList);
233 for(rec = 0; rec < db_ptr->recordCount; rec++)
235 rec_ptr = &rec_ptr_list[rec];
236 _DtDtsMMPrintRec(rec, rec_ptr, fd);
241 _DtDtsMMPrint(FILE *org_fd)
244 DtDtsMMDatabase *db_ptr;
254 for(db = 0; db < head->num_db; db++)
256 db_ptr = &db_list[db];
260 tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
261 if((fd = fopen(tmp, "w")) == NULL)
264 DtProgName, DtError, NULL,
269 _DtDtsMMPrintDb(db, db_ptr, fd);
276 _DtSvcProcessUnlock();
280 _DtDtsMMCompareRecordNames(DtDtsMMRecord *a, DtDtsMMRecord *b)
282 return (a->recordName - b->recordName);
286 _DtDtsMMCompareFieldNames(DtDtsMMField *a, DtDtsMMField *b)
288 return (a->fieldName - b->fieldName);
294 _DtDtsMMInit(int override)
296 DtDirPaths *dirs = _DtGetDatabaseDirPaths();
297 char *CacheFile = _DtDtsMMCacheName(1);
300 if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
303 _DtFreeDatabaseDirPaths(dirs);
306 _debug_print_name(CacheFile, "Init");
310 int success = _DtDtsMMapDB(CacheFile);
313 if(!MMValidateDb(dirs, ".dt"))
319 _debug_print_name(CacheFile, "Mapped");
325 CacheFile = _DtDtsMMCacheName(0);
326 _debug_print_name(CacheFile, "Private");
327 /* Check return status, and pass status to caller. */
328 if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
331 _DtFreeDatabaseDirPaths(dirs);
337 _DtFreeDatabaseDirPaths(dirs);
353 list = (char **)malloc((head->num_db+1)*sizeof(char *));
354 for ( i = 0; i < head->num_db; i++ )
356 list[i] = (char *)_DtDtsMMBosonToString(db_list[i].databaseName);
359 _DtSvcProcessUnlock();
365 _DtDtsMMGet(const char *name)
368 DtShmBoson boson = _DtDtsMMStringToBoson(name);
369 DtDtsMMDatabase *ret_db;
376 for(i = 0; i < head->num_db; i++)
378 if(db_list[i].databaseName == boson)
380 ret_db = &db_list[i];
381 _DtSvcProcessUnlock();
386 _DtSvcProcessUnlock();
392 _DtDtsMMGetField(DtDtsMMRecord *rec, const char *name)
396 DtDtsMMField *fld_ptr;
397 DtDtsMMField *fld_ptr_list;
400 * Field names have been quarked so quark 'name' and
401 * do a linear search for the quark'ed field name.
403 DtShmBoson tmp = _DtDtsMMStringToBoson (name);
405 fld_ptr_list = _DtDtsMMGetPtr(rec->fieldList);
406 for (i = 0; i < rec->fieldCount; i++)
408 fld_ptr = &fld_ptr_list[i];
409 if (fld_ptr->fieldName == tmp)
418 _DtDtsMMGetFieldByName(DtDtsMMRecord *rec, const char *name)
420 DtDtsMMField *result;
422 result = _DtDtsMMGetField(rec, name);
425 return(_DtDtsMMBosonToString(result->fieldValue));
435 _DtDtsMMGetRecordByName(DtDtsMMDatabase *db, const char *name)
438 DtDtsMMRecord *result;
439 DtDtsMMRecord *s = &srch;
441 DtShmBoson name_quark = _DtDtsMMStringToBoson(name);
442 DtDtsMMRecord *rec_ptr;
443 DtDtsMMRecord *rec_ptr_list;
446 * If the fields are not sorted in alphanumeric order
447 * by name a binary search will fail. So do the slow but
448 * sure linear search.
450 rec_ptr_list = _DtDtsMMGetPtr(db->recordList);
452 for (i = 0; i < db->recordCount; i++)
454 rec_ptr = &rec_ptr_list[i];
455 if (rec_ptr->recordName == name_quark)
463 _DtDtsMMPathHash(DtDirPaths *dirs)
467 struct dirent *dp = NULL;
472 char *suffix = ".dt";
474 char *cur_dir = getcwd(0,MAXPATHLEN);
477 _Xreaddirparams dirEntryBuf;
478 struct dirent *result;
480 for(i = 0; dirs->paths[i] ; i++)
482 if(chdir(dirs->paths[i]) == -1)
486 dirp = opendir (".");
487 while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
489 if ((int)strlen (result->d_name) >= (int)strlen(suffix))
491 suffixLen = DtCharCount(suffix);
492 nameLen = DtCharCount(result->d_name);
493 file_suffix = (char *)_DtGetNthChar(result->d_name,
494 nameLen - suffixLen);
495 stat(result->d_name, &buf);
497 (strcmp(file_suffix, suffix) == 0) &&
498 (buf.st_mode&S_IFREG))
500 char *c = dirs->paths[i];
518 _DtDtsMMCacheName(int override)
520 char *dsp = getenv("DISPLAY");
526 results = malloc(strlen(_DTDTSMMTEMPDIR)+
527 strlen(_DTDTSMMTEMPFILE)+
529 sprintf(results, "%s/%s%s\0",
533 c = strchr(results, ':');
542 /* tempnam(3) is affected by the TMPDIR environment variable. */
543 /* This creates problems for rename() if "tmpfile" and "cacheFile" */
544 /* are on different file systems. Use tmpnam(3) to create the */
545 /* unique file name instead. */
546 char tmpnam_buf[L_tmpnam + 1];
548 results = (char *)malloc(sizeof(_DTDTSMMTEMPDIR) +
549 sizeof(_DTDTSMMTEMPFILE) +
552 sprintf(results, "%s/%s%s", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE,
553 basename(tmpnam_buf));
560 _DtDtsMMapDB(const char *CacheFile)
569 /* Already have a file memory-mapped. Unload it. */
573 mmaped_fd = open(CacheFile, O_RDONLY, 0400);
576 if(fstat(mmaped_fd, &buf) == 0 && buf.st_uid == getuid())
578 mmaped_db = (char *)mmap(NULL,
581 #if defined(sun) || defined(USL)
582 /* MAP_NORESERVE is only supported
583 on sun and novell platforms */
584 MAP_SHARED|MAP_NORESERVE,
590 if(mmaped_db != (void *) -1)
593 mmaped_size = buf.st_size;
594 head = (DtDtsMMHeader *)mmaped_db;
595 db_list = (DtDtsMMDatabase *)_DtDtsMMGetPtr(head->db_offset);
600 DtProgName, DtError, NULL,
601 (char*) CacheFile, NULL);
609 _DtSvcProcessUnlock();
614 MMValidateDb(DtDirPaths *dirs, char *suffix)
617 struct dirent *direntp;
620 int size = sizeof(buf.st_mtime);
621 DtShmBoson *boson_list = 0;
626 int pathhash = _DtDtsMMPathHash(dirs);
629 if(head->pathhash != pathhash)
631 _DtSvcProcessUnlock();
635 count = head->files_count;
636 mtime_list = _DtDtsMMGetPtr(head->mtimes_offset);
637 boson_list = _DtDtsMMGetPtr(head->files_offset);
639 for(i = 0; i < count; i++)
641 file = _DtDtsMMBosonToString(boson_list[i]);
643 if(mtime_list[i] != buf.st_mtime)
645 _DtSvcProcessUnlock();
650 _DtSvcProcessUnlock();
656 _DtDtsMMExpandValue(const char *value)
664 newval = (char *)malloc(1024);
666 strcpy(newval, value);
667 _DtDbFillVariables(&newval);
672 _DtDtsMMSafeFree(char *value)
674 if(value && !_DtDtsMMIsMemory(value))
681 _DtDtsMMIsMemory(const char *value)
684 if((caddr_t)value < mmaped_db || (caddr_t)value > mmaped_db+mmaped_size)
686 _DtSvcProcessUnlock();
691 _DtSvcProcessUnlock();
705 _DtSvcProcessUnlock();
708 if(munmap(mmaped_db, mmaped_size) == -1)
710 _DtSimpleError(DtProgName, DtError, NULL,
711 "munmap of dts_cache file", NULL);
714 if(close(mmaped_fd) == -1)
716 _DtSimpleError(DtProgName, DtError, NULL,
717 "close of dts_cache file", NULL);
725 _DtSvcProcessUnlock();
729 #include "Dt/UserMsg.h"
732 _debug_print_name(char *name, char *label)
735 static char *db = (char *)-1;
740 db = getenv("MMAP_DEBUG");
742 _DtSvcProcessUnlock();
748 "%s - db name = %s\n", label,