/*
 * This is Ping-Pong convers/conversd derived from the wampes
 * convers package written by Dieter Deyke <deyke@mdddhd.fc.hp.com>
 *
 * Modifications by Fred Baumgarten <dc6iq@insu1.etec.uni-karlsruhe.de>
 * $Revision: 2.99 $$Date: 1994/10/02 10:33:12 $
 */

#ifndef SOMAXCONN
#define SOMAXCONN       5
#endif

#ifndef WNOHANG
#define WNOHANG         1
#endif

#ifdef POSIX
#define FD_SET_TYPE fd_set
#endif

#ifndef FD_SET_TYPE
#define FD_SET_TYPE struct fd_set
#endif

#if defined(__TURBOC__) || defined(__STDC__)
#define __ARGS(x)       x
#ifndef __DOTS
#define __DOTS		,...
#endif
#else
#define __ARGS(x)       ()
#define const
#ifndef __DOTS
#define __DOTS
#endif
#endif

#ifndef min
#define min(a,b) ((a) >= (b) ? (b) : (a))
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif

#define MAXCHANNEL      32767
#define uchar(x) ((x) & 0xff)

struct mbuf {
  struct mbuf *next;
  char *data;
};

struct clist {
  int channel;			/* channel number */
  int channelop;		/* channel operator status */
  long time;			/* join time */
  struct clist *next;		/* pointer to next entry */
};

#define NULLCLIST ((struct clist *) 0)

struct connection {
  int type;                     /* Connection type */
#define CT_UNKNOWN      0
#define CT_USER         1
#define CT_HOST         2
#define CT_CLOSED       3
  char name[64];                /* Name of user or host */
  char host[64];                /* Name of host where user is logged on */
  char rev[64];                 /* revision of software (CT_HOST) */
  struct connection *via;       /* Pointer to neighbor host */
  int channel;                  /* current channel number */
  struct clist *chan_list;	/* linked list of joined channels */
  long time;                    /* Connect time */
  int locked;                   /* Set if mesg already sent */
  int fd;                       /* Socket descriptor */
  char ibuf[2048];              /* Input buffer */
  int icnt;                     /* Number of bytes in input buffer */
  struct mbuf *obuf;            /* Output queue */
  int received;                 /* Number of bytes received */
  int xmitted;                  /* Number of bytes transmitted */
  char away[512];               /* Away string */
  int amprnet;			/* is it /..UDAT (1) or /..USER (0) ? */
  long atime;                   /* time of last "away" state change */
  long mtime;                   /* time of last message receive */
  char pers[512];               /* Personal string */
  int verbose;                  /* verbose mode */
  char prompt[4];               /* prompt mode */
  char query[64];               /* name of queried user */
  char notify[512];             /* List of calls you like to be notified */
  int charset_in;               /* charset - default ISO (ansi) */
  int charset_out;              /* charset - default ISO (ansi) */
  int channelop;		/* channel operator of current channel ? */
  int operator;			/* convers operator */
  int expected;			/* expected answer */
  int invitation_channel;	/* last invitation was from this channel */
  int width;			/* user screen width */
  struct connection *next;      /* Linked list pointer */
};

#define CM_UNKNOWN   (1 << CT_UNKNOWN)
#define CM_USER      (1 << CT_USER)
#define CM_HOST      (1 << CT_HOST)
#define CM_CLOSED    (1 << CT_CLOSED)

#define NULLCONNECTION  ((struct connection *) 0)

#define NR_PERMLINKS 20

struct permlink {
  char name[80];                /* Name of host */
  char socket[80];              /* Name of socket to connect to */
  char command[256];            /* Optional connect command */
  struct connection *connection;/* Pointer to associated connection */
  long statetime;               /* Time of last (dis)connect */
  int tries;                    /* Number of connect tries */
  long waittime;                /* Time between connect tries */
  long retrytime;               /* Time of next connect try */
  long testwaittime;            /* Time between tries */
  long testnexttime;            /* Time of next test */
  long rxtime;                  /* rtt by other side */
  long txtime;                  /* rtt found out by me */
  int quality;			/* quality of given link */
  int group;			/* link list group */
  int permanent;		/* this is a permanent entered link */
};

