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, ¤t_addr)) backend_init_supplies(snmp_fd, addr); else if (num_supplies > 0) _cupsSNMPWalk(snmp_fd, ¤t_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); }
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); }
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 */ }