Remove building with NOCRYPTO option
[minix.git] / minix / commands / crontab / crontab.c
blob7985b87dc410468c445162361f097b62294f8371
1 /* crontab 1.2 - user crontab manipulation Author: Kees J. Bot
2 * 12 Jan 1997
3 */
4 #define nil ((void*)0)
5 #include <sys/types.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <signal.h>
10 #include <time.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <fcntl.h>
14 #include <pwd.h>
15 #include <sys/stat.h>
16 #include "misc.h"
17 #include "tab.h"
19 static int opentab(int uid, char *file, int how)
20 /* Open a crontab file under the given uid. How is 'r' or 'w'. Return
21 * the result of open(2).
24 uid_t safe_uid;
25 int flags, r, err;
27 switch (how) {
28 case 'r': flags= O_RDONLY; break;
29 case 'w': flags= O_WRONLY | O_CREAT | O_TRUNC; break;
30 default: errno= EINVAL; return -1;
33 safe_uid= geteuid();
34 seteuid(uid);
35 r= open(file, flags, 0666);
36 err= errno;
37 seteuid(safe_uid);
38 errno= err;
39 return r;
42 static void copytab(int fd_in, char *file_in, int fd_out, char *file_out)
43 /* Copy one open file to another. Complain and exit on errors. */
45 ssize_t r, w;
46 char buf[1024];
48 while ((r= read(fd_in, buf, sizeof(buf))) > 0) {
49 w= 0;
50 while (w < r) {
51 if ((r= write(fd_out, buf+w, r-w)) <= 0) {
52 fprintf(stderr,
53 "%s: Write error on %s: %s\n",
54 prog_name,
55 file_out,
56 r == 0 ? "End of file"
57 : strerror(errno));
58 exit(1);
60 w+= r;
63 if (r < 0) {
64 fprintf(stderr, "%s: Read error on %s: %s\n",
65 prog_name, file_in, strerror(errno));
66 exit(1);
70 static void usage(void)
72 fprintf(stderr,
73 "Usage: %s -c [user] file # Change crontab\n"
74 " %s -l [user] # List crontab\n"
75 " %s -r [user] # Remove crontab\n"
76 " %s -p # Tell cron to reload\n",
77 prog_name, prog_name, prog_name, prog_name);
78 exit(1);
81 int main(int argc, char **argv)
83 int i;
84 int cflag, lflag, rflag, pflag;
85 uid_t uid;
86 char *user, *file;
87 struct passwd *pw;
88 static char SPOOLDIR[]= "/usr/spool/crontabs";
89 char tabfile[sizeof(SPOOLDIR) + NAME_MAX];
91 prog_name= strrchr(argv[0], '/');
92 if (prog_name == nil) prog_name= argv[0]; else prog_name++;
94 cflag= lflag= rflag= pflag= 0;
95 i= 1;
96 while (i < argc && argv[i][0] == '-') {
97 char *opt= argv[i++] + 1;
99 if (opt[0] == '-' && opt[1] == 0) break; /* -- */
101 while (*opt != 0) switch (*opt++) {
102 case 'c': cflag= 1; break;
103 case 'l': lflag= 1; break;
104 case 'r': rflag= 1; break;
105 case 'p': pflag= 1; break;
106 default: usage();
109 if (cflag + lflag + rflag + pflag != 1) usage();
111 user= file= nil;
112 if (!pflag && i < argc) user= argv[i++];
113 if (cflag) {
114 if (user == nil) usage();
115 if (i < argc) {
116 file= argv[i++];
117 } else {
118 file= user;
119 user= nil;
122 if (i != argc) usage();
124 if (geteuid() != 0) {
125 fprintf(stderr, "%s: No root privileges?\n", prog_name);
127 uid= getuid();
128 if (user == nil) {
129 if ((pw= getpwuid(uid)) == nil) {
130 fprintf(stderr,
131 "%s: Don't know who you (uid %lu) are!\n",
132 prog_name, (unsigned long) uid);
133 exit(1);
135 } else {
136 if ((pw= getpwnam(user)) == nil) {
137 fprintf(stderr,
138 "%s: Don't know who you (%s) are!\n",
139 prog_name, user);
140 exit(1);
143 if (uid != 0 && pw->pw_uid != uid) {
144 fprintf(stderr,
145 "%s: Only root can change the crontabs of others!\n",
146 prog_name);
147 exit(1);
149 user= pw->pw_name;
150 uid= pw->pw_uid;
151 seteuid(uid);
152 umask(0077);
154 selectlog(STDERR);
155 sprintf(tabfile, "%s/%s", SPOOLDIR, user);
157 if (lflag) {
158 int fd;
160 if ((fd= opentab(0, tabfile, 'r')) < 0) {
161 fprintf(stderr, "%s: Can't open %s: %s\n",
162 prog_name, tabfile, strerror(errno));
163 exit(1);
165 copytab(fd, tabfile, 1, "stdout");
166 close(fd);
169 if (rflag) {
170 seteuid(0);
171 if (unlink(tabfile) < 0) {
172 fprintf(stderr, "%s: Can't remove %s: %s\n",
173 prog_name, tabfile, strerror(errno));
174 exit(1);
176 seteuid(uid);
177 printf("Crontab of %s removed\n", user);
178 pflag= 1;
181 /* Initialize current Time */
182 time(&now);
184 if (cflag) {
185 int fd1, fd2;
187 if ((fd1= opentab(uid, file, 'r')) < 0) {
188 fprintf(stderr, "%s: Can't open %s: %s\n",
189 prog_name, file, strerror(errno));
190 exit(1);
193 /* Try to parse the new crontab file. If the parsing
194 * succeeds then 'crontabs' will be non-null.
196 tab_parse(file, user);
197 tab_purge();
198 if (crontabs == nil) exit(1);
200 if ((fd2= opentab(0, tabfile, 'w')) < 0) {
201 fprintf(stderr, "%s: Can't open %s: %s\n",
202 prog_name, tabfile, strerror(errno));
203 exit(1);
205 copytab(fd1, file, fd2, tabfile);
206 close(fd1);
207 close(fd2);
208 printf("New crontab for %s installed\n", user);
209 pflag= 1;
212 if (pflag) {
213 /* Alert cron to the new situation. */
214 FILE *fp;
216 seteuid(0);
217 if ((fp= fopen(PIDFILE, "r")) != NULL) {
218 unsigned long pid;
219 int c;
221 pid= 0;
222 while ((c= fgetc(fp)) != EOF && c != '\n') {
223 if ((unsigned) (c - '0') >= 10) {
224 pid= 0; break;
226 pid= 10*pid + (c - '0');
227 if (pid >= 30000) { pid= 0; break; }
229 if (pid > 1 && kill((pid_t) pid, SIGHUP) == 0) {
230 pflag= 0;
233 seteuid(uid);
234 if (pflag) {
235 fprintf(stderr,
236 "%s: Alerting cron has failed; cron still running?\n",
237 prog_name);
238 exit(1);
240 printf("Cron signalled to reload tables\n");
242 return 0;
246 * $PchId: crontab.c,v 1.4 2000/07/17 18:54:50 philip Exp $