Merge branch '1858_segfault_in_search'
[midnight-commander.git] / vfs / mcfsutil.c
blobd3c2e04507a4e4249794db7f1e95c00f82aef4c4
1 /* Low-level protocol for MCFS.
3 Copyright (C) 1995, 1996 Miguel de Icaza
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License
7 as published by the Free Software Foundation; either version 2 of
8 the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 /**
20 * \file
21 * \brief Source: Low-level protocol for MCFS
22 * \author Miguel de Icaza
23 * \date 1995, 1996
26 #include <config.h>
28 #ifdef ENABLE_VFS_MCFS
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <signal.h>
34 #include <pwd.h>
35 #include <sys/types.h>
36 #include <netdb.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #ifdef HAVE_ARPA_INET_H
40 #include <arpa/inet.h>
41 #endif
43 #ifdef HAVE_PMAP_SET
44 #include <rpc/rpc.h>
45 #include <rpc/pmap_prot.h>
46 #ifdef HAVE_RPC_PMAP_CLNT_H
47 #include <rpc/pmap_clnt.h>
48 #endif
49 #endif
51 #include <errno.h>
53 #include "../src/global.h"
54 #include "../src/wtools.h" /* message() */
55 #include "../src/main.h" /* print_vfs_message */
56 #include "utilvfs.h"
57 #include "mcfsutil.h"
58 #include "tcputil.h"
59 #include "mcfs.h" /* tcp_invalidate_socket() */
61 #define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
62 { tcp_invalidate_socket (sock); return got_sigpipe = 0; }
64 /* Reads a block on dest for len bytes from sock */
65 /* Returns a boolean indicating the success status */
66 int
67 socket_read_block (int sock, char *dest, int len)
69 int nread, n;
71 for (nread = 0; nread < len;) {
72 n = read (sock, dest + nread, len - nread);
73 if (n <= 0) {
74 tcp_invalidate_socket (sock);
75 return 0;
77 nread += n;
79 return 1;
82 int
83 socket_write_block (int sock, const char *buffer, int len)
85 int left, status;
87 for (left = len; left > 0;) {
88 status = write (sock, buffer, left);
89 CHECK_SIG_PIPE (sock);
90 if (status < 0)
91 return 0;
92 left -= status;
93 buffer += status;
95 return 1;
98 int
99 rpc_send (int sock, ...)
101 long int tmp, len, cmd;
102 char *text;
103 va_list ap;
105 va_start (ap, sock);
107 for (;;) {
108 cmd = va_arg (ap, int);
109 switch (cmd) {
110 case RPC_END:
111 va_end (ap);
112 return 1;
114 case RPC_INT:
115 tmp = htonl (va_arg (ap, int));
116 write (sock, &tmp, sizeof (tmp));
117 CHECK_SIG_PIPE (sock);
118 break;
120 case RPC_STRING:
121 text = va_arg (ap, char *);
122 len = strlen (text);
123 tmp = htonl (len);
124 write (sock, &tmp, sizeof (tmp));
125 CHECK_SIG_PIPE (sock);
126 write (sock, text, len);
127 CHECK_SIG_PIPE (sock);
128 break;
130 case RPC_BLOCK:
131 len = va_arg (ap, int);
132 text = va_arg (ap, char *);
133 tmp = htonl (len);
134 write (sock, text, len);
135 CHECK_SIG_PIPE (sock);
136 break;
138 default:
139 vfs_die ("Unknown rpc message\n");
145 rpc_get (int sock, ...)
147 long int tmp, len;
148 char *text, **str_dest;
149 int *dest, cmd;
150 va_list ap;
152 va_start (ap, sock);
154 for (;;) {
155 cmd = va_arg (ap, int);
156 switch (cmd) {
157 case RPC_END:
158 va_end (ap);
159 return 1;
161 case RPC_INT:
162 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
163 va_end (ap);
164 return 0;
166 dest = va_arg (ap, int *);
167 *dest = ntohl (tmp);
168 break;
170 /* returns an allocated string */
171 case RPC_LIMITED_STRING:
172 case RPC_STRING:
173 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
174 va_end (ap);
175 return 0;
177 len = ntohl (tmp);
178 if (cmd == RPC_LIMITED_STRING)
179 if (len > 16 * 1024) {
180 /* silently die */
181 abort ();
183 if (len > 128 * 1024)
184 abort ();
186 /* Don't use glib functions here - this code is used by mcserv */
187 text = malloc (len + 1);
188 if (socket_read_block (sock, text, len) == 0) {
189 free (text);
190 va_end (ap);
191 return 0;
193 text[len] = '\0';
195 str_dest = va_arg (ap, char **);
196 *str_dest = text;
197 break;
199 case RPC_BLOCK:
200 len = va_arg (ap, int);
201 text = va_arg (ap, char *);
202 if (socket_read_block (sock, text, len) == 0) {
203 va_end (ap);
204 return 0;
206 break;
208 default:
209 vfs_die ("Unknown rpc message\n");
213 #endif /* ENABLE_VFS_MCFS */