Logo Search packages:      
Sourcecode: dctc version File versions  Download package

dc_manage.c

/* DCTC - a Direct Connect text clone for Linux
 * Copyright (C) 2001 Eric Prevoteau
 *
 * dc_manage.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
/*
$Id: dc_manage.c,v 1.25 2004/01/09 18:16:00 ericprev Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include <sys/time.h>
#include <glib.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>

#include "display.h"
#include "action.h"
#include "macro.h"
#include "dc_com.h"
#include "key.h"
#include "network.h"
#include "var.h"
#include "main.h"
#include "mydb.h"
#include "dc_manage.h"
#include "he3.h"
#include "user_manage.h"
#include "gts.h"
#include "timed_out_string.h"
#include "typical_action.h"
#include "tos_key.h"
#include "sema.h"
#include "ls_cache.h"
#include "gdl.h"
#include "uaddr.h"
#include "misc.h"
#include "userinfo.h"
#include "keyboard.h"
#include "md_crc.h"
#include "dc_xfer_common.h"

/***************************************************************************/
/* process the "$ConnectToMe nick ip:port|" command                        */
/* when a user want someone to connect him directly, this message is sent. */
/* this case appears when someone (!BHF) wants to ul/dl/filebrowse with    */
/* the user here.                                                          */
/***************************************************************************/
int connecttome_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nic,*host,*port;
      pthread_attr_t thread_attr;
      GString *dest;
      pthread_t num;

      /* why wasting time and bandwidth to do something which cannot succeed */
      /* if we are in active mode, we receive a connect to me only if someone */
      /* in active mode wants to download from us. If no download slot is available */
      /* we can simply ignore the query */
#if 0
      if((!behind_fw)&&(number_of_free_slot(bl_semid)==0))
      {
            return 1;
      }
#endif

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
      
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"connecttome_process","bad param(1)",NULL);
            return 1;
      }
      
      /* get nickname */
      nic=t;
      t=strchr(nic,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

#if 0
      /* if this code is active, some hub scripts kick the client because it does not */
      /* respond to their request */
      if(!behind_fw)
      {
            /* we check slot limit only if we are not in passive mode because in such */
            /* case, we will also prevent our download to start when there is no upload */
            /* slot */
            if(number_of_free_slot(bl_semid)==0)
            {
                  /* there is no free slot but perhaps this user has special rights */
                  if(!user_has_flag(nic,"IGNORE_SLOT_LIMIT"))
                        return 1;         /* user has no download privilege */
            }
      }
#endif

      /* get hostname */
      host=t;
      t=strchr(host,':');
      if(t==NULL)
            goto bad_param;
      *t++='\0';
      
      /* get port */
      port=t;
      (strchr(t,'|'))[0]='\0';                  /* never fails because DC line always ends with a | */

      disp_msg(DEBUG_MSG,"connecttome_process",nic,host,port,NULL);

      /* we will start immediatly a thread to avoid hanging of the main thread during the connect */
      dest=g_string_new(host);
      g_string_sprintfa(dest,":%s",port);
   pthread_attr_init (&thread_attr);
      pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
   pthread_create(&num,&thread_attr, (void*)do_connect_to_me,dest);
   pthread_attr_destroy (&thread_attr);

      /* dest is used and freed by the thread */

      return 1;
}

/***************************************************************************/
/* process the "$RevConnectToMe nick mynick" command                       */
/***************************************************************************/
static int revconnecttome_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nic;  
      GString *str;

      if(behind_fw)
      {
            disp_msg(DEBUG_MSG,"revconnecttome_process","impossible, we also are behind a firewall",NULL);
            return 1;
      }

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
      
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"revconnecttome_process","bad param(2)",NULL);
            return 1;
      }
      
      /* get nickname */
      nic=t;
      t=strchr(nic,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* the nick after this one is ours, don't check */
      disp_msg(DEBUG_MSG,"revconnecttome_process",nic,NULL);

      LOCK_READ(user_info);
      str=g_string_new(host_ip);
      UNLOCK_READ(user_info);
      g_string_sprintfa(str,":%hu",com_port);

      send_dc_line(sck,"$ConnectToMe",nic,str->str,NULL);

      g_string_free(str,TRUE);
      return 1;
}

