]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/tray-monitor/tray-monitor.c
Fix typo.
[bacula/bacula] / bacula / src / tray-monitor / tray-monitor.c
index 69a41059e877175786a9f9fce9444ba1a6a81a76..4037272618160337acb7f11974e2ffa47bd37c6a 100644 (file)
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2009 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   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 Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  *
  *   Bacula Gnome Tray Monitor
  *     Version $Id$
  */
 
-/*
-   Copyright (C) 2004-2005 Kern Sibbald
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   This library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with this library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-   MA 02111-1307, USA.
-
- */
 
 #include "bacula.h"
 #include "tray-monitor.h"
 
-#include "eggstatusicon.h"
-
 #include "generic.xpm"
 
 #define TRAY_DEBUG_MEMORY 0
@@ -40,6 +46,7 @@
 int authenticate_director(JCR *jcr, MONITOR *monitor, DIRRES *director);
 int authenticate_file_daemon(JCR *jcr, MONITOR *monitor, CLIENT* client);
 int authenticate_storage_daemon(JCR *jcr, MONITOR *monitor, STORE* store);
+extern bool parse_tmon_config(CONFIG *config, const char *configfile, int exit_code);
 
 /* Dummy functions */
 int generate_daemon_event(JCR *jcr, const char *event) { return 1; }
@@ -57,6 +64,7 @@ static int nitems = 0;
 static int fullitem = 0; //Item to be display in detailled status window
 static int lastupdated = -1; //Last item updated
 static monitoritem items[32];
+static CONFIG *config;
 
 /* Data received from DIR/FD/SD */
 static char OKqstatus[]   = "%c000 OK .status\n";
@@ -85,33 +93,38 @@ static void DaemonChanged(GtkWidget *widget, monitoritem* data);
 static gboolean delete_event(GtkWidget *widget, GdkEvent  *event, gpointer   data);
 
 static guint timerTag;
-static EggStatusIcon *mTrayIcon;
+static GtkStatusIcon *mTrayIcon;
 static GtkWidget *mTrayMenu;
 static GtkWidget *window;
 static GtkWidget *textview;
 static GtkTextBuffer *buffer;
 static GtkWidget *timeoutspinner;
+static GtkWidget *scrolledWindow;
 char** xpm_generic_var;
 static gboolean blinkstate = TRUE;
 
