#include /* * \usr\decusc\lib\wild.c * * This module provides wilcard file manipulation through * the following functions: * * FILE *fwild (char *pattern, char *access) * FILE *fnext (FILE *stream) * char *fgetname (FILE *stream) */ extern FILE *fopen (); extern unsigned char *dos_error (); #define DOS_ERROR(n) { fputs (dos_error (n), stderr); exit (); } #define DOS(n) { srv.ax = n << 8;\ status = sysint (0x21, &srv, &rrv);\ if (status & 1) DOS_ERROR (rrv.ax); }; /* These lengths all include the trailing null */ #define MAX_FILENAME_LENGTH 9 #define MAX_FILETYPE_LENGTH 4 #define MAX_PREFIX_LENGTH 64 #define MAX_FILESPEC_LENGTH (MAX_PREFIX_LENGTH + \ MAX_FILENAME_LENGTH + \ MAX_FILETYPE_LENGTH + 1) #define MAX_WILD_CHANNELS 4 static unsigned int status; struct regval {int ax, bx, cx, dx, si, di, ds, es;}; struct segval {int scs, sss, sds, ses;}; static struct regval srv, rrv; static struct segval seg; static struct { unsigned char reserved[21]; unsigned char attr; unsigned time; unsigned date; unsigned size_l; unsigned size_h; unsigned char pname[13]; } find_buf; static struct wild_file { unsigned char pattern[MAX_FILESPEC_LENGTH]; unsigned char name[MAX_FILESPEC_LENGTH]; unsigned char prefix[MAX_PREFIX_LENGTH]; unsigned char access[4]; unsigned int first_flag; FILE *stream; } files[MAX_WILD_CHANNELS] = { {"", "", "", 0, NULL}, /* MAX_WILD_CHANNELS = 4 */ {"", "", "", 0, NULL}, {"", "", "", 0, NULL}, {"", "", "", 0, NULL} }; FILE *fwild (pattern, access) unsigned char *pattern, *access; { unsigned int i, findex; FILE *fd; struct wild_file *wfile; char c, *sp, *terminator; if (strlen (pattern) >= MAX_FILESPEC_LENGTH) error ("fwild called with filespec too long"); if (strlen (access) > 3) error ("fwild called with access string too long"); wfile = NULL; for (findex = 0; findex < MAX_WILD_CHANNELS; findex++) if (files[findex].stream == NULL) { wfile = &files[findex]; break; }; if (wfile == NULL) error ("fwild out of channels"); sp = pattern; terminator = NULL; while (c = *sp++) if (c == ':' || c == '\\' || c == '/') terminator = sp; /* find last prefix terminator if one exists */ if (terminator == NULL) wfile->prefix[0] = 0; else { /* copy drive and directory */ i = 0; for (sp = pattern; sp != terminator; sp++) wfile->prefix[i++] = *sp; wfile->prefix[i] = 0; }; segread (&seg); srv.ds = seg.sds; srv.dx = &find_buf; /* set DMA to GNJFN block */ srv.ax = 0x1A00; sysint (0x21, &srv, &rrv); srv.dx = pattern; /* pathname */ srv.cx = 0; /* attributes */ srv.ax = 0x4E00; /* GTJFN */ status = sysint (0x21, &srv, &rrv); if (status & 1) if (rrv.ax == 18) { wfile->stream = NULL; return (NULL); } else DOS_ERROR (rrv.ax); strcpy (wfile->pattern, pattern); /* copy pattern */ strcpy (wfile->name, wfile->prefix); strcat (wfile->name, find_buf.pname); /* copy first name */ strcpy (wfile->access, access); /* copy access string */ if ((fd = fopen (wfile->name, access)) == NULL) { wfile->stream = NULL; return (NULL); }; wfile->stream = fd; wfile->first_flag = 1; return (fd); } FILE *fnext (stream) FILE *stream; { unsigned int findex; FILE *fd; struct wild_file *wfile; wfile = NULL; for (findex = 0; findex < MAX_WILD_CHANNELS; findex++) if (files[findex].stream == stream) { wfile = &files[findex]; break; }; if (wfile == NULL) error ("fnext called for invalid stream"); if (wfile->first_flag) { wfile->first_flag = 0; return (wfile->stream); }; if (fclose (wfile->stream) != NULL) error ("implicit fclose failed in fnext"); srv.ax = 0x4F00; /* GNJFN */ status = sysint (0x21, &srv, &rrv); if (status & 1) if (rrv.ax != 18) DOS_ERROR (rrv.ax) else { wfile->stream = NULL; return (NULL); }; strcpy (wfile->name, wfile->prefix); strcat (wfile->name, find_buf.pname); if ((fd = fopen (wfile->name, wfile->access)) == NULL) { wfile->stream = NULL; return (NULL); }; wfile->stream = fd; return (fd); } fgetname (stream, name) FILE *stream; unsigned char *name; { unsigned int findex; struct wild_file *wfile; wfile = NULL; for (findex = 0; findex < MAX_WILD_CHANNELS; findex++) if (files[findex].stream == stream) { wfile = &files[findex]; break; }; if (wfile == NULL) error ("fgetname called for invalid stream"); strcpy (name, wfile->name); } fclean (stream) FILE *stream; { unsigned int findex; struct wild_file *wfile; if (stream == NULL) return; wfile = NULL; for (findex = 0; findex < MAX_WILD_CHANNELS; findex++) if (files[findex].stream == stream) { wfile = &files[findex]; break; }; if (wfile == NULL) error ("fclean called for invalid stream"); fclose (stream); wfile->stream = NULL; }