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