]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/testmime.c
2 * MIME test program for CUPS.
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
11 * Include necessary headers...
14 #include <cups/string-private.h>
16 #include <cups/debug-private.h>
17 #include <cups/ppd-private.h>
25 static void add_ppd_filter(mime_t
*mime
, mime_type_t
*filtertype
,
27 static void add_ppd_filters(mime_t
*mime
, ppd_file_t
*ppd
);
28 static void print_rules(mime_magic_t
*rules
);
29 static void type_dir(mime_t
*mime
, const char *dirname
);
33 * 'main()' - Main entry for the test program.
36 int /* O - Exit status */
37 main(int argc
, /* I - Number of command-line args */
38 char *argv
[]) /* I - Command-line arguments */
40 int i
; /* Looping vars */
41 const char *filter_path
; /* Filter path */
42 char super
[MIME_MAX_SUPER
], /* Super-type name */
43 type
[MIME_MAX_TYPE
]; /* Type name */
44 int compression
; /* Compression of file */
45 int cost
; /* Cost of filters */
46 mime_t
*mime
; /* MIME database */
47 mime_type_t
*src
, /* Source type */
48 *dst
; /* Destination type */
49 struct stat srcinfo
; /* Source information */
50 ppd_file_t
*ppd
; /* PPD file */
51 cups_array_t
*filters
; /* Filters for the file */
52 mime_filter_t
*filter
; /* Current filter */
59 filter_path
= "../filter:" CUPS_SERVERBIN
"/filter";
63 for (i
= 1; i
< argc
; i
++)
64 if (!strcmp(argv
[i
], "-d"))
70 mime
= mimeLoad(argv
[i
], filter_path
);
73 add_ppd_filters(mime
, ppd
);
76 else if (!strcmp(argv
[i
], "-f"))
81 filter_path
= argv
[i
];
83 else if (!strcmp(argv
[i
], "-p"))
89 ppd
= ppdOpenFile(argv
[i
]);
92 add_ppd_filters(mime
, ppd
);
98 mime
= mimeLoad("../conf", filter_path
);
101 add_ppd_filters(mime
, ppd
);
103 src
= mimeFileType(mime
, argv
[i
], NULL
, &compression
);
104 stat(argv
[i
], &srcinfo
);
107 printf("%s: %s/%s%s\n", argv
[i
], src
->super
, src
->type
,
108 compression
? " (gzipped)" : "");
109 else if ((src
= mimeType(mime
, "application", "octet-stream")) != NULL
)
110 printf("%s: application/octet-stream\n", argv
[i
]);
113 printf("%s: unknown\n", argv
[i
]);
121 sscanf(argv
[i
], "%15[^/]/%255s", super
, type
);
122 dst
= mimeType(mime
, super
, type
);
124 filters
= mimeFilter2(mime
, src
, (size_t)srcinfo
.st_size
, dst
, &cost
);
128 printf("No filters to convert from %s/%s to %s.\n", src
->super
,
133 int first
= 1; /* First filter shown? */
135 printf("Filter cost = %d\n", cost
);
137 for (filter
= (mime_filter_t
*)cupsArrayFirst(filters
);
139 filter
= (mime_filter_t
*)cupsArrayNext(filters
))
141 if (!strcmp(filter
->filter
, "-"))
147 fputs(filter
->filter
, stdout
);
150 printf(" | %s", filter
->filter
);
155 cupsArrayDelete(filters
);
161 mime
= mimeLoad("../conf", filter_path
);
163 add_ppd_filters(mime
, ppd
);
168 puts("MIME database types:");
169 for (src
= mimeFirstType(mime
); src
; src
= mimeNextType(mime
))
171 printf("\t%s/%s (%d):\n", src
->super
, src
->type
, src
->priority
);
172 print_rules(src
->rules
);
178 puts("MIME database filters:");
179 for (filter
= mimeFirstFilter(mime
); filter
; filter
= mimeNextFilter(mime
))
180 printf("\t%s/%s to %s/%s: %s (%d)\n",
181 filter
->src
->super
, filter
->src
->type
,
182 filter
->dst
->super
, filter
->dst
->type
,
183 filter
->filter
, filter
->cost
);
185 type_dir(mime
, "../doc");
193 * 'add_printer_filter()' - Add a printer filter from a PPD.
197 add_ppd_filter(mime_t
*mime
, /* I - MIME database */
198 mime_type_t
*filtertype
, /* I - Filter or prefilter MIME type */
199 const char *filter
) /* I - Filter to add */
201 char super
[MIME_MAX_SUPER
], /* Super-type for filter */
202 type
[MIME_MAX_TYPE
], /* Type for filter */
203 dsuper
[MIME_MAX_SUPER
], /* Destination super-type for filter */
204 dtype
[MIME_MAX_TYPE
], /* Destination type for filter */
205 dest
[MIME_MAX_SUPER
+ MIME_MAX_TYPE
+ 2],
206 /* Destination super/type */
207 program
[1024]; /* Program/filter name */
208 int cost
; /* Cost of filter */
209 size_t maxsize
= 0; /* Maximum supported file size */
210 mime_type_t
*temptype
, /* MIME type looping var */
211 *desttype
; /* Destination MIME type */
212 mime_filter_t
*filterptr
; /* MIME filter */
216 * Parse the filter string; it should be in one of the following formats:
218 * source/type cost program
219 * source/type cost maxsize(nnnn) program
220 * source/type dest/type cost program
221 * source/type dest/type cost maxsize(nnnn) program
224 if (sscanf(filter
, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
225 super
, type
, dsuper
, dtype
, &cost
, program
) == 6)
227 snprintf(dest
, sizeof(dest
), "test/%s/%s", dsuper
, dtype
);
229 if ((desttype
= mimeType(mime
, "printer", dest
)) == NULL
)
230 desttype
= mimeAddType(mime
, "printer", dest
);
234 if (sscanf(filter
, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super
, type
, &cost
,
237 desttype
= filtertype
;
241 printf("testmime: Invalid filter string \"%s\".\n", filter
);
246 if (!strncmp(program
, "maxsize(", 8))
248 char *ptr
; /* Pointer into maxsize(nnnn) program */
250 maxsize
= (size_t)strtoll(program
+ 8, &ptr
, 10);
254 printf("testmime: Invalid filter string \"%s\".\n", filter
);
259 while (_cups_isspace(*ptr
))
262 _cups_strcpy(program
, ptr
);
266 * Add the filter to the MIME database, supporting wildcards as needed...
269 for (temptype
= mimeFirstType(mime
);
271 temptype
= mimeNextType(mime
))
272 if (((super
[0] == '*' && _cups_strcasecmp(temptype
->super
, "printer")) ||
273 !_cups_strcasecmp(temptype
->super
, super
)) &&
274 (type
[0] == '*' || !_cups_strcasecmp(temptype
->type
, type
)))
276 if (desttype
!= filtertype
)
278 filterptr
= mimeAddFilter(mime
, temptype
, desttype
, cost
, program
);
280 if (!mimeFilterLookup(mime
, desttype
, filtertype
))
281 mimeAddFilter(mime
, desttype
, filtertype
, 0, "-");
284 filterptr
= mimeAddFilter(mime
, temptype
, filtertype
, cost
, program
);
287 filterptr
->maxsize
= maxsize
;
293 * 'add_ppd_filters()' - Add all filters from a PPD.
297 add_ppd_filters(mime_t
*mime
, /* I - MIME database */
298 ppd_file_t
*ppd
) /* I - PPD file */
300 _ppd_cache_t
*pc
; /* Cache data for PPD */
301 const char *value
; /* Filter definition value */
302 mime_type_t
*filter
, /* Filter type */
303 *prefilter
; /* Pre-filter type */
306 pc
= _ppdCacheCreateWithPPD(ppd
);
310 filter
= mimeAddType(mime
, "printer", "test");
314 for (value
= (const char *)cupsArrayFirst(pc
->filters
);
316 value
= (const char *)cupsArrayNext(pc
->filters
))
317 add_ppd_filter(mime
, filter
, value
);
321 add_ppd_filter(mime
, filter
, "application/vnd.cups-raw 0 -");
322 add_ppd_filter(mime
, filter
, "application/vnd.cups-postscript 0 -");
327 prefilter
= mimeAddType(mime
, "prefilter", "test");
329 for (value
= (const char *)cupsArrayFirst(pc
->prefilters
);
331 value
= (const char *)cupsArrayNext(pc
->prefilters
))
332 add_ppd_filter(mime
, prefilter
, value
);
338 * 'print_rules()' - Print the rules for a file type...
342 print_rules(mime_magic_t
*rules
) /* I - Rules to print */
344 int i
; /* Looping var */
345 static char indent
[255] = "\t"; /* Indentation for rules */
351 while (rules
!= NULL
)
353 printf("%s[%p] ", indent
, rules
);
360 case MIME_MAGIC_MATCH
:
361 printf("match(%s)", rules
->value
.matchv
);
363 case MIME_MAGIC_LOCALE
:
364 printf("locale(%s)", rules
->value
.localev
);
366 case MIME_MAGIC_ASCII
:
367 printf("ascii(%d,%d)", rules
->offset
, rules
->length
);
369 case MIME_MAGIC_PRINTABLE
:
370 printf("printable(%d,%d)", rules
->offset
, rules
->length
);
372 case MIME_MAGIC_STRING
:
373 printf("string(%d,", rules
->offset
);
374 for (i
= 0; i
< rules
->length
; i
++)
375 if (rules
->value
.stringv
[i
] < ' ' ||
376 rules
->value
.stringv
[i
] > 126)
377 printf("<%02X>", rules
->value
.stringv
[i
]);
379 putchar(rules
->value
.stringv
[i
]);
382 case MIME_MAGIC_CHAR
:
383 printf("char(%d,%d)", rules
->offset
, rules
->value
.charv
);
385 case MIME_MAGIC_SHORT
:
386 printf("short(%d,%d)", rules
->offset
, rules
->value
.shortv
);
388 case MIME_MAGIC_INT
:
389 printf("int(%d,%d)", rules
->offset
, rules
->value
.intv
);
391 case MIME_MAGIC_CONTAINS
:
392 printf("contains(%d,%d,", rules
->offset
, rules
->region
);
393 for (i
= 0; i
< rules
->length
; i
++)
394 if (rules
->value
.stringv
[i
] < ' ' ||
395 rules
->value
.stringv
[i
] > 126)
396 printf("<%02X>", rules
->value
.stringv
[i
]);
398 putchar(rules
->value
.stringv
[i
]);
405 if (rules
->child
!= NULL
)
407 if (rules
->op
== MIME_MAGIC_OR
)
412 strcat(indent
, "\t");
413 print_rules(rules
->child
);
414 indent
[strlen(indent
) - 1] = '\0';
415 printf("%s)\n", indent
);
426 * 'type_dir()' - Show the MIME types for a given directory.
430 type_dir(mime_t
*mime
, /* I - MIME database */
431 const char *dirname
) /* I - Directory */
433 cups_dir_t
*dir
; /* Directory */
434 cups_dentry_t
*dent
; /* Directory entry */
435 char filename
[1024]; /* File to type */
436 mime_type_t
*filetype
; /* File type */
437 int compression
; /* Compressed file? */
438 mime_type_t
*pstype
; /* application/vnd.cups-postscript */
439 cups_array_t
*filters
; /* Filters to pstype */
440 mime_filter_t
*filter
; /* Current filter */
441 int cost
; /* Filter cost */
444 dir
= cupsDirOpen(dirname
);
448 pstype
= mimeType(mime
, "application", "vnd.cups-postscript");
450 while ((dent
= cupsDirRead(dir
)) != NULL
)
452 if (dent
->filename
[0] == '.')
455 snprintf(filename
, sizeof(filename
), "%s/%s", dirname
, dent
->filename
);
457 if (S_ISDIR(dent
->fileinfo
.st_mode
))
458 type_dir(mime
, filename
);
460 if (!S_ISREG(dent
->fileinfo
.st_mode
))
463 filetype
= mimeFileType(mime
, filename
, NULL
, &compression
);
467 printf("%s: %s/%s%s\n", filename
, filetype
->super
, filetype
->type
,
468 compression
? " (compressed)" : "");
470 filters
= mimeFilter(mime
, filetype
, pstype
, &cost
);
473 puts(" No filters to convert application/vnd.cups-postscript.");
476 printf(" Filter cost = %d\n", cost
);
478 filter
= (mime_filter_t
*)cupsArrayFirst(filters
);
479 printf(" %s", filter
->filter
);
481 for (filter
= (mime_filter_t
*)cupsArrayNext(filters
);
483 filter
= (mime_filter_t
*)cupsArrayNext(filters
))
484 printf(" | %s", filter
->filter
);
488 cupsArrayDelete(filters
);
492 printf("%s: unknown%s\n", filename
, compression
? " (compressed)" : "");