* @brief get paths used by the program
* @author Milan
*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
GNUNET_snprintf (fn,
sizeof(fn), "/proc/%u/exe", getpid ());
size = readlink (fn, lnk, sizeof (lnk)-1);
- if ((size == 0) || (size >= sizeof(lnk)-1))
+ if (size <= 0)
{
GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "readlink", fn);
- GNUNET_free (lnk);
return NULL;
}
+ GNUNET_assert (size < sizeof (lnk));
lnk[size] = '\0';
while ((lnk[size] != '/') && (size > 0))
size--;
if ((size < 4) || (lnk[size - 4] != '/'))
{
/* not installed in "/bin/" -- binary path probably useless */
- GNUNET_free (lnk);
return NULL;
}
lnk[size] = '\0';
}
#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;
-
- while (NULL != (end = strchr (pos, ':')))
+ pos = path;
+ while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
{
*end = '\0';
- sprintf (buf, "%s/%s", pos, "gnunetd");
+ 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, "gnunetd");
+ 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 */
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_
- ("Could not determine installation path for GNUnet. Set `%s' environment variable.\n"),
+ ("Could not determine installation path for %s. Set `%s' environment variable.\n"),
+ "GNUnet",
"GNUNET_PREFIX");
return NULL;
}
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;
return tmp;
}
-#if 0 /* keep Emacsens' auto-indent happy */
+
+/**
+ * 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
-#ifdef __cplusplus
-}
+ 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 */