|
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: 3923 (0xf53) Types: TextFile Notes: UNIX file Names: »atrun.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code └─⟦f4b8d8c84⟧ UNIX Filesystem └─ ⟦this⟧ »cmd/atrun.c«
/* * Atrun is the daemon which is regularly invoked by cron inorder * to run scripts saved by at. It runs the files by changeing its * uid and gid to the owner and then running a shell on them. * In order to have the ability to set its uid and group id, it * must be set uid to root. * Since anyone can write into the at spooling directory, for a * script to be run, it must have the set uid, set gid and owner * execute bits set. */ #include <stdio.h> #include <sys/types.h> #include <ctype.h> #include <dir.h> #include <time.h> #include <setjmp.h> #include <sys/stat.h> #define MODE 06100 /* set uid, set gid, owner exec */ #define TRUE (0 == 0) #define FALSE (0 != 0) #define STDIN 0 /* standard input file descriptor */ #define STDOUT 1 /* standard output file descriptor */ #define STDERR 2 /* standard error file descriptor */ #define RW 2 /* open code for read and write */ struct tm *now; /* current time */ char atdir[] = "/usr/spool/at"; jmp_buf cerror; /* where to go if file is strange */ FILE *atfp; /* stream for file atdir */ main() { time_t ct; struct direct dent; time_t time(); if (chdir(atdir) < 0) exit(1); time(&ct); now = localtime(&ct); atfp = fopen(".", "r"); if (atfp == NULL) exit(1); while (fread(&dent, sizeof dent, 1, atfp) == 1) check(&dent, now); return (0); } /* * Check checks to see if the file with directory entry `dent' * should be executed. */ check(dent) register struct direct *dent; { struct tm dot; if (dent->d_ino == 0 || setjmp(cerror)) return; gettime(&dot, dent->d_name); if (cmptime(&dot, now) <= 0) docmd(dent->d_name); } /* * Gettime fills in certain fields in the struct tm `time' according to * the file name `name'. The file name is assumed to be of the form * yymmddhhmm.xx where * yy is the last two digits of the year * mm is the month number (1 - 12) * dd is the day of the month (1 - 31) * hh is the hour * mm is the minute * Only the corresponding fields of `time' are filled in. */ gettime(time, name) register struct tm *time; register char *name; { time->tm_year = cnum2(name); name += 2; /* * This kludge will fail in 2070. */ if (time->tm_year < 70) time->tm_year += 100; time->tm_mon = cnum2(name) - 1; name += 2; time->tm_mday = cnum2(name); name += 2; time->tm_hour = cnum2(name); name += 2; time->tm_min = cnum2(name); if (name[2] != '.') longjmp(cerror, TRUE); } /* * Cnum2 converts the first two characters of the string `str' * to a number. */ cnum2(str) register char *str; { register int res, i; for (res=0, i=2; --i >= 0; ++str) { if (!isascii(*str) || !isdigit(*str)) longjmp(cerror, TRUE); res *= 10; res += *str - '0'; } return (res); } /* * Cmptime compares the two struct tm's `a' and `b'. It returns * a number which compares to zero in the same way that `a' compares * to `b'. */ cmptime(a, b) register struct tm *a, *b; { register int res; if ((res = a->tm_year - b->tm_year) != 0) return (res); if ((res = a->tm_mon - b->tm_mon) != 0) return (res); if ((res = a->tm_mday - b->tm_mday) != 0) return (res); if ((res = a->tm_hour - b->tm_hour) != 0) return (res); return (a->tm_min - b->tm_min); } /* * Docmd executes the shell command file `file'. This entails * forking of a child which changes its user and group id and * then calls the shell. */ docmd(file) char *file; { register int fd; char cbuf[DIRSIZ + 2]; struct stat sbuf; if (fork() != 0) return; fclose(atfp); strncpy(cbuf, file, DIRSIZ+1); if (stat(cbuf, &sbuf) != 0) exit(1); if ((MODE & ~sbuf.st_mode) != 0) exit(1); if (setgid(sbuf.st_gid) != 0) exit(1); if (setuid(sbuf.st_uid) != 0) exit(1); if ((fd = open("/dev/null", RW)) == EOF) exit(1); dup2(fd, STDIN); dup2(fd, STDOUT); dup2(fd, STDERR); close(fd); strcat(cbuf, "&"); execle("/bin/sh", "sh", "-c", cbuf, NULL, NULL); exit(1); }