?? ckudia.c
字號:
/* * Failure reasons for use with the 'longjmp' exit. */#define F_time 1 /* timeout */#define F_int 2 /* interrupt */#define F_modem 3 /* modem-detected failure */#define F_minit 4 /* cannot initialize modem */staticchar *F_reason[5] = { /* failure reasons for message */ "Unknown", "Timeout", "Interrupt", "Modem", "Initialize" };static int tries = 0;#define LBUFL 100static char lbuf[LBUFL];static jmp_buf sjbuf;static int (*savAlrm)(); /* for saving alarm handler */static int (*savInt)(); /* for saving interrupt handler */dialtime() { /* timer interrupt handler */ longjmp( sjbuf, F_time );}dialint() /* user-interrupt handler */ { longjmp( sjbuf, F_int ); }staticttolSlow(s,millisec) char *s; int millisec; { /* output s-l-o-w-l-y */ for (; *s; s++) { ttoc(*s); msleep(millisec); } }/* * Wait for a string of characters. * * The characters are waited for individually, and other characters may * be received "in between". This merely guarantees that the characters * ARE received, and in the order specified. */staticwaitFor(s) char *s; { CHAR c; while ( c = *s++ ) /* while more characters remain... */ while ( ( ttinc(0) & 0177 ) != c ) ; /* wait for the character */ }staticdidWeGet(s,r) char *s, *r; { /* Looks in string s for response r */ int lr = strlen(r); /* 0 means not found, 1 means found it */ int i; for (i = strlen(s)-lr; i >= 0; i--) if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 ); return( 0 ); }/* R E S E T -- Reset alarms, etc. on exit. */staticreset () { alarm(0); signal(SIGALRM,savAlrm); /* restore alarm handler */ signal(SIGINT,savInt); /* restore interrupt handler */ }/* D I A L -- Dial up the remote system */dial(telnbr) char *telnbr; { char c; char *i, *j; int waitct, status; char errmsg[50], *erp; MDMINF *pmdminf; /* pointer to modem-specific info */ int augmdmtyp; /* "augmented" modem type, to handle modem modes */ int mdmEcho = 0; /* assume modem does not echo */ int n, n1; char *pc; /* pointer to a character */ if (!mdmtyp) { printf("Sorry, you must 'set modem' first\n"); return(-2); } if (!local) { printf("Sorry, you must 'set line' first\n"); return(-2); } if (speed < 0) { printf("Sorry, you must 'set speed' first\n"); return(-2); } if (ttopen(ttname,&local,mdmtyp) < 0) {/* Open, no wait for carrier */ erp = errmsg; sprintf(erp,"Sorry, can't open %s",ttname); perror(errmsg); return(-2); } pmdminf = ptrtab[mdmtyp-1]; /* set pointer to modem info */ augmdmtyp = mdmtyp; /* initialize "augmented" modem type *//* cont'd... */ /* interdigit waits for tone dial *//* ...dial, cont'd */ waitct = 1*strlen(telnbr) ; /* compute time to dial worst case */ waitct += pmdminf->dial_time; /* dialtone + completion wait times */ for (i=telnbr; *i; i++) /* add in pause characters time */ for (j=pmdminf->pause_chars; *j; j++) if (*i == *j) { waitct += pmdminf->pause_time; break; } printf("Dialing thru %s, speed %d, number %s.\r\n",ttname,speed,telnbr); printf("The timeout for completing the call is %d seconds.\r\n",waitct); printf("Type the interrupt character to cancel the dialing.\r\n");/* Hang up the modem (in case it wasn't "on hook") */ if ( tthang() < 0 ) { printf("Sorry, Can't hang up tty line\n"); return(-2); }/* Condition console terminal and communication line */ /* place line into "clocal" dialing state */ if ( ttpkt(speed,DIALING) < 0 ) { printf("Sorry, Can't condition communication line\n"); return(-2); }/* * Establish jump vector, or handle "failure" jumps. */ if ( n = setjmp(sjbuf) ) /* if a "failure jump" was taken... */ { alarm ( 0 ); /* disable timeouts */ if ( n1 = setjmp(sjbuf) ) /* failure while handling failure */ { printf ( "%s failure while handling failure.\r\n", F_reason[n1] ); } else /* first (i.e., non-nested) failure */ { signal ( SIGALRM, dialtime ); /* be sure to catch signals */ if ( signal ( SIGINT, SIG_IGN ) != SIG_IGN ) signal ( SIGINT, dialint ); alarm ( 5 ); /* be sure to get out of this section */ ttclos (); /* hangup and close the line */ } switch ( n ) /* type of failure */ { case F_time: /* timed out */ { printf ( "No connection made within the allotted time.\r\n" ); break; } case F_int: /* dialing interrupted */ { printf ( "Dialing interrupted.\r\n" ); break; } case F_modem: /* modem detected a failure */ { printf ( "Failed (\"" ); for ( pc=lbuf; *pc; pc++ ) if ( isprint(*pc) ) putchar(*pc); /* display printable reason */ printf ( "\").\r\n" ); break; } case F_minit: /* cannot initialize modem */ { printf ( "Cannot initialize modem.\r\n" ); break; } } reset (); /* reset alarms, etc. */ return ( -2 ); /* exit with failure code */ }/* * Set timer and interrupt handlers. */ savAlrm = signal(SIGALRM,dialtime); /* set alarm handler */ if ( ( savInt = signal ( SIGINT, SIG_IGN ) ) != SIG_IGN ) signal ( SIGINT, dialint ); /* set int handler if not ignored */ alarm(10); /* give modem 10 seconds to wake up */ ttflui(); /* flush input buffer if any *//* * Put modem in command mode. */#define OKAY 1 /* modem attention attempt status */#define IGNORE 2#define GOT_O -2#define GOT_A -3switch (augmdmtyp) { case n_HAYES: case n_HAYESNV: while(tries++ < 4) { ttol( HAYES.wake_str, strlen(HAYES.wake_str) ); /* wakeup */ status = 0; while ( status <= 0 ) { switch (ttinc(0) & 0177) { case 'A': /* echoing, ignore */ status = GOT_A; break; case 'T': if (status == GOT_A) { mdmEcho = 1; /* expect echoing later */ status = 0; break; } status = IGNORE; break; case '\n': case '\r': status = 0; break; case '0': /* numeric result code */ augmdmtyp = n_HAYESNV; /* nonverbal result codes */ status = OKAY; break; case 'O': /* maybe English result code*/ status = GOT_O; break; case 'K': if (status == GOT_O) { augmdmtyp = n_HAYES; status = OKAY; break; } /* else its default anyway */ default: status = IGNORE; break; } } if (status == OKAY) break; if (status == IGNORE) ttflui(); sleep(1); /* wait before retrying */ } if (status != 0) break; longjmp( sjbuf, F_minit ); /* modem-initialization failure *//* cont'd... */ /* interdigit waits for tone dial *//* ...dial, cont'd */ default: /* place modem into command mode */ ttolSlow(pmdminf->wake_str, pmdminf->wake_rate); waitFor(pmdminf->wake_prompt); break; } alarm(0); /* turn off alarm */ msleep(500); /* give things settling time */ alarm(10); /* alarm on dialing prompts */ /* Dial the number */ /* put modem into dialing mode */ ttolSlow(pmdminf->dmode_str, pmdminf->dial_rate); if (pmdminf->dmode_prompt) { /* wait for prompt, if any expected */ waitFor(pmdminf->dmode_prompt); msleep(300); } alarm(0); /* turn off alarm on dialing prompts */ alarm(waitct); /* time to allow for connecting */ ttflui(); /* clear out stuff from waking modem up */ sprintf(lbuf, pmdminf->dial_str, telnbr); /* form dialing string */ ttolSlow(lbuf,pmdminf->dial_rate); /* send dialing string */ if (augmdmtyp == n_RACAL) { /* acknowledge printout of dialing string */ sleep(3); ttflui(); ttoc('\r'); }/* cont'd... */ /* interdigit waits for tone dial *//* ...dial, cont'd *//* Check for connection *//* * I believe we also need to look for carrier in order to determine if a * connection has been made. In fact, for many we may only want to look for * the "failure" responses in order to short-circuit the timeout, and let * carrier be the determination of whether a connection has been made. -- DS */ status = 0; strcpy(lbuf,"No Connection"); /* default failure reason */ while (status == 0) { switch (augmdmtyp) { default: for (n=0; n < LBUFL; n++) { /* accumulate response */ lbuf[n] = (ttinc(0) & 0177); if ( lbuf[n] == '\r' || lbuf[n] == '\n' ) break; } lbuf[n] = '\0'; /* terminate response from modem */ if (n) { /* if one or more characters present */ switch (augmdmtyp) { case n_CERMETEK: if (didWeGet(lbuf,"\016A")) { status = CONNECTED; ttolSlow("\016U 1\r",200); /* make transparent*/ } break; case n_DF100: /* DF100 won't generate some of these */ case n_DF200: if (didWeGet(lbuf,"Attached")) status = CONNECTED; /* * The DF100 will respond with "Attached" even if DTR * and/or carrier are not present. Another reason to * (also) wait for carrier? */ if (didWeGet(lbuf,"Busy")) status = FAILED; if (didWeGet(lbuf,"Disconnected")) status = FAILED; if (didWeGet(lbuf,"Error")) status = FAILED; if (didWeGet(lbuf,"No answer")) status = FAILED; if (didWeGet(lbuf,"No dial tone")) status = FAILED; if (didWeGet(lbuf,"Speed:")) status = FAILED; /* * It appears that the "Speed:..." response comes after an * "Attached" response, so this is never seen. HOWEVER, * it would be very handy to detect this and temporarily * reset the speed, since it's a nuiscance otherwise. * If we wait for some more input from the modem, how do * we know if it's from the remote host or the modem? * Carrier reportedly doesn't get set until after the * "Speed:..." response (if any) is sent. Another reason * to (also) wait for carrier. */ break; case n_GDC: if (didWeGet(lbuf,"ON LINE")) status = CONNECTED; if (didWeGet(lbuf,"NO CONNECT")) status = FAILED; break; case n_HAYES: case n_USROBOT: if (didWeGet(lbuf,"CONNECT")) status = CONNECTED; if (didWeGet(lbuf,"NO CARRIER")) status = FAILED; break; case n_PENRIL: if (didWeGet(lbuf,"OK")) status = CONNECTED; if (didWeGet(lbuf,"BUSY")) status = FAILED; if (didWeGet(lbuf,"NO RING")) status = FAILED; break; case n_RACAL: if (didWeGet(lbuf,"ON LINE")) status = CONNECTED; if (didWeGet(lbuf,"FAILED CALL")) status = FAILED; break; case n_VENTEL: if (didWeGet(lbuf,"ONLINE!")) status = CONNECTED; if (didWeGet(lbuf,"BUSY")) status = FAILED; if (didWeGet(lbuf,"DEAD PHONE")) status = FAILED; break; } } break; case n_DF03: /* because response lacks CR or NL */ c = ttinc(0) & 0177; if ( c == 'A' ) status = CONNECTED; if ( c == 'B' ) status = FAILED; break; case n_HAYESNV: c = ttinc(0) & 0177; if (mdmEcho) { /* sponge up dialing string */ mdmEcho = c!='\r'; /* until return is echoed */ break; } if (c == '1') status = CONNECTED; if (c == '3') status = FAILED; if (c == '5') status = CONNECTED; break; case n_UNKNOWN: /** SHOULD WAIT FOR CARRIER OR TIMEOUT -- DS **/ break; } /* switch (augmdmtyp) */ } /* while status == 0 */ alarm(0); /* turn off alarm on connecting */ if ( status != CONNECTED ) /* modem-detected failure */ longjmp( sjbuf, F_modem ); /* exit (with reason in lbuf) */ alarm(3); /* precaution in case of trouble */ ttpkt(speed,CONNECT); /* cancel dialing state ioctl */ reset (); /* reset alarms, etc. */ if ( ! quiet ) printf ( "Call completed.\07\r\n" ); return ( 0 ); /* return, and presumably connect */}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -