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

📄 ckucon.c

📁 linux终端仿真程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (!obuf) {	if (!(obuf = malloc(OBUFL+1))) {    /* Allocate output line buffer */	    printf("Sorry, CONNECT output buffer can't be allocated\n");	    goto conret0;	} else {	    obp = obuf;	    obc = 0;	}    }    if (!kbuf) {	if (!(kbuf = malloc(KBUFL+1))) { /* Allocate keyboard input buffer */	    printf("Sorry, CONNECT keyboard buffer can't be allocated\n");	    goto conret0;	}    }    if (!temp) {	if (!(temp = malloc(TMPLEN+1))) { /* Allocate temporary buffer */	    printf("Sorry, CONNECT temporary buffer can't be allocated\n");	    goto conret0;	}    }#else#ifdef COMMENT    ibp = ibuf;				    ibc = 0;#endif /* COMMENT */    obp = obuf;    obc = 0;#endif /* DYNAMIC */    kbp = kbuf;				/* Always clear these. */    *kbp = NUL;				/* No need to preserve them between */    kbc = 0;				/* CONNECT sessions. */#ifdef DEBUG    if (deblog) {	debug(F101,"ckucon entry ttyfd","",ttyfd);	debug(F101,"ckucon entry ibc","",ibc);	debug(F101,"ckucon entry obc","",obc);	debug(F101,"ckucon entry kbc","",kbc);	if (ttyfd > -1) {	    n = ttchk();	    debug(F101,"ckucon entry ttchk","",n);	}    }    #endif /* DEBUG */        if (ttyfd < 0) {			/* If communication device not open */	debug(F111,"ckucon opening",ttname,0); /* Open it now */	if (ttopen(ttname,		   &local,		   network ? -nettype : mdmtyp,		   0		   ) < 0) {	    sprintf(temp,"Sorry, can't open %s",ttname);	    perror(temp);	    debug(F110,"ckucon open failure",ttname,0);	    goto conret0;	}    }    dohangup = 0;			/* Hangup not requested yet */#ifdef SUNX25    dox25clr = 0;			/* X.25 clear not requested yet */#endif /* SUNX25 */    if (!quiet#ifdef CK_APC	&& !apcactive#endif /* CK_APC */	) {#ifdef NETCONN	if (network) {	    printf("Connecting to host %s",ttname);#ifdef SUNX25	    if (nettype == NET_SX25)	      printf(", Link ID %d, LCN %d",linkid,lcn);#endif /* SUNX25 */	} else {#endif /* NETCONN */	    printf("Connecting to %s",ttname);	    if (speed > -1L) printf(", speed %ld",speed);#ifdef NETCONN	}#endif /* NETCONN */	if (tt_escape) {	    printf(".\r\nThe escape character is Ctrl-%c (ASCII %d, %s)\r\n",		   ctl(escape), escape,		   (escape == 127 ? "DEL" : ccntab[escape]));	    printf("Type the escape character followed by C to get back,\r\n");	    printf("or followed by ? to see other options.\r\n");	} else {	    printf(".\r\n\nESCAPE CHARACTER IS DISABLED\r\n\n");	}	if (seslog) {	    printf("(Session logged to %s, ",sesfil);	    printf("%s)\r\n", sessft ? "binary" : "text");	}	if (debses) printf("Debugging Display...)\r\n");	fflush(stdout);    }/* Condition console terminal and communication line */	        if (conbin((char)escape) < 0) {	printf("Sorry, can't condition console terminal\n");	goto conret0;    }    debug(F101,"CONNECT cmask","",cmask);    debug(F101,"CONNECT cmdmsk","",cmdmsk);    debug(F101,"CONNECT speed before ttvt","",speed);    if ((n = ttvt(speed,flow)) < 0) {	/* Enter "virtual terminal" mode */	debug(F101,"CONNECT ttvt","",n);	tthang();			/* Hang up and close the device. */	ttclos(0);	if (ttopen(ttname,		/* Open it again... */		   &local,		   network ? -nettype : mdmtyp,		   0		   ) < 0) {	    sprintf(temp,"Sorry, can't reopen %s",ttname);	    perror(temp);	    goto conret0;	}	if (ttvt(speed,flow) < 0) {	/* Try virtual terminal mode again. */	    conres();			/* Failure this time is fatal. */	    printf("Sorry, Can't condition communication line\n");	    goto conret0;	}    }    debug(F101,"CONNECT ttvt ok, escape","",escape);#ifndef NOCSETS/* Set up character set translations */    tcs = gettcs(tcsr,tcsl);		/* Get intermediate set. */    if (tcsr == tcsl) {			/* Remote and local sets the same? */	sxo = rxo = NULL;		/* If so, no translation. */	sxi = rxi = NULL;    } else {				/* Otherwise, set up */	sxo = xls[tcs][tcsl];		/* translation function */	rxo = xlr[tcs][tcsr];		/* pointers for output functions */	sxi = xls[tcs][tcsr];		/* and for input functions. */	rxi = xlr[tcs][tcsl];    }/*  This is to prevent use of zmstuff() and zdstuff() by translation functions.  They only work with disk i/o, not with communication i/o.  Luckily Russian  translation functions don't do any stuffing...*/    langsv = language;#ifndef NOCYRIL    if (language != L_RUSSIAN)#endif /* NOCYRIL */      language = L_USASCII;#ifdef COMMENT#ifdef DEBUG    if (deblog) {	debug(F101,"tcs","",tcs);	debug(F101,"tcsl","",tcsl);	debug(F101,"tcsr","",tcsr);	debug(F101,"fcsinfo[tcsl].size","",fcsinfo[tcsl].size);	debug(F101,"fcsinfo[tcsr].size","",fcsinfo[tcsr].size);    }#endif /* DEBUG */#endif /* COMMENT */#ifdef CK_XYZ#ifndef XYZ_INTERNAL    {	extern int binary;		/* See about ZMODEM autodownloads */	char * s;	s = binary ? ptab[PROTO_Z].p_b_rcmd : ptab[PROTO_Z].p_t_rcmd;	if (!s) s = "";	zmdlok = (*s != NUL);		/* OK if we have external commands */    }#endif /* XYZ_INTERNAL */#endif /* CK_XYZ */#ifndef NOESCSEQ/*  We need to activate the escape-sequence recognition feature when:   (a) translation is elected, AND   (b) the local and/or remote set is a 7-bit set other than US ASCII. Or:   SET TERMINAL APC is not OFF (handled in the next statement).*/    escseq = (tcs != TC_TRANSP) &&	/* Not transparent */      (fcsinfo[tcsl].size == 128 || fcsinfo[tcsr].size == 128) && /* 7 bits */	(fcsinfo[tcsl].code != FC_USASCII); /* But not ASCII */#endif /* NOESCSEQ */#endif /* NOCSETS */#ifndef NOESCSEQ#ifdef CK_APC    escseq = escseq || (apcstatus != APC_OFF);    apcactive = 0;			/* An APC command is not active */    apclength = 0;			/* ... */#endif /* CK_APC */    inesc = ES_NORMAL;			/* Initial state of recognizer */    debug(F101,"escseq","",escseq);#endif /* NOESCSEQ *//*  This is a label we jump back to when the lower fork sensed the need  to change modes.  As of 5A(178), this is used only by X.25 code  (perhaps unnecessarily? -- The X.25 code needs a lot of testing and  cleaning up...)  As of 5A(190), it is not used at all, good.*/#ifdef COMMENTnewfork:    debug(F100,"CONNECT newfork","",0);#endif /* COMMENT */    parent_id = getpid();		/* Get parent's pid for signalling */    debug(F101,"CONNECT parent pid","",parent_id);    if (xpipe[0] > -1)			/* If old pipe hanging around, close */      close(xpipe[0]);    xpipe[0] = -1;    if (xpipe[1] > -1)      close(xpipe[1]);    xpipe[1] = -1;    goterr = 0;				/* Error flag for pipe & fork */    if (pipe(xpipe) != 0) {		/* Create new pipe to pass info */	perror("Can't make pipe");	/* between forks. */	debug(F101,"CONNECT pipe error","",errno);	goterr = 1;    } else#ifdef BEBOX    {        pid = spawn_thread(concld, "Lower Fork", B_NORMAL_PRIORITY, NULL);        resume_thread(pid);    }#else    if ((pid = fork()) == (PID_T) -1) { /* Pipe OK, make port fork. */	perror("Can't make port fork");	debug(F101,"CONNECT fork error","",errno);	goterr = 1;	    }#endif /* BEBOX */    if (goterr) {			/* Failed to make pipe or fork */	conres();			/* Reset the console. */	if (!quiet) {	    printf("\r\nCommunications disconnect (Back at %s)\r\n",		   *myhost ?		   myhost :#ifdef UNIX		   "local UNIX system"#else		   "local system"#endif /* UNIX */		   );	}	printf("\n");	what = W_NOTHING;		/* So console modes are set right. */#ifndef NOCSETS	language = langsv;		/* Restore language */#endif /* NOCSETS */	parent_id = (PID_T) 0;		/* Clean up */	goto conret1;    }    debug(F101,"CONNECT fork pid","",pid);/* Upper fork (KEYB fork) reads keystrokes and sends them out. */    if (pid) {				/* pid != 0, so I am the upper fork. *//*  Before doing anything significant, the child fork must wait for a go-ahead  character from xpipe[0].  Before starting to wait, we have enough time to  clear buffers and set up the signal handler.  When done with this, we will  allow the child to continue by satisfying its pending read.  Remember the child and parent have separate address space.  The child has  its own copy of input buffers, so we must clear the input buffers in the  parent.  Otherwise strange effects may occur, like chunks of characters  repeatedly echoed on terminal screen.  The child process is designed to  empty its input buffers by reading all available characters and either  echoing them on the terminal screen or saving them for future use in the  parent.  The latter case happens during APC processing - see the code around  CEV_APC occurrences to see how the child passes its ibuf etc to parent via  xpipe, for preservation until the next entry to this module, to ensure that  no characters are lost between CONNECT sessions.*//*  This one needs a bit of extra explanation...  In addition to the CONNECT  module's own buffers, which are communicated and synchronized via xpipe,  the low-level UNIX communication routines (ttinc, ttxin, etc) are also  buffered, statically, in the ckutio.c module.  But when the two CONNECT  forks split off, the lower fork is updating this buffer's pointers and  counts, but the upper fork never finds out about it and still has the old  ones.  The following UNIX-specific call to the ckutio.c module takes care  of this...  Without it, we get dual echoing of incoming characters.*/	ttflux();/*  At this point, perhaps you are wondering why we use forks at all.  It is  simply because there is no other method portable among all UNIX variations.  Not threads, not select(), ...*/	ibp = ibuf;			/* Clear ibuf[]. */	ibc = 0;			/* Child now has its own copy */	signal(CK_FORK_SIG, pipeint);	/* Handler for messages from child. */	write(xpipe[1], ibuf, 1);	/* Allow child to proceed */	close(xpipe[1]); xpipe[1] = -1; /* Parent - prevent future writes */	what = W_CONNECT;		/* Keep track of what we're doing */	active = 1;	debug(F101,"CONNECT keyboard fork duplex","",duplex);/*  Catch communication errors or mode changes in lower fork.  Note: Some C compilers (e.g. Cray UNICOS) interpret the ANSI C standard  about setjmp() in a way that disallows constructions like:        if ((var = [sig]setjmp(env)) == 0) ...  which prevents the value returned by cklongjmp() from being used at all.  So the signal handlers set a global variable, sjval, instead.*/	if (#ifdef CK_POSIX_SIG	    sigsetjmp(con_env,1)#else	    setjmp(con_env)#endif /* CK_POSIX_SIG */	    == 0) {			/* Normal entry... */	    jbset = 1;			/* Now we have a longjmp buffer */	    sjval = CEV_NO;		/* Initialize setjmp return code. */	    debug(F101,"CONNECT setjmp normal entry","",sjval);#ifdef SUNX25	    if (network && nettype == NET_SX25) {		obufl = 0;		bzero (x25obuf,sizeof(x25obuf));	    }#endif /* SUNX25 *//*  Here is the big loop that gets characters from the keyboard and sends them  out the communication device.  There are two components to the communication  path: the connection from the keyboard to C-Kermit, and from C-Kermit to  the remote computer.  The treatment of the 8th bit of keyboard characters   is governed by SET COMMAND BYTESIZE (cmdmsk).  The treatment of the 8th bit  of characters sent to the remote is governed by SET TERMINAL BYTESIZE  (cmask).   This distinction was introduced in edit 5A(164).*/	    while (active) {#ifndef NOSETKEY		if (kmptr) {		/* Have current macro? */		    debug(F100,"kmptr non NULL","",0);		    if ((c = (CHAR) *kmptr++) == NUL) { /* Get char from it */			kmptr = NULL;	/* If no more chars,  */			debug(F100,"macro empty, continuing","",0);			continue;	/* reset pointer and continue */		    }		    debug(F000,"char from macro","",c);		} else			/* No macro... */#endif /* NOSETKEY */		  c = CONGKS();		/* Read from keyboard */		debug(F101,"** KEYB","",c);                if (c == -1) {		/* If read() got an error... */		    debug(F101,"CONNECT keyboard read errno","",errno);#ifdef COMMENT/* This seems to cause problems.  If read() returns -1, the signal has already been delivered, and nothing will wake up the pause().*/		    pause();		/* Wait for transmitter to finish. */#else#ifdef A986/*  On Altos machines with Xenix 3.0, pressing DEL in connect mode brings us  here (reason unknown).  The console line discipline at this point has  intr = ^C.  The communications tty has intr = DEL but we get here after  pressing DEL on the keyboard, even when the remote system has been set not  to echo.  With A986 defined, we stay in the read loop and beep only if the  offending character is not DEL.*/		    if ((c & 127) != 127) conoc(BEL);#else#ifdef EINTR/*   This can be caused by the other fork signalling this one about    an echoing change during TELNET negotiations.*/		    if (errno == EINTR)		      continue;#endif /* EINTR */		    conoc(BEL);		/* Otherwise, beep */		    active = 0;		/* and terminate the read loop */		    continue;#endif /* A986 */#endif /* COMMENT */		}		c &= cmdmsk;		/* Do any requested masking */#ifndef NOSETKEY/*  Note: kmptr is NULL if we got character c from the keyboard, and it is  not NULL if it came from a macro.  In the latter case, we must avoid  expanding it again.*/		if (!kmptr && macrotab[c]) { /* Macro definition for c? */		    kmptr = macrotab[c];     /* Yes, set up macro pointer */		    continue;		     /* and restart the loop, */		} else c = keymap[c];	     /* else use single-char keymap */#endif /* NOSETKEY */		if (#ifndef NOSETKEY		    !kmptr &&#endif /* NOSETKEY */		    (tt_escape && (c & 0x7f) == escape)) { /* Escape char? */		    debug(F000,"CONNECT got escape","",c);

⌨️ 快捷键说明

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