]>
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 */
215 DEBUG_printf(("add_ppd_filter(mime=%p, filtertype=%p(%s/%s), filter=\"%s\")",
216 mime
, filtertype
, filtertype
->super
, filtertype
->type
, filter
));
219 * Parse the filter string; it should be in one of the following formats:
221 * source/type cost program
222 * source/type cost maxsize(nnnn) program
223 * source/type dest/type cost program
224 * source/type dest/type cost maxsize(nnnn) program
227 if (sscanf(filter
, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
228 super
, type
, dsuper
, dtype
, &cost
, program
) == 6)
230 snprintf(dest
, sizeof(dest
), "test/%s/%s", dsuper
, dtype
);
232 if ((desttype
= mimeType(mime
, "printer", dest
)) == NULL
)
233 desttype
= mimeAddType(mime
, "printer", dest
);
237 if (sscanf(filter
, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super
, type
, &cost
,
240 desttype
= filtertype
;
244 printf("testmime: Invalid filter string \"%s\".\n", filter
);
249 if (!strncmp(program
, "maxsize(", 8))
251 char *ptr
; /* Pointer into maxsize(nnnn) program */
253 maxsize
= (size_t)strtoll(program
+ 8, &ptr
, 10);
257 printf("testmime: Invalid filter string \"%s\".\n", filter
);
262 while (_cups_isspace(*ptr
))
265 _cups_strcpy(program
, ptr
);
269 * Add the filter to the MIME database, supporting wildcards as needed...
272 for (temptype
= mimeFirstType(mime
);
274 temptype
= mimeNextType(mime
))
275 if (((super
[0] == '*' && _cups_strcasecmp(temptype
->super
, "printer")) ||
276 !_cups_strcasecmp(temptype
->super
, super
)) &&
277 (type
[0] == '*' || !_cups_strcasecmp(temptype
->type
, type
)))
279 if (desttype
!= filtertype
)
281 DEBUG_printf(("add_ppd_filter: Adding filter %s/%s %s/%s %d %s",
282 temptype
->super
, temptype
->type
, desttype
->super
,
283 desttype
->type
, cost
, program
));
284 filterptr
= mimeAddFilter(mime
, temptype
, desttype
, cost
, program
);
286 if (!mimeFilterLookup(mime
, desttype
, filtertype
))
288 DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s 0 -",
289 desttype
->super
, desttype
->type
, filtertype
->super
,
291 mimeAddFilter(mime
, desttype
, filtertype
, 0, "-");
296 DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s %d %s",
297 temptype
->super
, temptype
->type
, filtertype
->super
,
298 filtertype
->type
, cost
, program
));
299 filterptr
= mimeAddFilter(mime
, temptype
, filtertype
, cost
, program
);
303 filterptr
->maxsize
= maxsize
;
309 * 'add_ppd_filters()' - Add all filters from a PPD.
313 add_ppd_filters(mime_t
*mime
, /* I - MIME database */
314 ppd_file_t
*ppd
) /* I - PPD file */
316 _ppd_cache_t
*pc
; /* Cache data for PPD */
317 const char *value
; /* Filter definition value */
318 mime_type_t
*filter
, /* Filter type */
319 *prefilter
; /* Pre-filter type */
322 pc
= _ppdCacheCreateWithPPD(ppd
);
326 filter
= mimeAddType(mime
, "printer", "test");
330 for (value
= (const char *)cupsArrayFirst(pc
->filters
);
332 value
= (const char *)cupsArrayNext(pc
->filters
))
333 add_ppd_filter(mime
, filter
, value
);
337 add_ppd_filter(mime
, filter
, "application/vnd.cups-raw 0 -");
338 add_ppd_filter(mime
, filter
, "application/vnd.cups-postscript 0 -");
343 prefilter
= mimeAddType(mime
, "prefilter", "test");
345 for (value
= (const char *)cupsArrayFirst(pc
->prefilters
);
347 value
= (const char *)cupsArrayNext(pc
->prefilters
))
348 add_ppd_filter(mime
, prefilter
, value
);
354 * 'print_rules()' - Print the rules for a file type...
358 print_rules(mime_magic_t
*rules
) /* I - Rules to print */
360 int i
; /* Looping var */
361 static char indent
[255] = "\t"; /* Indentation for rules */
367 while (rules
!= NULL
)
369 printf("%s[%p] ", indent
, rules
);
376 case MIME_MAGIC_MATCH
:
377 printf("match(%s)", rules
->value
.matchv
);
379 case MIME_MAGIC_LOCALE
:
380 printf("locale(%s)", rules
->value
.localev
);
382 case MIME_MAGIC_ASCII
:
383 printf("ascii(%d,%d)", rules
->offset
, rules
->length
);
385 case MIME_MAGIC_PRINTABLE
:
386 printf("printable(%d,%d)", rules
->offset
, rules
->length
);
388 case MIME_MAGIC_STRING
:
389 printf("string(%d,", rules
->offset
);
390 for (i
= 0; i
< rules
->length
; i
++)
391 if (rules
->value
.stringv
[i
] < ' ' ||
392 rules
->value
.stringv
[i
] > 126)
393 printf("<%02X>", rules
->value
.stringv
[i
]);
395 putchar(rules
->value
.stringv
[i
]);
398 case MIME_MAGIC_CHAR
:
399 printf("char(%d,%d)", rules
->offset
, rules
->value
.charv
);
401 case MIME_MAGIC_SHORT
:
402 printf("short(%d,%d)", rules
->offset
, rules
->value
.shortv
);
404 case MIME_MAGIC_INT
:
405 printf("int(%d,%d)", rules
->offset
, rules
->value
.intv
);
407 case MIME_MAGIC_CONTAINS
:
408 printf("contains(%d,%d,", rules
->offset
, rules
->region
);
409 for (i
= 0; i
< rules
->length
; i
++)
410 if (rules
->value
.stringv
[i
] < ' ' ||
411 rules
->value
.stringv
[i
] > 126)
412 printf("<%02X>", rules
->value
.stringv
[i
]);
414 putchar(rules
->value
.stringv
[i
]);
421 if (rules
->child
!= NULL
)
423 if (rules
->op
== MIME_MAGIC_OR
)
428 strcat(indent
, "\t");
429 print_rules(rules
->child
);
430 indent
[strlen(indent
) - 1] = '\0';
431 printf("%s)\n", indent
);
442 * 'type_dir()' - Show the MIME types for a given directory.
446 type_dir(mime_t
*mime
, /* I - MIME database */
447 const char *dirname
) /* I - Directory */
449 cups_dir_t
*dir
; /* Directory */
450 cups_dentry_t
*dent
; /* Directory entry */
451 char filename
[1024]; /* File to type */
452 mime_type_t
*filetype
; /* File type */
453 int compression
; /* Compressed file? */
454 mime_type_t
*pstype
; /* application/vnd.cups-postscript */
455 cups_array_t
*filters
; /* Filters to pstype */
456 mime_filter_t
*filter
; /* Current filter */
457 int cost
; /* Filter cost */
460 dir
= cupsDirOpen(dirname
);
464 pstype
= mimeType(mime
, "application", "vnd.cups-postscript");
466 while ((dent
= cupsDirRead(dir
)) != NULL
)
468 if (dent
->filename
[0] == '.')
471 snprintf(filename
, sizeof(filename
), "%s/%s", dirname
, dent
->filename
);
473 if (S_ISDIR(dent
->fileinfo
.st_mode
))
474 type_dir(mime
, filename
);
476 if (!S_ISREG(dent
->fileinfo
.st_mode
))
479 filetype
= mimeFileType(mime
, filename
, NULL
, &compression
);
483 printf("%s: %s/%s%s\n", filename
, filetype
->super
, filetype
->type
,
484 compression
? " (compressed)" : "");
486 filters
= mimeFilter(mime
, filetype
, pstype
, &cost
);
489 puts(" No filters to convert application/vnd.cups-postscript.");
492 printf(" Filter cost = %d\n", cost
);
494 filter
= (mime_filter_t
*)cupsArrayFirst(filters
);
495 printf(" %s", filter
->filter
);
497 for (filter
= (mime_filter_t
*)cupsArrayNext(filters
);
499 filter
= (mime_filter_t
*)cupsArrayNext(filters
))
500 printf(" | %s", filter
->filter
);
504 cupsArrayDelete(filters
);
508 printf("%s: unknown%s\n", filename
, compression
? " (compressed)" : "");