オープンソース・ソフトウェアの開発とダウンロード

Subversion リポジトリの参照

Annotation of /trunk/1.5.x/ccs-tools/ccstools/ccstools.src/ccstools.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 213 - (hide annotations) (download) (as text)
Tue May 15 11:05:45 2007 UTC (17 years ago) by kumaneko
Original Path: trunk/ccs-tools/ccstools/ccstools.src/ccstools.c
File MIME type: text/x-csrc
File size: 14549 byte(s)
Split ccstools
1 kumaneko 213 /*
2     * ccstools.c
3     *
4     * TOMOYO Linux's utilities.
5     *
6     * Copyright (C) 2005-2007 NTT DATA CORPORATION
7     *
8     * Version: 1.4+ 2007/05/15
9     *
10     */
11    
12     #include "ccstools.h"
13    
14     /***** UTILITY FUNCTIONS START *****/
15    
16     void OutOfMemory(void) {
17     fprintf(stderr, "Out of memory. Aborted.\n");
18     exit(1);
19     }
20    
21     void NormalizeLine(unsigned char *line) {
22     unsigned char *sp = line, *dp = line;
23     int first = 1;
24     while (*sp && (*sp <= 32 || 127 <= *sp)) sp++;
25     while (*sp) {
26     if (!first) *dp++ = ' ';
27     first = 0;
28     while (32 < *sp && *sp < 127) *dp++ = *sp++;
29     while (*sp && (*sp <= 32 || 127 <= *sp)) sp++;
30     }
31     *dp = '\0';
32     }
33    
34     /* Copied from kernel source. */
35     static inline unsigned long partial_name_hash(unsigned long c, unsigned long prevhash) {
36     return (prevhash + (c << 4) + (c >> 4)) * 11;
37     }
38    
39     /* Copied from kernel source. */
40     static inline unsigned int full_name_hash(const unsigned char *name, unsigned int len) {
41     unsigned long hash = 0;
42     while (len--) hash = partial_name_hash(*name++, hash);
43     return (unsigned int) hash;
44     }
45    
46     static char *alloc_element(const unsigned int size) {
47     static char *buf = NULL;
48     static unsigned int buf_used_len = PAGE_SIZE;
49     char *ptr = NULL;
50     if (size > PAGE_SIZE) return NULL;
51     if (buf_used_len + size > PAGE_SIZE) {
52     if ((ptr = malloc(PAGE_SIZE)) == NULL) OutOfMemory();
53     buf = ptr;
54     memset(buf, 0, PAGE_SIZE);
55     buf_used_len = size;
56     ptr = buf;
57     } else if (size) {
58     int i;
59     ptr = buf + buf_used_len;
60     buf_used_len += size;
61     for (i = 0; i < size; i++) if (ptr[i]) OutOfMemory();
62     }
63     return ptr;
64     }
65    
66     static int PathDepth(const char *pathname) {
67     int i = 0;
68     if (pathname) {
69     char *ep = strchr(pathname, '\0');
70     if (pathname < ep--) {
71     if (*ep != '/') i++;
72     while (pathname <= ep) if (*ep-- == '/') i += 2;
73     }
74     }
75     return i;
76     }
77    
78     static int const_part_length(const char *filename) {
79     int len = 0;
80     if (filename) {
81     char c;
82     while ((c = *filename++) != '\0') {
83     if (c != '\\') { len++; continue; }
84     switch (c = *filename++) {
85     case '\\': /* "\\" */
86     len += 2; continue;
87     case '0': /* "\ooo" */
88     case '1':
89     case '2':
90     case '3':
91     if ((c = *filename++) >= '0' && c <= '7' && (c = *filename++) >= '0' && c <= '7') { len += 4; continue; }
92     }
93     break;
94     }
95     }
96     return len;
97     }
98    
99     int IsDomainDef(const unsigned char *domainname) {
100     return strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN) == 0 && (domainname[ROOT_NAME_LEN] == '\0' || domainname[ROOT_NAME_LEN] == ' ');
101     }
102    
103     int IsCorrectDomain(const unsigned char *domainname) {
104     unsigned char c, d, e;
105     if (!domainname || strncmp(domainname, ROOT_NAME, ROOT_NAME_LEN)) goto out;
106     domainname += ROOT_NAME_LEN;
107     if (!*domainname) return 1;
108     do {
109     if (*domainname++ != ' ') goto out;
110     if (*domainname++ != '/') goto out;
111     while ((c = *domainname) != '\0' && c != ' ') {
112     domainname++;
113     if (c == '\\') {
114     switch ((c = *domainname++)) {
115     case '\\': /* "\\" */
116     continue;
117     case '0': /* "\ooo" */
118     case '1':
119     case '2':
120     case '3':
121     if ((d = *domainname++) >= '0' && d <= '7' && (e = *domainname++) >= '0' && e <= '7') {
122     const unsigned char f =
123     (((unsigned char) (c - '0')) << 6) +
124     (((unsigned char) (d - '0')) << 3) +
125     (((unsigned char) (e - '0')));
126     if (f && (f <= ' ' || f >= 127)) continue; /* pattern is not \000 */
127     }
128     }
129     goto out;
130     } else if (c < ' ' || c >= 127) {
131     goto out;
132     }
133     }
134     } while (*domainname);
135     return 1;
136     out:
137     return 0;
138     }
139    
140     void fprintf_encoded(FILE *fp, const char *pathname) {
141     unsigned char c;
142     while ((c = * (const unsigned char *) pathname++) != 0) {
143     if (c == '\\') {
144     fputc('\\', fp);
145     fputc('\\', fp);
146     } else if (c > 32 && c < 127) {
147     fputc(c, fp);
148     } else {
149     fprintf(fp, "\\%c%c%c", (c >> 6) + '0', ((c >> 3) & 7) + '0', (c & 7) + '0');
150     }
151     }
152     }
153    
154     void RemoveHeader(char *line, const int len) {
155     memmove(line, line + len, strlen(line + len) + 1);
156     }
157    
158     int IsCorrectPath(const char *filename, const int start_type, const int pattern_type, const int end_type) {
159     int contains_pattern = 0;
160     char c, d, e;
161     if (!filename) goto out;
162     c = *filename;
163     if (start_type == 1) { /* Must start with '/' */
164     if (c != '/') goto out;
165     } else if (start_type == -1) { /* Must not start with '/' */
166     if (c == '/') goto out;
167     }
168     if (c) c = * (strchr(filename, '\0') - 1);
169     if (end_type == 1) { /* Must end with '/' */
170     if (c != '/') goto out;
171     } else if (end_type == -1) { /* Must not end with '/' */
172     if (c == '/') goto out;
173     }
174     while ((c = *filename++) != '\0') {
175     if (c == '\\') {
176     switch ((c = *filename++)) {
177     case '\\': /* "\\" */
178     continue;
179     case '$': /* "\$" */
180     case '+': /* "\+" */
181     case '?': /* "\?" */
182     case '*': /* "\*" */
183     case '@': /* "\@" */
184     case 'x': /* "\x" */
185     case 'X': /* "\X" */
186     case 'a': /* "\a" */
187     case 'A': /* "\A" */
188     case '-': /* "\-" */
189     if (pattern_type == -1) break; /* Must not contain pattern */
190     contains_pattern = 1;
191     continue;
192     case '0': /* "\ooo" */
193     case '1':
194     case '2':
195     case '3':
196     if ((d = *filename++) >= '0' && d <= '7' && (e = *filename++) >= '0' && e <= '7') {
197     const unsigned char f =
198     (((unsigned char) (c - '0')) << 6) +
199     (((unsigned char) (d - '0')) << 3) +
200     (((unsigned char) (e - '0')));
201     if (f && (f <= ' ' || f >= 127)) continue; /* pattern is not \000 */
202     }
203     }
204     goto out;
205     } else if (c <= ' ' || c >= 127) {
206     goto out;
207     }
208     }
209     if (pattern_type == 1) { /* Must contain pattern */
210     if (!contains_pattern) goto out;
211     }
212     return 1;
213     out:
214     return 0;
215     }
216    
217     static int FileMatchesToPattern2(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end) {
218     while (filename < filename_end && pattern < pattern_end) {
219     if (*pattern != '\\') {
220     if (*filename++ != *pattern++) return 0;
221     } else {
222     char c = *filename;
223     pattern++;
224     switch (*pattern) {
225     case '?':
226     if (c == '/') {
227     return 0;
228     } else if (c == '\\') {
229     if ((c = filename[1]) == '\\') {
230     filename++; /* safe because filename is \\ */
231     } else if (c >= '0' && c <= '3' && (c = filename[2]) >= '0' && c <= '7' && (c = filename[3]) >= '0' && c <= '7') {
232     filename += 3; /* safe because filename is \ooo */
233     } else {
234     return 0;
235     }
236     }
237     break;
238     case '\\':
239     if (c != '\\') return 0;
240     if (*++filename != '\\') return 0; /* safe because *filename != '\0' */
241     break;
242     case '+':
243     if (c < '0' || c > '9') return 0;
244     break;
245     case 'x':
246     if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) return 0;
247     break;
248     case 'a':
249     if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) return 0;
250     break;
251     case '0':
252     case '1':
253     case '2':
254     case '3':
255     if (c == '\\' && (c = filename[1]) >= '0' && c <= '3' && c == *pattern
256     && (c = filename[2]) >= '0' && c <= '7' && c == pattern[1]
257     && (c = filename[3]) >= '0' && c <= '7' && c == pattern[2]) {
258     filename += 3; /* safe because filename is \ooo */
259     pattern += 2; /* safe because pattern is \ooo */
260     break;
261     }
262     return 0; /* Not matched. */
263     case '*':
264     case '@':
265     {
266     int i;
267     for (i = 0; i <= filename_end - filename; i++) {
268     if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
269     if ((c = filename[i]) == '.' && *pattern == '@') break;
270     if (c == '\\') {
271     if ((c = filename[i + 1]) == '\\') {
272     i++; /* safe because filename is \\ */
273     } else if (c >= '0' && c <= '3' && (c = filename[i + 2]) >= '0' && c <= '7' && (c = filename[i + 3]) >= '0' && c <= '7') {
274     i += 3; /* safe because filename is \ooo */
275     } else {
276     break; /* Bad pattern. */
277     }
278     }
279     }
280     return 0; /* Not matched. */
281     }
282     default:
283     {
284     int i, j = 0;
285     if ((c = *pattern) == '$') {
286     while ((c = filename[j]) >= '0' && c <= '9') j++;
287     } else if (c == 'X') {
288     while (((c = filename[j]) >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) j++;
289     } else if (c == 'A') {
290     while (((c = filename[j]) >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) j++;
291     }
292     for (i = 1; i <= j; i++) {
293     if (FileMatchesToPattern2(filename + i, filename_end, pattern + 1, pattern_end)) return 1;
294     }
295     }
296     return 0; /* Not matched or bad pattern. */
297     }
298     filename++; /* safe because *filename != '\0' */
299     pattern++; /* safe because *pattern != '\0' */
300     }
301     }
302     while (*pattern == '\\' && (*(pattern + 1) == '*' || *(pattern + 1) == '@')) pattern += 2;
303     return (filename == filename_end && pattern == pattern_end);
304     }
305    
306     int FileMatchesToPattern(const char *filename, const char *filename_end, const char *pattern, const char *pattern_end) {
307     const char *pattern_start = pattern;
308     int first = 1;
309     int result;
310     while (pattern < pattern_end - 1) {
311     if (*pattern++ != '\\' || *pattern++ != '-') continue;
312     result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern - 2);
313     if (first) result = !result;
314     if (result) return 0;
315     first = 0;
316     pattern_start = pattern;
317     }
318     result = FileMatchesToPattern2(filename, filename_end, pattern_start, pattern_end);
319     return first ? result : !result;
320     }
321    
322     int string_compare(const void *a, const void *b) {
323     return strcmp(* (char **) a, * (char **) b);
324     }
325    
326     int pathcmp(const struct path_info *a, const struct path_info *b) {
327     return a->hash != b->hash || strcmp(a->name, b->name);
328     }
329    
330     void fill_path_info(struct path_info *ptr) {
331     const char *name = ptr->name;
332     const int len = strlen(name);
333     ptr->total_len = len;
334     ptr->const_len = const_part_length(name);
335     ptr->is_dir = len && (name[len - 1] == '/');
336     ptr->is_patterned = (ptr->const_len < len);
337     ptr->hash = full_name_hash(name, len);
338     ptr->depth = PathDepth(name);
339     }
340    
341     const struct path_info *SaveName(const char *name) {
342     static FREE_MEMORY_BLOCK_LIST fmb_list = { NULL, NULL, 0 };
343     static SAVENAME_ENTRY name_list[SAVENAME_MAX_HASH]; /* The list of names. */
344     SAVENAME_ENTRY *ptr, *prev = NULL;
345     unsigned int hash;
346     FREE_MEMORY_BLOCK_LIST *fmb = &fmb_list;
347     int len;
348     static int first_call = 1;
349     if (!name) return NULL;
350     len = strlen(name) + 1;
351     if (len > CCS_MAX_PATHNAME_LEN) {
352     fprintf(stderr, "ERROR: Name too long for SaveName().\n");
353     return NULL;
354     }
355     hash = full_name_hash((const unsigned char *) name, len - 1);
356     if (first_call) {
357     int i;
358     first_call = 0;
359     memset(&name_list, 0, sizeof(name_list));
360     for (i = 0; i < SAVENAME_MAX_HASH; i++) {
361     name_list[i].entry.name = "/";
362     fill_path_info(&name_list[i].entry);
363     }
364     if (CCS_MAX_PATHNAME_LEN > PAGE_SIZE) abort();
365     }
366     ptr = &name_list[hash % SAVENAME_MAX_HASH];
367     while (ptr) {
368     if (hash == ptr->entry.hash && strcmp(name, ptr->entry.name) == 0) goto out;
369     prev = ptr; ptr = ptr->next;
370     }
371     while (len > fmb->len) {
372     if (fmb->next) {
373     fmb = fmb->next;
374     } else {
375     char *cp;
376     if ((cp = (char *) malloc(PAGE_SIZE)) == NULL || (fmb->next = (FREE_MEMORY_BLOCK_LIST *) alloc_element(sizeof(FREE_MEMORY_BLOCK_LIST))) == NULL) OutOfMemory();
377     memset(cp, 0, PAGE_SIZE);
378     fmb = fmb->next;
379     fmb->ptr = cp;
380     fmb->len = PAGE_SIZE;
381     }
382     }
383     if ((ptr = (SAVENAME_ENTRY *) alloc_element(sizeof(SAVENAME_ENTRY))) == NULL) OutOfMemory();
384     memset(ptr, 0, sizeof(SAVENAME_ENTRY));
385     ptr->entry.name = fmb->ptr;
386     memmove(fmb->ptr, name, len);
387     fill_path_info(&ptr->entry);
388     fmb->ptr += len;
389     fmb->len -= len;
390     prev->next = ptr; /* prev != NULL because name_list is not empty. */
391     if (fmb->len == 0) {
392     FREE_MEMORY_BLOCK_LIST *ptr = &fmb_list;
393     while (ptr->next != fmb) ptr = ptr->next; ptr->next = fmb->next;
394     }
395     out:
396     return ptr ? &ptr->entry : NULL;
397     }
398    
399     char *shared_buffer = NULL;
400     static int buffer_lock = 0;
401     void get(void) {
402     if (buffer_lock) OutOfMemory();
403     if (!shared_buffer && (shared_buffer = malloc(shared_buffer_len)) == NULL) OutOfMemory();
404     buffer_lock++;
405     }
406     void put(void) {
407     if (buffer_lock != 1) OutOfMemory();
408     buffer_lock--;
409     }
410     int freadline(FILE *fp) {
411     char *cp;
412     memset(shared_buffer, 0, shared_buffer_len);
413     if (fgets(shared_buffer, shared_buffer_len - 1, fp) == NULL ||
414     (cp = strchr(shared_buffer, '\n')) == NULL) return 0;
415     *cp = '\0';
416     NormalizeLine(shared_buffer);
417     return 1;
418     }
419    
420     /***** UTILITY FUNCTIONS END *****/
421    
422     extern int sortpolicy_main(int argc, char *argv[]);
423     extern int setprofile_main(int argc, char *argv[]);
424     extern int setlevel_main(int argc, char *argv[]);
425     extern int savepolicy_main(int argc, char *argv[]);
426     extern int pathmatch_main(int argc, char *argv[]);
427     extern int loadpolicy_main(int argc, char *argv[]);
428     extern int ldwatch_main(int argc, char *argv[]);
429     extern int findtemp_main(int argc, char *argv[]);
430     extern int editpolicy_main(int argc, char *argv[]);
431     extern int checkpolicy_main(int argc, char *argv[]);
432     extern int ccstree_main(int argc, char *argv[]);
433     extern int ccsqueryd_main(int argc, char *argv[]);
434     extern int ccsauditd_main(int argc, char *argv[]);
435     extern int patternize_main(int argc, char *argv[]);
436    
437     int main(int argc, char *argv[]) {
438     const char *argv0 = argv[0];
439     if (!argv0) {
440     fprintf(stderr, "Function not specified.\n");
441     return 1;
442     }
443     if (strrchr(argv0, '/')) argv0 = strrchr(argv0, '/') + 1;
444     if (strcmp(argv0, "sortpolicy") == 0) return sortpolicy_main(argc, argv);
445     if (strcmp(argv0, "setprofile") == 0) return setprofile_main(argc, argv);
446     if (strcmp(argv0, "setlevel") == 0) return setlevel_main(argc, argv);
447     if (strcmp(argv0, "savepolicy") == 0) return savepolicy_main(argc, argv);
448     if (strcmp(argv0, "pathmatch") == 0) return pathmatch_main(argc, argv);
449     if (strcmp(argv0, "loadpolicy") == 0) return loadpolicy_main(argc, argv);
450     if (strcmp(argv0, "ld-watch") == 0) return ldwatch_main(argc, argv);
451     if (strcmp(argv0, "findtemp") == 0) return findtemp_main(argc, argv);
452     if (strcmp(argv0, "editpolicy") == 0 || strcmp(argv0, "editpolicy_offline") == 0) return editpolicy_main(argc, argv);
453     if (strcmp(argv0, "checkpolicy") == 0) return checkpolicy_main(argc, argv);
454     if (strcmp(argv0, "ccstree") == 0) return ccstree_main(argc, argv);
455     if (strcmp(argv0, "ccs-queryd") == 0) return ccsqueryd_main(argc, argv);
456     if (strcmp(argv0, "ccs-auditd") == 0) return ccsauditd_main(argc, argv);
457     if (strcmp(argv0, "patternize") == 0) return patternize_main(argc, argv);
458     /*
459     * Unlike busybox, I don't use argv[1] if argv[0] is the name of this program
460     * because it is dangerous to allow updating policies via unchecked argv[1].
461     * You should use either "symbolic links with 'alias' directive" or "hard links".
462     */
463     printf("ccstools version 1.4+ build 2007/05/15\n");
464     fprintf(stderr, "Function %s not implemented.\n", argv0);
465     return 1;
466     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26