source: trunk/minix/commands/simple/at.c@ 15

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

Minix 3.1.2a

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