Example #1
0
/* ****************************************************************************
*
* Duration::parse -
*/
int64_t Duration::parse(void)
{
  seconds = parse8601(string);

  valid = (seconds == -1)? false : true;

  return seconds;
}
Example #2
0
/*
 * Parse a configuration file and return a linked list of all the logs
 * to process
 */
struct conf_entry *
parse_file(int *nentries)
{
	char line[BUFSIZ], *parse, *q, *errline, *group, *tmp, *ep;
	struct conf_entry *working = NULL, *first = NULL;
	struct passwd *pwd;
	struct group *grp;
	struct stat sb;
	int lineno;
	FILE *f;
	long l;

	if (strcmp(conf, "-") == 0)
		f = stdin;
	else if ((f = fopen(conf, "r")) == NULL)
		err(1, "can't open %s", conf);

	*nentries = 0;
	for (lineno = 1; fgets(line, sizeof(line), f); lineno++) {
		tmp = sob(line);
		if (*tmp == '\0' || *tmp == '#')
			continue;
		errline = strdup(tmp);
		if (errline == NULL)
			err(1, "strdup");
		(*nentries)++;
		if (!first) {
			working = malloc(sizeof(struct conf_entry));
			if (working == NULL)
				err(1, "malloc");
			first = working;
		} else {
			working->next = malloc(sizeof(struct conf_entry));
			if (working->next == NULL)
				err(1, "malloc");
			working = working->next;
		}

		q = parse = missing_field(sob(line), errline, lineno);
		*(parse = son(line)) = '\0';
		working->log = strdup(q);
		if (working->log == NULL)
			err(1, "strdup");

		if ((working->logbase = strrchr(working->log, '/')) != NULL)
			working->logbase++;

		q = parse = missing_field(sob(++parse), errline, lineno);
		*(parse = son(parse)) = '\0';
		if ((group = strchr(q, ':')) != NULL ||
		    (group = strrchr(q, '.')) != NULL)  {
			*group++ = '\0';
			if (*q) {
				if (!(isnumberstr(q))) {
					if ((pwd = getpwnam(q)) == NULL)
						errx(1, "%s:%d: unknown user: %s",
						    conf, lineno, q);
					working->uid = pwd->pw_uid;
				} else
					working->uid = atoi(q);
			} else
				working->uid = (uid_t)-1;
			
			q = group;
			if (*q) {
				if (!(isnumberstr(q))) {
					if ((grp = getgrnam(q)) == NULL)
						errx(1, "%s:%d: unknown group: %s",
						    conf, lineno, q);
					working->gid = grp->gr_gid;
				} else
					working->gid = atoi(q);
			} else
				working->gid = (gid_t)-1;
			
			q = parse = missing_field(sob(++parse), errline, lineno);
			*(parse = son(parse)) = '\0';
		} else {
			working->uid = (uid_t)-1;
			working->gid = (gid_t)-1;
		}

		l = strtol(q, &ep, 8);
		if (*ep != '\0' || l < 0 || l > ALLPERMS)
			errx(1, "%s:%d: bad permissions: %s", conf, lineno, q);
		working->permissions = (mode_t)l;

		q = parse = missing_field(sob(++parse), errline, lineno);
		*(parse = son(parse)) = '\0';
		l = strtol(q, &ep, 10);
		if (*ep != '\0' || l < 0 || l >= INT_MAX)
			errx(1, "%s:%d: bad number: %s", conf, lineno, q);
		working->numlogs = (int)l;

		q = parse = missing_field(sob(++parse), errline, lineno);
		*(parse = son(parse)) = '\0';
		if (isdigit(*q))
			working->size = atoi(q) * 1024;
		else
			working->size = -1;
		
		working->flags = 0;
		q = parse = missing_field(sob(++parse), errline, lineno);
		*(parse = son(parse)) = '\0';
		l = strtol(q, &ep, 10);
		if (l < 0 || l >= INT_MAX)
			errx(1, "%s:%d: interval out of range: %s", conf,
			    lineno, q);
		working->hours = (int)l;
		switch (*ep) {
		case '\0':
			break;
		case '@':
			working->trim_at = parse8601(ep + 1);
			if (working->trim_at == (time_t) - 1)
				errx(1, "%s:%d: bad time: %s", conf, lineno, q);
			working->flags |= CE_TRIMAT;
			break;
		case '$':
			working->trim_at = parseDWM(ep + 1);
			if (working->trim_at == (time_t) - 1)
				errx(1, "%s:%d: bad time: %s", conf, lineno, q);
			working->flags |= CE_TRIMAT;
			break;
		case '*':
			if (q == ep)
				break;
			/* FALLTHROUGH */
		default:
			errx(1, "%s:%d: bad interval/at: %s", conf, lineno, q);
			break;
		}

		q = sob(++parse);	/* Optional field */
		if (*q == 'Z' || *q == 'z' || *q == 'B' || *q == 'b' ||
		    *q == 'M' || *q == 'm') {
			*(parse = son(q)) = '\0';
			while (*q) {
				switch (*q) {
				case 'Z':
				case 'z':
					working->flags |= CE_COMPACT;
					break;
				case 'B':
				case 'b':
					working->flags |= CE_BINARY;
					break;
				case 'M':
				case 'm':
					working->flags |= CE_MONITOR;
					break;
				case 'F':
				case 'f':
					working->flags |= CE_FOLLOW;
					break;
				default:
					errx(1, "%s:%d: illegal flag: `%c'",
					    conf, lineno, *q);
					break;
				}
				q++;
			}
		} else
			parse--;	/* no flags so undo */

		working->pidfile = PIDFILE;
		working->signal = SIGHUP;
		working->runcmd = NULL;
		working->whom = NULL;
		for (;;) {
			q = parse = sob(++parse);	/* Optional field */
			if (q == NULL || *q == '\0')
				break;
			if (*q == '/') {
				*(parse = son(parse)) = '\0';
				if (strlen(q) >= MAXPATHLEN)
					errx(1, "%s:%d: pathname too long: %s",
					    conf, lineno, q);
				working->pidfile = strdup(q);
				if (working->pidfile == NULL)
					err(1, "strdup");
			} else if (*q == '"' && (tmp = strchr(q + 1, '"'))) {
				*(parse = tmp) = '\0';
				if (*++q != '\0') {
					working->runcmd = strdup(q);
					if (working->runcmd == NULL)
						err(1, "strdup");
				}
				working->pidfile = NULL;
				working->signal = -1;
			} else if (strncmp(q, "SIG", 3) == 0) {
				int i;

				*(parse = son(parse)) = '\0';
				for (i = 1; i < NSIG; i++) {
					if (!strcmp(sys_signame[i], q + 3)) {
						working->signal = i;
						break;
					}
				}
				if (i == NSIG)
					errx(1, "%s:%d: unknown signal: %s",
					    conf, lineno, q);
			} else if (working->flags & CE_MONITOR) {
				*(parse = son(parse)) = '\0';
				working->whom = strdup(q);
				if (working->whom == NULL)
					err(1, "strdup");
			} else
				errx(1, "%s:%d: unrecognized field: %s",
				    conf, lineno, q);
		}
		free(errline);

		if ((working->flags & CE_MONITOR) && working->whom == NULL)
			errx(1, "%s:%d: missing monitor notification field",
			    conf, lineno);

		/* If there is an arcdir, set working->backdir. */
		if (arcdir != NULL && working->logbase != NULL) {
			if (*arcdir == '/') {
				/* Fully qualified arcdir */
				working->backdir = arcdir;
			} else {
				/* arcdir is relative to log's parent dir */
				*(working->logbase - 1) = '\0';
				if ((asprintf(&working->backdir, "%s/%s",
				    working->log, arcdir)) == -1)
					err(1, "malloc");
				*(working->logbase - 1) = '/';
			}
			/* Ignore arcdir if it doesn't exist. */
			if (stat(working->backdir, &sb) != 0 ||
			    !S_ISDIR(sb.st_mode)) {
				if (working->backdir != arcdir)
					free(working->backdir);
				working->backdir = NULL;
			}
		} else
			working->backdir = NULL;

		/* Make sure we can't oflow MAXPATHLEN */
		if (working->backdir != NULL) {
			if (snprintf(line, sizeof(line), "%s/%s.%d%s",
			    working->backdir, working->logbase,
			    working->numlogs, COMPRESS_POSTFIX) >= MAXPATHLEN)
				errx(1, "%s:%d: pathname too long: %s",
				    conf, lineno, q);
		} else {
			if (snprintf(line, sizeof(line), "%s.%d%s",
			    working->log, working->numlogs, COMPRESS_POSTFIX)
			    >= MAXPATHLEN)
				errx(1, "%s:%d: pathname too long: %s",
				    conf, lineno, working->log);
		}
	}
	if (working)
		working->next = NULL;
	(void)fclose(f);
	return (first);
}
Example #3
0
int
ptime_relparse(struct ptime_data *ptime, int parseopts, time_t basetime,
    const char *str)
{
	int dpm, pres;
	struct tm temp_tm;

	ptime->parseopts = parseopts;
	ptime->basesecs = basetime;
	ptime->basetm = *(localtime(&ptime->basesecs));
	ptime->tm = ptime->basetm;
	ptime->tm.tm_hour = ptime->tm.tm_min = ptime->tm.tm_sec = 0;

	/*
	 * Call a routine which sets ptime.tm and ptime.tspecs based
	 * on the given string and parsing-options.  Note that the
	 * routine should not call mktime to set ptime.tsecs.
	 */
	if (parseopts & PTM_PARSE_DWM)
		pres = parseDWM(ptime, str);
	else
		pres = parse8601(ptime, str);
	if (pres < 0) {
		ptime->tsecs = (time_t)pres;
		return (pres);
	}

	/*
	 * Before calling mktime, check to see if we ended up with a
	 * "day-of-month" that does not exist in the selected month.
	 * If we did call mktime with that info, then mktime will
	 * make it look like the user specifically requested a day
	 * in the following month (eg: Feb 31 turns into Mar 3rd).
	 */
	dpm = days_pmonth(ptime->tm.tm_mon, ptime->tm.tm_year);
	if ((parseopts & PTM_PARSE_MATCHDOM) &&
	    (ptime->tmspec & TSPEC_DAYOFMONTH) &&
	    (ptime->tm.tm_mday> dpm)) {
		/*
		 * ptime_nxtime() will want a ptime->tsecs value,
		 * but we need to avoid mktime resetting all the
		 * ptime->tm values.
		 */
		if (verbose && dbg_at_times > 1)
			fprintf(stderr,
			    "\t-- dom fixed: %4d/%02d/%02d %02d:%02d (%02d)",
			    ptime->tm.tm_year, ptime->tm.tm_mon,
			    ptime->tm.tm_mday, ptime->tm.tm_hour,
			    ptime->tm.tm_min, dpm);
		temp_tm = ptime->tm;
		ptime->tsecs = mktime(&temp_tm);
		if (ptime->tsecs > (time_t)-1)
			ptimeset_nxtime(ptime);
		if (verbose && dbg_at_times > 1)
			fprintf(stderr,
			    " to: %4d/%02d/%02d %02d:%02d\n",
			    ptime->tm.tm_year, ptime->tm.tm_mon,
			    ptime->tm.tm_mday, ptime->tm.tm_hour,
			    ptime->tm.tm_min);
	}

	/*
	 * Convert the ptime.tm into standard time_t seconds.  Check
	 * for invalid times, which includes things like the hour lost
	 * when switching from "standard time" to "daylight saving".
	 */
	ptime->tsecs = mktime(&ptime->tm);
	if (ptime->tsecs == (time_t)-1) {
		ptime->tsecs = (time_t)-2;
		return (-2);
	}

	return (0);
}
/* ****************************************************************************
*
* parse8601 - 
*/
TEST(commonGlobals, parse8601)
{
   int       secs;
   const int oneYear    = 365 * 24 * 3600 * 1;
   const int oneMonth   =  30 * 24 * 3600 * 1;
   const int oneWeek    =   7 * 24 * 3600 * 1;
   const int oneDay     =       24 * 3600 * 1;
   const int oneHour    =            3600 * 1;
   const int oneMinute  =              60 * 1;
   const int oneSecond  =                   1;
   const int twoYears   = 365 * 24 * 3600 * 2;
   const int twoMonths  =  30 * 24 * 3600 * 2;
   const int twoWeeks   =         oneWeek * 2;
   const int twoDays    =       24 * 3600 * 2;
   const int twoHours   =            3600 * 2;
   const int twoMinutes =              60 * 2;
   const int twoSeconds =       oneSecond * 2;
   const int threeYearsOneMonthOneDayOneHourOneMinuteAndElevenSeconds = 3 * oneYear + oneMonth + oneDay + oneHour + oneMinute + 11;

   secs = parse8601("P2Y");
   EXPECT_EQ(twoYears, secs) << "bad value for two years";
   secs = parse8601("PT2Y");
   EXPECT_EQ(-1, secs) << "PT2Y should return -1 - parse error ...";

   secs = parse8601("P2M");
   EXPECT_EQ(twoMonths, secs) << "bad value for two months";

   secs = parse8601("P2W");
   EXPECT_EQ(twoWeeks, secs) << "bad value for two weeks";
   secs = parse8601("PT2W");
   EXPECT_EQ(-1, secs) << "PT2W should return -1 - parse error ...";

   secs = parse8601("P2D");
   EXPECT_EQ(twoDays, secs) << "bad value for two days";
   secs = parse8601("PT2D");
   EXPECT_EQ(-1, secs) << "PT2D should return -1 - parse error ...";

   secs = parse8601("PT2H");
   EXPECT_EQ(twoHours, secs) << "bad value for two hours";
   secs = parse8601("P2H");
   EXPECT_EQ(-1, secs) << "P2H should return -1 - parse error ...";

   secs = parse8601("PT2M");
   EXPECT_EQ(twoMinutes, secs) << "bad value for two minutes";

   secs = parse8601("PT2S");
   EXPECT_EQ(twoSeconds, secs) << "bad value for two seconds";
   secs = parse8601("P2S");
   EXPECT_EQ(-1, secs) << "P2S should return -1 - parse error ...";

   secs = parse8601("P3Y1M1DT1H1M11S");
   EXPECT_EQ(threeYearsOneMonthOneDayOneHourOneMinuteAndElevenSeconds, secs) << "parse error for 'P3Y1M1DT1H1M11S'";
}
Example #5
0
/* ****************************************************************************
*
* Throttling::parse -
*/
int64_t Throttling::parse(void)
{
  seconds = parse8601(string);
  return seconds;
}