Пример #1
0
char *
smalldate(time_t clock)
{
    static char buf[MAX_DATE_STRING];
    struct tm *lt, *gm;
    struct tm   gmbuf;

    if (!clock)
        time(&clock);
    gm = gmtime(&clock);
    memcpy((char *) &gmbuf, (char *) gm, sizeof(gmbuf));
    gm = &gmbuf;
    lt = localtime(&clock);

    ircsprintf(buf, "%04d/%02d/%02d %02d.%02d", lt->tm_year + 1900, 
               lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min);

    return buf;
}
Пример #2
0
int
WriteSeen()

{
  FILE *fp;
  char tempname[MAXLINE];
  aSeen *seen;

  ircsprintf(tempname, "%s.tmp", SeenServDB);
  fp = CreateDatabase(tempname, "SeenServ Database");
  if (!fp)
  {
    putlog(LOG1, "Error writing SeenServ Database (%s): %s",
      SeenServDB,
      strerror(errno));
    return 0;
  }

  for (seen = seenb; seen; seen = seen->next) {
    if (seen) 
    switch(seen->type) {
      case 1:
         fprintf(fp, "->QUIT %s %s %ld :%s\n", seen->nick, seen->userhost, (long) seen->time, seen->msg);
         break;
      case 2:
         fprintf(fp, "->NICK %s %s %ld\n", seen->nick, seen->userhost, (long) seen->time);
         break;
      default:
         break;
    }
  }

  fclose(fp);

  rename(tempname, SeenServDB);

  putlog(LOG3, "Wrote %s",
    SeenServDB);

  return 1;

} /* WriteSeen() */
Пример #3
0
int
WriteStats()

{
  FILE *fp;
  char tempname[MAXLINE];

  ircsprintf(tempname, "%s.tmp", StatServDB);
  fp = CreateDatabase(tempname, "StatServ Database");
  if (!fp)
  {
    putlog(LOG1, "Error writing StatServ Database (%s): %s",
      StatServDB,
      strerror(errno));
    return 0;
  }

  fprintf(fp, "->USERS %ld %ld\n",
    Network->MaxUsers,
    (long) Network->MaxUsers_ts);

  fprintf(fp, "->OPERS %ld %ld\n",
    Network->MaxOperators,
    (long) Network->MaxOperators_ts);

  fprintf(fp, "->CHANS %ld %ld\n",
    Network->MaxChannels,
    (long) Network->MaxChannels_ts);

  fprintf(fp, "->SERVS %ld %ld\n",
    Network->MaxServers,
    (long) Network->MaxServers_ts);

  fclose(fp);

  rename(tempname, StatServDB);

  putlog(LOG3, "Wrote %s",
    StatServDB);

  return 1;
} /* WriteStats() */
Пример #4
0
const char *
smalldate(time_t lclock)
{
  static char buf[MAX_DATE_STRING];
  struct tm *lt, *gm;
  struct tm gmbuf;

  if (!lclock)
    lclock = CurrentTime;
  gm = gmtime(&lclock);
  memcpy((void *)&gmbuf, (void *)gm, sizeof(gmbuf));
  gm = &gmbuf; 
  lt = localtime(&lclock);
  
  ircsprintf(buf, "%d/%d/%d %02d.%02d",
             lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday,
             lt->tm_hour, lt->tm_min);

  return(buf);
}
Пример #5
0
Файл: child.c Проект: xiu/child
void mylog (char *file, char *msg, ...)
{
    char tmp[1024];
    char buf[1024];
    va_list val;
    FILE *index;
    time_t tm;
    ircsprintf(buf,1023,msg,val);
    
    tm = time(NULL);
    
    snprintf(tmp,1023,"[ %s] %s\n",ctime(&tm),buf);
    
    /* The ctime() function returns the result with a trailing '\n' */
    
    *(strstr(tmp,"\n")) = ' ';
    index = fopen(file,"a+");
    if (!index) return;
    fputs(tmp,index);
    fclose(index);
}
Пример #6
0
/*
 * send_authports
 *
 * Send the ident server a query giving "theirport , ourport".
 * The write is only attempted *once* so it is deemed to be a fail if the
 * entire write doesn't write all the data given.  This shouldnt be a
 * problem since the socket should have a write buffer far greater than
 * this message to store it in should problems arise. -avalon
 */
void	send_authports(aClient *cptr)
{
  struct sockaddr_in us, them;
  char	authbuf[32];
  int	ulen, tlen;

  Debug((DEBUG_NOTICE,"write_authports(%x) fd %d authfd %d stat %d",
	 cptr, cptr->fd, cptr->authfd, cptr->status));
  tlen = ulen = sizeof(us);

  if (getsockname(cptr->fd, (struct sockaddr *)&us, &ulen) ||
      getpeername(cptr->fd, (struct sockaddr *)&them, &tlen))
    {
#ifdef	USE_SYSLOG
      syslog(LOG_DEBUG, "auth get{sock,peer}name error for %s:%m",
	     get_client_name(cptr, TRUE));
#endif
      authsenderr(cptr);
/*      cptr->flags &= ~FLAGS_WRAUTH; */
	return;
    }

      (void)ircsprintf(authbuf, "%u , %u\r\n",
		       (unsigned int)ntohs(them.sin_port),
		       (unsigned int)ntohs(us.sin_port));

      Debug((DEBUG_SEND, "sending [%s] to auth port %s.113",
	     authbuf, inetntoa((char *)&them.sin_addr)));
      
      if (write(cptr->authfd, authbuf, strlen(authbuf)) != strlen(authbuf))
      {
	authsenderr(cptr);
	return;
      }

    cptr->flags &= ~FLAGS_WRAUTH;

    return;
}
Пример #7
0
/* [just a helper for channel_modef_string()] */
static inline char *chmodefstrhelper(char *buf, char t, char tdef, unsigned short l, unsigned char a, unsigned char r)
{
char *p;
char tmpbuf[16], *p2 = tmpbuf;

	ircsprintf(buf, "%hd", l);
	p = buf + strlen(buf);
	*p++ = t;
	if (a && ((a != tdef) || r))
	{
		*p++ = '#';
		*p++ = a;
		if (r)
		{
			sprintf(tmpbuf, "%hd", (short)r);
			while ((*p = *p2++))
				p++;
		}
	}
	*p++ = ',';
	return p;
}
Пример #8
0
static void
write_pidfile(const char *filename)
{
  FBFILE *fb;

  if ((fb = fbopen(filename, "w")))
  {
    char buff[32];
    unsigned int pid = (unsigned int)getpid();
    size_t nbytes = ircsprintf(buff, "%u\n", pid);

    if ((fbputs(buff, fb, nbytes) == -1))
      ilog(L_ERROR, "Error writing %u to pid file %s (%s)",
           pid, filename, strerror(errno));

    fbclose(fb);
  }
  else
  {
    ilog(L_ERROR, "Error opening pid file %s", filename);
  }
}
Пример #9
0
/* date()
 *
 * returns date in human readable form
 */
static char *
date(void)
{
	static char buf[80];
	char plus;
	struct tm *lt;
	struct tm *gm;
	struct tm gmbuf;
	time_t lclock;
	int minswest;

	lclock = CurrentTime;
	gm = gmtime(&lclock);
	memcpy((void *) &gmbuf, (void *) gm, sizeof(gmbuf));
	gm = &gmbuf;
	lt = localtime(&lclock);

	if(lt->tm_yday == gm->tm_yday)
		minswest = (gm->tm_hour - lt->tm_hour) * 60 + (gm->tm_min - lt->tm_min);
	else if(lt->tm_yday > gm->tm_yday && lt->tm_year == gm->tm_year)
		minswest = (gm->tm_hour - (lt->tm_hour + 24)) * 60;
	else
		minswest = ((gm->tm_hour + 24) - lt->tm_hour) * 60;

	plus = (minswest > 0) ? '-' : '+';

	if(minswest < 0)
		minswest = -minswest;

	ircsprintf(buf, "%s %s %d %d -- %02u:%02u:%02u %c%02u:%02u",
		   weekdays[lt->tm_wday], months[lt->tm_mon], lt->tm_mday,
		   lt->tm_year + 1900, lt->tm_hour, lt->tm_min, lt->tm_sec,
		   plus, minswest / 60, minswest % 60);

	return buf;
}
Пример #10
0
inline char *first_visible_channel(aClient *cptr, aClient *sptr)
{
    Link *lp;
    int secret = 0;
    aChannel *chptr = NULL;
    static char chnbuf[CHANNELLEN + 2];

    if(cptr->user->channel)
    {
	if(IsAdmin(sptr))
	{
	    chptr = cptr->user->channel->value.chptr;
	    if(!(ShowChannel(sptr, chptr)))
		secret = 1;
	}
	else
	{
	    for(lp = cptr->user->channel; lp; lp = lp->next)
	    {
		if(ShowChannel(sptr, lp->value.chptr))
		    break;
	    }
	    if(lp)
		chptr = lp->value.chptr;
	}

	if(chptr)
	{
	    if(!secret)
		return chptr->chname;
	    ircsprintf(chnbuf, "%%%s", chptr->chname);
	    return chnbuf;
	}
    }
    return "*";
}
Пример #11
0
/*
** m_svskill
**      parv[0] = sender prefix
**      parv[1] = person to disconnect
**      parv[2] = reason
*/
static void
m_svskill (struct Client *client_p, struct Client *source_p,
	   int parc, char *parv[])
{
  struct Client *target_p;
  dlink_node *server_node;
  char reason[TOPICLEN + 1];

  if (!IsServer (source_p))
    return;

  if ((target_p = (struct Client *) find_client (parv[1])) == NULL)
    return;

  ircsprintf (reason, "%s", parv[2]);

  target_p->flags |= FLAGS_KILLED;

  exit_client (client_p, target_p, target_p, reason);

  /* Propigate kill attempts. */
  sendto_server (source_p, NULL, NOCAPS, NOCAPS,
                 ":%s SVSKILL %s :%s", parv[0], parv[1], parv[2]);         
}
Пример #12
0
int
CheckJuped(char *name)

{
	struct Jupe *tempjupe;
	struct Server *tempserv;
	char sendstr[MAXLINE + 1], **arv;

	for (tempjupe = JupeList; tempjupe; tempjupe = tempjupe->next)
	{
		if (match(tempjupe->name, name))
		{
			if (tempjupe->isnick)
			{
				struct Luser *lptr;

				if (!(lptr = FindClient(name)))
					return 0;

				/* its a nick jupe, not a server jupe */

#ifdef DANCER

				ircsprintf(sendstr,
				           "NICK %s 1 %ld +i juped juped.com %s %lu :%s\r\n",
				           tempjupe->name,
#ifdef NICKSERVICES
				           (long) (lptr->nick_ts - 1),
#else
				           (long) (lptr->since - 1),
#endif /* NICKSERVICES */
				           Me.name, 0xffffffffL, tempjupe->reason ?
				           tempjupe->reason : "Jupitered Nickname");
#else
				/* collide the nickname */
				ircsprintf(sendstr, "NICK %s 1 %ld +i %s %s %s :%s\r\n",
				           tempjupe->name,
#ifdef NICKSERVICES
				           (long) (lptr->nick_ts - 1),
#else
				(long) (lptr->since - 1),
#endif /* NICKSERVICES */
				           JUPED_USERNAME, JUPED_HOSTNAME, Me.name,
				           tempjupe->reason ? tempjupe->reason :
				           "Jupitered Nickname");
#endif /* DANCER */

				toserv("%s", sendstr);

				DeleteClient(lptr);

				SplitBuf(sendstr, &arv);
				AddClient(arv);
				MyFree(arv);

				if (Me.sptr)
					Me.sptr->numoperkills++;
				Network->TotalOperKills++;
#ifdef STATSERVICES

				if (Network->TotalOperKills > Network->OperKillsT)
					Network->OperKillsT = Network->TotalOperKills;
#endif

			}
			else
			{
				toserv("SQUIT %s :Juped: %s (%s)\r\n", name,
				       tempjupe->reason, tempjupe->who);

				tempserv = FindServer(name);
				DeleteServer(tempserv);

			/* If the fake server is introduced before the remote server has quited,
			 * we get "server already exists" and services get SQUIT'ed,
			 * so we'll introduce it in s_squit()
			 */


			}
			return 1;
		}
	}
	return 0;
} /* CheckJuped */
Пример #13
0
int
WriteChans()

{
  FILE *fp;
  char tempname[MAXLINE];
  struct ChanInfo *cptr, *cnext;
  int ii,
      ccnt;

  ircsprintf(tempname, "%s.tmp", ChanServDB);
  fp = CreateDatabase(tempname, "ChanServ Database");
  if (!fp)
  {
    putlog(LOG1, "Error writing ChanServ Database (%s): %s",
      ChanServDB,
      strerror(errno));
    return 0;
  }

  ccnt = 0;

  for (ii = 0; ii < CHANLIST_MAX; ++ii)
  {
    for (cptr = chanlist[ii]; cptr; cptr = cnext)
    {
      cnext = cptr->next;

      if (!GetLink(cptr->contact))
      {
        /*
         * There is no contact - check if there is an alternate contact.  If
         * so, make them contact, otherwise delete the channel.
         */
        if (cptr->alternate && GetLink(cptr->alternate))
        {
          /*
           * There is a valid alternate contact - make them contact
           */
          MakeContact(cptr);
        }
        else
        {
          putlog(LOG2,
            "%s: dropping channel [%s] (no contact)",
            n_ChanServ,
            cptr->name);

          DeleteChan(cptr);

          continue;
        }
      }

      if (cptr->alternate)
      {
        if (!GetLink(cptr->alternate))
        {
          /* alternate contact's nickname has expired - erase it */
          putlog(LOG2,
            "%s: Alternate contact [%s] for channel [%s] expired, removing",
            n_ChanServ,
            cptr->alternate,
            cptr->name);

          MyFree(cptr->alternate);
          cptr->alternate = NULL;
        }
      }

      ++ccnt;

      /*
       * format: channel-name flags ts_created ts_lastused
       */
      fprintf(fp, "%s %ld %ld %ld\n",
	      cptr->name,
	      cptr->flags,
	      (long) cptr->created,
	      (long) cptr->lastused);

      {
        struct ChanAccess *ca;
        struct AutoKick *ak;
        int jj;

        /* write contact */
        fprintf(fp, "->FNDR %s %ld\n",
		cptr->contact,
		(long) cptr->last_contact_active);

        /* write password */
        fprintf(fp, "->PASS %s\n",
          cptr->password);

        if (cptr->alternate)
          fprintf(fp, "->SUCCESSOR %s %ld\n",
		  cptr->alternate,
		  (long) cptr->last_alternate_active);

        if (cptr->topic)
          fprintf(fp, "->TOPIC :%s\n",
            cptr->topic);

        if (cptr->limit)
          fprintf(fp, "->LIMIT %ld\n",
            cptr->limit);

        if (cptr->key)
          fprintf(fp, "->KEY %s\n",
            cptr->key);

        if (cptr->forward)
          fprintf(fp, "->FORWARD %s\n",
            cptr->forward);

        if (cptr->throttle)
          fprintf(fp, "->THROTTLE %s\n",
            cptr->throttle);

        if (cptr->dline)
          fprintf(fp, "->DLINE %s\n",
            cptr->dline);

        if (cptr->modes_on)
          fprintf(fp, "->MON %d\n",
            cptr->modes_on);

        if (cptr->modes_off)
          fprintf(fp, "->MOFF %d\n",
            cptr->modes_off);

        if (cptr->entrymsg)
          fprintf(fp, "->ENTRYMSG :%s\n",
            cptr->entrymsg);

        if (cptr->email)
          fprintf(fp, "->EMAIL %s\n",
            cptr->email);

        if (cptr->url)
          fprintf(fp, "->URL %s\n",
            cptr->url);

        fprintf(fp, "->ALVL");
        for (jj = 0; jj <= CA_CONTACT; ++jj)
          fprintf(fp, " %d",
            cptr->access_lvl[jj]);
        fprintf(fp, "\n");

        for (ca = cptr->access; ca; ca = ca->next)
          fprintf(fp, "->ACCESS %s %d %ld %ld\n",
		  ca->nptr ? ca->nptr->nick : stripctrlsymbols(ca->hostmask),
		  ca->level,
		  (long) ca->created, (long) ca->last_used);

        for (ak = cptr->akick; ak; ak = ak->next)
          fprintf(fp, "->AKICK %s :%s\n",
            stripctrlsymbols(ak->hostmask),
            ak->reason ? stripctrlsymbols(ak->reason) : "");
      }
    } /* for (cptr = chanlist[ii]; cptr; cptr = cnext) */
  } /* for (ii = 0; ii < CHANLIST_MAX; ++ii) */

  fclose(fp);

  rename(tempname, ChanServDB);

  putlog(LOG3, "Wrote %s (%d registered channels)",
    ChanServDB,
    ccnt);

  return (1);
} /* WriteChans() */
Пример #14
0
int
WriteNicks()

{
  FILE *fp;
  char tempname[MAXLINE];
  int ii, ncnt;
  struct NickInfo *nptr;
  struct NickHost *hptr;
  int islinked;

  ircsprintf(tempname, "%s.tmp", NickServDB);
  fp = CreateDatabase(tempname, "NickServ Database");
  if (!fp)
  {
    putlog(LOG1, "Error writing NickServ Database (%s): %s",
      NickServDB,
      strerror(errno));
    return 0;
  }

  ncnt = 0;

#ifdef LINKED_NICKNAMES

  /*
   * We have to go through the nicklist to write out all master entries
   * first, because the leaf entries will have a ->LINK <master nick>, so
   * the next time the database is read, we have to make sure we can find
   * the master nickname entry or we've got problems :-). Basically, make
   * sure the leaf entries don't get written out before master entries.
   * Unfortunately, we have to repeat some code here.
   */

  for (ii = 0; ii < NICKLIST_MAX; ++ii)
  {
    for (nptr = nicklist[ii]; nptr; nptr = nptr->next)
    {
      if (nptr->master || !nptr->nextlink)
      {
        /* This is not a master nickname */
        continue;
      }

      ++ncnt;

      /* write out "nickname flags created last-seen" to file */
      fprintf(fp, "%s %ld %ld %ld\n",
        nptr->nick,
        nptr->flags,
        (long) nptr->created,
        (long) nptr->lastseen);

      /* write out password only if not forbidden! -kre */
      if (nptr->password)
        fprintf(fp, "->PASS %s\n", nptr->password);

      if (nptr->cloak)
        fprintf(fp, "->CLOAK %s\n", nptr->cloak);

      if (nptr->email)
        fprintf(fp, "->EMAIL %s\n", nptr->email);

      if (nptr->url)
        fprintf(fp, "->URL %s\n", nptr->url);

      if (nptr->gsm)
        fprintf(fp, "->GSM %s\n", nptr->gsm);

      if (nptr->phone)
        fprintf(fp, "->PHONE %s\n", nptr->phone);

      if (nptr->UIN)
        fprintf(fp, "->UIN %s\n", nptr->UIN);

      if (LastSeenInfo)
      {
        if (nptr->lastu && nptr->lasth)
          fprintf(fp, "->LASTUH %s %s\n", nptr->lastu,
            nptr->lasth);

        if (nptr->lastqmsg)
          fprintf(fp, "->LASTQMSG :%s\n", nptr->lastqmsg);
      }

      for (hptr = nptr->hosts; hptr; hptr = hptr->next)
        fprintf(fp, "->HOST %s\n", hptr->hostmask);

    } /* for (nptr = nicklist[ii]; nptr; nptr = nptr->next) */
  } /* for (ii = 0; ii < NICKLIST_MAX; ++ii) */

#endif /* LINKED_NICKNAMES */

  /*
   * Now go through and write out all non-master nickname
   * entries
   */

  for (ii = 0; ii < NICKLIST_MAX; ++ii)
  {
    for (nptr = nicklist[ii]; nptr; nptr = nptr->next)
    {
      islinked = 0;

    #ifdef LINKED_NICKNAMES
      if (nptr->master)
        islinked = 1;
      else
      {
        /*
         * If nptr->master is NULL, but nptr->nextlink is not,
         * this is a master nickname, which was already written,
         * continue the loop
         */
        if (nptr->nextlink)
          continue;
      }
    #endif /* LINKED_NICKNAMES */

      ++ncnt;

      /* write out "nickname flags created last-seen" to file */
      fprintf(fp, "%s %ld %ld %ld\n",
        nptr->nick, nptr->flags, (long) nptr->created, (long)
        nptr->lastseen);

      if (nptr->password)
        fprintf(fp, "->PASS %s\n", nptr->password);

      if (nptr->cloak)
        fprintf(fp, "->CLOAK %s\n", nptr->cloak);

      if (nptr->email)
        fprintf(fp, "->EMAIL %s\n", nptr->email);

      if (nptr->url)
        fprintf(fp, "->URL %s\n", nptr->url);

      if (nptr->gsm)
        fprintf(fp, "->GSM %s\n", nptr->gsm);

      if (nptr->phone)
        fprintf(fp, "->PHONE %s\n", nptr->phone);

      if (nptr->UIN)
        fprintf(fp, "->UIN %s\n", nptr->UIN);

      if (LastSeenInfo)
      {
        if (nptr->lastu && nptr->lasth)
          fprintf(fp, "->LASTUH %s %s\n",
            nptr->lastu,
            nptr->lasth);

        if (nptr->lastqmsg)
          fprintf(fp, "->LASTQMSG :%s\n",
            nptr->lastqmsg);
      }

      if (!islinked)
      {
        /*
         * write out hostmasks only if this nickname is
         * not linked - if it is, the master nickname
         * (previously written) has the access list
         */

        for (hptr = nptr->hosts; hptr; hptr = hptr->next)
          fprintf(fp, "->HOST %s\n",
            hptr->hostmask);
      }

    #ifdef LINKED_NICKNAMES

#if 0
      assert(nptr != nptr->master);
#endif
      /* Quickfix. Seems unlink is broken atm. But, there is no need to
       * die here since master was not written because of
       * nptr->nextlink. Huh. Should fix link copying routines -kre */
      if ((nptr != nptr->master) && nptr->master)
        fprintf(fp, "->LINK %s\n",
          nptr->master->nick);

    #endif /* LINKED_NICKNAMES */
    } /* for (nptr = nicklist[ii]; nptr; nptr = nptr->next) */
  } /* for (ii = 0; ii < NICKLIST_MAX; ++ii) */

  fclose(fp);

  rename(tempname, NickServDB);

  putlog(LOG3, "Wrote %s (%d registered nicknames)",
    NickServDB, ncnt);

  return (1);
} /* WriteNicks() */
Пример #15
0
/*
  DoListen()
*/
void DoListen(struct PortInfo *portptr)
{
	struct addrinfo hints;
	struct addrinfo *res, *res_o;
	int error;
	char port[MAXLINE];

	/* can't use standard LookupHostname */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;

	ircsprintf(port, "%d", portptr->port);
	error = getaddrinfo(LocalHostName, port, &hints, &res);

	res_o = res;

	if (error)
	{
		putlog(LOG1,
		       "Unable to get local addresses, this should never happen: %s",
		       gai_strerror(error));
		return;
	}

	while (res != NULL)
	{
		if ((portptr->socket = socket(res->ai_family, SOCK_STREAM, 6)) == -1)
		{
			res = res->ai_next;
			portptr->socket = NOSOCKET;
			continue;
		}

		/* set various socket options */
		SetSocketOptions(portptr->socket);
		SetPort((struct sockaddr *)res->ai_addr, portptr->port);

		if (bind(portptr->socket, res->ai_addr, res->ai_addrlen) == -1)
		{
			putlog(LOG1, "FATAL: Unable to bind port tcp/%d: %s",
			       portptr->port, strerror(errno));
			close(portptr->socket);
			portptr->socket = NOSOCKET;
		}
		else
#ifdef SOMAXCONN
			if (listen(portptr->socket, SOMAXCONN) == -1)
#else

			if (listen(portptr->socket, HYBSERV_SOMAXCONN) == -1)
#endif

			{
				putlog(LOG1, "Unable to listen on port tcp/%d: %s",
				       portptr->port, strerror(errno));
				close(portptr->socket);
				portptr->socket = NOSOCKET;
			}
			else
			{
				putlog(LOG1,
				       "Listener successfully started on host [%s] port tcp/%d",
				       (LocalHostName != NULL) ? LocalHostName : "*",
				       portptr->port);
			}

		res = res->ai_next;
	}

	portptr->tries++;

	if (res_o != NULL)
		freeaddrinfo(res_o);
} /* DoListen() */
Пример #16
0
void
BackupDatabases(time_t unixtime)

{
  struct tm *backup_tm;
  char bpath[MAXLINE],
       temp[MAXLINE];

  /*
   * First make sure HPath/backup/ exists
   * Notice that %s/backup/something has to be under 512 characters. -kre
   */
  ircsprintf(bpath, "%s/backup", HPath);
  /* Function mkdir() returns -1 on failure -kre */
  if (mkdir(bpath, 0700)==-1)
  {
    /* Proceed if errno is set. This usually should not be necessary, but
     * this code should help me find why Solaris complains -kre */
    if (errno && errno!=EEXIST)
    {
      putlog(LOG1,
        "Error creating backup directory [%s]: %s",
        bpath,
        strerror(errno));
      return;
    }
  }

  backup_tm = localtime(&unixtime);

  ircsprintf(bpath, "%s/backup/%d%02d%02d", HPath, 1900 +
      backup_tm->tm_year, backup_tm->tm_mon + 1, backup_tm->tm_mday);

  /*
   * Make the directory permissions: drwx------
   * Function mkdir() returns -1 on failure -kre
   */
  if (mkdir(bpath, 0700)==-1)
  {
    /* Proceed if errno is set. This usually should not be necessary, but
     * this code should help me find why Solaris complains -kre */
    if (errno && errno!=EEXIST)
    {
      putlog(LOG1,
        "Error creating backup directory [%s]: %s",
        bpath,
        strerror(errno));
      return;
    }
  }

  ircsprintf(temp, "%s/%s", bpath, OperServDB);

  CopyFile(OperServDB, temp);

#ifdef STATSERVICES

  ircsprintf(temp, "%s/%s", bpath, StatServDB);

  CopyFile(StatServDB, temp);

#endif /* STATSERVICES */

#ifdef NICKSERVICES

  ircsprintf(temp, "%s/%s", bpath, NickServDB);

  CopyFile(NickServDB, temp);

#ifdef CHANNELSERVICES
  ircsprintf(temp, "%s/%s", bpath, ChanServDB);

  CopyFile(ChanServDB, temp);
#endif /* CHANNELSERVICES */

#ifdef MEMOSERVICES
  ircsprintf(temp, "%s/%s", bpath, MemoServDB);

  CopyFile(MemoServDB, temp);
#endif /* MEMOSERVICES */

/* SeenServDB should be backed up too. -kre */
#ifdef SEENSERVICES
  ircsprintf(temp, "%s/%s", bpath, SeenServDB);

  CopyFile(SeenServDB, temp);
#endif

#endif /* NICKSERVICES */
} /* BackupDatabases() */
Пример #17
0
static void
ss_greplog(struct Luser *lptr, int ac, char **av )
{
	int             day;
	char            buf[MAXLINE + 1];
	char            date[10];
	FILE *          lf;
	char            grep_log_filename[MAXLINE + 1];
	int             i;
	struct tm *     tm;
	int             iCounter;

	if (ac < 3)
	{
		notice(n_StatServ,lptr->nick,
		       "Syntax: \002GREPLOG <service> <pattern> [days]\002");
		return;
	}

	if (ac > 3 && av[3] != NULL)
		day = atoi(av[3]);
	else
		day = 0;

	if (day < 0)
	{
		notice(n_StatServ, lptr->nick, "Day count should be positive.");
		return;
	}

	if (!GetService(av[1]))
	{
		notice(n_StatServ, lptr->nick, "Invalid service!");
		return;
	}

	iCounter = 0;
	tm = localtime(&current_ts);

	RecordCommand("%s: %s!%s@%s GREPLOG [%s %s] %s", n_StatServ, lptr->nick,
			lptr->username, lptr->hostname,
			av[1], av[2], (ac >= 4) ? av[3] : "");

	ircsprintf(date, "%4.4d%2.2d%2.2d",
	           tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);

	for (i = 0; i <= day; i++)
	{
		if (i == 0)
			ircsprintf(grep_log_filename, "%s/%s", LogPath, LogFile);
		else
			ircsprintf(grep_log_filename, "%s/%s.%8.8ld", LogPath, LogFile,
			           korectdat(atol(date), -i));

		if ((lf = fopen(grep_log_filename, "r")) == NULL)
		{
			notice(n_StatServ, lptr->nick, "No log file: %s",
			       grep_log_filename);
			continue;
		}
		notice(n_StatServ, lptr->nick,
		       "Searching for [%s] with service [%s] for [%d] days in file [%s]",
		       av[2], av[1], day, grep_log_filename);

		while (fgets(buf, sizeof(buf), lf))
		{
			if ((ircncmp(buf + 25, av[1], strlen(av[1])) == 0)
			        && match(av[2], buf + 25 + strlen(av[1]) + 2))
			{
				iCounter ++;
				notice(n_StatServ, lptr->nick,
				       "[%d] ... %s", iCounter, buf);
			}
		}
		fclose(lf);
	}
	notice(n_StatServ, lptr->nick, "End of search." );

	return;
} /* o_greplog */
Пример #18
0
static time_t io_loop(time_t delay)
{
  static char   to_send[200];
  static time_t lasttime  = 0;
  static long   lastrecvK = 0;
  static int    lrv       = 0;
  time_t        lasttimeofday;
  lasttimeofday = CurrentTime;

  if (CurrentTime < lasttimeofday)
    {
      ircsprintf(to_send, "System clock is running backwards - (%d < %d)",
                 CurrentTime, lasttimeofday);
      report_error(to_send, me.name, 0);
    }
  if(!next_gc)
    {
  	next_gc = CurrentTime + 600;
    }

  /*
   * This chunk of code determines whether or not
   * "life sucks", that is to say if the traffic
   * level is so high that standard server
   * commands should be restricted
   *
   * Changed by Taner so that it tells you what's going on
   * as well as allows forced on (long LCF), etc...
   */
  
  if ((CurrentTime - lasttime) >= LCF)
    {
      lrv = LRV * LCF;
      lasttime = CurrentTime;
      currlife = (float)((long)me.receiveK - lastrecvK)/(float)LCF;
      if (((long)me.receiveK - lrv) > lastrecvK )
        {
          if (!LIFESUX)
            {
              LIFESUX = 1;

              if (NOISYHTM)
                {
                  sprintf(to_send, 
                        "Entering high-traffic mode - (%.1fk/s > %dk/s)",
                                (float)currlife, LRV);
                  sendto_ops("%s", to_send);
                }
            }
          else
            {
              LIFESUX++;                /* Ok, life really sucks! */
              LCF += 2;                 /* Wait even longer */
              if (NOISYHTM) 
                {
                  sprintf(to_send,
                        "Still high-traffic mode %d%s (%d delay): %.1fk/s",
                                LIFESUX,
                                (LIFESUX & 0x04) ?  " (TURBO)" : "",
                                (int)LCF, (float)currlife);
                  sendto_ops("%s", to_send);
                }
            }
        }
      else
        {
          LCF = LOADCFREQ;
          if (LIFESUX)
            {
              LIFESUX = 0;
              if (NOISYHTM)
                sendto_ops("Resuming standard operation . . . .");
            }
        }
      lastrecvK = (long)me.receiveK;
    }

  /*
  ** We only want to connect if a connection is due,
  ** not every time through.  Note, if there are no
  ** active C lines, this call to Tryconnections is
  ** made once only; it will return 0. - avalon
  */
  if (nextconnect && CurrentTime >= nextconnect)
    nextconnect = try_connections(CurrentTime);

  /*
  ** take the smaller of the two 'timed' event times as
  ** the time of next event (stops us being late :) - avalon
  ** WARNING - nextconnect can return 0!
  */
  if (nextconnect)
    delay = IRCD_MIN(nextping, nextconnect);
  delay -= CurrentTime;
  /*
  ** Adjust delay to something reasonable [ad hoc values]
  ** (one might think something more clever here... --msa)
  ** We don't really need to check that often and as long
  ** as we don't delay too long, everything should be ok.
  ** waiting too long can cause things to timeout...
  ** i.e. PINGS -> a disconnection :(
  ** - avalon
  */
  if (delay < 1)
    delay = 1;
  else
    delay = IRCD_MIN(delay, TIMESEC);
  /*
   * We want to read servers on every io_loop, as well
   * as "busy" clients (which again, includes servers.
   * If "lifesux", then we read servers AGAIN, and then
   * flush any data to servers.
   *    -Taner
   */

#ifndef NO_PRIORITY
  read_message(0, FDL_SERVER);
  read_message(0, FDL_BUSY);
  if (LIFESUX)
    {
      read_message(0, FDL_SERVER);
      if (LIFESUX & 0x4)
        {       /* life really sucks */
          read_message(0, FDL_BUSY);
          read_message(0, FDL_SERVER);
        }
      flush_server_connections();
    }

  /*
   * CLIENT_SERVER = TRUE:
   *    If we're in normal mode, or if "lifesux" and a few
   *    seconds have passed, then read everything.
   * CLIENT_SERVER = FALSE:
   *    If it's been more than lifesux*2 seconds (that is, 
   *    at most 1 second, or at least 2s when lifesux is
   *    != 0) check everything.
   *    -Taner
   */
  {
    static time_t lslasttime=0;
#ifdef CLIENT_SERVER
    if (!LIFESUX || (lslasttime + LIFESUX) < CurrentTime)
      {
#else
    if ((lslasttime + (LIFESUX + 1)) < CurrentTime)
      {
#endif
        read_message(0, FDL_ALL); /*  check everything! */
        lslasttime = CurrentTime;
      }
   }
#else
  read_message(0, FDL_ALL); /*  check everything! */
  flush_server_connections();
#endif

  /*
  ** ...perhaps should not do these loops every time,
  ** but only if there is some chance of something
  ** happening (but, note that conf->hold times may
  ** be changed elsewhere--so precomputed next event
  ** time might be too far away... (similarly with
  ** ping times) --msa
  */

  if (CurrentTime >= nextping) {
    nextping = check_pings(CurrentTime);
    timeout_auth_queries(CurrentTime);
  }

  if (dorehash && !LIFESUX)
    {
      rehash(&me, &me, 1);
      dorehash = 0;
    }
  /*
  ** Flush output buffers on all connections now if they
  ** have data in them (or at least try to flush)
  ** -avalon
  */
  flush_connections(0);

#ifndef NO_PRIORITY
  fdlist_check(CurrentTime);
#endif
  
  if(CurrentTime >= next_gc)
  {
     block_garbage_collect();
     next_gc = CurrentTime + 600;
  }

  return delay;

}

/*
 * initalialize_global_set_options
 *
 * inputs       - none
 * output       - none
 * side effects - This sets all global set options needed 
 */

static void initialize_global_set_options(void)
{
  memset( &GlobalSetOptions, 0, sizeof(GlobalSetOptions));

  MAXCLIENTS = MAX_CLIENTS;
  NOISYHTM = NOISY_HTM;
  GlobalSetOptions.autoconn = 1;

#ifdef FLUD
  FLUDNUM = FLUD_NUM;
  FLUDTIME = FLUD_TIME;
  FLUDBLOCK = FLUD_BLOCK;
#endif

#ifdef IDLE_CHECK
  IDLETIME = MIN_IDLETIME;
#endif

#ifdef ANTI_SPAMBOT
  SPAMTIME = MIN_JOIN_LEAVE_TIME;
  SPAMNUM = MAX_JOIN_LEAVE_COUNT;
#endif

#ifdef ANTI_DRONE_FLOOD
  DRONETIME = DEFAULT_DRONE_TIME;
  DRONECOUNT = DEFAULT_DRONE_COUNT;
#endif

#ifdef NEED_SPLITCODE
 SPLITDELAY = (DEFAULT_SERVER_SPLIT_RECOVERY_TIME * 60);
 SPLITNUM = SPLIT_SMALLNET_SIZE;
 SPLITUSERS = SPLIT_SMALLNET_USER_SIZE;
 server_split_time = CurrentTime;
#endif

 /* End of global set options */

}
Пример #19
0
static void
mo_spoof(struct Client *client_p, struct Client *source_p,
         int parc, char *parv[])
{
  char *host, *spoof, *password;
  const char *tmp = NULL;
  const char *user = NULL;
  const char *flags = NULL;
  int i = 0;
#ifdef SPOOF_FILE
  int class_opers;
  FBFILE *f;
  char buffer[1024];
  struct AddressRec *arec;
#endif

  if (MyConnect(source_p) && !IsOperAdmin(source_p))
  {
    sendto_one(source_p, form_str(ERR_NOPRIVS),
               me.name, source_p->name, "SPOOF");
    return;
  }

  /* check the user@host mask */
  if (strchr(parv[1], '!') != NULL)
  {
    syntax:
    if (MyConnect(source_p))
      sendto_one(source_p, ":%s NOTICE %s :Syntax: SPOOF <umask@hmask> "
                 "<spoof/-> [flags/- [password]]", me.name, source_p->name);
    return;
  }

  (void) collapse(parv[1]);

  for (tmp = parv[1]; *tmp; tmp++)
    if (!IsKWildChar(*tmp))
      if (++i >= ConfigFileEntry.min_nonwildcard)
        break;
  if (i < ConfigFileEntry.min_nonwildcard)
  {
    if (MyConnect(source_p))
      sendto_one(source_p, ":%s NOTICE %s :Not enough non-wildcard characters "
                           "in user@host mask",
                           me.name, source_p->name);
    return;
  }

  host = strchr(parv[1], '@');
  if (host)
  {
    user = parv[1];
    *host = '\0';
    host++;
  }
  else
  {
    user = "******";
    host = parv[1];
  }

  /* check the spoof field */
  spoof = parv[2];
  if (spoof == NULL || !*spoof)
    goto syntax;

  if (spoof[0] != '-' || spoof[1] != '\0')
  {
    for (tmp = spoof; *tmp; tmp++)
      if (!IsHostChar(*tmp)) {
        if (MyConnect(source_p))
          sendto_one(source_p, ":%s NOTICE %s :The spoof [%s] is invalid",
                     me.name, source_p->name, spoof);
        return;
      }
    if (strlen(spoof) >= HOSTLEN) {
      if (MyConnect(source_p))
        sendto_one(source_p, ":%s NOTICE %s :Spoofs must be less than %d.."
                             "ignoring it", me.name, source_p->name, HOSTLEN);
      return;
    }
  }

  flags = (parc > 3) ? parv[3] : "-";
  password = (parc > 4 && parv[4][0]) ? parv[4] : NULL;

#ifdef PROPAGATE_SPOOF
  sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, LL_ICLIENT,
                ":%s SPOOF %s@%s %s %s :%s",
                source_p->name, user, host, spoof, flags, password ? password : "");
#endif

#ifdef SPOOF_FILE
  /* Walk through auth {} items and check if we have another auth block
   * for this hostname */
  for (i = 0; i < ATABLE_SIZE; i++)
    for (arec = atable[i]; arec; arec = arec->next)
      if (arec->type == CONF_CLIENT && !irccmp(arec->aconf->host, host) &&
        !irccmp(arec->aconf->user, user))
      {
        /* auth entry already exists */
        if (MyConnect(source_p))
          sendto_one(source_p,
                     ":%s NOTICE %s :auth for %s@%s already exists, you need "
                     "to use /DELSPOOF first", me.name, source_p->name, user, host);
#ifdef LOG_SPOOF
        sendto_realops_flags(UMODE_ALL, L_ALL,
                             "%s attemped to re-add auth for %s@%s "
                             "[spoof: %s, flags: %s]", source_p->name, user, host,
                             spoof, flags);
#endif
        return;
      }

  /* Add the spoof to the the spoof file */
  if ((f = fbopen(SPOOF_FILE, "a")) == NULL)
  {
    sendto_realops_flags(UMODE_ALL, L_ALL,
                         "Could not open %s file, auth for %s@%s "
                         "[spoof: %s, flags: %s, requested by %s] not added",
                         SPOOF_FILE, user, host, spoof, flags, source_p->name);
    return;
  }

  /* write the auth {} block */
  fbputs("auth {\n", f, 7);
  i = ircsprintf(buffer, "\tuser = \"%s@%s\";\n", user, host);
  fbputs(buffer, f, i);
  if (spoof[0] != '-' || spoof[1] != '\0')
  {
    i = ircsprintf(buffer, "\tspoof = \"%s\";\n", spoof);
    fbputs(buffer, f, i);
  }
  if (password)
  {
    i = ircsprintf(buffer, "\tpassword = \"%s\";\n", password);
    fbputs(buffer, f, i);
  }

  /* process given flags */
  i = class_opers = 0;
  for (tmp = flags; *tmp; ++tmp)
    switch (*tmp)
    {
      case 't': i |= CONF_FLAGS_NO_TILDE;      /* no_tilde = yes; */
                break;
      case 'i': i |= CONF_FLAGS_NEED_IDENTD;   /* need_ident = yes; */
                break;
      case 'k': i |= CONF_FLAGS_EXEMPTKLINE;   /* kline_exempt = yes; */
                break;
      case 'g': i |= CONF_FLAGS_EXEMPTGLINE;   /* gline_exempt = yes; */
                break;
      case 'l': i |= CONF_FLAGS_NOLIMIT;       /* exceed_limit = yes; */
                break;
      case 'o': class_opers = 1;               /* class = "opers"; */
                break;
      case 'f': i |= CONF_FLAGS_CAN_FLOOD;     /* can_flood = yes; */
                break;
      case 'p': i|= CONF_FLAGS_NEED_PASSWORD;  /* need_password = yes; */
    }

  if (i)
  {
    fbputs("\tflags = ", f, 9);
    try_flag(f, &i, CONF_FLAGS_NO_TILDE, "no_tilde");
    try_flag(f, &i, CONF_FLAGS_NEED_IDENTD, "need_ident");
    try_flag(f, &i, CONF_FLAGS_EXEMPTKLINE, "kline_exempt");
    try_flag(f, &i, CONF_FLAGS_EXEMPTGLINE, "gline_exempt");
    try_flag(f, &i, CONF_FLAGS_NOLIMIT, "exceed_limit");
    try_flag(f, &i, CONF_FLAGS_CAN_FLOOD, "can_flood");
    try_flag(f, &i, CONF_FLAGS_NEED_PASSWORD, "need_password");
  }

  if (class_opers)
    fbputs("\tclass = \"opers\";\n", f, 18);
  else
    fbputs("\tclass = \"users\";\n", f, 18);

  fbputs("};\n\n", f, 4);
  fbclose(f);

  rehash(0);
#endif

#ifdef LOG_SPOOF
  sendto_realops_flags(UMODE_ALL, L_ALL,
                       "%s added auth for %s@%s [spoof: %s, flags: %s]",
                       source_p->name, user, host, spoof, flags);
  ilog(L_TRACE, "%s added auth for %s@%s [spoof: %s, flags: %s]",
                source_p->name, user, host, spoof, flags);
#endif
}
Пример #20
0
static void
do_ison(struct Client *client_p, struct Client *up, struct Client *source_p,
        int parc, char *parv[])
{
  struct Client *target_p = NULL;
  char *nick;
  char *p;
  char *current_insert_point, *current_insert_point2;
  char buf[IRCD_BUFSIZE];
  char buf2[IRCD_BUFSIZE];
  int len;
  int i;
  int done = 0;
  int relay_to_hub = 0;

  current_insert_point2 = buf2;
  *buf2 = '\0';

  len = ircsprintf(buf, form_str(RPL_ISON), me.name, parv[0]);
  current_insert_point = buf + len;

  /* rfc1459 is ambigious about how to handle ISON
   * this should handle both interpretations.
   */
  for (i = 1; i < parc; i++)
  {
    for (nick = strtoken(&p, parv[i], " "); nick;
         nick = strtoken(&p, NULL, " "))
    {
      if ((target_p = find_person(client_p, nick)))
      {
        len = strlen(target_p->name);

        if ((current_insert_point + (len + 5)) < (buf + sizeof(buf)))
        {
          memcpy(current_insert_point, target_p->name, len);
          current_insert_point += len;
          *current_insert_point++ = ' ';
        }
        else
        {
          done = 1;
          break;
        }
      }

      if (up)
      {
        /* Build up a single list, for use if we relay.. */
        len = strlen(nick);

        if ((current_insert_point2 + len + 5) < (buf2 + sizeof(buf2)))
        {
          memcpy(current_insert_point2, nick, len);
          current_insert_point2 += len;
          *current_insert_point2++ = ' ';
        }

        if (target_p == NULL)
        {
          /*
           * XXX Ick. we need to ask our hub if nick is online.
           * it's probably safest to relay the whole command,
           * unless we can answer it fully ourselves.
           * -davidt
           */
          relay_to_hub = 1;

          /* Also cache info about nick */
          sendto_one(up, ":%s NBURST %s", ID_or_name(&me, up), nick);
        }
      }
    }

    if (done)
      break;
  }

  /*  current_insert_point--;
   *  Do NOT take out the trailing space, it breaks ircII
   *  --Rodder */

  *current_insert_point  = '\0';
  *current_insert_point2 = '\0'; 
  
  if (relay_to_hub)
    sendto_one(up, ":%s ISON :%s", ID_or_name(source_p, up), buf2);
  else
    sendto_one(source_p, "%s", buf);
}
Пример #21
0
/*
 *
 *      parc    number of arguments ('sender' counted as one!)
 *      parv[0] pointer to 'sender' (may point to empty string) (not used)
 *      parv[1]..parv[parc-1]
 *              pointers to additional parameters, this is a NULL
 *              terminated list (parv[parc] == NULL).
 *
 * *WARNING*
 *      Numerics are mostly error reports. If there is something
 *      wrong with the message, just *DROP* it! Don't even think of
 *      sending back a neat error message -- big danger of creating
 *      a ping pong error message...
 */
