Fix bytarget list not cleared for new search PAZ-1019
[pazpar2-moved-to-github.git] / src / host.c
1 /* This file is part of Pazpar2.
2    Copyright (C) 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 // Create a new host structure for hostport
43 static struct host *create_host(const char *proxy,
44                                 const char *tproxy,
45                                 iochan_man_t iochan_man)
46 {
47     struct host *host;
48
49     host = xmalloc(sizeof(struct host));
50     host->proxy = 0;
51     host->tproxy = 0;
52     if (proxy && *proxy)
53         host->proxy = xstrdup(proxy);
54     else
55     {
56         assert(tproxy);
57         host->tproxy = xstrdup(tproxy);
58     }
59     host->connections = 0;
60     host->ipport = 0;
61     host->mutex = 0;
62     host->error = 0;
63
64     if (host_getaddrinfo(host, iochan_man))
65     {
66         xfree(host->ipport);
67         xfree(host->tproxy);
68         xfree(host->proxy);
69         xfree(host);
70         return 0;
71     }
72     pazpar2_mutex_create(&host->mutex, "host");
73
74     yaz_cond_create(&host->cond_ready);
75
76     return host;
77 }
78
79 struct host *find_host(database_hosts_t hosts, const char *url,
80                        const char *proxy, int port,
81                        iochan_man_t iochan_man)
82 {
83     struct host *p;
84     char *tproxy = 0;
85
86     if (!proxy || !*proxy)
87     {
88         char *cp;
89
90         tproxy = xmalloc (strlen(url) + 10); /* so we can add :port */
91         strcpy(tproxy, url);
92         if (!strncmp(tproxy, "http://", 7))
93             cp = tproxy + 7;
94         else if (!strncmp(tproxy, "https://", 8))
95             cp = tproxy + 8;
96         else
97             cp = tproxy;
98         for (; *cp; cp++)
99             if (strchr("/?#~", *cp))
100             {
101                 *cp = '\0';
102                 break;
103             }
104         if (!strchr(tproxy, ':'))
105             sprintf(cp, ":%d", port); /* no port given, add it */
106     }
107     yaz_mutex_enter(hosts->mutex);
108     for (p = hosts->hosts; p; p = p->next)
109     {
110         if (!yaz_strcmp_null(p->tproxy, tproxy) &&
111             !yaz_strcmp_null(p->proxy, proxy))
112         {
113             break;
114         }
115     }
116     if (!p)
117     {
118         p = create_host(proxy, tproxy, iochan_man);
119         if (p)
120         {
121             p->next = hosts->hosts;
122             hosts->hosts = p;
123         }
124     }
125     if (p && p->error) /* already resolved error */
126         p = 0;
127     yaz_mutex_leave(hosts->mutex);
128     xfree(tproxy);
129     return p;
130 }
131
132 database_hosts_t database_hosts_create(void)
133 {
134     database_hosts_t p = xmalloc(sizeof(*p));
135     p->hosts = 0;
136     p->mutex = 0;
137     pazpar2_mutex_create(&p->mutex, "database");
138     return p;
139 }
140
141 void database_hosts_destroy(database_hosts_t *pp)
142 {
143     if (*pp)
144     {
145         struct host *p = (*pp)->hosts;
146         while (p)
147         {
148             struct host *p_next = p->next;
149             yaz_mutex_destroy(&p->mutex);
150             yaz_cond_destroy(&p->cond_ready);
151             xfree(p->ipport);
152             xfree(p);
153             p = p_next;
154         }
155         yaz_mutex_destroy(&(*pp)->mutex);
156         xfree(*pp);
157     }
158 }
159
160 /*
161  * Local variables:
162  * c-basic-offset: 4
163  * c-file-style: "Stroustrup"
164  * indent-tabs-mode: nil
165  * End:
166  * vim: shiftwidth=4 tabstop=8 expandtab
167  */
168