#define NULLPERMLINK  ((struct permlink *) 0)

extern struct permlink *permarray[NR_PERMLINKS];

struct destination {
  char name[80];		/* destination name */
  char rev[64];                 /* revision of software (CT_HOST) */
  struct permlink *link;	/* link to this destination */
  long rtt;			/* round trip time to this host */
  long last_sent_rtt;		/* last donwnstream sent rtt */
  int downstream[NR_PERMLINKS];	/* all up/downstream times */
  struct destination *next;	/* a one dimansional list is ok for now :-) */
};

#define NULLDESTINATION  ((struct destination *) 0)

struct channel {
  char name[80];		/* ascii name of channel */
  char topic[512];		/* topic of channel */
  long time;			/* when was the topic set ? */
  int chan;			/* integer value of channel (<32768 !) */
  int flags;			/* channel flags */
#define M_CHAN_S 0x01	/* secret channel - number invisible */
#define M_CHAN_P 0x02	/* private channel - only join by invitation */
#define M_CHAN_T 0x04	/* topic settable by operator only */
#define M_CHAN_I 0x08	/* invisible channel - only sysops can see */
#define M_CHAN_M 0x10	/* moderated channel - operators may talk */
#define M_CHAN_L 0x20	/* local channel - no forwarding */
  struct channel *next;		/* linked list again */
};

#define NULLCHANNEL  ((struct channel *) 0)

struct cmdtable {
  char *name;
  void (*fnc)();
  char *help;
  int states;
};

extern void appendstring __ARGS((struct connection *cp, const char *string));
extern void appendc __ARGS((struct connection *cp, const int n, const int ast));
extern void appendprompt __ARGS((struct connection *cp, const int ast));
extern void destroy_channel __ARGS((int number));
extern void free_connection __ARGS((struct connection *cp));
extern int queuelength __ARGS((const struct mbuf *bp));
extern void free_closed_connections __ARGS((void));
extern char *getarg __ARGS((char *line, int all));
extern char *getargcs __ARGS((char *line, int all));
extern char *formatline __ARGS((char *prefix, char *text, int linelen));
extern char *ts __ARGS((long gmt));
extern char *ts2 __ARGS((long gmt));
extern char *ts3 __ARGS((long seconds, char *buffer));
extern char *ts4 __ARGS((long seconds));
extern struct connection *alloc_connection __ARGS((int fd));
extern void accept_connect_request __ARGS((int flisten));
extern void clear_locks __ARGS((void));
extern int count_user __ARGS((int channel));
extern void send_awaymsg __ARGS((char *name, char *host, int channel, long time, char *text));
extern void send_mode __ARGS((struct channel *chan));
extern void send_opermsg __ARGS((char *name, char *host, char *from, int channel));
extern void send_persmsg __ARGS((char *name, char *host, int channel, char *text, long time));
extern void send_topic __ARGS((char *name, char *host, long time, int channel, char *text));
extern void send_user_change_msg __ARGS((char *name, char *host, int oldchannel, int newchannel, char *pers, long time));
extern void send_msg_to_user __ARGS((char *fromname, char *toname, char *text));
extern void send_msg_to_channel __ARGS((char *fromname, int channel, char *text));
extern void send_invite_msg __ARGS((char *fromname, char *toname, int channel));
extern void log_user_change __ARGS((char *name, char *host, int oldchannel, int newchannel));
extern void update_destinations __ARGS((struct permlink *p, char *name, long rtt, char *rev));
extern struct permlink *update_permlinks __ARGS((char *name, struct connection *cp, int isperm));
extern void connect_permlinks __ARGS((void));

extern struct connection *connections;
extern struct permlink *permlinks;
extern struct permlink *notpermlinks;
extern struct destination *destinations;
extern struct channel *channels;

extern long boottime;
extern long currtime;
extern char *myhostname;
extern char userfile[];
extern char motdfile[];
extern char convtype[];
extern char myrev[];
extern char myfeatures[];
extern int amprnet;
extern int secretnumber;
