Пример #1
0
cups_sc_status_t			/* O  - Status of command */
cupsSideChannelDoRequest(
    cups_sc_command_t command,		/* I  - Command to send */
    char              *data,		/* O  - Response data buffer pointer */
    int               *datalen,		/* IO - Size of data buffer on entry, number of bytes in buffer on return */
    double            timeout)		/* I  - Timeout in seconds */
{
  cups_sc_status_t	status;		/* Status of command */
  cups_sc_command_t	rcommand;	/* Response command */


  if (cupsSideChannelWrite(command, CUPS_SC_STATUS_NONE, NULL, 0, timeout))
    return (CUPS_SC_STATUS_TIMEOUT);

  if (cupsSideChannelRead(&rcommand, &status, data, datalen, timeout))
    return (CUPS_SC_STATUS_TIMEOUT);

  if (rcommand != command)
    return (CUPS_SC_STATUS_BAD_MESSAGE);

  return (status);
}
Пример #2
0
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 */
    int         snmp_fd,		/* I - SNMP socket */
    http_addr_t *addr,			/* I - Address of device */
    int         use_bc)			/* I - Use back-channel data? */
{
  cups_sc_command_t	command;	/* Request command */
  cups_sc_status_t	status;		/* Request/response status */
  char			data[65536];	/* Request/response data */
  int			datalen;	/* Request/response data size */
  const char		*device_id;	/* 1284DEVICEID env var */


  datalen = sizeof(data);

  if (cupsSideChannelRead(&command, &status, data, &datalen, 1.0))
    return (-1);

  switch (command)
  {
    case CUPS_SC_CMD_DRAIN_OUTPUT :
       /*
        * Our sockets disable the Nagle algorithm and data is sent immediately.
	*/

        if (device_fd < 0)
	  status = CUPS_SC_STATUS_NOT_IMPLEMENTED;
	else if (backendDrainOutput(print_fd, device_fd))
	  status = CUPS_SC_STATUS_IO_ERROR;
	else
          status = CUPS_SC_STATUS_OK;

	datalen = 0;
        break;

    case CUPS_SC_CMD_GET_BIDI :
	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;

    case CUPS_SC_CMD_GET_DEVICE_ID :
        if (snmp_fd >= 0)
	{
	  cups_snmp_t	packet;		/* Packet from printer */
	  static const int ppmPrinterIEEE1284DeviceId[] =
	  		{ CUPS_OID_ppmPrinterIEEE1284DeviceId,1,-1 };


          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, (char *)packet.object_value.string.bytes,
	              sizeof(data));
	      datalen = (int)strlen(data);
	      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;
	}

    default :
        status  = CUPS_SC_STATUS_NOT_IMPLEMENTED;
	datalen = 0;
	break;
  }

  return (cupsSideChannelWrite(command, status, data, datalen, 1.0));
}
Пример #3
0
cups_sc_status_t			/* O - Status of first query of @code CUPS_SC_STATUS_OK@ on success */
cupsSideChannelSNMPWalk(
    const char          *oid,		/* I - First numeric OID to query */
    double              timeout,	/* I - Timeout for each query in seconds */
    cups_sc_walk_func_t cb,		/* I - Function to call with each value */
    void                *context)	/* I - Application-defined pointer to send to callback */
{
  cups_sc_status_t	status;		/* Status of command */
  cups_sc_command_t	rcommand;	/* Response command */
  char			*real_data;	/* Real data buffer for response */
  int			real_datalen,	/* Real length of data buffer */
			real_oidlen,	/* Length of returned OID string */
			oidlen;		/* Length of first OID */
  const char		*current_oid;	/* Current OID */
  char			last_oid[2048];	/* Last OID */


  DEBUG_printf(("cupsSideChannelSNMPWalk(oid=\"%s\", timeout=%.3f, cb=%p, "
                "context=%p)", oid, timeout, cb, context));

 /*
  * Range check input...
  */

  if (!oid || !*oid || !cb)
    return (CUPS_SC_STATUS_BAD_MESSAGE);

  if ((real_data = _cupsBufferGet(_CUPS_SC_MAX_BUFFER)) == NULL)
    return (CUPS_SC_STATUS_TOO_BIG);

 /*
  * Loop until the OIDs don't match...
  */

  current_oid = oid;
  oidlen      = (int)strlen(oid);
  last_oid[0] = '\0';

  do
  {
   /*
    * Send the request to the backend and wait for a response...
    */

    if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET_NEXT, CUPS_SC_STATUS_NONE,
                             current_oid, (int)strlen(current_oid) + 1, timeout))
    {
      _cupsBufferRelease(real_data);
      return (CUPS_SC_STATUS_TIMEOUT);
    }

    real_datalen = _CUPS_SC_MAX_BUFFER;
    if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen,
                            timeout))
    {
      _cupsBufferRelease(real_data);
      return (CUPS_SC_STATUS_TIMEOUT);
    }

    if (rcommand != CUPS_SC_CMD_SNMP_GET_NEXT)
    {
      _cupsBufferRelease(real_data);
      return (CUPS_SC_STATUS_BAD_MESSAGE);
    }

    if (status == CUPS_SC_STATUS_OK)
    {
     /*
      * Parse the response of the form "oid\0value"...
      */

      if (strncmp(real_data, oid, oidlen) || real_data[oidlen] != '.' ||
          !strcmp(real_data, last_oid))
      {
       /*
        * Done with this set of OIDs...
	*/

	_cupsBufferRelease(real_data);
        return (CUPS_SC_STATUS_OK);
      }

      if (real_datalen < sizeof(real_data))
        real_data[real_datalen] = '\0';

      real_oidlen  = strlen(real_data) + 1;
      real_datalen -= real_oidlen;

     /*
      * Call the callback with the OID and data...
      */

      (*cb)(real_data, real_data + real_oidlen, real_datalen, context);

     /*
      * Update the current OID...
      */

      current_oid = real_data;
      strlcpy(last_oid, current_oid, sizeof(last_oid));
    }
  }
  while (status == CUPS_SC_STATUS_OK);

  _cupsBufferRelease(real_data);

  return (status);
}
Пример #4
0
cups_sc_status_t			/* O  - Query status */
cupsSideChannelSNMPGet(
    const char *oid,			/* I  - OID to query */
    char       *data,			/* I  - Buffer for OID value */
    int        *datalen,		/* IO - Size of OID buffer on entry, size of value on return */
    double     timeout)			/* I  - Timeout in seconds */
{
  cups_sc_status_t	status;		/* Status of command */
  cups_sc_command_t	rcommand;	/* Response command */
  char			*real_data;	/* Real data buffer for response */
  int			real_datalen,	/* Real length of data buffer */
			real_oidlen;	/* Length of returned OID string */


  DEBUG_printf(("cupsSideChannelSNMPGet(oid=\"%s\", data=%p, datalen=%p(%d), "
                "timeout=%.3f)", oid, data, datalen, datalen ? *datalen : -1,
		timeout));

 /*
  * Range check input...
  */

  if (!oid || !*oid || !data || !datalen || *datalen < 2)
    return (CUPS_SC_STATUS_BAD_MESSAGE);

  *data = '\0';

 /*
  * Send the request to the backend and wait for a response...
  */

  if (cupsSideChannelWrite(CUPS_SC_CMD_SNMP_GET, CUPS_SC_STATUS_NONE, oid,
                           (int)strlen(oid) + 1, timeout))
    return (CUPS_SC_STATUS_TIMEOUT);

  if ((real_data = _cupsBufferGet(_CUPS_SC_MAX_BUFFER)) == NULL)
    return (CUPS_SC_STATUS_TOO_BIG);

  real_datalen = _CUPS_SC_MAX_BUFFER;
  if (cupsSideChannelRead(&rcommand, &status, real_data, &real_datalen, timeout))
  {
    _cupsBufferRelease(real_data);
    return (CUPS_SC_STATUS_TIMEOUT);
  }

  if (rcommand != CUPS_SC_CMD_SNMP_GET)
  {
    _cupsBufferRelease(real_data);
    return (CUPS_SC_STATUS_BAD_MESSAGE);
  }

  if (status == CUPS_SC_STATUS_OK)
  {
   /*
    * Parse the response of the form "oid\0value"...
    */

    real_oidlen  = strlen(real_data) + 1;
    real_datalen -= real_oidlen;

    if ((real_datalen + 1) > *datalen)
    {
      _cupsBufferRelease(real_data);
      return (CUPS_SC_STATUS_TOO_BIG);
    }

    memcpy(data, real_data + real_oidlen, real_datalen);
    data[real_datalen] = '\0';

    *datalen = real_datalen;
  }

  _cupsBufferRelease(real_data);

  return (status);
}