Factorized confirmation code
This commit is contained in:
parent
2ba9d0e69a
commit
1d73c291f1
52
src/cp.c
52
src/cp.c
|
@ -94,17 +94,24 @@ static int _cp_confirm(char const * message)
|
||||||
static int _single_dir(Prefs * prefs, char const * src, char const * dst);
|
static int _single_dir(Prefs * prefs, char const * src, char const * dst);
|
||||||
static int _single_fifo(char const * dst);
|
static int _single_fifo(char const * dst);
|
||||||
static int _single_symlink(char const * src, char const * dst);
|
static int _single_symlink(char const * src, char const * dst);
|
||||||
static int _single_regular(Prefs * prefs, char const * src, char const * dst);
|
static int _single_regular(char const * src, char const * dst);
|
||||||
static int _single_p(char const * dst, struct stat * st);
|
static int _single_p(char const * dst, struct stat * st);
|
||||||
|
|
||||||
static int _cp_single(Prefs * prefs, char const * src, char const * dst)
|
static int _cp_single(Prefs * prefs, char const * src, char const * dst)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
struct stat st2;
|
||||||
|
|
||||||
if(lstat(src, &st) != 0) /* XXX TOCTOU */
|
if(lstat(src, &st) != 0 && errno == ENOENT) /* XXX TOCTOU */
|
||||||
return _cp_error(src, 1);
|
return _cp_error(src, 1);
|
||||||
/* FIXME ask for confirmation here instead? */
|
if(lstat(dst, &st2) == 0)
|
||||||
|
{
|
||||||
|
if(*prefs & PREFS_i && _cp_confirm(dst) != 1)
|
||||||
|
return 0;
|
||||||
|
if(unlink(dst) != 0)
|
||||||
|
return _cp_error(dst, 1);
|
||||||
|
}
|
||||||
if(S_ISDIR(st.st_mode))
|
if(S_ISDIR(st.st_mode))
|
||||||
ret = _single_dir(prefs, src, dst);
|
ret = _single_dir(prefs, src, dst);
|
||||||
else if(S_ISFIFO(st.st_mode))
|
else if(S_ISFIFO(st.st_mode))
|
||||||
|
@ -112,7 +119,7 @@ static int _cp_single(Prefs * prefs, char const * src, char const * dst)
|
||||||
else if(S_ISLNK(st.st_mode) && (*prefs & PREFS_P))
|
else if(S_ISLNK(st.st_mode) && (*prefs & PREFS_P))
|
||||||
return _single_symlink(src, dst);
|
return _single_symlink(src, dst);
|
||||||
else
|
else
|
||||||
ret = _single_regular(prefs, src, dst);
|
ret = _single_regular(src, dst);
|
||||||
if(ret != 0)
|
if(ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
if(*prefs & PREFS_p) /* XXX TOCTOU */
|
if(*prefs & PREFS_p) /* XXX TOCTOU */
|
||||||
|
@ -217,8 +224,7 @@ static int _single_symlink(char const * src, char const * dst)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE * _regular_open_dst(Prefs * prefs, char const * dst);
|
static int _single_regular(char const * src, char const * dst)
|
||||||
static int _single_regular(Prefs * prefs, char const * src, char const * dst)
|
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
FILE * fsrc;
|
FILE * fsrc;
|
||||||
|
@ -228,7 +234,7 @@ static int _single_regular(Prefs * prefs, char const * src, char const * dst)
|
||||||
|
|
||||||
if((fsrc = fopen(src, "r")) == NULL)
|
if((fsrc = fopen(src, "r")) == NULL)
|
||||||
return _cp_error(src, 1);
|
return _cp_error(src, 1);
|
||||||
if((fdst = _regular_open_dst(prefs, dst)) == NULL)
|
if((fdst = fopen(dst, "w")) == NULL)
|
||||||
{
|
{
|
||||||
ret = _cp_error(dst, 1);
|
ret = _cp_error(dst, 1);
|
||||||
fclose(fsrc);
|
fclose(fsrc);
|
||||||
|
@ -251,38 +257,6 @@ static int _single_regular(Prefs * prefs, char const * src, char const * dst)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE * _regular_open_dst(Prefs * prefs, char const * dst)
|
|
||||||
{
|
|
||||||
FILE * fp;
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
if(*prefs & PREFS_f)
|
|
||||||
{
|
|
||||||
if((fp = fopen(dst, "w")) == NULL)
|
|
||||||
_cp_error(dst, 1);
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
if((fd = open(dst, O_WRONLY | O_CREAT | O_EXCL, 0666)) < 0)
|
|
||||||
{
|
|
||||||
if(errno != EEXIST)
|
|
||||||
{
|
|
||||||
_cp_error(dst, 1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if(!_cp_confirm(dst))
|
|
||||||
return NULL;
|
|
||||||
/* XXX TOCTOU */
|
|
||||||
if((fd = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0)
|
|
||||||
{
|
|
||||||
_cp_error(dst, 1);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if((fp = fdopen(fd, "w")) == NULL)
|
|
||||||
_cp_error(dst, 1);
|
|
||||||
return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _single_p(char const * dst, struct stat * st)
|
static int _single_p(char const * dst, struct stat * st)
|
||||||
{
|
{
|
||||||
struct timeval tv[2];
|
struct timeval tv[2];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user