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 librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
24 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
25 * (c) Copyright 1993, 1994 International Business Machines Corp. *
26 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
27 * (c) Copyright 1993, 1994 Novell, Inc. *
32 * $TOG: Dts.c /main/18 1999/10/15 12:18:39 mgreess $
34 * RESTRICTED CONFIDENTIAL INFORMATION:
36 * The information in this document is subject to special
37 * restrictions in a confidential disclosure agreement bertween
38 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
39 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
40 * Sun's specific written approval. This documment and all copies
41 * and derivative works thereof must be returned or destroyed at
44 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
58 * On HP MAXINT is defined in both <values.h> and <sys/param.h>
61 #elif defined(CSRG_BASED)
62 #define MAXINT INT_MAX
66 #include <sys/param.h>
67 #include <sys/errno.h>
71 #include <sys/utsname.h>
72 #define X_INCLUDE_STRING_H
73 #define XOS_USE_XT_LOCKING
74 #include <X11/Xos_r.h>
75 #include <Dt/DtNlUtils.h>
78 #include "DtSvcLock.h"
79 #include <Dt/UserMsg.h>
81 #include <X11/Xosdefs.h>
93 typedef struct type_info
97 const struct stat *file_stat;
98 const struct stat *file_lstat;
102 int mmap_size_to_free;
104 const char *opt_name;
106 const char *link_path;
107 const char *link_name;
118 static DtShmBoson dtdts_path_pattern = 0;
119 static DtShmBoson dtdts_name_pattern = 0;
120 static DtShmBoson dtdts_mode = 0;
121 static DtShmBoson dtdts_link_name = 0;
122 static DtShmBoson dtdts_link_path = 0;
123 static DtShmBoson dtdts_content = 0;
124 static DtShmBoson dtdts_data_attributes_name = 0;
125 static DtShmBoson dtdts_da_is_action = 0;
126 static DtShmBoson dtdts_da_icon = 0;
127 static DtShmBoson dtdts_da_description = 0;
128 static DtShmBoson dtdts_da_label = 0;
131 #define _MBLEN(p) (mblen(p, MB_CUR_MAX) > 1 ? mblen(p, MB_CUR_MAX) : 1)
132 #define _MBADV(p) ((p) += _MBLEN(p))
134 /* external functions */
135 extern char *strdup(const char *);
136 extern FILE *popen(const char *, const char *);
137 extern char *DtActionIcon(const char *);
138 extern char *DtActionDescription(const char *);
139 extern char *DtActionLabel(const char *);
140 extern XtAppContext _DtAppContext;
142 /* local functions */
143 static DtDtsMMRecord * name_list(type_info_t *linfo,
145 DtDtsMMRecord *rec_ptr);
146 static const struct stat *get_stat();
148 static int csh_match(const char *, const char *);
149 static int csh_match_star(const char *, const char *);
151 /* filetype comparison function for sorting */
152 extern int cde_dc_compare(DtDtsMMRecord **entry1, DtDtsMMRecord **entry2);
153 extern int cde_da_compare(DtDtsMMRecord **entry1, DtDtsMMRecord **entry2);
154 extern int cde_dc_field_compare(DtDtsMMField **entry1, DtDtsMMField **entry2);
160 dtdts_path_pattern = 0;
161 dtdts_name_pattern = 0;
166 dtdts_data_attributes_name = 0;
167 dtdts_da_is_action = 0;
169 dtdts_da_description = 0;
171 _DtSvcProcessUnlock();
175 gmatch(const char *string, const char *pattern)
184 for (; 1; _MBADV(pattern), _MBADV(string))
186 lower_bound = (wchar_t)MAXINT;
187 mbtowc(&string_ch, string, MB_CUR_MAX);
188 mbtowc(&pattern_ch, pattern, MB_CUR_MAX);
193 for(mbtowc(&pattern_ch, _MBADV(pattern), MB_CUR_MAX);
195 mbtowc(&pattern_ch, _MBADV(pattern), MB_CUR_MAX))
208 if(lower_bound <= string_ch) {
210 mbtowc(&pattern_ch, _MBADV(pattern),
212 k |= (string_ch <= pattern_ch);
217 /* Fall through... */
220 (lower_bound = pattern_ch))
228 return csh_match_star(string, _MBADV(pattern));
230 return ((string_ch != L'\0') ? 0 : 1);
232 if (string_ch == L'\0')
238 if (pattern_ch != string_ch)
249 * csh_match_star(string, pattern) This matches the '*' portion of a pattern.
252 csh_match_star(const char *string, const char *pattern)
257 mbtowc(&pattern_ch, pattern, MB_CUR_MAX);
267 if(gmatch(string, pattern)) {
276 mbtowc(&pattern_ch, pattern, MB_CUR_MAX);
280 mbtowc(&string_ch, string, MB_CUR_MAX);
282 if(string_ch == pattern_ch && gmatch(string, pattern))
293 max_buf(size_t size, type_info_t *info)
297 info->mb_size += MB_SIZE;
298 info->mb = (char *)calloc(info->mb_size, 1);
304 if(size > info->mb_size)
306 info->mb = (char *)realloc(info->mb, info->mb_size);
307 info->mb_size = size;
313 set_vals(const char *fn,
316 const struct stat *fs,
318 const struct stat *ls,
322 type_info_t *linfo = (type_info_t *)calloc(1, sizeof(type_info_t));
324 linfo->buff_size = -1;
327 linfo->mmap_size_to_free = -1;
328 linfo->size_to_free = -1;
329 linfo->set_datatype = 0;
333 linfo->orig_attr = 0;
337 linfo->file_path = strdup(fn);
338 linfo->name = strrchr(linfo->file_path, '/');
345 char path[MAXPATHLEN];
348 getcwd(path, MAXPATHLEN);
350 strcat(path, linfo->file_path);
352 tmp = linfo->file_path;
353 linfo->file_path = strdup(path);
354 linfo->name = strstr(linfo->file_path, tmp);
363 buf = malloc(sizeof(struct stat));
364 memset(buf, '\0', sizeof(struct stat));
365 buf->st_mode = S_IFREG | S_IROTH | S_IRGRP |
366 S_IRUSR | S_IWOTH | S_IWGRP |
368 linfo->file_stat = (const struct stat *)buf;
377 * 04/30/96 - What should this if() REALLY be? Chances are
378 * pretty good that bs will either not equal 0 or not equal -1!
380 if(bs != 0 || bs != -1)
382 linfo->buff_size = bs;
386 linfo->file_stat = (struct stat *)malloc(sizeof(struct stat));
387 memcpy((void *)linfo->file_stat,
389 sizeof(struct stat));
395 linfo->link_path = (char *)strdup(ln);
396 linfo->link_name = strrchr(ln, '/');
404 linfo->link_name = (char *)ln;
409 linfo->file_lstat = (struct stat *)malloc(sizeof(struct stat));
410 memcpy((void*)linfo->file_lstat,
412 sizeof(struct stat));
416 linfo->opt_name = strdup(on);
423 cleanup(char *ot, type_info_t *info)
431 ot = strdup(info->ot);
435 ot = strdup(DtDTS_DT_UNKNOWN);
444 free((void *)info->file_stat);
448 free((void *)info->file_lstat);
452 info->file_lstat = 0;
455 if(info->mmap_size_to_free != -1)
457 if(munmap((caddr_t)info->buffer,
458 info->mmap_size_to_free) != 0)
461 DtProgName, DtError, NULL,
465 info->mmap_size_to_free = -1;
467 else if(info->size_to_free != -1)
469 free((void *)info->buffer);
471 info->size_to_free = -1;
474 if(info->file_fd != -1)
476 close(info->file_fd);
482 free((void *)info->file_path);
488 free((void *)info->name);
494 info->buff_size = -1;
496 if(info->link_path != (char *)0 && info->link_path != (char *)-1)
498 free((void *)info->link_path);
503 free((void *)info->opt_name);
511 _DtDtsMMSafeFree(info->orig_attr);
520 get_opt_name(type_info_t *info)
522 return(info->opt_name);
526 get_name(type_info_t *info)
532 get_file_path(type_info_t *info)
536 return(info->file_path);
545 get_fd(type_info_t *info)
547 if(!info->error && info->file_fd == -1)
549 if(info->file_path == 0)
553 if((info->file_fd = open(info->file_path, O_RDONLY|O_NOCTTY, 0)) == -1)
559 return(info->file_fd);
562 static const struct stat *
563 get_lstat(type_info_t *info)
567 if(!info->file_lstat)
569 if(NULL == info->file_path)
571 info->error = ENOENT;
572 info->file_lstat = 0;
575 else if(lstat(info->file_path, &buf) == -1)
578 info->file_lstat = 0;
583 info->file_lstat = (struct stat *)malloc(sizeof(struct stat));
584 memcpy((char *)info->file_lstat, &buf, sizeof(buf));
587 return(info->file_lstat);
590 static const struct stat *
591 get_stat(type_info_t *info)
596 if (!info->file_stat)
598 if(NULL == get_file_path(info))
600 info->error = ENOENT;
603 else if(stat(get_file_path(info), &buf) == -1)
609 info->ot = strdup(DtDTS_DT_BROKEN_LINK);
617 info->file_stat = (struct stat *)malloc(sizeof(struct stat));
618 memcpy((char *)info->file_stat, &buf, sizeof(buf));
622 return(info->file_stat);
626 islink(type_info_t *info)
628 if(info->file_lstat || info->link_path || info->link_name)
636 get_link_info(type_info_t *info)
638 char buff[MAXPATHLEN];
639 const char *name = 0;
642 if(info->link_path == 0)
644 if((name = get_file_path(info)) == 0)
646 info->link_path = (char *)-1;
647 info->link_name = (char *)-1;
654 while((n = readlink(name, buff, MAXPATHLEN)) > 0)
661 if(errno == EINVAL || errno == ENOENT)
663 info->link_path = name;
664 info->link_name = strrchr(info->link_path, '/');
665 if(info->link_name == 0)
667 info->link_name = info->link_path;
677 info->link_path = (char *)-1;
678 info->link_name = (char *)-1;
685 get_link_path(type_info_t *info)
688 return(info->link_path);
692 get_link_name(type_info_t *info)
695 return(info->link_name);
699 get_buff(type_info_t *info)
701 const struct stat *buf;
703 if(!info->buffer && info->buffer != (char *)-1)
705 buf = get_stat(info);
706 if(buf && buf->st_size)
708 if ((info->file_fd == -1) && (get_fd(info) == -1))
711 info->mmap_size_to_free = buf->st_size;
712 if((info->buffer = mmap(NULL,
714 PROT_READ, MAP_PRIVATE,
715 info->file_fd, NULL)) == (char *)-1)
717 info->mmap_size_to_free = -1;
718 info->size_to_free = buf->st_size+1;
719 info->buffer = malloc(info->size_to_free);
720 if(read(info->file_fd, (void *)info->buffer,
721 info->size_to_free) == -1)
726 info->buff_size = buf->st_size;
734 return(info->buffer);
738 get_buff_size(type_info_t *info)
740 return(info->buff_size);
742 static DtDtsMMDatabase *
745 DtDtsMMDatabase *dc_db = 0;
750 fprintf(stderr, "Load DataCriteria\n");
752 dc_db = _DtDtsMMGet(DtDTS_DC_NAME);
756 DtProgName, DtError, NULL,
757 "No DataBase loaded\n", NULL);
762 if(dc_db->compare != cde_dc_compare)
765 for(i = 0; i < dc_db->recordCount; i++)
767 if(dc_db->recordList[i]->compare !=cde_dc_field_compare)
769 _DtDtsMMFieldSort(dc_db->recordList[i],
770 cde_dc_field_compare);
773 _DtDtsMMRecordSort(dc_db, cde_dc_compare);
775 _DtDtsMMPrint(stdout);
782 static DtDtsMMDatabase *
785 DtDtsMMDatabase *da_db = 0;
789 fprintf(stderr, "Load DataAttributes\n");
791 da_db = _DtDtsMMGet(DtDTS_DA_NAME);
795 DtProgName, DtError, NULL,
796 "No DataBase loaded\n", NULL);
802 if(da_db->compare != _DtDtsMMCompareRecordNames)
805 for(i = 0; i < da_db->recordCount; i++)
807 if(da_db->recordList[i]->compare !=
808 _DtDtsMMCompareFieldNames)
810 _DtDtsMMFieldSort(da_db->recordList[i],
811 _DtDtsMMCompareFieldNames);
815 _DtDtsMMRecordSort(da_db, _DtDtsMMCompareRecordNames);
821 #define DTSATTRVAL(attr_name) if(_DtDtsMMStringToBoson(attr_name) == fld_ptr->fieldName)
824 type_content(char *attr, type_info_t *info)
829 const char *buff = 0;
830 const struct stat *buf;
832 _Xstrtokparams strtok_buf;
834 if(buf = get_stat(info))
836 if((buf->st_mode&S_IFMT) == S_IFDIR &&
837 (c = strstr(attr, "filename")))
842 c = _XStrtok(c, " \t\n", strtok_buf);
843 c = _XStrtok(NULL, " \t\n", strtok_buf);
844 path = get_file_path(info);
845 file = calloc(1, strlen(path)+strlen(c)+2);
846 sprintf(file, "%s/%s", path, c);
847 if(access(file, F_OK))
858 else if((buf->st_mode&S_IFMT) != S_IFREG)
863 buff = get_buff(info);
864 if((long)buff == 0 || (long)buff == -1)
870 c = _XStrtok(attr, " \t\n", strtok_buf);
871 if(!isdigit(*c) && *c != '-')
873 /* find where c is in buff */
874 printf("start as string not ready yet\n");
890 if (s > buf->st_size)
895 s = buf->st_size - s;
899 if (!info->buff_size || (s > info->buff_size))
904 s = info->buff_size - s;
907 c = _XStrtok(NULL, " \t\n", strtok_buf);
910 case 't': /* string */
914 c = _XStrtok(NULL, "\n", strtok_buf);
916 if((info->buff_size-s) >= cl && memcmp(&buff[s], c, cl) == 0)
933 while(c = _XStrtok(NULL, "\t \n", strtok_buf))
935 if(s+i*sizeof(lv)+sizeof(lv) > get_buff_size(info))
940 memcpy(&lv, &buff[s+i*sizeof(lv)], sizeof(lv));
941 num = (unsigned char)strtol(c, &p, 0);
942 if (num != lv || c == p)
955 case 'h': /* short */
960 const unsigned char *bufPtr;
963 for(i = 0;(c = _XStrtok(NULL, "\t \n", strtok_buf)); i++)
965 if(s+i*sizeof(lv)+sizeof(lv) > get_buff_size(info))
970 bufPtr = (unsigned char *)
971 &buff[s + (i * sizeof(lv))];
972 lv = (((unsigned short)*bufPtr) << 8) |
973 ((unsigned short)*(bufPtr + 1));
974 num = (unsigned short)strtol(c, &p, 0);
975 if (num != lv || c == p)
989 /* Not true long - really 4 bytes. */
993 const unsigned char *bufPtr;
996 for(i = 0;(c = _XStrtok(NULL, "\t \n", strtok_buf)); i++)
998 if(s+i*sizeof(lv)+sizeof(lv) > get_buff_size(info))
1003 bufPtr = (unsigned char *)
1004 &buff[s + (i * sizeof(lv))];
1005 lv = (((unsigned int)*bufPtr) << 24) |
1006 (((unsigned int)*(bufPtr + 1)) << 16) |
1007 (((unsigned int)*(bufPtr + 2)) << 8) |
1008 ((unsigned int)*(bufPtr + 3));
1009 num = (unsigned int)strtol(c, &p, 0);
1010 if (num != lv || c == p)
1032 _DtDtsGetDataType(const char *file)
1036 struct stat file_stat;
1042 name = calloc(1, MAXPATHLEN+1);
1043 sprintf(name, "%s/%s", file, DtDTS_DT_DIR);
1044 if((fd = open(name, O_RDONLY, 0644)) != -1)
1046 if(fstat(fd, &file_stat) == 0)
1048 buff = (u_char *)calloc((size_t)1, file_stat.st_size+1);
1049 read(fd, buff, file_stat.st_size);
1051 dt = strstr((char *)buff, DtDTS_DATA_ATTRIBUTES_NAME);
1054 start = dt-(char*)buff;
1055 while(!isspace(buff[start])) start++;
1056 while(isspace(buff[start]))start++;
1058 while(!isspace(buff[end])) end++;
1060 dt = strdup((char *)&buff[start]);
1070 type_mode(char *attr, type_info_t *info)
1073 const struct stat *buf = get_stat(info);
1074 const struct stat *lbuf;
1087 match = (buf->st_mode&S_IFMT) == S_IFREG;
1090 match = (buf->st_mode&S_IFMT) == S_IFCHR;
1093 match = (buf->st_mode&S_IFMT) == S_IFBLK;
1096 if((buf->st_mode&S_IFMT) == S_IFDIR)
1102 if(!info->set_datatype)
1104 info->set_datatype = 1;
1106 _DtDtsGetDataType(get_file_path(info));
1107 if(info->ot) return(match);
1121 else if(lbuf = get_lstat(info))
1123 match = (lbuf->st_mode&S_IFMT) == S_IFLNK;
1131 if(buf->st_mode&S_IROTH || \
1132 buf->st_mode&S_IRGRP || \
1133 buf->st_mode&S_IRUSR )
1143 if(buf->st_mode&S_IWOTH || \
1144 buf->st_mode&S_IWGRP || \
1145 buf->st_mode&S_IWUSR )
1155 if(buf->st_mode&S_IXOTH || \
1156 buf->st_mode&S_IXGRP || \
1157 buf->st_mode&S_IXUSR )
1167 match = buf->st_mode&S_ISGID;
1170 match = buf->st_mode&S_ISUID;
1174 } while(*attr && match);
1179 type_name(const char *name, char *attr)
1183 if(name && (int)name != -1)
1186 match = !fnmatch(attr, name, 0);
1188 match = gmatch(name, attr);
1195 type_path(const char *path, char *attr)
1200 if(path && (int)path != -1)
1203 match = !fnmatch(attr, path, 0);
1205 match = gmatch(path, attr);
1212 next_sep(char *str, char *sep)
1220 c = _dt_strpbrk(c, sep);
1226 if((c == str) || (_is_previous_single(str, c) && (*prev != '\\')))
1236 DtDtsDataToDataType(const char *fp,
1239 const struct stat *fs,
1241 const struct stat *ls,
1244 DtDtsMMDatabase *db;
1245 DtDtsMMRecord *rec_ptr = 0;
1246 DtDtsMMRecord *rec_ptr_list;
1247 DtDtsMMField *fld_ptr;
1248 DtDtsMMField *fld_ptr_list;
1249 type_info_t *info = 0;
1262 _DtSvcAppLockDefault();
1263 _DtSvcProcessLock();
1267 _DtSvcProcessUnlock();
1268 _DtSvcAppUnlockDefault();
1269 return(strdup("UNKNOWN"));
1272 info = set_vals(fp, buf, bs, fs, ln, ls, on);
1273 if(!dtdts_path_pattern)
1275 dtdts_path_pattern = _DtDtsMMStringToBoson(DtDTS_PATH_PATTERN);
1276 dtdts_name_pattern = _DtDtsMMStringToBoson(DtDTS_NAME_PATTERN);
1277 dtdts_mode = _DtDtsMMStringToBoson(DtDTS_MODE);
1278 dtdts_link_name = _DtDtsMMStringToBoson(DtDTS_LINK_NAME);
1279 dtdts_link_path = _DtDtsMMStringToBoson(DtDTS_LINK_PATH);
1280 dtdts_content = _DtDtsMMStringToBoson(DtDTS_CONTENT);
1281 dtdts_data_attributes_name = _DtDtsMMStringToBoson(DtDTS_DATA_ATTRIBUTES_NAME);
1283 dtdts_da_is_action = _DtDtsMMStringToBoson(DtDTS_DA_IS_ACTION);
1284 dtdts_da_icon = _DtDtsMMStringToBoson(DtDTS_DA_ICON);
1285 dtdts_da_description = _DtDtsMMStringToBoson(DtDTS_DA_DESCRIPTION);
1286 dtdts_da_label = _DtDtsMMStringToBoson(DtDTS_DA_LABEL);
1289 for(i = 0; !rec_m && (rec_ptr = name_list(info, db, rec_ptr)); i++)
1291 fld_ptr_list = _DtDtsMMGetPtr(rec_ptr->fieldList);
1293 for(j=0; fld_m && j < rec_ptr->fieldCount; j++)
1296 DtDtsMMField *fld_ptr = &fld_ptr_list[j];
1300 info->orig_attr = _DtDtsMMExpandValue(
1301 _DtDtsMMBosonToString(fld_ptr->fieldValue));
1302 attr = info->orig_attr;
1316 new_sep = next_sep(attr, "&|\0");
1319 new_sep = attr + strlen(attr);
1322 c = max_buf((size_t)n, info);
1324 strncpy(c, attr, new_sep-attr);
1325 c[new_sep-attr] = '\0';
1329 while(new_sep = (char *)_dt_strpbrk(new_sep, "&|"))
1332 strcpy(new_sep, &new_sep[1]);
1337 if(fld_ptr->fieldName == dtdts_path_pattern)
1340 get_file_path(info),
1341 max_buf((size_t)0, info));
1343 else if(fld_ptr->fieldName == dtdts_name_pattern)
1345 if(get_file_path(info))
1349 max_buf((size_t)0, info));
1355 max_buf((size_t)0, info));
1358 else if(fld_ptr->fieldName == dtdts_mode)
1360 if(get_file_path(info))
1363 max_buf((size_t)0, info), info);
1370 else if(fld_ptr->fieldName == dtdts_link_name)
1373 get_link_name(info),
1374 max_buf((size_t)0, info));
1377 else if(fld_ptr->fieldName == dtdts_link_path)
1380 get_link_path(info),
1381 max_buf((size_t)0, info));
1383 else if(fld_ptr->fieldName == dtdts_content)
1385 atr_m = type_content(
1386 max_buf((size_t)0, info), info);
1388 else if(fld_ptr->fieldName == dtdts_data_attributes_name)
1390 info->ot = strdup(max_buf((size_t)0, info));
1393 if(info->error == ELOOP)
1395 _DtSvcProcessUnlock();
1396 _DtSvcAppUnlockDefault();
1398 cleanup(DtDTS_DT_RECURSIVE_LINK, info)
1403 _DtSvcProcessUnlock();
1404 _DtSvcAppUnlockDefault();
1405 return(cleanup(0, info));
1408 atr_m=(neg)?!atr_m:atr_m;
1413 p_atr_m = atr_m && p_atr_m;
1416 p_atr_m = atr_m || p_atr_m;
1426 c_atr_m = p_atr_m?1:0;
1429 c_atr_m = p_atr_m?0:1;
1437 } while ( c_atr_m );
1440 _DtDtsMMSafeFree(info->orig_attr);
1441 info->orig_attr = 0;
1454 _DtSvcProcessUnlock();
1455 _DtSvcAppUnlockDefault();
1456 return(cleanup(0, info));
1460 DtDtsFileToDataType(const char *filepath)
1462 char *dt = DtDtsDataToDataType(filepath, 0, -1, 0, 0, 0, 0);
1467 DtDtsBufferToDataType(const void *buffer, const int size, const char *name)
1469 char *dt = DtDtsDataToDataType(0, buffer, size, 0, 0, 0, name);
1474 expand_keyword(const char *attr_in, const char *in_pathname)
1483 char *attr = (char *)attr_in;
1493 buf = (char *) calloc(1, n);
1494 netPath = strdup(in_pathname);
1496 for(c = attr, i= 0; *c && i < n; c++)
1501 buf[i]=0; /* ensure null string termination */
1504 /* check for keyword matches */
1505 if ( !strncmp(c,"%file%",6) )
1507 n += strlen(netPath) - 6;
1508 buf = (char *)realloc(buf, n);
1509 strcpy((buf+i), netPath);
1510 i += strlen(netPath);
1514 else if ( !strncmp(c,"%dir%",5) )
1516 tmp = strrchr(netPath, '/');
1518 n += strlen(netPath) - 5;
1519 buf = (char *)realloc(buf, n);
1520 strcpy((buf+i),netPath);
1521 i += strlen(netPath);
1525 else if ( !strncmp(c,"%name%",6) )
1527 tmp = strrchr(netPath, '/');
1529 n += strlen(tmp) - 6;
1530 buf = (char *)realloc(buf, n);
1531 strcpy((buf+i),tmp);
1535 else if ( !strncmp(c,"%suffix%",8) )
1537 if ((p = strrchr(netPath,'.')) != NULL)
1541 buf = (char *)realloc(buf, n);
1547 else if ( !strncmp(c,"%base%",6) )
1549 tmp = strrchr(netPath, '/');
1551 if ((p = strrchr(tmp,'.')) != NULL)
1554 buf = (char *)realloc(buf, n);
1555 strncpy((buf+i),tmp,p-tmp);
1556 buf[i+p-tmp] = '\0';
1562 { /* no match -- just copy the character */
1564 buf[i]=0; /* ensure null string termination */
1568 if(netPath)free(netPath);
1573 return(strdup(attr));
1578 append(char *old, char *add)
1584 new = realloc(old, strlen(old)+strlen(add)+1);
1588 new = malloc(strlen(add)+1);
1598 expand_shell(const char *attr)
1612 nattr = strdup(attr);
1614 while((start = DtStrchr(srch, '`')) != NULL)
1616 if((srch != start) && _is_previous_single(srch, start) &&
1617 (*(start-1) == '`'))
1622 if((end = DtStrchr(&start[1], '`')) == NULL)
1629 results = append(results, srch);
1632 if((fd = popen(&start[1], "r")) == NULL)
1635 DtProgName, DtError, NULL,
1636 (char*) &start[1], NULL);
1637 if(nattr)free(nattr);
1638 if(results)free(results);
1642 memset(buff, '\0', sizeof(buff));
1643 while(size = fread(buff, 1, sizeof(buff)-1, fd))
1645 buff[sizeof(buff)-1] = '\0';
1646 results = append(results, buff);
1647 memset(buff, '\0', sizeof(buff));
1651 results = append(results, srch);
1652 if(nattr) free(nattr);
1657 expand_value(DtShmBoson attr, char *in_pathname)
1663 if(attr && attr != -1)
1665 tmp = _DtDtsMMExpandValue(_DtDtsMMBosonToString(attr));
1666 exp = expand_keyword(tmp, in_pathname);
1667 shell_exp = expand_shell(exp);
1669 _DtDtsMMSafeFree(tmp);
1673 exp = expand_keyword(shell_exp, in_pathname);
1686 DtDtsDataTypeToAttributeValue(const char *obj_type, const char *attr, const char *filename)
1688 DtDtsMMDatabase *db;
1689 DtDtsMMRecord *entry;
1692 _DtSvcAppLockDefault();
1693 _DtSvcProcessLock();
1697 entry = _DtDtsMMGetRecordByName(db, (char *)obj_type);
1702 DtDtsMMField *fld = _DtDtsMMGetField(entry,(char *)attr);
1707 value = expand_value(fld->fieldValue,
1712 _DtSvcProcessUnlock();
1713 _DtSvcAppUnlockDefault();
1718 DtDtsDataTypeToAttributeList(const char *obj_type, const char *filename)
1720 DtDtsMMDatabase *db;
1721 DtDtsMMRecord *entry;
1722 DtDtsMMField *fld_ptr_list;
1723 DtDtsMMField *fld_ptr;
1724 DtDtsAttribute **list = NULL;
1726 int action_flag = 0;
1731 _DtSvcAppLockDefault();
1732 _DtSvcProcessLock();
1734 entry = _DtDtsMMGetRecordByName(db, (char *)obj_type);
1736 if(!db || !obj_type || !entry)
1738 _DtSvcProcessUnlock();
1739 _DtSvcAppUnlockDefault();
1743 list = (DtDtsAttribute **)calloc(entry->fieldCount+1,
1744 sizeof(DtDtsAttribute *));
1745 fld_ptr_list = _DtDtsMMGetPtr(entry->fieldList);
1746 for(i = 0; i < entry->fieldCount; i++)
1749 fld_ptr = &fld_ptr_list[i];
1751 list[i] = (DtDtsAttribute *)malloc(sizeof(DtDtsAttribute));
1753 expand_value(fld_ptr->fieldName,
1757 expand_value(fld_ptr->fieldValue, (char *)filename);
1760 _DtSvcProcessUnlock();
1761 _DtSvcAppUnlockDefault();
1766 DtDtsFreeAttributeList(DtDtsAttribute **list)
1768 DtDtsAttribute **item = list;
1773 while(list[i] && list[i]->name)
1775 if(list[i]->name)free(list[i]->name);
1776 if(list[i]->value)free(list[i]->value);
1777 if(list[i]) free(list[i]);
1785 DtDtsFileToAttributeList(const char *filepath)
1787 char *ot = DtDtsFileToDataType(filepath);
1788 DtDtsAttribute **al = DtDtsDataTypeToAttributeList(ot, filepath);
1790 DtDtsFreeDataType(ot);
1795 DtDtsBufferToAttributeList(const void *buffer, const int size, const char *name)
1797 char *ot = DtDtsBufferToDataType(buffer, size, name);
1798 DtDtsAttribute **al = DtDtsDataTypeToAttributeList(ot, NULL);
1800 DtDtsFreeDataType(ot);
1805 DtDtsFileToAttributeValue(const char *filepath, const char *attr)
1807 char *ot = DtDtsFileToDataType(filepath);
1808 char *value = DtDtsDataTypeToAttributeValue(ot, attr, filepath);
1810 DtDtsFreeDataType(ot);
1815 DtDtsBufferToAttributeValue(const void *buffer, const int size, const char *attr, const char *name)
1817 char *ot = DtDtsBufferToDataType(buffer, size, name);
1818 char *value = DtDtsDataTypeToAttributeValue(ot, attr, name);
1820 DtDtsFreeDataType(ot);
1825 DtDtsFreeAttributeValue(char *value)
1827 if(value) free(value);
1831 DtDtsFreeDataType(char *datatype)
1833 if(datatype) free(datatype);
1837 DtDtsDataTypeIsAction(const char *datatype)
1840 if(val = DtDtsDataTypeToAttributeValue(datatype, "IS_ACTION", NULL))
1842 DtDtsFreeAttributeValue(val);
1852 DtDtsDataTypeNames(void)
1854 DtDtsMMDatabase *db;
1855 DtDtsMMRecord *rec_list;
1856 DtDtsMMRecord *rec_ptr;
1860 _DtSvcAppLockDefault();
1861 _DtSvcProcessLock();
1865 _DtSvcProcessUnlock();
1866 _DtSvcAppUnlockDefault();
1870 names = (char **)malloc((db->recordCount+1)*sizeof(char *));
1872 rec_list = _DtDtsMMGetPtr(db->recordList);
1873 for(i = 0; i < db->recordCount; i++)
1875 rec_ptr = &rec_list[i];
1876 names[j] = strdup((char *)_DtDtsMMBosonToString(rec_ptr->recordName));
1880 _DtSvcProcessUnlock();
1881 _DtSvcAppUnlockDefault();
1891 DtDtsFindAttribute(const char *name, const char *value)
1893 DtDtsMMDatabase *ot;
1898 DtDtsMMRecord *rec_ptr;
1899 DtDtsMMRecord *rec_ptr_list;
1901 _DtSvcAppLockDefault();
1902 _DtSvcProcessLock(); /* To avoid deadlock with DtDtsMMDatabase mutex
1905 if(!ot || ot->recordCount == 0)
1907 _DtSvcProcessUnlock();
1908 _DtSvcAppUnlockDefault();
1912 list = (char **)calloc(ot->recordCount, sizeof(char *));
1913 rec_ptr_list = _DtDtsMMGetPtr(ot->recordList);
1914 for(i = 0; i < ot->recordCount; i++)
1916 rec_ptr = &rec_ptr_list[i];
1917 v = _DtDtsMMExpandValue(_DtDtsMMGetFieldByName(rec_ptr, (char *)name));
1918 if(v && !strcmp(value, v))
1920 list[j++] = strdup(_DtDtsMMBosonToString(rec_ptr->recordName));
1922 _DtDtsMMSafeFree(v);
1925 _DtSvcProcessUnlock();
1926 _DtSvcAppUnlockDefault();
1931 DtDtsFreeDataTypeNames(char **list)
1943 #define DIR_INFO "DIR_INFO\n{\n\t%s\t%s\n}\n"
1945 DtDtsSetDataType(const char *filename, const char *datatype_in, const int overide)
1953 struct stat file_stat;
1956 fsize = strlen(filename)+strlen(DtDTS_DT_DIR)+2;
1957 file = (char *)calloc(1,fsize);
1958 sprintf(file, "%s/%s", filename, DtDTS_DT_DIR);
1960 if((fd = open(file, O_EXCL|O_CREAT|O_RDWR, 0644)) != -1)
1964 size = strlen(DIR_INFO);
1965 size += strlen(DtDTS_DATA_ATTRIBUTES_NAME);
1966 size += strlen(datatype_in);
1968 buff = (u_char *)calloc((size_t)1, size);
1969 sprintf((char *)buff, DIR_INFO, DtDTS_DATA_ATTRIBUTES_NAME, datatype_in);
1971 write_size = write(fd, buff, size);
1972 if(write_size != size)
1975 DtProgName, DtError, NULL,
1976 (char*) buff, NULL);
1978 datatype = strdup(datatype_in);
1982 else if(overide && (fd = open(file, O_RDWR, 0644)) != -1)
1986 int dtsize = strlen(datatype_in);
1989 if(fstat(fd, &file_stat) == 0)
1991 buff = (u_char *)calloc((size_t)1, file_stat.st_size+1);
1992 read(fd, buff, file_stat.st_size);
1994 dt = strstr((char *)buff, DtDTS_DATA_ATTRIBUTES_NAME);
1998 size = strlen(DIR_INFO);
1999 size += strlen(DtDTS_DATA_ATTRIBUTES_NAME);
2002 buff = (u_char *)calloc((size_t)1, size);
2003 sprintf((char *)buff, DIR_INFO,
2004 DtDTS_DATA_ATTRIBUTES_NAME,
2006 write_size = write(fd, buff, size);
2007 if(write_size != size)
2010 DtProgName, DtError, NULL,
2011 (char*) buff, NULL);
2013 datatype = strdup(datatype_in);
2019 start = dt-(char *)buff;
2020 while(!isspace(buff[start])) start++;
2021 while(isspace(buff[start]))start++;
2023 while(!isspace(buff[end])) end++;
2024 lseek(fd, start, SEEK_SET);
2025 if(write(fd, datatype_in, dtsize) != dtsize)
2028 DtProgName, DtError, NULL,
2029 (char*) file, NULL);
2031 off = write(fd, &buff[end], strlen((char *)&buff[end])+1);
2032 if(off != strlen((char *)&buff[end])+1)
2035 DtProgName, DtError, NULL,
2036 (char*) file, NULL);
2040 total = file_stat.st_size-(end-start)+dtsize;
2041 ftruncate(fd, total);
2042 datatype = strdup(datatype_in);
2048 else if (access(file, R_OK) == 0)
2050 datatype = _DtDtsGetDataType(filename);
2061 srch(const void *a, const void *b)
2063 int results = ((struct list *)a)->boson - ((struct list *)b)->boson;
2067 results = ((struct list *)a)->rec - ((struct list *)b)->rec;
2073 get_name_list(char *name, int *count)
2075 int boson = name?_DtDtsMMStringToBoson((const char *)name):-1;
2085 results = (int *)_DtShmFindIntTabEntry(_DtDtsMMGetDCNameIndex(&size), boson);
2092 list = (int *)_DtDtsMMGetPtr(-(*results));
2093 *count = _DtDtsMMGetPtrSize(-(*results));
2103 static DtDtsMMRecord *
2104 name_list(type_info_t *linfo, DtDtsMMDatabase *db, DtDtsMMRecord *rec_ptr)
2111 DtDtsMMRecord *record_list;
2116 /* if this is the first time */
2124 /* if not name use opt name */
2125 name = (char *)linfo->opt_name;
2128 /* initialize name count */
2129 linfo->name_count = 0;
2132 /* a name could not be found so this must be a buffer */
2133 linfo->name_prev = (int *)
2134 _DtDtsMMGetBufferIndex(&linfo->name_count);
2135 linfo->name_type = 3;
2141 /* now find suffix if any */
2142 suffix = strrchr(name, '.');
2146 if(!linfo->name_count && name)
2148 /* find if name exist in our list */
2149 linfo->name_prev = get_name_list(name,
2150 &linfo->name_count);
2151 linfo->name_type = 1;
2153 if(!linfo->name_count && suffix)
2155 /* find if suffix exist in our list */
2156 linfo->name_prev = get_name_list(suffix,
2157 &linfo->name_count);
2158 linfo->name_type = 2;
2160 if(!linfo->name_count)
2162 /* neither exist so check ambugious ones */
2163 linfo->name_prev = (int *)_DtDtsMMGetNoNameIndex(&linfo->name_count);
2164 linfo->name_type = 3;
2169 /* we found one befor so . . . */
2170 if(linfo->name_count > 0)
2172 /* if there are more on the list get the next one */
2177 /* go to the next list */
2178 switch(linfo->name_type)
2181 /* if we were in a name portion then we need to
2182 check for a suffix */
2183 suffix = strrchr(linfo->name, '.');
2186 /* if found us it */
2187 linfo->name_prev = get_name_list(suffix,
2188 &linfo->name_count);
2189 linfo->name_type = 2;
2194 /* use the ambigous list */
2196 _DtDtsMMGetNoNameIndex(&linfo->name_count);
2197 linfo->name_type = 3;
2200 /* start now with the buffer list */
2201 linfo->name_prev = (int *)
2202 _DtDtsMMGetBufferIndex(&linfo->name_count);
2203 linfo->name_type = 3;
2210 record_list = _DtDtsMMGetPtr(db->recordList);
2211 if(linfo->name_count == 0)
2217 linfo->name_count--;
2218 return(&record_list[*linfo->name_prev]);
2222 #ifdef NEED_STRCASECMP
2224 * In case strcasecmp is not provided by the system here is one
2225 * which does the trick.
2228 strcasecmp(register const char *s1,
2229 register const char *s2)
2231 register int c1, c2;
2233 while (*s1 && *s2) {
2234 c1 = isupper(*s1) ? tolower(*s1) : *s1;
2235 c2 = isupper(*s2) ? tolower(*s2) : *s2;
2241 return (int) (*s1 - *s2);
2246 DtDtsIsTrue(const char *str)
2248 if (str && ((strcasecmp(str, "true") == 0)
2249 || (strcasecmp(str, "yes") == 0)
2250 || (strcasecmp(str, "on") == 0)
2251 || (strcasecmp(str, "1") == 0)))