unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
map.c (5567B)
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 23 #include "unrealircd.h" 24 25 CMD_FUNC(cmd_map); 26 27 #define MSG_MAP "MAP" 28 29 static int lmax = 0; 30 static int umax = 0; 31 32 static int dcount(int n) 33 { 34 int cnt = 0; 35 36 while (n != 0) 37 { 38 n = n/10; 39 cnt++; 40 } 41 42 return cnt; 43 } 44 45 ModuleHeader MOD_HEADER 46 = { 47 "map", 48 "5.0", 49 "command /map", 50 "UnrealIRCd Team", 51 "unrealircd-6", 52 }; 53 54 MOD_INIT() 55 { 56 CommandAdd(modinfo->handle, MSG_MAP, cmd_map, MAXPARA, CMD_USER); 57 ISupportAdd(modinfo->handle, "MAP", NULL); 58 MARK_AS_OFFICIAL_MODULE(modinfo); 59 return MOD_SUCCESS; 60 } 61 62 MOD_LOAD() 63 { 64 return MOD_SUCCESS; 65 } 66 67 MOD_UNLOAD() 68 { 69 return MOD_SUCCESS; 70 } 71 72 /* 73 * New /MAP format -Potvin 74 * dump_map function. 75 */ 76 static void dump_map(Client *client, Client *server, char *mask, int prompt_length, int length) 77 { 78 static char prompt[64]; 79 char *p = &prompt[prompt_length]; 80 int cnt = 0; 81 Client *acptr; 82 83 *p = '\0'; 84 85 if (prompt_length > 60) 86 sendnumeric(client, RPL_MAPMORE, prompt, length, server->name); 87 else 88 { 89 char tbuf[256]; 90 char sid[10]; 91 int len = length - strlen(server->name) + 1; 92 93 if (len < 0) 94 len = 0; 95 if (len > 255) 96 len = 255; 97 98 tbuf[len--] = '\0'; 99 while (len >= 0) 100 tbuf[len--] = '-'; 101 if (IsOper(client)) 102 snprintf(sid, sizeof(sid), " [%s]", server->id); 103 sendnumeric(client, RPL_MAP, prompt, server->name, tbuf, umax, 104 server->server->users, (double)(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5, 105 (server->server->users * 100.0 / irccounts.clients), 106 IsOper(client) ? sid : ""); 107 cnt = 0; 108 } 109 110 if (prompt_length > 0) 111 { 112 p[-1] = ' '; 113 if (p[-2] == '`') 114 p[-2] = ' '; 115 } 116 if (prompt_length > 60) 117 return; 118 119 strcpy(p, "|-"); 120 121 list_for_each_entry(acptr, &global_server_list, client_node) 122 { 123 if (acptr->uplink != server || 124 (IsULine(acptr) && HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL))) 125 continue; 126 SetMap(acptr); 127 cnt++; 128 } 129 130 list_for_each_entry(acptr, &global_server_list, client_node) 131 { 132 if (IsULine(acptr) && HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) 133 continue; 134 if (acptr->uplink != server) 135 continue; 136 if (!IsMap(acptr)) 137 continue; 138 if (--cnt == 0) 139 *p = '`'; 140 dump_map(client, acptr, mask, prompt_length + 2, length - 2); 141 } 142 143 if (prompt_length > 0) 144 p[-1] = '-'; 145 } 146 147 void dump_flat_map(Client *client, Client *server, int length) 148 { 149 char buf[4]; 150 char tbuf[256]; 151 Client *acptr; 152 int cnt = 0, len = 0, hide_ulines; 153 154 hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0; 155 156 len = length - strlen(server->name) + 3; 157 if (len < 0) 158 len = 0; 159 if (len > 255) 160 len = 255; 161 162 tbuf[len--] = '\0'; 163 while (len >= 0) 164 tbuf[len--] = '-'; 165 166 sendnumeric(client, RPL_MAP, "", server->name, tbuf, umax, server->server->users, 167 (lmax < 10) ? 4 : (lmax == 100) ? 6 : 5, 168 (server->server->users * 100.0 / irccounts.clients), ""); 169 170 list_for_each_entry(acptr, &global_server_list, client_node) 171 { 172 if ((IsULine(acptr) && hide_ulines) || (acptr == server)) 173 continue; 174 cnt++; 175 } 176 177 strcpy(buf, "|-"); 178 list_for_each_entry(acptr, &global_server_list, client_node) 179 { 180 if ((IsULine(acptr) && hide_ulines) || (acptr == server)) 181 continue; 182 if (--cnt == 0) 183 *buf = '`'; 184 185 len = length - strlen(acptr->name) + 1; 186 if (len < 0) 187 len = 0; 188 if (len > 255) 189 len = 255; 190 191 tbuf[len--] = '\0'; 192 while (len >= 0) 193 tbuf[len--] = '-'; 194 195 sendnumeric(client, RPL_MAP, buf, acptr->name, tbuf, umax, acptr->server->users, 196 (lmax < 10) ? 4 : (lmax == 100) ? 6 : 5, 197 (acptr->server->users * 100.0 / irccounts.clients), ""); 198 } 199 } 200 201 /* 202 ** New /MAP format. -Potvin 203 ** cmd_map (NEW) 204 ** 205 ** parv[1] = server mask 206 **/ 207 CMD_FUNC(cmd_map) 208 { 209 Client *acptr; 210 int longest = strlen(me.name); 211 float avg_users; 212 213 umax = 0; 214 lmax = 0; 215 216 if (parc < 2) 217 parv[1] = "*"; 218 219 list_for_each_entry(acptr, &global_server_list, client_node) 220 { 221 int perc = (acptr->server->users * 100 / irccounts.clients); 222 if ((strlen(acptr->name) + acptr->hopcount * 2) > longest) 223 longest = strlen(acptr->name) + acptr->hopcount * 2; 224 if (lmax < perc) 225 lmax = perc; 226 if (umax < dcount(acptr->server->users)) 227 umax = dcount(acptr->server->users); 228 } 229 230 if (longest > 60) 231 longest = 60; 232 longest += 2; 233 234 if (FLAT_MAP && !ValidatePermissionsForPath("server:info:map:real-map",client,NULL,NULL,NULL)) 235 dump_flat_map(client, &me, longest); 236 else 237 dump_map(client, &me, "*", 0, longest); 238 239 avg_users = irccounts.clients * 1.0 / irccounts.servers; 240 sendnumeric(client, RPL_MAPUSERS, irccounts.servers, (irccounts.servers > 1 ? "s" : ""), irccounts.clients, 241 (irccounts.clients > 1 ? "s" : ""), avg_users); 242 sendnumeric(client, RPL_MAPEND); 243 }