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>
19 #include "afs_assert.h"
23 #ifdef AFS_PTHREAD_ENV
25 static pthread_once_t dirInit_once = PTHREAD_ONCE_INIT;
29 #include <WINNT\afssw.h>
33 /* static storage for path strings */
34 static char dirPathArray[AFSDIR_PATHSTRING_MAX][AFSDIR_PATH_MAX];
36 /* indicate if and how the dirpath module initialized. */
37 static int initFlag = 0;
38 static unsigned int initStatus = 0;
41 /* storage for dynamically-determined install dir (NT only; long and short) */
43 static char ntServerInstallDirLong[AFSDIR_PATH_MAX];
44 static char ntServerInstallDirShort[AFSDIR_PATH_MAX];
45 static char ntClientConfigDirLong[AFSDIR_PATH_MAX];
46 static char ntClientConfigDirShort[AFSDIR_PATH_MAX];
49 /* storage for local afs server/client paths (top-level) */
50 static char afsSrvDirPath[AFSDIR_PATH_MAX];
51 static char afsClntDirPath[AFSDIR_PATH_MAX];
53 /* internal array init function */
54 static void initDirPathArray(void);
56 /* Additional macros for ease of use */
57 /* buf is expected to be atleast AFS_PATH_MAX bytes long */
58 #define AFSDIR_SERVER_DIRPATH(buf, dir) \
59 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, NULL)
61 #define AFSDIR_SERVER_FILEPATH(buf, dir, file) \
62 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, "/", file, NULL)
64 #define AFSDIR_CLIENT_DIRPATH(buf, dir) \
65 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, NULL)
67 #define AFSDIR_CLIENT_FILEPATH(buf, dir, file) \
68 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, "/", file, NULL)
71 /* initAFSDirPath() -- External users call this function to initialize
72 * the dirpath module and/or to determine the initialization status.
77 if (initFlag == 0) { /* not yet init'ed, so initialize */
78 #ifdef AFS_PTHREAD_ENV
79 pthread_once(&dirInit_once, initDirPathArray);
88 /* initDirPathArray() -- Initializes the afs dir paths for the
89 * server and client installations.
91 * For NT these are determined dynamically; for Unix they are static.
93 * NT NOTE: If a particular component (client/server) is not installed
94 * then we may not be able to initialize the paths to anything
95 * meaningful. In this case the paths are set to the local
96 * temp directory to avoid later reference to an uninitialized
97 * variable. The initStatus flag is set to indicate which
98 * paths (client/server) initialized properly for callers of
99 * initAFSDirPath() who would like to know this information.
102 initDirPathArray(void)
105 const char *clientPrefix = "";
106 const char *serverPrefix = "";
112 /* get the afs server software installation dir from the registry */
113 if (afssw_GetServerInstallDir(&buf)) {
114 /* failed; server not installed; use temp directory */
115 strcpy(ntServerInstallDirLong, gettmpdir());
117 strcpy(ntServerInstallDirLong, buf);
119 initStatus |= AFSDIR_SERVER_PATHS_OK;
121 FilepathNormalize(ntServerInstallDirLong);
123 GetShortPathName(ntServerInstallDirLong, ntServerInstallDirShort,
125 if (status == 0 || status > AFSDIR_PATH_MAX) {
126 /* can't convert path to short version; just use long version */
127 strcpy(ntServerInstallDirShort, ntServerInstallDirLong);
129 FilepathNormalize(ntServerInstallDirShort);
131 /* get the afs client configuration directory (/usr/vice/etc equivalent) */
132 if (afssw_GetClientCellServDBDir(&buf)) {
134 status = GetWindowsDirectory(ntClientConfigDirLong, AFSDIR_PATH_MAX);
135 if (status == 0 || status > AFSDIR_PATH_MAX) {
136 /* failed to get canonical Windows directory; use temp directory */
137 strcpy(ntClientConfigDirLong, gettmpdir());
139 initStatus |= AFSDIR_CLIENT_PATHS_OK;
142 strcpy(ntClientConfigDirLong, buf);
144 initStatus |= AFSDIR_CLIENT_PATHS_OK;
146 FilepathNormalize(ntClientConfigDirLong);
149 GetShortPathName(ntClientConfigDirLong, ntClientConfigDirShort,
151 if (status == 0 || status > AFSDIR_PATH_MAX) {
152 /* can't convert path to short version; just use long version */
153 strcpy(ntClientConfigDirShort, ntClientConfigDirLong);
155 FilepathNormalize(ntClientConfigDirShort);
156 clientPrefix = ntClientConfigDirShort;
158 /* setup the root server directory path (/usr/afs equivalent) */
159 strcpy(afsSrvDirPath, ntServerInstallDirShort);
160 strcat(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
162 /* there is no root client directory path (/usr/vice equivalent) */
163 afsClntDirPath[0] = '\0';
165 /* setup top level dirpath (/usr equivalent); valid for server ONLY */
166 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], ntServerInstallDirShort);
167 serverPrefix = ntServerInstallDirShort;
168 strcat(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
170 #else /* AFS_NT40_ENV */
171 /* setup the root server directory path */
172 strcpy(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
174 /* setup the root client directory path */
175 #ifdef AFS_DARWIN_ENV
176 if (access(AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH, F_OK) == 0)
177 strcpy(afsClntDirPath, AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH);
180 strcpy(afsClntDirPath, AFSDIR_CANONICAL_CLIENT_VICE_DIRPATH);
182 /* setup top level dirpath; valid for both server and client */
183 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
185 initStatus |= (AFSDIR_CLIENT_PATHS_OK | AFSDIR_SERVER_PATHS_OK);
186 #endif /* AFS_NT40_ENV */
188 /* now initialize various dir and file paths exported by dirpath module */
190 /* server dir paths */
191 strcpy(dirPathArray[AFSDIR_SERVER_AFS_DIRPATH_ID], afsSrvDirPath);
193 pathp = dirPathArray[AFSDIR_SERVER_ETC_DIRPATH_ID];
194 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_ETC_DIR);
196 pathp = dirPathArray[AFSDIR_SERVER_BIN_DIRPATH_ID];
197 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_BIN_DIR);
199 pathp = dirPathArray[AFSDIR_SERVER_CORES_DIRPATH_ID];
200 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_CORES_DIR);
202 pathp = dirPathArray[AFSDIR_SERVER_DB_DIRPATH_ID];
203 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_DB_DIR);
205 pathp = dirPathArray[AFSDIR_SERVER_LOGS_DIRPATH_ID];
206 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOGS_DIR);
208 pathp = dirPathArray[AFSDIR_SERVER_LOCAL_DIRPATH_ID];
209 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOCAL_DIR);
211 pathp = dirPathArray[AFSDIR_SERVER_BACKUP_DIRPATH_ID];
212 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BACKUP_DIR);
214 pathp = dirPathArray[AFSDIR_SERVER_MIGRATE_DIRPATH_ID];
215 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_MIGR_DIR);
217 pathp = dirPathArray[AFSDIR_SERVER_BIN_FILE_DIRPATH_ID];
218 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BIN_FILE_DIR);
220 /* client dir path */
222 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID],
223 "/NoUsrViceDirectoryOnWindows");
224 strcpy(dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID],
225 ntClientConfigDirShort);
227 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID], afsClntDirPath);
229 pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID];
230 #ifdef AFS_DARWIN_ENV
231 if (access(AFSDIR_ALTERNATE_CLIENT_ETC_DIR, F_OK) == 0)
232 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_ETC_DIR);
235 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR);
236 #endif /* AFS_NT40_ENV */
239 pathp = dirPathArray[AFSDIR_CLIENT_DATA_DIRPATH_ID];
240 #ifdef AFS_DARWIN_ENV
241 if (access(AFSDIR_ALTERNATE_CLIENT_DATA_DIR, F_OK) == 0)
242 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_DATA_DIR);
245 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_DATA_DIR);
248 /* server file paths */
249 pathp = dirPathArray[AFSDIR_SERVER_THISCELL_FILEPATH_ID];
250 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
251 AFSDIR_THISCELL_FILE);
253 pathp = dirPathArray[AFSDIR_SERVER_CELLSERVDB_FILEPATH_ID];
254 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
255 AFSDIR_CELLSERVDB_FILE);
257 pathp = dirPathArray[AFSDIR_SERVER_NOAUTH_FILEPATH_ID];
258 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NOAUTH_FILE);
260 pathp = dirPathArray[AFSDIR_SERVER_BUDBLOG_FILEPATH_ID];
261 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BUDBLOG_FILE);
263 pathp = dirPathArray[AFSDIR_SERVER_TAPECONFIG_FILEPATH_ID];
264 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BACKUP_DIR, AFSDIR_TAPECONFIG_FILE);
266 pathp = dirPathArray[AFSDIR_SERVER_KALOGDB_FILEPATH_ID];
267 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOGDB_FILE);
269 pathp = dirPathArray[AFSDIR_SERVER_KALOG_FILEPATH_ID];
270 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOG_FILE);
272 pathp = dirPathArray[AFSDIR_SERVER_KADB_FILEPATH_ID];
273 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_KADB_FILE);
275 pathp = dirPathArray[AFSDIR_SERVER_NTPD_FILEPATH_ID];
276 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR, AFSDIR_NTPD_FILE);
278 pathp = dirPathArray[AFSDIR_SERVER_PRDB_FILEPATH_ID];
279 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_PRDB_FILE);
281 pathp = dirPathArray[AFSDIR_SERVER_PTLOG_FILEPATH_ID];
282 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_PTLOG_FILE);
284 pathp = dirPathArray[AFSDIR_SERVER_KCONF_FILEPATH_ID];
285 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KCONF_FILE);
287 pathp = dirPathArray[AFSDIR_SERVER_VLDB_FILEPATH_ID];
288 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_VLDB_FILE);
290 pathp = dirPathArray[AFSDIR_SERVER_VLOG_FILEPATH_ID];
291 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VLOG_FILE);
293 pathp = dirPathArray[AFSDIR_SERVER_CORELOG_FILEPATH_ID];
294 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_CORE_FILE);
296 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
297 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
299 pathp = dirPathArray[AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID];
300 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SALSRVLOG_FILE);
302 pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
303 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
304 AFSDIR_SALVAGER_FILE);
306 pathp = dirPathArray[AFSDIR_SERVER_SALSRV_FILEPATH_ID];
307 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
310 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
311 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
313 pathp = dirPathArray[AFSDIR_SERVER_KEY_FILEPATH_ID];
314 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KEY_FILE);
316 pathp = dirPathArray[AFSDIR_SERVER_ULIST_FILEPATH_ID];
317 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ULIST_FILE);
319 pathp = dirPathArray[AFSDIR_SERVER_BOZCONF_FILEPATH_ID];
320 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZCONF_FILE);
322 pathp = dirPathArray[AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID];
323 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR,
324 AFSDIR_BOZCONFNEW_FILE);
326 pathp = dirPathArray[AFSDIR_SERVER_BOZLOG_FILEPATH_ID];
327 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BOZLOG_FILE);
329 pathp = dirPathArray[AFSDIR_SERVER_BOZINIT_FILEPATH_ID];
330 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZINIT_FILE);
332 pathp = dirPathArray[AFSDIR_SERVER_BOSVR_FILEPATH_ID];
333 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSSERVER_DIR, AFSDIR_BOSVR_FILE);
335 pathp = dirPathArray[AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID];
336 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VOLSERLOG_FILE);
338 pathp = dirPathArray[AFSDIR_SERVER_ROOTVOL_FILEPATH_ID];
339 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ROOTVOL_FILE);
341 pathp = dirPathArray[AFSDIR_SERVER_HOSTDUMP_FILEPATH_ID];
342 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_HOSTDUMP_FILE);
344 pathp = dirPathArray[AFSDIR_SERVER_CLNTDUMP_FILEPATH_ID];
345 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CLNTDUMP_FILE);
347 pathp = dirPathArray[AFSDIR_SERVER_CBKDUMP_FILEPATH_ID];
348 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CBKDUMP_FILE);
350 pathp = dirPathArray[AFSDIR_SERVER_OLDSYSID_FILEPATH_ID];
351 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_OLDSYSID_FILE);
353 pathp = dirPathArray[AFSDIR_SERVER_SYSID_FILEPATH_ID];
354 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SYSID_FILE);
356 pathp = dirPathArray[AFSDIR_SERVER_FILELOG_FILEPATH_ID];
357 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_FILELOG_FILE);
359 pathp = dirPathArray[AFSDIR_SERVER_AUDIT_FILEPATH_ID];
360 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_AUDIT_FILE);
362 pathp = dirPathArray[AFSDIR_SERVER_NETINFO_FILEPATH_ID];
363 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETINFO_FILE);
365 pathp = dirPathArray[AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID];
366 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETRESTRICT_FILE);
368 pathp = dirPathArray[AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH_ID];
369 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
370 AFSDIR_WEIGHTINGCONST_FILE);
372 pathp = dirPathArray[AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID];
373 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
374 AFSDIR_THRESHOLDCONST_FILE);
376 pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
377 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
379 pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
380 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
382 pathp = dirPathArray[AFSDIR_SERVER_FSSTATE_FILEPATH_ID];
383 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_FSSTATE_FILE);
385 /* client file paths */
387 strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
388 "/NoUsrViceEtcThisCellFileOnWindows");
389 sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
390 ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
391 strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
392 "/NoCellAliasOnWindows");
394 pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
395 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
396 AFSDIR_THISCELL_FILE);
398 pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID];
399 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
400 AFSDIR_CELLSERVDB_FILE);
402 pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID];
403 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
404 AFSDIR_CELLALIAS_FILE);
405 #endif /* AFS_NT40_ENV */
407 pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];
408 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_NETINFO_FILE);
410 pathp = dirPathArray[AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID];
411 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
412 AFSDIR_NETRESTRICT_FILE);
414 initFlag = 1; /* finished dirpath initialization */
418 /* getDirPath - returns a const char pointer to the requested string
419 * from the internal path array.
420 * string_id - index into the path array
423 getDirPath(afsdir_id_t string_id)
425 /* check if the array has been initialized */
426 if (initFlag == 0) { /* no it's not, so initialize */
427 #ifdef AFS_PTHREAD_ENV
428 pthread_once(&dirInit_once, initDirPathArray);
433 return (const char *)dirPathArray[string_id];
437 * LocalizePathHead() -- Make path relative to local part
439 * ConstructLocalPath takes a path and a directory that path should
440 * be considered relative to. There are two possible cases:
442 * The path is an absolute path. In this case, the relative path
443 * is ignored. We check the path for a prefix that represents a
444 * canonical path, and if one is found, we adjust the path to remove
445 * the prefix and adjust the directory to which it should be
446 * considered relative to be the local version of that canonical path.
448 * The path is a relative path. In this case, we check to see if the
449 * directory to which it is relative represents a canonical path, and
450 * if so, we adjust that directory to be the local version of that
451 * canonical path. The relative path itself is left unchanged.
454 /* The following array maps cannonical parts to local parts. It
455 * might seem reasonable to simply construct an array in parallel to
456 * dirpatharray but it turns out you don't want translations for all
460 struct canonmapping {
461 const char *canonical;
464 static struct canonmapping CanonicalTranslations[] = {
465 {AFSDIR_CANONICAL_SERVER_ETC_DIRPATH, AFSDIR_SERVER_ETC_DIR},
466 {AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH, AFSDIR_LOGS_DIR},
467 {AFSDIR_CANONICAL_SERVER_LOCAL_DIRPATH, AFSDIR_LOCAL_DIR},
468 {AFSDIR_CANONICAL_SERVER_BIN_DIRPATH, AFSDIR_SERVER_BIN_DIR},
473 LocalizePathHead(const char **path, const char **relativeTo)
475 struct canonmapping *map;
478 for (map = CanonicalTranslations; map->local != NULL; map++) {
479 int canonlength = strlen(map->canonical);
480 if (strncmp(*path, map->canonical, canonlength) == 0) {
481 (*path) += canonlength;
484 *relativeTo = map->local;
489 for (map = CanonicalTranslations; map->local != NULL; map++) {
490 if (strcmp(*relativeTo, map->canonical) == 0) {
491 *relativeTo = map->local;
500 /* NT version of ConstructLocalPath() */
503 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
504 * specified local path. Upon successful completion, *fullPathBufp is
505 * set to an allocated buffer containing the fully specified local path
506 * constructed from the cpath argument.
508 * On NT, path construction proceeds as follows:
509 * 1) If cpath is fully qualified (i.e., starts with 'X:/') then the
510 * path returned is equivalent to cpath.
511 * 2) If cpath begins with a drive letter but is not fully qualified,
512 * i.e., it is drive relative, then the function fails with EINVAL.
513 * 3) If cpath begins with '/' (or '\') then the path returned is the
514 * concatenation AFS-server-install-dir + cpath after translating for localization.
515 * 4) Otherwise the path returned is the concatenation
516 * AFS-server-install-dir + relativeTo + cpath.
518 * Leading whitespace in cpath is ignored; the constructed path is
519 * normalized (FilepathNormalize()).
521 * RETURN CODES: 0 if successful; errno code otherwise.
524 ConstructLocalPath(const char *cpath, const char *relativeTo,
528 char *newPath = NULL;
530 if (initFlag == 0) { /* dirpath module not yet initialized */
531 #ifdef AFS_PTHREAD_ENV
532 pthread_once(&dirInit_once, initDirPathArray);
538 *fullPathBufp = NULL;
540 while (isspace(*cpath)) {
544 LocalizePathHead(&cpath, &relativeTo);
545 if ((((*cpath >= 'a') && (*cpath <= 'z'))
546 || ((*cpath >= 'A') && (*cpath <= 'Z'))) && (*(cpath + 1) == ':')) {
548 /* cpath has a leading drive letter */
549 if ((*(cpath + 2) != '/') && (*(cpath + 2) != '\\')) {
550 /* drive letter relative path; this is not allowed */
553 /* fully qualified path; just make a copy */
554 newPath = (char *)malloc(strlen(cpath) + 1);
558 (void)strcpy(newPath, cpath);
563 /* cpath has NO leading drive letter; make relative to install dir */
564 size_t pathSize = strlen(ntServerInstallDirShort) + 2;
566 if ((*cpath == '/') || (*cpath == '\\')) {
567 /* construct path relative to install directory only */
568 pathSize += strlen(cpath);
570 newPath = (char *)malloc(pathSize);
574 sprintf(newPath, "%s/%s", ntServerInstallDirShort, cpath);
577 /* construct path relative to 'relativeTo' (and install dir) */
578 pathSize += strlen(relativeTo) + 1 + strlen(cpath);
580 newPath = (char *)malloc(pathSize);
584 sprintf(newPath, "%s/%s/%s", ntServerInstallDirShort,
591 FilepathNormalize(newPath);
593 /* return buffer containing fully specified path */
594 *fullPathBufp = newPath;
601 /* Unix version of ConstructLocalPath() */
604 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
605 * specified local path. Upon successful completion, *fullPathBufp is
606 * set to an allocated buffer containing the fully specified local path
607 * constructed from the cpath argument.
609 * On Unix, path construction proceeds as follows:
610 * 1) If cpath begins with '/' then the path returned is equivalent
612 * 2) Otherwise the path returned is the concatenation
613 * relativeTo + cpath.
615 * Leading whitespace in cpath is ignored; the constructed path is
616 * normalized (FilepathNormalize()).
618 * RETURN CODES: 0 if successful; errno code otherwise.
621 ConstructLocalPath(const char *cpath, const char *relativeTo,
625 char *newPath = NULL;
627 if (initFlag == 0) { /* dirpath module not yet initialized */
628 #ifdef AFS_PTHREAD_ENV
629 pthread_once(&dirInit_once, initDirPathArray);
635 *fullPathBufp = NULL;
637 while (isspace(*cpath)) {
641 LocalizePathHead(&cpath, &relativeTo);
643 newPath = (char *)malloc(strlen(cpath) + 1);
647 strcpy(newPath, cpath);
650 newPath = (char *)malloc(strlen(relativeTo) + 1 + strlen(cpath) + 1);
654 sprintf(newPath, "%s/%s", relativeTo, cpath);
659 FilepathNormalize(newPath);
661 /* return buffer containing fully specified path */
662 *fullPathBufp = newPath;
667 #endif /* AFS_NT40_ENV */
671 * ConstructLocalBinPath() -- A convenience wrapper for ConstructLocalPath()
672 * that specifies the canonical AFS server binary directory as the relative
676 ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
678 return ConstructLocalPath(cpath, AFSDIR_SERVER_BIN_DIRPATH,
684 * ConstructLocalLogPath() -- A convenience wrapper for ConstructLocalPath()
685 * that specifies the canonical AFS server logs directory as the relative
689 ConstructLocalLogPath(const char *cpath, char **fullPathBufp)
691 return ConstructLocalPath(cpath, AFSDIR_SERVER_LOGS_DIRPATH,