version 1.33, 2002/02/13 00:28:13 |
version 1.33.2.2, 2002/10/11 14:51:52 |
|
|
"Unknown error" /* Others */ |
"Unknown error" /* Others */ |
}; |
}; |
|
|
TRACE("sent status id %d error %d", id, error); |
TRACE("sent status id %u error %u", id, error); |
buffer_init(&msg); |
buffer_init(&msg); |
buffer_put_char(&msg, SSH2_FXP_STATUS); |
buffer_put_char(&msg, SSH2_FXP_STATUS); |
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
|
|
static void |
static void |
send_data(u_int32_t id, char *data, int dlen) |
send_data(u_int32_t id, char *data, int dlen) |
{ |
{ |
TRACE("sent data id %d len %d", id, dlen); |
TRACE("sent data id %u len %d", id, dlen); |
send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); |
send_data_or_handle(SSH2_FXP_DATA, id, data, dlen); |
} |
} |
|
|
|
|
int hlen; |
int hlen; |
|
|
handle_to_string(handle, &string, &hlen); |
handle_to_string(handle, &string, &hlen); |
TRACE("sent handle id %d handle %d", id, handle); |
TRACE("sent handle id %u handle %d", id, handle); |
send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); |
send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen); |
xfree(string); |
xfree(string); |
} |
} |
|
|
buffer_put_char(&msg, SSH2_FXP_NAME); |
buffer_put_char(&msg, SSH2_FXP_NAME); |
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
buffer_put_int(&msg, count); |
buffer_put_int(&msg, count); |
TRACE("sent names id %d count %d", id, count); |
TRACE("sent names id %u count %d", id, count); |
for (i = 0; i < count; i++) { |
for (i = 0; i < count; i++) { |
buffer_put_cstring(&msg, stats[i].name); |
buffer_put_cstring(&msg, stats[i].name); |
buffer_put_cstring(&msg, stats[i].long_name); |
buffer_put_cstring(&msg, stats[i].long_name); |
|
|
{ |
{ |
Buffer msg; |
Buffer msg; |
|
|
TRACE("sent attrib id %d have 0x%x", id, a->flags); |
TRACE("sent attrib id %u have 0x%x", id, a->flags); |
buffer_init(&msg); |
buffer_init(&msg); |
buffer_put_char(&msg, SSH2_FXP_ATTRS); |
buffer_put_char(&msg, SSH2_FXP_ATTRS); |
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
|
|
{ |
{ |
Buffer msg; |
Buffer msg; |
|
|
version = buffer_get_int(&iqueue); |
version = get_int(); |
TRACE("client version %d", version); |
TRACE("client version %d", version); |
buffer_init(&msg); |
buffer_init(&msg); |
buffer_put_char(&msg, SSH2_FXP_VERSION); |
buffer_put_char(&msg, SSH2_FXP_VERSION); |
|
|
a = get_attrib(); |
a = get_attrib(); |
flags = flags_from_portable(pflags); |
flags = flags_from_portable(pflags); |
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; |
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; |
TRACE("open id %d name %s flags %d mode 0%o", id, name, pflags, mode); |
TRACE("open id %u name %s flags %d mode 0%o", id, name, pflags, mode); |
fd = open(name, flags, mode); |
fd = open(name, flags, mode); |
if (fd < 0) { |
if (fd < 0) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
|
|
|
|
id = get_int(); |
id = get_int(); |
handle = get_handle(); |
handle = get_handle(); |
TRACE("close id %d handle %d", id, handle); |
TRACE("close id %u handle %d", id, handle); |
ret = handle_close(handle); |
ret = handle_close(handle); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
send_status(id, status); |
send_status(id, status); |
|
|
off = get_int64(); |
off = get_int64(); |
len = get_int(); |
len = get_int(); |
|
|
TRACE("read id %d handle %d off %llu len %d", id, handle, |
TRACE("read id %u handle %d off %llu len %d", id, handle, |
(unsigned long long)off, len); |
(unsigned long long)off, len); |
if (len > sizeof buf) { |
if (len > sizeof buf) { |
len = sizeof buf; |
len = sizeof buf; |
|
|
off = get_int64(); |
off = get_int64(); |
data = get_string(&len); |
data = get_string(&len); |
|
|
TRACE("write id %d handle %d off %llu len %d", id, handle, |
TRACE("write id %u handle %d off %llu len %d", id, handle, |
(unsigned long long)off, len); |
(unsigned long long)off, len); |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd >= 0) { |
if (fd >= 0) { |
|
|
|
|
id = get_int(); |
id = get_int(); |
name = get_string(NULL); |
name = get_string(NULL); |
TRACE("%sstat id %d name %s", do_lstat ? "l" : "", id, name); |
TRACE("%sstat id %u name %s", do_lstat ? "l" : "", id, name); |
ret = do_lstat ? lstat(name, &st) : stat(name, &st); |
ret = do_lstat ? lstat(name, &st) : stat(name, &st); |
if (ret < 0) { |
if (ret < 0) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
|
|
|
|
id = get_int(); |
id = get_int(); |
handle = get_handle(); |
handle = get_handle(); |
TRACE("fstat id %d handle %d", id, handle); |
TRACE("fstat id %u handle %d", id, handle); |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd >= 0) { |
if (fd >= 0) { |
ret = fstat(fd, &st); |
ret = fstat(fd, &st); |
|
|
Attrib *a; |
Attrib *a; |
u_int32_t id; |
u_int32_t id; |
char *name; |
char *name; |
int ret; |
int status = SSH2_FX_OK, ret; |
int status = SSH2_FX_OK; |
|
|
|
id = get_int(); |
id = get_int(); |
name = get_string(NULL); |
name = get_string(NULL); |
a = get_attrib(); |
a = get_attrib(); |
TRACE("setstat id %d name %s", id, name); |
TRACE("setstat id %u name %s", id, name); |
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { |
ret = truncate(name, a->size); |
ret = truncate(name, a->size); |
if (ret == -1) |
if (ret == -1) |
|
|
id = get_int(); |
id = get_int(); |
handle = get_handle(); |
handle = get_handle(); |
a = get_attrib(); |
a = get_attrib(); |
TRACE("fsetstat id %d handle %d", id, handle); |
TRACE("fsetstat id %u handle %d", id, handle); |
fd = handle_to_fd(handle); |
fd = handle_to_fd(handle); |
if (fd < 0) { |
if (fd < 0) { |
status = SSH2_FX_FAILURE; |
status = SSH2_FX_FAILURE; |
|
|
|
|
id = get_int(); |
id = get_int(); |
path = get_string(NULL); |
path = get_string(NULL); |
TRACE("opendir id %d path %s", id, path); |
TRACE("opendir id %u path %s", id, path); |
dirp = opendir(path); |
dirp = opendir(path); |
if (dirp == NULL) { |
if (dirp == NULL) { |
status = errno_to_portable(errno); |
status = errno_to_portable(errno); |
|
|
xfree(path); |
xfree(path); |
} |
} |
|
|
/* |
|
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh |
|
*/ |
|
static char * |
|
ls_file(char *name, struct stat *st) |
|
{ |
|
int ulen, glen, sz = 0; |
|
struct passwd *pw; |
|
struct group *gr; |
|
struct tm *ltime = localtime(&st->st_mtime); |
|
char *user, *group; |
|
char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; |
|
|
|
strmode(st->st_mode, mode); |
|
if ((pw = getpwuid(st->st_uid)) != NULL) { |
|
user = pw->pw_name; |
|
} else { |
|
snprintf(ubuf, sizeof ubuf, "%d", st->st_uid); |
|
user = ubuf; |
|
} |
|
if ((gr = getgrgid(st->st_gid)) != NULL) { |
|
group = gr->gr_name; |
|
} else { |
|
snprintf(gbuf, sizeof gbuf, "%d", st->st_gid); |
|
group = gbuf; |
|
} |
|
if (ltime != NULL) { |
|
if (time(NULL) - st->st_mtime < (365*24*60*60)/2) |
|
sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime); |
|
else |
|
sz = strftime(tbuf, sizeof tbuf, "%b %e %Y", ltime); |
|
} |
|
if (sz == 0) |
|
tbuf[0] = '\0'; |
|
ulen = MAX(strlen(user), 8); |
|
glen = MAX(strlen(group), 8); |
|
snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode, |
|
st->st_nlink, ulen, user, glen, group, |
|
(unsigned long long)st->st_size, tbuf, name); |
|
return xstrdup(buf); |
|
} |
|
|
|
static void |
static void |
process_readdir(void) |
process_readdir(void) |
{ |
{ |
|
|
|
|
id = get_int(); |
id = get_int(); |
handle = get_handle(); |
handle = get_handle(); |
TRACE("readdir id %d handle %d", id, handle); |
TRACE("readdir id %u handle %d", id, handle); |
dirp = handle_to_dir(handle); |
dirp = handle_to_dir(handle); |
path = handle_to_name(handle); |
path = handle_to_name(handle); |
if (dirp == NULL || path == NULL) { |
if (dirp == NULL || path == NULL) { |
|
|
char pathname[1024]; |
char pathname[1024]; |
Stat *stats; |
Stat *stats; |
int nstats = 10, count = 0, i; |
int nstats = 10, count = 0, i; |
|
|
stats = xmalloc(nstats * sizeof(Stat)); |
stats = xmalloc(nstats * sizeof(Stat)); |
while ((dp = readdir(dirp)) != NULL) { |
while ((dp = readdir(dirp)) != NULL) { |
if (count >= nstats) { |
if (count >= nstats) { |
|
|
continue; |
continue; |
stat_to_attrib(&st, &(stats[count].attrib)); |
stat_to_attrib(&st, &(stats[count].attrib)); |
stats[count].name = xstrdup(dp->d_name); |
stats[count].name = xstrdup(dp->d_name); |
stats[count].long_name = ls_file(dp->d_name, &st); |
stats[count].long_name = ls_file(dp->d_name, &st, 0); |
count++; |
count++; |
/* send up to 100 entries in one message */ |
/* send up to 100 entries in one message */ |
/* XXX check packet size instead */ |
/* XXX check packet size instead */ |
|
|
|
|
id = get_int(); |
id = get_int(); |
name = get_string(NULL); |
name = get_string(NULL); |
TRACE("remove id %d name %s", id, name); |
TRACE("remove id %u name %s", id, name); |
ret = unlink(name); |
ret = unlink(name); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
send_status(id, status); |
send_status(id, status); |
|
|
a = get_attrib(); |
a = get_attrib(); |
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? |
mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? |
a->perm & 0777 : 0777; |
a->perm & 0777 : 0777; |
TRACE("mkdir id %d name %s mode 0%o", id, name, mode); |
TRACE("mkdir id %u name %s mode 0%o", id, name, mode); |
ret = mkdir(name, mode); |
ret = mkdir(name, mode); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
send_status(id, status); |
send_status(id, status); |
|
|
|
|
id = get_int(); |
id = get_int(); |
name = get_string(NULL); |
name = get_string(NULL); |
TRACE("rmdir id %d name %s", id, name); |
TRACE("rmdir id %u name %s", id, name); |
ret = rmdir(name); |
ret = rmdir(name); |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; |
send_status(id, status); |
send_status(id, status); |
|
|
xfree(path); |
xfree(path); |
path = xstrdup("."); |
path = xstrdup("."); |
} |
} |
TRACE("realpath id %d path %s", id, path); |
TRACE("realpath id %u path %s", id, path); |
if (realpath(path, resolvedname) == NULL) { |
if (realpath(path, resolvedname) == NULL) { |
send_status(id, errno_to_portable(errno)); |
send_status(id, errno_to_portable(errno)); |
} else { |
} else { |
|
|
id = get_int(); |
id = get_int(); |
oldpath = get_string(NULL); |
oldpath = get_string(NULL); |
newpath = get_string(NULL); |
newpath = get_string(NULL); |
TRACE("rename id %d old %s new %s", id, oldpath, newpath); |
TRACE("rename id %u old %s new %s", id, oldpath, newpath); |
/* fail if 'newpath' exists */ |
/* fail if 'newpath' exists */ |
if (stat(newpath, &st) == -1) { |
if (stat(newpath, &st) == -1) { |
ret = rename(oldpath, newpath); |
ret = rename(oldpath, newpath); |
|
|
|
|
id = get_int(); |
id = get_int(); |
path = get_string(NULL); |
path = get_string(NULL); |
TRACE("readlink id %d path %s", id, path); |
TRACE("readlink id %u path %s", id, path); |
if ((len = readlink(path, link, sizeof(link) - 1)) == -1) |
if ((len = readlink(path, link, sizeof(link) - 1)) == -1) |
send_status(id, errno_to_portable(errno)); |
send_status(id, errno_to_portable(errno)); |
else { |
else { |
|
|
id = get_int(); |
id = get_int(); |
oldpath = get_string(NULL); |
oldpath = get_string(NULL); |
newpath = get_string(NULL); |
newpath = get_string(NULL); |
TRACE("symlink id %d old %s new %s", id, oldpath, newpath); |
TRACE("symlink id %u old %s new %s", id, oldpath, newpath); |
/* fail if 'newpath' exists */ |
/* fail if 'newpath' exists */ |
if (stat(newpath, &st) == -1) { |
if (stat(newpath, &st) == -1) { |
ret = symlink(oldpath, newpath); |
ret = symlink(oldpath, newpath); |
|
|
process(void) |
process(void) |
{ |
{ |
u_int msg_len; |
u_int msg_len; |
|
u_int buf_len; |
|
u_int consumed; |
u_int type; |
u_int type; |
u_char *cp; |
u_char *cp; |
|
|
if (buffer_len(&iqueue) < 5) |
buf_len = buffer_len(&iqueue); |
|
if (buf_len < 5) |
return; /* Incomplete message. */ |
return; /* Incomplete message. */ |
cp = buffer_ptr(&iqueue); |
cp = buffer_ptr(&iqueue); |
msg_len = GET_32BIT(cp); |
msg_len = GET_32BIT(cp); |
|
|
error("bad message "); |
error("bad message "); |
exit(11); |
exit(11); |
} |
} |
if (buffer_len(&iqueue) < msg_len + 4) |
if (buf_len < msg_len + 4) |
return; |
return; |
buffer_consume(&iqueue, 4); |
buffer_consume(&iqueue, 4); |
|
buf_len -= 4; |
type = buffer_get_char(&iqueue); |
type = buffer_get_char(&iqueue); |
switch (type) { |
switch (type) { |
case SSH2_FXP_INIT: |
case SSH2_FXP_INIT: |
|
|
error("Unknown message %d", type); |
error("Unknown message %d", type); |
break; |
break; |
} |
} |
|
/* discard the remaining bytes from the current packet */ |
|
if (buf_len < buffer_len(&iqueue)) |
|
fatal("iqueue grows"); |
|
consumed = buf_len - buffer_len(&iqueue); |
|
if (msg_len < consumed) |
|
fatal("msg_len %d < consumed %d", msg_len, consumed); |
|
if (msg_len > consumed) |
|
buffer_consume(&iqueue, msg_len - consumed); |
} |
} |
|
|
int |
int |