Example #1
0
unsigned accessfile(struct VCB * vcb,struct fiddef * fid,struct FCB **fcbadd,
                    unsigned wrtflg)
{
    register struct FCB *fcb;
    unsigned create = sizeof(struct FCB);
    register unsigned fileno = (fid->fid$b_nmx << 16) + fid->fid$w_num;
#ifdef DEBUG
    printf("Accessing file (%d,%d,%d)\n",(fid->fid$b_nmx << 16) +
           fid->fid$w_num,fid->fid$w_seq,fid->fid$b_rvn);
#endif
    if (fileno < 1) return SS$_BADPARAM;
    if (wrtflg && ((vcb->status & VCB_WRITE) == 0)) return SS$_WRITLCK;
    if (fid->fid$b_rvn > 1) fileno |= ((fid->fid$b_rvn - 1) << 24);
    fcb = cachesearch((void *) &vcb->fcb,fileno,0,NULL,NULL,&create);
    if (fcb == NULL) return SS$_INSFMEM;
    /* If not found make one... */
    if (create == 0) {
        fcb->cache.status |= 0x100;     /* For debugging! */
        fcb->rvn = fid->fid$b_rvn;
        if (fcb->rvn == 0 && vcb->devices > 1) fcb->rvn = 1;
        fcb->vcb = vcb;
        fcb->wcb = NULL;
        fcb->headvioc = NULL;
        fcb->vioc = NULL;
        fcb->cache.objmanager = fcbmanager;
    }
    if (wrtflg) {
        if (fcb->headvioc != NULL && (fcb->cache.status & CACHE_WRITE) == 0) {
            deaccesshead(fcb->headvioc,NULL,0);
            fcb->headvioc = NULL;
        }
        fcb->cache.status |= CACHE_WRITE;
    }
    if (fcb->headvioc == NULL) {
        register unsigned sts;
        if (vcb->idxboot != NULL) {
            *fcbadd = fcb;
            fcb->hiblock = 32767;       /* guess at indexf.sys file size */
            fcb->highwater = 0;
            fcb->head = vcb->idxboot;   /* Load bootup header */
        }
        sts = accesshead(vcb,fid,&fcb->headvioc,&fcb->head,&fcb->modmask,wrtflg);
        if (sts & 1) {
            fcb->hiblock = swapw(fcb->head->fh2$w_recattr.fat$l_hiblk);
            if (fcb->head->fh2$b_idoffset > 39) {
                fcb->highwater = fcb->head->fh2$l_highwater;
            } else {
                fcb->highwater = 0;
            }
        } else {
            fcb->cache.objmanager = NULL;
            cacheuntouch(&fcb->cache,0,0);
            cachefree(&fcb->cache);
            return sts;
        }
    }
    *fcbadd = fcb;
    return SS$_NORMAL;
}
Example #2
0
/* ast parser, the way we pass context around is very very hacky... */
searchNode *search_astparse(searchCtx *ctx, char *loc) {
  searchASTCache *cache = ctx->arg;
  searchASTExpr *expr = cachesearch(cache, (exprunion *)&loc);
  searchNode *node;
  char **v;
  int i;

  if(!expr) {
    parseError = "WARNING: AST parsing failed";
    return NULL;
  }

  switch(expr->type) {
    case AST_NODE_LITERAL:
      if (!(node=(searchNode *)malloc(sizeof(searchNode)))) {
        parseError = "malloc: could not allocate memory for this search.";
        return NULL;
      }
      node->localdata  = getsstring(expr->u.literal,512);
      node->returntype = RETURNTYPE_CONST | RETURNTYPE_STRING;
      node->exe        = literal_exe;
      node->free       = literal_free;
      return node;
    case AST_NODE_CHILD:
      v = (char **)malloc(expr->u.child.argc * sizeof(char *));
      if(!v) {
        parseError = "malloc: could not allocate memory for this search.";
        return NULL;
      }
      for(i=0;i<expr->u.child.argc;i++) {
        searchASTExpr *child = &expr->u.child.argv[i];

        cachepush(cache, child);
        switch(child->type) {
          case AST_NODE_LITERAL:
            v[i] = child->u.literal;
            break;
          case AST_NODE_CHILD:
            v[i] = (char *)child;
            break;
          default:
            parseError = "static_parse: bad child node type";
            free(v);
            return NULL;
        }
      }

      node = expr->u.child.fn(ctx, expr->u.child.argc, v);
      free(v);
      return node;
   default:
      parseError = "static_parse: bad node type";
      return NULL;
  }
}
Example #3
0
unsigned dircache(struct VCB *vcb,char *dirnam,int dirlen,struct fiddef *dirid)
{
    register struct DIRCACHE *dir;
    if (dirlen < 1) {
        dirid->fid$w_num = 4;
        dirid->fid$w_seq = 4;
        dirid->fid$b_rvn = 0;
        dirid->fid$b_nmx = 0;
        return 1;
    } else {
        unsigned create = 0;
        dir = cachesearch((void *) &vcb->dircache,0,dirlen,dirnam,dircmp,&create);
        if (dir != NULL) {
            memcpy(dirid,&dir->dirid,sizeof(struct fiddef));
            return 1;
        }
        return 0;
    }
}
Example #4
0
unsigned accesschunk(struct FCB *fcb,unsigned vbn,struct VIOC **retvioc,
                     char **retbuff,unsigned *retblocks,unsigned wrtblks,
                     unsigned *retmodmask)
{
    /*
        First find cache entry...
    */
    register struct VIOC *vioc;
    unsigned create = sizeof(struct VIOC);
    register unsigned base = (vbn - 1) / VIOC_CHUNKSIZE * VIOC_CHUNKSIZE + 1;
#ifdef DEBUG
    printf("Access chunk %8x %d (%x)\n",base,vbn,fcb->cache.keyval);
#endif
    if (wrtblks && ((fcb->cache.status & CACHE_WRITE) == 0)) return SS$_WRITLCK;
    if (vbn < 1 || vbn > fcb->hiblock) return SS$_ENDOFFILE;
    vioc = cachesearch((void *) &fcb->vioc,base,0,NULL,NULL,&create);
    if (vioc == NULL) return SS$_INSFMEM;
    /*
        If not found make one...
    */
    if (create == 0) {
        register unsigned length;
        register char *address;
        register unsigned mapbase = base;
        vioc->cache.status |= 0x400;    /* For debugging! */
        vioc->fcb = fcb;
        vioc->wrtmask = 0;
        vioc->modmask = 0;
        length = fcb->hiblock - mapbase + 1;
        if (length > VIOC_CHUNKSIZE) length = VIOC_CHUNKSIZE;
        address = (char *) vioc->data;
        do {
            if (fcb->highwater > 0 && mapbase >= fcb->highwater) {
                memset(address,0,length * 512);
                length = 0;
            } else {
                register unsigned sts;
                unsigned rvn,mapblk,maplen;
                register struct VCBDEV *vcbdev;
                sts = getwindow(fcb,mapbase,&rvn,&mapblk,&maplen);
                if (sts & 1) {
                    if (maplen > length) maplen = length;
                    if (fcb->highwater > 0 && mapbase + maplen > fcb->highwater) {
                        maplen = fcb->head->fh2$l_highwater - mapbase;
                    }
                    if (rvn > fcb->vcb->devices) {
                        sts = SS$_NOSUCHFILE;
                    } else {
                        if (rvn < 2) {
                            vcbdev = fcb->vcb->vcbdev;
                        } else {
                            vcbdev = &fcb->vcb->vcbdev[rvn - 1];
                        }
                        if (vcbdev->dev == NULL) return SS$_NOSUCHFILE;
                        sts = phyio_read(vcbdev->dev->handle,mapblk,maplen * 512,address);
                    }
                }
                if ((sts & 1) == 0) {
                    cacheuntouch(&vioc->cache,0,0);
                    cachefree(&vioc->cache);
                    return sts;
                }
                length -= maplen;
                mapbase += maplen;
                address += maplen * 512;
            }
        } while (length > 0);
    }
    if (wrtblks) {
        vioc->cache.status |= CACHE_WRITE;
        vioc->cache.objmanager = viocmanager;
    }
    /*
        Return result to caller...
    */
    *retvioc = vioc;
    *retbuff = vioc->data[vbn - base];
    if (wrtblks || retblocks != NULL || retmodmask != NULL) {
        register unsigned modmask = 0;
        register unsigned blocks = base + VIOC_CHUNKSIZE - vbn;
        if (blocks > fcb->hiblock - vbn) blocks = fcb->hiblock - vbn + 1;
            if (wrtblks) if (blocks > wrtblks) blocks = wrtblks;
        if (retblocks != NULL) *retblocks = blocks;
        if (wrtblks) {
            modmask = 1 << (vbn - base);
            if (blocks > 1) {
                while (--blocks > 0) modmask |= modmask << 1;
            }
            vioc->wrtmask |= modmask;
        }
        if (retmodmask != NULL) *retmodmask = modmask;
    }
    return SS$_NORMAL;
}
Example #5
0
unsigned getwindow(struct FCB * fcb,unsigned vbn,unsigned *phyrvn,unsigned *phyblk,unsigned *phylen)
{
    register struct WCB *wcb;
    struct WCB *prev_wcb = NULL;
    unsigned create = sizeof(struct WCB);
#ifdef DEBUG
    printf("Accessing window for vbn %d, file (%x)\n",vbn,fcb->cache.keyval);
#endif
    wcb = cachesearch((void *) &fcb->wcb,0,vbn,&prev_wcb,wincmp,&create);
    if (wcb == NULL) return SS$_INSFMEM;
    /* If not found make one... */
    if (create == 0) {
        register unsigned wd_base,wd_exts;
        unsigned prev_hiblk,rvn;
        struct VIOC *vioc;
        struct HEAD *head;
        wcb->cache.status |= 0x200;     /* For debugging! */
        vioc = NULL;
        wd_base = 1;
        rvn = fcb->rvn;
        head = fcb->head;
        prev_hiblk = 0;
        if (prev_wcb != NULL) {
            register unsigned sts;
            register struct fiddef *fid = &prev_wcb->hd_fid;
            register struct fiddef *filefid = &fcb->head->fh2$w_fid;
            if (fid->fid$w_num != filefid->fid$w_num ||
                fid->fid$b_nmx != filefid->fid$b_nmx ||
                ((fid->fid$b_rvn > 1 || fcb->rvn > 1) && fid->fid$b_rvn != fcb->rvn)) {
                wd_base = prev_wcb->hd_base;
                rvn = prev_wcb->hd_fid.fid$b_rvn;
                sts = accesshead(fcb->vcb,fid,&vioc,&head,NULL,0);
                if ((sts & 1) == 0) {
                    cacheuntouch(&wcb->cache,0,0);
                    cachefree(&wcb->cache);
                    return sts;
                }
            }
            prev_hiblk = prev_wcb->hiblk;
        }
        wcb->hd_base = wd_base;
        wd_exts = 0;
#ifdef DEBUG
        printf("Making window %d %d\n",wd_base,prev_hiblk);
#endif
        do {
            register unsigned short *mp = (unsigned short *) head + head->fh2$b_mpoffset;
            register unsigned short *me = mp + head->fh2$b_map_inuse;
            while (mp < me) {
                register unsigned phylen,phyblk;
                switch ((*mp) >> 14) {
                    case 0:
                        phylen = 0;
                        mp++;
                        break;
                    case 1:
                        phylen = ((*mp) & 0377) + 1;
                        phyblk = (((*mp) & 037400) << 8) + mp[1];
                        mp += 2;
                        break;
                    case 2:
                        phylen = ((*mp) & 037777) + 1;
                        phyblk = (mp[2] << 16) + mp[1];
                        mp += 3;
                        break;
                    case 3:
                        phylen = (((*mp) & 037777) << 16) + mp[1] + 1;
                        phyblk = (mp[3] << 16) + mp[2];
                        mp += 4;
                }
                if (phylen > 0 && wd_base > prev_hiblk) {
                    register struct EXT *ext;
                    if (wd_exts == 0) wcb->loblk = wd_base;
                    ext = &wcb->ext[wd_exts++];
                    ext->phylen = phylen;
                    ext->phyblk = phyblk;
                    wd_base += phylen;
                    if (wd_exts >= EXTMAX) {
                        if (wd_base > vbn) {
                            break;
                        } else {
                            wd_exts = 0;
                        }
                    }
                } else {
                    wd_base += phylen;
                }
            }
            if (wd_base > vbn) {
                break;
            } else {
                register unsigned sts;
                struct fiddef extfid;
                memcpy(&extfid,&head->fh2$w_ext_fid,sizeof(struct fiddef));
                if (extfid.fid$b_rvn != 0 && extfid.fid$b_rvn != rvn) {
                    wd_exts = 0;/* Can't let window extend across devices */
                    rvn = extfid.fid$b_rvn;
                } else {
                    extfid.fid$b_rvn = rvn;
                }
                if (vioc != NULL) deaccesshead(vioc,NULL,0);
                sts = accesshead(fcb->vcb,&extfid,&vioc,&head,NULL,0);
                if ((sts & 1) == 0) {
                    cacheuntouch(&wcb->cache,0,0);
                    cachefree(&wcb->cache);
                    return sts;
                }
                wcb->hd_base = wd_base;
            }
        } while (wd_base <= vbn);
        memcpy(&wcb->hd_fid,&head->fh2$w_fid,sizeof(struct fiddef));
        wcb->hd_fid.fid$b_rvn = rvn;
        wcb->hiblk = wd_base - 1;
        wcb->extcount = wd_exts;
        if (vioc != NULL) deaccesshead(vioc,NULL,0);
    } {
        register struct EXT *ext = wcb->ext;
        register unsigned extcnt = wcb->extcount;
        register unsigned togo = vbn - wcb->loblk;
        while (togo >= ext->phylen) {
            togo -= (ext++)->phylen;
            if (extcnt-- < 1) return SS$_BUGCHECK;
        }
        *phyrvn = wcb->hd_fid.fid$b_rvn;
        *phyblk = ext->phyblk + togo;
        *phylen = ext->phylen - togo;
#ifdef DEBUG
        printf("Mapping vbn %d to %d (%d -> %d)[%d] file (%x)\n",
               vbn,*phyblk,wcb->loblk,wcb->hiblk,wcb->hd_base,fcb->cache.keyval);
#endif
        cacheuntouch(&wcb->cache,1,0);
    }
    return SS$_NORMAL;
}