|
|
1.1 root 1: /* rtf.c - RT-file transfer utility -- initiator */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/rtf/RCS/rtf.c,v 7.1 90/07/01 21:04:45 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/rtf/RCS/rtf.c,v 7.1 90/07/01 21:04:45 mrose Exp $
9: *
10: *
11: * $Log: rtf.c,v $
12: * Revision 7.1 90/07/01 21:04:45 mrose
13: * pepsy
14: *
15: * Revision 7.0 89/11/23 22:10:45 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 "isoservent.h"
34:
35: /* DATA */
36:
37: static char *myname = "rtf";
38:
39: static char *myprovider = "rtsap";
40: static char *myentity = "file transfer";
41:
42: static char *host = NULL;
43: static char *user = NULL;
44: static char *password = NULL;
45: static char *source = NULL;
46: static char *destination = NULL;
47: static int turn = NOTOK;
48:
49: static int fd;
50: static int nbytes;
51:
52: int downtrans (), uptrans ();
53:
54:
55: char *getenv ();
56:
57: /* MAIN */
58:
59: /* ARGSUSED */
60:
61: main (argc, argv, envp)
62: int argc;
63: char **argv,
64: **envp;
65: {
66: int result,
67: sd;
68: char *file;
69: register struct isoservent *is;
70: struct SSAPaddr *sa;
71: struct RtSAPaddr rtzs;
72: register struct RtSAPaddr *rtz = &rtzs;
73: struct RtSAPconnect rtcs;
74: register struct RtSAPconnect *rtc = &rtcs;
75: struct RtSAPindication rtis;
76: register struct RtSAPindication *rti = &rtis;
77: register struct RtSAPabort *rta = &rti -> rti_abort;
78: PE pe;
79: struct type_RTF_Request reqs;
80: register struct type_RTF_Request *req = &reqs;
81:
82: arginit (argv);
83:
84: if (turn == RTS_INITIATOR) {
85: if ((fd = open (source, O_RDONLY, 0x00)) == NOTOK)
86: adios (source, "unable to open");
87: file = destination;
88: }
89: else
90: file = source;
91:
92: if ((req -> user = str2qb (user, strlen (user), 1)) == NULL
93: || (req -> password = str2qb (password, strlen (password), 1))
94: == NULL
95: || (req -> file = str2qb (file, strlen (file), 1)) == NULL)
96: adios (NULLCP, "out of memory");
97: pe = NULLPE;
98: if (encode_RTF_Request (&pe, 1, 0, NULLCP, req) == NOTOK)
99: adios (NULLCP, "error encoding request: %s", PY_pepy);
100: PLOGP (pgm_log,RTF_Request, pe, "Request", 0);
101:
102: if ((is = getisoserventbyname (myentity, myprovider)) == NULL)
103: adios (NULLCP, "%s/%s: unknown provider/entity pair",
104: myentity, myprovider);
105: rtz -> rta_port = is -> is_port; /* yikes! */
106: if ((is = getisoserventbyname ("rts", "ssap")) == NULL)
107: adios (NULLCP, "ssap/rts: unknown entity");
108: if ((sa = is2saddr (host, NULLCP, is)) == NULLSA)
109: adios (NULLCP, "address translation failed");
110: rtz -> rta_addr = *sa; /* struct copy */
111:
112: fprintf (stderr, "%s...", host);
113: (void) fflush (stderr);
114: if (RtBeginRequest (rtz, RTS_TWA, turn, pe, rtc, rti) == NOTOK) {
115: fprintf (stderr, "failed\n");
116: rts_adios (rta, "RT-BEGIN.REQUEST");
117: }
118:
119: pe_free (pe);
120: qb_free (req -> user);
121: qb_free (req -> password);
122: qb_free (req -> file);
123:
124: if (rtc -> rtc_result != RTS_ACCEPT) {
125: fprintf (stderr, "failed\n");
126: adios (NULLCP, "association rejected: [%s]",
127: RtErrString (rtc -> rtc_result));
128: }
129: fprintf (stderr, "connected\n");
130:
131: sd = rtc -> rtc_sd;
132:
133: RTCFREE (rtc);
134:
135: if (turn == RTS_INITIATOR) {
136: if (RtSetDownTrans (sd, downtrans, rti) == NOTOK)
137: rts_adios (rta, "set DownTrans upcall");
138:
139: if (RtTransferRequest (sd, NULLPE, NOTOK, rti) == NOTOK)
140: rts_adios (rta, "RT-TRANSFER.REQUEST");
141:
142: if (nbytes == 0)
143: advise (LLOG_NOTICE, NULLCP, "transfer complete");
144: else
145: timer (nbytes);
146:
147: (void) close (fd);
148: }
149: else {
150: if (RtSetUpTrans (sd, uptrans, rti) == NOTOK)
151: rts_adios (rta, "set UpTrans upcall");
152:
153: for (;;) {
154: switch (result = RtWaitRequest (sd, NOTOK, rti)) {
155: case NOTOK:
156: case OK:
157: case DONE:
158: break;
159:
160: default:
161: adios (NULLCP, "unknown return from RtWaitRequest=%d",
162: result);
163: }
164:
165: switch (rti -> rti_type) {
166: case RTI_TURN:
167: {
168: register struct RtSAPturn *rtu = &rti -> rti_turn;
169:
170: if (rtu -> rtu_please) {
171: if (RtGTurnRequest (sd, rti) == NOTOK)
172: rts_adios (rta, "RT-TURN-GIVE.REQUEST");
173: }
174: else
175: break;
176: }
177: continue;
178:
179: case RTI_TRANSFER:
180: {
181: #ifndef lint
182: register struct RtSAPtransfer *rtt =
183: &rti -> rti_transfer;
184: #endif
185:
186: if (nbytes == 0)
187: advise (LLOG_NOTICE, NULLCP, "transfer complete");
188: else
189: timer (nbytes);
190: if (RtPTurnRequest (sd, 1, rti) == NOTOK)
191: rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
192: }
193: continue;
194:
195: case RTI_ABORT:
196: {
197: register struct RtSAPabort *rtb = &rti -> rti_abort;
198:
199: if (rtb -> rta_peer)
200: rts_adios (rtb, "RT-U-ABORT.INDICATION");
201: if (RTS_FATAL (rtb -> rta_reason))
202: rts_adios (rtb, "RT-P-ABORT.INDICATION");
203: rts_advise (rtb, "RT-P-ABORT.INDICATION");
204: }
205: break;
206:
207: case RTI_CLOSE:
208: case RTI_FINISH:
209: adios (NULLCP, "unexpected indication type=%d",
210: rti -> rti_type);
211:
212: default:
213: adios (NULLCP, "unknown indication type=%d",
214: rti -> rti_type);
215: }
216: break;
217: }
218: }
219:
220: if (RtEndRequest (sd, rti) == NOTOK)
221: rts_adios (rta, "RT-END.REQUEST");
222:
223: exit (0);
224: }
225:
226: /* TRANSFER */
227:
228: /* ARGSUSED */
229:
230: static int downtrans (sd, base, len, size, ssn, ack, rti)
231: int sd;
232: char **base;
233: int *len,
234: size;
235: long ssn,
236: ack;
237: struct RtSAPindication *rti;
238: {
239: register int cc;
240: int n;
241: register char *dp,
242: *ep;
243: static int bsize;
244: static char *bp = NULL;
245:
246: if (base == NULLVP) {
247: #ifdef DEBUG
248: advise (LLOG_DEBUG, NULLCP, "RT-PLEASE.INDICATION: %d", size);
249: #endif
250: return OK;
251: }
252:
253: if (bp == NULL) {
254: struct stat st;
255:
256: if (fstat (fd, &st) == NOTOK)
257: return rtsaplose (rti, RTS_TRANSFER, source, "unable to fstat");
258: #ifdef MAXBSIZE
259: bsize = st.st_blksize > 0 ? st.st_blksize : BUFSIZ;
260: #else
261: bsize = BUFSIZ;
262: #endif
263: if (size == 0) /* no checkpointing... */
264: n = st.st_size;
265: else
266: if ((n = bsize) > size)
267: n = size;
268: if ((bp = malloc ((unsigned) n)) == NULL)
269: return rtsaplose (rti, RTS_CONGEST, NULLCP, "out of memory");
270: #ifdef DEBUG
271: advise (LLOG_DEBUG, NULLCP, "Selecting block size of %d", n);
272: advise (LLOG_DEBUG, NULLCP,
273: " based on blksize of %d and RTTR size of %d",
274: bsize, size);
275: #endif
276: bsize = n;
277: timer (nbytes = 0);
278: }
279:
280: *base = NULLCP, *len = 0;
281: for (ep = (dp = bp) + (cc = bsize); dp < ep; dp += n, cc -= n) {
282: switch (n = read (fd, dp, cc)) {
283: case NOTOK:
284: return rtsaplose (rti, RTS_TRANSFER, "failed", "read");
285:
286: default:
287: continue;
288:
289: case OK:
290: break;
291: }
292: break;
293: }
294: if ((cc = dp - bp) > 0) {
295: *base = bp, *len = cc;
296: nbytes += cc;
297: }
298:
299: return OK;
300: }
301:
302: /* */
303:
304: /* ARGSUSED */
305:
306: static int uptrans (sd, type, addr, rti)
307: int sd;
308: int type;
309: caddr_t addr;
310: struct RtSAPindication *rti;
311: {
312: switch (type) {
313: case SI_DATA:
314: {
315: register struct qbuf *qb = (struct qbuf *) addr;
316: register struct qbuf *qp;
317:
318: for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw)
319: if (write (fd, qp -> qb_data, qp -> qb_len) !=qp -> qb_len)
320: return rtsaplose (rti, RTS_TRANSFER, "failed","write");
321: else
322: nbytes += qp -> qb_len;
323: }
324: break;
325:
326: case SI_SYNC:
327: {
328: #ifdef DEBUG
329: register struct SSAPsync *sn = (struct SSAPsync *) addr;
330:
331: advise (LLOG_DEBUG, NULLCP, "S-MINOR-SYNC.INDICATION: %ld",
332: sn -> sn_ssn);
333: #endif
334: }
335: break;
336:
337: case SI_ACTIVITY:
338: {
339: register struct SSAPactivity *sv = (struct SSAPactivity *)addr;
340:
341: switch (sv -> sv_type) {
342: case SV_START:
343: #ifdef DEBUG
344: advise (LLOG_DEBUG, NULLCP,
345: "S-ACTIVITY-START.INDICATION");
346: #endif
347: if ((fd = creat (destination, 0666)) == NOTOK) {
348: advise (LLOG_EXCEPTIONS, destination,
349: "unable to create");
350: return rtsaplose (rti, RTS_TRANSFER, destination,
351: "unable to create");
352: }
353: timer (nbytes = 0);
354: break;
355:
356: case SV_INTRIND:
357: case SV_DISCIND:
358: advise (LLOG_EXCEPTIONS, NULLCP,
359: "activity %s: %s",
360: sv -> sv_type == SV_INTRIND ? "interrupted"
361: : "discarded",
362: SReportString (sv -> sv_reason));
363: if (unlink (destination) == NOTOK)
364: advise (LLOG_EXCEPTIONS, destination,
365: "unable to unlink");
366: break;
367:
368: case SV_ENDIND:
369: #ifdef DEBUG
370: advise (LLOG_DEBUG, NULLCP,
371: "S-ACTIVITY-END.INDICATION");
372: #endif
373: if (close (fd) == NOTOK)
374: return rtsaplose (rti, RTS_TRANSFER, destination,
375: "close failed on");
376: break;
377:
378: default:
379: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
380: "unexpected activity indication=0x%x",
381: sv -> sv_type);
382: }
383: }
384: break;
385:
386: case SI_REPORT:
387: {
388: register struct SSAPreport *sp = (struct SSAPreport *) addr;
389:
390: if (!sp -> sp_peer)
391: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
392: "unexpected provider-initiated exception report");
393: advise (LLOG_EXCEPTIONS, NULLCP,
394: "exception: %s", SReportString (sp -> sp_reason));
395: if (unlink (destination) == NOTOK)
396: advise (LLOG_EXCEPTIONS, destination, "unable to unlink");
397: }
398: break;
399:
400: default:
401: return rtsaplose (rti, RTS_TRANSFER, NULLCP,
402: "unknown uptrans type=0x%x", type);
403: }
404:
405: return OK;
406: }
407:
408: /* */
409:
410: static arginit (vec)
411: char **vec;
412: {
413: register char *ap;
414: char prompt[BUFSIZ];
415:
416: if (myname = rindex (*vec, '/'))
417: myname++;
418: if (myname == NULL || *myname == NULL)
419: myname = *vec;
420: if (strcmp (myname, "rtf") && strcmp (myname, "xrtf"))
421: host = myname, myname = "rtf";
422:
423: isodetailor (myname, 1);
424:
425: ll_hdinit (pgm_log, myname);
426: pgm_log -> ll_stat |= LLOGTTY;
427:
428: for (vec++; ap = *vec; vec++) {
429: if (*ap == '-')
430: switch (*++ap) {
431: case 'l':
432: if ((user = *++vec) == NULL || *user == '-')
433: adios (NULLCP, "usage: %s -l username", myname);
434: continue;
435:
436: default:
437: adios (NULLCP, "-%s: unknown switch", ap);
438: }
439:
440: if (host == NULL)
441: host = ap;
442: else
443: if (turn == NOTOK) {
444: if (strcmp (ap, "get") == 0)
445: turn = RTS_RESPONDER;
446: else
447: if (strcmp (ap, "put") == 0)
448: turn = RTS_INITIATOR;
449: else
450: goto usage;
451: }
452: else
453: if (source == NULL)
454: source = ap;
455: else
456: if (destination == NULL)
457: destination = ap;
458: else {
459: usage: ;
460: adios (NULLCP,
461: "usage: %s host [get|put] source destination",
462: myname);
463: }
464: }
465:
466: if (destination == NULL)
467: goto usage;
468:
469: if (user == NULL && (user = getenv ("USER")) == NULL)
470: user = getenv ("LOGNAME");
471: if (strcmp (user, "anon") == 0)
472: user = "ANON";
473:
474: if (password == NULL) {
475: if (strcmp (user, "ANON")) {
476: (void) sprintf (prompt, "password (%s:%s): ", host, user);
477: password = getpassword (prompt);
478: }
479: else
480: password = user ? user : "";
481: }
482: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.