1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
/*
** PushDir() and PopDir()
**
** Original Copyright 1988-1991 by Bob Stout as part of
** the MicroFirm Function Library (MFL)
**
** This subset version is an expanded version of the one
** originally published by the author in Tech Specialist
** magazine and is hereby donated to the public domain.
*/
#include <dos.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef __TURBOC__
#include <dir.h>
#else
#include <direct.h>
#endif
#define DIR_STACK_SIZE 8
#define MAX_FLEN 67
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
/*
** NOTE: Uses the author's chdrv(), also in SNIPPETS!
*/
int chdrv(int);
static int PushDir_stack_ptr;
static char PushDir_stack[DIR_STACK_SIZE][MAX_FLEN];
/*
** PushDir()
**
** Like chdir(), except a drive may be specified and the old directory
** is saved.
**
** Arguments: 1 - newdir, the buffer containing the new directory name
**
** Returns: -1 - stack overflow
** 0 - error
** 1 - success, still on same drive
** 2 - success, changed drive
**
** Side effects: Converts name in newdir to upper case and prepends
** a drive letter.
**
** CAUTION: Since a drive will be prepended to newdir, it's buffer
** should be at at least MAX_FLEN long.
*/
int PushDir(char *newdir)
{
char pname[MAX_FLEN];
char drive[3];
char *target = &pname[2];
int new_drv = 0, ercode = 0;
static int init = 0;
if (!init)
PushDir_stack_ptr = init = -1;
if (DIR_STACK_SIZE <= ++PushDir_stack_ptr)
{
ercode = -1;
goto ErrEx;
}
getcwd(PushDir_stack[PushDir_stack_ptr], MAX_FLEN);
strupr(PushDir_stack[PushDir_stack_ptr]);
strncpy(drive, PushDir_stack[PushDir_stack_ptr], 2);
drive[2] = '\0';
if (':' == newdir[1])
{ /* If a drive is specified */
strupr(newdir);
strcpy(pname, newdir);
if (strchr(target, ':')) /* if filename is illegal */
goto ErrEx;
if (*drive != *newdir)
{
if (ERROR == chdrv(newdir[0] - 'A'))
{ /* If the drive is invalid */
goto ErrEx;
}
else new_drv = 1;
}
}
else
{ /* If a drive isn't specified */
if (!strchr(strupr(newdir), ':'))
{ /* If legal filename */
strcpy(pname, drive);
strcat(pname, newdir);
strcpy(newdir, pname);
}
else
{ /* If filename is illegal */
goto ErrEx;
}
}
if (*target)
{
if (chdir(target))
{
if (1 == new_drv) /* We already changed drives */
chdrv(*drive - 'A'); /* Go home before exit */
goto ErrEx;
}
}
return (new_drv + 1);
ErrEx:
--PushDir_stack_ptr;
return (ercode);
}
/*
** PopDir()
**
** Like chdir(), except goes to the drive/directory specified on the
** top of the PushDir stack.
**
** Arguments: none
**
** Returns: -1 - stack empty
** 0 - error - stack pointer unchanged
** 1 - success, still on same drive
** 2 - success, changed drive
**
** Side effects: none
**
** CAUTION: chdir() or chdrv() should not be called between PushDir-
** PopDir calls.
*/
int PopDir(void)
{
char I_am_here[MAX_FLEN], target_drv, *target;
int new_drv = 0;
if (0 > PushDir_stack_ptr)
return -1;
getcwd(I_am_here, MAX_FLEN);
target = &PushDir_stack[PushDir_stack_ptr][2];
target_drv = PushDir_stack[PushDir_stack_ptr][0];
if (I_am_here[0] != target_drv)
{
if (ERROR == chdrv(target_drv - 'A'))
return 0;
new_drv = 1;
}
if (!chdir(target))
{
--PushDir_stack_ptr;
return (1 + new_drv);
}
else return 0;
}
/*
** isdir()
**
** Checks to see if a drive and/or path are a valid directory.
**
** Arguments: 1 - dir, the buffer containing the new directory name
**
** Returns: ERROR - push/popdir stack overflow
** FALSE - not a valid directory
** TRUE - valid directory
**
** Side effects: Converts name in dir to upper case and prepends a
** drive letter.
**
** CAUTION: Since a drive will be prepended to newdir, it's buffer
** should be at at least MAX_FLEN long.
*/
int isdir(char *dir)
{
int ercode;
if (-1 == (ercode = PushDir(dir)))
return ercode;
if (ercode)
PopDir();
return BOOL(ercode);
}
|