]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - backend/network.c
Remove all of the Subversion keywords from various source files.
[thirdparty/cups.git] / backend / network.c
index d83ea9ccfab341edec7523b15191079cb7d72dbd..8beced8d27b7b001d8a86b61deef3e02ddacec11 100644 (file)
@@ -1,25 +1,16 @@
 /*
- * "$Id$"
+ * Common backend network APIs for CUPS.
  *
- *   Common network APIs for the Common UNIX Printing System (CUPS).
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 2006-2007 by Easy Software Products, all rights reserved.
  *
- *   Copyright 2007-2008 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/".
  *
- *   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:
- *
- *   backendCheckSideChannel() - Check the side-channel for pending requests.
- *   backendNetworkSideCB()    - Handle common network side-channel commands.
- *   backendResolveURI()       - Get the device URI, resolving as needed.
- *   resolve_callback()        - Build a device URI for the given service name.
+ * This file is subject to the Apple OS-Developed Software exception.
  */
 
 /*
 
 #include "backend-private.h"
 #include <limits.h>
-#ifdef __hpux
-#  include <sys/time.h>
-#else
-#  include <sys/select.h>
-#endif /* __hpux */
-#ifdef HAVE_DNSSD
-#  include <dns_sd.h>
-#endif /* HAVE_DNSSD */
-
-
-/*
- * Local functions...
- */
-
-#ifdef HAVE_DNSSD
-static void    resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags,
-                                uint32_t interfaceIndex,
-                                DNSServiceErrorType errorCode,
-                                const char *fullName, const char *hostTarget,
-                                uint16_t port, uint16_t txtLen,
-                                const unsigned char *txtRecord, void *context);
-#endif /* HAVE_DNSSD */
+#include <sys/select.h>
 
 
 /*
@@ -80,7 +50,7 @@ backendCheckSideChannel(
  * 'backendNetworkSideCB()' - Handle common network side-channel commands.
  */
 
