|
|
1.1 root 1:
2: static char SCCSID[] = "@(#)push.c 2.1 DKHOST 85/01/15";
3:
4: #include <errno.h>
5: #include <varargs.h>
6: #include "string.h"
7: #include "pupu.h"
8: #include "ndir.h"
9:
10: Efn confirmed, remoteerror, alldone;
11:
12: Sexp justconf[] = {
13: 'c', confirmed,
14: 'e', remoteerror,
15: 'X', alldone,
16: 0, 0
17: };
18:
19: Eexp justquit[];
20:
21: EcharP alreadydumped();
22:
23: push(fd, names, directory, errfcn, options)
24: PfnP errfcn;
25: PcharP *names, directory, options;
26: {
27: begin(fd, errfcn, "local", "");
28:
29: if(setjmp(giveup))
30: return(lasterror);
31:
32: sendinit(options);
33:
34: msginit('D');
35: msgfmt("%s", directory);
36: msgconf(justconf);
37:
38: while(*names)
39: sendfile(*names++);
40:
41: msginit('X');
42: msgsend();
43: msgwait(justquit);
44:
45: signal(SIGALRM, alarmwas);
46: return(lasterror);
47: }
48:
49: putfile(longname, shortname)
50: RcharP longname, shortname;
51: {
52: Rint ifd;
53: AcharP lp;
54: Astat statbuf;
55:
56: if((ifd = openn(shortname, 0)) < 0){
57: warn("Can't open", longname, EX_NOINPUT);
58: return;
59: }
60:
61: fstat(ifd, &statbuf);
62:
63: if(statbuf.st_nlink > 1
64: && (statbuf.st_mode & S_IFMT) != S_IFDIR
65: && (lp = alreadydumped(longname, &statbuf)))
66: dumplink(longname, lp);
67: else
68: switch(statbuf.st_mode & S_IFMT){
69: case S_IFREG:
70: dumpfile('r', ifd, &statbuf, longname);
71: break;
72:
73: case S_IFDIR:
74: dumpdir(ifd, longname, shortname);
75: dumpfile('d', -1, &statbuf, longname);
76: break;
77:
78: case S_IFCHR:
79: dumpfile('c', -1, &statbuf, longname);
80: break;
81:
82: case S_IFBLK:
83: dumpfile('b', -1, &statbuf, longname);
84: break;
85:
86: case S_IFIFO:
87: dumpfile('p', -1, &statbuf, longname);
88: }
89:
90: closen(ifd);
91: }
92:
93: dumpdir(ifd, lname, sname)
94: PcharP lname, sname;
95: {
96: DIR *df;
97: struct direct *de;
98: Along mark;
99: Achar member[NAMELEN];
100:
101: if(chdir(sname) < 0){
102: warn("Can't chdir to", lname, EX_NOINPUT);
103: return;
104: }
105:
106: df = fdopendir(ifd);
107:
108: while(de = readdir(df)){
109:
110: if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
111: continue;
112:
113: if(df->dd_fd > TOPFD){
114: mark = telldir(df);
115: openfiles[df->dd_fd] = 0;
116: closedir(df);
117: }else
118: mark = -1;
119:
120: sprintf(member, "%s/%s", lname, de->d_name);
121:
122: putfile(member, strrchr(member, '/')+1);
123:
124: if(mark >= 0){
125: df = opendir(".");
126: openfiles[df->dd_fd] = 1;
127: seekdir(df, mark);
128: }
129: }
130:
131: openfiles[df->dd_fd] = 0;
132: closedir(df);
133:
134: chdir("..");
135: }
136:
137: dumpfile(type, ifd, st, name)
138: Pchar type;
139: RstatP st;
140: PcharP name;
141: {
142: Rint len;
143:
144: msginit('F');
145:
146: msgfmt("%c", type);
147: msgfmt("%s", name);
148: msgfmt("%o", st->st_mode & 07777);
149: msgfmt("%d", st->st_uid);
150: msgfmt("%d", st->st_gid);
151: msgfmt("%ld", st->st_mtime);
152:
153: if(type == 'r')
154: msgfmt("%ld", st->st_size);
155: else if(type == 'c' || type == 'b'){
156: msgfmt("%d", major(st->st_rdev));
157: msgfmt("%d", minor(st->st_rdev));
158: }
159:
160: msgsend();
161:
162: if(type == 'r'){
163: currentfile = name;
164: timeoutmsg = "File transmission timed out";
165:
166: while((len = read(ifd, buf, sizeof(buf))) > 0){
167: alarm(WTIMEOUT);
168:
169: if(write(cfd, buf, len) != len)
170: err("Channel write error", NIL, EX_IOERR);
171: }
172:
173: if(len < 0)
174: err("Error reading", name, EX_IOERR);
175:
176: dkeof(cfd);
177:
178: alarm(0);
179: }
180:
181: msgwait(justconf);
182: }
183:
184: PcharP
185: alreadydumped(name, st)
186: PcharP name;
187: RstatP st;
188: {
189: RlinkP plp, clp;
190: Schar linkname[NAMELEN];
191:
192: for(plp = &linkhead; clp = plp->next; plp = clp)
193: if(clp->ino == st->st_ino && clp->dev == st->st_dev){
194: strcpy(linkname, clp->name);
195:
196: if(--clp->count <= 0){
197: plp->next = clp->next;
198: free(clp);
199: }
200:
201: return(linkname);
202: }
203:
204: clp = (TlinkP) malloc(sizeof(*clp) + strlen(name));
205:
206: if(clp){
207: strcpy(clp->name, name);
208:
209: clp->count = st->st_nlink - 1;
210: clp->ino = st->st_ino;
211: clp->dev = st->st_dev;
212:
213: clp->next = linkhead.next;
214: linkhead.next = clp;
215: }
216:
217: return(NIL);
218: }
219:
220: dumplink(new, prev)
221: PcharP new, prev;
222: {
223: msginit('L');
224:
225: msgfmt("%s", new);
226: msgfmt("%s", prev);
227:
228: msgconf(justconf);
229: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.