multiping.c 24 KB

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