Code

autoconf stuff
[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 = 0, l;
38     if (hidden) {
39         if (!isatty(fileno(stdin)))
40             hidden = 0;
41         else {
42             if (tcgetattr(fileno(stdin),  &t) < 0)
43                 hidden = 0;
44             else {
45                 c = t.c_lflag;
46                 t.c_lflag &= ~ECHO;
47                 if (tcsetattr(fileno(stdin), TCSANOW, &t) < 0)
48                     hidden = 0;
49             }
50         }
51     }
52     
53     fprintf(stderr, "%s: ", p);
54     r = fgets(q, sizeof(q), stdin);
55     l = strlen(q);
56     if (l && q[l-1] == '\n')
57         q[l-1] = 0;
59     if (hidden) {
60         t.c_lflag = c;
61         tcsetattr(fileno(stdin), TCSANOW, &t);
62         fprintf(stderr, "\n");
63     }
64     
65     return r ? strdup(r) : NULL;
66 }
68 static int ssl_verify_cb(void *userdata, int failures, const ne_ssl_certificate *cert) {
69     return 0;
70 }
72 static int ne_auth_creds_cb(void *userdata, const char *realm, int attempt, char *u, char *p) {
73     int r = -1;
74     
75     
76     pthread_mutex_lock(&credential_mutex);
78     if (attempt) {
79         fprintf(stderr, "Authenication failure!\n");
80         free((void*) username);
81         free((void*) password);
82         username = password = NULL;
83     }
84     
85     if (!username)
86         username = ask_user("Username", 0);
87     
88     if (username && !password)
89         password = ask_user("Password", 1);
91     if (username && password) {
92         snprintf(u, NE_ABUFSIZ, "%s", username);
93         snprintf(p, NE_ABUFSIZ, "%s", password);
94         r  = 0;
95     }
97     pthread_mutex_unlock(&credential_mutex);
98     return r;
99 }
101 static ne_session *session_open(void) {
102     char *scheme = NULL;
103     ne_session *session;
105     if (!b_uri)
106         return NULL;
108     scheme = uri.scheme ? uri.scheme : "http";
109     
110     if (!(session = ne_session_create(scheme, uri.host, uri.port ? uri.port : ne_uri_defaultport(scheme)))) {
111         fprintf(stderr, "Failed to create session\n");
112         return NULL;
113     }
115     ne_ssl_set_verify(session, ssl_verify_cb, NULL);
116     ne_set_server_auth(session, ne_auth_creds_cb, NULL);
117     return session;
120 static void session_destroy(void *s) {
121     ne_session *session = s;
122     assert(s);
123     ne_session_destroy(session);
126 static void session_tsd_key_init(void) {
127     pthread_key_create(&session_tsd_key, session_destroy);
130 ne_session *session_get(void) {
131     ne_session *session;
132     
133     pthread_once(&session_once, session_tsd_key_init);
135     if ((session = pthread_getspecific(session_tsd_key)))
136         return session;
138     session = session_open();
139     pthread_setspecific(session_tsd_key, session);
141     return session;
144 int session_set_uri(const char *s, const char *u, const char *p) {
145     assert(!b_uri && !username && !password);
146     int l;
147         
148     if (ne_uri_parse(s, &uri)) {
149         fprintf(stderr, "Invalid URI <%s>\n", s);
150         goto finish;
151     }
153     b_uri = 1;
155     if (!uri.host) {
156         fprintf(stderr, "Missing host part in URI <%s>\n", s);
157         goto finish;
158     }
160     base_directory = strdup(uri.path);
161     l = strlen(base_directory);
162     if (base_directory[l-1] == '/')
163         ((char*) base_directory)[l-1] = 0;
165     if (u)
166         username = strdup(u);
168     if (p)
169         password = strdup(p);
171     return 0;
172     
173 finish:
174     
175     if (b_uri) {
176         ne_uri_free(&uri);
177         b_uri = 0;
178     }
180     return -1;
184 void session_free(void) {
185     if (b_uri) {
186         ne_uri_free(&uri);
187         b_uri = 0;
188     }
190     free((char*) username);
191     free((char*) password);
192     free((char*) base_directory);
194     username = password = base_directory = NULL;