multiping.c 24 KB

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