/*
- * "$Id: type.c 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: type.c 5052 2006-02-02 16:21:13Z mike $"
*
* MIME typing routines for the Common UNIX Printing System (CUPS).
*
#include <cups/debug.h>
+/*
+ * Local types...
+ */
+
+typedef struct _mime_filebuf_s /**** File buffer for MIME typing ****/
+{
+ cups_file_t *fp; /* File pointer */
+ int offset, /* Offset in file */
+ length; /* Length of buffered data */
+ unsigned char buffer[MIME_MAX_BUFFER];/* Buffered data */
+} _mime_filebuf_t;
+
+
/*
* Local functions...
*/
static int compare_types(mime_type_t *t0, mime_type_t *t1);
-static int checkrules(const char *, cups_file_t *, mime_magic_t *);
-static int patmatch(const char *, const char *);
+static int checkrules(const char *filename, _mime_filebuf_t *fb,
+ mime_magic_t *rules);
+static int patmatch(const char *s, const char *pat);
/*
else if (*rule == '+' && current != NULL)
{
if (logic != MIME_MAGIC_AND &&
- current != NULL && current->prev != NULL && current->prev->prev != NULL)
+ current != NULL && current->prev != NULL &&
+ current->prev->prev != NULL)
{
/*
* OK, we have more than 1 rule in the current tree level... Make a
* Read an extension name or a function...
*/
- for (ptr = name; isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1);)
+ ptr = name;
+ while (isalnum(*rule & 255) && (ptr - name) < (sizeof(name) - 1))
*ptr++ = *rule++;
*ptr = '\0';
mime_type_t * /* O - Type of file */
mimeFileType(mime_t *mime, /* I - MIME database */
- const char *pathname, /* I - Name of file to check */
+ const char *pathname, /* I - Name of file to check on disk */
+ const char *filename, /* I - Original filename or NULL */
int *compression) /* O - Is the file compressed? */
{
- cups_file_t *fp; /* File pointer */
- mime_type_t *type; /* File type */
- const char *filename; /* Base filename of file */
+ _mime_filebuf_t fb; /* File buffer */
+ const char *base; /* Base filename of file */
+ mime_type_t *type; /* File type */
- DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", compression=%p)\n",
- mime, pathname ? pathname : "(nil)", compression));
+ DEBUG_printf(("mimeFileType(mime=%p, pathname=\"%s\", basename=\"%s\", "
+ "compression=%p)\n",
+ mime, pathname ? pathname : "(nil)",
+ filename ? filename : "(nil)",
+ basenamecompression));
/*
* Range check input parameters...
* Try to open the file...
*/
- if ((fp = cupsFileOpen(pathname, "r")) == NULL)
+ if ((fb.fp = cupsFileOpen(pathname, "r")) == NULL)
return (NULL);
+ fb.offset = -1;
+ fb.length = 0;
+
/*
- * Figure out the filename (without directory portion)...
+ * Figure out the base filename (without directory portion)...
*/
- if ((filename = strrchr(pathname, '/')) != NULL)
- filename ++;
+ if (filename)
+ {
+ if ((base = strrchr(filename, '/')) != NULL)
+ base ++;
+ else
+ filename = filename;
+ }
+ else if ((base = strrchr(pathname, '/')) != NULL)
+ base ++;
else
filename = pathname;
for (type = (mime_type_t *)cupsArrayFirst(mime->types);
type;
type = (mime_type_t *)cupsArrayNext(mime->types))
- if (checkrules(filename, fp, type->rules))
+ if (checkrules(base, &fb, type->rules))
break;
/*
*/
if (compression)
- *compression = cupsFileCompression(fp);
+ *compression = cupsFileCompression(fb.fp);
- cupsFileClose(fp);
+ cupsFileClose(fb.fp);
return (type);
}
*/
static int /* O - 1 if match, 0 if no match */
-checkrules(const char *filename, /* I - Filename */
- cups_file_t *fp, /* I - File to check */
- mime_magic_t *rules) /* I - Rules to check */
+checkrules(const char *filename, /* I - Filename */
+ _mime_filebuf_t *fb, /* I - File to check */
+ mime_magic_t *rules) /* I - Rules to check */
{
int n; /* Looping var */
int region; /* Region to look at */
result, /* Result of test */
intv; /* Integer value */
short shortv; /* Short value */
- unsigned char buffer[MIME_MAX_BUFFER],/* Input buffer */
- *bufptr; /* Current buffer position */
- int bufoffset, /* Offset in file for buffer */
- buflength; /* Length of data in buffer */
+ unsigned char *bufptr; /* Pointer into buffer */
#ifdef DEBUG
const char * const debug_tests[] = /* Test names... */
{
"OR", /* Logical OR of all children */
"MATCH", /* Filename match */
"ASCII", /* ASCII characters in range */
- "PRINTABLE", /* Printable characters (32-255) in range */
+ "PRINTABLE", /* Printable characters (32-255) */
"STRING", /* String matches */
"CHAR", /* Character/byte matches */
"SHORT", /* Short/16-bit word matches */
else
logic = rules->parent->op;
- bufoffset = -1;
- buflength = 0;
- result = 0;
+ result = 0;
while (rules != NULL)
{
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* Test for ASCII printable characters plus standard control chars.
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
- n = bufoffset + buflength - rules->offset;
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
+ n = fb->offset + fb->length - rules->offset;
else
n = rules->length;
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
while (n > 0)
if ((*bufptr >= 32 && *bufptr <= 126) ||
(*bufptr >= 8 && *bufptr <= 13) ||
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* Test for 8-bit printable characters plus standard control chars.
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
- n = bufoffset + buflength - rules->offset;
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
+ n = fb->offset + fb->length - rules->offset;
else
n = rules->length;
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
while (n > 0)
if (*bufptr >= 128 ||
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
- DEBUG_printf((" loaded %d byte buffer at %d, starts with \"%c%c%c%c\"...\n",
- buflength, bufoffset, buffer[0], buffer[1],
- buffer[2], buffer[3]));
+ DEBUG_printf((" loaded %d byte fb->buffer at %d, starts "
+ "with \"%c%c%c%c\"...\n",
+ fb->length, fb->offset, fb->buffer[0], fb->buffer[1],
+ fb->buffer[2], fb->buffer[3]));
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (memcmp(buffer + rules->offset - bufoffset,
+ result = (memcmp(fb->buffer + rules->offset - fb->offset,
rules->value.stringv, rules->length) == 0);
DEBUG_printf((" result=%d\n", result));
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->length) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->length) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
- result = (strncasecmp((char *)buffer + rules->offset - bufoffset,
+ result = (strncasecmp((char *)fb->buffer + rules->offset -
+ fb->offset,
rules->value.stringv, rules->length) == 0);
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset)
+ if (fb->offset < 0 || rules->offset < fb->offset)
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 1)
+ if (fb->length < 1)
result = 0;
else
- result = (buffer[rules->offset - bufoffset] == rules->value.charv);
+ result = (fb->buffer[rules->offset - fb->offset] ==
+ rules->value.charv);
break;
case MIME_MAGIC_SHORT :
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + 2) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + 2) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 2)
+ if (fb->length < 2)
result = 0;
else
{
- bufptr = buffer + rules->offset - bufoffset;
+ bufptr = fb->buffer + rules->offset - fb->offset;
shortv = (bufptr[0] << 8) | bufptr[1];
result = (shortv == rules->value.shortv);
}
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + 4) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + 4) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* can't match...
*/
- if (buflength < 4)
+ if (fb->length < 4)
result = 0;
else
{
- bufptr = buffer + rules->offset - bufoffset;
- intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) | bufptr[2]) << 8) |
- bufptr[3];;
+ bufptr = fb->buffer + rules->offset - fb->offset;
+ intv = (((((bufptr[0] << 8) | bufptr[1]) << 8) |
+ bufptr[2]) << 8) | bufptr[3];
result = (intv == rules->value.intv);
}
break;
case MIME_MAGIC_LOCALE :
#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__)
- result = (strcmp(rules->value.localev, setlocale(LC_ALL, "")) == 0);
+ result = (strcmp(rules->value.localev,
+ setlocale(LC_ALL, "")) == 0);
#else
- result = (strcmp(rules->value.localev, setlocale(LC_MESSAGES, "")) == 0);
+ result = (strcmp(rules->value.localev,
+ setlocale(LC_MESSAGES, "")) == 0);
#endif /* __APPLE__ */
break;
* Load the buffer if necessary...
*/
- if (bufoffset < 0 || rules->offset < bufoffset ||
- (rules->offset + rules->region) > (bufoffset + buflength))
+ if (fb->offset < 0 || rules->offset < fb->offset ||
+ (rules->offset + rules->region) > (fb->offset + fb->length))
{
/*
* Reload file buffer...
*/
- cupsFileSeek(fp, rules->offset);
- buflength = cupsFileRead(fp, (char *)buffer, sizeof(buffer));
- bufoffset = rules->offset;
+ cupsFileSeek(fb->fp, rules->offset);
+ fb->length = cupsFileRead(fb->fp, (char *)fb->buffer,
+ sizeof(fb->buffer));
+ fb->offset = rules->offset;
}
/*
* short then don't compare - it can't match...
*/
- if ((rules->offset + rules->length) > (bufoffset + buflength))
+ if ((rules->offset + rules->length) > (fb->offset + fb->length))
result = 0;
else
{
- if (buflength > rules->region)
+ if (fb->length > rules->region)
region = rules->region - rules->length;
else
- region = buflength - rules->length;
+ region = fb->length - rules->length;
for (n = 0; n < region; n ++)
- if ((result = (memcmp(buffer + rules->offset - bufoffset + n,
- rules->value.stringv, rules->length) == 0)) != 0)
+ if ((result = (memcmp(fb->buffer + rules->offset - fb->offset + n,
+ rules->value.stringv,
+ rules->length) == 0)) != 0)
break;
}
break;
default :
if (rules->child != NULL)
- result = checkrules(filename, fp, rules->child);
+ result = checkrules(filename, fb, rules->child);
else
result = 0;
break;
pat ++;
if (*pat == '\0')
- return (1); /* Last pattern char is *, so everything matches now... */
+ return (1); /* Last pattern char is *, so everything matches... */
/*
* Test all remaining combinations until we get to the end of the string.
}
/*
- * Done parsing the pattern and string; return 1 if the last character matches
- * and 0 otherwise...
+ * Done parsing the pattern and string; return 1 if the last character
+ * matches and 0 otherwise...
*/
return (*s == *pat);
/*
- * End of "$Id: type.c 4970 2006-01-24 14:05:45Z mike $".
+ * End of "$Id: type.c 5052 2006-02-02 16:21:13Z mike $".
*/