backport to buster
[hcoop/debian/openafs.git] / src / util / dirpath.c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14 #include <afs/opr.h>
15
16 #include <stddef.h>
17 #include <ctype.h>
18 #include <limits.h>
19
20 #include "afsutil.h"
21 #include "fileutil.h"
22
23 #include <afs/opr.h>
24
25 #ifdef AFS_PTHREAD_ENV
26 #include <pthread.h>
27 static pthread_once_t dirInit_once = PTHREAD_ONCE_INIT;
28 #endif
29
30 #ifdef AFS_NT40_ENV
31 #include <WINNT\afssw.h>
32 #endif
33
34 /* local vars */
35 /* static storage for path strings */
36 static char dirPathArray[AFSDIR_PATHSTRING_MAX][AFSDIR_PATH_MAX];
37
38 /* indicate if and how the dirpath module initialized. */
39 static int initFlag = 0;
40 static unsigned int initStatus = 0;
41
42
43 /* storage for dynamically-determined install dir (NT only; long and short) */
44 #ifdef AFS_NT40_ENV
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];
49 #endif
50
51 /* storage for local afs server/client paths (top-level) */
52 static char afsSrvDirPath[AFSDIR_PATH_MAX];
53 static char afsClntDirPath[AFSDIR_PATH_MAX];
54
55 /* internal array init function */
56 static void initDirPathArray(void);
57
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, (char *)NULL)
62
63 #define AFSDIR_SERVER_FILEPATH(buf, dir, file) \
64 (void) strcompose(buf, AFSDIR_PATH_MAX, serverPrefix, dir, "/", file, (char *)NULL)
65
66 #define AFSDIR_CLIENT_DIRPATH(buf, dir) \
67 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, (char *)NULL)
68
69 #define AFSDIR_CLIENT_FILEPATH(buf, dir, file) \
70 (void) strcompose(buf, AFSDIR_PATH_MAX, clientPrefix, dir, "/", file, (char *)NULL)
71
72
73 /* initAFSDirPath() -- External users call this function to initialize
74 * the dirpath module and/or to determine the initialization status.
75 */
76 unsigned int
77 initAFSDirPath(void)
78 {
79 if (initFlag == 0) { /* not yet init'ed, so initialize */
80 #ifdef AFS_PTHREAD_ENV
81 pthread_once(&dirInit_once, initDirPathArray);
82 #else
83 initDirPathArray();
84 #endif
85 }
86 return initStatus;
87 }
88
89
90 /* initDirPathArray() -- Initializes the afs dir paths for the
91 * server and client installations.
92 *
93 * For NT these are determined dynamically; for Unix they are static.
94 *
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.
102 */
103 static void
104 initDirPathArray(void)
105 {
106 char *pathp, *clntEtcDir;
107 const char *clientPrefix = "";
108 const char *serverPrefix = "";
109
110 #ifdef AFS_NT40_ENV
111 char *buf;
112 int status;
113
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());
118 } else {
119 strcpy(ntServerInstallDirLong, buf);
120 free(buf);
121 initStatus |= AFSDIR_SERVER_PATHS_OK;
122 }
123 FilepathNormalize(ntServerInstallDirLong);
124 status =
125 GetShortPathName(ntServerInstallDirLong, ntServerInstallDirShort,
126 AFSDIR_PATH_MAX);
127 if (status == 0 || status > AFSDIR_PATH_MAX) {
128 /* can't convert path to short version; just use long version */
129 strcpy(ntServerInstallDirShort, ntServerInstallDirLong);
130 }
131 FilepathNormalize(ntServerInstallDirShort);
132
133 /* get the afs client configuration directory (/usr/vice/etc equivalent) */
134 if (afssw_GetClientCellServDBDir(&buf)) {
135 /* failed */
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());
140 } else {
141 initStatus |= AFSDIR_CLIENT_PATHS_OK;
142 }
143 } else {
144 strcpy(ntClientConfigDirLong, buf);
145 free(buf);
146 initStatus |= AFSDIR_CLIENT_PATHS_OK;
147 }
148 FilepathNormalize(ntClientConfigDirLong);
149
150 status =
151 GetShortPathName(ntClientConfigDirLong, ntClientConfigDirShort,
152 AFSDIR_PATH_MAX);
153 if (status == 0 || status > AFSDIR_PATH_MAX) {
154 /* can't convert path to short version; just use long version */
155 strcpy(ntClientConfigDirShort, ntClientConfigDirLong);
156 }
157 FilepathNormalize(ntClientConfigDirShort);
158 clientPrefix = ntClientConfigDirShort;
159
160 /* setup the root server directory path (/usr/afs equivalent) */
161 strcpy(afsSrvDirPath, ntServerInstallDirShort);
162 strcat(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
163
164 /* there is no root client directory path (/usr/vice equivalent) */
165 afsClntDirPath[0] = '\0';
166
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);
171
172 #else /* AFS_NT40_ENV */
173 /* setup the root server directory path */
174 strcpy(afsSrvDirPath, AFSDIR_CANONICAL_SERVER_AFS_DIRPATH);
175
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);
180 else
181 #endif
182 strcpy(afsClntDirPath, AFSDIR_CANONICAL_CLIENT_VICE_DIRPATH);
183
184 /* setup top level dirpath; valid for both server and client */
185 strcpy(dirPathArray[AFSDIR_USR_DIRPATH_ID], AFSDIR_CANONICAL_USR_DIRPATH);
186
187 initStatus |= (AFSDIR_CLIENT_PATHS_OK | AFSDIR_SERVER_PATHS_OK);
188 #endif /* AFS_NT40_ENV */
189
190 /* now initialize various dir and file paths exported by dirpath module */
191
192 /* server dir paths */
193 strcpy(dirPathArray[AFSDIR_SERVER_AFS_DIRPATH_ID], afsSrvDirPath);
194
195 pathp = dirPathArray[AFSDIR_SERVER_ETC_DIRPATH_ID];
196 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_ETC_DIR);
197
198 pathp = dirPathArray[AFSDIR_SERVER_BIN_DIRPATH_ID];
199 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_SERVER_BIN_DIR);
200
201 pathp = dirPathArray[AFSDIR_SERVER_CORES_DIRPATH_ID];
202 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_CORES_DIR);
203
204 pathp = dirPathArray[AFSDIR_SERVER_DB_DIRPATH_ID];
205 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_DB_DIR);
206
207 pathp = dirPathArray[AFSDIR_SERVER_LOGS_DIRPATH_ID];
208 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOGS_DIR);
209
210 pathp = dirPathArray[AFSDIR_SERVER_LOCAL_DIRPATH_ID];
211 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_LOCAL_DIR);
212
213 pathp = dirPathArray[AFSDIR_SERVER_BACKUP_DIRPATH_ID];
214 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BACKUP_DIR);
215
216 pathp = dirPathArray[AFSDIR_SERVER_MIGRATE_DIRPATH_ID];
217 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_MIGR_DIR);
218
219 pathp = dirPathArray[AFSDIR_SERVER_BIN_FILE_DIRPATH_ID];
220 AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BIN_FILE_DIR);
221
222 /* client dir path */
223 #ifdef AFS_NT40_ENV
224 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID],
225 "/NoUsrViceDirectoryOnWindows");
226 strcpy(dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID],
227 ntClientConfigDirShort);
228
229 clntEtcDir = pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID];
230 #else
231 strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID], afsClntDirPath);
232
233 clntEtcDir = pathp = dirPathArray[AFSDIR_CLIENT_ETC_DIRPATH_ID];
234 #ifdef AFS_DARWIN_ENV
235 if (access(AFSDIR_ALTERNATE_CLIENT_ETC_DIR, F_OK) == 0)
236 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_ETC_DIR);
237 else
238 #endif
239 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR);
240 #endif /* AFS_NT40_ENV */
241
242 #ifndef AFS_NT40_ENV
243 pathp = dirPathArray[AFSDIR_CLIENT_DATA_DIRPATH_ID];
244 #ifdef AFS_DARWIN_ENV
245 if (access(AFSDIR_ALTERNATE_CLIENT_DATA_DIR, F_OK) == 0)
246 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_DATA_DIR);
247 else
248 #endif
249 AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_DATA_DIR);
250 #endif
251
252 /* server file paths */
253 pathp = dirPathArray[AFSDIR_SERVER_THISCELL_FILEPATH_ID];
254 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
255 AFSDIR_THISCELL_FILE);
256
257 pathp = dirPathArray[AFSDIR_SERVER_CELLSERVDB_FILEPATH_ID];
258 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
259 AFSDIR_CELLSERVDB_FILE);
260
261 pathp = dirPathArray[AFSDIR_SERVER_NOAUTH_FILEPATH_ID];
262 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NOAUTH_FILE);
263
264 pathp = dirPathArray[AFSDIR_SERVER_BUDBLOG_FILEPATH_ID];
265 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BUDBLOG_FILE);
266
267 pathp = dirPathArray[AFSDIR_SERVER_TAPECONFIG_FILEPATH_ID];
268 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BACKUP_DIR, AFSDIR_TAPECONFIG_FILE);
269
270 pathp = dirPathArray[AFSDIR_SERVER_KALOGDB_FILEPATH_ID];
271 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOGDB_FILE);
272
273 pathp = dirPathArray[AFSDIR_SERVER_KALOG_FILEPATH_ID];
274 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_KALOG_FILE);
275
276 pathp = dirPathArray[AFSDIR_SERVER_KADB_FILEPATH_ID];
277 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_KADB_FILE);
278
279 pathp = dirPathArray[AFSDIR_SERVER_NTPD_FILEPATH_ID];
280 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR, AFSDIR_NTPD_FILE);
281
282 pathp = dirPathArray[AFSDIR_SERVER_PRDB_FILEPATH_ID];
283 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_PRDB_FILE);
284
285 pathp = dirPathArray[AFSDIR_SERVER_PTLOG_FILEPATH_ID];
286 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_PTLOG_FILE);
287
288 pathp = dirPathArray[AFSDIR_SERVER_KCONF_FILEPATH_ID];
289 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KCONF_FILE);
290
291 pathp = dirPathArray[AFSDIR_SERVER_VLDB_FILEPATH_ID];
292 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_DB_DIR, AFSDIR_VLDB_FILE);
293
294 pathp = dirPathArray[AFSDIR_SERVER_VLOG_FILEPATH_ID];
295 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VLOG_FILE);
296
297 pathp = dirPathArray[AFSDIR_SERVER_CORELOG_FILEPATH_ID];
298 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_CORE_FILE);
299
300 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
301 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
302
303 pathp = dirPathArray[AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID];
304 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SALSRVLOG_FILE);
305
306 pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
307 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
308 AFSDIR_SALVAGER_FILE);
309
310 pathp = dirPathArray[AFSDIR_SERVER_SALSRV_FILEPATH_ID];
311 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
312 AFSDIR_SALSRV_FILE);
313
314 pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
315 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
316
317 pathp = dirPathArray[AFSDIR_SERVER_KEY_FILEPATH_ID];
318 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KEY_FILE);
319
320 pathp = dirPathArray[AFSDIR_SERVER_ULIST_FILEPATH_ID];
321 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ULIST_FILE);
322
323 pathp = dirPathArray[AFSDIR_SERVER_BOZCONF_FILEPATH_ID];
324 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZCONF_FILE);
325
326 pathp = dirPathArray[AFSDIR_SERVER_BOZCONFNEW_FILEPATH_ID];
327 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR,
328 AFSDIR_BOZCONFNEW_FILE);
329
330 pathp = dirPathArray[AFSDIR_SERVER_BOZLOG_FILEPATH_ID];
331 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_BOZLOG_FILE);
332
333 pathp = dirPathArray[AFSDIR_SERVER_BOZINIT_FILEPATH_ID];
334 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZINIT_FILE);
335
336 pathp = dirPathArray[AFSDIR_SERVER_BOZRXBIND_FILEPATH_ID];
337 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZRXBIND_FILE);
338
339 pathp = dirPathArray[AFSDIR_SERVER_BOSVR_FILEPATH_ID];
340 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSSERVER_DIR, AFSDIR_BOSVR_FILE);
341
342 pathp = dirPathArray[AFSDIR_SERVER_VOLSERLOG_FILEPATH_ID];
343 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_VOLSERLOG_FILE);
344
345 pathp = dirPathArray[AFSDIR_SERVER_ROOTVOL_FILEPATH_ID];
346 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_ROOTVOL_FILE);
347
348 pathp = dirPathArray[AFSDIR_SERVER_HOSTDUMP_FILEPATH_ID];
349 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_HOSTDUMP_FILE);
350
351 pathp = dirPathArray[AFSDIR_SERVER_CLNTDUMP_FILEPATH_ID];
352 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CLNTDUMP_FILE);
353
354 pathp = dirPathArray[AFSDIR_SERVER_CBKDUMP_FILEPATH_ID];
355 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_CBKDUMP_FILE);
356
357 pathp = dirPathArray[AFSDIR_SERVER_OLDSYSID_FILEPATH_ID];
358 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_OLDSYSID_FILE);
359
360 pathp = dirPathArray[AFSDIR_SERVER_SYSID_FILEPATH_ID];
361 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SYSID_FILE);
362
363 pathp = dirPathArray[AFSDIR_SERVER_FILELOG_FILEPATH_ID];
364 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_FILELOG_FILE);
365
366 pathp = dirPathArray[AFSDIR_SERVER_AUDIT_FILEPATH_ID];
367 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_AUDIT_FILE);
368
369 pathp = dirPathArray[AFSDIR_SERVER_CONFIG_FILE_FILEPATH_ID];
370 AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
371 AFSDIR_SERVER_CONFIG_FILE);
372
373 pathp = dirPathArray[AFSDIR_SERVER_NETINFO_FILEPATH_ID];
374 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETINFO_FILE);
375
376 pathp = dirPathArray[AFSDIR_SERVER_NETRESTRICT_FILEPATH_ID];
377 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_NETRESTRICT_FILE);
378
379 pathp = dirPathArray[AFSDIR_SERVER_WEIGHTING_CONSTANTS_FILEPATH_ID];
380 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
381 AFSDIR_WEIGHTINGCONST_FILE);
382
383 pathp = dirPathArray[AFSDIR_SERVER_THRESHOLD_CONSTANTS_FILEPATH_ID];
384 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR,
385 AFSDIR_THRESHOLDCONST_FILE);
386
387 pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
388 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
389
390 pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
391 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
392
393 pathp = dirPathArray[AFSDIR_SERVER_FSSTATE_FILEPATH_ID];
394 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_FSSTATE_FILE);
395
396 pathp = dirPathArray[AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH_ID];
397 AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_RXKAD_KEYTAB_FILE);
398
399 /* client file paths */
400 #ifdef AFS_NT40_ENV
401 strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
402 "/NoUsrViceEtcThisCellFileOnWindows");
403 sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
404 ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
405 strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
406 "/NoCellAliasOnWindows");
407 #else
408 pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
409 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_THISCELL_FILE);
410
411 pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID];
412 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_CELLSERVDB_FILE);
413
414 pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID];
415 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_CELLALIAS_FILE);
416 #endif /* AFS_NT40_ENV */
417
418 pathp = dirPathArray[AFSDIR_CLIENT_CONFIG_FILE_FILEPATH_ID];
419 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_CLIENT_CONFIG_FILE);
420
421 pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];
422 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_NETINFO_FILE);
423
424 pathp = dirPathArray[AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID];
425 AFSDIR_CLIENT_FILEPATH(pathp, clntEtcDir, AFSDIR_NETRESTRICT_FILE);
426
427 initFlag = 1; /* finished dirpath initialization */
428 return;
429 }
430
431 /* afs_getDirPath - returns a const char pointer to the requested string
432 * from the internal path array.
433 * string_id - index into the path array
434 */
435 const char *
436 afs_getDirPath(afsdir_id_t string_id)
437 {
438 /* check if the array has been initialized */
439 if (initFlag == 0) { /* no it's not, so initialize */
440 #ifdef AFS_PTHREAD_ENV
441 pthread_once(&dirInit_once, initDirPathArray);
442 #else
443 initDirPathArray();
444 #endif
445 }
446 return (const char *)dirPathArray[string_id];
447 }
448
449 #ifdef AFS_NT40_ENV
450 /* getDirPath - present for ABI compatibility on Windows systems;
451 * Unix systems should not use it. */
452 const char *
453 getDirPath(afsdir_id_t string_id)
454 {
455 return afs_getDirPath(string_id);
456 }
457 #endif
458
459 /*
460 * LocalizePathHead() -- Make path relative to local part
461 *
462 * ConstructLocalPath takes a path and a directory that path should
463 * be considered relative to. There are two possible cases:
464 *
465 * The path is an absolute path. In this case, the relative path
466 * is ignored. We check the path for a prefix that represents a
467 * canonical path, and if one is found, we adjust the path to remove
468 * the prefix and adjust the directory to which it should be
469 * considered relative to be the local version of that canonical path.
470 *
471 * The path is a relative path. In this case, we check to see if the
472 * directory to which it is relative represents a canonical path, and
473 * if so, we adjust that directory to be the local version of that
474 * canonical path. The relative path itself is left unchanged.
475 */
476
477 /* The following array maps cannonical parts to local parts. It
478 * might seem reasonable to simply construct an array in parallel to
479 * dirpatharray but it turns out you don't want translations for all
480 * local paths.
481 */
482
483 struct canonmapping {
484 const char *canonical;
485 const char *local;
486 };
487 static struct canonmapping CanonicalTranslations[] = {
488 {AFSDIR_CANONICAL_SERVER_ETC_DIRPATH, AFSDIR_SERVER_ETC_DIR},
489 {AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH, AFSDIR_LOGS_DIR},
490 {AFSDIR_CANONICAL_SERVER_LOCAL_DIRPATH, AFSDIR_LOCAL_DIR},
491 {AFSDIR_CANONICAL_SERVER_BIN_DIRPATH, AFSDIR_SERVER_BIN_DIR},
492 {NULL, NULL}
493 };
494
495 static void
496 LocalizePathHead(const char **path, const char **relativeTo)
497 {
498 struct canonmapping *map;
499
500 if (**path == '/') {
501 for (map = CanonicalTranslations; map->local != NULL; map++) {
502 int canonlength = strlen(map->canonical);
503 if (strncmp(*path, map->canonical, canonlength) == 0) {
504 (*path) += canonlength;
505 if (**path == '/')
506 (*path)++;
507 *relativeTo = map->local;
508 return;
509 }
510 }
511 } else {
512 for (map = CanonicalTranslations; map->local != NULL; map++) {
513 if (strcmp(*relativeTo, map->canonical) == 0) {
514 *relativeTo = map->local;
515 return;
516 }
517 }
518 }
519 }
520
521
522 #ifdef AFS_NT40_ENV
523 /* NT version of ConstructLocalPath() */
524
525 /*
526 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
527 * specified local path. Upon successful completion, *fullPathBufp is
528 * set to an allocated buffer containing the fully specified local path
529 * constructed from the cpath argument.
530 *
531 * On NT, path construction proceeds as follows:
532 * 1) If cpath is fully qualified (i.e., starts with 'X:/') then the
533 * path returned is equivalent to cpath.
534 * 2) If cpath begins with a drive letter but is not fully qualified,
535 * i.e., it is drive relative, then the function fails with EINVAL.
536 * 3) If cpath begins with '/' (or '\') then the path returned is the
537 * concatenation AFS-server-install-dir + cpath after translating for localization.
538 * 4) Otherwise the path returned is the concatenation
539 * AFS-server-install-dir + relativeTo + cpath.
540 *
541 * Leading whitespace in cpath is ignored; the constructed path is
542 * normalized (FilepathNormalize()).
543 *
544 * RETURN CODES: 0 if successful; errno code otherwise.
545 */
546 int
547 ConstructLocalPath(const char *cpath, const char *relativeTo,
548 char **fullPathBufp)
549 {
550 int status = 0;
551 char *newPath = NULL;
552
553 if (initFlag == 0) { /* dirpath module not yet initialized */
554 #ifdef AFS_PTHREAD_ENV
555 pthread_once(&dirInit_once, initDirPathArray);
556 #else
557 initDirPathArray();
558 #endif
559 }
560
561 *fullPathBufp = NULL;
562
563 while (isspace(*cpath)) {
564 cpath++;
565 }
566
567 LocalizePathHead(&cpath, &relativeTo);
568 if ((((*cpath >= 'a') && (*cpath <= 'z'))
569 || ((*cpath >= 'A') && (*cpath <= 'Z'))) && (*(cpath + 1) == ':')) {
570
571 /* cpath has a leading drive letter */
572 if ((*(cpath + 2) != '/') && (*(cpath + 2) != '\\')) {
573 /* drive letter relative path; this is not allowed */
574 status = EINVAL;
575 } else {
576 /* fully qualified path; just make a copy */
577 newPath = strdup(cpath);
578 if (!newPath)
579 status = ENOMEM;
580 }
581
582 } else {
583 /* cpath has NO leading drive letter; make relative to install dir */
584 size_t pathSize = strlen(ntServerInstallDirShort) + 2;
585
586 if ((*cpath == '/') || (*cpath == '\\')) {
587 /* construct path relative to install directory only */
588 pathSize += strlen(cpath);
589
590 newPath = malloc(pathSize);
591 if (!newPath) {
592 status = ENOMEM;
593 } else {
594 sprintf(newPath, "%s/%s", ntServerInstallDirShort, cpath);
595 }
596 } else {
597 /* construct path relative to 'relativeTo' (and install dir) */
598 pathSize += strlen(relativeTo) + 1 + strlen(cpath);
599
600 newPath = malloc(pathSize);
601 if (!newPath) {
602 status = ENOMEM;
603 } else {
604 sprintf(newPath, "%s/%s/%s", ntServerInstallDirShort,
605 relativeTo, cpath);
606 }
607 }
608 }
609
610 if (status == 0) {
611 FilepathNormalize(newPath);
612
613 /* return buffer containing fully specified path */
614 *fullPathBufp = newPath;
615 }
616
617 return status;
618 }
619
620 #else
621 /* Unix version of ConstructLocalPath() */
622
623 /*
624 * ConstructLocalPath() -- Convert a canonical (wire-format) path to a fully
625 * specified local path. Upon successful completion, *fullPathBufp is
626 * set to an allocated buffer containing the fully specified local path
627 * constructed from the cpath argument.
628 *
629 * On Unix, path construction proceeds as follows:
630 * 1) If cpath begins with '/' then the path returned is equivalent
631 * to cpath.
632 * 2) Otherwise the path returned is the concatenation
633 * relativeTo + cpath.
634 *
635 * Leading whitespace in cpath is ignored; the constructed path is
636 * normalized (FilepathNormalize()).
637 *
638 * RETURN CODES: 0 if successful; errno code otherwise.
639 */
640 int
641 ConstructLocalPath(const char *cpath, const char *relativeTo,
642 char **fullPathBufp)
643 {
644 int status = 0;
645 char *newPath = NULL;
646
647 if (initFlag == 0) { /* dirpath module not yet initialized */
648 #ifdef AFS_PTHREAD_ENV
649 pthread_once(&dirInit_once, initDirPathArray);
650 #else
651 initDirPathArray();
652 #endif
653 }
654
655 *fullPathBufp = NULL;
656
657 while (isspace(*cpath)) {
658 cpath++;
659 }
660
661 LocalizePathHead(&cpath, &relativeTo);
662 if (*cpath == '/') {
663 newPath = strdup(cpath);
664 } else {
665 if (asprintf(&newPath, "%s/%s", relativeTo, cpath) < 0)
666 newPath = NULL;
667 }
668 if (newPath == NULL)
669 status = ENOMEM;
670
671 if (status == 0) {
672 FilepathNormalize(newPath);
673
674 /* return buffer containing fully specified path */
675 *fullPathBufp = newPath;
676 }
677
678 return status;
679 }
680 #endif /* AFS_NT40_ENV */
681
682
683 /*
684 * ConstructLocalBinPath() -- A convenience wrapper for ConstructLocalPath()
685 * that specifies the canonical AFS server binary directory as the relative
686 * directory.
687 */
688 int
689 ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
690 {
691 return ConstructLocalPath(cpath, AFSDIR_SERVER_BIN_DIRPATH,
692 fullPathBufp);
693 }
694
695
696 /*
697 * ConstructLocalLogPath() -- A convenience wrapper for ConstructLocalPath()
698 * that specifies the canonical AFS server logs directory as the relative
699 * directory.
700 */
701 int
702 ConstructLocalLogPath(const char *cpath, char **fullPathBufp)
703 {
704 return ConstructLocalPath(cpath, AFSDIR_SERVER_LOGS_DIRPATH,
705 fullPathBufp);
706 }