Annotation of 43BSDReno/contrib/isode-beta/ftam2/ftamuser.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.