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>
25 #ifdef AFS_PTHREAD_ENV
27 static pthread_once_t dirInit_once = PTHREAD_ONCE_INIT;
31 #include <WINNT\afssw.h>
35 /* static storage for path strings */
36 static char dirPathArray[AFSDIR_PATHSTRING_MAX][AFSDIR_PATH_MAX];
38 /* indicate if and how the dirpath module initialized. */
39 static int initFlag = 0;
40 static unsigned int initStatus = 0;
43 /* storage for dynamically-determined install dir (NT only; long and short) */
45 static char ntServerInstallDirLong[AFSDIR_PATH_MAX];
46 static char ntServerInstallDirShort[AFSDIR_PATH_MAX];
47 static char ntClientConfigDirLong[AFSDIR_PATH_MAX];
48 static char ntClientConfigDirShort[AFSDIR_PATH_MAX];
51 /* storage for local afs server/client paths (top-level) */
52 static char afsSrvDirPath[AFSDIR_PATH_MAX];
53 static char afsClntDirPath[AFSDIR_PATH_MAX];
55 /* internal array init function */
56 static void initDirPathArray(void);
58 /* Additional macros for ease of use */
59 /* buf is expected to be atleast AFS_PATH_MAX bytes long */
60 #define AFSDIR_SERVER_DIRPATH(buf, dir) \
61 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, NULL)
63 #define AFSDIR_SERVER_FILEPATH(buf, dir, file) \
64 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, "/", file, NULL)
66 #define AFSDIR_CLIENT_DIRPATH(buf, dir) \
67 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, NULL)
69 #define AFSDIR_CLIENT_FILEPATH(buf, dir, file) \
70 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, "/", file, NULL)
73 /* initAFSDirPath() -- External users call this function to initialize
74 * the dirpath module and/or to determine the initialization status.
79 if (initFlag == 0) { /* not yet init'ed, so initialize */
80 #ifdef AFS_PTHREAD_ENV
81 pthread_once(&dirInit_once, initDirPathArray);
90 /* initDirPathArray() -- Initializes the afs dir paths for the
91 * server and client installations.
93 * For NT these are determined dynamically; for Unix they are static.
95 * NT NOTE: If a particular component (client/server) is not installed
96 * then we may not be able to initialize the paths to anything
97 * meaningful. In this case the paths are set to the local
98 * temp directory to avoid later reference to an uninitialized
99 * variable. The initStatus flag is set to indicate which
100 * paths (client/server) initialized properly for callers of
101 * initAFSDirPath() who would like to know this information.
104 initDirPathArray(void)
107 const char *clientPrefix = "";
108 const char *serverPrefix = "";
114 /* get the afs server software installation dir from the registry */
115 if (afssw_GetServerInstallDir(&buf)) {
116 /* failed; server not installed; use temp directory */
117 strcpy(ntServerInstallDirLong, gettmpdir());
119 strcpy(ntServerInstallDirLong, buf);
121 initStatus |= AFSDIR_SERVER_PATHS_OK;
123 FilepathNormalize(ntServerInstallDirLong);
125 GetShortPathName(ntServerInstallDirLong, ntServerInstallDirShort,
127 if (status == 0 || status > AFSDIR_PATH_MAX) {
128 /* can't convert path to short version; just use long version */
129 strcpy(ntServerInstallDirShort, ntServerInstallDirLong);
131 FilepathNormalize(ntServerInstallDirShort);
133 /* get the afs client configuration directory (/usr/vice/etc equivalent) */
134 if (afssw_GetClientCellServDBDir(&buf)) {
136 status = GetWindowsDirectory(ntClientConfigDirLong, AFSDIR_PATH_MAX);
137 if (status == 0 || status > AFSDIR_PATH_MAX) {
138 /* failed to get canonical Windows directory; use temp directory */
139 strcpy(ntClientConfigDirLong, gettmpdir());
141 initStatus |= AFSDIR_CLIENT_PATHS_OK;
144 strcpy(ntClientConfigDirLong, buf);
146 initStatus |= AFSDIR_CLIENT_PATHS_OK;
148 FilepathNormalize(ntClientConfigDirLong);
151 GetShortPathName(ntClientConfigDirLong, ntClientConfigDirShort,
153 if (status == 0 || status > AFSDIR_PATH_MAX) {
154 /* can't convert path to short version; just use long version */
155 strcpy(ntClientConfigDirShort, ntClientConfigDirLong);
157 FilepathNormalize(ntClientConfigDirShort);
158 clientPrefix = ntClientConfigDirShort;
160 /* setup the root server directory path (/usr/afs equivalent) */
161 strcpy(afsSrvDirPath, ntServerInstallDirShort);
162 strcat(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
164 /* there is no root client directory path (/usr/vice equivalent) */
165 afsClntDirPath[0] = '\0';
167 /* setup top level dirpath (/usr equivalent); valid for server ONLY */
168 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], ntServerInstallDirShort);
169 serverPrefix = ntServerInstallDirShort;
170 strcat(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
172 #else /* AFS_NT40_ENV */
173 /* setup the root server directory path */
174 strcpy(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
176 /* setup the root client directory path */
177 #ifdef AFS_DARWIN_ENV
178 if (access(AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH, F_OK) == 0)
179 strcpy(afsClntDirPath, AFSDIR_ALTERNATE_CLIENT_VICE_DIRPATH);
182 strcpy(afsClntDirPath, AFSDIR_CANONICAL_CLIENT_VICE_DIRPATH);
184 /* setup top level dirpath; valid for both server and client */
185 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
187 initStatus |= (AFSDIR_CLIENT_PATHS_OK | AFSDIR_SERVER_PATHS_OK);
188 #endif /* AFS_NT40_ENV */
190 /* now initialize various dir and file paths exported by dirpath module */
192 /* server dir paths */
193 strcpy(dirPathArray[AFSDIR_SERVER_AFS_DIRPATH_ID], afsSrvDirPath);
195 pathp = dirPathArray[AFSDIR_SERVER_ETC_DIRPATH_ID];
196 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_ETC_DIR);
198 pathp = dirPathArray[AFSDIR_SERVER_BIN_DIRPATH_ID];
199 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_BIN_DIR);
201 pathp = dirPathArray[AFSDIR_SERVER_CORES_DIRPATH_ID];
202 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_CORES_DIR);
204 pathp = dirPathArray[AFSDIR_SERVER_DB_DIRPATH_ID];
205 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_DB_DIR);
207 pathp = dirPathArray[AFSDIR_SERVER_LOGS_DIRPATH_ID];
208 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOGS_DIR);
210 pathp = dirPathArray[AFSDIR_SERVER_LOCAL_DIRPATH_ID];
211 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOCAL_DIR);
213 pathp = dirPathArray[AFSDIR_SERVER_BACKUP_DIRPATH_ID];
214 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BACKUP_DIR);
216 pathp = dirPathArray[AFSDIR_SERVER_MIGRATE_DIRPATH_ID];
217 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_MIGR_DIR);
219 pathp = dirPathArray[AFSDIR_SERVER_BIN_FILE_DIRPATH_ID];
220 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BIN_FILE_DIR);
222 /* client dir path */
224 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID],
225 "/NoUsrViceDirectoryOnWindows");
226 strcpy(dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID],
227 ntClientConfigDirShort);
229 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID], afsClntDirPath);
231 pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID];
232 #ifdef AFS_DARWIN_ENV
233 if (access(AFSDIR_ALTERNATE_CLIENT_ETC_DIR, F_OK) == 0)
234 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_ETC_DIR);
237 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR);
238 #endif /* AFS_NT40_ENV */
241 pathp = dirPathArray[AFSDIR_CLIENT_DATA_DIRPATH_ID];
242 #ifdef AFS_DARWIN_ENV
243 if (access(AFSDIR_ALTERNATE_CLIENT_DATA_DIR, F_OK) == 0)
244 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_DATA_DIR);
247 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_DATA_DIR);
250 /* server file paths */
251 pathp = dirPathArray[AFSDIR_SERVER_THISCELL_FILEPATH_ID];
252 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
253 AFSDIR_THISCELL_FILE);
255 pathp = dirPathArray[AFSDIR_SERVER_CELLSERVDB_FILEPATH_ID];
256 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
257 AFSDIR_CELLSERVDB_FILE);
259 pathp = dirPathArray[AFSDIR_SERVER_NOAUTH_FILEPATH_ID];
260 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NOAUTH_FILE);
262 pathp = dirPathArray[AFSDIR_SERVER_BUDBLOG_FILEPATH_ID];
263 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BUDBLOG_FILE);
265 pathp = dirPathArray[AFSDIR_SERVER_TAPECONFIG_FILEPATH_ID];
266 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BACKUP_DIR, AFSDIR_TAPECONFIG_FILE);
268 pathp = dirPathArray[AFSDIR_SERVER_KALOGDB_FILEPATH_ID];
269 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOGDB_FILE);
271 pathp = dirPathArray[AFSDIR_SERVER_KALOG_FILEPATH_ID];
272 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOG_FILE);
274 pathp = dirPathArray[AFSDIR_SERVER_KADB_FILEPATH_ID];
275 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_KADB_FILE);
277 pathp = dirPathArray[AFSDIR_SERVER_NTPD_FILEPATH_ID];
278 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR, AFSDIR_NTPD_FILE);
280 pathp = dirPathArray[AFSDIR_SERVER_PRDB_FILEPATH_ID];
281 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_PRDB_FILE);
283 pathp = dirPathArray[AFSDIR_SERVER_PTLOG_FILEPATH_ID];
284 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_PTLOG_FILE);
286 pathp = dirPathArray[AFSDIR_SERVER_KCONF_FILEPATH_ID];
287 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KCONF_FILE);
289 pathp = dirPathArray[AFSDIR_SERVER_VLDB_FILEPATH_ID];
290 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_VLDB_FILE);
292 pathp = dirPathArray[AFSDIR_SERVER_VLOG_FILEPATH_ID];
293 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VLOG_FILE);
295 pathp = dirPathArray[AFSDIR_SERVER_CORELOG_FILEPATH_ID];
296 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_CORE_FILE);
298 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
299 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
301 pathp = dirPathArray[AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID];
302 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SALSRVLOG_FILE);
304 pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
305 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
306 AFSDIR_SALVAGER_FILE);
308 pathp = dirPathArray[AFSDIR_SERVER_SALSRV_FILEPATH_ID];
309 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
312 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
313 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
315 pathp = dirPathArray[AFSDIR_SERVER_KEY_FILEPATH_ID];
316 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KEY_FILE);
318 pathp = dirPathArray[AFSDIR_SERVER_ULIST_FILEPATH_ID];
319 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ULIST_FILE);
321 pathp = dirPathArray[AFSDIR_SERVER_BOZCONF_FILEPATH_ID];
322 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZCONF_FILE);
324 pathp = dirPathArray[AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID];
325 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR,
326 AFSDIR_BOZCONFNEW_FILE);
328 pathp = dirPathArray[AFSDIR_SERVER_BOZLOG_FILEPATH_ID];
329 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BOZLOG_FILE);
331 pathp = dirPathArray[AFSDIR_SERVER_BOZINIT_FILEPATH_ID];
332 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZINIT_FILE);
334 pathp = dirPathArray[AFSDIR_SERVER_BOZRXBIND_FILEPATH_ID];
335 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZRXBIND_FILE);
337 pathp = dirPathArray[AFSDIR_SERVER_BOSVR_FILEPATH_ID];
338 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSSERVER_DIR, AFSDIR_BOSVR_FILE);
340 pathp = dirPathArray[AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID];
341 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VOLSERLOG_FILE);
343 pathp = dirPathArray[AFSDIR_SERVER_ROOTVOL_FILEPATH_ID];
344 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ROOTVOL_FILE);
346 pathp = dirPathArray[AFSDIR_SERVER_HOSTDUMP_FILEPATH_ID];
347 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_HOSTDUMP_FILE);
349 pathp = dirPathArray[AFSDIR_SERVER_CLNTDUMP_FILEPATH_ID];
350 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CLNTDUMP_FILE);
352 pathp = dirPathArray[AFSDIR_SERVER_CBKDUMP_FILEPATH_ID];
353 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CBKDUMP_FILE);
355 pathp = dirPathArray[AFSDIR_SERVER_OLDSYSID_FILEPATH_ID];
356 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_OLDSYSID_FILE);
358 pathp = dirPathArray[AFSDIR_SERVER_SYSID_FILEPATH_ID];
359 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SYSID_FILE);
361 pathp = dirPathArray[AFSDIR_SERVER_FILELOG_FILEPATH_ID];
362 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_FILELOG_FILE);
364 pathp = dirPathArray[AFSDIR_SERVER_AUDIT_FILEPATH_ID];
365 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_AUDIT_FILE);
367 pathp = dirPathArray[AFSDIR_SERVER_NETINFO_FILEPATH_ID];
368 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETINFO_FILE);
370 pathp = dirPathArray[AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID];
371 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETRESTRICT_FILE);
373 pathp = dirPathArray[AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH_ID];
374 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
375 AFSDIR_WEIGHTINGCONST_FILE);
377 pathp = dirPathArray[AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID];
378 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
379 AFSDIR_THRESHOLDCONST_FILE);
381 pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
382 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
384 pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
385 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
387 pathp = dirPathArray[AFSDIR_SERVER_FSSTATE_FILEPATH_ID];
388 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_FSSTATE_FILE);
390 /* client file paths */
392 strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
393 "/NoUsrViceEtcThisCellFileOnWindows");
394 sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
395 ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
396 strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
397 "/NoCellAliasOnWindows");
399 pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
400 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
401 AFSDIR_THISCELL_FILE);
403 pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID];
404 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
405 AFSDIR_CELLSERVDB_FILE);
407 pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID];
408 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
409 AFSDIR_CELLALIAS_FILE);
410 #endif /* AFS_NT40_ENV */
412 pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];
413 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_NETINFO_FILE);
415 pathp = dirPathArray[AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID];
416 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR,
417 AFSDIR_NETRESTRICT_FILE);
419 initFlag = 1; /* finished dirpath initialization */
423 /* getDirPath - returns a const char pointer to the requested string
424 * from the internal path array.
425 * string_id - index into the path array
428 getDirPath(afsdir_id_t string_id)
430 /* check if the array has been initialized */
431 if (initFlag == 0) { /* no it's not, so initialize */
432 #ifdef AFS_PTHREAD_ENV
433 pthread_once(&dirInit_once, initDirPathArray);
438 return (const char *)dirPathArray[string_id];
442 * LocalizePathHead() -- Make path relative to local part
444 * ConstructLocalPath takes a path and a directory that path should
445 * be considered relative to. There are two possible cases:
447 * The path is an absolute path. In this case, the relative path
448 * is ignored. We check the path for a prefix that represents a
449 * canonical path, and if one is found, we adjust the path to remove
450 * the prefix and adjust the directory to which it should be
451 * considered relative to be the local version of that canonical path.
453 * The path is a relative path. In this case, we check to see if the
454 * directory to which it is relative represents a canonical path, and
455 * if so, we adjust that directory to be the local version of that
456 * canonical path. The relative path itself is left unchanged.
459 /* The following array maps cannonical parts to local parts. It
460 * might seem reasonable to simply construct an array in parallel to
461 * dirpatharray but it turns out you don't want translations for all
465 struct canonmapping {
466 const char *canonical;
469 static struct canonmapping CanonicalTranslations[] = {
470 {AFSDIR_CANONICAL_SERVER_ETC_DIRPATH, AFSDIR_SERVER_ETC_DIR},
471 {AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH, AFSDIR_LOGS_DIR},
472 {AFSDIR_CANONICAL_SERVER_LOCAL_DIRPATH, AFSDIR_LOCAL_DIR},
473 {AFSDIR_CANONICAL_SERVER_BIN_DIRPATH, AFSDIR_SERVER_BIN_DIR},
478 LocalizePathHead(const char **path, const char **relativeTo)
480 struct canonmapping *map;
483 for (map = CanonicalTranslations; map->local != NULL; map++) {
484 int canonlength = strlen(map->canonical);
485 if (strncmp(*path, map->canonical, canonlength) == 0) {
486 (*path) += canonlength;
489 *relativeTo = map->local;
494 for (map = CanonicalTranslations; map->local != NULL; map++) {
495 if (strcmp(*relativeTo, map->canonical) == 0) {
496 *relativeTo = map->local;
505 /* NT version of ConstructLocalPath() */
508 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
509 * specified local path. Upon successful completion, *fullPathBufp is
510 * set to an allocated buffer containing the fully specified local path
511 * constructed from the cpath argument.
513 * On NT, path construction proceeds as follows:
514 * 1) If cpath is fully qualified (i.e., starts with 'X:/') then the
515 * path returned is equivalent to cpath.
516 * 2) If cpath begins with a drive letter but is not fully qualified,
517 * i.e., it is drive relative, then the function fails with EINVAL.
518 * 3) If cpath begins with '/' (or '\') then the path returned is the
519 * concatenation AFS-server-install-dir + cpath after translating for localization.
520 * 4) Otherwise the path returned is the concatenation
521 * AFS-server-install-dir + relativeTo + cpath.
523 * Leading whitespace in cpath is ignored; the constructed path is
524 * normalized (FilepathNormalize()).
526 * RETURN CODES: 0 if successful; errno code otherwise.
529 ConstructLocalPath(const char *cpath, const char *relativeTo,
533 char *newPath = NULL;
535 if (initFlag == 0) { /* dirpath module not yet initialized */
536 #ifdef AFS_PTHREAD_ENV
537 pthread_once(&dirInit_once, initDirPathArray);
543 *fullPathBufp = NULL;
545 while (isspace(*cpath)) {
549 LocalizePathHead(&cpath, &relativeTo);
550 if ((((*cpath >= 'a') && (*cpath <= 'z'))
551 || ((*cpath >= 'A') && (*cpath <= 'Z'))) && (*(cpath + 1) == ':')) {
553 /* cpath has a leading drive letter */
554 if ((*(cpath + 2) != '/') && (*(cpath + 2) != '\\')) {
555 /* drive letter relative path; this is not allowed */
558 /* fully qualified path; just make a copy */
559 newPath = strdup(cpath);
565 /* cpath has NO leading drive letter; make relative to install dir */
566 size_t pathSize = strlen(ntServerInstallDirShort) + 2;
568 if ((*cpath == '/') || (*cpath == '\\')) {
569 /* construct path relative to install directory only */
570 pathSize += strlen(cpath);
572 newPath = (char *)malloc(pathSize);
576 sprintf(newPath, "%s/%s", ntServerInstallDirShort, cpath);
579 /* construct path relative to 'relativeTo' (and install dir) */
580 pathSize += strlen(relativeTo) + 1 + strlen(cpath);
582 newPath = (char *)malloc(pathSize);
586 sprintf(newPath, "%s/%s/%s", ntServerInstallDirShort,
593 FilepathNormalize(newPath);
595 /* return buffer containing fully specified path */
596 *fullPathBufp = newPath;
603 /* Unix version of ConstructLocalPath() */
606 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
607 * specified local path. Upon successful completion, *fullPathBufp is
608 * set to an allocated buffer containing the fully specified local path
609 * constructed from the cpath argument.
611 * On Unix, path construction proceeds as follows:
612 * 1) If cpath begins with '/' then the path returned is equivalent
614 * 2) Otherwise the path returned is the concatenation
615 * relativeTo + cpath.
617 * Leading whitespace in cpath is ignored; the constructed path is
618 * normalized (FilepathNormalize()).
620 * RETURN CODES: 0 if successful; errno code otherwise.
623 ConstructLocalPath(const char *cpath, const char *relativeTo,
627 char *newPath = NULL;
629 if (initFlag == 0) { /* dirpath module not yet initialized */
630 #ifdef AFS_PTHREAD_ENV
631 pthread_once(&dirInit_once, initDirPathArray);
637 *fullPathBufp = NULL;
639 while (isspace(*cpath)) {
643 LocalizePathHead(&cpath, &relativeTo);
645 newPath = strdup(cpath);
649 newPath = (char *)malloc(strlen(relativeTo) + 1 + strlen(cpath) + 1);
653 sprintf(newPath, "%s/%s", relativeTo, cpath);
658 FilepathNormalize(newPath);
660 /* return buffer containing fully specified path */
661 *fullPathBufp = newPath;
666 #endif /* AFS_NT40_ENV */
670 * ConstructLocalBinPath() -- A convenience wrapper for ConstructLocalPath()
671 * that specifies the canonical AFS server binary directory as the relative
675 ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
677 return ConstructLocalPath(cpath, AFSDIR_SERVER_BIN_DIRPATH,
683 * ConstructLocalLogPath() -- A convenience wrapper for ConstructLocalPath()
684 * that specifies the canonical AFS server logs directory as the relative
688 ConstructLocalLogPath(const char *cpath, char **fullPathBufp)
690 return ConstructLocalPath(cpath, AFSDIR_SERVER_LOGS_DIRPATH,