]>
jfr.im git - solanum.git/blob - modules/m_map.c
2 * ircd-ratbox: A slightly useful ircd.
3 * m_map.c: Sends an Undernet compatible map to a user.
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
31 #define USER_COL 50 /* display | Users: %d at col 50 */
33 static const char map_desc
[] = "Provides the MAP command to view network topology information";
35 static void m_map(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[]);
36 static void mo_map(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[]);
38 struct Message map_msgtab
= {
40 {mg_unreg
, {m_map
, 0}, mg_ignore
, mg_ignore
, mg_ignore
, {mo_map
, 0}}
43 mapi_clist_av1 map_clist
[] = { &map_msgtab
, NULL
};
45 DECLARE_MODULE_AV2(map
, NULL
, NULL
, map_clist
, NULL
, NULL
, NULL
, NULL
, map_desc
);
47 static void dump_map(struct Client
*client_p
, struct Client
*root
, char *pbuf
);
48 static void flattened_map(struct Client
*client_p
);
50 static char buf
[BUFSIZE
];
55 m_map(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
57 if((!IsExemptShide(source_p
) && ConfigServerHide
.flatten_links
) ||
58 ConfigFileEntry
.map_oper_only
)
60 flattened_map(client_p
);
61 sendto_one_numeric(client_p
, RPL_MAPEND
, form_str(RPL_MAPEND
));
65 dump_map(client_p
, &me
, buf
);
66 sendto_one_numeric(client_p
, RPL_MAPEND
, form_str(RPL_MAPEND
));
73 mo_map(struct MsgBuf
*msgbuf_p
, struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
75 dump_map(client_p
, &me
, buf
);
76 scache_send_missing(client_p
);
77 sendto_one_numeric(client_p
, RPL_MAPEND
, form_str(RPL_MAPEND
));
82 ** dumps server map, called recursively.
85 dump_map(struct Client
*client_p
, struct Client
*root_p
, char *pbuf
)
87 int cnt
= 0, i
= 0, len
, frac
;
88 struct Client
*server_p
;
92 rb_strlcat(pbuf
, root_p
->name
, BUFSIZE
);
95 rb_strlcat(pbuf
, "[", BUFSIZE
);
96 rb_strlcat(pbuf
, root_p
->id
, BUFSIZE
);
97 rb_strlcat(pbuf
, "]", BUFSIZE
);
104 for (i
= len
+ 1; i
< USER_COL
; i
++)
110 frac
= (1000 * rb_dlink_list_length(&root_p
->serv
->users
) + Count
.total
/ 2) / Count
.total
;
111 snprintf(buf
+ USER_COL
, BUFSIZE
- USER_COL
,
112 " | Users: %5lu (%2d.%1d%%)", rb_dlink_list_length(&root_p
->serv
->users
),
113 frac
/ 10, frac
% 10);
115 sendto_one_numeric(client_p
, RPL_MAP
, form_str(RPL_MAP
), buf
);
117 if(root_p
->serv
->servers
.head
!= NULL
)
119 cnt
+= rb_dlink_list_length(&root_p
->serv
->servers
);
132 RB_DLINK_FOREACH(ptr
, root_p
->serv
->servers
.head
)
134 server_p
= ptr
->data
;
143 dump_map(client_p
, server_p
, pbuf
+ 4);
150 * flattened_map - display a version of map that doesn't give away routing
151 * information to users when flattened links is enabled.
154 flattened_map(struct Client
*client_p
)
158 struct Client
*target_p
;
160 unsigned long cnt
= 0;
162 /* First display me as the root */
163 rb_strlcpy(buf
, me
.name
, BUFSIZE
);
169 for (i
= len
+ 1; i
< USER_COL
; i
++)
175 snprintf(buf
+ USER_COL
, BUFSIZE
- USER_COL
,
176 " | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&me
.serv
->users
),
177 100 * (float) rb_dlink_list_length(&me
.serv
->users
) / (float) Count
.total
);
179 sendto_one_numeric(client_p
, RPL_MAP
, form_str(RPL_MAP
), buf
);
181 /* Next, we run through every other server and list them */
182 RB_DLINK_FOREACH(ptr
, global_serv_list
.head
)
184 target_p
= ptr
->data
;
188 /* Skip ourselves, it's already counted */
192 /* if we're hidden, go on to the next leaf */
193 if(!ConfigServerHide
.disable_hidden
&& IsHidden(target_p
))
196 if (cnt
== rb_dlink_list_length(&global_serv_list
))
197 rb_strlcpy(buf
, " `- ", BUFSIZE
);
199 rb_strlcpy(buf
, " |- ", BUFSIZE
);
201 rb_strlcat(buf
, target_p
->name
, BUFSIZE
);
207 for (i
= len
+ 1; i
< USER_COL
; i
++)
213 snprintf(buf
+ USER_COL
, BUFSIZE
- USER_COL
,
214 " | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&target_p
->serv
->users
),
215 100 * (float) rb_dlink_list_length(&target_p
->serv
->users
) / (float) Count
.total
);
217 sendto_one_numeric(client_p
, RPL_MAP
, form_str(RPL_MAP
), buf
);