Example #1
0
int cmd_time(char *rest)
{
  struct dostime_t t;
  char s[40];
  int ec;

  noPrompt = 0;

  if((ec = leadOptions(&rest, opt_date, NULL)) != E_None)
      return ec;

  if (!*rest)
  {
	char *time;
    _dos_gettime(&t);

    time = nls_maketime(0, t.hour, t.minute, t.second, t.hsecond);
    if(!time) {	
    	error_out_of_memory();
    	return 1;
    }
    displayString(TEXT_MSG_CURRENT_TIME, time);
    free(time);
    rest = NULL;
  }

  while (1)
  {
    if (rest)
    {
      if (parsetime(rest))
        return 0;
    } else {
		if(noPrompt) return 0;

      if ((rest = getMessage(TEXT_MSG_ENTER_TIME)) == NULL)
        return 1;

      fputs(rest, stdout);
      free(rest);
      fgets(s, sizeof(s), stdin);
      if (cbreak)
        return 1;
      if (parsetime(s))
        return 0;
    }
    displayString(TEXT_ERROR_INVALID_TIME);
    // force input the next time around.
    rest = NULL;
  }
}
char* printstrftime(long argc, const char **args){
	struct	rrd_time_value start_tv, end_tv;
	char    *parsetime_error = NULL;
	char	formatted[MAX_STRFTIME_SIZE];
	struct tm *the_tm;
	time_t	start_tmp, end_tmp;

	/* Make sure that we were given the right number of args */
	if( argc != 4) {
		rrd_set_error( "wrong number of args %d", argc);
		return stralloc("");
	}

	/* Init start and end time */
	parsetime("end-24h", &start_tv);
	parsetime("now", &end_tv);

	/* Parse the start and end times we were given */
	if( (parsetime_error = parsetime( args[1], &start_tv))) {
		rrd_set_error( "start time: %s", parsetime_error);
		return stralloc("");
	}
	if( (parsetime_error = parsetime( args[2], &end_tv))) {
		rrd_set_error( "end time: %s", parsetime_error);
		return stralloc("");
	}
	if( proc_start_end( &start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
		return stralloc("");
	}

	/* Do we do the start or end */
	if( strcasecmp( args[0], "START") == 0) {
		the_tm = localtime( &start_tmp);
	}
	else if( strcasecmp( args[0], "END") == 0) {
		the_tm = localtime( &end_tmp);
	}
	else {
		rrd_set_error( "start/end not found in '%s'", args[0]);
		return stralloc("");
	}

	/* now format it */
	if( strftime( formatted, MAX_STRFTIME_SIZE, args[3], the_tm)) {
		return( stralloc( formatted));
	}
	else {
		rrd_set_error( "strftime failed");
		return stralloc("");
	}
}
Example #3
0
int zoneParserTest(int argc, char *argv[]) {
    if (argc < 4) {
        fprintf(stderr, "need conf file\n");
        exit(1);
    }
    test_cond("parse ttl 1", parsetime("2w3d3M2") == 17*(24*3600)+180 + 2);
    test_cond("parse ttl 2", parsetime("2002112") == 2002112);
    {
        char dot_origin[] = "google.com.";
        char domain[255] = "www.google.com.";
        abs2lenRelative(domain, dot_origin);
        test_cond("abs2lenRelative 1", strcmp(domain, "\3www") == 0);

        strcpy(domain, "aa.bb.google.com.");
        abs2lenRelative(domain, dot_origin);
        test_cond("abs2lenRelative 2", strcmp(domain, "\2aa\2bb") == 0);

        strcpy(domain, "google.com.");
        abs2lenRelative(domain, dot_origin);
        test_cond("abs2lenRelative 3", strcmp(domain, "@") == 0);
    }
    char *ss = readFile(argv[3]);
    char buf[1000];
    int idx = 0;
    int err;
    char errstr[ERR_STR_LEN];
    fprintf(stderr, "\n");
    while ((err=readFullRecord(errstr, &ss, buf, 1000, &idx)) == OK_CODE) {
        fprintf(stderr, "l%d:%s \n", idx, buf);
    }
    fprintf(stderr, "\n");

    zone *z;
    loadZoneFromFile(SOCKET_ID_HEAP, argv[3], &z);
    sds s = zoneToStr(z);
    printf("%s\n", s);
    sdsfree(s);

    // {
    //     zone *z = zoneDictFetchVal(zd, "\7example\3com");
    //     sds s = zoneToStr(z);
    //     LOG_DEBUG("%s", s);
    //     sdsfree(s);
    //     zoneDecRef(z);
    // }
    test_report();
    return 0;
}
Example #4
0
static value_t fl_time_fromstring(value_t *args, uint32_t nargs)
{
    argcount("time.fromstring", nargs, 1);
    char *ptr = tostring(args[0], "time.fromstring");
    double t = parsetime(ptr);
    int64_t it = (int64_t)t;
    if ((double)it == t && fits_fixnum(it))
        return fixnum(it);
    return mk_double(t);
}
Example #5
0
/* -----------------------------------------------------------------------
   Reads through the arguments on the lookout for an option starting
   with 'string'. The rest of the option is read as a time and passed
   to *result, where the result is meant to mean 'number of samples' in
   that time.
   On failure, *result is unchanged.
   return value is TRUE on success, FALSE otherwise.
   -----------------------------------------------------------------------*/
int parsetimearg( int argcount, char *args[], char *string, int *result)
{
    int i;

    if ((i = findoption( argcount, args, string)) > 0)
    {
	if (parsetime(args[i] + 1 + strlen( string), result))
	    return TRUE;
	argerrornum(args[i]+1, ME_NOTIME);
    }
    return FALSE;
}
Example #6
0
int
main(int argc, char *argv[])
{
	time_t tmpt, now;
	double days, today, tomorrow;
	char buf[1024];

	if (time(&now) == (time_t)-1)
		err(1, "time");
	if (argc > 1) {
		tmpt = parsetime(argv[1]);
		strftime(buf, sizeof(buf), "%a %Y %b %e %H:%M:%S (%Z)",
			localtime(&tmpt));
		printf("%s:  ", buf);
	} else {
		tmpt = now;
	}
	days = (tmpt - EPOCH_MINUS_1970 * 86400) / 86400.0;
	today = potm(days) + .5;
	if (tmpt < now)
		(void)printf("The Moon was ");
	else if (tmpt == now)
		(void)printf("The Moon is ");
	else
		(void)printf("The Moon will be ");
	if ((int)today == 100)
		(void)printf("Full\n");
	else if (!(int)today)
		(void)printf("New\n");
	else {
		tomorrow = potm(days + 1);
		if ((int)today == 50)
			(void)printf("%s\n", tomorrow > today ?
			    "at the First Quarter" : "at the Last Quarter");
			/* today is 0.5 too big, but it doesn't matter here
			 * since the phase is changing fast enough
			 */
		else {
			today -= 0.5;		/* Now it might matter */
			(void)printf("%s ", tomorrow > today ?
			    "Waxing" : "Waning");
			if (today > 50)
				(void)printf("Gibbous (%1.0f%% of Full)\n",
				    today);
			else if (today < 50)
				(void)printf("Crescent (%1.0f%% of Full)\n",
				    today);
		}
	}

	return EXIT_SUCCESS;
}
Example #7
0
static int my_settime(const char *s)
{	struct dostime_t t;

	switch(parsetime(s, &t)) {
	case E_None:		/* success -> set the date */
		_dos_settime(&t);
		/* fall through */
	case E_Empty:		/* empty line */
		return 1;		/* success */
	}

	return 0;			/* failure */
}
Example #8
0
int
main(int argc, char *argv[])
{
	struct stat st;
	char *ref = NULL;
	clock_gettime(CLOCK_REALTIME, &times[0]);

	ARGBEGIN {
	case 'a':
		aflag = 1;
		break;
	case 'c':
		cflag = 1;
		break;
	case 'd':
	case 't':
		times[0].tv_sec = parsetime(EARGF(usage()), times[0].tv_sec);
		break;
	case 'm':
		mflag = 1;
		break;
	case 'r':
		ref = EARGF(usage());
		if (stat(ref, &st) < 0)
			eprintf("stat '%s':", ref);
		times[0] = st.st_atim;
		times[1] = st.st_mtim;
		break;
	case 'T':
		times[0].tv_sec = estrtonum(EARGF(usage()), 0, LLONG_MAX);
		break;
	default:
		usage();
	} ARGEND;

	if (!argc)
		usage();
	if (!aflag && !mflag)
		aflag = mflag = 1;
	if (!ref)
		times[1] = times[0];

	for (; *argv; argc--, argv++)
		touch(*argv);

	return 0;
}
Example #9
0
// parse the directives(starts with $) at the top of zone files.
static int readDirectives(char *errstr, char **ssp, char *origin, uint32_t *ttl, int *line_idx) {
    char rbuf[RECORD_SIZE];
    char *tokens[8];
    int ntokens = 8;
    int prev_idx = *line_idx;
    char *ss = *ssp;
    int err;
    for (; ((err= readFullRecord(NULL, ssp, rbuf, RECORD_SIZE, line_idx)) == OK_CODE); ss = *ssp, prev_idx=*line_idx) {
        // unget this line
        if (rbuf[0] != '$') {
            *ssp = ss;
            *line_idx = prev_idx;
            return OK_CODE;
        }
        tokenize(rbuf, tokens, &ntokens, " \t");

        if (strcasecmp(tokens[0], "$ORIGIN") == 0) {
            if (ntokens < 2) {
                snprintf(errstr, ERR_STR_LEN, "Syntax error(line %d): no argument for $ORIGIN", *line_idx);
                return ERR_CODE;
            }
            strncpy(origin, tokens[1], 255);
            continue;
        } else if (strcasecmp(tokens[0], "$TTL") == 0) {
            if (ntokens < 2) {
                snprintf(errstr, ERR_STR_LEN, "Syntax error(line %d): no argument for $TTL", *line_idx);
                return ERR_CODE;
            }
            *ttl = (uint32_t) parsetime(tokens[1]);
            continue;
        } else {
            snprintf(errstr, ERR_STR_LEN, "Syntax error(line %d): invalid or unsupported directive %s.", *line_idx, tokens[0]);
            return ERR_CODE;
        }
    }
    if (err != EOF_CODE) err = OK_CODE;
    return err;
}
Example #10
0
int RRParserParseTextRdata(RRParser *psr, RRSet **rs, zone *z) {
    int err = OK_CODE;
    uint16_t type = psr->type;
    char *tok;

    char buf[4096];
    char *ptr = buf;
    uint16_t rdlength = 0;
    ptr += 2;

    size_t nameLen;
    int remain = RRParserRemainTokens(psr);

    switch (type) {
    case DNS_TYPE_A:
        tok = RRParserNextToken(psr);
        if (tok == NULL) {
            snprintf(psr->errstr, ERR_STR_LEN, "A record needs a ipv4 address");
            goto error;
        }
        char ipv4[4];
        if (str2ipv4(tok, ipv4) == false) {
            snprintf(psr->errstr, ERR_STR_LEN, "%s is an invalid ipv4 address.", tok);
            goto error;
        }
        memcpy(ptr, ipv4, 4);
        ptr += 4;
        break;
    case DNS_TYPE_AAAA:
        tok = RRParserNextToken(psr);
        if (tok == NULL) {
            snprintf(psr->errstr, ERR_STR_LEN, "AAAA record needs a ipv6 address");
            goto error;
        }
        char ipv6[16];
        if (str2ipv6(tok, ipv6) == false) {
            snprintf(psr->errstr, ERR_STR_LEN, "%s is an invalid ipv6 address.", tok);
            goto error;
        }
        memcpy(ptr, ipv6, 16);
        ptr += 16;
        break;
    case DNS_TYPE_NS:
    case DNS_TYPE_CNAME:
        tok = RRParserNextToken(psr);
        if (tok == NULL) {
            snprintf(psr->errstr, ERR_STR_LEN, "need a domain name.");
            goto error;
        }
        dot2lenlabel(tok, NULL);
        if (checkLenLabel(tok, 0) == ERR_CODE) {
            snprintf(psr->errstr, ERR_STR_LEN, "%s is an invalid domain name", tok);
            goto error;
        }
        nameLen = strlen(tok) + 1;
        memcpy(ptr, tok, nameLen);
        ptr += nameLen;
        break;
    case DNS_TYPE_MX:
        if (remain != 2) {
            snprintf(psr->errstr, ERR_STR_LEN, "MX record needs 2 tokens, but got %d.", remain);
            goto error;
        }
        tok = RRParserNextToken(psr);
        int pref = atoi(tok);
        if (pref > 0xffff) {
            snprintf(psr->errstr, ERR_STR_LEN, "preference of MX record is too big(%d)", pref);
            goto error;
        }
        dump16be((uint16_t)pref, ptr);
        ptr+=2;
        tok = RRParserNextToken(psr);
        if (tok == NULL) {
            snprintf(psr->errstr, ERR_STR_LEN, "no name for MX Record");
            goto error;
        }
        dot2lenlabel(tok, NULL);
        if (checkLenLabel(tok, 0) == ERR_CODE) {
            snprintf(psr->errstr, ERR_STR_LEN, "%s is an invalid domain name.", tok);
            goto error;
        }
        nameLen = strlen(tok) + 1;
        memcpy(ptr, tok, nameLen);
        ptr += nameLen;
        break;
    case DNS_TYPE_TXT:
        if (remain < 1) {
            snprintf(psr->errstr, ERR_STR_LEN, "TXT records should at least has 1 token.");
            goto error;
        }
        for (; ; ) {
            tok = RRParserNextToken(psr);
            if (tok == NULL) break;
            tok = strip(tok, "\"");
            size_t txtLen = strlen(tok);
            if (txtLen > 255) {
                snprintf(psr->errstr, ERR_STR_LEN, "txt string is too long %zu", txtLen);
                goto error;
            }
            if (ptr+txtLen+1 - buf >= (int)sizeof(buf)) {
                snprintf(psr->errstr, ERR_STR_LEN, "TXT records is too long");
                goto error;
            }
            *ptr = (uint8_t)txtLen;
            ptr++;
            memcpy(ptr, tok, txtLen);
            ptr += txtLen;
        }
        break;
    case DNS_TYPE_SOA:
        if (remain != 7) {
            snprintf(psr->errstr, ERR_STR_LEN, "SOA record needs 7 tokens, but gives %d field", remain);
            return ERR_CODE;
        }
        tok = RRParserNextToken(psr);
        dot2lenlabel(tok, NULL);
        nameLen = strlen(tok) + 1;
        memcpy(ptr, tok, nameLen);
        ptr += nameLen;

        tok = RRParserNextToken(psr);
        dot2lenlabel(tok, NULL);
        nameLen = strlen(tok) + 1;
        memcpy(ptr, tok, nameLen);
        ptr += nameLen;

        tok = RRParserNextToken(psr);
        uint32_t sn = (uint32_t)strtoul(tok, NULL, 10);
        z->sn = sn;
        dump32be(sn, ptr);
        ptr += 4;

        tok = RRParserNextToken(psr);
        uint32_t refresh = (uint32_t)parsetime(tok);
        z->refresh = refresh;
        dump32be(refresh, ptr);
        ptr += 4;

        tok = RRParserNextToken(psr);
        uint32_t retry = (uint32_t)parsetime(tok);
        z->retry = retry;
        dump32be(retry, ptr);
        ptr += 4;

        tok = RRParserNextToken(psr);
        uint32_t expiry = (uint32_t)parsetime(tok);
        z->expiry = expiry;
        dump32be(expiry, ptr);
        ptr += 4;

        tok = RRParserNextToken(psr);
        uint32_t nx = (uint32_t)parsetime(tok);
        z->nx = nx;
        dump32be(nx, ptr);
        ptr += 4;
        break;
    case DNS_TYPE_SRV:
        if (remain != 4) {
            snprintf(psr->errstr, ERR_STR_LEN, "SRV record needs 4 field, but gives %d field", remain);
            goto error;
        }
        tok = RRParserNextToken(psr);
        int priority = atoi(tok);
        if (priority < 0 || priority > 65535) {
            snprintf(psr->errstr, ERR_STR_LEN, "invalid priority for SRV record");
            goto error;
        }

        tok = RRParserNextToken(psr);
        int weight = atoi(tok);
        if (weight < 0 || weight > 65535) {
            snprintf(psr->errstr, ERR_STR_LEN, "invalid weight for SRV record");
            goto error;
        }

        tok = RRParserNextToken(psr);
        int port = atoi(tok);
        if (port < 0 || port > 65535) {
            snprintf(psr->errstr, ERR_STR_LEN, "invalid port for SRV record.");
            goto error;
        }
        dump16be((uint16_t)priority, ptr);
        ptr += 2;
        dump16be((uint16_t)weight, ptr);
        ptr += 2;
        dump16be((uint16_t)port, ptr);
        ptr += 2;

        tok = RRParserNextToken(psr);
        size_t targetLen = strlen(tok)+1;
        dot2lenlabel(tok, NULL);
        memcpy(ptr, tok, targetLen);
        ptr += targetLen;
        break;
    case DNS_TYPE_PTR:
        break;
    default:
        snprintf(psr->errstr, ERR_STR_LEN, "unsupported dns record type(%d)", type);
        goto error;
    }
    rdlength = (uint16_t )(ptr-buf - 2);
    dump16be(rdlength, buf);
    *rs = RRSetCat(*rs, buf, ptr-buf);

    goto ok;
error:
    err = ERR_CODE;
    psr->err = PARSER_ERR;
ok:
    return err;
}
Example #11
0
/* mostly rrd_graph(), just pushed a bit here and stretched a bit there */
int
rrd_xport(int argc, char **argv, int *xsize,
          time_t         *start,
          time_t         *end,        /* which time frame do you want ?
				       * will be changed to represent reality */
          unsigned long  *step,       /* which stepsize do you want?
				       * will be changed to represent reality */
          unsigned long  *col_cnt,    /* number of data columns in the result */
          char           ***legend_v, /* legend entries */
          rrd_value_t    **data)      /* two dimensional array containing the data */

{
    image_desc_t   im;
    int            i;
    long           long_tmp;
    time_t	   start_tmp=0,end_tmp=0;
    char           symname[100];
    long           scancount;
    struct rrd_time_value start_tv, end_tv;
    char           *parsetime_error = NULL;

    parsetime("end-24h", &start_tv);
    parsetime("now", &end_tv);

    /* use the default values from rrd_graph.c */
    im.xlab_user.minsec = -1;
    im.xgif=0;
    im.ygif=0;
    im.xsize = 400;
    im.ysize = 100;
    im.step = 0;
    im.ylegend[0] = '\0';
    im.title[0] = '\0';
    im.minval = DNAN;
    im.maxval = DNAN;
    im.interlaced = 0;
    im.unitsexponent= 9999;
    im.unitslength= 9;
    im.extra_flags= 0;
    im.rigid = 0;
    im.imginfo = NULL;
    im.lazy = 0;
    im.logarithmic = 0;
    im.ygridstep = DNAN;
    im.draw_x_grid = 1;
    im.draw_y_grid = 1;
    im.base = 1000;
    im.prt_c = 0;
    im.gdes_c = 0;
    im.gdes = NULL;
    im.imgformat = IF_GIF; /* we default to GIF output */

    while (1) {
        static struct option long_options[] =
        {
            {"start",      required_argument, 0,  's'},
            {"end",        required_argument, 0,  'e'},
            {"maxrows",    required_argument, 0,  'm'},
            {"step",       required_argument, 0,   261},
            {0,0,0,0}
        };
        int option_index = 0;
        int opt;

        opt = getopt_long(argc, argv, "s:e:m:",
                          long_options, &option_index);

        if (opt == EOF)
            break;

        switch(opt) {
        case 261:
            im.step =  atoi(optarg);
            break;
        case 's':
            if ((parsetime_error = parsetime(optarg, &start_tv))) {
                rrd_set_error( "start time: %s", parsetime_error );
                return -1;
            }
            break;
        case 'e':
            if ((parsetime_error = parsetime(optarg, &end_tv))) {
                rrd_set_error( "end time: %s", parsetime_error );
                return -1;
            }
            break;
        case 'm':
            long_tmp = atol(optarg);
            if (long_tmp < 10) {
                rrd_set_error("maxrows below 10 rows");
                return -1;
            }
            im.xsize = long_tmp;
            break;

        case '?':
            if (optopt != 0)
                rrd_set_error("unknown option '%c'", optopt);
            else
                rrd_set_error("unknown option '%s'",argv[optind-1]);
            return -1;
        }
    }

    /*
    if (optind >= argc) {
       rrd_set_error("missing filename");
       return -1;
    }
    */

    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1) {
        return -1;
    }

    if (start_tmp < 3600*24*365*10) {
        rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
        return -1;
    }

    if (end_tmp < start_tmp) {
        rrd_set_error("start (%ld) should be less than end (%ld)",
                      start_tmp, end_tmp);
        return -1;
    }

    im.start = start_tmp;
    im.end = end_tmp;


    for(i=optind; i<argc; i++) {
        int   argstart=0;
        int   strstart=0;
        char  varname[30],*rpnex;
        gdes_alloc(&im);
        if(sscanf(argv[i],"%10[A-Z0-9]:%n",symname,&argstart)==1) {
            if((im.gdes[im.gdes_c-1].gf=gf_conv(symname))==-1) {
                im_free(&im);
                rrd_set_error("unknown function '%s'",symname);
                return -1;
            }
        } else {
            rrd_set_error("can't parse '%s'",argv[i]);
            im_free(&im);
            return -1;
        }

        switch(im.gdes[im.gdes_c-1].gf) {
        case GF_CDEF:
            if((rpnex = malloc(strlen(&argv[i][argstart])*sizeof(char)))==NULL) {
                rrd_set_error("malloc for CDEF");
                return -1;
            }
            if(sscanf(
                        &argv[i][argstart],
                        DEF_NAM_FMT "=%[^: ]",
                        im.gdes[im.gdes_c-1].vname,
                        rpnex) != 2) {
                im_free(&im);
                free(rpnex);
                rrd_set_error("can't parse CDEF '%s'",&argv[i][argstart]);
                return -1;
            }
            /* checking for duplicate DEF CDEFS */
            if(find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) {
                im_free(&im);
                rrd_set_error("duplicate variable '%s'",
                              im.gdes[im.gdes_c-1].vname);
                return -1;
            }
            if((im.gdes[im.gdes_c-1].rpnp = str2rpn(&im,rpnex))== NULL) {
                rrd_set_error("invalid rpn expression '%s'", rpnex);
                im_free(&im);
                return -1;
            }
            free(rpnex);
            break;
        case GF_DEF:
            if (sscanf(
                        &argv[i][argstart],
                        DEF_NAM_FMT "=%n",
                        im.gdes[im.gdes_c-1].vname,
                        &strstart)== 1 && strstart) { /* is the = did not match %n returns 0 */
                if(sscanf(&argv[i][argstart
                                   +strstart
                                   +scan_for_col(&argv[i][argstart+strstart],
                                                 MAXPATH,im.gdes[im.gdes_c-1].rrd)],
                          ":" DS_NAM_FMT ":" CF_NAM_FMT,
                          im.gdes[im.gdes_c-1].ds_nam,
                          symname) != 2) {
                    im_free(&im);
                    rrd_set_error("can't parse DEF '%s' -2",&argv[i][argstart]);
                    return -1;
                }
            } else {
                im_free(&im);
                rrd_set_error("can't parse DEF '%s'",&argv[i][argstart]);
                return -1;
            }

            /* checking for duplicate DEF CDEFS */
            if (find_var(&im,im.gdes[im.gdes_c-1].vname) != -1) {
                im_free(&im);
                rrd_set_error("duplicate variable '%s'",
                              im.gdes[im.gdes_c-1].vname);
                return -1;
            }
            if((im.gdes[im.gdes_c-1].cf=cf_conv(symname))==-1) {
                im_free(&im);
                rrd_set_error("unknown cf '%s'",symname);
                return -1;
            }
            break;
        case GF_XPORT:
            if((scancount=sscanf(
                              &argv[i][argstart],
                              "%29[^:]:%n",
                              varname,
                              &strstart))>=1) {
                if(strstart <= 0) {
                    im.gdes[im.gdes_c-1].legend[0] = '\0';
                } else {
                    scan_for_col(&argv[i][argstart+strstart],FMT_LEG_LEN,im.gdes[im.gdes_c-1].legend);
                }
                if((im.gdes[im.gdes_c-1].vidx=find_var(&im,varname))==-1) {
                    im_free(&im);
                    rrd_set_error("unknown variable '%s'",varname);
                    return -1;
                }
            } else {
                im_free(&im);
                rrd_set_error("can't parse '%s'",&argv[i][argstart]);
                return -1;
            }
            break;
        default:
            break;
        }

    }

    if (im.gdes_c == 0) {
        rrd_set_error("can't make a graph without contents");
        im_free(&im);
        return(-1);
    }

    if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) {
        im_free(&im);
        return -1;
    }

    im_free(&im);
    return 0;
}
Example #12
0
size_t scan_httpdate(const char *in,time_t *t) {
  struct tm x;
  int i;
  unsigned long tmp;
  const char* c;
  static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  if (!(c=in)) return 0;
  if (c[3]==',') c+=5; else
  if (c[6]==',') c+=8; else {
    c+=4;
    for (i=0; i<12; ++i) {
      if (case_equalb(c,3,months+i*3)) {
	x.tm_mon=i; break;
      }
    }
    c+=4; if (*c==' ') ++c;
    c+=scan_ulong(c,&tmp); x.tm_mday=tmp;
    ++c;
    if (parsetime(c,&x)) return 0;
    c+=9;
    c+=scan_ulong(c,&tmp); x.tm_year=tmp-1900;
    goto done;
  }
  c+=scan_ulong(c,&tmp); x.tm_mday=tmp;
  while (*c==' ') ++c; // work around crappy sqlite download httpd
//  ++c;
  for (i=0; i<12; ++i)
    if (case_equalb(c,3,months+i*3)) {
      x.tm_mon=i; break;
    }
  c+=4;
  c+=scan_ulong(c,&tmp);
  if (tmp>1000) x.tm_year=tmp-1900; else
    if (tmp<70) x.tm_year=tmp+100; else
                x.tm_year=tmp;
  ++c;
  if (parsetime(c,&x)) return 0;
  c+=9;
  if (byte_equal(c,3,"GMT")) c+=3;
  if (*c=='+' || *c=='-') {
    ++c;
    while (*c>='0' && *c<='9') ++c;
  }
done:
  x.tm_wday=x.tm_yday=x.tm_isdst=0;
#if defined(__dietlibc__) || defined(__GLIBC__)
  *t=timegm(&x);
#elif defined(__MINGW32__)
  *t=mktime(&x);
#else
  {
#ifdef sgi
    char** old=environ;
    char** newenv={0};
    environ=newenv;
    *t=mktime(&x);
    environ=old;
#else
    char* old=getenv("TZ");
    unsetenv("TZ");
    *t=mktime(&x);
    if (old) setenv("TZ",old,1);
#endif
  }
#endif
  return c-in;
}
Example #13
0
void test_parsetime(void)
{
  assert(parsetime("1+02", 2) == 62);
  assert(parsetime("1+02+05", 2) == 62);
}
Example #14
0
int
rrd_fetch(int argc, 
	  char **argv,
	  time_t         *start,
	  time_t         *end,       /* which time frame do you want ?
				      * will be changed to represent reality */
	  unsigned long  *step,      /* which stepsize do you want? 
				      * will be changed to represent reality */
	  unsigned long  *ds_cnt,    /* number of data sources in file */
	  char           ***ds_namv,   /* names of data sources */
	  rrd_value_t    **data)     /* two dimensional array containing the data */
{


    long     step_tmp =1;
    time_t   start_tmp=0, end_tmp=0;
    enum     cf_en cf_idx;

    struct rrd_time_value start_tv, end_tv;
    char     *parsetime_error = NULL;
    optind = 0; opterr = 0;  /* initialize getopt */

    /* init start and end time */
    parsetime("end-24h", &start_tv);
    parsetime("now", &end_tv);

    while (1){
	static struct option long_options[] =
	{
	    {"resolution",      required_argument, 0, 'r'},
	    {"start",      required_argument, 0, 's'},
	    {"end",      required_argument, 0, 'e'},
	    {0,0,0,0}
	};
	int option_index = 0;
	int opt;
	opt = getopt_long(argc, argv, "r:s:e:", 
			  long_options, &option_index);

	if (opt == EOF)
	    break;

	switch(opt) {
	case 's':
            if ((parsetime_error = parsetime(optarg, &start_tv))) {
                rrd_set_error( "start time: %s", parsetime_error );
                return -1;
	    }
	    break;
	case 'e':
            if ((parsetime_error = parsetime(optarg, &end_tv))) {
                rrd_set_error( "end time: %s", parsetime_error );
                return -1;
	    }
	    break;
	case 'r':
	    step_tmp = atol(optarg);
	    break;
	case '?':
	    rrd_set_error("unknown option '-%c'",optopt);
	    return(-1);
	}
    }

    
    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
	return -1;
    }  

    
    if (start_tmp < 3600*24*365*10){
	rrd_set_error("the first entry to fetch should be after 1980");
	return(-1);
    }
    
    if (end_tmp < start_tmp) {
	rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp);
	return(-1);
    }
    
    *start = start_tmp;
    *end = end_tmp;

    if (step_tmp < 1) {
	rrd_set_error("step must be >= 1 second");
	return -1;
    }
    *step = step_tmp;
    
    if (optind + 1 >= argc){
	rrd_set_error("not enough arguments");
	return -1;
    }
    
    if ((int)(cf_idx=cf_conv(argv[optind+1])) == -1 ){
	return -1;
    }

    if (rrd_fetch_fn(argv[optind],cf_idx,start,end,step,ds_cnt,ds_namv,data) == -1)
	return(-1);
    return (0);
}
Example #15
0
time_t rfc822_parsedt(const char *rfcdt)
{
unsigned day=0, mon=0, year;
int secs;
int offset;
time_t t;
unsigned y;

	/* Ignore day of the week.  Tolerate "Tue, 25 Feb 1997 ... "
	** without the comma.  Tolerate "Feb 25 1997 ...".
	*/

	while (!day || !mon)
	{
		if (!*rfcdt)	return (0);
		if (isalpha((int)(unsigned char)*rfcdt))
		{
			if (mon)	return (0);
			mon=parsekey(&rfcdt, mnames);
			if (!mon)
				while (*rfcdt && isalpha((int)(unsigned char)*rfcdt))
					++rfcdt;
			continue;
		}

		if (isdigit((int)(unsigned char)*rfcdt))
		{
			if (day)	return (0);
			day=parsedig(&rfcdt);
			if (!day)	return (0);
			continue;
		}
		++rfcdt;
	}

	while (*rfcdt && isspace((int)(unsigned char)*rfcdt))
		++rfcdt;
	if (!isdigit((int)(unsigned char)*rfcdt))	return (0);
	year=parsedig(&rfcdt);
	if (year < 70)	year += 2000;
	if (year < 100)	year += 1900;

	while (*rfcdt && isspace((int)(unsigned char)*rfcdt))
		++rfcdt;

	if (day == 0 || mon == 0 || mon > 12 || day > mdays(mon,year))
		return (0);

	secs=parsetime(&rfcdt);
	if (secs < 0)	return (0);

	offset=0;

	/* RFC822 sez no parenthesis, but I've seen (EST) */

	while ( *rfcdt )
	{
		if (isalnum((int)(unsigned char)*rfcdt) || *rfcdt == '+' || *rfcdt == '-')
			break;
		++rfcdt;
	}

	if (isalpha((int)(unsigned char)*rfcdt))
	{
	int	n=parsekey(&rfcdt, zonenames);

		if (n > 0)	offset= zoneoffset[n-1];
	}
	else
	{
	int	sign=1;
	unsigned n;

		switch (*rfcdt)	{
		case '-':
			sign= -1;
		case '+':
			++rfcdt;
		}

		if (isdigit((int)(unsigned char)*rfcdt))
		{
			n=parsedig(&rfcdt);
			if (n > 2359 || (n % 100) > 59)	n=0;
			offset = sign * ( (n % 100) * 60 + n / 100 * 60 * 60);
		}
	}

	if (year < 1970)	return (0);

	t=0;
	for (y=1970; y<year; y++)
	{
		if ( leap(y) )
		{
			if (year-y >= 4)
			{
				y += 3;
				t += ( 365*3+366 ) * 24 * 60 * 60;
				continue;
			}
			t += 24 * 60 * 60;
		}
		t += 365 * 24 * 60 * 60;
	}

	for (y=1; y < mon; y++)
		t += mdays(y, year) * 24 * 60 * 60;

	return ( t + (day-1) * 24 * 60 * 60 + secs - offset );
}
Example #16
0
int main ( int ac, char **av )
{
  static struct option long_options[] =
  {
     {"start",      required_argument, 0, 's'},
     {"end",        required_argument, 0, 'e'},
     {0,0,0,0}};
  int option_index = 0;
  int opt;
   
  time_t start_tmp, end_tmp, Now = time(NULL);
  char tim_b[200];
  
  struct time_value start_tv, end_tv;
  char *parsetime_error = NULL;
  
  /* default values */
  parsetime("end-24h", &start_tv);
  parsetime("now", &end_tv);

  if( ac < 2 )
    {
    printf( "usage: %s [--start|-s start] [--end|-e end]\n"
	    "\n"
	    "In plain English, this means that to time specification try\n"
	    "a single time specification (just like in the rrdtool create)\n"
	    "you can use the first form, while to try two of them at once\n"
	    "(just like in rrdtool graph or fetch) you need the seconf form\n",
	    av[0] );
    exit(0);
    }
  
  printf( "The time now is: %s\n", ctime(&Now) );
  
  while(1){
	opt = getopt_long(ac, av, "s:e:", long_options, &option_index);
    
	if (opt == EOF)  
	    break;
	
	switch(opt)
	{
	case 's': 
	    strncpy( soption, optarg, BUF_LEN );
	    if ((parsetime_error = parsetime(optarg, &start_tv))) {
		fprintf( stderr, "ERROR: start time: %s\n", parsetime_error );
		exit(1);
	    }
	    
	    break;
	case 'e': 
	    strncpy( eoption, optarg, BUF_LEN );
	    if ((parsetime_error = parsetime(optarg, &end_tv))) {
	        fprintf( stderr, "ERROR: end time: %s\n", parsetime_error );
		exit(1);
	    }	    
 	    break;
	}
  }
  
  if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
      printf("ERROR: %s\n",rrd_get_error());
      rrd_clear_error();
      exit(1);
  }
  
  strftime(tim_b,100,"%c %Z",localtime(&start_tmp));
  if( *soption )
      printf( "Start time was specified as: '%s',\n"
	      "for me this means: %s (or %ld sec since epoch)\n\n", 
              soption, tim_b, start_tmp );
    else
      printf( "Start time was not specified, default value will be used (end-24h)\n"
	      "for me this means: %s (or %ld sec since epoch)\n\n",
	      tim_b, start_tmp );
    
  strftime(tim_b,100,"%c %Z",localtime(&end_tmp));
  if( *eoption )
      printf( "End time was specified as: '%s',\n"
	      "for me this means: %s (or %ld sec since epoch)\n", 
              eoption, tim_b, end_tmp );
  else
      printf( "End time was not specified, default value will be used (now)\n"
	      "for me this means: %s (or %ld sec since epoch)\n\n",
	      tim_b, end_tmp );
  exit(0);
}
Example #17
0
static void spu_end(const char *v)          { curspu->sd           = parsetime(v); }
Example #18
0
static void spu_start(const char *v)        { curspu->spts         = parsetime(v); }
Example #19
0
int
rrd_parse_def(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
    int			i=0;
    char 		command[7]; /* step, start, end, reduce */
    char		tmpstr[256];
    struct rrd_time_value	start_tv,end_tv;
    time_t		start_tmp=0,end_tmp=0;
    char		*parsetime_error=NULL;

    start_tv.type   = end_tv.type=ABSOLUTE_TIME;
    start_tv.offset = end_tv.offset=0;
    localtime_r(&gdp->start, &start_tv.tm);
    localtime_r(&gdp->end, &end_tv.tm);
    
    dprintf("- parsing '%s'\n",&line[*eaten]);
    dprintf("- from line '%s'\n",line);

    if (rrd_parse_vname(line,eaten,gdp,im)) return 1;
    i=scan_for_col(&line[*eaten],254,gdp->rrd);
    if (line[*eaten+i]!=':') {
	rrd_set_error("Problems reading database name");
	return 1;
    }
    (*eaten)+=++i;
    dprintf("- using file '%s'\n",gdp->rrd);

    i=0;
    sscanf(&line[*eaten], DS_NAM_FMT ":%n", gdp->ds_nam,&i);
    if (!i) {
	rrd_set_error("Cannot parse DS in '%s'",line);
	return 1;
    }
    (*eaten)+=i;
    dprintf("- using DS '%s'\n",gdp->ds_nam);

    if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
    gdp->cf_reduce = gdp->cf;
    
    if (line[*eaten]=='\0') return 0;

    while (1) {
	dprintf("- optional parameter follows: %s\n", &line[*eaten]);
	i=0;
	sscanf(&line[*eaten], "%6[a-z]=%n", command, &i);
	if (!i) {
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	(*eaten)+=i;
	dprintf("- processing '%s'\n",command);
	if (!strcmp("reduce",command)) {
	  if (rrd_parse_CF(line,eaten,gdp,&gdp->cf_reduce)) return 1;
	  if (line[*eaten] != '\0')
	      (*eaten)--;
	} else if (!strcmp("step",command)) {
	    i=0;
	    sscanf(&line[*eaten],"%lu%n",&gdp->step,&i);
	    (*eaten)+=i;
	    dprintf("- using step %lu\n",gdp->step);
	} else if (!strcmp("start",command)) {
	    i=scan_for_col(&line[*eaten],255,tmpstr);
	    (*eaten)+=i;
	    if ((parsetime_error = parsetime(tmpstr, &start_tv))) {
		rrd_set_error( "start time: %s", parsetime_error );
		return 1;
	    }
	    dprintf("- done parsing:  '%s'\n",&line[*eaten]);
	} else if (!strcmp("end",command)) {
	    i=scan_for_col(&line[*eaten],255,tmpstr);
	    (*eaten)+=i;
	    if ((parsetime_error = parsetime(tmpstr, &end_tv))) {
		rrd_set_error( "end time: %s", parsetime_error );
		return 1;
	    }
	    dprintf("- done parsing:  '%s'\n",&line[*eaten]);
	} else {
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	if (line[*eaten]=='\0') break;
	if (line[*eaten]!=':') {
	    dprintf("- Expected to see end of string but got '%s'\n",\
							 &line[*eaten]);
	    rrd_set_error("Parse error in '%s'",line);
	    return 1;
	}
	(*eaten)++;
    }
    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
	/* error string is set in parsetime.c */
	return 1;
    }
    if (start_tmp < 3600*24*365*10) {
	rrd_set_error("the first entry to fetch should be "
			"after 1980 (%ld)",start_tmp);
	return 1;
    }

    if (end_tmp < start_tmp) {
	rrd_set_error("start (%ld) should be less than end (%ld)",
			start_tmp, end_tmp);
	return 1;
    }

    gdp->start = start_tmp;
    gdp->end = end_tmp;

    dprintf("- start time %lu\n",gdp->start);
    dprintf("- end   time %lu\n",gdp->end);

    return 0;
}
Example #20
0
int
rrd_create(int argc, char **argv) 
{
    rrd_t          rrd;
    long                i,long_tmp;
    time_t             last_up;
    struct rrd_time_value last_up_tv;
    char *parsetime_error = NULL;

    /* init last_up */
    last_up = time(NULL)-10;
    /* init rrd clean */
    rrd_init(&rrd);
    /* static header */
    if((rrd.stat_head = calloc(1,sizeof(stat_head_t)))==NULL){
	rrd_set_error("allocating rrd.stat_head");
	return(-1);
    }

    /* live header */
    if((rrd.live_head = calloc(1,sizeof(live_head_t)))==NULL){
	rrd_set_error("allocating rrd.live_head");
	return(-1);
    }

    /* set some defaults */
    strcpy(rrd.stat_head->cookie,RRD_COOKIE);
    strcpy(rrd.stat_head->version,RRD_VERSION);
    rrd.stat_head->float_cookie = FLOAT_COOKIE;
    rrd.stat_head->ds_cnt = 0; /* this will be adjusted later */
    rrd.stat_head->rra_cnt = 0; /* ditto */
    rrd.stat_head->pdp_step = 300; /* 5 minute default */

    /* a default value */
    rrd.ds_def = NULL;
    rrd.rra_def = NULL;
    
    while (1){
	static struct option long_options[] =
	{
	    {"start",      required_argument, 0, 'b'},
	    {"step",        required_argument,0,'s'},
	    {0,0,0,0}
	};
	int option_index = 0;
	int opt;
	opt = getopt_long(argc, argv, "b:s:", 
			  long_options, &option_index);
	
	if (opt == EOF)
	  break;
	
	switch(opt) {
	case 'b':
            if ((parsetime_error = parsetime(optarg, &last_up_tv))) {
                rrd_set_error("start time: %s", parsetime_error );
		rrd_free(&rrd);
                return(-1);
	    }
	    if (last_up_tv.type == RELATIVE_TO_END_TIME ||
		last_up_tv.type == RELATIVE_TO_START_TIME) {
		rrd_set_error("specifying time relative to the 'start' "
                              "or 'end' makes no sense here");
		rrd_free(&rrd);
		return(-1);
	    }

	    last_up = mktime(&last_up_tv.tm) + last_up_tv.offset;
	    
	    if (last_up < 3600*24*365*10){
		rrd_set_error("the first entry to the RRD should be after 1980");
		rrd_free(&rrd);
		return(-1);
	    }	
	    break;

	case 's':
	    long_tmp = atol(optarg);
	    if (long_tmp < 1){
		rrd_set_error("step size should be no less than one second");
		rrd_free(&rrd);
		return(-1);
	    }
	    rrd.stat_head->pdp_step = long_tmp;
	    break;

	case '?':
            if (optopt != 0)
                rrd_set_error("unknown option '%c'", optopt);
            else
                rrd_set_error("unknown option '%s'",argv[optind-1]);
            rrd_free(&rrd);
	    return(-1);
	}
    }
    rrd.live_head->last_up = last_up;

    for(i=optind+1;i<argc;i++){
	char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];	
	int ii;
	if (strncmp(argv[i],"DS:",3)==0){
	    size_t old_size = sizeof(ds_def_t)*(rrd.stat_head->ds_cnt);
	    if((rrd.ds_def = rrd_realloc(rrd.ds_def,
				     old_size+sizeof(ds_def_t)))==NULL){
		rrd_set_error("allocating rrd.ds_def");
		rrd_free(&rrd);
		return(-1);	
	    }
	    memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
	    if (sscanf(&argv[i][3],
		       DS_NAM_FMT ":" DST_FMT ":%lu:%18[^:]:%18[^:]",
		       rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
		       rrd.ds_def[rrd.stat_head->ds_cnt].dst,
		       &rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_mrhb_cnt].u_cnt,
		       minstr,maxstr) == 5){
		/* check for duplicate datasource names */
		for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
			if(strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
			  	  rrd.ds_def[ii].ds_nam) == 0){
				rrd_set_error("Duplicate DS name: %s",rrd.ds_def[ii].ds_nam);
		                rrd_free(&rrd);
                                return(-1);
			}				                                
		}
		if(dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst) == -1){
		    rrd_free(&rrd);
		    return (-1);
		}
		if (minstr[0] == 'U' && minstr[1] == 0)
		    rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_min_val].u_val = DNAN;
		else
		    rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_min_val].u_val = atof(minstr);
		
		if (maxstr[0] == 'U' && maxstr[1] == 0)
		    rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_max_val].u_val = DNAN;
		else
		    rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_max_val].u_val  = atof(maxstr);
		
		if (! isnan(rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_min_val].u_val) &&
		    ! isnan(rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_max_val].u_val) &&
		    rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_min_val].u_val
		    >= rrd.ds_def[rrd.stat_head->ds_cnt].par[DS_max_val].u_val ) {
		    rrd_set_error("min must be less than max in DS definition");
		    rrd_free(&rrd);
		    return (-1);		
		}
		rrd.stat_head->ds_cnt++;	    
	    } else {
		rrd_set_error("can't parse argument '%s'",argv[i]);
		rrd_free(&rrd);
		return (-1);		
	    }
	} else if (strncmp(argv[i],"RRA:",3)==0){
	    size_t old_size = sizeof(rra_def_t)*(rrd.stat_head->rra_cnt);
	    if((rrd.rra_def = rrd_realloc(rrd.rra_def,
				      old_size+sizeof(rra_def_t)))==NULL){
		rrd_set_error("allocating rrd.rra_def");
		rrd_free(&rrd);
		return(-1);	
	    }
	    memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0, sizeof(rra_def_t));
	    if (sscanf(&argv[i][4],
		       CF_NAM_FMT ":%lf:%lu:%lu",
		       rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
		       &rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val,
		       &rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt,
		       &rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt) == 4){
		if(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) == -1){
		    rrd_free(&rrd);
		    return (-1);
		}
	        if (rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val<0.0 ||
		    rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val>=1.0) {
		    rrd_set_error("the xff must always be >= 0 and < 1");
		    rrd_free(&rrd);
		    return (-1);
		}
		rrd.stat_head->rra_cnt++;	    		
	    }
	    else {  
		rrd_set_error("can't parse argument '%s'",argv[i]);
		rrd_free(&rrd);
		return (-1);		
	    }

	} else {
	    rrd_set_error("can't parse argument '%s'",argv[i]);
	    rrd_free(&rrd);
            return -1;
	}
    }


    if (rrd.stat_head->rra_cnt < 1){
	rrd_set_error("you must define at least one Round Robin Archive");
	rrd_free(&rrd);
	return(-1);
    }

    if (rrd.stat_head->ds_cnt < 1){
	rrd_set_error("you must define at least one Data Source");
	rrd_free(&rrd);
	return(-1);
    }
    return rrd_create_fn(argv[optind],&rrd);
}
Example #21
0
int 
rrd_xport(int argc, char **argv, int UNUSED(*xsize),
	  time_t         *start,
	  time_t         *end,        /* which time frame do you want ?
				       * will be changed to represent reality */
	  unsigned long  *step,       /* which stepsize do you want? 
				       * will be changed to represent reality */
	  unsigned long  *col_cnt,    /* number of data columns in the result */
	  char           ***legend_v, /* legend entries */
	  rrd_value_t    **data)      /* two dimensional array containing the data */

