|
|
1.1 root 1:
2: static char SCCSID[] = "@(#)pupucommon.c 2.1 DKHOST 85/01/15";
3:
4: #include "pupu.h"
5: #include <varargs.h>
6: #include <errno.h>
7: #include "string.h"
8: extern int errno ;
9:
10: Xint cfd;
11:
12: Xchar mhead[H_DATA] = "\206\006";
13: Xchar buf[BLOCKSIZE];
14: XcharP mnext;
15: Xchar sseq, rseq;
16:
17: Xjmp giveup;
18: XfnP alarmwas;
19:
20: Xchar wdir[NAMELEN];
21: Xchar basedir[NAMELEN];
22: Xchar wholename[NAMELEN];
23:
24: Xlink linkhead;
25:
26: XfnP errorfunction;
27: Xint lasterror;
28: XcharP remoteorlocal;
29: XcharP currentfile, timeoutmsg;
30:
31: Xchar openfiles[TOPFD+4];
32:
33: Efn gotinit, gotinitreply;
34:
35: Xexp inittable[] = {
36: 'I', gotinit,
37: 'i', gotinitreply,
38: 0, 0
39: };
40:
41: Efn remotedone, remoteerror, alldone;
42:
43: Xexp justquit[] = {
44: 'x', remotedone,
45: 'e', remoteerror,
46: 'X', alldone,
47: 0, 0
48: };
49:
50: SexpP toexpect;
51:
52: Xchar myversion[6] = "1";
53: Xchar theirversion[6];
54:
55: Xchar options[32];
56:
57: Efn timeout;
58:
59: begin(fd, errfcn, rol, initwdir)
60: PfnP errfcn;
61: PcharP rol, initwdir;
62: {
63: cfd = fd;
64: errorfunction = errfcn;
65: remoteorlocal = rol;
66: currentfile = NIL;
67: lasterror = 0;
68:
69: strcpy(wdir, initwdir);
70:
71: signal(SIGALRM, timeout);
72: }
73:
74: sendinit(opt)
75: PcharP opt;
76: {
77: msginit('I');
78: msgfmt("%s", myversion);
79: msgfmt("%s", opt);
80:
81: msgconf(inittable);
82: }
83:
84: gotinit()
85: {
86: msgtake("%s", theirversion);
87: msgtake("%s", options);
88:
89: msginit('i');
90: msgfmt("%s", myversion);
91: msgsend();
92:
93: return(1);
94: }
95:
96: gotinitreply()
97: {
98: msgtake("%s", theirversion);
99:
100: return(1);
101: }
102:
103: err(msg, parm, en)
104: PcharP msg, parm;
105: {
106: warn(msg, parm, en);
107:
108: if(*remoteorlocal == 'r')
109: reply('X');
110:
111: stopnow(en);
112: }
113:
114: warn(msg, parm, en)
115: PcharP msg, parm;
116: {
117: RcharP ep;
118: Achar ebuf[BUFSIZ];
119:
120: ep = ebuf;
121:
122: ep += sprintf(ep, "(%s): %s", remoteorlocal, msg);
123:
124: if(parm)
125: ep += sprintf(ep, " [%s]", parm);
126:
127: if(en > 0 && errno >= 0 && errno <= sys_nerr)
128: sprintf(ep, " -- %s", sys_errlist[errno]);
129:
130: db(stderr, "warn * %s\n", ebuf);
131: if(*remoteorlocal == 'l')
132: (*errorfunction)(ebuf);
133: else{
134: msginit('e');
135: msgfmt("%s", ebuf);
136: msgsend();
137: }
138:
139: lasterror = en < 0 ? -en : en;
140: }
141:
142: creatn(name, mode)
143: PcharP name;
144: {
145: Rint fd;
146:
147: fd = creat(name, mode);
148:
149: if(fd >= 0)
150: openfiles[fd] = 1;
151:
152: return(fd);
153: }
154:
155: openn(name, flags)
156: PcharP name;
157: {
158: Rint fd;
159:
160: fd = open(name, flags);
161:
162: if(fd >= 0)
163: openfiles[fd] = 1;
164:
165: return(fd);
166: }
167:
168: closen(fd)
169: {
170: close(fd);
171:
172: openfiles[fd] = 0;
173: }
174:
175: remotedone()
176: {
177: Aint en;
178:
179: msgtake("%d", &en);
180:
181: if(en)
182: lasterror = en;
183:
184: return(1);
185: }
186:
187: alldone()
188: {
189: stopnow(0);
190: }
191:
192: stopnow(en)
193: {
194: Rint i;
195: RlinkP lp, nlp;
196:
197: alarm(0);
198: signal(SIGALRM, alarmwas);
199:
200: for(i = 0; i < sizeof(openfiles)/sizeof(openfiles[0]); i++)
201: if(openfiles[i])
202: closen(i);
203:
204: for(lp = linkhead.next; lp; lp = nlp){
205: nlp = lp->next;
206: free(lp);
207: }
208: linkhead.next = 0;
209:
210: if(en > 0)
211: lasterror = en;
212: else if(en < 0)
213: lasterror = -en;
214:
215: longjmp(giveup, 1);
216: }
217:
218: msgtake(fmt, ptr)
219: PcharP fmt, ptr;
220: {
221: if(strcmp(fmt, "%s") == 0)
222: strcpy(ptr, mnext); /* Foo! sscanf stops at white space */
223: else
224: sscanf(mnext, fmt, ptr);
225:
226: mnext += strlen(mnext)+1;
227: }
228:
229: reply(type)
230: Pchar type;
231: {
232: if(++sseq > SEQMAX)
233: sseq = SEQMIN;
234: mhead[H_SEQN] = sseq;
235:
236: mhead[H_TYPE] = type;
237:
238: timeoutmsg = "Protocol exchange timed out";
239:
240: alarm(WTIMEOUT);
241:
242: write(cfd, mhead, sizeof(mhead));
243:
244: alarm(0);
245: }
246:
247: confirmed()
248: {
249: return(1);
250: }
251:
252: remoteerror()
253: {
254: Achar ebuf[BUFSIZ];
255:
256: msgtake("%s", ebuf);
257:
258: (*errorfunction)(ebuf);
259:
260: return(0);
261: }
262:
263: msginit(type)
264: Pchar type;
265: {
266: if(toexpect){
267: msgwait(toexpect);
268: toexpect = 0;
269: }
270:
271: if(++sseq > SEQMAX)
272: sseq = SEQMIN;
273: mhead[H_SEQN] = sseq;
274:
275: mhead[H_TYPE] = type;
276:
277: strcpy(buf, mhead);
278:
279: mnext = &buf[H_DATA];
280: }
281:
282: /* VARARGS0 */
283: msgfmt(va_alist)
284: va_dcl
285: {
286: RcharP fmt;
287: va_list args;
288:
289: va_start(args);
290:
291: fmt = va_arg(args, TcharP);
292:
293: mnext += vsprintf(mnext, fmt, args) + 1;
294: }
295:
296: msgconf(expect)
297: PexpP expect;
298: {
299: msgsend();
300:
301: toexpect = expect;
302: }
303:
304: msgsend()
305: {
306: Rint len;
307: db(stderr, "msgsend %c\n", buf[H_TYPE]);
308:
309: len = mnext - buf;
310:
311: timeoutmsg = "Protocol exchange timed out";
312:
313: alarm(WTIMEOUT);
314:
315: if(write(cfd, buf, len) != len)
316: if(*remoteorlocal == 'r')
317: stopnow(EX_IOERR);
318: else
319: err("Message write failed", NIL, EX_IOERR);
320:
321: alarm(0);
322: }
323:
324: msgwait(expect)
325: PexpP expect;
326: {
327: Rint len;
328: RexpP ep;
329:
330: db(stderr, "msgwait %X\n", expect);
331: timeoutmsg = "Protocol exchange timed out";
332:
333: for(;;){
334: alarm(RTIMEOUT);
335:
336: len = read(cfd, buf, sizeof(buf));
337:
338: alarm(0);
339: db(stderr, "read len %d type %c\n", len, buf[H_TYPE]);
340:
341: if(len <= 0)
342: err("Message read error", NIL, EX_IOERR);
343:
344: if(++rseq > SEQMAX)
345: rseq = SEQMIN;
346: if(buf[H_MAG1] != mhead[H_MAG1] || buf[H_MAG2] != mhead[H_MAG2])
347: err("Bad magic number on message", NIL, -EX_PROTOCOL);
348: if(buf[H_SEQN] != rseq)
349: err("Bad sequence number on message", NIL, -EX_PROTOCOL);
350:
351: mnext = &buf[H_DATA];
352:
353: for(ep = expect; ep->type; ep++)
354: if(ep->type == buf[H_TYPE])
355: if((*ep->fn)())
356: return;
357: else
358: break;
359:
360: if(!ep->type)
361: err("Unexpected message type", &buf[H_TYPE], -EX_PROTOCOL);
362: }
363: }
364:
365:
366: sendfile(name)
367: RcharP name;
368: {
369: AcharP d;
370:
371: if(d = strrchr(name, '/')){
372: if(!wdir[0])
373: curdir(wdir);
374:
375: if(d == name)
376: name = "/";
377: else
378: *d = '\0';
379:
380: if(chdir(name) < 0){
381: warn("Can't change directory to", name, EX_NOINPUT);
382: return;
383: }
384:
385: name = d+1;
386: }
387:
388: putfile(name, name);
389:
390: if(d)
391: chdir(wdir);
392: }
393:
394: timeout()
395: {
396: err(timeoutmsg, currentfile, -EX_IOERR);
397: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.