}
#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;
return NULL;
path = GNUNET_strdup (p); /* because we write on it */
buf = GNUNET_malloc (strlen (path) + 20);
- pos = path;
-
+ 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);
}
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);
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 */
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 */