-void
+int                                    /* O - -1 on error, 0 on success */
 backendNetworkSideCB(
     int         print_fd,              /* I - Print file or -1 */
     int         device_fd,             /* I - Device file or -1 */
@@ -90,7 +60,7 @@ backendNetworkSideCB(
 {
   cups_sc_command_t    command;        /* Request command */
   cups_sc_status_t     status;         /* Request/response status */
-  char                 data[2048];     /* Request/response data */
+  char                 data[65536];    /* Request/response data */
   int                  datalen;        /* Request/response data size */
   const char           *device_id;     /* 1284DEVICEID env var */
 
@@ -98,10 +68,7 @@ backendNetworkSideCB(
   datalen = sizeof(data);
 
   if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
-  {
-    _cupsLangPuts(stderr, _("WARNING: Failed to read side-channel request!\n"));
-    return;
-  }
+    return (-1);
 
   switch (command)
   {
@@ -114,14 +81,176 @@ backendNetworkSideCB(
          status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
        else if (backendDrainOutput(print_fd, device_fd))
          status = CUPS_SC_STATUS_IO_ERROR;
-       else 
+       else
           status = CUPS_SC_STATUS_OK;
 
        datalen = 0;
         break;
 
     case CUPS_SC_CMD_GET_BIDI :
-        data[0] = use_bc;
+       status  = CUPS_SC_STATUS_OK;
+        data[0] = (char)use_bc;
+        datalen = 1;
+        break;
+
+    case CUPS_SC_CMD_SNMP_GET :
+    case CUPS_SC_CMD_SNMP_GET_NEXT :
+        fprintf(stderr, "DEBUG: CUPS_SC_CMD_SNMP_%s: %d (%s)\n",
+               command == CUPS_SC_CMD_SNMP_GET ? "GET" : "GET_NEXT", datalen,
+               data);
+
+        if (datalen < 2)
+       {
+         status  = CUPS_SC_STATUS_BAD_MESSAGE;
+         datalen = 0;
+         break;
+       }
+
+        if (snmp_fd >= 0)
+       {
+         char          *dataptr;       /* Pointer into data */
+         cups_snmp_t   packet;         /* Packet from printer */
+          const char   *snmp_value;    /* CUPS_SNMP_VALUE env var */
+
+          if ((snmp_value = getenv("CUPS_SNMP_VALUE")) != NULL)
+          {
+            const char *snmp_count;    /* CUPS_SNMP_COUNT env var */
+            int                count;          /* Repetition count */
+
+            if ((snmp_count = getenv("CUPS_SNMP_COUNT")) != NULL)
+            {
+              if ((count = atoi(snmp_count)) <= 0)
+                count = 1;
+            }
+            else
+              count = 1;
+
+           for (dataptr = data + strlen(data) + 1;
+                count > 0 && dataptr < (data + sizeof(data) - 1);
+                count --, dataptr += strlen(dataptr))
+             strlcpy(dataptr, snmp_value, sizeof(data) - (size_t)(dataptr - data));
+
+           fprintf(stderr, "DEBUG: Returning %s %s\n", data,
+                   data + strlen(data) + 1);
+
+           status  = CUPS_SC_STATUS_OK;
+           datalen = (int)(dataptr - data);
+           break;
+          }
+
+          if (!_cupsSNMPStringToOID(data, packet.object_name, CUPS_SNMP_MAX_OID))
+         {
+           status  = CUPS_SC_STATUS_BAD_MESSAGE;
+           datalen = 0;
+           break;
+         }
+
+          status  = CUPS_SC_STATUS_IO_ERROR;
+         datalen = 0;
+
+          if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
+                            _cupsSNMPDefaultCommunity(),
+                            command == CUPS_SC_CMD_SNMP_GET ?
+                                CUPS_ASN1_GET_REQUEST :
+                                CUPS_ASN1_GET_NEXT_REQUEST, 1,
+                            packet.object_name))
+          {
+           if (_cupsSNMPRead(snmp_fd, &packet, 1.0))
+           {
+             size_t    i;              /* Looping var */
+
+
+              if (!_cupsSNMPOIDToString(packet.object_name, data, sizeof(data)))
+             {
+               fputs("DEBUG: Bad OID returned!\n", stderr);
+               break;
+             }
+
+             datalen = (int)strlen(data) + 1;
+              dataptr = data + datalen;
+
+             switch (packet.object_type)
+             {
+               case CUPS_ASN1_BOOLEAN :
+                   snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%d", packet.object_value.boolean);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+               case CUPS_ASN1_INTEGER :
+                   snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%d",
+                            packet.object_value.integer);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+               case CUPS_ASN1_BIT_STRING :
+               case CUPS_ASN1_OCTET_STRING :
+                   if (packet.object_value.string.num_bytes < (sizeof(data) - (size_t)(dataptr - data)))
+                     i = packet.object_value.string.num_bytes;
+                   else
+                     i = sizeof(data) - (size_t)(dataptr - data);
+
+                   memcpy(dataptr, packet.object_value.string.bytes, i);
+
+                    datalen += (int)i;
+                   break;
+
+               case CUPS_ASN1_OID :
+                   _cupsSNMPOIDToString(packet.object_value.oid, dataptr,
+                                        sizeof(data) - (size_t)(dataptr - data));
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+                case CUPS_ASN1_HEX_STRING :
+                   for (i = 0;
+                        i < packet.object_value.string.num_bytes &&
+                            dataptr < (data + sizeof(data) - 3);
+                        i ++, dataptr += 2)
+                     sprintf(dataptr, "%02X", packet.object_value.string.bytes[i]);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+                case CUPS_ASN1_COUNTER :
+                   snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.counter);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+                case CUPS_ASN1_GAUGE :
+                   snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.gauge);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+                case CUPS_ASN1_TIMETICKS :
+                   snprintf(dataptr, sizeof(data) - (size_t)(dataptr - data), "%u", packet.object_value.timeticks);
+                   datalen += (int)strlen(dataptr);
+                   break;
+
+                default :
+                   fprintf(stderr, "DEBUG: Unknown OID value type %02X.\n", packet.object_type);
+
+               case CUPS_ASN1_NULL_VALUE :
+                   dataptr[0] = '\0';
+                   break;
+              }
+
+             fprintf(stderr, "DEBUG: Returning %s %s\n", data, data + datalen);
+
+             status = CUPS_SC_STATUS_OK;
+           }
+           else
+             fputs("DEBUG: SNMP read error...\n", stderr);
+         }
+         else
+           fputs("DEBUG: SNMP write error...\n", stderr);
+         break;
+        }
+
+        status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
+       datalen = 0;
+       break;
+
+    case CUPS_SC_CMD_GET_CONNECTED :
+       status  = CUPS_SC_STATUS_OK;
+        data[0] = device_fd != -1;
         datalen = 1;
         break;
 
@@ -132,24 +261,33 @@ backendNetworkSideCB(
          static const int ppmPrinterIEEE1284DeviceId[] =
                        { CUPS_OID_ppmPrinterIEEE1284DeviceId,1,-1 };
 
-          if (_cupsSNMPWrite(snmp_fd, addr, 1, _cupsSNMPDefaultCommunity(),
+
+          status  = CUPS_SC_STATUS_IO_ERROR;
+         datalen = 0;
+
+          if (_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
+                            _cupsSNMPDefaultCommunity(),
                             CUPS_ASN1_GET_REQUEST, 1,
                             ppmPrinterIEEE1284DeviceId))
           {
            if (_cupsSNMPRead(snmp_fd, &packet, 1.0) &&
                packet.object_type == CUPS_ASN1_OCTET_STRING)
            {
-             strlcpy(data, packet.object_value.string, sizeof(data));
+             strlcpy(data, (char *)packet.object_value.string.bytes,
+                     sizeof(data));
              datalen = (int)strlen(data);
-             break;
+             status  = CUPS_SC_STATUS_OK;
            }
          }
+
+         break;
         }
 
        if ((device_id = getenv("1284DEVICEID")) != NULL)
        {
          strlcpy(data, device_id, sizeof(data));
          datalen = (int)strlen(data);
+         status  = CUPS_SC_STATUS_OK;
          break;
        }
 
@@ -159,178 +297,5 @@ backendNetworkSideCB(
        break;
   }
 
-  cupsSideChannelWrite(command, status, data, datalen, 1.0);
+  return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
 }
-
-
-/*
- * 'backendResolveURI()' - Get the device URI, resolving as needed.
- */
-
-const char *                           /* O - Device URI */
-backendResolveURI(char **argv)         /* I - Command-line arguments */
-{
-  const char           *uri;           /* Device URI */
-  char                 scheme[32],     /* URI components... */
-                       userpass[256],
-                       hostname[1024],
-                       resource[1024];
-  int                  port;
-  http_uri_status_t    status;         /* URI decode status */
-
- /*
-  * Get the device URI...
-  */
-
-  uri = cupsBackendDeviceURI(argv);
-
-  if ((status = httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme,
-                                sizeof(scheme), userpass, sizeof(userpass),
-                               hostname, sizeof(hostname), &port,
-                               resource, sizeof(resource))) < HTTP_URI_OK)
-  {
-    fprintf(stderr, "ERROR: Bad device URI \"%s\" (%d)!\n", uri, status);
-    exit (CUPS_BACKEND_STOP);
-  }
-
- /*
-  * Resolve it as needed...
-  */
-
-  if (strstr(hostname, "._tcp"))
-  {
-#ifdef HAVE_DNSSD
-    DNSServiceRef      ref;            /* DNS-SD service reference */
-    char               *regtype,       /* Pointer to type in hostname */
-                       *domain;        /* Pointer to domain in hostname */
-    static char                resolved_uri[HTTP_MAX_URI];
-                                       /* Resolved device URI */
-
-   /*
-    * Separate the hostname into service name, registration type, and domain...
-    */
-
-    regtype = strchr(hostname, '.');
-    *regtype++ = '\0';
-
-    domain = regtype + strlen(regtype) - 1;
-    if (domain > regtype && *domain == '.')
-      *domain = '\0';
-
-    for (domain = strchr(regtype, '.');
-         domain;
-        domain = strchr(domain + 1, '.'))
-      if (domain[1] != '_')
-        break;
-
-    if (domain)
-      *domain++ = '\0';
-
-    fprintf(stderr,
-            "DEBUG: Resolving service \"%s\", regtype \"%s\", domain \"%s\"\n",
-           hostname, regtype, domain ? domain : "(null)");
-
-    if (DNSServiceResolve(&ref, 0, 0, hostname, regtype, domain,
-                         resolve_callback,
-                         resolved_uri) == kDNSServiceErr_NoError)
-    {
-      if (DNSServiceProcessResult(ref) != kDNSServiceErr_NoError)
-        uri = NULL;
-      else
-        uri = resolved_uri;
-
-      DNSServiceRefDeallocate(ref);
-    }
-    else
-#endif /* HAVE_DNSSD */
-
-    uri = NULL;
-
-    if (!uri)
-    {
-      fprintf(stderr, "ERROR: Unable to resolve DNS-SD service \"%s\"!\n", uri);
-      exit(CUPS_BACKEND_STOP);
-    }
-  }
-
-  return (uri);
-}
-
-
-#ifdef HAVE_DNSSD
-/*
- * 'resolve_callback()' - Build a device URI for the given service name.
- */
-
-static void
-resolve_callback(
-    DNSServiceRef       sdRef,         /* I - Service reference */
-    DNSServiceFlags     flags,         /* I - Results flags */
-    uint32_t            interfaceIndex,        /* I - Interface number */
-    DNSServiceErrorType errorCode,     /* I - Error, if any */
-    const char          *fullName,     /* I - Full service name */
-    const char          *hostTarget,   /* I - Hostname */
-    uint16_t            port,          /* I - Port number */
-    uint16_t            txtLen,                /* I - Length of TXT record */
-    const unsigned char *txtRecord,    /* I - TXT record data */
-    void                *context)      /* I - Pointer to URI buffer */
-{
-  const char   *scheme;                /* URI scheme */
-  char         rp[257];                /* Remote printer */
-  const void   *value;                 /* Value from TXT record */
-  uint8_t      valueLen;               /* Length of value */
-
-
-  fprintf(stderr,
-          "DEBUG2: resolve_callback(sdRef=%p, flags=%x, interfaceIndex=%u, "
-         "errorCode=%d, fullName=\"%s\", hostTarget=\"%s\", port=%u, "
-         "txtLen=%u, txtRecord=%p, context=%p)\n", sdRef, flags,
-         interfaceIndex, errorCode, fullName, hostTarget, port, txtLen,
-         txtRecord, context);
-
- /*
-  * Figure out the scheme from the full name...
-  */
-
-  if (strstr(fullName, "._ipp"))
-    scheme = "ipp";
-  else if (strstr(fullName, "._printer."))
-    scheme = "lpd";
-  else if (strstr(fullName, "._pdl-datastream."))
-    scheme = "socket";
-  else
-    scheme = "riousbprint";
-
- /*
-  * Extract the "remote printer" key from the TXT record...
-  */
-
-  if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, "rp",
-                                    &valueLen)) != NULL)
-  {
-   /*
-    * Convert to resource by concatenating with a leading "/"...
-    */
-
-    rp[0] = '/';
-    memcpy(rp + 1, value, valueLen);
-    rp[valueLen + 1] = '\0';
-  }
-  else
-    rp[0] = '\0';
-
- /*
-  * Assemble the final device URI...
-  */
-
-  httpAssembleURI(HTTP_URI_CODING_ALL, (char *)context, HTTP_MAX_URI, scheme,
-                  NULL, hostTarget, ntohs(port), rp);
-
-  fprintf(stderr, "DEBUG: Resolved URI is \"%s\"...\n", (char *)context);
-}
-#endif /* HAVE_DNSSD */
-
-
-/*
- * End of "$Id$".
- */