shithub: clone

Download patch

ref: ca40584147f8d3d5e0d8628eba44daeaa1ad51c9
parent: 9ffb694797cfae556b8e1c9b07865d5e828d53fc
author: kvik <kvik@a-b.xyz>
date: Wed Mar 13 16:54:55 EDT 2019

ricing the code

--- a/clone.c
+++ b/clone.c
@@ -9,25 +9,29 @@
 	Blksz = 128*1024,
 };
 
-typedef struct {
+typedef struct Waitgroup Waitgroup;
+typedef struct File File;
+typedef struct Blk Blk;
+
+struct Waitgroup {
 	Rendez;
 	QLock;
 	Ref;
-} WaitGroup;
+};
 
-typedef struct {
+struct File {
 	Dir;
-	WaitGroup wg;
+	Waitgroup wg;
 	Channel *errchan;
 	char *src, *dst;
 	int sfd, dfd;
-} File;
+};
 
-typedef struct {
+struct Blk {
 	File *f;
 	long sz;
 	vlong offset;
-} Blk;
+};
 
 int errors = 0;
 int multisrc = 0;
@@ -45,29 +49,6 @@
 Channel *filechan; /* chan(File*) */
 Channel *blkchan; /* chan(Blk*) */
 
-void usage(void);
-void *emalloc(ulong);
-char *estrdup(char*);
-
-extern int cas(long *p, long ov, long nv);
-void wginit(WaitGroup*, long);
-void wgadd(WaitGroup*, long);
-void wgdone(WaitGroup*);
-void wgwait(WaitGroup*);
-
-char *filename(char*);
-int mkdir(char*, char*, Dir*, Dir**);
-int same(Dir*, Dir*);
-void clone(char*, char*);
-int cloneattr(int, Dir*);
-void clonedir(char*, char*);
-int clonefile(File*);
-File *filenew(char*, char*, Dir*);
-void filefree(File*);
-void fileproc(void*);
-vlong blklist(File*, Blk**);
-void blkproc(void*);
-
 void
 usage(void)
 {
@@ -110,8 +91,10 @@
 	return p;
 }
 
+extern int cas(long *p, long ov, long nv);
+
 void
-wginit(WaitGroup *wg, long n)
+wginit(Waitgroup *wg, long n)
 {
 	memset(wg, 0, sizeof(*wg));
 	wg->l = &wg->QLock;
@@ -120,7 +103,7 @@
 }
 
 void
-wgadd(WaitGroup *wg, long n)
+wgadd(Waitgroup *wg, long n)
 {
 	long v;
 
@@ -130,7 +113,7 @@
 }
 
 void
