1 |
/* Copyright (C) 2003, 2004 Stephane Thiell |
2 |
* |
3 |
* This file is part of pxyservd (from pxys) |
4 |
* |
5 |
* This program is free software; you can redistribute it and/or |
6 |
* modify it under the terms of the GNU General Public License |
7 |
* as published by the Free Software Foundation; either version 2 |
8 |
* of the License, or (at your option) any later version. |
9 |
* |
10 |
* This program is distributed in the hope that it will be useful, |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
* GNU General Public License for more details. |
14 |
* |
15 |
* You should have received a copy of the GNU General Public License |
16 |
* along with this program; if not, write to the Free Software |
17 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 |
* |
19 |
*/ |
20 |
#define RCSID "$Id: cmd_proxytop.c,v 1.2 2004/01/10 14:32:29 mbuna Exp $" |
21 |
|
22 |
#ifdef HAVE_CONFIG_H |
23 |
#include "config.h" |
24 |
#endif |
25 |
|
26 |
#include "irc_cmd.h" |
27 |
#include "irc_network.h" |
28 |
#include "irc_send.h" |
29 |
#include "irc_struct.h" |
30 |
|
31 |
#include <stdlib.h> |
32 |
#include <string.h> |
33 |
|
34 |
#include <peak/peak.h> |
35 |
|
36 |
extern time_t proxy_count_last_reset_time; |
37 |
|
38 |
static void |
39 |
proxytop_server_cb(struct Server *sptr, void *context) |
40 |
{ |
41 |
struct Server ***p = (struct Server ***)context; |
42 |
*(*p)++ = sptr; |
43 |
} |
44 |
|
45 |
static int |
46 |
proxytop_comparator(const void *s1, const void *s2) |
47 |
{ |
48 |
struct Server *server1 = *(struct Server **)s1; |
49 |
struct Server *server2 = *(struct Server **)s2; |
50 |
unsigned int t1 = server1->proxy_count; |
51 |
unsigned int t2 = server2->proxy_count; |
52 |
int result; |
53 |
|
54 |
if (t1 < t2) |
55 |
result = 1; |
56 |
else if (t1 > t2) |
57 |
result = -1; |
58 |
else if (server1->proxy_since > server2->proxy_since) |
59 |
result = 1; |
60 |
else if (server1->proxy_since < server2->proxy_since) |
61 |
result = -1; |
62 |
else |
63 |
result = strcmp(server1->name, server2->name); |
64 |
|
65 |
return result; |
66 |
} |
67 |
|
68 |
void |
69 |
cmd_proxytop(struct Client *cptr, toktabptr ttab) |
70 |
{ |
71 |
const char *dst = ttab->tok[0]; |
72 |
struct Server **base, **p, *s; |
73 |
unsigned int total = 0; |
74 |
int count, i, rank; |
75 |
peak_tz tz = peak_tz_create_system(); |
76 |
peak_time_date gdate; |
77 |
|
78 |
count = irc_network_get_remote_server_count(); |
79 |
|
80 |
#ifdef HAVE_ALLOCA |
81 |
base = (struct Server **)alloca(count * sizeof(struct Server *)); |
82 |
#else |
83 |
base = (struct Server **)peak_allocate(count * sizeof(struct Server *)); |
84 |
#endif |
85 |
|
86 |
p = base; |
87 |
irc_network_map_servers(proxytop_server_cb, &p); |
88 |
|
89 |
qsort(base, count, sizeof(struct Server *), proxytop_comparator); |
90 |
|
91 |
for (i = 0, p = base; i < count; i++, p++) |
92 |
total += (*p)->proxy_count; |
93 |
|
94 |
if (!total) |
95 |
total = 1; |
96 |
|
97 |
send_client_to_one(dst, "RANK SERVER PROXY-COUNT/PERCENTAGE (MAXUSERS)"); |
98 |
|
99 |
for (i = 0, p = base, rank = 1; i < count; i++) |
100 |
{ |
101 |
s = *p++; |
102 |
if (s->proxy_count || s->maxclients) |
103 |
send_client_to_one(dst, "%02d %s%s \2%lu\2 %.2f%% (%lu)", |
104 |
rank++, |
105 |
(s->flags & SERVER_FLAG_BURSTING) ? "\2!\2" : " ", |
106 |
s->name, |
107 |
s->proxy_count, |
108 |
100.0 * (double)s->proxy_count/(double)total, |
109 |
s->maxclients); |
110 |
} |
111 |
if (tz) |
112 |
{ |
113 |
time_t last = proxy_count_last_reset_time; |
114 |
gdate = peak_time_get_date(last, tz); |
115 |
send_client_to_one(dst, "PROXYTOP SINCE %d-%d-%d %d:%02d:%02d %s", |
116 |
gdate.year, gdate.month, gdate.day, gdate.hour, |
117 |
gdate.minute, (int)gdate.second, |
118 |
peak_tz_get_abbreviation(tz, last)); |
119 |
} |
120 |
#ifndef HAVE_ALLOCA |
121 |
peak_deallocate(base); |
122 |
#endif |
123 |
peak_release(tz); |
124 |
} |