mc.sh & mc.csh creation fixed...
[midnight-commander.git] / vfs / mcfsutil.c
blob8961e7fe6c94d4208303745ada6311686b1a23db
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"
50 #define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
51 { tcp_invalidate_socket (sock); return got_sigpipe = 0; }
53 extern void tcp_invalidate_socket (int);
54 extern void vfs_die (char *);
56 /* Reads a block on dest for len bytes from sock */
57 /* Returns a boolean indicating the success status */
58 int
59 socket_read_block (int sock, char *dest, int len)
61 int nread, n;
63 for (nread = 0; nread < len;) {
64 n = read (sock, dest + nread, len - nread);
65 if (n <= 0) {
66 tcp_invalidate_socket (sock);
67 return 0;
69 nread += n;
71 return 1;
74 int
75 socket_write_block (int sock, char *buffer, int len)
77 int left, status;
79 for (left = len; left > 0;) {
80 status = write (sock, buffer, left);
81 CHECK_SIG_PIPE (sock);
82 if (status < 0)
83 return 0;
84 left -= status;
85 buffer += status;
87 return 1;
90 int
91 rpc_send (int sock, ...)
93 long int tmp, len, cmd;
94 char *text;
95 va_list ap;
97 va_start (ap, sock);
99 for (;;) {
100 cmd = va_arg (ap, int);
101 switch (cmd) {
102 case RPC_END:
103 va_end (ap);
104 return 1;
106 case RPC_INT:
107 tmp = htonl (va_arg (ap, int));
108 write (sock, &tmp, sizeof (tmp));
109 CHECK_SIG_PIPE (sock);
110 break;
112 case RPC_STRING:
113 text = va_arg (ap, char *);
114 len = strlen (text);
115 tmp = htonl (len);
116 write (sock, &tmp, sizeof (tmp));
117 CHECK_SIG_PIPE (sock);
118 write (sock, text, len);
119 CHECK_SIG_PIPE (sock);
120 break;
122 case RPC_BLOCK:
123 len = va_arg (ap, int);
124 text = va_arg (ap, char *);
125 tmp = htonl (len);
126 write (sock, text, len);
127 CHECK_SIG_PIPE (sock);
128 break;
130 default:
131 vfs_die ("Unknown rpc message\n");
137 rpc_get (int sock, ...)
139 long int tmp, len;
140 char *text, **str_dest;
141 int *dest, cmd;
142 va_list ap;
144 va_start (ap, sock);
146 for (;;) {
147 cmd = va_arg (ap, int);
148 switch (cmd) {
149 case RPC_END:
150 va_end (ap);
151 return 1;
153 case RPC_INT:
154 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
155 va_end (ap);
156 return 0;
158 dest = va_arg (ap, int *);
159 *dest = ntohl (tmp);
160 break;
162 /* returns an allocated string */
163 case RPC_LIMITED_STRING:
164 case RPC_STRING:
165 if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
166 va_end (ap);
167 return 0;
169 len = ntohl (tmp);
170 if (cmd == RPC_LIMITED_STRING)
171 if (len > 16 * 1024) {
172 /* silently die */
173 abort ();
175 if (len > 128 * 1024)
176 abort ();
178 /* Don't use glib functions here - this code is used by mcserv */
179 text = malloc (len + 1);
180 if (socket_read_block (sock, text, len) == 0) {
181 free (text);
182 va_end (ap);
183 return 0;
185 text[len] = '\0';
187 str_dest = va_arg (ap, char **);
188 *str_dest = text;
189 break;
191 case RPC_BLOCK:
192 len = va_arg (ap, int);
193 text = va_arg (ap, char *);
194 if (socket_read_block (sock, text, len) == 0) {
195 va_end (ap);
196 return 0;
198 break;
200 default:
201 vfs_die ("Unknown rpc message\n");
205 #endif /* WITH_MCFS */