mirror of
https://github.com/upa/mscp.git
synced 2026-02-23 16:34:44 +08:00
cleanup wrappers for file operations
Previously wrapper functions for open(), opendir(), and stat(), etc, are implemneted in path.h, and now they are in fileops.h and fileops.c. This commit is a reparation for remote glob.
This commit is contained in:
249
src/path.h
249
src/path.h
@@ -98,253 +98,4 @@ int copy_chunk(FILE *msg_fp, struct chunk *c,
|
||||
/* just print contents. just for debugging */
|
||||
void path_dump(struct list_head *path_list);
|
||||
|
||||
|
||||
|
||||
/* wrap DIR/dirent and sftp_dir/sftp_attribute. not thread safe */
|
||||
struct mscp_dir {
|
||||
DIR *l;
|
||||
sftp_dir r;
|
||||
sftp_session sftp;
|
||||
};
|
||||
typedef struct mscp_dir mdir;
|
||||
|
||||
struct mscp_dirent {
|
||||
struct dirent *l;
|
||||
sftp_attributes r;
|
||||
};
|
||||
typedef struct mscp_dirent mdirent;
|
||||
|
||||
#define mdirent_name(e) ((e->l) ? e->l->d_name : e->r->name)
|
||||
#define mdirent_is_dir(e) ((e->l) ? \
|
||||
(e->l->d_type == DT_DIR) : \
|
||||
(e->r->type == SSH_FILEXFER_TYPE_DIRECTORY))
|
||||
#define mdirent_is_null(e) (e->l == NULL && e->r == NULL)
|
||||
|
||||
static mdir *mscp_opendir(const char *path, sftp_session sftp)
|
||||
{
|
||||
mdir *d;
|
||||
|
||||
if (!(d = malloc(sizeof(*d))))
|
||||
return NULL;
|
||||
memset(d, 0, sizeof(*d));
|
||||
|
||||
d->sftp = sftp;
|
||||
|
||||
if (sftp) {
|
||||
d->r = sftp_opendir(sftp, path);
|
||||
if (!d->r) {
|
||||
mscp_set_error("sftp_opendir '%s': %s",
|
||||
path, sftp_get_ssh_error(sftp));
|
||||
free(d);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
d->l = opendir(path);
|
||||
if (!d->l) {
|
||||
mscp_set_error("opendir '%s': %s", path, strerrno());
|
||||
free(d);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
static int mscp_closedir(mdir *d)
|
||||
{
|
||||
int ret;
|
||||
if (d->r)
|
||||
ret = sftp_closedir(d->r);
|
||||
else
|
||||
ret = closedir(d->l);
|
||||
free(d);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static mdirent *mscp_readdir(mdir *d)
|
||||
{
|
||||
static mdirent e;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
if (d->r)
|
||||
e.r = sftp_readdir(d->sftp, d->r);
|
||||
else
|
||||
e.l = readdir(d->l);
|
||||
return &e;
|
||||
}
|
||||
|
||||
static void mscp_dirent_free(mdirent *e)
|
||||
{
|
||||
if (e->r) {
|
||||
sftp_attributes_free(e->r);
|
||||
e->r = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* wrap retriving error */
|
||||
static const char *mscp_strerror(sftp_session sftp)
|
||||
{
|
||||
if (sftp)
|
||||
return sftp_get_ssh_error(sftp);
|
||||
return strerrno();
|
||||
}
|
||||
|
||||
/* warp stat/sftp_stat */
|
||||
struct mscp_stat {
|
||||
struct stat l;
|
||||
sftp_attributes r;
|
||||
};
|
||||
typedef struct mscp_stat mstat;
|
||||
|
||||
static int mscp_stat(const char *path, mstat *s, sftp_session sftp)
|
||||
{
|
||||
memset(s, 0, sizeof(*s));
|
||||
|
||||
if (sftp) {
|
||||
s->r = sftp_stat(sftp, path);
|
||||
if (!s->r) {
|
||||
mscp_set_error("sftp_stat: %s %s",
|
||||
sftp_get_ssh_error(sftp), path);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (stat(path, &s->l) < 0) {
|
||||
mscp_set_error("stat: %s %s", strerrno(), path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mscp_stat_check_err_noent(sftp_session sftp)
|
||||
{
|
||||
if (sftp) {
|
||||
if (sftp_get_error(sftp) == SSH_FX_NO_SUCH_PATH ||
|
||||
sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE)
|
||||
return 0;
|
||||
} else {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void mscp_stat_free(mstat s) {
|
||||
if (s.r)
|
||||
sftp_attributes_free(s.r);
|
||||
}
|
||||
|
||||
#define mstat_size(s) ((s.r) ? s.r->size : s.l.st_size)
|
||||
#define mstat_mode(s) ((s.r) ? \
|
||||
s.r->permissions : \
|
||||
s.l.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))
|
||||
#define mstat_is_regular(s) ((s.r) ? \
|
||||
(s.r->type == SSH_FILEXFER_TYPE_REGULAR) : \
|
||||
S_ISREG(s.l.st_mode))
|
||||
#define mstat_is_dir(s) ((s.r) ? \
|
||||
(s.r->type == SSH_FILEXFER_TYPE_DIRECTORY) : \
|
||||
S_ISDIR(s.l.st_mode))
|
||||
|
||||
/* wrap mkdir */
|
||||
static int mscp_mkdir(const char *path, mode_t mode, sftp_session sftp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sftp) {
|
||||
ret = sftp_mkdir(sftp, path, mode);
|
||||
if (ret < 0 &&
|
||||
sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS) {
|
||||
mscp_set_error("sftp_mkdir '%s': %s",
|
||||
path, sftp_get_ssh_error(sftp));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (mkdir(path, mode) == -1 && errno != EEXIST) {
|
||||
mscp_set_error("mkdir '%s': %s", path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* wrap open/sftp_open */
|
||||
struct mscp_file_handle {
|
||||
int fd;
|
||||
sftp_file sf;
|
||||
};
|
||||
typedef struct mscp_file_handle mfh;
|
||||
|
||||
static mfh mscp_open(const char *path, int flags, mode_t mode, size_t off,
|
||||
sftp_session sftp)
|
||||
{
|
||||
mfh h;
|
||||
|
||||
h.fd = -1;
|
||||
h.sf = NULL;
|
||||
|
||||
if (sftp) {
|
||||
h.sf = sftp_open(sftp, path, flags, mode);
|
||||
if (!h.sf) {
|
||||
mscp_set_error("sftp_open '%s': %s",
|
||||
path, sftp_get_ssh_error(sftp));
|
||||
return h;
|
||||
}
|
||||
|
||||
if (sftp_seek64(h.sf, off) < 0) {
|
||||
mscp_set_error("sftp_seek64 '%s': %s",
|
||||
path, sftp_get_ssh_error(sftp));
|
||||
sftp_close(h.sf);
|
||||
h.sf = NULL;
|
||||
return h;
|
||||
}
|
||||
} else {
|
||||
h.fd = open(path, flags, mode);
|
||||
if (h.fd < 0) {
|
||||
mscp_set_error("open '%s': %s", path, strerrno());
|
||||
return h;
|
||||
}
|
||||
if (lseek(h.fd, off, SEEK_SET) < 0) {
|
||||
mscp_set_error("lseek '%s': %s", path, strerrno());
|
||||
close(h.fd);
|
||||
h.fd = -1;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
#define mscp_open_is_failed(h) (h.fd < 0 && h.sf == NULL)
|
||||
|
||||
static void mscp_close(mfh h)
|
||||
{
|
||||
if (h.sf)
|
||||
sftp_close(h.sf);
|
||||
if (h.fd > 0)
|
||||
close(h.fd);
|
||||
h.sf = NULL;
|
||||
h.fd = -1;
|
||||
}
|
||||
|
||||
/* wrap chmod/sftp_chmod */
|
||||
|
||||
static int mscp_chmod(const char *path, mode_t mode, sftp_session sftp)
|
||||
{
|
||||
if (sftp) {
|
||||
if (sftp_chmod(sftp, path, mode) < 0) {
|
||||
mscp_set_error("sftp_chmod '%s': %s",
|
||||
path, sftp_get_ssh_error(sftp));
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (chmod(path, mode) < 0) {
|
||||
mscp_set_error("chmod '%s': %s", path, strerrno());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _PATH_H_ */
|
||||
|
||||
Reference in New Issue
Block a user