#include "libudev-private.h"
#include "macro.h"
-#define BUFSIZE 16
-#define UDEV_ALARM_TIMEOUT 180
+#define BUFSIZE 16
+#define UDEV_ALARM_TIMEOUT 180
enum collect_state {
STATE_NONE,
return container_of(node, struct _mate, node);
}
-_noreturn_ static void sig_alrm(int signo)
+noreturn static void sig_alrm(int signo)
{
exit(4);
}
static void usage(void)
{
- printf("usage: collect [--add|--remove] [--debug] <checkpoint> <id> <idlist>\n"
- "\n"
+ printf("%s [options] <checkpoint> <id> <idlist>\n\n"
+ "Collect variables across events.\n\n"
+ " -h --help Print this message\n"
+ " -a --add Add ID <id> to the list <idlist>\n"
+ " -r --remove Remove ID <id> from the list <idlist>\n"
+ " -d --debug Debug to stderr\n\n"
" Adds ID <id> to the list governed by <checkpoint>.\n"
" <id> must be part of the list <idlist>.\n"
" If all IDs given by <idlist> are listed (ie collect has been\n"
" invoked for each ID in <idlist>) collect returns 0, the\n"
" number of missing IDs otherwise.\n"
- " On error a negative number is returned.\n"
- "\n");
+ " On error a negative number is returned.\n\n"
+ , program_invocation_short_name);
}
/*
*/
static int prepare(char *dir, char *filename)
{
- struct stat statbuf;
char buf[512];
- int fd;
+ int r, fd;
- if (stat(dir, &statbuf) < 0)
- mkdir(dir, 0700);
+ r = mkdir(dir, 0700);
+ if (r < 0 && errno != EEXIST)
+ return -errno;
- sprintf(buf, "%s/%s", dir, filename);
+ snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
- fd = open(buf,O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+ fd = open(buf,O_RDWR|O_CREAT|O_CLOEXEC, 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)
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);
}
}
restart:
len = bufsize >> 1;
- buf = calloc(1,bufsize + 1);
- if (!buf) {
- fprintf(stderr, "Out of memory\n");
- return -1;
- }
+ buf = malloc(bufsize + 1);
+ if (!buf)
+ return log_oom();
memset(buf, ' ', bufsize);
+ buf[bufsize] = '\0';
+
ptr = buf + len;
while ((read(fd, buf + len, len)) > 0) {
while (ptr && *ptr) {
if (!ptr && word < (buf + len)) {
bufsize = bufsize << 1;
if (debug)
- fprintf(stderr, "ID overflow, restarting with size %zi\n", bufsize);
+ fprintf(stderr, "ID overflow, restarting with size %zu\n", bufsize);
free(buf);
lseek(fd, 0, SEEK_SET);
goto restart;
if (debug)
fprintf(stderr, "Found word %s\n", word);
him = malloc(sizeof (struct _mate));
+ if (!him) {
+ free(buf);
+ return log_oom();
+ }
him->name = strdup(word);
+ if (!him->name) {
+ free(buf);
+ free(him);
+ return log_oom();
+ }
him->state = STATE_OLD;
udev_list_node_append(&him->node, &bunch);
word = NULL;
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
- if (!strcmp(him->name, us)) {
+ if (streq(him->name, us)) {
him->state = STATE_CONFIRMED;
who = him;
}
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
- if (!strcmp(him->name, us)) {
+ if (streq(him->name, us)) {
him->state = STATE_NONE;
who = him;
}
* kickout
*
* Remove all IDs in the internal list which are not part
- * of the list passed via the commandline.
+ * of the list passed via the command line.
*/
static void kickout(void)
{
buf = malloc(bufsize);
if (!buf)
- return -1;
+ return log_oom();
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
tmpbuf = realloc(buf, bufsize);
if (!tmpbuf) {
free(buf);
- return -1;
+ return log_oom();
}
buf = tmpbuf;
}
snprintf(buf, strlen(him->name)+2, "%s ", him->name);
- write(fd, buf, strlen(buf));
+ if (write(fd, buf, strlen(buf)) < 0) {
+ free(buf);
+ return -1;
+ }
}
}
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;
}
if (debug)
fprintf(stderr, "Using checkpoint '%s'\n", checkpoint);
- util_strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL);
+ strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL);
fd = prepare(tmpdir, checkpoint);
if (fd < 0) {
ret = 3;
udev_list_node_foreach(him_node, &bunch) {
struct _mate *him = node_to_mate(him_node);
- if (!strcmp(him->name, argv[i]))
+ if (streq(him->name, argv[i]))
who = him;
}
if (!who) {
if (debug)
fprintf(stderr, "ID %s: not in database\n", argv[i]);
- him = malloc(sizeof (struct _mate));
- him->name = malloc(strlen(argv[i]) + 1);
- strcpy(him->name, argv[i]);
+ him = new(struct _mate, 1);
+ if (!him) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ him->name = strdup(argv[i]);
+ if (!him->name) {
+ free(him);
+ ret = ENOMEM;
+ goto out;
+ }
+
him->state = STATE_NONE;
udev_list_node_append(&him->node, &bunch);
} else {