-dce
[oweals/gnunet.git] / src / util / os_installation.c
index 188401abbc40de24d32a14a1d8f2aff2ea9609f8..b82813d74dccc1efc70bf21551d0e95122fd07c9 100644 (file)
 #include <mach-o/dyld.h>
 #endif
 
+#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
+
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
+
 #if LINUX
 /**
  * Try to determine path by reading /proc/PID/exe
@@ -52,21 +56,21 @@ get_path_from_proc_maps ()
   char *lgu;
 
   GNUNET_snprintf (fn, sizeof (fn), "/proc/%u/maps", getpid ());
-  f = fopen (fn, "r");
+  f = FOPEN (fn, "r");
   if (f == NULL)
     return NULL;
   while (NULL != fgets (line, sizeof (line), f))
   {
-    if ((1 == sscanf (line,
-                      "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s",
-                      dir)) && (NULL != (lgu = strstr (dir, "libgnunetutil"))))
+    if ((1 ==
+         sscanf (line, "%*x-%*x %*c%*c%*c%*c %*x %*2u:%*2u %*u%*[ ]%s", dir)) &&
+        (NULL != (lgu = strstr (dir, "libgnunetutil"))))
     {
       lgu[0] = '\0';
-      fclose (f);
+      FCLOSE (f);
       return GNUNET_strdup (dir);
     }
   }
-  fclose (f);
+  FCLOSE (f);
   return NULL;
 }
 
@@ -84,7 +88,7 @@ get_path_from_proc_exe ()
   size = readlink (fn, lnk, sizeof (lnk) - 1);
   if (size <= 0)
   {
-    GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "readlink", fn);
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "readlink", fn);
     return NULL;
   }
   GNUNET_assert (size < sizeof (lnk));
@@ -108,15 +112,19 @@ get_path_from_proc_exe ()
 static char *
 get_path_from_module_filename ()
 {
-  char path[4097];
-  char *idx;
+  wchar_t path[4097];
+  char upath[4097];
+  wchar_t *idx;
 
-  GetModuleFileName (NULL, path, sizeof (path) - 1);
-  idx = path + strlen (path);
-  while ((idx > path) && (*idx != '\\') && (*idx != '/'))
+  GetModuleFileNameW (NULL, path, sizeof (path) - 1);
+  idx = path + wcslen (path);
+  while ((idx > path) && (*idx != L'\\') && (*idx != L'/'))
     idx--;
-  *idx = '\0';
-  return GNUNET_strdup (path);
+  *idx = L'\0';
+  upath[0] = '\0';
+  WideCharToMultiByte (CP_UTF8, 0, path, -1, upath, 4097, NULL, NULL);
+
+  return GNUNET_strdup (upath);
 }
 #endif
 
@@ -174,7 +182,7 @@ get_path_from_dyld_image ()
       path = _dyld_get_image_name (i);
       if (path != NULL && strlen (path) > 0)
       {
-        p = strdup (path);
+        p = GNUNET_strdup (path);
         s = p + strlen (p);
         while ((s > p) && (*s != '/'))
           s--;
@@ -247,7 +255,7 @@ get_path_from_GNUNET_PREFIX ()
   return NULL;
 }
 
-/*
+/**
  * @brief get the path to GNUnet bin/ or lib/, prefering the lib/ path
  * @author Milan
  *
@@ -286,10 +294,10 @@ os_get_gnunet_path ()
   if (ret != NULL)
     return ret;
   /* other attempts here */
-  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-              _
-              ("Could not determine installation path for %s.  Set `%s' environment variable.\n"),
-              "GNUnet", "GNUNET_PREFIX");
+  LOG (GNUNET_ERROR_TYPE_ERROR,
+       _
+       ("Could not determine installation path for %s.  Set `%s' environment variable.\n"),
+       "GNUnet", "GNUNET_PREFIX");
   return NULL;
 }
 
@@ -417,6 +425,11 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
     dirname =
         DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "icons" DIR_SEPARATOR_STR;
     break;
+  case GNUNET_OS_IPK_DOCDIR:
+    dirname =
+        DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "doc" DIR_SEPARATOR_STR \
+        "gnunet" DIR_SEPARATOR_STR;
+    break;
   default:
     GNUNET_free (execpath);
     return NULL;
@@ -435,7 +448,7 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
  * PATH environment variable as a search path.
  *
  * @param binary the name of the file to check
- * @return GNUNET_YES if the file is SUID, 
+ * @return GNUNET_YES if the file is SUID,
  *         GNUNET_NO if not SUID (but binary exists)
  *         GNUNET_SYSERR on error (no such binary or not executable)
  */
@@ -458,7 +471,7 @@ GNUNET_OS_check_helper_binary (const char *binary)
     GNUNET_free (p);
     p = pf;
   }
-  free (binaryexe);
+  GNUNET_free (binaryexe);
 #else
   p = get_path_from_PATH (binary);
   if (p != NULL)
@@ -470,30 +483,41 @@ GNUNET_OS_check_helper_binary (const char *binary)
 #endif
   if (p == NULL)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                _("Could not find binary `%s' in PATH!\n"), binary);
+    LOG (GNUNET_ERROR_TYPE_INFO, _("Could not find binary `%s' in PATH!\n"),
+         binary);
     return GNUNET_SYSERR;
   }
-  if (0 != STAT (p, &statbuf))
+  if (0 != ACCESS (p, X_OK))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-                _("stat (%s) failed: %s\n"), p, STRERROR (errno));
+    LOG (GNUNET_ERROR_TYPE_WARNING, _("access (%s, X_OK) failed: %s\n"), p,
+         STRERROR (errno));
     GNUNET_free (p);
     return GNUNET_SYSERR;
   }
 #ifndef MINGW
-  if ((0 != (statbuf.st_mode & S_ISUID)) && (statbuf.st_uid == 0))
+  if (0 == getuid ())
   {
+    /* as we run as root, we don't insist on SUID */
     GNUNET_free (p);
-    return GNUNET_YES;
+    return GNUNET_OK;
   }
-  if (0 == ACCESS (p, X_OK))
+#endif
+  if (0 != STAT (p, &statbuf))
   {
+    LOG (GNUNET_ERROR_TYPE_WARNING, _("stat (%s) failed: %s\n"), p,
+         STRERROR (errno));
     GNUNET_free (p);
-    return GNUNET_NO;
+    return GNUNET_SYSERR;
+  }
+#ifndef MINGW
+  if ((0 != (statbuf.st_mode & S_ISUID)) && (statbuf.st_uid == 0))
+  {
+    GNUNET_free (p);
+    return GNUNET_YES;
   }
+  /* binary exists, but not SUID */
   GNUNET_free (p);
-  return GNUNET_SYSERR;
+  return GNUNET_NO;
 #else
   GNUNET_free (p);
   rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
@@ -501,9 +525,8 @@ GNUNET_OS_check_helper_binary (const char *binary)
   {
     DWORD err = GetLastError ();
 
-    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-                "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n",
-                err);
+    LOG (GNUNET_ERROR_TYPE_INFO,
+         "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", err);
     return GNUNET_NO;           /* not running as administrator */
   }
   closesocket (rawsock);