Beispiel #1
0
void crash_report_header(FILE *reportfd, char *coredump)
{
	char buf[512];
	time_t t;
	
	fprintf(reportfd, "== UNREALIRCD CRASH REPORT ==\n"
	                  "\n"
	                  "SYSTEM INFORMATION:\n");
	
	fprintf(reportfd, "UnrealIRCd version: %s\n", VERSIONONLY);
#if defined(__VERSION__)
	fprintf(reportfd, "          Compiler: %s\n", __VERSION__);
#endif
	
	fprintf(reportfd, "  Operating System: %s\n", MYOSNAME);

	
	fprintf(reportfd, "Using core file: %s\n", coredump);
	
	t = get_file_time(coredump);
	if (t != 0)
	{
		fprintf(reportfd, "Crash date/time: %s\n", myctime(t) ? myctime(t) : "???");
		fprintf(reportfd, " Crash secs ago: %ld\n",
			(long)(time(NULL) - t));
	} else {
		fprintf(reportfd, "Crash date/time: UNKNOWN\n");
		fprintf(reportfd, " Crash secs ago: UNKNOWN\n");
	}
	
	fprintf(reportfd, "\n");
}
Beispiel #2
0
static int
whowas_do(struct Client *client_p, struct Client *source_p, int parc, char *parv[])
{
	struct Whowas *temp;
	int cur = 0;
	int max = -1, found = 0;
	char *p, *nick;

	if(parc < 2 || BadPtr(parv[1]))
	{
		sendto_one(source_p, form_str(ERR_NONICKNAMEGIVEN), me.name, parv[0]);
		return 0;
	}
	if(parc > 2)
		max = atoi(parv[2]);
	if(parc > 3)
		if(hunt_server(client_p, source_p, ":%s WHOWAS %s %s :%s", 3, parc, parv))
			return 0;


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

	nick = parv[1];

	temp = WHOWASHASH[hash_whowas_name(nick)];
	found = 0;
	for (; temp; temp = temp->next)
	{
		if(!irccmp(nick, temp->name))
		{
			sendto_one(source_p, form_str(RPL_WHOWASUSER),
				   me.name, parv[0], temp->name,
				   temp->username,
                                   (IsOperAdmin(source_p))? temp->hostname : temp->rhostname, temp->realname);

			if(ConfigServerHide.hide_servers && !IsOper(source_p))
				sendto_one(source_p, form_str(RPL_WHOISSERVER),
					   me.name, parv[0], temp->name,
					   ServerInfo.network_name, myctime(temp->logoff));
			else
				sendto_one(source_p, form_str(RPL_WHOISSERVER),
					   me.name, parv[0], temp->name,
					   temp->servername, myctime(temp->logoff));

			cur++;
			found++;
		}
		if(max > 0 && cur >= max)
			break;
	}
	if(!found)
		sendto_one(source_p, form_str(ERR_WASNOSUCHNICK), me.name, parv[0], nick);

	sendto_one(source_p, form_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
	return 0;
}
Beispiel #3
0
/* log_user_exit()
 *
 * inputs	- pointer to connecting client
 * output	- NONE
 * side effects - Current exiting client is logged to
 *		  either SYSLOG or to file.
 */
void
log_user_exit(struct Client *source_p)
{
  time_t on_for = CurrentTime - source_p->firsttime;
#ifdef SYSLOG_USERS
  if (IsPerson(source_p))
  {
    ilog(L_INFO, "%s (%3ld:%02ld:%02ld): %s!%s@%s %ld/%ld\n",
         myctime(source_p->firsttime),
	  (signed long) on_for / 3600,
	  (signed long) (on_for % 3600)/60,
	  (signed long) on_for % 60,
	  source_p->name, source_p->username, source_p->host,
	  source_p->localClient->sendK,
	  source_p->localClient->receiveK);
    }
#else
  {
    char linebuf[BUFSIZ];

    /*
     * This conditional makes the logfile active only after
     * it's been created - thus logging can be turned off by
     * removing the file.
     * -Taner
     */
    if (IsPerson(source_p))
    {
      if (user_log_fb == NULL)
      {
	if ((ConfigLoggingEntry.userlog[0] != '\0') && 
	   (user_log_fb = fbopen(ConfigLoggingEntry.userlog, "r")) != NULL)
	{
	  fbclose(user_log_fb);
	  user_log_fb = fbopen(ConfigLoggingEntry.userlog, "a");
	}
      }

      if (user_log_fb != NULL)
      {
        size_t nbytes = ircsprintf(linebuf,
		   "%s (%3ld:%02ld:%02ld): %s!%s@%s %d/%d\n",
		   myctime(source_p->firsttime),
		   (signed long) on_for / 3600,
		   (signed long) (on_for % 3600)/60,
		   (signed long) on_for % 60,
		   source_p->name, source_p->username, source_p->host,
		   source_p->localClient->sendK,
		   source_p->localClient->receiveK);
	fbputs(linebuf, user_log_fb, nbytes);
      }
    }
  }
#endif
}
Beispiel #4
0
void	vsendto_log(int flags, char *pattern, va_list va)
{
	char	logbuf[4096];

	logbuf[0] = '>';
	vsprintf(logbuf + 1, pattern, va);

#if defined(USE_SYSLOG)
	if (flags < 10)
		syslog(flags, "%s", logbuf + 1);
#endif

	strcat(logbuf, "\n");

#if defined(ISERV_DEBUG) && defined(DEBUGLVL)
	if ((flags <= (DEBUGLVL + 9))  && (flags > LOG_DEBUG) && debug)
	    {
		fprintf(debug, "[%s] %s", logstrings[flags], logbuf + 1);
		fflush(debug);
	    }
#endif
	if (iservlog && (flags < LOG_DEBUG))
	    {
		fprintf(iservlog, "[%s][%s]: %s", myctime(time(NULL)), logstrings[flags], logbuf+1);
		fflush(iservlog);
	    }
}
Beispiel #5
0
/* log_failed_oper()
 *
 * inputs	- pointer to client that failed to oper up
 *              - oper name
 * output	- none
 * side effects - ffailed_operlog is written to, if its present
 */
void
log_failed_oper(struct Client *source_p, const char *name)
{
  if (ConfigLoggingEntry.failed_operlog[0] == '\0')
    return;

  if (IsPerson(source_p))
  {
    FBFILE *oper_fb;

    if ((oper_fb = fbopen(ConfigLoggingEntry.failed_operlog, "r")) != NULL)
    {
      fbclose(oper_fb);
      oper_fb = fbopen(ConfigLoggingEntry.failed_operlog, "a");
    }

    if (oper_fb != NULL)
    {
      char linebuf[BUFSIZE];
      size_t nbytes = ircsprintf(linebuf,
                                 "%s FAILED OPER (%s) by (%s!%s@%s)\n",
                                 myctime(CurrentTime), name, source_p->name,
                                 source_p->username, source_p->host);
      fbputs(linebuf, oper_fb, nbytes);
      fbclose(oper_fb);
    }
  }
}
Beispiel #6
0
/*
 * mo_info - oper message handler
 *
 * parv[0] = sender prefix
 * parv[1] = servername
 */
int mo_info(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
  const char **text = infotext;

  if (hunt_server_cmd(sptr, CMD_INFO, cptr, 1, ":%C", 1, parc, parv) ==
      HUNTED_ISME)
  {
    while (text[212])
    {
      if (!IsOper(sptr))
	send_reply(sptr, RPL_INFO, *text);
      text++;
    }
    if (IsOper(sptr) && (NULL != parv[1]))
    {
      while (*text)
	send_reply(sptr, RPL_INFO, *text++);
      send_reply(sptr, RPL_INFO, "");
    }
    send_reply(sptr, SND_EXPLICIT | RPL_INFO, ":Birth Date: %s, compile # %s",
	       creation, generation);
    send_reply(sptr, SND_EXPLICIT | RPL_INFO, ":On-line since %s",
	       myctime(cli_firsttime(&me)));
    send_reply(sptr, RPL_ENDOFINFO);
  }
  return 0;
}
Beispiel #7
0
/* send_birthdate_online_time()
 *
 * inputs	- client pointer to send to
 * output	- NONE
 * side effects	- birthdate and online time are sent
 */
static void
send_birthdate_online_time(struct Client *source_p)
{
  sendto_one_numeric(source_p, &me, RPL_INFO|SND_EXPLICIT,
                     ":On-line since %s",
                     myctime(me.connection->firsttime));
}
Beispiel #8
0
void checkServer(struct Client *sptr, struct Client *acptr)
{
   char outbuf[BUFSIZE];

   /* Header */
   send_reply(sptr, RPL_DATASTR, " ");
   send_reply(sptr, RPL_CHKHEAD, "server", acptr->cli_name);
   send_reply(sptr, RPL_DATASTR, " ");

   ircd_snprintf(0, outbuf, sizeof(outbuf),  "   Connected at:: %s (%Tu)", myctime(acptr->cli_serv->timestamp), acptr->cli_serv->timestamp);
   send_reply(sptr, RPL_DATASTR, outbuf);

   ircd_snprintf(0, outbuf, sizeof(outbuf), "    Server name:: %s", acptr->cli_name);
   send_reply(sptr, RPL_DATASTR,  outbuf);

   if (cli_sslclifp(acptr) && (strlen(cli_sslclifp(acptr)) > 0)) {
     ircd_snprintf(0, outbuf, sizeof(outbuf), "SSL Fingerprint:: %s", cli_sslclifp(acptr));
     send_reply(sptr, RPL_DATASTR, outbuf);
   }

   ircd_snprintf(0, outbuf, sizeof(outbuf), "        Numeric:: %s --> %d", NumServ(acptr), base64toint(acptr->cli_yxx));
   send_reply(sptr, RPL_DATASTR, outbuf);

   ircd_snprintf(0, outbuf, sizeof(outbuf), "          Users:: %d / %d", (acptr == &me) ? UserStats.local_clients : cli_serv(acptr)->clients, 
                 base64toint(cli_serv(acptr)->nn_capacity));
   send_reply(sptr, RPL_DATASTR, outbuf);

   if (IsBurst(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Bursting");
   else if (IsBurstAck(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Awaiting EOB Ack");
   else if (IsService(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Network Service");
   else if (IsHub(acptr))
     send_reply(sptr, RPL_DATASTR, "         Status:: Network Hub");

   ircd_snprintf(0, outbuf, sizeof(outbuf), "          Class:: %s", get_client_class(acptr));
   send_reply(sptr, RPL_DATASTR, outbuf);

   if (feature_bool(FEAT_CHECK_EXTENDED)) {
     int dlinkc = 0;
     struct DLink* slink = NULL;
    
     send_reply(sptr, RPL_DATASTR, " ");
     send_reply(sptr, RPL_DATASTR, "Downlinks::");
     for (slink = cli_serv(acptr)->down; slink; slink = slink->next) {
       ircd_snprintf(0, outbuf, sizeof(outbuf), "[%d] - %s%s", ++dlinkc, 
             IsBurst(slink->value.cptr) ? "*" : IsBurstAck(slink->value.cptr) ? "!" : IsService(slink->value.cptr) ? "=" : IsHub(slink->value.cptr) ? "+" : " ", 
             cli_name(slink->value.cptr));
       send_reply(sptr, RPL_DATASTR, outbuf);
     }

     if (!dlinkc)
       send_reply(sptr, RPL_DATASTR, "<none>");
   }

   /* Send 'END OF CHECK' message */
   send_reply(sptr, RPL_ENDOFCHECK, " ");
}
Beispiel #9
0
/*
** m_whowas
**      parv[0] = sender prefix
**      parv[1] = nickname queried
*/
DLLFUNC CMD_FUNC(m_whowas)
{
	aWhowas *temp;
	int  cur = 0;
	int  max = -1, found = 0;
	char *p, *nick;

	if (parc < 2)
	{
		sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
		    me.name, parv[0]);
		return 0;
	}
	if (parc > 2)
		max = atoi(parv[2]);
	if (parc > 3)
		if (hunt_server_token(cptr, sptr, MSG_WHOWAS, TOK_WHOWAS, "%s %s :%s", 3, parc,
		    parv))
			return 0;

	if (!MyConnect(sptr) && (max > 20))
		max = 20;

	p = (char *)strchr(parv[1], ',');
	if (p)
		*p = '\0';
	nick = parv[1];
	temp = WHOWASHASH[hash_whowas_name(nick)];
	found = 0;
	for (; temp; temp = temp->next)
	{
		if (!mycmp(nick, temp->name))
		{
			sendto_one(sptr, rpl_str(RPL_WHOWASUSER),
			    me.name, parv[0], temp->name,
			    temp->username,
			    (IsOper(sptr) ? temp->hostname :
			    (*temp->virthost !=
			    '\0') ? temp->virthost : temp->hostname),
			    temp->realname);
                	if (!((Find_uline(temp->servername)) && !IsOper(sptr) && HIDE_ULINES))
				sendto_one(sptr, rpl_str(RPL_WHOISSERVER), me.name,
				    parv[0], temp->name, temp->servername,
				    myctime(temp->logoff));
			cur++;
			found++;
		}
		if (max > 0 && cur >= max)
			break;
	}
	if (!found)
		sendto_one(sptr, err_str(ERR_WASNOSUCHNICK),
		    me.name, parv[0], nick);

	sendto_one(sptr, rpl_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
	return 0;
}
Beispiel #10
0
/*
 * m_whowas - generic message handler
 *
 * parv[0] = sender prefix
 * parv[1] = nickname queried
 * parv[2] = maximum returned items (optional, default is unlimited)
 * parv[3] = remote server target (Opers only, max returned items 20)
 */
int m_whowas(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
    struct Whowas *temp;
    int cur = 0;
    int max = -1, found = 0;
    char *p, *nick, *s;

    if (parc < 2)
    {
        send_reply(sptr, ERR_NONICKNAMEGIVEN);
        return 0;
    }
    if (parc > 2)
        max = atoi(parv[2]);
    if (parc > 3)
        if (hunt_server_cmd(sptr, CMD_WHOWAS, cptr, 1, "%s %s :%C", 3, parc, parv))
            return 0;

    parv[1] = canonize(parv[1]);
    if (!MyConnect(sptr) && (max > 20))
        max = 20;                   /* Set max replies at 20 */
    for (s = parv[1]; (nick = ircd_strtok(&p, s, ",")); s = 0)
    {
        /* Search through bucket, finding all nicknames that match */
        found = 0;
        for (temp = whowashash[hash_whowas_name(nick)]; temp; temp = temp->hnext)
        {
            if (0 == ircd_strcmp(nick, temp->name))
            {
                send_reply(sptr, RPL_WHOWASUSER, temp->name, temp->username,
                           temp->hostname, temp->realname);
                if (IsAnOper(sptr) && temp->realhost)
                    send_reply(sptr, RPL_WHOISACTUALLY, temp->name, temp->username, temp->realhost, "<untracked>");
                send_reply(sptr, RPL_WHOISSERVER, temp->name,
                           (feature_bool(FEAT_HIS_WHOIS_SERVERNAME) && !IsOper(sptr)) ?
                           feature_str(FEAT_HIS_SERVERNAME) :
                           temp->servername,
                           myctime(temp->logoff));
                if (temp->away)
                    send_reply(sptr, RPL_AWAY, temp->name, temp->away);
                cur++;
                found++;
            }
            if (max >= 0 && cur >= max)
                break;
        }
        if (!found)
            send_reply(sptr, ERR_WASNOSUCHNICK, nick);
        /* To keep parv[1] intact for ENDOFWHOWAS */
        if (p)
            p[-1] = ',';
    }
    send_reply(sptr, RPL_ENDOFWHOWAS, parv[1]);
    return 0;
}
Beispiel #11
0
void
longt(Armember *bp)
{
    char *cp;

    pmode(strtoul(bp->hdr.mode, 0, 8));
    Bprint(&bout, "%3ld/%1ld", atol(bp->hdr.uid), atol(bp->hdr.gid));
    Bprint(&bout, "%7ld", bp->size);
    cp = myctime(bp->date);
    Bprint(&bout, " %-12.12s %-4.4s ", cp+4, cp+24);
}
Beispiel #12
0
/*
 * send_birthdate_online_time
 *
 * inputs	- client pointer to send to
 * output	- none
 * side effects	- birthdate and online time are sent
 */
static void
send_birthdate_online_time(struct Client *source_p)
{
	sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
		   get_id(&me, source_p), RPL_INFO, 
		   get_id(source_p, source_p), creation, generation);

	sendto_one(source_p, ":%s %d %s :On-line since %s",
		   get_id(&me, source_p), RPL_INFO, 
		   get_id(source_p, source_p), myctime(startup_time));
}
Beispiel #13
0
static void measure(int fd)
{
    time_t start_time;
    int last_state;
    time_t last_time;
    int curr_state;
    time_t curr_time = 0;
    time_t time_diff;
    time_t active_time = 0;
    time_t sleep_time = 0;
    time_t unknown_time = 0;
    time_t total_time = 0;
    int changes = 0;
    float tmp;

    printf("Starting measurements\n");

    last_state = check_powermode(fd);
    start_time = last_time = time(0);
    printf("  System is in state %s\n\n", state_name(last_state));

    while(!endit) {
	sleep(1);
	curr_state = check_powermode(fd);

	if (curr_state != last_state || endit) {
	    changes++;
	    curr_time = time(0);
	    time_diff = curr_time - last_time;

	    if (last_state == 1) active_time += time_diff;
	    else if (last_state == 0) sleep_time += time_diff;
	    else unknown_time += time_diff;

	    last_state = curr_state;
	    last_time = curr_time;

	    printf("%s: State-change to %s\n", myctime(curr_time),
		   state_name(curr_state));
	}
    }
    changes--; /* Compensate for SIGINT */

    total_time = time(0) - start_time;
    printf("\nTotal running time:  %lus\n", curr_time - start_time);
    printf(" State changed %d times\n", changes);

    tmp = (float)sleep_time / (float)total_time * 100;
    printf(" Time in sleep state:   %lus (%.2f%%)\n", sleep_time, tmp);
    tmp = (float)active_time / (float)total_time * 100;
    printf(" Time in active state:  %lus (%.2f%%)\n", active_time, tmp);
    tmp = (float)unknown_time / (float)total_time * 100;
    printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
}
Beispiel #14
0
/* irc logs.. */
void ircd_log(int flags, char *format, ...)
{
	va_list ap;
	ConfigItem_log *logs;
	char buf[2048], timebuf[128];
	int fd;
	struct stat fstats;

	va_start(ap, format);
	ircvsprintf(buf, format, ap);	
	snprintf(timebuf, sizeof timebuf, "[%s] - ", myctime(TStime()));
	RunHook3(HOOKTYPE_LOG, flags, timebuf, buf);
	strlcat(buf, "\n", sizeof buf);

	for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) {
#ifdef HAVE_SYSLOG
		if (!stricmp(logs->file, "syslog") && logs->flags & flags) {
#ifdef HAVE_VSYSLOG
			vsyslog(LOG_INFO, format, ap);
#else
			/* %s just to be safe */
			syslog(LOG_INFO, "%s", buf);
#endif
			continue;
		}
#endif
		if (logs->flags & flags) {
			if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize) {
#ifndef _WIN32
				fd = open(logs->file, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
#else
				fd = open(logs->file, O_CREAT|O_WRONLY|O_TRUNC, S_IREAD|S_IWRITE);
#endif
				if (fd == -1)
					continue;
				write(fd, "Max file size reached, starting new log file\n", 45);
			}
			else {
#ifndef _WIN32
			fd = open(logs->file, O_CREAT|O_APPEND|O_WRONLY, S_IRUSR|S_IWUSR);
#else
			fd = open(logs->file, O_CREAT|O_APPEND|O_WRONLY, S_IREAD|S_IWRITE);
#endif
			if (fd == -1)
				continue;
			}	
			write(fd, timebuf, strlen(timebuf));
			write(fd, buf, strlen(buf));
			close(fd);
		}
	}
	va_end(ap);
}
Beispiel #15
0
/* send_birthdate_online_time()
 *
 * inputs	- client pointer to send to
 * output	- NONE
 * side effects	- birthdate and online time are sent
 */
static void
send_birthdate_online_time(struct Client *source_p)
{
  if (!MyClient(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p))
  {
    sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
               me.id, RPL_INFO, source_p->id,
               creation, generation);
             
    sendto_one(source_p, ":%s %d %s :On-line since %s",
               me.id, RPL_INFO, source_p->id,
               myctime(me.firsttime));
  }
  else
  {
    sendto_one(source_p, ":%s %d %s :Birth Date: %s, compile # %s",
               me.name, RPL_INFO, source_p->name,
               creation, generation);

    sendto_one(source_p, ":%s %d %s :On-line since %s",
               me.name, RPL_INFO, source_p->name,
               myctime(me.firsttime));
  }
}
Beispiel #16
0
void checkChannel(struct Client *sptr, struct Channel *chptr)
{
   char outbuf[TOPICLEN + MODEBUFLEN + 64], modebuf[MODEBUFLEN], parabuf[MODEBUFLEN];

   /* Header */
   send_reply(sptr, RPL_DATASTR, " ");
   send_reply(sptr, RPL_CHKHEAD, "channel", chptr->chname);
   send_reply(sptr, RPL_DATASTR, " ");

   /* Creation Time */
   ircd_snprintf(sptr, outbuf, sizeof(outbuf), "  Creation time:: %s", myctime(chptr->creationtime));
   send_reply(sptr, RPL_DATASTR, outbuf);

   /* Topic */
   if (strlen(chptr->topic) <= 0)
      send_reply(sptr, RPL_DATASTR, "          Topic:: <none>");
   else {
      ircd_snprintf(sptr, outbuf, sizeof(outbuf), "          Topic:: %s", chptr->topic);
      send_reply(sptr, RPL_DATASTR, outbuf);

      /* ..set by */
      ircd_snprintf(sptr, outbuf, sizeof(outbuf), "         Set by:: %s", chptr->topic_nick);
      send_reply(sptr, RPL_DATASTR, outbuf);
   }

   /* Channel Modes */

   strcpy(outbuf, "Channel mode(s):: ");

   modebuf[0] = '\0';
   parabuf[0] = '\0';

   channel_modes(sptr, modebuf, parabuf, sizeof(modebuf), chptr);

   if(modebuf[1] == '\0')
      strcat(outbuf, "<none>");
   else if(*parabuf) {
      strcat(outbuf, modebuf);
      strcat(outbuf, " ");
      strcat(outbuf, parabuf);
   } else
      strcat(outbuf, modebuf);

   send_reply(sptr, RPL_DATASTR, outbuf);

   /* Don't send 'END OF CHECK' message, it's sent in checkUsers, which is called after this. */
}
Beispiel #17
0
int write_chat_record(struct command *cmdline,char *ip)
{
	struct tm *tml;
	tml=myctime();
	char buf[1024];

	pthread_mutex_lock(&chatrecord_mutex);
	sprintf(buf, 
			"[%d-%d-%d %d:%d:%d][%s][%s][%s]:\n%s\n",
			tml->tm_year,tml->tm_mon,tml->tm_mday,tml->tm_hour,tml->tm_min,tml->tm_sec,
			ip,
			cmdline->source,
			cmdline->dest,
			cmdline->data);
	fwrite(buf,sizeof(char),strlen(buf),fp);
	sync();
	pthread_mutex_unlock(&chatrecord_mutex);
	return 0;
}
Beispiel #18
0
Datei: a_log.c Projekt: ahf/irc
void	vsendto_log(int flags, int slflag, char *pattern, va_list va)
{
	char	logbuf[4096];

	logbuf[0] = '>';
	vsprintf(logbuf+1, pattern, va);

#if defined(USE_SYSLOG)
	if (slflag)
		syslog(slflag, "%s", logbuf+1);
#endif

	strcat(logbuf, "\n");

#if defined(IAUTH_DEBUG)
	if ((flags & ALOG_DALL) && (flags & debuglevel) && debug)
	    {
		fprintf(debug, "%s", logbuf+1);
		fflush(debug);
	    }
#endif
	if (authlog && (flags & ALOG_FLOG))
	    {
		fprintf(authlog, "%s: %s", myctime(time(NULL)), logbuf+1);
		fflush(authlog);
	    }
	if (flags & ALOG_IRCD)
	    {
		write(0, logbuf, strlen(logbuf));
#if defined(IAUTH_DEBUG)
		if ((ALOG_DSPY & debuglevel) && debug)
		    {
			fprintf(debug, "To ircd: %s", logbuf+1);
			fflush(debug);
		    }
#endif
	    }
}
Beispiel #19
0
void m_info_send(aClient *sptr)
{
char **text = unrealinfo;

	sendto_one(sptr, ":%s %d %s :=-=-=-= %s =-=-=-=",
	    me.name, RPL_INFO, sptr->name, IRCDTOTALVERSION);

	while (*text)
		sendto_one(sptr, ":%s %d %s :| %s", 
		    me.name, RPL_INFO, sptr->name, *text++);

	sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :| Credits - Type /Credits",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :| DALnet Credits - Type /DalInfo",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :|", me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :| This is an UnrealIRCd-style server",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :| If you find any bugs, please report them at:",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :|  http://bugs.unrealircd.org/",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr,
	    ":%s %d %s :| UnrealIRCd Homepage: http://www.unrealircd.com",
	    me.name, RPL_INFO, sptr->name);
	sendto_one(sptr,
	    ":%s %d %s :-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=", me.name,
	    RPL_INFO, sptr->name);
	sendto_one(sptr, ":%s %d %s :Birth Date: %s, compile # %s", me.name,
	    RPL_INFO, sptr->name, creation, generation);
	sendto_one(sptr, ":%s %d %s :On-line since %s", me.name, RPL_INFO,
	    sptr->name, myctime(me.firsttime));
	sendto_one(sptr, ":%s %d %s :ReleaseID (%s)", me.name, RPL_INFO,
	    sptr->name, buildid);
	sendto_one(sptr, rpl_str(RPL_ENDOFINFO), me.name, sptr->name);
}
Beispiel #20
0
/*
** m_whowas
**	parv[0] = sender prefix
**	parv[1] = nickname queried
*/
int	m_whowas(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	Reg	aName	*wp, *wp2 = NULL;
	Reg	int	j = 0;
	Reg	anUser	*up = NULL;
	int	max = -1;
	char	*p = NULL, *nick, *s;

 	if (parc < 2)
	    {
		sendto_one(sptr, replies[ERR_NONICKNAMEGIVEN], ME, BadTo(parv[0]));
		return 1;
	    }
	if (parc > 2)
		max = atoi(parv[2]);
	if (parc > 3)
		if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
			return 3;

	parv[1] = canonize(parv[1]);
	if (!MyConnect(sptr))
		max = MIN(max, 20);

	for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL)
	    {
		wp = wp2 = &was[(ww_index ? ww_index : ww_size) - 1];
		j = 0;

		do {
			if (mycmp(nick, wp->ww_nick) == 0)
			    {
				up = wp->ww_user;
				sendto_one(sptr, replies[RPL_WHOWASUSER],
					   ME, BadTo(parv[0]), wp->ww_nick, up->username,
					   up->host, wp->ww_info);
				sendto_one(sptr, replies[RPL_WHOISSERVER],
					   ME, BadTo(parv[0]), wp->ww_nick, up->server,
					   myctime(wp->ww_logout));
				j++;
			    }
			if (max > 0 && j >= max)
				break;
			if (wp == was)
				wp = &was[ww_size - 1];
			else
				wp--;
		} while (wp != wp2);

		if (up == NULL)
		    {
			if (strlen(nick) > (size_t) NICKLEN)
				nick[NICKLEN] = '\0';
			sendto_one(sptr, replies[ERR_WASNOSUCHNICK], ME, BadTo(parv[0]),
				   nick);
		    }
		else
			up = NULL;

		if (p)
			p[-1] = ',';
	    }
	sendto_one(sptr, replies[RPL_ENDOFWHOWAS], ME, BadTo(parv[0]), parv[1]);
	return 2;
    }
Beispiel #21
0
/* irc logs.. */
void ircd_log(int flags, char *format, ...)
{
static int last_log_file_warning = 0;
static char recursion_trap=0;

	va_list ap;
	ConfigItem_log *logs;
	char buf[2048], timebuf[128];
	struct stat fstats;
	int written = 0, write_failure = 0;
	int n;

	/* Trap infinite recursions to avoid crash if log file is unavailable,
	 * this will also avoid calling ircd_log from anything else called
	 */
	if (recursion_trap == 1)
		return;

	recursion_trap = 1;
	va_start(ap, format);
	ircvsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime()));

	RunHook3(HOOKTYPE_LOG, flags, timebuf, buf);
	strlcat(buf, "\n", sizeof(buf));

	if (!loop.ircd_forked && (flags & LOG_ERROR))
		fprintf(stderr, "%s", buf);

	for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) {
#ifdef HAVE_SYSLOG
		if (!stricmp(logs->file, "syslog") && logs->flags & flags) {
			syslog(LOG_INFO, "%s", buf);
			written++;
			continue;
		}
#endif
		if (logs->flags & flags)
		{
			if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize)
			{
				char oldlog[512];
				if (logs->logfd != -1)
				{
					write(logs->logfd, "Max file size reached, starting new log file\n", 45);
					fd_close(logs->logfd);
				}
				
				/* Rename log file to xxxxxx.old */
				snprintf(oldlog, sizeof(oldlog), "%s.old", logs->file);
				rename(logs->file, oldlog);
				
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC);
				if (logs->logfd == -1)
					continue;
			}
			else if (logs->logfd == -1) {
#ifndef _WIN32
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
#else
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
#endif
				if (logs->logfd == -1)
				{
					if (!loop.ircd_booted)
					{
						config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
					} else {
						if (last_log_file_warning + 300 < TStime())
						{
							config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
							last_log_file_warning = TStime();
						}
					}
					write_failure = 1;
					continue;
				}
			}
			/* this shouldn't happen, but lets not waste unnecessary syscalls... */
			if (logs->logfd == -1)
				continue;
			write(logs->logfd, timebuf, strlen(timebuf));
			n = write(logs->logfd, buf, strlen(buf));
			if (n == strlen(buf))
			{
				written++;
			}
			else
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				} else {
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}

				write_failure = 1;
			}
