/* return NULL on error */ nutscan_device_t * nutscan_scan_ipmi() { ipmi_ctx_t ipmi_ctx = NULL; nutscan_device_t * nut_dev = NULL; nutscan_device_t * current_nut_dev = NULL; int ret = -1; int ipmi_id = 0; char port_id[10]; if( !nutscan_avail_ipmi ) { return NULL; } /* Initialize the FreeIPMI library. */ if (!(ipmi_ctx = (*nut_ipmi_ctx_create) ())) { /* we have to force cleanup, since exit handler is not yet installed */ fprintf(stderr, "ipmi_ctx_create\n"); return NULL; } if ((ret = (*nut_ipmi_ctx_find_inband) (ipmi_ctx, NULL, 0, /* don't disable auto-probe */ 0, 0, NULL, 0, /* workaround flags, none by default */ 0 /* flags */ )) < 0) { fprintf(stderr, "ipmi_ctx_find_inband: %s\n", (*nut_ipmi_ctx_errormsg) (ipmi_ctx)); return NULL; } if (!ret) { /* No local IPMI device detected */ return NULL; } /* Loop through all possible devices */ for (ipmi_id = 0 ; ipmi_id <= IPMI_FRU_DEVICE_ID_MAX ; ipmi_id++) { if (is_ipmi_device_supported(ipmi_ctx, ipmi_id)) { if ( (nut_dev = nutscan_new_device()) == NULL ) { fprintf(stderr,"Memory allocation error\n"); nutscan_free_device(current_nut_dev); break; } /* Fill the device structure (sufficient with driver and port) */ nut_dev->type = TYPE_IPMI; nut_dev->driver = strdup(NUT_IPMI_DRV_NAME); sprintf(port_id, "id%x", ipmi_id); nut_dev->port = strdup(port_id); current_nut_dev = nutscan_add_device_to_device( current_nut_dev, nut_dev); memset (port_id, 0, sizeof(port_id)); } } /* Final cleanup */ if (ipmi_ctx) { (*nut_ipmi_ctx_close) (ipmi_ctx); (*nut_ipmi_ctx_destroy) (ipmi_ctx); } return current_nut_dev; }
static void update_device(const char * host_name,const char *ip, uint16_t port,char * text, int proto) { nutscan_device_t * dev = NULL; char * t = NULL; char * t_saveptr = NULL; char * phrase = NULL; char * phrase_saveptr = NULL; char * word = NULL; char * value = NULL; char * device = NULL; char * device_saveptr = NULL; int device_found = 0; char buf[6]; int buf_size; if( text == NULL ) { return; } t = strdup(text); phrase = strtok_r(t,"\"",&t_saveptr); while(phrase != NULL ) { word = strtok_r(phrase,"=",&phrase_saveptr); if( word == NULL ) { phrase = strtok_r(NULL,"\"",&t_saveptr); continue; } value = strtok_r(NULL,"=",&phrase_saveptr); if( value == NULL ) { phrase = strtok_r(NULL,"\"",&t_saveptr); continue; } if( strcmp(word,"device_list") != 0 ) { phrase = strtok_r(NULL,"\"",&t_saveptr); continue; } device = strtok_r(value,";",&device_saveptr); while( device != NULL ) { device_found = 1; dev = nutscan_new_device(); dev->type = TYPE_NUT; dev->driver = strdup("nutclient"); if( proto == AVAHI_PROTO_INET) { nutscan_add_option_to_device(dev,"desc","IPv4"); } if( proto == AVAHI_PROTO_INET6 ) { nutscan_add_option_to_device(dev,"desc","IPv6"); } if( port != PORT) { /* +5+1+1+1 is for : - port number (max 65535 so 5 characters), - '@' and ':' characters - terminating 0 */ buf_size = strlen(device)+strlen(host_name)+ 5+1+1+1; dev->port=malloc(buf_size); if(dev->port) { snprintf(dev->port,buf_size,"%s@%s:%u", device,host_name,port); } } else { /*+1+1 is for '@' character and terminating 0 */ buf_size = strlen(device)+strlen(host_name)+1+1; dev->port=malloc(buf_size); if(dev->port) { snprintf(dev->port,buf_size,"%s@%s", device,host_name); } } if( dev->port ) { dev_ret = nutscan_add_device_to_device(dev_ret,dev); } else { nutscan_free_device(dev); } device = strtok_r(NULL,";",&device_saveptr); }; phrase = strtok_r(NULL,"\"",&t_saveptr); }; free(t); /* If no device published in avahi data, try to get the device by connecting directly to upsd */ if( !device_found) { snprintf(buf,sizeof(buf),"%u",port); dev = nutscan_scan_nut(ip,ip,buf,avahi_usec_timeout); if(dev) { dev_ret = nutscan_add_device_to_device(dev_ret,dev); } /* add an upsd entry without associated device */ else { dev = nutscan_new_device(); dev->type = TYPE_NUT; dev->driver = strdup("nutclient"); if( proto == AVAHI_PROTO_INET) { nutscan_add_option_to_device(dev,"desc","IPv4"); } if( proto == AVAHI_PROTO_INET6 ) { nutscan_add_option_to_device(dev,"desc","IPv6"); } if( port != PORT) { /*+1+1 is for ':' character and terminating 0 */ /*buf is the string containing the port number*/ buf_size = strlen(host_name)+strlen(buf)+1+1; dev->port=malloc(buf_size); if(dev->port) { snprintf(dev->port,buf_size,"%s:%s", host_name,buf); } } else { dev->port=strdup(host_name); } if( dev->port ) { dev_ret = nutscan_add_device_to_device(dev_ret,dev); } else { nutscan_free_device(dev); } } } }
/* FIXME: SSL support */ static void * list_nut_devices(void * arg) { struct scan_nut_arg * nut_arg = (struct scan_nut_arg*)arg; char *target_hostname = nut_arg->hostname; struct timeval tv; int port; unsigned int numq, numa; const char *query[4]; char **answer; char *hostname = NULL; UPSCONN_t *ups = malloc(sizeof(*ups)); nutscan_device_t * dev = NULL; int buf_size; tv.tv_sec = nut_arg->timeout / (1000*1000); tv.tv_usec = nut_arg->timeout % (1000*1000); query[0] = "UPS"; numq = 1; if ((*nut_upscli_splitaddr)(target_hostname, &hostname, &port) != 0) { free(target_hostname); free(nut_arg); free(ups); return NULL; } if ((*nut_upscli_tryconnect)(ups, hostname, port,UPSCLI_CONN_TRYSSL,&tv) < 0) { free(target_hostname); free(nut_arg); free(ups); return NULL; } if((*nut_upscli_list_start)(ups, numq, query) < 0) { free(target_hostname); free(nut_arg); free(ups); return NULL; } while ((*nut_upscli_list_next)(ups,numq, query, &numa, &answer) == 1) { /* UPS <upsname> <description> */ if (numa < 3) { free(target_hostname); free(nut_arg); free(ups); return NULL; } /* FIXME: check for duplication by getting driver.port and device.serial * for comparison with other busses results */ /* FIXME: * - also print answer[2] if != "Unavailable"? * - for upsmon.conf or ups.conf (using dummy-ups)? */ if (numa >= 3) { dev = nutscan_new_device(); dev->type = TYPE_NUT; dev->driver = strdup("nutclient"); /* +1+1 is for '@' character and terminating 0 */ buf_size = strlen(answer[1])+strlen(hostname)+1+1; dev->port = malloc(buf_size); if( dev->port ) { snprintf(dev->port,buf_size,"%s@%s",answer[1], hostname); #ifdef HAVE_PTHREAD pthread_mutex_lock(&dev_mutex); #endif dev_ret = nutscan_add_device_to_device(dev_ret,dev); #ifdef HAVE_PTHREAD pthread_mutex_unlock(&dev_mutex); #endif } } } free(target_hostname); free(nut_arg); free(ups); return NULL; }
/* return NULL if error */ nutscan_device_t * nutscan_scan_usb() { int ret; char string[256]; char *driver_name = NULL; char *serialnumber = NULL; char *device_name = NULL; char *vendor_name = NULL; struct usb_device *dev; struct usb_bus *bus; usb_dev_handle *udev; nutscan_device_t * nut_dev = NULL; nutscan_device_t * current_nut_dev = NULL; if( !nutscan_avail_usb ) { return NULL; } /* libusb base init */ (*nut_usb_init)(); (*nut_usb_find_busses)(); (*nut_usb_find_devices)(); for (bus = (*nut_usb_busses); bus; bus = bus->next) { for (dev = bus->devices; dev; dev = dev->next) { if ((driver_name = is_usb_device_supported(usb_device_table, dev->descriptor.idVendor, dev->descriptor.idProduct)) != NULL) { /* open the device */ udev = (*nut_usb_open)(dev); if (!udev) { fprintf(stderr,"Failed to open device, \ skipping. (%s)\n", (*nut_usb_strerror)()); continue; } /* get serial number */ if (dev->descriptor.iSerialNumber) { ret = (*nut_usb_get_string_simple)(udev, dev->descriptor.iSerialNumber, string, sizeof(string)); if (ret > 0) { serialnumber = strdup(rtrim(string, ' ')); } } /* get product name */ if (dev->descriptor.iProduct) { ret = (*nut_usb_get_string_simple)(udev, dev->descriptor.iProduct, string, sizeof(string)); if (ret > 0) { device_name = strdup(rtrim(string, ' ')); } } /* get vendor name */ if (dev->descriptor.iManufacturer) { ret = (*nut_usb_get_string_simple)(udev, dev->descriptor.iManufacturer, string, sizeof(string)); if (ret > 0) { vendor_name = strdup(rtrim(string, ' ')); } } nut_dev = nutscan_new_device(); if(nut_dev == NULL) { fprintf(stderr,"Memory allocation \ error\n"); nutscan_free_device(current_nut_dev); free(serialnumber); free(device_name); free(vendor_name); return NULL; } nut_dev->type = TYPE_USB; if(driver_name) { nut_dev->driver = strdup(driver_name); } nut_dev->port = strdup("auto"); sprintf(string,"%04X",dev->descriptor.idVendor); nutscan_add_option_to_device(nut_dev,"vendorid", string); sprintf(string,"%04X", dev->descriptor.idProduct); nutscan_add_option_to_device(nut_dev,"productid", string); if(device_name) { nutscan_add_option_to_device(nut_dev, "product", device_name); free(device_name); } if(serialnumber) { nutscan_add_option_to_device(nut_dev, "serial", serialnumber); free(serialnumber); } if(vendor_name) { nutscan_add_option_to_device(nut_dev, "vendor", vendor_name); free(vendor_name); } nutscan_add_option_to_device(nut_dev,"bus", bus->dirname); current_nut_dev = nutscan_add_device_to_device( current_nut_dev, nut_dev); memset (string, 0, sizeof(string)); (*nut_usb_close)(udev); }