00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "libts.h"
00025 #include "I_Layout.h"
00026 
00027 static Layout *layout = NULL;
00028 
00029 Layout *
00030 Layout::get()
00031 {
00032   if (layout == NULL) {
00033     ink_assert("need to call create_default_layout before accessing" "default_layout()");
00034   }
00035   return layout;
00036 }
00037 
00038 void
00039 Layout::create(const char *prefix)
00040 {
00041   if (layout == NULL) {
00042     layout = new Layout(prefix);
00043   }
00044 }
00045 
00046 static char *
00047 layout_relative(const char *root, const char *file)
00048 {
00049   char path[PATH_NAME_MAX];
00050 
00051   if (ink_filepath_merge(path, PATH_NAME_MAX, root, file, INK_FILEPATH_TRUENAME)) {
00052     int err = errno;
00053     
00054     if (err == EACCES) {
00055       ink_error("Cannot merge path '%s' above the root '%s'\n", file, root);
00056     } else if (err == E2BIG) {
00057       ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
00058     }
00059     else {
00060       
00061       ink_error("Cannot merge '%s' with '%s' error=%d\n", file, root, err);
00062     }
00063     return NULL;
00064   }
00065   return ats_strdup(path);
00066 }
00067 
00068 char *
00069 Layout::relative(const char *file)
00070 {
00071   return layout_relative(prefix, file);
00072 }
00073 
00074 void
00075 Layout::relative(char *buf, size_t bufsz, const char *file)
00076 {
00077   char path[PATH_NAME_MAX];
00078 
00079   if (ink_filepath_merge(path, PATH_NAME_MAX, prefix, file,
00080       INK_FILEPATH_TRUENAME)) {
00081     int err = errno;
00082     
00083     if (err == EACCES) {
00084       ink_error("Cannot merge path '%s' above the root '%s'\n", file, prefix);
00085     } else if (err == E2BIG) {
00086       ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
00087     }
00088     else {
00089       
00090       ink_error("Cannot merge '%s' with '%s' error=%d\n", file, prefix, err);
00091     }
00092     return;
00093   }
00094   size_t path_len = strlen(path) + 1;
00095   if (path_len > bufsz) {
00096     ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
00097   }
00098   else {
00099     ink_strlcpy(buf, path, bufsz);
00100   }
00101 }
00102 
00103 char *
00104 Layout::relative_to(const char *dir, const char *file)
00105 {
00106   return layout_relative(dir, file);
00107 }
00108 
00109 void
00110 Layout::relative_to(char *buf, size_t bufsz, const char *dir, const char *file)
00111 {
00112   char path[PATH_NAME_MAX];
00113 
00114   if (ink_filepath_merge(path, PATH_NAME_MAX, dir, file, INK_FILEPATH_TRUENAME)) {
00115     int err = errno;
00116     
00117     if (err == EACCES) {
00118       ink_error("Cannot merge path '%s' above the root '%s'\n", file, dir);
00119     } else if (err == E2BIG) {
00120       ink_error("Exceeding file name length limit of %d characters\n", PATH_NAME_MAX);
00121     }
00122     else {
00123       
00124       ink_error("Cannot merge '%s' with '%s' error=%d\n", file, dir, err);
00125     }
00126     return;
00127   }
00128   size_t path_len = strlen(path) + 1;
00129   if (path_len > bufsz) {
00130     ink_error("Provided buffer is too small: %zu, required %zu\n", bufsz, path_len);
00131   }
00132   else {
00133     ink_strlcpy(buf, path, bufsz);
00134   }
00135 }
00136 
00137 Layout::Layout(const char *_prefix)
00138 {
00139   if (_prefix) {
00140     prefix = ats_strdup(_prefix);
00141   } else {
00142     char *env_path;
00143     char path[PATH_NAME_MAX];
00144     int  len;
00145 
00146     if ((env_path = getenv("TS_ROOT"))) {
00147       len = strlen(env_path);
00148       if ((len + 1) > PATH_NAME_MAX) {
00149         ink_error("TS_ROOT environment variable is too big: %d, max %d\n", len, PATH_NAME_MAX -1);
00150         return;
00151       }
00152       ink_strlcpy(path, env_path, sizeof(path));
00153       while (len > 1 && path[len - 1] == '/') {
00154         path[len - 1] = '\0';
00155         --len;
00156       }
00157     } else {
00158         
00159       ink_strlcpy(path, TS_BUILD_PREFIX, sizeof(path));
00160     }
00161 
00162     prefix = ats_strdup(path);
00163   }
00164   exec_prefix = layout_relative(prefix, TS_BUILD_EXEC_PREFIX);
00165   bindir = layout_relative(prefix, TS_BUILD_BINDIR);
00166   sbindir = layout_relative(prefix, TS_BUILD_SBINDIR);
00167   sysconfdir = layout_relative(prefix, TS_BUILD_SYSCONFDIR);
00168   datadir = layout_relative(prefix, TS_BUILD_DATADIR);
00169   includedir = layout_relative(prefix, TS_BUILD_INCLUDEDIR);
00170   libdir = layout_relative(prefix, TS_BUILD_LIBDIR);
00171   libexecdir = layout_relative(prefix, TS_BUILD_LIBEXECDIR);
00172   localstatedir = layout_relative(prefix, TS_BUILD_LOCALSTATEDIR);
00173   runtimedir = layout_relative(prefix, TS_BUILD_RUNTIMEDIR);
00174   logdir = layout_relative(prefix, TS_BUILD_LOGDIR);
00175   mandir = layout_relative(prefix, TS_BUILD_MANDIR);
00176   infodir = layout_relative(prefix, TS_BUILD_INFODIR);
00177   cachedir = layout_relative(prefix, TS_BUILD_CACHEDIR);
00178 
00179 }
00180 
00181 Layout::~Layout()
00182 {
00183   ats_free(prefix);
00184   ats_free(exec_prefix);
00185   ats_free(bindir);
00186   ats_free(sbindir);
00187   ats_free(sysconfdir);
00188   ats_free(datadir);
00189   ats_free(includedir);
00190   ats_free(libdir);
00191   ats_free(libexecdir);
00192   ats_free(localstatedir);
00193   ats_free(runtimedir);
00194   ats_free(logdir);
00195   ats_free(mandir);
00196   ats_free(infodir);
00197   ats_free(cachedir);
00198 }
00199