/************************************************************/
/* process the "$To: mynick From: remotenick $msg|" command */
/************************************************************/
static int to_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nic;
      char *msg;
      GString *org_msg=NULL;

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
      
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"to_process","bad param(3)",NULL);
            if(org_msg!=NULL)
                  g_string_free(org_msg,TRUE);
            return 1;
      }
      
      org_msg=g_string_new(input->str);
      if(org_msg==NULL)
            goto bad_param;

      /* skip my nickname */
      t=strchr(t,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      if(strncmp(t,"From: ",sizeof("From: ")-1))
            goto bad_param;
      /* skip the from */
      t+=sizeof("From: ")-1;
      SKIP_SPACE(t)

      /* set the remote nick */
      nic=t;
      t=strstr(nic," $");
      if(t==NULL)
            goto bad_param;

      *t++='\0';
      if(user_has_flag(nic,"IGNORE_PMSG"))            /* ignore private message from this user */
            return 1;

      t++;
      msg=t;
      strrchr(t,'|')[0]='\0';       /* can never fail */

      subst_char(msg,'\n','\r');

      disp_msg(PRIV_MSG,NULL,nic,msg,NULL);

      /* and relay the message to all client */
      /* but only if it is not a relayed message */
      if(input->str[0]=='$')
      {
            org_msg=g_string_prepend_c(org_msg,'*');

            /* search the end of the sender nickname in the message */
            t=strstr(org_msg->str+(msg-input->str),"> ");
            if((t!=NULL)&&(hubname!=NULL)&&(hubname->len!=0))
            {
                  gint pos=t-org_msg->str;
                  org_msg=g_string_insert(org_msg,pos," ()");
                  pos+=2;
                  org_msg=g_string_insert(org_msg,pos,hubname->str);    /* put the hubname between the 2 parenthesis */
            }

            send_dc_line_to_dctc_link_direct(NULL,org_msg->str);
      }

      g_string_free(org_msg,TRUE);
      return 1;         /* end */
}

/*******************************************************/
/* process the "$Hello " command                       */
/* this function is called when an user enters the hub */
/*******************************************************/
static int hello_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      int msg_type=(int)xtra_param;

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)

      if(*t=='\0')
      {
            disp_msg(ERR_MSG,"hello_process","no nick (2)",NULL);
            return 1;
      }

      (strchr(t,'|'))[0]='\0';                  /* never fails because DC line always ends with a | */

      if(disp_user)
            disp_msg(msg_type,NULL,t,NULL);

      if(msg_type==USER_IN_MSG)
      {
            if(!strcmp(t,nickname))
            {
                  /* the hub "hello" me, I will send it my information */
                  hub_logged=1;
                  LOCK_READ(user_info);
                  send_dc_line(main_sck,"$Version",dc_version,NULL);             /* nothing is returned */
                  send_client2hub_capabilities();
                  send_dc_line(main_sck,"$GetNickList",NULL);              /* get list of all nickname */
                  set_user_info(main_sck,nickname,user_desc,cnx_type,cnx_opt,email,sizeof_data);
                  UNLOCK_READ(user_info);
            }
            add_user_to_user_list(t);           /* USER_IN_MSG */

            if((with_incoming_wake_up)&&(!tos_entry_exists(WAKEUGDL_TOSKEY,nickname,strlen(nickname),0)))
            {     /* if option is enabled and this user waiting downloads have not been waked up since enough time, wake up them */
                  add_tos_entry_v1_uniq(WAKEUGDL_TOSKEY,min_gdl_wake_up_delay,nickname,strlen(nickname),NULL,0);
                  send_dc_line_to_dctc_link(NULL,sck,"/WAKEUGDL",nickname,NULL);
                  gdl_wake_up_sources(nickname,0);
            }

            /* add the user to the uinfo file */
            uinfo_update_user_info(t,"0","Not defined",1,"Not defined","Not defined",0,1);
      }
      else if(msg_type==USER_OUT_MSG)
      {
            remove_user_to_user_list(t);  /* USER_OUT_MSG */

            if(abort_upload_when_user_leaves)
            {
                  terminate_upload_of_user(t);
            }

            uinfo_delete_user_info(t);
      }

      return 1;         /* end */
}