#ifndef _WIN32
			fsync(logs->logfd);
#endif
		}
	}

	recursion_trap = 0;
}
Beispiel #22
0
/* irc logs.. */
void ircd_log(int flags, char *format, ...)
{
static int last_log_file_warning = 0;

	va_list ap;
	ConfigItem_log *logs;
	char buf[2048], timebuf[128];
	struct stat fstats;
	int written = 0, write_failure = 0;

	va_start(ap, format);
	ircvsnprintf(buf, sizeof(buf), format, ap);
	va_end(ap);
	snprintf(timebuf, sizeof(timebuf), "[%s] - ", myctime(TStime()));
	RunHook3(HOOKTYPE_LOG, flags, timebuf, buf);
	strlcat(buf, "\n", sizeof(buf));

	for (logs = conf_log; logs; logs = (ConfigItem_log *) logs->next) {
#ifdef HAVE_SYSLOG
		if (!stricmp(logs->file, "syslog") && logs->flags & flags) {
			syslog(LOG_INFO, "%s", buf);
			written++;
			continue;
		}
#endif
		if (logs->flags & flags)
		{
			if (stat(logs->file, &fstats) != -1 && logs->maxsize && fstats.st_size >= logs->maxsize)
			{
				if (logs->logfd != -1)
					fd_close(logs->logfd);
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_WRONLY|O_TRUNC);
				if (logs->logfd == -1)
					continue;
				if (write(logs->logfd, "Max file size reached, starting new log file\n", 45) < 0)
				{
					write_failure = 1;
					continue;
				}
			}
			else if (logs->logfd == -1) {
				logs->logfd = fd_fileopen(logs->file, O_CREAT|O_APPEND|O_WRONLY);
				if (logs->logfd == -1)
				{
					if (!loop.ircd_booted)
					{
						config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
					}
					else
					{
						if (last_log_file_warning + 300 < TStime())
						{
							config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
							last_log_file_warning = TStime();
						}
					}
					write_failure = 1;
					continue;
				}
			}
			/* this shouldn't happen, but lets not waste unnecessary syscalls... */
			if (logs->logfd == -1)
				continue;
			if (write(logs->logfd, timebuf, strlen(timebuf)) < 0)
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				}
				else
				{
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}
				write_failure = 1;
			}
			if (write(logs->logfd, buf, strlen(buf)) == strlen(buf))
			{
				written++;
			}
			else
			{
				if (!loop.ircd_booted)
				{
					config_status("WARNING: Unable to write to '%s': %s", logs->file, strerror(ERRNO));
				}
				else
				{
					if (last_log_file_warning + 300 < TStime())
					{
						config_status("WARNING: Unable to write to '%s': %s. This warning will not re-appear for at least 5 minutes.", logs->file, strerror(ERRNO));
						last_log_file_warning = TStime();
					}
				}
				write_failure = 1;
			}
			fsync(logs->logfd);
		}
	}

	/* If nothing got written at all AND we had a write failure AND we are booting, then exit.
	 * Note that we can't just fail when nothing got written, as we might have been called for
	 * 'tkl' for example, which might not be in our log block.
	 */
	if (!written && write_failure && !loop.ircd_booted)
	{
		config_status("ERROR: Unable to write to any log file. Please check your log { } blocks and file permissions!");
		exit(9);
	}
}
Beispiel #23
0
/*
 * try_connections 
 * 
 *      Scan through configuration and try new connections. 
 *   Returns  the calendar time when the next call to this 
 *      function should be made latest. (No harm done if this 
 *      is called earlier or later...)
 */
