|
|
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: exit(0); ! 61: }else if(pid==-1){ ! 62: error("can't fork", "try again"); ! 63: exit(1); ! 64: } ! 65: } ! 66: for(i=2; i<argc-1; i++) ! 67: sendfile(argv[i]); ! 68: write(server, buf, 0); /* End of file */ ! 69: if(server>1) ! 70: wait(&status); /* To get all the error messages */ ! 71: return(errors); ! 72: } ! 73: ! 74: #define NDIRSTACK 20 ! 75: char directory[128]; /* Name buffer for directories */ ! 76: char *dirstack[NDIRSTACK]; ! 77: char *basep=directory; ! 78: int dirstkp=0; ! 79: ! 80: pushdir(s, m) ! 81: register char *s; ! 82: { ! 83: char buf[128]; ! 84: if(dirstkp>=NDIRSTACK){ ! 85: error("directory stack overflow", ""); ! 86: exit(1); ! 87: } ! 88: dirstack[dirstkp++]=directory+strlen(directory); ! 89: (void)strcat(directory, s); ! 90: if(dirstkp==1) /* First entry on stack */ ! 91: basep=basename(directory); ! 92: sprintf(buf, "%03o%s%s", m, targetdir, basep); ! 93: message('D', buf); ! 94: (void)strcat(directory, "/"); ! 95: } ! 96: ! 97: popdir() ! 98: { ! 99: if(dirstkp<=0){ ! 100: error("directory stack underflow", ""); ! 101: exit(1); ! 102: } ! 103: *dirstack[--dirstkp]='\0'; ! 104: if(dirstkp<=0) ! 105: basep=directory; ! 106: } ! 107: ! 108: ! 109: sendfile(s) ! 110: register char *s; ! 111: { ! 112: struct stat statbuf; ! 113: char filebuf[128]; ! 114: char remotebuf[128]; ! 115: (void)strcat(strcpy(filebuf, directory), s); ! 116: if(stat(filebuf, &statbuf)<0){ ! 117: error("can't stat", s); ! 118: return; ! 119: } ! 120: if(server>1 && vflag) ! 121: printf("push: send %s\n", filebuf); ! 122: switch(statbuf.st_mode&S_IFMT){ ! 123: case S_IFDIR: ! 124: senddir(filebuf, s, statbuf.st_mode&0777); ! 125: break; ! 126: case S_IFREG: ! 127: sprintf(remotebuf, "%03o%s%s%s", statbuf.st_mode&0777, ! 128: targetdir, basep, basename(s)); ! 129: senddata(filebuf, remotebuf); ! 130: break; ! 131: case S_IFBLK: ! 132: case S_IFCHR: ! 133: error(s, "is a special file; can't send it"); ! 134: break; ! 135: } ! 136: } ! 137: ! 138: senddata(s, remote) ! 139: register char *s, *remote; ! 140: { ! 141: char buf[1024]; ! 142: register f, cc; ! 143: if((f=open(s, 0))<0){ ! 144: error("can't open", s); ! 145: return; ! 146: } ! 147: message('F', remote); ! 148: while((cc=read(f, buf, sizeof buf))>0) ! 149: write(server, buf, cc); ! 150: write(server, buf, 0); ! 151: close(f); ! 152: } ! 153: ! 154: senddir(fullname, localname, m) ! 155: register char *fullname, *localname; ! 156: { ! 157: /* Same as <sys/dir.h> but with DIRSIZ+1 chars */ ! 158: struct direct15{ ! 159: ino_t d_ino; ! 160: char d_name[DIRSIZ+1]; ! 161: }direct15; ! 162: register df; ! 163: if((df=open(fullname, 0))<0){ ! 164: error("can't open directory", fullname); ! 165: return; ! 166: } ! 167: pushdir(localname, m); ! 168: direct15.d_name[14]='\0'; ! 169: while(read(df, (char *)&direct15, sizeof(struct direct))==sizeof(struct direct)){ ! 170: if(direct15.d_ino && strcmp(direct15.d_name, ".")!=0 ! 171: && strcmp(direct15.d_name, "..")!=0) ! 172: sendfile(direct15.d_name); ! 173: } ! 174: popdir(); ! 175: close(df); ! 176: } ! 177: error(s, t) ! 178: char *s, *t; ! 179: { ! 180: char ebuf[512]; ! 181: errors=1; ! 182: if(server>1) ! 183: fprintf(stderr, "push: %s %s\n", s, t); ! 184: else{ ! 185: sprintf(ebuf, "%s %s", s, t); ! 186: message('E', ebuf); ! 187: } ! 188: } ! 189: ! 190: report(s, n) ! 191: register char *s; ! 192: { ! 193: static char msgbuf[512]; ! 194: static char *msgp=msgbuf; ! 195: register i; ! 196: for(i=0; i<n; i++){ ! 197: *msgp= *s++; ! 198: if(*msgp++=='\n'){ ! 199: write(2, "push: (remote) ", 14); ! 200: write(2, msgbuf, msgp-msgbuf); ! 201: msgp=msgbuf; ! 202: } ! 203: } ! 204: } ! 205: ! 206: message(c, s) ! 207: register char *s; ! 208: { ! 209: char buf[128]; ! 210: buf[0]=c; ! 211: strcpy(buf+1, s); ! 212: write(server, buf, strlen(buf)); ! 213: write(server, buf, 0); /* Terminate & synchronize */ ! 214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.