1 /*****************************************************************************
2 * RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
3 *****************************************************************************
4 * rrd_first Return
5 *****************************************************************************
6 * Initial version by Burton Strauss, ntopSupport.com - 3/2005
7 *****************************************************************************/
9 #include <stdlib.h>
10 #include "rrd_tool.h"
11 #include "rrd_client.h"
14 time_t rrd_first(
15 int argc,
16 char **argv)
17 {
18 int target_rraindex = 0;
19 char *endptr;
20 char *opt_daemon = NULL;
21 struct option long_options[] = {
22 {"rraindex", required_argument, 0, 129},
23 {"daemon", required_argument, 0, 'd'},
24 {0, 0, 0, 0}
25 };
27 optind = 0;
28 opterr = 0; /* initialize getopt */
30 while (1) {
31 int option_index = 0;
32 int opt;
34 opt = getopt_long(argc, argv, "d:F", long_options, &option_index);
36 if (opt == EOF)
37 break;
39 switch (opt) {
40 case 129:
41 target_rraindex = strtol(optarg, &endptr, 0);
42 if (target_rraindex < 0) {
43 rrd_set_error("invalid rraindex number");
44 return (-1);
45 }
46 break;
47 case 'd':
48 if (opt_daemon != NULL)
49 free (opt_daemon);
50 opt_daemon = strdup (optarg);
51 if (opt_daemon == NULL)
52 {
53 rrd_set_error ("strdup failed.");
54 return (-1);
55 }
56 break;
57 default:
58 rrd_set_error("usage rrdtool %s [--rraindex number] [--daemon <addr>] file.rrd",
59 argv[0]);
60 return (-1);
61 }
62 }
64 if (optind >= argc) {
65 rrd_set_error("usage rrdtool %s [--rraindex number] [--daemon <addr>] file.rrd",
66 argv[0]);
67 return -1;
68 }
70 rrdc_connect (opt_daemon);
71 if (rrdc_is_connected (opt_daemon)) {
72 return (rrdc_first (argv[optind], target_rraindex));
73 } else {
74 return (rrd_first_r(argv[optind], target_rraindex));
75 }
76 }
79 time_t rrd_first_r(
80 const char *filename,
81 const int rraindex)
82 {
83 off_t rra_start, timer;
84 time_t then = -1;
85 rrd_t rrd;
86 rrd_file_t *rrd_file;
88 rrd_init(&rrd);
89 rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
90 if (rrd_file == NULL) {
91 goto err_free;
92 }
94 if ((rraindex < 0) || (rraindex >= (int) rrd.stat_head->rra_cnt)) {
95 rrd_set_error("invalid rraindex number");
96 goto err_close;
97 }
99 rra_start = rrd_file->header_len;
100 rrd_seek(rrd_file,
101 (rra_start +
102 (rrd.rra_ptr[rraindex].cur_row + 1) *
103 rrd.stat_head->ds_cnt * sizeof(rrd_value_t)), SEEK_SET);
104 timer = -(long)(rrd.rra_def[rraindex].row_cnt - 1);
105 if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
106 rrd_seek(rrd_file, rra_start, SEEK_SET);
107 }
108 then = (rrd.live_head->last_up -
109 rrd.live_head->last_up %
110 (rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step)) +
111 (timer * rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step);
112 err_close:
113 rrd_close(rrd_file);
114 err_free:
115 rrd_free(&rrd);
116 return (then);
117 }