|
|
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: extern char *strcat(); ! 8: ! 9: char targetdir[128]; ! 10: ! 11: char SERVER[]="/usr/lib/Rpull"; ! 12: int server=2; /* should be >1 until proven guilty */ ! 13: ! 14: char * ! 15: basename(s) ! 16: register char *s; ! 17: { ! 18: extern char *strrchr(); ! 19: register char *t; ! 20: t=strrchr(s, '/'); ! 21: return(t? t+1 : s); ! 22: } ! 23: ! 24: int errors=0; ! 25: int vflag; ! 26: ! 27: main(argc, argv) ! 28: char *argv[]; ! 29: { ! 30: register i; ! 31: int status; ! 32: register pid; ! 33: char buf[129]; ! 34: if(argc>1 && strcmp(argv[1], "-v")==0){ ! 35: vflag=1; ! 36: argv++; ! 37: --argc; ! 38: } ! 39: if(argc<4){ ! 40: error("Usage: push machine <files|dirs> remotedir>", ""); ! 41: exit(1); ! 42: } ! 43: (void)strcat(strcpy(targetdir, argv[argc-1]), "/"); ! 44: if(basename(argv[0])[0]=='R') ! 45: server=1; ! 46: else{ ! 47: /* Set up the remote process */ ! 48: sprintf(buf, "%s %s", SERVER, argv[argc-1]); ! 49: server=tdkexec(argv[1], buf); ! 50: if(server<0){ ! 51: extern char *dkerror; ! 52: fprintf(stderr, "push: can't execute %s (%s)\n", SERVER, ! 53: dkerror); ! 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, &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.