-/*
- *
- * Bacula Gnome Tray Monitor
- *
- * Nicolas Boichat, August MMIV
- *
- * Version $Id$
- */
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2004-2006 Free Software Foundation Europe e.V.
+ 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 two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
+ 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 General Public License
+ 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 John Walker.
+ 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
+ *
+ * Nicolas Boichat, August MMIV
+ *
+ * Version $Id$
+ */
+
#include "bacula.h"
#include "tray-monitor.h"
-#include "eggstatusicon.h"
-
#include "generic.xpm"
#define TRAY_DEBUG_MEMORY 0
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; }
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";
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-%s Kern Sibbald\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"), BYEAR, 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;
DIRRES* dird;
CLIENT* filed;
STORE* stored;
+ CONFONTRES *con_font;
setlocale(LC_ALL, "");
bindtextdomain("bacula", LOCALEDIR);
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) {
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;
configfile = bstrdup(CONFIG_FILE);
}
- parse_config(configfile);
+ config = new_config_parser();
+ parse_tmon_config(config, configfile, M_ERROR_TERM);
LockRes();
nitems = 0;
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;
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);
}
}
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));
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);
}
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);
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);
break;
}
//writecmd(&items[i], "quit");
- bnet_sig(items[i].D_sock, BNET_TERMINATE); /* send EOF */
- bnet_close(items[i].D_sock);
+ items[i].D_sock->signal(BNET_TERMINATE); /* send EOF */
+ items[i].D_sock->close();
}
}
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
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-2006 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-2006 Kern Sibbald\n"
- "Written by Nicolas Boichat\n"),
- _("Version:"),
- BYEAR, VERSION, BDATE, HOST_OS, DISTNAME);
+ 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)(
), 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++) {
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:
writecmd(item, command);
while(1) {
- if ((stat = bnet_recv(item->D_sock)) >= 0) {
+ if ((stat = item->D_sock->recv()) >= 0) {
*list = g_slist_append(*list, g_string_new(item->D_sock->msg));
}
else if (stat == BNET_SIGNAL) {
//fprintf(stderr, "<< EOD >>\n");
return 1;
}
- else if (item->D_sock->msglen == BNET_PROMPT) {
+ else if (item->D_sock->msglen == BNET_SUB_PROMPT) {
//fprintf(stderr, "<< PROMPT >>\n");
- *list = g_slist_append(*list, g_string_new(_("<< Error: BNET_PROMPT signal received. >>\n")));
+ *list = g_slist_append(*list, g_string_new(_("<< Error: BNET_SUB_PROMPT signal received. >>\n")));
return 0;
}
else if (item->D_sock->msglen == BNET_HEARTBEAT) {
- bnet_sig(item->D_sock, BNET_HB_RESPONSE);
+ item->D_sock->signal(BNET_HB_RESPONSE);
*list = g_slist_append(*list, g_string_new(_("<< Heartbeat signal received, answered. >>\n")));
}
else {
return 0;
}
- if (is_bnet_stop(item->D_sock)) {
+ if (item->D_sock->is_stop()) {
g_string_append_printf(str, _("<STOP>\n"));
item->D_sock = NULL;
item->state = error;
if (item->D_sock) {
item->D_sock->msglen = strlen(command);
pm_strcpy(&item->D_sock->msg, command);
- bnet_send(item->D_sock);
+ item->D_sock->send();
}
}
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,...) {
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 {
}
/* 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: