/* main.c
*
- * $Id: main.c,v 1.253 2002/07/06 16:47:17 gerald Exp $
+ * $Id: main.c,v 1.264 2002/09/23 19:09:49 oabad Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Richard Sharpe, 13-Feb-1999, added support for initializing structures
* needed by dissect routines
* Jeff Foster, 2001/03/12, added support tabbed hex display windowss
- *
- *
+ *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <gtk/gtk.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <errno.h>
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
#ifdef HAVE_IO_H
#include <io.h> /* open/close on win32 */
#endif
-#ifdef HAVE_DIRECT_H
-#include <direct.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-
-#include <signal.h>
-
#ifdef HAVE_LIBPCAP
#include <pcap.h>
#endif
#include "ui_util.h"
#include "image/clist_ascend.xpm"
#include "image/clist_descend.xpm"
+#include "../tap.h"
+#include "rpc_stat.h"
+#include "rpc_progs.h"
#ifdef WIN32
#include "capture-wpcap.h"
}
void
-match_selected_cb_replace(GtkWidget *w, gpointer data)
+match_selected_cb_replace_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-match_selected_cb_and(GtkWidget *w, gpointer data)
+match_selected_cb_and_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-match_selected_cb_or(GtkWidget *w, gpointer data)
+match_selected_cb_or_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-match_selected_cb_not(GtkWidget *w, gpointer data)
+match_selected_cb_not_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-match_selected_cb_and_not(GtkWidget *w, gpointer data)
+match_selected_cb_and_ptree_not(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-match_selected_cb_or_not(GtkWidget *w, gpointer data)
+match_selected_cb_or_ptree_not(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_replace(GtkWidget *w, gpointer data)
+prepare_selected_cb_replace_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_and(GtkWidget *w, gpointer data)
+prepare_selected_cb_and_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_or(GtkWidget *w, gpointer data)
+prepare_selected_cb_or_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_not(GtkWidget *w, gpointer data)
+prepare_selected_cb_not_ptree(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_and_not(GtkWidget *w, gpointer data)
+prepare_selected_cb_and_ptree_not(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
}
void
-prepare_selected_cb_or_not(GtkWidget *w, gpointer data)
+prepare_selected_cb_or_ptree_not(GtkWidget *w, gpointer data)
{
if (finfo_selected)
match_selected_cb_do((data ? data : w),
epan_dissect_free(edt);
}
-
+
return buf;
}
void
-match_selected_cb_replace2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_replace_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW,
}
void
-match_selected_cb_and2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_and_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW,
}
void
-match_selected_cb_or2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_or_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW,
}
void
-match_selected_cb_not2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_not_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW,
}
void
-match_selected_cb_and_not2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_and_plist_not(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW,
}
void
-match_selected_cb_or_not2(GtkWidget *w _U_, gpointer data)
+match_selected_cb_or_plist_not(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW,
}
void
-prepare_selected_cb_replace2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_replace_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_REPLACE,
}
void
-prepare_selected_cb_and2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_and_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_AND,
}
void
-prepare_selected_cb_or2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_or_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_OR,
}
void
-prepare_selected_cb_not2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_not_plist(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_NOT,
}
void
-prepare_selected_cb_and_not2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_and_plist_not(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_AND_NOT,
}
void
-prepare_selected_cb_or_not2(GtkWidget *w _U_, gpointer data)
+prepare_selected_cb_or_plist_not(GtkWidget *w _U_, gpointer data)
{
match_selected_cb_do(data,
MATCH_SELECTED_OR_NOT,
gboolean add_filter = TRUE;
gboolean free_filter = TRUE;
char *s;
-
+
g_assert(data);
s = g_strdup(gtk_entry_get_text(GTK_ENTRY(data)));
-
+
/* GtkCombos don't let us get at their list contents easily, so we maintain
our own filter list, and feed it to gtk_combo_set_popdown_strings when
a new filter is added. */
/* Attempt to convert to numbers */
double num1 = atof(text1);
double num2 = atof(text2);
-
+
gint col_fmt = cfile.cinfo.col_fmt[clist->sort_column];
-
+
if ((col_fmt == COL_NUMBER) || (col_fmt == COL_REL_TIME) || (col_fmt == COL_DELTA_TIME) ||
((col_fmt == COL_CLS_TIME) && (timestamp_type == RELATIVE)) ||
((col_fmt == COL_CLS_TIME) && (timestamp_type == DELTA)) ||
else
return 0;
}
-
+
else {
-
+
/* Compare text column */
if (!text2)
return (text1 != NULL);
}
/* What to do when a column is clicked */
-static void
+static void
packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
{
column_arrows *col_arrows = (column_arrows *) data;
int i;
-
+
gtk_clist_freeze(clist);
-
+
for (i = 0; i < cfile.cinfo.num_cols; i++) {
gtk_widget_hide(col_arrows[i].ascend_pm);
gtk_widget_hide(col_arrows[i].descend_pm);
}
-
+
if (column == clist->sort_column) {
if (clist->sort_type == GTK_SORT_ASCENDING) {
clist->sort_type = GTK_SORT_DESCENDING;
}
/* mark packets */
-static void
+static void
set_frame_mark(gboolean set, frame_data *frame, gint row) {
GdkColor fg, bg;
mark_frame(&cfile, frame);
color_t_to_gdkcolor(&fg, &prefs.gui_marked_fg);
color_t_to_gdkcolor(&bg, &prefs.gui_marked_bg);
+ gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
+ gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
} else {
unmark_frame(&cfile, frame);
- fg = BLACK;
- bg = WHITE;
+ gtk_clist_set_background(GTK_CLIST(packet_list), row, NULL);
+ gtk_clist_set_foreground(GTK_CLIST(packet_list), row, NULL);
}
file_set_save_marked_sensitive();
- gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
- gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
}
static void
packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_) {
-
+
GdkEventButton *event_button = (GdkEventButton *)event;
gint row, column;
if (cfile.current_frame) {
/* XXX hum, should better have a "cfile->current_row" here ... */
set_frame_mark(!cfile.current_frame->flags.marked,
- cfile.current_frame,
- gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
+ cfile.current_frame,
+ gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
cfile.current_frame));
}
}
for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
set_frame_mark(set,
fdata,
- gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));
+ gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));
}
}
tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_, gpointer user_data _U_)
{
field_info *finfo;
- gchar *help_str = NULL, len_str[] = ", 65536 bytes ";
+ gchar *help_str = NULL;
+ gchar len_str[2+10+1+5+1]; /* ", {N} bytes\0",
+ N < 4294967296 */
gboolean has_blurb = FALSE;
guint length = 0, byte_len;
GtkWidget *byte_view;
set_menus_for_selected_tree_row(TRUE);
if (finfo->hfinfo) {
- if (finfo->hfinfo->blurb != NULL &&
+ if (finfo->hfinfo->blurb != NULL &&
finfo->hfinfo->blurb[0] != '\0') {
has_blurb = TRUE;
length = strlen(finfo->hfinfo->blurb);
} else if (finfo->length == 1) {
strcpy (len_str, ", 1 byte");
} else {
- sprintf (len_str, ", %d bytes", finfo->length);
+ snprintf (len_str, sizeof len_str, ", %d bytes", finfo->length);
}
statusbar_pop_field_msg(); /* get rid of current help msg */
if (length) {
length += strlen(finfo->hfinfo->abbrev) + strlen(len_str) + 10;
help_str = g_malloc(sizeof(gchar) * length);
- sprintf(help_str, "%s (%s)%s",
+ sprintf(help_str, "%s (%s)%s",
(has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
finfo->hfinfo->abbrev, len_str);
statusbar_push_field_msg(help_str);
{
GtkWidget *byte_view;
const guint8 *data;
- guint len;
+ guint len;
/*
* Which byte view is displaying the current protocol tree
gtk_clist_set_selection_mode(GTK_CLIST(packet_list), GTK_SELECTION_BROWSE);
}
}
-
+
/* Set the font of the packet list window. */
void
set_plist_font(GdkFont *font)
do_quit();
}
-static void
+static void
print_usage(gboolean print_ver) {
if (print_ver) {
fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n",
comp_info_str->str);
- }
+ }
#ifdef HAVE_LIBPCAP
fprintf(stderr, "\n%s [ -vh ] [ -klpQS ] [ -a <capture autostop condition> ] ...\n",
PACKAGE);
#endif
}
-static void
+static void
show_version(void)
{
#ifdef WIN32
static gboolean
set_autostop_criterion(const char *autostoparg)
{
- u_char *p, *colonp;
+ guchar *p, *colonp;
colonp = strchr(autostoparg, ':');
if (colonp == NULL)
}
#endif
+/*
+ Once every 3 seconds we get a callback here which we use to update
+ the tap extensions. Since Gtk1 is single threaded we dont have to
+ worry about any locking or critical regions.
+ */
+static gint
+update_cb(gpointer data _U_)
+{
+ draw_tap_listeners(FALSE);
+ return 1;
+}
+void
+protect_thread_critical_region(void)
+{
+}
+void
+unprotect_thread_critical_region(void)
+{
+}
+
/* And now our feature presentation... [ fade to music ] */
int
main(int argc, char *argv[])
extern char pcap_version[];
#endif /* HAVE_PCAP_VERSION */
#endif /* HAVE_LIBPCAP */
-
+
#ifdef WIN32
- WSADATA wsaData;
+ WSADATA wsaData;
#endif
char *gpf_path, *cf_path, *df_path;
- const char *pf_path;
+ char *pf_path;
int gpf_open_errno, pf_open_errno, cf_open_errno, df_open_errno;
int err;
#ifdef HAVE_LIBPCAP
gint desk_x, desk_y;
gboolean prefs_write_needed = FALSE;
-#define OPTSTRING_INIT "a:b:B:c:f:hi:klm:nN:o:pP:Qr:R:Ss:t:T:w:v"
+#define OPTSTRING_INIT "a:b:B:c:f:hi:klm:nN:o:pP:Qr:R:Ss:t:T:w:vz:"
#ifdef HAVE_LIBPCAP
#ifdef WIN32
exit(0);
}
- /* Set the current locale according to the program environment.
+ /* this is to keep tap extensions updating once every 3 seconds */
+ gtk_timeout_add(3000, (GtkFunction)update_cb,(gpointer)NULL);
+
+ /* Set the current locale according to the program environment.
* We haven't localized anything, but some GTK widgets are localized
* (the file selection dialogue, for example).
* This also sets the C-language locale to the native environment. */
/* Let GTK get its args */
gtk_init (&argc, &argv);
-
+
/* Read the preference files. */
prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
/* Read the display filter file. */
read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
- /* Initialize the capture file struct */
- cfile.plist = NULL;
- cfile.plist_end = NULL;
- cfile.wth = NULL;
- cfile.filename = NULL;
- cfile.user_saved = FALSE;
- cfile.is_tempfile = FALSE;
- cfile.rfcode = NULL;
- cfile.dfilter = NULL;
- cfile.dfcode = NULL;
-#ifdef HAVE_LIBPCAP
- cfile.cfilter = g_strdup(EMPTY_FILTER);
-#endif
- cfile.iface = NULL;
- cfile.save_file = NULL;
- cfile.save_file_fd = -1;
- cfile.has_snap = FALSE;
- cfile.snap = WTAP_MAX_PACKET_SIZE;
- cfile.count = 0;
- col_init(&cfile.cinfo, prefs->num_cols);
+ init_cap_file(&cfile);
/* Assemble the compile-time options */
comp_info_str = g_string_new("");
#ifdef HAVE_LIBPCAP
if (set_autostop_criterion(optarg) == FALSE) {
fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
- exit(1);
+ exit(1);
}
#else
capture_option_specified = TRUE;
cfile.save_file_fd = atoi(optarg);
break;
#endif
+ case 'z':
+ if(!strncmp(optarg,"rpc,",4)){
+ if(!strncmp(optarg,"rpc,rtt,",8)){
+ int rpcprogram, rpcversion;
+ if(sscanf(optarg,"rpc,rtt,%d,%d",&rpcprogram,&rpcversion)==2){
+ gtk_rpcstat_init(rpcprogram,rpcversion);
+ } else {
+ fprintf(stderr, "ethereal: invalid \"-z rpc,rtt,<program>,<version>\" argument\n");
+ exit(1);
+ }
+ } else if(!strncmp(optarg,"rpc,programs",12)){
+ gtk_rpcprogs_init();
+ } else {
+ fprintf(stderr, "ethereal: invalid -z argument. Argument must be one of:\n");
+ fprintf(stderr, " \"-z rpc,rtt,<program>,<version>\"\n");
+ fprintf(stderr, " \"-z rpc,programs\"\n");
+ exit(1);
+ }
+ } else {
+ fprintf(stderr, "ethereal: invalid -z argument. Argument must be \"-z rpc,...\"\n");
+ exit(1);
+ }
+ break;
#ifdef _WIN32
#ifdef HAVE_LIBPCAP
sync_mode takes precedence;
c) it makes no sense to enable the ring buffer if the maximum
file size is set to "infinite". */
- if (cfile.save_file == NULL) {
+ if (save_file == NULL) {
fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
capture_opts.ringbuffer_on = FALSE;
}
/* Notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command
- line that its preferences have changed. */
+ line that their preferences have changed. */
prefs_apply_all();
#ifndef HAVE_LIBPCAP
if_list = get_interface_list(&err, err_str);
if (if_list == NULL) {
switch (err) {
-
+
case CANT_GET_INTERFACE_LIST:
fprintf(stderr, "ethereal: Can't get list of interfaces: %s\n",
err_str);
break;
-
+
case NO_INTERFACES_FOUND:
fprintf(stderr, "ethereal: There are no interfaces on which a capture can be done\n");
break;
}
#endif
- /* Build the column format array */
+ /* Build the column format array */
+ col_init(&cfile.cinfo, prefs->num_cols);
for (i = 0; i < cfile.cinfo.num_cols; i++) {
cfile.cinfo.col_fmt[i] = get_column_format(i);
cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
else if (capture_opts.snaplen < MIN_PACKET_SIZE)
capture_opts.snaplen = MIN_PACKET_SIZE;
}
-
+
/* Check the value range of the ringbuffer_num_files parameter */
if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
#endif
-
+
rc_file = get_persconffile_path(RC_FILE, FALSE);
gtk_rc_parse(rc_file);
argument. */
s = get_dirname(cf_name);
set_last_open_dir(s);
+ g_free(cf_name);
+ cf_name = NULL;
} else {
if (rfcode != NULL)
dfilter_free(rfcode);
simple_dialog(ESD_TYPE_WARN, NULL,
"Could not open your preferences file\n\"%s\": %s.", pf_path,
strerror(pf_open_errno));
+ g_free(pf_path);
+ pf_path = NULL;
}
/* If the user's capture filter file exists but we failed to open it,
if (start_capture) {
/* "-k" was specified; start a capture. */
do_capture(save_file);
+ if (save_file != NULL) {
+ /* Save the directory name for future file dialogs. */
+ s = get_dirname(save_file); /* Overwrites save_file */
+ set_last_open_dir(s);
+ g_free(save_file);
+ save_file = NULL;
+ }
}
else {
set_menus_for_capture_in_progress(FALSE);
documentation correctly, gdk_window_get_deskrelative_origin applies
mainly to Enlightenment and gdk_window_get_root_origin applies for
all other WMs.
-
+
The code below tries both routines, and picks the one that returns
the upper-left-most coordinates.
-
+
More info at:
http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html
prefs_write_needed = TRUE;
}
}
-
+
if (prefs->gui_geometry_save_size) {
if (top_level->window != NULL) {
/* XXX - Is this the "approved" method? */
prefs_write_needed = TRUE;
}
}
-
+
if (prefs_write_needed) {
write_prefs(&pf_path);
}
+ } else {
+ /* Ignore errors silently */
+ g_free(pf_path);
}
-
+
epan_cleanup();
g_free(rc_file);
{ "bold", "ultrabold" }
};
#define N_WEIGHTS (sizeof weight_map / sizeof weight_map[0])
-
+
char *
boldify(const char *font_name)
{
TRUE,
TRUE
};
-
- /* Main window */
+
+ /* Main window */
top_level = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name(top_level, "main window");
- gtk_signal_connect(GTK_OBJECT(top_level), "delete_event",
+ gtk_signal_connect(GTK_OBJECT(top_level), "delete_event",
GTK_SIGNAL_FUNC(main_window_delete_event_cb), NULL);
gtk_signal_connect (GTK_OBJECT (top_level), "realize",
GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list);
col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * cfile.cinfo.num_cols);
-
+
set_plist_sel_browse(prefs->gui_plist_sel_browse);
set_plist_font(m_r_font);
gtk_widget_set_name(packet_list, "packet list");
/* Right-justify the packet number column. */
if (cfile.cinfo.col_fmt[i] == COL_NUMBER)
- gtk_clist_set_column_justification(GTK_CLIST(packet_list), i,
+ gtk_clist_set_column_justification(GTK_CLIST(packet_list), i,
GTK_JUSTIFY_RIGHT);
}
gtk_widget_set_usize(packet_list, -1, pl_size);
gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event",
- GTK_SIGNAL_FUNC(popup_menu_handler),
+ GTK_SIGNAL_FUNC(popup_menu_handler),
gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event",
GTK_SIGNAL_FUNC(packet_list_button_pressed_cb), NULL);
GTK_SIGNAL_FUNC(display_filter_construct_cb), &args);
gtk_box_pack_start(GTK_BOX(stat_hbox), filter_bt, FALSE, TRUE, 0);
gtk_widget_show(filter_bt);
-
+
filter_cm = gtk_combo_new();
filter_list = g_list_append (filter_list, "");
gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), filter_list);
GTK_SHRINK, GTK_SHRINK, 0, 0);
gtk_widget_show(column_lb);
col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
- gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm,
+ gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm,
1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
if (i == 0) {
gtk_widget_show(col_arrows[i].ascend_pm);
if (dirname) {
len = strlen(dirname);
- if (dirname[len-1] != G_DIR_SEPARATOR) {
+ if (dirname[len-1] == G_DIR_SEPARATOR) {
+ last_open_dir = g_strconcat(dirname, NULL);
+ }
+ else {
last_open_dir = g_strconcat(dirname, G_DIR_SEPARATOR_S,
NULL);
}