multiping.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780
  1. /*____________________________________________________________________________
  2. gkrellm multiping plugin
  3. Copyright (C) 2002 Jindrich Makovicka
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, Write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ____________________________________________________________________________*/
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <gkrellm2/gkrellm.h>
  19. #include <sys/types.h>
  20. #include <sys/wait.h>
  21. #include "decal_multiping_status.xpm"
  22. #define CONFIG_NAME "Multiping"
  23. #define STYLE_NAME "multiping"
  24. #define COMMAND "/usr/local/lib/gkrellm2/plugins/pinger"
  25. static GkrellmMonitor *monitor;
  26. static GkrellmPanel *panel;
  27. static gint style_id;
  28. static FILE *pinger_pipe = NULL;
  29. static pid_t pinger_pid;
  30. static gshort selected_row;
  31. static gboolean delete_list;
  32. static gboolean list_modified;
  33. static GtkWidget *plugin_vbox;
  34. static GtkWidget *label_entry;
  35. static GtkWidget *url_entry;
  36. static GtkWidget *updatefreq_spin;
  37. static GtkWidget *multiping_clist;
  38. static GtkWidget *show_trip_checkbutton;
  39. static GkrellmPiximage *decal_status_image;
  40. static GdkPixmap *status_pixmap;
  41. static GdkBitmap *status_mask;
  42. static gint vspacing, hspacing, time_xoffset;
  43. typedef struct _host_data {
  44. GString *name, *ip, *percentage, *sent_str, *recv_str, *msg, *shortmsg, *updatefreq;
  45. GkrellmDecal *name_text, *msg_text, *decal_pix;
  46. gboolean show_trip;
  47. } host_data;
  48. static GList *hosts;
  49. static host_data *host_malloc()
  50. {
  51. host_data *h = (host_data *) g_malloc(sizeof(host_data));
  52. h->name_text = NULL;
  53. h->msg_text = NULL;
  54. h->decal_pix = NULL;
  55. h->name = g_string_new(NULL);
  56. h->ip = g_string_new(NULL);
  57. h->percentage = g_string_new(NULL);
  58. h->sent_str = g_string_new(NULL);
  59. h->recv_str = g_string_new(NULL);
  60. h->msg = g_string_new(NULL);
  61. h->shortmsg = g_string_new("wait");
  62. h->updatefreq = g_string_new(NULL);
  63. h->show_trip = 0;
  64. return h;
  65. }
  66. static void host_free(host_data * h)
  67. {
  68. if (h->name_text) {
  69. gkrellm_destroy_decal(h->name_text);
  70. }
  71. if (h->msg_text) {
  72. gkrellm_destroy_decal(h->msg_text);
  73. }
  74. if (h->decal_pix) {
  75. gkrellm_destroy_decal(h->decal_pix);
  76. }
  77. g_string_free(h->name, TRUE);
  78. g_string_free(h->ip, TRUE);
  79. g_string_free(h->percentage, TRUE);
  80. g_string_free(h->sent_str, TRUE);
  81. g_string_free(h->recv_str, TRUE);
  82. g_string_free(h->msg, TRUE);
  83. g_string_free(h->shortmsg, TRUE);
  84. g_string_free(h->updatefreq, TRUE);
  85. g_free(h);
  86. }
  87. static void strip_nl(gchar *buf)
  88. {
  89. if (buf[strlen(buf) - 1] == '\n')
  90. buf[strlen(buf) - 1] = 0;
  91. }
  92. static void host_read_pipe(host_data * h)
  93. {
  94. gchar buf[512];
  95. fgets(buf, 512, pinger_pipe);
  96. strip_nl(buf);
  97. g_string_assign(h->percentage, buf);
  98. fgets(buf, 512, pinger_pipe);
  99. strip_nl(buf);
  100. g_string_assign(h->sent_str, buf);
  101. fgets(buf, 512, pinger_pipe);
  102. strip_nl(buf);
  103. g_string_assign(h->recv_str, buf);
  104. fgets(buf, 512, pinger_pipe);
  105. strip_nl(buf);
  106. g_string_assign(h->msg, buf);
  107. fgets(buf, 512, pinger_pipe);
  108. strip_nl(buf);
  109. g_string_assign(h->shortmsg, buf);
  110. }
  111. static void kill_pinger()
  112. {
  113. if (pinger_pipe) {
  114. kill(pinger_pid, SIGTERM);
  115. waitpid(pinger_pid, NULL, 0);
  116. fclose(pinger_pipe);
  117. pinger_pipe = NULL;
  118. }
  119. }
  120. static void launch_pipe()
  121. {
  122. GString *s = g_string_new(COMMAND);
  123. gint i;
  124. GList *list;
  125. host_data *h;
  126. pid_t pid;
  127. gint mypipe[2];
  128. for (i = 0, list = hosts; list; list = list->next, i++) {
  129. h = (host_data *) list->data;
  130. g_string_append(s, " ");
  131. g_string_append(s, h->ip->str);
  132. g_string_append(s, " ");
  133. g_string_append(s, h->updatefreq->str);
  134. }
  135. if (pipe(mypipe)) {
  136. fprintf(stderr, "Pipe failed.\n");
  137. return;
  138. }
  139. pid = fork();
  140. if (pid == 0) {
  141. /* This is the child process. Execute the shell command. */
  142. close(mypipe[0]);
  143. dup2(mypipe[1], 1);
  144. execl("/bin/sh", "/bin/sh", "-c", s->str, NULL);
  145. _exit(EXIT_FAILURE);
  146. } else if (pid < 0) {
  147. /* The fork failed. Report failure. */
  148. fprintf(stderr, "failed to fork\n");
  149. } else {
  150. /* This is the parent process. Prepare the pipe stream. */
  151. close(mypipe[1]);
  152. pinger_pipe = fdopen(mypipe[0], "r");
  153. pinger_pid = pid;
  154. }
  155. }
  156. /*
  157. static void
  158. host_append_info(host_data *h, GString *str)
  159. {
  160. GString *s = g_string_new(NULL);
  161. g_string_sprintf(s, "%s: %s, %s\n",
  162. h->name->str, h->percentage->str, h->msg->str);
  163. g_string_append(str, s->str);
  164. g_string_free(s, TRUE);
  165. }
  166. */
  167. static void host_draw_name(host_data * h)
  168. {
  169. gkrellm_draw_decal_text(panel, h->name_text, h->name->str, -1);
  170. }
  171. static void host_draw_msg(host_data * h)
  172. {
  173. gint n, p;
  174. if (h->show_trip) {
  175. gkrellm_draw_decal_text(panel, h->msg_text, h->shortmsg->str, -1);
  176. }
  177. n = sscanf(h->percentage->str, "%d", &p);
  178. if (n != 1 || p == 0) {
  179. gkrellm_draw_decal_pixmap(panel, h->decal_pix, 0);
  180. } else if (p < 100) {
  181. gkrellm_draw_decal_pixmap(panel, h->decal_pix, 2);
  182. } else {
  183. gkrellm_draw_decal_pixmap(panel, h->decal_pix, 1);
  184. }
  185. }
  186. static GList *append_host(GList * list, gchar * name, gchar * ip, gboolean show_trip, gchar * updatefreq)
  187. {
  188. host_data *h = host_malloc();
  189. g_string_assign(h->name, name);
  190. g_string_assign(h->ip, ip);
  191. h->show_trip = show_trip;
  192. g_string_assign(h->updatefreq, updatefreq);
  193. return g_list_append(list, h);
  194. }
  195. static gint
  196. display_host(host_data * h, GkrellmStyle * style, GkrellmTextstyle * ts,
  197. GkrellmTextstyle * ts_alt, gint y)
  198. {
  199. if (h->show_trip) {
  200. h->msg_text =
  201. gkrellm_create_decal_text(panel, "999", ts_alt, style, 0, y, 0);
  202. h->msg_text->x = gkrellm_chart_width() - h->msg_text->w + time_xoffset;
  203. }
  204. h->decal_pix =
  205. gkrellm_create_decal_pixmap(panel, status_pixmap, status_mask, 3,
  206. style, -1, y);
  207. h->name_text =
  208. gkrellm_create_decal_text(panel, "Ay", ts, style,
  209. h->decal_pix->x+h->decal_pix->w+hspacing, y, -1);
  210. if (h->name_text->h < h->decal_pix->h) {
  211. h->name_text->y += (h->decal_pix->h-h->name_text->h)/2;
  212. if (h->show_trip) {
  213. h->msg_text->y = h->name_text->y;
  214. }
  215. return h->decal_pix->y + h->decal_pix->h + vspacing;
  216. } else {
  217. h->decal_pix->y += (h->name_text->h-h->decal_pix->h)/2;
  218. return h->name_text->y + h->name_text->h + vspacing;
  219. }
  220. }
  221. static gint panel_click_event(GtkWidget * widget, GdkEventButton * ev)
  222. {
  223. if (ev->button == 3)
  224. gkrellm_open_config_window(monitor);
  225. return 1;
  226. }
  227. static gint panel_expose_event(GtkWidget * widget, GdkEventExpose * ev)
  228. {
  229. gdk_draw_pixmap(widget->window,
  230. widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
  231. panel->pixmap, ev->area.x, ev->area.y, ev->area.x,
  232. ev->area.y, ev->area.width, ev->area.height);
  233. return FALSE;
  234. }
  235. static void update_plugin()
  236. {
  237. fd_set fds;
  238. struct timeval tv;
  239. gint ret;
  240. GString *str = g_string_new(NULL);
  241. FD_ZERO(&fds);
  242. FD_SET(fileno(pinger_pipe), &fds);
  243. tv.tv_sec = 0;
  244. tv.tv_usec = 0;
  245. ret = select(fileno(pinger_pipe) + 1, &fds, 0, 0, &tv);
  246. if (ret) {
  247. g_list_foreach(hosts, (GFunc) host_read_pipe, NULL);
  248. g_list_foreach(hosts, (GFunc) host_draw_msg, NULL);
  249. gkrellm_draw_panel_layers(panel);
  250. }
  251. /*
  252. if (GK.minute_tick && tooltip) {
  253. // if (tooltip->tip_window == NULL || !GTK_WIDGET_VISIBLE(tooltip->tip_window)) {
  254. g_list_foreach(hosts, (GFunc)host_append_info, str);
  255. gtk_tooltips_set_tip(tooltip, panel->drawing_area, str->str, NULL);
  256. gtk_tooltips_set_delay(tooltip, 750);
  257. gtk_tooltips_enable(tooltip);
  258. // }
  259. }
  260. */
  261. g_string_free(str, TRUE);
  262. }
  263. static void setup_display(gboolean first_create)
  264. {
  265. gshort i;
  266. gint y;
  267. GkrellmStyle *style;
  268. GkrellmTextstyle *ts, *ts_alt;
  269. GList *list;
  270. host_data *h;
  271. if (first_create) {
  272. panel = gkrellm_panel_new0();
  273. }
  274. style = gkrellm_panel_style(style_id);
  275. ts = gkrellm_meter_textstyle(style_id);
  276. ts_alt = gkrellm_meter_alt_textstyle(style_id);
  277. y = 3;
  278. // y = style->top_margin;
  279. for (i = 0, list = hosts; list; list = list->next, i++) {
  280. h = (host_data *) list->data;
  281. y = display_host(h, style, ts, ts_alt, y);
  282. }
  283. gkrellm_panel_configure(panel, NULL, style);
  284. gkrellm_panel_create(plugin_vbox, monitor, panel);
  285. if (first_create) {
  286. gtk_signal_connect(GTK_OBJECT(panel->drawing_area), "expose_event",
  287. (GtkSignalFunc) panel_expose_event, NULL);
  288. gtk_signal_connect(GTK_OBJECT(panel->drawing_area),
  289. "button_release_event",
  290. (GtkSignalFunc) panel_click_event, NULL);
  291. }
  292. g_list_foreach(hosts, (GFunc) host_draw_name, NULL);
  293. g_list_foreach(hosts, (GFunc) host_draw_msg, NULL);
  294. gkrellm_draw_panel_layers(panel);
  295. }
  296. static void create_plugin(GtkWidget * vbox, gint first_create)
  297. {
  298. plugin_vbox = vbox;
  299. gkrellm_load_piximage("decal_multiping_status", decal_multiping_status_xpm,
  300. &decal_status_image, STYLE_NAME);
  301. gkrellm_scale_piximage_to_pixmap(decal_status_image, &status_pixmap,
  302. &status_mask, 0, 0);
  303. if (!gkrellm_get_gkrellmrc_integer("multiping_vspacing", &vspacing))
  304. vspacing = 2;
  305. if (!gkrellm_get_gkrellmrc_integer("multiping_hspacing", &hspacing))
  306. hspacing = 2;
  307. if (!gkrellm_get_gkrellmrc_integer("multiping_time_xoffset", &time_xoffset))
  308. time_xoffset = 0;
  309. kill_pinger();
  310. launch_pipe();
  311. setup_display(first_create);
  312. }
  313. static void cb_up(GtkWidget * widget, gpointer drawer)
  314. {
  315. GtkWidget *clist;
  316. gshort row;
  317. clist = multiping_clist;
  318. row = selected_row;
  319. if (row > 0) {
  320. gtk_clist_row_move(GTK_CLIST(clist), row, row - 1);
  321. gtk_clist_select_row(GTK_CLIST(clist), row - 1, -1);
  322. if (gtk_clist_row_is_visible(GTK_CLIST(clist), row - 1) !=
  323. GTK_VISIBILITY_FULL)
  324. gtk_clist_moveto(GTK_CLIST(clist), row - 1, -1, 0.0, 0.0);
  325. selected_row = row - 1;
  326. list_modified = TRUE;
  327. }
  328. }
  329. static void cb_down(GtkWidget * widget, gpointer drawer)
  330. {
  331. GtkWidget *clist;
  332. gshort row;
  333. clist = multiping_clist;
  334. row = selected_row;
  335. if (row >= 0 && row < GTK_CLIST(clist)->rows - 1) {
  336. gtk_clist_row_move(GTK_CLIST(clist), row, row + 1);
  337. gtk_clist_select_row(GTK_CLIST(clist), row + 1, -1);
  338. if (gtk_clist_row_is_visible(GTK_CLIST(clist), row + 1) !=
  339. GTK_VISIBILITY_FULL)
  340. gtk_clist_moveto(GTK_CLIST(clist), row + 1, -1, 1.0, 0.0);
  341. selected_row = row + 1;
  342. list_modified = TRUE;
  343. }
  344. }
  345. static void reset_entries()
  346. {
  347. gtk_entry_set_text(GTK_ENTRY(label_entry), "");
  348. gtk_entry_set_text(GTK_ENTRY(url_entry), "");
  349. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_trip_checkbutton), TRUE);
  350. gtk_spin_button_set_value(GTK_SPIN_BUTTON(updatefreq_spin),60);
  351. return;
  352. }
  353. static void cb_selected(GtkWidget * clist, gint row, gint column,
  354. GdkEventButton * bevent, gpointer data)
  355. {
  356. gchar *s;
  357. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 0, &s);
  358. gtk_entry_set_text(GTK_ENTRY(label_entry), s);
  359. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 1, &s);
  360. gtk_entry_set_text(GTK_ENTRY(url_entry), s);
  361. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 2, &s);
  362. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_trip_checkbutton), strcmp(s, "yes") == 0);
  363. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 3, &s);
  364. gtk_spin_button_set_value(GTK_SPIN_BUTTON(updatefreq_spin),atoi(s));
  365. selected_row = row;
  366. return;
  367. }
  368. static void cb_unselected(GtkWidget * clist, gint row, gint column,
  369. GdkEventButton * bevent, gpointer data)
  370. {
  371. selected_row = -1;
  372. reset_entries();
  373. return;
  374. }
  375. static void cb_enter(GtkWidget * widget, gpointer data)
  376. {
  377. gchar *buf[4];
  378. gboolean active;
  379. active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(show_trip_checkbutton));
  380. buf[0] = gkrellm_gtk_entry_get_text(&label_entry);
  381. buf[1] = gkrellm_gtk_entry_get_text(&url_entry);
  382. buf[2] = active ? "yes" : "no";
  383. buf[3] = gkrellm_gtk_entry_get_text(&updatefreq_spin);
  384. if ((strlen(buf[0]) == 0) || (strlen(buf[1]) == 0))
  385. return;
  386. if (selected_row >= 0) {
  387. gtk_clist_set_text(GTK_CLIST(multiping_clist), selected_row, 0,
  388. buf[0]);
  389. gtk_clist_set_text(GTK_CLIST(multiping_clist), selected_row, 1,
  390. buf[1]);
  391. gtk_clist_set_text(GTK_CLIST(multiping_clist), selected_row, 2,
  392. buf[2]);
  393. gtk_clist_set_text(GTK_CLIST(multiping_clist), selected_row, 3,
  394. buf[3]);
  395. gtk_clist_unselect_row(GTK_CLIST(multiping_clist), selected_row,
  396. 0);
  397. selected_row = -1;
  398. } else
  399. gtk_clist_append(GTK_CLIST(multiping_clist), buf);
  400. reset_entries();
  401. list_modified = TRUE;
  402. return;
  403. }
  404. static void cb_delete(GtkWidget * widget, gpointer data)
  405. {
  406. reset_entries();
  407. if (selected_row >= 0) {
  408. gtk_clist_remove(GTK_CLIST(multiping_clist), selected_row);
  409. list_modified = TRUE;
  410. selected_row = -1;
  411. }
  412. return;
  413. }
  414. static gchar plugin_about_text[] =
  415. "GKrellM Multiping version " VERSION "\n\n\n"
  416. "Copyright (C) 2002 by Jindrich Makovicka\n"
  417. "makovick@kmlinux.fjfi.cvut.cz\n"
  418. "Released under the GPL.\n"
  419. "Portions (C) 2001 Tilman \"Trillian\" Sauerbeck";
  420. static void create_plugin_config(GtkWidget * tab_vbox)
  421. {
  422. GtkWidget *tabs;
  423. GtkWidget *vbox;
  424. GtkWidget *hbox;
  425. GtkWidget *hbox2;
  426. GtkWidget *label;
  427. GtkWidget *scrolled;
  428. GtkWidget *button;
  429. GtkWidget *arrow;
  430. GtkAdjustment *spin_adjust;
  431. GList *list;
  432. GtkWidget *info_label;
  433. gchar *buf[2];
  434. gchar *titles[4] = { "Label", "Hostname / IP Address", "Trip", "Ping Freq" };
  435. gshort i;
  436. host_data *nt;
  437. list_modified = FALSE;
  438. selected_row = -1;
  439. /* Make a couple of tabs */
  440. tabs = gtk_notebook_new();
  441. gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
  442. gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
  443. /* Sources tab */
  444. vbox = gkrellm_gtk_framed_notebook_page(tabs, "Hosts");
  445. hbox = gtk_hbox_new(FALSE, 0);
  446. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 2);
  447. label = gtk_label_new("Label:");
  448. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  449. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 2);
  450. label_entry = gtk_entry_new();
  451. gtk_entry_set_max_length(GTK_ENTRY(label_entry), 25);
  452. // gtk_widget_set_usize(label_entry, 180, 0);
  453. gtk_box_pack_start(GTK_BOX(hbox), label_entry, FALSE, TRUE, 0);
  454. hbox = gtk_hbox_new(FALSE, 0);
  455. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 2);
  456. label = gtk_label_new("Hostname / IP Address:");
  457. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  458. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 2);
  459. url_entry = gtk_entry_new();
  460. gtk_entry_set_max_length(GTK_ENTRY(url_entry), 75);
  461. gtk_widget_set_usize(url_entry, 475, 0);
  462. gtk_box_pack_start(GTK_BOX(hbox), url_entry, FALSE, TRUE, 2);
  463. hbox = gtk_hbox_new(FALSE, 0);
  464. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5);
  465. label = gtk_label_new("Ping Frequency:");
  466. gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
  467. gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 2);
  468. spin_adjust = (GtkAdjustment *) gtk_adjustment_new(0,10,100,1.0,0,0);
  469. updatefreq_spin = gtk_spin_button_new(spin_adjust,1.0,0);
  470. gtk_spin_button_set_value(GTK_SPIN_BUTTON(updatefreq_spin),60);
  471. gtk_box_pack_start(GTK_BOX(hbox), updatefreq_spin, FALSE, TRUE, 0);
  472. show_trip_checkbutton = gtk_check_button_new_with_label("Display trip time");
  473. gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(show_trip_checkbutton),TRUE);
  474. gtk_box_pack_start(GTK_BOX(hbox), show_trip_checkbutton, FALSE, TRUE, 0);
  475. hbox = gtk_hbox_new(TRUE, 100);
  476. gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 5);
  477. hbox2 = gtk_hbutton_box_new();
  478. gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox2), GTK_BUTTONBOX_START);
  479. gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox2), 5);
  480. gtk_box_pack_start(GTK_BOX(hbox), hbox2, FALSE, FALSE, 5);
  481. button = gtk_button_new_with_label("Enter");
  482. gtk_signal_connect(GTK_OBJECT(button), "clicked",
  483. (GtkSignalFunc) cb_enter, NULL);
  484. gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
  485. button = gtk_button_new_with_label("Delete");
  486. gtk_signal_connect(GTK_OBJECT(button), "clicked",
  487. (GtkSignalFunc) cb_delete, NULL);
  488. gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
  489. hbox2 = gtk_hbutton_box_new();
  490. gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox2), GTK_BUTTONBOX_END);
  491. gtk_button_box_set_spacing(GTK_BUTTON_BOX(hbox2), 5);
  492. gtk_box_pack_start(GTK_BOX(hbox), hbox2, FALSE, FALSE, 5);
  493. button = gtk_button_new();
  494. arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_ETCHED_OUT);
  495. gtk_container_add(GTK_CONTAINER(button), arrow);
  496. gtk_signal_connect(GTK_OBJECT(button), "clicked",
  497. (GtkSignalFunc) cb_up, NULL);
  498. gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
  499. button = gtk_button_new();
  500. arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_ETCHED_OUT);
  501. gtk_container_add(GTK_CONTAINER(button), arrow);
  502. gtk_signal_connect(GTK_OBJECT(button), "clicked",
  503. (GtkSignalFunc) cb_down, NULL);
  504. gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
  505. scrolled = gtk_scrolled_window_new(NULL, NULL);
  506. gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
  507. GTK_POLICY_AUTOMATIC,
  508. GTK_POLICY_AUTOMATIC);
  509. gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
  510. multiping_clist = gtk_clist_new_with_titles(4, titles);
  511. gtk_clist_set_shadow_type(GTK_CLIST(multiping_clist), GTK_SHADOW_OUT);
  512. gtk_clist_column_titles_passive(GTK_CLIST(multiping_clist));
  513. gtk_clist_set_column_justification(GTK_CLIST(multiping_clist), 0,
  514. GTK_JUSTIFY_LEFT);
  515. gtk_clist_set_column_justification(GTK_CLIST(multiping_clist), 1,
  516. GTK_JUSTIFY_LEFT);
  517. gtk_clist_set_column_width(GTK_CLIST(multiping_clist), 0, 100);
  518. gtk_clist_set_column_width(GTK_CLIST(multiping_clist), 1, 200);
  519. gtk_signal_connect(GTK_OBJECT(multiping_clist), "select_row",
  520. (GtkSignalFunc) cb_selected, NULL);
  521. gtk_signal_connect(GTK_OBJECT(multiping_clist), "unselect_row",
  522. (GtkSignalFunc) cb_unselected, NULL);
  523. gtk_container_add(GTK_CONTAINER(scrolled), multiping_clist);
  524. for (i = 0, list = hosts; list; i++, list = list->next) {
  525. nt = (host_data *) list->data;
  526. buf[0] = nt->name->str;
  527. buf[1] = nt->ip->str;
  528. buf[2] = nt->show_trip ? "yes" : "no";
  529. buf[3] = nt->updatefreq->str;
  530. gtk_clist_append(GTK_CLIST(multiping_clist), buf);
  531. gtk_clist_set_row_data(GTK_CLIST(multiping_clist), i, nt);
  532. }
  533. /* Setup */
  534. // vbox = gkrellm_create_framed_tab(tabs, "Setup");
  535. /* Info tab */
  536. // vbox = gkrellm_create_framed_tab(tabs, "Info");
  537. // text = gkrellm_scrolled_text(vbox, NULL, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
  538. // for (i = 0; i < sizeof(plugin_info_text)/sizeof(gchar *); i++)
  539. // gkrellm_add_info_text_string(text, plugin_info_text[i]);
  540. /* About tab */
  541. info_label = gtk_label_new(plugin_about_text);
  542. label = gtk_label_new("About");
  543. gtk_notebook_append_page(GTK_NOTEBOOK(tabs), info_label, label);
  544. }
  545. static void apply_plugin_config()
  546. {
  547. gshort row;
  548. gchar *s1, *s2, *s3, *s4;
  549. GList *new_hosts;
  550. if (list_modified) {
  551. kill_pinger();
  552. new_hosts = NULL;
  553. for (row = 0; row < GTK_CLIST(multiping_clist)->rows; row++) {
  554. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 0, &s1);
  555. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 1, &s2);
  556. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 2, &s3);
  557. gtk_clist_get_text(GTK_CLIST(multiping_clist), row, 3, &s4);
  558. new_hosts = append_host(new_hosts, s1, s2, strcmp(s3, "yes") == 0,s4);
  559. }
  560. g_list_foreach(hosts, (GFunc) host_free, NULL);
  561. g_list_free(hosts);
  562. gkrellm_panel_destroy(panel);
  563. panel = gkrellm_panel_new0();
  564. hosts = new_hosts;
  565. setup_display(1);
  566. list_modified = FALSE;
  567. launch_pipe();
  568. }
  569. }
  570. static void save_plugin_config(FILE * f)
  571. {
  572. gchar *label;
  573. gchar *pt;
  574. GList *list;
  575. host_data *h;
  576. for (list = hosts; list; list = list->next) {
  577. h = (host_data *) list->data;
  578. //when saving, we convert spaces in labels to underscores
  579. label = g_strdup(h->name->str);
  580. for (pt = label; *pt; pt++)
  581. if (*pt == ' ')
  582. *pt = '_';
  583. fprintf(f, "multiping host %s %s %d %s\n", label, h->ip->str, h->show_trip,
  584. h->updatefreq->str);
  585. g_free(label);
  586. }
  587. }
  588. static void load_plugin_config(gchar * arg)
  589. {
  590. gchar plugin_config[64];
  591. gchar item[256];
  592. gchar label[26];
  593. gchar ip[76];
  594. gchar updatefreq[4];
  595. gchar *pt;
  596. gshort n;
  597. gboolean show_trip;
  598. n = sscanf(arg, "%s %[^\n]", plugin_config, item);
  599. if (n == 2) {
  600. if (!strcmp(plugin_config, "host")) {
  601. if (delete_list) {
  602. g_list_foreach(hosts, (GFunc) host_free, NULL);
  603. g_list_free(hosts);
  604. delete_list = FALSE;
  605. }
  606. label[0] = '\0';
  607. ip[0] = '\0';
  608. updatefreq[0] = '\0';
  609. sscanf(item, "%25s %75s %d %3s", label, ip, &show_trip, updatefreq);
  610. //when loading, we convert underscores in labels to spaces
  611. for (pt = label; *pt; pt++)
  612. if (*pt == '_')
  613. *pt = ' ';
  614. hosts = append_host(hosts, label, ip, show_trip, updatefreq);
  615. }
  616. }
  617. }
  618. /* The monitor structure tells GKrellM how to call the plugin routines.
  619. */
  620. static GkrellmMonitor plugin_mon = {
  621. CONFIG_NAME, /* Name, for config tab. */
  622. 0, /* Id, 0 if a plugin */
  623. create_plugin, /* The create function */
  624. update_plugin, /* The update function */
  625. create_plugin_config, /* The config tab create function */
  626. apply_plugin_config, /* Apply the config function */
  627. save_plugin_config, /* Save user config */
  628. load_plugin_config, /* Load user config */
  629. "multiping", /* config keyword */
  630. NULL, /* Undefined 2 */
  631. NULL, /* Undefined 1 */
  632. NULL, /* private */
  633. MON_MAIL, /* Insert plugin before this monitor */
  634. NULL, /* Handle if a plugin, filled in by GKrellM */
  635. NULL /* path if a plugin, filled in by GKrellM */
  636. };
  637. GkrellmMonitor *gkrellm_init_plugin()
  638. {
  639. list_modified = FALSE;
  640. delete_list = TRUE;
  641. style_id = gkrellm_add_meter_style(&plugin_mon, STYLE_NAME);
  642. monitor = &plugin_mon;
  643. return &plugin_mon;
  644. }