|
|
1.1 ! root 1: /* ftamuser.c - FTAM initiator routines */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftamuser.c,v 7.2 90/07/01 21:03:37 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/ftam2/RCS/ftamuser.c,v 7.2 90/07/01 21:03:37 mrose Exp $ ! 9: * ! 10: * ! 11: * $Log: ftamuser.c,v $ ! 12: * Revision 7.2 90/07/01 21:03:37 mrose ! 13: * pepsy ! 14: * ! 15: * Revision 7.1 90/01/11 18:35:50 mrose ! 16: * real-sync ! 17: * ! 18: * Revision 7.0 89/11/23 21:54:42 mrose ! 19: * Release 6.0 ! 20: * ! 21: */ ! 22: ! 23: /* ! 24: * NOTICE ! 25: * ! 26: * Acquisition, use, and distribution of this module and related ! 27: * materials are subject to the restrictions of a license agreement. ! 28: * Consult the Preface in the User's Manual for the full terms of ! 29: * this agreement. ! 30: * ! 31: */ ! 32: ! 33: ! 34: #include <ctype.h> ! 35: #include <errno.h> ! 36: #include <stdio.h> ! 37: #include "ftamuser.h" ! 38: #include "tailor.h" ! 39: #if defined(SYS5) && !defined(HPUX) ! 40: #include <sys/times.h> ! 41: #define TMS ! 42: #endif ! 43: #ifdef BSD42 ! 44: #include <sys/ioctl.h> ! 45: #endif ! 46: ! 47: /* DATA */ ! 48: ! 49: int ftamfd = NOTOK; ! 50: ! 51: char *host = NULLCP; ! 52: char *user = NULLCP; ! 53: char *account = NULLCP; ! 54: #ifndef BRIDGE ! 55: char *storename = NULLCP; ! 56: #endif ! 57: ! 58: int bell = 0; ! 59: #ifndef BRIDGE ! 60: int debug = 0; ! 61: #endif ! 62: #ifdef BRIDGE ! 63: int globbing = 1; ! 64: #else ! 65: int globbing = 0; ! 66: #endif ! 67: int hash = 0; ! 68: int marks = 0; ! 69: int omode = FOVER_WRITE; ! 70: int query = 1; ! 71: int runcom = 0; ! 72: #ifdef BRIDGE ! 73: int tmode = VFS_UTF; ! 74: #else ! 75: int tmode = VFS_DEF; ! 76: #endif ! 77: int trace = 0; ! 78: #ifndef BRIDGE ! 79: int verbose = 0; ! 80: int watch = 0; ! 81: #endif ! 82: ! 83: ! 84: char *myuser = NULLCP; ! 85: char *myhome = NULLCP; ! 86: ! 87: #ifdef BRIDGE ! 88: int realstore = RFS_UNIX; ! 89: #else ! 90: int realstore = 0; ! 91: #endif ! 92: ! 93: char *rs_unknown = ! 94: "type of remote realstore is unknown; use \"set realstore\""; ! 95: char *rs_support = "operation not supported on remote realstore"; ! 96: ! 97: ! 98: char *rcwd = NULL; ! 99: ! 100: #ifdef BRIDGE ! 101: int ftp_default = VFS_UTF; ! 102: int ftp_directory; ! 103: char ftam_error[BUFSIZ]; ! 104: #endif ! 105: ! 106: struct QOStype myqos; ! 107: ! 108: /* DISPATCH */ ! 109: ! 110: #ifndef BRIDGE ! 111: int f_open (), f_close (), f_quit (), f_status (); ! 112: int f_set (), f_help (); ! 113: int f_lcd (), f_cd (), f_pwd (); ! 114: int f_ls (), f_fls (); ! 115: int f_get (), f_put (); ! 116: int f_mv (), f_rm (), f_chgrp (), f_mkdir (); ! 117: int f_echo (); ! 118: ! 119: ! 120: static struct dispatch dispatches[] = { ! 121: "append", f_put, DS_OPEN | DS_MODES, FCLASS_TRANSFER, FUNIT_WRITE, ! 122: "append to a file in the virtual filestore", ! 123: ! 124: "cd", f_cd, DS_OPEN, 0, 0, ! 125: "change working directory on virtual filestore", ! 126: ! 127: "chgrp", f_chgrp, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_ENHANCED, ! 128: "change group of a file", ! 129: ! 130: "close", f_close, DS_OPEN, 0, 0, ! 131: "terminate association with virtual filestore", ! 132: ! 133: "dir", f_ls, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 134: "print long directory listing", ! 135: ! 136: "echo", f_echo, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 137: "echo globbed filenames", ! 138: ! 139: "fdir", f_fls, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 140: "print long directory listing to a file/program", ! 141: ! 142: "fls", f_fls, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 143: "print directory listing to a file/program", ! 144: ! 145: "get", f_get, DS_OPEN | DS_MODES, FCLASS_TRANSFER, FUNIT_READ, ! 146: "retrieve file", ! 147: ! 148: "help", f_help, DS_NULL, 0, 0, ! 149: "print help information", ! 150: ! 151: "lcd", f_lcd, DS_NULL, 0, 0, ! 152: "change working directory on local system", ! 153: ! 154: "ls", f_ls, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 155: "print directory listing", ! 156: ! 157: "mkdir", f_mkdir, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 158: "create directory", ! 159: ! 160: "mv", f_mv, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_ENHANCED, ! 161: "rename file", ! 162: ! 163: "open", f_open, DS_CLOSE, 0, 0, ! 164: "associate with virtual filestore", ! 165: ! 166: "put", f_put, DS_OPEN | DS_MODES, FCLASS_TRANSFER, FUNIT_WRITE, ! 167: "store file", ! 168: ! 169: "pwd", f_pwd, DS_NULL, 0, 0, ! 170: "print working directories", ! 171: ! 172: "quit", f_quit, DS_NULL, 0, 0, ! 173: "terminate association with virtual filestore and exit", ! 174: ! 175: "rm", f_rm, DS_OPEN | DS_MODES, FCLASS_MANAGE, FUNIT_LIMITED, ! 176: "delete file", ! 177: ! 178: "set", f_set, DS_NULL, 0, 0, ! 179: "display or change variables", ! 180: ! 181: "status", f_status, DS_OPEN, 0, 0, ! 182: "show current status", ! 183: ! 184: NULL ! 185: }; ! 186: ! 187: /* */ ! 188: ! 189: struct dispatch *getds (name) ! 190: register char *name; ! 191: { ! 192: register int longest, ! 193: nmatches; ! 194: register char *p, ! 195: *q; ! 196: char buffer[BUFSIZ]; ! 197: register struct dispatch *ds, ! 198: *fs; ! 199: ! 200: longest = nmatches = 0; ! 201: for (ds = dispatches; p = ds -> ds_name; ds++) { ! 202: for (q = name; *q == *p++; q++) ! 203: if (*q == NULL) ! 204: return ds; ! 205: if (*q == NULL) ! 206: if (q - name > longest) { ! 207: longest = q - name; ! 208: nmatches = 1; ! 209: fs = ds; ! 210: } ! 211: else ! 212: if (q - name == longest) ! 213: nmatches++; ! 214: } ! 215: ! 216: switch (nmatches) { ! 217: case 0: ! 218: advise (NULLCP, "unknown operation \"%s\"", name); ! 219: return NULL; ! 220: ! 221: case 1: ! 222: return fs; ! 223: ! 224: default: ! 225: for (ds = dispatches, p = buffer; q = ds -> ds_name; ds++) ! 226: if (strncmp (q, name, longest) == 0) { ! 227: (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q); ! 228: p += strlen (p); ! 229: } ! 230: advise (NULLCP, "ambiguous operation, it could be one of:%s", ! 231: buffer); ! 232: return NULL; ! 233: } ! 234: } ! 235: #endif ! 236: ! 237: /* VARIABLES */ ! 238: ! 239: #ifndef BRIDGE ! 240: static char *bool[] = { ! 241: "off", "on", NULL ! 242: }; ! 243: ! 244: static char *hmodes[] = { ! 245: "off", "on", "total", NULL ! 246: }; ! 247: ! 248: static char *omodes[] = { ! 249: "fail", "select", "write", "delete", NULL ! 250: }; ! 251: ! 252: static char *tmodes[] = { ! 253: "default", "binary", "text", NULL ! 254: }; ! 255: ! 256: static char *realstores[] = { ! 257: "unknown", "unix", NULL ! 258: }; ! 259: ! 260: static char *xsaplevels[] = { ! 261: "none", "fatal", "exceptions", "notice", "pdus", "trace", "debug", NULL ! 262: }; ! 263: ! 264: ! 265: static char *sversions[] = { ! 266: "default", "v1", "v2", NULL ! 267: }; ! 268: ! 269: ! 270: struct var { ! 271: char *v_name; ! 272: IP v_value; ! 273: ! 274: char *v_dname; ! 275: char **v_dvalue; ! 276: char *v_mask; ! 277: ! 278: IFP v_hook; ! 279: }; ! 280: ! 281: struct var *getvar (); ! 282: ! 283: ! 284: int set_realstore (), set_trace (), set_type (); ! 285: ! 286: ! 287: static struct var vars[] = { ! 288: "acsaplevel", &_acsap_log.ll_events, "ACSAP logging", xsaplevels, ! 289: LLOG_MASK, NULLIFP, ! 290: "acsapfile", NULLIP, "ACSAP trace file", &_acsap_log.ll_file, NULLCP, ! 291: NULLIFP, ! 292: ! 293: "addrlevel", &_addr_log.ll_events, "address logging", xsaplevels, ! 294: LLOG_MASK, NULLIFP, ! 295: "addrfile", NULLIP, "address trace file", &_addr_log.ll_file, NULLCP, ! 296: NULLIFP, ! 297: ! 298: "bell", &bell, "ring the bell when a command finishes", bool, NULLCP, ! 299: NULLIFP, ! 300: ! 301: "compatlevel", &_compat_log.ll_events, "COMPAT logging", xsaplevels, ! 302: LLOG_MASK, NULLIFP, ! 303: "compatfile", NULLIP, "COMPAT trace file", &_compat_log.ll_file, NULLCP, ! 304: NULLIFP, ! 305: ! 306: "debug", &debug, "debug FTAM", bool, NULLCP, NULLIFP, ! 307: ! 308: "glob", &globbing, "expand metacharacters like the shell", bool, NULLCP, ! 309: NULLIFP, ! 310: ! 311: "hash", &hash, "hash mark printing", hmodes, NULLCP, NULLIFP, ! 312: ! 313: "override", &omode, "creation override mode", omodes, NULLCP, NULLIFP, ! 314: ! 315: "psaplevel", &_psap_log.ll_events, "PSAP logging", xsaplevels, ! 316: LLOG_MASK, NULLIFP, ! 317: "psapfile", NULLIP, "PSAP trace file", &_psap_log.ll_file, NULLCP, ! 318: NULLIFP, ! 319: ! 320: "psap2level", &_psap2_log.ll_events, "PSAP2 logging", xsaplevels, ! 321: LLOG_MASK, NULLIFP, ! 322: "psap2file", NULLIP, "PSAP2 trace file", &_psap2_log.ll_file, NULLCP, ! 323: NULLIFP, ! 324: ! 325: "qualifier", NULLIP, "service qualifier", &storename, NULLCP, NULLIFP, ! 326: ! 327: "query", &query, "confirm operations on globbing", bool, NULLCP, NULLIFP, ! 328: ! 329: "realstore", &realstore, "type of remote realstore", realstores, NULLCP, ! 330: set_realstore, ! 331: ! 332: "ssaplevel", &_ssap_log.ll_events, "SSAP logging", xsaplevels, ! 333: LLOG_MASK, NULLIFP, ! 334: "ssapfile", NULLIP, "SSAP trace file", &_ssap_log.ll_file, NULLCP, ! 335: NULLIFP, ! 336: ! 337: "sversion", &myqos.qos_sversion, "session version number", sversions, ! 338: NULLCP, NULLIFP, ! 339: ! 340: "trace", &trace, "trace FPDUs", bool, NULLCP, set_trace, ! 341: "tracefile", NULLIP, "FTAM trace file", &_ftam_log.ll_file, NULLCP, ! 342: NULLIFP, ! 343: ! 344: "tsaplevel", &_tsap_log.ll_events, "TSAP logging", xsaplevels, ! 345: LLOG_MASK, NULLIFP, ! 346: "tsapfile", NULLIP, "TSAP trace file", &_tsap_log.ll_file, NULLCP, ! 347: NULLIFP, ! 348: ! 349: "type", &tmode, "file transfer mode", tmodes, NULLCP, set_type, ! 350: ! 351: "verbose", &verbose, "verbose interaction", bool, NULLCP, NULLIFP, ! 352: ! 353: "watch", &watch, "watch transfers", bool, NULLCP, NULLIFP, ! 354: ! 355: NULL ! 356: }; ! 357: ! 358: ! 359: static int varwidth1; ! 360: static int varwidth2; ! 361: ! 362: char **getval (); ! 363: ! 364: /* */ ! 365: ! 366: static int f_set (vec) ! 367: char **vec; ! 368: { ! 369: register int i, ! 370: j; ! 371: int value, ! 372: vflag; ! 373: register char **cp, ! 374: *dp; ! 375: register struct var *v; ! 376: ! 377: if (*++vec == NULL) { ! 378: register int w; ! 379: int columns, ! 380: width, ! 381: lines; ! 382: register struct var *u; ! 383: ! 384: for (u = vars; u -> v_name; u++) ! 385: continue; ! 386: width = varwidth1; ! 387: ! 388: if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0) ! 389: columns = 1; ! 390: lines = ((u - vars) + columns - 1) / columns; ! 391: ! 392: printf ("Variables:\n"); ! 393: for (i = 0; i < lines; i++) ! 394: for (j = 0; j < columns; j++) { ! 395: v = vars + j * lines + i; ! 396: printf ("%s", v -> v_name); ! 397: if (v + lines >= u) { ! 398: printf ("\n"); ! 399: break; ! 400: } ! 401: for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7) ! 402: (void) putchar ('\t'); ! 403: } ! 404: ! 405: return OK; ! 406: } ! 407: ! 408: if (strcmp (*vec, "?") == 0) { ! 409: for (v = vars; v -> v_name; v++) ! 410: printvar (v); ! 411: ! 412: return OK; ! 413: } ! 414: ! 415: if ((v = getvar (*vec)) == NULL) ! 416: return OK; ! 417: ! 418: if (*++vec == NULL) { ! 419: printvar (v); ! 420: ! 421: return OK; ! 422: } ! 423: ! 424: if (strcmp (*vec, "?") == 0) { ! 425: if (v -> v_value && (cp = v -> v_dvalue)) { ! 426: printf ("use %s of:", v -> v_mask ? "any" : "one"); ! 427: for (i = 0; *cp; cp++) ! 428: printf ("%s \"%s\"", i++ ? "," : "", *cp); ! 429: if (v -> v_mask) ! 430: printf (";\n\tor \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n", ! 431: (1 << (i - 1)) - 1); ! 432: else ! 433: printf (";\n\tor a number from 0 to %d\n", ! 434: cp - v -> v_dvalue - 1); ! 435: } ! 436: else ! 437: printf ("use any %s value\n", ! 438: v -> v_value ? "integer" : "string"); ! 439: ! 440: return OK; ! 441: } ! 442: ! 443: if (v -> v_value == NULLIP) { ! 444: register int w; ! 445: ! 446: if (*v -> v_dvalue) ! 447: free (*v -> v_dvalue); ! 448: *v -> v_dvalue = strdup (*vec); ! 449: if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2) ! 450: varwidth2 = w; ! 451: if (v -> v_hook) ! 452: (*v -> v_hook) (v); ! 453: if (verbose) ! 454: printvar (v); ! 455: return OK; ! 456: } ! 457: ! 458: if (v -> v_mask) { ! 459: if (strcmp (dp = *vec, "all") == 0 && (cp = v -> v_dvalue)) { ! 460: i = 1; ! 461: while (*++cp) ! 462: i <<= 1; ! 463: value = i - 1; ! 464: j = 1; ! 465: } ! 466: else { ! 467: if (strncmp (dp, "0x", 2) == 0) ! 468: dp += 2; ! 469: for (j = sscanf (dp, "%x", &value); *dp; dp++) ! 470: if (!isxdigit (*dp)) { ! 471: j = 0; ! 472: break; ! 473: } ! 474: } ! 475: } ! 476: else ! 477: j = sscanf (*vec, "%d", &value); ! 478: ! 479: if (j == 1) { ! 480: if (cp = v -> v_dvalue) { ! 481: if (v -> v_mask) { ! 482: i = 1; ! 483: while (*++cp) ! 484: i <<= 1; ! 485: if (value >= i) ! 486: goto out_of_range; ! 487: } ! 488: else { ! 489: for (; *cp; cp++) ! 490: continue; ! 491: if (value >= cp - v -> v_dvalue) { ! 492: out_of_range: ; ! 493: advise (NULLCP, "value out of range \"%s\"", *vec); ! 494: ! 495: return OK; ! 496: } ! 497: } ! 498: } ! 499: ! 500: vflag = verbose; ! 501: *v -> v_value = value; ! 502: if (v -> v_hook) ! 503: (*v -> v_hook) (v); ! 504: if (vflag) ! 505: printvar (v); ! 506: ! 507: return OK; ! 508: } ! 509: ! 510: if (v -> v_mask) { ! 511: i = 0; ! 512: for (; *vec; vec++) { ! 513: if (!(cp = getval (*vec, v -> v_dvalue))) { ! 514: advise (NULLCP, "bad value \"%s\"", *vec); ! 515: ! 516: return OK; ! 517: } ! 518: if ((j = cp - v -> v_dvalue) <= 0) ! 519: continue; ! 520: ! 521: i |= 1 << (j - 1); ! 522: } ! 523: ! 524: vflag = verbose; ! 525: *v -> v_value = i; ! 526: if (v -> v_hook) ! 527: (*v -> v_hook) (v); ! 528: if (vflag) ! 529: printvar (v); ! 530: ! 531: return OK; ! 532: } ! 533: ! 534: if (v -> v_dvalue && (cp = getval (*vec, v -> v_dvalue))) { ! 535: vflag = verbose; ! 536: *v -> v_value = cp - v -> v_dvalue; ! 537: if (v -> v_hook) ! 538: (*v -> v_hook) (v); ! 539: if (vflag) ! 540: printvar (v); ! 541: } ! 542: else ! 543: if (!v -> v_dvalue) ! 544: advise (NULLCP, "bad value \"%s\"", *vec); ! 545: ! 546: return OK; ! 547: } ! 548: ! 549: /* */ ! 550: ! 551: static printvar (v) ! 552: register struct var *v; ! 553: { ! 554: int i; ! 555: char buffer[BUFSIZ]; ! 556: ! 557: if (runcom) ! 558: return; ! 559: ! 560: printf ("%-*s = ", varwidth1, v -> v_name); ! 561: if (v -> v_value) { ! 562: i = *v -> v_value; ! 563: ! 564: if (v -> v_mask) { ! 565: if (v -> v_dvalue) { ! 566: if (i == 0) ! 567: printf ("%-*s", varwidth2, v -> v_dvalue[i]); ! 568: else { ! 569: (void) strcpy (buffer, sprintb (i, v -> v_mask)); ! 570: if (strlen (buffer) <= varwidth2) ! 571: printf ("%-*s", varwidth2, buffer); ! 572: else ! 573: printf ("%s\n%*s", buffer, varwidth1 + varwidth2 + 3, ! 574: ""); ! 575: } ! 576: } ! 577: else ! 578: printf ("0x%-*x", varwidth2 - 2, i); ! 579: } ! 580: else { ! 581: if (v -> v_dvalue) ! 582: printf ("%-*s", varwidth2, v -> v_dvalue[i]); ! 583: else ! 584: printf ("%-*d", varwidth2, i); ! 585: } ! 586: } ! 587: else ! 588: if (*v -> v_dvalue) { ! 589: (void) sprintf (buffer, "\"%s\"", *v -> v_dvalue); ! 590: printf ("%-*s", varwidth2, buffer); ! 591: } ! 592: printf (" - %s\n", v -> v_dname); ! 593: } ! 594: ! 595: /* */ ! 596: ! 597: /* ARGSUSED */ ! 598: ! 599: static int set_realstore (v) ! 600: struct var *v; ! 601: { ! 602: char *vec[2]; ! 603: ! 604: if (ftamfd != NOTOK) { ! 605: vec[0] = "sd"; ! 606: vec[1] = NULLCP; ! 607: ! 608: (void) f_cd (vec); ! 609: } ! 610: } ! 611: ! 612: ! 613: ! 614: /* ARGSUSED */ ! 615: ! 616: static int set_trace (v) ! 617: struct var *v; ! 618: { ! 619: struct FTAMindication ftis; ! 620: register struct FTAMindication *fti = &ftis; ! 621: ! 622: if (ftamfd == NOTOK) ! 623: return; ! 624: ! 625: if (FHookRequest (ftamfd, trace ? FTraceHook : NULLIFP, fti) == NOTOK) ! 626: ftam_advise (&fti -> fti_abort, "F-HOOK.REQUEST"); ! 627: } ! 628: ! 629: ! 630: /* ARGSUSED */ ! 631: ! 632: static int set_type (v) ! 633: struct var *v; ! 634: { ! 635: register struct vfsmap *vf; ! 636: ! 637: if (ftamfd == NOTOK) ! 638: return; ! 639: ! 640: if ((vf = &vfs[tmode]) != &vfs[VFS_DEF] ! 641: && (vf -> vf_oid == NULLOID || !(vf -> vf_flags & VF_OK))) { ! 642: advise (NULLCP, "negotiation prevents transfer of %ss", ! 643: vf -> vf_text); ! 644: ! 645: tmode = VFS_DEF; ! 646: } ! 647: } ! 648: ! 649: /* */ ! 650: ! 651: static char **getval (name, choices) ! 652: register char *name; ! 653: char **choices; ! 654: { ! 655: register int longest, ! 656: nmatches; ! 657: register char *p, ! 658: *q, ! 659: **cp, ! 660: **fp; ! 661: char buffer[BUFSIZ]; ! 662: ! 663: longest = nmatches = 0; ! 664: for (cp = choices; p = *cp; cp++) { ! 665: for (q = name; *q == *p++; q++) ! 666: if (*q == NULL) ! 667: return cp; ! 668: if (*q == NULL) ! 669: if (q - name > longest) { ! 670: longest = q - name; ! 671: nmatches = 1; ! 672: fp = cp; ! 673: } ! 674: else ! 675: if (q - name == longest) ! 676: nmatches++; ! 677: } ! 678: ! 679: switch (nmatches) { ! 680: case 0: ! 681: advise (NULLCP, "unknown value \"%s\"", name); ! 682: return NULL; ! 683: ! 684: case 1: ! 685: return fp; ! 686: ! 687: default: ! 688: for (cp = choices, p = buffer; q = *cp; cp++) ! 689: if (strncmp (q, name, longest) == 0) { ! 690: (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q); ! 691: p += strlen (p); ! 692: } ! 693: advise (NULLCP, "ambiguous value, it could be one of:%s", ! 694: buffer); ! 695: return NULL; ! 696: } ! 697: } ! 698: ! 699: /* */ ! 700: ! 701: static struct var *getvar (name) ! 702: register char *name; ! 703: { ! 704: register int longest, ! 705: nmatches; ! 706: register char *p, ! 707: *q; ! 708: char buffer[BUFSIZ]; ! 709: register struct var *v, ! 710: *f; ! 711: ! 712: longest = nmatches = 0; ! 713: for (v = vars; p = v -> v_name; v++) { ! 714: for (q = name; *q == *p++; q++) ! 715: if (*q == NULL) ! 716: return v; ! 717: if (*q == NULL) ! 718: if (q - name > longest) { ! 719: longest = q - name; ! 720: nmatches = 1; ! 721: f = v; ! 722: } ! 723: else ! 724: if (q - name == longest) ! 725: nmatches++; ! 726: } ! 727: ! 728: switch (nmatches) { ! 729: case 0: ! 730: advise (NULLCP, "unknown variable \"%s\"", name); ! 731: return NULL; ! 732: ! 733: case 1: ! 734: return f; ! 735: ! 736: default: ! 737: for (v = vars, p = buffer; q = v -> v_name; v++) ! 738: if (strncmp (q, name, longest) == 0) { ! 739: (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q); ! 740: p += strlen (p); ! 741: } ! 742: advise (NULLCP, "ambiguous variable, it could be one of:%s", ! 743: buffer); ! 744: return NULL; ! 745: } ! 746: } ! 747: ! 748: /* HELP */ ! 749: ! 750: static int helpwidth; ! 751: ! 752: /* */ ! 753: ! 754: static int f_help (vec) ! 755: char **vec; ! 756: { ! 757: register int i, ! 758: j, ! 759: w; ! 760: int columns, ! 761: width, ! 762: lines; ! 763: register struct dispatch *ds, ! 764: *es; ! 765: ! 766: for (es = dispatches; es -> ds_name; es++) ! 767: continue; ! 768: width = helpwidth; ! 769: ! 770: if (*++vec == NULL) { ! 771: if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0) ! 772: columns = 1; ! 773: lines = ((es - dispatches) + columns - 1) / columns; ! 774: ! 775: printf ("Operations:\n"); ! 776: for (i = 0; i < lines; i++) ! 777: for (j = 0; j < columns; j++) { ! 778: ds = dispatches + j * lines + i; ! 779: printf ("%s", ds -> ds_name); ! 780: if (ds + lines >= es) { ! 781: printf ("\n"); ! 782: break; ! 783: } ! 784: for (w = strlen (ds -> ds_name); w < width; w = (w + 8) & ~7) ! 785: (void) putchar ('\t'); ! 786: } ! 787: ! 788: printf ("\nversion info:\t%s\n\t\t%s\n", ftamversion, isodeversion); ! 789: ! 790: return OK; ! 791: } ! 792: ! 793: for (; *vec; vec++) ! 794: if (strcmp (*vec, "?") == 0) { ! 795: for (ds = dispatches; ds -> ds_name; ds++) ! 796: printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help); ! 797: ! 798: break; ! 799: } ! 800: else ! 801: if (ds = getds (*vec)) ! 802: printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help); ! 803: ! 804: return OK; ! 805: } ! 806: #endif ! 807: ! 808: /* FTAM */ ! 809: ! 810: /* When going from an FADU to an SSDU via FTAM, we are talking about: ! 811: ! 812: octets = 2 + <number of FADUs>*12 + <size of each FADU> ! 813: ! 814: in the best case, and probably ! 815: ! 816: octets = 3 + <number of FADUs>*16 + <size of each FADU> ! 817: ! 818: on the average. ! 819: ! 820: On a Berkeley UNIX system we typically see a blksize of 8192 octets. ! 821: ! 822: When deciding how to read from the filesystem when writing to the network, ! 823: for the file's FADU size, we prefer to use the integral FADU size, ! 824: unless the blksize is larger. This works well on LANs. ! 825: */ ! 826: ! 827: OID context; ! 828: int fqos; ! 829: int class = FCLASS_TRANSFER | FCLASS_MANAGE | FCLASS_TM; ! 830: int units; ! 831: int attrs; ! 832: int fadusize; ! 833: ! 834: ! 835: struct vfsmap vfs[] = { ! 836: /* VFS_DEF */ ! 837: "default", NULLOID, NULLCP, VF_NULL, 0, 0, NULLIFP, ' ', VFS_XXX, ! 838: 0, ! 839: 0, NULLIFP, ! 840: -1, ! 841: NULLCP, ! 842: ! 843: /* VFS_UBF */ ! 844: "FTAM-3", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, binarypeek, 'b', VFS_XXX, ! 845: FA_ACC_UA, ! 846: 1, binarycheck, ! 847: _ZFTAM_3_ParametersDOCS, ! 848: "unstructured binary file", ! 849: ! 850: /* VFS_UTF */ ! 851: "FTAM-1", NULLOID, NULLCP, VF_WARN, 0, S_IFREG, textpeek, 't', VFS_UBF, ! 852: FA_ACC_UA, ! 853: 1, textcheck, ! 854: _ZFTAM_1_ParametersDOCS, ! 855: "unstructured text file", ! 856: ! 857: /* VFS_FDF */ ! 858: "NBS-9", NULLOID, NULLCP, VF_NULL, 0, S_IFDIR, fdfpeek, 'd', VFS_XXX, ! 859: FA_ACC_UA, ! 860: 0, NULLIFP, ! 861: _ZNBS_9_ParametersDOCS, ! 862: "file directory file", ! 863: ! 864: NULL ! 865: }; ! 866: #ifdef BRIDGE ! 867: int vfs_fdf = VFS_FDF; ! 868: #endif ! 869: ! 870: struct vfsmap *myvf; ! 871: ! 872: /* */ ! 873: ! 874: void ftam_advise (fta, event) ! 875: register struct FTAMabort *fta; ! 876: char *event; ! 877: { ! 878: if (hash && marks >= BUFSIZ) { ! 879: marks = 0; ! 880: printf ("\n"); ! 881: } ! 882: ! 883: (void) fflush (stdout); ! 884: ! 885: if (fta -> fta_peer) { ! 886: #ifdef BRIDGE ! 887: (void) sprintf (ftam_error, "%s: peer aborted association, due to ", ! 888: event); ! 889: #else ! 890: fprintf (stderr, "%s: peer aborted association, due to ", event); ! 891: #endif ! 892: switch (fta -> fta_action) { ! 893: case FACTION_TRANS: ! 894: #ifdef BRIDGE ! 895: (void) sprintf (ftam_error + strlen (ftam_error), ! 896: "transient-error"); ! 897: #else ! 898: fprintf (stderr, "transient-error"); ! 899: #endif ! 900: break; ! 901: ! 902: case FACTION_PERM: ! 903: #ifdef BRIDGE ! 904: (void) sprintf (ftam_error + strlen (ftam_error), ! 905: "permanent-error"); ! 906: #else ! 907: fprintf (stderr, "permanent-error"); ! 908: #endif ! 909: break; ! 910: ! 911: default: ! 912: #ifdef BRIDGE ! 913: (void) sprintf (ftam_error + strlen (ftam_error), ! 914: "action result %d", fta -> fta_action); ! 915: #else ! 916: fprintf (stderr, "action result %d", fta -> fta_action); ! 917: #endif ! 918: break; ! 919: } ! 920: #ifndef BRIDGE ! 921: fprintf (stderr, "\n"); ! 922: #endif ! 923: } ! 924: else ! 925: #ifdef BRIDGE ! 926: (void) sprintf (ftam_error + strlen (ftam_error), "%s: failed\n", ! 927: event); ! 928: if (verbose) ! 929: advise (NULLCP, "%s", ftam_error); ! 930: #else ! 931: fprintf (stderr, "%s: failed\n", event); ! 932: #endif ! 933: ftam_diag (fta -> fta_diags, fta -> fta_ndiag, fta -> fta_peer, ! 934: FACTION_PERM); ! 935: ! 936: if (fta -> fta_action == FACTION_PERM) { ! 937: ftamfd = NOTOK; ! 938: if (rcwd) { ! 939: free (rcwd); ! 940: rcwd = NULL; ! 941: } ! 942: } ! 943: } ! 944: ! 945: /* */ ! 946: ! 947: void ftam_chrg (charges) ! 948: register struct FTAMcharging *charges; ! 949: { ! 950: register int i; ! 951: char *cp; ! 952: register struct fc_charge *fc; ! 953: ! 954: cp = "charging information:\n %s: %d %s\n"; ! 955: for (fc = charges -> fc_charges, i = charges -> fc_ncharge - 1; ! 956: i >= 0; ! 957: fc++, i--, cp = " %s: %d %s\n") ! 958: #ifdef BRIDGE ! 959: (void) sprintf (ftam_error, cp, fc -> fc_resource, fc -> fc_value, ! 960: fc -> fc_unit); ! 961: advise (NULLCP, "%s", ftam_error); ! 962: #else ! 963: printf (cp, fc -> fc_resource, fc -> fc_value, fc -> fc_unit); ! 964: #endif ! 965: } ! 966: ! 967: /* */ ! 968: ! 969: static char *entity[] = { ! 970: "unknown", ! 971: "initiator", ! 972: "initiator's FPM", ! 973: "virtual filestore", ! 974: "responder's FPM", ! 975: "responder" ! 976: }; ! 977: ! 978: ! 979: void ftam_diag (diag, ndiag, peer, action) ! 980: struct FTAMdiagnostic diag[]; ! 981: int ndiag; ! 982: int peer, ! 983: action; ! 984: { ! 985: register int i; ! 986: int didit; ! 987: register struct FTAMdiagnostic *dp; ! 988: ! 989: #ifdef BRIDGE ! 990: ftam_error[0] = NULL; ! 991: #endif ! 992: for (dp = diag, i = ndiag - 1; i >= 0; dp++, i--) { ! 993: if (dp -> ftd_identifier != FS_GEN_NOREASON) { ! 994: #ifdef BRIDGE ! 995: (void) sprintf (ftam_error + strlen (ftam_error), ! 996: "%s", FErrString (dp -> ftd_identifier)); ! 997: #else ! 998: printf ("%s", FErrString (dp -> ftd_identifier)); ! 999: #endif ! 1000: if (dp -> ftd_cc > 0) ! 1001: #ifdef BRIDGE ! 1002: (void) sprintf (ftam_error + strlen (ftam_error), ! 1003: ": %*.*s", dp -> ftd_cc, dp -> ftd_cc, ! 1004: dp -> ftd_data); ! 1005: #else ! 1006: printf (": %*.*s", dp -> ftd_cc, dp -> ftd_cc, dp -> ftd_data); ! 1007: #endif ! 1008: } ! 1009: else ! 1010: if (dp -> ftd_cc > 0) ! 1011: #ifdef BRIDGE ! 1012: (void) sprintf (ftam_error + strlen (ftam_error), ! 1013: "%*.*s", dp -> ftd_cc, dp -> ftd_cc, ! 1014: dp -> ftd_data); ! 1015: #else ! 1016: printf ("%*.*s", dp -> ftd_cc, dp -> ftd_cc, dp -> ftd_data); ! 1017: #endif ! 1018: ! 1019: #ifdef BRIDGE ! 1020: advise (NULLCP, "%s", ftam_error); ! 1021: #else ! 1022: printf ("\n"); ! 1023: #endif ! 1024: ! 1025: didit = 0; ! 1026: switch (dp -> ftd_type) { ! 1027: case DIAG_INFORM: ! 1028: if (action == FACTION_SUCCESS) ! 1029: break; ! 1030: didit++; ! 1031: #ifdef BRIDGE ! 1032: (void) sprintf (ftam_error + strlen (ftam_error), ! 1033: " type informative"); ! 1034: #else ! 1035: printf (" type informative"); ! 1036: #endif ! 1037: break; ! 1038: ! 1039: case DIAG_TRANS: ! 1040: didit++; ! 1041: #ifdef BRIDGE ! 1042: (void) sprintf (ftam_error + strlen (ftam_error), ! 1043: " type transient"); ! 1044: #else ! 1045: printf (" type transient"); ! 1046: #endif ! 1047: break; ! 1048: ! 1049: case DIAG_PERM: ! 1050: if (dp -> ftd_observer == EREF_IFSU) ! 1051: ftamfd = NOTOK; ! 1052: if (action != FACTION_SUCCESS) ! 1053: break; ! 1054: didit++; ! 1055: #ifdef BRIDGE ! 1056: (void) sprintf (ftam_error + strlen (ftam_error), ! 1057: " type permanent"); ! 1058: #else ! 1059: printf (" type permanent"); ! 1060: #endif ! 1061: break; ! 1062: ! 1063: default: ! 1064: didit++; ! 1065: #ifdef BRIDGE ! 1066: (void) sprintf (ftam_error + strlen (ftam_error), ! 1067: " type %d", dp -> ftd_type); ! 1068: #else ! 1069: printf (" type %d", dp -> ftd_type); ! 1070: #endif ! 1071: break; ! 1072: } ! 1073: ! 1074: switch (dp -> ftd_observer) { ! 1075: case EREF_IFSU: ! 1076: goto print_it; ! 1077: ! 1078: case EREF_IFPM: ! 1079: if (peer) ! 1080: goto print_it; ! 1081: break; ! 1082: ! 1083: case EREF_RFSU: ! 1084: if (peer) ! 1085: break; /* else fall */ ! 1086: case EREF_RFPM: ! 1087: print_it: ; ! 1088: #ifdef BRIDGE ! 1089: (void) sprintf (ftam_error + strlen (ftam_error), ! 1090: "%sobserver %s", didit++ ? ", " : " ", ! 1091: entity[dp -> ftd_observer]); ! 1092: #else ! 1093: printf ("%sobserver %s", didit++ ? ", " : " ", ! 1094: entity[dp -> ftd_observer]); ! 1095: #endif ! 1096: break; ! 1097: ! 1098: default: ! 1099: #ifdef BRIDGE ! 1100: (void) sprintf (ftam_error + strlen (ftam_error), ! 1101: "%sobserver %d", didit++ ? ", " : " ", ! 1102: dp -> ftd_observer); ! 1103: #else ! 1104: printf ("%sobserver %d", didit++ ? ", " : " ", ! 1105: dp -> ftd_observer); ! 1106: #endif ! 1107: break; ! 1108: } ! 1109: ! 1110: switch (dp -> ftd_source) { ! 1111: case EREF_NONE: ! 1112: case EREF_IFSU: ! 1113: break; ! 1114: ! 1115: case EREF_SERV: ! 1116: case EREF_RFSU: ! 1117: if (peer) ! 1118: break; /* else fall */ ! 1119: case EREF_IFPM: ! 1120: case EREF_RFPM: ! 1121: #ifdef BRIDGE ! 1122: (void) sprintf (ftam_error + strlen (ftam_error), ! 1123: "%ssource %s", didit++ ? ", " : " ", ! 1124: entity[dp -> ftd_source]); ! 1125: #else ! 1126: printf ("%ssource %s", didit++ ? ", " : " ", ! 1127: entity[dp -> ftd_source]); ! 1128: #endif ! 1129: break; ! 1130: ! 1131: default: ! 1132: #ifdef BRIDGE ! 1133: (void) sprintf (ftam_error + strlen (ftam_error), ! 1134: "%ssource %d", didit++ ? ", " : " ", ! 1135: dp -> ftd_source); ! 1136: #else ! 1137: printf ("%ssource %d", didit++ ? ", " : " ", ! 1138: dp -> ftd_source); ! 1139: #endif ! 1140: break; ! 1141: } ! 1142: ! 1143: if (dp -> ftd_delay != DIAG_NODELAY) ! 1144: #ifdef BRIDGE ! 1145: (void) sprintf (ftam_error + strlen (ftam_error), ! 1146: "%ssuggested-delay %d", didit++ ? ", " : " ", ! 1147: dp -> ftd_delay); ! 1148: #else ! 1149: printf ("%ssuggested-delay %d", didit++ ? ", " : " ", ! 1150: dp -> ftd_delay); ! 1151: #endif ! 1152: ! 1153: #ifndef BRIDGE ! 1154: if (didit) ! 1155: printf ("\n"); ! 1156: #endif ! 1157: } ! 1158: #ifdef BRIDGE ! 1159: if (ftam_error[0]) ! 1160: advise (NULLCP, "%s", ftam_error); ! 1161: #endif ! 1162: } ! 1163: ! 1164: /* MISCELLANY */ ! 1165: ! 1166: rcinit () ! 1167: { ! 1168: #ifndef BRIDGE ! 1169: register int w; ! 1170: register char **cp; ! 1171: register struct dispatch *ds; ! 1172: register struct var *v; ! 1173: #endif ! 1174: register struct isodocument *id; ! 1175: register struct vfsmap *vf; ! 1176: ! 1177: #ifndef BRIDGE ! 1178: if ((myhome = getenv ("HOME")) == NULL) ! 1179: myhome = "."; /* could do passwd search... */ ! 1180: ! 1181: if ((myuser = getenv ("USER")) == NULLCP) ! 1182: myuser = getenv ("LOGNAME"); ! 1183: #endif ! 1184: ! 1185: for (vf = vfs + 1; vf -> vf_entry; vf++) /* skip "default" entry */ ! 1186: if (id = getisodocumentbyentry (vf -> vf_entry)) { ! 1187: if ((vf -> vf_oid = oid_cpy (id -> id_type)) == NULLOID) ! 1188: adios (NULLCP, "out of memory"); ! 1189: } ! 1190: else ! 1191: if (vf -> vf_flags & VF_WARN) ! 1192: advise (NULLCP, ! 1193: "warning: local realstore has no support for %ss (%s)", ! 1194: vf -> vf_text, vf -> vf_entry); ! 1195: ! 1196: bzero ((char *) &myqos, sizeof myqos); ! 1197: myqos.qos_sversion = 2; ! 1198: ! 1199: #ifndef BRIDGE ! 1200: for (ds = dispatches, helpwidth = 0; ds -> ds_name; ds++) ! 1201: if ((w = strlen (ds -> ds_name)) > helpwidth) ! 1202: helpwidth = w; ! 1203: ! 1204: for (v = vars, varwidth1 = 0; v -> v_name; v++) { ! 1205: if ((w = strlen (v -> v_name)) > varwidth1) ! 1206: varwidth1 = w; ! 1207: ! 1208: if (v -> v_value) { ! 1209: if (cp = v -> v_dvalue) { ! 1210: if (v -> v_mask) { ! 1211: #ifdef notdef ! 1212: w = 1; ! 1213: while (*++cp) ! 1214: w <<= 1; ! 1215: w--; ! 1216: if ((w = strlen (sprintb (w, v -> v_mask))) > varwidth2) ! 1217: varwidth2 = w; ! 1218: #endif ! 1219: } ! 1220: else ! 1221: for (; *cp; cp++) ! 1222: if ((w = strlen (*cp)) > varwidth2) ! 1223: varwidth2 = w; ! 1224: } ! 1225: } ! 1226: else ! 1227: if (*v -> v_dvalue) { ! 1228: *v -> v_dvalue = strdup (*v -> v_dvalue); ! 1229: if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2) ! 1230: varwidth2 = w; ! 1231: } ! 1232: } ! 1233: #endif ! 1234: } ! 1235: ! 1236: ! 1237: #ifndef TIOCGWINSZ ! 1238: /* ARGSUSED */ ! 1239: #endif ! 1240: ! 1241: int ncols (fp) ! 1242: FILE *fp; ! 1243: { ! 1244: #ifdef TIOCGWINSZ ! 1245: int i; ! 1246: struct winsize ws; ! 1247: ! 1248: if (ioctl (fileno (fp), TIOCGWINSZ, (char *) &ws) != NOTOK ! 1249: && (i = ws.ws_col) > 0) ! 1250: return i; ! 1251: #endif ! 1252: ! 1253: return 80; ! 1254: } ! 1255: ! 1256: /* */ ! 1257: ! 1258: #ifndef NBBY ! 1259: #define NBBY 8 ! 1260: #endif ! 1261: ! 1262: ! 1263: #ifndef TMS ! 1264: timer (cc, action) ! 1265: int cc; ! 1266: char *action; ! 1267: { ! 1268: long ms; ! 1269: float bs; ! 1270: struct timeval stop, ! 1271: td; ! 1272: static struct timeval start; ! 1273: ! 1274: if (cc == 0) { ! 1275: (void) gettimeofday (&start, (struct timezone *) 0); ! 1276: return; ! 1277: } ! 1278: else ! 1279: (void) gettimeofday (&stop, (struct timezone *) 0); ! 1280: ! 1281: tvsub (&td, &stop, &start); ! 1282: ms = (td.tv_sec * 1000) + (td.tv_usec / 1000); ! 1283: bs = (((float) cc * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; ! 1284: ! 1285: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)", ! 1286: cc, action, td.tv_sec, td.tv_usec / 10000, bs / 1024); ! 1287: } ! 1288: ! 1289: ! 1290: static tvsub (tdiff, t1, t0) ! 1291: register struct timeval *tdiff, ! 1292: *t1, ! 1293: *t0; ! 1294: { ! 1295: ! 1296: tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec; ! 1297: tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec; ! 1298: if (tdiff -> tv_usec < 0) ! 1299: tdiff -> tv_sec--, tdiff -> tv_usec += 1000000; ! 1300: } ! 1301: ! 1302: #else ! 1303: #ifndef HZ ! 1304: #define HZ 60 ! 1305: #endif ! 1306: ! 1307: ! 1308: long times (); ! 1309: ! 1310: ! 1311: timer (cc, action) ! 1312: int cc; ! 1313: char *action; ! 1314: { ! 1315: long ms; ! 1316: float bs; ! 1317: long stop, ! 1318: td, ! 1319: secs, ! 1320: msecs; ! 1321: struct tms tm; ! 1322: static long start; ! 1323: ! 1324: if (cc == 0) { ! 1325: start = times (&tm); ! 1326: return; ! 1327: } ! 1328: else ! 1329: stop = times (&tm); ! 1330: ! 1331: td = stop - start; ! 1332: secs = td / HZ, msecs = (td % HZ) * 1000 / HZ; ! 1333: ms = (secs * 1000) + msecs; ! 1334: bs = (((float) cc * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY; ! 1335: ! 1336: advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)", ! 1337: cc, action, secs, msecs / 10, bs / 1024); ! 1338: } ! 1339: #endif ! 1340: ! 1341: /* */ ! 1342: ! 1343: #ifdef BRIDGE ! 1344: /* FTP TYPE Function */ ! 1345: ! 1346: #include <arpa/ftp.h> ! 1347: ! 1348: f_type (mode) ! 1349: int mode; ! 1350: { ! 1351: switch(mode) { ! 1352: case TYPE_A: ! 1353: tmode = VFS_UTF; ! 1354: return OK; ! 1355: ! 1356: case TYPE_I: ! 1357: case TYPE_L: ! 1358: tmode = VFS_UBF; ! 1359: return OK; ! 1360: ! 1361: case TYPE_E: ! 1362: default: ! 1363: return NOTOK; ! 1364: } ! 1365: } ! 1366: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.