jacs.c - jacc - Jabber/XMPP client for Plan 9
(HTM) git clone git://r-36.net/jacc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
jacs.c (4764B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <u.h>
7 #include <libc.h>
8 #include <auth.h>
9 #include <mp.h>
10 #include <libsec.h>
11 #include "xmlpull.h"
12 #include "jacs.h"
13 #include "dat.h"
14 #include "roster.h"
15 #include "recv.h"
16
17 #define NAME "jacs - Jabber Service Registry for Plan9"
18 #define VERSION "2nd ed"
19 #define OS "Plan9 4th ed"
20
21 int
22 xmljacc(int sock)
23 {
24 return fprint(sock, "<?xml version=\"1.0\"?>\n");
25 }
26
27 int
28 loginjacc(int sock, char *serv)
29 {
30 return fprint(sock, "<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\""
31 " xmlns=\"jabber:client\" to=\"%s\">\n", serv);
32 }
33
34 int
35 userjacc(int sock, char *user, char *pass, char *res)
36 {
37 return fprint(sock, "<iq type=\"set\" id=\"auth_1\">\n"
38 "<query xmlns=\"jabber:iq:auth\">\n"
39 "<username>%s</username>\n"
40 "<password>%s</password>\n"
41 "<resource>%s</resource>\n"
42 "</query>\n"
43 "</iq>\n", user, pass, res);
44 }
45
46 int
47 presencejacc(int sock, char *stat, char *show, char *from, char *to)
48 {
49 return fprint(sock, "<presence%s%s%s%s%s%s>\n"
50 "<show>%s</show>\n"
51 "<status>%s</status>\n"
52 "<priority>1</priority>\n"
53 "</presence>\n", (from != nil) ? " from=\"" : "",
54 (from != nil) ? from : "",
55 (from != nil) ? "\"" : "",
56 (to != nil) ? " to=\"" : "",
57 (to != nil) ? to : "",
58 (to != nil) ? "\"" : "",
59 (show != nil) ? show : "",
60 (stat != nil) ? stat : "");
61 }
62
63 int
64 versionjacc(int sock, char *from, char *to, char *id)
65 {
66 return fprint(sock, "<iq from=\"%s\" type=\"result\" id=\"%s\" to=\"%s\">\n"
67 "<query xmlns=\"jabber:iq:version\">\n"
68 "<name>" NAME "</name>\n"
69 "<version>" VERSION "</version>\n"
70 "<os>" OS "</os>\n"
71 "</query>\n"
72 "</iq>\n", from, id, to);
73 }
74
75 int
76 featuresjacc(int sock, char *from, char *to, char *id)
77 {
78 return fprint(sock, "<iq from=\"%s\" type=\"result\" to=\"%s\" id=\"%s\">\n"
79 "<query xmlns=\"http://jabber.org/protocol/disco#info\">\n"
80 "</query>\n"
81 "</iq>\n", from, to, id);
82 }
83
84 int
85 answersjacc(int sock, char *who, char *t, char *id, ilist *l)
86 {
87 fprint(sock, "<iq type=\"set\" to=\"%s\" id=\"%s\">\n"
88 "<query xmlns=\"%s\">\n", who, id, t);
89 for(; l; l = l->n)
90 fprint(sock, "<%s>%s</%s>\n", l->name, l->val, l->name);
91
92 return fprint(sock, "</query>\n"
93 "</iq>\n");
94 }
95
96 int
97 xmlnsjacc(int sock, char *who, char *t, char *id)
98 {
99 return fprint(sock, "<iq type=\"get\" to=\"%s\" id=\"%s\">\n"
100 "<query xmlns=\"%s\"/>\n"
101 "</iq>\n", who, id, t);
102 }
103
104 int
105 xmlnsnegjacc(int sock, char *who, char *t, char* id)
106 {
107 return fprint(sock, "<iq type=\"set\" to=\"%s\" id=\"%s\">\n"
108 "<query xmlns=\"%s\">\n"
109 "<remove/>\n"
110 "</query>\n"
111 "</iq>\n", who, id, t);
112 }
113
114 void
115 usage(void)
116 {
117 print("usage: jacs [-dtu] [-e dest] [-s tosrv] [-r res] net!server!port\n");
118 exits(0);
119 }
120
121 int
122 main(int argc, char *argv[])
123 {
124 char *server, *user, *lbl, *b, *dest, *buf, *toserver;
125 int sock, ts, tls, debug, unreg;
126 UserPasswd *i;
127 TLSconn conn;
128 jabberc *me;
129
130 tls = 0;
131 b = nil;
132 dest = nil;
133 unreg = 0;
134 debug = 0;
135 toserver = nil;
136
137 ARGBEGIN {
138 case 't':
139 tls = 1;
140 break;
141 case 'r':
142 b = EARGF(usage());
143 break;
144 case 'e':
145 dest = EARGF(usage());
146 break;
147 case 'u':
148 unreg = 1;
149 break;
150 case 'd':
151 debug = 1;
152 break;
153 case 's':
154 toserver = EARGF(usage());
155 break;
156 default:
157 usage();
158 } ARGEND;
159
160 if(argc < 1 || dest == nil)
161 usage();
162 server = strdup(argv[0]);
163
164 lbl = getwindowlbl();
165 user = reallocj(nil, strlen(server) + 9, 2);
166 snprint(user, strlen(server) + 8, "jacs - %s", server);
167 setwindowlbl(user);
168 free(user);
169
170 i = auth_getuserpasswd(auth_getkey, "proto=pass server=%s service=jabber", server);
171 if(i == nil)
172 sysfatal("auth_getuserpasswd: %r");
173
174 sock = dial(netmkaddr(server, "tcp", tls ? "5223" : "5222"), 0, 0, 0);
175 if(sock < 0)
176 sysfatal("dial: &r");
177
178 if(tls){
179 ts = tlsClient(sock, &conn);
180 if(ts < 0)
181 sysfatal("tlsClient: %r");
182 sock = ts;
183
184 if(conn.cert != nil)
185 free(conn.cert);
186 }
187
188 buf = strchr(server, '!');
189 if(buf != nil) {
190 *buf++ = '\0';
191 user = strchr(buf, '!');
192 if(user != nil)
193 *user = '\0';
194 user = strdup(buf);
195 free(server);
196 server = user;
197 }
198
199 if(toserver == nil)
200 toserver = server;
201
202 me = mkjabberc();
203 me->dest = strdup(dest);
204 me->show = strdup("Online");
205 me->stat = strdup("Online");
206 me->name = strdup(i->user);
207 me->serv = strdup(toserver);
208
209 if(b != nil)
210 me->reso = strdup(b);
211 else
212 me->reso = strdup("Plan9-Service");
213 me->jid = printjid(me->name, me->serv, me->reso);
214 me->debug = debug;
215 me->unreg = unreg;
216
217 free(buf);
218
219 if(recvjacc(sock, me, i->passwd) < 0)
220 perror("recv_jacc");
221
222 if(lbl != nil){
223 setwindowlbl(lbl);
224 lbl = nil;
225 free(lbl);
226 }
227
228 freejabberc(me);
229 exits(0);
230 return 0;
231 }