?? efax.c
字號:
if ( gethsc ( hsc, 0 ) ) { mode = NONE ; } if ( DATAMODE && x ) *crate = x ; return mode ;}/* Answer the phone. 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 or *vcmd for data or voice calls. */int answer ( TFILE *f, char **lkfile, int wait, int share, int softaa, char *getty, char *vcmd, char *acmd ){ int err=0, c ; int crate=19200, hsc=-1, i ; enum connectmode mode=NONE ; if ( ! err && share ) { err = ttymode ( f, COMMAND ) ; if ( ! err ) err = unlockall ( lkfile ) ; } if ( ! err && wait ) { msg ( "Iwaiting for activity") ; tdata ( f, -1 ) ; msg ( "Iactivity detected") ; } if ( ! err && share ) { msleep ( 500 ) ; /* let other programs lock port */ err = lockall ( lkfile, 1 ) ; if ( err ) err = msg ( "W1can't answer: can't lock device" ) ; else err = ttymode ( f, COMMAND ) ; /* in case it was changed silently */ } for ( i=0 ; ! err && mode == NONE && ( i==0 || ( i==1 && softaa ) ) ; i++ ) { c = cmd ( f, wait ? 0 : acmd, ( i==0 && softaa ) ? TO_DATAF : TO_A ) ; if ( c == DATA ) cmd ( f, c1 ? "O" : 0, TO_A ) ; /* +FAE=1 weirdness */ mode = ansmode ( &crate, &hsc ) ; switch ( mode ) { case DATAMODE : msg ( "Idata call answered") ; if ( getty && *getty ) { char buf [ MAXGETTY ] ; if ( ckfmt ( getty, 6 ) ) { err = msg ( "E3 too many %%d escapes in command (%s)", getty ) ; } else { 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:" ) ; } } else { err = msg ( "E2no getty command defined for data call" ) ; } break ; case FAXMODE : nframes = 0 ; msg ( "Ifax call answered") ; break ; case VOICEMODE : msg ( "Ivoice call answered") ; if ( vcmd && *vcmd ) { char buf [ MAXGETTY ] ; if ( ckfmt ( vcmd, 6 ) ) { } else { sprintf ( buf, vcmd, f->fd, f->fd, f->fd, f->fd, f->fd, f->fd ) ; msg ( "Iexec'ing /bin/sh -c \"%s\"" , buf ) ; execl ( "/bin/sh" , "sh" , "-c" , buf , (void*) 0 ) ; err = msg ( "ES2exec failed:" ) ; } } else { err = msg ( "E2no voice command defined for voice call" ) ; } break ; case NONE: if ( i==0 && softaa && hsc < 0 && getty && *getty ) { int j ; /* switch to fax for 2nd try */ for ( j=0 ; j<3 ; j++ ) if ( cmd ( f, c1 ? "+FCLASS=1" : ( c20 ? "+FCLASS=2.0" : "+FCLASS=2" ), -TO_RESET ) == OK ) break ; wait = 0 ; acmd = ANSCMD ; } else { err = msg ( "E3unable to answer call") ; } break ; default: err = msg ( "E3can't happen(answer)" ) ; break ; } } return err ;}/* Initialize modem. Determine class to use and issue class-specific fax initialization commands. If poll is true, issues commands to enable polling also. Returns 0 or 3 if a mandatory setup command fails. */int modem_init ( TFILE *mf, cap c, char *id, int calling, int poll, int capsset, int *preverse ){ int err=0, t=-TO_RESET ; char buf [ CMDBUFSIZE ], model [ CMDBUFSIZE ] = "" ; char **p, *q, *modelq [2][4] = { { "+FMFR?", "+FMDL?", 0 }, { "+FMI?", "+FMM?", "+FMR?", 0 } } ; /* diasable command echo and get firmware revision */ cmd ( mf, "E0", t ) ; if ( cmd ( mf, "I3", t ) == OK ) { getresp ( "", model, CMDBUFSIZE-1 ) ; strcat ( model, " " ) ; } /* if not already chosen, pick safest class; set it */ if ( ! err && ! c1 && !c2 && ! c20 ) { if ( cmd ( mf, "+FCLASS=?", t ) != OK ) { err = msg ("E3 modem does not support fax" ) ; } else { if ( strinresp ( "2.0" ) ) c20 = 1 ; else if ( strinresp ( "2" ) ) ; else if ( strinresp ( "1" ) ) c1 = 1 ; else err = msg ("E3 can't determine fax modem class support" ) ; if ( strstr ( model, "Sportster" ) ) { /* USR Sporsters are buggy */ c1 = 1 ; c2 = c20 = 0 ; } } } ckcmd ( mf, &err, c1 ? "+FCLASS=1" : ( c20 ? "+FCLASS=2.0" : "+FCLASS=2" ), t, OK ) ; /* get make & model if using Class 2 or 2.0 */ if ( ! c1 ) { for ( p = modelq [ c20 ] ; ! err && *p ; p++ ) { if ( cmd ( mf, *p, t ) == OK ) { getresp ( "", model, CMDBUFSIZE-1 ) ; strcat ( model, " " ) ; } } if ( ! c1 && strstr ( model, "Multi-Tech" ) ) { *preverse = 0 ; msg ("I Multi-Tech bit order set" ) ; } } if ( ! err ) msg ( "I using %sin class %s", model, c1 ? "1" : c20 ? "2.0" : "2" ) ; /* get maximum modem speed if not already set (Class 1 only) */ if ( ! err && c1 && ! capsset ) { int i ; char *c1spstr [6] = { "24", "48", "72", "96", "121", "145" } ; ckcmd ( mf, &err, calling ? "+FTM=?" : "+FRM=?", t, OK ) ; for ( i=0 ; i < 6 && strinresp ( c1spstr[i] ) ; i++ ) ; c[1]=i?i-1:0; } /* issue essential commands and set/get modem capabilities (Class 2 only) */ if ( ! err && ! c1 ) { if ( c20 ) { ckcmd ( mf, 0, "+FIP", t, OK ) ; ckcmd ( mf, 0, "+FNR=1,1,1,1", t, OK ) ; } ckcmd ( mf, &err, "+FCR=1", t, OK ) ; if ( ! capsset ) { if ( cmd ( mf, c20 ? "+FIS?" : "+FDIS?", -t ) == OK && ( q = strinresp ( "," ) ) ) { str2cap ( q-1, c ) ; } else { msg ( "W can't get modem capabilities, set to default" ) ; capsset = 1 ; } } if ( capsset ) { sprintf ( buf, c20 ? "+FCC=%d,%d,%d,%d,%d,%d,%d,%d" : "+FDCC=%d,%d,%d,%d,%d,%d,%d,%d", c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7] ) ; ckcmd ( mf, 0, buf, -t, OK ) ; } sprintf ( buf, c20 ? "+FLI=\"%.*s\"" : "+FLID=\"%.*s\"" , CMDBUFSIZE-9, id ) ; ckcmd ( mf, 0, buf, -t, OK ) ; if ( ! err && poll ) { ckcmd ( mf, 0, c20 ? "+FSP=1" : "+FSPL=1", -t, OK ) ; sprintf ( buf, c20 ? "+FPI=\"%.*s\"" : "+FCIG=\"%.*s\"" , CMDBUFSIZE-9, id ) ; ckcmd ( mf, 0, buf, -t, OK ) ; } } return err ;}/* the following are global so can terminate properly on signal */char *icmd[3][ MAXICMD+1 ] = {{0},{0},{0}} ; /* initialization commands */TFILE faxdev = { -1, 0,0, {0}, 0, 0 } ; /* modem */char *lkfile [ MAXLKFILE+1 ] = {0} ; /* lock file names */IFILE ifile = { 0 } ; /* files being sent */int locked = 0 ; /* modem locked *//* print names of files not sent and reset modem before exiting. */int cleanup ( int err ){ /* log names of files not sent */ logifnames ( &ifile, "I failed -> %s" ) ; if ( ! locked && faxdev.fd >= 0 ) end_session ( &faxdev, icmd[2], lkfile, err != 4 ) ; msg ( "Idone, returning %d (%s)", err, errormsg [ err >= 0 && err <= 5 ? err : 6 ] ) ; return err ;}/* signal handler */void onsig ( int sig ) { msg ( "E terminating on signal %d", sig ) ; exit ( cleanup ( 5 ) ) ;}/* Fax send/receive program for Class 1, 2 and 2.0 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 signal. */int main( int argc, char **argv){ int err=0, doneargs=0, c=0, i ; int testing=0, calling=0 ; int nicmd[3]={0,0,0}, nlkfile=0, nverb=0 ; char *faxfile = FAXFILE ; int softaa=0, share=0, wait=0, reverse=1, ignerr=0, noretry=0, hwfc=0 ; int capsset=0 ; char *getty = "", *vcmd = "", *acmd=ANSCMD ; cap local = { DEFCAP } ; char localid [ IDLEN + 1 ] = DEFID ; int maxpgerr = MAXPGERR ; time_t now ; char *header = 0, headerbuf [ MAXLINELEN ] ; char *fontname = 0 ; faxfont font ; OFILE ofile ; int pages = 0 ; char *phnum="", *ansfname = DEFPAT ; char fnamepat [ EFAX_PATH_MAX ] ; /* print initial message to both stderr & stdout */ argv0 = argv[0] ; verb[1] = "ewia" ; msg ( "I " Version " " Copyright ) ; argv0 = efaxbasename ( argv0 ) ; msg ( "A compiled "__DATE__ " " __TIME__ ) ; verb[1] = "" ; while ( ! err && ! doneargs && ( c = nextopt ( argc,argv, "a:c:d:e:f:g:h:i:j:k:l:o:p:q:r:st:v:wx:T" ) ) != -1 ) { switch (c) { case 'a': acmd = nxtoptarg ; break ; case 'c': err = str2cap ( nxtoptarg, local ) ; capsset = 1 ; break ; case 'l': if ( strlen ( nxtoptarg ) > IDLEN ) msg("Wlocal ID (%s) truncated to %d characters", nxtoptarg, IDLEN ) ; if ( strspn ( nxtoptarg, " +0123456789" ) != strlen ( nxtoptarg ) ) msg("Wlocal ID (%s) has non-standard characters", nxtoptarg ) ; sprintf ( localid, "%*.*s", IDLEN, IDLEN, nxtoptarg ) ; break ; case 'i': if ( nicmd[0] < MAXICMD ) icmd[0][ nicmd[0]++ ] = nxtoptarg ; else err = msg ( "E2too many '-i' options"); break ; case 'j': if ( nicmd[1] < MAXICMD ) icmd[1][ nicmd[1]++ ] = nxtoptarg ; else err = msg ( "E2too many '-j' options"); break ; case 'k': if ( nicmd[2] < MAXICMD ) icmd[2][ nicmd[2]++ ] = nxtoptarg ; else err = msg ( "E2too many '-k' options"); break ; case 'h': header = nxtoptarg ; break ; case 'f': fontname = nxtoptarg ; break ; case 'd': faxfile = nxtoptarg ; break ; case 'e': vcmd = nxtoptarg ; break ; case 'g': getty = nxtoptarg ; break ; case 'o': /* most protocol options are globals */ for ( ; *nxtoptarg ; nxtoptarg++ ) switch ( *nxtoptarg ) { case '0' : c20 = 1 ; break ; case '1' : c1 = 1 ; break ; case '2' : c2 = 1 ; break ; case 'a' : softaa = 1 ; break ; case 'e' : ignerr = 1 ; break ; case 'f' : vfc = 1 ; break ; case 'h' : hwfc = 1 ; break ; case 'l' : lockpolldelay /= 2 ; break ; case 'n' : noretry = 1 ; break ; case 'r' : reverse = 0 ; break ; case 'x' : startchar = XON ; break ; case 'z' : cmdpause += T_CMD ; break ; default : msg ( "Wunrecognized protocol option (%c)", *nxtoptarg ) ; } break ; case 'q': if ( sscanf ( nxtoptarg , "%d", &maxpgerr ) != 1 || maxpgerr < 0 ) err=msg ("E2bad quality (-q) argument (%s)", nxtoptarg ) ; break; case 'r': ansfname = nxtoptarg ; break; case 's': share = 1 ; break; case 't': calling=1; /* fall through */ case 'p': if ( argv [ argc ] ) err = msg ("E2can't happen(unterminated argv)") ; if ( ! err ) err = newIFILE ( &ifile, argv + nxtoptind ) ; pages = argc - nxtoptind - ( c == 'p' ? 1 : 0 ) ; pages = pages < 0 ? 0 : pages ; phnum = nxtoptarg ; doneargs=1 ; break; case 'v': verb[nverb] = nxtoptarg ; nverb=1; break ; case 'w': wait = 1 ; break ; case 'x': if ( nlkfile < MAXLKFILE ) lkfile[ nlkfile++ ] = nxtoptarg ; else err = msg ( "E2too many lock files" ) ; break ; case 'T': /* test: begin+end session */ testing=1; doneargs=1 ; break ; default : fprintf ( stderr, Usage, argv0 ) ; err = 2 ; break ; } } for ( i=0 ; i<argc ; i++ ) msg ( "Aargv[%d]=%s", i, argv[i]) ; if ( ! nicmd[2] ) icmd[2][nicmd[2]++] = "H" ; /* default -k command */ readfont ( fontname, &font ) ; if ( ! header ) { char tmp [ MAXLINELEN ] ; now = time ( 0 ) ; strftime ( tmp, MAXLINELEN, "%c %%s P. %%%%d", localtime ( &now ) ) ; sprintf ( header = headerbuf, tmp, localid ) ; } if ( ! err ) { err = begin_session ( &faxdev, faxfile, !c1 && !c20 && reverse, /* Class 2 rx bit reversal */ hwfc, lkfile, COMMAND, onsig ) ; if ( ! err ) err = setup ( &faxdev, icmd[0], ignerr ) ; if ( ! err ) err = modem_init ( &faxdev, local, localid, calling, calling && !pages, capsset, &reverse ) ; if ( ! err ) err = setup ( &faxdev, icmd[1], ignerr ) ; if ( err == 1 ) locked = 1 ; } if ( ! err && ! testing ) { if ( calling ) { err = dial ( &faxdev, phnum, 0 ) ; } else { err = answer ( &faxdev, lkfile, wait, share, softaa, getty, vcmd, acmd ) ; if ( err == 1 ) locked = 1 ; } now = time(0) ; /* do it here so use reception time */ strftime ( fnamepat, EFAX_PATH_MAX, ansfname, localtime ( &now ) ) ; strncat ( fnamepat, ".%03d", EFAX_PATH_MAX - strlen ( fnamepat ) ) ; newOFILE ( &ofile, O_TIFF_FAX, fnamepat, 0, 0, 0, 0 ) ; if ( ! err ) { if ( c1 ) { err = c1sndrcv ( &faxdev, local, localid, &ofile, &ifile, pages, header, &font, maxpgerr, noretry, calling ) ; } else { err = c2sndrcv ( &faxdev, local, localid, &ofile, &ifile, pages, header, &font, maxpgerr, noretry, calling ) ; } } } return cleanup ( err ) ;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -