V10/cmd/backup.old/rcv.c
#include <fio.h>
#include "backup.h"
#include <signal.h>
#define DONE fprint(2, "X")
#define Exit(n) (sleep(5), exit(n))
char outfile[256], who[256], bdir[FNAMELEN];
siggy(sn)
{
char buf[256];
signal(sn, SIG_IGN);
strcpy(buf, bdir);
logprint("rcv.%s: signal %d!\n", who, sn);
exit(0);
}
main(argc, argv)
char *argv[];
{
int n, nn;
int ofd;
off_t size;
struct backfile h;
char buf[512];
long nf, nb, t1, t2;
int cfd = 0; /* because we are a server */
int cnt;
unsigned short csum, ocsum;
int erred;
int i;
chdir("/tmp");
backupdir(bdir);
for(n = 1; n < NSIG; n++)
signal(n, siggy);
signal(SIGHUP, SIG_IGN);
dup2(cfd, 2); /* for perror */
ainit();
nb = nf = 0;
(void)time(&t1);
for(i = 0; i < sizeof who; i++){
if(Fread(cfd, &who[i], 1L) != 1){
who[i] = 0;
break;
}
if(who[i] == 0) break;
}
while((i = Fread(cfd, (char *)&h, (long)sizeof h)) == sizeof h){
if(h.version < 0){
i = 0;
break;
}
/*
logprint("rcv.%s: file %d; %d bytes\n", who, nf, h.sbuf.st_size);
write(creat("/tmp/agh", 0666), &h, sizeof h);
if(h.sbuf.st_size > 1000000)h.sbuf.st_size = 2184;
*/
erred = 0;
if((ofd = filefor(&h)) < 0){
strcpy(buf, bdir);
(void)time(&t2);
logprint("rcv.%s: out of space during %ldth file, %ld bytes (%lds)\n", who, nf, nb, t2-t1);
fprint(cfd, "*out of space after %d files\n", nf-1);
erred = 1;
ofd = open("/dev/null", 1);
}
csum = sum(((unsigned char *)&h)+2, sizeof h - 2, 0);
if(strncmp(h.oname, "/n/", 3) == 0){
nf++;
nb += h.sbuf.st_size+sizeof h;
}
sprint(argv[0], "%ld", nf);
for(size = h.sbuf.st_size, n = sizeof buf; size > 0; size -= n){
if(n > size)
n = size;
if((nn = Fread(cfd, buf, (long)n)) != n){
fprint(cfd, "read(%d)=%d", n, nn);
perror("");
DONE;
Exit(1);
}
csum = sum((unsigned char *)buf, n, csum);
if(write(ofd, buf, n) != n){
if(erred == 0){
erred = 1;
perror(outfile);
}
}
}
if((cnt = Fread(cfd, (char *)&ocsum, 2L)) != 2){
fprint(2, "wanted 2, got %d; ", cnt);
perror("read 2");
DONE;
Exit(2);
}
if(csum != ocsum){
fprint(cfd, "%s: csum=%d ocsum=%d (file=%s)\n", h.oname, csum, ocsum, outfile);
DONE;
Exit(3);
}
lseek(ofd, 0L, 0);
if(write(ofd, (char *)&csum, 2) != 2){
perror(outfile);
DONE;
Exit(3);
}
if(chmod(outfile, 0600) < 0){
if(!erred)
perror(outfile);
DONE;
Exit(4);
}
close(ofd);
DONE;
}
(void)time(&t2);
strcpy(buf, bdir);
if(i > 0)
logprint("rcv.%s: bad loop read (%d)\n", who, i);
logprint("rcv.%s: %ld files, %ld bytes (%lds)\n", who, nf, nb, t2-t1);
fprint(cfd, "%ld files, %ld bytes (%lds)\n", nf, nb, t2-t1);
sleep(5); /* give time for things to settle */
exit(0);
}
char *dirs[100];
int ndir;
int nfile;
ainit()
{
char buf[512];
int fd, i;
char *s, *strdup();
sprint(buf, "%s/%s", bdir, RCVDIRS);
if((fd = open(buf, 0)) < 0){
perror(buf);
dirs[0] = "/unix";
dirs[1] = 0;
}
i = 0;
while(s = Frdline(fd))
dirs[i++] = strdup(s);
dirs[i] = 0;
close(fd);
ndir = 0;
nfile = 0;
}
filefor(h)
struct backfile *h;
{
int fd, i;
char buf[4096];
i = ndir;
do {
if((fd = probe(dirs[i], h->sbuf.st_size+sizeof h)) >= 0)
break;
if(dirs[++i] == 0)
i = 0;
nfile = 0;
} while(i != ndir);
ndir = i;
if(fd < 0){
/*fprint(2, "No space left to rcv\n");*/
return(-1);
}
lseek(fd, 0L, 0);
if(write(fd, (char *)h, sizeof *h) != sizeof *h){
perror(outfile);
close(fd);
return(-1);
}
return(fd);
}
probe(dir, size)
char *dir;
off_t size;
{
static i = 0;
char buf[4096];
int n, nn, fd = -1, pid = getpid();
off_t s;
for(n = 0; n < 20; n++){
sprint(outfile, "%s/rcv%d/%d-%d", dir, (pid+i)%32, pid, i);
i++;
if((fd = creat(outfile, 0)) >= 0){
for(s = 0, nn = sizeof buf; s < size; s += nn){
if(size-s < nn)
nn = size-s;
if(write(fd, buf, nn) != nn){
unlink(outfile);
close(fd);
return(-1);
}
}
break;
}
}
return(fd);
}