/* */

#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <strings.h>
#include <sys/ioctl.h> /**/

#include "network.h"
#include "messages.h"

void log_trans(char *line);

void send_connections(void);

void proc_trans(void);
int parse_trans();
int hdl_transact(CONN *conn);


int      cur_sock;
int max_stale_time; /* in shutdown mode wait until all conn have been 
		       inactive for this many minutes */
static int      next_id;
static char     in_buff[BUFSIZ];
static int      full_format = FALSE;
static int      format_type;
static CONN     *currconn; /* this is not always correct because of LWPs so
			      be careful how you use it */
extern CONN     conntab[];
extern int      PENDING_SHUTDOWN;
extern char     *shutdown_msg;
extern char     *alt_banner;
extern int ALT_BANNER;
extern int      debug;
extern int      errno;
extern char     *msglist[]; /* the list of error messages */
extern char     *next_field();
extern void     add_recv(int fd, char *file_name, int sock);
extern void     log_read(char *line);

extern void     change_token(char *line, int token_no,char *value);

static char    *uid; /* the user id who sent the current transaction */
static char    *trans_data; /* everything after the 1st ":" */  
static char     trans_type;

int
hdl_transact(CONN *conn)
{
	char            log_line[BUFSIZ];
	int             length;

	currconn = conn;
	cur_sock = conn->c_socket;
	uid = conn->c_uid;
	conn->c_trans_cnt++; 
	bzero(in_buff, BUFSIZ);
	length = read(cur_sock, in_buff, BUFSIZ);
	if (length <= 0) {
	  if (length)
	    perror("socket read");
	  /*                if (errno == EWOULDBLOCK)
			    return 0;
			    else 
	   This caused looping error -ST */
	  return 1;
	}
	if (in_buff[length - 1] == LF)
		length--;
	if (in_buff[length - 1] == CR)
		length--;
	in_buff[length] = '\0';

	if (!parse_trans() || length == 0)
		return 1;	/* quit and close connection */
	log_trans(log_line);	/* log the transaction */
	proc_trans();
	return 0;		/* ok */
}

int
parse_trans()
{
	char           *c;

	trans_type = *in_buff;
	c = (char *) index(in_buff, DLM);
	if (c)
		trans_data = c + 1;
	else if (in_buff[1] && trans_type)
		trans_data = in_buff + 1;
	else
		trans_data = "";
	if (debug)
	  printf("Transaction(type=`%c' data=[%s])\n", trans_type, trans_data);
	if (trans_type == T_QUIT)
		return 0;
	return 1;
}

/* Switch on transaction type, calling handler procedure */
void
proc_trans(void)
{
	char *          get_source_info(char *str);
	char            *src_line,*cp;
	int rc;
	switch (trans_type) {

	case T_SHOW_CONN: /* show the connections */ {
	  send_connections();
	  break;
		}
		default:
		send_msg(msglist[ HUH ]);

	}
}

#define BUFFERSIZE (200 + FD_SETSIZE*110)

/* Send a description of the current connections */
void
send_connections(void) 
{
  int i;
  char *buf, *prov, *cp;
  time_t  secs;

  
  buf = (char *) domalloc((unsigned) BUFFERSIZE);
  bzero(buf, BUFFERSIZE);

  sprintf(buf,"Conn #, Sock,                      host,       host type, session len,time inactive, provider?\n");
  
  time(&secs);
  for (i = 0; i < FD_SETSIZE; i++) 
    {
      if (conntab[i].c_socket != -1)
	{
	  cp = (char *) index(buf,'\0');
	  if (conntab[i].c_flags & C_PROVIDER)
	    prov = "PROV";
	  else
	    prov = "";
	  sprintf(cp,"%5d, %5d, %25.25s %15.15s,         %-4.1f,         %-4.1f,       %s\n"
		  ,i,conntab[i].c_socket,
		  conntab[i].c_hostname, 
		  conntab[i].c_type,
		  (float) ((secs - conntab[i].c_made) /60.0),
		  (float) ((secs - conntab[i].c_last) /60.0), prov);
	}
    }
  /* 
   * Put End-of-Message on buffer & send it out.  sendbuf() frees the
   *  buffer for us.
   */
  strcat(buf, EOM);
  sendbuf(buf, strlen(buf), cur_sock);
}
#undef BUFFERSIZE

/* write the transaction to the log file */
void
log_trans(char *line)
{
        int     dfd;
	char            logline[BUFSIZ];
	time_t          secs;

	time(&secs);
	sprintf(logline, "%s:%s", line, ctime(&secs));
	if ((dfd = open(TRANS_LOG, O_APPEND | O_CREAT | O_WRONLY, 0644)) == 0)
		printf("error logging transaction\n");
	write(dfd, logline, strlen(logline));
	close(dfd);
	return;
}

