Inital commit
[fusedav.git] / src / session.c
blobe4780e9c9ae3bf4986f9771b25f6d6235be302dd
1 #include <stdio.h>
2 #include <assert.h>
3 #include <pthread.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <termios.h>
7 #include <unistd.h>
9 #include <ne_uri.h>
10 #include <ne_request.h>
11 #include <ne_basic.h>
12 #include <ne_props.h>
13 #include <ne_utils.h>
14 #include <ne_socket.h>
15 #include <ne_auth.h>
16 #include <ne_dates.h>
18 #include "session.h"
21 static pthread_once_t session_once = PTHREAD_ONCE_INIT;
22 static pthread_key_t session_tsd_key;
24 static ne_uri uri;
25 static int b_uri = 0;
27 static const char *username = NULL, *password = NULL;
28 const char *base_directory = NULL;
30 static pthread_mutex_t credential_mutex = PTHREAD_MUTEX_INITIALIZER;
33 static char* ask_user(char *p, int hidden) {
34 char q[256], *r;
35 struct termios t;
36 int c, l;
39 if (hidden) {
40 if (!isatty(fileno(stdin)))
41 hidden = 0;
42 else {
43 if (tcgetattr(fileno(stdin), &t) < 0)
44 hidden = 0;
45 else {
46 c = t.c_lflag;
47 t.c_lflag &= ~ECHO;
48 if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0)
49 hidden = 0;
54 fprintf(stderr, "%s: ", p);
55 r = fgets(q, sizeof(q), stdin);
56 l = strlen(q);
57 if (l && q[l-1] == '\n')
58 q[l-1] = 0;
60 if (hidden) {
61 t.c_lflag = c;
62 tcsetattr(fileno(stdin), TCSANOW, &t);
63 fprintf(stderr, "\n");
66 return r ? strdup(r) : NULL;
69 static int ssl_verify_cb(void *userdata, int failures, const ne_ssl_certificate *cert) {
70 return 0;
73 static int ne_auth_creds_cb(void *userdata, const char *realm, int attempt, char *u, char *p) {
74 int r = -1;
77 pthread_mutex_lock(&credential_mutex);
79 if (attempt) {
80 fprintf(stderr, "Authenication failure!\n");
81 free((void*) username);
82 free((void*) password);
83 username = password = NULL;
86 if (!username)
87 username = ask_user("Username", 0);
89 if (username && !password)
90 password = ask_user("Password", 1);
92 if (username && password) {
93 snprintf(u, NE_ABUFSIZ, "%s", username);
94 snprintf(p, NE_ABUFSIZ, "%s", password);
95 r = 0;
98 pthread_mutex_unlock(&credential_mutex);
99 return r;
102 static ne_session *session_open(void) {
103 char *scheme = NULL;
104 ne_session *session;
106 if (!b_uri)
107 return NULL;
109 scheme = uri.scheme ? uri.scheme : "http";
111 if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
112 fprintf(stderr, "Failed to create session\n");
113 return NULL;
116 ne_ssl_set_verify(session, ssl_verify_cb, NULL);
117 ne_set_server_auth(session, ne_auth_creds_cb, NULL);
118 return session;
121 static void session_destroy(void *s) {
122 ne_session *session = s;
123 assert(s);
124 ne_session_destroy(session);
127 static void session_tsd_key_init(void) {
128 pthread_key_create(&session_tsd_key, session_destroy);
131 ne_session *session_get(void) {
132 ne_session *session;
134 pthread_once(&session_once, session_tsd_key_init);
136 if ((session = pthread_getspecific(session_tsd_key)))
137 return session;
139 session = session_open();
140 pthread_setspecific(session_tsd_key, session);
142 return session;
145 int session_set_uri(const char *s, const char *u, const char *p) {
146 assert(!b_uri && !username && !password);
147 int l;
149 if (ne_uri_parse(s, &uri)) {
150 fprintf(stderr, "Invalid URI <%s>\n", s);
151 goto finish;
154 b_uri = 1;
156 if (!uri.host) {
157 fprintf(stderr, "Missing host part in URI <%s>\n", s);
158 goto finish;
161 base_directory = strdup(uri.path);
162 l = strlen(base_directory);
163 if (base_directory[l-1] == '/')
164 ((char*) base_directory)[l-1] = 0;
166 if (u)
167 username = strdup(u);
169 if (p)
170 password = strdup(p);
172 return 0;
174 finish:
176 if (b_uri) {
177 ne_uri_free(&uri);
178 b_uri = 0;
181 return -1;
185 void session_free(void) {
186 if (b_uri) {
187 ne_uri_free(&uri);
188 b_uri = 0;
191 free((char*) username);
192 free((char*) password);
193 free((char*) base_directory);
195 username = password = base_directory = NULL;