+PangoFontDescription *font_desc = NULL;
+
 #define CONFIG_FILE "./tray-monitor.conf"   /* default configuration file */
 
 static void usage()
 {
    fprintf(stderr, _(
-"Copyright (C) 2000-2004 Kern Sibbald and John Walker\n"
+PROG_COPYRIGHT
 "Written by Nicolas Boichat (2004)\n"
 "\nVersion: %s (%s) %s %s %s\n\n"
 "Usage: tray-monitor [-c config_file] [-d debug_level]\n"
 "       -c <file>     set configuration file to file\n"
-"       -dnn          set debug level to nn\n"
+"       -d <nn>       set debug level to <nn>\n"
+"       -dt           print timestamp in debug output\n"
 "       -t            test - read configuration and exit\n"
 "       -?            print this message.\n"
-"\n"), VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
+"\n"), 2004, VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
 }
 
 static GtkWidget *new_image_button(const gchar *stock_id,
-                                   const gchar *label_text) {
+                                   const gchar *label_text)
+{
     GtkWidget *button;
     GtkWidget *box;
     GtkWidget *label;
@@ -181,6 +194,7 @@ int main(int argc, char *argv[])
    DIRRES* dird;
    CLIENT* filed;
    STORE* stored;
+   CONFONTRES *con_font;
 
    setlocale(LC_ALL, "");
    bindtextdomain("bacula", LOCALEDIR);
@@ -197,7 +211,7 @@ int main(int argc, char *argv[])
    sigfillset(&sigignore.sa_mask);
    sigaction(SIGPIPE, &sigignore, NULL);
 
-   gtk_init (&argc, &argv);
+   gtk_init(&argc, &argv);
 
    while ((ch = getopt(argc, argv, "bc:d:th?f:s:")) != -1) {
       switch (ch) {
@@ -209,9 +223,13 @@ int main(int argc, char *argv[])
          break;
 
       case 'd':
-         debug_level = atoi(optarg);
-         if (debug_level <= 0) {
-            debug_level = 1;
+         if (*optarg == 't') {
+            dbg_timestamp = true;
+         } else {
+            debug_level = atoi(optarg);
+            if (debug_level <= 0) {
+               debug_level = 1;
+            }
          }
          break;
 
@@ -238,7 +256,8 @@ int main(int argc, char *argv[])
       configfile = bstrdup(CONFIG_FILE);
    }
 
-   parse_config(configfile);
+   config = new_config_parser();
+   parse_tmon_config(config, configfile, M_ERROR_TERM);
 
    LockRes();
    nitems = 0;
@@ -248,7 +267,7 @@ int main(int argc, char *argv[])
 
    if (nitems != 1) {
       Emsg2(M_ERROR_TERM, 0,
-         _("Error: %d Monitor resource defined in %s. You must define one and only one Monitor resource.\n"), nitems, configfile);
+         _("Error: %d Monitor resources defined in %s. You must define one and only one Monitor resource.\n"), nitems, configfile);
    }
 
    nitems = 0;
@@ -279,7 +298,7 @@ int main(int argc, char *argv[])
    UnlockRes();
 
    if (nitems == 0) {
-      Emsg1(M_ERROR_TERM, 0, _("No Client, Storage nor Director resource defined in %s\n"
+      Emsg1(M_ERROR_TERM, 0, _("No Client, Storage or Director resource defined in %s\n"
 "Without that I don't how to get status from the File, Storage or Director Daemon :-(\n"), configfile);
    }
 
@@ -306,8 +325,9 @@ int main(int argc, char *argv[])
    }
 
    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_xpm_data(generateXPM(warn, warn));
-   // This should be ideally replaced by a completely libpr0n-based icon rendering.
-   mTrayIcon = egg_status_icon_new_from_pixbuf(pixbuf);
+
+   mTrayIcon = gtk_status_icon_new_from_pixbuf(pixbuf);
+   gtk_status_icon_set_tooltip(mTrayIcon, _("Bacula daemon status monitor"));
    g_signal_connect(G_OBJECT(mTrayIcon), "activate", G_CALLBACK(TrayIconActivate), NULL);
    g_signal_connect(G_OBJECT(mTrayIcon), "popup-menu", G_CALLBACK(TrayIconPopupMenu), NULL);
    g_object_unref(G_OBJECT(pixbuf));
@@ -330,7 +350,7 @@ int main(int argc, char *argv[])
 
    timerTag = g_timeout_add( 1000*monitor->RefreshInterval/nitems, fd_read, NULL );
 
-   g_timeout_add( 1000, blink, NULL );
+   g_timeout_add( 1000, blink, NULL);
 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
@@ -398,14 +418,47 @@ int main(int argc, char *argv[])
    }
 
    gtk_box_pack_start(GTK_BOX(vbox), daemon_table, FALSE, FALSE, 0);
-
+  
    textview = gtk_text_view_new();
 
+   scrolledWindow = gtk_scrolled_window_new(NULL, NULL);
+   gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+   gtk_container_add(GTK_CONTAINER (scrolledWindow), textview);
+   
    buffer = gtk_text_buffer_new(NULL);
 
    gtk_text_buffer_set_text(buffer, "", -1);
 
-   PangoFontDescription *font_desc = pango_font_description_from_string ("Fixed 10");
+  /*
+   * Gtk2/pango have different font names. Gnome2 comes with "Monospace 10"
+   */
+
+   LockRes();
+   foreach_res(con_font, R_CONSOLE_FONT) {
+       if (!con_font->fontface) {
+          Dmsg1(400, "No fontface for %s\n", con_font->hdr.name);
+          continue;
+       }
+       Dmsg1(100, "Now loading: %s\n",con_font->fontface);
+       font_desc = pango_font_description_from_string(con_font->fontface);
+       if (font_desc == NULL) {
+           Dmsg2(400, "Load of requested ConsoleFont \"%s\" (%s) failed!\n",
+                  con_font->hdr.name, con_font->fontface);
+       } else {
+           Dmsg2(400, "ConsoleFont \"%s\" (%s) loaded.\n",
+                  con_font->hdr.name, con_font->fontface);
+           break;
+       }
+   }
+   UnlockRes();
+
+   if (!font_desc) {
+      font_desc = pango_font_description_from_string("Monospace 10");
+   }
+   if (!font_desc) {
+      font_desc = pango_font_description_from_string("monospace");
+   }
+
    gtk_widget_modify_font(textview, font_desc);
    pango_font_description_free(font_desc);
 
@@ -416,7 +469,7 @@ int main(int argc, char *argv[])
 
    gtk_text_view_set_buffer(GTK_TEXT_VIEW(textview), buffer);
 
-   gtk_box_pack_start(GTK_BOX(vbox), textview, TRUE, TRUE, 0);
+   gtk_box_pack_start(GTK_BOX(vbox), scrolledWindow, TRUE, TRUE, 0);
 
    GtkWidget* hbox = gtk_hbox_new(FALSE, 10);
 
@@ -484,6 +537,9 @@ int main(int argc, char *argv[])
    
    gtk_object_destroy(GTK_OBJECT(window));
    gtk_object_destroy(GTK_OBJECT(mTrayMenu));
+   config->free_resources();
+   free(config);
+   config = NULL;
    term_msg();
 
 #if TRAY_DEBUG_MEMORY
@@ -493,59 +549,75 @@ int main(int argc, char *argv[])
    return 0;
 }
 
-static void MonitorAbout(GtkWidget *widget, gpointer data) {
+static void MonitorAbout(GtkWidget *widget, gpointer data)
+{
 #if HAVE_GTK_2_4
    GtkWidget* about = gtk_message_dialog_new_with_markup(GTK_WINDOW(window),GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
       "<span size='x-large' weight='bold'>%s</span>\n\n"
+      PROG_COPYRIGHT
       "%s"
       "\n<small>%s: %s (%s) %s %s %s</small>",
       _("Bacula Tray Monitor"),
-      _("Copyright (C) 2004-2005 Kern Sibbald\n"
-        "Written by Nicolas Boichat\n"),
-      _("Version:"),
+        2004,
+      _("Written by Nicolas Boichat\n"),
+      _("Version"),
       VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
 #else
    GtkWidget* about = gtk_message_dialog_new(GTK_WINDOW(window),GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,   
       "%s\n\n"
+      PROG_COPYRIGHT
       "%s"
-      "\n%s %s (%s) %s %s %s",
+      "\n%s: %s (%s) %s %s %s",
       _("Bacula Tray Monitor"),
-      _("Copyright (C) 2004-2005 Kern Sibbald\n"
-        "Written by Nicolas Boichat\n"),
-      _("Version:"),
+        2004,
+      _("Written by Nicolas Boichat\n"),
+      _("Version"),
       VERSION, BDATE, HOST_OS, DISTNAME, DISTVER);
 #endif
    gtk_dialog_run(GTK_DIALOG(about));
    gtk_widget_destroy(about);
 }
 
-static void MonitorRefresh(GtkWidget *widget, gpointer data) {
+static void MonitorRefresh(GtkWidget *widget, gpointer data)
+{
    for (int i = 0; i < nitems; i++) {
       fd_read(NULL);
    }
 }
 
-static gboolean delete_event( GtkWidget *widget,
-                              GdkEvent  *event,
-                              gpointer   data ) {
+static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
+{
    gtk_widget_hide(window);
    return TRUE; /* do not destroy the window */
 }
 
-static void TrayIconActivate(GtkWidget *widget, gpointer data) {
-    gtk_widget_show(window);
+/*
+ * Come here when the user right clicks on the icon.
+ *   We display the icon menu.
+ */
+static void TrayIconActivate(GtkWidget *widget, gpointer data)
+{
+   gtk_widget_show(window);
 }
 
-static void TrayIconPopupMenu(unsigned int activateTime, unsigned int button) {
-  gtk_menu_popup(GTK_MENU(mTrayMenu), NULL, NULL, NULL, NULL, 1, 0);
-  gtk_widget_show_all(mTrayMenu);
+/*
+ * Come here when the user left clicks on the icon. 
+ *  We popup the status window.
+ */
+static void TrayIconPopupMenu(unsigned int activateTime, unsigned int button) 
+{
+   gtk_menu_popup(GTK_MENU(mTrayMenu), NULL, NULL, NULL, NULL, button,
+                  gtk_get_current_event_time());
+   gtk_widget_show(mTrayMenu);
 }
 
-static void TrayIconExit(unsigned int activateTime, unsigned int button) {
+static void TrayIconExit(unsigned int activateTime, unsigned int button)
+{
    gtk_main_quit();
 }
 
-static void IntervalChanged(GtkWidget *widget, gpointer data) {
+static void IntervalChanged(GtkWidget *widget, gpointer data)
+{
    g_source_remove(timerTag);
    timerTag = g_timeout_add(
       (guint)(
@@ -553,7 +625,8 @@ static void IntervalChanged(GtkWidget *widget, gpointer data) {
       ), fd_read, NULL );
 }
 
-static void DaemonChanged(GtkWidget *widget, monitoritem* data) {
+static void DaemonChanged(GtkWidget *widget, monitoritem* data) 
+{
    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
       fullitem = -1;
       for (int i = 0; i < nitems; i++) {
@@ -596,7 +669,8 @@ static gboolean blink(gpointer data) {
    return true;
 }
 
-static gboolean fd_read(gpointer data) {
+static gboolean fd_read(gpointer data)
+{
    sm_line++;
 #if TRAY_DEBUG_MEMORY
    printf("sm_line=%d\n", sm_line);
@@ -672,7 +746,8 @@ void append_error_string(GString* str, int joberrors) {
    }
 }
 
-void getstatus(monitoritem* item, int current, GString** str) {
+void getstatus(monitoritem* item, int current, GString** str)
+{
    GSList *list, *it;
    stateenum ret = error;
    int jobid = 0, joberrors = 0;
@@ -824,7 +899,9 @@ void getstatus(monitoritem* item, int current, GString** str) {
 
    it = list;
    do {
-      if (it->data) g_string_free((GString*)it->data, TRUE);
+      if (it->data) {
+         g_string_free((GString*)it->data, TRUE);
+      }
    } while ((it = it->next) != NULL);
 
    g_slist_free(list);
@@ -837,7 +914,8 @@ void getstatus(monitoritem* item, int current, GString** str) {
    }
 }
 
-int docmd(monitoritem* item, const char* command, GSList** list) {
+int docmd(monitoritem* item, const char* command, GSList** list) 
+{
    int stat;
    GString* str = NULL;
 
@@ -857,21 +935,21 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
          dird = (DIRRES*)item->resource;
          trayMessage(_("Connecting to Director %s:%d\n"), dird->address, dird->DIRport);
          changeStatusMessage(item, _("Connecting to Director %s:%d"), dird->address, dird->DIRport);
-         item->D_sock = bnet_connect(NULL, 0, 0, _("Director daemon"), dird->address, NULL, dird->DIRport, 0);
+         item->D_sock = bnet_connect(NULL, 0, 0, 0, _("Director daemon"), dird->address, NULL, dird->DIRport, 0);
          jcr.dir_bsock = item->D_sock;
          break;
       case R_CLIENT:
          filed = (CLIENT*)item->resource;
          trayMessage(_("Connecting to Client %s:%d\n"), filed->address, filed->FDport);
          changeStatusMessage(item, _("Connecting to Client %s:%d"), filed->address, filed->FDport);
-         item->D_sock = bnet_connect(NULL, 0, 0, _("File daemon"), filed->address, NULL, filed->FDport, 0);
+         item->D_sock = bnet_connect(NULL, 0, 0, 0, _("File daemon"), filed->address, NULL, filed->FDport, 0);
          jcr.file_bsock = item->D_sock;
          break;
       case R_STORAGE:
          stored = (STORE*)item->resource;
          trayMessage(_("Connecting to Storage %s:%d\n"), stored->address, stored->SDport);
          changeStatusMessage(item, _("Connecting to Storage %s:%d"), stored->address, stored->SDport);
-         item->D_sock = bnet_connect(NULL, 0, 0, _("Storage daemon"), stored->address, NULL, stored->SDport, 0);
+         item->D_sock = bnet_connect(NULL, 0, 0, 0, _("Storage daemon"), stored->address, NULL, stored->SDport, 0);
          jcr.store_bsock = item->D_sock;
          break;
       default:
@@ -881,7 +959,7 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
       }
 
       if (item->D_sock == NULL) {
-         g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
+         *list = g_slist_append(*list, g_string_new(_("Cannot connect to daemon.\n")));
          changeStatusMessage(item, _("Cannot connect to daemon."));
          item->state = error;
          item->oldstate = error;
@@ -891,7 +969,7 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
       if (!authenticate_daemon(item, &jcr)) {
          str = g_string_sized_new(64);
          g_string_printf(str, "ERR=%s\n", item->D_sock->msg);
-         g_slist_append(*list, str);
+         *list = g_slist_append(*list, str);
          item->state = error;
          item->oldstate = error;
          changeStatusMessage(item, _("Authentication error : %s"), item->D_sock->msg);
@@ -920,14 +998,16 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
       }
 
       if (item->type == R_DIRECTOR) { /* Read connection messages... */
-         GSList *list, *it;
-         docmd(item, "", &list); /* Usually invalid, but no matter */
-         it = list;
+         GSList *tlist, *it;
+         docmd(item, "", &tlist); /* Usually invalid, but no matter */
+         it = tlist;
          do {
-            if (it->data) g_string_free((GString*)it->data, TRUE);
+            if (it->data) {
+               g_string_free((GString*)it->data, TRUE);
+            }
          } while ((it = it->next) != NULL);
 
-         g_slist_free(list);
+         g_slist_free(tlist);
       }
    }
 
@@ -936,7 +1016,7 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
 
    while(1) {
       if ((stat = bnet_recv(item->D_sock)) >= 0) {
-         g_slist_append(*list, g_string_new(item->D_sock->msg));
+         *list = g_slist_append(*list, g_string_new(item->D_sock->msg));
       }
       else if (stat == BNET_SIGNAL) {
          if (item->D_sock->msglen == BNET_EOD) {
@@ -945,21 +1025,21 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
          }
          else if (item->D_sock->msglen == BNET_PROMPT) {
             //fprintf(stderr, "<< PROMPT >>\n");
-            g_slist_append(*list, g_string_new(_("<< Error: BNET_PROMPT signal received. >>\n")));
+            *list = g_slist_append(*list, g_string_new(_("<< Error: BNET_PROMPT signal received. >>\n")));
             return 0;
          }
          else if (item->D_sock->msglen == BNET_HEARTBEAT) {
             bnet_sig(item->D_sock, BNET_HB_RESPONSE);
-            g_slist_append(*list, g_string_new(_("<< Heartbeat signal received, answered. >>\n")));
+            *list = g_slist_append(*list, g_string_new(_("<< Heartbeat signal received, answered. >>\n")));
          }
          else {
             str = g_string_sized_new(64);
             g_string_printf(str, _("<< Unexpected signal received : %s >>\n"), bnet_sig_to_ascii(item->D_sock));
-            g_slist_append(*list, str);
+            *list = g_slist_append(*list, str);
          }
       }
       else { /* BNET_HARDEOF || BNET_ERROR */
-         g_slist_append(*list, g_string_new(_("<ERROR>\n")));
+         *list = g_slist_append(*list, g_string_new(_("<ERROR>\n")));
          item->D_sock = NULL;
          item->state = error;
          item->oldstate = error;
@@ -989,7 +1069,8 @@ void writecmd(monitoritem* item, const char* command) {
 }
 
 /* Note: Does not seem to work either on Gnome nor KDE... */
-void trayMessage(const char *fmt,...) {
+void trayMessage(const char *fmt,...)
+{
    char buf[512];
    va_list arg_ptr;
 
@@ -997,9 +1078,9 @@ void trayMessage(const char *fmt,...) {
    bvsnprintf(buf, sizeof(buf), (char *)fmt, arg_ptr);
    va_end(arg_ptr);
 
-   fprintf(stderr, buf);
+   fprintf(stderr, "%s", buf);
 
-   egg_tray_icon_send_message(egg_status_icon_get_tray_icon(mTrayIcon), 5000, (const char*)&buf, -1);
+// gtk_tray_icon_send_message(gtk_status_icon_get_tray_icon(mTrayIcon), 5000, (const char*)&buf, -1);
 }
 
 void changeStatusMessage(monitoritem* item, const char *fmt,...) {
@@ -1058,7 +1139,7 @@ void updateStatusIcon(monitoritem* item) {
 
    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_xpm_data(xpm);
    if (item == NULL) {
-      egg_status_icon_set_from_pixbuf(mTrayIcon, pixbuf);
+      gtk_status_icon_set_from_pixbuf(mTrayIcon, pixbuf);
       gtk_window_set_icon(GTK_WINDOW(window), pixbuf);
    }
    else {
@@ -1068,7 +1149,8 @@ void updateStatusIcon(monitoritem* item) {
 }
 
 /* Note: result should not be stored, as it is a reference to xpm_generic_var */
-static const char** generateXPM(stateenum newstate, stateenum oldstate) {
+static const char** generateXPM(stateenum newstate, stateenum oldstate) 
+{
    char* address = &xpm_generic_var[xpm_generic_first_color][xpm_generic_column];
    switch (newstate) {
    case error: