static int /* boolean */ confirm(File *src, File *dest) { int absent, n, tty = eopen(TTY, 2); char c, junk; Dir *stp; if ((stp = dirstat(src->name)) == nil) sysfatal("no input file %s: %r", src->name); free(stp); stp = dirstat(dest->name); absent = (stp == nil); free(stp); fprint(2, "%s: copy %s to %s%s? ", argv0, src->name, dest->name, (absent? " (missing)": "")); n = read(tty, &c, 1); junk = c; if (n < 1) c = 'n'; while (n > 0 && junk != '\n') n = read(tty, &junk, 1); close(tty); if (isascii(c) && isupper(c)) c = tolower(c); return c == 'y'; }
void main(int argc, char **argv) { int fd, ofd; char diffout[40], idiffout[40]; Biobuf *b1, *b2, bdiff, bout, bstdout; Dir *d; ARGBEGIN{ default: usage(); case 'b': diffbflag++; break; case 'w': diffwflag++; break; }ARGEND if(argc != 2) usage(); if((d = dirstat(argv[0])) == nil) sysfatal("stat %s: %r", argv[0]); if(d->mode&DMDIR) sysfatal("%s is a directory", argv[0]); free(d); if((d = dirstat(argv[1])) == nil) sysfatal("stat %s: %r", argv[1]); if(d->mode&DMDIR) sysfatal("%s is a directory", argv[1]); free(d); if((b1 = Bopen(argv[0], OREAD)) == nil) sysfatal("open %s: %r", argv[0]); if((b2 = Bopen(argv[1], OREAD)) == nil) sysfatal("open %s: %r", argv[1]); strcpy(diffout, "/tmp/idiff.XXXXXX"); fd = opentemp(diffout, ORDWR|ORCLOSE, 0); strcpy(idiffout, "/tmp/idiff.XXXXXX"); ofd = opentemp(idiffout, ORDWR|ORCLOSE, 0); rundiff(argv[0], argv[1], fd); seek(fd, 0, 0); Binit(&bdiff, fd, OREAD); Binit(&bout, ofd, OWRITE); idiff(b1, argv[0], b2, argv[1], &bdiff, diffout, &bout, idiffout); Bterm(&bdiff); Bflush(&bout); seek(ofd, 0, 0); Binit(&bout, ofd, OREAD); Binit(&bstdout, 1, OWRITE); copy(&bout, idiffout, &bstdout, "<stdout>"); exits(nil); }
void mkdir(char *name, uint32_t mode, uint32_t mtime, char *uid, char *gid) { Dir *d, xd; int fd; char *p; char olderr[256]; fd = create(name, OREAD, mode); if(fd < 0){ rerrstr(olderr, sizeof(olderr)); if((d = dirstat(name)) == nil || !(d->mode & DMDIR)){ free(d); warn("can't make directory %q, mode %luo: %s", name, mode, olderr); return; } free(d); } close(fd); d = &xd; nulldir(d); p = utfrrune(name, L'/'); if(p) p++; else p = name; d->name = p; if(uflag){ d->uid = uid; d->gid = gid; } if(Tflag) d->mtime = mtime; d->mode = mode; if(dirwstat(name, d) < 0) warn("can't set modes for %q: %r", name); if(uflag||Tflag){ if((d = dirstat(name)) == nil){ warn("can't reread modes for %q: %r", name); return; } if(Tflag && d->mtime != mtime) warn("%q: time mismatch %lu %lu\n", name, mtime, d->mtime); if(uflag && strcmp(uid, d->uid)) warn("%q: uid mismatch %q %q", name, uid, d->uid); if(uflag && strcmp(gid, d->gid)) warn("%q: gid mismatch %q %q", name, gid, d->gid); } }
void main(int argc, char *argv[]) { int i, failed; Dir *dirto, *dirfrom; char *todir, *toelem; if(argc<3){ fprint(2, "usage: mv fromfile tofile\n"); fprint(2, " mv fromfile ... todir\n"); exits("bad usage"); } /* Skip -f */ if(argv[1][0] == '-' && argv[1][1] == 'f' && argv[1][2] == 0) { for(i=2; i<argc; i++) { argv[i-1] = argv[i]; } argc--; } /* prepass to canonicalise names before splitting, etc. */ for(i=1; i < argc; i++) cleanname(argv[i]); if((dirto = dirstat(argv[argc-1])) != nil && (dirto->mode&DMDIR)){ dirfrom = nil; if(argc == 3 && (dirfrom = dirstat(argv[1])) != nil && (dirfrom->mode & DMDIR)) split(argv[argc-1], &todir, &toelem); /* mv dir1 dir2 */ else{ /* mv file... dir */ todir = argv[argc-1]; toelem = nil; /* toelem will be fromelem */ } free(dirfrom); }else split(argv[argc-1], &todir, &toelem); /* mv file1 file2 */ free(dirto); if(argc>3 && toelem != nil){ fprint(2, "mv: %s not a directory\n", argv[argc-1]); exits("bad usage"); } failed = 0; for(i=1; i < argc-1; i++) if(mv(argv[i], todir, toelem) < 0) failed++; if(failed) exits("failure"); exits(0); }
void readalljobs(void) { User *u; Dir *d, *du; char file[128]; int i, n, fd; fd = open("/cron", OREAD); if(fd < 0) fatal("can't open /cron: %r"); while((n = dirread(fd, &d)) > 0){ for(i = 0; i < n; i++){ if(strcmp(d[i].name, "log") == 0 || !(d[i].qid.type & QTDIR)) continue; if(strcmp(d[i].name, d[i].uid) != 0){ syslog(1, CRONLOG, "cron for %s owned by %s", d[i].name, d[i].uid); continue; } u = newuser(d[i].name); snprint(file, sizeof file, "/cron/%s/cron", d[i].name); du = dirstat(file); if(du == nil || qidcmp(u->lastqid, du->qid) != 0){ freejobs(u->jobs); u->jobs = readjobs(file, u); } free(du); } free(d); } close(fd); }
static Dir* xdirstat0(char **path, int (*namecmp)(char *, char *), char *err) { char *base, *name; Dir *d, *t; int n, i; if(d = dirstat(*path)) return d; if(!splitpath(*path, &base, &name)) return nil; if((n = xdirread0(&base, namecmp, &t)) < 0) goto out; for(i=0; i<n; i++){ if(namecmp(t[i].name, name)) continue; free(*path); *path = conspath(base, t[i].name); d = xdirdup(&t[i], 1); goto out; } werrstr("%s", err); out: free(base); free(name); return d; }
void main(int argc, char *argv[]) { int i; int recurse; char *f; Dir *db; ignerr = 0; recurse = 0; ARGBEGIN{ case 'r': recurse = 1; break; case 'f': ignerr = 1; break; default: fprint(2, "usage: rm [-fr] file ...\n"); exits("usage"); }ARGEND for(i=0; i<argc; i++){ f = argv[i]; if(remove(f) != -1) continue; if((db = dirstat(f)) == nil || (db->qid.type&QTDIR) ==0) err(f); else if(RemoveDirectory(f) == 0) if(recurse) Ntrmdir(f); else err(f); } exits(errbuf); }
void corefile(char *name, int explicit) { Fhdr *hdr; char t[100]; Dir *d; if((d = dirstat(name)) == nil){ if(explicit) fprint(2, "%s; %r\n", name); return; } strcpy(t, ctime(d->mtime)); t[strlen(t)-1] = 0; /* newline */ if((hdr = crackhdr(name, OREAD)) == nil){ if(explicit) fprint(2, "%s: %r\n", name); return; } if(hdr->ftype != FCORE){ uncrackhdr(hdr); if(explicit) fprint(2, "%s: not a core file\n", name); return; }
void coreall(char *name) { Dir *d; int fd, i, n; char *p; if((d = dirstat(name)) == nil){ fprint(2, "%s: %r\n", name); return; } if((d->mode&DMDIR) == 0){ free(d); corefile(name, 1); return; } free(d); if((fd = open(name, OREAD)) < 0){ fprint(2, "open %s: %r\n", name); return; } n = dirreadall(fd, &d); qsort(d, n, sizeof(d[0]), timecmp); for(i=0; i<n; i++){ p = smprint("%s/%s", name, d[i].name); if(p == nil) sysfatal("out of memory"); corefile(p, 0); free(p); } }
static int openlock(char *lock) { int lckfd; Dir *dir; /* first ensure that the lock file has the lock bit set */ dir = dirstat(lock); if (dir == nil) sysfatal("can't stat %s: %r", lock); if (!(dir->mode & DMEXCL)) { dir->mode |= DMEXCL; dir->qid.type |= QTEXCL; if (dirwstat(lock, dir) < 0) sysfatal("can't make %s exclusive access: %r", lock); } free(dir); if (lockwait) while ((lckfd = open(lock, ORDWR)) < 0) sleep(1000); else lckfd = open(lock, ORDWR); if (lckfd < 0) sysfatal("can't open %s read/write: %r", lock); return lckfd; }
void dirtime(char *dir, char *path) { Dir d; void *t; char buf[8192]; HANDLE handle; WIN32_FIND_DATA wfd; snprint(buf, sizeof(buf), "%s/*.*", dir); handle = FindFirstFile(buf, &wfd); if(handle == INVALID_HANDLE_VALUE) return; do { sprint(buf, "%s%s", path, wfd.cFileName); if(dirstat(buf, &d) < 0) continue; t = (void *)d.mtime; if (!t) /* zero mode file */ continue; if(symlook(buf, S_TIME, 0)) continue; symlook(strdup9(buf), S_TIME, t)->value = t; } while(FindNextFile(handle, &wfd) == TRUE); FindClose(handle); }
int access(char *name, int mode) { int fd; Dir *db; static char omode[] = { 0, OEXEC, OWRITE, ORDWR, OREAD, OEXEC, /* only approximate */ ORDWR, ORDWR /* only approximate */ }; if(mode == AEXIST){ db = dirstat(name); free(db); if(db != nil) return 0; return -1; } fd = open(name, omode[mode&7]); if(fd >= 0){ close(fd); return 0; } return -1; }
void removeall(char *p) { int fd, n, i; Dir *d; char *q; if(remove(p) >= 0) return; if((d = dirstat(p)) == nil) return; if(!(d->mode & DMDIR)) { free(d); return; } free(d); if((fd = open(p, OREAD)) < 0) return; n = dirreadall(fd, &d); close(fd); for(i=0; i<n; i++) { q = smprint("%s/%s", p, d[i].name); removeall(q); free(q); } free(d); }
/* * Depends on d.qid.vers being highest numbered message in dir. */ void acmetimer(Article *m, Window *w) { Biobuf *b; Dir *d; assert(m==nil && w==root); if((d = dirstat(dir))==nil | hi==d->qid.vers){ free(d); return; } if(w->data < 0) w->data = winopenfile(w, "data"); if(winsetaddr(w, "0", 0)) write(w->data, "", 0); b = emalloc(sizeof(*b)); Binit(b, w->data, OWRITE); adddir(b, d->qid.vers, hi+1, d->qid.vers); hi = d->qid.vers; Bterm(b); free(b); free(d); winselect(w, "0,.", 0); }
char* getPath(char* command) // Search for `command` on the different directories specified on the path and // return the executable full path. // If command is not found, it returns the last processed full path { char* env = getenv(ENV_PATH); char* array[10]; int numTokens = gettokens(env, array, 10, PATH_TOKEN_SPLIT); char* path = calloc(256, sizeof(char)); int i; for(i = 0; i < numTokens; ++i) { // Calc command path strncpy(path, array[i],256); strncat(path, "/", 256); strncat(path, command, 256); // If command exists at dir, return it Dir* d = dirstat(path); free(d); if(d) // We are only interested on the pointer, not on it's content... break; } free(env); return path; }
Dir* cdDirstat(char *dir, char *file) { if(myChdir(dir) < 0) return nil; return dirstat(file); }
static int removefile(SConn *conn, char *id, char *f) { Dir *d; char buf[Maxmsg]; snprint(buf, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, f); if((d = dirstat(buf)) == nil){ snprint(buf, sizeof buf, "remove failed: %r"); writerr(conn, buf); return -1; }else if(d->mode & DMDIR){ snprint(buf, sizeof buf, "can't remove a directory"); writerr(conn, buf); free(d); return -1; } free(d); if(remove(buf) < 0){ snprint(buf, sizeof buf, "remove failed: %r"); writerr(conn, buf); return -1; } return 0; }
int auth_getkey(char *params) { char *name; Dir *d; int pid; Waitmsg *w; /* start /factotum to query for a key */ name = "/factotum"; d = dirstat(name); if(d == nil){ name = "/boot/factotum"; d = dirstat(name); } if(d == nil){ werrstr("auth_getkey: no /factotum or /boot/factotum: didn't get key %s", params); return -1; } if(0) if(d->type != '/'){ werrstr("auth_getkey: /factotum may be bad: didn't get key %s", params); return -1; } switch(pid = fork()){ case -1: werrstr("can't fork for %s: %r", name); return -1; case 0: execl(name, "getkey", "-g", params, nil); exits(0); default: for(;;){ w = wait(); if(w == nil) break; if(w->pid == pid){ if(w->msg[0] != '\0'){ free(w); return -1; } free(w); return 0; } } } return 0; }
/* * get a cracked dependency file */ Dfile* getdf(char *path) { Dfile *df, **l; QLock *lk; Dir *d; int i, fd; Biobuf *b; i = shash(path, Ndfhash); l = &dfhash[i]; lk = &dfhlock[i]; qlock(lk); for(df = *l; df; df = *l){ if(strcmp(path, df->path) == 0) break; l = &df->next; } d = dirstat(path); if(df){ if(d!=nil && d->qid.type == df->qid.type && d->qid.vers == df->qid.vers && d->qid.vers == df->qid.vers){ free(path); lock(df); df->use++; unlock(df); goto Return; } *l = df->next; freedf(df); } fd = open(path, OREAD); if(d == nil || fd < 0){ close(fd); goto Return; } df = emalloc(sizeof(*df)); b = emalloc(sizeof(Biobuf)); Binit(b, fd, OREAD); df->qid = d->qid; df->path = path; crackdf(df, b, d->length, path); Bterm(b); free(b); df->next = *l; *l = df; df->use = 1; Return: qunlock(lk); free(d); return df; }
Dir* wdirstat(char *fn) { Dir *d; fn = wname(fn); d = dirstat(fn); free(fn); return d; }
/* * read_dir: get the file names and modification dates for the * files in /usr/news into n_list; sort them in reverse by * modification date. */ void read_dir(int update) { Dir *d; char newstime[100], *home; int i, j, n, na, fd; n_count = 0; n_list = malloc(NINC*sizeof(File)); na = NINC; home = getenv("HOME"); if(home) { sprint(newstime, TFILE, home); d = dirstat(newstime); if(d != nil) { n_list[n_count].name = strdup(""); n_list[n_count].time =d->mtime-1; n_list[n_count].length = 0; n_count++; free(d); } if(update) { fd = create(newstime, OWRITE, 0644); if(fd >= 0) close(fd); } } fd = open(NEWS, OREAD); if(fd < 0) { fprint(2, "news: "); perror(NEWS); exits(NEWS); } n = dirreadall(fd, &d); for(i=0; i<n; i++) { for(j=0; ignore[j]; j++) if(strcmp(ignore[j], d[i].name) == 0) goto ign; if(na <= n_count) { na += NINC; n_list = realloc(n_list, na*sizeof(File)); } n_list[n_count].name = strdup(d[i].name); n_list[n_count].time = d[i].mtime; n_list[n_count].length = d[i].length; n_count++; ign:; } free(d); close(fd); qsort(n_list, n_count, sizeof(File), fcmp); }
int samefile(char *a, char *b) { Dir *da, *db; int ret; if(strcmp(a, b) == 0) return 1; da = dirstat(a); db = dirstat(b); ret = (da != nil && db != nil && da->qid.type==db->qid.type && da->qid.path==db->qid.path && da->qid.vers==db->qid.vers && da->dev==db->dev && da->type==db->type); free(da); free(db); return ret; }
int chgtime(char *name) { Dir sbuf; if(dirstat(name, &sbuf) >= 0) { sbuf.mtime = time((long *)0); return dirwstat(name, &sbuf); } return close(create(name, OWRITE, 0666)); }
int localdirstat(char *name, Dir *d) { static Dir *d2; free(d2); if((d2 = dirstat(name)) == nil) return -1; *d = *d2; return 0; }
int isdir(char *s) { uint32_t m; Dir *d; if((d = dirstat(s)) == nil) return 0; m = d->mode; free(d); return (m&DMDIR) != 0; }
int gethi(void) { Dir *d; int hi; if((d = dirstat(dir)) == nil) return -1; hi = d->qid.vers; free(d); return hi; }
char * getcmdstr(void) { Event ev; int e; static ulong timekey = 0; ulong tracktm = 0; Dir *dir; if(track){ if(timekey == 0) timekey = etimer(0, 5000); dir = dirstat(track); if(dir != nil){ tracktm = dir->mtime; free(dir); } } for (;;) { e = event(&ev); if(resized){ resized = 0; return "p"; } if ((e & Emouse) && ev.mouse.buttons) { mouse = ev.mouse; return getmousestr(); } else if (e & Ekeyboard) return getkbdstr(ev.kbdc); /* sadly, no way to unget */ else if (e & timekey) { if((dir = dirstat(track)) != nil){ if(tracktm < dir->mtime){ free(dir); return "q"; } free(dir); } } } }
void initdata(char *f, int) { char err[ERRMAX]; char buf[1024], *fld[8]; int n; Dir *d; isdev = 1; flash.dfd = open(f, ORDWR); if(flash.dfd < 0){ errstr(err, sizeof err); if((flash.dfd = create(f, ORDWR, 0666)) >= 0){ fprint(2, "warning: created plain file %s\n", buf); goto Plain; } errstr(err, sizeof err); /* restore open error */ sysfatal("opening %s: %r", f); } if(snprint(buf, sizeof buf, "%sctl", f) != strlen(f)+3) sysfatal("path too long: %s", f); flash.cfd = open(buf, ORDWR); if(flash.cfd < 0){ fprint(2, "warning: cannot open %s (%r); assuming plain file\n", buf); Plain: isdev = 0; if(sectsize == 0) sectsize = 512; if(nsects == 0){ if((d = dirstat(f)) == nil) sysfatal("stat %s: %r", f); nsects = d->length / sectsize; free(d); } ones = emalloc9p(sectsize); memset(ones, ~0, sectsize); }else{ n = read(flash.cfd, buf, sizeof(buf)-1); if(n <= 0) sysfatal("reading %sctl: %r", f); buf[n] = 0; n = tokenize(buf, fld, nelem(fld)); if(n < 7) sysfatal("bad flash geometry"); nsects = atoi(fld[5]); sectsize = atoi(fld[6]); if(nsects < 8) sysfatal("unreasonable value for nsects: %lud", nsects); if(sectsize < 512) sysfatal("unreasonable value for sectsize: %lud", sectsize); } }
// mtime returns the modification time of the file p. Time mtime(char *p) { Dir *d; ulong t; d = dirstat(p); if(d == nil) return 0; t = d->mtime; free(d); return (Time)t; }
// isfile reports whether p names an existing file. bool isfile(char *p) { Dir *d; ulong mode; d = dirstat(p); if(d == nil) return 0; mode = d->mode; free(d); return (mode & DMDIR) == 0; }