]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/tray-monitor/tray-monitor.c
add src/tray-monitor directory
[bacula/bacula] / bacula / src / tray-monitor / tray-monitor.c
1 /*
2  *
3  *   Bacula Gnome Tray Monitor
4  *
5  *     Nicolas Boichat, August MMIV
6  *
7  *     Version $Id$
8  */
9
10 /*
11    Copyright (C) 2000-2004 Kern Sibbald and John Walker
12
13    This library is free software; you can redistribute it and/or
14    modify it under the terms of the GNU Lesser General Public
15    License as published by the Free Software Foundation; either
16    version 2.1 of the License, or (at your option) any later version.
17
18    This library is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    Lesser General Public License for more details.
22
23    You should have received a copy of the GNU Lesser General Public
24    License along with this library; if not, write to the Free
25    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26    MA 02111-1307, USA.
27
28  */
29
30 #include "bacula.h"
31 #include "tray-monitor.h"
32
33 #include "eggstatusicon.h"
34 #include <gtk/gtk.h>
35
36 #include "idle.xpm"
37 #include "error.xpm"
38 #include "running.xpm"
39 #include "saving.xpm"
40 #include "warn.xpm"
41
42 /* Imported functions */
43 int authenticate_file_daemon(JCR *jcr, MONITOR *monitor, CLIENT* client);
44
45 /* Forward referenced functions */
46 static void terminate_console(int sig);
47 void writecmd(const char* command);
48
49 /* Static variables */
50 static char *configfile = NULL;
51 static BSOCK *FD_sock = NULL;
52 static MONITOR *monitor;
53 static POOLMEM *args;
54
55 /* UI variables and functions */
56 gboolean fd_read(gpointer data);
57
58 static EggStatusIcon* mTrayIcon;
59
60 #define CONFIG_FILE "./tray-monitor.conf"   /* default configuration file */
61
62 static void usage()
63 {
64    fprintf(stderr, _(
65 "Copyright (C) 2000-2004 Kern Sibbald and John Walker\n"
66 "\nVersion: " VERSION " (" BDATE ") %s %s %s\n\n"
67 "Usage: tray-monitor [-s] [-c config_file] [-d debug_level]\n"
68 "       -c <file>   set configuration file to file\n"
69 "       -dnn        set debug level to nn\n"
70 "       -s          no signals\n"
71 "       -t          test - read configuration and exit\n"
72 "       -?          print this message.\n"  
73 "\n"), HOST_OS, DISTNAME, DISTVER);
74 }
75
76 /*********************************************************************
77  *
78  *         Main Bacula Tray Monitor -- User Interface Program
79  *
80  */
81 int main(int argc, char *argv[])
82 {
83    int ch, nfiled;
84    bool test_config = false;
85    JCR jcr;
86    CLIENT* filed;
87
88    init_stack_dump();
89    my_name_is(argc, argv, "tray-monitor");
90    textdomain("bacula");
91    init_msg(NULL, NULL);
92    working_directory = "/tmp";
93    args = get_pool_memory(PM_FNAME);
94
95    while ((ch = getopt(argc, argv, "bc:d:r:st?")) != -1) {
96       switch (ch) {
97       case 'c':                    /* configuration file */
98          if (configfile != NULL) {
99             free(configfile);
100          }
101          configfile = bstrdup(optarg);
102          break;
103
104       case 'd':
105          debug_level = atoi(optarg);
106          if (debug_level <= 0) {
107             debug_level = 1;
108          }
109          break;
110
111       case 't':
112          test_config = true;
113          break;
114
115       case '?':
116       default:
117          usage();
118          exit(1);
119       }  
120    }
121    argc -= optind;
122    argv += optind;
123
124    if (argc) {
125       usage();
126       exit(1);
127    }
128
129    if (configfile == NULL) {
130       configfile = bstrdup(CONFIG_FILE);
131    }
132
133    parse_config(configfile);
134
135    LockRes();
136    nfiled = 0;
137    foreach_res(filed, R_CLIENT) {
138       nfiled++;
139    }
140    UnlockRes();
141    if (nfiled != 1) {
142       Emsg1(M_ERROR_TERM, 0, _("No Client resource defined in %s (or more than one)\n\
143 Without that I don't how to get status from the Client :-(\n"), configfile);
144    }
145
146    if (test_config) {
147       terminate_console(0);
148       exit(0);
149    }
150    
151    LockRes();
152    filed = (CLIENT*)GetNextRes(R_CLIENT, NULL);
153    UnlockRes();
154
155    memset(&jcr, 0, sizeof(jcr));
156
157    (void)WSA_Init();                        /* Initialize Windows sockets */
158       
159    printf(_("Connecting to Client %s:%d\n"), filed->address, filed->FDport);
160    FD_sock = bnet_connect(NULL, 5, 15, "File daemon", filed->address, 
161                           NULL, filed->FDport, 0);
162    if (FD_sock == NULL) {
163       terminate_console(0);
164       return 1;
165    }
166    jcr.file_bsock = FD_sock;
167    
168    LockRes();
169    monitor = (MONITOR*)GetNextRes(R_MONITOR, (RES *)NULL);
170    UnlockRes();
171    
172    if (!authenticate_file_daemon(&jcr, monitor, filed)) {
173       fprintf(stderr, "ERR=%s", FD_sock->msg);
174       terminate_console(0);
175       return 1;
176    }
177
178    printf("Opened connection with File daemon\n");
179
180    writecmd("status");
181
182    gtk_init (&argc, &argv);
183    
184    GdkPixbuf* pixbuf = gdk_pixbuf_new_from_xpm_data(xpm_idle);
185    // This should be ideally replaced by a completely libpr0n-based icon rendering.
186    mTrayIcon = egg_status_icon_new_from_pixbuf(pixbuf);
187 /*   g_signal_connect(G_OBJECT(mTrayIcon), "activate", G_CALLBACK(TrayIconActivate), this);
188    g_signal_connect(G_OBJECT(mTrayIcon), "popup-menu", G_CALLBACK(TrayIconPopupMenu), this);*/
189    g_object_unref(G_OBJECT(pixbuf));
190
191    gtk_idle_add( fd_read, NULL );
192       
193    gtk_main();
194    
195    if (FD_sock) {
196       bnet_sig(FD_sock, BNET_TERMINATE); /* send EOF */
197       bnet_close(FD_sock);
198    }
199
200    terminate_console(0);
201    return 0;
202 }
203
204 gboolean fd_read(gpointer data) {
205    int stat;
206    
207    while(1) {
208       if ((stat = bnet_recv(FD_sock)) >= 0) {
209          printf(FD_sock->msg);
210       }
211       else if (stat == BNET_SIGNAL) {
212          if (FD_sock->msglen == BNET_PROMPT) {
213             printf("<PROMPT>");
214          }
215          else if (FD_sock->msglen == BNET_EOD) {
216             printf("<END>");
217             writecmd("status");
218             sleep(1);
219             return 1;
220          }
221          else if (FD_sock->msglen == BNET_HEARTBEAT) {
222             bnet_sig(FD_sock, BNET_HB_RESPONSE);
223             printf("<< Heartbeat signal received, answered. >>");
224          }
225          else {
226             printf("<< Unexpected signal received : %s >>", bnet_sig_to_ascii(FD_sock));
227          }
228       }
229       else { /* BNET_HARDEOF || BNET_ERROR */
230          printf("<ERROR>");
231          break;
232       }
233            
234       if (is_bnet_stop(FD_sock)) {
235          printf("<STOP>");
236          break;            /* error or term */
237       }
238    }
239    return 0;
240 }
241
242 /* Cleanup and then exit */
243 static void terminate_console(int sig)
244 {
245
246    static bool already_here = false;
247
248    if (already_here) {                /* avoid recursive temination problems */
249       exit(1);
250    }
251    already_here = true;
252    free_pool_memory(args);
253    (void)WSACleanup();               /* Cleanup Windows sockets */
254    if (sig != 0) {
255       exit(1);
256    }
257    return;
258 }
259
260 void writecmd(const char* command) {
261    FD_sock->msglen = strlen(command);
262    pm_strcpy(&FD_sock->msg, command);
263    bnet_send(FD_sock);
264 }