Annotation of 43BSDReno/contrib/isode-beta/ftam2/ftamd-select.c, revision 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.