ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/vendor/pxys2-2.1.0/pxyservd/src/irc_client.c
Revision: 3253
Committed: Wed Apr 2 20:46:18 2014 UTC (10 years ago) by michael
Content type: text/x-csrc
File size: 6829 byte(s)
Log Message:
- Imported pxys2-2.1.0

File Contents

# Content
1 /* Copyright (C) 2003, 2004 Stephane Thiell
2 *
3 * This file is part of pxyservd (from pxys)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 */
20 #define RCSID "$Id: irc_client.c,v 1.6 2004/01/17 19:44:29 mbuna Exp $"
21
22 #include "irc_client.h"
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include <peak/peak.h>
33
34 #include "cfgloader.h"
35 #include "debug.h"
36 #include "irc_channel.h"
37 #include "irc_cmd.h"
38 #include "irc_membership.h"
39 #include "irc_msg.h"
40 #include "irc_network.h"
41 #include "irc_numnicks.h"
42 #include "irc_send.h"
43 #include "irc_struct.h"
44 #include "irc_userbase.h"
45 #include "pxyservd_log.h"
46
47 #if NICKLEN > 9
48 #define MYNICKLEN 9
49 #else
50 #define MYNICKLEN NICKLEN
51 #endif
52
53 extern time_t gBirthTime;
54
55 peak_dict cmds_map;
56
57 static void irc_client_nick_change_timer_cb(peak_timer ti, void *context);
58 static void randnick_gen(char *nickbuf, size_t nicklen);
59
60 static char my_netnum[6];
61
62 static const peak_dict_init_entry my_commands[] =
63 {
64 { "evreg", cmd_evreg },
65 { "evshow", cmd_evshow },
66 { "grem", cmd_grem },
67 { "help", cmd_help },
68 { "info", cmd_info },
69 { "inv", cmd_inv },
70 { "noscan", cmd_noscan },
71 { "proxytop", cmd_proxytop },
72 { "pxstats", cmd_pxstats },
73 { "recheck", cmd_recheck },
74 { "servers", cmd_servers },
75 { "showcmds", cmd_showcmds },
76 { "stats", cmd_stats },
77 { "status", cmd_status }
78 };
79
80 void
81 irc_client_init()
82 {
83 cmds_map = peak_dict_create(&peak_dict_stringcase_key_ops,
84 &peak_dict_null_value_ops,
85 my_commands,
86 PEAK_DICT_INIT_ENTRY_COUNT(my_commands));
87 assert(cmds_map != NULL);
88
89 if (gConfig->client.nick_change_delay > 0)
90 peak_task_timer_add(peak_task_self(),
91 peak_timer_create(gConfig->client.nick_change_delay,
92 gConfig->client.nick_change_delay,
93 irc_client_nick_change_timer_cb,
94 NULL));
95 }
96
97 void
98 irc_client_register()
99 {
100 char addr64[8];
101 ClientAddr caddr;
102 char *nick;
103 char randnick[MYNICKLEN + 1];
104
105 inttobase64(addr64, gConfig->client.userip.s_addr, 6);
106 snprintf(my_netnum, sizeof(my_netnum), "%s%s", gMe.yy, MYCLIENT_NUM64);
107
108 if (gConfig->client.nick_change_delay > 0)
109 {
110 strncpy(randnick, gConfig->client.nickname, MYNICKLEN);
111 randnick[MYNICKLEN] = '\0';
112 randnick_gen(randnick, MYNICKLEN);
113 nick = randnick;
114 }
115 else
116 nick = gConfig->client.nickname;
117
118 send_raw("%s %s %s %d %ld %s %s %s %s %s :%s" CRLF, gMe.yy, TOK_NICK,
119 nick, 1, gBirthTime,
120 gConfig->client.username, gConfig->client.hostname,
121 gConfig->client.usermode, addr64, my_netnum,
122 gConfig->client.realname);
123
124 caddr.ip4 = gConfig->client.userip;
125
126 irc_userbase_add(nick,
127 gConfig->client.username,
128 gBirthTime,
129 gConfig->client.usermode,
130 0,
131 caddr,
132 my_netnum);
133 }
134
135 void
136 irc_client_unregister()
137 {
138 irc_userbase_remove(my_netnum);
139 }
140
141 void
142 irc_client_burst()
143 {
144 struct Channel *ch;
145 struct Client *me;
146
147 if (!(me = irc_network_find_client(yxx_to_int(my_netnum))))
148 return;
149
150 /* Burst our client on the console channel */
151 if (!(ch = irc_channel_get(gConfig->client.channel)))
152 ch = irc_channel_create(gConfig->client.channel, gConfig->client.chanTS);
153
154 irc_membership_add(ch, me);
155
156 /* Send something concrete to our uplink */
157 send_raw("%s %s %s %ld %s %s%s:o" CRLF, gMe.yy, TOK_BURST,
158 gConfig->client.channel, gConfig->client.chanTS,
159 gConfig->client.chanmode, gMe.yy, MYCLIENT_NUM64);
160 }
161
162 static void
163 irc_client_nick_change_timer_cb(peak_timer ti, void *context)
164 {
165 char new_nick[MYNICKLEN + 1];
166 char nn[6];
167
168 /* Find an available nickname */
169 do
170 {
171 strncpy(new_nick, gConfig->client.nickname, MYNICKLEN);
172 new_nick[MYNICKLEN] = '\0';
173 randnick_gen(new_nick, MYNICKLEN);
174 }
175 while (irc_userbase_get_by_nick(new_nick));
176
177 snprintf(nn, sizeof(nn), "%s%s", gMe.yy, MYCLIENT_NUM64);
178 irc_userbase_nick_change(nn, new_nick);
179
180 send_raw("%s%s %s %s %ld" CRLF, gMe.yy, MYCLIENT_NUM64, TOK_NICK,
181 new_nick, peak_time());
182 }
183
184 static void
185 randnick_gen(char *nickbuf, size_t nicklen)
186 {
187 size_t length;
188
189 if ((length = strlen(gConfig->client.nickname)) >= nicklen)
190 length = nicklen - 2; /* grr */
191
192 snprintf(nickbuf + length, nicklen - length + 1, "%lu",
193 (unsigned long)rand() * (unsigned long)rand());
194 }
195
196 void
197 irc_client_handle_private(toktabptr ttab)
198 {
199 cmd_func f;
200 struct Client *cptr;
201 const char *dst = ttab->tok[0];
202 const char *cmd = ttab->tok[3];
203 char ipbuf[32];
204
205 assert(cmd != NULL && ttab->size >= 4);
206 if (*cmd == ':')
207 cmd++;
208
209 if (!*cmd)
210 return;
211
212 if ((cptr = irc_network_find_client(yxx_to_int(dst))) == NULL)
213 return; /* doh */
214
215 if (!(cptr->flags & CLIENT_FLAG_OPER))
216 return; /* Non opers go play balls. */
217
218 if (!inet_ntop(cptr->flags & CLIENT_FLAG_IPV6 ? AF_INET6 : AF_INET,
219 &cptr->addr, ipbuf, sizeof(ipbuf)))
220 return;
221
222 switch (ttab->size)
223 {
224 case 4:
225 log_write(LOGID_OPERCMDS, "<%s!%s@%s> %s", cptr->nick, cptr->user,
226 ipbuf, cmd);
227 break;
228 case 5:
229 log_write(LOGID_OPERCMDS, "<%s!%s@%s> %s %s", cptr->nick, cptr->user,
230 ipbuf, cmd, ttab->tok[4]);
231 break;
232 case 6:
233 log_write(LOGID_OPERCMDS, "<%s!%s@%s> %s %s %s", cptr->nick, cptr->user,
234 ipbuf, cmd, ttab->tok[4], ttab->tok[5]);
235 break;
236 default:
237 log_write(LOGID_OPERCMDS, "<%s!%s@%s> %s %s %s (...)", cptr->nick,
238 cptr->user, ipbuf, cmd, ttab->tok[4], ttab->tok[5]);
239 break;
240 }
241
242 /* Get client pointer here instead of in every cmd handlers.. */
243 if ((f = (cmd_func)peak_dict_get_value(cmds_map, cmd)))
244 (*f)(cptr, ttab);
245 else
246 send_client_to_one(dst, "Sorry, command not found.");
247 }