struct session *connect_session(struct session *ses) { int sock; push_call("connection_session(%p)",ses); ses->connect_retry = utime() + gts->connect_retry; reconnect: sock = connect_mud(ses, ses->host, ses->port); if (sock == -1) { cleanup_session(ses); pop_call(); return NULL; } if (sock) { gtd->ses = ses; ses->socket = sock; ses->connect_retry = 0; SET_BIT(ses->flags, SES_FLAG_CONNECTED); tintin_printf2(ses, ""); tintin_printf(ses, "#SESSION '%s' CONNECTED TO '%s' PORT '%s'", ses->name, ses->host, ses->port); check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION CONNECTED", ses->name, ses->host, ses->ip, ses->port); pop_call(); return ses; } if (ses->connect_retry > utime()) { goto reconnect; } if (ses->connect_error) { tintin_printf(ses, "#SESSION '%s' FAILED TO CONNECT.", ses->name); } cleanup_session(ses); pop_call(); return NULL; }
void do_one_line(char *line, struct session *ses) { char strip[BUFFER_SIZE]; push_call("[%s] do_one_line(%s)",ses->name,line); if (HAS_BIT(ses->flags, SES_FLAG_IGNORELINE)) { 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)) { if (HAS_BIT(ses->flags, SES_FLAG_SPLIT)) { 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 (ses->logline) { logit(ses, line, ses->logline, TRUE); fclose(ses->logline); ses->logline = NULL; } pop_call(); return; }
void init_buffer(struct session *ses, int size) { int cnt; push_call("init_buffer(%p,%p)",ses,size); if (ses->scroll_max == size) { pop_call(); return; } if (ses->buffer) { cnt = ses->scroll_row; do { if (++cnt == ses->scroll_max) { cnt = 0; } if (ses->buffer[cnt] == NULL) { break; } str_unhash(ses->buffer[cnt]); } while (cnt != ses->scroll_row); } if (ses->buffer) { free(ses->buffer); } if (size) { ses->buffer = (char **) calloc(size, sizeof(char *)); ses->scroll_max = size; ses->scroll_row = size - 1; ses->scroll_line = - 1; } pop_call(); return; }
void printline(struct session *ses, char **str, int prompt) { char *out; push_call("printline(%p,%p,%d)",ses,*str,prompt); if (ses->scroll_line != -1 && HAS_BIT(ses->flags, SES_FLAG_SCROLLLOCK)) { pop_call(); return; } if (HAS_BIT(ses->flags, SES_FLAG_SCAN) && !HAS_BIT(ses->flags, SES_FLAG_VERBOSE)) { pop_call(); return; } out = str_alloc(strlen(*str) * 2); if (HAS_BIT(ses->flags, SES_FLAG_CONVERTMETA)) { convert_meta(*str, out); str_cpy(str, out); } if (HAS_BIT(ses->flags, SES_FLAG_WORDWRAP)) { word_wrap(ses, *str, out, TRUE); } else { strcpy(out, *str); } if (prompt) { printf("%s", out); } else { printf("%s\n", out); } str_free(out); pop_call(); return; }
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; }
void write_line_mud(struct session *ses, char *line, int size) { static int retry; push_call("write_line_mud(%p,%p)",line,ses); if (ses == gts) { tintin_printf2(ses, "#NO SESSION ACTIVE. USE: %csession {name} {host} {port} TO START ONE.", gtd->tintin_char); pop_call(); return; } if (!HAS_BIT(ses->flags, SES_FLAG_CONNECTED)) { tintin_printf2(ses, "#THIS SESSION IS NOT CONNECTED."); pop_call(); return; } if (write(ses->socket, line, size) == -1) { if (retry++ < 10) { usleep(100000); write_line_mud(ses, line, size); pop_call(); return; } perror("write in write_line_mud"); cleanup_session(ses); pop_call(); return; } retry = 0; check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "SEND OUTPUT", line); pop_call(); return; }
int read_buffer_mud(struct session *ses) { unsigned char buffer[BUFFER_SIZE]; int size; push_call("read_buffer_mud(%p)", ses); size = read(ses->socket, buffer, BUFFER_SIZE - 1); if (size <= 0) { pop_call(); return FALSE; } ses->read_len = translate_telopts(ses, buffer, size); pop_call(); return TRUE; }
char *strip_vt102_strstr(char *str, char *buf, int *len) { char *pti, *ptm, *pts; push_call("strip_vt102_strstr(%p,%p,%p)",str,buf,len); pts = str; while (*pts) { pti = pts; ptm = buf; while (*pti) { if (*pti++ != *ptm++) { break; } if (*ptm == 0) { if (len) { *len = pti - pts; } pop_call(); return pts; } while (skip_vt102_codes(pti)) { pti += skip_vt102_codes(pti); } } pts++; } pop_call(); return NULL; }
void write_node(struct session *ses, int list, struct listnode *node, FILE *file) { char result[STRING_SIZE], buffer[BUFFER_SIZE]; int llen = UMAX(20, strlen(node->left)); int rlen = UMAX(25, strlen(node->right)); push_call("write_node(%d,%p,%p)",list,node,file); switch (list) { case LIST_EVENT: case LIST_FUNCTION: case LIST_MACRO: sprintf(result, "%c%s {%s}\n{\n%s\n}\n\n", gtd->command_char, list_table[list].name, node->left, script_writer(ses, node->right)); break; case LIST_ACTION: case LIST_ALIAS: sprintf(result, "%c%s {%s}\n{\n%s\n}\n{%s}\n\n", gtd->command_char, list_table[list].name, node->left, script_writer(ses, node->right), node->pr); break; case LIST_VARIABLE: show_nest_node(node, buffer, 1); sprintf(result, "%c%-16s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", buffer); break; default: switch (list_table[list].args) { case 0: result[0] = 0; break; case 1: sprintf(result, "%c%-16s {%s}\n", gtd->command_char, list_table[list].name, node->left); break; case 2: sprintf(result, "%c%-16s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", node->right); break; case 3: sprintf(result, "%c%-16s {%s} %*s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", node->right, 25 - rlen, "", node->pr); break; } break; } fputs(result, file); pop_call(); return; }
struct session *parse_command(struct session *ses, char *input) { char *arg, line[BUFFER_SIZE], cmd1[BUFFER_SIZE], cmd2[BUFFER_SIZE]; push_call("parse_command(%p,%p)",ses,input); arg = get_arg_stop_spaces(ses, input, cmd1, 0); substitute(ses, cmd1, cmd2, SUB_VAR|SUB_FUN); if (!strcmp(cmd1, cmd2)) { pop_call(); return NULL; } sprintf(line, "%s%s%s", cmd2, *arg ? " " : "", arg); strcpy(input, line); pop_call(); return ses; }
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; }
struct session *newactive_session(void) { push_call("newactive_session(void)"); if (gts->next) { activate_session(gts->next); } else { activate_session(gts); } pop_call(); return gtd->ses; }
void dispose_session(struct session *ses) { int index; push_call("dispose_session(%p)", ses); UNLINK(ses, gtd->dispose_next, gtd->dispose_prev); for (index = 0 ; index < LIST_MAX ; index++) { free_list(ses->list[index]); } free(ses->name); free(ses->command); free(ses->group); free(ses); pop_call(); return; }
void dispose_session(struct session *ses) { int index; push_call("dispose_session(%p)", ses); UNLINK(ses, gtd->dispose_next, gtd->dispose_prev); for (index = 0 ; index < LIST_MAX ; index++) { free_list(ses->list[index]); } if (ses->map) { delete_map(ses); } if (ses->mccp) { inflateEnd(ses->mccp); free(ses->mccp); } init_buffer(ses, 0); free(ses->name); free(ses->host); free(ses->ip); free(ses->port); free(ses->group); free(ses->read_buf); free(ses->cmd_color); free(ses); pop_call(); return; }
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; } } }
struct session *parse_input(struct session *ses, char *input) { char *line; push_call("parse_input(%s,%s)",ses->name,input); if (*input == 0) { write_mud(ses, input, SUB_EOL); pop_call(); return ses; } if (VERBATIM(ses)) { line = (char *) malloc(BUFFER_SIZE); strcpy(line, input); if (check_all_aliases(ses, line)) { ses = script_driver(ses, LIST_ALIAS, line); } else { write_mud(ses, line, SUB_EOL); } free(line); pop_call(); return ses; } if (*input == gtd->verbatim_char) { write_mud(ses, input+1, SUB_EOL); pop_call(); return ses; } line = (char *) malloc(BUFFER_SIZE); while (*input) { input = space_out(input); input = get_arg_all(ses, input, line, FALSE); if (parse_command(ses, line)) { ses = script_driver(ses, -1, line); } else if (check_all_aliases(ses, line)) { ses = script_driver(ses, LIST_ALIAS, line); } else if (HAS_BIT(ses->flags, SES_FLAG_SPEEDWALK) && is_speedwalk(ses, line)) { process_speedwalk(ses, line); } else { write_mud(ses, line, SUB_VAR|SUB_FUN|SUB_ESC|SUB_EOL); } if (*input == COMMAND_SEPARATOR) { input++; } } free(line); pop_call(); return ses; }
void process_mud_output(struct session *ses, char *linebuf, int prompt) { char line[STRING_SIZE]; push_call("process_mud_output(%p,%p,%d)",ses,linebuf,prompt); 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); pop_call(); 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); } pop_call(); return; }
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; }
int skip_vt102_codes(char *str) { int skip; push_call("skip_vt102_codes(%p)",str); switch (str[0]) { case 5: /* ENQ */ case 7: /* BEL */ case 8: /* BS */ /* case 9: *//* HT */ /* case 10: *//* LF */ case 11: /* VT */ case 12: /* FF */ case 13: /* CR */ case 14: /* SO */ case 15: /* SI */ case 17: /* DC1 */ case 19: /* DC3 */ case 24: /* CAN */ case 26: /* SUB */ case 127: /* DEL */ pop_call(); return 1; case 27: /* ESC */ break; default: pop_call(); return 0; } switch (str[1]) { case '\0': pop_call(); return 1; case '%': case '#': case '(': case ')': pop_call(); return str[2] ? 3 : 2; case ']': switch (str[2]) { case 'P': for (skip = 3 ; skip < 10 ; skip++) { if (str[skip] == 0) { break; } } pop_call(); return skip; case 'R': pop_call(); return 3; } pop_call(); return 2; case '[': break; default: pop_call(); return 2; } for (skip = 2 ; str[skip] != 0 ; skip++) { if (isalpha((int) str[skip])) { pop_call(); return skip + 1; } switch (str[skip]) { case '@': case '`': case ']': pop_call(); return skip + 1; } } pop_call(); return skip; }
int word_wrap(struct session *ses, char *textin, char *textout, int display) { char *pti, *pto, *lis, *los, *chi, *cho; int skip = 0, cnt = 0; push_call("word_wrap(%s,%p,%p)",ses->name, textin,textout); pti = chi = lis = textin; pto = cho = los = textout; ses->cur_col = 1; while (*pti != 0) { if (skip_vt102_codes(pti)) { if (display) { interpret_vt102_codes(ses, pti, TRUE); } for (skip = skip_vt102_codes(pti) ; skip > 0 ; skip--) { *pto++ = *pti++; } continue; } if (*pti == '\n') { *pto++ = *pti++; cnt = cnt + 1; los = pto; lis = pti; ses->cur_col = 1; continue; } if (*pti == ' ') { los = pto; lis = pti; } if (ses->cur_col > ses->cols) { cnt++; ses->cur_col = 1; if (HAS_BIT(ses->flags, SES_FLAG_WORDWRAP)) { if (pto - los > 15 || !SCROLL(ses)) { *pto++ = '\n'; los = pto; lis = pti; } else if (lis != chi) // infinite VT loop detection { pto = los; *pto++ = '\n'; pti = chi = lis; pti++; } else if (los != cho) { pto = cho = los; pto++; pti = chi = lis; pti++; } } } else { if (HAS_BIT(ses->flags, SES_FLAG_BIG5) && *pti & 128 && pti[1] != 0) { *pto++ = *pti++; *pto++ = *pti++; } else if (HAS_BIT(ses->flags, SES_FLAG_UTF8) && (*pti & 192) == 192) { *pto++ = *pti++; while ((*pti & 192) == 128) { *pto++ = *pti++; } } else { *pto++ = *pti++; } ses->cur_col++; } } *pto = 0; pop_call(); return (cnt + 1); }
int word_wrap_split(struct session *ses, char *textin, char *textout, int skip, int keep) { char *pti, *pto, *lis, *los, *chi, *cho, *ptb; int i = 0, cnt = 0; push_call("word_wrap_split(%s,%p,%p,%d,%d)",ses->name, textin,textout, skip, keep); pti = chi = lis = textin; pto = cho = los = textout; ses->cur_col = 1; while (*pti != 0) { if (skip_vt102_codes(pti)) { if (cnt >= skip && cnt < keep) { for (i = skip_vt102_codes(pti) ; i > 0 ; i--) { *pto++ = *pti++; } } else { pti += skip_vt102_codes(pti); } continue; } if (*pti == '\n') { if (cnt >= skip && cnt < keep) { *pto++ = *pti++; } else { pti++; } cnt = cnt + 1; los = pto; lis = pti; ses->cur_col = 1; continue; } if (*pti == ' ') { los = pto; lis = pti; } if (ses->cur_col > ses->cols) { cnt++; ses->cur_col = 1; if (HAS_BIT(ses->flags, SES_FLAG_WORDWRAP)) { if (pto - los > 15 || !SCROLL(ses)) { if (cnt >= skip && cnt < keep) { *pto++ = '\n'; } los = pto; lis = pti; } else if (lis != chi) // infinite VT loop detection { if (cnt >= skip && cnt < keep) { pto = los; *pto++ = '\n'; } pti = chi = lis; pti++; } else if (los != cho) { if (cnt >= skip && cnt < keep) { pto = cho = los; pto++; } else { cho = los; } pti = chi = lis; pti++; } } } else { ptb = pto; if (HAS_BIT(ses->flags, SES_FLAG_BIG5) && *pti & 128 && pti[1] != 0) { *pto++ = *pti++; *pto++ = *pti++; } else if (HAS_BIT(ses->flags, SES_FLAG_UTF8) && (*pti & 192) == 192) { *pto++ = *pti++; while ((*pti & 192) == 128) { *pto++ = *pti++; } } else { *pto++ = *pti++; } if (cnt < skip || cnt >= keep) { pto = ptb; } ses->cur_col++; } } *pto = 0; pop_call(); return (cnt + 1); }
void cleanup_session(struct session *ses) { push_call("cleanup_session(%p)",ses); if (HAS_BIT(ses->flags, SES_FLAG_CLOSED)) { tintin_printf2(NULL, "\n#SESSION '%s' IS ALREADY CLOSED.", ses->name); dump_stack(); pop_call(); return; } 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"); } // the PID is stored in the session's port. if (HAS_BIT(ses->flags, SES_FLAG_RUN)) { kill(atoi(ses->port), SIGKILL); } } SET_BIT(ses->flags, SES_FLAG_CLOSED); if (HAS_BIT(ses->flags, SES_FLAG_CONNECTED)) { check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION DISCONNECTED", ses->name, ses->host, ses->ip, ses->port); tintin_printf(gtd->ses, "#SESSION '%s' DIED.", ses->name); } else { check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "SESSION TIMED OUT", ses->name, ses->host, ses->ip, ses->port); tintin_printf(gtd->ses, "#SESSION '%s' TIMED OUT.", 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; }
int check_all_events(struct session *ses, int flags, int args, int vars, char *fmt, ...) { struct session *ses_ptr; struct listnode *node; char name[BUFFER_SIZE], buf[BUFFER_SIZE]; va_list list; int cnt; va_start(list, fmt); vsprintf(name, fmt, list); va_end(list); push_call("check_all_events(%p,%d,%d,%d,%s, ...)",ses,flags,args,vars,name); for (ses_ptr = ses ? ses : gts ; ses_ptr ; ses_ptr = ses_ptr->next) { if (!HAS_BIT(ses_ptr->list[LIST_EVENT]->flags, LIST_FLAG_IGNORE)) { show_info(ses_ptr, LIST_EVENT, "#INFO EVENT {%s}", name); node = search_node_list(ses_ptr->list[LIST_EVENT], name); if (node) { va_start(list, fmt); for (cnt = 0 ; cnt < args ; cnt++) { va_arg(list, char *); } for (cnt = 0 ; cnt < vars ; cnt++) { RESTRING(gtd->vars[cnt], va_arg(list, char *)); } substitute(ses_ptr, node->right, buf, flags); if (HAS_BIT(ses_ptr->list[LIST_EVENT]->flags, LIST_FLAG_DEBUG)) { show_debug(ses_ptr, LIST_ACTION, "#DEBUG EVENT {%s} (%s}", node->left, node->right); } script_driver(ses_ptr, LIST_EVENT, buf); va_end(list); if (ses) { pop_call(); return 1; } } } if (ses) { pop_call(); return 0; } }
void add_line_buffer(struct session *ses, char *line, int more_output) { char linebuf[STRING_SIZE]; char *pti, *pto; int lines; int sav_row, sav_col, cur_row, cur_col, top_row, bot_row; push_call("add_line_buffer(%p,%s,%d)", ses, line, more_output); if (ses->buffer == NULL || HAS_BIT(ses->flags, SES_FLAG_SCROLLSTOP)) { pop_call(); return; } sav_row = ses->sav_row; sav_col = ses->sav_col; cur_row = ses->cur_row; cur_col = ses->cur_col; top_row = ses->top_row; bot_row = ses->bot_row; if (more_output == TRUE) { if (strlen(ses->more_output) < BUFFER_SIZE / 2) { strcat(ses->more_output, line); pop_call(); return; } } strcat(ses->more_output, line); pti = pto = ses->more_output; while (*pti != 0) { while (skip_vt102_codes_non_graph(pti)) { interpret_vt102_codes(ses, pti, FALSE); pti += skip_vt102_codes_non_graph(pti); } if (*pti == 0) { break; } if (SCROLL(ses)) { *pto++ = *pti++; } else { pti++; } } *pto = 0; lines = word_wrap(ses, ses->more_output, linebuf, FALSE); ses->more_output[0] = 0; ses->buffer[ses->scroll_row] = str_hash(linebuf, lines); if (more_output == -1) { str_hash_grep(ses->buffer[ses->scroll_row], TRUE); } if (!HAS_BIT(ses->flags, SES_FLAG_LOGLEVEL)) { if (ses->logfile) { logit(ses, linebuf, ses->logfile, TRUE); } } if (gtd->chat) { chat_forward_session(ses, linebuf); } if (--ses->scroll_row < 0) { ses->scroll_row = ses->scroll_max - 1; } if (ses->buffer[ses->scroll_row]) { ses->buffer[ses->scroll_row] = str_unhash(ses->buffer[ses->scroll_row]); } ses->sav_row = sav_row; ses->sav_col = sav_col; ses->cur_row = cur_row; ses->cur_col = cur_col; ses->top_row = top_row; ses->bot_row = bot_row; pop_call(); return; }
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; }