Blame


1 e3769d22 2005-07-13 devnull #include <u.h>
2 e3769d22 2005-07-13 devnull #include <libc.h>
3 e3769d22 2005-07-13 devnull #include <ctype.h>
4 e3769d22 2005-07-13 devnull
5 e3769d22 2005-07-13 devnull #define MINUTE(x) ((long)(x)*60L)
6 e3769d22 2005-07-13 devnull #define HOUR(x) (MINUTE(x)*60L)
7 e3769d22 2005-07-13 devnull #define YEAR(x) (HOUR(x)*24L*360L)
8 e3769d22 2005-07-13 devnull
9 e3769d22 2005-07-13 devnull int verb;
10 e3769d22 2005-07-13 devnull int uflag;
11 e3769d22 2005-07-13 devnull int force;
12 e3769d22 2005-07-13 devnull int diff;
13 e3769d22 2005-07-13 devnull int diffb;
14 e3769d22 2005-07-13 devnull char* sflag;
15 e3769d22 2005-07-13 devnull char *sys;
16 e3769d22 2005-07-13 devnull
17 e3769d22 2005-07-13 devnull void ysearch(char*);
18 e3769d22 2005-07-13 devnull long starttime(char*);
19 e3769d22 2005-07-13 devnull void lastbefore(ulong, char*, char*, char*);
20 e3769d22 2005-07-13 devnull char* prtime(ulong);
21 e3769d22 2005-07-13 devnull
22 e3769d22 2005-07-13 devnull int
23 e3769d22 2005-07-13 devnull main(int argc, char *argv[])
24 e3769d22 2005-07-13 devnull {
25 e3769d22 2005-07-13 devnull int i;
26 fa325e9b 2020-01-10 cross
27 e3769d22 2005-07-13 devnull sys = sysname();
28 e3769d22 2005-07-13 devnull if(strncmp(sys, "amsterdam", 9) == 0) /* BUG */
29 e3769d22 2005-07-13 devnull sys = "am";
30 e3769d22 2005-07-13 devnull
31 e3769d22 2005-07-13 devnull ARGBEGIN {
32 e3769d22 2005-07-13 devnull default:
33 e3769d22 2005-07-13 devnull goto usage;
34 e3769d22 2005-07-13 devnull case 'v':
35 e3769d22 2005-07-13 devnull verb = 1;
36 e3769d22 2005-07-13 devnull break;
37 e3769d22 2005-07-13 devnull case 'f':
38 e3769d22 2005-07-13 devnull force = 1;
39 e3769d22 2005-07-13 devnull break;
40 e3769d22 2005-07-13 devnull case 'd':
41 e3769d22 2005-07-13 devnull diff = 1;
42 e3769d22 2005-07-13 devnull break;
43 e3769d22 2005-07-13 devnull case 'b':
44 e3769d22 2005-07-13 devnull diffb = 1;
45 e3769d22 2005-07-13 devnull break;
46 e3769d22 2005-07-13 devnull case 's':
47 e3769d22 2005-07-13 devnull sflag = ARGF();
48 e3769d22 2005-07-13 devnull break;
49 e3769d22 2005-07-13 devnull case 'u':
50 e3769d22 2005-07-13 devnull uflag = 1;
51 e3769d22 2005-07-13 devnull break;
52 e3769d22 2005-07-13 devnull } ARGEND
53 e3769d22 2005-07-13 devnull
54 e3769d22 2005-07-13 devnull if(argc == 0) {
55 e3769d22 2005-07-13 devnull usage:
56 e3769d22 2005-07-13 devnull fprint(2, "usage: hist [-bdfuv] [-s yyyymmdd] files\n");
57 e3769d22 2005-07-13 devnull exits(0);
58 e3769d22 2005-07-13 devnull }
59 e3769d22 2005-07-13 devnull
60 e3769d22 2005-07-13 devnull for(i=0; i<argc; i++)
61 e3769d22 2005-07-13 devnull ysearch(argv[i]);
62 e3769d22 2005-07-13 devnull exits(0);
63 e3769d22 2005-07-13 devnull return 0;
64 e3769d22 2005-07-13 devnull }
65 e3769d22 2005-07-13 devnull
66 e3769d22 2005-07-13 devnull int
67 e3769d22 2005-07-13 devnull strprefix(char *a, char *aa)
68 e3769d22 2005-07-13 devnull {
69 e3769d22 2005-07-13 devnull return memcmp(a, aa, strlen(a)) == 0;
70 e3769d22 2005-07-13 devnull }
71 e3769d22 2005-07-13 devnull
72 e3769d22 2005-07-13 devnull void
73 e3769d22 2005-07-13 devnull ysearch(char *file)
74 e3769d22 2005-07-13 devnull {
75 e3769d22 2005-07-13 devnull char *ndump;
76 52bba5f0 2005-07-13 devnull char fil[400], buf[500], nbuf[100], pair[2][500];
77 e3769d22 2005-07-13 devnull Tm *tm;
78 e3769d22 2005-07-13 devnull Dir *dir, *d;
79 e3769d22 2005-07-13 devnull ulong otime, dt;
80 e3769d22 2005-07-13 devnull int toggle, started, missing;
81 e3769d22 2005-07-13 devnull
82 e3769d22 2005-07-13 devnull started = 0;
83 e3769d22 2005-07-13 devnull dir = dirstat(file);
84 e3769d22 2005-07-13 devnull if(dir == nil)
85 e3769d22 2005-07-13 devnull fprint(2, "history: warning: %s does not exist\n", file);
86 e3769d22 2005-07-13 devnull else{
87 e3769d22 2005-07-13 devnull print("%s %s %lld\n", prtime(dir->mtime), file, dir->length);
88 e3769d22 2005-07-13 devnull started = 1;
89 e3769d22 2005-07-13 devnull strcpy(pair[1], file);
90 e3769d22 2005-07-13 devnull }
91 e3769d22 2005-07-13 devnull free(dir);
92 e3769d22 2005-07-13 devnull fil[0] = 0;
93 e3769d22 2005-07-13 devnull if(file[0] != '/') {
94 e3769d22 2005-07-13 devnull getwd(strchr(fil, 0), 100);
95 e3769d22 2005-07-13 devnull strcat(fil, "/");
96 e3769d22 2005-07-13 devnull }
97 e3769d22 2005-07-13 devnull strcat(fil, file);
98 e3769d22 2005-07-13 devnull cleanname(fil);
99 e3769d22 2005-07-13 devnull
100 e3769d22 2005-07-13 devnull sprint(nbuf, "/dump/%s", sys);
101 e3769d22 2005-07-13 devnull ndump = nbuf;
102 e3769d22 2005-07-13 devnull
103 e3769d22 2005-07-13 devnull tm = localtime(time(0));
104 e3769d22 2005-07-13 devnull sprint(buf, "%s/%.4d/", ndump, tm->year+1900);
105 e3769d22 2005-07-13 devnull if(access(buf, AREAD) < 0){
106 e3769d22 2005-07-13 devnull print("cannot access %s\n", buf);
107 e3769d22 2005-07-13 devnull return;
108 e3769d22 2005-07-13 devnull }
109 e3769d22 2005-07-13 devnull
110 e3769d22 2005-07-13 devnull otime = starttime(sflag);
111 e3769d22 2005-07-13 devnull toggle = 0;
112 e3769d22 2005-07-13 devnull for(;;) {
113 e3769d22 2005-07-13 devnull lastbefore(otime, fil, buf, ndump);
114 e3769d22 2005-07-13 devnull dir = dirstat(buf);
115 e3769d22 2005-07-13 devnull if(dir == nil) {
116 e3769d22 2005-07-13 devnull if(!force)
117 e3769d22 2005-07-13 devnull return;
118 e3769d22 2005-07-13 devnull dir = malloc(sizeof(Dir));
119 e3769d22 2005-07-13 devnull nulldir(dir);
120 e3769d22 2005-07-13 devnull dir->mtime = otime + 1;
121 e3769d22 2005-07-13 devnull }
122 e3769d22 2005-07-13 devnull dt = HOUR(12);
123 e3769d22 2005-07-13 devnull missing = 0;
124 e3769d22 2005-07-13 devnull while(otime <= dir->mtime){
125 e3769d22 2005-07-13 devnull if(verb)
126 e3769d22 2005-07-13 devnull print("backup %ld, %ld\n", dir->mtime, otime-dt);
127 e3769d22 2005-07-13 devnull lastbefore(otime-dt, fil, buf, ndump);
128 e3769d22 2005-07-13 devnull d = dirstat(buf);
129 e3769d22 2005-07-13 devnull if(d == nil){
130 e3769d22 2005-07-13 devnull if(!force)
131 e3769d22 2005-07-13 devnull return;
132 e3769d22 2005-07-13 devnull if(!missing)
133 e3769d22 2005-07-13 devnull print("removed %s\n", buf);
134 e3769d22 2005-07-13 devnull missing = 1;
135 e3769d22 2005-07-13 devnull }else{
136 e3769d22 2005-07-13 devnull free(dir);
137 e3769d22 2005-07-13 devnull dir = d;
138 e3769d22 2005-07-13 devnull }
139 e3769d22 2005-07-13 devnull dt += HOUR(12);
140 e3769d22 2005-07-13 devnull }
141 e3769d22 2005-07-13 devnull strcpy(pair[toggle], buf);
142 e3769d22 2005-07-13 devnull if(diff && started){
143 e3769d22 2005-07-13 devnull if(verb)
144 e3769d22 2005-07-13 devnull print("diff %s %s\n", pair[toggle^1], pair[toggle]);
145 e3769d22 2005-07-13 devnull switch(rfork(RFFDG|RFPROC)){
146 e3769d22 2005-07-13 devnull case 0:
147 a8ec4910 2005-07-13 devnull execlp("diff", "diff", diffb ? "-cb" : "-c", pair[toggle], pair[toggle ^ 1], (char*)0);
148 e3769d22 2005-07-13 devnull fprint(2, "can't exec diff: %r\n");
149 e3769d22 2005-07-13 devnull exits(0);
150 e3769d22 2005-07-13 devnull case -1:
151 e3769d22 2005-07-13 devnull fprint(2, "can't fork diff: %r\n");
152 e3769d22 2005-07-13 devnull break;
153 e3769d22 2005-07-13 devnull default:
154 e3769d22 2005-07-13 devnull while(waitpid() != -1)
155 e3769d22 2005-07-13 devnull ;
156 e3769d22 2005-07-13 devnull break;
157 e3769d22 2005-07-13 devnull }
158 e3769d22 2005-07-13 devnull }
159 e3769d22 2005-07-13 devnull print("%s %s %lld\n", prtime(dir->mtime), buf, dir->length);
160 e3769d22 2005-07-13 devnull toggle ^= 1;
161 e3769d22 2005-07-13 devnull started = 1;
162 e3769d22 2005-07-13 devnull otime = dir->mtime;
163 e3769d22 2005-07-13 devnull free(dir);
164 e3769d22 2005-07-13 devnull }
165 e3769d22 2005-07-13 devnull }
166 e3769d22 2005-07-13 devnull
167 e3769d22 2005-07-13 devnull void
168 e3769d22 2005-07-13 devnull lastbefore(ulong t, char *f, char *b, char *ndump)
169 e3769d22 2005-07-13 devnull {
170 e3769d22 2005-07-13 devnull Tm *tm;
171 e3769d22 2005-07-13 devnull Dir *dir;
172 e3769d22 2005-07-13 devnull int vers, try;
173 e3769d22 2005-07-13 devnull ulong t0, mtime;
174 e3769d22 2005-07-13 devnull
175 e3769d22 2005-07-13 devnull t0 = t;
176 e3769d22 2005-07-13 devnull if(verb)
177 e3769d22 2005-07-13 devnull print("%ld lastbefore %s\n", t0, f);
178 e3769d22 2005-07-13 devnull mtime = 0;
179 e3769d22 2005-07-13 devnull for(try=0; try<10; try++) {
180 e3769d22 2005-07-13 devnull tm = localtime(t);
181 e3769d22 2005-07-13 devnull sprint(b, "%s/%.4d/%.2d%.2d", ndump,
182 e3769d22 2005-07-13 devnull tm->year+1900, tm->mon+1, tm->mday);
183 e3769d22 2005-07-13 devnull dir = dirstat(b);
184 e3769d22 2005-07-13 devnull if(dir){
185 e3769d22 2005-07-13 devnull mtime = dir->mtime;
186 e3769d22 2005-07-13 devnull free(dir);
187 e3769d22 2005-07-13 devnull }
188 e3769d22 2005-07-13 devnull if(dir==nil || mtime > t0) {
189 e3769d22 2005-07-13 devnull if(verb)
190 e3769d22 2005-07-13 devnull print("%ld earlier %s\n", mtime, b);
191 e3769d22 2005-07-13 devnull t -= HOUR(24);
192 e3769d22 2005-07-13 devnull continue;
193 e3769d22 2005-07-13 devnull }
194 e3769d22 2005-07-13 devnull for(vers=0;; vers++) {
195 e3769d22 2005-07-13 devnull sprint(b, "%s/%.4d/%.2d%.2d%d", ndump,
196 e3769d22 2005-07-13 devnull tm->year+1900, tm->mon+1, tm->mday, vers+1);
197 e3769d22 2005-07-13 devnull dir = dirstat(b);
198 e3769d22 2005-07-13 devnull if(dir){
199 e3769d22 2005-07-13 devnull mtime = dir->mtime;
200 e3769d22 2005-07-13 devnull free(dir);
201 e3769d22 2005-07-13 devnull }
202 e3769d22 2005-07-13 devnull if(dir==nil || mtime > t0)
203 e3769d22 2005-07-13 devnull break;
204 e3769d22 2005-07-13 devnull if(verb)
205 e3769d22 2005-07-13 devnull print("%ld later %s\n", mtime, b);
206 e3769d22 2005-07-13 devnull }
207 e3769d22 2005-07-13 devnull sprint(b, "%s/%.4d/%.2d%.2d%s", ndump,
208 e3769d22 2005-07-13 devnull tm->year+1900, tm->mon+1, tm->mday, f);
209 e3769d22 2005-07-13 devnull if(vers)
210 e3769d22 2005-07-13 devnull sprint(b, "%s/%.4d/%.2d%.2d%d%s", ndump,
211 e3769d22 2005-07-13 devnull tm->year+1900, tm->mon+1, tm->mday, vers, f);
212 e3769d22 2005-07-13 devnull return;
213 e3769d22 2005-07-13 devnull }
214 e3769d22 2005-07-13 devnull strcpy(b, "XXX"); /* error */
215 e3769d22 2005-07-13 devnull }
216 e3769d22 2005-07-13 devnull
217 e3769d22 2005-07-13 devnull char*
218 e3769d22 2005-07-13 devnull prtime(ulong t)
219 e3769d22 2005-07-13 devnull {
220 e3769d22 2005-07-13 devnull static char buf[100];
221 e3769d22 2005-07-13 devnull char *b;
222 e3769d22 2005-07-13 devnull Tm *tm;
223 e3769d22 2005-07-13 devnull
224 e3769d22 2005-07-13 devnull if(uflag)
225 e3769d22 2005-07-13 devnull tm = gmtime(t);
226 e3769d22 2005-07-13 devnull else
227 e3769d22 2005-07-13 devnull tm = localtime(t);
228 e3769d22 2005-07-13 devnull b = asctime(tm);
229 e3769d22 2005-07-13 devnull memcpy(buf, b+4, 24);
230 e3769d22 2005-07-13 devnull buf[24] = 0;
231 e3769d22 2005-07-13 devnull return buf;
232 e3769d22 2005-07-13 devnull }
233 e3769d22 2005-07-13 devnull
234 e3769d22 2005-07-13 devnull long
235 e3769d22 2005-07-13 devnull starttime(char *s)
236 e3769d22 2005-07-13 devnull {
237 e3769d22 2005-07-13 devnull Tm *tm;
238 e3769d22 2005-07-13 devnull long t, dt;
239 e3769d22 2005-07-13 devnull int i, yr, mo, da;
240 e3769d22 2005-07-13 devnull
241 e3769d22 2005-07-13 devnull t = time(0);
242 e3769d22 2005-07-13 devnull if(s == 0)
243 e3769d22 2005-07-13 devnull return t;
244 e3769d22 2005-07-13 devnull for(i=0; s[i]; i++)
245 e3769d22 2005-07-13 devnull if(s[i] < '0' || s[i] > '9') {
246 e3769d22 2005-07-13 devnull fprint(2, "bad start time: %s\n", s);
247 e3769d22 2005-07-13 devnull return t;
248 e3769d22 2005-07-13 devnull }
249 e3769d22 2005-07-13 devnull if(strlen(s)==6){
250 e3769d22 2005-07-13 devnull yr = (s[0]-'0')*10 + s[1]-'0';
251 e3769d22 2005-07-13 devnull mo = (s[2]-'0')*10 + s[3]-'0' - 1;
252 e3769d22 2005-07-13 devnull da = (s[4]-'0')*10 + s[5]-'0';
253 e3769d22 2005-07-13 devnull if(yr < 70)
254 e3769d22 2005-07-13 devnull yr += 100;
255 e3769d22 2005-07-13 devnull }else if(strlen(s)==8){
256 e3769d22 2005-07-13 devnull yr = (((s[0]-'0')*10 + s[1]-'0')*10 + s[2]-'0')*10 + s[3]-'0';
257 e3769d22 2005-07-13 devnull yr -= 1900;
258 e3769d22 2005-07-13 devnull mo = (s[4]-'0')*10 + s[5]-'0' - 1;
259 e3769d22 2005-07-13 devnull da = (s[6]-'0')*10 + s[7]-'0';
260 e3769d22 2005-07-13 devnull }else{
261 e3769d22 2005-07-13 devnull fprint(2, "bad start time: %s\n", s);
262 e3769d22 2005-07-13 devnull return t;
263 e3769d22 2005-07-13 devnull }
264 e3769d22 2005-07-13 devnull t = 0;
265 e3769d22 2005-07-13 devnull dt = YEAR(10);
266 e3769d22 2005-07-13 devnull for(i=0; i<50; i++) {
267 e3769d22 2005-07-13 devnull tm = localtime(t+dt);
268 e3769d22 2005-07-13 devnull if(yr > tm->year ||
269 e3769d22 2005-07-13 devnull (yr == tm->year && mo > tm->mon) ||
270 e3769d22 2005-07-13 devnull (yr == tm->year && mo == tm->mon) && da > tm->mday) {
271 e3769d22 2005-07-13 devnull t += dt;
272 e3769d22 2005-07-13 devnull continue;
273 e3769d22 2005-07-13 devnull }
274 e3769d22 2005-07-13 devnull dt /= 2;
275 e3769d22 2005-07-13 devnull if(dt == 0)
276 e3769d22 2005-07-13 devnull break;
277 e3769d22 2005-07-13 devnull }
278 e3769d22 2005-07-13 devnull t += HOUR(12); /* .5 day to get to noon of argument */
279 e3769d22 2005-07-13 devnull return t;
280 e3769d22 2005-07-13 devnull }