Restructure the code a lot.
[cascardo/pubsub-bot.git] / status.c
1 /*
2  *  Copyright (C) 2009  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19
20 #include <iksemel.h>
21 #include <stdio.h>
22
23 int
24 xmpp_session_hook (iksparser *parser, iks *node)
25 {
26   iks *iq;
27   iq = iks_new ("iq");
28   iks_insert_attrib (iq, "type", "set");
29   iks_insert_attrib (iq, "id", "session1");
30   iks_insert_attrib (iks_insert (iq, "session"),
31                      "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
32   iks_send (parser, iq);
33   iks_delete (iq);
34   return 0;
35 }
36
37 int
38 xmpp_initial_presence_hook (iksparser *parser, iks *node)
39 {
40   iks *pres;
41   pres = iks_make_pres (IKS_SHOW_AVAILABLE, "Microblogging here!\n");
42   iks_send (parser, pres);
43   iks_delete (pres);
44   return 0;
45 }
46
47 int
48 xmpp_id_hook (iksparser *parser, iks *node, char *id)
49 {
50   if (!iks_strcmp (id, "bind1"))
51     {
52       xmpp_session_hook (parser, node);
53       return 0;
54     }
55   else if (!iks_strcmp (id, "session1"))
56     {
57       xmpp_initial_presence_hook (parser, node);
58       return 0;
59     }
60   return 1;
61 }
62
63 int
64 xmpp_ns_hook (iksparser *parser, iks *node, char *ns)
65 {
66   return 1;
67 }
68
69 int
70 xmpp_iq_error (iksparser *parser, iks *node)
71 {
72   iks *enode;
73   char *to;
74   char *from;
75   if (!iks_strcmp (iks_find_attrib (node, "type"), "error"))
76     return 1;
77   to = iks_find_attrib (node, "to");
78   from = iks_find_attrib (node, "from");
79   if (to)
80     iks_insert_attrib (node, "from", to);
81   else
82     iks_insert_attrib (node, "from", NULL);
83   if (from)
84     iks_insert_attrib (node, "to", from);
85   else
86     iks_insert_attrib (node, "to", NULL);
87   iks_insert_attrib (node, "type", "error");
88   enode = iks_insert (node, "error");
89   iks_insert_attrib (enode, "type", "cancel");
90   iks_insert_attrib (iks_insert (enode, "feature-not-implemented"),
91                      "xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas");
92   iks_send (parser, node);
93   return 0;
94 }
95
96 int
97 xmpp_tls_hook (iksparser *parser, iks *node)
98 {
99   iks_start_tls (parser);
100   return 0;
101 }
102
103 int
104 xmpp_sasl_hook (iksparser *parser, iks* node)
105 {
106   iks_start_sasl (parser, IKS_SASL_DIGEST_MD5, "pubsub", "pubsub");
107   return 0;
108 }
109
110 int
111 xmpp_bind_hook (iksparser *parser, iks *node)
112 {
113   iks *iq;
114   iq = iks_new ("iq");
115   iks_insert_attrib (iq, "type", "set");
116   iks_insert_attrib (iq, "id", "bind1");
117   iks_insert_attrib (iks_insert (iq, "bind"),
118                      "xmlns", "urn:ietf:params:xml:ns:xmpp-bind");
119   iks_send (parser, iq);
120   iks_delete (iq);
121   return 0;
122 }
123
124 int
125 xmpp_features_hook (iksparser *parser, iks *node)
126 {
127   iks *feat;
128   char *ns;
129   for (feat = iks_child (node); feat != NULL; feat = iks_next (feat))
130     {
131       ns = iks_find_attrib (feat, "xmlns");
132       if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-tls"))
133         {
134           xmpp_tls_hook (parser, node);
135           return 0;
136         }
137       else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
138         {
139           xmpp_sasl_hook (parser, node);
140           return 0;
141         }
142       else if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-bind"))
143         {
144           xmpp_bind_hook (parser, node);
145           return 0;
146         }
147     }
148   return 1;
149 }
150
151 int
152 xmpp_other_hook (iksparser *parser, iks *node, char *ns)
153 {
154   if (!iks_strcmp (ns, "urn:ietf:params:xml:ns:xmpp-sasl"))
155     {
156       if (!iks_strcmp (iks_name (node), "success"))
157         iks_send_header (parser, "jabber-br.org");
158       return 0;
159     }
160   return 1;
161 }
162
163 static int
164 hook (void *data, int type, iks *node)
165 {
166   char *name;
167   char *id;
168   char *ns;
169   char *iqns;
170   iksparser *parser;
171   parser = *(iksparser **) data;
172   name = iks_name (node);
173   id = iks_find_attrib (node, "id");
174   ns = iks_find_attrib (node, "xmlns"); 
175   iqns = iks_find_attrib (iks_child (node), "xmlns"); 
176   if (!iks_strcmp (name, "message"))
177     {
178       printf ("Got milk?\n");
179       return IKS_OK;
180     }
181   else if (!iks_strcmp (name, "presence"))
182     {
183       printf ("I sense a disturbance in the force!\n");
184     }
185   else if (!iks_strcmp (name, "iq"))
186     {
187       if (xmpp_id_hook (parser, node, id) == 0)
188         return IKS_OK;
189       if (xmpp_ns_hook (parser, node, iqns) == 0)
190         return IKS_OK;
191       xmpp_iq_error (parser, node);
192     }
193   else if (!iks_strcmp (name, "stream:features"))
194     {
195       if (xmpp_features_hook (parser, node) == 0)
196         return IKS_OK;
197     }
198   else
199     {
200       if (xmpp_other_hook (parser, node, ns) == 0)
201         return IKS_OK;
202       printf ("No no: %s\n", name);
203     }
204   return IKS_OK;
205 }
206
207 int
208 main (int argc, char **argv)
209 {
210   iksparser *parser;
211   parser = iks_stream_new ("jabber:client", &parser, hook);
212   iks_connect_tcp (parser, "jabber-br.org", 5222);
213   while (1)
214     iks_recv (parser, -1);
215   return 0;
216 }