Add $ and ` for escaping and reorder it according to the ascii values
[midnight-commander.git] / vfs / mcfsutil.c
blobdd753f7cb75f8b48c3b1654bfd406638edfb7922
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 #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 "../src/global.h"
47 #include "../src/tty.h" /* enable/disable interrupt key */
48 #include "../src/wtools.h" /* message() */
49 #include "../src/main.h" /* print_vfs_message */
50 #include "utilvfs.h"
51 #include "mcfsutil.h"
52 #include "tcputil.h"
53 #include "mcfs.h" /* tcp_invalidate_socket() */
55 #define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
56 { tcp_invalidate_socket (sock); return got_sigpipe = 0; }
58 /* Reads a block on dest for len bytes from sock */
59 /* Returns a boolean indicating the success status */
60 int
61 socket_read_block (int sock, char *dest, int len)
63 int nread, n;
65 for (nread = 0; nread < len;) {
66 n = read (sock, dest + nread, len - nread);
67 if (n <= 0) {
68 tcp_invalidate_socket (sock);
69 return 0;
71 nread += n;
73 return 1;
76 int
77 socket_write_block (int sock, const char *buffer, int len)
79 int left, status;
81 for (left = len; left > 0;) {
82 status = write (sock, buffer, left);
83 CHECK_SIG_PIPE (sock);
84 if (status < 0)
85 return 0;
86 left -= status;
87 buffer += status;
89 return 1;
92 int
93 rpc_send (int sock, ...)
95 long int tmp, len, cmd;
96 char *text;
97 va_list ap;
99 va_start (ap, sock);
101 for (;;) {
102 cmd = va_arg (ap, int);
103 switch (cmd) {
104 case RPC_END:
105 va_end (ap);
106 return 1;
108 case RPC_INT:
109 tmp = htonl (va_arg (ap, int));
110 write (sock, &tmp, sizeof (tmp));
111 CHECK_SIG_PIPE (sock);
112 break;
114 case RPC_STRING:
115 text = va_arg (ap, char *);
116 len = strlen (text);
117 tmp = htonl (len);
118 write (sock, &tmp, sizeof (tmp));
119 CHECK_SIG_PIPE (sock);
120 write (sock, text, len);
121 CHECK_SIG_PIPE (sock);
122 break;
124 case RPC_BLOCK:
125 len = va_arg (ap, int);
126 text = va_arg (ap, char *);
127 tmp = htonl (len);
128 write (sock, text, len);
129 CHECK_SIG_PIPE (sock);
130 break;
132 default:
133 vfs_die ("Unknown rpc message\n");
139 rpc_get (int sock, ...)
141 long int tmp, len;
142 char *text, **str_dest;
143 int *dest, cmd;
144 va_list ap;
146 va_start (ap, sock);
148 for (;;) {
149 cmd = va_arg (ap, int);
150 switch (cmd) {
151 case RPC_END:
152 va_end (ap);
153 return 1;
155 case RPC_INT:
156 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
157 va_end (ap);
158 return 0;
160 dest = va_arg (ap, int *);
161 *dest = ntohl (tmp);
162 break;
164 /* returns an allocated string */
165 case RPC_LIMITED_STRING:
166 case RPC_STRING:
167 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
168 va_end (ap);
169 return 0;
171 len = ntohl (tmp);
172 if (cmd == RPC_LIMITED_STRING)
173 if (len > 16 * 1024) {
174 /* silently die */
175 abort ();
177 if (len > 128 * 1024)
178 abort ();
180 /* Don't use glib functions here - this code is used by mcserv */
181 text = malloc (len + 1);
182 if (socket_read_block (sock, text, len) == 0) {
183 free (text);
184 va_end (ap);
185 return 0;
187 text[len] = '\0';
189 str_dest = va_arg (ap, char **);
190 *str_dest = text;
191 break;
193 case RPC_BLOCK:
194 len = va_arg (ap, int);
195 text = va_arg (ap, char *);
196 if (socket_read_block (sock, text, len) == 0) {
197 va_end (ap);
198 return 0;
200 break;
202 default:
203 vfs_die ("Unknown rpc message\n");
207 #endif /* WITH_MCFS */