Code

Inital commit
[fusedav.git] / src / session.c
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;
50             }
51         }
52     }
53     
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");
64     }
65     
66     return r ? strdup(r) : NULL;
67 }
69 static int ssl_verify_cb(void *userdata, int failures, const ne_ssl_certificate *cert) {
70     return 0;
71 }
73 static int ne_auth_creds_cb(void *userdata, const char *realm, int attempt, char *u, char *p) {
74     int r = -1;
75     
76     
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;
84     }
85     
86     if (!username)
87         username = ask_user("Username", 0);
88     
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;
96     }
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";
110     
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;
114     }
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;
133     
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;
148         
149     if (ne_uri_parse(s, &uri)) {
150         fprintf(stderr, "Invalid URI <%s>\n", s);
151         goto finish;
152     }
154     b_uri = 1;
156     if (!uri.host) {
157         fprintf(stderr, "Missing host part in URI <%s>\n", s);
158         goto finish;
159     }
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;
173     
174 finish:
175     
176     if (b_uri) {
177         ne_uri_free(&uri);
178         b_uri = 0;
179     }
181     return -1;
185 void session_free(void) {
186     if (b_uri) {
187         ne_uri_free(&uri);
188         b_uri = 0;
189     }
191     free((char*) username);
192     free((char*) password);
193     free((char*) base_directory);
195     username = password = base_directory = NULL;