int check_all_aliases(struct session *ses, char *input) { struct listnode *node; struct listroot *root; char line[BUFFER_SIZE], tmp[BUFFER_SIZE], *arg; int i; root = ses->list[LIST_ALIAS]; if (HAS_BIT(root->flags, LIST_FLAG_IGNORE)) { return FALSE; } for (i = 1; i < 100; i++) { if (*gtd->vars[i]) { RESTRING(gtd->vars[i], ""); } } substitute(ses, input, line, SUB_VAR | SUB_FUN); for (root->update = 0; root->update < root->used; root->update++) { if (check_one_regexp(ses, root->list[root->update], line, line, PCRE_ANCHORED)) { node = root->list[root->update]; i = strlen(node->left); if (!strncmp(node->left, line, i)) { if (line[i] && line[i] != ' ') { continue; } arg = get_arg_in_braces(ses, line, tmp, FALSE); RESTRING(gtd->vars[0], arg) for (i = 1; i < 100 && *arg; i++) { arg = get_arg_in_braces(ses, arg, tmp, FALSE); RESTRING(gtd->vars[i], tmp); } } substitute(ses, node->right, tmp, SUB_ARG); if (!strncmp(node->left, line, strlen(node->left)) && !strcmp(node->right, tmp) && *gtd->vars[0]) { sprintf(input, "%s %s", tmp, gtd->vars[0]); } else { sprintf(input, "%s", tmp); } show_debug(ses, LIST_ALIAS, "#DEBUG ALIAS {%s} {%s}", node->left, gtd->vars[0]); return TRUE; } }
int connect_mud(struct session *ses, char *host, char *port) { int sock, d; struct sockaddr_in sockaddr; if (sscanf(host, "%d.%d.%d.%d", &d, &d, &d, &d) == 4) { sockaddr.sin_addr.s_addr = inet_addr(host); } else { struct hostent *hp; if (!(hp = gethostbyname(host))) { tintin_puts2(ses, "#ERROR - UNKNOWN HOST."); return -1; } memcpy((char *)&sockaddr.sin_addr, hp->h_addr, sizeof(sockaddr.sin_addr)); } if (is_number(port)) { sockaddr.sin_port = htons(atoi(port)); } else { tintin_puts(ses, "#THE PORT SHOULD BE A NUMBER."); return -1; } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { syserr("socket"); } sockaddr.sin_family = AF_INET; ses->connect_error = connect(sock, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); if (ses->connect_error) { close(sock); return 0; } if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1) { perror("connect_mud: fcntl O_NDELAY|O_NONBLOCK"); } RESTRING(ses->ip, inet_ntoa(sockaddr.sin_addr)); return sock; }
int connect_mud(struct session *ses, char *host, char *port) { int sock, error; struct addrinfo *address; static struct addrinfo hints; char ip[100]; if (!is_number(port)) { tintin_puts(ses, "#THE PORT SHOULD BE A NUMBER."); return -1; } hints.ai_family = AF_UNSPEC; hints.ai_protocol = IPPROTO_TCP; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(host, port, &hints, &address); if (error) { tintin_printf(ses, "#SESSION '%s' COULD NOT CONNECT - UNKNOWN HOST.", ses->name); return -1; } sock = socket(address->ai_family, address->ai_socktype, address->ai_protocol); if (sock < 0) { syserr("socket"); } ses->connect_error = connect(sock, address->ai_addr, address->ai_addrlen); if (ses->connect_error) { close(sock); freeaddrinfo(address); return 0; } if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1) { perror("connect_mud: fcntl O_NDELAY|O_NONBLOCK"); } getnameinfo(address->ai_addr, address->ai_addrlen, ip, 100, NULL, 0, NI_NUMERICHOST); RESTRING(ses->ip, ip); freeaddrinfo(address); return sock; }
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; } } }