roster.c

  1/*
  2 * @file roster.c
  3 *
  4 * vim: expandtab:ts=2:sts=2:sw=2
  5 *
  6 * Copyright (C) 2020 Anoxinon e.V.
  7 *
  8 * This file is part of xmppc.
  9 *
 10 * xmppc is free software: you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation, either version 3 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * xmppc is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 22 *
 23 * German
 24 *
 25 * Diese Datei ist Teil von xmppc.
 26 *
 27 * xmppc ist Freie Software: Sie können es unter den Bedingungen
 28 * der GNU General Public License, wie von der Free Software Foundation,
 29 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 30 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 31 *
 32 * xmppc wird in der Hoffnung, dass es nützlich sein wird, aber
 33 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 34 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 35 * Siehe die GNU General Public License für weitere Details.
 36 *
 37 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 38 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 39 */
 40
 41#include "roster.h"
 42#include <stdio.h>
 43#include <string.h>
 44#include <stdlib.h>
 45
 46#define COMMAND_LIST "list"
 47#define COMMAND_EXPORT "export"
 48
 49typedef enum commandTyp { C_UNKOWN, LIST, EXPORT } CommandType;
 50
 51typedef struct command {
 52  CommandType type;
 53} command_t;
 54
 55static void _roster_parse_command(command_t *command, int argc, char *argv[]);
 56
 57static void _roster_send_query(xmppc_t *xmppc,command_t *command);
 58
 59static int _handle_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
 60                  void *const userdata);
 61
 62static void _teardown(xmppc_t *xmppc);
 63
 64void roster_execute_command(xmppc_t *xmppc, int argc, char *argv[]) {
 65  command_t *command = malloc(sizeof(command_t)); 
 66  command->type = UNKOWN;
 67
 68  if (argc == 0) {
 69    logError(xmppc, "No subcommand provided\n");
 70  } else {
 71    _roster_parse_command(command, argc, argv);
 72    _roster_send_query(xmppc, command);
 73  }
 74
 75  _teardown(xmppc);
 76}
 77
 78static void _roster_parse_command(command_t *command, int argc, char *argv[]) {
 79  if (strcmp(COMMAND_LIST, argv[0]) == 0) {
 80    command->type = LIST;
 81  } else if (strcmp(COMMAND_EXPORT, argv[0]) == 0) {
 82    command->type = EXPORT;
 83  }
 84}
 85
 86static void _roster_send_query(xmppc_t *xmppc, command_t *command ) {
 87  logInfo(xmppc, "Send roster query\n");
 88  xmpp_ctx_t *ctx = xmppc->ctx;
 89  xmpp_conn_t *conn = xmppc->conn;
 90  xmpp_stanza_t *iq, *query;
 91  iq = xmpp_iq_new(ctx, "get", "roster1");
 92  query = xmpp_stanza_new(ctx);
 93  xmpp_stanza_set_name(query, "query");
 94  xmpp_stanza_set_ns(query, XMPP_NS_ROSTER);
 95  xmpp_stanza_add_child(iq, query);
 96  xmpp_stanza_release(query);
 97  xmpp_id_handler_add(conn, _handle_reply, "roster1",command);
 98  xmpp_send(conn, iq);
 99  xmpp_stanza_release(iq);
100}
101
102int _handle_reply(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza,
103                  void *const userdata) {
104  command_t* command = (command_t*) userdata;
105  xmpp_stanza_t *query, *item;
106  const char *type, *name;
107  type = xmpp_stanza_get_type(stanza);
108  if (strcmp(type, "error") == 0)
109    printf("query failed\n");
110  else {
111    query = xmpp_stanza_get_child_by_name(stanza, "query");
112    for (item = xmpp_stanza_get_children(query); item;
113         item = xmpp_stanza_get_next(item)) {
114      if(command->type == LIST) {
115      if ((name = xmpp_stanza_get_attribute(item, "name"))) 
116        printf("\t %s (%s) sub=%s\n", name,
117               xmpp_stanza_get_attribute(item, "jid"),
118               xmpp_stanza_get_attribute(item, "subscription"));
119      else
120        printf("\t %s sub=%s\n", xmpp_stanza_get_attribute(item, "jid"),
121               xmpp_stanza_get_attribute(item, "subscription"));
122      } else if (command->type == EXPORT) {
123        printf("%s\n", xmpp_stanza_get_attribute(item, "jid"));
124      }
125    }
126  }
127  return 0;
128}
129
130static void _teardown(xmppc_t *xmppc) {
131  xmpp_conn_t *conn = xmppc->conn;
132  xmpp_disconnect(conn);
133  xmpp_stop(xmpp_conn_get_context(conn));
134}