]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/type.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / type.c
index 9aaa10ccde80e94e01e533c4860382b20a3aecd3..06afd235201c2d17d5d09c939770ef0d50a4334f 100644 (file)
@@ -1,25 +1,16 @@
 /*
- * "$Id: type.c 4970 2006-01-24 14:05:45Z mike $"
+ * "$Id: type.c 6649 2007-07-11 21:46:42Z mike $"
  *
  *   MIME typing routines for the Common UNIX Printing System (CUPS).
  *
+ *   Copyright 2007 by Apple Inc.
  *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products and are protected by Federal
- *   copyright law.  Distribution and use rights are outlined in the file
- *   "LICENSE.txt" which should have been included with this file.  If this
- *   file is missing or damaged please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *   property of Apple Inc. and are protected by Federal copyright
+ *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ *   which should have been included with this file.  If this file is
+ *   file is missing or damaged, see the license at "http://www.cups.org/".
  *
  * Contents:
  *
 #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);
 
 
 /*
@@ -182,7 +187,8 @@ mimeAddTypeRule(mime_type_t *mt,    /* I - Type to add to */
     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
@@ -271,7 +277,8 @@ mimeAddTypeRule(mime_type_t *mt,    /* I - Type to add to */
       * 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';
@@ -519,16 +526,20 @@ mimeAddTypeRule(mime_type_t *mt,  /* I - Type to add to */
 
 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\", filename=\"%s\", "
+                "compression=%p)\n",
+                mime, pathname ? pathname : "(nil)",
+               filename ? filename : "(nil)",
+               compression));
 
  /*
   * Range check input parameters...
@@ -541,15 +552,25 @@ mimeFileType(mime_t     *mime,            /* I - MIME database */
   * 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;
 
@@ -560,7 +581,7 @@ mimeFileType(mime_t     *mime,              /* I - MIME database */
   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;
 
  /*
@@ -568,9 +589,9 @@ mimeFileType(mime_t     *mime,              /* I - MIME database */
   */
 
   if (compression)
-    *compression = cupsFileCompression(fp);
+    *compression = cupsFileCompression(fb.fp);
 
-  cupsFileClose(fp);
+  cupsFileClose(fb.fp);
 
   return (type);
 }
@@ -629,9 +650,9 @@ compare_types(mime_type_t *t0,              /* I - First 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 */
@@ -639,10 +660,7 @@ checkrules(const char   *filename, /* I - Filename */
                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... */
                {
@@ -651,7 +669,7 @@ checkrules(const char   *filename,  /* I - Filename */
                  "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 */
@@ -663,8 +681,8 @@ checkrules(const char   *filename,  /* I - Filename */
 #endif /* DEBUG */
 
 
-  DEBUG_printf(("checkrules(filename=\"%s\", fp=%p, rules=%p)\n", filename,
-                fp, rules));
+  DEBUG_printf(("checkrules(filename=\"%s\", fb=%p, rules=%p)\n", filename,
+                fb, rules));
 
   if (rules == NULL)
     return (0);
@@ -674,9 +692,7 @@ checkrules(const char   *filename,  /* I - Filename */
   else
     logic = rules->parent->op;
 
-  bufoffset = -1;
-  buflength = 0;
-  result    = 0;
+  result = 0;
 
   while (rules != NULL)
   {
@@ -695,28 +711,29 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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) ||
@@ -736,28 +753,29 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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 ||
@@ -782,20 +800,22 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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]));
          }
 
          /*
@@ -803,10 +823,10 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
@@ -816,16 +836,17 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
          }
 
          /*
@@ -833,10 +854,11 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
 
@@ -845,15 +867,16 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
          }
 
         /*
@@ -861,10 +884,11 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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 :
@@ -872,16 +896,17 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
          }
 
         /*
@@ -889,11 +914,11 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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);
          }
@@ -904,16 +929,17 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
          }
 
         /*
@@ -921,22 +947,24 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
 
@@ -945,16 +973,17 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
          }
 
          /*
@@ -962,25 +991,26 @@ checkrules(const char   *filename,        /* I - Filename */
          * 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;
@@ -1047,7 +1077,7 @@ patmatch(const char *s,           /* I - String to match against */
 
       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.
@@ -1113,8 +1143,8 @@ patmatch(const char *s,           /* I - String to match against */
   }
 
  /*
-  * 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);
@@ -1122,5 +1152,5 @@ patmatch(const char *s,           /* I - String to match against */
 
 
 /*
- * End of "$Id: type.c 4970 2006-01-24 14:05:45Z mike $".
+ * End of "$Id: type.c 6649 2007-07-11 21:46:42Z mike $".
  */