/****************************************************************************/
/*  psfilter.c  version 1.05                                                */ 
/*  Copyright(c) 1996.  All Rights Reserved.                                */
/****************************************************************************/

/*****************************************************************************/
/*  The program is the client program on UNIX hosts,  which communicates with*/
/*  the printer server through TCP/IT.                                       */
/*                                                                           */
/*  Log Histroy:                                                             */
/*  12/13/93  KMY  --Created the program.                                    */
/*  03/25/94  KMY  --Modified the program so that no alarm for write timeout */
/*                   is set if infinite delay of printer is allowed.         */
/*  09/09/94  KMY  --Extracted all messages to errormsg.h                    */
/*  09/04/95  KMY  --Added -o and -r options for 3P_1S.                      */
/*  01/30/96  KMY  --Added -z option for WAIT_PRINTER_BUSY.                  */
/*                                                                           */ 
/*****************************************************************************/
#define BSD 0     
#define SVR3 0     
#define SVR4 1     
#define HP 0     
#define AIX 0     
#define OSF1 0     

#if OSF1
#define __STDC__
#endif


#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <sys/times.h>
#include <sys/time.h>
#include "errormsg.h"

#if BSD
extern size_t fread();
#endif

#if OSF1
#define BSD 1     
#endif


#if BSD
#include <sys/errno.h>
#define printer_error  2
#define CANCELSIG     SIGINT
#endif


#if SVR3
#define printer_error  129
#define CANCELSIG     SIGTERM
#endif

#if SVR4
#include <sys/errno.h>
#define printer_error  129
#define CANCELSIG     SIGTERM
#endif

#if  HP
#include <sys/errno.h>
#define printer_error  2
#define CANCELSIG     SIGTERM
#endif

#if AIX 
#include <sys/errno.h>
#include <sys/select.h>
#include <IN/standard.h>
#define printer_error  EXITFATAL
#define CANCELSIG     SIGTERM
#endif


#if AIX
#define pm_error    EXITERROR 
#define cancel_exit EXITSIGNAL     
#else
#define pm_error         1
#define cancel_exit      0
#endif

#define FALSE  0
#define TRUE   1

#define PARALLEL   3000
#define HIGHSPEED  3010
#define SERIAL     3020
#define PARA3      3030

#define MARK	     0xff
#define PM_RESERVE   0x80
#define PM_STA_7     0x40
#define PM_STA_6     0x20
#define PM_STA_5     0x10
#define PM_STA_4     0x08
#define PM_MEN_FULL  0x04
#define PM_PDRT_BUSY 0x02
#define PM_IN_USE    0x01


#define PRT_NOT_BUSY  0x80
#define PRT_STA_7     0x40
#define PRT_OUT_PAPER 0x20
#define PRT_SELECT    0x10
#define PRT_IO_ERR    0x08
#define PRT_STA_3     0x04
#define PRT_STA_2     0x02
#define PRT_TIME_OUT  0x01


#define BUFSIZE        512 
#define NUM_OF_PORTS     4



/* answer type */
#define ACCEPT       0   /* You can send file right now. */
#define BUSY         1
#define REJECT       2   /* Error condition. Abort the print job */
#define ERROR        3
#define FORMAT_ERROR 4
#define PM_BUSY      5

#define UNKNOWN     -3
#define SEL_TIMEOUT -2

#define BUSY_INTERVAL       20  
#define WAIT_PRT_IO_ERR     60
#define WAIT_READ          600
#define TRY_READ_STATE      10

#define UNKNOWN_TIMEOUT      0
#define CONNECT_TIMEOUT      1
#define SENDDATA_TIMEOUT     2
#define READDATA_TIMEOUT     3

#define AllPorts            0
#define SinglePort          1

typedef struct info_type {
	unsigned char prt;
	unsigned char pm;
} info_t;


typedef struct packet_type {
	unsigned char premark;
	info_t        parallel;
	info_t        highspeed;
	info_t        serial;
        info_t        para3;
	unsigned char sufmark;
} packet_t;


typedef struct port_list_type {
	int ports[NUM_OF_PORTS];
	int index;
	int count;
} port_list_t;


typedef struct state_buf_type {
	unsigned char buf[32];
	int          cnt;
} state_buf_t;

int TRY_CONNECT_PORTS;
int TRY_CONNECT_A_PORT;
int WAIT_STATE_PACK;
int WAIT_SEND;
int CNET_FAIL_NUM;
int  DEBUG;
int LOGF;
int is_debug;
int is_logf;

char *dest;
int curr_port;
int default_port;
char *prestr;
char *sufstr;
char *other_ports;
int  delay_min;
int  delay_cnt;
int  timeout_flag;
port_list_t port_list;
int  busy_nw;
int  text_mode;
int WAIT_PRINTER_BUSY;

FILE *logfd;
FILE *errfd;
FILE *headfd;
FILE *tailfd;
FILE *confd;

int  sockfd;
struct sockaddr_in server;
struct hostent     *ServerHost;
state_buf_t state_buf;
int state_pack_size;
int large_state_pack_size;
int TOTAL_DATA;
char sendbuf[BUFSIZE];
char argbuf[BUFSIZE];
packet_t glo_state_pack;

char *log_fname;
char *err_fname;
char *headfn;
char *tailfn;
int  is_confg_file;
char *confg_fname;
char confg_default[]=".pmopts";
char log_template[]="/tmp/PMfilterXXXXXX";
char err_template[]="/tmp/PMErrLogXXXXXX";
char *err_mark;

/* rember the last character of the read_buffer for CR/LF conversion */
char prev_char;

extern int errno;

char *reroute_ports;
void create_reroute_list();
int is_in_port_list();

char *str_cpy();
extern char *mktemp();
int ClientInit();
int ServerInit();
int CnetMgnt();
int SendMgnt();
int SendStr();
int QuitMgnt();
int ParserState();
int query_status();
int cnet_and_parse_state();
int get_other_port();
int recv_1st_state();
int recv_state();

int get_opts_from_file(  );
int read_line();
char *get_argment();
void append_to_argbuf();

void create_port_list();
int append_to_port_list();
int next_port();
void reset_port_list();
void print_port_list();

int my_recv();
void partition_hdler();
void append_to_state_buf();
void error_exit();
void print_warning();
int check_state_pack();

void dump_to_logf();
void dump_to_errf();

static void timeout();
static void sigs_hdler();
static void sigcancel_hdler();

size_t read_and_CR_LF_convert();
void check_OEM_mark();


int processPortNo();

#if SVR4
void bcopy();
#endif

