]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2 * "$Id: mime.c 4613 2005-08-30 12:41:48Z mike $"
4 * MIME database file routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2005 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 * mimeMerge() - Merge a MIME database from disk with the current one.
28 * mimeNew() - Create a new, empty MIME database.
29 * load_types() - Load a xyz.types file...
30 * delete_rules() - Free all memory for the given rule tree.
31 * load_convs() - Load a xyz.convs file...
35 * Include necessary headers...
42 #include <cups/string.h>
56 static void load_types(mime_t
*mime
, const char *filename
);
57 static void load_convs(mime_t
*mime
, const char *filename
,
58 const char *filterpath
);
59 static void delete_rules(mime_magic_t
*rules
);
63 * 'mimeDelete()' - Delete (free) a MIME database.
67 mimeDelete(mime_t
*mime
) /* I - MIME database */
69 int i
; /* Looping var */
76 * Loop through the file types and delete any rules...
79 for (i
= 0; i
< mime
->num_types
; i
++)
81 delete_rules(mime
->types
[i
]->rules
);
82 free(mime
->types
[i
]->type
);
87 * Free the types and filters arrays, and then the MIME database structure.
97 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
100 mime_t
* /* O - Updated MIME database */
101 mimeMerge(mime_t
*mime
, /* I - MIME database to add to */
102 const char *pathname
, /* I - Directory to load */
103 const char *filterpath
)/* I - Directory to load */
106 HANDLE dir
; /* Directory handle */
107 WIN32_FIND_DATA dent
; /* Directory entry */
108 char filename
[1024], /* Full filename of types/converts file */
109 *pathsep
; /* Last character in path */
113 * First open the directory specified by pathname... Return NULL if nothing
114 * was read or if the pathname is NULL...
117 if (pathname
== NULL
)
120 strlcpy(filename
, pathname
, sizeof(filename
));
122 pathsep
= filename
+ strlen(filename
);
123 if ((pathsep
- filename
+ 9) > sizeof(filename
))
126 if (pathsep
== filename
||
127 (pathsep
[-1] != '/' && pathsep
[-1] != '\\'))
129 strcpy(pathsep
, "/");
133 strcpy(pathsep
, "*.types");
135 if ((dir
= FindFirstFile(filename
, &dent
)) == 0)
139 * If "mime" is NULL, make a new, blank database...
143 if ((mime
= mimeNew()) == NULL
)
147 * Read all the .types files...
153 * Load a mime.types file...
156 if ((pathsep
- filename
+ strlen(dent
.cFileName
)) >= sizeof(filename
))
159 strcpy(pathsep
, dent
.cFileName
);
160 load_types(mime
, filename
);
162 while (FindNextFile(dir
, &dent
));
167 * Read all the .convs files...
170 strcpy(pathsep
, "*.convs");
172 if ((dir
= FindFirstFile(filename
, &dent
)) == 0)
178 * Load a mime.convs file...
181 if ((pathsep
- filename
+ strlen(dent
.cFileName
)) >= sizeof(filename
))
184 strcpy(pathsep
, dent
.cFileName
);
185 load_convs(mime
, filename
);
187 while (FindNextFile(dir
, &dent
));
193 DIR *dir
; /* Directory */
194 struct dirent
*dent
; /* Directory entry */
195 char filename
[1024]; /* Full filename of types/converts file */
199 * First open the directory specified by pathname... Return NULL if nothing
200 * was read or if the pathname is NULL...
203 if (pathname
== NULL
)
206 if ((dir
= opendir(pathname
)) == NULL
)
210 * If "mime" is NULL, make a new, blank database...
214 if ((mime
= mimeNew()) == NULL
)
218 * Read all the .types files...
221 while ((dent
= readdir(dir
)) != NULL
)
223 if (strlen(dent
->d_name
) > 6 &&
224 strcmp(dent
->d_name
+ strlen(dent
->d_name
) - 6, ".types") == 0)
227 * Load a mime.types file...
230 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->d_name
);
231 load_types(mime
, filename
);
238 * Read all the .convs files...
241 while ((dent
= readdir(dir
)) != NULL
)
243 if (strlen(dent
->d_name
) > 6 &&
244 strcmp(dent
->d_name
+ strlen(dent
->d_name
) - 6, ".convs") == 0)
247 * Load a mime.convs file...
250 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->d_name
);
251 load_convs(mime
, filename
, filterpath
);
263 * 'mimeNew()' - Create a new, empty MIME database.
266 mime_t
* /* O - MIME database */
269 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
274 * 'load_types()' - Load a xyz.types file...
278 load_types(mime_t
*mime
, /* I - MIME database */
279 const char *filename
) /* I - Types file to load */
281 cups_file_t
*fp
; /* Types file */
282 int linelen
; /* Length of line */
283 char line
[65536], /* Input line from file */
284 *lineptr
, /* Current position in line */
285 super
[MIME_MAX_SUPER
], /* Super-type name */
286 type
[MIME_MAX_TYPE
], /* Type name */
287 *temp
; /* Temporary pointer */
288 mime_type_t
*typeptr
; /* New MIME type */
292 * First try to open the file...
295 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
299 * Then read each line from the file, skipping any comments in the file...
302 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
305 * Skip blank lines and lines starting with a #...
308 if (!line
[0] || line
[0] == '#')
312 * While the last character in the line is a backslash, continue on to the
313 * next line (and the next, etc.)
316 linelen
= strlen(line
);
318 while (line
[linelen
- 1] == '\\')
322 if (cupsFileGets(fp
, line
+ linelen
, sizeof(line
) - linelen
) == NULL
)
323 line
[linelen
] = '\0';
325 linelen
+= strlen(line
+ linelen
);
329 * Extract the super-type and type names from the beginning of the line.
335 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
336 (temp
- super
+ 1) < MIME_MAX_SUPER
)
337 *temp
++ = tolower(*lineptr
++ & 255);
347 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
348 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
349 *temp
++ = tolower(*lineptr
++ & 255);
354 * Add the type and rules to the MIME database...
357 typeptr
= mimeAddType(mime
, super
, type
);
358 mimeAddTypeRule(typeptr
, lineptr
);
366 * 'load_convs()' - Load a xyz.convs file...
370 load_convs(mime_t
*mime
, /* I - MIME database */
371 const char *filename
, /* I - Convs file to load */
372 const char *filterpath
) /* I - Directory to load */
374 int i
; /* Looping var */
375 cups_file_t
*fp
; /* Convs file */
376 char line
[1024], /* Input line from file */
377 *lineptr
, /* Current position in line */
378 super
[MIME_MAX_SUPER
], /* Super-type name */
379 type
[MIME_MAX_TYPE
], /* Type name */
380 *temp
, /* Temporary pointer */
381 *filter
; /* Filter program */
382 mime_type_t
**temptype
, /* MIME type looping var */
383 *dsttype
; /* Destination MIME type */
384 int cost
; /* Cost of filter */
385 char filterprog
[1024]; /* Full path of filter... */
389 * First try to open the file...
392 if ((fp
= cupsFileOpen(filename
, "r")) == NULL
)
396 * Then read each line from the file, skipping any comments in the file...
399 while (cupsFileGets(fp
, line
, sizeof(line
)) != NULL
)
402 * Skip blank lines and lines starting with a #...
405 if (!line
[0] || line
[0] == '#')
409 * Strip trailing whitespace...
412 for (lineptr
= line
+ strlen(line
) - 1;
413 lineptr
>= line
&& isspace(*lineptr
& 255);
418 * Extract the destination super-type and type names from the middle of
423 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
426 while (*lineptr
== ' ' || *lineptr
== '\t')
431 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
432 (temp
- super
+ 1) < MIME_MAX_SUPER
)
433 *temp
++ = tolower(*lineptr
++ & 255);
443 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
444 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
445 *temp
++ = tolower(*lineptr
++ & 255);
449 if (*lineptr
== '\0' || *lineptr
== '\n')
452 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
456 * Then get the cost and filter program...
459 while (*lineptr
== ' ' || *lineptr
== '\t')
462 if (*lineptr
< '0' || *lineptr
> '9')
465 cost
= atoi(lineptr
);
467 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
469 while (*lineptr
== ' ' || *lineptr
== '\t')
472 if (*lineptr
== '\0' || *lineptr
== '\n')
478 if (strcmp(filter
, "-") != 0)
481 * Verify that the filter exists and is executable...
484 if (filter
[0] == '/')
485 strlcpy(filterprog
, filter
, sizeof(filterprog
));
487 snprintf(filterprog
, sizeof(filterprog
), "%s/%s", filterpath
, filter
);
489 if (access(filterprog
, X_OK
))
495 * Finally, get the source super-type and type names from the beginning of
496 * the line. We do it here so we can support wildcards...
502 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
503 (temp
- super
+ 1) < MIME_MAX_SUPER
)
504 *temp
++ = tolower(*lineptr
++ & 255);
514 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
515 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
516 *temp
++ = tolower(*lineptr
++ & 255);
520 if (strcmp(super
, "*") == 0 && strcmp(type
, "*") == 0)
523 * Force * / * to be "application/octet-stream"...
526 strcpy(super
, "application");
527 strcpy(type
, "octet-stream");
531 * Add the filter to the MIME database, supporting wildcards as needed...
534 for (temptype
= mime
->types
, i
= 0; i
< mime
->num_types
; i
++, temptype
++)
535 if ((super
[0] == '*' || strcmp((*temptype
)->super
, super
) == 0) &&
536 (type
[0] == '*' || strcmp((*temptype
)->type
, type
) == 0))
537 mimeAddFilter(mime
, *temptype
, dsttype
, cost
, filter
);
545 * 'delete_rules()' - Free all memory for the given rule tree.
549 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
551 mime_magic_t
*next
; /* Next rule to free */
555 * Free the rules list, descending recursively to free any child rules.
558 while (rules
!= NULL
)
562 if (rules
->child
!= NULL
)
563 delete_rules(rules
->child
);
572 * End of "$Id: mime.c 4613 2005-08-30 12:41:48Z mike $".