2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
26 #ifdef AFS_PTHREAD_ENV
28 static pthread_once_t dirInit_once = PTHREAD_ONCE_INIT;
32 #include <WINNT\afssw.h>
39 /* static storage for path strings */
40 static char dirPathArray[AFSDIR_PATHSTRING_MAX][AFSDIR_PATH_MAX];
42 /* indicate if and how the dirpath module initialized. */
43 static int initFlag = 0;
44 static unsigned int initStatus = 0;
47 /* storage for dynamically-determined install dir (NT only; long and short) */
49 static char ntServerInstallDirLong[AFSDIR_PATH_MAX];
50 static char ntServerInstallDirShort[AFSDIR_PATH_MAX];
51 static char ntClientConfigDirLong[AFSDIR_PATH_MAX];
52 static char ntClientConfigDirShort[AFSDIR_PATH_MAX];
55 /* storage for local afs server/client paths (top-level) */
56 static char afsSrvDirPath[AFSDIR_PATH_MAX];
57 static char afsClntDirPath[AFSDIR_PATH_MAX];
59 /* internal array init function */
60 static void initDirPathArray(void);
62 /* Additional macros for ease of use */
63 /* buf is expected to be atleast AFS_PATH_MAX bytes long */
64 #define AFSDIR_SERVER_DIRPATH(buf, dir) \
65 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, NULL)
67 #define AFSDIR_SERVER_FILEPATH(buf, dir, file) \
68 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, "/", file, NULL)
70 #define AFSDIR_CLIENT_DIRPATH(buf, dir) \
71 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, NULL)
73 #define AFSDIR_CLIENT_FILEPATH(buf, dir, file) \
74 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, "/", file, NULL)
77 /* initAFSDirPath() -- External users call this function to initialize
78 * the dirpath module and/or to determine the initialization status.
83 if (initFlag == 0) { /* not yet init'ed, so initialize */
84 #ifdef AFS_PTHREAD_ENV
85 pthread_once(&dirInit_once, initDirPathArray);
94 /* initDirPathArray() -- Initializes the afs dir paths for the
95 * server and client installations.
97 * For NT these are determined dynamically; for Unix they are static.
99 * NT NOTE: If a particular component (client/server) is not installed
100 * then we may not be able to initialize the paths to anything
101 * meaningful. In this case the paths are set to the local
102 * temp directory to avoid later reference to an uninitialized
103 * variable. The initStatus flag is set to indicate which
104 * paths (client/server) initialized properly for callers of
105 * initAFSDirPath() who would like to know this information.
108 initDirPathArray(void)
111 const char *clientPrefix = "";
112 const char *serverPrefix = "";
118 /* get the afs server software installation dir from the registry */
119 if (afssw_GetServerInstallDir(&buf)) {
120 /* failed; server not installed; use temp directory */
121 strcpy(ntServerInstallDirLong, gettmpdir());
123 strcpy(ntServerInstallDirLong, buf);
125 initStatus |= AFSDIR_SERVER_PATHS_OK;
127 FilepathNormalize(ntServerInstallDirLong);
129 GetShortPathName(ntServerInstallDirLong, ntServerInstallDirShort,
131 if (status == 0 || status > AFSDIR_PATH_MAX) {
132 /* can't convert path to short version; just use long version */
133 strcpy(ntServerInstallDirShort, ntServerInstallDirLong);
135 FilepathNormalize(ntServerInstallDirShort);
137 /* get the afs client configuration directory (/usr/vice/etc equivalent) */
138 if (afssw_GetClientInstallDir(&buf)) {
140 status = GetWindowsDirectory(ntClientConfigDirLong, AFSDIR_PATH_MAX);
141 if (status == 0 || status > AFSDIR_PATH_MAX) {
142 /* failed to get canonical Windows directory; use temp directory */
143 strcpy(ntClientConfigDirLong, gettmpdir());
145 initStatus |= AFSDIR_CLIENT_PATHS_OK;
148 strcpy(ntClientConfigDirLong, buf);
150 initStatus |= AFSDIR_CLIENT_PATHS_OK;
152 FilepathNormalize(ntClientConfigDirLong);
155 GetShortPathName(ntClientConfigDirLong, ntClientConfigDirShort,
157 if (status == 0 || status > AFSDIR_PATH_MAX) {
158 /* can't convert path to short version; just use long version */
159 strcpy(ntClientConfigDirShort, ntClientConfigDirLong);
161 FilepathNormalize(ntClientConfigDirShort);
162 clientPrefix = ntClientConfigDirShort;
164 /* setup the root server directory path (/usr/afs equivalent) */
165 strcpy(afsSrvDirPath, ntServerInstallDirShort);
166 strcat(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
168 /* there is no root client directory path (/usr/vice equivalent) */
169 afsClntDirPath[0] = '\0';
171 /* setup top level dirpath (/usr equivalent); valid for server ONLY */
172 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], ntServerInstallDirShort);
173 serverPrefix = ntServerInstallDirShort;
174 strcat(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
176 #else /* AFS_NT40_ENV */
177 /* setup the root server directory path */
178 strcpy(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
180 /* setup the root client directory path */
181 #ifdef AFS_DARWIN_ENV
182 if (access(AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH, F_OK) == 0)
183 strcpy(afsClntDirPath, AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH);
186 strcpy(afsClntDirPath, AFSDIR_CANONICAL_CLIENT_VICE_DIRPATH);
188 /* setup top level dirpath; valid for both server and client */
189 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
191 initStatus |= (AFSDIR_CLIENT_PATHS_OK | AFSDIR_SERVER_PATHS_OK);
192 #endif /* AFS_NT40_ENV */
194 /* now initialize various dir and file paths exported by dirpath module */
196 /* server dir paths */
197 strcpy(dirPathArray[AFSDIR_SERVER_AFS_DIRPATH_ID], afsSrvDirPath);
199 pathp = dirPathArray[AFSDIR_SERVER_ETC_DIRPATH_ID];
200 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_ETC_DIR);
202 pathp = dirPathArray[AFSDIR_SERVER_BIN_DIRPATH_ID];
203 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_BIN_DIR);
205 pathp = dirPathArray[AFSDIR_SERVER_CORES_DIRPATH_ID];
206 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_CORES_DIR);
208 pathp = dirPathArray[AFSDIR_SERVER_DB_DIRPATH_ID];
209 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_DB_DIR);
211 pathp = dirPathArray[AFSDIR_SERVER_LOGS_DIRPATH_ID];
212 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOGS_DIR);
214 pathp = dirPathArray[AFSDIR_SERVER_LOCAL_DIRPATH_ID];
215 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOCAL_DIR);
217 pathp = dirPathArray[AFSDIR_SERVER_BACKUP_DIRPATH_ID];
218 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BACKUP_DIR);
220 pathp = dirPathArray[AFSDIR_SERVER_MIGRATE_DIRPATH_ID];
221 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_MIGR_DIR);
223 pathp = dirPathArray[AFSDIR_SERVER_BIN_FILE_DIRPATH_ID];
224 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BIN_FILE_DIR);
226 /* client dir path */
228 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID],
229 "/NoUsrViceDirectoryOnWindows");
230 strcpy(dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID],
231 ntClientConfigDirShort);
233 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID], afsClntDirPath);
235 pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID];
236 #ifdef AFS_DARWIN_ENV
237 if (access(AFSDIR_ALTERNATE_CLIENT_ETC_DIR, F_OK) == 0)
238 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_ETC_DIR);
241 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR);
242 #endif /* AFS_NT40_ENV */
244 /* server file paths */
245 pathp = dirPathArray[AFSDIR_SERVER_THISCELL_FILEPATH_ID];
246 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
247 AFSDIR_THISCELL_FILE);
249 pathp = dirPathArray[AFSDIR_SERVER_CELLSERVDB_FILEPATH_ID];
250 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
251 AFSDIR_CELLSERVDB_FILE);
253 pathp = dirPathArray[AFSDIR_SERVER_NOAUTH_FILEPATH_ID];
254 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NOAUTH_FILE);
256 pathp = dirPathArray[AFSDIR_SERVER_BUDBLOG_FILEPATH_ID];
257 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BUDBLOG_FILE);
259 pathp = dirPathArray[AFSDIR_SERVER_TAPECONFIG_FILEPATH_ID];
260 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BACKUP_DIR, AFSDIR_TAPECONFIG_FILE);
262 pathp = dirPathArray[AFSDIR_SERVER_KALOGDB_FILEPATH_ID];
263 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOGDB_FILE);
265 pathp = dirPathArray[AFSDIR_SERVER_KALOG_FILEPATH_ID];
266 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOG_FILE);
268 pathp = dirPathArray[AFSDIR_SERVER_KADB_FILEPATH_ID];
269 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_KADB_FILE);
271 pathp = dirPathArray[AFSDIR_SERVER_NTPD_FILEPATH_ID];
272 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR, AFSDIR_NTPD_FILE);
274 pathp = dirPathArray[AFSDIR_SERVER_PRDB_FILEPATH_ID];
275 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_PRDB_FILE);
277 pathp = dirPathArray[AFSDIR_SERVER_PTLOG_FILEPATH_ID];
278 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_PTLOG_FILE);
280 pathp = dirPathArray[AFSDIR_SERVER_KCONF_FILEPATH_ID];
281 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KCONF_FILE);
283 pathp = dirPathArray[AFSDIR_SERVER_VLDB_FILEPATH_ID];
284 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_VLDB_FILE);
286 pathp = dirPathArray[AFSDIR_SERVER_VLOG_FILEPATH_ID];
287 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VLOG_FILE);
289 pathp = dirPathArray[AFSDIR_SERVER_CORELOG_FILEPATH_ID];
290 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_CORE_FILE);
292 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
293 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
295 pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
296 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
297 AFSDIR_SALVAGER_FILE);
299 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
300 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
302 pathp = dirPathArray[AFSDIR_SERVER_KEY_FILEPATH_ID];
303 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KEY_FILE);
305 pathp = dirPathArray[AFSDIR_SERVER_ULIST_FILEPATH_ID];
306 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ULIST_FILE);
308 pathp = dirPathArray[AFSDIR_SERVER_BOZCONF_FILEPATH_ID];
309 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZCONF_FILE);
311 pathp = dirPathArray[AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID];
312 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR,
313 AFSDIR_BOZCONFNEW_FILE);
315 pathp = dirPathArray[AFSDIR_SERVER_BOZLOG_FILEPATH_ID];
316 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BOZLOG_FILE);
318 pathp = dirPathArray[AFSDIR_SERVER_BOZINIT_FILEPATH_ID];
319 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZINIT_FILE);
321 pathp = dirPathArray[AFSDIR_SERVER_BOSVR_FILEPATH_ID];
322 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSSERVER_DIR, AFSDIR_BOSVR_FILE);
324 pathp = dirPathArray[AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID];
325 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VOLSERLOG_FILE);
327 pathp = dirPathArray[AFSDIR_SERVER_ROOTVOL_FILEPATH_ID];
328 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ROOTVOL_FILE);
330 pathp = dirPathArray[AFSDIR_SERVER_HOSTDUMP_FILEPATH_ID];
331 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_HOSTDUMP_FILE);
333 pathp = dirPathArray[AFSDIR_SERVER_CLNTDUMP_FILEPATH_ID];
334 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CLNTDUMP_FILE);
336 pathp = dirPathArray[AFSDIR_SERVER_CBKDUMP_FILEPATH_ID];
337 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CBKDUMP_FILE);
339 pathp = dirPathArray[AFSDIR_SERVER_OLDSYSID_FILEPATH_ID];
340 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_OLDSYSID_FILE);
342 pathp = dirPathArray[AFSDIR_SERVER_SYSID_FILEPATH_ID];
343 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SYSID_FILE);
345 pathp = dirPathArray[AFSDIR_SERVER_FILELOG_FILEPATH_ID];
346 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_FILELOG_FILE);
348 pathp = dirPathArray[AFSDIR_SERVER_AUDIT_FILEPATH_ID];
349 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_AUDIT_FILE);
351 pathp = dirPathArray[AFSDIR_SERVER_NETINFO_FILEPATH_ID];
352 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETINFO_FILE);
354 pathp = dirPathArray[AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID];
355 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETRESTRICT_FILE);
357 pathp = dirPathArray[AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH_ID];
358 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
359 AFSDIR_WEIGHTINGCONST_FILE);
361 pathp = dirPathArray[AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID];
362 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
363 AFSDIR_THRESHOLDCONST_FILE);
365 pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
366 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
369 /* client file paths */
371 strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
372 "/NoUsrViceEtcThisCellFileOnWindows");
373 sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
374 ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
375 strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
376 "/NoCellAliasOnWindows");
378 pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
379 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
380 AFSDIR_THISCELL_FILE);
382 pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID];
383 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
384 AFSDIR_CELLSERVDB_FILE);
386 pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID];
387 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
388 AFSDIR_CELLALIAS_FILE);
389 #endif /* AFS_NT40_ENV */
391 pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];
392 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_NETINFO_FILE);
394 pathp = dirPathArray[AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID];
395 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
396 AFSDIR_NETRESTRICT_FILE);
398 initFlag = 1; /* finished dirpath initialization */
402 /* getDirPath - returns a const char pointer to the requested string
403 * from the internal path array.
404 * string_id - index into the path array
407 getDirPath(afsdir_id_t string_id)
409 /* check if the array has been initialized */
410 if (initFlag == 0) { /* no it's not, so initialize */
411 #ifdef AFS_PTHREAD_ENV
412 pthread_once(&dirInit_once, initDirPathArray);
417 return (const char *)dirPathArray[string_id];
421 * LocalizePathHead() -- Make path relative to local part
423 * ConstructLocalPath takes a path and a directory that path should
424 * be considered relative to. This function checks the given path
425 * for a prefix that represents a canonical path. If such a prefix
426 * is found, the path is adjusted to remove the prefix and the path
427 * is considered relative to the local version of that path.
430 /* The following array maps cannonical parts to local parts. It
431 * might seem reasonable to simply construct an array in parallel to
432 * dirpatharray but it turns out you don't want translations for all
436 struct canonmapping {
437 const char *canonical;
440 static struct canonmapping CanonicalTranslations[] = {
441 {AFSDIR_CANONICAL_SERVER_ETC_DIRPATH, AFSDIR_SERVER_ETC_DIR},
442 {AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH, AFSDIR_LOGS_DIR},
443 {AFSDIR_CANONICAL_SERVER_LOCAL_DIRPATH, AFSDIR_LOCAL_DIR},
444 {AFSDIR_CANONICAL_SERVER_BIN_DIRPATH, AFSDIR_SERVER_BIN_DIR},
449 LocalizePathHead(const char **path, const char **relativeTo)
451 struct canonmapping *current;
452 for (current = CanonicalTranslations; current->local != NULL; current++) {
453 size_t canonlength = strlen(current->canonical);
454 if (strncmp(*path, current->canonical, canonlength) == 0) {
455 (*path) += canonlength;
458 *relativeTo = current->local;
466 /* NT version of ConstructLocalPath() */
469 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
470 * specified local path. Upon successful completion, *fullPathBufp is
471 * set to an allocated buffer containing the fully specified local path
472 * constructed from the cpath argument.
474 * On NT, path construction proceeds as follows:
475 * 1) If cpath is fully qualified (i.e., starts with 'X:/') then the
476 * path returned is equivalent to cpath.
477 * 2) If cpath begins with a drive letter but is not fully qualified,
478 * i.e., it is drive relative, then the function fails with EINVAL.
479 * 3) If cpath begins with '/' (or '\') then the path returned is the
480 * concatenation AFS-server-install-dir + cpath after translating for localization.
481 * 4) Otherwise the path returned is the concatenation
482 * AFS-server-install-dir + relativeTo + cpath.
484 * Leading whitespace in cpath is ignored; the constructed path is
485 * normalized (FilepathNormalize()).
487 * RETURN CODES: 0 if successful; errno code otherwise.
490 ConstructLocalPath(const char *cpath, const char *relativeTo,
494 char *newPath = NULL;
496 if (initFlag == 0) { /* dirpath module not yet initialized */
497 #ifdef AFS_PTHREAD_ENV
498 pthread_once(&dirInit_once, initDirPathArray);
504 *fullPathBufp = NULL;
506 while (isspace(*cpath)) {
510 LocalizePathHead(&cpath, &relativeTo);
511 if ((((*cpath >= 'a') && (*cpath <= 'z'))
512 || ((*cpath >= 'A') && (*cpath <= 'Z'))) && (*(cpath + 1) == ':')) {
514 /* cpath has a leading drive letter */
515 if ((*(cpath + 2) != '/') && (*(cpath + 2) != '\\')) {
516 /* drive letter relative path; this is not allowed */
519 /* fully qualified path; just make a copy */
520 newPath = (char *)malloc(strlen(cpath) + 1);
524 (void)strcpy(newPath, cpath);
529 /* cpath has NO leading drive letter; make relative to install dir */
530 size_t pathSize = strlen(ntServerInstallDirShort) + 2;
532 if ((*cpath == '/') || (*cpath == '\\')) {
533 /* construct path relative to install directory only */
534 pathSize += strlen(cpath);
536 newPath = (char *)malloc(pathSize);
540 sprintf(newPath, "%s/%s", ntServerInstallDirShort, cpath);
543 /* construct path relative to 'relativeTo' (and install dir) */
544 pathSize += strlen(relativeTo) + 1 + strlen(cpath);
546 newPath = (char *)malloc(pathSize);
550 sprintf(newPath, "%s/%s/%s", ntServerInstallDirShort,
557 FilepathNormalize(newPath);
559 /* return buffer containing fully specified path */
560 *fullPathBufp = newPath;
567 /* Unix version of ConstructLocalPath() */
570 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
571 * specified local path. Upon successful completion, *fullPathBufp is
572 * set to an allocated buffer containing the fully specified local path
573 * constructed from the cpath argument.
575 * On Unix, path construction proceeds as follows:
576 * 1) If cpath begins with '/' then the path returned is equivalent
578 * 2) Otherwise the path returned is the concatenation
579 * relativeTo + cpath.
581 * Leading whitespace in cpath is ignored; the constructed path is
582 * normalized (FilepathNormalize()).
584 * RETURN CODES: 0 if successful; errno code otherwise.
587 ConstructLocalPath(const char *cpath, const char *relativeTo,
591 char *newPath = NULL;
593 if (initFlag == 0) { /* dirpath module not yet initialized */
594 #ifdef AFS_PTHREAD_ENV
595 pthread_once(&dirInit_once, initDirPathArray);
601 *fullPathBufp = NULL;
603 while (isspace(*cpath)) {
607 LocalizePathHead(&cpath, &relativeTo);
609 newPath = (char *)malloc(strlen(cpath) + 1);
613 strcpy(newPath, cpath);
616 newPath = (char *)malloc(strlen(relativeTo) + 1 + strlen(cpath) + 1);
620 sprintf(newPath, "%s/%s", relativeTo, cpath);
625 FilepathNormalize(newPath);
627 /* return buffer containing fully specified path */
628 *fullPathBufp = newPath;
633 #endif /* AFS_NT40_ENV */
637 * ConstructLocalBinPath() -- A convenience wrapper for ConstructLocalPath()
638 * that specifies the canonical AFS server binary directory as the relative
642 ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
644 return ConstructLocalPath(cpath, AFSDIR_SERVER_BIN_DIRPATH,
650 * ConstructLocalLogPath() -- A convenience wrapper for ConstructLocalPath()
651 * that specifies the canonical AFS server logs directory as the relative
655 ConstructLocalLogPath(const char *cpath, char **fullPathBufp)
657 return ConstructLocalPath(cpath, AFSDIR_SERVER_LOGS_DIRPATH,