00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdinc.h"
00026 #include "handlers.h"
00027 #include "client.h"
00028 #include "channel.h"
00029 #include "ircd.h"
00030 #include "irc_string.h"
00031 #include "numeric.h"
00032 #include "s_serv.h"
00033 #include "send.h"
00034 #include "msg.h"
00035 #include "parse.h"
00036 #include "modules.h"
00037 #include "s_conf.h"
00038 #include "s_log.h"
00039 #include "resv.h"
00040 #include "hash.h"
00041
00042 static void mo_resv(struct Client *, struct Client *, int, char *[]);
00043 static void me_resv(struct Client *, struct Client *, int, char *[]);
00044 static void ms_resv(struct Client *, struct Client *, int, char *[]);
00045 static void mo_unresv(struct Client *, struct Client *, int, char *[]);
00046 static void ms_unresv(struct Client *, struct Client *, int, char *[]);
00047
00048 static void parse_resv(struct Client *, char *, int, char *);
00049 static void remove_resv(struct Client *, const char *);
00050
00051 struct Message resv_msgtab = {
00052 "RESV", 0, 0, 3, 0, MFLG_SLOW, 0,
00053 { m_ignore, m_not_oper, ms_resv, me_resv, mo_resv, m_ignore }
00054 };
00055
00056 struct Message unresv_msgtab = {
00057 "UNRESV", 0, 0, 2, 0, MFLG_SLOW, 0,
00058 { m_ignore, m_not_oper, ms_unresv, m_ignore, mo_unresv, m_ignore }
00059 };
00060
00061 #ifndef STATIC_MODULES
00062 void
00063 _modinit(void)
00064 {
00065 mod_add_cmd(&resv_msgtab);
00066 mod_add_cmd(&unresv_msgtab);
00067 }
00068
00069 void
00070 _moddeinit(void)
00071 {
00072 mod_del_cmd(&resv_msgtab);
00073 mod_del_cmd(&unresv_msgtab);
00074 }
00075
00076 const char *_version = "$Revision: 33 $";
00077 #endif
00078
00079
00080
00081
00082
00083 static void
00084 mo_resv(struct Client *client_p, struct Client *source_p,
00085 int parc, char *parv[])
00086 {
00087 char *resv = NULL;
00088 char *reason = NULL;
00089 char *target_server = NULL;
00090 time_t tkline_time = 0;
00091
00092
00093
00094
00095 if (parse_aline("RESV", source_p, parc, parv,
00096 AWILD, &resv, NULL, &tkline_time, &target_server, &reason) < 0)
00097 return;
00098
00099 if (target_server != NULL)
00100 {
00101
00102 if (tkline_time != 0)
00103 sendto_match_servs(source_p, target_server, CAP_ENCAP,
00104 "ENCAP %s RESV %d %s 0 :%s",
00105 target_server, (int)tkline_time, resv, reason);
00106 else
00107 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
00108 "RESV %s %s :%s",
00109 target_server, resv, reason);
00110
00111 if (!match(target_server, me.name))
00112 return;
00113 }
00114 else
00115 {
00116
00117
00118
00119 if (tkline_time != 0)
00120 cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_RESV,
00121 "RESV %d %s 0 : %s", (int)tkline_time, resv, reason);
00122 else
00123 cluster_a_line(source_p, "RESV", CAP_KLN, SHARED_RESV,
00124 "%s : %s", resv, reason);
00125 }
00126
00127 parse_resv(source_p, resv, (int)tkline_time, reason);
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 static void
00148 me_resv(struct Client *client_p, struct Client *source_p,
00149 int parc, char *parv[])
00150 {
00151 if (parc != 5 || !IsClient(source_p))
00152 return;
00153
00154 parse_resv(source_p, parv[2], atoi(parv[1]), parv[4]);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 static void
00164 ms_resv(struct Client *client_p, struct Client *source_p,
00165 int parc, char *parv[])
00166 {
00167 if ((parc != 4) || EmptyString(parv[3]))
00168 return;
00169
00170 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
00171 "RESV %s %s :%s",
00172 parv[1], parv[2], parv[3]);
00173
00174 if (!IsClient(source_p) || !match(parv[1], me.name))
00175 return;
00176
00177 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
00178 source_p->username, source_p->host,
00179 SHARED_RESV))
00180 parse_resv(source_p, parv[2], 0, parv[3]);
00181 }
00182
00183
00184
00185
00186
00187 static void
00188 mo_unresv(struct Client *client_p, struct Client *source_p,
00189 int parc, char *parv[])
00190 {
00191 char *resv = NULL;
00192 char *reason = NULL;
00193 char *target_server = NULL;
00194
00195
00196
00197 if (parse_aline("UNRESV", source_p, parc, parv,
00198 0, &resv, NULL, NULL, &target_server, &reason) < 0)
00199 return;
00200
00201 if (target_server != NULL)
00202 {
00203 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
00204 "UNRESV %s %s",
00205 target_server, resv);
00206
00207
00208 if (!match(target_server, me.name))
00209 return;
00210 }
00211 else
00212 cluster_a_line(source_p, "UNRESV", CAP_KLN, SHARED_UNRESV, resv);
00213
00214 remove_resv(source_p, resv);
00215 }
00216
00217
00218
00219
00220
00221
00222 static void
00223 ms_unresv(struct Client *client_p, struct Client *source_p,
00224 int parc, char *parv[])
00225 {
00226 if ((parc != 3) || EmptyString(parv[2]))
00227 return;
00228
00229 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
00230 "UNRESV %s %s",
00231 parv[1], parv[2]);
00232
00233 if (!IsClient(source_p) || !match(parv[1], me.name))
00234 return;
00235
00236 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
00237 source_p->username, source_p->host,
00238 SHARED_UNRESV))
00239 remove_resv(source_p, parv[2]);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 static void
00252 parse_resv(struct Client *source_p, char *name, int tkline_time, char *reason)
00253 {
00254 struct ConfItem *conf = NULL;
00255
00256 if (IsChanPrefix(*name))
00257 {
00258 struct ResvChannel *resv_p;
00259
00260 if ((conf = create_channel_resv(name, reason, 0)) == NULL)
00261 {
00262 sendto_one(source_p,
00263 ":%s NOTICE %s :A RESV has already been placed on channel: %s",
00264 me.name, source_p->name, name);
00265 return;
00266 }
00267
00268 resv_p = map_to_conf(conf);
00269
00270 if (tkline_time != 0)
00271 {
00272 sendto_one(source_p,
00273 ":%s NOTICE %s :A %d minute %s RESV has been placed on channel: %s",
00274 me.name, source_p->name,
00275 tkline_time/60,
00276 (MyClient(source_p) ? "local" : "remote"), name);
00277 sendto_realops_flags(UMODE_ALL, L_ALL,
00278 "%s has placed a %d minute %s RESV on channel: %s [%s]",
00279 get_oper_name(source_p),
00280 tkline_time/60,
00281 (MyClient(source_p) ? "local" : "remote"),
00282 resv_p->name, resv_p->reason);
00283 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
00284 source_p->name, (int)tkline_time/60,
00285 conf->name, resv_p->reason);
00286 resv_p->hold = CurrentTime + tkline_time;
00287 add_temp_line(conf);
00288 }
00289 else
00290 {
00291 sendto_one(source_p,
00292 ":%s NOTICE %s :A %s RESV has been placed on channel %s",
00293 me.name, source_p->name,
00294 (MyClient(source_p) ? "local" : "remote"), name);
00295 sendto_realops_flags(UMODE_ALL, L_ALL,
00296 "%s has placed a %s RESV on channel %s : [%s]",
00297 get_oper_name(source_p),
00298 (MyClient(source_p) ? "local" : "remote"),
00299 resv_p->name, resv_p->reason);
00300 write_conf_line(source_p, conf, NULL , 0 );
00301 }
00302 }
00303 else
00304 {
00305 struct MatchItem *resv_p = NULL;
00306
00307 if (!valid_wild_card_simple(name))
00308 {
00309 sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the resv",
00310 me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
00311 return;
00312 }
00313
00314 if (!IsAdmin(source_p) && strpbrk(name, "*?#"))
00315 {
00316 sendto_one(source_p, ":%s NOTICE %s :You must be an admin to perform a "
00317 "wildcard RESV", me.name, source_p->name);
00318 return;
00319 }
00320
00321 if ((conf = create_nick_resv(name, reason, 0)) == NULL)
00322 {
00323 sendto_one(source_p,
00324 ":%s NOTICE %s :A RESV has already been placed on nick %s",
00325 me.name, source_p->name, name);
00326 return;
00327 }
00328
00329 resv_p = map_to_conf(conf);
00330
00331 if (tkline_time != 0)
00332 {
00333 sendto_one(source_p,
00334 ":%s NOTICE %s :A %d minute %s RESV has been placed on nick %s : [%s]",
00335 me.name, source_p->name,
00336 tkline_time/60,
00337 (MyClient(source_p) ? "local" : "remote"),
00338 conf->name, resv_p->reason);
00339 sendto_realops_flags(UMODE_ALL, L_ALL,
00340 "%s has placed a %d minute %s RESV on nick %s : [%s]",
00341 get_oper_name(source_p),
00342 tkline_time/60,
00343 (MyClient(source_p) ? "local" : "remote"),
00344 conf->name, resv_p->reason);
00345 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
00346 source_p->name, (int)tkline_time/60,
00347 conf->name, resv_p->reason);
00348 resv_p->hold = CurrentTime + tkline_time;
00349 add_temp_line(conf);
00350 }
00351 else
00352 {
00353 sendto_one(source_p,
00354 ":%s NOTICE %s :A %s RESV has been placed on nick %s : [%s]",
00355 me.name, source_p->name,
00356 (MyClient(source_p) ? "local" : "remote"),
00357 conf->name, resv_p->reason);
00358 sendto_realops_flags(UMODE_ALL, L_ALL,
00359 "%s has placed a %s RESV on nick %s : [%s]",
00360 get_oper_name(source_p),
00361 (MyClient(source_p) ? "local" : "remote"),
00362 conf->name, resv_p->reason);
00363 write_conf_line(source_p, conf, NULL , 0 );
00364 }
00365 }
00366 }
00367
00368 static void
00369 remove_resv(struct Client *source_p, const char *name)
00370 {
00371 struct ConfItem *conf = NULL;
00372
00373 if (IsChanPrefix(*name))
00374 {
00375 struct ResvChannel *resv_p;
00376
00377 if (resv_channel_list.head == NULL ||
00378 !(resv_p = hash_find_resv(name)))
00379 {
00380 sendto_one(source_p,
00381 ":%s NOTICE %s :A RESV does not exist for channel: %s",
00382 me.name, source_p->name, name);
00383 return;
00384 }
00385
00386 if (resv_p->conf)
00387 {
00388 sendto_one(source_p,
00389 ":%s NOTICE %s :The RESV for channel: %s is in ircd.conf and must be removed by hand.",
00390 me.name, source_p->name, name);
00391 return;
00392 }
00393
00394 delete_channel_resv(resv_p);
00395 remove_conf_line(CRESV_TYPE, source_p, name, NULL);
00396
00397 sendto_one(source_p,
00398 ":%s NOTICE %s :The RESV has been removed on channel: %s",
00399 me.name, source_p->name, name);
00400 sendto_realops_flags(UMODE_ALL, L_ALL,
00401 "%s has removed the RESV for channel: %s",
00402 get_oper_name(source_p), name);
00403 }
00404 else
00405 {
00406 struct MatchItem *resv_p = NULL;
00407
00408 if ((conf = find_exact_name_conf(NRESV_TYPE, name, NULL, NULL)) == NULL)
00409 {
00410 sendto_one(source_p, ":%s NOTICE %s :A RESV does not exist for nick: %s",
00411 me.name, source_p->name, name);
00412 return;
00413 }
00414
00415 resv_p = map_to_conf(conf);
00416
00417 if (resv_p->action)
00418 {
00419 sendto_one(source_p,
00420 ":%s NOTICE %s :The RESV for nick: %s is in ircd.conf and must be removed by hand.",
00421 me.name, source_p->name, name);
00422 return;
00423 }
00424
00425 delete_conf_item(conf);
00426 remove_conf_line(NRESV_TYPE, source_p, name, NULL);
00427
00428 sendto_one(source_p, ":%s NOTICE %s :The RESV has been removed on nick: %s",
00429 me.name, source_p->name, name);
00430 sendto_realops_flags(UMODE_ALL, L_ALL,
00431 "%s has removed the RESV for nick: %s",
00432 get_oper_name(source_p), name);
00433 }
00434 }