static void
do_numeric(char numeric[], struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Client *target_p;
	struct Channel *chptr;

	if(parc < 2 || !IsServer(source_p))
		return;

	/* Remap low number numerics. */
	if(numeric[0] == '0')
		numeric[0] = '1';

	/*
	 * Prepare the parameter portion of the message into 'buffer'.
	 * (Because the buffer is twice as large as the message buffer
	 * for the socket, no overflow can occur here... ...on current
	 * assumptions--bets are off, if these are changed --msa)
	 * Note: if buffer is non-empty, it will begin with SPACE.
	 */
	if(parc > 1)
	{
		char *t = buffer;	/* Current position within the buffer */
		int i;
		int tl;		/* current length of presently being built string in t */
		for (i = 2; i < (parc - 1); i++)
		{
			tl = ircsprintf(t, " %s", parv[i]);
			t += tl;
		}
		ircsprintf(t, " :%s", parv[parc - 1]);
	}

	if((target_p = find_client(parv[1])) != NULL)
	{
		if(IsMe(target_p))
		{
			/*
			 * We shouldn't get numerics sent to us,
			 * any numerics we do get indicate a bug somewhere..
			 */
			/* ugh.  this is here because of nick collisions.  when two servers
			 * relink, they burst each other their nicks, then perform collides.
			 * if there is a nick collision, BOTH servers will kill their own
			 * nicks, and BOTH will kill the other servers nick, which wont exist,
			 * because it will have been already killed by the local server.
			 *
			 * unfortunately, as we cant guarantee other servers will do the
			 * "right thing" on a nick collision, we have to keep both kills.  
			 * ergo we need to ignore ERR_NOSUCHNICK. --fl_
			 */
			/* quick comment. This _was_ tried. i.e. assume the other servers
			 * will do the "right thing" and kill a nick that is colliding.
			 * unfortunately, it did not work. --Dianora
			 */
			if(atoi(numeric) != ERR_NOSUCHNICK)
				sendto_realops_flags(UMODE_ALL, L_ADMIN,
						     "*** %s(via %s) sent a %s numeric to me: %s",
						     source_p->name, client_p->name, numeric,
						     buffer);
			return;
		}
		else if(target_p->from == client_p)
		{
			/* This message changed direction (nick collision?)
			 * ignore it.
			 */
			return;
		}

		/* csircd will send out unknown umode flag for +a (admin), drop it here. */
		if((atoi(numeric) == ERR_UMODEUNKNOWNFLAG) && MyClient(target_p))
			return;

		/* Fake it for server hiding, if its our client */
		if(ConfigServerHide.hide_servers && MyClient(target_p) && !IsOper(target_p))
			sendto_one(target_p, ":%s %s %s%s", me.name, numeric, parv[1], buffer);
		else
			sendto_one(target_p, ":%s %s %s%s", source_p->name, numeric, parv[1],
				   buffer);
		return;
	}
	else if((chptr = hash_find_channel(parv[1])) != NULL)
		sendto_channel_local(ALL_MEMBERS, chptr,
				     ":%s %s %s %s",
				     source_p->name, numeric, chptr->chname, buffer);
}
Пример #22
0
static void
ss_stats(struct Luser *lptr, int ac, char **av)

