Code

Merge branch 'upstream'
[pkg-rrdtool.git] / src / rrd_first.c
1 /*****************************************************************************
2  * RRDtool 1.3.8  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 "rrd_tool.h"
11 #ifdef WIN32
12 #include <stdlib.h>
13 #endif
15 time_t rrd_first(
16     int argc,
17     char **argv)
18 {
19     int       target_rraindex = 0;
20     char     *endptr;
21     struct option long_options[] = {
22         {"rraindex", required_argument, 0, 129},
23         {0, 0, 0, 0}
24     };
26     optind = 0;
27     opterr = 0;         /* initialize getopt */
29     while (1) {
30         int       option_index = 0;
31         int       opt;
33         opt = getopt_long(argc, argv, "", long_options, &option_index);
35         if (opt == EOF)
36             break;
38         switch (opt) {
39         case 129:
40             target_rraindex = strtol(optarg, &endptr, 0);
41             if (target_rraindex < 0) {
42                 rrd_set_error("invalid rraindex number");
43                 return (-1);
44             }
45             break;
46         default:
47             rrd_set_error("usage rrdtool %s [--rraindex number] file.rrd",
48                           argv[0]);
49             return (-1);
50         }
51     }
53     if (optind >= argc) {
54         rrd_set_error("not enough arguments");
55         return -1;
56     }
58     return (rrd_first_r(argv[optind], target_rraindex));
59 }
62 time_t rrd_first_r(
63     const char *filename,
64     const int rraindex)
65 {
66     off_t     rra_start, timer;
67     time_t    then = -1;
68     rrd_t     rrd;
69     rrd_file_t *rrd_file;
71     rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
72     if (rrd_file == NULL) {
73         goto err_free;
74     }
76     if ((rraindex < 0) || (rraindex >= (int) rrd.stat_head->rra_cnt)) {
77         rrd_set_error("invalid rraindex number");
78         goto err_close;
79     }
81     rra_start = rrd_file->header_len;
82     rrd_seek(rrd_file,
83              (rra_start +
84               (rrd.rra_ptr[rraindex].cur_row + 1) *
85               rrd.stat_head->ds_cnt * sizeof(rrd_value_t)), SEEK_SET);
86     timer = -(long)(rrd.rra_def[rraindex].row_cnt - 1);
87     if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
88         rrd_seek(rrd_file, rra_start, SEEK_SET);
89     }
90     then = (rrd.live_head->last_up -
91             rrd.live_head->last_up %
92             (rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step)) +
93         (timer * rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step);
94   err_close:
95     rrd_close(rrd_file);
96   err_free:
97     rrd_free(&rrd);
98     return (then);
99 }