home *** CD-ROM | disk | FTP | other *** search
- /* 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
-