10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 30Sigor@sysoev.ru * Copyright (C) Igor Sysoev 40Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 50Sigor@sysoev.ru */ 60Sigor@sysoev.ru 70Sigor@sysoev.ru #include <nxt_main.h> 80Sigor@sysoev.ru 90Sigor@sysoev.ru 100Sigor@sysoev.ru /* 110Sigor@sysoev.ru * nxt_time_parse() parses a time string given in RFC822, RFC850, or ISOC 120Sigor@sysoev.ru * formats and returns nxt_time_t value >= 0 on success or -1 on failure. 130Sigor@sysoev.ru */ 140Sigor@sysoev.ru 150Sigor@sysoev.ru nxt_time_t 160Sigor@sysoev.ru nxt_time_parse(const u_char *p, size_t len) 170Sigor@sysoev.ru { 180Sigor@sysoev.ru size_t n; 190Sigor@sysoev.ru u_char c; 200Sigor@sysoev.ru uint64_t s; 210Sigor@sysoev.ru nxt_int_t yr, month, day, hour, min, sec; 220Sigor@sysoev.ru nxt_uint_t year, days; 230Sigor@sysoev.ru const u_char *end; 240Sigor@sysoev.ru 250Sigor@sysoev.ru static nxt_int_t mday[12] = { 260Sigor@sysoev.ru 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 270Sigor@sysoev.ru }; 280Sigor@sysoev.ru 290Sigor@sysoev.ru enum { 300Sigor@sysoev.ru RFC822 = 0, /* "Mon, 28 Sep 1970 12:00:00" */ 310Sigor@sysoev.ru RFC850, /* "Monday, 28-Sep-70 12:00:00" */ 320Sigor@sysoev.ru ISOC, /* "Mon Sep 28 12:00:00 1970" */ 330Sigor@sysoev.ru } fmt; 340Sigor@sysoev.ru 350Sigor@sysoev.ru fmt = RFC822; 360Sigor@sysoev.ru end = p + len; 370Sigor@sysoev.ru 380Sigor@sysoev.ru while (p < end) { 390Sigor@sysoev.ru c = *p++; 400Sigor@sysoev.ru 410Sigor@sysoev.ru if (c == ',') { 420Sigor@sysoev.ru break; 430Sigor@sysoev.ru } 440Sigor@sysoev.ru 450Sigor@sysoev.ru if (c == ' ') { 460Sigor@sysoev.ru fmt = ISOC; 470Sigor@sysoev.ru break; 480Sigor@sysoev.ru } 490Sigor@sysoev.ru } 500Sigor@sysoev.ru 510Sigor@sysoev.ru while (p < end) { 520Sigor@sysoev.ru if (*p != ' ') { 530Sigor@sysoev.ru break; 540Sigor@sysoev.ru } 550Sigor@sysoev.ru 560Sigor@sysoev.ru p++; 570Sigor@sysoev.ru } 580Sigor@sysoev.ru 590Sigor@sysoev.ru if (nxt_slow_path(p + 18 > end)) { 600Sigor@sysoev.ru /* Lesser than RFC850 "28-Sep-70 12:00:00" length. */ 610Sigor@sysoev.ru return -1; 620Sigor@sysoev.ru } 630Sigor@sysoev.ru 640Sigor@sysoev.ru day = 0; 650Sigor@sysoev.ru 660Sigor@sysoev.ru if (fmt != ISOC) { 670Sigor@sysoev.ru day = nxt_int_parse(p, 2); 680Sigor@sysoev.ru if (nxt_slow_path(day <= 0)) { 690Sigor@sysoev.ru return -1; 700Sigor@sysoev.ru } 710Sigor@sysoev.ru p += 2; 720Sigor@sysoev.ru 730Sigor@sysoev.ru if (*p == ' ') { 740Sigor@sysoev.ru if (nxt_slow_path(p + 18 > end)) { 750Sigor@sysoev.ru /* Lesser than RFC822 " Sep 1970 12:00:00" length. */ 760Sigor@sysoev.ru return -1; 770Sigor@sysoev.ru } 780Sigor@sysoev.ru 790Sigor@sysoev.ru /* RFC822 */ 800Sigor@sysoev.ru 810Sigor@sysoev.ru } else if (*p == '-') { 820Sigor@sysoev.ru fmt = RFC850; 830Sigor@sysoev.ru 840Sigor@sysoev.ru } else { 850Sigor@sysoev.ru return -1; 860Sigor@sysoev.ru } 870Sigor@sysoev.ru 880Sigor@sysoev.ru p++; 890Sigor@sysoev.ru } 900Sigor@sysoev.ru 910Sigor@sysoev.ru switch (*p) { 920Sigor@sysoev.ru 930Sigor@sysoev.ru case 'J': 940Sigor@sysoev.ru month = p[1] == 'a' ? 0 : p[2] == 'n' ? 5 : 6; 950Sigor@sysoev.ru break; 960Sigor@sysoev.ru 970Sigor@sysoev.ru case 'F': 980Sigor@sysoev.ru month = 1; 990Sigor@sysoev.ru break; 1000Sigor@sysoev.ru 1010Sigor@sysoev.ru case 'M': 1020Sigor@sysoev.ru month = p[2] == 'r' ? 2 : 4; 1030Sigor@sysoev.ru break; 1040Sigor@sysoev.ru 1050Sigor@sysoev.ru case 'A': 1060Sigor@sysoev.ru month = p[1] == 'p' ? 3 : 7; 1070Sigor@sysoev.ru break; 1080Sigor@sysoev.ru 1090Sigor@sysoev.ru case 'S': 1100Sigor@sysoev.ru month = 8; 1110Sigor@sysoev.ru break; 1120Sigor@sysoev.ru 1130Sigor@sysoev.ru case 'O': 1140Sigor@sysoev.ru month = 9; 1150Sigor@sysoev.ru break; 1160Sigor@sysoev.ru 1170Sigor@sysoev.ru case 'N': 1180Sigor@sysoev.ru month = 10; 1190Sigor@sysoev.ru break; 1200Sigor@sysoev.ru 1210Sigor@sysoev.ru case 'D': 1220Sigor@sysoev.ru month = 11; 1230Sigor@sysoev.ru break; 1240Sigor@sysoev.ru 1250Sigor@sysoev.ru default: 1260Sigor@sysoev.ru return -1; 1270Sigor@sysoev.ru } 1280Sigor@sysoev.ru 1290Sigor@sysoev.ru p += 3; 1300Sigor@sysoev.ru yr = 0; 1310Sigor@sysoev.ru 1320Sigor@sysoev.ru switch (fmt) { 1330Sigor@sysoev.ru 1340Sigor@sysoev.ru case RFC822: 1350Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 1360Sigor@sysoev.ru return -1; 1370Sigor@sysoev.ru } 1380Sigor@sysoev.ru 1390Sigor@sysoev.ru yr = nxt_int_parse(p, 4); 1400Sigor@sysoev.ru if (nxt_slow_path(yr <= 0)) { 1410Sigor@sysoev.ru return -1; 1420Sigor@sysoev.ru } 1430Sigor@sysoev.ru p += 4; 1440Sigor@sysoev.ru 1450Sigor@sysoev.ru break; 1460Sigor@sysoev.ru 1470Sigor@sysoev.ru case RFC850: 1480Sigor@sysoev.ru if (nxt_slow_path(*p++ != '-')) { 1490Sigor@sysoev.ru return -1; 1500Sigor@sysoev.ru } 1510Sigor@sysoev.ru 1520Sigor@sysoev.ru yr = nxt_int_parse(p, 2); 1530Sigor@sysoev.ru if (nxt_slow_path(yr <= 0)) { 1540Sigor@sysoev.ru return -1; 1550Sigor@sysoev.ru } 1560Sigor@sysoev.ru p += 2; 1570Sigor@sysoev.ru 1580Sigor@sysoev.ru yr += (yr < 70) ? 2000 : 1900; 1590Sigor@sysoev.ru 1600Sigor@sysoev.ru break; 1610Sigor@sysoev.ru 1620Sigor@sysoev.ru default: /* ISOC */ 1630Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 1640Sigor@sysoev.ru return -1; 1650Sigor@sysoev.ru } 1660Sigor@sysoev.ru 1670Sigor@sysoev.ru if (p[0] != ' ') { 1680Sigor@sysoev.ru n = 2; 1690Sigor@sysoev.ru 1700Sigor@sysoev.ru if (p[1] == ' ') { 1710Sigor@sysoev.ru n = 1; 1720Sigor@sysoev.ru } 1730Sigor@sysoev.ru 1740Sigor@sysoev.ru } else { 1750Sigor@sysoev.ru p++; 1760Sigor@sysoev.ru n = 1; 1770Sigor@sysoev.ru } 1780Sigor@sysoev.ru 1790Sigor@sysoev.ru day = nxt_int_parse(p, n); 1800Sigor@sysoev.ru if (nxt_slow_path(day <= 0)) { 1810Sigor@sysoev.ru return -1; 1820Sigor@sysoev.ru } 1830Sigor@sysoev.ru p += n; 1840Sigor@sysoev.ru 1850Sigor@sysoev.ru if (nxt_slow_path(p + 14 > end)) { 1860Sigor@sysoev.ru /* Lesser than ISOC " 12:00:00 1970" length. */ 1870Sigor@sysoev.ru return -1; 1880Sigor@sysoev.ru } 1890Sigor@sysoev.ru 1900Sigor@sysoev.ru break; 1910Sigor@sysoev.ru } 1920Sigor@sysoev.ru 1930Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 1940Sigor@sysoev.ru return -1; 1950Sigor@sysoev.ru } 1960Sigor@sysoev.ru 1970Sigor@sysoev.ru hour = nxt_int_parse(p, 2); 1980Sigor@sysoev.ru if (nxt_slow_path(hour < 0)) { 1990Sigor@sysoev.ru return -1; 2000Sigor@sysoev.ru } 2010Sigor@sysoev.ru p += 2; 2020Sigor@sysoev.ru 2030Sigor@sysoev.ru if (nxt_slow_path(*p++ != ':')) { 2040Sigor@sysoev.ru return -1; 2050Sigor@sysoev.ru } 2060Sigor@sysoev.ru 2070Sigor@sysoev.ru min = nxt_int_parse(p, 2); 2080Sigor@sysoev.ru if (nxt_slow_path(min < 0)) { 2090Sigor@sysoev.ru return -1; 2100Sigor@sysoev.ru } 2110Sigor@sysoev.ru p += 2; 2120Sigor@sysoev.ru 2130Sigor@sysoev.ru if (nxt_slow_path(*p++ != ':')) { 2140Sigor@sysoev.ru return -1; 2150Sigor@sysoev.ru } 2160Sigor@sysoev.ru 2170Sigor@sysoev.ru sec = nxt_int_parse(p, 2); 2180Sigor@sysoev.ru if (nxt_slow_path(sec < 0)) { 2190Sigor@sysoev.ru return -1; 2200Sigor@sysoev.ru } 2210Sigor@sysoev.ru 2220Sigor@sysoev.ru if (fmt == ISOC) { 2230Sigor@sysoev.ru p += 2; 2240Sigor@sysoev.ru 2250Sigor@sysoev.ru if (nxt_slow_path(*p++ != ' ')) { 2260Sigor@sysoev.ru return -1; 2270Sigor@sysoev.ru } 2280Sigor@sysoev.ru 2290Sigor@sysoev.ru yr = nxt_int_parse(p, 4); 2300Sigor@sysoev.ru if (nxt_slow_path(yr < 0)) { 2310Sigor@sysoev.ru return -1; 2320Sigor@sysoev.ru } 2330Sigor@sysoev.ru } 2340Sigor@sysoev.ru 2350Sigor@sysoev.ru if (nxt_slow_path(hour > 23 || min > 59 || sec > 59)) { 2360Sigor@sysoev.ru return -1; 2370Sigor@sysoev.ru } 2380Sigor@sysoev.ru 2390Sigor@sysoev.ru year = yr; 2400Sigor@sysoev.ru 2410Sigor@sysoev.ru if (day == 29 && month == 1) { 2420Sigor@sysoev.ru 2430Sigor@sysoev.ru if (nxt_slow_path((year & 3) != 0)) { 2440Sigor@sysoev.ru /* Not a leap year. */ 2450Sigor@sysoev.ru return -1; 2460Sigor@sysoev.ru } 2470Sigor@sysoev.ru 2480Sigor@sysoev.ru if (nxt_slow_path((year % 100 == 0) && (year % 400) != 0)) { 2490Sigor@sysoev.ru /* Not a leap year. */ 2500Sigor@sysoev.ru return -1; 2510Sigor@sysoev.ru } 2520Sigor@sysoev.ru 2530Sigor@sysoev.ru } else if (nxt_slow_path(day > mday[(nxt_uint_t) month])) { 2540Sigor@sysoev.ru return -1; 2550Sigor@sysoev.ru } 2560Sigor@sysoev.ru 2570Sigor@sysoev.ru /* 2580Sigor@sysoev.ru * Shift new year to March 1 and start months 2590Sigor@sysoev.ru * from 1 (not 0), as required for Gauss' formula. 2600Sigor@sysoev.ru */ 2610Sigor@sysoev.ru 2620Sigor@sysoev.ru if (--month <= 0) { 2630Sigor@sysoev.ru month += 12; 2640Sigor@sysoev.ru year -= 1; 2650Sigor@sysoev.ru } 2660Sigor@sysoev.ru 2670Sigor@sysoev.ru /* Gauss' formula for Gregorian days since March 1, 1 BCE. */ 2680Sigor@sysoev.ru 2690Sigor@sysoev.ru /* Days in years including leap years since March 1, 1 BCE. */ 2700Sigor@sysoev.ru days = 365 * year + year / 4 - year / 100 + year / 400 2710Sigor@sysoev.ru 2720Sigor@sysoev.ru /* Days before the month. */ 2730Sigor@sysoev.ru + 367 * (nxt_uint_t) month / 12 - 30 2740Sigor@sysoev.ru 2750Sigor@sysoev.ru /* Days before the day. */ 2760Sigor@sysoev.ru + (nxt_uint_t) day - 1; 2770Sigor@sysoev.ru 2780Sigor@sysoev.ru /* 2790Sigor@sysoev.ru * 719527 days were between March 1, 1 BCE and March 1, 1970, 2800Sigor@sysoev.ru * 31 and 28 days were in January and February 1970. 2810Sigor@sysoev.ru */ 2820Sigor@sysoev.ru days = days - 719527 + 31 + 28; 2830Sigor@sysoev.ru 2840Sigor@sysoev.ru s = (uint64_t) days * 86400 285*2078Salx.manpages@gmail.com + (nxt_uint_t) hour * 3600 286*2078Salx.manpages@gmail.com + (nxt_uint_t) min * 60 287*2078Salx.manpages@gmail.com + (nxt_uint_t) sec; 2880Sigor@sysoev.ru 2890Sigor@sysoev.ru #if (NXT_TIME_T_SIZE <= 4) 2900Sigor@sysoev.ru 2910Sigor@sysoev.ru /* Y2038 */ 2920Sigor@sysoev.ru 293611Svbart@nginx.com if (nxt_slow_path(s > 0x7FFFFFFF)) { 2940Sigor@sysoev.ru return -1; 2950Sigor@sysoev.ru } 2960Sigor@sysoev.ru 2970Sigor@sysoev.ru #endif 2980Sigor@sysoev.ru 2990Sigor@sysoev.ru return (nxt_time_t) s; 3000Sigor@sysoev.ru } 3010Sigor@sysoev.ru 3020Sigor@sysoev.ru 3030Sigor@sysoev.ru /* 3040Sigor@sysoev.ru * nxt_term_parse() parses term string given in format "200", "10m", 3050Sigor@sysoev.ru * or "1d 1h" and returns nxt_int_t value >= 0 on success, -1 on failure, 3060Sigor@sysoev.ru * and -2 on overflow. The maximum valid value is 2^31 - 1 or about 3070Sigor@sysoev.ru * 68 years in seconds or about 24 days in milliseconds. 3080Sigor@sysoev.ru */ 3090Sigor@sysoev.ru 3100Sigor@sysoev.ru nxt_int_t 3110Sigor@sysoev.ru nxt_term_parse(const u_char *p, size_t len, nxt_bool_t seconds) 3120Sigor@sysoev.ru { 3130Sigor@sysoev.ru u_char c, ch; 3140Sigor@sysoev.ru nxt_uint_t val, term, scale, max; 3150Sigor@sysoev.ru const u_char *end; 3160Sigor@sysoev.ru 3170Sigor@sysoev.ru enum { 3180Sigor@sysoev.ru st_first_digit = 0, 3190Sigor@sysoev.ru st_digit, 3200Sigor@sysoev.ru st_letter, 3210Sigor@sysoev.ru st_space, 3220Sigor@sysoev.ru } state; 3230Sigor@sysoev.ru 3240Sigor@sysoev.ru enum { 3250Sigor@sysoev.ru st_start = 0, 3260Sigor@sysoev.ru st_year, 3270Sigor@sysoev.ru st_month, 3280Sigor@sysoev.ru st_week, 3290Sigor@sysoev.ru st_day, 3300Sigor@sysoev.ru st_hour, 3310Sigor@sysoev.ru st_min, 3320Sigor@sysoev.ru st_sec, 3330Sigor@sysoev.ru st_msec, 3340Sigor@sysoev.ru st_last, 3350Sigor@sysoev.ru } step; 3360Sigor@sysoev.ru 3370Sigor@sysoev.ru val = 0; 3380Sigor@sysoev.ru term = 0; 3390Sigor@sysoev.ru state = st_first_digit; 3400Sigor@sysoev.ru step = seconds ? st_start : st_month; 3410Sigor@sysoev.ru 3420Sigor@sysoev.ru end = p + len; 3430Sigor@sysoev.ru 3440Sigor@sysoev.ru while (p < end) { 3450Sigor@sysoev.ru 3460Sigor@sysoev.ru ch = *p++; 3470Sigor@sysoev.ru 3480Sigor@sysoev.ru if (state == st_space) { 3490Sigor@sysoev.ru 3500Sigor@sysoev.ru if (ch == ' ') { 3510Sigor@sysoev.ru continue; 3520Sigor@sysoev.ru } 3530Sigor@sysoev.ru 3540Sigor@sysoev.ru state = st_first_digit; 3550Sigor@sysoev.ru } 3560Sigor@sysoev.ru 3570Sigor@sysoev.ru if (state != st_letter) { 3580Sigor@sysoev.ru 3590Sigor@sysoev.ru /* Values below '0' become >= 208. */ 3600Sigor@sysoev.ru c = ch - '0'; 3610Sigor@sysoev.ru 3620Sigor@sysoev.ru if (c <= 9) { 3630Sigor@sysoev.ru val = val * 10 + c; 3640Sigor@sysoev.ru state = st_digit; 3650Sigor@sysoev.ru continue; 3660Sigor@sysoev.ru } 3670Sigor@sysoev.ru 3680Sigor@sysoev.ru if (state == st_first_digit) { 3690Sigor@sysoev.ru return -1; 3700Sigor@sysoev.ru } 3710Sigor@sysoev.ru 3720Sigor@sysoev.ru state = st_letter; 3730Sigor@sysoev.ru } 3740Sigor@sysoev.ru 3750Sigor@sysoev.ru switch (ch) { 3760Sigor@sysoev.ru 3770Sigor@sysoev.ru case 'y': 3780Sigor@sysoev.ru if (step > st_start) { 3790Sigor@sysoev.ru return -1; 3800Sigor@sysoev.ru } 3810Sigor@sysoev.ru step = st_year; 3820Sigor@sysoev.ru max = NXT_INT32_T_MAX / (365 * 24 * 60 * 60); 3830Sigor@sysoev.ru scale = 365 * 24 * 60 * 60; 3840Sigor@sysoev.ru break; 3850Sigor@sysoev.ru 3860Sigor@sysoev.ru case 'M': 3870Sigor@sysoev.ru if (step >= st_month) { 3880Sigor@sysoev.ru return -1; 3890Sigor@sysoev.ru } 3900Sigor@sysoev.ru step = st_month; 3910Sigor@sysoev.ru max = NXT_INT32_T_MAX / (30 * 24 * 60 * 60); 3920Sigor@sysoev.ru scale = 30 * 24 * 60 * 60; 3930Sigor@sysoev.ru break; 3940Sigor@sysoev.ru 3950Sigor@sysoev.ru case 'w': 3960Sigor@sysoev.ru if (step >= st_week) { 3970Sigor@sysoev.ru return -1; 3980Sigor@sysoev.ru } 3990Sigor@sysoev.ru step = st_week; 4000Sigor@sysoev.ru max = NXT_INT32_T_MAX / (7 * 24 * 60 * 60); 4010Sigor@sysoev.ru scale = 7 * 24 * 60 * 60; 4020Sigor@sysoev.ru break; 4030Sigor@sysoev.ru 4040Sigor@sysoev.ru case 'd': 4050Sigor@sysoev.ru if (step >= st_day) { 4060Sigor@sysoev.ru return -1; 4070Sigor@sysoev.ru } 4080Sigor@sysoev.ru step = st_day; 4090Sigor@sysoev.ru max = NXT_INT32_T_MAX / (24 * 60 * 60); 4100Sigor@sysoev.ru scale = 24 * 60 * 60; 4110Sigor@sysoev.ru break; 4120Sigor@sysoev.ru 4130Sigor@sysoev.ru case 'h': 4140Sigor@sysoev.ru if (step >= st_hour) { 4150Sigor@sysoev.ru return -1; 4160Sigor@sysoev.ru } 4170Sigor@sysoev.ru step = st_hour; 4180Sigor@sysoev.ru max = NXT_INT32_T_MAX / (60 * 60); 4190Sigor@sysoev.ru scale = 60 * 60; 4200Sigor@sysoev.ru break; 4210Sigor@sysoev.ru 4220Sigor@sysoev.ru case 'm': 4230Sigor@sysoev.ru if (p < end && *p == 's') { 4240Sigor@sysoev.ru if (seconds || step >= st_msec) { 4250Sigor@sysoev.ru return -1; 4260Sigor@sysoev.ru } 4270Sigor@sysoev.ru p++; 4280Sigor@sysoev.ru step = st_msec; 4290Sigor@sysoev.ru max = NXT_INT32_T_MAX; 4300Sigor@sysoev.ru scale = 1; 4310Sigor@sysoev.ru break; 4320Sigor@sysoev.ru } 4330Sigor@sysoev.ru 4340Sigor@sysoev.ru if (step >= st_min) { 4350Sigor@sysoev.ru return -1; 4360Sigor@sysoev.ru } 4370Sigor@sysoev.ru step = st_min; 4380Sigor@sysoev.ru max = NXT_INT32_T_MAX / 60; 4390Sigor@sysoev.ru scale = 60; 4400Sigor@sysoev.ru break; 4410Sigor@sysoev.ru 4420Sigor@sysoev.ru case 's': 4430Sigor@sysoev.ru if (step >= st_sec) { 4440Sigor@sysoev.ru return -1; 4450Sigor@sysoev.ru } 4460Sigor@sysoev.ru step = st_sec; 4470Sigor@sysoev.ru max = NXT_INT32_T_MAX; 4480Sigor@sysoev.ru scale = 1; 4490Sigor@sysoev.ru break; 4500Sigor@sysoev.ru 4510Sigor@sysoev.ru case ' ': 4520Sigor@sysoev.ru if (step >= st_sec) { 4530Sigor@sysoev.ru return -1; 4540Sigor@sysoev.ru } 4550Sigor@sysoev.ru step = st_last; 4560Sigor@sysoev.ru max = NXT_INT32_T_MAX; 4570Sigor@sysoev.ru scale = 1; 4580Sigor@sysoev.ru break; 4590Sigor@sysoev.ru 4600Sigor@sysoev.ru default: 4610Sigor@sysoev.ru return -1; 4620Sigor@sysoev.ru } 4630Sigor@sysoev.ru 4640Sigor@sysoev.ru if (!seconds && step != st_msec) { 4650Sigor@sysoev.ru scale *= 1000; 4660Sigor@sysoev.ru max /= 1000; 4670Sigor@sysoev.ru } 4680Sigor@sysoev.ru 4690Sigor@sysoev.ru if (val > max) { 4700Sigor@sysoev.ru return -2; 4710Sigor@sysoev.ru } 4720Sigor@sysoev.ru 4730Sigor@sysoev.ru term += val * scale; 4740Sigor@sysoev.ru 4750Sigor@sysoev.ru if (term > NXT_INT32_T_MAX) { 4760Sigor@sysoev.ru return -2; 4770Sigor@sysoev.ru } 4780Sigor@sysoev.ru 4790Sigor@sysoev.ru val = 0; 4800Sigor@sysoev.ru 4810Sigor@sysoev.ru state = st_space; 4820Sigor@sysoev.ru } 4830Sigor@sysoev.ru 4840Sigor@sysoev.ru if (!seconds) { 4850Sigor@sysoev.ru val *= 1000; 4860Sigor@sysoev.ru } 4870Sigor@sysoev.ru 4880Sigor@sysoev.ru return term + val; 4890Sigor@sysoev.ru } 490