/********************************************************/
/* process the "$Search xxx:yyyy a?b?c?d?eeee|" command */
/* a=F if size doesn't care, T if size is important     */
/* b=F size is "at least", T if size is "at most"       */
/* c= size in bytes (or 0)                              */
/* d= data type 1=any,2=audio,3=compressed,4=document,5=exe,6=picture,7=videos,8=folder */
/* xxxx:yyyy is either "Hub:ttt" (ttt is nickname) or "ip:port.                         */
/****************************************************************************************/
static int search_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      int bool_a;
      int bool_b;
      char *c;
      char *d;
      char *e;
      char *reply_to;
      unsigned char *md5sum=NULL;
      unsigned char decoded_md5sum[MD5SUMLEN];

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)

#if 0
      printf("%s\n",input->str);
#endif

      if(*t=='\0')
      {
            disp_msg(ERR_MSG,"search_process","no param",NULL);
            return 1;
      }

      /* return address: Hub:nick (if sender is (or not) BHF) || host:ip (if sender is not BHF) */
      reply_to=t;

      /* search the space after the nickname */
      t=strchr(t,' ');
      if(t==NULL)
      {
            bad_param:
            disp_msg(ERR_MSG,"search_process","bad param(4)",NULL);
            return 1;
      }
      *t++='\0';

      /* verify if reply contains a ':' */
      if(strchr(reply_to,':')==NULL)
            goto bad_param;

      SKIP_SPACE(t)

      /* param 1 (size ? ) */
      if(bool_letter(*t++,&bool_a))
            goto bad_param;

      /* check if a md5sum is provided */
      if(*t=='.')
      {
            t++;
            if(strtomd5(t,decoded_md5sum))
                        md5sum=decoded_md5sum;
            t+=(3*MD5SUMLEN);
      }

      if(*t++!='?')
            goto bad_param;

      /* param 2 (size type ? ) */
      if(bool_letter(*t++,&bool_b))
            goto bad_param;

      if(*t++!='?')
            goto bad_param;

      /* param 3 (wanted size) */
      c=t;
      t=strchr(t,'?');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* param 4 (wanted type) */
      d=t;
      t=strchr(t,'?');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* param 5 (pattern) */
      e=t;
      (strchr(t,'|'))[0]='\0';                  /* never fails because DC line always ends with a | */


      if(!strncmp(reply_to,"Hub:",4))
      {
            /* the remote user is behind a firewall */
            set_xtra_information_cnx(reply_to+4,PASSIVE,NULL);

            delete_uaddr_entry_by_name(reply_to+4);               /* user is not a valid direct download because he is passive */
            if(!user_has_flag(reply_to+4,"IGNORE_SRCH"))
            {     /* user query not to ignore ? */
#if 0
                  /* currently, we reply to everybody */
                  if(!behind_fw)
#endif
                  {
                        /* don't reply if we are also behind a firewall */
                        /* because no transfer is possible */
                        LOCK_READ(user_info);
                        if(strcmp(reply_to+4,nickname))
                        {     /* don't reply to our own query */
                              UNLOCK_READ(user_info);
            
                              search_in_db(sck, reply_to+4,             /* don't put the hub: */
                                                                  atoi(d),                      /* wanted type */
                                                                  (bool_a==0)?SA_NO_MATTER: ( (bool_b==0)? SA_AT_LEAST:SA_AT_MOST ),      /* size type */
                                                                  strtoul(c,NULL,10),                 /* wanted size */
                                                                  e,
                                                                  md5sum,                       /* md5sum */
                                                                  NULL);
                        }
                        else
                        {
                              UNLOCK_READ(user_info);
                        }
                  }
            }
      }
      else
      {
            struct sockaddr_in dest;
            char *dp;
            char tmp_repl[512];

            strncpy_max(tmp_repl,reply_to,sizeof(tmp_repl));

            dp=strchr(reply_to,':');
            if(dp==NULL)
                  goto bad_param;

            dest.sin_family = AF_INET;
            dest.sin_port=htons(atoi(dp+1));
            *dp='\0';
            if(str_to_inaddr(reply_to,&(dest.sin_addr)))
                  goto bad_param;

#if 0
            add_uaddr_entry_addr_dl_only(tmp_repl);               /* user is a valid direct download because he is active */
                                                                                                            /* problem, we have an address but no name */
#else
            add_uaddr_entry_addr_dl_only_xtra(tmp_repl);
#endif

            search_in_db(srch_sck, NULL,  
                                    atoi(d),                      /* wanted type */
                                    (bool_a==0)?SA_NO_MATTER: ( (bool_b==0)? SA_AT_LEAST:SA_AT_MOST ),      /* size type */
                                    strtoul(c,NULL,10),                 /* wanted size */
                                    e,
                                    md5sum,                       /* md5sum */
                                    &dest);
      }

      return 1;         /* end */
}

