summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/udevadm.xml1
-rw-r--r--src/udev/ata_id/ata_id.c345
-rw-r--r--src/udev/cdrom_id/cdrom_id.c20
-rw-r--r--src/udev/dmi_memory_id/dmi_memory_id.c11
-rw-r--r--src/udev/fido_id/fido_id.c52
-rw-r--r--src/udev/meson.build1
-rw-r--r--src/udev/mtd_probe/mtd_probe.c65
-rw-r--r--src/udev/v4l_id/v4l_id.c49
8 files changed, 310 insertions, 234 deletions
diff --git a/man/udevadm.xml b/man/udevadm.xml
index ce40ded8f3..734e38cd05 100644
--- a/man/udevadm.xml
+++ b/man/udevadm.xml
@@ -739,6 +739,7 @@
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
+ <xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
</refsect2>
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index 6a631e515c..0b1f0b7157 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -23,14 +23,20 @@
#include <sys/types.h>
#include <unistd.h>
+#include "build.h"
#include "device-nodes.h"
#include "fd-util.h"
#include "log.h"
+#include "main-func.h"
#include "memory-util.h"
#include "udev-util.h"
+#include "unaligned.h"
#define COMMAND_TIMEOUT_MSEC (30 * 1000)
+static bool arg_export = false;
+static const char *arg_device = NULL;
+
static int disk_scsi_inquiry_command(
int fd,
void *buf,
@@ -55,45 +61,39 @@ static int disk_scsi_inquiry_command(
.din_xferp = (uintptr_t) buf,
.timeout = COMMAND_TIMEOUT_MSEC,
};
- int ret;
- ret = ioctl(fd, SG_IO, &io_v4);
- if (ret != 0) {
+ if (ioctl(fd, SG_IO, &io_v4) != 0) {
+ if (errno != EINVAL)
+ return log_debug_errno(errno, "ioctl v4 failed: %m");
+
/* could be that the driver doesn't do version 4, try version 3 */
- if (errno == EINVAL) {
- struct sg_io_hdr io_hdr = {
- .interface_id = 'S',
- .cmdp = (unsigned char*) cdb,
- .cmd_len = sizeof (cdb),
- .dxferp = buf,
- .dxfer_len = buf_len,
- .sbp = sense,
- .mx_sb_len = sizeof(sense),
- .dxfer_direction = SG_DXFER_FROM_DEV,
- .timeout = COMMAND_TIMEOUT_MSEC,
- };
-
- ret = ioctl(fd, SG_IO, &io_hdr);
- if (ret != 0)
- return ret;
-
- /* even if the ioctl succeeds, we need to check the return value */
- if (!(io_hdr.status == 0 &&
- io_hdr.host_status == 0 &&
- io_hdr.driver_status == 0)) {
- errno = EIO;
- return -1;
- }
- } else
- return ret;
- }
+ struct sg_io_hdr io_hdr = {
+ .interface_id = 'S',
+ .cmdp = (unsigned char*) cdb,
+ .cmd_len = sizeof (cdb),
+ .dxferp = buf,
+ .dxfer_len = buf_len,
+ .sbp = sense,
+ .mx_sb_len = sizeof(sense),
+ .dxfer_direction = SG_DXFER_FROM_DEV,
+ .timeout = COMMAND_TIMEOUT_MSEC,
+ };
+
+ if (ioctl(fd, SG_IO, &io_hdr) != 0)
+ return log_debug_errno(errno, "ioctl v3 failed: %m");
+
+ /* even if the ioctl succeeds, we need to check the return value */
+ if (io_hdr.status != 0 ||
+ io_hdr.host_status != 0 ||
+ io_hdr.driver_status != 0)
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "ioctl v3 failed");
- /* even if the ioctl succeeds, we need to check the return value */
- if (!(io_v4.device_status == 0 &&
- io_v4.transport_status == 0 &&
- io_v4.driver_status == 0)) {
- errno = EIO;
- return -1;
+ } else {
+ /* even if the ioctl succeeds, we need to check the return value */
+ if (io_v4.device_status != 0 ||
+ io_v4.transport_status != 0 ||
+ io_v4.driver_status != 0)
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "ioctl v4 failed");
}
return 0;
@@ -137,35 +137,30 @@ static int disk_identify_command(
.din_xferp = (uintptr_t) buf,
.timeout = COMMAND_TIMEOUT_MSEC,
};
- int ret;
- ret = ioctl(fd, SG_IO, &io_v4);
- if (ret != 0) {
- /* could be that the driver doesn't do version 4, try version 3 */
- if (errno == EINVAL) {
- struct sg_io_hdr io_hdr = {
- .interface_id = 'S',
- .cmdp = (unsigned char*) cdb,
- .cmd_len = sizeof (cdb),
- .dxferp = buf,
- .dxfer_len = buf_len,
- .sbp = sense,
- .mx_sb_len = sizeof (sense),
- .dxfer_direction = SG_DXFER_FROM_DEV,
- .timeout = COMMAND_TIMEOUT_MSEC,
- };
-
- ret = ioctl(fd, SG_IO, &io_hdr);
- if (ret != 0)
- return ret;
- } else
- return ret;
- }
+ if (ioctl(fd, SG_IO, &io_v4) != 0) {
+ if (errno != EINVAL)
+ return log_debug_errno(errno, "ioctl v4 failed: %m");
- if (!((sense[0] & 0x7f) == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c) &&
- !((sense[0] & 0x7f) == 0x70 && sense[12] == 0x00 && sense[13] == 0x1d)) {
- errno = EIO;
- return -1;
+ /* could be that the driver doesn't do version 4, try version 3 */
+ struct sg_io_hdr io_hdr = {
+ .interface_id = 'S',
+ .cmdp = (unsigned char*) cdb,
+ .cmd_len = sizeof (cdb),
+ .dxferp = buf,
+ .dxfer_len = buf_len,
+ .sbp = sense,
+ .mx_sb_len = sizeof (sense),
+ .dxfer_direction = SG_DXFER_FROM_DEV,
+ .timeout = COMMAND_TIMEOUT_MSEC,
+ };
+
+ if (ioctl(fd, SG_IO, &io_hdr) != 0)
+ return log_debug_errno(errno, "ioctl v3 failed: %m");
+ } else {
+ if (!((sense[0] & 0x7f) == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c) &&
+ !((sense[0] & 0x7f) == 0x70 && sense[12] == 0x00 && sense[13] == 0x1d))
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "ioctl v4 failed: %m");
}
return 0;
@@ -215,34 +210,29 @@ static int disk_identify_packet_device_command(
.din_xferp = (uintptr_t) buf,
.timeout = COMMAND_TIMEOUT_MSEC,
};
- int ret;
- ret = ioctl(fd, SG_IO, &io_v4);
- if (ret != 0) {
- /* could be that the driver doesn't do version 4, try version 3 */
- if (errno == EINVAL) {
- struct sg_io_hdr io_hdr = {
- .interface_id = 'S',
- .cmdp = (unsigned char*) cdb,
- .cmd_len = sizeof (cdb),
- .dxferp = buf,
- .dxfer_len = buf_len,
- .sbp = sense,
- .mx_sb_len = sizeof (sense),
- .dxfer_direction = SG_DXFER_FROM_DEV,
- .timeout = COMMAND_TIMEOUT_MSEC,
- };
-
- ret = ioctl(fd, SG_IO, &io_hdr);
- if (ret != 0)
- return ret;
- } else
- return ret;
- }
+ if (ioctl(fd, SG_IO, &io_v4) != 0) {
+ if (errno != EINVAL)
+ return log_debug_errno(errno, "ioctl v4 failed: %m");
- if (!((sense[0] & 0x7f) == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
- errno = EIO;
- return -1;
+ /* could be that the driver doesn't do version 4, try version 3 */
+ struct sg_io_hdr io_hdr = {
+ .interface_id = 'S',
+ .cmdp = (unsigned char*) cdb,
+ .cmd_len = sizeof (cdb),
+ .dxferp = buf,
+ .dxfer_len = buf_len,
+ .sbp = sense,
+ .mx_sb_len = sizeof (sense),
+ .dxfer_direction = SG_DXFER_FROM_DEV,
+ .timeout = COMMAND_TIMEOUT_MSEC,
+ };
+
+ if (ioctl(fd, SG_IO, &io_hdr) != 0)
+ return log_debug_errno(errno, "ioctl v3 failed: %m");
+ } else {
+ if ((sense[0] & 0x7f) != 0x72 || desc[0] != 0x9 || desc[1] != 0x0c)
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "ioctl v4 failed: %m");
}
return 0;
@@ -282,26 +272,25 @@ static void disk_identify_fixup_string(
uint8_t identify[512],
unsigned offset_words,
size_t len) {
+ assert(offset_words < 512/2);
disk_identify_get_string(identify, offset_words,
(char *) identify + offset_words * 2, len);
}
-static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned offset_words) {
- uint16_t *p;
-
- p = (uint16_t *) identify;
- p[offset_words] = le16toh (p[offset_words]);
+static void disk_identify_fixup_uint16(uint8_t identify[512], unsigned offset_words) {
+ assert(offset_words < 512/2);
+ unaligned_write_ne16(identify + offset_words * 2,
+ unaligned_read_le16(identify + offset_words * 2));
}
/**
* disk_identify:
* @fd: File descriptor for the block device.
* @out_identify: Return location for IDENTIFY data.
- * @out_is_packet_device: Return location for whether returned data is from an IDENTIFY PACKET DEVICE.
*
* Sends the IDENTIFY DEVICE or IDENTIFY PACKET DEVICE command to the
* device represented by @fd. If successful, then the result will be
- * copied into @out_identify and @out_is_packet_device.
+ * copied into @out_identify.
*
* This routine is based on code from libatasmart, LGPL v2.1.
*
@@ -309,14 +298,9 @@ static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned offset_w
* non-zero with errno set.
*/
static int disk_identify(int fd,
- uint8_t out_identify[512],
- int *out_is_packet_device) {
- int ret;
+ uint8_t out_identify[512]) {
uint8_t inquiry_buf[36];
- int peripheral_device_type;
- int all_nul_bytes;
- int n;
- int is_packet_device = 0;
+ int peripheral_device_type, r;
/* init results */
memzero(out_identify, 512);
@@ -342,110 +326,103 @@ static int disk_identify(int fd,
* the original bug-fix and see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=556635
* for the original bug-report.)
*/
- ret = disk_scsi_inquiry_command (fd, inquiry_buf, sizeof (inquiry_buf));
- if (ret != 0)
- goto out;
+ r = disk_scsi_inquiry_command(fd, inquiry_buf, sizeof inquiry_buf);
+ if (r < 0)
+ return r;
/* SPC-4, section 6.4.2: Standard INQUIRY data */
peripheral_device_type = inquiry_buf[0] & 0x1f;
- if (peripheral_device_type == 0x05)
- {
- is_packet_device = 1;
- ret = disk_identify_packet_device_command(fd, out_identify, 512);
- goto check_nul_bytes;
- }
- if (!IN_SET(peripheral_device_type, 0x00, 0x14)) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (peripheral_device_type == 0x05) {
+ r = disk_identify_packet_device_command(fd, out_identify, 512);
+ if (r < 0)
+ return r;
- /* OK, now issue the IDENTIFY DEVICE command */
- ret = disk_identify_command(fd, out_identify, 512);
- if (ret != 0)
- goto out;
+ } else {
+ if (!IN_SET(peripheral_device_type, 0x00, 0x14))
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Unsupported device type.");
+
+ /* OK, now issue the IDENTIFY DEVICE command */
+ r = disk_identify_command(fd, out_identify, 512);
+ if (r < 0)
+ return r;
+ }
- check_nul_bytes:
/* Check if IDENTIFY data is all NUL bytes - if so, bail */
- all_nul_bytes = 1;
- for (n = 0; n < 512; n++) {
+ bool all_nul_bytes = true;
+ for (size_t n = 0; n < 512; n++)
if (out_identify[n] != '\0') {
- all_nul_bytes = 0;
+ all_nul_bytes = false;
break;
}
- }
- if (all_nul_bytes) {
- ret = -1;
- errno = EIO;
- goto out;
- }
+ if (all_nul_bytes)
+ return log_debug_errno(SYNTHETIC_ERRNO(EIO), "IDENTIFY data is all zeroes.");
+
+ return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+ static const struct option options[] = {
+ { "export", no_argument, NULL, 'x' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ {}
+ };
+ int c;
+
+ while ((c = getopt_long(argc, argv, "xh", options, NULL)) >= 0)
+ switch (c) {
+ case 'x':
+ arg_export = true;
+ break;
+ case 'h':
+ printf("%s [OPTIONS...] DEVICE\n\n"
+ " -x --export Print values as environment keys\n"
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
+ program_invocation_short_name);
+ return 0;
+ case 'v':
+ return version();
+ case '?':
+ return -EINVAL;
+ default:
+ assert_not_reached();
+ }
-out:
- if (out_is_packet_device)
- *out_is_packet_device = is_packet_device;
- return ret;
+ if (!argv[optind])
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "DEVICE argument missing.");
+
+ arg_device = argv[optind];
+ return 1;
}
-int main(int argc, char *argv[]) {
+static int run(int argc, char *argv[]) {
struct hd_driveid id;
union {
uint8_t byte[512];
uint16_t wyde[256];
} identify;
- char model[41];
- char model_enc[256];
- char serial[21];
- char revision[9];
- const char *node = NULL;
- int export = 0;
+ char model[41], model_enc[256], serial[21], revision[9];
_cleanup_close_ int fd = -EBADF;
uint16_t word;
- int is_packet_device = 0;
- static const struct option options[] = {
- { "export", no_argument, NULL, 'x' },
- { "help", no_argument, NULL, 'h' },
- {}
- };
+ int r;
log_set_target(LOG_TARGET_AUTO);
udev_parse_config();
log_parse_environment();
log_open();
- for (;;) {
- int option;
-
- option = getopt_long(argc, argv, "xh", options, NULL);
- if (option == -1)
- break;
-
- switch (option) {
- case 'x':
- export = 1;
- break;
- case 'h':
- printf("Usage: %s [--export] [--help] <device>\n"
- " -x,--export print values as environment keys\n"
- " -h,--help print this help text\n\n",
- program_invocation_short_name);
- return 0;
- }
- }
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ return r;
- node = argv[optind];
- if (!node) {
- log_error("no node specified");
- return 1;
- }
+ fd = open(ASSERT_PTR(arg_device), O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
+ if (fd < 0)
+ return log_error_errno(errno, "Cannot open %s: %m", arg_device);
- fd = open(node, O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY);
- if (fd < 0) {
- log_error("unable to open '%s'", node);
- return 1;
- }
-
- if (disk_identify(fd, identify.byte, &is_packet_device) == 0) {
+ if (disk_identify(fd, identify.byte) >= 0) {
/*
* fix up only the fields from the IDENTIFY data that we are going to
* use and copy it into the hd_driveid struct for convenience
@@ -475,10 +452,8 @@ int main(int argc, char *argv[]) {
memcpy(&id, identify.byte, sizeof id);
} else {
/* If this fails, then try HDIO_GET_IDENTITY */
- if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0) {
- log_debug_errno(errno, "HDIO_GET_IDENTITY failed for '%s': %m", node);
- return 2;
- }
+ if (ioctl(fd, HDIO_GET_IDENTITY, &id) != 0)
+ return log_debug_errno(errno, "%s: HDIO_GET_IDENTITY failed: %m", arg_device);
}
memcpy(model, id.model, 40);
@@ -491,7 +466,7 @@ int main(int argc, char *argv[]) {
udev_replace_whitespace((char *) id.fw_rev, revision, 8);
udev_replace_chars(revision, NULL);
- if (export) {
+ if (arg_export) {
/* Set this to convey the disk speaks the ATA protocol */
printf("ID_ATA=1\n");
@@ -649,3 +624,5 @@ int main(int argc, char *argv[]) {
return 0;
}
+
+DEFINE_MAIN_FUNCTION(run);
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index ea420a9617..5b5fbd0109 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -10,6 +10,7 @@
#include <sys/ioctl.h>
#include <unistd.h>
+#include "build.h"
#include "fd-util.h"
#include "main-func.h"
#include "memory-util.h"
@@ -897,13 +898,13 @@ static void print_properties(const Context *c) {
}
static int help(void) {
- printf("Usage: %s [options] <device>\n"
- " -l --lock-media lock the media (to enable eject request events)\n"
- " -u --unlock-media unlock the media\n"
- " -e --eject-media eject the media\n"
- " -d --debug print debug messages to stderr\n"
- " -h --help print this help text\n"
- "\n",
+ printf("%s [OPTIONS...] DEVICE\n\n"
+ " -l --lock-media Lock the media (to enable eject request events)\n"
+ " -u --unlock-media Unlock the media\n"
+ " -e --eject-media Eject the media\n"
+ " -d --debug Print debug messages to stderr\n"
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
program_invocation_short_name);
return 0;
@@ -916,6 +917,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "eject-media", no_argument, NULL, 'e' },
{ "debug", no_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
{}
};
int c;
@@ -938,6 +940,10 @@ static int parse_argv(int argc, char *argv[]) {
break;
case 'h':
return help();
+ case 'v':
+ return version();
+ case '?':
+ return -EINVAL;
default:
assert_not_reached();
}
diff --git a/src/udev/dmi_memory_id/dmi_memory_id.c b/src/udev/dmi_memory_id/dmi_memory_id.c
index 1345289219..dd46113137 100644
--- a/src/udev/dmi_memory_id/dmi_memory_id.c
+++ b/src/udev/dmi_memory_id/dmi_memory_id.c
@@ -45,6 +45,7 @@
#include <getopt.h>
#include "alloc-util.h"
+#include "build.h"
#include "fileio.h"
#include "main-func.h"
#include "string-util.h"
@@ -638,9 +639,10 @@ static int legacy_decode(const uint8_t *buf, const char *devmem, bool no_file_of
}
static int help(void) {
- printf("Usage: %s [options]\n"
- " -F,--from-dump FILE read DMI information from a binary file\n"
- " -h,--help print this help text\n\n",
+ printf("%s [OPTIONS...]\n\n"
+ " -F --from-dump FILE Read DMI information from a binary file\n"
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
program_invocation_short_name);
return 0;
}
@@ -650,6 +652,7 @@ static int parse_argv(int argc, char * const *argv) {
{ "from-dump", required_argument, NULL, 'F' },
{ "version", no_argument, NULL, 'V' },
{ "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
{}
};
int c;
@@ -666,6 +669,8 @@ static int parse_argv(int argc, char * const *argv) {
return help();
case '?':
return -EINVAL;
+ case 'v':
+ return version();
default:
assert_not_reached();
}
diff --git a/src/udev/fido_id/fido_id.c b/src/udev/fido_id/fido_id.c
index f2fbc38003..e01f37d04c 100644
--- a/src/udev/fido_id/fido_id.c
+++ b/src/udev/fido_id/fido_id.c
@@ -8,12 +8,14 @@
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <linux/hid.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
+#include "build.h"
#include "device-private.h"
#include "device-util.h"
#include "fd-util.h"
@@ -25,16 +27,47 @@
#include "string-util.h"
#include "udev-util.h"
+static const char *arg_device = NULL;
+
+static int parse_argv(int argc, char *argv[]) {
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ {}
+ };
+ int c;
+
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ switch (c) {
+ case 'h':
+ printf("%s [OPTIONS...] SYSFS_PATH\n\n"
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
+ program_invocation_short_name);
+ return 0;
+ case 'v':
+ return version();
+ case '?':
+ return -EINVAL;
+ default:
+ assert_not_reached();
+ }
+
+ if (argc > 2)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error: unexpected argument.");
+
+ arg_device = argv[optind];
+ return 1;
+}
+
static int run(int argc, char **argv) {
_cleanup_(sd_device_unrefp) struct sd_device *device = NULL;
_cleanup_free_ char *desc_path = NULL;
_cleanup_close_ int fd = -EBADF;
-
struct sd_device *hid_device;
const char *sys_path;
uint8_t desc[HID_MAX_DESCRIPTOR_SIZE];
ssize_t desc_len;
-
int r;
log_set_target(LOG_TARGET_AUTO);
@@ -42,17 +75,18 @@ static int run(int argc, char **argv) {
log_parse_environment();
log_open();
- if (argc > 2)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Usage: %s [SYSFS_PATH]", program_invocation_short_name);
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ return r;
- if (argc == 1) {
- r = device_new_from_strv(&device, environ);
+ if (arg_device) {
+ r = sd_device_new_from_syspath(&device, arg_device);
if (r < 0)
- return log_error_errno(r, "Failed to get current device from environment: %m");
+ return log_error_errno(r, "Failed to get device from syspath %s: %m", arg_device);
} else {
- r = sd_device_new_from_syspath(&device, argv[1]);
+ r = device_new_from_strv(&device, environ);
if (r < 0)
- return log_error_errno(r, "Failed to get device from syspath: %m");
+ return log_error_errno(r, "Failed to get current device from environment: %m");
}
r = sd_device_get_parent(device, &hid_device);
diff --git a/src/udev/meson.build b/src/udev/meson.build
index af7dea0dce..5b44dd8d7d 100644
--- a/src/udev/meson.build
+++ b/src/udev/meson.build
@@ -143,6 +143,7 @@ foreach prog : udev_progs
install_dir : udevlibexecdir)
udev_prog_paths += {name : exe}
+ public_programs += exe
endforeach
if install_sysconfdir_samples
diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c
index a7210a05e3..1035320490 100644
--- a/src/udev/mtd_probe/mtd_probe.c
+++ b/src/udev/mtd_probe/mtd_probe.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <mtd/mtd-user.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,31 +30,61 @@
#include <unistd.h>
#include "alloc-util.h"
+#include "build.h"
#include "fd-util.h"
+#include "main-func.h"
#include "mtd_probe.h"
-int main(int argc, char** argv) {
+static const char *arg_device = NULL;
+
+static int parse_argv(int argc, char *argv[]) {
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
+ {}
+ };
+ int c;
+
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+ switch (c) {
+ case 'h':
+ printf("%s /dev/mtd[n]\n\n"
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
+ program_invocation_short_name);
+ return 0;
+ case 'v':
+ return version();
+ case '?':
+ return -EINVAL;
+ default:
+ assert_not_reached();
+ }
+
+ if (argc > 2)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error: unexpected argument.");
+
+ arg_device = argv[optind];
+ return 1;
+}
+
+static int run(int argc, char** argv) {
_cleanup_close_ int mtd_fd = -EBADF;
mtd_info_t mtd_info;
+ int r;
- if (argc != 2) {
- printf("usage: mtd_probe /dev/mtd[n]\n");
- return EXIT_FAILURE;
- }
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ return r;
mtd_fd = open(argv[1], O_RDONLY|O_CLOEXEC|O_NOCTTY);
- if (mtd_fd < 0) {
- log_error_errno(errno, "Failed to open: %m");
- return EXIT_FAILURE;
- }
+ if (mtd_fd < 0)
+ return log_error_errno(errno, "Failed to open: %m");
- if (ioctl(mtd_fd, MEMGETINFO, &mtd_info) < 0) {
- log_error_errno(errno, "Failed to issue MEMGETINFO ioctl: %m");
- return EXIT_FAILURE;
- }
+ if (ioctl(mtd_fd, MEMGETINFO, &mtd_info) < 0)
+ return log_error_errno(errno, "MEMGETINFO ioctl failed: %m");
- if (probe_smart_media(mtd_fd, &mtd_info) < 0)
- return EXIT_FAILURE;
-
- return EXIT_SUCCESS;
+ return probe_smart_media(mtd_fd, &mtd_info);
}
+
+DEFINE_MAIN_FUNCTION(run);
diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c
index 4f163c4350..30527e9556 100644
--- a/src/udev/v4l_id/v4l_id.c
+++ b/src/udev/v4l_id/v4l_id.c
@@ -26,51 +26,70 @@
#include <unistd.h>
#include <linux/videodev2.h>
+#include "build.h"
#include "fd-util.h"
+#include "main-func.h"
-int main(int argc, char *argv[]) {
+static const char *arg_device = NULL;
+
+static int parse_argv(int argc, char *argv[]) {
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, 'v' },
{}
};
- _cleanup_close_ int fd = -EBADF;
- char *device;
- struct v4l2_capability v2cap;
int c;
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
-
switch (c) {
case 'h':
- printf("%s [-h,--help] <device file>\n\n"
+ printf("%s [OPTIONS...] DEVICE\n\n"
"Video4Linux device identification.\n\n"
- " -h Print this message\n",
+ " -h --help Show this help text\n"
+ " --version Show package version\n",
program_invocation_short_name);
return 0;
+ case 'v':
+ return version();
case '?':
return -EINVAL;
-
default:
assert_not_reached();
}
- device = argv[optind];
- if (!device)
- return 2;
+ if (!argv[optind])
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "DEVICE argument missing.");
+
+ arg_device = argv[optind];
+ return 1;
+}
- fd = open(device, O_RDONLY);
+static int run(int argc, char *argv[]) {
+ _cleanup_close_ int fd = -EBADF;
+ struct v4l2_capability v2cap;
+ int r;
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ return r;
+
+ fd = open(arg_device, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
- return 3;
+ return log_error_errno(errno, "Failed to open %s: %m", arg_device);
if (ioctl(fd, VIDIOC_QUERYCAP, &v2cap) == 0) {
int capabilities;
+
printf("ID_V4L_VERSION=2\n");
printf("ID_V4L_PRODUCT=%s\n", v2cap.card);
printf("ID_V4L_CAPABILITIES=:");
+
if (v2cap.capabilities & V4L2_CAP_DEVICE_CAPS)
capabilities = v2cap.device_caps;
else
capabilities = v2cap.capabilities;
+
if ((capabilities & V4L2_CAP_VIDEO_CAPTURE) > 0 ||
(capabilities & V4L2_CAP_VIDEO_CAPTURE_MPLANE) > 0)
printf("capture:");
@@ -90,3 +109,5 @@ int main(int argc, char *argv[]) {
return 0;
}
+
+DEFINE_MAIN_FUNCTION(run);