#include <ngx_config.h> | |
#include <ngx_core.h> | |
int ngx_parse_size(ngx_str_t *line) | |
{ | |
int scale, size; | |
char last; | |
size_t len; | |
len = line->len; | |
last = line->data[len - 1]; | |
switch (last) { | |
case 'K': | |
case 'k': | |
len--; | |
scale = 1024; | |
break; | |
case 'M': | |
case 'm': | |
len--; | |
scale = 1024 * 1024; | |
break; | |
default: | |
scale = 1; | |
} | |
size = ngx_atoi(line->data, len); | |
if (size == NGX_ERROR) { | |
return NGX_ERROR; | |
} | |
size *= scale; | |
return size; | |
} | |
int ngx_parse_time(ngx_str_t *line, int sec) | |
{ | |
int value, total, scale; | |
u_int max, i; | |
size_t len; | |
char *start, last; | |
enum { | |
st_start = 0, | |
st_year, | |
st_month, | |
st_week, | |
st_day, | |
st_hour, | |
st_min, | |
st_sec, | |
st_msec, | |
st_last | |
} step; | |
start = line->data; | |
len = 0; | |
total = 0; | |
step = sec ? st_start : st_month; | |
for (i = 0; /* void */ ; i++) { | |
if (i < line->len) { | |
if (line->data[i] != ' ') { | |
len++; | |
continue; | |
} | |
if (line->data[i] == ' ' && len == 0) { | |
start = &line->data[i + 1]; | |
continue; | |
} | |
} | |
if (len == 0) { | |
break; | |
} | |
last = line->data[i - 1]; | |
switch (last) { | |
case 'y': | |
if (step > st_start) { | |
return NGX_ERROR; | |
} | |
step = st_year; | |
len--; | |
max = 68; | |
scale = 60 * 60 * 24 * 365; | |
break; | |
case 'M': | |
if (step > st_year) { | |
return NGX_ERROR; | |
} | |
step = st_month; | |
len--; | |
max = 828; | |
scale = 60 * 60 * 24 * 30; | |
break; | |
case 'w': | |
if (step > st_month) { | |
return NGX_ERROR; | |
} | |
step = st_week; | |
len--; | |
max = 3550; | |
scale = 60 * 60 * 24 * 7; | |
break; | |
case 'd': | |
if (step > st_week) { | |
return NGX_ERROR; | |
} | |
step = st_day; | |
len--; | |
max = 24855; | |
scale = 60 * 60 * 24; | |
break; | |
case 'h': | |
if (step > st_day) { | |
return NGX_ERROR; | |
} | |
step = st_hour; | |
len--; | |
max = 596523; | |
scale = 60 * 60; | |
break; | |
case 'm': | |
if (step > st_hour) { | |
return NGX_ERROR; | |
} | |
step = st_min; | |
len--; | |
max = 35791394; | |
scale = 60; | |
break; | |
case 's': | |
len--; | |
if (line->data[i - 2] == 'm') { | |
if (sec || step > st_sec) { | |
return NGX_ERROR; | |
} | |
step = st_msec; | |
len--; | |
max = 2147483647; | |
scale = 1; | |
break; | |
} | |
if (step > st_min) { | |
return NGX_ERROR; | |
} | |
step = st_sec; | |
max = 2147483647; | |
scale = 1; | |
break; | |
default: | |
step = st_last; | |
max = 2147483647; | |
scale = 1; | |
} | |
value = ngx_atoi(start, len); | |
if (value == NGX_ERROR) { | |
return NGX_ERROR; | |
} | |
if (step != st_msec && !sec) { | |
scale *= 1000; | |
max /= 1000; | |
} | |
if ((u_int) value > max) { | |
return NGX_PARSE_LARGE_TIME; | |
} | |
total += value * scale; | |
if ((u_int) total > 2147483647) { | |
return NGX_PARSE_LARGE_TIME; | |
} | |
if (i >= line->len) { | |
break; | |
} | |
len = 0; | |
start = &line->data[i + 1]; | |
} | |
return total; | |
} |