]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/mime.c
2e4e0b76ce851968d9247dc4a0cc1e6b2f3c39e0
2 * "$Id: mime.c,v 1.7 2001/01/22 15:04:01 mike Exp $"
4 * MIME database file routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2001 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-3111 USA
20 * Voice: (301) 373-9603
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>
45 #if defined(WIN32) || defined(__EMX__)
49 typedef struct dirent DIRENT
;
50 # define NAMLEN(dirent) strlen((dirent)->d_name)
53 # include <sys/ndir.h>
61 typedef struct direct DIRENT
;
62 # define NAMLEN(dirent) (dirent)->d_namlen
70 static void load_types(mime_t
*mime
, char *filename
);
71 static void load_convs(mime_t
*mime
, char *filename
);
72 static void delete_rules(mime_magic_t
*rules
);
76 * 'mimeDelete()' - Delete (free) a MIME database.
80 mimeDelete(mime_t
*mime
) /* I - MIME database */
82 int i
; /* Looping var */
89 * Loop through the file types and delete any rules...
92 for (i
= 0; i
< mime
->num_types
; i
++)
94 delete_rules(mime
->types
[i
]->rules
);
99 * Free the types and filters arrays, and then the MIME database structure.
109 * 'mimeMerge()' - Merge a MIME database from disk with the current one.
112 mime_t
* /* O - Updated MIME database */
113 mimeMerge(mime_t
*mime
, /* I - MIME database to add to */
114 const char *pathname
) /* I - Directory to load */
116 #if defined(WIN32) || defined(__EMX__)
117 HANDLE dir
; /* Directory handle */
118 WIN32_FIND_DATA dent
; /* Directory entry */
119 char filename
[1024], /* Full filename of types/converts file */
120 *pathsep
; /* Last character in path */
124 * First open the directory specified by pathname... Return NULL if nothing
125 * was read or if the pathname is NULL...
128 if (pathname
== NULL
)
131 strncpy(filename
, pathname
, sizeof(filename
) - 1);
132 filename
[sizeof(filename
) - 1] = '\0';
134 pathsep
= filename
+ strlen(filename
);
135 if ((pathsep
- filename
+ 9) > sizeof(filename
))
138 if (pathsep
== filename
||
139 (pathsep
[-1] != '/' && pathsep
[-1] != '\\'))
141 strcpy(pathsep
, "/");
145 strcpy(pathsep
, "*.types");
147 if ((dir
= FindFirstFile(filename
, &dent
)) == 0)
151 * If "mime" is NULL, make a new, blank database...
155 if ((mime
= mimeNew()) == NULL
)
159 * Read all the .types files...
165 * Load a mime.types file...
168 if ((pathsep
- filename
+ strlen(dent
.cFileName
)) >= sizeof(filename
))
171 strcpy(pathsep
, dent
.cFileName
);
172 load_types(mime
, filename
);
174 while (FindNextFile(dir
, &dent
));
179 * Read all the .convs files...
182 strcpy(pathsep
, "*.convs");
184 if ((dir
= FindFirstFile(filename
, &dent
)) == 0)
190 * Load a mime.convs file...
193 if ((pathsep
- filename
+ strlen(dent
.cFileName
)) >= sizeof(filename
))
196 strcpy(pathsep
, dent
.cFileName
);
197 load_convs(mime
, filename
);
199 while (FindNextFile(dir
, &dent
));
205 DIR *dir
; /* Directory */
206 DIRENT
*dent
; /* Directory entry */
207 char filename
[1024]; /* Full filename of types/converts file */
211 * First open the directory specified by pathname... Return NULL if nothing
212 * was read or if the pathname is NULL...
215 if (pathname
== NULL
)
218 if ((dir
= opendir(pathname
)) == NULL
)
222 * If "mime" is NULL, make a new, blank database...
226 if ((mime
= mimeNew()) == NULL
)
230 * Read all the .types files...
233 while ((dent
= readdir(dir
)) != NULL
)
235 if (NAMLEN(dent
) > 6 &&
236 strcmp(dent
->d_name
+ NAMLEN(dent
) - 6, ".types") == 0)
239 * Load a mime.types file...
242 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->d_name
);
243 load_types(mime
, filename
);
250 * Read all the .convs files...
253 while ((dent
= readdir(dir
)) != NULL
)
255 if (NAMLEN(dent
) > 6 &&
256 strcmp(dent
->d_name
+ NAMLEN(dent
) - 6, ".convs") == 0)
259 * Load a mime.convs file...
262 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->d_name
);
263 load_convs(mime
, filename
);
270 #endif /* WIN32 || __EMX__ */
275 * 'mimeNew()' - Create a new, empty MIME database.
278 mime_t
* /* O - MIME database */
281 return ((mime_t
*)calloc(1, sizeof(mime_t
)));
286 * 'load_types()' - Load a xyz.types file...
290 load_types(mime_t
*mime
, /* I - MIME database */
291 char *filename
) /* I - Types file to load */
293 FILE *fp
; /* Types file */
294 int linelen
; /* Length of line */
295 char line
[65536], /* Input line from file */
296 *lineptr
, /* Current position in line */
297 super
[MIME_MAX_SUPER
], /* Super-type name */
298 type
[MIME_MAX_TYPE
], /* Type name */
299 *temp
; /* Temporary pointer */
300 mime_type_t
*typeptr
; /* New MIME type */
304 * First try to open the file...
307 if ((fp
= fopen(filename
, "r")) == NULL
)
311 * Then read each line from the file, skipping any comments in the file...
314 while (fgets(line
, sizeof(line
), fp
) != NULL
)
316 linelen
= strlen(line
);
319 * While the last character in the line is a backslash, continue on to the
320 * next line (and the next, etc.)
323 if (line
[linelen
- 1] == '\n')
325 line
[linelen
- 1] = '\0';
329 while (line
[linelen
- 1] == '\\')
333 if (fgets(line
+ linelen
, sizeof(line
) - linelen
, fp
) == NULL
)
334 line
[linelen
] = '\0';
337 linelen
+= strlen(line
+ linelen
);
338 if (line
[linelen
- 1] == '\n')
340 line
[linelen
- 1] = '\0';
347 * Skip blank lines and lines starting with a #...
350 if (line
[0] == '\n' || line
[0] == '#')
354 * Extract the super-type and type names from the beginning of the line.
360 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
361 (temp
- super
+ 1) < MIME_MAX_SUPER
)
362 *temp
++ = tolower(*lineptr
++);
372 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
373 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
374 *temp
++ = tolower(*lineptr
++);
379 * Add the type and rules to the MIME database...
382 typeptr
= mimeAddType(mime
, super
, type
);
383 mimeAddTypeRule(typeptr
, lineptr
);
391 * 'load_convs()' - Load a xyz.convs file...
395 load_convs(mime_t
*mime
, /* I - MIME database */
396 char *filename
) /* I - Convs file to load */
398 int i
; /* Looping var */
399 FILE *fp
; /* Convs file */
400 char line
[1024], /* Input line from file */
401 *lineptr
, /* Current position in line */
402 super
[MIME_MAX_SUPER
], /* Super-type name */
403 type
[MIME_MAX_TYPE
], /* Type name */
404 *temp
, /* Temporary pointer */
405 *filter
; /* Filter program */
406 mime_type_t
**temptype
, /* MIME type looping var */
407 *dsttype
; /* Destination MIME type */
408 int cost
; /* Cost of filter */
412 * First try to open the file...
415 if ((fp
= fopen(filename
, "r")) == NULL
)
419 * Then read each line from the file, skipping any comments in the file...
422 while (fgets(line
, sizeof(line
), fp
) != NULL
)
425 * Skip blank lines and lines starting with a #...
428 if (line
[0] == '\n' || line
[0] == '#')
432 * Extract the destination super-type and type names from the middle of
437 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
440 while (*lineptr
== ' ' || *lineptr
== '\t')
445 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
446 (temp
- super
+ 1) < MIME_MAX_SUPER
)
447 *temp
++ = tolower(*lineptr
++);
457 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
458 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
459 *temp
++ = tolower(*lineptr
++);
463 if (*lineptr
== '\0' || *lineptr
== '\n')
466 if ((dsttype
= mimeType(mime
, super
, type
)) == NULL
)
470 * Then get the cost and filter program...
473 while (*lineptr
== ' ' || *lineptr
== '\t')
476 if (*lineptr
< '0' || *lineptr
> '9')
479 cost
= atoi(lineptr
);
481 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\0')
483 while (*lineptr
== ' ' || *lineptr
== '\t')
486 if (*lineptr
== '\0' || *lineptr
== '\n')
490 if (filter
[strlen(filter
) - 1] == '\n')
491 filter
[strlen(filter
) - 1] = '\0';
494 * Finally, get the source super-type and type names from the beginning of
495 * the line. We do it here so we can support wildcards...
501 while (*lineptr
!= '/' && *lineptr
!= '\n' && *lineptr
!= '\0' &&
502 (temp
- super
+ 1) < MIME_MAX_SUPER
)
503 *temp
++ = tolower(*lineptr
++);
513 while (*lineptr
!= ' ' && *lineptr
!= '\t' && *lineptr
!= '\n' &&
514 *lineptr
!= '\0' && (temp
- type
+ 1) < MIME_MAX_TYPE
)
515 *temp
++ = tolower(*lineptr
++);
519 if (strcmp(super
, "*") == 0 && strcmp(type
, "*") == 0)
522 * Force * / * to be "application/octet-stream"...
525 strcpy(super
, "application");
526 strcpy(type
, "octet-stream");
530 * Add the filter to the MIME database, supporting wildcards as needed...
533 for (temptype
= mime
->types
, i
= 0; i
< mime
->num_types
; i
++, temptype
++)
534 if ((super
[0] == '*' || strcmp((*temptype
)->super
, super
) == 0) &&
535 (type
[0] == '*' || strcmp((*temptype
)->type
, type
) == 0))
536 mimeAddFilter(mime
, *temptype
, dsttype
, cost
, filter
);
544 * 'delete_rules()' - Free all memory for the given rule tree.
548 delete_rules(mime_magic_t
*rules
) /* I - Rules to free */
550 mime_magic_t
*next
; /* Next rule to free */
554 * Free the rules list, descending recursively to free any child rules.
557 while (rules
!= NULL
)
561 if (rules
->child
!= NULL
)
562 delete_rules(rules
->child
);
571 * End of "$Id: mime.c,v 1.7 2001/01/22 15:04:01 mike Exp $".