main(argc, argv)
int argc;
char *argv[];
{
	int c;
        int i;
	extern char *optarg;
	int state;
	unsigned char *t;
	char *errstr;

	int  l_opt;
	int  w_opt;
	int  f_option;
	int option_count;

	TRY_CONNECT_PORTS=1;
	TRY_CONNECT_A_PORT=3;
	WAIT_STATE_PACK=20;
	WAIT_SEND=300;
        WAIT_PRINTER_BUSY=0;
	DEBUG=0;
	LOGF=0;
        is_debug=FALSE;
        is_logf=FALSE;

        logfd=NULL;
        errfd=NULL;
        headfd=NULL;
        tailfd=NULL;
        confd=NULL;

	sockfd=-1;
	dest=NULL;
	curr_port = HIGHSPEED;
	default_port = HIGHSPEED;
	prestr=NULL;
	sufstr=NULL;
	other_ports=NULL;
	reroute_ports=NULL;
	log_fname=NULL;
	err_fname=NULL;
	delay_min=-1;
	state_buf.cnt=0;
	state_pack_size=8;
	large_state_pack_size=10;
	port_list.index=0;
	port_list.count=0;
	timeout_flag=UNKNOWN_TIMEOUT;
	headfn=NULL;
	tailfn=NULL;
	TOTAL_DATA=0;
        argbuf[0]='\0';

        text_mode=FALSE;
        prev_char=0;
        check_OEM_mark(argv[0]);

	l_opt=FALSE;
	w_opt=FALSE;
	f_option=FALSE;
	confg_fname=str_cpy(confg_default);
	is_confg_file=FALSE;
	busy_nw=FALSE;

#if BSD
        err_mark=lpr_err;
#else
        err_mark=lp_err;
#endif



	option_count=0;
	while ( ( c = getopt(argc, argv, "vxbSPTD:p:s:a:d:h:t:l:w:f:o:r:z:") ) != EOF) {
		switch(c) {
		case 'D':
			dest=str_cpy(optarg);
			break;
		case 'S':
			if ( curr_port == HIGHSPEED ) {
				curr_port=SERIAL;
				default_port=SERIAL;
			}
			else {
				error_exit(pm_error, SP_option_err);
			};
			break;
		case 'P':
			if ( curr_port == HIGHSPEED ) {
				curr_port=PARALLEL;
				default_port=PARALLEL;
			}
			else {
				error_exit(pm_error, SP_option_err);
			};
			break;
                case 'o':
                         curr_port=processPortNo(optarg);
                         if ( curr_port < 0 ) {
                           error_exit(pm_error, port_no_error); 
                         };
                         default_port=curr_port;
                         break;
		case 'p':
			prestr=str_cpy(optarg);
			break;
		case 's':
			sufstr=str_cpy(optarg);
			break;
		case 'h':
			headfn=str_cpy(optarg);
			break;
		case 't':
			tailfn=str_cpy(optarg);
			break;
		case 'a':
			other_ports=str_cpy(optarg);
			break;

		case 'r':
			reroute_ports=str_cpy(optarg);
			break;

		case 'd':
			delay_min=atoi(optarg);
			break;
		case 'z':
			WAIT_PRINTER_BUSY=atoi(optarg);
			break;
		case 'v':
			is_debug=TRUE;
			break;
		case 'x':
			is_logf=TRUE;
			break;
		case 'b':
			busy_nw=TRUE;
			TRY_CONNECT_PORTS=2;
			TRY_CONNECT_A_PORT=6;
			WAIT_STATE_PACK=40;
			WAIT_SEND=600;
			break;
		case 'l':
			l_opt=TRUE;
			break;
		case 'w':
			w_opt=TRUE;
			break;
		case 'f':
			confg_fname=str_cpy(optarg);
			f_option=TRUE;
			break;
                case 'T':
                         text_mode=TRUE; 
                         break;

		case '?':
			error_exit(pm_error, bad_option_err);

		}; /* end of switch */
		option_count++;
	}; /* end of while */

	if ( option_count == 0 )
		is_confg_file=TRUE;

	if ( f_option == TRUE ) {
		if ( option_count == 1 ) {
			is_confg_file=TRUE;
		}
		else {
			error_exit(pm_error, bad_option_err);
		};
	};

	if (l_opt==TRUE || w_opt==TRUE) {
		if (option_count != 2 ) {
			error_exit(pm_error, bad_option_err);
		}
		else {
			if ( l_opt == TRUE && w_opt == TRUE ) {
				is_confg_file=TRUE;
			}
			else {
				error_exit(pm_error, bad_option_err);
			};
		};
	};



	if ( is_confg_file == TRUE ) {
		if ( (confd=fopen(confg_fname, "r")) == NULL ) {
			perror("Printer Filter Error: fopen");


			fprintf(stderr, "%s %s %s. \n", err_mark,cant_open_file,confg_fname);
			fflush(stderr);
			exit( pm_error );
		};

		if ( (i=get_opts_from_file( )) == FALSE ) {
			fprintf(stderr, "%s %s \n", err_mark, confg_err);

			fclose(confd);
			exit( pm_error );
		};
	fclose(confd);
	};


	if (is_logf == TRUE) {
		dump_to_logf();
	};


	if (is_debug == TRUE) {
		dump_to_errf();
	};



	if ( dest == NULL ) {
		error_exit(pm_error, dest_option_err);
	};

        if ( delay_min < 0 ) {
          WAIT_SEND=0;
        }
        else {
          if ( delay_min > 0 ) {
             if ( WAIT_SEND < delay_min*60 ) {
                 WAIT_SEND=delay_min*60;
             };
          };
        } ;
	if ( DEBUG ) {
        	fprintf(errfd,"WAIT_SEND=%d \n",WAIT_SEND);
	};


	if ( headfn != NULL ) {
		if (( headfd=fopen(headfn, "r") ) == NULL ) {

			if (LOGF) {
				fprintf(logfd,"%s can't open file %s for reading. \n",err_mark, headfn);
                         };

			fprintf(stderr,"%s %s %s. \n",err_mark,cant_open_file, headfn);
			if ( DEBUG ) {
				fprintf(errfd,"%s can't open file %s for reading. \n",err_mark, headfn);
			};
			error_exit(pm_error, NULL);
		};
	};

	if ( tailfn != NULL ) {
		if (( tailfd=fopen(tailfn, "r") ) == NULL ) {

			if (LOGF) {
				fprintf(logfd,"%s can't open file %s for reading. \n",err_mark, tailfn);
                        };
			fprintf(stderr,"%s %s %s. \n",err_mark,cant_open_file, tailfn);
			if ( DEBUG ) {
				fprintf(errfd,"%s can't open file %s for reading. \n",err_mark, tailfn);
			};
			error_exit(pm_error, NULL);
		};
	};

	create_port_list();
        CNET_FAIL_NUM=TRY_CONNECT_PORTS*port_list.count;

	if (DEBUG) {
		print_port_list();
                fprintf(errfd, "CNET_FAIL_NUM= %d \n", CNET_FAIL_NUM);
                fflush(errfd);
	};

	delay_cnt=delay_min;

	if ( signal(SIGHUP, SIG_IGN)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGHUP can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGHUP can't be caught! \n");
                fflush(errfd);
		};
	};

	if ( signal(SIGQUIT, SIG_IGN)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGQUIT can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGQUIT can't be caught! \n");
                fflush(errfd);
		};
	};

	if ( signal(SIGALRM, timeout)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGALRM can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGALRM can't be caught! \n");
                fflush(errfd);
		};
	};

	if ( signal(SIGPIPE, sigs_hdler) == SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGPIPE can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGPIPE can't be caught! \n");
                fflush(errfd);
		};
	};


#if BSD        
	if ( signal(SIGINT, sigcancel_hdler)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGINT can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGINT can't be caught! \n");
                fflush(errfd);
		};
	};

	if ( signal(SIGTERM, sigs_hdler)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGTERM can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGTERM can't be caught! \n");
                fflush(errfd);
		};
	};

#else
	if ( signal(SIGINT, SIG_IGN)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGINT can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGINT can't be caught! \n");
                fflush(errfd);
		};
	};

	if ( signal(SIGTERM, sigcancel_hdler)== SIG_ERR) {

		if (LOGF) {
			fprintf(logfd,"WARNING: SIGTERM can't be caught! \n");
                };

		if (DEBUG) {
			fprintf(errfd,"WARNING: SIGTERM can't be caught! \n");
                fflush(errfd);
		};
	};
