]> jfr.im git - irc/quakenet/newserv.git/blame - splitlist/splitlist_commands.c
fix assorted undefined functions on newer OS
[irc/quakenet/newserv.git] / splitlist / splitlist_commands.c
CommitLineData
c96aa815
P
1/* oper commands for the splitlist */
2
719d21bb
P
3#include <errno.h>
4#include <string.h>
e7e7312d 5#include <strings.h>
719d21bb 6
c96aa815
P
7#include "../lib/irc_string.h"
8#include "../irc/irc.h"
719d21bb 9#include "../irc/irc_config.h"
c96aa815 10#include "../splitlist/splitlist.h"
81f6c579 11#include "../serverlist/serverlist.h"
c96aa815 12#include "../control/control.h"
5857b2db 13#include "../lib/version.h"
719d21bb 14#include "../lib/flags.h"
5857b2db
P
15
16MODULE_VERSION("");
c96aa815
P
17
18int spcmd_splitlist(void *source, int cargc, char **cargv);
19int spcmd_splitdel(void *source, int cargc, char **cargv);
719d21bb 20int spcmd_splitadd(void *source, int cargc, char **cargv);
c96aa815
P
21
22void _init(void) {
81f6c579 23 registercontrolhelpcmd("splitlist", NO_STAFF, 0, &spcmd_splitlist, "Usage: splitlist\nLists servers currently split from the network.");
c96aa815 24 registercontrolcmd("splitdel", 10, 1, &spcmd_splitdel);
719d21bb
P
25 registercontrolhelpcmd("splitadd", 10, 3, &spcmd_splitadd,
26 "Usage: splitadd <servername> [+flags] [split time as unix timestamp]\n"
27 " Adds a server as split from the network.\n"
28 " Flags:\n"
29 " +c: Client server\n"
30 " +h: Hub server\n"
31 " +s: Service\n"
32 " +Q: Q/CServe\n"
33 " +S: S/spamscan\n"
34 " +X: Other critical service\n"
35 " If no flags are given, an attempt to figure them out based on name\n"
6c4405e0 36 " will be made, but it's likely not a good one.");
c96aa815
P
37}
38
39void _fini(void) {
40 deregistercontrolcmd("splitlist", &spcmd_splitlist);
41 deregistercontrolcmd("splitdel", &spcmd_splitdel);
719d21bb 42 deregistercontrolcmd("splitadd", &spcmd_splitadd);
c96aa815
P
43}
44
45/* todo: add RELINK status */
46int spcmd_splitlist(void *source, int cargc, char **cargv) {
47 nick *np = (nick*)source;
48 int i;
49 splitserver srv;
50
51 if (splitlist.cursi == 0) {
52 controlreply(np, "There currently aren't any registered splits.");
53
54 return CMD_OK;
55 }
56
57 controlreply(np, "Server Status Split for");
58
59 for (i = 0; i < splitlist.cursi; i++) {
60 srv = ((splitserver*)splitlist.content)[i];
61
81f6c579 62 controlreply(np, "%s M.I.A. %s (%s)", srv.name->content, longtoduration(getnettime() - srv.ts, 1), printflags(srv.type, servertypeflags));
c96aa815
P
63 }
64
65 controlreply(np, "--- End of splitlist");
66
67 return CMD_OK;
68}
69
70int spcmd_splitdel(void *source, int cargc, char **cargv) {
71 nick *np = (nick*)source;
72 int i, count;
73 splitserver srv;
74
75 if (cargc < 1) {
76 controlreply(np, "Syntax: splitdel <pattern>");
77
78 return CMD_ERROR;
79 }
80
81 count = 0;
82
83 for (i = splitlist.cursi - 1; i >= 0; i--) {
84 srv = ((splitserver*)splitlist.content)[i];
85
86 if (match2strings(cargv[0], srv.name->content)) {
87 sp_deletesplit(srv.name->content); /* inefficient .. but it doesn't matter */
88 count++;
89 }
90 }
91
7fb2e4b8
C
92 if (count > 0)
93 controlwall(NO_OPERED, NL_MISC, "%s/%s used SPLITDEL on %s", np->nick, np->authname, cargv[0]);
c96aa815
P
94 controlreply(np, "%d %s deleted.", count, count != 1 ? "splits" : "split");
95
96 return CMD_OK;
97}
719d21bb 98
6c4405e0
P
99static int doessplitalreadyexist(const char *servername) {
100 splitserver srv;
101 unsigned int i;
102
103 for (i = 0; i < splitlist.cursi; i++) {
104 srv = ((splitserver*)splitlist.content)[i];
105
106 if (!strcasecmp(srv.name->content, servername))
107 return 1;
108 }
109
110 return 0;
111}
112
719d21bb
P
113int spcmd_splitadd(void *source, int cargc, char **cargv) {
114 nick *np = (nick*)source;
115 unsigned long long num;
116 char *end;
117 flag_t servertype = 0;
118 char *servername;
119 size_t servernamelen;
120 time_t splittime;
121 server fake;
122
123 if (cargc < 1) {
124 controlreply(np, "Usage: splitadd <servername> [+flags] [split time as unix timestamp]");
125 return CMD_ERROR;
126 }
127
128 servername = cargv[0];
129 servernamelen = strlen(servername);
130
131 if (findserver(servername) != -1) {
132 controlreply(np, "Server %s is linked right now, refusing to add split.",
133 servername);
134 return CMD_ERROR;
135 }
136
6c4405e0
P
137 if (doessplitalreadyexist(servername)) {
138 controlreply(np, "There is a split for %s already.", servername);
139 return CMD_ERROR;
140 }
141
719d21bb
P
142 if (servernamelen > SERVERLEN) {
143 controlreply(np, "Server name %s is too long (max: %d characters)",
144 servername, SERVERLEN);
145 return CMD_ERROR;
146 }
147
148 /* Handle flags */
149 if (cargc > 1) {
150 if (setflags(&servertype, (flag_t)-1, cargv[1], servertypeflags,
151 REJECT_UNKNOWN) != REJECT_NONE) {
6c4405e0 152 controlreply(np, "Flag string %s contained invalid flags.", cargv[1]);
719d21bb
P
153 return CMD_ERROR;
154 }
155 } else {
156 /* Set up a fake server for getservertype. */
157 memset(&fake, 0, sizeof(fake));
158
159 fake.name = getsstring(servername, servernamelen);
160 servertype = getservertype(&fake);
161 freesstring(fake.name);
162 }
163
164 /* Handle timestamp */
165 if (cargc < 3) {
166 splittime = getnettime();
167 } else {
168 errno = 0;
169 num = strtoull(cargv[2], &end, 10);
170 if (errno == ERANGE) {
6c4405e0 171 controlreply(np, "%s is out of range for a timestamp.", cargv[2]);
719d21bb
P
172 return CMD_ERROR;
173 }
174
175 /* Truncation may happen here.
176 * However, there's no way to get the max time_t value, so we'll just try to
177 * find out after the fact.
178 */
179 splittime = (time_t)num;
180
181 if ((unsigned long long)splittime < num) {
182 controlreply(np, "Tried to use %llu as split time value, but it's too "
183 "large for the system to handle", num);
184 return CMD_ERROR;
185 }
186 }
187
188 sp_addsplit(servername, splittime, servertype);
189 controlreply(np, "Added split for %s (%s ago) with flags %s.",
190 servername, longtoduration(getnettime() - splittime, 1),
191 printflags(servertype, servertypeflags));
192
193 return CMD_OK;
194}