|
|
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.