#include <stdio.h>
#include <stdlib.h>
#include <cups/string.h>
#include "mime.h"
static void print_rules(mime_magic_t *rules);
int
main(int argc,
char *argv[])
{
int i, j;
const char *filter_path;
char super[MIME_MAX_SUPER],
type[MIME_MAX_TYPE];
int compression;
mime_t *mime;
mime_type_t *src,
*dst,
**types;
mime_filter_t *filters;
int num_filters;
mime = NULL;
src = NULL;
dst = NULL;
filter_path = "../filter";
for (i = 1; i < argc; i ++)
if (strcmp(argv[i], "-d") == 0)
{
i ++;
if (i < argc)
mime = mimeLoad(argv[i], filter_path);
}
else if (strcmp(argv[i], "-f") == 0)
{
i ++;
if (i < argc)
filter_path = argv[i];
}
else if (src == NULL)
{
if (!mime)
mime = mimeLoad("../conf", filter_path);
src = mimeFileType(mime, argv[i], &compression);
if (src != NULL)
printf("%s: %s/%s%s\n", argv[i], src->super, src->type,
compression ? " (gzipped)" : "");
else
{
printf("%s: unknown\n", argv[i]);
if (mime)
mimeDelete(mime);
return (1);
}
}
else
{
sscanf(argv[i], "%15[^/]/%31s", super, type);
dst = mimeType(mime, super, type);
filters = mimeFilter(mime, src, dst, &num_filters, NULL);
if (filters == NULL)
{
printf("No filters to convert from %s/%s to %s.\n", src->super,
src->type, argv[i]);
}
else
{
for (j = 0; j < num_filters; j ++)
if (j < (num_filters - 1))
printf("%s | ", filters[j].filter);
else
puts(filters[j].filter);
free(filters);
}
}
if (!mime)
mime = mimeLoad("../conf", filter_path);
if (src == NULL)
{
puts("MIME database types:");
for (i = 0, types = mime->types; i < mime->num_types; i ++, types ++)
{
printf("\t%s/%s:\n", (*types)->super, (*types)->type);
print_rules((*types)->rules);
puts("");
}
puts("");
puts("MIME database filters:");
for (i = 0, filters = mime->filters; i < mime->num_filters; i ++, filters ++)
printf("\t%s/%s to %s/%s: %s (%d)\n",
filters->src->super, filters->src->type,
filters->dst->super, filters->dst->type,
filters->filter, filters->cost);
}
return (0);
}
static void
print_rules(mime_magic_t *rules)
{
int i;
static char indent[255] = "\t";
if (rules == NULL)
return;
while (rules != NULL)
{
printf("%s[%p] ", indent, rules);
if (rules->invert)
printf("NOT ");
switch (rules->op)
{
case MIME_MAGIC_MATCH :
printf("match(%s)", rules->value.matchv);
break;
case MIME_MAGIC_LOCALE :
printf("locale(%s)", rules->value.localev);
break;
case MIME_MAGIC_ASCII :
printf("ascii(%d,%d)", rules->offset, rules->length);
break;
case MIME_MAGIC_PRINTABLE :
printf("printable(%d,%d)", rules->offset, rules->length);
break;
case MIME_MAGIC_STRING :
printf("string(%d,", rules->offset);
for (i = 0; i < rules->length; i ++)
if (rules->value.stringv[i] < ' ' ||
rules->value.stringv[i] > 126)
printf("<%02X>", rules->value.stringv[i]);
else
putchar(rules->value.stringv[i]);
putchar(')');
break;
case MIME_MAGIC_CHAR :
printf("char(%d,%d)", rules->offset, rules->value.charv);
break;
case MIME_MAGIC_SHORT :
printf("short(%d,%d)", rules->offset, rules->value.shortv);
break;
case MIME_MAGIC_INT :
printf("int(%d,%d)", rules->offset, rules->value.intv);
break;
case MIME_MAGIC_CONTAINS :
printf("contains(%d,%d,", rules->offset, rules->region);
for (i = 0; i < rules->length; i ++)
if (rules->value.stringv[i] < ' ' ||
rules->value.stringv[i] > 126)
printf("<%02X>", rules->value.stringv[i]);
else
putchar(rules->value.stringv[i]);
putchar(')');
break;
default :
break;
}
if (rules->child != NULL)
{
if (rules->op == MIME_MAGIC_OR)
puts("OR (");
else
puts("AND (");
strcat(indent, "\t");
print_rules(rules->child);
indent[strlen(indent) - 1] = '\0';
printf("%s)\n", indent);
}
else
putchar('\n');
rules = rules->next;
}
}