#endif

	if ( ClientInit()==FALSE ) {
		error_exit(pm_error, NULL);
	};



	state=query_status();


	if (state != ACCEPT ) {
        if ( sockfd >= 0 ) {
		close(sockfd);
                sockfd=-1;
        };
		switch(state) {
		case ERROR:
			errstr=NULL ;
			break;
		case REJECT:
			errstr=prt_err ;
			break;
		default:
			errstr=pack_format_err ;
                        break;
		};
		error_exit(printer_error, errstr);
	};


	t=(unsigned char *)&server.sin_addr;
	if (LOGF) {
		fprintf(logfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(logfd,"Connection to server succeeds! \n");
		fflush(logfd);
	};

	if ( DEBUG ) {
		fprintf(errfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(errfd,"Connection to server succeeds! \n");
		fflush(errfd);
	};

	if ( prestr != NULL ) {
		if (SendStr(prestr) == FALSE)
		{
			error_exit(printer_error, NULL);
		};
	};

	if ( headfd != NULL ) {

		if (LOGF) {
			fprintf(logfd,"Send Head File to server! \n");
                };

		if ( DEBUG ) {
			fprintf(errfd,"Send Head File to server! \n");
                fflush(errfd);
		};

		if (SendMgnt(headfd,FALSE) == FALSE )
		{
			fclose(headfd);
			error_exit(printer_error, NULL);
		};
		fclose(headfd);
	};


	if (LOGF) {
		fprintf(logfd,"Send Data Files to server! \n");
        };
	if (DEBUG) {
		fprintf(errfd,"Send Data Files to server! \n");
                fflush(errfd);
	};
	if (SendMgnt(stdin, text_mode) == FALSE )
	{
		error_exit(printer_error, NULL);
	};


	if ( tailfd != NULL ) {

		if (LOGF) {
			fprintf(logfd,"Send Tail File to server! \n");
                 };

		if (DEBUG) {
			fprintf(errfd,"Send Tail File to server! \n");
                fflush(errfd);
		};
		if (SendMgnt(tailfd, FALSE) == FALSE )
		{
			fclose(tailfd);
			error_exit(printer_error, NULL);
		};
		fclose(tailfd);
	};

	if ( sufstr != NULL ) {
		if (SendStr(sufstr) == FALSE )
		{
			error_exit(printer_error, NULL);
		};
	};
	QuitMgnt();

	exit(0);
} /* end of main */


/****************************** End of Main ********************************/
/****************************** End of Main ********************************/
/****************************** End of Main ********************************/
/**************************************************************************/
/********     check_OEM_mark() *****/
/**************************************************************************/
void check_OEM_mark(program_name)
char *program_name;
 {
  char *strpt;
  int  len;
  len=strlen(program_name);
  strpt=program_name+len-8;
  if ( len >= 8 ) {
    if (strcmp(strpt, "PSfilter") == 0 )
    {
      strcpy( confg_default, ".psopts");
      strcpy(log_template, "/tmp/PSfilterXXXXXX");
      strcpy(err_template, "/tmp/PSErrLogXXXXXX");
    }
  }
}
/**************************************************************************/
/********     dump_to_logf() *****/
/**************************************************************************/
void dump_to_logf() {

	if ( (log_fname=mktemp( log_template ) ) == NULL ) {
		perror("Printer Filter Error: log_file: mktemp");
		exit( pm_error );
	};

	if ( (logfd=fopen(log_fname, "w")) == NULL ) {
		perror("Printer Filter Error: log_file: fopen");
		exit( pm_error );
	};
        LOGF=1;

	if ( dest != NULL )
		fprintf(logfd,"Name of server host: %s \n", dest);

	switch( default_port) {
	case PARALLEL:
		fprintf(logfd,"Port is PARALLEL port 2. \n");
		break;
	case HIGHSPEED :
		fprintf(logfd,"Port is HIGHSPEED parallel port 1.\n");
		break;
	case SERIAL:
		fprintf(logfd,"Port is SERIAL . \n");
		break;
	case PARA3:
		fprintf(logfd,"Port is PARALLEL 3. \n");
		break;
	};

	if ( is_confg_file == TRUE  )
		fprintf(logfd,"Configuration file: %s \n", confg_fname );

	if ( delay_min != -1  )
		fprintf(logfd,"Delay minutes for printer faults: %d \n",delay_min);

	if ( WAIT_PRINTER_BUSY != 0  )
		fprintf(logfd,"Sleep seconds for printer busy: %d \n", WAIT_PRINTER_BUSY);
	if ( other_ports != NULL )
		fprintf(logfd,"Auto sending to others ports: %s \n", other_ports );

	if ( reroute_ports != NULL )
		fprintf(logfd,"Auto rerouting to others ports: %s \n", reroute_ports );

	if ( headfn != NULL )
		fprintf(logfd,"Header file name: %s \n", headfn );

	if ( tailfn != NULL )
		fprintf(logfd,"Tailer file name: %s \n", tailfn);

	if ( prestr != NULL )
		fprintf(logfd,"String sent before print job: %s \n", prestr );

	if ( sufstr != NULL )
		fprintf(logfd,"String sent after print job: %s \n", sufstr );

	if ( is_debug == TRUE ) 
		fprintf(logfd, "Debug mode is invoked.  \n");
        

	if ( busy_nw == TRUE )
		fprintf(logfd, "Network busy mode is invoked. \n");

	if ( text_mode == TRUE )
		fprintf(logfd, "TEXT mode is invoked. LF--> CR|LF \n");
	fflush(logfd);

}
/**************************************************************************/
/********     dump_to_errf() *****/
/**************************************************************************/
void dump_to_errf() {

	if ( (err_fname=mktemp( err_template ) ) == NULL ) {
		perror("Printer Filter Error: err_file: mktemp");
		exit( pm_error );
	};

	if ( (errfd=fopen(err_fname, "w")) == NULL ) {
		perror("Printer Filter Error: err_file: fopen");
		exit( pm_error );
	};
        DEBUG=1;

	if ( dest != NULL )
		fprintf(errfd,"Name of server host: %s \n", dest);

	switch( default_port) {
	case PARALLEL:
		fprintf(errfd,"Port is PARALLEL port 2. \n");
		break;
	case HIGHSPEED :
		fprintf(errfd,"Port is HIGHSPEED parallel port 1.\n");
		break;
	case SERIAL:
		fprintf(errfd,"Port is SERIAL . \n");
		break;
	case PARA3:
		fprintf(errfd,"Port is PARALLEL 3 . \n");
		break;
	};

	if ( is_confg_file == TRUE  )
		fprintf(errfd,"Configuration file: %s \n", confg_fname );

	if ( delay_min != -1  )
		fprintf(errfd,"Delay minutes for printer faults: %d \n",delay_min);

	if ( WAIT_PRINTER_BUSY != 0  )
		fprintf(errfd,"Sleep seconds for printer busy: %d \n", WAIT_PRINTER_BUSY);
	if ( other_ports != NULL )
		fprintf(errfd,"Auto sending to others ports: %s \n", other_ports );

	if ( reroute_ports != NULL )
		fprintf(errfd,"Auto reroute to others ports: %s \n", reroute_ports );

	if ( headfn != NULL )
		fprintf(errfd,"Header file name: %s \n", headfn );

	if ( tailfn != NULL )
		fprintf(errfd,"Tailer file name: %s \n", tailfn);

	if ( prestr != NULL )
		fprintf(errfd,"String sent before print job: %s \n", prestr );

	if ( sufstr != NULL )
		fprintf(errfd,"String sent after print job: %s \n", sufstr );

	if ( DEBUG == 1 )
		fprintf(errfd, "Debug mode is invoked.  \n");

	if ( busy_nw == TRUE )
		fprintf(errfd, "Network busy mode is invoked. \n");

	if ( text_mode == TRUE )
		fprintf(errfd, "TEXT mode is invoked. LF--> CR|LF \n");

	fflush(errfd);

}
/**************************************************************************/
/********     get_opts_from_file() *****/
/**************************************************************************/
int get_opts_from_file()
{
	int c;
	int is_left;
	char *arg;

        arg=NULL;
        is_left=TRUE;
	while ( ( c = fgetc(confd )) != EOF) {
		switch(c) {
		case 'D':
			arg=get_argment(&is_left );
			dest=str_cpy(arg);
			break;
		case 'S':
			is_left=read_line();
			if ( curr_port == HIGHSPEED ) {
				curr_port=SERIAL;
				default_port=SERIAL;
			}
			else {
				error_exit(pm_error, SP_option_err);
			};
			break;
                case 'T':
			is_left=read_line();
                         text_mode=TRUE; 
                         break;
		case 'P':
			is_left=read_line();
			if ( curr_port == HIGHSPEED ) {
				curr_port=PARALLEL;
				default_port=PARALLEL;
			}
			else {
				error_exit(pm_error, SP_option_err);
			};
			break;
                case 'o':
			 arg=get_argment(&is_left );
                         curr_port=processPortNo(arg);
                         if ( curr_port < 0 ) {
                           error_exit(pm_error, port_no_error); 
                         };
                         default_port=curr_port;
                         break;
		case 'p':
			arg=get_argment(&is_left);
			prestr=str_cpy(arg);
			break;
		case 's':
			arg=get_argment(&is_left);
			sufstr=str_cpy(arg);
			break;
		case 'h':
			arg=get_argment(&is_left);
			headfn=str_cpy(arg);
			break;
		case 't':
			arg=get_argment(&is_left);
			tailfn=str_cpy(arg);
			break;
		case 'a':
			arg=get_argment(&is_left);
			other_ports=str_cpy(arg);
			break;

		case 'r':
			arg=get_argment(&is_left);
			reroute_ports=str_cpy(arg);
			break;

		case 'd':
			arg=get_argment(&is_left);
			delay_min=atoi(arg);
			break;
		case 'z':
			arg=get_argment(&is_left);
			WAIT_PRINTER_BUSY=atoi(arg);
			break;
		case 'v':
			is_left=read_line();
			is_debug=TRUE;
			break;
		case 'x':
			is_left=read_line();
			is_logf=TRUE;
			break;
		case 'b':
			is_left=read_line();
			TRY_CONNECT_PORTS=2;
			TRY_CONNECT_A_PORT=6;
			WAIT_STATE_PACK=40;
			WAIT_SEND=600;
			break;

		case '\n': 
			break;
		case '\r': 
			break;
		case ' ': 
			break;
		case '\t': 
			break;
		case '\f': 
			break;
		case '\b': 
			break;

		default :
			return( FALSE );
			break;

		}; /* end of switch */

		if ( is_left == FALSE )
			break;
	}; /* end of while */

	return( TRUE );
}

/****************************************************************************/
/* get_argment() */
/****************************************************************************/
char *get_argment(left)
int *left;
{
	int is_EOLN;
	int ch;
	int delimiter;
	int del_cnt;
	int is_EOARG;
        int arg_begin;
        int len;
        int size;

	argbuf[0]='\0';
	delimiter=0;
	del_cnt=0;
	is_EOLN=FALSE;
	is_EOARG=FALSE;
        arg_begin=FALSE;
        size=BUFSIZE-1;

        ch=fgetc(confd);
        if ( ch != ' ' && ch != '\t' )
          return(NULL);

	while( (ch=fgetc(confd)) != EOF ){
		switch(ch) {
		case ' ':
		case '\t':
                        if ( del_cnt == 1 ) {
			  append_to_argbuf(ch);
                        }
                        else {
                          if ( arg_begin == TRUE ) 
                             is_EOARG=TRUE;  
                        };
			break;

		case '\n':
		case '\r':
                        if ( del_cnt == 1 )
                           return(NULL);

			is_EOLN=TRUE;
			break;
		case 34 :
		case 39 :
			if (del_cnt == 0 ) {
				delimiter=ch;
				del_cnt++;
                                break;
			}
			else {
				if (delimiter==ch) {
					del_cnt++;
					is_EOARG=TRUE;
					break;
				}
			};
                         len=strlen(argbuf);
                        if ( len < size ) {
			append_to_argbuf(ch);
                        }
                        else {
                          is_EOARG=TRUE;
                         fprintf(stderr, "%s %s \n",PM_warn, arg_discarded_err);
                        };
			break;
		default :
                        arg_begin=TRUE;
			append_to_argbuf(ch);
			break;

		}; /* end of case */

		if ( is_EOLN == TRUE || is_EOARG == TRUE )
			break;
	}; /* end while */

         if ( ch == EOF ) {
            *left=FALSE;
            is_EOLN=TRUE;
         };

	if ( del_cnt == 1 ) {
			fprintf(stderr,"%s %s %c %s! \n", err_mark, bad_option_err, (char)delimiter, unmatched);
		return( NULL );
	};

	if ( is_EOLN == FALSE ) {
		*left=read_line();
	};

	if (strlen(argbuf)==0) {
		return(NULL);
	}
	else {
		return(argbuf);
	};

}

/****************************************************************************/
/* append_to_argbuf() */
/****************************************************************************/
void append_to_argbuf( ch )
int ch;
{
	int len;
	char chr;

	chr=(char)ch;
	if ((len=strlen(argbuf)) < BUFSIZE-1 ) {
		argbuf[len]=chr;
		argbuf[len+1]='\0';
	};
}




/****************************************************************************/
/* read_line() */
/****************************************************************************/
int read_line()
{
	int ch;

	while( (ch=fgetc(confd)) != EOF ) {
		switch(ch){
		case '\n':
			return( TRUE );
			break;
		case '\r':
			return( TRUE );
			break;
		};
	};

	return( FALSE );
}

/****************************************************************************/
/* str_cpy() */
/****************************************************************************/
char *str_cpy(from)
char *from;
{
	char *to;
	int   len;

	if (from == NULL ) {
		error_exit(pm_error, bad_option_err);
	}
	else {
		len = strlen(from)+1;
		if( (to=(char *)malloc( len*sizeof(char) )) == NULL)  {
			error_exit(pm_error, malloc_err);
		};
		strcpy(to, from);
	};
	return(to);

}

/****************************************************************************/
/* print_warning() */
/****************************************************************************/
void print_warning(){
   int i;
   char *str10;

          switch(curr_port) {
            case HIGHSPEED : i=1;
                             str10=para1;
                             break;
            case PARALLEL : i=2;
                             str10=para2;
                             break;
            case SERIAL : i=3;
                             str10=serial;
                             break;
          };

          fprintf(stderr, "%s %d ( %s ) %s \n",warn10, i, str10, warn11);

	  if (logfd != NULL) {
            fprintf(logfd, "WARNING: printer on PMTI port %d (%s port) is gone off line! \n",i, str10);
          };

	  if (errfd != NULL) {
            fprintf(errfd, "WARNING: printer on PMTI port %d (%s port) is gone off line! \n",i, str10);
          };
	  fflush(stderr);
}

/****************************************************************************/
/* error_exit() */
/****************************************************************************/
void error_exit(exit_code, err_msg)
int exit_code;
char *err_msg;
{

	if ( sockfd >= 0 ) {
		close(sockfd);
                sockfd=-1;
	};
  
        if ( curr_port != default_port ) {
         print_warning();
       };

	fflush(stderr);

	if (err_msg != NULL ) {
		fprintf(stderr,"%s %s \n", err_mark, err_msg);
	};

	if (logfd != NULL) {
		if (err_msg != NULL ) {
			fprintf(logfd,"%s %s \n", err_mark, err_msg);
		};
		fprintf(logfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(logfd);
		fclose(logfd);
	};

	if ( errfd != NULL ) {
		if (err_msg != NULL ) {
			fprintf(errfd,"%s %s \n", err_mark, err_msg);
		};
		fprintf(errfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(errfd);
		fclose(errfd);
	}

	exit(exit_code);
}

/****************************************************************************/
/* cnet_and_parse_state() */
/****************************************************************************/
int cnet_and_parse_state(mode, port_num )
int mode;
int port_num;
{

	int flag1;
	int try_cnt;
	int temp;

	if (DEBUG) {
		fprintf(errfd,"cnet_and_parse_state() \n");
                fflush(errfd);
	};

	try_cnt=0;
	while ( try_cnt < TRY_READ_STATE ) {
		try_cnt++;

		if (mode==AllPorts) {
			temp=CnetMgnt();
		}
		else {
			temp=cnet_single_port(port_num);
		};

		if (temp == FALSE ) {

			if (DEBUG) {
				fprintf(errfd,"cnet_and_parse_state(): return ERROR\n");
                fflush(errfd);
			}
			return( ERROR );
		};

                if (temp == PM_BUSY) {
                    return(BUSY);
                };

		if ( (flag1=recv_1st_state(&glo_state_pack,WAIT_STATE_PACK))  <= 0)     {
                        if ( sockfd >= 0 ) {
			close( sockfd );
                        sockfd = -1;
                        };

			if (DEBUG) {
				fprintf(errfd,"cnet_and_parse_state(): recv_1st_state return %d\n", flag1);
                fflush(errfd);
			};
			continue;
		};

		flag1=ParserState(&glo_state_pack , curr_port, 0);

		return( flag1 );
	};
	if (LOGF) {
		fprintf(logfd,"%s Can't receive status_packet from printer server! \n", err_mark);
        };
	if (DEBUG) {
		fprintf(errfd,"%s Can't receive status_packet from printer server! \n", err_mark);
                fflush(errfd);
	};
	return( ERROR);

} /* end cnet_and_parse_state */

/****************************************************************************/
/* query_status() */
/****************************************************************************/
int query_status()
{
	int loop;
	int flag1;
	int another_port;
	int loop_cnt;
	int other_status;

	if (DEBUG) {
		fprintf(errfd,"query_status() \n");
                fflush(errfd);
	}

	loop=TRUE;
	loop_cnt=0;
	while ( loop == TRUE ) {
		loop_cnt++;

		if (DEBUG) {
			fprintf(errfd,"Trying query server's status: %d times \n", loop_cnt);
                fflush(errfd);
		}

		if (LOGF) {
			fprintf(logfd, "Trying query server's status: %d times \n", loop_cnt);
                };

		flag1=cnet_and_parse_state(AllPorts, 0);

		if (LOGF) {
			fprintf(logfd,"Current port number is %d \n", curr_port);
                };
		if (DEBUG) {
		fprintf(errfd,"Current port number is %d \n", curr_port);
                fflush(errfd);
		};

		if (flag1 == ERROR ) {
			if (LOGF) {
				fprintf(logfd,"%s %s \n", err_mark, server_err);
                        };
			fprintf(stderr,"%s %s \n", err_mark, server_err);
			if (DEBUG) {
				fprintf(errfd,"%s %s \n", err_mark, server_err);
                                fflush(errfd);
			};
			return( ERROR );
		};

		if ( flag1 == ACCEPT ) {

			if (DEBUG) {
				fprintf(errfd,"Auto_send_query_state(): return ACCEPT\n");
                                fflush(errfd);
			}

			return( ACCEPT );
		}
		else {

        if ( sockfd >= 0 ) {
			close(sockfd);
                        sockfd=-1;
        };
			if (DEBUG) {
				fprintf(errfd,"query_state(): try other ports. \n");
                                fflush(errfd);
			}

			if (LOGF) {
				fprintf(logfd, "Try query status of other ports. \n");
                         };

			if ( (another_port=get_other_port( &glo_state_pack )) > 0 )
			{

				if (DEBUG) {
					fprintf(errfd,"query_state(): another port is acceptable. \n");
					fprintf(errfd,"Current port number is %d \n", curr_port);
					fprintf(errfd,"another port number is %d \n", another_port);
                                fflush(errfd);
				}



				if (LOGF) {
					fprintf(logfd,"Another port is acceptable. \n");
					fprintf(logfd,"Current port number is %d \n", curr_port);
				};


				other_status=cnet_and_parse_state(SinglePort, another_port);
				if ( other_status != ACCEPT ) {
        if ( sockfd >= 0 ) {
						close(sockfd);
                                                sockfd=-1;
           };
                                       if ( other_status == ERROR ) {
                                            return(ERROR);
                                       };  

						if (LOGF) {
							fprintf(logfd,"query_state():another port:%d is not accept now \n", curr_port);
                                                };

						if (DEBUG) {
							fprintf(errfd,"query_state():another port:%d is not accept now \n", curr_port);
                                                 fflush(errfd);
						}

						continue;
				}
				else {

					if (DEBUG) {
						fprintf(errfd,"query_state(): return ACCEPT. port=%d\n",curr_port);
                                               fflush(errfd);
					}
					return ( ACCEPT );
				};

			}
                        /* get_other_port < 0 */
			else {
			if ( curr_port != default_port ) {
				sleep(BUSY_INTERVAL);
				continue;
			};
				switch( flag1 ) {

				case BUSY:

					if (DEBUG) {
						fprintf(errfd,"Auto_Send_Query_Status(): BUSY sleep 10 seconds. socket closed. \n");
                                         fflush(errfd);

					}

					sleep(BUSY_INTERVAL);
					break;

				case REJECT :
					if (delay_cnt < 0 ) {
						if (DEBUG) {
							fprintf(errfd,"Auto_Send_Query_Status(): sleep 60 seconds.\n");
                        fflush(errfd);
						}

						sleep(WAIT_PRT_IO_ERR);
					}
					else if (delay_cnt > 0) {
						delay_cnt--;

						if (DEBUG) {
							fprintf(errfd,"Auto_Send_Query_Status(): sleep 60 seconds. \n");
                        fflush(errfd);
						}

						sleep(WAIT_PRT_IO_ERR);
					}
					else {

						if (DEBUG) {
							fprintf(errfd,"Auto_send_query_state(): return REJECT\n");
                        fflush(errfd);
						}

						return(REJECT);
					};
					break;

				default :
					if (DEBUG) {
						fprintf(errfd,"Auto_send_query_state(): return FORMAT_ERROR\n");
                        fflush(errfd);
					}
                                        if ( sockfd >= 0 ) {
			                   close(sockfd);
                                           sockfd=-1;
                                        };
					return( FORMAT_ERROR );

				};

			};/* end case */
		}; /* end else */
	}; /* end while */
} /* end auto_send_query_status */

/*****************************************************************************/
/* ClientInit() */
/*****************************************************************************/
int ClientInit()
{
	unsigned char *t;

	if (DEBUG) {
		fprintf(errfd,"ClientInit() \n");
                        fflush(errfd);
	}

	if ((ServerHost=gethostbyname(dest)) == NULL ) {
		if (LOGF) {
			fprintf(logfd,"Printer Filter Error: gethostbyname(): Unknown server name: %s .\n", dest);
                };
		if (DEBUG) {
			fprintf(errfd,"Printer Filter Error: gethostbyname(): Unknown server name: %s .\n", dest);
                        fflush(errfd);
                };
		fprintf(stderr,"%s %s %s .\n",err_mark, unknown_server, dest);
		return( FALSE );
	};


	server.sin_family = AF_INET;
	server.sin_port = htons( default_port );
	bcopy( ServerHost->h_addr, ( char *)&server.sin_addr.s_addr, ServerHost->h_length);

	t=(unsigned char *)&server.sin_addr;
	if (LOGF) {
		fprintf(logfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], default_port);
        };


	if (DEBUG) {
		fprintf(errfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], default_port);
                        fflush(errfd);
	};
	return( TRUE );
}


/*****************************************************************************/
/* ServerInit()  */
/*****************************************************************************/
int ServerInit(id)
int id;
{
	server.sin_port = htons( id );
	curr_port = id;

	if (DEBUG) {
		fprintf(errfd,"ServerInit() : curr_port=%d\n", id);
                        fflush(errfd);
	}

	return( TRUE );
}


/*****************************************************************************/
/* cnet_single_port() */
/*****************************************************************************/
int cnet_single_port(port_num)
int port_num;
{
	unsigned char *t;
	int temp;
        ushort ppn;

	if (DEBUG) {
		fprintf(errfd,"cnet_single_port() port=%d\n", port_num);
                        fflush(errfd);
	}
        
        if (sockfd >= 0 ) {
          close(sockfd);
          sockfd=-1;
        };

        if ( DEBUG ) {
           fprintf(errfd, "Before create a new socket: sockfd=%d \n", sockfd);
                fflush(errfd);
        };
	if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))  < 0 ) {
		perror("Printer Filter Error: socket");
		error_exit(pm_error, socket_err);
	};

	ServerInit(port_num);

		/*
           temp=connect(sockfd, &server, sizeof(server)); 
*/
        if ( DEBUG ) {
                ppn=ntohs(server.sin_port);
           fprintf(errfd, "Before connect to a socket: sockfd=%d port=%u\n", sockfd, ppn);
                fflush(errfd);
        };
		temp=connect(sockfd, (struct sockaddr *)&server, sizeof(server));
        if ( DEBUG ) {
                ppn=ntohs(server.sin_port);
           fprintf(errfd, "After connect to a socket: sockfd=%d port=%u\n", sockfd, ppn);
                fflush(errfd);
        };


		if (temp == 0 ) {

			if (DEBUG) {
				fprintf(errfd,"Connection succeeded! port: %d \n", curr_port);
                        fflush(errfd);
			}

			return( TRUE );
		}
		else {
                  if ( sockfd >= 0 ) {
                  close(sockfd);
                  sockfd=-1;
                  };
                  if ( errno == ECONNREFUSED ) { 
			if (DEBUG) {
				perror("Printer Filter Error: cnet_single_port(): connect");
				fprintf(errfd,"cnet_single_port(): try connecting refused forcedly. port=%d \n", curr_port);
                        fflush(errfd);
			};/* end DEBUG */
                        return(PM_BUSY);
                     };
		}; /* end if connect */


	perror("Printer Filter Error: connect");
	t=(unsigned char *)&server.sin_addr;
	fprintf(stderr,"%s %s\n",err_mark, connect_err);
	if (LOGF) {
		fprintf(logfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(logfd,"%s %s\n",err_mark, connect_err);
		fflush(logfd);
	};
	if (DEBUG) {
		fprintf(errfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(errfd,"%s %s\n",err_mark, connect_err);
		fflush(errfd);
	};
	return(FALSE);
}
/*****************************************************************************/
/* CnetMgnt() */
/*****************************************************************************/
int CnetMgnt()
{
	unsigned char *t;
	int tport;
	int temp;
        int cnet_fail_cnt;
        ushort ppn;

        if (DEBUG) {
           fprintf(errfd,"CnetMgnt() \n");
           fflush(errfd);
        };


        cnet_fail_cnt=0;
        reset_port_list();
	while ( 1 )  {
	        tport=next_port();
                if (tport < 0 ) {
                        sleep(BUSY_INTERVAL);
                	reset_port_list();
	                tport=next_port();
                };
       if ( sockfd >= 0 ) {
         close(sockfd);
         sockfd=-1;
       };

        if ( DEBUG ) {
           fprintf(errfd, "Before create a new socket: sockfd=%d \n", sockfd);
                fflush(errfd);
        };

	if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))  < 0 ) {
		perror("Printer Filter Error: socket");
		error_exit(pm_error, socket_err);
	};
		ServerInit(tport);

                if (DEBUG) {
                fprintf(errfd, "CnetMgnt(): Trying make connect to port %d \n", curr_port);
                fflush(errfd);
              };

