diff options
Diffstat (limited to 'uzbl.c')
-rw-r--r-- | uzbl.c | 523 |
1 files changed, 335 insertions, 188 deletions
@@ -43,6 +43,12 @@ #include <sys/types.h> #include <unistd.h> #include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <sys/types.h> +#include <fcntl.h> +#include <sys/socket.h> +#include <sys/un.h> /* housekeeping / internal variables */ static GtkWidget* main_window; @@ -50,19 +56,22 @@ static GtkWidget* mainbar; static GtkWidget* mainbar_label; static WebKitWebView* web_view; static gchar* main_title; -static gchar selected_url[500]; +static gchar selected_url[500] = "\0"; static gint load_progress; static Window xwin = 0; -static char fifopath[64]; +static char fifo_path[64]; +static char socket_path[108]; /* state variables (initial values coming from command line arguments but may be changed later) */ static gchar* uri = NULL; static gchar* config_file = NULL; +static gchar config_file_path[500]; static gboolean verbose = FALSE; /* settings from config: group behaviour */ static gchar* history_handler = NULL; -static gchar* fifodir = NULL; +static gchar* fifo_dir = NULL; +static gchar* socket_dir = NULL; static gchar* download_handler = NULL; static gboolean always_insert_mode = FALSE; static gboolean show_status = FALSE; @@ -70,16 +79,18 @@ static gboolean insert_mode = FALSE; static gboolean status_top = FALSE; static gchar* modkey = NULL; static guint modmask = 0; +static gchar* home_page = NULL; -typedef struct { - char *binding; - char *action; - char *param; -} Binding; +/* settings from config: group bindings, key -> action */ +static GHashTable *bindings; -/* settings from config: group bindings_internal */ -static Binding bindings[MAX_BINDINGS]; -static int num_bindings = 0; +/* command list: name -> Command */ +static GHashTable *commands; + +typedef struct { + char *name; + char *param; +} Action; /* commandline arguments (set initial values for the state variables) */ static GOptionEntry entries[] = @@ -90,12 +101,7 @@ static GOptionEntry entries[] = { NULL, 0, 0, 0, NULL, NULL, NULL } }; -/* for internal list of commands */ -typedef struct -{ - const char *command; - void (*func)(WebKitWebView*, const char *); -} Command; +typedef void (*Command)(WebKitWebView*, const char *); /* XDG stuff */ static char *XDG_CONFIG_HOME_default[256]; @@ -107,15 +113,31 @@ update_title (GtkWindow* window); static void load_uri ( WebKitWebView * web_view, const gchar * uri); +static void +new_window_load_uri (const gchar * uri); + +static void +go_home (WebKitWebView *page, const char *param); + +static void +close_uzbl (WebKitWebView *page, const char *param); + static gboolean run_command(const char *command, const char *args); static void spawn(WebKitWebView *web_view, const char *param); +static void +free_action(gpointer action); + +static Action* +new_action(const gchar *name, const gchar *param); + /* --- CALLBACKS --- */ + static gboolean new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequest *request, WebKitWebNavigationAction *navigation_action, WebKitWebPolicyDecision *policy_decision, gpointer user_data) { (void) web_view; @@ -125,36 +147,44 @@ new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNetworkRequ (void) user_data; const gchar* uri = webkit_network_request_get_uri (request); printf("New window requested -> %s \n", uri); - gboolean result; - GString* to_execute = g_string_new (""); - g_string_printf (to_execute, "uzbl --uri '%s'", uri); - result = g_spawn_command_line_async (to_execute->str, NULL); - if (!result) { - g_string_printf (to_execute, "./uzbl --uri '%s'", uri); - result = g_spawn_command_line_async (to_execute->str, NULL); - } - g_string_free (to_execute, TRUE); + new_window_load_uri(uri); return (FALSE); } +WebKitWebView* +create_web_view_cb (WebKitWebView *web_view, WebKitWebFrame *frame, gpointer user_data) { + (void) web_view; + (void) frame; + (void) user_data; + if (selected_url[0]!=0) { + printf("\nNew web view -> %s\n",selected_url); + new_window_load_uri(selected_url); + } else { + printf("New web view -> %s\n","Nothing to open, exiting"); + } + return (NULL); +} + static gboolean download_cb (WebKitWebView *web_view, GObject *download, gpointer user_data) { (void) web_view; (void) user_data; - const gchar* uri = webkit_download_get_uri ((WebKitDownload*)download); - printf("Download -> %s\n",uri); - run_command(download_handler, uri); + if (download_handler) { + const gchar* uri = webkit_download_get_uri ((WebKitDownload*)download); + printf("Download -> %s\n",uri); + run_command(download_handler, uri); + } return (FALSE); } static void toggle_status_cb (WebKitWebView* page, const char *param) { (void)page; - (void)param; + (void)param; if (show_status) { - gtk_widget_hide(mainbar); + gtk_widget_hide(mainbar); } else { - gtk_widget_show(mainbar); + gtk_widget_show(mainbar); } show_status = !show_status; update_title (GTK_WINDOW (main_window)); @@ -237,22 +267,56 @@ VIEWFUNC(go_forward) /* -- command to callback/function map for things we cannot attach to any signals */ // TODO: reload, home, quit -static Command commands[] = + +static struct {char *name; Command command;} cmdlist[] = { { "back", view_go_back }, { "forward", view_go_forward }, { "reload", view_reload, }, //Buggy + { "refresh", view_reload, }, /* for convenience, will change */ { "stop", view_stop_loading, }, { "zoom_in", view_zoom_in, }, //Can crash (when max zoom reached?). { "zoom_out", view_zoom_out, }, { "uri", load_uri }, { "toggle_status", toggle_status_cb }, - { "spawn", spawn }, -//{ "get uri", &webkit_web_view_get_uri}, + { "spawn", spawn }, + { "home", go_home }, + { "exit", close_uzbl }, }; +static void +commands_hash(void) +{ + unsigned int i; + commands = g_hash_table_new(g_str_hash, g_str_equal); + + for (i = 0; i < LENGTH(cmdlist); i++) + g_hash_table_insert(commands, cmdlist[i].name, cmdlist[i].command); +} + /* -- CORE FUNCTIONS -- */ - + +void +free_action(gpointer act) { + Action *action = (Action*)act; + g_free(action->name); + if (action->param) + g_free(action->param); + g_free(action); +} + +Action* +new_action(const gchar *name, const gchar *param) { + Action *action = g_new(Action, 1); + + action->name = g_strdup(name); + if (param) + action->param = g_strdup(param); + else + action->param = NULL; + + return action; +} static bool file_exists (const char * filename) { @@ -275,14 +339,49 @@ load_uri (WebKitWebView * web_view, const gchar *param) { } } +static void +new_window_load_uri (const gchar * uri) { + GString* to_execute = g_string_new (""); + if (!config_file) { + g_string_printf (to_execute, "uzbl --uri '%s'", uri); + } else { + g_string_printf (to_execute, "uzbl --uri '%s' --config '%s'", uri, config_file); + } + printf("Spawning %s\n",to_execute->str); + if (!g_spawn_command_line_async (to_execute->str, NULL)) { + if (!config_file) { + g_string_printf (to_execute, "./uzbl --uri '%s'", uri); + } else { + g_string_printf (to_execute, "./uzbl --uri '%s' --config '%s'", uri, config_file); + } + printf("Spawning %s\n",to_execute->str); + g_spawn_command_line_async (to_execute->str, NULL); + } + g_string_free (to_execute, TRUE); +} + +static void +go_home (WebKitWebView *page, const char *param) { + (void)param; + + if (home_page) + webkit_web_view_load_uri (page, home_page); +} + +static void +close_uzbl (WebKitWebView *page, const char *param) { + (void)page; + (void)param; + gtk_main_quit (); +} // make sure to put '' around args, so that if there is whitespace we can still keep arguments together. static gboolean run_command(const char *command, const char *args) { - //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> [args] + //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args] GString* to_execute = g_string_new (""); gboolean result; - g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s'", command, config_file, (int) getpid() , (int) xwin, fifopath); + g_string_printf (to_execute, "%s '%s' '%i' '%i' '%s' '%s'", command, config_file, (int) getpid() , (int) xwin, fifo_path, socket_path); if(args) { g_string_append_printf (to_execute, " %s", args); } @@ -294,71 +393,142 @@ run_command(const char *command, const char *args) { static void spawn(WebKitWebView *web_view, const char *param) { - (void)web_view; - run_command(param, NULL); + (void)web_view; + run_command(param, NULL); } static void -parse_command(const char *action, const char *param) { - unsigned int i; - int parsed = 0; +parse_command(const char *cmd, const char *param) { + Command c; + + if ((c = g_hash_table_lookup(commands, cmd))) + c(web_view, param); + else + fprintf (stderr, "command \"%s\" not understood. ignoring.\n", cmd); +} - for (i = 0; i < LENGTH (commands); i++) - if (strcmp(action, commands[i].command) == 0) { - commands[i].func(web_view, param); - parsed = 1; - } +static void +parse_line(char *line) { + gchar **parts; - if (!parsed) - fprintf (stderr, "command \"%s\" not understood. ignoring.\n", action); + g_strstrip(line); + + parts = g_strsplit(line, " ", 2); + + if (!parts) + return; + + parse_command(parts[0], parts[1]); + + g_strfreev(parts); } - + static void -*control_fifo() { - if (fifodir) { - sprintf (fifopath, "%s/uzbl_%d", fifodir, (int) xwin); +control_fifo(GIOChannel *fd) { + gchar *ctl_line; + gsize term_pos; + + if(!fd) + return; + + g_io_channel_read_line(fd, &ctl_line, NULL, &term_pos, NULL); + ctl_line[term_pos] ='\0'; + + parse_line(ctl_line); + + g_free(ctl_line); + + return; +} + +static void +create_fifo() { + GIOChannel *chan = NULL; + + if (fifo_dir) { + sprintf (fifo_path, "%s/uzbl_fifo_%d", fifo_dir, (int) xwin); } else { - sprintf (fifopath, "/tmp/uzbl_%d", (int) xwin); + sprintf (fifo_path, "/tmp/uzbl_fifo_%d", (int) xwin); } - - if (mkfifo (fifopath, 0666) == -1) { + printf ("Control fifo opened in %s\n", fifo_path); + if (mkfifo (fifo_path, 0666) == -1) { printf ("Possible error creating fifo\n"); } + + if( (chan = g_io_channel_new_file((gchar *) fifo_path, "r+", NULL)) ) + g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, chan); + return; +} + +static void +*control_socket() { + if (socket_dir) { + sprintf (socket_path, "%s/uzbl_socket_%d", socket_dir, (int) xwin); + } else { + sprintf (socket_path, "/tmp/uzbl_socket_%d", (int) xwin); + } - printf ("Control fifo opened in %s\n", fifopath); - - while (true) { - FILE *fifo = fopen (fifopath, "r"); - if (!fifo) { - printf ("Could not open %s for reading\n", fifopath); - return NULL; - } - - char buffer[256]; - memset (buffer, 0, sizeof (buffer)); - while (!feof (fifo) && fgets (buffer, sizeof (buffer), fifo)) { - gchar **parts; + int sock, clientsock, len; + unsigned int t; + struct sockaddr_un local, remote; - g_strstrip(buffer); + sock = socket (AF_UNIX, SOCK_STREAM, 0); - parts = g_strsplit(buffer, " ", 2); + local.sun_family = AF_UNIX; + strcpy (local.sun_path, socket_path); + unlink (local.sun_path); - if (!parts) - continue; + len = strlen (local.sun_path) + sizeof (local.sun_family); + bind (sock, (struct sockaddr *) &local, len); + + if (errno == -1) { + printf ("A problem occurred when opening a socket in %s\n", socket_path); + } else { + printf ("Control socket opened in %s\n", socket_path); + } + + listen (sock, 5); + + char buffer[512]; + char temp[128]; + int done, n; + for(;;) { + memset (buffer, 0, sizeof (buffer)); + + t = sizeof (remote); + clientsock = accept (sock, (struct sockaddr *) &remote, &t); + printf ("Connected to client\n"); + + done = 0; + do { + memset (temp, 0, sizeof (temp)); + n = recv (clientsock, temp, 128, 0); + if (n == 0) { + buffer[strlen (buffer)] = '\0'; + done = 1; + } - parse_command(parts[0], parts[1]); + if (!done) + strcat (buffer, temp); + } while (!done); - g_strfreev(parts); + if (strcmp (buffer, "\n") < 0) { + buffer[strlen (buffer) - 1] = '\0'; + } else { + buffer[strlen (buffer)] = '\0'; } + + parse_line (buffer); + close (clientsock); } - + return NULL; } static void setup_threading () { pthread_t control_thread; - pthread_create(&control_thread, NULL, control_fifo, NULL); + pthread_create(&control_thread, NULL, control_socket, NULL); } static void @@ -367,10 +537,10 @@ update_title (GtkWindow* window) { GString* string_short = g_string_new (""); if (!always_insert_mode) g_string_append (string_long, (insert_mode ? "[I] " : "[C] ")); - if (main_title) { - g_string_append (string_long, main_title); - g_string_append (string_short, main_title); - } + if (main_title) { + g_string_append (string_long, main_title); + g_string_append (string_short, main_title); + } g_string_append (string_long, " - Uzbl browser"); g_string_append (string_short, " - Uzbl browser"); if (load_progress < 100) @@ -385,7 +555,7 @@ update_title (GtkWindow* window) { if (show_status) { gtk_window_set_title (window, title_short); - gtk_label_set_text(GTK_LABEL(mainbar_label), title_long); + gtk_label_set_text(GTK_LABEL(mainbar_label), title_long); } else { gtk_window_set_title (window, title_long); } @@ -397,32 +567,28 @@ update_title (GtkWindow* window) { static gboolean key_press_cb (WebKitWebView* page, GdkEventKey* event) { + //TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further. + (void) page; - int i; - gboolean result=FALSE; //TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further. - if (event->type != GDK_KEY_PRESS) - return result; + Action *action; + + if (event->type != GDK_KEY_PRESS || event->keyval == GDK_Page_Up || event->keyval == GDK_Page_Down + || event->keyval == GDK_Up || event->keyval == GDK_Down || event->keyval == GDK_Left || event->keyval == GDK_Right) + return FALSE; //TURN OFF/ON INSERT MODE - if (!always_insert_mode && ((insert_mode && (event->keyval == GDK_Escape)) || (!insert_mode && (event->string[0] == 'i')))) { - insert_mode = !insert_mode; + if ((insert_mode && (event->keyval == GDK_Escape)) || (!insert_mode && (event->string[0] == 'i'))) { + insert_mode = !insert_mode || always_insert_mode; update_title (GTK_WINDOW (main_window)); return TRUE; } - for (i = 0; i < num_bindings; i++) { - if (strcmp(event->string, bindings[i].binding) == 0) { - if (!insert_mode || (event->state == modmask)) { - parse_command(bindings[i].action, bindings[i].param); - result = TRUE; - } - } + if ((!insert_mode || (event->state == modmask)) && (action = g_hash_table_lookup(bindings, event->string))) { + parse_command(action->name, action->param); + return TRUE; } - if (!result) - result = (insert_mode ? FALSE : TRUE); - - return result; + return !insert_mode; } static GtkWidget* @@ -441,6 +607,7 @@ create_browser () { g_signal_connect (G_OBJECT (web_view), "key-press-event", G_CALLBACK (key_press_cb), web_view); g_signal_connect (G_OBJECT (web_view), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb), web_view); g_signal_connect (G_OBJECT (web_view), "download-requested", G_CALLBACK (download_cb), web_view); + g_signal_connect (G_OBJECT (web_view), "create-web-view", G_CALLBACK (create_web_view_cb), web_view); return scrolled_window; } @@ -466,47 +633,38 @@ GtkWidget* create_window () { } static void -add_binding (const gchar *key, const gchar *action) { - char **parts = g_strsplit(action, " ", 2); - - printf("add_binding, key '%s', action '%s'", key, action); - - if (!parts) - return; +add_binding (const gchar *key, const gchar *act) { + char **parts = g_strsplit(act, " ", 2); + Action *action; - if (MAX_BINDINGS == num_bindings) { - fprintf(stderr, "Maximum number number bindings reached, ignoring\n"); - return; - } + if (!parts) + return; - bindings[num_bindings].binding = g_strdup(key); - bindings[num_bindings].action = g_strdup(parts[0]); /* parts[0] is always defined */ - bindings[num_bindings].param = (parts[1] ? g_strdup(parts[1]) : NULL); - - num_bindings++; + action = new_action(parts[0], parts[1]); + g_hash_table_insert(bindings, g_strdup(key), action); - g_strfreev(parts); + g_strfreev(parts); } static void settings_init () { GKeyFile* config; gboolean res = FALSE; + char *saveptr; gchar** keys = NULL; - if (! config_file) { + if (!config_file) { const char* XDG_CONFIG_HOME = getenv ("XDG_CONFIG_HOME"); - char conf[256]; if (! XDG_CONFIG_HOME || ! strcmp (XDG_CONFIG_HOME, "")) { XDG_CONFIG_HOME = (char*)XDG_CONFIG_HOME_default; } printf("XDG_CONFIG_HOME: %s\n", XDG_CONFIG_HOME); - strcpy (conf, XDG_CONFIG_HOME); - strcat (conf, "/uzbl/config"); - if (file_exists (conf)) { - printf ("Config file %s found.\n", conf); - config_file = &conf[0]; + strcpy (config_file_path, XDG_CONFIG_HOME); + strcat (config_file_path, "/uzbl/config"); + if (file_exists (config_file_path)) { + printf ("Config file %s found.\n", config_file_path); + config_file = &config_file_path[0]; } else { // Now we check $XDG_CONFIG_DIRS char *XDG_CONFIG_DIRS = getenv ("XDG_CONFIG_DIRS"); @@ -517,15 +675,15 @@ settings_init () { char buffer[512]; strcpy (buffer, XDG_CONFIG_DIRS); - const gchar* dir = strtok (buffer, ":"); - while (dir && ! file_exists (conf)) { - strcpy (conf, dir); - strcat (conf, "/uzbl/config"); - if (file_exists (conf)) { - printf ("Config file %s found.\n", conf); - config_file = &conf[0]; + const gchar* dir = (char *) strtok_r (buffer, ":", &saveptr); + while (dir && ! file_exists (config_file_path)) { + strcpy (config_file_path, dir); + strcat (config_file_path, "/uzbl/config_file_pathig"); + if (file_exists (config_file_path)) { + printf ("Config file %s found.\n", config_file_path); + config_file = &config_file_path[0]; } - dir = strtok (NULL, ":"); + dir = (char * ) strtok_r (NULL, ":", &saveptr); } } } @@ -533,9 +691,9 @@ settings_init () { if (config_file) { config = g_key_file_new (); res = g_key_file_load_from_file (config, config_file, G_KEY_FILE_NONE, NULL); - if(res) { + if(res) { printf ("Config %s loaded\n", config_file); - } else { + } else { fprintf (stderr, "Config %s loading failed\n", config_file); } } else { @@ -543,47 +701,33 @@ settings_init () { } if (res) { - history_handler = g_key_file_get_value (config, "behavior", "history_handler", NULL); - download_handler = g_key_file_get_value (config, "behavior", "download_handler", NULL); + history_handler = g_key_file_get_value (config, "behavior", "history_handler", NULL); + download_handler = g_key_file_get_value (config, "behavior", "download_handler", NULL); always_insert_mode = g_key_file_get_boolean (config, "behavior", "always_insert_mode", NULL); - show_status = g_key_file_get_boolean (config, "behavior", "show_status", NULL); - modkey = g_key_file_get_value (config, "behavior", "modkey", NULL); - status_top = g_key_file_get_boolean (config, "behavior", "status_top", NULL); - if (! fifodir) - fifodir = g_key_file_get_value (config, "behavior", "fifodir", NULL); - keys = g_key_file_get_keys (config, "bindings", NULL, NULL); + show_status = g_key_file_get_boolean (config, "behavior", "show_status", NULL); + modkey = g_key_file_get_value (config, "behavior", "modkey", NULL); + status_top = g_key_file_get_boolean (config, "behavior", "status_top", NULL); + home_page = g_key_file_get_value (config, "behavior", "home_page", NULL); + if (! fifo_dir) + fifo_dir = g_key_file_get_value (config, "behavior", "fifodir", NULL); + if (! socket_dir) + socket_dir = g_key_file_get_value (config, "behavior", "socket_dir", NULL); + keys = g_key_file_get_keys (config, "bindings", NULL, NULL); } - - if (history_handler) { - printf ("History handler: %s\n", history_handler); - } else { - printf ("History handler disabled\n"); - } - - if (download_handler) { - printf ("Download manager: %s\n", download_handler); - } else { - printf ("Download manager disabled\n"); - } - - if (fifodir) { - printf ("Fifo directory: %s\n", fifodir); - } else { - printf ("Fifo directory: /tmp\n"); - } - - printf ("Always insert mode: %s\n", (always_insert_mode ? "TRUE" : "FALSE")); - - printf ("Show status: %s\n", (show_status ? "TRUE" : "FALSE")); - - printf ("Status top: %s\n", (status_top ? "TRUE" : "FALSE")); + + printf ("History handler: %s\n", (history_handler ? history_handler : "disabled")); + printf ("Download manager: %s\n", (download_handler ? download_handler : "disabled")); + printf ("Fifo directory: %s\n", (fifo_dir ? fifo_dir : "/tmp")); + printf ("Socket directory: %s\n", (socket_dir ? socket_dir : "/tmp")); + printf ("Always insert mode: %s\n", (always_insert_mode ? "TRUE" : "FALSE")); + printf ("Show status: %s\n", (show_status ? "TRUE" : "FALSE")); + printf ("Status top: %s\n", (status_top ? "TRUE" : "FALSE")); + printf ("Modkey: %s\n", (modkey ? modkey : "disabled")); + printf ("Home page: %s\n", (home_page ? home_page : "disabled")); + + if (! modkey) + modkey = ""; - if (modkey) { - printf ("Modkey: %s\n", modkey); - } else { - printf ("Modkey disabled\n"); - modkey = ""; - } //POSSIBLE MODKEY VALUES (COMBINATIONS CAN BE USED) gchar* modkeyup = g_utf8_strup (modkey, -1); if (g_strrstr (modkeyup,"SHIFT") != NULL) modmask |= GDK_SHIFT_MASK; //the Shift key. @@ -609,32 +753,36 @@ settings_init () { for (i = 0; keys[i]; i++) { gchar *value = g_key_file_get_string (config, "bindings", keys[i], NULL); - add_binding(g_strstrip(keys[i]), value); - g_free(value); + add_binding(g_strstrip(keys[i]), value); + g_free(value); } - g_strfreev(keys); + g_strfreev(keys); } } int main (int argc, char* argv[]) { - int i; - gtk_init (&argc, &argv); if (!g_thread_supported ()) g_thread_init (NULL); - strcat ((char*)XDG_CONFIG_HOME_default, getenv ("HOME")); - strcat ((char*)XDG_CONFIG_HOME_default, "/.config"); + printf("Uzbl start location: %s\n", argv[0]); + + strcat ((char *) XDG_CONFIG_HOME_default, getenv ("HOME")); + strcat ((char *) XDG_CONFIG_HOME_default, "/.config"); GError *error = NULL; GOptionContext* context = g_option_context_new ("- some stuff here maybe someday"); g_option_context_add_main_entries (context, entries, NULL); g_option_context_add_group (context, gtk_get_option_group (TRUE)); g_option_context_parse (context, &argc, &argv, &error); + /* initialize hash table */ + bindings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_action); settings_init (); + commands_hash (); + if (always_insert_mode) insert_mode = TRUE; @@ -657,20 +805,19 @@ main (int argc, char* argv[]) { printf("pid %i\n", getpid ()); if (!show_status) - gtk_widget_hide(mainbar); + gtk_widget_hide(mainbar); setup_threading (); + create_fifo (); gtk_main (); - for (i = 0; i < num_bindings; i++) { - g_free(bindings[i].binding); - g_free(bindings[i].action); - if (bindings[i].param) - g_free(bindings[i].param); - } - - unlink (fifopath); + unlink (socket_path); + unlink (fifo_path); + g_hash_table_destroy(bindings); + g_hash_table_destroy(commands); return 0; } + +/* vi: set et ts=4: */ |