Commit | Line | Data |
---|---|---|
805e021f CE |
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 | } |