/*
	        temp=connect(sockfd, &server, sizeof(server));
*/
        if ( DEBUG ) {
                ppn=ntohs(server.sin_port);
           fprintf(errfd, "Before connect to a socket: sockfd=%d port=%u \n", sockfd, ppn);
                fflush(errfd);
        };
		temp=connect(sockfd, (struct sockaddr *)&server, sizeof(server));
        if ( DEBUG ) {
                ppn=ntohs(server.sin_port);
           fprintf(errfd, "After connect to a socket: sockfd=%d port=%u\n", sockfd, ppn);
                fflush(errfd);
        };
		if (temp == 0 ) {

         		if (DEBUG) {
			     fprintf(errfd,"Connection succeeded! Trying Fail Times: %d port=%d\n", cnet_fail_cnt, curr_port);
                fflush(errfd);
		        }
         		if (LOGF) {
			     fprintf(logfd,"Connection succeeded! Trying Fail Times: %d port=%d\n", cnet_fail_cnt, curr_port);
                fflush(logfd);
		        }

	        	return( TRUE );
		}
		else {
                  if (sockfd >= 0 ) {
                  close(sockfd);
                  sockfd=-1;
                  };
                  if ( errno == ECONNREFUSED ) {
                    cnet_fail_cnt++;
			if (DEBUG) {
					perror("Printer Filter Error: CnetMgnt(): connect");
					fprintf(errfd,"CnetMgnt(): try connecting refused forcedly. times=%d  port=%d\n", cnet_fail_cnt, curr_port);
                fflush(errfd);
				};/* end DEBUG */
                   } 
                   else {
                     break;
                   };
        	}; /* end if connect */
	};/* end while */

	perror("Printer Filter Error: connect");
	t=(unsigned char *)&server.sin_addr;
	fprintf(stderr,"%s %s\n",err_mark, connect_err);
	if (LOGF) {
		fprintf(logfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(logfd,"%s %s\n",err_mark, connect_err);
		fflush(logfd);
	};
	if (DEBUG) {
		fprintf(errfd,"Server IP address: %3u %3u %3u %3u Port: %d \n",t[0],t[1],t[2],t[3], curr_port);
		fprintf(errfd,"%s %s\n",err_mark, connect_err);
		fflush(errfd);
	};
	return(FALSE);
}

