Corrected Changelog entries for ri-gcc-warnings.m4
[midnight-commander.git] / vfs / mcfsutil.c
blobb64ea39219a66a1f27a7c8175ccf76f9e133430d
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19 #include <config.h>
21 #ifdef WITH_MCFS
22 #include <unistd.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <signal.h>
27 #include <pwd.h>
28 #include <sys/types.h>
29 #include <netdb.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #ifdef HAVE_ARPA_INET_H
33 #include <arpa/inet.h>
34 #endif
36 #ifdef HAVE_PMAP_SET
37 #include <rpc/rpc.h>
38 #include <rpc/pmap_prot.h>
39 #ifdef HAVE_RPC_PMAP_CLNT_H
40 #include <rpc/pmap_clnt.h>
41 #endif
42 #endif
44 #include <errno.h>
46 #include "mcfsutil.h"
47 #include "tcputil.h"
48 #include "utilvfs.h"
49 #include "mcfs.h" /* tcp_invalidate_socket() */
51 #define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
52 { tcp_invalidate_socket (sock); return got_sigpipe = 0; }
54 /* Reads a block on dest for len bytes from sock */
55 /* Returns a boolean indicating the success status */
56 int
57 socket_read_block (int sock, char *dest, int len)
59 int nread, n;
61 for (nread = 0; nread < len;) {
62 n = read (sock, dest + nread, len - nread);
63 if (n <= 0) {
64 tcp_invalidate_socket (sock);
65 return 0;
67 nread += n;
69 return 1;
72 int
73 socket_write_block (int sock, char *buffer, int len)
75 int left, status;
77 for (left = len; left > 0;) {
78 status = write (sock, buffer, left);
79 CHECK_SIG_PIPE (sock);
80 if (status < 0)
81 return 0;
82 left -= status;
83 buffer += status;
85 return 1;
88 int
89 rpc_send (int sock, ...)
91 long int tmp, len, cmd;
92 char *text;
93 va_list ap;
95 va_start (ap, sock);
97 for (;;) {
98 cmd = va_arg (ap, int);
99 switch (cmd) {
100 case RPC_END:
101 va_end (ap);
102 return 1;
104 case RPC_INT:
105 tmp = htonl (va_arg (ap, int));
106 write (sock, &tmp, sizeof (tmp));
107 CHECK_SIG_PIPE (sock);
108 break;
110 case RPC_STRING:
111 text = va_arg (ap, char *);
112 len = strlen (text);
113 tmp = htonl (len);
114 write (sock, &tmp, sizeof (tmp));
115 CHECK_SIG_PIPE (sock);
116 write (sock, text, len);
117 CHECK_SIG_PIPE (sock);
118 break;
120 case RPC_BLOCK:
121 len = va_arg (ap, int);
122 text = va_arg (ap, char *);
123 tmp = htonl (len);
124 write (sock, text, len);
125 CHECK_SIG_PIPE (sock);
126 break;
128 default:
129 vfs_die ("Unknown rpc message\n");
135 rpc_get (int sock, ...)
137 long int tmp, len;
138 char *text, **str_dest;
139 int *dest, cmd;
140 va_list ap;
142 va_start (ap, sock);
144 for (;;) {
145 cmd = va_arg (ap, int);
146 switch (cmd) {
147 case RPC_END:
148 va_end (ap);
149 return 1;
151 case RPC_INT:
152 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
153 va_end (ap);
154 return 0;
156 dest = va_arg (ap, int *);
157 *dest = ntohl (tmp);
158 break;
160 /* returns an allocated string */
161 case RPC_LIMITED_STRING:
162 case RPC_STRING:
163 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
164 va_end (ap);
165 return 0;
167 len = ntohl (tmp);
168 if (cmd == RPC_LIMITED_STRING)
169 if (len > 16 * 1024) {
170 /* silently die */
171 abort ();
173 if (len > 128 * 1024)
174 abort ();
176 /* Don't use glib functions here - this code is used by mcserv */
177 text = malloc (len + 1);
178 if (socket_read_block (sock, text, len) == 0) {
179 free (text);
180 va_end (ap);
181 return 0;
183 text[len] = '\0';
185 str_dest = va_arg (ap, char **);
186 *str_dest = text;
187 break;
189 case RPC_BLOCK:
190 len = va_arg (ap, int);
191 text = va_arg (ap, char *);
192 if (socket_read_block (sock, text, len) == 0) {
193 va_end (ap);
194 return 0;
196 break;
198 default:
199 vfs_die ("Unknown rpc message\n");
203 #endif /* WITH_MCFS */