]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2 * "$Id: mime.c 181 2006-06-22 20:01:18Z jlovell $"
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...
54 #include <cups/debug.h>
56 #include <cups/string.h>
64 typedef struct _mime_fcache_s
/**** Filter cache structure ****/
66 char *name
, /* Filter name */
67 *path
; /* Full path to filter if available */
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
);
79 static void delete_rules(mime_magic_t
*rules
);
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
);
87 * 'mimeDelete()' - Delete (free) a MIME database.
91 mimeDelete(mime_t
*mime
) /* I - MIME database */
93 mime_type_t
*type
; /* Current type */
94 mime_filter_t
*filter
; /* Current filter */
101 * Loop through filters and free them...
104 for (filter
= (mime_filter_t
*)cupsArrayFirst(mime
->filters
);
106 filter
= (mime_filter_t
*)cupsArrayNext(mime
->filters
))
107 mimeDeleteFilter(mime
, filter
);
110 * Loop through the file types and delete any rules...
113 for (type
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
115 type
= (mime_type_t
*)cupsArrayNext(mime
->types
))
116 mimeDeleteType(mime
, type
);
119 * Free the types and filters arrays, and then the MIME database structure.
122 cupsArrayDelete(mime
->types
);
123 cupsArrayDelete(mime
->filters
);
124 cupsArrayDelete(mime
->srcs
);
130 * 'mimeDeleteFilter()' - Delete a filter from the MIME database.
134 mimeDeleteFilter(mime_t
*mime
, /* I - MIME database */
135 mime_filter_t
*filter
) /* I - Filter */
137 if (!mime
|| !filter
)
140 cupsArrayRemove(mime
->filters
, filter
);
144 * Deleting a filter invalidates the source lookup cache used by
150 cupsArrayDelete(mime
->srcs
);
157 * 'mimeDeleteType()' - Delete a type from the MIME database.
161 mimeDeleteType(mime_t
*mime
, /* I - MIME database */
162 mime_type_t
*mt
) /* I - Type */
167 cupsArrayRemove(mime
->types
, mt
);
169 delete_rules(mt
->rules
);
175 * 'mimeFirstFilter()' - Get the first filter in the MIME database.
178 mime_filter_t
* /* O - Filter or NULL */
179 mimeFirstFilter(mime_t
*mime
) /* I - MIME database */
184 return ((mime_filter_t
*)cupsArrayFirst(mime
->filters
));
189 * 'mimeFirstType()' - Get the first type in the MIME database.
192 mime_type_t
* /* O - Type or NULL */
193 mimeFirstType(mime_t
*mime
) /* I - MIME database */
198 return ((mime_type_t
*)cupsArrayFirst(mime
->types
));
203 * 'mimeLoad()' - Create a new MIME database from disk.
206 mime_t
* /* O - New MIME database */
207 mimeLoad(const char *pathname
, /* I - Directory to load */
208 const char *filterpath
) /* I - Directory to load */
210 return (mimeMerge(NULL
, pathname
, filterpath
));
215 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
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 */
223 cups_dir_t
*dir
; /* Directory */
224 cups_dentry_t
*dent
; /* Directory entry */
225 char filename
[1024]; /* Full filename of types/converts file */
226 cups_array_t
*filtercache
; /* Filter cache */
230 * First open the directory specified by pathname... Return NULL if nothing
231 * was read or if the pathname is NULL...
237 if ((dir
= cupsDirOpen(pathname
)) == NULL
)
241 * If "mime" is NULL, make a new, blank database...
250 * Read all the .types files...
253 while ((dent
= cupsDirRead(dir
)) != NULL
)
255 if (strlen(dent
->filename
) > 6 &&
256 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".types"))
259 * Load a mime.types file...
262 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
263 load_types(mime
, filename
);
270 * Read all the .convs files...
273 filtercache
= cupsArrayNew((cups_array_func_t
)compare_fcache
, NULL
);
275 while ((dent
= cupsDirRead(dir
)) != NULL
)
277 if (strlen(dent
->filename
) > 6 &&
278 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".convs"))
281 * Load a mime.convs file...
284 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
285 load_convs(mime
, filename
, filterpath
, filtercache
);
289 delete_fcache(filtercache
);
298 * 'mimeNew()' - Create a new, empty MIME database.
301 mime_t
* /* O - MIME database */
304 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
309 * 'mimeNextFilter()' - Get the next filter in the MIME database.
312 mime_filter_t
* /* O - Filter or NULL */
313 mimeNextFilter(mime_t
*mime
) /* I - MIME database */
318 return ((mime_filter_t
*)cupsArrayNext(mime
->filters
));
323 * 'mimeNextType()' - Get the next type in the MIME database.
326 mime_type_t
* /* O - Type or NULL */
327 mimeNextType(mime_t
*mime
) /* I - MIME database */
332 return ((mime_type_t
*)cupsArrayNext(mime
->types
));
337 * 'mimeNumFilters()' - Get the number of filters in a MIME database.
341 mimeNumFilters(mime_t
*mime
) /* I - MIME database */
346 return (cupsArrayCount(mime
->filters
));
351 * 'mimeNumTypes()' - Get the number of types in a MIME database.
355 mimeNumTypes(mime_t
*mime
) /* I - MIME database */
360 return (cupsArrayCount(mime
->types
));
365 * 'add_fcache()' - Add a filter to the filter cache.
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 */
373 _mime_fcache_t key
, /* Search key */
374 *temp
; /* New filter cache */
375 char path
[1024]; /* Full path to filter */
378 key
.name
= (char *)name
;
379 if ((temp
= (_mime_fcache_t
*)cupsArrayFind(filtercache
, &key
)) != NULL
)
382 if ((temp
= calloc(1, sizeof(_mime_fcache_t
))) == NULL
)
385 temp
->name
= strdup(name
);
387 if (cupsFileFind(name
, filterpath
, 1, path
, sizeof(path
)))
388 temp
->path
= strdup(path
);
390 cupsArrayAdd(filtercache
, temp
);
397 * 'compare_fcache()' - Compare two filter cache entries.
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 */
404 return (strcmp(a
->name
, b
->name
));
409 * 'delete_fcache()' - Free all memory used by the filter cache.
413 delete_fcache(cups_array_t
*filtercache
)/* I - Filter cache */
415 _mime_fcache_t
*current
; /* Current cache entry */
418 for (current
= (_mime_fcache_t
*)cupsArrayFirst(filtercache
);
420 current
= (_mime_fcache_t
*)cupsArrayNext(filtercache
))
430 cupsArrayDelete(filtercache
);
435 * 'delete_rules()' - Free all memory for the given rule tree.
439 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
441 mime_magic_t
*next
; /* Next rule to free */
445 * Free the rules list, descending recursively to free any child rules.
448 while (rules
!= NULL
)
452 if (rules
->child
!= NULL
)
453 delete_rules(rules
->child
);
462 * 'load_convs()' - Load a xyz.convs file...
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 */
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 */
478 mime_type_t
*temptype
, /* MIME type looping var */
479 *dsttype
; /* Destination MIME type */
480 int cost
; /* Cost of filter */
484 * First try to open the file...
487 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
490 DEBUG_printf(("\"%s\":\n", filename
));
493 * Then read each line from the file, skipping any comments in the file...
496 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
499 * Skip blank lines and lines starting with a #...
504 if (!line
[0] || line
[0] == '#')
508 * Strip trailing whitespace...
511 for (lineptr
= line
+ strlen(line
) - 1;
512 lineptr
>= line
&& isspace(*lineptr
& 255);
517 * Extract the destination super-type and type names from the middle of
522 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
525 while (*lineptr
== ' ' || *lineptr
== '\t')
530 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
531 (temp
- super
+ 1) < MIME_MAX_SUPER
)
532 *temp
++ = tolower(*lineptr
++ & 255);
542 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
543 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
544 *temp
++ = tolower(*lineptr
++ & 255);
548 if (*lineptr
== '\0' || *lineptr
== '\n')
551 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
553 DEBUG_printf((" Destination type %s/%s not found!\n", super
, type
));
558 * Then get the cost and filter program...
561 while (*lineptr
== ' ' || *lineptr
== '\t')
564 if (*lineptr
< '0' || *lineptr
> '9')
567 cost
= atoi(lineptr
);
569 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
571 while (*lineptr
== ' ' || *lineptr
== '\t')
574 if (*lineptr
== '\0' || *lineptr
== '\n')
579 if (strcmp(filter
, "-"))
582 * Verify that the filter exists and is executable...
585 if (!add_fcache(filtercache
, filter
, filterpath
))
587 DEBUG_printf((" Filter %s not found in %s!\n", filter
, filterpath
));
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...
600 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
601 (temp
- super
+ 1) < MIME_MAX_SUPER
)
602 *temp
++ = tolower(*lineptr
++ & 255);
612 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
613 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
614 *temp
++ = tolower(*lineptr
++ & 255);
618 if (!strcmp(super
, "*") && !strcmp(type
, "*"))
621 * Force * / * to be "application/octet-stream"...
624 strcpy(super
, "application");
625 strcpy(type
, "octet-stream");
629 * Add the filter to the MIME database, supporting wildcards as needed...
632 for (temptype
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
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
);
645 * 'load_types()' - Load a xyz.types file...
649 load_types(mime_t
*mime
, /* I - MIME database */
650 const char *filename
) /* I - Types file to load */
652 cups_file_t
*fp
; /* Types file */
653 int linelen
; /* Length of line */
654 char line
[32768], /* Input line from file */
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 */
663 * First try to open the file...
666 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
669 DEBUG_printf(("\"%s\":\n", filename
));
672 * Then read each line from the file, skipping any comments in the file...
675 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
678 * Skip blank lines and lines starting with a #...
683 if (!line
[0] || line
[0] == '#')
687 * While the last character in the line is a backslash, continue on to the
688 * next line (and the next, etc.)
691 linelen
= strlen(line
);
693 while (line
[linelen
- 1] == '\\')
697 if (cupsFileGets(fp
, line
+ linelen
, sizeof(line
) - linelen
) == NULL
)
698 line
[linelen
] = '\0';
700 linelen
+= strlen(line
+ linelen
);
704 * Extract the super-type and type names from the beginning of the line.
710 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
711 (temp
- super
+ 1) < MIME_MAX_SUPER
)
712 *temp
++ = tolower(*lineptr
++ & 255);
722 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
723 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
724 *temp
++ = tolower(*lineptr
++ & 255);
729 * Add the type and rules to the MIME database...
732 typeptr
= mimeAddType(mime
, super
, type
);
733 mimeAddTypeRule(typeptr
, lineptr
);
741 * End of "$Id: mime.c 181 2006-06-22 20:01:18Z jlovell $".