Use asprintf for string construction
[openafs.git] / src / util / dirpath.c
index 0b7acc1..b307184 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
+#include <afs/opr.h>
 
 #include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
 #include <ctype.h>
 #include <limits.h>
-#include <errno.h>
-#include <stdio.h>
-#include "assert.h"
+
 #include "afsutil.h"
 #include "fileutil.h"
+
+#include <afs/opr.h>
+
 #ifdef AFS_PTHREAD_ENV
 #include <pthread.h>
 static pthread_once_t dirInit_once = PTHREAD_ONCE_INIT;
 #endif
+
 #ifdef AFS_NT40_ENV
-#include <windows.h>
 #include <WINNT\afssw.h>
 #endif
-#ifdef AFS_DARWIN_ENV
-#include <unistd.h>
-#endif
 
 /* local vars */
 /* static storage for path strings */
@@ -91,7 +87,7 @@ initAFSDirPath(void)
 }
 
 
-/* initDirPathArray() -- Initializes the afs dir paths for the 
+/* initDirPathArray() -- Initializes the afs dir paths for the
  *     server and client installations.
  *
  *     For NT these are determined dynamically; for Unix they are static.
@@ -135,12 +131,19 @@ initDirPathArray(void)
     FilepathNormalize(ntServerInstallDirShort);
 
     /* get the afs client configuration directory (/usr/vice/etc equivalent) */
-    status = GetWindowsDirectory(ntClientConfigDirLong, AFSDIR_PATH_MAX);
-    if (status == 0 || status > AFSDIR_PATH_MAX) {
-       /* failed to get canonical Windows directory; use temp directory */
-       strcpy(ntClientConfigDirLong, gettmpdir());
+    if (afssw_GetClientCellServDBDir(&buf)) {
+        /* failed */
+        status = GetWindowsDirectory(ntClientConfigDirLong, AFSDIR_PATH_MAX);
+        if (status == 0 || status > AFSDIR_PATH_MAX) {
+            /* failed to get canonical Windows directory; use temp directory */
+            strcpy(ntClientConfigDirLong, gettmpdir());
+        } else {
+            initStatus |= AFSDIR_CLIENT_PATHS_OK;
+        }
     } else {
-       initStatus |= AFSDIR_CLIENT_PATHS_OK;
+        strcpy(ntClientConfigDirLong, buf);
+        free(buf);
+        initStatus |= AFSDIR_CLIENT_PATHS_OK;
     }
     FilepathNormalize(ntClientConfigDirLong);
 
@@ -187,7 +190,6 @@ initDirPathArray(void)
     /* now initialize various dir and file paths exported by dirpath module */
 
     /* server dir paths */
-
     strcpy(dirPathArray[AFSDIR_SERVER_AFS_DIRPATH_ID], afsSrvDirPath);
 
     pathp = dirPathArray[AFSDIR_SERVER_ETC_DIRPATH_ID];
@@ -218,7 +220,6 @@ initDirPathArray(void)
     AFSDIR_SERVER_DIRPATH(pathp, AFSDIR_BIN_FILE_DIR);
 
     /* client dir path */
-
 #ifdef AFS_NT40_ENV
     strcpy(dirPathArray[AFSDIR_CLIENT_VICE_DIRPATH_ID],
           "/NoUsrViceDirectoryOnWindows");
@@ -236,8 +237,17 @@ initDirPathArray(void)
        AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_CLIENT_ETC_DIR);
 #endif /* AFS_NT40_ENV */
 
-    /* server file paths */
+#ifndef AFS_NT40_ENV
+    pathp = dirPathArray[AFSDIR_CLIENT_DATA_DIRPATH_ID];
+#ifdef AFS_DARWIN_ENV
+    if (access(AFSDIR_ALTERNATE_CLIENT_DATA_DIR, F_OK) == 0)
+       AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_ALTERNATE_CLIENT_DATA_DIR);
+    else
+#endif
+       AFSDIR_CLIENT_DIRPATH(pathp, AFSDIR_DATA_DIR);
+#endif
 
+    /* server file paths */
     pathp = dirPathArray[AFSDIR_SERVER_THISCELL_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR,
                           AFSDIR_THISCELL_FILE);
@@ -288,10 +298,17 @@ initDirPathArray(void)
     pathp = dirPathArray[AFSDIR_SERVER_SLVGLOG_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SLVGLOG_FILE);
 
+    pathp = dirPathArray[AFSDIR_SERVER_SALSRVLOG_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOGS_DIR, AFSDIR_SALSRVLOG_FILE);
+
     pathp = dirPathArray[AFSDIR_SERVER_SALVAGER_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
                           AFSDIR_SALVAGER_FILE);
 
+    pathp = dirPathArray[AFSDIR_SERVER_SALSRV_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_BIN_DIR,
+                          AFSDIR_SALSRV_FILE);
+
     pathp = dirPathArray[AFSDIR_SERVER_SLVGLOCK_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_SLVGLOCK_FILE);
 
@@ -314,6 +331,9 @@ initDirPathArray(void)
     pathp = dirPathArray[AFSDIR_SERVER_BOZINIT_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZINIT_FILE);
 
+    pathp = dirPathArray[AFSDIR_SERVER_BOZRXBIND_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSCONFIG_DIR, AFSDIR_BOZRXBIND_FILE);
+
     pathp = dirPathArray[AFSDIR_SERVER_BOSVR_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_BOSSERVER_DIR, AFSDIR_BOSVR_FILE);
 
@@ -361,9 +381,13 @@ initDirPathArray(void)
     pathp = dirPathArray[AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID];
     AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_MIGR_DIR, AFSDIR_MIGRATE_LOGNAME);
 
