示例#1
0
文件: fsdir.c 项目: ragnar76/emutos
long xchmod(char *p, int wrt, char mod)
{
        OFD *fd;
        DND *dn;                                        /*  M01.01.03   */
        const char *s;
        long pos;

        if ((long)(dn = findit(p,&s,0)) < 0)            /* M01.01.1212.01 */
                return( (long)dn );
        if (!(long)dn)                                  /* M01.01.1214.01 */
                return( EPTHNF );

        pos = 0;


        if( ! scan( dn , s , FA_NORM , &pos )  )        /*  M01.01.03   */
                return( EFILNF ) ;


        pos -= 21;                           /* point at attribute in file */
        fd = dn->d_ofd;
        ixlseek(fd,pos);
        if (!wrt)
                ixread(fd,1L,&mod);
        else
        {
                ixwrite(fd,1L,&mod);
                ixclose(fd,CL_DIR); /* for flush */
        }
        return(mod);
}
示例#2
0
/*
**  ixdel - internal delete file.
**
**  Traverse the list of files open for this directory node.
**  If a file is found that has the same position in the directory as the one
**  we are to delete, then scan the system file table to see if this process is
**  then owner.  If so, then close it, otherwise abort.
**
**  NOTE:       both 'for' loops scan for the entire length of their
**              respective data structures, and do not drop out of the loop on
**              the first occurrence of a match.
**      Used by
**              ixcreat()
**              xunlink()
**              xrmdir()
**
*/
long ixdel(DND *dn, FCB *f, long pos)
{
    OFD *fd;
    DMD *dm;
    int n2;
    int n;
    char c;

    for (fd = dn->d_files; fd; fd = fd->o_link)
        if (fd->o_dirbyt == pos)
            for (n = 0; n < OPNFILES; n++)
                if (sft[n].f_ofd == fd)
                {
                    if (sft[n].f_own == run)
                        ixclose(fd,0);
                    else
                        return EACCDN;
                }

    /*
     * Traverse this file's chain of allocated clusters, freeing them.
     */
    dm = dn->d_drv;
    n = f->f_clust;
    swpw(n);

    while (n && !endofchain(n))
    {
        n2 = getrealcl(n,dm);
        clfix(n,FREECLUSTER,dm);
        n = n2;
    }

    /*
     * Mark the directory entry as erased.
     */
    fd = dn->d_ofd;
    ixlseek(fd,pos);
    c = (char)ERASE_MARKER;
    ixwrite(fd,1L,&c);
    ixclose(fd,CL_DIR);

    /*
     * NOTE that the preceding routines that do physical disk operations
     * will 'longjmp' on failure at the BIOS level, thereby allowing us to
     * simply return with E_OK.
     */
    return E_OK;
}
示例#3
0
/*  name: path name of file
 *  attr: atttributes
 */
