]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2 * "$Id: mime.c 5394 2006-04-14 18:20:04Z mike $"
4 * MIME database file routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
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.
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.
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.
41 * delete_rules() - Free all memory for the given rule tree.
42 * load_convs() - Load a xyz.convs file...
43 * load_types() - Load a xyz.types file...
47 * Include necessary headers...
55 #include <cups/string.h>
63 typedef struct _mime_fcache_s
/**** Filter cache structure ****/
65 char *name
, /* Filter name */
66 *path
; /* Full path to filter if available */
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
);
78 static void delete_rules(mime_magic_t
*rules
);
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
);
86 * 'mimeDelete()' - Delete (free) a MIME database.
90 mimeDelete(mime_t
*mime
) /* I - MIME database */
92 mime_type_t
*type
; /* Current type */
93 mime_filter_t
*filter
; /* Current filter */
100 * Loop through filters and free them...
103 for (filter
= (mime_filter_t
*)cupsArrayFirst(mime
->filters
);
105 filter
= (mime_filter_t
*)cupsArrayNext(mime
->filters
))
106 mimeDeleteFilter(mime
, filter
);
109 * Loop through the file types and delete any rules...
112 for (type
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
114 type
= (mime_type_t
*)cupsArrayNext(mime
->types
))
115 mimeDeleteType(mime
, type
);
118 * Free the types and filters arrays, and then the MIME database structure.
121 cupsArrayDelete(mime
->types
);
122 cupsArrayDelete(mime
->filters
);
128 * 'mimeDeleteFilter()' - Delete a filter from the MIME database.
132 mimeDeleteFilter(mime_t
*mime
, /* I - MIME database */
133 mime_filter_t
*filter
) /* I - Filter */
135 if (!mime
|| !filter
)
138 cupsArrayRemove(mime
->filters
, filter
);
144 * 'mimeDeleteType()' - Delete a type from the MIME database.
148 mimeDeleteType(mime_t
*mime
, /* I - MIME database */
149 mime_type_t
*mt
) /* I - Type */
154 cupsArrayRemove(mime
->types
, mt
);
156 delete_rules(mt
->rules
);
162 * 'mimeFirstFilter()' - Get the first filter in the MIME database.
165 mime_filter_t
* /* O - Filter or NULL */
166 mimeFirstFilter(mime_t
*mime
) /* I - MIME database */
171 return ((mime_filter_t
*)cupsArrayFirst(mime
->filters
));
176 * 'mimeFirstType()' - Get the first type in the MIME database.
179 mime_type_t
* /* O - Type or NULL */
180 mimeFirstType(mime_t
*mime
) /* I - MIME database */
185 return ((mime_type_t
*)cupsArrayFirst(mime
->types
));
190 * 'mimeLoad()' - Create a new MIME database from disk.
193 mime_t
* /* O - New MIME database */
194 mimeLoad(const char *pathname
, /* I - Directory to load */
195 const char *filterpath
) /* I - Directory to load */
197 return (mimeMerge(NULL
, pathname
, filterpath
));
202 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
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 */
210 cups_dir_t
*dir
; /* Directory */
211 cups_dentry_t
*dent
; /* Directory entry */
212 char filename
[1024]; /* Full filename of types/converts file */
213 cups_array_t
*filtercache
; /* Filter cache */
217 * First open the directory specified by pathname... Return NULL if nothing
218 * was read or if the pathname is NULL...
224 if ((dir
= cupsDirOpen(pathname
)) == NULL
)
228 * If "mime" is NULL, make a new, blank database...
237 * Read all the .types files...
240 while ((dent
= cupsDirRead(dir
)) != NULL
)
242 if (strlen(dent
->filename
) > 6 &&
243 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".types"))
246 * Load a mime.types file...
249 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
250 load_types(mime
, filename
);
257 * Read all the .convs files...
260 filtercache
= cupsArrayNew((cups_array_func_t
)compare_fcache
, NULL
);
262 while ((dent
= cupsDirRead(dir
)) != NULL
)
264 if (strlen(dent
->filename
) > 6 &&
265 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".convs"))
268 * Load a mime.convs file...
271 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
272 load_convs(mime
, filename
, filterpath
, filtercache
);
276 delete_fcache(filtercache
);
285 * 'mimeNew()' - Create a new, empty MIME database.
288 mime_t
* /* O - MIME database */
291 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
296 * 'mimeNextFilter()' - Get the next filter in the MIME database.
299 mime_filter_t
* /* O - Filter or NULL */
300 mimeNextFilter(mime_t
*mime
) /* I - MIME database */
305 return ((mime_filter_t
*)cupsArrayNext(mime
->filters
));
310 * 'mimeNextType()' - Get the next type in the MIME database.
313 mime_type_t
* /* O - Type or NULL */
314 mimeNextType(mime_t
*mime
) /* I - MIME database */
319 return ((mime_type_t
*)cupsArrayNext(mime
->types
));
324 * 'mimeNumFilters()' - Get the number of filters in a MIME database.
328 mimeNumFilters(mime_t
*mime
) /* I - MIME database */
333 return (cupsArrayCount(mime
->filters
));
338 * 'mimeNumTypes()' - Get the number of types in a MIME database.
342 mimeNumTypes(mime_t
*mime
) /* I - MIME database */
347 return (cupsArrayCount(mime
->types
));
352 * 'add_fcache()' - Add a filter to the filter cache.
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 */
360 _mime_fcache_t key
, /* Search key */
361 *temp
; /* New filter cache */
362 char path
[1024]; /* Full path to filter */
365 key
.name
= (char *)name
;
366 if ((temp
= (_mime_fcache_t
*)cupsArrayFind(filtercache
, &key
)) != NULL
)
369 if ((temp
= calloc(1, sizeof(_mime_fcache_t
))) == NULL
)
372 temp
->name
= strdup(name
);
374 if (cupsFileFind(name
, filterpath
, 1, path
, sizeof(path
)))
375 temp
->path
= strdup(path
);
377 cupsArrayAdd(filtercache
, temp
);
384 * 'compare_fcache()' - Compare two filter cache entries.
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 */
391 return (strcmp(a
->name
, b
->name
));
396 * 'delete_fcache()' - Free all memory used by the filter cache.
400 delete_fcache(cups_array_t
*filtercache
)/* I - Filter cache */
402 _mime_fcache_t
*current
; /* Current cache entry */
405 for (current
= (_mime_fcache_t
*)cupsArrayFirst(filtercache
);
407 current
= (_mime_fcache_t
*)cupsArrayNext(filtercache
))
417 cupsArrayDelete(filtercache
);
422 * 'delete_rules()' - Free all memory for the given rule tree.
426 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
428 mime_magic_t
*next
; /* Next rule to free */
432 * Free the rules list, descending recursively to free any child rules.
435 while (rules
!= NULL
)
439 if (rules
->child
!= NULL
)
440 delete_rules(rules
->child
);
449 * 'load_convs()' - Load a xyz.convs file...
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 */
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 */
465 mime_type_t
*temptype
, /* MIME type looping var */
466 *dsttype
; /* Destination MIME type */
467 int cost
; /* Cost of filter */
471 * First try to open the file...
474 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
478 * Then read each line from the file, skipping any comments in the file...
481 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
484 * Skip blank lines and lines starting with a #...
487 if (!line
[0] || line
[0] == '#')
491 * Strip trailing whitespace...
494 for (lineptr
= line
+ strlen(line
) - 1;
495 lineptr
>= line
&& isspace(*lineptr
& 255);
500 * Extract the destination super-type and type names from the middle of
505 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
508 while (*lineptr
== ' ' || *lineptr
== '\t')
513 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
514 (temp
- super
+ 1) < MIME_MAX_SUPER
)
515 *temp
++ = tolower(*lineptr
++ & 255);
525 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
526 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
527 *temp
++ = tolower(*lineptr
++ & 255);
531 if (*lineptr
== '\0' || *lineptr
== '\n')
534 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
538 * Then get the cost and filter program...
541 while (*lineptr
== ' ' || *lineptr
== '\t')
544 if (*lineptr
< '0' || *lineptr
> '9')
547 cost
= atoi(lineptr
);
549 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
551 while (*lineptr
== ' ' || *lineptr
== '\t')
554 if (*lineptr
== '\0' || *lineptr
== '\n')
559 if (strcmp(filter
, "-"))
562 * Verify that the filter exists and is executable...
565 if (!add_fcache(filtercache
, filter
, filterpath
))
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...
577 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
578 (temp
- super
+ 1) < MIME_MAX_SUPER
)
579 *temp
++ = tolower(*lineptr
++ & 255);
589 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
590 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
591 *temp
++ = tolower(*lineptr
++ & 255);
595 if (!strcmp(super
, "*") && !strcmp(type
, "*"))
598 * Force * / * to be "application/octet-stream"...
601 strcpy(super
, "application");
602 strcpy(type
, "octet-stream");
606 * Add the filter to the MIME database, supporting wildcards as needed...
609 for (temptype
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
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
);
622 * 'load_types()' - Load a xyz.types file...
626 load_types(mime_t
*mime
, /* I - MIME database */
627 const char *filename
) /* I - Types file to load */
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 */
640 * First try to open the file...
643 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
647 * Then read each line from the file, skipping any comments in the file...
650 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
653 * Skip blank lines and lines starting with a #...
656 if (!line
[0] || line
[0] == '#')
660 * While the last character in the line is a backslash, continue on to the
661 * next line (and the next, etc.)
664 linelen
= strlen(line
);
666 while (line
[linelen
- 1] == '\\')
670 if (cupsFileGets(fp
, line
+ linelen
, sizeof(line
) - linelen
) == NULL
)
671 line
[linelen
] = '\0';
673 linelen
+= strlen(line
+ linelen
);
677 * Extract the super-type and type names from the beginning of the line.
683 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
684 (temp
- super
+ 1) < MIME_MAX_SUPER
)
685 *temp
++ = tolower(*lineptr
++ & 255);
695 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
696 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
697 *temp
++ = tolower(*lineptr
++ & 255);
702 * Add the type and rules to the MIME database...
705 typeptr
= mimeAddType(mime
, super
, type
);
706 mimeAddTypeRule(typeptr
, lineptr
);
714 * End of "$Id: mime.c 5394 2006-04-14 18:20:04Z mike $".