void echo_command(struct session *ses, char *line) { char buffer[STRING_SIZE], result[STRING_SIZE]; if (HAS_BIT(ses->flags, SES_FLAG_SPLIT)) { sprintf(buffer, "%s%s\033[0m", ses->cmd_color, line); } else { sprintf(buffer, "%s", line); } /* Deal with pending output */ if (ses->more_output[0]) { if (ses->check_output) { strcpy(result, ses->more_output); ses->more_output[0] = 0; process_mud_output(ses, result, FALSE); } } DEL_BIT(ses->telopts, TELOPT_FLAG_PROMPT); if (HAS_BIT(ses->flags, SES_FLAG_SPLIT)) { if (!HAS_BIT(ses->flags, SES_FLAG_ECHOCOMMAND)) { sprintf(result, "\033[0;37m"); } else { sprintf(result, "%s%s", ses->more_output, buffer); } add_line_buffer(ses, buffer, -1); SET_BIT(ses->flags, SES_FLAG_SCROLLSTOP); tintin_printf2(ses, "%s", result); DEL_BIT(ses->flags, SES_FLAG_SCROLLSTOP); } else { add_line_buffer(ses, buffer, -1); } }
void init_terminal() { struct termios io; if (tcgetattr(0, >d->old_terminal)) { perror("tcgetattr"); exit(errno); } io = gtd->old_terminal; /* Canonical mode off */ DEL_BIT(io.c_lflag, ICANON); io.c_cc[VMIN] = 1; io.c_cc[VTIME] = 0; io.c_cc[VSTART] = 255; io.c_cc[VSTOP] = 255; /* Make the terminalal as raw as possible */ /* DEL_BIT(io.c_iflag, IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); DEL_BIT(io.c_oflag, OPOST); DEL_BIT(io.c_cflag, CSIZE|PARENB); */ DEL_BIT(io.c_lflag, ECHO|ECHONL|IEXTEN|ISIG); SET_BIT(io.c_cflag, CS8); if (tcsetattr(0, TCSANOW, &io)) { perror("tcsetattr"); exit(errno); } if (tcgetattr(0, >d->new_terminal)) { perror("tcgetattr"); exit(errno); } }
void echo_off(struct session *ses) { struct termios io; tcgetattr(STDIN_FILENO, &io); DEL_BIT(io.c_lflag, ECHO|ECHONL); tcsetattr(STDIN_FILENO, TCSADRAIN, &io); }
void process_input(void) { if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_SGA) && !HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { read_key(); } else { read_line(); } if (!HAS_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT)) { return; } DEL_BIT(gtd->flags, TINTIN_FLAG_PROCESSINPUT); if (gtd->chat && gtd->chat->paste_time) { chat_paste(gtd->input_buf, NULL); return; } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { add_line_history(gtd->ses, gtd->input_buf); } if (HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_ECHO)) { echo_command(gtd->ses, gtd->input_buf); } else { echo_command(gtd->ses, ""); } if (gtd->ses->scroll_line != -1) { buffer_end(gtd->ses, ""); } check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED INPUT", gtd->input_buf); gtd->ses = script_driver(gtd->ses, LIST_COMMAND, gtd->input_buf); if (IS_SPLIT(gtd->ses)) { erase_toeol(); } gtd->input_buf[0] = 0; }
void modified_input(void) { kill_list(gtd->ses->list[LIST_TABCYCLE]); if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { cursor_history_find(""); } if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE)) { DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); } }
void cleanup_session(struct session *ses) { push_call("cleanup_session(%p)",ses); if (ses == gtd->update) { gtd->update = ses->next; } UNLINK(ses, gts->next, gts->prev); if (ses->socket) { if (close(ses->socket) == -1) { syserr("close in cleanup"); } if (HAS_BIT(ses->flags, SES_FLAG_RUN)) { kill(ses->pid, SIGKILL); } DEL_BIT(ses->flags, SES_FLAG_CONNECTED); } check_all_events(ses, SUB_ARG|SUB_SEC, 0, 3, "SESSION DISCONNECTED", ses->name, ses->command, ntos(ses->pid)); display_printf(gtd->ses, "#SESSION '%s' DIED.", ses->name); if (ses == gtd->ses) { gtd->ses = newactive_session(); } if (ses->logfile) { fclose(ses->logfile); } if (ses->logline) { fclose(ses->logline); } LINK(ses, gtd->dispose_next, gtd->dispose_prev); pop_call(); return; }
void process_mud_output(struct session *ses, char *linebuf, int prompt) { char line[STRING_SIZE]; ses->check_output = 0; strip_vt102_codes(linebuf, line); check_all_events(ses, SUB_ARG | SUB_SEC, 0, 2, "RECEIVED LINE", linebuf, line); if (prompt) { check_all_events(ses, SUB_ARG | SUB_SEC, 0, 2, "RECEIVED PROMPT", linebuf, line); } if (HAS_BIT(ses->flags, SES_FLAG_COLORPATCH)) { sprintf(line, "%s%s", ses->color, linebuf); get_color_codes(ses->color, linebuf, ses->color); linebuf = line; } do_one_line(linebuf, ses); /* changes linebuf */ /* Take care of gags, vt102 support still goes */ if (HAS_BIT(ses->flags, SES_FLAG_GAG)) { strip_non_vt102_codes(linebuf, ses->more_output); printf("%s", ses->more_output); ses->more_output[0] = 0; DEL_BIT(ses->flags, SES_FLAG_GAG); return; } add_line_buffer(ses, linebuf, prompt); if (ses == gtd->ses) { printline(ses, linebuf, prompt); } else if (HAS_BIT(ses->flags, SES_FLAG_SNOOP)) { strip_vt102_codes_non_graph(linebuf, linebuf); tintin_printf2(gtd->ses, "[%s] %s", ses->name, linebuf); } }
void do_one_line(char *line, struct session *ses) { char strip[BUFFER_SIZE]; push_call("[%s] do_one_line(%s)",ses->name,line); if (gtd->ignore_level) { pop_call(); return; } strip_vt102_codes(line, strip); if (!HAS_BIT(ses->list[LIST_ACTION]->flags, LIST_FLAG_IGNORE)) { check_all_actions(ses, line, strip); } if (!HAS_BIT(ses->list[LIST_PROMPT]->flags, LIST_FLAG_IGNORE)) { check_all_prompts(ses, line, strip); } if (!HAS_BIT(ses->list[LIST_GAG]->flags, LIST_FLAG_IGNORE)) { check_all_gags(ses, line, strip); } if (!HAS_BIT(ses->list[LIST_SUBSTITUTE]->flags, LIST_FLAG_IGNORE)) { check_all_substitutions(ses, line, strip); } if (!HAS_BIT(ses->list[LIST_HIGHLIGHT]->flags, LIST_FLAG_IGNORE)) { check_all_highlights(ses, line, strip); } if (HAS_BIT(ses->flags, SES_FLAG_LOGNEXT)) { logit(ses, line, ses->lognext_file, TRUE); DEL_BIT(ses->flags, SES_FLAG_LOGNEXT); } pop_call(); return; }
int show_buffer(struct session *ses) { char temp[STRING_SIZE]; int scroll_size, scroll_cnt, scroll_tmp, scroll_add, scroll_cut; if (ses != gtd->ses) { return TRUE; } scroll_size = get_scroll_size(ses); scroll_add = 0 - ses->scroll_base; scroll_tmp = 0; scroll_cnt = ses->scroll_line; scroll_cut = 0; /* Find the upper limit of the buffer shown */ while (TRUE) { if (ses->buffer[scroll_cnt] == NULL) { break; } scroll_tmp = str_hash_lines(ses->buffer[scroll_cnt]); if (scroll_add + scroll_tmp > scroll_size) { if (scroll_add == scroll_size) { scroll_cut = 0; } else { scroll_cut = scroll_tmp - (scroll_size - scroll_add); } break; } scroll_add += scroll_tmp; if (scroll_cnt == ses->scroll_max - 1) { scroll_cnt = 0; } else { scroll_cnt++; } } if (ses->buffer[scroll_cnt] == NULL) { erase_screen(ses); } if (IS_SPLIT(ses)) { save_pos(ses); goto_rowcol(ses, ses->bot_row, 1); SET_BIT(ses->flags, SES_FLAG_READMUD); } /* If the top line exists of multiple lines split it in the middle. */ if (ses->buffer[scroll_cnt] && scroll_cut) { if (scroll_add >= 0) { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, scroll_tmp - scroll_cut, scroll_cut); printf("%s\n", temp); } else { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, ses->scroll_base, scroll_size); goto eof; } } /* Print away */ while (TRUE) { if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max - 1; } else { scroll_cnt--; } if (ses->buffer[scroll_cnt] == NULL) { break; } scroll_tmp = word_wrap(ses, ses->buffer[scroll_cnt], temp, FALSE); if (scroll_add - scroll_tmp < 0) { scroll_cut = scroll_add; break; } scroll_add -= scroll_tmp; printf("%s\n", temp); } /* If the bottom line exists of multiple lines split it in the middle */ if (scroll_tmp && ses->buffer[scroll_cnt]) { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, 0, scroll_cut); } eof: if (IS_SPLIT(ses)) { restore_pos(ses); DEL_BIT(ses->flags, SES_FLAG_READMUD); } return TRUE; }
void read_line() { char buffer[STRING_SIZE]; struct listnode *node; struct listroot *root; int len, cnt, match; gtd->input_buf[gtd->input_len] = 0; len = read(0, buffer, 1); buffer[len] = 0; if (HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA) || HAS_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR)) { convert_meta(buffer, >d->macro_buf[strlen(gtd->macro_buf)]); } else { strcat(gtd->macro_buf, buffer); } if (!HAS_BIT(gtd->ses->flags, SES_FLAG_CONVERTMETA)) { match = 0; root = gtd->ses->list[LIST_MACRO]; for (root->update = 0; root->update < root->used; root->update++) { node = root->list[root->update]; if (!strcmp(gtd->macro_buf, node->pr)) { script_driver(gtd->ses, LIST_MACRO, node->right); gtd->macro_buf[0] = 0; return; } else if (!strncmp(gtd->macro_buf, node->pr, strlen(gtd->macro_buf))) { match = 1; } } for (cnt = 0; *cursor_table[cnt].fun != NULL; cnt++) { if (!strcmp(gtd->macro_buf, cursor_table[cnt].code)) { cursor_table[cnt].fun(""); gtd->macro_buf[0] = 0; return; } else if (!strncmp(gtd->macro_buf, cursor_table[cnt].code, strlen(gtd->macro_buf))) { match = 1; } } if (match) { return; } } if (gtd->macro_buf[0] == ESCAPE) { strcpy(buffer, gtd->macro_buf); convert_meta(buffer, gtd->macro_buf); } for (cnt = 0; gtd->macro_buf[cnt]; cnt++) { switch (gtd->macro_buf[cnt]) { case 10: cursor_enter(""); break; default: if (HAS_BIT(gtd->flags, TINTIN_FLAG_INSERTINPUT) && gtd->input_len != gtd->input_cur) { if (!HAS_BIT(gtd->ses->flags, SES_FLAG_UTF8) || (gtd->macro_buf[cnt] & 192) != 128) { cursor_delete(""); } } ins_sprintf(>d->input_buf[gtd->input_cur], "%c", gtd->macro_buf[cnt]); gtd->input_len++; gtd->input_cur++; if (!HAS_BIT(gtd->ses->flags, SES_FLAG_UTF8) || (gtd->macro_buf[cnt] & 192) != 128) { gtd->input_pos++; } if (gtd->input_len != gtd->input_cur) { if (HAS_BIT(gtd->ses->flags, SES_FLAG_UTF8) && (gtd->macro_buf[cnt] & 192) == 128) { input_printf("%c", gtd->macro_buf[cnt]); } else { input_printf("\033[1@%c", gtd->macro_buf[cnt]); } } else { input_printf("%c", gtd->macro_buf[cnt]); } gtd->macro_buf[0] = 0; gtd->input_tmp[0] = 0; gtd->input_buf[gtd->input_len] = 0; cursor_check_line_modified(""); DEL_BIT(gtd->flags, TINTIN_FLAG_HISTORYBROWSE); kill_list(gtd->ses->list[LIST_TABCYCLE]); if (HAS_BIT(gtd->flags, TINTIN_FLAG_HISTORYSEARCH)) { cursor_history_find(""); } break; } } }
void convert_meta(char *input, char *output) { char *pti, *pto; DEL_BIT(gtd->flags, TINTIN_FLAG_CONVERTMETACHAR); pti = input; pto = output; while (*pti) { switch (*pti) { case ESCAPE: *pto++ = '\\'; *pto++ = 'e'; pti++; break; case 127: *pto++ = '\\'; *pto++ = 'b'; pti++; break; case '\a': *pto++ = '\\'; *pto++ = 'a'; pti++; break; case '\b': *pto++ = '\\'; *pto++ = 'b'; pti++; break; case '\t': *pto++ = '\\'; *pto++ = 't'; pti++; break; case '\r': *pto++ = '\\'; *pto++ = 'r'; pti++; break; case '\n': *pto++ = *pti++; break; default: if (*pti > 0 && *pti < 32) { *pto++ = '\\'; *pto++ = 'c'; if (*pti <= 26) { *pto++ = 'a' + *pti - 1; } else { *pto++ = 'A' + *pti - 1; } pti++; break; } else { *pto++ = *pti++; } break; } } *pto = 0; }
struct session *new_session(struct session *ses, char *name, char *arg, int desc) { int cnt = 0; char host[BUFFER_SIZE], port[BUFFER_SIZE], file[BUFFER_SIZE]; struct session *newsession; push_call("new_session(%p,%p,%p,%d)",ses,name,arg,desc); if (HAS_BIT(gtd->flags, TINTIN_FLAG_TERMINATE)) { pop_call(); return ses; } arg = sub_arg_in_braces(ses, arg, host, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, port, GET_ONE, SUB_VAR|SUB_FUN); arg = sub_arg_in_braces(ses, arg, file, GET_ONE, SUB_VAR|SUB_FUN); if (desc == 0) { if (*host == 0) { tintin_puts(ses, "#HEY! SPECIFY AN ADDRESS WILL YOU?"); pop_call(); return ses; } if (*port == 0) { tintin_puts(ses, "#HEY! SPECIFY A PORT NUMBER WILL YOU?"); pop_call(); return ses; } } for (newsession = gts ; newsession ; newsession = newsession->next) { if (!strcmp(newsession->name, name)) { tintin_puts(ses, "THERE'S A SESSION WITH THAT NAME ALREADY."); pop_call(); return ses; } } newsession = (struct session *) calloc(1, sizeof(struct session)); newsession->name = strdup(name); newsession->host = strdup(host); newsession->ip = strdup(""); newsession->port = strdup(port); newsession->group = strdup(gts->group); newsession->flags = gts->flags; newsession->telopts = gts->telopts; newsession->auto_tab = gts->auto_tab; newsession->cmd_color = strdup(gts->cmd_color); newsession->read_max = gts->read_max; newsession->read_buf = (unsigned char *) calloc(1, gts->read_max); LINK(newsession, gts->next, gts->prev); for (cnt = 0 ; cnt < LIST_MAX ; cnt++) { newsession->list[cnt] = copy_list(newsession, gts->list[cnt], cnt); } newsession->rows = gts->rows; newsession->cols = gts->cols; newsession->top_row = gts->top_row; newsession->bot_row = gts->bot_row; init_buffer(newsession, gts->scroll_max); if (desc) { tintin_printf(ses, "#TRYING TO LAUNCH '%s' RUNNING '%s'.", newsession->name, newsession->host); } else { tintin_printf(ses, "#TRYING TO CONNECT '%s' TO '%s' PORT '%s'.", newsession->name, newsession->host, newsession->port); } gtd->ses = newsession; dirty_screen(newsession); if (desc == 0) { newsession = connect_session(newsession); } else { SET_BIT(newsession->flags, SES_FLAG_CONNECTED|SES_FLAG_RUN); SET_BIT(newsession->telopts, TELOPT_FLAG_SGA); DEL_BIT(newsession->telopts, TELOPT_FLAG_ECHO); gtd->ses = newsession; gtd->ses->socket = desc; } if (newsession) { if (*file) { do_read(newsession, file); } } pop_call(); return gtd->ses; }
int substitute(struct session *ses, char *string, char *result, int flags) { struct listnode *node; char temp[BUFFER_SIZE], buf[BUFFER_SIZE], buffer[BUFFER_SIZE], *pti, *pto, *ptt; char *pte, old[6] = { 0 }; int i, cnt, escape = FALSE, flags_neol = flags; push_call("substitute(%p,%p,%p,%d)", ses, string, result, flags); pti = string; pto = (string == result) ? buffer : result; DEL_BIT(flags_neol, SUB_EOL | SUB_LNF); while (TRUE) { if (HAS_BIT(ses->flags, SES_FLAG_BIG5) && *pti & 128 && pti[1] != 0) { *pto++ = *pti++; *pto++ = *pti++; continue; } switch (*pti) { case '\0': if (HAS_BIT(flags, SUB_EOL)) { if (HAS_BIT(ses->flags, SES_FLAG_RUN)) { *pto++ = '\r'; } else { *pto++ = '\r'; *pto++ = '\n'; } } if (HAS_BIT(flags, SUB_LNF)) { *pto++ = '\n'; } *pto = 0; pop_call(); if (string == result) { strcpy(result, buffer); return pto - buffer; } else { return pto - result; } break; case '$': if (HAS_BIT(flags, SUB_VAR) && (pti[1] == DEFAULT_OPEN || isalpha((int)pti[1]) || pti[1] == '$')) { int def = FALSE; if (pti[1] == '$') { while (pti[1] == '$') { *pto++ = *pti++; } if (pti[1] == DEFAULT_OPEN || isalnum((int)pti[1])) { pti++; } else { *pto++ = *pti++; } continue; } pti++; if (*pti == DEFAULT_OPEN) { def = TRUE; pti = get_arg_in_braces(ses, pti, buf, TRUE); substitute(ses, buf, temp, flags_neol); } else { ptt = temp; while (isalnum((int)*pti) || *pti == '_') { *ptt++ = *pti++; } *ptt = 0; } pti = get_arg_at_brackets(ses, pti, temp + strlen(temp)); substitute(ses, temp, buf, flags_neol); get_nest_node(ses->list[LIST_VARIABLE], buf, temp, def); substitute(ses, temp, pto, flags_neol - SUB_VAR); pto += strlen(pto); } else { *pto++ = *pti++; } break; case '<': if (HAS_BIT(flags, SUB_COL)) { if (HAS_BIT(flags, SUB_CMP) && !strncmp(old, pti, 5)) { pti += 5; } else if (isdigit((int)pti[1]) && isdigit((int)pti[2]) && isdigit((int)pti[3]) && pti[4] == '>') { if (pti[1] != '8' || pti[2] != '8' || pti[3] != '8') { *pto++ = ESCAPE; *pto++ = '['; switch (pti[1]) { case '2': *pto++ = '2'; *pto++ = '2'; *pto++ = ';'; break; case '8': break; default: *pto++ = pti[1]; *pto++ = ';'; } switch (pti[2]) { case '8': break; default: *pto++ = '3'; *pto++ = pti[2]; *pto++ = ';'; break; } switch (pti[3]) { case '8': break; default: *pto++ = '4'; *pto++ = pti[3]; *pto++ = ';'; break; } pto--; *pto++ = 'm'; } pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]); } else if (pti[1] >= 'a' && pti[1] <= 'f' && pti[2] >= 'a' && pti[2] <= 'f' && pti[3] >= 'a' && pti[3] <= 'f' && pti[4] == '>') { *pto++ = ESCAPE; *pto++ = '['; *pto++ = '3'; *pto++ = '8'; *pto++ = ';'; *pto++ = '5'; *pto++ = ';'; cnt = 16 + (pti[1] - 'a') * 36 + (pti[2] - 'a') * 6 + (pti[3] - 'a'); *pto++ = '0' + cnt / 100; *pto++ = '0' + cnt % 100 / 10; *pto++ = '0' + cnt % 10; *pto++ = 'm'; pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]); } else if (pti[1] >= 'A' && pti[1] <= 'F' && pti[2] >= 'A' && pti[2] <= 'F' && pti[3] >= 'A' && pti[3] <= 'F' && pti[4] == '>') { *pto++ = ESCAPE; *pto++ = '['; *pto++ = '4'; *pto++ = '8'; *pto++ = ';'; *pto++ = '5'; *pto++ = ';'; cnt = 16 + (pti[1] - 'A') * 36 + (pti[2] - 'A') * 6 + (pti[3] - 'A'); *pto++ = '0' + cnt / 100; *pto++ = '0' + cnt % 100 / 10; *pto++ = '0' + cnt % 10; *pto++ = 'm'; pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]); } else if (pti[1] == 'g' && isdigit((int)pti[2]) && isdigit((int)pti[3]) && pti[4] == '>') { *pto++ = ESCAPE; *pto++ = '['; *pto++ = '3'; *pto++ = '8'; *pto++ = ';'; *pto++ = '5'; *pto++ = ';'; cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0'); *pto++ = '0' + cnt / 100; *pto++ = '0' + cnt % 100 / 10; *pto++ = '0' + cnt % 10; *pto++ = 'm'; pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]); } else if (pti[1] == 'G' && isdigit((int)pti[2]) && isdigit((int)pti[3]) && pti[4] == '>') { *pto++ = ESCAPE; *pto++ = '['; *pto++ = '4'; *pto++ = '8'; *pto++ = ';'; *pto++ = '5'; *pto++ = ';'; cnt = 232 + (pti[2] - '0') * 10 + (pti[3] - '0'); *pto++ = '0' + cnt / 100; *pto++ = '0' + cnt % 100 / 10; *pto++ = '0' + cnt % 10; *pto++ = 'm'; pti += sprintf(old, "<%c%c%c>", pti[1], pti[2], pti[3]); } else { *pto++ = *pti++; } } else { *pto++ = *pti++; } break; case '@': if (HAS_BIT(flags, SUB_FUN)) { if (pti[1] == '@') { escape = TRUE; *pto++ = *pti++; continue; } for (ptt = temp, i = 1; isalnum((int)pti[i]) || pti[i] == '_'; i++) { *ptt++ = pti[i]; } *ptt = 0; node = search_node_list(ses->list[LIST_FUNCTION], temp); if (node == NULL || pti[i] != DEFAULT_OPEN) { escape = FALSE; *pto++ = *pti++; continue; } if (escape) { pti++; continue; } pti = get_arg_in_braces(ses, &pti[i], temp, FALSE); substitute(ses, temp, buf, flags_neol); show_debug(ses, LIST_FUNCTION, "#DEBUG FUNCTION {%s}", node->left); RESTRING(gtd->vars[0], buf); pte = buf; for (i = 1; i < 100; i++) { pte = get_arg_in_braces(ses, pte, temp, TRUE); RESTRING(gtd->vars[i], temp); if (*pte == 0) { break; } if (*pte == COMMAND_SEPARATOR) { pte++; } } substitute(ses, node->right, buf, SUB_ARG); script_driver(ses, LIST_FUNCTION, buf); substitute(ses, "$result", pto, flags_neol | SUB_VAR); pto += strlen(pto); } else { *pto++ = *pti++; } break; case '%': if (HAS_BIT(flags, SUB_ARG) && (isdigit((int)pti[1]) || pti[1] == '%')) { if (pti[1] == '%') { while (pti[1] == '%') { *pto++ = *pti++; } pti++; } else { i = isdigit((int)pti[2]) ? (pti[1] - '0') * 10 + pti[2] - '0' : pti[1] - '0'; ptt = gtd->vars[i]; while (*ptt) { if (HAS_BIT(ses->flags, SES_FLAG_BIG5) && *ptt & 128 && ptt[1] != 0) { *pto++ = *ptt++; *pto++ = *ptt++; continue; } if (HAS_BIT(flags, SUB_SEC)) { switch (*ptt) { case '\\': *pto++ = '\\'; *pto++ = '\\'; break; case '{': *pto++ = '\\'; *pto++ = 'x'; *pto++ = '7'; *pto++ = 'B'; break; case '}': *pto++ = '\\'; *pto++ = 'x'; *pto++ = '7'; *pto++ = 'D'; break; case COMMAND_SEPARATOR: *pto++ = '\\'; *pto++ = COMMAND_SEPARATOR; break; default: *pto++ = *ptt; break; } ptt++; } else { *pto++ = *ptt++; } } pti += isdigit((int)pti[2]) ? 3 : 2; } } else { *pto++ = *pti++; } break; case '&': if (HAS_BIT(flags, SUB_CMD) && (isdigit((int)pti[1]) || pti[1] == '&')) { if (pti[1] == '&') { while (pti[1] == '&') { *pto++ = *pti++; } if (isdigit((int)pti[1])) { pti++; } else { *pto++ = *pti++; } } else { i = isdigit((int)pti[2]) ? (pti[1] - '0') * 10 + pti[2] - '0' : pti[1] - '0'; for (cnt = 0; gtd->cmds[i][cnt]; cnt++) { *pto++ = gtd->cmds[i][cnt]; } pti += isdigit((int)pti[2]) ? 3 : 2; } } else if (HAS_BIT(flags, SUB_VAR) && (pti[1] == DEFAULT_OPEN || isalpha((int)pti[1]) || pti[1] == '&')) { int def = 0; if (pti[1] == '&') { while (pti[1] == '&') { *pto++ = *pti++; } if (pti[1] == DEFAULT_OPEN || isalnum((int)pti[1])) { pti++; } else { *pto++ = *pti++; } continue; } pti++; if (*pti == DEFAULT_OPEN) { def = TRUE; pti = get_arg_in_braces(ses, pti, buf, TRUE); substitute(ses, buf, temp, flags_neol); } else { for (ptt = temp; isalnum((int)*pti) || *pti == '_'; i++) { *ptt++ = *pti++; } *ptt = 0; } pti = get_arg_at_brackets(ses, pti, temp + strlen(temp)); substitute(ses, temp, buf, flags_neol); get_nest_index(ses->list[LIST_VARIABLE], buf, temp, def); substitute(ses, temp, pto, flags_neol - SUB_VAR); pto += strlen(pto); } else { *pto++ = *pti++; } break; case '\\': if (HAS_BIT(flags, SUB_ESC)) { pti++; switch (*pti) { case 'a': *pto++ = '\a'; break; case 'b': *pto++ = '\b'; break; case 'c': if (pti[1]) { pti++; *pto++ = *pti % 32; } break; case 'e': *pto++ = '\033'; break; case 'n': *pto++ = '\n'; break; case 'r': *pto++ = '\r'; break; case 't': *pto++ = '\t'; break; case 'x': if (pti[1] && pti[2]) { pti++; *pto++ = hex_number(pti); pti++; } break; case '0': if (pti[1] && pti[2]) { pti++; *pto++ = oct_number(pti); pti++; } break; case '\0': DEL_BIT(flags, SUB_EOL); DEL_BIT(flags, SUB_LNF); continue; default: *pto++ = *pti; break; } pti++; } else { *pto++ = *pti++; } break; case ESCAPE: *pto++ = *pti++; break; default: if (HAS_BIT(flags, SUB_SEC) && !HAS_BIT(flags, SUB_ARG)) { switch (*pti) { case '\\': *pto++ = '\\'; *pto++ = '\\'; break; case '{': *pto++ = '\\'; *pto++ = 'x'; *pto++ = '7'; *pto++ = 'B'; break; case '}': *pto++ = '\\'; *pto++ = 'x'; *pto++ = '7'; *pto++ = 'D'; break; case COMMAND_SEPARATOR: *pto++ = '\\'; *pto++ = COMMAND_SEPARATOR; break; default: *pto++ = *pti; break; } pti++; } else { *pto++ = *pti++; } break; } } }
void readmud(struct session *ses) { char *line, *next_line; char linebuf[STRING_SIZE]; push_call("readmud(%p)", ses); if (gtd->mud_output_len < BUFFER_SIZE) { check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "RECEIVED OUTPUT", gtd->mud_output_buf); } gtd->mud_output_len = 0; /* separate into lines and print away */ if (HAS_BIT(gtd->ses->flags, SES_FLAG_SPLIT)) { save_pos(gtd->ses); goto_rowcol(gtd->ses, gtd->ses->bot_row, 1); } SET_BIT(gtd->ses->flags, SES_FLAG_READMUD); for (line = gtd->mud_output_buf ; line && *line ; line = next_line) { next_line = strchr(line, '\n'); if (next_line) { *next_line = 0; next_line++; } else if (*line == 0) { break; } if (next_line == NULL && strlen(ses->more_output) < BUFFER_SIZE / 2) { if (!HAS_BIT(gtd->ses->telopts, TELOPT_FLAG_PROMPT)) { if (gts->check_output) { strcat(ses->more_output, line); ses->check_output = utime() + gts->check_output; break; } } } if (ses->more_output[0]) { if (ses->check_output) { sprintf(linebuf, "%s%s", ses->more_output, line); ses->more_output[0] = 0; } else { strcpy(linebuf, line); } } else { strcpy(linebuf, line); } process_mud_output(ses, linebuf, next_line == NULL); } DEL_BIT(gtd->ses->flags, SES_FLAG_READMUD); if (HAS_BIT(gtd->ses->flags, SES_FLAG_SPLIT)) { restore_pos(gtd->ses); } pop_call(); return; }
void get_color_codes(char *old, char *str, char *buf) { char *pti, *pto, col[100], tmp[BUFFER_SIZE]; int len, vtc, fgc, bgc, cnt; pto = tmp; pti = old; while (*pti) { while ((len = find_non_color_codes(pti)) != 0) { memcpy(pto, pti, len); pti += len; pto += len; } if (*pti) { pti++; } } pti = str; while (*pti) { while ((len = find_non_color_codes(pti)) != 0) { memcpy(pto, pti, len); pti += len; pto += len; } if (*pti) { pti++; } } *pto = 0; if (strlen(tmp) == 0) { buf[0] = 0; return; } vtc = 0; fgc = -1; bgc = -1; pti = tmp; while (*pti) { switch (*pti) { case 27: pti += 2; if (pti[-1] == 'm') { vtc = 0; fgc = -1; bgc = -1; break; } for (cnt = 0 ; pti[cnt] ; cnt++) { col[cnt] = pti[cnt]; if (pti[cnt] == ';' || pti[cnt] == 'm') { col[cnt] = 0; cnt = -1; pti += 1 + strlen(col); if (HAS_BIT(vtc, COL_256) && (HAS_BIT(vtc, COL_XTF) || HAS_BIT(vtc, COL_XTB))) { if (HAS_BIT(vtc, COL_XTF)) { fgc = URANGE(0, atoi(col), 255); } if (HAS_BIT(vtc, COL_XTB)) { bgc = URANGE(0, atoi(col), 255); } DEL_BIT(vtc, COL_XTF|COL_XTB); } else { switch (atoi(col)) { case 0: vtc = 0; fgc = -1; bgc = -1; break; case 1: SET_BIT(vtc, COL_BLD); break; case 4: SET_BIT(vtc, COL_UND); break; case 5: if (HAS_BIT(vtc, COL_XTF) || HAS_BIT(vtc, COL_XTB)) { SET_BIT(vtc, COL_256); } else { SET_BIT(vtc, COL_BLK); } break; case 7: SET_BIT(vtc, COL_REV); break; case 2: case 21: case 22: DEL_BIT(vtc, COL_BLD); break; case 24: DEL_BIT(vtc, COL_UND); break; case 25: DEL_BIT(vtc, COL_BLK); break; case 27: DEL_BIT(vtc, COL_REV); break; case 38: DEL_BIT(vtc, COL_XTB); DEL_BIT(vtc, COL_256); SET_BIT(vtc, COL_XTF); fgc = -1; break; case 39: DEL_BIT(vtc, COL_UND); fgc = -1; break; case 48: DEL_BIT(vtc, COL_XTF); DEL_BIT(vtc, COL_256); SET_BIT(vtc, COL_XTB); bgc = -1; break; default: DEL_BIT(vtc, COL_256); /* Use 256 color's 16 color notation */ if (atoi(col) / 10 == 4) { bgc = atoi(col) % 10; } if (atoi(col) / 10 == 9) { bgc = atoi(col) % 10 + 8; } if (atoi(col) / 10 == 3) { fgc = atoi(col) % 10; } if (atoi(col) / 10 == 10) { fgc = atoi(col) % 10 + 8; } break; } } } if (pti[-1] == 'm') { break; } } break; default: pti++; break; } } strcpy(buf, "\033[0"); if (HAS_BIT(vtc, COL_BLD)) { strcat(buf, ";1"); } if (HAS_BIT(vtc, COL_UND)) { strcat(buf, ";4"); } if (HAS_BIT(vtc, COL_BLK)) { strcat(buf, ";5"); } if (HAS_BIT(vtc, COL_REV)) { strcat(buf, ";7"); } if (fgc >= 16) { cat_sprintf(buf, ";38;5;%d", fgc); } else if (fgc >= 8) { cat_sprintf(buf, ";%d", fgc + 100); } else if (fgc >= 0) { cat_sprintf(buf, ";%d", fgc + 30); } if (bgc >= 16) { cat_sprintf(buf, ";48;5;%d", bgc); } else if (bgc >= 8) { cat_sprintf(buf, ";%d", fgc + 90); } else if (bgc >= 0) { cat_sprintf(buf, ";%d", bgc + 40); } strcat(buf, "m"); }
struct session *new_session(struct session *ses, char *name, char *command, int pid, int socket) { int cnt = 0; struct session *newsession; push_call("new_session(%p,%p,%p,%d,%d)",ses,name,command,pid,socket); for (newsession = gts ; newsession ; newsession = newsession->next) { if (!strcmp(newsession->name, name)) { display_puts(ses, "THERE'S A SESSION WITH THAT NAME ALREADY."); if (close(socket) == -1) { syserr("close in new_session"); } kill(pid, SIGKILL); pop_call(); return ses; } } newsession = (struct session *) calloc(1, sizeof(struct session)); newsession->name = strdup(name); newsession->command = strdup(command); newsession->pid = pid; newsession->group = strdup(gts->group); newsession->flags = gts->flags; LINK(newsession, gts->next, gts->prev); for (cnt = 0 ; cnt < LIST_MAX ; cnt++) { newsession->list[cnt] = copy_list(newsession, gts->list[cnt], cnt); } newsession->rows = gts->rows; newsession->cols = gts->cols; display_printf(ses, "#TRYING TO LAUNCH '%s' RUNNING '%s'.", newsession->name, newsession->command); gtd->ses = newsession; SET_BIT(newsession->flags, SES_FLAG_CONNECTED|SES_FLAG_RUN); DEL_BIT(newsession->flags, SES_FLAG_LOCALECHO); gtd->ses = newsession; gtd->ses->socket = socket; check_all_events(ses, SUB_ARG|SUB_SEC, 0, 3, "SESSION CONNECTED", ses->name, ses->command, ntos(ses->pid)); pop_call(); return gtd->ses; }