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