home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource4
/
288_01
/
sd.c
< prev
next >
Wrap
Text File
|
1989-05-25
|
10KB
|
428 lines
/*
HEADER: ;
TITLE: Enhaced Chdir command;
VERSION: 1.2;
DESCRIPTION: "
SD (Set Directory): this is a replacement for the MS-DOS
CD (Chdir: change directory) command.
SD is upwardly compatible with CD, all options of the CD command
have been implemented in SD. The only exception is that
SD <drive:><path>
will switch to the specified drive.
Extended options:
SD ? or SD /? Gives a usage (help) message
SD - Returns to the last directory used (by SD)
This makes use of the MS-DOS environment to
keep the name of the last path in #SD_LAST.
SD [<drive>:]path This sets a new drive and path. If no
drive is given the current drive is used.
SD <name> The file SD.DAT, in a directory specified by PATH
is used to store a list of logical names, and the
drive & path associated with the name.
V1.1 Added ability to invoke a program after
moving to the directory.
BDF Aug. 88
eg:
123 c:\123 123
pas c:\dev\pas
c c:\dev\c
Thus the command line:
SD C
Will move you to drive C, path \DEV\C. While
SD 123
Will move to drive C, path \123 and start the
program 123.
History:
V1.1 Added abilty to start a program after moving to a named
logical directory.
BDF Aug. 1988
V1.2 Stored the name of the last path used in the environment
variable SDLAST. This was the original intention but I
could not find a way to do it, so I used a temp. file to
hold the name of the last path. However, a back issue of
Micro Cornucopia (issue 42) I found in a shop, contained
an articule by Scott Robert Ladd on how to do it (see
GLOBENV.C). Thank you Scott.
BDF Jan. 1989";
FILENAME: SD.C;
WARNINGS: ;
SEE-ALSO: ;
AUTHORS: Brian Farquhar (with thanks to Scott Robert Ladd);
COMPILERS: Microsoft C v5.1 & QuickC;
*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <direct.h>
#include <process.h>
#include <dos.h>
#define TRUE 1 /* Logical true */
#define FALSE 0 /* Logical false */
#define MATCH 0 /* Match on strcmp() */
#define EOL '\n' /* End of line char */
#define MAX_LINE 255 /* Data file Max. line */
#define CDERROR -1 /* Error from chdir() */
#define DATAFILE "SD.DAT" /* Logical names file */
#define LASTPATH "SDLAST" /* Last path */
#define DELIMITERS " \t" /* Used in strtok() */
extern char *getgenv(char *varname);
extern int putgenv(char *varname, char *vartext);
extern int delgenv(char *varname);
/* Local functions */
void help_msg(void);
void prt_cwd(void);
void set_path(char *path);
void save_path(void);
char *get_last(char *path);
void prt_path(char drive);
int logical_name(char *name);
void search_path(char *file, char *path);
void main( int argc,
char **argv)
{
char path[_MAX_PATH]; /* directory path */
char *path_ptr;
if (argc == 1) /* asking for the current path? (SD <cr>) */
{
prt_cwd(); /* print the current path */
printf("\nLast path\t= %s",get_last(path));
printf("\n\nUse the '/?' option for help.\n",argv[0]);
}
/* Asking for the path on another drive? (SD <drive>:) */
else if (strlen(argv[1]) == 2 && argv[1][1] == ':')
{
prt_path(argv[1][0]); /* path on drive x */
printf("\nLast path\t= %s\n",get_last(path));
}
/* did he ask for help? (SD ? or SD /?) */
else if (argv[1][0] == '?'|| (strcmp(argv[1],"/?") == MATCH))
help_msg();
/* go back to the last directory? (SD -) */
else if (strcmp(argv[1],"-") == MATCH)
{
path_ptr = get_last(path);
save_path();
set_path(path_ptr);
}
else /* try to set the given path */
{
save_path(); /* save the current path */
if (!logical_name(argv[1]))
set_path(argv[1]);
}
exit(0);
}
/************************************************************************
Test to see if the "name" is a logical name in the datafile.
If it is, return a value of TRUE after moving to the associated directory
path. Otherwise return FALSE.
V1.1 Added ability to invoke the program named in the data file.
************************************************************************/
int logical_name( char *name)
{
char file[_MAX_PATH]; /* full file spec of DATAFILE */
char buff[MAX_LINE]; /* line from the DATAFILE */
char *token;
FILE *fp; /* file pointer for DATAFILE */
char *prog; /* program to chain to */
int c;
int i;
search_path(DATAFILE,file); /* look for the file on PATH */
if (file[0] == NULL) /* found it? */
{
printf("Error: can not find the data file '%s'.",DATAFILE);
return(FALSE);
}
if ((fp = fopen(file,"r")) == NULL) /* open the data file */
{
printf("\nError: unable to open the file '%s'.\n",file);
return(FALSE);
}
i = 0;
while ((c = fgetc(fp)) != EOF) /* read the data file */
{
if (i == MAX_LINE -1) /* line too long? */
{
fprintf(stderr,"Maximum of %d characters per line"
" in '%s'.",MAX_LINE,DATAFILE);
c = EOL;
}
if (c == EOL)
{
/* Now we have a line from the data file,
use the strtok() function to get the
logical name on the line, and if it is
the required name move to the directory
given by the second token.
V1.1 If a third token is on the line try
and invoke it as a program.
*/
buff[i] = '\0';
i = 0;
token = strtok(buff,DELIMITERS);
if (strcmp(token,name) == MATCH)
{
/* get the next token */
token = strtok(NULL,DELIMITERS);
set_path(token);
prog = strtok(NULL,DELIMITERS);
if (prog != NULL)
system(prog);
return(TRUE);
}
}
else
{
buff[i] = (char) c;
i++;
}
}
return(FALSE);
}
/************************************************************************
print a help (usage) message.
************************************************************************/
void help_msg(void)
{
printf( "\nSD: Set Directory, an enhanced Chdir command\n"
"\nSD version 1.1:"
"\tAdded ability to call a program\n"
"\t\t\twhen moving to a named directory\n"
"\nUsage:\tSD <CR>\t"
"\tWith no parameters prints the current path\n"
"\tSD <drive>:\tPrints the current path on the given drive\n"
"\tSD /? \t\tPrints this help message\n"
"\tSD - \t\tReturns to the last directory used (by SD)\n"
"\tSD [d:]path\tSet the path to the given drive and path\n"
"\tSD <name> \tMove to the directory in the file SD.DAT\n");
}
/************************************************************************
Print the C(urrent) W(orking) D(irectory)
************************************************************************/
void prt_cwd(void)
{
char path[_MAX_PATH];
if (getcwd(path,_MAX_PATH) == NULL)
perror("Get current working directory error");
else
printf("\nPath on %c:\t= %s",path[0],path);
}
/************************************************************************
set the given drive (optional) & path
************************************************************************/
void set_path(char *path)
{
unsigned curr_drive;
unsigned num_drives;
unsigned tmp,i;
if (isalpha(path[0]) && path[1] == ':') /* drive given? */
{
i = toupper(path[0]) - 'A' + 1; /* A=0, B=1... */
tmp = i;
_dos_getdrive(&curr_drive);
_dos_setdrive(tmp,&num_drives);
/* validate the drive */
_dos_getdrive(&tmp);
if (tmp != i)
{
if (tmp != curr_drive)
_dos_setdrive(curr_drive,&num_drives);
exit(1);
}
}
if (chdir(path) == CDERROR)
{
printf("Error changing to '%s'.\n",path);
exit(-1);
}
}
/************************************************************************
Save the current path.
************************************************************************/
void save_path(void)
{
char path[_MAX_P