Remove building with NOCRYPTO option
[minix.git] / minix / commands / at / at.c
bloba700c741c128e1b2fb335c9601e59c3a7fca0c5c
1 /* at - run a command at a specified time Author: Jan Looyen */
3 #include <sys/types.h>
4 #include <time.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <sys/stat.h>
10 #include <stdio.h>
11 #include <limits.h>
12 #include <signal.h>
13 #include <errno.h>
15 #define STARTDAY 0 /* see ctime(3) */
16 #define LEAPDAY (STARTDAY+59)
17 #define MAXDAYNR (STARTDAY+365)
18 #define NODAY (-2)
19 char CRONPID[] = "/usr/run/cron.pid";
21 int main(int argc, char **argv, char **envp);
22 int getltim(char *t);
23 int getlday(char *m, char *d);
24 int digitstring(char *s);
26 int main(int argc, char **argv, char **envp)
28 int i, c, mask, ltim, year, lday = NODAY;
29 char buf[64], job[30], pastjob[35], *dp, *sp;
30 struct tm *p;
31 time_t clk;
32 FILE *fp;
33 char pwd[PATH_MAX+1];
35 /*-------------------------------------------------------------------------*
36 * check arguments & pipe to "pwd" *
37 *-------------------------------------------------------------------------*/
38 if (argc < 2 || argc > 5) {
39 fprintf(stderr, "Usage: %s time [month day] [file]\n", argv[0]);
40 exit(1);
42 if ((ltim = getltim(argv[1])) == -1) {
43 fprintf(stderr, "%s: wrong time specification\n", argv[0]);
44 exit(1);
46 if ((argc == 4 || argc == 5) && (lday = getlday(argv[2], argv[3])) == -1) {
47 fprintf(stderr, "%s: wrong date specification\n", argv[0]);
48 exit(1);
50 if ((argc == 3 || argc == 5) && open(argv[argc - 1], O_RDONLY) == -1) {
51 fprintf(stderr, "%s: cannot find: %s\n", argv[0], argv[argc - 1]);
52 exit(1);
54 if (getcwd(pwd, sizeof(pwd)) == NULL) {
55 fprintf(stderr, "%s: cannot determine current directory: %s\n",
56 argv[0], strerror(errno));
57 exit(1);
60 /*-------------------------------------------------------------------------*
61 * determine execution time and create 'at' job file *
62 *-------------------------------------------------------------------------*/
63 time(&clk);
64 p = localtime(&clk);
65 year = p->tm_year;
66 if (lday == NODAY) { /* no [month day] given */
67 lday = p->tm_yday;
68 if (ltim <= (p->tm_hour * 100 + p->tm_min)) {
69 lday++;
70 if ((lday == MAXDAYNR && (year % 4)) || lday == MAXDAYNR + 1) {
71 lday = STARTDAY;
72 year++;
75 } else
76 switch (year % 4) {
77 case 0:
78 if (lday < p->tm_yday ||
79 (lday == p->tm_yday &&
80 ltim <= (p->tm_hour * 100 + p->tm_min))) {
81 year++;
82 if (lday > LEAPDAY) lday--;
84 break;
85 case 1:
86 case 2:
87 if (lday > LEAPDAY) lday--;
88 if (lday < p->tm_yday ||
89 (lday == p->tm_yday &&
90 ltim <= (p->tm_hour * 100 + p->tm_min)))
91 year++;
92 break;
93 case 3:
94 if (lday < ((lday > LEAPDAY) ? p->tm_yday + 1 : p->tm_yday) ||
95 (lday ==((lday > LEAPDAY) ? p->tm_yday + 1 : p->tm_yday) &&
96 ltim <= (p->tm_hour * 100 + p->tm_min)))
97 year++;
98 else if (lday > LEAPDAY)
99 lday--;
100 break;
102 sprintf(job, "/usr/spool/at/%02d.%03d.%04d.%02d",
103 year % 100, lday, ltim, getpid() % 100);
104 sprintf(pastjob, "/usr/spool/at/past/%02d.%03d.%04d.%02d",
105 year % 100, lday, ltim, getpid() % 100);
106 mask= umask(0077);
107 if ((fp = fopen(pastjob, "w")) == NULL) {
108 fprintf(stderr, "%s: cannot create %s: %s\n",
109 argv[0], pastjob, strerror(errno));
110 exit(1);
113 /*-------------------------------------------------------------------------*
114 * write environment and command(s) to 'at'job file *
115 *-------------------------------------------------------------------------*/
116 i = 0;
117 while ((sp= envp[i++]) != NULL) {
118 dp = buf;
119 while ((c= *sp++) != '\0' && c != '=' && dp < buf+sizeof(buf)-1)
120 *dp++ = c;
121 if (c != '=') continue;
122 *dp = '\0';
123 fprintf(fp, "%s='", buf);
124 while (*sp != 0) {
125 if (*sp == '\'')
126 fprintf(fp, "'\\''");
127 else
128 fputc(*sp, fp);
129 sp++;
131 fprintf(fp, "'; export %s\n", buf);
133 fprintf(fp, "cd '%s'\n", pwd);
134 fprintf(fp, "umask %o\n", mask);
135 if (argc == 3 || argc == 5)
136 fprintf(fp, "%s\n", argv[argc - 1]);
137 else /* read from stdinput */
138 while ((c = getchar()) != EOF) putc(c, fp);
139 fclose(fp);
141 if (chown(pastjob, getuid(), getgid()) == -1) {
142 fprintf(stderr, "%s: cannot set ownership of %s: %s\n",
143 argv[0], pastjob, strerror(errno));
144 unlink(pastjob);
145 exit(1);
147 /* "Arm" the job. */
148 if (rename(pastjob, job) == -1) {
149 fprintf(stderr, "%s: cannot move %s to %s: %s\n",
150 argv[0], pastjob, job, strerror(errno));
151 unlink(pastjob);
152 exit(1);
154 printf("%s: %s created\n", argv[0], job);
156 /* Alert cron to the new situation. */
157 if ((fp= fopen(CRONPID, "r")) != NULL) {
158 unsigned long pid;
160 pid= 0;
161 while ((c= fgetc(fp)) != EOF && c != '\n') {
162 if ((unsigned) (c - '0') >= 10) { pid= 0; break; }
163 pid= 10*pid + (c - '0');
164 if (pid >= 30000) { pid= 0; break; }
166 if (pid > 1) kill((pid_t) pid, SIGHUP);
168 return(0);
171 /*-------------------------------------------------------------------------*
172 * getltim() return((time OK) ? daytime : -1) *
173 *-------------------------------------------------------------------------*/
174 int getltim(char *t)
176 if (t[4] == '\0' && t[3] >= '0' && t[3] <= '9' &&
177 t[2] >= '0' && t[2] <= '5' && t[1] >= '0' && t[1] <= '9' &&
178 (t[0] == '0' || t[0] == '1' || (t[1] <= '3' && t[0] == '2')))
179 return(atoi(t));
180 else
181 return(-1);
184 /*-------------------------------------------------------------------------*
185 * getlday() return ((date OK) ? yearday : -1) *
186 *-------------------------------------------------------------------------*/
187 int getlday(char *m, char *d)
189 int i, day, im;
190 static int cumday[] = {0, 0, 31, 60, 91, 121, 152,
191 182, 213, 244, 274, 305, 335};
192 static struct date {
193 char *mon;
194 int dcnt;
195 } *pc, kal[] = {
196 { "Jan", 31 }, { "Feb", 29 }, { "Mar", 31 }, { "Apr", 30 },
197 { "May", 31 }, { "Jun", 30 }, { "Jul", 31 }, { "Aug", 31 },
198 { "Sep", 30 }, { "Oct", 31 }, { "Nov", 30 }, { "Dec", 31 },
201 pc = kal;
202 im = (digitstring(m)) ? atoi(m) : 0;
203 m[0] &= 0337;
204 for (i = 1; i < 13 && strcmp(m, pc->mon) && im != i; i++, pc++);
205 if (i < 13 && (day = (digitstring(d)) ? atoi(d) : 0) && day <= pc->dcnt) {
206 if (!STARTDAY) day--;
207 return(day + cumday[i]);
208 } else
209 return(-1);
214 int digitstring(char *s)
216 while (*s >= '0' && *s <= '9') s++;
217 return((*s == '\0') ? 1 : 0);