|
|
1.1 root 1: /*%cc -o pull % -ldk
2: */
3: #include <sys/types.h>
4: #include <sys/stat.h>
5: #include <stdio.h>
6: #include <errno.h>
7: #include <ipc.h>
8: #include <libc.h>
9:
10: extern int errno;
11:
12: char SERVER[]="/usr/lib/Rpush";
13: int server;
14:
15: #define MAXCHARS 8192
16: char args[MAXCHARS];
17:
18: char *bldargs(argv)
19: register char *argv[];
20: {
21: register char *s, *t;
22: extern char *strcpy();
23: s=strcpy(args, SERVER);
24: s+=strlen(s);
25: *s++=' ';
26: while(t= *argv++){ /* assignment = */
27: while(*s = *t++)
28: if(s++ >= &args[MAXCHARS-1]){
29: error("arg list too long", "");
30: exit(1);
31: }
32: *s++=' ';
33: }
34: s[-1]='\0';
35: return(args);
36: }
37:
38: char *
39: basename(s)
40: register char *s;
41: {
42: extern char *strrchr();
43: register char *t;
44: t=strrchr(s, '/');
45: return(t? t+1 : s);
46: }
47:
48: char *
49: str(s, n)
50: register char *s;
51: {
52: static char strbuf[129];
53: (void)strncpy(strbuf, s, n);
54: strbuf[n]=0;
55: return(strbuf);
56: }
57:
58: int errors=0;
59: int vflag;
60:
61: main(argc, argv)
62: char *argv[];
63: {
64: register n;
65: char *targetdir;
66: char buf[512];
67:
68: if(argc>1 && strcmp(argv[1], "-v")==0){
69: vflag=1;
70: argv++;
71: --argc;
72: }
73: if(basename(argv[0])[0]=='R'){
74: if(argc!=2){
75: error("arg count", ""); /* It's ok; other guy will decrypt it */
76: exit(1);
77: }
78: targetdir=argv[1];
79: }else{
80: if(argc<4){
81: error("Usage: pull machine <remotefiles|dirs> localdir", "");
82: exit(1);
83: }
84: targetdir=argv[argc-1];
85: server=0; /* Standard input */
86: server=ipcexec(argv[1], "heavy delim hup", bldargs(&argv[1]));
87: if(server<0){
88: fprintf(stderr, "pull: can't execute %s (%s)\n", SERVER,
89: errstr);
90: exit(1);
91: }
92: }
93: if(mkdir(targetdir, 0777)==0){
94: error("can't make directory", argv[1]);
95: exit(1);
96: }
97: while((n=read(server, buf, sizeof buf))>0){
98: switch(buf[0]){
99: case 'D':
100: if(mkdir(str(buf+4, n-4), o3(buf+1))==0)
101: error("can't make directory", str(buf+1, n-1));
102: break;
103: case 'E':
104: error("(remote)", str(buf+1, n-1));
105: break;
106: case 'F':
107: createfile(str(buf+4, n-4), o3(buf+1));
108: continue; /* createfile() will read null message */
109: default:
110: buf[1]='\0';
111: error("unknown message", buf);
112: break;
113: }
114: if(read(server, buf, sizeof buf)!=0){
115: error("synchronization error", "");
116: do; while(read(server, buf, sizeof buf)>0);
117: }
118: }
119: return(errors);
120: }
121:
122: createfile(s, m)
123: register char *s;
124: {
125: char buf[1024];
126: register f;
127: register cc;
128: if(server>1 && vflag)
129: printf("pull: receive %s\n", s);
130: if((f=creat(s, m))<0)
131: error("can't create", s);
132: else{
133: if(read(server, buf, sizeof buf)>0){
134: error("synchronization", "error");
135: close(f);
136: return;
137: }
138: while((cc=read(server, buf, sizeof buf))>0)
139: if(write(f, buf, cc)!=cc){
140: error("write error", s);
141: if(errno==ENOSPC){
142: error("file system is full; aborting", "");
143: exit(1);
144: }
145: close(f);
146: return;
147: }
148: close(f);
149: }
150: }
151:
152: error(s, t)
153: char *s, *t;
154: {
155: char ebuf[128];
156: errors=1;
157: sprintf(ebuf, "%s%s %s\n", server>0? "pull: " : "" ,s, t);
158: write(2, ebuf, strlen(ebuf));
159: }
160:
161: mkdir(s, m)
162: register char *s;
163: {
164: struct stat statbuf;
165: int status;
166: if(stat(s, &statbuf)<0){
167: if(fork()==0){
168: execl("/bin/mkdir", "mkdir", s, 0);
169: exit(1);
170: }
171: (void)wait(&status);
172: chmod(s, m);
173: return(!status);
174: }
175: return((statbuf.st_mode&S_IFMT)==S_IFDIR);
176: }
177:
178: o3(s)
179: register char *s;
180: {
181: return(((s[0]-'0')*0100)+((s[1]-'0')*010)+(s[2]-'0'));
182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.