Commit 792f4ae7 authored by Niels Möller's avatar Niels Möller
Browse files

* io_output.c: New file, with all the functions that need to knwo

about the internals of struct sftp_output.
* io_input.c: New file, with all the functions that need to knwo
about the internals of struct sftp_input.

Rev: src/sftp/io_input.c:1.1
Rev: src/sftp/io_output.c:1.1
parent 8ac244b3
/* io_input.c */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 2001 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "io.h"
#include "xmalloc.h"
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#define SFTP_MAX_STRINGS 2
struct sftp_input
{
int fd;
UINT32 left;
/* Strings that we own */
UINT8 *strings[SFTP_MAX_STRINGS];
unsigned used_strings;
};
int
sftp_check_input(const struct sftp_input *i, UINT32 length)
{
return (i->left >= length);
}
int
sftp_get_data(struct sftp_input *i, UINT32 length, UINT8 *data)
{
if (sftp_check_input(i, length))
{
UINT8* buf = data;
int j;
while (length)
{
j = read(i->fd, buf, length);
while (-1==j && EINTR==errno) /* Loop over EINTR */
j = read(i->fd, buf, length);
if (-1==j) /* Error, and not EINTR */
return -1; /* Error */
buf += j; /* Move counters accordingly */
length -= j;
i->left -= j;
}
return 1; /* Success */
}
return 0; /* FIXME: Return code? */
}
struct sftp_input *
sftp_make_input(int fd)
{
struct sftp_input *i = xmalloc(sizeof(struct sftp_input));
i->fd = fd;
i->left = 0;
i->used_strings = 0;
return i;
}
void
sftp_input_clear_strings(struct sftp_input *i)
{
unsigned k;
for (k = 0; k < i->used_strings; k++)
sftp_free_string(i->strings[k]);
i->used_strings = 0;
}
void
sftp_input_remember_string(struct sftp_input *i, uint8_t *s)
{
assert(i->used_strings < SFTP_MAX_STRINGS);
i->strings[i->used_strings++] = s;
}
int
sftp_get_eod(struct sftp_input *i)
{
return !i->left;
}
/* Returns 1 of all was well, 0 on error, and -1 on EOF */
int
sftp_read_packet(struct sftp_input *i)
{
UINT8 buf[4];
int bytesread = 0;
if (i->left) /* Unread data? */
{
UINT8 d;
while (i->left && /* Data remaining? */
0<sftp_get_data(i, 1, &d) /* Read OK? */
)
;
/* Now, there shouldn't be any more data remaining. Next time
* we're called, the next packet should be read (or we had an
* error and all data is not read, if that's the case, return
* error).
*/
if (i->left) /* i->left non-zero => sftp_get_data failed => error */
return -1;
return 0;
}
/* First, deallocate the strings. */
sftp_input_clear_strings(i);
while (bytesread < sizeof(buf))
{
int j = read(i->fd, buf+bytesread, sizeof(buf)-bytesread);
while(-1==j && EINTR==errno) /* Loop over EINTR */
j = read(i->fd, buf+bytesread, sizeof(buf)-bytesread);
if (-1==j) /* Not EINTR but a real error */
return -1;
if (j == 0)
/* EOF */
return bytesread ? 0 : -1;
bytesread += j;
}
i->left = READ_UINT32(buf); /* Store packet size */
return 1;
}
/* io_output.c */
/* lsh, an implementation of the ssh protocol
*
* Copyright (C) 2001 Niels Mller
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "io.h"
#include "xmalloc.h"
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
struct sftp_output
{
int fd;
/* The message type is the first byte of a message, after the
* length. */
UINT8 msg;
/* The next word is either the id, or the version. */
UINT32 first;
/* The rest of the packet is variable length. */
UINT8 *data;
UINT32 size;
UINT32 i;
};
/* The first part of the buffer is always
*
* uint32 length
* uint8 msg
* uint32 id/version
*/
struct sftp_output *
sftp_make_output(int fd)
{
struct sftp_output *o = xmalloc(sizeof(struct sftp_output));
o->fd = fd;
o->data = NULL;
o->size = 0;
o->i = 0;
return o;
}
void
sftp_set_msg(struct sftp_output *o, UINT8 msg)
{
o->msg = msg;
}
void
sftp_set_id(struct sftp_output *o, UINT32 id)
{
o->first = id;
}
static void
sftp_check_output(struct sftp_output *o, UINT32 length)
{
UINT32 needed = o->i + length;
if (!o->data || (needed > o->size))
{
UINT32 size = 2 * needed + 40;
o->data = xrealloc(o->data, size);
o->size = size;
}
}
void
sftp_put_data(struct sftp_output *o, UINT32 length, const UINT8 *data)
{
sftp_check_output(o, length);
memcpy(o->data + o->i, data, length);
o->i += length;
}
void
sftp_put_uint8(struct sftp_output *o, UINT8 value)
{
sftp_check_output(o, 1);
o->data[o->i++] = value;
}
uint8_t *
sftp_put_start(struct sftp_output *o, uint32_t length)
{
sftp_check_output(o, length);
return o->data + o->i;
}
void
sftp_put_end(struct sftp_output *o, uint32_t length)
{
o->i += length;
}
uint32_t
sftp_put_reserve_length(struct sftp_output *o)
{
UINT32 index;
sftp_check_output(o, 4);
index = o->i;
o->i += 4;
return index;
}
void
sftp_put_length(struct sftp_output *o,
UINT32 index,
UINT32 length)
{
assert( (index + 4) < o->i);
WRITE_UINT32(o->data + index, length);
}
void
sftp_put_final_length(struct sftp_output *o,
UINT32 index)
{
sftp_put_length(o, index, o->i - index - 4);
}
void
sftp_put_reset(struct sftp_output *o,
UINT32 index)
{
assert(index < o->i);
o->i = index;
}
int
sftp_write_packet(struct sftp_output *o)
{
int j;
int written = 0;
UINT32 length = o->i + 5;
UINT8 buf[9];
WRITE_UINT32(buf, length);
buf[4] = o->msg;
WRITE_UINT32(buf + 5, o->first);
/* Write 9 bytes from buf */
while (written<9)
{
j = write(o->fd, buf+written, 9-written);
while (-1==j && errno==EINTR) /* Loop over EINTR */
j = write(o->fd, buf+written, 9-written);;
if (-1==j) /* Error, and not EINTR */
return -1; /* Error */
written += j; /* Move counters accordingly */
}
/* Write o->i bytes from data */
written = 0; /* Reset counter */
while (written<o->i)
{
j = write(o->fd, o->data+written, o->i-written);
while (-1==j && errno==EINTR) /* Loop over EINTR */
j = write(o->fd, o->data+written, o->i-written);;
if (-1==j) /* Error, and not EINTR */
return -1; /* Error */
written += j; /* Move counters accordingly */
}
o->i = 0;
return 1;
}
int
sftp_packet_size(struct sftp_output* out)
{
return out->i;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment