diff options
30 files changed, 738 insertions, 386 deletions
diff --git a/src/accelerometer/accelerometer.c b/src/accelerometer/accelerometer.c index 86966fbd5f..babd66f6b5 100644 --- a/src/accelerometer/accelerometer.c +++ b/src/accelerometer/accelerometer.c @@ -335,7 +335,7 @@ int main (int argc, char** argv) return 0; } - log_debug("opening accelerometer device %s\n", devnode); + log_debug("opening accelerometer device %s", devnode); test_orientation(udev, dev, devnode); free(devnode); log_close(); diff --git a/src/ata_id/ata_id.c b/src/ata_id/ata_id.c index c2bf940cd9..649890618e 100644 --- a/src/ata_id/ata_id.c +++ b/src/ata_id/ata_id.c @@ -463,14 +463,14 @@ int main(int argc, char *argv[]) node = argv[optind]; if (node == NULL) { - log_error("no node specified\n"); + log_error("no node specified"); rc = 1; goto exit; } fd = open(node, O_RDONLY|O_NONBLOCK); if (fd < 0) { - log_error("unable to open '%s'\n", node); + log_error("unable to open '%s'", node); rc = 1; goto exit; } @@ -502,7 +502,7 @@ int main(int argc, char *argv[]) } else { /* If this fails, then try HDIO_GET_IDENTITY */ if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) { - log_info("HDIO_GET_IDENTITY failed for '%s': %m\n", node); + log_debug("HDIO_GET_IDENTITY failed for '%s': %m", node); rc = 2; goto close; } diff --git a/src/cdrom_id/cdrom_id.c b/src/cdrom_id/cdrom_id.c index d0588eb1bd..5b98ff35bd 100644 --- a/src/cdrom_id/cdrom_id.c +++ b/src/cdrom_id/cdrom_id.c @@ -142,10 +142,10 @@ static bool is_mounted(const char *device) static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err) { if (err == -1) { - log_debug("%s failed\n", cmd); + log_debug("%s failed", cmd); return; } - log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh\n", cmd, SK(err), ASC(err), ASCQ(err)); + log_debug("%s failed with SK=%Xh/ASC=%02Xh/ACQ=%02Xh", cmd, SK(err), ASC(err), ASCQ(err)); } struct scsi_cmd { @@ -210,11 +210,11 @@ static int media_lock(struct udev *udev, int fd, bool lock) /* disable the kernel's lock logic */ err = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_LOCK); if (err < 0) - log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed\n"); + log_debug("CDROM_CLEAR_OPTIONS, CDO_LOCK failed"); err = ioctl(fd, CDROM_LOCKDOOR, lock ? 1 : 0); if (err < 0) - log_debug("CDROM_LOCKDOOR failed\n"); + log_debug("CDROM_LOCKDOOR failed"); return err; } @@ -242,7 +242,7 @@ static int cd_capability_compat(struct udev *udev, int fd) capability = ioctl(fd, CDROM_GET_CAPABILITY, NULL); if (capability < 0) { - log_debug("CDROM_GET_CAPABILITY failed\n"); + log_debug("CDROM_GET_CAPABILITY failed"); return -1; } @@ -266,7 +266,7 @@ static int cd_capability_compat(struct udev *udev, int fd) static int cd_media_compat(struct udev *udev, int fd) { if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) != CDS_DISC_OK) { - log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK\n"); + log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK"); return -1; } cd_media = 1; @@ -290,11 +290,11 @@ static int cd_inquiry(struct udev *udev, int fd) } if ((inq[0] & 0x1F) != 5) { - log_debug("not an MMC unit\n"); + log_debug("not an MMC unit"); return -1; } - log_debug("INQUIRY: [%.8s][%.16s][%.4s]\n", inq + 8, inq + 16, inq + 32); + log_debug("INQUIRY: [%.8s][%.16s][%.4s]", inq + 8, inq + 16, inq + 32); return 0; } @@ -304,105 +304,105 @@ static void feature_profile_media(struct udev *udev, int cur_profile) case 0x03: case 0x04: case 0x05: - log_debug("profile 0x%02x \n", cur_profile); + log_debug("profile 0x%02x ", cur_profile); cd_media = 1; cd_media_mo = 1; break; case 0x08: - log_debug("profile 0x%02x media_cd_rom\n", cur_profile); + log_debug("profile 0x%02x media_cd_rom", cur_profile); cd_media = 1; cd_media_cd_rom = 1; break; case 0x09: - log_debug("profile 0x%02x media_cd_r\n", cur_profile); + log_debug("profile 0x%02x media_cd_r", cur_profile); cd_media = 1; cd_media_cd_r = 1; break; case 0x0a: - log_debug("profile 0x%02x media_cd_rw\n", cur_profile); + log_debug("profile 0x%02x media_cd_rw", cur_profile); cd_media = 1; cd_media_cd_rw = 1; break; case 0x10: - log_debug("profile 0x%02x media_dvd_ro\n", cur_profile); + log_debug("profile 0x%02x media_dvd_ro", cur_profile); cd_media = 1; cd_media_dvd_rom = 1; break; case 0x11: - log_debug("profile 0x%02x media_dvd_r\n", cur_profile); + log_debug("profile 0x%02x media_dvd_r", cur_profile); cd_media = 1; cd_media_dvd_r = 1; break; case 0x12: - log_debug("profile 0x%02x media_dvd_ram\n", cur_profile); + log_debug("profile 0x%02x media_dvd_ram", cur_profile); cd_media = 1; cd_media_dvd_ram = 1; break; case 0x13: - log_debug("profile 0x%02x media_dvd_rw_ro\n", cur_profile); + log_debug("profile 0x%02x media_dvd_rw_ro", cur_profile); cd_media = 1; cd_media_dvd_rw = 1; cd_media_dvd_rw_ro = 1; break; case 0x14: - log_debug("profile 0x%02x media_dvd_rw_seq\n", cur_profile); + log_debug("profile 0x%02x media_dvd_rw_seq", cur_profile); cd_media = 1; cd_media_dvd_rw = 1; cd_media_dvd_rw_seq = 1; break; case 0x1B: - log_debug("profile 0x%02x media_dvd_plus_r\n", cur_profile); + log_debug("profile 0x%02x media_dvd_plus_r", cur_profile); cd_media = 1; cd_media_dvd_plus_r = 1; break; case 0x1A: - log_debug("profile 0x%02x media_dvd_plus_rw\n", cur_profile); + log_debug("profile 0x%02x media_dvd_plus_rw", cur_profile); cd_media = 1; cd_media_dvd_plus_rw = 1; break; case 0x2A: - log_debug("profile 0x%02x media_dvd_plus_rw_dl\n", cur_profile); + log_debug("profile 0x%02x media_dvd_plus_rw_dl", cur_profile); cd_media = 1; cd_media_dvd_plus_rw_dl = 1; break; case 0x2B: - log_debug("profile 0x%02x media_dvd_plus_r_dl\n", cur_profile); + log_debug("profile 0x%02x media_dvd_plus_r_dl", cur_profile); cd_media = 1; cd_media_dvd_plus_r_dl = 1; break; case 0x40: - log_debug("profile 0x%02x media_bd\n", cur_profile); + log_debug("profile 0x%02x media_bd", cur_profile); cd_media = 1; cd_media_bd = 1; break; case 0x41: case 0x42: - log_debug("profile 0x%02x media_bd_r\n", cur_profile); + log_debug("profile 0x%02x media_bd_r", cur_profile); cd_media = 1; cd_media_bd_r = 1; break; case 0x43: - log_debug("profile 0x%02x media_bd_re\n", cur_profile); + log_debug("profile 0x%02x media_bd_re", cur_profile); cd_media = 1; cd_media_bd_re = 1; break; case 0x50: - log_debug("profile 0x%02x media_hddvd\n", cur_profile); + log_debug("profile 0x%02x media_hddvd", cur_profile); cd_media = 1; cd_media_hddvd = 1; break; case 0x51: - log_debug("profile 0x%02x media_hddvd_r\n", cur_profile); + log_debug("profile 0x%02x media_hddvd_r", cur_profile); cd_media = 1; cd_media_hddvd_r = 1; break; case 0x52: - log_debug("profile 0x%02x media_hddvd_rw\n", cur_profile); + log_debug("profile 0x%02x media_hddvd_rw", cur_profile); cd_media = 1; cd_media_hddvd_rw = 1; break; default: - log_debug("profile 0x%02x <ignored>\n", cur_profile); + log_debug("profile 0x%02x <ignored>", cur_profile); break; } } @@ -419,77 +419,77 @@ static int feature_profiles(struct udev *udev, const unsigned char *profiles, si case 0x03: case 0x04: case 0x05: - log_debug("profile 0x%02x mo\n", profile); + log_debug("profile 0x%02x mo", profile); cd_mo = 1; break; case 0x08: - log_debug("profile 0x%02x cd_rom\n", profile); + log_debug("profile 0x%02x cd_rom", profile); cd_cd_rom = 1; break; case 0x09: - log_debug("profile 0x%02x cd_r\n", profile); + log_debug("profile 0x%02x cd_r", profile); cd_cd_r = 1; break; case 0x0A: - log_debug("profile 0x%02x cd_rw\n", profile); + log_debug("profile 0x%02x cd_rw", profile); cd_cd_rw = 1; break; case 0x10: - log_debug("profile 0x%02x dvd_rom\n", profile); + log_debug("profile 0x%02x dvd_rom", profile); cd_dvd_rom = 1; break; case 0x12: - log_debug("profile 0x%02x dvd_ram\n", profile); + log_debug("profile 0x%02x dvd_ram", profile); cd_dvd_ram = 1; break; case 0x13: case 0x14: - log_debug("profile 0x%02x dvd_rw\n", profile); + log_debug("profile 0x%02x dvd_rw", profile); cd_dvd_rw = 1; break; case 0x1B: - log_debug("profile 0x%02x dvd_plus_r\n", profile); + log_debug("profile 0x%02x dvd_plus_r", profile); cd_dvd_plus_r = 1; break; case 0x1A: - log_debug("profile 0x%02x dvd_plus_rw\n", profile); + log_debug("profile 0x%02x dvd_plus_rw", profile); cd_dvd_plus_rw = 1; break; case 0x2A: - log_debug("profile 0x%02x dvd_plus_rw_dl\n", profile); + log_debug("profile 0x%02x dvd_plus_rw_dl", profile); cd_dvd_plus_rw_dl = 1; break; case 0x2B: - log_debug("profile 0x%02x dvd_plus_r_dl\n", profile); + log_debug("profile 0x%02x dvd_plus_r_dl", profile); cd_dvd_plus_r_dl = 1; break; case 0x40: cd_bd = 1; - log_debug("profile 0x%02x bd\n", profile); + log_debug("profile 0x%02x bd", profile); break; case 0x41: case 0x42: cd_bd_r = 1; - log_debug("profile 0x%02x bd_r\n", profile); + log_debug("profile 0x%02x bd_r", profile); break; case 0x43: cd_bd_re = 1; - log_debug("profile 0x%02x bd_re\n", profile); + log_debug("profile 0x%02x bd_re", profile); break; case 0x50: cd_hddvd = 1; - log_debug("profile 0x%02x hddvd\n", profile); + log_debug("profile 0x%02x hddvd", profile); break; case 0x51: cd_hddvd_r = 1; - log_debug("profile 0x%02x hddvd_r\n", profile); + log_debug("profile 0x%02x hddvd_r", profile); break; case 0x52: cd_hddvd_rw = 1; - log_debug("profile 0x%02x hddvd_rw\n", profile); + log_debug("profile 0x%02x hddvd_rw", profile); break; default: - log_debug("profile 0x%02x <ignored>\n", profile); + log_debug("profile 0x%02x <ignored>", profile); break; } } @@ -512,13 +512,13 @@ static int cd_profiles_old_mmc(struct udev *udev, int fd) if ((err != 0)) { info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); if (cd_media == 1) { - log_debug("no current profile, but disc is present; assuming CD-ROM\n"); + log_debug("no current profile, but disc is present; assuming CD-ROM"); cd_media_cd_rom = 1; cd_media_track_count = 1; cd_media_track_count_data = 1; return 0; } else { - log_debug("no current profile, assuming no media\n"); + log_debug("no current profile, assuming no media"); return -1; } }; @@ -527,13 +527,13 @@ static int cd_profiles_old_mmc(struct udev *udev, int fd) if (header[2] & 16) { cd_media_cd_rw = 1; - log_debug("profile 0x0a media_cd_rw\n"); + log_debug("profile 0x0a media_cd_rw"); } else if ((header[2] & 3) < 2 && cd_cd_r) { cd_media_cd_r = 1; - log_debug("profile 0x09 media_cd_r\n"); + log_debug("profile 0x09 media_cd_r"); } else { cd_media_cd_rom = 1; - log_debug("profile 0x08 media_cd_rom\n"); + log_debug("profile 0x08 media_cd_rom"); } return 0; } @@ -561,8 +561,8 @@ static int cd_profiles(struct udev *udev, int fd) info_scsi_cmd_err(udev, "GET CONFIGURATION", err); /* handle pre-MMC2 drives which do not support GET CONFIGURATION */ if (SK(err) == 0x5 && ASC(err) == 0x20) { - log_debug("drive is pre-MMC2 and does not support 46h get configuration command\n"); - log_debug("trying to work around the problem\n"); + log_debug("drive is pre-MMC2 and does not support 46h get configuration command"); + log_debug("trying to work around the problem"); ret = cd_profiles_old_mmc(udev, fd); } goto out; @@ -570,18 +570,18 @@ static int cd_profiles(struct udev *udev, int fd) cur_profile = features[6] << 8 | features[7]; if (cur_profile > 0) { - log_debug("current profile 0x%02x\n", cur_profile); + log_debug("current profile 0x%02x", cur_profile); feature_profile_media (udev, cur_profile); ret = 0; /* we have media */ } else { - log_debug("no current profile, assuming no media\n"); + log_debug("no current profile, assuming no media"); } len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; - log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len); + log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len); if (len > sizeof(features)) { - log_debug("can not get features in a single query, truncating\n"); + log_debug("can not get features in a single query, truncating"); len = sizeof(features); } else if (len <= 8) { len = sizeof(features); @@ -601,10 +601,10 @@ static int cd_profiles(struct udev *udev, int fd) /* parse the length once more, in case the drive decided to have other features suddenly :) */ len = features[0] << 24 | features[1] << 16 | features[2] << 8 | features[3]; - log_debug("GET CONFIGURATION: size of features buffer 0x%04x\n", len); + log_debug("GET CONFIGURATION: size of features buffer 0x%04x", len); if (len > sizeof(features)) { - log_debug("can not get features in a single query, truncating\n"); + log_debug("can not get features in a single query, truncating"); len = sizeof(features); } @@ -616,11 +616,11 @@ static int cd_profiles(struct udev *udev, int fd) switch (feature) { case 0x00: - log_debug("GET CONFIGURATION: feature 'profiles', with %i entries\n", features[i+3] / 4); + log_debug("GET CONFIGURATION: feature 'profiles', with %i entries", features[i+3] / 4); feature_profiles(udev, &features[i]+4, features[i+3]); break; default: - log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes\n", feature, features[i+3]); + log_debug("GET CONFIGURATION: feature 0x%04x <ignored>, with 0x%02x bytes", feature, features[i+3]); break; } } @@ -651,8 +651,8 @@ static int cd_media_info(struct udev *udev, int fd) }; cd_media = 1; - log_debug("disk type %02x\n", header[8]); - log_debug("hardware reported media status: %s\n", media_status[header[2] & 3]); + log_debug("disk type %02x", header[8]); + log_debug("hardware reported media status: %s", media_status[header[2] & 3]); /* exclude plain CDROM, some fake cdroms return 0 for "blank" media here */ if (!cd_media_cd_rom) @@ -690,7 +690,7 @@ static int cd_media_info(struct udev *udev, int fd) } if (dvdstruct[4] & 0x02) { cd_media_state = media_status[2]; - log_debug("write-protected DVD-RAM media inserted\n"); + log_debug("write-protected DVD-RAM media inserted"); goto determined; } @@ -707,13 +707,13 @@ static int cd_media_info(struct udev *udev, int fd) len = format[3]; if (len & 7 || len < 16) { - log_debug("invalid format capacities length\n"); + log_debug("invalid format capacities length"); return -1; } switch(format[8] & 3) { case 1: - log_debug("unformatted DVD-RAM media inserted\n"); + log_debug("unformatted DVD-RAM media inserted"); /* This means that last format was interrupted * or failed, blank dvd-ram discs are factory * formatted. Take no action here as it takes @@ -722,12 +722,12 @@ static int cd_media_info(struct udev *udev, int fd) goto determined; case 2: - log_debug("formatted DVD-RAM media inserted\n"); + log_debug("formatted DVD-RAM media inserted"); break; case 3: cd_media = 0; //return no media - log_debug("format capacities returned no media\n"); + log_debug("format capacities returned no media"); return -1; } } @@ -763,9 +763,9 @@ static int cd_media_info(struct udev *udev, int fd) if (!result) { cd_media_state = media_status[0]; - log_debug("no data in blocks 0 or 16, assuming blank\n"); + log_debug("no data in blocks 0 or 16, assuming blank"); } else { - log_debug("data in blocks 0 or 16, assuming complete\n"); + log_debug("data in blocks 0 or 16, assuming complete"); } } @@ -801,7 +801,7 @@ static int cd_media_toc(struct udev *udev, int fd) } len = (header[0] << 8 | header[1]) + 2; - log_debug("READ TOC: len: %d, start track: %d, end track: %d\n", len, header[2], header[3]); + log_debug("READ TOC: len: %d, start track: %d, end track: %d", len, header[2], header[3]); if (len > sizeof(toc)) return -1; if (len < 2) @@ -835,7 +835,7 @@ static int cd_media_toc(struct udev *udev, int fd) is_data_track = (p[1] & 0x04) != 0; block = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; - log_debug("track=%u info=0x%x(%s) start_block=%u\n", + log_debug("track=%u info=0x%x(%s) start_block=%u", p[2], p[1] & 0x0f, is_data_track ? "data":"audio", block); if (is_data_track) @@ -855,7 +855,7 @@ static int cd_media_toc(struct udev *udev, int fd) return -1; } len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7]; - log_debug("last track %u starts at block %u\n", header[4+2], len); + log_debug("last track %u starts at block %u", header[4+2], len); cd_media_session_last_offset = (unsigned long long int)len * 2048; return 0; } @@ -924,7 +924,7 @@ int main(int argc, char *argv[]) node = argv[optind]; if (!node) { - log_error("no device\n"); + log_error("no device"); fprintf(stderr, "no device\n"); rc = 1; goto exit; @@ -942,12 +942,12 @@ int main(int argc, char *argv[]) nanosleep(&duration, NULL); } if (fd < 0) { - log_debug("unable to open '%s'\n", node); + log_debug("unable to open '%s'", node); fprintf(stderr, "unable to open '%s'\n", node); rc = 1; goto exit; } - log_debug("probing: '%s'\n", node); + log_debug("probing: '%s'", node); /* same data as original cdrom_id */ if (cd_capability_compat(udev, fd) < 0) { @@ -978,19 +978,19 @@ int main(int argc, char *argv[]) work: /* lock the media, so we enable eject button events */ if (lock && cd_media) { - log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)\n"); + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)"); media_lock(udev, fd, true); } if (unlock && cd_media) { - log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); } if (eject) { - log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)\n"); + log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); media_lock(udev, fd, false); - log_debug("START_STOP_UNIT (eject)\n"); + log_debug("START_STOP_UNIT (eject)"); media_eject(udev, fd); } diff --git a/src/collect/collect.c b/src/collect/collect.c index 1346f27f91..cb5df01c6a 100644 --- a/src/collect/collect.c +++ b/src/collect/collect.c @@ -61,7 +61,7 @@ static inline struct _mate *node_to_mate(struct udev_list_node *node) return container_of(node, struct _mate, node); } -_noreturn_ static void sig_alrm(int signo) +noreturn static void sig_alrm(int signo) { exit(4); } @@ -97,7 +97,7 @@ static int prepare(char *dir, char *filename) fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR); if (fd < 0) - fprintf(stderr, "Cannot open %s: %s\n", buf, strerror(errno)); + fprintf(stderr, "Cannot open %s: %m\n", buf); if (lockf(fd,F_TLOCK,0) < 0) { if (debug) @@ -109,7 +109,7 @@ static int prepare(char *dir, char *filename) fprintf(stderr, "Acquired lock on %s\n", buf); } else { if (debug) - fprintf(stderr, "Could not get lock on %s: %s\n", buf, strerror(errno)); + fprintf(stderr, "Could not get lock on %s: %m\n", buf); } } @@ -404,7 +404,7 @@ int main(int argc, char **argv) us = argv[argi++]; if (signal(SIGALRM, sig_alrm) == SIG_ERR) { - fprintf(stderr, "Cannot set SIGALRM: %s\n", strerror(errno)); + fprintf(stderr, "Cannot set SIGALRM: %m\n"); ret = 2; goto exit; } diff --git a/src/libudev/Makefile.am b/src/libudev/Makefile.am index 286dc4b62a..84d018ae03 100644 --- a/src/libudev/Makefile.am +++ b/src/libudev/Makefile.am @@ -43,6 +43,7 @@ libudev_la_SOURCES =\ MurmurHash2.c \ path-util.c \ set.c \ + siphash24.c \ strbuf.c \ strv.c \ strxcpyx.c \ @@ -66,6 +67,7 @@ noinst_HEADERS = \ MurmurHash2.h \ path-util.h \ set.h \ + siphash24.h \ socket-util.h \ sparse-endian.h \ strbuf.h \ diff --git a/src/libudev/cgroup-util.c b/src/libudev/cgroup-util.c index 71bd529ad2..af6ce959c1 100644 --- a/src/libudev/cgroup-util.c +++ b/src/libudev/cgroup-util.c @@ -198,7 +198,7 @@ static int join_path(const char *controller, const char *path, const char *suffi int cg_get_path(const char *controller, const char *path, const char *suffix, char **fs) { const char *p; - static __thread bool good = false; + static thread_local bool good = false; assert(fs); @@ -223,9 +223,7 @@ int cg_get_path(const char *controller, const char *path, const char *suffix, ch #define CONTROLLER_VALID \ - "0123456789" \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + DIGITS LETTERS \ "_" bool cg_controller_is_valid(const char *p, bool allow_named) { diff --git a/src/libudev/conf-files.c b/src/libudev/conf-files.c index 2d413999f9..dc4f970313 100644 --- a/src/libudev/conf-files.c +++ b/src/libudev/conf-files.c @@ -53,13 +53,13 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char for (;;) { struct dirent *de; - union dirent_storage buf; char *p; int r; - r = readdir_r(dir, &buf.de, &de); - if (r != 0) - return -r; + errno = 0; + de = readdir(dir); + if (!de && errno != 0) + return -errno; if (!de) break; @@ -71,7 +71,7 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char if (!p) return -ENOMEM; - r = hashmap_put(h, path_get_file_name(p), p); + r = hashmap_put(h, basename(p), p); if (r == -EEXIST) { log_debug("Skipping overridden file: %s.", p); free(p); @@ -92,7 +92,7 @@ static int base_cmp(const void *a, const void *b) { s1 = *(char * const *)a; s2 = *(char * const *)b; - return strcmp(path_get_file_name(s1), path_get_file_name(s2)); + return strcmp(basename(s1), basename(s2)); } static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) { diff --git a/src/libudev/def.h b/src/libudev/def.h index 3c44e27121..d4844f4186 100644 --- a/src/libudev/def.h +++ b/src/libudev/def.h @@ -24,3 +24,8 @@ #include "util.h" #define SYSTEMD_CGROUP_CONTROLLER "name=systemd" + +#define DIGITS "0123456789" +#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS diff --git a/src/libudev/hashmap.c b/src/libudev/hashmap.c index c483fbad11..23e42f7b34 100644 --- a/src/libudev/hashmap.c +++ b/src/libudev/hashmap.c @@ -27,8 +27,9 @@ #include "util.h" #include "hashmap.h" #include "macro.h" +#include "siphash24.h" -#define NBUCKETS 127 +#define INITIAL_N_BUCKETS 31 struct hashmap_entry { const void *key; @@ -42,12 +43,13 @@ struct Hashmap { compare_func_t compare_func; struct hashmap_entry *iterate_list_head, *iterate_list_tail; - unsigned n_entries; - bool from_pool; -}; + struct hashmap_entry ** buckets; + unsigned n_buckets, n_entries; -#define BY_HASH(h) ((struct hashmap_entry**) ((uint8_t*) (h) + ALIGN(sizeof(Hashmap)))) + uint8_t hash_key[HASH_KEY_SIZE]; + bool from_pool:1; +}; struct pool { struct pool *next; @@ -61,9 +63,15 @@ static void *first_hashmap_tile = NULL; static struct pool *first_entry_pool = NULL; static void *first_entry_tile = NULL; -static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size) { +static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t tile_size, unsigned at_least) { unsigned i; + /* When a tile is released we add it to the list and simply + * place the next pointer at its offset 0. */ + + assert(tile_size >= sizeof(void*)); + assert(at_least > 0); + if (*first_tile) { void *r; @@ -78,7 +86,7 @@ static void* allocate_tile(struct pool **first_pool, void **first_tile, size_t t struct pool *p; n = *first_pool ? (*first_pool)->n_tiles : 0; - n = MAX(512U, n * 2); + n = MAX(at_least, n * 2); size = PAGE_ALIGN(ALIGN(sizeof(struct pool)) + n*tile_size); n = (size - ALIGN(sizeof(struct pool))) / tile_size; @@ -103,30 +111,49 @@ static void deallocate_tile(void **first_tile, void *p) { *first_tile = p; } -unsigned string_hash_func(const void *p) { - unsigned hash = 5381; - const signed char *c; - - /* DJB's hash function */ - - for (c = p; *c; c++) - hash = (hash << 5) + hash + (unsigned) *c; - - return hash; +unsigned long string_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { + uint64_t u; + siphash24((uint8_t*) &u, p, strlen(p), hash_key); + return (unsigned long) u; } int string_compare_func(const void *a, const void *b) { return strcmp(a, b); } -unsigned trivial_hash_func(const void *p) { - return PTR_TO_UINT(p); +unsigned long trivial_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) { + uint64_t u; + siphash24((uint8_t*) &u, &p, sizeof(p), hash_key); + return (unsigned long) u; } int trivial_compare_func(const void *a, const void *b) { return a < b ? -1 : (a > b ? 1 : 0); } +static unsigned bucket_hash(Hashmap *h, const void *p) { + return (unsigned) (h->hash_func(p, h->hash_key) % h->n_buckets); +} + +static void get_hash_key(uint8_t hash_key[HASH_KEY_SIZE], bool reuse_is_ok) { + static uint8_t current[HASH_KEY_SIZE]; + static bool current_initialized = false; + + /* Returns a hash function key to use. In order to keep things + * fast we will not generate a new key each time we allocate a + * new hash table. Instead, we'll just reuse the most recently + * generated one, except if we never generated one or when we + * are rehashing an entire hash table because we reached a + * fill level */ + + if (!current_initialized || !reuse_is_ok) { + random_bytes(current, sizeof(current)); + current_initialized = true; + } + + memcpy(hash_key, current, sizeof(current)); +} + Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { bool b; Hashmap *h; @@ -134,10 +161,10 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { b = is_main_thread(); - size = ALIGN(sizeof(Hashmap)) + NBUCKETS * sizeof(struct hashmap_entry*); + size = ALIGN(sizeof(Hashmap)) + INITIAL_N_BUCKETS * sizeof(struct hashmap_entry*); if (b) { - h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size); + h = allocate_tile(&first_hashmap_pool, &first_hashmap_tile, size, 8); if (!h) return NULL; @@ -152,11 +179,16 @@ Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func) { h->hash_func = hash_func ? hash_func : trivial_hash_func; h->compare_func = compare_func ? compare_func : trivial_compare_func; + h->n_buckets = INITIAL_N_BUCKETS; h->n_entries = 0; h->iterate_list_head = h->iterate_list_tail = NULL; + h->buckets = (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap))); + h->from_pool = b; + get_hash_key(h->hash_key, true); + return h; } @@ -165,11 +197,11 @@ static void link_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { assert(e); /* Insert into hash table */ - e->bucket_next = BY_HASH(h)[hash]; + e->bucket_next = h->buckets[hash]; e->bucket_previous = NULL; - if (BY_HASH(h)[hash]) - BY_HASH(h)[hash]->bucket_previous = e; - BY_HASH(h)[hash] = e; + if (h->buckets[hash]) + h->buckets[hash]->bucket_previous = e; + h->buckets[hash] = e; /* Insert into iteration list */ e->iterate_previous = h->iterate_list_tail; @@ -209,7 +241,7 @@ static void unlink_entry(Hashmap *h, struct hashmap_entry *e, unsigned hash) { if (e->bucket_previous) e->bucket_previous->bucket_next = e->bucket_next; else - BY_HASH(h)[hash] = e->bucket_next; + h->buckets[hash] = e->bucket_next; assert(h->n_entries >= 1); h->n_entries--; @@ -221,8 +253,7 @@ static void remove_entry(Hashmap *h, struct hashmap_entry *e) { assert(h); assert(e); - hash = h->hash_func(e->key) % NBUCKETS; - + hash = bucket_hash(h, e->key); unlink_entry(h, e, hash); if (h->from_pool) @@ -240,6 +271,9 @@ void hashmap_free(Hashmap*h) { hashmap_clear(h); + if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap)))) + free(h->buckets); + if (h->from_pool) deallocate_tile(&first_hashmap_tile, h); else @@ -279,34 +313,92 @@ void hashmap_clear_free(Hashmap *h) { static struct hashmap_entry *hash_scan(Hashmap *h, unsigned hash, const void *key) { struct hashmap_entry *e; assert(h); - assert(hash < NBUCKETS); + assert(hash < h->n_buckets); - for (e = BY_HASH(h)[hash]; e; e = e->bucket_next) + for (e = h->buckets[hash]; e; e = e->bucket_next) if (h->compare_func(e->key, key) == 0) return e; return NULL; } +static bool resize_buckets(Hashmap *h) { + struct hashmap_entry **n, *i; + unsigned m; + uint8_t nkey[HASH_KEY_SIZE]; + + assert(h); + + if (_likely_(h->n_entries*4 < h->n_buckets*3)) + return false; + + /* Increase by four */ + m = (h->n_entries+1)*4-1; + + /* If we hit OOM we simply risk packed hashmaps... */ + n = new0(struct hashmap_entry*, m); + if (!n) + return false; + + /* Let's use a different randomized hash key for the + * extension, so that people cannot guess what we are using + * here forever */ + get_hash_key(nkey, false); + + for (i = h->iterate_list_head; i; i = i->iterate_next) { + unsigned long old_bucket, new_bucket; + + old_bucket = h->hash_func(i->key, h->hash_key) % h->n_buckets; + + /* First, drop from old bucket table */ + if (i->bucket_next) + i->bucket_next->bucket_previous = i->bucket_previous; + + if (i->bucket_previous) + i->bucket_previous->bucket_next = i->bucket_next; + else + h->buckets[old_bucket] = i->bucket_next; + + /* Then, add to new backet table */ + new_bucket = h->hash_func(i->key, nkey) % m; + + i->bucket_next = n[new_bucket]; + i->bucket_previous = NULL; + if (n[new_bucket]) + n[new_bucket]->bucket_previous = i; + n[new_bucket] = i; + } + + if (h->buckets != (struct hashmap_entry**) ((uint8_t*) h + ALIGN(sizeof(Hashmap)))) + free(h->buckets); + + h->buckets = n; + h->n_buckets = m; + + memcpy(h->hash_key, nkey, HASH_KEY_SIZE); + + return true; +} + int hashmap_put(Hashmap *h, const void *key, void *value) { struct hashmap_entry *e; unsigned hash; assert(h); - hash = h->hash_func(key) % NBUCKETS; - + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (e) { - if (e->value == value) return 0; - return -EEXIST; } + if (resize_buckets(h)) + hash = bucket_hash(h, key); + if (h->from_pool) - e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry)); + e = allocate_tile(&first_entry_pool, &first_entry_tile, sizeof(struct hashmap_entry), 64U); else e = new(struct hashmap_entry, 1); @@ -328,7 +420,7 @@ void* hashmap_get(Hashmap *h, const void *key) { if (!h) return NULL; - hash = h->hash_func(key) % NBUCKETS; + hash = bucket_hash(h, key); e = hash_scan(h, hash, key); if (!e) return NULL; @@ -342,12 +434,8 @@ bool hashmap_contains(Hashmap *h, const void *key) { if (!h) return false; - hash = h->hash_func(key) % NBUCKETS; - - if (!hash_scan(h, hash, key)) - return false; - - return true; + hash = bucket_hash(h, key); + return !!hash_scan(h, hash, key); } void *hashmap_iterate(Hashmap *h, Iterator *i, const void **key) { diff --git a/src/libudev/hashmap.h b/src/libudev/hashmap.h index 3b65142eca..387c32243e 100644 --- a/src/libudev/hashmap.h +++ b/src/libudev/hashmap.h @@ -30,6 +30,8 @@ * for all read operations. That way it is not necessary to * instantiate an object for each Hashmap use. */ +#define HASH_KEY_SIZE 16 + typedef struct Hashmap Hashmap; typedef struct _IteratorStruct _IteratorStruct; typedef _IteratorStruct* Iterator; @@ -37,16 +39,16 @@ typedef _IteratorStruct* Iterator; #define ITERATOR_FIRST ((Iterator) 0) #define ITERATOR_LAST ((Iterator) -1) -typedef unsigned (*hash_func_t)(const void *p); +typedef unsigned long (*hash_func_t)(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]); typedef int (*compare_func_t)(const void *a, const void *b); -unsigned string_hash_func(const void *p) _pure_; +unsigned long string_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_; int string_compare_func(const void *a, const void *b) _pure_; /* This will compare the passed pointers directly, and will not * dereference them. This is hence not useful for strings or * suchlike. */ -unsigned trivial_hash_func(const void *p) _const_; +unsigned long trivial_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_; int trivial_compare_func(const void *a, const void *b) _const_; Hashmap *hashmap_new(hash_func_t hash_func, compare_func_t compare_func); diff --git a/src/libudev/libudev-queue-private.c b/src/libudev/libudev-queue-private.c index 51a1d672be..80d7ceef2b 100644 --- a/src/libudev/libudev-queue-private.c +++ b/src/libudev/libudev-queue-private.c @@ -224,8 +224,8 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) if (new_queue_file == NULL) goto error; seqnum = udev_queue_export->seqnum_max; - if (fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file) != sizeof(unsigned long long int)) - goto error; + fwrite(&seqnum, 1, sizeof(unsigned long long int), new_queue_file); + /* copy unfinished events only to the new file */ if (devpaths != NULL) { for (i = devpaths->devpaths_first; i < devpaths->devpaths_size; i++) { @@ -239,12 +239,9 @@ static int rebuild_queue_file(struct udev_queue_export *udev_queue_export) err = udev_queue_read_devpath(udev_queue_export->queue_file, devpath, sizeof(devpath)); devpath_len = err; - if (fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file) != 1) - goto error; - if (fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file) != 1) - goto error; - if (fwrite(devpath, 1, devpath_len, new_queue_file) != devpath_len) - goto error; + fwrite(&seqnum, sizeof(unsigned long long int), 1, new_queue_file); + fwrite(&devpath_len, sizeof(unsigned short), 1, new_queue_file); + fwrite(devpath, 1, devpath_len, new_queue_file); } seqnum++; } diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index 2c31d5b1db..6087c8f106 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -87,11 +87,8 @@ uid_t util_lookup_user(struct udev *udev, const char *user) struct passwd *pw; uid_t uid; size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); - char *buf; + char *buf = alloca(buflen); - if (buflen == -1) - buflen = 1024; - buf = alloca(buflen); if (streq(user, "root")) return 0; uid = strtoul(user, &endptr, 10); @@ -114,11 +111,9 @@ gid_t util_lookup_group(struct udev *udev, const char *group) struct group grbuf; struct group *gr; gid_t gid = 0; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *buf = NULL; - if (buflen == -1) - buflen = 1024; if (streq(group, "root")) return 0; gid = strtoul(group, &endptr, 10); diff --git a/src/libudev/log.c b/src/libudev/log.c index da5ad583d9..75157083c6 100644 --- a/src/libudev/log.c +++ b/src/libudev/log.c @@ -115,10 +115,7 @@ void log_close_syslog(void) { static int create_log_socket(int type) { int fd; - /* All output to the syslog/journal fds we do asynchronously, - * and if the buffers are full we just drop the messages */ - - fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); + fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0); if (fd < 0) return -errno; @@ -190,6 +187,12 @@ int log_open(void) { getpid() == 1 || isatty(STDERR_FILENO) <= 0) { + if (log_target == LOG_TARGET_AUTO) + if (r >= 0) { + log_close_syslog(); + log_close_console(); + return r; + } if (log_target == LOG_TARGET_SYSLOG_OR_KMSG || log_target == LOG_TARGET_SYSLOG) { r = log_open_syslog(); @@ -214,8 +217,6 @@ int log_open(void) { log_close_syslog(); - /* Get the real /dev/console if we are PID=1, hence reopen */ - log_close_console(); return log_open_console(); } @@ -270,8 +271,25 @@ static int write_to_console( IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF); IOVEC_SET_STRING(iovec[n++], "\n"); - if (writev(console_fd, iovec, n) < 0) - return -errno; + if (writev(console_fd, iovec, n) < 0) { + + if (errno == EIO && getpid() == 1) { + + /* If somebody tried to kick us from our + * console tty (via vhangup() or suchlike), + * try to reconnect */ + + log_close_console(); + log_open_console(); + + if (console_fd < 0) + return 0; + + if (writev(console_fd, iovec, n) < 0) + return -errno; + } else + return -errno; + } return 1; } @@ -515,25 +533,29 @@ int log_meta( #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-nonliteral" -_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) { +static void log_assert(int level, const char *text, const char *file, int line, const char *func, const char *format) { static char buffer[LINE_MAX]; + if (_likely_(LOG_PRI(level) > log_max_level)) + return; + snprintf(buffer, sizeof(buffer), format, text, file, line, func); char_array_0(buffer); log_abort_msg = buffer; - log_dispatch(LOG_CRIT, file, line, func, NULL, NULL, buffer); - abort(); + log_dispatch(level, file, line, func, NULL, NULL, buffer); } #pragma GCC diagnostic pop -_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) { - log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); +noreturn void log_assert_failed(const char *text, const char *file, int line, const char *func) { + log_assert(LOG_CRIT, text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); + abort(); } -_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { - log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); +noreturn void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { + log_assert(LOG_CRIT, text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); + abort(); } int log_oom_internal(const char *file, int line, const char *func) { @@ -541,6 +563,9 @@ int log_oom_internal(const char *file, int line, const char *func) { return -ENOMEM; } +int log_get_max_level(void) { + return log_max_level; +} static const char *const log_target_table[] = { [LOG_TARGET_CONSOLE] = "console", [LOG_TARGET_KMSG] = "kmsg", diff --git a/src/libudev/log.h b/src/libudev/log.h index 23ada2255c..45a4f9c2f0 100644 --- a/src/libudev/log.h +++ b/src/libudev/log.h @@ -44,6 +44,7 @@ typedef enum LogTarget{ void log_set_target(LogTarget target); void log_set_max_level(int level); +int log_get_max_level(void) _pure_; int log_open(void); void log_close(void); @@ -73,25 +74,32 @@ int log_oom_internal( int line, const char *func); -_noreturn_ void log_assert_failed( +noreturn void log_assert_failed( const char *text, const char *file, int line, const char *func); -_noreturn_ void log_assert_failed_unreachable( +noreturn void log_assert_failed_unreachable( const char *text, const char *file, int line, const char *func); -#define log_full(level, ...) log_meta(level, __FILE__, __LINE__, __func__, __VA_ARGS__) -#define log_debug(...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__) -#define log_info(...) log_meta(LOG_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__) -#define log_notice(...) log_meta(LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__) -#define log_warning(...) log_meta(LOG_WARNING, __FILE__, __LINE__, __func__, __VA_ARGS__) -#define log_error(...) log_meta(LOG_ERR, __FILE__, __LINE__, __func__, __VA_ARGS__) +#define log_full(level, ...) \ +do { \ + if (log_get_max_level() >= (level)) \ + log_meta((level), __FILE__, __LINE__, __func__, __VA_ARGS__); \ +} while (0) + +#define log_debug(...) log_full(LOG_DEBUG, __VA_ARGS__) +#define log_info(...) log_full(LOG_INFO, __VA_ARGS__) +#define log_notice(...) log_full(LOG_NOTICE, __VA_ARGS__) +#define log_warning(...) log_full(LOG_WARNING, __VA_ARGS__) +#define log_error(...) log_full(LOG_ERR, __VA_ARGS__) + +#define log_struct(level, ...) log_struct_internal(level, __FILE__, __LINE__, __func__, __VA_ARGS__) #define log_oom() log_oom_internal(__FILE__, __LINE__, __func__) diff --git a/src/libudev/macro.h b/src/libudev/macro.h index dddc040cec..835610caf3 100644 --- a/src/libudev/macro.h +++ b/src/libudev/macro.h @@ -30,7 +30,6 @@ #define _printf_(a,b) __attribute__ ((format (printf, a, b))) #define _alloc_(...) __attribute__ ((alloc_size(__VA_ARGS__))) #define _sentinel_ __attribute__ ((sentinel)) -#define _noreturn_ __attribute__((noreturn)) #define _pure_ __attribute__ ((pure)) #define _const_ __attribute__ ((const)) #define _packed_ __attribute__ ((packed)) @@ -68,7 +67,6 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { * @member: the name of the member within the struct. * */ - #define container_of(ptr, type, member) \ __extension__ ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ @@ -95,19 +93,9 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { } while (false) #if defined(static_assert) -#define assert_cc(expr) \ - do { \ - static_assert(expr, #expr); \ - } while (false) +#define assert_cc(expr) static_assert(expr, #expr) #else -#define assert_cc(expr) \ - do { \ - switch (0) { \ - case 0: \ - case !!(expr): \ - ; \ - } \ - } while (false) +#define assert_cc(expr) struct UNIQUE(_assert_struct_) { char x[(expr) ? 0 : -1]; }; #endif #define PTR_TO_INT(p) ((int) ((intptr_t) (p))) @@ -174,17 +162,39 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { * the const magic to the type, otherwise the compiler warns about * signed/unsigned comparison, because the magic can be 32 bit unsigned. */ -#define F_TYPE_CMP(a, b) (a == (typeof(a)) b) - +#define F_TYPE_EQUAL(a, b) (a == (typeof(a)) b) /* Returns the number of chars needed to format variables of the * specified type as a decimal string. Adds in extra space for a * negative '-' prefix. */ - #define DECIMAL_STR_MAX(type) \ - (1+(sizeof(type) <= 1 ? 3 : \ + (2+(sizeof(type) <= 1 ? 3 : \ sizeof(type) <= 2 ? 5 : \ sizeof(type) <= 4 ? 10 : \ sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) +/* Define C11 thread_local attribute even on older gcc compiler + * version */ +#ifndef thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define thread_local _Thread_local +#else +#define thread_local __thread +#endif +#endif + +/* Define C11 noreturn without <stdnoreturn.h> and even on older gcc + * compiler versions */ +#ifndef noreturn +#if __STDC_VERSION__ >= 201112L +#define noreturn _Noreturn +#else +#define noreturn __attribute__((noreturn)) +#endif +#endif + #include "log.h" diff --git a/src/libudev/path-util.c b/src/libudev/path-util.c index 616577088c..a4484c8de1 100644 --- a/src/libudev/path-util.c +++ b/src/libudev/path-util.c @@ -107,7 +107,7 @@ char *path_make_absolute(const char *p, const char *prefix) { } char *path_make_absolute_cwd(const char *p) { - char *cwd, *r; + _cleanup_free_ char *cwd = NULL; assert(p); @@ -121,10 +121,7 @@ char *path_make_absolute_cwd(const char *p) { if (!cwd) return NULL; - r = path_make_absolute(p, cwd); - free(cwd); - - return r; + return path_make_absolute(p, cwd); } char **path_strv_canonicalize(char **l) { @@ -152,7 +149,7 @@ char **path_strv_canonicalize(char **l) { } errno = 0; - u = realpath(t, 0); + u = canonicalize_file_name(t); if (!u) { if (errno == ENOENT) u = t; @@ -332,33 +329,37 @@ fallback: return a.st_dev != b.st_dev; } -bool paths_check_timestamp(char **paths, usec_t *paths_ts_usec, bool update) -{ - unsigned int i; +bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool update) { bool changed = false; + const char* const* i; + + assert(timestamp); if (paths == NULL) - goto out; + return false; - for (i = 0; paths[i]; i++) { + STRV_FOREACH(i, paths) { struct stat stats; + usec_t u; - if (stat(paths[i], &stats) < 0) + if (stat(*i, &stats) < 0) continue; - if (paths_ts_usec[i] == timespec_load(&stats.st_mtim)) - continue; + u = timespec_load(&stats.st_mtim); /* first check */ - if (paths_ts_usec[i] != 0) { - log_debug("reload - timestamp of '%s' changed\n", paths[i]); - changed = true; - } + if (*timestamp >= u) + continue; + + log_debug("timestamp of '%s' changed", *i); /* update timestamp */ - if (update) - paths_ts_usec[i] = timespec_load(&stats.st_mtim); + if (update) { + *timestamp = u; + changed = true; + } else + return true; } -out: + return changed; } diff --git a/src/libudev/path-util.h b/src/libudev/path-util.h index 0b7577ff4f..eea7589d00 100644 --- a/src/libudev/path-util.h +++ b/src/libudev/path-util.h @@ -35,5 +35,5 @@ char** path_strv_canonicalize(char **l); char** path_strv_canonicalize_uniq(char **l); int path_is_mount_point(const char *path, bool allow_symlink); +bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update); -bool paths_check_timestamp(char **paths, usec_t *paths_ts_usec, bool update); diff --git a/src/libudev/siphash24.c b/src/libudev/siphash24.c new file mode 100644 index 0000000000..f68bd283a1 --- /dev/null +++ b/src/libudev/siphash24.c @@ -0,0 +1,135 @@ +/* + SipHash reference C implementation + + Written in 2012 by + Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com> + Daniel J. Bernstein <djb@cr.yp.to> + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along with + this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. + + (Minimal changes made by Lennart Poettering, to make clean for inclusion in systemd) +*/ +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include "siphash24.h" + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint8_t u8; + +#define ROTL(x,b) (u64)( ((x) << (b)) | ( (x) >> (64 - (b))) ) + +#define U32TO8_LE(p, v) \ + (p)[0] = (u8)((v) ); (p)[1] = (u8)((v) >> 8); \ + (p)[2] = (u8)((v) >> 16); (p)[3] = (u8)((v) >> 24); + +#define U64TO8_LE(p, v) \ + U32TO8_LE((p), (u32)((v) )); \ + U32TO8_LE((p) + 4, (u32)((v) >> 32)); + +#define U8TO64_LE(p) \ + (((u64)((p)[0]) ) | \ + ((u64)((p)[1]) << 8) | \ + ((u64)((p)[2]) << 16) | \ + ((u64)((p)[3]) << 24) | \ + ((u64)((p)[4]) << 32) | \ + ((u64)((p)[5]) << 40) | \ + ((u64)((p)[6]) << 48) | \ + ((u64)((p)[7]) << 56)) + +#define SIPROUND \ + do { \ + v0 += v1; v1=ROTL(v1,13); v1 ^= v0; v0=ROTL(v0,32); \ + v2 += v3; v3=ROTL(v3,16); v3 ^= v2; \ + v0 += v3; v3=ROTL(v3,21); v3 ^= v0; \ + v2 += v1; v1=ROTL(v1,17); v1 ^= v2; v2=ROTL(v2,32); \ + } while(0) + +/* SipHash-2-4 */ +void siphash24(uint8_t out[8], const void *_in, size_t inlen, const uint8_t k[16]) +{ + /* "somepseudorandomlygeneratedbytes" */ + u64 v0 = 0x736f6d6570736575ULL; + u64 v1 = 0x646f72616e646f6dULL; + u64 v2 = 0x6c7967656e657261ULL; + u64 v3 = 0x7465646279746573ULL; + u64 b; + u64 k0 = U8TO64_LE( k ); + u64 k1 = U8TO64_LE( k + 8 ); + u64 m; + const u8 *in = _in; + const u8 *end = in + inlen - ( inlen % sizeof( u64 ) ); + const int left = inlen & 7; + b = ( ( u64 )inlen ) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + + for ( ; in != end; in += 8 ) + { + m = U8TO64_LE( in ); +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) compress %08x %08x\n", ( int )inlen, ( u32 )( m >> 32 ), ( u32 )m ); +#endif + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + + switch( left ) + { + case 7: b |= ( ( u64 )in[ 6] ) << 48; + + case 6: b |= ( ( u64 )in[ 5] ) << 40; + + case 5: b |= ( ( u64 )in[ 4] ) << 32; + + case 4: b |= ( ( u64 )in[ 3] ) << 24; + + case 3: b |= ( ( u64 )in[ 2] ) << 16; + + case 2: b |= ( ( u64 )in[ 1] ) << 8; + + case 1: b |= ( ( u64 )in[ 0] ); break; + + case 0: break; + } + +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); + printf( "(%3d) padding %08x %08x\n", ( int )inlen, ( u32 )( b >> 32 ), ( u32 )b ); +#endif + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; +#ifdef DEBUG + printf( "(%3d) v0 %08x %08x\n", ( int )inlen, ( u32 )( v0 >> 32 ), ( u32 )v0 ); + printf( "(%3d) v1 %08x %08x\n", ( int )inlen, ( u32 )( v1 >> 32 ), ( u32 )v1 ); + printf( "(%3d) v2 %08x %08x\n", ( int )inlen, ( u32 )( v2 >> 32 ), ( u32 )v2 ); + printf( "(%3d) v3 %08x %08x\n", ( int )inlen, ( u32 )( v3 >> 32 ), ( u32 )v3 ); +#endif + v2 ^= 0xff; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + U64TO8_LE( out, b ); +} diff --git a/src/libudev/siphash24.h b/src/libudev/siphash24.h new file mode 100644 index 0000000000..3253c179b6 --- /dev/null +++ b/src/libudev/siphash24.h @@ -0,0 +1,4 @@ +#include <inttypes.h> +#include <sys/types.h> + +void siphash24(uint8_t out[8], const void *in, size_t inlen, const uint8_t k[16]); diff --git a/src/libudev/socket-util.h b/src/libudev/socket-util.h index f362757bc0..2daa3279fa 100644 --- a/src/libudev/socket-util.h +++ b/src/libudev/socket-util.h @@ -1,9 +1,5 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - /*** - This file is part of systemd. + This file is part of eudev, forked from systemd. Copyright 2010 Lennart Poettering @@ -21,14 +17,20 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <sys/socket.h> #include <netinet/in.h> +#include <sys/un.h> +#include <net/if.h> +#include <asm/types.h> #include <linux/netlink.h> +#include <linux/if_packet.h> union sockaddr_union { struct sockaddr sa; - struct sockaddr_in in4; + struct sockaddr_in in; struct sockaddr_in6 in6; struct sockaddr_un un; struct sockaddr_nl nl; struct sockaddr_storage storage; + struct sockaddr_ll ll; }; diff --git a/src/libudev/sparse-endian.h b/src/libudev/sparse-endian.h index 51694bebb7..eb4dbf3615 100644 --- a/src/libudev/sparse-endian.h +++ b/src/libudev/sparse-endian.h @@ -23,7 +23,6 @@ #include <endian.h> #include <stdint.h> -#include <byteswap.h> #ifdef __CHECKER__ #define __bitwise __attribute__((bitwise)) diff --git a/src/libudev/strv.c b/src/libudev/strv.c index 3619701e9d..cbfe2388d6 100644 --- a/src/libudev/strv.c +++ b/src/libudev/strv.c @@ -202,15 +202,11 @@ char **strv_remove(char **l, const char *s) { /* Drops every occurrence of s in the string list, edits * in-place. */ - for (f = t = l; *f; f++) { - - if (streq(*f, s)) { + for (f = t = l; *f; f++) + if (streq(*f, s)) free(*f); - continue; - } - - *(t++) = *f; - } + else + *(t++) = *f; *t = NULL; return l; diff --git a/src/libudev/strv.h b/src/libudev/strv.h index 9fba94e566..12fa9f0524 100644 --- a/src/libudev/strv.h +++ b/src/libudev/strv.h @@ -31,6 +31,7 @@ static inline void strv_freep(char ***l) { strv_free(*l); } +void strv_free(char **l); #define _cleanup_strv_free_ _cleanup_(strv_freep) char **strv_copy(char * const *l); diff --git a/src/libudev/strxcpyx.c b/src/libudev/strxcpyx.c index fbdf5ac658..6efa237d4b 100644 --- a/src/libudev/strxcpyx.c +++ b/src/libudev/strxcpyx.c @@ -29,8 +29,7 @@ #include <string.h> #include "strxcpyx.h" -size_t strpcpy(char **dest, size_t size, const char *src) -{ +size_t strpcpy(char **dest, size_t size, const char *src) { size_t len; len = strlen(src); @@ -48,8 +47,7 @@ size_t strpcpy(char **dest, size_t size, const char *src) return size; } -size_t strpcpyf(char **dest, size_t size, const char *src, ...) -{ +size_t strpcpyf(char **dest, size_t size, const char *src, ...) { va_list va; int i; @@ -67,8 +65,7 @@ size_t strpcpyf(char **dest, size_t size, const char *src, ...) return size; } -size_t strpcpyl(char **dest, size_t size, const char *src, ...) -{ +size_t strpcpyl(char **dest, size_t size, const char *src, ...) { va_list va; va_start(va, src); @@ -80,8 +77,7 @@ size_t strpcpyl(char **dest, size_t size, const char *src, ...) return size; } -size_t strscpy(char *dest, size_t size, const char *src) -{ +size_t strscpy(char *dest, size_t size, const char *src) { char *s; s = dest; diff --git a/src/libudev/util.c b/src/libudev/util.c index 98be5307f6..93f60b8ec4 100644 --- a/src/libudev/util.c +++ b/src/libudev/util.c @@ -1,7 +1,5 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** - This file is part of systemd. + This file is part of eudev, forked from systemd. Copyright 2010 Lennart Poettering @@ -78,7 +76,7 @@ static volatile unsigned cached_columns = 0; static volatile unsigned cached_lines = 0; size_t page_size(void) { - static __thread size_t pgsz = 0; + static thread_local size_t pgsz = 0; long r; if (_likely_(pgsz > 0)) @@ -615,6 +613,50 @@ bool ignore_file(const char *filename) { return ignore_file_allow_backup(filename); } +void random_bytes(void *p, size_t n) { + static bool srand_called = false; + _cleanup_close_ int fd; + ssize_t k; + uint8_t *q; + + fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + if (fd < 0) + goto fallback; + + k = loop_read(fd, p, n, true); + if (k < 0 || (size_t) k != n) + goto fallback; + + return; + +fallback: + + if (!srand_called) { + +#ifdef HAVE_SYS_AUXV_H + /* The kernel provides us with a bit of entropy in + * auxv, so let's try to make use of that to seed the + * pseudo-random generator. It's better than + * nothing... */ + + void *auxv; + + auxv = (void*) getauxval(AT_RANDOM); + if (auxv) + srand(*(unsigned*) auxv); + else +#endif + srand(time(NULL) + gettid()); + + srand_called = true; + } + + /* If some idiot made /dev/urandom unavailable to us, he'll + * get a PRNG instead. */ + for (q = p; q < (uint8_t*) p + n; q ++) + *q = rand(); +} + int open_terminal(const char *name, int mode) { int fd, r; unsigned c = 0; @@ -665,9 +707,9 @@ int open_terminal(const char *name, int mode) { _pure_ static int is_temporary_fs(struct statfs *s) { assert(s); - return - F_TYPE_CMP(s->f_type, TMPFS_MAGIC) || - F_TYPE_CMP(s->f_type, RAMFS_MAGIC); + + return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) || + F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC); } int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) { @@ -823,6 +865,55 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) { return 0; } +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) { + uint8_t *p; + ssize_t n = 0; + + assert(fd >= 0); + assert(buf); + + p = buf; + + while (nbytes > 0) { + ssize_t k; + + if ((k = read(fd, p, nbytes)) <= 0) { + + if (k < 0 && errno == EINTR) + continue; + + if (k < 0 && errno == EAGAIN && do_poll) { + struct pollfd pollfd = { + .fd = fd, + .events = POLLIN, + }; + + if (poll(&pollfd, 1, -1) < 0) { + if (errno == EINTR) + continue; + + return n > 0 ? n : -errno; + } + + /* We knowingly ignore the revents value here, + * and expect that any error/EOF is reported + * via read()/write() + */ + + continue; + } + + return n > 0 ? n : (k < 0 ? -errno : 0); + } + + p += k; + nbytes -= k; + n += k; + } + + return n; +} + char *strjoin(const char *x, ...) { va_list ap; size_t l; diff --git a/src/libudev/util.h b/src/libudev/util.h index 50e6a44af5..14233c9d7e 100644 --- a/src/libudev/util.h +++ b/src/libudev/util.h @@ -1,9 +1,5 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - -#pragma once - /*** - This file is part of systemd. + This file is part of eudev, forked from systemd. Copyright 2010 Lennart Poettering @@ -21,6 +17,8 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#pragma once + #include <string.h> #include <time.h> #include <stdlib.h> @@ -149,6 +147,8 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pu bool ignore_file(const char *filename) _pure_; +void random_bytes(void *p, size_t n); + /* For basic lookup tables with strictly enumerated entries */ #define __DEFINE_STRING_TABLE_LOOKUP(name,type,scope) \ scope const char *name##_to_string(type i) { \ @@ -207,6 +207,7 @@ int open_terminal(const char *name, int mode); int fopen_temporary(const char *path, FILE **_f, char **_temp_path); +ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll); int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid); bool null_or_empty(struct stat *st) _pure_; diff --git a/src/scsi_id/scsi_id.c b/src/scsi_id/scsi_id.c index 58a54d4a63..849453f8eb 100644 --- a/src/scsi_id/scsi_id.c +++ b/src/scsi_id/scsi_id.c @@ -18,13 +18,14 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> +#include <stdbool.h> #include <unistd.h> #include <signal.h> #include <fcntl.h> #include <errno.h> #include <string.h> #include <syslog.h> -#include <stdarg.h> #include <ctype.h> #include <getopt.h> #include <sys/stat.h> @@ -32,34 +33,31 @@ #include "libudev.h" #include "libudev-private.h" #include "scsi_id.h" +#include "udev-util.h" static const struct option options[] = { - { "device", required_argument, NULL, 'd' }, - { "config", required_argument, NULL, 'f' }, - { "page", required_argument, NULL, 'p' }, - { "blacklisted", no_argument, NULL, 'b' }, - { "whitelisted", no_argument, NULL, 'g' }, - { "replace-whitespace", no_argument, NULL, 'u' }, - { "sg-version", required_argument, NULL, 's' }, - { "verbose", no_argument, NULL, 'v' }, - { "version", no_argument, NULL, 'V' }, - { "export", no_argument, NULL, 'x' }, - { "help", no_argument, NULL, 'h' }, + { "device", required_argument, NULL, 'd' }, + { "config", required_argument, NULL, 'f' }, + { "page", required_argument, NULL, 'p' }, + { "blacklisted", no_argument, NULL, 'b' }, + { "whitelisted", no_argument, NULL, 'g' }, + { "replace-whitespace", no_argument, NULL, 'u' }, + { "sg-version", required_argument, NULL, 's' }, + { "verbose", no_argument, NULL, 'v' }, + { "version", no_argument, NULL, 'V' }, /* don't advertise -V */ + { "export", no_argument, NULL, 'x' }, + { "help", no_argument, NULL, 'h' }, {} }; -static const char short_options[] = "d:f:ghip:uvVx"; -static const char dev_short_options[] = "bgp:"; - -static int all_good; -static int dev_specified; +static bool all_good = false; +static bool dev_specified = false; static char config_file[MAX_PATH_LEN] = "/etc/scsi_id.config"; -static enum page_code default_page_code; +static enum page_code default_page_code = PAGE_UNSPECIFIED; static int sg_version = 4; -static int use_stderr; -static int debug; -static int reformat_serial; -static int export; +static int debug = 0; +static bool reformat_serial = false; +static bool export = false; static char vendor_str[64]; static char model_str[64]; static char vendor_enc_str[256]; @@ -173,7 +171,7 @@ static int get_file_options(struct udev *udev, int *argc, char ***newargv) { char *buffer; - FILE *fd; + _cleanup_fclose_ FILE *f; char *buf; char *str1; char *vendor_in, *model_in, *options_in; /* read in from file */ @@ -181,12 +179,12 @@ static int get_file_options(struct udev *udev, int c; int retval = 0; - fd = fopen(config_file, "re"); - if (fd == NULL) { - if (errno == ENOENT) { + f = fopen(config_file, "re"); + if (f == NULL) { + if (errno == ENOENT) return 1; - } else { - log_error("can't open %s: %s\n", config_file, strerror(errno)); + else { + log_error("can't open %s: %m", config_file); return -1; } } @@ -197,22 +195,20 @@ static int get_file_options(struct udev *udev, * points into this buffer for its strings). */ buffer = malloc(MAX_BUFFER_LEN); - if (!buffer) { - fclose(fd); + if (!buffer) return log_oom(); - } *newargv = NULL; lineno = 0; while (1) { vendor_in = model_in = options_in = NULL; - buf = fgets(buffer, MAX_BUFFER_LEN, fd); + buf = fgets(buffer, MAX_BUFFER_LEN, f); if (buf == NULL) break; lineno++; if (buf[strlen(buffer) - 1] != '\n') { - log_error("Config file line %d too long\n", lineno); + log_error("Config file line %d too long", lineno); break; } @@ -261,17 +257,17 @@ static int get_file_options(struct udev *udev, * Only allow: [vendor=foo[,model=bar]]options=stuff */ if (!options_in || (!vendor_in && model_in)) { - log_error("Error parsing config file line %d '%s'\n", lineno, buffer); + log_error("Error parsing config file line %d '%s'", lineno, buffer); retval = -1; break; } if (vendor == NULL) { if (vendor_in == NULL) break; - } else if ((vendor_in && strneq(vendor, vendor_in, - strlen(vendor_in))) && - (!model_in || (strneq(model, model_in, - strlen(model_in))))) { + } else if (vendor_in && + strneq(vendor, vendor_in, strlen(vendor_in)) && + (!model_in || + (strneq(model, model_in, strlen(model_in))))) { /* * Matched vendor and optionally model. * @@ -314,12 +310,27 @@ static int get_file_options(struct udev *udev, } if (retval != 0) free(buffer); - fclose(fd); return retval; } +static void help(void) { + printf("Usage: scsi_id [OPTION...] DEVICE\n" + " -d,--device= device node for SG_IO commands\n" + " -f,--config= location of config file\n" + " -p,--page=0x80|0x83|pre-spc3-83 SCSI page (0x80, 0x83, pre-spc3-83)\n" + " -s,--sg-version=3|4 use SGv3 or SGv4\n" + " -b,--blacklisted threat device as blacklisted\n" + " -g,--whitelisted threat device as whitelisted\n" + " -u,--replace-whitespace replace all whitespace by underscores\n" + " -v,--verbose verbose logging\n" + " --version print version\n" + " -x,--export print values as environment keys\n" + " -h,--help print this help text\n\n"); + +} + static int set_options(struct udev *udev, - int argc, char **argv, const char *short_opts, + int argc, char **argv, char *maj_min_dev) { int option; @@ -330,57 +341,38 @@ static int set_options(struct udev *udev, * file) we have to reset this back to 1. */ optind = 1; - while (1) { - option = getopt_long(argc, argv, short_opts, options, NULL); - if (option == -1) - break; - + while ((option = getopt_long(argc, argv, "d:f:gp:uvVxh", options, NULL)) >= 0) switch (option) { case 'b': - all_good = 0; + all_good = false; break; case 'd': - dev_specified = 1; + dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, optarg); break; - case 'e': - use_stderr = 1; - break; - case 'f': strscpy(config_file, MAX_PATH_LEN, optarg); break; case 'g': - all_good = 1; + all_good = true; break; case 'h': - printf("Usage: scsi_id OPTIONS <device>\n" - " --device= device node for SG_IO commands\n" - " --config= location of config file\n" - " --page=0x80|0x83|pre-spc3-83 SCSI page (0x80, 0x83, pre-spc3-83)\n" - " --sg-version=3|4 use SGv3 or SGv4\n" - " --blacklisted threat device as blacklisted\n" - " --whitelisted threat device as whitelisted\n" - " --replace-whitespace replace all whitespaces by underscores\n" - " --verbose verbose logging\n" - " --version print version\n" - " --export print values as environment keys\n" - " --help print this help text\n\n"); + help(); exit(0); case 'p': - if (streq(optarg, "0x80")) { + if (streq(optarg, "0x80")) default_page_code = PAGE_80; - } else if (streq(optarg, "0x83")) { + else if (streq(optarg, "0x83")) default_page_code = PAGE_83; - } else if (streq(optarg, "pre-spc3-83")) { + else if (streq(optarg, "pre-spc3-83")) default_page_code = PAGE_83_PRE_SPC3; - } else { - log_error("Unknown page code '%s'\n", optarg); + else { + log_error("Unknown page code '%s'", optarg); return -1; } break; @@ -388,17 +380,13 @@ static int set_options(struct udev *udev, case 's': sg_version = atoi(optarg); if (sg_version < 3 || sg_version > 4) { - log_error("Unknown SG version '%s'\n", optarg); + log_error("Unknown SG version '%s'", optarg); return -1; } break; case 'u': - reformat_serial = 1; - break; - - case 'x': - export = 1; + reformat_serial = true; break; case 'v': @@ -410,14 +398,22 @@ static int set_options(struct udev *udev, exit(0); break; + case 'x': + export = true; + break; + + case '?': + return -1; + default: - exit(1); + assert_not_reached("Unknown option"); } - } + if (optind < argc && !dev_specified) { - dev_specified = 1; + dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); } + return 0; } @@ -436,7 +432,7 @@ static int per_dev_options(struct udev *udev, optind = 1; /* reset this global extern */ while (retval == 0) { - option = getopt_long(newargc, newargv, dev_short_options, options, NULL); + option = getopt_long(newargc, newargv, "bgp:", options, NULL); if (option == -1) break; @@ -457,13 +453,13 @@ static int per_dev_options(struct udev *udev, } else if (streq(optarg, "pre-spc3-83")) { *page_code = PAGE_83_PRE_SPC3; } else { - log_error("Unknown page code '%s'\n", optarg); + log_error("Unknown page code '%s'", optarg); retval = -1; } break; default: - log_error("Unknown or bad option '%c' (0x%x)\n", option, option); + log_error("Unknown or bad option '%c' (0x%x)", option, option); retval = -1; break; } @@ -505,13 +501,11 @@ static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, co */ static int scsi_id(struct udev *udev, char *maj_min_dev) { - struct scsi_id_device dev_scsi; + struct scsi_id_device dev_scsi = {}; int good_dev; int page_code; int retval = 0; - memset(&dev_scsi, 0x00, sizeof(struct scsi_id_device)); - if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { retval = 1; goto out; @@ -584,11 +578,11 @@ out: int main(int argc, char **argv) { - struct udev *udev; + _cleanup_udev_unref_ struct udev *udev; int retval = 0; char maj_min_dev[MAX_PATH_LEN]; int newargc; - char **newargv; + char **newargv = NULL; udev = udev_new(); if (udev == NULL) @@ -600,28 +594,28 @@ int main(int argc, char **argv) /* * Get config file options. */ - newargv = NULL; retval = get_file_options(udev, NULL, NULL, &newargc, &newargv); if (retval < 0) { retval = 1; goto exit; } - if (newargv && (retval == 0)) { - if (set_options(udev, newargc, newargv, short_options, maj_min_dev) < 0) { + if (retval == 0) { + assert(newargv); + + if (set_options(udev, newargc, newargv, maj_min_dev) < 0) { retval = 2; goto exit; } - free(newargv); } /* * Get command line options (overriding any config file settings). */ - if (set_options(udev, argc, argv, short_options, maj_min_dev) < 0) + if (set_options(udev, argc, argv, maj_min_dev) < 0) exit(1); if (!dev_specified) { - log_error("no device specified\n"); + log_error("no device specified"); retval = 1; goto exit; } @@ -629,7 +623,10 @@ int main(int argc, char **argv) retval = scsi_id(udev, maj_min_dev); exit: - udev_unref(udev); + if (newargv) { + free(newargv[0]); + free(newargv); + } log_close(); return retval; } diff --git a/src/scsi_id/scsi_id.h b/src/scsi_id/scsi_id.h index 103e443d07..648b5ce42a 100644 --- a/src/scsi_id/scsi_id.h +++ b/src/scsi_id/scsi_id.h @@ -66,8 +66,8 @@ int scsi_get_serial(struct udev *udev, struct scsi_id_device *dev_scsi, const ch * Page code values. */ enum page_code { - PAGE_83_PRE_SPC3 = -0x83, - PAGE_UNSPECIFIED = 0x00, - PAGE_80 = 0x80, - PAGE_83 = 0x83, + PAGE_83_PRE_SPC3 = -0x83, + PAGE_UNSPECIFIED = 0x00, + PAGE_80 = 0x80, + PAGE_83 = 0x83, }; diff --git a/src/scsi_id/scsi_serial.c b/src/scsi_id/scsi_serial.c index d522a23a08..66e752e426 100644 --- a/src/scsi_id/scsi_serial.c +++ b/src/scsi_id/scsi_serial.c @@ -197,7 +197,7 @@ static int scsi_dump_sense(struct udev *udev, */ if (sb_len < 1) { - log_debug("%s: sense buffer empty\n", dev_scsi->kernel); + log_debug("%s: sense buffer empty", dev_scsi->kernel); return -1; } @@ -210,7 +210,7 @@ static int scsi_dump_sense(struct udev *udev, */ s = sense_buffer[7] + 8; if (sb_len < s) { - log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n", + log_debug("%s: sense buffer too small %d bytes, %d bytes too short", dev_scsi->kernel, sb_len, s - sb_len); return -1; } @@ -220,7 +220,7 @@ static int scsi_dump_sense(struct udev *udev, /* * Possible? */ - log_debug("%s: sense result too" " small %d bytes\n", + log_debug("%s: sense result too" " small %d bytes", dev_scsi->kernel, s); return -1; } @@ -231,25 +231,25 @@ static int scsi_dump_sense(struct udev *udev, asc = sense_buffer[2]; ascq = sense_buffer[3]; } else { - log_debug("%s: invalid sense code 0x%x\n", + log_debug("%s: invalid sense code 0x%x", dev_scsi->kernel, code); return -1; } - log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", + log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x", dev_scsi->kernel, sense_key, asc, ascq); } else { if (sb_len < 4) { - log_debug("%s: sense buffer too small %d bytes, %d bytes too short\n", + log_debug("%s: sense buffer too small %d bytes, %d bytes too short", dev_scsi->kernel, sb_len, 4 - sb_len); return -1; } if (sense_buffer[0] < 15) - log_debug("%s: old sense key: 0x%x\n", dev_scsi->kernel, sense_buffer[0] & 0x0f); + log_debug("%s: old sense key: 0x%x", dev_scsi->kernel, sense_buffer[0] & 0x0f); else - log_debug("%s: sense = %2x %2x\n", + log_debug("%s: sense = %2x %2x", dev_scsi->kernel, sense_buffer[0], sense_buffer[2]); - log_debug("%s: non-extended sense class %d code 0x%0x\n", + log_debug("%s: non-extended sense class %d code 0x%0x", dev_scsi->kernel, sense_class, code); } @@ -261,8 +261,8 @@ static int scsi_dump_sense(struct udev *udev, out_buffer[j++] = ' '; } out_buffer[j] = '\0'; - log_debug("%s: sense dump:\n", dev_scsi->kernel); - log_debug("%s: %s\n", dev_scsi->kernel, out_buffer); + log_debug("%s: sense dump:", dev_scsi->kernel); + log_debug("%s: %s", dev_scsi->kernel, out_buffer); #endif return -1; @@ -276,11 +276,11 @@ static int scsi_dump(struct udev *udev, /* * Impossible, should not be called. */ - log_debug("%s: called with no error\n", __FUNCTION__); + log_debug("%s: called with no error", __FUNCTION__); return -1; } - log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n", + log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x", dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status); if (io->status == SCSI_CHECK_CONDITION) return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr); @@ -296,11 +296,11 @@ static int scsi_dump_v4(struct udev *udev, /* * Impossible, should not be called. */ - log_debug("%s: called with no error\n", __FUNCTION__); + log_debug("%s: called with no error", __FUNCTION__); return -1; } - log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x\n", + log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x", dev_scsi->kernel, io->driver_status, io->transport_status, io->device_status); if (io->device_status == SCSI_CHECK_CONDITION) @@ -325,7 +325,7 @@ static int scsi_inquiry(struct udev *udev, int retval; if (buflen > SCSI_INQ_BUFF_LEN) { - log_debug("buflen %d too long\n", buflen); + log_debug("buflen %d too long", buflen); return -1; } @@ -362,7 +362,7 @@ resend: dev_scsi->use_sg = 3; goto resend; } - log_debug("%s: ioctl failed: %s\n", dev_scsi->kernel, strerror(errno)); + log_debug("%s: ioctl failed: %m", dev_scsi->kernel); goto error; } @@ -397,7 +397,7 @@ resend: error: if (retval < 0) - log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.\n", + log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.", dev_scsi->kernel, evpd, page); return retval; @@ -416,11 +416,11 @@ static int do_scsi_page0_inquiry(struct udev *udev, return 1; if (buffer[1] != 0) { - log_debug("%s: page 0 not available.\n", dev_scsi->kernel); + log_debug("%s: page 0 not available.", dev_scsi->kernel); return 1; } if (buffer[3] > len) { - log_debug("%s: page 0 buffer too long %d\n", dev_scsi->kernel, buffer[3]); + log_debug("%s: page 0 buffer too long %d", dev_scsi->kernel, buffer[3]); return 1; } @@ -437,7 +437,7 @@ static int do_scsi_page0_inquiry(struct udev *udev, * invalid. */ if (strneq((char *)&buffer[VENDOR_LENGTH], dev_scsi->vendor, VENDOR_LENGTH)) { - log_debug("%s: invalid page0 data\n", dev_scsi->kernel); + log_debug("%s: invalid page0 data", dev_scsi->kernel); return 1; } } @@ -462,7 +462,7 @@ static int prepend_vendor_model(struct udev *udev, * above, ind will never be too large. */ if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) { - log_debug("%s: expected length %d, got length %d\n", + log_debug("%s: expected length %d, got length %d", dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind); return -1; } @@ -528,7 +528,7 @@ static int check_fill_0x83_id(struct udev *udev, len += VENDOR_LENGTH + MODEL_LENGTH; if (max_len < len) { - log_debug("%s: length %d too short - need %d\n", + log_debug("%s: length %d too short - need %d", dev_scsi->kernel, max_len, len); return 1; } @@ -629,7 +629,7 @@ static int do_scsi_page83_inquiry(struct udev *udev, return 1; if (page_83[1] != PAGE_83) { - log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel); + log_debug("%s: Invalid page 0x83", dev_scsi->kernel); return 1; } @@ -715,7 +715,7 @@ static int do_scsi_page83_prespc3_inquiry(struct udev *udev, return 1; if (page_83[1] != PAGE_83) { - log_debug("%s: Invalid page 0x83\n", dev_scsi->kernel); + log_debug("%s: Invalid page 0x83", dev_scsi->kernel); return 1; } /* @@ -779,13 +779,13 @@ static int do_scsi_page80_inquiry(struct udev *udev, return retval; if (buf[1] != PAGE_80) { - log_debug("%s: Invalid page 0x80\n", dev_scsi->kernel); + log_debug("%s: Invalid page 0x80", dev_scsi->kernel); return 1; } len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; if (max_len < len) { - log_debug("%s: length %d too short - need %d\n", + log_debug("%s: length %d too short - need %d", dev_scsi->kernel, max_len, len); return 1; } @@ -820,14 +820,12 @@ int scsi_std_inquiry(struct udev *udev, fd = open(devname, O_RDONLY | O_NONBLOCK); if (fd < 0) { - log_debug("scsi_id: cannot open %s: %s\n", - devname, strerror(errno)); + log_debug("scsi_id: cannot open %s: %m", devname); return 1; } if (fstat(fd, &statbuf) < 0) { - log_debug("scsi_id: cannot stat %s: %s\n", - devname, strerror(errno)); + log_debug("scsi_id: cannot stat %s: %m", devname); err = 2; goto out; } @@ -920,7 +918,7 @@ int scsi_get_serial(struct udev *udev, goto completed; } } else if (page_code != 0x00) { - log_debug("%s: unsupported page code 0x%d\n", dev_scsi->kernel, page_code); + log_debug("%s: unsupported page code 0x%d", dev_scsi->kernel, page_code); retval = 1; goto completed; } diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index f87d629c4b..2fba5223ba 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -1,5 +1,5 @@ /*** - This file is part of systemd. + This file is part of eudev, forked from systemd. Copyright 2012 Kay Sievers <kay@vrfy.org> @@ -95,6 +95,7 @@ #include <linux/pci_regs.h> #include "udev.h" +#include "fileio.h" enum netname_type{ NET_UNDEF, |