xref: /aosp_15_r20/external/libcups/scheduler/mime.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * MIME database file routines for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 1997-2006 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include <cups/string-private.h>
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/dir.h>
16*5e7646d2SAndroid Build Coastguard Worker #include "mime-private.h"
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker /*
20*5e7646d2SAndroid Build Coastguard Worker  * Debug macros that used to be private API...
21*5e7646d2SAndroid Build Coastguard Worker  */
22*5e7646d2SAndroid Build Coastguard Worker 
23*5e7646d2SAndroid Build Coastguard Worker #define DEBUG_puts(x)
24*5e7646d2SAndroid Build Coastguard Worker #define DEBUG_printf(...)
25*5e7646d2SAndroid Build Coastguard Worker 
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker  * Local types...
29*5e7646d2SAndroid Build Coastguard Worker  */
30*5e7646d2SAndroid Build Coastguard Worker 
31*5e7646d2SAndroid Build Coastguard Worker typedef struct _mime_fcache_s		/**** Filter cache structure ****/
32*5e7646d2SAndroid Build Coastguard Worker {
33*5e7646d2SAndroid Build Coastguard Worker   char	*name,				/* Filter name */
34*5e7646d2SAndroid Build Coastguard Worker 	*path;				/* Full path to filter if available */
35*5e7646d2SAndroid Build Coastguard Worker } _mime_fcache_t;
36*5e7646d2SAndroid Build Coastguard Worker 
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker /*
39*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
40*5e7646d2SAndroid Build Coastguard Worker  */
41*5e7646d2SAndroid Build Coastguard Worker 
42*5e7646d2SAndroid Build Coastguard Worker static const char *mime_add_fcache(cups_array_t *filtercache, const char *name,
43*5e7646d2SAndroid Build Coastguard Worker 		                   const char *filterpath);
44*5e7646d2SAndroid Build Coastguard Worker static int	mime_compare_fcache(_mime_fcache_t *a, _mime_fcache_t *b);
45*5e7646d2SAndroid Build Coastguard Worker static void	mime_delete_fcache(cups_array_t *filtercache);
46*5e7646d2SAndroid Build Coastguard Worker static void	mime_delete_rules(mime_magic_t *rules);
47*5e7646d2SAndroid Build Coastguard Worker static void	mime_load_convs(mime_t *mime, const char *filename,
48*5e7646d2SAndroid Build Coastguard Worker 		                const char *filterpath,
49*5e7646d2SAndroid Build Coastguard Worker 			        cups_array_t *filtercache);
50*5e7646d2SAndroid Build Coastguard Worker static void	mime_load_types(mime_t *mime, const char *filename);
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker /*
54*5e7646d2SAndroid Build Coastguard Worker  * 'mimeDelete()' - Delete (free) a MIME database.
55*5e7646d2SAndroid Build Coastguard Worker  */
56*5e7646d2SAndroid Build Coastguard Worker 
57*5e7646d2SAndroid Build Coastguard Worker void
mimeDelete(mime_t * mime)58*5e7646d2SAndroid Build Coastguard Worker mimeDelete(mime_t *mime)		/* I - MIME database */
59*5e7646d2SAndroid Build Coastguard Worker {
60*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*type;			/* Current type */
61*5e7646d2SAndroid Build Coastguard Worker   mime_filter_t	*filter;		/* Current filter */
62*5e7646d2SAndroid Build Coastguard Worker 
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeDelete(mime=%p)", mime));
65*5e7646d2SAndroid Build Coastguard Worker 
66*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
67*5e7646d2SAndroid Build Coastguard Worker     return;
68*5e7646d2SAndroid Build Coastguard Worker 
69*5e7646d2SAndroid Build Coastguard Worker  /*
70*5e7646d2SAndroid Build Coastguard Worker   * Loop through filters and free them...
71*5e7646d2SAndroid Build Coastguard Worker   */
72*5e7646d2SAndroid Build Coastguard Worker 
73*5e7646d2SAndroid Build Coastguard Worker   for (filter = (mime_filter_t *)cupsArrayFirst(mime->filters);
74*5e7646d2SAndroid Build Coastguard Worker        filter;
75*5e7646d2SAndroid Build Coastguard Worker        filter = (mime_filter_t *)cupsArrayNext(mime->filters))
76*5e7646d2SAndroid Build Coastguard Worker     mimeDeleteFilter(mime, filter);
77*5e7646d2SAndroid Build Coastguard Worker 
78*5e7646d2SAndroid Build Coastguard Worker  /*
79*5e7646d2SAndroid Build Coastguard Worker   * Loop through the file types and delete any rules...
80*5e7646d2SAndroid Build Coastguard Worker   */
81*5e7646d2SAndroid Build Coastguard Worker 
82*5e7646d2SAndroid Build Coastguard Worker   for (type = (mime_type_t *)cupsArrayFirst(mime->types);
83*5e7646d2SAndroid Build Coastguard Worker        type;
84*5e7646d2SAndroid Build Coastguard Worker        type = (mime_type_t *)cupsArrayNext(mime->types))
85*5e7646d2SAndroid Build Coastguard Worker     mimeDeleteType(mime, type);
86*5e7646d2SAndroid Build Coastguard Worker 
87*5e7646d2SAndroid Build Coastguard Worker  /*
88*5e7646d2SAndroid Build Coastguard Worker   * Free the types and filters arrays, and then the MIME database structure.
89*5e7646d2SAndroid Build Coastguard Worker   */
90*5e7646d2SAndroid Build Coastguard Worker 
91*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(mime->types);
92*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(mime->filters);
93*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(mime->srcs);
94*5e7646d2SAndroid Build Coastguard Worker   free(mime);
95*5e7646d2SAndroid Build Coastguard Worker }
96*5e7646d2SAndroid Build Coastguard Worker 
97*5e7646d2SAndroid Build Coastguard Worker 
98*5e7646d2SAndroid Build Coastguard Worker /*
99*5e7646d2SAndroid Build Coastguard Worker  * 'mimeDeleteFilter()' - Delete a filter from the MIME database.
100*5e7646d2SAndroid Build Coastguard Worker  */
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker void
mimeDeleteFilter(mime_t * mime,mime_filter_t * filter)103*5e7646d2SAndroid Build Coastguard Worker mimeDeleteFilter(mime_t        *mime,	/* I - MIME database */
104*5e7646d2SAndroid Build Coastguard Worker 		 mime_filter_t *filter)	/* I - Filter */
105*5e7646d2SAndroid Build Coastguard Worker {
106*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeDeleteFilter(mime=%p, filter=%p(%s/%s->%s/%s, cost=%d, "
107*5e7646d2SAndroid Build Coastguard Worker                 "maxsize=" CUPS_LLFMT "))", mime, filter,
108*5e7646d2SAndroid Build Coastguard Worker 		filter ? filter->src->super : "???",
109*5e7646d2SAndroid Build Coastguard Worker 		filter ? filter->src->type : "???",
110*5e7646d2SAndroid Build Coastguard Worker 		filter ? filter->dst->super : "???",
111*5e7646d2SAndroid Build Coastguard Worker 		filter ? filter->dst->super : "???",
112*5e7646d2SAndroid Build Coastguard Worker 		filter ? filter->cost : -1,
113*5e7646d2SAndroid Build Coastguard Worker 		filter ? CUPS_LLCAST filter->maxsize : CUPS_LLCAST -1));
114*5e7646d2SAndroid Build Coastguard Worker 
115*5e7646d2SAndroid Build Coastguard Worker   if (!mime || !filter)
116*5e7646d2SAndroid Build Coastguard Worker     return;
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
119*5e7646d2SAndroid Build Coastguard Worker   if (!cupsArrayFind(mime->filters, filter))
120*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeDeleteFilter: Filter not in MIME database.");
121*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRemove(mime->filters, filter);
124*5e7646d2SAndroid Build Coastguard Worker   free(filter);
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker  /*
127*5e7646d2SAndroid Build Coastguard Worker   * Deleting a filter invalidates the source lookup cache used by
128*5e7646d2SAndroid Build Coastguard Worker   * mimeFilter()...
129*5e7646d2SAndroid Build Coastguard Worker   */
130*5e7646d2SAndroid Build Coastguard Worker 
131*5e7646d2SAndroid Build Coastguard Worker   if (mime->srcs)
132*5e7646d2SAndroid Build Coastguard Worker   {
133*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeDeleteFilter: Deleting source lookup cache.");
134*5e7646d2SAndroid Build Coastguard Worker     cupsArrayDelete(mime->srcs);
135*5e7646d2SAndroid Build Coastguard Worker     mime->srcs = NULL;
136*5e7646d2SAndroid Build Coastguard Worker   }
137*5e7646d2SAndroid Build Coastguard Worker }
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker 
140*5e7646d2SAndroid Build Coastguard Worker /*
141*5e7646d2SAndroid Build Coastguard Worker  * 'mimeDeleteType()' - Delete a type from the MIME database.
142*5e7646d2SAndroid Build Coastguard Worker  */
143*5e7646d2SAndroid Build Coastguard Worker 
144*5e7646d2SAndroid Build Coastguard Worker void
mimeDeleteType(mime_t * mime,mime_type_t * mt)145*5e7646d2SAndroid Build Coastguard Worker mimeDeleteType(mime_t      *mime,	/* I - MIME database */
146*5e7646d2SAndroid Build Coastguard Worker 	       mime_type_t *mt)		/* I - Type */
147*5e7646d2SAndroid Build Coastguard Worker {
148*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeDeleteType(mime=%p, mt=%p(%s/%s))", mime, mt,
149*5e7646d2SAndroid Build Coastguard Worker                 mt ? mt->super : "???", mt ? mt->type : "???"));
150*5e7646d2SAndroid Build Coastguard Worker 
151*5e7646d2SAndroid Build Coastguard Worker   if (!mime || !mt)
152*5e7646d2SAndroid Build Coastguard Worker     return;
153*5e7646d2SAndroid Build Coastguard Worker 
154*5e7646d2SAndroid Build Coastguard Worker #ifdef DEBUG
155*5e7646d2SAndroid Build Coastguard Worker   if (!cupsArrayFind(mime->types, mt))
156*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeDeleteFilter: Type not in MIME database.");
157*5e7646d2SAndroid Build Coastguard Worker #endif /* DEBUG */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRemove(mime->types, mt);
160*5e7646d2SAndroid Build Coastguard Worker 
161*5e7646d2SAndroid Build Coastguard Worker   mime_delete_rules(mt->rules);
162*5e7646d2SAndroid Build Coastguard Worker   free(mt);
163*5e7646d2SAndroid Build Coastguard Worker }
164*5e7646d2SAndroid Build Coastguard Worker 
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker /*
167*5e7646d2SAndroid Build Coastguard Worker  * '_mimeError()' - Show an error message.
168*5e7646d2SAndroid Build Coastguard Worker  */
169*5e7646d2SAndroid Build Coastguard Worker 
170*5e7646d2SAndroid Build Coastguard Worker void
_mimeError(mime_t * mime,const char * message,...)171*5e7646d2SAndroid Build Coastguard Worker _mimeError(mime_t     *mime,		/* I - MIME database */
172*5e7646d2SAndroid Build Coastguard Worker            const char *message,		/* I - Printf-style message string */
173*5e7646d2SAndroid Build Coastguard Worker 	   ...)				/* I - Additional arguments as needed */
174*5e7646d2SAndroid Build Coastguard Worker {
175*5e7646d2SAndroid Build Coastguard Worker   va_list	ap;			/* Argument pointer */
176*5e7646d2SAndroid Build Coastguard Worker   char		buffer[8192];		/* Message buffer */
177*5e7646d2SAndroid Build Coastguard Worker 
178*5e7646d2SAndroid Build Coastguard Worker 
179*5e7646d2SAndroid Build Coastguard Worker   if (mime->error_cb)
180*5e7646d2SAndroid Build Coastguard Worker   {
181*5e7646d2SAndroid Build Coastguard Worker     va_start(ap, message);
182*5e7646d2SAndroid Build Coastguard Worker     vsnprintf(buffer, sizeof(buffer), message, ap);
183*5e7646d2SAndroid Build Coastguard Worker     va_end(ap);
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker     (*mime->error_cb)(mime->error_ctx, buffer);
186*5e7646d2SAndroid Build Coastguard Worker   }
187*5e7646d2SAndroid Build Coastguard Worker }
188*5e7646d2SAndroid Build Coastguard Worker 
189*5e7646d2SAndroid Build Coastguard Worker 
190*5e7646d2SAndroid Build Coastguard Worker /*
191*5e7646d2SAndroid Build Coastguard Worker  * 'mimeFirstFilter()' - Get the first filter in the MIME database.
192*5e7646d2SAndroid Build Coastguard Worker  */
193*5e7646d2SAndroid Build Coastguard Worker 
194*5e7646d2SAndroid Build Coastguard Worker mime_filter_t *				/* O - Filter or NULL */
mimeFirstFilter(mime_t * mime)195*5e7646d2SAndroid Build Coastguard Worker mimeFirstFilter(mime_t *mime)		/* I - MIME database */
196*5e7646d2SAndroid Build Coastguard Worker {
197*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("6mimeFirstFilter(mime=%p)", mime));
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
200*5e7646d2SAndroid Build Coastguard Worker   {
201*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("7mimeFirstFilter: Returning NULL.");
202*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
203*5e7646d2SAndroid Build Coastguard Worker   }
204*5e7646d2SAndroid Build Coastguard Worker   else
205*5e7646d2SAndroid Build Coastguard Worker   {
206*5e7646d2SAndroid Build Coastguard Worker     mime_filter_t *first = (mime_filter_t *)cupsArrayFirst(mime->filters);
207*5e7646d2SAndroid Build Coastguard Worker 					/* First filter */
208*5e7646d2SAndroid Build Coastguard Worker 
209*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("7mimeFirstFilter: Returning %p.", first));
210*5e7646d2SAndroid Build Coastguard Worker     return (first);
211*5e7646d2SAndroid Build Coastguard Worker   }
212*5e7646d2SAndroid Build Coastguard Worker }
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker /*
216*5e7646d2SAndroid Build Coastguard Worker  * 'mimeFirstType()' - Get the first type in the MIME database.
217*5e7646d2SAndroid Build Coastguard Worker  */
218*5e7646d2SAndroid Build Coastguard Worker 
219*5e7646d2SAndroid Build Coastguard Worker mime_type_t *				/* O - Type or NULL */
mimeFirstType(mime_t * mime)220*5e7646d2SAndroid Build Coastguard Worker mimeFirstType(mime_t *mime)		/* I - MIME database */
221*5e7646d2SAndroid Build Coastguard Worker {
222*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("6mimeFirstType(mime=%p)", mime));
223*5e7646d2SAndroid Build Coastguard Worker 
224*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
225*5e7646d2SAndroid Build Coastguard Worker   {
226*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("7mimeFirstType: Returning NULL.");
227*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
228*5e7646d2SAndroid Build Coastguard Worker   }
229*5e7646d2SAndroid Build Coastguard Worker   else
230*5e7646d2SAndroid Build Coastguard Worker   {
231*5e7646d2SAndroid Build Coastguard Worker     mime_type_t *first = (mime_type_t *)cupsArrayFirst(mime->types);
232*5e7646d2SAndroid Build Coastguard Worker 					/* First type */
233*5e7646d2SAndroid Build Coastguard Worker 
234*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("7mimeFirstType: Returning %p.", first));
235*5e7646d2SAndroid Build Coastguard Worker     return (first);
236*5e7646d2SAndroid Build Coastguard Worker   }
237*5e7646d2SAndroid Build Coastguard Worker }
238*5e7646d2SAndroid Build Coastguard Worker 
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker /*
241*5e7646d2SAndroid Build Coastguard Worker  * 'mimeLoad()' - Create a new MIME database from disk.
242*5e7646d2SAndroid Build Coastguard Worker  *
243*5e7646d2SAndroid Build Coastguard Worker  * This function uses @link mimeLoadFilters@ and @link mimeLoadTypes@ to
244*5e7646d2SAndroid Build Coastguard Worker  * create a MIME database from a single directory.
245*5e7646d2SAndroid Build Coastguard Worker  */
246*5e7646d2SAndroid Build Coastguard Worker 
247*5e7646d2SAndroid Build Coastguard Worker mime_t *				/* O - New MIME database */
mimeLoad(const char * pathname,const char * filterpath)248*5e7646d2SAndroid Build Coastguard Worker mimeLoad(const char *pathname,		/* I - Directory to load */
249*5e7646d2SAndroid Build Coastguard Worker          const char *filterpath)	/* I - Directory to load */
250*5e7646d2SAndroid Build Coastguard Worker {
251*5e7646d2SAndroid Build Coastguard Worker   mime_t *mime;				/* New MIME database */
252*5e7646d2SAndroid Build Coastguard Worker 
253*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeLoad(pathname=\"%s\", filterpath=\"%s\")", pathname,
254*5e7646d2SAndroid Build Coastguard Worker                 filterpath));
255*5e7646d2SAndroid Build Coastguard Worker 
256*5e7646d2SAndroid Build Coastguard Worker   mime = mimeLoadFilters(mimeLoadTypes(NULL, pathname), pathname, filterpath);
257*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("1mimeLoad: Returning %p.", mime));
258*5e7646d2SAndroid Build Coastguard Worker 
259*5e7646d2SAndroid Build Coastguard Worker   return (mime);
260*5e7646d2SAndroid Build Coastguard Worker }
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker 
263*5e7646d2SAndroid Build Coastguard Worker /*
264*5e7646d2SAndroid Build Coastguard Worker  * 'mimeLoadFilters()' - Load filter definitions from disk.
265*5e7646d2SAndroid Build Coastguard Worker  *
266*5e7646d2SAndroid Build Coastguard Worker  * This function loads all of the .convs files from the specified directory.
267*5e7646d2SAndroid Build Coastguard Worker  * Use @link mimeLoadTypes@ to load all types before you load the filters.
268*5e7646d2SAndroid Build Coastguard Worker  */
269*5e7646d2SAndroid Build Coastguard Worker 
270*5e7646d2SAndroid Build Coastguard Worker mime_t *				/* O - MIME database */
mimeLoadFilters(mime_t * mime,const char * pathname,const char * filterpath)271*5e7646d2SAndroid Build Coastguard Worker mimeLoadFilters(mime_t     *mime,	/* I - MIME database */
272*5e7646d2SAndroid Build Coastguard Worker                 const char *pathname,	/* I - Directory to load from */
273*5e7646d2SAndroid Build Coastguard Worker                 const char *filterpath)	/* I - Default filter program directory */
274*5e7646d2SAndroid Build Coastguard Worker {
275*5e7646d2SAndroid Build Coastguard Worker   cups_dir_t	*dir;			/* Directory */
276*5e7646d2SAndroid Build Coastguard Worker   cups_dentry_t	*dent;			/* Directory entry */
277*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024];		/* Full filename of .convs file */
278*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*filtercache;		/* Filter cache */
279*5e7646d2SAndroid Build Coastguard Worker 
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeLoadFilters(mime=%p, pathname=\"%s\", filterpath=\"%s\")",
282*5e7646d2SAndroid Build Coastguard Worker 		mime, pathname, filterpath));
283*5e7646d2SAndroid Build Coastguard Worker 
284*5e7646d2SAndroid Build Coastguard Worker  /*
285*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
286*5e7646d2SAndroid Build Coastguard Worker   */
287*5e7646d2SAndroid Build Coastguard Worker 
288*5e7646d2SAndroid Build Coastguard Worker   if (!mime || !pathname || !filterpath)
289*5e7646d2SAndroid Build Coastguard Worker   {
290*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeLoadFilters: Bad arguments.");
291*5e7646d2SAndroid Build Coastguard Worker     return (mime);
292*5e7646d2SAndroid Build Coastguard Worker   }
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker  /*
295*5e7646d2SAndroid Build Coastguard Worker   * Then open the directory specified by pathname...
296*5e7646d2SAndroid Build Coastguard Worker   */
297*5e7646d2SAndroid Build Coastguard Worker 
298*5e7646d2SAndroid Build Coastguard Worker   if ((dir = cupsDirOpen(pathname)) == NULL)
299*5e7646d2SAndroid Build Coastguard Worker   {
300*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("1mimeLoadFilters: Unable to open \"%s\": %s", pathname,
301*5e7646d2SAndroid Build Coastguard Worker                   strerror(errno)));
302*5e7646d2SAndroid Build Coastguard Worker     _mimeError(mime, "Unable to open \"%s\": %s", pathname, strerror(errno));
303*5e7646d2SAndroid Build Coastguard Worker     return (mime);
304*5e7646d2SAndroid Build Coastguard Worker   }
305*5e7646d2SAndroid Build Coastguard Worker 
306*5e7646d2SAndroid Build Coastguard Worker  /*
307*5e7646d2SAndroid Build Coastguard Worker   * Read all the .convs files...
308*5e7646d2SAndroid Build Coastguard Worker   */
309*5e7646d2SAndroid Build Coastguard Worker 
310*5e7646d2SAndroid Build Coastguard Worker   filtercache = cupsArrayNew((cups_array_func_t)mime_compare_fcache, NULL);
311*5e7646d2SAndroid Build Coastguard Worker 
312*5e7646d2SAndroid Build Coastguard Worker   while ((dent = cupsDirRead(dir)) != NULL)
313*5e7646d2SAndroid Build Coastguard Worker   {
314*5e7646d2SAndroid Build Coastguard Worker     if (strlen(dent->filename) > 6 &&
315*5e7646d2SAndroid Build Coastguard Worker         !strcmp(dent->filename + strlen(dent->filename) - 6, ".convs"))
316*5e7646d2SAndroid Build Coastguard Worker     {
317*5e7646d2SAndroid Build Coastguard Worker      /*
318*5e7646d2SAndroid Build Coastguard Worker       * Load a mime.convs file...
319*5e7646d2SAndroid Build Coastguard Worker       */
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename);
322*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("1mimeLoadFilters: Loading \"%s\".", filename));
323*5e7646d2SAndroid Build Coastguard Worker       mime_load_convs(mime, filename, filterpath, filtercache);
324*5e7646d2SAndroid Build Coastguard Worker     }
325*5e7646d2SAndroid Build Coastguard Worker   }
326*5e7646d2SAndroid Build Coastguard Worker 
327*5e7646d2SAndroid Build Coastguard Worker   mime_delete_fcache(filtercache);
328*5e7646d2SAndroid Build Coastguard Worker 
329*5e7646d2SAndroid Build Coastguard Worker   cupsDirClose(dir);
330*5e7646d2SAndroid Build Coastguard Worker 
331*5e7646d2SAndroid Build Coastguard Worker   return (mime);
332*5e7646d2SAndroid Build Coastguard Worker }
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker 
335*5e7646d2SAndroid Build Coastguard Worker /*
336*5e7646d2SAndroid Build Coastguard Worker  * 'mimeLoadTypes()' - Load type definitions from disk.
337*5e7646d2SAndroid Build Coastguard Worker  *
338*5e7646d2SAndroid Build Coastguard Worker  * This function loads all of the .types files from the specified directory.
339*5e7646d2SAndroid Build Coastguard Worker  * Use @link mimeLoadFilters@ to load all filters after you load the types.
340*5e7646d2SAndroid Build Coastguard Worker  */
341*5e7646d2SAndroid Build Coastguard Worker 
342*5e7646d2SAndroid Build Coastguard Worker mime_t *				/* O - MIME database */
mimeLoadTypes(mime_t * mime,const char * pathname)343*5e7646d2SAndroid Build Coastguard Worker mimeLoadTypes(mime_t     *mime,		/* I - MIME database or @code NULL@ to create a new one */
344*5e7646d2SAndroid Build Coastguard Worker               const char *pathname)	/* I - Directory to load from */
345*5e7646d2SAndroid Build Coastguard Worker {
346*5e7646d2SAndroid Build Coastguard Worker   cups_dir_t	*dir;			/* Directory */
347*5e7646d2SAndroid Build Coastguard Worker   cups_dentry_t	*dent;			/* Directory entry */
348*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024];		/* Full filename of .types file */
349*5e7646d2SAndroid Build Coastguard Worker 
350*5e7646d2SAndroid Build Coastguard Worker 
351*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeLoadTypes(mime=%p, pathname=\"%s\")", mime, pathname));
352*5e7646d2SAndroid Build Coastguard Worker 
353*5e7646d2SAndroid Build Coastguard Worker  /*
354*5e7646d2SAndroid Build Coastguard Worker   * First open the directory specified by pathname...
355*5e7646d2SAndroid Build Coastguard Worker   */
356*5e7646d2SAndroid Build Coastguard Worker 
357*5e7646d2SAndroid Build Coastguard Worker   if ((dir = cupsDirOpen(pathname)) == NULL)
358*5e7646d2SAndroid Build Coastguard Worker   {
359*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("1mimeLoadTypes: Unable to open \"%s\": %s", pathname,
360*5e7646d2SAndroid Build Coastguard Worker                   strerror(errno)));
361*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("1mimeLoadTypes: Returning %p.", mime));
362*5e7646d2SAndroid Build Coastguard Worker     _mimeError(mime, "Unable to open \"%s\": %s", pathname, strerror(errno));
363*5e7646d2SAndroid Build Coastguard Worker     return (mime);
364*5e7646d2SAndroid Build Coastguard Worker   }
365*5e7646d2SAndroid Build Coastguard Worker 
366*5e7646d2SAndroid Build Coastguard Worker  /*
367*5e7646d2SAndroid Build Coastguard Worker   * If "mime" is NULL, make a new, empty database...
368*5e7646d2SAndroid Build Coastguard Worker   */
369*5e7646d2SAndroid Build Coastguard Worker 
370*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
371*5e7646d2SAndroid Build Coastguard Worker     mime = mimeNew();
372*5e7646d2SAndroid Build Coastguard Worker 
373*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
374*5e7646d2SAndroid Build Coastguard Worker   {
375*5e7646d2SAndroid Build Coastguard Worker     cupsDirClose(dir);
376*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeLoadTypes: Returning NULL.");
377*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
378*5e7646d2SAndroid Build Coastguard Worker   }
379*5e7646d2SAndroid Build Coastguard Worker 
380*5e7646d2SAndroid Build Coastguard Worker  /*
381*5e7646d2SAndroid Build Coastguard Worker   * Read all the .types files...
382*5e7646d2SAndroid Build Coastguard Worker   */
383*5e7646d2SAndroid Build Coastguard Worker 
384*5e7646d2SAndroid Build Coastguard Worker   while ((dent = cupsDirRead(dir)) != NULL)
385*5e7646d2SAndroid Build Coastguard Worker   {
386*5e7646d2SAndroid Build Coastguard Worker     if (strlen(dent->filename) > 6 &&
387*5e7646d2SAndroid Build Coastguard Worker         !strcmp(dent->filename + strlen(dent->filename) - 6, ".types"))
388*5e7646d2SAndroid Build Coastguard Worker     {
389*5e7646d2SAndroid Build Coastguard Worker      /*
390*5e7646d2SAndroid Build Coastguard Worker       * Load a mime.types file...
391*5e7646d2SAndroid Build Coastguard Worker       */
392*5e7646d2SAndroid Build Coastguard Worker 
393*5e7646d2SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename);
394*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("1mimeLoadTypes: Loading \"%s\".", filename));
395*5e7646d2SAndroid Build Coastguard Worker       mime_load_types(mime, filename);
396*5e7646d2SAndroid Build Coastguard Worker     }
397*5e7646d2SAndroid Build Coastguard Worker   }
398*5e7646d2SAndroid Build Coastguard Worker 
399*5e7646d2SAndroid Build Coastguard Worker   cupsDirClose(dir);
400*5e7646d2SAndroid Build Coastguard Worker 
401*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("1mimeLoadTypes: Returning %p.", mime));
402*5e7646d2SAndroid Build Coastguard Worker 
403*5e7646d2SAndroid Build Coastguard Worker   return (mime);
404*5e7646d2SAndroid Build Coastguard Worker }
405*5e7646d2SAndroid Build Coastguard Worker 
406*5e7646d2SAndroid Build Coastguard Worker 
407*5e7646d2SAndroid Build Coastguard Worker /*
408*5e7646d2SAndroid Build Coastguard Worker  * 'mimeNew()' - Create a new, empty MIME database.
409*5e7646d2SAndroid Build Coastguard Worker  */
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker mime_t *				/* O - MIME database */
mimeNew(void)412*5e7646d2SAndroid Build Coastguard Worker mimeNew(void)
413*5e7646d2SAndroid Build Coastguard Worker {
414*5e7646d2SAndroid Build Coastguard Worker   return ((mime_t *)calloc(1, sizeof(mime_t)));
415*5e7646d2SAndroid Build Coastguard Worker }
416*5e7646d2SAndroid Build Coastguard Worker 
417*5e7646d2SAndroid Build Coastguard Worker 
418*5e7646d2SAndroid Build Coastguard Worker /*
419*5e7646d2SAndroid Build Coastguard Worker  * 'mimeNextFilter()' - Get the next filter in the MIME database.
420*5e7646d2SAndroid Build Coastguard Worker  */
421*5e7646d2SAndroid Build Coastguard Worker 
422*5e7646d2SAndroid Build Coastguard Worker mime_filter_t *				/* O - Filter or NULL */
mimeNextFilter(mime_t * mime)423*5e7646d2SAndroid Build Coastguard Worker mimeNextFilter(mime_t *mime)		/* I - MIME database */
424*5e7646d2SAndroid Build Coastguard Worker {
425*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("6mimeNextFilter(mime=%p)", mime));
426*5e7646d2SAndroid Build Coastguard Worker 
427*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
428*5e7646d2SAndroid Build Coastguard Worker   {
429*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("7mimeNextFilter: Returning NULL.");
430*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
431*5e7646d2SAndroid Build Coastguard Worker   }
432*5e7646d2SAndroid Build Coastguard Worker   else
433*5e7646d2SAndroid Build Coastguard Worker   {
434*5e7646d2SAndroid Build Coastguard Worker     mime_filter_t *next = (mime_filter_t *)cupsArrayNext(mime->filters);
435*5e7646d2SAndroid Build Coastguard Worker 					/* Next filter */
436*5e7646d2SAndroid Build Coastguard Worker 
437*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("7mimeNextFilter: Returning %p.", next));
438*5e7646d2SAndroid Build Coastguard Worker     return (next);
439*5e7646d2SAndroid Build Coastguard Worker   }
440*5e7646d2SAndroid Build Coastguard Worker }
441*5e7646d2SAndroid Build Coastguard Worker 
442*5e7646d2SAndroid Build Coastguard Worker 
443*5e7646d2SAndroid Build Coastguard Worker /*
444*5e7646d2SAndroid Build Coastguard Worker  * 'mimeNextType()' - Get the next type in the MIME database.
445*5e7646d2SAndroid Build Coastguard Worker  */
446*5e7646d2SAndroid Build Coastguard Worker 
447*5e7646d2SAndroid Build Coastguard Worker mime_type_t *				/* O - Type or NULL */
mimeNextType(mime_t * mime)448*5e7646d2SAndroid Build Coastguard Worker mimeNextType(mime_t *mime)		/* I - MIME database */
449*5e7646d2SAndroid Build Coastguard Worker {
450*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("6mimeNextType(mime=%p)", mime));
451*5e7646d2SAndroid Build Coastguard Worker 
452*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
453*5e7646d2SAndroid Build Coastguard Worker   {
454*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("7mimeNextType: Returning NULL.");
455*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
456*5e7646d2SAndroid Build Coastguard Worker   }
457*5e7646d2SAndroid Build Coastguard Worker   else
458*5e7646d2SAndroid Build Coastguard Worker   {
459*5e7646d2SAndroid Build Coastguard Worker     mime_type_t *next = (mime_type_t *)cupsArrayNext(mime->types);
460*5e7646d2SAndroid Build Coastguard Worker 					/* Next type */
461*5e7646d2SAndroid Build Coastguard Worker 
462*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("7mimeNextType: Returning %p.", next));
463*5e7646d2SAndroid Build Coastguard Worker     return (next);
464*5e7646d2SAndroid Build Coastguard Worker   }
465*5e7646d2SAndroid Build Coastguard Worker }
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker 
468*5e7646d2SAndroid Build Coastguard Worker /*
469*5e7646d2SAndroid Build Coastguard Worker  * 'mimeNumFilters()' - Get the number of filters in a MIME database.
470*5e7646d2SAndroid Build Coastguard Worker  */
471*5e7646d2SAndroid Build Coastguard Worker 
472*5e7646d2SAndroid Build Coastguard Worker int
mimeNumFilters(mime_t * mime)473*5e7646d2SAndroid Build Coastguard Worker mimeNumFilters(mime_t *mime)		/* I - MIME database */
474*5e7646d2SAndroid Build Coastguard Worker {
475*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeNumFilters(mime=%p)", mime));
476*5e7646d2SAndroid Build Coastguard Worker 
477*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
478*5e7646d2SAndroid Build Coastguard Worker   {
479*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeNumFilters: Returning 0.");
480*5e7646d2SAndroid Build Coastguard Worker     return (0);
481*5e7646d2SAndroid Build Coastguard Worker   }
482*5e7646d2SAndroid Build Coastguard Worker   else
483*5e7646d2SAndroid Build Coastguard Worker   {
484*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("1mimeNumFilters: Returning %d.",
485*5e7646d2SAndroid Build Coastguard Worker                   cupsArrayCount(mime->filters)));
486*5e7646d2SAndroid Build Coastguard Worker     return (cupsArrayCount(mime->filters));
487*5e7646d2SAndroid Build Coastguard Worker   }
488*5e7646d2SAndroid Build Coastguard Worker }
489*5e7646d2SAndroid Build Coastguard Worker 
490*5e7646d2SAndroid Build Coastguard Worker 
491*5e7646d2SAndroid Build Coastguard Worker /*
492*5e7646d2SAndroid Build Coastguard Worker  * 'mimeNumTypes()' - Get the number of types in a MIME database.
493*5e7646d2SAndroid Build Coastguard Worker  */
494*5e7646d2SAndroid Build Coastguard Worker 
495*5e7646d2SAndroid Build Coastguard Worker int
mimeNumTypes(mime_t * mime)496*5e7646d2SAndroid Build Coastguard Worker mimeNumTypes(mime_t *mime)		/* I - MIME database */
497*5e7646d2SAndroid Build Coastguard Worker {
498*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("mimeNumTypes(mime=%p)", mime));
499*5e7646d2SAndroid Build Coastguard Worker 
500*5e7646d2SAndroid Build Coastguard Worker   if (!mime)
501*5e7646d2SAndroid Build Coastguard Worker   {
502*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("1mimeNumTypes: Returning 0.");
503*5e7646d2SAndroid Build Coastguard Worker     return (0);
504*5e7646d2SAndroid Build Coastguard Worker   }
505*5e7646d2SAndroid Build Coastguard Worker   else
506*5e7646d2SAndroid Build Coastguard Worker   {
507*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("1mimeNumTypes: Returning %d.",
508*5e7646d2SAndroid Build Coastguard Worker                   cupsArrayCount(mime->types)));
509*5e7646d2SAndroid Build Coastguard Worker     return (cupsArrayCount(mime->types));
510*5e7646d2SAndroid Build Coastguard Worker   }
511*5e7646d2SAndroid Build Coastguard Worker }
512*5e7646d2SAndroid Build Coastguard Worker 
513*5e7646d2SAndroid Build Coastguard Worker 
514*5e7646d2SAndroid Build Coastguard Worker /*
515*5e7646d2SAndroid Build Coastguard Worker  * 'mimeSetErrorCallback()' - Set the callback for error messages.
516*5e7646d2SAndroid Build Coastguard Worker  */
517*5e7646d2SAndroid Build Coastguard Worker 
518*5e7646d2SAndroid Build Coastguard Worker void
mimeSetErrorCallback(mime_t * mime,mime_error_cb_t cb,void * ctx)519*5e7646d2SAndroid Build Coastguard Worker mimeSetErrorCallback(
520*5e7646d2SAndroid Build Coastguard Worker     mime_t          *mime,		/* I - MIME database */
521*5e7646d2SAndroid Build Coastguard Worker     mime_error_cb_t cb,			/* I - Callback function */
522*5e7646d2SAndroid Build Coastguard Worker     void            *ctx)		/* I - Context pointer for callback */
523*5e7646d2SAndroid Build Coastguard Worker {
524*5e7646d2SAndroid Build Coastguard Worker   if (mime)
525*5e7646d2SAndroid Build Coastguard Worker   {
526*5e7646d2SAndroid Build Coastguard Worker     mime->error_cb  = cb;
527*5e7646d2SAndroid Build Coastguard Worker     mime->error_ctx = ctx;
528*5e7646d2SAndroid Build Coastguard Worker   }
529*5e7646d2SAndroid Build Coastguard Worker }
530*5e7646d2SAndroid Build Coastguard Worker 
531*5e7646d2SAndroid Build Coastguard Worker 
532*5e7646d2SAndroid Build Coastguard Worker /*
533*5e7646d2SAndroid Build Coastguard Worker  * 'mime_add_fcache()' - Add a filter to the filter cache.
534*5e7646d2SAndroid Build Coastguard Worker  */
535*5e7646d2SAndroid Build Coastguard Worker 
536*5e7646d2SAndroid Build Coastguard Worker static const char *			/* O - Full path to filter or NULL */
mime_add_fcache(cups_array_t * filtercache,const char * name,const char * filterpath)537*5e7646d2SAndroid Build Coastguard Worker mime_add_fcache(
538*5e7646d2SAndroid Build Coastguard Worker     cups_array_t *filtercache,		/* I - Filter cache */
539*5e7646d2SAndroid Build Coastguard Worker     const char   *name,			/* I - Filter name */
540*5e7646d2SAndroid Build Coastguard Worker     const char   *filterpath)		/* I - Filter path */
541*5e7646d2SAndroid Build Coastguard Worker {
542*5e7646d2SAndroid Build Coastguard Worker   _mime_fcache_t	key,		/* Search key */
543*5e7646d2SAndroid Build Coastguard Worker 			*temp;		/* New filter cache */
544*5e7646d2SAndroid Build Coastguard Worker   char			path[1024];	/* Full path to filter */
545*5e7646d2SAndroid Build Coastguard Worker 
546*5e7646d2SAndroid Build Coastguard Worker 
547*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2mime_add_fcache(filtercache=%p, name=\"%s\", "
548*5e7646d2SAndroid Build Coastguard Worker                 "filterpath=\"%s\")", filtercache, name, filterpath));
549*5e7646d2SAndroid Build Coastguard Worker 
550*5e7646d2SAndroid Build Coastguard Worker   key.name = (char *)name;
551*5e7646d2SAndroid Build Coastguard Worker   if ((temp = (_mime_fcache_t *)cupsArrayFind(filtercache, &key)) != NULL)
552*5e7646d2SAndroid Build Coastguard Worker   {
553*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("3mime_add_fcache: Returning \"%s\".", temp->path));
554*5e7646d2SAndroid Build Coastguard Worker     return (temp->path);
555*5e7646d2SAndroid Build Coastguard Worker   }
556*5e7646d2SAndroid Build Coastguard Worker 
557*5e7646d2SAndroid Build Coastguard Worker   if ((temp = calloc(1, sizeof(_mime_fcache_t))) == NULL)
558*5e7646d2SAndroid Build Coastguard Worker   {
559*5e7646d2SAndroid Build Coastguard Worker     DEBUG_puts("3mime_add_fcache: Returning NULL.");
560*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
561*5e7646d2SAndroid Build Coastguard Worker   }
562*5e7646d2SAndroid Build Coastguard Worker 
563*5e7646d2SAndroid Build Coastguard Worker   temp->name = strdup(name);
564*5e7646d2SAndroid Build Coastguard Worker 
565*5e7646d2SAndroid Build Coastguard Worker   if (cupsFileFind(name, filterpath, 1, path, sizeof(path)))
566*5e7646d2SAndroid Build Coastguard Worker     temp->path = strdup(path);
567*5e7646d2SAndroid Build Coastguard Worker 
568*5e7646d2SAndroid Build Coastguard Worker   cupsArrayAdd(filtercache, temp);
569*5e7646d2SAndroid Build Coastguard Worker 
570*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("3mime_add_fcache: Returning \"%s\".", temp->path));
571*5e7646d2SAndroid Build Coastguard Worker   return (temp->path);
572*5e7646d2SAndroid Build Coastguard Worker }
573*5e7646d2SAndroid Build Coastguard Worker 
574*5e7646d2SAndroid Build Coastguard Worker 
575*5e7646d2SAndroid Build Coastguard Worker /*
576*5e7646d2SAndroid Build Coastguard Worker  * 'mime_compare_fcache()' - Compare two filter cache entries.
577*5e7646d2SAndroid Build Coastguard Worker  */
578*5e7646d2SAndroid Build Coastguard Worker 
579*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
mime_compare_fcache(_mime_fcache_t * a,_mime_fcache_t * b)580*5e7646d2SAndroid Build Coastguard Worker mime_compare_fcache(_mime_fcache_t *a,	/* I - First entry */
581*5e7646d2SAndroid Build Coastguard Worker                _mime_fcache_t *b)	/* I - Second entry */
582*5e7646d2SAndroid Build Coastguard Worker {
583*5e7646d2SAndroid Build Coastguard Worker   return (strcmp(a->name, b->name));
584*5e7646d2SAndroid Build Coastguard Worker }
585*5e7646d2SAndroid Build Coastguard Worker 
586*5e7646d2SAndroid Build Coastguard Worker 
587*5e7646d2SAndroid Build Coastguard Worker /*
588*5e7646d2SAndroid Build Coastguard Worker  * 'mime_delete_fcache()' - Free all memory used by the filter cache.
589*5e7646d2SAndroid Build Coastguard Worker  */
590*5e7646d2SAndroid Build Coastguard Worker 
591*5e7646d2SAndroid Build Coastguard Worker static void
mime_delete_fcache(cups_array_t * filtercache)592*5e7646d2SAndroid Build Coastguard Worker mime_delete_fcache(
593*5e7646d2SAndroid Build Coastguard Worker     cups_array_t *filtercache)		/* I - Filter cache */
594*5e7646d2SAndroid Build Coastguard Worker {
595*5e7646d2SAndroid Build Coastguard Worker   _mime_fcache_t	*current;	/* Current cache entry */
596*5e7646d2SAndroid Build Coastguard Worker 
597*5e7646d2SAndroid Build Coastguard Worker 
598*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2mime_delete_fcache(filtercache=%p)", filtercache));
599*5e7646d2SAndroid Build Coastguard Worker 
600*5e7646d2SAndroid Build Coastguard Worker   for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache);
601*5e7646d2SAndroid Build Coastguard Worker        current;
602*5e7646d2SAndroid Build Coastguard Worker        current = (_mime_fcache_t *)cupsArrayNext(filtercache))
603*5e7646d2SAndroid Build Coastguard Worker   {
604*5e7646d2SAndroid Build Coastguard Worker     free(current->name);
605*5e7646d2SAndroid Build Coastguard Worker 
606*5e7646d2SAndroid Build Coastguard Worker     if (current->path)
607*5e7646d2SAndroid Build Coastguard Worker       free(current->path);
608*5e7646d2SAndroid Build Coastguard Worker 
609*5e7646d2SAndroid Build Coastguard Worker     free(current);
610*5e7646d2SAndroid Build Coastguard Worker   }
611*5e7646d2SAndroid Build Coastguard Worker 
612*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(filtercache);
613*5e7646d2SAndroid Build Coastguard Worker }
614*5e7646d2SAndroid Build Coastguard Worker 
615*5e7646d2SAndroid Build Coastguard Worker 
616*5e7646d2SAndroid Build Coastguard Worker /*
617*5e7646d2SAndroid Build Coastguard Worker  * 'mime_delete_rules()' - Free all memory for the given rule tree.
618*5e7646d2SAndroid Build Coastguard Worker  */
619*5e7646d2SAndroid Build Coastguard Worker 
620*5e7646d2SAndroid Build Coastguard Worker static void
mime_delete_rules(mime_magic_t * rules)621*5e7646d2SAndroid Build Coastguard Worker mime_delete_rules(mime_magic_t *rules)	/* I - Rules to free */
622*5e7646d2SAndroid Build Coastguard Worker {
623*5e7646d2SAndroid Build Coastguard Worker   mime_magic_t	*next;			/* Next rule to free */
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker 
626*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2mime_delete_rules(rules=%p)", rules));
627*5e7646d2SAndroid Build Coastguard Worker 
628*5e7646d2SAndroid Build Coastguard Worker  /*
629*5e7646d2SAndroid Build Coastguard Worker   * Free the rules list, descending recursively to free any child rules.
630*5e7646d2SAndroid Build Coastguard Worker   */
631*5e7646d2SAndroid Build Coastguard Worker 
632*5e7646d2SAndroid Build Coastguard Worker   while (rules != NULL)
633*5e7646d2SAndroid Build Coastguard Worker   {
634*5e7646d2SAndroid Build Coastguard Worker     next = rules->next;
635*5e7646d2SAndroid Build Coastguard Worker 
636*5e7646d2SAndroid Build Coastguard Worker     if (rules->child != NULL)
637*5e7646d2SAndroid Build Coastguard Worker       mime_delete_rules(rules->child);
638*5e7646d2SAndroid Build Coastguard Worker 
639*5e7646d2SAndroid Build Coastguard Worker     if (rules->op == MIME_MAGIC_REGEX)
640*5e7646d2SAndroid Build Coastguard Worker       regfree(&(rules->value.rev));
641*5e7646d2SAndroid Build Coastguard Worker 
642*5e7646d2SAndroid Build Coastguard Worker     free(rules);
643*5e7646d2SAndroid Build Coastguard Worker     rules = next;
644*5e7646d2SAndroid Build Coastguard Worker   }
645*5e7646d2SAndroid Build Coastguard Worker }
646*5e7646d2SAndroid Build Coastguard Worker 
647*5e7646d2SAndroid Build Coastguard Worker 
648*5e7646d2SAndroid Build Coastguard Worker /*
649*5e7646d2SAndroid Build Coastguard Worker  * 'mime_load_convs()' - Load a xyz.convs file.
650*5e7646d2SAndroid Build Coastguard Worker  */
651*5e7646d2SAndroid Build Coastguard Worker 
652*5e7646d2SAndroid Build Coastguard Worker static void
mime_load_convs(mime_t * mime,const char * filename,const char * filterpath,cups_array_t * filtercache)653*5e7646d2SAndroid Build Coastguard Worker mime_load_convs(
654*5e7646d2SAndroid Build Coastguard Worker     mime_t       *mime,			/* I - MIME database */
655*5e7646d2SAndroid Build Coastguard Worker     const char   *filename,		/* I - Convs file to load */
656*5e7646d2SAndroid Build Coastguard Worker     const char   *filterpath,		/* I - Path for filters */
657*5e7646d2SAndroid Build Coastguard Worker     cups_array_t *filtercache)		/* I - Filter program cache */
658*5e7646d2SAndroid Build Coastguard Worker {
659*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* Convs file */
660*5e7646d2SAndroid Build Coastguard Worker   char		line[1024],		/* Input line from file */
661*5e7646d2SAndroid Build Coastguard Worker 		*lineptr,		/* Current position in line */
662*5e7646d2SAndroid Build Coastguard Worker 		super[MIME_MAX_SUPER],	/* Super-type name */
663*5e7646d2SAndroid Build Coastguard Worker 		type[MIME_MAX_TYPE],	/* Type name */
664*5e7646d2SAndroid Build Coastguard Worker 		*temp,			/* Temporary pointer */
665*5e7646d2SAndroid Build Coastguard Worker 		*filter;		/* Filter program */
666*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*temptype,		/* MIME type looping var */
667*5e7646d2SAndroid Build Coastguard Worker 		*dsttype;		/* Destination MIME type */
668*5e7646d2SAndroid Build Coastguard Worker   int		cost;			/* Cost of filter */
669*5e7646d2SAndroid Build Coastguard Worker 
670*5e7646d2SAndroid Build Coastguard Worker 
671*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2mime_load_convs(mime=%p, filename=\"%s\", filterpath=\"%s\", "
672*5e7646d2SAndroid Build Coastguard Worker                 "filtercache=%p)", mime, filename, filterpath, filtercache));
673*5e7646d2SAndroid Build Coastguard Worker 
674*5e7646d2SAndroid Build Coastguard Worker  /*
675*5e7646d2SAndroid Build Coastguard Worker   * First try to open the file...
676*5e7646d2SAndroid Build Coastguard Worker   */
677*5e7646d2SAndroid Build Coastguard Worker 
678*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(filename, "r")) == NULL)
679*5e7646d2SAndroid Build Coastguard Worker   {
680*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("3mime_load_convs: Unable to open \"%s\": %s", filename,
681*5e7646d2SAndroid Build Coastguard Worker                   strerror(errno)));
682*5e7646d2SAndroid Build Coastguard Worker     _mimeError(mime, "Unable to open \"%s\": %s", filename, strerror(errno));
683*5e7646d2SAndroid Build Coastguard Worker     return;
684*5e7646d2SAndroid Build Coastguard Worker   }
685*5e7646d2SAndroid Build Coastguard Worker 
686*5e7646d2SAndroid Build Coastguard Worker  /*
687*5e7646d2SAndroid Build Coastguard Worker   * Then read each line from the file, skipping any comments in the file...
688*5e7646d2SAndroid Build Coastguard Worker   */
689*5e7646d2SAndroid Build Coastguard Worker 
690*5e7646d2SAndroid Build Coastguard Worker   while (cupsFileGets(fp, line, sizeof(line)) != NULL)
691*5e7646d2SAndroid Build Coastguard Worker   {
692*5e7646d2SAndroid Build Coastguard Worker    /*
693*5e7646d2SAndroid Build Coastguard Worker     * Skip blank lines and lines starting with a #...
694*5e7646d2SAndroid Build Coastguard Worker     */
695*5e7646d2SAndroid Build Coastguard Worker 
696*5e7646d2SAndroid Build Coastguard Worker     if (!line[0] || line[0] == '#')
697*5e7646d2SAndroid Build Coastguard Worker       continue;
698*5e7646d2SAndroid Build Coastguard Worker 
699*5e7646d2SAndroid Build Coastguard Worker    /*
700*5e7646d2SAndroid Build Coastguard Worker     * Strip trailing whitespace...
701*5e7646d2SAndroid Build Coastguard Worker     */
702*5e7646d2SAndroid Build Coastguard Worker 
703*5e7646d2SAndroid Build Coastguard Worker     for (lineptr = line + strlen(line) - 1;
704*5e7646d2SAndroid Build Coastguard Worker          lineptr >= line && isspace(*lineptr & 255);
705*5e7646d2SAndroid Build Coastguard Worker 	 lineptr --)
706*5e7646d2SAndroid Build Coastguard Worker       *lineptr = '\0';
707*5e7646d2SAndroid Build Coastguard Worker 
708*5e7646d2SAndroid Build Coastguard Worker    /*
709*5e7646d2SAndroid Build Coastguard Worker     * Extract the destination super-type and type names from the middle of
710*5e7646d2SAndroid Build Coastguard Worker     * the line.
711*5e7646d2SAndroid Build Coastguard Worker     */
712*5e7646d2SAndroid Build Coastguard Worker 
713*5e7646d2SAndroid Build Coastguard Worker     lineptr = line;
714*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0')
715*5e7646d2SAndroid Build Coastguard Worker       lineptr ++;
716*5e7646d2SAndroid Build Coastguard Worker 
717*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr == ' ' || *lineptr == '\t')
718*5e7646d2SAndroid Build Coastguard Worker       lineptr ++;
719*5e7646d2SAndroid Build Coastguard Worker 
720*5e7646d2SAndroid Build Coastguard Worker     temp = super;
721*5e7646d2SAndroid Build Coastguard Worker 
722*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
723*5e7646d2SAndroid Build Coastguard Worker            (temp - super + 1) < MIME_MAX_SUPER)
724*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
725*5e7646d2SAndroid Build Coastguard Worker 
726*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
727*5e7646d2SAndroid Build Coastguard Worker 
728*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr != '/')
729*5e7646d2SAndroid Build Coastguard Worker       continue;
730*5e7646d2SAndroid Build Coastguard Worker 
731*5e7646d2SAndroid Build Coastguard Worker     lineptr ++;
732*5e7646d2SAndroid Build Coastguard Worker     temp = type;
733*5e7646d2SAndroid Build Coastguard Worker 
734*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
735*5e7646d2SAndroid Build Coastguard Worker            *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
736*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
737*5e7646d2SAndroid Build Coastguard Worker 
738*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
739*5e7646d2SAndroid Build Coastguard Worker 
740*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr == '\0' || *lineptr == '\n')
741*5e7646d2SAndroid Build Coastguard Worker       continue;
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker     if ((dsttype = mimeType(mime, super, type)) == NULL)
744*5e7646d2SAndroid Build Coastguard Worker     {
745*5e7646d2SAndroid Build Coastguard Worker       DEBUG_printf(("3mime_load_convs: Destination type %s/%s not found.",
746*5e7646d2SAndroid Build Coastguard Worker                     super, type));
747*5e7646d2SAndroid Build Coastguard Worker       continue;
748*5e7646d2SAndroid Build Coastguard Worker     }
749*5e7646d2SAndroid Build Coastguard Worker 
750*5e7646d2SAndroid Build Coastguard Worker    /*
751*5e7646d2SAndroid Build Coastguard Worker     * Then get the cost and filter program...
752*5e7646d2SAndroid Build Coastguard Worker     */
753*5e7646d2SAndroid Build Coastguard Worker 
754*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr == ' ' || *lineptr == '\t')
755*5e7646d2SAndroid Build Coastguard Worker       lineptr ++;
756*5e7646d2SAndroid Build Coastguard Worker 
757*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr < '0' || *lineptr > '9')
758*5e7646d2SAndroid Build Coastguard Worker       continue;
759*5e7646d2SAndroid Build Coastguard Worker 
760*5e7646d2SAndroid Build Coastguard Worker     cost = atoi(lineptr);
761*5e7646d2SAndroid Build Coastguard Worker 
762*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\0')
763*5e7646d2SAndroid Build Coastguard Worker       lineptr ++;
764*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr == ' ' || *lineptr == '\t')
765*5e7646d2SAndroid Build Coastguard Worker       lineptr ++;
766*5e7646d2SAndroid Build Coastguard Worker 
767*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr == '\0' || *lineptr == '\n')
768*5e7646d2SAndroid Build Coastguard Worker       continue;
769*5e7646d2SAndroid Build Coastguard Worker 
770*5e7646d2SAndroid Build Coastguard Worker     filter = lineptr;
771*5e7646d2SAndroid Build Coastguard Worker 
772*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(filter, "-"))
773*5e7646d2SAndroid Build Coastguard Worker     {
774*5e7646d2SAndroid Build Coastguard Worker      /*
775*5e7646d2SAndroid Build Coastguard Worker       * Verify that the filter exists and is executable...
776*5e7646d2SAndroid Build Coastguard Worker       */
777*5e7646d2SAndroid Build Coastguard Worker 
778*5e7646d2SAndroid Build Coastguard Worker       if (!mime_add_fcache(filtercache, filter, filterpath))
779*5e7646d2SAndroid Build Coastguard Worker       {
780*5e7646d2SAndroid Build Coastguard Worker         DEBUG_printf(("mime_load_convs: Filter %s not found in %s.", filter,
781*5e7646d2SAndroid Build Coastguard Worker 	              filterpath));
782*5e7646d2SAndroid Build Coastguard Worker         _mimeError(mime, "Filter \"%s\" not found.", filter);
783*5e7646d2SAndroid Build Coastguard Worker         continue;
784*5e7646d2SAndroid Build Coastguard Worker       }
785*5e7646d2SAndroid Build Coastguard Worker     }
786*5e7646d2SAndroid Build Coastguard Worker 
787*5e7646d2SAndroid Build Coastguard Worker    /*
788*5e7646d2SAndroid Build Coastguard Worker     * Finally, get the source super-type and type names from the beginning of
789*5e7646d2SAndroid Build Coastguard Worker     * the line.  We do it here so we can support wildcards...
790*5e7646d2SAndroid Build Coastguard Worker     */
791*5e7646d2SAndroid Build Coastguard Worker 
792*5e7646d2SAndroid Build Coastguard Worker     lineptr = line;
793*5e7646d2SAndroid Build Coastguard Worker     temp    = super;
794*5e7646d2SAndroid Build Coastguard Worker 
795*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
796*5e7646d2SAndroid Build Coastguard Worker            (temp - super + 1) < MIME_MAX_SUPER)
797*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
798*5e7646d2SAndroid Build Coastguard Worker 
799*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
800*5e7646d2SAndroid Build Coastguard Worker 
801*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr != '/')
802*5e7646d2SAndroid Build Coastguard Worker       continue;
803*5e7646d2SAndroid Build Coastguard Worker 
804*5e7646d2SAndroid Build Coastguard Worker     lineptr ++;
805*5e7646d2SAndroid Build Coastguard Worker     temp = type;
806*5e7646d2SAndroid Build Coastguard Worker 
807*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
808*5e7646d2SAndroid Build Coastguard Worker            *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
809*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
810*5e7646d2SAndroid Build Coastguard Worker 
811*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
812*5e7646d2SAndroid Build Coastguard Worker 
813*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(super, "*") && !strcmp(type, "*"))
814*5e7646d2SAndroid Build Coastguard Worker     {
815*5e7646d2SAndroid Build Coastguard Worker      /*
816*5e7646d2SAndroid Build Coastguard Worker       * Force * / * to be "application/octet-stream"...
817*5e7646d2SAndroid Build Coastguard Worker       */
818*5e7646d2SAndroid Build Coastguard Worker 
819*5e7646d2SAndroid Build Coastguard Worker       strlcpy(super, "application", sizeof(super));
820*5e7646d2SAndroid Build Coastguard Worker       strlcpy(type, "octet-stream", sizeof(type));
821*5e7646d2SAndroid Build Coastguard Worker     }
822*5e7646d2SAndroid Build Coastguard Worker 
823*5e7646d2SAndroid Build Coastguard Worker    /*
824*5e7646d2SAndroid Build Coastguard Worker     * Add the filter to the MIME database, supporting wildcards as needed...
825*5e7646d2SAndroid Build Coastguard Worker     */
826*5e7646d2SAndroid Build Coastguard Worker 
827*5e7646d2SAndroid Build Coastguard Worker     for (temptype = (mime_type_t *)cupsArrayFirst(mime->types);
828*5e7646d2SAndroid Build Coastguard Worker          temptype;
829*5e7646d2SAndroid Build Coastguard Worker 	 temptype = (mime_type_t *)cupsArrayNext(mime->types))
830*5e7646d2SAndroid Build Coastguard Worker       if ((super[0] == '*' || !strcmp(temptype->super, super)) &&
831*5e7646d2SAndroid Build Coastguard Worker           (type[0] == '*' || !strcmp(temptype->type, type)))
832*5e7646d2SAndroid Build Coastguard Worker 	mimeAddFilter(mime, temptype, dsttype, cost, filter);
833*5e7646d2SAndroid Build Coastguard Worker   }
834*5e7646d2SAndroid Build Coastguard Worker 
835*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
836*5e7646d2SAndroid Build Coastguard Worker }
837*5e7646d2SAndroid Build Coastguard Worker 
838*5e7646d2SAndroid Build Coastguard Worker 
839*5e7646d2SAndroid Build Coastguard Worker /*
840*5e7646d2SAndroid Build Coastguard Worker  * 'mime_load_types()' - Load a xyz.types file.
841*5e7646d2SAndroid Build Coastguard Worker  */
842*5e7646d2SAndroid Build Coastguard Worker 
843*5e7646d2SAndroid Build Coastguard Worker static void
mime_load_types(mime_t * mime,const char * filename)844*5e7646d2SAndroid Build Coastguard Worker mime_load_types(mime_t     *mime,	/* I - MIME database */
845*5e7646d2SAndroid Build Coastguard Worker                 const char *filename)	/* I - Types file to load */
846*5e7646d2SAndroid Build Coastguard Worker {
847*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* Types file */
848*5e7646d2SAndroid Build Coastguard Worker   size_t	linelen;		/* Length of line */
849*5e7646d2SAndroid Build Coastguard Worker   char		line[32768],		/* Input line from file */
850*5e7646d2SAndroid Build Coastguard Worker 		*lineptr,		/* Current position in line */
851*5e7646d2SAndroid Build Coastguard Worker 		super[MIME_MAX_SUPER],	/* Super-type name */
852*5e7646d2SAndroid Build Coastguard Worker 		type[MIME_MAX_TYPE],	/* Type name */
853*5e7646d2SAndroid Build Coastguard Worker 		*temp;			/* Temporary pointer */
854*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*typeptr;		/* New MIME type */
855*5e7646d2SAndroid Build Coastguard Worker 
856*5e7646d2SAndroid Build Coastguard Worker 
857*5e7646d2SAndroid Build Coastguard Worker   DEBUG_printf(("2mime_load_types(mime=%p, filename=\"%s\")", mime, filename));
858*5e7646d2SAndroid Build Coastguard Worker 
859*5e7646d2SAndroid Build Coastguard Worker  /*
860*5e7646d2SAndroid Build Coastguard Worker   * First try to open the file...
861*5e7646d2SAndroid Build Coastguard Worker   */
862*5e7646d2SAndroid Build Coastguard Worker 
863*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(filename, "r")) == NULL)
864*5e7646d2SAndroid Build Coastguard Worker   {
865*5e7646d2SAndroid Build Coastguard Worker     DEBUG_printf(("3mime_load_types: Unable to open \"%s\": %s", filename,
866*5e7646d2SAndroid Build Coastguard Worker                   strerror(errno)));
867*5e7646d2SAndroid Build Coastguard Worker     _mimeError(mime, "Unable to open \"%s\": %s", filename, strerror(errno));
868*5e7646d2SAndroid Build Coastguard Worker     return;
869*5e7646d2SAndroid Build Coastguard Worker   }
870*5e7646d2SAndroid Build Coastguard Worker 
871*5e7646d2SAndroid Build Coastguard Worker  /*
872*5e7646d2SAndroid Build Coastguard Worker   * Then read each line from the file, skipping any comments in the file...
873*5e7646d2SAndroid Build Coastguard Worker   */
874*5e7646d2SAndroid Build Coastguard Worker 
875*5e7646d2SAndroid Build Coastguard Worker   while (cupsFileGets(fp, line, sizeof(line)) != NULL)
876*5e7646d2SAndroid Build Coastguard Worker   {
877*5e7646d2SAndroid Build Coastguard Worker    /*
878*5e7646d2SAndroid Build Coastguard Worker     * Skip blank lines and lines starting with a #...
879*5e7646d2SAndroid Build Coastguard Worker     */
880*5e7646d2SAndroid Build Coastguard Worker 
881*5e7646d2SAndroid Build Coastguard Worker     if (!line[0] || line[0] == '#')
882*5e7646d2SAndroid Build Coastguard Worker       continue;
883*5e7646d2SAndroid Build Coastguard Worker 
884*5e7646d2SAndroid Build Coastguard Worker    /*
885*5e7646d2SAndroid Build Coastguard Worker     * While the last character in the line is a backslash, continue on to the
886*5e7646d2SAndroid Build Coastguard Worker     * next line (and the next, etc.)
887*5e7646d2SAndroid Build Coastguard Worker     */
888*5e7646d2SAndroid Build Coastguard Worker 
889*5e7646d2SAndroid Build Coastguard Worker     linelen = strlen(line);
890*5e7646d2SAndroid Build Coastguard Worker 
891*5e7646d2SAndroid Build Coastguard Worker     while (line[linelen - 1] == '\\')
892*5e7646d2SAndroid Build Coastguard Worker     {
893*5e7646d2SAndroid Build Coastguard Worker       linelen --;
894*5e7646d2SAndroid Build Coastguard Worker 
895*5e7646d2SAndroid Build Coastguard Worker       if (cupsFileGets(fp, line + linelen, sizeof(line) - linelen) == NULL)
896*5e7646d2SAndroid Build Coastguard Worker         line[linelen] = '\0';
897*5e7646d2SAndroid Build Coastguard Worker       else
898*5e7646d2SAndroid Build Coastguard Worker         linelen += strlen(line + linelen);
899*5e7646d2SAndroid Build Coastguard Worker     }
900*5e7646d2SAndroid Build Coastguard Worker 
901*5e7646d2SAndroid Build Coastguard Worker    /*
902*5e7646d2SAndroid Build Coastguard Worker     * Extract the super-type and type names from the beginning of the line.
903*5e7646d2SAndroid Build Coastguard Worker     */
904*5e7646d2SAndroid Build Coastguard Worker 
905*5e7646d2SAndroid Build Coastguard Worker     lineptr = line;
906*5e7646d2SAndroid Build Coastguard Worker     temp    = super;
907*5e7646d2SAndroid Build Coastguard Worker 
908*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != '/' && *lineptr != '\n' && *lineptr != '\0' &&
909*5e7646d2SAndroid Build Coastguard Worker            (temp - super + 1) < MIME_MAX_SUPER)
910*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
911*5e7646d2SAndroid Build Coastguard Worker 
912*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
913*5e7646d2SAndroid Build Coastguard Worker 
914*5e7646d2SAndroid Build Coastguard Worker     if (*lineptr != '/')
915*5e7646d2SAndroid Build Coastguard Worker       continue;
916*5e7646d2SAndroid Build Coastguard Worker 
917*5e7646d2SAndroid Build Coastguard Worker     lineptr ++;
918*5e7646d2SAndroid Build Coastguard Worker     temp = type;
919*5e7646d2SAndroid Build Coastguard Worker 
920*5e7646d2SAndroid Build Coastguard Worker     while (*lineptr != ' ' && *lineptr != '\t' && *lineptr != '\n' &&
921*5e7646d2SAndroid Build Coastguard Worker            *lineptr != '\0' && (temp - type + 1) < MIME_MAX_TYPE)
922*5e7646d2SAndroid Build Coastguard Worker       *temp++ = (char)tolower(*lineptr++ & 255);
923*5e7646d2SAndroid Build Coastguard Worker 
924*5e7646d2SAndroid Build Coastguard Worker     *temp = '\0';
925*5e7646d2SAndroid Build Coastguard Worker 
926*5e7646d2SAndroid Build Coastguard Worker    /*
927*5e7646d2SAndroid Build Coastguard Worker     * Add the type and rules to the MIME database...
928*5e7646d2SAndroid Build Coastguard Worker     */
929*5e7646d2SAndroid Build Coastguard Worker 
930*5e7646d2SAndroid Build Coastguard Worker     typeptr = mimeAddType(mime, super, type);
931*5e7646d2SAndroid Build Coastguard Worker     mimeAddTypeRule(typeptr, lineptr);
932*5e7646d2SAndroid Build Coastguard Worker   }
933*5e7646d2SAndroid Build Coastguard Worker 
934*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
935*5e7646d2SAndroid Build Coastguard Worker }
936