/*****************************************************************************/
/* SendMgnt() */
/*****************************************************************************/
int SendMgnt( rfd, is_text )
FILE *rfd;
int is_text;
{
	int scnt, rcnt, total;
	int state;
	int state_size;
        int wait_sending_data;
        size_t (*read_func)();
        int loop_cnt_r;


        if ( curr_port == SERIAL ) {
           wait_sending_data=4*WAIT_SEND;
        }
        else {
          wait_sending_data=WAIT_SEND;
        };

        if (is_text == FALSE ) {
          read_func=fread;
        }
        else {
          read_func=read_and_CR_LF_convert; 
        };
        

	if (DEBUG) {
		fprintf(errfd,"SendMgnt(): seconds allowed for sending data=%d \n", wait_sending_data);
		fprintf(errfd,"Reading data from input file and sending data to server. \n");
                fflush(errfd);
	}

	if (LOGF) {
		fprintf(logfd,"Reading data from input file and sending data to server. \n");
        };
	total = 0;
        loop_cnt_r=0;
	timeout_flag=READDATA_TIMEOUT;
	alarm(WAIT_READ);
	while ( (rcnt = (*read_func)(sendbuf, sizeof(char), BUFSIZE, rfd)) > 0) {
		alarm(0);
		timeout_flag=UNKNOWN_TIMEOUT;

/*
		if (DEBUG) {
			fprintf(errfd,"Read date bytes: %d \n", rcnt);
                fflush(errfd);
		}
*/

                if ( WAIT_PRINTER_BUSY > 0 ) {
                   loop_cnt_r++;
                   if (loop_cnt_r%2 == 0 ) {
                       loop_cnt_r=0;
                       sleep(WAIT_PRINTER_BUSY); 
                   } 
                }

		timeout_flag=SENDDATA_TIMEOUT;
		alarm(wait_sending_data);
		if ((scnt=send(sockfd, sendbuf, rcnt, 0)) <= 0 ) {
			alarm(0);
			timeout_flag=UNKNOWN_TIMEOUT;
			perror("Printer Filter Error: send");
			if (LOGF) {
				fprintf(logfd,"%s %s \n", err_mark, send_err);
                        };
			if (DEBUG) {
				fprintf(errfd,"%s %s \n", err_mark, send_err);
                fflush(errfd);
			};
			return( FALSE );
		}
		else {
			alarm(0);
			timeout_flag=UNKNOWN_TIMEOUT;

/*
			if (DEBUG) {
				fprintf(errfd,"Data sent:  %d   bytes\n", scnt);
                fflush(errfd);
			}
*/

			total += scnt;
			TOTAL_DATA += scnt;
		/*
			if ( rcnt < BUFSIZE ) continue;


       if ((state_size=recv_state(&glo_state_pack, 0)) <= 0 ) {
          if (DEBUG) {
            fprintf(errfd,"SendMgnt(): 1st recv_state return %d \n", state_size);
                fflush(errfd);
          };
          continue; 
       };

     loop = TRUE;
     while(loop == TRUE ) {

       state=ParserState(&glo_state_pack , curr_port, 1);
       switch(state)
       {
         case ACCEPT: loop = FALSE;

if (DEBUG) {
fprintf(errfd,"SendMgnt(): server status ACCEPT. \n");
                fflush(errfd);
}

                      break;
   
        case BUSY:  

if (DEBUG) {
fprintf(errfd,"SendMgnt(): BUSY, sleep 10 seconds. \n");
                fflush(errfd);
}

                     sleep(BUSY_INTERVAL);
                     break;

      case REJECT : if (delay_cnt < 0 ) {

if (DEBUG) {
fprintf(errfd,"SendMgnt(): REJECT, sleep 60 seconds. delay_cnt=%d\n",delay_cnt);
                fflush(errfd);
}

                      sleep(WAIT_PRT_IO_ERR);  
                    }
                    else if (delay_cnt > 0) {
                      delay_cnt--;

if (DEBUG) {
fprintf(errfd,"SendMgnt(): REJECT, sleep 60 second. delay_cnt=%d \n", delay_cnt);
                fflush(errfd);
}

                      sleep(WAIT_PRT_IO_ERR);  
                    } 
                    else { 
       if (LOGF) {
                      fprintf(logfd,"%s %s \n", err_mark, prt_err);
       };
                      fprintf(stderr,"%s %s \n", err_mark, prt_err);
                      if (DEBUG) {
                        fprintf(errfd,"%s %s \n", err_mark, prt_err);
                fflush(errfd);
                      };
                      return(FALSE);
                    }  
                    break;

    };  * end case *

     if ( state != ACCEPT ) {
       if ((state_size=recv_state(&glo_state_pack, WAIT_STATE_PACK)) <= 0 ) {
          if (DEBUG) {
            fprintf(errfd,"SendMgnt(): 2nd recv_state return %d \n", state_size);
                fflush(errfd);
          };
          break;
        };
     };

       }; * end while loop parser *
*/
		}; /*end if send*/

		timeout_flag=READDATA_TIMEOUT;
		alarm(WAIT_READ);
	}; /* end while read */
	alarm(0);
	timeout_flag=UNKNOWN_TIMEOUT;
	if (LOGF)  {
		fprintf(logfd, "Total data sent: [ %d ] \n", total);
         };

	if (DEBUG) {
		fprintf(errfd,"Total data sent: [ %d ] \n", total);
                fflush(errfd);
	}
	return( TRUE);
} /* end sendmgnt */

