* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.14 2001/01/21 19:05:56 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.19 2001/02/07 18:01:18 itojun Exp $");
#include "buffer.h"
#include "bufaux.h"
#include "xmalloc.h"
#include "sftp.h"
+#include "sftp-common.h"
/* helper */
#define get_int64() buffer_get_int64(&iqueue);
/* portable attibutes, etc. */
-typedef struct Attrib Attrib;
typedef struct Stat Stat;
-struct Attrib
-{
- u_int32_t flags;
- u_int64_t size;
- u_int32_t uid;
- u_int32_t gid;
- u_int32_t perm;
- u_int32_t atime;
- u_int32_t mtime;
-};
-
-struct Stat
-{
+struct Stat {
char *name;
char *long_name;
Attrib attrib;
return flags;
}
-void
-attrib_clear(Attrib *a)
-{
- a->flags = 0;
- a->size = 0;
- a->uid = 0;
- a->gid = 0;
- a->perm = 0;
- a->atime = 0;
- a->mtime = 0;
-}
-
-Attrib *
-decode_attrib(Buffer *b)
-{
- static Attrib a;
- attrib_clear(&a);
- a.flags = buffer_get_int(b);
- if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
- a.size = buffer_get_int64(b);
- }
- if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
- a.uid = buffer_get_int(b);
- a.gid = buffer_get_int(b);
- }
- if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
- a.perm = buffer_get_int(b);
- }
- if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
- a.atime = buffer_get_int(b);
- a.mtime = buffer_get_int(b);
- }
- /* vendor-specific extensions */
- if (a.flags & SSH2_FILEXFER_ATTR_EXTENDED) {
- char *type, *data;
- int i, count;
- count = buffer_get_int(b);
- for (i = 0; i < count; i++) {
- type = buffer_get_string(b, NULL);
- data = buffer_get_string(b, NULL);
- xfree(type);
- xfree(data);
- }
- }
- return &a;
-}
-
-void
-encode_attrib(Buffer *b, Attrib *a)
-{
- buffer_put_int(b, a->flags);
- if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
- buffer_put_int64(b, a->size);
- }
- if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
- buffer_put_int(b, a->uid);
- buffer_put_int(b, a->gid);
- }
- if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
- buffer_put_int(b, a->perm);
- }
- if (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
- buffer_put_int(b, a->atime);
- buffer_put_int(b, a->mtime);
- }
-}
-
-void
-stat_to_attrib(struct stat *st, Attrib *a)
-{
- attrib_clear(a);
- a->flags = 0;
- a->flags |= SSH2_FILEXFER_ATTR_SIZE;
- a->size = st->st_size;
- a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
- a->uid = st->st_uid;
- a->gid = st->st_gid;
- a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
- a->perm = st->st_mode;
- a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
- a->atime = st->st_atime;
- a->mtime = st->st_mtime;
-}
-
Attrib *
get_attrib(void)
{
int
handle_to_fd(int handle)
{
- if (handle_is_ok(handle, HANDLE_FILE))
+ if (handle_is_ok(handle, HANDLE_FILE))
return handles[handle].fd;
return -1;
}
off = get_int64();
len = get_int();
- TRACE("read id %d handle %d off %lld len %d", id, handle, off, len);
+ TRACE("read id %d handle %d off %llu len %d", id, handle,
+ (unsigned long long)off, len);
if (len > sizeof buf) {
len = sizeof buf;
log("read change len %d", len);
off = get_int64();
data = get_string(&len);
- TRACE("write id %d handle %d off %lld len %d", id, handle, off, len);
+ TRACE("write id %d handle %d off %llu len %d", id, handle,
+ (unsigned long long)off, len);
fd = handle_to_fd(handle);
if (fd >= 0) {
if (lseek(fd, off, SEEK_SET) < 0) {
if (ret == -1)
status = errno_to_portable(errno);
}
+ if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
+ ret = chown(name, a->uid, a->gid);
+ if (ret == -1)
+ status = errno_to_portable(errno);
+ }
send_status(id, status);
xfree(name);
}
int handle, fd, ret;
int status = SSH2_FX_OK;
char *name;
-
+
id = get_int();
handle = get_handle();
a = get_attrib();
TRACE("fsetstat id %d handle %d", id, handle);
fd = handle_to_fd(handle);
name = handle_to_name(handle);
- if ((fd < 0) || (name == NULL)) {
+ if (fd < 0 || name == NULL) {
status = SSH2_FX_FAILURE;
} else {
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
#ifdef HAVE_FCHMOD
ret = fchmod(fd, a->perm & 0777);
#else
- ret = chmod(name, a->perm & 077);
+ ret = chmod(name, a->perm & 0777);
#endif
if (ret == -1)
status = errno_to_portable(errno);
if (ret == -1)
status = errno_to_portable(errno);
}
+ if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
+ ret = fchown(fd, a->uid, a->gid);
+ if (ret == -1)
+ status = errno_to_portable(errno);
+ }
}
send_status(id, status);
}
id = get_int();
path = get_string(NULL);
TRACE("opendir id %d path %s", id, path);
- dirp = opendir(path);
+ dirp = opendir(path);
if (dirp == NULL) {
status = errno_to_portable(errno);
} else {
send_handle(id, handle);
status = SSH2_FX_OK;
}
-
+
}
if (status != SSH2_FX_OK)
send_status(id, status);
}
if (sz == 0)
tbuf[0] = '\0';
- snprintf(buf, sizeof buf, "%s %3d %-8.8s %-8.8s %8qd %s %s", mode,
- st->st_nlink, user, group, (long long)st->st_size, tbuf, name);
+ snprintf(buf, sizeof buf, "%s %3d %-8.8s %-8.8s %8llu %s %s", mode,
+ st->st_nlink, user, group, (unsigned long long)st->st_size, tbuf, name);
return xstrdup(buf);
}
handle_init();
#ifdef DEBUG_SFTP_SERVER
- log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
+ log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0);
#endif
in = dup(STDIN_FILENO);