diff options
author | Ron Yorston <rmy@pobox.com> | 2015-03-14 20:33:00 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2015-03-14 20:33:00 +0000 |
commit | a4f58436b78fe59e57620c6e0301f213ee25f273 (patch) | |
tree | 8355f724926e605280af2d6f2b1ccc6b1bd02dee /libbb | |
parent | ba0c36cfcf84efbac6f89e27238e04bb57e9cd45 (diff) | |
parent | 49acc1a7618a28d34381cbb7661d7c981fcb238f (diff) | |
download | busybox-w32-a4f58436b78fe59e57620c6e0301f213ee25f273.tar.gz busybox-w32-a4f58436b78fe59e57620c6e0301f213ee25f273.tar.bz2 busybox-w32-a4f58436b78fe59e57620c6e0301f213ee25f273.zip |
Merge branch 'busybox' into merge
Conflicts:
coreutils/od_bloaty.c
libbb/lineedit.c
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/appletlib.c | 8 | ||||
-rw-r--r-- | libbb/bb_pwd.c | 48 | ||||
-rw-r--r-- | libbb/compare_string_array.c | 23 | ||||
-rw-r--r-- | libbb/inet_common.c | 84 | ||||
-rw-r--r-- | libbb/lineedit.c | 35 | ||||
-rw-r--r-- | libbb/loop.c | 11 | ||||
-rw-r--r-- | libbb/match_fstype.c | 7 | ||||
-rw-r--r-- | libbb/procps.c | 12 | ||||
-rw-r--r-- | libbb/rtc.c | 2 | ||||
-rw-r--r-- | libbb/skip_whitespace.c | 2 | ||||
-rw-r--r-- | libbb/update_passwd.c | 45 | ||||
-rw-r--r-- | libbb/utmp.c | 14 | ||||
-rw-r--r-- | libbb/xconnect.c | 2 |
13 files changed, 142 insertions, 151 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index dba66cc93..3f51ecef6 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -197,7 +197,7 @@ void lbb_prepare(const char *applet | |||
197 | if (argv[1] | 197 | if (argv[1] |
198 | && !argv[2] | 198 | && !argv[2] |
199 | && strcmp(argv[1], "--help") == 0 | 199 | && strcmp(argv[1], "--help") == 0 |
200 | && strncmp(applet, "busybox", 7) != 0 | 200 | && !is_prefixed_with(applet, "busybox") |
201 | ) { | 201 | ) { |
202 | /* Special case. POSIX says "test --help" | 202 | /* Special case. POSIX says "test --help" |
203 | * should be no different from e.g. "test --foo". */ | 203 | * should be no different from e.g. "test --foo". */ |
@@ -686,7 +686,7 @@ static int busybox_main(char **argv) | |||
686 | return 0; | 686 | return 0; |
687 | } | 687 | } |
688 | 688 | ||
689 | if (strncmp(argv[1], "--list", 6) == 0) { | 689 | if (is_prefixed_with(argv[1], "--list")) { |
690 | unsigned i = 0; | 690 | unsigned i = 0; |
691 | const char *a = applet_names; | 691 | const char *a = applet_names; |
692 | dup2(1, 2); | 692 | dup2(1, 2); |
@@ -791,7 +791,7 @@ void FAST_FUNC run_applet_and_exit(const char *name, char **argv) | |||
791 | int applet = find_applet_by_name(name); | 791 | int applet = find_applet_by_name(name); |
792 | if (applet >= 0) | 792 | if (applet >= 0) |
793 | run_applet_no_and_exit(applet, argv); | 793 | run_applet_no_and_exit(applet, argv); |
794 | if (strncmp(name, "busybox", 7) == 0) | 794 | if (is_prefixed_with(name, "busybox")) |
795 | exit(busybox_main(argv)); | 795 | exit(busybox_main(argv)); |
796 | } | 796 | } |
797 | 797 | ||
@@ -842,7 +842,7 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
842 | 842 | ||
843 | #if defined(SINGLE_APPLET_MAIN) | 843 | #if defined(SINGLE_APPLET_MAIN) |
844 | /* Only one applet is selected in .config */ | 844 | /* Only one applet is selected in .config */ |
845 | if (argv[1] && strncmp(argv[0], "busybox", 7) == 0) { | 845 | if (argv[1] && is_prefixed_with(argv[0], "busybox")) { |
846 | /* "busybox <applet> <params>" should still work as expected */ | 846 | /* "busybox <applet> <params>" should still work as expected */ |
847 | argv++; | 847 | argv++; |
848 | } | 848 | } |
diff --git a/libbb/bb_pwd.c b/libbb/bb_pwd.c index 8250cd446..4829b723a 100644 --- a/libbb/bb_pwd.c +++ b/libbb/bb_pwd.c | |||
@@ -110,51 +110,3 @@ unsigned long FAST_FUNC get_ug_id(const char *s, | |||
110 | return xname2id(s); | 110 | return xname2id(s); |
111 | return r; | 111 | return r; |
112 | } | 112 | } |
113 | |||
114 | /* Experimental "mallocing" API. | ||
115 | * The goal is nice: "we want to support a case when "guests" group is very large" | ||
116 | * but the code is butt-ugly. | ||
117 | */ | ||
118 | #if 0 | ||
119 | static char *find_latest(char last, char *cp) | ||
120 | { | ||
121 | if (!cp) | ||
122 | return last; | ||
123 | cp += strlen(cp) + 1; | ||
124 | if (last < cp) | ||
125 | last = cp; | ||
126 | return last; | ||
127 | } | ||
128 | |||
129 | struct group* FAST_FUNC xmalloc_getgrnam(const char *name) | ||
130 | { | ||
131 | struct { | ||
132 | struct group gr; | ||
133 | // May still be not enough! | ||
134 | char buf[64*1024 - sizeof(struct group) - 16]; | ||
135 | } *s; | ||
136 | struct group *grp; | ||
137 | int r; | ||
138 | char *last; | ||
139 | char **gr_mem; | ||
140 | |||
141 | s = xmalloc(sizeof(*s)); | ||
142 | r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp); | ||
143 | if (!grp) { | ||
144 | free(s); | ||
145 | return grp; | ||
146 | } | ||
147 | last = find_latest(s->buf, grp->gr_name); | ||
148 | last = find_latest(last, grp->gr_passwd); | ||
149 | gr_mem = grp->gr_mem; | ||
150 | while (*gr_mem) | ||
151 | last = find_latest(last, *gr_mem++); | ||
152 | gr_mem++; /* points past NULL */ | ||
153 | if (last < (char*)gr_mem) | ||
154 | last = (char*)gr_mem; | ||
155 | //FIXME: what if we get not only truncated, but also moved here? | ||
156 | // grp->gr_name pointer and friends are invalid now!!! | ||
157 | s = xrealloc(s, last - (char*)s); | ||
158 | return grp; | ||
159 | } | ||
160 | #endif | ||
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index 4b10cc138..e24815a03 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c | |||
@@ -5,6 +5,24 @@ | |||
5 | 5 | ||
6 | #include "libbb.h" | 6 | #include "libbb.h" |
7 | 7 | ||
8 | char* FAST_FUNC is_prefixed_with(const char *string, const char *key) | ||
9 | { | ||
10 | #if 0 /* Two passes over key - probably slower */ | ||
11 | int len = strlen(key); | ||
12 | if (strncmp(string, key, len) == 0) | ||
13 | return string + len; | ||
14 | return NULL; | ||
15 | #else /* Open-coded */ | ||
16 | while (*key != '\0') { | ||
17 | if (*key != *string) | ||
18 | return NULL; | ||
19 | key++; | ||
20 | string++; | ||
21 | } | ||
22 | return (char*)string; | ||
23 | #endif | ||
24 | } | ||
25 | |||
8 | /* returns the array index of the string */ | 26 | /* returns the array index of the string */ |
9 | /* (index of first match is returned, or -1) */ | 27 | /* (index of first match is returned, or -1) */ |
10 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) | 28 | int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) |
@@ -39,10 +57,9 @@ int FAST_FUNC index_in_strings(const char *strings, const char *key) | |||
39 | int FAST_FUNC index_in_substr_array(const char *const string_array[], const char *key) | 57 | int FAST_FUNC index_in_substr_array(const char *const string_array[], const char *key) |
40 | { | 58 | { |
41 | int i; | 59 | int i; |
42 | int len = strlen(key); | 60 | if (key[0]) { |
43 | if (len) { | ||
44 | for (i = 0; string_array[i] != 0; i++) { | 61 | for (i = 0; string_array[i] != 0; i++) { |
45 | if (strncmp(string_array[i], key, len) == 0) { | 62 | if (is_prefixed_with(string_array[i], key)) { |
46 | return i; | 63 | return i; |
47 | } | 64 | } |
48 | } | 65 | } |
diff --git a/libbb/inet_common.c b/libbb/inet_common.c index b3e0802ee..5b4a4a10b 100644 --- a/libbb/inet_common.c +++ b/libbb/inet_common.c | |||
@@ -32,14 +32,12 @@ int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostf | |||
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | /* If we expect this to be a hostname, try hostname database first */ | 34 | /* If we expect this to be a hostname, try hostname database first */ |
35 | #ifdef DEBUG | ||
36 | if (hostfirst) { | 35 | if (hostfirst) { |
36 | #ifdef DEBUG | ||
37 | bb_error_msg("gethostbyname(%s)", name); | 37 | bb_error_msg("gethostbyname(%s)", name); |
38 | } | ||
39 | #endif | 38 | #endif |
40 | if (hostfirst) { | ||
41 | hp = gethostbyname(name); | 39 | hp = gethostbyname(name); |
42 | if (hp != NULL) { | 40 | if (hp) { |
43 | memcpy(&s_in->sin_addr, hp->h_addr_list[0], | 41 | memcpy(&s_in->sin_addr, hp->h_addr_list[0], |
44 | sizeof(struct in_addr)); | 42 | sizeof(struct in_addr)); |
45 | return 0; | 43 | return 0; |
@@ -51,7 +49,7 @@ int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostf | |||
51 | bb_error_msg("getnetbyname(%s)", name); | 49 | bb_error_msg("getnetbyname(%s)", name); |
52 | #endif | 50 | #endif |
53 | np = getnetbyname(name); | 51 | np = getnetbyname(name); |
54 | if (np != NULL) { | 52 | if (np) { |
55 | s_in->sin_addr.s_addr = htonl(np->n_net); | 53 | s_in->sin_addr.s_addr = htonl(np->n_net); |
56 | return 1; | 54 | return 1; |
57 | } | 55 | } |
@@ -66,7 +64,7 @@ int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostf | |||
66 | bb_error_msg("gethostbyname(%s)", name); | 64 | bb_error_msg("gethostbyname(%s)", name); |
67 | #endif | 65 | #endif |
68 | hp = gethostbyname(name); | 66 | hp = gethostbyname(name); |
69 | if (hp == NULL) { | 67 | if (!hp) { |
70 | return -1; | 68 | return -1; |
71 | } | 69 | } |
72 | memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); | 70 | memcpy(&s_in->sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); |
@@ -74,7 +72,7 @@ int FAST_FUNC INET_resolve(const char *name, struct sockaddr_in *s_in, int hostf | |||
74 | } | 72 | } |
75 | 73 | ||
76 | 74 | ||
77 | /* numeric: & 0x8000: default instead of *, | 75 | /* numeric: & 0x8000: "default" instead of "*", |
78 | * & 0x4000: host instead of net, | 76 | * & 0x4000: host instead of net, |
79 | * & 0x0fff: don't resolve | 77 | * & 0x0fff: don't resolve |
80 | */ | 78 | */ |
@@ -83,16 +81,16 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne | |||
83 | /* addr-to-name cache */ | 81 | /* addr-to-name cache */ |
84 | struct addr { | 82 | struct addr { |
85 | struct addr *next; | 83 | struct addr *next; |
86 | struct sockaddr_in addr; | 84 | uint32_t nip; |
87 | int host; | 85 | smallint is_host; |
88 | char name[1]; | 86 | char name[1]; |
89 | }; | 87 | }; |
90 | static struct addr *cache = NULL; | 88 | static struct addr *cache = NULL; |
91 | 89 | ||
92 | struct addr *pn; | 90 | struct addr *pn; |
93 | char *name; | 91 | char *name; |
94 | uint32_t ad, host_ad; | 92 | uint32_t nip; |
95 | int host = 0; | 93 | smallint is_host; |
96 | 94 | ||
97 | if (s_in->sin_family != AF_INET) { | 95 | if (s_in->sin_family != AF_INET) { |
98 | #ifdef DEBUG | 96 | #ifdef DEBUG |
@@ -102,61 +100,57 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne | |||
102 | errno = EAFNOSUPPORT; | 100 | errno = EAFNOSUPPORT; |
103 | return NULL; | 101 | return NULL; |
104 | } | 102 | } |
105 | ad = s_in->sin_addr.s_addr; | 103 | nip = s_in->sin_addr.s_addr; |
106 | #ifdef DEBUG | 104 | #ifdef DEBUG |
107 | bb_error_msg("rresolve: %08x, mask %08x, num %08x", (unsigned)ad, netmask, numeric); | 105 | bb_error_msg("rresolve: %08x mask:%08x num:%08x", (unsigned)nip, netmask, numeric); |
108 | #endif | 106 | #endif |
109 | if (ad == INADDR_ANY) { | ||
110 | if ((numeric & 0x0FFF) == 0) { | ||
111 | if (numeric & 0x8000) | ||
112 | return xstrdup("default"); | ||
113 | return xstrdup("*"); | ||
114 | } | ||
115 | } | ||
116 | if (numeric & 0x0FFF) | 107 | if (numeric & 0x0FFF) |
117 | return xstrdup(inet_ntoa(s_in->sin_addr)); | 108 | return xmalloc_sockaddr2dotted_noport((void*)s_in); |
109 | if (nip == INADDR_ANY) { | ||
110 | if (numeric & 0x8000) | ||
111 | return xstrdup("default"); | ||
112 | return xstrdup("*"); | ||
113 | } | ||
114 | |||
115 | is_host = ((nip & (~netmask)) != 0 || (numeric & 0x4000)); | ||
118 | 116 | ||
119 | if ((ad & (~netmask)) != 0 || (numeric & 0x4000)) | ||
120 | host = 1; | ||
121 | pn = cache; | 117 | pn = cache; |
122 | while (pn) { | 118 | while (pn) { |
123 | if (pn->addr.sin_addr.s_addr == ad && pn->host == host) { | 119 | if (pn->nip == nip && pn->is_host == is_host) { |
124 | #ifdef DEBUG | 120 | #ifdef DEBUG |
125 | bb_error_msg("rresolve: found %s %08x in cache", | 121 | bb_error_msg("rresolve: found %s %08x in cache", |
126 | (host ? "host" : "net"), (unsigned)ad); | 122 | (is_host ? "host" : "net"), (unsigned)nip); |
127 | #endif | 123 | #endif |
128 | return xstrdup(pn->name); | 124 | return xstrdup(pn->name); |
129 | } | 125 | } |
130 | pn = pn->next; | 126 | pn = pn->next; |
131 | } | 127 | } |
132 | 128 | ||
133 | host_ad = ntohl(ad); | ||
134 | name = NULL; | 129 | name = NULL; |
135 | if (host) { | 130 | if (is_host) { |
136 | struct hostent *ent; | ||
137 | #ifdef DEBUG | 131 | #ifdef DEBUG |
138 | bb_error_msg("gethostbyaddr (%08x)", (unsigned)ad); | 132 | bb_error_msg("sockaddr2host_noport(%08x)", (unsigned)nip); |
139 | #endif | 133 | #endif |
140 | ent = gethostbyaddr((char *) &ad, 4, AF_INET); | 134 | name = xmalloc_sockaddr2host_noport((void*)s_in); |
141 | if (ent) | ||
142 | name = xstrdup(ent->h_name); | ||
143 | } else if (ENABLE_FEATURE_ETC_NETWORKS) { | 135 | } else if (ENABLE_FEATURE_ETC_NETWORKS) { |
144 | struct netent *np; | 136 | struct netent *np; |
145 | #ifdef DEBUG | 137 | #ifdef DEBUG |
146 | bb_error_msg("getnetbyaddr (%08x)", (unsigned)host_ad); | 138 | bb_error_msg("getnetbyaddr(%08x)", (unsigned)ntohl(nip)); |
147 | #endif | 139 | #endif |
148 | np = getnetbyaddr(host_ad, AF_INET); | 140 | np = getnetbyaddr(ntohl(nip), AF_INET); |
149 | if (np) | 141 | if (np) |
150 | name = xstrdup(np->n_name); | 142 | name = xstrdup(np->n_name); |
151 | } | 143 | } |
152 | if (!name) | 144 | if (!name) |
153 | name = xstrdup(inet_ntoa(s_in->sin_addr)); | 145 | name = xmalloc_sockaddr2dotted_noport((void*)s_in); |
146 | |||
154 | pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */ | 147 | pn = xmalloc(sizeof(*pn) + strlen(name)); /* no '+ 1', it's already accounted for */ |
155 | pn->next = cache; | 148 | pn->next = cache; |
156 | pn->addr = *s_in; | 149 | pn->nip = nip; |
157 | pn->host = host; | 150 | pn->is_host = is_host; |
158 | strcpy(pn->name, name); | 151 | strcpy(pn->name, name); |
159 | cache = pn; | 152 | cache = pn; |
153 | |||
160 | return name; | 154 | return name; |
161 | } | 155 | } |
162 | 156 | ||
@@ -188,9 +182,6 @@ int FAST_FUNC INET6_resolve(const char *name, struct sockaddr_in6 *sin6) | |||
188 | 182 | ||
189 | char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) | 183 | char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) |
190 | { | 184 | { |
191 | char name[128]; | ||
192 | int s; | ||
193 | |||
194 | if (sin6->sin6_family != AF_INET6) { | 185 | if (sin6->sin6_family != AF_INET6) { |
195 | #ifdef DEBUG | 186 | #ifdef DEBUG |
196 | bb_error_msg("rresolve: unsupported address family %d!", | 187 | bb_error_msg("rresolve: unsupported address family %d!", |
@@ -200,8 +191,7 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) | |||
200 | return NULL; | 191 | return NULL; |
201 | } | 192 | } |
202 | if (numeric & 0x7FFF) { | 193 | if (numeric & 0x7FFF) { |
203 | inet_ntop(AF_INET6, &sin6->sin6_addr, name, sizeof(name)); | 194 | return xmalloc_sockaddr2dotted_noport((void*)sin6); |
204 | return xstrdup(name); | ||
205 | } | 195 | } |
206 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { | 196 | if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { |
207 | if (numeric & 0x8000) | 197 | if (numeric & 0x8000) |
@@ -209,15 +199,7 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) | |||
209 | return xstrdup("*"); | 199 | return xstrdup("*"); |
210 | } | 200 | } |
211 | 201 | ||
212 | s = getnameinfo((struct sockaddr *) sin6, sizeof(*sin6), | 202 | return xmalloc_sockaddr2host_noport((void*)sin6); |
213 | name, sizeof(name), | ||
214 | /*serv,servlen:*/ NULL, 0, | ||
215 | 0); | ||
216 | if (s != 0) { | ||
217 | bb_error_msg("getnameinfo failed"); | ||
218 | return NULL; | ||
219 | } | ||
220 | return xstrdup(name); | ||
221 | } | 203 | } |
222 | 204 | ||
223 | #endif /* CONFIG_FEATURE_IPV6 */ | 205 | #endif /* CONFIG_FEATURE_IPV6 */ |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 3d96a8e9f..7982f2997 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -714,23 +714,20 @@ static char *username_path_completion(char *ud) | |||
714 | */ | 714 | */ |
715 | static NOINLINE unsigned complete_username(const char *ud) | 715 | static NOINLINE unsigned complete_username(const char *ud) |
716 | { | 716 | { |
717 | /* Using _r function to avoid pulling in static buffers */ | 717 | struct passwd *pw; |
718 | char line_buff[256]; | ||
719 | struct passwd pwd; | ||
720 | struct passwd *result; | ||
721 | unsigned userlen; | 718 | unsigned userlen; |
722 | 719 | ||
723 | ud++; /* skip ~ */ | 720 | ud++; /* skip ~ */ |
724 | userlen = strlen(ud); | 721 | userlen = strlen(ud); |
725 | 722 | ||
726 | setpwent(); | 723 | setpwent(); |
727 | while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) { | 724 | while ((pw = getpwent()) != NULL) { |
728 | /* Null usernames should result in all users as possible completions. */ | 725 | /* Null usernames should result in all users as possible completions. */ |
729 | if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) { | 726 | if (/* !ud[0] || */ is_prefixed_with(pw->pw_name, ud)) { |
730 | add_match(xasprintf("~%s/", pwd.pw_name)); | 727 | add_match(xasprintf("~%s/", pw->pw_name)); |
731 | } | 728 | } |
732 | } | 729 | } |
733 | endpwent(); | 730 | endpwent(); /* don't keep password file open */ |
734 | 731 | ||
735 | return 1 + userlen; | 732 | return 1 + userlen; |
736 | } | 733 | } |
@@ -845,7 +842,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
845 | if (!pfind[0] && DOT_OR_DOTDOT(name_found)) | 842 | if (!pfind[0] && DOT_OR_DOTDOT(name_found)) |
846 | continue; | 843 | continue; |
847 | /* match? */ | 844 | /* match? */ |
848 | if (strncmp(name_found, pfind, pf_len) != 0) | 845 | if (!is_prefixed_with(name_found, pfind)) |
849 | continue; /* no */ | 846 | continue; /* no */ |
850 | 847 | ||
851 | found = concat_path_file(paths[i], name_found); | 848 | found = concat_path_file(paths[i], name_found); |
@@ -1932,19 +1929,25 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
1932 | cwd_buf = xrealloc_getcwd_or_warn(NULL); | 1929 | cwd_buf = xrealloc_getcwd_or_warn(NULL); |
1933 | if (!cwd_buf) | 1930 | if (!cwd_buf) |
1934 | cwd_buf = (char *)bb_msg_unknown; | 1931 | cwd_buf = (char *)bb_msg_unknown; |
1935 | else { | 1932 | else if (home_pwd_buf[0]) { |
1933 | char *after_home_user; | ||
1934 | |||
1936 | /* /home/user[/something] -> ~[/something] */ | 1935 | /* /home/user[/something] -> ~[/something] */ |
1937 | l = strlen(home_pwd_buf); | ||
1938 | if (l != 0 | ||
1939 | #if !ENABLE_PLATFORM_MINGW32 | 1936 | #if !ENABLE_PLATFORM_MINGW32 |
1940 | && strncmp(home_pwd_buf, cwd_buf, l) == 0 | 1937 | after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); |
1941 | #else | 1938 | #else |
1942 | && strncasecmp(home_pwd_buf, cwd_buf, l) == 0 | 1939 | after_home_user = NULL; |
1940 | l = strlen(home_pwd_buf); | ||
1941 | if (l != 0 | ||
1942 | && strncasecmp(home_pwd_buf, cwd_buf, l) == 0) { | ||
1943 | after_home_user = cwd_buf + l; | ||
1944 | } | ||
1943 | #endif | 1945 | #endif |
1944 | && (cwd_buf[l] == '/' || cwd_buf[l] == '\0') | 1946 | if (after_home_user |
1947 | && (*after_home_user == '/' || *after_home_user == '\0') | ||
1945 | ) { | 1948 | ) { |
1946 | cwd_buf[0] = '~'; | 1949 | cwd_buf[0] = '~'; |
1947 | overlapping_strcpy(cwd_buf + 1, cwd_buf + l); | 1950 | overlapping_strcpy(cwd_buf + 1, after_home_user); |
1948 | } | 1951 | } |
1949 | } | 1952 | } |
1950 | } | 1953 | } |
diff --git a/libbb/loop.c b/libbb/loop.c index c96c5e070..d30b378d7 100644 --- a/libbb/loop.c +++ b/libbb/loop.c | |||
@@ -154,16 +154,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
154 | else | 154 | else |
155 | ioctl(dfd, LOOP_CLR_FD, 0); | 155 | ioctl(dfd, LOOP_CLR_FD, 0); |
156 | } | 156 | } |
157 | 157 | } else { | |
158 | /* If this block device already set up right, re-use it. | ||
159 | * (Yes this is racy, but associating two loop devices with the same | ||
160 | * file isn't pretty either. In general, mounting the same file twice | ||
161 | * without using losetup manually is problematic.) | ||
162 | */ | ||
163 | } else | ||
164 | if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 | ||
165 | || offset != loopinfo.lo_offset | ||
166 | ) { | ||
167 | rc = -1; | 158 | rc = -1; |
168 | } | 159 | } |
169 | close(dfd); | 160 | close(dfd); |
diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index 32c3d7f18..b066b4211 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c | |||
@@ -17,7 +17,6 @@ | |||
17 | int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) | 17 | int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) |
18 | { | 18 | { |
19 | int match = 1; | 19 | int match = 1; |
20 | int len; | ||
21 | 20 | ||
22 | if (!t_fstype) | 21 | if (!t_fstype) |
23 | return match; | 22 | return match; |
@@ -27,10 +26,10 @@ int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) | |||
27 | t_fstype += 2; | 26 | t_fstype += 2; |
28 | } | 27 | } |
29 | 28 | ||
30 | len = strlen(mt->mnt_type); | ||
31 | while (1) { | 29 | while (1) { |
32 | if (strncmp(mt->mnt_type, t_fstype, len) == 0 | 30 | char *after_mnt_type = is_prefixed_with(t_fstype, mt->mnt_type); |
33 | && (t_fstype[len] == '\0' || t_fstype[len] == ',') | 31 | if (after_mnt_type |
32 | && (*after_mnt_type == '\0' || *after_mnt_type == ',') | ||
34 | ) { | 33 | ) { |
35 | return match; | 34 | return match; |
36 | } | 35 | } |
diff --git a/libbb/procps.c b/libbb/procps.c index 3c99ac6e7..fff9f8b0b 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -206,11 +206,11 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
206 | // Rss: nnn kB | 206 | // Rss: nnn kB |
207 | // ..... | 207 | // ..... |
208 | 208 | ||
209 | char *tp = buf, *p; | 209 | char *tp, *p; |
210 | 210 | ||
211 | #define SCAN(S, X) \ | 211 | #define SCAN(S, X) \ |
212 | if (strncmp(tp, S, sizeof(S)-1) == 0) { \ | 212 | if ((tp = is_prefixed_with(buf, S)) != NULL) { \ |
213 | tp = skip_whitespace(tp + sizeof(S)-1); \ | 213 | tp = skip_whitespace(tp); \ |
214 | total->X += currec.X = fast_strtoul_10(&tp); \ | 214 | total->X += currec.X = fast_strtoul_10(&tp); \ |
215 | continue; \ | 215 | continue; \ |
216 | } | 216 | } |
@@ -248,7 +248,7 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, | |||
248 | // skipping "rw-s FILEOFS M:m INODE " | 248 | // skipping "rw-s FILEOFS M:m INODE " |
249 | tp = skip_whitespace(skip_fields(tp, 4)); | 249 | tp = skip_whitespace(skip_fields(tp, 4)); |
250 | // filter out /dev/something (something != zero) | 250 | // filter out /dev/something (something != zero) |
251 | if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { | 251 | if (!is_prefixed_with(tp, "/dev/") || strcmp(tp, "/dev/zero\n") == 0) { |
252 | if (currec.smap_mode[1] == 'w') { | 252 | if (currec.smap_mode[1] == 'w') { |
253 | currec.mapped_rw = currec.smap_size; | 253 | currec.mapped_rw = currec.smap_size; |
254 | total->mapped_rw += currec.smap_size; | 254 | total->mapped_rw += currec.smap_size; |
@@ -498,8 +498,8 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
498 | while (fgets(buf, sizeof(buf), file)) { | 498 | while (fgets(buf, sizeof(buf), file)) { |
499 | char *tp; | 499 | char *tp; |
500 | #define SCAN_TWO(str, name, statement) \ | 500 | #define SCAN_TWO(str, name, statement) \ |
501 | if (strncmp(buf, str, sizeof(str)-1) == 0) { \ | 501 | if ((tp = is_prefixed_with(buf, str)) != NULL) { \ |
502 | tp = skip_whitespace(buf + sizeof(str)-1); \ | 502 | tp = skip_whitespace(tp); \ |
503 | sscanf(tp, "%u", &sp->name); \ | 503 | sscanf(tp, "%u", &sp->name); \ |
504 | statement; \ | 504 | statement; \ |
505 | } | 505 | } |
diff --git a/libbb/rtc.c b/libbb/rtc.c index 6d06d57f9..c4117ba34 100644 --- a/libbb/rtc.c +++ b/libbb/rtc.c | |||
@@ -22,7 +22,7 @@ int FAST_FUNC rtc_adjtime_is_utc(void) | |||
22 | char buffer[128]; | 22 | char buffer[128]; |
23 | 23 | ||
24 | while (fgets(buffer, sizeof(buffer), f)) { | 24 | while (fgets(buffer, sizeof(buffer), f)) { |
25 | if (strncmp(buffer, "UTC", 3) == 0) { | 25 | if (is_prefixed_with(buffer, "UTC")) { |
26 | utc = 1; | 26 | utc = 1; |
27 | break; | 27 | break; |
28 | } | 28 | } |
diff --git a/libbb/skip_whitespace.c b/libbb/skip_whitespace.c index 8c7b674c3..b6cfbba4d 100644 --- a/libbb/skip_whitespace.c +++ b/libbb/skip_whitespace.c | |||
@@ -33,7 +33,7 @@ char* FAST_FUNC skip_non_whitespace(const char *s) | |||
33 | 33 | ||
34 | char* FAST_FUNC skip_dev_pfx(const char *tty_name) | 34 | char* FAST_FUNC skip_dev_pfx(const char *tty_name) |
35 | { | 35 | { |
36 | if (strncmp(tty_name, "/dev/", 5) == 0) | 36 | if (is_prefixed_with(tty_name, "/dev/")) |
37 | tty_name += 5; | 37 | tty_name += 5; |
38 | return (char*)tty_name; | 38 | return (char*)tty_name; |
39 | } | 39 | } |
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c index a30af6f72..a2004f480 100644 --- a/libbb/update_passwd.c +++ b/libbb/update_passwd.c | |||
@@ -62,6 +62,8 @@ static void check_selinux_update_passwd(const char *username) | |||
62 | only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd | 62 | only if CONFIG_PASSWD=y and applet_name[0] == 'p' like in passwd |
63 | or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd | 63 | or if CONFIG_CHPASSWD=y and applet_name[0] == 'c' like in chpasswd |
64 | 64 | ||
65 | 8) delete a user from all groups: update_passwd(FILE, NULL, NULL, MEMBER) | ||
66 | |||
65 | This function does not validate the arguments fed to it | 67 | This function does not validate the arguments fed to it |
66 | so the calling program should take care of that. | 68 | so the calling program should take care of that. |
67 | 69 | ||
@@ -82,7 +84,6 @@ int FAST_FUNC update_passwd(const char *filename, | |||
82 | char *fnamesfx; | 84 | char *fnamesfx; |
83 | char *sfx_char; | 85 | char *sfx_char; |
84 | char *name_colon; | 86 | char *name_colon; |
85 | unsigned user_len; | ||
86 | int old_fd; | 87 | int old_fd; |
87 | int new_fd; | 88 | int new_fd; |
88 | int i; | 89 | int i; |
@@ -99,13 +100,13 @@ int FAST_FUNC update_passwd(const char *filename, | |||
99 | if (filename == NULL) | 100 | if (filename == NULL) |
100 | return ret; | 101 | return ret; |
101 | 102 | ||
102 | check_selinux_update_passwd(name); | 103 | if (name) |
104 | check_selinux_update_passwd(name); | ||
103 | 105 | ||
104 | /* New passwd file, "/etc/passwd+" for now */ | 106 | /* New passwd file, "/etc/passwd+" for now */ |
105 | fnamesfx = xasprintf("%s+", filename); | 107 | fnamesfx = xasprintf("%s+", filename); |
106 | sfx_char = &fnamesfx[strlen(fnamesfx)-1]; | 108 | sfx_char = &fnamesfx[strlen(fnamesfx)-1]; |
107 | name_colon = xasprintf("%s:", name); | 109 | name_colon = xasprintf("%s:", name ? name : ""); |
108 | user_len = strlen(name_colon); | ||
109 | 110 | ||
110 | if (shadow) | 111 | if (shadow) |
111 | old_fp = fopen(filename, "r+"); | 112 | old_fp = fopen(filename, "r+"); |
@@ -167,13 +168,45 @@ int FAST_FUNC update_passwd(const char *filename, | |||
167 | line = xmalloc_fgetline(old_fp); | 168 | line = xmalloc_fgetline(old_fp); |
168 | if (!line) /* EOF/error */ | 169 | if (!line) /* EOF/error */ |
169 | break; | 170 | break; |
170 | if (strncmp(name_colon, line, user_len) != 0) { | 171 | |
172 | if (!name && member) { | ||
173 | /* Delete member from all groups */ | ||
174 | /* line is "GROUP:PASSWD:[member1[,member2]...]" */ | ||
175 | unsigned member_len = strlen(member); | ||
176 | char *list = strrchr(line, ':'); | ||
177 | while (list) { | ||
178 | list++; | ||
179 | next_list_element: | ||
180 | if (is_prefixed_with(list, member)) { | ||
181 | char c; | ||
182 | changed_lines++; | ||
183 | c = list[member_len]; | ||
184 | if (c == '\0') { | ||
185 | if (list[-1] == ',') | ||
186 | list--; | ||
187 | *list = '\0'; | ||
188 | break; | ||
189 | } | ||
190 | if (c == ',') { | ||
191 | overlapping_strcpy(list, list + member_len + 1); | ||
192 | goto next_list_element; | ||
193 | } | ||
194 | changed_lines--; | ||
195 | } | ||
196 | list = strchr(list, ','); | ||
197 | } | ||
198 | fprintf(new_fp, "%s\n", line); | ||
199 | goto next; | ||
200 | } | ||
201 | |||
202 | cp = is_prefixed_with(line, name_colon); | ||
203 | if (!cp) { | ||
171 | fprintf(new_fp, "%s\n", line); | 204 | fprintf(new_fp, "%s\n", line); |
172 | goto next; | 205 | goto next; |
173 | } | 206 | } |
174 | 207 | ||
175 | /* We have a match with "name:"... */ | 208 | /* We have a match with "name:"... */ |
176 | cp = line + user_len; /* move past name: */ | 209 | /* cp points past "name:" */ |
177 | 210 | ||
178 | #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP | 211 | #if ENABLE_FEATURE_ADDUSER_TO_GROUP || ENABLE_FEATURE_DEL_USER_FROM_GROUP |
179 | if (member) { | 212 | if (member) { |
diff --git a/libbb/utmp.c b/libbb/utmp.c index 09443fb6c..8ad9ba27e 100644 --- a/libbb/utmp.c +++ b/libbb/utmp.c | |||
@@ -130,3 +130,17 @@ void FAST_FUNC update_utmp(pid_t pid, int new_type, const char *tty_name, const | |||
130 | updwtmp(bb_path_wtmp_file, &utent); | 130 | updwtmp(bb_path_wtmp_file, &utent); |
131 | #endif | 131 | #endif |
132 | } | 132 | } |
133 | |||
134 | /* man utmp: | ||
135 | * When init(8) finds that a process has exited, it locates its utmp entry | ||
136 | * by ut_pid, sets ut_type to DEAD_PROCESS, and clears ut_user, ut_host | ||
137 | * and ut_time with null bytes. | ||
138 | * [same applies to other processes which maintain utmp entries, like telnetd] | ||
139 | * | ||
140 | * We do not bother actually clearing fields: | ||
141 | * it might be interesting to know who was logged in and from where | ||
142 | */ | ||
143 | void FAST_FUNC update_utmp_DEAD_PROCESS(pid_t pid) | ||
144 | { | ||
145 | update_utmp(pid, DEAD_PROCESS, NULL, NULL, NULL); | ||
146 | } | ||
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 1c8bb2b73..2a96e03dc 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -171,7 +171,7 @@ IF_NOT_FEATURE_IPV6(sa_family_t af = AF_INET;) | |||
171 | const char *cp; | 171 | const char *cp; |
172 | struct addrinfo hint; | 172 | struct addrinfo hint; |
173 | 173 | ||
174 | if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) { | 174 | if (ENABLE_FEATURE_UNIX_LOCAL && is_prefixed_with(host, "local:")) { |
175 | struct sockaddr_un *sun; | 175 | struct sockaddr_un *sun; |
176 | 176 | ||
177 | r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_un)); | 177 | r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_un)); |