⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 efax.c

📁 用于使用moden进行传真的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
  if ( ! err ) err = wrpage ( outf, rxpage ) ;  disbit=0x00 ;  for ( t=0 ; !err && t<T1 ; t+=T2+10 ) {    revcpy ( (uchar*) localid, fif ) ;    if ( !err )       err = putframe ( CSI | disbit | MORE_FR, buf, IDLEN, mf, -1 ) ;        mkdis ( local, fif, DEFDISLEN, 1, pages ) ;    if ( !err )       err = putframe ( DIS | disbit | SUB_FR, buf, DEFDISLEN, mf, -1 ) ;    frame = getfr ( mf, buf, 0 ) ;    if ( frame > 0 ) {      disbit = ( frame == DIS ) ? 0x80 : 0x00 ;      goto F_2 ;    }  }  if ( err ) goto C ;  else goto C_timeout ;   F:  /* get a command */  last = frame ;  frame = getfr ( mf, buf, 1 ) ;  if ( writepending ) {		/* do postponed file close/open */    writepending=0 ;    err = wrpage ( outf, rxpage ) ;    if ( err ) goto C ;  }  if ( frame < 0 ) {    if ( frame == -2 ) goto getdata ; /* data carrier detected */    if ( last == EOM ) goto R ;     else { err = msg ("E3 timed out waiting for command" ) ; goto B ; }  }   F_2:  switch ( frame ) {  case DTC:    goto D ;  case DIS:    try=0 ;    goto A ;      case DCS:     mkcap ( fif, session, 0 ) ;    printcap ( "session", session ) ;        cmd ( mf, "+FTS=1", T3S ) ;	/* make sure DCS is over */    gettrain ( mf, c1cmd [RCV][TRN][session[BR]], cps[session[BR]], &good ) ;    if ( putframe ( ( good ? CFR : FTT ) | disbit, buf, 0, mf, -1 ) ||	! good ) goto F ;  getdata:        outf->w=pagewidth[session[WD]];    outf->h=0;    outf->xres=204.0;    outf->yres=vresolution[session[VR]];    nerr = 0 ;      re_getdata:    if ( cmd ( mf, c1cmd [RCV][DTA][session[BR]], TO_FT ) != CONNECT )       goto F ;			/* +FCERROR -> DCS resent */        switch ( receive_data ( mf, outf, session, &nerr ) ) {    case 0:      good = nerr < maxpgerr ;      msg ( "I-received -> %s", outf->cfname ) ;      writepending=1 ;		/* ppm follows immediately, don't write yet */      rxpage++ ;      break ;    case 1:      /* no RTC, re-issue +FRM command */      goto re_getdata ;    default:      good = 0 ;      break ;    }    ckcmd ( mf, 0, 0, TO_RTCMD, NO ) ;    goto F ;    /* III: */  case PRI_EOM:  case PRI_MPS:  case PRI_EOP:    frame &=0xf7 ;		/* ignore PRocedure Interrupt bit */  case MPS:  case EOP:  case EOM:    putframe ( ( good ? MCF : RTN ) | disbit, buf, 0, mf, -1 ) ;    if ( good && frame == MPS ) goto getdata ;    else goto F ;      case DCN:    goto B ;      default:    err = msg ( "E3 unrecognized command" ) ;    goto B ;  } C_timeout:  err = msg ( "E3 no command/response from remote" ) ; C:  putframe ( DCN, buf, 0, mf, -1 ) ; B:  ckcmd ( mf, 0, "H", TO_RESET, OK ) ;	/* hang up */  if ( rxpage > 0 )     wrpage ( outf, -1 ) ;	/* remove last file */  return err ;}/* Check for hangup message.  Assumes hsc is initialized to a   negative value.  Returns 0 if no hangup message, 1 if there   was one.  If perr is not null, sets it to 2 if the hsc was   non-zero (error). */int gethsc ( int *hsc, int *perr ){  int err=0, i ;  if ( sresponse ( "+FHNG:", hsc ) || sresponse ( "+FHS:", hsc ) ) {    if ( hsc && *hsc > 0 ) {      err = msg ( "E2abnormal termination (code %d)", *hsc ) ;      for ( i=0 ; c2msg[i].min >= 0 ; i++ ) {	if ( *hsc >= c2msg[i].min && *hsc <= c2msg[i].max ) {	  msg ( "E %s", c2msg[i].msg ) ;	}      }      if ( perr && ! *perr ) {	*perr = 2 ;      }    } else {      err = 1 ;    }  }  return err ;}/* Print remote ID and store DCS values in session as per   responses since last command. */void getc2dcs ( cap session ){  char *p ;  if ( ( p = sresponse ( "+FTI:",  0 ) ) != 0 ||         ( p =  sresponse ( "+FTSI:", 0 ) ) != 0 ) {    msg ( "I- remote ID -> %s", p ) ;  }  if ( ( p = sresponse ( "+FCS:", 0 ) ) != 0 ||       ( p = sresponse ( "+FDCS:", 0 ) ) != 0 ) {    str2cap ( p, session ) ;    printcap ( "session", session ) ;  }}  /* Wait for a starting character XON or DC2.  Display & ignore   any other characters received. */void getstartc ( TFILE *mf ){  int c, noise ;    for ( noise=0 ; ( c = tgetc ( mf, TO_C2X ) ) != XON && c != DC2 ; noise++ ) {    if ( c == EOF ) {      msg ( "Wno XON/DC2 received after CONNECT") ;      break ;    } else {       msg ( "W-+%s", cname ( c ) ) ;       noise++ ;     }  }    if ( noise )    msg ( "W  : %d characters received while waiting to send", noise ) ;}  /* Class 2 send and receive.     If calling, polls if no files to send, otherwise sends.  If   not calling sends documents if files to send, else receives.   When sending, issues +FDIS to change session parameters if   file format changes, then sends +FDT followed by data and a   post-page message determined by format of next page, if any.   Retransmits each page up to NTXRETRY times.   When receiving extracts file format from responses to +FDR or   ATA and saves them in the file. Receives data to a file and   sets page transfer status if too many errors.   Returns 0 if OK or 2 on errors.  */int c2sndrcv (	      TFILE *mf, cap local, char *localid, 	      OFILE *outf, IFILE *inf, 	      int pages, char *header, faxfont *font, 	      int maxpgerr, int noretry, int calling ){  int err=0, done=0, page, pagetry, nerr, c, dp=0 ;  int ppm=0, good, hsc, changed ;  int remtx=0 ;  char *fname=0 ;  cap session = { 0,0,0,0, 0,0,0,0 } ;  char buf [ CMDBUFSIZE ] ;  hsc=-1 ;			/* will be set >= 0 on hangup */  if ( sresponse ( "+FPO", 0 ) ) {    remtx = 1 ;    msg ( "N remote has document(s) to send." ) ;  }  if ( calling ) {    if ( pages ) goto send ;    else goto poll ;  } else {    if ( pages ) goto pollserver ;    else goto receive ;  }  /* Class 2 Send */ pollserver:  /* with +FLP[L]=1 the modem should accept +FDT. */ send:    page=1 ;    pagetry=0 ;  while ( ! err && ! done ) {    err = rdpage ( inf, dp, &ppm, local, &changed ) ;    if ( ! err && changed ) {      sprintf ( buf, c20 ? "+FIS=%d,%d,%d,%d" : "+FDIS=%d,%d,%d,%d", 	       local[0], local[1], local[2], local[3] ) ;      ckcmd ( mf, 0, buf, TO_FT, OK ) ;      if ( gethsc ( &hsc, &err ) ) {	continue ;      }    }        ckcmd ( mf, &err, "+FDT", -TO_C2B, CONNECT ) ;    if ( err || gethsc ( &hsc, &err ) ) {       done=1 ;       continue ;     }    getc2dcs ( session ) ;     if ( ! c20 ) getstartc ( mf ) ;    send_data ( mf, inf, page, pages, local, session, header, font ) ;    pagetry++ ;    if ( c20 ) {      end_data ( mf, session, ppm, &good ) ;    } else {      end_data ( mf, session, 0, 0 ) ;      gethsc ( &hsc, &err ) ;      if ( ! err && hsc < 0 ) {	ckcmd ( mf, &err, ppm == EOP ? "+FET=2" : 	       ppm == EOM ? "+FET=1" : "+FET=0" , TO_C2PP, OK ) ;      }      gethsc ( &hsc, &err ) ;      if ( ! err && hsc < 0 ) {	if ( sresponse ( "+FPTS:", &good ) ) {	  good &= 1 ;		/* odd values mean received OK */	} else {			/* no +FPTS and +FHNG probably NG */	  good = gethsc ( 0, 0 ) ? 0 :  	    msg ( "W1no +FPTS response, assumed received" ) ;	}      }    }        if ( noretry ) good = 1;        if ( good ) {      fname = inf->page->fname ;      if ( fname ) msg ( "Isent -> %s", fname ) ;      pagetry=0 ;      page++ ;      dp = 1 ;      if ( ppm == EOP ) {	nextipage ( inf, 1 ) ;	/* skip ahead to mark all files done */	done = 1 ;      }    } else {      dp = 0 ;      if ( pagetry >= NTXRETRY )	err = msg ( "E2too many page send retries" ) ;    }    if ( gethsc ( &hsc, &err ) )  done=1 ;    if ( good && lastpage ( inf ) ) {      done = 1 ;    }  }  goto done ;  /* Class 2 Receive */ poll:  /* with +FSP[L]=1 and +FPO[LL]: the modem should now accept +FDR. */ receive:  getc2dcs ( session ) ;	/* get ATA responses */  done=0 ;  for ( page=0 ; ! err && ! done ; page++ ) {    if ( ! ( err = wrpage ( outf, page ) ) ) {      c = cmd ( mf, "+FDR", -TO_C2R ) ;      switch ( c ) {      case CONNECT:   	getc2dcs ( session ) ;    	outf->w=pagewidth[session[WD]];   	outf->h=0;	outf->xres=204.0;	outf->yres=vresolution[session[VR]];	nerr = 0 ;		tput ( mf, &startchar, 1 ) ;	if ( receive_data ( mf, outf, session, &nerr ) == 0 ) {	  good = nerr < maxpgerr ;	  msg ( "I-received -> %s", outf->cfname ) ;	} else { 	  good = 0 ;	}		ckcmd ( mf, &err, 0, TO_C2EOR, OK ) ;	if ( err || gethsc ( &hsc, &err ) )  { 	  wrpage ( outf, page+1 ) ;	  wrpage ( outf, -1 ) ;	  done=1 ; 	  continue ; 	}		if ( ! good ) {	  msg ( "Wreception errors" ) ;	  ckcmd ( mf, 0, c20 ? "+FPS=2" : "+FPTS=2",  T3S, OK ) ;	  if ( gethsc ( &hsc, &err ) ) continue ;	}	break ;      case OK:	wrpage ( outf, -1 ) ;	/* no more pages */	done=1 ;	if ( gethsc ( &hsc, &err ) ) continue ;	break ;      default:	wrpage ( outf, -1 ) ;	/* oops */	err = msg ( "E3receive (+FDR) command failed") ;	break ;      }    }  }    done:  if ( hsc < 0 ) ckcmd ( mf, 0, c20 ? "+FKS" : "+FK", TO_RESET, OK ) ;  return err ;}/* Dial the phone number given by string s.  If nowait is true   adds a ';' to the dial string to avoid waiting for a   CONNECTion (might allow ersatz polling).  Also resets the   global "nframes" if appropriate so getfr() and putframe() know   not to issue +FRH/+FTH. Returns 0 if dialed OK, 1 if busy, 2   on errors.  */int dial ( TFILE *f, char *s, int nowait ){  int err=0, hsc=-1 ;  char c, dsbuf [ 128 ], *p ;  sprintf ( dsbuf, nowait ? "D%.126s;" : "D%.127s" , s ) ;  msg ( "Idialing %s", dsbuf+1 ) ;  c = cmd ( f, dsbuf, TO_A ) ;  if ( ( p = sresponse ( "+FCSI:", 0 ) ) != 0 ||       ( p =  sresponse ( "+FCI:", 0 ) ) != 0 ) {    msg ( "I- remote ID -> %s", p ) ;  }  if ( nowait && c == OK ) {    msg ( "Icalled" ) ;    nframes = 1 ;  } else if ( c1 && c == CONNECT ) {    msg ( "Iconnected" ) ;     nframes = 0 ;  } else if ( !c1 && c == OK ) {    msg ( "Iconnected" ) ;   } else if ( c ==  BUSY ) {    err = msg ( "W1number is busy" ) ;   } else {    err = msg ( "E2dial command failed" ) ;  }  gethsc ( &hsc, err ? 0 : &err ) ;  return err ;}/* Figure out which mode the modem answered in (fax, data, voice   or none) based on modem class and responses to the previous   command.  Sets crate (connect rate) for DATAMODE and hsc   (hangup status code) if detects a class 2 hangup message. */enum connectmode { NONE, DATAMODE, FAXMODE, VOICEMODE } ; enum connectmode ansmode ( int *crate, int *hsc ){  enum connectmode mode = NONE ;  int x=0 ;  if ( c1 && sresponse ( "CONNECT", &x ) ) {    mode = x ? DATAMODE : FAXMODE ;  }  if ( !c1 && sresponse ( "OK", 0 ) ) {    mode = FAXMODE ;  }   if ( !c1 && ( sresponse ( "CONNECT", &x ) || sresponse ( "+FDM", 0 ) ) ) {    mode = DATAMODE ;  }   if ( sresponse ( "DATA", 0 ) || sresponse ( "CONNECT DATA", 0 ) ) {    mode = DATAMODE ;    sresponse ( "CONNECT", &x ) ;  }  if ( sresponse ( "FAX", 0 ) || sresponse ( "+FCO", 0 ) ) {    mode = FAXMODE ;  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -