ref: d746543eaed06a1027b5faf07ce37963710d36c2
dir: /fops.c/
#include "a.h" int mkdir(char *wd, char *name) { char *p; int fd; p = abspath(wd, name); if(access(p, 0) >= 0){ werrstr("directory already exists"); free(p); return -1; } fd = create(p, OREAD, DMDIR|0755); if(fd < 0){ free(p); return -1; } free(p); close(fd); return 0; } int rmdir(char *path) { Dir *dirs; int i, fd, ndirs; fd = open(path, OREAD); if(fd < 0) return -1; ndirs = dirreadall(fd, &dirs); close(fd); if(ndirs < 0) return -1; for(i = 0; i < ndirs; i++){ if(rm(path, dirs[i]) < 0){ free(dirs); return -1; } } free(dirs); if(remove(path) < 0) return -1; return 0; } int rm(char *path, Dir d) { char buf[1024] = {0}; int rc; snprint(buf, sizeof buf, "%s/%s", path, d.name); if(d.qid.type&QTDIR){ rc = rmdir(buf); }else{ rc = remove(buf); } return rc; } static int fcopy(char *ipath, char *in, char *opath, char *out, int mode) { int rc, ifd, ofd, r, w; char buf[8192]; snprint(buf, sizeof buf, "%s/%s", ipath, in); ifd = open(buf, OREAD); if(ifd < 0) return -1; snprint(buf, sizeof buf, "%s/%s", opath, out); ofd = create(buf, OWRITE, mode); if(ofd < 0){ close(ifd); return -1; } rc = 0; for(;;){ r = read(ifd, buf, sizeof buf); if(r < 0){ rc = -1; break; }else if(r == 0) break; w = write(ofd, buf, r); if(w != r){ rc = -1; break; } } close(ifd); close(ofd); return rc; } static int dircp(char *ipath, Dir d, char *opath, char *oname) { char outp[1024], inp[1024]; Dir *dirs; int i, n, fd; snprint(outp, sizeof outp, "%s/%s", opath, oname ? oname : d.name); if(access(outp, 0) < 0){ fd = create(outp, OREAD, DMDIR|0755); if(fd < 0) return -1; close(fd); } snprint(inp, sizeof inp, "%s/%s", ipath, d.name); fd = open(inp, OREAD); if(fd < 0) return -1; n = dirreadall(fd, &dirs); if(n < 0){ close(fd); return -1; } close(fd); for(i = 0; i < n; i++){ if(cp(inp, dirs[i], outp, dirs[i].name) < 0){ free(dirs); return -1; } } free(dirs); return 0; } int cp(char *ipath, Dir d, char *opath, char *oname) { int rc; if(d.qid.type&QTDIR){ rc = dircp(ipath, d, opath, oname); }else rc = fcopy(ipath, d.name, opath, oname ? oname : d.name, d.mode); return rc; }