unrealircd- supernets unrealircd source & configuration |
git clone git://git.acid.vegas/unrealircd.git |
Log | Files | Refs | Archive | README | LICENSE |
away.c (4605B)
1 /* 2 * IRC - Internet Relay Chat, src/modules/away.c 3 * (C) 2001 The UnrealIRCd Team 4 * 5 * away command 6 * 7 * See file AUTHORS in IRC package for additional names of 8 * the programmers. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 1, or (at your option) 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 */ 24 25 #include "unrealircd.h" 26 27 CMD_FUNC(cmd_away); 28 int away_join(Client *client, Channel *channel, MessageTag *mtags); 29 30 long CAP_AWAY_NOTIFY = 0L; 31 32 #define MSG_AWAY "AWAY" 33 34 ModuleHeader MOD_HEADER 35 = { 36 "away", 37 "5.0", 38 "command /away", 39 "UnrealIRCd Team", 40 "unrealircd-6", 41 }; 42 43 MOD_INIT() 44 { 45 ClientCapabilityInfo c; 46 memset(&c, 0, sizeof(c)); 47 c.name = "away-notify"; 48 ClientCapabilityAdd(modinfo->handle, &c, &CAP_AWAY_NOTIFY); 49 CommandAdd(modinfo->handle, MSG_AWAY, cmd_away, 1, CMD_USER); 50 HookAdd(modinfo->handle, HOOKTYPE_LOCAL_JOIN, 0, away_join); 51 HookAdd(modinfo->handle, HOOKTYPE_REMOTE_JOIN, 0, away_join); 52 53 MARK_AS_OFFICIAL_MODULE(modinfo); 54 return MOD_SUCCESS; 55 } 56 57 MOD_LOAD() 58 { 59 return MOD_SUCCESS; 60 } 61 62 MOD_UNLOAD() 63 { 64 return MOD_SUCCESS; 65 } 66 67 int away_join(Client *client, Channel *channel, MessageTag *mtags) 68 { 69 Member *lp; 70 Client *acptr; 71 int invisible = invisible_user_in_channel(client, channel); 72 for (lp = channel->members; lp; lp = lp->next) 73 { 74 acptr = lp->client; 75 76 if (!MyConnect(acptr)) 77 continue; /* only locally connected clients */ 78 79 if (invisible && !check_channel_access_member(lp, "hoaq") && (client != acptr)) 80 continue; /* skip non-ops if requested to (used for mode +D), but always send to 'client' */ 81 82 if (client->user->away && HasCapabilityFast(acptr, CAP_AWAY_NOTIFY)) 83 { 84 MessageTag *mtags_away = NULL; 85 new_message(client, NULL, &mtags_away); 86 sendto_one(acptr, mtags_away, ":%s!%s@%s AWAY :%s", 87 client->name, client->user->username, GetHost(client), client->user->away); 88 free_message_tags(mtags_away); 89 } 90 } 91 return 0; 92 } 93 94 /** Mark client as AWAY or mark them as back (in case of empty reason) */ 95 CMD_FUNC(cmd_away) 96 { 97 char reason[512]; 98 int n, already_as_away = 0; 99 MessageTag *mtags = NULL; 100 101 if (IsServer(client)) 102 return; 103 104 if (parc < 2 || BadPtr(parv[1])) 105 { 106 /* Marking as not away */ 107 if (client->user->away) 108 { 109 safe_free(client->user->away); 110 111 new_message(client, recv_mtags, &mtags); 112 sendto_server(client, 0, 0, mtags, ":%s AWAY", client->name); 113 sendto_local_common_channels(client, client, CAP_AWAY_NOTIFY, mtags, 114 ":%s AWAY", client->name); 115 RunHook(HOOKTYPE_AWAY, client, mtags, NULL, 0); 116 free_message_tags(mtags); 117 } 118 119 if (MyConnect(client)) 120 sendnumeric(client, RPL_UNAWAY); 121 return; 122 } 123 124 /* Obey set::away-length */ 125 strlncpy(reason, parv[1], sizeof(reason), iConf.away_length); 126 127 /* Check spamfilters */ 128 if (MyUser(client) && match_spamfilter(client, reason, SPAMF_AWAY, "AWAY", NULL, 0, NULL)) 129 return; 130 131 /* Check away-flood */ 132 if (MyUser(client) && 133 !ValidatePermissionsForPath("immune:away-flood",client,NULL,NULL,NULL) && 134 flood_limit_exceeded(client, FLD_AWAY)) 135 { 136 sendnumeric(client, ERR_TOOMANYAWAY); 137 return; 138 } 139 140 /* Check if the new away reason is the same as the current reason - if so then return (no change) */ 141 if ((client->user->away) && !strcmp(client->user->away, reason)) 142 return; 143 144 /* All tests passed. Now marking as away (or still away but changing the away reason) */ 145 146 client->user->away_since = TStime(); 147 148 new_message(client, recv_mtags, &mtags); 149 150 sendto_server(client, 0, 0, mtags, ":%s AWAY :%s", client->id, reason); 151 152 if (client->user->away) 153 { 154 safe_free(client->user->away); 155 already_as_away = 1; 156 } 157 158 safe_strdup(client->user->away, reason); 159 160 if (MyConnect(client)) 161 sendnumeric(client, RPL_NOWAWAY); 162 163 sendto_local_common_channels(client, client, 164 CAP_AWAY_NOTIFY, mtags, 165 ":%s AWAY :%s", client->name, client->user->away); 166 167 RunHook(HOOKTYPE_AWAY, client, mtags, client->user->away, already_as_away); 168 169 free_message_tags(mtags); 170 171 return; 172 }