/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.24 2001/03/14 22:50:25 deraadt Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.32 2001/12/29 21:56:01 stevesk Exp $");
#include "buffer.h"
#include "bufaux.h"
Attrib attrib;
};
-int
+static int
errno_to_portable(int unixerrno)
{
int ret = 0;
return ret;
}
-int
+static int
flags_from_portable(int pflags)
{
int flags = 0;
return flags;
}
-Attrib *
+static Attrib *
get_attrib(void)
{
return decode_attrib(&iqueue);
Handle handles[100];
-void
+static void
handle_init(void)
{
int i;
- for(i = 0; i < sizeof(handles)/sizeof(Handle); i++)
+ for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
handles[i].use = HANDLE_UNUSED;
}
-int
+static int
handle_new(int use, char *name, int fd, DIR *dirp)
{
int i;
- for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
+ for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
if (handles[i].use == HANDLE_UNUSED) {
handles[i].use = use;
handles[i].dirp = dirp;
return -1;
}
-int
+static int
handle_is_ok(int i, int type)
{
return i >= 0 && i < sizeof(handles)/sizeof(Handle) &&
handles[i].use == type;
}
-int
+static int
handle_to_string(int handle, char **stringp, int *hlenp)
{
if (stringp == NULL || hlenp == NULL)
return 0;
}
-int
+static int
handle_from_string(char *handle, u_int hlen)
{
int val;
return -1;
}
-char *
+static char *
handle_to_name(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR)||
return NULL;
}
-DIR *
+static DIR *
handle_to_dir(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR))
return NULL;
}
-int
+static int
handle_to_fd(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
return -1;
}
-int
+static int
handle_close(int handle)
{
int ret = -1;
return ret;
}
-int
+static int
get_handle(void)
{
char *handle;
/* send replies */
-void
+static void
send_msg(Buffer *m)
{
int mlen = buffer_len(m);
buffer_consume(m, mlen);
}
-void
+static void
send_status(u_int32_t id, u_int32_t error)
{
Buffer msg;
buffer_put_int(&msg, id);
buffer_put_int(&msg, error);
if (version >= 3) {
- buffer_put_cstring(&msg,
+ buffer_put_cstring(&msg,
status_messages[MIN(error,SSH2_FX_MAX)]);
buffer_put_cstring(&msg, "");
}
send_msg(&msg);
buffer_free(&msg);
}
-void
+static void
send_data_or_handle(char type, u_int32_t id, char *data, int dlen)
{
Buffer msg;
buffer_free(&msg);
}
-void
+static void
send_data(u_int32_t id, char *data, int dlen)
{
TRACE("sent data id %d len %d", id, dlen);
send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
}
-void
+static void
send_handle(u_int32_t id, int handle)
{
char *string;
xfree(string);
}
-void
+static void
send_names(u_int32_t id, int count, Stat *stats)
{
Buffer msg;
buffer_free(&msg);
}
-void
+static void
send_attrib(u_int32_t id, Attrib *a)
{
Buffer msg;
/* parse incoming */
-void
+static void
process_init(void)
{
Buffer msg;
buffer_free(&msg);
}
-void
+static void
process_open(void)
{
u_int32_t id, pflags;
xfree(name);
}
-void
+static void
process_close(void)
{
u_int32_t id;
send_status(id, status);
}
-void
+static void
process_read(void)
{
char buf[64*1024];
send_status(id, status);
}
-void
+static void
process_write(void)
{
u_int32_t id;
xfree(data);
}
-void
+static void
process_do_stat(int do_lstat)
{
Attrib a;
xfree(name);
}
-void
+static void
process_stat(void)
{
process_do_stat(0);
}
-void
+static void
process_lstat(void)
{
process_do_stat(1);
}
-void
+static void
process_fstat(void)
{
Attrib a;
send_status(id, status);
}
-struct timeval *
+static struct timeval *
attrib_to_tv(Attrib *a)
{
static struct timeval tv[2];
return tv;
}
-void
+static void
process_setstat(void)
{
Attrib *a;
xfree(name);
}
-void
+static void
process_fsetstat(void)
{
Attrib *a;
send_status(id, status);
}
-void
+static void
process_opendir(void)
{
DIR *dirp = NULL;
/*
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh
*/
-char *
+static char *
ls_file(char *name, struct stat *st)
{
- int sz = 0;
+ int ulen, glen, sz = 0;
struct passwd *pw;
struct group *gr;
struct tm *ltime = localtime(&st->st_mtime);
}
if (sz == 0)
tbuf[0] = '\0';
- snprintf(buf, sizeof buf, "%s %3d %-8.8s %-8.8s %8llu %s %s", mode,
- st->st_nlink, user, group, (u_int64_t)st->st_size, tbuf, name);
+ 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,
+ (u_int64_t)st->st_size, tbuf, name);
return xstrdup(buf);
}
-void
+static void
process_readdir(void)
{
DIR *dirp;
stats = xrealloc(stats, nstats * sizeof(Stat));
}
/* XXX OVERFLOW ? */
- snprintf(pathname, sizeof pathname,
- "%s/%s", path, dp->d_name);
+ snprintf(pathname, sizeof pathname, "%s%s%s", path,
+ strcmp(path, "/") ? "/" : "", dp->d_name);
if (lstat(pathname, &st) < 0)
continue;
stat_to_attrib(&st, &(stats[count].attrib));
}
if (count > 0) {
send_names(id, count, stats);
- for(i = 0; i < count; i++) {
+ for (i = 0; i < count; i++) {
xfree(stats[i].name);
xfree(stats[i].long_name);
}
}
}
-void
+static void
process_remove(void)
{
char *name;
xfree(name);
}
-void
+static void
process_mkdir(void)
{
Attrib *a;
xfree(name);
}
-void
+static void
process_rmdir(void)
{
u_int32_t id;
xfree(name);
}
-void
+static void
process_realpath(void)
{
char resolvedname[MAXPATHLEN];
xfree(path);
}
-void
+static void
process_rename(void)
{
u_int32_t id;
xfree(newpath);
}
-void
+static void
process_readlink(void)
{
u_int32_t id;
+ int len;
char link[MAXPATHLEN];
char *path;
id = get_int();
path = get_string(NULL);
TRACE("readlink id %d path %s", id, path);
- if (readlink(path, link, sizeof(link) - 1) == -1)
+ if ((len = readlink(path, link, sizeof(link) - 1)) == -1)
send_status(id, errno_to_portable(errno));
else {
Stat s;
-
- link[sizeof(link) - 1] = '\0';
+
+ link[len] = '\0';
attrib_clear(&s.attrib);
s.name = s.long_name = link;
send_names(id, 1, &s);
xfree(path);
}
-void
+static void
process_symlink(void)
{
u_int32_t id;
xfree(newpath);
}
-void
+static void
process_extended(void)
{
u_int32_t id;
/* stolen from ssh-agent */
-void
+static void
process(void)
{
u_int msg_len;
if (buffer_len(&iqueue) < 5)
return; /* Incomplete message. */
- cp = (u_char *) buffer_ptr(&iqueue);
+ cp = buffer_ptr(&iqueue);
msg_len = GET_32BIT(cp);
if (msg_len > 256 * 1024) {
error("bad message ");
in = dup(STDIN_FILENO);
out = dup(STDOUT_FILENO);
+#ifdef HAVE_CYGWIN
+ setmode(in, O_BINARY);
+ setmode(out, O_BINARY);
+#endif
+
max = 0;
if (in > max)
max = in;