示例#1
0
文件: hash.c 项目: NoelMinamino/irc
void	inithashtables(void)
{
	Reg int i;

	clear_client_hash_table((_HASHSIZE) ? _HASHSIZE : HASHSIZE);
	clear_uid_hash_table((_UIDSIZE) ? _UIDSIZE : UIDSIZE);
	clear_channel_hash_table((_CHANNELHASHSIZE) ? _CHANNELHASHSIZE
                                 : CHANNELHASHSIZE);
	clear_sid_hash_table((_SIDSIZE) ? _SIDSIZE : SIDSIZE);
#ifdef USE_HOSTHASH
	clear_hostname_hash_table((_HOSTNAMEHASHSIZE) ? _HOSTNAMEHASHSIZE : 
				   HOSTNAMEHASHSIZE);
#endif
#ifdef USE_IPHASH
	clear_ip_hash_table((_IPHASHSIZE) ? _IPHASHSIZE : IPHASHSIZE);
#endif

	/*
	 * Moved multiplication out from the hashfunctions and into
	 * a pre-generated lookup table. Should save some CPU usage
	 * even on machines with a fast mathprocessor.  -- Core
	 */
	hashtab = (u_int *) MyMalloc(256 * sizeof(u_int));
	for (i = 0; i < 256; i++)
		hashtab[i] = tolower((char)i) * 109;
}
示例#2
0
int m_hash(struct Client *cptr, struct Client *sptr,int parc,char *parv[])
{
  register int l;
  register int i;
  register struct HashEntry* tab;
  struct HashEntry* table;
  struct tm*        tmptr;
  int        deepest = 0;
  int   deeplink = 0;
  int   showlist = 0;
  int   tothits = 0;
  int        mosthit = 0;
  int   mosthits = 0;
  int   used = 0;
  int   used_now = 0;
  int   totlink = 0;
  int   size = U_MAX;
  char        ch;
  int   out = 0;
  int        link_pop[10];
  char  result_buf[256];
  char  hash_log_file[256];
  char  timebuffer[MAX_DATE_STRING];

  if (!MyClient(sptr) || !HasUmode(sptr,UMODE_DEBUG))
    {
      sendto_one(sptr, form_str(ERR_NOPRIVILEGES), me.name, parv[0]);
      return 0;
    }
  if(parc > 1)
    {
      if(!irccmp(parv[1],"iphash"))
        {
          iphash_stats(cptr,sptr,parc,parv,-1);
          return 0;
        }
      else if(!irccmp(parv[1],"Diphash"))
        {
          tmptr = localtime(&CurrentTime);
          strftime(timebuffer, MAX_DATE_STRING, "%Y%m%d%H%M", tmptr);
          sprintf(hash_log_file, "%s.%s",
		  hash_log_file_base, timebuffer);

          if ((out = open(hash_log_file, O_RDWR | O_APPEND | O_CREAT,0664))==-1)
              sendto_one(sptr, ":%s NOTICE %s :Problem opening %s",
                         me.name, parv[0], hash_log_file);
          else
            sendto_one(sptr, ":%s NOTICE %s :Writing hash log to %s",
                       me.name, parv[0], hash_log_file);

          iphash_stats(cptr,sptr,parc,parv,out);
          return 0;
        }

      ch = *parv[1];
      if (IsLower(ch))
        {
          table = clientTable;
          
        }
      else
        {
          table = channelTable;
          size = CH_MAX;
        }
      if (ch == 'L' || ch == 'l')
        {
          tmptr = localtime(&CurrentTime);
          strftime(timebuffer, MAX_DATE_STRING, "%Y%m%d%H%M", tmptr);
          sprintf(hash_log_file, "%s-%cdump.%s",
		  hash_log_file_base, ch, timebuffer);
          showlist = 1;
          if ((out = open(hash_log_file, O_RDWR|O_APPEND|O_CREAT,0664))==-1)
              sendto_one(sptr, ":%s NOTICE %s :Problem opening %s ",
                         me.name, parv[0], hash_log_file);
          else
            sendto_one(sptr, ":%s NOTICE %s :Writing hash log to %s ",
                       me.name, parv[0], hash_log_file);
        }
    }
  else
    {
      ch = '\0';
      table = clientTable;
    }

  for (i = 0; i < 10; i++)
    link_pop[i] = 0;

  for (i = 0; i < size; i++)
    {
      tab = &table[i];
      l = tab->links;
      if (showlist)
        {
        /*
          sendto_one(sptr,
          "NOTICE %s :Hash Entry:%6d Hits:%7d Links:%6d",
          parv[0], i, tab->hits, l); */
          if(out >= 0)
            {
              sprintf(result_buf,"Hash Entry:%6d Hits;%7d Links:%6d\n",
                            i, tab->hits, l);
              write(out,result_buf,strlen(result_buf));
            }
        }

      if (l > 0)
        {
          if (l < 10)
            link_pop[l]++;
          else
            link_pop[9]++;
          used_now++;
          totlink += l;
          if (l > deepest)
            {
              deepest = l;
              deeplink = i;
            }
        }
      else
        link_pop[0]++;
      l = tab->hits;
      if (l)
        {
          used++;
          tothits += l;
          if (l > mosthits)
            {
              mosthits = l;
              mosthit = i;
            }
        }
    }
  if(showlist && (out >= 0))
     (void)close(out);

  switch((int)ch)
    {
    case 'V' : case 'v' :
      {
        register struct Client* acptr;
        int        bad = 0, listlength = 0;
        
        for (acptr = GlobalClientList; acptr; acptr = acptr->next) {
          if (hash_find_client(acptr->name,acptr) != acptr)
            {
              if (ch == 'V')
                sendto_one(sptr, "NOTICE %s :Bad hash for %s",
                           parv[0], acptr->name);
              bad++;
            }
          listlength++;
        }
        sendto_one(sptr,"NOTICE %s :List Length: %d Bad Hashes: %d",
                   parv[0], listlength, bad);
      }
    case 'P' : case 'p' :
      for (i = 0; i < 10; i++)
        sendto_one(sptr,"NOTICE %s :Entires with %d links : %d",
                   parv[0], i, link_pop[i]);
      return (0);
    case 'r' :
      {
        register        struct Client        *acptr;

        sendto_one(sptr,"NOTICE %s :Rehashing Client List.", parv[0]);
        clear_client_hash_table();
        for (acptr = GlobalClientList; acptr; acptr = acptr->next)
          add_to_client_hash_table(acptr->name, acptr);
        break;
      }
    case 'R' :
      {
        register        struct Channel        *acptr;

        sendto_one(sptr,"NOTICE %s :Rehashing Channel List.", parv[0]);
        clear_channel_hash_table();
        for (acptr = channel; acptr; acptr = acptr->nextch)
          (void)add_to_channel_hash_table(acptr->chname, acptr);
        break;
      }
    case 'H' :
      if (parc > 2)
        sendto_one(sptr,"NOTICE %s :%s hash to entry %d",
                   parv[0], parv[2],
                   hash_channel_name(parv[2]));
      return (0);
    case 'h' :
      if (parc > 2)
        sendto_one(sptr,"NOTICE %s :%s hash to entry %d",
                   parv[0], parv[2],
                   hash_nick_name(parv[2]));
      return (0);
    case 'n' :
      {
        struct Client        *tmp;
        int        max;
        
        if (parc <= 2)
          return (0);
        l = atoi(parv[2]) % U_MAX;
        if (parc > 3)
          max = atoi(parv[3]) % U_MAX;
        else
          max = l;
        for (;l <= max; l++)
          for (i = 0, tmp = (struct Client *)clientTable[l].list; tmp;
               i++, tmp = tmp->hnext)
            {
              if (parv[1][2] == '1' && tmp != tmp->from)
                continue;
              sendto_one(sptr,"NOTICE %s :Node: %d #%d %s",
                         parv[0], l, i, tmp->name);
            }
        return (0);
      }
    case 'N' :
      {
        struct Channel *tmp;
        int        max;

        if (parc <= 2)
          return (0);
        l = atoi(parv[2]) % CH_MAX;
        if (parc > 3)
          max = atoi(parv[3]) % CH_MAX;
        else
          max = l;
        for (;l <= max; l++)
          for (i = 0, tmp = (struct Channel*) channelTable[l].list; tmp;
               i++, tmp = tmp->hnextch)
            sendto_one(sptr,"NOTICE %s :Node: %d #%d %s",
                       parv[0], l, i, tmp->chname);
        return (0);
      }
#ifdef DEBUGMODE
    case 'S' :

      sendto_one(sptr,"NOTICE %s :Entries Hashed: %d NonEmpty: %d of %d",
                 parv[0], totlink, used_now, size);
      if (!used_now)
        used_now = 1;
      sendto_one(sptr,"NOTICE %s :Hash Ratio (av. depth): %f %%Full: %f",
                 parv[0], (float)((1.0 * totlink) / (1.0 * used_now)),
                 (float)((1.0 * used_now) / (1.0 * size)));
      sendto_one(sptr,"NOTICE %s :Deepest Link: %d Links: %d",
                 parv[0], deeplink, deepest);
      if (!used)
        used = 1;
      sendto_one(sptr,"NOTICE %s :Total Hits: %d Unhit: %d Av Hits: %f",
                 parv[0], tothits, size-used,
                 (float)((1.0 * tothits) / (1.0 * used)));
      sendto_one(sptr,"NOTICE %s :Entry Most Hit: %d Hits: %d",
                 parv[0], mosthit, mosthits);
      sendto_one(sptr,"NOTICE %s :Client hits %d miss %d",
                 parv[0], clhits, clmiss);
      sendto_one(sptr,"NOTICE %s :Channel hits %d miss %d",
                 parv[0], chhits, chmiss);
      return 0;
#endif
    }
  return 0;
}
示例#3
0
int
main(int argc, char *argv[])
{
   uid_t         uid, euid;
   int           portarg = 0,  fd;
#ifdef SAVE_MAXCLIENT_STATS
   FILE 	*mcsfp;
#endif

   memset(&me, 0, sizeof(aClient));
	
   if ((timeofday = time(NULL)) == -1) 
   {
      (void) fprintf(stderr, "ERROR: Clock Failure (%d)\n", errno);
      exit(errno);
   }
	
   build_version();
	
   Count.server = 1;		/* us */
   Count.oper = 0;
   Count.chan = 0;
   Count.local = 0;
   Count.total = 0;
   Count.invisi = 0;
   Count.unknown = 0;
   Count.max_loc = 0;
   Count.max_tot = 0;
   Count.today = 0;
   Count.weekly = 0;
   Count.monthly = 0;
   Count.yearly = 0;
   Count.start = NOW;
   Count.day = NOW;
   Count.week = NOW;
   Count.month = NOW;
   Count.year = NOW;

#ifdef SAVE_MAXCLIENT_STATS
	mcsfp=fopen(DPATH "/.maxclients", "r");
	if(mcsfp!=NULL) {
		fscanf(mcsfp, "%d %d %li %li %li %ld %ld %ld %ld", &Count.max_loc, 
			&Count.max_tot, &Count.weekly, &Count.monthly, &Count.yearly, 
			&Count.start, &Count.week, &Count.month, &Count.year);
		fclose(mcsfp);
	}
#endif
	

	
   /*
    * this code by [email protected] 
    * it is intended to keep the ircd from being swapped out. BSD
    * swapping criteria do not match the requirements of ircd
    */
	
#ifdef INITIAL_DBUFS
   dbuf_init();			/* set up some dbuf stuff to control paging */
#endif

   sbrk0 = (char *) sbrk((size_t) 0);
   uid = getuid();
   euid = geteuid();
#ifdef	PROFIL
   (void) monstartup(0, etext);
   (void) moncontrol(1);
   (void) signal(SIGUSR1, s_monitor);
#endif
	
   myargv = argv;
   (void) umask(077);		/* better safe than sorry --SRB  */
   memset((char *) &me, '\0', sizeof(me));
	
   setup_signals();
   /*
    * * All command line parameters have the syntax "-fstring"  or "-f
    * string" (e.g. the space is optional). String may  be empty. Flag
    * characters cannot be concatenated (like "-fxyz"), it would
    * conflict with the form "-fstring".
    */
   while (--argc > 0 && (*++argv)[0] == '-') 
   {
	char       *p = argv[0] + 1;
	int         flag = *p++;
		
        if (flag == '\0' || *p == '\0') 
	{
	   if (argc > 1 && argv[1][0] != '-') 
	   {
		p = *++argv;
		argc -= 1;
	   }
	   else
		p = "";
	   }
		
      switch (flag) 
      {
		 case 'a':
			bootopt |= BOOT_AUTODIE;
			break;
		 case 'c':
			bootopt |= BOOT_CONSOLE;
			break;
		 case 'q':
			bootopt |= BOOT_QUICK;
			break;
		 case 'd':
			(void) setuid((uid_t) uid);
			dpath = p;
			break;
		 case 'o':		/* Per user local daemon... */
			(void) setuid((uid_t) uid);
			bootopt |= BOOT_OPER;
			break;
#ifdef CMDLINE_CONFIG
		 case 'f':
			(void) setuid((uid_t) uid);
			configfile = p;
			break;
			
# ifdef KPATH
		 case 'k':
			(void) setuid((uid_t) uid);
			klinefile = p;
			break;
# endif
			
#endif
		 case 'h':
			strncpyzt(me.name, p, sizeof(me.name));
			break;
		 case 'i':
			bootopt |= BOOT_INETD | BOOT_AUTODIE;
			break;
		 case 'p':
			if ((portarg = atoi(p)) > 0)
			  portnum = portarg;
			break;
		 case 's':
			bootopt |= BOOT_STDERR;
			break;
		 case 't':
			(void) setuid((uid_t) uid);
			bootopt |= BOOT_TTY;
			break;
		 case 'v':
			(void) printf("ircd %s\n", version);
			exit(0);
		 case 'x':
#ifdef	DEBUGMODE
			(void) setuid((uid_t) uid);
			debuglevel = atoi(p);
			debugmode = *p ? p : "0";
			bootopt |= BOOT_DEBUG;
			break;
#else
			(void) fprintf(stderr,
				"%s: DEBUGMODE must be defined for -x y\n",
								myargv[0]);
			exit(0);
#endif
		 default:
			bad_command();
			break;
      }
   }
	
   if (chdir(dpath)) 
   {
      perror("chdir");
      exit(-1);
   }
   if ((uid != euid) && !euid) 
   {
      (void) fprintf(stderr,
	"ERROR: do not run ircd setuid root. Make it setuid a normal user.\n");
      exit(-1);
   }
	
   if (argc > 0)
	  return bad_command();	/* This should exit out  */
   initialize_ssl();

   motd = (aMotd *) NULL;
   helpfile = (aMotd *) NULL;
   motd_tm = NULL;
#ifdef SHORT_MOTD
   shortmotd = NULL;
#endif
	
   read_motd(MOTD);
   read_help(HELPFILE);
#ifdef SHORT_MOTD
   read_shortmotd(SHORTMOTD);
#endif
	
   clear_client_hash_table();
   clear_channel_hash_table();
   clear_scache_hash_table();	/* server cache name table */
   clear_ip_hash_table();	/* client host ip hash table */

   initlists();
   initclass();
   initwhowas();
   initstats();
   init_tree_parse(msgtab);
   init_send();
   NOW = time(NULL);
   open_debugfile();
   NOW = time(NULL);
   init_fdlist(&serv_fdlist);
   init_fdlist(&oper_fdlist);
   init_fdlist(&listen_fdlist);
	
#ifndef NO_PRIORITY
   init_fdlist(&busycli_fdlist);
#endif
	
   init_fdlist(&default_fdlist);
	  {
		  int i;
		  
		  for (i = MAXCONNECTIONS + 1; i > 0; i--) 
		  {
			  default_fdlist.entry[i] = i - 1;
		  }
	  }

   if ((timeofday = time(NULL)) == -1) 
   {
#ifdef USE_SYSLOG
      syslog(LOG_WARNING, "Clock Failure (%d), TS can be corrupted", errno);
#endif
      sendto_ops("Clock Failure (%d), TS can be corrupted", errno);
   }

#ifdef WINGATE_NOTICE
   strcpy(ProxyMonURL, "http://");
   strncpyzt((ProxyMonURL + 7), DEFAULT_PROXY_INFO_URL, (TOPICLEN + 1) - 7);
   strncpyzt(ProxyMonHost, MONITOR_HOST, (HOSTLEN + 1));
#endif
	
   if (portnum < 0)
	  portnum = PORTNUM;
   me.port = portnum;
   (void) init_sys();
   me.flags = FLAGS_LISTEN;
#ifndef _WIN32
   if (bootopt & BOOT_INETD) 
   {
      me.fd = 0;
      local[0] = &me;
      me.flags = FLAGS_LISTEN;
   }
   else
#endif
	  me.fd = -1;
	
#ifdef USE_SYSLOG
# define SYSLOG_ME     "ircd"
   openlog(SYSLOG_ME, LOG_PID | LOG_NDELAY, LOG_FACILITY);
#endif
   if ((fd = openconf(configfile)) == -1) 
   {
      Debug((DEBUG_FATAL, "Failed in reading configuration file %s",
				 configfile));
      (void) printf("Couldn't open configuration file %s\n",
						  configfile);
      exit(-1);
   }
   (void) initconf(bootopt, fd);
	
   /* comstuds SEPARATE_QUOTE_KLINES_BY_DATE code */
#ifdef SEPARATE_QUOTE_KLINES_BY_DATE
	  {
		  struct tm  *tmptr;
		  char        timebuffer[20], filename[200];
		  
		  tmptr = localtime(&NOW);
		  (void) strftime(timebuffer, 20, "%y%m%d", tmptr);
		  ircsprintf(filename, "%s.%s", klinefile, timebuffer);
		  if ((fd = openconf(filename)) == -1) 
		  {
			  Debug((DEBUG_ERROR, "Failed reading kline file %s",
						filename));
			  (void) printf("Couldn't open kline file %s\n",
								 filename);
		  }
		  else
			 (void) initconf(0, fd);
	  }
#else
# ifdef KPATH
   if ((fd = openconf(klinefile)) == -1) 
   {
      Debug((DEBUG_ERROR, "Failed reading kline file %s", klinefile));
      (void) printf("Couldn't open kline file %s\n", klinefile);
   }
   else
	  (void) initconf(0, fd);
# endif
#endif
   if (!(bootopt & BOOT_INETD)) 
   {
		static char star[] = "*";
		aConfItem  *aconf;
		u_long      vaddr;
		
      if ((aconf = find_me()) && portarg <= 0 && aconf->port > 0)
		  portnum = aconf->port;

      Debug((DEBUG_ERROR, "Port = %d", portnum));

      if ((aconf->passwd[0] != '\0') && (aconf->passwd[0] != '*'))
		  vaddr = inet_addr(aconf->passwd);
      else
		  vaddr = (u_long) NULL;
		
      if (inetport(&me, star, portnum, vaddr)) 
      {
			if (bootopt & BOOT_STDERR)
			  fprintf(stderr, "Couldn't bind to primary port %d\n", portnum);
#ifdef USE_SYSLOG
			(void) syslog(LOG_CRIT, "Couldn't bind to primary port %d\n", portnum);
#endif
			exit(1);
      }
   }
   else if (inetport(&me, "*", 0, 0)) 
   {
      if (bootopt & BOOT_STDERR)
		  fprintf(stderr, "Couldn't bind to port passed from inetd\n");
#ifdef USE_SYSLOG
      (void) syslog(LOG_CRIT, "Couldn't bind to port passed from inetd\n");
#endif
      exit(1);
   }
	
   (void) get_my_name(&me, me.sockhost, sizeof(me.sockhost) - 1);
   if (me.name[0] == '\0')
	  strncpyzt(me.name, me.sockhost, sizeof(me.name));
   me.hopcount = 0;
   me.authfd = -1;
   me.confs = NULL;
   me.next = NULL;
   me.user = NULL;
   me.from = &me;
   SetMe(&me);
   make_server(&me);
   me.serv->up = me.name;
   me.lasttime = me.since = me.firsttime = NOW;
   (void) add_to_client_hash_table(me.name, &me);
	
   /* We don't want to calculate these every time they are used :) */
	
   sprintf(REPORT_DO_DNS, REPORT_DO_DNS_, me.name);
   sprintf(REPORT_FIN_DNS, REPORT_FIN_DNS_, me.name);
   sprintf(REPORT_FIN_DNSC, REPORT_FIN_DNSC_, me.name);
   sprintf(REPORT_FAIL_DNS, REPORT_FAIL_DNS_, me.name);
   sprintf(REPORT_DO_ID, REPORT_DO_ID_, me.name);
   sprintf(REPORT_FIN_ID, REPORT_FIN_ID_, me.name);
   sprintf(REPORT_FAIL_ID, REPORT_FAIL_ID_, me.name);
   R_do_dns = strlen(REPORT_DO_DNS);
   R_fin_dns = strlen(REPORT_FIN_DNS);
   R_fin_dnsc = strlen(REPORT_FIN_DNSC);
   R_fail_dns = strlen(REPORT_FAIL_DNS);
   R_do_id = strlen(REPORT_DO_ID);
   R_fin_id = strlen(REPORT_FIN_ID);
   R_fail_id = strlen(REPORT_FAIL_ID);
	
   check_class();
   if (bootopt & BOOT_OPER) 
   {
      aClient    *tmp = add_connection(&me, 0);
		
      if (!tmp)
		  exit(1);
      SetMaster(tmp);
   }
   else
	  write_pidfile();
	
   Debug((DEBUG_NOTICE, "Server ready..."));
#ifdef USE_SYSLOG
   syslog(LOG_NOTICE, "Server Ready");
#endif
   NOW = time(NULL);
	
#ifndef NO_PRIORITY
   check_fdlists();
#endif
	
   if ((timeofday = time(NULL)) == -1) 
   {
#ifdef USE_SYSLOG
      syslog(LOG_WARNING, "Clock Failure (%d), TS can be corrupted", errno);
#endif
      sendto_ops("Clock Failure (%d), TS can be corrupted", errno);
   }

#ifdef DUMP_DEBUG
   dumpfp=fopen("dump.log", "w");
#endif

   io_loop();
   return 0;
}
示例#4
0
void init_hash(void)
{
  clear_client_hash_table();
  clear_channel_hash_table();
}