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