shithub: nc

Download patch

ref: e3f76c40a809af8bff12c76f0c413e20048c1acf
parent: 585bff5ec0ebd75c2adba9d45c581c8cd7c3722d
author: phil9 <[email protected]>
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;
+}