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