{

    image_desc_t   im;
    time_t	   start_tmp=0,end_tmp=0;
    struct rrd_time_value start_tv, end_tv;
    char           *parsetime_error = NULL;
    optind = 0; opterr = 0;  /* initialize getopt */

    rrd_graph_init(&im);

    parsetime("end-24h", &start_tv);
    parsetime("now", &end_tv);

    while (1){
	static struct option long_options[] =
	{
	    {"start",      required_argument, 0,  's'},
	    {"end",        required_argument, 0,  'e'},
	    {"maxrows",    required_argument, 0,  'm'},
	    {"step",       required_argument, 0,   261},
	    {0,0,0,0}
	};
	int option_index = 0;
	int opt;
	
	opt = getopt_long(argc, argv, "s:e:m:",
			  long_options, &option_index);

	if (opt == EOF)
	    break;
	
	switch(opt) {
	case 261:
	    im.step =  atoi(optarg);
	    break;
	case 's':
	    if ((parsetime_error = parsetime(optarg, &start_tv))) {
	        rrd_set_error( "start time: %s", parsetime_error );
		return -1;
	    }
	    break;
	case 'e':
	    if ((parsetime_error = parsetime(optarg, &end_tv))) {
	        rrd_set_error( "end time: %s", parsetime_error );
		return -1;
	    }
	    break;
	case 'm':
	    im.xsize = atol(optarg);
	    if (im.xsize < 10) {
		rrd_set_error("maxrows below 10 rows");
		return -1;
	    }
	    break;
	case '?':
	    rrd_set_error("unknown option '%c'", optopt);
            return -1;
	}
    }

    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
	return -1;
    }  
    
    if (start_tmp < 3600*24*365*10){
	rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
	return -1;
    }
    
    if (end_tmp < start_tmp) {
	rrd_set_error("start (%ld) should be less than end (%ld)", 
	       start_tmp, end_tmp);
	return -1;
    }
    
    im.start = start_tmp;
    im.end = end_tmp;
    im.step = max((long)im.step, (im.end-im.start)/im.xsize);
    
    rrd_graph_script(argc,argv,&im,0);
    if (rrd_test_error()) {
	im_free(&im);
	return -1;
    }

    if (im.gdes_c == 0){
	rrd_set_error("can't make a graph without contents");
	im_free(&im);
	return(-1); 
    }
    
    if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1){
	im_free(&im);
	return -1;
    }

    im_free(&im);
    return 0;
}