multiping.c 23 KB

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