]>
Commit | Line | Data |
---|---|---|
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 | |
16 | MODULE_VERSION(""); | |
c96aa815 P |
17 | |
18 | int spcmd_splitlist(void *source, int cargc, char **cargv); | |
19 | int spcmd_splitdel(void *source, int cargc, char **cargv); | |
719d21bb | 20 | int spcmd_splitadd(void *source, int cargc, char **cargv); |
c96aa815 P |
21 | |
22 | void _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 | ||
39 | void _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 */ | |
46 | int 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 | ||
70 | int 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 |
99 | static 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 |
113 | int 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 | } |