#ifndef CLIENT_H
#define CLIENT_H
#include "config.h"
#include "terminal.h"

#ifndef un_char
#define un_char unsigned char
#endif
/*define BUFFER_SIZE 16384*/

struct Buffer {
    un_char * data;
    int start, end;
    int size;
    int alloced;
    };

#define C_SWITCH        '@'

/* Client commands.  If you need to reserve a something for a patch you
 * are working on, let me know.  If we run out, we can start going to
 * two character commands for less common commands.  If you don't absolutely
 * need to add something don't as this breaks forward compatability. 
 * (forcing people to upgrade...)
 *
 *   (bcr@physics.purdue.edu)
 */

#define C_OPEN		'1'	/* Open a file a file for uploading */
				/* without truncating it. */
#define	C_CLOSE		'2'	/* Close a connection. */
#define C_EXEC		'3'	/* Not used/implemented. */
#define C_PTYEXEC	'4'	/* Fork() a shell attached to a pty. */
#define C_DUMB		'5'	/* Go dumb. Escape all '@' received, */
				/* so no commands are processed. */
#define C_UPLOAD	'6'	/* Open a file for writing, creating */
				/* it if it doesn't exist, truncating */
				/* it if it does. */
#define C_DOWNLOAD	'7'	/* Open a file for reading. */
#define C_SOCKET        '8'	/* Connect to a unix-domain socket. */
#define C_PORT          'A'	/* Connect to a TCP/IP port on the */
				/* specified host, and port number. */
#define C_PRIORITY      'B'	/* Raise/lower the priority of this */
				/* client. */
#define C_COMPRESS	'C'  	/* note, i jumped B :) (croutons). */
				/* Turn compression on or off. */
#define C_STAT          'D'	/* Get information on a remote file. */
#define C_SEEK          'E'	/* Execute an lseek() on the remote */
				/* file descriptor. Assumes the remote */
				/* is a file handle, and not a socket. */
#define C_STATS         'F'	/* Get information on various parts of */
				/* term.  */
#define C_NAME          'G'	/* Set the name of this client. Only */
				/* used by C_STATS. */
#define C_RESIZE        'H'	/* For handleing SIGWINCH */
#define C_CLIENTNUM     'I'	/* Not used. Obselete. */
#define C_BIND          'J'	/* Bind a remote socket. */
#define C_ACCEPT        'K'	/* Accept a connection from a remotely */
				/* bound sockets. */
#define C_DUMP          'L'	/* Go dumb for the next 'n' bytes. */
#define C_CLCLOSE       'M'     /* Close the remote fd when the */
				/* buffers have been emptied. */
#define C_QUIT          'N'	/* Shutdown term. */
#define C_BINDN         'U'     /* Bind a remote unspecified socket. -ot */
#define C_BINDS         'S'     /* Allow connects one time only from a tcpip */
                                /* socket... */
/*                      'V'        Reserved for udp support */
#define C_X_SERVER	'X'	/* Open connection to X server */
#define C_SEND          'Z'     /* Send a message to a tcpip socket */

#define C_GETSOCKNAME   'a'     /* Get the sockaddr */
#define C_GETPEERNAME   'b'     /* Get the peername */
#define C_GETHOSTNAME   'c'     /* Get the hostname */

/* Return status */

#define I_FAIL		'a'
#define I_CLOSE		'b'
#define I_EXIT		'c'
#define I_OK		'd'

/* Prototypes */

int read_into_buff(int fd, struct Buffer *, int);
int write_from_buff(int fd, struct Buffer *, int);

int do_read_into_buff(int fd, struct Buffer *, int);

void set_share_mode(void);
int socket_connect_server(int,char *);
int connect_server(char *);

void set_nonblock(int);
void set_block(int);

void set_ttyraw(int);
void set_ttynormal(int);

typedef int (*Callback) ( char, char *);

int client_options(int argc, char *argv[], char *myopts, Callback callback);

#ifdef USE_VARARGS
int send_command();
#else
int send_command(int, int, int, char *, ...);
#endif

char * build_arg(char**);
extern int priority;

int open_unix(char *);
int connect_unix(int,char *);
int bind_tcp( int );
int bind_unix(char *);
void do_select_loop(int, int, int);
extern char *term_server;

extern char *command_result;

int eaccess(char *pathname, int mode);

void do_connect(int num, int *svs, int (*get_server)(int n)); /* -ot */

int term_rcmd(char **ahost,unsigned short inport, char *locuser,
  char *remuser, char *cmd, int *fd2p);
struct hostent *term_gethostbyname(char *name);
struct hostent *term_gethostbyaddr(char *addr, int len, int type);
void term_close_fd(int fd);
int term_shutdown(int fd,int how);
int term_close(int fd);
int term_listen(int fd, int backlog);
/* int term_sendto(int s, void *msg, int  len, unsigned  int flags,
  struct sockaddr *to, int tolen); */
/* int term_accept(int s, struct sockaddr *addr, int *addrlen); */
/* int term_bind(int s, struct sockaddr *my_addr, int addrlen); */
/* int term_connect(int s, struct sockaddr *addr, int addrlen); */
/* int term_getpeername(int s, struct sockaddr *name, int *namelen); */
/* int term_getsockname(int s, struct sockaddr *name, int *namelen); */

#endif
