?? efax.c
字號(hào):
break ; default: msg ( "I%s frame ignored", frname ( frame ) ) ; break ; } /* switch */ } /* do */ wrpage ( f, -1 ) ; /* remove last file */ return err ;}void getc2dcs ( cap session ){ char *p ; if ( ( p = sresponse ( "+FCS:", 0 ) ) != 0 ) str2cap ( p, session ) ; else if ( ( p = sresponse ( "+FDCS:", 0 ) ) != 0 ) str2cap ( p, session ) ;} /* Class 2 fax transmission. Retries each page up to NTXRETRY times. Transmission begins after DC2 or XON is received. Sends the data and sends appropriate post-page message. */int c2send ( MODEM *m, IFILE *f, int pages, cap local, char *header, pbmfont *font ){ int c=0, page, err=0, done=0, try ; int ppr, ppm=0, hsc=-1, good, noise=0 ; cap session = { 0,0,0,0, 0,0,0,0 } ; for ( page=0 ; ! err && ! done ; page++ ) { for ( try=good=0 ; ! err && ! done && ! good && try<NTXRETRY ; try++ ) { done = rdpage ( f, ! ( page==0 || try > 0 ), &ppm, local ) ; if ( done != 1 ) err = done ; if ( done ) continue ; if ( ppm == EOM ) /* send +FDIS= */ ; if ( cmd ( m, "+FDT", TO_C2B ) != CONNECT ) { err = 2 ; continue ; } getc2dcs ( session ) ; while ( ! err && ( c = tgetc ( m->f, TO_C2X ) ) != XON && c != DC2 ) if ( c == EOF ) { msg ( "Wno XON/DC2 received after CONNECT") ; break ; } else { msg ( "W+%s", cname ( c ) ) ; noise++ ; } if ( noise ) { msg ( "Wreceived (%d) characters while waiting to send", noise ) ; noise = 0 ; } err = send_data ( m, f, page, pages, local, session, header, font ) ; ckcmd ( m, &err, ppm == EOP ? "+FET=2" : ppm == EOM ? "+FET=1" : "+FET=0" , TO_C2PP, OK ) ; if ( sresponse ( "+FPTS:", &ppr ) || sresponse ( "+FPS:", &ppr ) ) ; else ppr = msg ( "Wno +FP[T]S response" ), 1 ; good = ppr & 1 ; } if ( ppm == EOP ) done = 1 ; if ( try >= NTXRETRY && ! good ) { err = msg ( "E2too many page send retries" ) ; cmd ( m, m->c20 ? "+FKS" : "+FK", T3S ) ; } } if ( ( sresponse ( "+FHNG:", &hsc ) || sresponse ( "+FHS:", &hsc ) ) && hsc > 0 ) err = msg ( "E2abnormal termination (code %d)", hsc ) ; return err ; }/* Class 2 fax reception. Send fax data receive command. If response is OK, then no more pages are coming. If it's CONNECT receive the data for one page. Returns 0 or 2 for errors. */int c2receive ( MODEM *m, OFILE *f, cap local, int maxpgerr ){ int err=0, done=0, page, good, nerr, hsc, c=0 ; cap session = { 0,0,0,0, 0,0,0,0 } ; for ( page=0 ; ! err && ! done ; page++ ) { err = wrpage ( f, page ) ; if ( ! err && ( c = cmd ( m, "+FDR", TO_C2R ) ) == CONNECT ) { getc2dcs ( session ) ; tputcnow ( m, m->startchar, -1 ) ; err = receive_data ( m, f, session, &nerr ) ; good = nerr < maxpgerr ; if ( cmd ( m, 0, TO_C2EOR ) != OK ) err = msg ( "E2no response after sending data" ) ; if ( good ) msg ( "ITreceived -> %s", f->cfname ) ; /* +FPTS= not available on Intel modems: ckcmd ( m, &err, good ? "+FPTS=1" : "+FPTS=2", T3S , OK ) ; */ } else { wrpage ( f, -1 ) ; if ( c == OK ) done = 1 ; else err = msg ( "E3receive (+FDR) command failed") ; } } if ( ( sresponse ( "+FHNG:", &hsc ) || sresponse ( "+FHS:", &hsc ) ) && hsc > 0 ) err = msg ( "E2abnormal termination (code %d)", hsc ) ; return err ;}/* Dial a number and send a fax. */int dial ( MODEM *m, char *s ){ int err=0, hsc=-1 ; char c, dsbuf [ 128 ] ; sprintf ( dsbuf , "D%.127s" , s ) ; msg ( "Idialing %s", dsbuf+1 ) ; c = cmd ( m, dsbuf, TO_A ) ; if ( c == ( m->c1 ? CONNECT : OK ) ) msg ( "Iconnected" ) ; else if ( c == BUSY ) err = msg ( "W1number is busy" ) ; else err = msg ( "E2can't establish session" ) ; if ( ( sresponse ( "+FHNG:", &hsc ) || sresponse ( "+FHS:", &hsc ) ) && hsc > 0 ) err = msg ( "E2abnormal termination (code %d)", hsc ) ; return err ;}/* Answer the phone. Open modem device and initialize it. Remove our lock if sharing device with outgoing calls. If waiting for call, wait for modem activity, else answer phone. Figure out what mode we answered in and handle call appropriately. Re-lock if necessary. Exec *getty if data call. Modems prompt as follows after answering: Class 0: CONNECT nnn for data; Class 1: FAX + CONNECT for fax, DATA + CONNECT nnn for data, just CONNECT for fax if +FAE=0; Class 2: CONNECT (data) or OK (fax). ("+FCON" and "CONNECT FAX" are status messages, not prompts). */int answer ( MODEM *m, char **lkfile, int wait, int share, int softaa, char *getty ){ enum connectmode { NONE, DATAMODE, FAXMODE } ; enum connectmode mode=NONE ; int datamode=0 ; /* true if answered in data mode */ int c=0, err=0 ; int hsc=-1 ; int crate = 19200 ; /* CONNECT rate */ if ( ! err && share ) err = unlockall ( lkfile ) ; if ( ! err && wait ) { msg ( "Iwaiting for activity") ; tdata ( m->f, -1 ) ; msg ( "Iactivity detected at ") ; } if ( ! err && share ) { msleep ( 200 ) ; /* let other programs lock port */ err = lockall ( lkfile ) ; } if ( ! err && softaa && *getty ) { if ( cmd ( m, ( wait ? 0 : "A" ), TO_DATAF ) == CONNECT ) { sresponse ( "CONNECT", &crate ) ; sresponse ( "+FHNG:", &hsc ) ; sresponse ( "+FHS:", &hsc ) ; mode = DATAMODE ; } else { int i ; /* abort data answer mode & set fax mode to try again */ for ( i=0 ; i<3 ; i++ ) if ( cmd ( m, m->c1 ? "+FCLASS=1" : ( m->c20 ? "+FCLASS=2.0" : "+FCLASS=2" ), -TO_RESET ) == OK ) break ; } } if ( ! err && mode == NONE ) { c = cmd ( m, ! wait || ( softaa && *getty ) ? "A" : 0, TO_A ) ; datamode = sresponse ( "DATA", 0 ) || sresponse ( "CONNECT DATA", 0 ) ; sresponse ( "CONNECT", &crate ) ; sresponse ( "+FHNG:", &hsc ) ; sresponse ( "+FHS:", &hsc ) ; if ( m->c1 ) mode = ( c == CONNECT ) ? ( datamode ? DATAMODE : FAXMODE ) : NONE ; else mode = ( c == CONNECT ) ? DATAMODE : ( c == OK ? FAXMODE : NONE ) ; } if ( err || hsc >= 0 ) mode = NONE ; if ( ! err ) switch ( mode ) { case DATAMODE : { char buf [ MAXGETTY ] ; msg ( "Idata call answered") ; sprintf ( buf , getty , crate, crate, crate, crate, crate, crate ) ; msg ( "Iexec'ing /bin/sh -c \"%s\"" , buf ) ; execl ( "/bin/sh" , "sh" , "-c" , buf , (void*) 0 ) ; err = msg ( "ES2exec failed:" ) ; break ; } case FAXMODE : msg ( "Ifax call answered") ; break ; case NONE: err = msg ( "E3unable to answer call") ; break ; } return err ;}/* Fax send/receive program for Class 1 or 2 fax modems. Returns 0 on success, 1 if number busy or device locked, 2 for errors, 3 for protocol errors, 4 if no modem response, 5 on fatal signal. */int main( int argc, char **argv){ int err=0, doneargs=0, c=0, locked, i, qfaxerr=0 ; char msgbuf [ MAXMSGBUF ] ; FILE *rfp; char *icmd[ MAXICMD ], *zcmd[ MAXICMD ], *lkfile [ MAXLKFILE+1 ] ; int nicmd=0, nzcmd=0, nlkfile=0 ; char *faxfile = FAXFILE ; TFILE faxdev ; MODEM modem = { 0, 0,0, T_CMD, DC2 }, *m = &modem ; int softaa=0, share=0, wait=0, reverse=0, ignerr=0 ; char *getty = "" ; char capinit [ CMDBUFSIZE ], idinit [ CMDBUFSIZE ] ; cap local = { DEFCAP } ; char localid [ IDLEN + 1 ] = "" ; int maxpgerr = 10 ; time_t t ; char *header = 0, headerbuf [ MAXLINELEN ] ; char *fontname = 0 ; pbmfont font ; IFILE ifile ; int pages = 0 ; OFILE ofile ; char *phnum="", *ansfname, fnamepat [ FILENAME_MAX ] ; modem.f = &faxdev ; cname ( 0 ) ; argv0 = argv[0] ; setvbuf ( LOGF , msgbuf , _IOFBF , MAXMSGBUF ) ; msg ( "I " Version " starts ") ; if ( strrchr ( argv0 , '/' ) ) argv0 = strrchr ( argv0 , '/' ) + 1 ; msg ( "I " Copyright " (compiled "__DATE__ " " __TIME__ ")" ) ; while ( ! err && ! doneargs && ( c=nextopt(argc,argv,"c:d:f:g:h:i:l:o:p:q:r:st:v:wx:z:T") ) != -1) { switch (c) { case 'c': err = str2cap ( optarg , local ) ; sprintf ( capinit , m->c20 ? "+FCC=%.*s" : "+FDCC=%.*s" , CMDBUFSIZE-7, optarg ) ; if ( ! err && ! m->c1 ) { optarg = capinit ; goto addopt ; } break ; case 'l': if ( strlen ( optarg ) > IDLEN ) msg("Wlocal ID (%s) truncated to 20 characters", optarg ) ; if ( strspn ( optarg, " +0123456789" ) != strlen ( optarg ) ) msg("Wlocal ID (%s) has non-standard characters", optarg ) ; sprintf ( localid, "%*.*s", IDLEN, IDLEN, optarg ) ; sprintf ( idinit , m->c20 ? "+FLI=\"%.*s\"" : "+FLID=\"%.*s\"" , CMDBUFSIZE-9, localid ) ; if ( ! m->c1 ) { optarg = idinit ; goto addopt ; } break ; case 'i': addopt: if ( nicmd < MAXICMD ) icmd [ nicmd++ ] = optarg ; else err = msg ( "E2too many modem init commands"); break ; case 'z': if ( nzcmd < MAXICMD ) zcmd [ nzcmd++ ] = optarg ; else err = msg ( "E2too many modem reset commands"); break ; case 'h': header = optarg ; break ; case 'f': fontname = optarg ; break ; case 'd': faxfile = optarg ; break ; case 'g': getty = optarg ; break ; case 'o': for ( ; *optarg ; optarg++ ) switch ( *optarg ) { case '0' : m->c20 = 1 ; break ; case '1' : m->c1 = 1 ; break ; case 'a' : softaa = 1 ; break ; case 'e' : ignerr = 1 ; break ; case 'r' : reverse = 1 ; break ; case 'x' : m->startchar = XON ; break ; case 'z' : m->cmdpause += T_CMD ; break ; default : msg ( "Wunrecognized protocol option (%c)", *optarg ) ; } break ; case 'q': if ( sscanf ( optarg , "%d", &maxpgerr ) != 1 ) err=msg ("E2bad quality (-q) argument (%s)", optarg ) ; break; case 'p': phnum = optarg ; optarg = optind < argc ? argv [ optind ] : "" ; /* fall through */ case 'r': ansfname = optarg ; doneargs=1 ; break; case 's': share = 1 ; break; case 't': if ( argv [ argc ] ) err = msg ("E2can't happen(unterminated argv)") ; newIFILE ( &ifile, FAX, argv + optind ) ; pages = argc - optind ; phnum = optarg ; doneargs=1 ; break; case 'v': verb = optarg ; break ; case 'w': wait = 1 ; break ; case 'x': if ( nlkfile < MAXLKFILE ) lkfile [ nlkfile++ ] = optarg ; else err = msg ( "E2too many lock files" ) ; break ; case 'T': /* test: begin+end session */ doneargs=1 ; break ; default : fprintf ( stderr, Usage, argv0 ) ; err = 2 ; break ; } } for ( i=0 ; i<argc ; i++ ) msg ( "Aargv[%d]=%s", i, argv[i]) ; zcmd [ nzcmd ] = icmd [ nicmd ] = lkfile [ nlkfile ] = 0 ; readfont ( fontname, &font ) ; if ( ! header ) strftime ( header = headerbuf , MAXLINELEN, "%c %%s -> P. %%d/%%d", ( t = time(0), localtime ( &t ) ) ) ; sigm = m ; sigcmd = zcmd ; siglkfile = lkfile ; if ( ! err ) err = begin_session ( m, faxfile, reverse, lkfile, icmd, ignerr ) ; locked = ( err == 1 ) ; if ( ! err ) switch ( c ) { case 't': err = dial ( m, phnum ) ; if ( ! err ) if ( m->c1 ) err = c1send ( m, &ifile, pages, local, localid, header, &font ) ; else err = c2send ( m, &ifile, pages, local, header, &font ) ; break ; case 'r': err = answer ( m, lkfile, wait, share, softaa, getty ) ; locked = err == 1 ; strftime ( fnamepat, FILENAME_MAX, *ansfname ? ansfname : "%m%d%H%M%S", ( t = time(0), localtime ( &t ) ) ) ; strncat ( fnamepat, ".%03d", FILENAME_MAX - strlen ( fnamepat ) ) ; newOFILE ( &ofile, FAX, fnamepat, 204, 196, 1728, 2287 ) ; if ( ! err ) if ( m->c1 ) err = c1receive ( m, &ofile, local, localid, maxpgerr, 0 ) ; else err = c2receive ( m, &ofile, local, maxpgerr ) ; break ; case 'p': if ( ! m->c1 ) { msg ("E2pollling only implemented for Class 1" ) ; } else { err = dial ( m, phnum ) ; if ( ! err ) err = c1receive ( m, &ofile, local, localid, maxpgerr, 1 ) ; } break ; case 'T': break ; } qfaxerr = err; if ( ! locked && err != 4 && m->f->fd >= 0 ) end_session ( m, zcmd, lkfile ) ; if (qfaxerr !=0) err = qfaxerr; msg ( "Idone, returning %d", err ) ; rfp = fopen(RESULT, "w"); fprintf(rfp, "%d", err); fclose(rfp); return err ;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -