Allow unix sockets.. Not well tested yet!
[pazpar2-moved-to-github.git] / src / host.c
1 /* This file is part of Pazpar2.
2    Copyright (C) 2006-2013 Index Data
3
4 Pazpar2 is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <assert.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <yaz/log.h>
28 #include <yaz/nmem.h>
29 #include <yaz/matchstr.h>
30 #include <yaz/unix.h>
31
32 #include "ppmutex.h"
33 #include "session.h"
34 #include "host.h"
35
36 #include <sys/types.h>
37
38 struct database_hosts {
39     struct host *hosts;
40     YAZ_MUTEX mutex;
41 };
42
43 // Create a new host structure for hostport
44 static struct host *create_host(const char *proxy,
45                                 const char *tproxy,
46                                 CS_TYPE cs_type,
47                                 iochan_man_t iochan_man)
48 {
49     struct host *host;
50
51     host = xmalloc(sizeof(struct host));
52     host->proxy = 0;
53     host->tproxy = 0;
54     if (proxy && *proxy)
55         host->proxy = xstrdup(proxy);
56     else
57     {
58         assert(tproxy);
59         host->tproxy = xstrdup(tproxy);
60     }
61     host->connections = 0;
62     host->ipport = 0;
63     host->mutex = 0;
64
65     if (cs_type == unix_type)
66         host->ipport = xstrdup(host->tproxy);
67     else
68     {
69         if (host_getaddrinfo(host, iochan_man))
70         {
71             xfree(host->ipport);
72             xfree(host->tproxy);
73             xfree(host->proxy);
74             xfree(host);
75             return 0;
76         }
77     }
78     pazpar2_mutex_create(&host->mutex, "host");
79
80     yaz_cond_create(&host->cond_ready);
81
82     return host;
83 }
84
85 struct host *find_host(database_hosts_t hosts, const char *url,
86                        const char *proxy, iochan_man_t iochan_man)
87 {
88     struct host *p;
89     char *tproxy = 0;
90     const char *host = 0;
91     CS_TYPE t;
92     enum oid_proto proto;
93     char *connect_host = 0;
94     if (!cs_parse_host(url, &host, &t, &proto, &connect_host))
95         return 0;
96     else
97     {
98         if (t == unix_type)
99             tproxy = xstrdup(url);
100         else
101         {
102             if (proxy && *proxy)
103             {
104                 /* plain proxy host already given, but we get CS_TYPE t  */
105                 xfree(connect_host);
106             }
107             else
108             {
109                 if (connect_host)
110                 {
111                     tproxy = connect_host;
112                 }
113                 else
114                 {
115                     char *cp;
116                     tproxy = xstrdup(host);
117                     for (cp = tproxy; *cp; cp++)
118                         if (strchr("/?#~", *cp))
119                         {
120                             *cp = '\0';
121                             break;
122                         }
123                 }
124             }
125         }
126     }
127     yaz_mutex_enter(hosts->mutex);
128     for (p = hosts->hosts; p; p = p->next)
129     {
130         if (!yaz_strcmp_null(p->tproxy, tproxy) &&
131             !yaz_strcmp_null(p->proxy, proxy))
132         {
133             break;
134         }
135     }
136     if (!p)
137     {
138         p = create_host(proxy, tproxy, t, iochan_man);
139         if (p)
140         {
141             p->next = hosts->hosts;
142             hosts->hosts = p;
143         }
144     }
145     yaz_mutex_leave(hosts->mutex);
146     xfree(tproxy);
147     return p;
148 }
149
150 database_hosts_t database_hosts_create(void)
151 {
152     database_hosts_t p = xmalloc(sizeof(*p));
153     p->hosts = 0;
154     p->mutex = 0;
155     pazpar2_mutex_create(&p->mutex, "database");
156     return p;
157 }
158
159 void database_hosts_destroy(database_hosts_t *pp)
160 {
161     if (*pp)
162     {
163         struct host *p = (*pp)->hosts;
164         while (p)
165         {
166             struct host *p_next = p->next;
167             yaz_mutex_destroy(&p->mutex);
168             yaz_cond_destroy(&p->cond_ready);
169             xfree(p->ipport);
170             xfree(p);
171             p = p_next;
172         }
173         yaz_mutex_destroy(&(*pp)->mutex);
174         xfree(*pp);
175     }
176 }
177
178 /*
179  * Local variables:
180  * c-basic-offset: 4
181  * c-file-style: "Stroustrup"
182  * indent-tabs-mode: nil
183  * End:
184  * vim: shiftwidth=4 tabstop=8 expandtab
185  */
186