Make url part of connection rather than host PAZ-880
[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
31 #include "ppmutex.h"
32 #include "session.h"
33 #include "host.h"
34
35 #include <sys/types.h>
36
37 struct database_hosts {
38     struct host *hosts;
39     YAZ_MUTEX mutex;
40 };
41
42 #if YAZ_VERSIONL > 0x4023e
43 #define strcmp_null(x, y) yaz_strcmp_null(x, y)
44 #else
45 #define strcmp_null(x, y) local_strcmp_null(x, y)
46
47 static int local_strcmp_null(const char *v1, const char *v2)
48 {
49     if (v1)
50     {
51         if (v2)
52             return strcmp(v1, v2);
53         else
54             return 1;
55     }
56     else if (v2)
57         return -1;
58     return 0;
59 }
60 #endif
61
62 // Create a new host structure for hostport
63 static struct host *create_host(const char *proxy,
64                                 const char *tproxy,
65                                 iochan_man_t iochan_man)
66 {
67     struct host *host;
68
69     host = xmalloc(sizeof(struct host));
70     host->proxy = 0;
71     host->tproxy = 0;
72     if (proxy && *proxy)
73         host->proxy = xstrdup(proxy);
74     else
75     {
76         assert(tproxy);
77         host->tproxy = xstrdup(tproxy);
78     }
79     host->connections = 0;
80     host->ipport = 0;
81     host->mutex = 0;
82
83     if (host_getaddrinfo(host, iochan_man))
84     {
85         xfree(host->ipport);
86         xfree(host->tproxy);
87         xfree(host->proxy);
88         xfree(host);
89         return 0;
90     }
91     pazpar2_mutex_create(&host->mutex, "host");
92
93     yaz_cond_create(&host->cond_ready);
94
95     return host;
96 }
97
98 struct host *find_host(database_hosts_t hosts, const char *url,
99                        const char *proxy, int port,
100                        iochan_man_t iochan_man)
101 {
102     struct host *p;
103     char *tproxy = 0;
104
105     if (!proxy || !*proxy)
106     {
107         char *cp;
108
109         tproxy = xmalloc (strlen(url) + 10); /* so we can add :port */
110         strcpy(tproxy, url);
111         for (cp = tproxy; *cp; cp++)
112             if (strchr("/?#~", *cp))
113             {
114                 *cp = '\0';
115                 break;
116             }
117         if (!strchr(tproxy, ':'))
118             sprintf(cp, ":%d", port); /* no port given, add it */
119     }
120     yaz_mutex_enter(hosts->mutex);
121     for (p = hosts->hosts; p; p = p->next)
122     {
123         if (!strcmp_null(p->tproxy, tproxy) &&
124             !strcmp_null(p->proxy, proxy))
125         {
126             break;
127         }
128     }
129     if (!p)
130     {
131         p = create_host(proxy, tproxy, iochan_man);
132         if (p)
133         {
134             p->next = hosts->hosts;
135             hosts->hosts = p;
136         }
137     }
138     yaz_mutex_leave(hosts->mutex);
139     xfree(tproxy);
140     return p;
141 }
142
143 database_hosts_t database_hosts_create(void)
144 {
145     database_hosts_t p = xmalloc(sizeof(*p));
146     p->hosts = 0;
147     p->mutex = 0;
148     pazpar2_mutex_create(&p->mutex, "database");
149     return p;
150 }
151
152 void database_hosts_destroy(database_hosts_t *pp)
153 {
154     if (*pp)
155     {
156         struct host *p = (*pp)->hosts;
157         while (p)
158         {
159             struct host *p_next = p->next;
160             yaz_mutex_destroy(&p->mutex);
161             yaz_cond_destroy(&p->cond_ready);
162             xfree(p->ipport);
163             xfree(p);
164             p = p_next;
165         }
166         yaz_mutex_destroy(&(*pp)->mutex);
167         xfree(*pp);
168     }
169 }
170
171 /*
172  * Local variables:
173  * c-basic-offset: 4
174  * c-file-style: "Stroustrup"
175  * indent-tabs-mode: nil
176  * End:
177  * vim: shiftwidth=4 tabstop=8 expandtab
178  */
179