fix from alex
[rrdtool.git] / src / rrd_first.c
1 /*****************************************************************************
2  * RRDtool 1.3.2  Copyright by Tobi Oetiker, 1997-2008
3  *****************************************************************************
4  * rrd_first Return
5  *****************************************************************************
6  * Initial version by Burton Strauss, ntopSupport.com - 3/2005
7  *****************************************************************************/
8
9 #include "rrd_tool.h"
10
11
12 time_t rrd_first(
13     int argc,
14     char **argv)
15 {
16     int       target_rraindex = 0;
17     char     *endptr;
18     struct option long_options[] = {
19         {"rraindex", required_argument, 0, 129},
20         {0, 0, 0, 0}
21     };
22
23     optind = 0;
24     opterr = 0;         /* initialize getopt */
25
26     while (1) {
27         int       option_index = 0;
28         int       opt;
29
30         opt = getopt_long(argc, argv, "", long_options, &option_index);
31
32         if (opt == EOF)
33             break;
34
35         switch (opt) {
36         case 129:
37             target_rraindex = strtol(optarg, &endptr, 0);
38             if (target_rraindex < 0) {
39                 rrd_set_error("invalid rraindex number");
40                 return (-1);
41             }
42             break;
43         default:
44             rrd_set_error("usage rrdtool %s [--rraindex number] file.rrd",
45                           argv[0]);
46             return (-1);
47         }
48     }
49
50     if (optind >= argc) {
51         rrd_set_error("not enough arguments");
52         return -1;
53     }
54
55     return (rrd_first_r(argv[optind], target_rraindex));
56 }
57
58
59 time_t rrd_first_r(
60     const char *filename,
61     const int rraindex)
62 {
63     off_t     rra_start, timer;
64     time_t    then = -1;
65     rrd_t     rrd;
66     rrd_file_t *rrd_file;
67
68     rrd_init(&rrd);
69     rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
70     if (rrd_file == NULL) {
71         goto err_free;
72     }
73
74     if ((rraindex < 0) || (rraindex >= (int) rrd.stat_head->rra_cnt)) {
75         rrd_set_error("invalid rraindex number");
76         goto err_close;
77     }
78
79     rra_start = rrd_file->header_len;
80     rrd_seek(rrd_file,
81              (rra_start +
82               (rrd.rra_ptr[rraindex].cur_row + 1) *
83               rrd.stat_head->ds_cnt * sizeof(rrd_value_t)), SEEK_SET);
84     timer = -(rrd.rra_def[rraindex].row_cnt - 1);
85     if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
86         rrd_seek(rrd_file, rra_start, SEEK_SET);
87     }
88     then = (rrd.live_head->last_up -
89             rrd.live_head->last_up %
90             (rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step)) +
91         (timer * rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step);
92   err_close:
93     rrd_close(rrd_file);
94   err_free:
95     rrd_free(&rrd);
96     return (then);
97 }