0
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
660
|
4 * Copyright (C) Nginx, Inc.
|
0
|
5 */
|
|
6
|
|
7
|
|
8 #include <ngx_config.h>
|
|
9 #include <ngx_core.h>
|
|
10
|
|
11
|
112
|
12 ssize_t
|
|
13 ngx_parse_size(ngx_str_t *line)
|
0
|
14 {
|
372
|
15 u_char unit;
|
0
|
16 size_t len;
|
112
|
17 ssize_t size;
|
|
18 ngx_int_t scale;
|
0
|
19
|
|
20 len = line->len;
|
372
|
21 unit = line->data[len - 1];
|
0
|
22
|
372
|
23 switch (unit) {
|
0
|
24 case 'K':
|
|
25 case 'k':
|
|
26 len--;
|
|
27 scale = 1024;
|
|
28 break;
|
|
29
|
|
30 case 'M':
|
|
31 case 'm':
|
|
32 len--;
|
|
33 scale = 1024 * 1024;
|
|
34 break;
|
|
35
|
|
36 default:
|
|
37 scale = 1;
|
|
38 }
|
|
39
|
112
|
40 size = ngx_atosz(line->data, len);
|
0
|
41 if (size == NGX_ERROR) {
|
|
42 return NGX_ERROR;
|
|
43 }
|
|
44
|
|
45 size *= scale;
|
|
46
|
|
47 return size;
|
|
48 }
|
|
49
|
|
50
|
212
|
51 off_t
|
|
52 ngx_parse_offset(ngx_str_t *line)
|
|
53 {
|
372
|
54 u_char unit;
|
212
|
55 off_t offset;
|
|
56 size_t len;
|
|
57 ngx_int_t scale;
|
|
58
|
|
59 len = line->len;
|
372
|
60 unit = line->data[len - 1];
|
212
|
61
|
372
|
62 switch (unit) {
|
212
|
63 case 'K':
|
|
64 case 'k':
|
|
65 len--;
|
|
66 scale = 1024;
|
|
67 break;
|
|
68
|
|
69 case 'M':
|
|
70 case 'm':
|
|
71 len--;
|
|
72 scale = 1024 * 1024;
|
|
73 break;
|
|
74
|
|
75 case 'G':
|
|
76 case 'g':
|
|
77 len--;
|
|
78 scale = 1024 * 1024 * 1024;
|
|
79 break;
|
|
80
|
|
81 default:
|
|
82 scale = 1;
|
|
83 }
|
|
84
|
|
85 offset = ngx_atoof(line->data, len);
|
|
86 if (offset == NGX_ERROR) {
|
|
87 return NGX_ERROR;
|
|
88 }
|
|
89
|
|
90 offset *= scale;
|
|
91
|
|
92 return offset;
|
|
93 }
|
|
94
|
|
95
|
112
|
96 ngx_int_t
|
644
|
97 ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
|
0
|
98 {
|
372
|
99 u_char *p, *last;
|
200
|
100 ngx_int_t value, total, scale;
|
372
|
101 ngx_uint_t max, valid;
|
0
|
102 enum {
|
|
103 st_start = 0,
|
|
104 st_year,
|
|
105 st_month,
|
|
106 st_week,
|
|
107 st_day,
|
|
108 st_hour,
|
|
109 st_min,
|
|
110 st_sec,
|
|
111 st_msec,
|
|
112 st_last
|
|
113 } step;
|
|
114
|
372
|
115 valid = 0;
|
|
116 value = 0;
|
0
|
117 total = 0;
|
644
|
118 step = is_sec ? st_start : st_month;
|
|
119 scale = is_sec ? 1 : 1000;
|
0
|
120
|
372
|
121 p = line->data;
|
|
122 last = p + line->len;
|
0
|
123
|
372
|
124 while (p < last) {
|
0
|
125
|
372
|
126 if (*p >= '0' && *p <= '9') {
|
|
127 value = value * 10 + (*p++ - '0');
|
|
128 valid = 1;
|
|
129 continue;
|
0
|
130 }
|
|
131
|
372
|
132 switch (*p++) {
|
0
|
133
|
|
134 case 'y':
|
|
135 if (step > st_start) {
|
|
136 return NGX_ERROR;
|
|
137 }
|
|
138 step = st_year;
|
644
|
139 max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
|
0
|
140 scale = 60 * 60 * 24 * 365;
|
|
141 break;
|
|
142
|
|
143 case 'M':
|
644
|
144 if (step >= st_month) {
|
0
|
145 return NGX_ERROR;
|
|
146 }
|
|
147 step = st_month;
|
644
|
148 max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
|
0
|
149 scale = 60 * 60 * 24 * 30;
|
|
150 break;
|
|
151
|
|
152 case 'w':
|
644
|
153 if (step >= st_week) {
|
0
|
154 return NGX_ERROR;
|
|
155 }
|
|
156 step = st_week;
|
644
|
157 max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
|
0
|
158 scale = 60 * 60 * 24 * 7;
|
|
159 break;
|
|
160
|
|
161 case 'd':
|
644
|
162 if (step >= st_day) {
|
0
|
163 return NGX_ERROR;
|
|
164 }
|
|
165 step = st_day;
|
644
|
166 max = NGX_MAX_INT32_VALUE / (60 * 60 * 24);
|
0
|
167 scale = 60 * 60 * 24;
|
|
168 break;
|
|
169
|
|
170 case 'h':
|
644
|
171 if (step >= st_hour) {
|
0
|
172 return NGX_ERROR;
|
|
173 }
|
|
174 step = st_hour;
|
644
|
175 max = NGX_MAX_INT32_VALUE / (60 * 60);
|
0
|
176 scale = 60 * 60;
|
|
177 break;
|
|
178
|
|
179 case 'm':
|
372
|
180 if (*p == 's') {
|
644
|
181 if (is_sec || step >= st_msec) {
|
372
|
182 return NGX_ERROR;
|
|
183 }
|
|
184 p++;
|
|
185 step = st_msec;
|
644
|
186 max = NGX_MAX_INT32_VALUE;
|
372
|
187 scale = 1;
|
|
188 break;
|
|
189 }
|
|
190
|
644
|
191 if (step >= st_min) {
|
0
|
192 return NGX_ERROR;
|
|
193 }
|
|
194 step = st_min;
|
644
|
195 max = NGX_MAX_INT32_VALUE / 60;
|
0
|
196 scale = 60;
|
|
197 break;
|
|
198
|
|
199 case 's':
|
644
|
200 if (step >= st_sec) {
|
0
|
201 return NGX_ERROR;
|
|
202 }
|
|
203 step = st_sec;
|
644
|
204 max = NGX_MAX_INT32_VALUE;
|
0
|
205 scale = 1;
|
|
206 break;
|
|
207
|
372
|
208 case ' ':
|
644
|
209 if (step >= st_sec) {
|
372
|
210 return NGX_ERROR;
|
|
211 }
|
0
|
212 step = st_last;
|
644
|
213 max = NGX_MAX_INT32_VALUE;
|
0
|
214 scale = 1;
|
372
|
215 break;
|
0
|
216
|
372
|
217 default:
|
0
|
218 return NGX_ERROR;
|
|
219 }
|
|
220
|
644
|
221 if (step != st_msec && !is_sec) {
|
0
|
222 scale *= 1000;
|
|
223 max /= 1000;
|
|
224 }
|
|
225
|
372
|
226 if ((ngx_uint_t) value > max) {
|
|
227 return NGX_ERROR;
|
0
|
228 }
|
|
229
|
|
230 total += value * scale;
|
|
231
|
644
|
232 if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
|
372
|
233 return NGX_ERROR;
|
0
|
234 }
|
|
235
|
372
|
236 value = 0;
|
644
|
237 scale = is_sec ? 1 : 1000;
|
372
|
238
|
|
239 while (p < last && *p == ' ') {
|
|
240 p++;
|
0
|
241 }
|
|
242 }
|
|
243
|
372
|
244 if (valid) {
|
|
245 return total + value * scale;
|
|
246 }
|
|
247
|
|
248 return NGX_ERROR;
|
0
|
249 }
|