aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2006-05-01 06:51:14 +0000
committerGuy Harris <guy@alum.mit.edu>2006-05-01 06:51:14 +0000
commit0dfbc73cbedd0d1b88218eb594f88bc98c583faf (patch)
treed89d037d5ac2d66e245060575b23e2f9f8437b3c
parent56728f40ede189fd4d6fed7e416cb9ec6cda3520 (diff)
Handle the case where we *can't* determine the pathname in which to find
programs, by reporting it with a dialog box that at least attempts to indicate what the problem is, and by giving up early on running dumpcap. svn path=/trunk/; revision=18051
-rw-r--r--capture_sync.c11
-rw-r--r--epan/filesystem.c145
-rw-r--r--epan/filesystem.h5
-rw-r--r--gtk/about_dlg.c6
-rw-r--r--gtk/main.c11
5 files changed, 127 insertions, 51 deletions
diff --git a/capture_sync.c b/capture_sync.c
index cd2c8d8452..091c782a97 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -241,6 +241,7 @@ sync_pipe_start(capture_options *capture_opts) {
enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
#endif
int sync_pipe_read_fd;
+ const char *progfile_dir;
char *exename;
int argc;
const char **argv;
@@ -251,6 +252,13 @@ sync_pipe_start(capture_options *capture_opts) {
capture_opts->fork_child = -1;
+ progfile_dir = get_progfile_dir();
+ if (progfile_dir == NULL) {
+ /* We don't know where to find dumpcap. */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "We don't know where to find dumpcap.");
+ return FALSE;
+ }
+
/* Allocate the string pointer array with enough space for the
terminating NULL pointer. */
argc = 0;
@@ -258,8 +266,7 @@ sync_pipe_start(capture_options *capture_opts) {
*argv = NULL;
/* take ethereal's absolute program path and replace "ethereal" with "dumpcap" */
- exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap",
- get_progfile_dir());
+ exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap", progfile_dir);
/* Make that the first argument in the argument list (argv[0]). */
argv = sync_pipe_add_arg(argv, &argc, exename);
diff --git a/epan/filesystem.c b/epan/filesystem.c
index 011adae1c6..dce300ae18 100644
--- a/epan/filesystem.c
+++ b/epan/filesystem.c
@@ -208,9 +208,10 @@ static char *progfile_dir;
/*
* Get the pathname of the directory from which the executable came,
- * and save it for future use.
+ * and save it for future use. Returns NULL on success, and a
+ * g_mallocated string containing an error on failure.
*/
-void
+char *
init_progfile_dir(const char *arg0
#ifdef _WIN32
_U_
@@ -223,6 +224,9 @@ init_progfile_dir(const char *arg0
TCHAR prog_pathname_w[_MAX_PATH+2];
size_t progfile_dir_len;
char *prog_pathname;
+ TCHAR *msg_w;
+ guchar *msg;
+ size_t msglen;
/*
* Attempt to get the full pathname of the currently running
@@ -239,12 +243,12 @@ init_progfile_dir(const char *arg0
* the file name of the executable, giving us the pathname
* of the directory where the executable resies
*
- * First, find the last "\\" in the directory, as that
+ * First, find the last "\" in the directory, as that
* marks the end of the directory pathname.
*
* XXX - Can the pathname be something such as
* "C:ethereal.exe"? Or is it always a full pathname
- * beginning with "\\" after the drive letter?
+ * beginning with "\" after the drive letter?
*/
dir_end = strrchr(prog_pathname, '\\');
if (dir_end != NULL) {
@@ -262,14 +266,50 @@ init_progfile_dir(const char *arg0
strncpy(path, prog_pathname, progfile_dir_len);
path[progfile_dir_len] = '\0';
progfile_dir = path;
+
+ return NULL; /* we succeeded */
+ } else {
+ /*
+ * OK, no \ - what do we do now?
+ */
+ return g_sprintf_alloc("No \\ in executable pathname \"%s\",
+ prog_pathname);
}
+ } else {
+ /*
+ * Oh, well. Return an indication of the error.
+ */
+ error = GetLastError();
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
+ /*
+ * Gak. We can't format the message.
+ */
+ return g_sprintf_alloc("GetModuleFileName failed: %u (FormatMessage failed: %u)",
+ error, GetLastError());
+ }
+ msg = utf_16to8(msg_w);
+ LocalFree(msg_w);
+ /*
+ * "FormatMessage()" "helpfully" sticks CR/LF at the
+ * end of the message. Get rid of it.
+ */
+ msglen = strlen(msg);
+ if (msglen >= 2) {
+ msg[msglen - 1] = '\0';
+ msg[msglen - 2] = '\0';
+ }
+ return g_sprintf_alloc("GetModuleFileName failed: %s (%u)",
+ msg, error);
}
#else
char *prog_pathname;
char *curdir;
long path_max;
+ char *pathstr;
char *path_start, *path_end;
size_t path_component_len;
+ char *retstr;
/*
* Try to figure out the directory in which the currently running
@@ -297,7 +337,8 @@ init_progfile_dir(const char *arg0
* We have no idea how big a buffer to
* allocate for the current directory.
*/
- return;
+ return g_strdup_printf("pathconf failed: %s\n",
+ strerror(errno));
}
curdir = g_malloc(path_max);
if (getcwd(curdir, sizeof curdir) == NULL) {
@@ -306,7 +347,8 @@ init_progfile_dir(const char *arg0
* with DATAFILE_DIR.
*/
g_free(curdir);
- return;
+ return g_strdup_printf("getcwd failed: %s\n",
+ strerror(errno));
}
path = g_malloc(strlen(curdir) + 1 + strlen(arg0) + 1);
strcpy(path, curdir);
@@ -321,7 +363,8 @@ init_progfile_dir(const char *arg0
* that's executable.
*/
prog_pathname = NULL; /* haven't found it yet */
- path_start = getenv("PATH");
+ pathstr = getenv("PATH");
+ path_start = pathstr;
if (path_start != NULL) {
while (*path_start != '\0') {
path_end = strchr(path_start, ':');
@@ -357,52 +400,66 @@ init_progfile_dir(const char *arg0
path_start = path_end;
g_free(path);
}
+ if (prog_pathname == NULL) {
+ /*
+ * Program not found in path.
+ */
+ return g_strdup_printf("\"%s\" not found in \"%s\"",
+ arg0, pathstr);
+ }
+ } else {
+ /*
+ * PATH isn't set.
+ * XXX - should we pick a default?
+ */
+ return g_strdup("PATH isn't set");
}
}
- if (prog_pathname != NULL) {
+ /*
+ * OK, we have what we think is the pathname
+ * of the program.
+ *
+ * First, find the last "/" in the directory,
+ * as that marks the end of the directory pathname.
+ */
+ dir_end = strrchr(prog_pathname, '/');
+ if (dir_end != NULL) {
/*
- * OK, we have what we think is the pathname
- * of the program.
- *
- * First, find the last "/" in the directory,
- * as that marks the end of the directory pathname.
+ * Found it. Strip off the last component,
+ * as that's the path of the program.
+ */
+ *dir_end = '\0';
+
+ /*
+ * Is there a "/.libs" at the end?
*/
dir_end = strrchr(prog_pathname, '/');
if (dir_end != NULL) {
- /*
- * Found it. Strip off the last component,
- * as that's the path of the program.
- */
- *dir_end = '\0';
-
- /*
- * Is there a "/.libs" at the end?
- */
- dir_end = strrchr(prog_pathname, '/');
- if (dir_end != NULL) {
- if (strcmp(dir_end, "/.libs") == 0) {
- /*
- * Yup, it's ".libs".
- * Strip that off; it's an
- * artifact of libtool.
- */
- *dir_end = '\0';
- }
+ if (strcmp(dir_end, "/.libs") == 0) {
+ /*
+ * Yup, it's ".libs".
+ * Strip that off; it's an
+ * artifact of libtool.
+ */
+ *dir_end = '\0';
}
-
- /*
- * OK, we have the path we want.
- */
- progfile_dir = prog_pathname;
- } else {
- /*
- * This "shouldn't happen"; we apparently
- * have no "/" in the pathname.
- * Just free up prog_pathname.
- */
- g_free(prog_pathname);
}
+
+ /*
+ * OK, we have the path we want.
+ */
+ progfile_dir = prog_pathname;
+ return NULL;
+ } else {
+ /*
+ * This "shouldn't happen"; we apparently
+ * have no "/" in the pathname.
+ * Just free up prog_pathname.
+ */
+ retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
+ g_free(prog_pathname);
+ return retstr;
}
#endif
}
diff --git a/epan/filesystem.h b/epan/filesystem.h
index 95c8a96444..650552e9a4 100644
--- a/epan/filesystem.h
+++ b/epan/filesystem.h
@@ -65,9 +65,10 @@ extern int test_for_fifo(const char *);
/*
* Get the pathname of the directory from which the executable came,
- * and save it for future use.
+ * and save it for future use. Returns NULL on success, and a
+ * g_mallocated string containing an error on failure.
*/
-extern void init_progfile_dir(const char *arg0);
+extern char *init_progfile_dir(const char *arg0);
/*
* Get the directory in which the program resides.
diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c
index 7d0401d0c0..41abeb370d 100644
--- a/gtk/about_dlg.c
+++ b/gtk/about_dlg.c
@@ -234,8 +234,10 @@ about_folders_page_new(void)
/* global conf */
constpath = get_datafile_dir();
- about_folders_row(table, "Global configuration", constpath,
- "\"dfilters\", \"preferences\", \"manuf\", ...");
+ if (constpath != NULL) {
+ about_folders_row(table, "Global configuration", constpath,
+ "\"dfilters\", \"preferences\", \"manuf\", ...");
+ }
/* system */
constpath = get_systemfile_dir();
diff --git a/gtk/main.c b/gtk/main.c
index daa70992eb..ba6e4f6b15 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -1876,6 +1876,7 @@ static void main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
int
main(int argc, char *argv[])
{
+ char *init_progfile_dir_error;
char *s;
int i;
int opt;
@@ -1928,7 +1929,7 @@ main(int argc, char *argv[])
/*
* Attempt to get the pathname of the executable file.
*/
- init_progfile_dir(argv[0]);
+ init_progfile_dir_error = init_progfile_dir(argv[0]);
/*
* Get credential information for later use.
@@ -2103,6 +2104,14 @@ main(int argc, char *argv[])
/* We won't come till here, if we had a "console only" command line parameter. */
splash_win = splash_new("Loading Ethereal ...");
+ if (init_progfile_dir_error != NULL) {
+ simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
+ "Can't get pathname of Ethereal: %s.\n"
+ "It won't be possible to capture traffic.\n"
+ "Report this to the Ethereal developers.",
+ init_progfile_dir_error);
+ g_free(init_progfile_dir_error);
+ }
splash_update(splash_win, "Init dissectors ...");