]> jfr.im git - irc/quakenet/newserv.git/blame - server/server.c
Sigh
[irc/quakenet/newserv.git] / server / server.c
CommitLineData
c86edd1d
Q
1/* server.c
2 *
3 * This module is responsible for tracking the active server tree.
4 */
5
6#include "../parser/parser.h"
7#include "../irc/irc_config.h"
8#include "../irc/irc.h"
9#include "../lib/base64.h"
10#include "../lib/sstring.h"
11#include "../core/error.h"
12#include "../core/hooks.h"
13#include "../core/config.h"
87698d77 14#include "../lib/version.h"
c86edd1d
Q
15#include "server.h"
16
17#include <stdio.h>
18#include <string.h>
19
0a55e401 20MODULE_VERSION("$Id: server.c 663 2006-05-16 17:27:36Z newserv $")
87698d77 21
c86edd1d
Q
22int findserver(const char *name);
23void completelink(int servernum);
24
25server serverlist[MAXSERVERS];
26int myhub;
27
28void _init() {
29 /* Initialise the server tree */
30 memset(serverlist,0,MAXSERVERS*sizeof(server));
31
32 myhub=-1;
33
34 serverlist[numerictolong(mynumeric->content,2)].parent=-1;
35 serverlist[numerictolong(mynumeric->content,2)].name=getsstring(myserver->content,HOSTLEN);
36 serverlist[numerictolong(mynumeric->content,2)].description=getcopyconfigitem("irc","serverdescription","newserv",100);
37 serverlist[numerictolong(mynumeric->content,2)].maxusernum=MAXLOCALUSER;
38 serverlist[numerictolong(mynumeric->content,2)].linkstate=LS_LINKED;
39
40 /* Register the protocol messages we handle */
41 registerserverhandler("SERVER",&handleservermsg,8);
42 registerserverhandler("S",&handleservermsg,8);
43 registerserverhandler("SQ",&handlesquitmsg,3);
44 registerserverhandler("EB",&handleeobmsg,0);
45
46 /* And the events we hook */
47 registerhook(HOOK_IRC_DISCON,&handledisconnect);
48}
49
50void _fini() {
51 int i;
52
53 /* Deregister everything */
54 deregisterserverhandler("SERVER",&handleservermsg);
55 deregisterserverhandler("S",&handleservermsg);
56 deregisterserverhandler("SQ",&handlesquitmsg);
57 deregisterserverhandler("EB",&handleeobmsg);
58 deregisterhook(HOOK_IRC_DISCON,&handledisconnect);
59
60 for (i=0;i<MAXSERVERS;i++) {
61 if (serverlist[i].name!=NULL)
62 freesstring(serverlist[i].name);
63 }
64}
65
66int handleservermsg(void *source, int cargc, char **cargv) {
67 int servernum;
68
69 servernum=numerictolong(cargv[5],2);
70
71 if (serverlist[servernum].name!=NULL) {
72 Error("server",ERR_ERROR,"New server %d already exists in servertable.",servernum);
73 return CMD_ERROR;
74 }
75
76 serverlist[servernum].name=getsstring(cargv[0],HOSTLEN);
77 serverlist[servernum].description=getsstring(cargv[cargc-1],REALLEN);
78 serverlist[servernum].maxusernum=numerictolong(cargv[5]+2,3);
79
80 if (!strncmp((char *)source,"INIT",4)) {
81 /* This is the initial server */
82 myhub=servernum;
83 serverlist[servernum].parent=numerictolong(mynumeric->content,2);
84 } else {
85 serverlist[servernum].parent=numerictolong(source,2);
86 }
87
88 /* Set up the initial server state -- this MUST be one of the "linking" states */
89 if (cargv[4][0]=='J') {
90 serverlist[servernum].linkstate=LS_LINKING;
91 Error("server",ERR_DEBUG,"Creating server %s in LS_LINKING state.",serverlist[servernum].name->content);
92 } else {
93 serverlist[servernum].linkstate=LS_PLINKING;
94 Error("server",ERR_DEBUG,"Creating server %s in LS_PLINKING state.",serverlist[servernum].name->content);
95 }
96
97 triggerhook(HOOK_SERVER_NEWSERVER,(void *)servernum);
98 return CMD_OK;
99}
100
101int handleeobmsg(void *source, int cargc, char **argv) {
102 int servernum;
103
104 servernum=numerictolong(source,2);
105 completelink(servernum);
106
107 if (servernum==myhub) {
108 /* Send EA */
109 irc_send("%s EA",mynumeric->content);
110 Error("server",ERR_INFO,"Acknowledging end of burst");
e609eb1f 111 triggerhook(HOOK_SERVER_END_OF_BURST, NULL);
c86edd1d
Q
112 }
113
114 return CMD_OK;
115}
116
117int handlesquitmsg(void *source, int cargc, char **cargv) {
118 int servernum=findserver(cargv[0]);
119 if (servernum<0) {
120 Error("server",ERR_WARNING,"Received SQUIT for unknown server %s\n",cargv[0]);
121 return CMD_ERROR;
122 }
123 if (servernum==myhub) {
124 Error("server",ERR_WARNING,"Rejected by our hub: %s",cargv[cargc-1]);
125 irc_disconnected();
126 return CMD_OK;
127 }
128 deleteserver(servernum);
129
130 return CMD_OK;
131}
132
133void handledisconnect(int hooknum, void *arg) {
134 if (myhub>=0) {
135 deleteserver(myhub);
136 myhub=-1;
137 }
138}
139
140void completelink(int servernum) {
141 int i;
142
143 if (serverlist[servernum].name==NULL) {
144 Error("server",ERR_WARNING,"Tried to complete link for server %d which doesn't exist.",servernum);
145 return;
146 }
147
148 /* Complete the link for all children in the PLINKING state. */
149 for (i=0;i<MAXSERVERS;i++) {
150 if (serverlist[i].parent==servernum && serverlist[i].linkstate==LS_PLINKING) {
151 completelink(i);
152 }
153 }
154
155 /* This server is now fully linked. */
156 serverlist[servernum].linkstate=LS_LINKED;
157 Error("server",ERR_DEBUG,"Setting link state on %s to LS_LINKED",serverlist[servernum].name->content);
158}
159
160void deleteserver(int servernum) {
161 int i;
162
163 if (serverlist[servernum].name==NULL) {
164 Error("server",ERR_WARNING,"Tried to remove server %d which doesn't exist.",servernum);
165 return;
166 }
167
168 /* Delete all it's children first */
169 for (i=0;i<MAXSERVERS;i++) {
170 if (serverlist[i].parent==servernum && serverlist[i].name!=NULL) {
171 deleteserver(i);
172 }
173 }
174
175 /* Set state to SQUITting, then trigger hook */
176 Error("server",ERR_DEBUG,"Setting link state on %s to LS_SQUIT",serverlist[servernum].name->content);
177 serverlist[servernum].linkstate=LS_SQUIT;
e609eb1f
CP
178
179 /* Until hooks have priorities we need something like this */
180 triggerhook(HOOK_SERVER_PRE_LOSTSERVER,(void *)servernum);
c86edd1d
Q
181 triggerhook(HOOK_SERVER_LOSTSERVER,(void *)servernum);
182
183 /* Now delete the actual server */
184 freesstring(serverlist[servernum].name);
185 freesstring(serverlist[servernum].description);
186 memset(&(serverlist[servernum]),0,sizeof(server)); /* sets state back to LS_INVALID */
187}
188
189int findserver(const char *name) {
190 int i;
191
192 for(i=0;i<MAXSERVERS;i++)
193 if (serverlist[i].name!=NULL && !strncmp(serverlist[i].name->content,name,serverlist[i].name->length))
194 return i;
195
196 return -1;
197}
198