size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; const char *p = data, *pe; ssize_t to_read; enum state state = (enum state) parser->state; enum header_states header_state = (enum header_states) parser->header_state; size_t index = parser->index; size_t nread = parser->nread; if (len == 0) { if (state == s_body_identity_eof) { CALLBACK2(message_complete); } return 0; } /* technically we could combine all of these (except for url_mark) into one variable, saving stack space, but it seems more clear to have them separated. */ const char *header_field_mark = 0; const char *header_value_mark = 0; const char *fragment_mark = 0; const char *query_string_mark = 0; const char *path_mark = 0; const char *url_mark = 0; if (state == s_header_field) header_field_mark = data; if (state == s_header_value) header_value_mark = data; if (state == s_req_fragment) fragment_mark = data; if (state == s_req_query_string) query_string_mark = data; if (state == s_req_path) path_mark = data; if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash || state == s_req_schema_slash_slash || state == s_req_port || state == s_req_query_string_start || state == s_req_query_string || state == s_req_host || state == s_req_fragment_start || state == s_req_fragment) url_mark = data; for (p=data, pe=data+len; p != pe; p++) { ch = *p; if (PARSING_HEADER(state)) { ++nread; /* Buffer overflow attack */ if (nread > HTTP_MAX_HEADER_SIZE) goto error; } switch (state) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ goto error; case s_start_req_or_res: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (ch == 'H') state = s_res_or_resp_H; else { parser->type = HTTP_REQUEST; goto start_req_method_assign; } break; } case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; state = s_res_HT; } else { if (ch != 'E') goto error; parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; index = 2; state = s_req_method; } break; case s_start_res: { parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); switch (ch) { case 'H': state = s_res_H; break; case CR: case LF: break; default: goto error; } break; } case s_res_H: STRICT_CHECK(ch != 'T'); state = s_res_HT; break; case s_res_HT: STRICT_CHECK(ch != 'T'); state = s_res_HTT; break; case s_res_HTT: STRICT_CHECK(ch != 'P'); state = s_res_HTTP; break; case s_res_HTTP: STRICT_CHECK(ch != '/'); state = s_res_first_http_major; break; case s_res_first_http_major: if (ch < '1' || ch > '9') goto error; parser->http_major = ch - '0'; state = s_res_http_major; break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { state = s_res_first_http_minor; break; } if (ch < '0' || ch > '9') goto error; parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) goto error; break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (ch < '0' || ch > '9') goto error; parser->http_minor = ch - '0'; state = s_res_http_minor; break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { state = s_res_first_status_code; break; } if (ch < '0' || ch > '9') goto error; parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) goto error; break; } case s_res_first_status_code: { if (ch < '0' || ch > '9') { if (ch == ' ') { break; } goto error; } parser->status_code = ch - '0'; state = s_res_status_code; break; } case s_res_status_code: { if (ch < '0' || ch > '9') { switch (ch) { case ' ': state = s_res_status; break; case CR: state = s_res_line_almost_done; break; case LF: state = s_header_field_start; break; default: goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (parser->status_code > 999) goto error; break; } case s_res_status: /* the human readable status. e.g. "NOT FOUND" * we are not humans so just ignore this */ if (ch == CR) { state = s_res_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); state = s_header_field_start; break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (ch < 'A' || 'Z' < ch) goto error; start_req_method_assign: parser->method = (enum http_method) 0; index = 1; switch (ch) { case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; case 'L': parser->method = HTTP_LOCK; break; case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE */ break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND or PROPPATCH or PUT */ break; case 'R': parser->method = HTTP_REPORT; break; case 'T': parser->method = HTTP_TRACE; break; case 'U': parser->method = HTTP_UNLOCK; break; default: goto error; } state = s_req_method; break; } case s_req_method: { if (ch == '\0') goto error; const char *matcher = method_strings[parser->method]; if (ch == ' ' && matcher[index] == '\0') { state = s_req_spaces_before_url; } else if (ch == matcher[index]) { ; // nada } else if (parser->method == HTTP_CONNECT) { if (index == 1 && ch == 'H') { parser->method = HTTP_CHECKOUT; } else if (index == 2 && ch == 'P') { parser->method = HTTP_COPY; } } else if (parser->method == HTTP_MKCOL) { if (index == 1 && ch == 'O') { parser->method = HTTP_MOVE; } else if (index == 1 && ch == 'E') { parser->method = HTTP_MERGE; } else if (index == 2 && ch == 'A') { parser->method = HTTP_MKACTIVITY; } } else if (index == 1 && parser->method == HTTP_POST && ch == 'R') { parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ } else if (index == 1 && parser->method == HTTP_POST && ch == 'U') { parser->method = HTTP_PUT; } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { parser->method = HTTP_PROPPATCH; } else { goto error; } ++index; break; } case s_req_spaces_before_url: { if (ch == ' ') break; if (ch == '/') { MARK(url); MARK(path); state = s_req_path; break; } c = LOWER(ch); if (c >= 'a' && c <= 'z') { MARK(url); state = s_req_schema; break; } goto error; } case s_req_schema: { c = LOWER(ch); if (c >= 'a' && c <= 'z') break; if (ch == ':') { state = s_req_schema_slash; break; } else if (ch == '.') { state = s_req_host; break; } goto error; } case s_req_schema_slash: STRICT_CHECK(ch != '/'); state = s_req_schema_slash_slash; break; case s_req_schema_slash_slash: STRICT_CHECK(ch != '/'); state = s_req_host; break; case s_req_host: { c = LOWER(ch); if (c >= 'a' && c <= 'z') break; if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') break; switch (ch) { case ':': state = s_req_port; break; case '/': MARK(path); state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; default: goto error; } break; } case s_req_port: { if (ch >= '0' && ch <= '9') break; switch (ch) { case '/': MARK(path); state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com:1234 HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; default: goto error; } break; } case s_req_path: { if (USUAL(ch)) break; switch (ch) { case ' ': CALLBACK(url); CALLBACK(path); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(path); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(path); parser->http_minor = 9; state = s_header_field_start; break; case '?': CALLBACK(path); state = s_req_query_string_start; break; case '#': CALLBACK(path); state = s_req_fragment_start; break; default: goto error; } break; } case s_req_query_string_start: { if (USUAL(ch)) { MARK(query_string); state = s_req_query_string; break; } switch (ch) { case '?': break; // XXX ignore extra '?' ... is this right? case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: goto error; } break; } case s_req_query_string: { if (USUAL(ch)) break; switch (ch) { case '?': // allow extra '?' in query string break; case ' ': CALLBACK(url); CALLBACK(query_string); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(query_string); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(query_string); parser->http_minor = 9; state = s_header_field_start; break; case '#': CALLBACK(query_string); state = s_req_fragment_start; break; default: goto error; } break; } case s_req_fragment_start: { if (USUAL(ch)) { MARK(fragment); state = s_req_fragment; break; } switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_minor = 9; state = s_header_field_start; break; case '?': MARK(fragment); state = s_req_fragment; break; case '#': break; default: goto error; } break; } case s_req_fragment: { if (USUAL(ch)) break; switch (ch) { case ' ': CALLBACK(url); CALLBACK(fragment); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(fragment); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(fragment); parser->http_minor = 9; state = s_header_field_start; break; case '?': case '#': break; default: goto error; } break; } case s_req_http_start: switch (ch) { case 'H': state = s_req_http_H; break; case ' ': break; default: goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); state = s_req_http_HT; break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); state = s_req_http_HTT; break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); state = s_req_http_HTTP; break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); state = s_req_first_http_major; break; /* first digit of major HTTP version */ case s_req_first_http_major: if (ch < '1' || ch > '9') goto error; parser->http_major = ch - '0'; state = s_req_http_major; break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { state = s_req_first_http_minor; break; } if (ch < '0' || ch > '9') goto error; parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) goto error; break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (ch < '0' || ch > '9') goto error; parser->http_minor = ch - '0'; state = s_req_http_minor; break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { state = s_req_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } /* XXX allow spaces after digit? */ if (ch < '0' || ch > '9') goto error; parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) goto error; break; } /* end of request line */ case s_req_line_almost_done: { if (ch != LF) goto error; state = s_header_field_start; break; } case s_header_field_start: { if (ch == CR) { state = s_headers_almost_done; break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ state = s_headers_almost_done; goto headers_almost_done; } c = LOWER(ch); if (c < 'a' || 'z' < c) goto error; MARK(header_field); index = 0; state = s_header_field; switch (c) { case 'c': header_state = h_C; break; case 'p': header_state = h_matching_proxy_connection; break; case 't': header_state = h_matching_transfer_encoding; break; case 'u': header_state = h_matching_upgrade; break; default: header_state = h_general; break; } break; } case s_header_field: { c = lowcase[(unsigned char)ch]; if (c) { switch (header_state) { case h_general: break; case h_C: index++; header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: index++; header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: index++; switch (c) { case 'n': header_state = h_matching_connection; break; case 't': header_state = h_matching_content_length; break; default: header_state = h_general; break; } break; /* connection */ case h_matching_connection: index++; if (index > sizeof(CONNECTION)-1 || c != CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(CONNECTION)-2) { header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: index++; if (index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(PROXY_CONNECTION)-2) { header_state = h_connection; } break; /* content-length */ case h_matching_content_length: index++; if (index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[index]) { header_state = h_general; } else if (index == sizeof(CONTENT_LENGTH)-2) { header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: index++; if (index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[index]) { header_state = h_general; } else if (index == sizeof(TRANSFER_ENCODING)-2) { header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: index++; if (index > sizeof(UPGRADE)-1 || c != UPGRADE[index]) { header_state = h_general; } else if (index == sizeof(UPGRADE)-2) { header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } break; } if (ch == ':') { CALLBACK(header_field); state = s_header_value_start; break; } if (ch == CR) { state = s_header_almost_done; CALLBACK(header_field); break; } if (ch == LF) { CALLBACK(header_field); state = s_header_field_start; break; } goto error; } case s_header_value_start: { if (ch == ' ') break; MARK(header_value); state = s_header_value; index = 0; c = lowcase[(unsigned char)ch]; if (!c) { if (ch == CR) { CALLBACK(header_value); header_state = h_general; state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); state = s_header_field_start; break; } header_state = h_general; break; } switch (header_state) { case h_upgrade: parser->flags |= F_UPGRADE; header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { header_state = h_matching_transfer_encoding_chunked; } else { header_state = h_general; } break; case h_content_length: if (ch < '0' || ch > '9') goto error; parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { header_state = h_matching_connection_close; } else { header_state = h_general; } break; default: header_state = h_general; break; } break; } case s_header_value: { c = lowcase[(unsigned char)ch]; if (!c) { if (ch == CR) { CALLBACK(header_value); state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); goto header_almost_done; } break; } switch (header_state) { case h_general: break; case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: if (ch < '0' || ch > '9') goto error; parser->content_length *= 10; parser->content_length += ch - '0'; break; /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: index++; if (index > sizeof(CHUNKED)-1 || c != CHUNKED[index]) { header_state = h_general; } else if (index == sizeof(CHUNKED)-2) { header_state = h_transfer_encoding_chunked; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: index++; if (index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[index]) { header_state = h_general; } else if (index == sizeof(KEEP_ALIVE)-2) { header_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: index++; if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { header_state = h_general; } else if (index == sizeof(CLOSE)-2) { header_state = h_connection_close; } break; case h_transfer_encoding_chunked: case h_connection_keep_alive: case h_connection_close: if (ch != ' ') header_state = h_general; break; default: state = s_header_value; header_state = h_general; break; } break; } case s_header_almost_done: header_almost_done: { STRICT_CHECK(ch != LF); state = s_header_field_start; switch (header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } break; } case s_headers_almost_done: headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ CALLBACK2(message_complete); state = NEW_MESSAGE(); break; } nread = 0; if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) parser->upgrade = 1; /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we * will interpret that as saying that this message has no body. This * is needed for the annoying case of recieving a response to a HEAD * request. */ if (settings->on_headers_complete) { switch (settings->on_headers_complete(parser)) { case 0: break; case 1: parser->flags |= F_SKIPBODY; break; default: return p - data; /* Error */ } } // Exit, the rest of the connect is in a different protocol. if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) { CALLBACK2(message_complete); return (p - data); } if (parser->flags & F_SKIPBODY) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ state = s_chunk_size_start; } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->content_length > 0) { /* Content-Length header given and non-zero */ state = s_body_identity; } else { if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { /* Assume content-length 0 - read the next */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else { /* Read body until EOF */ state = s_body_identity_eof; } } } break; } case s_body_identity: to_read = MIN(pe - p, (ssize_t)parser->content_length); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; parser->content_length -= to_read; if (parser->content_length == 0) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } } break; /* read until EOF */ case s_body_identity_eof: to_read = pe - p; if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } break; case s_chunk_size_start: { assert(parser->flags & F_CHUNKED); c = unhex[(int)ch]; if (c == -1) goto error; parser->content_length = c; state = s_chunk_size; break; } case s_chunk_size: { assert(parser->flags & F_CHUNKED); if (ch == CR) { state = s_chunk_size_almost_done; break; } c = unhex[(int)ch]; if (c == -1) { if (ch == ';' || ch == ' ') { state = s_chunk_parameters; break; } goto error; } parser->content_length *= 16; parser->content_length += c; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { state = s_chunk_size_almost_done; break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); if (parser->content_length == 0) { parser->flags |= F_TRAILING; state = s_header_field_start; } else { state = s_chunk_data; } break; } case s_chunk_data: { assert(parser->flags & F_CHUNKED); to_read = MIN(pe - p, (ssize_t)(parser->content_length)); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } if (to_read == parser->content_length) { state = s_chunk_data_almost_done; } parser->content_length -= to_read; break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != CR); state = s_chunk_data_done; break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); state = s_chunk_size_start; break; default: assert(0 && "unhandled state"); goto error; } } CALLBACK_NOCLEAR(header_field); CALLBACK_NOCLEAR(header_value); CALLBACK_NOCLEAR(fragment); CALLBACK_NOCLEAR(query_string); CALLBACK_NOCLEAR(path); CALLBACK_NOCLEAR(url); parser->state = state; parser->header_state = header_state; parser->index = index; parser->nread = nread; return len; error: return (p - data); }
int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { if (bHeader == 10) // 엔터는 무시 return 0; if (bHeader == HEADER_CG_TEXT) { ++c_pData; const char * c_pSep; if (!(c_pSep = strchr(c_pData, '\n'))) // \n을 찾는다. return -1; if (*(c_pSep - 1) == '\r') --c_pSep; std::string stResult; std::string stBuf; stBuf.assign(c_pData, 0, c_pSep - c_pData); sys_log(0, "SOCKET_CMD: FROM(%s) CMD(%s)", d->GetHostName(), stBuf.c_str()); if (!stBuf.compare("IS_SERVER_UP")) { if (g_bNoMoreClient) stResult = "NO"; else stResult = "YES"; } else if (!stBuf.compare("IS_PASSPOD_UP")) { if (g_bNoPasspod) stResult = "NO"; else stResult = "YES"; } //else if (!stBuf.compare("SHOWMETHEMONEY")) else if (stBuf == g_stAdminPagePassword) { if (!IsEmptyAdminPage()) { if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr))) { char szTmp[64]; snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr)); stResult += szTmp; } else { d->SetAdminMode(); stResult = "UNKNOWN"; } } else { d->SetAdminMode(); stResult = "UNKNOWN"; } } else if (!stBuf.compare("USER_COUNT")) { char szTmp[64]; if (!IsEmptyAdminPage()) { if (!IsAdminPage(inet_ntoa(d->GetAddr().sin_addr))) { snprintf(szTmp, sizeof(szTmp), "WEBADMIN : Wrong Connector : %s", inet_ntoa(d->GetAddr().sin_addr)); } else { int iTotal; int * paiEmpireUserCount; int iLocal; DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal); snprintf(szTmp, sizeof(szTmp), "%d %d %d %d %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal); } } else { int iTotal; int * paiEmpireUserCount; int iLocal; DESC_MANAGER::instance().GetUserCount(iTotal, &paiEmpireUserCount, iLocal); snprintf(szTmp, sizeof(szTmp), "%d %d %d %d %d", iTotal, paiEmpireUserCount[1], paiEmpireUserCount[2], paiEmpireUserCount[3], iLocal); } stResult += szTmp; } else if (!stBuf.compare("CHECK_P2P_CONNECTIONS")) { std::ostringstream oss(std::ostringstream::out); oss << "P2P CONNECTION NUMBER : " << P2P_MANAGER::instance().GetDescCount() << "\n"; std::string hostNames; P2P_MANAGER::Instance().GetP2PHostNames(hostNames); oss << hostNames; stResult = oss.str(); TPacketGGCheckAwakeness packet; packet.bHeader = HEADER_GG_CHECK_AWAKENESS; P2P_MANAGER::instance().Send(&packet, sizeof(packet)); } else if (!stBuf.compare("PACKET_INFO")) { m_pMainPacketInfo->Log("packet_info.txt"); stResult = "OK"; } else if (!stBuf.compare("PROFILE")) { CProfiler::instance().Log("profile.txt"); stResult = "OK"; } //gift notify delete command else if (!stBuf.compare(0,15,"DELETE_AWARDID ")) { char szTmp[64]; std::string msg = stBuf.substr(15,26); // item_award의 id범위? TPacketDeleteAwardID p; p.dwID = (DWORD)(atoi(msg.c_str())); snprintf(szTmp,sizeof(szTmp),"Sent to DB cache to delete ItemAward, id: %d",p.dwID); //sys_log(0,"%d",p.dwID); // strlcpymt(p.login, msg.c_str(), sizeof(p.login)); db_clientdesc->DBPacket(HEADER_GD_DELETE_AWARDID, 0, &p, sizeof(p)); stResult += szTmp; } else { stResult = "UNKNOWN"; if (d->IsAdminMode()) { // 어드민 명령들 if (!stBuf.compare(0, 7, "NOTICE ")) { std::string msg = stBuf.substr(7, 50); LogManager::instance().CharLog(0, 0, 0, 1, "NOTICE", msg.c_str(), d->GetHostName()); BroadcastNotice(msg.c_str()); } else if (!stBuf.compare("CLOSE_PASSPOD")) { g_bNoPasspod = true; stResult += "CLOSE_PASSPOD"; } else if (!stBuf.compare("OPEN_PASSPOD")) { g_bNoPasspod = false; stResult += "OPEN_PASSPOD"; } else if (!stBuf.compare("SHUTDOWN")) { LogManager::instance().CharLog(0, 0, 0, 2, "SHUTDOWN", "", d->GetHostName()); TPacketGGShutdown p; p.bHeader = HEADER_GG_SHUTDOWN; P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown)); sys_err("Accept shutdown command from %s.", d->GetHostName()); Shutdown(10); } else if (!stBuf.compare("SHUTDOWN_ONLY")) { LogManager::instance().CharLog(0, 0, 0, 2, "SHUTDOWN", "", d->GetHostName()); sys_err("Accept shutdown only command from %s.", d->GetHostName()); Shutdown(10); } else if (!stBuf.compare(0, 3, "DC ")) { std::string msg = stBuf.substr(3, LOGIN_MAX_LEN); dev_log(LOG_DEB0, "DC : '%s'", msg.c_str()); TPacketGGDisconnect pgg; pgg.bHeader = HEADER_GG_DISCONNECT; strlcpymt(pgg.szLogin, msg.c_str(), sizeof(pgg.szLogin)); P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGDisconnect)); // delete login key { TPacketDC p; strlcpymt(p.login, msg.c_str(), sizeof(p.login)); db_clientdesc->DBPacket(HEADER_GD_DC, 0, &p, sizeof(p)); } } else if (!stBuf.compare(0, 10, "RELOAD_CRC")) { LoadValidCRCList(); BYTE bHeader = HEADER_GG_RELOAD_CRC_LIST; P2P_MANAGER::instance().Send(&bHeader, sizeof(BYTE)); stResult = "OK"; } else if (!stBuf.compare(0, 20, "CHECK_CLIENT_VERSION")) { CheckClientVersion(); BYTE bHeader = HEADER_GG_CHECK_CLIENT_VERSION; P2P_MANAGER::instance().Send(&bHeader, sizeof(BYTE)); stResult = "OK"; } else if (!stBuf.compare(0, 6, "RELOAD")) { if (stBuf.size() == 6) { LoadStateUserCount(); db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0); DBManager::instance().LoadDBString(); } else { char c = stBuf[7]; switch (LOWER(c)) { case 'u': LoadStateUserCount(); break; case 'p': db_clientdesc->DBPacket(HEADER_GD_RELOAD_PROTO, 0, NULL, 0); break; case 's': DBManager::instance().LoadDBString(); break; case 'q': quest::CQuestManager::instance().Reload(); break; case 'f': fishing::Initialize(); break; case 'a': db_clientdesc->DBPacket(HEADER_GD_RELOAD_ADMIN, 0, NULL, 0); sys_log(0, "Reloading admin infomation."); break; } } } else if (!stBuf.compare(0, 6, "EVENT ")) { std::istringstream is(stBuf); std::string strEvent, strFlagName; long lValue; is >> strEvent >> strFlagName >> lValue; if (!is.fail()) { sys_log(0, "EXTERNAL EVENT FLAG name %s value %d", strFlagName.c_str(), lValue); quest::CQuestManager::instance().RequestSetEventFlag(strFlagName, lValue); stResult = "EVENT FLAG CHANGE "; stResult += strFlagName; } else { stResult = "EVENT FLAG FAIL"; } } // BLOCK_CHAT else if (!stBuf.compare(0, 11, "BLOCK_CHAT ")) { std::istringstream is(stBuf); std::string strBlockChat, strCharName; long lDuration; is >> strBlockChat >> strCharName >> lDuration; if (!is.fail()) { sys_log(0, "EXTERNAL BLOCK_CHAT name %s duration %d", strCharName.c_str(), lDuration); do_block_chat(NULL, const_cast<char*>(stBuf.c_str() + 11), 0, 0); stResult = "BLOCK_CHAT "; stResult += strCharName; } else { stResult = "BLOCK_CHAT FAIL"; } }
size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; const char *p = data, *pe; ssize_t to_read; enum state state = (enum state) parser->state; enum header_states header_state = (enum header_states) parser->header_state; size_t index = parser->index; size_t nread = parser->nread; if (len == 0) { if (state == s_body_identity_eof) { CALLBACK2(message_complete); } return 0; } if (parser->header_field_mark) parser->header_field_mark = data; if (parser->header_value_mark) parser->header_value_mark = data; if (parser->fragment_mark) parser->fragment_mark = data; if (parser->query_string_mark) parser->query_string_mark = data; if (parser->path_mark) parser->path_mark = data; if (parser->url_mark) parser->url_mark = data; for (p=data, pe=data+len; p != pe; p++) { ch = *p; if (++nread > HTTP_MAX_HEADER_SIZE && PARSING_HEADER(state)) { /* Buffer overflow attack */ goto error; } switch (state) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ goto error; case s_start_res: { parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); switch (ch) { case 'H': state = s_res_H; break; case CR: case LF: break; default: goto error; } break; } case s_res_H: STRICT_CHECK(ch != 'T'); state = s_res_HT; break; case s_res_HT: STRICT_CHECK(ch != 'T'); state = s_res_HTT; break; case s_res_HTT: STRICT_CHECK(ch != 'P'); state = s_res_HTTP; break; case s_res_HTTP: STRICT_CHECK(ch != '/'); state = s_res_first_http_major; break; case s_res_first_http_major: if (ch < '1' || ch > '9') goto error; parser->http_major = ch - '0'; state = s_res_http_major; break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { state = s_res_first_http_minor; break; } if (ch < '0' || ch > '9') goto error; parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) goto error; break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (ch < '0' || ch > '9') goto error; parser->http_minor = ch - '0'; state = s_res_http_minor; break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { state = s_res_first_status_code; break; } if (ch < '0' || ch > '9') goto error; parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) goto error; break; } case s_res_first_status_code: { if (ch < '0' || ch > '9') { if (ch == ' ') { break; } goto error; } parser->status_code = ch - '0'; state = s_res_status_code; break; } case s_res_status_code: { if (ch < '0' || ch > '9') { switch (ch) { case ' ': state = s_res_status; break; case CR: state = s_res_line_almost_done; break; case LF: state = s_header_field_start; break; default: goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (parser->status_code > 999) goto error; break; } case s_res_status: /* the human readable status. e.g. "NOT FOUND" * we are not humans so just ignore this */ if (ch == CR) { state = s_res_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); state = s_header_field_start; break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = -1; CALLBACK2(message_begin); if (ch < 'A' || 'Z' < ch) goto error; parser->method = (enum http_method) 0; index = 0; parser->buffer[0] = ch; state = s_req_method; break; } case s_req_method: if (ch == ' ') { assert(index+1 < HTTP_PARSER_MAX_METHOD_LEN); parser->buffer[index+1] = '\0'; switch (index+1) { case 3: if (ngx_str3_cmp(parser->buffer, 'G', 'E', 'T')) { parser->method = HTTP_GET; break; } if (ngx_str3_cmp(parser->buffer, 'P', 'U', 'T')) { parser->method = HTTP_PUT; break; } break; case 4: if (ngx_str4cmp(parser->buffer, 'P', 'O', 'S', 'T')) { parser->method = HTTP_POST; break; } if (ngx_str4cmp(parser->buffer, 'H', 'E', 'A', 'D')) { parser->method = HTTP_HEAD; break; } if (ngx_str4cmp(parser->buffer, 'C', 'O', 'P', 'Y')) { parser->method = HTTP_COPY; break; } if (ngx_str4cmp(parser->buffer, 'M', 'O', 'V', 'E')) { parser->method = HTTP_MOVE; break; } break; case 5: if (ngx_str5cmp(parser->buffer, 'M', 'K', 'C', 'O', 'L')) { parser->method = HTTP_MKCOL; break; } if (ngx_str5cmp(parser->buffer, 'T', 'R', 'A', 'C', 'E')) { parser->method = HTTP_TRACE; break; } break; case 6: if (ngx_str6cmp(parser->buffer, 'D', 'E', 'L', 'E', 'T', 'E')) { parser->method = HTTP_DELETE; break; } if (ngx_str6cmp(parser->buffer, 'U', 'N', 'L', 'O', 'C', 'K')) { parser->method = HTTP_UNLOCK; break; } break; case 7: if (ngx_str7_cmp(parser->buffer, 'O', 'P', 'T', 'I', 'O', 'N', 'S', '\0')) { parser->method = HTTP_OPTIONS; break; } if (ngx_str7_cmp(parser->buffer, 'C', 'O', 'N', 'N', 'E', 'C', 'T', '\0')) { parser->method = HTTP_CONNECT; break; } break; case 8: if (ngx_str8cmp(parser->buffer, 'P', 'R', 'O', 'P', 'F', 'I', 'N', 'D')) { parser->method = HTTP_PROPFIND; break; } break; case 9: if (ngx_str9cmp(parser->buffer, 'P', 'R', 'O', 'P', 'P', 'A', 'T', 'C', 'H')) { parser->method = HTTP_PROPPATCH; break; } break; } state = s_req_spaces_before_url; break; } if (ch < 'A' || 'Z' < ch) goto error; if (++index >= HTTP_PARSER_MAX_METHOD_LEN - 1) { goto error; } parser->buffer[index] = ch; break; case s_req_spaces_before_url: { if (ch == ' ') break; if (ch == '/') { MARK(url); MARK(path); state = s_req_path; break; } c = LOWER(ch); if (c >= 'a' && c <= 'z') { MARK(url); state = s_req_schema; break; } goto error; } case s_req_schema: { c = LOWER(ch); if (c >= 'a' && c <= 'z') break; if (ch == ':') { state = s_req_schema_slash; break; } goto error; } case s_req_schema_slash: STRICT_CHECK(ch != '/'); state = s_req_schema_slash_slash; break; case s_req_schema_slash_slash: STRICT_CHECK(ch != '/'); state = s_req_host; break; case s_req_host: { c = LOWER(ch); if (c >= 'a' && c <= 'z') break; if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') break; switch (ch) { case ':': state = s_req_port; break; case '/': MARK(path); state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; default: goto error; } break; } case s_req_port: { if (ch >= '0' && ch <= '9') break; switch (ch) { case '/': MARK(path); state = s_req_path; break; case ' ': /* The request line looks like: * "GET http://foo.bar.com:1234 HTTP/1.1" * That is, there is no path. */ CALLBACK(url); state = s_req_http_start; break; default: goto error; } break; } case s_req_path: { if (USUAL(ch)) break; switch (ch) { case ' ': CALLBACK(url); CALLBACK(path); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(path); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(path); parser->http_minor = 9; state = s_header_field_start; break; case '?': CALLBACK(path); state = s_req_query_string_start; break; case '#': CALLBACK(path); state = s_req_fragment_start; break; default: goto error; } break; } case s_req_query_string_start: { if (USUAL(ch)) { MARK(query_string); state = s_req_query_string; break; } switch (ch) { case '?': break; // XXX ignore extra '?' ... is this right? case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_minor = 9; state = s_header_field_start; break; case '#': state = s_req_fragment_start; break; default: goto error; } break; } case s_req_query_string: { if (USUAL(ch)) break; switch (ch) { case '?': // allow extra '?' in query string break; case ' ': CALLBACK(url); CALLBACK(query_string); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(query_string); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(query_string); parser->http_minor = 9; state = s_header_field_start; break; case '#': CALLBACK(query_string); state = s_req_fragment_start; break; default: goto error; } break; } case s_req_fragment_start: { if (USUAL(ch)) { MARK(fragment); state = s_req_fragment; break; } switch (ch) { case ' ': CALLBACK(url); state = s_req_http_start; break; case CR: CALLBACK(url); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); parser->http_minor = 9; state = s_header_field_start; break; case '?': MARK(fragment); state = s_req_fragment; break; case '#': break; default: goto error; } break; } case s_req_fragment: { if (USUAL(ch)) break; switch (ch) { case ' ': CALLBACK(url); CALLBACK(fragment); state = s_req_http_start; break; case CR: CALLBACK(url); CALLBACK(fragment); parser->http_minor = 9; state = s_req_line_almost_done; break; case LF: CALLBACK(url); CALLBACK(fragment); parser->http_minor = 9; state = s_header_field_start; break; case '?': case '#': break; default: goto error; } break; } case s_req_http_start: switch (ch) { case 'H': state = s_req_http_H; break; case ' ': break; default: goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); state = s_req_http_HT; break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); state = s_req_http_HTT; break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); state = s_req_http_HTTP; break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); state = s_req_first_http_major; break; /* first digit of major HTTP version */ case s_req_first_http_major: if (ch < '1' || ch > '9') goto error; parser->http_major = ch - '0'; state = s_req_http_major; break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { state = s_req_first_http_minor; break; } if (ch < '0' || ch > '9') goto error; parser->http_major *= 10; parser->http_major += ch - '0'; if (parser->http_major > 999) goto error; break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (ch < '0' || ch > '9') goto error; parser->http_minor = ch - '0'; state = s_req_http_minor; break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { state = s_req_line_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } /* XXX allow spaces after digit? */ if (ch < '0' || ch > '9') goto error; parser->http_minor *= 10; parser->http_minor += ch - '0'; if (parser->http_minor > 999) goto error; break; } /* end of request line */ case s_req_line_almost_done: { if (ch != LF) goto error; state = s_header_field_start; break; } case s_header_field_start: { if (ch == CR) { state = s_headers_almost_done; break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ state = s_headers_almost_done; goto headers_almost_done; } c = LOWER(ch); if (c < 'a' || 'z' < c) goto error; MARK(header_field); index = 0; state = s_header_field; switch (c) { case 'c': header_state = h_C; break; case 'p': header_state = h_matching_proxy_connection; break; case 't': header_state = h_matching_transfer_encoding; break; case 'u': header_state = h_matching_upgrade; break; default: header_state = h_general; break; } break; } case s_header_field: { c = lowcase[(int)ch]; if (c) { switch (header_state) { case h_general: break; case h_C: index++; header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: index++; header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: index++; switch (c) { case 'n': header_state = h_matching_connection; break; case 't': header_state = h_matching_content_length; break; default: header_state = h_general; break; } break; /* connection */ case h_matching_connection: index++; if (index > sizeof(CONNECTION)-1 || c != CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(CONNECTION)-2) { header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: index++; if (index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[index]) { header_state = h_general; } else if (index == sizeof(PROXY_CONNECTION)-2) { header_state = h_connection; } break; /* content-length */ case h_matching_content_length: index++; if (index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[index]) { header_state = h_general; } else if (index == sizeof(CONTENT_LENGTH)-2) { header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: index++; if (index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[index]) { header_state = h_general; } else if (index == sizeof(TRANSFER_ENCODING)-2) { header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: index++; if (index > sizeof(UPGRADE)-1 || c != UPGRADE[index]) { header_state = h_general; } else if (index == sizeof(UPGRADE)-2) { header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } break; } if (ch == ':') { CALLBACK(header_field); state = s_header_value_start; break; } if (ch == CR) { state = s_header_almost_done; CALLBACK(header_field); break; } if (ch == LF) { CALLBACK(header_field); state = s_header_field_start; break; } goto error; } case s_header_value_start: { if (ch == ' ') break; MARK(header_value); state = s_header_value; index = 0; c = lowcase[(int)ch]; if (!c) { if (ch == CR) { header_state = h_general; state = s_header_almost_done; break; } if (ch == LF) { state = s_header_field_start; break; } header_state = h_general; break; } switch (header_state) { case h_upgrade: parser->flags |= F_UPGRADE; header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { header_state = h_matching_transfer_encoding_chunked; } else { header_state = h_general; } break; case h_content_length: if (ch < '0' || ch > '9') goto error; parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { header_state = h_matching_connection_close; } else { header_state = h_general; } break; default: header_state = h_general; break; } break; } case s_header_value: { c = lowcase[(int)ch]; if (!c) { if (ch == CR) { CALLBACK(header_value); state = s_header_almost_done; break; } if (ch == LF) { CALLBACK(header_value); goto header_almost_done; } break; } switch (header_state) { case h_general: break; case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: if (ch < '0' || ch > '9') goto error; parser->content_length *= 10; parser->content_length += ch - '0'; break; /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: index++; if (index > sizeof(CHUNKED)-1 || c != CHUNKED[index]) { header_state = h_general; } else if (index == sizeof(CHUNKED)-2) { header_state = h_transfer_encoding_chunked; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: index++; if (index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[index]) { header_state = h_general; } else if (index == sizeof(KEEP_ALIVE)-2) { header_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: index++; if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { header_state = h_general; } else if (index == sizeof(CLOSE)-2) { header_state = h_connection_close; } break; case h_transfer_encoding_chunked: case h_connection_keep_alive: case h_connection_close: if (ch != ' ') header_state = h_general; break; default: state = s_header_value; header_state = h_general; break; } break; } case s_header_almost_done: header_almost_done: { STRICT_CHECK(ch != LF); state = s_header_field_start; switch (header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } break; } case s_headers_almost_done: headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ CALLBACK2(message_complete); state = NEW_MESSAGE(); break; } parser->body_read = 0; nread = 0; if (parser->flags & F_UPGRADE) parser->upgrade = 1; CALLBACK2(headers_complete); // Exit, the rest of the connect is in a different protocol. if (parser->flags & F_UPGRADE) { CALLBACK2(message_complete); return (p - data); } if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ state = s_chunk_size_start; } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else if (parser->content_length > 0) { /* Content-Length header given and non-zero */ state = s_body_identity; } else { if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { /* Assume content-length 0 - read the next */ CALLBACK2(message_complete); state = NEW_MESSAGE(); } else { /* Read body until EOF */ state = s_body_identity_eof; } } } break; } case s_body_identity: to_read = MIN(pe - p, (ssize_t)(parser->content_length - parser->body_read)); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; parser->body_read += to_read; if (parser->body_read == parser->content_length) { CALLBACK2(message_complete); state = NEW_MESSAGE(); } } break; /* read until EOF */ case s_body_identity_eof: to_read = pe - p; if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; parser->body_read += to_read; } break; case s_chunk_size_start: { assert(parser->flags & F_CHUNKED); c = unhex[(int)ch]; if (c == -1) goto error; parser->content_length = c; state = s_chunk_size; break; } case s_chunk_size: { assert(parser->flags & F_CHUNKED); if (ch == CR) { state = s_chunk_size_almost_done; break; } c = unhex[(int)ch]; if (c == -1) { if (ch == ';' || ch == ' ') { state = s_chunk_parameters; break; } goto error; } parser->content_length *= 16; parser->content_length += c; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { state = s_chunk_size_almost_done; break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); if (parser->content_length == 0) { parser->flags |= F_TRAILING; state = s_header_field_start; } else { state = s_chunk_data; } break; } case s_chunk_data: { assert(parser->flags & F_CHUNKED); to_read = MIN(pe - p, (ssize_t)(parser->content_length)); if (to_read > 0) { if (settings->on_body) settings->on_body(parser, p, to_read); p += to_read - 1; } if (to_read == parser->content_length) { state = s_chunk_data_almost_done; } parser->content_length -= to_read; break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != CR); state = s_chunk_data_done; break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); state = s_chunk_size_start; break; default: assert(0 && "unhandled state"); goto error; } } CALLBACK_NOCLEAR(header_field); CALLBACK_NOCLEAR(header_value); CALLBACK_NOCLEAR(fragment); CALLBACK_NOCLEAR(query_string); CALLBACK_NOCLEAR(path); CALLBACK_NOCLEAR(url); parser->state = state; parser->header_state = header_state; parser->index = index; parser->nread = nread; return len; error: return (p - data); }
/** process_3a_data: * * Arguments: * @p_ae_params : ptr to aec data * * Return : int32_t type of status * NO_ERROR -- success * none-zero failure code * * Description: * process 3a data * * Notes: this needs to be filled for the metadata **/ int process_3a_data(cam_ae_params_t *p_ae_params, cam_awb_params_t *p_awb_params, cam_auto_focus_data_t *p_focus_data, QOMX_EXIF_INFO *exif_info) { int rc = 0; srat_t val_srat; rat_t val_rat; double shutter_speed_value; uint16_t aaa_exif_buff[AAA_EXIF_BUF_SIZE]; uint32_t exif_byte_cnt = 0; memset(aaa_exif_buff, 0x0, sizeof(aaa_exif_buff)); if (NULL == p_ae_params) { ALOGE("%s %d: AE params are null", __func__, __LINE__); /* increment exif_byte_cnt, so that this info will be filled with 0s */ exif_byte_cnt += AE_EXIF_SIZE; } else { ALOGE("%s:%d] exp_time %f, iso_value %d exp idx: %d, lc: %d, gain: %f", __func__, __LINE__, p_ae_params->exp_time, p_ae_params->iso_value, p_ae_params->exp_index, p_ae_params->line_count, p_ae_params->real_gain); /* Exposure time */ if (0.0f >= p_ae_params->exp_time) { val_rat.num = 0; val_rat.denom = 0; } else { val_rat.num = 1; val_rat.denom = ROUND(1.0/p_ae_params->exp_time); } CDBG_HIGH("%s: numer %d denom %d", __func__, val_rat.num, val_rat.denom ); rc = addExifEntry(exif_info, EXIFTAGID_EXPOSURE_TIME, EXIF_RATIONAL, (sizeof(val_rat)/(8)), &val_rat); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Exposure time", __func__, __LINE__); } /* Shutter Speed*/ if (p_ae_params->exp_time > 0) { shutter_speed_value = log10(1/p_ae_params->exp_time)/log10(2); val_srat.num = (int32_t)(shutter_speed_value * 1000.0f); val_srat.denom = 1000; } else { val_srat.num = 0; val_srat.denom = 0; } rc = addExifEntry(exif_info, EXIFTAGID_SHUTTER_SPEED, EXIF_SRATIONAL, (sizeof(val_srat)/(8)), &val_srat); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry", __func__, __LINE__); } /* ISO */ short val_short; val_short = (short) p_ae_params->iso_value; rc = addExifEntry(exif_info, EXIFTAGID_ISO_SPEED_RATING, EXIF_SHORT, sizeof(val_short)/2, &val_short); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry ISO", __func__, __LINE__); } /* Gain */ val_short = (short) p_ae_params->real_gain; rc = addExifEntry(exif_info, EXIFTAGID_GAIN_CONTROL, EXIF_SHORT, sizeof(val_short)/2, &val_short); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Gain", __func__, __LINE__); } /* Exposure Index */ val_rat.num = p_ae_params->exp_index; val_rat.denom = 1; CDBG_HIGH("%s: numer %d denom %d", __func__, val_rat.num, val_rat.denom ); rc = addExifEntry(exif_info, EXIFTAGID_EXPOSURE_INDEX, EXIF_RATIONAL, (sizeof(val_rat)/(8)), &val_rat); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Exposure Index", __func__, __LINE__); } /* AE line count */ aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(LOWER(p_ae_params->line_count)); aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(UPPER(p_ae_params->line_count)); /* Metering Mode */ val_short = (unsigned short) p_ae_params->metering_mode; rc = addExifEntry(exif_info,EXIFTAGID_METERING_MODE, EXIF_SHORT, sizeof(val_short)/2, &val_short); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Metering mode", __func__, __LINE__); } /*Exposure Program*/ val_short = (unsigned short) p_ae_params->exposure_program; rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_PROGRAM, EXIF_SHORT, sizeof(val_short)/2, &val_short); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Exposure program", __func__, __LINE__); } /*Exposure Mode */ val_short = (unsigned short) p_ae_params->exposure_mode; rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_MODE, EXIF_SHORT, sizeof(val_short)/2, &val_short); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Exposure Mode", __func__, __LINE__); } /*Scenetype*/ uint8_t val_undef; val_undef = (uint8_t) p_ae_params->scenetype; rc = addExifEntry(exif_info,EXIFTAGID_SCENE_TYPE, EXIF_UNDEFINED, sizeof(val_undef), &val_undef); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Scene type", __func__, __LINE__); } /* Brightness Value*/ val_srat.num = p_ae_params->brightness*100; val_srat.denom = 100; rc = addExifEntry(exif_info,EXIFTAGID_BRIGHTNESS, EXIF_SRATIONAL, (sizeof(val_srat)/(8)), &val_srat); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Brightness value", __func__, __LINE__); } } if (NULL == p_awb_params) { ALOGE("%s %d: AWB params are null", __func__, __LINE__); /* increment exif_byte_cnt, so that this info will be filled with 0s */ exif_byte_cnt += AWB_EXIF_SIZE; } else { aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(LOWER(p_awb_params->cct_value)); aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(UPPER(p_awb_params->cct_value)); aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(LOWER(p_awb_params->decision)); aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(UPPER(p_awb_params->decision)); } if (NULL == p_focus_data) { ALOGE("%s %d: AF params are null", __func__, __LINE__); /* increment exif_byte_cnt, so that this info will be filled with 0s */ exif_byte_cnt += AF_EXIF_SIZE; } else { aaa_exif_buff[exif_byte_cnt++] = CHANGE_ENDIAN_16(LOWER(p_focus_data->focus_pos)); aaa_exif_buff[exif_byte_cnt] = CHANGE_ENDIAN_16(UPPER(p_focus_data->focus_pos)); } /* Add to exif data */ rc = addExifEntry(exif_info, EXIFTAGID_EXIF_MAKER_NOTE, EXIF_UNDEFINED, (exif_byte_cnt * 2), aaa_exif_buff); if (rc) { ALOGE("%s:%d]: Error adding Exif Entry Maker note", __func__, __LINE__); } return rc; }
bool check_total_bans( DESCRIPTOR_DATA * d ) { BAN_DATA *pban; char new_host[MAX_STRING_LENGTH]; int i; for( i = 0; i < ( int )strlen( d->host ); i++ ) new_host[i] = LOWER( d->host[i] ); new_host[i] = '\0'; for( pban = first_ban; pban; pban = pban->next ) { if( pban->level != LEVEL_SUPREME ) continue; if( pban->prefix && pban->suffix && strstr( new_host, pban->name ) ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_SITE ); save_banlist( ); return FALSE; } else return TRUE; } /* * Bug of switched checks noticed by Cronel */ if( pban->suffix && !str_prefix( pban->name, new_host ) ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_SITE ); save_banlist( ); return FALSE; } else return TRUE; } if( pban->prefix && !str_suffix( pban->name, new_host ) ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_SITE ); save_banlist( ); return FALSE; } else return TRUE; } if( !str_cmp( pban->name, new_host ) ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_SITE ); save_banlist( ); return FALSE; } else return TRUE; } } return FALSE; }
bool check_bans( CHAR_DATA * ch, int type ) { BAN_DATA *pban; char new_host[MAX_STRING_LENGTH]; int i; bool fMatch = FALSE; switch ( type ) { case BAN_RACE: pban = first_ban_race; break; case BAN_CLASS: pban = first_ban_class; break; case BAN_SITE: pban = first_ban; for( i = 0; i < ( int )( strlen( ch->desc->host ) ); i++ ) new_host[i] = LOWER( ch->desc->host[i] ); new_host[i] = '\0'; break; default: bug( "Ban type in check_bans: %d.", type ); return FALSE; } for( ; pban; pban = pban->next ) { if( type == BAN_CLASS && pban->flag == ch->Class ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_CLASS ); save_banlist( ); return FALSE; } if( ch->level > pban->level ) { if( pban->warn ) { log_printf_plus( LOG_WARN, sysdata.log_level, "%s class logging in from %s.", pban->name, ch->desc->host ); } return FALSE; } else return TRUE; } if( type == BAN_RACE && pban->flag == ch->race ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_RACE ); save_banlist( ); return FALSE; } if( ch->level > pban->level ) { if( pban->warn ) { log_printf_plus( LOG_WARN, sysdata.log_level, "%s race logging in from %s.", pban->name, ch->desc->host ); } return FALSE; } else return TRUE; } if( type == BAN_SITE ) { if( pban->prefix && pban->suffix && strstr( new_host, pban->name ) ) fMatch = TRUE; else if( pban->prefix && !str_suffix( pban->name, new_host ) ) fMatch = TRUE; else if( pban->suffix && !str_prefix( pban->name, new_host ) ) fMatch = TRUE; else if( !str_cmp( pban->name, new_host ) ) fMatch = TRUE; if( fMatch ) { if( check_expire( pban ) ) { dispose_ban( pban, BAN_SITE ); save_banlist( ); return FALSE; } if( ch->level > pban->level ) { if( pban->warn ) { log_printf_plus( LOG_WARN, sysdata.log_level, "%s logging in from site %s.", ch->name, ch->desc->host ); } return FALSE; } else return TRUE; } } } return FALSE; }
static opk_status_t boxsteplimits(opk_vspace_t* space, double* smin1, double* smin2, double* smax, const opk_vector_t* xvec, const void* lower, const void* upper, int bound, const opk_vector_t* dvec, int orient) { const REAL* x = DATA(xvec); const REAL* d = DATA(dvec); const REAL* xl; const REAL* xu; const REAL inf = FLOAT_CHOICE(FLT_MAX, DBL_MAX); REAL a, b; REAL s, s1, s2, s3; opk_index_t i, n; #define VALUE(addr) (*((double*)(addr))) #define BOXED(lo, hi) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p > 0) { \ s = (hi - x[i])/p; \ } else if (p < 0) { \ s = (lo - x[i])/p; \ } else { \ continue; \ } \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } \ } else { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p < 0) { \ s = (x[i] - hi)/p; \ } else if (p > 0) { \ s = (x[i] - lo)/p; \ } else { \ continue; \ } \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } \ } #define LOWER(lo) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p < 0) { \ s = (lo - x[i])/p; \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } else if (p > 0) { \ s3 = inf; \ } \ } \ } else { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p > 0) { \ s = (x[i] - lo)/p; \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } else if (p < 0) { \ s3 = inf; \ } \ } \ } #define UPPER(hi) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p > 0) { \ s = (hi - x[i])/p; \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } else if (p < 0) { \ s3 = inf; \ } \ } \ } else { \ for (i = 0; i < n; ++i) { \ REAL p = d[i]; \ if (p < 0) { \ s = (x[i] - hi)/p; \ if (s < s1) s1 = s; \ if (s < s2 && s > 0) s2 = s; \ if (s > s3) s3 = s; \ } else if (p > 0) { \ s3 = inf; \ } \ } \ } /* Find the step limits. */ n = space->size; s1 = inf; s2 = inf; switch (bound) { case 0: s3 = inf; break; case 1: s3 = 0; a = VALUE(lower); LOWER(a); break; case 2: s3 = 0; xl = DATA(lower); LOWER(xl[i]); break; case 3: s3 = 0; b = VALUE(upper); UPPER(b); break; case 4: s3 = 0; a = VALUE(lower); b = VALUE(upper); BOXED(a, b); break; case 5: s3 = 0; xl = DATA(lower); b = VALUE(upper); BOXED(xl[i], b); break; case 6: s3 = 0; xu = DATA(upper); UPPER(xu[i]); break; case 7: s3 = 0; a = VALUE(lower); xu = DATA(upper); BOXED(a, xu[i]); break; case 8: s3 = 0; xl = DATA(lower); xu = DATA(upper); BOXED(xl[i], xu[i]); break; } #undef LOWER #undef UPPER #undef BOXED #undef VALUE if (smin1 != NULL) *smin1 = s1; if (smin2 != NULL) *smin2 = s2; if (smax != NULL) *smax = s3; return OPK_SUCCESS; }
static opk_status_t boxfreevar(opk_vspace_t* space, opk_vector_t* dstvec, const opk_vector_t* srcvec, const void* lower, const void* upper, int bound, const opk_vector_t* dirvec, int orient) { REAL* dst = DATA(dstvec); const REAL* x = DATA(srcvec); const REAL* d = DATA(dirvec); const REAL* xl; const REAL* xu; REAL a, b; opk_index_t i, n = space->size; #define VALUE(addr) (*((double*)(addr))) #define BOXED(lo, hi) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] < 0 ? (x[i] > lo ? 1 : 0) : \ ( d[i] > 0 ? (x[i] < hi ? 1 : 0) : 0); \ } \ } else { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] > 0 ? (x[i] > lo ? 1 : 0) : \ ( d[i] < 0 ? (x[i] < hi ? 1 : 0) : 0); \ } \ } #define LOWER(lo) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] < 0 ? (x[i] > lo ? 1 : 0) : \ ( d[i] > 0 ? 1 : 0); \ } \ } else { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] > 0 ? (x[i] > lo ? 1 : 0) : \ ( d[i] < 0 ? 1 : 0); \ } \ } #define UPPER(hi) \ if (orient > 0) { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] < 0 ? 1 : \ ( d[i] > 0 ? (x[i] < hi ? 1 : 0) : 0); \ } \ } else { \ for (i = 0; i < n; ++i) { \ dst[i] = d[i] > 0 ? 1 : \ ( d[i] < 0 ? (x[i] < hi ? 1 : 0) : 0); \ } \ } switch (bound) { case 0: for (i = 0; i < n; ++i) { dst[i] = 1; } break; case 1: a = VALUE(lower); LOWER(a); break; case 2: xl = DATA(lower); LOWER(xl[i]); break; case 3: b = VALUE(upper); UPPER(b); break; case 4: a = VALUE(lower); b = VALUE(upper); BOXED(a, b); break; case 5: xl = DATA(lower); b = VALUE(upper); BOXED(xl[i], b); break; case 6: xu = DATA(upper); UPPER(xu[i]); break; case 7: a = VALUE(lower); xu = DATA(upper); BOXED(a, xu[i]); break; case 8: xl = DATA(lower); xu = DATA(upper); BOXED(xl[i], xu[i]); break; } #undef LOWER #undef UPPER #undef BOXED #undef VALUE return OPK_SUCCESS; }
void to_lower(char *buf) { int i; for(i = 0; buf[i]; ++i) buf[i] = LOWER(buf[i]); }
/* * The main entry point for executing commands. * Can be recursively called from 'at', 'order', 'force'. */ void interpret( CHAR_DATA * ch, const char *argument ) { char command[MAX_INPUT_LENGTH]; char logline[MAX_INPUT_LENGTH]; char logname[MAX_INPUT_LENGTH]; TIMER *timer = NULL; CMDTYPE *cmd = NULL; int trust; int loglvl; bool found; struct timeval time_used; long tmptime; if( !ch ) { bug( "interpret: null ch!", 0 ); return; } found = FALSE; if( ch->substate == SUB_REPEATCMD ) { DO_FUN *fun; if( ( fun = ch->last_cmd ) == NULL ) { ch->substate = SUB_NONE; bug( "interpret: SUB_REPEATCMD with NULL last_cmd", 0 ); return; } else { int x; /* * yes... we lose out on the hashing speediness here... * but the only REPEATCMDS are wizcommands (currently) */ for( x = 0; x < 126; x++ ) { for( cmd = command_hash[x]; cmd; cmd = cmd->next ) if( cmd->do_fun == fun ) { found = TRUE; break; } if( found ) break; } if( !found ) { cmd = NULL; bug( "interpret: SUB_REPEATCMD: last_cmd invalid", 0 ); return; } sprintf( logline, "(%s) %s", cmd->name, argument ); } } if( !cmd ) { /* * Changed the order of these ifchecks to prevent crashing. */ if( !argument || !strcmp( argument, "" ) ) { bug( "interpret: null argument!", 0 ); return; } /* * Strip leading spaces. */ while( isspace( *argument ) ) argument++; if( argument[0] == '\0' ) return; timer = get_timerptr( ch, TIMER_DO_FUN ); /* * REMOVE_BIT( ch->affected_by, AFF_HIDE ); */ /* * Implement freeze command. */ if( !IS_NPC( ch ) && IS_SET( ch->act, PLR_FREEZE ) ) { send_to_char( "You're totally frozen!\r\n", ch ); return; } /* * Grab the command word. * Special parsing so ' can be a command, * also no spaces needed after punctuation. */ strcpy( logline, argument ); if( !isalpha( argument[0] ) && !isdigit( argument[0] ) ) { command[0] = argument[0]; command[1] = '\0'; argument++; while( isspace( *argument ) ) argument++; } else argument = one_argument( argument, command ); /* * Look for command in command table. * Check for council powers and/or bestowments */ trust = get_trust( ch ); for( cmd = command_hash[LOWER( command[0] ) % 126]; cmd; cmd = cmd->next ) if( !str_prefix( command, cmd->name ) && ( cmd->level <= trust || ( !IS_NPC( ch ) && ch->pcdata->bestowments && ch->pcdata->bestowments[0] != '\0' && is_name( cmd->name, ch->pcdata->bestowments ) && cmd->level <= ( trust + 5 ) ) ) ) { found = TRUE; break; } /* * Turn off afk bit when any command performed. */ if( !IS_NPC( ch ) && IS_SET( ch->act, PLR_AFK ) && ( str_cmp( command, "AFK" ) ) ) { REMOVE_BIT( ch->act, PLR_AFK ); act( AT_GREY, "$n is no longer afk.", ch, NULL, NULL, TO_ROOM ); } } /* * Log and snoop. */ sprintf( lastplayercmd, "** %s: %s", ch->name, logline ); if( found && cmd->log == LOG_NEVER ) strcpy( logline, "XXXXXXXX XXXXXXXX XXXXXXXX" ); loglvl = found ? cmd->log : LOG_NORMAL; if( ( !IS_NPC( ch ) && IS_SET( ch->act, PLR_LOG ) ) || fLogAll || loglvl == LOG_BUILD || loglvl == LOG_HIGH || loglvl == LOG_ALWAYS ) { /* * Added by Narn to show who is switched into a mob that executes * a logged command. Check for descriptor in case force is used. */ if( ch->desc && ch->desc->original ) sprintf( log_buf, "Log %s (%s): %s", ch->name, ch->desc->original->name, logline ); else sprintf( log_buf, "Log %s: %s", ch->name, logline ); /* * Make it so a 'log all' will send most output to the log * file only, and not spam the log channel to death -Thoric */ if( fLogAll && loglvl == LOG_NORMAL && ( IS_NPC( ch ) || !IS_SET( ch->act, PLR_LOG ) ) ) loglvl = LOG_ALL; /* * This is handled in get_trust already */ /* if ( ch->desc && ch->desc->original ) log_string_plus( log_buf, loglvl, ch->desc->original->level ); else*/ log_string_plus( log_buf, loglvl, get_trust( ch ) ); } if( ch->desc && ch->desc->snoop_by ) { sprintf( logname, "%s", ch->name ); write_to_buffer( ch->desc->snoop_by, logname, 0 ); write_to_buffer( ch->desc->snoop_by, "% ", 2 ); write_to_buffer( ch->desc->snoop_by, logline, 0 ); write_to_buffer( ch->desc->snoop_by, "\r\n", 2 ); } if( timer ) { int tempsub; tempsub = ch->substate; ch->substate = SUB_TIMER_DO_ABORT; ( timer->do_fun ) ( ch, "" ); if( char_died( ch ) ) return; if( ch->substate != SUB_TIMER_CANT_ABORT ) { ch->substate = tempsub; extract_timer( ch, timer ); } else { ch->substate = tempsub; return; } } /* * Look for command in skill and socials table. */ if( !found ) { if( !check_skill( ch, command, argument ) && !check_social( ch, command, argument ) #ifdef IMC && !imc_command_hook( ch, command, argument ) #endif ) { EXIT_DATA *pexit; /* * check for an auto-matic exit command */ if( ( pexit = find_door( ch, command, TRUE ) ) != NULL && IS_SET( pexit->exit_info, EX_xAUTO ) ) { if( IS_SET( pexit->exit_info, EX_CLOSED ) && ( !IS_AFFECTED( ch, AFF_PASS_DOOR ) || IS_SET( pexit->exit_info, EX_NOPASSDOOR ) ) ) { if( !IS_SET( pexit->exit_info, EX_SECRET ) ) act( AT_PLAIN, "The $d is closed.", ch, NULL, pexit->keyword, TO_CHAR ); else send_to_char( "You cannot do that here.\r\n", ch ); return; } move_char( ch, pexit, 0 ); return; } send_to_char( "Huh?\r\n", ch ); } return; } /* * Character not in position for command? */ if( !check_pos( ch, cmd->position ) ) return; /* * Berserk check for flee.. maybe add drunk to this?.. but too much * hardcoding is annoying.. -- Altrag */ if( !str_cmp( cmd->name, "flee" ) && IS_AFFECTED( ch, AFF_BERSERK ) ) { send_to_char( "You aren't thinking very clearly..\r\n", ch ); return; } /* * Dispatch the command. */ ch->prev_cmd = ch->last_cmd; /* haus, for automapping */ ch->last_cmd = cmd->do_fun; start_timer( &time_used ); ( *cmd->do_fun ) ( ch, argument ); end_timer( &time_used ); /* * Update the record of how many times this command has been used (haus) */ update_userec( &time_used, &cmd->userec ); tmptime = UMIN( time_used.tv_sec, 19 ) * 1000000 + time_used.tv_usec; /* * laggy command notice: command took longer than 1.5 seconds */ if( tmptime > 1500000 ) { sprintf( log_buf, "[*****] LAG: %s: %s %s (R:%d S:%d.%06d)", ch->name, cmd->name, ( cmd->log == LOG_NEVER ? "XXX" : argument ), ch->in_room ? ch->in_room->vnum : 0, ( int )( time_used.tv_sec ), ( int )( time_used.tv_usec ) ); log_string_plus( log_buf, LOG_NORMAL, get_trust( ch ) ); } tail_chain( ); }
//////// NON-KINGDOM SPECIFIC CODE //////// char *str_sep(char *str, char *sep) { char buf[MAX_STRING_LENGTH]; long addlen = 0; long lensep; long lenstr; long i; long k; long compare; long beginning; if(str == 0 || sep == 0) return 0; lensep = strlen(sep); lenstr = strlen(str); for(i = 0, compare = 0, beginning = 0; i < lenstr; i++) { if(LOWER(str[i]) == LOWER(sep[compare])) { if(compare == 0) { if( i == 0 ) { beginning = i; } else { beginning = i-1; // get rid of space behind name addlen = 1; } } if(++compare == lensep) break; } else { compare = 0; beginning = 0; } } lensep += addlen; if(compare > 0 && compare == lensep) { for(i = 0, k = 0; i < lenstr; i++) { if(i < beginning || i > (beginning + lensep - 1)) buf[k++] = str[i]; } buf[k] = '\0'; if(strlen(buf) <= 3) { log_string(buf); return str_dup(""); } return str_dup(buf); } return 0; }