+    pathp = dirPathArray[AFSDIR_SERVER_KRB_EXCL_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_SERVER_ETC_DIR, AFSDIR_KRB_EXCL_FILE);
 
-    /* client file paths */
+    pathp = dirPathArray[AFSDIR_SERVER_FSSTATE_FILEPATH_ID];
+    AFSDIR_SERVER_FILEPATH(pathp, AFSDIR_LOCAL_DIR, AFSDIR_FSSTATE_FILE);
 
+    /* client file paths */
 #ifdef AFS_NT40_ENV
     strcpy(dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID],
           "/NoUsrViceEtcThisCellFileOnWindows");
@@ -398,7 +422,7 @@ initDirPathArray(void)
 
 /* getDirPath - returns a const char pointer to the requested string
  * from the internal path array.
- * string_id - index into the path array 
+ * string_id - index into the path array
  */
 const char *
 getDirPath(afsdir_id_t string_id)
@@ -417,17 +441,25 @@ getDirPath(afsdir_id_t string_id)
 /*
  * LocalizePathHead() -- Make path relative to local part
  *
- * ConstructLocalPath takes a path  and a directory that path should
- * be considered relative to.   This  function checks the given path
- * for   a prefix  that represents a canonical path.  If such a prefix
- * is found,  the path is adjusted to remove the prefix and the path
- * is considered  relative to the local version of that path.
+ * ConstructLocalPath takes a path and a directory that path should
+ * be considered relative to.  There are two possible cases:
+ *
+ * The path is an absolute path.  In this case, the relative path
+ * is ignored.  We check the path for a prefix that represents a
+ * canonical path, and if one is found, we adjust the path to remove
+ * the prefix and adjust the directory to which it should be
+ * considered relative to be the local version of that canonical path.
+ *
+ * The path is a relative path.  In this case, we check to see if the
+ * directory to which it is relative represents a canonical path, and
+ * if so, we adjust that directory to be the local version of that
+ * canonical path.  The relative path itself is left unchanged.
  */
 
 /* The following array  maps cannonical parts to local parts.  It
  * might  seem reasonable to  simply construct an array in parallel to
  * dirpatharray  but it turns out you don't want translations for all
- local paths.
+ * local paths.
 */
 
 struct canonmapping {
@@ -445,17 +477,27 @@ static struct canonmapping CanonicalTranslations[] = {
 static void
 LocalizePathHead(const char **path, const char **relativeTo)
 {
-    struct canonmapping *current;
-    for (current = CanonicalTranslations; current->local != NULL; current++) {
-       int canonlength = strlen(current->canonical);
-       if (strncmp(*path, current->canonical, canonlength) == 0) {
-           (*path) += canonlength;
-           if (**path == '/')
-               (*path)++;
-           *relativeTo = current->local;
-           return;
-       }
-    }
+     struct canonmapping *map;
+
+     if (**path == '/') {
+        for (map = CanonicalTranslations; map->local != NULL; map++) {
+            int canonlength = strlen(map->canonical);
+            if (strncmp(*path, map->canonical, canonlength) == 0) {
+                (*path) += canonlength;
+                if (**path == '/')
+                    (*path)++;
+                *relativeTo = map->local;
+                return;
+            }
+        }
+     } else {
+        for (map = CanonicalTranslations; map->local != NULL; map++) {
+            if (strcmp(*relativeTo, map->canonical) == 0) {
+                *relativeTo = map->local;
+                return;
+            }
+        }
+     }
 }
 
 
@@ -514,12 +556,9 @@ ConstructLocalPath(const char *cpath, const char *relativeTo,
            status = EINVAL;
        } else {
            /* fully qualified path; just make a copy */
-           newPath = (char *)malloc(strlen(cpath) + 1);
-           if (!newPath) {
+           newPath = strdup(cpath);
+           if (!newPath)
                status = ENOMEM;
-           } else {
-               (void)strcpy(newPath, cpath);
-           }
        }
 
     } else {
@@ -603,20 +642,12 @@ ConstructLocalPath(const char *cpath, const char *relativeTo,
 
     LocalizePathHead(&cpath, &relativeTo);
     if (*cpath == '/') {
-       newPath = (char *)malloc(strlen(cpath) + 1);
-       if (!newPath) {
-           status = ENOMEM;
-       } else {
-           strcpy(newPath, cpath);
-       }
+       newPath = strdup(cpath);
     } else {
-       newPath = (char *)malloc(strlen(relativeTo) + 1 + strlen(cpath) + 1);
-       if (!newPath) {
-           status = ENOMEM;
-       } else {
-           sprintf(newPath, "%s/%s", relativeTo, cpath);
-       }
+       asprintf(&newPath, "%s/%s", relativeTo, cpath);
     }
+    if (newPath == NULL)
+       status = ENOMEM;
 
     if (status == 0) {
        FilepathNormalize(newPath);
@@ -638,7 +669,7 @@ ConstructLocalPath(const char *cpath, const char *relativeTo,
 int
 ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
 {
-    return ConstructLocalPath(cpath, AFSDIR_CANONICAL_SERVER_BIN_DIRPATH,
+    return ConstructLocalPath(cpath, AFSDIR_SERVER_BIN_DIRPATH,
                              fullPathBufp);
 }
 
@@ -651,6 +682,6 @@ ConstructLocalBinPath(const char *cpath, char **fullPathBufp)
 int
 ConstructLocalLogPath(const char *cpath, char **fullPathBufp)
 {
-    return ConstructLocalPath(cpath, AFSDIR_CANONICAL_SERVER_LOGS_DIRPATH,
+    return ConstructLocalPath(cpath, AFSDIR_SERVER_LOGS_DIRPATH,
                              fullPathBufp);
 }