PageRenderTime 67ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/Modules/m_delayjoin.c

https://bitbucket.org/stealth/unreal32
C | 271 lines | 163 code | 28 blank | 80 comment | 26 complexity | 74203f39f2c90ae8c005cd84ab800902 MD5 | raw file
  1. /*
  2. * ==================================================================
  3. * Module: m_delayjoin.c
  4. * Author: Stealth <stealth@x-tab.org>
  5. * Version: 2.0.2
  6. * License: GNU Afferro General Public Licnese
  7. * Description: Requires clients to be connected for a certain amount
  8. * of time before allowing them to join any channels.
  9. * ==================================================================
  10. * Copyright (C) 2012 "Stealth" <stealth@x-tab.org>
  11. *
  12. * This license grants permission to freely use, modify, and
  13. * distribute this module with the following conditions:
  14. * - You must keep this module licensed with the GNU Affero General
  15. * Public Licnese, either version 3 or newer.
  16. * - This copyright notice must stay intact.
  17. * - You must provide the module source (incluing any modifications)
  18. * upon request to anyone who wishes to see it.
  19. * Please see the GNU AGPL text for full details (link below).
  20. *
  21. * This program is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU Affero General Public License for more details.
  25. *
  26. * The full version of the GNU AGPL license may be found at
  27. * http://www.gnu.org/licenses/agpl.html
  28. */
  29. /*
  30. * Configuration:
  31. *
  32. * There are 2 directives that need to be set in your unrealircd.conf file:
  33. *
  34. * set::delayjoin::time
  35. * This should be set to the time users will be unable to join channels after
  36. * connecting to your server. The default is in seconds, unless you specify
  37. * otherwise. The time value should be formatted the same as a G:Line.
  38. *
  39. * set::delayjoin::reason
  40. * This is what will be displayed to users when they attempt to join a
  41. * channel. The reason will be prefixed with "Cannot join #Channel:". It would
  42. * probably be helpful to your users if you put the time you set in this
  43. * reason.
  44. *
  45. *
  46. * ChangeLog:
  47. * 1/8/2012 - 2.0.2
  48. * - Changed license to GNU AGPL
  49. *
  50. * 12/31/2011 - 2.0.1
  51. * - Don't remember when/why I made the module 2.0.1, but I did...
  52. * - Fix whitespaces in docs/changelog. Everything is now consistent.
  53. *
  54. * 12/19/2007 - 2.0.0
  55. * - Changed module from using Command Override to hooking pre_local_join
  56. * - Added configuration
  57. * - Thanks to fez for helping with set::auto-join issues
  58. *
  59. * 12/18/2007 - 0.0.1
  60. * -Initial version (built off of delaylist by w00t <surreal.w00t@gmail.com>)
  61. *
  62. *
  63. *
  64. * Credits:
  65. * - w00t <surreal.w00t@gmail.com>
  66. * Initial version was built off of DelayList.
  67. *
  68. * - Syzop <syzop@vulnscan.org>
  69. * Configuration stuff was borrowed from the antirandom module
  70. *
  71. * - DukePyrolator <DukePyrolator@FantasyIRC.net>
  72. * Guide for hooking pre_local_join in m_onlyopersjoin
  73. *
  74. * - fez <wrongway.org>
  75. * Hours of debugging and putting up with my n00bness :P
  76. */
  77. #include "config.h"
  78. #include "struct.h"
  79. #include "common.h"
  80. #include "sys.h"
  81. #include "numeric.h"
  82. #include "msg.h"
  83. #include "channel.h"
  84. #include <time.h>
  85. #include <sys/stat.h>
  86. #include <stdio.h>
  87. #include <stdlib.h>
  88. #include <string.h>
  89. #ifdef _WIN32
  90. #include <io.h>
  91. #endif
  92. #include <fcntl.h>
  93. #include "h.h"
  94. #include "proto.h"
  95. #ifdef STRIPBADWORDS
  96. #include "badwords.h"
  97. #endif
  98. #ifdef _WIN32
  99. #include "version.h"
  100. #endif
  101. struct {
  102. int reason;
  103. int time;
  104. } req;
  105. struct {
  106. char *reason;
  107. long time;
  108. } cfg;
  109. static Cmdoverride *delayjoin_override = NULL;
  110. static ModuleInfo *delayjoin_modinfo = NULL;
  111. static void free_config(void);
  112. #define DelHook(x) if (x) HookDel(x); x = NULL
  113. Hook *HookJoin = NULL;
  114. DLLFUNC int delayjoin_config_test(ConfigFile *, ConfigEntry *, int, int *);
  115. DLLFUNC int delayjoin_config_run(ConfigFile *, ConfigEntry *, int);
  116. DLLFUNC int delayjoin_config_posttest(int *);
  117. DLLFUNC int m_delayjoin(aClient *sptr, aChannel *chptr, char *parv[]);
  118. ModuleHeader MOD_HEADER(delayjoin)
  119. = {
  120. "delayjoin", /* Name */
  121. "2.0.2", /* Ver */
  122. "Deny /join for newly connected users by Stealth <stealth@x-tab.org>", /* Desc. */
  123. "3.2-b8-1",
  124. NULL
  125. };
  126. DLLFUNC int MOD_TEST(delayjoin)(ModuleInfo *modinfo)
  127. {
  128. memset(&req, 0, sizeof(req));
  129. memset(&cfg, 0, sizeof(cfg));
  130. HookAddEx(modinfo->handle, HOOKTYPE_CONFIGTEST, delayjoin_config_test);
  131. HookAddEx(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, delayjoin_config_posttest);
  132. return MOD_SUCCESS;
  133. }
  134. DLLFUNC int MOD_INIT(delayjoin)(ModuleInfo *modinfo)
  135. {
  136. delayjoin_modinfo = modinfo;
  137. HookAddEx(modinfo->handle, HOOKTYPE_CONFIGRUN, delayjoin_config_run);
  138. HookJoin = HookAddEx(modinfo->handle, HOOKTYPE_PRE_LOCAL_JOIN, m_delayjoin);
  139. return MOD_SUCCESS;
  140. }
  141. DLLFUNC int MOD_LOAD(delayjoin)(int module_load)
  142. {
  143. return MOD_SUCCESS;
  144. }
  145. DLLFUNC int MOD_UNLOAD(delayjoin)(int module_unload)
  146. {
  147. DelHook(HookJoin);
  148. free_config();
  149. return MOD_SUCCESS;
  150. }
  151. static void free_config(void)
  152. {
  153. if (cfg.reason)
  154. MyFree(cfg.reason);
  155. memset(&cfg, 0, sizeof(cfg)); /* needed! */
  156. }
  157. DLLFUNC int delayjoin_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
  158. {
  159. int errors = 0;
  160. ConfigEntry *cep;
  161. if (type != CONFIG_SET)
  162. return 0;
  163. /* We are only interrested in set::delayjoin... */
  164. if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "delayjoin"))
  165. return 0;
  166. for (cep = ce->ce_entries; cep; cep = cep->ce_next)
  167. {
  168. if (!cep->ce_varname)
  169. {
  170. config_error("%s:%i: blank set::delayjoin item",
  171. cep->ce_fileptr->cf_filename, cep->ce_varlinenum);
  172. errors++;
  173. } else
  174. if (!cep->ce_vardata)
  175. {
  176. config_error("%s:%i: set::delayjoin::%s with no value",
  177. cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_varname);
  178. errors++;
  179. } else
  180. if (!strcmp(cep->ce_varname, "reason"))
  181. {
  182. req.reason = 1;
  183. } else
  184. if (!strcmp(cep->ce_varname, "time"))
  185. {
  186. req.time = 1;
  187. } else
  188. {
  189. config_error("%s:%i: unknown directive set::delayjoin::%s",
  190. cep->ce_fileptr->cf_filename, cep->ce_varlinenum, cep->ce_varname);
  191. errors++;
  192. }
  193. }
  194. *errs = errors;
  195. return errors ? -1 : 1;
  196. }
  197. DLLFUNC int delayjoin_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
  198. {
  199. ConfigEntry *cep, *cep2;
  200. if (type != CONFIG_SET)
  201. return 0;
  202. /* We are only interrested in set::delayjoin... */
  203. if (!ce || !ce->ce_varname || strcmp(ce->ce_varname, "delayjoin"))
  204. return 0;
  205. for (cep = ce->ce_entries; cep; cep = cep->ce_next)
  206. {
  207. if (!strcmp(cep->ce_varname, "reason"))
  208. {
  209. if (cfg.reason)
  210. MyFree(cfg.reason);
  211. cfg.reason = strdup(cep->ce_vardata);
  212. } else
  213. if (!strcmp(cep->ce_varname, "time"))
  214. {
  215. cfg.time = config_checkval(cep->ce_vardata, CFG_TIME);
  216. }
  217. }
  218. return 1;
  219. }
  220. DLLFUNC int delayjoin_config_posttest(int *errs)
  221. {
  222. int errors = 0;
  223. if (!req.time) { config_error("set::delayjoin::time missing"); errors++; }
  224. if (!req.reason) { config_error("set::delayjoin::reason missing"); errors++; }
  225. *errs = errors;
  226. return errors ? -1 : 1;
  227. }
  228. DLLFUNC int m_delayjoin(aClient *sptr, aChannel *chptr, char *parv[])
  229. {
  230. if (is_autojoin_chan(chptr->chname))
  231. return HOOK_CONTINUE;
  232. if (!IsAnOper(sptr))
  233. {
  234. if ((TStime() - sptr->firsttime) < cfg.time)
  235. {
  236. /* DENIED! */
  237. sendto_one(sptr, ":%s %s %s :*** Cannot join %s: %s", me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", sptr->name, chptr->chname, cfg.reason);
  238. return HOOK_DENY;
  239. }
  240. }
  241. /* aww, no fun. they've been connected a while :( - let it through */
  242. return HOOK_CONTINUE;
  243. }