home *** CD-ROM | disk | FTP | other *** search
- /* SCCS Id: @(#)multi.c 3.1 93/01/08
- /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993 */
- /* NetHack may be freely redistributed. See license for details. */
-
- /*
- * NB - internal structure under development. End users should NOT
- * get too creative!
- */
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <dos.h>
- #include <string.h>
- #include <assert.h>
- #include "multi.h"
-
- static int start_next_file(multifh *); /* should return enum */
- BPTR
- MultiOpen(char *dirfile, ULONG mode, union multiopts *mo){
- multifh *retval;
-
- assert(mode==MODE_OLDFILE); /* no chioce this version */
- retval=(multifh *)AllocMem(sizeof(multifh),MEMF_CLEAR);
- if(retval){
- retval->mfh_dirfh=Open(dirfile,MODE_OLDFILE);
- if(retval->mfh_dirfh){
- retval->mfh_mo= *mo;
- if(start_next_file(retval)==1){
- return((BPTR)retval); /* success */
- }
- }
- }
-
- if(retval)FreeMem(retval,sizeof(multifh));
- return 0;
- }
-
- ULONG
- MultiRead(BPTR xmfp, ULONG *where, ULONG len){
- multifh *mfp=(multifh *)xmfp;
- ULONG sofar=0;
- ULONG this;
-
- if(len<=0)return len;
- if(mfp->mfh_fh==0)return 0; /* pending EOF (possibly premature) */
-
- while(sofar<len){
- this=Read(mfp->mfh_fh,where,len-sofar);
- if(this==-1) return -1;
- if(this==0){
- Close(mfp->mfh_fh);
- mfp->mfh_fh=0;
- if(start_next_file(mfp)<=0){
- return sofar;
- }
- }
- sofar += this; where += this;
- }
- return sofar;
- }
-
- void
- MultiClose(BPTR xmfp){
- multifh *mfp=(multifh *)xmfp;
- if(mfp->mfh_dirfh)Close(mfp->mfh_dirfh);
- if(mfp->mfh_fh)Close(mfp->mfh_fh);
- FreeMem(mfp,sizeof(multifh));
- }
-
- /* return 0==no more data, -1 error. else more data available unless file
- * is empty
- */
- static
- start_next_file(multifh *mfp){
- ULONG t;
- char line[100]; /* should be based on PATHLEN */
- char *eol;
-
- while(1){
- t=Read(mfp->mfh_dirfh,line,99);
- if(t==0)return(0);
- if(t==-1)return(-1);
-
- line[t]='\0';
- eol=strchr(line,'\n');
- if(eol){
- *eol='\0';
- Seek(mfp->mfh_dirfh,-(t-(eol-line))+1,OFFSET_CURRENT);
- }
- switch(line[0]){
- case '\0':
- case '#':
- break; /* comment, blank lines */
- default:
- if(line[0]==mfp->mfh_mo.r.mor_tag){
- mfp->mfh_fh=Open(&line[1],MODE_OLDFILE);
- if(!mfp->mfh_fh){
- return -1; /* error */
- }
- return 1;
- }
- }
- }
- }
-