18c5943b478f8a43c75108bf4d1bd6dc619e4d55
[oweals/cde.git] / cde / lib / DtSearch / raima / pathfcns.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: pathfcns.c /main/2 1996/05/09 04:13:28 drk $ */
24 /*
25  *   COMPONENT_NAME: austext
26  *
27  *   FUNCTIONS: con_dbd
28  *              con_dbf
29  *              d_ctbpath
30  *              get_element
31  *              isabs
32  *              remdrv
33  *              remfile
34  *
35  *   ORIGINS: 157
36  *
37  *   OBJECT CODE ONLY SOURCE MATERIALS
38  */
39 /*-----------------------------------------------------------------------
40    pathfcns.c - Dictionary and file path functions
41
42    This file contains the functions con_dbd and con_dbf which construct
43    the full path for the dictionary and data files.  It provides a uniform
44    method of dealing with how to construct the full paths given the schema
45    path, d_open path, and the paths provided in DBDPATH and DBFPATH.  This
46    function does not depend upon the runtime and can be included with
47    utilities that do not call the runtime.
48
49    This file also contains the function get_element which extracts a single
50    element out of the possibly multiple-element DBDPATH or DBFPATH.  Each
51    element is separated by a semacolon.
52
53    AUTHOR:      R.S. Carlson
54    DATE:        08-Jun-88
55    PROJECT:     db_VISTA 3.10 enhancements
56
57    Copyright (C) 1988 by Raima Corporation
58 -----------------------------------------------------------------------*/
59
60 /* ********************** EDIT HISTORY *******************************
61
62  SCR    DATE    INI                   DESCRIPTION
63 ----- --------- --- -----------------------------------------------------
64       16-JUN-88 RSC Cleaned up prototyping (proto.h) and made functions static
65       23-Jun-88 RSC Make const_dbd and const_dbf unique to 7 chars
66 */
67
68
69 /* ********************** INCLUDE FILES ****************************** */
70
71 #include <stdio.h>
72 #include "vista.h"
73 #include "dbtype.h"
74
75 #ifdef dbdpath
76 #undef dbdpath
77 #endif
78 #ifdef dbfpath
79 #undef dbfpath
80 #endif
81
82 /* ********************** FUNCTION PROTOTYPES ************************ */
83
84 static int isabs(P1(char *));
85                                         /* TRUE if path is absolute */
86 static char * remdrv(P1(char *));
87                                         /* Removes drive spec from path */
88 static char * remfile(P1(char *));
89                                         /* Removes file from path */
90
91 /* ======================================================================
92    Construct the full path to the dictionary.
93 */
94 int con_dbd(
95 char *path_str, /* (output) string to receive the full path to the
96                            dictionary */
97 char *dbname,   /* contains the filename of the dictionary preceded
98                            optionally by a path preceded optionally (DOS only)
99                            by a drive spec. */
100 char *dbdpath   /* contains one element of the environment variable
101                            DBDPATH.  NULL means no DBDPATH defined. */
102 )
103 {
104 /*
105    RETURNS: db_status, S_OKAY means no errors
106    ASSUMES: That the string dbdpath contains enough room
107                   to add a DIRCHAR if it isn't in there.
108 */
109
110    int i;                               /* Trusty loop counter / index */
111
112    /* We stop constructing the string when we find an absolute path */
113    if (isabs(dbname)) {
114       strcpy(path_str,dbname);
115    }
116    else {
117
118       /* See if dbdpath was defined.  Make sure it ends with a DIRCHAR
119          or ':' */
120       if (dbdpath) {
121          i = strlen(dbdpath);
122          if (dbdpath[i-1] != DIRCHAR && dbdpath[i-1] != ':') {
123             dbdpath[i++] = DIRCHAR;
124             dbdpath[i]   = '\0';
125          }
126          if (i >= FILENMLEN - 4) return (db_status = S_NAMELEN);
127
128          /*  Now construct the path with dbdpath + dbname */
129          strcpy(path_str,dbdpath);
130          if (strlen(path_str) + strlen(remdrv(dbname)) >= FILENMLEN - 4)
131             return (db_status = S_NAMELEN);
132          strcat(path_str,remdrv(dbname));
133       }
134       else                           /* dbdpath not defined */
135          strcpy(path_str,dbname);
136    }
137
138    /* Now add the .dbd extension */
139    strcat(path_str,".dbd");
140    return (db_status = S_OKAY);
141
142 }
143 /* ======================================================================
144    Construct full path to data/key files
145 */
146 int con_dbf(
147 char *path_str, /* (output) receives full path to dictionary */
148 char *dbfile,   /* path to database file (defn in schema) */
149 char *dbname,   /* d_open dbname argument - path to dictionary */
150 char *dbfpath   /* one element from DBFPATH, or NULL for no path */
151 )
152 {
153 /*
154    RETURNS: db_status, S_OKAY means no error.
155    ASSUMES: None.
156 */
157    char filespec[FILENMLEN];            /* Scratch work space */
158    int i;                               /* Trusty loop counter/index */
159
160    /* Stop construction when we get to an absolute path.  If we prepend
161       then remove the previous drive specifier */
162    strcpy(path_str,dbfile);
163    if (isabs(dbfile)) return (db_status = S_OKAY);
164
165    /* Add only the drive specification and directory component of the
166       path supplied in dbname */
167    if ((dbname = remfile(dbname)) != NULL) {
168       if (strlen(path_str) + strlen(dbname) >= FILENMLEN)
169          return(db_status = S_NAMELEN);
170       strcpy(filespec,dbname);          /* Copy to working space */
171       strcat(filespec,remdrv(path_str));/* Construct dbname + schema */
172       strcpy(path_str,filespec);        /* Place in o/p string */
173       if (isabs(dbname)) return (db_status = S_OKAY);
174    }
175
176    /* Now add the path specification from DBFPATH, if defined */
177    if (dbfpath == NULL) return (db_status = S_OKAY);
178    i = strlen(dbfpath);                 /* Make sure it ends with DIRCHAR */
179    if (dbfpath[i-1] != DIRCHAR && dbfpath[i-1] != ';') {
180       dbfpath[i++] = DIRCHAR;
181       dbfpath[i]   = '\0';
182    }
183    if (strlen(path_str) + strlen(dbfpath) >= FILENMLEN)
184       return (db_status = S_NAMELEN);
185    strcpy(filespec,dbfpath);
186    strcat(filespec,remdrv(path_str));
187    strcpy(path_str,filespec);
188    return (db_status = S_OKAY);
189
190 }
191
192 /* ======================================================================
193    extracts a single element from DBxPATH type variables
194 */
195 char * get_element(
196 char *dbxpath,  /* DBxPATH, elements separated by semicolons
197                            NULL causes get_element to return NULL.
198                            A NULL string also causes a NULL return */
199 int num                 /* Element to extract (0 = first) */
200 )
201 {
202 /*
203    RETURNS: Pointer to string with element.  NULL if no such element
204             exists.  If there is only one element in the string, then
205             that element is returned regardless of the value of num.
206    ASSUMES: dbxpath cannot exceed FILENMLEN chars.
207 */
208
209    static char element[FILENMLEN+1];    /* return value */
210    int i;
211    char *save;
212
213    if (dbxpath == NULL) return (NULL);
214    if (dbxpath[0] == '\0') return (NULL);       /* NULL string? */
215    strcpy(element,dbxpath);
216
217    /* If there is only one element, always return that */
218    if (strchr(element,';') == NULL) {
219       i = strlen(element);
220       if (element[i-1] != DIRCHAR && element[i-1] != ':') {
221          element[i++] = DIRCHAR;
222          element[i] = '\0';
223       }
224       return (element);
225    }
226
227    /* There are multiple elements - return the one requested */
228    dbxpath = element - 1;
229    for (i=0; i<num; i++)
230       if ((dbxpath = strchr(dbxpath+1,';')) == NULL) return (NULL);
231    dbxpath++;
232    if ((save = strchr(dbxpath+1,';')) != NULL) *save = '\0';
233    i = (dbxpath - (char *)element) + strlen((const char *)dbxpath);
234    if (element[i-1] != DIRCHAR && element[i-1] != ':') {
235       element[i++] = DIRCHAR;
236       element[i] = '\0';
237    }
238    return (dbxpath);
239 }
240
241 /* ======================================================================
242    Returns TRUE of path is absolute
243 */
244 static int isabs(
245 char *path_str  /* path to test, NULL causes iabs to return FALSE */
246 )
247 {
248 /*
249    RETURNS: TRUE if path is absolute
250    ASSUMES: None.
251 */
252    char *path;                  /* Points to path w/o drive spec */
253
254    if (path_str == NULL) return (FALSE);
255    path = remdrv(path_str);
256    if (path[0] != DIRCHAR) return (FALSE);
257    return (TRUE);
258 }
259
260 /* ======================================================================
261    Removes drive specifier from path
262 */
263 static char * remdrv(
264 char *path_str          /* path to remove drive from */
265 )
266 {
267 /*
268    RETURNS:       Pointer to string w/o drive specification.  Note that
269                   this simply points further into path_str.
270    ASSUMES: None.
271 */
272    char *path;                  /* Return value */
273
274    if ((path = strrchr(path_str,':')) == NULL) return (path_str);
275    return (path+1);
276 }
277
278 /* ======================================================================
279    Removes file from a path.
280 */
281 static char * remfile(
282 char *path_str          /* Path to remove filename from */
283 )
284 {
285 /*
286    RETURNS: Pointer to the path with the filename removed (a static
287             string declared within remfile).  If there is no filename
288             (only a directory or drive spec), remfile will return
289             NULL.  The returned string will end with a DIRCHAR
290    ASSUMES: path_str cannot exceed FILENMLEN characters.
291 */
292    static char dirpath[FILENMLEN];              /* Return value */
293
294    /* There is only a filename if string does not contain a DIRCHAR or
295       ':' which separates drive spec from path. */
296    if (path_str == NULL) return (NULL);
297    strcpy(dirpath,path_str);            /* Copy into output string */
298    if ((path_str = strrchr(dirpath,DIRCHAR)) == NULL)
299       if ((path_str = strrchr(dirpath,':')) == NULL) return (NULL);
300    path_str[1] = '\0';                  /* Truncate string */
301    return (dirpath);
302 }
303
304 /* Set Country Table path
305 */
306 int d_ctbpath(const char *ctb)
307 {
308    int i;
309
310    DB_ENTER(NO_DB_ID TASK_ID LOCK_SET(LOCK_NONE));
311
312    if ( dbopen )
313       dberr(S_DBOPEN);
314    else {
315       strncpy(db_global.ctbpath, ctb, FILENMLEN - 1);
316       db_global.ctbpath[FILENMLEN - 1] = '\0';
317       if ( db_global.ctbpath[0] ) {
318          i = strlen(db_global.ctbpath);
319          if ( db_global.ctbpath[i-1] != DIRCHAR &&
320             db_global.ctbpath[i-1] != ':' ) {
321             db_global.ctbpath[i++] = DIRCHAR;
322             db_global.ctbpath[i] = '\0';
323          }
324          if ( i >= FILENMLEN-1 ) RETURN( dberr(S_NAMELEN) );
325       }
326
327       db_status = S_OKAY;
328    }
329
330    RETURN( db_status );
331 }
332 /* vpp -nOS2 -dUNIX -nBSD -nVANILLA_BSD -nVMS -nMEMLOCK -nWINDOWS -nFAR_ALLOC -f/usr/users/master/config/nonwin pathfcns.c */