Interdata_v6/usr/source/wgong/dcopy.c
#
char usage[] "Usage: dcopy -v input-directory output-directory\n";
char source[] "Input directory not found\n";
char target[] "Output directory not found\n";
struct {
int dev;
int ino;
int flags;
char nlinks;
char uid;
char gid;
char size0;
int size1;
int addr[8];
int actime[2];
int mtime[2];
} stbuf;
char *buff; /* buffer allocated dynamically */
#define BUFFSIZE 1024*10
char from[128], to[128];
char *fend from;
char *tend;
int tdev, tino; /* device & inode of target directory */
int fdev; /* device of source directory */
int vflag;
main(argc, argv)
char **argv;
{
register char *p, *q;
if (--argc > 0 && **++argv == '-') {
if (argv[0][1] == 'v')
vflag++;
argc--;
argv++;
}
if (argc != 2) {
write(1, usage, sizeof usage);
exit(1);
}
p = argv[0];
for (q = from; *q = *p++; *q++)
;
fend = q;
if (stat(from, &stbuf) < 0 || (stbuf.flags&060000) != 040000) {
write(1, source, sizeof source);
exit(1);
}
fdev = stbuf.dev;
p = argv[1];
for (q = to; *q = *p++; *q++)
;
tend = q;
if (stat(to, &stbuf) < 0 || (stbuf.flags&060000) != 040000) {
write(1, target, sizeof target);
exit(1);
}
tdev = stbuf.dev;
tino = stbuf.ino;
buff = sbrk(BUFFSIZE);
close(0);
close(2);
dcopy(1);
}
dcopy(firsttime)
{
register fi, fo, len;
register t0, t1;
int status;
if (vflag) {
puts(from);
putchar('\n');
}
if (stat(from, &stbuf) < 0) {
msg("can't find");
return;
}
switch (stbuf.flags & 060000) {
/* ordinary file */
case 0000000:
if ((fi = open(from, 0)) < 0)
msg("can't open");
else if ((fo = creat(to, stbuf.flags&07777)) < 0) {
msg("can't create");
close(fi);
} else {
while((len = read(fi, buff, BUFFSIZE)) > 0) {
if (write(fo, buff, len) != len) {
msg("write error");
break;
}
}
if (len < 0)
msg("read error");
close(fi);
close(fo);
chown(to, (stbuf.gid<<8) | stbuf.uid);
smdate(to, stbuf.mtime);
}
break;
/* special file */
case 020000:
case 060000:
if (mknod(to, stbuf.flags, stbuf.addr[0]) < 0)
msg("can't mknod");
else {
chown(to, (stbuf.gid<<8) | stbuf.uid);
smdate(to, stbuf.mtime);
}
break;
/* directory */
case 040000:
t0 = stbuf.mtime[0];
t1 = stbuf.mtime[1];
if (!firsttime) {
if (stbuf.dev != fdev ||
(stbuf.dev == tdev && stbuf.ino == tino))
break;
if (!fork()) {
execl("/bin/mkdir", "mkdir", to, 0);
msg("can't exec mkdir");
exit(1);
}
wait(&status);
if (status)
break;
chmod(to, stbuf.flags&07777);
chown(to, (stbuf.gid<<8) | stbuf.uid);
}
if ((fi = open(from, 0)) < 0)
msg("can't open");
else {
while (read(fi, buff, 16) == 16)
if ((buff[0] | buff[1]) != 0
&& (buff[2] != '.'
|| (buff[3] != '\0'
&& (buff[3] != '.'
|| buff[4] != '\0')))
&& nxtpath(&buff[2])) {
dcopy(0);
lstpath();
}
close(fi);
}
if (!firsttime) {
stbuf.mtime[0] = t0;
stbuf.mtime[1] = t1;
smdate(to, stbuf.mtime);
}
break;
}
return;
}
nxtpath(fn)
char *fn;
{
register char *f, *t, *p;
f = fend; t = tend;
if (f[-1] != '/')
*f++ = '/';
if (t[-1] != '/')
*t++ = '/';
for (p = fn; p < &fn[14] && (*t = *f = *p++); ++t, ++f)
if (t>=&to[sizeof(to)-1] || f>=&from[sizeof(from)-1]) {
msg("name too long");
return(0);
}
fend = f; tend = t;
return(1);
}
lstpath()
{
register char *f, *t;
f = fend; t = tend;
do
--f;
while (*--t != '/');
*f = *t = '\0';
fend = f; tend = t;
}
msg(s)
char *s;
{
if (!vflag)
puts(from);
puts(" -- ");
puts(s);
putchar('\n');
}
puts(s)
char *s;
{
register char *p;
for (p = s; putchar(*p); p++)
;
}