|
|
1.1 root 1: /* rtfd.c - RT-file transfer utility -- responder */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.1 90/07/01 21:04:48 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/rtf/RCS/rtfd.c,v 7.1 90/07/01 21:04:48 mrose Exp $
9: *
10: *
11: * $Log: rtfd.c,v $
12: * Revision 7.1 90/07/01 21:04:48 mrose
13: * pepsy
14: *
15: * Revision 7.0 89/11/23 22:10:49 mrose
16: * Release 6.0
17: *
18: */
19:
20: /*
21: * NOTICE
22: *
23: * Acquisition, use, and distribution of this module and related
24: * materials are subject to the restrictions of a license agreement.
25: * Consult the Preface in the User's Manual for the full terms of
26: * this agreement.
27: *
28: */
29:
30:
31: #include "RTF-types.h"
32: #include "rtf.h"
33: #include <pwd.h>
34:
35:
36: #ifdef SYS5
37: struct passwd *getpwnam ();
38: #endif
39:
40: #ifndef ANON
41: #define ANON "ftp"
42: #endif
43:
44: /* DATA */
45:
46: static int debug = 0;
47:
48: static char *myname = "rtfd";
49:
50:
51: static int fd;
52: static int nbytes;
53: static char *destination;
54:
55: int downtrans (), uptrans ();
56:
57: /* MAIN */
58:
59: /* ARGSUSED */
60:
61: main (argc, argv, envp)
62: int argc;
63: char **argv,
64: **envp;
65: {
66: int guest,
67: sd,
68: result,
69: turn;
70: register char *cp,
71: *user;
72: register struct passwd *pw;
73: struct RtSAPstart rtss;
74: register struct RtSAPstart *rts = &rtss;
75: struct RtSAPindication rtis;
76: register struct RtSAPindication *rti = &rtis;
77: register struct RtSAPabort *rta = &rti -> rti_abort;
78: struct type_RTF_Request *req;
79:
80: if (myname = rindex (argv[0], '/'))
81: myname++;
82: if (myname == NULL || *myname == NULL)
83: myname = argv[0];
84:
85: isodetailor (myname, 0);
86: if (debug = isatty (fileno (stderr)))
87: ll_dbinit (pgm_log, myname);
88: else
89: ll_hdinit (pgm_log, myname);
90:
91: advise (LLOG_NOTICE, NULLCP, "starting");
92:
93: if (RtBInit (argc, argv, rts, rti) == NOTOK)
94: rts_adios (rta, "(RtB)initialization fails");
95: advise (LLOG_NOTICE, NULLCP,
96: "RT-BEGIN.INDICATION: <%d, %s, %s, <%d, %s>, 0x%x>",
97: rts -> rts_sd, rts -> rts_mode == RTS_TWA ? "twa" : "monologue",
98: rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
99: ntohs (rts -> rts_port),
100: saddr2str (&rts -> rts_initiator.rta_addr),
101: rts -> rts_data);
102:
103: sd = rts -> rts_sd;
104:
105: if (rts -> rts_data == NULLPE) {
106: advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- no user-data parameter");
107: reject: ;
108: if (RtBeginResponse (sd, RTS_REJECT, NULLPE, rti) == NOTOK)
109: rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
110: exit (1);
111: }
112:
113: req = NULL;
114: if (decode_RTF_Request (rts -> rts_data, 1, NULLIP, NULLVP, &req)
115: == NOTOK) {
116: advise (LLOG_EXCEPTIONS, NULLCP,
117: "rejected -- error decoding request: %s", PY_pepy);
118: goto reject;
119: }
120: PLOGP (pgm_log,RTF_Request, rts -> rts_data, "Request", 1);
121:
122: if (qb_pullup (req -> user) == NOTOK) {
123: no_mem: ;
124: advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- out of memory");
125: goto reject;
126: }
127: if (qb_pullup (req -> password) == NOTOK)
128: goto no_mem;
129: if ((cp = qb2str (req -> file)) == NULL)
130: goto no_mem;
131:
132: guest = 0;
133: advise (LLOG_NOTICE, NULLCP, "%s: %s \"%s\"",
134: user = req -> user -> qb_forw -> qb_data,
135: (turn = rts -> rts_turn) == RTS_RESPONDER ? "get" : "put", cp);
136:
137: if (strcmp (cp, "ANON") == 0 || strcmp (user, ANON) == 0) {
138: if ((pw = getpwnam (ANON)) && pw -> pw_uid == 0)
139: pw = NULL;
140: guest = 1;
141: }
142: else
143: pw = baduser (NULLCP, user) ? NULL : getpwnam (user);
144: if (pw == NULL) {
145: advise (LLOG_EXCEPTIONS, NULLCP, "rejected -- no such user");
146: no_validate: ;
147: if (RtBeginResponse (sd, RTS_VALIDATE, NULLPE, rti) == NOTOK)
148: rts_adios (rta, "RT-BEGIN.RESPONSE (validate)");
149: exit (1);
150: }
151: if (*pw -> pw_passwd == NULL
152: || (!guest && strcmp (crypt (req -> password -> qb_forw -> qb_data,
153: pw -> pw_passwd), pw -> pw_passwd))) {
154: advise (LLOG_EXCEPTIONS, NULLCP,
155: "authentication failure for \"%s\"%s requesting %s of \"%s\"",
156: user, guest ? " (guest)" : "",
157: (turn = rts -> rts_turn) == RTS_RESPONDER ? "get" : "put",
158: cp);
159: goto no_validate;
160: }
161:
162: if (chdir (pw -> pw_dir) == NOTOK) {
163: advise (LLOG_EXCEPTIONS, pw -> pw_dir,
164: "unable to change directory to");
165: no_dice: ;
166: if (RtBeginResponse (sd, RTS_BUSY, NULLPE, rti) == NOTOK)
167: rts_adios (rta, "RT-BEGIN.RESPONSE (busy)");
168: exit (1);
169: }
170: if (guest && chroot (pw -> pw_dir) == NOTOK) {
171: advise (LLOG_EXCEPTIONS, pw -> pw_dir,
172: "unable to change root to");
173: goto no_dice;
174: }
175:
176: (void) setgid (pw -> pw_gid);
177: #ifndef SYS5
178: (void) initgroups (pw -> pw_name, pw -> pw_gid);
179: #endif
180: (void) setuid (pw -> pw_uid);
181:
182: (void) umask (0022);
183:
184: if (turn == RTS_RESPONDER) {
185: if ((fd = open (cp, O_RDONLY, 0x00)) == NOTOK) {
186: advise (LLOG_EXCEPTIONS, cp, "rejected -- unable to open");
187: goto reject;
188: }
189: free (cp);
190: }
191: else
192: destination = cp;
193:
194: free_RTF_Request (req);
195:
196: RTSFREE (rts);
197:
198: if (RtBeginResponse (sd, RTS_ACCEPT, NULLPE, rti) == NOTOK)
199: rts_adios (rta, "RT-BEGIN.RESPONSE (accept)");
200:
201: if (turn == RTS_RESPONDER) {
202: if (RtSetDownTrans (sd, downtrans, rti) == NOTOK)
203: rts_adios (rta, "set DownTrans upcall");
204:
205: if (RtTransferRequest (sd, NULLPE, NOTOK, rti) == NOTOK)
206: rts_adios (rta, "RT-TRANSFER.REQUEST");
207:
208: if (nbytes == 0)
209: advise (LLOG_NOTICE, NULLCP, "transfer complete");
210: else
211: timer (nbytes);
212:
213: (void) close (fd);
214: }
215: else
216: if (RtSetUpTrans (sd, uptrans, rti) == NOTOK)
217: rts_adios (rta, "set UpTrans upcall");
218:
219: for (;;) {
220: switch (result = RtWaitRequest (sd, NOTOK, rti)) {
221: case NOTOK:
222: case OK:
223: case DONE:
224: break;
225:
226: default:
227: adios (NULLCP, "unknown return from RtWaitRequest=%d",
228: result);
229: }
230:
231: switch (rti -> rti_type) {
232: case RTI_TURN:
233: {
234: register struct RtSAPturn *rtu = &rti -> rti_turn;
235:
236: if (rtu -> rtu_please) {
237: if (RtGTurnRequest (sd, rti) == NOTOK)
238: rts_adios (rta, "RT-TURN-GIVE.REQUEST");
239: }
240: else
241: adios (NULLCP, "protocol screw-up");
242: }
243: continue;
244:
245: case RTI_TRANSFER:
246: {
247: #ifndef lint
248: register struct RtSAPtransfer *rtt = &rti -> rti_transfer;
249: #endif
250:
251: if (nbytes == 0)
252: advise (LLOG_NOTICE, NULLCP, "transfer complete");
253: else
254: timer (nbytes);
255: }
256: continue;
257:
258: case RTI_ABORT:
259: {
260: register struct RtSAPabort *rtb = &rti -> rti_abort;
261:
262: if (rtb -> rta_peer)
263: rts_adios (rtb, "RT-U-ABORT.INDICATION");
264: if (RTS_FATAL (rtb -> rta_reason))
265: rts_adios (rtb, "RT-P-ABORT.INDICATION");
266: rts_advise (rtb, "RT-P-ABORT.INDICATION");
267: }
268: break;
269:
270: case RTI_CLOSE:
271: {
272: #ifndef lint
273: register struct RtSAPclose *rtc = &rti -> rti_close;
274: #endif
275:
276: advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
277: if (RtEndResponse (sd, rti) == NOTOK)
278: rts_adios (rta, "RT-END.RESPONSE");
279: }
280: break;
281:
282: case RTI_FINISH:
283: adios (NULLCP, "unexpected indication type=%d",
284: rti -> rti_type);
285:
286: default:
287: adios (NULLCP, "unknown indication type=%d", rti -> rti_type);
288: }
289: break;
290: }
291:
292: exit (0);
293: }
294:
295: /* TRANSFER */
296:
297: /* ARGSUSED */
298:
299: static int downtrans (sd, base, len, size, ssn, ack, rti)
300: int sd;
301: char **base;
302: int *len,
303: size;
304: long ssn,
305: ack;
306: struct RtSAPindication *rti;
307: {
308: register int cc;
309: int n;
310: register char *dp,
311: *ep;
312: static int bsize;
313: static char *bp = NULL;
314:
315: if (base == NULLVP) {
316: #ifdef DEBUG
317: advise (LLOG_DEBUG, NULLCP, "RT-PLEASE.INDICATION: %d", size);
318: #endif
319: return OK;
320: }
321:
322: if (bp == NULL) {
323: struct stat st;
324:
325: if (fstat (fd, &st) == NOTOK)
326: return rtsaplose (rti, RTS_TRANSFER, destination,
327: "unable to fstat");
328: #ifdef MAXBSIZE
329: bsize = st.st_blksize > 0 ? st.st_blksize : BUFSIZ;
330: #else
331: bsize = BUFSIZ;
332: #endif
333: if (size == 0) /* no checkpointing... */
334: n = st.st_size;
335: else
336: if ((n = bsize) > size)
337: n = size;
338: if ((bp = malloc ((unsigned) n)) == NULL)
339: return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory");
340: #ifdef DEBUG
341: advise (LLOG_DEBUG, NULLCP, "Selecting block size of %d", n);
342: advise (LLOG_DEBUG, NULLCP,
343: " based on blksize of %d and RTTR size of %d",
344: bsize, size);
345: #endif
346: bsize = n;
347: timer (nbytes = 0);
348: }
349:
350: *base = NULLCP, *len = 0;
351: for (ep = (dp = bp) + (cc = bsize); dp < ep; dp += n, cc -= n) {
352: switch (n = read (fd, dp, cc)) {
353: case NOTOK:
354: return rtsaplose (rti, RTS_TRANSFER, "failed", "read");
355:
356: default:
357: continue;
358:
359: case OK:
360: break;
361: }
362: break;
363: }
364: if ((cc = dp - bp) > 0) {
365: *base = bp, *len = cc;
366: nbytes += cc;
367: }
368:
369: return OK;
370: }
371:
372: /* */
373:
374: /* ARGSUSED */
375:
376: static int uptrans (sd, type, addr, rti)
377: int sd;
378: int type;
379: caddr_t addr;
380: struct RtSAPindication *rti;
381: {
382: switch (type) {
383: case SI_DATA:
384: {
385: register struct qbuf *qb = (struct qbuf *) addr;
386: register struct qbuf *qp;
387:
388: for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw)
389: if (write (fd, qp -> qb_data, qp -> qb_len) !=qp -> qb_len)
390: return rtsaplose (rti, RTS_TRANSFER, "failed","write");
391: else
392: nbytes += qp -> qb_len;
393: }
394: break;
395:
396: case SI_SYNC:
397: {
398: #ifdef DEBUG
399: register struct SSAPsync *sn = (struct SSAPsync *) addr;
400:
401: advise (LLOG_DEBUG, NULLCP, "S-MINOR-SYNC.INDICATION: %ld",
402: sn -> sn_ssn);
403: #endif
404: }
405: break;
406:
407: case SI_ACTIVITY:
408: {
409: register struct SSAPactivity *sv = (struct SSAPactivity *)addr;
410:
411: switch (sv -> sv_type) {
412: case SV_START:
413: #ifdef DEBUG
414: advise (LLOG_DEBUG, NULLCP,
415: "S-ACTIVITY-START.INDICATION");
416: #endif
417: if ((fd = creat (destination, 0666)) == NOTOK) {
418: advise (LLOG_EXCEPTIONS, destination,
419: "unable to create");
420: return rtsaplose (rti, RTS_TRANSFER, destination,
421: "unable to create");
422: }
423: timer (nbytes = 0);
424: break;
425:
426: case SV_INTRIND:
427: case SV_DISCIND:
428: advise (LLOG_EXCEPTIONS, NULLCP,
429: "activity %s: %s",
430: sv -> sv_type == SV_INTRIND ? "interrupted"
431: : "discarded",
432: SReportString (sv -> sv_reason));
433: remove (destination);
434: break;
435:
436: case SV_ENDIND:
437: #ifdef DEBUG
438: advise (LLOG_DEBUG, NULLCP,
439: "S-ACTIVITY-END.INDICATION");
440: #endif
441: if (close (fd) == NOTOK)
442: return rtsaplose (rti, RTS_TRANSFER, destination,
443: "close failed on");
444: break;
445:
446: default:
447: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
448: "unexpected activity indication=0x%x",
449: sv -> sv_type);
450: }
451: }
452: break;
453:
454: case SI_REPORT:
455: {
456: register struct SSAPreport *sp = (struct SSAPreport *) addr;
457:
458: if (!sp -> sp_peer)
459: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
460: "unexpected provider-initiated exception report");
461: advise (LLOG_EXCEPTIONS, NULLCP,
462: "exception: %s", SReportString (sp -> sp_reason));
463: remove (destination);
464: }
465: break;
466:
467: default:
468: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
469: "unknown uptrans type=0x%x", type);
470: }
471:
472: return OK;
473: }
474:
475: /* */
476:
477: static remove (file)
478: char *file;
479: {
480: struct stat st;
481:
482: if (stat (file, &st) != NOTOK
483: && (st.st_mode & S_IFMT) == S_IFREG
484: && unlink (file) == NOTOK)
485: advise (LLOG_EXCEPTIONS, file, "unable to unlink");
486: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.