-wgdone(WaitGroup *wg)
+wgdone(Waitgroup *wg)
 {
 	if(decref(wg) == 0){
 		qlock(wg);
@@ -140,7 +123,7 @@
 }
 
 void
-wgwait(WaitGroup *wg)
+wgwait(Waitgroup *wg)
 {
 	qlock(wg);
 	while(wg->ref != 0)
@@ -164,39 +147,6 @@
 }
 
 int
-mkdir(char *src, char *dst, Dir *sd, Dir **dd)
-{
-	int fd;
-	Dir d;
-	
-	if(!(sd->mode & 0400)){
-		error("can't clone directory: '%s' permission denied", src);
-		return -1;
-	}
-	d = *sd;
-	d.mode = d.mode | DMDIR | 0200;
-	fd = create(dst, 0, d.mode);
-	if(fd < 0){
-		error("can't create directory: %r");
-		return -1;
-	}
-	if(cloneattr(fd, &d) < 0){
-		close(fd);
-		return -1;
-	}
-	if(dd){
-		*dd = dirfstat(fd);
-		if(*dd == nil){
-			error("can't stat: %r");
-			close(fd);
-			return -1;
-		}
-	}
-	close(fd);
-	return 1;
-}
-
-int
 same(Dir *a, Dir *b)
 {
 	if(a->type == b->type &&
@@ -250,7 +200,7 @@
 		return 1;
 	nulldir(&dd);
 	if(keepmode)
-		dd.mode = d->mode & DMDIR ? d->mode|0200 : d->mode;
+		dd.mode = d->mode&DMDIR ? d->mode|0200 : d->mode;
 	if(keepmtime)
 		dd.mtime = d->mtime;
 	if(keepuser)
@@ -264,7 +214,84 @@
 	return 1;
 }
 
+int
+mkdir(char *src, char *dst, Dir *sd, Dir **dd)
+{
+	int fd;
+	Dir d;
+	
+	if(!(sd->mode & 0400)){
+		error("can't clone directory: '%s' permission denied", src);
+		return -1;
+	}
+	d = *sd;
+	d.mode = d.mode | DMDIR | 0200;
+	fd = create(dst, 0, d.mode);
+	if(fd < 0){
+		error("can't create directory: %r");
+		return -1;
+	}
+	if(cloneattr(fd, &d) < 0){
+		close(fd);
+		return -1;
+	}
+	if(dd){
+		*dd = dirfstat(fd);
+		if(*dd == nil){
+			error("can't stat: %r");
+			close(fd);
+			return -1;
+		}
+	}
+	close(fd);
+	return 1;
+}
+
 void
+clonedir(char *src, char *dst)
+{
+	int fd;
+	long n;
+	char *sn, *dn;
+	Dir *dirs, *d;
+	File *f;
+
+	dirs = nil;
+
+	fd = open(src, OREAD);
+	if(fd < 0){
+		error("can't open: %r");
+		return;
+	}
+	n = dirreadall(fd, &dirs);
+	if(n < 0){
+		error("can't read directory: %r");
+		close(fd);
+		return;
+	}
+	close(fd);
+
+	for(d = dirs; n; n--, d++){
+		if(d->mode & DMDIR && same(skipdir, d))
+			continue;
+
+		sn = smprint("%s/%s", src, d->name);
+		dn = smprint("%s/%s", dst, d->name);
+		if(d->mode & DMDIR){
+			if(mkdir(sn, dn, d, nil) < 0)
+				continue;
+			clonedir(sn, dn);
+		}else{
+			f = filenew(sn, dn, d);
+			sendp(filechan, f);
+		}
+		free(sn);
+		free(dn);
+	}
+	free(dirs);
+}
+
+void
 clone(char *src, char *dst)
 {
 	char *dn;
@@ -317,50 +344,6 @@
 	free(dd);
 }
 
-void
-clonedir(char *src, char *dst)
-{
-	int fd;
-	long n;
-	char *sn, *dn;
-	Dir *dirs, *d;
-	File *f;
-
-	dirs = nil;
-
-	fd = open(src, OREAD);
-	if(fd < 0){
-		error("can't open: %r");
-		return;
-	}
-	n = dirreadall(fd, &dirs);
-	if(n < 0){
-		error("can't read directory: %r");
-		close(fd);
-		return;
-	}
-	close(fd);
-
-	for(d = dirs; n; n--, d++){
-		if(d->mode & DMDIR && same(skipdir, d))
-			continue;
-
-		sn = smprint("%s/%s", src, d->name);
-		dn = smprint("%s/%s", dst, d->name);
-		if(d->mode & DMDIR){
-			if(mkdir(sn, dn, d, nil) < 0)
-				continue;
-			clonedir(sn, dn);
-		}else{
-			f = filenew(sn, dn, d);
-			sendp(filechan, f);
-		}
-		free(sn);
-		free(dn);
-	}
-	free(dirs);
-}
-
 vlong
 blklist(File *f, Blk **bp)
 {
@@ -476,7 +459,7 @@
 	char *dst;
 	Dir d;
 	File *f;
-	WaitGroup *wg;
+	Waitgroup *wg;
 	
 	threadsetname("fileproc");
 	
@@ -532,7 +515,7 @@
 {
 	int i;
 	char *dst, *p;
-	WaitGroup filewg;
+	Waitgroup filewg;
 
 	salt = time(0);
 	ARGBEGIN{