2 * generate a list of files and their metadata
3 * using a given proto file.
27 for(i=0; i<nmatch; i++){
28 if(strcmp(s, match[i]) == 0)
30 len = strlen(match[i]);
31 if(strncmp(s, match[i], len) == 0 && s[len]=='/')
38 xlog(int c, char *name, Dir *d)
43 if(strcmp(dname, name) == 0)
46 Bprint(&blog, "%lud %d ", now, n++);
47 Bprint(&blog, "%c %q %q %luo %q %q %lud %lld\n",
48 c, name, dname, d->mode, uid ? uid : d->uid, d->gid, d->mtime, d->length);
52 walk(char *new, char *old, Dir *xd, void*)
57 new = unroot(new, "/");
58 old = unroot(old, root);
63 if(strcmp(new, x[i]) == 0)
66 if(strncmp(new, x[i], len)==0 && new[len]=='/')
72 memset(&od, 0, sizeof od);
74 if(markdb(db, new, &od) < 0){
80 if((d.mode&DMDIR)==0 && (od.mtime!=d.mtime || od.length!=d.length)){
84 if((!uid&&strcmp(od.uid,d.uid)!=0)
85 || strcmp(od.gid,d.gid)!=0
91 if(!justlog && change){
94 d.muid = "mark"; /* mark bit */
95 insertdb(db, new, &d);
100 warn(char *msg, void*)
104 fprint(2, "warning: %s\n", msg);
106 /* find the %r in "can't open foo: %r" */
107 p = strstr(msg, ": ");
112 * if the error is about a remote server failing,
113 * then there's no point in continuing to look
114 * for changes -- we'll think everything got deleted!
116 * actual errors i see are:
117 * "i/o on hungup channel" for a local hangup
118 * "i/o on hungup channel" for a timeout (yank the network wire)
119 * "'/n/sources/plan9' Hangup" for a remote hangup
120 * the rest is paranoia.
123 if(cistrstr(p, "hungup") || cistrstr(p, "Hangup")
124 || cistrstr(p, "rpc error")
125 || cistrstr(p, "shut down")
126 || cistrstr(p, "i/o")
127 || cistrstr(p, "connection"))
128 sysfatal("suspected network or i/o error - bailing out");
135 fprint(2, "usage: replica/updatedb [-c] [-p proto] [-r root] [-t now n] [-u uid] [-x path]... db [paths]\n");
140 main(int argc, char **argv)
147 proto = "/sys/lib/sysconfig/proto/allproto";
149 Binit(&blog, 1, OWRITE);
158 proto = EARGF(usage());
161 root = EARGF(usage());
164 now = strtoul(EARGF(usage()), 0, 0);
165 n = atoi(EARGF(usage()));
168 uid = EARGF(usage());
172 x = erealloc(x, (nx+16)*sizeof(x[0]));
173 x[nx++] = EARGF(usage());
185 db = opendb(argv[0]);
186 if(rdproto(proto, root, walk, warn, nil) < 0)
187 sysfatal("rdproto: %r");
190 for(e = (Entry*)avlmax(db->avl); e != nil; e = (Entry*)avlprev(e)){
191 if(!ismatch(e->name))
193 if(!e->d.mark){ /* not visited during walk */
194 memset(&d, 0, sizeof d);
198 d.mtime = e->d.mtime;
200 xlog('d', e->name, &d);
202 removedb(db, e->name);
208 sysfatal("writing output: %r");