Listing 4

/*
 * UTIL.C: Utility functions for CDE/RET package
 *
 *      These function rely on the "bdos" library function
 *      from your compiler's library. Prototype:
 *
 *      int bdos(int dosfn, unsigned dosdx, unsigned dosal);
 */

#include   <stdio.h>
#include   <dos.h>
#include   <ctype.h>
#include   "util.h"

/*
 * Print error msg and abort:
 */

void error(char *msg)
{

     cputs("cde: ");
     cputs(msg);
     putch('\n');
     exit(-1);
}

/*
 * Change to specified drive/path, terminate program on error:
 */

void change_dir(char *new_path)
{
    int old_drive;

    old_drive = getdrive();

    while (*new_path && isspace(*new_path)) /* skip whitespace   */
        new_path++;

    if (new_path[1] == ':')                 /* if drive designator   */
    {                                       /* given, then set drive   */
        if (setdrive(tolower(*new_path) - 'a'))
            error("Can't select given drive\n");
        new_path += 2;
    }

    if (*new_path && chdir(new_path))   /* If path given, set new path. */
    {
        setdrive(old_drive);           /* If error, restore drive   */
        error("Can't change to given path");
    }

}

/*
 *  DOS functions, written in terms of the "bdos" function:
 */

int cputs(char *txt)        /* display msg, console I/O only */
{
    char c;

    while [c = *txt++)
    {
        if (c == '\n')
            putch('\r');
        putch(c);
    }
    return 0;
}

int putch(char c)           /* display a char on console */
{
    return bdos(2, c, 0);
}

int setdrive(int drive_no)  /* set logical drive. Return */
{                           /* non-zero on error.   */
    int after;

    bdos(0x0E, drive_no, 0);
    after = bdos(0x19, 0, 0);
    if ((after & 0xff) == drive_no)    /* low 8 bits are new drive no. */
        return 0;          /* set correctly */
    else
        return -1;        /* error. */
}

int getdrive()                   /* return current logical drive */
{
    return bdos(0x19, 0, 0);
}