long ixcreat(char *name, char attr)
{
    DND *dn;
    OFD *fd;
    FCB *f;
    const char *s;
    char n[2], a[11];                       /*  M01.01.03   */
    int i, f2;                              /*  M01.01.03   */
    long pos, rc;

    n[0] = (char)ERASE_MARKER; n[1] = 0;

    /* first find path */

    if ((long)(dn = findit(name,&s,0)) < 0) /* M01.01.1212.01 */
        return (long)dn;
    if (!dn)                                /* M01.01.1214.01 */
        return EPTHNF;

    if (!*s || (*s == '.'))         /*  no file name || '.' || '..' */
        return EPTHNF;

    /*  M01.01.0721.01  */
    if (contains_illegal_characters(s))
        return EACCDN;

    /*
     * if the volume label attribute is set, no others are allowed
     */
    if ((attr&FA_VOL) && (attr != FA_VOL))
        return EACCDN;

    /*
     * volume labels may only be created in the root
     */
    if ((attr == FA_VOL) && dn->d_parent)
        return EACCDN;

    if (!(fd = dn->d_ofd))
        fd = makofd(dn);            /* makofd() also updates dn->d_ofd */

    /*
     * if a matching file already exists, we delete it first.  note
     * that the definition of matching, and the action taken, differs
     * depending on whether the file is a volume label or not:
     *  . for a volume label, *any* existing volume label matches
     *    and will be deleted (reference: Rainbow TOS Release Notes)
     *  . for other files, the name must match, and the existing
     *    file will be deleted unless (a) it's read-only or a folder
     *    or (b) the file being created is a folder.
     */
    pos = 0;
    if (attr == FA_VOL)
        f = scan(dn,"*.*",FA_VOL,&pos);
    else f = scan(dn,s,FA_NORM|FA_SUBDIR,&pos);

    if (f)                  /* found matching file / label */
    {
        if (attr != FA_VOL) /* for normal files, need to check more stuff */
        {
                                        /* M01.01.0730.01   */
            if ((f->f_attrib & (FA_SUBDIR | FA_RO)) || (attr == FA_SUBDIR))
                return EACCDN;          /*  subdir or read only  */
        }
        pos -= 32;
        ixdel(dn,f,pos);
    }
    else
        pos = 0;

    /* now scan for empty space */

    /*  M01.01.SCC.FS.02  */
    while( !( f = scan(dn,n,0xff,&pos) ) )
    {
        /*  not in current dir, need to grow  */
        if (!fd->o_dnode)           /*  but can't grow root  */
            return EACCDN;

        if ( nextcl(fd,1) )
            return EACCDN;

        f = dirinit(dn);
        pos = 0;
    }

    builds(s,a);
    pos -= 32;
    f->f_attrib = attr;
    for (i = 0; i < 10; i++)
        f->f_fill[i] = 0;
    f->f_td.time = current_time;
    swpw(f->f_td.time);
    f->f_td.date = current_date;
    swpw(f->f_td.date);
    f->f_clust = 0;
    f->f_fileln = 0;
    ixlseek(fd,pos);
    ixwrite(fd,11L,a);              /* write name, set dirty flag */
    ixclose(fd,CL_DIR);             /* partial close to flush */
    ixlseek(fd,pos);
    s = (char*) ixread(fd,32L,NULL);
    f2 = rc = opnfil((FCB*)s,dn,(f->f_attrib&FA_RO)?RO_MODE:RW_MODE);

    if (rc < 0)
        return rc;

    getofd(f2)->o_flag |= O_DIRTY;

    return f2;
}
示例#4
0
/*
**  ixclose -
**
**  Error returns   EINTRN
**
**  Last modified   SCC     10 Apr 85
**
**  NOTE:   I'm not sure that returning immediately upon an error from
**          ixlseek() is the right thing to do.  Some data structures may
**          not be updated correctly.  Watch out for this!
**          Also, I'm not sure that the EINTRN return is ok.
*/
long ixclose(OFD *fd, int part)
{                                   /*  M01.01.03                   */
    OFD *p, **q;
    int i;                          /*  M01.01.03                   */
    BCB *b;

    /*
     * if the file or folder has been modified, we need to make sure
     * that the date/time, starting cluster, and file length in the
     * directory entry are updated.  In addition, for files, we must
     * set the archive flag.
     *
     * The following code avoids multiple ixlseek()/ixlread()/ixlwrite()
     * sequences by just getting a pointer to a buffer containing the
     * FCB, and updating it directly.  We must do an ixwrite() at the
     * end so that the buffer is marked as dirty and is subsequently
     * written.
     */
    if (fd->o_flag & O_DIRTY)
    {
        FCB *fcb;
        UBYTE attr;

        ixlseek(fd->o_dirfil,fd->o_dirbyt); /* start of dir entry */
        fcb = (FCB *)ixread(fd->o_dirfil,32L,NULL);
        attr = fcb->f_attrib;               /* get attributes */
        memcpy(&fcb->f_td,&fd->o_td,10);    /* copy date/time, start, length */
        swpw(fcb->f_clust);                 /*  & fixup byte order */
        swpl(fcb->f_fileln);

        if (part & CL_DIR)
            fcb->f_fileln = 0L;             /* dir lengths on disk are zero */
        else
            attr |= FA_ARCHIVE;             /* set the archive flag for files */

        ixlseek(fd->o_dirfil,fd->o_dirbyt+11);  /* seek to attrib byte */
        ixwrite(fd->o_dirfil,1,&attr);          /*  & rewrite it       */
    }

    if ((!part) || (part & CL_FULL))
    {
        q = &fd->o_dnode->d_files;

        for (p = *q; p ; p = *(q = &p->o_link))
            if (p == fd)
                break;

        /* someone else has this file open **** TBA */

        if (p)
            *q = p->o_link;
        else
            return EINTRN;  /* some kind of internal error */
    }

    /* only flush to appropriate drive ***** TBA ******/

    for (i = 0; i < 2; i++)
        for (b = bufl[i]; b; b = b->b_link)
            flush(b);

    return E_OK;
}
示例#5
0
文件: fsdir.c 项目: ragnar76/emutos
/*ARGSUSED*/
long xrename(int n, char *p1, char *p2)
{
        register OFD *fd2;
        OFD     *f1,*fd;
        FCB     *f;
        DND     *dn1,*dn2;
        const char *s1,*s2;
        char    buf[11];
        int     hnew,att;
        long    rc, h1;

        if (!ixsfirst(p2,0,(DTAINFO *)0L))
                return(EACCDN);

        if ((long)(dn1 = findit(p1,&s1,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn1 );
        if (!dn1)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if ((long)(dn2 = findit(p2,&s2,0)) < 0)          /* M01.01.1212.01 */
                return( (long)dn2 );
        if (!dn2)                                        /* M01.01.1214.01 */
                return( EPTHNF );

        if (contains_illegal_characters(s2))
                return( EACCDN ) ;

        if ((h1 = xopen(p1, 2)) < 0L)
                return (h1);

        f1 = getofd ((int)h1);

        fd = f1->o_dirfil;
        buf[0] = 0xe5;
        ixlseek(fd,f1->o_dirbyt);

        if (dn1 != dn2)
        {
                /* get old attribute */
                f = (FCB *) ixread(fd,32L,NULLPTR);
                att = f->f_attrib;
                /* erase (0xe5) old file */
                ixlseek(fd,f1->o_dirbyt);
                ixwrite(fd,1L,buf);

                /* copy time/date/clust, etc. */

                ixlseek(fd,f1->o_dirbyt + 22);
                ixread(fd,10L,buf);
                hnew = xcreat(p2,att);
                fd2 = getofd(hnew);
                ixlseek(fd2->o_dirfil,fd2->o_dirbyt + 22);
                ixwrite(fd2->o_dirfil,10L,buf);
                fd2->o_flag &= ~O_DIRTY;
                xclose(hnew);
                ixclose(fd2->o_dirfil,CL_DIR);
        }
        else
        {
                builds(s2,buf);
                ixwrite(fd,11L,buf);
        }

        if ((rc = xclose((int)h1)) < 0L)
                return(rc);

        return(ixclose(fd,CL_DIR));
}