{
	float avgops, avguc, avgus;
	struct tm *tmp_tm;
	char str[MAXLINE + 1], tmp[MAXLINE + 1];
	char **tav;
	time_t currtime;

	RecordCommand("%s: %s!%s@%s STATS",
	              n_StatServ,
	              lptr->nick,
	              lptr->username,
	              lptr->hostname);

	avgops = Network->TotalOperators / Network->TotalServers;
	if (Network->TotalChannels > 0.0)
		avguc = Network->TotalUsers / Network->TotalChannels;
	else
		avguc = 0;
	avgus = Network->TotalUsers / Network->TotalServers;

	notice(n_StatServ, lptr->nick,
	       "Current Users:              %1.0f (avg. %1.2f users per server)",
	       Network->TotalUsers,
	       avgus);
	notice(n_StatServ, lptr->nick,
	       "Current Operators:          %1.0f (avg. %1.2f operators per server)",
	       Network->TotalOperators,
	       avgops);
	notice(n_StatServ, lptr->nick,
	       "Current Channels:           %1.0f (avg. %1.2f users per channel)",
	       Network->TotalChannels,
	       avguc);
	notice(n_StatServ, lptr->nick,
	       "Current Servers:            %1.0f",
	       Network->TotalServers);

	strlcpy(str, ctime(&Network->MaxUsers_ts), sizeof(str));
	str[strlen(str) - 1] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Users:                  %ld on %s",
	       Network->MaxUsers,
	       str);

	if (Network->MaxOperators_ts)
	{
		strlcpy(str, "on ", sizeof(str));
		strlcat(str, ctime(&Network->MaxOperators_ts), sizeof(str));
		str[strlen(str) - 1] = '\0';
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Operators:              %ld %s",
	       Network->MaxOperators,
	       str);

	if (Network->MaxChannels_ts)
	{
		strlcpy(str, "on ", sizeof(str));
		strlcat(str, ctime(&Network->MaxChannels_ts), sizeof(str));
		str[strlen(str) - 1] = '\0';
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Channels:               %ld %s",
	       Network->MaxChannels,
	       str);

	strlcpy(str, ctime(&Network->MaxServers_ts), sizeof(str));
	str[strlen(str) - 1] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Servers:                %ld on %s",
	       Network->MaxServers,
	       str);

	notice(n_StatServ, lptr->nick,
	       "Identd Users:               %ld",
	       Network->Identd);
	notice(n_StatServ, lptr->nick,
	       "Non-Identd Users:           %ld",
	       Network->NonIdentd);
	notice(n_StatServ, lptr->nick,
	       "Resolving Host Users:       %ld",
	       Network->ResHosts);
	notice(n_StatServ, lptr->nick,
	       "Non-Resolving Host Users:   %ld",
	       (long) Network->TotalUsers - Network->ResHosts);

	currtime = current_ts;
	strlcpy(tmp, ctime(&currtime), sizeof(tmp));
	SplitBuf(tmp, &tav);
	ircsprintf(str, "%s %s %s, %s", tav[0], tav[1], tav[2], tav[4]);
	notice(n_StatServ, lptr->nick,
	       "-- \002So far today:\002 (%s) --",
	       str);
	MyFree(tav);

	if (Network->MaxUsersT_ts)
	{
		tmp_tm = localtime(&Network->MaxUsersT_ts);
		ircsprintf(str, "at %d:%02d:%02d", tmp_tm->tm_hour, tmp_tm->tm_min,
		           tmp_tm->tm_sec);
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Users:                  %ld %s",
	       Network->MaxUsersT,
	       str);

	if (Network->MaxOperatorsT_ts)
	{
		tmp_tm = localtime(&Network->MaxOperatorsT_ts);
		ircsprintf(str, "at %d:%02d:%02d", tmp_tm->tm_hour, tmp_tm->tm_min,
		           tmp_tm->tm_sec);
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Operators:              %ld %s",
	       Network->MaxOperatorsT,
	       str);

	if (Network->MaxChannelsT_ts)
	{
		tmp_tm = localtime(&Network->MaxChannelsT_ts);
		ircsprintf(str, "at %d:%02d:%02d", tmp_tm->tm_hour, tmp_tm->tm_min,
		           tmp_tm->tm_sec);
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Channels:               %ld %s",
	       Network->MaxChannelsT,
	       str);

	if (Network->MaxServersT_ts)
	{
		tmp_tm = localtime(&Network->MaxServersT_ts);
		ircsprintf(str, "at %d:%02d:%02d", tmp_tm->tm_hour, tmp_tm->tm_min,
		           tmp_tm->tm_sec);
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Servers:                %ld %s",
	       Network->MaxServersT,
	       str);

	notice(n_StatServ, lptr->nick,
	       "Operator Kills:             %ld",
	       Network->OperKillsT);
	notice(n_StatServ, lptr->nick,
	       "Server Kills:               %ld",
	       Network->ServKillsT);
} /* ss_stats() */
Пример #23
0
static void
ShowServerInfo(struct Server *servptr, struct Luser *lptr, int showinfo)

