123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * generate a list of files and their metadata
- * using a given proto file.
- */
- #include "all.h"
- int changesonly;
- char *uid;
- Db *db;
- Biobuf blog;
- ulong now;
- int n;
- char **x;
- int nx;
- int justlog;
- char *root=".";
- char **match;
- int nmatch;
- int
- ismatch(char *s)
- {
- int i, len;
- if(nmatch == 0)
- return 1;
- for(i=0; i<nmatch; i++){
- if(strcmp(s, match[i]) == 0)
- return 1;
- len = strlen(match[i]);
- if(strncmp(s, match[i], len) == 0 && s[len]=='/')
- return 1;
- }
- return 0;
- }
- void
- xlog(int c, char *name, Dir *d)
- {
- char *dname;
- dname = d->name;
- if(strcmp(dname, name) == 0)
- dname = "-";
- if(!justlog)
- Bprint(&blog, "%lud %d ", now, n++);
- Bprint(&blog, "%c %q %q %luo %q %q %lud %lld\n",
- c, name, dname, d->mode, uid ? uid : d->uid, d->gid, d->mtime, d->length);
- }
- void
- walk(char *new, char *old, Dir *xd, void*)
- {
- int i, change, len;
- Dir od, d;
- new = unroot(new, "/");
- old = unroot(old, root);
- if(!ismatch(new))
- return;
- for(i=0; i<nx; i++){
- if(strcmp(new, x[i]) == 0)
- return;
- len = strlen(x[i]);
- if(strncmp(new, x[i], len)==0 && new[len]=='/')
- return;
- }
- d = *xd;
- d.name = old;
- memset(&od, 0, sizeof od);
- change = 0;
- if(markdb(db, new, &od) < 0){
- if(!changesonly){
- xlog('a', new, &d);
- change = 1;
- }
- }else{
- if((d.mode&DMDIR)==0 && (od.mtime!=d.mtime || od.length!=d.length)){
- xlog('c', new, &d);
- change = 1;
- }
- if((!uid&&strcmp(od.uid,d.uid)!=0)
- || strcmp(od.gid,d.gid)!=0
- || od.mode!=d.mode){
- xlog('m', new, &d);
- change = 1;
- }
- }
- if(!justlog && change){
- if(uid)
- d.uid = uid;
- d.muid = "mark"; /* mark bit */
- insertdb(db, new, &d);
- }
- }
- void
- usage(void)
- {
- fprint(2, "usage: replica/updatedb [-c] [-p proto] [-r root] [-t now n] [-u uid] [-x path]... db [paths]\n");
- exits("usage");
- }
- void
- main(int argc, char **argv)
- {
- char *proto;
- Avlwalk *w;
- Dir d;
- Entry *e;
- quotefmtinstall();
- proto = "/sys/lib/sysconfig/proto/allproto";
- now = time(0);
- Binit(&blog, 1, OWRITE);
- ARGBEGIN{
- case 'c':
- changesonly = 1;
- break;
- case 'l':
- justlog = 1;
- break;
- case 'p':
- proto = EARGF(usage());
- break;
- case 'r':
- root = EARGF(usage());
- break;
- case 't':
- now = strtoul(EARGF(usage()), 0, 0);
- n = atoi(EARGF(usage()));
- break;
- case 'u':
- uid = EARGF(usage());
- break;
- case 'x':
- if(nx%16 == 0)
- x = erealloc(x, (nx+16)*sizeof(x[0]));
- x[nx++] = EARGF(usage());
- break;
- default:
- usage();
- }ARGEND
- if(argc <1)
- usage();
- match = argv+1;
- nmatch = argc-1;
- db = opendb(argv[0]);
- if(rdproto(proto, root, walk, nil, nil) < 0)
- sysfatal("rdproto: %r");
- if(!changesonly){
- w = avlwalk(db->avl);
- while(e = (Entry*)avlprev(w)){
- if(!ismatch(e->name))
- continue;
- if(!e->d.mark){ /* not visited during walk */
- memset(&d, 0, sizeof d);
- d.name = e->d.name;
- d.uid = e->d.uid;
- d.gid = e->d.gid;
- d.mtime = e->d.mtime;
- d.mode = e->d.mode;
- xlog('d', e->name, &d);
- if(!justlog)
- removedb(db, e->name);
- }
- }
- }
- if(Bterm(&blog) < 0)
- sysfatal("writing output: %r");
- exits(nil);
- }
|