Internet Relay Chat (IRC) Part 5/6

david bleckmann bleckmd at jacobs.cs.orst.edu
Tue Jun 20 13:35:18 AEST 1989


---- Cut Here and unpack ----
#!/bin/sh
# this is part 5 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file r_msg.c continued
#
CurArch=5
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file r_msg.c"
sed 's/^X//' << 'SHAR_EOF' >> r_msg.c
X  putline(mybuf);
X}
X
Xm_private(sptr, cptr, sender, buf, buf2)
Xstruct Client *sptr, *cptr;
Xchar *buf, *buf2, *sender;
X{
X  char *ptr;
X  if (sender && sender[0]) {
X    if (myncmp(sender, client->nickname, NICKLEN))
X      sprintf(mybuf,"*%s* %s", sender, buf2);
X    else
X      sprintf(mybuf,"-> *%s* %s", buf, buf2);
X    putline(mybuf);
X    parse(
X    if (ptr = mycncmp(buf2,"DEAL", 1)) {
X      sendto_one(client,"MSG :Deal requested by %s", sender);
X      deal();
X    } else if (ptr = mycncmp(buf2, "PLAYER", 1)) {
X      sendto_one(client,"MSG :%s requested to be added to game",
X		 sender);
X      player(sender);
X    } else if (ptr = mycncmp(buf2, "INIT", 1)) {
X      sendto_one(client,"MSG :%s requested a new game with %d cards",
X		 sender, atoi(ptr));
X      if (atoi(ptr) > 0)
X	init_game(atoi(ptr));
X    } else if (ptr = mycncmp(buf2, "NAMES", 1)) {
X      sendto_one(client,"MSG :Revealing names of players");
X      names();
X    } else if (ptr = mycncmp(buf2, "HAND", 1)) {
X      hand(sender);
X    } else if (ptr = mycncmp(buf2, "SHUFFLE", 1)) {
X      shuffle(sender);
X    } else {
X      sendto_one(client,"PRIVMSG %s :Commands available are:", sender);
X      sendto_one(client,"PRIVMSG %s :INIT PLAYER NAMES DEAL HAND SHUFFLE",
X		 sender);
X    }
X  }
X  else
X    putline(buf2);
X}
X
Xm_invite(sptr, cptr, sender, buf, buf2)
Xstruct Client *sptr, *cptr;
Xchar *buf, *buf2, *sender;
X{
X  sprintf(mybuf,"*** %s Invites you to channel %s", sender, buf2);
X  putline(mybuf);
X  sendto_one(client,"MSG :%s invited me away, Byebye...", sender);
X  sendto_one(client,"CHANNEL %s", buf2);
X  sendto_one(client,"MSG :Hello %s, always ready to serve you...", sender);
X}
X
Xm_error(sptr, cptr, sender, buf, buf2)
Xstruct Client *sptr, *cptr;
Xchar *buf, *buf2, *sender;
X{
X  sprintf(mybuf,"*** Error: %s %s", buf, (buf2) ? buf2 : "");
X  putline(mybuf);
X}
SHAR_EOF
echo "File r_msg.c is complete"
chmod 0600 r_msg.c || echo "restore of r_msg.c fails"
set `wc -c r_msg.c`;Sum=$1
if test "$Sum" != "7406"
then echo original size 7406, current size $Sum;fi
echo "x - extracting s_bsd.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > s_bsd.c &&
X/*************************************************************************
X ** s_bsd.c  Beta  v2.0    (22 Aug 1988)
X **
X ** This file is part of Internet Relay Chat v2.0
X **
X ** Author:           Jarkko Oikarinen 
X **         Internet: jto at tolsun.oulu.fi
X **             UUCP: ...!mcvax!tut!oulu!jto
X **           BITNET: toljto at finou
X **
X ** Copyright (c) 1988 University of Oulu, Computing Center
X **
X ** All rights reserved.
X **
X ** See file COPYRIGHT in this package for full copyright.
X ** 
X *************************************************************************/
X
Xchar s_bsd_id[] = "s_bsd.c v2.0 (c) 1988 University of Oulu, Computing Center";
X
X#include "struct.h"
X#if HPUX
X#include <time.h>
X#else
X#include <sys/time.h>
X#endif
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/file.h>
X#include <sys/ioctl.h>
X#include <netinet/in.h>
X#if !HPUX
X#include <arpa/inet.h>
X#endif
X#include <netdb.h>
X#include <stdio.h>
X#include <signal.h>
X#include <fcntl.h>
X#include <utmp.h>
X#if BSD42 || ULTRIX || HPUX
X#include "sock.h"
X#endif
X#include "sys.h"
X
Xextern struct Client me;
Xextern struct Client *client;
Xextern struct Confitem *find_conf();
Xextern int portnum;
Xextern int dummy();
X
Xint
Xopen_port(portnum)
Xint portnum;
X{
X  int sock, length;
X  static struct sockaddr_in server;
X  /* At first, open a new socket */
X  sock = socket(AF_INET, SOCK_STREAM, 0);
X  if (sock < 0) {
X    perror("opening stream socket");
X    exit(-1);
X  }
X
X  /* Bind a port to listen for new connections */
X  server.sin_family = AF_INET;
X  server.sin_addr.s_addr = INADDR_ANY;
X  server.sin_port = htons(portnum);
X  for (length = 0; length < 10; length++) {
X    if (bind(sock, &server, sizeof(server))) {
X      perror("binding stream socket");
X      if (length >= 9)
X	exit(-1);
X      sleep(20);
X    } else
X      break;
X  }
X  listen(sock, 3);
X  return(sock);
X}
X
Xinit_sys()
X{
X  int fd;
X#ifdef NOTTY
X#if !HPUX
X  setlinebuf(stdout);
X  setlinebuf(stderr);
X#endif
X  if (isatty(0)) {
X    close (0); close(1); close(2);
X    if (fork()) exit(0);
X#ifdef TIOCNOTTY
X    if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
X      ioctl(fd, TIOCNOTTY, (char *) 0);
X      close(fd);
X    }
X#else
X    setpgrp(0,getpid());
X#endif
X  } else {
X    close (0); close(1); close(2);
X  }
X#endif
X}
X
Xint
Xcheck_access(cptr, flags) /* Check whether any clients/daemons/operators */
Xstruct Client *cptr;   /* are allowed to enter from this host         */
Xint flags;
X{
X  struct sockaddr_in name;
X  struct hostent *host;
X  char *hname;
X  int namecount = -1;
X  int len = sizeof(name);
X  if (getpeername(cptr->fd, &name, &len) == -1) {
X    perror("check_access (getpeername)");
X    return(-1);
X  }
X  if ((host = gethostbyaddr(&(name.sin_addr),
X			    sizeof (struct in_addr), AF_INET)) == NULL) {
X#if ULTRIX
X    return(-1);
X#endif
X  }
X#if !ULTRIX
X  hname = inet_ntoa(name.sin_addr);
X#else
X  hname = host->h_name;
X#endif
X  do {
X    debug(DEBUG_DEBUG,"Checking access for (%s) host", hname);
X    if (find_conf(hname, NULL, NULL, flags)) {
X      debug(DEBUG_DEBUG,"Access ok, host (%s)", hname);
X      break;
X    }
X    debug(DEBUG_DEBUG,"Access checked");
X    if (hname) {
X      if (namecount < 0) {
X	if (host == 0)
X	  return -1;
X	hname = host->h_name;
X	namecount = 0;
X      }
X      else {
X	if (host == 0)
X	  return -1;
X	hname = host->h_aliases[namecount++];
X      }
X      if (hname == 0 || *hname == 0)
X	hname = NULL;
X    }
X  } while (hname);
X  if (!hname)
X    return -1;
X  strncpy(cptr->sockhost, hname, HOSTLEN);
X  cptr->sockhost[HOSTLEN] = '\0';
X}
X
Xread_msg(buffer, buflen, from)
Xchar *buffer;
Xint buflen;
Xstruct Client **from;
X{
X  struct timeval wait;
X  int nfds, res, length;
X  fd_set read_set;                 
X  struct Client *cptr;
X  struct Confitem *aconf;
X  res = 0;
X  do {
X    wait.tv_sec = TIMESEC;
X    wait.tv_usec = 0;
X    FD_ZERO(&read_set);
X    cptr = client;
X    while (cptr) {
X      if (cptr->fd >= 0) FD_SET(cptr->fd, &read_set);
X      cptr = cptr->next;
X    }
X    nfds = select(FD_SETSIZE, &read_set, (fd_set *) 0, (fd_set *) 0, &wait);
X    if (nfds < 0) {
X      perror("select");
X      res++;
X      if (res > 5) {
X	restart();
X      }
X      sleep(10);
X    }
X  } while (nfds < 0);
X  if (nfds == 0)
X    return(nfds);
X  else {
X    if (FD_ISSET(me.fd, &read_set)) {
X      nfds--;
X      cptr = make_client();
X      strcpy(cptr->server, myhostname);
X      if ((cptr->fd = accept(me.fd, (struct sockaddr *) 0, (int *) 0)) < 0)
X	{
X	  perror("accept");
X	  free(cptr);
X	}
X      else {
X/*	res = fcntl(cptr->fd, F_GETFL, 0);
X	fcntl(cptr->fd, F_SETFL, res | O_NDELAY); */
X	if (check_access(cptr, CONF_CLIENT | CONF_NOCONNECT_SERVER
X			 | CONF_UPHOST) >= 0)
X	  client = cptr;
X	else {
X	  close(cptr->fd);
X	  free(cptr);
X	}
X      }
X    }
X    cptr = client;
X      while (cptr && nfds) {
X	if (cptr->fd >= 0 && FD_ISSET(cptr->fd, &read_set) && 
X	    cptr->status != STAT_ME) {
X	  nfds--;
X	  if ((length = read(cptr->fd, buffer, buflen)) <= 0) {
X            perror("read");
X	    debug(DEBUG_DEBUG,"READ ERROR (FATAL): fd = %d", cptr->fd);
X	    aconf = (struct Confitem *) 0;
X	    if (cptr->status == STAT_SERVER)
X		aconf = find_conf(cptr->sockhost, NULL, cptr->host,
X				   CONF_CONNECT_SERVER);
X	    m_bye(cptr, cptr);
X	    if (aconf && aconf->port > 0) {
X	      sleep(3);
X	      connect_server(aconf);
X	    }
X	  }
X	  *from = cptr;
X	  return(length);
X	}
X	cptr = cptr->next;
X      }
X    }
X  return(-1);
X}    
X  
X
Xconnect_server(aconf)
Xstruct Confitem *aconf;
X{
X  struct sockaddr_in server;
X  struct hostent *hp;
X  struct Client *acptr;
X  struct Client *cptr = make_client();
X  int res;
X  struct sockaddr_in name;
X  struct hostent *host;
X  int len = sizeof(name);
X  cptr->fd = socket(AF_INET, SOCK_STREAM, 0);
X  if (cptr->fd < 0) {
X    perror("opening stream socket to server");
X    free(cptr);
X    return(-1);
X  }
X  server.sin_family = AF_INET;
X
X /* MY FIX -- jtrim at duorion.cair.du.edu  (2/10/89) */
X#if !ULTRIX
X  if (isdigit(*(aconf->host))) 
X      server.sin_addr.s_addr = inet_addr(aconf->host);
X  else 
X  {
X#endif
X    hp = gethostbyname(aconf->host);
X    if (hp == 0) {
X      close(cptr->fd);
X      free(cptr);
X      debug(DEBUG_FATAL, "%s: unknown host", aconf->host);
X      return(-1);
X    }
X   bcopy(hp->h_addr, &server.sin_addr, hp->h_length);
X#if !ULTRIX
X  }
X#endif
X  server.sin_port = htons((aconf->port > 0) ? aconf->port : portnum);
X
X/*  sleep(5); */
X
X/* End FIX */
X
X  signal(SIGALRM, dummy);
X  alarm(4);
X  if (connect(cptr->fd, (struct sockaddr *) &server, sizeof(server)) < 0) {
X    alarm(0);
X    perror("connect");
X    close(cptr->fd);
X    free(cptr);
X    return(-1);
X  }
X  alarm(0);
X  strncpy(cptr->fromhost, aconf->host, HOSTLEN);
X  cptr->fromhost[HOSTLEN] = '\0';
X  strncpy(cptr->host, aconf->host, HOSTLEN);
X  cptr->host[HOSTLEN] = '\0';
X  cptr->status = STAT_HANDSHAKE;
X/*  strncpy(me.server, aconf->host, HOSTLEN);
X  me.server[HOSTLEN] = '\0'; */
X  if (aconf->passwd[0])
X    sendto_one(cptr, "PASS %s",aconf->passwd);
X  sendto_one(cptr, "SERVER %s %s", myhostname, me.server);
X  if (check_access(cptr, CONF_NOCONNECT_SERVER | CONF_UPHOST) < 0) {
X    close(cptr->fd);
X    free(cptr);
X    debug(DEBUG_DEBUG,"No such host in hosts database !");
X    return(-1);
X  }
X  cptr->next = client;
X  client = cptr;
X  return(0);
X/*  res = fcntl(cptr->fd, F_GETFL, 0);
X  fcntl(cptr->fd, F_SETFL, res | O_NDELAY); */
X}
X
Xint utmp_open()
X{
X  int fd;
X  return (open(UTMP,O_RDONLY));
X}
X
Xint utmp_read(fd, name, line, host)
Xint fd;
Xchar *name, *line, *host;
X{
X  struct utmp ut;
X  while (read(fd, &ut, sizeof (struct utmp)) == sizeof (struct utmp)) {
X    strncpy(name,ut.ut_name,8);  name[8] = '\0';
X    strncpy(line,ut.ut_line,8);  line[8] = '\0';
X#ifdef USER_PROCESS
X    strncpy(host, myhostname, 8); host[8] = '\0';
X    if (ut.ut_type == USER_PROCESS)
X      return(0);
X#else
X    strncpy(host,(ut.ut_host[0]) ? (ut.ut_host) : myhostname, 16);
X    if (ut.ut_name[0])
X      return(0);
X#endif
X  }
X  return(-1);
X}
X
Xint utmp_close(fd)
Xint fd;
X{
X  return(close(fd));
X}
X
Xsummon(who, namebuf, linebuf)
Xstruct Client *who;
Xchar *namebuf, *linebuf;
X{
X  int fd;
X  char line[120], *wrerr = "PRIVMSG %s :Write error. Couldn't summon.";
X  if (strlen(linebuf) > 8) {
X    sendto_one(who,"PRIVMSG %s :Serious fault in SUMMON.");
X    sendto_one(who,"PRIVMSG %s :linebuf too long. Inform Administrator");
X    return(-1);
X  }
X  /* Following line added to prevent cracking to e.g. /dev/kmem if */
X  /* UTMP is for some silly reason writable to everyone... */
X  if ((linebuf[0] != 't' || linebuf[1] != 't' || linebuf[2] != 'y') &&
X      (linebuf[0] != 'c' || linebuf[1] != 'o' || linebuf[2] != 'n')) {
X    sendto_one(who,"PRIVMSG %s :Looks like mere mortal souls are trying to");
X    sendto_one(who,"PRIVMSG %s :enter the twilight zone... ");
X    debug(0, "%s (%s@%s, nick %s, %s)",
X	  "FATAL: major security hack. Notify Administrator !",
X	  who->username, who->host, who->nickname, who->realname);
X    return(-1);
X  }
X  strcpy(line,"/dev/");
X  strcat(line,linebuf);
X  alarm(5);
X  if ((fd = open(line, O_WRONLY | O_NDELAY)) == -1) {
X    alarm(0);
X    sendto_one(who,"PRIVMSG %s :%s seems to have disabled summoning...",
X	       who->nickname, namebuf);
X    return(-1);
X  }
X  alarm(0);
X  strcpy(line,
X	 "\n\r\007ircd: You are being summoned to Internet Relay Chat by\n\r");
X  alarm(5);
X  if (write(fd, line, strlen(line)) != strlen(line)) {
X    alarm(0);
X    close(fd);
X    sendto_one(who,wrerr,who->nickname);
X    return(-1);
X  }
X  alarm(0);
X  sprintf(line, "ircd: Channel %d: %s@%s (%s) %s\n\r", who->channel,
X	  who->username, who->host, who->nickname, who->realname);
X  alarm(5);
X  if (write(fd, line, strlen(line)) != strlen(line)) {
X    alarm(0);
X    close(fd);
X    sendto_one(who,wrerr,who->nickname);
X    return(-1);
X  }
X  alarm(0);
X  strcpy(line,"ircd: Respond with irc\n\r");
X  alarm(5);
X  if (write(fd, line, strlen(line)) != strlen(line)) {
X    alarm(0);
X    close(fd);
X    sendto_one(who,wrerr,who->nickname);
X    return(-1);
X  }
X  close(fd);
X  alarm(0);
X  sendto_one(who, "PRIVMSG %s :%s: Summoning user %s to irc",
X	     who->nickname, myhostname, namebuf);
X  return(0);
X}
X  
Xgetmyname(name, len)
Xchar *name;
Xint len;
X{
X  int namelen;
X  if (gethostname(name,len) < 0)
X    return(-1);
X  name[len] = '\0';
X#if DOMAINNAME
X  if ((index(name,'.') == (char *) 0) && ((namelen = strlen(name)) < len - 1))
X    {
X      name[namelen] = '.';
X      if (getdomainname(&name[namelen+1], len-namelen-1) < 0)
X	return(-1);
X      name[len] = '\0';
X    } 
X  else
X    return(-1);
X#endif
X}
X
Xlong
Xgetlongtime()
X{
X  return(time(0));
X}
SHAR_EOF
chmod 0600 s_bsd.c || echo "restore of s_bsd.c fails"
set `wc -c s_bsd.c`;Sum=$1
if test "$Sum" != "10443"
then echo original size 10443, current size $Sum;fi
echo "x - extracting s_msg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > s_msg.c &&
X/*************************************************************************
X ** s_msg.c  Beta  v2.0    (22 Aug 1988)
X **
X ** This file is part of Internet Relay Chat v2.0
X **
X ** Author:           Jarkko Oikarinen 
X **         Internet: jto at tolsun.oulu.fi
X **             UUCP: ...!mcvax!tut!oulu!jto
X **           BITNET: toljto at finou
X **
X ** Copyright (c) 1988 University of Oulu, Computing Center
X **
X ** All rights reserved.
X **
X ** See file COPYRIGHT in this package for full copyright.
X ** 
X *************************************************************************/
X
Xchar s_msg_id[] = "s_msg.c v2.0 (c) 1988 University of Oulu, Computing Center";
X
X#include "struct.h"
X#include "sys.h"
X#include <sys/types.h>
X#include <sys/file.h>
X#if APOLLO
X#include <sys/types.h>
X#endif
X#include <utmp.h>
X#include "msg.h"
X
X#define NULL ((char *) 0)
X
Xextern struct Client *client, me;
Xextern struct Client *find_client();
Xextern struct Client *find_server();
Xextern struct Confitem *find_conf(), *find_admin();
Xextern struct Confitem *conf;
Xextern struct Channel *find_channel();
Xextern char *center();
Xextern char *uphost;
Xstruct Channel *channel = (struct Channel *) 0;
Xextern int maxusersperchannel;
X
Xchar buf[BUFSIZE];
Xchar buf2[80];
X
Xm_nick(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{
X  struct Client *acptr;
X  char *ch;
X  int flag = 0;
X  if (para == NULL || *para == '\0') {
X    sendto_one(sptr,"ERROR :Nickname %s not changed",sptr->nickname);
X  } else {
X    ch = para;
X    if ((*ch >= '0' && *ch <= '9') || *ch == '-' || *ch == '+')
X      *ch = '\0';
X    while (*ch) {
X      if ((*ch < 65 || *ch > 125) && (*ch < '0' || *ch > '9') &&
X	  *ch != '_' && *ch != '-') *ch = '\0';
X      ch++;
X    }
X    if (*para == '\0') {
X      sendto_one(sptr,"ERROR :Illegal Nickname");
X      return(0);
X    }
X    if ((acptr = find_client(para,NULL)) == (struct Client *) 0) {
X      if (sptr->status == STAT_SERVER) {
X	sptr = make_client();
X	strcpy(sptr->fromhost, cptr->host);
X	flag = 1;
X      }
X      else if (sptr->realname[0]) {
X	if (sptr->fd >= 0 && sptr->status == STAT_UNKNOWN) {
X	  sptr->status = STAT_CLIENT;
X	  dowelcome(sptr);
X	}
X	if (sptr->realname[0] && sptr->nickname[0] == '\0')
X	  flag = 2;
X      }
X      if (sptr->channel != 0)
X	sendto_channel_butserv(sptr->channel, ":%s NICK %s",
X			       sptr->nickname, para);
X      if (sptr->nickname[0])
X	sendto_serv_butone(cptr, ":%s NICK %s",sptr->nickname, para);
X      else
X	sendto_serv_butone(cptr, "NICK %s", para);
X      strncpy(sptr->nickname, para, NICKLEN-1);
X      sptr->nickname[NICKLEN-1] = '\0';
X      if (flag == 2) {
X	sendto_serv_butone(cptr,":%s USER %s %s %s :%s", sptr->nickname,
X			   sptr->username, sptr->host, sptr->server,
X			   sptr->realname);
X      }
X      if (flag == 1) {
X	sptr->next = client;
X	client = sptr;
X      } 
X    } else {
X      sendto_one(sptr,"ERROR :Nickname %s already exists. %s",
X		 para, "No change performed");
X      if (cptr->status == STAT_SERVER)
X	m_bye(acptr, acptr);
X    }
X  }
X  return(0);
X}
X
Xm_text(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{
X  if (para == NULL || *para == '\0' || sptr->status < 0) 
X    sendto_one(sptr,"ERROR :No text sent");
X  else if (sptr->channel != 0) 
X    sendto_channel_butone(cptr,
X			  sptr->channel, ":%s MSG :%s", 
X			  sptr->nickname, para);
X  else
X    sendto_one(sptr,"ERROR :You have not joined any channel");
X  return(0);
X}
X
Xm_private(cptr, sptr, sender, para, para2)
Xstruct Client *cptr, *sptr;
Xchar *para, *para2, *sender;
X{
X  struct Client *acptr;
X  struct Channel *chptr;
X  char *nick, *tmp;
X  if (para == NULL || *para == '\0' || para2 == NULL || *para2 == '\0' ||
X      sptr->status < 0)
X    sendto_one(sptr,"ERROR :No text sent");
X  else {
X    tmp = para;
X    do {
X      nick = tmp;
X      if (tmp = index(nick, ',')) {
X	*(tmp++) = '\0';
X      }
X      acptr = find_client(nick, NULL);
X      if (acptr) {
X	if (acptr->away) {
X	  sendto_one(sptr,"PRIVMSG %s :%s has marked himself as being %s",
X		     sptr->nickname, acptr->nickname, 
X		     "away and gave message: ");
X	  sendto_one(sptr,"PRIVMSG %s :\'%s\'",sptr->nickname,acptr->away);
X	  sendto_one(sptr,"PRIVMSG %s :Your message was sent to him anyway",
X		     sptr->nickname);
X	}
X	sendto_one(acptr, ":%s PRIVMSG %s :%s", sptr->nickname, nick, para2);
X      } else if (chptr = find_channel(nick, NULL)) {
X	sendto_channel_butone(cptr, chptr->channo,
X			      ":%s PRIVMSG %d :%s", sptr->nickname,
X			      chptr->channo, para2);
X      } else {
X	sendto_one(sptr, "PRIVMSG %s :*** Error: No such nickname (%s)",
X		   sptr->nickname, nick);
X      }
X    } while (tmp && *tmp);
X  }
X  return (0);
X}
X
Xm_who(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{
X  int i;
X  struct Client *acptr = client;
X  if (para == NULL || para[0] == '\0')
X    i = 0;
X  else if (index(para,'*'))
X    i = sptr->channel;
X  else
X    i = atoi(para);
X  sendto_one(sptr,"WHOREPLY * User Host Server Nickname S :Name");
X  while (acptr) {
X    if ((i == 0 || acptr->channel == i) && 
X	(acptr->status == STAT_CLIENT || acptr->status == STAT_OPER) &&
X	(acptr->channel >= 0 || acptr->channel == sptr->channel)) {
X      if ((acptr->channel < 1000 && acptr->channel > 0) ||
X	  (sptr->channel == acptr->channel && sptr->channel != 0))
X	sendto_one(sptr, "WHOREPLY %d %s %s %s %s %c%c :%s",
X		   acptr->channel, acptr->username, acptr->host,
X		   acptr->server, acptr->nickname, (acptr->away) ? 'G' : 'H',
X		   (acptr->status == STAT_OPER) ? '*' : ' ', acptr->realname);
X      else
X	sendto_one(sptr,"WHOREPLY 0 %s %s %s %s %c%c :%s",
X		   acptr->username, acptr->host, acptr->server,
X		   acptr->nickname, (acptr->away) ? 'G' : 'H',
X		   (acptr->status == STAT_OPER) ? '*' : ' ', acptr->realname);
X    }
X    acptr = acptr->next;
X  }
X  return(0);
X}
X
Xm_whois(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{
X  struct Client *acptr;
X  if (para == NULL || *para == '\0')
X    sendto_one(sptr,"ERROR No nickname specified");
X  else {
X    acptr = find_client(para,NULL);
X    if (acptr == (struct Client *) 0)
X      sendto_one(sptr,"ERROR :No such nickname");
X    else {
X      sendto_one(sptr,"PRIVMSG %s :%s is %s at %s (%s)",sptr->nickname,
X		 acptr->nickname, acptr->username, acptr->host,
X		 acptr->realname);
X      sendto_one(sptr,"PRIVMSG %s :On IRC via server %s",sptr->nickname,
X		 acptr->server);
X      if (acptr->away) 
X	sendto_one(sptr,"PRIVMSG %s :He is away: \"%s\"",
X		   sptr->nickname, acptr->away);
X    }
X  }
X  return(0);
X}
X
Xm_user(cptr, sptr, sender, username, host, server, realname)
Xstruct Client *cptr, *sptr;
Xchar *username, *server, *host, *realname, *sender;
X{
X  struct Confitem *aconf;
X  if (username == NULL || server == NULL || host == NULL || realname == NULL
X      || *username == '\0' || *server == '\0' || *host == '\0' ||
X      *realname == '\0')
X    sendto_one(sptr,"ERROR Not enough parameters");
X  else if (sptr->status != STAT_UNKNOWN && sptr->status != STAT_OPER)
X    sendto_one(sptr,"ERROR Identity problems, eh ?");
X  else {
X    if (sptr->fd >= 0) {
X      if ((aconf = find_conf(sptr->sockhost, NULL, NULL, CONF_CLIENT)) == 0) {
X	if ((aconf = find_conf("", NULL, NULL, CONF_CLIENT)) == 0) {
X	  sendto_one(sptr,"ERROR :Access denied (no host)");
X	  m_bye(sptr, sptr);
X	  return(FLUSH_BUFFER);
X	} 
X      } else 
X	if (strcmp(sptr->passwd, aconf->passwd)) {
X	  sendto_one(sptr,"ERROR :Access denied (passwd mismatch)");
X	  m_bye(sptr, sptr);
X	  return(FLUSH_BUFFER);
X	}
X      host = sptr->sockhost;
X      if (find_conf(host, NULL, username,
X		    CONF_KILL)) {
X	sendto_one(sptr,"ERROR :Ghosts are not allowed on irc...");
X	m_bye(sptr, sptr);
X	return(FLUSH_BUFFER);
X      }
X    }
X    if (sptr->nickname[0]) {
X      sptr->status = STAT_CLIENT;
X      if (sptr->fd >= 0)
X	dowelcome(sptr);
X    }
X    strncpy(sptr->username, username, USERLEN);
X    sptr->username[USERLEN] = '\0';
X    if (cptr != sptr)
X      strncpy(sptr->server, server, HOSTLEN);
X    else
X      strcpy(sptr->server, myhostname);
X    sptr->server[HOSTLEN] = '\0';
X    strncpy(sptr->host, host, HOSTLEN);
X    sptr->host[HOSTLEN] = '\0';
X    strcpy(sptr->realname, realname);
X    sptr->realname[REALLEN] = '\0';
X    if (sptr->status == STAT_CLIENT)
X      sendto_serv_butone(cptr,":%s USER %s %s %s :%s", sptr->nickname,
X			 username, host, sptr->server, realname);
X  }
X  return(0);
X}
X
Xm_list(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{
X  struct Channel *chptr = channel;
X  sendto_one(sptr,"PRIVMSG %s :  Channel  : Users  Name",
X	     sptr->nickname);
X  while (chptr) {
X    if ((chptr->channo < 1000 && chptr->channo > 0) ||
X	(chptr->channo == sptr->channel && sptr->channel != 0))
X      sprintf(buf2,"Channel %3d:",chptr->channo);
X    else
X      strcpy(buf2,"* Private *:");
X    sendto_one(sptr,"PRIVMSG %s :%12s %5d %s",
X	       sptr->nickname, buf2, chptr->users, chptr->name);
X    chptr = chptr->nextch;
X  }
X  return(0);
X}
X
Xm_topic(cptr, sptr, sender, topic)
Xstruct Client *cptr, *sptr;
Xchar *topic, *sender;
X{
X  struct Channel *chptr = channel;
X  if (sptr->status == STAT_UNKNOWN) {
X    sendto_one(sptr,"ERROR :You have not registered yourself yet");
X    return(0);
X  }
X  sendto_serv_butone(cptr,":%s TOPIC %s",sptr->nickname,topic);
X  while (chptr) {
X    if (chptr->channo == sptr->channel) {
X      if (topic == NULL || topic[0] == '\0') {
X	chptr->name[0] = '*'; chptr->name[1] = '\0';
X      } else {
X	strncpy(chptr->name, topic, CHANNELLEN);
X	chptr->name[CHANNELLEN] = '\0';
X      }
X      if (sptr->fd >= 0)
X	sendto_one(sptr,
X		   "PRIVMSG %s :New topic of channel %d (%d users): %s",
X		   sptr->nickname, chptr->channo, chptr->users, chptr->name);
X    }	
X    chptr = chptr->nextch;
X  }
X  return(0);
X}
X
Xm_invite(cptr, sptr, sender, user, channel)
Xstruct Client *cptr, *sptr;
Xchar *user, *channel, *sender;
X{
X  struct Client *acptr;
X  int i;
X  if (sptr->status < 0)
X    sendto_one(sptr,"ERROR :You have not registered yourself yet");
X  else if (user == NULL || *user == '\0')
X    sendto_one(sptr,"ERROR :Not enough parameters");
X  else {
X    acptr = find_client(user,NULL);
X    if (channel == NULL)
X      i = 0;
X    else 
X      i = atoi(channel);
X    if (i == 0)
X      i = sptr->channel;
X    if (acptr == (struct Client *) 0) 
X      sendto_one(sptr,"ERROR :No such nickname");
X    else {
X      sendto_one(sptr,"PRIVMSG %s :%s: Inviting user %s to channel %d",
X		 sptr->nickname, myhostname, acptr->nickname, i);
X      sendto_one(acptr,":%s INVITE %s %d",sptr->nickname,
X		 acptr->nickname, i);
X    }
X  }
X  return(0);
X}
X
Xm_channel(cptr, sptr, sender, ch)
Xstruct Client *cptr, *sptr;
Xchar *ch, *sender;
X{
X  struct Client *acptr;
X  struct Channel *chptr, *pchptr, *ch2ptr;
X  int i;
X  if ((sptr->status != STAT_CLIENT) && (sptr->status != STAT_OPER)) {
X    sendto_one(sptr,"ERROR You have not registered yourself");
X    return(0);
X  }
X  acptr = client;
X  chptr = channel;
X  if (ch == NULL)
X    i = 0;
X  else
X    i = atoi(ch);
X  pchptr = (struct Channel *) 0;
X  if (i > 0) {
X    while (chptr) {
X      if (chptr->channo == i)
X	break;
X      chptr = chptr->nextch;
X    }
X    if (chptr == (struct Channel *) 0) {
X      if ((chptr = (struct Channel *) malloc(sizeof(struct Channel))) == 
X	  (struct Channel *) 0)
X	{
X	  perror("malloc");
X	  debug(DEBUG_FATAL,"Out of memory. Cannot allocate channel");
X	  restart();
X	}
X      chptr->nextch = channel;
X      chptr->channo = i;
X      chptr->name[0] = '\0';
X      chptr->users = 0;
X      channel = chptr;
X    } else if (cptr == sptr && is_full(i, chptr->users)) {
X      sendto_one(sptr,"PRIVMSG %s :Sorry, Channel is full.", sptr->nickname);
X      return(0);
X    }
X    chptr->users++;
X  }
X  chptr = channel;
X  while (chptr) {
X    if (chptr->channo == sptr->channel && chptr->users > 0) 
X      --chptr->users;
X    if (chptr->users <= 0) {
X      if (pchptr)
X	pchptr->nextch = chptr->nextch;
X      else
X	channel = chptr->nextch;
X      free(chptr);
X    }
X    pchptr = chptr;
X    chptr = chptr->nextch;
X  }
X  sendto_serv_butone(cptr, ":%s CHANNEL %d",
X			sptr->nickname, i);
X  if (sptr->channel != 0)
X    sendto_channel_butserv(sptr->channel, ":%s CHANNEL 0", sptr->nickname);
X  sptr->channel = i;
X  if (sptr->channel != 0)
X    sendto_channel_butserv(i, ":%s CHANNEL %d", sptr->nickname, i);
X  return(0);
X}
X
Xm_version(cptr, sptr, sender, vers)
Xstruct Client *sptr, *cptr;
Xchar *sender, *vers;
X{
X  if (vers == NULL)
X    sendto_one(sptr,"VERSION :%s", version);
X  return(0);
X}
X
Xm_quit(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X/*  if (sptr->fd >= 0 && strcmp(sptr->fromhost, cptr->fromhost))
X    return(FLUSH_BUFFER); */  /* Fix 12 Mar 1989 by Jto */
X  if (sptr->status != STAT_SERVER) {
X    m_bye(cptr, sptr);
X    if (cptr == sptr)
X      return(FLUSH_BUFFER);
X    else
X      return(0);
X  }
X  return(0);
X}
X
Xm_squit(cptr, sptr, dummy, server)
Xstruct Client *cptr, *sptr;
Xchar *dummy, *server;
X{
X  struct Client *acptr = find_server(server, NULL);
X  if (sptr->status != STAT_SERVER && sptr->status != STAT_OPER) {
X    sendto_one(sptr,"ERROR :'tis is no game for mere mortal souls");
X    return(0);
X  }
X  if (acptr)
X    m_bye(cptr, acptr);
X  return(0);
X}
X
Xm_server(cptr, sptr, user, host, server)
Xstruct Client *cptr, *sptr;
Xchar *host, *server, *user;
X{
X  struct Client *acptr;
X  struct Confitem *aconf, *bconf;
X  if (host == NULL || *host == '\0') {
X    sendto_one(cptr,"ERROR :No hostname");
X    return(0);
X  }
X  if (find_server(host, NULL)) {
X    sendto_one(sptr,"ERROR :Such name already exists... ");
X    if (cptr == sptr) {
X      m_bye(cptr, sptr);
X      return(FLUSH_BUFFER);
X    } else
X      return(0);
X  }
X  if (sptr->status == STAT_SERVER) {
X    if (server == NULL || *server == '\0') {
X      sendto_one(cptr,"ERROR :No servername specified");
X      return(0);
X    }
X    acptr = make_client();
X    strncpy(acptr->host,host,HOSTLEN); strncpy(acptr->server,server,HOSTLEN);
X    acptr->host[HOSTLEN] = '\0';   acptr->server[HOSTLEN] = '\0';
X    acptr->status = STAT_SERVER;
X    acptr->next = client;
X    strncpy(acptr->fromhost,sptr->host,HOSTLEN);
X    client = acptr;
X    sendto_serv_butone(cptr,"SERVER %s %s",acptr->host, acptr->server);
X    return(0);
X  } else if ((sptr->status == STAT_CLIENT) || (sptr->status == STAT_OPER)) {
X    sendto_one(cptr,"ERROR :Client may not currently become server");
X    return(0);
X  } else if (sptr->status == STAT_UNKNOWN || sptr->status == STAT_HANDSHAKE) {
X    if ((aconf = find_conf(sptr->sockhost, NULL, host, CONF_NOCONNECT_SERVER))
X	== 0) {
X      sendto_one(sptr,"ERROR :Access denied (no such server enabled) (%s@%s)",
X		 host, (server) ? (server) : "Master");
X      m_bye(sptr, sptr);
X      return(FLUSH_BUFFER);
X    }
X    if ((bconf = find_conf(sptr->sockhost, NULL, host, CONF_CONNECT_SERVER))
X	== 0) {
X      sendto_one(sptr, "ERROR :Only C field for server.");
X      m_bye(sptr, sptr);
X      return(FLUSH_BUFFER);
X    }
X    if (*(aconf->passwd) && strcmp(aconf->passwd, sptr->passwd)) {
X      sendto_one(sptr,"ERROR :Access denied (passwd mismatch)");
X      m_bye(sptr, sptr);
X      return(FLUSH_BUFFER);
X    }
X    strncpy(sptr->host, host, HOSTLEN);   sptr->host[HOSTLEN] = '\0';
X    if (server && *server) {
X      strncpy(sptr->server, server, HOSTLEN); sptr->server[HOSTLEN] = '\0';
X    }
X    else {
X      strncpy(sptr->server, myhostname, HOSTLEN); sptr->server[HOSTLEN] = '\0';
X    }
X    strncpy(sptr->fromhost, host, HOSTLEN); sptr->fromhost[HOSTLEN] = '\0';
X    acptr = client;
X    if (sptr->status == STAT_UNKNOWN) {
X      if (aconf->passwd[0])
X	sendto_one(cptr,"PASS %s",bconf->passwd);
X      sendto_one(cptr,"SERVER %s %s", myhostname, 
X		 (me.server[0]) ? (me.server) : "Master");
X    }
X    sptr->status = STAT_SERVER;
X    sendto_serv_butone(cptr,"SERVER %s %s",sptr->host, sptr->server);
X    while (acptr) {
X      if ((acptr->status == STAT_CLIENT) ||
X	  (acptr->status == STAT_OPER)) {
X	sendto_one(cptr,"NICK %s",acptr->nickname);
X	sendto_one(cptr,":%s USER %s %s %s :%s",acptr->nickname,
X		   acptr->username, acptr->host, acptr->server,
X		   acptr->realname);
X	sendto_one(cptr,":%s CHANNEL %d",acptr->nickname, acptr->channel);
X	if (acptr->status == STAT_OPER) 
X	  sendto_one(cptr,":%s OPER", acptr->nickname);
X      } else if (acptr->status == STAT_SERVER && acptr != sptr) {
X	  sendto_one(cptr,"SERVER %s %s",acptr->host, acptr->server);
X      }
X      acptr = acptr->next;
X    }
X    return(0);
X  }
X  return(0);
X}
X
Xm_kill(cptr, sptr, sender, user)
Xstruct Client *cptr, *sptr;
Xchar *sender, *user;
X{
X  struct Client *acptr;
X  debug(DEBUG_DEBUG,"%s: m_kill: %s", sptr->nickname, user);
X  if ((user == NULL) || (*user == '\0')) {
X    sendto_one(sptr,"ERROR :No user specified");
X    return(0);
X  }
X  if (sptr->status != STAT_OPER && sptr->status != STAT_SERVER) {
X    sendto_one(sptr,"ERROR :Death before dishonor ?");
X    return(0);
X  }
X  if ((acptr = find_client(user, NULL)) == (struct Client *) 0) {
X    sendto_one(sptr,"ERROR :Hunting for ghosts ?");
X    return(0);
X  }
X  sendto_one(sptr,"PRIVMSG %s :May his soul rest in peace...",sptr->nickname);
X  sendto_serv_butone(cptr,"KILL %s",user);
X  m_bye(acptr, acptr);
X  return(0);
X}
X
Xm_info(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  sendto_one(sptr,"PRIVMSG %s :%s", sptr->nickname, info1);
X  sendto_one(sptr,"PRIVMSG %s :%s", sptr->nickname, info2);
X  sendto_one(sptr,"PRIVMSG %s :%s", sptr->nickname, info3);
X  return(0);
X}
X
Xm_links(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  struct Client *acptr = client;
X  if (sptr->nickname[0] == '\0') {
X    sendto_one(sptr,"ERROR Nickname not specified yet");
X    return(0);
X  }
X  while (acptr) {
X    if (acptr->status == STAT_SERVER || acptr->status == STAT_ME)
X      sendto_one(sptr,"LINREPLY %s %s", acptr->host,
X		 (acptr->server[0] ? acptr->server : "(Unknown Location)"));
X    acptr = acptr->next;
X  }
X  return(0);
X}
X
Xm_summon(cptr, sptr, sender, user)
Xstruct Client *sptr, *cptr;
Xchar *user, *sender;
X{
X  struct Client *acptr=client, *a2cptr=client;
X  char namebuf[10],linebuf[10],hostbuf[17],*host;
X  int fd, flag;
X  if (sptr->nickname[0] == '\0') {
X    sendto_one(sptr,"ERROR Nickname not specified yet");
X    return(0);
X  }
X  if (user == NULL || *user == '\0') {
X    sendto_one(sptr,"PRIVMSG %s :%s: No user specified",sptr->nickname,
X	       myhostname);
X    return(0);
X  }
X  if ((host = index(user,'@')) == NULL)
X    host = myhostname;
X  else 
X    *(host++) = '\0';
X  if (host == NULL || *host == '\0' || strcmp(host,myhostname) == 0) {
X    if ((fd = utmp_open()) == -1) {
X      sendto_one(sptr,"PRIVMSG %s Cannot open %s",sptr->nickname,UTMP);
X      return(0);
X    }
X    while ((flag = utmp_read(fd, namebuf, linebuf, hostbuf)) == 0) 
X      if (strcmp(namebuf,user) == 0)
X	break;
X    utmp_close(fd);
X    if (flag == -1)
X      sendto_one(sptr,"PRIVMSG %s :%s: No such user found",
X		 sptr->nickname, myhostname);
X    else
X      summon(sptr, namebuf, linebuf);
X    return(0);
X  }
X  while (acptr) 
X    if (acptr->status == STAT_SERVER && strcmp(acptr->host, host) == 0)
X      break;
X    else 
X      acptr = acptr->next;
X  if (acptr == (struct Client *) 0) 
X    sendto_one(sptr,"ERROR No such host found");
X  else {
X    while(a2cptr)
X      if (a2cptr->status == STAT_SERVER &&
X	  strcmp(acptr->fromhost, a2cptr->host) == 0)
X	break;
X    else
X      a2cptr = a2cptr->next;
X    if (a2cptr == (struct Client *) 0)
X      sendto_one(sptr,"ERROR Internal Error. Contact Administrator");
X    else 
X      sendto_one(a2cptr,":%s SUMMON %s@%s",sptr->nickname, user, host);
X  }
X  return(0);
X}
X
Xm_stats(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  struct Message *mptr = msgtab;
X  for (; mptr->cmd; mptr++)
X    sendto_one(sptr,"PRIVMSG %s :%s has been used %d times after startup",
X	       sptr->nickname, mptr->cmd, mptr->count);
X  return(0);
X}
X
Xm_users(cptr, sptr, from, host)
Xstruct Client *cptr, *sptr;
Xchar *from, *host;
X{
X  struct Client *acptr=client, *a2cptr=client;
X  char namebuf[10],linebuf[10],hostbuf[17];
X  int fd, flag = 0;
X  if (sptr->nickname[0] == '\0') {
X    sendto_one(sptr,"ERROR Nickname not specified yet");
X    return(0);
X  }
X  if (host == NULL || *host == '\0' || strcmp(host,myhostname) == 0) {
X    if ((fd = utmp_open()) == -1) {
X      sendto_one(sptr,"PRIVMSG %s Cannot open %s",sptr->nickname,UTMP);
X      return(0);
X    }
X    sendto_one(sptr,"PRIVMSG %s :UserID   Terminal Host", sptr->nickname);
X    while (utmp_read(fd, namebuf, linebuf, hostbuf) == 0) {
X      flag = 1;
X      sendto_one(sptr,"PRIVMSG %s :%-8s %-8s %-8s",
X		 sptr->nickname, namebuf, linebuf, hostbuf);
X    }
X    if (flag == 0) 
X      sendto_one(sptr,"PRIVMSG %s :Nobody logged in on %s",
X		 sptr->nickname, host);
X    utmp_close(fd);
X    return(0);
X  }
X  while (acptr) 
X    if (acptr->status == STAT_SERVER && strcmp(acptr->host, host) == 0)
X      break;
X    else 
X      acptr = acptr->next;
X  if (acptr == (struct Client *) 0) 
X    sendto_one(sptr,"ERROR No such host found");
X  else {
X    while(a2cptr)
X      if (a2cptr->status == STAT_SERVER &&
X	  strcmp(acptr->fromhost, a2cptr->host) == 0)
X	break;
X    else
X      a2cptr = a2cptr->next;
X    if (a2cptr == (struct Client *) 0)
X      sendto_one(sptr,"ERROR Internal Error. Contact Administrator");
X    else 
X      sendto_one(a2cptr,":%s USERS %s",sptr->nickname, host);
X  }
X  return(0);
X}
X
Xm_bye(cptr, sptr) 
Xstruct Client *cptr;
Xstruct Client *sptr;
X{
X  struct Client *acptr;
X  struct Channel *chptr = channel, *pchptr;
X  close(sptr->fd); sptr->fd = -20;
X  if (sptr->status == STAT_SERVER && sptr == cptr) {
X    acptr = client;
X    while (acptr) {
X      if ((acptr->status == STAT_CLIENT || acptr->status == STAT_OPER) &&
X	  strcmp(acptr->fromhost, sptr->host) == 0 &&
X	  sptr != acptr) {
X	exit_user(cptr, acptr);
X	acptr = client;
X      } else 
X	acptr = acptr->next;
X    }
X    acptr = client;
X    while (acptr) {
X      if (acptr->status == STAT_SERVER &&
X	  strcmp(acptr->fromhost, sptr->host) == 0 &&
X	  sptr != acptr) {
X	exit_user(cptr, acptr);
X	acptr = client;
X      } else 
X	acptr = acptr->next;
X    }
X  }
X  exit_user(cptr, sptr);
X  return(0);
X}
X
Xexit_user(cptr, sptr)
Xstruct Client *sptr;
Xstruct Client *cptr;
X{
X  struct Client *acptr;
X  struct Channel *chptr = channel, *pchptr;
X  int i;
X  if ((sptr->status == STAT_CLIENT || sptr->status == STAT_OPER) &&
X      ((i = sptr->channel) != 0)) {
X    sptr->channel = 0;
X    sendto_channel_butserv(i,":%s QUIT", sptr->nickname);
X  } else
X    i = 0;
X  if (sptr->status == STAT_SERVER)
X    sendto_serv_butone(cptr,"SQUIT %s",sptr->host);
X  else if (sptr->nickname[0])
X    sendto_serv_butone(cptr,":%s QUIT",sptr->nickname);
X  pchptr = (struct Channel *) 0;
X  while (chptr) {
X    if (chptr->channo == i && chptr->users > 0) 
X      --chptr->users;
X    if (chptr->users <= 0) {
X      if (pchptr)
X	pchptr->nextch = chptr->nextch;
X      else
X	channel = chptr->nextch;
X      free(chptr);
X    }
X    pchptr = chptr;
X    chptr = chptr->nextch;
X  }
X  if (sptr->fd >= 0)
X    close (sptr->fd);
X  if (sptr == client) {
X    client = client->next;
X    if (sptr->away)
X      free(sptr->away);
X    free(sptr);
X    return(0);
X  }
X  acptr = client;
X  while (acptr && acptr->next != sptr) 
X    acptr = acptr->next;
X  if (acptr) {
X    acptr->next = sptr->next;
X  } else {
X    debug(DEBUG_FATAL, "List corrupted");
X    restart();
X  }
X  if (sptr->away)
X    free(sptr->away);
X  free(sptr);
X}
X
Xm_error(cptr, sptr, sender, para1, para2, para3, para4)
Xstruct Client *cptr, *sptr;
Xchar *sender, *para1, *para2, *para3, *para4;
X{
X  debug(DEBUG_ERROR,"Received ERROR message from %s: %s %s %s %s",
X	sptr->nickname, para1, para2, para3, para4);
X  return(0);
X}
X
Xm_help(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  int i;
X  for (i = 0; msgtab[i].cmd; i++)
X    sendto_one(sptr,"PRIVMSG %s :%s",sptr->nickname,msgtab[i].cmd);
X  return(0);
X}
X
Xm_whoreply(cptr, sptr, sender, para1, para2, para3, para4, para5, para6)
Xstruct Client *cptr, *sptr;
Xchar *sender, *para1, *para2, *para3, *para4, *para5, *para6;
X{
X  m_error(cptr, sptr, sender, "Whoreply", para1, para2, para3);
X}
X
Xm_restart(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  if (sptr->status == STAT_OPER)
X    restart();
X}
X
Xm_die(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  if (sptr->status == STAT_OPER)
X    exit(-1);
X}
X
Xdowelcome(sptr)
Xstruct Client *sptr;
X{
X  struct Client *acptr;
X  int s_count = 0, c_count = 0, u_count = 0;
X  sendto_one(sptr,"MSG :%s%s",welcome1,version);
X  acptr = client;
X  while (acptr) {
X    switch (acptr->status) {
X    case STAT_SERVER:
X    case STAT_ME:
X      s_count++;
X      break;
X    case STAT_CLIENT:
X    case STAT_OPER:
X      c_count++;
X      break;
X    default:
X      u_count++;
X      break;
X    }
X    acptr = acptr->next;
X  }
X  sendto_one(sptr,"MSG :There are %d users on %d servers",
X	     c_count, s_count);
X  if (u_count > 0)
X    sendto_one(sptr,"MSG :And %d yet unknown connections", u_count);
X}
X  
X  
X/***********************************************************************
X * m_away() - Added 14 Dec 1988 by jto. 
X *            Not currently really working, I don't like this
X *            call at all...
X ***********************************************************************/
X
Xm_away(cptr, sptr, sender, msg)
Xstruct Client *cptr, *sptr;
Xchar *msg;
X{
X  if (sptr->status != STAT_CLIENT && sptr->status != STAT_SERVICE &&
X      sptr->status != STAT_OPER) {
X    sendto_one(sptr,"ERROR :You must register yourself first");
X    return(-1);
X  }
X  if (sptr->away) {
X    free(sptr->away);
X    sptr->away = NULL;
X  }
X  if (msg && *msg) {
X    sptr->away = (char *) malloc((unsigned int) (strlen(msg)+1));
X    if (sptr->away == NULL)
X      sendto_one(sptr,"ERROR :Randomness of the world has proven its power!");
X    else {
X      sendto_one(sptr,"PRIVMSG %s :You have marked as being away",
X	         sptr->nickname);
X      strcpy(sptr->away, msg);
X    }
X  } else {
X    sendto_one(sptr,"PRIVMSG %s :You are no longer marked as being away",
X               sptr->nickname);
X  }
X  return(0);
X}
X
X/***********************************************************************
X * m_connect() - Added by Jto 11 Feb 1989
X ***********************************************************************/
X
Xm_connect(cptr, sptr, sender, host, portstr)
Xstruct Client *cptr, *sptr;
Xchar *sender, *host, *portstr;
X{
X  int port, tmpport;
X  struct Confitem *aconf;
X  if (sptr->status != STAT_SERVER && sptr->status != STAT_OPER) {
X    sendto_one(cptr,"ERROR :CONNECT: Privileged command");
X    return(-1);
X  }
X  if (!host || *host == '\0' || !portstr || *portstr == '\0') {
X    sendto_one(cptr,"ERROR :CONNECT: Syntax error");
X    return(-1);
X  }
X  if ((port = atoi(portstr)) <= 0) {
X    sendto_one(cptr,"ERROR :CONNECT: Illegal portnumber");
X    return(-1);
X  }
X  aconf = conf;
X  while (aconf) {
X    if (aconf->status == CONF_CONNECT_SERVER &&
X	strcmp(aconf->host, host) == 0) {
X      tmpport = aconf->port;
X      aconf->port = port;
X      connect_server(aconf);
X      aconf->port = tmpport;
X      break;
X    }
X    aconf = aconf->next;
X  }
X  return(0);
X}
X
Xm_ping(cptr, sptr, sender, origin, destination)
Xstruct Client *cptr, *sptr;
Xchar *sender, *origin, *destination;
X{
X  struct Client *acptr;
X  if (origin == NULL || *origin == '\0') {
X    sendto_one(sptr,"ERROR :No origin specified.");
X    return(-1);
X  }
X  if (destination && *destination && strcmp(destination, myhostname)) {
X    if (acptr = find_server(destination,NULL)) {
X      sendto_one(acptr,"PING %s %s", origin, destination);
X      return(0);
X    } else {
X      sendto_one(sptr,"ERROR :No such host found");
X      return(-1);
X    }
X  } else {
X    sendto_one(sptr,"PONG %s %s", 
X	       (destination) ? destination : myhostname, origin);
X    return(0);
X  }
X}
X
Xm_pong(cptr, sptr, sender, origin, destination)
Xstruct Client *cptr, *sptr;
Xchar *sender, *origin, *destination;
X{
X  struct Client *acptr;
X  if (origin == NULL || *origin == '\0') {
X    sendto_one(sptr,"ERROR :No origin specified.");
X    return(-1);
X  }
X  cptr->flags &= ~FLAGS_PINGSENT;
X  sptr->flags &= ~FLAGS_PINGSENT;
X  if (destination && *destination && strcmp(destination, myhostname)) {
X    if (acptr = find_server(destination,NULL)) {
X      sendto_one(acptr,"PONG %s %s", origin, destination);
X      return(0);
X    } else {
X      sendto_one(sptr,"ERROR :No such host found");
X      return(-1);
X    }
X  } else {
X    debug(DEBUG_NOTICE, "PONG: %s %s", origin, destination);
X    return(0);
X  }
X}
X
X/**************************************************************************
X * m_oper() added Sat, 4 March 1989
X **************************************************************************/
X
Xm_oper(cptr, sptr, sender, name, password)
Xstruct Client *cptr, *sptr;
Xchar *sender, *name, *password;
X{
X  struct Confitem *aconf;
X  if (sptr->status != STAT_CLIENT || 
X      (name == NULL || *name == '\0' || password == NULL ||
X      *password == '\0') && cptr == sptr ) {
X    sendto_one(sptr, "ERROR :Dave, don't do that...");
X    return(0);
X  }
X  if (cptr->status == STAT_SERVER) {
X    sptr->status = STAT_OPER;
X    sendto_serv_butone(cptr, ":%s OPER", sptr->nickname);
X    return(0);
X  }
X  if ((aconf = find_conf(cptr->sockhost, NULL, name, CONF_OPERATOR)) 
X      == (struct Confitem *) 0) {
X    sendto_one(sptr, "ERROR :Only few of mere mortals may try to %s",
X	       "enter twilight zone");
X    return(0);
X  } 
X  if (aconf->status == CONF_OPERATOR &&
X      strcmp(password, aconf->passwd) == 0) {
X    sendto_one(sptr, "MSG :Good afternoon, gentleman. %s",
X	       "I am a HAL 9000 computer.");
X    sptr->status = STAT_OPER;
X    sendto_serv_butone(cptr, ":%s OPER", sptr->nickname);
X  } else {
X    sendto_one(sptr, "ERROR :Only real wizards do know the %s",
X	       "spells to open the gates of paradise");
X    return(0);
X  }
X  return(0);
X}
X
X/***************************************************************************
X * m_pass() - Added Sat, 4 March 1989
X ***************************************************************************/
X
Xm_pass(cptr, sptr, sender, password)
Xstruct Client *cptr, *sptr;
Xchar *sender, *password;
X{
X  if ((password == NULL) || (*password == '\0')) {
X    sendto_one(cptr,"ERROR :No password is not good password");
X    return(0);
X  }
X  if (sptr != cptr || (cptr->status != STAT_UNKNOWN &&
X                       cptr->status != STAT_HANDSHAKE)) {
X    sendto_one(cptr,"ERROR :Trying to unlock the door twice, eh ?");
X    return(0);
X  }
X  strncpy(cptr->passwd, password, PASSWDLEN);
X  cptr->passwd[PASSWDLEN] = '\0';
X  return(0);
X}
X
Xm_wall(cptr, sptr, sender, message)
Xstruct Client *cptr, *sptr;
Xchar *sender, *message;
X{
X  if (sptr->status != STAT_OPER) {
X    sendto_one(sptr,"ERROR :Only real wizards know the correct spells to %s",
X	       "open this gate");
X    return(0);
X  }
X  if (sender && *sender) {
X    if (cptr == sptr)
X      sendto_all_butone(NULL, ":%s WALL :%s", sender, message);
X    else
X      sendto_all_butone(cptr, ":%s WALL :%s", sender, message);
X  }
X  else if (cptr == sptr)
X    sendto_all_butone(NULL, ":%s WALL :%s", sptr->nickname, message);
X  else
X    sendto_all_butone(cptr, ":%s WALL :%s", sptr->nickname, message);
X  return(0);
X}
X
X/**************************************************************************
X * time() - Command added 23 March 1989
X **************************************************************************/
X
Xm_time(cptr, sptr, sender, destination)
Xstruct Client *cptr, *sptr;
Xchar *sender, *destination;
X{
X  struct Client *acptr;
X  if (destination && *destination && strcmp(destination, myhostname)) {
X    if (acptr = find_server(destination,NULL)) {
X      sendto_one(acptr,":%s TIME %s", sptr->nickname, destination);
X      return(0);
X    } else {
X      sendto_one(sptr,"ERROR :No such host found");
X      return(-1);
X    }
X  } else {
X    sendto_one(sptr,"PRIVMSG %s :%s (%s)", sptr->nickname, date(), myhostname);
X    return(0);
X  }
X}
X
X/************************************************************************
X * m_rehash() - Added by Jto 20 Apr 1989
X ************************************************************************/
X
Xm_rehash(cptr, sptr)
Xstruct Client *cptr, *sptr;
X{
X  if (sptr->status != STAT_OPER) {
X    sendto_one(sptr,"ERROR :Use the force, Luke !");
X    return(-1);
X  }
X  sendto_one(sptr,"PRIVMSG %s :Rereading irc.conf -file...",sptr->nickname);
X  rehash();
X}
X
X/************************************************************************
X * m_names() - Added by Jto 27 Apr 1989
X ************************************************************************/
X
Xm_names(cptr, sptr, sender, para)
Xstruct Client *cptr, *sptr;
Xchar *para, *sender;
X{ 
X  struct Channel *chptr = channel;
X  struct Client *c2ptr;
X  int idx, flag;
X
X  while (chptr) {
X    if (para == NULL || *para == '\0' ||
X	chan_match(chptr, chan_conv(para))) {
X      if (!chan_isprivate(chptr) || chan_match(chptr, sptr->channel)) {
X	c2ptr = client;
X	if (chan_isprivate(chptr))
X	  sprintf(buf, "* %d ", chptr->channo);
X	else
X	  sprintf(buf, "= %d ", chptr->channo);
X	idx = strlen(buf);
X	flag = 0;
X	while (c2ptr) {
X	  if ((c2ptr->status == STAT_OPER || c2ptr->status == STAT_CLIENT) &&
X	      chan_match(chptr, c2ptr->channel)) {
X	    strncat(buf, c2ptr->nickname, NICKLEN);
X	    idx += strlen(c2ptr->nickname) + 1;
X	    flag = 1;
X	    strcat(buf," ");
X	    if (idx + NICKLEN > BUFSIZE - 2) {
X	      sendto_one(sptr, "NAMREPLY %s", buf);
X	      if (chan_isprivate(channel))
X		sprintf(buf, "* %d ", chptr->channo);
X	      else
X		sprintf(buf, "= %d ", chptr->channo);
X	      idx = strlen(buf);
X	      flag = 0;
X	    }
X	  }
X	  c2ptr = c2ptr->next;
X	}
X	if (flag)
X	  sendto_one(sptr, "NAMREPLY %s", buf);
X      }
X    }
X    chptr = chptr->nextch;
X  }
X
X  if (para != NULL && *para)
X    return(1);
X  strcpy(buf, "* * ");
X  idx = strlen(buf);
X  c2ptr = client;
X  flag = 0;
X  while (c2ptr) {
X    if ((c2ptr->status == STAT_OPER || c2ptr->status == STAT_CLIENT) &&
X	((c2ptr->channel > 999 && (sptr->channel != c2ptr->channel)) ||
X	c2ptr->channel == 0)) {
X      strncat(buf, c2ptr->nickname, NICKLEN);
X      idx += strlen(c2ptr->nickname) + 1;
X      strcat(buf," ");
X      flag = 1;
X      if (idx + NICKLEN > BUFSIZE - 2) {
X	sendto_one(sptr, "NAMREPLY %s", buf);
X	strcpy(buf, "* * ");
X	idx = strlen(buf);
X	flag = 0;
X      }
X    }
X    c2ptr = c2ptr->next;
X  }
X  if (flag)
X    sendto_one(sptr, "NAMREPLY %s", buf);
X  return(1);
X}
X
Xm_namreply(cptr, sptr, sender, para1, para2, para3, para4, para5, para6)
Xstruct Client *cptr, *sptr;
SHAR_EOF
echo "End of part 5"
echo "File s_msg.c is continued in part 6"
echo "6" > s2_seq_.tmp
exit 0



More information about the Alt.sources mailing list