This source file includes following definitions.
- open_tsfile
- lock_file
- consider_job
- unlock
- update_timestamp
- fake_job
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <unistd.h>
34 #include <errno.h>
35 #include <signal.h>
36 #include "global.h"
37 #include "gregor.h"
38
39 static void
40 open_tsfile(job_rec *jr)
41
42 {
43 jr->timestamp_fd = open(jr->ident, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
44 if (jr->timestamp_fd == -1)
45 die_e("Can't open timestamp file for job %s", jr->ident);
46 fcntl(jr->timestamp_fd, F_SETFD, 1);
47
48
49 if (fchown(jr->timestamp_fd, getuid(), getgid()))
50 die_e("Can't chown timestamp file %s", jr->ident);
51 if (fchmod(jr->timestamp_fd, S_IRUSR | S_IWUSR))
52 die_e("Can't chmod timestamp file %s", jr->ident);
53 }
54
55 static int
56 lock_file(int fd)
57
58
59
60 {
61 int r;
62 struct flock sfl;
63
64 sfl.l_type = F_WRLCK;
65 sfl.l_start = 0;
66 sfl.l_whence = SEEK_SET;
67 sfl.l_len = 0;
68 errno = 0;
69 r = fcntl(fd, F_SETLK, &sfl);
70 if (r != -1) return 1;
71 if (errno != EACCES && errno != EAGAIN)
72 die_e("fcntl() error");
73 return 0;
74 }
75
76 int
77 consider_job(job_rec *jr)
78
79
80
81 {
82 char timestamp[9];
83 int ts_year, ts_month, ts_day, dn;
84 ssize_t b;
85
86 open_tsfile(jr);
87
88
89 b = read(jr->timestamp_fd, timestamp, 8);
90 if (b == -1) die_e("Error reading timestamp file %s", jr->ident);
91 timestamp[8] = 0;
92
93
94 if (!force && b == 8)
95 {
96 int day_delta;
97 time_t jobtime;
98 struct tm *t;
99
100 if (sscanf(timestamp, "%4d%2d%2d", &ts_year, &ts_month, &ts_day) == 3)
101 dn = day_num(ts_year, ts_month, ts_day);
102 else
103 dn = 0;
104
105 day_delta = day_now - dn;
106
107
108
109
110
111
112 if (day_delta >= 0 && day_delta < jr->period)
113 {
114
115 xclose(jr->timestamp_fd);
116 return 0;
117 }
118
119
120
121
122
123 if (jr->named_period)
124 {
125 int period = 0, bypass = 0;
126 switch (jr->named_period)
127 {
128 case 1:
129 period = days_last_month ();
130 bypass = days_this_month ();
131 break;
132 case 2:
133 period = days_last_year ();
134 bypass = days_this_year ();
135 break;
136 case 3:
137 period = 1;
138 bypass = 1;
139 break;
140 case 4:
141 period = 7;
142 bypass = 7;
143 break;
144 default:
145 die ("Unknown named period for %s (%d)", jr->ident, jr->named_period);
146 }
147 printf ("Checking against %d with %d\n", day_delta, period);
148 if (day_delta < period && day_delta != bypass)
149 {
150
151 xclose (jr->timestamp_fd);
152 return 0;
153 }
154 }
155
156 jobtime = start_sec + jr->delay * 60;
157
158 t = localtime(&jobtime);
159 if (!now && preferred_hour != -1 && t->tm_hour != preferred_hour) {
160 Debug(("The job's %s preferred hour %d was missed, skipping the job.", jr->ident, preferred_hour));
161 xclose (jr->timestamp_fd);
162 return 0;
163 }
164
165 if (!now && range_start != -1 && range_stop != -1 &&
166 (t->tm_hour < range_start || t->tm_hour >= range_stop))
167 {
168 Debug(("The job `%s' falls out of the %02d:00-%02d:00 hours range, skipping.",
169 jr->ident, range_start, range_stop));
170 xclose (jr->timestamp_fd);
171 return 0;
172 }
173 }
174
175
176 if (lock_file(jr->timestamp_fd)) return 1;
177
178
179 xclose(jr->timestamp_fd);
180 explain("Job `%s' locked by another anacron - skipping", jr->ident);
181 return 0;
182 }
183
184 void
185 unlock(job_rec *jr)
186 {
187 xclose(jr->timestamp_fd);
188 }
189
190 void
191 update_timestamp(job_rec *jr)
192
193
194
195
196
197
198 {
199 char stamp[10];
200
201 snprintf(stamp, 10, "%04d%02d%02d\n", year, month, day_of_month);
202 if (lseek(jr->timestamp_fd, 0, SEEK_SET))
203 die_e("Can't lseek timestamp file for job %s", jr->ident);
204 if (write(jr->timestamp_fd, stamp, 9) != 9)
205 die_e("Can't write timestamp file for job %s", jr->ident);
206 if (ftruncate(jr->timestamp_fd, 9))
207 die_e("ftruncate error");
208 }
209
210 void
211 fake_job(job_rec *jr)
212
213 {
214 open_tsfile(jr);
215 update_timestamp(jr);
216 xclose(jr->timestamp_fd);
217 }