1 /*
2  *   IRC - Internet Relay Chat, src/modules/out.c
3  *   (C) 2004 The UnrealIRCd Team
4  *
5  *   See file AUTHORS in IRC package for additional names of
6  *   the programmers.
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 1, or (at your option)
11  *   any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 #include "config.h"
23 #include "struct.h"
24 #include "common.h"
25 #include "sys.h"
26 #include "numeric.h"
27 #include "msg.h"
28 #include "proto.h"
29 #include "channel.h"
30 #include <time.h>
31 #include <sys/stat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #ifdef _WIN32
36 #include <io.h>
37 #endif
38 #include <fcntl.h>
39 #include "h.h"
40 #ifdef STRIPBADWORDS
41 #include "badwords.h"
42 #endif
43 #include "version.h"
44 
45 DLLFUNC int m_netinfo(aClient *cptr, aClient *sptr, int parc, char *parv[]);
46 
47 #define MSG_NETINFO 	"NETINFO"
48 #define TOK_NETINFO 	"AO"
49 
50 ModuleHeader MOD_HEADER(m_netinfo)
51   = {
52 	"m_netinfo",
53 	"$Id$",
54 	"command /netinfo",
55 	"3.2-b8-1",
56 	NULL
57     };
58 
MOD_INIT(m_netinfo)59 DLLFUNC int MOD_INIT(m_netinfo)(ModuleInfo *modinfo)
60 {
61 	add_Command(MSG_NETINFO, TOK_NETINFO, m_netinfo, MAXPARA);
62 	MARK_AS_OFFICIAL_MODULE(modinfo);
63 	return MOD_SUCCESS;
64 }
65 
MOD_LOAD(m_netinfo)66 DLLFUNC int MOD_LOAD(m_netinfo)(int module_load)
67 {
68 	return MOD_SUCCESS;
69 }
70 
MOD_UNLOAD(m_netinfo)71 DLLFUNC int MOD_UNLOAD(m_netinfo)(int module_unload)
72 {
73 	if (del_Command(MSG_NETINFO, TOK_NETINFO, m_netinfo) < 0)
74 	{
75 		sendto_realops("Failed to delete commands when unloading %s",
76 			MOD_HEADER(m_netinfo).name);
77 	}
78 	return MOD_SUCCESS;
79 }
80 
81 /*
82 ** m_netinfo
83 ** by Stskeeps
84 **  parv[0] = sender prefix
85 **  parv[1] = max global count
86 **  parv[2] = time of end sync
87 **  parv[3] = unreal protocol using (numeric)
88 **  parv[4] = cloak-crc (> u2302)
89 **  parv[5] = free(**)
90 **  parv[6] = free(**)
91 **  parv[7] = free(**)
92 **  parv[8] = ircnet
93 **/
94 
CMD_FUNC(m_netinfo)95 DLLFUNC CMD_FUNC(m_netinfo)
96 {
97 	long 		lmax;
98 	time_t	 	xx;
99 	long 		endsync, protocol;
100 	char		buf[512];
101 
102 	if (IsPerson(sptr))
103 		return 0;
104 	if (!IsServer(cptr))
105 		return 0;
106 
107 	if (parc < 3)
108 	{
109 		/* Talking to a UnProtocol 2090 */
110 		sendto_realops
111 		    ("Link %s is using a too old UnProtocol - (parc < 3)",
112 		    cptr->name);
113 		return 0;
114 	}
115 	if (parc < 9)
116 	{
117 		return 0;
118 	}
119 
120 	if (GotNetInfo(cptr))
121 	{
122 		sendto_realops("Already got NETINFO from Link %s", cptr->name);
123 		return 0;
124 	}
125 	/* is a long therefore not ATOI */
126 	lmax = atol(parv[1]);
127 	endsync = TS2ts(parv[2]);
128 	protocol = atol(parv[3]);
129 
130 	/* max global count != max_global_count --sts */
131 	if (lmax > IRCstats.global_max)
132 	{
133 		IRCstats.global_max = lmax;
134 		sendto_realops("Max Global Count is now %li (set by link %s)",
135 		    lmax, cptr->name);
136 	}
137 
138 	xx = TStime();
139 	if ((xx - endsync) < 0)
140 	{
141 		char *emsg = "";
142 		if (xx - endsync < -10)
143 		{
144 			emsg = " [\002PLEASE SYNC YOUR CLOCKS!\002]";
145 		}
146 		sendto_realops
147 		    ("Possible negative TS split at link %s (%li - %li = %li)%s",
148 		    cptr->name, (xx), (endsync), (xx - endsync), emsg);
149 		sendto_serv_butone(&me,
150 		    ":%s SMO o :\2(sync)\2 Possible negative TS split at link %s (%li - %li = %li)%s",
151 		    me.name, cptr->name, (xx), (endsync), (xx - endsync), emsg);
152 	}
153 	sendto_realops
154 	    ("Link %s -> %s is now synced [secs: %li recv: %ld.%hu sent: %ld.%hu]",
155 	    cptr->name, me.name, (TStime() - endsync), sptr->receiveK,
156 	    sptr->receiveB, sptr->sendK, sptr->sendB);
157 #ifdef ZIP_LINKS
158 	if ((MyConnect(cptr)) && (IsZipped(cptr)) && cptr->zip->in->total_out && cptr->zip->out->total_in) {
159 		sendto_realops
160 		("Zipstats for link to %s: decompressed (in): %01lu=>%01lu (%3.1f%%), compressed (out): %01lu=>%01lu (%3.1f%%)",
161 			get_client_name(cptr, TRUE),
162 			cptr->zip->in->total_in, cptr->zip->in->total_out,
163 			(100.0*(float)cptr->zip->in->total_in) /(float)cptr->zip->in->total_out,
164 			cptr->zip->out->total_in, cptr->zip->out->total_out,
165 			(100.0*(float)cptr->zip->out->total_out) /(float)cptr->zip->out->total_in);
166 	}
167 #endif
168 
169 	sendto_serv_butone(&me,
170 	    ":%s SMO o :\2(sync)\2 Link %s -> %s is now synced [secs: %li recv: %ld.%hu sent: %ld.%hu]",
171 	    me.name, cptr->name, me.name, (TStime() - endsync), sptr->receiveK,
172 	    sptr->receiveB, sptr->sendK, sptr->sendB);
173 
174 	if (!(strcmp(ircnetwork, parv[8]) == 0))
175 	{
176 		sendto_realops("Network name mismatch from link %s (%s != %s)",
177 		    cptr->name, parv[8], ircnetwork);
178 		sendto_serv_butone(&me,
179 		    ":%s SMO o :\2(sync)\2 Network name mismatch from link %s (%s != %s)",
180 		    me.name, cptr->name, parv[8], ircnetwork);
181 	}
182 
183 	if ((protocol != UnrealProtocol) && (protocol != 0))
184 	{
185 		sendto_realops
186 		    ("Link %s is running Protocol u%li while we are running %d!",
187 		    cptr->name, protocol, UnrealProtocol);
188 		sendto_serv_butone(&me,
189 		    ":%s SMO o :\2(sync)\2 Link %s is running u%li while %s is running %d!",
190 		    me.name, cptr->name, protocol, me.name, UnrealProtocol);
191 
192 	}
193 	strlcpy(buf, CLOAK_KEYCRC, sizeof(buf));
194 	if (*parv[4] != '*' && strcmp(buf, parv[4]))
195 	{
196 		sendto_realops
197 			("Link %s has a DIFFERENT CLOAK KEY - %s != %s. \002YOU SHOULD CORRECT THIS ASAP\002.",
198 				cptr->name, parv[4], buf);
199 	}
200 	SetNetInfo(cptr);
201 	return 0;
202 }
203