|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 6898 (0x1af2) Types: TextFile Notes: UNIX file Names: »Ncron.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/Ncron.c«
/* * Cron. Execute commands stored in /usr/lib/crontab at preset times. * It sets its uid and gid to those of daemon, if possible. */ #include <stdio.h> #include <sys/types.h> #include <time.h> #include <signal.h> #include <errno.h> #include <ctype.h> #include <pwd.h> #define TRUE (0 == 0) #define FALSE (0 != 0) /* * Time field types. */ #define MIN 0 #define HOUR 1 #define MDAY 2 #define MON 3 #define WDAY 4 /* * (Finite) States in valid(). */ #define START 0 #define INT 1 #define INTDASH 2 #define RANGE 3 #define STR 4 #define STRPLUS 5 #define ERR 6 #define END 7 #define GLOB ('*') /* * Tokens returned by gettoken(). Tokens are integers. EOF is also a token. * INT, STR and GLOB above are also tokens. */ #define DASH ('-') #define COMMA (',') #define WS (' ') #define PERCENT (-2) #define NEWLINE (-3) struct tm *tm; long clock; int tmfield[5]; FILE *f; extern int errno; int ugtokflag = FALSE; int ugtoken; int ufetflag = FALSE; int ufetval; char *tokbuf; int buflen = 512; char crontab[] = "/usr/lib/crontab"; char clog[] = "/usr/lib/cronlog"; main() { int n; register FILE *logf; sigsetup(); todaemon(); tokbuf = malloc(buflen); chdir("/bin"); time(&clock); tm = localtime(&clock); alarm(61 - tm->tm_sec); for (;;) { /* Put the time values into tmfield[] for easy reference. * localtime() gives tm_mon in the range 0-11, tm_wday, 0-6 * (0=sunday). These are adjusted for cron's syntax. */ tmfield[MIN] = tm->tm_min; tmfield[HOUR] = tm->tm_hour; tmfield[MDAY] = tm->tm_mday; tmfield[MON] = tm->tm_mon + 1; tmfield[WDAY] = tm->tm_wday; if (tm->tm_min == 0) { logf = fopen(clog, "a"); fputc(0x0A, logf); fwrite(ctime(&clock), strlen(ctime(&clock)), 1, logf); fputc(0x0A, logf); fclose(logf); } if ((f = fopen(crontab, "r")) != NULL) { while (tex() != EOF) ; fclose(f); } while (wait(&n) != -1) ; if (errno == ECHILD) pause(); } } /* * Test and Execute: tests a crontab entry against the time fields in `tm' to * see if it should be executed, if so it executes. f is left pointing to the * next entry (line). Returns EOF when encountered, something else otherwise. */ tex() { register int fieldnum; for (fieldnum = MIN; fieldnum <= WDAY; ++fieldnum) if (!valid(fieldnum)) return (skip_it()); return (do_it()); } /* * Valid(fieldnum) parses the next time field from the current line in crontab * and checks whether tmfield[fieldnum] satisfies the constraints of that time * field. Returns TRUE if so, FALSE if not. Leaves f at the next field. * Detects syntax errors in the time fields. */ valid(fieldnum) int fieldnum; { register int t; register int ival; register int state = START; int ival2; int tm_val = tmfield[fieldnum]; if (fieldnum == MIN) { while ((t = gettoken()) == WS || t == NEWLINE) ; ungettoken(t); } for (;;) { t = gettoken(); switch (state) { case START: switch (t) { case INT: if (strlen(tokbuf) <= 2) { ival = atoi(tokbuf); state = INT; } else state = ERR; break; case GLOB: state = GLOB; break; case WS: state = END; break; default: state = ERR; break; } break; case INT: if (t == COMMA || t == WS) { if (ival == tm_val) { while (t != WS) t = gettoken(); return (TRUE); } state = (t == WS) ? END : START; } else if (t == DASH) state = INTDASH; else state = ERR; break; case INTDASH: if (t == INT && strlen(tokbuf) <= 2) { ival2 = atoi(tokbuf); state = RANGE; } else state = ERR; break; case RANGE: if (t == COMMA || t == WS) { if (ival <= tm_val && tm_val <= ival2) { while (t != WS) t = gettoken(); return (TRUE); } state = (t == WS) ? END : START; } else state = ERR; break; case GLOB: if (t == COMMA || t == WS) { while (t != WS) t = gettoken(); return (TRUE); } else state = ERR; break; } /* End switch on state */ if (state == END) return (FALSE); if (state == ERR) { ungettoken(t); ungettoken(skip_it()); return (FALSE); } } } ungettoken(t) int t; { ugtokflag = TRUE; ugtoken = t; } gettoken() { register int c; register char *sp = tokbuf; register char *mark; int posn; if (ugtokflag) { ugtokflag = FALSE; return (ugtoken); } switch (c = fetch()) { case NEWLINE: case EOF: case PERCENT: return (c); case ' ': case '\t': while ((c = fetch()) == ' ' || c == '\t') ; unfetch(c); return (WS); case '-': return (DASH); case ',': return (COMMA); case '*': return (GLOB); } /* * Case of INT. Place ascii digit string into tokbuf. */ if (isdigit(c)) { *sp++ = c; while (isdigit(c = fetch())) *sp++ = c; unfetch(c); *sp = '\0'; return (INT); } /* * The only remaining possibility is the token STR or STRPLUS. */ *sp++ = c; mark = tokbuf + buflen - 2; while ((c = fetch()) != EOF && c != NEWLINE && c != PERCENT) { if (sp == mark) { posn = sp - tokbuf; tokbuf = realloc(tokbuf, (buflen += 128)); sp = tokbuf + posn; mark = sp + buflen; } *sp++ = c; } *sp = '\0'; if (c == PERCENT) return (STRPLUS); unfetch(c); return (STR); } unfetch(c) int c; { ufetval = c; ufetflag = TRUE; } fetch() { register int c; register int c2; if (ufetflag) { ufetflag = FALSE; return (ufetval); } for (;;) switch (c = getc(f)) { case '%': return (PERCENT); case '\n': return (NEWLINE); case '\\': if ((c2 = getc(f)) == '%') return ('%'); else if (c2 == '\n') continue; else { ungetc(c2, f); return ('\\'); } default: return (c); } } skip_it() { register int t; while ((t = gettoken()) != EOF && t != NEWLINE) ; return (t); } do_it() { register int c; register FILE *fp, *logf; if ((c = gettoken()) != STR && c != STRPLUS) { ungettoken(c); return (skip_it()); } if ((fp = popen(tokbuf, "w")) == NULL) { fprintf(stderr, "Cron:\tCould not popen: %s\n\t\ errno = %d: %s.\n", tokbuf, errno, perror()); return (skip_it()); } logf = fopen(clog, "a"); fwrite(tokbuf, strlen(tokbuf), 1, logf); fputc(0x0A, logf); fclose(logf); if (c == STR) { fclose(fp); return (gettoken()); } while ((c = fetch()) != NEWLINE && c != EOF) if (c == PERCENT) putc('\n', fp); else putc(c, fp); putc('\n', fp); fclose(fp); return(c); } sigsetup() { int catchalarm(); signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGALRM, catchalarm); } catchalarm() { signal(SIGALRM, catchalarm); time(&clock); tm = localtime(&clock); alarm(61 - tm->tm_sec); } todaemon() { register struct passwd *pwp; struct passwd *getpwnam(); pwp = getpwnam("daemon"); endpwent(); if (pwp == NULL) return; setgid(pwp->pw_gid); setuid(pwp->pw_uid); }