static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) { struct udev *udev = udev_device_get_udev(parent); struct udev_device *transportdev; struct udev_device *sessiondev = NULL; const char *target; char *connname; struct udev_device *conndev = NULL; const char *addr; const char *port; /* find iscsi session */ transportdev = parent; while (1) { transportdev = udev_device_get_parent(transportdev); if (transportdev == NULL) return NULL; if (strncmp(udev_device_get_sysname(transportdev), "session", 7) == 0) break; } if (transportdev == NULL) return NULL; /* find iscsi session device */ sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev)); if (sessiondev == NULL) return NULL; target = udev_device_get_sysattr_value(sessiondev, "targetname"); if (target == NULL) { parent = NULL; goto out; } if (asprintf(&connname, "connection%s:0", udev_device_get_sysnum(transportdev)) < 0) { parent = NULL; goto out; } conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname); free(connname); if (conndev == NULL) { parent = NULL; goto out; } addr = udev_device_get_sysattr_value(conndev, "persistent_address"); port = udev_device_get_sysattr_value(conndev, "persistent_port"); if (addr == NULL || port == NULL) { parent = NULL; goto out; } path_prepend(path, "ip-%s:%s-iscsi-%s-lun-%s", addr, port, target, udev_device_get_sysnum(parent)); out: udev_device_unref(sessiondev); udev_device_unref(conndev); return parent; }
static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) { struct udev_device *scsi_dev; scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device"); if (scsi_dev != NULL) { const char *wwpn; const char *lun; const char *hba_id; hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id"); wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn"); lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun"); if (hba_id != NULL && lun != NULL && wwpn != NULL) { path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun); goto out; } } path_prepend(path, "ccw-%s", udev_device_get_sysname(parent)); out: parent = skip_subsystem(parent, "ccw"); return parent; }
/** * Find a location of the suffix in the tree. * @param st the suffixtree in question * @param j the extension number counting from 0 * @param i the current phase - 1 * @param log the log to record errors in * @return the position (combined node and edge-offset) */ static pos *find_beta( suffixtree *st, int j, int i, plugin_log *log ) { pos *p; if ( st->old_j > 0 && st->old_j == j ) { p = pos_create(); p->loc = st->old_beta.loc; p->v = st->old_beta.v; } else if ( j>i ) // empty string { p = pos_create(); p->loc = 0; p->v = st->root; } else if ( j==0 ) // entire string { p = pos_create(); p->loc = i; p->v = st->f; } else // walk across tree { node *v = st->last.v; int len = st->last.loc-node_start(st->last.v)+1; path *q = path_create( node_start(v), len, log ); v = node_parent( v ); while ( v != st->root && node_link(v)==NULL ) { path_prepend( q, node_len(v) ); v = node_parent( v ); } if ( v != st->root ) { v = node_link( v ); p = walk_down( st, v, q ); } else { path_dispose( q ); p = walk_down( st, st->root, path_create(j,i-j+1,log) ); } } st->last = *p; return p; }
/** * Find a location of the suffix in the tree. * @param j the extension number counting from 0 * @param i the current phase - 1 * @return the position (combined node and edge-offset) */ static pos *find_beta( int j, int i ) { pos *p; if ( old_j > 0 && old_j == j ) { p = pos_create(); p->loc = old_beta.loc; p->v = old_beta.v; } else if ( j>i ) // empty string { p = pos_create(); p->loc = 0; p->v = root; } else if ( j==0 ) // entire string { p = pos_create(); p->loc = i; p->v = f; } else // walk across tree { node *v = last.v; int len = last.loc-node_start(last.v)+1; path *q = path_create( node_start(v), len ); v = node_parent( v ); while ( v != root && node_link(v)==NULL ) { path_prepend( q, node_len(v) ); v = node_parent( v ); } if ( v != root ) { v = node_link( v ); p = walk_down( v, q ); } else { path_dispose( q ); p = walk_down( root, path_create(j,i-j+1) ); } } last = *p; return p; }
static struct udev_device *handle_usb(struct udev_device *parent, char **path) { const char *devtype; const char *str; const char *port; devtype = udev_device_get_devtype(parent); if (devtype == NULL || strcmp(devtype, "usb_interface") != 0) return parent; str = udev_device_get_sysname(parent); port = strchr(str, '-'); if (port == NULL) return parent; port++; parent = skip_subsystem(parent, "usb"); path_prepend(path, "usb-0:%s", port); return parent; }
static struct udev_device *handle_scsi(struct udev_device *parent, char **path) { const char *devtype; const char *name; const char *id; devtype = udev_device_get_devtype(parent); if (devtype == NULL || strcmp(devtype, "scsi_device") != 0) return parent; /* firewire */ id = udev_device_get_sysattr_value(parent, "ieee1394_id"); if (id != NULL) { parent = skip_subsystem(parent, "scsi"); path_prepend(path, "ieee1394-0x%s", id); goto out; } /* lousy scsi sysfs does not have a "subsystem" for the transport */ name = udev_device_get_syspath(parent); if (strstr(name, "/rport-") != NULL) { parent = handle_scsi_fibre_channel(parent, path); goto out; } if (strstr(name, "/end_device-") != NULL) { parent = handle_scsi_sas(parent, path); goto out; } if (strstr(name, "/session") != NULL) { parent = handle_scsi_iscsi(parent, path); goto out; } parent = handle_scsi_default(parent, path); out: return parent; }
int main(int argc, char **argv) { static const struct option options[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; struct udev *udev; struct udev_device *dev; struct udev_device *parent; char syspath[UTIL_PATH_SIZE]; const char *devpath; char *path; char *path_suffix; int rc = 1; udev = udev_new(); if (udev == NULL) goto exit; udev_log_init("path_id"); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "dh", options, NULL); if (option == -1) break; switch (option) { case 'd': debug = 1; if (udev_get_log_priority(udev) < LOG_INFO) udev_set_log_priority(udev, LOG_INFO); break; case 'h': printf("Usage: path_id [--debug] [--help] <devpath>\n" " --debug print debug information\n" " --help print this help text\n\n"); default: rc = 1; goto exit; } } devpath = argv[optind]; if (devpath == NULL) { fprintf(stderr, "No device specified\n"); rc = 2; goto exit; } util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), devpath, NULL); dev = udev_device_new_from_syspath(udev, syspath); if (dev == NULL) { fprintf(stderr, "unable to access '%s'\n", devpath); rc = 3; goto exit; } path = NULL; path_suffix = NULL; /* S390 ccw bus */ parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL); if (parent != NULL) { handle_ccw(parent, dev, &path); goto out; } /* walk up the chain of devices and compose path */ parent = dev; while (parent != NULL) { const char *subsys; subsys = udev_device_get_subsystem(parent); if (subsys == NULL) { ; } else if (strcmp(subsys, "scsi_tape") == 0) { handle_scsi_tape(parent, &path_suffix); } else if (strcmp(subsys, "scsi") == 0) { parent = handle_scsi(parent, &path); } else if (strcmp(subsys, "cciss") == 0) { handle_cciss(parent, &path); } else if (strcmp(subsys, "usb") == 0) { parent = handle_usb(parent, &path); } else if (strcmp(subsys, "serio") == 0) { path_prepend(&path, "serio-%s", udev_device_get_sysnum(parent)); parent = skip_subsystem(parent, "serio"); } else if (strcmp(subsys, "pci") == 0) { path_prepend(&path, "pci-%s", udev_device_get_sysname(parent)); parent = skip_subsystem(parent, "pci"); } else if (strcmp(subsys, "platform") == 0) { path_prepend(&path, "platform-%s", udev_device_get_sysname(parent)); parent = skip_subsystem(parent, "platform"); } else if (strcmp(subsys, "xen") == 0) { path_prepend(&path, "xen-%s", udev_device_get_sysname(parent)); parent = skip_subsystem(parent, "xen"); } else if (strcmp(subsys, "virtio") == 0) { path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent)); parent = skip_subsystem(parent, "virtio"); } parent = udev_device_get_parent(parent); } out: if (path != NULL) { if (path_suffix != NULL) { printf("ID_PATH=%s%s\n", path, path_suffix); free(path_suffix); } else { printf("ID_PATH=%s\n", path); } free(path); rc = 0; } udev_device_unref(dev); exit: udev_unref(udev); udev_log_close(); return rc; }
static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) { struct udev_device *hostdev; int host, bus, target, lun; const char *name; char *base; char *pos; DIR *dir; struct dirent *dent; int basenum; hostdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); if (hostdev == NULL) return NULL; name = udev_device_get_sysname(parent); if (sscanf(name, "%d:%d:%d:%d", &host, &bus, &target, &lun) != 4) return NULL; /* rebase host offset to get the local relative number */ basenum = -1; base = strdup(udev_device_get_syspath(hostdev)); if (base == NULL) return NULL; pos = strrchr(base, '/'); if (pos == NULL) { parent = NULL; goto out; } pos[0] = '\0'; dir = opendir(base); if (dir == NULL) { parent = NULL; goto out; } for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { char *rest; int i; if (dent->d_name[0] == '.') continue; if (dent->d_type != DT_DIR && dent->d_type != DT_LNK) continue; if (strncmp(dent->d_name, "host", 4) != 0) continue; i = strtoul(&dent->d_name[4], &rest, 10); if (rest[0] != '\0') continue; if (basenum == -1 || i < basenum) basenum = i; } closedir(dir); if (basenum == -1) { parent = NULL; goto out; } host -= basenum; path_prepend(path, "scsi-%u:%u:%u:%u", host, bus, target, lun); out: free(base); return hostdev; }
void config_load( const char* name, hash_t filter_section, bool built_in, bool overwrite ) { /*lint --e{838} Safety null assign all pointers for all preprocessor paths */ /*lint --e{750} Unused macros in some paths */ #define NUM_SEARCH_PATHS 10 #define ANDROID_ASSET_PATH_INDEX 5 char* sub_exe_path = 0; char* exe_parent_path = 0; char* exe_processed_path = 0; char* abs_exe_parent_path = 0; char* abs_exe_processed_path = 0; char* bundle_path = 0; char* home_dir = 0; char* cmdline_path = 0; char* cwd_config_path = 0; const char* paths[NUM_SEARCH_PATHS]; #if !FOUNDATION_PLATFORM_FAMILY_MOBILE const char* const* cmd_line; int icl, clsize; #endif int start_path, i, j; const char buildsuffix[4][9] = { "/debug", "/release", "/profile", "/deploy" }; const char platformsuffix[7][14] = { "/win32", "/win64", "/osx", "/ios", "/android", "/raspberrypi", "/unknown" }; const char binsuffix[1][5] = { "/bin" }; FOUNDATION_ASSERT( name ); sub_exe_path = path_merge( environment_executable_directory(), "config" ); exe_parent_path = path_merge( environment_executable_directory(), "../config" ); abs_exe_parent_path = path_make_absolute( exe_parent_path ); exe_processed_path = string_clone( environment_executable_directory() ); for( i = 0; i < 4; ++i ) { if( string_ends_with( exe_processed_path, buildsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( buildsuffix[i] ) ] = 0; break; } } for( i = 0; i < 7; ++i ) { if( string_ends_with( exe_processed_path, platformsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( platformsuffix[i] ) ] = 0; break; } } for( i = 0; i < 1; ++i ) { if( string_ends_with( exe_processed_path, binsuffix[i] ) ) { exe_processed_path[ string_length( exe_processed_path ) - string_length( binsuffix[i] ) ] = 0; break; } } exe_processed_path = path_append( exe_processed_path, "config" ); abs_exe_processed_path = path_make_absolute( exe_processed_path ); paths[0] = environment_executable_directory(); paths[1] = sub_exe_path; paths[2] = abs_exe_parent_path; paths[3] = abs_exe_processed_path; #if FOUNDATION_PLATFORM_FAMILY_DESKTOP && !BUILD_DEPLOY paths[4] = environment_initial_working_directory(); #else paths[4] = 0; #endif #if FOUNDATION_PLATFORM_APPLE bundle_path = path_merge( environment_executable_directory(), "../Resources/config" ); paths[5] = bundle_path; #elif FOUNDATION_PLATFORM_ANDROID paths[5] = "/config"; #else paths[5] = 0; #endif #if FOUNDATION_PLATFORM_FAMILY_DESKTOP paths[6] = environment_current_working_directory(); #else paths[6] = 0; #endif paths[7] = 0; paths[8] = 0; string_deallocate( exe_parent_path ); string_deallocate( exe_processed_path ); #if FOUNDATION_PLATFORM_FAMILY_DESKTOP cwd_config_path = path_merge( environment_current_working_directory(), "config" ); paths[7] = cwd_config_path; cmd_line = environment_command_line(); /*lint -e{850} We modify loop var to skip extra arg */ for( icl = 0, clsize = array_size( cmd_line ); icl < clsize; ++icl ) { /*lint -e{613} array_size( cmd_line ) in loop condition does the null pointer guard */ if( string_equal_substr( cmd_line[icl], "--configdir", 11 ) ) { if( string_equal_substr( cmd_line[icl], "--configdir=", 12 ) ) { paths[8] = cmdline_path = string_substr( cmd_line[icl], 12, STRING_NPOS ); } else if( icl < ( clsize - 1 ) ) { paths[8] = cmdline_path = string_clone( cmd_line[++icl] ); } } } #endif start_path = 0; if( !built_in ) { #if FOUNDATION_PLATFORM_WINDOWS home_dir = path_merge( environment_home_directory(), environment_application()->config_dir ); #elif FOUNDATION_PLATFORM_LINUX || FOUNDATION_PLATFORM_MACOSX home_dir = path_prepend( string_concat( ".", environment_application()->config_dir ), environment_home_directory() ); #endif if( home_dir ) paths[9] = home_dir; start_path = 9; } else { paths[9] = 0; } for( i = start_path; i < NUM_SEARCH_PATHS; ++i ) { char* filename; stream_t* istream; bool path_already_searched = false; if( !paths[i] ) continue; for( j = start_path; j < i; ++j ) { if( paths[j] && string_equal( paths[j], paths[i] ) ) { path_already_searched = true; break; } } if( path_already_searched ) continue; //TODO: Support loading configs from virtual file system (i.e in zip/other packages) filename = string_append( path_merge( paths[i], name ), ".ini" ); istream = 0; #if FOUNDATION_PLATFORM_ANDROID if( i == ANDROID_ASSET_PATH_INDEX ) istream = asset_stream_open( filename, STREAM_IN ); else #endif istream = stream_open( filename, STREAM_IN ); if( istream ) { config_parse( istream, filter_section, overwrite ); stream_deallocate( istream ); } string_deallocate( filename ); if( built_in ) { const char* FOUNDATION_PLATFORM_name = #if FOUNDATION_PLATFORM_WINDOWS "windows"; #elif FOUNDATION_PLATFORM_LINUX_RASPBERRYPI "raspberrypi"; #elif FOUNDATION_PLATFORM_LINUX "linux"; #elif FOUNDATION_PLATFORM_MACOSX "osx"; #elif FOUNDATION_PLATFORM_IOS "ios"; #elif FOUNDATION_PLATFORM_ANDROID "android"; #else # error Insert platform name "unknown"; #endif filename = string_append( path_append( path_merge( paths[i], FOUNDATION_PLATFORM_name ), name ), ".ini" ); #if FOUNDATION_PLATFORM_ANDROID if( i == ANDROID_ASSET_PATH_INDEX ) istream = asset_stream_open( filename, STREAM_IN ); else #endif istream = stream_open( filename, STREAM_IN ); if( istream ) { config_parse( istream, filter_section, overwrite ); stream_deallocate( istream ); } string_deallocate( filename ); } } string_deallocate( home_dir ); string_deallocate( cmdline_path ); string_deallocate( sub_exe_path ); string_deallocate( abs_exe_processed_path ); string_deallocate( abs_exe_parent_path ); string_deallocate( bundle_path ); string_deallocate( cwd_config_path ); }