]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2 * "$Id: mime.c 4970 2006-01-24 14:05:45Z 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 * mimeNextType() - Get the next type in the MIME database.
32 * mimeLoad() - Create a new MIME database from disk.
33 * mimeMerge() - Merge a MIME database from disk with the current one.
34 * mimeNew() - Create a new, empty MIME database.
35 * mimeNextFilter() - Get the next filter in the MIME database.
36 * mimeNextType() - Get the next type in the MIME database.
37 * mimeNumFilters() - Get the number of filters in a MIME database.
38 * mimeNumTypes() - Get the number of types in a MIME database.
39 * load_types() - Load a xyz.types file...
40 * delete_rules() - Free all memory for the given rule tree.
41 * load_convs() - Load a xyz.convs file...
45 * Include necessary headers...
53 #include <cups/string.h>
61 static void load_types(mime_t
*mime
, const char *filename
);
62 static void load_convs(mime_t
*mime
, const char *filename
,
63 const char *filterpath
);
64 static void delete_rules(mime_magic_t
*rules
);
68 * 'mimeDelete()' - Delete (free) a MIME database.
72 mimeDelete(mime_t
*mime
) /* I - MIME database */
74 mime_type_t
*type
; /* Current type */
75 mime_filter_t
*filter
; /* Current filter */
82 * Loop through the file types and delete any rules...
85 for (type
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
87 type
= (mime_type_t
*)cupsArrayNext(mime
->types
))
88 mimeDeleteType(mime
, type
);
91 * Loop through filters and free them...
94 for (filter
= (mime_filter_t
*)cupsArrayFirst(mime
->filters
);
96 filter
= (mime_filter_t
*)cupsArrayNext(mime
->filters
))
97 mimeDeleteFilter(mime
, filter
);
100 * Free the types and filters arrays, and then the MIME database structure.
103 cupsArrayDelete(mime
->types
);
104 cupsArrayDelete(mime
->filters
);
110 * 'mimeDeleteFilter()' - Delete a filter from the MIME database.
114 mimeDeleteFilter(mime_t
*mime
, /* I - MIME database */
115 mime_filter_t
*filter
) /* I - Filter */
117 if (!mime
|| !filter
)
120 cupsArrayRemove(mime
->filters
, filter
);
126 * 'mimeDeleteType()' - Delete a type from the MIME database.
130 mimeDeleteType(mime_t
*mime
, /* I - MIME database */
131 mime_type_t
*mt
) /* I - Type */
136 cupsArrayRemove(mime
->types
, mt
);
138 delete_rules(mt
->rules
);
144 * 'mimeFirstFilter()' - Get the first filter in the MIME database.
147 mime_filter_t
* /* O - Filter or NULL */
148 mimeFirstFilter(mime_t
*mime
) /* I - MIME database */
153 return ((mime_filter_t
*)cupsArrayFirst(mime
->filters
));
158 * 'mimeFirstType()' - Get the first type in the MIME database.
161 mime_type_t
* /* O - Type or NULL */
162 mimeFirstType(mime_t
*mime
) /* I - MIME database */
167 return ((mime_type_t
*)cupsArrayFirst(mime
->types
));
172 * 'mimeLoad()' - Create a new MIME database from disk.
175 mime_t
* /* O - New MIME database */
176 mimeLoad(const char *pathname
, /* I - Directory to load */
177 const char *filterpath
) /* I - Directory to load */
179 return (mimeMerge(NULL
, pathname
, filterpath
));
184 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
187 mime_t
* /* O - Updated MIME database */
188 mimeMerge(mime_t
*mime
, /* I - MIME database to add to */
189 const char *pathname
, /* I - Directory to load */
190 const char *filterpath
) /* I - Directory to load */
192 cups_dir_t
*dir
; /* Directory */
193 cups_dentry_t
*dent
; /* Directory entry */
194 char filename
[1024]; /* Full filename of types/converts file */
198 * First open the directory specified by pathname... Return NULL if nothing
199 * was read or if the pathname is NULL...
205 if ((dir
= cupsDirOpen(pathname
)) == NULL
)
209 * If "mime" is NULL, make a new, blank database...
218 * Read all the .types files...
221 while ((dent
= cupsDirRead(dir
)) != NULL
)
223 if (strlen(dent
->filename
) > 6 &&
224 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".types"))
227 * Load a mime.types file...
230 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
231 load_types(mime
, filename
);
238 * Read all the .convs files...
241 while ((dent
= cupsDirRead(dir
)) != NULL
)
243 if (strlen(dent
->filename
) > 6 &&
244 !strcmp(dent
->filename
+ strlen(dent
->filename
) - 6, ".convs"))
247 * Load a mime.convs file...
250 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
251 load_convs(mime
, filename
, filterpath
);
262 * 'mimeNew()' - Create a new, empty MIME database.
265 mime_t
* /* O - MIME database */
268 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
273 * 'mimeNextFilter()' - Get the next filter in the MIME database.
276 mime_filter_t
* /* O - Filter or NULL */
277 mimeNextFilter(mime_t
*mime
) /* I - MIME database */
282 return ((mime_filter_t
*)cupsArrayNext(mime
->filters
));
287 * 'mimeNextType()' - Get the next type in the MIME database.
290 mime_type_t
* /* O - Type or NULL */
291 mimeNextType(mime_t
*mime
) /* I - MIME database */
296 return ((mime_type_t
*)cupsArrayNext(mime
->types
));
301 * 'mimeNumFilters()' - Get the number of filters in a MIME database.
305 mimeNumFilters(mime_t
*mime
) /* I - MIME database */
310 return (cupsArrayCount(mime
->filters
));
315 * 'mimeNumTypes()' - Get the number of types in a MIME database.
319 mimeNumTypes(mime_t
*mime
) /* I - MIME database */
324 return (cupsArrayCount(mime
->types
));
329 * 'load_types()' - Load a xyz.types file...
333 load_types(mime_t
*mime
, /* I - MIME database */
334 const char *filename
) /* I - Types file to load */
336 cups_file_t
*fp
; /* Types file */
337 int linelen
; /* Length of line */
338 char line
[65536], /* Input line from file */
339 *lineptr
, /* Current position in line */
340 super
[MIME_MAX_SUPER
], /* Super-type name */
341 type
[MIME_MAX_TYPE
], /* Type name */
342 *temp
; /* Temporary pointer */
343 mime_type_t
*typeptr
; /* New MIME type */
347 * First try to open the file...
350 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
354 * Then read each line from the file, skipping any comments in the file...
357 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
360 * Skip blank lines and lines starting with a #...
363 if (!line
[0] || line
[0] == '#')
367 * While the last character in the line is a backslash, continue on to the
368 * next line (and the next, etc.)
371 linelen
= strlen(line
);
373 while (line
[linelen
- 1] == '\\')
377 if (cupsFileGets(fp
, line
+ linelen
, sizeof(line
) - linelen
) == NULL
)
378 line
[linelen
] = '\0';
380 linelen
+= strlen(line
+ linelen
);
384 * Extract the super-type and type names from the beginning of the line.
390 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
391 (temp
- super
+ 1) < MIME_MAX_SUPER
)
392 *temp
++ = tolower(*lineptr
++ & 255);
402 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
403 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
404 *temp
++ = tolower(*lineptr
++ & 255);
409 * Add the type and rules to the MIME database...
412 typeptr
= mimeAddType(mime
, super
, type
);
413 mimeAddTypeRule(typeptr
, lineptr
);
421 * 'load_convs()' - Load a xyz.convs file...
425 load_convs(mime_t
*mime
, /* I - MIME database */
426 const char *filename
, /* I - Convs file to load */
427 const char *filterpath
) /* I - Path for filters */
429 cups_file_t
*fp
; /* Convs file */
430 char line
[1024], /* Input line from file */
431 *lineptr
, /* Current position in line */
432 super
[MIME_MAX_SUPER
], /* Super-type name */
433 type
[MIME_MAX_TYPE
], /* Type name */
434 *temp
, /* Temporary pointer */
435 *filter
; /* Filter program */
436 mime_type_t
*temptype
, /* MIME type looping var */
437 *dsttype
; /* Destination MIME type */
438 int cost
; /* Cost of filter */
440 char filterprog
[1024]; /* Full path of filter... */
445 * First try to open the file...
448 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
452 * Then read each line from the file, skipping any comments in the file...
455 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
458 * Skip blank lines and lines starting with a #...
461 if (!line
[0] || line
[0] == '#')
465 * Strip trailing whitespace...
468 for (lineptr
= line
+ strlen(line
) - 1;
469 lineptr
>= line
&& isspace(*lineptr
& 255);
474 * Extract the destination super-type and type names from the middle of
479 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
482 while (*lineptr
== ' ' || *lineptr
== '\t')
487 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
488 (temp
- super
+ 1) < MIME_MAX_SUPER
)
489 *temp
++ = tolower(*lineptr
++ & 255);
499 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
500 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
501 *temp
++ = tolower(*lineptr
++ & 255);
505 if (*lineptr
== '\0' || *lineptr
== '\n')
508 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
512 * Then get the cost and filter program...
515 while (*lineptr
== ' ' || *lineptr
== '\t')
518 if (*lineptr
< '0' || *lineptr
> '9')
521 cost
= atoi(lineptr
);
523 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
525 while (*lineptr
== ' ' || *lineptr
== '\t')
528 if (*lineptr
== '\0' || *lineptr
== '\n')
534 if (strcmp(filter
, "-"))
537 * Verify that the filter exists and is executable...
540 if (filter
[0] == '/')
541 strlcpy(filterprog
, filter
, sizeof(filterprog
));
542 else if (!cupsFileFind(filter
, filterpath
, filterprog
,
546 if (access(filterprog
, X_OK
))
552 * Finally, get the source super-type and type names from the beginning of
553 * the line. We do it here so we can support wildcards...
559 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
560 (temp
- super
+ 1) < MIME_MAX_SUPER
)
561 *temp
++ = tolower(*lineptr
++ & 255);
571 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
572 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
573 *temp
++ = tolower(*lineptr
++ & 255);
577 if (!strcmp(super
, "*") && !strcmp(type
, "*"))
580 * Force * / * to be "application/octet-stream"...
583 strcpy(super
, "application");
584 strcpy(type
, "octet-stream");
588 * Add the filter to the MIME database, supporting wildcards as needed...
591 for (temptype
= (mime_type_t
*)cupsArrayFirst(mime
->types
);
593 temptype
= (mime_type_t
*)cupsArrayNext(mime
->types
))
594 if ((super
[0] == '*' || !strcmp(temptype
->super
, super
)) &&
595 (type
[0] == '*' || !strcmp(temptype
->type
, type
)))
596 mimeAddFilter(mime
, temptype
, dsttype
, cost
, filter
);
604 * 'delete_rules()' - Free all memory for the given rule tree.
608 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
610 mime_magic_t
*next
; /* Next rule to free */
614 * Free the rules list, descending recursively to free any child rules.
617 while (rules
!= NULL
)
621 if (rules
->child
!= NULL
)
622 delete_rules(rules
->child
);
631 * End of "$Id: mime.c 4970 2006-01-24 14:05:45Z mike $".