1 /* crontab 1.2 - user crontab manipulation Author: Kees J. Bot
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).
28 case 'r': flags
= O_RDONLY
; break;
29 case 'w': flags
= O_WRONLY
| O_CREAT
| O_TRUNC
; break;
30 default: errno
= EINVAL
; return -1;
35 r
= open(file
, flags
, 0666);
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. */
48 while ((r
= read(fd_in
, buf
, sizeof(buf
))) > 0) {
51 if ((r
= write(fd_out
, buf
+w
, r
-w
)) <= 0) {
53 "%s: Write error on %s: %s\n",
56 r
== 0 ? "End of file"
64 fprintf(stderr
, "%s: Read error on %s: %s\n",
65 prog_name
, file_in
, strerror(errno
));
70 static void usage(void)
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
);
81 int main(int argc
, char **argv
)
84 int cflag
, lflag
, rflag
, pflag
;
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;
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;
109 if (cflag
+ lflag
+ rflag
+ pflag
!= 1) usage();
112 if (!pflag
&& i
< argc
) user
= argv
[i
++];
114 if (user
== nil
) usage();
122 if (i
!= argc
) usage();
124 if (geteuid() != 0) {
125 fprintf(stderr
, "%s: No root privileges?\n", prog_name
);
129 if ((pw
= getpwuid(uid
)) == nil
) {
131 "%s: Don't know who you (uid %lu) are!\n",
132 prog_name
, (unsigned long) uid
);
136 if ((pw
= getpwnam(user
)) == nil
) {
138 "%s: Don't know who you (%s) are!\n",
143 if (uid
!= 0 && pw
->pw_uid
!= uid
) {
145 "%s: Only root can change the crontabs of others!\n",
155 sprintf(tabfile
, "%s/%s", SPOOLDIR
, user
);
160 if ((fd
= opentab(0, tabfile
, 'r')) < 0) {
161 fprintf(stderr
, "%s: Can't open %s: %s\n",
162 prog_name
, tabfile
, strerror(errno
));
165 copytab(fd
, tabfile
, 1, "stdout");
171 if (unlink(tabfile
) < 0) {
172 fprintf(stderr
, "%s: Can't remove %s: %s\n",
173 prog_name
, tabfile
, strerror(errno
));
177 printf("Crontab of %s removed\n", user
);
181 /* Initialize current Time */
187 if ((fd1
= opentab(uid
, file
, 'r')) < 0) {
188 fprintf(stderr
, "%s: Can't open %s: %s\n",
189 prog_name
, file
, strerror(errno
));
193 /* Try to parse the new crontab file. If the parsing
194 * succeeds then 'crontabs' will be non-null.
196 tab_parse(file
, user
);
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
));
205 copytab(fd1
, file
, fd2
, tabfile
);
208 printf("New crontab for %s installed\n", user
);
213 /* Alert cron to the new situation. */
217 if ((fp
= fopen(PIDFILE
, "r")) != NULL
) {
222 while ((c
= fgetc(fp
)) != EOF
&& c
!= '\n') {
223 if ((unsigned) (c
- '0') >= 10) {
226 pid
= 10*pid
+ (c
- '0');
227 if (pid
>= 30000) { pid
= 0; break; }
229 if (pid
> 1 && kill((pid_t
) pid
, SIGHUP
) == 0) {
236 "%s: Alerting cron has failed; cron still running?\n",
240 printf("Cron signalled to reload tables\n");
246 * $PchId: crontab.c,v 1.4 2000/07/17 18:54:50 philip Exp $