diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Kbuild.src | 1 | ||||
-rw-r--r-- | libbb/bb_cat.c | 33 | ||||
-rw-r--r-- | libbb/correct_password.c | 8 | ||||
-rw-r--r-- | libbb/getopt32.c | 10 | ||||
-rw-r--r-- | libbb/isqrt.c | 60 | ||||
-rw-r--r-- | libbb/loop.c | 49 | ||||
-rw-r--r-- | libbb/print_numbered_lines.c | 29 | ||||
-rw-r--r-- | libbb/recursive_action.c | 46 | ||||
-rw-r--r-- | libbb/securetty.c | 26 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 28 |
10 files changed, 219 insertions, 71 deletions
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index fc9371db1..0d7dd2a2c 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -77,6 +77,7 @@ lib-y += safe_gethostname.o | |||
77 | lib-y += safe_poll.o | 77 | lib-y += safe_poll.o |
78 | lib-y += safe_strncpy.o | 78 | lib-y += safe_strncpy.o |
79 | lib-y += safe_write.o | 79 | lib-y += safe_write.o |
80 | lib-y += securetty.o | ||
80 | lib-y += setup_environment.o | 81 | lib-y += setup_environment.o |
81 | lib-y += simplify_path.o | 82 | lib-y += simplify_path.o |
82 | lib-y += single_argv.o | 83 | lib-y += single_argv.o |
diff --git a/libbb/bb_cat.c b/libbb/bb_cat.c new file mode 100644 index 000000000..0a4a350fb --- /dev/null +++ b/libbb/bb_cat.c | |||
@@ -0,0 +1,33 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //kbuild:lib-y += bb_cat.o | ||
8 | |||
9 | #include "libbb.h" | ||
10 | |||
11 | int FAST_FUNC bb_cat(char **argv) | ||
12 | { | ||
13 | int fd; | ||
14 | int retval = EXIT_SUCCESS; | ||
15 | |||
16 | if (!*argv) | ||
17 | argv = (char**) &bb_argv_dash; | ||
18 | |||
19 | do { | ||
20 | fd = open_or_warn_stdin(*argv); | ||
21 | if (fd >= 0) { | ||
22 | /* This is not a xfunc - never exits */ | ||
23 | off_t r = bb_copyfd_eof(fd, STDOUT_FILENO); | ||
24 | if (fd != STDIN_FILENO) | ||
25 | close(fd); | ||
26 | if (r >= 0) | ||
27 | continue; | ||
28 | } | ||
29 | retval = EXIT_FAILURE; | ||
30 | } while (*++argv); | ||
31 | |||
32 | return retval; | ||
33 | } | ||
diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 513c93028..f4635a5bc 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c | |||
@@ -63,7 +63,7 @@ static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZ | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Return 1 if PW has an empty password. | 66 | * Return CHECKPASS_PW_HAS_EMPTY_PASSWORD if PW has an empty password. |
67 | * Return 1 if the user gives the correct password for entry PW, | 67 | * Return 1 if the user gives the correct password for entry PW, |
68 | * 0 if not. | 68 | * 0 if not. |
69 | * NULL pw means "just fake it for login with bad username" | 69 | * NULL pw means "just fake it for login with bad username" |
@@ -77,7 +77,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) | |||
77 | 77 | ||
78 | pw_pass = get_passwd(pw, buffer); | 78 | pw_pass = get_passwd(pw, buffer); |
79 | if (!pw_pass[0]) { /* empty password field? */ | 79 | if (!pw_pass[0]) { /* empty password field? */ |
80 | return 1; | 80 | return CHECKPASS_PW_HAS_EMPTY_PASSWORD; |
81 | } | 81 | } |
82 | 82 | ||
83 | encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1); | 83 | encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1); |
@@ -88,7 +88,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) | |||
88 | 88 | ||
89 | 89 | ||
90 | /* Ask the user for a password. | 90 | /* Ask the user for a password. |
91 | * Return 1 without asking if PW has an empty password. | 91 | * Return CHECKPASS_PW_HAS_EMPTY_PASSWORD without asking if PW has an empty password. |
92 | * Return -1 on EOF, error while reading input, or timeout. | 92 | * Return -1 on EOF, error while reading input, or timeout. |
93 | * Return 1 if the user gives the correct password for entry PW, | 93 | * Return 1 if the user gives the correct password for entry PW, |
94 | * 0 if not. | 94 | * 0 if not. |
@@ -105,7 +105,7 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, | |||
105 | 105 | ||
106 | pw_pass = get_passwd(pw, buffer); | 106 | pw_pass = get_passwd(pw, buffer); |
107 | if (!pw_pass[0]) /* empty password field? */ | 107 | if (!pw_pass[0]) /* empty password field? */ |
108 | return 1; | 108 | return CHECKPASS_PW_HAS_EMPTY_PASSWORD; |
109 | 109 | ||
110 | plaintext = bb_ask(STDIN_FILENO, timeout, prompt); | 110 | plaintext = bb_ask(STDIN_FILENO, timeout, prompt); |
111 | if (!plaintext) { | 111 | if (!plaintext) { |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 03fca3493..b87b83538 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -128,7 +128,7 @@ const char *opt_complementary | |||
128 | "abc" If groups of two or more chars are specified, the first char | 128 | "abc" If groups of two or more chars are specified, the first char |
129 | is the main option and the other chars are secondary options. | 129 | is the main option and the other chars are secondary options. |
130 | Their flags will be turned on if the main option is found even | 130 | Their flags will be turned on if the main option is found even |
131 | if they are not specifed on the command line. For example: | 131 | if they are not specified on the command line. For example: |
132 | 132 | ||
133 | opt_complementary = "abc"; | 133 | opt_complementary = "abc"; |
134 | flags = getopt32(argv, "abcd") | 134 | flags = getopt32(argv, "abcd") |
@@ -576,13 +576,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
576 | * run_nofork_applet() does this, but we might end up here | 576 | * run_nofork_applet() does this, but we might end up here |
577 | * also via gunzip_main() -> gzip_main(). Play safe. | 577 | * also via gunzip_main() -> gzip_main(). Play safe. |
578 | */ | 578 | */ |
579 | #if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32 | 579 | GETOPT_RESET(); |
580 | optind = 0; | ||
581 | #else /* BSD style */ | ||
582 | optind = 1; | ||
583 | /* optreset = 1; */ | ||
584 | #endif | ||
585 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
586 | 580 | ||
587 | /* Note: just "getopt() <= 0" will not work well for | 581 | /* Note: just "getopt() <= 0" will not work well for |
588 | * "fake" short options, like this one: | 582 | * "fake" short options, like this one: |
diff --git a/libbb/isqrt.c b/libbb/isqrt.c new file mode 100644 index 000000000..817b7d036 --- /dev/null +++ b/libbb/isqrt.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | //kbuild:lib-y += isqrt.o | ||
8 | |||
9 | #ifndef ISQRT_TEST | ||
10 | # include "libbb.h" | ||
11 | #else | ||
12 | /* gcc -DISQRT_TEST -Wall -O2 isqrt.c -oisqrt && ./isqrt $((RANDOM*RANDOM)) */ | ||
13 | # include <stdlib.h> | ||
14 | # include <stdio.h> | ||
15 | # include <time.h> | ||
16 | # define FAST_FUNC /* nothing */ | ||
17 | #endif | ||
18 | |||
19 | /* Returns such x that x+1 > sqrt(N) */ | ||
20 | unsigned long FAST_FUNC isqrt(unsigned long long N) | ||
21 | { | ||
22 | unsigned long x; | ||
23 | unsigned shift; | ||
24 | #define LL_WIDTH_BITS (unsigned)(sizeof(N)*8) | ||
25 | |||
26 | shift = LL_WIDTH_BITS - 2; | ||
27 | x = 0; | ||
28 | do { | ||
29 | x = (x << 1) + 1; | ||
30 | if ((unsigned long long)x * x > (N >> shift)) | ||
31 | x--; /* whoops, that +1 was too much */ | ||
32 | shift -= 2; | ||
33 | } while ((int)shift >= 0); | ||
34 | return x; | ||
35 | } | ||
36 | |||
37 | #ifdef ISQRT_TEST | ||
38 | int main(int argc, char **argv) | ||
39 | { | ||
40 | unsigned long long n = argv[1] ? strtoull(argv[1], NULL, 0) : time(NULL); | ||
41 | for (;;) { | ||
42 | unsigned long h; | ||
43 | n--; | ||
44 | h = isqrt(n); | ||
45 | if (!(n & 0xffff)) | ||
46 | printf("isqrt(%llx)=%lx\n", n, h); | ||
47 | if ((unsigned long long)h * h > n) { | ||
48 | printf("BAD1: isqrt(%llx)=%lx\n", n, h); | ||
49 | return 1; | ||
50 | } | ||
51 | h++; | ||
52 | if ((unsigned long long)h * h != 0 /* this can overflow to 0 - not a bug */ | ||
53 | && (unsigned long long)h * h <= n) | ||
54 | { | ||
55 | printf("BAD2: isqrt(%llx)=%lx\n", n, h); | ||
56 | return 1; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | #endif | ||
diff --git a/libbb/loop.c b/libbb/loop.c index d30b378d7..f0d4296ae 100644 --- a/libbb/loop.c +++ b/libbb/loop.c | |||
@@ -78,22 +78,24 @@ int FAST_FUNC del_loop(const char *device) | |||
78 | return rc; | 78 | return rc; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Returns 0 if mounted RW, 1 if mounted read-only, <0 for error. | 81 | /* Returns opened fd to the loop device, <0 on error. |
82 | *device is loop device to use, or if *device==NULL finds a loop device to | 82 | * *device is loop device to use, or if *device==NULL finds a loop device to |
83 | mount it on and sets *device to a strdup of that loop device name. This | 83 | * mount it on and sets *device to a strdup of that loop device name. This |
84 | search will re-use an existing loop device already bound to that | 84 | * search will re-use an existing loop device already bound to that |
85 | file/offset if it finds one. | 85 | * file/offset if it finds one. |
86 | */ | 86 | */ |
87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) | 87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, unsigned flags) |
88 | { | 88 | { |
89 | char dev[LOOP_NAMESIZE]; | 89 | char dev[LOOP_NAMESIZE]; |
90 | char *try; | 90 | char *try; |
91 | bb_loop_info loopinfo; | 91 | bb_loop_info loopinfo; |
92 | struct stat statbuf; | 92 | struct stat statbuf; |
93 | int i, dfd, ffd, mode, rc = -1; | 93 | int i, dfd, ffd, mode, rc; |
94 | |||
95 | rc = dfd = -1; | ||
94 | 96 | ||
95 | /* Open the file. Barf if this doesn't work. */ | 97 | /* Open the file. Barf if this doesn't work. */ |
96 | mode = ro ? O_RDONLY : O_RDWR; | 98 | mode = (flags & BB_LO_FLAGS_READ_ONLY) ? O_RDONLY : O_RDWR; |
97 | open_ffd: | 99 | open_ffd: |
98 | ffd = open(file, mode); | 100 | ffd = open(file, mode); |
99 | if (ffd < 0) { | 101 | if (ffd < 0) { |
@@ -144,20 +146,35 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
144 | 146 | ||
145 | /* If device is free, claim it. */ | 147 | /* If device is free, claim it. */ |
146 | if (rc && errno == ENXIO) { | 148 | if (rc && errno == ENXIO) { |
147 | memset(&loopinfo, 0, sizeof(loopinfo)); | ||
148 | safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); | ||
149 | loopinfo.lo_offset = offset; | ||
150 | /* Associate free loop device with file. */ | 149 | /* Associate free loop device with file. */ |
151 | if (ioctl(dfd, LOOP_SET_FD, ffd) == 0) { | 150 | if (ioctl(dfd, LOOP_SET_FD, ffd) == 0) { |
152 | if (ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo) == 0) | 151 | memset(&loopinfo, 0, sizeof(loopinfo)); |
153 | rc = 0; | 152 | safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); |
154 | else | 153 | loopinfo.lo_offset = offset; |
154 | /* | ||
155 | * Used by mount to set LO_FLAGS_AUTOCLEAR. | ||
156 | * LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file. | ||
157 | * Note that closing LO_FLAGS_AUTOCLEARed dfd before mount | ||
158 | * is wrong (would free the loop device!) | ||
159 | */ | ||
160 | loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY); | ||
161 | rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo); | ||
162 | if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) { | ||
163 | /* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */ | ||
164 | /* (this code path is not tested) */ | ||
165 | loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR; | ||
166 | rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo); | ||
167 | } | ||
168 | if (rc != 0) { | ||
155 | ioctl(dfd, LOOP_CLR_FD, 0); | 169 | ioctl(dfd, LOOP_CLR_FD, 0); |
170 | } | ||
156 | } | 171 | } |
157 | } else { | 172 | } else { |
158 | rc = -1; | 173 | rc = -1; |
159 | } | 174 | } |
160 | close(dfd); | 175 | if (rc != 0) { |
176 | close(dfd); | ||
177 | } | ||
161 | try_again: | 178 | try_again: |
162 | if (*device) break; | 179 | if (*device) break; |
163 | } | 180 | } |
@@ -165,7 +182,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
165 | if (rc == 0) { | 182 | if (rc == 0) { |
166 | if (!*device) | 183 | if (!*device) |
167 | *device = xstrdup(dev); | 184 | *device = xstrdup(dev); |
168 | return (mode == O_RDONLY); /* 1:ro, 0:rw */ | 185 | return dfd; |
169 | } | 186 | } |
170 | return rc; | 187 | return rc; |
171 | } | 188 | } |
diff --git a/libbb/print_numbered_lines.c b/libbb/print_numbered_lines.c new file mode 100644 index 000000000..702aed1ea --- /dev/null +++ b/libbb/print_numbered_lines.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //kbuild:lib-y += print_numbered_lines.o | ||
8 | |||
9 | #include "libbb.h" | ||
10 | |||
11 | void FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename) | ||
12 | { | ||
13 | FILE *fp = fopen_or_warn_stdin(filename); | ||
14 | unsigned N = ns->start; | ||
15 | char *line; | ||
16 | |||
17 | while ((line = xmalloc_fgetline(fp)) != NULL) { | ||
18 | if (ns->all | ||
19 | || (ns->nonempty && line[0]) | ||
20 | ) { | ||
21 | printf("%*u%s%s\n", ns->width, N, ns->sep, line); | ||
22 | N += ns->inc; | ||
23 | } else if (ns->empty_str) | ||
24 | fputs(ns->empty_str, stdout); | ||
25 | free(line); | ||
26 | } | ||
27 | |||
28 | fclose(fp); | ||
29 | } | ||
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index b5cf7c0ab..8f2b8b932 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c | |||
@@ -30,24 +30,37 @@ static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM, | |||
30 | return TRUE; | 30 | return TRUE; |
31 | } | 31 | } |
32 | 32 | ||
33 | /* fileAction return value of 0 on any file in directory will make | 33 | /* fileName is (l)stat'ed (depending on ACTION_FOLLOWLINKS[_L0]). |
34 | * recursive_action() return 0, but it doesn't stop directory traversal | 34 | * |
35 | * If it is a file: fileAction in run on it, its return value is returned. | ||
36 | * | ||
37 | * In case we are in a recursive invocation (see below): | ||
38 | * normally, fileAction should return 1 (TRUE) to indicate that | ||
39 | * everything is okay and processing should continue. | ||
40 | * fileAction return value of 0 (FALSE) on any file in directory will make | ||
41 | * recursive_action() also return 0, but it doesn't stop directory traversal | ||
35 | * (fileAction/dirAction will be called on each file). | 42 | * (fileAction/dirAction will be called on each file). |
36 | * | 43 | * |
37 | * If !ACTION_RECURSE, dirAction is called on the directory and its | 44 | * [TODO: maybe introduce -1 to mean "stop traversal NOW and return"] |
45 | * | ||
46 | * If it is a directory: | ||
47 | * | ||
48 | * If !ACTION_RECURSE, dirAction is called and its | ||
38 | * return value is returned from recursive_action(). No recursion. | 49 | * return value is returned from recursive_action(). No recursion. |
39 | * | 50 | * |
40 | * If ACTION_RECURSE, recursive_action() is called on each directory. | 51 | * If ACTION_RECURSE, directory is opened, and recursive_action() is called |
52 | * on each file/subdirectory. | ||
41 | * If any one of these calls returns 0, current recursive_action() returns 0. | 53 | * If any one of these calls returns 0, current recursive_action() returns 0. |
42 | * | 54 | * |
55 | * If !ACTION_DEPTHFIRST, dirAction is called before recurse. | ||
56 | * Return value of 0 (FALSE) is an error: prevents recursion, | ||
57 | * the warning is printed (unless ACTION_QUIET) and recursive_action() returns 0. | ||
58 | * Return value of 2 (SKIP) prevents recursion, instead recursive_action() | ||
59 | * returns 1 (TRUE, no error). | ||
60 | * | ||
43 | * If ACTION_DEPTHFIRST, dirAction is called after recurse. | 61 | * If ACTION_DEPTHFIRST, dirAction is called after recurse. |
44 | * If it returns 0, the warning is printed and recursive_action() returns 0. | 62 | * If it returns 0, the warning is printed and recursive_action() returns 0. |
45 | * | 63 | * |
46 | * If !ACTION_DEPTHFIRST, dirAction is called before we recurse. | ||
47 | * Return value of 0 (FALSE) or 2 (SKIP) prevents recursion | ||
48 | * into that directory, instead recursive_action() returns 0 (if FALSE) | ||
49 | * or 1 (if SKIP) | ||
50 | * | ||
51 | * ACTION_FOLLOWLINKS mainly controls handling of links to dirs. | 64 | * ACTION_FOLLOWLINKS mainly controls handling of links to dirs. |
52 | * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. | 65 | * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. |
53 | * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. | 66 | * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. |
@@ -105,7 +118,7 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
105 | 118 | ||
106 | if (!(flags & ACTION_DEPTHFIRST)) { | 119 | if (!(flags & ACTION_DEPTHFIRST)) { |
107 | status = dirAction(fileName, &statbuf, userData, depth); | 120 | status = dirAction(fileName, &statbuf, userData, depth); |
108 | if (!status) | 121 | if (status == FALSE) |
109 | goto done_nak_warn; | 122 | goto done_nak_warn; |
110 | if (status == SKIP) | 123 | if (status == SKIP) |
111 | return TRUE; | 124 | return TRUE; |
@@ -121,24 +134,23 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
121 | status = TRUE; | 134 | status = TRUE; |
122 | while ((next = readdir(dir)) != NULL) { | 135 | while ((next = readdir(dir)) != NULL) { |
123 | char *nextFile; | 136 | char *nextFile; |
137 | int s; | ||
124 | 138 | ||
125 | nextFile = concat_subpath_file(fileName, next->d_name); | 139 | nextFile = concat_subpath_file(fileName, next->d_name); |
126 | if (nextFile == NULL) | 140 | if (nextFile == NULL) |
127 | continue; | 141 | continue; |
142 | |||
128 | /* process every file (NB: ACTION_RECURSE is set in flags) */ | 143 | /* process every file (NB: ACTION_RECURSE is set in flags) */ |
129 | if (!recursive_action(nextFile, flags, fileAction, dirAction, | 144 | s = recursive_action(nextFile, flags, fileAction, dirAction, |
130 | userData, depth + 1)) | 145 | userData, depth + 1); |
146 | if (s == FALSE) | ||
131 | status = FALSE; | 147 | status = FALSE; |
132 | // s = recursive_action(nextFile, flags, fileAction, dirAction, | ||
133 | // userData, depth + 1); | ||
134 | free(nextFile); | 148 | free(nextFile); |
135 | //#define RECURSE_RESULT_ABORT 3 | 149 | //#define RECURSE_RESULT_ABORT -1 |
136 | // if (s == RECURSE_RESULT_ABORT) { | 150 | // if (s == RECURSE_RESULT_ABORT) { |
137 | // closedir(dir); | 151 | // closedir(dir); |
138 | // return s; | 152 | // return s; |
139 | // } | 153 | // } |
140 | // if (s == FALSE) | ||
141 | // status = FALSE; | ||
142 | } | 154 | } |
143 | closedir(dir); | 155 | closedir(dir); |
144 | 156 | ||
diff --git a/libbb/securetty.c b/libbb/securetty.c new file mode 100644 index 000000000..21354e2fa --- /dev/null +++ b/libbb/securetty.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * /etc/securetty checking. | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | #include "libbb.h" | ||
8 | |||
9 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | ||
10 | int FAST_FUNC is_tty_secure(const char *short_tty) | ||
11 | { | ||
12 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ | ||
13 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); | ||
14 | while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) { | ||
15 | if (strcmp(buf, short_tty) == 0) | ||
16 | break; | ||
17 | buf = NULL; | ||
18 | } | ||
19 | config_close(parser); | ||
20 | /* buf != NULL here if config file was not found, empty | ||
21 | * or line was found which equals short_tty. | ||
22 | * In all these cases, we report "this tty is secure". | ||
23 | */ | ||
24 | return buf != NULL; | ||
25 | } | ||
26 | #endif | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index a6d260a40..9ab49d0a1 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -123,28 +123,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
123 | 123 | ||
124 | /* In case getopt() or getopt32() was already called: | 124 | /* In case getopt() or getopt32() was already called: |
125 | * reset the libc getopt() function, which keeps internal state. | 125 | * reset the libc getopt() function, which keeps internal state. |
126 | * | ||
127 | * BSD-derived getopt() functions require that optind be set to 1 in | ||
128 | * order to reset getopt() state. This used to be generally accepted | ||
129 | * way of resetting getopt(). However, glibc's getopt() | ||
130 | * has additional getopt() state beyond optind, and requires that | ||
131 | * optind be set to zero to reset its state. So the unfortunate state of | ||
132 | * affairs is that BSD-derived versions of getopt() misbehave if | ||
133 | * optind is set to 0 in order to reset getopt(), and glibc's getopt() | ||
134 | * will core dump if optind is set 1 in order to reset getopt(). | ||
135 | * | ||
136 | * More modern versions of BSD require that optreset be set to 1 in | ||
137 | * order to reset getopt(). Sigh. Standards, anyone? | ||
138 | */ | 126 | */ |
139 | #ifdef __GLIBC__ | 127 | GETOPT_RESET(); |
140 | optind = 0; | ||
141 | #else /* BSD style */ | ||
142 | optind = 1; | ||
143 | /* optreset = 1; */ | ||
144 | #endif | ||
145 | /* optarg = NULL; opterr = 1; optopt = 63; - do we need this too? */ | ||
146 | /* (values above are what they initialized to in glibc and uclibc) */ | ||
147 | /* option_mask32 = 0; - not needed, no applet depends on it being 0 */ | ||
148 | 128 | ||
149 | argc = 1; | 129 | argc = 1; |
150 | while (argv[argc]) | 130 | while (argv[argc]) |
@@ -169,11 +149,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
169 | restore_nofork_data(&old); | 149 | restore_nofork_data(&old); |
170 | 150 | ||
171 | /* Other globals can be simply reset to defaults */ | 151 | /* Other globals can be simply reset to defaults */ |
172 | #ifdef __GLIBC__ | 152 | GETOPT_RESET(); |
173 | optind = 0; | ||
174 | #else /* BSD style */ | ||
175 | optind = 1; | ||
176 | #endif | ||
177 | 153 | ||
178 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ | 154 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ |
179 | } | 155 | } |