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