version 1.1.1.2, 2013/10/14 07:51:14
|
version 1.1.1.3, 2016/11/01 09:54:32
|
Line 4
|
Line 4
|
* Copyright (C) 1996-2000 Andrew Tridgell |
* Copyright (C) 1996-2000 Andrew Tridgell |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2003-2013 Wayne Davison | * Copyright (C) 2003-2015 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* it under the terms of the GNU General Public License as published by |
Line 25
|
Line 25
|
#include "itypes.h" |
#include "itypes.h" |
#include "inums.h" |
#include "inums.h" |
|
|
|
extern int dry_run; |
extern int module_id; |
extern int module_id; |
extern int protect_args; |
extern int protect_args; |
extern int modify_window; |
extern int modify_window; |
Line 189 int make_path(char *fname, int flags)
|
Line 190 int make_path(char *fname, int flags)
|
|
|
if (flags & MKP_DROP_NAME) { |
if (flags & MKP_DROP_NAME) { |
end = strrchr(fname, '/'); |
end = strrchr(fname, '/'); |
if (!end) | if (!end || end == fname) |
return 0; |
return 0; |
*end = '\0'; |
*end = '\0'; |
} else |
} else |
Line 197 int make_path(char *fname, int flags)
|
Line 198 int make_path(char *fname, int flags)
|
|
|
/* Try to find an existing dir, starting from the deepest dir. */ |
/* Try to find an existing dir, starting from the deepest dir. */ |
for (p = end; ; ) { |
for (p = end; ; ) { |
if (do_mkdir(fname, ACCESSPERMS) == 0) { | if (dry_run) { |
| STRUCT_STAT st; |
| if (do_stat(fname, &st) == 0) { |
| if (S_ISDIR(st.st_mode)) |
| errno = EEXIST; |
| else |
| errno = ENOTDIR; |
| } |
| } else if (do_mkdir(fname, ACCESSPERMS) == 0) { |
ret++; |
ret++; |
break; |
break; |
} |
} |
|
|
if (errno != ENOENT) { |
if (errno != ENOENT) { |
if (errno != EEXIST) | STRUCT_STAT st; |
| if (errno != EEXIST || (do_stat(fname, &st) == 0 && !S_ISDIR(st.st_mode))) |
ret = -ret - 1; |
ret = -ret - 1; |
break; |
break; |
} |
} |
while (1) { |
while (1) { |
if (p == fname) { |
if (p == fname) { |
ret = -ret - 1; | /* We got a relative path that doesn't exist, so assume that '.' |
| * is there and just break out and create the whole thing. */ |
| p = NULL; |
goto double_break; |
goto double_break; |
} |
} |
if (*--p == '/') { |
if (*--p == '/') { |
if (p == fname) { |
if (p == fname) { |
ret = -ret - 1; /* impossible... */ | /* We reached the "/" dir, which we assume is there. */ |
goto double_break; |
goto double_break; |
} |
} |
*p = '\0'; |
*p = '\0'; |
Line 225 int make_path(char *fname, int flags)
|
Line 238 int make_path(char *fname, int flags)
|
|
|
/* Make all the dirs that we didn't find on the way here. */ |
/* Make all the dirs that we didn't find on the way here. */ |
while (p != end) { |
while (p != end) { |
*p = '/'; | if (p) |
| *p = '/'; |
| else |
| p = fname; |
p += strlen(p); |
p += strlen(p); |
if (ret < 0) /* Skip mkdir on error, but keep restoring the path. */ |
if (ret < 0) /* Skip mkdir on error, but keep restoring the path. */ |
continue; |
continue; |
Line 858 int count_dir_elements(const char *p)
|
Line 874 int count_dir_elements(const char *p)
|
* CFN_KEEP_TRAILING_SLASH is flagged, and will also collapse ".." elements |
* CFN_KEEP_TRAILING_SLASH is flagged, and will also collapse ".." elements |
* (except at the start) if CFN_COLLAPSE_DOT_DOT_DIRS is flagged. If the |
* (except at the start) if CFN_COLLAPSE_DOT_DOT_DIRS is flagged. If the |
* resulting name would be empty, returns ".". */ |
* resulting name would be empty, returns ".". */ |
unsigned int clean_fname(char *name, int flags) | int clean_fname(char *name, int flags) |
{ |
{ |
char *limit = name - 1, *t = name, *f = name; |
char *limit = name - 1, *t = name, *f = name; |
int anchored; |
int anchored; |
Line 866 unsigned int clean_fname(char *name, int flags)
|
Line 882 unsigned int clean_fname(char *name, int flags)
|
if (!name) |
if (!name) |
return 0; |
return 0; |
|
|
|
#define DOT_IS_DOT_DOT_DIR(bp) (bp[1] == '.' && (bp[2] == '/' || !bp[2])) |
|
|
if ((anchored = *f == '/') != 0) { |
if ((anchored = *f == '/') != 0) { |
*t++ = *f++; |
*t++ = *f++; |
#ifdef __CYGWIN__ |
#ifdef __CYGWIN__ |
Line 878 unsigned int clean_fname(char *name, int flags)
|
Line 896 unsigned int clean_fname(char *name, int flags)
|
} else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') { |
} else if (flags & CFN_KEEP_DOT_DIRS && *f == '.' && f[1] == '/') { |
*t++ = *f++; |
*t++ = *f++; |
*t++ = *f++; |
*t++ = *f++; |
} | } else if (flags & CFN_REFUSE_DOT_DOT_DIRS && *f == '.' && DOT_IS_DOT_DOT_DIR(f)) |
| return -1; |
while (*f) { |
while (*f) { |
/* discard extra slashes */ |
/* discard extra slashes */ |
if (*f == '/') { |
if (*f == '/') { |
Line 894 unsigned int clean_fname(char *name, int flags)
|
Line 913 unsigned int clean_fname(char *name, int flags)
|
if (f[1] == '\0' && flags & CFN_DROP_TRAILING_DOT_DIR) |
if (f[1] == '\0' && flags & CFN_DROP_TRAILING_DOT_DIR) |
break; |
break; |
/* collapse ".." dirs */ |
/* collapse ".." dirs */ |
if (flags & CFN_COLLAPSE_DOT_DOT_DIRS | if (flags & (CFN_COLLAPSE_DOT_DOT_DIRS|CFN_REFUSE_DOT_DOT_DIRS) && DOT_IS_DOT_DOT_DIR(f)) { |
&& f[1] == '.' && (f[2] == '/' || !f[2])) { | |
char *s = t - 1; |
char *s = t - 1; |
|
if (flags & CFN_REFUSE_DOT_DOT_DIRS) |
|
return -1; |
if (s == name && anchored) { |
if (s == name && anchored) { |
f += 2; |
f += 2; |
continue; |
continue; |
Line 919 unsigned int clean_fname(char *name, int flags)
|
Line 939 unsigned int clean_fname(char *name, int flags)
|
*t++ = '.'; |
*t++ = '.'; |
*t = '\0'; |
*t = '\0'; |
|
|
|
#undef DOT_IS_DOT_DOT_DIR |
|
|
return t - name; |
return t - name; |
} |
} |
|
|
Line 1305 char *timestring(time_t t)
|
Line 1327 char *timestring(time_t t)
|
int cmp_time(time_t file1, time_t file2) |
int cmp_time(time_t file1, time_t file2) |
{ |
{ |
if (file2 > file1) { |
if (file2 > file1) { |
if (file2 - file1 <= modify_window) | /* The final comparison makes sure that modify_window doesn't overflow a |
return 0; | * time_t, which would mean that file2 must be in the equality window. */ |
return -1; | if (!modify_window || (file2 > file1 + modify_window && file1 + modify_window > file1)) |
| return -1; |
| } else if (file1 > file2) { |
| if (!modify_window || (file1 > file2 + modify_window && file2 + modify_window > file2)) |
| return 1; |
} |
} |
if (file1 - file2 <= modify_window) | return 0; |
return 0; | |
return 1; | |
} |
} |
|
|
|
|
#ifdef __INSURE__XX |
#ifdef __INSURE__XX |
#include <dlfcn.h> |
#include <dlfcn.h> |
|
|
Line 1582 int flist_ndx_pop(flist_ndx_list *lp)
|
Line 1605 int flist_ndx_pop(flist_ndx_list *lp)
|
return ndx; |
return ndx; |
} |
} |
|
|
|
/* Make sure there is room for one more item in the item list. If there |
|
* is not, expand the list as indicated by the value of "incr": |
|
* - if incr < 0 then increase the malloced size by -1 * incr |
|
* - if incr >= 0 then either make the malloced size equal to "incr" |
|
* or (if that's not large enough) double the malloced size |
|
* After the size check, the list's count is incremented by 1 and a pointer |
|
* to the "new" list item is returned. |
|
*/ |
void *expand_item_list(item_list *lp, size_t item_size, |
void *expand_item_list(item_list *lp, size_t item_size, |
const char *desc, int incr) |
const char *desc, int incr) |
{ |
{ |
Line 1592 void *expand_item_list(item_list *lp, size_t item_size
|
Line 1623 void *expand_item_list(item_list *lp, size_t item_size
|
if (incr < 0) |
if (incr < 0) |
new_size += -incr; /* increase slowly */ |
new_size += -incr; /* increase slowly */ |
else if (new_size < (size_t)incr) |
else if (new_size < (size_t)incr) |
new_size += incr; | new_size = incr; |
else | else if (new_size) |
new_size *= 2; |
new_size *= 2; |
if (new_size < lp->malloced) | else |
| new_size = 1; |
| if (new_size <= lp->malloced) |
overflow_exit("expand_item_list"); |
overflow_exit("expand_item_list"); |
/* Using _realloc_array() lets us pass the size, not a type. */ |
/* Using _realloc_array() lets us pass the size, not a type. */ |
new_ptr = _realloc_array(lp->items, item_size, new_size); |
new_ptr = _realloc_array(lp->items, item_size, new_size); |