home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
program
/
lynxlib
/
pathname.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-23
|
10KB
|
358 lines
/* This source file is part of the LynxLib miscellaneous library by
Robert Fischer, and is Copyright 1990 by Robert Fischer. It costs no
money, and you may not make money off of it, but you may redistribute
it. It comes with ABSOLUTELY NO WARRANTY. See the file LYNXLIB.DOC
for more details.
To contact the author:
Robert Fischer \\80 Killdeer Rd \\Hamden, CT 06517 USA
(203) 288-9599 fischer-robert@cs.yale.edu */
#include <e_osbind.h>
#include <ctype.h>
#include <nstring.h>
add_slash(name)
char *name;
{
register int i;
i = strlen(name) - 1;
if (name[i] != '\\') {
name[i+1] = '\\';
name[i+2] = '\0';
}
}
/* ---------------------------------------------------------------- */
trim_slash(name)
char *name;
{
register int i;
i = strlen(name) - 1;
if (name[i] == '\\')
name[i] = '\0';
}
/* ---------------------------------------------------------------- */
ppath(path, drvltr, dir, leaf)
/* Parses a path name and returns its component parts */
char *path; /* Input path name */
char *drvltr; /* Output: drive letter of path */
/* 0 = default, 'A' = drive A, ... */
char *dir; /* Directory part of name: */
/* '.\' - default directory */
/* '\' - root directory */
/* '.\xxx\' - subfolder of default dir */
/* '\xxx\' - subfolder of root */
char *leaf; /* Leaf name or wildcard pattern */
{
char s[80];
int i;
*drvltr = _toupper(path[0]);
/* Get drive specifier */
if (strlen(path) >= 2 && path[1] == ':' &&
'A' <= *drvltr && *drvltr <= 'P') {
strcpy(s, path + 2);
} else {
*drvltr = 0;
strcpy(s, path);
}
/* Split directory name into two parts */
i = strlen(s);
while (i > -1 && s[i] != '\\') i--;
if (i == -1) { /* No backslashes in pathname */
strcpy(dir, ".\\");
strcpy(leaf, s);
} else { /* Name contains a '\\' */
if (s[0] != '\\') {
dir[0] = '.'; dir[1] = '\\';
s[i] = NIL;
strcpy(dir + 2, s);
} else {
s[i] = NIL;
strcpy(dir, s);
}
strcpy(leaf, s + i+1);
}
/* Add a trailing slash */
add_slash(dir);
}
/* ---------------------------------------------------------------- */
resolve_pname(ipath, dflt)
/* Converts path to fully specified form, supplying current default */
/* drive and directory. */
/* Eliminates all occurrences of '.' and '..' */
/* BUGS: The default directory given in dflt is used as the default
for ALL drives. For example, if ipath=c:x and dflt=e:\r\,
then ipath is resolved to c:\r\x */
char *ipath; /* Path name to be resolved. Output returned here, too */
char *dflt; /* Default pathname to use for ambiguous things. */
/* If defalt is '', use GEMDOS's defaults */
{
char drvltr; /* Drive letter */
fle_name dir; /* Directory path */
leaf_name leaf; /* Leaf part of ipath */
int i,j;
fle_name ddir; /* Path of default */
leaf_name dleaf;
char ddrv; /* Drive letter of default */
fle_name s;
ppath(ipath, &drvltr, dir, leaf);
/* Get the defaults correct */
if (dflt[0] == NIL) {
ddrv = 'A' + Dgetdrv();
if (drvltr == 0) Dgetpath(ddir, 0);
else Dgetpath(ddir, drvltr - 'A' + 1);
add_slash(ddir);
} else {
resolve_pname(dflt, "");
ppath(dflt, &ddrv, ddir, dleaf);
strcat(ddir, dleaf);
add_slash(ddir);
}
/* Resolve drive */
if (drvltr == 0) drvltr = ddrv;
/* Resolve path */
if (dir[0] == '.') {
strcpy(s, dir); /* dir := concat(ddir, dir); */
pstrcpy(pstrcpy(dir, ddir), s);
}
/* Combine names */
ipath[0] = drvltr;
ipath[1] = ':';
pstrcpy(pstrcpy(ipath + 2, dir), leaf);
/* Remove '.' and '..' from ipath */
for (i = j = 0; ipath[i] != NIL; ) {
if (ipath[i] == '\\' && ipath[i+1] == '.' && ipath[i+2] == '\\') {
i += 2;
} else ipath[j++] = ipath[i++];
}
ipath[j] = NIL;
for (i = 0; i < 3; i++) if (ipath[i] == NIL) goto skip; /* No possibility for '..' in name */
for (j = 3; ipath[i] != NIL; ) {
if (ipath[i] == '\\' && ipath[i+1] == '.' &&
ipath[i+2] == '.' && ipath[i+3] == '\\') {
i += 3;
if (j > 2) for (j--; ipath[j] != '\\'; j--) ; /* Scan to last '\' */
} else ipath[j++] = ipath[i++];
}
ipath[j] = NIL;
skip:
/* Force result to upper case */
pstrupper(ipath);
}
/* ---------------------------------------------------------------- */
resolve_dname(idir, dflt)
/* Resolves a directory name */
char *idir;
char *dflt;
{
char *c;
if (idir[0] != NIL) add_slash(idir);
strcat(idir, "x"); /* Make a dummy file name */
resolve_pname(idir, dflt);
c = pstrlen(idir);
*(c-1) = NIL; /* Remove dummy file name */
}
/* ---------------------------------------------------------------- */
get_curdir(pname) /* gets the current directory */
char *pname;
{
Dgetpath(&pname[2], 0);
pname[0] = Dgetdrv() + 'A';
pname[1] = ':';
add_slash(pname);
}
/* ---------------------------------------------------------------- */
trim_leaf(pname) /* Removes the leaf from a name */
/* E:\C turnes to E:\, E:\C\ turns to E:\C\ */
register char *pname;
{
register int i;
for (i = strlen(pname); pname[i] != '\\' && i > 0; i--) ;
if (i != 0) pname[i+1] = '\0';
}
/* ---------------------------------------------------------------- */
BOOLEAN g_file_attrib(name, modebits, td, size)
/* Gets the file attributes according to directory */
char *name; /* name of file */
WORD *modebits; /* File's modebits */
GEMDOS_TD_REC *td; /* Files date and time */
long *size; /* Filesize */
{
TRANS_BUF trans, *old_trans;
int err;
old_trans = Fgetdta(); /* Save old DTA, set new one */
Fsetdta(&trans);
err = Fsfirst(name, READ_ONLY | CLOSED);
Fsetdta(old_trans);
if (err != E_OK) return FALSE;
/* Take out the information */
td->td.date = trans.date;
td->td.time = trans.time;
*modebits = trans.attrib & 0xFF;
*size = trans.size;
return TRUE;
}
/* ---------------------------------------------------------------- */
BOOLEAN s_file_attrib(name, modebits, td)
char *name;
WORD modebits;
GEMDOS_TD_REC td;
{
GFILE f;
/* Set the date and time, opening the file */
f = Fopen(name, G_RW);
if (f <= 0) return FALSE;
Fdatime(&td, f, SET_FDTM);
if (Fclose(f) != E_OK) return FALSE;
/* Set the attributes, only requiring the name */
Fattrib(name, SET_ATTRIB, modebits);
return TRUE;
}
/* ---------------------------------------------------------------- */
BOOLEAN cd(d, odrive, opath)
/* Changes current directory to dir. Returns the previous default
drive in odrive and the previous default path on the drive specified
in d in opath. Returns TRUE on success */
char *d;
int *odrive;
char *opath;
{
int i;
*odrive = Dgetdrv();
Dgetpath(opath, 0);
/* Look for drive letter */
if (d[0] != NIL && d[1] == ':') { /* We've found a drive letter! */
i = _toupper(d[0]) - 'A';
/* If the drive set doesn't really exist */
if (i > 15 || (Drvmap() & (1 << i)) == 0) return FALSE;
Dsetdrv(i);
Dgetpath(opath, 0);
d += 2;
}
/* Now, test the non-drive part */
return (Dsetpath(d) == E_OK);
}
/* ---------------------------------------------------------------- */
BOOLEAN existd(d) /* Sees if a directory exists */
char *d;
{
fle_name defpath; /* Saved default path */
int defdrive; /* Saved default drive */
BOOLEAN ret;
ret = cd(d, &defdrive, defpath);
/* Restore defaults */
if (defpath[0] == NIL) add_slash(defpath);
Dsetpath(defpath);
Dsetdrv(defdrive);
return ret;
}
/* ---------------------------------------------------------------- */
BOOLEAN create_dir(d) /* Creates a directory if it doesn't already exist */
/* d may be a file-name. Then the dir. of that name will be created */
char *d;
{
int i;
for (i = 0; d[i] != NIL; i++) {
if (d[i] == '\\') {
d[i] = NIL;
if (existf(d)) return FALSE;
if (!existd(d)) Dcreate(d);
d[i] = '\\';
}
}
if (existf(d)) return FALSE;
if (!existd(d)) Dcreate(d);
return TRUE;
}
/*---------------------------------------------------------------- */
pleaf(leaf, root, ext)
/* Parses a leaf into a root and extender */
char *leaf, *root, *ext;
{
char *c;
c = rindex(leaf, '.');
if (c == NULL) {
ext[0] = NIL;
strcpy(root, leaf);
} else {
*c = NIL;
strcpy(root, leaf);
strcpy(ext, c+1);
*c = '.';
}
}
/*---------------------------------------------------------------- */
remove_leaf(s, leaf)
/* Removes the leafname off of s, and puts it into leaf */
/* If there's no backslash, it's assumed to be an entire leafname */
char *s;
char *leaf;
{
char *c;
c = rindex(s, '\\');
if (c == NULL) {
strcpy(leaf, s);
strcpy(s, ".\\"); /* The entire thing is a leaf */
} else {
strcpy(leaf, c+1);
*(c+1) = NIL;
}
}
/*---------------------------------------------------------------- */
force_ext(s, ext)
/* Forces the extender on a name to be ext (ext contains no dot) */
/* Appends the extender ext if there is none. */
char *s;
char *ext;
{
char *c, *end;
c = end = pstrlen(s);
while (TRUE) {
if (*c == '\\' || c == s) { /* No extender */
*(end++) = '.';
strcpy(end, ext);
break;
}
if (*c == '.') { /* Extender to replace */
strcpy(c+1, ext);
break;
}
c--;
}
}
/* --------------------------------------------------------------- */
/*---------------------------------------------------------------- */
#if 0
main()
{
char s[80], d[80];
while (TRUE) {
printf("Enter your pathname: ");
gets(s);
printf("Enter your default: ");
gets(d);
resolve_pname(s, d);
printf("Resolved name is: %s\n", s);
}
}
#endif