Beispiel #1
0
unsigned deaccesshead(struct VIOC *vioc,struct HEAD *head,unsigned modmask)
{
#ifdef DEBUG
    printf("Deaccessing header %x\n",vioc->cache.keyval);
#endif
    if (modmask) head->fh2$w_checksum = checksum((u_word *) head);
    return deaccesschunk(vioc,modmask,1);
}
Beispiel #2
0
unsigned accesshead(struct VCB *vcb,struct fiddef *fid,
                    struct VIOC **vioc,struct HEAD **headbuff,
                    unsigned *modmask,unsigned wrtflg)
{
    register unsigned sts;
    register struct VCBDEV *vcbdev;
    register unsigned idxblk = fid->fid$w_num + (fid->fid$b_nmx << 16) - 1;
    if (fid->fid$b_rvn > vcb->devices) return SS$_NOSUCHFILE;
    if (fid->fid$b_rvn < 2) {
        vcbdev = vcb->vcbdev;
    } else {
        vcbdev = &vcb->vcbdev[fid->fid$b_rvn - 1];
    }
    if (vcbdev->dev == NULL) return SS$_NOSUCHFILE;
    if (wrtflg && ((vcb->status & VCB_WRITE) == 0)) return SS$_WRITLCK;
#ifdef DEBUG
    printf("Accessing header (%d,%d,%d)\n",(fid->fid$b_nmx << 16) +
           fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn);
#endif
    idxblk += vcbdev->home.hm2$w_ibmapvbn + vcbdev->home.hm2$w_ibmapsize;
    if (idxblk >= swapw(vcbdev->idxfcb->head->fh2$w_recattr.fat$l_efblk)) return SS$_NOSUCHFILE;
    sts = accesschunk(vcbdev->idxfcb,idxblk,vioc,(char **) headbuff,
                      NULL,wrtflg ? 1 : 0,modmask);
    if (sts & 1) {
        register struct HEAD *head = *headbuff;
        if (checksum((u_word *) head) != head->fh2$w_checksum) {
#ifdef DEBUG
            printf("Accesshead checksum %d != %d\n",checksum((u_word *) head),head->fh2$w_checksum);
#endif
            sts = SS$_NOSUCHFILE;
        } else {
            if (head->fh2$w_fid.fid$w_num != fid->fid$w_num ||
                head->fh2$w_fid.fid$b_nmx != fid->fid$b_nmx ||
                head->fh2$w_fid.fid$w_seq != fid->fid$w_seq ||
                (head->fh2$w_fid.fid$b_rvn != fid->fid$b_rvn &&
                 head->fh2$w_fid.fid$b_rvn != 0)) {
#ifdef DEBUG
                printf("Accesshead fileid doesn't match %d %d %d\n",
                       fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn);
#endif
                sts = SS$_NOSUCHFILE;
            } else {
                if (head->fh2$b_idoffset < 38 ||
                    head->fh2$b_idoffset > head->fh2$b_mpoffset ||
                    head->fh2$b_mpoffset > head->fh2$b_acoffset ||
                    head->fh2$b_acoffset > head->fh2$b_rsoffset ||
                    head->fh2$b_map_inuse > (head->fh2$b_acoffset - head->fh2$b_mpoffset)) {
#ifdef DEBUG
                    printf("Accesshead areas incorrect\n");
#endif
                    sts = SS$_NOSUCHFILE;
                }
            }
        }
        if ((sts & 1) == 0) deaccesschunk(*vioc,0,0);
    }
    return sts;
}
Beispiel #3
0
unsigned update_freecount(struct _vcb *vcbdev,unsigned *retcount)
{
    unsigned sts;
    unsigned free_clusters = 0;
    unsigned map_block, map_end;
    struct _scbdef * scb;
    sts = exttwo_accesschunk(getmapfcb(vcbdev),1,(char **) &scb,0,1,0);
    map_end = ((scb->scb$l_volsize/scb->scb$w_cluster) + 4095) / 4096 + 2;
    for (map_block = 2; map_block < map_end; )
    {
        unsigned blkcount;
        WORK_UNIT *bitmap,*work_ptr;
        unsigned work_count;
        sts = exttwo_accesschunk(getmapfcb(vcbdev),map_block,(char **) &bitmap,&blkcount,0,0);
        if (!(sts & 1)) return sts;
        if (blkcount > map_end - map_block) blkcount = map_end - map_block + 1;
        work_ptr = bitmap;
        work_count = blkcount * 512 / sizeof(WORK_UNIT);
        do
        {
            WORK_UNIT work_val = *work_ptr++;
            if (work_val == WORK_MASK)
            {
                free_clusters += WORK_BITS;
            }
            else
            {
                while (work_val != 0)
                {
                    if (work_val & 1) free_clusters++;
                    work_val = work_val >> 1;
                }
            }
        }
        while (--work_count > 0);
        sts = deaccesschunk(0,0,1);
        if (!(sts & 1)) return sts;
        map_block += blkcount;
    }
    *retcount = free_clusters;
    return sts;
}
Beispiel #4
0
unsigned sys_get(struct RAB *rab)
{
    char delim,*buffer,*output;
    unsigned cpylen,reclen,block,blocks,offset,eofblk;
    unsigned endflg,rfm,sts;
    struct VIOC *vioc;
    struct FCB *fcb = ifi_table[rab->rab$l_fab->fab$w_ifi]->wcf_fcb;

    rfm = rab->rab$l_fab->fab$b_rfm;
    if (rfm == FAB$C_STM || rfm == FAB$C_STMCR || rfm == FAB$C_STMLF) {
        delim = 1;
        if (rfm == FAB$C_STMLF) {
            delim = '\n';
        } else {
            if (rfm == FAB$C_STMCR) delim = '\r';
        }
        reclen = rab->rab$w_usz;
    } else {
        delim = 0;
        if (rfm == FAB$C_FIX) {
            reclen = rab->rab$l_fab->fab$w_mrs;
        }
    }

    offset = rab->rab$w_rfa[2] + rab->rab$w_rsz;
    block = (rab->rab$w_rfa[1] << 16) + rab->rab$w_rfa[0];
    if (block == 0 && offset == 0) {
        block = 1;
    } else {
        if (rab->rab$b_rac != RAB$C_RFA) {
            if (delim) {
                offset++;
            } else {
                if (rfm == FAB$C_VAR) {
                    offset += 2;
                } else {
                    if (rfm == FAB$C_VFC) offset += 2 + rab->rab$l_fab->fab$b_fsz;
                }
                if (offset & 1) offset++;
                if (rab->rab$l_fab->fab$b_rat & FAB$M_BLK) offset = (offset + 511) / 512 * 512;
            }
            block += offset / 512;
        }
    }
    rab->rab$w_rfa[0] = block & 0xffff;
    rab->rab$w_rfa[1] = block >> 16;
    rab->rab$w_rfa[2] = offset = offset % 512;


    eofblk = swapw(fcb->head->fh2$w_recattr.fat$l_efblk);
    if (block > eofblk || (block == eofblk &&
                           offset >= fcb->head->fh2$w_recattr.fat$w_ffbyte)) return RMS$_EOF;
    sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0,NULL);
    if ((sts & 1) == 0) return sts;

    if (rfm == FAB$C_VAR || rfm == FAB$C_VFC) {
        unsigned short *lenptr = (unsigned short *) (buffer + offset);
        reclen = *lenptr;
        offset += 2;
    }
