]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2 * "$Id: mime.c 5495 2006-05-05 17:58:07Z 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
);
123 cupsArrayDelete(mime
->srcs
);
129 * 'mimeDeleteFilter()' - Delete a filter from the MIME database.
133 mimeDeleteFilter(mime_t
*mime
, /* I - MIME database */
134 mime_filter_t
*filter
) /* I - Filter */
136 if (!mime
|| !filter
)
139 cupsArrayRemove(mime
->filters
, filter
);
143 * Deleting a filter invalidates the source lookup cache used by
149 cupsArrayDelete(mime
->srcs
);
156 * 'mimeDeleteType()' - Delete a type from the MIME database.
160 mimeDeleteType(mime_t
*mime
, /* I - MIME database */
161 mime_type_t
*mt
) /* I - Type */
166 cupsArrayRemove(mime
->types
, mt
);
168 delete_rules(mt
->rules
);
174 * 'mimeFirstFilter()' - Get the first filter in the MIME database.
177 mime_filter_t
* /* O - Filter or NULL */
178 mimeFirstFilter(mime_t
*mime
) /* I - MIME database */
183 return ((mime_filter_t
*)cupsArrayFirst(mime
->filters
));
188 * 'mimeFirstType()' - Get the first type in the MIME database.
191 mime_type_t
* /* O - Type or NULL */
192 mimeFirstType(mime_t
*mime
) /* I - MIME database */
197 return ((mime_type_t
*)cupsArrayFirst(mime
->types
));
202 * 'mimeLoad()' - Create a new MIME database from disk.
205 mime_t
* /* O - New MIME database */
206 mimeLoad(const char *pathname
, /* I - Directory to load */
207 const char *filterpath
) /* I - Directory to load */
209 return (mimeMerge(NULL
, pathname
, filterpath
));
214 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
217 mime_t
* /* O - Updated MIME database */
218 mimeMerge(mime_t
*mime
, /* I - MIME database to add to */
219 const char *pathname
, /* I - Directory to load */
220 const char *filterpath
) /* I - Directory to load */
222 cups_dir_t
*dir
; /* Directory */
223 cups_dentry_t
*dent
; /* Directory entry */
224 char filename
[1024]; /* Full filename of types/converts file */
225 cups_array_t
*filtercache
; /* Filter cache */
229 * First open the directory specified by pathname... Return NULL if nothing
230 * was read or if the pathname is NULL...
236 if ((dir
= cupsDirOpen(pathname
)) == NULL
)
240 * If "mime" is NULL, make a new, blank database...
249 * Read all the .types files...
252 while ((dent
= cupsDirRead(dir
)) != NULL
)
254 if (strlen(dent
->filename
) > 6 &&
255 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".types"))
258 * Load a mime.types file...
261 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
262 load_types(mime
, filename
);
269 * Read all the .convs files...
272 filtercache
= cupsArrayNew((cups_array_func_t
)compare_fcache
, NULL
);
274 while ((dent
= cupsDirRead(dir
)) != NULL
)
276 if (strlen(dent
->filename
) > 6 &&
277 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".convs"))
280 * Load a mime.convs file...
283 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
284 load_convs(mime
, filename
, filterpath
, filtercache
);
288 delete_fcache(filtercache
);
297 * 'mimeNew()' - Create a new, empty MIME database.
300 mime_t
* /* O - MIME database */
303 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
308 * 'mimeNextFilter()' - Get the next filter in the MIME database.
311 mime_filter_t
* /* O - Filter or NULL */
312 mimeNextFilter(mime_t
*mime
) /* I - MIME database */
317 return ((mime_filter_t
*)cupsArrayNext(mime
->filters
));
322 * 'mimeNextType()' - Get the next type in the MIME database.
325 mime_type_t
* /* O - Type or NULL */
326 mimeNextType(mime_t
*mime
) /* I - MIME database */
331 return ((mime_type_t
*)cupsArrayNext(mime
->types
));
336 * 'mimeNumFilters()' - Get the number of filters in a MIME database.
340 mimeNumFilters(mime_t
*mime
) /* I - MIME database */
345 return (cupsArrayCount(mime
->filters
));
350 * 'mimeNumTypes()' - Get the number of types in a MIME database.
354 mimeNumTypes(mime_t
*mime
) /* I - MIME database */
359 return (cupsArrayCount(mime
->types
));
364 * 'add_fcache()' - Add a filter to the filter cache.
367 static const char * /* O - Full path to filter or NULL */
368 add_fcache(cups_array_t
*filtercache
, /* I - Filter cache */
369 const char *name
, /* I - Filter name */
370 const char *filterpath
) /* I - Filter path */
372 _mime_fcache_t key
, /* Search key */
373 *temp
; /* New filter cache */
374 char path
[1024]; /* Full path to filter */
377 key
.name
= (char *)name
;
378 if ((temp
= (_mime_fcache_t
*)cupsArrayFind(filtercache
, &key
)) != NULL
)
381 if ((temp
= calloc(1, sizeof(_mime_fcache_t
))) == NULL
)
384 temp
->name
= strdup(name
);
386 if (cupsFileFind(name
, filterpath
, 1, path
, sizeof(path
)))
387 temp
->path
= strdup(path
);
389 cupsArrayAdd(filtercache
, temp
);
396 * 'compare_fcache()' - Compare two filter cache entries.
399 static int /* O - Result of comparison */
400 compare_fcache(_mime_fcache_t
*a
, /* I - First entry */
401 _mime_fcache_t
*b
) /* I - Second entry */
403 return (strcmp(a
->name
, b
->name
));
408 * 'delete_fcache()' - Free all memory used by the filter cache.
412 delete_fcache(cups_array_t
*filtercache
)/* I - Filter cache */
414 _mime_fcache_t
*current
; /* Current cache entry */
417 for (current
= (_mime_fcache_t
*)cupsArrayFirst(filtercache
);
419 current
= (_mime_fcache_t
*)cupsArrayNext(filtercache
))
429 cupsArrayDelete(filtercache
);
434 * 'delete_rules()' - Free all memory for the given rule tree.
438 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
440 mime_magic_t
*next
; /* Next rule to free */
444 * Free the rules list, descending recursively to free any child rules.
447 while (rules
!= NULL
)
451 if (rules
->child
!= NULL
)
452 delete_rules(rules
->child
);
461 * 'load_convs()' - Load a xyz.convs file...
465 load_convs(mime_t
*mime
, /* I - MIME database */
466 const char *filename
, /* I - Convs file to load */
467 const char *filterpath
, /* I - Path for filters */
468 cups_array_t
*filtercache
) /* I - Filter program cache */
470 cups_file_t
*fp
; /* Convs file */
471 char line
[1024], /* Input line from file */
472 *lineptr
, /* Current position in line */
473 super
[MIME_MAX_SUPER
], /* Super-type name */
474 type
[MIME_MAX_TYPE
], /* Type name */
475 *temp
, /* Temporary pointer */
476 *filter
; /* Filter program */
477 mime_type_t
*temptype
, /* MIME type looping var */
478 *dsttype
; /* Destination MIME type */
479 int cost
; /* Cost of filter */
483 * First try to open the file...
486 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
490 * Then read each line from the file, skipping any comments in the file...
493 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
496 * Skip blank lines and lines starting with a #...
499 if (!line
[0] || line
[0] == '#')
503 * Strip trailing whitespace...
506 for (lineptr
= line
+ strlen(line
) - 1;
507 lineptr
>= line
&& isspace(*lineptr
& 255);
512 * Extract the destination super-type and type names from the middle of
517 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
520 while (*lineptr
== ' ' || *lineptr
== '\t')
525 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
526 (temp
- super
+ 1) < MIME_MAX_SUPER
)
527 *temp
++ = tolower(*lineptr
++ & 255);
537 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
538 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
539 *temp
++ = tolower(*lineptr
++ & 255);
543 if (*lineptr
== '\0' || *lineptr
== '\n')
546 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
550 * Then get the cost and filter program...
553 while (*lineptr
== ' ' || *lineptr
== '\t')
556 if (*lineptr
< '0' || *lineptr
> '9')
559 cost
= atoi(lineptr
);
561 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
563 while (*lineptr
== ' ' || *lineptr
== '\t')
566 if (*lineptr
== '\0' || *lineptr
== '\n')
571 if (strcmp(filter
, "-"))
574 * Verify that the filter exists and is executable...
577 if (!add_fcache(filtercache
, filter
, filterpath
))
582 * Finally, get the source super-type and type names from the beginning of
583 * the line. We do it here so we can support wildcards...
589 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
590 (temp
- super
+ 1) < MIME_MAX_SUPER
)
591 *temp
++ = tolower(*lineptr
++ & 255);
601 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
602 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
603 *temp
++ = tolower(*lineptr
++ & 255);
607 if (!strcmp(super
, "*") && !strcmp(type
, "*"))
610 * Force * / * to be "application/octet-stream"...
613 strcpy(super
, "application");
614 strcpy(type
, "octet-stream");
618 * Add the filter to the MIME database, supporting wildcards as needed...
621 for (temptype
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
623 temptype
= (mime_type_t
*)cupsArrayNext(mime
->types
))
624 if ((super
[0] == '*' || !strcmp(temptype
->super
, super
)) &&
625 (type
[0] == '*' || !strcmp(temptype
->type
, type
)))
626 mimeAddFilter(mime
, temptype
, dsttype
, cost
, filter
);
634 * 'load_types()' - Load a xyz.types file...
638 load_types(mime_t
*mime
, /* I - MIME database */
639 const char *filename
) /* I - Types file to load */
641 cups_file_t
*fp
; /* Types file */
642 int linelen
; /* Length of line */
643 char line
[32768], /* Input line from file */
644 *lineptr
, /* Current position in line */
645 super
[MIME_MAX_SUPER
], /* Super-type name */
646 type
[MIME_MAX_TYPE
], /* Type name */
647 *temp
; /* Temporary pointer */
648 mime_type_t
*typeptr
; /* New MIME type */
652 * First try to open the file...
655 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
659 * Then read each line from the file, skipping any comments in the file...
662 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
665 * Skip blank lines and lines starting with a #...
668 if (!line
[0] || line
[0] == '#')
672 * While the last character in the line is a backslash, continue on to the
673 * next line (and the next, etc.)
676 linelen
= strlen(line
);
678 while (line
[linelen
- 1] == '\\')
682 if (cupsFileGets(fp
, line
+ linelen
, sizeof(line
) - linelen
) == NULL
)
683 line
[linelen
] = '\0';
685 linelen
+= strlen(line
+ linelen
);
689 * Extract the super-type and type names from the beginning of the line.
695 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
696 (temp
- super
+ 1) < MIME_MAX_SUPER
)
697 *temp
++ = tolower(*lineptr
++ & 255);
707 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
708 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
709 *temp
++ = tolower(*lineptr
++ & 255);
714 * Add the type and rules to the MIME database...
717 typeptr
= mimeAddType(mime
, super
, type
);
718 mimeAddTypeRule(typeptr
, lineptr
);
726 * End of "$Id: mime.c 5495 2006-05-05 17:58:07Z mike $".