This commit is contained in:
2023-12-26 16:40:53 -05:00
commit ab64084f63
93 changed files with 40857 additions and 0 deletions

622
include/struct.h Normal file
View File

@@ -0,0 +1,622 @@
/************************************************************************
* IRC - Internet Relay Chat, include/struct.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.
*/
#ifndef __struct_include__
#define __struct_include__
#include "config.h"
#include "common.h"
#include "sys.h"
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef STDDEFH
# include <stddef.h>
#endif
#ifdef USE_SYSLOG
# include <syslog.h>
# ifdef SYSSYSLOGH
# include <sys/syslog.h>
# endif
#endif
#ifdef pyr
#include <sys/time.h>
#endif
typedef struct ConfItem aConfItem;
typedef struct Gline aGline;
typedef struct Client aClient;
typedef struct Channel aChannel;
typedef struct User anUser;
typedef struct Server aServer;
typedef struct SLink Link;
typedef struct SMode Mode;
typedef struct DSlink Dlink;
#ifndef VMSP
#include "class.h"
#include "dbuf.h" /* THIS REALLY SHOULDN'T BE HERE!!! --msa */
#endif
#define HOSTLEN 63 /* Length of hostname. Updated to */
/* comply with RFC1123 */
#define NICKLEN 9 /* Necessary to put 9 here instead of 10
** if s_msg.c/m_nick has been corrected.
** This preserves compatibility with old
** servers --msa
*/
#define USERLEN 10
#define REALLEN 50
#define TOPICLEN 160
#define CHANNELLEN 200
#define PASSWDLEN 20
#define KEYLEN 23
#define BUFSIZE 512 /* WARNING: *DONT* CHANGE THIS!!!! */
#define MAXRECIPIENTS 20
#define MAXBANS 30
#define MAXBANLENGTH 1024
#define MAXSILELENGTH 128
#define USERHOST_REPLYLEN (NICKLEN+HOSTLEN+USERLEN+5)
#ifdef USE_SERVICES
#include "service.h"
#endif
/*
** 'offsetof' is defined in ANSI-C. The following definition
** is not absolutely portable (I have been told), but so far
** it has worked on all machines I have needed it. The type
** should be size_t but... --msa
*/
#ifndef offsetof
#define offsetof(t,m) (int)((&((t *)0L)->m))
#endif
#define elementsof(x) (sizeof(x)/sizeof(x[0]))
/*
** flags for bootup options (command line flags)
*/
#define BOOT_CONSOLE 1
#define BOOT_QUICK 2
#define BOOT_DEBUG 4
#define BOOT_INETD 8
#define BOOT_TTY 16
#define BOOT_OPER 32
#define BOOT_AUTODIE 64
#define STAT_PING -7
#define STAT_LOG -6 /* logfile for -x */
#define STAT_MASTER -5 /* Local ircd master before identification */
#define STAT_CONNECTING -4
#define STAT_HANDSHAKE -3
#define STAT_ME -2
#define STAT_UNKNOWN -1
#define STAT_SERVER 0
#define STAT_CLIENT 1
#define STAT_SERVICE 2 /* Services not implemented yet */
/*
* status macros.
*/
#define IsRegisteredUser(x) ((x)->status == STAT_CLIENT)
#define IsRegistered(x) ((x)->status >= STAT_SERVER)
#define IsConnecting(x) ((x)->status == STAT_CONNECTING)
#define IsHandshake(x) ((x)->status == STAT_HANDSHAKE)
#define IsMe(x) ((x)->status == STAT_ME)
#define IsUnknown(x) ((x)->status == STAT_UNKNOWN || \
(x)->status == STAT_MASTER)
#define IsServer(x) ((x)->status == STAT_SERVER)
#define IsClient(x) ((x)->status == STAT_CLIENT)
#define IsLog(x) ((x)->status == STAT_LOG)
#define IsService(x) ((x)->status == STAT_SERVICE)
#define IsPing(x) ((x)->status == STAT_PING)
#define SetMaster(x) ((x)->status = STAT_MASTER)
#define SetConnecting(x) ((x)->status = STAT_CONNECTING)
#define SetHandshake(x) ((x)->status = STAT_HANDSHAKE)
#define SetMe(x) ((x)->status = STAT_ME)
#define SetUnknown(x) ((x)->status = STAT_UNKNOWN)
#define SetServer(x) ((x)->status = STAT_SERVER)
#define SetClient(x) ((x)->status = STAT_CLIENT)
#define SetLog(x) ((x)->status = STAT_LOG)
#define SetService(x) ((x)->status = STAT_SERVICE)
#define SetPing(x) ((x)->status = STAT_PING)
#define FLAGS_PINGSENT 0x0001 /* Unreplied ping sent */
#define FLAGS_DEADSOCKET 0x0002 /* Local socket is dead--Exiting soon */
#define FLAGS_KILLED 0x0004 /* Prevents "QUIT" from being sent for this */
#define FLAGS_OPER 0x0008 /* Operator */
#define FLAGS_LOCOP 0x0010 /* Local operator -- SRB */
#define FLAGS_INVISIBLE 0x0020 /* makes user invisible */
#define FLAGS_WALLOP 0x0040 /* send wallops to them */
#define FLAGS_SERVNOTICE 0x0080 /* server notices such as kill */
#define FLAGS_BLOCKED 0x0100 /* socket is in a blocked condition */
#define FLAGS_UNIX 0x0200 /* socket is in the unix domain, not inet */
#define FLAGS_CLOSING 0x0400 /* set when closing to suppress errors */
#define FLAGS_LISTEN 0x0800 /* used to mark clients which we listen() on */
#define FLAGS_CHKACCESS 0x1000 /* ok to check clients access if set */
#define FLAGS_DOINGDNS 0x2000 /* client is waiting for a DNS response */
#define FLAGS_AUTH 0x4000 /* client is waiting on rfc931 response */
#define FLAGS_WRAUTH 0x8000 /* set if we havent writen to ident server */
#define FLAGS_LOCAL 0x10000 /* set for local clients */
#define FLAGS_GOTID 0x20000 /* successful ident lookup achieved */
#define FLAGS_DOID 0x40000 /* I-lines say must use ident return */
#define FLAGS_NONL 0x80000 /* No \n in buffer */
#define FLAGS_TS8 0x100000 /* Why do you want to know? */
#define FLAGS_PING 0x200000 /* Socket is waiting for udp ping response */
#define FLAGS_ASKEDPING 0x400000 /* Client asked for udp ping */
#define FLAGS_MAP 0x800000 /* Show server on the map */
#define FLAGS_JUNCTION 0x1000000 /* Junction causing the net.burst */
#define FLAGS_DEAF 0x2000000 /* Makes user deaf */
#define FLAGS_NOKICK 0x4000000 /* prevents the possibility of KICK or MODE
-o on the user; can only be set by server
connections, not by local users */
#define SEND_UMODES (FLAGS_INVISIBLE|FLAGS_OPER|FLAGS_WALLOP|FLAGS_DEAF|FLAGS_NOKICK)
#define ALL_UMODES (SEND_UMODES|FLAGS_SERVNOTICE|FLAGS_LOCOP)
/* FLAGS_LOCOP was originally left out; this was a bug */
#define FLAGS_ID (FLAGS_DOID|FLAGS_GOTID)
/*
* flags macros.
*/
#define IsOper(x) ((x)->flags & FLAGS_OPER)
#define IsLocOp(x) ((x)->flags & FLAGS_LOCOP)
#define IsInvisible(x) ((x)->flags & FLAGS_INVISIBLE)
#define IsDeaf(x) ((x)->flags & FLAGS_DEAF)
#define IsAnOper(x) ((x)->flags & (FLAGS_OPER|FLAGS_LOCOP))
#define IsPerson(x) ((x)->user && IsClient(x))
#define IsPrivileged(x) (IsAnOper(x) || IsServer(x))
#define SendWallops(x) ((x)->flags & FLAGS_WALLOP)
#define SendServNotice(x) ((x)->flags & FLAGS_SERVNOTICE)
#define IsUnixSocket(x) ((x)->flags & FLAGS_UNIX)
#define IsListening(x) ((x)->flags & FLAGS_LISTEN)
#define DoAccess(x) ((x)->flags & FLAGS_CHKACCESS)
#define IsLocal(x) ((x)->flags & FLAGS_LOCAL)
#define IsDead(x) ((x)->flags & FLAGS_DEADSOCKET)
#define IsJunction(x) ((x)->flags & FLAGS_JUNCTION)
#define SetOper(x) ((x)->flags |= FLAGS_OPER)
#define SetLocOp(x) ((x)->flags |= FLAGS_LOCOP)
#define SetInvisible(x) ((x)->flags |= FLAGS_INVISIBLE)
#define SetWallops(x) ((x)->flags |= FLAGS_WALLOP)
#define SetUnixSock(x) ((x)->flags |= FLAGS_UNIX)
#define SetDNS(x) ((x)->flags |= FLAGS_DOINGDNS)
#define DoingDNS(x) ((x)->flags & FLAGS_DOINGDNS)
#define SetAccess(x) ((x)->flags |= FLAGS_CHKACCESS)
#define DoingAuth(x) ((x)->flags & FLAGS_AUTH)
#define NoNewLine(x) ((x)->flags & FLAGS_NONL)
#define DoPing(x) ((x)->flags & FLAGS_PING)
#define SetAskedPing(x) ((x)->flags |= FLAGS_ASKEDPING)
#define AskedPing(x) ((x)->flags & FLAGS_ASKEDPING)
#define SetJunction(x) ((x)->flags |= FLAGS_JUNCTION)
#define ClearOper(x) ((x)->flags &= ~FLAGS_OPER)
#define ClearInvisible(x) ((x)->flags &= ~FLAGS_INVISIBLE)
#define ClearWallops(x) ((x)->flags &= ~FLAGS_WALLOP)
#define ClearDNS(x) ((x)->flags &= ~FLAGS_DOINGDNS)
#define ClearAuth(x) ((x)->flags &= ~FLAGS_AUTH)
#define ClearAccess(x) ((x)->flags &= ~FLAGS_CHKACCESS)
#define ClearPing(x) ((x)->flags &= ~FLAGS_PING)
#define ClearAskedPing(x) ((x)->flags &= ~FLAGS_ASKEDPING)
/*
* defined debugging levels
*/
#define DEBUG_FATAL 0
#define DEBUG_ERROR 1 /* report_error() and other errors that are found */
#define DEBUG_NOTICE 3
#define DEBUG_DNS 4 /* used by all DNS related routines - a *lot* */
#define DEBUG_INFO 5 /* general usful info */
#define DEBUG_NUM 6 /* numerics */
#define DEBUG_SEND 7 /* everything that is sent out */
#define DEBUG_DEBUG 8 /* anything to do with debugging, ie unimportant :) */
#define DEBUG_MALLOC 9 /* malloc/free calls */
#define DEBUG_LIST 10 /* debug list use */
/*
* defines for curses in client
*/
#define DUMMY_TERM 0
#define CURSES_TERM 1
#define TERMCAP_TERM 2
struct ConfItem {
unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
int clients; /* Number of *LOCAL* clients using this */
struct in_addr ipnum; /* ip number of host field */
char *host;
char *passwd;
char *name;
int port;
time_t hold; /* Hold action until this time (calendar time) */
#ifndef VMSP
aClass *class; /* Class of connection */
#endif
struct ConfItem *next;
};
#define CONF_ILLEGAL 0x80000000
#define CONF_MATCH 0x40000000
#define CONF_QUARANTINED_SERVER 0x0001
#define CONF_CLIENT 0x0002
#define CONF_CONNECT_SERVER 0x0004
#define CONF_NOCONNECT_SERVER 0x0008
#define CONF_LOCOP 0x0010
#define CONF_OPERATOR 0x0020
#define CONF_ME 0x0040
#define CONF_KILL 0x0080
#define CONF_ADMIN 0x0100
#ifdef R_LINES
#define CONF_RESTRICT 0x0200
#endif
#define CONF_CLASS 0x0400
#define CONF_SERVICE 0x0800
#define CONF_LEAF 0x1000
#define CONF_LISTEN_PORT 0x2000
#define CONF_HUB 0x4000
#define CONF_UWORLD 0x8000
#define CONF_CRULEALL 0x00200000
#define CONF_CRULEAUTO 0x00400000
#define CONF_TLINES 0x00800000
#define CONF_OPS (CONF_OPERATOR | CONF_LOCOP)
#define CONF_SERVER_MASK (CONF_CONNECT_SERVER | CONF_NOCONNECT_SERVER)
#define CONF_CLIENT_MASK (CONF_CLIENT | CONF_SERVICE | CONF_OPS | \
CONF_SERVER_MASK)
#define CONF_CRULE (CONF_CRULEALL | CONF_CRULEAUTO)
#define IsIllegal(x) ((x)->status & CONF_ILLEGAL)
struct Gline {
struct Gline *next;
char *host;
char *reason;
char *name;
time_t expire;
int active;
};
#define GLINE_ACTIVE 1
#define GLINE_INACTIVE 0
/*
* Client structures
*/
struct User {
struct User *nextu;
aClient *server; /* client structure of server */
Dlink *clink; /* own Dlink in server->serv->client struct */
Link *channel; /* chain of channel pointer blocks */
Link *invited; /* chain of invite pointer blocks */
Link *silence; /* chain of silence pointer blocks */
char *away; /* pointer to away message */
time_t last;
int refcnt; /* Number of times this block is referenced */
int joined; /* number of channels joined */
char username[USERLEN+1];
char host[HOSTLEN+1];
#ifdef LIST_DEBUG
aClient *bcptr;
#endif
};
struct Server {
struct Server *nexts;
aClient *up; /* Server one closer to me */
Dlink *down; /* List with downlink servers */
Dlink *updown; /* own Dlink in up->serv->down struct */
Dlink *client; /* List with clients for this server */
anUser *user; /* who activated this connection */
char by[NICKLEN+1];
aConfItem *nline; /* N-line pointer for this server */
time_t timestamp; /* Remotely determined connect try time */
time_t ghost; /* Local time at which a new server caused a Ghost */
u_short prot; /* Major protocol */
#ifdef LIST_DEBUG
aClient *bcptr;
#endif
};
struct Client {
struct Client *next,*prev, *hnext;
anUser *user; /* ...defined, if this is a User */
aServer *serv; /* ...defined, if this is a server */
#ifdef USE_SERVICES
aService *service;
#endif
int hashv; /* raw hash value */
time_t lasttime; /* ...should be only LOCAL clients? --msa */
time_t firsttime; /* time client was created */
time_t since; /* last time we parsed something */
time_t lastnick; /* TimeStamp on nick */
long flags; /* client flags */
aClient *from; /* == self, if Local Client, *NEVER* NULL! */
int fd; /* >= 0, for local clients */
int hopcount; /* number of servers to this 0 = local */
short status; /* Client type */
char name[HOSTLEN+1]; /* Unique name of the client, nick or host */
char username[USERLEN+1]; /* username here now for auth stuff */
char info[REALLEN+1]; /* Free form additional client information */
/*
** The following fields are allocated only for local clients
** (directly connected to *this* server with a socket.
** The first of them *MUST* be the "count"--it is the field
** to which the allocation is tied to! *Never* refer to
** these fields, if (from != self).
*/
int count; /* Amount of data in buffer */
char buffer[BUFSIZE]; /* Incoming message buffer */
short lastsq; /* # of 2k blocks when sendqueued called last*/
#ifdef NICK_DELAY
time_t nextnick; /* Next time that a nick change is allowed */
#endif
u_long cookie; /* Random number the user must PONG */
dbuf sendQ; /* Outgoing message queue--if socket full */
dbuf recvQ; /* Hold for data incoming yet to be parsed */
long sendM; /* Statistics: protocol messages send */
long sendK; /* Statistics: total k-bytes send */
long receiveM; /* Statistics: protocol messages received */
long receiveK; /* Statistics: total k-bytes received */
u_short sendB; /* counters to count upto 1-k lots of bytes */
u_short receiveB; /* sent and received. */
aClient *acpt; /* listening client which we accepted from */
Link *confs; /* Configuration record associated */
int authfd; /* fd for rfc931 authentication */
struct in_addr ip; /* keep real ip# too */
unsigned short port; /* and the remote port# too :-) */
struct hostent *hostp;
aChannel *listing;
#ifdef pyr
struct timeval lw;
#endif
char sockhost[HOSTLEN+1]; /* This is the host name from the socket
** and after which the connection was
** accepted.
*/
char passwd[PASSWDLEN+1];
};
#define CLIENT_LOCAL_SIZE sizeof(aClient)
#define CLIENT_REMOTE_SIZE offsetof(aClient,count)
/*
* statistics structures
*/
struct stats {
unsigned int is_cl; /* number of client connections */
unsigned int is_sv; /* number of server connections */
unsigned int is_ni; /* connection but no idea who it was */
unsigned short is_cbs; /* bytes sent to clients */
unsigned short is_cbr; /* bytes received to clients */
unsigned short is_sbs; /* bytes sent to servers */
unsigned short is_sbr; /* bytes received to servers */
unsigned long is_cks; /* k-bytes sent to clients */
unsigned long is_ckr; /* k-bytes received to clients */
unsigned long is_sks; /* k-bytes sent to servers */
unsigned long is_skr; /* k-bytes received to servers */
time_t is_cti; /* time spent connected by clients */
time_t is_sti; /* time spent connected by servers */
unsigned int is_ac; /* connections accepted */
unsigned int is_ref; /* accepts refused */
unsigned int is_unco; /* unknown commands */
unsigned int is_wrdi; /* command going in wrong direction */
unsigned int is_unpf; /* unknown prefix */
unsigned int is_empt; /* empty message */
unsigned int is_num; /* numeric message */
unsigned int is_kill; /* number of kills generated on collisions */
unsigned int is_fake; /* MODE 'fakes' */
unsigned int is_asuc; /* successful auth requests */
unsigned int is_abad; /* bad auth requests */
unsigned int is_udp; /* packets recv'd on udp port */
unsigned int is_loc; /* local connections made */
};
/* mode structure for channels */
struct SMode {
unsigned int mode;
int limit;
char key[KEYLEN+1];
};
/* Message table structure */
struct Message {
char *cmd;
int (* func)();
unsigned int count;
int parameters;
char flags;
/* bit 0 set means that this command is allowed to be used
* only on the average of once per 2 seconds -SRB */
unsigned long bytes;
};
/* general link structure used for chains */
struct SLink {
struct SLink *next;
union {
aClient *cptr;
aChannel *chptr;
aConfItem *aconf;
char *cp;
struct {
char *banstr;
char *who;
time_t when;
} ban;
} value;
int flags;
};
struct DSlink {
struct DSlink *next;
struct DSlink *prev;
union {
aClient *cptr;
aChannel *chptr;
aConfItem *aconf;
char *cp;
} value;
};
/* channel structure */
struct Channel {
struct Channel *nextch, *prevch, *hnextch;
int hashv; /* raw hash value */
Mode mode;
time_t creationtime;
char topic[TOPICLEN+1];
char topic_nick[NICKLEN+1];
time_t topic_time;
int users;
Link *members;
Link *invites;
Link *banlist;
char chname[1];
};
/*
** Channel Related macros follow
*/
/* Channel related flags */
#define CHFL_CHANOP 0x0001 /* Channel operator */
#define CHFL_VOICE 0x0002 /* the power to speak */
#define CHFL_DEOPPED 0x0004 /* Is de-opped by a server */
#define CHFL_SERVOPOK 0x0008 /* Server op allowed */
#define CHFL_ZOMBIE 0x0010 /* Kicked from channel */
#define CHFL_BAN 0x0020 /* ban channel flag */
#define CHFL_OVERLAP (CHFL_CHANOP|CHFL_VOICE)
/* Channel Visibility macros */
#define MODE_CHANOP CHFL_CHANOP
#define MODE_VOICE CHFL_VOICE
#define MODE_PRIVATE 0x0004
#define MODE_SECRET 0x0008
#define MODE_MODERATED 0x0010
#define MODE_TOPICLIMIT 0x0020
#define MODE_INVITEONLY 0x0040
#define MODE_NOPRIVMSGS 0x0080
#define MODE_KEY 0x0100
#define MODE_BAN 0x0200
#define MODE_LIMIT 0x0400
#define MODE_LISTED 0x10000
/*
* mode flags which take another parameter (With PARAmeterS)
*/
#define MODE_WPARAS (MODE_CHANOP|MODE_VOICE|MODE_BAN|MODE_KEY|MODE_LIMIT)
/*
* Undefined here, these are used in conjunction with the above modes in
* the source.
#define MODE_DEL 0x20000000
#define MODE_ADD 0x40000000
*/
#define HoldChannel(x) (!(x))
/* name invisible */
#define SecretChannel(x) ((x) && ((x)->mode.mode & MODE_SECRET))
/* channel not shown but names are */
#define HiddenChannel(x) ((x) && ((x)->mode.mode & MODE_PRIVATE))
/* channel visible */
#define ShowChannel(v,c) (PubChannel(c) || IsMember((v),(c)))
#define PubChannel(x) ((!x) || ((x)->mode.mode &\
(MODE_PRIVATE | MODE_SECRET)) == 0)
#define is_listed(x) ((x)->mode.mode & MODE_LISTED)
#define IsChannelName(name) ((name) && (*(name) == '#' || *(name) == '&'))
/* Misc macros */
#define BadPtr(x) (!(x) || (*(x) == '\0'))
#define isvalid(c) (((c) >= 'A' && (c) <= '~') || isdigit(c) || (c) == '-')
#define MyConnect(x) ((x)->fd >= 0)
#define MyClient(x) (MyConnect(x) && IsClient(x))
#define MyOper(x) (MyConnect(x) && IsOper(x))
#define Protocol(x) ((x)->serv->prot)
#define TStime() (now+TSoffset)
/* String manipulation macros */
/* strncopynt --> strncpyzt to avoid confusion, sematics changed
N must be now the number of bytes in the array --msa */
#define strncpyzt(x, y, N) do{(void)strncpy(x,y,N);x[N-1]='\0';}while(0)
#define StrEq(x,y) (!strcmp((x),(y)))
/* used in SetMode() in channel.c and m_umode() in s_msg.c */
#define MODE_NULL 0
#define MODE_ADD 0x40000000
#define MODE_DEL 0x20000000
/* return values for hunt_server() */
#define HUNTED_NOSUCH (-1) /* if the hunted server is not found */
#define HUNTED_ISME 0 /* if this server should execute the command */
#define HUNTED_PASS 1 /* if message passed onwards successfully */
/* used when sending to #mask or $mask */
#define MATCH_SERVER 1
#define MATCH_HOST 2
/* used for async dns values */
#define ASYNC_NONE (-1)
#define ASYNC_CLIENT 0
#define ASYNC_CONNECT 1
#define ASYNC_CONF 2
#define ASYNC_PING 3
/* This is not used, and as soon as it is, I have to check if
make_server has been called before... --Run
#define ASYNC_SERVER 4
*/
/* misc variable externs */
extern char *version, *infotext[];
extern char *generation, *creation;
extern time_t TSoffset;
/* misc defines */
#define CPTR_KILLED -2
#define UTMP "/etc/utmp"
#define COMMA ","
#define UDP_PORT "7007"
#define MINOR_PROTOCOL "04"
#define MAJOR_PROTOCOL "09"
#define BASE_VERSION "u2.9"
#endif /* __struct_include__ */