1 /* Some utterly useless dog */
3 #include "../core/schedule.h"
4 #include "../irc/irc.h"
5 #include "../lib/irc_string.h"
6 #include "../localuser/localuserchannel.h"
7 #include "../control/control.h"
8 #include "../usercount/usercount.h"
9 #include "../lib/version.h"
19 int cmd_serverlist(void *sender
, int cargc
, char **cargv
);
20 void serverlist_hook_newserver(int hook
, void *arg
);
21 void serverlist_hook_lostserver(int hook
, void *arg
);
22 int serverlist_versionreply(void *source
, int cargc
, char **cargv
);
23 void serverlist_pingservers(void *arg
);
24 int serverlist_rpong(void *source
, int cargc
, char **cargv
);
32 } serverinfo
[MAXSERVERS
];
34 void serverlist_doversion(void);
38 registercontrolhelpcmd("serverlist",NO_OPER
,1,&cmd_serverlist
,"Usage: serverlist [pattern]\nShows all currently connected servers");
39 /* hooks for serverlist */
40 registerhook(HOOK_SERVER_NEWSERVER
, &serverlist_hook_newserver
);
41 registerhook(HOOK_SERVER_LOSTSERVER
, &serverlist_hook_lostserver
);
44 for (i
= 0; i
< MAXSERVERS
; i
++) {
45 if (serverlist
[i
].linkstate
== LS_LINKED
)
46 serverinfo
[i
].used
= 1;
48 serverinfo
[i
].used
= 0;
50 serverinfo
[i
].ts
= getnettime();
51 serverinfo
[i
].lag
= -1;
52 serverinfo
[i
].version1
= NULL
;
53 serverinfo
[i
].version2
= NULL
;
55 registernumerichandler(351, &serverlist_versionreply
, 2);
56 registerserverhandler("RO", &serverlist_rpong
, 4);
58 schedulerecurring(time(NULL
)+1, 0, 60, &serverlist_pingservers
, NULL
);
63 for (i
= 0; i
< MAXSERVERS
; i
++) {
64 if (serverinfo
[i
].used
) {
65 freesstring(serverinfo
[i
].version1
);
66 freesstring(serverinfo
[i
].version2
);
69 deregisternumerichandler(351, &serverlist_versionreply
);
70 deregisterserverhandler("RO", &serverlist_rpong
);
72 deregisterhook(HOOK_SERVER_NEWSERVER
, &serverlist_hook_newserver
);
73 deregisterhook(HOOK_SERVER_LOSTSERVER
, &serverlist_hook_lostserver
);
75 deregistercontrolcmd("serverlist",cmd_serverlist
);
77 deleteschedule(NULL
, &serverlist_pingservers
, NULL
);
80 int cmd_serverlist(void *sender
, int cargc
, char **cargv
) {
81 nick
*np
= (nick
*)sender
;
82 int a
, i
, ucount
, acount
, scount
;
85 controlreply(np
, "%-7s %-30s %5s/%5s/%-5s %-7s %-16s %-8s %-20s", "Numeric", "Hostname", "ECl", "Cl", "MaxCl", "Flags", "Connected for", "Lag", "Version");
89 for (i
= 0; i
< MAXSERVERS
; i
++) {
90 if (serverlist
[i
].linkstate
== LS_LINKED
&& (cargc
< 1 || match2strings(cargv
[0], serverlist
[i
].name
->content
))) {
93 for (a
= 0; a
<= serverlist
[i
].maxusernum
; a
++)
94 if (servernicks
[i
][a
] != NULL
)
100 if (serverinfo
[i
].lag
== -1)
103 snprintf(lagstr
, sizeof(lagstr
), "%d", serverinfo
[i
].lag
);
105 controlreply(np
, "%-7d %-30s %5d/%5d/%-5d %-7s %-16s %-8s %-20s - %s", i
, serverlist
[i
].name
->content
,
106 servercount
[i
], ucount
, serverlist
[i
].maxusernum
,
107 printflags(serverlist
[i
].flags
, smodeflags
),
108 longtoduration(getnettime() - serverinfo
[i
].ts
, 0),
110 serverinfo
[i
].version1
? serverinfo
[i
].version1
->content
: "Unknown",
111 serverinfo
[i
].version2
? serverinfo
[i
].version2
->content
: "Unknown");
115 controlreply(np
, "--- End of list. %d users and %d servers on the net.", acount
, scount
);
117 /* update version info for next time */
118 serverlist_doversion();
123 int serverlist_versionreply(void *source
, int cargc
, char **cargv
) {
129 num
= numerictolong(cargv
[0], 2);
131 if (serverinfo
[num
].used
) {
132 freesstring(serverinfo
[num
].version1
);
133 freesstring(serverinfo
[num
].version2
);
135 serverinfo
[num
].version1
= getsstring(cargv
[3], strlen(cargv
[3]));
136 serverinfo
[num
].version2
= getsstring(cargv
[5], strlen(cargv
[5]));
141 void serverlist_doversion(void) {
143 char *num1
, *numeric
;
148 for (i
= 0; i
< MAXSERVERS
; i
++) {
149 if (serverlist
[i
].linkstate
== LS_LINKED
&& serverinfo
[i
].version1
== NULL
) {
150 numeric
= longtonumeric(mynick
->numeric
,5);
151 num1
= (char*)malloc(strlen(numeric
) + 1); /* bleh.. longtonumeric() is using static variables */
152 strcpy(num1
, numeric
);
154 irc_send("%s V :%s", num1
, longtonumeric(i
,2));
160 void serverlist_hook_newserver(int hook
, void *arg
) {
161 char *num1
, *numeric
;
162 long num
= (long)arg
;
167 serverinfo
[num
].used
= 1;
168 serverinfo
[num
].ts
= getnettime();
169 serverinfo
[num
].version1
= NULL
;
170 serverinfo
[num
].version2
= NULL
;
172 numeric
= longtonumeric(mynick
->numeric
,5);
173 num1
= (char*)malloc(strlen(numeric
) + 1); /* bleh.. longtonumeric() is using static variables */
174 strcpy(num1
, numeric
);
176 irc_send("%s V :%s", num1
, longtonumeric(num
,2));
181 void serverlist_hook_lostserver(int hook
, void *arg
) {
182 long num
= (long)arg
;
184 serverinfo
[num
].used
= 0;
185 freesstring(serverinfo
[num
].version1
);
186 freesstring(serverinfo
[num
].version2
);
190 void serverlist_pingservers(void *arg
) {
193 char fnum
[10], tnum
[10];
199 for(i
=0;i
<MAXSERVERS
;i
++) {
202 if (to
->parent
== -1)
205 from
= &serverlist
[to
->parent
];
207 if (to
->linkstate
!= LS_LINKED
|| from
->linkstate
!= LS_LINKED
)
210 strcpy(fnum
, longtonumeric(to
->parent
,2));
211 strcpy(tnum
, longtonumeric(i
, 2));
213 if (from
->parent
== -1) { /* Are we the source? */
214 (void) gettimeofday(&tv
, NULL
);
215 irc_send("%s RI %s %s %jd %jd :RP", mynumeric
->content
, tnum
, longtonumeric(mynick
->numeric
,5), (intmax_t)tv
.tv_sec
, (intmax_t)tv
.tv_usec
);
217 strcpy(fnum
, longtonumeric(to
->parent
,2));
218 strcpy(tnum
, longtonumeric(i
, 2));
219 irc_send("%s RI %s %s :RP", longtonumeric(mynick
->numeric
,5), to
->name
->content
, fnum
);
224 int serverlist_rpong(void *source
, int cargc
, char **cargv
) {
231 if (cargc
== 5) { /* From target to source server */
232 if (strcmp(cargv
[4], "RP") != 0)
235 to
= numerictolong(source
, 2);
237 (void) gettimeofday(&tv
, NULL
);
238 lag
= (tv
.tv_sec
- strtoull(cargv
[2], NULL
, 10)) * 1000 + (tv
.tv_usec
- strtoull(cargv
[3], NULL
, 10)) / 1000;
239 } else { /* From source server to client */
240 if (strcmp(cargv
[3], "RP") != 0)
243 to
= findserver(cargv
[1]);
248 lag
= atoi(cargv
[2]);
251 serverinfo
[to
].lag
= lag
;