{
	char str[MAXLINE + 1];

	assert(servptr != 0);
	assert(lptr != 0);

	if (!showinfo)
	{
#ifdef SPLIT_INFO
		if (!servptr->split_ts)
#endif

			notice(n_StatServ, lptr->nick,
			       "%-30s connected: %s, users: %d",
			       servptr->name,
			       timeago(servptr->connect_ts, 0),
			       servptr->numusers);
#ifdef SPLIT_INFO

		else
			notice(n_StatServ, lptr->nick,
			       "%-30s currently in \002netsplit\002 for %s",
			       servptr->name,
			       timeago(servptr->split_ts, 0));
#endif

		return;
	}

#ifdef SPLIT_INFO
	if (!servptr->split_ts)
#endif

		notice(n_StatServ, lptr->nick,
		       "Statistics for server: \002%s\002",
		       servptr->name);
#ifdef SPLIT_INFO

	else
		notice(n_StatServ, lptr->nick,
		       "Last known statistics for server: \002%s\002",
		       servptr->name);
#endif

	notice(n_StatServ, lptr->nick,
	       "Current Clients:       %ld",
	       servptr->numusers);
	notice(n_StatServ, lptr->nick,
	       "Current Opers:         %ld",
	       servptr->numopers);
	notice(n_StatServ, lptr->nick,
	       "Current Servers:       %ld",
	       servptr->numservs);

	if (servptr->maxusers_ts)
	{
		strlcpy(str, "on ", sizeof(str));
		strlcat(str, ctime(&servptr->maxusers_ts), sizeof(str));
		str[strlen(str) - 1] = '\0';
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Clients:           %ld %s",
	       servptr->maxusers,
	       str);

	if (servptr->maxopers_ts)
	{
		strlcpy(str, "on ", sizeof(str));
		strlcat(str, ctime(&servptr->maxopers_ts), sizeof(str));
		str[strlen(str) - 1] = '\0';
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Opers:             %ld %s",
	       servptr->maxopers,
	       str);

	if (servptr->maxservs_ts)
	{
		strlcpy(str, "on ", sizeof(str));
		strlcat(str, ctime(&servptr->maxservs_ts), sizeof(str));
		str[strlen(str) - 1] = '\0';
	}
	else
		str[0] = '\0';
	notice(n_StatServ, lptr->nick,
	       "Max Servers:           %ld %s",
	       servptr->maxservs,
	       str);

	notice(n_StatServ, lptr->nick,
	       "Identd Users:          %ld",
	       servptr->numidentd);
	notice(n_StatServ, lptr->nick,
	       "Non-Identd Users:      %ld",
	       servptr->numusers - servptr->numidentd);
	notice(n_StatServ, lptr->nick,
	       "Resolving Hosts:       %ld",
	       servptr->numreshosts);
	notice(n_StatServ, lptr->nick,
	       "Non-Resolving Hosts:   %ld",
	       servptr->numusers - servptr->numreshosts);

	notice(n_StatServ, lptr->nick,
	       "Operator Kills:        %ld",
	       servptr->numoperkills);
	notice(n_StatServ, lptr->nick,
	       "Server Kills:          %ld",
	       servptr->numservkills);

	if (servptr->ping > 0.0)
	{
		notice(n_StatServ, lptr->nick,
		       "Current Ping:          %5.4f seconds",
		       servptr->ping);

		if ((servptr->maxping > 0.0) && servptr->maxping_ts)
		{
			ircsprintf(str, "on %s", ctime(&servptr->maxping_ts));
			str[strlen(str) - 1] = '\0';
			notice(n_StatServ, lptr->nick,
			       "Highest Ping:          %5.4f seconds %s",
			       servptr->maxping,
			       str);
		}

		if ((servptr->minping > 0.0) && servptr->minping_ts)
		{
			ircsprintf(str, "on %s", ctime(&servptr->minping_ts));
			str[strlen(str) - 1] = '\0';
			notice(n_StatServ, lptr->nick,
			       "Lowest Ping:           %5.4f seconds %s",
			       servptr->minping,
			       str);
		}
	}

	if (servptr->uplink)
		notice(n_StatServ, lptr->nick,
		       "Current Hub:           %s (connected for [%s])",
		       servptr->uplink->name,
		       timeago(servptr->connect_ts, 0));
#ifdef SPLIT_INFO

	else
		notice(n_StatServ, lptr->nick,
		       "Currently in \002netsplit\002 for %s",
		       servptr->name,
		       timeago(servptr->connect_ts, 0));
#endif
} /* ShowServerInfo() */
Пример #24
0
static void
ss_server(struct Luser *lptr, int ac, char **av)

{
	struct Server *servptr,
				*hub;
	char argbuf[MAXLINE + 1],
	str[MAXLINE + 1];
	char *target; /* target server */
	int maxusers, /* -maxusers */
	minusers, /* -minusers */
	info;     /* -info */
	int ii,
	alen,
	cnt;

	if (ac < 2)
{
		notice(n_StatServ, lptr->nick,
		       "Syntax: SERVER <server | mask> [options]");
		notice(n_StatServ, lptr->nick,
		       ERR_MORE_INFO,
		       n_StatServ,
		       "SERVER");
		return;
	}

	hub = NULL;
	maxusers = -1;
	minusers = -1;
	target = NULL;
	info = 0;

	/*
	 * Parse their args
	 */
	for (ii = 1; ii < ac; ii++)
	{
		alen = strlen(av[ii]);

		if (!ircncmp(av[ii], "-maxusers", alen))
		{
			if (++ii >= ac)
			{
				notice(n_StatServ, lptr->nick,
				       "No maximum user count given");
				return;
			}

			maxusers = atoi(av[ii]);
		}
		else if (!ircncmp(av[ii], "-minusers", alen))
		{
			if (++ii >= ac)
			{
				notice(n_StatServ, lptr->nick,
				       "No minimum user count given");
				return;
			}

			minusers = atoi(av[ii]);
		}
		else if (!ircncmp(av[ii], "-info", alen))
			info = 1;
		else if (!ircncmp(av[ii], "-hub", alen))
		{
			if (++ii >= ac)
			{
				notice(n_StatServ, lptr->nick,
				       "No hub server given");
				return;
			}

			if (!(hub = FindServer(av[ii])))
			{
				notice(n_StatServ, lptr->nick,
				       "No such server: %s",
				       av[ii]);
				return;
			}
		}
		else
		{
			if (!target)
				target = av[ii];
		}
	}

	if (!target)
	{
		notice(n_StatServ, lptr->nick,
		       "No target server specified");
		return;
	}

	argbuf[0] = '\0';

	if (maxusers >= 0)
	{
		ircsprintf(str, "-maxusers %d ", maxusers);
		strlcat(argbuf, str, sizeof(argbuf));
	}

	if (minusers >= 0)
	{
		ircsprintf(str, "-minusers %d ", minusers);
		strlcat(argbuf, str, sizeof(argbuf));
	}

	if (info)
		strlcat(argbuf, "-info ", sizeof(argbuf));

	if (hub)
	{
		ircsprintf(str, "-hub %s ", hub->name);
		strlcat(argbuf, str, sizeof(argbuf));
	}

	RecordCommand("%s: %s!%s@%s SERVER [%s] %s",
	              n_StatServ,
	              lptr->nick,
	              lptr->username,
	              lptr->hostname,
	              target,
	              argbuf);

	if ((servptr = FindServer(target)))
	{
		ShowServerInfo(servptr, lptr, 1);
		return;
	}

	cnt = 0;
	for (servptr = ServerList; servptr; servptr = servptr->next)
	{
		if (!match(target, servptr->name))
			continue;

		if (((maxusers >= 0) && (servptr->numusers > maxusers)) ||
		        ((minusers >= 0) && (servptr->numusers < minusers)))
			continue;
		else if (hub && (servptr->uplink != hub))
			continue;

		/*
		 * servptr passes all the tests
		 */

		++cnt;

		notice(n_StatServ, lptr->nick,
		       "-----");

		ShowServerInfo(servptr, lptr, info);
	}

	notice(n_StatServ, lptr->nick,
	       "%d match%s found",
	       cnt,
	       (cnt == 1) ? "" : "es");
} /* ss_server() */
Пример #25
0
/* clicap_generate()
 *   Generates a list of capabilities.
 *
 * Inputs: client to send to, subcmd to send,
 *         flags to match against: 0 to do none, -1 if client has no flags,
 *         int to whether we are doing CAP CLEAR
 * Outputs: None
 */
static void
clicap_generate(struct Client *source_p, const char *subcmd, int flags, int clear)
{
	char buf[BUFSIZE];
	char capbuf[BUFSIZE];
	char *p;
	int buflen = 0;
	int curlen, mlen;
	int i;

	mlen = ircsprintf(buf, ":%s CAP %s %s",
			me.name, 
			EmptyString(source_p->name) ? "*" : source_p->name, 
			subcmd);

	p = capbuf;
	buflen = mlen;

	/* shortcut, nothing to do */
	if(flags == -1)
	{
		sendto_one(source_p, "%s :", buf);
		return;
	}

	for(i = 0; i < CLICAP_LIST_LEN; i++)
	{
		if(flags)
		{
			if(!IsCapable(source_p, clicap_list[i].cap_serv))
				continue;
			/* they are capable of this, check sticky */
			else if(clear && clicap_list[i].flags & CLICAP_FLAGS_STICKY)
				continue;
		}

		/* \r\n\0, possible "-~=", space, " *" */
		if(buflen + clicap_list[i].namelen >= BUFSIZE - 10)
		{
			/* remove our trailing space -- if buflen == mlen
			 * here, we didnt even succeed in adding one.
			 */
			if(buflen != mlen)
				*(p - 1) = '\0';
			else
				*p = '\0';

			sendto_one(source_p, "%s * :%s", buf, capbuf);
			p = capbuf;
			buflen = mlen;
		}

		if(clear)
		{
			*p++ = '-';
			buflen++;

			/* needs a client ack */
			if(clicap_list[i].cap_cli && 
			   IsCapable(source_p, clicap_list[i].cap_cli))
			{
				*p++ = '~';
				buflen++;
			}
		}
		else
		{
			if(clicap_list[i].flags & CLICAP_FLAGS_STICKY)
			{
				*p++ = '=';
				buflen++;
			}

			/* if we're doing an LS, then we only send this if
			 * they havent ack'd
			 */
			if(clicap_list[i].cap_cli &&
			   (!flags || !IsCapable(source_p, clicap_list[i].cap_cli)))
			{
				*p++ = '~';
				buflen++;
			}
		}

		curlen = ircsprintf(p, "%s ", clicap_list[i].name);
		p += curlen;
		buflen += curlen;
	}

	/* remove trailing space */
	if(buflen != mlen)
		*(p - 1) = '\0';
	else
		*p = '\0';

	sendto_one(source_p, "%s :%s", buf, capbuf);
}
Пример #26
0
/*
 * ms_bmask()
 *
 * inputs	- parv[0] = SID
 *		  parv[1] = TS
 *		  parv[2] = channel name
 *		  parv[3] = type of ban to add ('b' 'I' or 'e')
 *		  parv[4] = space delimited list of masks to add
 * outputs	- none
 * side effects	- propgates unchanged bmask line to CAP_TS6 servers,
 *		  sends plain modes to the others.  nothing is sent
 *		  to the server the issuing server is connected through
 */
