ref: dec6ba0839287843baddfed39179e7b094c38715
parent: 7026f4a83d50b8f61a05bba3b93e1b26d3e5b645
author: kvik <kvik@a-b.xyz>
date: Tue Oct 30 14:00:12 EDT 2018
add -g -u -x flags as in cp(1) and friends
--- a/clone.c
+++ b/clone.c
@@ -13,10 +13,9 @@
};
typedef struct {
+ Dir;
char *src, *dst;
int sfd, dfd;
- ulong mode;
- vlong length;
Channel *c;
} File;
@@ -26,6 +25,9 @@
} Blk;
int keepmode = 0;
+int keepmtime = 0;
+int keepuser = 0;
+int keepgroup = 0;
int blksz = Blksz;
int fileprocs = Nfileprocs;
int blkprocs = Nblkprocs;
@@ -42,9 +44,9 @@
char *filename(char*);
Dir *mkdir(char*, Dir*, int);
-void chmod(char*, ulong);
int same(Dir*, Dir*);
void clone(char*, char*);
+void cloneattr(char*, Dir*);
void clonedir(char*, char*);
void clonefile(File*);
File *filenew(char*, char*, Dir*);
@@ -80,7 +82,7 @@
p = malloc(n);
if(p == nil)
- error("out of memory");
+ error("malloc");
return p;
}
@@ -91,7 +93,7 @@
p = strdup(s);
if(p == nil)
- error("out of memory");
+ error("strdup");
return p;
}
@@ -130,13 +132,22 @@
}
void
-chmod(char *name, ulong mode)
+cloneattr(char *name, Dir *d)
{
- Dir d;
+ Dir dd;
- nulldir(&d);
- d.mode = mode;
- if(dirwstat(name, &d) < 0)
+ if(!(keepmode || keepuser || keepgroup || keepmtime))
+ return;
+ nulldir(&dd);
+ if(keepmode)
+ dd.mode = d->mode & DMDIR ? d->mode|0200 : d->mode;
+ if(keepmtime)
+ dd.mtime = d->mtime;
+ if(keepuser)
+ dd.uid = d->uid;
+ if(keepgroup)
+ dd.gid = d->gid;
+ if(dirwstat(name, &dd) < 0)
error("can't wstat");
}
@@ -158,10 +169,11 @@
File *f;
f = emalloc(sizeof(File));
+ memmove(f, d, sizeof(Dir));
+ f->uid = estrdup(d->uid);
+ f->gid = estrdup(d->gid);
f->src = estrdup(src);
f->dst = estrdup(dst);
- f->mode = d->mode;
- f->length = d->length;
f->sfd = -1;
f->dfd = -1;
f->c = nil;
@@ -176,6 +188,8 @@
close(f->sfd);
if(f->dfd >= 0)
close(f->dfd);
+ free(f->uid);
+ free(f->gid);
free(f->src);
free(f->dst);
free(f);
@@ -211,6 +225,7 @@
dst = smprint("%s/%s", dst, filename(src));
skipdir = mkdir(dst, sd, 1);
clonedir(src, dst);
+ cloneattr(dst, sd);
}
void
@@ -239,8 +254,7 @@
if(d->mode & DMDIR){
mkdir(dn, d, 0);
clonedir(sn, dn);
- if(keepmode)
- chmod(dn, d->mode | 0200);
+ cloneattr(dn, d);
}else{
f = filenew(sn, dn, d);
sendp(filechan, f);
@@ -360,8 +374,7 @@
error("fileproc: can't create");
clonefile(f);
- if(keepmode)
- chmod(f->dst, f->mode);
+ cloneattr(f->dst, f);
filefree(f);
}
}
@@ -381,8 +394,14 @@
*p++ = 0;
blkprocs = strtol(p, nil, 0);
break;
- case 'm':
- keepmode = 1;
+ case 'x':
+ keepmode = keepmtime = 1;
+ break;
+ case 'u':
+ keepuser = 1;
+ break;
+ case 'g':
+ keepgroup = 1;
break;
}ARGEND;
if(argc < 2)