/*
 * $Id: user.h,v 1.4 1999/01/26 16:29:03 labovit Exp $
 */

#ifndef _USER_H
#define _USER_H

#include <New.h>
#include <linked_list.h>

#define UII_DEFAULT_PORT 5674


#define UII_OUTPUT_BUFFER_SIZE	4096*100

#define UII_UNPREV 	        0
#define UII_NORMAL              1
#define UII_CONFIG              2
#define UII_CONFIG_ROUTER       3	/* obsolete */
#define UII_CONFIG_ROUTE_MAP    4
#define UII_CONFIG_INTERFACE    5
#define UII_CONFIG_NETWORK_LIST 6	/* used in bgpsim */
#define UII_CONFIG_ROUTER_RIP   7
#define UII_CONFIG_ROUTER_RIPNG 8
#define UII_CONFIG_ROUTER_BGP   9
#define UII_CONFIG_ROUTER_OSPF 10
#define UII_PROMPT_MORE        11	/* --more-- */
#define UII_MAX_STATE	       12	/* the last plus one */

#define UII_ALL	       	       98	/* match with all levels except 0 */
#define UII_CONFIG_ALL	       99	/* match with all levels 
					   more than UII_CONFIG */
#define UII_EXIT	     1000	/* user connection has terminated */

#define COMMAND_NORM		0
#define COMMAND_NODISPLAY	1
#define COMMAND_DISPLAY_ONLY	2
#define COMMAND_MATCH_FIRST	4	/* for password and comments -- 
					     match if any of command matches */
					 
/* options to set in uii */
enum UII_ATTR {
    UII_NULL = 0,
    UII_PROMPT,			/* the default prompt */
    UII_ACCESS_LIST,		/* Access list number */
    UII_PASSWORD,		/* Password for telnet access */
    UII_PORT,			/* Port to listen on */
    UII_ADDR,			/* Address to listen at */
    UII_INITIAL_STATE,		/* what state do we start in */
    UII_DISABLED		/* UII access disabled */
};

typedef struct _uii_t {
    trace_t *trace;
    int sockfd;			/* socket for connectoin requests */
    int port; 			/* port to listen on */ 
    prefix_t *prefix;		/* address to listen at */
    int disabled;		/* UII telnet access is disabled */
    LINKED_LIST *ll_uii_commands;
    LINKED_LIST *ll_uii_connections;
    char *prompts[UII_MAX_STATE];
    int initial_state;
    char *service_name;		/* what we are called in /etc/services */
    int access_list;		/* access list to check before accepting telnets */
    char	*password;	/* password "securing" the telnet connection */
    char	*redirect;	/* directory able to redirect */
} uii_t;

typedef struct _uii_connection_t {
    int state;
    int prev_state;
    int sockfd;
    char buffer[MAXLINE];
#define MAXHIST 20
    char cmds[MAXHIST][MAXLINE];
    int cmdcp;			/* number of current cmd */
    int cmdend;			/* end of cmd history */
    char tmp[MAXLINE];
    char *cp;			/* pointer to cursor in line */
    char *end;			/* pointer to end of line */
    int negative;		
    char *comment;		/* pointer to comment */
  /*  int show;			 the command is being called from show config */ 
    int protocol;		/* will be obsolete */

    LINKED_LIST *ll_tokens;

    /* used when a uii requests gobs of data from another thread 
     * that thread fills in a buffer and signals the waiting thread
     */
#ifdef HAVE_LIBPTHREAD
    pthread_cond_t      cond;
    pthread_mutex_t     mutex_cond_lock;
#endif /* HAVE_LIBPTHREAD */
    char *answer;
    int	answer_len;
    int	tty_current_line;	/* current line of the tty */
    int tty_max_lines;		/* max number of lines on telnet tty */

    schedule_t *schedule;
    prefix_t *from;
    int sockfd_out;		/* used for console output and  redirection */

    /* telnet negotiation stuff */
    int telnet;
    u_char telnet_buf[15];

    pthread_mutex_t       *mutex_lock_p; /* grab a lock for config mode */
    char *more;		/* resume point */
    int retries;		/* password retries */
} uii_connection_t;

/* typedef int (*uii_call_fn_t)(uii_connection_t *, ...); */
typedef int (*uii_call_fn_t)();

/* Each object submits a list of commands that is will respond to */
typedef struct _uii_command_t {
    char string[MAXLINE];
    uii_call_fn_t call_fn;
    int state;			/* UII_UNPREV, UII_NORMAL, UII_CONFIG, etc */
    int flag;			/* COMMAND_NORM, COMMAND_NODISPLAY, etc */
    char *explanation;		/* helpful text on what this command does */
    LINKED_LIST *ll_tokens;	/* instead of a string, list of tokens to match on */
    schedule_t *schedule;	/* schedule it if expected so */
} uii_command_t;


extern uii_t *UII;

int uii_add_command (int state, char *cmd, uii_call_fn_t call_fn);
int uii_add_command2 (int state, int flag, char *string, 
		      uii_call_fn_t call_fn, char *explanation);
int uii_add_command_schedule (int state, int flag, char *string,
      uii_call_fn_t call_fn, char *explanation, schedule_t *schedule);
int uii_proccess_command (uii_connection_t * uii);
uii_t *New_UII (trace_t * ltrace);
int uii_send_data (uii_connection_t * uii,...);
int init_uii (trace_t * trace);
int listen_uii ();
int listen_uii2 (char *port);
char *uii_parse_line (char **line);
char *uii_parse_line2 (char **line, char *word);
int parse_line (char *line, char *format, ...);
int set_uii (uii_t *, int, ...);
int uii_check_passwd (uii_connection_t *uii);
char *strip_spaces (char *tmp);
int uii_show_timers (uii_connection_t *uii);
void signal_uii_data_ready (uii_connection_t *uii);
uii_command_t *uii_match_command (uii_connection_t *uii);
int uii_show_help (uii_connection_t *uii);
int uii_add_bulk_output (uii_connection_t *uii, char *format, ...);
int uii_add_bulk_output_raw (uii_connection_t *uii, char *string);
void uii_send_bulk_data (uii_connection_t * uii);
void uii_command_tab_complete (uii_connection_t *uii, int alone);
int uii_destroy_connection (uii_connection_t * connection);
void user_notice (int trace_flag, trace_t *tr, uii_connection_t *uii,
             char *format, ...);
void print_error_list (struct _uii_connection_t *uii, trace_t *tr);

#endif /* _USER_H */