/*********************************************************************************/
/* process the "$SR nick filename\5filesize slotratio\5hubname (hubIP)|" command */
/* (this string is the result of a search).                                      */
/*********************************************************************************/
static int sresult_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nic, *fic, *ficsize, *ratio, *hbname, *hbip;
      char *u;
      int res;
      char cpy[2048];

      strncpy_max(cpy,input->str,sizeof(cpy));

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
#if 0
      printf("%s\n",input->str);
#endif
      
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"sresult_process","bad param(5)",cpy,NULL);
            return 1;
      }
      
      /* get nickname */
      nic=t;
      t=strchr(nic,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      LOCK_READ(user_info);
      res=strcmp(nic,nickname);
      UNLOCK_READ(user_info);
      if(res==0)
            return 1;                     /* it is our nickname */

      if(user_has_flag(nic,"IGNORE_SREP"))
            return 1;                     /* ignore this user replies */

      /* get filename */
      fic=t;
      t=strchr(fic,5);
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* get filesize */
      ficsize=t;
      t=strchr(ficsize,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* get ratio */
      ratio=t;
      t=strchr(ratio,5);
      if(t==NULL)
            goto bad_param;
      *t++='\0';

      /* get hubname */
      hbname=t;
      t=strrchr(hbname,'(');
      if(t==NULL)
            goto bad_param;
      t[-1]='\0';
      t++;

      /* get hubip */
      hbip=t;
      t=strchr(hbip,')');
      if(t==NULL)
            goto bad_param;
      *t='\0';

      if((u=strchr(ficsize,'.'))==NULL)
            disp_msg(SRESULT_MSG,NULL,nic,fic,ficsize,ratio,hbname,hbip,NULL);
      else
      {
            unsigned char md5sum[MD5SUMLEN];
            char *true_fname=NULL;
            int true_fname_len;

            *u++='\0';
            strtomd5(u,md5sum);

            get_tos_entry(CSRCH_TOSKEY,md5sum,MD5SUMLEN,1,&true_fname,&true_fname_len);

            /* be careful, get_csearch_true_name can return a NULL */
            disp_msg(SRESULT_MSG,NULL,nic,fic,ficsize,ratio,hbname,hbip,true_fname,NULL);

            if(true_fname!=NULL)
                  free(true_fname);
      }

      {
            int ratio_free, ratio_ttl;

            if(sscanf(ratio,"%d/%d",&ratio_free,&ratio_ttl)==2)
            {
                  if((ratio_free>0)&&(with_sr_wake_up)&&(!tos_entry_exists(WAKEUGDL_TOSKEY,nic,strlen(nic),0)))
                  {     /* if there is free slot and option is enabled and this user waiting downloads have not been waked up since enough time, wake up them */
                        add_tos_entry_v1_uniq(WAKEUGDL_TOSKEY,min_gdl_wake_up_delay,nic,strlen(nic),NULL,0);
                        send_dc_line_to_dctc_link(NULL,sck,"/WAKEUGDL",nic,NULL);
                        gdl_wake_up_sources(nic,0);
                  }
            }
      }

      return 1;         /* end */
}

/******************************************************/
/* process the "$MD4Set" command                      */
/* this function is called when a partial CRC arrives */
/******************************************************/
static int md4set_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      GString *str;
      int nb;

      /* format: $MD4Set nickname CRC length L0CRC filename */
      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"md4set_process","bad param(6)",input->str,NULL);
            return 1;
      }
      
      /* we are on the nick name (it is our) */
      t=strchr(t,' ');
      if(t==NULL)
            goto bad_param;
      SKIP_SPACE(t);
      if(*t=='\0')
            goto bad_param;
      t--;  /* keep one space */
      /* convert " CRC length L0CRC filename" into "|CRC|length|L0CRC|filename|" */

      str=g_string_new("/MD4SET");
      g_string_append(str,t);
      t=str->str;
      nb=0;
      while((*t!='\0')&&(nb<4))
      {
            if(*t==' ')
            {
                  *t='|';
                  nb++;
            }
            t++;
      }

      if(nb!=4)
      {
            g_string_free(str,TRUE);
            goto bad_param;
      }

      if(str->str[str->len-1]!='|')
            g_string_append_c(str,'|');   /* add missing trailing pipe if required */
      
      add_new_sim_input(0,str->str);
      g_string_free(str,TRUE);
      return 1;         /* end */
}

