Beispiel #1
0
/* 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);
}
Beispiel #2
0
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;
}