|
|
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.