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