|
|
1.1 ! root 1: ! 2: static char SCCSID[] = "@(#)push.c 2.1 DKHOST 85/01/15"; ! 3: ! 4: #include <errno.h> ! 5: #include <varargs.h> ! 6: #include "string.h" ! 7: #include "pupu.h" ! 8: #include "ndir.h" ! 9: ! 10: Efn confirmed, remoteerror, alldone; ! 11: ! 12: Sexp justconf[] = { ! 13: 'c', confirmed, ! 14: 'e', remoteerror, ! 15: 'X', alldone, ! 16: 0, 0 ! 17: }; ! 18: ! 19: Eexp justquit[]; ! 20: ! 21: EcharP alreadydumped(); ! 22: ! 23: push(fd, names, directory, errfcn, options) ! 24: PfnP errfcn; ! 25: PcharP *names, directory, options; ! 26: { ! 27: begin(fd, errfcn, "local", ""); ! 28: ! 29: if(setjmp(giveup)) ! 30: return(lasterror); ! 31: ! 32: sendinit(options); ! 33: ! 34: msginit('D'); ! 35: msgfmt("%s", directory); ! 36: msgconf(justconf); ! 37: ! 38: while(*names) ! 39: sendfile(*names++); ! 40: ! 41: msginit('X'); ! 42: msgsend(); ! 43: msgwait(justquit); ! 44: ! 45: signal(SIGALRM, alarmwas); ! 46: return(lasterror); ! 47: } ! 48: ! 49: putfile(longname, shortname) ! 50: RcharP longname, shortname; ! 51: { ! 52: Rint ifd; ! 53: AcharP lp; ! 54: Astat statbuf; ! 55: ! 56: if((ifd = openn(shortname, 0)) < 0){ ! 57: warn("Can't open", longname, EX_NOINPUT); ! 58: return; ! 59: } ! 60: ! 61: fstat(ifd, &statbuf); ! 62: ! 63: if(statbuf.st_nlink > 1 ! 64: && (statbuf.st_mode & S_IFMT) != S_IFDIR ! 65: && (lp = alreadydumped(longname, &statbuf))) ! 66: dumplink(longname, lp); ! 67: else ! 68: switch(statbuf.st_mode & S_IFMT){ ! 69: case S_IFREG: ! 70: dumpfile('r', ifd, &statbuf, longname); ! 71: break; ! 72: ! 73: case S_IFDIR: ! 74: dumpdir(ifd, longname, shortname); ! 75: dumpfile('d', -1, &statbuf, longname); ! 76: break; ! 77: ! 78: case S_IFCHR: ! 79: dumpfile('c', -1, &statbuf, longname); ! 80: break; ! 81: ! 82: case S_IFBLK: ! 83: dumpfile('b', -1, &statbuf, longname); ! 84: break; ! 85: ! 86: case S_IFIFO: ! 87: dumpfile('p', -1, &statbuf, longname); ! 88: } ! 89: ! 90: closen(ifd); ! 91: } ! 92: ! 93: dumpdir(ifd, lname, sname) ! 94: PcharP lname, sname; ! 95: { ! 96: DIR *df; ! 97: struct direct *de; ! 98: Along mark; ! 99: Achar member[NAMELEN]; ! 100: ! 101: if(chdir(sname) < 0){ ! 102: warn("Can't chdir to", lname, EX_NOINPUT); ! 103: return; ! 104: } ! 105: ! 106: df = fdopendir(ifd); ! 107: ! 108: while(de = readdir(df)){ ! 109: ! 110: if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) ! 111: continue; ! 112: ! 113: if(df->dd_fd > TOPFD){ ! 114: mark = telldir(df); ! 115: openfiles[df->dd_fd] = 0; ! 116: closedir(df); ! 117: }else ! 118: mark = -1; ! 119: ! 120: sprintf(member, "%s/%s", lname, de->d_name); ! 121: ! 122: putfile(member, strrchr(member, '/')+1); ! 123: ! 124: if(mark >= 0){ ! 125: df = opendir("."); ! 126: openfiles[df->dd_fd] = 1; ! 127: seekdir(df, mark); ! 128: } ! 129: } ! 130: ! 131: openfiles[df->dd_fd] = 0; ! 132: closedir(df); ! 133: ! 134: chdir(".."); ! 135: } ! 136: ! 137: dumpfile(type, ifd, st, name) ! 138: Pchar type; ! 139: RstatP st; ! 140: PcharP name; ! 141: { ! 142: Rint len; ! 143: ! 144: msginit('F'); ! 145: ! 146: msgfmt("%c", type); ! 147: msgfmt("%s", name); ! 148: msgfmt("%o", st->st_mode & 07777); ! 149: msgfmt("%d", st->st_uid); ! 150: msgfmt("%d", st->st_gid); ! 151: msgfmt("%ld", st->st_mtime); ! 152: ! 153: if(type == 'r') ! 154: msgfmt("%ld", st->st_size); ! 155: else if(type == 'c' || type == 'b'){ ! 156: msgfmt("%d", major(st->st_rdev)); ! 157: msgfmt("%d", minor(st->st_rdev)); ! 158: } ! 159: ! 160: msgsend(); ! 161: ! 162: if(type == 'r'){ ! 163: currentfile = name; ! 164: timeoutmsg = "File transmission timed out"; ! 165: ! 166: while((len = read(ifd, buf, sizeof(buf))) > 0){ ! 167: alarm(WTIMEOUT); ! 168: ! 169: if(write(cfd, buf, len) != len) ! 170: err("Channel write error", NIL, EX_IOERR); ! 171: } ! 172: ! 173: if(len < 0) ! 174: err("Error reading", name, EX_IOERR); ! 175: ! 176: dkeof(cfd); ! 177: ! 178: alarm(0); ! 179: } ! 180: ! 181: msgwait(justconf); ! 182: } ! 183: ! 184: PcharP ! 185: alreadydumped(name, st) ! 186: PcharP name; ! 187: RstatP st; ! 188: { ! 189: RlinkP plp, clp; ! 190: Schar linkname[NAMELEN]; ! 191: ! 192: for(plp = &linkhead; clp = plp->next; plp = clp) ! 193: if(clp->ino == st->st_ino && clp->dev == st->st_dev){ ! 194: strcpy(linkname, clp->name); ! 195: ! 196: if(--clp->count <= 0){ ! 197: plp->next = clp->next; ! 198: free(clp); ! 199: } ! 200: ! 201: return(linkname); ! 202: } ! 203: ! 204: clp = (TlinkP) malloc(sizeof(*clp) + strlen(name)); ! 205: ! 206: if(clp){ ! 207: strcpy(clp->name, name); ! 208: ! 209: clp->count = st->st_nlink - 1; ! 210: clp->ino = st->st_ino; ! 211: clp->dev = st->st_dev; ! 212: ! 213: clp->next = linkhead.next; ! 214: linkhead.next = clp; ! 215: } ! 216: ! 217: return(NIL); ! 218: } ! 219: ! 220: dumplink(new, prev) ! 221: PcharP new, prev; ! 222: { ! 223: msginit('L'); ! 224: ! 225: msgfmt("%s", new); ! 226: msgfmt("%s", prev); ! 227: ! 228: msgconf(justconf); ! 229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.