]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
bc44d920 | 2 | * "$Id: mime.c 6649 2007-07-11 21:46:42Z mike $" |
ef416fc2 | 3 | * |
4 | * MIME database file routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
91c84a35 | 6 | * Copyright 2007-2008 by Apple Inc. |
fa73b229 | 7 | * Copyright 1997-2006 by Easy Software Products, all rights reserved. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 14 | * |
15 | * Contents: | |
16 | * | |
fa73b229 | 17 | * mimeDelete() - Delete (free) a MIME database. |
18 | * mimeDeleteFilter() - Delete a filter from the MIME database. | |
19 | * mimeDeleteType() - Delete a type from the MIME database. | |
20 | * mimeFirstFilter() - Get the first filter in the MIME database. | |
21 | * mimeFirstType() - Get the first type in the MIME database. | |
fa73b229 | 22 | * mimeLoad() - Create a new MIME database from disk. |
23 | * mimeMerge() - Merge a MIME database from disk with the current one. | |
24 | * mimeNew() - Create a new, empty MIME database. | |
25 | * mimeNextFilter() - Get the next filter in the MIME database. | |
26 | * mimeNextType() - Get the next type in the MIME database. | |
27 | * mimeNumFilters() - Get the number of filters in a MIME database. | |
28 | * mimeNumTypes() - Get the number of types in a MIME database. | |
4400e98d | 29 | * add_fcache() - Add a filter to the filter cache. |
30 | * compare_fcache() - Compare two filter cache entries. | |
31 | * delete_fcache() - Free all memory used by the filter cache. | |
fa73b229 | 32 | * delete_rules() - Free all memory for the given rule tree. |
33 | * load_convs() - Load a xyz.convs file... | |
4400e98d | 34 | * load_types() - Load a xyz.types file... |
ef416fc2 | 35 | */ |
36 | ||
37 | /* | |
38 | * Include necessary headers... | |
39 | */ | |
40 | ||
41 | #include <stdio.h> | |
42 | #include <stdlib.h> | |
43 | #include <ctype.h> | |
44 | ||
ed486911 | 45 | #include <cups/debug.h> |
fa73b229 | 46 | #include <cups/dir.h> |
ef416fc2 | 47 | #include <cups/string.h> |
48 | #include "mime.h" | |
49 | ||
ef416fc2 | 50 | |
4400e98d | 51 | /* |
52 | * Local types... | |
53 | */ | |
54 | ||
55 | typedef struct _mime_fcache_s /**** Filter cache structure ****/ | |
56 | { | |
57 | char *name, /* Filter name */ | |
58 | *path; /* Full path to filter if available */ | |
59 | } _mime_fcache_t; | |
60 | ||
61 | ||
ef416fc2 | 62 | /* |
63 | * Local functions... | |
64 | */ | |
65 | ||
4400e98d | 66 | static const char *add_fcache(cups_array_t *filtercache, const char *name, |
67 | const char *filterpath); | |
68 | static int compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b); | |
69 | static void delete_fcache(cups_array_t *filtercache); | |
ef416fc2 | 70 | static void delete_rules(mime_magic_t *rules); |
4400e98d | 71 | static void load_convs(mime_t *mime, const char *filename, |
72 | const char *filterpath, | |
73 | cups_array_t *filtercache); | |
74 | static void load_types(mime_t *mime, const char *filename); | |
ef416fc2 | 75 | |
76 | ||
77 | /* | |
78 | * 'mimeDelete()' - Delete (free) a MIME database. | |
79 | */ | |
80 | ||
81 | void | |
fa73b229 | 82 | mimeDelete(mime_t *mime) /* I - MIME database */ |
ef416fc2 | 83 | { |
fa73b229 | 84 | mime_type_t *type; /* Current type */ |
85 | mime_filter_t *filter; /* Current filter */ | |
ef416fc2 | 86 | |
87 | ||
fa73b229 | 88 | if (!mime) |
ef416fc2 | 89 | return; |
90 | ||
fa73b229 | 91 | /* |
92 | * Loop through filters and free them... | |
93 | */ | |
94 | ||
95 | for (filter = (mime_filter_t *)cupsArrayFirst(mime->filters); | |
96 | filter; | |
97 | filter = (mime_filter_t *)cupsArrayNext(mime->filters)) | |
98 | mimeDeleteFilter(mime, filter); | |
ef416fc2 | 99 | |
89d46774 | 100 | /* |
101 | * Loop through the file types and delete any rules... | |
102 | */ | |
103 | ||
104 | for (type = (mime_type_t *)cupsArrayFirst(mime->types); | |
105 | type; | |
106 | type = (mime_type_t *)cupsArrayNext(mime->types)) | |
107 | mimeDeleteType(mime, type); | |
108 | ||
ef416fc2 | 109 | /* |
110 | * Free the types and filters arrays, and then the MIME database structure. | |
111 | */ | |
112 | ||
fa73b229 | 113 | cupsArrayDelete(mime->types); |
114 | cupsArrayDelete(mime->filters); | |
a74454a7 | 115 | cupsArrayDelete(mime->srcs); |
ef416fc2 | 116 | free(mime); |
117 | } | |
118 | ||
119 | ||
120 | /* | |
fa73b229 | 121 | * 'mimeDeleteFilter()' - Delete a filter from the MIME database. |
ef416fc2 | 122 | */ |
123 | ||
fa73b229 | 124 | void |
125 | mimeDeleteFilter(mime_t *mime, /* I - MIME database */ | |
126 | mime_filter_t *filter) /* I - Filter */ | |
ef416fc2 | 127 | { |
fa73b229 | 128 | if (!mime || !filter) |
129 | return; | |
ef416fc2 | 130 | |
fa73b229 | 131 | cupsArrayRemove(mime->filters, filter); |
132 | free(filter); | |
a74454a7 | 133 | |
134 | /* | |
135 | * Deleting a filter invalidates the source lookup cache used by | |
136 | * mimeFilter()... | |
137 | */ | |
138 | ||
139 | if (mime->srcs) | |
140 | { | |
141 | cupsArrayDelete(mime->srcs); | |
142 | mime->srcs = NULL; | |
143 | } | |
fa73b229 | 144 | } |
ef416fc2 | 145 | |
ef416fc2 | 146 | |
fa73b229 | 147 | /* |
148 | * 'mimeDeleteType()' - Delete a type from the MIME database. | |
149 | */ | |
ef416fc2 | 150 | |
fa73b229 | 151 | void |
152 | mimeDeleteType(mime_t *mime, /* I - MIME database */ | |
153 | mime_type_t *mt) /* I - Type */ | |
154 | { | |
155 | if (!mime || !mt) | |
156 | return; | |
ef416fc2 | 157 | |
fa73b229 | 158 | cupsArrayRemove(mime->types, mt); |
ef416fc2 | 159 | |
fa73b229 | 160 | delete_rules(mt->rules); |
161 | free(mt); | |
162 | } | |
ef416fc2 | 163 | |
ef416fc2 | 164 | |
fa73b229 | 165 | /* |
166 | * 'mimeFirstFilter()' - Get the first filter in the MIME database. | |
167 | */ | |
ef416fc2 | 168 | |
fa73b229 | 169 | mime_filter_t * /* O - Filter or NULL */ |
170 | mimeFirstFilter(mime_t *mime) /* I - MIME database */ | |
171 | { | |
172 | if (!mime) | |
173 | return (NULL); | |
174 | else | |
175 | return ((mime_filter_t *)cupsArrayFirst(mime->filters)); | |
176 | } | |
ef416fc2 | 177 | |
ef416fc2 | 178 | |
fa73b229 | 179 | /* |
180 | * 'mimeFirstType()' - Get the first type in the MIME database. | |
181 | */ | |
ef416fc2 | 182 | |
fa73b229 | 183 | mime_type_t * /* O - Type or NULL */ |
184 | mimeFirstType(mime_t *mime) /* I - MIME database */ | |
185 | { | |
186 | if (!mime) | |
187 | return (NULL); | |
188 | else | |
189 | return ((mime_type_t *)cupsArrayFirst(mime->types)); | |
190 | } | |
ef416fc2 | 191 | |
ef416fc2 | 192 | |
fa73b229 | 193 | /* |
194 | * 'mimeLoad()' - Create a new MIME database from disk. | |
195 | */ | |
ef416fc2 | 196 | |
fa73b229 | 197 | mime_t * /* O - New MIME database */ |
198 | mimeLoad(const char *pathname, /* I - Directory to load */ | |
199 | const char *filterpath) /* I - Directory to load */ | |
200 | { | |
201 | return (mimeMerge(NULL, pathname, filterpath)); | |
202 | } | |
ef416fc2 | 203 | |
ef416fc2 | 204 | |
fa73b229 | 205 | /* |
206 | * 'mimeMerge()' - Merge a MIME database from disk with the current one. | |
207 | */ | |
ef416fc2 | 208 | |
fa73b229 | 209 | mime_t * /* O - Updated MIME database */ |
210 | mimeMerge(mime_t *mime, /* I - MIME database to add to */ | |
211 | const char *pathname, /* I - Directory to load */ | |
212 | const char *filterpath) /* I - Directory to load */ | |
213 | { | |
214 | cups_dir_t *dir; /* Directory */ | |
215 | cups_dentry_t *dent; /* Directory entry */ | |
216 | char filename[1024]; /* Full filename of types/converts file */ | |
4400e98d | 217 | cups_array_t *filtercache; /* Filter cache */ |
ef416fc2 | 218 | |
219 | ||
220 | /* | |
221 | * First open the directory specified by pathname... Return NULL if nothing | |
222 | * was read or if the pathname is NULL... | |
223 | */ | |
224 | ||
fa73b229 | 225 | if (!pathname) |
ef416fc2 | 226 | return (NULL); |
227 | ||
fa73b229 | 228 | if ((dir = cupsDirOpen(pathname)) == NULL) |
ef416fc2 | 229 | return (NULL); |
230 | ||
231 | /* | |
232 | * If "mime" is NULL, make a new, blank database... | |
233 | */ | |
234 | ||
fa73b229 | 235 | if (!mime) |
236 | mime = mimeNew(); | |
237 | if (!mime) | |
91c84a35 MS |
238 | { |
239 | cupsDirClose(dir); | |
fa73b229 | 240 | return (NULL); |
91c84a35 | 241 | } |
ef416fc2 | 242 | |
243 | /* | |
244 | * Read all the .types files... | |
245 | */ | |
246 | ||
fa73b229 | 247 | while ((dent = cupsDirRead(dir)) != NULL) |
ef416fc2 | 248 | { |
fa73b229 | 249 | if (strlen(dent->filename) > 6 && |
250 | !strcmp(dent->filename + strlen(dent->filename) - 6, ".types")) | |
ef416fc2 | 251 | { |
252 | /* | |
253 | * Load a mime.types file... | |
254 | */ | |
255 | ||
fa73b229 | 256 | snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); |
ef416fc2 | 257 | load_types(mime, filename); |
258 | } | |
259 | } | |
260 | ||
fa73b229 | 261 | cupsDirRewind(dir); |
ef416fc2 | 262 | |
263 | /* | |
264 | * Read all the .convs files... | |
265 | */ | |
266 | ||
4400e98d | 267 | filtercache = cupsArrayNew((cups_array_func_t)compare_fcache, NULL); |
268 | ||
fa73b229 | 269 | while ((dent = cupsDirRead(dir)) != NULL) |
ef416fc2 | 270 | { |
fa73b229 | 271 | if (strlen(dent->filename) > 6 && |
272 | !strcmp(dent->filename + strlen(dent->filename) - 6, ".convs")) | |
ef416fc2 | 273 | { |
274 | /* | |
275 | * Load a mime.convs file... | |
276 | */ | |
277 | ||
fa73b229 | 278 | snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename); |
4400e98d | 279 | load_convs(mime, filename, filterpath, filtercache); |
ef416fc2 | 280 | } |
281 | } | |
282 | ||
4400e98d | 283 | delete_fcache(filtercache); |
284 | ||
fa73b229 | 285 | cupsDirClose(dir); |
ef416fc2 | 286 | |
287 | return (mime); | |
ef416fc2 | 288 | } |
289 | ||
290 | ||
291 | /* | |
292 | * 'mimeNew()' - Create a new, empty MIME database. | |
293 | */ | |
294 | ||
fa73b229 | 295 | mime_t * /* O - MIME database */ |
ef416fc2 | 296 | mimeNew(void) |
297 | { | |
298 | return ((mime_t *)calloc(1, sizeof(mime_t))); | |
299 | } | |
300 | ||
301 | ||
fa73b229 | 302 | /* |
303 | * 'mimeNextFilter()' - Get the next filter in the MIME database. | |
304 | */ | |
305 | ||
306 | mime_filter_t * /* O - Filter or NULL */ | |
307 | mimeNextFilter(mime_t *mime) /* I - MIME database */ | |
308 | { | |
309 | if (!mime) | |
310 | return (NULL); | |
311 | else | |
312 | return ((mime_filter_t *)cupsArrayNext(mime->filters)); | |
313 | } | |
314 | ||
315 | ||
316 | /* | |
317 | * 'mimeNextType()' - Get the next type in the MIME database. | |
318 | */ | |
319 | ||
320 | mime_type_t * /* O - Type or NULL */ | |
321 | mimeNextType(mime_t *mime) /* I - MIME database */ | |
322 | { | |
323 | if (!mime) | |
324 | return (NULL); | |
325 | else | |
326 | return ((mime_type_t *)cupsArrayNext(mime->types)); | |
327 | } | |
328 | ||
329 | ||
330 | /* | |
331 | * 'mimeNumFilters()' - Get the number of filters in a MIME database. | |
332 | */ | |
333 | ||
334 | int | |
335 | mimeNumFilters(mime_t *mime) /* I - MIME database */ | |
336 | { | |
337 | if (!mime) | |
338 | return (0); | |
339 | else | |
340 | return (cupsArrayCount(mime->filters)); | |
341 | } | |
342 | ||
343 | ||
344 | /* | |
345 | * 'mimeNumTypes()' - Get the number of types in a MIME database. | |
346 | */ | |
347 | ||
348 | int | |
349 | mimeNumTypes(mime_t *mime) /* I - MIME database */ | |
350 | { | |
351 | if (!mime) | |
352 | return (0); | |
353 | else | |
354 | return (cupsArrayCount(mime->types)); | |
355 | } | |
356 | ||
357 | ||
ef416fc2 | 358 | /* |
4400e98d | 359 | * 'add_fcache()' - Add a filter to the filter cache. |
ef416fc2 | 360 | */ |
361 | ||
4400e98d | 362 | static const char * /* O - Full path to filter or NULL */ |
363 | add_fcache(cups_array_t *filtercache, /* I - Filter cache */ | |
364 | const char *name, /* I - Filter name */ | |
365 | const char *filterpath) /* I - Filter path */ | |
ef416fc2 | 366 | { |
4400e98d | 367 | _mime_fcache_t key, /* Search key */ |
368 | *temp; /* New filter cache */ | |
369 | char path[1024]; /* Full path to filter */ | |
ef416fc2 | 370 | |
371 | ||
4400e98d | 372 | key.name = (char *)name; |
373 | if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL) | |
374 | return (temp->path); | |
ef416fc2 | 375 | |
4400e98d | 376 | if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL) |
377 | return (NULL); | |
ef416fc2 | 378 | |
4400e98d | 379 | temp->name = strdup(name); |
ef416fc2 | 380 | |
4400e98d | 381 | if (cupsFileFind(name, filterpath, 1, path, sizeof(path))) |
382 | temp->path = strdup(path); | |
ef416fc2 | 383 | |
4400e98d | 384 | cupsArrayAdd(filtercache, temp); |
ef416fc2 | 385 | |
4400e98d | 386 | return (temp->path); |
387 | } | |
ef416fc2 | 388 | |
ef416fc2 | 389 | |
4400e98d | 390 | /* |
391 | * 'compare_fcache()' - Compare two filter cache entries. | |
392 | */ | |
ef416fc2 | 393 | |
4400e98d | 394 | static int /* O - Result of comparison */ |
395 | compare_fcache(_mime_fcache_t *a, /* I - First entry */ | |
396 | _mime_fcache_t *b) /* I - Second entry */ | |
397 | { | |
398 | return (strcmp(a->name, b->name)); | |
399 | } | |
ef416fc2 | 400 | |
ef416fc2 | 401 | |
4400e98d | 402 | /* |
403 | * 'delete_fcache()' - Free all memory used by the filter cache. | |
404 | */ | |
ef416fc2 | 405 | |
4400e98d | 406 | static void |
407 | delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ | |
408 | { | |
409 | _mime_fcache_t *current; /* Current cache entry */ | |
ef416fc2 | 410 | |
ef416fc2 | 411 | |
4400e98d | 412 | for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache); |
413 | current; | |
414 | current = (_mime_fcache_t *)cupsArrayNext(filtercache)) | |
415 | { | |
416 | free(current->name); | |
ef416fc2 | 417 | |
4400e98d | 418 | if (current->path) |
419 | free(current->path); | |
ef416fc2 | 420 | |
4400e98d | 421 | free(current); |
422 | } | |
ef416fc2 | 423 | |
4400e98d | 424 | cupsArrayDelete(filtercache); |
425 | } | |
ef416fc2 | 426 | |
ef416fc2 | 427 | |
4400e98d | 428 | /* |
429 | * 'delete_rules()' - Free all memory for the given rule tree. | |
430 | */ | |
ef416fc2 | 431 | |
4400e98d | 432 | static void |
433 | delete_rules(mime_magic_t *rules) /* I - Rules to free */ | |
434 | { | |
435 | mime_magic_t *next; /* Next rule to free */ | |
436 | ||
437 | ||
438 | /* | |
439 | * Free the rules list, descending recursively to free any child rules. | |
440 | */ | |
441 | ||
442 | while (rules != NULL) | |
443 | { | |
444 | next = rules->next; | |
445 | ||
446 | if (rules->child != NULL) | |
447 | delete_rules(rules->child); | |
448 | ||
449 | free(rules); | |
450 | rules = next; | |
451 | } | |
ef416fc2 | 452 | } |
453 | ||
454 | ||
455 | /* | |
456 | * 'load_convs()' - Load a xyz.convs file... | |
457 | */ | |
458 | ||
459 | static void | |
4400e98d | 460 | load_convs(mime_t *mime, /* I - MIME database */ |
461 | const char *filename, /* I - Convs file to load */ | |
462 | const char *filterpath, /* I - Path for filters */ | |
463 | cups_array_t *filtercache) /* I - Filter program cache */ | |
ef416fc2 | 464 | { |
ef416fc2 | 465 | cups_file_t *fp; /* Convs file */ |
466 | char line[1024], /* Input line from file */ | |
467 | *lineptr, /* Current position in line */ | |
468 | super[MIME_MAX_SUPER], /* Super-type name */ | |
469 | type[MIME_MAX_TYPE], /* Type name */ | |
470 | *temp, /* Temporary pointer */ | |
471 | *filter; /* Filter program */ | |
fa73b229 | 472 | mime_type_t *temptype, /* MIME type looping var */ |
ef416fc2 | 473 | *dsttype; /* Destination MIME type */ |
474 | int cost; /* Cost of filter */ | |
ef416fc2 | 475 | |
476 | ||
477 | /* | |
478 | * First try to open the file... | |
479 | */ | |
480 | ||
481 | if ((fp = cupsFileOpen(filename, "r")) == NULL) | |
482 | return; | |
483 | ||
ed486911 | 484 | DEBUG_printf(("\"%s\":\n", filename)); |
485 | ||
ef416fc2 | 486 | /* |
487 | * Then read each line from the file, skipping any comments in the file... | |
488 | */ | |
489 | ||
490 | while (cupsFileGets(fp, line, sizeof(line)) != NULL) | |
491 | { | |
492 | /* | |
493 | * Skip blank lines and lines starting with a #... | |
494 | */ | |
495 | ||
ed486911 | 496 | DEBUG_puts(line); |
497 | ||
ef416fc2 | 498 | if (!line[0] || line[0] == '#') |
499 | continue; | |
500 | ||
501 | /* | |
502 | * Strip trailing whitespace... | |
503 | */ | |
504 | ||
505 | for (lineptr = line + strlen(line) - 1; | |
506 | lineptr >= line && isspace(*lineptr & 255); | |
507 | lineptr --) | |
508 | *lineptr = '\0'; | |
509 | ||
510 | /* | |
511 | * Extract the destination super-type and type names from the middle of | |
512 | * the line. | |
513 | */ | |
514 | ||
515 | lineptr = line; | |
516 | while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0') | |
517 | lineptr ++; | |
518 | ||
519 | while (*lineptr == ' ' || *lineptr == '\t') | |
520 | lineptr ++; | |
521 | ||
522 | temp = super; | |
523 | ||
524 | while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' && | |
525 | (temp - super + 1) < MIME_MAX_SUPER) | |
526 | *temp++ = tolower(*lineptr++ & 255); | |
527 | ||
528 | *temp = '\0'; | |
529 | ||
530 | if (*lineptr != '/') | |
531 | continue; | |
532 | ||
533 | lineptr ++; | |
534 | temp = type; | |
535 | ||
536 | while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' && | |
537 | *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE) | |
538 | *temp++ = tolower(*lineptr++ & 255); | |
539 | ||
540 | *temp = '\0'; | |
541 | ||
542 | if (*lineptr == '\0' || *lineptr == '\n') | |
543 | continue; | |
544 | ||
545 | if ((dsttype = mimeType(mime, super, type)) == NULL) | |
ed486911 | 546 | { |
547 | DEBUG_printf((" Destination type %s/%s not found!\n", super, type)); | |
ef416fc2 | 548 | continue; |
ed486911 | 549 | } |
ef416fc2 | 550 | |
551 | /* | |
552 | * Then get the cost and filter program... | |
553 | */ | |
554 | ||
555 | while (*lineptr == ' ' || *lineptr == '\t') | |
556 | lineptr ++; | |
557 | ||
558 | if (*lineptr < '0' || *lineptr > '9') | |
559 | continue; | |
560 | ||
561 | cost = atoi(lineptr); | |
562 | ||
563 | while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0') | |
564 | lineptr ++; | |
565 | while (*lineptr == ' ' || *lineptr == '\t') | |
566 | lineptr ++; | |
567 | ||
568 | if (*lineptr == '\0' || *lineptr == '\n') | |
569 | continue; | |
570 | ||
571 | filter = lineptr; | |
572 | ||
fa73b229 | 573 | if (strcmp(filter, "-")) |
ef416fc2 | 574 | { |
575 | /* | |
576 | * Verify that the filter exists and is executable... | |
577 | */ | |
578 | ||
4400e98d | 579 | if (!add_fcache(filtercache, filter, filterpath)) |
ed486911 | 580 | { |
581 | DEBUG_printf((" Filter %s not found in %s!\n", filter, filterpath)); | |
fa73b229 | 582 | continue; |
ed486911 | 583 | } |
ef416fc2 | 584 | } |
ef416fc2 | 585 | |
586 | /* | |
587 | * Finally, get the source super-type and type names from the beginning of | |
588 | * the line. We do it here so we can support wildcards... | |
589 | */ | |
590 | ||
591 | lineptr = line; | |
592 | temp = super; | |
593 | ||
594 | while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' && | |
595 | (temp - super + 1) < MIME_MAX_SUPER) | |
596 | *temp++ = tolower(*lineptr++ & 255); | |
597 | ||
598 | *temp = '\0'; | |
599 | ||
600 | if (*lineptr != '/') | |
601 | continue; | |
602 | ||
603 | lineptr ++; | |
604 | temp = type; | |
605 | ||
606 | while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' && | |
607 | *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE) | |
608 | *temp++ = tolower(*lineptr++ & 255); | |
609 | ||
610 | *temp = '\0'; | |
611 | ||
fa73b229 | 612 | if (!strcmp(super, "*") && !strcmp(type, "*")) |
ef416fc2 | 613 | { |
614 | /* | |
615 | * Force * / * to be "application/octet-stream"... | |
616 | */ | |
617 | ||
618 | strcpy(super, "application"); | |
619 | strcpy(type, "octet-stream"); | |
620 | } | |
621 | ||
622 | /* | |
623 | * Add the filter to the MIME database, supporting wildcards as needed... | |
624 | */ | |
625 | ||
fa73b229 | 626 | for (temptype = (mime_type_t *)cupsArrayFirst(mime->types); |
627 | temptype; | |
628 | temptype = (mime_type_t *)cupsArrayNext(mime->types)) | |
629 | if ((super[0] == '*' || !strcmp(temptype->super, super)) && | |
630 | (type[0] == '*' || !strcmp(temptype->type, type))) | |
631 | mimeAddFilter(mime, temptype, dsttype, cost, filter); | |
ef416fc2 | 632 | } |
633 | ||
634 | cupsFileClose(fp); | |
635 | } | |
636 | ||
637 | ||
638 | /* | |
4400e98d | 639 | * 'load_types()' - Load a xyz.types file... |
ef416fc2 | 640 | */ |
641 | ||
642 | static void | |
4400e98d | 643 | load_types(mime_t *mime, /* I - MIME database */ |
644 | const char *filename) /* I - Types file to load */ | |
ef416fc2 | 645 | { |
4400e98d | 646 | cups_file_t *fp; /* Types file */ |
647 | int linelen; /* Length of line */ | |
a74454a7 | 648 | char line[32768], /* Input line from file */ |
4400e98d | 649 | *lineptr, /* Current position in line */ |
650 | super[MIME_MAX_SUPER], /* Super-type name */ | |
651 | type[MIME_MAX_TYPE], /* Type name */ | |
652 | *temp; /* Temporary pointer */ | |
653 | mime_type_t *typeptr; /* New MIME type */ | |
ef416fc2 | 654 | |
655 | ||
656 | /* | |
4400e98d | 657 | * First try to open the file... |
ef416fc2 | 658 | */ |
659 | ||
4400e98d | 660 | if ((fp = cupsFileOpen(filename, "r")) == NULL) |
661 | return; | |
662 | ||
ed486911 | 663 | DEBUG_printf(("\"%s\":\n", filename)); |
664 | ||
4400e98d | 665 | /* |
666 | * Then read each line from the file, skipping any comments in the file... | |
667 | */ | |
668 | ||
669 | while (cupsFileGets(fp, line, sizeof(line)) != NULL) | |
ef416fc2 | 670 | { |
4400e98d | 671 | /* |
672 | * Skip blank lines and lines starting with a #... | |
673 | */ | |
ef416fc2 | 674 | |
ed486911 | 675 | DEBUG_puts(line); |
676 | ||
4400e98d | 677 | if (!line[0] || line[0] == '#') |
678 | continue; | |
ef416fc2 | 679 | |
4400e98d | 680 | /* |
681 | * While the last character in the line is a backslash, continue on to the | |
682 | * next line (and the next, etc.) | |
683 | */ | |
684 | ||
685 | linelen = strlen(line); | |
686 | ||
687 | while (line[linelen - 1] == '\\') | |
688 | { | |
689 | linelen --; | |
690 | ||
691 | if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL) | |
692 | line[linelen] = '\0'; | |
693 | else | |
694 | linelen += strlen(line + linelen); | |
695 | } | |
696 | ||
697 | /* | |
698 | * Extract the super-type and type names from the beginning of the line. | |
699 | */ | |
700 | ||
701 | lineptr = line; | |
702 | temp = super; | |
703 | ||
704 | while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' && | |
705 | (temp - super + 1) < MIME_MAX_SUPER) | |
706 | *temp++ = tolower(*lineptr++ & 255); | |
707 | ||
708 | *temp = '\0'; | |
709 | ||
710 | if (*lineptr != '/') | |
711 | continue; | |
712 | ||
713 | lineptr ++; | |
714 | temp = type; | |
715 | ||
716 | while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' && | |
717 | *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE) | |
718 | *temp++ = tolower(*lineptr++ & 255); | |
719 | ||
720 | *temp = '\0'; | |
721 | ||
722 | /* | |
723 | * Add the type and rules to the MIME database... | |
724 | */ | |
725 | ||
726 | typeptr = mimeAddType(mime, super, type); | |
727 | mimeAddTypeRule(typeptr, lineptr); | |
ef416fc2 | 728 | } |
4400e98d | 729 | |
730 | cupsFileClose(fp); | |
ef416fc2 | 731 | } |
732 | ||
733 | ||
734 | /* | |
bc44d920 | 735 | * End of "$Id: mime.c 6649 2007-07-11 21:46:42Z mike $". |
ef416fc2 | 736 | */ |