예제 #1
0
int					/* O - 0 on success, -1 on error */
backendSNMPSupplies(
    int         snmp_fd,		/* I - SNMP socket */
    http_addr_t *addr,			/* I - Printer address */
    int         *page_count,		/* O - Page count */
    int         *printer_state)		/* O - Printer state */
{
  if (!httpAddrEqual(addr, &current_addr))
    backend_init_supplies(snmp_fd, addr);
  else if (num_supplies > 0)
    _cupsSNMPWalk(snmp_fd, &current_addr, CUPS_SNMP_VERSION_1,
		  _cupsSNMPDefaultCommunity(), prtMarkerSuppliesLevel,
		  CUPS_SUPPLY_TIMEOUT, backend_walk_cb, NULL);

  if (page_count)
    *page_count = -1;

  if (printer_state)
    *printer_state = -1;

  if (num_supplies > 0)
  {
    int		i,			/* Looping var */
		percent,		/* Percent full */
		new_state,		/* New state value */
		change_state,		/* State change */
		new_supply_state = 0;	/* Supply state */
    char	value[CUPS_MAX_SUPPLIES * 4],
					/* marker-levels value string */
		*ptr;			/* Pointer into value string */
    cups_snmp_t	packet;			/* SNMP response packet */

   /*
    * Generate the marker-levels value string...
    */

    for (i = 0, ptr = value; i < num_supplies; i ++, ptr += strlen(ptr))
    {
      if (supplies[i].max_capacity > 0 && supplies[i].level >= 0)
	percent = 100 * supplies[i].level / supplies[i].max_capacity;
      else if (supplies[i].level >= 0 && supplies[i].level <= 100 &&
               (quirks & CUPS_SNMP_CAPACITY))
        percent = supplies[i].level;
      else
        percent = 50;

      if (supplies[i].sclass == CUPS_TC_receptacleThatIsFilled)
        percent = 100 - percent;

      if (percent <= 5)
      {
        switch (supplies[i].type)
        {
          case CUPS_TC_toner :
          case CUPS_TC_tonerCartridge :
              if (percent <= 1)
                new_supply_state |= CUPS_TONER_EMPTY;
              else
                new_supply_state |= CUPS_TONER_LOW;
              break;
          case CUPS_TC_ink :
          case CUPS_TC_inkCartridge :
          case CUPS_TC_inkRibbon :
          case CUPS_TC_solidWax :
          case CUPS_TC_ribbonWax :
              if (percent <= 1)
                new_supply_state |= CUPS_MARKER_SUPPLY_EMPTY;
              else
                new_supply_state |= CUPS_MARKER_SUPPLY_LOW;
              break;
          case CUPS_TC_developer :
              if (percent <= 1)
                new_supply_state |= CUPS_DEVELOPER_EMPTY;
              else
                new_supply_state |= CUPS_DEVELOPER_LOW;
              break;
          case CUPS_TC_coronaWire :
          case CUPS_TC_fuser :
          case CUPS_TC_opc :
          case CUPS_TC_transferUnit :
              if (percent <= 1)
                new_supply_state |= CUPS_OPC_LIFE_OVER;
              else
                new_supply_state |= CUPS_OPC_NEAR_EOL;
              break;
#if 0 /* Because no two vendors report waste containers the same, disable SNMP reporting of same */
          case CUPS_TC_wasteInk :
          case CUPS_TC_wastePaper :
          case CUPS_TC_wasteToner :
          case CUPS_TC_wasteWater :
          case CUPS_TC_wasteWax :
              if (percent <= 1)
                new_supply_state |= CUPS_WASTE_FULL;
              else
                new_supply_state |= CUPS_WASTE_ALMOST_FULL;
              break;
#endif /* 0 */
          case CUPS_TC_cleanerUnit :
          case CUPS_TC_fuserCleaningPad :
              if (percent <= 1)
                new_supply_state |= CUPS_CLEANER_LIFE_OVER;
              else
                new_supply_state |= CUPS_CLEANER_NEAR_EOL;
              break;
        }
      }

      if (i)
        *ptr++ = ',';

      if ((supplies[i].max_capacity > 0 || (quirks & CUPS_SNMP_CAPACITY)) &&
          supplies[i].level >= 0)
        snprintf(ptr, sizeof(value) - (size_t)(ptr - value), "%d", percent);
      else
        strlcpy(ptr, "-1", sizeof(value) - (size_t)(ptr - value));
    }

    fprintf(stderr, "ATTR: marker-levels=%s\n", value);

    if (supply_state < 0)
      change_state = 0xffff;
    else
      change_state = supply_state ^ new_supply_state;

    fprintf(stderr, "DEBUG: new_supply_state=%x, change_state=%x\n",
            new_supply_state, change_state);

    for (i = 0;
         i < (int)(sizeof(supply_states) / sizeof(supply_states[0]));
         i ++)
      if (change_state & supply_states[i].bit)
      {
	fprintf(stderr, "STATE: %c%s\n",
		(new_supply_state & supply_states[i].bit) ? '+' : '-',
		supply_states[i].keyword);
      }

    supply_state = new_supply_state;

   /*
    * Get the current printer status bits...
    */

    if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
                       _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
                       hrPrinterDetectedErrorState))
      return (-1);

    if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
        packet.object_type != CUPS_ASN1_OCTET_STRING)
      return (-1);

    if (packet.object_value.string.num_bytes == 2)
      new_state = (packet.object_value.string.bytes[0] << 8) |
		  packet.object_value.string.bytes[1];
    else if (packet.object_value.string.num_bytes == 1)
      new_state = (packet.object_value.string.bytes[0] << 8);
    else
      new_state = 0;

    if (current_state < 0)
      change_state = 0xffff;
    else
      change_state = current_state ^ new_state;

    fprintf(stderr, "DEBUG: new_state=%x, change_state=%x\n", new_state,
            change_state);

    for (i = 0;
         i < (int)(sizeof(printer_states) / sizeof(printer_states[0]));
         i ++)
      if (change_state & printer_states[i].bit)
      {
	fprintf(stderr, "STATE: %c%s\n",
		(new_state & printer_states[i].bit) ? '+' : '-',
		printer_states[i].keyword);
      }

    current_state = new_state;

   /*
    * Get the current printer state...
    */

    if (printer_state)
    {
      if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
			 _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
			 hrPrinterStatus))
	return (-1);

      if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
	  packet.object_type != CUPS_ASN1_INTEGER)
	return (-1);

      *printer_state = packet.object_value.integer;
    }

   /*
    * Get the current page count...
    */

    if (page_count)
    {
      if (!_cupsSNMPWrite(snmp_fd, addr, CUPS_SNMP_VERSION_1,
			 _cupsSNMPDefaultCommunity(), CUPS_ASN1_GET_REQUEST, 1,
			 prtMarkerLifeCount))
	return (-1);

      if (!_cupsSNMPRead(snmp_fd, &packet, CUPS_SUPPLY_TIMEOUT) ||
	  packet.object_type != CUPS_ASN1_COUNTER)
	return (-1);

      *page_count = packet.object_value.counter;
    }

    return (0);
  }
  else
    return (-1);
}
예제 #2
0
파일: main.c 프로젝트: ChErePOdaViLka/cups
static void
launchd_checkin(void)
{
  size_t		i,		/* Looping var */
			count;		/* Number of listeners */
  launch_data_t		ld_msg,		/* Launch data message */
			ld_resp,	/* Launch data response */
			ld_array,	/* Launch data array */
			ld_sockets,	/* Launch data sockets dictionary */
			tmp;		/* Launch data */
  cupsd_listener_t	*lis;		/* Listeners array */
  http_addr_t		addr;		/* Address variable */
  socklen_t		addrlen;	/* Length of address */
  int			fd;		/* File descriptor */
  char			s[256];		/* String addresss */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());

 /*
  * Check-in with launchd...
  */

  ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  if ((ld_resp = launch_msg(ld_msg)) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
		    "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
		    "\") IPC failure");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

  if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
  {
    errno = launch_data_get_errno(ld_resp);
    cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s",
                    strerror(errno));
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the sockets dictionary...
  */

  if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
          == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the array of listener sockets...
  */

  if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Add listening fd(s) to the Listener array...
  */

  if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
  {
    count = launch_data_array_get_count(ld_array);

    for (i = 0; i < count; i ++)
    {
     /*
      * Get the launchd file descriptor and address...
      */

      if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
      {
	fd      = launch_data_get_fd(tmp);
	addrlen = sizeof(addr);

	if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "launchd_checkin: Unable to get local address - %s",
			  strerror(errno));
	  continue;
	}

       /*
	* Try to match the launchd socket address to one of the listeners...
	*/

	for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
	     lis;
	     lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
	  if (httpAddrEqual(&lis->address, &addr))
	    break;

       /*
	* Add a new listener If there's no match...
	*/

	if (lis)
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Matched existing listener %s with fd %d...",
		  httpAddrString(&(lis->address), s, sizeof(s)), fd);
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Adding new listener %s with fd %d...",
		  httpAddrString(&addr, s, sizeof(s)), fd);

	  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "launchd_checkin: Unable to allocate listener - "
			    "%s.", strerror(errno));
	    exit(EXIT_FAILURE);
	  }

	  cupsArrayAdd(Listeners, lis);

	  memcpy(&lis->address, &addr, sizeof(lis->address));
	}

	lis->fd = fd;

