]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/testmime.c
Import CUPS v2.0b1
[thirdparty/cups.git] / scheduler / testmime.c
CommitLineData
ef416fc2 1/*
1a18c85c 2 * "$Id: testmime.c 11558 2014-02-06 18:33:34Z msweet $"
ef416fc2 3 *
1a18c85c 4 * MIME test program for CUPS.
ef416fc2 5 *
1a18c85c
MS
6 * Copyright 2007-2014 by Apple Inc.
7 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
ef416fc2 8 *
1a18c85c
MS
9 * These coded instructions, statements, and computer programs are the
10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 */
15
16/*
17 * Include necessary headers...
18 */
19
71e16022 20#include <cups/string-private.h>
4400e98d 21#include <cups/dir.h>
22c9029b
MS
22#include <cups/debug-private.h>
23#include <cups/ppd-private.h>
71e16022 24#include "mime.h"
ef416fc2 25
26
27/*
28 * Local functions...
29 */
30
22c9029b
MS
31static void add_ppd_filter(mime_t *mime, mime_type_t *filtertype,
32 const char *filter);
33static void add_ppd_filters(mime_t *mime, ppd_file_t *ppd);
4400e98d 34static void print_rules(mime_magic_t *rules);
35static void type_dir(mime_t *mime, const char *dirname);
ef416fc2 36
37
38/*
39 * 'main()' - Main entry for the test program.
40 */
41
42int /* O - Exit status */
43main(int argc, /* I - Number of command-line args */
44 char *argv[]) /* I - Command-line arguments */
45{
fa73b229 46 int i; /* Looping vars */
ef416fc2 47 const char *filter_path; /* Filter path */
48 char super[MIME_MAX_SUPER], /* Super-type name */
49 type[MIME_MAX_TYPE]; /* Type name */
50 int compression; /* Compression of file */
fa73b229 51 int cost; /* Cost of filters */
ef416fc2 52 mime_t *mime; /* MIME database */
53 mime_type_t *src, /* Source type */
fa73b229 54 *dst; /* Destination type */
22c9029b
MS
55 struct stat srcinfo; /* Source information */
56 ppd_file_t *ppd; /* PPD file */
fa73b229 57 cups_array_t *filters; /* Filters for the file */
58 mime_filter_t *filter; /* Current filter */
ef416fc2 59
60
61 mime = NULL;
62 src = NULL;
63 dst = NULL;
22c9029b
MS
64 ppd = NULL;
65 filter_path = "../filter:" CUPS_SERVERBIN "/filter";
66
67 srcinfo.st_size = 0;
ef416fc2 68
69 for (i = 1; i < argc; i ++)
fa73b229 70 if (!strcmp(argv[i], "-d"))
ef416fc2 71 {
72 i ++;
73
74 if (i < argc)
22c9029b 75 {
ef416fc2 76 mime = mimeLoad(argv[i], filter_path);
22c9029b
MS
77
78 if (ppd)
79 add_ppd_filters(mime, ppd);
80 }
ef416fc2 81 }
fa73b229 82 else if (!strcmp(argv[i], "-f"))
ef416fc2 83 {
84 i ++;
85
86 if (i < argc)
87 filter_path = argv[i];
88 }
22c9029b
MS
89 else if (!strcmp(argv[i], "-p"))
90 {
91 i ++;
92
93 if (i < argc)
94 {
95 ppd = ppdOpenFile(argv[i]);
96
97 if (mime)
98 add_ppd_filters(mime, ppd);
99 }
100 }
fa73b229 101 else if (!src)
ef416fc2 102 {
103 if (!mime)
104 mime = mimeLoad("../conf", filter_path);
105
22c9029b
MS
106 if (ppd)
107 add_ppd_filters(mime, ppd);
108
4400e98d 109 src = mimeFileType(mime, argv[i], NULL, &compression);
22c9029b 110 stat(argv[i], &srcinfo);
ef416fc2 111
fa73b229 112 if (src)
ef416fc2 113 printf("%s: %s/%s%s\n", argv[i], src->super, src->type,
114 compression ? " (gzipped)" : "");
f301802f 115 else if ((src = mimeType(mime, "application", "octet-stream")) != NULL)
116 printf("%s: application/octet-stream\n", argv[i]);
ef416fc2 117 else
118 {
119 printf("%s: unknown\n", argv[i]);
120 if (mime)
121 mimeDelete(mime);
122 return (1);
123 }
124 }
125 else
126 {
c5b24bfa 127 sscanf(argv[i], "%15[^/]/%255s", super, type);
ef416fc2 128 dst = mimeType(mime, super, type);
129
1a18c85c 130 filters = mimeFilter2(mime, src, (size_t)srcinfo.st_size, dst, &cost);
ef416fc2 131
fa73b229 132 if (!filters)
ef416fc2 133 {
134 printf("No filters to convert from %s/%s to %s.\n", src->super,
135 src->type, argv[i]);
136 }
137 else
138 {
22c9029b 139 int first = 1; /* First filter shown? */
ef416fc2 140
22c9029b 141 printf("Filter cost = %d\n", cost);
fa73b229 142
22c9029b 143 for (filter = (mime_filter_t *)cupsArrayFirst(filters);
fa73b229 144 filter;
145 filter = (mime_filter_t *)cupsArrayNext(filters))
22c9029b
MS
146 {
147 if (!strcmp(filter->filter, "-"))
148 continue;
149
150 if (first)
151 {
152 first = 0;
153 fputs(filter->filter, stdout);
154 }
155 else
156 printf(" | %s", filter->filter);
157 }
fa73b229 158
159 putchar('\n');
160
161 cupsArrayDelete(filters);
ef416fc2 162 }
163 }
164
165 if (!mime)
22c9029b 166 {
ef416fc2 167 mime = mimeLoad("../conf", filter_path);
22c9029b
MS
168 if (ppd)
169 add_ppd_filters(mime, ppd);
170 }
ef416fc2 171
fa73b229 172 if (!src)
ef416fc2 173 {
174 puts("MIME database types:");
fa73b229 175 for (src = mimeFirstType(mime); src; src = mimeNextType(mime))
ef416fc2 176 {
c168a833 177 printf("\t%s/%s (%d):\n", src->super, src->type, src->priority);
fa73b229 178 print_rules(src->rules);
ef416fc2 179 puts("");
180 }
181
182 puts("");
183
184 puts("MIME database filters:");
fa73b229 185 for (filter = mimeFirstFilter(mime); filter; filter = mimeNextFilter(mime))
ef416fc2 186 printf("\t%s/%s to %s/%s: %s (%d)\n",
fa73b229 187 filter->src->super, filter->src->type,
188 filter->dst->super, filter->dst->type,
189 filter->filter, filter->cost);
4400e98d 190
f301802f 191 type_dir(mime, "../doc");
ef416fc2 192 }
193
194 return (0);
195}
196
197
22c9029b
MS
198/*
199 * 'add_printer_filter()' - Add a printer filter from a PPD.
200 */
201
202static void
203add_ppd_filter(mime_t *mime, /* I - MIME database */
204 mime_type_t *filtertype, /* I - Filter or prefilter MIME type */
205 const char *filter) /* I - Filter to add */
206{
207 char super[MIME_MAX_SUPER], /* Super-type for filter */
208 type[MIME_MAX_TYPE], /* Type for filter */
209 dsuper[MIME_MAX_SUPER], /* Destination super-type for filter */
210 dtype[MIME_MAX_TYPE], /* Destination type for filter */
211 dest[MIME_MAX_SUPER + MIME_MAX_TYPE + 2],
212 /* Destination super/type */
213 program[1024]; /* Program/filter name */
214 int cost; /* Cost of filter */
215 size_t maxsize = 0; /* Maximum supported file size */
216 mime_type_t *temptype, /* MIME type looping var */
217 *desttype; /* Destination MIME type */
218 mime_filter_t *filterptr; /* MIME filter */
219
220
221 DEBUG_printf(("add_ppd_filter(mime=%p, filtertype=%p(%s/%s), filter=\"%s\")",
222 mime, filtertype, filtertype->super, filtertype->type, filter));
223
224 /*
225 * Parse the filter string; it should be in one of the following formats:
226 *
227 * source/type cost program
228 * source/type cost maxsize(nnnn) program
229 * source/type dest/type cost program
230 * source/type dest/type cost maxsize(nnnn) program
231 */
232
233 if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
234 super, type, dsuper, dtype, &cost, program) == 6)
235 {
236 snprintf(dest, sizeof(dest), "test/%s/%s", dsuper, dtype);
237
238 if ((desttype = mimeType(mime, "printer", dest)) == NULL)
239 desttype = mimeAddType(mime, "printer", dest);
240 }
241 else
242 {
243 if (sscanf(filter, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost,
244 program) == 4)
245 {
246 desttype = filtertype;
247 }
248 else
249 {
250 printf("testmime: Invalid filter string \"%s\".\n", filter);
251 return;
252 }
253 }
254
255 if (!strncmp(program, "maxsize(", 8))
256 {
257 char *ptr; /* Pointer into maxsize(nnnn) program */
258
1a18c85c 259 maxsize = (size_t)strtoll(program + 8, &ptr, 10);
22c9029b
MS
260
261 if (*ptr != ')')
262 {
263 printf("testmime: Invalid filter string \"%s\".\n", filter);
264 return;
265 }
266
267 ptr ++;
268 while (_cups_isspace(*ptr))
269 ptr ++;
270
271 _cups_strcpy(program, ptr);
272 }
273
274 /*
275 * Add the filter to the MIME database, supporting wildcards as needed...
276 */
277
278 for (temptype = mimeFirstType(mime);
279 temptype;
280 temptype = mimeNextType(mime))
88f9aafc
MS
281 if (((super[0] == '*' && _cups_strcasecmp(temptype->super, "printer")) ||
282 !_cups_strcasecmp(temptype->super, super)) &&
283 (type[0] == '*' || !_cups_strcasecmp(temptype->type, type)))
22c9029b
MS
284 {
285 if (desttype != filtertype)
286 {
287 DEBUG_printf(("add_ppd_filter: Adding filter %s/%s %s/%s %d %s",
288 temptype->super, temptype->type, desttype->super,
289 desttype->type, cost, program));
290 filterptr = mimeAddFilter(mime, temptype, desttype, cost, program);
291
292 if (!mimeFilterLookup(mime, desttype, filtertype))
293 {
294 DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s 0 -",
295 desttype->super, desttype->type, filtertype->super,
296 filtertype->type));
771bd8cb 297 mimeAddFilter(mime, desttype, filtertype, 0, "-");
22c9029b
MS
298 }
299 }
300 else
301 {
302 DEBUG_printf(("add_printer_filter: Adding filter %s/%s %s/%s %d %s",
303 temptype->super, temptype->type, filtertype->super,
304 filtertype->type, cost, program));
305 filterptr = mimeAddFilter(mime, temptype, filtertype, cost, program);
306 }
307
308 if (filterptr)
309 filterptr->maxsize = maxsize;
310 }
311}
312
313
314/*
315 * 'add_ppd_filters()' - Add all filters from a PPD.
316 */
317
318static void
319add_ppd_filters(mime_t *mime, /* I - MIME database */
320 ppd_file_t *ppd) /* I - PPD file */
321{
322 _ppd_cache_t *pc; /* Cache data for PPD */
323 const char *value; /* Filter definition value */
324 mime_type_t *filter, /* Filter type */
325 *prefilter; /* Pre-filter type */
326
327
328 pc = _ppdCacheCreateWithPPD(ppd);
329 if (!pc)
330 return;
331
332 filter = mimeAddType(mime, "printer", "test");
333
334 if (pc->filters)
335 {
336 for (value = (const char *)cupsArrayFirst(pc->filters);
337 value;
338 value = (const char *)cupsArrayNext(pc->filters))
339 add_ppd_filter(mime, filter, value);
340 }
341 else
342 {
343 add_ppd_filter(mime, filter, "application/vnd.cups-raw 0 -");
344 add_ppd_filter(mime, filter, "application/vnd.cups-postscript 0 -");
345 }
346
347 if (pc->prefilters)
348 {
349 prefilter = mimeAddType(mime, "prefilter", "test");
350
351 for (value = (const char *)cupsArrayFirst(pc->prefilters);
352 value;
353 value = (const char *)cupsArrayNext(pc->prefilters))
354 add_ppd_filter(mime, prefilter, value);
355 }
356}
357
358
ef416fc2 359/*
360 * 'print_rules()' - Print the rules for a file type...
361 */
362
363static void
364print_rules(mime_magic_t *rules) /* I - Rules to print */
365{
366 int i; /* Looping var */
367 static char indent[255] = "\t"; /* Indentation for rules */
368
369
370 if (rules == NULL)
371 return;
372
373 while (rules != NULL)
374 {
375 printf("%s[%p] ", indent, rules);
376
377 if (rules->invert)
378 printf("NOT ");
379
380 switch (rules->op)
381 {
382 case MIME_MAGIC_MATCH :
383 printf("match(%s)", rules->value.matchv);
384 break;
385 case MIME_MAGIC_LOCALE :
386 printf("locale(%s)", rules->value.localev);
387 break;
388 case MIME_MAGIC_ASCII :
389 printf("ascii(%d,%d)", rules->offset, rules->length);
390 break;
391 case MIME_MAGIC_PRINTABLE :
392 printf("printable(%d,%d)", rules->offset, rules->length);
393 break;
394 case MIME_MAGIC_STRING :
395 printf("string(%d,", rules->offset);
396 for (i = 0; i < rules->length; i ++)
397 if (rules->value.stringv[i] < ' ' ||
398 rules->value.stringv[i] > 126)
399 printf("<%02X>", rules->value.stringv[i]);
400 else
401 putchar(rules->value.stringv[i]);
402 putchar(')');
403 break;
404 case MIME_MAGIC_CHAR :
405 printf("char(%d,%d)", rules->offset, rules->value.charv);
406 break;
407 case MIME_MAGIC_SHORT :
408 printf("short(%d,%d)", rules->offset, rules->value.shortv);
409 break;
410 case MIME_MAGIC_INT :
411 printf("int(%d,%d)", rules->offset, rules->value.intv);
412 break;
413 case MIME_MAGIC_CONTAINS :
414 printf("contains(%d,%d,", rules->offset, rules->region);
415 for (i = 0; i < rules->length; i ++)
416 if (rules->value.stringv[i] < ' ' ||
417 rules->value.stringv[i] > 126)
418 printf("<%02X>", rules->value.stringv[i]);
419 else
420 putchar(rules->value.stringv[i]);
421 putchar(')');
422 break;
423 default :
424 break;
425 }
426
427 if (rules->child != NULL)
428 {
429 if (rules->op == MIME_MAGIC_OR)
430 puts("OR (");
431 else
432 puts("AND (");
433
434 strcat(indent, "\t");
435 print_rules(rules->child);
436 indent[strlen(indent) - 1] = '\0';
437 printf("%s)\n", indent);
438 }
439 else
440 putchar('\n');
441
442 rules = rules->next;
443 }
444}
445
446
447/*
4400e98d 448 * 'type_dir()' - Show the MIME types for a given directory.
449 */
450
451static void
452type_dir(mime_t *mime, /* I - MIME database */
453 const char *dirname) /* I - Directory */
454{
455 cups_dir_t *dir; /* Directory */
456 cups_dentry_t *dent; /* Directory entry */
457 char filename[1024]; /* File to type */
458 mime_type_t *filetype; /* File type */
459 int compression; /* Compressed file? */
460 mime_type_t *pstype; /* application/vnd.cups-postscript */
461 cups_array_t *filters; /* Filters to pstype */
462 mime_filter_t *filter; /* Current filter */
463 int cost; /* Filter cost */
464
465
466 dir = cupsDirOpen(dirname);
467 if (!dir)
468 return;
469
470 pstype = mimeType(mime, "application", "vnd.cups-postscript");
471
472 while ((dent = cupsDirRead(dir)) != NULL)
473 {
f301802f 474 if (dent->filename[0] == '.')
475 continue;
476
4400e98d 477 snprintf(filename, sizeof(filename), "%s/%s", dirname, dent->filename);
478
479 if (S_ISDIR(dent->fileinfo.st_mode))
480 type_dir(mime, filename);
481
482 if (!S_ISREG(dent->fileinfo.st_mode))
483 continue;
484
485 filetype = mimeFileType(mime, filename, NULL, &compression);
486
487 if (filetype)
488 {
489 printf("%s: %s/%s%s\n", filename, filetype->super, filetype->type,
490 compression ? " (compressed)" : "");
491
bd7854cb 492 filters = mimeFilter(mime, filetype, pstype, &cost);
4400e98d 493
494 if (!filters)
495 puts(" No filters to convert application/vnd.cups-postscript.");
496 else
497 {
498 printf(" Filter cost = %d\n", cost);
499
500 filter = (mime_filter_t *)cupsArrayFirst(filters);
501 printf(" %s", filter->filter);
502
503 for (filter = (mime_filter_t *)cupsArrayNext(filters);
504 filter;
505 filter = (mime_filter_t *)cupsArrayNext(filters))
506 printf(" | %s", filter->filter);
507
508 putchar('\n');
509
510 cupsArrayDelete(filters);
511 }
512 }
513 else
514 printf("%s: unknown%s\n", filename, compression ? " (compressed)" : "");
515 }
516
517 cupsDirClose(dir);
518}
519
520
521/*
1a18c85c 522 * End of "$Id: testmime.c 11558 2014-02-06 18:33:34Z msweet $".
ef416fc2 523 */