2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
24 * $TOG: DtsMM.c /main/16 1998/10/23 13:48:28 mgreess $
26 * RESTRICTED CONFIDENTIAL INFORMATION:
28 * (c) Copyright 1993,1994,1995 Sun Microsystems, Inc.
29 * All rights reserved.
35 #include <sys/types.h>
40 #include <sys/utsname.h>
43 #include <sys/param.h>
47 #define X_INCLUDE_DIRENT_H
48 #define XOS_USE_XT_LOCKING
49 #include <X11/Xos_r.h>
50 #include <Dt/DbReader.h>
52 #include "Dt/DtNlUtils.h"
53 #include <Dt/UserMsg.h>
54 #include "DtSvcLock.h"
56 extern char *strdup(const char *);
57 static int MMValidateDb(DtDirPaths *dirs, char *suffix);
58 static int _debug_print_name(char *name, char *label);
60 typedef int (*genfunc)(const void *, const void *);
62 static DtDtsMMDatabase *db_list;
63 static caddr_t mmaped_db = 0;
64 static size_t mmaped_size = 0;
65 static int mmaped_fd = 0;
66 static DtDtsMMHeader *head = 0;
68 int _DtDtsMMUnLoad(void);
70 extern void _DtDbFillVariables (char **line );
71 extern void _DtDtsClear(void);
74 _DtDtsMMGetPtr(int index)
76 DtShmIntList int_list;
83 int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
84 _DtSvcProcessUnlock();
85 return((void *)&int_list[index]);
89 _DtDtsMMGetPtrSize(int index)
91 DtShmIntList int_list;
98 int_list = (DtShmIntList)&mmaped_db[sizeof(DtDtsMMHeader)];
99 _DtSvcProcessUnlock();
100 return(int_list[index-1]);
104 _DtDtsMMGetDCNameIndex(int *size)
109 *size = _DtDtsMMGetPtrSize(head->name_list_offset);
110 result = (int*) _DtDtsMMGetPtr(head->name_list_offset);
111 _DtSvcProcessUnlock();
116 _DtDtsMMGetDbName(DtDtsMMDatabase *db, DtShmBoson boson)
118 DtShmInttab tab = (DtShmInttab)_DtDtsMMGetPtr(db->nameIndex);
119 return((int *)_DtShmFindIntTabEntry(tab, boson));
123 _DtDtsMMGetNoNameIndex(int *size)
129 if(head->no_name_offset == -1)
132 _DtSvcProcessUnlock();
135 *size = _DtDtsMMGetPtrSize(head->no_name_offset);
136 result = (int *) _DtDtsMMGetPtr(head->no_name_offset);
137 _DtSvcProcessUnlock();
141 /* returns the pointer to buffer only name list */
143 _DtDtsMMGetBufferIndex(int *size)
145 int *list = (int*)_DtDtsMMGetNoNameIndex(size);
149 *size -= head->buffer_start_index;
150 bufferIndex = &list[head->buffer_start_index];
151 _DtSvcProcessUnlock();
157 _DtDtsMMGetFileList(void)
159 DtShmInttab file_index;
162 file_index = (DtShmStrtab)_DtDtsMMGetPtr(head->files_offset);
163 _DtSvcProcessUnlock();
168 _DtDtsMMBosonToString(DtShmBoson boson)
170 DtShmStrtab str_table;
181 str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
182 _DtSvcProcessUnlock();
184 return(_DtShmBosonToString(str_table, boson));
188 _DtDtsMMStringToBoson(const char *string)
190 DtShmStrtab str_table;
192 if ((string == (char *)NULL) || (*string == '\0'))
201 str_table = (DtShmStrtab)_DtDtsMMGetPtr(head->str_tbl_offset);
202 _DtSvcProcessUnlock();
204 return(_DtShmStringToBoson(str_table, string));
208 _DtDtsMMPrintFld(int fld, DtDtsMMField *fld_ptr, FILE *fd_in)
216 tmp = _DtDtsMMBosonToString(fld_ptr->fieldName);
217 tmpv = _DtDtsMMBosonToString(fld_ptr->fieldValue);
218 fprintf(fd, "\t\t[%d]\t%s(%d)\t%s(%d)\n", fld, tmp,fld_ptr->fieldName,
219 tmpv?tmpv:"(NULL)", fld_ptr->fieldValue);
223 _DtDtsMMPrintRec(int rec, DtDtsMMRecord *rec_ptr, FILE *fd_in)
226 DtDtsMMField *fld_ptr;
227 DtDtsMMField *fld_ptr_list;
233 tmp = _DtDtsMMBosonToString(rec_ptr->recordName);
234 fprintf(fd, "\tRec[%d] name = %s(%d)\n\t%d Fields\n", rec,
235 tmp, rec_ptr->recordName,
236 rec_ptr->fieldCount);
237 fld_ptr_list = _DtDtsMMGetPtr(rec_ptr->fieldList);
238 for(fld = 0; fld < rec_ptr->fieldCount; fld++)
240 fld_ptr = &fld_ptr_list[fld];
241 _DtDtsMMPrintFld(fld, fld_ptr, fd);
246 _DtDtsMMPrintDb(int db, DtDtsMMDatabase *db_ptr, FILE *fd_in)
249 DtDtsMMRecord *rec_ptr;
250 DtDtsMMRecord *rec_ptr_list;
256 fprintf(fd, "DB[%d] ", db);
257 tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
258 fprintf(fd, "name = %s(%d)\n", tmp, db_ptr->databaseName);
259 fprintf(fd, "%d Records\n", db_ptr->recordCount);
260 rec_ptr_list = _DtDtsMMGetPtr(db_ptr->recordList);
261 for(rec = 0; rec < db_ptr->recordCount; rec++)
263 rec_ptr = &rec_ptr_list[rec];
264 _DtDtsMMPrintRec(rec, rec_ptr, fd);
269 _DtDtsMMPrint(FILE *org_fd)
272 DtDtsMMDatabase *db_ptr;
282 for(db = 0; db < head->num_db; db++)
284 db_ptr = &db_list[db];
288 tmp = _DtDtsMMBosonToString(db_ptr->databaseName);
289 if((fd = fopen(tmp, "w")) == NULL)
292 DtProgName, DtError, NULL,
297 _DtDtsMMPrintDb(db, db_ptr, fd);
304 _DtSvcProcessUnlock();
308 _DtDtsMMCompareRecordNames(DtDtsMMRecord *a, DtDtsMMRecord *b)
310 return (a->recordName - b->recordName);
314 _DtDtsMMCompareFieldNames(DtDtsMMField *a, DtDtsMMField *b)
316 return (a->fieldName - b->fieldName);
322 _DtDtsMMInit(int override)
324 DtDirPaths *dirs = _DtGetDatabaseDirPaths();
325 char *CacheFile = _DtDtsMMCacheName(1);
328 if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
331 _DtFreeDatabaseDirPaths(dirs);
334 _debug_print_name(CacheFile, "Init");
338 int success = _DtDtsMMapDB(CacheFile);
341 if(!MMValidateDb(dirs, ".dt"))
347 _debug_print_name(CacheFile, "Mapped");
353 CacheFile = _DtDtsMMCacheName(0);
354 _debug_print_name(CacheFile, "Private");
355 /* Check return status, and pass status to caller. */
356 if (!_DtDtsMMCreateDb(dirs, CacheFile, override))
359 _DtFreeDatabaseDirPaths(dirs);
365 _DtFreeDatabaseDirPaths(dirs);
381 list = (char **)malloc((head->num_db+1)*sizeof(char *));
382 for ( i = 0; i < head->num_db; i++ )
384 list[i] = (char *)_DtDtsMMBosonToString(db_list[i].databaseName);
387 _DtSvcProcessUnlock();
393 _DtDtsMMGet(const char *name)
396 DtShmBoson boson = _DtDtsMMStringToBoson(name);
397 DtDtsMMDatabase *ret_db;
404 for(i = 0; i < head->num_db; i++)
406 if(db_list[i].databaseName == boson)
408 ret_db = &db_list[i];
409 _DtSvcProcessUnlock();
414 _DtSvcProcessUnlock();
420 _DtDtsMMGetField(DtDtsMMRecord *rec, const char *name)
424 DtDtsMMField *fld_ptr;
425 DtDtsMMField *fld_ptr_list;
428 * Field names have been quarked so quark 'name' and
429 * do a linear search for the quark'ed field name.
431 DtShmBoson tmp = _DtDtsMMStringToBoson (name);
433 fld_ptr_list = _DtDtsMMGetPtr(rec->fieldList);
434 for (i = 0; i < rec->fieldCount; i++)
436 fld_ptr = &fld_ptr_list[i];
437 if (fld_ptr->fieldName == tmp)
446 _DtDtsMMGetFieldByName(DtDtsMMRecord *rec, const char *name)
448 DtDtsMMField *result;
450 result = _DtDtsMMGetField(rec, name);
453 return(_DtDtsMMBosonToString(result->fieldValue));
463 _DtDtsMMGetRecordByName(DtDtsMMDatabase *db, const char *name)
466 DtDtsMMRecord *result;
467 DtDtsMMRecord *s = &srch;
469 DtShmBoson name_quark = _DtDtsMMStringToBoson(name);
470 DtDtsMMRecord *rec_ptr;
471 DtDtsMMRecord *rec_ptr_list;
474 * If the fields are not sorted in alphanumeric order
475 * by name a binary search will fail. So do the slow but
476 * sure linear search.
478 rec_ptr_list = _DtDtsMMGetPtr(db->recordList);
480 for (i = 0; i < db->recordCount; i++)
482 rec_ptr = &rec_ptr_list[i];
483 if (rec_ptr->recordName == name_quark)
491 _DtDtsMMPathHash(DtDirPaths *dirs)
495 struct dirent *dp = NULL;
500 char *suffix = ".dt";
502 char *cur_dir = getcwd(0,MAXPATHLEN);
505 _Xreaddirparams dirEntryBuf;
506 struct dirent *result;
508 for(i = 0; dirs->paths[i] ; i++)
510 if(chdir(dirs->paths[i]) == -1)
514 dirp = opendir (".");
515 while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL)
517 if ((int)strlen (result->d_name) >= (int)strlen(suffix))
519 suffixLen = DtCharCount(suffix);
520 nameLen = DtCharCount(result->d_name);
521 file_suffix = (char *)_DtGetNthChar(result->d_name,
522 nameLen - suffixLen);
523 stat(result->d_name, &buf);
525 (strcmp(file_suffix, suffix) == 0) &&
526 (buf.st_mode&S_IFREG))
528 char *c = dirs->paths[i];
546 _DtDtsMMCacheName(int override)
548 char *dsp = getenv("DISPLAY");
554 results = malloc(strlen(_DTDTSMMTEMPDIR)+
555 strlen(_DTDTSMMTEMPFILE)+
557 sprintf(results, "%s/%s%s",
561 c = strchr(results, ':');
570 /* tempnam(3) is affected by the TMPDIR environment variable. */
571 /* This creates problems for rename() if "tmpfile" and "cacheFile" */
572 /* are on different file systems. Use tmpnam(3) to create the */
573 /* unique file name instead. */
574 char tmpnam_buf[L_tmpnam + 1];
576 results = (char *)malloc(strlen(_DTDTSMMTEMPDIR) +
577 strlen(_DTDTSMMTEMPFILE) +
580 sprintf(results, "%s/%s%s", _DTDTSMMTEMPDIR, _DTDTSMMTEMPFILE,
581 basename(tmpnam_buf));
588 _DtDtsMMapDB(const char *CacheFile)
597 /* Already have a file memory-mapped. Unload it. */
601 mmaped_fd = open(CacheFile, O_RDONLY, 0400);
604 if(fstat(mmaped_fd, &buf) == 0 && buf.st_uid == getuid())
606 mmaped_db = (char *)mmap(NULL,
610 /* MAP_NORESERVE is only supported
611 on sun and novell platforms */
612 MAP_SHARED|MAP_NORESERVE,
618 if(mmaped_db != (void *) -1)
621 mmaped_size = buf.st_size;
622 head = (DtDtsMMHeader *)mmaped_db;
623 db_list = (DtDtsMMDatabase *)_DtDtsMMGetPtr(head->db_offset);
628 DtProgName, DtError, NULL,
629 (char*) CacheFile, NULL);
637 _DtSvcProcessUnlock();
642 MMValidateDb(DtDirPaths *dirs, char *suffix)
645 struct dirent *direntp;
648 int size = sizeof(buf.st_mtime);
649 DtShmBoson *boson_list = 0;
654 int pathhash = _DtDtsMMPathHash(dirs);
657 if(head->pathhash != pathhash)
659 _DtSvcProcessUnlock();
663 count = head->files_count;
664 mtime_list = _DtDtsMMGetPtr(head->mtimes_offset);
665 boson_list = _DtDtsMMGetPtr(head->files_offset);
667 for(i = 0; i < count; i++)
669 file = _DtDtsMMBosonToString(boson_list[i]);
671 if(mtime_list[i] != buf.st_mtime)
673 _DtSvcProcessUnlock();
678 _DtSvcProcessUnlock();
684 _DtDtsMMExpandValue(const char *value)
692 newval = (char *)malloc(1024);
694 strcpy(newval, value);
695 _DtDbFillVariables(&newval);
700 _DtDtsMMSafeFree(char *value)
702 if(value && !_DtDtsMMIsMemory(value))
709 _DtDtsMMIsMemory(const char *value)
712 if((caddr_t)value < mmaped_db || (caddr_t)value > mmaped_db+mmaped_size)
714 _DtSvcProcessUnlock();
719 _DtSvcProcessUnlock();
733 _DtSvcProcessUnlock();
736 if(munmap(mmaped_db, mmaped_size) == -1)
738 _DtSimpleError(DtProgName, DtError, NULL,
739 "munmap of dts_cache file", NULL);
742 if(close(mmaped_fd) == -1)
744 _DtSimpleError(DtProgName, DtError, NULL,
745 "close of dts_cache file", NULL);
753 _DtSvcProcessUnlock();
757 #include "Dt/UserMsg.h"
760 _debug_print_name(char *name, char *label)
763 static char *db = (char *)-1;
768 db = getenv("MMAP_DEBUG");
770 _DtSvcProcessUnlock();
776 "%s - db name = %s\n", label,