#  ifdef HAVE_SSL
	if (_httpAddrPort(&(lis->address)) == 443)
	  lis->encryption = HTTP_ENCRYPT_ALWAYS;
#  endif /* HAVE_SSL */
      }
    }
  }

  launch_data_free(ld_msg);
  launch_data_free(ld_resp);
}
예제 #3
0
파일: main.c 프로젝트: apple/cups
static void
service_add_listener(int fd,		/* I - Socket file descriptor */
                     int idx)		/* I - Listener number, for logging */
{
  cupsd_listener_t	*lis;		/* Listeners array */
  http_addr_t		addr;		/* Address variable */
  socklen_t		addrlen;	/* Length of address */
  char			s[256];		/* String addresss */


  addrlen = sizeof(addr);

  if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
  {
    cupsdLogMessage(CUPSD_LOG_ERROR, "service_add_listener: Unable to get local address for listener #%d: %s", idx + 1, strerror(errno));
    return;
  }

  cupsdLogMessage(CUPSD_LOG_DEBUG, "service_add_listener: Listener #%d at fd %d, \"%s\".", idx + 1, fd, httpAddrString(&addr, s, sizeof(s)));

 /*
  * Try to match the on-demand socket address to one of the listeners...
  */

  for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
       lis;
       lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
    if (httpAddrEqual(&lis->address, &addr))
      break;

  /*
   * Add a new listener If there's no match...
   */

  if (lis)
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "service_add_listener: Matched existing listener #%d to %s.", idx + 1, httpAddrString(&(lis->address), s, sizeof(s)));
  }
  else
  {
    cupsdLogMessage(CUPSD_LOG_DEBUG, "service_add_listener: Adding new listener #%d for %s.", idx + 1, httpAddrString(&addr, s, sizeof(s)));

    if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR, "service_add_listener: Unable to allocate listener: %s.", strerror(errno));
      exit(EXIT_FAILURE);
      return;
    }

    cupsArrayAdd(Listeners, lis);

    memcpy(&lis->address, &addr, sizeof(lis->address));
  }

  lis->fd        = fd;
  lis->on_demand = 1;

#  ifdef HAVE_SSL
  if (httpAddrPort(&(lis->address)) == 443)
    lis->encryption = HTTP_ENCRYPT_ALWAYS;
#  endif /* HAVE_SSL */
}