]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - backend/snmp.c
Off by one error in ipp_finishings_vendor
[thirdparty/cups.git] / backend / snmp.c
index 34494d0e7f98716edceaf86434ea3dedfa9cc1da..66ac884c67e24e83013864cf2625384f569abfb9 100644 (file)
@@ -1,44 +1,11 @@
 /*
- * "$Id: snmp.c 7810 2008-07-29 01:11:15Z mike $"
+ * SNMP discovery backend for CUPS.
  *
- *   SNMP discovery backend for CUPS.
+ * Copyright © 2007-2014 by Apple Inc.
+ * Copyright © 2006-2007 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007-2011 by Apple Inc.
- *   Copyright 2006-2007 by Easy Software Products, all rights reserved.
- *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   "LICENSE" which should have been included with this file.  If this
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   main()                    - Discover printers via SNMP.
- *   add_array()               - Add a string to an array.
- *   add_cache()               - Add a cached device...
- *   add_device_uri()          - Add a device URI to the cache.
- *   alarm_handler()           - Handle alarm signals...
- *   compare_cache()           - Compare two cache entries.
- *   debug_printf()            - Display some debugging information.
- *   fix_make_model()          - Fix common problems in the make-and-model
- *                               string.
- *   free_array()              - Free an array of strings.
- *   free_cache()              - Free the array of cached devices.
- *   get_interface_addresses() - Get the broadcast address(es) associated with
- *                               an interface.
- *   list_device()             - List a device we found...
- *   password_cb()             - Handle authentication requests.
- *   probe_device()            - Probe a device to discover whether it is a
- *                               printer.
- *   read_snmp_conf()          - Read the snmp.conf file.
- *   read_snmp_response()      - Read and parse a SNMP response...
- *   run_time()                - Return the total running time...
- *   scan_devices()            - Scan for devices using SNMP.
- *   try_connect()             - Try connecting on a port...
- *   update_cache()            - Update a cached device...
+ * Licensed under Apache License v2.0.  See the file "LICENSE" for more
+ * information.
  */
 
 /*
@@ -251,7 +218,7 @@ main(int  argc,                             /* I - Number of command-line arguments (6 or 7) */
 
 #ifdef AF_INET6
   if ((ipv6 = _cupsSNMPOpen(AF_INET6)) < 0)
-    return (1);
+    perror("DEBUG: Unable to create IPv6 socket");
 #else
   ipv6 = -1;
 #endif /* AF_INET6 */
@@ -467,7 +434,7 @@ static int                          /* O - Result of comparison */
 compare_cache(snmp_cache_t *a,         /* I - First cache entry */
               snmp_cache_t *b)         /* I - Second cache entry */
 {
-  return (strcasecmp(a->addrname, b->addrname));
+  return (_cups_strcasecmp(a->addrname, b->addrname));
 }
 
 
