sock_man_t API complete
[yaz-moved-to-github.git] / src / nanohttp.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2009 Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file 
7  * \brief Small HTTP server
8  */
9
10 #include <yaz/zgdu.h>
11 #include <yaz/comstack.h>
12 #include <yaz/nmem.h>
13 #include <yaz/log.h>
14 #include <yaz/sock_man.h>
15 #include <assert.h>
16
17 typedef struct yaz_nano_srv_s *yaz_nano_srv_t;
18 typedef struct yaz_nano_pkg_s *yaz_nano_pkg_t;
19
20 struct yaz_nano_pkg_s {
21     void *handle;
22     int listener_id;
23     ODR encode_odr;
24     Z_GDU *request_gdu;
25     Z_GDU *response_gdu;
26 };
27
28 struct yaz_nano_srv_s {
29     COMSTACK *cs_listeners;
30     size_t num_listeners;
31     NMEM nmem;
32     yaz_sock_man_t sock_man;
33 };
34
35 void yaz_nano_srv_destroy(yaz_nano_srv_t p)
36 {
37     if (p)
38     {
39         size_t i;
40         for (i = 0; i < p->num_listeners; i++)
41             if (p->cs_listeners[i])
42                 cs_close(p->cs_listeners[i]);
43         yaz_sock_man_destroy(p->sock_man);
44         nmem_destroy(p->nmem);
45     }
46 }
47
48 yaz_nano_srv_t yaz_nano_srv_create(const char **listeners_str)
49 {
50     NMEM nmem = nmem_create();
51     yaz_nano_srv_t p = nmem_malloc(nmem, sizeof(*p));
52     size_t i;
53     for (i = 0; listeners_str[i]; i++)
54         ;
55     p->nmem = nmem;
56     p->num_listeners = i;
57     p->cs_listeners = 
58         nmem_malloc(nmem, p->num_listeners * sizeof(*p->cs_listeners));
59     for (i = 0; i < p->num_listeners; i++)
60     {
61         void *ap;
62         const char *where = listeners_str[i];
63         COMSTACK l = cs_create_host(where, 2, &ap);
64         p->cs_listeners[i] = 0; /* not OK (yet) */
65         if (!l)
66         {
67             yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_create_host(%s) failed", where);
68         }
69         else
70         {
71             if (cs_bind(l, ap, CS_SERVER) < 0)
72             {
73                 if (cs_errno(l) == CSYSERR)
74                     yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to bind to %s", where);
75                 else
76                     yaz_log(YLOG_FATAL, "Failed to bind to %s: %s", where,
77                             cs_strerror(l));
78                 cs_close(l);
79             }
80             else
81                 p->cs_listeners[i] = l; /* success */
82         }
83     }
84     p->sock_man = yaz_sock_man_new();
85
86     /* check if all are OK */
87     for (i = 0; i < p->num_listeners; i++)
88         if (!p->cs_listeners[i])
89         {
90             yaz_nano_srv_destroy(p);
91             return 0;
92         }
93
94     for (i = 0; i < p->num_listeners; i++)
95     {
96         yaz_sock_chan_t chan;
97
98         chan = yaz_sock_chan_new(p->sock_man, cs_fileno(p->cs_listeners[i]),
99                                  p->cs_listeners + i,
100                                  yaz_poll_read | yaz_poll_except);
101     }    
102     return p;
103 }
104
105 Z_GDU *yaz_nano_pkg_req(yaz_nano_pkg_t pkg)
106 {
107     return pkg->request_gdu;
108 }
109
110 Z_GDU *yaz_nano_pkg_response(yaz_nano_pkg_t pkg)
111 {
112     return pkg->response_gdu;
113 }
114
115 ODR yaz_nano_pkg_encode(yaz_nano_pkg_t pkg)
116 {
117     return pkg->encode_odr;
118 }
119
120 int yaz_nano_pkg_listener_id(yaz_nano_pkg_t pkg)
121 {
122     return pkg->listener_id;
123 }
124
125 yaz_nano_pkg_t yaz_nano_srv_get_pkg(yaz_nano_srv_t p)
126 {
127     return 0;
128 }
129
130 void yaz_nano_srv_put_pkg(yaz_nano_srv_t p, yaz_nano_pkg_t pkg)
131 {
132
133 }
134
135 /*
136  * Local variables:
137  * c-basic-offset: 4
138  * c-file-style: "Stroustrup"
139  * indent-tabs-mode: nil
140  * End:
141  * vim: shiftwidth=4 tabstop=8 expandtab
142  */
143