simplified file copying
This commit is contained in:
parent
11f364a6d0
commit
206065f904
@ -172,6 +172,7 @@
|
||||
fmt-intmax.c
|
||||
fmt-out.c
|
||||
fs.c
|
||||
fs-attr.c
|
||||
fs-copy.c
|
||||
fs-delete.c
|
||||
fs-err.c
|
||||
|
@ -111,7 +111,7 @@ struct qse_fs_ent_t
|
||||
qse_ntime_t create;
|
||||
qse_ntime_t access;
|
||||
qse_ntime_t modify;
|
||||
qse_ntime_t change; /* inode status change */
|
||||
qse_ntime_t change; /* inode status change */
|
||||
} time;
|
||||
};
|
||||
|
||||
@ -124,11 +124,15 @@ struct qse_fs_attr_t
|
||||
unsigned int isreg: 1;
|
||||
unsigned int isblk: 1;
|
||||
unsigned int ischr: 1;
|
||||
|
||||
qse_uintptr_t mode;
|
||||
|
||||
qse_uintmax_t size;
|
||||
qse_uintmax_t ino;
|
||||
qse_uintmax_t dev;
|
||||
qse_uintptr_t uid;
|
||||
qse_uintptr_t gid;
|
||||
|
||||
qse_ntime_t atime; /* last access */
|
||||
qse_ntime_t mtime; /* last modification */
|
||||
qse_ntime_t ctime; /* last status change */
|
||||
@ -314,6 +318,24 @@ QSE_EXPORT int qse_fs_pop (
|
||||
const qse_char_t* name
|
||||
);
|
||||
|
||||
QSE_EXPORT int qse_fs_getattrmbs (
|
||||
qse_fs_t* fs,
|
||||
const qse_mchar_t* path,
|
||||
qse_fs_attr_t* attr
|
||||
);
|
||||
|
||||
QSE_EXPORT int qse_fs_getattrwcs (
|
||||
qse_fs_t* fs,
|
||||
const qse_wchar_t* path,
|
||||
qse_fs_attr_t* attr
|
||||
);
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
# define qse_fs_getattr(fs,path,attr) qse_fs_getattrmbs(fs,path,attr)
|
||||
#else
|
||||
# define qse_fs_getattr(fs,path,attr) qse_fs_getattrwcs(fs,path,attr)
|
||||
#endif
|
||||
|
||||
QSE_EXPORT int qse_fs_move (
|
||||
qse_fs_t* fs,
|
||||
const qse_char_t* oldpath,
|
||||
|
@ -46,6 +46,7 @@ libqsecmn_la_SOURCES = \
|
||||
fmt-intmax.c \
|
||||
fmt-out.c \
|
||||
fs.c \
|
||||
fs-attr.c \
|
||||
fs-copy.c \
|
||||
fs-delete.c \
|
||||
fs-err.c \
|
||||
|
@ -107,38 +107,40 @@ libqsecmn_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
|
||||
$(am__DEPENDENCIES_1)
|
||||
am__libqsecmn_la_SOURCES_DIST = alg-base64.c alg-rand.c alg-search.c \
|
||||
alg-sort.c assert.c chr.c dir.c dll.c env.c gdl.c htb.c fio.c \
|
||||
fma.c fmt-intmax.c fmt-out.c fs.c fs-copy.c fs-delete.c \
|
||||
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
|
||||
mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \
|
||||
nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c \
|
||||
path-core.c path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c \
|
||||
sll.c slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
|
||||
str-cpy.c str-del.c str-dup.c str-dyn.c str-end.c str-excl.c \
|
||||
str-fcpy.c str-fmt.c str-fnmat.c str-incl.c str-join.c \
|
||||
str-len.c str-pac.c str-pbrk.c str-put.c str-rev.c str-rot.c \
|
||||
str-set.c str-spl.c str-spn.c str-str.c str-subst.c str-tok.c \
|
||||
str-trm.c str-word.c task.c time.c tio.c tmr.c tre.c tre-ast.c \
|
||||
tre-compile.c tre-match-bt.c tre-match-pa.c tre-parse.c \
|
||||
tre-stack.c uri.c utf8.c xma.c uni.c cp949.c cp950.c
|
||||
fma.c fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c \
|
||||
fs-delete.c fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c \
|
||||
lda.c main.c mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c \
|
||||
nwad-skad.c nwif.c nwif-cfg.c nwio.c oht.c opt.c path-base.c \
|
||||
path-canon.c path-core.c path-merge.c pio.c pma.c rbt.c rex.c \
|
||||
sck.c sio.c sll.c slmb.c str-beg.c str-cat.c str-chr.c \
|
||||
str-cnv.c str-cmp.c str-cpy.c str-del.c str-dup.c str-dyn.c \
|
||||
str-end.c str-excl.c str-fcpy.c str-fmt.c str-fnmat.c \
|
||||
str-incl.c str-join.c str-len.c str-pac.c str-pbrk.c str-put.c \
|
||||
str-rev.c str-rot.c str-set.c str-spl.c str-spn.c str-str.c \
|
||||
str-subst.c str-tok.c str-trm.c str-word.c task.c time.c tio.c \
|
||||
tmr.c tre.c tre-ast.c tre-compile.c tre-match-bt.c \
|
||||
tre-match-pa.c tre-parse.c tre-stack.c uri.c utf8.c xma.c \
|
||||
uni.c cp949.c cp950.c
|
||||
@ENABLE_BUNDLED_UNICODE_TRUE@am__objects_1 = uni.lo
|
||||
@ENABLE_XCMGRS_TRUE@am__objects_2 = cp949.lo cp950.lo
|
||||
am_libqsecmn_la_OBJECTS = alg-base64.lo alg-rand.lo alg-search.lo \
|
||||
alg-sort.lo assert.lo chr.lo dir.lo dll.lo env.lo gdl.lo \
|
||||
htb.lo fio.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-copy.lo \
|
||||
fs-delete.lo fs-err.lo fs-make.lo fs-move.lo glob.lo hton.lo \
|
||||
ipad.lo lda.lo main.lo mb8.lo mbwc.lo mbwc-str.lo mem.lo \
|
||||
mux.lo nwad.lo nwad-skad.lo nwif.lo nwif-cfg.lo nwio.lo oht.lo \
|
||||
opt.lo path-base.lo path-canon.lo path-core.lo path-merge.lo \
|
||||
pio.lo pma.lo rbt.lo rex.lo sck.lo sio.lo sll.lo slmb.lo \
|
||||
str-beg.lo str-cat.lo str-chr.lo str-cnv.lo str-cmp.lo \
|
||||
str-cpy.lo str-del.lo str-dup.lo str-dyn.lo str-end.lo \
|
||||
str-excl.lo str-fcpy.lo str-fmt.lo str-fnmat.lo str-incl.lo \
|
||||
str-join.lo str-len.lo str-pac.lo str-pbrk.lo str-put.lo \
|
||||
str-rev.lo str-rot.lo str-set.lo str-spl.lo str-spn.lo \
|
||||
str-str.lo str-subst.lo str-tok.lo str-trm.lo str-word.lo \
|
||||
task.lo time.lo tio.lo tmr.lo tre.lo tre-ast.lo tre-compile.lo \
|
||||
tre-match-bt.lo tre-match-pa.lo tre-parse.lo tre-stack.lo \
|
||||
uri.lo utf8.lo xma.lo $(am__objects_1) $(am__objects_2)
|
||||
htb.lo fio.lo fma.lo fmt-intmax.lo fmt-out.lo fs.lo fs-attr.lo \
|
||||
fs-copy.lo fs-delete.lo fs-err.lo fs-make.lo fs-move.lo \
|
||||
glob.lo hton.lo ipad.lo lda.lo main.lo mb8.lo mbwc.lo \
|
||||
mbwc-str.lo mem.lo mux.lo nwad.lo nwad-skad.lo nwif.lo \
|
||||
nwif-cfg.lo nwio.lo oht.lo opt.lo path-base.lo path-canon.lo \
|
||||
path-core.lo path-merge.lo pio.lo pma.lo rbt.lo rex.lo sck.lo \
|
||||
sio.lo sll.lo slmb.lo str-beg.lo str-cat.lo str-chr.lo \
|
||||
str-cnv.lo str-cmp.lo str-cpy.lo str-del.lo str-dup.lo \
|
||||
str-dyn.lo str-end.lo str-excl.lo str-fcpy.lo str-fmt.lo \
|
||||
str-fnmat.lo str-incl.lo str-join.lo str-len.lo str-pac.lo \
|
||||
str-pbrk.lo str-put.lo str-rev.lo str-rot.lo str-set.lo \
|
||||
str-spl.lo str-spn.lo str-str.lo str-subst.lo str-tok.lo \
|
||||
str-trm.lo str-word.lo task.lo time.lo tio.lo tmr.lo tre.lo \
|
||||
tre-ast.lo tre-compile.lo tre-match-bt.lo tre-match-pa.lo \
|
||||
tre-parse.lo tre-stack.lo uri.lo utf8.lo xma.lo \
|
||||
$(am__objects_1) $(am__objects_2)
|
||||
libqsecmn_la_OBJECTS = $(am_libqsecmn_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -415,9 +417,9 @@ noinst_HEADERS = \
|
||||
|
||||
libqsecmn_la_SOURCES = alg-base64.c alg-rand.c alg-search.c alg-sort.c \
|
||||
assert.c chr.c dir.c dll.c env.c gdl.c htb.c fio.c fma.c \
|
||||
fmt-intmax.c fmt-out.c fs.c fs-copy.c fs-delete.c fs-err.c \
|
||||
fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c mb8.c \
|
||||
mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \
|
||||
fmt-intmax.c fmt-out.c fs.c fs-attr.c fs-copy.c fs-delete.c \
|
||||
fs-err.c fs-make.c fs-move.c glob.c hton.c ipad.c lda.c main.c \
|
||||
mb8.c mbwc.c mbwc-str.c mem.c mux.c nwad.c nwad-skad.c nwif.c \
|
||||
nwif-cfg.c nwio.c oht.c opt.c path-base.c path-canon.c \
|
||||
path-core.c path-merge.c pio.c pma.c rbt.c rex.c sck.c sio.c \
|
||||
sll.c slmb.c str-beg.c str-cat.c str-chr.c str-cnv.c str-cmp.c \
|
||||
@ -529,6 +531,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fma.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-intmax.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt-out.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-attr.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-copy.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-delete.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fs-err.Plo@am__quote@
|
||||
|
135
qse/lib/cmn/fs-attr.c
Normal file
135
qse/lib/cmn/fs-attr.c
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "fs.h"
|
||||
#include "mem.h"
|
||||
|
||||
int qse_fs_sysgetattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
/* TODO */
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#else
|
||||
#if defined(HAVE_LSTAT)
|
||||
qse_lstat_t st;
|
||||
#else
|
||||
qse_stat_t st;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LSTAT)
|
||||
if (QSE_LSTAT (fspath, &st) == -1)
|
||||
{
|
||||
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
/* is this ok to use stat? */
|
||||
if (QSE_STAT (fspath, &st) == -1)
|
||||
{
|
||||
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
|
||||
|
||||
if (S_ISDIR(st.st_mode)) attr->isdir = 1;
|
||||
if (S_ISLNK(st.st_mode)) attr->islnk = 1;
|
||||
if (S_ISREG(st.st_mode)) attr->isreg = 1;
|
||||
if (S_ISBLK(st.st_mode)) attr->isblk = 1;
|
||||
if (S_ISCHR(st.st_mode)) attr->ischr = 1;
|
||||
|
||||
attr->mode = st.st_mode;
|
||||
attr->size = st.st_size;
|
||||
attr->ino = st.st_ino;
|
||||
attr->dev = st.st_dev;
|
||||
attr->uid = st.st_uid;
|
||||
attr->gid = st.st_gid;
|
||||
|
||||
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||
attr->atime.sec = st.st_atim.tv_sec;
|
||||
attr->atime.nsec = st.st_atim.tv_nsec;
|
||||
attr->mtime.sec = st.st_mtim.tv_sec;
|
||||
attr->mtime.nsec = st.st_mtim.tv_nsec;
|
||||
attr->ctime.sec = st.st_ctim.tv_sec;
|
||||
attr->ctime.nsec = st.st_ctim.tv_nsec;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||
attr->atime.sec = st.st_atimespec.tv_sec;
|
||||
attr->atime.nsec = st.st_atimespec.tv_nsec;
|
||||
attr->mtime.sec = st.st_mtimespec.tv_sec;
|
||||
attr->mtime.nsec = st.st_mtimespec.tv_nsec;
|
||||
attr->ctime.sec = st.st_ctimespec.tv_sec;
|
||||
attr->ctime.nsec = st.st_ctimespec.tv_nsec;
|
||||
#else
|
||||
attr->atime.sec = st.st_atime;
|
||||
attr->mtime.sec = st.st_mtime;
|
||||
attr->ctime.sec = st.st_ctime;
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int qse_fs_getattrmbs (qse_fs_t* fs, const qse_mchar_t* path, qse_fs_attr_t* attr)
|
||||
{
|
||||
qse_fs_char_t* fspath;
|
||||
int ret;
|
||||
|
||||
fspath = qse_fs_makefspathformbs (fs, path);
|
||||
if (!fspath) return -1;
|
||||
|
||||
ret = qse_fs_sysgetattr (fs, fspath, attr);
|
||||
|
||||
qse_fs_freefspathformbs (fs, path, fspath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qse_fs_getattrwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_attr_t* attr)
|
||||
{
|
||||
qse_fs_char_t* fspath;
|
||||
int ret;
|
||||
|
||||
fspath = qse_fs_makefspathforwcs (fs, path);
|
||||
if (!fspath) return -1;
|
||||
|
||||
ret = qse_fs_sysgetattr (fs, fspath, attr);
|
||||
|
||||
qse_fs_freefspathforwcs (fs, path, fspath);
|
||||
return ret;
|
||||
}
|
@ -30,9 +30,7 @@
|
||||
#include "mem.h"
|
||||
|
||||
/* internal flags. it must not overlap with qse_fs_cpfile_flag_t enumerators */
|
||||
#define CPFILE_DST_ATTR (1 << 27)
|
||||
#define CPFILE_DST_PATH_DUP (1 << 28)
|
||||
#define CPFILE_DST_FSPATH_DUP (1 << 29)
|
||||
#define CPFILE_DST_ATTR (1 << 29)
|
||||
#define CPFILE_DST_FSPATH_MERGED (1 << 30)
|
||||
|
||||
struct cpfile_t
|
||||
@ -42,14 +40,12 @@ struct cpfile_t
|
||||
qse_fs_char_t* src_fspath;
|
||||
qse_fs_char_t* dst_fspath;
|
||||
|
||||
qse_char_t* src_path;
|
||||
qse_char_t* dst_path;
|
||||
|
||||
qse_fs_attr_t src_attr;
|
||||
qse_fs_attr_t dst_attr;
|
||||
};
|
||||
typedef struct cpfile_t cpfile_t;
|
||||
|
||||
|
||||
static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
{
|
||||
qse_fs_char_t* fstmp;
|
||||
@ -59,25 +55,6 @@ static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
* in the directory */
|
||||
QSE_ASSERT (cpfile->dst_attr.isdir);
|
||||
|
||||
if (cpfile->dst_path)
|
||||
{
|
||||
qse_char_t* tmp;
|
||||
|
||||
tmp = qse_mergepathdup (cpfile->dst_path, qse_basename (cpfile->src_path), fs->mmgr);
|
||||
if (!tmp)
|
||||
{
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cpfile->flags & CPFILE_DST_PATH_DUP)
|
||||
QSE_MMGR_FREE (fs->mmgr, cpfile->dst_path);
|
||||
|
||||
cpfile->dst_path = tmp;
|
||||
cpfile->flags |= CPFILE_DST_PATH_DUP;
|
||||
}
|
||||
|
||||
|
||||
fstmp = merge_fspath_dup (cpfile->dst_fspath, get_fspath_base (cpfile->src_fspath), fs->mmgr);
|
||||
if (!fstmp)
|
||||
{
|
||||
@ -85,28 +62,25 @@ static int merge_dstdir_and_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cpfile->flags & CPFILE_DST_FSPATH_DUP)
|
||||
QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath);
|
||||
qse_fs_freefspath (fs, QSE_NULL, cpfile->dst_fspath);
|
||||
cpfile->dst_fspath = fstmp;
|
||||
cpfile->flags |= CPFILE_DST_FSPATH_DUP;
|
||||
|
||||
if (qse_fs_getattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0)
|
||||
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) <= -1)
|
||||
{
|
||||
cpfile->flags |= CPFILE_DST_ATTR;
|
||||
/* attribute on the new destination is not available */
|
||||
cpfile->flags &= ~CPFILE_DST_ATTR;
|
||||
}
|
||||
else
|
||||
{
|
||||
cpfile->flags &= ~CPFILE_DST_ATTR;
|
||||
/* the attribute has been updated to reflect the new destination */
|
||||
cpfile->flags |= CPFILE_DST_ATTR;
|
||||
}
|
||||
|
||||
cpfile->flags |= CPFILE_DST_FSPATH_MERGED;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
#if defined(_WIN32)
|
||||
DWORD copy_file_progress (
|
||||
@ -229,12 +203,12 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
goto oops;
|
||||
}
|
||||
|
||||
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, 0777); /* TODO: proper mode */
|
||||
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode);
|
||||
if (out <= -1 && (cpfile->flags & QSE_FS_CPFILE_FORCE))
|
||||
{
|
||||
/* if forced, delete it and try to open it again */
|
||||
QSE_UNLINK (cpfile->dst_fspath);
|
||||
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, 0777); /* TODO: proper mode */
|
||||
out = QSE_OPEN (cpfile->dst_fspath, O_CREAT | O_WRONLY | O_TRUNC, cpfile->src_attr.mode);
|
||||
}
|
||||
if (out <= -1)
|
||||
{
|
||||
@ -267,7 +241,8 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
struct timeval tv[2];
|
||||
#endif
|
||||
|
||||
if (QSE_FCHOWN (out, cpfile->src_attr.uid, cpfile->src_attr.gid) <= -1)
|
||||
if (QSE_FCHOWN (out, cpfile->src_attr.uid, cpfile->src_attr.gid) <= -1 ||
|
||||
QSE_FCHMOD (out, cpfile->src_attr.mode) <= -1)
|
||||
{
|
||||
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
|
||||
goto oops;
|
||||
@ -311,6 +286,29 @@ static int copy_file_in_fs (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int prepare_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
{
|
||||
/* error if the source file can't be stat'ed.
|
||||
* ok if the destination file can't be stat'ed */
|
||||
if (qse_fs_sysgetattr (fs, cpfile->src_fspath, &cpfile->src_attr) <= -1) return -1;
|
||||
if (qse_fs_sysgetattr (fs, cpfile->dst_fspath, &cpfile->dst_attr) >= 0) cpfile->flags |= CPFILE_DST_ATTR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clear_cpfile (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
{
|
||||
if (cpfile->src_fspath)
|
||||
{
|
||||
QSE_MMGR_FREE (fs->mmgr, cpfile->src_fspath);
|
||||
cpfile->src_fspath = QSE_NULL;
|
||||
}
|
||||
if (cpfile->dst_fspath)
|
||||
{
|
||||
QSE_MMGR_FREE (fs->mmgr, cpfile->dst_fspath);
|
||||
cpfile->dst_fspath = QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
{
|
||||
if (cpfile->src_attr.isdir)
|
||||
@ -320,11 +318,11 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
qse_dir_t* dir;
|
||||
qse_dir_errnum_t direrr;
|
||||
qse_dir_ent_t dirent;
|
||||
qse_char_t* src_path, * dst_path;
|
||||
cpfile_t sub_cpfile;
|
||||
int x;
|
||||
|
||||
copy_dir:
|
||||
if (cpfile->flags & CPFILE_DST_ATTR)
|
||||
if (cpfile->flags & CPFILE_DST_ATTR)
|
||||
{
|
||||
if (!cpfile->dst_attr.isdir)
|
||||
{
|
||||
@ -361,12 +359,20 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
|
||||
if (!(cpfile->flags & QSE_FS_CPFILE_RECURSIVE))
|
||||
{
|
||||
/* cann not copy a directory without recursion */
|
||||
/* cannot copy a directory without recursion */
|
||||
fs->errnum = QSE_FS_EISDIR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
dir = qse_dir_open (fs->mmgr, 0, cpfile->src_path, QSE_DIR_SKIPSPCDIR, &direrr);
|
||||
dir = qse_dir_open (
|
||||
fs->mmgr, 0, (const qse_char_t*)cpfile->src_fspath,
|
||||
#if defined(QSE_FS_CHAR_IS_MCHAR)
|
||||
QSE_DIR_SKIPSPCDIR | QSE_DIR_MBSPATH,
|
||||
#else
|
||||
QSE_DIR_SKIPSPCDIR | QSE_DIR_WCSPATH,
|
||||
#endif
|
||||
&direrr
|
||||
);
|
||||
if (!dir)
|
||||
{
|
||||
fs->errnum = qse_fs_direrrtoerrnum (fs, direrr);
|
||||
@ -390,21 +396,21 @@ static int copy_file (qse_fs_t* fs, cpfile_t* cpfile)
|
||||
}
|
||||
if (x == 0) break; /* no more entries */
|
||||
|
||||
|
||||
src_path = qse_mergepathdup (cpfile->src_path, dirent.name, fs->mmgr);
|
||||
dst_path = qse_mergepathdup (cpfile->dst_path, dirent.name, fs->mmgr);
|
||||
if (!src_path || !dst_path)
|
||||
QSE_MEMSET (&sub_cpfile, 0, QSE_SIZEOF(sub_cpfile));
|
||||
sub_cpfile.flags = cpfile->flags & QSE_FS_CPFILE_ALL; /* inherit public flags */
|
||||
sub_cpfile.src_fspath = merge_fspath_dup (cpfile->src_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
|
||||
sub_cpfile.dst_fspath = merge_fspath_dup (cpfile->dst_fspath, (qse_fs_char_t*)dirent.name, fs->mmgr);
|
||||
if (!sub_cpfile.src_fspath || !sub_cpfile.dst_fspath || prepare_cpfile (fs, &sub_cpfile) <= -1)
|
||||
{
|
||||
if (dst_path) QSE_MMGR_FREE (fs->mmgr, dst_path);
|
||||
if (src_path) QSE_MMGR_FREE (fs->mmgr, src_path);
|
||||
clear_cpfile (fs, &sub_cpfile);
|
||||
qse_dir_close (dir);
|
||||
return -1;
|
||||
}
|
||||
|
||||
x = qse_fs_cpfile (fs, src_path, dst_path, (cpfile->flags & QSE_FS_CPFILE_ALL));
|
||||
x = copy_file (fs, &sub_cpfile); /* TODO: remove recursion */
|
||||
|
||||
clear_cpfile (fs, &sub_cpfile);
|
||||
|
||||
QSE_MMGR_FREE (fs->mmgr, dst_path);
|
||||
QSE_MMGR_FREE (fs->mmgr, src_path);
|
||||
if (x <= -1)
|
||||
{
|
||||
qse_dir_close (dir);
|
||||
@ -469,34 +475,17 @@ int qse_fs_cpfilembs (qse_fs_t* fs, const qse_mchar_t* srcpath, const qse_mchar_
|
||||
|
||||
cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */
|
||||
|
||||
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, srcpath);
|
||||
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathformbs (fs, dstpath);
|
||||
cpfile.src_path = (qse_char_t*)make_str_with_mbs (fs, srcpath);
|
||||
cpfile.dst_path = (qse_char_t*)make_str_with_mbs (fs, dstpath);
|
||||
if (!cpfile.src_fspath || !cpfile.dst_fspath || !cpfile.src_path || !cpfile.dst_path) goto oops;
|
||||
|
||||
if (cpfile.dst_fspath != dstpath)
|
||||
{
|
||||
/* mark that it's been duplicated. */
|
||||
cpfile.flags |= CPFILE_DST_FSPATH_DUP;
|
||||
}
|
||||
|
||||
if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops;
|
||||
if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR;
|
||||
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, srcpath);
|
||||
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathformbs (fs, dstpath);
|
||||
if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops;
|
||||
|
||||
ret = copy_file (fs, &cpfile);
|
||||
|
||||
free_str_with_mbs (fs, dstpath, cpfile.dst_path);
|
||||
free_str_with_mbs (fs, srcpath, cpfile.src_path);
|
||||
qse_fs_freefspathformbs (fs, dstpath, cpfile.dst_fspath);
|
||||
qse_fs_freefspathformbs (fs, srcpath, cpfile.src_fspath);
|
||||
clear_cpfile (fs, &cpfile);
|
||||
return ret;
|
||||
|
||||
oops:
|
||||
if (cpfile.dst_path) free_str_with_mbs (fs, dstpath, cpfile.dst_path);
|
||||
if (cpfile.src_path) free_str_with_mbs (fs, srcpath, cpfile.src_path);
|
||||
if (cpfile.dst_fspath) qse_fs_freefspathformbs (fs, srcpath, cpfile.dst_fspath);
|
||||
if (cpfile.src_fspath) qse_fs_freefspathformbs (fs, dstpath, cpfile.src_fspath);
|
||||
clear_cpfile (fs, &cpfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -509,35 +498,16 @@ int qse_fs_cpfilewcs (qse_fs_t* fs, const qse_wchar_t* srcpath, const qse_wchar_
|
||||
|
||||
cpfile.flags = flags & QSE_FS_CPFILE_ALL; /* keep public flags only */
|
||||
|
||||
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, srcpath);
|
||||
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_makefspathforwcs (fs, dstpath);
|
||||
cpfile.src_path = (qse_char_t*)make_str_with_wcs (fs, srcpath);
|
||||
cpfile.dst_path = (qse_char_t*)make_str_with_wcs (fs, dstpath);
|
||||
if (!cpfile.src_fspath || !cpfile.dst_fspath || !cpfile.src_path || !cpfile.dst_path) goto oops;
|
||||
|
||||
if (cpfile.dst_fspath != dstpath)
|
||||
{
|
||||
/* mark that it's been duplicated */
|
||||
cpfile.flags |= CPFILE_DST_FSPATH_DUP;
|
||||
}
|
||||
|
||||
if (qse_fs_getattr (fs, cpfile.src_fspath, &cpfile.src_attr) <= -1) goto oops;
|
||||
if (qse_fs_getattr (fs, cpfile.dst_fspath, &cpfile.dst_attr) >= 0) cpfile.flags |= CPFILE_DST_ATTR;
|
||||
cpfile.src_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, srcpath);
|
||||
cpfile.dst_fspath = (qse_fs_char_t*)qse_fs_dupfspathforwcs (fs, dstpath);
|
||||
if (!cpfile.src_fspath || !cpfile.dst_fspath || prepare_cpfile (fs, &cpfile) <= -1) goto oops;
|
||||
|
||||
ret = copy_file (fs, &cpfile);
|
||||
|
||||
free_str_with_wcs (fs, dstpath, cpfile.dst_path);
|
||||
free_str_with_wcs (fs, srcpath, cpfile.src_path);
|
||||
qse_fs_freefspathforwcs (fs, dstpath, cpfile.dst_fspath);
|
||||
qse_fs_freefspathforwcs (fs, srcpath, cpfile.src_fspath);
|
||||
clear_cpfile (fs, &cpfile);
|
||||
return ret;
|
||||
|
||||
oops:
|
||||
if (cpfile.dst_path) free_str_with_wcs (fs, dstpath, cpfile.dst_path);
|
||||
if (cpfile.src_path) free_str_with_wcs (fs, srcpath, cpfile.src_path);
|
||||
if (cpfile.dst_fspath) qse_fs_freefspathforwcs (fs, srcpath, cpfile.dst_fspath);
|
||||
if (cpfile.src_fspath) qse_fs_freefspathforwcs (fs, dstpath, cpfile.src_fspath);
|
||||
clear_cpfile (fs, &cpfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -815,79 +815,3 @@ void qse_fs_freefspathforwcs (qse_fs_t* fs, const qse_wchar_t* path, qse_fs_char
|
||||
}
|
||||
|
||||
|
||||
int qse_fs_getattr (qse_fs_t* fs, const qse_fs_char_t* fspath, qse_fs_attr_t* attr)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#elif defined(__OS2__)
|
||||
|
||||
/* TODO */
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#elif defined(__DOS__)
|
||||
|
||||
fs->errnum = QSE_FS_ENOIMPL;
|
||||
return -1;
|
||||
|
||||
#else
|
||||
#if defined(HAVE_LSTAT)
|
||||
qse_lstat_t st;
|
||||
#else
|
||||
qse_stat_t st;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LSTAT)
|
||||
if (QSE_LSTAT (fspath, &st) == -1)
|
||||
{
|
||||
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
/* is this ok to use stat? */
|
||||
if (QSE_STAT (fspath, &st) == -1)
|
||||
{
|
||||
fs->errnum = qse_fs_syserrtoerrnum (fs, errno);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
QSE_MEMSET (attr, 0, QSE_SIZEOF(*attr));
|
||||
|
||||
if (S_ISDIR(st.st_mode)) attr->isdir = 1;
|
||||
if (S_ISLNK(st.st_mode)) attr->islnk = 1;
|
||||
if (S_ISREG(st.st_mode)) attr->isreg = 1;
|
||||
if (S_ISBLK(st.st_mode)) attr->isblk = 1;
|
||||
if (S_ISCHR(st.st_mode)) attr->ischr = 1;
|
||||
|
||||
attr->size = st.st_size;
|
||||
attr->ino = st.st_ino;
|
||||
attr->dev = st.st_dev;
|
||||
attr->uid = st.st_uid;
|
||||
attr->gid = st.st_gid;
|
||||
|
||||
#if defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC)
|
||||
attr->atime.sec = st.st_atim.tv_sec;
|
||||
attr->atime.nsec = st.st_atim.tv_nsec;
|
||||
attr->mtime.sec = st.st_mtim.tv_sec;
|
||||
attr->mtime.nsec = st.st_mtim.tv_nsec;
|
||||
attr->ctime.sec = st.st_ctim.tv_sec;
|
||||
attr->ctime.nsec = st.st_ctim.tv_nsec;
|
||||
#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC)
|
||||
attr->atime.sec = st.st_atimespec.tv_sec;
|
||||
attr->atime.nsec = st.st_atimespec.tv_nsec;
|
||||
attr->mtime.sec = st.st_mtimespec.tv_sec;
|
||||
attr->mtime.nsec = st.st_mtimespec.tv_nsec;
|
||||
attr->ctime.sec = st.st_ctimespec.tv_sec;
|
||||
attr->ctime.nsec = st.st_ctimespec.tv_nsec;
|
||||
#else
|
||||
attr->atime.sec = st.st_atime;
|
||||
attr->mtime.sec = st.st_mtime;
|
||||
attr->ctime.sec = st.st_ctime;
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -143,11 +143,16 @@ void qse_fs_freefspathforwcs (
|
||||
# define qse_fs_freefspath(fs,path,fspath) qse_fs_freefspathforwcs(fs,path,fspath);
|
||||
#endif
|
||||
|
||||
|
||||
int qse_fs_getattr (
|
||||
int qse_fs_sysgetattr (
|
||||
qse_fs_t* fs,
|
||||
const qse_fs_char_t* fspath,
|
||||
qse_fs_attr_t* attr
|
||||
qse_fs_attr_t* attr
|
||||
);
|
||||
|
||||
int qse_fs_syscpfile (
|
||||
qse_fs_t* fs,
|
||||
const qse_fs_char_t* srcpath,
|
||||
const qse_fs_char_t* dstpath
|
||||
);
|
||||
|
||||
int qse_fs_sysmkdir (
|
||||
|
Loading…
Reference in New Issue
Block a user