コード例 #1
0
ファイル: ftnnntp.c プロジェクト: ftnapps/FTNd
void send_nntp(const char *format, ...)
{
    char    *out, p[4];
    va_list va_ptr;

    out = calloc(4096, sizeof(char));

    va_start(va_ptr, format);
    vsnprintf(out, 4096, format, va_ptr);
    va_end(va_ptr);

    /*
     * Only log responses
     */
    if (out[3] == ' ') {
	memset(&p, 0, sizeof(p));
    	strncpy(p, out, 3);
	if (atoi(p) > 0) {
	    Syslog('n', "> \"%s\"", printable(out, 0));
	}
    }

    PUTSTR(out);
    PUTSTR((char *)"\r\n");
    FLUSHOUT();
    sentbytes += (strlen(out) + 2);
    free(out);
}
コード例 #2
0
static int getsync(void)
{
    int	c;

    PUTCHAR(0xaa);
    PUTCHAR(0x55);
    FLUSHOUT();
    Syslog('a', "getsync try to synchronize");

gs:
    if (tty_status) {
	WriteError("TCP: getsync failed %s", ttystat[tty_status]);
	return 1;
    }
    while ((c = GETCHAR(120)) != 0xaa)
	if (tty_status) {
	    WriteError("TCP: getsync failed: %s", ttystat[tty_status]);
	    return 1;
	}

    if ((c = GETCHAR(120)) != 0x55)
	goto gs;

    Syslog('a', "getsync done, tty_status %s", ttystat[tty_status]);
    return tty_status;
}
コード例 #3
0
ファイル: prot_emsi.c プロジェクト: askovpen/binkleyforce
/* SM1 */
static int sm_rx_sendnak(s_rx_emsidat *d)
{
	if( ++d->tries > 6 )
	{
		log("too many tries resyncing with remote");
		return(SME);
	}
	
	DEB((D_HSHAKE, "sm_rx_sendnak: try number %d", d->tries));
	
	if( !d->caller )
	{
		if( conf_boolean(cf_emsi_slave_sends_nak)
		 && PUTSTR("**EMSI_NAKEEC3\r") < 0 )
			return SME;
		if( PUTSTR("**EMSI_REQA77E\r") < 0 )
			return SME;
	}
	else if( d->tries > 1 )
	{
		if( PUTSTR("**EMSI_NAKEEC3\r") < 0 )
			return SME;
	}

	if( FLUSHOUT() < 0 )
		return SME;
	
	return SM2;
}
コード例 #4
0
ファイル: prot_emsi.c プロジェクト: askovpen/binkleyforce
/* SM1 */
static int sm_tx_senddat(s_tx_emsidat *d)
{
	char *emsi_dat = NULL;
	char buf[8];
	
	if( ++d->tries > 6 )
	{
		log("too many tries sending emsi data");
		return(SME);
	}
	
	if( d->tries > 1 )
		log("emsi data send - retry %d", d->tries - 1);
	
	DEB((D_HSHAKE, "sm_tx_senddat: try number %d", d->tries));
	
	if( (emsi_dat = emsi_createdat(d->local_emsi)) == NULL )
	{
		log("cannot create emsi data packet");
		return(SME);
	}
	
	DEB((D_HSHAKE, "sm_tx_senddat: emsi: \"%s\"", emsi_dat));
	
	if( tty_puts(emsi_dat, 60) < 0 )
	{
		free(emsi_dat);
		return SME;
	}
	
	/*
	 * Calculate and send CRC-16 of our emsi packet
	 */
	sprintf(buf, "%04hX\r",
		(short unsigned)getcrc16xmodem(emsi_dat+2, strlen(emsi_dat+2)));
	
	free(emsi_dat); emsi_dat = NULL;
	
	if( PUTSTR(buf) < 0 || FLUSHOUT() < 0 )
		return SME;
	
	return SM2;
}
コード例 #5
0
static int tcp_sblk(char *buf, int len, int typ)
{
    Nopper();
    if (typ == TCP_CMD)
	Syslog('a', "tcp_sblk: cmd: %s", buf);
    else
	Syslog('a', "tcp_sblk: data: %d bytes", len);

    PUTCHAR(TCP_BLKSTRT);
    PUTCHAR(typ);
    PUTCHAR((len >> 8) & 0x0ff);
    PUTCHAR(len & 0x0ff);
    PUT(buf, len);
    PUTCHAR(TCP_BLKEND);
    FLUSHOUT();

    if (tty_status)
	WriteError("TCP: send error: %s", ttystat[tty_status]);
    return tty_status;
}
コード例 #6
0
ファイル: analyze.c プロジェクト: ChunHungLiu/timberwolf
DOUBLE analyze()
{

INT **number , i , net , net1 , net2 , num , cell ;
INT *count , different , cnum , c2num , *arraynet ;
INT num_nets , tot_cels ;
DOUBLE C , C1 , C2 , C3 , wireRatio ;
PINBOXPTR pinptr ;
INT comparex() ;
DOUBLE weight_past_runs( /* wireRatio */ ) ;

count  = (INT *) Ysafe_malloc( (1 + numcellsG) * sizeof( INT ) ) ;
number = (INT **) Ysafe_malloc( (1 + numnetsG) * sizeof( INT *) ) ;
howmanyS = (INT *) Ysafe_malloc( (1 + numnetsG) * sizeof( INT ) ) ;
arraynet = (INT *) Ysafe_malloc( (1 + numnetsG) * sizeof( INT ) ) ;
for( net = 0 ; net <= numnetsG ; net++ ) {
    number[net] = (INT *) Ysafe_malloc( (1 + numcellsG) * sizeof(INT) ) ;
}

for( net = 1 ; net <= numnetsG ; net++ ) {
    for( cell = 0 ; cell <= numcellsG ; cell++ ) {
	count[cell] = 0 ;
	number[net][cell] = 0 ;
    }
    for( pinptr=netarrayG[net]->pins;pinptr; pinptr = pinptr->next ){
	if( pinptr->cell <= numcellsG ) {
	    count[pinptr->cell] = 1 ;
	}
    }
    /*
     *  I would like to find the number of distinct nets
     */
    for( cell = 1 ; cell <= numcellsG ; cell++ ) { 
	if( count[cell] == 1 ) {
	    number[net][ ++number[net][0] ] = cell ;
	}
    }
}
/* ********************************************************** */
num_nets = 0 ;
tot_cels = 0 ;
for( net1 = 1 ; net1 <= numnetsG ; net1++ ) {
    if( number[net1][0] <= 1 ) {
	continue ;
    }
    num_nets++ ;
    tot_cels += number[net1][0] ;
}


OUT1("\n\n*************************************\n");
OUT2("AVERAGE NUMBER OF CELLS PER NET: %f\n",
		( (DOUBLE) tot_cels / (DOUBLE) num_nets	)  ) ;
OUT1("*************************************\n\n\n");
/* ********************************************************** */
for( net1 = 1 ; net1 <= numnetsG ; net1++ ) {
    if( number[net1][0] == 0 ) {
	howmanyS[net1] = 0 ;
	continue ;
    }
    if( number[net1][0] == 1 ) {
	number[net1][0] = 0 ;
	howmanyS[net1] = 0 ;
	continue ;
    }
    howmanyS[net1] = 1 ;
    for( net2 = net1 + 1 ; net2 <= numnetsG ; net2++ ) {
	if( number[net2][0] != number[net1][0] ) {
	    continue ;
	}
	different = 0 ;
	for( i = 1 ; i <= numcellsG ; i++ ) {
	    if( number[net2][i] != number[net1][i] ) {
		different = 1 ;
		break ;
	    }
	}
	if( ! different ) {
	    number[net2][0] = 0 ;
	    howmanyS[net1]++ ;
	}
    }
}

arraynet[0] = 0 ;
for( net = 1 ; net <= numnetsG ; net++ ) {
    if( howmanyS[net] <= 0 ) {
	continue ;
    }
    arraynet[ ++arraynet[0] ] = net ;
}
num = arraynet[0] ;
arraynet[0] = arraynet[ arraynet[0] ] ;
Yquicksort( (char *) arraynet ,  num , sizeof( INT ), comparex  ) ;
/*  sorted: most occurrences first  */

num = 0 ;
cnum = 0 ;
c2num = 0 ;
for( net = 1 ; net <= numnetsG ; net++ ) {
    if( number[net][0] > 0 ) {
	cnum += number[net][0] - 1 ;
	c2num += number[net][0] ;
	num++ ;
    }
}

C = (DOUBLE) num / (DOUBLE) numcellsG ;
C1 = (DOUBLE) cnum / (DOUBLE) num ;
C2 = (DOUBLE) c2num / (DOUBLE) num ;
C3 = (DOUBLE) cnum / (DOUBLE)(numcellsG - 1) ;
OUT1("\n\n\n**********************************************\n\n");
OUT1("The average number of distinct nets per cell is\n");
OUT2("given by: %6.2f\n\n", C );
OUT1("The average number of cells per net is\n");
OUT2("given by: %6.2f\n\n", C2 );
OUT1("The average number of other cells per net is\n");
OUT2("given by: %6.2f\n\n", C1 );
OUT1("The ratio of total cells specified per net to\n");
OUT2("numcells is given by: %6.2f\n\n", C3 );
OUT1("The average number of cells connected to a cell is\n");
OUT2("given by: %6.2f\n\n", C * C1 );
OUT1("**********************************************\n\n\n");
wireRatio = EXPECTEDWIRERATIO ;

OUT2("Expected Wire Reduction Relative to Random:%6.2f\n\n",wireRatio);
FLUSHOUT();

wireRatio = weight_past_runs( wireRatio ) ;
sprintf( YmsgG,"\n\nWire ratio updated to:%4.2f\n\n", wireRatio ) ;
M( MSG, "analyze", YmsgG ) ;

return( wireRatio );
}
コード例 #7
0
ファイル: prot_zmsend.c プロジェクト: askovpen/binkleyforce
/* ------------------------------------------------------------------------- */
int tx_zmodem(s_protinfo *pi, bool caller)
{
	int   startblk  = 64;  /* Initial Zmodem block size                  */
	int   minblk    = 64;  /* Minimal Z-protocol block size              */
	int   maxblk    = 1024;/* Maximal Z-protocol block size              */
	int   blocklen  = 0;   /* Length of transmitted blocks               */
	int   goodblk   = 0;   /* How many blocks we sent w/o ZRPOS'tion :)  */
	int   txwindow  = 0;   /* Tranmitter window size (0 means streaming) */
	int   newcnt    = 0;   /* Count free bytes in receiver's buffer      */
	int   rxbuflen  = 0;   /* Receiver's max buffer length               */
	int   rxlastpos = 0;   /* Receiver's last reported offset            */
	int   beenhere  = 0;   /* How many times we've been ZRPOS'd same place */
	long  bytescnt  = 0;   /* Received bytes(current offset)             */
	long  lastsync  = 0;   /* Last offset to which we got a ZRPOS        */
	char  zconv     = 0;   /* Local ZMODEM file conversion request       */
	char  zmanag    = 0;   /* Local ZMODEM file management request       */
	char  ztrans    = 0;   /* Local ZMODEM file translation request      */
	char  zexten    = 0;   /* Local ZMODEM file extended options         */
	char *txbuf     = NULL;/* Buffer with ZMAXBLOCKLEN size              */
	int   zrinitcnt = 0;   /* Count received ZRINITs                     */
	int   rxflags1  = 0;
	int   rxflags2  = 0;
	int   txtries   = 0;
	int   junkcnt   = 0;
	int   initacked = 0;   /* TRUE when at least one ZRQINIT was sent    */
	                       /* after first ZRINIT was received            */
	int   rc        = 0;   /* Our return code                            */
	int   dtype, n;
	int   ftype;
	char  c, *p;
	long unsigned crc32;
	enum  ztxstates txstate;
	time_t deadtimer;
	
	log("start %s send", Protocols[state.handshake->protocol]);
	DEB((D_PROT, "start %s send", Protocols[state.handshake->protocol]));
	
	/* Set time transfer started at */
	if( pi->start_time == 0 )
		pi->start_time = time(NULL);
	
	txbuf      = (char *)xmalloc(ZMAXBLOCKLEN+1);
	zconv      = ZCBIN;
	maxblk     = (state.handshake->protocol == PROT_ZMODEM) ? 1024 : 8192;
	
	/* Set initial block size (default is 128b) */
	if( (startblk = conf_number(cf_zmodem_start_block_size)) > 0 )
	{
		if( startblk%64 || startblk > maxblk || startblk < 64 )
			startblk = 256;
	} else 
		startblk = 256;
	
	blocklen  = startblk;
	txwindow  = conf_number(cf_zmodem_tx_window);
	Z_Rxwait  = ZWAITTIME;
	Z_Rxtout  = ZRXTIMEOUT;
	txstate   = ZTX_START;

	timer_set(&deadtimer, ZDEADTIMER);
	
	setalarm(Z_Rxtout);
	
	/*
	 * At zmodem batches send empty netmail packet
	 * if no real outgoing traffic available
	 */
	if( !pi->send_left_size && conf_boolean(cf_zmodem_send_dummy_pkt) )
		zmodem_add_empty_packet(pi);
	
	while(1)
	{
		if( timer_expired(deadtimer) )
		{
			log("brain dead! (abort)");
			gotoexit(PRC_LOCALABORTED);
		}
		
		if( txstate == ZTX_RQINIT || txstate == ZTX_FINFO
		 || txstate == ZTX_EOF    || txstate == ZTX_FIN )
		{
#ifdef DEBUG
			if( txtries ) DEB((D_PROT, "tx_zmodem: try #%d", txtries));
#endif			
			if( ++txtries > ZMAXTRIES )
			{
				log("out of tries");
				gotoexit(PRC_LOCALABORTED);
			}
		}
		
		switch(txstate) {
		case ZTX_START:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_START"));
			if( PUTSTR("rz\r") < 0 )
				gotoexit(PRC_ERROR);
			txtries = 0;
			txstate = ZTX_RQINIT;
			break;
			
		case ZTX_RQINIT:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_RQINIT"));
			stohdr(Z_Txhdr, 0L);
			if( zshhdr(ZRQINIT, Z_Txhdr) < 0 )
				gotoexit(PRC_ERROR);
			setalarm(Z_Rxtout);
			txstate = ZTX_RQINITACK;
			break;
			
		case ZTX_NEXTFILE:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_NEXTFILE"));
			if (pi->send) p_tx_fclose(pi);
			txtries = 0;
			txstate = p_tx_fopen(pi, NULL) ? ZTX_FIN : ZTX_FINFO;
			log("nextfile next state: %d", txstate);
			break;

		case ZTX_FINFO:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_FINFO"));
			
			zrinitcnt = 0;
			
			strnxcpy(txbuf, pi->send->net_name, ZMAXFNAME);
			
			p = txbuf + strlen(txbuf) + 1; 
			sprintf(p, "%ld %lo %lo 0 %ld %ld",
				(long)pi->send->bytes_total, (long)pi->send->mod_time,
				(long)pi->send->mode, (long)pi->send_left_num,
				(long)pi->send_left_size);
			
			DEB((D_PROT, "tx_zmodem: send \"%s\\000%s\"", txbuf, p));
			
			Z_Txhdr[ZF0] = zconv;	/* file conversion request */
			Z_Txhdr[ZF1] = zmanag;  /* file management request */
			Z_Txhdr[ZF2] = ztrans;  /* file transport request  */
			Z_Txhdr[ZF3] = zexten;
			
			if( zsbhdr(ZFILE, Z_Txhdr) < 0 )
				gotoexit(PRC_ERROR);
			if( zsdata(txbuf, (p - txbuf) + strlen(p), ZCRCW, 0) < 0 )
				gotoexit(PRC_ERROR);
			
			setalarm(Z_Rxtout);
			txstate = ZTX_FINFOACK;
			break;
			
		case ZTX_STARTDATA:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_STARTDATA"));
			
			newcnt   = rxbuflen;
			junkcnt  = 0;
			
			stohdr(Z_Txhdr, pi->send->bytes_sent);
			if( zsbhdr(ZDATA, Z_Txhdr) < 0 )
				gotoexit(PRC_ERROR);
			
			txstate = ZTX_DATA;
			break;
			
		case ZTX_DATA:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_DATA"));
			
			timer_set(&deadtimer, ZDEADTIMER);
			setalarm(Z_Rxtout); /* Remove annoing timeouts! */
			
			if( (n = p_tx_readfile(txbuf, blocklen, pi)) < 0 )
			{
				/* error occured, remote wait for DATA */
				/* so send null ZCRCE data subpacket   */
				if( zsdata(txbuf, 0, ZCRCE, 0) < 0 )
					gotoexit(PRC_ERROR);
				txstate = ZTX_NEXTFILE;
				break;
			}
		
			if( pi->send->eofseen )
				dtype = ZCRCE;
			else if( junkcnt > 6 )
				dtype = ZCRCW;
			else if( bytescnt == lastsync )
				dtype = ZCRCW;
			else if( rxbuflen && (newcnt -= n) <= 0 )
				dtype = ZCRCW;
			else if( txwindow && (bytescnt - rxlastpos + n) >= txwindow )
				dtype = ZCRCQ;
			else
				dtype = ZCRCG;

			if( (rc = p_info(pi, 0)) )
				gotoexit(rc);
			
			if( zsdata(txbuf, n, dtype, pi->send->bytes_sent) < 0 )
				gotoexit(PRC_ERROR);
			
			if( ++goodblk > 5 && blocklen*2 <= maxblk )
			{
				goodblk = 0;
				blocklen *= 2;
				DEB((D_PROT, "tx_zmodem: new blocklen = %ld byte(s)", blocklen));
			}
			
			bytescnt = pi->send->bytes_sent += n;
			
			if( dtype == ZCRCW )
			{
				junkcnt = 0;
				setalarm(Z_Rxtout);
				txstate = ZTX_CRCWACK;
				break;
			}
			else if( dtype == ZCRCQ )
			{
				junkcnt = 0;
				setalarm(Z_Rxtout);
				txstate = ZTX_CRCQACK;
				break;
			}
			else if( dtype == ZCRCE )
			{
				txtries = 0;
				txstate = ZTX_EOF;
				break;
			}
			
			if( CHARWAIT(0) )
			{
				while( (rc = GETCHAR(1)) != ZTIMER )
				{
					if( rc < 0 )
					{
						gotoexit(PRC_ERROR);
					}
					else if( rc == CAN || rc == ZPAD )
					{
						DEB((D_PROT, "tx_zmodem: got ZPAD or CAN!"));
						setalarm(Z_Rxtout);
						txstate = ZTX_READCHECK;
						break;
					}
					else if( rc == XOFF || rc == (XOFF|0200) )
					{
						DEB((D_PROT, "tx_zmodem: got XOFF"));
						if( GETCHAR(5) < 0 )
							gotoexit(PRC_ERROR);
						break;
					}
					else if( rc == XON  || rc == (XON|0200) )
					{
						DEB((D_PROT, "tx_zmodem: got XON"));
					}
					else
					{
						junkcnt++;
						DEB((D_PROT, "tx_zmodem: got JUNK = 0x%x (junkcnt = %d)",
							rc, junkcnt));
					}
				} /* end of while( rc != ZTIMER ) */
			} /* end of if( CHARWAIT(0) ) */
			break;
		
		case ZTX_EOF:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_EOF"));
			
			stohdr(Z_Txhdr, pi->send->bytes_sent);
			if( zsbhdr(ZEOF, Z_Txhdr) < 0 )
				gotoexit(PRC_ERROR);
			
			setalarm(Z_Rxtout);
			txstate = ZTX_EOFACK;
			break;
			
		case ZTX_FIN:
			DEB((D_PROT, "tx_zmodem: entering state ZTX_FIN"));
			
			stohdr(Z_Txhdr, 0L);
			if( zshhdr(ZFIN, Z_Txhdr) < 0 )
				gotoexit(PRC_ERROR);
			
			setalarm(Z_Rxtout);
			txstate = ZTX_FINACK;
			break;
			
		default:
			/* Ignore them all */
			break;
		} /* end of switch(txstate) */
	
		if( txstate != ZTX_START  && txstate != ZTX_RQINIT
		 && txstate != ZTX_FINFO  && txstate != ZTX_DATA
		 && txstate != ZTX_EOF    && txstate != ZTX_FIN )
		{
			switch( ftype = zgethdr(Z_Rxhdr) ) {
			case ZCAN:
				gotoexit(PRC_REMOTEABORTED);
				break;
				
			case ZHANGUP:
			case ZEXIT:
				gotoexit(PRC_ERROR);
				break;
				
			case ZTIMER:
				log("time out");
				
				if( txstate == ZTX_READCHECK )
					zsdata(txbuf, 0, ZCRCE, 0);
				
				switch(txstate) {
				case ZTX_RQINITACK: txstate = ZTX_RQINIT;    break;
				case ZTX_FINFOACK:  txstate = ZTX_FINFO;     break;
				case ZTX_READCHECK: txstate = ZTX_STARTDATA; break;
				case ZTX_CRCWACK:   txstate = ZTX_STARTDATA; break;
				case ZTX_CRCQACK:   txstate = ZTX_STARTDATA; break;
				case ZTX_EOFACK:    txstate = ZTX_EOF;       break;
				case ZTX_FINACK:    txstate = ZTX_FIN;       break;
				default:            break;
				}
				break;
				
			case ZERROR:
			case ZCRCERR:
				/* NAK them all! */
				stohdr(Z_Txhdr, 0L);
				if( zshhdr(ZNAK, Z_Txhdr) < 0 )
					gotoexit(PRC_ERROR);
				break;
				
			case ZRQINIT:
				if( txstate == ZTX_RQINITACK )
				{
					if( Z_Rxhdr[0] == ZCOMMAND )
						break;
					
					stohdr(Z_Txhdr, 0L);
					if( zshhdr(ZNAK, Z_Txhdr) < 0 )
						gotoexit(PRC_ERROR);
					
					txstate = ZTX_RQINIT;
				}
				else if( txstate == ZTX_FINFOACK )
				{
					/* remote is sender - abort */
					log("zmodem: remote is sender");
					gotoexit(PRC_LOCALABORTED);
				}
				break;
				
			case ZRINIT:
				if( txstate == ZTX_RQINITACK )
				{
					if( initacked == 0 )
					{
						/* Be sure ack first ZRINIT */
						stohdr(Z_Txhdr, 0L);
						if( zshhdr(ZRQINIT, Z_Txhdr) < 0 )
							gotoexit(PRC_ERROR);
						initacked = 1;
					}
					
					/* Get receiver's options */
					rxflags1  = (0377 & Z_Rxhdr[ZF0]);
					rxflags2  = (0377 & Z_Rxhdr[ZF1]);
					Z_Txfcs32 = (rxflags1 & CANFC32);
					Z_Ctlesc |= (rxflags1 & TESCCTL);
					rxbuflen  = (0377 & Z_Rxhdr[ZP0]);
					rxbuflen += ((0377 & Z_Rxhdr[ZP1])<<8);
					
					/* No ZCRCQ if remote doesn't indicate */
					/* FDX ability                         */ 
					if( !(rxflags1 & CANFDX) )
						txwindow = 0;
				
					DEB((D_PROT, "tx_zmodem: Z_Txfcs32 = %d Z_Ctlesc = %d",
						Z_Txfcs32, Z_Ctlesc));
					DEB((D_PROT, "tx_zmodem: rxbuflen = %d blocklen = %d",
						rxbuflen, blocklen));
					DEB((D_PROT, "tx_zmodem: txwindow = %u",
						txwindow));
				
					txstate   = ZTX_NEXTFILE;
				}
				else if( txstate == ZTX_FINFOACK )
				{
					/* Possible they didn't see */
					/* our file information     */
					if( ++zrinitcnt > 2 )
						txstate = ZTX_FINFO;
				}
				else if( txstate == ZTX_READCHECK
				      || txstate == ZTX_CRCQACK
				      || txstate == ZTX_CRCWACK )
				{
					if( txstate == ZTX_READCHECK
					 || txstate == ZTX_CRCQACK )
						zsdata(txbuf, 0, ZCRCE, 0);
					
					/* Assume file normaly sent ? */
					log("assume file normaly sent");
					
					pi->send->status = FSTAT_SUCCESS;
					txstate = ZTX_NEXTFILE;
				}
				else if( txstate == ZTX_EOFACK )
				{
					/* ok, send next */
					pi->send->status = FSTAT_SUCCESS;
					txstate = ZTX_NEXTFILE;
				}
				else if( txstate == ZTX_FINACK )
				{
					/* Possible we should ignore  */
					/* first ZRINIT. Because they */
					/* didn't see our first ZFIN  */
					/* But I'm soo lazy .. :))    */
					txstate = ZTX_FIN;
				}
				break;
				
			case ZACK:
				if( txstate == ZTX_CRCWACK )
				{
					rxlastpos = Z_Rxpos;
					if( pi->send->bytes_sent == Z_Rxpos )
						txstate = ZTX_STARTDATA;
				}
				else if( txstate == ZTX_READCHECK
				      || txstate == ZTX_CRCQACK )
				{
					rxlastpos = Z_Rxpos;
					txstate   = ZTX_DATA;
				}
				break;
				
			case ZSKIP:
				if( txstate == ZTX_FINFOACK
				 || txstate == ZTX_READCHECK
				 || txstate == ZTX_CRCQACK
				 || txstate == ZTX_CRCWACK
				 || txstate == ZTX_EOFACK )
				{
					if( txstate == ZTX_READCHECK
					 || txstate == ZTX_CRCQACK )
						zsdata(txbuf, 0, ZCRCE, 0);
					
					if( txstate == ZTX_READCHECK )
						CLEAROUT();
					
					pi->send->status = FSTAT_SKIPPED;
					log("remote side skipped file");
					
					txstate = ZTX_NEXTFILE;
				}
				break;
				
			case ZFIN:
				/* BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG! */
				/* BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG! */
				log(" BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG!BUG! ");
				if( txstate == ZTX_FINACK )
				{
					if( PUTSTR("OO") == 0 )
						FLUSHOUT();
					gotoexit(PRC_NOERROR);
				}
				break;
				
			case ZRPOS:
				if( txstate == ZTX_FINFOACK
				 || txstate == ZTX_READCHECK
				 || txstate == ZTX_CRCQACK
				 || txstate == ZTX_CRCWACK
				 || txstate == ZTX_EOFACK )
				{
					rxlastpos = Z_Rxpos;
					
					/* Clear modem buffers */
					/* if( txstate != FINFOACK ) SENDBREAK(); */
					if( txstate == ZTX_READCHECK ) CLEAROUT();

					if( txstate == ZTX_READCHECK
					 || txstate == ZTX_CRCQACK )
					{
						if( zsdata(txbuf, 0, ZCRCE, 0) < 0 )
							gotoexit(PRC_ERROR);
					}
					
					/* Reset EOF flag! */
					pi->send->eofseen = FALSE;
					
					/* Check pos */
					if( (Z_Rxpos || txstate != ZTX_FINFOACK)
					 && p_tx_rewind(pi, Z_Rxpos) )
					{
						logerr("can't send file from requested position");
						/* Open next file for send */
						txstate = ZTX_NEXTFILE;
						break;
					}
					
					if( txstate == ZTX_FINFOACK )
					{
						if( Z_Rxpos )
						{
							log("resyncing at offset %d", Z_Rxpos);
							pi->send->bytes_skipped = Z_Rxpos;
						}
					}
					else if( txstate == ZTX_READCHECK
					      || txstate == ZTX_CRCWACK
					      || txstate == ZTX_CRCQACK )
					{
						goodblk = 0;
						if( lastsync >= Z_Rxpos && ++beenhere > 4 )
							if( blocklen > minblk )
							{
								blocklen /= 2;
								DEB((D_PROT, "tx_zmodem: falldown to %ld BlockLen", blocklen));
							}
					}
					
					lastsync = bytescnt = pi->send->bytes_sent = Z_Rxpos;
					
					if( txstate == ZTX_FINFOACK )
						--lastsync;
					
					txstate = ZTX_STARTDATA;
				}
				break;
				
			case ZNAK:
				switch(txstate) {
				case ZTX_RQINITACK: txstate = ZTX_RQINIT; break;
				case ZTX_FINFOACK:  txstate = ZTX_FINFO;  break;
				case ZTX_EOFACK:    txstate = ZTX_EOF;    break;
				case ZTX_FINACK:    txstate = ZTX_FIN;    break;
				default:            break;
				}
				break;
				
			case ZCRC:
				if( txstate == ZTX_FINFOACK )
				{
					log(" Send file's CRC-32 ");
					crc32 = 0xFFFFFFFFL;
					
					while( ((c = getc(pi->send->fp)) != EOF) && --Z_Rxpos )
						crc32 = updcrc32(c, crc32);
					
					crc32 = ~crc32;
					
					clearerr(pi->send->fp); /* Clear EOF */
					fseek(pi->send->fp, 0L, 0);
					
					stohdr(Z_Txhdr, crc32);
					if( zsbhdr(ZCRC, Z_Txhdr) < 0 )
						gotoexit(PRC_ERROR);
				}
				break;
				
			case ZCHALLENGE:
				if( txstate == ZTX_RQINITACK )
				{
					/* Echo receiver's challenge number */
					stohdr(Z_Txhdr, Z_Rxpos);
					if( zshhdr(ZACK, Z_Txhdr) < 0 )
						gotoexit(PRC_ERROR);
					txstate = ZTX_RQINIT;
				}
				break;
				
			case ZCOMMAND:
				if( txstate == ZTX_RQINITACK )
				{
					txstate = ZTX_RQINIT;
				}
				break;

			case ZABORT:
				log("remote requested for session abort");
				stohdr(Z_Txhdr, 0L);
				if( zshhdr(ZFIN, Z_Txhdr) < 0 )
					gotoexit(PRC_ERROR);
				gotoexit(PRC_REMOTEABORTED);
				break;
				
			case ZFERR:
				if( txstate == ZTX_FINFOACK
				 || txstate == ZTX_READCHECK
				 || txstate == ZTX_CRCWACK
				 || txstate == ZTX_CRCQACK
				 || txstate == ZTX_EOFACK )
				{
					if( txstate == ZTX_READCHECK
					 || txstate == ZTX_CRCQACK )
					{
						if( zsdata(txbuf, 0, ZCRCE, 0) < 0 )
							gotoexit(PRC_ERROR);
					}

					pi->send->status = FSTAT_REFUSED;
					log("remote side refused file");
					
					txstate = ZTX_NEXTFILE;
				}
				break;
				
			default:
				log("got unexpected frame %d", ftype);
				break;
			} /* end of switch(hdr) */
		} /* end of if */
	} /* end of while */
	
exit:
	DEB((D_PROT, "tx_zmodem: SEND exit = %d", rc));
	
	setalarm(0);
	
	if (pi->send) p_tx_fclose(pi);
	
	if( txbuf ) {
		free(txbuf);
		txbuf = NULL;
	}
	
	
	return(rc);
}
コード例 #8
0
ファイル: prot_emsi.c プロジェクト: askovpen/binkleyforce
/* SM3 */
static int sm_rx_getdat(s_rx_emsidat *d)
{
	int rc = 0;
	int pos = 0;
	int emsi_len = 0;
	short unsigned ourcrc;
	short unsigned remcrc;
	char *emsi_dat = NULL;
	
	if( d->tries_recv++ )
		log("emsi data receive - retry %d", d->tries_recv);
	
	/*
	 * At this point, there is a EMSI_DATXXXX packet in
	 * the buffer, there XXXX is the hex length of emsi
	 * data packet
	 */
	if( strspn(d->buf+8, "0123456789abcdefABCDEF") != 4 )
		return SM1;
	
	if( sscanf(d->buf+8, "%04x", &emsi_len) != 1 )
		return SM1;
	
	/*
	 * Don't receive emsi packet's longer our "limit"
	 */
	if( emsi_len > EMSI_MAXDAT )
	{
		CLEARIN();
		log("emsi data packet too long %db (maximum %db allowed)",
				emsi_len, EMSI_MAXDAT);
		return SM1;
	}
	
	/* Increase packet's length on CRC length */
	emsi_len += 16;
	
	emsi_dat = (char*)xmalloc(emsi_len + 1);
	strncpy(emsi_dat, d->buf, 12);
	pos = 12;
	
	while( pos < emsi_len )
	{
		if( timer_expired(d->mast_timer) )
			break;
		
		if( (rc = GETCHAR(1)) < 0 )
		{
			if( rc != TTY_TIMEOUT )
				break;
		}
		else
		{
			emsi_dat[pos++] = (unsigned char)rc;
			emsi_dat[pos  ] = '\0';
		}
	}
	
	if( pos != emsi_len )
	{
		/* Fatal error occured */
		DEB((D_HSHAKE, "sm_rx_getdat: can't get emsi_dat packet"));
		DEB((D_HSHAKE, "sm_rx_getdat: buffer: \"%s\"",
				string_printable(emsi_dat)));
		free(emsi_dat);
		return SME;
	}

	DEB((D_HSHAKE, "sm_rx_getdat: got \"%s\"",
			string_printable(emsi_dat)));

	/*
	 * Get CRC given by remote
	 */
	if( sscanf(emsi_dat + emsi_len - 4 , "%04hX", &remcrc) != 1 )
	{
		log("bad emsi data packet (can't get CRC16)");
		free(emsi_dat);
		
		return(SM1);
	}
	
	/*
	 * Calculate our own crc of the data packet
	 */
	ourcrc = getcrc16xmodem(emsi_dat, emsi_len-4);
	
	/*
	 * Compare our and remote CRCs
	 */
	if( ourcrc != remcrc )
	{
		DEB((D_HSHAKE, "sm_rx_getdat: our = %hX, remote = %hX",	ourcrc, remcrc));
		log("got emsi data packet with bad CRC");
		free(emsi_dat);
		
		return SM1;
	}
	
	/*
	 * Parse received emsi data packet. All obtained
	 * information will be stored in d->remote_emsi
	 */
	rc = emsi_parsedat(emsi_dat+12, d->remote_emsi);
	
	free(emsi_dat);
		
	if( rc )
	{
		log("received invalid emsi data packet");
		return SM1;
	}
	
	/* Send acknowlegment */
	if( PUTSTR("**EMSI_ACKA490\r**EMSI_ACKA490\r") < 0 )
		return SME;
	if( FLUSHOUT() < 0 )
		return SME;
	
	return SM0;
}
コード例 #9
0
ファイル: prot_emsi.c プロジェクト: askovpen/binkleyforce
/* SM2 */
static int sm_tx_waitseq(s_tx_emsidat *d)
{
	int rc, pos = 0;
	
	timer_set(&d->sync_timer, (d->tries > 1) ? 20 : 10);
	
	while(1)
	{
		if( timer_expired(d->mast_timer) )
		{
			DEB((D_HSHAKE, "sm_tx_waitseq: master timer expired"));
			log("master timer expired");
			return(SME);
		}
		
		if( timer_expired(d->sync_timer) )
		{
			DEB((D_HSHAKE, "sm_tx_waitseq: sync timer expired"));
			return(SM1);
		}
		
		if( (rc = GETCHAR(1)) < 0 )
		{
			if( rc != TTY_TIMEOUT )
			{
				DEB((D_HSHAKE, "sm_rx_waitseq: got ERROR/HANGUP"));
				return SME;
			}
		}
		else if( rc == XON || rc == XOFF )
		{
			/* Do nothing. Drop them down */
		}
		else if( rc == '*' )
		{
			memset(d->buf, '\0', sizeof(d->buf));
			pos = 0;
			d->emsi_seq = 1;
		}
		else if( d->emsi_seq && rc > ' ' && rc < '~' )
		{
			if( pos < sizeof(d->buf)-1 )
			{
				d->buf[pos++] = rc;
				d->buf[pos  ] = '\0';
			}
			
			if( pos == (sizeof(d->buf) - 1) )
			{
				DEB((D_HSHAKE, "sm_tx_waitseq: emsi buffer full \"%s\"", d->buf));
				
				d->emsi_seq = 0;
				
				if( !strncasecmp(d->buf, "EMSI_REQA77E", 12) )
				{
					/* Do nothing. Drop it down */
				}
				else if( !strncasecmp(d->buf, "EMSI_ACKA490", 12) )
				{
					/*
					 * Remote acknowleged our
					 * emsi data packet. exit.
					 */
					return SM0;
				}
				else if( !strncasecmp(d->buf, "EMSI_NAKEEC3", 12) )
				{
					/*
					 * Remote failed on our emsi data
					 * packet. Resend EMSI_DAT only after
					 * first EMSI_NAK
					 */
					DEB((D_HSHAKE, "sm_tx_waitseq: got NAK"));
					if( !d->nakcount++ )
						return SM1;
				}
				else if( !strncasecmp(d->buf, "EMSI_INQC816", 12) )
				{
					/*
					 * Do nothing. Just update sync timer
					 */
					return SM2;
				}
				else if( !strncasecmp(d->buf, "EMSI_DAT", 8) )
				{
					/*
					 * 1) We are calling system
					 * We got an echo of our sequence,
					 * possible they don't know about
					 * FIDO. yet :) Resend EMSI_INQ
					 * again.
					 * 2) We are asnwering system
					 * Think where is a stupid mailer
					 * that didn't seen our EMSI_ACK,
					 * so send it again in hope to the
					 * best
					 */
					DEB((D_HSHAKE, "sm_tx_waitseq: got echo \"%s\"",
							string_printable(d->buf)));

					if( d->caller )
					{
						/* Wait for a login prompt */
						sleep(2);
						
						if( PUTSTR("**EMSI_INQC816\r") < 0
						 || FLUSHOUT() < 0 )
							return SME;

						/* Wait for a password prompt */
						sleep(2);
						
						if( PUTSTR("**EMSI_INQC816\r") < 0
						 || FLUSHOUT() < 0 )
							return SME;
						
						return SM1;
					}
					else
					{
						/* Send acknowlegment */
						if( PUTSTR("**EMSI_ACKA490\r**EMSI_ACKA490\r") < 0 )
							return SME;
						if( FLUSHOUT() < 0 )
							return SME;
					}
				}
				else
				{
					DEB((D_HSHAKE, "got unexpected emsi sequence: \"%s\"",
							string_printable(d->buf)));
					log("got unexpected emsi sequence \"%s\"",
							string_printable(d->buf));
				}
			}
		}
		else if( d->emsi_seq )
		{
			d->emsi_seq = 0;
			DEB((D_HSHAKE, "sm_tx_waitseq: bad character 0x%02x in \"%s\"",
					rc, string_printable(d->buf)));
		}
	}

	return SME;
}
コード例 #10
0
ファイル: finalpin.c プロジェクト: collabchip/graywolf
/* perform a low temperature anneal on pins */
final_pin_place()
{

    INT i ;               /* counter */
    INT attempts ;        /* number of moves made */
    INT nummoves ;        /* number of moves to do on a cell */
    INT selection ;       /* select a cell with softpins */
    INT nsoftpin_cells ;  /* number of cells with softpins */
    CELLBOXPTR acellptr;  /* current cell with softpins */

    /* don't perform if cost only is specified in input file */
    /* scale data variable is necessary for recursive TimberWolfMC call */
    if( /* cost_onlyG || */ scale_dataG > 1 ){
	return ;
    }

    /* now check to see if we have any soft pins if not return */
    if( (nsoftpin_cells = (int) softPinArrayG[HOWMANY] ) == 0 ){
	return ;
    }

    /* make new site arrays for pins */
    for( i = 1; i <= nsoftpin_cells; i++ ){
	update_sites( softPinArrayG[i] ) ;
    }
    findcost() ;

    /* continue with a low Temp anneal */
    TG = 10.0 ;
    attempts = 0 ;
    if( overpenalG ){  
	/* make pinFactor 1 order more important than wirelength */
	pinFactorG =  10.0 * (DOUBLE) funccostG / (DOUBLE) overpenalG ;
	/* also set softPinArrayG to look at cells with overlap */
    } else {
	/* otherwise use previous pinFactorG */
	/* make 1 order more important */
	pinFactorG *= 10.0 ;
    }

    while( attempts < attmaxG ) {

	/* to make pin moves more efficient, use softPinArrayG */
	/* which keeps track of all softcells which have pins */
	/* which can move. softPinArrayG[0] holds size of array */
	selection = PICK_INT( 1, (int) softPinArrayG[HOWMANY] );
	/* now get cellptr */
	acellptr = softPinArrayG[selection] ;
	/* pick number of pins moves to be attempted */
	/* PIN_MOVE is beginning of sequence.  */
	if( overpenalG && !(doPartitionG) ){  
	    /* if a penalty exists do many moves */
	    nummoves = acellptr->numsoftpins ;
	} else {
	    nummoves = 1 ; /* no penalty try to reduce wirelen */
	}

	/* *********** NOW EVALUATE THE PROPOSED MOVE ********* */
	/* now try softpin moves */
	for( i=1; i<= nummoves; i++ ){
	    selectpin( acellptr ) ;
	}
	/* *********** END OF PROPOSED MOVE  EVALUATION ********* */
	attempts++ ;

	D( "finalpin", checkcost() ) ; /* if debug on check cost after each move */

    } /* ****** END OF ANNEALING LOOP **************** */

    /* verify incremental and current costs after each iteration */
    D( "finalpin", checkcost() ) ;

    /* ----------------------------------------------------------------- 
       now output statistics for this temperature.
    */

    OUT1("\n\nPin place optimizer\n");
    OUT1("\nI     T     funccost  overpen  x pinFact = overfill pinflips\n");
    OUT2("%3d ",iterationG ); 
    OUT2("%4.2le ",TG ); 
    OUT2("%4.2le ",(DOUBLE) funccostG ); 
    OUT2("%4.2le ",(DOUBLE) overpenalG ); 
    OUT2("%4.2le ",(DOUBLE) pinFactorG ); 
    OUT2("%4.2le ",(DOUBLE) overfillG ); 
    OUT3("%3d/%3d\n\n",flippG,attpG ); 
    FLUSHOUT() ;

    return ;
} /* end final_pin_place */
コード例 #11
0
ファイル: sess_init.c プロジェクト: askovpen/binkleyforce
/* ------------------------------------------------------------------------- */
int session_init_incoming()
{
	int    c = 0;
	int    pos = 0;
	bool   canemsi = FALSE;
	bool   canyoohoo = FALSE;
	bool   canftsc = FALSE;
	char   buf[13];
	int    emsi_seq = 0;      /* start reading emsi sequence     */
	int    yoohoo_count = 0;  /* number of ENQ received          */
	int    tsync_count  = 0;  /* number of NAK or 'C' received   */
	int    yoohoo_need = 1;
	int    tsync_need = 1;
	time_t mast_timer = 0;    /* master timer, seems to be 60sec */
	time_t sync_timer = 0;
	long   options = conf_options(cf_options);
	int    unexp_count = 0;

	state.session = SESSION_UNKNOWN;
	
	//log("init");
	
	if( (options & OPTIONS_NO_EMSI) != OPTIONS_NO_EMSI ) {
		//log("can emsi");
		canemsi = TRUE;
	}
	if( (options & OPTIONS_NO_YOOHOO) != OPTIONS_NO_YOOHOO ) {
		//log("can yahoo");
		canyoohoo = TRUE;
	}
	if( (options & OPTIONS_NO_FTS1) != OPTIONS_NO_FTS1 ) {
		//log("can ftsc");
		canftsc = TRUE;
	}
	
	yoohoo_need = canemsi ? 2 : 1;
	tsync_need = (canemsi || canyoohoo) ? 2 : 1;

	if( PUTCHAR('\r') < 0 ) {
		log("error: cannot put char");
		return 1;
	}
	
	/*
	 * Output banner
	 */
	if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) {
		log("error: cannot put banner");
		return 1;
	}

	if( state.connstr )
	{
		/* Show connect string */
		if( PUTCHAR('[') < 0 ) {
			log("error: cannot put ']'");
			return 1;
		}
		if( PUTSTR(state.connstr) < 0 ) {
			log("error: cannot put connstr");
			return 1;
		}
		if( PUTSTR("]\n") < 0 ) {
			log("error: cannot put ']'");
			return 1;
		}
	}
	
	if( PUTSTR(BF_BANNERVER) < 0 || PUTCHAR(' ') < 0
	 || PUTSTR(BF_COPYRIGHT) < 0 || PUTCHAR('\n') < 0 ) {
		log("session_init_incoming error: output");
		return 1;
	}

	if( FLUSHOUT() < 0 ) {
		log("session_init_incoming error: flush");
		return 1;
	}
	
	/* Start timers */
	timer_set(&mast_timer, INCOMING_MAST_TIMER);
	timer_set(&sync_timer, INCOMING_SYNC_TIMER/2);
	
	/*
	 * Determine supported handshakes on called system
	 * (support for FTS-1, YooHoo, EMSI)
	 */
	 
	//log("begin loop");
	while(1)
	{
		if( timer_expired(mast_timer) )
		{
			log("session initialisation timed out");
			DEB((D_HSHAKE, "handshake initialisation timed out"));
			
			return 1;
		}
		
		if( timer_expired(sync_timer) )
		{
			DEB((D_HSHAKE, "rx_init: resyncing"));
			
			if( canemsi && PUTSTR("**EMSI_REQA77E\r") < 0 ) {
				log("session_init_incoming error: output");
				return 1;
			}

			if( FLUSHOUT() < 0 ) {
				log("session_init_incoming error: flush");
				return 1;
			}
			
			timer_set(&sync_timer, INCOMING_SYNC_TIMER);
		}
		
		/*
		 * Pickup next char
		 */
		if( (c = GETCHAR(1)) < 0 )
		{
			if( c != TTY_TIMEOUT )
			{
				DEB((D_HSHAKE, "rx_init: got TTY_ERROR/TTY_HANGUP"));
				return 1;
			}				
		}
		else if( c == XON || c == XOFF )
		{
			/* Do nothing. Drop them down */
		}
		else if( c == YOOHOO )
		{
			if( ++yoohoo_count >= yoohoo_need && canyoohoo )
			{
				DEB((D_HSHAKE, "rx_init: exit with YooHoo"));
				state.session = SESSION_YOOHOO;
				
				return 0;
			}
		}
		else if( c == TSYNC )
		{
			if( ++tsync_count > tsync_need && canftsc )
			{
				DEB((D_HSHAKE, "rx_init: exit with FTS-1"));
				state.session = SESSION_FTSC;
				
				return 0;
			}
		}
		else if( canemsi && c > ' ' && c < '~' )
		{
			tsync_count = 0;
			yoohoo_count = 0;
			
			if( c == '*' )
			{
				memset(buf, '\0', sizeof(buf));
				pos = 0;
				emsi_seq = 1;
			}
			else if( emsi_seq )
			{
				if( pos < sizeof(buf)-1 )
				{
					buf[pos++] = (char)(c & 0xff);
					buf[pos  ] = '\0';
				}
			
				if( pos >= sizeof(buf)-1 )
				{
					emsi_seq = 0;
					
					DEB((D_HSHAKE, "rx_init: emsi buffer full \"%s\"",
							string_printable(buf)));
					
					if( !strncasecmp(buf, "EMSI_INQC816", 12) )
					{
						DEB((D_HSHAKE, "rx_init: exit with EMSI"));
						state.session = SESSION_EMSI;
						
						return 0;
					}
					else if( !strncasecmp(buf, "EMSI", 4) )
					{
						log("unexpected emsi sequence \"%s\"",
								string_printable(buf));
						
						if( ++unexp_count > 10 )
						{
							log("too many unexpected emsi sequences");
							return 1;
						}
					}
				}
			}
		}
		else if( emsi_seq )
		{
			emsi_seq = 0;
			DEB((D_HSHAKE, "rx_init: bad character 0x%02x in \"%s\"",
					c, string_printable(buf)));
		}
	}
	
	return 1;
}
コード例 #12
0
ファイル: sess_init.c プロジェクト: askovpen/binkleyforce
/* ------------------------------------------------------------------------- */
int session_init_outgoing()
{
	int    c = 0;
	int    tries = 0;
	int    pos_emsi = 0;
	int    pos_intro = 0;
	bool   canemsi = FALSE;
	bool   canyoohoo = FALSE;
	bool   canftsc = FALSE;
	bool   canintro = FALSE;
	char   buf_emsi[13];
	char   buf_intro[256];
	int    emsi_seq = 0;    /* start reading emsi sequence     */
	int    enqcount = 0;    /* number of ENQ received          */
	int    nakcount = 0;    /* number of NAK or 'C' received   */
	int    enq_need = 1;
	int    nak_need = 1;
	time_t mast_timer = 0;  /* master timer, seems to be 60sec */
	time_t sync_timer = 0;  /* resync every .. seconds         */
	long   options = conf_options(cf_options);
	int    intro_lines = 0;
	int    intro_count = 0;
	int    unexp_count = 0;

	state.session = SESSION_UNKNOWN;
	
	if( (options & OPTIONS_NO_EMSI) != OPTIONS_NO_EMSI )
		canemsi = TRUE;
	if( (options & OPTIONS_NO_YOOHOO) != OPTIONS_NO_YOOHOO )
		canyoohoo = TRUE;
	if( (options & OPTIONS_NO_FTS1) != OPTIONS_NO_FTS1 )
		canftsc = TRUE;
	if( (options & OPTIONS_NO_INTRO) != OPTIONS_NO_INTRO )
		canintro = TRUE;
	
	enq_need = canemsi ? 2 : 1;
	nak_need = (canemsi || canyoohoo) ? 2 : 1;
	
	/*
	 * Put CR until any character received
	 */
	if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) {
		log("error: output");
		return 1;
	}
	
	while( !CHARWAIT(1) )
	{
		if( ++tries > 15 )
		{
			log("too much tries waking remote");
			return 1;
		}
		
		if( PUTCHAR('\r') < 0 || FLUSHOUT() < 0 ) {
			log("error: output");
			return 1;
		}
	}
	
