Use `errno_t` in all uspace and kernel code.
[helenos.git] / uspace / lib / c / generic / dnsr.c
blob60cb55d42ff18cc64003f0434ba7d0856fe1bd6b
1 /*
2 * Copyright (c) 2013 Jiri Svoboda
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include <async.h>
30 #include <assert.h>
31 #include <errno.h>
32 #include <fibril_synch.h>
33 #include <inet/dnsr.h>
34 #include <ipc/dnsr.h>
35 #include <ipc/services.h>
36 #include <loc.h>
37 #include <stdlib.h>
38 #include <str.h>
40 static FIBRIL_MUTEX_INITIALIZE(dnsr_sess_mutex);
42 static async_sess_t *dnsr_sess = NULL;
44 static async_exch_t *dnsr_exchange_begin(void)
46 fibril_mutex_lock(&dnsr_sess_mutex);
48 if (dnsr_sess == NULL) {
49 service_id_t dnsr_svc;
51 (void) loc_service_get_id(SERVICE_NAME_DNSR, &dnsr_svc,
52 IPC_FLAG_BLOCKING);
54 dnsr_sess = loc_service_connect(dnsr_svc, INTERFACE_DNSR,
55 IPC_FLAG_BLOCKING);
58 async_sess_t *sess = dnsr_sess;
59 fibril_mutex_unlock(&dnsr_sess_mutex);
61 return async_exchange_begin(sess);
64 static void dnsr_exchange_end(async_exch_t *exch)
66 async_exchange_end(exch);
69 errno_t dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo, ip_ver_t ver)
71 async_exch_t *exch = dnsr_exchange_begin();
73 ipc_call_t answer;
74 aid_t req = async_send_1(exch, DNSR_NAME2HOST, (sysarg_t) ver,
75 &answer);
77 errno_t rc = async_data_write_start(exch, name, str_size(name));
78 if (rc != EOK) {
79 async_exchange_end(exch);
80 async_forget(req);
81 return rc;
84 dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
85 if (info == NULL)
86 return ENOMEM;
88 ipc_call_t answer_addr;
89 aid_t req_addr = async_data_read(exch, &info->addr,
90 sizeof(inet_addr_t), &answer_addr);
92 errno_t retval_addr;
93 async_wait_for(req_addr, &retval_addr);
95 if (retval_addr != EOK) {
96 async_exchange_end(exch);
97 async_forget(req);
98 free(info);
99 return retval_addr;
102 ipc_call_t answer_cname;
103 char cname_buf[DNSR_NAME_MAX_SIZE + 1];
104 aid_t req_cname = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
105 &answer_cname);
107 dnsr_exchange_end(exch);
109 errno_t retval_cname;
110 async_wait_for(req_cname, &retval_cname);
112 if (retval_cname != EOK) {
113 async_forget(req);
114 free(info);
115 return retval_cname;
118 errno_t retval;
119 async_wait_for(req, &retval);
121 if (retval != EOK) {
122 async_forget(req);
123 free(info);
124 return retval;
127 size_t act_size = IPC_GET_ARG2(answer_cname);
128 assert(act_size <= DNSR_NAME_MAX_SIZE);
130 cname_buf[act_size] = '\0';
132 info->cname = str_dup(cname_buf);
134 if (info->cname == NULL) {
135 free(info);
136 return ENOMEM;
139 *rinfo = info;
140 return EOK;
143 void dnsr_hostinfo_destroy(dnsr_hostinfo_t *info)
145 if (info == NULL)
146 return;
148 free(info->cname);
149 free(info);
152 errno_t dnsr_get_srvaddr(inet_addr_t *srvaddr)
154 async_exch_t *exch = dnsr_exchange_begin();
156 ipc_call_t answer;
157 aid_t req = async_send_0(exch, DNSR_GET_SRVADDR, &answer);
158 errno_t rc = async_data_read_start(exch, srvaddr, sizeof(inet_addr_t));
160 loc_exchange_end(exch);
162 if (rc != EOK) {
163 async_forget(req);
164 return rc;
167 errno_t retval;
168 async_wait_for(req, &retval);
170 return retval;
173 errno_t dnsr_set_srvaddr(inet_addr_t *srvaddr)
175 async_exch_t *exch = dnsr_exchange_begin();
177 ipc_call_t answer;
178 aid_t req = async_send_0(exch, DNSR_SET_SRVADDR, &answer);
179 errno_t rc = async_data_write_start(exch, srvaddr, sizeof(inet_addr_t));
181 loc_exchange_end(exch);
183 if (rc != EOK) {
184 async_forget(req);
185 return rc;
188 errno_t retval;
189 async_wait_for(req, &retval);
191 return retval;
194 /** @}