/* * adfGetDirEnt * */ struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect ) { return adfGetRDirEnt(vol, nSect, FALSE); }
int main(int argc, char* argv[]) { int i, j; BOOL rflag, lflag, xflag, cflag, vflag, sflag, dflag, pflag, qflag; struct List* files, *rtfiles; char *devname, *dirname; char strbuf[80]; unsigned char *extbuf; int vInd, dInd, fInd, aInd; BOOL nextArg; struct Device *dev; struct Volume *vol; struct List *list, *cell; int volNum; BOOL true = TRUE; if (argc<2) { help(); exit(0); } rflag = lflag = cflag = vflag = sflag = dflag = pflag = qflag = FALSE; vInd = dInd = fInd = aInd = -1; xflag = TRUE; dirname = NULL; devname = NULL; files = rtfiles = NULL; volNum = 0; fprintf(stderr,"unADF v%s : a unzip like for .ADF files, powered by ADFlib (v%s - %s)\n\n", UNADF_VERSION, adfGetVersionNumber(),adfGetVersionDate()); /* parse options */ i=1; while(i<argc) { if (argv[i][0]=='-') { j=1; nextArg = FALSE; while(j<(int)strlen(argv[i]) && !nextArg) { switch(argv[i][j]) { case 'v': vflag = TRUE; if ((i+1)<(argc-1)) { i++; nextArg = TRUE; errno = 0; volNum = atoi(argv[i]); if (errno!=0 || volNum<0) { fprintf(stderr,"invalid volume number, aborting.\n"); exit(1); } } else fprintf(stderr,"no volume number, -v option ignored.\n"); break; case 'l': lflag = TRUE; xflag = FALSE; break; case 's': sflag = TRUE; break; case 'c': cflag = TRUE; break; case 'r': rflag = TRUE; break; case 'd': if (devname!=NULL && xflag && (i+1)==(argc-1)) { i++; dirname = argv[i]; if (dirname[strlen(dirname)-1]==DIRSEP) dirname[strlen(dirname)-1]='\0'; nextArg = TRUE; dflag = TRUE; } break; case 'p': if (xflag) { fprintf(stderr,"sending files to pipe.\n"); pflag = TRUE; qflag = TRUE; } else fprintf(stderr,"-p option must be used with extraction, ignored.\n"); break; case 'h': default: help(); exit(0); } /* switch */ j++; } /* while */ } /* if */ else { /* the last non option string is taken as a filename */ if (devname==NULL) /* if the device name has been already given */ devname = argv[i]; else { if (xflag) { if (rtfiles==NULL) rtfiles = files = newCell(NULL, (void*)argv[i]); else files = newCell(files, (void*)argv[i]); } else fprintf(stderr,"Must be used with extraction, ignored.\n"); } } i++; } /* while */ extbuf =(unsigned char*)malloc(EXTBUFL*sizeof(char)); if (!extbuf) { fprintf(stderr,"malloc error\n"); exit(1); } /* initialize the library */ adfEnvInitDefault(); dev = adfMountDev( devname,TRUE ); if (!dev) { sprintf(strbuf,"Can't mount the dump device '%s'.\n", devname); fprintf(stderr, strbuf); adfEnvCleanUp(); exit(1); } if (!qflag) printDev(dev); if (volNum>=dev->nVol) { fprintf(stderr,"This device has only %d volume(s), aborting.\n",dev->nVol); exit(1); } vol = adfMount(dev, volNum, TRUE); if (!vol) { adfUnMountDev(dev); fprintf(stderr, "Can't mount the volume\n"); adfEnvCleanUp(); exit(1); } if (!qflag) { printVol(vol, volNum); putchar('\n'); } if (cflag && isDIRCACHE(vol->dosType) && lflag) { adfChgEnvProp(PR_USEDIRC,&true); if (!qflag) puts("Using dir cache blocks."); } if (lflag) { if (!rflag) { cell = list = adfGetDirEnt(vol,vol->curDirPtr); while(cell) { printEnt(vol,cell->content,"", sflag); cell = cell->next; } adfFreeDirList(list); } else { cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE); printTree(vol,cell,"", sflag); adfFreeDirList(list); } }else if (xflag) { if (rtfiles!=NULL) { files = rtfiles; while(files!=NULL) { if (dirname!=NULL) processFile(vol, (char*)files->content, dirname, extbuf, pflag, qflag); else processFile(vol, (char*)files->content, "", extbuf, pflag, qflag); files = files->next; } freeList(rtfiles); } else { cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE); if (dirname==NULL) extractTree(vol, cell, "", extbuf, pflag, qflag); else extractTree(vol, cell, dirname, extbuf, pflag, qflag); adfFreeDirList(list); } } else help(); free(extbuf); adfUnMount(vol); adfUnMountDev(dev); adfEnvCleanUp(); return(0); }
/* * adfGetRDirEnt * */ struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM nSect, BOOL recurs ) { struct bEntryBlock entryBlk; struct List *cell, *head; int i; struct Entry *entry; SECTNUM nextSector; int32_t *hashTable; struct bEntryBlock parent; if (adfEnv.useDirCache && isDIRCACHE(vol->dosType)) return (adfGetDirEntCache(vol, nSect, recurs )); if (adfReadEntryBlock(vol,nSect,&parent)!=RC_OK) return NULL; hashTable = parent.hashTable; cell = head = NULL; for(i=0; i<HT_SIZE; i++) { if (hashTable[i]!=0) { entry = (struct Entry *)calloc(1,sizeof(struct Entry)); if (!entry) { adfFreeDirList(head); (*adfEnv.eFct)("adfGetDirEnt : malloc"); return NULL; } if (adfReadEntryBlock(vol, hashTable[i], &entryBlk)!=RC_OK) { adfFreeDirList(head); return NULL; } if (adfEntBlock2Entry(&entryBlk, entry)!=RC_OK) { adfFreeDirList(head); return NULL; } entry->sector = hashTable[i]; if (head==NULL) head = cell = newCell(0, (void*)entry); else cell = newCell(cell, (void*)entry); if (cell==NULL) { adfFreeDirList(head); return NULL; } if (recurs && entry->type==ST_DIR) cell->subdir = adfGetRDirEnt(vol,entry->sector,recurs); /* same hashcode linked list */ nextSector = entryBlk.nextSameHash; while( nextSector!=0 ) { entry = (struct Entry *)calloc(1,sizeof(struct Entry)); if (!entry) { adfFreeDirList(head); (*adfEnv.eFct)("adfGetDirEnt : malloc"); return NULL; } if (adfReadEntryBlock(vol, nextSector, &entryBlk)!=RC_OK) { adfFreeDirList(head); return NULL; } if (adfEntBlock2Entry(&entryBlk, entry)!=RC_OK) { adfFreeDirList(head); return NULL; } entry->sector = nextSector; cell = newCell(cell, (void*)entry); if (cell==NULL) { adfFreeDirList(head); return NULL; } if (recurs && entry->type==ST_DIR) cell->subdir = adfGetRDirEnt(vol,entry->sector,recurs); nextSector = entryBlk.nextSameHash; } } } /* if (parent.extension && isDIRCACHE(vol->dosType) ) adfReadDirCache(vol,parent.extension); */ return head; }