/***************************************************************************/
/***************************************************************************/
/* */
/* (c) 1995-1999. The Regents of the University of California. All */
/* rights reserved. */
/* */
/* This work was produced at the University of California, Lawrence */
/* Livermore National Laboratory (UC LLNL) under contract no. */
/* W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy */
/* (DOE) and The Regents of the University of California (University) */
/* for the operation of UC LLNL. Copyright is reserved to the */
/* University for purposes of controlled dissemination, */
/* commercialization through formal licensing, or other disposition */
/* under terms of Contract 48; DOE policies, regulations and orders; */
/* and U.S. statutes. The rights of the Federal Government are */
/* reserved under Contract 48 subject to the restrictions agreed upon */
/* by the DOE and University. */
/* */
/* */
/* DISCLAIMER */
/* */
/* This software was prepared as an account of work sponsored by an */
/* agency of the United States Government. Neither the United States */
/* Government nor the University of California nor any of their */
/* employees, makes any warranty, express or implied, or assumes any */
/* liability or responsibility for the accuracy, completeness, or */
/* usefulness of any information, apparatus, product, or process */
/* disclosed, or represents that its specific commercial products, */
/* process, or service by trade name, trademark, manufacturer, or */
/* otherwise, does not necessarily constitute or imply its */
/* endorsement, recommendation, or favoring by the United States */
/* Government or the University of California. The views and opinions */
/* of the authors expressed herein do not necessarily state or reflect */
/* those of the United States Government or the University of */
/* California, and shall not be used for advertising or product */
/* endorsement purposes. */
/* */
/* Permission to use, copy, modify and distribute this software and its */
/* documentation for any non-commercial purpose, without fee, is */
/* hereby granted, provided that the above copyright notice and this */
/* permission notice appear in all copies of the software and */
/* supporting documentation, and that all UC LLNL identification in */
/* the user interface remain unchanged. The title to copyright LLNL */
/* XDIR shall at all times remain with The Regents of the University */
/* of California and users agree to preserve same. Users seeking the */
/* right to make derivative works with LLNL XDIR for commercial */
/* purposes may obtain a license from the Lawrence Livermore National */
/* Laboratory's Technology Transfer Office, P.O. Box 808, L-795, */
/* Livermore, CA 94550. */
/* */
/***************************************************************************/
/***************************************************************************/
#include <ctype.h>
#include <X11/Intrinsic.h>
#include "xdir.h"
#include "str.h"
/*
* unix_path_to_links - Parses the UNIX path name into its constituent links.
* unix_path_to_links returns a pointer to an array of
* pointers to the link names. The last entry in the
* array is a NULL pointer. Call release_path_links()
* to free memory returned by unix_path_to_links().
*/
char **
unix_path_to_links(path)
char *path;
{
char *p;
char *q;
char *pathcopy;
char **links;
int nlinks;
/* Check for null path name */
if (path[0] == '\0')
fatal_error("Trouble in unix_path_to_links()");
/* Need to copy path because routine strtok() is destructive */
pathcopy = XtNewString(path);
/* Allocate space for array of link names */
links = (char **)XtMalloc(sizeof(char *)*(MAXLINKS+1));
/* Special case first link of full path name */
if (pathcopy[0] == '/') {
if (pathcopy[1] == '/') { /* Handle Apollo */
links[0] = XtNewString("//");
p = &pathcopy[2];
} else {
links[0] = XtNewString("/");
p = &pathcopy[1];
}
nlinks = 1;
} else {
p = pathcopy;
nlinks = 0;
}
/* Loop through links of path name */
while ((q=strtok(p, "/")) != NULL) {
if (nlinks == MAXLINKS)
fatal_error("Trouble in unix_path_to_links()");
links[nlinks++] = XtNewString(q);
p = NULL;
}
/* Success */
links[nlinks] = NULL;
XtFree(pathcopy);
return links;
}
/*
* dw_path_to_links - Parses the DOS/Windows path name into its constituent
* links. "delim" is the character that delimits
* links in the path. Use '\' for DOS and '/' for
* Windows. dw_path_to_links returns a pointer to an
* array of pointers to the link names. The last entry
* in the array is a NULL pointer. Call
* release_path_links() to free memory returned by
* dw_path_to_links().
*/
char **
dw_path_to_links(path, delim)
char *path;
int delim;
{
char *p;
char *q;
char *pathcopy;
char **links;
char temp[2];
int nlinks;
int len;
/* Check for null path name */
if (path[0] == '\0')
fatal_error("Trouble in dw_path_to_links()");
/* Need to copy path because routine strtok() is destructive */
pathcopy = XtNewString(path);
/* Allocate space for array of link names */
links = (char **)XtMalloc(sizeof(char *)*(MAXLINKS+1));
/* Special case first link of full path name */
len = strlen(pathcopy);
p = pathcopy;
if ((len > 1) && (pathcopy[1] == ':')) {
links[0] = XtMalloc(4);
links[0][0] = *p++;
links[0][1] = *p++;
if ((len > 2) && (pathcopy[2] == delim)) {
links[0][2] = *p++;
links[0][3] = '\0';
} else
links[0][2] = '\0';
nlinks = 1;
} else
nlinks = 0;
/* Loop through links of path name */
temp[0] = delim;
temp[1] = '\0';
while ((q=strtok(p, temp)) != NULL) {
if (nlinks == MAXLINKS)
fatal_error("Trouble in dw_path_to_links()");
links[nlinks++] = XtNewString(q);
p = NULL;
}
/* Success */
links[nlinks] = NULL;
XtFree(pathcopy);
return links;
}
/*
* dos_path_to_links - Parses the DOS path name into its constituent links.
* dos_path_to_links returns a pointer to an array of
* pointers to the link names. The last entry in the
* array is a NULL pointer. Call release_path_links()
* to free memory returned by dos_path_to_links().
*/
char **
dos_path_to_links(path)
char *path;
{
return dw_path_to_links(path, '\\');
}
/*
* windows_path_to_links - Parses the Windows path name into its
* constituent links. windows_path_to_links
* returns a pointer to an array of pointers
* to the link names. The last entry in the
* array is a NULL pointer. Call
* release_path_links() to free memory returned
* by windows_path_to_links().
*/
char **
windows_path_to_links(path)
char *path;
{
return dw_path_to_links(path, '/');
}
/*
* vms_path_to_links - Parses the path name into its constituent links.
* vms_path_to_links returns a pointer to an array of
* pointers to the link names. The last entry in the
* array is a NULL pointer. Call release_path_links()
* to free memory returned by vms_path_to_links().
* Some examples:
*
* a::b:[c.d]e --> a::, b:, c.dir, d.dir, e
* b:[c.d]e --> b:, c.dir, d.dir, e
* [.c.d]e --> c.dir, d.dir, e
* [.c] --> c.dir
* e --> e
* c.dir --> c.dir
*/
char **
vms_path_to_links(path)
char *path;
{
char *pathcopy;
char **links;
int nlinks = 0;
char *q;
char *p;
int len;
char *filename;
int i;
/* Check for null path name */
if (path[0] == '\0')
fatal_error("Trouble in vms_path_to_links()");
/* Need to copy path because routine strtok() is destructive */
pathcopy = XtNewString(path);
/* Allocate space for array of link names */
links = (char **)XtMalloc(sizeof(char *)*(MAXLINKS+1));
/* Network node */
p = pathcopy;
if ((q = strstr(p, "::"))) {
len = q-p+2;
links[nlinks] = XtMalloc(len+1);
for (i=0; i<len; i++)
links[nlinks][i] = p[i];
links[nlinks][len] = '\0';
nlinks++;
p = q+2;
}
/* Device */
if ((q = strchr(p, ':'))) {
len = q-p+1;
links[nlinks] = XtMalloc(len+1);
for (i=0; i<len; i++)
links[nlinks][i] = p[i];
links[nlinks][len] = '\0';
nlinks++;
p = q+1;
}
/* Directory and file */
if (*p == '[') {
p++;
if (*p == '.') {
if (nlinks != 0)
fatal_error("Trouble in vms_path_to_links()");
p++;
} else if (nlinks == 0)
fatal_error("Trouble in vms_path_to_links()");
filename = strchr(pathcopy, ']');
if (filename == NULL || filename == p)
fatal_error("Trouble in vms_path_to_links()");
*filename++ = '\0';
while ((q=strtok(p, ".")) != NULL) {
if (nlinks == MAXLINKS)
fatal_error("Trouble in vms_path_to_links()");
links[nlinks] = XtMalloc(strlen(q)+5);
strcpy(links[nlinks], q);
strcat(links[nlinks], ".dir");
nlinks++;
p = NULL;
}
if (strlen(filename)) {
if (nlinks == MAXLINKS)
fatal_error("Trouble in vms_path_to_links()");
links[nlinks++] = XtNewString(filename);
}
} else {
links[nlinks++] = XtNewString(p);
}
/* Success */
links[nlinks] = NULL;
XtFree(pathcopy);
return links;
}
/*
* path_to_links - Parses the path name into its constituent links.
* path_to_links returns a pointer to an array of
* pointers to the link names. The last entry in the
* array is a NULL pointer. Call release_path_links()
* to free memory returned by path_to_links(). "system"
* identifies the system (e.g., SYS_UNIX).
*/
char **
path_to_links(system, path)
int system;
char *path;
{
switch (system) {
case SYS_VMS:
return vms_path_to_links(path);
case SYS_DOS:
return dos_path_to_links(path);
case SYS_WINDOWS:
return windows_path_to_links(path);
default:
return unix_path_to_links(path);
}
}
/*
* release_path_links - Release the memory returned by path_to_links().
*/
void
release_path_links(links)
char **links;
{
char **ptr = links;
/* Check for null pointer */
if (links == NULL)
return;
/* Release memory */
while (*ptr)
XtFree(*ptr++);
XtFree ((char *)links);
links = NULL;
}
/*
* reverse_link_order - Reverse the order of the directory links in the
* array returned by path_to_links().
*/
void
reverse_link_order(links)
char **links;
{
int nlinks = 0;
int nlim;
int i;
char **ptr = links;
char *temp;
while (*ptr++)
nlinks++;
nlim = nlinks/2;
for (i=0; i<nlim; i++) {
temp = links[i];
links[i] = links[nlinks-1-i];
links[nlinks-1-i] = temp;
}
}
/*
* unix_links_to_path - Construct a Unix path from its constituent links.
* "links" is a pointer to an array of pointers to the
* link names. "nlinks" is the number of entries in
* "links". Call XtFree() to free the memory returned
* by unix_links_to_path().
*/
char *
unix_links_to_path(links, nlinks)
char **links;
int nlinks;
{
int len = 0;
int i;
char *path;
/* Determine length of path name */
for (i=0; i<nlinks; i++)
len += strlen(links[i])+1;
/* Build path name for new working directory */
path = XtMalloc(len+1);
strcpy(path, "");
for (i=0; i<nlinks; i++) {
strcat(path, links[i]);
if (path[strlen(path)-1] != '/' && i < nlinks-1)
strcat(path, "/");
};
return path;
}
/*
* nt_links_to_path - Construct NT path from its constituent links.
* "links" is a pointer to an array of pointers to the
* link names. "nlinks" is the number of entries in
* "links". Call XtFree() to free the memory returned
* by nt_links_to_path().
*/
char *
nt_links_to_path(links, nlinks)
char **links;
int nlinks;
{
int len = 0;
int i;
char *path;
/* Determine length of path name */
for (i=0; i<nlinks; i++)
len += strlen(links[i])+1;
/* Build path name for new working directory */
path = XtMalloc(len+1);
strcpy(path, "");
for (i=0; i<nlinks; i++) {
strcat(path, links[i]);
if (path[strlen(path)-1] != '/' && i < nlinks-1)
strcat(path, "/");
};
/* Make sure that "x:" looks like "x:/" */
if (nlinks == 1 && strlen(path) == 2 && path[1] == ':')
strcat(path, "/");
return path;
}
/*
* dw_links_to_path - Construct a DOS/Windows path from its constituent
* links. "delim" is the character that delimits links
* in the path. Use '\' for DOS and '/' for Windows.
* "links" is a pointer to an array of pointers to the
* link names. "nlinks" is the number of entries in
* "links". Call XtFree() to free the memory returned
* by dw_links_to_path().
*/
char *
dw_links_to_path(links, nlinks, delim)
char **links;
int nlinks;
int delim;
{
int len = 0;
int i;
char *path;
char temp[2];
/* Determine length of path name */
for (i=0; i<nlinks; i++)
len += strlen(links[i])+1;
/* Build path name for new working directory */
temp[0] = delim;
temp[1] = '\0';
path = XtMalloc(len+1);
strcpy(path, "");
for (i=0; i<nlinks; i++) {
strcat(path, links[i]);
if (path[strlen(path)-1] != delim && i < nlinks-1)
strcat(path, temp);
};
return path;
}
/*
* dos_links_to_path - Construct a DOS path from its constituent links.
* "links" is a pointer to an array of pointers to the
* link names. "nlinks" is the number of entries in
* "links". Call XtFree() to free the memory returned
* by dos_links_to_path().
*/
char *
dos_links_to_path(links, nlinks)
char **links;
int nlinks;
{
return dw_links_to_path(links, nlinks, '\\');
}
/*
* windows_links_to_path - Construct a Windows path from its constituent
* links. "links" is a pointer to an array of
* pointers to the link names. "nlinks" is the
* number of entries in "links". Call XtFree()
* to free the memory returned by
* windows_links_to_path().
*/
char *
windows_links_to_path(links, nlinks)
char **links;
int nlinks;
{
return dw_links_to_path(links, nlinks, '/');
}
/*
* vms_links_to_path - Construct a VMS path from its constituent links.
* "links" is a pointer to an array of pointers to the
* link names. "nlinks" is the number of entries in
* "links". Call XtFree() to free the memory returned
* by vms_links_to_path().
*/
char *
vms_links_to_path(links, nlinks)
char **links;
int nlinks;
{
int len;
int i;
int state = 0;
char *path;
char *q;
char *temp;
/* Conservatively allocate enough memory to hold path */
len = 2;
for (i=0; i<nlinks; i++)
len += strlen(links[i])+1;
path = XtMalloc(len+1);
/* Construct VMS path */
path[0] = '\0';
for (i=0; i<nlinks; i++) {
len = strlen(links[i]);
if (len == 0)
fatal_error("Problem in vms_links_to_path()");
switch (state) {
case 0:
if ((len > 2) && !strcmp(&links[i][len-2], "::")) {
strcat(path, links[i]);
state = 1;
} else if ((len > 1) && (links[i][len-1] == ':')) {
strcat(path, links[i]);
state = 2;
} else if (strstr(links[i], ".dir")) {
strcat(path, "[.");
temp = XtNewString(links[i]);
q = strstr(temp, ".dir");
*q = '\0';
strcat(path, temp);
XtFree(temp);
state = 3;
} else {
strcat(path, links[i]);
state = 4;
}
break;
case 1:
if ((len > 1) && (links[i][len-1] == ':')) {
strcat(path, links[i]);
state = 2;
} else if (strstr(links[i], ".dir")) {
strcat(path, "[.");
temp = XtNewString(links[i]);
q = strstr(temp, ".dir");
*q = '\0';
strcat(path, temp);
XtFree(temp);
state = 3;
} else {
strcat(path, links[i]);
state = 4;
}
break;
case 2:
if (strstr(links[i], ".dir")) {
strcat(path, "[");
temp = XtNewString(links[i]);
q = strstr(temp, ".dir");
*q = '\0';
strcat(path, temp);
XtFree(temp);
state = 3;
} else {
strcat(path, links[i]);
state = 4;
}
break;
case 3:
if (strstr(links[i], ".dir")) {
strcat(path, ".");
temp = XtNewString(links[i]);
q = strstr(temp, ".dir");
*q = '\0';
strcat(path, temp);
XtFree(temp);
} else {
strcat(path, "]");
strcat(path, links[i]);
state = 4;
}
break;
case 4:
fatal_error("Problem in vms_links_to_path()");
}
}
/* Is a closed bracket needed? */
if (state == 3)
strcat(path, "]");
return path;
}
/*
* links_to_path - Construct a path from its constituent links. "system"
* identifies the system (e.g., SYS_UNIX). "links" is a
* pointer to an array of pointers to the link names.
* "nlinks" is the number of entries in "links". Call
* XtFree() to free the memory returned by links_to_path().
*/
char *
links_to_path(system, links, nlinks)
int system;
char **links;
int nlinks;
{
switch (system) {
case SYS_VMS:
return vms_links_to_path(links, nlinks);
case SYS_DOS:
return dos_links_to_path(links, nlinks);
case SYS_WINDOWS:
return windows_links_to_path(links, nlinks);
case SYS_NT:
return nt_links_to_path(links, nlinks);
default:
return unix_links_to_path(links, nlinks);
}
}
/*
* merge_paths - Merge paths "full_path" and "rel_path". "full_path"
* should be a full directory path and "rel_path" should be
* relative to "full_path". The intent is to return a full
* path that is equivalent to referencing "rel_path" from
* directory "full_path". "system" identifies the system
* (e.g., "SYS_UNIX"). Call XtFree() to free memory returned
* by merge_paths().
*/
char *
merge_paths(system, full_path, rel_path)
int system;
char *full_path;
char *rel_path;
{
char **full_path_links;
char **rel_path_links;
char **links;
char **ptr;
char *path;
int nlinks = 0;
int indx;
full_path_links = path_to_links(system, full_path);
rel_path_links = path_to_links(system, rel_path);
/* Allocate space for array of link names */
ptr = full_path_links;
while (*ptr++)
nlinks++;
ptr = rel_path_links;
while (*ptr++)
nlinks++;
links = (char **)XtMalloc(sizeof(char *)*(nlinks+1));
/* Merge links */
indx = 0;
ptr = full_path_links;
while (*ptr) {
links[indx++] = XtNewString(*ptr);
ptr++;
}
ptr = rel_path_links;
while (*ptr) {
links[indx++] = XtNewString(*ptr);
ptr++;
}
links[indx] = NULL;
/* Create a merged path */
path = links_to_path(system, links, nlinks);
/* Free memory before returning */
release_path_links(full_path_links);
release_path_links(rel_path_links);
release_path_links(links);
return path;
}
/*
* parse_path - Parses path name "path" into its constituent directory
* "dir" and entry "entry". The caller is responsible
* for calling XtFree() to release memory. "system" identifies
* the system (e.g., SYS_UNIX). If "dir" or "entry" is NULL,
* no corresponding value is returned.
*/
void
parse_path(system, path, dir, entry)
int system;
char *path;
char **dir;
char **entry;
{
char **links;
char **dir_links;
char **ptr;
int nlinks = 0;
int i;
/* Break path into links and count them */
links = path_to_links(system, path);
ptr = links;
while (*ptr++)
nlinks++;
/* Sanity check */
if (nlinks < 2)
fatal_error("Problem in parse_path()");
/* Create directory path from links */
dir_links = (char **)XtMalloc(sizeof(char *)*nlinks);
for (i=0; i<nlinks-1; i++)
dir_links[i] = XtNewString(links[i]);
dir_links[nlinks-1] = NULL;
if (dir)
*dir = links_to_path(system, dir_links, nlinks-1);
/* Pick off entry */
if (entry)
*entry = XtNewString(links[nlinks-1]);
/* Free memory before returning */
release_path_links(links);
release_path_links(dir_links);
}
/*
* unix_rel_dir_path_to_dos - Convert the Unix relative directory path to
* the format used by the DOS system. Call
* XtFree() to release returned memory.
*/
char *
unix_rel_dir_path_to_dos(path)
char *path;
{
char *dos_path;
char *p;
/* Same as Unix relative path, with the /'s changed to \'s */
dos_path = XtNewString(path);
p = dos_path;
while (*p) {
if (*p == '/')
*p = '\\';
p++;
}
return dos_path;
}
/*
* unix_rel_dir_path_to_windows - Convert the Unix relative directory path
* to the format used by the Windows system.
* Call XtFree() to release returned memory.
*/
char *
unix_rel_dir_path_to_windows(path)
char *path;
{
return XtNewString(path);
}
/*
* unix_rel_dir_path_to_vms - Convert the Unix relative directory path to
* the format used by the VMS system. Call
* XtFree() to release returned memory.
*/
char *
unix_rel_dir_path_to_vms(path)
char *path;
{
char **unix_links;
char **vms_links;
char *vms_path;
char **ptr;
int nlinks = 0;
int i;
/* Parse Unix relative path into links */
unix_links = unix_path_to_links(path);
/* Allocate space for array of VMS links names */
ptr = unix_links;
while (*ptr++)
nlinks++;
vms_links = (char **)XtMalloc(sizeof(char *)*(nlinks+1));
/* Create VMS links */
for (i=0; i<nlinks; i++) {
vms_links[i] = XtMalloc(strlen(unix_links[i])+5);
strcpy(vms_links[i], unix_links[i]);
strcat(vms_links[i], ".dir");
}
vms_links[nlinks] = NULL;
/* Create VMS path from links */
vms_path = vms_links_to_path(vms_links, nlinks);
/* Release memory before returning */
release_path_links(unix_links);
release_path_links(vms_links);
return vms_path;
}
/*
* unix_rel_dir_path_to_native - Convert the Unix relative directory path
* to the native "system" format. "system"
* identifies the system (e.g., SYS_UNIX).
* Call XtFree() to release returned memory.
*/
char *
unix_rel_dir_path_to_native(system, path)
int system;
char *path;
{
switch (system) {
case SYS_VMS:
return unix_rel_dir_path_to_vms(path);
case SYS_DOS:
return unix_rel_dir_path_to_dos(path);
case SYS_WINDOWS:
return unix_rel_dir_path_to_windows(path);
default:
return XtNewString(path);
}
}
/*
* unix_rel_file_path_to_vms - Convert the Unix relative file path to
* the format used by the VMS system. Call
* XtFree() to release returned memory.
*/
char *
unix_rel_file_path_to_vms(path)
char *path;
{
char **unix_links;
char **vms_links;
char *vms_path;
char **ptr;
int nlinks = 0;
int i;
/* Parse Unix relative path into links */
unix_links = unix_path_to_links(path);
/* Allocate space for array of VMS links names */
ptr = unix_links;
while (*ptr++)
nlinks++;
vms_links = (char **)XtMalloc(sizeof(char *)*(nlinks+1));
/* Create VMS links */
for (i=0; i<nlinks-1; i++) {
vms_links[i] = XtMalloc(strlen(unix_links[i])+5);
strcpy(vms_links[i], unix_links[i]);
strcat(vms_links[i], ".dir");
}
vms_links[nlinks-1] = XtNewString(unix_links[nlinks-1]);
vms_links[nlinks] = NULL;
/* Create VMS path from links */
vms_path = vms_links_to_path(vms_links, nlinks);
/* Release memory before returning */
release_path_links(unix_links);
release_path_links(vms_links);
return vms_path;
}
/*
* unix_rel_file_path_to_native - Convert the Unix relative file path
* to the native "system" format. "system"
* identifies the system (e.g., SYS_UNIX).
* Call XtFree() to release returned memory.
*/
char *
unix_rel_file_path_to_native(system, path)
int system;
char *path;
{
switch (system) {
case SYS_VMS:
return unix_rel_file_path_to_vms(path);
case SYS_DOS:
return unix_rel_dir_path_to_dos(path);
case SYS_WINDOWS:
return unix_rel_dir_path_to_windows(path);
default:
return XtNewString(path);
}
}
/*
* equivalent_file_path - The purpose of this kludgy function is to convert
* a directory path into a file path. This is a no-op
* if "system" is not SYS_VMS. If "system" is SYS_VMS,
* the following sort of conversion take place:
*
* a::b:[c.d.e] --> a::b:[c.d]e.dir
* a::b:[c.d]e --> a::b:[c.d]e (no-op)
* a::b:[c] --> a::b:c.dir
*
* Call XtFree() to release returned memory.
*/
char *
equivalent_file_path(system, path)
int system;
char *path;
{
char **links;
char **ptr;
char *dir_path;
char *new_path;
int nlinks = 0;
int len = 0;
if (system == SYS_VMS) {
links = vms_path_to_links(path);
ptr = links;
while (*ptr++)
nlinks++;
len = strlen(links[nlinks-1]);
if ((len > 4) && !strcmp(&links[nlinks-1][len-4], ".dir")) {
dir_path = vms_links_to_path(links, nlinks-1);
new_path = XtMalloc(strlen(dir_path)+len+1);
strcpy(new_path, dir_path);
strcat(new_path, links[nlinks-1]);
XtFree(dir_path);
} else {
new_path = XtNewString(path);
}
release_path_links(links);
} else
new_path = XtNewString(path);
return new_path;
}
syntax highlighted by Code2HTML, v. 0.9.1