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

1.1       root        1: /* ftamd-select.c - FTAM responder -- selection regime */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/ftam2/RCS/ftamd-select.c,v 7.1 90/07/01 21:03:20 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/ftam2/RCS/ftamd-select.c,v 7.1 90/07/01 21:03:20 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       ftamd-select.c,v $
                     12:  * Revision 7.1  90/07/01  21:03:20  mrose
                     13:  * pepsy
                     14:  * 
                     15:  * Revision 7.0  89/11/23  21:54:29  mrose
                     16:  * Release 6.0
                     17:  * 
                     18:  */
                     19: 
                     20: /*
                     21:  *                               NOTICE
                     22:  *
                     23:  *    Acquisition, use, and distribution of this module and related
                     24:  *    materials are subject to the restrictions of a license agreement.
                     25:  *    Consult the Preface in the User's Manual for the full terms of
                     26:  *    this agreement.
                     27:  *
                     28:  */
                     29: 
                     30: 
                     31: #include <grp.h>
                     32: #include <stdio.h>
                     33: #include <pwd.h>
                     34: #include "ftamsystem.h"
                     35: 
                     36: 
                     37: #define        NUID    400
                     38: #define        NGID    400
                     39: 
                     40: 
                     41: #define        FA_CHATTR \
                     42:     (FA_FILENAME | FA_ACCOUNT)
                     43: 
                     44: 
                     45: #define        FA_PERM_WRITE   (FA_PERM_INSERT | FA_PERM_REPLACE | FA_PERM_EXTEND \
                     46:                                | FA_PERM_ERASE)
                     47: #define        FA_PERM_OWNER   FA_PERM_CHNGATTR
                     48: #define        FA_PERM_PARENT  FA_PERM_DELETE
                     49: 
                     50: 
                     51: #ifdef SYS5
                     52: struct group  *getgrnam ();
                     53: struct passwd *getpwnam (), *getpwent (), *getpwuid ();
                     54: #endif
                     55: 
                     56: /*    DATA */
                     57: 
                     58: static char mvfile[MAXPATHLEN];
                     59: static PE   rdparam = NULLPE;
                     60: 
                     61: char   *getfile ();
                     62: #ifdef BRIDGE
                     63: #define        E_OK    R_OK
                     64: #else
                     65: char   *getuser (), *getgroup ();
                     66: #endif
                     67: 
                     68: 
                     69: long   lseek ();
                     70: 
                     71: #ifdef SYS5
                     72: #define        EACCESS access
                     73: 
                     74: #define        rename(f1,f2)   \
                     75:        (unlink (f2), link (f1, f2) != NOTOK ? unlink (f1) : NOTOK)
                     76: #endif
                     77: 
                     78: #ifdef BRIDGE
                     79: #define        ftp_access(file,mode)   ftp_exist (file)
                     80: #endif
                     81: 
                     82: /*    SELECTION REGIME */
                     83: 
                     84: int    ftam_selection (ftg, ftm)
                     85: register struct FTAMgroup *ftg,
                     86:                          *ftm;
                     87: {
                     88:     int     action,
                     89:             state;
                     90: 
                     91:     bzero ((char *) ftm, sizeof *ftm);
                     92:     ftm -> ftg_flags = ftg -> ftg_flags;
                     93: 
                     94:     statok = 0;
                     95: 
                     96:     state = FSTATE_SUCCESS;
                     97:     if (ftg -> ftg_flags & FTG_SELECT) {
                     98:        register struct FTAMselect *ftse = &ftg -> ftg_select;
                     99:        register struct FTAMattributes *fa = &ftse -> ftse_attrs;
                    100:        struct FTAMdiagnostic *dp = ftm -> ftg_select.ftse_diags;
                    101: 
                    102:        errno = 0;
                    103:        if (!(fa -> fa_present & FA_FILENAME)
                    104:                || fa -> fa_nfile != 1
                    105:                || (myfile = getfile (fa -> fa_files[0])) == NULL
                    106: #ifdef BRIDGE
                    107:                || ftp_access (myfile, E_OK) == NOTOK) {
                    108: #else
                    109:                || stat (myfile, &myst) == NOTOK) {
                    110: #endif
                    111:            dp -> ftd_type = DIAG_PERM;
                    112:            dp -> ftd_identifier = FS_SEL_FILENAME;
                    113:            dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    114:            dp -> ftd_delay = DIAG_NODELAY;
                    115:            if (errno) {
                    116:                (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    117:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    118:            }
                    119:            else
                    120:                dp -> ftd_cc = 0;
                    121:            dp++;
                    122: 
                    123:            state = FSTATE_FAILURE;
                    124:            goto done_select;
                    125:        }
                    126:        statok = 1;
                    127: #ifndef        BRIDGE
                    128:        switch (myst.st_mode & S_IFMT) {
                    129:            case S_IFREG: 
                    130:            case S_IFDIR: 
                    131:                break;
                    132: 
                    133:            default:
                    134:                if (myst.st_dev == null_dev && myst.st_ino == null_ino) {
                    135:                    myst.st_mode &= ~S_IFMT, myst.st_mode |= S_IFREG;
                    136:                    break;
                    137:                }
                    138:                dp -> ftd_type = DIAG_PERM;
                    139:                dp -> ftd_identifier = FS_SEL_AVAIL;
                    140:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    141:                dp -> ftd_delay = DIAG_NODELAY;
                    142:                dp -> ftd_cc = 0;
                    143:                dp++;
                    144: 
                    145:                state = FSTATE_FAILURE;
                    146:                goto done_select;
                    147:        }
                    148: #else
                    149: /* can't check a file you don't have */
                    150: #endif
                    151: 
                    152:        if (ftg -> ftg_flags & FTG_RDATTR)
                    153:            ftse -> ftse_access |= FA_PERM_READATTR;
                    154:        if (ftg -> ftg_flags & FTG_CHATTR)
                    155:            ftse -> ftse_access |= FA_PERM_CHNGATTR;
                    156:        if (ftg -> ftg_flags & FTG_DELETE)
                    157:            ftse -> ftse_access |= FA_PERM_DELETE;
                    158:        if (chkaccess (NOTOK, ftse -> ftse_access, &ftse -> ftse_conctl, &dp)
                    159:                == NOTOK) {
                    160:            state = FSTATE_FAILURE;
                    161:            goto done_select;
                    162:        }
                    163: #ifndef        BRIDGE
                    164:        if (ftse -> ftse_account) {
                    165:            if ((mygid = findgid (ftse -> ftse_account)) == NOTOK) {
                    166:                dp -> ftd_type = DIAG_PERM;
                    167:                dp -> ftd_identifier = FS_SEL_ACCOUNT;
                    168:                dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                    169:                dp -> ftd_delay = DIAG_NODELAY;
                    170:                dp -> ftd_cc = 0;
                    171:                dp++;
                    172: 
                    173:                state = FSTATE_FAILURE;
                    174:                goto done_select;
                    175:            }
                    176:        }
                    177:        else
                    178: #else
                    179: /* no account checking */
                    180: #endif
                    181:            mygid = NOTOK;
                    182: 
                    183: done_select: ;
                    184:        myaccess = ftse -> ftse_access;
                    185:        ftm -> ftg_select.ftse_state = state;
                    186:        ftm -> ftg_select.ftse_ndiag = dp - ftm -> ftg_select.ftse_diags;
                    187:     }
                    188: 
                    189:     if (ftg -> ftg_flags & FTG_CREATE) {
                    190:        register struct FTAMcreate *ftce = &ftg -> ftg_create;
                    191:        register struct FTAMattributes *fa = &ftce -> ftce_attrs;
                    192:        struct FTAMdiagnostic *dp = ftm -> ftg_create.ftce_diags;
                    193:        register struct vfsmap *vf;
                    194: 
                    195:        if (!(fa -> fa_present & FA_FILENAME)
                    196:                || fa -> fa_nfile != 1
                    197:                || (myfile = getfile (fa -> fa_files[0])) == NULL) {
                    198:            dp -> ftd_type = DIAG_PERM;
                    199:            dp -> ftd_identifier = FS_SEL_FILENAME;
                    200:            dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    201:            dp -> ftd_delay = DIAG_NODELAY;
                    202:            dp -> ftd_cc = 0;
                    203:            dp++;
                    204: 
                    205:            state = FSTATE_FAILURE;
                    206:            goto done_create;
                    207:        }
                    208: #ifdef BRIDGE
                    209:        if (ftp_access (myfile, E_OK) != NOTOK)
                    210: #else
                    211:        if (stat (myfile, &myst) != NOTOK)
                    212: #endif
                    213:            statok = 1;
                    214:        if (statok) {
                    215: #ifndef        BRIDGE  /* Assume file type allow corrective action */
                    216:            switch (myst.st_mode & S_IFMT) {
                    217:                case S_IFREG: 
                    218:                    break;
                    219: 
                    220:                case S_IFDIR: 
                    221:                    switch (ftce -> ftce_override) {
                    222:                        case FOVER_WRITE: 
                    223:                            dp -> ftd_type = DIAG_PERM;
                    224:                            dp -> ftd_identifier = FS_SEL_CRELOSE;
                    225:                            dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    226:                            dp -> ftd_delay = DIAG_NODELAY;
                    227:                            dp -> ftd_cc = 0;
                    228:                            dp++;
                    229: 
                    230:                            state = FSTATE_FAILURE;
                    231:                            goto done_create;
                    232: 
                    233:                        default: 
                    234:                            break;
                    235:                    }
                    236:                    break;
                    237: 
                    238:                default: 
                    239:                    if (myst.st_dev == null_dev && myst.st_ino == null_ino) {
                    240:                        myst.st_mode &= ~S_IFMT, myst.st_mode |= S_IFREG;
                    241:                        break;
                    242:                    }
                    243:                    dp -> ftd_type = DIAG_PERM;
                    244:                    dp -> ftd_identifier = FS_SEL_AVAIL;
                    245:                    dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    246:                    dp -> ftd_delay = DIAG_NODELAY;
                    247:                    dp -> ftd_cc = 0;
                    248:                    dp++;
                    249: 
                    250:                    state = FSTATE_FAILURE;
                    251:                    goto done_create;
                    252:            }
                    253: #endif
                    254:            switch (ftce -> ftce_override) {
                    255:                case FOVER_FAIL: 
                    256:                    dp -> ftd_type = DIAG_PERM;
                    257:                    dp -> ftd_identifier = FS_SEL_EXISTS;
                    258:                    dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    259:                    dp -> ftd_delay = DIAG_NODELAY;
                    260:                    dp -> ftd_cc = 0;
                    261:                    dp++;
                    262: 
                    263:                    state = FSTATE_FAILURE;
                    264:                    goto done_create;
                    265: 
                    266:                case FOVER_SELECT:
                    267:                        if (ftg -> ftg_flags & FTG_RDATTR)
                    268:                            ftce -> ftce_access |= FA_PERM_READATTR;
                    269:                        if (ftg -> ftg_flags & FTG_CHATTR)
                    270:                            ftce -> ftce_access |= FA_PERM_CHNGATTR;
                    271:                        if (ftg -> ftg_flags & FTG_DELETE)
                    272:                            ftce -> ftce_access |= FA_PERM_DELETE;
                    273:                        if (chkaccess (NOTOK, ftce -> ftce_access, 
                    274:                                    &ftce -> ftce_conctl, &dp) == NOTOK) {
                    275:                            state = FSTATE_FAILURE;
                    276:                            goto done_create;
                    277:                        }
                    278:                    break;
                    279: 
                    280:                default: 
                    281:                    break;
                    282:            }
                    283:        }
                    284: 
                    285:        for (vf = vfs; vf -> vf_entry; vf++)
                    286:            if (vf -> vf_oid
                    287:                    && oid_cmp (vf -> vf_oid, fa -> fa_contents) == 0)
                    288:                break;
                    289:        if (!vf -> vf_entry) {
                    290:            (void) sprintf (dp -> ftd_data,
                    291:                           "invalid contents-type %s",
                    292:                           sprintoid (fa -> fa_contents));
                    293:            dp -> ftd_cc = strlen (dp -> ftd_data);
                    294:            dp -> ftd_type = DIAG_PERM;
                    295:            dp -> ftd_identifier = FS_SEL_ATRVALUE;
                    296:            dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                    297:            dp -> ftd_delay = DIAG_NODELAY;
                    298:            dp++;
                    299: 
                    300:            state = FSTATE_FAILURE;
                    301:            goto done_create;
                    302:        }
                    303: 
                    304:        if (chkattrs (fa, fa -> fa_present & ~(FA_FILENAME | FA_CONTENTS),
                    305:                    1, &dp) == NOTOK) {
                    306:            state = FSTATE_FAILURE;
                    307:            goto done_create;
                    308:        }
                    309: 
                    310: #ifndef        BRIDGE   /* no account checking */
                    311:        if (ftce -> ftce_account) {
                    312:            if ((mygid = findgid (ftce -> ftce_account)) == NOTOK) {
                    313:                dp -> ftd_type = DIAG_PERM;
                    314:                dp -> ftd_identifier = FS_SEL_ACCOUNT;
                    315:                dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                    316:                dp -> ftd_delay = DIAG_NODELAY;
                    317:                dp -> ftd_cc = 0;
                    318:                dp++;
                    319: 
                    320:                state = FSTATE_FAILURE;
                    321:                goto done_create;
                    322:            }
                    323:        }
                    324:        else
                    325: #endif
                    326:            mygid = NOTOK;
                    327: 
                    328: done_create: ;
                    329:        ftm -> ftg_create.ftce_state = state;
                    330:        ftm -> ftg_create.ftce_ndiag = dp - ftm -> ftg_create.ftce_diags;
                    331:     }
                    332: 
                    333:     if (ftg -> ftg_flags & FTG_RDATTR)
                    334:        ftm -> ftg_readattr.ftra_action = FACTION_SUCCESS;
                    335: 
                    336:     if (ftg -> ftg_flags & FTG_CHATTR) {
                    337:        register struct FTAMchngattr   *ftca = &ftg -> ftg_chngattr;
                    338:        register struct FTAMattributes *fa = &ftca -> ftca_attrs;
                    339:        struct FTAMdiagnostic *dp = ftm -> ftg_chngattr.ftca_diags;
                    340: 
                    341:        if (chkattrs (fa, fa -> fa_present, 0, &dp) == NOTOK)
                    342:            action = FACTION_PERM;
                    343:        else
                    344:            action = FACTION_SUCCESS;
                    345: 
                    346:        ftm -> ftg_chngattr.ftca_action = action;
                    347:        ftm -> ftg_chngattr.ftca_ndiag = dp - ftm -> ftg_chngattr.ftca_diags;
                    348:     }
                    349:     
                    350:     if (ftg -> ftg_flags & FTG_OPEN) {
                    351:        register struct FTAMopen *ftop = &ftm -> ftg_open;
                    352: 
                    353:        ftop -> ftop_state = FSTATE_FAILURE;
                    354:        ftop -> ftop_action = FACTION_SUCCESS;
                    355:        if (ftop -> ftop_contents = ftg -> ftg_open.ftop_contents)
                    356:            ftop -> ftop_parameter = ftg -> ftg_open.ftop_parameter;
                    357: 
                    358:        FCINIT (&ftop -> ftop_conctl);
                    359:     }
                    360: 
                    361:     if (ftg -> ftg_flags & FTG_CLOSE)
                    362:        ftm -> ftg_close.ftcl_action = FACTION_SUCCESS;
                    363: 
                    364:     if (ftg -> ftg_flags & FTG_DESELECT)
                    365:        ftm -> ftg_deselect.ftde_action = FACTION_SUCCESS;
                    366: 
                    367:     if (ftg -> ftg_flags & FTG_DELETE)
                    368:        ftm -> ftg_delete.ftxe_action = FACTION_SUCCESS;
                    369: 
                    370:     if (ftg -> ftg_flags & FTG_SELECT) {
                    371:        register struct FTAMselect *ftse = &ftm -> ftg_select;
                    372:        register struct FTAMattributes *fa = &ftse -> ftse_attrs;
                    373: 
                    374:        if (state != FSTATE_SUCCESS) {
                    375:            ftse -> ftse_action = FACTION_PERM;
                    376:            *fa = ftg -> ftg_select.ftse_attrs; /* struct copy */
                    377:            ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN);
                    378:            return;
                    379:        }
                    380:        ftse -> ftse_action = FACTION_SUCCESS;
                    381:        fa -> fa_present = FA_FILENAME;
                    382:        fa -> fa_nfile = 0;
                    383:        fa -> fa_files[fa -> fa_nfile++] = myfile;
                    384:     }
                    385: 
                    386:     if (ftg -> ftg_flags & FTG_CREATE) {
                    387:        register struct FTAMattributes *fa = &ftg -> ftg_create.ftce_attrs;
                    388:        register struct FTAMcreate *ftce = &ftm -> ftg_create;
                    389:        struct FTAMdiagnostic  *dp = ftce -> ftce_diags + ftce -> ftce_ndiag;
                    390: 
                    391:        if (state != FSTATE_SUCCESS) {
                    392:            ftce -> ftce_action = FACTION_PERM;
                    393:            ftce -> ftce_attrs = *fa;   /* struct copy */
                    394:            ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN);
                    395:            return;
                    396:        }
                    397:        switch (ftg -> ftg_create.ftce_override) {
                    398:            case FOVER_SELECT:
                    399:            default: 
                    400:                if (statok)
                    401:                    break;
                    402:                goto do_create;
                    403: 
                    404:            case FOVER_DELETE: 
                    405: #ifdef BRIDGE
                    406:                if (statok && ftp_delete (myfile) == NOTOK) {
                    407: #else
                    408:                if (statok
                    409:                        && ((myst.st_mode & S_IFMT) == S_IFREG
                    410:                                    ? unlink (myfile)
                    411:                                    : rmdir (myfile)) == NOTOK) {
                    412:            bad_override: ;
                    413: #endif
                    414:                    dp -> ftd_type = DIAG_PERM;
                    415:                    dp -> ftd_identifier = FS_SEL_CRELOSE;
                    416:                    dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    417:                    dp -> ftd_delay = DIAG_NODELAY;
                    418: #ifdef BRIDGE
                    419:                    (void) strcpy (dp -> ftd_data, ftp_error);
                    420: #else
                    421:                    (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    422: #endif
                    423:                    dp -> ftd_cc = strlen (dp -> ftd_data);
                    424:                    dp++;
                    425: 
                    426:            bad_create: ;
                    427:                    ftce -> ftce_action = FACTION_PERM;
                    428:                    ftce -> ftce_attrs = *fa;   /* struct copy */
                    429:                    ftce -> ftce_ndiag = dp - ftce -> ftce_diags;
                    430: 
                    431:                    ftce -> ftce_state = FSTATE_FAILURE;
                    432:                    ftm -> ftg_flags &= ~(FTG_RDATTR | FTG_CHATTR | FTG_OPEN);
                    433:                    return;
                    434:                }
                    435:                /* else fall */
                    436: 
                    437:            case FOVER_FAIL:
                    438:                statok = 0;
                    439:        do_create: ;
                    440:                if (!(fa -> fa_present & FA_CONTENTS)
                    441:                        || oid_cmp (vfs[VFS_FDF].vf_oid, fa -> fa_contents)) {
                    442: #ifdef BRIDGE
                    443:                    if (ftp_create (myfile) == NOTOK) {
                    444: #else
                    445:                    if ((myfd = open (myfile, O_RDWR | O_CREAT | O_TRUNC,
                    446:                                        0666)) == NOTOK) {
                    447: #endif
                    448:                bad_open: ;
                    449:                        dp -> ftd_type = DIAG_PERM;
                    450:                        dp -> ftd_identifier = FS_SEL_CREATE;
                    451:                        dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    452:                        dp -> ftd_delay = DIAG_NODELAY;
                    453:                        (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    454:                        dp -> ftd_cc = strlen (dp -> ftd_data);
                    455:                        dp++;
                    456: 
                    457:                        goto bad_create;
                    458:                    }
                    459:                }
                    460:                else
                    461: #ifdef BRIDGE
                    462:                    if (ftp_mkdir (myfile) == NOTOK)
                    463: #else
                    464:                    if (mkdir (myfile, 0755) == NOTOK)
                    465: #endif
                    466:                        goto bad_open;
                    467:                if (chngattrs (fa -> fa_present
                    468:                        & ~(FA_FILENAME | FA_CONTENTS), fa, &dp) == NOTOK)
                    469:                    goto bad_create;
                    470:                break;
                    471: 
                    472:            case FOVER_WRITE: 
                    473:                if (!statok)
                    474:                    goto do_create;
                    475: #ifndef        BRIDGE
                    476: #ifdef SUNOS4
                    477:                if (myst.st_size > 0 && truncate (myfile, (off_t) 0) == NOTOK)
                    478:                    goto bad_override;
                    479: #else
                    480:                if (myst.st_size > 0 && truncate (myfile, 0) == NOTOK)
                    481:                    goto bad_override;
                    482: #endif
                    483: #endif
                    484:                break;
                    485:        }
                    486: 
                    487:        ftce -> ftce_action = FACTION_SUCCESS;
                    488:        (void) readattrs (FA_FILENAME | FA_ACTIONS | FA_CONTENTS,
                    489:                          &ftce -> ftce_attrs, fa -> fa_contents,
                    490:                          fa -> fa_parameter, myfile, &myst, &dp);
                    491:        if (fa -> fa_present & FA_ACTIONS)
                    492:            ftce -> ftce_attrs.fa_permitted &= fa -> fa_permitted;
                    493:        ftce -> ftce_ndiag = dp - ftce -> ftce_diags;
                    494:     }
                    495: 
                    496:     if (ftg -> ftg_flags & FTG_RDATTR
                    497:            && (ftm -> ftg_readattr.ftra_action == FACTION_SUCCESS)) {
                    498:        register struct FTAMreadattr   *ftra = &ftm -> ftg_readattr;
                    499:        struct FTAMdiagnostic  *dp = ftra -> ftra_diags + ftra -> ftra_ndiag;
                    500: 
                    501:        if (!statok) {
                    502: #ifdef BRIDGE
                    503:            if (0) { /* assume OK */
                    504: #else
                    505:            if ((myfd != NOTOK ? fstat (myfd, &myst)
                    506:                               : stat (myfile, &myst)) == NOTOK) {
                    507:                dp -> ftd_type = DIAG_PERM;
                    508:                dp -> ftd_identifier = FS_MGT_READ;
                    509:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    510:                dp -> ftd_delay = DIAG_NODELAY;
                    511:                dp -> ftd_cc = 0;
                    512:                dp++;
                    513: #endif
                    514: 
                    515:        bad_readattr: ;
                    516:                ftra -> ftra_action = FACTION_PERM;
                    517:                ftra -> ftra_ndiag = dp - ftra -> ftra_diags;
                    518:                return;
                    519:            }
                    520:            else
                    521:                statok++;
                    522:        }
                    523:        if (readattrs (ftg -> ftg_readattr.ftra_attrnames,
                    524:                       &ftra -> ftra_attrs, ftg -> ftg_flags & FTG_OPEN
                    525:                           ? ftg -> ftg_open.ftop_contents : NULLOID, NULLPE,
                    526:                       myfile, &myst, &dp) == NOTOK)
                    527:            goto bad_readattr;
                    528:        ftra -> ftra_ndiag = dp - ftra -> ftra_diags;
                    529:     }
                    530: 
                    531:     if (ftg -> ftg_flags & FTG_CHATTR
                    532:            && (ftm -> ftg_chngattr.ftca_action == FACTION_SUCCESS)) {
                    533:        register struct FTAMchngattr   *ftca = &ftm -> ftg_chngattr;
                    534:        register struct FTAMattributes *fa = &ftg -> ftg_chngattr.ftca_attrs;
                    535:        struct FTAMdiagnostic  *dp = ftca -> ftca_diags + ftca -> ftca_ndiag;
                    536: 
                    537:        if (chngattrs (fa -> fa_present, fa, &dp) == NOTOK) {
                    538:            ftca -> ftca_action = FACTION_PERM;
                    539:            ftca -> ftca_ndiag = dp - ftca -> ftca_diags;
                    540:            return;
                    541:        }
                    542: 
                    543:        ftca -> ftca_ndiag = dp - ftca -> ftca_diags;
                    544:     }
                    545: 
                    546:     if (ftg -> ftg_flags & FTG_OPEN) {
                    547: #ifndef        BRIDGE
                    548:        int     mode;
                    549: #endif
                    550:        register struct FTAMopen *ftop = &ftm -> ftg_open;
                    551:        struct FTAMdiagnostic  *dp = ftop -> ftop_diags + ftop -> ftop_ndiag;
                    552:        
                    553:        ftop -> ftop_state = FSTATE_SUCCESS;
                    554:        if (statok == 0) {
                    555:            if (stat (myfile, &myst) == NOTOK) {
                    556: #ifndef        BRIDGE
                    557: unavailable: ;
                    558: #endif
                    559:                dp -> ftd_type = DIAG_PERM;
                    560:                dp -> ftd_identifier = FS_SEL_AVAIL;
                    561:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    562:                dp -> ftd_delay = DIAG_NODELAY;
                    563:                if (errno) {
                    564:                    (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    565:                    dp -> ftd_cc = strlen (dp -> ftd_data);
                    566:                }
                    567:                else
                    568:                    dp -> ftd_cc = 0;
                    569:                dp++;
                    570: 
                    571:                ftop -> ftop_state = FSTATE_FAILURE;
                    572:                goto done_open;
                    573:            }
                    574:            else
                    575:                statok = 1;
                    576:        }
                    577: 
                    578:         if (ftop -> ftop_contents == NULL) {
                    579:            register struct FTAMattributes *fa;
                    580: 
                    581:            if (ftg -> ftg_flags & FTG_CREATE) {
                    582:                fa = &ftg -> ftg_create.ftce_attrs;
                    583: 
                    584:                ftop -> ftop_contents = fa -> fa_contents;
                    585:                ftop -> ftop_parameter = fa -> fa_parameter;
                    586:                advise (LLOG_DEBUG, NULLCP,
                    587:                        "using contents-type from CREATE <%s, 0x%x>",
                    588:                        oid2ode (ftop -> ftop_contents),
                    589:                        ftop -> ftop_parameter);
                    590:                goto find_myvfs;
                    591:            }
                    592: 
                    593:            if ((ftg -> ftg_flags & FTG_RDATTR)
                    594:                    && ftm -> ftg_readattr.ftra_action == FACTION_SUCCESS
                    595:                    && ((fa = &ftm -> ftg_readattr.ftra_attrs) -> fa_present
                    596:                                & FA_CONTENTS)) {
                    597:                ftop -> ftop_contents = fa -> fa_contents;
                    598:                ftop -> ftop_parameter = fa -> fa_parameter;
                    599:                advise (LLOG_DEBUG, NULLCP,
                    600:                        "using contents-type from READ-ATTRIBUTE <%s, 0x%x>",
                    601:                        oid2ode (ftop -> ftop_contents),
                    602:                        ftop -> ftop_parameter);
                    603: 
                    604: find_myvfs: ;
                    605:                if ((myvf = st2vfs (myfd, myfile, &myst, ftop -> ftop_contents,
                    606:                                    ftamfd)) == NULL)
                    607:                    goto no_ascertain;
                    608:                if (oid_cmp (ftop -> ftop_contents, myvf -> vf_oid) == 0)
                    609:                    goto find_param;
                    610:                advise (LLOG_DEBUG, NULLCP,
                    611:                        "wrong intuition; back to step one");
                    612:                ftop -> ftop_contents = NULLOID;
                    613:                ftop -> ftop_parameter = NULLPE;
                    614:            }
                    615: 
                    616:            if ((myvf = st2vfs (myfd, myfile, &myst, NULLOID, ftamfd))
                    617:                    == NULL) {
                    618: no_ascertain: ;
                    619:                (void) strcpy (dp -> ftd_data,
                    620:                               "unable to ascertain contents-type");
                    621:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    622:                dp -> ftd_type = DIAG_PERM;
                    623:                dp -> ftd_identifier = FS_ACC_LCL;
                    624:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    625:                dp -> ftd_delay = DIAG_NODELAY;
                    626:                dp++;
                    627: 
                    628:                ftop -> ftop_state = FSTATE_FAILURE;
                    629:                goto done_open;
                    630:            }
                    631:            ftop -> ftop_contents = myvf -> vf_oid;
                    632:            advise (LLOG_DEBUG, NULLCP,
                    633:                    "using contents-type from st2vfs: %s",
                    634:                    oid2ode (ftop -> ftop_contents));
                    635: 
                    636: find_param: ;
                    637:            if (myvf -> vf_mandatory > 0 && ftop -> ftop_parameter == NULL) {
                    638:                char buffer[BUFSIZ];
                    639: 
                    640:                if (rdparam)
                    641:                    pe_free (rdparam), rdparam = NULLPE;
                    642:                if (enc_f (myvf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0,
                    643:                           NULLCP, myvf -> vf_parameter) == NOTOK) {
                    644:                    advise (LLOG_EXCEPTIONS, NULLCP,
                    645:                            "unable to build parameter: %s", PY_pepy);
                    646:                    if (rdparam)
                    647:                        pe_free (rdparam), rdparam = NULLPE;
                    648:                    goto no_ascertain;
                    649:                }
                    650:                ftop -> ftop_parameter = rdparam;
                    651: 
                    652:                vpushstr (buffer);
                    653:                vunknown (ftop -> ftop_parameter);
                    654:                vpopstr ();
                    655:                advise (LLOG_DEBUG, NULLCP,
                    656:                        "generating parameter from vfs: %s", buffer);
                    657:            }
                    658:            else
                    659:                if (!myvf -> vf_mandatory && ftop -> ftop_parameter)
                    660:                    ftop -> ftop_parameter = NULLPE;
                    661:        }
                    662:        else
                    663:            if ((myvf = st2vfs (myfd, myfile, &myst, ftop -> ftop_contents,
                    664:                                ftamfd)) == NULL) {
                    665:                dp -> ftd_cc = 0;
                    666: bad_param: ;
                    667:                dp -> ftd_type = DIAG_PERM;
                    668:                dp -> ftd_identifier = FS_ACC_TYPINCON;
                    669:                dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                    670:                dp -> ftd_delay = DIAG_NODELAY;
                    671:                dp++;
                    672: 
                    673:                ftop -> ftop_state = FSTATE_FAILURE;
                    674:                goto done_open;
                    675:            }
                    676: 
                    677:         if (oid_cmp (ftop -> ftop_contents, myvf -> vf_oid)) {
                    678:            advise (LLOG_NOTICE, NULLCP, "simplifying document type");
                    679: 
                    680:            ftop -> ftop_contents = myvf -> vf_oid;
                    681:            ftop -> ftop_parameter = NULLPE;
                    682:            if (myvf -> vf_mandatory) {
                    683:                char buffer[BUFSIZ];
                    684: 
                    685:                if (rdparam)
                    686:                    pe_free (rdparam), rdparam = NULLPE;
                    687:                if (enc_f (myvf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0,
                    688:                           NULLCP, myvf -> vf_parameter) == NOTOK) {
                    689:                    advise (LLOG_EXCEPTIONS, NULLCP,
                    690:                            "unable to build parameter: %s", PY_pepy);
                    691:                    if (rdparam)
                    692:                        pe_free (rdparam), rdparam = NULLPE;
                    693:                    goto no_ascertain;
                    694:                }
                    695:                ftop -> ftop_parameter = rdparam;
                    696: 
                    697:                vpushstr (buffer);
                    698:                vunknown (ftop -> ftop_parameter);
                    699:                vpopstr ();
                    700:                advise (LLOG_DEBUG, NULLCP,
                    701:                        "generating parameter from myvf: %s", buffer);
                    702:            }
                    703:        }
                    704: 
                    705:        if (ftop -> ftop_parameter) {
                    706:            if (myvf -> vf_number < 0) {
                    707:                (void) sprintf (dp -> ftd_data,
                    708:                                "unexpected document type parameter");
                    709:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    710:                goto bad_param;
                    711:            }
                    712:            myparam = NULL;
                    713:            if (dec_f (myvf -> vf_number, &_ZDOCS_mod, ftop -> ftop_parameter,
                    714:                       1, NULLIP, NULLVP, &myparam) == NOTOK) {
                    715:                (void) sprintf (dp -> ftd_data,
                    716:                                "unable to parse document type parameter: %s",
                    717:                                PY_pepy);
                    718:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    719:                goto bad_param;
                    720:            }
                    721:            if (myvf -> vf_check
                    722:                    && (*myvf -> vf_check) (myparam, dp -> ftd_data)
                    723:                            == NOTOK)
                    724:                goto bad_param;
                    725:        }
                    726:        else
                    727:            if (myvf -> vf_mandatory > 0) {
                    728:                (void) strcpy (dp -> ftd_data,
                    729:                               "mandatory document type parameter missing");
                    730:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    731:                goto bad_param;
                    732:            }
                    733: 
                    734:        mymode = ftg -> ftg_open.ftop_mode;
                    735: #ifndef        BRIDGE
                    736:        if (mymode & FA_PERM_WRITE)
                    737:            mode = (mymode & FA_PERM_READ) ? O_RDWR : O_WRONLY;
                    738:        else
                    739:            mode = O_RDONLY;
                    740: #endif
                    741: 
                    742:        errno = 0;
                    743: #ifndef        BRIDGE
                    744:        switch (myst.st_mode & S_IFMT) {
                    745:            case S_IFREG:
                    746:                if (myfd == NOTOK && (myfd = open (myfile, mode)) == NOTOK)
                    747:                    goto unavailable;
                    748:                break;
                    749:                    
                    750:            case S_IFDIR:
                    751:                if (mode == O_RDONLY)
                    752:                    break;
                    753:                /* else fall */
                    754: 
                    755:            default:
                    756:                goto unavailable;
                    757:        }
                    758: #endif
                    759: 
                    760:        myconctl = ftg -> ftg_open.ftop_conctl; /* struct copy */
                    761:        ftm -> ftg_open.ftop_conctl = myconctl; /*   .. */
                    762:        mylockstyle = ftg -> ftg_open.ftop_locking;
                    763: 
                    764:        if (chkaccess (myfd, mymode, &myconctl, &dp) == NOTOK) {
                    765:            ftop -> ftop_state = FSTATE_FAILURE;
                    766:            goto done_open;
                    767:        }
                    768: 
                    769: done_open: ;
                    770:        ftop -> ftop_ndiag = dp - ftop -> ftop_diags;
                    771: 
                    772:        if (ftop -> ftop_state != FSTATE_SUCCESS) {
                    773:            ftop -> ftop_action = FACTION_PERM;
                    774:            return;
                    775:        }
                    776:     }
                    777: 
                    778:     if (ftg -> ftg_flags & FTG_CLOSE
                    779:            && (ftm -> ftg_close.ftcl_action == FACTION_SUCCESS)) {
                    780:        if (myfd != NOTOK) {
                    781: #ifdef BRIDGE
                    782:            (void) close (myfd);
                    783:            (void) ftp_reply ();
                    784: #else
                    785:            unlock ();
                    786:            (void) close (myfd);
                    787: #endif
                    788:            myfd = NOTOK;
                    789:        }
                    790:        if (myvf && myparam) {
                    791:            fre_obj (myparam, _ZDOCS_mod.md_dtab[myvf -> vf_number],
                    792:                     &_ZDOCS_mod);
                    793:            myparam = NULL;
                    794:        }
                    795:     }
                    796: 
                    797:     if (ftg -> ftg_flags & FTG_DESELECT) {
                    798:        register struct FTAMdeselect   *ftde = &ftm -> ftg_deselect;
                    799: 
                    800:        if (ftde -> ftde_action == FACTION_SUCCESS) {
                    801:        /* anything to charge if (mygid != NOTOK)?  ha! */
                    802:        }
                    803:     }
                    804: 
                    805:     if (ftg -> ftg_flags & FTG_DELETE) {
                    806:        register struct FTAMdelete *ftxe = &ftm -> ftg_delete;
                    807:        struct FTAMdiagnostic  *dp = ftxe -> ftxe_diags + ftxe -> ftxe_ndiag;
                    808: 
                    809:        if (ftxe -> ftxe_action == FACTION_SUCCESS) {
                    810: #ifdef BRIDGE
                    811:            if (ftp_delete (myfile) == NOTOK) {
                    812: #else
                    813:            if (!statok && stat (myfile, &myst) == NOTOK)
                    814:                myst.st_mode = S_IFREG;
                    815:            if (((myst.st_mode & S_IFMT) == S_IFREG ? unlink (myfile)
                    816:                                                    : rmdir (myfile))
                    817:                        == NOTOK) {
                    818: #endif
                    819:                dp -> ftd_type = DIAG_PERM;
                    820:                dp -> ftd_identifier = FS_SEL_DELETE;
                    821:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    822:                dp -> ftd_delay = DIAG_NODELAY;
                    823: #ifdef BRIDGE
                    824:                (void) strcpy (dp -> ftd_data, ftp_error);
                    825: #else
                    826:                (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    827: #endif
                    828:                dp -> ftd_cc = strlen (dp -> ftd_data);
                    829:                dp++;
                    830: 
                    831:                ftxe -> ftxe_action = FACTION_PERM;
                    832:                ftxe -> ftxe_ndiag = dp - ftxe -> ftxe_diags;
                    833:                return;
                    834:            }
                    835:            advise (LLOG_NOTICE, NULLCP, "delete %s", myfile);
                    836:        }
                    837:     }
                    838: }
                    839: 
                    840: /*  */
                    841: 
                    842: #ifdef BRIDGE
                    843: /* ARGSUSED */
                    844: #endif
                    845: 
                    846: static int  chkaccess (fd, request, fc, diags)
                    847: int    fd,
                    848:        request;
                    849: #ifndef        BRIDGE
                    850: register
                    851: #endif
                    852: struct FTAMconcurrency *fc;
                    853: register struct FTAMdiagnostic **diags;
                    854: {
                    855:     int     result;
                    856: #ifndef        BRIDGE
                    857:     register char  *cp;
                    858: #endif
                    859:     register struct FTAMdiagnostic *dp = *diags;
                    860: 
                    861:     result = OK;
                    862: 
                    863: #ifndef        BRIDGE
                    864:     if (((request & FA_PERM_READ) && EACCESS (myfile, R_OK) == NOTOK)
                    865:            || ((request & FA_PERM_WRITE) && EACCESS (myfile, W_OK) == NOTOK)
                    866:            || ((request & FA_PERM_OWNER)
                    867:                        && (myuid != myst.st_uid && myuid != 0))) {
                    868: no_access: ;
                    869:        dp -> ftd_type = DIAG_PERM;
                    870:        dp -> ftd_identifier = FS_SEL_ACCAVAIL;
                    871:        dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    872:        dp -> ftd_delay = DIAG_NODELAY;
                    873:        dp -> ftd_cc = 0;
                    874:        dp++;
                    875: 
                    876:        result = NOTOK;
                    877:        goto out;
                    878:     }
                    879:     if (request & FA_PERM_PARENT) {
                    880:        if (cp = rindex (myfile, '/')) {
                    881:            *cp = NULL;
                    882:            result = EACCESS (*myfile ? myfile : "/", W_OK);
                    883:            *cp = '/';
                    884:        }
                    885:        else
                    886:            result = EACCESS (".", W_OK);
                    887: 
                    888:        if (result == NOTOK)
                    889:            goto no_access;
                    890:     }
                    891: #else
                    892: /* already selected file and know it exists, FTP cannot tell us more */
                    893: #endif
                    894: 
                    895: #ifndef        BRIDGE
                    896: out: ;
                    897: 
                    898:     if (attrs & FATTR_STORAGE) {
                    899:        if (fd == NOTOK) {
                    900:            mylock = 0;
                    901: 
                    902:            if (((request & FA_PERM_READATTR)
                    903:                        && (fc -> fc_readattrlock & FLOCK_RESTRICT))
                    904:                    || ((request & FA_PERM_CHNGATTR)
                    905:                        && (fc -> fc_chngattrlock & FLOCK_RESTRICT))
                    906:                    || ((request & FA_PERM_DELETE)
                    907:                        && (fc -> fc_deletelock & FLOCK_RESTRICT))) {
                    908:                dp -> ftd_type = DIAG_PERM;
                    909:                dp -> ftd_identifier = FS_SEL_CONSUPRT;
                    910:                dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    911:                dp -> ftd_delay = DIAG_NODELAY;
                    912:                dp -> ftd_cc = 0;
                    913:                dp++;
                    914: 
                    915:                result = NOTOK;
                    916:            }
                    917:        }
                    918:        else {
                    919: #ifdef SYS5
                    920:            struct flock    fs;
                    921: #endif
                    922: 
                    923:            if ((request & FA_PERM_WRITE)
                    924:                    && ((fc -> fc_insertlock & FLOCK_RESTRICT)
                    925:                            || (fc -> fc_replacelock & FLOCK_RESTRICT)
                    926:                            || (fc -> fc_eraselock & FLOCK_RESTRICT)
                    927:                            || (fc -> fc_extendlock & FLOCK_RESTRICT))) {
                    928:                mylock = 1;
                    929: #ifndef        SYS5
                    930:                if (flock (fd, LOCK_EX) == NOTOK)
                    931:                    goto bad_concur;
                    932: #else
                    933:                fs.l_type = F_WRLCK;
                    934:                fs.l_whence = L_SET;
                    935:                fs.l_start = fs.l_len = 0;
                    936:                if (fcntl (fd, F_SETLKW, &fs) == NOTOK)
                    937:                    goto bad_concur;
                    938: #endif
                    939:            }
                    940:            else
                    941:                if ((request & FA_PERM_READ)
                    942:                        && (fc -> fc_readlock & FLOCK_RESTRICT)) {
                    943:                    mylock = 1;
                    944: #ifndef        SYS5
                    945:                    if (flock (fd, LOCK_SH) == NOTOK) {
                    946: #else
                    947:                    fs.l_type = F_RDLCK;
                    948:                    fs.l_whence = L_SET;
                    949:                    fs.l_start = fs.l_len = 0;
                    950:                    if (fcntl (fd, F_SETLKW, &fs) == NOTOK) {
                    951: #endif
                    952: bad_concur: ;
                    953:                        dp -> ftd_type = DIAG_PERM;
                    954:                        dp -> ftd_identifier = FS_ACC_CONAVAIL;
                    955:                        dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    956:                        dp -> ftd_delay = DIAG_NODELAY;
                    957:                        (void) strcpy (dp -> ftd_data, sys_errname (errno));
                    958:                        dp -> ftd_cc = strlen (dp -> ftd_data);
                    959:                        dp++;
                    960: 
                    961:                        mylock = 0;
                    962:                        result = NOTOK;
                    963:                    }
                    964:                }
                    965:        }
                    966:     }
                    967: #endif
                    968: 
                    969:     *diags = dp;
                    970:     return result;
                    971: }
                    972: 
                    973: /*  */
                    974: 
                    975: static int  chkattrs (fa, present, select, diags)
                    976: register struct FTAMattributes *fa;
                    977: long   present;
                    978: int    select;
                    979: register struct FTAMdiagnostic **diags;
                    980: {
                    981:     int     id,
                    982:            result;
                    983:     char   *file;
                    984:     register struct FTAMdiagnostic *dp = *diags;
                    985: 
                    986:     result = OK;
                    987: 
                    988:     present &= ~FA_FUTURESIZE; /* be liberal in what you accept... */
                    989:     if (present & ~(FA_CHATTR | FA_RDATTR)) {
                    990:        dp -> ftd_type = DIAG_PERM;
                    991:        dp -> ftd_identifier = select ? FS_SEL_INITIAL
                    992:            : (present & FA_RDATTR) ? FS_MGT_CHANGE : FS_MGT_EXIST;
                    993:        dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                    994:        dp -> ftd_delay = DIAG_NODELAY;
                    995:        dp -> ftd_cc = 0;
                    996:        dp++;
                    997: 
                    998:        result = NOTOK;
                    999:     }
                   1000: 
                   1001:     id = select ? FS_SEL_ATRVALUE : FS_MGT_VALUE;
                   1002: 
                   1003:     if (present & FA_FILENAME) {
                   1004:        if (fa -> fa_nfile != 1
                   1005:                || (file = getfile (fa -> fa_files[0])) == NULL) {
                   1006:            dp -> ftd_type = DIAG_PERM;
                   1007:            dp -> ftd_identifier = id;
                   1008:            dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                   1009:            dp -> ftd_delay = DIAG_NODELAY;
                   1010:            (void) strcpy (dp -> ftd_data, "00bad filename");
                   1011:            dp -> ftd_cc = strlen (dp -> ftd_data);
                   1012:            dp++;
                   1013: 
                   1014:            result = NOTOK;
                   1015:        }
                   1016:        else
                   1017:            (void) strcpy (mvfile, file);
                   1018:     }
                   1019: 
                   1020: #ifndef        BRIDGE
                   1021:     if ((present & FA_ACCOUNT) && findgid (fa -> fa_account) == NOTOK) {
                   1022:        dp -> ftd_type = DIAG_PERM;
                   1023:        dp -> ftd_identifier = id;
                   1024:        dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                   1025:        dp -> ftd_delay = DIAG_NODELAY;
                   1026:        (void) strcpy (dp -> ftd_data, "02bad storage account");
                   1027:        dp -> ftd_cc = strlen (dp -> ftd_data);
                   1028:        dp++;
                   1029: 
                   1030:        result = NOTOK;
                   1031:     }
                   1032: 
                   1033:     if ((present & FA_FILESIZE) && fa -> fa_filesize < 0) {
                   1034:        dp -> ftd_type = DIAG_PERM;
                   1035:        dp -> ftd_identifier = id;
                   1036:        dp -> ftd_observer = EREF_RFSU, dp -> ftd_source = EREF_IFSU;
                   1037:        dp -> ftd_delay = DIAG_NODELAY;
                   1038:        (void) strcpy (dp -> ftd_data, "13bad filesize");
                   1039:        dp -> ftd_cc = strlen (dp -> ftd_data);
                   1040:        dp++;
                   1041: 
                   1042:        result = NOTOK;
                   1043:     }
                   1044: #endif
                   1045: 
                   1046:     *diags = dp;
                   1047:     return result;
                   1048: }
                   1049: 
                   1050: /*  */
                   1051: 
                   1052: int    readattrs (attrnames, fa, proposed, parameter, file, st, diags)
                   1053: int    attrnames;
                   1054: register struct FTAMattributes *fa;
                   1055: OID    proposed;
                   1056: PE     parameter;
                   1057: char   *file;
                   1058: struct stat *st;
                   1059: register struct FTAMdiagnostic **diags;
                   1060: {
                   1061: #ifndef        BRIDGE
                   1062:     int     result;
                   1063:     char   *cp;
                   1064:     register struct tm *tm;
                   1065: #endif
                   1066:     register struct FTAMdiagnostic *dp = *diags;
                   1067: 
                   1068:     fa -> fa_present = attrnames;
                   1069:     fa -> fa_novalue = attrnames & (FA_SECURITY | FA_PRIVATE);
                   1070: 
                   1071:     if (attrnames & FA_FILENAME) {
                   1072:        fa -> fa_nfile = 0;
                   1073:        fa -> fa_files[fa -> fa_nfile++] = file;
                   1074:     }
                   1075: 
                   1076:     if (attrnames & FA_ACTIONS) {
                   1077:        fa -> fa_permitted = 0;
                   1078: #ifndef        BRIDGE
                   1079:        if (EACCESS (file, R_OK) != NOTOK)
                   1080: #endif
                   1081:            fa -> fa_permitted |= FA_PERM_READ;
                   1082: 
                   1083: #ifndef        BRIDGE
                   1084:        if (EACCESS (file, W_OK) != NOTOK)
                   1085: #endif
                   1086:            fa -> fa_permitted |= FA_PERM_WRITE;
                   1087: 
                   1088:        if (fa -> fa_permitted & (FA_PERM_READ | FA_PERM_WRITE))
                   1089:            fa -> fa_permitted |= FA_PERM_TRAVERSAL;
                   1090: 
                   1091:        fa -> fa_permitted |= FA_PERM_READATTR;
                   1092: 
                   1093: #ifndef        BRIDGE
                   1094:        if (myuid == st -> st_uid || myuid == 0)
                   1095: #endif
                   1096:            fa -> fa_permitted |= FA_PERM_OWNER;
                   1097: 
                   1098: #ifndef        BRIDGE
                   1099:        if (cp = rindex (file, '/')) {
                   1100:            *cp = NULL;
                   1101:            result = EACCESS (*file ? file : "/", W_OK);
                   1102:            *cp = '/';
                   1103:        }
                   1104:        else
                   1105:            result = EACCESS (".", W_OK);
                   1106:        if (result != NOTOK)
                   1107: #endif
                   1108:            fa -> fa_permitted |= FA_PERM_PARENT;
                   1109:     }
                   1110: 
                   1111:     if (attrnames & FA_CONTENTS) {
                   1112:        register struct vfsmap *vf;
                   1113: 
                   1114:        if (vf = st2vfs (myfd, file, st, proposed, ftamfd)) {
                   1115:            fa -> fa_contents = vf -> vf_oid;
                   1116:            if (proposed
                   1117:                    && oid_cmp (proposed, vf -> vf_oid) == 0
                   1118:                    && parameter
                   1119:                    && vf -> vf_number >= 0
                   1120:                    && vf -> vf_check) {
                   1121:                caddr_t p = NULL;
                   1122: 
                   1123:                if (dec_f (vf -> vf_number, &_ZDOCS_mod, parameter, 1, NULLIP,
                   1124:                           NULLVP, &p) == NOTOK) {
                   1125:                    advise (LLOG_NOTICE, NULLCP,
                   1126:                            "unable to parse document type parameter: %s",
                   1127:                            PY_pepy);
                   1128:                    goto bad_param;
                   1129:                }
                   1130:                if ((*vf -> vf_check) (p, dp -> ftd_data) == NOTOK) {
                   1131:                    advise (LLOG_NOTICE, NULLCP,
                   1132:                            "unacceptable document type parameter: %s",
                   1133:                            dp -> ftd_data);
                   1134:                    goto bad_param;
                   1135:                }
                   1136:                fre_obj (p, _ZDOCS_mod.md_dtab[vf -> vf_number], &_ZDOCS_mod);
                   1137:                fa -> fa_parameter = parameter;
                   1138:            }
                   1139: bad_param: ;
                   1140: 
                   1141:            if (vf -> vf_parameter) {
                   1142:                if (rdparam)
                   1143:                    pe_free (rdparam), rdparam = NULLPE;
                   1144: 
                   1145:                if (enc_f (vf -> vf_number, &_ZDOCS_mod, &rdparam, 1, 0,
                   1146:                           NULLCP, vf -> vf_parameter) == NOTOK) {
                   1147:                    advise (LLOG_EXCEPTIONS, NULLCP,
                   1148:                            "unable to build parameter: %s", PY_pepy);
                   1149:                    if (rdparam)
                   1150:                        pe_free (rdparam), rdparam = NULLPE;
                   1151:                }
                   1152:                fa -> fa_parameter = rdparam;
                   1153:            }
                   1154:            else
                   1155:                fa -> fa_parameter = NULLPE;
                   1156:        }
                   1157:        else
                   1158:            fa -> fa_present &= ~FA_CONTENTS;
                   1159:     }
                   1160: 
                   1161: #ifdef BRIDGE
                   1162: /* these values cannot be obtained from FTP */
                   1163:     if (attrnames & FA_ACCOUNT)
                   1164: #else
                   1165:     if ((attrnames & FA_ACCOUNT)
                   1166:            && (fa -> fa_account = getgroup (st -> st_gid)) == NULL)
                   1167: #endif
                   1168:        fa -> fa_present &= ~FA_ACCOUNT;
                   1169: 
                   1170:     if (attrnames & FA_DATE_CREATE)
                   1171: #ifndef        BRIDGE
                   1172:        if (tm = gmtime ((long *) &st -> st_mtime))
                   1173:            tm2ut (tm, &fa -> fa_date_create);
                   1174:        else
                   1175: #endif
                   1176:            fa -> fa_novalue |= FA_DATE_CREATE;
                   1177: 
                   1178:     if (attrnames & FA_DATE_MODIFY)
                   1179: #ifndef        BRIDGE
                   1180:        if (tm = gmtime ((long *) &st -> st_mtime))
                   1181:            tm2ut (tm, &fa -> fa_date_modify);
                   1182:        else
                   1183: #endif
                   1184:            fa -> fa_novalue |= FA_DATE_MODIFY;
                   1185: 
                   1186:     if (attrnames & FA_DATE_READ)
                   1187: #ifndef        BRIDGE
                   1188:        if (tm = gmtime ((long *) &st -> st_atime))
                   1189:            tm2ut (tm, &fa -> fa_date_read);
                   1190:        else
                   1191: #endif
                   1192:            fa -> fa_novalue |= FA_DATE_READ;
                   1193: 
                   1194:     if (attrnames & FA_DATE_ATTR)
                   1195: #ifndef        BRIDGE
                   1196:        if (tm = gmtime ((long *) &st -> st_ctime))
                   1197:            tm2ut (tm, &fa -> fa_date_attribute);
                   1198:        else
                   1199: #endif
                   1200:            fa -> fa_novalue |= FA_DATE_ATTR;
                   1201: 
                   1202: #ifdef BRIDGE
                   1203:     if (attrnames & FA_ID_CREATE)
                   1204: #else
                   1205:     if ((attrnames & FA_ID_CREATE)
                   1206:            && (fa -> fa_id_create = getuser (st -> st_uid)) == NULL)
                   1207: #endif
                   1208:        fa -> fa_novalue |= FA_ID_CREATE;
                   1209: 
                   1210: #ifdef BRIDGE
                   1211:     if (attrnames & FA_ID_MODIFY)
                   1212: #else
                   1213:     if ((attrnames & FA_ID_MODIFY)
                   1214:            && ((st -> st_mode & 0022)
                   1215:                    || (fa -> fa_id_modify = getuser (st -> st_uid)) == NULL))
                   1216: #endif
                   1217:        fa -> fa_novalue |= FA_ID_MODIFY;
                   1218: 
                   1219: #ifdef BRIDGE
                   1220:     if (attrnames & FA_ID_READ)
                   1221: #else
                   1222:     if ((attrnames & FA_ID_READ)
                   1223:            && ((st -> st_mode & 0044)
                   1224:                    || (fa -> fa_id_read = getuser (st -> st_uid)) == NULL))
                   1225: #endif
                   1226:        fa -> fa_novalue |= FA_ID_READ;
                   1227: 
                   1228: #ifdef BRIDGE
                   1229:     if (attrnames & FA_ID_ATTR)
                   1230: #else
                   1231:     if ((attrnames & FA_ID_ATTR)
                   1232:            && ( (st -> st_mode & 0022)
                   1233:                    || (fa -> fa_id_attribute = getuser (st -> st_uid))
                   1234:                                == NULL))
                   1235: #endif
                   1236:        fa -> fa_novalue |= FA_ID_ATTR;
                   1237: 
                   1238:     if (attrnames & FA_AVAILABILITY)
                   1239:        fa -> fa_availability = FA_AVAIL_IMMED;
                   1240: 
                   1241:     if (attrnames & FA_FILESIZE)
                   1242: #ifdef BRIDGE
                   1243:        fa -> fa_novalue |= FA_FILESIZE;
                   1244: #else
                   1245:        fa -> fa_filesize = (int) st -> st_size;
                   1246: #endif
                   1247: 
                   1248:     if (attrnames & FA_FUTURESIZE)
                   1249:        fa -> fa_novalue |= FA_FUTURESIZE;
                   1250: 
                   1251:     *diags = dp;
                   1252:     return OK;
                   1253: }
                   1254: 
                   1255: /*  */
                   1256: 
                   1257: static int  chngattrs (present, fa, diags)
                   1258: long   present;
                   1259: register struct FTAMattributes *fa;
                   1260: register struct FTAMdiagnostic **diags;
                   1261: {
                   1262: #ifndef        BRIDGE
                   1263:     int     gid,
                   1264:             result;
                   1265: #endif
                   1266:     register struct FTAMdiagnostic *dp = *diags;
                   1267: 
                   1268: 
                   1269: #ifdef BRIDGE
                   1270:     statok = 1;
                   1271: #else
                   1272:     if ((myfd != NOTOK ? fstat (myfd, &myst) : stat (myfile, &myst))
                   1273:            == NOTOK) {
                   1274: bad_system: ;
                   1275:        (void) strcpy (dp -> ftd_data, sys_errname (errno));
                   1276:        dp -> ftd_cc = strlen (dp -> ftd_data);
                   1277:        goto no_change;
                   1278:     }
                   1279:     statok = 1;
                   1280:     if (myuid != myst.st_uid && myuid != 0) {
                   1281:        errno = EPERM;
                   1282:        goto bad_system;
                   1283:     }
                   1284: #endif
                   1285: 
                   1286: #ifndef        BRIDGE
                   1287:     if ((present & FA_ACCOUNT)
                   1288:            && (gid = findgid (fa -> fa_account)) != NOTOK) {
                   1289: #ifndef        SYS5
                   1290:        (void) seteuid (0);
                   1291:        result = myfd != NOTOK ? fchown (myfd, -1, gid)
                   1292:                               : chown (myfile, -1, gid);
                   1293:        (void) seteuid (myuid);
                   1294: #else
                   1295:        result = chgrp (myfile, gid);
                   1296: #endif
                   1297: 
                   1298:        if (result == NOTOK) {
                   1299:            (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_account,
                   1300:                    sys_errname (errno));
                   1301:            dp -> ftd_cc = strlen (dp -> ftd_data);
                   1302: 
                   1303:     no_change: ;
                   1304:            dp -> ftd_type = DIAG_PERM;
                   1305:            dp -> ftd_identifier = FS_MGT_CHANGE;
                   1306:            dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                   1307:            dp -> ftd_delay = DIAG_NODELAY;
                   1308:            dp++;
                   1309: 
                   1310:            *diags = dp;
                   1311:            return NOTOK;
                   1312:        }
                   1313: 
                   1314:        myst.st_gid = gid;
                   1315:     }
                   1316: #endif
                   1317: 
                   1318:     if (present & FA_FILENAME) {
                   1319: #ifdef BRIDGE
                   1320:        if (ftp_rename (myfile, mvfile) == NOTOK) {
                   1321:            (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_files[0],
                   1322:                            ftp_error);
                   1323: #else
                   1324:        if (rename (myfile, mvfile) == NOTOK) { /* on EXDEV could do gonzo
                   1325:                                                   copy, but why bother? */
                   1326:            (void) sprintf (dp -> ftd_data, "%s: %s", fa -> fa_files[0],
                   1327:                    sys_errname (errno));
                   1328: #endif
                   1329:            dp -> ftd_cc = strlen (dp -> ftd_data);
                   1330: #ifndef        BRIDGE
                   1331:            goto no_change;
                   1332: #else
                   1333:            dp -> ftd_type = DIAG_PERM;
                   1334:            dp -> ftd_identifier = FS_MGT_CHANGE;
                   1335:            dp -> ftd_observer = dp -> ftd_source = EREF_RFSU;
                   1336:            dp -> ftd_delay = DIAG_NODELAY;
                   1337:            dp++;
                   1338: 
                   1339:            *diags = dp;
                   1340:            return NOTOK;
                   1341: #endif
                   1342:        }
                   1343:        advise (LLOG_NOTICE, NULLCP, "rename %s to %s", myfile, mvfile);
                   1344: 
                   1345:        myfile = mvfile;
                   1346:     }
                   1347: 
                   1348:     *diags = dp;
                   1349:     return OK;
                   1350: }
                   1351: 
                   1352: /*  */
                   1353: 
                   1354: static char *getfile (file)
                   1355: char   *file;
                   1356: {
                   1357:     register char  *bp;
                   1358: #ifndef        BRIDGE
                   1359:     register char  *cp,
                   1360:                    *pp;
                   1361:     register struct passwd *pw;
                   1362: #endif
                   1363:     static int  i = 0;
                   1364:     static char buffer1[MAXPATHLEN],
                   1365:                 buffer2[MAXPATHLEN];
                   1366: 
                   1367:     bp = (i++ % 2) ? buffer1 : buffer2;
                   1368: 
                   1369: #ifndef        BRIDGE
                   1370:     switch (*file) {
                   1371:        case '/': 
                   1372:            if (strlen (file) >= MAXPATHLEN)
                   1373:                goto trunc;
                   1374: 
                   1375:            (void) strcpy (bp, file);
                   1376:            break;
                   1377: 
                   1378:        case '~': 
                   1379:            if (cp = index (pp = file + 1, '/'))
                   1380:                *cp = NULL;
                   1381: 
                   1382:            if (*pp == NULL)
                   1383:                pp = myhome;
                   1384:            else {
                   1385:                if ((pw = getpwnam (pp)) == NULL)
                   1386:                    return NULL;
                   1387:                else
                   1388:                    pp = pw -> pw_dir;
                   1389:            }
                   1390: 
                   1391:            if (strlen (pp) + 1 + (cp ? strlen (cp) : 0) >= MAXPATHLEN)
                   1392:                goto trunc;
                   1393: 
                   1394:            (void) sprintf (bp, "%s/%s", pp, cp ? cp + 1 : "");
                   1395:            if (cp)
                   1396:                *cp = '/';
                   1397:            break;
                   1398: 
                   1399:        default: 
                   1400:            if (strlen (file) + myhomelen + 1 >= MAXPATHLEN)
                   1401:                goto trunc;
                   1402: 
                   1403:            (void) sprintf (bp, "%s/%s", myhome, file);
                   1404:            break;
                   1405:     }
                   1406: 
                   1407:     compath (bp);
                   1408: 
                   1409: #ifndef        apollo          /* always return RELATIVE pathnames */
                   1410:     if (strncmp (bp, myhome, myhomelen - 1) == 0)
                   1411:        switch (bp[myhomelen - 1]) {
                   1412:            case NULL: 
                   1413:                (void) strcpy (bp, ".");
                   1414:                break;
                   1415: 
                   1416:            case '/': 
                   1417:                bp += myhomelen;
                   1418:                break;
                   1419: 
                   1420:            default: 
                   1421:                break;
                   1422:        }
                   1423: #endif
                   1424: 
                   1425:     return bp;
                   1426: 
                   1427: trunc: ;
                   1428:     errno = 0;
                   1429:     return NULLCP;
                   1430: #else
                   1431:        (void) strcpy (bp, file);
                   1432:        return bp;
                   1433: #endif
                   1434: }
                   1435: 
                   1436: /*  */
                   1437: 
                   1438: #ifndef        BRIDGE
                   1439: /* originally used algorithms similar to those in /bin/ls; Don Preuss of
                   1440:    Apollo suggested these algorithms as they work better with distributed
                   1441:    /etc/passwd and /etc/group files */
                   1442: 
                   1443: static char *getuser (uid)
                   1444: int    uid;
                   1445: {
                   1446:     static struct passwd *pw = NULL;
                   1447: 
                   1448:     if (pw == NULL || pw -> pw_uid != uid)
                   1449:        pw = getpwuid (uid);
                   1450:     return (pw ? pw -> pw_name : NULL);
                   1451: }
                   1452: 
                   1453: /*  */
                   1454: 
                   1455: static char *getgroup (gid)
                   1456: int    gid;
                   1457: {
                   1458:     register struct group *gr;
                   1459:     static int my_gid = -1;
                   1460:     static char my_name[NMAX + 1];
                   1461: 
                   1462:     if (my_gid != gid) {
                   1463:        if ((gr = getgrgid (gid)) == NULL)
                   1464:            return NULL;
                   1465: 
                   1466:        my_gid = gr -> gr_gid;
                   1467:        (void) strcpy (my_name, gr -> gr_name);
                   1468:     }
                   1469: 
                   1470:     return my_name;
                   1471: }
                   1472: 
                   1473: /*  */
                   1474: 
                   1475: int    findgid (group)
                   1476: char   *group;
                   1477: {
                   1478:     int            i;
                   1479: #ifdef BSD42
                   1480:     int            gidset[NGROUPS];
                   1481: #endif
                   1482:     register struct group *gr;
                   1483:     static int my_gid = -1;
                   1484:     static char my_name[NMAX + 1] = "";
                   1485: 
                   1486:     if (*group == NULL)
                   1487:        return NOTOK;
                   1488: 
                   1489:     if (strcmp (my_name, group) != 0) {
                   1490:        if ((gr = getgrnam (group)) == NULL)
                   1491:            return NOTOK;
                   1492: 
                   1493: #ifdef BSD42
                   1494:        for (i = getgroups (NGROUPS, gidset) - 1; i >= 0; i--)
                   1495:            if (gr -> gr_gid == gidset[i])
                   1496:                break;
                   1497:        if (i < 0)
                   1498:            return NOTOK;
                   1499: #endif
                   1500: 
                   1501:        (void) strcpy (my_name, gr -> gr_name);
                   1502:        my_gid = gr -> gr_gid;
                   1503:     }
                   1504: 
                   1505:     return my_gid;
                   1506: }
                   1507: #endif
                   1508: 
                   1509: /*  */
                   1510: 
                   1511: #ifndef        SYS5
                   1512: #ifndef        BRIDGE
                   1513: static int  EACCESS (file, mode)
                   1514: char   *file;
                   1515: int    mode;
                   1516: {
                   1517:     int            result;
                   1518: 
                   1519:     (void) seteuid (0);
                   1520:     (void) setruid (myuid);
                   1521: 
                   1522:     result = access (file, mode);
                   1523: 
                   1524:     (void) setruid (0);
                   1525:     (void) seteuid (myuid);
                   1526: 
                   1527:     return result;
                   1528: }
                   1529: #endif
                   1530: #else
                   1531: 
                   1532: /*  */
                   1533: 
                   1534: static int  chgrp (file, gid)
                   1535: char   *file;
                   1536: int    gid;
                   1537: {
                   1538:     int     i,
                   1539:            pid,
                   1540:            status;
                   1541:     char    group[10];
                   1542:     struct stat st;
                   1543: 
                   1544:     (void) sprintf (group, "%d", gid);
                   1545: 
                   1546:     switch (pid = fork ()) {
                   1547:        case NOTOK: 
                   1548:            return NOTOK;
                   1549: 
                   1550:        case OK: 
                   1551:            execl ("/bin/chgrp", "chgrp", group, file, NULLCP);
                   1552:            execl ("/usr/bin/chgrp", "chgrp", group, file, NULLCP);
                   1553:            execl ("/etc/chgrp", "chgrp", group, file, NULLCP);
                   1554:            _exit (NOTOK);
                   1555: 
                   1556:        default: 
                   1557:            while ((i = wait (&status)) != NOTOK && pid != i)
                   1558:                continue;
                   1559:            if (i != NOTOK && status) {
                   1560:                if (stat (file, &st) == NOTOK || st.st_gid != gid) {
                   1561:                    i = NOTOK;
                   1562:                    errno = EACCES;
                   1563:                }
                   1564:                else
                   1565:                    status = OK;
                   1566:            }
                   1567:            return (i == NOTOK ? NOTOK : status);
                   1568:     }
                   1569: }
                   1570: 
                   1571: /*  */
                   1572: 
                   1573: static int  mkdir (dir, mode)
                   1574: char   *dir;
                   1575: int    mode;
                   1576: {
                   1577:     int     i,
                   1578:            pid,
                   1579:            status;
                   1580:     struct stat st;
                   1581: 
                   1582:     switch (pid = fork ()) {
                   1583:        case NOTOK: 
                   1584:            return NOTOK;
                   1585: 
                   1586:        case OK: 
                   1587:            (void) umask (~mode);
                   1588:            execl ("/bin/mkdir", "mkdir", dir, NULLCP);
                   1589:            execl ("/usr/bin/mkdir", "mkdir", dir, NULLCP);
                   1590:            execl ("/etc/mkdir", "mkdir", dir, NULLCP);
                   1591:            _exit (NOTOK);
                   1592: 
                   1593:        default: 
                   1594:            while ((i = wait (&status)) != NOTOK && pid != i)
                   1595:                continue;
                   1596:            if (i != NOTOK && status) {
                   1597:                if (stat (dir, &st) == NOTOK
                   1598:                        || (st.st_mode & S_IFMT) != S_IFDIR) {
                   1599:                    i = NOTOK;
                   1600:                    errno = EACCES;
                   1601:                }
                   1602:                else
                   1603:                    status = OK;
                   1604:            }
                   1605:            return (i == NOTOK ? NOTOK : status);
                   1606:     }
                   1607: }
                   1608: 
                   1609: /*  */
                   1610: 
                   1611: static int  rmdir (dir)
                   1612: char   *dir;
                   1613: {
                   1614:     int     i,
                   1615:            pid,
                   1616:            status;
                   1617: 
                   1618:     switch (pid = fork ()) {
                   1619:        case NOTOK: 
                   1620:            return NOTOK;
                   1621: 
                   1622:        case OK: 
                   1623:            execl ("/bin/rmdir", "rmdir", dir, NULLCP);
                   1624:            execl ("/usr/bin/rmdir", "rmdir", dir, NULLCP);
                   1625:            execl ("/etc/rmdir", "rmdir", dir, NULLCP);
                   1626:            _exit (NOTOK);
                   1627: 
                   1628:        default: 
                   1629:            while ((i = wait (&status)) != NOTOK && pid != i)
                   1630:                continue;
                   1631:            if (i != NOTOK && status) {
                   1632:                if (access (dir, 0x00) != NOTOK) {
                   1633:                    i = NOTOK;
                   1634:                    errno = EACCES;
                   1635:                }
                   1636:                else
                   1637:                    status = OK;
                   1638:            }
                   1639:            return (i == NOTOK ? NOTOK : status);
                   1640:     }
                   1641: }
                   1642: 
                   1643: /*  */
                   1644: 
                   1645: static int  truncate (file, length)
                   1646: char   *file;
                   1647: int    length;
                   1648: {
                   1649:     int            fd;
                   1650: 
                   1651:     if (length != 0) {         /* XXX: too much work to get right */
                   1652:        errno = EINVAL;
                   1653:        return NOTOK;
                   1654:     }
                   1655: 
                   1656:     if ((fd = open (file, O_WRONLY | O_TRUNC)) == NOTOK)
                   1657:        return NOTOK;
                   1658: 
                   1659:     (void) close (fd);
                   1660:     return OK;
                   1661: }
                   1662: 
                   1663: 
                   1664: /* ARGSUSED */
                   1665: 
                   1666: int    ftruncate (fd, length)  /* works only 'cause we're lucky */
                   1667: int    fd,
                   1668:        length;
                   1669: {
                   1670:     return truncate (myfile, length);
                   1671: }
                   1672: #endif
                   1673: 
                   1674: /*    DEBUG */
                   1675: 
                   1676: #if    defined(FTAMDEBUG) && defined(BSD42)
                   1677: #include <syscall.h>
                   1678: 
                   1679: 
                   1680: static int  unlink (file)
                   1681: char   *file;
                   1682: {
                   1683:     if (debug) {
                   1684:        int     i,
                   1685:                b;
                   1686: 
                   1687: again:         ;
                   1688:        fprintf (stderr, "unlink(\"%s\")? y, w, l: ", file);
                   1689: 
                   1690:        i = b = getchar ();
                   1691:        while (b != '\n' && b != EOF)
                   1692:            b = getchar ();
                   1693: 
                   1694:        switch (i) {
                   1695:            case 'y': 
                   1696:                break;
                   1697: 
                   1698:            case 'w': 
                   1699:                return OK;
                   1700: 
                   1701:            case 'l': 
                   1702:                return NOTOK;
                   1703: 
                   1704:            default: 
                   1705:                goto again;
                   1706:        }
                   1707:     }
                   1708: 
                   1709:     return syscall (SYS_unlink, file);
                   1710: }
                   1711: 
                   1712: 
                   1713: static int  rmdir (dir)
                   1714: char   *dir;
                   1715: {
                   1716:     if (debug) {
                   1717:        int     i,
                   1718:                b;
                   1719: 
                   1720: again:         ;
                   1721:        fprintf (stderr, "rmdir(\"%s\")? y, w, l: ", dir);
                   1722: 
                   1723:        i = b = getchar ();
                   1724:        while (b != '\n' && b != EOF)
                   1725:            b = getchar ();
                   1726: 
                   1727:        switch (i) {
                   1728:            case 'y': 
                   1729:                break;
                   1730: 
                   1731:            case 'w': 
                   1732:                return OK;
                   1733: 
                   1734:            case 'l': 
                   1735:                return NOTOK;
                   1736: 
                   1737:            default: 
                   1738:                goto again;
                   1739:        }
                   1740:     }
                   1741: 
                   1742:     return syscall (SYS_rmdir, dir);
                   1743: }
                   1744: 
                   1745: 
                   1746: /* VARARGS2 */
                   1747: 
                   1748: static int  open (file, flags, mode)
                   1749: char   *file;
                   1750: int     flags,
                   1751:         mode;
                   1752: {
                   1753:     if (debug) {
                   1754:        int     i,
                   1755:                b;
                   1756: 
                   1757: again:         ;
                   1758:        fprintf (stderr, "open(\"%s\",0x%x,0%o)? y, l: ", file, flags,
                   1759:                        (flags & O_CREAT) ? mode : 0);
                   1760: 
                   1761:        i = b = getchar ();
                   1762:        while (b != '\n' && b != EOF)
                   1763:            b = getchar ();
                   1764: 
                   1765:        switch (i) {
                   1766:            case 'y': 
                   1767:                break;
                   1768: 
                   1769:            case 'l': 
                   1770:                return NOTOK;
                   1771: 
                   1772:            default: 
                   1773:                goto again;
                   1774:        }
                   1775:     }
                   1776: 
                   1777:     return syscall (SYS_open, file, flags, mode);
                   1778: }
                   1779: 
                   1780: 
                   1781: static int  mkdir (dir, mode)
                   1782: char   *dir;
                   1783: int     mode;
                   1784: {
                   1785:     if (debug) {
                   1786:        int     i,
                   1787:                b;
                   1788: 
                   1789: again:         ;
                   1790:        fprintf (stderr, "mkdir(\"%s\",0%o)? y, w, l: ", dir, mode);
                   1791: 
                   1792:        i = b = getchar ();
                   1793:        while (b != '\n' && b != EOF)
                   1794:            b = getchar ();
                   1795: 
                   1796:        switch (i) {
                   1797:            case 'y': 
                   1798:                break;
                   1799: 
                   1800:            case 'w': 
                   1801:                return OK;
                   1802: 
                   1803:            case 'l': 
                   1804:                return NOTOK;
                   1805: 
                   1806:            default: 
                   1807:                goto again;
                   1808:        }
                   1809:     }
                   1810: 
                   1811:     return syscall (SYS_mkdir, dir, mode);
                   1812: }
                   1813: 
                   1814: 
                   1815: static int  chown (file, uid, gid)
                   1816: char   *file;
                   1817: int     uid,
                   1818:         gid;
                   1819: {
                   1820:     if (debug) {
                   1821:        int     i,
                   1822:                b;
                   1823: 
                   1824: again:         ;
                   1825:        fprintf (stderr, "chown(\"%s\",%d,%d)? y, w, l: ", file, uid, gid);
                   1826: 
                   1827:        i = b = getchar ();
                   1828:        while (b != '\n' && b != EOF)
                   1829:            b = getchar ();
                   1830: 
                   1831:        switch (i) {
                   1832:            case 'y': 
                   1833:                break;
                   1834: 
                   1835:            case 'w': 
                   1836:                return OK;
                   1837: 
                   1838:            case 'l': 
                   1839:                return NOTOK;
                   1840: 
                   1841:            default: 
                   1842:                goto again;
                   1843:        }
                   1844:     }
                   1845: 
                   1846:     return syscall (SYS_chown, file, uid, gid);
                   1847: }
                   1848: 
                   1849: 
                   1850: static int  fchown (fd, uid, gid)
                   1851: int     fd;
                   1852: int     uid,
                   1853:         gid;
                   1854: {
                   1855:     if (debug) {
                   1856:        int     i,
                   1857:                b;
                   1858: 
                   1859: again:         ;
                   1860:        fprintf (stderr, "fchown(%d,%d,%d)? y, w, l: ", fd, uid, gid);
                   1861: 
                   1862:        i = b = getchar ();
                   1863:        while (b != '\n' && b != EOF)
                   1864:            b = getchar ();
                   1865: 
                   1866:        switch (i) {
                   1867:            case 'y': 
                   1868:                break;
                   1869: 
                   1870:            case 'w': 
                   1871:                return OK;
                   1872: 
                   1873:            case 'l': 
                   1874:                return NOTOK;
                   1875: 
                   1876:            default: 
                   1877:                goto again;
                   1878:        }
                   1879:     }
                   1880: 
                   1881:     return syscall (SYS_fchown, fd, uid, gid);
                   1882: }
                   1883: 
                   1884: 
                   1885: static int  truncate (file, length)
                   1886: char   *file;
                   1887: int     length;
                   1888: {
                   1889:     if (debug) {
                   1890:        int     i,
                   1891:                b;
                   1892: 
                   1893: again:         ;
                   1894:        fprintf (stderr, "truncate(\"%s\",%d)? y, w, l: ", file, length);
                   1895: 
                   1896:        i = b = getchar ();
                   1897:        while (b != '\n' && b != EOF)
                   1898:            b = getchar ();
                   1899: 
                   1900:        switch (i) {
                   1901:            case 'y': 
                   1902:                break;
                   1903: 
                   1904:            case 'w': 
                   1905:                return OK;
                   1906: 
                   1907:            case 'l': 
                   1908:                return NOTOK;
                   1909: 
                   1910:            default: 
                   1911:                goto again;
                   1912:        }
                   1913:     }
                   1914: 
                   1915:     return syscall (SYS_truncate, file, length);
                   1916: }
                   1917: 
                   1918: 
                   1919: static int  rename (old, new)
                   1920: char   *old;
                   1921: char   *new;
                   1922: {
                   1923:     if (debug) {
                   1924:        int     i,
                   1925:                b;
                   1926: 
                   1927: again:         ;
                   1928:        fprintf (stderr, "rename(\"%s\",\"%s\")? y, w, l: ", old, new);
                   1929: 
                   1930:        i = b = getchar ();
                   1931:        while (b != '\n' && b != EOF)
                   1932:            b = getchar ();
                   1933: 
                   1934:        switch (i) {
                   1935:            case 'y': 
                   1936:                break;
                   1937: 
                   1938:            case 'w': 
                   1939:                return OK;
                   1940: 
                   1941:            case 'l': 
                   1942:                return NOTOK;
                   1943: 
                   1944:            default: 
                   1945:                goto again;
                   1946:        }
                   1947:     }
                   1948: 
                   1949:     return syscall (SYS_rename, old, new);
                   1950: }
                   1951: 
                   1952: 
                   1953: static int  flock (fd, operation)
                   1954: int    fd,
                   1955:        operation;
                   1956: {
                   1957:     if (debug) {
                   1958:        int     i,
                   1959:                b;
                   1960: 
                   1961: again:         ;
                   1962:        fprintf (stderr, "flock(%d,0x%x)? y, w, l: ", fd, operation);
                   1963: 
                   1964:        i = b = getchar ();
                   1965:        while (b != '\n' && b != EOF)
                   1966:            b = getchar ();
                   1967: 
                   1968:        switch (i) {
                   1969:            case 'y': 
                   1970:                break;
                   1971: 
                   1972:            case 'w': 
                   1973:                return OK;
                   1974: 
                   1975:            case 'l': 
                   1976:                return NOTOK;
                   1977: 
                   1978:            default: 
                   1979:                goto again;
                   1980:        }
                   1981:     }
                   1982: 
                   1983:     return syscall (SYS_flock, fd, operation);
                   1984: }
                   1985: #endif

unix.superglobalmegacorp.com

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