aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-09-07 23:22:08 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-09-07 23:22:08 +0000
commit8d89bed8401bfbca9c5ef18f201439b3502e733b (patch)
treeb5db7bd373d32b4891610cd2c58f6307d4808447
parentee9deb863e089e1b607cc5771123257c3223bea0 (diff)
downloadbusybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.tar.gz
busybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.tar.bz2
busybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.zip
watchdog: add -T option
function old new delta watchdog_main 159 219 +60 mdev: support match by major,minor. See bug 4714. +100 bytes.
-rw-r--r--debianutils/start_stop_daemon.c2
-rw-r--r--docs/mdev.txt6
-rw-r--r--include/usage.h7
-rw-r--r--libpwdgrp/uidgid_get.c5
-rw-r--r--miscutils/watchdog.c59
-rwxr-xr-xtestsuite/mdev.tests13
-rw-r--r--util-linux/mdev.c55
7 files changed, 81 insertions, 66 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 875eca511..99864d0a4 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -428,7 +428,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
428 write_pidfile(pidfile); 428 write_pidfile(pidfile);
429 } 429 }
430 if (opt & OPT_c) { 430 if (opt & OPT_c) {
431 struct bb_uidgid_t ugid; 431 struct bb_uidgid_t ugid = { -1, -1 };
432 parse_chown_usergroup_or_die(&ugid, chuid); 432 parse_chown_usergroup_or_die(&ugid, chuid);
433 if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); 433 if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid);
434 if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); 434 if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid);
diff --git a/docs/mdev.txt b/docs/mdev.txt
index 63ad40602..a8a816ce9 100644
--- a/docs/mdev.txt
+++ b/docs/mdev.txt
@@ -51,9 +51,11 @@ device nodes if your system needs something more than the default root/root
51660 permissions. 51660 permissions.
52 52
53The file has the format: 53The file has the format:
54 <device regex> <uid>:<gid> <octal permissions> 54 <device regex> <uid>:<gid> <octal permissions>
55 or @<maj[,min1[-min2]]> <uid>:<gid> <octal permissions>
56
55For example: 57For example:
56 hd[a-z][0-9]* 0:3 660 58 hd[a-z][0-9]* 0:3 660
57 59
58The config file parsing stops at the first matching line. If no line is 60The config file parsing stops at the first matching line. If no line is
59matched, then the default of 0:0 660 is used. To set your own default, simply 61matched, then the default of 0:0 660 is used. To set your own default, simply
diff --git a/include/usage.h b/include/usage.h
index c0b81efd1..fdad63a4f 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -4561,14 +4561,15 @@
4561 "Mon Dec 17 10:31:44 GMT 2000" 4561 "Mon Dec 17 10:31:44 GMT 2000"
4562 4562
4563#define watchdog_trivial_usage \ 4563#define watchdog_trivial_usage \
4564 "[-t N[ms]] [-F] DEV" 4564 "[-t N[ms]] [-T N[ms]] [-F] DEV"
4565#define watchdog_full_usage "\n\n" \ 4565#define watchdog_full_usage "\n\n" \
4566 "Periodically write to watchdog device DEV\n" \ 4566 "Periodically write to watchdog device DEV\n" \
4567 "\nOptions:" \ 4567 "\nOptions:" \
4568 "\n -t N Timer period (default 30)" \ 4568 "\n -T N Reboot after N seconds if not reset (default 60)" \
4569 "\n -t N Reset every N seconds (default 30)" \
4569 "\n -F Run in foreground" \ 4570 "\n -F Run in foreground" \
4570 "\n" \ 4571 "\n" \
4571 "\nUse -t 500ms to specify period in milliseconds" \ 4572 "\nUse 500ms to specify period in milliseconds" \
4572 4573
4573#define wc_trivial_usage \ 4574#define wc_trivial_usage \
4574 "[OPTION]... [FILE]..." 4575 "[OPTION]... [FILE]..."
diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c
index ebc7fc58c..92290bfdb 100644
--- a/libpwdgrp/uidgid_get.c
+++ b/libpwdgrp/uidgid_get.c
@@ -87,15 +87,12 @@ void FAST_FUNC xget_uidgid(struct bb_uidgid_t *u, const char *ug)
87 * ":group" sets gid only 87 * ":group" sets gid only
88 * "user:" sets uid and gid (to user's primary group id) 88 * "user:" sets uid and gid (to user's primary group id)
89 * "user:group" sets uid and gid 89 * "user:group" sets uid and gid
90 * ('unset' uid or gid is actually set to -1) 90 * ('unset' uid or gid retains the value it has on entry)
91 */ 91 */
92void FAST_FUNC parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) 92void FAST_FUNC parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group)
93{ 93{
94 char *group; 94 char *group;
95 95
96 u->uid = -1;
97 u->gid = -1;
98
99 /* Check if there is a group name */ 96 /* Check if there is a group name */
100 group = strchr(user_group, '.'); /* deprecated? */ 97 group = strchr(user_group, '.'); /* deprecated? */
101 if (!group) 98 if (!group)
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index 9b1a110ea..e102a598a 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -4,14 +4,17 @@
4 * 4 *
5 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> 5 * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org>
6 * Copyright (C) 2006 Bernhard Fischer <busybox@busybox.net> 6 * Copyright (C) 2006 Bernhard Fischer <busybox@busybox.net>
7 * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com>
7 * 8 *
8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 9 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9 */ 10 */
10 11
11#include "libbb.h" 12#include "libbb.h"
13#include "linux/watchdog.h"
12 14
13#define OPT_FOREGROUND 0x01 15#define OPT_FOREGROUND (1 << 0)
14#define OPT_TIMER 0x02 16#define OPT_STIMER (1 << 1)
17#define OPT_HTIMER (1 << 2)
15 18
16static void watchdog_shutdown(int sig UNUSED_PARAM) 19static void watchdog_shutdown(int sig UNUSED_PARAM)
17{ 20{
@@ -26,38 +29,42 @@ static void watchdog_shutdown(int sig UNUSED_PARAM)
26int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 29int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
27int watchdog_main(int argc, char **argv) 30int watchdog_main(int argc, char **argv)
28{ 31{
29 unsigned opts; 32 static const struct suffix_mult suffixes[] = {
30 unsigned timer_duration = 30000; /* Userspace timer duration, in milliseconds */ 33 { "ms", 1 },
31 char *t_arg; 34 { "", 1000 },
35 { }
36 };
32 37
33 opt_complementary = "=1"; /* must have 1 argument */ 38 unsigned opts;
34 opts = getopt32(argv, "Ft:", &t_arg); 39 unsigned stimer_duration; /* how often to restart */
40 unsigned htimer_duration = 60000; /* reboots after N ms if not restarted */
41 char *st_arg;
42 char *ht_arg;
35 43
36 if (opts & OPT_TIMER) { 44 opt_complementary = "=1"; /* must have exactly 1 argument */
37 static const struct suffix_mult suffixes[] = { 45 opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg);
38 { "ms", 1 },
39 { "", 1000 },
40 { }
41 };
42 timer_duration = xatou_sfx(t_arg, suffixes);
43 }
44 46
45 if (!(opts & OPT_FOREGROUND)) { 47 if (opts & OPT_HTIMER)
46 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 48 htimer_duration = xatou_sfx(ht_arg, suffixes);
47 } 49 stimer_duration = htimer_duration / 2;
50 if (opts & OPT_STIMER)
51 stimer_duration = xatou_sfx(st_arg, suffixes);
48 52
49 bb_signals(BB_FATAL_SIGS, watchdog_shutdown); 53 bb_signals(BB_FATAL_SIGS, watchdog_shutdown);
50 54
51 /* Use known fd # - avoid needing global 'int fd' */ 55 /* Use known fd # - avoid needing global 'int fd' */
52 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); 56 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
53 57
54// TODO? 58 ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration);
55// if (!(opts & OPT_TIMER)) { 59#if 0
56// if (ioctl(fd, WDIOC_GETTIMEOUT, &timer_duration) == 0) 60 ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration);
57// timer_duration *= 500; 61 printf("watchdog: SW timer is %dms, HW timer is %dms\n",
58// else 62 stimer_duration, htimer_duration * 1000);
59// timer_duration = 30000; 63#endif
60// } 64
65 if (!(opts & OPT_FOREGROUND)) {
66 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
67 }
61 68
62 while (1) { 69 while (1) {
63 /* 70 /*
@@ -65,7 +72,7 @@ int watchdog_main(int argc, char **argv)
65 * is undefined at this point -- PFM 72 * is undefined at this point -- PFM
66 */ 73 */
67 write(3, "", 1); /* write zero byte */ 74 write(3, "", 1); /* write zero byte */
68 usleep(timer_duration * 1000L); 75 usleep(stimer_duration * 1000L);
69 } 76 }
70 return EXIT_SUCCESS; /* - not reached, but gcc 4.2.1 is too dumb! */ 77 return EXIT_SUCCESS; /* - not reached, but gcc 4.2.1 is too dumb! */
71} 78}
diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests
index dad5bddb8..22855791a 100755
--- a/testsuite/mdev.tests
+++ b/testsuite/mdev.tests
@@ -98,7 +98,6 @@ brw-r--r-- 1 0 0 a_sda
98 98
99# continuing to use directory structure from prev test 99# continuing to use directory structure from prev test
100rm -rf mdev.testdir/dev/* 100rm -rf mdev.testdir/dev/*
101# here we complicate things by having non-matching group 1 and using %0
102echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf 101echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf
103testing "mdev command" \ 102testing "mdev command" \
104 "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; 103 "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1;
@@ -110,6 +109,18 @@ brw-r--r-- 1 0 0 8,0 sda
110" \ 109" \
111 "" "" 110 "" ""
112 111
112# continuing to use directory structure from prev test
113rm -rf mdev.testdir/dev/*
114echo "@8,0 :1 644" >mdev.testdir/etc/mdev.conf
115testing "mdev #maj,min and no explicit uid" \
116 "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1;
117 ls -lnR mdev.testdir/dev | $FILTER_LS" \
118"\
119mdev.testdir/dev:
120brw-r--r-- 1 0 1 8,0 sda
121" \
122 "" ""
123
113# clean up 124# clean up
114rm -rf mdev.testdir 125rm -rf mdev.testdir
115 126
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index d0d010382..5ac801555 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -59,8 +59,7 @@ static void make_device(char *path, int delete)
59 int major, minor, type, len; 59 int major, minor, type, len;
60 int mode = 0660; 60 int mode = 0660;
61#if ENABLE_FEATURE_MDEV_CONF 61#if ENABLE_FEATURE_MDEV_CONF
62 uid_t uid = 0; 62 struct bb_uidgid_t ugid = { 0, 0 };
63 gid_t gid = 0;
64 parser_t *parser; 63 parser_t *parser;
65 char *tokens[5]; 64 char *tokens[5];
66#endif 65#endif
@@ -78,9 +77,10 @@ static void make_device(char *path, int delete)
78 77
79 /* Try to read major/minor string. Note that the kernel puts \n after 78 /* Try to read major/minor string. Note that the kernel puts \n after
80 * the data, so we don't need to worry about null terminating the string 79 * the data, so we don't need to worry about null terminating the string
81 * because sscanf() will stop at the first nondigit, which \n is. We 80 * because sscanf() will stop at the first nondigit, which \n is.
82 * also depend on path having writeable space after it. 81 * We also depend on path having writeable space after it.
83 */ 82 */
83 major = -1;
84 if (!delete) { 84 if (!delete) {
85 strcpy(dev_maj_min, "/dev"); 85 strcpy(dev_maj_min, "/dev");
86 len = open_read_close(path, dev_maj_min + 1, 64); 86 len = open_read_close(path, dev_maj_min + 1, 64);
@@ -90,6 +90,8 @@ static void make_device(char *path, int delete)
90 return; 90 return;
91 /* no "dev" file, so just try to run script */ 91 /* no "dev" file, so just try to run script */
92 *dev_maj_min = '\0'; 92 *dev_maj_min = '\0';
93 } else if (sscanf(dev_maj_min, "%u:%u", &major, &minor) != 2) {
94 major = -1;
93 } 95 }
94 } 96 }
95 97
@@ -113,8 +115,23 @@ static void make_device(char *path, int delete)
113 115
114 /* Fields: regex uid:gid mode [alias] [cmd] */ 116 /* Fields: regex uid:gid mode [alias] [cmd] */
115 117
116 /* 1st field: regex to match this device */ 118 /* 1st field: @<numeric maj,min>... */
117 { 119 if (tokens[0][0] == '@') {
120 /* @major,minor[-last] */
121 /* (useful when name is ambiguous:
122 * "/sys/class/usb/lp0" and
123 * "/sys/class/printer/lp0") */
124 int cmaj, cmin0, cmin1, sc;
125 if (major < 0)
126 continue; /* no dev, no match */
127 sc = sscanf(tokens[0], "@%u,%u-%u", &cmaj, &cmin0, &cmin1);
128 if (sc < 1 || major != cmaj
129 || (sc == 2 && minor != cmin0)
130 || (sc == 3 && (minor < cmin0 || minor > cmin1))
131 ) {
132 continue; /* no match */
133 }
134 } else { /* ... or regex to match device name */
118 regex_t match; 135 regex_t match;
119 int result; 136 int result;
120 137
@@ -144,27 +161,7 @@ static void make_device(char *path, int delete)
144 * after parsing the rest of fields */ 161 * after parsing the rest of fields */
145 162
146 /* 2nd field: uid:gid - device ownership */ 163 /* 2nd field: uid:gid - device ownership */
147 { 164 parse_chown_usergroup_or_die(&ugid, tokens[1]);
148 struct passwd *pass;
149 struct group *grp;
150 char *str_uid = tokens[1];
151 char *str_gid = strchrnul(str_uid, ':');
152
153 if (*str_gid)
154 *str_gid++ = '\0';
155 /* Parse UID */
156 pass = getpwnam(str_uid);
157 if (pass)
158 uid = pass->pw_uid;
159 else
160 uid = strtoul(str_uid, NULL, 10);
161 /* Parse GID */
162 grp = getgrnam(str_gid);
163 if (grp)
164 gid = grp->gr_gid;
165 else
166 gid = strtoul(str_gid, NULL, 10);
167 }
168 165
169 /* 3rd field: mode - device permissions */ 166 /* 3rd field: mode - device permissions */
170 mode = strtoul(tokens[2], NULL, 8); 167 mode = strtoul(tokens[2], NULL, 8);
@@ -243,7 +240,7 @@ static void make_device(char *path, int delete)
243 config_close(parser); 240 config_close(parser);
244#endif /* ENABLE_FEATURE_MDEV_CONF */ 241#endif /* ENABLE_FEATURE_MDEV_CONF */
245 242
246 if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) { 243 if (!delete && major >= 0) {
247 244
248 if (ENABLE_FEATURE_MDEV_RENAME) 245 if (ENABLE_FEATURE_MDEV_RENAME)
249 unlink(device_name); 246 unlink(device_name);
@@ -255,7 +252,7 @@ static void make_device(char *path, int delete)
255 symlink(device_name, "root"); 252 symlink(device_name, "root");
256 253
257#if ENABLE_FEATURE_MDEV_CONF 254#if ENABLE_FEATURE_MDEV_CONF
258 chown(device_name, uid, gid); 255 chown(device_name, ugid.uid, ugid.gid);
259 256
260#if ENABLE_FEATURE_MDEV_RENAME 257#if ENABLE_FEATURE_MDEV_RENAME
261 if (alias) { 258 if (alias) {