The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
ban.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Pauli Nieminen <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "config.hpp"
16 #include "log.hpp"
17 #include "filesystem.hpp"
18 #include "serialization/parser.hpp"
22 #include "util.hpp"
23 
24 #include "ban.hpp"
25 
26 #include "utils/functional.hpp"
27 
28 namespace wesnothd {
29 
30 
31 static lg::log_domain log_server("server");
32 #define ERR_SERVER LOG_STREAM(err, log_server)
33 #define LOG_SERVER LOG_STREAM(info, log_server)
34 #define DBG_SERVER LOG_STREAM(debug, log_server)
35 
36  std::ostream& operator<<(std::ostream& o, const banned& n)
37  {
38  return o << "IP: " << n.get_ip() <<
39  (n.get_nick().empty() ? "" : " nick: " + n.get_nick()) <<
40  " reason: '" << n.get_reason() << "'"
41  " start_time: " << n.get_human_start_time() <<
42  " end_time: " << n.get_human_end_time() <<
43  " issuer: " << n.get_who_banned();
44  }
45 
46  bool banned_compare::operator()(const banned_ptr& a, const banned_ptr& b) const
47  {
48  return (*a) > (*b);
49  }
50 
52 
54  {
55  return (this->*(active_))(a,b);
56  }
57 
59  {
60  return a->get_int_ip() < b->get_int_ip();
61  }
62 
64 
66  {
67  banned_ptr dummy(new banned(ip));
68  return dummy;
69  }
70 
72  ip_(0),
73  mask_(0),
74  ip_text_(),
75  end_time_(0),
76  start_time_(0),
77  reason_(),
78  who_banned_(who_banned_default_),
79  group_(),
80  nick_()
81  {
82  ip_mask pair = parse_ip(ip);
83  ip_ = pair.first;
84  mask_ = 0xFFFFFFFF;
85  }
86 
88  const time_t end_time,
89  const std::string& reason,
90  const std::string& who_banned,
91  const std::string& group,
92  const std::string& nick) :
93  ip_(0),
94  mask_(0),
95  ip_text_(ip),
96  end_time_(end_time),
97  start_time_(time(0)),
98  reason_(reason),
99  who_banned_(who_banned),
100  group_(group),
101  nick_(nick)
102  {
103  ip_mask pair = parse_ip(ip_text_);
104  ip_ = pair.first;
105  mask_ = pair.second;
106  }
107 
108  banned::banned(const config& cfg) :
109  ip_(0),
110  mask_(0),
111  ip_text_(),
112  end_time_(0),
113  start_time_(0),
114  reason_(),
115  who_banned_(who_banned_default_),
116  group_(),
117  nick_()
118  {
119  read(cfg);
120  }
121 
123  {
124  // We use bit operations to construct the integer
125  // ip_mask is a pair: first is ip and second is mask
126  ip_mask ret;
127  ret.first = 0;
128  ret.second = 0;
129  std::vector<std::string> split_ip = utils::split(ip, '.');
130  if (split_ip.size() > 4) throw banned::error("Malformed ip address: " + ip);
131 
132  unsigned int shift = 4*8; // start shifting from the highest byte
133  unsigned int mask = 0xFF000000;
134  const unsigned int complete_part_mask = 0xFF;
135  std::vector<std::string>::const_iterator part = split_ip.begin();
136  bool wildcard = false;
137  do {
138  shift -= 8;
139  mask >>= 8;
140  if (part == split_ip.end())
141  {
142  if (!wildcard)
143  throw banned::error("Malformed ip address: '" + ip + "'");
144  // Adding 0 to ip and mask is nop
145  // we can then break out of loop
146  break;
147  } else {
148  if (*part == "*")
149  {
150  wildcard = true;
151  // Adding 0 to ip and mask is nop
152  } else {
153  //wildcard = false;
154  unsigned int part_ip = lexical_cast_default<unsigned int>(*part, complete_part_mask + 1);
155  if (part_ip > complete_part_mask)
156  throw banned::error("Malformed ip address: '" + ip + "'");
157  ret.first |= (part_ip << shift);
158  ret.second |= (complete_part_mask << shift);
159  }
160  }
161  ++part;
162  } while (shift);
163  return ret;
164  }
165 
166  void banned::read(const config& cfg)
167  {
168  {
169  // parse ip and mask
170  ip_text_ = cfg["ip"].str();
171  ip_mask pair = parse_ip(ip_text_);
172  ip_ = pair.first;
173  mask_ = pair.second;
174  }
175  nick_ = cfg["nick"].str();
176  if (cfg.has_attribute("end_time"))
177  end_time_ = lexical_cast_default<time_t>(cfg["end_time"], 0);
178  if (cfg.has_attribute("start_time"))
179  start_time_ = lexical_cast_default<time_t>(cfg["start_time"], 0);
180  reason_ = cfg["reason"].str();
181 
182  // only overwrite defaults if exists
183  if (cfg.has_attribute("who_banned"))
184  who_banned_ = cfg["who_banned"].str();
185  if (cfg.has_attribute("group"))
186  group_ = cfg["group"].str();
187  }
188 
189  void banned::write(config& cfg) const
190  {
191  cfg["ip"] = get_ip();
192  cfg["nick"] = get_nick();
193  if (end_time_ > 0)
194  {
195  std::stringstream ss;
196  ss << end_time_;
197  cfg["end_time"] = ss.str();
198  }
199  if (start_time_ > 0)
200  {
201  std::stringstream ss;
202  ss << start_time_;
203  cfg["start_time"] = ss.str();
204  }
205 
206  cfg["reason"] = reason_;
208  {
209  cfg["who_banned"] = who_banned_;
210  }
211  if (!group_.empty())
212  {
213  cfg["group"] = group_;
214  }
215  }
216 
218  {
219  if (start_time_ == 0)
220  return "unknown";
222  }
223 
225  {
226  if (end_time_ == 0)
227  {
228  return "permanent";
229  }
231  }
232 
234  {
235  if (end_time_ == 0)
236  {
237  return "permanent";
238  }
239  return lg::get_timespan(end_time_ - time(nullptr));
240  }
241 
242  bool banned::operator>(const banned& b) const
243  {
244  return end_time_ > b.get_end_time();
245  }
246 
247  unsigned int banned::get_mask_ip(unsigned int mask) const
248  {
249  return ip_ & mask & mask_;
250  }
251 
252  bool banned::match_ip(const ip_mask& pair) const {
253  return (ip_ & mask_) == (pair.first & mask_);
254  }
255 
256  // Unlike match_ip this function takes both masks into account.
257  bool banned::match_ipmask(const ip_mask& pair) const {
258  return (ip_ & mask_ & pair.second) == (pair.first & pair.second & mask_);
259  }
260 
262  {
264  return;
265  LOG_SERVER << "Reading bans from " << filename_ << "\n";
266  config cfg;
268  read_gz(cfg, *ban_file);
269 
270  for (const config &b : cfg.child_range("ban"))
271  {
272  try {
273  banned_ptr new_ban(new banned(b));
274  assert(bans_.insert(new_ban).second);
275 
276  if (new_ban->get_end_time() != 0)
277  time_queue_.push(new_ban);
278  } catch (banned::error& e) {
279  ERR_SERVER << e.message << " while reading bans" << std::endl;
280  }
281  }
282 
283  // load deleted too
284  if (const config &cfg_del = cfg.child("deleted"))
285  {
286  for (const config &b : cfg_del.child_range("ban"))
287  {
288  try {
289  banned_ptr new_ban(new banned(b));
290  deleted_bans_.push_back(new_ban);
291  } catch (banned::error& e) {
292  ERR_SERVER << e.message << " while reading deleted bans" << std::endl;
293  }
294  }
295  }
296 
297 
298  }
299 
301  {
302  if (filename_.empty() || !dirty_)
303  return;
304  LOG_SERVER << "Writing bans to " << filename_ << "\n";
305  dirty_ = false;
306  config cfg;
307  for (ban_set::const_iterator itor = bans_.begin();
308  itor != bans_.end(); ++itor)
309  {
310  config& child = cfg.add_child("ban");
311  (*itor)->write(child);
312  }
313  config& deleted = cfg.add_child("deleted");
314  for (deleted_ban_list::const_iterator itor = deleted_bans_.begin();
315  itor != deleted_bans_.end(); ++itor)
316  {
317  config& child = deleted.add_child("ban");
318  (*itor)->write(child);
319  }
320 
322  config_writer writer(*ban_file, true);
323  writer.write(cfg);
324  }
325 
326  bool ban_manager::parse_time(const std::string& duration, time_t* time) const
327  {
328  if (!time) return false;
329 
330  if (duration.substr(0,4) == "TIME") {
331  struct tm* loc;
332  loc = localtime(time);
333 
334  size_t number = 0;
335  for (std::string::const_iterator i = duration.begin() + 4;
336  i != duration.end(); ++i) {
337  if (is_digit(*i))
338  {
339  number = number * 10 + to_digit(*i);
340  }
341  else
342  {
343  switch(*i)
344  {
345  case 'Y':
346  loc->tm_year = number;
347  break;
348  case 'M':
349  loc->tm_mon = number;
350  break;
351  case 'D':
352  loc->tm_mday = number;
353  break;
354  case 'h':
355  loc->tm_hour = number;
356  break;
357  case 'm':
358  loc->tm_min = number;
359  break;
360  case 's':
361  loc->tm_sec = number;
362  break;
363  default:
364  LOG_SERVER << "Invalid time modifier given: '" << *i << "'.\n";
365  break;
366  }
367  number = 0;
368  }
369  }
370  *time = mktime(loc);
371  return true;
372  }
373  default_ban_times::const_iterator time_itor = ban_times_.find(duration);
374 
375  std::string dur_lower;
376  try {
377  dur_lower = utf8::lowercase(duration);
378  } catch ( utf8::invalid_utf8_exception & e ) {
379  ERR_SERVER << "While parsing ban command duration string, caught an invalid utf8 exception: " << e.what() << std::endl;
380  return false;
381  }
382 
383  if (dur_lower == "permanent" || duration == "0") {
384  *time = 0;
385  } else if (ban_times_.find(duration) != ban_times_.end()) {
386  *time += time_itor->second;
387  } else {
388  std::string::const_iterator i = duration.begin();
389  int number = -1;
390  for (std::string::const_iterator d_end = duration.end(); i != d_end; ++i) {
391  if (is_digit(*i))
392  {
393  if (number == -1) number = 0;
394  number = number * 10 + to_digit(*i);
395  } else {
396  if (number == -1) number = 1;
397  switch(*i)
398  {
399  case 'Y':
400  case 'y':
401  if (++i != d_end && tolower(*i) == 'e'
402  && ++i != d_end && tolower(*i) == 'a'
403  && ++i != d_end && tolower(*i) == 'r'
404  && ++i != d_end && tolower(*i) == 's') {
405  } else --i;
406  *time += number * 365*24*60*60; // a year;
407  break;
408  case 'M':
409  if (++i != d_end && tolower(*i) == 'i') {
410  if (++i != d_end && tolower(*i) == 'n'
411  && ++i != d_end && tolower(*i) == 'u'
412  && ++i != d_end && tolower(*i) == 't'
413  && ++i != d_end && tolower(*i) == 'e'
414  && ++i != d_end && tolower(*i) == 's') {
415  } else --i;
416  *time += number * 60;
417  break;
418  }
419  --i;
420  if (++i != d_end && tolower(*i) == 'o'
421  && ++i != d_end && tolower(*i) == 'n'
422  && ++i != d_end && tolower(*i) == 't'
423  && ++i != d_end && tolower(*i) == 'h'
424  && ++i != d_end && tolower(*i) == 's') {
425  } else --i;
426  *time += number * 30*24*60*60; // 30 days
427  break;
428  case 'D':
429  case 'd':
430  if (++i != d_end && tolower(*i) == 'a'
431  && ++i != d_end && tolower(*i) == 'y'
432  && ++i != d_end && tolower(*i) == 's') {
433  } else --i;
434  *time += number * 24*60*60;
435  break;
436  case 'H':
437  case 'h':
438  if (++i != d_end && tolower(*i) == 'o'
439  && ++i != d_end && tolower(*i) == 'u'
440  && ++i != d_end && tolower(*i) == 'r'
441  && ++i != d_end && tolower(*i) == 's') {
442  } else --i;
443  *time += number * 60*60;
444  break;
445  case 'm':
446  if (++i != d_end && tolower(*i) == 'o') {
447  if (++i != d_end && tolower(*i) == 'n'
448  && ++i != d_end && tolower(*i) == 't'
449  && ++i != d_end && tolower(*i) == 'h'
450  && ++i != d_end && tolower(*i) == 's') {
451  } else --i;
452  *time += number * 30*24*60*60; // 30 days
453  break;
454  }
455  --i;
456  if (++i != d_end && tolower(*i) == 'i'
457  && ++i != d_end && tolower(*i) == 'n'
458  && ++i != d_end && tolower(*i) == 'u'
459  && ++i != d_end && tolower(*i) == 't'
460  && ++i != d_end && tolower(*i) == 'e'
461  && ++i != d_end && tolower(*i) == 's') {
462  } else --i;
463  *time += number * 60;
464  break;
465  case 'S':
466  case 's':
467  if (++i != d_end && tolower(*i) == 'e'
468  && ++i != d_end && tolower(*i) == 'c'
469  && ++i != d_end && tolower(*i) == 'o'
470  && ++i != d_end && tolower(*i) == 'n'
471  && ++i != d_end && tolower(*i) == 'd'
472  && ++i != d_end && tolower(*i) == 's') {
473  } else --i;
474  *time += number;
475  break;
476  default:
477  return false;
478  break;
479  }
480  number = -1;
481  }
482  }
483  if (is_digit(*--i)) {
484  *time += number * 60; // default to minutes
485  }
486  }
487  return true;
488  }
489 
491  const time_t& end_time,
492  const std::string& reason,
493  const std::string& who_banned,
494  const std::string& group,
495  const std::string& nick)
496  {
497  std::ostringstream ret;
498  try {
500  if ((ban = bans_.find(banned::create_dummy(ip))) != bans_.end())
501  {
502  // Already exsiting ban for ip. We have to first remove it
503  ret << "Overwriting ban: " << (**ban) << "\n";
504  bans_.erase(ban);
505  }
506  } catch (banned::error& e) {
507  ERR_SERVER << e.message << " while creating dummy ban for finding existing ban" << std::endl;
508  return e.message;
509  }
510  try {
511  banned_ptr new_ban(new banned(ip, end_time, reason,who_banned, group, nick));
512  bans_.insert(new_ban);
513  if (end_time != 0)
514  time_queue_.push(new_ban);
515  ret << *new_ban;
516  } catch (banned::error& e) {
517  ERR_SERVER << e.message << " while banning" << std::endl;
518  return e.message;
519  }
520  dirty_ = true;
521  return ret.str();
522  }
523 
524  void ban_manager::unban(std::ostringstream& os, const std::string& ip)
525  {
527  try {
528  ban = bans_.find(banned::create_dummy(ip));
529  } catch (banned::error& e) {
530  ERR_SERVER << e.message << std::endl;
531  os << e.message;
532  return;
533  }
534 
535  if (ban == bans_.end())
536  {
537  os << "There is no ban on '" << ip << "'.";
538  return;
539  }
540  // keep ban entry still in memory
541  os << "Ban on '" << **ban << "' removed.";
542  // group bans don't get saved
543  if ((*ban)->get_group().empty()) deleted_bans_.push_back(*ban);
544  bans_.erase(ban);
545  dirty_ = true;
546 
547  }
548 
549  void ban_manager::unban_group(std::ostringstream& os, const std::string& group)
550  {
551  ban_set temp;
552  std::insert_iterator<ban_set> temp_inserter(temp, temp.begin());
553  std::remove_copy_if(bans_.begin(), bans_.end(), temp_inserter, std::bind(&banned::match_group,std::bind(&banned_ptr::get,_1),group));
554 
555  os << "Removed " << (bans_.size() - temp.size()) << " bans";
556  bans_.swap(temp);
557  dirty_ = true;
558  }
559 
560  void ban_manager::check_ban_times(time_t time_now)
561  {
562  while (!time_queue_.empty())
563  {
564  banned_ptr ban = time_queue_.top();
565 
566  if (ban->get_end_time() > time_now)
567  {
568  // No bans going to expire
569  DBG_SERVER << "ban " << ban->get_ip() << " not removed. time: " << time_now << " end_time " << ban->get_end_time() << "\n";
570  break;
571  }
572 
573  // This ban is going to expire so delete it.
574  LOG_SERVER << "Remove a ban " << ban->get_ip() << ". time: " << time_now << " end_time " << ban->get_end_time() << "\n";
575  std::ostringstream os;
576  unban(os, ban->get_ip());
577  time_queue_.pop();
578 
579  }
580  // Save bans if there is any new ones
581  write();
582  }
583 
584  void ban_manager::list_deleted_bans(std::ostringstream& out, const std::string& mask) const
585  {
586  if (deleted_bans_.empty())
587  {
588  out << "No removed bans found.";
589  return;
590  }
591 
592  ip_mask pair;
593  try {
594  pair = parse_ip(mask);
595  } catch (banned::error& e) {
596  out << "parse error: " << e.message;
597  return;
598  }
599 
600  out << "DELETED BANS LIST";
601  for (deleted_ban_list::const_iterator i = deleted_bans_.begin();
602  i != deleted_bans_.end();
603  ++i)
604  {
605  if ((*i)->match_ipmask(pair)) out << "\n" << (**i);
606  }
607 
608  }
609 
610 
611 
612  void ban_manager::list_bans(std::ostringstream& out, const std::string& mask) const
613  {
614  if (bans_.empty())
615  {
616  out << "No bans set.";
617  return;
618  }
619 
620  ip_mask pair;
621  try {
622  pair = parse_ip(mask);
623  } catch (banned::error& e) {
624  out << "parse error: " << e.message;
625  return;
626  }
627 
628  out << "BAN LIST";
629  std::set<std::string> groups;
630 
631  for (ban_set::const_iterator i = bans_.begin();
632  i != bans_.end(); ++i)
633  {
634  if ((*i)->get_group().empty())
635  {
636  if ((*i)->match_ipmask(pair)) out << "\n" << (**i);
637  } else {
638  groups.insert((*i)->get_group());
639  }
640  }
641 
642  // Don't list ban groups when looking for specific bans.
643  if (!groups.empty() && mask == "*")
644  {
645  out << "\nban groups: ";
646 
647  out << *groups.begin();
648  std::ostream& (*fn)(std::ostream&,const std::string&) = &std::operator<<;
649  std::for_each( ++groups.begin(), groups.end(), std::bind(fn,std::bind(fn,std::ref(out),std::string(", ")),_1));
650  }
651 
652  }
653 
654 
656  {
657  ip_mask pair;
658  try {
659  pair = parse_ip(ip);
660  } catch (banned::error&) {
661  return "";
662  }
663  ban_set::const_iterator ban = std::find_if(bans_.begin(), bans_.end(), std::bind(&banned::match_ip, std::bind(&banned_ptr::get, _1), pair));
664  if (ban == bans_.end()) return "";
665  const std::string& nick = (*ban)->get_nick();
666  return (*ban)->get_reason() + (nick.empty() ? "" : " (" + nick + ")") + " (" + (*ban)->get_human_time_span() + ")";
667  }
668 
670  {
671  ban_help_ = "ban <mask> <time> <reason>\n"
672  "The time format is: %d[%s[%d[%s[...]]]] where %s is a time"
673  " modifier: s or S (seconds), m (minutes), h or H (hours), d"
674  " or D (days), M (months) or y or Y (years) and %d is a number.\n"
675  "Permanent bans can be set with 'permanent' or '0' as the time"
676  " argument.\n";
678  if (itor != ban_times_.end())
679  {
680  ban_help_ += "You can also use " + itor->first;
681  ++itor;
682  }
683  for (; itor != ban_times_.end(); ++itor)
684  {
685  ban_help_ += std::string(", ") + itor->first;
686  }
687  if (!ban_times_.empty())
688  {
689  ban_help_ += " for standard ban times. (not combinable)\n";
690  }
691  ban_help_ += "ban 127.0.0.1 2h20m flooded lobby\n"
692  "kban suokko 5D flooded again\n"
693  "kban suokko Y One year ban for constant flooding";
694  }
695 
697  {
698  ban_times_.clear();
699  for (const config &bt : cfg.child_range("ban_time")) {
700  time_t duration = 0;
701  if (parse_time(bt["time"], &duration)) {
702  ban_times_.insert(default_ban_times::value_type(bt["name"], duration));
703  }
704  }
705  init_ban_help();
706  if (filename_ != cfg["ban_save_file"])
707  {
708  dirty_ = true;
709  filename_ = cfg["ban_save_file"].str();
710  }
711  }
712 
714  {
715  try {
716  write();
717  } catch (...) {}
718  }
719 
721  : bans_()
722  , deleted_bans_()
723  , time_queue_()
724  , ban_times_()
725  , ban_help_()
726  , filename_()
727  , dirty_(false)
728  {
729  init_ban_help();
730  }
731 
732 
733 }
size_t to_digit(const char &c) const
Definition: ban.hpp:136
#define LOG_SERVER
Definition: ban.cpp:33
child_itors child_range(const std::string &key)
Definition: config.cpp:613
#define DBG_SERVER
Definition: ban.cpp:34
std::string reason_
Definition: ban.hpp:64
void write(const config &cfg)
unsigned int get_mask_ip(unsigned int) const
Definition: ban.cpp:247
default_ban_times ban_times_
Definition: ban.hpp:129
void list_deleted_bans(std::ostringstream &out, const std::string &mask="*") const
Definition: ban.cpp:584
void load_config(const config &)
Definition: ban.cpp:696
std::string get_timestamp(const time_t &t, const std::string &format)
Definition: log.cpp:174
bool match_group(const std::string &group) const
Definition: ban.hpp:101
std::string ban(const std::string &, const time_t &, const std::string &, const std::string &, const std::string &, const std::string &="")
Definition: ban.cpp:490
std::string get_human_time_span() const
Definition: ban.cpp:233
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
deleted_ban_list deleted_bans_
Definition: ban.hpp:127
bool(banned_compare_subnet::* compare_fn)(const banned_ptr &a, const banned_ptr &b) const
Definition: ban.hpp:46
utf8::string lowercase(const utf8::string &s)
Returns a lowercased version of the string.
Definition: unicode.cpp:53
std::string get_human_start_time() const
Definition: ban.cpp:217
const std::string number
template to number regex
Definitions for the interface to Wesnoth Markup Language (WML).
std::set< banned_ptr, banned_compare_subnet > ban_set
Definition: ban.hpp:50
std::string group_
Definition: ban.hpp:66
bool match_ip(const ip_mask &ip) const
Definition: ban.cpp:252
void read_gz(config &cfg, std::istream &file, abstract_validator *validator)
might throw a std::ios_base::failure especially a gzip_error
Definition: parser.cpp:454
static compare_fn active_
Definition: ban.hpp:47
std::string filename_
Definition: action_wml.cpp:506
std::string is_ip_banned(const std::string &ip) const
Definition: ban.cpp:655
std::pair< unsigned int, unsigned int > ip_mask
Definition: ban.hpp:54
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
void read(const config &)
Definition: ban.cpp:166
bool operator()(const banned_ptr &a, const banned_ptr &b) const
Definition: ban.cpp:53
time_t get_end_time() const
Definition: ban.hpp:79
bool parse_time(const std::string &duration, time_t *time) const
Parses the given duration and adds it to *time except if the duration is '0' or 'permanent' in which ...
Definition: ban.cpp:326
std::string nick_
Definition: ban.hpp:67
static lg::log_domain log_server("server")
void unban_group(std::ostringstream &os, const std::string &group)
Definition: ban.cpp:549
Class for writing a config out to a file in pieces.
bool less(const banned_ptr &a, const banned_ptr &b) const
Definition: ban.cpp:58
std::string get_human_end_time() const
Definition: ban.cpp:224
std::istream * istream_file(const std::string &fname, bool treat_failure_as_error=true)
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
std::ostream * ostream_file(std::string const &fname, bool create_directory=true)
config & add_child(const std::string &key)
Definition: config.cpp:743
ip_mask parse_ip(const std::string &ip)
Definition: ban.cpp:122
GLenum GLint GLuint mask
Definition: glew.h:1813
banned(const std::string &ip)
Definition: ban.cpp:71
Templates and utility-routines for strings and numbers.
bool match_ipmask(const ip_mask &ip) const
Definition: ban.cpp:257
ban_time_queue time_queue_
Definition: ban.hpp:128
static banned_ptr create_dummy(const std::string &ip)
Definition: ban.cpp:65
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
std::string get_nick() const
Definition: ban.hpp:98
Thrown by operations encountering invalid UTF-8 data.
std::string who_banned_
Definition: ban.hpp:65
void unban(std::ostringstream &os, const std::string &ip)
Definition: ban.cpp:524
std::ostream & operator<<(std::ostream &o, const banned &n)
Definition: ban.cpp:36
std::string ban_help_
Definition: ban.hpp:130
size_t i
Definition: function.cpp:1057
bool operator>(const banned &b) const
Definition: ban.cpp:242
CURSOR_TYPE get()
Definition: cursor.cpp:194
static const std::string who_banned_default_
Definition: ban.hpp:68
std::string get_timespan(const time_t &t)
Definition: log.cpp:182
Declarations for File-IO.
static int writer(lua_State *L, const void *b, size_t size, void *B)
Definition: lstrlib.cpp:166
void list_bans(std::ostringstream &out, const std::string &mask="*") const
Definition: ban.cpp:612
unsigned int ip_
Definition: ban.hpp:59
#define ERR_SERVER
Definition: ban.cpp:32
GLclampd n
Definition: glew.h:5903
void init_ban_help()
Definition: ban.cpp:669
GLenum GLint ref
Definition: glew.h:1813
void check_ban_times(time_t time_now)
Definition: ban.cpp:560
GLboolean GLuint group
Definition: glew.h:2589
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
Definition: ban.cpp:28
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
std::string get_who_banned() const
Definition: ban.hpp:95
Standard logging facilities (interface).
std::string message
Definition: exceptions.hpp:29
time_t end_time_
Definition: ban.hpp:62
std::string filename_
Definition: ban.hpp:131
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
#define e
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLsizei GLuint * groups
Definition: glew.h:2588
bool file_exists(const std::string &name)
Returns true if a file or directory with such name already exists.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
time_t start_time_
Definition: ban.hpp:63
std::string ip_text_
Definition: ban.hpp:61
void write(config &) const
Definition: ban.cpp:189
std::string get_reason() const
Definition: ban.hpp:87
unsigned int mask_
Definition: ban.hpp:60
bool operator()(const banned_ptr &a, const banned_ptr &b) const
Definition: ban.cpp:46
bool is_digit(const char &c) const
Definition: ban.hpp:134
std::string get_ip() const
Definition: ban.hpp:90