gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r3283 - in GNUnet/src: include setup util/os


From: grothoff
Subject: [GNUnet-SVN] r3283 - in GNUnet/src: include setup util/os
Date: Sun, 20 Aug 2006 21:29:19 -0700 (PDT)

Author: grothoff
Date: 2006-08-20 21:29:15 -0700 (Sun, 20 Aug 2006)
New Revision: 3283

Modified:
   GNUnet/src/include/gnunet_util_os.h
   GNUnet/src/setup/gnunet-setup.c
   GNUnet/src/util/os/dso.c
   GNUnet/src/util/os/installpath.c
Log:
cleaning up installpath (memory leak, cannot use cfg/ectx during startup, use 
in dso, code cleanup)

Modified: GNUnet/src/include/gnunet_util_os.h
===================================================================
--- GNUnet/src/include/gnunet_util_os.h 2006-08-21 02:15:09 UTC (rev 3282)
+++ GNUnet/src/include/gnunet_util_os.h 2006-08-21 04:29:15 UTC (rev 3283)
@@ -269,12 +269,12 @@
  * List of install paths
  */
 enum InstallPathKind {
-  PREFIX,
-  BINDIR,
-  LIBDIR,
-  GNDATADIR,
-  PACKAGEDATADIR,
-  LOCALEDIR };
+  IPK_PREFIX,
+  IPK_BINDIR,
+  IPK_LIBDIR,
+  IPK_DATADIR,
+  IPK_LOCALEDIR 
+};
 
 /**
  * @brief get the path to a specific app dir
@@ -283,9 +283,7 @@
  * @param cfg the context to get configuration values from
  * @return a pointer to the dir path (to be freed by the caller)
  */
-char * os_get_installation_path(struct GE_Context * ectx,
-                                struct GC_Configuration * cfg,
-                                enum InstallPathKind dirkind);
+char * os_get_installation_path(enum InstallPathKind dirkind);
 
 
 

Modified: GNUnet/src/setup/gnunet-setup.c
===================================================================
--- GNUnet/src/setup/gnunet-setup.c     2006-08-21 02:15:09 UTC (rev 3282)
+++ GNUnet/src/setup/gnunet-setup.c     2006-08-21 04:29:15 UTC (rev 3283)
@@ -200,16 +200,14 @@
   if(0 == ACCESS(filename, F_OK)) 
     GC_parse_configuration(cfg,
                           filename);
-  dirname = os_get_installation_path(ectx,
-                                    cfg,
-                                    GNDATADIR);
-  specname = MALLOC(strlen(dirname) + strlen("/config-daemon.scm") + 1);
+  dirname = os_get_installation_path(IPK_DATADIR);
+  specname = MALLOC(strlen(dirname) + strlen("config-daemon.scm") + 1);
   strcpy(specname, dirname);
   FREE(dirname);
   if (config_daemon) 
-    strcat(specname, "/config-daemon.scm");
+    strcat(specname, "config-daemon.scm");
   else 
-    strcat(specname, "/config-client.scm");  
+    strcat(specname, "config-client.scm");  
   gns = GNS_load_specification(ectx,
                               cfg,
                               specname); 

Modified: GNUnet/src/util/os/dso.c
===================================================================
--- GNUnet/src/util/os/dso.c    2006-08-21 02:15:09 UTC (rev 3282)
+++ GNUnet/src/util/os/dso.c    2006-08-21 04:29:15 UTC (rev 3283)
@@ -38,68 +38,7 @@
 
 static char * old_dlsearchpath;
 