/***********************************************************/
/* process the "$MD4Get0 " command                         */
/* this function is called when client query a partial CRC */
/***********************************************************/
static int md4get0_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nick;
      char *crc;
      unsigned long flength;
      int i;
      guint8 g_crc[MD4_DIGEST_LENGTH];

      /* format: $MD4Get0 nickname CRC length */
      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
      if(*t=='\0')
      {
            bad_param:
            disp_msg(ERR_MSG,"md4get0_process","bad param(7)",input->str,NULL);
            return 1;
      }
      
      /* we are on the nick name */
      nick=t;
      t=strchr(t,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';
      SKIP_SPACE(t);
      if(*t=='\0')
            goto bad_param;

      if(!user_in_list(hub_user_list,nick))     /* why wasting something if the user is not here */
            goto abrt;
      
      crc=t;
      t=strchr(t,' ');
      if(t==NULL)
            goto bad_param;
      *t++='\0';
      SKIP_SPACE(t);
      if(*t=='\0')
            goto bad_param;

      if(strlen(crc)!=2*MD4_DIGEST_LENGTH)
            goto bad_param;
            
      for(i=0;i<2*MD4_DIGEST_LENGTH;i++)
      {
            if(!isxdigit(crc[i]))
                  goto bad_param;
      }
      id_ascii_to_bin(crc,g_crc);

      sscanf(t,"%lu",&flength);

      find_file_with_crc_and_length_and_reply(sck,nick,g_crc,flength);
      abrt:
      return 1;         /* end */
}

