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