static void
ms_bmask(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
  static char modebuf[BUFSIZE];
  static char parabuf[BUFSIZE];
  static char banbuf[BUFSIZE];
  struct Channel *chptr;
  char *s, *t, *mbuf, *pbuf;
  long mode_type;
  int mlen;
  int plen = 0;
  int tlen;
  int modecount = 0;
  int needcap = NOCAPS;

  if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
    return;

  if((chptr = hash_find_channel(parv[2])) == NULL)
    return;

  /* TS is higher, drop it. */
  if(atol(parv[1]) > chptr->channelts)
    return;

  switch(parv[3][0])
  {
    case 'b':
      mode_type = CHFL_BAN;
      break;

    case 'e':
      mode_type = CHFL_EXCEPTION;
      needcap = CAP_EX;
      break;

    case 'I':
      mode_type = CHFL_INVEX;
      needcap = CAP_IE;
      break;

    /* maybe we should just blindly propagate this? */
    default:
      return; 
  }

  parabuf[0] = '\0';
  s = banbuf;
  strlcpy(s, parv[4], sizeof(banbuf));

  /* only need to construct one buffer, for non-ts6 servers */
  mlen = ircsprintf(modebuf, ":%s MODE %s +",
                    source_p->name, chptr->chname);
  mbuf = modebuf + mlen;
  pbuf = parabuf;

  if((t = strchr(s, ' ')) != NULL)
    *t++ = '\0';

  while(s != NULL)
  {
    tlen = strlen(s);

    /* I dont even want to begin parsing this.. */
    if(tlen > MODEBUFLEN)
      break;

    if(tlen && add_id(source_p, chptr, s, mode_type))
    {
      /* this new one wont fit.. */
      if(mlen + MAXMODEPARAMS + plen + tlen > BUFSIZE - 4 ||
         modecount >= MAXMODEPARAMS)
      {
        *mbuf = '\0';
        *(pbuf - 1) = '\0';
        sendto_channel_local(ALL_MEMBERS, chptr, "%s %s",
                             modebuf, parabuf);
        sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
                      "%s %s",
                      modebuf, parabuf);

        mbuf = modebuf + mlen;
        pbuf = parabuf;
        plen = modecount = 0;
      }

      *mbuf++ = parv[3][0];
      plen = ircsprintf(pbuf, "%s ", s);
      pbuf += plen;
      modecount++;
    }

    s = t;

    if(s != NULL)
    {
      /* trailing space marking the end. */
      if(*s == '\0')
        break;

      if((t = strchr(s, ' ')) != NULL)
        *t++ = '\0';
    }
  }

  if(modecount)
  {
    *mbuf = *(pbuf - 1) = '\0';
    sendto_channel_local(ALL_MEMBERS, chptr, "%s %s", modebuf, parabuf);
    sendto_server(client_p, NULL, chptr, needcap, CAP_TS6, NOFLAGS,
                  "%s %s", modebuf, parabuf);
  }

  /* assumption here is that since the server sent BMASK, they are TS6, so they have an ID */
  sendto_server(client_p, NULL, chptr, CAP_TS6|needcap, NOCAPS, NOFLAGS,
                ":%s BMASK %lu %s %s :%s",
                 source_p->id, (unsigned long)chptr->channelts, chptr->chname,
                 parv[3], parv[4]);
}
Пример #27
0
int _register_user(aClient *cptr, aClient *sptr, char *nick, char *username, char *umode, char *virthost, char *ip)
{
	ConfigItem_ban *bconf;
	char *parv[3], *tmpstr;
#ifdef HOSTILENAME
	char stripuser[USERLEN + 1], *u1 = stripuser, *u2, olduser[USERLEN + 1],
	    userbad[USERLEN * 2 + 1], *ubad = userbad, noident = 0;
#endif
	int  xx;
	anUser *user = sptr->user;
	aClient *nsptr;
	int  i;
	char mo[256];
	char *tkllayer[9] = {
		me.name,	/*0  server.name */
		"+",		/*1  +|- */
		"z",		/*2  G   */
		"*",		/*3  user */
		NULL,		/*4  host */
		NULL,
		NULL,		/*6  expire_at */
		NULL,		/*7  set_at */
		NULL		/*8  reason */
	};
	aTKline *savetkl = NULL;
	ConfigItem_tld *tlds;
	cptr->last = TStime();
	parv[0] = sptr->name;
	parv[1] = parv[2] = NULL;
	nick = sptr->name; /* <- The data is always the same, but the pointer is sometimes not,
	                    *    I need this for one of my modules, so do not remove! ;) -- Syzop */
	
	if (MyConnect(sptr))
	{
		if ((i = check_client(sptr, username))) {
			/* This had return i; before -McSkaf */
			if (i == -5)
				return FLUSH_BUFFER;

			sendto_snomask(SNO_CLIENT,
			    "*** Notice -- %s from %s.",
			    i == -3 ? "Too many connections" :
			    "Unauthorized connection", get_client_host(sptr));
			ircstp->is_ref++;
			ircsprintf(mo, "This server is full.");
			return
			    exit_client(cptr, sptr, &me,
			    i ==
			    -3 ? mo :
			    "You are not authorized to connect to this server");
		}

		if (sptr->hostp)
		{
			/* reject ascci < 32 and ascii >= 127 (note: upper resolver might be even more strict) */
			for (tmpstr = sptr->sockhost; *tmpstr > ' ' && *tmpstr < 127; tmpstr++);
			
			/* if host contained invalid ASCII _OR_ the DNS reply is an IP-like reply
			 * (like: 1.2.3.4), then reject it and use IP instead.
			 */
			if (*tmpstr || !*user->realhost || (isdigit(*sptr->sockhost) && isdigit(*tmpstr - 1)))
				strncpyzt(sptr->sockhost, (char *)Inet_ia2p((struct IN_ADDR*)&sptr->ip), sizeof(sptr->sockhost));
		}
		strncpyzt(user->realhost, sptr->sockhost, sizeof(sptr->sockhost)); /* SET HOSTNAME */

		/*
		 * I do not consider *, ~ or ! 'hostile' in usernames,
		 * as it is easy to differentiate them (Use \*, \? and \\)
		 * with the possible?
		 * exception of !. With mIRC etc. ident is easy to fake
		 * to contain @ though, so if that is found use non-ident
		 * username. -Donwulff
		 *
		 * I do, We only allow a-z A-Z 0-9 _ - and . now so the
		 * !strchr(sptr->username, '@') check is out of date. -Cabal95
		 *
		 * Moved the noident stuff here. -OnyxDragon
		 */
		if (!(sptr->flags & FLAGS_DOID)) 
			strncpyzt(user->username, username, USERLEN + 1);
		else if (sptr->flags & FLAGS_GOTID) 
			strncpyzt(user->username, sptr->username, USERLEN + 1);
		else
		{

			/* because username may point to user->username */
			char temp[USERLEN + 1];
			strncpyzt(temp, username, USERLEN + 1);
			if (IDENT_CHECK == 0) {
				strncpyzt(user->username, temp, USERLEN + 1);
			}
			else {
				*user->username = '******';
				strncpyzt((user->username + 1), temp, USERLEN);
#ifdef HOSTILENAME
				noident = 1;
#endif
			}

		}
#ifdef HOSTILENAME
		/*
		 * Limit usernames to just 0-9 a-z A-Z _ - and .
		 * It strips the "bad" chars out, and if nothing is left
		 * changes the username to the first 8 characters of their
		 * nickname. After the MOTD is displayed it sends numeric
		 * 455 to the user telling them what(if anything) happened.
		 * -Cabal95
		 *
		 * Moved the noident thing to the right place - see above
		 * -OnyxDragon
		 * 
		 * No longer use nickname if the entire ident is invalid,
                 * if thats the case, it is likely the user is trying to cause
		 * problems so just ban them. (Using the nick could introduce
		 * hostile chars) -- codemastr
		 */
		for (u2 = user->username + noident; *u2; u2++)
		{
			if (isallowed(*u2))
				*u1++ = *u2;
			else if (*u2 < 32)
			{
				/*
				 * Make sure they can read what control
				 * characters were in their username.
				 */
				*ubad++ = '^';
				*ubad++ = *u2 + '@';
			}
			else
				*ubad++ = *u2;
		}
		*u1 = '\0';
		*ubad = '\0';
		if (strlen(stripuser) != strlen(user->username + noident))
		{
			if (stripuser[0] == '\0')
			{
				return exit_client(cptr, cptr, cptr, "Hostile username. Please use only 0-9 a-z A-Z _ - and . in your username.");
			}

			strcpy(olduser, user->username + noident);
			strncpy(user->username + 1, stripuser, USERLEN - 1);
			user->username[0] = '~';
			user->username[USERLEN] = '\0';
		}
		else
			u1 = NULL;
#endif

		/*
		 * following block for the benefit of time-dependent K:-lines
		 */
		if ((bconf =
		    Find_ban(sptr, make_user_host(user->username, user->realhost),
		    CONF_BAN_USER)))
		{
			ircstp->is_ref++;
			sendto_one(cptr,
			    ":%s %d %s :*** You are not welcome on this server (%s)"
			    " Email %s for more information.",
			    me.name, ERR_YOUREBANNEDCREEP,
			    cptr->name, bconf->reason ? bconf->reason : "",
			    KLINE_ADDRESS);
			return exit_client(cptr, cptr, cptr, "You are banned");
		}
		if ((bconf = Find_ban(NULL, sptr->info, CONF_BAN_REALNAME)))
		{
			ircstp->is_ref++;
			sendto_one(cptr,
			    ":%s %d %s :*** Your GECOS (real name) is not allowed on this server (%s)"
			    " Please change it and reconnect",
			    me.name, ERR_YOUREBANNEDCREEP,
			    cptr->name, bconf->reason ? bconf->reason : "");

			return exit_client(cptr, sptr, &me,
			    "Your GECOS (real name) is banned from this server");
		}
		tkl_check_expire(NULL);
		/* Check G/Z lines before shuns -- kill before quite -- codemastr */
		if ((xx = find_tkline_match(sptr, 0)) < 0)
		{
			ircstp->is_ref++;
			return xx;
		}
		find_shun(sptr);

		/* Technical note regarding next few lines of code:
		 * If the spamfilter matches, depending on the action:
		 *  If it's block/dccblock/whatever the retval is -1 ===> we return, client stays "locked forever".
		 *  If it's kill/tklline the retval is -2 ==> we return with -2 (aka: FLUSH_BUFFER)
		 *  If it's action is viruschan the retval is -5 ==> we continue, and at the end of this return
		 *    take special actions. We cannot do that directly here since the user is not fully registered
		 *    yet (at all).
		 *  -- Syzop
		 */
		spamfilter_build_user_string(spamfilter_user, sptr->name, sptr);
		xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, &savetkl);
		if ((xx < 0) && (xx != -5))
			return xx;

		RunHookReturnInt(HOOKTYPE_PRE_LOCAL_CONNECT, sptr, !=0);
	}
	else
	{
Пример #28
0
static void
accept_connection(int pfd, void *data)
{
	static time_t last_oper_notice = 0;

	struct irc_sockaddr_storage sai;
	socklen_t addrlen = sizeof(sai);
	int fd;
	struct Listener *listener = data;
	struct ConfItem *aconf;
	char buf[BUFSIZE];

	s_assert(listener != NULL);
	if(listener == NULL)
		return;


	for(;;)			/* loop until something breaks us out */
	{

		/*
		 * There may be many reasons for error return, but
		 * in otherwise correctly working environment the
		 * probable cause is running out of file descriptors
		 * (EMFILE, ENFILE or others?). The man pages for
		 * accept don't seem to list these as possible,
		 * although it's obvious that it may happen here.
		 * Thus no specific errors are tested at this
		 * point, just assume that connections cannot
		 * be accepted until some old is closed first.
		 */

		fd = comm_accept(listener->fd, (struct sockaddr *) &sai, &addrlen);

		/* This needs to be done here, otherwise we break dlines */
		mangle_mapped_sockaddr((struct sockaddr *) &sai);

		if(fd < 0)
		{
			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}
		/*
		 * check for connection limit
		 */
		if((maxconnections - 10) < fd)
		{
			++ServerStats->is_ref;
			/*
			 * slow down the whining to opers bit
			 */
			if((last_oper_notice + 20) <= CurrentTime)
			{
				sendto_realops_flags(UMODE_ALL, L_ALL,
						     "All connections in use. (%s)",
						     get_listener_name(listener));
				last_oper_notice = CurrentTime;
			}

			write(fd, "ERROR :All connections in use\r\n", 32);
			comm_close(fd);
			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}

		/* Do an initial check we aren't connecting too fast or with too many
		 * from this IP... */
		if((aconf = conf_connect_allowed((struct sockaddr *) &sai, sai.ss_family)) != NULL)
		{
			ServerStats->is_ref++;

			if(ConfigFileEntry.dline_with_reason)
			{
				if(ircsnprintf
				   (buf, sizeof(buf), "ERROR :*** Banned: %s\r\n",
				    aconf->passwd) >= (sizeof(buf) - 1))
				{
					buf[sizeof(buf) - 3] = '\r';
					buf[sizeof(buf) - 2] = '\n';
					buf[sizeof(buf) - 1] = '\0';
				}
			}
			else
				ircsprintf(buf, "ERROR :You have been D-lined.\r\n");

			write(fd, buf, strlen(buf));
			comm_close(fd);

			/* Re-register a new IO request for the next accept .. */
			comm_setselect(listener->fd, FDLIST_SERVICE,
				       COMM_SELECT_READ, accept_connection, listener);
			return;
		}

		ServerStats->is_ac++;
		add_connection(listener, fd, (struct sockaddr *) &sai);

	}
	/* Re-register a new IO request for the next accept .. */
	comm_setselect(listener->fd, FDLIST_SERVICE, COMM_SELECT_READ,
		       accept_connection, listener);
}
Пример #29
0
/*
 * m_topic
 *      parv[0] = sender prefix
 *      parv[1] = channel name
 *	parv[2] = new topic, if setting topic
 */
static int
m_topic(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
{
	struct Channel *chptr = NULL;
	struct membership *msptr;
	char *p = NULL;

	if((p = strchr(parv[1], ',')))
		*p = '\0';

	if(MyClient(source_p) && !IsFloodDone(source_p))
		flood_endgrace(source_p);

	if(!IsChannelName(parv[1]))
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				   form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	chptr = find_channel(parv[1]);

	if(chptr == NULL)
	{
		sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
				form_str(ERR_NOSUCHCHANNEL), parv[1]);
		return 0;
	}

	/* setting topic */
	if(parc > 2)
	{
		msptr = find_channel_membership(chptr, source_p);

		if(msptr == NULL)
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}

		if((chptr->mode.mode & MODE_TOPICLIMIT) == 0 || is_chanop(msptr) || !MyClient(source_p))
		{
			char topic_info[USERHOST_REPLYLEN];
			ircsprintf(topic_info, "%s!%s@%s",
					source_p->name, source_p->username, source_p->host);
			set_channel_topic(chptr, parv[2], topic_info, CurrentTime);

			sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
					":%s TOPIC %s :%s",
					use_id(source_p), chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
			sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
					":%s TOPIC %s :%s",
					source_p->name, chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
			sendto_channel_local(ALL_MEMBERS,
					chptr, ":%s!%s@%s TOPIC %s :%s",
					source_p->name, source_p->username,
					source_p->host, chptr->chname,
					chptr->topic == NULL ? "" : chptr->topic);
		}
		else
			sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED),
					me.name, source_p->name, parv[1]);
	}
	else if(MyClient(source_p))
	{
		if(!IsMember(source_p, chptr) && SecretChannel(chptr))
		{
			sendto_one_numeric(source_p, ERR_NOTONCHANNEL,
					form_str(ERR_NOTONCHANNEL), parv[1]);
			return 0;
		}
		if(chptr->topic == NULL)
			sendto_one(source_p, form_str(RPL_NOTOPIC),
					me.name, source_p->name, parv[1]);
		else
		{
			sendto_one(source_p, form_str(RPL_TOPIC),
					me.name, source_p->name, chptr->chname, chptr->topic);

			sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
					me.name, source_p->name, chptr->chname,
					chptr->topic_info, chptr->topic_time);
		}
	}

	return 0;
}
Пример #30
0
int main(int argc, char *argv[])
{
#if !defined DEBUGMODE && !defined DAEMONTOOLS
	pid_t pid; /* pid of this process */
#endif /* !DEBUGMODE && !DAEMONTOOLS */

#ifdef GDB_DEBUG

	int GDBAttached = 0;
#endif /* GDB_DEBUG */

#if defined GIMMECORE || defined DEBUGMODE

	struct rlimit rlim; /* resource limits -kre */
#endif /* GIMMECORE || DEBUGMODE */

	FILE *pidfile; /* to write our pid */
	uid_t uid; /* real user id */
	uid_t euid; /* effective user id */

#if defined HAVE_BOEHM_GC
	GC_INIT();
#endif /* HAVE_BOEHM_GC */

	myargv = argv;

	/* Initialise current TS for services -kre */
	TimeStarted = current_ts = time(NULL);

	/* Be sure, be paranoid, be safe. -kre */
	umask(077);

	fprintf(stderr,
	        "Hybserv2 TS services version %s by Hybserv2 team\n"
#if defined __DATE__ && defined __TIME__
	        "Compiled at %s, %s\n",
#endif
	        hVersion
#if defined __DATE__ && defined __TIME__
	        , __DATE__, __TIME__
#endif
	       );

#ifdef GDB_DEBUG

	while (!GDBAttached)
		sleep(1);
#endif /* GDB_DEBUG */

	/*
	 * Load SETPATH (settings.conf) - this must be done
	 * before the config file is loaded, and before any
	 * putlog() calls are made, since LogFile is specified
	 * in settings.conf
	 */
	if (LoadSettings(0) == 0)
	{
		fprintf(stderr, "Fatal errors encountered parsing %s, exiting\n"
		        "Check logfile %s/%s\n", SETPATH, LogPath ? LogPath : "",
		        LogFile ?  LogFile : "*unknown*");
		return (0);
	}

	/*
	 * If they run ./shownicks or ./showchans rather than ./hybserv
	 * display nicknames/channels
	 */
	if (strstr(argv[0], "shownicks"))
	{
#ifdef NICKSERVICES
		ShowNicknames(argc, argv);
#endif /* NICKSERVICES */

		return (0);
	}
	else if (strstr(argv[0], "showchans"))
	{
#if defined(NICKSERVICES) && defined(CHANNELSERVICES)
		ShowChannels(argc, argv);
#endif /* defined(NICKSERVICES) && defined(CHANNELSERVICES) */

		return 0;
	}

	/* Check for running services -kre */
	if ((pidfile = fopen(PidFile, "r")) == NULL)
		fprintf(stderr, "WARNING: Unable to read pid file %s\n",
		        PidFile);
	else
	{
		pid_t mypid;
		char line[MAXLINE + 1];

		if (fgets(line, sizeof(line), pidfile) != NULL)
		{
			mypid = atoi(line);
			if (mypid && !kill(mypid, 0))
			{
				fprintf(stderr, "FATAL: Services are already running!\n");
				fclose(pidfile);
				exit(EXIT_FAILURE);
			}
		}
		fclose(pidfile);
	}

	uid = getuid(); /* the user id of the user who ran the process */
	euid = geteuid(); /* the effective id (different if setuid) */

	if (!uid || !euid)
	{
		fprintf(stderr,
		        "FATAL: Please don't run services as root. Now exiting.\n");
		exit(EXIT_FAILURE);
	}

	if (chdir(HPath) != 0)
	{
		fprintf(stderr,
		        "HPath is an invalid directory, please check %s\n",
		        SETPATH);
		exit(EXIT_FAILURE);
	}

	putlog(LOG1, "Hybserv2 TS services version %s started", hVersion);

	/* Get the offset from GMT (London time) */
	gmt_offset = GetTZOffset(TimeStarted);

	/*
	 * the Network list must be initialized before the config
	 * file is loaded
	 */
	InitLists();

	/* load server, jupe, gline, user, admin info */
	LoadConfig();

	/* load nick/chan/memo/stat databases */
	LoadData();

#ifdef GLOBALSERVICES

	if (LogonNews)
	{
		Network->LogonNewsFile.filename = LogonNews;
		ReadMessageFile(&Network->LogonNewsFile);
	}

#endif /* GLOBALSERVICES */

	if (LocalHostName)
		SetupVirtualHost();

#if !defined DEBUGMODE && !defined GDB_DEBUG

	/* Daemontools compatibility stuff */
#ifndef DAEMONTOOLS

	pid = fork();
	if (pid == -1)
	{
		printf("Unable to fork(), exiting.\n");
		exit(EXIT_FAILURE);
	}
	if (pid != 0)
	{
		printf("Running in background (pid: %d)\n", (int)pid);
		exit(EXIT_SUCCESS);
	}

	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);

	/* Make current process session leader -kre */
	if (setsid() == -1)
	{
		exit(EXIT_FAILURE);
	}
