diff options
author | Kay Sievers <kay.sievers@suse.de> | 2005-06-15 03:07:14 +0200 |
---|---|---|
committer | Kay Sievers <kay.sievers@suse.de> | 2005-06-15 03:07:14 +0200 |
commit | 3632a3685883d3270145c59d5764de6246547943 (patch) | |
tree | 6b2a5d22d47f354f708df8f7fc733a4d20499942 /udeveventrecorder.c | |
parent | e5b7f7b83428cb50f165b49408c2f7559dcfefef (diff) |
udeveventrecorder: add small program that writes an event to disk
Used for debugging and event replay from initramfs.
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
Diffstat (limited to 'udeveventrecorder.c')
-rw-r--r-- | udeveventrecorder.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/udeveventrecorder.c b/udeveventrecorder.c new file mode 100644 index 0000000000..af7ea7c15c --- /dev/null +++ b/udeveventrecorder.c @@ -0,0 +1,127 @@ +/* + * udeveventrecorder.c + * + * Userspace devfs + * + * Copyright (C) 2004, 2005 Olaf Hering <olh@suse.de> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "udev.h" +#include "udev_version.h" +#include "udev_utils.h" +#include "logging.h" + +#define BUFSIZE 12345 +#define FNSIZE 123 + +static int log = 0; + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + + if (priority > log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +int main(int argc, char **argv, char **envp) +{ + int fd, i; + unsigned long seq; + char **ep = envp; + char *buf, *p, *a; + struct stat sb; + const char *env; + + if (stat("/events", &sb) || !(S_ISDIR(sb.st_mode))) + return 1; + + env = getenv("UDEV_LOG"); + if (env) + log = log_priority(env); + + logging_init("udeveventrecorder"); + dbg("version %s", UDEV_VERSION); + + p = getenv("SEQNUM"); + a = getenv("ACTION"); + buf = malloc(FNSIZE); + if (!(buf && a && argv[1])) + goto error; + if (p) + seq = strtoul(p, NULL, 0); + else + seq = 0; + + snprintf(buf, FNSIZE, "/events/debug.%05lu.%s.%s.%u", seq, argv[1], a ? a : "", getpid()); + if ((fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0) { + err("error creating '%s'", buf); + goto error; + } + free(buf); + p = malloc(BUFSIZE); + buf = p; + buf += snprintf(buf, p + BUFSIZE - buf, "set --"); + for (i = 1; i < argc; ++i) { + buf += snprintf(buf, p + BUFSIZE - buf, " %s", argv[i]); + if (buf > p + BUFSIZE) + goto full; + } + buf += snprintf(buf, p + BUFSIZE - buf, "\n"); + if (buf > p + BUFSIZE) + goto full; + while (*ep) { + unsigned char *t; + t = memchr(*ep, '=', strlen(*ep)); + if (t) { + *t = '\0'; + t++; + buf += snprintf(buf, p + BUFSIZE - buf, "%s='%s'\n", *ep, t); + --t; + *t = '='; + } + ep++; + if (buf > p + BUFSIZE) + break; + } + +full: + buf = p; + write(fd, buf, strlen(buf)); + close(fd); + free(buf); + return 0; + +error: + fprintf(stderr, "record enviroment to /events, to be called from udev context\n"); + return 1; +} |