/* Takes a string, sent with command_to_script, and sends it to the script * itself, i.e, we are in the script parsing process */ void sub_to_script(char *buf) { char subname[31]; /* Name of the Perl sub */ char *arg1 = NULL; /* First argument to the sub */ char *arg2 = NULL; /* Second argument to the sub */ char *arg3 = NULL; /* Third argument to the sub */ char *temp; char temp_nick[MAX_NICK_LEN+1]; struct user_t *temp_user; int i; if(sscanf(buf, "%30[^| ]", subname) != 1) { logprintf(1, "Got incomplete command to to_script()\n"); return; } /* user_info is a special case, since it isn't sent to the scripts, it's * only used to set variables of the user in the script parsing process. */ if(!strncmp(subname, "user_info", 9)) { sscanf(buf + 10, "%50s", temp_nick); /* If the user isn't already here, allocate a new user. */ if((temp_user = get_human_user(temp_nick)) == NULL) { if((temp_user = malloc(sizeof(struct user_t))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } temp_user->email = NULL; temp_user->desc = NULL; temp_user->buf = NULL; temp_user->outbuf = NULL; } else { remove_human_from_hash(temp_user->nick); if(temp_user->email != NULL) free(temp_user->email); temp_user->email = NULL; if(temp_user->desc != NULL) free(temp_user->desc); temp_user->desc = NULL; if(temp_user->buf != NULL) free(temp_user->buf); temp_user->buf = NULL; if(temp_user->outbuf != NULL) free(temp_user->outbuf); temp_user->outbuf = NULL; } temp_user->type = NON_LOGGED; memset(temp_user->version, 0, MAX_VERSION_LEN+1); temp_user->con_type = 0; temp_user->flag = 0; temp_user->share = 0; temp_user->timeout = 0; temp_user->rem = 0; temp_user->key = 0; temp_user->last_search = (time_t)0; /* The sock won't be used in the script, so set it to 0. */ temp_user->sock = 0; /* Set the nick. */ strcpy(temp_user->nick, temp_nick); /* Add to hashtable. */ add_human_to_hash(temp_user); sscanf(buf + 10, "%50s %lu %120s %d %30[^ |]", temp_user->nick, &temp_user->ip, temp_user->hostname, &temp_user->type, temp_user->version); return; } /* First argument */ if(((i = cut_string(buf, '\005')) != -1) /* Do we have a first argument? */ && (*(buf+i+1) == '\005')) { temp = buf + i + 2; if(!(((i = cut_string(temp, '\005')) != -1) /* Do we not have a second argument? */ && (*(temp+i+1) == '\005'))) { if((arg1 = malloc(sizeof(char) * (cut_string(temp, '|') + 2))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } memset(arg1, 0, cut_string(temp, '|') + 1); strncpy(arg1, temp, cut_string(temp, '|')); } else /* We have a second argument. */ { if((arg1 = malloc(sizeof(char) * (cut_string(temp, '\005') + 2))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } memset(arg1, 0, cut_string(temp, '\005') + 1); strncpy(arg1, temp, cut_string(temp, '\005')); /* Second argument */ temp = temp + cut_string(temp, '\005') + 2; if(!(((i = cut_string(temp, '\005')) != -1) /* Do we not have a third argument? */ && (*(temp+i+1) == '\005'))) { if((arg2 = malloc(sizeof(char) * (cut_string(temp, '|') + 2))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } memset(arg2, 0, cut_string(temp, '|') + 2); strncpy(arg2, temp, cut_string(temp, '|')); } else /* We have a third argument */ { if((arg2 = malloc(sizeof(char) * (cut_string(temp, '\005') + 2))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } memset(arg2, 0, cut_string(temp, '\005') + 2); strncpy(arg2, temp, cut_string(temp, '\005') + 1); /* Third argument */ temp = temp + cut_string(temp, '\005') + 1; if((arg3 = malloc(sizeof(char) * (cut_string(temp, '|') + 2))) == NULL) { logprintf(1, "Error - In sub_to_script()/malloc(): "); logerror(1, errno); quit = 1; return; } memset(arg3, 0, cut_string(temp, '|') + 2); strncpy(arg3, temp, cut_string(temp, '|')); } } } /* And call the sub. */ { dSP; ENTER; SAVETMPS; PUSHMARK(SP); /* These subs take three arguments: */ if(!strncmp(subname, "added_temp_ban", 14)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); XPUSHs(sv_2mortal(newSVuv(atol(arg2)))); if(arg3 != NULL) XPUSHs(sv_2mortal(newSVpvn(arg3, strlen(arg3)))); } else if(!strncmp(subname, "added_temp_allow", 16)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); XPUSHs(sv_2mortal(newSVuv(atol(arg2)))); if(arg3 != NULL) XPUSHs(sv_2mortal(newSVpvn(arg3, strlen(arg3)))); } /* These subs take two arguments: */ else if(!strncmp(subname, "data_arrival", 12)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); /* We'll have to add the pipe here, since we actually want it in * this argument. It looks a bit ugly, but it seems to be the best * way since the pipe can't be used internally between processes. * Maybe Open DC Hub shouldn't be using the flawed Direct Connect * protocol between processes, but thats a _big_ todo... */ strcat(arg2, "|"); XPUSHs(sv_2mortal(newSVpvn(arg2, strlen(arg2)))); } else if(!strncmp(subname, "added_multi_hub", 15)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); XPUSHs(sv_2mortal(newSViv(atoi(arg2)))); } else if(!strncmp(subname, "added_perm_ban", 14)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); if(arg2 != NULL) XPUSHs(sv_2mortal(newSVpvn(arg2, strlen(arg2)))); } else if(!strncmp(subname, "added_perm_allow", 16)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); if(arg2 != NULL) XPUSHs(sv_2mortal(newSVpvn(arg2, strlen(arg2)))); } else if(!strncmp(subname, "added_perm_nickban", 18)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); } else if(!strncmp(subname, "added_temp_nickban", 18)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); XPUSHs(sv_2mortal(newSVuv(atol(arg2)))); } else if(!strncmp(subname, "kicked_user", 11)) { XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); XPUSHs(sv_2mortal(newSVpvn(arg2, strlen(arg2)))); } /* If it isn't the ones with no arguments or the ones with two, * it has one argument. */ else if(strncmp(subname, "started_serving", 15)) if(strncmp(subname, "hub_timer", 9)) XPUSHs(sv_2mortal(newSVpvn(arg1, strlen(arg1)))); PUTBACK; call_pv(subname, G_DISCARD|G_EVAL); FREETMPS; LEAVE; } /* If it was user_disconnected, remove the user. */ if(!strncmp(subname, "user_disconnected", 17)) { if((temp_user = get_human_user(arg1)) != NULL) { if(temp_user->buf != NULL) { free(temp_user->buf); temp_user->buf = NULL; } if(temp_user->outbuf != NULL) { free(temp_user->outbuf); temp_user->outbuf = NULL; } if(temp_user->email != NULL) { free(temp_user->email); temp_user->email = NULL; } if(temp_user->desc != NULL) { free(temp_user->desc); temp_user->desc = NULL; } remove_human_from_hash(temp_user->nick); } } if(arg1 != NULL) free(arg1); if(arg2 != NULL) free(arg2); }
static int pushExtendedOperand(void* word_db, StateObj *pStObj,QueryNode *pQuNode) { QueryNode qnode; int nRet = 0; int nMorpheme = 0; int i = 0; index_word_extractor_t *extractor=NULL; index_word_t indexwords[ENOUGH_INDEXWORD_NUM]; int morp_id=0, indexwordnum=0; nRet = pushDefaultOperator(pStObj); DEBUG(" nRet of pushDefaultOperator is [%d] ",nRet); if ( nRet < 0 ) return nRet; if (is_both_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); pQuNode->original_word[len-1] = '\0'; /* XXX: moving including NULL */ memmove(pQuNode->original_word, pQuNode->original_word+1, len-1); return pushBothEndBigram(word_db, pStObj, pQuNode); } else if (is_left_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); /* XXX: moving including NULL */ memmove(pQuNode->original_word, pQuNode->original_word+1, len); return pushLeftEndBigram(word_db, pStObj, pQuNode); } else if (is_right_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); pQuNode->original_word[len-1] = '\0'; DEBUG("original_word for word> : %s", pQuNode->original_word); return pushRightEndBigram(word_db, pStObj, pQuNode); } morp_id = mQppMorpAnalyzerId[pStObj->searchField]; debug("morp_id[%d], mMorpIdForPhrase[%d], virtualfield_morpid[%d]", morp_id, mMorpIdForPhrase, pStObj->virtualfield_morpid); if (pStObj->posWithinPhrase == TRUE) { /* 구문검색시 무조건 바이그램을 쓰지 않도록 수정 */ morp_id = mMorpIdForPhrase; } if (pStObj->virtualfield != 0) { morp_id = pStObj->virtualfield_morpid; } extractor = sb_run_new_index_word_extractor(morp_id); if (extractor == NULL || extractor == (index_word_extractor_t*)MINUS_DECLINE) { error("cannot create index_word_extractor: %p", extractor); return FAIL; } //sb_run_index_word_extractor_set_text(extractor, pQuNode->word_st.string); info("original_word:%s", pQuNode->original_word); strncpy(pQuNode->word_st.string, pQuNode->original_word, MAX_WORD_LEN-1); pQuNode->word_st.string[MAX_WORD_LEN-1] = '\0'; cut_string(pQuNode->word_st.string, MAX_WORD_LEN-2); sb_run_index_word_extractor_set_text(extractor, pQuNode->original_word); //XXX: get_index_words should be called in a loop // (more than MAX_QPP_INDEXED_WORDS indexwords can be returned) nRet = sb_run_get_index_words(extractor, indexwords, ENOUGH_INDEXWORD_NUM); if (nRet < 0) { error("error while getting index_words. nRet[%d]", nRet); sb_run_delete_index_word_extractor(extractor); return FAIL; } indexwordnum = nRet; if (indexwordnum > MAX_QPP_INDEXED_WORDS) { indexwordnum = reduce_index_words(indexwords, indexwordnum); } nMorpheme = indexwordnum; sb_run_delete_index_word_extractor(extractor); // daum_koma를 사용하는 경우 특수처리 // 이놈은 boolean query를 리턴한다 /* if ( morp_id == 16 ) { char buf[STRING_SIZE]; struct daum_tree_node* tree = parse_daum_query(indexwords, nMorpheme); if ( tree == NULL ) { error("failed parsing daum koma query: %s", pQuNode->original_word); return FAIL; } info("original query: [%s]", pQuNode->original_word); info("parsed daum query: [%s]", print_daum_tree(tree, buf, sizeof(buf))); if ( push_daum_tree(word_db, pStObj, tree) != SUCCESS ) { error("push_daum_tree failed"); destroy_daum_tree(tree); return FAIL; } // 단어가 등장하면 최소한 { 가 } 와 같이 3개가 나온다 if ( nMorpheme >= 3 && pStObj->posWithinPhrase == TRUE ) { pStObj->numPhraseOperand++; } destroy_daum_tree(tree); pStObj->nextTurn = TURN_BINARY_OPERATOR; return SUCCESS; } else*/ if (nMorpheme > 0) { for (i=0; i<nMorpheme; i++) { strncpy(qnode.word_st.string, indexwords[i].word, MAX_WORD_LEN-1); qnode.word_st.string[MAX_WORD_LEN-1] = '\0'; cut_string(qnode.word_st.string, MAX_WORD_LEN-2); INFO("qnode[%d] word:%s", i, qnode.word_st.string); nRet = pushOperand(word_db, pStObj, &qnode); if (nRet < 0) { error("failed to push operand for word[%s]", qnode.word_st.string); return FAIL; } } if (pStObj->posWithinPhrase == TRUE) { pStObj->numPhraseOperand++; } /* 하나의 토큰에서 두개이상의 색인어가 추출되는 경우 within 연산으로 처리 */ if (nMorpheme > 1) { qnode.type = OPERATOR; qnode.operator = QPP_OP_WITHIN; qnode.opParam = 0; /* within 0 */ qnode.num_of_operands = nMorpheme; nRet = stk_push(&(pStObj->postfixStack),&qnode); if (nRet < 0) return nRet; } } else { /* 색인어가 없는 경우 바로 리턴한다. */ return SUCCESS; } /* * 형태소분석 : 10 <= morp_id < 20 * 바이그램 : 20 <= morp_id < 30 */ /* 형태소분석 결과의 버그를 피해가는 코드는 사용하지 않는다. * 2007-09-18 김정겸 */ #if 0 /* if (nMorpheme == 0 && (morp_id >= 10 && morp_id < 20)) { // 형태소 분석 결과가 없으면 원래 단어로 검색 nRet = pushOperand(pStObj, pQuNode); if (nRet < 0) { error("error while pushing original wordp[%s] into stack", pQuNode->word_st.string); return nRet; } } else */ if (nMorpheme == 1 && (morp_id >= 10 && morp_id < 20)) { /* 형태소 분석 결과 단어와 입력단어가 다르면 입력단어를 OR 검색으로 추가 */ if ( strncmp(pQuNode->original_word, indexwords[0].word, MAX_WORD_LEN) != 0) { // or with original word nRet = pushOperand(word_db, pStObj, pQuNode); if (nRet < 0) { error("error while pushing original wordp[%s] into stack", pQuNode->word_st.string); return nRet; } qnode.type = OPERATOR; qnode.operator = QPP_OP_OR; qnode.num_of_operands = 2; nRet = stk_push(&(pStObj->postfixStack), &qnode); if (nRet < 0) { error("error while pushing original word into stack"); return nRet; } } } else if (nMorpheme >= 2 && (morp_id >= 10 && morp_id < 20)) { /* 형태소 분석 결과 단어와 입력단어가 다르면 입력단어를 OR 검색으로 추가 */ // or with original word nRet = pushOperand(word_db, pStObj, pQuNode); if (nRet < 0) { error("error while pushing original word[%s] into stack", pQuNode->word_st.string); return nRet; } qnode.type = OPERATOR; qnode.operator = QPP_OP_OR; qnode.num_of_operands = 2; nRet = stk_push(&(pStObj->postfixStack), &qnode); if (nRet < 0) { error("error while pushing original word into stack"); return nRet; } } #endif pStObj->nextTurn = TURN_BINARY_OPERATOR; return SUCCESS; }