source: irc_send.c @ 410bf6d

Last change on this file since 410bf6d was 410bf6d, checked in by Wilmer van der Gaast <wilmer@…>, at 2010-03-27T18:10:03Z

Fixed bug in /WHO $channel output.

  • Property mode set to 100644
File size: 7.9 KB
RevLine 
[ebaebfe]1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* The IRC-based UI - Sending responses to commands/etc.                */
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;
22  if not, write to the Free Software Foundation, Inc., 59 Temple Place,
23  Suite 330, Boston, MA  02111-1307  USA
24*/
25
26#include "bitlbee.h"
27
28void irc_send_num( irc_t *irc, int code, char *format, ... )
29{
30        char text[IRC_MAX_LINE];
31        va_list params;
32       
33        va_start( params, format );
34        g_vsnprintf( text, IRC_MAX_LINE, format, params );
35        va_end( params );
36       
[4be8239]37        irc_write( irc, ":%s %03d %s %s", irc->root->host, code, irc->user->nick ? : "*", text );
[ebaebfe]38}
39
40void irc_send_login( irc_t *irc )
41{
42        irc_send_num( irc,   1, ":Welcome to the BitlBee gateway, %s", irc->user->nick );
43        irc_send_num( irc,   2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->root->host );
44        irc_send_num( irc,   3, ":%s", IRCD_INFO );
45        irc_send_num( irc,   4, "%s %s %s %s", irc->root->host, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES );
46        irc_send_num( irc,   5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee "
47                                "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server",
48                                CTYPES, CMODES, MAX_NICK_LENGTH - 1 );
49        irc_send_motd( irc );
50       
51        irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n"
52                          "If you've never used BitlBee before, please do read the help "
53                          "information using the \x02help\x02 command. Lots of FAQs are "
54                          "answered there.\n"
55                          "If you already have an account on this server, just use the "
56                          "\x02identify\x02 command to identify yourself." );
57}
58
59void irc_send_motd( irc_t *irc )
60{
61        int fd;
62       
63        fd = open( global.conf->motdfile, O_RDONLY );
64        if( fd == -1 )
65        {
66                irc_send_num( irc, 422, ":We don't need MOTDs." );
67        }
68        else
69        {
70                char linebuf[80];       /* Max. line length for MOTD's is 79 chars. It's what most IRC networks seem to do. */
71                char *add, max;
72                int len;
73               
74                linebuf[79] = len = 0;
75                max = sizeof( linebuf ) - 1;
76               
77                irc_send_num( irc, 375, ":- %s Message Of The Day - ", irc->root->host );
78                while( read( fd, linebuf + len, 1 ) == 1 )
79                {
80                        if( linebuf[len] == '\n' || len == max )
81                        {
82                                linebuf[len] = 0;
83                                irc_send_num( irc, 372, ":- %s", linebuf );
84                                len = 0;
85                        }
86                        else if( linebuf[len] == '%' )
87                        {
88                                read( fd, linebuf + len, 1 );
89                                if( linebuf[len] == 'h' )
90                                        add = irc->root->host;
91                                else if( linebuf[len] == 'v' )
92                                        add = BITLBEE_VERSION;
93                                else if( linebuf[len] == 'n' )
94                                        add = irc->user->nick;
95                                else
96                                        add = "%";
97                               
98                                strncpy( linebuf + len, add, max - len );
99                                while( linebuf[++len] );
100                        }
101                        else if( len < max )
102                        {
103                                len ++;
104                        }
105                }
106                irc_send_num( irc, 376, ":End of MOTD" );
107                close( fd );
108        }
109}
110
[4be8239]111void irc_usermsg( irc_t *irc, char *format, ... )
[ebaebfe]112{
[74f1cde]113        irc_channel_t *ic;
114        irc_user_t *iu;
[ebaebfe]115        char text[1024];
116        va_list params;
117       
118        va_start( params, format );
119        g_vsnprintf( text, sizeof( text ), format, params );
120        va_end( params );
121       
[74f1cde]122        if( irc->last_root_cmd &&
123            irc_channel_name_ok( irc->last_root_cmd ) && 
124            ( ic = irc_channel_by_name( irc, irc->last_root_cmd ) ) &&
125            ic->flags & IRC_CHANNEL_JOINED )
126                irc_send_msg( irc->root, "PRIVMSG", irc->last_root_cmd, text );
127        else if( irc->last_root_cmd &&
128                 ( iu = irc_user_by_name( irc, irc->last_root_cmd ) ) &&
129                 iu->f == &irc_user_root_funcs )
130                irc_send_msg( iu, "PRIVMSG", irc->user->nick, text );
131        else
132        {
133                g_free( irc->last_root_cmd );
134                irc->last_root_cmd = NULL;
135               
136                irc_send_msg( irc->root, "PRIVMSG", irc->user->nick, text );
137        }
[ebaebfe]138       
139        /*return( irc_msgfrom( irc, u->nick, text ) );*/
140}
[4be8239]141
142void irc_send_join( irc_channel_t *ic, irc_user_t *iu )
143{
144        irc_t *irc = ic->irc;
145       
146        irc_write( irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name );
147       
148        if( iu == irc->user )
149        {
150                irc_write( irc, ":%s MODE %s +%s", irc->root->host, ic->name, ic->mode );
151                irc_send_names( ic );
[83e92bf]152                irc_send_topic( ic, FALSE );
[4be8239]153        }
154}
155
156void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason )
157{
158        irc_write( ic->irc, ":%s!%s@%s PART %s :%s", iu->nick, iu->user, iu->host, ic->name, reason );
159}
160
161void irc_send_names( irc_channel_t *ic )
162{
163        GSList *l;
164        char namelist[385] = "";
[280c56a]165        //char *ops = set_getstr( &ic->irc->b->set, "ops" );
[4be8239]166       
167        /* RFCs say there is no error reply allowed on NAMES, so when the
168           channel is invalid, just give an empty reply. */
169        for( l = ic->users; l; l = l->next )
170        {
171                irc_user_t *iu = l->data;
172               
173                if( strlen( namelist ) + strlen( iu->nick ) > sizeof( namelist ) - 4 )
174                {
175                        irc_send_num( ic->irc, 353, "= %s :%s", ic->name, namelist );
176                        *namelist = 0;
177                }
178               
179                /*
180                if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) )
181                        strcat( namelist, "+" );
182                else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ||
183                         ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) )
184                        strcat( namelist, "@" );
185                */
186               
187                strcat( namelist, iu->nick );
188                strcat( namelist, " " );
189        }
190       
191        if( *namelist )
192                irc_send_num( ic->irc, 353, "= %s :%s", ic->name, namelist );
193       
194        irc_send_num( ic->irc, 366, "%s :End of /NAMES list", ic->name );
195}
196
[83e92bf]197void irc_send_topic( irc_channel_t *ic, gboolean topic_change )
[4be8239]198{
[83e92bf]199        if( topic_change && ic->topic_who )
200        {
201                irc_write( ic->irc, ":%s TOPIC %s :%s", ic->topic_who, 
202                           ic->name, ic->topic && *ic->topic ? ic->topic : "" );
203        }
204        else if( ic->topic )
205        {
[4be8239]206                irc_send_num( ic->irc, 332, "%s :%s", ic->name, ic->topic );
[83e92bf]207                if( ic->topic_who )
208                        irc_send_num( ic->irc, 333, "%s %s %d",
209                                      ic->name, ic->topic_who, (int) ic->topic_time );
210        }
[4be8239]211        else
212                irc_send_num( ic->irc, 331, "%s :No topic for this channel", ic->name );
213}
[b95932e]214
215void irc_send_whois( irc_user_t *iu )
216{
217        irc_t *irc = iu->irc;
218       
219        irc_send_num( irc, 311, "%s %s %s * :%s",
220                      iu->nick, iu->user, iu->host, iu->fullname );
221       
222        /*
223        if( u->ic )
224                irc_send_num( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user,
225                           u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "",
226                           u->ic->acc->prpl->name );
227        else
228                irc_send_num( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO );
229        */
230       
231        /*
232        if( u->away )
233                irc_send_num( irc, 301, "%s :%s", u->nick, u->away );
234        if( u->status_msg )
235                irc_send_num( irc, 333, "%s :Status: %s", u->nick, u->status_msg );
236        */
237       
238        irc_send_num( irc, 318, "%s :End of /WHOIS list", iu->nick );
239}
[2f53ada]240
241void irc_send_who( irc_t *irc, GSList *l, const char *channel )
242{
243        while( l )
244        {
245                irc_user_t *iu = l->data;
246                /* TODO(wilmer): Restore away/channel information here */
247                irc_send_num( irc, 352, "%s %s %s %s %s %c :0 %s",
[410bf6d]248                              channel ? : "*", iu->user, iu->host, irc->root->host,
[2f53ada]249                              iu->nick, 'H', iu->fullname );
250                l = l->next;
251        }
252       
253        irc_send_num( irc, 315, "%s :End of /WHO list", channel );
254}
[280c56a]255
256void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg )
257{
258        irc_write( iu->irc, ":%s!%s@%s %s %s :%s",
259                   iu->nick, iu->user, iu->host, type, dst, msg );
260}
Note: See TracBrowser for help on using the repository browser.