1 /*****************************************************************************
2 * RRDtool 1.4.2 Copyright by Tobi Oetiker, 1997-2009
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"
13 time_t rrd_first(
14 int argc,
15 char **argv)
16 {
17 int target_rraindex = 0;
18 char *endptr;
19 struct option long_options[] = {
20 {"rraindex", required_argument, 0, 129},
21 {0, 0, 0, 0}
22 };
24 optind = 0;
25 opterr = 0; /* initialize getopt */
27 while (1) {
28 int option_index = 0;
29 int opt;
31 opt = getopt_long(argc, argv, "", long_options, &option_index);
33 if (opt == EOF)
34 break;
36 switch (opt) {
37 case 129:
38 target_rraindex = strtol(optarg, &endptr, 0);
39 if (target_rraindex < 0) {
40 rrd_set_error("invalid rraindex number");
41 return (-1);
42 }
43 break;
44 default:
45 rrd_set_error("usage rrdtool %s [--rraindex number] file.rrd",
46 argv[0]);
47 return (-1);
48 }
49 }
51 if (optind >= argc) {
52 rrd_set_error("not enough arguments");
53 return -1;
54 }
56 return (rrd_first_r(argv[optind], target_rraindex));
57 }
60 time_t rrd_first_r(
61 const char *filename,
62 const int rraindex)
63 {
64 off_t rra_start, timer;
65 time_t then = -1;
66 rrd_t rrd;
67 rrd_file_t *rrd_file;
69 rrd_init(&rrd);
70 rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
71 if (rrd_file == NULL) {
72 goto err_free;
73 }
75 if ((rraindex < 0) || (rraindex >= (int) rrd.stat_head->rra_cnt)) {
76 rrd_set_error("invalid rraindex number");
77 goto err_close;
78 }
80 rra_start = rrd_file->header_len;
81 rrd_seek(rrd_file,
82 (rra_start +
83 (rrd.rra_ptr[rraindex].cur_row + 1) *
84 rrd.stat_head->ds_cnt * sizeof(rrd_value_t)), SEEK_SET);
85 timer = -(long)(rrd.rra_def[rraindex].row_cnt - 1);
86 if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
87 rrd_seek(rrd_file, rra_start, SEEK_SET);
88 }
89 then = (rrd.live_head->last_up -
90 rrd.live_head->last_up %
91 (rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step)) +
92 (timer * rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step);
93 err_close:
94 rrd_close(rrd_file);
95 err_free:
96 rrd_free(&rrd);
97 return (then);
98 }