2 Copyright (C) 2010 by Ronnie Sahlberg <ronniesahlberg@gmail.com>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "aros_compat.h"
26 #include "win32_compat.h"
46 #include "libnfs-zdr.h"
48 #include "libnfs-raw.h"
49 #include "libnfs-private.h"
51 struct rpc_context
*rpc_init_context(void)
53 struct rpc_context
*rpc
;
54 static uint32_t salt
= 0;
57 rpc
= malloc(sizeof(struct rpc_context
));
61 memset(rpc
, 0, sizeof(struct rpc_context
));
63 rpc
->magic
= RPC_CONTEXT_MAGIC
;
65 /* Allow 1M of data (for writes) and some */
66 rpc
->encodebuflen
= 1024 * 1024 + 4096;
67 rpc
->encodebuf
= malloc(rpc
->encodebuflen
);
68 if (rpc
->encodebuf
== NULL
) {
73 rpc
->auth
= authunix_create_default();
74 if (rpc
->auth
== NULL
) {
79 rpc
->xid
= salt
+ time(NULL
) + getpid() << 16;
82 rpc
->tcp_syncnt
= RPC_PARAM_UNDEFINED
;
83 #if defined(WIN32) || defined(ANDROID)
90 rpc_reset_queue(&rpc
->outqueue
);
91 for (i
= 0; i
< HASHES
; i
++)
92 rpc_reset_queue(&rpc
->waitpdu
[i
]);
97 void rpc_set_readahead(struct rpc_context
*rpc
, uint32_t v
)
99 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
104 struct rpc_context
*rpc_init_udp_context(void)
106 struct rpc_context
*rpc
;
108 rpc
= rpc_init_context();
116 void rpc_set_auth(struct rpc_context
*rpc
, struct AUTH
*auth
)
118 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
120 if (rpc
->auth
!= NULL
) {
121 auth_destroy(rpc
->auth
);
126 static void rpc_set_uid_gid(struct rpc_context
*rpc
, int uid
, int gid
) {
127 if (uid
!= rpc
->uid
|| gid
!= rpc
->gid
) {
128 struct AUTH
*auth
= libnfs_authunix_create("libnfs", uid
, gid
, 0, NULL
);
130 rpc_set_auth(rpc
, auth
);
137 void rpc_set_uid(struct rpc_context
*rpc
, int uid
) {
138 rpc_set_uid_gid(rpc
, uid
, rpc
->gid
);
141 void rpc_set_gid(struct rpc_context
*rpc
, int gid
) {
142 rpc_set_uid_gid(rpc
, rpc
->uid
, gid
);
145 void rpc_set_error(struct rpc_context
*rpc
, char *error_string
, ...)
148 char *old_error_string
= rpc
->error_string
;
150 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
152 va_start(ap
, error_string
);
153 rpc
->error_string
= malloc(1024);
154 vsnprintf(rpc
->error_string
, 1024, error_string
, ap
);
157 if (old_error_string
!= NULL
) {
158 free(old_error_string
);
162 char *rpc_get_error(struct rpc_context
*rpc
)
164 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
166 return rpc
->error_string
;
169 void rpc_error_all_pdus(struct rpc_context
*rpc
, char *error
)
171 struct rpc_pdu
*pdu
, *next
;
174 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
176 while ((pdu
= rpc
->outqueue
.head
) != NULL
) {
177 pdu
->cb(rpc
, RPC_STATUS_ERROR
, error
, pdu
->private_data
);
178 rpc
->outqueue
.head
= pdu
->next
;
179 rpc_free_pdu(rpc
, pdu
);
181 rpc
->outqueue
.tail
= NULL
;
183 for (i
= 0; i
< HASHES
; i
++) {
184 struct rpc_queue
*q
= &rpc
->waitpdu
[i
];
186 while((pdu
= q
->head
) != NULL
) {
187 pdu
->cb(rpc
, RPC_STATUS_ERROR
, error
, pdu
->private_data
);
189 rpc_free_pdu(rpc
, pdu
);
195 static void rpc_free_fragment(struct rpc_fragment
*fragment
)
197 if (fragment
->data
!= NULL
) {
198 free(fragment
->data
);
203 void rpc_free_all_fragments(struct rpc_context
*rpc
)
205 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
207 while (rpc
->fragments
!= NULL
) {
208 struct rpc_fragment
*fragment
= rpc
->fragments
;
210 rpc
->fragments
= fragment
->next
;
211 rpc_free_fragment(fragment
);
215 int rpc_add_fragment(struct rpc_context
*rpc
, char *data
, uint64_t size
)
217 struct rpc_fragment
*fragment
;
219 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
221 fragment
= malloc(sizeof(struct rpc_fragment
));
222 if (fragment
== NULL
) {
226 fragment
->size
= size
;
227 fragment
->data
= malloc(fragment
->size
);
228 if(fragment
->data
== NULL
) {
233 memcpy(fragment
->data
, data
, fragment
->size
);
234 LIBNFS_LIST_ADD_END(&rpc
->fragments
, fragment
);
238 void rpc_destroy_context(struct rpc_context
*rpc
)
243 assert(rpc
->magic
== RPC_CONTEXT_MAGIC
);
245 while((pdu
= rpc
->outqueue
.head
) != NULL
) {
246 pdu
->cb(rpc
, RPC_STATUS_CANCEL
, NULL
, pdu
->private_data
);
247 LIBNFS_LIST_REMOVE(&rpc
->outqueue
.head
, pdu
);
248 rpc_free_pdu(rpc
, pdu
);
251 for (i
= 0; i
< HASHES
; i
++) {
252 struct rpc_queue
*q
= &rpc
->waitpdu
[i
];
254 while((pdu
= q
->head
) != NULL
) {
255 pdu
->cb(rpc
, RPC_STATUS_CANCEL
, NULL
, pdu
->private_data
);
256 LIBNFS_LIST_REMOVE(&q
->head
, pdu
);
257 rpc_free_pdu(rpc
, pdu
);
261 rpc_free_all_fragments(rpc
);
263 auth_destroy(rpc
->auth
);
270 if (rpc
->encodebuf
!= NULL
) {
271 free(rpc
->encodebuf
);
272 rpc
->encodebuf
= NULL
;
275 if (rpc
->error_string
!= NULL
) {
276 free(rpc
->error_string
);
277 rpc
->error_string
= NULL
;
280 if (rpc
->udp_dest
!= NULL
) {
282 rpc
->udp_dest
= NULL
;