2 * IRC - Internet Relay Chat, ircd/map.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
5 * Copyright (C) 2002 Joseph Bongaarts <foxxe@wtfs.net>
7 * See file AUTHORS in IRC package for additional names of
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 1, or (at your option)
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include "ircd_defs.h"
32 #include "ircd_policy.h"
33 #include "ircd_reply.h"
34 #include "ircd_snprintf.h"
35 #include "ircd_string.h"
36 #include "ircd_alloc.h"
45 #include "querycmds.h"
52 #if defined(HEAD_IN_SAND_MAP) || defined(HEAD_IN_SAND_LINKS)
54 static struct Map *MapList = 0;
56 /* Add a server to the map list. */
57 static void map_add(struct Client *server)
59 struct Map *map = (struct Map *)MyMalloc(sizeof(struct Map));
61 assert(IsServer(server));
62 assert(!IsHub(server));
63 assert(!IsService(server));
65 map->lasttime = TStime();
66 strcpy(map->name, cli_name(server));
67 strcpy(map->info, cli_info(server));
68 map->prot = Protocol(server);
69 map->maxclients = cli_serv(server)->clients;
80 /* Remove a server from the map list */
81 static void map_remove(struct Map *cptr)
86 cptr->next->prev = cptr->prev;
89 cptr->prev->next = cptr->next;
98 /* Update a server in the list. Called when a server connects
99 * splits, or we haven't checked in more than a week. */
100 void map_update(struct Client *cptr)
104 assert(IsServer(cptr));
106 /* Find the server in the list and update it */
107 for(map = MapList; map; map = map->next)
109 /* Show max clients not current, otherwise a split can be detected. */
110 if(!ircd_strcmp(cli_name(cptr), map->name))
112 map->lasttime = TStime();
113 map->prot = Protocol(cptr);
114 strcpy(map->info, cli_info(cptr));
115 if(map->maxclients < cli_serv(cptr)->clients)
116 map->maxclients = cli_serv(cptr)->clients;
121 /* We do this check after finding a matching map because
122 * a client server can become a hub or service (such as
125 if(IsHub(cptr) || IsService(cptr))
132 /* If we haven't seen it before, add it to the list. */
136 #endif /* HEAD_IN_SAND_MAP || HEAD_IN_SAND_LINKS*/
138 #ifdef HEAD_IN_SAND_MAP
140 void map_dump_head_in_sand(struct Client *cptr)
143 struct Map *smap = 0;
144 struct Client *acptr = 0;
147 send_reply(cptr, RPL_MAP, "", "", cli_name(&me), "", UserStats.local_clients);
149 for(map = MapList; map; map = smap)
153 /* Don't show servers we haven't seen in more than a week */
154 if(map->lasttime < TStime() - MAP_CACHE_TIME)
156 acptr = FindServer(map->name);
165 send_reply(cptr, RPL_MAP, smap ? "|" : "`", "-", map->name, "", map->maxclients);
169 #endif /* HEAD_IN_SAND_MAP */
171 #ifdef HEAD_IN_SAND_LINKS
172 void map_dump_links_head_in_sand(struct Client *sptr, char *mask)
174 struct Map *link = 0;
175 struct Map *slink = 0;
176 struct Client *acptr = 0;
180 for(link = MapList; link; link = slink)
184 if(link->lasttime < TStime() - MAP_CACHE_TIME)
186 acptr = FindServer(link->name);
195 if (!BadPtr(mask) && match(mask, link->name))
197 send_reply(sptr, RPL_LINKS, link->name, cli_name(&me), 1, link->prot,
200 /* don't forget to send me */
201 send_reply(sptr, RPL_LINKS, cli_name(&me), cli_name(&me), 0, Protocol(&me),
204 #endif /* HEAD_IN_SAND_LINKS */
206 void map_dump(struct Client *cptr, struct Client *server, char *mask, int prompt_length)
208 static char prompt[64];
210 char *p = &prompt[prompt_length];
214 if (prompt_length > 60)
215 send_reply(cptr, RPL_MAPMORE, prompt, cli_name(server));
218 if (cli_serv(server)->lag>10000)
220 else if (cli_serv(server)->lag<0)
223 sprintf(lag,"(%is)",cli_serv(server)->lag);
224 send_reply(cptr, RPL_MAP, prompt, (
225 (IsBurst(server)) ? "*" : (IsBurstAck(server) ? "!" : "")),
226 cli_name(server), lag, (server == &me) ? UserStats.local_clients :
227 cli_serv(server)->clients);
229 if (prompt_length > 0)
235 if (prompt_length > 60)
238 for (lp = cli_serv(server)->down; lp; lp = lp->next)
239 if (match(mask, cli_name(lp->value.cptr)))
240 ClrFlag(lp->value.cptr, FLAG_MAP);
243 SetFlag(lp->value.cptr, FLAG_MAP);
246 for (lp = cli_serv(server)->down; lp; lp = lp->next)
248 if (!HasFlag(lp->value.cptr, FLAG_MAP))
252 map_dump(cptr, lp->value.cptr, mask, prompt_length + 2);
254 if (prompt_length > 0)