"Fossies" - the Fresh Open Source Software Archive 
Member "gkrellm_snmp-1.1/gkrellm_snmp.c" (3 Jan 2009, 48337 Bytes) of package /linux/privat/old/gkrellm_snmp-1.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /* SNMP reader plugin for GKrellM
2 | Copyright (C) 2000-2009 Christian W. Zuckschwerdt <zany@triq.net>
3 |
4 | Author: Christian W. Zuckschwerdt <zany@triq.net> http://triq.net/
5 | Latest versions might be found at: http://gkrellm.net/
6 |
7 | GKrellM_SNMP is free software; you can redistribute it and/or
8 | modify it under the terms of the GNU General Public License as
9 | published by the Free Software Foundation; either version 2 of
10 | the License, or (at your option) any later version.
11 |
12 | In addition, as a special exception, the copyright holders give
13 | permission to link the code of this program with the OpenSSL library,
14 | and distribute linked combinations including the two.
15 | You must obey the GNU General Public License in all respects
16 | for all of the code used other than OpenSSL. If you modify
17 | file(s) with this exception, you may extend this exception to your
18 | version of the file(s), but you are not obligated to do so. If you
19 | do not wish to do so, delete this exception statement from your
20 | version. If you delete this exception statement from all source
21 | files in the program, then also delete it here.
22
23 | This program is distributed in the hope that it will be useful,
24 | but WITHOUT ANY WARRANTY; without even the implied warranty of
25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 | GNU General Public License for more details.
27
28 | You should have received a copy of the GNU General Public License
29 | along with GKrellM_SNMP. If not, see <http://www.gnu.org/>.
30 */
31
32 /* Installation:
33 |
34 | make
35 | make install
36 | or without using superuser privileges
37 | make install-user
38 |
39 */
40
41 /* In case of SNMP trouble: #define DEBUG_SNMP */
42
43 #include <stdio.h>
44 #include <sys/types.h>
45
46 #ifdef UCDSNMP
47 #include <ucd-snmp/asn1.h>
48 #include <ucd-snmp/mib.h>
49 #include <ucd-snmp/parse.h>
50 #include <ucd-snmp/snmp.h>
51 #include <ucd-snmp/snmp_api.h>
52 #include <ucd-snmp/snmp_client.h>
53 #include <ucd-snmp/snmp_impl.h> /* special ASN types */
54 #ifdef DEBUG_SNMP
55 #include <ucd-snmp/snmp_debug.h>
56 #endif /* DEBUG_SNMP */
57 #else /* UCDSNMP */
58 #include <net-snmp/net-snmp-config.h>
59 #include <net-snmp/net-snmp-includes.h>
60 #define RECEIVED_MESSAGE NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE
61 #define TIMED_OUT NETSNMP_CALLBACK_OP_TIMED_OUT
62 #ifdef DEBUG_SNMP
63 #include <net-snmp/snmp_debug.h>
64 #endif /* DEBUG_SNMP */
65 #endif /* UCDSNMP */
66
67 #include <sys/time.h>
68
69
70 #include <gkrellm2/gkrellm.h>
71
72 /* #define STREAM /* test for Lou Cephyr */
73
74
75 #define SNMP_PLUGIN_MAJOR_VERSION 0
76 #define SNMP_PLUGIN_MINOR_VERSION 21
77
78 #define PLUGIN_CONFIG_NAME "SNMP"
79 #define PLUGIN_CONFIG_KEYWORD "snmp_monitor"
80
81
82 typedef struct Reader Reader;
83
84 struct Reader {
85 Reader *next;
86 gchar *label;
87 gchar *peer;
88 gint port;
89 gchar *community;
90 gchar *oid_str;
91 oid objid[MAX_OID_LEN];
92 size_t objid_length;
93 gchar *unit;
94 gint divisor;
95 gboolean scale;
96 gint delay;
97 gboolean active;
98 gboolean delta;
99 gint asn1_type;
100 gchar *sample;
101 u_long sample_n;
102 u_long sample_time;
103 gchar *old_sample;
104 u_long old_sample_n;
105 u_long old_sample_time;
106 gchar *error;
107 gchar *old_error;
108 struct snmp_session *session;
109
110 GkrellmPanel *panel;
111 GtkTooltips *tooltip;
112
113 GkrellmChart *chart;
114 GkrellmChartdata *chart_data;
115 GkrellmChartconfig *chart_config;
116 };
117
118
119 /*
120 * caller needs to free the returned gchar*
121 */
122
123 gchar *
124 scale(u_long num)
125 {
126 if (num > 2000000000)
127 return g_strdup_printf("%ldG", num/1024/1024/1024);
128 if (num > 6000000)
129 return g_strdup_printf("%ldM", num/1024/1024);
130 if (num > 6000)
131 return g_strdup_printf("%ldK", num/1024);
132 return g_strdup_printf("%ld", num);
133 }
134
135 gchar *
136 strdup_uptime (u_long time)
137 {
138 gint up_d, up_h, up_m;
139
140 up_d = time/100/60/60/24;
141 up_h = (time/100/60/60) % 24;
142 up_m = (time/100/60) % 60;
143
144 return g_strdup_printf ("%dd %d:%d", up_d, up_h, up_m );
145 }
146
147 gchar *
148 render_error(Reader *reader)
149 {
150 return g_strdup_printf ("%s %s (snmp://%s@%s:%d/%s)",
151 reader->label,
152 reader->session ? reader->error : "Unknown host",
153 reader->community,
154 reader->peer, reader->port,
155 reader->oid_str );
156 }
157
158 gchar *
159 render_label(Reader *reader)
160 {
161 u_long since_last = 0;
162 u_long val;
163
164 /* 100: turn TimeTicks into seconds */
165 since_last = (reader->sample_time - reader->old_sample_time) / 100;
166
167 /* short-cut if only binary data present */
168 if (reader->asn1_type == ASN_OCTET_STR) {
169 return g_strdup_printf ("%s %s%s",
170 reader->label,
171 reader->sample,
172 reader->unit);
173 }
174
175 /* pretty print Uptime */
176 if (reader->asn1_type == ASN_TIMETICKS) {
177 return strdup_uptime (reader->sample_n);
178 }
179
180 if (reader->delta)
181 val = (reader->sample_n - reader->old_sample_n) /
182 ( (since_last < 1) ? 1 : since_last ) /
183 ( (reader->divisor == 0) ? 1 : reader->divisor );
184 else
185 val = reader->sample_n /
186 ( (reader->divisor == 0) ? 1 : reader->divisor );
187
188 if (reader->scale)
189 return g_strdup_printf ("%s %s%s",
190 reader->label,
191 scale(val),
192 reader->unit);
193 else
194 return g_strdup_printf ("%s %ld%s",
195 reader->label,
196 val,
197 reader->unit);
198 }
199
200 gchar *
201 render_info(Reader *reader)
202 {
203 u_long since_last = 0;
204 u_long delta;
205 gint up_d, up_h, up_m;
206
207 /* 100: turn TimeTicks into seconds */
208 since_last = (reader->sample_time - reader->old_sample_time) / 100;
209
210 up_d = reader->sample_time/100/60/60/24;
211 up_h = (reader->sample_time/100/60/60) % 24;
212 up_m = (reader->sample_time/100/60) % 60;
213
214 delta = (reader->sample_n - reader->old_sample_n) /
215 ( (since_last < 1) ? 1 : since_last );
216
217 return g_strdup_printf ("%s '%s' %ld (%ld s: %ld /%d =%ld) %s (snmp://%s@%s:%d/%s) Uptime: %dd %d:%d",
218 reader->label,
219 reader->sample,
220 reader->sample_n,
221 since_last,
222 delta,
223 reader->divisor,
224 delta / ( (reader->divisor == 0) ? 1 : reader->divisor ),
225 reader->unit,
226 reader->community,
227 reader->peer, reader->port,
228 reader->oid_str,
229 up_d, up_h, up_m );
230 }
231
232 #ifdef UCDSNMP_PRE_4_2
233
234 /*
235 * snmp_parse_args.c
236 */
237
238 oid
239 *snmp_parse_oid(const char *argv,
240 oid *root,
241 size_t *rootlen)
242 {
243 size_t savlen = *rootlen;
244 /* printf("parse_oid: read_objid\n"); */
245 if (read_objid(argv,root,rootlen)) {
246 return root;
247 }
248 *rootlen = savlen;
249 /* printf("parse_oid: get_node\n"); */
250 if (get_node(argv,root,rootlen)) {
251 return root;
252 }
253 *rootlen = savlen;
254 /* printf("parse_oid: wildly parsing\n"); */
255 if (get_wild_node(argv,root,rootlen)) {
256 return root;
257 }
258 return NULL;
259 }
260
261 #endif
262
263 gchar *
264 snmp_probe(gchar *peer, gint port, gchar *community)
265 {
266 oid sysDescr[MAX_OID_LEN];
267 size_t sysDescr_length;
268 oid sysObjectID[MAX_OID_LEN];
269 size_t sysObjectID_length;
270 oid sysUpTime[MAX_OID_LEN];
271 size_t sysUpTime_length;
272 oid sysContact[MAX_OID_LEN];
273 size_t sysContact_length;
274 oid sysName[MAX_OID_LEN];
275 size_t sysName_length;
276 oid sysLocation[MAX_OID_LEN];
277 size_t sysLocation_length;
278
279 struct snmp_session session, *ss;
280 struct snmp_pdu *pdu, *response;
281 struct variable_list *vars;
282
283 int count;
284 int status;
285
286 char textbuf[1024];
287 char *result = NULL;
288 char *tmp = NULL;
289
290 /* transform interesting OIDs */
291 sysDescr_length = MAX_OID_LEN;
292 if (!snmp_parse_oid("system.sysDescr.0", sysDescr, &sysDescr_length))
293 printf("error parsing oid: system.sysDescr.0\n");
294
295 sysObjectID_length = MAX_OID_LEN;
296 if (!snmp_parse_oid("system.sysObjectID.0", sysObjectID, &sysObjectID_length))
297 printf("error parsing oid: system.sysObjectID.0\n");
298
299 sysUpTime_length = MAX_OID_LEN;
300 if (!snmp_parse_oid("system.sysUpTime.0", sysUpTime, &sysUpTime_length))
301 printf("error parsing oid: system.sysUpTime.0\n");
302
303 sysContact_length = MAX_OID_LEN;
304 if (!snmp_parse_oid("system.sysContact.0", sysContact, &sysContact_length))
305 printf("error parsing oid: system.sysContact.0\n");
306
307 sysName_length = MAX_OID_LEN;
308 if (!snmp_parse_oid("system.sysName.0", sysName, &sysName_length))
309 printf("error parsing oid: system.sysName.0\n");
310
311 sysLocation_length = MAX_OID_LEN;
312 if (!snmp_parse_oid("system.sysLocation.0", sysLocation, &sysLocation_length))
313 printf("error parsing oid: system.sysLocation.0\n");
314
315 /* initialize session to default values */
316 snmp_sess_init( &session );
317
318 session.version = SNMP_VERSION_1;
319 session.community = community;
320 session.community_len = strlen(community);
321 session.peername = peer;
322
323 #ifdef STREAM
324 session.flags |= SNMP_FLAGS_STREAM_SOCKET;
325 fprintf (stderr, "local port set to: %d\n", session.local_port);
326 #endif
327
328 /*
329 * Open an SNMP session.
330 */
331 ss = snmp_open(&session);
332 if (ss == NULL){
333 fprintf (stderr, "local port set to: %d\n", session.local_port);
334 snmp_sess_perror("snmp_open", &session);
335 exit(1);
336 }
337
338 /*
339 * Create PDU for GET request and add object names to request.
340 */
341 pdu = snmp_pdu_create(SNMP_MSG_GET);
342
343 snmp_add_null_var(pdu, sysDescr, sysDescr_length);
344 snmp_add_null_var(pdu, sysObjectID, sysObjectID_length);
345 snmp_add_null_var(pdu, sysUpTime, sysUpTime_length);
346 snmp_add_null_var(pdu, sysContact, sysContact_length);
347 snmp_add_null_var(pdu, sysName, sysName_length);
348 snmp_add_null_var(pdu, sysLocation, sysLocation_length);
349
350 /*
351 * Perform the request.
352 *
353 * If the Get Request fails, note the OID that caused the error,
354 * "fix" the PDU (removing the error-prone OID) and retry.
355 */
356 retry:
357 status = snmp_synch_response(ss, pdu, &response);
358 if (status == STAT_SUCCESS){
359 if (response->errstat == SNMP_ERR_NOERROR){
360 /* just render all vars */
361 for(vars = response->variables; vars; vars = vars->next_variable) {
362 snprint_variable(textbuf, 1023, vars->name, vars->name_length, vars);
363 textbuf[1023] = '\0';
364 if (result) {
365 tmp = result;
366 result = g_strdup_printf("%s\n%s\n", tmp, textbuf);
367 g_free(tmp);
368 } else {
369 result = g_strdup_printf("%s\n", textbuf);
370 }
371 }
372
373 } else {
374 fprintf(stderr, "Error in packet\nReason: %s\n",
375 snmp_errstring(response->errstat));
376
377 if (response->errstat == SNMP_ERR_NOSUCHNAME){
378 fprintf(stderr, "This name doesn't exist: ");
379 for(count = 1, vars = response->variables;
380 vars && count != response->errindex;
381 vars = vars->next_variable, count++)
382 /*EMPTY*/ ;
383 if (vars)
384 fprint_objid(stderr, vars->name, vars->name_length);
385 fprintf(stderr, "\n");
386 }
387
388 /* retry if the errored variable was successfully removed */
389 pdu = snmp_fix_pdu(response, SNMP_MSG_GET);
390 snmp_free_pdu(response);
391 response = NULL;
392 if (pdu != NULL)
393 goto retry;
394
395 } /* endif -- SNMP_ERR_NOERROR */
396
397 } else if (status == STAT_TIMEOUT){
398 snmp_close(ss);
399 return g_strdup_printf("Timeout: No Response from %s.\n", session.peername);
400
401 } else { /* status == STAT_ERROR */
402 fprintf (stderr, "local port set to: %d\n", session.local_port);
403 snmp_sess_perror("STAT_ERROR", ss);
404 snmp_close(ss);
405 return NULL;
406
407 } /* endif -- STAT_SUCCESS */
408
409 if (response)
410 snmp_free_pdu(response);
411 snmp_close(ss);
412
413 return result;
414 }
415
416 int
417 snmp_input(int op,
418 struct snmp_session *session,
419 int reqid,
420 struct snmp_pdu *pdu,
421 void *magic)
422 {
423 struct variable_list *vars;
424 gint asn1_type = 0;
425 gchar *result = NULL;
426 u_long result_n = 0;
427
428 gchar *error = NULL;
429 u_long time = 0;
430 Reader *reader = NULL;
431
432 if (op == RECEIVED_MESSAGE) {
433
434 if (pdu->errstat == SNMP_ERR_NOERROR) {
435
436 /*
437 fprintf(stderr, "recv from (@ %ld): %s type: %d\n",
438 pdu->time, session->peername, pdu->variables->type);
439 */
440
441 for(vars = pdu->variables; vars; vars = vars->next_variable) {
442 switch (vars->type) {
443 case ASN_TIMETICKS:
444 time = *vars->val.integer;
445 break;
446 case ASN_OCTET_STR: /* value is a string */
447 asn1_type = ASN_OCTET_STR;
448 result = g_strndup(vars->val.string, vars->val_len);
449 break;
450 case ASN_INTEGER: /* value is a integer */
451 case ASN_COUNTER: /* use as if it were integer */
452 case ASN_UNSIGNED: /* use as if it were integer */
453 asn1_type = ASN_INTEGER;
454 result_n = *vars->val.integer;
455 result = g_strdup_printf("%ld", *vars->val.integer);
456 break;
457 default:
458 fprintf(stderr, "recv unknown ASN type: %d - please report to zany@triq.net\n", vars->type);
459 }
460 }
461
462 } else {
463 error = g_strdup_printf("Error in packet\nReason: %s",
464 snmp_errstring(pdu->errstat));
465
466 if (pdu->errstat == SNMP_ERR_NOSUCHNAME) {
467 error = g_strdup_printf("Error! This name doesn't exist!");
468 }
469 }
470
471
472 } else if (op == TIMED_OUT){
473 error = g_strdup_printf("Error! SNMP Timeout.");
474 }
475 /* we use session's callback magic to pass back data */
476 if (session->callback_magic) {
477 reader = session->callback_magic;
478 if (error) {
479 if (reader->error)
480 g_free(reader->error);
481 reader->error = error;
482 } else {
483 if (reader->error)
484 {
485 g_free (reader->error);
486 reader->error = NULL;
487 }
488 if (reader->sample)
489 g_free(reader->sample);
490 /* should we save data ? */
491 /*
492 if (reader->old_sample)
493 g_free(reader->old_sample);
494 reader->old_sample = reader->sample;
495 reader->old_sample-time = reader->sample_time;
496 */
497 reader->asn1_type = asn1_type;
498 reader->sample = result;
499 reader->sample_n = result_n;
500 reader->sample_time = time;
501
502 if (strcmp(reader->oid_str, "sysUpTime.0") == 0) {
503 reader->asn1_type = ASN_TIMETICKS;
504 reader->sample_n = time;
505 reader->sample= strdup_uptime (time);
506 }
507 }
508 }
509 return 1;
510 }
511
512 void
513 simpleSNMPupdate()
514 {
515 int count;
516 int numfds, block;
517 fd_set fdset;
518 struct timeval timeout, *tvp;
519
520 numfds = 0;
521 FD_ZERO(&fdset);
522 block = 0;
523 tvp = &timeout;
524 timerclear(tvp);
525 tvp->tv_sec = 0;
526 snmp_select_info(&numfds, &fdset, tvp, &block);
527 /* if (block == 1)
528 tvp = NULL; */ /* block without timeout */
529 count = select(numfds, &fdset, 0, 0, tvp);
530 if (count > 0){
531 snmp_read(&fdset);
532 } else switch(count){
533 case 0:
534 snmp_timeout();
535 break;
536 case -1:
537 fprintf(stderr, "snmp error on select\n");
538 break;
539 default:
540 fprintf(stderr, "select returned %d\n", count);
541 }
542 }
543
544 struct snmp_session *
545 simpleSNMPopen(gchar *peername,
546 gint port,
547 gchar *community,
548 void *data)
549 {
550 struct snmp_session session, *ss;
551
552 /*
553 * initialize session to default values
554 */
555 snmp_sess_init( &session );
556
557 session.version = SNMP_VERSION_1;
558 session.community = community;
559 session.community_len = strlen(community);
560 session.peername = peername;
561 session.remote_port = port;
562
563 session.retries = SNMP_DEFAULT_RETRIES;
564 session.timeout = SNMP_DEFAULT_TIMEOUT;
565
566 session.callback = snmp_input;
567 session.callback_magic = data; /* most likely a Reader */
568 session.authenticator = NULL;
569
570 #ifdef STREAM
571 session.flags |= SNMP_FLAGS_STREAM_SOCKET;
572 #endif
573
574 /*
575 * Open an SNMP session.
576 */
577 ss = snmp_open(&session);
578 if (ss == NULL){
579 snmp_sess_perror("snmp_open", &session);
580 // exit(1);
581 }
582
583 return ss;
584 }
585
586 void
587 simpleSNMPsend(struct snmp_session *session,
588 oid *name,
589 size_t name_length)
590 {
591 struct snmp_pdu *pdu;
592 oid uptime[MAX_OID_LEN];
593 size_t uptime_length;
594
595 /*
596 * Create PDU for GET request and add object names to request.
597 */
598 pdu = snmp_pdu_create(SNMP_MSG_GET);
599
600 /*
601 * First insert uptime request into PDU.
602 */
603 uptime_length = MAX_OID_LEN;
604 if (!snmp_parse_oid("system.sysUpTime.0",
605 uptime, &uptime_length)) {
606 printf("error parsing oid: system.sysUpTime.0\n");
607 }
608 snmp_add_null_var(pdu, uptime, uptime_length);
609
610 snmp_add_null_var(pdu, name, name_length);
611
612 /*
613 * Perform the request.
614 */
615
616 snmp_send(session, pdu);
617 }
618
619
620 /* GKrellM Callbacks */
621
622 static void
623 cb_draw_chart(gpointer data)
624 {
625 Reader *reader = (Reader *)data;
626
627 gchar *text = render_label(reader);
628 gkrellm_draw_chartdata(reader->chart);
629 gkrellm_draw_chart_text(reader->chart,
630 DEFAULT_STYLE_ID,
631 text);
632 gkrellm_draw_chart_to_screen(reader->chart);
633 g_free(text);
634 }
635
636 static void
637 cb_chart_click(GtkWidget *widget, GdkEventButton *event, gpointer data)
638 {
639 if (event->button == 3)
640 gkrellm_chartconfig_window_create(data);
641 }
642
643 /* GKrellM interface */
644
645 static GkrellmMonitor *mon;
646 static Reader *readers;
647 static GtkWidget *main_vbox;
648
649 static void
650 update_plugin()
651 {
652 Reader *reader;
653 gchar *text;
654 u_long val, since_last;
655 gint clock_style_id;
656 // GkrellmKrell *k;
657 // gint i;
658
659 /* See if we recieved SNMP responses */
660 simpleSNMPupdate();
661
662 /* Send new SNMP requests */
663 for (reader = readers; reader ; reader = reader->next)
664 {
665 // k = KRELL(panel);
666 // k->previous = 0;
667
668 if ( (! reader->session) && (! reader->old_error) ) {
669 reader->session = simpleSNMPopen(reader->peer,
670 reader->port,
671 reader->community,
672 reader);
673 if (! reader->session) {
674 text = reader->old_error;
675 reader->old_error = render_error(reader);
676 g_free(text);
677 }
678 }
679
680 /* Send new SNMP requests */
681 if ( (reader->session) && ((GK.timer_ticks % reader->delay) == 0))
682 simpleSNMPsend(reader->session,
683 reader->objid,
684 reader->objid_length);
685
686
687 if ( (reader->session) && (reader->sample) ) {
688 if ((reader->error) && (reader->panel != NULL)) {
689 if (!reader->old_error ||
690 strcmp(reader->error,
691 reader->old_error) ) {
692 text = reader->old_error;
693 reader->old_error = g_strdup(reader->error);
694 g_free(text);
695 reader->panel->textstyle = gkrellm_panel_alt_textstyle(DEFAULT_STYLE_ID);
696 text = render_error(reader);
697 gtk_tooltips_set_tip(reader->tooltip, reader->panel->drawing_area, text, "");
698 gtk_tooltips_enable(reader->tooltip);
699 g_free(text);
700 }
701 } else {
702 if ((GK.timer_ticks % reader->delay) == 0)
703 if (reader->chart != NULL)
704 {
705 /* 100: turn TimeTicks into seconds */
706 since_last = (reader->sample_time - reader->old_sample_time) / 100;
707
708 if (reader->delta)
709 val = (reader->sample_n - reader->old_sample_n) /
710 ( (since_last < 1) ? 1 : since_last ) /
711 ( (reader->divisor == 0) ? 1 : reader->divisor );
712 else
713 val = reader->sample_n /
714 ( (reader->divisor == 0) ? 1 : reader->divisor );
715
716 gkrellm_store_chartdata(reader->chart, 0, val);
717 cb_draw_chart(reader);
718
719 text = render_info(reader);
720 gtk_tooltips_set_tip(reader->tooltip, reader->chart->drawing_area, text, "");
721 gtk_tooltips_enable(reader->tooltip);
722 g_free(text);
723
724 reader->old_sample_n = reader->sample_n;
725 reader->old_sample_time = reader->sample_time;
726 }
727
728 /* if there are changes update label */
729 if (reader->panel != NULL)
730 {
731 reader->panel->textstyle = gkrellm_panel_textstyle(DEFAULT_STYLE_ID);
732 if ( !reader->old_sample || strcmp(reader->sample,
733 reader->old_sample) ||
734 (reader->sample_n != reader->old_sample_n) ) {
735
736 g_free(reader->old_sample);
737 reader->old_sample = g_strdup(reader->sample);
738
739 text = render_label(reader);
740 gkrellm_dup_string(&reader->panel->label->string, text);
741 g_free(text);
742 // i = atoi(text);
743
744 text = render_info(reader);
745 gtk_tooltips_set_tip(reader->tooltip, reader->panel->drawing_area, text, "");
746 gtk_tooltips_enable(reader->tooltip);
747
748 g_free(text);
749 reader->old_sample_n = reader->sample_n;
750 reader->old_sample_time = reader->sample_time;
751 }
752 }
753 }
754
755 } else {
756 if (reader->panel != NULL)
757 reader->panel->textstyle = gkrellm_panel_alt_textstyle(DEFAULT_STYLE_ID);
758 if (reader->panel != NULL)
759 gtk_tooltips_disable(reader->tooltip);
760 // i = -1;
761 }
762
763 // gkrellm_update_krell(panel, k, i);
764
765 clock_style_id = gkrellm_lookup_meter_style_id(CLOCK_STYLE_NAME);
766
767 if (reader->panel != NULL)
768 gkrellm_draw_panel_label( reader->panel );
769 //GTK2 gkrellm_bg_panel_piximage(clock_style_id) );
770 if (reader->panel != NULL)
771 gkrellm_draw_panel_layers(reader->panel);
772 }
773
774 }
775
776 static gint
777 panel_expose_event(GtkWidget *widget, GdkEventExpose *ev)
778 {
779 Reader *reader;
780
781 for (reader = readers; reader ; reader = reader->next)
782 if ((reader->panel) && (widget == reader->panel->drawing_area)) {
783
784 gdk_draw_pixmap(widget->window,
785 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
786 reader->panel->pixmap,
787 ev->area.x, ev->area.y, ev->area.x, ev->area.y,
788 ev->area.width, ev->area.height);
789 }
790 return FALSE;
791 }
792
793 static gint
794 chart_expose_event(GtkWidget *widget, GdkEventExpose *ev)
795 {
796 Reader *reader;
797
798 for (reader = readers; reader ; reader = reader->next)
799 if ((reader->chart) && (widget == reader->chart->drawing_area)) {
800
801 gdk_draw_pixmap(widget->window,
802 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
803 reader->chart->pixmap,
804 ev->area.x, ev->area.y, ev->area.x, ev->area.y,
805 ev->area.width, ev->area.height);
806 }
807 return FALSE;
808 }
809
810 static void
811 create_chart(GtkWidget *vbox, Reader *reader, gint first_create)
812 {
813 if (first_create)
814 reader->chart = gkrellm_chart_new0();
815
816 // gkrellm_set_chart_height_default(reader->chart, 20);
817
818 gkrellm_chart_create(vbox, mon, reader->chart, &reader->chart_config);
819
820 gkrellm_chartconfig_grid_resolution_adjustment(reader->chart_config,
821 /*map*/TRUE, /*spin_factor*/1.0, /*low*/1, /*high*/100000000,
822 /*step0*/0, /*step1*/0, /*digits*/0, /*width*/50);
823
824 reader->chart_data = gkrellm_add_default_chartdata(reader->chart, "Plugin Data");
825
826 gkrellm_monotonic_chartdata(reader->chart_data, FALSE);
827
828 gkrellm_set_chartdata_draw_style_default(reader->chart_data, CHARTDATA_LINE);
829 gkrellm_set_chartdata_flags(reader->chart_data, CHARTDATA_ALLOW_HIDE);
830
831 gkrellm_alloc_chartdata(reader->chart);
832
833 if (first_create)
834 {
835 gkrellm_set_draw_chart_function(reader->chart, cb_draw_chart, reader);
836 gtk_signal_connect(GTK_OBJECT(reader->chart->drawing_area),
837 "expose_event", (GtkSignalFunc) chart_expose_event, NULL);
838 gtk_signal_connect(GTK_OBJECT(reader->chart->drawing_area),
839 "button_press_event", (GtkSignalFunc) cb_chart_click, reader->chart);
840 reader->tooltip=gtk_tooltips_new();
841 }
842 else
843 {
844 gkrellm_draw_chartdata(reader->chart);
845 gkrellm_draw_chart_to_screen(reader->chart);
846 }
847
848 }
849
850 static void
851 create_panel(GtkWidget *vbox, Reader *reader, gint first_create)
852 {
853 // GkrellmKrell *k;
854 GkrellmStyle *style;
855 // GkrellmPiximage *krell_piximage;
856 gchar *text;
857
858 if (first_create)
859 reader->panel = gkrellm_panel_new0();
860 else
861 gkrellm_destroy_krell_list(reader->panel);
862
863 /* Create a krell. A Krell structure is allocated and linked into
864 | the list of krells pointed to by panel->krell.
865 */
866 style = gkrellm_meter_style(DEFAULT_STYLE_ID);
867 //GTK2 style->label_position = LABEL_CENTER;
868 // krell_piximage = gkrellm_krell_meter_piximage(DEFAULT_STYLE_ID);
869 // k = gkrellm_create_krell(panel, krell_piximage, style);
870 // k->full_scale = 30;
871
872 /* Configure panel calculates the panel height needed for the "Plugin" label.
873 | and the krell.
874 */
875 reader->panel->textstyle = gkrellm_meter_textstyle(DEFAULT_STYLE_ID);
876 gkrellm_panel_configure(reader->panel, "SNMP", style);
877
878 // reader->panel->textstyle = gkrellm_panel_alt_textstyle(DEFAULT_STYLE_ID);
879
880
881 /* Build the configured panel with a background image and pack it into
882 | the vbox assigned to this monitor.
883 */
884 //dep: gkrellm_create_panel(vbox, reader->panel, gkrellm_bg_meter_piximage(DEFAULT_STYLE_ID));
885 gkrellm_panel_create(vbox, mon, reader->panel);
886 gkrellm_monitor_height_adjust(reader->panel->h);
887
888 if (first_create) {
889 gtk_signal_connect(GTK_OBJECT (reader->panel->drawing_area),
890 "expose_event",
891 (GtkSignalFunc) panel_expose_event, NULL);
892 reader->tooltip=gtk_tooltips_new();
893 }
894
895 /* refresh the display */
896 text = render_label(reader);
897 gkrellm_dup_string(&reader->panel->label->string, text);
898 g_free(text);
899 }
900
901 static void
902 create_reader(GtkWidget *vbox, Reader *reader, gint first_create)
903 {
904 if (1) /* FIXME */
905 create_chart(vbox, reader, first_create);
906 else
907 create_panel(vbox, reader, first_create);
908 }
909
910 static void
911 destroy_reader(Reader *reader)
912 {
913 if (!reader)
914 return;
915
916 reader->session->callback_magic = 0; /* detach the callback */
917 g_free(reader->label);
918 g_free(reader->peer);
919 g_free(reader->community);
920 g_free(reader->oid_str);
921 g_free(reader->unit);
922
923 g_free(reader->sample);
924 g_free(reader->old_sample);
925
926 /* can't free snmp session. may be there are pending snmp_reads! */
927 /*
928 if (reader->session)
929 snmp_close(reader->session);
930 g_free(reader->session);
931 */
932
933 if (reader->panel)
934 {
935 gkrellm_monitor_height_adjust( - reader->panel->h);
936 gkrellm_panel_destroy(reader->panel);
937 }
938
939 if (reader->chart)
940 {
941 gkrellm_monitor_height_adjust( - reader->chart->h);
942 gkrellm_chartconfig_destroy(&reader->chart_config);
943 gkrellm_chart_destroy(reader->chart);
944 }
945
946 // gtk_widget_destroy(reader->vbox);
947 g_free(reader);
948 }
949
950 static void
951 create_plugin(GtkWidget *vbox, gint first_create)
952 {
953 Reader *reader;
954
955 main_vbox = vbox;
956
957 for (reader = readers; reader ; reader = reader->next) {
958 create_reader(vbox, reader, first_create);
959 }
960 }
961
962 /* Config section */
963
964 static GtkWidget *label_entry;
965 static GtkWidget *peer_entry;
966 static GtkObject *port_spin_adj;
967 static GtkWidget *port_spin;
968 static GtkWidget *community_entry;
969 static GtkWidget *oid_entry;
970 static GtkWidget *unit_entry;
971 static GtkObject *freq_spin_adj;
972 static GtkWidget *freq_spin;
973 static GtkObject *div_spin_adj;
974 static GtkWidget *div_spin;
975 static GtkWidget *delta_button;
976 static GtkWidget *scale_button;
977 static GtkWidget *reader_clist;
978 static gint selected_row = -1;
979 static gint list_modified;
980 #define CLIST_WIDTH 11
981
982 #define STR_DELIMITERS " \t"
983
984 static void
985 save_plugin_config(FILE *f)
986 {
987 Reader *reader;
988 gchar *label, *unit;
989
990 for (reader = readers; reader ; reader = reader->next) {
991 label = g_strdelimit(g_strdup(reader->label), STR_DELIMITERS, '_');
992 unit = g_strdelimit(g_strdup(reader->unit), STR_DELIMITERS, '_');
993 if (label[0] == '\0') label = strdup("_");
994 if (unit[0] == '\0') unit = strdup("_");
995 fprintf(f, "%s %s snmp://%s@%s:%d/%s %s %d %d %d %d\n",
996 PLUGIN_CONFIG_KEYWORD,
997 label, reader->community,
998 reader->peer, reader->port,
999 reader->oid_str, unit,
1000 reader->delay, reader->delta,
1001 reader->divisor, reader->scale);
1002 gkrellm_save_chartconfig(f, reader->chart_config, PLUGIN_CONFIG_KEYWORD, label);
1003 g_free(label);
1004 g_free(unit);
1005 }
1006 }
1007
1008 static void
1009 load_plugin_config(gchar *config_line)
1010 {
1011 Reader *reader, *nreader = NULL;
1012
1013 gchar proto[CFG_BUFSIZE], bufl[CFG_BUFSIZE];
1014 gchar bufc[CFG_BUFSIZE], bufp[CFG_BUFSIZE];
1015 gchar bufo[CFG_BUFSIZE], bufu[CFG_BUFSIZE];
1016 gchar buft[CFG_BUFSIZE], peer[CFG_BUFSIZE];
1017 gint n;
1018
1019 if (sscanf(config_line, GKRELLM_CHARTCONFIG_KEYWORD " %s %[^\n]", bufl, bufc) == 2) {
1020 g_strdelimit(bufl, "_", ' ');
1021 /* look for any such reader */
1022 for (reader = readers; reader ; reader = reader->next) {
1023 if (!strcmp(reader->label, bufl)) {
1024 nreader = reader;
1025 break;
1026 }
1027 }
1028 /* look for unconf'd reader */
1029 for (reader = readers; reader ; reader = reader->next) {
1030 if (!strcmp(reader->label, bufl) && !reader->chart_config) {
1031 nreader = reader;
1032 break;
1033 }
1034 }
1035 if (!nreader) {/* well... */
1036 fprintf(stderr, "chart_config appeared before chart, this isn't handled\n%s\n", config_line);
1037 return;
1038 }
1039 //"chart_config in "
1040 gkrellm_load_chartconfig(&nreader->chart_config, bufc, /*max_cd*/1);
1041 return;
1042 }
1043
1044 reader = g_new0(Reader, 1);
1045
1046 n = sscanf(config_line, "%s %[^:]://%[^@]@%[^:]:%[^:]:%d/%s %s %d %d %d %d",
1047 bufl, proto, bufc, buft, bufp, &reader->port, bufo, bufu,
1048 &reader->delay, &reader->delta,
1049 &reader->divisor, &reader->scale);
1050 if (n >= 6) {
1051 g_snprintf(peer, CFG_BUFSIZE, "%s:%s", buft, bufp);
1052 peer[CFG_BUFSIZE-1] = '\0';
1053 } else
1054 n = sscanf(config_line, "%s %[^:]://%[^@]@%[^:]:%d/%s %s %d %d %d %d",
1055 bufl, proto, bufc, peer, &reader->port, bufo, bufu,
1056 &reader->delay, &reader->delta,
1057 &reader->divisor, &reader->scale);
1058 if (n >= 7)
1059 {
1060 if (g_strcasecmp(proto, "snmp") == 0) {
1061 gkrellm_dup_string(&reader->label, bufl);
1062 gkrellm_dup_string(&reader->community, bufc);
1063 gkrellm_dup_string(&reader->peer, peer);
1064 if (reader->delay < 10)
1065 reader->delay = 100;
1066 if (reader->divisor == 0)
1067 reader->divisor = 1;
1068
1069 gkrellm_dup_string(&reader->oid_str, bufo);
1070
1071 reader->objid_length = MAX_OID_LEN;
1072 if (!snmp_parse_oid(reader->oid_str,
1073 reader->objid, &reader->objid_length)) {
1074 //FIXME:
1075 printf("error parsing oid: %s\n", reader->oid_str);
1076 }
1077
1078 if (n > 7) {
1079 gkrellm_dup_string(&reader->unit, bufu);
1080 } else {
1081 gkrellm_dup_string(&reader->unit, "");
1082 }
1083
1084 g_strdelimit(reader->label, "_", ' ');
1085 g_strdelimit(reader->unit, "_", ' ');
1086
1087 // reader->old_sample = "SNMP"; // be nice.
1088 }
1089
1090 if (!readers)
1091 readers = reader;
1092 else {
1093 for (nreader = readers; nreader->next ; nreader = nreader->next);
1094 nreader->next = reader;
1095 }
1096
1097 }
1098 }
1099
1100 static void
1101 apply_plugin_config()
1102 {
1103 Reader *reader, *nreader;
1104 gchar *name;
1105 gint row;
1106
1107 if (!list_modified)
1108 return;
1109
1110 for (reader = readers; reader; reader = readers) {
1111 readers = reader->next;
1112 destroy_reader(reader);
1113 }
1114
1115 for (row = 0; row < GTK_CLIST(reader_clist)->rows; ++row)
1116 {
1117 gint i;
1118 i = 0;
1119 reader = g_new0(Reader, 1);
1120
1121 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1122 gkrellm_dup_string(&reader->label, name);
1123
1124 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1125 gkrellm_dup_string(&reader->peer, name);
1126
1127 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1128 reader->port = atoi(name);
1129
1130 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1131 gkrellm_dup_string(&reader->community, name);
1132
1133 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1134 gkrellm_dup_string(&reader->oid_str, name);
1135 reader->objid_length = MAX_OID_LEN;
1136 if (!snmp_parse_oid(reader->oid_str,
1137 reader->objid, &reader->objid_length)) {
1138 //FIXME:
1139 printf("error parsing oid: %s\n", reader->oid_str);
1140 }
1141
1142 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1143 gkrellm_dup_string(&reader->unit, name);
1144
1145 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1146 reader->delay = atoi(name);
1147
1148 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1149 reader->divisor = atoi(name);
1150
1151 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1152 reader->delta = (strcmp(name, "yes") == 0) ? TRUE : FALSE;
1153
1154 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1155 reader->scale = (strcmp(name, "yes") == 0) ? TRUE : FALSE;
1156
1157 gtk_clist_get_text(GTK_CLIST(reader_clist), row, i++, &name);
1158 reader->active = (strcmp(name, "yes") == 0) ? TRUE : FALSE;
1159
1160 if (!readers)
1161 readers = reader;
1162 else {
1163 for (nreader = readers; nreader->next ; nreader = nreader->next);
1164 nreader->next = reader;
1165 }
1166 create_reader(main_vbox, reader, 1);
1167 }
1168 list_modified = 0;
1169 }
1170
1171
1172 static void
1173 reset_entries()
1174 {
1175 gtk_entry_set_text(GTK_ENTRY(label_entry), "");
1176 gtk_entry_set_text(GTK_ENTRY(peer_entry), "");
1177 // gtk_entry_set_text(GTK_ENTRY(port_entry), "");
1178 gtk_entry_set_text(GTK_ENTRY(community_entry), "");
1179 gtk_entry_set_text(GTK_ENTRY(oid_entry), "");
1180 gtk_entry_set_text(GTK_ENTRY(unit_entry), "");
1181 // gtk_entry_set_text(GTK_ENTRY(freq_entry), "");
1182 // gtk_entry_set_text(GTK_ENTRY(div_entry), "");
1183 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(delta_button), FALSE);
1184 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scale_button), TRUE);
1185 // gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(active_button), FALSE);
1186 }
1187
1188
1189 static void
1190 cb_clist_selected(GtkWidget *clist, gint row, gint column,
1191 GdkEventButton *bevent)
1192 {
1193 gchar *s;
1194 gint state, i;
1195
1196 i = 0;
1197 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1198 gtk_entry_set_text(GTK_ENTRY(label_entry), s);
1199
1200 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1201 gtk_entry_set_text(GTK_ENTRY(peer_entry), s);
1202
1203 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1204 gtk_entry_set_text(GTK_ENTRY(port_spin), s);
1205 // gtk_spin_button_get_value_as_int(GTK_SPINBUTTON(port_spin), 161);
1206
1207 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1208 gtk_entry_set_text(GTK_ENTRY(community_entry), s);
1209
1210 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1211 gtk_entry_set_text(GTK_ENTRY(oid_entry), s);
1212
1213 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1214 gtk_entry_set_text(GTK_ENTRY(unit_entry), s);
1215
1216 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1217 gtk_entry_set_text(GTK_ENTRY(freq_spin), s);
1218
1219 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1220 gtk_entry_set_text(GTK_ENTRY(div_spin), s);
1221
1222 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1223 state = (strcmp(s, "yes") == 0) ? TRUE : FALSE;
1224 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(delta_button), state);
1225
1226 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1227 state = (strcmp(s, "yes") == 0) ? TRUE : FALSE;
1228 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scale_button), state);
1229
1230 gtk_clist_get_text(GTK_CLIST(clist), row, i++, &s);
1231 state = (strcmp(s, "yes") == 0) ? TRUE : FALSE;
1232 // gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(active_button), state);
1233
1234 selected_row = row;
1235 }
1236
1237 static void
1238 cb_clist_unselected(GtkWidget *clist, gint row, gint column,
1239 GdkEventButton *bevent)
1240 {
1241 reset_entries();
1242 selected_row = -1;
1243 }
1244
1245 static void
1246 cb_clist_up(GtkWidget *widget)
1247 {
1248 gint row;
1249
1250 row = selected_row;
1251 if (row > 0)
1252 {
1253 gtk_clist_row_move(GTK_CLIST(reader_clist), row, row - 1);
1254 gtk_clist_select_row(GTK_CLIST(reader_clist), row - 1, -1);
1255 if (gtk_clist_row_is_visible(GTK_CLIST(reader_clist), row - 1)
1256 != GTK_VISIBILITY_FULL)
1257 gtk_clist_moveto(GTK_CLIST(reader_clist), row - 1, -1, 0.0, 0.0);
1258 selected_row = row - 1;
1259 list_modified = TRUE;
1260 }
1261 }
1262
1263 static void
1264 cb_clist_down(GtkWidget *widget)
1265 {
1266 gint row;
1267
1268 row = selected_row;
1269 if (row >= 0 && row < GTK_CLIST(reader_clist)->rows - 1)
1270 {
1271 gtk_clist_row_move(GTK_CLIST(reader_clist), row, row + 1);
1272 gtk_clist_select_row(GTK_CLIST(reader_clist), row + 1, -1);
1273 if (gtk_clist_row_is_visible(GTK_CLIST(reader_clist), row + 1)
1274 != GTK_VISIBILITY_FULL)
1275 gtk_clist_moveto(GTK_CLIST(reader_clist), row + 1, -1, 1.0, 0.0);
1276 selected_row = row + 1;
1277 list_modified = TRUE;
1278 }
1279 }
1280
1281 static void
1282 cb_enter(GtkWidget *widget)
1283 {
1284 gchar *buf[CLIST_WIDTH];
1285 gint i;
1286
1287 i = 0;
1288 buf[i++] = gkrellm_gtk_entry_get_text(&label_entry);
1289 buf[i++] = gkrellm_gtk_entry_get_text(&peer_entry);
1290 buf[i++] = gkrellm_gtk_entry_get_text(&port_spin);
1291 buf[i++] = gkrellm_gtk_entry_get_text(&community_entry);
1292 buf[i++] = gkrellm_gtk_entry_get_text(&oid_entry);
1293 buf[i++] = gkrellm_gtk_entry_get_text(&unit_entry);
1294 buf[i++] = gkrellm_gtk_entry_get_text(&freq_spin);
1295 buf[i++] = gkrellm_gtk_entry_get_text(&div_spin);
1296 buf[i++] = GTK_TOGGLE_BUTTON(delta_button)->active ? "yes" : "no";
1297 buf[i++] = GTK_TOGGLE_BUTTON(scale_button)->active ? "yes" : "no";
1298 buf[i++] = "yes"; // GTK_TOGGLE_BUTTON(active_button)->active ? "yes" : "no";
1299
1300 /* validate we have input */
1301 if (!*(buf[1]) || !*(buf[2]) || !*(buf[3]) || !*(buf[4]))
1302 {
1303 gkrellm_config_message_dialog("Entry Error",
1304 "Peer, Port, Community and OID must be entered.");
1305 return;
1306 }
1307 if (selected_row >= 0)
1308 {
1309 for (i = 0; i < CLIST_WIDTH; ++i)
1310 gtk_clist_set_text(GTK_CLIST(reader_clist), selected_row, i, buf[i]);
1311 gtk_clist_unselect_row(GTK_CLIST(reader_clist), selected_row, 0);
1312 selected_row = -1;
1313 }
1314 else
1315 gtk_clist_append(GTK_CLIST(reader_clist), buf);
1316 reset_entries();
1317 list_modified = TRUE;
1318 }
1319
1320 static void
1321 cb_delete(GtkWidget *widget)
1322 {
1323 reset_entries();
1324 if (selected_row >= 0)
1325 {
1326 gtk_clist_remove(GTK_CLIST(reader_clist), selected_row);
1327 list_modified = TRUE;
1328 selected_row = -1;
1329 }
1330 }
1331
1332 static void
1333 cb_probe(GtkWidget *widget)
1334 {
1335 gchar *peer;
1336 gint port;
1337 gchar *community;
1338 gchar *probe;
1339
1340 peer = gkrellm_gtk_entry_get_text(&peer_entry);
1341 port = atoi(gkrellm_gtk_entry_get_text(&port_spin));
1342 community = gkrellm_gtk_entry_get_text(&community_entry);
1343
1344 /* validate we have input */
1345 if (!*(peer) || !*(community))
1346 {
1347 gkrellm_config_message_dialog("Entry Error",
1348 "Peer, Port and Community must be entered.");
1349 return;
1350 }
1351 probe = snmp_probe(peer, port, community);
1352 gkrellm_config_message_dialog("SNMP Probe", probe);
1353 g_free(probe);
1354 }
1355
1356
1357 static gchar *plugin_info_text =
1358 "This configuration tab is for the SNMP monitor plugin.\n"
1359 "\n"
1360 "Adding new SNMP readers should be fairly easy.\n"
1361 "Peer, Port, Community and OID are the respective SNMP parameters.\n"
1362 "Whereas Port ist preselected with the default value 161.\n"
1363 "Freq sets the delay between updates of the reader value.\n"
1364 "It's measured in GKrellM ticks -- that's 1/10 seconds.\n"
1365 "Label is a unique name that gets prepended to your reader.\n"
1366 "Unit is just a string thats appended to your reader.\n"
1367 "You can prepend a specific transport to the peer name.\n"
1368 "(i.e. tcp:192.168.0.1)\n"
1369 "\n"
1370 "Some examples:\n"
1371 "\n"
1372 "(1)\n"
1373 "The ambiente temperature sensor for some net-snmp server\n"
1374 "public / 192.168.1.2 port 161 oid .1.3.6.1.4.1.2021.8.1.101.1\n"
1375 "\n"
1376 "That is:\n"
1377 " SNMP peer '192.168.1.2' (some.server.name)\n"
1378 " SNMP port '161' (that's the default)\n"
1379 " SNMP community name 'public'\n"
1380 " SNMP oid '.1.3.6.1.4.1.2021.8.1.101.1'\n"
1381 "\n"
1382 "Resonable Label/Unit would be 'Temp.' / '°C'\n"
1383 "\n"
1384 "(2)\n"
1385 "\n"
1386 "Server CPU load using a string ranging from 0.00 to 1.00\n"
1387 "\n"
1388 "public / 192.168.1.3 pot 161 oid .1.3.6.1.4.1.2021.10.1.3.1\n"
1389 "(Thats the load factor for some server)\n"
1390 "\n"
1391 "(3)\n"
1392 "\n"
1393 "Server CPU load using integer variable ranging from 0 to 100\n"
1394 "\n"
1395 "public / 192.168.1.4 port 161 oid .1.3.6.1.4.1.2021.10.1.5.1\n"
1396 "(Thats the percentile load for some server)\n"
1397 "\n"
1398 "please mail any problems/questions to me...\n"
1399 ;
1400
1401 static gchar *plugin_about_text =
1402 "SNMP plugin 1.0\n"
1403 "GKrellM SNMP monitor Plugin\n\n"
1404 "Copyright (C) 2000-2006 Christian W. Zuckschwerdt <zany@triq.net>\n"
1405 "\n"
1406 "http://triq.net/gkrellm.html\n\n"
1407 "Released under the GNU Public Licence with OpenSSL exemption"
1408 ;
1409
1410 static gchar *reader_title[CLIST_WIDTH] =
1411 { "Label", "Peer", "Port",
1412 "Community", "OID", "Unit",
1413 "Freq", "Divisor", "Delta", "Scale", "Active" };
1414
1415 static void
1416 create_plugin_tab(GtkWidget *tab_vbox)
1417 {
1418 Reader *reader;
1419
1420 GtkWidget *tabs;
1421 GtkWidget *vbox;
1422 GtkWidget *hbox;
1423 GtkWidget *button;
1424 GtkWidget *arrow;
1425 GtkWidget *scrolled;
1426 GtkWidget *text;
1427 GtkWidget *label;
1428
1429 gchar *buf[CLIST_WIDTH];
1430 gint row, i;
1431
1432 /* Make a couple of tabs. One for setup and one for info
1433 */
1434 tabs = gtk_notebook_new();
1435 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tabs), GTK_POS_TOP);
1436 gtk_box_pack_start(GTK_BOX(tab_vbox), tabs, TRUE, TRUE, 0);
1437
1438 /* --- Setup tab */
1439 vbox = gkrellm_gtk_framed_notebook_page(tabs, "Setup");
1440
1441 hbox = gtk_hbox_new(FALSE,0);
1442
1443 label = gtk_label_new("Label : ");
1444 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1445 label_entry = gtk_entry_new();
1446 gtk_entry_set_text(GTK_ENTRY(label_entry), "");
1447 gtk_box_pack_start(GTK_BOX(hbox),label_entry,FALSE,FALSE,0);
1448
1449 label = gtk_label_new("Peer : ");
1450 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1451 peer_entry = gtk_entry_new();
1452 gtk_entry_set_text(GTK_ENTRY(peer_entry), "");
1453 gtk_box_pack_start(GTK_BOX(hbox),peer_entry,FALSE,FALSE,0);
1454
1455 label = gtk_label_new("Port : ");
1456 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1457 port_spin_adj = gtk_adjustment_new (161, 1, 65535, 1, 10, 10);
1458 port_spin = gtk_spin_button_new (GTK_ADJUSTMENT (port_spin_adj), 1, 0);
1459 gtk_box_pack_start(GTK_BOX(hbox),port_spin,FALSE,FALSE,0);
1460
1461 label = gtk_label_new("Freq : ");
1462 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1463 freq_spin_adj = gtk_adjustment_new (100, 10, 6000, 10, 100, 100);
1464 freq_spin = gtk_spin_button_new (GTK_ADJUSTMENT (freq_spin_adj), 1, 0);
1465 gtk_box_pack_start(GTK_BOX(hbox),freq_spin,FALSE,FALSE,0);
1466
1467 gtk_container_add(GTK_CONTAINER(vbox),hbox);
1468 hbox = gtk_hbox_new(FALSE,0);
1469
1470 label = gtk_label_new("Community : ");
1471 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1472 community_entry = gtk_entry_new();
1473 gtk_entry_set_text(GTK_ENTRY(community_entry), "");
1474 gtk_box_pack_start(GTK_BOX(hbox), community_entry, FALSE, FALSE, 0);
1475
1476 label = gtk_label_new("OID : ");
1477 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1478 oid_entry = gtk_entry_new();
1479 gtk_entry_set_text(GTK_ENTRY(oid_entry), "");
1480 gtk_box_pack_start(GTK_BOX(hbox), oid_entry, FALSE, FALSE, 0);
1481
1482 label = gtk_label_new("Unit : ");
1483 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1484 unit_entry = gtk_entry_new();
1485 gtk_entry_set_text(GTK_ENTRY(unit_entry), "");
1486 gtk_box_pack_start(GTK_BOX(hbox),unit_entry,FALSE,FALSE,0);
1487
1488 gtk_container_add(GTK_CONTAINER(vbox),hbox);
1489 hbox = gtk_hbox_new(FALSE,0);
1490
1491 label = gtk_label_new("Divisor : ");
1492 gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
1493 div_spin_adj = gtk_adjustment_new (1, 1, 1024, 1, 1, 1);
1494 div_spin = gtk_spin_button_new (GTK_ADJUSTMENT (div_spin_adj), 1, 0);
1495 gtk_box_pack_start(GTK_BOX(hbox),div_spin,FALSE,FALSE,0);
1496
1497 delta_button = gtk_check_button_new_with_label("Compute delta");
1498 gtk_box_pack_start(GTK_BOX(hbox),delta_button,FALSE,FALSE,0);
1499
1500 scale_button = gtk_check_button_new_with_label("Auto scale");
1501 gtk_box_pack_start(GTK_BOX(hbox),scale_button,FALSE,FALSE,0);
1502
1503 button = gtk_button_new_with_label("Probe");
1504 gtk_signal_connect(GTK_OBJECT(button), "clicked",
1505 (GtkSignalFunc) cb_probe, NULL);
1506 gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 4);
1507
1508 gtk_container_add(GTK_CONTAINER(vbox),hbox);
1509
1510 hbox = gtk_hbox_new(FALSE, 3);
1511 gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2);
1512 /*
1513 *mount_button = gtk_check_button_new_with_label(
1514 "Enable /etc/fstab mounting");
1515 gtk_box_pack_start(GTK_BOX(hbox), *mount_button, TRUE, TRUE, 0);
1516 gtk_signal_connect(GTK_OBJECT(GTK_BUTTON(*mount_button)), "clicked",
1517 GTK_SIGNAL_FUNC (cb_mount_button_clicked), NULL);
1518 */
1519
1520 button = gtk_button_new();
1521 arrow = gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_ETCHED_OUT);
1522 gtk_container_add(GTK_CONTAINER(button), arrow);
1523 gtk_signal_connect(GTK_OBJECT(button), "clicked",
1524 (GtkSignalFunc) cb_clist_up, NULL);
1525 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 4);
1526
1527 button = gtk_button_new();
1528 arrow = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_ETCHED_OUT);
1529 gtk_container_add(GTK_CONTAINER(button), arrow);
1530 gtk_signal_connect(GTK_OBJECT(button), "clicked",
1531 (GtkSignalFunc) cb_clist_down, NULL);
1532 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 4);
1533
1534 button = gtk_button_new_with_label("Enter");
1535 gtk_signal_connect(GTK_OBJECT(button), "clicked",
1536 (GtkSignalFunc) cb_enter, NULL);
1537 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 4);
1538
1539 button = gtk_button_new_with_label("Delete");
1540 gtk_signal_connect(GTK_OBJECT(button), "clicked",
1541 (GtkSignalFunc) cb_delete, NULL);
1542 gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 4);
1543
1544
1545 scrolled = gtk_scrolled_window_new(NULL, NULL);
1546 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1547 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1548 gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
1549
1550 reader_clist = gtk_clist_new_with_titles(CLIST_WIDTH, reader_title);
1551 gtk_clist_set_shadow_type (GTK_CLIST(reader_clist), GTK_SHADOW_OUT);
1552 gtk_clist_set_column_width (GTK_CLIST(reader_clist), 1, 100);
1553 gtk_clist_set_column_width (GTK_CLIST(reader_clist), 4, 100);
1554
1555 gtk_signal_connect(GTK_OBJECT(reader_clist), "select_row",
1556 (GtkSignalFunc) cb_clist_selected, NULL);
1557 gtk_signal_connect(GTK_OBJECT(reader_clist), "unselect_row",
1558 (GtkSignalFunc) cb_clist_unselected, NULL);
1559
1560 gtk_container_add(GTK_CONTAINER(scrolled), reader_clist);
1561
1562 for (reader = readers; reader; reader = reader->next)
1563 {
1564 i = 0;
1565 buf[i++] = reader->label;
1566 buf[i++] = reader->peer;
1567 buf[i++] = g_strdup_printf("%d", reader->port);
1568 buf[i++] = reader->community;
1569 buf[i++] = reader->oid_str;
1570 buf[i++] = reader->unit;
1571 buf[i++] = g_strdup_printf("%d", reader->delay);
1572 buf[i++] = g_strdup_printf("%d", reader->divisor);
1573 buf[i++] = reader->delta ? "yes" : "no";
1574 buf[i++] = reader->scale ? "yes" : "no";
1575 buf[i++] = reader->active ? "yes" : "no";
1576 row = gtk_clist_append(GTK_CLIST(reader_clist), buf);
1577 }
1578
1579
1580 /* --- Info tab */
1581 vbox = gkrellm_gtk_framed_notebook_page(tabs, "Info");
1582 // scrolled = gtk_scrolled_window_new(NULL, NULL);
1583 // gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
1584 // GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1585 // gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0);
1586 // text = gtk_text_new(NULL, NULL);
1587 text = gkrellm_gtk_scrolled_text_view(vbox, NULL, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1588 // gtk_text_insert(GTK_TEXT(text), NULL, NULL, NULL, plugin_info_text, -1);
1589 gkrellm_gtk_text_view_append(text, plugin_info_text);
1590 // gtk_text_set_editable(GTK_TEXT(text), FALSE);
1591 // gtk_container_add(GTK_CONTAINER(scrolled), text);
1592
1593 /* --- about text */
1594
1595 text = gtk_label_new(plugin_about_text);
1596
1597 gtk_notebook_append_page(GTK_NOTEBOOK(tabs), text,
1598 gtk_label_new("About"));
1599
1600 }
1601
1602
1603
1604
1605 static GkrellmMonitor plugin_mon =
1606 {
1607 PLUGIN_CONFIG_NAME, /* Name, for config tab. */
1608 0, /* Id, 0 if a plugin */
1609 create_plugin, /* The create_plugin() function */
1610 update_plugin, /* The update_plugin() function */
1611 create_plugin_tab, /* The create_plugin_tab() config function */
1612 apply_plugin_config, /* The apply_plugin_config() function */
1613
1614 save_plugin_config, /* The save_plugin_config() function */
1615 load_plugin_config, /* The load_plugin_config() function */
1616 PLUGIN_CONFIG_KEYWORD, /* config keyword */
1617
1618 NULL, /* Undefined 2 */
1619 NULL, /* Undefined 1 */
1620 NULL, /* Undefined 0 */
1621
1622 MON_MAIL, /* Insert plugin before this monitor. */
1623 NULL, /* Handle if a plugin, filled in by GKrellM */
1624 NULL /* path if a plugin, filled in by GKrellM */
1625 };
1626
1627 GkrellmMonitor *
1628 gkrellm_init_plugin(void)
1629 {
1630 readers = NULL;
1631
1632 #ifdef DEBUG_SNMP
1633 debug_register_tokens("all");
1634 snmp_set_do_debugging(1);
1635 #endif /* DEBUG_SNMP */
1636
1637 init_mib();
1638
1639 mon = &plugin_mon;
1640 return &plugin_mon;
1641 }