@@ -509,7 +476,7 @@ fix_make_model(
   * that printer driver detection works better...
   */
 
-  if (!strncasecmp(old_make_model, "Hewlett-Packard", 15))
+  if (!_cups_strncasecmp(old_make_model, "Hewlett-Packard", 15))
   {
    /*
     * Strip leading Hewlett-Packard and hp prefixes and replace
@@ -521,7 +488,7 @@ fix_make_model(
     while (isspace(*mmptr & 255))
       mmptr ++;
 
-    if (!strncasecmp(mmptr, "hp", 2))
+    if (!_cups_strncasecmp(mmptr, "hp", 2))
     {
       mmptr += 2;
 
@@ -532,17 +499,16 @@ fix_make_model(
     make_model[0] = 'H';
     make_model[1] = 'P';
     make_model[2] = ' ';
-    strlcpy(make_model + 3, mmptr, make_model_size - 3);
+    strlcpy(make_model + 3, mmptr, (size_t)make_model_size - 3);
   }
-  else if (!strncasecmp(old_make_model, "deskjet", 7))
-    snprintf(make_model, make_model_size, "HP DeskJet%s", old_make_model + 7);
-  else if (!strncasecmp(old_make_model, "officejet", 9))
-    snprintf(make_model, make_model_size, "HP OfficeJet%s", old_make_model + 9);
-  else if (!strncasecmp(old_make_model, "stylus_pro_", 11))
-    snprintf(make_model, make_model_size, "EPSON Stylus Pro %s",
-             old_make_model + 11);
+  else if (!_cups_strncasecmp(old_make_model, "deskjet", 7))
+    snprintf(make_model, (size_t)make_model_size, "HP DeskJet%s", old_make_model + 7);
+  else if (!_cups_strncasecmp(old_make_model, "officejet", 9))
+    snprintf(make_model, (size_t)make_model_size, "HP OfficeJet%s", old_make_model + 9);
+  else if (!_cups_strncasecmp(old_make_model, "stylus_pro_", 11))
+    snprintf(make_model, (size_t)make_model_size, "EPSON Stylus Pro %s", old_make_model + 11);
   else
-    strlcpy(make_model, old_make_model, make_model_size);
+    strlcpy(make_model, old_make_model, (size_t)make_model_size);
 
   if ((mmptr = strstr(make_model, ", Inc.,")) != NULL)
   {
@@ -753,7 +719,7 @@ probe_device(snmp_cache_t *device)  /* I - Device */
            * Insert hostname/address...
            */
 
-           strlcpy(uriptr, device->addrname, sizeof(uri) - (uriptr - uri));
+           strlcpy(uriptr, device->addrname, sizeof(uri) - (size_t)(uriptr - uri));
            uriptr += strlen(uriptr);
            format += 2;
          }
@@ -844,16 +810,16 @@ read_snmp_conf(const char *address)       /* I - Single address to probe */
       if (!value)
         fprintf(stderr, "ERROR: Missing value on line %d of %s!\n", linenum,
                filename);
-      else if (!strcasecmp(line, "Address"))
+      else if (!_cups_strcasecmp(line, "Address"))
       {
         if (!address)
           add_array(Addresses, value);
       }
-      else if (!strcasecmp(line, "Community"))
+      else if (!_cups_strcasecmp(line, "Community"))
         add_array(Communities, value);
-      else if (!strcasecmp(line, "DebugLevel"))
+      else if (!_cups_strcasecmp(line, "DebugLevel"))
         DebugLevel = atoi(value);
-      else if (!strcasecmp(line, "DeviceURI"))
+      else if (!_cups_strcasecmp(line, "DeviceURI"))
       {
         if (*value != '\"')
          fprintf(stderr,
@@ -862,12 +828,12 @@ read_snmp_conf(const char *address)       /* I - Single address to probe */
         else
          add_device_uri(value);
       }
-      else if (!strcasecmp(line, "HostNameLookups"))
-        HostNameLookups = !strcasecmp(value, "on") ||
-                         !strcasecmp(value, "yes") ||
-                         !strcasecmp(value, "true") ||
-                         !strcasecmp(value, "double");
-      else if (!strcasecmp(line, "MaxRunTime"))
+      else if (!_cups_strcasecmp(line, "HostNameLookups"))
+        HostNameLookups = !_cups_strcasecmp(value, "on") ||
+                         !_cups_strcasecmp(value, "yes") ||
+                         !_cups_strcasecmp(value, "true") ||
+                         !_cups_strcasecmp(value, "double");
+      else if (!_cups_strcasecmp(line, "MaxRunTime"))
         MaxRunTime = atoi(value);
       else
         fprintf(stderr, "ERROR: Unknown directive %s on line %d of %s!\n",
@@ -948,7 +914,7 @@ read_snmp_response(int fd)          /* I - SNMP socket file descriptor */
   debug_printf("DEBUG: request-id=%d\n", packet.request_id);
   debug_printf("DEBUG: error-status=%d\n", packet.error_status);
 
-  if (packet.error_status)
+  if (packet.error_status && packet.request_id != DEVICE_TYPE)
     return;
 
  /*
@@ -1025,6 +991,11 @@ read_snmp_response(int fd)                /* I - SNMP socket file descriptor */
            * Description is the IEEE-1284 device ID...
            */
 
+            char *ptr;                 /* Pointer into device ID */
+
+            for (ptr = (char *)packet.object_value.string.bytes; *ptr; ptr ++)
+              if (*ptr == '\n')
+                *ptr = ';';            /* A lot of bad printers put a newline */
            if (!device->id)
              device->id = strdup((char *)packet.object_value.string.bytes);
 
@@ -1066,8 +1037,11 @@ read_snmp_response(int fd)               /* I - SNMP socket file descriptor */
          */
 
          char  make_model[256];        /* Make and model */
+          char *ptr;                   /* Pointer into device ID */
 
-
+          for (ptr = (char *)packet.object_value.string.bytes; *ptr; ptr ++)
+            if (*ptr == '\n')
+              *ptr = ';';              /* A lot of bad printers put a newline */
          if (device->id)
            free(device->id);
 
@@ -1112,12 +1086,18 @@ read_snmp_response(int fd)              /* I - SNMP socket file descriptor */
 
     case DEVICE_URI :
        if (device && packet.object_type == CUPS_ASN1_OCTET_STRING &&
-           !device->uri && packet.object_value.string.num_bytes > 0)
+           !device->uri && packet.object_value.string.num_bytes > 3)
        {
         /*
          * Update an existing cache entry...
          */
 
+          char scheme[32],             /* URI scheme */
+               userpass[256],          /* Username:password in URI */
+               hostname[256],          /* Hostname in URI */
+               resource[1024];         /* Resource path in URI */
+         int   port;                   /* Port number in URI */
+
          if (!strncmp((char *)packet.object_value.string.bytes, "lpr:", 4))
          {
           /*
@@ -1127,7 +1107,13 @@ read_snmp_response(int fd)               /* I - SNMP socket file descriptor */
            packet.object_value.string.bytes[2] = 'd';
          }
 
-         device->uri = strdup((char *)packet.object_value.string.bytes);
+          if (httpSeparateURI(HTTP_URI_CODING_ALL,
+                              (char *)packet.object_value.string.bytes,
+                              scheme, sizeof(scheme),
+                              userpass, sizeof(userpass),
+                              hostname, sizeof(hostname), &port,
+                              resource, sizeof(resource)) >= HTTP_URI_OK)
+           device->uri = strdup((char *)packet.object_value.string.bytes);
        }
        break;
   }
@@ -1213,7 +1199,7 @@ scan_devices(int ipv4,                    /* I - SNMP IPv4 socket */
       for (addr = addrs; addr; addr = addr->next)
       {
 #ifdef AF_INET6
-        if (_httpAddrFamily(&(addr->addr)) == AF_INET6)
+        if (httpAddrFamily(&(addr->addr)) == AF_INET6)
          fd = ipv6;
        else
 #endif /* AF_INET6 */
@@ -1315,7 +1301,7 @@ try_connect(http_addr_t *addr,            /* I - Socket address */
   debug_printf("DEBUG: %.3f Trying %s://%s:%d...\n", run_time(),
                port == 515 ? "lpd" : "socket", addrname, port);
 
-  if ((fd = socket(_httpAddrFamily(addr), SOCK_STREAM, 0)) < 0)
+  if ((fd = socket(httpAddrFamily(addr), SOCK_STREAM, 0)) < 0)
   {
     fprintf(stderr, "ERROR: Unable to create socket: %s\n",
             strerror(errno));
@@ -1326,7 +1312,7 @@ try_connect(http_addr_t *addr,            /* I - Socket address */
 
   alarm(1);
 
-  status = connect(fd, (void *)addr, httpAddrLength(addr));
+  status = connect(fd, (void *)addr, (socklen_t)httpAddrLength(addr));
 
   close(fd);
   alarm(0);
@@ -1368,8 +1354,3 @@ update_cache(snmp_cache_t *device,        /* I - Device */
 
   list_device(device);
 }
-
-
-/*
- * End of "$Id: snmp.c 7810 2008-07-29 01:11:15Z mike $".
- */