a2d5f1e8fbfff0ab84f7dc07a0615b195c6ce977
[ngircd-alex.git] / src / ngircd / irc.c
1 /*
2  * ngIRCd -- The Next Generation IRC Daemon
3  * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * Please read the file COPYING, README and AUTHORS for more information.
10  *
11  * IRC commands
12  */
13
14
15 #include "portab.h"
16
17 static char UNUSED id[] = "$Id: irc.c,v 1.109 2002/12/26 17:14:48 alex Exp $";
18
19 #include "imp.h"
20 #include <assert.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "conn.h"
25 #include "client.h"
26 #include "channel.h"
27 #include "defines.h"
28 #include "irc-write.h"
29 #include "log.h"
30 #include "messages.h"
31 #include "parse.h"
32
33 #include "exp.h"
34 #include "irc.h"
35
36
37 GLOBAL BOOLEAN
38 IRC_ERROR( CLIENT *Client, REQUEST *Req )
39 {
40         assert( Client != NULL );
41         assert( Req != NULL );
42
43         if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
44         else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
45
46         return CONNECTED;
47 } /* IRC_ERROR */
48
49
50 GLOBAL BOOLEAN
51 IRC_KILL( CLIENT *Client, REQUEST *Req )
52 {
53         CLIENT *prefix, *c;
54         CHAR reason[COMMAND_LEN];
55
56         assert( Client != NULL );
57         assert( Req != NULL );
58
59         /* is the user an IRC operator? */
60         if(( Client_Type( Client ) != CLIENT_SERVER ) && ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
61
62         /* Falsche Anzahl Parameter? */
63         if(( Req->argc != 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
64
65         if( Req->prefix ) prefix = Client_Search( Req->prefix );
66         else prefix = Client;
67         if( ! prefix )
68         {
69                 Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!", Req->prefix );
70                 prefix = Client_ThisServer( );
71         }
72
73         Log( LOG_NOTICE|LOG_snotice, "Got KILL command from \"%s\" for \"%s\": %s", Client_Mask( prefix ), Req->argv[0], Req->argv[1] );
74
75         /* build reason string */
76         if( Client_Type( Client ) == CLIENT_USER ) snprintf( reason, sizeof( reason ), "KILLed by %s: %s", Client_ID( Client ), Req->argv[1] );
77         else strlcpy( reason, Req->argv[1], sizeof( reason ));
78
79         /* andere Server benachrichtigen */
80         IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s", Req->argv[0], reason );
81
82         /* haben wir selber einen solchen Client? */
83         c = Client_Search( Req->argv[0] );
84         if( c )
85         {
86                 /* Ja, wir haben einen solchen Client */
87                 if( Client_Conn( c ) != NONE ) Conn_Close( Client_Conn( c ), NULL, reason, TRUE );
88                 else Client_Destroy( c, NULL, reason, TRUE );
89         }
90         else Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
91
92         return CONNECTED;
93 } /* IRC_KILL */
94
95
96 GLOBAL BOOLEAN
97 IRC_NOTICE( CLIENT *Client, REQUEST *Req )
98 {
99         CLIENT *to, *from;
100
101         assert( Client != NULL );
102         assert( Req != NULL );
103
104         if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return CONNECTED;
105
106         /* Falsche Anzahl Parameter? */
107         if( Req->argc != 2 ) return CONNECTED;
108
109         if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
110         else from = Client;
111         if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
112
113         to = Client_Search( Req->argv[0] );
114         if(( to ) && ( Client_Type( to ) == CLIENT_USER ))
115         {
116                 /* Okay, Ziel ist ein User */
117                 return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] );
118         }
119         else return CONNECTED;
120 } /* IRC_NOTICE */
121
122
123 GLOBAL BOOLEAN
124 IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
125 {
126         CLIENT *cl, *from;
127         CHANNEL *chan;
128         
129         assert( Client != NULL );
130         assert( Req != NULL );
131
132         /* Falsche Anzahl Parameter? */
133         if( Req->argc == 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
134         if( Req->argc == 1 ) return IRC_WriteStrClient( Client, ERR_NOTEXTTOSEND_MSG, Client_ID( Client ));
135         if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
136
137         if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
138         else from = Client;
139         if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
140
141         cl = Client_Search( Req->argv[0] );
142         if( cl )
143         {
144                 /* Okay, Ziel ist ein Client. Aber ist es auch ein User? */
145                 if( Client_Type( cl ) != CLIENT_USER ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
146
147                 /* Okay, Ziel ist ein User */
148                 if(( Client_Type( Client ) != CLIENT_SERVER ) && ( strchr( Client_Modes( cl ), 'a' )))
149                 {
150                         /* Ziel-User ist AWAY: Meldung verschicken */
151                         if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( cl ), Client_Away( cl ))) return DISCONNECTED;
152                 }
153
154                 /* Text senden */
155                 if( Client_Conn( from ) > NONE ) Conn_UpdateIdle( Client_Conn( from ));
156                 return IRC_WriteStrClientPrefix( cl, from, "PRIVMSG %s :%s", Client_ID( cl ), Req->argv[1] );
157         }
158
159         chan = Channel_Search( Req->argv[0] );
160         if( chan ) return Channel_Write( chan, from, Client, Req->argv[1] );
161
162         return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
163 } /* IRC_PRIVMSG */
164
165
166 /* -eof- */