Bug Summary

File:core/ngx_file.c
Location:line 907, column 13
Description:Null pointer argument in call to memory copy function

Annotated Source Code

1
2/*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
5 */
6
7
8#include <ngx_config.h>
9#include <ngx_core.h>
10
11
12static ngx_atomic_t temp_number = 0;
13ngx_atomic_t *ngx_temp_number = &temp_number;
14ngx_atomic_int_t ngx_random_number = 123456;
15
16
17ssize_t
18ngx_write_chain_to_temp_file(ngx_temp_file_t *tf, ngx_chain_t *chain)
19{
20 ngx_int_t rc;
21
22 if (tf->file.fd == NGX_INVALID_FILE-1) {
23 rc = ngx_create_temp_file(&tf->file, tf->path, tf->pool,
24 tf->persistent, tf->clean, tf->access);
25
26 if (rc == NGX_ERROR-1 || rc == NGX_AGAIN-2) {
27 return rc;
28 }
29
30 if (tf->log_level) {
31 ngx_log_error(tf->log_level, tf->file.log, 0, "%s %V",if ((tf->file.log)->log_level >= tf->log_level) ngx_log_error_core
(tf->log_level, tf->file.log, 0, "%s %V", tf->warn, &
tf->file.name)
32 tf->warn, &tf->file.name)if ((tf->file.log)->log_level >= tf->log_level) ngx_log_error_core
(tf->log_level, tf->file.log, 0, "%s %V", tf->warn, &
tf->file.name)
;
33 }
34 }
35
36 return ngx_write_chain_to_file(&tf->file, chain, tf->offset, tf->pool);
37}
38
39
40ngx_int_t
41ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
42 ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access)
43{
44 uint32_t n;
45 ngx_err_t err;
46 ngx_pool_cleanup_t *cln;
47 ngx_pool_cleanup_file_t *clnf;
48
49 file->name.len = path->name.len + 1 + path->len + 10;
50
51 file->name.data = ngx_pnalloc(pool, file->name.len + 1);
52 if (file->name.data == NULL((void*)0)) {
53 return NGX_ERROR-1;
54 }
55
56#if 0
57 for (i = 0; i < file->name.len; i++) {
58 file->name.data[i] = 'X';
59 }
60#endif
61
62 ngx_memcpy(file->name.data, path->name.data, path->name.len)(void) ((__builtin_object_size (file->name.data, 0) != (size_t
) -1) ? __builtin___memcpy_chk (file->name.data, path->
name.data, path->name.len, __builtin_object_size (file->
name.data, 0)) : __inline_memcpy_chk (file->name.data, path
->name.data, path->name.len))
;
63
64 n = (uint32_t) ngx_next_temp_number(0);
65
66 cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t));
67 if (cln == NULL((void*)0)) {
68 return NGX_ERROR-1;
69 }
70
71 for ( ;; ) {
72 (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len,
73 "%010uD%Z", n);
74
75 ngx_create_hashed_filename(path, file->name.data, file->name.len);
76
77 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
78 "hashed path: %s", file->name.data);
79
80 file->fd = ngx_open_tempfile(file->name.data, persistent, access);
81
82 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
83 "temp fd:%d", file->fd);
84
85 if (file->fd != NGX_INVALID_FILE-1) {
86
87 cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file;
88 clnf = cln->data;
89
90 clnf->fd = file->fd;
91 clnf->name = file->name.data;
92 clnf->log = pool->log;
93
94 return NGX_OK0;
95 }
96
97 err = ngx_errno(*__error());
98
99 if (err == NGX_EEXIST17) {
100 n = (uint32_t) ngx_next_temp_number(1);
101 continue;
102 }
103
104 if ((path->level[0] == 0) || (err != NGX_ENOPATH2)) {
105 ngx_log_error(NGX_LOG_CRIT, file->log, err,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "open()" " \"%s\" failed", file->name
.data)
106 ngx_open_tempfile_n " \"%s\" failed",if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "open()" " \"%s\" failed", file->name
.data)
107 file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "open()" " \"%s\" failed", file->name
.data)
;
108 return NGX_ERROR-1;
109 }
110
111 if (ngx_create_path(file, path) == NGX_ERROR-1) {
112 return NGX_ERROR-1;
113 }
114 }
115}
116
117
118void
119ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len)
120{
121 size_t i, level;
122 ngx_uint_t n;
123
124 i = path->name.len + 1;
125
126 file[path->name.len + path->len] = '/';
127
128 for (n = 0; n < 3; n++) {
129 level = path->level[n];
130
131 if (level == 0) {
132 break;
133 }
134
135 len -= level;
136 file[i - 1] = '/';
137 ngx_memcpy(&file[i], &file[len], level)(void) ((__builtin_object_size (&file[i], 0) != (size_t) -
1) ? __builtin___memcpy_chk (&file[i], &file[len], level
, __builtin_object_size (&file[i], 0)) : __inline_memcpy_chk
(&file[i], &file[len], level))
;
138 i += level + 1;
139 }
140}
141
142
143ngx_int_t
144ngx_create_path(ngx_file_t *file, ngx_path_t *path)
145{
146 size_t pos;
147 ngx_err_t err;
148 ngx_uint_t i;
149
150 pos = path->name.len;
151
152 for (i = 0; i < 3; i++) {
153 if (path->level[i] == 0) {
154 break;
155 }
156
157 pos += path->level[i] + 1;
158
159 file->name.data[pos] = '\0';
160
161 ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
162 "temp file: \"%s\"", file->name.data);
163
164 if (ngx_create_dir(file->name.data, 0700)mkdir((const char *) file->name.data, 0700) == NGX_FILE_ERROR-1) {
165 err = ngx_errno(*__error());
166 if (err != NGX_EEXIST17) {
167 ngx_log_error(NGX_LOG_CRIT, file->log, err,if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "mkdir()" " \"%s\" failed", file->name
.data)
168 ngx_create_dir_n " \"%s\" failed",if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "mkdir()" " \"%s\" failed", file->name
.data)
169 file->name.data)if ((file->log)->log_level >= 3) ngx_log_error_core(
3, file->log, err, "mkdir()" " \"%s\" failed", file->name
.data)
;
170 return NGX_ERROR-1;
171 }
172 }
173
174 file->name.data[pos] = '/';
175 }
176
177 return NGX_OK0;
178}
179
180
181ngx_err_t
182ngx_create_full_path(u_char *dir, ngx_uint_t access)
183{
184 u_char *p, ch;
185 ngx_err_t err;
186
187 err = 0;
188
189#if (NGX_WIN32)
190 p = dir + 3;
191#else
192 p = dir + 1;
193#endif
194
195 for ( /* void */ ; *p; p++) {
196 ch = *p;
197
198 if (ch != '/') {
199 continue;
200 }
201
202 *p = '\0';
203
204 if (ngx_create_dir(dir, access)mkdir((const char *) dir, access) == NGX_FILE_ERROR-1) {
205 err = ngx_errno(*__error());
206
207 switch (err) {
208 case NGX_EEXIST17:
209 err = 0;
210 case NGX_EACCES13:
211 break;
212
213 default:
214 return err;
215 }
216 }
217
218 *p = '/';
219 }
220
221 return err;
222}
223
224
225ngx_atomic_uint_t
226ngx_next_temp_number(ngx_uint_t collision)
227{
228 ngx_atomic_uint_t n, add;
229
230 add = collision ? ngx_random_number : 1;
231
232 n = ngx_atomic_fetch_add(ngx_temp_number, add)(OSAtomicAdd64(add, (int64_t *) ngx_temp_number) - add);
233
234 return n + add;
235}
236
237
238char *
239ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
240{
241 char *p = conf;
242
243 ssize_t level;
244 ngx_str_t *value;
245 ngx_uint_t i, n;
246 ngx_path_t *path, **slot;
247
248 slot = (ngx_path_t **) (p + cmd->offset);
249
250 if (*slot) {
251 return "is duplicate";
252 }
253
254 path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
255 if (path == NULL((void*)0)) {
256 return NGX_CONF_ERROR(void *) -1;
257 }
258
259 value = cf->args->elts;
260
261 path->name = value[1];
262
263 if (path->name.data[path->name.len - 1] == '/') {
264 path->name.len--;
265 }
266
267 if (ngx_conf_full_name(cf->cycle, &path->name, 0) != NGX_OK0) {
268 return NULL((void*)0);
269 }
270
271 path->len = 0;
272 path->manager = NULL((void*)0);
273 path->loader = NULL((void*)0);
274 path->conf_file = cf->conf_file->file.name.data;
275 path->line = cf->conf_file->line;
276
277 for (i = 0, n = 2; n < cf->args->nelts; i++, n++) {
278 level = ngx_atoi(value[n].data, value[n].len);
279 if (level == NGX_ERROR-1 || level == 0) {
280 return "invalid value";
281 }
282
283 path->level[i] = level;
284 path->len += level + 1;
285 }
286
287 while (i < 3) {
288 path->level[i++] = 0;
289 }
290
291 *slot = path;
292
293 if (ngx_add_path(cf, slot) == NGX_ERROR-1) {
294 return NGX_CONF_ERROR(void *) -1;
295 }
296
297 return NGX_CONF_OK((void*)0);
298}
299
300
301char *
302ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
303 ngx_path_init_t *init)
304{
305 if (*path) {
306 return NGX_CONF_OK((void*)0);
307 }
308
309 if (prev) {
310 *path = prev;
311 return NGX_CONF_OK((void*)0);
312 }
313
314 *path = ngx_palloc(cf->pool, sizeof(ngx_path_t));
315 if (*path == NULL((void*)0)) {
316 return NGX_CONF_ERROR(void *) -1;
317 }
318
319 (*path)->name = init->name;
320
321 if (ngx_conf_full_name(cf->cycle, &(*path)->name, 0) != NGX_OK0) {
322 return NGX_CONF_ERROR(void *) -1;
323 }
324
325 (*path)->level[0] = init->level[0];
326 (*path)->level[1] = init->level[1];
327 (*path)->level[2] = init->level[2];
328
329 (*path)->len = init->level[0] + (init->level[0] ? 1 : 0)
330 + init->level[1] + (init->level[1] ? 1 : 0)
331 + init->level[2] + (init->level[2] ? 1 : 0);
332
333 (*path)->manager = NULL((void*)0);
334 (*path)->loader = NULL((void*)0);
335 (*path)->conf_file = NULL((void*)0);
336
337 if (ngx_add_path(cf, path) != NGX_OK0) {
338 return NGX_CONF_ERROR(void *) -1;
339 }
340
341 return NGX_CONF_OK((void*)0);
342}
343
344
345char *
346ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
347{
348 char *confp = conf;
349
350 u_char *p;
351 ngx_str_t *value;
352 ngx_uint_t i, right, shift, *access;
353
354 access = (ngx_uint_t *) (confp + cmd->offset);
355
356 if (*access != NGX_CONF_UNSET_UINT(ngx_uint_t) -1) {
357 return "is duplicate";
358 }
359
360 value = cf->args->elts;
361
362 *access = 0600;
363
364 for (i = 1; i < cf->args->nelts; i++) {
365
366 p = value[i].data;
367
368 if (ngx_strncmp(p, "user:", sizeof("user:") - 1)strncmp((const char *) p, (const char *) "user:", sizeof("user:"
) - 1)
== 0) {
369 shift = 6;
370 p += sizeof("user:") - 1;
371
372 } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1)strncmp((const char *) p, (const char *) "group:", sizeof("group:"
) - 1)
== 0) {
373 shift = 3;
374 p += sizeof("group:") - 1;
375
376 } else if (ngx_strncmp(p, "all:", sizeof("all:") - 1)strncmp((const char *) p, (const char *) "all:", sizeof("all:"
) - 1)
== 0) {
377 shift = 0;
378 p += sizeof("all:") - 1;
379
380 } else {
381 goto invalid;
382 }
383
384 if (ngx_strcmp(p, "rw")strcmp((const char *) p, (const char *) "rw") == 0) {
385 right = 6;
386
387 } else if (ngx_strcmp(p, "r")strcmp((const char *) p, (const char *) "r") == 0) {
388 right = 4;
389
390 } else {
391 goto invalid;
392 }
393
394 *access |= right << shift;
395 }
396
397 return NGX_CONF_OK((void*)0);
398
399invalid:
400
401 ngx_conf_log_error(NGX_LOG_EMERG1, cf, 0, "invalid value \"%V\"", &value[i]);
402
403 return NGX_CONF_ERROR(void *) -1;
404}
405
406
407ngx_int_t
408ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
409{
410 ngx_uint_t i, n;
411 ngx_path_t *path, **p;
412
413 path = *slot;
414
415 p = cf->cycle->paths.elts;
416 for (i = 0; i < cf->cycle->paths.nelts; i++) {
417 if (p[i]->name.len == path->name.len
418 && ngx_strcmp(p[i]->name.data, path->name.data)strcmp((const char *) p[i]->name.data, (const char *) path
->name.data)
== 0)
419 {
420 for (n = 0; n < 3; n++) {
421 if (p[i]->level[n] != path->level[n]) {
422 if (path->conf_file == NULL((void*)0)) {
423 if (p[i]->conf_file == NULL((void*)0)) {
424 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
425 "the default path name \"%V\" has "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
426 "the same name as another default path, "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
427 "but the different levels, you need to "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
428 "redefine one of them in http section",if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
429 &p[i]->name)if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the default path name \"%V\" has " "the same name as another default path, "
"but the different levels, you need to " "redefine one of them in http section"
, &p[i]->name)
;
430 return NGX_ERROR-1;
431 }
432
433 ngx_log_error(NGX_LOG_EMERG, cf->log, 0,if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
434 "the path name \"%V\" in %s:%ui has "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
435 "the same name as default path, but "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
436 "the different levels, you need to "if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
437 "define default path in http section",if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
438 &p[i]->name, p[i]->conf_file, p[i]->line)if ((cf->log)->log_level >= 1) ngx_log_error_core(1,
cf->log, 0, "the path name \"%V\" in %s:%ui has " "the same name as default path, but "
"the different levels, you need to " "define default path in http section"
, &p[i]->name, p[i]->conf_file, p[i]->line)
;
439 return NGX_ERROR-1;
440 }
441
442 ngx_conf_log_error(NGX_LOG_EMERG1, cf, 0,
443 "the same path name \"%V\" in %s:%ui "
444 "has the different levels than",
445 &p[i]->name, p[i]->conf_file, p[i]->line);
446 return NGX_ERROR-1;
447 }
448
449 if (p[i]->level[n] == 0) {
450 break;
451 }
452 }
453
454 *slot = p[i];
455
456 return NGX_OK0;
457 }
458 }
459
460 p = ngx_array_push(&cf->cycle->paths);
461 if (p == NULL((void*)0)) {
462 return NGX_ERROR-1;
463 }
464
465 *p = path;
466
467 return NGX_OK0;
468}
469
470
471ngx_int_t
472ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user)
473{
474 ngx_err_t err;
475 ngx_uint_t i;
476 ngx_path_t **path;
477
478 path = cycle->paths.elts;
479 for (i = 0; i < cycle->paths.nelts; i++) {
480
481 if (ngx_create_dir(path[i]->name.data, 0700)mkdir((const char *) path[i]->name.data, 0700) == NGX_FILE_ERROR-1) {
482 err = ngx_errno(*__error());
483 if (err != NGX_EEXIST17) {
484 ngx_log_error(NGX_LOG_EMERG, cycle->log, err,if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, err, "mkdir()" " \"%s\" failed", path[i]->
name.data)
485 ngx_create_dir_n " \"%s\" failed",if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, err, "mkdir()" " \"%s\" failed", path[i]->
name.data)
486 path[i]->name.data)if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, err, "mkdir()" " \"%s\" failed", path[i]->
name.data)
;
487 return NGX_ERROR-1;
488 }
489 }
490
491 if (user == (ngx_uid_t) NGX_CONF_UNSET_UINT(ngx_uint_t) -1) {
492 continue;
493 }
494
495#if !(NGX_WIN32)
496 {
497 ngx_file_info_t fi;
498
499 if (ngx_file_info((const char *) path[i]->name.data, &fi)stat((const char *) (const char *) path[i]->name.data, &
fi)
500 == NGX_FILE_ERROR-1)
501 {
502 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "stat()" " \"%s\" failed", path
[i]->name.data)
503 ngx_file_info_n " \"%s\" failed", path[i]->name.data)if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "stat()" " \"%s\" failed", path
[i]->name.data)
;
504 return NGX_ERROR-1;
505 }
506
507 if (fi.st_uid != user) {
508 if (chown((const char *) path[i]->name.data, user, -1) == -1) {
509 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "chown(\"%s\", %d) failed", path
[i]->name.data, user)
510 "chown(\"%s\", %d) failed",if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "chown(\"%s\", %d) failed", path
[i]->name.data, user)
511 path[i]->name.data, user)if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "chown(\"%s\", %d) failed", path
[i]->name.data, user)
;
512 return NGX_ERROR-1;
513 }
514 }
515
516 if ((fi.st_mode & (S_IRUSR0000400|S_IWUSR0000200|S_IXUSR0000100))
517 != (S_IRUSR0000400|S_IWUSR0000200|S_IXUSR0000100))
518 {
519 fi.st_mode |= (S_IRUSR0000400|S_IWUSR0000200|S_IXUSR0000100);
520
521 if (chmod((const char *) path[i]->name.data, fi.st_mode) == -1) {
522 ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "chmod() \"%s\" failed", path
[i]->name.data)
523 "chmod() \"%s\" failed", path[i]->name.data)if ((cycle->log)->log_level >= 1) ngx_log_error_core
(1, cycle->log, (*__error()), "chmod() \"%s\" failed", path
[i]->name.data)
;
524 return NGX_ERROR-1;
525 }
526 }
527 }
528#endif
529 }
530
531 return NGX_OK0;
532}
533
534
535ngx_int_t
536ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
537{
538 u_char *name;
539 ngx_err_t err;
540 ngx_copy_file_t cf;
541
542#if !(NGX_WIN32)
543
544 if (ext->access) {
545 if (ngx_change_file_access(src->data, ext->access)chmod((const char *) src->data, ext->access) == NGX_FILE_ERROR-1) {
546 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "chmod()" " \"%s\" failed", src->
data)
547 ngx_change_file_access_n " \"%s\" failed", src->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "chmod()" " \"%s\" failed", src->
data)
;
548 err = 0;
549 goto failed;
550 }
551 }
552
553#endif
554
555 if (ext->time != -1) {
556 if (ngx_set_file_time(src->data, ext->fd, ext->time) != NGX_OK0) {
557 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "utimes()" " \"%s\" failed", src
->data)
558 ngx_set_file_time_n " \"%s\" failed", src->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "utimes()" " \"%s\" failed", src
->data)
;
559 err = 0;
560 goto failed;
561 }
562 }
563
564 if (ngx_rename_file(src->data, to->data)rename((const char *) src->data, (const char *) to->data
)
!= NGX_FILE_ERROR-1) {
565 return NGX_OK0;
566 }
567
568 err = ngx_errno(*__error());
569
570 if (err == NGX_ENOPATH2) {
571
572 if (!ext->create_path) {
573 goto failed;
574 }
575
576 err = ngx_create_full_path(to->data, ngx_dir_access(ext->path_access)(ext->path_access | (ext->path_access & 0444) >>
2)
);
577
578 if (err) {
579 ngx_log_error(NGX_LOG_CRIT, ext->log, err,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, err, "mkdir()" " \"%s\" failed", to->data)
580 ngx_create_dir_n " \"%s\" failed", to->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, err, "mkdir()" " \"%s\" failed", to->data)
;
581 err = 0;
582 goto failed;
583 }
584
585 if (ngx_rename_file(src->data, to->data)rename((const char *) src->data, (const char *) to->data
)
!= NGX_FILE_ERROR-1) {
586 return NGX_OK0;
587 }
588
589 err = ngx_errno(*__error());
590 }
591
592#if (NGX_WIN32)
593
594 if (err == NGX_EEXIST17) {
595 err = ngx_win32_rename_file(src, to, ext->log);
596
597 if (err == 0) {
598 return NGX_OK0;
599 }
600 }
601
602#endif
603
604 if (err == NGX_EXDEV18) {
605
606 cf.size = -1;
607 cf.buf_size = 0;
608 cf.access = ext->access;
609 cf.time = ext->time;
610 cf.log = ext->log;
611
612 name = ngx_alloc(to->len + 1 + 10 + 1, ext->log);
613 if (name == NULL((void*)0)) {
614 return NGX_ERROR-1;
615 }
616
617 (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len, to->data,
618 (uint32_t) ngx_next_temp_number(0));
619
620 if (ngx_copy_file(src->data, name, &cf) == NGX_OK0) {
621
622 if (ngx_rename_file(name, to->data)rename((const char *) name, (const char *) to->data) != NGX_FILE_ERROR-1) {
623 ngx_freefree(name);
624
625 if (ngx_delete_file(src->data)unlink((const char *) src->data) == NGX_FILE_ERROR-1) {
626 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", src
->data)
627 ngx_delete_file_n " \"%s\" failed",if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", src
->data)
628 src->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", src
->data)
;
629 return NGX_ERROR-1;
630 }
631
632 return NGX_OK0;
633 }
634
635 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "rename()" " \"%s\" to \"%s\" failed"
, name, to->data)
636 ngx_rename_file_n " \"%s\" to \"%s\" failed",if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "rename()" " \"%s\" to \"%s\" failed"
, name, to->data)
637 name, to->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "rename()" " \"%s\" to \"%s\" failed"
, name, to->data)
;
638
639 if (ngx_delete_file(name)unlink((const char *) name) == NGX_FILE_ERROR-1) {
640 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", name
)
641 ngx_delete_file_n " \"%s\" failed", name)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", name
)
;
642
643 }
644 }
645
646 ngx_freefree(name);
647
648 err = 0;
649 }
650
651failed:
652
653 if (ext->delete_file) {
654 if (ngx_delete_file(src->data)unlink((const char *) src->data) == NGX_FILE_ERROR-1) {
655 ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", src
->data)
656 ngx_delete_file_n " \"%s\" failed", src->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, (*__error()), "unlink()" " \"%s\" failed", src
->data)
;
657 }
658 }
659
660 if (err) {
661 ngx_log_error(NGX_LOG_CRIT, ext->log, err,if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, err, "rename()" " \"%s\" to \"%s\" failed", src
->data, to->data)
662 ngx_rename_file_n " \"%s\" to \"%s\" failed",if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, err, "rename()" " \"%s\" to \"%s\" failed", src
->data, to->data)
663 src->data, to->data)if ((ext->log)->log_level >= 3) ngx_log_error_core(3
, ext->log, err, "rename()" " \"%s\" to \"%s\" failed", src
->data, to->data)
;
664 }
665
666 return NGX_ERROR-1;
667}
668
669
670ngx_int_t
671ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
672{
673 char *buf;
674 off_t size;
675 size_t len;
676 ssize_t n;
677 ngx_fd_t fd, nfd;
678 ngx_int_t rc;
679 ngx_file_info_t fi;
680
681 rc = NGX_ERROR-1;
682 buf = NULL((void*)0);
683 nfd = NGX_INVALID_FILE-1;
684
685 fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0)open((const char *) from, 0x0000|0, 0);
686
687 if (fd == NGX_INVALID_FILE-1) {
688 ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,if ((cf->log)->log_level >= 3) ngx_log_error_core(3,
cf->log, (*__error()), "open()" " \"%s\" failed", from)
689 ngx_open_file_n " \"%s\" failed", from)if ((cf->log)->log_level >= 3) ngx_log_error_core(3,
cf->log, (*__error()), "open()" " \"%s\" failed", from)
;
690 goto failed;
691 }
692
693 if (cf->size != -1) {
694 size = cf->size;
695
696 } else {
697 if (ngx_fd_info(fd, &fi)fstat(fd, &fi) == NGX_FILE_ERROR-1) {
698 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "fstat()" " \"%s\" failed", from)
699 ngx_fd_info_n " \"%s\" failed", from)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "fstat()" " \"%s\" failed", from)
;
700
701 goto failed;
702 }
703
704 size = ngx_file_size(&fi)(&fi)->st_size;
705 }
706
707 len = cf->buf_size ? cf->buf_size : 65536;
708
709 if ((off_t) len > size) {
710 len = (size_t) size;
711 }
712
713 buf = ngx_alloc(len, cf->log);
714 if (buf == NULL((void*)0)) {
715 goto failed;
716 }
717
718 nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,open((const char *) to, 0x0001|0x0200, cf->access)
719 cf->access)open((const char *) to, 0x0001|0x0200, cf->access);
720
721 if (nfd == NGX_INVALID_FILE-1) {
722 ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,if ((cf->log)->log_level >= 3) ngx_log_error_core(3,
cf->log, (*__error()), "open()" " \"%s\" failed", to)
723 ngx_open_file_n " \"%s\" failed", to)if ((cf->log)->log_level >= 3) ngx_log_error_core(3,
cf->log, (*__error()), "open()" " \"%s\" failed", to)
;
724 goto failed;
725 }
726
727 while (size > 0) {
728
729 if ((off_t) len > size) {
730 len = (size_t) size;
731 }
732
733 n = ngx_read_fdread(fd, buf, len);
734
735 if (n == -1) {
736 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "read()" " \"%s\" failed", from)
737 ngx_read_fd_n " \"%s\" failed", from)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "read()" " \"%s\" failed", from)
;
738 goto failed;
739 }
740
741 if ((size_t) n != len) {
742 ngx_log_error(NGX_LOG_ALERT, cf->log, 0,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "read()" " has read only %z of %uz from %s", n
, size, from)
743 ngx_read_fd_n " has read only %z of %uz from %s",if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "read()" " has read only %z of %uz from %s", n
, size, from)
744 n, size, from)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "read()" " has read only %z of %uz from %s", n
, size, from)
;
745 goto failed;
746 }
747
748 n = ngx_write_fd(nfd, buf, len);
749
750 if (n == -1) {
751 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "write()" " \"%s\" failed", to)
752 ngx_write_fd_n " \"%s\" failed", to)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "write()" " \"%s\" failed", to)
;
753 goto failed;
754 }
755
756 if ((size_t) n != len) {
757 ngx_log_error(NGX_LOG_ALERT, cf->log, 0,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "write()" " has written only %z of %uz to %s"
, n, size, to)
758 ngx_write_fd_n " has written only %z of %uz to %s",if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "write()" " has written only %z of %uz to %s"
, n, size, to)
759 n, size, to)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, 0, "write()" " has written only %z of %uz to %s"
, n, size, to)
;
760 goto failed;
761 }
762
763 size -= n;
764 }
765
766 if (cf->time != -1) {
767 if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK0) {
768 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "utimes()" " \"%s\" failed", to)
769 ngx_set_file_time_n " \"%s\" failed", to)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "utimes()" " \"%s\" failed", to)
;
770 goto failed;
771 }
772 }
773
774 rc = NGX_OK0;
775
776failed:
777
778 if (nfd != NGX_INVALID_FILE-1) {
779 if (ngx_close_fileclose(nfd) == NGX_FILE_ERROR-1) {
780 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "close()" " \"%s\" failed", to)
781 ngx_close_file_n " \"%s\" failed", to)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "close()" " \"%s\" failed", to)
;
782 }
783 }
784
785 if (fd != NGX_INVALID_FILE-1) {
786 if (ngx_close_fileclose(fd) == NGX_FILE_ERROR-1) {
787 ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "close()" " \"%s\" failed", from)
788 ngx_close_file_n " \"%s\" failed", from)if ((cf->log)->log_level >= 2) ngx_log_error_core(2,
cf->log, (*__error()), "close()" " \"%s\" failed", from)
;
789 }
790 }
791
792 if (buf) {
793 ngx_freefree(buf);
794 }
795
796 return rc;
797}
798
799
800/*
801 * ctx->init_handler() - see ctx->alloc
802 * ctx->file_handler() - file handler
803 * ctx->pre_tree_handler() - handler is called before entering directory
804 * ctx->post_tree_handler() - handler is called after leaving directory
805 * ctx->spec_handler() - special (socket, FIFO, etc.) file handler
806 *
807 * ctx->data - some data structure, it may be the same on all levels, or
808 * reallocated if ctx->alloc is nonzero
809 *
810 * ctx->alloc - a size of data structure that is allocated at every level
811 * and is initialized by ctx->init_handler()
812 *
813 * ctx->log - a log
814 *
815 * on fatal (memory) error handler must return NGX_ABORT to stop walking tree
816 */
817
818ngx_int_t
819ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree)
820{
821 void *data, *prev;
822 u_char *p, *name;
823 size_t len;
824 ngx_int_t rc;
825 ngx_err_t err;
826 ngx_str_t file, buf;
827 ngx_dir_t dir;
828
829 ngx_str_null(&buf)(&buf)->len = 0; (&buf)->data = ((void*)0);
1
Within the expansion of the macro 'ngx_str_null':
a
Null pointer value stored to 'buf.data'
830
831 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
832 "walk tree \"%V\"", tree);
833
834 if (ngx_open_dir(tree, &dir) == NGX_ERROR-1) {
2
Taking false branch
835 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "opendir()" " \"%s\" failed", tree
->data)
836 ngx_open_dir_n " \"%s\" failed", tree->data)if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "opendir()" " \"%s\" failed", tree
->data)
;
837 return NGX_ERROR-1;
838 }
839
840 prev = ctx->data;
841
842 if (ctx->alloc) {
3
Taking false branch
843 data = ngx_alloc(ctx->alloc, ctx->log);
844 if (data == NULL((void*)0)) {
845 goto failed;
846 }
847
848 if (ctx->init_handler(data, prev) == NGX_ABORT-6) {
849 goto failed;
850 }
851
852 ctx->data = data;
853
854 } else {
855 data = NULL((void*)0);
856 }
857
858 for ( ;; ) {
4
Loop condition is true. Entering loop body
859
860 ngx_set_errno(0)(*__error()) = 0;
861
862 if (ngx_read_dir(&dir) == NGX_ERROR-1) {
5
Taking false branch
863 err = ngx_errno(*__error());
864
865 if (err == NGX_ENOMOREFILES0) {
866 rc = NGX_OK0;
867
868 } else {
869 ngx_log_error(NGX_LOG_CRIT, ctx->log, err,if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, err, "readdir()" " \"%s\" failed", tree->data
)
870 ngx_read_dir_n " \"%s\" failed", tree->data)if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, err, "readdir()" " \"%s\" failed", tree->data
)
;
871 rc = NGX_ERROR-1;
872 }
873
874 goto done;
875 }
876
877 len = ngx_de_namelen(&dir)(&dir)->de->d_namlen;
878 name = ngx_de_name(&dir)((u_char *) (&dir)->de->d_name);
879
880 ngx_log_debug2(NGX_LOG_DEBUG_CORE, ctx->log, 0,
881 "tree name %uz:\"%s\"", len, name);
882
883 if (len == 1 && name[0] == '.') {
6
Assuming 'len' is not equal to 1
884 continue;
885 }
886
887 if (len == 2 && name[0] == '.' && name[1] == '.') {
7
Assuming 'len' is not equal to 2
888 continue;
889 }
890
891 file.len = tree->len + 1 + len;
892
893 if (file.len + NGX_DIR_MASK_LEN0 > buf.len) {
8
Taking false branch
894
895 if (buf.len) {
896 ngx_freefree(buf.data);
897 }
898
899 buf.len = tree->len + 1 + len + NGX_DIR_MASK_LEN0;
900
901 buf.data = ngx_alloc(buf.len + 1, ctx->log);
902 if (buf.data == NULL((void*)0)) {
903 goto failed;
904 }
905 }
906
907 p = ngx_cpymem(buf.data, tree->data, tree->len)(((u_char *) ((__builtin_object_size (buf.data, 0) != (size_t
) -1) ? __builtin___memcpy_chk (buf.data, tree->data, tree
->len, __builtin_object_size (buf.data, 0)) : __inline_memcpy_chk
(buf.data, tree->data, tree->len))) + (tree->len))
;
9
Within the expansion of the macro 'ngx_cpymem':
a
Null pointer argument in call to memory copy function
908 *p++ = '/';
909 ngx_memcpy(p, name, len + 1)(void) ((__builtin_object_size (p, 0) != (size_t) -1) ? __builtin___memcpy_chk
(p, name, len + 1, __builtin_object_size (p, 0)) : __inline_memcpy_chk
(p, name, len + 1))
;
910
911 file.data = buf.data;
912
913 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
914 "tree path \"%s\"", file.data);
915
916 if (!dir.valid_info) {
917 if (ngx_de_info(file.data, &dir) == NGX_FILE_ERROR-1) {
918 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "stat()" " \"%s\" failed", file.
data)
919 ngx_de_info_n " \"%s\" failed", file.data)if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "stat()" " \"%s\" failed", file.
data)
;
920 continue;
921 }
922 }
923
924 if (ngx_de_is_file(&dir)(((&dir)->type) ? ((&dir)->type == 8) : (((((&
dir)->info.st_mode) & 0170000) == 0100000)))
) {
925
926 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
927 "tree file \"%s\"", file.data);
928
929 ctx->size = ngx_de_size(&dir)(&dir)->info.st_size;
930 ctx->fs_size = ngx_de_fs_size(&dir)(((&dir)->info.st_size < (&dir)->info.st_blocks
* 512) ? ((&dir)->info.st_blocks * 512) : ((&dir)
->info.st_size))
;
931 ctx->access = ngx_de_access(&dir)(((&dir)->info.st_mode) & 0777);
932 ctx->mtime = ngx_de_mtime(&dir)(&dir)->info.st_mtimespec.tv_sec;
933
934 if (ctx->file_handler(ctx, &file) == NGX_ABORT-6) {
935 goto failed;
936 }
937
938 } else if (ngx_de_is_dir(&dir)(((&dir)->type) ? ((&dir)->type == 4) : (((((&
dir)->info.st_mode) & 0170000) == 0040000)))
) {
939
940 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
941 "tree enter dir \"%s\"", file.data);
942
943 ctx->access = ngx_de_access(&dir)(((&dir)->info.st_mode) & 0777);
944 ctx->mtime = ngx_de_mtime(&dir)(&dir)->info.st_mtimespec.tv_sec;
945
946 if (ctx->pre_tree_handler(ctx, &file) == NGX_ABORT-6) {
947 goto failed;
948 }
949
950 if (ngx_walk_tree(ctx, &file) == NGX_ABORT-6) {
951 goto failed;
952 }
953
954 ctx->access = ngx_de_access(&dir)(((&dir)->info.st_mode) & 0777);
955 ctx->mtime = ngx_de_mtime(&dir)(&dir)->info.st_mtimespec.tv_sec;
956
957 if (ctx->post_tree_handler(ctx, &file) == NGX_ABORT-6) {
958 goto failed;
959 }
960
961 } else {
962
963 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ctx->log, 0,
964 "tree special \"%s\"", file.data);
965
966 if (ctx->spec_handler(ctx, &file) == NGX_ABORT-6) {
967 goto failed;
968 }
969 }
970 }
971
972failed:
973
974 rc = NGX_ABORT-6;
975
976done:
977
978 if (buf.len) {
979 ngx_freefree(buf.data);
980 }
981
982 if (data) {
983 ngx_freefree(data);
984 ctx->data = prev;
985 }
986
987 if (ngx_close_dir(&dir)closedir((&dir)->dir) == NGX_ERROR-1) {
988 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno,if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "closedir()" " \"%s\" failed", tree
->data)
989 ngx_close_dir_n " \"%s\" failed", tree->data)if ((ctx->log)->log_level >= 3) ngx_log_error_core(3
, ctx->log, (*__error()), "closedir()" " \"%s\" failed", tree
->data)
;
990 }
991
992 return rc;
993}