unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
quit.c (4332B)
1 /* 2 * Unreal Internet Relay Chat Daemon, src/modules/quit.c 3 * (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team 4 * Moved to modules by Fish (Justin Hammond) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 1, or (at your option) 9 * any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 */ 20 21 #include "unrealircd.h" 22 23 CMD_FUNC(cmd_quit); 24 25 #define MSG_QUIT "QUIT" /* QUIT */ 26 27 ModuleHeader MOD_HEADER 28 = { 29 "quit", /* Name of module */ 30 "5.0", /* Version */ 31 "command /quit", /* Short description of module */ 32 "UnrealIRCd Team", 33 "unrealircd-6", 34 }; 35 36 /* This is called on module init, before Server Ready */ 37 MOD_INIT() 38 { 39 CommandAdd(modinfo->handle, MSG_QUIT, cmd_quit, 1, CMD_UNREGISTERED|CMD_USER|CMD_VIRUS); 40 MARK_AS_OFFICIAL_MODULE(modinfo); 41 return MOD_SUCCESS; 42 } 43 44 /* Is first run when server is 100% ready */ 45 MOD_LOAD() 46 { 47 return MOD_SUCCESS; 48 } 49 50 /* Called when module is unloaded */ 51 MOD_UNLOAD() 52 { 53 return MOD_SUCCESS; 54 } 55 56 /* 57 ** cmd_quit 58 ** parv[1] = comment 59 */ 60 CMD_FUNC(cmd_quit) 61 { 62 const char *comment = (parc > 1 && parv[1]) ? parv[1] : client->name; 63 char commentbuf[MAXQUITLEN + 1]; 64 char commentbuf2[MAXQUITLEN + 1]; 65 66 if (parc > 1 && parv[1]) 67 { 68 strlncpy(commentbuf, parv[1], sizeof(commentbuf), iConf.quit_length); 69 comment = commentbuf; 70 } else { 71 comment = client->name; 72 } 73 74 if (MyUser(client)) 75 { 76 int n; 77 Hook *tmphook; 78 79 if (STATIC_QUIT) 80 { 81 exit_client(client, recv_mtags, STATIC_QUIT); 82 return; 83 } 84 85 if (IsVirus(client)) 86 { 87 exit_client(client, recv_mtags, "Client exited"); 88 return; 89 } 90 91 if (match_spamfilter(client, comment, SPAMF_QUIT, "QUIT", NULL, 0, NULL)) 92 { 93 comment = client->name; 94 if (IsDead(client)) 95 return; 96 } 97 98 if (!ValidatePermissionsForPath("immune:anti-spam-quit-message-time",client,NULL,NULL,NULL) && ANTI_SPAM_QUIT_MSG_TIME) 99 { 100 if (client->local->creationtime+ANTI_SPAM_QUIT_MSG_TIME > TStime()) 101 comment = client->name; 102 } 103 104 if (iConf.part_instead_of_quit_on_comment_change && MyUser(client)) 105 { 106 Membership *lp, *lp_next; 107 const char *newcomment; 108 Channel *channel; 109 110 for (lp = client->user->channel; lp; lp = lp_next) 111 { 112 channel = lp->channel; 113 newcomment = comment; 114 lp_next = lp->next; 115 116 for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_QUIT_CHAN]; tmphook; tmphook = tmphook->next) 117 { 118 newcomment = (*(tmphook->func.stringfunc))(client, channel, comment); 119 if (!newcomment) 120 break; 121 } 122 123 if (newcomment && is_banned(client, channel, BANCHK_LEAVE_MSG, &newcomment, NULL)) 124 newcomment = NULL; 125 126 /* Comment changed? Then PART the user before we do the QUIT. */ 127 if (comment != newcomment) 128 { 129 const char *parx[4]; 130 char tmp[512]; 131 int ret; 132 133 134 parx[0] = NULL; 135 parx[1] = channel->name; 136 if (newcomment) 137 { 138 strlcpy(tmp, newcomment, sizeof(tmp)); 139 parx[2] = tmp; 140 parx[3] = NULL; 141 } else { 142 parx[2] = NULL; 143 } 144 145 do_cmd(client, recv_mtags, "PART", newcomment ? 3 : 2, parx); 146 /* This would be unusual, but possible (somewhere in the future perhaps): */ 147 if (IsDead(client)) 148 return; 149 } 150 } 151 } 152 153 for (tmphook = Hooks[HOOKTYPE_PRE_LOCAL_QUIT]; tmphook; tmphook = tmphook->next) 154 { 155 comment = (*(tmphook->func.stringfunc))(client, comment); 156 if (!comment) 157 { 158 comment = client->name; 159 break; 160 } 161 } 162 163 if (PREFIX_QUIT) 164 snprintf(commentbuf2, sizeof(commentbuf2), "%s: %s", PREFIX_QUIT, comment); 165 else 166 strlcpy(commentbuf2, comment, sizeof(commentbuf2)); 167 168 exit_client(client, recv_mtags, commentbuf2); 169 } 170 else 171 { 172 /* Remote quits and non-person quits always use their original comment. 173 * Also pass recv_mtags so to keep the msgid and such. 174 */ 175 exit_client(client, recv_mtags, comment); 176 } 177 }