/*****************************************************************************/
/* SendStr() */
/*****************************************************************************/
int SendStr(str)
char *str;
{
	int scnt, rcnt;

	if (DEBUG) {
		fprintf(errfd,"SendStr(): str=%s \n", str);
                fflush(errfd);
	}

	rcnt=strlen(str);
	timeout_flag=SENDDATA_TIMEOUT;
	alarm(WAIT_SEND);
	if ((scnt=send(sockfd, str, rcnt, 0) ) < 0 ) {
		alarm(0);
		timeout_flag=UNKNOWN_TIMEOUT;
		perror("Printer Filter Error: Send pre/suf string");
		if (LOGF) {
			fprintf(logfd,"%s %s \n",err_mark, send_err);
                };
		fprintf(stderr,"%s %s \n",err_mark, send_err);
		if (DEBUG) {
			fprintf(errfd,"%s %s \n",err_mark, send_err);
                fflush(errfd);
		};
		return( FALSE );
	};
	alarm(0);
	TOTAL_DATA += scnt;
	timeout_flag=UNKNOWN_TIMEOUT;
	if (LOGF) {
		fprintf(logfd,"Send pre/suf string %s \n", str);
        };
	return( TRUE);
}

/*****************************************************************************/
/* QuitMgnt() */
/*****************************************************************************/
int QuitMgnt()
{
        if ( WAIT_PRINTER_BUSY != 0 ) {
          sleep(10);
        }

        if ( sockfd >= 0 ) {
	close(sockfd);
        sockfd=-1;
        };

	if (DEBUG) {
/*
          unlink(err_fname);
*/
		fprintf(errfd,"QuitMgnt() \n");
		fprintf(errfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(errfd);
		fclose(errfd);
	};

	if (LOGF) {
/*
		unlink(log_fname);
*/
		fprintf(logfd,"QuitMgnt() \n");
		fprintf(logfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(logfd);
		fclose(logfd);
         };

	return(0);
}

/*****************************************************************************/
/* ParserState()  */
/*****************************************************************************/
int ParserState(pack, id, flag)
packet_t *pack;
int id;
int flag;
{
	info_t *state;

	if (DEBUG) {
		fprintf(errfd,"ParseState(): port=%d packet: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, pack->premark, pack->parallel.prt, pack->parallel.pm, pack->highspeed.prt, pack->highspeed.pm, pack->serial.prt, pack->serial.pm,pack->para3.prt, pack->para3.pm, pack->sufmark);
                fflush(errfd);
	}

	switch (id)
	{
	case PARALLEL:
		state=(info_t *)&pack->parallel;
		break;

	case HIGHSPEED:
		state=(info_t *)&pack->highspeed;
		break;

	case SERIAL:
		state=(info_t *)&pack->serial;
		break;

	case PARA3:
		state=(info_t *)&pack->para3;
		break;

	};

	if ( state->prt&PRT_TIME_OUT || state->prt&PRT_IO_ERR || state->prt&PRT_OUT_PAPER ) {

		if (DEBUG) {
			fprintf(errfd,"ParseState(): return( REJECT ) \n");
		fprintf(errfd,"ParseState(): port=%d packet: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", id, pack->premark, pack->parallel.prt, pack->parallel.pm, pack->highspeed.prt, pack->highspeed.pm, pack->serial.prt, pack->serial.pm,pack->para3.prt,pack->para3.pm, pack->sufmark);
             fflush(errfd);
		}

		return( REJECT );
	};

	if ( flag == 0 ) {
		if ( state->prt&PRT_SELECT && state->prt&PRT_NOT_BUSY && !(state->pm&PM_IN_USE) ) {

			if (DEBUG) {
				fprintf(errfd,"ParseState(): return( ACCEPT ) \n");
          fflush(errfd);

			}

			return( ACCEPT );
		};
	}
	else {
		if ( state->prt&PRT_SELECT && state->prt&PRT_NOT_BUSY ) {

			if (DEBUG) {
				fprintf(errfd,"ParseState(): return( ACCEPT ) \n");
                  fflush(errfd);
			}

			return( ACCEPT );
		};
	};

	if (DEBUG) {
		fprintf(errfd,"ParseState(): return( BUSY ) \n");
                fflush(errfd);
	}

	return( BUSY );
}

/*****************************************************************************/
/* get_other_port()  */
/*****************************************************************************/
int  get_other_port(pstate_pack)
packet_t *pstate_pack;
{
	int tport;
        int rember_index;

	if (DEBUG) {
		fprintf(errfd,"get_other_port() \n");
                fflush(errfd);
	}

        rember_index=port_list.index;
	reset_port_list();
	tport=next_port();
	while( tport > 0 ) {
		if ( ParserState( pstate_pack, tport, 0)==ACCEPT) {
                        port_list.index=rember_index;
			return(tport);
                }
		else
			tport=next_port();
	};
        port_list.index=rember_index;
	return( -1 );

}


/*****************************************************************************/
/* append_to_state_buf()  */
/*****************************************************************************/
void append_to_state_buf(from, nbytes)
unsigned char *from;
int  *nbytes;
{
	int i;
	unsigned char *start;

	if (( state_buf.cnt + *nbytes ) < 2*state_pack_size ) {
		start = (unsigned char *)state_buf.buf+state_buf.cnt;
		for (i = 0; i < (*nbytes); i++)
			*( start+i) = *(from+i);
		state_buf.cnt += *nbytes;
	}
	else {
		state_buf.cnt -= state_pack_size;
		for(i=0; i < state_buf.cnt; i++)
			*(state_buf.buf+i) = *(state_buf.buf+state_pack_size+i);

		start = (unsigned char *)state_buf.buf+state_buf.cnt;
		for (i = 0; i < (*nbytes); i++)
			*( start+i) = *(from+i);
		state_buf.cnt += *nbytes;

		if ( state_buf.cnt >= 2*state_pack_size ) {
			state_buf.cnt -= state_pack_size;
			for(i=0; i < state_buf.cnt; i++)
				*(state_buf.buf+i) = *(state_buf.buf+state_pack_size+i);
		};
	};

}


/*****************************************************************************/
/* partition_hdler()  */
/*****************************************************************************/
void partition_hdler(bbufptt, rrcntt)
unsigned char *bbufptt;
int  *rrcntt;
{
	int rem;


	if ( (*rrcntt >= state_pack_size ) && ( (*rrcntt + state_buf.cnt )%state_pack_size == 0 ) )
	{
		state_buf.cnt = 0;
	}
	else {
		if ( *rrcntt >= (2*state_pack_size - 1 ) ) {
			rem=(state_buf.cnt + *rrcntt)%state_pack_size;
			state_buf.cnt=0;
			append_to_state_buf( (bbufptt+ *rrcntt - rem), &rem);
			*rrcntt = *rrcntt-rem;
		}
		else {
			append_to_state_buf( bbufptt, rrcntt );
			*rrcntt=0;
		};
	};
}

/*****************************************************************************/
/* check_state_pack()  */
/*****************************************************************************/
int check_state_pack(bufpt,state_pt,rcnt)
unsigned char *bufpt;
packet_t *state_pt;
int rcnt;
{
	int    i;
	int start;

	if (DEBUG) {
		fprintf(errfd,"check_state_pack() \n");
                fflush(errfd);
	};

	switch (rcnt) {
          case 8 : 
		if ( (*(bufpt+rcnt-1) == MARK ) && (*(bufpt+rcnt-state_pack_size) == MARK) ) {
                        state_pt->premark=*(bufpt);
                        state_pt->parallel.prt=*(bufpt+1);
                        state_pt->parallel.pm=*(bufpt+2);
                        state_pt->highspeed.prt=*(bufpt+3);
                        state_pt->highspeed.pm=*(bufpt+4);
                        state_pt->serial.prt=*(bufpt+5);
                        state_pt->serial.pm=*(bufpt+6);
                        state_pt->para3.prt=0;
                        state_pt->para3.pm=0;
                        state_pt->sufmark=*(bufpt+state_pack_size-1);

			return( state_pack_size );
		}
                break;

	case 10: 
		if ( (*(bufpt+rcnt-1) == MARK ) && (*(bufpt+rcnt-large_state_pack_size) == MARK) ) {
                        state_pt->premark=*(bufpt);
                        state_pt->parallel.prt=*(bufpt+1);
                        state_pt->parallel.pm=*(bufpt+2);
                        state_pt->highspeed.prt=*(bufpt+3);
                        state_pt->highspeed.pm=*(bufpt+4);
                        state_pt->serial.prt=*(bufpt+5);
                        state_pt->serial.pm=*(bufpt+6);
                        state_pt->para3.prt=*(bufpt+7);
                        state_pt->para3.pm=*(bufpt+8);
                      state_pt->sufmark=*(bufpt+large_state_pack_size-1);

			return( large_state_pack_size );
                   }
                   break;

           default :
			if (LOGF) {
				fprintf(logfd,"%s %s\n",err_mark, pack_format_err);
                        };
			fprintf(stderr,"%s %s\n",err_mark, pack_format_err);
			if (DEBUG) {
				fprintf(errfd,"%s %s\n",err_mark, pack_format_err);
                fflush(errfd);
			};
			return(-1  );
                break;
           }; /* end switch */
}

/*****************************************************************************/
/* recv_state()  */
/*****************************************************************************/
int recv_state(buf,time)
packet_t *buf;
int time;
{
	int    rcnt;
	int    received;
	int    pre_rcnt;
	unsigned char buf1[ BUFSIZE ];
	unsigned char *bufpt;

	if (DEBUG) {
		fprintf(errfd,"recv_state() \n");
                fflush(errfd);
	}

	bufpt=buf1;
	received=FALSE;
	rcnt=0;
	pre_rcnt=0;
	while ( 1 ) {

		pre_rcnt=rcnt;
		rcnt=my_recv(sockfd, (char *)bufpt, BUFSIZE, 0);

		if (DEBUG) {
			fprintf(errfd,"recv_state(): first recv: rcnt=%d \n", rcnt);
                fflush(errfd);
		}

		if ( rcnt == SEL_TIMEOUT )
			break;

		if ( rcnt <= 0 ) {
			if (LOGF) {
				fprintf(logfd, "Printer Filter Error:recv_state1: receive status packet from server. rcnt=%d\n", rcnt);
                         };
			return(-1);
		}

/*
		partition_hdler(bufpt, &rcnt);
*/

		received=TRUE;
	};


	if ( received == TRUE ) {
		rcnt=pre_rcnt;
	};

	if ( received == FALSE ) {

		if (DEBUG) {
			fprintf(errfd,"recv_state(): second select , wait_time=%d\n",time );
                fflush(errfd);
		};

		rcnt=my_recv(sockfd, (char *)bufpt, BUFSIZE, time);

		if (DEBUG) {
			fprintf(errfd,"recv_state(): second recv: rcnt=%d \n", rcnt);
                fflush(errfd);
		};

		if ( rcnt <= 0) {
			if ( rcnt != SEL_TIMEOUT ) {
				if (LOGF) {
					fprintf(logfd,"%s receiving status_packet form server failed \n", err_mark);
                                };
				if (DEBUG) {
					fprintf(errfd,"recv_state(): Error: second recv: rcnt=%d \n", rcnt);
                fflush(errfd);
				};
			}
			return( rcnt );
		};/* end if rcnt<0 */

/*
		partition_hdler(bufpt, &rcnt);
*/
	};

	return( check_state_pack(bufpt, buf, rcnt) );
}

/*****************************************************************************/
/* recv_1st_state()  */
/*****************************************************************************/
int recv_1st_state(buf,time)
packet_t *buf;
int time;
{
	int    rcnt;
	unsigned char buf1[ BUFSIZE ];
	unsigned char *bufpt;

	if (DEBUG) {
		fprintf(errfd,"recv_1st_state() \n");
                fflush(errfd);
	}

	bufpt=buf1;

	rcnt=my_recv(sockfd, (char *)bufpt, BUFSIZE, time);


	if ( rcnt <= 0) {
		if ( rcnt != SEL_TIMEOUT ) {
                        if ( DEBUG ) {
			fprintf(errfd, "Printer Filter Error:recv_1st_state() my_recv return: rcnt=%d\n", rcnt);
                        };
		}
		else {
			if (LOGF) {
				fprintf(logfd, "Printer Filter Error: Time out for receiving 1st state_packet from server. \n");
                         };
		};
		return( rcnt );
	}

/*
	partition_hdler(bufpt, &rcnt);
*/

	return( check_state_pack(bufpt, buf, rcnt) );
}



/*****************************************************************************/
/* sigs_hdler */
/*****************************************************************************/
static void sigs_hdler(signo)
int signo;
{

	signal(signo, SIG_IGN);
	alarm(0);

/*
        if ( sockfd >= 0 ) {
	close(sockfd);
        sockfd=-1;
        };
*/
        if ( sockfd >= 0 ) {
	shutdown(sockfd, 2);
        sockfd=-1;
        };

        if ( curr_port != default_port ) {
         print_warning();
       };

	fflush(stderr);

	switch( signo ) {
	case SIGHUP :
		if (logfd != NULL) {
			fprintf(logfd,"Got signal SIGHUP ! \n");
                };
		if (errfd != NULL) {
			fprintf(errfd,"Got signal SIGHUP ! \n");
		};
		break;
	case SIGINT :
		if (logfd != NULL) {
			fprintf(logfd,"Got signal SIGINT ! \n");
                };
		if (errfd != NULL) {
			fprintf(errfd,"Got signal SIGINT ! \n");
		};
		break;
	case SIGQUIT :
		if (logfd != NULL) {
			fprintf(logfd,"Got signal SIGQUIT ! \n");
                };
		if (errfd != NULL) {
			fprintf(errfd,"Got signal SIGQUIT ! \n");
		};
		break;

	case SIGTERM :
		if (logfd != NULL) {
			fprintf(logfd,"Got signal SIGTERM ! \n");
                 };
		if (errfd != NULL) {
			fprintf(errfd,"Got signal SIGTERM ! \n");
		};
		break;

	case SIGPIPE :
        	if (logfd != NULL) {
			fprintf(logfd,"Got signal SIGPIPE ! \n");
			fprintf(logfd,"%s %s \n", err_mark, sigpipe_err);
		};
		fprintf(stderr,"%s %s \n", err_mark, sigpipe_err);
		if (errfd != NULL) {
			fprintf(errfd,"Got signal SIGPIPE ! \n");
			fprintf(errfd,"%s %s \n", err_mark, sigpipe_err);
		};
		break;
	} /* end case */




	if (logfd != NULL) {
		fprintf(logfd,"TOTAL_DATA_SENT =%d \n", TOTAL_DATA);
		fflush(logfd);
		fclose(logfd);
	};
	if (errfd != NULL) {
		fprintf(errfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(errfd);
		fclose(errfd);
	};
	exit( printer_error );
}


/*****************************************************************************/
/* sigcancel_hdler()  */
/*****************************************************************************/
static void sigcancel_hdler()
{
	signal(CANCELSIG, SIG_IGN);
	alarm(0);
	timeout_flag=UNKNOWN_TIMEOUT;

/*
        if ( sockfd >= 0 ) {
	close( sockfd );
        sockfd = -1 ;
        };
*/

        if ( sockfd >= 0 ) {
	shutdown(sockfd, 2);
        sockfd=-1;
        };

	fflush(stderr);
	if (logfd != NULL) {
		unlink( log_fname);
        };

	if (errfd != NULL) {
		fprintf(errfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fprintf(errfd,"sigcancel_hdler(): Got SIGNAL for cancellation ! \n");
		fflush(errfd);
		fclose(errfd);
	}

	exit(cancel_exit);
}

/*****************************************************************************/
/* timeout()  */
/*****************************************************************************/
static void timeout() {

/*
        if ( sockfd >= 0 ) {
	close(sockfd);
        sockfd=-1;
        };
*/

        if ( sockfd >= 0 ) {
	shutdown(sockfd, 2);
        sockfd=-1;
        };

        if ( curr_port != default_port ) {
         print_warning();
       };

	if (errfd != NULL) {
		fprintf(errfd,"timeout(): Got signal: SIGALRM ! \n");
		fprintf(errfd,"timeout() \n");
	}
	if (logfd != NULL) {
		fprintf(logfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
        };

	switch( timeout_flag )
	{
	case CONNECT_TIMEOUT :
		if (logfd != NULL) {
			fprintf(logfd, "%s Try Making TCP Connection TimeOut\n",err_mark);
                };
		fprintf(stderr, "%s %s \n",err_mark,connect_err);
		if (errfd != NULL) {
			fprintf(errfd, "%s Try Making TCP Connection TimeOut\n",err_mark);
		};
		break;

	case SENDDATA_TIMEOUT :
		if (logfd != NULL) {
			fprintf(logfd, "%s Send Data to Server TimeOut\n", err_mark);
                };
		fprintf(stderr, "%s %s \n",err_mark,prt_err);
		if (errfd != NULL) {
			fprintf(errfd, "%s Send Data to Server TimeOut\n", err_mark);
		};
		break;

	case READDATA_TIMEOUT :
		if (logfd != NULL) {
			fprintf(logfd, "%s Read Data TimeOut\n",err_mark);
                };
		fprintf(stderr, "%s %s \n",err_mark,read_err);
		if (errfd != NULL) {
			fprintf(errfd, "%s Read Data TimeOut\n",err_mark);
		};
		break;

	default :
		if (logfd != NULL) {
			fprintf(logfd, "%s Unknown TimeOut\n",err_mark);
                };
		fprintf(stderr, "%s %s\n",err_mark, unknown_timeout);
		if (errfd != NULL) {
			fprintf(errfd, "%s Unknown TimeOut\n",err_mark);
		};
	};
	fflush(stderr);
	if (logfd != NULL) {
		fflush(logfd);
		fclose(logfd);
	};
	if (errfd != NULL) {
		fprintf(errfd,"TOTAL_DATA_SENT=%d \n", TOTAL_DATA);
		fflush(errfd);
		fclose(errfd);
	};
	exit( printer_error );
}

/*****************************************************************************/
/* my_recv()  */
/*****************************************************************************/
int my_recv(readfd, recvbuf, size, time_sec)
int readfd;
char *recvbuf;
int size;
int time_sec;
{
	int temp;
	int i;
	struct timeval tv;
/*
        long *test_fds;
*/
	fd_set  test_fds;


	if (DEBUG) {
		fprintf(errfd,"my_recv() \n");
                fflush(errfd);
	};

	tv.tv_usec = 0;
	tv.tv_sec = time_sec;
/*
	*test_fds = 0;
       	*test_fds |= (1 << readfd);
*/
	FD_ZERO(&test_fds);
	FD_SET(readfd, &test_fds);
	i=select(readfd+1, &test_fds, NULL, NULL, &tv) ;


	if (DEBUG) {
		fprintf(errfd,"my_recv(): select: time=%d, readfd=%d, result=%d \n", time_sec, readfd, i);
                fflush(errfd);
	}

	if ( i < 0 ) {

		if (DEBUG) {
			perror( "My_receive: select");
			fprintf(errfd, "PSfilter:My_Receive: Error: select error \n");
                fflush(errfd);
		}

		return(-1);
	};

	if ( i == 0 ) {
		return(SEL_TIMEOUT);
	};


	temp=recv(readfd, recvbuf, size, 0 );

	if (DEBUG) {
		fprintf(errfd,"my_recv(): recv: result=%d \n", temp);
                fflush(errfd);
		if ( temp < 0 )
			perror("PSfilter: my_recv: recv");
	};

	return(temp);
}



/*****************************************************************************/
/* bcopy()   */
/*****************************************************************************/
#if SVR4

void bcopy(from, to, len)
char *from;
char *to;
int len;
{
	int i;

	for (i=0; i<len; i++)
		to[i]=from[i];
}

#endif






/*****************************************************************************/
/* create_port_list()   */
/*****************************************************************************/
void create_port_list()
{
	int port1;
	int port2;

	port1=-1;
	port2=-1;
        port_list.count=0;
        port_list.index=0;

   if (DEBUG) {
		fprintf(errfd,"create_port_list() \n");
                fflush(errfd);
   };
   if ( reroute_ports != NULL ) {
          create_reroute_list();
   } else {

	append_to_port_list(default_port);

	if ( other_ports == NULL )
		return;

	if (strcmp(other_ports,"serial")==0) {
		port1=SERIAL;
	}
	else {
		if (strcmp(other_ports,"para1")==0) {
			port1=HIGHSPEED;
		}
		else {
			if ( strcmp(other_ports, "para2")==0) {
				port1=PARALLEL;
			};
		};
	};

	if ( port1 == default_port )
		return;

	if (strcmp(other_ports, "all")==0) {
		switch(default_port)
		{
		case HIGHSPEED :
			port1=PARALLEL;
			port2=SERIAL;
			break;
		case PARALLEL :
			port1=HIGHSPEED;
			port2=SERIAL;
			break;
		case SERIAL :
			port1=HIGHSPEED;
			port2=PARALLEL;
			break;

		};
	};

	if (port1 == -1) {
          if (LOGF) {
		fprintf(logfd,"WARNING: bad argument %s for -a option! \n", other_ports);
          };
		if (DEBUG) {
			fprintf(errfd,"WARNING: bad argument %s for -a option! \n", other_ports);
                fflush(errfd);
		};
		fprintf(stderr,"%s %s %s %s \n",PM_warn, warn20, other_ports, warn21);
		return;
	}

	append_to_port_list(port1);

	if ( port2 != -1 )
		append_to_port_list(port2);

  } /* end if reroute == NULL */

}

/******************************************************************************/
/****** print_port_list() ********/
/******************************************************************************/
void print_port_list() {
	int i;

        if ( DEBUG ) {
	fprintf(errfd,"Port List: ");
	for (i=0; i<port_list.count; i++) {
		fprintf(errfd," %d ", port_list.ports[i]);
	};
	fprintf(errfd,"\n");
	fflush(errfd);
        };
}


/*****************************************************************************/
/* append_to_port_list()   */
/*****************************************************************************/
int append_to_port_list(port_num)
int port_num;
{
	int i;

	if ( port_list.count < NUM_OF_PORTS ) {
		i=port_list.count;
		port_list.ports[i] = port_num;
		port_list.count++;
		return( TRUE );
	}
	else {
		return( FALSE );
	};

}

/*****************************************************************************/
/***** next_port() *****/
/*****************************************************************************/
int next_port()
{
	int i;

	if ( port_list.count > 0 ) {
		if ( port_list.index < port_list.count) {
			i = port_list.index;
			port_list.index++;
			return( port_list.ports[i] );
		};
	};
	return( -1 );
}

/*****************************************************************************/
/***** reset_port_list() *****/
/*****************************************************************************/
void reset_port_list()
{
	port_list.index=0;
}

/*****************************************************************************/
size_t read_and_CR_LF_convert(buf, size, count, stream)
char *buf;
unsigned int size;
unsigned int count;
FILE *stream;
{
 int i;
 int c;


 i=0;
 while ( i < (int)count ) {

   if (( c=getc(stream)) == EOF) {
     break;
   }
   else {
     if ( c == '\n' && prev_char != '\r' ) {
       *(buf+i) = '\r';
       i++;
     }; /* end if */    

     *(buf+i) = c;
     i++;
     prev_char=c;

   }; /* end if else */
 }; /* end while */
   return(i);

}
/**************************************************************************/
int processPortNo( portNo)
char *portNo;
{
  switch (*portNo) {
  case '1' :
         return(HIGHSPEED);
         break;
  case '2' :
         return(PARALLEL);
         break;
  case '3' :
         return(PARA3);
         break;
  case 'S' :
  case 's' :
         return(SERIAL);
         break;
   default :
          return(-1);
          break;
  }; /* end switch */
}
/****************************************************************************/
void create_reroute_list() {
char *roller;
int ccode;
int port_num;

if (DEBUG) {
 fprintf(errfd,"create_reroute_list()\n");
 fflush(errfd);
};
   append_to_port_list(default_port);
   roller=reroute_ports;
   while ( *roller != '\0' ) {
     switch (*roller) {
       case '1' :
             port_num=HIGHSPEED;
             break;
       case '2' :
             port_num=PARALLEL;
             break;
       case '3' :
             port_num=PARA3;
             break;
        case 's' :
       case 'S' :
             port_num=SERIAL;
             break;
        default :
             port_num=-1;
             break;

      }/* end switch */
      if ( port_num != -1 ) {
        ccode=is_in_port_list(port_num);
        if ( ccode == FALSE ) {
                append_to_port_list(port_num);
        }
      }
      roller++;
   } /* end while */
}
/**************************************************************************/
int is_in_port_list( port_num ) 
int port_num;
{
   int i;
 
    for ( i=0; i<port_list.count; i++) {
       if ( port_list.ports[i] == port_num ) {
          return(TRUE);
       };
    };
    return(FALSE);
}
