/* * return true, if have something needed to send * you need to delete readbuffer if not use anymore; */ void MmsServer::JsonProcess(int fd, fastbuffer * readbuffer, YYLibMysql * mysql) { if (fd <= 0 || !readbuffer) return; fastbuffer * buf = NULL; Item_data_ptr state = get_state(fd); if (state) { if (state->readbuffer) { state->readbuffer->append(readbuffer->buf(), readbuffer->size()); } else { state->readbuffer = readbuffer; readbuffer = NULL; } buf = state->readbuffer; } else { buf = readbuffer; } // json process YYJ * jobj; do { int offset = 0; jobj = NULL; YYMMSJSON_ERROR err; err = YYmmsJson::ParseCmd(buf->buf(), buf->size(), offset, jobj); switch (err) { case YYMMSJSON_ERROR_SUCCESS: { if (jobj->_id == YY_JSON_LOGIN) { // check user account YYJson_Login * login = (YYJson_Login*)jobj; if (!state) { state = boost::shared_ptr<Item_data>(new Item_data); if (!state) break; state->fd = fd; state->readbuffer = readbuffer; readbuffer = NULL; add_state(fd, state); _userData.add_state(login->yyID, state); } state->yyID = login->yyID; state->token = login->token; state->rsaStr = login->rsakey; std::string prik; state->rsa.SetRSAKey(state->rsaStr, prik); state->loginTime = GetTickCount(); LoginCmd(fd, state, mysql); } else { if (!state) { LOG::Info("YY_JSON_LOGIN not login fd=%d", fd); break; } NextRun: switch (jobj->_id) { case YY_JSON_COMPRESS_RSA: { assert(false); } break; case YY_JSON_COMPRESS_AES: { YYJson_Comp_AES * cmd = (YYJson_Comp_AES*)jobj; YYJ * realobj; if (!cmd->UnFormat(state->aes, realobj)) break; YYmmsJson::FreeCmd(jobj); jobj = realobj; goto NextRun; } break; case YY_JSON_LOGIN1: { YYJson_Login1 * cmd = (YYJson_Login1*)jobj; state->uid = cmd->uid; state->account = cmd->user; state->pwd = cmd->pwd; YYJson_Login1_res resp; resp.bSucc = true; _sendCmd(fd, &resp); } break; case YY_JSON_LOGOUT: { LOG::Info("YY_JSON_LOGIN logout fd=%d, uid=%u, account:%s, logintime=%u, logouttime=%u", fd, state->uid, state->account.c_str(), state->loginTime, GetTickCount()); YYJson_Logout_res resp; resp.yyID = state->yyID; _sendCmd(fd, &resp); ShellExit(state); _userData.del_state(state->yyID); del_state(fd); } break; case YY_JSON_OPENURL: { YYJson_OpenUrl * cmd = (YYJson_OpenUrl*)jobj; state->channelID = cmd->channelID; state->subChannelID = cmd->subChannelID; state->url = cmd->url; bool bSucc = true; if (state->isConnectShellClient()) openURL(state->shellClient_fd, state); else { bSucc = ShellExec(state); } YYJson_OpenUrl_res resp; resp.bSucc = (json_bool)bSucc; _sendCmd(fd, &resp); } break; } // LOG::Info("json %s", json_object_to_json_string(jobj->_jobj)); } buf->read(NULL, offset); YYmmsJson::FreeCmd(jobj); } break; // case YYMMSJSON_ERROR_ESC: // case YYMMSJSON_ERROR_JSON: default: buf->clear(); _event.closefd(fd); break; } } while (buf->size() > 0); if (readbuffer) delete readbuffer; }
int runcmd_cmd2strv(const char *str, int *out_argc, char **out_argv) { int arg = 0, i, a = 0; int state, ret = 0; size_t len; char *argz; set_state(STATE_NONE); len = strlen(str); argz = malloc(len + 10); for (i = 0; i < len; i++) { const char *p = &str[i]; switch (*p) { case 0: return ret; case ' ': case '\t': case '\r': case '\n': if (is_state(STATE_INARG)) { set_state(STATE_NONE); argz[a++] = 0; continue; } if (!in_quotes) continue; break; case '\\': i++; break; case '\'': if (have_state(STATE_INDQ)) break; if (have_state(STATE_INSQ)) { del_state(STATE_INSQ); continue; } /* * quotes can come inside arguments or * at the start of them */ if (is_state(STATE_NONE) || is_state(STATE_INARG)) { if (is_state(STATE_NONE)) { /* starting a new argument */ out_argv[arg++] = &argz[a]; } set_state(STATE_INSQ | STATE_INARG); continue; } case '"': if (have_state(STATE_INSQ)) break; if (have_state(STATE_INDQ)) { del_state(STATE_INDQ); continue; } if (is_state(STATE_NONE) || is_state(STATE_INARG)) { if (is_state(STATE_NONE)) { out_argv[arg++] = &argz[a]; } set_state(STATE_INDQ | STATE_INARG); continue; } break; case '|': if (!in_quotes) { add_ret(CMD_HAS_REDIR); } break; case '&': case ';': if (!in_quotes) { set_state(STATE_SPECIAL); add_ret(CMD_HAS_JOBCONTROL); if (i && str[i - 1] != *p) { argz[a++] = 0; out_argv[arg++] = &argz[a]; } } break; case '`': if (!in_quotes) { add_ret(CMD_HAS_SUBCOMMAND); } break; case '(': if (!in_quotes) { add_ret(CMD_HAS_PAREN); } break; case '*': case '?': if (!in_quotes) { add_ret(CMD_HAS_WILDCARD); } /* fallthrough */ default: break; } if (is_state(STATE_NONE)) { set_state(STATE_INARG); out_argv[arg++] = &argz[a]; } /* by default we simply copy the byte */ argz[a++] = str[i]; } /* make sure we nul-terminate the last argument */ argz[a++] = 0; if (have_state(STATE_INSQ)) add_ret(CMD_HAS_UBSQ); if (have_state(STATE_INDQ)) add_ret(CMD_HAS_UBDQ); *out_argc = arg; return ret; }