ecfdcf58ad9d0c8551ec13eb1c1d8586383f81e0
[deb_libnfs.git] / lib / init.c
1 /*
2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
3
4
5
6 This program is distributed in the hope that it will be useful,
7 but WITHOUT ANY WARRANTY; without even the implied warranty of
8 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 GNU Lesser General Public License for more details.
10
11 You should have received a copy of the GNU Lesser General Public License
12 along with this program; if not, see <http://www.gnu.org/licenses/>.
13 */
14
15 #ifdef WIN32
16 #include "win32_compat.h"
17 #define close closesocket
18 #else
19 #include <unistd.h>
20 #include <strings.h>
21 #endif/*WIN32*/
22 #define _GNU_SOURCE
23
24 #include <stdio.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <assert.h>
29 #include <time.h>
30 #include "slist.h"
31 #include "libnfs-zdr.h"
32 #include "libnfs.h"
33 #include "libnfs-raw.h"
34 #include "libnfs-private.h"
35
36 #ifdef AROS
37 #include "aros_compat.h"
38 #endif
39
40 struct rpc_context *rpc_init_context(void)
41 {
42 struct rpc_context *rpc;
43 static uint32_t salt = 0;
44
45 rpc = malloc(sizeof(struct rpc_context));
46 if (rpc == NULL) {
47 return NULL;
48 }
49 memset(rpc, 0, sizeof(struct rpc_context));
50
51 rpc->magic = RPC_CONTEXT_MAGIC;
52 rpc->encodebuflen = 65536;
53 rpc->encodebuf = malloc(rpc->encodebuflen);
54 if (rpc->encodebuf == NULL) {
55 free(rpc);
56 return NULL;
57 }
58
59 #if defined(WIN32)
60 rpc->auth = authunix_create("LibNFS", 65535, 65535, 0, NULL);
61 #else
62 rpc->auth = authunix_create_default();
63 #endif
64 if (rpc->auth == NULL) {
65 free(rpc->encodebuf);
66 free(rpc);
67 return NULL;
68 }
69 rpc->xid = salt + time(NULL);
70 salt += 0x01000000;
71 rpc->fd = -1;
72
73 return rpc;
74 }
75
76
77 struct rpc_context *rpc_init_udp_context(void)
78 {
79 struct rpc_context *rpc;
80
81 rpc = rpc_init_context();
82 if (rpc != NULL) {
83 rpc->is_udp = 1;
84 }
85
86 return rpc;
87 }
88
89 void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth)
90 {
91 assert(rpc->magic == RPC_CONTEXT_MAGIC);
92
93 if (rpc->auth != NULL) {
94 auth_destroy(rpc->auth);
95 }
96 rpc->auth = auth;
97 }
98
99
100 void rpc_set_error(struct rpc_context *rpc, char *error_string, ...)
101 {
102 va_list ap;
103
104 assert(rpc->magic == RPC_CONTEXT_MAGIC);
105
106 if (rpc->error_string != NULL) {
107 free(rpc->error_string);
108 }
109 va_start(ap, error_string);
110 rpc->error_string = malloc(1024);
111 vsnprintf(rpc->error_string, 1024, error_string, ap);
112 va_end(ap);
113 }
114
115 char *rpc_get_error(struct rpc_context *rpc)
116 {
117 assert(rpc->magic == RPC_CONTEXT_MAGIC);
118
119 return rpc->error_string;
120 }
121
122 void rpc_error_all_pdus(struct rpc_context *rpc, char *error)
123 {
124 struct rpc_pdu *pdu;
125
126 assert(rpc->magic == RPC_CONTEXT_MAGIC);
127
128 while((pdu = rpc->outqueue) != NULL) {
129 pdu->cb(rpc, RPC_STATUS_ERROR, error, pdu->private_data);
130 SLIST_REMOVE(&rpc->outqueue, pdu);
131 rpc_free_pdu(rpc, pdu);
132 }
133 while((pdu = rpc->waitpdu) != NULL) {
134 pdu->cb(rpc, RPC_STATUS_ERROR, error, pdu->private_data);
135 SLIST_REMOVE(&rpc->waitpdu, pdu);
136 rpc_free_pdu(rpc, pdu);
137 }
138 }
139
140 static void rpc_free_fragment(struct rpc_fragment *fragment)
141 {
142 if (fragment->data != NULL) {
143 free(fragment->data);
144 }
145 free(fragment);
146 }
147
148 void rpc_free_all_fragments(struct rpc_context *rpc)
149 {
150 assert(rpc->magic == RPC_CONTEXT_MAGIC);
151
152 while (rpc->fragments != NULL) {
153 struct rpc_fragment *fragment = rpc->fragments;
154
155 SLIST_REMOVE(&rpc->fragments, fragment);
156 rpc_free_fragment(fragment);
157 }
158 }
159
160 int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size)
161 {
162 struct rpc_fragment *fragment;
163
164 assert(rpc->magic == RPC_CONTEXT_MAGIC);
165
166 fragment = malloc(sizeof(struct rpc_fragment));
167 if (fragment == NULL) {
168 return -1;
169 }
170
171 fragment->size = size;
172 fragment->data = malloc(fragment->size);
173 if(fragment->data == NULL) {
174 free(fragment);
175 return -1;
176 }
177
178 memcpy(fragment->data, data, fragment->size);
179 SLIST_ADD_END(&rpc->fragments, fragment);
180 return 0;
181 }
182
183 void rpc_destroy_context(struct rpc_context *rpc)
184 {
185 struct rpc_pdu *pdu;
186
187 assert(rpc->magic == RPC_CONTEXT_MAGIC);
188
189 while((pdu = rpc->outqueue) != NULL) {
190 pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
191 SLIST_REMOVE(&rpc->outqueue, pdu);
192 rpc_free_pdu(rpc, pdu);
193 }
194 while((pdu = rpc->waitpdu) != NULL) {
195 pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data);
196 SLIST_REMOVE(&rpc->waitpdu, pdu);
197 rpc_free_pdu(rpc, pdu);
198 }
199
200 rpc_free_all_fragments(rpc);
201
202 auth_destroy(rpc->auth);
203 rpc->auth =NULL;
204
205 if (rpc->fd != -1) {
206 close(rpc->fd);
207 }
208
209 if (rpc->encodebuf != NULL) {
210 free(rpc->encodebuf);
211 rpc->encodebuf = NULL;
212 }
213
214 if (rpc->error_string != NULL) {
215 free(rpc->error_string);
216 rpc->error_string = NULL;
217 }
218
219 if (rpc->udp_dest != NULL) {
220 free(rpc->udp_dest);
221 rpc->udp_dest = NULL;
222 }
223
224 rpc->magic = 0;
225 free(rpc);
226 }
227
228