#else

	printf("Entering foreground debug mode\n");
#endif /* DEBUGMODE */
#endif /* DAEMONTOOLS */

#if defined GIMMECORE || defined DEBUGMODE

	printf("Setting corefile limit... ");
	/* Set corefilesize to maximum - therefore we ensure that core will be
	 * generated, no matter of shell limits -kre */
	getrlimit(RLIMIT_CORE, &rlim);
	rlim.rlim_cur = rlim.rlim_max;
	setrlimit(RLIMIT_CORE, &rlim);
	printf("done.\n");
#endif /* GIMMECORE || DEBUGMODE */

	/* Signals must be set up after fork(), since the parent exits */
	InitSignals();

	/* Initialise random number generator -kre */
	srandom(current_ts);
	srandom((unsigned int)random());

	/* Write our pid to a file */
	if ((pidfile = fopen(PidFile, "w")) == NULL)
		putlog(LOG1, "Unable to open %s", PidFile);
	else
	{
		char line[MAXLINE + 1];

		ircsprintf(line, "%d\n", getpid());
		fputs(line, pidfile);
		fclose(pidfile);
	}

	/* initialize tcm/user listening ports */
	InitListenPorts();

	/* initialize hash tables */
	ClearHashes(1);

#ifdef BLOCK_ALLOCATION

	InitHeaps();
#endif

	HubSock = NOSOCKET;
	CycleServers();

	while (1)
	{
		/* enter loop waiting for server info */
		ReadSocketInfo();

		if (Me.hub)
			SendUmode(OPERUMODE_Y, "*** Disconnected from %s", Me.hub->name);
		else
			SendUmode(OPERUMODE_Y, "*** Disconnected from hub server");

		if (currenthub)
		{
			if (currenthub->realname)
			{
				MyFree(currenthub->realname);
				currenthub->realname = NULL;
			}
			currenthub->connect_ts = 0;
		}

		close(HubSock); /* There was an error */
		HubSock = NOSOCKET;

		/*
		 * whenever Hybserv connects/reconnects to a server, clear
		 * users, servers, and chans
		 */
		ClearUsers();
		ClearChans();
		ClearServs();
		/*
		 * ClearHashes() must be called AFTER ClearUsers(),
		 * or StatServ's unique client counts will be off since
		 * cloneTable[] would be NULL while it was trying to find
		 * clones
		 */
		ClearHashes(0);

		PostCleanup();
	} /* while (1) */

	return 0;
} /* main() */