|
|
1.1 ! root 1: /*%cc -o push % -ldk ! 2: */ ! 3: #include <stdio.h> ! 4: #include <sys/types.h> ! 5: #include <sys/dir.h> ! 6: #include <sys/stat.h> ! 7: #include <libc.h> ! 8: #include <ipc.h> ! 9: ! 10: char targetdir[128]; ! 11: ! 12: char SERVER[]="/usr/lib/Rpull"; ! 13: int server=2; /* should be >1 until proven guilty */ ! 14: ! 15: char * ! 16: basename(s) ! 17: register char *s; ! 18: { ! 19: extern char *strrchr(); ! 20: register char *t; ! 21: t=strrchr(s, '/'); ! 22: return(t? t+1 : s); ! 23: } ! 24: ! 25: int errors=0; ! 26: int vflag; ! 27: ! 28: main(argc, argv) ! 29: char *argv[]; ! 30: { ! 31: register i; ! 32: int status; ! 33: register pid; ! 34: char buf[129]; ! 35: if(argc>1 && strcmp(argv[1], "-v")==0){ ! 36: vflag=1; ! 37: argv++; ! 38: --argc; ! 39: } ! 40: if(argc<4){ ! 41: error("Usage: push machine <files|dirs> remotedir>", ""); ! 42: exit(1); ! 43: } ! 44: (void)strcat(strcpy(targetdir, argv[argc-1]), "/"); ! 45: if(basename(argv[0])[0]=='R') ! 46: server=1; ! 47: else{ ! 48: /* Set up the remote process */ ! 49: sprintf(buf, "%s %s", SERVER, argv[argc-1]); ! 50: server=ipcexec(argv[1], "heavy delim hup", buf); ! 51: if(server<0){ ! 52: fprintf(stderr, "push: can't execute %s (%s)\n", SERVER, ! 53: errstr); ! 54: exit(1); ! 55: } ! 56: /* Must print remote errors locally */ ! 57: if((pid=fork())==0){ ! 58: while((i=read(server, buf, sizeof buf))>0) ! 59: report(buf, i); ! 60: report("done\n", 5); ! 61: exit(0); ! 62: }else if(pid==-1){ ! 63: error("can't fork", "try again"); ! 64: exit(1); ! 65: } ! 66: } ! 67: for(i=2; i<argc-1; i++) ! 68: sendfile(argv[i]); ! 69: write(server, buf, 0); /* End of file */ ! 70: if(server>1) ! 71: wait(&status); /* To get all the error messages */ ! 72: return(errors); ! 73: } ! 74: ! 75: #define NDIRSTACK 20 ! 76: char directory[128]; /* Name buffer for directories */ ! 77: char *dirstack[NDIRSTACK]; ! 78: char *basep=directory; ! 79: int dirstkp=0; ! 80: ! 81: pushdir(s, m) ! 82: register char *s; ! 83: { ! 84: char buf[128]; ! 85: if(dirstkp>=NDIRSTACK){ ! 86: error("directory stack overflow", ""); ! 87: exit(1); ! 88: } ! 89: dirstack[dirstkp++]=directory+strlen(directory); ! 90: (void)strcat(directory, s); ! 91: if(dirstkp==1) /* First entry on stack */ ! 92: basep=basename(directory); ! 93: sprintf(buf, "%03o%s%s", m, targetdir, basep); ! 94: message('D', buf); ! 95: (void)strcat(directory, "/"); ! 96: } ! 97: ! 98: popdir() ! 99: { ! 100: if(dirstkp<=0){ ! 101: error("directory stack underflow", ""); ! 102: exit(1); ! 103: } ! 104: *dirstack[--dirstkp]='\0'; ! 105: if(dirstkp<=0) ! 106: basep=directory; ! 107: } ! 108: ! 109: ! 110: sendfile(s) ! 111: register char *s; ! 112: { ! 113: struct stat statbuf; ! 114: char filebuf[128]; ! 115: char remotebuf[128]; ! 116: (void)strcat(strcpy(filebuf, directory), s); ! 117: if(stat(filebuf, &statbuf)<0){ ! 118: error("can't stat", s); ! 119: return; ! 120: } ! 121: if(server>1 && vflag) ! 122: printf("push: send %s\n", filebuf); ! 123: switch(statbuf.st_mode&S_IFMT){ ! 124: case S_IFDIR: ! 125: senddir(filebuf, s, statbuf.st_mode&0777); ! 126: break; ! 127: case S_IFREG: ! 128: sprintf(remotebuf, "%03o%s%s%s", statbuf.st_mode&0777, ! 129: targetdir, basep, basename(s)); ! 130: senddata(filebuf, remotebuf); ! 131: break; ! 132: case S_IFBLK: ! 133: case S_IFCHR: ! 134: error(s, "is a special file; can't send it"); ! 135: break; ! 136: } ! 137: } ! 138: ! 139: senddata(s, remote) ! 140: register char *s, *remote; ! 141: { ! 142: char buf[512]; ! 143: extern errno; ! 144: register f, cc; ! 145: int i; ! 146: if((f=open(s, 0))<0){ ! 147: error("can't open", s); ! 148: return; ! 149: } ! 150: message('F', remote); ! 151: i = 0; ! 152: while((cc=read(f, buf, sizeof buf))>0) { ! 153: write(server, buf, cc); ! 154: if (i%200 == 0) ! 155: fprintf(stderr, "."); ! 156: i++; ! 157: } ! 158: if (cc<0) { ! 159: fprintf(stderr, read error %d\n", errno); ! 160: } ! 161: fprintf(stderr, "push done\n"); ! 162: write(server, buf, 0); ! 163: close(f); ! 164: } ! 165: ! 166: senddir(fullname, localname, m) ! 167: register char *fullname, *localname; ! 168: { ! 169: /* Same as <sys/dir.h> but with DIRSIZ+1 chars */ ! 170: struct direct15{ ! 171: ino_t d_ino; ! 172: char d_name[DIRSIZ+1]; ! 173: }direct15; ! 174: register df; ! 175: if((df=open(fullname, 0))<0){ ! 176: error("can't open directory", fullname); ! 177: return; ! 178: } ! 179: pushdir(localname, m); ! 180: direct15.d_name[14]='\0'; ! 181: while(read(df, (char *)&direct15, sizeof(struct direct))==sizeof(struct direct)){ ! 182: if(direct15.d_ino && strcmp(direct15.d_name, ".")!=0 ! 183: && strcmp(direct15.d_name, "..")!=0) ! 184: sendfile(direct15.d_name); ! 185: } ! 186: popdir(); ! 187: close(df); ! 188: } ! 189: error(s, t) ! 190: char *s, *t; ! 191: { ! 192: char ebuf[512]; ! 193: errors=1; ! 194: if(server>1) ! 195: fprintf(stderr, "push: %s %s\n", s, t); ! 196: else{ ! 197: sprintf(ebuf, "%s %s", s, t); ! 198: message('E', ebuf); ! 199: } ! 200: } ! 201: ! 202: report(s, n) ! 203: register char *s; ! 204: { ! 205: static char msgbuf[512]; ! 206: static char *msgp=msgbuf; ! 207: register i; ! 208: fprintf(stderr, "report: %d: ", n); ! 209: for(i=0; i<n; i++){ ! 210: *msgp= *s++; ! 211: if(*msgp++=='\n'){ ! 212: write(2, "push: (remote) ", 14); ! 213: write(2, msgbuf, msgp-msgbuf); ! 214: msgp=msgbuf; ! 215: } ! 216: } ! 217: } ! 218: ! 219: message(c, s) ! 220: register char *s; ! 221: { ! 222: char buf[128]; ! 223: buf[0]=c; ! 224: strcpy(buf+1, s); ! 225: write(server, buf, strlen(buf)); ! 226: write(server, buf, 0); /* Terminate & synchronize */ ! 227: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.