int main(int argc, char *argv[]) { char *str[] = {"3", "3n", "3 hours", "3.5 day", "3 week", "3 m", "3 q", "3 years"}; utime_t val; char buf[100]; char outval[100]; for (int i=0; i<8; i++) { strcpy(buf, str[i]); if (!duration_to_utime(buf, &val)) { printf("Error return from duration_to_utime for in=%s\n", str[i]); continue; } edit_utime(val, outval); printf("in=%s val=%" lld " outval=%s\n", str[i], val, outval); } }
static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr) { char ed1[150], ed2[50]; POOL_MEM query(PM_MESSAGE); if (!duration_to_utime(val, &mr->VolRetention)) { ua->error_msg(_("Invalid retention period specified: %s\n"), val); return; } Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s", edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2)); if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) { ua->error_msg("%s", db_strerror(ua->db)); } else { ua->info_msg(_("New retention period is: %s\n"), edit_utime(mr->VolRetention, ed1, sizeof(ed1))); } }
/* * Store a time period in seconds */ static void store_time(LEX *lc, RES_ITEM *item, int index, int pass) { int token; utime_t utime; char period[500]; URES *res_all = (URES *)my_config->m_res_all; token = lex_get_token(lc, T_SKIP_EOL); errno = 0; switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncpy(period, lc->str, sizeof(period)); /* get first part */ /* * If terminated by space, scan and get modifier */ while (lc->ch == ' ') { token = lex_get_token(lc, T_ALL); switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncat(period, lc->str, sizeof(period)); break; } } if (!duration_to_utime(period, &utime)) { scan_err1(lc, _("expected a time period, got: %s"), period); return; } *(item->utimevalue) = utime; break; default: scan_err1(lc, _("expected a time period, got: %s"), lc->str); return; } if (token != T_EOL) { scan_to_eol(lc); } set_bit(index, res_all->hdr.item_present); }
/* * Confirm a retention period */ bool confirm_retention(UAContext *ua, utime_t *ret, const char *msg) { bool retval; char ed1[100]; int yes_in_arg; yes_in_arg = find_arg(ua, NT_("yes")); for ( ;; ) { ua->info_msg(_("The current %s retention period is: %s\n"), msg, edit_utime(*ret, ed1, sizeof(ed1))); if (yes_in_arg != -1) { return true; } if (!get_cmd(ua, _("Continue? (yes/mod/no): "))) { return false; } if (bstrcasecmp(ua->cmd, _("mod"))) { if (!get_cmd(ua, _("Enter new retention period: "))) { return false; } if (!duration_to_utime(ua->cmd, ret)) { ua->error_msg(_("Invalid period.\n")); continue; } continue; } if (is_yesno(ua->cmd, &retval)) { return retval; } } return true; }
/* * Store Schedule Run information * * Parse Run statement: * * Run <keyword=value ...> [on] 2 january at 23:45 * * Default Run time is daily at 0:0 * * There can be multiple run statements, they are simply chained * together. * */ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) { char *p; int i, j; int options = lc->options; int token, state, state2 = 0, code = 0, code2 = 0; bool found; utime_t utime; RES *res; RUNRES **run = (RUNRES **)(item->value); URES *res_all = (URES *)my_config->m_res_all; lc->options |= LOPT_NO_IDENT; /* Want only "strings" */ /* * Clear local copy of run record */ memset(&lrun, 0, sizeof(lrun)); /* * Scan for Job level "full", "incremental", ... */ for (found = true; found; ) { found = false; token = lex_get_token(lc, T_NAME); for (i = 0; !found && RunFields[i].name; i++) { if (bstrcasecmp(lc->str, RunFields[i].name)) { found = true; if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, _("Expected an equals, got: %s"), lc->str); /* NOT REACHED */ } switch (RunFields[i].token) { case 's': /* Data spooling */ token = lex_get_token(lc, T_NAME); if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) { lrun.spool_data = true; lrun.spool_data_set = true; } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) { lrun.spool_data = false; lrun.spool_data_set = true; } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); } break; case 'L': /* Level */ token = lex_get_token(lc, T_NAME); for (j = 0; joblevels[j].level_name; j++) { if (bstrcasecmp(lc->str, joblevels[j].level_name)) { lrun.level = joblevels[j].level; lrun.job_type = joblevels[j].job_type; j = 0; break; } } if (j != 0) { scan_err1(lc, _("Job level field: %s not found in run record"), lc->str); /* NOT REACHED */ } break; case 'p': /* Priority */ token = lex_get_token(lc, T_PINT32); if (pass == 2) { lrun.Priority = lc->pint32_val; } break; case 'P': /* Pool */ case 'f': /* FullPool */ case 'v': /* VFullPool */ case 'i': /* IncPool */ case 'd': /* DiffPool */ case 'n': /* NextPool */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_POOL, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Pool Resource: %s"), lc->str); /* NOT REACHED */ } switch(RunFields[i].token) { case 'P': lrun.pool = (POOLRES *)res; break; case 'f': lrun.full_pool = (POOLRES *)res; break; case 'v': lrun.vfull_pool = (POOLRES *)res; break; case 'i': lrun.inc_pool = (POOLRES *)res; break; case 'd': lrun.diff_pool = (POOLRES *)res; break; case 'n': lrun.next_pool = (POOLRES *)res; break; } } break; case 'S': /* Storage */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_STORAGE, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Storage Resource: %s"), lc->str); /* NOT REACHED */ } lrun.storage = (STORERES *)res; } break; case 'M': /* Messages */ token = lex_get_token(lc, T_NAME); if (pass == 2) { res = GetResWithName(R_MSGS, lc->str); if (res == NULL) { scan_err1(lc, _("Could not find specified Messages Resource: %s"), lc->str); /* NOT REACHED */ } lrun.msgs = (MSGSRES *)res; } break; case 'm': /* Max run sched time */ token = lex_get_token(lc, T_QUOTED_STRING); if (!duration_to_utime(lc->str, &utime)) { scan_err1(lc, _("expected a time period, got: %s"), lc->str); return; } lrun.MaxRunSchedTime = utime; lrun.MaxRunSchedTime_set = true; break; case 'a': /* Accurate */ token = lex_get_token(lc, T_NAME); if (strcasecmp(lc->str, "yes") == 0 || strcasecmp(lc->str, "true") == 0) { lrun.accurate = true; lrun.accurate_set = true; } else if (strcasecmp(lc->str, "no") == 0 || strcasecmp(lc->str, "false") == 0) { lrun.accurate = false; lrun.accurate_set = true; } else { scan_err1(lc, _("Expect a YES or NO, got: %s"), lc->str); } break; default: scan_err1(lc, _("Expected a keyword name, got: %s"), lc->str); /* NOT REACHED */ break; } /* end switch */ } /* end if bstrcasecmp */ } /* end for RunFields */ /* * At this point, it is not a keyword. Check for old syle * Job Levels without keyword. This form is depreciated!!! */ if (!found) { for (j = 0; joblevels[j].level_name; j++) { if (bstrcasecmp(lc->str, joblevels[j].level_name)) { lrun.level = joblevels[j].level; lrun.job_type = joblevels[j].job_type; found = true; break; } } } } /* end for found */ /* * Scan schedule times. * Default is: daily at 0:0 */ state = s_none; set_defaults(); for (; token != T_EOL; (token = lex_get_token(lc, T_ALL))) { int len; bool pm = false; bool am = false; switch (token) { case T_NUMBER: state = s_mday; code = atoi(lc->str) - 1; if (code < 0 || code > 30) { scan_err0(lc, _("Day number out of range (1-31)")); } break; case T_NAME: /* This handles drop through from keyword */ case T_UNQUOTED_STRING: if (strchr(lc->str, (int)'-')) { state = s_range; break; } if (strchr(lc->str, (int)':')) { state = s_time; break; } if (strchr(lc->str, (int)'/')) { state = s_modulo; break; } if (lc->str_len == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && is_an_integer(lc->str+1)) { code = atoi(lc->str+1); if (code < 0 || code > 53) { scan_err0(lc, _("Week number out of range (0-53)")); /* NOT REACHED */ } state = s_woy; /* Week of year */ break; } /* * Everything else must be a keyword */ for (i = 0; keyw[i].name; i++) { if (bstrcasecmp(lc->str, keyw[i].name)) { state = keyw[i].state; code = keyw[i].code; i = 0; break; } } if (i != 0) { scan_err1(lc, _("Job type field: %s in run record not found"), lc->str); /* NOT REACHED */ } break; case T_COMMA: continue; default: scan_err2(lc, _("Unexpected token: %d:%s"), token, lc->str); /* NOT REACHED */ break; } switch (state) { case s_none: continue; case s_mday: /* Day of month */ if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } set_bit(code, lrun.mday); break; case s_month: /* Month of year */ if (!have_month) { clear_bits(0, 11, lrun.month); have_month = true; } set_bit(code, lrun.month); break; case s_wday: /* Week day */ if (!have_wday) { clear_bits(0, 6, lrun.wday); have_wday = true; } set_bit(code, lrun.wday); break; case s_wom: /* Week of month 1st, ... */ if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } set_bit(code, lrun.wom); break; case s_woy: if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } set_bit(code, lrun.woy); break; case s_time: /* Time */ if (!have_at) { scan_err0(lc, _("Time must be preceded by keyword AT.")); /* NOT REACHED */ } if (!have_hour) { clear_bits(0, 23, lrun.hour); } // Dmsg1(000, "s_time=%s\n", lc->str); p = strchr(lc->str, ':'); if (!p) { scan_err0(lc, _("Time logic error.\n")); /* NOT REACHED */ } *p++ = 0; /* Separate two halves */ code = atoi(lc->str); /* Pick up hour */ code2 = atoi(p); /* Pick up minutes */ len = strlen(p); if (len >= 2) { p += 2; } if (bstrcasecmp(p, "pm")) { pm = true; } else if (bstrcasecmp(p, "am")) { am = true; } else if (len != 2) { scan_err0(lc, _("Bad time specification.")); /* NOT REACHED */ } /* * Note, according to NIST, 12am and 12pm are ambiguous and * can be defined to anything. However, 12:01am is the same * as 00:01 and 12:01pm is the same as 12:01, so we define * 12am as 00:00 and 12pm as 12:00. */ if (pm) { /* * Convert to 24 hour time */ if (code != 12) { code += 12; } } else if (am && code == 12) { /* * AM */ code -= 12; } if (code < 0 || code > 23 || code2 < 0 || code2 > 59) { scan_err0(lc, _("Bad time specification.")); /* NOT REACHED */ } set_bit(code, lrun.hour); lrun.minute = code2; have_hour = true; break; case s_at: have_at = true; break; case s_last: lrun.last_set = true; if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } break; case s_modulo: p = strchr(lc->str, '/'); if (!p) { scan_err0(lc, _("Modulo logic error.\n")); } *p++ = 0; /* Separate two halves */ if (is_an_integer(lc->str) && is_an_integer(p)) { /* * Check for day modulo specification. */ code = atoi(lc->str) - 1; code2 = atoi(p); if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { scan_err0(lc, _("Bad day specification in modulo.")); } if (code > code2) { scan_err0(lc, _("Bad day specification, offset must always be <= than modulo.")); } if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } /* * Set the bits according to the modulo specification. */ for (i = 0; i < 31; i++) { if (i % code2 == 0) { set_bit(i + code, lrun.mday); } } } else if (strlen(lc->str) == 3 && strlen(p) == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && (p[0] == 'w' || p[0] == 'W') && is_an_integer(lc->str + 1) && is_an_integer(p + 1)) { /* * Check for week modulo specification. */ code = atoi(lc->str + 1); code2 = atoi(p + 1); if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { scan_err0(lc, _("Week number out of range (0-53) in modulo")); } if (code > code2) { scan_err0(lc, _("Bad week number specification in modulo, offset must always be <= than modulo.")); } if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } /* * Set the bits according to the modulo specification. */ for (i = 0; i < 54; i++) { if (i % code2 == 0) { set_bit(i + code - 1, lrun.woy); } } } else { scan_err0(lc, _("Bad modulo time specification. Format for weekdays is '01/02', for yearweeks is 'w01/w02'.")); } break; case s_range: p = strchr(lc->str, '-'); if (!p) { scan_err0(lc, _("Range logic error.\n")); } *p++ = 0; /* Separate two halves */ if (is_an_integer(lc->str) && is_an_integer(p)) { /* * Check for day range. */ code = atoi(lc->str) - 1; code2 = atoi(p) - 1; if (code < 0 || code > 30 || code2 < 0 || code2 > 30) { scan_err0(lc, _("Bad day range specification.")); } if (!have_mday) { clear_bits(0, 30, lrun.mday); have_mday = true; } if (code < code2) { set_bits(code, code2, lrun.mday); } else { set_bits(code, 30, lrun.mday); set_bits(0, code2, lrun.mday); } } else if (strlen(lc->str) == 3 && strlen(p) == 3 && (lc->str[0] == 'w' || lc->str[0] == 'W') && (p[0] == 'w' || p[0] == 'W') && is_an_integer(lc->str + 1) && is_an_integer(p + 1)) { /* * Check for week of year range. */ code = atoi(lc->str + 1); code2 = atoi(p + 1); if (code < 0 || code > 53 || code2 < 0 || code2 > 53) { scan_err0(lc, _("Week number out of range (0-53)")); } if (!have_woy) { clear_bits(0, 53, lrun.woy); have_woy = true; } if (code < code2) { set_bits(code, code2, lrun.woy); } else { set_bits(code, 53, lrun.woy); set_bits(0, code2, lrun.woy); } } else { /* * lookup first half of keyword range (week days or months). */ lcase(lc->str); for (i = 0; keyw[i].name; i++) { if (bstrcmp(lc->str, keyw[i].name)) { state = keyw[i].state; code = keyw[i].code; i = 0; break; } } if (i != 0 || (state != s_month && state != s_wday && state != s_wom)) { scan_err0(lc, _("Invalid month, week or position day range")); /* NOT REACHED */ } /* * Lookup end of range. */ lcase(p); for (i = 0; keyw[i].name; i++) { if (bstrcmp(p, keyw[i].name)) { state2 = keyw[i].state; code2 = keyw[i].code; i = 0; break; } } if (i != 0 || state != state2 || code == code2) { scan_err0(lc, _("Invalid month, weekday or position range")); /* NOT REACHED */ } if (state == s_wday) { if (!have_wday) { clear_bits(0, 6, lrun.wday); have_wday = true; } if (code < code2) { set_bits(code, code2, lrun.wday); } else { set_bits(code, 6, lrun.wday); set_bits(0, code2, lrun.wday); } } else if (state == s_month) { if (!have_month) { clear_bits(0, 11, lrun.month); have_month = true; } if (code < code2) { set_bits(code, code2, lrun.month); } else { /* * This is a bit odd, but we accept it anyway */ set_bits(code, 11, lrun.month); set_bits(0, code2, lrun.month); } } else { /* * Must be position */ if (!have_wom) { clear_bits(0, 4, lrun.wom); have_wom = true; } if (code < code2) { set_bits(code, code2, lrun.wom); } else { set_bits(code, 4, lrun.wom); set_bits(0, code2, lrun.wom); } } } break; case s_hourly: have_hour = true; set_bits(0, 23, lrun.hour); break; case s_weekly: have_mday = have_wom = have_woy = true; set_bits(0, 30, lrun.mday); set_bits(0, 4, lrun.wom); set_bits(0, 53, lrun.woy); break; case s_daily: have_mday = true; set_bits(0, 6, lrun.wday); break; case s_monthly: have_month = true; set_bits(0, 11, lrun.month); break; default: scan_err0(lc, _("Unexpected run state\n")); /* NOT REACHED */ break; } } /* Allocate run record, copy new stuff into it, * and append it to the list of run records * in the schedule resource. */ if (pass == 2) { RUNRES *tail; /* Create new run record */ RUNRES *nrun = (RUNRES *)malloc(sizeof(RUNRES)); memcpy(nrun, &lrun, sizeof(RUNRES)); nrun ->next = NULL; if (!*run) { /* If empty list */ *run = nrun; /* Add new record */ } else { for (tail = *run; tail->next; tail=tail->next) { } tail->next = nrun; } } lc->options = options; /* Restore scanner options */ set_bit(index, res_all->res_sch.hdr.item_present); clear_bit(index, res_all->hdr.inherit_content); }