int main(int argc, char **argv) { struct xmpp xmpp = {0}; char path_buf[PATH_BUF]; int i, port = XMPP_PORT, ret = 1; char *jid = 0, *srv = 0, *s; s = getenv("HOME"); snprintf(path_buf, sizeof(path_buf), "%s/%s", (s) ? s : ".", root); s = getenv("USER"); snprintf(me, sizeof(me), "%s", (s) ? s : "me"); for (i = 1; i < argc - 1 && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'r': snprintf(path_buf, sizeof(path_buf), "%s", argv[++i]); break; case 'n': snprintf(me, sizeof(me), "%s", argv[++i]); break; case 'j': jid = argv[++i]; break; case 's': srv = argv[++i]; break; case 'p': port = atoi(argv[++i]); break; case 'l': log_level = atoi(argv[++i]); break; case 'e': snprintf(evfifo, sizeof(evfifo), "%s", argv[++i]); break; default: die_usage(); } if (!jid) die_usage(); xmpp.send = io_send; xmpp.tls_fn = start_tls; xmpp.stream_fn = stream_handler; xmpp.node_fn = node_handler; xmpp.auth_fn = auth_handler; xmpp.use_sasl = use_sasl; xmpp.jid = jid; if (read_line(0, sizeof(xmpp.pwd), xmpp.pwd)) xmpp.pwd[0] = 0; if (xmpp_init(&xmpp, 4096)) return 1; if (!srv) srv = xmpp.server; s = jid_partial(xmpp.jid, &i); snprintf(rootdir, sizeof(rootdir), "%s/%.*s", path_buf, i, s); fd = tcp_connect(srv, port); if (fd < 0) return 1; if (!(xmpp_start(&xmpp) != 0 || process_connection(fd, &xmpp))) ret = 0; xmpp_clean(&xmpp); close(fd); shutdown(fd, 2); return ret; }
static int node_handler(int x, void *user) { struct xmpp *xmpp = (struct xmpp *)user; char *name, *msg, *from, *show, *status, *type; int r, n; r = xmpp_default_node_hook(x, xmpp, user); if (r < 0) { if (!xmpp->is_authorized) fprintf(stderr, "Authorization error.\n"); return -1; } if (r) return 0; name = xml_node_name(x, &xmpp->xml.mem); if (!name) return -1; from = xml_node_find_attr(x, "from", &xmpp->xml.mem); if (!strcmp(name, "message")) { from = from ? jid_partial(from, &n) : 0; if (!from) return -1; snprintf(jid_from, sizeof(jid_from), "%.*s", n, from); msg = xml_node_find_text(x, "body", &xmpp->xml.mem); if (!msg) return -1; print_msg("<%.*s> %s\n", n, from, msg); } else if (!strcmp(name, "presence")) { if (!from) return -1; show = xml_node_find_text(x, "show", &xmpp->xml.mem); status = xml_node_find_text(x, "status", &xmpp->xml.mem); type = xml_node_find_attr(x, "type", &xmpp->xml.mem); if (type) print_msg("-!- %s sends %s\n", from, type); print_msg("-!- %s is %s (%s)\n", from, show ? show : (type ? type : "online"), status ? status : ""); } else if (!strcmp(name, "iq")) { name = xml_node_find_attr(x, "id", &xmpp->xml.mem); if (name && !strcmp(name, "roster")) roster_handler(x, xmpp); } return 0; }
static void cmd_leave(struct xmpp *xmpp, struct contact *u, char *s) { char *part; int len; if (s[2] && s[3]) { part = jid_partial(s + 3, &len); if (!part) return; find_contact(u, len, part); } if (!u->jid[0]) return; if (!strcmp(u->type, "groupchat")) xmpp_printf(xmpp, "<presence to='%s' type='unavailable'/>", u->jid); rm_contact(u); }
static void cmd_join(struct xmpp *xmpp, struct contact *u, char *s) { char *p, *part; int len; p = strchr(s + 3, ' '); if (p) *p = 0; part = jid_partial(s + 3, &len); if (!part) return; add_contact(len, part); if (p) { send_message(xmpp, "chat", s + 3, p + 1); print_msg(len, part, "<%s> %s\n", me, p + 1); } }
static void cmd_join_room(struct xmpp *xmpp, struct contact *u, char *s) { char *p, *part, *res; char to[JID_BUF]; int npart, nres; p = strchr(s + 3, ' '); if (p) *p = 0; part = jid_partial(s + 3, &npart); res = jid_resource(s + 3, &nres); if (!(part && res)) return; u = add_contact(npart, part); u->type = "groupchat"; snprintf(to, sizeof(to), "%.*s/%.*s", npart, part, nres, res); join_room(xmpp, to); }
static int presence_hook(int x, struct xmpp *xmpp) { char *show, *s, *status, *from, *part, *type; struct contact *u; int npart; show = xml_node_find_text(x, "show", &xmpp->xml.mem); status = xml_node_find_text(x, "status", &xmpp->xml.mem); type = xml_node_find_attr(x, "type", &xmpp->xml.mem); from = xml_node_find_attr(x, "from", &xmpp->xml.mem); if (!from) return 0; show = (!show && type && !strcmp("unavailable", type)) ? type : show; show = show ? show : STR_ONLINE; status = status ? status : ""; for (s = status; *s; ++s) if (*s == '\n') *s = '\\'; part = jid_partial(from, &npart); find_contact(u, npart, part); if (type && type[0] && (!u || strcmp(u->type, "groupchat"))) print_msg(0, "", "-!- %s sends %s\n", from, type); if (!u || strcmp(u->type, "groupchat")) print_msg(0, "", "-!- %s is %s (%s)\n", from, show, status); if (u) { if (!strcmp(u->type, "groupchat")) { if (!strcasecmp(show, STR_ONLINE) || !strcasecmp(show, STR_OFFLINE)) print_msg(npart, part, "-!- %s is %s\n", from, show); } else { print_msg(npart, part, "-!- %s is %s (%s)\n", from, show, status); snprintf(u->show, sizeof(u->show), "%s", show); snprintf(u->status, sizeof(u->status), "%s", status); } } return 0; }
static int msg_hook(int x, struct xmpp *xmpp) { char *s, *from, *part, *n, *type; int npart, len; struct contact *u; s = xml_node_find_text(x, "body", &xmpp->xml.mem); from = xml_node_find_attr(x, "from", &xmpp->xml.mem); part = from ? jid_partial(from, &npart) : 0; if (!part || !s) return 0; u = add_contact(npart, part); type = xml_node_find_attr(x, "type", &xmpp->xml.mem); if (type && !strcmp(type, "groupchat")) { u->type = "groupchat"; n = jid_resource(from, &len); } else n = jid_name(from, &len); print_msg(npart, from, "<%.*s> %s\n", len, n, s); notify(u->type, npart, from, len, n, s); return 0; }