+2002-02-25 Joseph Bongaarts <foxxe@wtfs.net>
+
+ * ircd/m_map.c: Modified to show a useful output to non-opered
+ clients when HEAD_IN_SAND_MAP is defined. Servers are added to
+ the list when first seen (after receiving SERVER) and that list
+ is sent to clients. Servers are excluded from the list if they are
+ hubs, services, or have been missing for more than 1 week.
+
+ * ircd/map.c: Created file for map_* functions
+
+ * include/map.h: Created file for map_* functions
+
+ * ircd/m_server.c: Added calls to map_update()
+
+ * ircd/s_misc.c: Added call to map_update()
+
+ * ircd/parse.c: Changed to use m_map() and mo_map()
+
2002-02-22 Reed Loden <reed@redmagnet.com>
* ircd/m_connect.c: Removed an extra : in remote connect message.
--- /dev/null
+#ifndef INCLUDED_map_h
+#define INCLUDED_map_h
+/*
+ * IRC - Internet Relay Chat, include/map.h
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ * Copyright (C) 2002 Joseph Bongaarts <foxxe@wtfs.net>
+ *
+ * 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 2, 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.
+ *
+ * $Id$
+ */
+#ifndef INCLUDED_time_h
+#include <time.h> /* struct tm */
+#define INCLUDED_time_h
+#endif
+#ifndef INCLUDED_sys_types_h
+#include <sys/types.h>
+#define INCLUDED_sys_types_h
+#endif
+
+#ifdef HEAD_IN_SAND_MAP
+
+struct Map {
+ time_t lasttime;
+ unsigned int maxclients;
+ char name[HOSTLEN+1];
+ struct Map *next;
+ struct Map *prev;
+}
+
+extern void map_update(struct Client *server);
+extern void map_dump_head_in_sand(struct Client *cptr);
+
+#endif /* HEAD_IN_SAND_MAP */
+
+extern void map_dump(struct Client *cptr, struct Client *server, char *mask, int prompt_length);
+
+#endif /* INCLUDED_motd_h */
+
#include "s_serv.h"
#include "send.h"
#include "querycmds.h"
+#include "map.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
-static void dump_map(struct Client *cptr, struct Client *server, char *mask, int prompt_length)
-{
- static char prompt[64];
- struct DLink *lp;
- char *p = &prompt[prompt_length];
- int cnt = 0;
-
- *p = '\0';
- if (prompt_length > 60)
- send_reply(cptr, RPL_MAPMORE, prompt, cli_name(server));
- else {
- char lag[512];
- if (cli_serv(server)->lag>10000)
- lag[0]=0;
- else if (cli_serv(server)->lag<0)
- strcpy(lag,"(0s)");
- else
- sprintf(lag,"(%is)",cli_serv(server)->lag);
- send_reply(cptr, RPL_MAP, prompt, (
- (IsBurst(server)) ? "*" : (IsBurstAck(server) ? "!" : "")),
- cli_name(server), lag, (server == &me) ? UserStats.local_clients :
- cli_serv(server)->clients);
- }
- if (prompt_length > 0)
- {
- p[-1] = ' ';
- if (p[-2] == '`')
- p[-2] = ' ';
- }
- if (prompt_length > 60)
- return;
- strcpy(p, "|-");
- for (lp = cli_serv(server)->down; lp; lp = lp->next)
- if (match(mask, cli_name(lp->value.cptr)))
- cli_flags(lp->value.cptr) &= ~FLAGS_MAP;
- else
- {
- cli_flags(lp->value.cptr) |= FLAGS_MAP;
- cnt++;
- }
- for (lp = cli_serv(server)->down; lp; lp = lp->next)
- {
- if ((cli_flags(lp->value.cptr) & FLAGS_MAP) == 0)
- continue;
- if (--cnt == 0)
- *p = '`';
- dump_map(cptr, lp->value.cptr, mask, prompt_length + 2);
- }
- if (prompt_length > 0)
- p[-1] = '-';
-}
-
-
/*
* m_map - generic message handler
* -- by Run
*/
int m_map(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
- if (parc < 2)
+#ifdef HEAD_IN_SAND_MAP
+ map_dump_head_in_sand(sptr);
+#else
+ if(parc < 2)
parv[1] = "*";
-
- dump_map(sptr, &me, parv[1], 0);
+ map_dump(sptr, &me, parv[1], 0);
+#endif /* HEAD_IN_SAND_MAP */
send_reply(sptr, RPL_MAPEND);
return 0;
}
-#ifdef HEAD_IN_SAND_MAP
-int m_map_redirect(struct Client* cptr, struct Client* sptr, int parc,
- char* parv[])
+int mo_map(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
{
- sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr,
- "/MAP has been disabled, from CFV-165. "
- "Visit " URL_SERVERS);
+ if (parc < 2)
+ parv[1] = "*";
+
+ map_dump(sptr, &me, parv[1], 0);
+ send_reply(sptr, RPL_MAPEND);
+
return 0;
}
-#endif
#include "s_serv.h"
#include "send.h"
#include "userload.h"
+#include "map.h"
#include <assert.h>
#include <stdlib.h>
else
ret = 0;
+ map_update(cptr);
+
if (feature_bool(FEAT_RELIABLE_CLOCK) &&
abs(cli_serv(cptr)->timestamp - recv_time) > 30) {
sendto_opmask_butone(0, SNO_OLDSNO, "Connected to a net with a "
Count_newremoteserver(UserStats);
add_client_to_list(acptr);
hAddClient(acptr);
+ map_update(acptr);
if (*parv[5] == 'J')
{
--- /dev/null
+/*
+ * IRC - Internet Relay Chat, ircd/map.c
+ * Copyright (C) 1990 Jarkko Oikarinen and
+ * University of Oulu, Computing Center
+ * Copyright (C) 2002 Joseph Bongaarts <foxxe@wtfs.net>
+ *
+ * See file AUTHORS in IRC package for additional names of
+ * the programmers.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include "client.h"
+#include "ircd.h"
+#include "ircd_defs.h"
+#include "ircd_policy.h"
+#include "ircd_reply.h"
+#include "ircd_snprintf.h"
+#include "ircd_string.h"
+#include "list.h"
+#include "match.h"
+#include "msg.h"
+#include "numeric.h"
+#include "s_user.h"
+#include "s_serv.h"
+#include "send.h"
+#include "querycmds.h"
+#include "map.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HEAD_IN_SAND_MAP
+
+static struct Map *MapList = 0;
+
+/* Add a server to the map list. */
+static void map_add(struct Client *server)
+{
+ assert(server != 0);
+ assert(!IsHub(server));
+ assert(!IsService(server));
+
+ struct Map *new = (struct Map *)MyAlloc(sizeof(struct Map));
+
+ new->lasttime = TStime();
+ ircd_strcpy(new->name, cli_name(server));
+ new->maxclients = cli_serv(server)->clients;
+
+ new->prev = 0;
+ new->next = MapList;
+
+ if(MapList)
+ MapList->prev = new;
+
+ MapList = new;
+}
+
+/* Remove a server from the map list */
+static void map_remove(struct Map *cptr)
+{
+ assert(cptr != 0);
+
+ if(cptr->next)
+ cptr->next->prev = cptr->prev;
+
+ if(cptr->prev)
+ cptr->prev->next = cptr->next;
+
+ if(MapList == cptr)
+ MapList = cptr->next;
+
+ MyFree(cptr);
+
+}
+
+/* Update a server in the list. Called when a server connects
+ * splits, or we haven't checked in more than a week. */
+void map_update(struct Client *cptr)
+{
+ assert(IsServer(cptr));
+
+ struct Map *map = 0;
+
+ /* Find the server in the list and update it */
+ for(map = MapList.list; map; map = map->next)
+ {
+ /* Show max clients not current, otherwise a split can be detected. */
+ if(!ircd_strcmp(cli_name(cptr), map->name))
+ {
+ map->lasttime = TStime();
+ if(map->maxclients < cli_serv(cptr)->clients)
+ map->maxclients = cli_serv(cptr)->clients;
+ break;
+ }
+ }
+
+ /* We do this check after finding a matching map because
+ * a client server can become a hub or service (such as
+ * santaclara)
+ */
+ if(IsHub(cptr) || IsService(cptr))
+ {
+ if(map)
+ map_remove(map);
+ return;
+ }
+
+ /* If we haven't seen it before, add it to the list. */
+ if(!map)
+ map_add(cli_name(cptr));
+}
+
+void dump_map_head_in_sand(struct Client *cptr)
+{
+ struct Map *map = 0;
+ struct Map *smap = 0;
+ struct Client *acptr = 0;
+
+ /* Send me first */
+ send_reply(cptr, RPL_MAP, "", "", cli_name(&me), "", UserStats.local_clients);
+
+ for(map = MapList; map; map = smap)
+ {
+ smap = map->next;
+
+ /* Don't show servers we haven't seen in more than a week */
+ if(map->lasttime < TStime() - 604800)
+ {
+ acptr = find_match_server(map->name);
+ if(!acptr)
+ {
+ map_remove(map);
+ continue;
+ }
+ else
+ map_update(acptr);
+ }
+ send_reply(cptr, RPL_MAP, "", "|-", map->name, "", map->maxclients);
+ }
+}
+
+#endif /* HEAD_IN_SAND_MAP */
+
+(void map_dump(struct Client *cptr, struct Client *server, char *mask, int prompt_length)
+{
+ static char prompt[64];
+ struct DLink *lp;
+ char *p = &prompt[prompt_length];
+ int cnt = 0;
+
+ *p = '\0';
+ if (prompt_length > 60)
+ send_reply(cptr, RPL_MAPMORE, prompt, cli_name(server));
+ else {
+ char lag[512];
+ if (cli_serv(server)->lag>10000)
+ lag[0]=0;
+ else if (cli_serv(server)->lag<0)
+ strcpy(lag,"(0s)");
+ else
+ sprintf(lag,"(%is)",cli_serv(server)->lag);
+ send_reply(cptr, RPL_MAP, prompt, (
+ (IsBurst(server)) ? "*" : (IsBurstAck(server) ? "!" : "")),
+ cli_name(server), lag, (server == &me) ? UserStats.local_clients :
+ cli_serv(server)->clients);
+ }
+ if (prompt_length > 0)
+ {
+ p[-1] = ' ';
+ if (p[-2] == '`')
+ p[-2] = ' ';
+ }
+ if (prompt_length > 60)
+ return;
+ strcpy(p, "|-");
+ for (lp = cli_serv(server)->down; lp; lp = lp->next)
+ if (match(mask, cli_name(lp->value.cptr)))
+ cli_flags(lp->value.cptr) &= ~FLAGS_MAP;
+ else
+ {
+ cli_flags(lp->value.cptr) |= FLAGS_MAP;
+ cnt++;
+ }
+ for (lp = cli_serv(server)->down; lp; lp = lp->next)
+ {
+ if ((cli_flags(lp->value.cptr) & FLAGS_MAP) == 0)
+ continue;
+ if (--cnt == 0)
+ *p = '`';
+ map_dump(cptr, lp->value.cptr, mask, prompt_length + 2);
+ }
+ if (prompt_length > 0)
+ p[-1] = '-';
+}
+
+
TOK_MAP,
0, MAXPARA, MFLG_SLOW, 0,
/* UNREG, CLIENT, SERVER, OPER, SERVICE */
-#ifdef HEAD_IN_SAND_MAP
- { m_unregistered, m_map_redirect, m_ignore, m_map, m_ignore }
-#else
- { m_unregistered, m_map, m_ignore, m_map, m_ignore }
-#endif
+ { m_unregistered, m_map, m_ignore, mo_map, m_ignore }
},
{
MSG_VERSION,
#include "sys.h"
#include "uping.h"
#include "userload.h"
+#include "map.h"
#include <assert.h>
#include <fcntl.h>
Count_serverdisconnects(UserStats);
else
Count_remoteserverquits(UserStats);
+
+ map_update(bcptr);
}
else if (IsMe(bcptr))
{