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

📄 ckucon.c

📁 linux终端仿真程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	      apcbuf[0] = 0;		/* Not pretty, but what else */	      inesc = ES_NORMAL;	/* can we do?  (ST might not come) */	  }#endif /* CK_APC */	  break;			/* Absorb all other characters. */	case ES_TERMIN:			/* May have a string terminator */	  if (c == '\\') {		/* which must be backslash */	      inesc = ES_NORMAL;	/* If so, back to NORMAL */#ifdef CK_APC	      if (apcactive) {		/* If it was an APC string, */		  debug(F101,"APC terminated","",c);		  apcbuf[apclength] = NUL; /* terminate it and then ... */		  return(1);	      }#endif /* CK_APC */	  } else {			/* Otherwise */	      inesc = ES_STRING;	/* Back to string absorption. */#ifdef CK_APC	      if (apcactive && (apclength+1 < apcbuflen)) { /* In APC string */		  apcbuf[apclength++] = ESC; /* deposit the Esc character */		  apcbuf[apclength++] = c;   /* and this character too */	      }#endif /* CK_APC */	  }      }    return(0);}#endif /* NOESCSEQ *//* Connect state parent/child communication signal handlers *//* Routines used by the child process */static intpipemsg(n) int n; {			/* Send message ID to parent */    int code = n & 255;    return(write(xpipe[1], &code, sizeof(code)));}/* Environment pointer for CK_FORK_SIG signal handling in child... */#ifdef CK_POSIX_SIGstatic sigjmp_buf sig_env;#elsestatic jmp_buf sig_env;#endif /* CK_POSIX_SIG */static SIGTYP				/* CK_FORK_SIG handling in child ... */forkint(foo) int foo; {    /* It is important to disable CK_FORK_SIG before longjmp */    signal(CK_FORK_SIG, SIG_IGN);	/* Set to ignore CK_FORK_SIG */    debug(F100, "forkint - CK_FORK_SIG", "", 0);    /* Force return from ck_sndmsg() */    cklongjmp(sig_env, 1);    /* NOTREACHED */}static VOIDck_sndmsg() {				/* Executed by child only ... */    debug(F100, "ck_sndmsg - notifying parent", "", 0);    if (#ifdef CK_POSIX_SIG	sigsetjmp(sig_env,1)#else	setjmp(sig_env)#endif /* CK_POSIX_SIG */	== 0) {        signal(CK_FORK_SIG, forkint);	/* Set up signal handler */        kill(parent_id, CK_FORK_SIG);	/* Kick the parent */        for (;;) pause();		/* Wait for CK_FORK_SIG or SIGKILL */	/* NOTREACHED */    }    /* We come here from forkint() via [sig]cklongjmp(sig_env,1) */    debug(F100, "ck_sndmsg - returning", "", 0);}/* Routines used by the parent process */#ifdef CK_POSIX_SIG		 /* Environment pointer for CONNECT errors */static sigjmp_buf con_env;#elsestatic jmp_buf con_env;#endif /* CK_POSIX_SIG *//*  pipeint() handles CK_FORK_SIG signals from the lower (port) fork.  It reads a function code from the pipe that connects the two forks,  then reads additional data from the pipe, then handles it.*/static SIGTYPpipeint(arg) int arg; {			/* Dummy argument */    int code;#ifndef NOCCTRAP    extern ckjmpbuf cmjbuf;#endif /* NOCCTRAP */    /*      IMPORTANT: At this point, the child fork is waiting for CK_FORK_SIG      (eventually for SIGKILL) inside of ck_sndmsg().  So we can't get any      subsequent CK_FORK_SIG from child before we send it CK_FORK_SIG.    */    signal(CK_FORK_SIG, SIG_IGN);	/* Ignore CK_FORK_SIG now */    debug(F101,"pipeint arg","",arg);    read(xpipe[0], &code, sizeof(code)); /* Get function code from pipe */    debug(F101,"pipeint code","",code);#ifndef NOCCTRAP#ifndef NOICP#define USECCJMPBUF#endif /* NOICP */#endif /* NOCCTRAP *//*  The CEV_HUP case is executed when the other side has hung up on us.  In some cases, this happens before we have had a chance to execute the  setjmp(con_env,1) call, and in that case we'd better not take the longjmp!  A good example is when you TELNET to port 13 on the local host; it prints  its asctime() string (26 chars) and then closes the connection.*/    switch (code & 255) {      case CEV_HUP:        sjval = CEV_HUP;		/* Set global variable. */	if (jbset) {			/* jmp_buf is initialized */	    cklongjmp(con_env,sjval);	/* so do the right thing. */	} else {#ifdef USECCJMPBUF	    /* jmp_buf not init'd yet a close approximation... */	    ttclos(0);			/* Close our end of the connection */#ifdef BEBOX	    {		long ret_val;		if (pid) kill(pid,SIGKILLTHR);	/* Kill lower fork */		wait_for_thread (pid, &ret_val);	    }#else#ifdef Plan9	    if (pid) kill(pid, SIGKILL); /* (should always use this really) */#else	    if (pid) kill(pid,9);	/* Kill lower fork (history) */#endif /* Plan9 */#endif /* BEBOX */	    conres();			/* Reset the console. */	    if (!quiet) {		printf("\r\n(Back at %s)\r\n",		       *myhost ? myhost :#ifdef UNIX		       "local UNIX system"#else		       "local system"#endif /* UNIX */		       );	    }	    what = W_NOTHING;		/* So console modes are set right. */	    printf("\r\n");		/* prevent prompt-stomping */	    cklongjmp(cmjbuf,0);	/* Do what the Ctrl-C handler does */#else	    printf("\r\nLongjump failure - fatal\r\n");	    doexit(1);			/* Better than dumping core... */#endif /* USECCJMPBUF */	}#ifdef USECCJMPBUF#undef USECCJMPBUF#endif /* USECCJMPBUF */      case CEV_DUP:			/* Child sends duplex change */	read(xpipe[0], (char *)&duplex, sizeof(duplex));	debug(F101,"pipeint duplex","",duplex);	break;#ifdef TNCODE      case CEV_MEBIN:			/* Child sends me_binary change */	read(xpipe[0], (char *)&me_binary, sizeof(me_binary));	debug(F101,"pipeint me_binary","",me_binary);	break;      case CEV_UBIN:			/* Child sends u_binary change */	read(xpipe[0], (char *)&u_binary, sizeof(u_binary));	debug(F101,"pipeint u_binary","",u_binary);	break;#endif /* TNCODE */#ifdef CK_APC      case CEV_AUL:			/* Autoupload */	justone = 1;	debug(F100,"autoupload at parent","",0);      case CEV_ADL:			/* Autodownload */	apcstatus = APC_LOCAL;	if (!justone) debug(F100,"autodownload at parent","",0);      case CEV_APC:			/* Application Program Command */	read(xpipe[0], (char *)&apclength, sizeof(apclength));	read(xpipe[0], apcbuf, apclength+1); /* Include trailing zero byte */	debug(F111,"APC at parent",apcbuf,apclength);	read(xpipe[0], (char *)&ibc, sizeof(ibc)); /* Copy child's */	if (ibc > 0) {				   /* input buffer. */	    read(xpipe[0], (char *)&ibp, sizeof(ibp));	    read(xpipe[0], ibp, ibc);	}	obc = 0; obp = obuf; *obuf = NUL; /* Because port fork flushed */	sjval = CEV_APC;	cklongjmp(con_env,sjval);	/* NOTREACHED */#endif /* CK_APC */#ifdef SUNX25      case CEV_PAD:			/* X.25 PAD parameter change */	debug(F100,"pipeint PAD change","",0);	read(xpipe[0],padparms,MAXPADPARMS);	sjval = CEV_PAD;		/* Set global variable. */#ifdef COMMENT				/* We might not need to do this... */	cklongjmp(con_env,sjval);	/* NOTREACHED */#else  /* COMMENT */	break;#endif /* COMMENT */#endif /* SUNX25 */    }    signal(CK_FORK_SIG, pipeint);	/* Set up signal handler */    kill(pid, CK_FORK_SIG);		/* Signal the port fork ... */}/*  C K C P U T C  --  C-Kermit CONNECT Put Character to Screen  *//*  Output is buffered to avoid slow screen writes on fast connections.  NOTE: These could (easily?) become macros ...*/static intckcputf() {				/* Dump the output buffer */    int x = 0;    if (obc > 0)			/* If we have any characters, */      x = conxo(obc,obuf);		/* dump them, */    obp = obuf;				/* reset the pointer */    obc = 0;				/* and the counter. */    return(x);				/* Return conxo's return code */}intckcputc(c) int c; {    int x;    *obp++ = c & 0xff;			/* Deposit the character */    obc++;				/* Count it */    if (ibc == 0 ||			/* If input buffer about empty */	obc == OBUFL) {			/* or output buffer full */	debug(F101,"CKCPUTC obc","",obc);	x = conxo(obc,obuf);		/* dump the buffer, */	obp = obuf;			/* reset the pointer */	obc = 0;			/* and the counter. */	return(x);			/* Return conxo's return code */    } else return(0);}/*  C K C G E T C  --  C-Kermit CONNECT Get Character  *//*  Buffered read from communication device.  Returns the next character, refilling the buffer if necessary.  On error, returns ttinc's return code (see ttinc() description).  Dummy argument for compatible calling conventions with ttinc().  NOTE: We don't have a macro for this because we have to pass  a pointer to this function as an argument to tn_doop().*/intckcgetc(dummy) int dummy; {    int c, n;    debug(F101,"CKCGETC 1 ibc","",ibc); /* Log */    if (ibc < 1) {			/* Need to refill buffer? */	ibc = 0;			/* Yes, reset count */	ibp = ibuf;			/* and buffer pointer */	debug(F100,"CKCGETC 1 calling ttinc(0)","",0); /* Log */	c = ttinc(0);			/* Read one character, blocking */	debug(F101,"CKCGETC 1 ttinc(0)","",c); /* Log */	if (c < 0) {			/* If error, return error code */	    return(c);	} else {			/* Otherwise, got one character */	    *ibp++ = c;			/* Advance buffer pointer */	    ibc++;			/* and count. */	}	/* Now quickly read any more that might have arrived */	if ((n = ttchk()) > 0) {	/* Any more waiting? */	    if (n > (IBUFL - ibc))	/* Get them all at once. */	      n = IBUFL - ibc;		/* Don't overflow buffer */	    if ((n = ttxin(n,(CHAR *)ibp)) > 0)	      ibc += n;			/* Advance counter */	}	debug(F101,"CKCGETC 2 ibc","",ibc); /* Log how many */	ibp = ibuf;    }    c = *ibp++ & 0xff;			/* Get next character from buffer */    ibc--;				/* Reduce buffer count */    return(c);				/* Return the character */}/*   Keyboard handling, buffered for speed, which is needed when C-Kermit is   in CONNECT mode between two other computers that are transferring data.*/static char *kbp;			/* Keyboard input buffer pointer */static int kbc;				/* Keyboard input buffer count */#ifdef pdp11				/* Keyboard input buffer length */#define KBUFL 32			/* Small for PDP-11 UNIX */#else#define KBUFL 257			/* Regular kernel size for others */#endif /* pdp11 */#ifdef DYNAMICstatic char *kbuf = NULL;#elsestatic char kbuf[KBUFL];#endif /* DYNAMIC *//* Macro for reading keystrokes. */#define CONGKS() (((--kbc)>=0) ? ((int)(*kbp++) & 0377) : kbget())/*  Note that we call read() directly here, normally a no-no, but in this case  we know it's UNIX and we're only doing what coninc(0) would have done,  except we're reading a block of characters rather than just one.  There is,  at present, no conxin() analog to ttxin() for chunk reads, and instituting  one would only add function-call overhead as it would only be a wrapper for  a read() call anyway.*//*  Another note: We stick in this read() till the user types something.  But the other (lower) fork is running too, and on TELNET connections,  it will signal us to indicate echo-change negotiations, and this can  interrupt the read().  Some UNIXes automatically restart the interrupted  system call, others return from it with errno == EINTR.*/static int				/* Keyboard buffer filler */kbget() {#ifdef EINTR    int tries = 10;			/* If read() is interrupted, */    int ok = 0;    while (tries-- > 0) {		/* try a few times... */#endif /* EINTR */	if ((kbc = conchk()) < 1)	/* How many chars waiting? */	  kbc = 1;			/* If none or dunno, wait for one. */	else if (kbc > KBUFL)		/* If too many, */	  kbc = KBUFL;			/* only read this many. */	if ((kbc = read(0, kbuf, kbc)) < 1) { /* Now read it/them. */	    debug(F101,"kbget errno","",errno);	/* Got an error. */#ifdef EINTR	    if (errno == EINTR)		/* Interrupted system call. */	      continue;			/* Try again, up to limit. */	    else			/* Something else. */#endif /* EINTR */	      return(-1);		/* Pass along read() error. */	}#ifdef EINTR	else { ok = 1; break; }    }    if (!ok) return(-1);#endif /* EINTR */    kbp = kbuf;				/* Adjust buffer pointer, */    kbc--;				/* count, */    return((int)(*kbp++) & 0377);	/* and return first character. */}/*  C O N C L D --  Interactive terminal connection child function */static#ifdef BEBOXlong#elseVOID#endif /* BEBOX */concld (#ifdef BEBOX       void *bevoid#endif /* BEBOX */       ) {    int	n;			/* General purpose counter */    int c;			/* c is a character, but must be signed 				   integer to pass thru -1, which is the				   modem disconnection signal, and is				   different from the character 0377 */    int c2;			/* A copy of c */    int csave;			/* Another copy of c */    int tx;			/* tn_doop() return code */#ifdef SUNX25    int i;				/* Worker for X.25 code */#endif /* SUNX25 */#ifdef NETCONN#endif /* NETCONN */#ifndef NOESCSEQ    int apcrc;#endif /* NOESCSEQ */    int conret = 0;			/* Return value from conect() */    /* jbchksum = -1L; */    jbset = 0;				/* jmp_buf not set yet, don't use it */    debug(F101,"CONCLD entry","",CK_FORK_SIG); 	/* *** */		/* Inferior reads, prints port input */    if (priv_can()) {			/* Cancel all privs */	printf("?setuid error - fatal\n");	doexit(BAD_EXIT,-1);    }    signal(SIGINT, SIG_IGN);		/* In case these haven't been */    signal(SIGQUIT, SIG_IGN);		/* inherited from above... */    signal(CK_FORK_SIG, SIG_IGN);	/* CK_FORK_SIG not expected yet */    inshift = outshift = 0;		/* Initial SO/SI shift state. */    {					/* Wait for parent's setup */	int i;	while ((i = read(xpipe[0], &c, 1)) <= 0) {	    if (i < 0) {		pipemsg(CEV_HUP);	/* Read error - hangup */		ck_sndmsg();		/* Send and wait to be killed */		/* NOTREACHED */	    } /* Restart interrupted read() */	}    }

⌨️ 快捷键说明

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