123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /*
- * $TOG: DbUtil.c /main/13 1998/04/09 17:47:56 mgreess $
- *
- * (c) Copyright 1988, 1989, 1990, 1991, 1992, 1993
- * by Hewlett-Packard Company, all rights reserved.
- *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <ctype.h>
- #include <string.h>
- #ifdef NLS16
- #include <limits.h>
- #endif
- #include <sys/stat.h>
- #include <sys/param.h> /* MAXPATHLEN, MAXHOSTNAMELEN */
- #include <X11/Xlib.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #define X_INCLUDE_DIRENT_H
- #define XOS_USE_XT_LOCKING
- #include <X11/Xos_r.h>
- #include <Dt/DtP.h>
- #include <Dt/Connect.h>
- #include <Dt/FileUtil.h>
- #include <Dt/DtNlUtils.h>
- #include <Dt/Action.h>
- #include <Dt/ActionP.h>
- #include <Dt/ActionDbP.h>
- #include <Dt/ActionUtilP.h>
- #include <Dt/DbUtil.h>
- #include <Dt/Utility.h>
- #include <Dt/ActionDb.h>
- #ifndef S_ISLNK
- /* This macro is normally defined in stat.h, but not on USL systems. */
- # define S_ISLNK(_M) ((_M & S_IFMT)==S_IFLNK) /* test for symbolic link */
- #endif
- #ifndef CDE_INSTALLATION_TOP
- #define CDE_INSTALLATION_TOP "/opt/dt"
- #endif
- #ifndef CDE_CONFIGURATION_TOP
- #define CDE_CONFIGURATION_TOP "/etc/opt/dt"
- #endif
- #define TRUE 1
- #define FALSE 0
- #define FILE_INCREMENT 20
- /* The following string holds the default value of the Dt database
- * search path. This default search path has the following major
- * components:
- *
- * $HOME/.dt/types[/%L] A location for the user's personal
- * actions and filetypes.
- *
- * <config-location>/appconfig/types[/%L]
- * The DT location for system-wide
- * customizations.
- *
- * <top-of-dt>/types/[%L] The DT location for default
- * system-wide actions and filetypes.
- */
- static char DTDATABASESEARCHPATH_DEFAULT[] =
- "%s/.dt/types/%%L,"
- "%s/.dt/types,"
- CDE_CONFIGURATION_TOP "/appconfig/types/%%L,"
- CDE_CONFIGURATION_TOP "/appconfig/types,"
- CDE_INSTALLATION_TOP "/appconfig/types/%%L,"
- CDE_INSTALLATION_TOP "/appconfig/types";
- /**** Substitution records used by XtFindFile() in _DtExpandLang() ****/
- static SubstitutionRec langSubstitutions[] =
- {
- {'L', (char *)NULL},
- {'l', (char *)NULL},
- {'t', (char *)NULL},
- {'c', (char *)NULL}
- };
- static int nLangSubstitutions = XtNumber(langSubstitutions);
- /******** Static Function Declarations ********/
- static Boolean __testPath(
- String str );
- static void __setupLangSubstitutions(
- void );
- static void __freeLangSubstitutions(
- void );
- static char *_DtExpandLang(
- char *string ) ;
- static char _DtIsDir(
- char *path,
- char *name) ;
- static void _DtFreeDirVector(
- char **dir_vector) ;
- static void __swap(
- int i ,
- DtDirPaths *data );
- static void _DtSortFiles(
- int low,
- int n,
- DtDirPaths *data) ;
- /******** End Static Function Declarations ********/
- /******************
- *
- * Function Name: __testPath
- *
- * Description:
- *
- * This function is needed by XtFindFile(). Always returns True.
- *
- * Synopsis:
- *
- * path = XtFindFile(..., __testPath);
- *
- ******************/
- static Boolean
- __testPath(String str)
- {
- return True;
- }
- /******************
- *
- * Function Name: __setupLangSubstitutions
- *
- * Description:
- *
- * This function initializes langSubstitutions[] for use by
- * XtFindFile().
- *
- * Synopsis:
- *
- * __setupLangSubstitutions();
- *
- ******************/
- static void
- __setupLangSubstitutions(void)
- {
- char *lang;
- char *languagePart;
- char *territoryPart;
- char *codesetPart;
- char *tlPtr, *ttPtr, *tcPtr, *endPtr;
- /*
- * We should really be calling setlocale to determine the "default"
- * locale but setlocale's return value is not standardized across
- * the various vendor platforms nor is it consistent within differnt
- * revs of individual OS's. (e.g. its changing between HP-UX 9.0 and
- * HP-UX 10.0). The "right" call would be the following line:
- *
- * if ((lang = getenv ("LANG")) || (lang = setlocale(LC_C_TYPE,NULL)))
- *
- * Here we hard code the default to "C" instead of leaving it NULL.
- */
- languagePart = territoryPart = codesetPart = (char *)NULL;
- if ((lang = getenv ("LANG")) == (char *)NULL)
- lang = "C";
- lang = XtNewString(lang); /* free'd in __freeLangSubstitutions() */
- tlPtr = lang;
- endPtr = (char *)NULL;
- if ((ttPtr = DtStrchr(tlPtr, '_')) != (char *)NULL)
- ttPtr++;
- if ((tcPtr = DtStrchr(ttPtr ? ttPtr : tlPtr, '.')) != (char *)NULL)
- {
- endPtr = tcPtr++;
- if (*tcPtr != '\0')
- codesetPart =
- XtNewString(tcPtr); /* free'd in __freeLangSubstitutions() */
- }
- if (ttPtr)
- {
- if (endPtr)
- {
- int ttLen = endPtr - ttPtr;
- if (ttLen > 0)
- {
- /* free'd in __freeLangSubstitutions() */
- territoryPart = (char *)XtMalloc((ttLen + 1) * sizeof(char));
- strncpy(territoryPart, ttPtr, ttLen);
- territoryPart[ttLen] = '\0';
- }
- }
- else territoryPart =
- XtNewString(ttPtr); /* free'd in __freeLangSubstitutions() */
- endPtr = ttPtr - 1;
- }
- if (endPtr)
- {
- int tlLen = endPtr - tlPtr;
- if (tlLen > 0)
- {
- /* free'd in __freeLangSubstitutions() */
- languagePart = (char *)XtMalloc((tlLen + 1) * sizeof(char));
- strncpy(languagePart, tlPtr, tlLen);
- languagePart[tlLen] = '\0';
- }
- }
- else languagePart =
- XtNewString(tlPtr); /* free'd in __freeLangSubstitutions() */
- langSubstitutions[0].substitution = lang;
- langSubstitutions[1].substitution = languagePart;
- langSubstitutions[2].substitution = territoryPart;
- langSubstitutions[3].substitution = codesetPart;
- }
- /******************
- *
- * Function Name: __freeLangSubstitutions
- *
- * Description:
- *
- * This function free's the strings allocated by
- * __setupLangSubstitutions and placed into langSubstitutions[]
- *
- * Synopsis:
- *
- * __freeLangSubstitutions();
- *
- ******************/
- static void
- __freeLangSubstitutions(void)
- {
- int i;
- for (i = 0; i < nLangSubstitutions; i++)
- XtFree(langSubstitutions[i].substitution);
- }
- /******************
- *
- * Function Name: _DtExpandLang
- *
- * Description:
- *
- * This function takes the string "string", and performs the following
- * replacements:
- * %L : contents of LANG environment variable.
- * %l : language part of the LANG environment variable.
- * %t : territory part of the LANG environment variable.
- * %c : codeset part of the LANG environment variable.
- * %% : % (e.g. %%L would be replaced by %L, and
- * no substitution would be performed on %L)
- *
- * If $LANG is not defined, the $LANG is assumed to be "C".
- *
- * Synopsis:
- *
- * ret_string = _DtExpandLang (string);
- *
- * char *ret_string; Returns NULL if "string" is NULL, or it points
- * to the expanded string.
- *
- * char *string; The comma-separated pathnames to expand.
- *
- * Note: The caller is responsible for free'ing the returned string.
- *
- ******************/
- static char *
- _DtExpandLang(
- char *string )
- {
- char *thisPath;
- char *newPath;
- char *modPath;
- int pathLen, maxPathLen;
- int nColons;
- char *tmpPtr, *tmpPtr1;
- char *newString;
- char *tokPtr;
- if (string == NULL)
- return (NULL);
- /*
- * We're going to use XtFindFile() to perform the replacements;
- * the colon character ':' is used as a delimiter in XtFindFile,
- * so we escape all colon characters in our string before
- * passing it along.
- */
- for (nColons = 0, tmpPtr = string;
- (tmpPtr = DtStrchr(tmpPtr, ':')) != (char *)NULL;
- nColons++, tmpPtr++)
- /* EMPTY */
- ;
- newString =
- (char *)XtCalloc(1, (strlen(string) + nColons + 1) * sizeof(char));
- for (tmpPtr = string;
- (tmpPtr1 = DtStrchr(tmpPtr, ':')) != (char *)NULL;
- tmpPtr = tmpPtr1 + 1)
- {
- strncat(newString, tmpPtr, tmpPtr1 - tmpPtr);
- strcat(newString, "%:");
- }
- strcat(newString, tmpPtr);
- __setupLangSubstitutions();
- /*
- * XtFindFile() assumes that the string into which it's making
- * substitutions is a path, and therefore it assumes that the
- * length of the string does not exceed MAXPATHLEN. Since
- * our string is a series of paths, it CAN exceed MAXPATHLEN.
- * So, we split our string into individual paths which we then
- * pass off to XtFindFile().
- */
- pathLen = maxPathLen = 0;
- newPath = (char *)NULL;
- for (thisPath = DtStrtok_r(newString, ",", &tokPtr);
- thisPath != (char *)NULL;
- thisPath = DtStrtok_r((char *)NULL, ",", &tokPtr))
- {
- modPath = XtFindFile(thisPath, langSubstitutions,
- nLangSubstitutions, __testPath);
- if (modPath)
- {
- char *origPath = modPath;
- int modLen;
- /*
- * For some reason, XtFindFile() collapses all '/'
- * characters EXCEPT at the beginning of the path!
- * For backwards compatibility, we collapse those here.
- */
- if (*modPath == '/')
- {
- while (*(modPath + 1) == '/')
- modPath++;
- }
- modLen = strlen(modPath);
- if (pathLen + modLen + 2 > maxPathLen)
- {
- maxPathLen =
- ((pathLen + modLen + 2 + MAXPATHLEN) / MAXPATHLEN) *
- MAXPATHLEN;
- newPath =
- (char *)XtRealloc(newPath, maxPathLen * sizeof(char));
- }
- if (pathLen > 0)
- newPath[pathLen++] = ',';
- strcpy(&(newPath[pathLen]), modPath);
- pathLen += modLen;
- XtFree(origPath);
- }
- }
- __freeLangSubstitutions();
- XtFree(newString);
- return newPath;
- }
- /******************
- *
- * Function Name: _DtIsDir
- *
- * Description:
- *
- * This function tests a pathname to see if it is a directory.
- * The path name is received in two pieces, which makes it easy
- * for the calling function to test a bunch of files in a directory
- * to see if any are subdirectories.
- *
- * This function does NOT handle Softbench-style pathnames with
- * embedded hostnames.
- *
- * Synopsis:
- *
- * dir = _DtIsDir (path, name);
- *
- * char dir; Returns 0 if the item is not a directory,
- * 1 if it is.
- * char *path; The first part of the pathname. Typically
- * the directory containing the item of interest.
- * char *name; The second half of the pathname. Typically
- * the name of the item of interest.
- *
- ******************/
- static char
- _DtIsDir(
- char *path,
- char *name )
- {
- struct stat stat_buf;
- char *stat_name;
-
- stat_name = XtMalloc ((Cardinal)(strlen(path) + strlen(name) + 2));
- (void)strcpy (stat_name, path);
- (void)strcat (stat_name, "/");
- (void)strcat (stat_name, name);
-
- if(stat (stat_name, &stat_buf))
- {
- stat_buf.st_mode = 0;
- }
- XtFree (stat_name);
-
- if (stat_buf.st_mode & S_IFDIR)
- return (TRUE);
- else
- return (FALSE);
- }
- /******************************
- *
- * Function Name: _DtFreeDirVector
- *
- * Description:
- *
- * This function frees a database-directory string vector.
- *
- * Synoposis:
- *
- * FreeDatabaseDirs (dirs);
- *
- * char **dirs; The string vector to free.
- *
- ********************************/
- static void
- _DtFreeDirVector(
- char **dir_vector )
- {
- char **v;
-
- if (dir_vector)
- {
- for (v = dir_vector; *v != NULL; v++)
- XtFree ((char *)*v);
-
- XtFree ((char *)dir_vector);
- }
- }
- /******************************
- *
- * Function Name: __swap
- *
- * Description:
- *
- * This function exchanges two elements in an array of DtDirPaths.
- *
- * Synoposis:
- *
- * __swap (i, data);
- *
- * int i; The base index to change.
- * DtDirPaths *data; The data to change.
- *
- ********************************/
- static void
- __swap(
- int i ,
- DtDirPaths *data )
- {
- char *tmp;
- /* The "names" field of the structure is not touched because
- * this field is "NULL" for all of the entries.
- */
- tmp = data->dirs[i];
- data->dirs[i] = data->dirs[i+1]; data->dirs[i+1] = tmp;
- tmp = data->paths[i];
- data->paths[i] = data->paths[i+1]; data->paths[i+1] = tmp;
- }
- /******************************
- *
- * Function Name: _DtSortFiles
- *
- * Description:
- *
- * Given an index, an array of "char" data and the number of elements to
- * sort, this function sorts the data. The sorting algorithm is based
- * on a bubble sort because the number of elements is usually less than
- * ten.
- *
- * Synoposis:
- *
- * _DtSortFiles (index, n, data);
- *
- * int low; The base of the array to begin the sorting.
- * int n; The number of elements to sort.
- * DtDirPaths *data; The data to sort.
- *
- ********************************/
- static void
- _DtSortFiles(
- int low,
- int n,
- DtDirPaths *data )
- {
- int i, j;
- int high = low + n;
- /*
- * This sorting routine needs to be able to sort any portion of
- * an array - it does not always start at element '0'.
- */
- for (i = low; i < (high - 1); i++)
- for (j = low; j < (high - 1); j++)
- #ifndef NO_MESSAGE_CATALOG
- if ((strcoll (data->paths[j], data->paths[j+1])) > 0)
- #else
- if ((strcmp (data->paths[j], data->paths[j+1])) > 0)
- #endif
- __swap (j, data);
- }
- /******************
- *
- * Function Name: _DtFindMatchingFiles
- *
- * Description:
- *
- * This function takes a string vector of directory names (which
- * are in "host:/path/file" format) and a filename suffix and
- * finds all of the files in those directories with the specified
- * suffix. It returns a string vector of the filenames.
- *
- * You will typically first call _DtGetDatabaseDirPaths() to get the
- * 'dirs' info.
- *
- * Use _DtFreeDatabaseDirPaths() to free up the return structure.
- *
- * Synopsis:
- *
- * filev = _DtFindMatchingFiles (dirs, suffix, sort_files);
- *
- * DtDirPaths *filev; A structure containing the names
- * of all the files that were found.
- * DtDirPaths *dirs; A structure of directories to be
- * searched.
- * char *suffix; The suffix string which is compared
- * to the end of the filenames. This
- * string must contain a "." if it is
- * part of the suffix you want to match
- * on (e.g. ".c").
- * Boolean sort_files; Should the files within a directory be sorted.
- *
- *
- ******************/
- DtDirPaths *
- _DtFindMatchingFiles(
- DtDirPaths *dirs,
- char *suffix,
- Boolean sort_files )
- {
- /* LOCAL VARIABLES */
-
- DtDirPaths *files; /* An array of pointers to the filenames which
- have been found. */
- int max_files; /* The total number of filenames that can be
- stored in the "files" array before it must
- be reallocd. */
- int num_found; /* The number of files which have been found. */
- DIR *dirp; /* Variables for walking through the directory
- entries. */
- char * next_file;
- struct dirent *dp = NULL;
- char *file_suffix;
- int suffixLen, nameLen;
- int nextIndex;
- char * next_path;
- int files_in_this_directory;
- int base;
- _Xreaddirparams dirEntryBuf;
- struct dirent *result;
- /* CODE */
- if (dirs == NULL)
- return(NULL);
-
- files = (DtDirPaths *) XtMalloc((Cardinal)(sizeof(DtDirPaths)));
- files->dirs = (char **) XtMalloc(sizeof(char *) * FILE_INCREMENT);
- files->paths = (char **) XtMalloc(sizeof(char *) * FILE_INCREMENT);
- max_files = FILE_INCREMENT;
- num_found = 0;
- nextIndex = 0;
-
- /* Process each one of the directories in priority order. */
- while (dirs->paths[nextIndex] != NULL) {
- next_path = dirs->paths[nextIndex];
- dirp = opendir (next_path);
- base = num_found;
-
- files_in_this_directory = 0;
- while ((result = _XReaddir(dirp, dirEntryBuf)) != NULL) {
- /* Check the name to see if it matches the suffix and is
- a file. */
- if (strlen (result->d_name) >= strlen(suffix))
- {
- /* Find the end of the name and compare it to the suffix. */
- /* Get the number of chars (not bytes) in each string */
- suffixLen = DtCharCount(suffix);
- nameLen = DtCharCount(result->d_name);
- file_suffix = _DtGetNthChar(result->d_name, nameLen - suffixLen);
- if (file_suffix && (strcmp(file_suffix, suffix) == 0) &&
- !_DtIsDir((char *)next_path, (char *)result->d_name))
- {
-
- /* The file is a match. See if there is room in the array
- or whether we need to realloc. The "-1" is to save room
- for the terminating NULL pointer. */
- if (num_found == max_files - 1) {
- files->dirs = (char **) XtRealloc ((char *)files->dirs,
- (Cardinal)(sizeof(char *) * (max_files + FILE_INCREMENT)));
- files->paths = (char **) XtRealloc ((char *)files->paths,
- (Cardinal)(sizeof(char *) * (max_files + FILE_INCREMENT)));
- max_files += FILE_INCREMENT;
- }
-
- /* Get some memory and copy the filename to the array. */
- files->dirs[num_found] = next_file = (char *)
- XtMalloc((Cardinal)(strlen(dirs->dirs[nextIndex]) +
- strlen (result->d_name) + 2));
- (void)strcpy(next_file, dirs->dirs[nextIndex]);
- (void)strcat(next_file, "/");
- (void)strcat(next_file, result->d_name);
- files->paths[num_found] = next_file = (char *)
- XtMalloc((Cardinal)(strlen(next_path) +
- strlen (result->d_name) + 2));
- (void)strcpy(next_file, next_path);
- (void)strcat(next_file, "/");
- (void)strcat(next_file, result->d_name);
-
- num_found++;
- files_in_this_directory++;
- }
- }
- }
- closedir (dirp);
- if (sort_files && (files_in_this_directory > 1))
- _DtSortFiles (base, files_in_this_directory, files);
- nextIndex++;
- }
- files->dirs[num_found] = NULL;
- files->paths[num_found] = NULL;
- return (files);
-
- }
- /******************************************************************************
- *
- * _DtDbGetDataBaseEnv( )
- * ------------------------
- * This function provides a PRIVATE API for internal manipulation of the
- * DTDATABASEDIRPATH environment variable before loading the databases.
- * -- used by the front panel code in dtwm.
- *
- * If the environment variable it returns a default path.
- *
- * NOTE: This function returns a freshly malloc'ed string. It is up to
- * the caller to free it.
- *
- ******************************************************************************/
- char *
- _DtDbGetDataBaseEnv( void )
- {
- char *nwh_dir;
- char *temp_buf;
- char *temp_s;
- int slen = 0;
- nwh_dir = getenv ("HOME");
- /*
- * Get the DTDATABASESEARCHPATH environment variable. If it is not set,
- * create the default value.
- */
- if (( temp_s = getenv ("DTDATABASESEARCHPATH")))
- if ( *temp_s != 0 ) return XtNewString(temp_s);
- slen = (2 * strlen(nwh_dir)) + strlen(DTDATABASESEARCHPATH_DEFAULT) + 1;
- temp_buf = XtCalloc(1, slen);
- snprintf (temp_buf, slen - 1,
- DTDATABASESEARCHPATH_DEFAULT, nwh_dir, nwh_dir);
- return temp_buf;
- }
- /******************************
- *
- * Function Name: _DtGetDatabaseDirPaths
- *
- * Description:
- *
- * This function returns a structure containing the external
- * and internal forms for all of the database directories that must be
- * searched for Dt database files.
- * The structure is freed using _DtFreeDatabaseDirPaths().
- *
- * The directories are all guaranteed to be fully-specified names;
- * i.e. host:/path/dir.
- *
- * THIS IS TYPICALLY CALLED BEFORE USING ANY OF THE FOLLOWING:
- *
- * DtReadDatabases()
- * DtPrepareToolboxDirs()
- * _DtDbRead()
- * _DtFindMatchingFiles()
- *
- * Synoposis:
- *
- * DtDirPaths * _DtGetDatabaseDirPaths ();
- *
- ********************************/
- DtDirPaths *
- _DtGetDatabaseDirPaths( void )
- {
- XrmValue resource_value;
- char *rep_type;
- char *dir_string, *remote_hosts;
- char *nwh_host; /* Holds the host portion of the user's
- network-home. */
- char **dir_vector; /* The list of directories are turned into
- a vector of strings. This points to the
- start of the vector. */
- char **hosts_vector;
- char **next_dir; /* A pointer used to walk through dir_vector. */
- char **next_host;
- char *dir; /* Points to next dir being processed */
- int valid_dirs; /* A count of the number of valid directories
- found. */
- char *home;
- char *nextc;
- DtDirPaths * ret_paths;
- char * internal;
- int i;
- char *tmp_dir_string;
- /* Get our host name, and the user's home directory */
- nwh_host = _DtGetLocalHostName ();
- tmp_dir_string = _DtDbGetDataBaseEnv();
- dir_string = _DtExpandLang (tmp_dir_string);
- XtFree (tmp_dir_string);
- /* Prepare the input vector and the two output vectors. */
- dir_vector = _DtVectorizeInPlace (dir_string, ',');
- ret_paths = (DtDirPaths *)XtMalloc(sizeof(DtDirPaths));
- ret_paths->dirs = NULL;
- ret_paths->paths = NULL;
- valid_dirs = 0;
- for (next_dir = dir_vector; *next_dir != NULL; next_dir++) {
- if (DtStrchr (*next_dir, '/') == NULL){
- /* It must be a relative path. */
- /* Ignore relative paths */
- continue;
- }
- /* If the name is not a valid directory, get rid of it. */
- if (!_DtIsOpenableDirContext (*next_dir, &internal)) {
- continue;
- }
- else {
- /* If not already in the list, add it to the structure. */
- for (i = 0; i < valid_dirs; i++)
- {
- if (strcmp(ret_paths->paths[i], internal) == 0)
- {
- break;
- }
- }
- if (i == valid_dirs)
- {
- valid_dirs++;
- ret_paths->dirs = (char **) XtRealloc ((char *)ret_paths->dirs,
- (Cardinal) (sizeof (char *) * valid_dirs));
- /* Make sure the directory name is fully-qualified with a host
- component. */
- if (DtStrchr (*next_dir, ':') != NULL)
- dir = XtNewString(*next_dir);
-
- /* If there is no host component, see if there is
- an absolute path. */
- else if (
- #ifdef NLS16
- (!is_multibyte || (mblen(*next_dir, MB_LEN_MAX) == 1)) &&
- #endif
- (**next_dir == '/')) {
- dir = XtMalloc ((Cardinal) (strlen (nwh_host) + 2 +
- strlen (*next_dir)));
- (void) sprintf (dir, "%s:%s", nwh_host, *next_dir);
- }
- else
- dir = XtNewString(*next_dir);
- ret_paths->dirs[valid_dirs - 1] = dir;
- ret_paths->paths = (char **) XtRealloc ((char *)ret_paths->paths,
- (Cardinal) (sizeof (char *) * valid_dirs));
- ret_paths->paths[valid_dirs - 1] = internal;
- }
- else {
- XtFree(internal);
- }
- }
- }
- /* The three vectors must be NULL terminated. */
- ret_paths->dirs = (char **) XtRealloc ((char *)ret_paths->dirs,
- (Cardinal) (sizeof (char *) *
- (valid_dirs + 1)));
- ret_paths->dirs[valid_dirs] = NULL;
- ret_paths->paths = (char **) XtRealloc ((char *)ret_paths->paths,
- (Cardinal) (sizeof (char *) *
- (valid_dirs + 1)));
- ret_paths->paths[valid_dirs] = NULL;
-
- XtFree ((char *) dir_string);
- XtFree ((char *) nwh_host);
- XtFree ((char *) dir_vector);
- return(ret_paths);
- }
- /***************************
- * void _DtFreeDatabaseDirPaths (paths)
- *
- * DtDirPaths * paths;
- *
- * This function will free up each of the arrays within the directory
- * information structure, and will then free the structure itself.
- *
- **************************/
- void
- _DtFreeDatabaseDirPaths(
- DtDirPaths *paths )
- {
- _DtFreeDirVector(paths->dirs);
- _DtFreeDirVector(paths->paths);
- XtFree((char *)paths);
- }
|