aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-07-28 07:40:39 +0000
committerEric Andersen <andersen@codepoet.org>2003-07-28 07:40:39 +0000
commit35e643b39f6cc77b702c714cfa8e70f1e10601a9 (patch)
treead6b608081a4dde117563a1f1e9a6e3892a8752c
parent4f4631732cab5886105d8809d4e9b17711def65b (diff)
downloadbusybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.tar.gz
busybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.tar.bz2
busybox-w32-35e643b39f6cc77b702c714cfa8e70f1e10601a9.zip
last_patch95 from vodz:
Hi. Last patch have new libbb function vfork_rexec() for can use daemon() to uClinux system. This patched daemons: syslog, klogd, inetd, crond. This not tested! I havn`t this systems. Also. Previous patch for feature request MD5 crypt password for httpd don`t sended to this mailist on 07/15/03 (mailist have Pytom module problem?). The previous patch included, and have testing. --w vodz
-rw-r--r--include/libbb.h2
-rw-r--r--libbb/Makefile.in2
-rw-r--r--libbb/vfork_daemon_rexec.c27
-rw-r--r--miscutils/Config.in7
-rw-r--r--miscutils/crond.c411
-rw-r--r--networking/Config.in9
-rw-r--r--networking/Makefile.in7
-rw-r--r--networking/httpd.c64
-rw-r--r--networking/inetd.c24
-rw-r--r--sysklogd/klogd.c4
-rw-r--r--sysklogd/syslogd.c5
11 files changed, 316 insertions, 246 deletions
diff --git a/include/libbb.h b/include/libbb.h
index a4d8c7196..6b75b8a89 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -453,4 +453,6 @@ extern llist_t *llist_add_to(llist_t *old_head, char *new_item);
453void print_login_issue(const char *issue_file, const char *tty); 453void print_login_issue(const char *issue_file, const char *tty);
454void print_login_prompt(void); 454void print_login_prompt(void);
455 455
456void vfork_daemon_rexec(int argc, char **argv, char *foreground_opt);
457
456#endif /* __LIBCONFIG_H__ */ 458#endif /* __LIBCONFIG_H__ */
diff --git a/libbb/Makefile.in b/libbb/Makefile.in
index c4886e3ff..b60adc959 100644
--- a/libbb/Makefile.in
+++ b/libbb/Makefile.in
@@ -48,7 +48,7 @@ LIBBB_SRC:= \
48 fclose_nonstdin.c fflush_stdout_and_exit.c getopt_ulflags.c \ 48 fclose_nonstdin.c fflush_stdout_and_exit.c getopt_ulflags.c \
49 default_error_retval.c wfopen_input.c speed_table.c \ 49 default_error_retval.c wfopen_input.c speed_table.c \
50 perror_nomsg_and_die.c perror_nomsg.c skip_whitespace.c \ 50 perror_nomsg_and_die.c perror_nomsg.c skip_whitespace.c \
51 warn_ignoring_args.c concat_subpath_file.c 51 warn_ignoring_args.c concat_subpath_file.c vfork_daemon_rexec.c
52 52
53LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC)) 53LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
54 54
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
new file mode 100644
index 000000000..c8f9d277e
--- /dev/null
+++ b/libbb/vfork_daemon_rexec.c
@@ -0,0 +1,27 @@
1/*
2 * Rexec program for system have fork() as vfork() with foregound option
3 * Copyright (C) Vladminr Oleynik and many different people.
4 */
5
6#include <unistd.h>
7#include "libbb.h"
8
9
10#if defined(__uClinux__)
11void vfork_daemon_rexec(int argc, char **argv, char *foreground_opt)
12{
13 char **vfork_args;
14 int a = 0;
15
16 vfork_args = xcalloc(sizeof(char *), argc + 3);
17 while(*argv) {
18 vfork_args[a++] = *argv;
19 argv++;
20 }
21 vfork_args[a] = foreground_opt;
22 execvp("/proc/self/exe", vfork_args);
23 vfork_args[0] = "/bin/busybox";
24 execv(vfork_args[0], vfork_args);
25 bb_perror_msg_and_die("execv %s", vfork_args[0]);
26}
27#endif /* uClinux */
diff --git a/miscutils/Config.in b/miscutils/Config.in
index b4a3475de..0c56f0ee9 100644
--- a/miscutils/Config.in
+++ b/miscutils/Config.in
@@ -19,6 +19,13 @@ config CONFIG_CROND
19 Crond is a background daemon that parses individual crontab 19 Crond is a background daemon that parses individual crontab
20 files and executes commands on behalf of the users in question. 20 files and executes commands on behalf of the users in question.
21 21
22config CONFIG_FEATURE_CROND_CALL_SENDMAIL
23 bool " Using /usr/sbin/sendmail?"
24 default n
25 depends on CONFIG_CROND
26 help
27 Support call /usr/sbin/sendmail for send cmd outputs.
28
22config CONFIG_CRONTAB 29config CONFIG_CRONTAB
23 bool "crontab" 30 bool "crontab"
24 default n 31 default n
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 9d9ecc290..198bc2d85 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -41,14 +41,11 @@
41#ifndef TMPDIR 41#ifndef TMPDIR
42#define TMPDIR "/var/spool/cron" 42#define TMPDIR "/var/spool/cron"
43#endif 43#endif
44#ifndef LOG_FILE
45#define LOG_FILE "/var/log/cron"
46#endif
47#ifndef SENDMAIL 44#ifndef SENDMAIL
48#define SENDMAIL "/usr/sbin/sendmail" 45#define SENDMAIL "/usr/sbin/sendmail"
49#endif 46#endif
50#ifndef SENDMAIL_ARGS 47#ifndef SENDMAIL_ARGS
51#define SENDMAIL_ARGS "-t", "-oem", "-i" 48#define SENDMAIL_ARGS "-ti", "oem"
52#endif 49#endif
53#ifndef CRONUPDATE 50#ifndef CRONUPDATE
54#define CRONUPDATE "cron.update" 51#define CRONUPDATE "cron.update"
@@ -57,6 +54,7 @@
57#define MAXLINES 256 /* max lines in non-root crontabs */ 54#define MAXLINES 256 /* max lines in non-root crontabs */
58#endif 55#endif
59 56
57static const char def_sh[] = "/bin/sh";
60 58
61 59
62typedef struct CronFile { 60typedef struct CronFile {
@@ -71,7 +69,7 @@ typedef struct CronFile {
71typedef struct CronLine { 69typedef struct CronLine {
72 struct CronLine *cl_Next; 70 struct CronLine *cl_Next;
73 char *cl_Shell; /* shell command */ 71 char *cl_Shell; /* shell command */
74 int cl_Pid; /* running pid, 0, or armed (-1) */ 72 pid_t cl_Pid; /* running pid, 0, or armed (-1) */
75 int cl_MailFlag; /* running pid is for mail */ 73 int cl_MailFlag; /* running pid is for mail */
76 int cl_MailPos; /* 'empty file' size */ 74 int cl_MailPos; /* 'empty file' size */
77 char cl_Mins[60]; /* 0-59 */ 75 char cl_Mins[60]; /* 0-59 */
@@ -92,13 +90,9 @@ static short DebugOpt;
92#endif 90#endif
93 91
94static short LogLevel = 8; 92static short LogLevel = 8;
95static short ForegroundOpt; 93static const char *LogFile;
96static short LoggerOpt;
97static const char *LogFile = LOG_FILE;
98static const char *CDir = CRONTABS; 94static const char *CDir = CRONTABS;
99 95
100static void log(int level, const char *ctl, ...);
101static void log9(const char *ctl, ...);
102static void startlogger(void); 96static void startlogger(void);
103 97
104static void CheckUpdates(void); 98static void CheckUpdates(void);
@@ -106,14 +100,54 @@ static void SynchronizeDir(void);
106static int TestJobs(time_t t1, time_t t2); 100static int TestJobs(time_t t1, time_t t2);
107static void RunJobs(void); 101static void RunJobs(void);
108static int CheckJobs(void); 102static int CheckJobs(void);
109static void RunJob(CronFile *file, CronLine *line); 103
110static void EndJob(const CronFile *file, CronLine *line); 104static void RunJob(const char *user, CronLine *line);
105#ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL
106static void EndJob(const char *user, CronLine *line);
107#else
108#define EndJob(user, line) line->cl_Pid = 0
109#endif
111 110
112static void DeleteFile(const char *userName); 111static void DeleteFile(const char *userName);
113 112
114static CronFile *FileBase; 113static CronFile *FileBase;
115 114
116 115
116static void
117log(const char *ctl, ...)
118{
119 va_list va;
120 int level = (int)(ctl[0] & 0xf);
121 int type = level == 20 ?
122 LOG_ERR : ((ctl[0] & 0100) ? LOG_WARNING : LOG_NOTICE);
123
124
125 va_start(va, ctl);
126 if (level >= LogLevel) {
127
128#ifdef FEATURE_DEBUG_OPT
129 if (DebugOpt) vfprintf(stderr, ctl, va);
130 else
131#endif
132 if (LogFile == 0) vsyslog(type, ctl, va);
133 else {
134 int logfd;
135
136 if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0) {
137 vdprintf(logfd, ctl, va);
138 close(logfd);
139#ifdef FEATURE_DEBUG_OPT
140 } else {
141 bb_perror_msg("Can't open log file");
142#endif
143 }
144 }
145 }
146 va_end(va);
147 if(ctl[0] & 0200)
148 exit(20);
149}
150
117int 151int
118crond_main(int ac, char **av) 152crond_main(int ac, char **av)
119{ 153{
@@ -138,10 +172,8 @@ crond_main(int ac, char **av)
138 ); 172 );
139 if(opt & 1) 173 if(opt & 1)
140 LogLevel = atoi(lopt); 174 LogLevel = atoi(lopt);
141 LoggerOpt = opt & 2; 175 if(opt & 2)
142 if(LoggerOpt)
143 if (*Lopt != 0) LogFile = Lopt; 176 if (*Lopt != 0) LogFile = Lopt;
144 ForegroundOpt = opt & 4;
145 if(opt & 32) { 177 if(opt & 32) {
146 if (*copt != 0) CDir = copt; 178 if (*copt != 0) CDir = copt;
147 } 179 }
@@ -157,7 +189,7 @@ crond_main(int ac, char **av)
157 */ 189 */
158 190
159 if (chdir(CDir) != 0) 191 if (chdir(CDir) != 0)
160 bb_perror_msg_and_die("chdir"); 192 bb_perror_msg_and_die("%s", CDir);
161 193
162 signal(SIGHUP,SIG_IGN); /* hmm.. but, if kill -HUP original 194 signal(SIGHUP,SIG_IGN); /* hmm.. but, if kill -HUP original
163 * version - his died. ;( 195 * version - his died. ;(
@@ -168,9 +200,15 @@ crond_main(int ac, char **av)
168 * optional detach from controlling terminal 200 * optional detach from controlling terminal
169 */ 201 */
170 202
171 if (ForegroundOpt == 0) { 203 if (!(opt & 4)) {
172 if(daemon(1, 0) < 0) 204 if(daemon(1, 0) < 0) {
173 bb_perror_msg_and_die("daemon"); 205 bb_perror_msg_and_die("daemon");
206#if defined(__uClinux__)
207 } else {
208 /* reexec for vfork() do continue parent */
209 vfork_daemon_rexec(ac, av, "-f");
210 }
211#endif /* uClinux */
174 } 212 }
175 213
176 (void)startlogger(); /* need if syslog mode selected */ 214 (void)startlogger(); /* need if syslog mode selected */
@@ -180,7 +218,8 @@ crond_main(int ac, char **av)
180 * of 1 second. 218 * of 1 second.
181 */ 219 */
182 220
183 log(9,"%s " VERSION " dillon, started, log level %d\n", av[0], LogLevel); 221 log("\011%s " VERSION " dillon, started, log level %d\n", bb_applet_name,
222 LogLevel);
184 223
185 SynchronizeDir(); 224 SynchronizeDir();
186 225
@@ -221,11 +260,11 @@ crond_main(int ac, char **av)
221 CheckUpdates(); 260 CheckUpdates();
222#ifdef FEATURE_DEBUG_OPT 261#ifdef FEATURE_DEBUG_OPT
223 if (DebugOpt) 262 if (DebugOpt)
224 log(5, "Wakeup dt=%d\n", dt); 263 log("\005Wakeup dt=%d\n", dt);
225#endif 264#endif
226 if (dt < -60*60 || dt > 60*60) { 265 if (dt < -60*60 || dt > 60*60) {
227 t1 = t2; 266 t1 = t2;
228 log9("time disparity of %d minutes detected\n", dt / 60); 267 log("\111time disparity of %d minutes detected\n", dt / 60);
229 } else if (dt > 0) { 268 } else if (dt > 0) {
230 TestJobs(t1, t2); 269 TestJobs(t1, t2);
231 RunJobs(); 270 RunJobs();
@@ -242,81 +281,10 @@ crond_main(int ac, char **av)
242} 281}
243 282
244 283
245static void 284#if defined(FEATURE_DEBUG_OPT) || defined(CONFIG_FEATURE_CROND_CALL_SENDMAIL)
246vlog(int level, int MLOG_LEVEL, const char *ctl, va_list va)
247{
248 char buf[1024];
249 int logfd;
250
251 if (level >= LogLevel) {
252
253 vsnprintf(buf,sizeof(buf), ctl, va);
254#ifdef FEATURE_DEBUG_OPT
255 if (DebugOpt) fprintf(stderr,"%s",buf);
256 else
257#endif
258 if (LoggerOpt == 0) syslog(MLOG_LEVEL, "%s", buf);
259 else {
260 if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0){
261 write(logfd, buf, strlen(buf));
262 close(logfd);
263 } else
264#ifdef FEATURE_DEBUG_OPT
265 bb_perror_msg("Can't open log file")
266#endif
267 ;
268 }
269 }
270}
271
272/*
273 set log_level=9 and log messages
274*/
275
276static void
277log9(const char *ctl, ...)
278{
279 va_list va;
280
281 va_start(va, ctl);
282 vlog(9, LOG_WARNING, ctl, va);
283 va_end(va);
284}
285
286/*
287 normal logger call point.
288*/
289
290static void
291log(int level, const char *ctl, ...)
292{
293 va_list va;
294
295 va_start(va, ctl);
296 vlog(level, LOG_NOTICE, ctl, va);
297 va_end(va);
298}
299
300/* 285/*
301 Original: void 286 write to temp file..
302 logfd(int fd, const char *ctl, ...)
303 Updated to: log_error (used by jobs.c)
304*/ 287*/
305
306static void
307log_err(const char *ctl, ...)
308{
309 va_list va;
310
311 va_start(va, ctl);
312 vlog(20, LOG_ERR, ctl, va);
313 va_end(va);
314}
315
316/*
317 used by jobs.c (write to temp file..)
318*/
319
320static void 288static void
321fdprintf(int fd, const char *ctl, ...) 289fdprintf(int fd, const char *ctl, ...)
322{ 290{
@@ -326,10 +294,11 @@ fdprintf(int fd, const char *ctl, ...)
326 vdprintf(fd, ctl, va); 294 vdprintf(fd, ctl, va);
327 va_end(va); 295 va_end(va);
328} 296}
297#endif
329 298
330 299
331static int 300static int
332ChangeUser(const char *user, short dochdir) 301ChangeUser(const char *user)
333{ 302{
334 struct passwd *pas; 303 struct passwd *pas;
335 304
@@ -338,58 +307,55 @@ ChangeUser(const char *user, short dochdir)
338 */ 307 */
339 308
340 if ((pas = getpwnam(user)) == 0) { 309 if ((pas = getpwnam(user)) == 0) {
341 log(9, "failed to get uid for %s", user); 310 log("\011failed to get uid for %s", user);
342 return(-1); 311 return(-1);
343 } 312 }
344 setenv("USER", pas->pw_name, 1); 313 setenv("USER", pas->pw_name, 1);
345 setenv("HOME", pas->pw_dir, 1); 314 setenv("HOME", pas->pw_dir, 1);
346 setenv("SHELL", "/bin/sh", 1); 315 setenv("SHELL", def_sh, 1);
347 316
348 /* 317 /*
349 * Change running state to the user in question 318 * Change running state to the user in question
350 */ 319 */
351 320
352 if (initgroups(user, pas->pw_gid) < 0) { 321 if (initgroups(user, pas->pw_gid) < 0) {
353 log(9, "initgroups failed: %s %m", user); 322 log("\011initgroups failed: %s %m", user);
354 return(-1); 323 return(-1);
355 } 324 }
356 if (setregid(pas->pw_gid, pas->pw_gid) < 0) { 325 /* drop all priviledges */
357 log(9, "setregid failed: %s %d", user, pas->pw_gid); 326 if (setgid(pas->pw_gid) < 0) {
327 log("\011setgid failed: %s %d", user, pas->pw_gid);
358 return(-1); 328 return(-1);
359 } 329 }
360 if (setreuid(pas->pw_uid, pas->pw_uid) < 0) { 330 if (setuid(pas->pw_uid) < 0) {
361 log(9, "setreuid failed: %s %d", user, pas->pw_uid); 331 log("\011setuid failed: %s %d", user, pas->pw_uid);
362 return(-1); 332 return(-1);
363 } 333 }
364 if (dochdir) {
365 if (chdir(pas->pw_dir) < 0) { 334 if (chdir(pas->pw_dir) < 0) {
366 log(8, "chdir failed: %s %s", user, pas->pw_dir); 335 log("\011chdir failed: %s: %m", pas->pw_dir);
367 if (chdir(TMPDIR) < 0) { 336 if (chdir(TMPDIR) < 0) {
368 log(9, "chdir failed: %s %s", TMPDIR, user); 337 log("\011chdir failed: %s: %m", TMPDIR);
369 return(-1); 338 return(-1);
370 } 339 }
371 } 340 }
372 }
373 return(pas->pw_uid); 341 return(pas->pw_uid);
374} 342}
375 343
376static void 344static void
377startlogger(void) 345startlogger(void)
378{ 346{
347 if (LogFile == 0)
348 openlog(bb_applet_name, LOG_CONS|LOG_PID, LOG_CRON);
349#ifdef FEATURE_DEBUG_OPT
350 else { /* test logfile */
379 int logfd; 351 int logfd;
380 352
381 if (LoggerOpt == 0) 353 if ((logfd = open(LogFile, O_WRONLY|O_CREAT|O_APPEND, 600)) >= 0)
382 openlog(bb_applet_name, LOG_CONS|LOG_PID,LOG_CRON);
383
384 else { /* test logfile */
385 if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0)
386 close(logfd); 354 close(logfd);
387 else 355 else
388#ifdef FEATURE_DEBUG_OPT 356 bb_perror_msg("Failed to open log file '%s' reason", LogFile);
389 printf("Failed to open log file '%s' reason: %m", LogFile)
390#endif
391 ;
392 } 357 }
358#endif
393} 359}
394 360
395 361
@@ -493,7 +459,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
493 */ 459 */
494 460
495 if (skip == 0) { 461 if (skip == 0) {
496 log9("failed user %s parsing %s\n", user, base); 462 log("\111failed user %s parsing %s\n", user, base);
497 return(NULL); 463 return(NULL);
498 } 464 }
499 if (*ptr == '-' && n2 < 0) { 465 if (*ptr == '-' && n2 < 0) {
@@ -532,7 +498,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
532 } while (n1 != n2 && --failsafe); 498 } while (n1 != n2 && --failsafe);
533 499
534 if (failsafe == 0) { 500 if (failsafe == 0) {
535 log9("failed user %s parsing %s\n", user, base); 501 log("\111failed user %s parsing %s\n", user, base);
536 return(NULL); 502 return(NULL);
537 } 503 }
538 } 504 }
@@ -544,7 +510,7 @@ ParseField(char *user, char *ary, int modvalue, int off,
544 } 510 }
545 511
546 if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n') { 512 if (*ptr != ' ' && *ptr != '\t' && *ptr != '\n') {
547 log9("failed user %s parsing %s\n", user, base); 513 log("\111failed user %s parsing %s\n", user, base);
548 return(NULL); 514 return(NULL);
549 } 515 }
550 516
@@ -556,8 +522,8 @@ ParseField(char *user, char *ary, int modvalue, int off,
556 int i; 522 int i;
557 523
558 for (i = 0; i < modvalue; ++i) 524 for (i = 0; i < modvalue; ++i)
559 log(5, "%d", ary[i]); 525 log("\005%d", ary[i]);
560 log(5, "\n"); 526 log("\005\n");
561 } 527 }
562#endif 528#endif
563 529
@@ -636,7 +602,7 @@ SynchronizeFile(const char *fileName)
636 602
637#ifdef FEATURE_DEBUG_OPT 603#ifdef FEATURE_DEBUG_OPT
638 if (DebugOpt) 604 if (DebugOpt)
639 log9("User %s Entry %s\n", fileName, buf); 605 log("\111User %s Entry %s\n", fileName, buf);
640#endif 606#endif
641 607
642 /* 608 /*
@@ -674,7 +640,7 @@ SynchronizeFile(const char *fileName)
674 640
675#ifdef FEATURE_DEBUG_OPT 641#ifdef FEATURE_DEBUG_OPT
676 if (DebugOpt) { 642 if (DebugOpt) {
677 log9(" Command %s\n", ptr); 643 log("\111 Command %s\n", ptr);
678 } 644 }
679#endif 645#endif
680 646
@@ -686,7 +652,7 @@ SynchronizeFile(const char *fileName)
686 FileBase = file; 652 FileBase = file;
687 653
688 if (maxLines == 0 || maxEntries == 0) 654 if (maxLines == 0 || maxEntries == 0)
689 log9("Maximum number of lines reached for user %s\n", fileName); 655 log("\111Maximum number of lines reached for user %s\n", fileName);
690 } 656 }
691 fclose(fi); 657 fclose(fi);
692 } 658 }
@@ -712,21 +678,17 @@ static void
712SynchronizeDir(void) 678SynchronizeDir(void)
713{ 679{
714 /* 680 /*
715 * Attempt to delete the database. Note that we have to make a copy 681 * Attempt to delete the database.
716 * of the string
717 */ 682 */
718 683
719 for (;;) { 684 for (;;) {
720 CronFile *file; 685 CronFile *file;
721 char *user;
722 686
723 for (file = FileBase; file && file->cf_Deleted; file = file->cf_Next) 687 for (file = FileBase; file && file->cf_Deleted; file = file->cf_Next)
724 ; 688 ;
725 if (file == NULL) 689 if (file == NULL)
726 break; 690 break;
727 user = strdup(file->cf_User); 691 DeleteFile(file->cf_User);
728 DeleteFile(user);
729 free(user);
730 } 692 }
731 693
732 /* 694 /*
@@ -740,8 +702,7 @@ SynchronizeDir(void)
740 702
741 remove(CRONUPDATE); 703 remove(CRONUPDATE);
742 if (chdir(CDir) < 0) { 704 if (chdir(CDir) < 0) {
743 log9("unable to find %s\n", CDir); 705 log("\311unable to find %s\n", CDir);
744 exit(20);
745 } 706 }
746 { 707 {
747 DIR *dir; 708 DIR *dir;
@@ -754,12 +715,11 @@ SynchronizeDir(void)
754 if (getpwnam(den->d_name)) 715 if (getpwnam(den->d_name))
755 SynchronizeFile(den->d_name); 716 SynchronizeFile(den->d_name);
756 else 717 else
757 log(7, "ignoring %s\n", den->d_name); 718 log("\007ignoring %s\n", den->d_name);
758 } 719 }
759 closedir(dir); 720 closedir(dir);
760 } else { 721 } else {
761 log9("Unable to open current dir!\n"); 722 log("\311Unable to open current dir!\n");
762 exit(20);
763 } 723 }
764 } 724 }
765} 725}
@@ -836,14 +796,14 @@ TestJobs(time_t t1, time_t t2)
836 for (file = FileBase; file; file = file->cf_Next) { 796 for (file = FileBase; file; file = file->cf_Next) {
837#ifdef FEATURE_DEBUG_OPT 797#ifdef FEATURE_DEBUG_OPT
838 if (DebugOpt) 798 if (DebugOpt)
839 log(5, "FILE %s:\n", file->cf_User); 799 log("\005FILE %s:\n", file->cf_User);
840#endif 800#endif
841 if (file->cf_Deleted) 801 if (file->cf_Deleted)
842 continue; 802 continue;
843 for (line = file->cf_LineBase; line; line = line->cl_Next) { 803 for (line = file->cf_LineBase; line; line = line->cl_Next) {
844#ifdef FEATURE_DEBUG_OPT 804#ifdef FEATURE_DEBUG_OPT
845 if (DebugOpt) 805 if (DebugOpt)
846 log(5, " LINE %s\n", line->cl_Shell); 806 log("\005 LINE %s\n", line->cl_Shell);
847#endif 807#endif
848 if (line->cl_Mins[tp->tm_min] && 808 if (line->cl_Mins[tp->tm_min] &&
849 line->cl_Hrs[tp->tm_hour] && 809 line->cl_Hrs[tp->tm_hour] &&
@@ -852,10 +812,10 @@ TestJobs(time_t t1, time_t t2)
852 ) { 812 ) {
853#ifdef FEATURE_DEBUG_OPT 813#ifdef FEATURE_DEBUG_OPT
854 if (DebugOpt) 814 if (DebugOpt)
855 log(5, " JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell); 815 log("\005 JobToDo: %d %s\n", line->cl_Pid, line->cl_Shell);
856#endif 816#endif
857 if (line->cl_Pid > 0) { 817 if (line->cl_Pid > 0) {
858 log(8, " process already running: %s %s\n", 818 log("\010 process already running: %s %s\n",
859 file->cf_User, 819 file->cf_User,
860 line->cl_Shell 820 line->cl_Shell
861 ); 821 );
@@ -885,9 +845,9 @@ RunJobs(void)
885 for (line = file->cf_LineBase; line; line = line->cl_Next) { 845 for (line = file->cf_LineBase; line; line = line->cl_Next) {
886 if (line->cl_Pid < 0) { 846 if (line->cl_Pid < 0) {
887 847
888 RunJob(file, line); 848 RunJob(file->cf_User, line);
889 849
890 log(8, "USER %s pid %3d cmd %s\n", 850 log("\010USER %s pid %3d cmd %s\n",
891 file->cf_User, 851 file->cf_User,
892 line->cl_Pid, 852 line->cl_Pid,
893 line->cl_Shell 853 line->cl_Shell
@@ -926,7 +886,7 @@ CheckJobs(void)
926 int r = wait4(line->cl_Pid, &status, WNOHANG, NULL); 886 int r = wait4(line->cl_Pid, &status, WNOHANG, NULL);
927 887
928 if (r < 0 || r == line->cl_Pid) { 888 if (r < 0 || r == line->cl_Pid) {
929 EndJob(file, line); 889 EndJob(file->cf_User, line);
930 if (line->cl_Pid) 890 if (line->cl_Pid)
931 file->cf_Running = 1; 891 file->cf_Running = 1;
932 } else if (r == 0) { 892 } else if (r == 0) {
@@ -941,83 +901,54 @@ CheckJobs(void)
941} 901}
942 902
943 903
944 904#ifdef CONFIG_FEATURE_CROND_CALL_SENDMAIL
945static void 905static void
946RunJob(CronFile *file, CronLine *line) 906ForkJob(const char *user, CronLine *line, int mailFd,
907 const char *prog, const char *cmd, const char *arg, const char *mailf)
947{ 908{
948 char mailFile[128];
949 int mailFd;
950
951 line->cl_Pid = 0;
952 line->cl_MailFlag = 0;
953
954 /*
955 * open mail file - owner root so nobody can screw with it.
956 */
957
958 snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
959 file->cf_User, getpid());
960 mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600);
961
962 if (mailFd >= 0) {
963 line->cl_MailFlag = 1;
964 fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n",
965 file->cf_User,
966 line->cl_Shell
967 );
968 line->cl_MailPos = lseek(mailFd, 0, 1);
969 }
970
971 /* 909 /*
972 * Fork as the user in question and run program 910 * Fork as the user in question and run program
973 */ 911 */
912 pid_t pid = fork();
974 913
975 if ((line->cl_Pid = fork()) == 0) { 914 line->cl_Pid = pid;
915 if (pid == 0) {
976 /* 916 /*
977 * CHILD, FORK OK 917 * CHILD
978 */ 918 */
979 919
980 /* 920 /*
981 * Change running state to the user in question 921 * Change running state to the user in question
982 */ 922 */
983 923
984 if (ChangeUser(file->cf_User, 1) < 0) 924 if (ChangeUser(user) < 0)
985 return; 925 exit(0);
986 926
987#ifdef FEATURE_DEBUG_OPT 927#ifdef FEATURE_DEBUG_OPT
988 if (DebugOpt) 928 if (DebugOpt)
989 log(5, "Child Running %s\n", line->cl_Shell); 929 log("\005Child Running %s\n", prog);
990#endif 930#endif
991 931
992 /*
993 * stdin is already /dev/null, setup stdout and stderr
994 */
995
996 if (mailFd >= 0) { 932 if (mailFd >= 0) {
997 dup2(mailFd, 1); 933 dup2(mailFd, mailf != NULL);
998 dup2(mailFd, 2); 934 dup2((mailf ? mailFd : 1), 2);
999 close(mailFd); 935 close(mailFd);
1000 } else {
1001 log_err("unable to create mail file user %s file %s, output to /dev/null\n",
1002 file->cf_User,
1003 mailFile
1004 );
1005 } 936 }
1006 execl("/bin/sh", "/bin/sh", "-c", line->cl_Shell, NULL, NULL); 937 execl(prog, prog, cmd, arg, NULL);
1007 log_err("unable to exec, user %s cmd /bin/sh -c %s\n", 938 log("\024unable to exec, user %s cmd %s %s %s\n", user,
1008 file->cf_User, 939 prog, cmd, arg);
1009 line->cl_Shell 940 if(mailf)
1010 ); 941 fdprintf(1, "Exec failed: %s -c %s\n", prog, arg);
1011 fdprintf(1, "Exec failed: /bin/sh -c %s\n", line->cl_Shell);
1012 exit(0); 942 exit(0);
1013 } else if (line->cl_Pid < 0) { 943 } else if (pid < 0) {
1014 /* 944 /*
1015 * PARENT, FORK FAILED 945 * FORK FAILED
1016 */ 946 */
1017 log_err("couldn't fork, user %s\n", file->cf_User); 947 log("\024couldn't fork, user %s\n", user);
1018 line->cl_Pid = 0; 948 line->cl_Pid = 0;
1019 remove(mailFile); 949 if(mailf)
1020 } else { 950 remove(mailf);
951 } else if(mailf) {
1021 /* 952 /*
1022 * PARENT, FORK SUCCESS 953 * PARENT, FORK SUCCESS
1023 * 954 *
@@ -1026,10 +957,9 @@ RunJob(CronFile *file, CronLine *line)
1026 char mailFile2[128]; 957 char mailFile2[128];
1027 958
1028 snprintf(mailFile2, sizeof(mailFile2), TMPDIR "/cron.%s.%d", 959 snprintf(mailFile2, sizeof(mailFile2), TMPDIR "/cron.%s.%d",
1029 file->cf_User, line->cl_Pid); 960 user, pid);
1030 rename(mailFile, mailFile2); 961 rename(mailf, mailFile2);
1031 } 962 }
1032
1033 /* 963 /*
1034 * Close the mail file descriptor.. we can't just leave it open in 964 * Close the mail file descriptor.. we can't just leave it open in
1035 * a structure, closing it later, because we might run out of descriptors 965 * a structure, closing it later, because we might run out of descriptors
@@ -1039,12 +969,42 @@ RunJob(CronFile *file, CronLine *line)
1039 close(mailFd); 969 close(mailFd);
1040} 970}
1041 971
972static void
973RunJob(const char *user, CronLine *line)
974{
975 char mailFile[128];
976 int mailFd;
977
978 line->cl_Pid = 0;
979 line->cl_MailFlag = 0;
980
981 /*
982 * open mail file - owner root so nobody can screw with it.
983 */
984
985 snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
986 user, getpid());
987 mailFd = open(mailFile, O_CREAT|O_TRUNC|O_WRONLY|O_EXCL|O_APPEND, 0600);
988
989 if (mailFd >= 0) {
990 line->cl_MailFlag = 1;
991 fdprintf(mailFd, "To: %s\nSubject: cron: %s\n\n", user,
992 line->cl_Shell);
993 line->cl_MailPos = lseek(mailFd, 0, 1);
994 } else {
995 log("\024unable to create mail file user %s file %s, output to /dev/null\n",
996 user, mailFile);
997 }
998
999 ForkJob(user, line, mailFd, def_sh, "-c", line->cl_Shell, mailFile);
1000}
1001
1042/* 1002/*
1043 * EndJob - called when job terminates and when mail terminates 1003 * EndJob - called when job terminates and when mail terminates
1044 */ 1004 */
1045 1005
1046static void 1006static void
1047EndJob(const CronFile *file, CronLine *line) 1007EndJob(const char *user, CronLine *line)
1048{ 1008{
1049 int mailFd; 1009 int mailFd;
1050 char mailFile[128]; 1010 char mailFile[128];
@@ -1065,7 +1025,7 @@ EndJob(const CronFile *file, CronLine *line)
1065 */ 1025 */
1066 1026
1067 snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d", 1027 snprintf(mailFile, sizeof(mailFile), TMPDIR "/cron.%s.%d",
1068 file->cf_User, line->cl_Pid); 1028 user, line->cl_Pid);
1069 line->cl_Pid = 0; 1029 line->cl_Pid = 0;
1070 1030
1071 if (line->cl_MailFlag != 1) 1031 if (line->cl_MailFlag != 1)
@@ -1093,46 +1053,47 @@ EndJob(const CronFile *file, CronLine *line)
1093 close(mailFd); 1053 close(mailFd);
1094 return; 1054 return;
1095 } 1055 }
1056 ForkJob(user, line, mailFd, SENDMAIL, SENDMAIL_ARGS, NULL);
1057}
1058#else
1059/* crond whithout sendmail */
1096 1060
1097 if ((line->cl_Pid = fork()) == 0) { 1061static void
1062RunJob(const char *user, CronLine *line)
1063{
1098 /* 1064 /*
1099 * CHILD, FORK OK 1065 * Fork as the user in question and run program
1100 */ 1066 */
1067 pid_t pid = fork();
1101 1068
1069 if (pid == 0) {
1102 /* 1070 /*
1103 * change user id - no way in hell security can be compromised 1071 * CHILD
1104 * by the mailing and we already verified the mail file.
1105 */ 1072 */
1106 1073
1107 if (ChangeUser(file->cf_User, 1) < 0)
1108 exit(0);
1109
1110 /* 1074 /*
1111 * run sendmail with mail file as standard input, only if 1075 * Change running state to the user in question
1112 * mail file exists!
1113 */ 1076 */
1114 1077
1115 dup2(mailFd, 0); 1078 if (ChangeUser(user) < 0)
1116 dup2(1, 2); 1079 exit(0);
1117 close(mailFd); 1080
1081#ifdef FEATURE_DEBUG_OPT
1082 if (DebugOpt)
1083 log("\005Child Running %s\n", def_sh);
1084#endif
1118 1085
1119 execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, NULL, NULL); 1086 execl(def_sh, def_sh, "-c", line->cl_Shell, NULL);
1120 log_err("unable to exec %s %s, user %s, output to sink null", 1087 log("\024unable to exec, user %s cmd %s -c %s\n", user,
1121 SENDMAIL, 1088 def_sh, line->cl_Shell);
1122 SENDMAIL_ARGS,
1123 file->cf_User
1124 );
1125 exit(0); 1089 exit(0);
1126 } else if (line->cl_Pid < 0) { 1090 } else if (pid < 0) {
1127 /*
1128 * PARENT, FORK FAILED
1129 */
1130 log_err("unable to fork, user %s", file->cf_User);
1131 line->cl_Pid = 0;
1132 } else {
1133 /* 1091 /*
1134 * PARENT, FORK OK 1092 * FORK FAILED
1135 */ 1093 */
1094 log("\024couldn't fork, user %s\n", user);
1095 pid = 0;
1136 } 1096 }
1137 close(mailFd); 1097 line->cl_Pid = pid;
1138} 1098}
1099#endif /* CONFIG_FEATURE_CROND_CALL_SENDMAIL */
diff --git a/networking/Config.in b/networking/Config.in
index 406b99163..0bd17fb63 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -58,6 +58,13 @@ config CONFIG_FEATURE_HTTPD_BASIC_AUTH
58 Utilizes password settings from /etc/httpd.conf for basic 58 Utilizes password settings from /etc/httpd.conf for basic
59 authentication on a per url basis. 59 authentication on a per url basis.
60 60
61config CONFIG_FEATURE_HTTPD_AUTH_MD5
62 bool " Enable support MD5 crypted password for httpd.conf"
63 default n
64 depends on CONFIG_FEATURE_HTTPD_BASIC_AUTH
65 help
66 Please help my - send patch for set this help message
67
61 68
62if !CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY 69if !CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
63config CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP 70config CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
@@ -105,7 +112,7 @@ config CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
105 112
106config CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV 113config CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
107 bool " Enable setting of CGI_varname=value environment vars for CGI" 114 bool " Enable setting of CGI_varname=value environment vars for CGI"
108 default y 115 default n
109 depends on CONFIG_FEATURE_HTTPD_CGI 116 depends on CONFIG_FEATURE_HTTPD_CGI
110 help 117 help
111 This option parses POST or GET arguments from a form and 118 This option parses POST or GET arguments from a form and
diff --git a/networking/Makefile.in b/networking/Makefile.in
index 7d0d0b8bc..7748d066b 100644
--- a/networking/Makefile.in
+++ b/networking/Makefile.in
@@ -53,6 +53,13 @@ NETWORKING-$(CONFIG_WGET) += wget.o
53 53
54libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR) 54libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR)
55 55
56needcrypt-y:=
57needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y
58
59ifeq ($(needcrypt-y),y)
60 LIBRARIES += -lcrypt
61endif
62
56$(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y)) 63$(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y))
57 $(AR) -ro $@ $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y)) 64 $(AR) -ro $@ $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y))
58 65
diff --git a/networking/httpd.c b/networking/httpd.c
index d3d88fcb6..d58414b55 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -153,12 +153,14 @@ static const char home[] = "./";
153/* Config options, disable this for do very small module */ 153/* Config options, disable this for do very small module */
154//#define CONFIG_FEATURE_HTTPD_CGI 154//#define CONFIG_FEATURE_HTTPD_CGI
155//#define CONFIG_FEATURE_HTTPD_BASIC_AUTH 155//#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
156//#define CONFIG_FEATURE_HTTPD_AUTH_MD5
156 157
157#ifdef HTTPD_STANDALONE 158#ifdef HTTPD_STANDALONE
158/* standalone, enable all features */ 159/* standalone, enable all features */
159#undef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY 160#undef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
160/* unset config option for remove warning as redefined */ 161/* unset config option for remove warning as redefined */
161#undef CONFIG_FEATURE_HTTPD_BASIC_AUTH 162#undef CONFIG_FEATURE_HTTPD_BASIC_AUTH
163#undef CONFIG_FEATURE_HTTPD_AUTH_MD5
162#undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV 164#undef CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
163#undef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR 165#undef CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
164#undef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV 166#undef CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
@@ -168,6 +170,7 @@ static const char home[] = "./";
168#undef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP 170#undef CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP
169/* enable all features now */ 171/* enable all features now */
170#define CONFIG_FEATURE_HTTPD_BASIC_AUTH 172#define CONFIG_FEATURE_HTTPD_BASIC_AUTH
173#define CONFIG_FEATURE_HTTPD_AUTH_MD5
171#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV 174#define CONFIG_FEATURE_HTTPD_SET_CGI_VARS_TO_ENV
172#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR 175#define CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
173#define CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV 176#define CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
@@ -425,11 +428,11 @@ static void parse_conf(const char *path, int flag)
425 } 428 }
426 429
427 while((f = fopen(cf, "r")) == NULL) { 430 while((f = fopen(cf, "r")) == NULL) {
428 if(flag != FIRST_PARSE) { 431 if(flag == SUBDIR_PARSE || flag == FIND_FROM_HTTPD_ROOT) {
429 /* config file not found, no changes to config */ 432 /* config file not found, no changes to config */
430 return; 433 return;
431 } 434 }
432 if(config->configFile) /* if -c option given */ 435 if(config->configFile && flag == FIRST_PARSE) /* if -c option given */
433 bb_perror_msg_and_die("%s", cf); 436 bb_perror_msg_and_die("%s", cf);
434 flag = FIND_FROM_HTTPD_ROOT; 437 flag = FIND_FROM_HTTPD_ROOT;
435 cf = httpd_conf; 438 cf = httpd_conf;
@@ -1326,10 +1329,38 @@ static int checkPerm(const char *path, const char *request)
1326 if(strncmp(p0, path, l) == 0 && 1329 if(strncmp(p0, path, l) == 0 &&
1327 (l == 1 || path[l] == '/' || path[l] == 0)) { 1330 (l == 1 || path[l] == '/' || path[l] == 0)) {
1328 /* path match found. Check request */ 1331 /* path match found. Check request */
1332
1333 /* for check next /path:user:password */
1334 prev = p0;
1335#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1336 {
1337 char *cipher;
1338 char *pp;
1339 char *u = strchr(request, ':');
1340
1341 if(u == NULL) {
1342 /* bad request, ':' required */
1343 continue;
1344 }
1345 if(strncmp(p, request, u-request) != 0) {
1346 /* user uncompared */
1347 continue;
1348 }
1349 pp = strchr(p, ':');
1350 if(pp && pp[1] == '$' && pp[2] == '1' &&
1351 pp[3] == '$' && pp[4]) {
1352 pp++;
1353 cipher = pw_encrypt(u+1, pp);
1354 if (strcmp(cipher, pp) == 0)
1355 return 1; /* Ok */
1356 /* unauthorized */
1357 continue;
1358 }
1359 }
1360#endif
1329 if (strcmp(p, request) == 0) 1361 if (strcmp(p, request) == 0)
1330 return 1; /* Ok */ 1362 return 1; /* Ok */
1331 /* unauthorized, but check next /path:user:password */ 1363 /* unauthorized */
1332 prev = p0;
1333 } 1364 }
1334 } 1365 }
1335 } /* for */ 1366 } /* for */
@@ -1731,7 +1762,12 @@ static const char httpd_opts[]="c:d:h:"
1731#endif 1762#endif
1732#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH 1763#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
1733 "r:" 1764 "r:"
1734#define OPT_INC_2 1 1765# ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1766 "m:"
1767# define OPT_INC_2 2
1768# else
1769# define OPT_INC_2 1
1770#endif
1735#else 1771#else
1736#define OPT_INC_2 0 1772#define OPT_INC_2 0
1737#endif 1773#endif
@@ -1740,14 +1776,15 @@ static const char httpd_opts[]="c:d:h:"
1740#ifdef CONFIG_FEATURE_HTTPD_SETUID 1776#ifdef CONFIG_FEATURE_HTTPD_SETUID
1741 "u:" 1777 "u:"
1742#endif 1778#endif
1743#endif 1779#endif /* CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY */
1744 ; 1780 ;
1745 1781
1746#define OPT_CONFIG_FILE (1<<0) 1782#define OPT_CONFIG_FILE (1<<0)
1747#define OPT_DECODE_URL (1<<1) 1783#define OPT_DECODE_URL (1<<1)
1748#define OPT_HOME_HTTPD (1<<2) 1784#define OPT_HOME_HTTPD (1<<2)
1749#define OPT_ENCODE_URL (1<<(2+OPT_INC_1)) 1785#define OPT_ENCODE_URL (1<<(2+OPT_INC_1))
1750#define OPT_REALM (1<<(2+OPT_INC_1+OPT_INC_2)) 1786#define OPT_REALM (1<<(3+OPT_INC_1))
1787#define OPT_MD5 (1<<(4+OPT_INC_1))
1751#define OPT_PORT (1<<(3+OPT_INC_1+OPT_INC_2)) 1788#define OPT_PORT (1<<(3+OPT_INC_1+OPT_INC_2))
1752#define OPT_DEBUG (1<<(4+OPT_INC_1+OPT_INC_2)) 1789#define OPT_DEBUG (1<<(4+OPT_INC_1+OPT_INC_2))
1753#define OPT_SETUID (1<<(5+OPT_INC_1+OPT_INC_2)) 1790#define OPT_SETUID (1<<(5+OPT_INC_1+OPT_INC_2))
@@ -1778,6 +1815,10 @@ int httpd_main(int argc, char *argv[])
1778 long uid = -1; 1815 long uid = -1;
1779#endif 1816#endif
1780 1817
1818#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1819 const char *pass;
1820#endif
1821
1781 config = xcalloc(1, sizeof(*config)); 1822 config = xcalloc(1, sizeof(*config));
1782#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH 1823#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
1783 config->realm = "Web Server Authentication"; 1824 config->realm = "Web Server Authentication";
@@ -1796,6 +1837,9 @@ int httpd_main(int argc, char *argv[])
1796#endif 1837#endif
1797#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH 1838#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
1798 , &(config->realm) 1839 , &(config->realm)
1840# ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1841 , &pass
1842# endif
1799#endif 1843#endif
1800#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY 1844#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
1801 , &s_port 1845 , &s_port
@@ -1815,6 +1859,12 @@ int httpd_main(int argc, char *argv[])
1815 return 0; 1859 return 0;
1816 } 1860 }
1817#endif 1861#endif
1862#ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
1863 if(opt & OPT_MD5) {
1864 printf("%s\n", pw_encrypt(pass, "$1$"));
1865 return 0;
1866 }
1867#endif
1818#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY 1868#ifndef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
1819 if(opt & OPT_PORT) 1869 if(opt & OPT_PORT)
1820 config->port = bb_xgetlarg(s_port, 10, 1, 0xffff); 1870 config->port = bb_xgetlarg(s_port, 10, 1, 0xffff);
diff --git a/networking/inetd.c b/networking/inetd.c
index 33b97ba94..af262c39c 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -806,7 +806,9 @@ inetd_main(int argc, char *argv[])
806 struct passwd *pwd; 806 struct passwd *pwd;
807 struct group *grp = NULL; 807 struct group *grp = NULL;
808 struct sigaction sa; 808 struct sigaction sa;
809 int ch, pid; 809 int pid;
810 unsigned long opt;
811 char *sq;
810 gid_t gid; 812 gid_t gid;
811 813
812#ifdef INETD_UNSUPPORT_BILTIN 814#ifdef INETD_UNSUPPORT_BILTIN
@@ -828,14 +830,21 @@ inetd_main(int argc, char *argv[])
828 LastArg = environ[-1] + strlen(environ[-1]); 830 LastArg = environ[-1] + strlen(environ[-1]);
829#endif 831#endif
830 832
831 while ((ch = getopt(argc, argv, "q:")) != EOF) 833#if defined(__uClinux__)
832 switch(ch) { 834 opt = bb_getopt_ulflags(argc, argv, "q:f", &sq);
833 case 'q': 835 if (!(opt & 4)) {
836 daemon(0, 0);
837 /* reexec for vfork() do continue parent */
838 vfork_daemon_rexec(argc, argv, "-f");
839 }
840#else
841 opt = bb_getopt_ulflags(ac, av, "q:", &sq);
842 daemon(0, 0);
843#endif /* uClinux */
844
845 if(opt & 1) {
834 global_queuelen = atoi(optarg); 846 global_queuelen = atoi(optarg);
835 if (global_queuelen < 8) global_queuelen=8; 847 if (global_queuelen < 8) global_queuelen=8;
836 break;
837 default:
838 bb_show_usage(); // "[-q len] [conf]"
839 } 848 }
840 argc -= optind; 849 argc -= optind;
841 argv += optind; 850 argv += optind;
@@ -843,7 +852,6 @@ inetd_main(int argc, char *argv[])
843 if (argc > 0) 852 if (argc > 0)
844 CONFIG = argv[0]; 853 CONFIG = argv[0];
845 854
846 daemon(0, 0);
847 openlog(bb_applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON); 855 openlog(bb_applet_name, LOG_PID | LOG_NOWAIT, LOG_DAEMON);
848 { 856 {
849 FILE *fp; 857 FILE *fp;
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index f537a4bb8..2e187b199 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -150,8 +150,8 @@ extern int klogd_main(int argc, char **argv)
150#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__) 150#if !defined(__UCLIBC__) || defined(__UCLIBC_HAS_MMU__)
151 if (daemon(0, 1) < 0) 151 if (daemon(0, 1) < 0)
152 bb_perror_msg_and_die("daemon"); 152 bb_perror_msg_and_die("daemon");
153#else 153#if defined(__uClinux__)
154 bb_error_msg_and_die("daemon not supported"); 154 vfork_daemon_rexec(argc, argv, "-n");
155#endif 155#endif
156 } 156 }
157 doKlogd(console_log_level); 157 doKlogd(console_log_level);
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 67324116d..c554536c8 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -632,11 +632,12 @@ extern int syslogd_main(int argc, char **argv)
632 632
633 umask(0); 633 umask(0);
634 634
635#if ! defined(__uClinux__)
636 if ((doFork == TRUE) && (daemon(0, 1) < 0)) { 635 if ((doFork == TRUE) && (daemon(0, 1) < 0)) {
637 bb_perror_msg_and_die("daemon"); 636 bb_perror_msg_and_die("daemon");
638 } 637#if ! defined(__uClinux__)
638 vfork_daemon_rexec(argc, argv, "-n");
639#endif 639#endif
640 }
640 doSyslogd(); 641 doSyslogd();
641 642
642 return EXIT_SUCCESS; 643 return EXIT_SUCCESS;