Mercurial > hg > nginx
comparison src/core/ngx_file.c @ 467:bbd6b0b4a2b1 release-0.1.8
nginx-0.1.8-RELEASE import
*) Bugfix: in the ngx_http_autoindex_module if the long file names were
in the listing.
*) Feature: the "^~" modifier in the location directive.
*) Feature: the proxy_max_temp_file_size directive.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sat, 20 Nov 2004 19:52:20 +0000 |
parents | a88a3e4e158f |
children | c52408583801 |
comparison
equal
deleted
inserted
replaced
466:ee6d66462bff | 467:bbd6b0b4a2b1 |
---|---|
10 | 10 |
11 static ngx_uint_t ngx_temp_number; | 11 static ngx_uint_t ngx_temp_number; |
12 static ngx_uint_t ngx_random; | 12 static ngx_uint_t ngx_random; |
13 | 13 |
14 | 14 |
15 int ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain) | 15 ssize_t ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain) |
16 { | 16 { |
17 int rc; | 17 ngx_int_t rc; |
18 | 18 |
19 if (tf->file.fd == NGX_INVALID_FILE) { | 19 if (tf->file.fd == NGX_INVALID_FILE) { |
20 rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool, | 20 rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool, |
21 tf->persistent); | 21 tf->persistent); |
22 | 22 |
31 | 31 |
32 return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool); | 32 return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool); |
33 } | 33 } |
34 | 34 |
35 | 35 |
36 int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, | 36 ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, |
37 ngx_pool_t *pool, int persistent) | 37 ngx_pool_t *pool, int persistent) |
38 { | 38 { |
39 int num; | 39 ngx_err_t err; |
40 ngx_err_t err; | 40 uint32_t num; |
41 | 41 |
42 file->name.len = path->name.len + 1 + path->len + 10; | 42 file->name.len = path->name.len + 1 + path->len + 10; |
43 | 43 |
44 ngx_test_null(file->name.data, ngx_palloc(pool, file->name.len + 1), | 44 if (!(file->name.data = ngx_palloc(pool, file->name.len + 1))) { |
45 NGX_ERROR); | 45 return NGX_ERROR; |
46 } | |
46 | 47 |
47 #if 0 | 48 #if 0 |
48 for (i = 0; i < file->name.len; i++) { | 49 for (i = 0; i < file->name.len; i++) { |
49 file->name.data[i] = 'X'; | 50 file->name.data[i] = 'X'; |
50 } | 51 } |
51 #endif | 52 #endif |
52 | 53 |
53 ngx_memcpy(file->name.data, path->name.data, path->name.len); | 54 ngx_memcpy(file->name.data, path->name.data, path->name.len); |
54 | 55 |
55 num = ngx_next_temp_number(0); | 56 num = (uint32_t) ngx_next_temp_number(0); |
56 | 57 |
57 for ( ;; ) { | 58 for ( ;; ) { |
58 ngx_sprintf(file->name.data + path->name.len + 1 + path->len, | 59 ngx_sprintf(file->name.data + path->name.len + 1 + path->len, |
59 "%010ud%Z", num); | 60 "%010ui%Z", num); |
60 | 61 |
61 ngx_create_hashed_filename(file, path); | 62 ngx_create_hashed_filename(file, path); |
62 | 63 |
63 #if 1 | 64 #if 1 |
64 file->fd = ngx_open_tempfile(file->name.data, persistent); | 65 file->fd = ngx_open_tempfile(file->name.data, persistent); |
83 if ((path->level[0] == 0) | 84 if ((path->level[0] == 0) |
84 || (err != NGX_ENOENT | 85 || (err != NGX_ENOENT |
85 #if (NGX_WIN32) | 86 #if (NGX_WIN32) |
86 && err != NGX_ENOTDIR | 87 && err != NGX_ENOTDIR |
87 #endif | 88 #endif |
88 )) { | 89 )) |
90 { | |
89 ngx_log_error(NGX_LOG_CRIT, file->log, err, | 91 ngx_log_error(NGX_LOG_CRIT, file->log, err, |
90 ngx_open_tempfile_n " \"%s\" failed", | 92 ngx_open_tempfile_n " \"%s\" failed", |
91 file->name.data); | 93 file->name.data); |
92 return NGX_ERROR; | 94 return NGX_ERROR; |
93 } | 95 } |
99 } | 101 } |
100 | 102 |
101 | 103 |
102 void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path) | 104 void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path) |
103 { | 105 { |
104 int i, name, pos; | 106 ngx_uint_t i, name, pos, level; |
105 size_t level; | |
106 | 107 |
107 name = file->name.len; | 108 name = file->name.len; |
108 pos = path->name.len + 1; | 109 pos = path->name.len + 1; |
109 | 110 |
110 file->name.data[path->name.len + path->len] = '/'; | 111 file->name.data[path->name.len + path->len] = '/'; |
125 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, | 126 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, |
126 "hashed path: %s", file->name.data); | 127 "hashed path: %s", file->name.data); |
127 } | 128 } |
128 | 129 |
129 | 130 |
130 int ngx_create_path(ngx_file_t *file, ngx_path_t *path) | 131 ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path) |
131 { | 132 { |
132 int i, pos; | 133 int i, pos; |
133 ngx_err_t err; | 134 ngx_err_t err; |
134 | 135 |
135 pos = path->name.len; | 136 pos = path->name.len; |
187 | 188 |
188 char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 189 char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
189 { | 190 { |
190 char *p = conf; | 191 char *p = conf; |
191 | 192 |
192 ngx_int_t level; | 193 ssize_t level; |
193 ngx_uint_t i, n; | 194 ngx_uint_t i, n; |
194 ngx_str_t *value; | 195 ngx_str_t *value; |
195 ngx_path_t *path, **pp; | 196 ngx_path_t *path, **pp, **slot; |
196 | 197 |
197 pp = (ngx_path_t **) (p + cmd->offset); | 198 slot = (ngx_path_t **) (p + cmd->offset); |
198 | 199 |
199 if (*pp) { | 200 if (*slot) { |
200 return "is duplicate"; | 201 return "is duplicate"; |
201 } | 202 } |
202 | 203 |
203 /* TODO: check duplicate in cf->cycle->pathes */ | 204 if (!(path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)))) { |
204 | 205 return NGX_CONF_ERROR; |
205 ngx_test_null(path, ngx_pcalloc(cf->pool, sizeof(ngx_path_t)), | 206 } |
206 NGX_CONF_ERROR); | 207 |
207 | 208 value = cf->args->elts; |
208 *pp = path; | |
209 | |
210 ngx_test_null(pp, ngx_push_array(&cf->cycle->pathes), NGX_CONF_ERROR); | |
211 *pp = path; | |
212 | |
213 value = (ngx_str_t *) cf->args->elts; | |
214 | 209 |
215 path->name = value[1]; | 210 path->name = value[1]; |
216 | |
217 path->len = 0; | 211 path->len = 0; |
212 path->gc_handler = (ngx_gc_handler_pt) cmd->post; | |
213 path->conf_file = cf->conf_file->file.name.data; | |
214 path->line = cf->conf_file->line; | |
218 | 215 |
219 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) { | 216 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) { |
220 level = ngx_atoi(value[n].data, value[n].len); | 217 level = ngx_atoi(value[n].data, value[n].len); |
221 if (level == NGX_ERROR || level == 0) { | 218 if (level == NGX_ERROR || level == 0) { |
222 return "invalid value"; | 219 return "invalid value"; |
228 | 225 |
229 while (i < 3) { | 226 while (i < 3) { |
230 path->level[i++] = 0; | 227 path->level[i++] = 0; |
231 } | 228 } |
232 | 229 |
233 path->gc_handler = (ngx_gc_handler_pt) cmd->post; | 230 |
231 pp = cf->cycle->pathes.elts; | |
232 for (i = 0; i < cf->cycle->pathes.nelts; i++) { | |
233 if (pp[i]->name.len == path->name.len | |
234 && ngx_strcmp(pp[i]->name.data, path->name.data) == 0) | |
235 { | |
236 for (n = 0; n < 3; n++) { | |
237 if (pp[i]->level[n] != path->level[n]) { | |
238 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
239 "the same \"%V\" path name in %s:%ui " | |
240 "has the different levels than", | |
241 &pp[i]->name, pp[i]->conf_file, pp[i]->line); | |
242 return NGX_CONF_ERROR; | |
243 } | |
244 | |
245 if (pp[i]->level[n] == 0) { | |
246 break; | |
247 } | |
248 } | |
249 | |
250 *slot = pp[i]; | |
251 | |
252 return NGX_CONF_OK; | |
253 } | |
254 } | |
255 | |
256 *slot = path; | |
257 | |
258 | |
259 if (!(pp = ngx_array_push(&cf->cycle->pathes))) { | |
260 return NGX_CONF_ERROR; | |
261 } | |
262 | |
263 *pp = path; | |
234 | 264 |
235 return NGX_CONF_OK; | 265 return NGX_CONF_OK; |
236 } | 266 } |
267 | |
268 | |
269 ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user) | |
270 { | |
271 ngx_err_t err; | |
272 ngx_uint_t i; | |
273 ngx_path_t **path; | |
274 #if !(NGX_WIN32) | |
275 ngx_file_info_t fi; | |
276 #endif | |
277 | |
278 path = cycle->pathes.elts; | |
279 for (i = 0; i < cycle->pathes.nelts; i++) { | |
280 | |
281 if (ngx_create_dir(path[i]->name.data) == NGX_FILE_ERROR) { | |
282 err = ngx_errno; | |
283 if (err != NGX_EEXIST) { | |
284 ngx_log_error(NGX_LOG_EMERG, cycle->log, err, | |
285 ngx_create_dir_n " \"%s\" failed", | |
286 path[i]->name.data); | |
287 return NGX_ERROR; | |
288 } | |
289 } | |
290 | |
291 if (user == (ngx_uid_t) -1) { | |
292 continue; | |
293 } | |
294 | |
295 #if !(NGX_WIN32) | |
296 | |
297 if (ngx_file_info((const char *) path[i]->name.data, &fi) == -1) { | |
298 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
299 ngx_file_info_n " \"%s\" failed", path[i]->name.data); | |
300 return NGX_ERROR; | |
301 } | |
302 | |
303 if (fi.st_uid != user) { | |
304 if (chown((const char *) path[i]->name.data, user, -1) == -1) { | |
305 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
306 "chown(\"%s\", %d) failed", | |
307 path[i]->name.data, user); | |
308 return NGX_ERROR; | |
309 } | |
310 } | |
311 | |
312 if ((fi.st_mode & (S_IRUSR|S_IWUSR|S_IXUSR)) | |
313 != (S_IRUSR|S_IWUSR|S_IXUSR)) | |
314 { | |
315 fi.st_mode |= (S_IRUSR|S_IWUSR|S_IXUSR); | |
316 | |
317 if (chmod((const char *) path[i]->name.data, fi.st_mode) == -1) { | |
318 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, | |
319 "chmod() \"%s\" failed", path[i]->name.data); | |
320 return NGX_ERROR; | |
321 } | |
322 } | |
323 | |
324 #endif | |
325 } | |
326 | |
327 return NGX_OK; | |
328 } |