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); }
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; }
/* 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; }
/* 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; }
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; }
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 ); }
/* ------------------------------------------------------------------------- */ 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); }
/* 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; }
/* 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; }
/* 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 */
/* ------------------------------------------------------------------------- */ 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; }
/* ------------------------------------------------------------------------- */ 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; }