Пример #1
0
/* p: start of path element to crack
 * d: ptr to destination buffer
 * dirspec: true = no file name, just dir path
 */
static int getpath(const char *p, char *d, int dirspec)
{
        register int    i, i2 ;
        register const char *p1 ;

        for( i = 0 , p1 = p ; *p1 && (*p1 != SLASH) ; p1++ , i++ )
                ;

        /*
        **  If the string we have just scanned over is a directory name, it
        **      will either be terminated by a SLASH, or 'dirspec' will be set 
        **      indicating that we are dealing with a directory path only
        **      (no file name at the end).
        */

        if( *p1 != '\0'  ||  dirspec )
        {       /*  directory name  */
                i2 = 0 ;
                if (p[0] == '.')                /*  dots in name        */
                {
                        i2--;                   /*  -1 for dot          */
                        if (p[1] == '.')
                                i2--;           /*  -2 for dotdot       */
                        return(i2);
                }

                if( i )                         /*  if not null path el */
                        builds(p,d);            /*  d => dir style fn   */

                return(i);                      /*  return nbr chars    */
        }

        return(0);              /*  if string is a file name            */
}
Пример #2
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;
}
Пример #3
0
/*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));
}
Пример #4
0
FCB     *scan(register DND *dnd, const char *n, WORD att, LONG *posp)
{ 
        char    name[12];
        register FCB *fcb;
        OFD     *fd;
        DND     *dnd1;
        BOOL    m;              /*  T: found a matching FCB             */

#if DBGFSDIR
        kprintf("scan(%p, '%s', 0x%x, %p)\n", dnd, n, att, posp);
#endif

        m = 0;                  /*  have_match = false                  */
        builds(n,name);         /*  format name into dir format         */
        name[11] = att;

        dnd1 = 0; /* dummy to avoid warning */

        /*
        **  if there is no open file descr for this directory, make one
        */

        if (!(fd = dnd->d_ofd))
        {
                if (!(dnd->d_ofd = (fd = makofd(dnd))))
                {
                        return ( (FCB *) 0 );
                }
        }

        /*
        **  seek to desired starting position.  If posp == -1, then start at
        **      the beginning.
        */

        ixlseek( fd , (*posp == -1) ? 0L : *posp ) ;

        /*
        **  scan thru the directory file, looking for a match
        */

        while ((fcb = (FCB *) ixread(fd,32L,NULLPTR)) && (fcb->f_name[0]))
        {
                /* 
                **  Add New DND.
                **  ( iff after scan ptr && complete flag not set && not a . 
                **  or .. && subdirectory && not deleted ) M01.01.0512.01
                */

                if( (fcb->f_attrib & FA_SUBDIR)         &&
#if     ! M0101052901
                    (!(fd->o_flag & O_COMPLETE))        &&
#endif
                    (fcb->f_name[0] != '.')             && 
                    (fcb->f_name[0] != (char)0xe5)
                )
                {       /*  see if we already have it  */
                        dnd1 = getdnd( &fcb->f_name[0] , dnd ) ;
                        if (!dnd1)
                                if (!(dnd1 = makdnd(dnd,fcb)))
                                        return( NULLPTR ) ;
                }

                if ( (m = match( name , fcb->f_name )) )
                                        break;
        }

#if DBGFSDIR
        kprintf("\n   scan(pos=%ld DND=%08lx DNDfoundFile=%08lx name=%s name1=%s, %d)",
                (long)fd->o_bytnum, (long)dnd, (long)dnd1, fcb->f_name, name, m);
#endif
        /* restore directory scanning pointer */

        if( *posp != -1L )
                *posp = fd->o_bytnum ;

        /*
        **  if there was no match, but we were looking for a deleted entry,
        **  then return a pointer to a deleted fcb.  Otherwise, if there was
        **  no match, return a null pointer
        */

        if (!m)
        {       /*  assumes that (*n != 0xe5) (if posp == -1)  */
                if( fcb && (*n == (char)0xe5) )
                        return(fcb) ;
#if     ! M0101052901
                fd->o_flag |= O_COMPLETE;
#endif
                return( (FCB *) 0 );
        }

        if (*posp == -1)
        {       /*  seek to position of found entry  */
                ixlseek(fd,fd->o_bytnum - 32);
                return(((FCB *) dnd1));
        }

        return(fcb);
}