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

📄 ckudia.c

📁 Kermit Kermit文件运输协议 Kermit文件运输协议是用于在PC之间交换文件的一种简单的文件运输协议。该协议是哥仑比亚大学开发的
💻 C
📖 第 1 页 / 共 2 页
字号:
#define FAILED	  2

/*
 * 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 */

static
char *F_reason[5] = { 		/* failure reasons for message */
    "Unknown",  "Timeout", "Interrupt", "Modem", "Initialize" };

static int tries = 0;

#define LBUFL 100
static 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 );
    }

static
ttolSlow(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.
 */
static
waitFor(s) char *s;
    {
    CHAR c;
    while ( c = *s++ )			/* while more characters remain... */
	while ( ( ttinc(0) & 0177 ) != c ) ;	/* wait for the character */
    }

static
didWeGet(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. */

static
reset ()
    {
    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 -3

switch (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 */
}

⌨️ 快捷键说明

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