summaryrefslogtreecommitdiffstats
path: root/src/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/session.c')
-rw-r--r--src/session.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/session.c b/src/session.c
new file mode 100644
index 0000000..e4780e9
--- /dev/null
+++ b/src/session.c
@@ -0,0 +1,197 @@
+#include <stdio.h>
+#include <assert.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <ne_uri.h>
+#include <ne_request.h>
+#include <ne_basic.h>
+#include <ne_props.h>
+#include <ne_utils.h>
+#include <ne_socket.h>
+#include <ne_auth.h>
+#include <ne_dates.h>
+
+#include "session.h"
+
+
+static pthread_once_t session_once = PTHREAD_ONCE_INIT;
+static pthread_key_t session_tsd_key;
+
+static ne_uri uri;
+static int b_uri = 0;
+
+static const char *username = NULL, *password = NULL;
+const char *base_directory = NULL;
+
+static pthread_mutex_t credential_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+static char* ask_user(char *p, int hidden) {
+ char q[256], *r;
+ struct termios t;
+ int c, l;
+
+
+ if (hidden) {
+ if (!isatty(fileno(stdin)))
+ hidden = 0;
+ else {
+ if (tcgetattr(fileno(stdin), &t) < 0)
+ hidden = 0;
+ else {
+ c = t.c_lflag;
+ t.c_lflag &= ~ECHO;
+ if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0)
+ hidden = 0;
+ }
+ }
+ }
+
+ fprintf(stderr, "%s: ", p);
+ r = fgets(q, sizeof(q), stdin);
+ l = strlen(q);
+ if (l && q[l-1] == '\n')
+ q[l-1] = 0;
+
+ if (hidden) {
+ t.c_lflag = c;
+ tcsetattr(fileno(stdin), TCSANOW, &t);
+ fprintf(stderr, "\n");
+ }
+
+ return r ? strdup(r) : NULL;
+}
+
+static int ssl_verify_cb(void *userdata, int failures, const ne_ssl_certificate *cert) {
+ return 0;
+}
+
+static int ne_auth_creds_cb(void *userdata, const char *realm, int attempt, char *u, char *p) {
+ int r = -1;
+
+
+ pthread_mutex_lock(&credential_mutex);
+
+ if (attempt) {
+ fprintf(stderr, "Authenication failure!\n");
+ free((void*) username);
+ free((void*) password);
+ username = password = NULL;
+ }
+
+ if (!username)
+ username = ask_user("Username", 0);
+
+ if (username && !password)
+ password = ask_user("Password", 1);
+
+ if (username && password) {
+ snprintf(u, NE_ABUFSIZ, "%s", username);
+ snprintf(p, NE_ABUFSIZ, "%s", password);
+ r = 0;
+ }
+
+ pthread_mutex_unlock(&credential_mutex);
+ return r;
+}
+
+static ne_session *session_open(void) {
+ char *scheme = NULL;
+ ne_session *session;
+
+ if (!b_uri)
+ return NULL;
+
+ scheme = uri.scheme ? uri.scheme : "http";
+
+ if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
+ fprintf(stderr, "Failed to create session\n");
+ return NULL;
+ }
+
+ ne_ssl_set_verify(session, ssl_verify_cb, NULL);
+ ne_set_server_auth(session, ne_auth_creds_cb, NULL);
+ return session;
+}
+
+static void session_destroy(void *s) {
+ ne_session *session = s;
+ assert(s);
+ ne_session_destroy(session);
+}
+
+static void session_tsd_key_init(void) {
+ pthread_key_create(&session_tsd_key, session_destroy);
+}
+
+ne_session *session_get(void) {
+ ne_session *session;
+
+ pthread_once(&session_once, session_tsd_key_init);
+
+ if ((session = pthread_getspecific(session_tsd_key)))
+ return session;
+
+ session = session_open();
+ pthread_setspecific(session_tsd_key, session);
+
+ return session;
+}
+
+int session_set_uri(const char *s, const char *u, const char *p) {
+ assert(!b_uri && !username && !password);
+ int l;
+
+ if (ne_uri_parse(s, &uri)) {
+ fprintf(stderr, "Invalid URI <%s>\n", s);
+ goto finish;
+ }
+
+ b_uri = 1;
+
+ if (!uri.host) {
+ fprintf(stderr, "Missing host part in URI <%s>\n", s);
+ goto finish;
+ }
+
+ base_directory = strdup(uri.path);
+ l = strlen(base_directory);
+ if (base_directory[l-1] == '/')
+ ((char*) base_directory)[l-1] = 0;
+
+ if (u)
+ username = strdup(u);
+
+ if (p)
+ password = strdup(p);
+
+ return 0;
+
+finish:
+
+ if (b_uri) {
+ ne_uri_free(&uri);
+ b_uri = 0;
+ }
+
+ return -1;
+}
+
+
+void session_free(void) {
+ if (b_uri) {
+ ne_uri_free(&uri);
+ b_uri = 0;
+ }
+
+ free((char*) username);
+ free((char*) password);
+ free((char*) base_directory);
+
+ username = password = base_directory = NULL;
+}
+