#ifndef __BIT_TYPES_DEFINED__
#define u_int8_t unsigned char
#define u_int16_t unsigned short
#define u_int32_t unsigned int
#endif

#define LINESIZE 128
#define BUFSIZE 4096
#define MAXARGS 20

#ifndef MIN
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#endif

#define MAXCHANNEL 255

#define skipspaces(s) {while (s && *s && isspace(*s)) s++;}

/* Server commands */
#define CHDIR		10	/* CHDIR <dir>		*/
#define GETDIR		11	/* GETDIR		*/
#define TELLDIR		12	/* TELLDIR		*/

/* File transfer setup oriented commands */
#define SENDFILE	15	/* SENDFILE <channel>	*/
#define NOFILEMATCH	16	/* NOFILEMATCH 		*/

/* Data stream oriented commands */
#define FILESIZE	20	/* FILESIZE <size>	*/
#define FILEMODE	21	/* FILEMODE <mode>	*/
#define DATA		22	/* DATA <data>		*/
#define ENDDATA		23	/* ENDDATA		*/
#define FILEOK		24	/* FILEOK <status>	*/
#define STREAM		25	/* STREAM		*/
#define REQUEST		26	/* REQUEST <name>	*/
#define FILENAME	27	/* FILENAME <name>	*/
#define EXEC		28	/* EXEC <command>	*/

/* Other commands */
#define ERROR		30	/* ERROR <string>	*/
#define SUCCESS		31	/* SUCCESS		*/
#define CLOSE		32	/* CLOSE		 */

typedef struct {
	char *str;
	int (*func) (char **, int);
} map;

typedef struct {
	u_int8_t channel;
	u_int8_t command;
	u_int32_t len;
	void *data;
} message;

typedef u_int8_t sftp_channel_t;
typedef u_int8_t sftp_command_t;

typedef struct {
	int (*accept_data)(sftp_channel_t c, message m);
	int (*send_data)(sftp_channel_t c);
	void *data;
	int waiting_to_send;
} sftp_channel;

typedef struct {
	char *name;
	int fd;
	int size;
	int count;
} sftp_file;

sftp_channel_t new_sendfile_channel(char *name);
void close_sendfile_channel(sftp_channel_t c);

sftp_channel_t new_recvfile_channel(sftp_channel_t c);
void close_recvfile_channel(sftp_channel_t c);

sftp_channel_t new_exec_channel(char *command, int len);
void close_exec_channel(sftp_channel_t c);

int tokenize(char *str, char **args, int maxargs);
char *findbasename(char *str);

int do_action (char *str, map *action);

message _message(u_int8_t command, void *data, u_int32_t len);
message _data_message(u_int8_t channel, u_int8_t command, void *data,
		      u_int32_t len);

int readn(int fd, void *buf, size_t count);
int send_message(int sock, message m);
int recv_message(int sock, message *m);
int query_message(int sock, message *m);

int do_sendfile (int sock, char *file);
int do_recvfile (int sock, u_int8_t channel);

struct timeval timediff(struct timeval tv1, struct timeval tv2);

u_int16_t strtomode(char *str);
void modetostr(u_int16_t mode, char *str);

sftp_channel *new_channel();

