extern DIR *opendirx( const char *dirname, char *pattern) { union REGS inregs, outregs; struct SREGS segregs; char pathname[FILENAME_MAX]; DTA far *dtasave; DTA far *dtaptr; char far *pathptr; /*--------------------------------------------------------------------*/ /* Build pathname to be scanned */ /*--------------------------------------------------------------------*/ strcpy(pathname, dirname); if ((*pattern != '/') || (dirname[ strlen(dirname) - 1] != '/')) strcat(pathname,"/"); strcat(pathname, pattern); /* allocate control block */ thisDirP = malloc(sizeof(DIR)); checkref( thisDirP ); /*--------------------------------------------------------------------*/ /* Set disk transfer address */ /*--------------------------------------------------------------------*/ dtasave = (DTA far *)getdta(); dtaptr = (DTA far *)&(thisDirP->dirdta); setdta((char far *)dtaptr); /*--------------------------------------------------------------------*/ /* look for the first file */ /*--------------------------------------------------------------------*/ inregs.h.ah = 0x4e; pathptr = (char far *)pathname; segregs.ds = FP_SEG(pathptr); inregs.x.dx = FP_OFF(pathptr); inregs.x.cx = 0; /* attribute */ intdosx(&inregs, &outregs, &segregs); /* bad directory name? */ if (outregs.x.cflag && (outregs.x.ax == 2 || outregs.x.ax == 3)) { free(thisDirP); return NULL; } thisDirP->dirfirst = outregs.x.cflag ? outregs.x.ax : 0; setdta((char far *)dtasave); strcpy(thisDirP->dirid, "DIR"); #ifdef UDEBUG printmsg(2,"opendir: Address is %p", thisDirP ); #endif openForBusiness = KWTrue; return thisDirP; } /*opendir*/
/* * Find first/next file * Return: OS error code */ static int findfile(FF_Block95 *ff, int mode, char *name, int attr) { struct REGPACK rp; char far *curDTA; /* first swap the DTA */ curDTA = getdta(); assert(curDTA); setdta((char far*)ff); /* second peform the desired command */ if((rp.r_ax = mode) == FIND_FIRST) { rp.r_ds = FP_SEG(name); rp.r_dx = FP_OFF(name); rp.r_cx = attr; } intr(0x21, &rp); /* third re-set previous DTA */ setdta(curDTA); convDOS(ff); /* forth check for an error */ return (rp.r_flags & 1)? errno = rp.r_ax: 0; }
int findnext(struct ffblk *ff) { void far *dta; IREGS r; int rv; dta = getdta(); setdta((void far*)ff); r.r_ax = 0x4f00; rv = invokeDOS(&r); setdta(dta); return rv; }
int findfirst(const char * const pattern, struct ffblk *ff, int attrib) { void far *dta; IREGS r; int rv; /* DOS uses the DTA to store the internal search data to. The usual implementation of find*() keeps the first 21 bytes of the DTA or simply hope that no DOS will use more than 21 byte and point the DTA directly on the search data buffer. */ dta = getdta(); setdta((void far*)ff); r.r_dx = FP_OFF(pattern); r.r_ds = FP_SEG(pattern); r.r_cx = attrib; r.r_ax = 0x4e00; rv = invokeDOS(&r); setdta(dta); return rv; }
void main(void) { char far *dta; dta = getdta(); printf("Current DTA is %lX\n", dta); if (MK_FP(_psp, 0x80) == dta) printf("DTA is at same location as command line\n"); dta = _fmalloc(128); setdta(dta); printf("New DTA is %lX\n", getdta()); }
struct direct *readdir(DIR *dirp) { int errcode; /*--------------------------------------------------------------------*/ /* Debugging code for failures when running on Novell networks */ /*--------------------------------------------------------------------*/ if ( dirp == NULL ) { flushall(); printmsg(0,"readdir: INTERNAL ERROR: dirp pointer is NULL"); printmsg(0,"readdir: Snuffles debug code: %s %p %p", openForBusiness ? "Open" : "Closed", lastDirP, thisDirP ); flushall(); panic(); } if (!equal(dirp->dirid, "DIR")) { flushall(); printmsg(0,"readdir: INTERNAL ERROR: No search in progress"); printmsg(0,"readdir: Snuffles debug code: %s %p %p %p %s", openForBusiness ? "Open" : "Closed", lastDirP, thisDirP, dirp, dirp->dirid ); flushall(); panic(); } if (dirp->dirfirst == -1) { union REGS inregs, outregs; struct SREGS segregs; DTA far *dtaptr; DTA far *dtasave; /* set DTA address to our buffer each time we're called */ dtasave = (DTA far *)getdta(); dtaptr = (DTA far *)&(dirp->dirdta); setdta((char far *)dtaptr); inregs.h.ah = 0x4f; segregs.ds = FP_SEG(dtaptr); inregs.x.dx = FP_OFF(dtaptr); intdosx(&inregs, &outregs, &segregs); errcode = outregs.x.cflag ? outregs.x.ax : 0; setdta((char far *)dtasave); /* Restore DTA address */ } else { errcode = dirp->dirfirst; dirp->dirfirst = -1; }; /* no more files in directory? */ if (errcode == 18) return NULL; if ( errcode != 0) { errno = errcode; printerr( "readdir" ); panic(); } dirp->dirent.d_ino = -1; /* no inode information */ strcpy(dirp->dirent.d_name, dirp->dirdta.filename); strlwr(dirp->dirent.d_name ); dirp->dirent.d_namlen = (short) strlen(dirp->dirent.d_name); dirp->dirent.d_reclen = (short) (sizeof(struct direct) - (MAXNAMLEN + 1) + ((((dirp->dirent.d_namlen + 1) + 3) / 4) * 4)); dirp->dirent.d_modified = dos2unix( dirp->dirdta.filedate, dirp->dirdta.filetime ); dirp->dirent.d_size = dirp->dirdta.filesize; return &(dirp->dirent); } /*readdir*/