int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, {} }; const char *command; unsigned int i; int rc = 1; udev = udev_new(); if (udev == NULL) goto out; log_open(); udev_set_log_fn(udev, udev_main_log); label_init("/dev"); for (;;) { int option; option = getopt_long(argc, argv, "+dhV", options, NULL); if (option == -1) break; switch (option) { case 'd': log_set_max_level(LOG_DEBUG); udev_set_log_priority(udev, LOG_DEBUG); break; case 'h': rc = adm_help(udev, argc, argv); goto out; case 'V': rc = adm_version(udev, argc, argv); goto out; default: goto out; } } command = argv[optind]; if (command != NULL) for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) { if (strcmp(udevadm_cmds[i]->name, command) == 0) { argc -= optind; argv += optind; /* we need '0' here to reset the internal state */ optind = 0; rc = run_command(udev, udevadm_cmds[i], argc, argv); goto out; } } fprintf(stderr, "missing or unknown command\n\n"); adm_help(udev, argc, argv); rc = 2; out: label_finish(); udev_unref(udev); log_close(); return rc; }
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; }
int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "export", no_argument, NULL, 'x' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; const char *node = NULL; int export = 0; int fd = -1; int cnt; int rc = 0; udev = udev_new(); if (udev == NULL) goto exit; udev_log_init("cdrom_id"); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "dxh", 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 'x': export = 1; break; case 'h': printf("Usage: cdrom_id [options] <device>\n" " --export export key/value pairs\n" " --debug debug to stderr\n" " --help print this help text\n\n"); goto exit; default: rc = 1; goto exit; } } node = argv[optind]; if (!node) { err(udev, "no device\n"); fprintf(stderr, "no device\n"); rc = 1; goto exit; } srand((unsigned int)getpid()); for (cnt = 20; cnt > 0; cnt--) { struct timespec duration; fd = open(node, O_RDONLY|O_NONBLOCK|(is_mounted(node) ? 0 : O_EXCL)); if (fd >= 0 || errno != EBUSY) break; duration.tv_sec = 0; duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); nanosleep(&duration, NULL); } if (fd < 0) { info(udev, "unable to open '%s'\n", node); fprintf(stderr, "unable to open '%s'\n", node); rc = 1; goto exit; } info(udev, "probing: '%s'\n", node); /* same data as original cdrom_id */ if (cd_capability_compat(udev, fd) < 0) { rc = 1; goto exit; } /* check for media - don't bail if there's no media as we still need to * to read profiles */ cd_media_compat(udev, fd); /* check if drive talks MMC */ if (cd_inquiry(udev, fd) < 0) goto print; /* read drive and possibly current profile */ if (cd_profiles(udev, fd) < 0) goto print; /* get session/track info */ cd_media_toc(udev, fd); /* get writable media state */ cd_media_info(udev, fd); print: printf("ID_CDROM=1\n"); if (cd_cd_rom) printf("ID_CDROM_CD=1\n"); if (cd_cd_r) printf("ID_CDROM_CD_R=1\n"); if (cd_cd_rw) printf("ID_CDROM_CD_RW=1\n"); if (cd_dvd_rom) printf("ID_CDROM_DVD=1\n"); if (cd_dvd_r) printf("ID_CDROM_DVD_R=1\n"); if (cd_dvd_rw) printf("ID_CDROM_DVD_RW=1\n"); if (cd_dvd_ram) printf("ID_CDROM_DVD_RAM=1\n"); if (cd_dvd_plus_r) printf("ID_CDROM_DVD_PLUS_R=1\n"); if (cd_dvd_plus_rw) printf("ID_CDROM_DVD_PLUS_RW=1\n"); if (cd_dvd_plus_r_dl) printf("ID_CDROM_DVD_PLUS_R_DL=1\n"); if (cd_dvd_plus_rw_dl) printf("ID_CDROM_DVD_PLUS_RW_DL=1\n"); if (cd_bd) printf("ID_CDROM_BD=1\n"); if (cd_bd_r) printf("ID_CDROM_BD_R=1\n"); if (cd_bd_re) printf("ID_CDROM_BD_RE=1\n"); if (cd_hddvd) printf("ID_CDROM_HDDVD=1\n"); if (cd_hddvd_r) printf("ID_CDROM_HDDVD_R=1\n"); if (cd_hddvd_rw) printf("ID_CDROM_HDDVD_RW=1\n"); if (cd_mo) printf("ID_CDROM_MO=1\n"); if (cd_mrw) printf("ID_CDROM_MRW=1\n"); if (cd_mrw_w) printf("ID_CDROM_MRW_W=1\n"); if (cd_media) printf("ID_CDROM_MEDIA=1\n"); if (cd_media_mo) printf("ID_CDROM_MEDIA_MO=1\n"); if (cd_media_mrw) printf("ID_CDROM_MEDIA_MRW=1\n"); if (cd_media_mrw_w) printf("ID_CDROM_MEDIA_MRW_W=1\n"); if (cd_media_cd_rom) printf("ID_CDROM_MEDIA_CD=1\n"); if (cd_media_cd_r) printf("ID_CDROM_MEDIA_CD_R=1\n"); if (cd_media_cd_rw) printf("ID_CDROM_MEDIA_CD_RW=1\n"); if (cd_media_dvd_rom) printf("ID_CDROM_MEDIA_DVD=1\n"); if (cd_media_dvd_r) printf("ID_CDROM_MEDIA_DVD_R=1\n"); if (cd_media_dvd_ram) printf("ID_CDROM_MEDIA_DVD_RAM=1\n"); if (cd_media_dvd_rw) printf("ID_CDROM_MEDIA_DVD_RW=1\n"); if (cd_media_dvd_plus_r) printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n"); if (cd_media_dvd_plus_rw) printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n"); if (cd_media_dvd_plus_rw_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n"); if (cd_media_dvd_plus_r_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n"); if (cd_media_bd) printf("ID_CDROM_MEDIA_BD=1\n"); if (cd_media_bd_r) printf("ID_CDROM_MEDIA_BD_R=1\n"); if (cd_media_bd_re) printf("ID_CDROM_MEDIA_BD_RE=1\n"); if (cd_media_hddvd) printf("ID_CDROM_MEDIA_HDDVD=1\n"); if (cd_media_hddvd_r) printf("ID_CDROM_MEDIA_HDDVD_R=1\n"); if (cd_media_hddvd_rw) printf("ID_CDROM_MEDIA_HDDVD_RW=1\n"); if (cd_media_state != NULL) printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state); if (cd_media_session_next > 0) printf("ID_CDROM_MEDIA_SESSION_NEXT=%d\n", cd_media_session_next); if (cd_media_session_count > 0) printf("ID_CDROM_MEDIA_SESSION_COUNT=%d\n", cd_media_session_count); if (cd_media_session_count > 1 && cd_media_session_last_offset > 0) printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset); if (cd_media_track_count > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT=%d\n", cd_media_track_count); if (cd_media_track_count_audio > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%d\n", cd_media_track_count_audio); if (cd_media_track_count_data > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%d\n", cd_media_track_count_data); exit: if (fd >= 0) close(fd); udev_unref(udev); udev_log_close(); return rc; }
int main(int argc, char *argv[]) { static const struct option options[] = { { "export", no_argument, NULL, 'e' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; struct udev *udev; struct stat buf; const char *devpath = NULL; char filename[UTIL_PATH_SIZE], devspec[256], devtype[256]; int export = 0; int rc = 1; int i, fd, len; udev = udev_new(); if (udev == NULL) goto exit; udev_log_init("vio_type"); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "edh", options, NULL); if (option == -1) break; switch (option) { case 'e': export = 1; break; case 'd': debug = 1; if (udev_get_log_priority(udev) < LOG_INFO) udev_set_log_priority(udev, LOG_INFO); break; case 'h': printf("Usage: vio_type [--debug] [--help] <devpath>\n" " --debug print debug information\n" " --help print this help text\n\n"); default: goto exit; } } devpath = argv[optind]; if (devpath == NULL) { err(udev, "No device specified"); rc = 2; goto exit; } util_strscpyl(filename, sizeof(filename), udev_get_sys_path(udev), devpath, "/devspec", NULL); fd = open(filename, O_RDONLY); if (fd < 0) { err(udev, "unable to open '%s'", filename); goto exit; } len = read(fd, devspec, sizeof(devspec)); if (len <= 0) { #if !defined(__sparc__) && !defined(__sparc64__) err(udev, "unable to read from '%s'", filename); #endif goto close; } devspec[len] = '\0'; if (devspec[len-1] == '\n') devspec[len-1] = '\0'; close(fd); #if !defined(__sparc__) && !defined(__sparc64__) /* now we look in /proc */ util_strscpyl(filename, sizeof(filename), "/proc/device-tree", devspec, "/device_type", NULL); /* hang around for /proc to catch up */ for (i = 100; i; i--) { if (stat(filename, &buf) == 0) break; usleep(30000); } fd = open(filename, O_RDONLY); if (fd < 0) { err(udev, "unable to open '%s'", filename); goto exit; } len = read(fd, devtype, sizeof(devtype)); if (len <= 0) { err(udev, "unable to read from '%s'", filename); goto close; } devtype[len] = '\0'; if (devtype[len-1] == '\n') devtype[len-1] = '\0'; #else strncpy(devtype,devspec,strlen(devspec)+1); #endif if (export) { printf("VIO_TYPE=%s\n", devtype); } else {
int main (int argc, char** argv) { struct udev *udev; struct udev_device *dev; static const struct option options[] = { { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; char devpath[PATH_MAX]; unsigned long bitmask_ev[NBITS(EV_MAX)]; unsigned long bitmask_abs[NBITS(ABS_MAX)]; unsigned long bitmask_key[NBITS(KEY_MAX)]; unsigned long bitmask_rel[NBITS(REL_MAX)]; udev = udev_new(); if (udev == NULL) return 1; udev_log_init("input_id"); udev_set_log_fn(udev, log_fn); /* CLI argument parsing */ while (1) { int option; option = getopt_long(argc, argv, "dxh", 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': help(); exit(0); default: exit(1); } } if (argv[optind] == NULL) { help(); exit(1); } /* get the device */ snprintf(devpath, sizeof(devpath), "%s/%s", udev_get_sys_path(udev), argv[optind]); dev = udev_device_new_from_syspath(udev, devpath); if (dev == NULL) { fprintf(stderr, "unable to access '%s'\n", devpath); return 1; } /* walk up the parental chain until we find the real input device; the * argument is very likely a subdevice of this, like eventN */ while (dev != NULL && udev_device_get_sysattr_value(dev, "capabilities/ev") == NULL) dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL); /* not an "input" class device */ if (dev == NULL) return 0; /* Use this as a flag that input devices were detected, so that this * program doesn't need to be called more than once per device */ puts("ID_INPUT=1"); get_cap_mask (dev, "capabilities/ev", bitmask_ev, sizeof (bitmask_ev)); get_cap_mask (dev, "capabilities/abs", bitmask_abs, sizeof (bitmask_abs)); get_cap_mask (dev, "capabilities/rel", bitmask_rel, sizeof (bitmask_rel)); get_cap_mask (dev, "capabilities/key", bitmask_key, sizeof (bitmask_key)); test_pointers(bitmask_ev, bitmask_abs, bitmask_key, bitmask_rel); test_key(udev, bitmask_ev, bitmask_key); return 0; }
int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "export", no_argument, NULL, 'x' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; char **devices; FILE *fp; struct mntent *mnt; int rc = 1; udev = udev_new(); if (udev == NULL) goto exit; udev_log_init("fstab_id"); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "dxh", 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: fstab_id [OPTIONS] name [...]\n" " --export print environment keys\n" " --debug debug to stderr\n" " --help print this help text\n\n"); goto exit; case 'x': break; default: rc = 2; goto exit; } } devices = &argv[optind]; if (devices[0] == NULL) { fprintf(stderr, "error: missing device(s) to match\n"); rc = 3; goto exit; } fp = setmntent ("/etc/fstab", "r"); if (fp == NULL) { fprintf(stderr, "error: opening fstab: %s\n", strerror(errno)); rc = 4; goto exit; } while (1) { mnt = getmntent(fp); if (mnt == NULL) break; info(udev, "found '%s'@'%s'\n", mnt->mnt_fsname, mnt->mnt_dir); /* skip root device */ if (strcmp(mnt->mnt_dir, "/") == 0) continue; /* match LABEL */ if (strncmp(mnt->mnt_fsname, "LABEL=", 6) == 0) { const char *label; char str[256]; label = &mnt->mnt_fsname[6]; if (label[0] == '"' || label[0] == '\'') { char *pos; util_strscpy(str, sizeof(str), &label[1]); pos = strrchr(str, label[0]); if (pos == NULL) continue; pos[0] = '\0'; label = str; } if (matches_device_list(udev, devices, label)) { print_fstab_entry(udev, mnt); rc = 0; break; } continue; } /* match UUID */ if (strncmp(mnt->mnt_fsname, "UUID=", 5) == 0) { const char *uuid; char str[256]; uuid = &mnt->mnt_fsname[5]; if (uuid[0] == '"' || uuid[0] == '\'') { char *pos; util_strscpy(str, sizeof(str), &uuid[1]); pos = strrchr(str, uuid[0]); if (pos == NULL) continue; pos[0] = '\0'; uuid = str; } if (matches_device_list(udev, devices, uuid)) { print_fstab_entry(udev, mnt); rc = 0; break; } continue; } /* only devices */ if (strncmp(mnt->mnt_fsname, udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) != 0) continue; if (matches_device_list(udev, devices, &mnt->mnt_fsname[strlen(udev_get_dev_path(udev))+1])) { print_fstab_entry(udev, mnt); rc = 0; break; } } endmntent(fp); exit: udev_unref(udev); udev_log_close(); return rc; }
/** * udev_new: * * Create udev library context. * * The initial refcount is 1, and needs to be decremented to * release the resources of the udev library context. * * Returns: a new udev library context **/ struct udev *udev_new(void) { struct udev *udev; const char *env; char *config_file; FILE *f; udev = calloc(1, sizeof(struct udev)); if (udev == NULL) return NULL; udev->refcount = 1; udev->log_fn = log_stderr; udev->log_priority = LOG_ERR; udev_list_init(&udev->properties_list); udev->run = 1; udev->dev_path = strdup(UDEV_PREFIX "/dev"); udev->sys_path = strdup("/sys"); config_file = strdup(SYSCONFDIR "/udev/udev.conf"); if (udev->dev_path == NULL || udev->sys_path == NULL || config_file == NULL) goto err; /* settings by environment and config file */ env = getenv("SYSFS_PATH"); if (env != NULL) { free(udev->sys_path); udev->sys_path = strdup(env); util_remove_trailing_chars(udev->sys_path, '/'); udev_add_property(udev, "SYSFS_PATH", udev->sys_path); } env = getenv("UDEV_RUN"); if (env != NULL && strcmp(env, "0") == 0) udev->run = 0; env = getenv("UDEV_CONFIG_FILE"); if (env != NULL) { free(config_file); config_file = strdup(env); util_remove_trailing_chars(config_file, '/'); } if (config_file == NULL) goto err; f = fopen(config_file, "r"); if (f != NULL) { char line[UTIL_LINE_SIZE]; int line_nr = 0; while (fgets(line, sizeof(line), f)) { size_t len; char *key; char *val; line_nr++; /* find key */ key = line; while (isspace(key[0])) key++; /* comment or empty line */ if (key[0] == '#' || key[0] == '\0') continue; /* split key/value */ val = strchr(key, '='); if (val == NULL) { err(udev, "missing <key>=<value> in '%s'[%i], skip line\n", config_file, line_nr); continue; } val[0] = '\0'; val++; /* find value */ while (isspace(val[0])) val++; /* terminate key */ len = strlen(key); if (len == 0) continue; while (isspace(key[len-1])) len--; key[len] = '\0'; /* terminate value */ len = strlen(val); if (len == 0) continue; while (isspace(val[len-1])) len--; val[len] = '\0'; if (len == 0) continue; /* unquote */ if (val[0] == '"' || val[0] == '\'') { if (val[len-1] != val[0]) { err(udev, "inconsistent quoting in '%s'[%i], skip line\n", config_file, line_nr); continue; } val[len-1] = '\0'; val++; } if (strcasecmp(key, "udev_log") == 0) { udev_set_log_priority(udev, util_log_priority(val)); continue; } if (strcasecmp(key, "udev_root") == 0) { free(udev->dev_path); udev->dev_path = strdup(val); util_remove_trailing_chars(udev->dev_path, '/'); continue; } if (strcasecmp(key, "udev_rules") == 0) { free(udev->rules_path); udev->rules_path = strdup(val); util_remove_trailing_chars(udev->rules_path, '/'); continue; } } fclose(f); } env = getenv("UDEV_ROOT"); if (env != NULL) { free(udev->dev_path); udev->dev_path = strdup(env); util_remove_trailing_chars(udev->dev_path, '/'); udev_add_property(udev, "UDEV_ROOT", udev->dev_path); } env = getenv("UDEV_LOG"); if (env != NULL) udev_set_log_priority(udev, util_log_priority(env)); if (udev->dev_path == NULL || udev->sys_path == NULL) goto err; dbg(udev, "context %p created\n", udev); dbg(udev, "log_priority=%d\n", udev->log_priority); dbg(udev, "config_file='%s'\n", config_file); dbg(udev, "dev_path='%s'\n", udev->dev_path); dbg(udev, "sys_path='%s'\n", udev->sys_path); if (udev->rules_path != NULL) dbg(udev, "rules_path='%s'\n", udev->rules_path); free(config_file); return udev; err: free(config_file); err(udev, "context creation failed\n"); udev_unref(udev); return NULL; }
static int set_options(struct udev *udev, int argc, char **argv, char *maj_min_dev) { int option; /* * optind is a global extern used by getopt. Since we can call * set_options twice (once for command line, and once for config * file) we have to reset this back to 1. */ optind = 1; while ((option = getopt_long(argc, argv, "d:f:gp:uvVxh", options, NULL)) >= 0) switch (option) { case 'b': all_good = false; break; case 'd': dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, optarg); break; case 'f': strscpy(config_file, MAX_PATH_LEN, optarg); break; case 'g': all_good = true; break; case 'h': help(); exit(0); case 'p': if (streq(optarg, "0x80")) default_page_code = PAGE_80; else if (streq(optarg, "0x83")) default_page_code = PAGE_83; else if (streq(optarg, "pre-spc3-83")) default_page_code = PAGE_83_PRE_SPC3; else { log_error("Unknown page code '%s'", optarg); return -1; } break; case 's': sg_version = atoi(optarg); if (sg_version < 3 || sg_version > 4) { log_error("Unknown SG version '%s'", optarg); return -1; } break; case 'u': reformat_serial = true; break; case 'v': log_set_target(LOG_TARGET_CONSOLE); log_set_max_level(LOG_DEBUG); udev_set_log_priority(udev, LOG_DEBUG); log_open(); break; case 'V': printf("%s\n", VERSION); exit(0); case 'x': export = true; break; case '?': return -1; default: assert_not_reached("Unknown option"); } if (optind < argc && !dev_specified) { dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); } return 0; }
/** * udev_new: * * Create udev library context. This reads the udev configuration * file, and fills in the default values. * * The initial refcount is 1, and needs to be decremented to * release the resources of the udev library context. * * Returns: a new udev library context **/ _public_ struct udev *udev_new(void) { struct udev *udev; const char *env; FILE *f; udev = calloc(1, sizeof(struct udev)); if (udev == NULL) return NULL; udev->refcount = 1; udev->log_fn = log_stderr; udev->log_priority = LOG_INFO; udev_list_init(udev, &udev->properties_list, true); f = fopen("/etc/udev/udev.conf", "re"); if (f != NULL) { char line[UTIL_LINE_SIZE]; int line_nr = 0; while (fgets(line, sizeof(line), f)) { size_t len; char *key; char *val; line_nr++; /* find key */ key = line; while (isspace(key[0])) key++; /* comment or empty line */ if (key[0] == '#' || key[0] == '\0') continue; /* split key/value */ val = strchr(key, '='); if (val == NULL) { udev_err(udev, "missing <key>=<value> in /etc/udev/udev.conf[%i]; skip line\n", line_nr); continue; } val[0] = '\0'; val++; /* find value */ while (isspace(val[0])) val++; /* terminate key */ len = strlen(key); if (len == 0) continue; while (isspace(key[len-1])) len--; key[len] = '\0'; /* terminate value */ len = strlen(val); if (len == 0) continue; while (isspace(val[len-1])) len--; val[len] = '\0'; if (len == 0) continue; /* unquote */ if (val[0] == '"' || val[0] == '\'') { if (val[len-1] != val[0]) { udev_err(udev, "inconsistent quoting in /etc/udev/udev.conf[%i]; skip line\n", line_nr); continue; } val[len-1] = '\0'; val++; } if (streq(key, "udev_log")) { udev_set_log_priority(udev, util_log_priority(val)); continue; } } fclose(f); } /* environment overrides config */ env = secure_getenv("UDEV_LOG"); if (env != NULL) udev_set_log_priority(udev, util_log_priority(env)); return udev; }
int main(int argc, char *argv[]) { struct udev *udev; static const struct option options[] = { { "lock-media", no_argument, NULL, 'l' }, { "unlock-media", no_argument, NULL, 'u' }, { "eject-media", no_argument, NULL, 'e' }, { "debug", no_argument, NULL, 'd' }, { "help", no_argument, NULL, 'h' }, {} }; bool eject = false; bool lock = false; bool unlock = false; const char *node = NULL; int fd = -1; int cnt; int rc = 0; udev = udev_new(); if (udev == NULL) goto exit; log_open(); udev_set_log_fn(udev, log_fn); while (1) { int option; option = getopt_long(argc, argv, "deluh", options, NULL); if (option == -1) break; switch (option) { case 'l': lock = true; break; case 'u': unlock = true; break; case 'e': eject = true; break; case 'd': debug = true; log_set_max_level(LOG_DEBUG); udev_set_log_priority(udev, LOG_DEBUG); break; case 'h': printf("Usage: cdrom_id [options] <device>\n" " --lock-media lock the media (to enable eject request events)\n" " --unlock-media unlock the media\n" " --eject-media eject the media\n" " --debug debug to stderr\n" " --help print this help text\n\n"); goto exit; default: rc = 1; goto exit; } } node = argv[optind]; if (!node) { log_error("no device"); fprintf(stderr, "no device\n"); rc = 1; goto exit; } srand((unsigned int)getpid()); for (cnt = 20; cnt > 0; cnt--) { struct timespec duration; fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC|(is_mounted(node) ? 0 : O_EXCL)); if (fd >= 0 || errno != EBUSY) break; duration.tv_sec = 0; duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000); nanosleep(&duration, NULL); } if (fd < 0) { log_debug("unable to open '%s'", node); fprintf(stderr, "unable to open '%s'\n", node); rc = 1; goto exit; } log_debug("probing: '%s'", node); /* same data as original cdrom_id */ if (cd_capability_compat(udev, fd) < 0) { rc = 1; goto exit; } /* check for media - don't bail if there's no media as we still need to * to read profiles */ cd_media_compat(udev, fd); /* check if drive talks MMC */ if (cd_inquiry(udev, fd) < 0) goto work; /* read drive and possibly current profile */ if (cd_profiles(udev, fd) != 0) goto work; /* at this point we are guaranteed to have media in the drive - find out more about it */ /* get session/track info */ cd_media_toc(udev, fd); /* get writable media state */ cd_media_info(udev, fd); work: /* lock the media, so we enable eject button events */ if (lock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)"); media_lock(udev, fd, true); } if (unlock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); } if (eject) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); log_debug("START_STOP_UNIT (eject)"); media_eject(udev, fd); } printf("ID_CDROM=1\n"); if (cd_cd_rom) printf("ID_CDROM_CD=1\n"); if (cd_cd_r) printf("ID_CDROM_CD_R=1\n"); if (cd_cd_rw) printf("ID_CDROM_CD_RW=1\n"); if (cd_dvd_rom) printf("ID_CDROM_DVD=1\n"); if (cd_dvd_r) printf("ID_CDROM_DVD_R=1\n"); if (cd_dvd_rw) printf("ID_CDROM_DVD_RW=1\n"); if (cd_dvd_ram) printf("ID_CDROM_DVD_RAM=1\n"); if (cd_dvd_plus_r) printf("ID_CDROM_DVD_PLUS_R=1\n"); if (cd_dvd_plus_rw) printf("ID_CDROM_DVD_PLUS_RW=1\n"); if (cd_dvd_plus_r_dl) printf("ID_CDROM_DVD_PLUS_R_DL=1\n"); if (cd_dvd_plus_rw_dl) printf("ID_CDROM_DVD_PLUS_RW_DL=1\n"); if (cd_bd) printf("ID_CDROM_BD=1\n"); if (cd_bd_r) printf("ID_CDROM_BD_R=1\n"); if (cd_bd_re) printf("ID_CDROM_BD_RE=1\n"); if (cd_hddvd) printf("ID_CDROM_HDDVD=1\n"); if (cd_hddvd_r) printf("ID_CDROM_HDDVD_R=1\n"); if (cd_hddvd_rw) printf("ID_CDROM_HDDVD_RW=1\n"); if (cd_mo) printf("ID_CDROM_MO=1\n"); if (cd_mrw) printf("ID_CDROM_MRW=1\n"); if (cd_mrw_w) printf("ID_CDROM_MRW_W=1\n"); if (cd_media) printf("ID_CDROM_MEDIA=1\n"); if (cd_media_mo) printf("ID_CDROM_MEDIA_MO=1\n"); if (cd_media_mrw) printf("ID_CDROM_MEDIA_MRW=1\n"); if (cd_media_mrw_w) printf("ID_CDROM_MEDIA_MRW_W=1\n"); if (cd_media_cd_rom) printf("ID_CDROM_MEDIA_CD=1\n"); if (cd_media_cd_r) printf("ID_CDROM_MEDIA_CD_R=1\n"); if (cd_media_cd_rw) printf("ID_CDROM_MEDIA_CD_RW=1\n"); if (cd_media_dvd_rom) printf("ID_CDROM_MEDIA_DVD=1\n"); if (cd_media_dvd_r) printf("ID_CDROM_MEDIA_DVD_R=1\n"); if (cd_media_dvd_ram) printf("ID_CDROM_MEDIA_DVD_RAM=1\n"); if (cd_media_dvd_rw) printf("ID_CDROM_MEDIA_DVD_RW=1\n"); if (cd_media_dvd_plus_r) printf("ID_CDROM_MEDIA_DVD_PLUS_R=1\n"); if (cd_media_dvd_plus_rw) printf("ID_CDROM_MEDIA_DVD_PLUS_RW=1\n"); if (cd_media_dvd_plus_rw_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_RW_DL=1\n"); if (cd_media_dvd_plus_r_dl) printf("ID_CDROM_MEDIA_DVD_PLUS_R_DL=1\n"); if (cd_media_bd) printf("ID_CDROM_MEDIA_BD=1\n"); if (cd_media_bd_r) printf("ID_CDROM_MEDIA_BD_R=1\n"); if (cd_media_bd_re) printf("ID_CDROM_MEDIA_BD_RE=1\n"); if (cd_media_hddvd) printf("ID_CDROM_MEDIA_HDDVD=1\n"); if (cd_media_hddvd_r) printf("ID_CDROM_MEDIA_HDDVD_R=1\n"); if (cd_media_hddvd_rw) printf("ID_CDROM_MEDIA_HDDVD_RW=1\n"); if (cd_media_state != NULL) printf("ID_CDROM_MEDIA_STATE=%s\n", cd_media_state); if (cd_media_session_next > 0) printf("ID_CDROM_MEDIA_SESSION_NEXT=%d\n", cd_media_session_next); if (cd_media_session_count > 0) printf("ID_CDROM_MEDIA_SESSION_COUNT=%d\n", cd_media_session_count); if (cd_media_session_count > 1 && cd_media_session_last_offset > 0) printf("ID_CDROM_MEDIA_SESSION_LAST_OFFSET=%llu\n", cd_media_session_last_offset); if (cd_media_track_count > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT=%d\n", cd_media_track_count); if (cd_media_track_count_audio > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_AUDIO=%d\n", cd_media_track_count_audio); if (cd_media_track_count_data > 0) printf("ID_CDROM_MEDIA_TRACK_COUNT_DATA=%d\n", cd_media_track_count_data); exit: if (fd >= 0) close(fd); udev_unref(udev); log_close(); return rc; }