summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/accelerometer/accelerometer.c2
-rw-r--r--src/ata_id/ata_id.c6
-rw-r--r--src/cdrom_id/cdrom_id.c160
-rw-r--r--src/collect/collect.c8
-rw-r--r--src/libudev/Makefile.am2
-rw-r--r--src/libudev/cgroup-util.c6
-rw-r--r--src/libudev/conf-files.c12
-rw-r--r--src/libudev/def.h5
-rw-r--r--src/libudev/hashmap.c172
-rw-r--r--src/libudev/hashmap.h8
-rw-r--r--src/libudev/libudev-queue-private.c13
-rw-r--r--src/libudev/libudev-util.c9
-rw-r--r--src/libudev/log.c55
-rw-r--r--src/libudev/log.h24
-rw-r--r--src/libudev/macro.h46
-rw-r--r--src/libudev/path-util.c43
-rw-r--r--src/libudev/path-util.h2
-rw-r--r--src/libudev/siphash24.c135
-rw-r--r--src/libudev/siphash24.h4
-rw-r--r--src/libudev/socket-util.h14
-rw-r--r--src/libudev/sparse-endian.h1
-rw-r--r--src/libudev/strv.c12
-rw-r--r--src/libudev/strv.h1
-rw-r--r--src/libudev/strxcpyx.c12
-rw-r--r--src/libudev/util.c105
-rw-r--r--src/libudev/util.h11
-rw-r--r--src/scsi_id/scsi_id.c183
-rw-r--r--src/scsi_id/scsi_id.h8
-rw-r--r--src/scsi_id/scsi_serial.c62
-rw-r--r--src/udev/udev-builtin-net_id.c3
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,