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 }