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