source: irc_user.c @ 114154c

Last change on this file since 114154c was 5ebff60, checked in by dequis <dx@…>, at 2015-02-20T22:50:54Z

Reindent everything to K&R style with tabs

Used uncrustify, with the configuration file in ./doc/uncrustify.cfg

Commit author set to "Indent <please@…>" so that it's easier to
skip while doing git blame.

  • Property mode set to 100644
File size: 6.8 KB
RevLine 
[5ebff60]1/********************************************************************\
[ebaebfe]2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[0e788f5]4  * Copyright 2002-2012 Wilmer van der Gaast and others                *
[ebaebfe]5  \********************************************************************/
6
7/* Stuff to handle, save and search IRC buddies                         */
8
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 2 of the License, or
13  (at your option) 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 with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
[6f10697]22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
[ebaebfe]24*/
25
26#include "bitlbee.h"
[debe871]27#include "ipc.h"
[ebaebfe]28
[5ebff60]29irc_user_t *irc_user_new(irc_t *irc, const char *nick)
[ebaebfe]30{
[5ebff60]31        irc_user_t *iu = g_new0(irc_user_t, 1);
32
[b95932e]33        iu->irc = irc;
[5ebff60]34        iu->nick = g_strdup(nick);
[ebaebfe]35        iu->user = iu->host = iu->fullname = iu->nick;
[5ebff60]36
37        iu->key = g_strdup(nick);
38        nick_lc(irc, iu->key);
[ebaebfe]39        /* Using the hash table for speed and irc->users for easy iteration
40           through the list (since the GLib API doesn't have anything sane
41           for that.) */
[5ebff60]42        g_hash_table_insert(irc->nick_user_hash, iu->key, iu);
43        irc->users = g_slist_insert_sorted(irc->users, iu, irc_user_cmp);
44
[ebaebfe]45        return iu;
46}
47
[5ebff60]48int irc_user_free(irc_t *irc, irc_user_t *iu)
[ebaebfe]49{
[0bd948e]50        static struct im_connection *last_ic;
51        static char *msg;
[5ebff60]52
53        if (!iu) {
[ebaebfe]54                return 0;
[5ebff60]55        }
56
57        if (iu->bu &&
58            (iu->bu->ic->flags & OPT_LOGGING_OUT) &&
59            iu->bu->ic != last_ic) {
[0bd948e]60                char host_prefix[] = "bitlbee.";
61                char *s;
[5ebff60]62
[0bd948e]63                /* Irssi recognises netsplits by quitmsgs with two
64                   hostnames, where a hostname is a "word" with one
65                   of more dots. Mangle no-dot hostnames a bit. */
[5ebff60]66                if (strchr(irc->root->host, '.')) {
[0bd948e]67                        *host_prefix = '\0';
[5ebff60]68                }
69
[0bd948e]70                last_ic = iu->bu->ic;
[5ebff60]71                g_free(msg);
72                if (!set_getbool(&irc->b->set, "simulate_netsplit")) {
73                        msg = g_strdup("Account off-line");
74                } else if ((s = strchr(iu->bu->ic->acc->user, '@'))) {
75                        msg = g_strdup_printf("%s%s %s", host_prefix,
76                                              irc->root->host, s + 1);
77                } else {
78                        msg = g_strdup_printf("%s%s %s.%s",
79                                              host_prefix, irc->root->host,
80                                              iu->bu->ic->acc->prpl->name, irc->root->host);
81                }
82        } else if (!iu->bu || !(iu->bu->ic->flags & OPT_LOGGING_OUT)) {
83                g_free(msg);
84                msg = g_strdup("Removed");
[0bd948e]85                last_ic = NULL;
[1f0224c]86        }
[5ebff60]87        irc_user_quit(iu, msg);
88
89        irc->users = g_slist_remove(irc->users, iu);
90        g_hash_table_remove(irc->nick_user_hash, iu->key);
91
92        g_free(iu->nick);
93        if (iu->nick != iu->user) {
94                g_free(iu->user);
95        }
96        if (iu->nick != iu->host) {
97                g_free(iu->host);
98        }
99        if (iu->nick != iu->fullname) {
100                g_free(iu->fullname);
101        }
102        g_free(iu->pastebuf);
103        if (iu->pastebuf_timer) {
104                b_event_remove(iu->pastebuf_timer);
105        }
106        g_free(iu->key);
107        g_free(iu);
108
[ebaebfe]109        return 1;
110}
111
[5ebff60]112irc_user_t *irc_user_by_name(irc_t *irc, const char *nick)
[ebaebfe]113{
[5ebff60]114        char key[strlen(nick) + 1];
115
116        strcpy(key, nick);
117        if (nick_lc(irc, key)) {
118                return g_hash_table_lookup(irc->nick_user_hash, key);
119        } else {
[ebaebfe]120                return NULL;
[5ebff60]121        }
[ebaebfe]122}
123
[5ebff60]124int irc_user_set_nick(irc_user_t *iu, const char *new)
[ebaebfe]125{
[57c96f7]126        irc_t *irc = iu->irc;
[9a9b520]127        irc_user_t *new_iu;
[5ebff60]128        char key[strlen(new) + 1];
[0b5cc72]129        GSList *cl;
[5ebff60]130
131        strcpy(key, new);
132        if (iu == NULL || !nick_lc(irc, key) ||
133            ((new_iu = irc_user_by_name(irc, new)) && new_iu != iu)) {
[ebaebfe]134                return 0;
[5ebff60]135        }
136
137        for (cl = irc->channels; cl; cl = cl->next) {
[0b5cc72]138                irc_channel_t *ic = cl->data;
[5ebff60]139
[0b5cc72]140                /* Send a NICK update if we're renaming our user, or someone
141                   who's in the same channel like our user. */
[5ebff60]142                if (iu == irc->user ||
143                    ((ic->flags & IRC_CHANNEL_JOINED) &&
144                     irc_channel_has_user(ic, iu))) {
145                        irc_send_nick(iu, new);
[0b5cc72]146                        break;
147                }
148        }
[5ebff60]149
150        irc->users = g_slist_remove(irc->users, iu);
151        g_hash_table_remove(irc->nick_user_hash, iu->key);
152
153        if (iu->nick == iu->user) {
154                iu->user = NULL;
155        }
156        if (iu->nick == iu->host) {
157                iu->host = NULL;
158        }
159        if (iu->nick == iu->fullname) {
160                iu->fullname = NULL;
161        }
162        g_free(iu->nick);
163        iu->nick = g_strdup(new);
164        if (iu->user == NULL) {
165                iu->user = g_strdup(iu->nick);
166        }
167        if (iu->host == NULL) {
168                iu->host = g_strdup(iu->nick);
169        }
170        if (iu->fullname == NULL) {
171                iu->fullname = g_strdup(iu->nick);
172        }
173
174        g_free(iu->key);
175        iu->key = g_strdup(key);
176        g_hash_table_insert(irc->nick_user_hash, iu->key, iu);
177        irc->users = g_slist_insert_sorted(irc->users, iu, irc_user_cmp);
178
179        if (iu == irc->user) {
180                ipc_to_master_str("NICK :%s\r\n", new);
181        }
182
[ebaebfe]183        return 1;
184}
185
[5ebff60]186gint irc_user_cmp(gconstpointer a_, gconstpointer b_)
[ebaebfe]187{
188        const irc_user_t *a = a_, *b = b_;
[5ebff60]189
190        return strcmp(a->key, b->key);
[ebaebfe]191}
[280c56a]192
[5ebff60]193const char *irc_user_get_away(irc_user_t *iu)
[003a12b]194{
195        irc_t *irc = iu->irc;
196        bee_user_t *bu = iu->bu;
[5ebff60]197
198        if (iu == irc->user) {
199                return set_getstr(&irc->b->set, "away");
200        } else if (bu) {
201                if (!bu->flags & BEE_USER_ONLINE) {
[003a12b]202                        return "Offline";
[5ebff60]203                } else if (bu->flags & BEE_USER_AWAY) {
204                        if (bu->status_msg) {
[4c3519a]205                                static char ret[MAX_STRING];
[5ebff60]206                                g_snprintf(ret, MAX_STRING - 1, "%s (%s)",
207                                           bu->status ? : "Away", bu->status_msg);
[4c3519a]208                                return ret;
[5ebff60]209                        } else {
[4c3519a]210                                return bu->status ? : "Away";
[5ebff60]211                        }
[4c3519a]212                }
[003a12b]213        }
[5ebff60]214
[003a12b]215        return NULL;
216}
217
[5ebff60]218void irc_user_quit(irc_user_t *iu, const char *msg)
[0bd948e]219{
220        GSList *l;
221        gboolean send_quit = FALSE;
[5ebff60]222
223        if (!iu) {
[0bd948e]224                return;
[5ebff60]225        }
226
227        for (l = iu->irc->channels; l; l = l->next) {
[4ffd757]228                irc_channel_t *ic = l->data;
[5ebff60]229                send_quit |= irc_channel_del_user(ic, iu, IRC_CDU_SILENT, NULL) &&
230                             (ic->flags & IRC_CHANNEL_JOINED);
231        }
232
233        if (send_quit) {
234                irc_send_quit(iu, msg);
[4ffd757]235        }
[0bd948e]236}
237
[280c56a]238/* User-type dependent functions, for root/NickServ: */
[5ebff60]239static gboolean root_privmsg(irc_user_t *iu, const char *msg)
[280c56a]240{
[5ebff60]241        char cmd[strlen(msg) + 1];
242
243        strcpy(cmd, msg);
244        root_command_string(iu->irc, cmd);
245
[280c56a]246        return TRUE;
247}
248
[5ebff60]249static gboolean root_ctcp(irc_user_t *iu, char * const *ctcp)
[24b8bbb]250{
[5ebff60]251        if (g_strcasecmp(ctcp[0], "VERSION") == 0) {
252                irc_send_msg_f(iu, "NOTICE", iu->irc->user->nick, "\001%s %s\001",
253                               ctcp[0], PACKAGE " " BITLBEE_VERSION " " ARCH "/" CPU);
254        } else if (g_strcasecmp(ctcp[0], "PING") == 0) {
255                irc_send_msg_f(iu, "NOTICE", iu->irc->user->nick, "\001%s %s\001",
256                               ctcp[0], ctcp[1] ? : "");
[7b59872]257        }
[5ebff60]258
[24b8bbb]259        return TRUE;
260}
261
[280c56a]262const struct irc_user_funcs irc_user_root_funcs = {
263        root_privmsg,
[24b8bbb]264        root_ctcp,
[280c56a]265};
266
267/* Echo to yourself: */
[5ebff60]268static gboolean self_privmsg(irc_user_t *iu, const char *msg)
[280c56a]269{
[5ebff60]270        irc_send_msg(iu, "PRIVMSG", iu->nick, msg, NULL);
271
[280c56a]272        return TRUE;
273}
274
275const struct irc_user_funcs irc_user_self_funcs = {
276        self_privmsg,
277};
Note: See TracBrowser for help on using the repository browser.