+
+
+/**
+ * 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.
+ * W32: must not have an .exe suffix.
+ * @param check_suid input true if the binary should be checked for SUID (*nix)
+ * W32: checks if the program has sufficient privileges by executing this
+ * binary with the -d flag. -d omits a programs main loop and only
+ * executes all privileged operations in an binary.
+ * @param params parameters used for w32 privilege checking (can be NULL for != w32 )
+ * @return #GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32),
+ * #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, int check_suid, const char *params)
+{
+ struct stat statbuf;
+ char *p;
+ char *pf;
+#ifdef MINGW
+ char *binaryexe;
+
+ GNUNET_asprintf (&binaryexe, "%s.exe", binary);
+ if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binaryexe, GNUNET_NO,
+ NULL, NULL)) ||
+ (0 == strncmp (binary, "./", 2)) )
+ p = GNUNET_strdup (binaryexe);
+ else
+ {
+ p = get_path_from_PATH (binaryexe);
+ if (NULL != p)
+ {
+ GNUNET_asprintf (&pf, "%s/%s", p, binaryexe);
+ GNUNET_free (p);
+ p = pf;
+ }
+ }
+ GNUNET_free (binaryexe);
+#else
+ if ( (GNUNET_YES == GNUNET_STRINGS_path_is_absolute (binary, GNUNET_NO,
+ NULL, NULL)) ||
+ (0 == strncmp (binary, "./", 2)) )
+ p = GNUNET_strdup (binary);
+ else
+ {
+ p = get_path_from_PATH (binary);
+ if (NULL != p)
+ {
+ GNUNET_asprintf (&pf, "%s/%s", p, binary);
+ GNUNET_free (p);
+ p = pf;
+ }
+ }
+#endif
+ if (NULL == p)
+ {
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ _("Could not find binary `%s' in PATH!\n"),
+ binary);
+ return GNUNET_SYSERR;
+ }
+ if (0 != ACCESS (p, X_OK))
+ {
+ LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", p);
+ GNUNET_free (p);
+ return GNUNET_SYSERR;
+ }
+#ifndef MINGW
+ if (0 == getuid ())
+ {
+ /* as we run as root, we don't insist on SUID */
+ GNUNET_free (p);
+ return GNUNET_OK;
+ }