|
|
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[]="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[512];
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.