#ifdef DEBUG
	if( tries > 0 )
		DEB((D_HSHAKE, "tx_init: remote waked on %d try", tries));
#endif
	
	/*
	 * Safety is the 1st law
	 */
	*buf_emsi = '\0';
	*buf_intro = '\0';
	
	/*
	 * Start timers
	 */
	timer_set(&mast_timer, OUTGOING_MAST_TIMER);
	timer_set(&sync_timer, OUTGOING_SYNC_TIMER*2);

	/*
	 * Determine supported handshakes on called system
	 * (support for FTS-1, YooHoo, EMSI)
	 */
	while(1)
	{
		if( timer_expired(mast_timer) )
		{
			log("session initialisation timed out");
			DEB((D_HSHAKE, "handshake initialisation timed out"));
			
			return 1;
		}
		
		if( timer_expired(sync_timer) )
		{
			DEB((D_HSHAKE, "tx_sendsync: resyncing"));
			
			if( canemsi && PUTSTR("**EMSI_INQC816**EMSI_INQC816") < 0 ) {
				log("error: output");
				return 1;
			}
			if( canyoohoo && PUTCHAR(YOOHOO) < 0 ) {
				log("error: output");
				return 1;
			}
			if( canftsc && PUTCHAR(TSYNC) < 0 ) {
				log("error: output");
				return 1;
			}
			if( canemsi && PUTCHAR('\r') < 0 ) {
				log("error: output");
				return 1;
			}

			if( FLUSHOUT() < 0 ) {
				log("error: flush");
				return 1;
			}
			
			timer_set(&sync_timer, OUTGOING_SYNC_TIMER);
		}
		
		/*
		 * Pickup next char
		 */
		c = GETCHAR(1);
		
		if( canintro && c > 0 )
		{
			if( c == XON || c == XOFF )
			{
				/* Do nothing. Drop them down */
			}
			else if( c == '\r' || c == '\n' )
			{
				if( pos_intro > 0 )
				{
					intro_lines += 1;
					intro_count += pos_intro;
					
					recode_intro_in(buf_intro);
					log("intro: \"%s\"",
						string_printable(buf_intro));
					
					pos_intro = 0;
					buf_intro[0] = '\0';
				}
			}
			else if( pos_intro < sizeof(buf_intro) - 1 )
			{
				buf_intro[pos_intro++] = (char)c;
				buf_intro[pos_intro  ] = '\0';
			}
			
			if( pos_intro >= sizeof(buf_intro) - 1 )
			{
				intro_lines += 1;
				intro_count += pos_intro;
				
				recode_intro_in(buf_intro);
				log("intro buffer is full");
				log("intro: \"%s\"",
					string_printable(buf_intro));
				
				pos_intro = 0;
				buf_intro[0] = '\0';
			}

			if( intro_lines >= INTRO_MAX_LINES )
			{
				log("stop logging intro: %d lines limit", intro_lines);
				canintro = FALSE;
			}
			else if( intro_count >= INTRO_MAX_SIZE )
			{
				log("stop logging intro: %d bytes limit", intro_count);
				canintro = FALSE;
			}
		}
		
		if( c < 0 )
		{
			if( c != TTY_TIMEOUT )
			{
				DEB((D_HSHAKE, "tx_init: got TTY_ERROR/TTY_HANGUP"));
				return 1;
			}				
		}
		else if( c == XON || c == XOFF )
		{
			/* Do nothing. Drop them down */
		}
		else if( c == ENQ )
		{
			if( enq_need && ++enqcount >= enq_need && canyoohoo )
			{
				DEB((D_HSHAKE, "tx_init: exit with YooHoo"));
				state.session = SESSION_YOOHOO;
				return 0;
			}
		}
		else if( c == TSYNC )
		{
			if( nak_need && ++nakcount > nak_need && canftsc )
			{
				DEB((D_HSHAKE, "tx_init: exit with FTS-1"));
				state.session = SESSION_FTSC;
				return 0;
			}
		}
		else if( canemsi && c > ' ' && c < '~' )
		{
			if( c != 'C' )
				nakcount = 0;
			
			enqcount = 0;
			
			if( c == '*' )
			{
				memset(buf_emsi, '\0', sizeof(buf_emsi));
				pos_emsi = 0;
				emsi_seq = 1;
			}
			else if( emsi_seq )
			{
				if( pos_emsi < sizeof(buf_emsi)-1 )
				{
					buf_emsi[pos_emsi++] = (char)c;
					buf_emsi[pos_emsi  ] = '\0';
				}
			
				if( pos_emsi >= sizeof(buf_emsi)-1 )
				{
					emsi_seq = 0;
					
					DEB((D_HSHAKE, "tx_init: emsi buffer full \"%s\"",
							string_printable(buf_emsi)));
					
					if( !strncasecmp(buf_emsi, "EMSI_REQA77E", 12)
					 || !strncasecmp(buf_emsi, "EMSI_NAKEEC3", 12) )
					{
						DEB((D_HSHAKE, "tx_init: exit with EMSI"));
						state.session = SESSION_EMSI;
						
						if( PUTSTR("**EMSI_INQC816\r") < 0
						 || PUTSTR("**EMSI_INQC816\r") < 0 ) {
							log("error: output");
							return 1;
						}
						if( FLUSHOUT() < 0 ) {
							log("error: output");
							return 1;
						}
						
						return 0;
					}
					else if( !strncasecmp(buf_emsi, "EMSI_INQC816", 12) )
					{
						/*
						 * Most probable it is echo of
						 * our own EMSI_INQ, try to send
						 * separated EMSI_INQ as user
						 * name and password to be sure
						 * that they understand us.
						 */

						/* Wait for a login prompt */
						sleep(3);
						
						if( PUTSTR("**EMSI_INQC816\r") < 0
						 || FLUSHOUT() < 0 ) {
							log("error: flush");
							return 1;
						}

						/* Wait for a password prompt */
						sleep(2);
						
						if( PUTSTR("**EMSI_INQC816\r") < 0
						 || FLUSHOUT() < 0 ) {
							log("error: output");
							return 1;
						}
						
						timer_set(&sync_timer, OUTGOING_SYNC_TIMER);
					}
					else if( !strncasecmp(buf_emsi, "EMSI", 4) )
					{
						log("unexpected emsi sequence \"%s\"",
								string_printable(buf_emsi));
						
						if( ++unexp_count > 10 )
						{
							log("too many unexpected emsi sequences");
							return 1;
						}
					}
				}
			}
		}
		else if( emsi_seq )
		{
			emsi_seq = 0;
			DEB((D_HSHAKE, "sm_rx_waitseq: bad character 0x%02x in \"%s\"",
					c, string_printable(buf_emsi)));
		}
	}
	//log("session_init_outgoing: end loop");

	return 1;
}