static void suboption(struct connectdata *conn) { struct curl_slist *v; unsigned char temp[2048]; int len; int tmplen; char varname[128]; char varval[128]; struct SessionHandle *data = conn->data; struct TELNET *tn = (struct TELNET *)conn->proto.telnet; printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2); switch (CURL_SB_GET(tn)) { case CURL_TELOPT_TTYPE: len = strlen(tn->subopt_ttype) + 4 + 2; snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE); (void)swrite(conn->sock[FIRSTSOCKET], temp, len); printsub(data, '>', &temp[2], len-2); break; case CURL_TELOPT_XDISPLOC: len = strlen(tn->subopt_xdisploc) + 4 + 2; snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE); (void)swrite(conn->sock[FIRSTSOCKET], temp, len); printsub(data, '>', &temp[2], len-2); break; case CURL_TELOPT_NEW_ENVIRON: snprintf((char *)temp, sizeof(temp), "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, CURL_TELQUAL_IS); len = 4; for(v = tn->telnet_vars; v; v = v->next) { tmplen = (strlen(v->data) + 1); /* Add the variable only if it fits */ if(len + tmplen < (int)sizeof(temp)-6) { sscanf(v->data, "%127[^,],%s", varname, varval); snprintf((char *)&temp[len], sizeof(temp) - len, "%c%s%c%s", CURL_NEW_ENV_VAR, varname, CURL_NEW_ENV_VALUE, varval); len += tmplen; } } snprintf((char *)&temp[len], sizeof(temp) - len, "%c%c", CURL_IAC, CURL_SE); len += 2; (void)swrite(conn->sock[FIRSTSOCKET], temp, len); printsub(data, '>', &temp[2], len-2); break; } return; }
void slc_import(int def) { if (NETROOM() > (int)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"); }
/* * This routine is called by the server to start authentication * negotiation. */ void auth_request(void) { static unsigned char str_request[64] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_SEND, }; Authenticator *ap = authenticators; unsigned char *e = str_request + 4; if (!authenticating) { authenticating = 1; while (ap->type) { if (i_support & ~i_wont_support & typemask(ap->type)) { if (auth_debug_mode) { printf(">>>%s: Sending type %d %d\r\n", Name, ap->type, ap->way); } *e++ = ap->type; *e++ = ap->way; } ++ap; } *e++ = IAC; *e++ = SE; net_write(str_request, e - str_request); printsub('>', &str_request[2], e - str_request - 2); } }
static int Data(Authenticator *ap, int type, void *d, int c) { unsigned char *p = str_data + 4; unsigned char *cd = (unsigned char *)d; if (c == -1) c = strlen(cd); if (auth_debug_mode) { printf("%s:%d: [%d] (%d)", str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY", str_data[3], type, c); printd(d, c); printf("\r\n"); } *p++ = ap->type; *p++ = ap->way; *p++ = type; while (c-- > 0) { if ((*p++ = *cd++) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; if (str_data[3] == TELQUAL_IS) printsub('>', &str_data[2], p - &str_data[2]); return(net_write(str_data, p - str_data)); }
int get_status() { unsigned char tmp[16]; unsigned char *cp; if (my_want_state_is_dont(TELOPT_STATUS)) { printf("Remote side does not support STATUS option\n"); return 0; } cp = tmp; *cp++ = IAC; *cp++ = SB; *cp++ = TELOPT_STATUS; *cp++ = TELQUAL_SEND; *cp++ = IAC; *cp++ = SE; if (NETROOM() >= cp - tmp) { ring_supply_data(&netoring, tmp, cp-tmp); printsub('>', tmp+2, cp - tmp - 2); } ++want_status_response; return 1; }
void sendnaws() { long rows, cols; unsigned char tmp[16]; unsigned char *cp; if (my_state_is_wont(TELOPT_NAWS)) return; #undef PUTSHORT #define PUTSHORT(cp, x) { if ((*cp++ = ((x)>>8)&0xff) == IAC) *cp++ = IAC; \ if ((*cp++ = ((x))&0xff) == IAC) *cp++ = IAC; } if (TerminalWindowSize(&rows, &cols) == 0) { /* Failed */ return; } cp = tmp; *cp++ = IAC; *cp++ = SB; *cp++ = TELOPT_NAWS; PUTSHORT(cp, cols); PUTSHORT(cp, rows); *cp++ = IAC; *cp++ = SE; if (NETROOM() >= cp - tmp) { ring_supply_data(&netoring, tmp, cp-tmp); printsub('>', tmp+2, cp - tmp - 2); } }
static int getterminaltype (void) { int retval = -1; settimer(baseline); send_do(TELOPT_TTYPE, 1); send_do(TELOPT_TSPEED, 1); send_do(TELOPT_XDISPLOC, 1); send_do(TELOPT_ENVIRON, 1); while (his_will_wont_is_changing(TELOPT_TTYPE) || his_will_wont_is_changing(TELOPT_TSPEED) || his_will_wont_is_changing(TELOPT_XDISPLOC) || his_will_wont_is_changing(TELOPT_ENVIRON)) { ttloop(); } if (his_state_is_will(TELOPT_TSPEED)) { static unsigned char sb[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; memmove((void *)nfrontp, (void *)sb, sizeof sb); nfrontp += sizeof sb; DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); }
int getterminaltype(char *name, size_t name_sz) { int retval = -1; settimer(baseline); #ifdef AUTHENTICATION /* * Handle the Authentication option before we do anything else. */ send_do(TELOPT_AUTHENTICATION, 1); while (his_will_wont_is_changing(TELOPT_AUTHENTICATION)) ttloop(); if (his_state_is_will(TELOPT_AUTHENTICATION)) { retval = auth_wait(name, name_sz); } #endif #ifdef ENCRYPTION send_will(TELOPT_ENCRYPT, 1); send_do(TELOPT_ENCRYPT, 1); /* [email protected] */ #endif /* DayDream wants binary transmission mode */ send_will(TELOPT_BINARY, 1); send_do(TELOPT_BINARY, 1); send_do(TELOPT_TTYPE, 1); send_do(TELOPT_TSPEED, 1); send_do(TELOPT_XDISPLOC, 1); send_do(TELOPT_NEW_ENVIRON, 1); send_do(TELOPT_OLD_ENVIRON, 1); while ( #ifdef ENCRYPTION his_do_dont_is_changing(TELOPT_ENCRYPT) || #endif his_do_dont_is_changing(TELOPT_BINARY) || his_will_wont_is_changing(TELOPT_TTYPE) || his_will_wont_is_changing(TELOPT_TSPEED) || his_will_wont_is_changing(TELOPT_XDISPLOC) || his_will_wont_is_changing(TELOPT_NEW_ENVIRON) || his_will_wont_is_changing(TELOPT_OLD_ENVIRON)) { ttloop(); } #ifdef ENCRYPTION /* * Wait for the negotiation of what type of encryption we can * send with. If autoencrypt is not set, this will just return. */ if (his_state_is_will(TELOPT_ENCRYPT)) { encrypt_wait(); } #endif if (his_state_is_will(TELOPT_BINARY)) { static unsigned char sb[] = { IAC, SB, TELOPT_BINARY, TELQUAL_SEND, IAC, SE }; telnet_net_write (sb, sizeof sb); DIAG(TD_OPTIONS, printsub('>', sb + 2, sizeof sb - 2);); }
static int fb64_start(struct fb *fbp, int dir, int server __unused) { size_t x; unsigned char *p; int state; switch (dir) { case DIR_DECRYPT: /* * This is simply a request to have the other side * start output (our input). He will negotiate an * IV so we need not look for it. */ state = fbp->state[dir-1]; if (state == FAILED) state = IN_PROGRESS; break; case DIR_ENCRYPT: state = fbp->state[dir-1]; if (state == FAILED) state = IN_PROGRESS; else if ((state & NO_SEND_IV) == 0) break; if (!VALIDKEY(fbp->krbdes_key)) { fbp->need_start = 1; break; } state &= ~NO_SEND_IV; state |= NO_RECV_IV; if (encrypt_debug_mode) printf("Creating new feed\r\n"); /* * Create a random feed and send it over. */ des_random_key((Block *)fbp->temp_feed); des_ecb_encrypt((Block *)fbp->temp_feed, (Block *)fbp->temp_feed, fbp->krbdes_sched, 1); p = fbp->fb_feed + 3; *p++ = ENCRYPT_IS; p++; *p++ = FB64_IV; for (x = 0; x < sizeof(Block); ++x) { if ((*p++ = fbp->temp_feed[x]) == IAC) *p++ = IAC; } *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); net_write(fbp->fb_feed, p - fbp->fb_feed); break; default: return(FAILED); } return(fbp->state[dir-1] = state); }
int net_write(unsigned char *str, int len) { if (NETROOM() > len) { ring_supply_data(&netoring, str, len); if (str[0] == IAC && str[1] == SE) printsub('>', &str[2], len-2); return(len); } return(0); }
static void sendsuboption(struct connectdata *conn, int option) { ssize_t bytes_written; int err; unsigned short x, y; unsigned char*uc1, *uc2; struct SessionHandle *data = conn->data; struct TELNET *tn = (struct TELNET *)data->req.protop; switch (option) { case CURL_TELOPT_NAWS: /* We prepare data to be sent */ CURL_SB_CLEAR(tn); CURL_SB_ACCUM(tn, CURL_IAC); CURL_SB_ACCUM(tn, CURL_SB); CURL_SB_ACCUM(tn, CURL_TELOPT_NAWS); /* We must deal either with litte or big endien processors */ /* Window size must be sent according to the 'network order' */ x=htons(tn->subopt_wsx); y=htons(tn->subopt_wsy); uc1 = (unsigned char*)&x; uc2 = (unsigned char*)&y; CURL_SB_ACCUM(tn, uc1[0]); CURL_SB_ACCUM(tn, uc1[1]); CURL_SB_ACCUM(tn, uc2[0]); CURL_SB_ACCUM(tn, uc2[1]); CURL_SB_ACCUM(tn, CURL_IAC); CURL_SB_ACCUM(tn, CURL_SE); CURL_SB_TERM(tn); /* data suboption is now ready */ printsub(data, '>', (unsigned char *)tn->subbuffer+2, CURL_SB_LEN(tn)-2); /* we send the header of the suboption... */ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer, 3); if(bytes_written < 0) { err = SOCKERRNO; failf(data, "Sending data failed (%d)", err); } /* ... then the window size with the send_telnet_data() function to deal with 0xFF cases ... */ send_telnet_data(conn, (char *)tn->subbuffer+3, 4); /* ... and the footer */ bytes_written = swrite(conn->sock[FIRSTSOCKET], tn->subbuffer+7, 2); if(bytes_written < 0) { err = SOCKERRNO; failf(data, "Sending data failed (%d)", err); } break; } }
void encrypt_send_support(void) { if (str_suplen) { /* * If the user has requested that decryption start * immediatly, then send a "REQUEST START" before * we negotiate the type. */ if (!Server && autodecrypt) encrypt_send_request_start(); net_write(str_send, str_suplen); printsub('>', &str_send[2], str_suplen - 2); str_suplen = 0; } }
/* * end_slc * * Finish up the slc negotiation. If something to send, then send it. */ int end_slc (register unsigned char **bufp) { register int len; void netflush (); /* * If a change has occured, store the new terminal control * structures back to the terminal driver. */ if (slcchange) { set_termbuf (); } /* * If the pty state has not yet been fully processed and there is a * deferred slc request from the client, then do not send any * sort of slc negotiation now. We will respond to the client's * request very soon. */ if (def_slcbuf && (terminit () == 0)) { return (0); } if (slcptr > (slcbuf + 4)) { if (bufp) { *bufp = &slcbuf[4]; return (slcptr - slcbuf - 4); } else { sprintf ((char *) slcptr, "%c%c", IAC, SE); slcptr += 2; len = slcptr - slcbuf; net_output_datalen (slcbuf, len); netflush (); /* force it out immediately */ DEBUG (debug_options, 1, printsub ('>', slcbuf + 2, len - 2)); } } return (0); } /* end of end_slc */
void slc_end_reply(void) { int len; /* The end of negotiation command requires 2 bytes. */ if (&slc_replyp[2] > slc_reply_eom) return; *slc_replyp++ = IAC; *slc_replyp++ = SE; len = slc_replyp - slc_reply; if (len <= 6) return; if (NETROOM() > len) { ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply); printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2); } /*@*/else printf("slc_end_reply: not enough room\n"); }
int tn3270_ttype(void) { /* * Try to send a 3270 type terminal name. Decide which one based * on the format of our screen, and (in the future) color * capaiblities. */ InitTerminal(); /* Sets MaxNumberColumns, MaxNumberLines */ if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) { Sent3270TerminalType = 1; if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) { MaxNumberLines = 27; MaxNumberColumns = 132; sb_terminal[SBTERMMODEL] = '5'; } else if (MaxNumberLines >= 43) { MaxNumberLines = 43; MaxNumberColumns = 80; sb_terminal[SBTERMMODEL] = '4'; } else if (MaxNumberLines >= 32) { MaxNumberLines = 32; MaxNumberColumns = 80; sb_terminal[SBTERMMODEL] = '3'; } else { MaxNumberLines = 24; MaxNumberColumns = 80; sb_terminal[SBTERMMODEL] = '2'; } NumberLines = 24; /* before we start out... */ NumberColumns = 80; ScreenSize = NumberLines*NumberColumns; if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) { ExitString("Programming error: MAXSCREENSIZE too small.\n", 1); /*NOTREACHED*/ } printsub('>', sb_terminal+2, sizeof sb_terminal-2); ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal); return 1; } else { return 0; } }
void lm_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() > (int)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 */ }
void lm_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() > (int)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; } }
void env_opt_end(int emptyok) { int len; len = opt_replyp - opt_reply + 2; if (emptyok || len > 6) { opt_add(IAC); opt_add(SE); if (NETROOM() > len) { ring_supply_data(&netoring, opt_reply, len); printsub('>', &opt_reply[2], len - 2); } /*@*/ else printf("slc_end_reply: not enough room\n"); } if (opt_reply) { free(opt_reply); opt_reply = opt_replyp = opt_replyend = NULL; } }
int auth_sendname(unsigned char *cp, int len) { static unsigned char str_request[256+6] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_NAME, }; unsigned char *e = str_request + 4; unsigned char *ee = &str_request[sizeof(str_request)-2]; while (--len >= 0) { if ((*e++ = *cp++) == IAC) *e++ = IAC; if (e >= ee) return(0); } *e++ = IAC; *e++ = SE; net_write(str_request, e - str_request); printsub('>', &str_request[2], e - &str_request[2]); return(1); }
static void slc_end_reply(void) { int len; if (slc_replyp + 2 >= slc_reply + sizeof(slc_reply)) { printf("slc_end_reply: not enough room\n"); return; } slc_add(IAC); slc_add(SE); len = slc_replyp - slc_reply; if (len <= 6) return; if (NETROOM() > len) { ring_supply_data(&netoring, slc_reply, slc_replyp - slc_reply); printsub('>', &slc_reply[2], slc_replyp - slc_reply - 2); } /*@*/else printf("slc_end_reply: not enough room\n"); }
void env_opt_end(int emptyok) { int len; if (opt_replyp + 2 > opt_replyend) return; len = opt_replyp + 2 - opt_reply; if (emptyok || len > 6) { *opt_replyp++ = IAC; *opt_replyp++ = SE; if (NETROOM() > len) { ring_supply_data(&netoring, opt_reply, len); printsub('>', &opt_reply[2], len - 2); } /*@*/ else printf("slc_end_reply: not enough room\n"); } if (opt_reply) { free(opt_reply); opt_reply = opt_replyp = opt_replyend = NULL; } }
static void suboption(void) { 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 { const char *name; unsigned char temp[50]; int len; name = gettermname(); len = strlen(name) + 4 + 2; if (len < NETROOM()) { sprintf(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%ld,%ld%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("DISPLAY")) == NULL || strlen(dp) > sizeof(temp) - 7) { /* * Something happened, we no longer have a DISPLAY * variable. Or it is too long. So, turn off the option. */ send_wont(TELOPT_XDISPLOC, 1); break; } snprintf(temp, sizeof(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; #ifdef 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; } }
void wiz_mode() { if(wiz_list.wizard_mode != 1) { printlog("#### 경고! 위자드모드는 점수등록이 안되며 재미를 큰폭으로 떨어뜨립니다. ### ",true,false,false,CL_danger); printlog("진짜로 킬꺼야? (Y/N) ",false,false,false,CL_danger); int key_ = waitkeyinput(); switch(key_) { case 'Y': enterlog(); break; default: printlog("위자드모드를 취소",true,false,false,CL_help); return; } } printlog("<위자드모드> 어느 명령어? ( ? - 도움말 )",true,false,false,CL_help); wiz_list.wizard_mode = 1; while(1) { int key_ = waitkeyinput(); changedisplay(DT_GAME); switch(key_) { case 'D': //맵밝히기 for(int i = 0;i<DG_MAX_X;i++) for(int j = 0;j<DG_MAX_Y;j++) env[current_level].magicmapping(i,j); break; case 'f': //연기 //for(int i = -1;i<2;i++) // for(int j = -1;j<2;j++) // env[current_level].MakeSmoke(coord_def(i+you.position.x,j+you.position.y),img_fog_fire,SMT_NORMAL,10,0,&you); MakeCloud(you.position, img_fog_thunder, SMT_ELEC, rand_int(8,10), rand_int(80,120), 0,5, &you); break; case 'A': { printlog("p-포션 s-스크롤 e-발동템 v-스펠카드 r-반지 b-책 a-방어구",true,false,false,CL_help); printlog("어느 아이템을 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); switch(key_) { case 'p': { int list[] = {PT_WATER, PT_HEAL, PT_POISON, PT_HEAL_WOUND, PT_MIGHT, PT_HASTE, PT_CONFUSE, PT_SLOW, PT_PARALYSIS, PT_CLEVER, PT_AGILITY, PT_MAGIC, PT_LEVETATION, PT_POWER, PT_DOWN_STAT, PT_RECOVER_STAT, PT_ALCOHOL}; enterlog(); printlog("a-물 b-치유 c-독 d-체력회복 e-힘 f-가속 g-혼란 h-감속 i-마비",true,false,false,CL_help); printlog("j-지능 k-민첩 l-영력 m-비행 n-파워 o-능력치감소 p-능력치회복 q-술",true,false,false,CL_help); printlog("어느 포션을 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); if(key_ >= 'a' && key_ <= 'q') { for(int i=0;i<10;i++) { item_infor t; makeitem(ITM_POTION, 0, &t, list[key_-'a']); env[current_level].MakeItem(you.position,t); enterlog(); } } else{ printlog(" 취소",true,false,false,CL_help); } } return; case 's': { int list[] = {SCT_TELEPORT,SCT_IDENTIFY,SCT_NONE,SCT_CURSE_WEAPON,SCT_CURSE_ARMOUR,SCT_REMOVE_CURSE, SCT_BLINK,SCT_MAPPING,SCT_ENCHANT_WEAPON_1, SCT_ENCHANT_ARMOUR,SCT_FOG,SCT_DETECT_CURSE, SCT_CURSE_JEWELRY,SCT_SILENCE,SCT_SOUL_SHOT,SCT_CHARGING,SCT_AMNESIA}; enterlog(); printlog("a-텔포 b-식별 c-낙서 d-무기저주 e-방어구저주 f-저주해제 g-순간이동 h-마법지도",true,false,false,CL_help); printlog("i-무기강화 j-방어구강화 k-연기 l-저주감지 m-장신구저주 n-정적 o-영격 p-스펠충전",true,false,false,CL_help); printlog("q-망각",true,false,false,CL_help); printlog("어느 스크롤을 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); if(key_ >= 'a' && key_ <= 'q') { for(int i=0;i<10;i++) { item_infor t; makeitem(ITM_SCROLL, 0, &t, list[key_-'a']); env[current_level].MakeItem(you.position,t); enterlog(); } } else{ printlog(" 취소",true,false,false,CL_help); } } return; case 'e': { int list[] = {EVK_PAGODA,EVK_AIR_SCROLL,EVK_DREAM_SOUL}; enterlog(); printlog("a-보탑 b-에어두루마리 c-몽혼",true,false,false,CL_help); printlog("어느 발동템을 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); if(key_ >= 'a' && key_ <= 'c') { item_infor t; makeitem(ITM_MISCELLANEOUS, 0, &t, list[key_-'a']); env[current_level].MakeItem(you.position,t); enterlog(); } else{ printlog(" 취소",true,false,false,CL_help); } } return; case 'v': { int list[] = {SPC_V_FIRE,SPC_V_ICE,SPC_V_EARTH,SPC_V_AIR,SPC_V_INVISIBLE}; enterlog(); printlog("a-화염 b-냉기 c-대지 d-대기 e-투명",true,false,false,CL_help); printlog("어느 스펠카드를 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); if(key_ >= 'a' && key_ <= 'e') { item_infor t; makeitem(ITM_SPELL, 0, &t, list[key_-'a']); env[current_level].MakeItem(you.position,t); enterlog(); } else{ printlog(" 취소",true,false,false,CL_help); } } return; case 'r': { int list[] = {RGT_STR,RGT_DEX,RGT_INT,RGT_HUNGRY,RGT_FULL,RGT_TELEPORT,RGT_POISON_RESIS, RGT_FIRE_RESIS, RGT_ICE_RESIS,RGT_SEE_INVISIBLE,RGT_GRAZE,RGT_LEVITATION,RGT_INVISIBLE, RGT_MANA,RGT_MAGACIAN,RGT_AC,RGT_EV,RGT_CONFUSE_RESIS, RGT_ELEC_RESIS,RGT_MAGIC_RESIS}; enterlog(); printlog("a-힘 b-민첩 c-지능 d-허기 e-만복도 f-공간이동 g-독저항 h-화염저항",true,false,false,CL_help); printlog("i-냉기저항 j-투명보기 k-그레이즈 l-비행 m-투명 n-영력 o-마법사 p-방어",true,false,false,CL_help); printlog("q-회피 r-혼란저항 s-전기저항 t-마법저항 !-아티펙트",true,false,false,CL_help); printlog("어느 반지를 얻어볼까?",false,false,false,CL_help); key_ = waitkeyinput(); if(key_ >= 'a' && key_ <= 't') { item_infor t; makeitem(ITM_RING, 0, &t, list[key_-'a']); env[current_level].MakeItem(you.position,t); enterlog(); } else if(key_ == '!') { item_infor t; makeitem(ITM_RING,randA(9)?1:-1,&t); t.artifact = true; item *it_ = env[current_level].MakeItem(you.position,t); MakeArtifact(it_,it_->curse?-1:1); enterlog(); } else{ printlog(" 취소",true,false,false,CL_help); } } return; case 'b': { item_infor t; makeitem(ITM_BOOK, 0, &t, -1); env[current_level].MakeItem(you.position,t); } return; case 'a': { item_infor t; item_type atype_ = (item_type)rand_int(ITM_ARMOR_BODY_FIRST,ITM_ARMOR_BODY_LAST-1); if(randA(1)==0) atype_ = (item_type)rand_int(ITM_ARMOR_HEAD,ITM_ARMOR_BOOT); makeitem(atype_,randA(2)?0:(randA(3)?1:-1),&t); if(randA(1)) t.artifact = true; item *it_ =env[current_level].MakeItem(you.position,t); if(t.artifact) MakeArtifact(it_,it_->curse?-1:1); } return; default: printlog(" 취소",true,false,false,CL_help); return; } } case 'H': you.HpUpDown(you.max_hp,DR_EFFECT); you.MpUpDown(you.max_mp); you.PowUpDown(500,true); break; case 'X': you.GetExp(you.GetNeedExp(you.level-1) - you.exper); break; case '>': //다음층 이동 if(!environment::isLastFloor(current_level)) { deque<monster*> dq; env[current_level+1].EnterMap(0,dq); //you.resetLOS(false); } break; case '<': //이전층 이동 if(!environment::isFirstFloor(current_level)) { deque<monster*> dq; env[current_level-1].EnterMap(0,dq); //you.resetLOS(false); } break; case 'G': //던전이동 { deque<monster*> dq; dungeon_level next_ = TEMPLE_LEVEL; printlog("d - 던전 t - 신전 l - 안개의 호수 m - 요괴의 산 s - 홍마관",true,false,false,CL_help); printlog("b - 홍마관도서관 u - 홍마관지하 a - 미궁의죽림 e - 영원정 y - 윳쿠리둥지 ",true,false,false,CL_help); printlog("p - 짐승길 h - 지령전 r - 꿈의 세계 o - 달의 세계 k - 마계 z - 하쿠레이신사",true,false,false,CL_help); printlog("어느 던전으로 이동해볼까? (대문자로 마지막층)",false,false,false,CL_help); key_ = waitkeyinput(); switch(key_) { case 'd': next_ = (dungeon_level)0; break; case 'D': next_ = MAX_DUNGEUN_LEVEL; break; case 't': case 'T': next_ = TEMPLE_LEVEL; break; case 'l': next_ = MISTY_LAKE_LEVEL; break; case 'L': next_ = MISTY_LAKE_LAST_LEVEL; break; case 'm': next_ = YOUKAI_MOUNTAIN_LEVEL; break; case 'M': next_ = YOUKAI_MOUNTAIN_LAST_LEVEL; break; case 's': next_ = SCARLET_LEVEL; break; case 'S': next_ = SCARLET_LEVEL_LAST_LEVEL; break; case 'b': case 'B': next_ = SCARLET_LIBRARY_LEVEL; break; case 'u': case 'U': next_ = SCARLET_UNDER_LEVEL; break; case 'a': case 'A': next_ = BAMBOO_LEVEL; break; case 'e': case 'E': next_ = EIENTEI_LEVEL; break; case 'h': next_ = SUBTERRANEAN_LEVEL; break; case 'H': next_ = SUBTERRANEAN_LEVEL_LAST_LEVEL; break; case 'y': next_ = YUKKURI_LEVEL; break; case 'Y': next_ = YUKKURI_LAST_LEVEL; break; case 'p': next_ = DEPTH_LEVEL; break; case 'P': next_ = DEPTH_LAST_LEVEL; break; case 'r': case 'R': next_ = DREAM_LEVEL; break; case 'o': case 'O': next_ = MOON_LEVEL; break; case 'k': case 'K': next_ = PANDEMONIUM_LEVEL; break; case 'z': next_ = HAKUREI_LEVEL; break; case 'Z': next_ = HAKUREI_LAST_LEVEL; break; default: printlog(" 취소",true,false,false,CL_help); return; } enterlog(); env[next_].EnterMap(0,dq); printlog("계단을 내려왔다.",true,false,false,CL_normal); //you.resetLOS(false); break; } case 'b': you.Blink(40); break; case 's': //skill_summon_bug(10,false,&you,you.position); if(you.equipment[ET_WEAPON] && !you.equipment[ET_WEAPON]->isArtifact()) { you.equipment[ET_WEAPON]->value5 = WB_CURSE; you.equipment[ET_WEAPON]->value6 = -1; } else { printlog("마법이 듣지 않는다.",true,false,false,CL_normal); } break; case 'w': //skill_summon_bug(100,&you,you.position); you.SetBuff((stat_up)rand_int(BUFFSTAT_STR,BUFFSTAT_EV),BUFF_DUPLE,rand_int(-3,3),10); break; case 'p': { dungeon_tile_type next_ = DG_TEMPLE_FIRST; printlog("B - 뱌쿠렌 K - 카나코 W - 스와코 A - 미노리코",true,false,false,CL_help); printlog("M - 미마 P - 신키 G - 유우기 Z - 시즈하 H - 히나 Y - 유카리 ",true,false,false,CL_help); printlog("E - 에이린 U - 유유코 S - 사토리 T - 텐시 J - 세이자 L - 릴리",true,false,false,CL_help); printlog("어떤 신전을 만들까?",false,false,false,CL_help); wiz_list.wizard_mode = true; key_ = waitkeyinput(); switch(key_) { //case 'x': //case 'X': // next_ = DG_TEMPLE_SHIKIEIKI; // break; case 'b': case 'B': next_ = DG_TEMPLE_BYAKUREN; break; case 'k': case 'K': next_ = DG_TEMPLE_KANAKO; break; case 'w': case 'W': next_ = DG_TEMPLE_SUWAKO; break; case 'a': case 'A': next_ = DG_TEMPLE_MINORIKO; break; case 'm': case 'M': next_ = DG_TEMPLE_MIMA; break; case 'p': case 'P': next_ = DG_TEMPLE_SHINKI; break; case 'g': case 'G': next_ = DG_TEMPLE_YUUGI; break; case 'z': case 'Z': next_ = DG_TEMPLE_SHIZUHA; break; case 'h': case 'H': next_ = DG_TEMPLE_HINA; break; case 'y': case 'Y': next_ = DG_TEMPLE_YUKARI; break; case 'e': case 'E': next_ = DG_TEMPLE_EIRIN; break; case 'u': case 'U': next_ = DG_TEMPLE_YUYUKO; break; case 's': case 'S': next_ = DG_TEMPLE_SATORI; break; case 't': case 'T': next_ = DG_TEMPLE_TENSI; break; case 'j': case 'J': next_ = DG_TEMPLE_SEIJA; break; case 'L': case 'l': next_ = DG_TEMPLE_LILLY; break; default: printlog(" 취소",true,false,false,CL_help); return; } enterlog(); env[current_level].dgtile[you.position.x][you.position.y].tile = next_; } break; case 'W': if(you.s_the_world) { you.s_the_world = 0; } else { you.s_the_world = -1; } break; case '!': { you.Memorize(SPL_DISCHARGE,true); } break; /*case 'M': if(monster* mon_=BaseSummon(MON_LUNAR, 100, false, false, 2, &you, you.position, SKD_OTHER, -1)) { mon_->state.SetState(MS_SLEEP); mon_->flag &= ~M_FLAG_SUMMON; mon_->ReturnEnemy(); } if(monster* mon_=BaseSummon(MON_STAR, 100, false, false, 2, &you, you.position, SKD_OTHER, -1)) { mon_->state.SetState(MS_SLEEP); mon_->flag &= ~M_FLAG_SUMMON; mon_->ReturnEnemy(); } if(monster* mon_=BaseSummon(MON_SUNNY, 100, false, false, 2, &you, you.position, SKD_OTHER, -1)) { mon_->state.SetState(MS_SLEEP); mon_->flag &= ~M_FLAG_SUMMON; mon_->ReturnEnemy(); } break; case 'm': if(monster* mon_=BaseSummon(MON_BENBEN, 100, false, false, 2, &you, you.position, SKD_OTHER, -1)) { mon_->state.SetState(MS_SLEEP); mon_->flag &= ~M_FLAG_SUMMON; mon_->ReturnEnemy(); } if(monster* mon_=BaseSummon(MON_YATHASI, 100, false, false, 2, &you, you.position, SKD_OTHER, -1)) { mon_->state.SetState(MS_SLEEP); mon_->flag &= ~M_FLAG_SUMMON; mon_->ReturnEnemy(); } break;*/ case '^': if(you.god != GT_SEIJA) you.PietyUpDown(10); you.GiftCount(10); break; case 'C': { for(vector<monster>::iterator it = env[current_level].mon_vector.begin(); it != env[current_level].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } for(list<item>::iterator it = env[current_level].item_list.begin(); it != env[current_level].item_list.end(); it++) { it->position = you.position; } } break; case 'E': { int prevexp_=0, exp_ = 0; for(int i = 0; i <= map_list.dungeon_enter[MISTY_LAKE].floor; i++) { env[i].MakeMap(true); for(vector<monster>::iterator it = env[i].mon_vector.begin(); it != env[i].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } } exp_ = you.exper; char temp[200]; sprintf_s(temp,200,"일반던전 %d층까지 레벨:%d (경험치양 %d)",map_list.dungeon_enter[MISTY_LAKE].floor+1, you.level,exp_-prevexp_); printlog(temp,true,false,false,CL_normal); prevexp_ = exp_; for(int i = MISTY_LAKE_LEVEL; i <= MISTY_LAKE_LAST_LEVEL; i++) { env[i].MakeMap(true); for(vector<monster>::iterator it = env[i].mon_vector.begin(); it != env[i].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } } exp_ = you.exper; sprintf_s(temp,200,"안개호수클리어 레벨:%d (경험치양 %d)", you.level,exp_-prevexp_); printlog(temp,true,false,false,CL_normal); prevexp_ = exp_; for(int i = map_list.dungeon_enter[MISTY_LAKE].floor+1; i <= MAX_DUNGEUN_LEVEL; i++) { env[i].MakeMap(true); for(vector<monster>::iterator it = env[i].mon_vector.begin(); it != env[i].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } } exp_ = you.exper; sprintf_s(temp,200,"남은던전 클리어 레벨:%d (경험치양 %d)", you.level,exp_-prevexp_); printlog(temp,true,false,false,CL_normal); prevexp_ = exp_; for(int i = YOUKAI_MOUNTAIN_LEVEL; i <= YOUKAI_MOUNTAIN_LAST_LEVEL; i++) { env[i].MakeMap(true); for(vector<monster>::iterator it = env[i].mon_vector.begin(); it != env[i].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } } exp_ = you.exper; sprintf_s(temp,200,"요괴의산 클리어 레벨:%d (경험치양 %d)", you.level,exp_-prevexp_); printlog(temp,true,false,false,CL_normal); prevexp_ = exp_; for(int i = SCARLET_LEVEL; i <= SCARLET_LEVEL_LAST_LEVEL; i++) { env[i].MakeMap(true); for(vector<monster>::iterator it = env[i].mon_vector.begin(); it != env[i].mon_vector.end(); it++) { if(it->isLive()) it->dead(PRT_PLAYER,false); } } exp_ = you.exper; sprintf_s(temp,200,"홍마관 클리어 레벨:%d (경험치양 %d)", you.level,exp_-prevexp_); printlog(temp,true,false,false,CL_normal); prevexp_ = exp_; } break; case 'B': god_punish(you.god); break; case '?'://도움말 WaitForSingleObject(mutx, INFINITE); deletesub(); printsub(" --- 위자드모드 커맨드 목록 ---",true,CL_normal); printsub("",true,CL_normal); printsub(" X - 1레벨업 ",true,CL_normal); printsub(" H - 체력 영력 파워 회복 ",true,CL_normal); printsub(" G - 장소이동 ",true,CL_normal); printsub(" p - 제단 생성 ",true,CL_normal); printsub(" ^ - 신앙심 10증가 ",true,CL_normal); printsub(" > - 아랫층으로 내려가기 ",true,CL_normal); printsub(" < - 윗층으로 올라가기 ",true,CL_normal); printsub(" A - 아이템생성(베타) ",true,CL_normal); printsub(" W - 시간정지 ",true,CL_normal); printsub(" D - 매직맵핑 ",true,CL_normal); printsub(" b - 블링크 ",true,CL_normal); printsub(" ",true,CL_normal); printsub(" 이외의 커맨드는 불안정하니 비추천 ",true,CL_normal); changedisplay(DT_SUB_TEXT); ReleaseMutex(mutx); continue; default: printlog("없는 명령어",true,false,false,CL_help); break; } return; } }
int fb64_is(unsigned char *data, int cnt, struct fb *fbp) { unsigned char *p; int state = fbp->state[DIR_DECRYPT-1]; if (cnt-- < 1) goto failure; switch (*data++) { case FB64_IV: if (cnt != sizeof(Block)) { if (encrypt_debug_mode) printf("CFB64: initial vector failed on size\r\n"); state = FAILED; goto failure; } if (encrypt_debug_mode) printf("CFB64: initial vector received\r\n"); if (encrypt_debug_mode) printf("Initializing Decrypt stream\r\n"); fb64_stream_iv((void *)data, &fbp->streams[DIR_DECRYPT-1]); p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_OK; *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); net_write(fbp->fb_feed, p - fbp->fb_feed); state = fbp->state[DIR_DECRYPT-1] = IN_PROGRESS; break; default: if (encrypt_debug_mode) { printf("Unknown option type: %d\r\n", *(data-1)); printd(data, cnt); printf("\r\n"); } /* FALL THROUGH */ failure: /* * We failed. Send an FB64_IV_BAD option * to the other side so it will know that * things failed. */ p = fbp->fb_feed + 3; *p++ = ENCRYPT_REPLY; p++; *p++ = FB64_IV_BAD; *p++ = IAC; *p++ = SE; printsub('>', &fbp->fb_feed[2], p - &fbp->fb_feed[2]); net_write(fbp->fb_feed, p - fbp->fb_feed); break; } return(fbp->state[DIR_DECRYPT-1] = state); }
static void suboption(void) { 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; name = gettermname(); len = strlen(name) + 4 + 2; if (len < NETROOM()) { snprintf((char *)temp, sizeof(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); } 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); snprintf((char *)temp, sizeof(temp), "%c%c%c%c%ld,%ld%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; 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("DISPLAY", 0)) == NULL) { /* * Something happened, we no longer have a DISPLAY * variable. So, turn off the option. */ send_wont(TELOPT_XDISPLOC, 1); break; } snprintf((char *)temp, sizeof(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; default: break; } }
/* * This is called when an AUTH SEND is received. * It should never arrive on the server side (as only the server can * send an AUTH SEND). * You should probably respond to it if you can... * * If you want to respond to the types out of order (i.e. even * if he sends LOGIN KERBEROS and you support both, you respond * with KERBEROS instead of LOGIN (which is against what the * protocol says)) you will have to hack this code... */ void auth_send (unsigned char *data, int cnt) { TN_Authenticator *ap; static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, AUTHTYPE_NULL, 0, IAC, SE }; if (Server) { if (auth_debug_mode) { printf (">>>%s: auth_send called!\r\n", Name); } return; } if (auth_debug_mode) { printf (">>>%s: auth_send got:", Name); printd (data, cnt); printf ("\r\n"); } /* * Save the data, if it is new, so that we can continue looking * at it if the authorization we try doesn't work */ if (data < _auth_send_data || data > _auth_send_data + sizeof (_auth_send_data)) { auth_send_cnt = cnt > sizeof (_auth_send_data) ? sizeof (_auth_send_data) : cnt; memmove ((void *) _auth_send_data, (void *) data, auth_send_cnt); auth_send_data = _auth_send_data; } else { /* * This is probably a no-op, but we just make sure */ auth_send_data = data; auth_send_cnt = cnt; } while ((auth_send_cnt -= 2) >= 0) { if (auth_debug_mode) printf (">>>%s: He supports %s (%d) %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (auth_send_data[0]) ? AUTHTYPE_NAME (auth_send_data[0]) : "unknown", auth_send_data[0], auth_send_data[1] & AUTH_HOW_MASK & AUTH_HOW_MUTUAL ? "MUTUAL" : "ONEWAY", auth_send_data[1]); if ((i_support & ~i_wont_support) & typemask (*auth_send_data)) { ap = findauthenticator (auth_send_data[0], auth_send_data[1]); if (ap && ap->send) { if (auth_debug_mode) printf (">>>%s: Trying %s (%d) %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (auth_send_data[0]) ? AUTHTYPE_NAME (auth_send_data[0]) : "unknown", auth_send_data[0], auth_send_data[1] & AUTH_HOW_MASK & AUTH_HOW_MUTUAL ? "MUTUAL" : "ONEWAY", auth_send_data[1]); if ((*ap->send) (ap)) { /* * Okay, we found one we like * and did it. * we can go home now. */ if (auth_debug_mode) printf (">>>%s: Using type %s (%d)\r\n", Name, AUTHTYPE_NAME_OK (*auth_send_data) ? AUTHTYPE_NAME (*auth_send_data) : "unknown", *auth_send_data); auth_send_data += 2; return; } } /* else * just continue on and look for the * next one if we didn't do anything. */ } auth_send_data += 2; } net_write (str_none, sizeof (str_none)); printsub ('>', &str_none[2], sizeof (str_none) - 2); if (auth_debug_mode) printf (">>>%s: Sent failure message\r\n", Name); auth_finished (0, AUTH_REJECT); # ifdef KANNAN /* * We requested strong authentication, however no mechanisms worked. * Therefore, exit on client end. */ printf ("Unable to securely authenticate user ... exit\n"); exit (EXIT_SUCCESS); # endif /* KANNAN */ }
static void suboption(struct connectdata *conn) { struct curl_slist *v; unsigned char temp[2048]; ssize_t bytes_written; size_t len; size_t tmplen; int err; char varname[128] = ""; char varval[128] = ""; struct Curl_easy *data = conn->data; struct TELNET *tn = (struct TELNET *)data->req.protop; printsub(data, '<', (unsigned char *)tn->subbuffer, CURL_SB_LEN(tn)+2); switch(CURL_SB_GET(tn)) { case CURL_TELOPT_TTYPE: len = strlen(tn->subopt_ttype) + 4 + 2; snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_TTYPE, CURL_TELQUAL_IS, tn->subopt_ttype, CURL_IAC, CURL_SE); bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); if(bytes_written < 0) { err = SOCKERRNO; failf(data,"Sending data failed (%d)",err); } printsub(data, '>', &temp[2], len-2); break; case CURL_TELOPT_XDISPLOC: len = strlen(tn->subopt_xdisploc) + 4 + 2; snprintf((char *)temp, sizeof(temp), "%c%c%c%c%s%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_XDISPLOC, CURL_TELQUAL_IS, tn->subopt_xdisploc, CURL_IAC, CURL_SE); bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); if(bytes_written < 0) { err = SOCKERRNO; failf(data,"Sending data failed (%d)",err); } printsub(data, '>', &temp[2], len-2); break; case CURL_TELOPT_NEW_ENVIRON: snprintf((char *)temp, sizeof(temp), "%c%c%c%c", CURL_IAC, CURL_SB, CURL_TELOPT_NEW_ENVIRON, CURL_TELQUAL_IS); len = 4; for(v = tn->telnet_vars;v;v = v->next) { tmplen = (strlen(v->data) + 1); /* Add the variable only if it fits */ if(len + tmplen < (int)sizeof(temp)-6) { if(sscanf(v->data, "%127[^,],%127s", varname, varval)) { snprintf((char *)&temp[len], sizeof(temp) - len, "%c%s%c%s", CURL_NEW_ENV_VAR, varname, CURL_NEW_ENV_VALUE, varval); len += tmplen; } } } snprintf((char *)&temp[len], sizeof(temp) - len, "%c%c", CURL_IAC, CURL_SE); len += 2; bytes_written = swrite(conn->sock[FIRSTSOCKET], temp, len); if(bytes_written < 0) { err = SOCKERRNO; failf(data,"Sending data failed (%d)",err); } printsub(data, '>', &temp[2], len-2); break; } return; }
/* * This is called when an AUTH SEND is received. * It should never arrive on the server side (as only the server can * send an AUTH SEND). * You should probably respond to it if you can... * * If you want to respond to the types out of order (i.e. even * if he sends LOGIN KERBEROS and you support both, you respond * with KERBEROS instead of LOGIN (which is against what the * protocol says)) you will have to hack this code... */ void auth_send(unsigned char *data, int cnt) { Authenticator *ap; static unsigned char str_none[] = { IAC, SB, TELOPT_AUTHENTICATION, TELQUAL_IS, AUTHTYPE_NULL, 0, IAC, SE }; if (Server) { if (auth_debug_mode) { printf(">>>%s: auth_send called!\r\n", Name); } return; } if (auth_debug_mode) { printf(">>>%s: auth_send got:", Name); printd(data, cnt); printf("\r\n"); } /* * Save the data, if it is new, so that we can continue looking * at it if the authorization we try doesn't work */ if (data < _auth_send_data || data > _auth_send_data + sizeof(_auth_send_data)) { auth_send_cnt = (size_t)cnt > sizeof(_auth_send_data) ? sizeof(_auth_send_data) : cnt; memmove((void *)_auth_send_data, (void *)data, auth_send_cnt); auth_send_data = _auth_send_data; } else { /* * This is probably a no-op, but we just make sure */ auth_send_data = data; auth_send_cnt = cnt; } while ((auth_send_cnt -= 2) >= 0) { if (auth_debug_mode) printf(">>>%s: He supports %d\r\n", Name, *auth_send_data); if ((i_support & ~i_wont_support) & typemask(*auth_send_data)) { ap = findauthenticator(auth_send_data[0], auth_send_data[1]); if (ap && ap->send) { if (auth_debug_mode) printf(">>>%s: Trying %d %d\r\n", Name, auth_send_data[0], auth_send_data[1]); if ((*ap->send)(ap)) { /* * Okay, we found one we like * and did it. * we can go home now. */ if (auth_debug_mode) printf(">>>%s: Using type %d\r\n", Name, *auth_send_data); auth_send_data += 2; return; } } /* else * just continue on and look for the * next one if we didn't do anything. */ } auth_send_data += 2; } net_write(str_none, sizeof(str_none)); printsub('>', &str_none[2], sizeof(str_none) - 2); if (auth_debug_mode) printf(">>>%s: Sent failure message\r\n", Name); auth_finished(0, AUTH_REJECT); }
/* int length; length of suboption data */ void printsub (char direction, unsigned char *pointer, int length) { register int i; extern int want_status_response; #if defined AUTHENTICATION || defined ENCRYPTION char buf[512]; #endif if (showoptions || direction == 0 || (want_status_response && (pointer[0] == TELOPT_STATUS))) { if (direction) { fprintf (NetTrace, "%s IAC SB ", (direction == '<') ? "RCVD" : "SENT"); if (length >= 3) { register int j; i = pointer[length - 2]; j = pointer[length - 1]; if (i != IAC || j != SE) { fprintf (NetTrace, "(terminated by "); if (TELOPT_OK (i)) fprintf (NetTrace, "%s ", TELOPT (i)); else if (TELCMD_OK (i)) fprintf (NetTrace, "%s ", TELCMD (i)); else fprintf (NetTrace, "%d ", i); if (TELOPT_OK (j)) fprintf (NetTrace, "%s", TELOPT (j)); else if (TELCMD_OK (j)) fprintf (NetTrace, "%s", TELCMD (j)); else fprintf (NetTrace, "%d", j); fprintf (NetTrace, ", not IAC SE!) "); } } length -= 2; } if (length < 1) { fprintf (NetTrace, "(Empty suboption??\?)"); if (NetTrace == stdout) fflush (NetTrace); return; } switch (pointer[0]) { case TELOPT_TTYPE: fprintf (NetTrace, "TERMINAL-TYPE "); switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS \"%.*s\"", length - 2, (char *) pointer + 2); break; case TELQUAL_SEND: fprintf (NetTrace, "SEND"); break; default: fprintf (NetTrace, "- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_TSPEED: fprintf (NetTrace, "TERMINAL-SPEED"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, " IS "); fprintf (NetTrace, "%.*s", length - 2, (char *) pointer + 2); break; default: if (pointer[1] == 1) fprintf (NetTrace, " SEND"); else fprintf (NetTrace, " %d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; } break; case TELOPT_LFLOW: fprintf (NetTrace, "TOGGLE-FLOW-CONTROL"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case LFLOW_OFF: fprintf (NetTrace, " OFF"); break; case LFLOW_ON: fprintf (NetTrace, " ON"); break; case LFLOW_RESTART_ANY: fprintf (NetTrace, " RESTART-ANY"); break; case LFLOW_RESTART_XON: fprintf (NetTrace, " RESTART-XON"); break; default: fprintf (NetTrace, " %d (unknown)", pointer[1]); } for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case TELOPT_NAWS: fprintf (NetTrace, "NAWS"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } if (length == 2) { fprintf (NetTrace, " ?%d?", pointer[1]); break; } fprintf (NetTrace, " %d %d (%d)", pointer[1], pointer[2], (int) ((((unsigned int) pointer[1]) << 8) | ((unsigned int) pointer[2]))); if (length == 4) { fprintf (NetTrace, " ?%d?", pointer[3]); break; } fprintf (NetTrace, " %d %d (%d)", pointer[3], pointer[4], (int) ((((unsigned int) pointer[3]) << 8) | ((unsigned int) pointer[4]))); for (i = 5; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; #if defined AUTHENTICATION case TELOPT_AUTHENTICATION: fprintf (NetTrace, "AUTHENTICATION"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case TELQUAL_REPLY: case TELQUAL_IS: fprintf (NetTrace, " %s ", (pointer[1] == TELQUAL_IS) ? "IS" : "REPLY"); if (AUTHTYPE_NAME_OK (pointer[2]) && AUTHTYPE_NAME (pointer[2])) fprintf (NetTrace, "%s ", AUTHTYPE_NAME (pointer[2])); else fprintf (NetTrace, "%d ", pointer[2]); if (length < 3) { fprintf (NetTrace, "(partial suboption??\?)"); break; } fprintf (NetTrace, "%s|%s", ((pointer[3] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[3] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); auth_printsub (&pointer[1], length - 1, buf, sizeof (buf)); fprintf (NetTrace, "%s", buf); break; case TELQUAL_SEND: i = 2; fprintf (NetTrace, " SEND "); while (i < length) { if (AUTHTYPE_NAME_OK (pointer[i]) && AUTHTYPE_NAME (pointer[i])) fprintf (NetTrace, "%s ", AUTHTYPE_NAME (pointer[i])); else fprintf (NetTrace, "%d ", pointer[i]); if (++i >= length) { fprintf (NetTrace, "(partial suboption??\?)"); break; } fprintf (NetTrace, "%s|%s ", ((pointer[i] & AUTH_WHO_MASK) == AUTH_WHO_CLIENT) ? "CLIENT" : "SERVER", ((pointer[i] & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ? "MUTUAL" : "ONE-WAY"); ++i; } break; case TELQUAL_NAME: i = 2; fprintf (NetTrace, " NAME \""); while (i < length) putc (pointer[i++], NetTrace); putc ('"', NetTrace); break; default: for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; } break; #endif #ifdef ENCRYPTION case TELOPT_ENCRYPT: fprintf (NetTrace, "ENCRYPT"); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case ENCRYPT_START: fprintf (NetTrace, " START"); break; case ENCRYPT_END: fprintf (NetTrace, " END"); break; case ENCRYPT_REQSTART: fprintf (NetTrace, " REQUEST-START"); break; case ENCRYPT_REQEND: fprintf (NetTrace, " REQUEST-END"); break; case ENCRYPT_IS: case ENCRYPT_REPLY: fprintf (NetTrace, " %s ", (pointer[1] == ENCRYPT_IS) ? "IS" : "REPLY"); if (length < 3) { fprintf (NetTrace, " (partial suboption??\?)"); break; } if (ENCTYPE_NAME_OK (pointer[2]) && ENCTYPE_NAME (pointer[2])) fprintf (NetTrace, "%s ", ENCTYPE_NAME (pointer[2])); else fprintf (NetTrace, " %d (unknown)", pointer[2]); encrypt_printsub (&pointer[1], length - 1, buf, sizeof (buf)); fprintf (NetTrace, "%s", buf); break; case ENCRYPT_SUPPORT: i = 2; fprintf (NetTrace, " SUPPORT "); while (i < length) { if (ENCTYPE_NAME_OK (pointer[i]) && ENCTYPE_NAME (pointer[i])) fprintf (NetTrace, "%s ", ENCTYPE_NAME (pointer[i])); else fprintf (NetTrace, "%d ", pointer[i]); i++; } break; case ENCRYPT_ENC_KEYID: fprintf (NetTrace, " ENC_KEYID "); goto encommon; case ENCRYPT_DEC_KEYID: fprintf (NetTrace, " DEC_KEYID "); goto encommon; default: fprintf (NetTrace, " %d (unknown)", pointer[1]); encommon: for (i = 2; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } break; #endif /* ENCRYPTION */ case TELOPT_LINEMODE: fprintf (NetTrace, "LINEMODE "); if (length < 2) { fprintf (NetTrace, " (empty suboption??\?)"); break; } switch (pointer[1]) { case WILL: fprintf (NetTrace, "WILL "); goto common; case WONT: fprintf (NetTrace, "WONT "); goto common; case DO: fprintf (NetTrace, "DO "); goto common; case DONT: fprintf (NetTrace, "DONT "); common: if (length < 3) { fprintf (NetTrace, "(no option??\?)"); break; } switch (pointer[2]) { case LM_FORWARDMASK: fprintf (NetTrace, "Forward Mask"); for (i = 3; i < length; i++) fprintf (NetTrace, " %x", pointer[i]); break; default: fprintf (NetTrace, "%d (unknown)", pointer[2]); for (i = 3; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } break; case LM_SLC: fprintf (NetTrace, "SLC"); for (i = 2; i < length - 2; i += 3) { if (SLC_NAME_OK (pointer[i + SLC_FUNC])) fprintf (NetTrace, " %s", SLC_NAME (pointer[i + SLC_FUNC])); else fprintf (NetTrace, " %d", pointer[i + SLC_FUNC]); switch (pointer[i + SLC_FLAGS] & SLC_LEVELBITS) { case SLC_NOSUPPORT: fprintf (NetTrace, " NOSUPPORT"); break; case SLC_CANTCHANGE: fprintf (NetTrace, " CANTCHANGE"); break; case SLC_VARIABLE: fprintf (NetTrace, " VARIABLE"); break; case SLC_DEFAULT: fprintf (NetTrace, " DEFAULT"); break; } fprintf (NetTrace, "%s%s%s", (pointer[i + SLC_FLAGS] & SLC_ACK) ? "|ACK" : "", (pointer[i + SLC_FLAGS] & SLC_FLUSHIN) ? "|FLUSHIN" : "", (pointer[i + SLC_FLAGS] & SLC_FLUSHOUT) ? "|FLUSHOUT" : ""); if (pointer[i + SLC_FLAGS] & ~(SLC_ACK | SLC_FLUSHIN | SLC_FLUSHOUT | SLC_LEVELBITS)) fprintf (NetTrace, "(0x%x)", pointer[i + SLC_FLAGS]); fprintf (NetTrace, " %d;", pointer[i + SLC_VALUE]); if ((pointer[i + SLC_VALUE] == IAC) && (pointer[i + SLC_VALUE + 1] == IAC)) i++; } for (; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case LM_MODE: fprintf (NetTrace, "MODE "); if (length < 3) { fprintf (NetTrace, "(no mode??\?)"); break; } { char tbuf[64]; sprintf (tbuf, "%s%s%s%s%s", pointer[2] & MODE_EDIT ? "|EDIT" : "", pointer[2] & MODE_TRAPSIG ? "|TRAPSIG" : "", pointer[2] & MODE_SOFT_TAB ? "|SOFT_TAB" : "", pointer[2] & MODE_LIT_ECHO ? "|LIT_ECHO" : "", pointer[2] & MODE_ACK ? "|ACK" : ""); fprintf (NetTrace, "%s", tbuf[1] ? &tbuf[1] : "0"); } if (pointer[2] & ~(MODE_MASK)) fprintf (NetTrace, " (0x%x)", pointer[2]); for (i = 3; i < length; i++) fprintf (NetTrace, " ?0x%x?", pointer[i]); break; default: fprintf (NetTrace, "%d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); } break; case TELOPT_STATUS: { register char *cp; register int j, k; fprintf (NetTrace, "STATUS"); switch (pointer[1]) { default: if (pointer[1] == TELQUAL_SEND) fprintf (NetTrace, " SEND"); else fprintf (NetTrace, " %d (unknown)", pointer[1]); for (i = 2; i < length; i++) fprintf (NetTrace, " ?%d?", pointer[i]); break; case TELQUAL_IS: if (--want_status_response < 0) want_status_response = 0; if (NetTrace == stdout) fprintf (NetTrace, " IS\r\n"); else fprintf (NetTrace, " IS\n"); for (i = 2; i < length; i++) { switch (pointer[i]) { case DO: cp = "DO"; goto common2; case DONT: cp = "DONT"; goto common2; case WILL: cp = "WILL"; goto common2; case WONT: cp = "WONT"; goto common2; common2: i++; if (TELOPT_OK ((int) pointer[i])) fprintf (NetTrace, " %s %s", cp, TELOPT (pointer[i])); else fprintf (NetTrace, " %s %d", cp, pointer[i]); if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); break; case SB: fprintf (NetTrace, " SB "); i++; j = k = i; while (j < length) { if (pointer[j] == SE) { if (j + 1 == length) break; if (pointer[j + 1] == SE) j++; else break; } pointer[k++] = pointer[j++]; } printsub (0, &pointer[i], k - i); if (i < length) { fprintf (NetTrace, " SE"); i = j; } else i = j - 1; if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); break; default: fprintf (NetTrace, " %d", pointer[i]); break; } } break; } break; } case TELOPT_XDISPLOC: fprintf (NetTrace, "X-DISPLAY-LOCATION "); switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS \"%.*s\"", length - 2, (char *) pointer + 2); break; case TELQUAL_SEND: fprintf (NetTrace, "SEND"); break; default: fprintf (NetTrace, "- unknown qualifier %d (0x%x).", pointer[1], pointer[1]); } break; case TELOPT_NEW_ENVIRON: fprintf (NetTrace, "NEW-ENVIRON "); #ifdef OLD_ENVIRON goto env_common1; case TELOPT_OLD_ENVIRON: fprintf (NetTrace, "OLD-ENVIRON"); env_common1: #endif switch (pointer[1]) { case TELQUAL_IS: fprintf (NetTrace, "IS "); goto env_common; case TELQUAL_SEND: fprintf (NetTrace, "SEND "); goto env_common; case TELQUAL_INFO: fprintf (NetTrace, "INFO "); env_common: { const char *quote = ""; #if defined ENV_HACK && defined OLD_ENVIRON extern int old_env_var, old_env_value; #endif for (i = 2; i < length; i++) { switch (pointer[i]) { case NEW_ENV_VALUE: #ifdef OLD_ENVIRON /* case NEW_ENV_OVAR: */ if (pointer[0] == TELOPT_OLD_ENVIRON) { # ifdef ENV_HACK if (old_env_var == OLD_ENV_VALUE) fprintf (NetTrace, "%s(VALUE) ", quote); else # endif fprintf (NetTrace, "%sVAR ", quote); } else #endif /* OLD_ENVIRON */ fprintf (NetTrace, "%sVALUE ", quote); quote = ""; break; case NEW_ENV_VAR: #ifdef OLD_ENVIRON /* case OLD_ENV_VALUE: */ if (pointer[0] == TELOPT_OLD_ENVIRON) { # ifdef ENV_HACK if (old_env_value == OLD_ENV_VAR) fprintf (NetTrace, "%s(VAR) ", quote); else # endif fprintf (NetTrace, "%sVALUE ", quote); } else #endif /* OLD_ENVIRON */ fprintf (NetTrace, "%sVAR ", quote); quote = ""; break; case ENV_ESC: fprintf (NetTrace, "%sESC ", quote); quote = ""; break; case ENV_USERVAR: fprintf (NetTrace, "%sUSERVAR ", quote); quote = ""; break; default: if (isprint (pointer[i]) && pointer[i] != '"') { if (quote[0] == '\0') { putc ('"', NetTrace); quote = "\" "; } putc (pointer[i], NetTrace); } else { fprintf (NetTrace, "%s%03o ", quote, pointer[i]); quote = ""; } break; } } if (quote[0] != '\0') putc ('"', NetTrace); break; } } break; default: if (TELOPT_OK (pointer[0])) fprintf (NetTrace, "%s (unknown)", TELOPT (pointer[0])); else fprintf (NetTrace, "%d (unknown)", pointer[0]); for (i = 1; i < length; i++) fprintf (NetTrace, " %d", pointer[i]); break; } if (direction) { if (NetTrace == stdout) fprintf (NetTrace, "\r\n"); else fprintf (NetTrace, "\n"); } if (NetTrace == stdout) fflush (NetTrace); } }
/* * suboption() * * Look at the sub-option buffer, and try to be helpful to the other * side. * * Currently we recognize: * * Terminal type is * Linemode * Window size * Terminal speed */ void suboption(void) { int subchar; DIAG(TD_OPTIONS, {netflush(); printsub('<', subpointer, SB_LEN()+2);});