static CMD_REPLY cmd_reply[]= {
                                                                  {"$HubName "       , sizeof("$HubName ")-1       ,hubname_process       ,(char*)HUBNAME_MSG},
                                                                  {"$Hello "         , sizeof("$Hello ")-1         ,hello_process         ,(char*)USER_IN_MSG},
                                                                  {"$Quit "          , sizeof("$Quit ")-1          ,hello_process         ,(char*)USER_OUT_MSG},
                                                                  {"$NickList "      , sizeof("$NickList ")-1      ,nicklist_process      ,(char*)USER_MSG},
                                                                  {"$OpList "        , sizeof("$OpList ")-1        ,nicklist_process      ,(char*)OP_MSG},
                                                                  {"$Search "        , sizeof("$Search ")-1        ,search_process        ,NULL},
                                                                  {"$SR "            , sizeof("$SR ")-1            ,sresult_process       ,NULL},
                                                                  {"$MyINFO "        , sizeof("$MyINFO ")-1        ,myinfo_process        ,NULL},
                                                                  {"$ConnectToMe "   , sizeof("$ConnectToMe ")-1   ,connecttome_process   ,NULL},
                                                                  {"$RevConnectToMe ", sizeof("$RevConnectToMe ")-1,revconnecttome_process,NULL},
                                                                  {"$To: "           , sizeof("$To: ")-1           ,to_process            ,NULL},
                                                                  {"*To: "           , sizeof("*To: ")-1           ,to_process            ,NULL},     /* redirection support */
                                                                  {"$ForceMove "     , sizeof("$ForceMove ")-1     ,force_process         ,NULL},
                                                                  {"$GetPass"        , sizeof("$GetPass")-1        ,getpass_process       ,NULL},
                                                                  {"$BadPass"        , sizeof("$BadPass")-1        ,badpass_process       ,NULL},
                                                                  {"$LogedIn "       , sizeof("$LogedIn ")-1       ,logedin_process       ,NULL},
                                                                  {"$ValidateDenide" , sizeof("$ValidateDenide")-1 ,validate_denied_process,NULL}, 

                                                                  /* DC protocol extension (this is the list of new keywords) */
                                                                  {"$Capabilities "  , sizeof("$Capabilities ")-1  ,capabilities_process  ,NULL},
                                                                  {"$MD4Set "        , sizeof("$MD4Set ")-1        ,md4set_process        ,NULL},
                                                                  {"$MD4Get0 "       , sizeof("$MD4Get0 ")-1       ,md4get0_process       ,NULL},
                                                                  {NULL,0,NULL},
                                                            };

/*************************************************************************************/
/* this function is called each time the client receives a full line from the server */
/*****************************************************************************************/
/* sck is provided because the function to process may requires and access to the socket */
/*****************************************************************************************/
/* output: 0: continue */
/*         1: end      */
/***********************/
int process_incoming_dc_data(int sck,GString *input)
{
      if(input->len<2)        /* nothing to process */
            return 1;               /* end */

      if((input->str[0]=='$')||(input->str[0]=='*'))
      {     /* it is a command */
            int i;

            /* looks like some buggy clones send incorrect strings containing '\0' (not the final one) before | */
            /* we replace this faulty '\0' by a space to avoid crash in function */
            for(i=0;i<input->len;i++)
            {
                  if(input->str[i]=='\0')
                        input->str[i]=' ';
            }

            i=0;
            while(cmd_reply[i].cmd!=NULL)
            {
                  if(!strncmp(input->str,cmd_reply[i].cmd,cmd_reply[i].cmd_len))
                  {
                        return cmd_reply[i].fnc(cmd_reply[i].cmd, sck,input, cmd_reply[i].xtra_param);
                  }
                  i++;
            }

            printf("unknown command (1): %s\n",input->str);
            {
                  for(i=0;i<input->len;i++)
                  {
                        printf("%c(%02X) ",input->str[i],((int)input->str[i])&255);
                  }

                  printf("\n");
            }
            return 1;
      }
      else
      {
            if( (input->len) && (input->str[input->len-1]=='|'))
                  input->str[input->len-1]='\0';

            subst_char(input->str,'\n','\r');
            if((hide_kick==0)||(!is_a_kick_message(input->str)))
            {
                  if(nick_does_not_have_ignore_pubmsg_flag(input))
                        disp_msg(GLOB_CHAT_MSG,NULL,input->str,NULL);
            }

            if(grab_ban_ip)
            {
                  grab_ban_ip_fnc(input);
            }
            return 1;         /* end */
      }
}

