📄 telnet.c
字号:
* long as this is not a duplicate name (case * insensitive) add it to the list. */ if (n || (cp - cp2 > 41)) ; else if (name && (strncasecmp(name, cp2, cp-cp2) == 0)) *argv = cp2; else if (is_unique(cp2, argv+1, argvp)) *argvp++ = cp2; if (c == ':') break; /* * Skip multiple delimiters. Reset cp2 to * the beginning of the next name. Reset n, * the flag for names with spaces. */ while ((c = *cp) == '|') cp++; cp2 = cp; n = 0; } /* * Skip entries with spaces or non-ascii values. * Convert lower case letters to upper case. */ if ((c == ' ') || !isascii(c)) n = 1; else if (islower(c)) *cp = toupper(c); } /* * Check for an old V6 2 character name. If the second * name points to the beginning of the buffer, and is * only 2 characters long, move it to the end of the array. */ if ((argv[1] == buf) && (strlen(argv[1]) == 2)) { --argvp; for (avt = &argv[1]; avt < argvp; avt++) *avt = *(avt+1); *argvp++ = buf; } /* * Duplicate last name, for TTYPE option, and null * terminate the array. If we didn't find a match on * our terminal name, put that name at the beginning. */ cp = *(argvp-1); *argvp++ = cp; *argvp = 0; if (*argv == 0) { if (name) *argv = name; else { --argvp; for (avt = argv; avt < argvp; avt++) *avt = *(avt+1); } } if (*argv) return(argv); else return(unknown);}intis_unique(register char *name, register char **as, register char **ae){ register char **ap; register int n; n = strlen(name) + 1; for (ap = as; ap < ae; ap++) if (strncasecmp(*ap, name, n) == 0) return(0); return (1);}#ifdef TERMCAPchar termbuf[1024]; /*ARGSUSED*/intinit_term (char *tname, int fd, int *errp){ if (tgetent(termbuf, tname) == 1) { termbuf[1023] = '\0'; if (errp) *errp = 1; return(0); } if (errp) *errp = 0; return(-1);}#else#define termbuf ttytypeextern char ttytype[];#endifint resettermname = 1;char *gettermname(){ char *tname; static char **tnamep = 0; static char **next; int err; if (resettermname) { resettermname = 0; if (tnamep && tnamep != unknown) free(tnamep); if ((tname = (char *)env_getvalue((unsigned char *)"TERM")) && (init_term (tname, 1, &err) == 0)) { tnamep = mklist(termbuf, tname); } else { if (tname && ((int)strlen(tname) <= 40)) { unknown[0] = tname; upcase(tname); } else unknown[0] = name_unknown; tnamep = unknown; } next = tnamep; } if (*next == 0) next = tnamep; return(*next++);}/* * suboption() * * Look at the sub-option buffer, and try to be helpful to the other * side. * * Currently we recognize: * * Terminal type, send request. * Terminal speed (send request). * Local flow control (is request). * Linemode */static voidsuboption(){ unsigned char subchar; printsub('<', subbuffer, SB_LEN()+2); switch (subchar = SB_GET()) { case TELOPT_TTYPE: if (my_want_state_is_wont(TELOPT_TTYPE)) return; if (SB_EOF() || SB_GET() != TELQUAL_SEND) { return; } else { char *name; unsigned char temp[50]; int len;#if defined(TN3270) if (tn3270_ttype()) { return; }#endif /* defined(TN3270) */ name = gettermname(); len = strlen(name) + 4 + 2; if (len < NETROOM()) { sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, TELQUAL_IS, name, IAC, SE); ring_supply_data(&netoring, temp, len); printsub('>', &temp[2], len-2); } else { ExitString("No room in buffer for terminal type.\n", 1); /*NOTREACHED*/ } } break; case TELOPT_TSPEED: if (my_want_state_is_wont(TELOPT_TSPEED)) return; if (SB_EOF()) return; if (SB_GET() == TELQUAL_SEND) { long ospeed, ispeed; unsigned char temp[50]; int len; TerminalSpeeds(&ispeed, &ospeed); sprintf((char *)temp, "%c%c%c%c%d,%d%c%c", IAC, SB, TELOPT_TSPEED, TELQUAL_IS, ospeed, ispeed, IAC, SE); len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */ if (len < NETROOM()) { ring_supply_data(&netoring, temp, len); printsub('>', temp+2, len - 2); }/*@*/ else printf("lm_will: not enough room in buffer\n"); } break; case TELOPT_LFLOW: if (my_want_state_is_wont(TELOPT_LFLOW)) return; if (SB_EOF()) return; switch(SB_GET()) { case LFLOW_RESTART_ANY: restartany = 1; break; case LFLOW_RESTART_XON: restartany = 0; break; case LFLOW_ON: localflow = 1; break; case LFLOW_OFF: localflow = 0; break; default: return; } setcommandmode(); setconnmode(0); break; case TELOPT_LINEMODE: if (my_want_state_is_wont(TELOPT_LINEMODE)) return; if (SB_EOF()) return; switch (SB_GET()) { case WILL: lm_will(subpointer, SB_LEN()); break; case WONT: lm_wont(subpointer, SB_LEN()); break; case DO: lm_do(subpointer, SB_LEN()); break; case DONT: lm_dont(subpointer, SB_LEN()); break; case LM_SLC: slc(subpointer, SB_LEN()); break; case LM_MODE: lm_mode(subpointer, SB_LEN(), 0); break; default: break; } break;#ifdef OLD_ENVIRON case TELOPT_OLD_ENVIRON:#endif case TELOPT_NEW_ENVIRON: if (SB_EOF()) return; switch(SB_PEEK()) { case TELQUAL_IS: case TELQUAL_INFO: if (my_want_state_is_dont(subchar)) return; break; case TELQUAL_SEND: if (my_want_state_is_wont(subchar)) { return; } break; default: return; } env_opt(subpointer, SB_LEN()); break; case TELOPT_XDISPLOC: if (my_want_state_is_wont(TELOPT_XDISPLOC)) return; if (SB_EOF()) return; if (SB_GET() == TELQUAL_SEND) { unsigned char temp[50], *dp; int len; if ((dp = env_getvalue((unsigned char *)"DISPLAY")) == NULL) { /* * Something happened, we no longer have a DISPLAY * variable. So, turn off the option. */ send_wont(TELOPT_XDISPLOC, 1); break; } sprintf((char *)temp, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_XDISPLOC, TELQUAL_IS, dp, IAC, SE); len = strlen((char *)temp+4) + 4; /* temp[3] is 0 ... */ if (len < NETROOM()) { ring_supply_data(&netoring, temp, len); printsub('>', temp+2, len - 2); }/*@*/ else printf("lm_will: not enough room in buffer\n"); } break;#if defined(AUTHENTICATION) case TELOPT_AUTHENTICATION: { if (!autologin) break; if (SB_EOF()) return; switch(SB_GET()) { case TELQUAL_IS: if (my_want_state_is_dont(TELOPT_AUTHENTICATION)) return; auth_is(subpointer, SB_LEN()); break; case TELQUAL_SEND: if (my_want_state_is_wont(TELOPT_AUTHENTICATION)) return; auth_send(subpointer, SB_LEN()); break; case TELQUAL_REPLY: if (my_want_state_is_wont(TELOPT_AUTHENTICATION)) return; auth_reply(subpointer, SB_LEN()); break; case TELQUAL_NAME: if (my_want_state_is_dont(TELOPT_AUTHENTICATION)) return; auth_name(subpointer, SB_LEN()); break; } } break;#endif#ifdef ENCRYPTION case TELOPT_ENCRYPT: if (SB_EOF()) return; switch(SB_GET()) { case ENCRYPT_START: if (my_want_state_is_dont(TELOPT_ENCRYPT)) return; encrypt_start(subpointer, SB_LEN()); break; case ENCRYPT_END: if (my_want_state_is_dont(TELOPT_ENCRYPT)) return; encrypt_end(); break; case ENCRYPT_SUPPORT: if (my_want_state_is_wont(TELOPT_ENCRYPT)) return; encrypt_support(subpointer, SB_LEN()); break; case ENCRYPT_REQSTART: if (my_want_state_is_wont(TELOPT_ENCRYPT)) return; encrypt_request_start(subpointer, SB_LEN()); break; case ENCRYPT_REQEND: if (my_want_state_is_wont(TELOPT_ENCRYPT)) return; /* * We can always send an REQEND so that we cannot * get stuck encrypting. We should only get this * if we have been able to get in the correct mode * anyhow. */ encrypt_request_end(); break; case ENCRYPT_IS: if (my_want_state_is_dont(TELOPT_ENCRYPT)) return; encrypt_is(subpointer, SB_LEN()); break; case ENCRYPT_REPLY: if (my_want_state_is_wont(TELOPT_ENCRYPT)) return; encrypt_reply(subpointer, SB_LEN()); break; case ENCRYPT_ENC_KEYID: if (my_want_state_is_dont(TELOPT_ENCRYPT)) return; encrypt_enc_keyid(subpointer, SB_LEN()); break; case ENCRYPT_DEC_KEYID: if (my_want_state_is_wont(TELOPT_ENCRYPT)) return; encrypt_dec_keyid(subpointer, SB_LEN()); break; default: break; } break;#endif /* ENCRYPTION */ default: break; }}static unsigned char str_lm[] = { IAC, SB, TELOPT_LINEMODE, 0, 0, IAC, SE };voidlm_will(unsigned char *cmd, int len){ if (len < 1) {/*@*/ printf("lm_will: no command!!!\n"); /* Should not happen... */ return; } switch(cmd[0]) { case LM_FORWARDMASK: /* We shouldn't ever get this... */ default: str_lm[3] = DONT; str_lm[4] = cmd[0]; if (NETROOM() > sizeof(str_lm)) { ring_supply_data(&netoring, str_lm, sizeof(str_lm)); printsub('>', &str_lm[2], sizeof(str_lm)-2); }/*@*/ else printf("lm_will: not enough room in buffer\n"); break; }}voidlm_wont(unsigned char *cmd, int len){ if (len < 1) {/*@*/ printf("lm_wont: no command!!!\n"); /* Should not happen... */ return; } switch(cmd[0]) { case LM_FORWARDMASK: /* We shouldn't ever get this... */ default: /* We are always DONT, so don't respond */ return; }}voidlm_do(unsigned char *cmd, int len){ if (len < 1) {/*@*/ printf("lm_do: no command!!!\n"); /* Should not happen... */ return; } switch(cmd[0]) { case LM_FORWARDMASK: default: str_lm[3] = WONT; str_lm[4] = cmd[0]; if (NETROOM() > sizeof(str_lm)) { ring_supply_data(&netoring, str_lm, sizeof(str_lm)); printsub('>', &str_lm[2], sizeof(str_lm)-2); }/*@*/ else printf("lm_do: not enough room in buffer\n"); break; }}voidlm_dont(unsigned char *cmd, int len){ if (len < 1) {/*@*/ printf("lm_dont: no command!!!\n"); /* Should not happen... */ return; } switch(cmd[0]) { case LM_FORWARDMASK: default: /* we are always WONT, so don't respond */ break; }}static unsigned char str_lm_mode[] = { IAC, SB, TELOPT_LINEMODE, LM_MODE, 0, IAC, SE};voidlm_mode(unsigned char *cmd, int len, int init){ if (len != 1) return; if ((linemode&MODE_MASK&~MODE_ACK) == *cmd) return; if (*cmd&MODE_ACK) return; linemode = *cmd&(MODE_MASK&~MODE_ACK); str_lm_mode[4] = linemode; if (!init) str_lm_mode[4] |= MODE_ACK; if (NETROOM() > sizeof(str_lm_mode)) { ring_supply_data(&netoring, str_lm_mode, sizeof(str_lm_mode)); printsub('>', &str_lm_mode[2], sizeof(str_lm_mode)-2); }/*@*/ else printf("lm_mode: not enough room in buffer\n"); setconnmode(0); /* set changed mode */}/* * slc() * Handle special character suboption of LINEMODE. */struct spc { cc_t val; cc_t *valp; char flags; /* Current flags & level */ char mylevel; /* Maximum level & flags */} spc_data[NSLC+1];#define SLC_IMPORT 0#define SLC_EXPORT 1#define SLC_RVALUE 2static int slc_mode = SLC_EXPORT;voidslc_init(){ register struct spc *spcp; localchars = 1; for (spcp = spc_data; spcp < &spc_data[NSLC+1]; spcp++) { spcp->val = 0; spcp->valp = 0; spcp->flags = spcp->mylevel = SLC_NOSUPPORT; }#define initfunc(func, flags) { \ spcp = &spc_data[func]; \ if (spcp->valp = tcval(func)) { \ spcp->val = *spcp->valp; \ spcp->mylevel = SLC_VARIABLE|flags; \ } else { \ spcp->val = 0; \ spcp->mylevel = SLC_DEFAULT; \ } \ } initfunc(SLC_SYNCH, 0); /* No BRK */ initfunc(SLC_AO, 0); initfunc(SLC_AYT, 0); /* No EOR */ initfunc(SLC_ABORT, SLC_FLUSHIN|SLC_FLUSHOUT); initfunc(SLC_EOF, 0);#ifndef SYSV_TERMIO initfunc(SLC_SUSP, SLC_FLUSHIN);#endif initfunc(SLC_EC, 0); initfunc(SLC_EL, 0);#ifndef SYSV_TERMIO initfunc(SLC_EW, 0); initfunc(SLC_RP, 0); initfunc(SLC_LNEXT, 0);#endif initfunc(SLC_XON, 0); initfunc(SLC_XOFF, 0);#ifdef SYSV_TERMIO spc_data[SLC_XON].mylevel = SLC_CANTCHANGE; spc_data[SLC_XOFF].mylevel = SLC_CANTCHANGE;#endif initfunc(SLC_FORW1, 0);#ifdef USE_TERMIO initfunc(SLC_FORW2, 0); /* No FORW2 */#endif initfunc(SLC_IP, SLC_FLUSHIN|SLC_FLUSHOUT);#undef initfunc if (slc_mode == SLC_EXPORT) slc_export(); else slc_import(1);}voidslcstate(){ printf("Special characters are %s values\n", slc_mode == SLC_IMPORT ? "remote default" : slc_mode == SLC_EXPORT ? "local" : "remote");}voidslc_mode_export(){ slc_mode = SLC_EXPORT; if (my_state_is_will(TELOPT_LINEMODE)) slc_export();}voidslc_mode_import(int def){ slc_mode = def ? SLC_IMPORT : SLC_RVALUE; if (my_state_is_will(TELOPT_LINEMODE)) slc_import(def);}unsigned char slc_import_val[] = { IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_VARIABLE, 0, IAC, SE};unsigned char slc_import_def[] = { IAC, SB, TELOPT_LINEMODE, LM_SLC, 0, SLC_DEFAULT, 0, IAC, SE};voidslc_import(int def){ if (NETROOM() > sizeof(slc_import_val)) { if (def) { ring_supply_data(&netoring, slc_import_def, sizeof(slc_import_def)); printsub('>', &slc_import_def[2], sizeof(slc_import_def)-2); } else { ring_supply_data(&netoring, slc_import_val, sizeof(slc_import_val)); printsub('>', &slc_import_val[2], sizeof(slc_import_val)-2); } }/*@*/ else printf("slc_import: not enough room\n");}voidslc_export(){ register struct spc *spcp; TerminalDefaultChars(); slc_start_reply(); for (spcp = &spc_data[1]; spcp < &spc_data[NSLC+1]; spcp++) { if (spcp->mylevel != SLC_NOSUPPORT) { if (spcp->val == (cc_t)(_POSIX_VDISABLE)) spcp->flags = SLC_NOSUPPORT; else spcp->flags = spcp->mylevel; if (spcp->valp) spcp->val = *spcp->valp; slc_add_reply(spcp - spc_data, spcp->flags, spcp->val); } } slc_end_reply();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -