aboutsummaryrefslogtreecommitdiff
path: root/irc
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2020-05-25 20:09:04 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2020-05-25 20:09:04 +0200
commit4440a86cfa359b8e40a484a2cd46d33db5455d8a (patch)
treef5c0c59aebf0058ae97e7ef8b5fb8017f459a05a /irc
downloadircd-4440a86cfa359b8e40a484a2cd46d33db5455d8a.tar.gz
Initial
Diffstat (limited to 'irc')
-rw-r--r--irc/c_bsd.c149
-rw-r--r--irc/c_bsd_ext.h39
-rw-r--r--irc/c_conf.c95
-rw-r--r--irc/c_conf_ext.h38
-rw-r--r--irc/c_debug.c61
-rw-r--r--irc/c_debug_ext.h49
-rw-r--r--irc/c_defines.h35
-rw-r--r--irc/c_externs.h44
-rw-r--r--irc/c_msg.c407
-rw-r--r--irc/c_msg_ext.h76
-rw-r--r--irc/c_numeric.c413
-rw-r--r--irc/c_numeric_ext.h39
-rw-r--r--irc/c_version.c46
-rw-r--r--irc/c_version_ext.h32
-rw-r--r--irc/ctcp.c50
-rw-r--r--irc/ctcp_ext.h33
-rw-r--r--irc/edit.c411
-rw-r--r--irc/edit_ext.h55
-rw-r--r--irc/help.c228
-rw-r--r--irc/help_def.h23
-rw-r--r--irc/help_ext.h40
-rw-r--r--irc/ignore.c141
-rw-r--r--irc/ignore_ext.h43
-rw-r--r--irc/irc.c908
-rw-r--r--irc/irc_def.h29
-rw-r--r--irc/irc_ext.h84
-rw-r--r--irc/screen.c287
-rw-r--r--irc/screen_ext.h56
-rw-r--r--irc/str.c84
-rw-r--r--irc/str_ext.h39
-rw-r--r--irc/swear.c216
-rw-r--r--irc/swear_ext.h53
32 files changed, 4303 insertions, 0 deletions
diff --git a/irc/c_bsd.c b/irc/c_bsd.c
new file mode 100644
index 0000000..25bbd83
--- /dev/null
+++ b/irc/c_bsd.c
@@ -0,0 +1,149 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_bsd.c
+ * Copyright (C) 1990, Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_bsd.c,v 1.5 1998/12/13 00:02:35 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_BSD_C
+#include "c_externs.h"
+#undef C_BSD_C
+
+#ifdef AUTOMATON
+#ifdef DOCURSES
+#undef DOCURSES
+#endif
+#ifdef DOTERMCAP
+#undef DOTERMCAP
+#endif
+#endif /* AUTOMATON */
+
+#define STDINBUFSIZE (0x80)
+
+int client_init(host, portnum, cptr)
+char *host;
+int portnum;
+aClient *cptr;
+{
+ int sock;
+ static struct hostent *hp;
+ static struct SOCKADDR_IN server;
+
+ sock = socket(AFINET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ perror("opening stream socket");
+ exit(1);
+ }
+ server.SIN_FAMILY = AFINET;
+
+ if (isdigit(*host))
+#ifdef INET6
+ {
+ if(!inet_pton(AF_INET6, host, server.sin6_addr.s6_addr))
+ bcopy(minus_one, server.sin6_addr.s6_addr, IN6ADDRSZ);
+ }
+#else
+ server.sin_addr.s_addr = inetaddr(host);
+#endif
+ else {
+#ifdef INET6
+ res_init();
+ _res.options|=RES_USE_INET6;
+#endif
+ hp = gethostbyname(host);
+ if (hp == 0) {
+ fprintf(stderr, "%s: unknown host\n", host);
+ exit(2);
+ }
+ bcopy(hp->h_addr, (char *)&server.SIN_ADDR, hp->h_length);
+ }
+ server.SIN_PORT = htons(portnum);
+ if (connect(sock, (SAP)&server, sizeof(server)) == -1) {
+ perror("irc");
+ exit(1);
+ }
+
+ cptr->acpt = cptr;
+ cptr->port = server.SIN_PORT;
+#ifdef INET6
+ bcopy(server.sin6_addr.s6_addr, cptr->ip.s6_addr, IN6ADDRSZ);
+#else
+ cptr->ip.s_addr = server.sin_addr.s_addr;
+#endif
+ return(sock);
+}
+
+void client_loop(sock)
+int sock;
+{
+ int i = 0, size, pos;
+ char apubuf[STDINBUFSIZE+1];
+ fd_set ready;
+
+ do {
+ if (sock < 0 || QuitFlag)
+ return;
+ FD_ZERO(&ready);
+ FD_SET(sock, &ready);
+ FD_SET(0, &ready);
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM)
+ move(LINES-1,i); refresh();
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ tcap_move (-1, i);
+#endif
+ if (select(32, (SELECT_FDSET_TYPE *)&ready, 0, 0, NULL) < 0) {
+/* perror("select"); */
+ continue;
+ }
+ if (FD_ISSET(sock, &ready)) {
+ if ((size = read(sock, apubuf, STDINBUFSIZE)) < 0)
+ perror("receiving stream packet");
+ if (size <= 0) {
+ close(sock);
+ return;
+ }
+ dopacket(&me, apubuf, size);
+ }
+#ifndef AUTOMATON
+ if (FD_ISSET(0, &ready)) {
+ if ((size = read(0, apubuf, STDINBUFSIZE)) < 0) {
+ putline("FATAL ERROR: End of stdin file !");
+ return;
+ }
+ for (pos = 0; pos < size; pos++) {
+ i=do_char(apubuf[pos]);
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM)
+ move(LINES-1, i);
+#endif
+#ifdef DOTERMCAP
+ if (termtype == CURSES_TERM)
+ tcap_move(-1, i);
+#endif
+ }
+ }
+#endif /* AUTOMATON */
+ } while (1);
+}
diff --git a/irc/c_bsd_ext.h b/irc/c_bsd_ext.h
new file mode 100644
index 0000000..fdd3500
--- /dev/null
+++ b/irc/c_bsd_ext.h
@@ -0,0 +1,39 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_bsd_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_bsd.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_BSD_C
+extern char c_bsd_id[];
+#endif /* C_BSD_C */
+
+/* External definitions for global functions.
+ */
+#ifndef C_BSD_C
+#define EXTERN extern
+#else /* C_BSD_C */
+#define EXTERN
+#endif /* C_BSD_C */
+EXTERN int client_init __P((char *host, int portnum, aClient *cptr));
+EXTERN void client_loop __P((int sock));
+#undef EXTERN
diff --git a/irc/c_conf.c b/irc/c_conf.c
new file mode 100644
index 0000000..ee980f2
--- /dev/null
+++ b/irc/c_conf.c
@@ -0,0 +1,95 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_conf.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_conf.c,v 1.3 1999/02/21 00:33:45 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_CONF_C
+#include "c_externs.h"
+#undef C_CONF_C
+
+initconf(host, passwd, myname, port)
+char *host, *passwd, *myname;
+int *port;
+{
+ FILE *fd;
+ char line[256], *tmp;
+
+ if ((fd = fopen(IRCDCONF_PATH, "r")) == NULL)
+ return /* (-1) */ ;
+ while (fgets(line,255,fd)) {
+ if (line[0] == '#' || line[0] == '\n' ||
+ line[0] == ' ' || line[0] == '\t')
+ continue;
+ switch (*getfield(line))
+ {
+ case 'C': /* Server where I should try to connect */
+ case 'c': /* in case of link failures */
+ case 'I': /* Just plain normal irc client trying */
+ case 'i': /* to connect me */
+ case 'N': /* Server where I should NOT try to */
+ case 'n': /* connect in case of link failures */
+ /* but which tries to connect ME */
+ case 'O': /* Operator. Line should contain at least */
+ case 'o': /* password and host where connection is */
+ /* allowed from */
+ case 'M': /* Me. Host field is name used for this host */
+ case 'm': /* and port number is the number of the port */
+ case 'a':
+ case 'A':
+ case 'k':
+ case 'K':
+ case 'q':
+ case 'Q':
+ case 'l':
+ case 'L':
+ case 'y':
+ case 'Y':
+ case 'h':
+ case 'H':
+ case 'p':
+ case 'P':
+ break;
+ case 'U': /* Uphost, ie. host where client reading */
+ case 'u': /* this should connect. */
+ if (!(tmp = getfield(NULL)))
+ break;
+ strncpyzt(host, tmp, HOSTLEN);
+ if (!(tmp = getfield(NULL)))
+ break;
+ strncpyzt(passwd, tmp, PASSWDLEN);
+ if (!(tmp = getfield(NULL)))
+ break;
+ strncpyzt(myname, tmp, HOSTLEN);
+ if (!(tmp = getfield(NULL)))
+ break;
+ if ((*port = atoi(tmp)) == 0)
+ debug(DEBUG_ERROR,
+ "Error in config file, bad port field");
+ break;
+ default:
+/* debug(DEBUG_ERROR, "Error in config file: %s", line); */
+ break;
+ }
+ }
+}
diff --git a/irc/c_conf_ext.h b/irc/c_conf_ext.h
new file mode 100644
index 0000000..a46e39b
--- /dev/null
+++ b/irc/c_conf_ext.h
@@ -0,0 +1,38 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_conf_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_conf.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_CONF_C
+extern char conf_id[];
+#endif /* C_CONF_C */
+
+/* External definitions for global functions.
+ */
+#ifndef C_CONF_C
+#define EXTERN extern
+#else /* C_CONF_C */
+#define EXTERN
+#endif /* C_CONF_C */
+EXTERN initconf __P((char *host, char *passwd, char *myname, int *port));
+#undef EXTERN
diff --git a/irc/c_debug.c b/irc/c_debug.c
new file mode 100644
index 0000000..4cf9156
--- /dev/null
+++ b/irc/c_debug.c
@@ -0,0 +1,61 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_debug.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_debug.c,v 1.3 1998/05/12 16:55:49 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_DEBUG_C
+#include "c_externs.h"
+#undef C_DEBUG_C
+
+struct stats ircst, *ircstp = &ircst;
+
+#ifdef DEBUGMODE
+#if ! USE_STDARG
+void debug(level, form, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
+int level;
+char *form, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10;
+#else
+void debug(int level, char *form, ...)
+#endif
+{
+ if (debuglevel >= 0)
+ if (level <= debuglevel) {
+ char buf[512];
+#if ! USE_STDARG
+ (void)sprintf(buf, form,
+ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+#else
+ va_list va;
+ va_start(va, form);
+ (void)vsprintf(buf, form, va);
+ va_end(va);
+#endif
+ putline(buf);
+ }
+}
+#else /* do nothing */
+void debug()
+{
+}
+#endif
diff --git a/irc/c_debug_ext.h b/irc/c_debug_ext.h
new file mode 100644
index 0000000..bb7ef4a
--- /dev/null
+++ b/irc/c_debug_ext.h
@@ -0,0 +1,49 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_debug_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_debug.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_DEBUG_C
+extern char debug_id[];
+extern struct stats ircst, *ircstp;
+#endif /* C_DEBUG_C */
+
+/* External definitions for global functions.
+ */
+#ifndef C_DEBUG_C
+#define EXTERN extern
+#else /* C_DEBUG_C */
+#define EXTERN
+#endif /* C_DEBUG_C */
+#ifdef DEBUGMODE
+#if ! USE_STDARG
+EXTERN void debug __P((int level, char *form, char *p1, char *p2, char *p3,
+ char *p4, char *p5, char *p6, char *p7, char *p8,
+ char *p9, char *p10));
+#else
+EXTERN void debug __P((int level, char *form, ...));
+#endif
+#else
+EXTERN void debug();
+#endif
+#undef EXTERN
diff --git a/irc/c_defines.h b/irc/c_defines.h
new file mode 100644
index 0000000..f0982a0
--- /dev/null
+++ b/irc/c_defines.h
@@ -0,0 +1,35 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_defines.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file includes all files defining constants, macros and types
+ definitions used by the IRC client.
+ */
+
+#include "config.h"
+#include "patchlevel.h"
+
+#include "common_def.h"
+#include "dbuf_def.h"
+#include "class_def.h"
+#include "struct_def.h"
+#include "msg_def.h"
+#include "numeric_def.h"
+#include "support_def.h"
+#include "irc_def.h"
+#include "help_def.h"
diff --git a/irc/c_externs.h b/irc/c_externs.h
new file mode 100644
index 0000000..269efc8
--- /dev/null
+++ b/irc/c_externs.h
@@ -0,0 +1,44 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_externs.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file includes all *_ext.h files containing external declarations
+ * for the IRC client.
+ */
+
+#include "bsd_ext.h"
+#include "c_bsd_ext.h"
+#include "c_conf_ext.h"
+#include "c_debug_ext.h"
+#include "c_msg_ext.h"
+#include "c_numeric_ext.h"
+#include "c_version_ext.h"
+#include "ctcp_ext.h"
+#include "dbuf_ext.h"
+#include "edit_ext.h"
+#include "help_ext.h"
+#include "ignore_ext.h"
+#include "irc_ext.h"
+#include "match_ext.h"
+#include "packet_ext.h"
+#include "parse_ext.h"
+#include "screen_ext.h"
+#include "send_ext.h"
+#include "str_ext.h"
+#include "support_ext.h"
+#include "swear_ext.h"
diff --git a/irc/c_msg.c b/irc/c_msg.c
new file mode 100644
index 0000000..b571b7d
--- /dev/null
+++ b/irc/c_msg.c
@@ -0,0 +1,407 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_msg.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_msg.c,v 1.3 1999/02/21 00:14:59 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_MSG_C
+#include "c_externs.h"
+#undef C_MSG_C
+
+char mybuf[513];
+
+void m_die() {
+ exit(-1);
+}
+
+int m_mode(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ strcpy(mybuf, "*** Mode change ");
+ while (parc--) {
+ strcat(mybuf, parv[0]);
+ strcat(mybuf, " ");
+ parv++;
+ }
+ putline(mybuf);
+ return 0;
+}
+
+int m_wall(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf, "*** #%s# %s", parv[0], parv[1]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_wallops(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf, "*** =%s= %s %s", parv[0], parv[1],
+ BadPtr(parv[2]) ? "" : parv[2]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_ping(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ if (parv[2] && *parv[2])
+ sendto_one(client, "PONG %s@%s %s", client->user->username,
+ client->sockhost, parv[2]);
+ else
+ sendto_one(client, "PONG %s@%s", client->user->username, client->sockhost);
+ return 0;
+}
+
+int m_pong(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf, "*** Received PONG message: %s %s from %s",
+ parv[1], (parv[2]) ? parv[2] : "", parv[0]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_nick(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Change: %s is now known as %s", parv[0], parv[1]);
+ if (!mycmp(me.name, parv[0])) {
+ strcpy(me.name, parv[1]);
+ write_statusline();
+ }
+ putline(mybuf);
+#ifdef AUTOMATON
+ a_nick(parv[0], parv[1]);
+#endif
+ return 0;
+}
+
+void m_away(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** %s is away: \"%s\"",parv[0], parv[1]);
+ putline(mybuf);
+}
+
+int m_server(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** New server: %s", parv[1]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_topic(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf, "*** %s changed the topic on %s to: %s",
+ parv[0], parv[1], parv[2]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_join(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ char *tmp = index(parv[1], '\007'); /* Find o/v mode in 2.9 */
+
+ if (tmp)
+ *tmp = ' ';
+ sprintf(mybuf,"*** %s <%s> joined channel %s",
+ parv[0], userhost, parv[1]);
+ putline(mybuf);
+ return 0;
+}
+
+int m_part(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Change: %s has left channel %s (%s)",
+ parv[0], parv[1], BadPtr(parv[2]) ? parv[1] : parv[2]);
+ putline(mybuf);
+ return 0;
+}
+
+void m_version(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Version: %s", parv[1]);
+ putline(mybuf);
+}
+
+void m_bye()
+{
+#if defined(DOCURSES) && !defined(AUTOMATON) && !defined(VMSP)
+ echo();
+ nocrmode();
+ clear();
+ refresh();
+#endif
+ exit(-1);
+}
+
+int m_quit(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Signoff: %s (%s)", parv[0], parv[1]);
+ putline(mybuf);
+#ifdef AUTOMATON
+ a_quit(sender);
+#endif
+ return 0;
+}
+
+int m_kill(cptr, sptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Kill: %s (%s)", parv[0], parv[2]);
+ putline(mybuf);
+ return 0;
+}
+
+void m_info(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Info: %s", parv[1]);
+ putline(mybuf);
+}
+
+void m_squit(sptr, cptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Server %s has died. Snif.", parv[1]);
+ putline(mybuf);
+}
+
+void m_newwhoreply(channel, username, host, nickname, away, realname)
+char *channel, *username, *host, *nickname, *away, *realname;
+{
+ /* ...dirty hack, just assume all parameters present.. --msa */
+
+ if (*away == 'S')
+ sprintf(mybuf, " %-13s %s %-42s %s",
+ "Nickname", "Chan", "Name", "<User@Host>");
+ else {
+ int i;
+ char uh[USERLEN + HOSTLEN + 1];
+ if (!realname)
+ realname = "";
+ if (!username)
+ username = "";
+ i = 50-strlen(realname)-strlen(username);
+
+ if (channel[0] == '*')
+ channel = "";
+
+ if (strlen(host) > (size_t) i) /* kludge --argv */
+ host += strlen(host) - (size_t) i;
+
+ sprintf(uh, "%s@%s", username, host);
+
+ sprintf(mybuf, "%c %s%s %*s %s %*s",
+ away[0], nickname, away+1,
+ (int)(21-strlen(nickname)-strlen(away)), channel,
+ realname,
+ (int)(53-strlen(realname)), uh);
+ }
+}
+
+void m_newnamreply(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ if (parv[2]) {
+ switch (parv[2][0]) {
+ case '*':
+ sprintf(mybuf,"Prv: %-3s %s", parv[3], parv[4]);
+ break;
+ case '=':
+ sprintf(mybuf,"Pub: %-3s %s", parv[3], parv[4]);
+ break;
+ case '@':
+ sprintf(mybuf,"Sec: %-3s %s", parv[3], parv[4]);
+ break;
+ default:
+ sprintf(mybuf,"???: %s %s %s", parv[3], parv[4], parv[5]);
+ break;
+ }
+ } else
+ sprintf(mybuf, "*** Internal Error: namreply");
+}
+
+void m_linreply(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Server: %s (%s) %s", parv[2], parv[3], parv[4]);
+}
+
+int m_private(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ anIgnore *iptr;
+
+ iptr = find_ignore(parv[0], (anIgnore *)NULL, userhost);
+ if ((iptr != (anIgnore *)NULL) &&
+ ((iptr->flags == IGNORE_TOTAL) ||
+ (IsChannelName(parv[1]) && (iptr->flags & IGNORE_PUBLIC)) ||
+ (!IsChannelName(parv[1]) && (iptr->flags & IGNORE_PRIVATE))))
+ return 0;
+ check_ctcp(sptr, cptr, parc, parv);
+
+ if (parv[0] && *parv[0]) {
+#ifdef AUTOMATON
+ a_privmsg(sender, parv[2]);
+#else
+ if (((*parv[1] >= '0') && (*parv[1] <= '9')) ||
+ (*parv[1] == '-') || (*parv[1] == '+') ||
+ IsChannelName(parv[1]) || (*parv[1] == '$')) {
+ sprintf(mybuf,"<%s:%s> %s", parv[0], parv[1], parv[2]);
+ } else {
+ sprintf(mybuf,"*%s* %s", parv[0], parv[2]);
+ last_to_me(parv[0]);
+ }
+ putline(mybuf);
+#endif
+ } else
+ putline(parv[2]); /* parv[2] and no parv[0] ?! - avalon */
+ return 0;
+}
+
+
+int m_kick(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** %s kicked %s off channel %s (%s)",
+ (parv[0]) ? parv[0] : "*Unknown*",
+ (parv[2]) ? parv[2] : "*Unknown*",
+ (parv[1]) ? parv[1] : "*Unknown*",
+ parv[3]);
+ if (!mycmp(me.name, parv[2])) {
+ free(querychannel);
+ querychannel = (char *)malloc(strlen(me.name) + 1);
+ strcpy(querychannel, me.name); /* Kludge? */
+ }
+ putline(mybuf);
+ return 0;
+}
+
+int m_notice(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ anIgnore *iptr;
+
+ iptr = find_ignore(parv[0], (anIgnore *)NULL, userhost);
+ if ((iptr != (anIgnore *)NULL) &&
+ ((iptr->flags == IGNORE_TOTAL) ||
+ (IsChannelName(parv[1]) && (iptr->flags & IGNORE_PUBLIC)) ||
+ (!IsChannelName(parv[1]) && (iptr->flags & IGNORE_PRIVATE))))
+ return 0;
+
+ if (parv[0] && parv[0][0] && parv[1]) {
+ if ((*parv[1] >= '0' && *parv[1] <= '9') ||
+ *parv[1] == '-' || IsChannelName(parv[1]) ||
+ *parv[1] == '$' || *parv[1] == '+')
+ sprintf(mybuf,"(%s:%s) %s",parv[0],parv[1],parv[2]);
+ else if (index(userhost, '@')) /* user */
+ sprintf(mybuf, "-%s- %s", parv[0], parv[2]);
+ else /* service */
+ sprintf(mybuf, "-%s@%s- %s",
+ parv[0], userhost, parv[2]);
+ putline(mybuf);
+ } else
+ putline(parv[2]);
+ return 0;
+}
+
+int m_invite(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ anIgnore *iptr;
+ if ((iptr = find_ignore(parv[0], (anIgnore *)NULL, userhost)) &&
+ (iptr->flags & IGNORE_PRIVATE))
+ return 0;
+#ifdef AUTOMATON
+ a_invite(parv[0], parv[2]);
+#else
+ sprintf(mybuf,"*** %s Invites you to channel %s", parv[0], parv[2]);
+ putline(mybuf);
+#endif
+ return 0;
+}
+
+int m_error(sptr, cptr, parc, parv)
+aClient *sptr, *cptr;
+int parc;
+char *parv[];
+{
+ sprintf(mybuf,"*** Error: %s %s", parv[1], (parv[2]) ? parv[2] : "");
+ putline(mybuf);
+ return 0;
+}
+
diff --git a/irc/c_msg_ext.h b/irc/c_msg_ext.h
new file mode 100644
index 0000000..8c5949d
--- /dev/null
+++ b/irc/c_msg_ext.h
@@ -0,0 +1,76 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_msg_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_msg.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_MSG_C
+#ifndef lint
+extern char c_msg_id[];
+#endif
+extern char mybuf[];
+#endif /* C_MSG_C */
+
+/* External definitions for global functions.
+ */
+#ifndef C_MSG_C
+#define EXTERN extern
+#else /* C_MSG_C */
+#define EXTERN
+#endif /* C_MSG_C */
+EXTERN void m_die();
+EXTERN int m_mode __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_wall __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_wallops __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_ping __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_pong __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_nick __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN void m_away __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_server __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_topic __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_join __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_part __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN void m_version __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN void m_bye();
+EXTERN int m_quit __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_kill __P((aClient *cptr, aClient *sptr, int parc, char *parv[]));
+EXTERN void m_info __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN void m_squit __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN void m_newwhoreply __P((char *channel, char *username, char *host,
+ char *nickname, char *away, char *realname));
+EXTERN void m_newnamreply __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN void m_linreply __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_private __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_kick __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+EXTERN int m_notice __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_invite __P((aClient *sptr, aClient *cptr, int parc,
+ char *parv[]));
+EXTERN int m_error __P((aClient *sptr, aClient *cptr, int parc, char *parv[]));
+#undef EXTERN
diff --git a/irc/c_numeric.c b/irc/c_numeric.c
new file mode 100644
index 0000000..f124a05
--- /dev/null
+++ b/irc/c_numeric.c
@@ -0,0 +1,413 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_numeric.c
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_numeric.c,v 1.3 1997/09/03 17:45:35 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_NUMERIC_C
+#include "c_externs.h"
+#undef C_NUMERIC_C
+
+/*
+** DoNumeric (replacement for the old do_numeric)
+**
+** parc number of arguments ('sender' counted as one!)
+** parv[0] pointer to 'sender' (may point to empty string) (not used)
+** parv[1]..parv[parc-1]
+** pointers to additional parameters, this is a NULL
+** terminated list (parv[parc] == NULL).
+*/
+
+int do_numeric(numeric, cptr, sptr, parc, parv)
+int numeric;
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+ {
+ char *tmp;
+ int i;
+ time_t l; /* ctime(&l) on STATS L */
+
+ /* ...make sure undefined parameters point to empty string */
+ for (i = parc; i < MAXPARA; parv[i++] = "");
+
+ switch (numeric)
+ {
+ case ERR_NOSUCHNICK:
+ sprintf(mybuf, "*** Error: %s: %s (%s)",
+ parv[0], parv[3], parv[2]);
+ sendto_one(&me, "WHOWAS %s 1", parv[2]);
+ break;
+ case ERR_WASNOSUCHNICK:
+ mybuf[0] = '\0';
+ break;
+ case ERR_NOSUCHSERVER:
+ sprintf(mybuf, "*** Error: %s: No such server (%s)",
+ parv[0], parv[2]);
+ break;
+ case ERR_NOSUCHCHANNEL:
+ sprintf(mybuf, "*** Error: %s: No such channel (%s)",
+ parv[0], parv[2]);
+ break;
+ case ERR_NOSUCHSERVICE:
+ sprintf(mybuf, "*** Error: %s: No such service (%s)",
+ parv[0], parv[2]);
+ break;
+ case ERR_TOOMANYCHANNELS:
+ sprintf(mybuf, "*** Error: %s: You have join max. channels",
+ parv[0]);
+ break;
+ case ERR_TOOMANYTARGETS:
+ sprintf(mybuf, "*** Error: %s: Too many targets given",
+ parv[0]);
+ break;
+ case ERR_NORECIPIENT:
+ sprintf(mybuf, "*** Error: %s: Message had no recipient",
+ parv[0]);
+ break;
+ case ERR_NOTEXTTOSEND:
+ sprintf(mybuf, "*** Error: %s: Empty messages cannot be sent",
+ parv[0]);
+ break;
+ case ERR_NOTOPLEVEL:
+ sprintf(mybuf, "*** Error: %s: No toplevel domainname given",
+ parv[0]);
+ break;
+ case ERR_WILDTOPLEVEL:
+ sprintf(mybuf, "*** Error: %s: Wildcard in toplevel name",
+ parv[0]);
+ break;
+ case ERR_UNKNOWNCOMMAND:
+ sprintf(mybuf, "*** Error: %s: Unknown command (%s)",
+ parv[0],parv[2]);
+ break;
+ case ERR_NONICKNAMEGIVEN:
+ sprintf(mybuf, "*** Error: %s: No nickname given", parv[0]);
+ break;
+ case ERR_ERRONEUSNICKNAME:
+ sprintf(mybuf,
+ "*** Error: %s: Some special characters cannot %s",
+ parv[0], "be used in nicknames");
+ break;
+ case ERR_NICKNAMEINUSE:
+ sprintf(mybuf,
+ "*** Error: %s: Nickname %s is already in use. %s",
+ parv[0], parv[2], "Please choose another.");
+ break;
+ case ERR_SERVICENAMEINUSE:
+ sprintf(mybuf, "*** Error: %s: Service %s is already in use.",
+ parv[0], parv[2]);
+ break;
+ case ERR_SERVICECONFUSED:
+ sprintf(mybuf, "Error: %s: Your service name is confused",
+ parv[0]);
+ break;
+ case ERR_USERNOTINCHANNEL:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "You have not joined any channel");
+ break;
+ case ERR_NOTONCHANNEL:
+ sprintf(mybuf, "*** Error: %s: %s %s",
+ parv[0], parv[3], parv[2]);
+ break;
+ case ERR_INVITEONLYCHAN:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ "Magic locks open only with an invitation key");
+ break;
+ case ERR_BANNEDFROMCHAN:
+ sprintf(mybuf,"*** Error: %s: %s %s",
+ parv[0], "You are banned from the channel", parv[2]);
+ break;
+ case ERR_NOTREGISTERED:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "You have not registered yourself yet");
+ break;
+ case ERR_NEEDMOREPARAMS:
+ sprintf(mybuf, "*** Error: %s: %s: %s", parv[0], parv[2],
+ (parv[3][0]) ? parv[3] : "Not enough parameters");
+ break;
+ case ERR_ALREADYREGISTRED:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] : "Identity problems, eh ?");
+ break;
+ case ERR_NOPERMFORHOST:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "Your host isn't among the privileged");
+ break;
+ case ERR_PASSWDMISMATCH:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] : "Incorrect password");
+ break;
+ case ERR_YOUREBANNEDCREEP:
+ sprintf(mybuf, "*** %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "You're banned from irc...");
+ break;
+ case ERR_YOUWILLBEBANNED:
+ sprintf(mybuf, "*** Warning: You will be banned in %d minutes",
+ atoi(parv[2]));
+ break;
+ case ERR_CHANNELISFULL:
+ sprintf(mybuf, "*** Error: %s: Channel %s is full",
+ parv[0], parv[2]);
+ break;
+ case ERR_CANNOTSENDTOCHAN:
+ sprintf(mybuf, "*** Error: Sending to channel is %s",
+ "forbidden from heathens");
+ break;
+ case ERR_NOPRIVILEGES:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "Only few and chosen are granted privileges. You're not one.");
+ break;
+ case ERR_NOOPERHOST:
+ sprintf(mybuf, "*** Error: %s: %s", parv[0],
+ (parv[2][0]) ? parv[2] :
+ "Only few of mere mortals may try to enter the twilight zone..");
+ break;
+ case ERR_UMODEUNKNOWNFLAG:
+ sprintf(mybuf, "*** Error: %s: Unknown User Mode Flag",
+ parv[0]);
+ break;
+ case ERR_USERSDONTMATCH:
+ sprintf(mybuf, "*** Error: %s: Can only change your own mode",
+ parv[0]);
+ break;
+ case RPL_AWAY:
+ sprintf(mybuf, "*** %s: %s is away: %s", parv[0],
+ (parv[2][0]) ? parv[2] : "*Unknown*",
+ (parv[3][0]) ? parv[3] : "*No message (strange)*");
+ break;
+ case RPL_USERHOST:
+ sprintf(mybuf, "*** USERHOST reply: %s", parv[2]);
+ break;
+ case RPL_ISON:
+ sprintf(mybuf, "*** ISON reply: %s", parv[2]);
+ break;
+ case RPL_WHOISUSER:
+ sprintf(mybuf, "*** %s is %s@%s (%s)",
+ parv[2], parv[3], parv[4], parv[6]);
+ break;
+ case RPL_WHOWASUSER:
+ sprintf(mybuf, "*** %s was %s@%s (%s)",
+ parv[2], parv[3], parv[4], parv[6]);
+ break;
+ case RPL_WHOISSERVER:
+ if (parc == 4)
+ sprintf(mybuf, "*** On irc via server %s (%s)",
+ parv[2], parv[3]);
+ else
+ sprintf(mybuf, "*** On irc via server %s (%s)",
+ parv[3], parv[4]);
+ break;
+ case RPL_WHOISOPERATOR:
+ sprintf(mybuf, "*** %s has a connection to the twilight zone",
+ parv[2]);
+ break;
+ case RPL_WHOISCHANOP:
+ sprintf(mybuf, "*** %s has been touched by magic forces",
+ parv[2]);
+ break;
+ case RPL_WHOISIDLE:
+ sprintf(mybuf, "*** %s %s %s",
+ parv[2], parv[3], parv[4]);
+ break;
+ case RPL_WHOISCHANNELS:
+ sprintf(mybuf, "*** On Channels: %s", parv[3]);
+ break;
+ case RPL_LISTSTART:
+ sprintf(mybuf, "*** Chn Users Name");
+ break;
+ case RPL_LIST:
+ sprintf(mybuf, "*** %3s %5s %s",
+ (parv[2][0] == '*') ? "Prv" : parv[2],
+ parv[3], parv[4]);
+ break;
+ case RPL_LISTEND:
+ mybuf[0] = '\0';
+ break;
+ case RPL_NOTOPIC:
+ sprintf(mybuf, "*** %s: No Topic is set", parv[0]);
+ break;
+ case RPL_TOPIC:
+ sprintf(mybuf, "*** %s: Topic on %s is: %s", parv[0], parv[2],
+ parv[3]);
+ break;
+ case RPL_INVITING:
+ sprintf(mybuf, "*** %s: Inviting user %s into channel %s",
+ parv[0], parv[2], parv[3]);
+ break;
+ case RPL_VERSION:
+ /* sprintf(mybuf, "*** %s: Server %s runs ircd %s (%s)", parv[0], */
+ sprintf(mybuf, "*** Server %s runs ircd %s (%s)",
+ parv[3], parv[2], parv[4]);
+ break;
+ case RPL_KILLDONE:
+ sprintf(mybuf, "*** %s: May %s rest in peace",
+ parv[0], parv[2]);
+ break;
+ case RPL_INFO:
+ sprintf(mybuf, "*** %s: Info: %s", parv[0], parv[2]);
+ break;
+#if 1
+ case RPL_MOTD:
+ sprintf(mybuf, "*** %s: Motd: %s", parv[0], parv[2]);
+ break;
+#endif /* 0 Looks better this way! -Vesa */
+ case RPL_YOUREOPER:
+ sprintf(mybuf, "*** %s: %s", parv[0], (parv[2][0] == '\0') ?
+ "You have operator privileges now. Be nice to mere mortal souls" :
+ parv[2]);
+ break;
+ case RPL_NOTOPERANYMORE:
+ sprintf(mybuf, "*** %s: You are No Longer Have Operator %s",
+ parv[0], "Privileges");
+ break;
+ case RPL_REHASHING:
+ sprintf(mybuf, "*** %s: %s", parv[0], (parv[2][0] == '\0') ?
+ "Rereading configuration file.." : parv[2]);
+ break;
+ case RPL_MYPORTIS:
+ sprintf(mybuf, "*** %s: %s %s", parv[0], parv[2], parv[1]);
+ break;
+ case RPL_TIME:
+ sprintf(mybuf, "*** Time on host %s is %s",
+ parv[2], parv[3]);
+ break;
+ case RPL_CHANNELMODEIS:
+ sprintf(mybuf, "*** Mode is %s %s %s",
+ parv[2], parv[3], parv[4]);
+ break;
+ case RPL_LINKS:
+ m_linreply(cptr, sptr, parc, parv);
+ break;
+ case RPL_WHOREPLY:
+ m_newwhoreply(parv[2],parv[3],parv[4],parv[6],parv[7],parv[8]);
+ break;
+ case RPL_NAMREPLY:
+ m_newnamreply(cptr, sptr, parc, parv);
+ break;
+ case RPL_BANLIST:
+ sprintf(mybuf, "*** %s is banned on %s",
+ parv[3], parv[2]);
+ break;
+ case RPL_TRACELINK:
+ sprintf(mybuf,"%s<%s> Link %s> %s (%s up %s) bQ:%s fQ:%s",
+ parv[0], parv[3], parv[6], parv[4], parv[5], parv[7],
+ parv[8], parv[9]);
+ break;
+ case RPL_TRACESERVER:
+ if (parc <= 5)
+ sprintf(mybuf,"*** %s Class: %s %s: %s",
+ parv[0], parv[3], parv[2], parv[4]);
+ else
+ sprintf(mybuf,"*** %s %s Cl:%s %s/%s %s %s %s",
+ parv[0], parv[2], parv[3], parv[4],
+ parv[5], parv[6], parv[7], parv[8]);
+ break;
+ case RPL_TRACECONNECTING:
+ case RPL_TRACEHANDSHAKE:
+ case RPL_TRACEUNKNOWN:
+ case RPL_TRACEOPERATOR:
+ case RPL_TRACEUSER:
+ case RPL_TRACESERVICE:
+ case RPL_TRACENEWTYPE:
+ sprintf(mybuf,"*** %s %s Class: %s %s",
+ parv[0], parv[2], parv[3], parv[4]);
+ break;
+ case RPL_TRACELOG:
+ sprintf(mybuf,"*** %s File: %s level:%s ",
+ parv[0], parv[3], parv[4]);
+ break;
+ case RPL_TRACECLASS:
+ sprintf(mybuf,"*** %s Class: %s Links: %s",
+ parv[0], parv[3], parv[4]);
+ break;
+ case RPL_STATSLINKINFO:
+ l = time(NULL) - atol(parv[8]); /* count startup time */
+ tmp = (char *) ctime(&l);
+ *((char *) index(tmp, '\n')) = (char) '\0'; /* remove '\n' */
+ sprintf(mybuf,"*** %s: %s Q:%s sM:%s sB:%s rM:%s rB:%s D:%s",
+ parv[0], parv[2], parv[3], parv[4], parv[5],
+ parv[6], parv[7], tmp);
+ break;
+ case RPL_STATSCOMMANDS:
+ sprintf(mybuf, "*** %s: %s has been used %s times (%s bytes)",
+ parv[0], parv[2], parv[3], parv[4]);
+ break;
+ case RPL_STATSYLINE:
+ sprintf(mybuf, "*** %s: Cl:%s Pf:%s Cf:%s Max:%s Sq:%s",
+ parv[0], parv[3], parv[4],
+ parv[5], parv[6], parv[7]);
+ break;
+ case RPL_UMODEIS:
+ sprintf(mybuf, "*** %s: Mode for user %s is %s",
+ parv[0], parv[1], parv[2]);
+ break;
+#ifdef HIDE_NUMERICS
+ case RPL_STATSCLINE:
+ case RPL_STATSNLINE:
+ case RPL_STATSILINE:
+ sprintf(mybuf, "*** %s: %s:%s:*:%s:%s:%s",
+ parv[0], parv[2], parv[3], parv[5], parv[6], parv[7]);
+ break;
+ case RPL_STATSKLINE:
+ case RPL_STATSQLINE:
+ sprintf(mybuf, "*** %s: %s:%s:%s:%s:%s:%s",
+ parv[0], parv[2], parv[3], parv[4],
+ parv[5], parv[6], parv[7]);
+ break;
+ case RPL_SERVICEINFO:
+ sprintf(mybuf, "*** %s: Info For Service %s: %s",
+ parv[0], parv[3], parv[4]);
+ break;
+ case RPL_ENDOFWHO:
+ case RPL_ENDOFWHOIS:
+ case RPL_ENDOFWHOWAS:
+ case RPL_ENDOFINFO:
+ case RPL_ENDOFMOTD:
+ case RPL_ENDOFUSERS:
+ case RPL_ENDOFLINKS:
+ case RPL_ENDOFNAMES:
+ case RPL_ENDOFSTATS:
+ case RPL_ENDOFBANLIST:
+ case RPL_ENDOFSERVICES:
+ mybuf[0] = '\0';
+ break;
+#endif /* !HIDE_NUMERICS */
+ case RPL_WELCOME:
+ strcpy(me.name, parv[1]);
+ write_statusline();
+ default:
+ sprintf(mybuf, "%03d %s %s %s %s %s %s %s %s %s",
+ numeric, parv[0], parv[2],
+ parv[3], parv[4], parv[5], parv[6], parv[7],
+ parv[8], parv[9]);
+ break;
+ }
+ if (mybuf[0])
+ putline(mybuf);
+ return 0;
+}
diff --git a/irc/c_numeric_ext.h b/irc/c_numeric_ext.h
new file mode 100644
index 0000000..087d058
--- /dev/null
+++ b/irc/c_numeric_ext.h
@@ -0,0 +1,39 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_numeric_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_numeric.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_NUMERIC_C
+extern char c_numeric_id[];
+#endif /* C_NUMERIC_C */
+
+/* External definitions for global functions.
+ */
+#ifndef C_NUMERIC_C
+#define EXTERN extern
+#else /* C_NUMERIC_C */
+#define EXTERN
+#endif /* C_NUMERIC_C */
+EXTERN int do_numeric __P((int numeric, aClient *cptr, aClient *sptr, int parc,
+ char *parv[]));
+#undef EXTERN
diff --git a/irc/c_version.c b/irc/c_version.c
new file mode 100644
index 0000000..2060dce
--- /dev/null
+++ b/irc/c_version.c
@@ -0,0 +1,46 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_version.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Finland
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: c_version.c,v 1.3 1998/12/13 00:02:35 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define C_VERSION_C
+#include "c_externs.h"
+#undef C_VERSION_C
+
+char *intro = "Internet Relay Chat v%s";
+char *version;
+char *infotext[] =
+ {
+ "Original code written by Jarkko Oikarinen <jto@tolsun.oulu.fi>",
+ "Copyright 1988,1989,1990 University of Oulu, Computing Center",
+ " and Jarkko Oikarinen",
+ 0,
+ };
+
+char *HEADEROLD =
+"*Internet Relay Chat* Type /help to get help * Client v%s * ";
+
+char *IRCHEADER =
+" *IRC Client v%s* %10.10s on %10.10s */help for help* ";
+
diff --git a/irc/c_version_ext.h b/irc/c_version_ext.h
new file mode 100644
index 0000000..34b5d6d
--- /dev/null
+++ b/irc/c_version_ext.h
@@ -0,0 +1,32 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_version_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/c_version.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef C_VERSION_C
+extern char *intro;
+extern char *version;
+extern char *infotext[];
+extern char *HEADEROLD;
+extern char *IRCHEADER;
+#endif /* C_VERSION_C */
diff --git a/irc/ctcp.c b/irc/ctcp.c
new file mode 100644
index 0000000..5c05a3d
--- /dev/null
+++ b/irc/ctcp.c
@@ -0,0 +1,50 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/c_bsd.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: ctcp.c,v 1.2 1997/09/03 17:45:36 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define CTCP_C
+#include "c_externs.h"
+#undef CTCP_C
+
+#define CTCP_CHAR 0x1
+
+void check_ctcp(cptr, sptr, parc, parv)
+aClient *cptr, *sptr;
+int parc;
+char *parv[];
+{
+ char *front = NULL, *back = NULL;
+
+ if (parc < 3)
+ return;
+
+ if (!(front = index(parv[2], CTCP_CHAR)))
+ return;
+ if (!(back = index(++front, CTCP_CHAR)))
+ return;
+ *back = '\0';
+ if (!strcmp(front, "VERSION"))
+ sendto_one(sptr, "NOTICE %s :%cVERSION %s%c", parv[0],
+ CTCP_CHAR, version, CTCP_CHAR);
+ *back = CTCP_CHAR;
+}
diff --git a/irc/ctcp_ext.h b/irc/ctcp_ext.h
new file mode 100644
index 0000000..e5a8fc8
--- /dev/null
+++ b/irc/ctcp_ext.h
@@ -0,0 +1,33 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/ctcp_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/ctcp.c.
+ */
+
+/* External definitions for global functions.
+ */
+#ifndef CTCP_C
+#define EXTERN extern
+#else /* CTCP_C */
+#define EXTERN
+#endif /* CTCP_C */
+EXTERN void check_ctcp __P((aClient *cptr, aClient *sptr, int parc,
+ char *parv[]));
+#undef EXTERN
diff --git a/irc/edit.c b/irc/edit.c
new file mode 100644
index 0000000..3abe487
--- /dev/null
+++ b/irc/edit.c
@@ -0,0 +1,411 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/edit.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: edit.c,v 1.2 1997/09/03 17:45:37 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define EDIT_C
+#include "c_externs.h"
+#undef EDIT_C
+
+#define FROM_START 0
+#define FROM_END 1
+#define RELATIVE 2
+
+static int esc=0;
+static int literal=0;
+
+int do_char(ch)
+char ch;
+{
+ static int first_time=0;
+
+ if (!first_time) {
+ toggle_ins();
+ toggle_ins();
+ first_time=1;
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM)
+ refresh();
+#endif
+ }
+ if (esc == 1) {
+ do_after_esc(ch);
+ return tulosta_viimeinen_rivi();
+ }
+ switch (ch)
+ {
+ case '\000': /* NULL */
+ break;
+ case '\001': /* ^A */
+ bol(); /* beginning of line */
+ break;
+ case '\002': /* ^B */
+ back_ch(); /* backward char */
+ break;
+ case '\003': /* ^C */
+ rev_line(); /* reverse line */
+ break;
+ case '\004': /* ^D */
+ del_ch_right(); /* delete char from right */
+ break;
+ case '\005': /* ^E */
+ eol(); /* end of line */
+ break;
+ case '\006': /* ^F */
+ forw_ch(); /* forward char */
+ break;
+ case '\007': /* ^G */
+ add_ch(ch); /* bell */
+ break;
+ case '\010': /* ^H */
+ del_ch_left(); /* delete char to left */
+ break;
+ case '\011': /* TAB */
+ toggle_ins(); /* toggle insert mode */
+ break;
+ case '\012': /* ^J */
+ send_this_line(); /* send this line */
+ break;
+ case '\013': /* ^K */
+ kill_eol(); /* kill to end of line */
+ break;
+ case '\014': /* ^L */
+ refresh_screen(); /* refresh screen */
+ write_statusline();
+ break;
+ case '\015': /* ^M */
+ send_this_line(); /* send this line */
+ break;
+ case '\016': /* ^N */
+ next_in_history(); /* next in history */
+ break;
+ case '\017': /* ^O */
+ break;
+ case '\020': /* ^P */
+ previous_in_history(); /* previous in history */
+ break;
+ case '\021': /* ^Q */
+ break;
+ case '\022': /* ^R */
+ case '\023': /* ^S */
+ case '\024': /* ^T */
+ break;
+ case '\025': /* ^U */
+ kill_whole_line(); /* kill whole line */
+ break;
+ case '\026': /* ^V */
+ literal_next(); /* literal next */
+ break;
+ case '\027': /* ^W */
+ del_word_left(); /* delete word left */
+ break;
+ case '\030': /* ^X */
+ break;
+ case '\031': /* ^Y */
+ yank(); /* yank */
+ break;
+ case '\032': /* ^Z */
+ suspend_irc(0); /* suspend irc */
+ break;
+ case '\033': /* ESC */
+ got_esc();
+ break;
+ case '\177': /* DEL */
+ del_ch_left(); /* delete char to left */
+ break;
+ default:
+ add_ch(ch);
+ break;
+ }
+ return tulosta_viimeinen_rivi();
+}
+
+void bol()
+{
+ set_position(0, FROM_START);
+}
+
+void eol()
+{
+ set_position(0, FROM_END);
+ set_position(1, RELATIVE);
+}
+
+void back_ch()
+{
+ set_position(-1, RELATIVE);
+}
+
+void forw_ch()
+{
+ set_position(1, RELATIVE);
+}
+
+void rev_line()
+{
+ int i1, i2, i3, i4;
+
+ i4 = get_position();
+ set_position(0, FROM_START);
+ i1 = get_position();
+ set_position(0, FROM_END);
+ i1 = get_position()-i1;
+ set_position(i4, FROM_START);
+
+ for (i2 = 0; i2 > i1/2; i2++) {
+ i3 = get_char(i2);
+ set_char(i2, get_char(i1-i2-1));
+ set_char(i1-i2-1, i3);
+ }
+}
+
+void del_ch_right()
+{
+ int i1, i2, i3;
+
+ i1 = get_position();
+
+ if (!get_char(i1))
+ return; /* last char in line */
+ set_position(0, FROM_END);
+ i2 = get_position();
+ for (i3 = i1; i3 < i2; i3++)
+ set_char(i3, get_char(i3+1));
+ set_char(i3, 0);
+ set_position(i1, FROM_START);
+}
+
+void del_ch_left()
+{
+ int i1, i2, i3;
+
+ i1 = get_position();
+
+ if (!i1)
+ return; /* first pos in line */
+ set_position(0, FROM_END);
+ i2 = get_position();
+ for (i3 = i1-1; i3 < i2; i3++)
+ set_char(i3, get_char(i3+1));
+ set_char(i3, 0);
+ set_position(i1, FROM_START);
+ set_position(-1, RELATIVE);
+}
+
+RETSIGTYPE suspend_irc(s)
+int s;
+{
+#ifdef SIGTSTP
+ signal(SIGTSTP, suspend_irc);
+# ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ echo();
+ nocrmode();
+ }
+# endif /* DOCURSES */
+# ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ io_off();
+# endif /* DOTERMCAP */
+# ifdef SIGSTOP
+ kill(getpid(), SIGSTOP);
+# endif /* SIGSTOP */
+# ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ /* initscr(); */
+ noecho();
+ crmode();
+ clear();
+ refresh();
+ }
+# endif /* DOCURSES */
+# ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM) {
+ io_on(1);
+ clearscreen();
+ }
+# endif /* DOTERMCAP */
+ write_statusline();
+#else /* || */
+# if !defined(SVR3)
+ tstp();
+# endif
+#endif /* || */
+}
+
+void got_esc()
+{
+ esc = 1;
+}
+
+void do_after_esc(ch)
+char ch;
+{
+ if (literal) {
+ literal = 0;
+ add_ch(ch);
+ return;
+ }
+ esc = 0;
+ switch (ch)
+ {
+ case 'b':
+ word_back();
+ break;
+ case 'd':
+ del_word_right();
+ break;
+ case 'f':
+ word_forw();
+ break;
+ case 'y':
+ yank();
+ break;
+ case '\177':
+ del_word_left();
+ break;
+ default:
+ break;
+ }
+}
+
+void refresh_screen()
+{
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ clearok(curscr, TRUE);
+ refresh();
+ }
+#endif
+}
+
+void add_ch(ch)
+int ch;
+{
+ int i1, i2, i3;
+
+ if (in_insert_mode()) {
+ i1 = get_position();
+ set_position(0, FROM_END);
+ i2 = get_position();
+ for (i3 = i2; i3 >= 0; i3--)
+ set_char(i1+i3+1, get_char(i3+i1));
+ set_char(i1, ch);
+ set_position(i1, FROM_START);
+ set_position(1, RELATIVE);
+ } else {
+ i1 = get_position();
+ set_char(i1, ch);
+ set_position(i1, FROM_START);
+ set_position(1, RELATIVE);
+ }
+}
+
+void literal_next()
+{
+ got_esc();
+ literal=1;
+}
+
+void word_forw()
+{
+ int i1,i2;
+
+ i1 = get_position();
+
+ while ((i2 = get_char(i1)))
+ if ((i2 == (int)' ') || (i2 == (int)'\t') ||
+ (i2 == (int)'_') || (i2 == (int)'-'))
+ i1++;
+ else
+ break;
+ while ((i2 = get_char(i1)))
+ if ((i2 == (int)' ') || (i2 == (int)'\t') ||
+ (i2 == (int)'_') || (i2 == (int)'-'))
+ break;
+ else
+ i1++;
+ set_position(i1, FROM_START);
+}
+
+void word_back()
+{
+ int i1,i2;
+
+ i1 = get_position();
+ if (i1 != 0)
+ i1--;
+
+ while ((i2 = get_char(i1)))
+ if ((i2 == (int)' ') || (i2 == (int)'\t') ||
+ (i2 == (int)'_') || (i2 == (int)'-'))
+ i1--;
+ else
+ break;
+ while ((i2 = get_char(i1)))
+ if ((i2 == (int)' ') || (i2 == (int)'\t') ||
+ (i2 == (int)'_') || (i2 == (int)'-'))
+ break;
+ else
+ i1--;
+ if (i1 <= 0)
+ i1 = 0;
+ else
+ i1++;
+ set_position(i1, FROM_START);
+}
+
+void del_word_left()
+{
+ int i1, i2, i3, i4;
+
+ i1 = get_position();
+ word_back();
+ i2 = get_position();
+ set_position(0, FROM_END);
+ i3 = get_position();
+ for(i4 = i2; i4 <= i3 - (i1 - i2); i4++)
+ set_char(i4, get_char(i4 + (i1 - i2)));
+ for(; i4 <= i3; i4++)
+ set_char(i4, (int)'\0');
+ set_position(i2, FROM_START);
+}
+
+void del_word_right()
+{
+ int i1, i2, i3, i4;
+
+ i2 = get_position();
+ word_forw();
+ i1 = get_position();
+ set_position(0, FROM_END);
+ i3 = get_position();
+ for(i4 = i2; i4 <= i3 - (i1 - i2); i4++)
+ set_char(i4, get_char(i4 + (i1 - i2)));
+ for(; i4 <= i3; i4++)
+ set_char(i4, (int)'\0');
+ set_position(i2, FROM_START);
+}
+
+
diff --git a/irc/edit_ext.h b/irc/edit_ext.h
new file mode 100644
index 0000000..54a0963
--- /dev/null
+++ b/irc/edit_ext.h
@@ -0,0 +1,55 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/edit_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/edit.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef EDIT_C
+extern char edit_id[];
+#endif /* EDIT_C */
+
+/* External definitions for global functions.
+ */
+#ifndef EDIT_C
+#define EXTERN extern
+#else /* EDIT_C */
+#define EXTERN
+#endif /* EDIT_C */
+EXTERN int do_char __P((char ch));
+EXTERN void bol();
+EXTERN void eol();
+EXTERN void back_ch();
+EXTERN void forw_ch();
+EXTERN void rev_line();
+EXTERN void del_ch_right();
+EXTERN void del_ch_left();
+EXTERN RETSIGTYPE suspend_irc __P((int s));
+EXTERN void got_esc();
+EXTERN void do_after_esc __P((char ch));
+EXTERN void refresh_screen();
+EXTERN void add_ch __P((int ch));
+EXTERN void literal_next();
+EXTERN void word_forw();
+EXTERN void word_back();
+EXTERN void del_word_left();
+EXTERN void del_word_right();
+#undef EXTERN
diff --git a/irc/help.c b/irc/help.c
new file mode 100644
index 0000000..71d3dfe
--- /dev/null
+++ b/irc/help.c
@@ -0,0 +1,228 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/help.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: help.c,v 1.2 1997/09/03 17:45:38 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define HELP_C
+#include "c_externs.h"
+#undef HELP_C
+
+struct Help helplist[] = {
+ { "ADMIN", "/ADMIN <server>",
+ { "Prints administrative information about an IRC server.",
+ "<server> defaults to your own IRC server.", "", "", "" } },
+ { "AWAY", "/AWAY <message>",
+ { "<Mark yourself as being away. <message> is a message that will be",
+ "automatically sent to anyone who tries sending you a private message.",
+ "If you are already marked as being away, /AWAY will change your status",
+ "back to \"here.\"", "" } },
+ { "BYE", "/BYE",
+ { "Exit from IRC. /BYE, /EXIT, /QUIT and /SIGNOFF are identical.",
+ "", "", "", "" } },
+ { "CHANNEL", "/CHANNEL <channel>",
+ { "Leave the current channel and join a new one. Channel is any number",
+ "or a string beginning with a plus (+) sign. Numbered channels above 999",
+ "are private channels, you cannot see them by /LIST. Negative channels",
+ "are secret; they do not appear in /WHO at all. String channels are open",
+ "first, but the channel operators can change the mode with /MODE" } },
+ { "CLEAR", "/CLEAR",
+ { "Clear your screen.", "", "", "", "" } },
+ { "CMDCH", "/CMDCH <x>",
+ { "Changes your command prefix character to <x>. This is useful if you",
+ "often start lines with slashes. For example, after typing \"/cmdch #\"",
+ "your commands would look like #who or #links.", "", "" } },
+ { "DATE", "/DATE <server>",
+ { "Prints the date and time local to a specific server. <server> defaults",
+ "to your own IRC server. /DATE and /TIME are identical.", "", "", "" } },
+ { "EXIT", "/EXIT",
+ { "Exit from IRC. /BYE, /EXIT, /QUIT and /SIGNOFF are identical.",
+ "", "", "", "" } },
+#ifdef VMSP
+ { "EXEC", "/EXEC <CP/CMS command>",
+ { "Executes a CP/CMS command. If the command spends some time, you may",
+ "be signed off by the server. See UNKILL.",
+ "Warning: Screen is cleared after execcuting a command.",
+ "", "" } },
+#endif
+ { "HELP", "/HELP <command>",
+ { "/HELP without parameters lists all IRC commands.",
+ "/HELP followed by a command name prints a description of that command.",
+ "", "", "" } },
+ { "IGNORE", "/IGNORE <+|-><nicknames>",
+ { "Allows you to automatically ignore messages from certain users. If",
+ "+ is specified before <nicknames>, only public messages are ignored.",
+ "Similarly, - ignores only private messages. If neither symbol is given",
+ "all messages are ignored. /IGNORE without parameters prints the current",
+ "list of ignored users." } },
+ { "INFO", "/INFO",
+ { "Prints some information about IRC.", "", "", "", "" } },
+ { "INVITE", "/INVITE <channel> <nickname>",
+ { "Invites a user to join your channel. The user must be currently using",
+ "IRC.", "", "", "" } },
+ { "JOIN", "/JOIN <channel>{,<channel>} [<key>{,<key>}]",
+ { "Leave the current channel and join a new one. Channels above 999",
+ "are private channels; their numbers are not listed by /WHO. Negative",
+ "numbered channels are secret; they do not appear in /WHO at all.",
+ "/JOIN and /CHANNEL are identical.", "" } },
+ { "KICK", "/KICK <channel> <user> [<comment>]",
+ { "Kicks specified user off given channel",
+ "Only channel operators are privileged to use this command",
+ "Channel operator privileges can be given to other users of channel",
+ "by command '/MODE <channel> +o <user>' and taken away by command",
+ "'/MODE <channel> -o <user>'" } },
+ { "LINKS", "/LINKS [<pattern> [<server>]]",
+ { "Lists all active IRC servers.",
+ "If <pattern> is given, list all active irc links matching <pattern>",
+ "For example, /links *.fi lists all links in Finland", "", "" } },
+ { "LIST", "/LIST",
+ { "Lists all active channels and, if set, their topics.", "", "", "", "" } },
+ { "LUSERS", "/LUSERS",
+ { "Show the number of people and servers connected to the IRC network.",
+ "", "", "", "" } },
+ { "LOG", "/LOG <filename>",
+ { "Sends a copy of your IRC session to a file.",
+ "/LOG followed by a filename begins logging in the given file.",
+ "/LOG with no parameters turns logging off.", "", "" } },
+ { "MSG", "/MSG <nicknames> <message>",
+ { "Send a private message. <nicknames> should be one or more nicknames or",
+ "channel numbers separated by commas (no spaces). If <nicknames> is \",\"",
+ "your message is sent to the last person who sent you a private message.",
+ "If <nicknames> is \".\" it's sent to the last personyou sent one to.",
+ "Messages sent to , or . can (currently) contain no other recipients." } },
+ { "MODE", "/MODE <channel> [+|-]<modechars> <parameters>",
+ { "Mode command is quite complicated and it allows channel operators to",
+ "change channel mode. <modechars> is one of m (moderated), s (secret),",
+ "p (private), l (limited), t (topiclimited), a (anonymous), o (oper)",
+ "i (inviteonly). + or - sign whether the specifies mode should be added",
+ "or deleted. Parameter for l is the maximum users allowed" } },
+ { "MOTD", "/MOTD <server>",
+ { "Query for message-of-today in given server. If <server> parameter is",
+ "left out, query local server", "", "", "" } },
+ { "NAMES", "/NAMES <channel>{,<channel>}",
+ { "/NAMES without a parameter lists the nicknames of users on all channels.",
+ "/NAMES followed by a channel number lists the names on that channel.",
+ "", "", "" } },
+ { "NICK", "/NICK <nickname>",
+ { "Change your nickname. You cannot choose a nickname that is already in",
+ "use. Additionally, some characters cannot be used in nicknames.",
+ "", "", "" } },
+ { "QUERY", "/QUERY <nicknames>",
+ { "Begin private chat with <nicknames>. All subsequent messages you type",
+ "will be automatically sent only to <nicknames>. /QUERY without",
+ "parameters ends any current chat. You can send a normal message to your",
+ "channel by prefixing it with a slash and a space, like \"/ hi\".", "" } },
+ { "QUIT", "/QUIT [<comment>]",
+ { "Exit from IRC. /BYE, /EXIT, /QUIT and /SIGNOFF are identical.",
+ "", "", "", "" } },
+ { "SERVER", "/SERVER <server>",
+ { "Disconnects from currect server and connects your client into a new",
+ "server specified in command line", "", "", "" } },
+ { "SIGNOFF", "/SIGNOFF",
+ { "Exit from IRC. /BYE, /EXIT, /QUIT and /SIGNOFF are identical.",
+ "", "", "", "" } },
+ { "STATS", "/STATS [<c|h|i|k|l|m|n|o|q|y>]",
+ { "Shows various IRC server statistics. This command is rather boring",
+ "", "", "", "" } },
+ { "SUMMON", "/SUMMON <user> [<server>]",
+ { "Ask a user to enter IRC. <user> is of the form guest@tolsun.oulu.fi.",
+ "You can only summon users on machines where an IRC server is running.",
+ "Some servers may have disabled the /SUMMON command.", "", "" } },
+ { "TIME", "/TIME <server>",
+ { "Prints the date and time local to a specific server. <server> defaults",
+ "to your own IRC server. /DATE and /TIME are identical.", "", "", "" } },
+ { "TOPIC", "/TOPIC <channel> [<topic>]",
+ { "Sets the topic for the channel you're on.", "", "", "", "" } },
+ { "UNKILL", "/UNKILL",
+ { "Orders to irc reconnect to server if you happen to become killed",
+ "accidentally or in purpose", "", "", "" } },
+ { "USERS", "/USERS <host>",
+ { "List all users logged in to a host. The host must be running an IRC",
+ "server. Finger(1) usually works better.", "", "", "" } },
+ { "VERSION", "/VERSION <server>",
+ { "Prints the version number of an IRC server. <server> defaults to your",
+ "own IRC server.", "", "", "" } },
+ { "WHO", "/WHO <channel> [<o>]",
+ { "/WHO without parameters lists users on all channels.",
+ "/WHO followed by a channel number lists users on that channel.",
+ "/WHO * lists users that are on the same channel as you.",
+ "You cannot see users that are on negative-numbered channels.", "" } },
+ { "WHOIS", "/WHOIS <nicknames>{,<nickname>}",
+ { "/WHOIS prints information about a particular user, including his or",
+ "her name, host name and IRC server. <nicknames> should be one of more",
+ "nicknames separated by commas.", "", "" } },
+ { "WHOWAS", "/WHOWAS <nickname>{,<nickname>} [<count> [<server>]]",
+ { "/WHOWAS returns nickname history information for each of the given",
+ "nicknames.", "", "", "" } },
+ { NULL, NULL,
+ { NULL, NULL, NULL, NULL, NULL } }
+};
+
+char helpbuf[80];
+
+void do_help(ptr, temp)
+char *ptr, *temp;
+{
+ struct Help *hptr;
+ int count;
+
+ if (BadPtr(ptr)) {
+ sprintf(helpbuf, "*** Help: Internet Relay Chat v%s Commands:", version);
+ putline(helpbuf);
+ count = 0;
+ for (hptr = helplist; hptr->command; hptr++) {
+ sprintf(&helpbuf[count*10], "%10s", hptr->command);
+ if (++count >= 6) {
+ count = 0;
+ putline(helpbuf);
+ }
+ }
+ if (count)
+ putline(helpbuf);
+ putline("Type /HELP <command> to get help about a particular command.");
+ putline("For example \"/HELP signoff\" gives you help about the");
+ putline("/SIGNOFF command. To use a command you must prefix it with a");
+ putline("slash or whatever your current command character is (see");
+ putline("\"/HELP cmdch\"");
+ putline("*** End Help");
+ } else {
+ for (hptr = helplist; hptr->command; hptr++)
+ if (mycncmp(ptr, hptr->command))
+ break;
+
+ if (hptr->command == (char *) 0) {
+ putline("*** There is no help information for that command.");
+ putline("*** Type \"/HELP\" to get a list of commands.");
+ return;
+ }
+ sprintf(helpbuf, "*** Help: %s", hptr->syntax);
+ putline(helpbuf);
+ for (count = 0; count < 5; count++)
+ if (hptr->explanation[count] && *(hptr->explanation[count])) {
+ sprintf(helpbuf, " %s", hptr->explanation[count]);
+ putline(helpbuf);
+ }
+ putline("*** End Help");
+ }
+}
+
diff --git a/irc/help_def.h b/irc/help_def.h
new file mode 100644
index 0000000..82a6769
--- /dev/null
+++ b/irc/help_def.h
@@ -0,0 +1,23 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/help_def.h
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+struct Help {
+ char *command, *syntax, *explanation[5];
+};
diff --git a/irc/help_ext.h b/irc/help_ext.h
new file mode 100644
index 0000000..6a85893
--- /dev/null
+++ b/irc/help_ext.h
@@ -0,0 +1,40 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/help_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/help.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef HELP_C
+extern struct Help helplist[];
+extern char help_id[];
+extern char helpbuf[];
+#endif /* HELP_C */
+
+/* External definitions for global functions.
+ */
+#ifndef HELP_C
+#define EXTERN extern
+#else /* HELP_C */
+#define EXTERN
+#endif /* HELP_C */
+EXTERN void do_help __P((char *ptr, char *temp));
+#undef EXTERN
diff --git a/irc/ignore.c b/irc/ignore.c
new file mode 100644
index 0000000..23bc5db
--- /dev/null
+++ b/irc/ignore.c
@@ -0,0 +1,141 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/ignore.c
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: ignore.c,v 1.2 1997/09/03 17:45:39 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define IGNORE_C
+#include "c_externs.h"
+#undef IGNORE_C
+
+anIgnore *ignore = (anIgnore *) 0;
+char ibuf[80];
+
+void do_ignore(user, temp)
+char *user, *temp;
+{
+ char *ch, *wild = "*";
+ anIgnore *iptr;
+ char *apu = user, *uh;
+ int status;
+ if ((user == (char *) 0) || (*user == '\0')) {
+
+ putline("*** Current ignore list entries:");
+ for (iptr = ignore; iptr; iptr = iptr->next) {
+ sprintf(ibuf," Ignoring %s messages from user %s!%s",
+ (iptr->flags == IGNORE_TOTAL) ? "all" :
+ (iptr->flags == IGNORE_PRIVATE) ? "private" : "public",
+ iptr->user, iptr->from);
+ putline(ibuf);
+ }
+ putline("*** End of ignore list entries");
+ return;
+ }
+ while (apu && *apu) {
+ ch = apu;
+ if (*ch == '+') {
+ ch++;
+ status = IGNORE_PUBLIC;
+ }
+ else if (*ch == '-') {
+ ch++;
+ status = IGNORE_PRIVATE;
+ }
+ else
+ status = IGNORE_TOTAL;
+ if ((apu = index(ch, ',')))
+ *(apu++) = '\0';
+ if ((uh = index(ch, '!')))
+ *uh++ = '\0';
+ else if ((uh = index(ch, '@')))
+ *uh++ = '\0';
+ else
+ uh = wild;
+ if (!*ch)
+ ch = wild;
+ if ((iptr = find_ignore(ch, (anIgnore *)NULL, uh))) {
+ sprintf(ibuf,"*** Ignore removed: user %s!%s",
+ iptr->user, iptr->from);
+ putline(ibuf);
+ kill_ignore(iptr);
+ } else {
+ if (strlen(ch) > (size_t) NICKLEN)
+ ch[NICKLEN] = '\0';
+ if (add_ignore(ch, status, uh) >= 0) {
+ sprintf(ibuf,"*** Ignore %s messages from user %s!%s",
+ (status == IGNORE_TOTAL) ? "all" :
+ (status == IGNORE_PRIVATE) ? "private" : "public", ch, uh);
+ putline(ibuf);
+ } else
+ putline("Fatal Error: Cannot allocate memory for ignore buffer");
+ }
+ }
+}
+
+anIgnore *find_ignore(user, para, fromhost)
+char *user, *fromhost;
+anIgnore *para;
+{
+ anIgnore *iptr;
+ for (iptr = ignore; iptr; iptr=iptr->next)
+ if ((match(iptr->user, user) == 0) &&
+ (match(iptr->from, fromhost)==0))
+ break;
+
+ return iptr ? iptr : para;
+}
+
+int kill_ignore(iptr)
+anIgnore *iptr;
+{
+ anIgnore *i2ptr, *i3ptr = (anIgnore *) 0;
+ for (i2ptr = ignore; i2ptr; i2ptr = i2ptr->next) {
+ if (i2ptr == iptr)
+ break;
+ i3ptr = i2ptr;
+ }
+ if (i2ptr) {
+ if (i3ptr)
+ i3ptr->next = i2ptr->next;
+ else
+ ignore = i2ptr->next;
+ free(i2ptr);
+ return (1);
+ }
+ return (-1);
+}
+
+int add_ignore(ch, status, fromhost)
+char *ch, *fromhost;
+int status;
+{
+ anIgnore *iptr;
+ iptr = (anIgnore *) malloc(sizeof (anIgnore));
+ if (iptr == (anIgnore *) 0)
+ return(-1);
+ strncpyzt(iptr->user, ch, sizeof(iptr->user));
+ strncpyzt(iptr->from, fromhost, sizeof(iptr->from));
+ iptr->next = ignore;
+ ignore = iptr;
+ iptr->flags = status;
+ return(1);
+}
diff --git a/irc/ignore_ext.h b/irc/ignore_ext.h
new file mode 100644
index 0000000..f2e3d16
--- /dev/null
+++ b/irc/ignore_ext.h
@@ -0,0 +1,43 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/ignore_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/ignore.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef IGNORE_C
+extern char ignore_id[];
+extern anIgnore *ignore;
+extern char ibuf[];
+#endif /* IGNORE_C */
+
+/* External definitions for global functions.
+ */
+#ifndef IGNORE_C
+#define EXTERN extern
+#else /* IGNORE_C */
+#define EXTERN
+#endif /* IGNORE_C */
+EXTERN void do_ignore __P((char *user, char *temp));
+EXTERN anIgnore *find_ignore __P((char *user, anIgnore *para, char *fromhost));
+EXTERN int kill_ignore __P((anIgnore *iptr));
+EXTERN int add_ignore __P((char *ch, int status, char *fromhost));
+#undef EXTERN
diff --git a/irc/irc.c b/irc/irc.c
new file mode 100644
index 0000000..7246f21
--- /dev/null
+++ b/irc/irc.c
@@ -0,0 +1,908 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/irc.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: irc.c,v 1.6 1998/12/13 00:02:35 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define IRC_C
+#include "c_externs.h"
+#undef IRC_C
+
+#define DEPTH 10
+#define KILLMAX 2 /* Number of kills to accept to really die */
+ /* this is to prevent looping with /unkill */
+
+#ifdef AUTOMATON
+#ifdef DOCURSES
+#undef DOCURSES
+#endif
+#ifdef DOTERMCAP
+#undef DOTERMCAP
+#endif
+#endif /* AUTOMATON */
+
+struct Command commands[] = {
+ { (void (*)()) 0, "SIGNOFF", SERVER_CMD, "\0\0", MSG_QUIT },
+ { do_bye, "QUIT", LOCAL_FUNC, "\0\0", MSG_QUIT },
+ { do_bye, "EXIT", LOCAL_FUNC, "\0\0", MSG_QUIT },
+ { do_bye, "BYE", LOCAL_FUNC, "\0\0", MSG_QUIT },
+ { do_kill, "KILL", LOCAL_FUNC, "\0\0", MSG_KILL },
+ { (void (*)()) 0, "SUMMON", SERVER_CMD, "\0\0", MSG_SUMMON },
+ { (void (*)()) 0, "STATS", SERVER_CMD, "\0\0", MSG_STATS },
+ { (void (*)()) 0, "USERS", SERVER_CMD, "\0\0", MSG_USERS },
+ { (void (*)()) 0, "TIME", SERVER_CMD, "\0\0", MSG_TIME },
+ { (void (*)()) 0, "DATE", SERVER_CMD, "\0\0", MSG_TIME },
+ { (void (*)()) 0, "NAMES", SERVER_CMD, "\0\0", MSG_NAMES },
+ { (void (*)()) 0, "NICK", SERVER_CMD, "\0\0", MSG_NICK },
+ { (void (*)()) 0, "WHO", SERVER_CMD, "\0\0", MSG_WHO },
+ { (void (*)()) 0, "WHOIS", SERVER_CMD, "\0\0", MSG_WHOIS },
+ { (void (*)()) 0, "WHOWAS", SERVER_CMD, "\0\0", MSG_WHOWAS },
+ { do_kill, "LEAVE", LOCAL_FUNC, "\0\0", MSG_PART },
+ { do_kill, "PART", LOCAL_FUNC, "\0\0", MSG_PART },
+ { (void (*)()) 0, "WOPS", SERVER_CMD, "\0\0", MSG_WALLOPS },
+ { do_channel, "JOIN", LOCAL_FUNC, "\0\0", MSG_JOIN },
+ { do_channel, "CHANNEL", LOCAL_FUNC, "\0\0", MSG_JOIN },
+#ifdef VMSP
+ { do_exec, "EXEC", LOCAL_FUNC, "\0\0", "EXEC" },
+ { do_oper, "OPER", LOCAL_FUNC, "\0\0", "OPER" },
+#endif
+#ifdef GETPASS
+ { do_oper, "OPER", LOCAL_FUNC, "\0\0", "OPER" },
+#else
+ { (void (*)()) 0, "OPER", SERVER_CMD, "\0\0", MSG_OPER },
+#endif
+ { do_away, "AWAY", LOCAL_FUNC, "\0\0", MSG_AWAY },
+ { do_mypriv, "MSG", LOCAL_FUNC, "\0\0", MSG_PRIVATE },
+ { do_kill, "TOPIC", LOCAL_FUNC, "\0\0", MSG_TOPIC },
+ { do_cmdch, "CMDCH", LOCAL_FUNC, "\0\0", "CMDCH" },
+ { (void (*)()) 0, "INVITE", SERVER_CMD, "\0\0", MSG_INVITE },
+ { (void (*)()) 0, "INFO", SERVER_CMD, "\0\0", MSG_INFO },
+ { (void (*)()) 0, "LIST", SERVER_CMD, "\0\0", MSG_LIST },
+ { (void (*)()) 0, "KILL", SERVER_CMD, "\0\0", MSG_KILL },
+ { do_quote, "QUOTE", LOCAL_FUNC, "\0\0", "QUOTE" },
+ { (void (*)()) 0, "LINKS", SERVER_CMD, "\0\0", MSG_LINKS },
+ { (void (*)()) 0, "ADMIN", SERVER_CMD, "\0\0", MSG_ADMIN },
+ { do_ignore, "IGNORE", LOCAL_FUNC, "\0\0", "IGNORE" },
+ { (void (*)()) 0, "TRACE", SERVER_CMD, "\0\0", MSG_TRACE },
+ { do_help, "HELP", LOCAL_FUNC, "\0\0", "HELP" },
+ { do_log, "LOG", LOCAL_FUNC, "\0\0", "LOG" },
+ { (void (*)()) 0, "VERSION", SERVER_CMD, "\0\0", MSG_VERSION },
+ { do_clear, "CLEAR", LOCAL_FUNC, "\0\0", "CLEAR" },
+ { (void (*)()) 0, "REHASH", SERVER_CMD, "\0\0", MSG_REHASH },
+ { do_query, "QUERY", LOCAL_FUNC, "\0\0", "QUERY" },
+ { (void (*)()) 0, "LUSERS", SERVER_CMD, "\0\0", MSG_LUSERS },
+ { (void (*)()) 0, "MOTD", SERVER_CMD, "\0\0", MSG_MOTD },
+ { do_unkill, "UNKILL", LOCAL_FUNC, "\0\0", "UNKILL" },
+ { do_server, "SERVER", LOCAL_FUNC, "\0\0", "SERVER" },
+ { (void (*)()) 0, "MODE", SERVER_CMD, "\0\0", MSG_MODE },
+#ifdef MSG_MAIL
+ { (void (*)()) 0, "MAIL", SERVER_CMD, "\0\0", MSG_MAIL },
+#endif
+ { do_kick, "KICK", LOCAL_FUNC, "\0\0", MSG_KICK },
+ { (void (*)()) 0, "USERHOST",SERVER_CMD, "\0\0", MSG_USERHOST },
+ { (void (*)()) 0, "ISON", SERVER_CMD, "\0\0", MSG_ISON },
+ { (void (*)()) 0, "CONNECT", SERVER_CMD, "\0\0", MSG_CONNECT },
+ { do_kill, "SQUIT", LOCAL_FUNC, "\0\0", MSG_SQUIT },
+ { (void (*)()) 0, "SERVLIST",SERVER_CMD, "\0\0", MSG_SERVLIST },
+ { do_kill, "SQUERY", LOCAL_FUNC, "\0\0", MSG_SQUERY },
+ { do_kill, "NOTICE", LOCAL_FUNC, "\0\0", MSG_NOTICE },
+ { (void (*)()) 0, (char *) 0, 0, "\0\0", (char *) 0 }
+};
+
+aChannel *channel = NULL;
+aClient me, *client = &me;
+anUser meUser; /* User block for 'me' --msa */
+FILE *logfile = NULL;
+char buf[BUFSIZE];
+char *querychannel;
+int portnum, termtype = CURSES_TERM;
+int debuglevel = DEBUG_ERROR;
+int unkill_flag = 0, cchannel = 0;
+int QuitFlag = 0;
+
+static int KillCount = 0;
+static int apu = 0; /* Line number we're currently on screen */
+static int sock; /* Server socket fd */
+static char currserver[HOSTLEN + 1];
+
+#if defined(HPUX) || defined(SVR3) || defined(SVR4)
+char logbuf[BUFSIZ];
+#endif
+
+#ifdef MAIL50
+int ucontext = 0, perslength;
+char persname[81];
+
+struct itmlst
+ null_list[] = {{0,0,0,0}},
+ gplist[] = {{80, MAIL$_USER_PERSONAL_NAME,
+ &persname, &perslength}};
+#endif
+
+int main(argc, argv)
+int argc;
+char *argv[];
+{
+ static char usage[] =
+ "Usage: %s [-c channel] [-k passwd] [-p port] [-i] [-w] [-s] [nickname [server]]\n";
+ char channel[BUFSIZE+1];
+ int length, mode = 0;
+ struct passwd *userdata;
+ char *cp, *argv0=argv[0], *nickptr, *servptr, *getenv(), ch;
+
+ if ((cp = rindex(argv0, '/')) != NULL)
+ argv0 = ++cp;
+ portnum = PORTNUM;
+ *buf = *currserver = '\0';
+ channel[0] = '\0';
+ me.user = &meUser;
+ me.from = &me;
+ me.info = (char *) malloc(REALLEN);
+ setuid(getuid());
+ version = make_version();
+
+ while (argc > 1 && argv[1][0] == '-') {
+ switch(ch = argv[1][1])
+ {
+ case 'h':
+ printf(usage, argv0);
+ exit(1);
+ break;
+ case 'p':
+ length = 0;
+ if (argv[1][2] != '\0')
+ length = atoi(&argv[1][2]);
+ else if (argc > 2) {
+ length = atoi(argv[2]);
+ argv++;
+ argc--;
+ }
+ if (length <= 0) {
+ printf(usage, argv0);
+ exit(1);
+ }
+ cchannel = length;
+ break;
+ case 'c':
+ if (argv[1][2] != '\0')
+ strncpy(channel, &argv[1][2], BUFSIZE);
+ else if (argc > 2) {
+ strncpy(channel, argv[2], BUFSIZE);
+ argv++;
+ argc--;
+ }
+ if (!channel[0]) {
+ printf(usage, argv0);
+ exit(1);
+ }
+ break;
+ case 'i':
+ mode |= FLAGS_INVISIBLE;
+ break;
+ case 'w':
+ mode |= FLAGS_WALLOP;
+ break;
+ case 'k':
+ if (argv[1][2] != '\0')
+ strncpy(me.passwd, &argv[1][2], PASSWDLEN);
+ else if (argc > 2) {
+ strncpy(me.passwd, argv[2], PASSWDLEN);
+ argv++;
+ argc--;
+ }
+ if (!me.passwd[0]) {
+ printf(usage, argv0);
+ exit(1);
+ }
+ break;
+#ifdef DOTERMCAP
+ case 's':
+ termtype = TERMCAP_TERM;
+ break;
+#endif
+ case 'v':
+ (void)printf("irc %s\n", version);
+ exit(0);
+ }
+ argv++;
+ argc--;
+ }
+
+ me.name[0] = me.buffer[0] = '\0';
+ me.next = NULL;
+ me.status = STAT_ME;
+ if ((servptr = getenv("IRCSERVER")))
+ strncpyzt(currserver, servptr, HOSTLEN);
+ if (argc > 2)
+ strncpyzt(currserver, argv[2], HOSTLEN);
+
+ do {
+ QuitFlag = 0;
+ if (unkill_flag < 0)
+ unkill_flag += 2;
+#ifdef UPHOST
+ if (!*currserver)
+ strncpyzt(currserver, UPHOST, HOSTLEN);
+#else
+ if (!*currserver)
+ strncpyzt(currserver, me.sockhost, HOSTLEN);
+#endif
+ if (cchannel > 0)
+ portnum = cchannel;
+
+ sock = client_init(currserver, portnum, &me);
+ if (sock < 0) {
+ printf("sock < 0\n");
+ exit(1);
+ }
+ userdata = getpwuid(getuid());
+ if (strlen(userdata->pw_name) >= (size_t) USERLEN) {
+ userdata->pw_name[USERLEN-1] = '\0';
+ }
+ if (strlen(userdata->pw_gecos) >= (size_t) REALLEN) {
+ userdata->pw_gecos[REALLEN-1] = '\0';
+ }
+ /* FIX: jtrim@orion.cair.du.edu -- 3/14/88
+ & jto@tolsun.oulu.fi */
+ if (!*me.name) {
+ if (argc >= 2) {
+ strncpy(me.name, argv[1], NICKLEN);
+ } else if ((nickptr = getenv("IRCNICK"))) {
+ strncpy(me.name, nickptr, NICKLEN);
+ } else
+#ifdef AUTOMATON
+ strncpy(me.name, a_myname(), NICKLEN);
+#else
+ strncpy(me.name, userdata->pw_name ,NICKLEN);
+#endif
+ }
+ me.name[NICKLEN] = '\0';
+ /* END FIX */
+
+ if (argv0[0] == ':') {
+ strcpy(me.sockhost, "OuluBox");
+ strncpy(me.info, &argv0[1], REALLEN);
+ strncpy(meUser.username, argv[1], USERLEN);
+ } else {
+ sprintf(me.sockhost, "%d", mode);
+ if ((cp = getenv("IRCNAME")))
+ strncpy(me.info, cp, REALLEN);
+ else if ((cp = getenv("NAME")))
+ strncpy(me.info, cp, REALLEN);
+ else {
+#ifdef AUTOMATON
+ strncpy(me.info, a_myreal(), REALLEN);
+#else
+ strncpy(me.info,real_name(userdata),REALLEN);
+#endif
+ if (me.info[0] == '\0')
+ strcpy(me.info, "*real name unknown*");
+ }
+#ifdef AUTOMATON
+ strncpy(meUser.username, a_myuser(), USERLEN);
+#else
+ strncpy(meUser.username,userdata->pw_name,USERLEN);
+#endif
+ }
+ meUser.server = mystrdup(me.sockhost);
+ meUser.username[USERLEN] = '\0';
+ me.info[REALLEN] = '\0';
+ me.fd = sock;
+#ifdef AUTOMATON
+ a_init();
+#endif
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ initscr();
+ signal(SIGINT, quit_intr);
+ signal(SIGTSTP, suspend_irc);
+ noecho();
+ crmode();
+ clear();
+ refresh();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM) {
+ printf("Io on !\n");
+ io_on(1);
+ clearscreen();
+ }
+#endif
+ if (me.passwd[0])
+ sendto_one(&me, "PASS %s", me.passwd);
+ sendto_one(&me, "NICK %s", me.name);
+ sendto_one(&me, "USER %s %s %s :%s", meUser.username,
+ me.sockhost, meUser.server, me.info);
+ querychannel = (char *)malloc(strlen(me.name) + 1);
+ strcpy(querychannel, me.name); /* Kludge? */
+ if (channel[0])
+ do_channel(channel, "JOIN");
+ myloop(sock);
+ if (logfile)
+ do_log(NULL, NULL);
+ printf("Press any key.");
+ refresh();
+ getchar();
+ printf("\n");
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ echo();
+ nocrmode();
+ endwin();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ io_off();
+#endif
+ apu = 0;
+ } while (unkill_flag && KillCount++ < KILLMAX);
+ exit(0);
+}
+
+void intr()
+{
+ if (logfile)
+ do_log(NULL, NULL);
+
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ echo();
+ nocrmode();
+ endwin();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ io_off();
+#endif
+ exit(0);
+}
+
+void myloop(sock)
+int sock;
+{
+ write_statusline();
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ put_statusline();
+#endif
+ client_loop(sock);
+}
+
+#define QUERYLEN 50
+
+static char cmdch = '/';
+static char queryuser[QUERYLEN+2] = "";
+
+void do_cmdch(ptr, temp)
+char *ptr, *temp;
+{
+ if (BadPtr(ptr)) {
+ putline("Error: Command character not changed");
+ return;
+ }
+ cmdch = *ptr;
+}
+
+void do_quote(ptr, temp)
+char *ptr, *temp;
+{
+ if (BadPtr(ptr)) {
+ putline("*** Error: Empty command");
+ return;
+ }
+ sendto_one(&me,"%s", ptr);
+}
+
+void do_query(ptr, temp)
+char *ptr, *temp;
+{
+ if (BadPtr(ptr)) {
+ sprintf(buf, "*** Ending a private chat with %s", queryuser);
+ putline(buf);
+ queryuser[0] = '\0';
+ } else {
+ strncpyzt(queryuser, ptr, QUERYLEN);
+ sprintf(buf, "*** Beginning a private chat with %s",
+ queryuser);
+ putline(buf);
+ }
+}
+
+void do_mypriv(buf1, buf2)
+char *buf1, *buf2;
+{
+ char *tmp = index(buf1, ' ');
+
+ if (tmp == NULL) {
+ putline("*** Error: Empty message not sent");
+ return;
+ }
+ if (buf1[0] == ',' && buf1[1] == ' ') {
+ sendto_one(&me, "PRIVMSG %s :%s", last_to_me(NULL), &buf1[2]);
+ last_from_me(last_to_me(NULL));
+ *(tmp++) = '\0';
+ sprintf(buf,"-> !!*%s* %s", last_to_me(NULL), tmp);
+ putline(buf);
+ } else if (buf1[0] == '.' && buf1[1] == ' ') {
+ sendto_one(&me, "PRIVMSG %s :%s", last_from_me(NULL), &buf1[2]);
+ *(tmp++) = '\0';
+ sprintf(buf,"-> ##*%s* %s", last_from_me(NULL), tmp);
+ putline(buf);
+ } else {
+ *(tmp++) = '\0';
+ sendto_one(&me, "PRIVMSG %s :%s", buf1, tmp);
+ last_from_me(buf1);
+ if (*buf1 == '#' || *buf1 == '&' || *buf1 == '+' || atoi(buf1))
+ sprintf(buf, "%s> %s", buf1, tmp);
+ else
+ sprintf(buf,"->%s> %s", buf1, tmp);
+ putline(buf);
+ }
+}
+
+void do_myqpriv(buf1, buf2)
+char *buf1, *buf2;
+{
+ if (BadPtr(buf1)) {
+ putline("*** Error: Empty message not sent");
+ return;
+ }
+ sendto_one(&me, "PRIVMSG %s :%s", queryuser, buf1);
+
+ sprintf(buf,"-> *%s* %s", queryuser, buf1);
+ putline(buf);
+}
+
+void do_mytext(buf1, temp)
+char *buf1, *temp;
+{
+ sendto_one(&me, "PRIVMSG %s :%s", querychannel, buf1);
+ sprintf(buf,"%s> %s", querychannel, buf1);
+ putline(buf);
+}
+
+void do_unkill(buf, temp)
+char *buf, *temp;
+{
+ if (unkill_flag)
+ unkill_flag = 0;
+ else
+ unkill_flag = 1;
+
+ sprintf(buf, "*** Unkill feature turned %s",
+ (unkill_flag) ? "on" : "off");
+ putline(buf);
+}
+
+void do_bye(buf, tmp)
+char *buf, *tmp;
+{
+ unkill_flag = 0;
+ sendto_one(&me, "%s :%s", tmp, buf);
+}
+
+/* KILL, PART, SQUIT, TOPIC "CMD PARA1 [:PARA2]" */
+void do_kill(buf1, tmp)
+char *buf1, *tmp;
+{
+ char *b2;
+
+ b2 = index(buf1, SPACE); /* find end of servername */
+ if (b2) /* comment */
+ {
+ *b2 = 0;
+ sendto_one(&me, "%s %s :%s", tmp, buf1, b2 + 1);
+ }
+ else
+ sendto_one(&me, "%s %s", tmp, buf1);
+ if (*tmp == 'P') { /* PART */
+ free(querychannel);
+ querychannel = (char *)malloc(strlen(me.name) + 1);
+ strcpy(querychannel, me.name); /* Kludge? */
+ }
+}
+
+/* "CMD PARA1 PARA2 [:PARA3]" */
+void do_kick(buf1, tmp)
+char *buf1, *tmp;
+{
+ char *b2, *b3 = NULL;
+
+ b2 = index(buf1, SPACE); /* find end of channel name */
+ if (b2)
+ b3 = index(b2 + 1, SPACE); /* find end of victim name */
+ if (b3)
+ {
+ *b3 = 0;
+ sendto_one(&me, "%s %s :%s", tmp, buf1, b3 + 1);
+ }
+ else
+ sendto_one(&me, "%s %s :No comment", tmp, buf1);
+}
+
+/* "CMD :PARA1" */
+void do_away(buf1, tmp)
+char *buf1, *tmp;
+{
+ sendto_one(&me, "%s :%s", tmp, buf1);
+}
+
+void do_server(buf, tmp)
+char *buf, *tmp;
+{
+ strncpyzt(currserver, buf, HOSTLEN);
+ unkill_flag -= 2;
+ sendto_one(&me,"QUIT");
+ close(sock);
+ QuitFlag = 1;
+}
+
+void sendit(line)
+char *line;
+{
+ char *ptr = NULL;
+ struct Command *cmd = commands;
+
+ KillCount = 0;
+ if (line[0] != cmdch) {
+ if (*queryuser)
+ do_myqpriv(line, NULL);
+ else
+ do_mytext(line, NULL);
+ return /* 0 */ ;
+ }
+ if (line[1] == ' ')
+ do_mytext(&line[2], NULL);
+ else if (line[1]) {
+ for ( ; cmd->name; cmd++)
+ if ((ptr = mycncmp(&line[1], cmd->name)))
+ break;
+ if (!cmd->name)
+ putline("*** Error: Unknown command");
+ else {
+ switch (cmd->type)
+ {
+ case SERVER_CMD:
+ sendto_one(&me, "%s %s", cmd->extra, ptr);
+ break;
+ case LOCAL_FUNC:
+ (*cmd->func)(ptr, cmd->extra);
+ return;
+ break;
+ default:
+ putline("*** Error: Data error in irc.h");
+ break;
+ }
+ }
+ }
+}
+
+char *mycncmp(str1, str2)
+char *str1, *str2;
+{
+ int flag = 0;
+ char *s1;
+
+ for (s1 = str1; *s1 != ' ' && *s1 && *str2; s1++, str2++) {
+ /* if (!isascii(*s1)) */
+ if (*s1 & 0x80)
+ return 0;
+ *s1 = toupper(*s1);
+ if (*s1 != *str2)
+ flag = 1;
+ }
+ if (*s1 && *s1 != ' ' && *str2 == '\0')
+ return 0;
+ if (flag)
+ return 0;
+ if (*s1)
+ return s1 + 1;
+ else
+ return s1;
+}
+
+void do_clear(buf, temp)
+char *buf, *temp;
+{
+#ifdef DOCURSES
+ char header[HEADERLEN];
+
+ if (termtype == CURSES_TERM) {
+ apu = 0;
+ sprintf(header, IRCHEADER ,version, me.name, currserver);
+ clear();
+ standout();
+ mvaddstr(LINES - 2, 0, header);
+ standend();
+ refresh();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ clearscreen();
+#endif
+}
+
+void putline(line)
+char *line;
+
+{
+ char *ptr, *ptr2;
+
+#ifdef DOCURSES
+ char ch='\0';
+ /* int pagelen = LINES - 3; not used -Armin */
+ int rmargin = COLS - 1;
+#endif
+
+ /*
+ ** This is a *safe* client--filter out all possibly dangerous
+ ** codes from the messages (this sets them as "_").
+ */
+ if (line)
+ for (ptr = line; *ptr; ptr++)
+ if ((*ptr < 32 && *ptr != 7 && *ptr != 9) ||
+ (*ptr > 126))
+ *ptr = '_';
+
+ ptr = line;
+
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ while (ptr) {
+
+/* first, see if we have to chop the string into pieces */
+
+ if (strlen(ptr) > (size_t) rmargin) {
+ ch = ptr[rmargin];
+ ptr[rmargin] = '\0';
+ ptr2 = &ptr[rmargin - 1];
+ }
+ else
+ ptr2 = NULL;
+
+/* move cursor to correct position and place line */
+
+ move(apu,0);
+ addstr(ptr);
+ if (logfile)
+ fprintf(logfile, "%s\n", ptr);
+
+/* now see if we are at the end of the page, and take action */
+
+#ifndef SCROLLINGCLIENT
+ /* clear one line. */
+ addstr("\n\n");
+ if (++apu > LINES - 4) {
+ apu = 0;
+ move(0,0);
+ clrtoeol();
+ }
+
+#else /* doesn't work, dumps core :-( */
+
+ if(++apu > LINES - 4) {
+ char header[HEADERLEN];
+ /* erase status line */
+ move(LINES - 2, 0 );
+ clrtobot();
+ refresh();
+ /* scroll screen */
+ scrollok(stdscr,TRUE);
+ move(LINES - 1, 0 );
+ addstr("\n\n\n\n");
+ refresh();
+ apu -= 4;
+ /* redraw status line */
+ sprintf(header, IRCHEADER, version,
+ me.name, currserver);
+ standout();
+ mvaddstr(LINES - 2, 0, header);
+ standend();
+ tulosta_viimeinen_rivi();
+ } else
+ addstr( "\n\n" );
+#endif
+
+/* finally, if this is a multiple-line line, munge things up so that
+ we print the next line. overwrites the end of the previous line. */
+
+ ptr = ptr2;
+ if (ptr2) {
+ *ptr2++ = '+';
+ *ptr2 = ch;
+ }
+ }
+ refresh();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ tcap_putline(line);
+#endif
+#ifdef AUTOMATON
+ puts(line);
+#endif
+}
+
+int unixuser()
+{
+ return(!StrEq(me.sockhost,"OuluBox"));
+}
+
+void do_log(ptr, temp)
+char *ptr, *temp;
+{
+ time_t tloc;
+ char buf[150];
+ char *ptr2;
+
+ if (!unixuser())
+ return;
+ if (!logfile) { /* logging currently off */
+ if (BadPtr(ptr))
+ putline("*** You must specify a filename to log to.");
+ else {
+ if (!(logfile = fopen(ptr, "a"))) {
+ sprintf(buf,
+ "*** Error: Can't open log file %s.\n",
+ ptr);
+ putline(buf);
+ } else {
+#if defined(HPUX) || defined(SVR3) || defined(SVR4)
+ setvbuf(logfile,logbuf,_IOLBF,sizeof(logbuf));
+#else
+# if !defined(_SEQUENT_) && !defined(SVR4)
+ setlinebuf(logfile);
+# endif
+#endif
+ time(&tloc);
+ sprintf(buf,
+ "*** IRC session log started at %s",
+ ctime(&tloc));
+ ptr2 = rindex(buf, '\n');
+ *ptr2 = '.';
+ putline(buf);
+ }
+ }
+ } else { /* logging currently on */
+ if (BadPtr(ptr)) {
+
+ time(&tloc);
+ sprintf(buf, "*** IRC session log ended at %s",
+ ctime(&tloc));
+ ptr2 = rindex(buf, '\n');
+ *ptr2 = '.';
+ putline(buf);
+ fclose(logfile);
+ logfile = NULL;
+ } else
+ putline("*** Your session is already being logged.");
+ }
+}
+
+/* remember the commas */
+#define LASTKEEPLEN (MAXRECIPIENTS * (NICKLEN+1))
+
+char *last_to_me(sender)
+char *sender;
+{
+ static char name[LASTKEEPLEN+1] = ",";
+
+ if (sender)
+ strncpyzt(name, sender, sizeof(name));
+
+ return (name);
+}
+
+char *last_from_me(recipient)
+char *recipient;
+{
+ static char name[LASTKEEPLEN+1] = ".";
+
+ if (recipient)
+ strncpyzt(name, recipient, sizeof(name));
+
+ return (name);
+}
+
+/*
+ * Left out until it works with VMS as well..
+ */
+
+#ifdef GETPASS
+do_oper(ptr, xtra)
+char *ptr, *xtra;
+{
+ extern char *getmypass();
+
+ if (BadPtr(ptr))
+ ptr = getmypass("Enter nick & password: ");
+
+ sendto_one(&me, "%s %s", xtra, ptr);
+}
+#endif
+
+/* Fake routine (it's only in server...) */
+
+void do_channel(ptr, xtra)
+char *ptr, *xtra;
+{
+ char *p1;
+
+ if (BadPtr(ptr)) {
+ putline("*** Which channel do you want to join?");
+ return;
+ }
+
+ free((char *)querychannel);
+
+ if ((querychannel = (char *)malloc(strlen(ptr) + 1)))
+ {
+ /* Copy only channel name from *ptr -Vesa */
+ strcpy(buf, ptr);
+ if ((p1 = index(buf, ' ')))
+ *p1 = '\0';
+ if ((p1 = rindex(buf, ','))) /* The last channel */
+ strcpy(querychannel, p1 + 1);
+ else /* The only channel */
+ strcpy(querychannel, buf);
+ }
+ else
+ printf("Blah! Out of memory?\n");
+
+ sendto_one(&me, "%s %s", xtra, ptr);
+}
+
+void write_statusline()
+{
+#ifdef DOCURSES
+ char header[HEADERLEN];
+
+ if (termtype == CURSES_TERM) {
+ sprintf(header, IRCHEADER, version, me.name, currserver);
+ standout();
+ mvaddstr(LINES - 2, 0, header);
+ standend();
+ }
+#endif
+}
+
+RETSIGTYPE quit_intr(s)
+int s;
+{
+ signal(SIGINT, SIG_IGN);
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ clear();
+ refresh();
+ echo();
+ nocrmode();
+ endwin();
+ }
+#endif
+ exit(0);
+}
diff --git a/irc/irc_def.h b/irc/irc_def.h
new file mode 100644
index 0000000..26f7a6c
--- /dev/null
+++ b/irc/irc_def.h
@@ -0,0 +1,29 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/irc_def.h
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+struct Command {
+ void (*func)();
+ char *name;
+ int type;
+ char keybinding[3];
+ char *extra; /* Normally contains the command to send to irc daemon */
+};
+
+#define SERVER_CMD 0
+#define LOCAL_FUNC 1
diff --git a/irc/irc_ext.h b/irc/irc_ext.h
new file mode 100644
index 0000000..4ef47a8
--- /dev/null
+++ b/irc/irc_ext.h
@@ -0,0 +1,84 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/irc_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/irc.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef IRC_C
+extern struct Command commands[];
+extern char irc_id[];
+extern aChannel *channel;
+extern aClient me, *client;
+extern anUser meUser;
+extern FILE *logfile;
+extern char buf[];
+extern char *querychannel;
+extern int portnum, termtype;
+extern int debuglevel;
+extern int unkill_flag, cchannel;
+extern int QuitFlag;
+#if defined(HPUX) || defined(SVR3) || defined(SVR4)
+extern char logbuf[];
+#endif
+#ifdef MAIL50
+extern int ucontext, perslength;
+extern char persname[];
+extern struct itmlst null_list[];
+#endif
+#endif /* IRC_C */
+
+/* External definitions for global functions.
+ */
+#ifndef IRC_C
+#define EXTERN extern
+#else /* IRC_C */
+#define EXTERN
+#endif /* IRC_C */
+EXTERN void intr();
+EXTERN void myloop __P((int sock));
+EXTERN void do_cmdch __P((char *ptr, char *temp));
+EXTERN void do_quote __P((char *ptr, char *temp));
+EXTERN void do_query __P((char *ptr, char *temp));
+EXTERN void do_mypriv __P((char *buf1, char *buf2));
+EXTERN void do_myqpriv __P((char *buf1, char *buf2));
+EXTERN void do_mytext __P((char *buf1, char *temp));
+EXTERN void do_unkill __P((char *buf, char *temp));
+EXTERN void do_bye __P((char *buf, char *tmp));
+EXTERN void do_kill __P((char *buf1, char *tmp));
+EXTERN void do_kick __P((char *buf1, char *tmp));
+EXTERN void do_away __P((char *buf1, char *tmp));
+EXTERN void do_server __P((char *buf, char *tmp));
+EXTERN void sendit __P((char *line));
+EXTERN char *mycncmp __P((char *str1, char *str2));
+EXTERN void do_clear __P((char *buf, char *temp));
+EXTERN void putline __P((char *line));
+EXTERN int unixuser();
+EXTERN void do_log __P((char *ptr, char *temp));
+EXTERN char *last_to_me __P((char *sender));
+EXTERN char *last_from_me __P((char *recipient));
+#ifdef GETPASS
+EXTERN do_oper __P((char *ptr, char *xtra));
+#endif
+EXTERN void do_channel __P((char *ptr, char *xtra));
+EXTERN void write_statusline();
+EXTERN RETSIGTYPE quit_intr __P((int s));
+#undef EXTERN
diff --git a/irc/screen.c b/irc/screen.c
new file mode 100644
index 0000000..01afa11
--- /dev/null
+++ b/irc/screen.c
@@ -0,0 +1,287 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/screen.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: screen.c,v 1.2 1997/09/03 17:45:42 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define SCREEN_C
+#include "c_externs.h"
+#undef SCREEN_C
+
+#define SBUFSIZ 240
+
+#define FROM_START 0
+#define FROM_END 1
+#define RELATIVE 2
+
+#define HIST_SIZ 1000
+
+static char last_line[SBUFSIZ+1];
+static char yank_buffer[SBUFSIZ+1];
+static char history[HIST_SIZ][SBUFSIZ+1];
+static int position = 0;
+static int pos_in_history = 0;
+
+int insert = 1; /* default to insert mode */
+ /* I want insert mode, thazwhat emacs does ! //jkp */
+
+int get_char(pos)
+int pos;
+{
+ if (pos>=SBUFSIZ || pos<0)
+ return 0;
+ return (int)last_line[pos];
+}
+
+void set_char(pos, ch)
+int pos, ch;
+{
+ if (pos<0 || pos>=SBUFSIZ)
+ return;
+ if (ch<0)
+ ch=0;
+ last_line[pos]=(char)ch;
+}
+
+int get_yank_char(pos)
+int pos;
+{
+ if (pos>=SBUFSIZ || pos<0)
+ return 0;
+ return (int)yank_buffer[pos];
+}
+
+void set_yank_char(pos, ch)
+int pos, ch;
+{
+ if (pos<0 || pos>=SBUFSIZ)
+ return;
+ if (ch<0)
+ ch=0;
+ yank_buffer[pos]=(char)ch;
+}
+
+void set_position(disp, from)
+int disp, from;
+{
+ int i1;
+
+ switch (from) {
+ case FROM_START:
+ position=disp;
+ break;
+ case RELATIVE:
+ position+=disp;
+ break;
+ case FROM_END:
+ for (i1=0; get_char(i1); i1++);
+ position=i1-1;
+ break;
+ default:
+ position=0;
+ break;
+ }
+}
+
+int get_position()
+{
+ return position;
+}
+
+void toggle_ins()
+{
+ insert = !insert;
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ standout();
+ if (insert)
+ mvaddstr(LINES-2, 75, "INS");
+ else
+ mvaddstr(LINES-2, 75, "OWR");
+ standend();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM)
+ put_insflag(insert);
+#endif
+}
+
+int in_insert_mode()
+{
+ return insert;
+}
+
+void send_this_line()
+{
+ record_line();
+ sendit(last_line);
+ clear_last_line();
+ bol();
+ tulosta_viimeinen_rivi();
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM)
+ refresh();
+#endif
+}
+
+void record_line()
+{
+ static int place=0;
+ int i1;
+
+ for(i1=0; i1<SBUFSIZ; i1++)
+ history[place][i1]=get_char(i1);
+ place++;
+ if (place==HIST_SIZ)
+ place=0;
+ pos_in_history=place;
+}
+
+void clear_last_line()
+{
+ int i1;
+
+ for(i1=0; i1<SBUFSIZ; i1++)
+ set_char(i1,(int)'\0');
+}
+
+void kill_eol()
+{
+ int i1, i2, i3;
+
+ i1=get_position();
+ set_position(0, FROM_END);
+ i2=get_position();
+ for(i3=0; i3<SBUFSIZ; i3++)
+ set_yank_char(i3,(int)'\0');
+ for(i3=0; i3<=(i2-i1); i3++) {
+ set_yank_char(i3,get_char(i1+i3));
+ set_char(i1+i3, 0);
+ }
+ set_position(i1, FROM_START);
+}
+
+void next_in_history()
+{
+ int i1;
+
+ pos_in_history++;
+ if (pos_in_history==HIST_SIZ)
+ pos_in_history=0;
+ clear_last_line();
+
+ for (i1 = 0; history[pos_in_history][i1]; i1++)
+ set_char(i1, history[pos_in_history][i1]);
+
+ set_position(0, FROM_START);
+}
+
+void previous_in_history()
+{
+ int i1;
+
+ pos_in_history--;
+ if (pos_in_history<0)
+ pos_in_history=HIST_SIZ-1;
+ clear_last_line();
+ for (i1=0; history[pos_in_history][i1]; i1++)
+ set_char(i1, history[pos_in_history][i1]);
+
+ set_position(0, FROM_START);
+}
+
+void kill_whole_line()
+{
+ clear_last_line();
+ set_position(0, FROM_START);
+}
+
+void yank()
+{
+ int i1, i2, i3;
+
+ i1=get_position();
+ i2=0;
+ while (get_yank_char(i2))
+ i2++;
+
+ for(i3=SBUFSIZ-1; i3>=i1+i2; i3--)
+ set_char(i3, get_char(i3-i2));
+ for(i3=0; i3<i2; i3++)
+ set_char(i1+i3, get_yank_char(i3));
+}
+
+int tulosta_viimeinen_rivi()
+{
+ static int paikka=0;
+ int i1, i2, i3;
+
+ i1=get_position();
+ /* taytyyko siirtaa puskuria */
+ if (i1<(get_disp(paikka)+10) && paikka) {
+ paikka--;
+ i2=get_disp(paikka);
+ } else if (i1>(get_disp(paikka)+70)) {
+ paikka++;
+ i2=get_disp(paikka);
+ } else {
+ i2=get_disp(paikka);
+ }
+
+#ifdef DOCURSES
+ if (termtype == CURSES_TERM) {
+ move(LINES-1,0);
+ for(i3=0; i3<78; i3++)
+ if (get_char(i2+i3))
+ mvaddch(LINES-1, i3, get_char(i2+i3));
+ clrtoeol();
+ move(LINES-1, i1-get_disp(paikka));
+ refresh();
+ }
+#endif
+#ifdef DOTERMCAP
+ if (termtype == TERMCAP_TERM) {
+ tcap_move(-1, 0);
+ for(i3=0; i3<78; i3++)
+ if (get_char(i2+i3))
+/* tcap_putch(LINES-1, i3, get_char(i2+i3)); */
+ tcap_putch(-1, i3, get_char(i2+i3));
+/* clear_to_eol(); */
+ clear_to_eol(-1, 78);
+ tcap_move(-1, i1-get_disp(paikka));
+/* refresh(); */
+ }
+#endif
+ return (i1-get_disp(paikka));
+}
+
+int get_disp(paikka)
+int paikka;
+{
+ static int place[]={0,55,110,165,220};
+
+ if (paikka>4 || paikka<0)
+ return 0;
+ return place[paikka];
+}
diff --git a/irc/screen_ext.h b/irc/screen_ext.h
new file mode 100644
index 0000000..5dfd792
--- /dev/null
+++ b/irc/screen_ext.h
@@ -0,0 +1,56 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/screen_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/screen.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef SCREEN_C
+extern char screen_id[];
+extern int insert;
+#endif /* SCREEN_C */
+
+/* External definitions for global functions.
+ */
+#ifndef SCREEN_C
+#define EXTERN extern
+#else /* SCREEN_C */
+#define EXTERN
+#endif /* SCREEN_C */
+EXTERN int get_char __P((int pos));
+EXTERN void set_char __P((int pos, int ch));
+EXTERN int get_yank_char __P((int pos));
+EXTERN void set_yank_char __P((int pos, int ch));
+EXTERN void set_position __P((int disp, int from));
+EXTERN int get_position();
+EXTERN void toggle_ins();
+EXTERN int in_insert_mode();
+EXTERN void send_this_line();
+EXTERN void record_line();
+EXTERN void clear_last_line();
+EXTERN void kill_eol();
+EXTERN void next_in_history();
+EXTERN void previous_in_history();
+EXTERN void kill_whole_line();
+EXTERN void yank();
+EXTERN int tulosta_viimeinen_rivi();
+EXTERN int get_disp __P((int paikka));
+#undef EXTERN
diff --git a/irc/str.c b/irc/str.c
new file mode 100644
index 0000000..aaff546
--- /dev/null
+++ b/irc/str.c
@@ -0,0 +1,84 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/str.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: str.c,v 1.2 1997/09/03 17:45:43 kalt Exp $";
+#endif
+
+#include "os.h"
+#include "c_defines.h"
+#define STR_C
+#include "c_externs.h"
+#undef STR_C
+
+char * center(buf,str,len)
+char *buf, *str;
+int len;
+{
+ char i,j,k;
+ if ((i = strlen(str)) > len) {
+ buf[len-1] = '\0';
+ for(len--; len > 0; len--) buf[len-1] = str[len-1];
+ return(buf);
+ }
+ j = (len-i)/2;
+ for (k=0; k<j; k++) buf[k] = ' ';
+ buf[k] = '\0';
+ strcat(buf,str);
+ for (k=j+i; k<len; k++) buf[k] = ' ';
+ buf[len] = '\0';
+ return (buf);
+}
+
+/* William Wisner <wisner@b.cc.umich.edu>, 16 March 1989 */
+char *
+real_name(user)
+ struct passwd *user;
+{
+ char *bp, *cp;
+ static char name[REALLEN+1];
+
+ bp = user->pw_gecos;
+ cp = name;
+
+ name[REALLEN] = '\0';
+ do {
+ switch(*bp) {
+ case '&':
+ *cp = '\0';
+ strncat(name, user->pw_name, REALLEN-strlen(name));
+ name[REALLEN] = '\0';
+ *cp = toupper(*cp);
+ cp = index(name, '\0');
+ bp++;
+ break;
+ case ',':
+ *bp = *cp = '\0';
+ break;
+ case '\0':
+ *cp = *bp;
+ break;
+ default:
+ *cp++ = *bp++;
+ }
+ } while (*bp != '\0' && strlen(name) < (size_t) REALLEN);
+ return(name);
+}
+
diff --git a/irc/str_ext.h b/irc/str_ext.h
new file mode 100644
index 0000000..6198141
--- /dev/null
+++ b/irc/str_ext.h
@@ -0,0 +1,39 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/str_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/str.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef STR_C
+extern char str_id[];
+#endif /* STR_C */
+
+/* External definitions for global functions.
+ */
+#ifndef STR_C
+#define EXTERN extern
+#else /* STR_C */
+#define EXTERN
+#endif /* STR_C */
+EXTERN char *center __P((char *buf, char *str, int len));
+EXTERN char *real_name __P((struct passwd *user));
+#undef EXTERN
diff --git a/irc/swear.c b/irc/swear.c
new file mode 100644
index 0000000..9c8b2a6
--- /dev/null
+++ b/irc/swear.c
@@ -0,0 +1,216 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/swear.c
+ * Copyright (C) 1990 Jarkko Oikarinen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef lint
+static char rcsid[] = "@(#)$Id: swear.c,v 1.4 1998/12/13 00:02:35 kalt Exp $";
+#endif
+
+/* Curses replacement routines. Uses termcap */
+
+#include "os.h"
+#include "c_defines.h"
+#define SWEAR_C
+#include "c_externs.h"
+#undef SWEAR_C
+
+#define LLEN 60
+
+#ifdef DOTERMCAP
+
+static struct sgttyb oldtty, newtty;
+static char termcapentry[1024];
+static char codes[1024], *cls;
+
+static char *irc_termname;
+
+static int currow = 0;
+int irc_lines, irc_columns, scroll_ok = 0, scroll_status = 0;
+
+void tcap_putch(row, col, ch)
+int row, col;
+char ch;
+{
+ tcap_move(row, col);
+ putchar(ch);
+ fflush(stdout);
+}
+
+void tcap_move(row, col)
+int row, col;
+{
+ cls = codes;
+ tgetstr("cm",&cls);
+ if (row < 0)
+ row = irc_lines - row;
+ cls = tgoto(codes, col, row);
+ printf("%s",cls);
+ fflush(stdout);
+}
+
+void clear_to_eol(row, col)
+int row, col;
+{
+ tcap_move(row, col);
+ cls = codes;
+ tgetstr("ce", &cls);
+ printf("%s",codes);
+ fflush(stdout);
+}
+
+void clearscreen()
+{
+ cls = codes;
+ tgetstr("cl",&cls);
+ printf("%s",codes);
+ fflush(stdout);
+ currow = 0;
+}
+
+int
+io_on(flag)
+int flag;
+{
+/* if (ioctl(0, TIOCGETP, &oldtty) == -1) {
+ perror("ioctl");
+ return(-1);
+ }
+ newtty = oldtty;
+ newtty.sg_flags &= ~ECHO;
+ newtty.sg_flags |= CBREAK;
+ ioctl(0, TIOCSETP, &newtty); */
+ system("stty -echo cbreak");
+ if (tgetent(termcapentry,irc_termname=getenv("TERM")) != 1) {
+ printf("Cannot find termcap entry !\n");
+ fflush(stdout);
+ }
+ printf("TERMCAP=%s\n",termcapentry);
+ irc_lines = tgetnum("li");
+ irc_columns = tgetnum("co");
+ return(0);
+}
+
+int
+io_off()
+{
+ if (scroll_ok)
+ scroll_ok_off();
+ if (ioctl(0, TIOCSETP, &oldtty) < 0)
+ return(-1);
+ return(0);
+}
+
+void scroll_ok_off()
+{
+ cls = codes;
+ tgetstr("cs",&cls);
+ cls = tgoto(codes, irc_lines-1, 0);
+ printf("%s",cls);
+ scroll_ok = 0;
+}
+
+void scroll_ok_on()
+{
+ cls = codes;
+ tgetstr("cm",&cls);
+ cls = tgoto(codes, 0, 0);
+ printf("%s",cls);
+ cls = codes;
+ tgetstr("cs",&cls);
+ cls = tgoto(codes, irc_lines-3, 0);
+ printf("%s",cls);
+ fflush(stdout);
+ scroll_ok = scroll_status = 1;
+}
+
+void put_insflag(flag)
+int flag;
+{
+ flag = insert;
+ tcap_move(-2, irc_columns - 5);
+ cls = codes;
+ tgetstr("mr",&cls);
+ printf("%s",codes);
+ printf((flag) ? "INS" : "OWR");
+ cls = codes;
+ tgetstr("me",&cls);
+ printf("%s",codes);
+ fflush(stdout);
+}
+
+void put_statusline()
+{
+ tcap_move (-2, 0);
+ cls = codes;
+ tgetstr("mr",&cls);
+ printf("%s",codes);
+ printf(IRCHEADER, version);
+ cls = codes;
+ tgetstr("me",&cls);
+ printf("%s",codes);
+ fflush(stdout);
+}
+
+void tcap_putline(line)
+char *line;
+{
+ char *ptr = line, *ptr2, *newl;
+ char ch='\0';
+ while (ptr) {
+ if (strlen(ptr) > irc_columns-1) {
+ ch = ptr[irc_columns-1];
+ ptr[irc_columns-1] = '\0';
+ ptr2 = &ptr[irc_columns-2];
+ }
+ else
+ ptr2 = NULL;
+ if (scroll_ok) {
+ tcap_move(irc_lines-3, 0);
+ } else {
+ tcap_move(currow++,0);
+ if (currow > irc_lines - 4) currow = 0;
+ }
+ while (newl = index(ptr,'\n'))
+ *newl = '\0';
+ printf("%s",ptr);
+ if (scroll_ok)
+ printf("\n",ptr);
+ else {
+ if (currow == 0) {
+ clear_to_eol(1,0);
+ clear_to_eol(2,0);
+ }
+ else if (currow == irc_lines - 4) {
+ clear_to_eol(irc_lines-4,0);
+ clear_to_eol(0,0);
+ }
+ else {
+ clear_to_eol(currow+1,0);
+ clear_to_eol(currow+2,0);
+ }
+ }
+ ptr = ptr2;
+ if (ptr2) {
+ *ptr2++ = '+';
+ *ptr2 = ch;
+ }
+ }
+ fflush(stdout);
+}
+
+#endif /* DO_TERMCAP */
diff --git a/irc/swear_ext.h b/irc/swear_ext.h
new file mode 100644
index 0000000..ce1c85e
--- /dev/null
+++ b/irc/swear_ext.h
@@ -0,0 +1,53 @@
+/************************************************************************
+ * IRC - Internet Relay Chat, irc/swear_ext.h
+ * Copyright (C) 1997 Alain Nissen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 1, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* This file contains external definitions for global variables and functions
+ defined in irc/swear.c.
+ */
+
+/* External definitions for global variables.
+ */
+#ifndef SWEAR_C
+#ifdef DOTERMCAP
+extern char swear_id[];
+extern int irc_lines, irc_columns, scroll_ok, scroll_status;
+#endif
+#endif /* SWEAR_C */
+
+/* External definitions for global functions.
+ */
+#ifndef SWEAR_C
+#define EXTERN extern
+#else /* SWEAR_C */
+#define EXTERN
+#endif /* SWEAR_C */
+#ifdef DOTERMCAP
+EXTERN void tcap_putch __P((int row, int col, char ch));
+EXTERN void tcap_move __P((int row, int col));
+EXTERN void clear_to_eol __P((int row, int col));
+EXTERN void clearscreen();
+EXTERN int io_on __P((int flag));
+EXTERN int io_off();
+EXTERN void scroll_ok_off();
+EXTERN void scroll_ok_on();
+EXTERN void put_insflag __P((int flag));
+EXTERN void put_statusline();
+EXTERN void tcap_putline __P((char *line));
+#endif
+#undef EXTERN