--- ./CHANGES:1.1 Fri Jan 7 18:15:59 2000 +++ ./CHANGES Thu Apr 20 12:10:36 2000 @@ -1,3 +1,15 @@ +20/03/00 - TEMHOTA + Adding SIGHUP signal handler. crond die when init send to it SIGHUP. + Rewrtited all loging code. Added logging through syslog and normal + logging to file. + + Technical details: + + logging through syslog used facility LOG_CRON + + log_err - now *always* write message to logger (if selected logging + through syslog - message send as LOG_ERR). + + log9 - sends message hrough syslog loglevel LOG_WARNING + + for all other log levels - default syslog loglevel LOG_NOTICE + 02/16/98 - Jordan Mendelson (jordy@wserv.com) Numerous people have reported a problem with logging. I'm sorry --- ./Makefile:1.1 Fri Jan 7 18:15:59 2000 +++ ./Makefile Thu Apr 20 12:24:40 2000 @@ -27,7 +27,7 @@ rm -f crond crontab cleano: - rm -f *.o dcron.tgz $(PROTOS) + rm -f *.o dcron.tgz $(PROTOS) *~ install: crond crontab install -o root -g root -m 0755 crond /usr/sbin --- ./crontab.c:1.1 Fri Jan 7 18:15:59 2000 +++ ./crontab.c Sun Mar 19 15:03:36 2000 @@ -15,6 +15,9 @@ char *CDir = CRONTABS; int UserId; short LogLevel = 9; +short DebugOpt = 0; +short LoggerOpt = 0; +char *LogFile = LOG_FILE; void EditFile(const char *user, const char *file); int GetReplaceStream(const char *user, const char *file); @@ -136,7 +139,7 @@ */ if (chdir(CDir) < 0) { - fprintf(stderr, "cannot change diir to %s: %s\n", CDir, strerror(errno)); + fprintf(stderr, "cannot change dir to %s: %s\n", CDir, strerror(errno)); exit(1); } --- ./defs.h:1.1 Fri Jan 7 18:15:59 2000 +++ ./defs.h Sun Mar 19 15:03:36 2000 @@ -17,6 +17,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -30,6 +33,9 @@ #endif #ifndef TMPDIR #define TMPDIR "/var/spool/cron" +#endif +#ifndef LOG_FILE +#define LOG_FILE "/var/log/cron" #endif #ifndef OPEN_MAX #define OPEN_MAX 256 --- ./job.c:1.1 Fri Jan 7 18:15:59 2000 +++ ./job.c Thu Apr 20 12:10:36 2000 @@ -16,7 +16,7 @@ { char mailFile[128]; int mailFd; - + line->cl_Pid = 0; line->cl_MailFlag = 0; @@ -57,14 +57,6 @@ log(5, "Child Running %s\n", line->cl_Shell); /* - * Setup close-on-exec descriptor in case exec fails - */ - - dup2(2, 8); - fcntl(8, F_SETFD, 1); - fclose(stderr); - - /* * stdin is already /dev/null, setup stdout and stderr */ @@ -73,13 +65,13 @@ dup2(mailFd, 2); close(mailFd); } else { - logfd(8, "unable to create mail file user %s file %s, output to /dev/null\n", + log_err("unable to create mail file user %s file %s, output to /dev/null\n", file->cf_User, mailFile ); } execl("/bin/sh", "/bin/sh", "-c", line->cl_Shell, NULL, NULL); - logfd(8, "unable to exec, user %s cmd /bin/sh -c %s\n", + log_err("unable to exec, user %s cmd /bin/sh -c %s\n", file->cf_User, line->cl_Shell ); @@ -89,7 +81,7 @@ /* * PARENT, FORK FAILED */ - log9("couldn't fork, user %s\n", file->cf_User); + log_err("couldn't fork, user %s\n", file->cf_User); line->cl_Pid = 0; remove(mailFile); } else { @@ -158,6 +150,7 @@ if (mailFd < 0) { return; } + if (fstat(mailFd, &sbuf) < 0 || sbuf.st_uid != DaemonUid || sbuf.st_nlink != 0 || @@ -182,15 +175,6 @@ exit(0); /* - * create close-on-exec log descriptor in case exec fails - */ - - dup2(2, 8); - fcntl(8, F_SETFD, 1); - - fclose(stderr); - - /* * run sendmail with mail file as standard input, only if * mail file exists! */ @@ -200,7 +184,7 @@ close(mailFd); execl(SENDMAIL, SENDMAIL, SENDMAIL_ARGS, NULL, NULL); - logfd(8, "unable to exec %s %s, user %s, output to sink null", + log_err("unable to exec %s %s, user %s, output to sink null", SENDMAIL, SENDMAIL_ARGS, file->cf_User @@ -210,7 +194,7 @@ /* * PARENT, FORK FAILED */ - log9("unable to fork, user %s", file->cf_User); + log_err("unable to fork, user %s", file->cf_User); line->cl_Pid = 0; } else { /* --- ./main.c:1.1 Fri Jan 7 18:15:59 2000 +++ ./main.c Sun Mar 19 15:03:36 2000 @@ -15,14 +15,18 @@ Prototype short DebugOpt; Prototype short LogLevel; Prototype short ForegroundOpt; -Prototype char *CDir; -Prototype int DaemonUid; +Prototype short LoggerOpt; +Prototype char *CDir; +Prototype char *LogFile; +Prototype uid_t DaemonUid; short DebugOpt; short LogLevel = 8; -short ForegroundOpt; +short ForegroundOpt = 0; +short LoggerOpt; char *CDir = CRONTABS; -int DaemonUid; +char *LogFile = LOG_FILE; +uid_t DaemonUid; int main(int ac, char **av) @@ -35,48 +39,49 @@ DaemonUid = getuid(); - for (i = 1; i < ac; ++i) { - char *ptr = av[i]; + opterr = 0; /* disable getopt 'errors' message.*/ - if (*ptr == '-') { - ptr += 2; - - switch(ptr[-1]) { + while ((i = getopt(ac,av,"d:l:L:fbSc:")) != EOF){ + + switch (i){ case 'l': - LogLevel = (*ptr) ? strtol(ptr, NULL, 0) : 1; - continue; + LogLevel = atoi(optarg); + break; case 'd': - DebugOpt = (*ptr) ? strtol(ptr, NULL, 0) : 1; + DebugOpt = atoi(optarg); LogLevel = 0; /* fall through */ + break; case 'f': ForegroundOpt = 1; - continue; + break; case 'b': ForegroundOpt = 0; - continue; + break; + case 'S': /* select logging to syslog */ + LoggerOpt = 0; + break; + case 'L': /* select internal file logger */ + LoggerOpt = 1; + if (*optarg != 0) LogFile = optarg; + break; case 'c': - CDir = (*ptr) ? ptr : av[++i]; - continue; + if (*optarg != 0) CDir = optarg; + break; default: + /* + * parse error + */ + printf("dcron " VERSION "\n"); + printf("dcron -d [#] -l [#] -S -L logfile -f -b -c dir\n"); + printf("-d num\tdebug level\n-l num\tlog level (8 - default)\n-S\tlog to syslod (defualt)\n"); + printf("-L file\tlog to file\n-f\trun in fordeground\n"); + printf("-b\trun in background (default)\n-c dir\tworking dir\n"); + exit(1); break; - } - } - break; /* error */ - } - - /* - * check for parse error - */ - - if (i != ac) { - if (i > ac) - puts("expected argument for option"); - printf("dcron " VERSION "\n"); - printf("dcron -d[#] -l[#] -f -b -c dir\n"); - exit(1); + } } - + /* * change directory */ @@ -87,14 +92,15 @@ } /* - * close stdin and stdout (stderr normally redirected by caller). - * close unused descriptors + * close stdin and stdout, stderr. + * close unused descriptors - don't need. * optional detach from controlling terminal */ fclose(stdin); fclose(stdout); - + fclose(stderr); + i = open("/dev/null", O_RDWR); if (i < 0) { perror("open: /dev/null:"); @@ -102,15 +108,14 @@ } dup2(i, 0); dup2(i, 1); + dup2(i, 2); - for (i = 3; i < OPEN_MAX; ++i) { - close(i); - } - if (ForegroundOpt == 0) { int fd; int pid; - + if (setsid() < 0) + perror("setsid"); + if ((fd = open("/dev/tty", O_RDWR)) >= 0) { ioctl(fd, TIOCNOTTY, 0); close(fd); @@ -125,13 +130,17 @@ if (pid > 0) exit(0); } - + + (void)startlogger(); /* need if syslog mode selected */ + (void)initsignals(); /* set some signal handlers */ + /* * main loop - synchronize to 1 second after the minute, minimum sleep * of 1 second. */ + + log(9,"%s " VERSION " dillon, started, log level %d\n", av[0], LogLevel); - log9("%s " VERSION " dillon, started\n", av[0]); SynchronizeDir("."); { --- ./subs.c:1.1 Fri Jan 7 18:15:59 2000 +++ ./subs.c Sun Mar 19 15:03:36 2000 @@ -10,43 +10,62 @@ Prototype void log(int level, const char *ctl, ...); Prototype void log9(const char *ctl, ...); -Prototype void logfd(int fd, const char *ctl, ...); +Prototype void log_err(const char *ctl, ...); Prototype void fdprintf(int fd, const char *ctl, ...); -Prototype int ChangeUser(const char *user, short dochdir); -Prototype void vlog(int level, int fd, const char *ctl, va_list va); -Prototype int slog(char *buf, size_t sz, const char *ctl, va_list va, short useDate); +Prototype void vlog(int level, int MLOG_LEVEL, const char *ctl, va_list va); +Prototype int ChangeUser(const char *user, short dochdir); Prototype char *xx_strdup(const char *); +Prototype void startlogger(void); +Prototype void initsignals(void); +/* + set log_level=9 and log messages +*/ + void log9(const char *ctl, ...) { va_list va; va_start(va, ctl); - vlog(9, 2, ctl, va); + vlog(9, LOG_WARNING, ctl, va); va_end(va); } +/* + normal logger call point. +*/ + void log(int level, const char *ctl, ...) { va_list va; va_start(va, ctl); - vlog(level, 2, ctl, va); + vlog(level, LOG_NOTICE, ctl, va); va_end(va); } +/* + Original: void + logfd(int fd, const char *ctl, ...) + Updated to: log_error (used by jobs.c) +*/ + void -logfd(int fd, const char *ctl, ...) +log_err(const char *ctl, ...) { va_list va; va_start(va, ctl); - vlog(9, fd, ctl, va); + vlog(20, LOG_ERR, ctl, va); va_end(va); } +/* + used by jobs.c (write to temp file..) +*/ + void fdprintf(int fd, const char *ctl, ...) { @@ -60,32 +79,28 @@ } void -vlog(int level, int fd, const char *ctl, va_list va) +vlog(int level, int MLOG_LEVEL, const char *ctl, va_list va) { char buf[1024]; - short n; - static short useDate = 1; + int logfd; if (level >= LogLevel) { - write(fd, buf, n = slog(buf, sizeof(buf), ctl, va, useDate)); - useDate = (n && buf[n-1] == '\n'); + + vsnprintf(buf,sizeof(buf), ctl, va); + if (DebugOpt) fprintf(stderr,"%s",buf); + else + if (LoggerOpt == 0) syslog(MLOG_LEVEL, "%s",buf ); + else { + if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0){ + write(logfd, buf, strlen(buf)); + close(logfd); + } else + fprintf(stderr,"Can't open log file. Err: %s",strerror(errno)); + } } } int -slog(char *buf, size_t sz, const char *ctl, va_list va, short useDate) -{ - time_t t = time(NULL); - struct tm *tp = localtime(&t); - - buf[0] = 0; - if (useDate) - strftime(buf, 128, "%d-%b-%Y %H:%M ", tp); - vsnprintf(buf + strlen(buf), sz - strlen(buf), ctl, va); - return(strlen(buf)); -} - -int ChangeUser(const char *user, short dochdir) { struct passwd *pas; @@ -141,3 +156,28 @@ return(ptr); } + +void +startlogger(void){ +int logfd; + + if (LoggerOpt == 0) + openlog("crond",LOG_CONS|LOG_PID,LOG_CRON); + + else { /* test logfile */ + if ((logfd = open(LogFile,O_WRONLY|O_CREAT|O_APPEND,600)) >= 0) + close(logfd); + else + printf("Failed to open log file '%s' reason: %s",LogFile,strerror(errno)); + } +} + + +void +initsignals(void){ + + signal(SIGHUP,SIG_IGN); /* hmm.. but, if kill -HUP original + * version - his died. ;( + */ + +}