LRN: Fix automake deps to allow -j* builds again
[oweals/gnunet.git] / src / util / os_installation.c
index 2b75a11961febac3895e21a96a5f7b7ec2ee9508..36627a8d8834ddbf621f37bbfef18bed1ca978a6 100644 (file)
@@ -193,8 +193,15 @@ get_path_from_dyld_image ()
 }
 #endif
 
+/**
+ * Return the actual path to a file found in the current
+ * PATH environment variable.
+ *
+ * @param binary the name of the file to find
+ * @return path to binary, NULL if not found
+ */
 static char *
-get_path_from_PATH ()
+get_path_from_PATH (const char *binary)
 {
   char *path;
   char *pos;
@@ -207,12 +214,11 @@ get_path_from_PATH ()
     return NULL;
   path = GNUNET_strdup (p);     /* because we write on it */
   buf = GNUNET_malloc (strlen (path) + 20);
-  pos = path;
-
-  while (NULL != (end = strchr (pos, ':')))
+  pos = path;  
+  while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
     {
       *end = '\0';
-      sprintf (buf, "%s/%s", pos, "gnunet-arm");
+      sprintf (buf, "%s/%s", pos, binary);
       if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
         {
           pos = GNUNET_strdup (pos);
@@ -222,7 +228,7 @@ get_path_from_PATH ()
         }
       pos = end + 1;
     }
-  sprintf (buf, "%s/%s", pos, "gnunet-arm");
+  sprintf (buf, "%s/%s", pos, binary);
   if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
     {
       pos = GNUNET_strdup (pos);
@@ -281,7 +287,7 @@ os_get_gnunet_path ()
   if (ret != NULL)
     return ret;
 #endif
-  ret = get_path_from_PATH ();
+  ret = get_path_from_PATH ("gnunet-arm");
   if (ret != NULL)
     return ret;
   /* other attempts here */
@@ -416,6 +422,10 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
         DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "locale"
         DIR_SEPARATOR_STR;
       break;
+    case GNUNET_OS_IPK_ICONDIR:
+      dirname =
+        DIR_SEPARATOR_STR "share" DIR_SEPARATOR_STR "icons" DIR_SEPARATOR_STR;
+      break;
     default:
       GNUNET_free (execpath);
       return NULL;
@@ -426,4 +436,90 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind)
   return tmp;
 }
 
+
+/**
+ * Check whether an executable exists and possibly
+ * if the suid bit is set on the file.
+ * Attempts to find the file using the current
+ * PATH environment variable as a search path.
+ *
+ * @param binary the name of the file to check
+ * @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)
+ */
+int
+GNUNET_OS_check_helper_binary (const char *binary)
+{
+  struct stat statbuf;
+  char *p;
+  char *pf;
+#ifdef MINGW
+  SOCKET rawsock;
+  char *binaryexe;
+
+  GNUNET_asprintf (&binaryexe, "%s.exe", binary);
+  p = get_path_from_PATH (binaryexe);
+  if (p != NULL)
+    {
+      GNUNET_asprintf (&pf, "%s/%s", p, binaryexe);
+      GNUNET_free (p);
+      p = pf;
+    }
+  free (binaryexe);
+#else
+  p = get_path_from_PATH (binary);
+  if (p != NULL)
+    {
+      GNUNET_asprintf (&pf, "%s/%s", p, binary);
+      GNUNET_free (p);
+      p = pf;
+    }
+#endif
+  if (p == NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                 _("Could not find binary `%s' in PATH!\n"),
+                 binary);
+      return GNUNET_SYSERR;
+    }
+  if (0 != STAT (p, &statbuf))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 
+                 _("stat (%s) 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) )
+    {
+      GNUNET_free (p);
+      return GNUNET_YES;
+    }
+  if (0 == ACCESS (p, X_OK))
+    {
+      GNUNET_free (p);
+      return GNUNET_NO;
+    }
+  GNUNET_free (p);
+  return GNUNET_SYSERR;
+#else
+  GNUNET_free (p);
+  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == rawsock)
+    {
+      DWORD err = GetLastError ();
+      GNUNET_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);
+  return GNUNET_YES;
+#endif
+}
+
+
 /* end of os_installation.c */