-static char * getPluginPath() {
-#if LINUX
-  char * fn;
-  char * lnk;
-  size_t size;
 
-  fn = MALLOC(64);
-  SNPRINTF(fn, 
-          64,
-          "/proc/%u/exe",
-          getpid());
-  lnk = MALLOC(1024);
-  size = readlink(fn, lnk, 1023);
-  if ( (size == 0) || (size >= 1024) ) {
-    GE_LOG_STRERROR_FILE(NULL,
-                        GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
-                        "readlink",
-                        fn);
-    FREE(fn);
-    FREE(lnk);
-    return NULL;
-  }
-  FREE(fn);
-  lnk[size] = '\0';
-  while ( (lnk[size] != '/') &&
-         (size > 0) )
-    size--;
-  if ( (size < 4) ||
-       (lnk[size-4] != '/') ) {
-    GE_LOG(NULL,
-          GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
-          _("Cannot determine plugin path (have, application must be installed 
in directory ending with `%s', have `%s').\n"),
-          "bin/",
-          lnk);
-    FREE(lnk);
-    return NULL;
-  }
-  lnk[  size] = '\0';
-  lnk[--size] = 'b';
-  lnk[--size] = 'i';
-  lnk[--size] = 'l';
-  return lnk;
-#elif WINDOWS
-  char *path, *idx;
-  
-  path = MALLOC(4097);
-  GetModuleFileName(NULL, path, 4096);
-  idx = path + strlen(idx);
-  while ( (idx > path) && 
-         (path != '\\') &&
-         (path != '/') )
-    idx++;
-  *idx = 0;
-  
-  return path;  
-#else
-/* FIXME/PORTME to other platforms */
-#error Missing port: getPluginPath()
-  Missing port: getPluginPath();
-#endif
-}
-
 /* using libtool, needs init! */
 void __attribute__ ((constructor)) gnc_ltdl_init(void) {
   int err;
@@ -116,14 +55,11 @@
   opath = lt_dlgetsearchpath();
   if (opath != NULL)
     old_dlsearchpath = STRDUP(opath);
-  path = getPluginPath();
-  if (path == NULL) {
-    fprintf(stderr,
-           _("Fatal error: could not determine path for plugins!\n"));    
-    abort();
+  path = os_get_installation_path(IPK_LIBDIR);
+  if (path != NULL) {
+    lt_dlsetsearchpath(path);
+    FREE(path);  
   }
-  lt_dlsetsearchpath(path);
-  FREE(path);  
 }
 
 void __attribute__ ((destructor)) gnc_ltdl_fini(void) {
@@ -132,7 +68,7 @@
     FREE(old_dlsearchpath);
     old_dlsearchpath = NULL;
   }
-  lt_dlexit ();
+  lt_dlexit();
 }
 
 struct PluginHandle * 

Modified: GNUnet/src/util/os/installpath.c
===================================================================
--- GNUnet/src/util/os/installpath.c    2006-08-21 02:15:09 UTC (rev 3282)
+++ GNUnet/src/util/os/installpath.c    2006-08-21 04:29:15 UTC (rev 3283)
@@ -39,226 +39,209 @@
 #include "platform.h"
 #include "gnunet_util_string.h"
 #include "gnunet_util_config.h"
+#include "gnunet_util_disk.h"
 #include "gnunet_util_os.h"
 
-/* assumed math size for a path
- * used to try allocating less memory than PATH_MAX */
-#define PATH_TRY 96
-
-
-/*
- * @brief get the path to the executable, including the binary itself
- * @author Milan
- * @param ectx the context to report the errors to
- * @param cfg the context to get configuration values from
- * @return a pointer to the executable path, owned by the function (don't free 
it)
+#if LINUX
+/**
+ * Try to determine path by reading /proc/PID/exe
  */
-static char *os_get_exec_path(struct GE_Context * ectx,
-                              struct GC_Configuration * cfg) {
-  static char *execpath = NULL; /* save it between calls */
-  int found;
+static char * 
+get_path_from_proc_exe() {
+  char * fn;
+  char * lnk;
+  size_t size;
 
-#ifdef WINDOWS
-/* FIXME MINGW: get the path
- * set found and execpath so the end of the function is valid */
- 
- found = 0;
-#else /* Should work on all Unices, else we won't run */
-  /* FIXME: we assume PATH_MAX is the same for all used files */
-  const long path_max = pathconf(".", _PC_PATH_MAX);
-  const long name_max = pathconf(".", _PC_NAME_MAX);
-
-  char *tmp, *path1, *path2, *path3;
-  size_t size, size1, size2;
-  struct stat dummy_stat;
-
-  if(execpath) /* already got the path, don't work more */
-     return execpath;
-
-  /* I. get the path from /proc */
-  tmp = MALLOC(name_max+10);
-  SNPRINTF(tmp, 
-          name_max+10,
+  fn = MALLOC(64);
+  SNPRINTF(fn, 
+          64,
           "/proc/%u/exe",
           getpid());
-  path1 = MALLOC(PATH_TRY); /* let's try with a little buffer */
-  size = readlink(tmp, path1, PATH_TRY-1);
-  if(size == PATH_TRY) { /* buffer too small */
-    path1 = REALLOC(path1, path_max);
-    size = readlink(tmp, path1, path_max-1); }
-  FREE(tmp);
-  if (size > 0) { /* this method worked well */
-    path1[size] = '\0';
+  lnk = MALLOC(1024);
+  size = readlink(fn, lnk, 1023);
+  if ( (size == 0) || (size >= 1024) ) {
+    GE_LOG_STRERROR_FILE(NULL,
+                        GE_ERROR | GE_USER | GE_ADMIN | GE_IMMEDIATE,
+                        "readlink",
+                        fn);
+    FREE(fn);
+    FREE(lnk);
+    return NULL;
+  }
+  FREE(fn);
+  lnk[size] = '\0';
+  while ( (lnk[size] != '/') &&
+         (size > 0) )
+    size--;
+  if ( (size < 4) ||
+       (lnk[size-4] != '/') ) {
+    /* not installed in "/bin/" -- binary path probably useless */
+    FREE(lnk);
+    return NULL;
+  }
+  lnk[size] = '\0';
+  return lnk;
+}
+#endif
 
-    execpath = STRDUP(path1);
-    FREE(path1);
-    return execpath; }
+#if WINDOWS
+/**
+ * Try to determine path with win32-specific function
+ */
+char * get_path_from_module_filename() {
+  char * path;
+  char * idx;
+  
+  path = MALLOC(4097);
+  GetModuleFileName(NULL, path, 4096);
+  idx = path + strlen(idx);
+  while ( (idx > path) && 
+         (path != '\\') &&
+         (path != '/') )
+    idx++;
+  *idx = '\0';
+  return path;  
+}
+#endif
 
-  FREE(path1);
+static char * 
+get_path_from_PATH() {
+  char * path;
+  char * pos;
+  char * end;
+  char * buf;
+  const char * p;
+  size_t size;
 
+  p = getenv("PATH");
+  if (p == NULL)
+    return NULL;
+  path = STRDUP(p); /* because we write on it */
+  buf = MALLOC(strlen(path) + 20);
+  size = strlen(path);
+  pos = path;
 
-  /* II. reading /proc failed, trying with argv[0] */
-  found = 0;
-  GC_get_configuration_value_string(cfg, 
-                                   "ARGV", 
-                                   "0", 
-                                   "gnunetd",
-                                   &path1);
-
-  /* 1. absolute path */
-  if (*path1 == '/') {
-    execpath = path1;
-    found = 1; }
-
-  /* 2. relative path */
-  else if(strchr(path1, '/')) {
-    tmp = MALLOC(PATH_TRY); /* let's try with a little buffer */
-    if( !getcwd(tmp, PATH_TRY-1) ) { /* buffer too small */
-      tmp = REALLOC(tmp, path_max);
-      getcwd(tmp, path_max-1); }
-    
-    if( (*path1 == '.') && (*(path1+1) == '.') ) { /* ../ so go one level 
higher */
-      strchr(tmp, '/')[0] = '\0';
-      path2 = path1+3; 
-    } /* and jump */
-    else if (*path1 == '.') /* ./ so just jump */
-      path2 = path1+2;
-    else
-      path2 = path1;
- 
-    if(tmp[strlen(tmp)-1] == '/') /* just to clean final '/' */
-      tmp[strlen(tmp)-1] = '\0';
-
-    execpath = MALLOC(strlen(tmp)+strlen(path1)+2);
-    sprintf(execpath, "%s/%s", tmp, path1);
-    FREE(tmp);
-    FREE(path1);
-    found = 1; }
-
-  /* 3. program in PATH */
-  else {
-    path3 = MALLOC(PATH_TRY);
-    tmp = STRDUP(getenv("PATH")); /* because we write on it */
-    size = strlen(path1);
-    size1 = PATH_TRY;
-
-    while(strchr(tmp, ':')) {
-      path2 = (strrchr(tmp, ':')+1);
-      size2 = strlen(path2)+size+2;
-      if(size2 > size1) {
-        path3 = REALLOC(path3, size2); /* not nice, but best to do: */
-        size1 = size2; }               /* malloc PATH_MAX bytes is too much */
-
-      sprintf(path3, "%s/%s", path2, path1);
-      if(stat(path3, &dummy_stat) == 0) {
-        found = 1;
-        break; }
-       *(path2-1) = '\0';
+  while (NULL != (end = strchr(pos, ':'))) {
+    *end = '\0';
+    sprintf(buf, "%s/%s", pos, "gnunetd");
+    if (disk_file_test(NULL, buf) == YES) {
+      pos = STRDUP(pos);
+      FREE(buf);
+      FREE(path);
+      return pos;
     }
+    pos = end + 1;
+  }
+  sprintf(buf, "%s/%s", pos, "gnunetd");
+  if (disk_file_test(NULL, buf) == YES) {
+    pos = STRDUP(pos);
+    FREE(buf);
+    FREE(path);
+    return pos;
+  }
+  FREE(buf);
+  FREE(path);
+  return NULL;
+}
 
-    if(!found) { /* first dir in PATH */
-      path2 = tmp;
-      sprintf(path3, "%s/%s", path2, path1);
-      if(STAT(path3, &dummy_stat) == 0)
-        found = 1; }
+static char * 
+get_path_from_GNUNET_PREFIX() {
+  const char * p;
 
-    execpath = STRDUP(path3);
+  p = getenv("GNUNET_PREFIX");
+  if (p != NULL)
+    return STRDUP(p);
+  return NULL;
+}
 
-    FREE(path1);
-    FREE(path3);
-    FREE(tmp); }
+/*
+ * @brief get the path to the executable, including the binary itself
+ * @author Milan
+ *
+ * @return a pointer to the executable path, or NULL on error
+ */
+static char *
+os_get_exec_path() {
+  char * ret;
 
+  ret = get_path_from_GNUNET_PREFIX();
+  if (ret != NULL)
+    return ret;  
+#if LINUX  
+  ret = get_path_from_proc_exe();
+  if (ret != NULL)
+    return ret;
 #endif
-  if(found) {
-      return execpath; }
-  else { /* we can do nothing to run normally */
-    GE_LOG(ectx, /* This error should not occur on standard Unices */
-          GE_ERROR | GE_USER | GE_ADMIN | GE_DEVELOPER | GE_IMMEDIATE,
-          _("Cannot determine the path to the executable, your system may be 
broken or not supported.\n"));
-     return NULL; }
+#if WINDOWS
+  ret = get_path_from_module_filename();
+  if (ret != NULL)
+    return ret;
+#endif
+  ret = get_path_from_PATH();
+  if (ret != NULL)
+    return ret;
+  /* other attempts here */
+  return NULL;
 }
 
+
+
 /*
  * @brief get the path to a specific app dir
  * @author Milan
- * @param ectx the context to report the errors to
- * @param cfg the context to get configuration values from
  * @return a pointer to the dir path (to be freed by the caller)
  */
-char * os_get_installation_path(struct GE_Context * ectx,
-                                struct GC_Configuration * cfg,
-                                enum InstallPathKind dirkind) {
-
-  static char *prefix = NULL; /*save it between calls */
-
-  unsigned int n;
+char * os_get_installation_path(enum InstallPathKind dirkind) {
+  size_t n;
   const char * dirname;
-  char *execpath;
-  char *tmp;
-  char *ptr;
+  char * execpath;
+  char * tmp;
 
-  if(!prefix) { /* if we already got the prefix once, don't work more */
-    if( !(execpath = os_get_exec_path(ectx, cfg)) )
-      return NULL;
+  execpath = os_get_exec_path();
+  if (execpath == NULL)
+    return NULL;
   
-    tmp = STRDUP(execpath);
-    ptr = strrchr(tmp, DIR_SEPARATOR); /* get prefix from prefix/bin/app */
-    *ptr = '\0';
-    n = 1;
-    while( *(ptr-n) == DIR_SEPARATOR ) { /* manage "//" in the path */
-      *(ptr-n) = '\0';
-      n++; }
-    ptr = strrchr(tmp, DIR_SEPARATOR);
-
-    if( !( (*(ptr+1) == 'b')
-          && (*(ptr+2) == 'i')
-          && (*(ptr+3) == 'n')) )
-      GE_LOG(ectx,
-             GE_WARNING | GE_ADMIN | GE_IMMEDIATE,
-             _("GNUnet executables are not in a directory named 'bin'. This 
may signal a broken installation.\n"));
-
-    *(ptr+1) = '\0';
-    n = 1;
-    while( *(ptr-n) == DIR_SEPARATOR ) { /* same, but keep the final '/' */
-      *(ptr-n+1) = '\0';
-      n++; }
-
-    if(*tmp == '\0') { /* no prefix at all */
-      GE_LOG(ectx,
-             GE_ERROR | GE_USER | GE_ADMIN | GE_DEVELOPER | GE_IMMEDIATE,
-             _("Cannot determine the installation prefix. Unknown error.\n"));
-     return NULL; }
-
-    prefix = STRDUP(tmp);
-    FREE(tmp); }
-
-
+  n = strlen(execpath);
+  if (n == 0) { 
+    /* should never happen, but better safe than sorry */
+    FREE(execpath);
+    return NULL;
+  }
+  if (execpath[n-1] == DIR_SEPARATOR) 
+    execpath[--n] = '\0';  
+  
+  if ( (n > 3) &&
+       (0 == strcmp(&execpath[n-3], "bin")) ) {
+    /* good, strip of '/bin'! */
+    execpath[n-3] = '\0';
+    n -= 3;
+  }
   switch(dirkind) {
-    case PREFIX:
-      dirname = "";
-      break;
-    case BINDIR:
-      dirname = "bin/";
-      break;
-    case LIBDIR:
-      dirname = "lib/GNUnet/";
-      break;
-    case PACKAGEDATADIR:
-    case GNDATADIR:
-      dirname = "share/GNUnet/";
-      break;
-    case LOCALEDIR:
-      dirname = "share/locale/";
-      break;
-    default:
-      return NULL; }
-
-  tmp = MALLOC(strlen(prefix)+strlen(dirname)+1);
+  case IPK_PREFIX:
+    dirname = "";
+    break;
+  case IPK_BINDIR:
+    dirname = "bin/";
+    break;
+  case IPK_LIBDIR:
+    dirname = "lib/GNUnet/";
+    break;
+  case IPK_DATADIR:
+    dirname = "share/GNUnet/";
+    break;
+  case IPK_LOCALEDIR:
+    dirname = "share/locale/";
+    break;
+  default:
+    FREE(execpath);
+    return NULL; 
+  }
+  tmp = MALLOC(strlen(execpath)+strlen(dirname)+1);
   sprintf(tmp, 
          "%s%s",
-         prefix,
+         execpath,
          dirname);
-  FREE(prefix);
+  FREE(execpath);
   return tmp;
 }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]