summaryrefslogtreecommitdiff
path: root/xmpp.c
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp.c')
-rw-r--r--xmpp.c200
1 files changed, 0 insertions, 200 deletions
diff --git a/xmpp.c b/xmpp.c
deleted file mode 100644
index 18bb6c5..0000000
--- a/xmpp.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * LimoX - The Linux on mobile XMPP chat client
- * Copyright (C) 2022 xengineering
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-
-#define _GNU_SOURCE
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdbool.h>
-
-
-/*
- * Get the domainpart of the Jabber ID (JID)
- *
- * See https://datatracker.ietf.org/doc/html/rfc7622#section-3.2 for details.
- */
-char *get_domainpart(char *jid)
-{
- int start = 0; // inclusive index
- int stop = strlen(jid); // exclusive index
-
- for(int i=0; i<strlen(jid); i++) {
- if (jid[i] == '/') {
- stop = i;
- break;
- }
- }
-
- for(int i=0; i<strlen(jid); i++) {
- if (jid[i] == '@') {
- start = i + 1;
- break;
- }
- }
-
- char *retval = (char *)malloc((stop-start+1) * sizeof(char));
- memcpy(retval, jid+start, (stop-start) * sizeof(char));
- retval[stop] = '\0';
-
- return retval;
-}
-
-/*
- * Return the preferred struct addrinfo * or NULL
- *
- * This handles DNS resolution. It returns the first valid addrinfo which is
- * returned by getaddrinfo. Mind that the addrinfo could use IPv6 instead of
- * IPv4.
- *
- * FIXME this just takes the first received IPv4 address (by far not compliant
- * to RFC 6120!)
- * FIXME This function contains a memory leak! Free the linked list servinfo!
- */
-struct addrinfo *resolve_dns(char *domain)
-{
- struct addrinfo hints;
- struct addrinfo *servinfo;
- void *addr;
- char ipstr[INET6_ADDRSTRLEN];
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(domain, "xmpp-client", &hints, &servinfo) != 0) {
- printf("Failed to resolve hostname '%s'.\n", domain);
- return NULL;
- }
- struct addrinfo *p;
- for(p=servinfo; p!=NULL; p=p->ai_next) {
- if (p->ai_family == AF_INET) {
- struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
- addr = &(ipv4->sin_addr);
- inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
- printf("Got compatible IPv4 address %s from DNS.\n", ipstr);
- return p;
- } else if (p->ai_family == AF_INET6) {
- printf("Ignored IPv6 DNS entry which is not supported.\n");
- } else {
- printf("Ignored unknown addrinfo address type.\n");
- }
- }
- printf("No suitable IP address found via DNS!\n");
- return NULL;
-}
-
-/*
- * Start XMPP stream via the given socket filedescriptor
- *
- * Returns 0 in case of success and -1 otherwise.
- */
-int start_stream(int sock_fd, char *jid, char *domainpart)
-{
- const char *tmpl = "<stream:stream\
- from='%s'\
- to='%s'\
- version='1.0'\
- xml:lang='en'\
- xmlns='jabber:client'\
- xmlns:stream='http://etherx.jabber.org/streams'>";
-
- char *msg;
- asprintf(&msg, tmpl, jid, domainpart);
- int len = strlen(msg);
-
- int sent = send(sock_fd, msg, len, 0);
- if (sent == len) {
- printf(">>> %s\n", msg);
- return 0;
- } else if (sent == 0) {
- printf("Failed to send any bytes to server!\n");
- return -1;
- } else {
- printf("Could just send %d bytes of %d bytes to server!\n", sent, len);
- return -1;
- }
-}
-
-/*
- * Get JID and password and return true on success
- */
-bool get_credentials(char **jid, char **pwd)
-{
- if (getenv("LIMOX_USER") == NULL || getenv("LIMOX_PWD") == NULL) {
- printf("Failed to connect.\n");
- printf("Please set the LIMOX_USER and LIMOX_PWD shell variables.\n");
- return false;
- }
-
- *jid = getenv("LIMOX_USER");
- *pwd = getenv("LIMOX_PWD");
-
- return true;
-}
-
-/*
- * Initialize the network connection to the XMPP server and return socket fd
- *
- * TODO: Error handling is missing.
- */
-int xmpp_connect(void)
-{
- printf("net_init()\n");
-
- int sock = -1;
-
- char *jid;
- char *pwd;
- if (!get_credentials(&jid, &pwd)) {
- return sock;
- }
- printf("Trying to connect as '%s' with '%s'.\n", jid, pwd);
-
- char *domain = get_domainpart(jid);
- printf("Domainpart is '%s'.\n", domain);
-
- struct addrinfo *addr = resolve_dns(domain);
-
- sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
- if (sock == -1) {
- printf("Failed to get socket from OS!.");
- return sock;
- } else {
- printf("Got socket number %d from OS.\n", sock);
- }
-
- if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
- printf("Failed to connect!\n");
- return sock;
- } else {
- printf("Successfully connected.\n");
- }
-
- if (start_stream(sock, jid, domain) == -1) {
- printf("Failed to init stream!\n");
- return sock;
- }
- printf("Stream init sent.\n");
-
- return sock;
-}