/* * DOS_C.C - is a Un*x compatibility module for Desmet C-Ware * C Compiler. This module comes in two parts. All Assembly * Language code is isolated in DOS_A.A - the necessary * structure invokations and defines are found in DOS.H * This if far from being either complete or faithful. The * machinations of making MsDos look like Un*x at the program * level are far from trivial (far from possible). Such is * life in 8088 land. * * --- 24 Sep '86 --- * --- John Birchfield --- */ # include "dos.h" char clock [20]; /* STAT () - a very miniscule implementation of stat. In this * implementation. the only information returned by stat is * the file's date & time of last update, the file's size, * and the attributes of the file. All this information is * returned in struct stat which is defined in DOS.H - If * stat succeeds a 0 is returned, otherwise a 1 * * Usage if (stat (filename, &statbuf)==0) * SUCCESS; * */ int stat (filename, statbuf) char *filename; struct stat *statbuf; { struct direct *dirp, *opendir (); int fp; if ((dirp=opendir (filename))==(struct direct *) NULL) return -1; statbuf->st_mode = dirp->d_mode; statbuf->st_time = dirp->d_time; statbuf->st_date = dirp->d_date; statbuf->st_size = (dirp->d_mode & ST_DIR)?0L:dirp->d_size; free (dirp); return 0; } /* * OPENDIR () - opendir () is not a documented Un*x function * but for implementing some of the Un*x style directory * reads it is handy along with readdir (). The primary * logical difference is that Un*x only performs an OPEN * and doesn't return any immediate information until the * first readdir (). All information is returned in * struct direct { again look in DOS.H }. If successful, * opendir returns a pointer to the structure containing * information necessary to perform subsequent readdir () * calls. Because the dta {Disk Transfer Address } is * set with each call it's possible to have multiple * directories open concurrently. * * Usage: if (dirp=opendir ("mask")) * SUCCESS; * Note: A call of opendir ("*.*") would allow searching the entire * current directory. All file attributes are set so that all * files {Hidden - System - Directory} will be returned. The * Volume Label will NOT be returned by this call. */ struct direct *opendir (mask) char *mask; { struct direct *tmp; if ((tmp = malloc (sizeof (struct direct)))==(struct direct *) NULL) return ((struct direct *) NULL); set_dta (tmp); if (a_open_dir (mask)==0) { free (tmp); return ((struct direct *) NULL); } return tmp; } /* READDIR () - readdir () is the continuation call * corresponding to opendir (). Read above for more * complete information. Mainly you use the pointer to the * direct structure to continue what was started above. * readdir () returns NULL upon failure. Use closedir () * or free () to free up the memory consumed by *dirp. * Usage: while (dirp=readdir (dirp) { * process directory ... * } */ struct direct *readdir (dp) struct direct *dp; { set_dta (dp); if (a_read_dir ()==0) return ((struct direct *) NULL); return dp; } /* * CLOSEDIR () - What is there to say - it could be done * with a macro ... */ void closedir (dp) struct direct *dp; { free (dp); } /* * ISDIR () - isdir () returns TRUE if the file is * a directory. Uses opendir () to get the info. * * Usage: if isdir ("mydir") * chdir ("mydir"); */ int isdir (name) char *name; { struct direct *tmp; int rval = FALSE; if (tmp=opendir (name)) { if (tmp->d_mode & ST_DIR) rval = TRUE; free (tmp); } return rval; } /* * CTIME () - ctime is a sort of semi compatible Un*x * call. If I was gonna do it write, I'd have translated * the date & time completely. As it is the date & time * are returned in the char buffer passed in the following * form. * "yy-mm-dd hh-mm-ss" * Which requires that buf be 19 characters in length. * * Usage: ctime (buf); */ char *ctime (s) char **s; { char t_buf [10]; # ifdef DEBUG db_out("Ctime ...\n"); # endif dates (t_buf); strcpy (*s, t_buf); strcat (*s, " "); times (t_buf); strcat (*s, t_buf); } /* * GETENV () - looks for the environment variable * passed to it. If found it returns a pointer to the * variable's value - if not NULL. * * Usage: if (cp = get_env ("PATH")) * printf ("Found PATH = '%s'\n", cp); */ char *getenv (pat) char *pat; { extern unsigned _PCB; unsigned seg = 0, offst = 0; char *ch; int i, length, copylen; char tmp [256], *str; length = strlen (pat); copylen = (*(pat+length-1)=='=')?length:length+1; *str = '\0'; seg = (_peek (0x2d, _PCB)<<8) + _peek (0x2c, _PCB); while (_peek (offst, seg) != 0) { i = 0; ch = tmp; *ch = '\0'; while (*ch = _peek (offst++, seg)) if (++i < 100) ch++; *ch = '\0'; if (strncmp(pat, tmp, length) == 0) { length = strlen (tmp+copylen) +1; str = malloc (length); strcpy (str, tmp + copylen); return (str); } } return (NULL); } /* * RAWMODE () - rawmode () uses ioctl () { in dos_a.a } * to turn off ^C checking on {stdin stdout & stderr } * When this is done {along with avoiding the putchar () and * getchar () function calls} one stands a minor chance of * not having TABS expanded to SPACES and ETX's replaced with * ^C's. Also some ^Z problems are alleiated. * * Note: For stdio ALL THREE HANDLES MUST BE SET FOR IT TO WORK. * Also note that this call will ONLY work with CHARACTER * DEVICE files. When this mode is set it will remain in effect * until programatically changed or a SYSTEM BOOT occurs. * * Usage: rawmode (stdin); rawmode (stdout); rawmode (stderr); */ int rawmode (fp) int fp; { struct ioctlbuf iob; iob.cmd = IOCTL_GET; iob.handle = fp; ioctl (&iob); iob.cmd = IOCTL_SET; iob.devdata &= 0xFF; iob.devdata |= RAW_MODE; return (ioctl (&iob)); } /* * NORMODE () - same as above... * * Usage: normode (stdin); etc... */ int normode (fp) int fp; { struct ioctlbuf iob; iob.cmd = IOCTL_GET; iob.handle = fp; ioctl (&iob); iob.cmd = IOCTL_SET; iob.devdata &= 0xFF; iob.devdata &= COOKED_MODE; return (ioctl (&iob)); } /* * _EXIT () - _exit () lets you exit but allows you to * turn off RAW_MODE on stdio before saying goodbye to the * world. * * Usage: _exit (5); */ int _exit (n) int n; { normode (0); normode (1); normode (2); exit (n); }