static      time_t
try_connections(time_t currenttime)
{
aConfItem *aconf, **pconf, *con_conf = (aConfItem *) NULL;
aClient   *cptr;
aClass    *cltmp;
int        connecting, confrq, con_class = 0;
time_t      next = 0;

   connecting = FALSE;

   Debug((DEBUG_NOTICE, "Connection check at   : %s",
	  myctime(currenttime)));

   for (aconf = conf; aconf; aconf = aconf->next) {
      /* Also when already connecting! (update holdtimes) --SRB */
      if (!(aconf->status & CONF_CONNECT_SERVER) || aconf->port <= 0)
	 continue;
      cltmp = Class (aconf);

      /*
       * * Skip this entry if the use of it is still on hold until 
       * future. Otherwise handle this entry (and set it on hold 
       * until next time). Will reset only hold times, if already 
       * made one successfull connection... [this algorithm is a bit
       * fuzzy... -- msa >;) ]
       */

      if ((aconf->hold > currenttime)) 
      {
	 if ((next > aconf->hold) || (next == 0))
	    next = aconf->hold;
	 continue;
      }

      confrq = get_con_freq(cltmp);
      aconf->hold = currenttime + confrq;

      /* Found a CONNECT config with port specified, scan clients 
       * and see if this server is already connected?
       */

      cptr = find_name(aconf->name, (aClient *) NULL);

      if (!cptr && (Links(cltmp) < MaxLinks(cltmp)) &&
	  (!connecting || (Class (cltmp) > con_class))) 
      {
	con_class = Class (cltmp);

 	con_conf = aconf;
	 /* We connect only one at time... */
	connecting = TRUE;
      }

      if ((next > aconf->hold) || (next == 0))
	 next = aconf->hold;
   }

   if (connecting) 
   {
      if (con_conf->next) 	/* are we already last? */
      {
	 for (pconf = &conf; (aconf = *pconf);
	      pconf = &(aconf->next))
	    /*
	     * put the current one at the end and make sure we try all
	     * connections
	     */
	    if (aconf == con_conf)
	       *pconf = aconf->next;
	 (*pconf = con_conf)->next = 0;
      }
      if (connect_server(con_conf, (aClient *) NULL,
			 (struct hostent *) NULL) == 0)
	 sendto_gnotice("from %s: Connection to %s activated.", me.name, con_conf->name);
   }
   Debug((DEBUG_NOTICE, "Next connection check : %s", myctime(next)));
   return (next);
}
Beispiel #24
0
static      time_t
check_pings(time_t currenttime)
{
aClient 	*cptr;
aConfItem 	*aconf = (aConfItem *) NULL;
int     	 killflag, zkillflag, ping = 0, i;
time_t      	 oldest = 0; /* timeout removed, see EXPLANATION below */
char       	*reason, *ktype, fbuf[512];
char 		*errtxt = "No response from %s, closing link";


   for (i = 0; i <= highest_fd; i++) 
   {
      if (!(cptr = local[i]) || IsMe(cptr) || IsLog(cptr))
	 continue;

       /* Note: No need to notify opers here. It's 
	* already done when "FLAGS_DEADSOCKET" is set.
        */

      if (cptr->flags & FLAGS_DEADSOCKET) 
      {
	 (void) exit_client(cptr, cptr, &me, (cptr->flags & FLAGS_SENDQEX) ?
			    "SendQ exceeded" : "Dead socket");
	 i--;
	 continue;
      }

      killflag = NO;
      zkillflag = NO;

      if (rehashed) 
      {
	 if (zline_in_progress) 
	 {
	    if (IsPerson(cptr)) 
	    {
	       if ((aconf = find_zkill(cptr)))	
		  zkillflag = YES;
	    }
	 }
	 else 
	 {
	    if(IsPerson(cptr)) 
	    {
	       if((aconf = find_kill(cptr)))	
		  killflag = YES;	
	    }
	 }
      }

      /* Added a bit of code here to differentiate 
       * between K and Z-lines. -ThemBones
       */

      if (zkillflag || killflag)
      {
         ktype = zkillflag ? "Z-lined" : 
            ((aconf->status == CONF_KILL) ? "K-lined" : "Autokilled");

	 if (killflag) 
         {
	    sendto_ops("%s active for %s",
                       (aconf->status == CONF_KILL) ? "K-line" : "Autokill",
		       get_client_name(cptr, FALSE));
	    reason = aconf->passwd ? aconf->passwd : ktype;
	 }
	 else 
         {			/* its a Z line */
	    sendto_ops("Z-line active for %s",
		       get_client_name(cptr, FALSE));
	    reason = aconf->passwd ? aconf->passwd : "Z-lined";
	 }

	 sendto_one(cptr, err_str(ERR_YOUREBANNEDCREEP),
		    me.name, cptr->name, ktype);

         ircsprintf(fbuf, "%s: %s", ktype, reason);
	 (void) exit_client(cptr, cptr, &me, fbuf);
	 i--;			/* subtract out this fd so we check it again.. */			
	 continue;
      }

      if (IsRegistered(cptr))
	 ping = cptr->pingval;
      else
	 ping = CONNECTTIMEOUT;

      /*
       * Ok, so goto's are ugly and can be avoided here but this code
       * is already indented enough so I think its justified. -avalon
       *
       * justified by what? laziness? <g>
       * If the client pingtime is fine (ie, not larger than the client ping) 
       * skip over all the checks below. - lucas
       */

      if (ping < (currenttime - cptr->lasttime))
      {
         /*
          * If the server hasnt talked to us in 2*ping seconds and it has
          * a ping time, then close its connection. If the client is a
          * user and a KILL line was found to be active, close this
          * connection too.
          */
         if (((cptr->flags & FLAGS_PINGSENT) && ((currenttime - cptr->lasttime) >= (2 * ping))) ||
             ((!IsRegistered(cptr) && (currenttime - cptr->since) >= ping))) 
         {
	    if (!IsRegistered(cptr) && (DoingDNS(cptr) || DoingAuth(cptr))) 
            {
	       if (cptr->authfd >= 0) 
	       {
	          (void) close(cptr->authfd);
	          cptr->authfd = -1;
	          cptr->count = 0;
	          *cptr->buffer = '\0';
	       }
#ifdef SHOW_HEADERS
	       if (DoingDNS(cptr))
	          ssl_send(cptr, REPORT_FAIL_DNS, R_fail_dns, 0);
	       if (DoingAuth(cptr))
	          ssl_send(cptr, REPORT_FAIL_ID, R_fail_id, 0);
#endif
	       Debug((DEBUG_NOTICE, "DNS/AUTH timeout %s",
	 	      get_client_name(cptr, TRUE)));
	       del_queries((char *) cptr);
	       ClearAuth(cptr);
	       ClearDNS(cptr);
	       SetAccess(cptr);
	       cptr->since = currenttime;
	       continue;
	    }

	    if (IsServer(cptr) || IsConnecting(cptr) || IsHandshake(cptr)) 
	    {
	       ircsprintf(fbuf, "from %s: %s", me.name, errtxt);
	       sendto_gnotice(fbuf, get_client_name(cptr, HIDEME));
	       ircsprintf(fbuf, ":%s GNOTICE :%s", me.name, errtxt);                                
	       sendto_serv_butone(cptr, fbuf, get_client_name(cptr, HIDEME));
	    }

	    (void) exit_client(cptr, cptr, &me, "Ping timeout");
	    i--;			/* subtract out this fd so we check it again.. */			
	    continue;
         } /* don't send pings during a burst, as we send them already. */

         else if (!(cptr->flags & (FLAGS_PINGSENT|FLAGS_BURST))) {
	    /*
	     * if we havent PINGed the connection and we havent heard from
	     * it in a while, PING it to make sure it is still alive.
	     */
	    cptr->flags |= FLAGS_PINGSENT;
	    /*
	     * not nice but does the job 
	     */
	    cptr->lasttime = currenttime - ping;
	    sendto_one(cptr, "PING :%s", me.name);
         }
      }

      /* see EXPLANATION below
       *
       * timeout = cptr->lasttime + ping;
       * while (timeout <= currenttime)
       *  timeout += ping;
       * if (timeout < oldest || !oldest)
       *   oldest = timeout;
       */

      /*
       * Check UNKNOWN connections - if they have been in this state
       * for > 100s, close them.
       */
      if (IsUnknown(cptr))
	 if (cptr->firsttime ? ((timeofday - cptr->firsttime) > 100) : 0) 
	    (void) exit_client(cptr, cptr, &me, "Connection Timed Out");
   }

   rehashed = 0;
   zline_in_progress = 0;

   /* EXPLANATION
    * on a server with a large volume of clients, at any given point
    * there may be a client which needs to be pinged the next second,
    * or even right away (a second may have passed while running
    * check_pings). Preserving CPU time is more important than
    * pinging clients out at exact times, IMO. Therefore, I am going to make
    * check_pings always return currenttime + 9. This means that it may take
    * a user up to 9 seconds more than pingfreq to timeout. Oh well.
    * Plus, the number is 9 to 'stagger' our check_pings calls out over
    * time, to avoid doing it and the other tasks ircd does at the same time
    * all the time (which are usually done on intervals of 5 seconds or so). 
    * - lucas
    *
    *  if (!oldest || oldest < currenttime)
    *     oldest = currenttime + PINGFREQUENCY;
    */

   oldest = currenttime + 9;

   Debug((DEBUG_NOTICE, "Next check_ping() call at: %s, %d %d %d",
	  myctime(oldest), ping, oldest, currenttime));

   return oldest;
}
Beispiel #25
0
/*
** try_connections
**
**	Scan through configuration and try new connections.
**	Returns the calendar time when the next call to this
**	function should be made latest. (No harm done if this
**	is called earlier or later...)
*/
static	time_t	try_connections(time_t currenttime)
{
	Reg	aConfItem *aconf;
	Reg	aClient *cptr;
	aConfItem **pconf;
	int	confrq;
	time_t	next = 0;
	aClass	*cltmp;
	aConfItem *con_conf = NULL;
	int	allheld = 1;
#ifdef DISABLE_DOUBLE_CONNECTS
	int	i;
#endif

	if ((bootopt & BOOT_STANDALONE))
		return 0;

	Debug((DEBUG_NOTICE,"Connection check at   : %s",
		myctime(currenttime)));
	for (aconf = conf; aconf; aconf = aconf->next )
	{
		/* not a C-line */
		if (!(aconf->status & (CONF_CONNECT_SERVER|CONF_ZCONNECT_SERVER)))
			continue;

		/* not a candidate for AC */
		if (aconf->port <= 0)
			continue;

		cltmp = Class(aconf);
		/* not a candidate for AC */
		if (MaxLinks(cltmp) == 0)
			continue;

		/* minimize next to lowest hold time of all AC-able C-lines */
		if (next > aconf->hold || next == 0)
			next = aconf->hold;

		/* skip conf if the use of it is on hold until future. */
		if (aconf->hold > currenttime)
			continue;

		/* at least one candidate not held for future, good */
		allheld = 0;

		/* see if another link in this conf is allowed */
		if (Links(cltmp) >= MaxLinks(cltmp))
			continue;
		
		/* next possible check after connfreq secs for this C-line */
		confrq = get_con_freq(cltmp);
		aconf->hold = currenttime + confrq;

		/* is this server already connected? */
		cptr = find_name(aconf->name, (aClient *)NULL);
		if (!cptr)
			cptr = find_mask(aconf->name, (aClient *)NULL);

		/* matching client already exists, no AC to it */
		if (cptr)
			continue;

		/* no such server, check D-lines */
		if (find_denied(aconf->name, Class(cltmp)))
			continue;

#ifdef DISABLE_DOUBLE_CONNECTS
		/* Much better would be traversing only unknown
		** connections, but this requires another global
		** variable, adding and removing from there in
		** proper places etc. Some day. --B. */
		for (i = highest_fd; i >= 0; i--)
		{
			if (!(cptr = local[i]) ||
				cptr->status > STAT_UNKNOWN)
			{
				continue;
			}
			/* an unknown traveller we have */
			if (
#ifndef INET6
				cptr->ip.s_addr == aconf->ipnum.s_addr
#else
				!memcmp(cptr->ip.s6_addr,
					aconf->ipnum.s6_addr, 16)
#endif
			)
			{
				/* IP the same. Coincidence? Maybe.
				** Do not cause havoc with double connect. */
				break;
			}
			cptr = NULL;
		}
		if (cptr)
		{
			sendto_flag(SCH_SERVER, "AC to %s postponed", aconf->name);
			continue;
		}
#endif
		/* we have a candidate! */

		/* choose the best. */
		if (!con_conf ||
		     (con_conf->pref > aconf->pref && aconf->pref >= 0) ||
		     (con_conf->pref == -1 &&
		      Class(cltmp) > ConfClass(con_conf)))
		{
			con_conf = aconf;
		}
		/* above is my doubt: if we always choose best connection
		** and it always fails connecting, we may never try another,
		** even "worse"; what shall we do? --Beeth */
	}
	if (con_conf)
	{
		if (con_conf->next)  /* are we already last? */
		{
			for (pconf = &conf; (aconf = *pconf);
			     pconf = &(aconf->next))
				/* put the current one at the end and
				 * make sure we try all connections
				 */
				if (aconf == con_conf)
					*pconf = aconf->next;
			(*pconf = con_conf)->next = 0;
		}

		/* "Penalty" for being the best, so in next call of
		 * try_connections() other servers have chance. --B. */
		con_conf->hold += get_con_freq(Class(con_conf));

		if (!iconf.aconnect)
		{
			sendto_flag(SCH_NOTICE,
				"Connection to %s deferred. Autoconnect "
				"administratively disabled", con_conf->name);
		}
		else if (connect_server(con_conf, (aClient *)NULL,
				   (struct hostent *)NULL) == 0)
		{
			sendto_flag(SCH_NOTICE,
				    "Connection to %s[%s] activated.",
				    con_conf->name, con_conf->host);
		}
	}
	else
	if (allheld == 0)	/* disable AC only when some C: got checked */
	{
		/* No suitable conf for AC was found, so why bother checking
		** again? If some server quits, it'd get reenabled --B. */
		next = 0;
	}
	Debug((DEBUG_NOTICE,"Next connection check : %s", myctime(next)));
	return (next);
}
Beispiel #26
0
/*
** m_whowas
**      parv[0] = sender prefix
**      parv[1] = nickname queried
*/
int     m_whowas(aClient *cptr,
                 aClient *sptr,
                 int parc,
                 char *parv[])
{
  aWhowas *temp;
  int cur = 0;
  int     max = -1, found = 0;
  char    *p, *nick;
/*  char    *s; */
  static time_t last_used=0L;

  if (parc < 2)
    {
      sendto_one(sptr, form_str(ERR_NONICKNAMEGIVEN),
                 me.name, parv[0]);
      return 0;
    }
  if (parc > 2)
    max = atoi(parv[2]);
  if (parc > 3)
    if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
      return 0;

  if(!IsAnOper(sptr) && !MyConnect(sptr)) /* pace non local requests */
    {
      if((last_used + WHOIS_WAIT) > CurrentTime)
        {
          return 0;
        }
      else
        {
          last_used = CurrentTime;
        }
    }

  if (!MyConnect(sptr) && (max > 20))
    max = 20;
  /*  for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL) */
  p = strchr(parv[1],',');
  if(p)
    *p = '\0';
  nick = parv[1];

  temp = WHOWASHASH[hash_whowas_name(nick)];
  found = 0;
  for(;temp;temp=temp->next)
    {
      if (!irccmp(nick, temp->name))
        {
          sendto_one(sptr, form_str(RPL_WHOWASUSER),
                     me.name, parv[0], temp->name,
                     temp->username,
                     temp->hostname,
                     temp->realname);
          sendto_one(sptr, form_str(RPL_WHOISSERVER),
                     me.name,
                     parv[0],
                     temp->name,
#ifdef SERVERHIDE
                     IsAnOper(sptr) ? temp->servername : NETWORK_NAME,
#else
                     temp->servername,
#endif
                     myctime(temp->logoff));
          cur++;
          found++;
        }
      if (max > 0 && cur >= max)
        break;
    }
  if (!found)
    sendto_one(sptr, form_str(ERR_WASNOSUCHNICK),
               me.name, parv[0], nick);

  sendto_one(sptr, form_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
  return 0;
}
Beispiel #27
0
/*
 *  exit_client 
 * This is old "m_bye". Name  changed, because this is not a
 * protocol function, but a general server utility function.
 * 
 *      This function exits a client of *any* type (user, server, etc) 
 * from this server. Also, this generates all necessary prototol 
 * messages that this exit may cause. 
 * 
 *   1) If the client is a local client, then this implicitly exits
 * all other clients depending on this connection (e.g. remote
 * clients having 'from'-field that points to this. 
 * 
 *   2) If the client is a remote client, then only this is exited. 
 * 
 * For convenience, this function returns a suitable value for 
 * m_function return value: 
 * 
 *      FLUSH_BUFFER    if (cptr == sptr) 
 *      0 if (cptr != sptr)
 */
int 
exit_client(aClient *cptr, aClient *sptr, aClient *from, char *comment)
{
#ifdef  FNAME_USERLOG
    time_t on_for;
#endif
    
    if (MyConnect(sptr)) 
    {
        call_hooks(CHOOK_SIGNOFF, sptr);

        if (IsUnknown(sptr))
            Count.unknown--;
        if (IsAnOper(sptr)) 
            remove_from_list(&oper_list, sptr, NULL);
        if (sptr->flags & FLAGS_HAVERECVQ)
        {
            /* mark invalid, will be deleted in do_recvqs() */
            DLink *lp = find_dlink(recvq_clients, sptr);
            if (lp)
                lp->flags = -1;
        }
        if (IsClient(sptr))
            Count.local--;
        if (IsNegoServer(sptr))
            sendto_realops("Lost server %s during negotiation: %s", 
                           sptr->name, comment);
        
        if (IsServer(sptr)) 
        {
            Count.myserver--;
            if (IsULine(sptr))
                Count.myulined--;
            remove_from_list(&server_list, sptr, NULL);
            if (server_list == NULL) 
                server_was_split = YES;
        }
        sptr->flags |= FLAGS_CLOSING;
        if (IsPerson(sptr)) 
        {
            Link *lp, *next;
            LOpts *lopt = sptr->user->lopt;
            /* poof goes their watchlist! */
            hash_del_watch_list(sptr);
            /* if they have listopts, axe those, too */
            if(lopt != NULL) 
            {
                remove_from_list(&listing_clients, sptr, NULL);
                for (lp = lopt->yeslist; lp; lp = next) 
                {
                    next = lp->next;
                    MyFree(lp->value.cp);
                    free_link(lp);
                }
                for (lp = lopt->nolist; lp; lp = next) 
                {
                    next = lp->next;
                    MyFree(lp->value.cp);
                    free_link(lp);
                }
                                
                MyFree(sptr->user->lopt);
                sptr->user->lopt = NULL;
            }
            sendto_realops_lev(CCONN_LEV,
                               "Client exiting: %s (%s@%s) [%s] [%s]",
                               sptr->name, sptr->user->username,
                               sptr->user->host,
                               (sptr->flags & FLAGS_NORMALEX) ?
                               "Client Quit" : comment,
                               sptr->hostip);
        }
#ifdef FNAME_USERLOG
        on_for = timeofday - sptr->firsttime;
#endif
#if defined(USE_SYSLOG) && defined(SYSLOG_USERS)
        if (IsPerson(sptr))
            syslog(LOG_NOTICE, "%s (%3d:%02d:%02d): %s!%s@%s %d/%d\n",
                   myctime(sptr->firsttime),
                   on_for / 3600, (on_for % 3600) / 60,
                   on_for % 60, sptr->name,
                   sptr->user->username, sptr->user->host,
                   sptr->sendK, sptr->receiveK);
#endif
#if defined(FNAME_USERLOG)
        {
            char        linebuf[300];
            static int  logfile = -1;
            static long lasttime;
            
            /*
             * This conditional makes the logfile active only after it's
             * been created - thus logging can be turned off by removing
             * the file.
             * 
             * stop NFS hangs...most systems should be able to open a file in
             * 3 seconds. -avalon (curtesy of wumpus)
             * 
             * Keep the logfile open, syncing it every 10 seconds -Taner
             */
            if (IsPerson(sptr)) 
            {
                if (logfile == -1) 
                {
                    alarm(3);
                    logfile = open(FNAME_USERLOG, O_WRONLY | O_APPEND);
                    alarm(0);
                }
                ircsprintf(linebuf, "%s (%3d:%02d:%02d): %s!%s@%s %d/%d\n",
                           myctime(sptr->firsttime), on_for / 3600,
                           (on_for % 3600) / 60, on_for % 60,
                           sptr->name, sptr->user->username,
                           sptr->user->host, sptr->sendK, sptr->receiveK);
                alarm(3);
                write(logfile, linebuf, strlen(linebuf));
                alarm(0);
                /* Resync the file evey 10 seconds*/
                if (timeofday - lasttime > 10) 
                {
                    alarm(3);
                    close(logfile);
                    alarm(0);
                    logfile = -1;
                    lasttime = timeofday;
                }
            }
        }
#endif
        if (sptr->fd >= 0) 
        {
            if (cptr != NULL && sptr != cptr)
              sendto_one(&me, sptr, "ERROR :Closing Link: %s %s (%s)",
                           IsPerson(sptr) ? sptr->sockhost : "0.0.0.0", 
                           sptr->name, comment);
            else
              sendto_one(&me, sptr, "ERROR :Closing Link: %s (%s)",
                           IsPerson(sptr) ? sptr->sockhost : "0.0.0.0", 
                           comment);
        }
        /*
         * * Currently only server connections can have * depending
         * remote clients here, but it does no * harm to check for all
         * local clients. In * future some other clients than servers
         * might * have remotes too... *
         * 
         * Close the Client connection first and mark it * so that no
         * messages are attempted to send to it. *, The following *must*
         * make MyConnect(sptr) == FALSE!). * It also makes sptr->from ==
         * NULL, thus it's unnecessary * to test whether "sptr != acptr"
         * in the following loops.
         */
        if (IsServer(sptr)) 
        {
            sendto_ops("%s was connected for %lu seconds.  %lu/%lu "
                       "sendK/recvK.", sptr->name,
		       (long)(timeofday - sptr->firsttime),
                       sptr->sendK, sptr->receiveK);
#ifdef USE_SYSLOG
            syslog(LOG_NOTICE, "%s was connected for %lu seconds.  %lu/%lu "
                   "sendK/recvK.", sptr->name, 
                        (u_long) timeofday - sptr->firsttime,
                   sptr->sendK, sptr->receiveK);
#endif
            close_connection(sptr);
            sptr->sockerr = 0;
            sptr->flags |= FLAGS_DEADSOCKET;
        }
        else
        {
            close_connection(sptr);
            sptr->sockerr = 0;
            sptr->flags |= FLAGS_DEADSOCKET;
        }
                
    }
    exit_one_client(cptr, sptr, from, comment);
    return cptr == sptr ? FLUSH_BUFFER : 0;
}
Beispiel #28
0
int main()
{
  buffer bin;
  buffer bout;
  struct prioq_elt pe;
  int fdoldmbox;
  int fdnewmbox;
  int fd;
  int match;
  int fdlock;

  umask(077);

  mbox = env_get("MAIL");
  if (!mbox) strerr_die2x(111,FATL,"MAIL not set");
  mboxtmp = env_get("MAILTMP");
  if (!mboxtmp) strerr_die2x(111,FATL,"MAILTMP not set");

  if (maildir_chdir() == -1)
    strerr_die1(111,FATAL,&maildir_chdir_err);
  maildir_clean(&filenames);
  if (maildir_scan(&pq,&filenames,1,1) == -1)
    strerr_die1(111,FATAL,&maildir_scan_err);

  if (!prioq_min(&pq,&pe)) _exit(0); /* nothing new */

  fdlock = open_append(mbox);
  if (fdlock == -1)
    strerr_die4sys(111,FATL,"unable to lock ",mbox,": ");
  if (lock_ex(fdlock) == -1)
    strerr_die4sys(111,FATL,"unable to lock ",mbox,": ");

  fdoldmbox = open_read(mbox);
  if (fdoldmbox == -1)
    strerr_die4sys(111,FATL,"unable to read ",mbox,": ");

  fdnewmbox = open_trunc(mboxtmp);
  if (fdnewmbox == -1)
    strerr_die4sys(111,FATL,"unable to create ",mboxtmp,": ");

  buffer_init(&bin,read,fdoldmbox,inbuf,sizeof(inbuf));
  buffer_init(&bout,write,fdnewmbox,outbuf,sizeof(outbuf));

  switch(buffer_copy(&bout,&bin))
  {
    case -2: strerr_die4sys(111,FATL,"unable to read ",mbox,": ");
    case -3: strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  }

  while (prioq_min(&pq,&pe))
  {
    prioq_delmin(&pq);
    if (!prioq_insert(&pq2,&pe)) die_nomem();

    fd = open_read(filenames.s + pe.id);
    if (fd == -1)
      strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
    buffer_init(&bin,read,fd,inbuf,sizeof(inbuf));

    if (getln(&bin,&line,&match,'\n') != 0)
      strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");

    if (!stralloc_copys(&ufline,"From XXX ")) die_nomem();
    if (match)
      if (stralloc_starts(&line,"Return-Path: <"))
      {
        if (line.s[14] == '>')
    {
          if (!stralloc_copys(&ufline,"From MAILER-DAEMON ")) die_nomem();
    }
        else
        {
      int i;
         if (!stralloc_ready(&ufline,line.len)) die_nomem();
         if (!stralloc_copys(&ufline,"From ")) die_nomem();
      for (i = 14;i < line.len - 2;++i)
        if ((line.s[i] == ' ') || (line.s[i] == '\t'))
          ufline.s[ufline.len++] = '-';
        else {
          ufline.s[ufline.len++] = line.s[i];
          if (!stralloc_cats(&ufline," ")) die_nomem();
          }
        }
      }
    if (!stralloc_cats(&ufline,myctime(pe.dt))) die_nomem();
    if (buffer_put(&bout,ufline.s,ufline.len) == -1)
      strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");

    while (match && line.len)
    {
      if (gfrom(line.s,line.len))
        if (buffer_puts(&bout,">") == -1)
          strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
      if (buffer_put(&bout,line.s,line.len) == -1)
        strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
      if (!match)
      {
        if (buffer_puts(&bout,"\n") == -1)
          strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
        break;
      }
      if (getln(&bin,&line,&match,'\n') != 0)
        strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
    }
    if (buffer_puts(&bout,"\n"))
      strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");

   close(fd);
  }

  if (buffer_flush(&bout) == -1)
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (fsync(fdnewmbox) == -1)
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (close(fdnewmbox) == -1) /* NFS dorks */
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (rename(mboxtmp,mbox) == -1)
    strerr_die6(111,FATL,"unable to move ",mboxtmp," to ",mbox,": ",&strerr_sys);

  while (prioq_min(&pq2,&pe))
  {
    prioq_delmin(&pq2);
    if (unlink(filenames.s + pe.id) == -1)
      strerr_warn4(WARNING,"$MAILDIR/",filenames.s + pe.id," will be delivered twice; unable to unlink: ",&strerr_sys);
  }

  return(0);
}
Beispiel #29
0
static	time_t	check_pings(time_t currenttime)
{
#ifdef TIMEDKLINES
	static	time_t	lkill = 0;
#endif
	Reg	aClient	*cptr;
	Reg	int	kflag = 0;
	aClient *bysptr = NULL;
	int	ping = 0, i;
	time_t	oldest = 0, timeout;
	char	*reason = NULL;

	for (i = highest_fd; i >= 0; i--)
	    {
		if (!(cptr = local[i]) || IsListener(cptr))
			continue;

#ifdef TIMEDKLINES
		kflag = 0;
		reason = NULL;
		/* 
		** Once per TIMEDKLINES seconds.
		** (1 minute is minimum resolution in K-line field)
		*/
		if ((currenttime - lkill > TIMEDKLINES)
			&& IsPerson(cptr) && !IsKlineExempt(cptr))
		{
			kflag = find_kill(cptr, 1, &reason);
		}
#endif
		ping = IsRegistered(cptr) ? cptr->ping : ACCEPTTIMEOUT;
		Debug((DEBUG_DEBUG, "c(%s) %d p %d k %d a %d",
			cptr->name, cptr->status, ping, kflag,
			currenttime - cptr->lasttime));
		/*
		 * Ok, so goto's are ugly and can be avoided here but this code
		 * is already indented enough so I think its justified. -avalon
		 */
		if (!kflag && IsRegistered(cptr) &&
		    (ping >= currenttime - cptr->lasttime))
			goto ping_timeout;
		/*
		 * If the server hasnt talked to us in 2*ping seconds
		 * and it has a ping time, then close its connection.
		 * If the client is a user and a KILL line was found
		 * to be active, close this connection too.
		 */
		if (kflag ||
		    ((currenttime - cptr->lasttime) >= (2 * ping) &&
		     (cptr->flags & FLAGS_PINGSENT)) ||
		    (!IsRegistered(cptr) &&
		     (currenttime - cptr->firsttime) >= ping))
		    {
			if (!IsRegistered(cptr) && 
			    (DoingDNS(cptr) || DoingAuth(cptr) ||
			     DoingXAuth(cptr)))
			    {
				if (cptr->authfd >= 0)
				    {
					(void)close(cptr->authfd);
					cptr->authfd = -1;
					cptr->count = 0;
					*cptr->buffer = '\0';
				    }
				Debug((DEBUG_NOTICE, "%s/%c%s timeout %s",
				       (DoingDNS(cptr)) ? "DNS" : "dns",
				       (DoingXAuth(cptr)) ? "X" : "x",
				       (DoingAuth(cptr)) ? "AUTH" : "auth",
				       get_client_name(cptr,TRUE)));
				del_queries((char *)cptr);
				ClearAuth(cptr);
#if defined(USE_IAUTH)
				if (DoingDNS(cptr) || DoingXAuth(cptr))
				    {
					if (DoingDNS(cptr) &&
					    (iauth_options & XOPT_EXTWAIT))
					    {
						/* iauth wants more time */
						sendto_iauth("%d d", cptr->fd);
						ClearDNS(cptr);
						cptr->lasttime = currenttime;
						continue;
					    }
					if (DoingXAuth(cptr) &&
					    (iauth_options & XOPT_NOTIMEOUT))
					    {
						cptr->exitc = EXITC_AUTHTOUT;
						sendto_iauth("%d T", cptr->fd);
						exit_client(cptr, cptr, &me,
						     "Authentication Timeout");
						continue;
					    }
					sendto_iauth("%d T", cptr->fd);
					SetDoneXAuth(cptr);
				    }
#endif
				ClearDNS(cptr);
				ClearXAuth(cptr);
				ClearWXAuth(cptr);
				cptr->firsttime = currenttime;
				cptr->lasttime = currenttime;
				continue;
			    }
			if (IsServer(cptr) || IsConnecting(cptr) ||
			    IsHandshake(cptr))
			{
				if (cptr->serv && cptr->serv->byuid[0])
				{
					bysptr = find_uid(cptr->serv->byuid,
							NULL);
				}
				/* we are interested only in *remote* opers */
				if (bysptr && !MyConnect(bysptr))
				{
					sendto_one(bysptr, ":%s NOTICE %s :"
						"No response from %s, closing"
						" link", ME, bysptr->name,
						get_client_name(cptr, FALSE));
				}
				sendto_flag(SCH_NOTICE,
					    "No response from %s closing link",
					    get_client_name(cptr, FALSE));
			}
			/*
			 * this is used for KILL lines with time restrictions
			 * on them - send a message to the user being killed
			 * first.
			 */
			if (kflag && IsPerson(cptr))
			    {
				char buf[100];

				sendto_flag(SCH_NOTICE,
					    "Kill line active for %s",
					    get_client_name(cptr, FALSE));
				cptr->exitc = EXITC_KLINE;
				if (!BadPtr(reason))
					sprintf(buf, "Kill line active: %.80s",
						reason);
				(void)exit_client(cptr, cptr, &me, (reason) ?
						  buf : "Kill line active");
			    }
			else
			    {
				cptr->exitc = EXITC_PING;
				(void)exit_client(cptr, cptr, &me,
						  "Ping timeout");
			    }
			continue;
		    }
		else if (IsRegistered(cptr) &&
			 (cptr->flags & FLAGS_PINGSENT) == 0)
		    {
			/*
			 * if we havent PINGed the connection and we havent
			 * heard from it in a while, PING it to make sure
			 * it is still alive.
			 */
			cptr->flags |= FLAGS_PINGSENT;
			/* not nice but does the job */
			cptr->lasttime = currenttime - ping;
			sendto_one(cptr, "PING :%s", me.name);
		    }
ping_timeout:
		timeout = cptr->lasttime + ping;
		while (timeout <= currenttime)
			timeout += ping;
		if (timeout < oldest || !oldest)
			oldest = timeout;
	    }
#ifdef TIMEDKLINES
	if (currenttime - lkill > 60)
		lkill = currenttime;
#endif
	if (!oldest || oldest < currenttime)
		oldest = currenttime + PINGFREQUENCY;
	if (oldest < currenttime + 30)
		oldest += 30;
	Debug((DEBUG_NOTICE,"Next check_ping() call at: %s, %d %d %d",
		myctime(oldest), ping, oldest, currenttime));
	return (oldest);
}
Beispiel #30
0
int
m_info(aClient *cptr, aClient *sptr, int parc, char *parv[])

{
  char **text = infotext;
  static time_t last_used=0L;
  Info *infoptr;

  if(IsServer(sptr))
    return 0;

  if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME)
  {
    sendto_ops_imodes(IMODE_SPY, "info requested by %s (%s@%s) [%s]",
      sptr->name, sptr->username, sptr->host,
      sptr->user->server);

    if (!IsAnOper(sptr))
    {
      /* reject non local requests */
      if (!MyConnect(sptr))
        return 0;
      if ((last_used + PACE_WAIT) > CurrentTime)
      {
        /* safe enough to give this on a local connect only */
        sendto_one(sptr,form_str(RPL_LOAD2HI),me.name,parv[0]);
        return 0;
      }
      else
        last_used = CurrentTime;
    } /* if (!IsAnOper(sptr)) */

    while (*text)
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], *text++);

    /*
     * Now send them a list of all our configuration options
     * (mostly from config.h)
     */
    if (IsAnOper(sptr))
    {
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "Compile-time configuration options:");

      for (infoptr = MyInformation; infoptr->name; infoptr++)
      {
        if (infoptr->intvalue)
          sendto_one(sptr,
            ":%s %d %s :%-30s %-5d [%-30s]",
            me.name,
            RPL_INFO,
            parv[0],
            infoptr->name,
            infoptr->intvalue,
            infoptr->desc);
        else
          sendto_one(sptr,
            ":%s %d %s :%-30s %-5s [%-30s]",
            me.name,
            RPL_INFO,
            parv[0],
            infoptr->name,
            infoptr->strvalue,
            infoptr->desc);
      }

      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");
      
      sendto_one(sptr,
        ":%s %d %s :Running binary [%s]",
        me.name,
        RPL_INFO,
        parv[0],
        ircdpath);

#ifndef SERVERHIDE
      sendto_one(sptr,
        ":%s %d %s :Compiled on [%s]",
        me.name,
        RPL_INFO,
        parv[0],
        platform);
#endif
#ifdef HLC
      sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");
      sendto_one(sptr, ":%s NOTICE %s :HLC - Current: %lu, Last received at: %lu, Lag: %lu",
        me.name, sptr->name, CurrentTime, receivedat, CurrentTime - receivedat);
      if (CurrentTime - receivedat >= LAGLIMIT)
        sendto_one(sptr, ":%s NOTICE %s :HLC - Rejecting all client connections",
          me.name, sptr->name);
#endif        
    } /* if (IsAnOper(sptr)) */

    sendto_one(sptr, form_str(RPL_INFO), me.name, parv[0], "");

    sendto_one(sptr,
      ":%s %d %s :Birth Date: %s, compile # %s",
      me.name,
      RPL_INFO,
      parv[0],
      creation,
      generation);

    sendto_one(sptr,
      ":%s %d %s :On-line since %s",
      me.name,
      RPL_INFO,
      parv[0],
      myctime(me.firsttime));

    sendto_one(sptr, form_str(RPL_ENDOFINFO), me.name, parv[0]);
  } /* if (hunt_server(cptr,sptr,":%s INFO :%s",1,parc,parv) == HUNTED_ISME) */

  return 0;
} /* m_info() */