root/trunk/src/jabber.c

Revision 680, 6.1 kB (checked in by jajcus, 3 years ago)

- dates in the copyright header updated

Line 
1 /* $Id: jabber.c,v 1.24 2004/04/13 17:44:07 jajcus Exp $ */
2
3 /*
4  *  (C) Copyright 2002-2006 Jacek Konieczny [jajcus(a)jajcus,net]
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License Version 2 as
8  *  published by the Free Software Foundation.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "ggtrans.h"
21 #include "jabber.h"
22 #include "stream.h"
23 #include "iq.h"
24 #include "presence.h"
25 #include "message.h"
26 #include "users.h"
27 #include "conf.h"
28
29 GSource * jabber_source=NULL;
30 Stream *stream=NULL;
31 char *stream_id=NULL;
32 const char *secret;
33 const char *my_name;
34 int bare_domain = 0;
35 int stop_it;
36
37 enum jabber_state_e jabber_state;
38
39 void jabber_stream_start(Stream *s,xmlnode x){
40 char hashbuf[50];
41 char *str;
42 xmlnode tag;
43
44         if (jabber_state!=JS_NONE){
45                 g_warning(N_("unexpected <stream:stream/>"));
46                 return;
47         }
48
49         stream_id=xmlnode_get_attrib(x,"id");
50         str=g_strdup_printf("%s%s",stream_id,secret);
51         shahash_r(str,hashbuf);
52         g_free(str);
53         tag=xmlnode_new_tag("handshake");
54         xmlnode_insert_cdata(tag,hashbuf,-1);
55         stream_write(s,tag);
56         xmlnode_free(tag);
57         jabber_state=JS_HANDSHAKE;
58 }
59
60 void jabber_handshake(Stream *s,xmlnode x){
61
62         if (jabber_state!=JS_HANDSHAKE){
63                 g_warning(N_("unexpected <hanshake/>"));
64                 return;
65         }
66
67         g_message(L_("handshake OK"));
68         jabber_state=JS_CONNECTED;
69         users_probe_all();
70 }
71
72 void jabber_stream_error(Stream *s,xmlnode x){
73 char *data;
74
75         data=xmlnode_get_data(x);
76         if (data==NULL) data="-unknown-";
77         g_critical(L_("Stream error: %s"),data);
78         stream_close(s);
79         stop_it=1;
80 }
81
82 struct stream_s * jabber_stream(){
83         return stream;
84 }
85
86 void jabber_node(Stream *s,xmlnode x){
87 char *name;
88
89         packets_in++;
90         name=xmlnode_get_name(x);
91         if (strcmp(name,"stream:stream")==0)
92                 jabber_stream_start(s,x);
93         else if (strcmp(name,"handshake")==0)
94                 jabber_handshake(s,x);
95         else if (strcmp(name,"stream:error")==0)
96                 jabber_stream_error(s,x);
97         else if (strcmp(name,"iq")==0)
98                 jabber_iq(s,x);
99         else if (strcmp(name,"presence")==0)
100                 jabber_presence(s,x);
101         else if (strcmp(name,"message")==0)
102                 jabber_message(s,x);
103         else g_warning(N_("Unsupported tag: %s"),xmlnode2str(x));
104         xmlnode_free(x);
105 }
106
107 void jabber_event_cb(int type,xmlnode x,void *arg){
108 Stream *s;
109 char *str;
110 char *data;
111
112         if (stop_it || !stream) return;
113
114         s=(Stream *)arg;
115         if (x){
116                 str=xmlnode2str(x);
117         }
118         switch(type){
119                 case XSTREAM_ROOT:
120                         jabber_node(s,x);
121                         break;
122                 case XSTREAM_CLOSE:
123                         if (x || !stop_it){
124                                 stop_it=1;
125                                 stream_close(s);
126                         }
127                         else stop_it=2;
128                         break;
129                 case XSTREAM_NODE:
130                         jabber_node(s,x);
131                         break;
132                 case XSTREAM_ERR:
133                         g_warning(N_("Stream Error"));
134                         if (x){
135                                 data=xmlnode_get_data(x);
136                                 if (data==NULL) data="-unknown-";
137                                 g_warning("    %s",data);
138                         }
139                         break;
140                 default:
141                         g_critical(L_("Unknown node type: %i"),type);
142                         stop_it=1;
143                         stream_close(s);
144                         break;
145         }
146 }
147
148 gboolean jabber_source_prepare(GSource *source,
149                                 gint     *timeout){
150
151         *timeout=1000;
152         if (stop_it || stream==NULL) return TRUE;
153         return FALSE;
154 }
155
156 gboolean jabber_source_check(GSource *source){
157
158         if (stop_it || stream==NULL) return TRUE;
159         return FALSE;
160 }
161
162 gboolean jabber_source_dispatch(GSource *source,
163                         GSourceFunc callback,
164                         gpointer  user_data){
165
166         if (stop_it && stream){
167                         if (stop_it>1){
168                                 stream_destroy(stream);
169                                 stream=NULL;
170                                 g_main_quit(main_loop);
171                         }
172                         stop_it++;
173         }
174         else if (stream==NULL) g_main_quit(main_loop);
175
176         return TRUE;
177 }
178
179 void jabber_source_finalize(GSource *source){
180 }
181
182 static GSourceFuncs jabber_source_funcs={
183                 jabber_source_prepare,
184                 jabber_source_check,
185                 jabber_source_dispatch,
186                 jabber_source_finalize,
187                 NULL,
188                 NULL
189                 };
190
191 void jabber_stream_destroyed(struct stream_s *s){
192
193         if (s==stream) stream=NULL;
194 }
195
196 int jabber_done(){
197
198         if (stream){
199                 stream_destroy(stream);
200                 stream=NULL;
201         }
202         if (jabber_source){
203                 g_source_destroy(jabber_source);
204         }
205         g_free(register_instructions);
206         g_free(search_instructions);
207         g_free(gateway_desc);
208         g_free(gateway_prompt);
209         stream_del_destroy_handler(jabber_stream_destroyed);
210         return 0;
211 }
212
213 static char *server;
214 static int port;
215
216 int jabber_init(){
217 xmlnode node;
218
219         stream_add_destroy_handler(jabber_stream_destroyed);
220         node=xmlnode_get_tag(config,"service");
221         if (!node)
222                 g_error(L_("No <service/> found in config file"));
223
224         my_name=xmlnode_get_attrib(node,"jid");
225         if (!my_name)
226                 g_error(L_("<service/> without \"jid\" in config file"));
227
228         node=xmlnode_get_tag(config, "bare_domain");
229         if (node) bare_domain=1;
230
231         server=config_load_string("connect/ip");
232         if (!server)
233                 g_error(L_("Jabberd server not found in config file"));
234
235         port=config_load_int("connect/port",0);
236         if (port<=0)
237                 g_error(L_("Connect port not found in config file"));
238
239         node=xmlnode_get_tag(config,"connect/secret");
240         if (node) secret=xmlnode_get_data(node);
241         if (!node || !secret)
242                 g_error(L_("Connect secret not found in config file"));
243
244         register_instructions=config_load_formatted_string("register/instructions");
245         if (!register_instructions)
246                 g_error(L_("Registration instructions not not found in config file"));
247
248         search_instructions=config_load_formatted_string("search/instructions");
249         if (!search_instructions)
250                 g_error(L_("Search instructions not found in config file"));
251
252         gateway_desc=config_load_formatted_string("gateway/desc");
253         if (!gateway_desc)
254                 g_error(L_("Gateway instructions not found in config file"));
255
256         gateway_prompt=config_load_formatted_string("gateway/prompt");
257         if (!gateway_prompt)
258                 g_error(L_("Gateway prompt not found in config file"));
259
260         jabber_state=JS_NONE;
261         return 0;
262 }
263
264 int jabber_connect(){
265
266         stream=stream_connect(server,port,1,jabber_event_cb);
267         g_assert(stream!=NULL);
268         jabber_source=g_source_new(&jabber_source_funcs,sizeof(GSource));
269         g_source_attach(jabber_source,g_main_loop_get_context(main_loop));
270         return 0;
271 }
272
Note: See TracBrowser for help on using the browser.