/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------- */
/**********************************************************************************/
/* contain valid information only when fonctions are called from manage_srch_port */
/**********************************************************************************/
static struct sockaddr_in srch_port_raddr;                                    /* address of the remote host which has sent data on the search port */
static int srch_port_raddr_len;

/**************************************************************************/
/* process the "$Pong nick" command (note: no | at the end of the string) */
/**************************************************************************/
static int pong_process(const char *cmd,int sck,GString *input, char *xtra_param)
{
      char *t;
      char *nic;
      GString *host_addr;

      t=input->str+strlen(cmd);
      SKIP_SPACE(t)
#if 1
      printf("%s\n",input->str);
#endif
      
      if(*t=='\0')
      {
            disp_msg(ERR_MSG,"pong_process","bad param(8)",NULL);
            return 1;
      }
      
      /* get nickname */
      nic=t;
      t=strchr(nic,' ');
      if(t==NULL)
      {
            t=strchr(nic,'|');            /* no pipe should be here but who knows */
            if(t!=NULL)
                  *t++='\0';
      }

      /* rebuild remote host address */
      host_addr=g_string_sized_new(64);
      G_LOCK(inet_ntoa);
      t=inet_ntoa((srch_port_raddr.sin_addr));
      if(t!=NULL)
      {
            host_addr=g_string_assign(host_addr,t);
            G_UNLOCK(inet_ntoa);

            g_string_sprintfa(host_addr,":%hu",ntohs(srch_port_raddr.sin_port));

            add_uaddr_entry(nic,host_addr->str);
      }
      else
      {
            G_UNLOCK(inet_ntoa);
      }

      g_string_free(host_addr,TRUE);
      return 1;         /* end */
}


static CMD_REPLY udp_reply[]= {
                                                                  {"$SR "            , sizeof("$SR ")-1            ,sresult_process    ,NULL},
/*    not yet supported but does not disturb
                                                                  {"$Ping"           , sizeof("$Ping")-1           ,ping_process       ,NULL},
*/
                                                                  {"$Pong "          , sizeof("$Pong ")-1          ,pong_process       ,NULL},
                                                                  {NULL,0,NULL},
                                                            };

/********************************************************/
/* we receive someone search results on the search port */
/********************************************************/
/* srch is the udp socket where search results come to */
/* sck is the normal hub connection.                   */
/*******************************************************/
int manage_srch_port(int srch_sck, int sck)
{
      char buf[8192];
      int ret;

      srch_port_raddr_len=sizeof(srch_port_raddr);

#if 0
      ret=recv(srch_sck,buf,sizeof(buf),MSG_NOSIGNAL);
#else
      ret=recvfrom(srch_sck,buf,sizeof(buf),MSG_NOSIGNAL,(void*)&srch_port_raddr,&srch_port_raddr_len);
#endif

      if(ret!=-1)
      {
            int i;
            GString *input;

            buf[ret]='\0';

            input=g_string_new(buf);

            i=0;
            while(udp_reply[i].cmd!=NULL)
            {
                  if(!strncmp(input->str,udp_reply[i].cmd,udp_reply[i].cmd_len))
                  {
                        ret=udp_reply[i].fnc(udp_reply[i].cmd, sck,input, udp_reply[i].xtra_param);
                        g_string_free(input,TRUE);
                        return ret;
                  }
                  i++;
            }

            printf("unknown command (2): %s\n",input->str);
            {
                  for(i=0;i<input->len;i++)
                  {
                        printf("%c(%02X) ",input->str[i],((int)input->str[i])&255);
                  }

                  printf("\n");
            }
            g_string_free(input,TRUE);
            return 1;
      }
      return 0;
}


Generated by  Doxygen 1.6.0   Back to index