ref: e3f76c40a809af8bff12c76f0c413e20048c1acf
parent: 585bff5ec0ebd75c2adba9d45c581c8cd7c3722d
author: phil9 <telephil9@gmail.com>
date: Wed Dec 28 10:40:34 EST 2022
implement copy operation
--- a/a.h
+++ b/a.h
@@ -157,6 +157,7 @@
int mkdir(char*, char*);
int rm(char*, Dir);
int rmdir(char*);
+int cp(char*, Dir, char*, char*);
Rectangle boundsrect(Rectangle);
Image* ealloccolor(ulong);
--- a/dirviewcmd.c
+++ b/dirviewcmd.c
@@ -50,7 +50,40 @@
static void
cmdcopy(void)
{
- fprint(2, "TODO: copy\n");
+ Dirpanel *p, *o;
+ Dir *md, d;
+ int nd, n;
+ char buf[1024] = {0};
+
+ p = dirviewcurrentpanel(dview);
+ o = dirviewotherpanel(dview);
+ nd = dirmodelmarklist(p->model, &md);
+ if(nd != 0){
+ snprint(buf, sizeof buf, "copy %d files/directories ?", nd);
+ if(message(Dconfirm, buf, mc, kc) == Bno)
+ return;
+ for(n = 0; n < nd; n++){
+ d = md[n];
+ if(cp(p->model->path, d, o->model->path, nil) < 0){
+ errormessage("copy failed", mc, kc);
+ return;
+ }
+ }
+ }else{
+ n = dirpanelselectedindex(p);
+ if(n == 0 && !p->model->isroot) /* up dir */
+ return;
+ d = dirmodelgetdir(p->model, n);
+ snprint(buf, sizeof buf, "copy %s '%s' to '%s' ?",
+ (d.qid.type&QTDIR) ? "directory" : "file", d.name, o->model->path);
+ if(message(Dconfirm, buf, mc, kc) == Bno)
+ return;
+ if(cp(p->model->path, d, o->model->path, nil) < 0){
+ errormessage("copy failed", mc, kc);
+ return;
+ }
+ }
+ dirmodelreload(o->model);
}
static void
--- a/fops.c
+++ b/fops.c
@@ -61,3 +61,84 @@
}
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;
+}