source: trunk/minix/commands/cron/crontab.c@ 12

Last change on this file since 12 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 5.4 KB
RevLine 
[9]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"
18
19#if __minix && !__minix_vmd
20#define seteuid(uid) ((uid),0) /* Minix can't fiddle with uids. */
21#endif
22
23static int opentab(int uid, char *file, int how)
24/* Open a crontab file under the given uid. How is 'r' or 'w'. Return
25 * the result of open(2).
26 */
27{
28 uid_t safe_uid;
29 int flags, r, err;
30
31 switch (how) {
32 case 'r': flags= O_RDONLY; break;
33 case 'w': flags= O_WRONLY | O_CREAT | O_TRUNC; break;
34 default: errno= EINVAL; return -1;
35 }
36
37#if __minix && !__minix_vmd
38 /* Standard Minix has no saved uid, so use the lousy old access(). */
39 if (uid != 0) {
40 if (access(file, how == 'r' ? R_OK : W_OK) < 0) return -1;
41 }
42#endif
43
44 safe_uid= geteuid();
45 seteuid(uid);
46 r= open(file, flags, 0666);
47 err= errno;
48 seteuid(safe_uid);
49 errno= err;
50 return r;
51}
52
53static void copytab(int fd_in, char *file_in, int fd_out, char *file_out)
54/* Copy one open file to another. Complain and exit on errors. */
55{
56 ssize_t r, w;
57 char buf[1024];
58
59 while ((r= read(fd_in, buf, sizeof(buf))) > 0) {
60 w= 0;
61 while (w < r) {
62 if ((r= write(fd_out, buf+w, r-w)) <= 0) {
63 fprintf(stderr,
64 "%s: Write error on %s: %s\n",
65 prog_name,
66 file_out,
67 r == 0 ? "End of file"
68 : strerror(errno));
69 exit(1);
70 }
71 w+= r;
72 }
73 }
74 if (r < 0) {
75 fprintf(stderr, "%s: Read error on %s: %s\n",
76 prog_name, file_in, strerror(errno));
77 exit(1);
78 }
79}
80
81static void usage(void)
82{
83 fprintf(stderr,
84 "Usage: %s -c [user] file # Change crontab\n"
85 " %s -l [user] # List crontab\n"
86 " %s -r [user] # Remove crontab\n"
87 " %s -p # Tell cron to reload\n",
88 prog_name, prog_name, prog_name, prog_name);
89 exit(1);
90}
91
92int main(int argc, char **argv)
93{
94 int i;
95 int cflag, lflag, rflag, pflag;
96 uid_t uid;
97 char *user, *file;
98 struct passwd *pw;
99 static char SPOOLDIR[]= "/usr/spool/crontabs";
100 char tabfile[sizeof(SPOOLDIR) + NAME_MAX];
101
102 prog_name= strrchr(argv[0], '/');
103 if (prog_name == nil) prog_name= argv[0]; else prog_name++;
104
105 cflag= lflag= rflag= pflag= 0;
106 i= 1;
107 while (i < argc && argv[i][0] == '-') {
108 char *opt= argv[i++] + 1;
109
110 if (opt[0] == '-' && opt[1] == 0) break; /* -- */
111
112 while (*opt != 0) switch (*opt++) {
113 case 'c': cflag= 1; break;
114 case 'l': lflag= 1; break;
115 case 'r': rflag= 1; break;
116 case 'p': pflag= 1; break;
117 default: usage();
118 }
119 }
120 if (cflag + lflag + rflag + pflag != 1) usage();
121
122 user= file= nil;
123 if (!pflag && i < argc) user= argv[i++];
124 if (cflag) {
125 if (user == nil) usage();
126 if (i < argc) {
127 file= argv[i++];
128 } else {
129 file= user;
130 user= nil;
131 }
132 }
133 if (i != argc) usage();
134
135 if (geteuid() != 0) {
136 fprintf(stderr, "%s: No root privileges?\n", prog_name);
137 }
138 uid= getuid();
139 if (user == nil) {
140 if ((pw= getpwuid(uid)) == nil) {
141 fprintf(stderr,
142 "%s: Don't know who you (uid %lu) are!\n",
143 prog_name, (unsigned long) uid);
144 exit(1);
145 }
146 } else {
147 if ((pw= getpwnam(user)) == nil) {
148 fprintf(stderr,
149 "%s: Don't know who you (%s) are!\n",
150 prog_name, user);
151 exit(1);
152 }
153 }
154 if (uid != 0 && pw->pw_uid != uid) {
155 fprintf(stderr,
156 "%s: Only root can change the crontabs of others!\n",
157 prog_name);
158 exit(1);
159 }
160 user= pw->pw_name;
161 uid= pw->pw_uid;
162 seteuid(uid);
163 umask(0077);
164
165 selectlog(STDERR);
166 sprintf(tabfile, "%s/%s", SPOOLDIR, user);
167
168 if (lflag) {
169 int fd;
170
171 if ((fd= opentab(0, tabfile, 'r')) < 0) {
172 fprintf(stderr, "%s: Can't open %s: %s\n",
173 prog_name, tabfile, strerror(errno));
174 exit(1);
175 }
176 copytab(fd, tabfile, 1, "stdout");
177 close(fd);
178 }
179
180 if (rflag) {
181 seteuid(0);
182 if (unlink(tabfile) < 0) {
183 fprintf(stderr, "%s: Can't remove %s: %s\n",
184 prog_name, tabfile, strerror(errno));
185 exit(1);
186 }
187 seteuid(uid);
188 printf("Crontab of %s removed\n", user);
189 pflag= 1;
190 }
191
192 /* Initialize current Time */
193 time(&now);
194
195 if (cflag) {
196 int fd1, fd2;
197
198 if ((fd1= opentab(uid, file, 'r')) < 0) {
199 fprintf(stderr, "%s: Can't open %s: %s\n",
200 prog_name, file, strerror(errno));
201 exit(1);
202 }
203
204 /* Try to parse the new crontab file. If the parsing
205 * succeeds then 'crontabs' will be non-null.
206 */
207 tab_parse(file, user);
208 tab_purge();
209 if (crontabs == nil) exit(1);
210
211 if ((fd2= opentab(0, tabfile, 'w')) < 0) {
212 fprintf(stderr, "%s: Can't open %s: %s\n",
213 prog_name, tabfile, strerror(errno));
214 exit(1);
215 }
216 copytab(fd1, file, fd2, tabfile);
217 close(fd1);
218 close(fd2);
219 printf("New crontab for %s installed\n", user);
220 pflag= 1;
221 }
222
223 if (pflag) {
224 /* Alert cron to the new situation. */
225 FILE *fp;
226
227 seteuid(0);
228 if ((fp= fopen(PIDFILE, "r")) != NULL) {
229 unsigned long pid;
230 int c;
231
232 pid= 0;
233 while ((c= fgetc(fp)) != EOF && c != '\n') {
234 if ((unsigned) (c - '0') >= 10) {
235 pid= 0; break;
236 }
237 pid= 10*pid + (c - '0');
238 if (pid >= 30000) { pid= 0; break; }
239 }
240 if (pid > 1 && kill((pid_t) pid, SIGHUP) == 0) {
241 pflag= 0;
242 }
243 }
244 seteuid(uid);
245 if (pflag) {
246 fprintf(stderr,
247 "%s: Alerting cron has failed; cron still running?\n",
248 prog_name);
249 exit(1);
250 }
251 printf("Cron signalled to reload tables\n");
252 }
253 return 0;
254}
255
256/*
257 * $PchId: crontab.c,v 1.4 2000/07/17 18:54:50 philip Exp $
258 */
Note: See TracBrowser for help on using the repository browser.