#ifdef DEBUG
    printf("Block %d Offset %d Reclen %d Eofblk %d\n",block,offset,reclen,eofblk);
#endif

    if (reclen > rab->rab$w_usz) {
        sts = deaccesschunk(vioc,0,0);
        return RMS$_RTB;
    }
    endflg = 0;
    if (block + reclen / 512 >= eofblk) {
        unsigned remaining = (eofblk - block) * 512 - offset +
           fcb->head->fh2$w_recattr.fat$w_ffbyte;
        if (remaining < reclen) {
            reclen = remaining;
            endflg = 1;
        }
    }
    cpylen = 0;
    output = rab->rab$l_ubf;
    while (cpylen < reclen) {
        unsigned seglen = blocks * 512 - offset;
        if (seglen > reclen - cpylen) seglen = reclen - cpylen;
        if (delim) {
            char *inptr = buffer + offset;
            if (delim != 1) {
                while (seglen-- > 0) {
                    char ch = *inptr++;
                    if (ch == delim) {
                        reclen = cpylen;
                        break;
                    }
                    if (cpylen++ < reclen) {
                        *output++ = ch;
                    } else {
                        sts = RMS$_RTB;
                        reclen = cpylen;
                        break;
                    }
                }
            } else {
                while (seglen-- > 0) {
                    char ch = *inptr++;
                    if (ch != 0 || cpylen > 0) {
                        if (ch == '\f' || ch == '\v' || ch == '\n' || ch == '\r') {
                            reclen = cpylen;
                        } else {
                            if (cpylen++ < reclen) {
                                *output++ = ch;
                            } else {
                                sts = RMS$_RTB;
                                reclen = cpylen;
                                break;
                            }
                        }
                    }
                }
            }
            if (cpylen == reclen && endflg) break;
        } else {
            if (rfm == FAB$C_VFC) {
                unsigned fsz = rab->rab$l_fab->fab$b_fsz;
                if (fsz > seglen) fsz = seglen;
                if (cpylen < fsz) {
                    fsz = fsz - cpylen;
                    if (rab->rab$l_rhb) memcpy(rab->rab$l_rhb + cpylen,buffer + offset,fsz);
                    cpylen += fsz;
                    offset += fsz;
                    seglen -= fsz;
                }
            }
            memcpy(output,buffer + offset,seglen);
            output += seglen;
            cpylen += seglen;
        }
        if (cpylen < reclen) {
            sts = deaccesschunk(vioc,0,0);
            block += blocks;
            if (block > eofblk) return RMS$_EOF;
            sts = accesschunk(fcb,block,&vioc,&buffer,&blocks,0,NULL);
            if ((sts & 1) == 0) return sts;
            offset = 0;
        }
    }
    if (rfm == FAB$C_VFC) {
        rab->rab$w_rsz = cpylen - rab->rab$l_fab->fab$b_fsz;;
    } else {
        rab->rab$w_rsz = cpylen;
    }
    deaccesschunk(vioc,0,1);
    return sts;
}
Beispiel #5
0
unsigned deallocfile(struct FCB *fcb)
{
    register unsigned sts = 1;
    /*
        First mark all file clusters as free in BITMAP.SYS
    */
    register unsigned vbn = 1;
    while (vbn <= fcb->hiblock) {
        register unsigned sts;
        unsigned rvn,mapblk,maplen;
        register struct VCBDEV *vcbdev;
        sts = getwindow(fcb,vbn,&rvn,&mapblk,&maplen);
        if ((sts & 1) == 0) break;
        if (rvn > fcb->vcb->devices) break;
        if (rvn < 2) {
            vcbdev = fcb->vcb->vcbdev;
        } else {
            vcbdev = &fcb->vcb->vcbdev[rvn - 1];
        }
        if (vcbdev->dev == NULL) {
            break;
        } else {
            unsigned *bitmap,blkcount,modmask;
            struct VIOC *vioc;
            register unsigned clustersz = vcbdev->home.hm2$w_cluster;
            register unsigned clusterno = mapblk / clustersz;
            sts = accesschunk(vcbdev->mapfcb,clusterno / 4096 + 2,
                              &vioc,(char **) &bitmap,&blkcount,1,&modmask);
            if (sts & 1) {
                register unsigned wordno = (clusterno % 4096) / (sizeof(unsigned) * 8);
                register unsigned bitno = clusterno % (sizeof(unsigned) * 8);
                do {
                    register unsigned mask = 1 << bitno;
                    vbn += clustersz;
                    maplen -= clustersz;
                    while (maplen > 0 && ++bitno < (sizeof(unsigned) * 8)) {
                        mask |= (mask << 1);
                        vbn += clustersz;
                        maplen -= clustersz;
                    }
                    bitmap[wordno++] |= mask;
                    bitno = 0;
                } while (maplen > 0 && wordno < blkcount / (sizeof(unsigned) * 8));
                sts = deaccesschunk(vioc,modmask,1);
            }
        }
    }
    /*
        Now reset file header bit map in INDEXF.SYS and
        update each of the file headers...
    */
    {
        unsigned rvn = fcb->rvn;
        unsigned modmask = fcb->modmask;
        struct HEAD *head = fcb->head;
        struct VIOC *headvioc = fcb->headvioc;
        do {
            struct fiddef extfid;
            register struct VCBDEV *vcbdev;
            if (rvn > fcb->vcb->devices) break;
            if (rvn < 2) {
                vcbdev = fcb->vcb->vcbdev;
            } else {
                vcbdev = &fcb->vcb->vcbdev[rvn - 1];
            }
            if (vcbdev->dev == NULL) {
                break;
            } else {
                unsigned *bitmap,viocmask;
                struct VIOC *vioc;
                register unsigned fileno = (head->fh2$w_fid.fid$b_nmx << 16) +
                         head->fh2$w_fid.fid$w_num - 1;
                register unsigned idxblk = fileno / 4096 +
                    vcbdev->home.hm2$w_cluster * 4 + 1;
                sts = accesschunk(vcbdev->idxfcb,idxblk,&vioc,
                                  (char **) &bitmap,NULL,1,&viocmask);
                if (sts & 1) {
                    bitmap[(fileno % 4096) / (sizeof(unsigned) * 8)] &=
                         ~(1 << (fileno % (sizeof(unsigned) * 8)));
                    sts = deaccesschunk(vioc,viocmask,1);
                } else {
                    break;
                }
            }
            head->fh2$w_fid.fid$w_num = 0;
            head->fh2$w_fid.fid$b_rvn = 0;
            head->fh2$w_fid.fid$b_nmx = 0;
            head->fh2$w_checksum = 0;
            memcpy(&extfid,&fcb->head->fh2$w_ext_fid,sizeof(struct fiddef));
            sts = deaccesshead(headvioc,head,modmask);
            if ((sts & 1) == 0) break;
            if (extfid.fid$b_rvn == 0) {
                extfid.fid$b_rvn = rvn;
            } else {
                rvn = extfid.fid$b_rvn;
            }
            if (extfid.fid$w_num != 0 || extfid.fid$b_nmx != 0) {
                sts = accesshead(fcb->vcb,&extfid,&headvioc,&head,&modmask,1);
                if ((sts & 1) == 0) break;
            } else {
                break;
            }
        } while (1);
        if (sts & 1) {
            fcb->headvioc = NULL;
            cacheuntouch(&fcb->cache,0,1);
            cachedelete(&fcb->cache);
        }
    }
    return sts;
}