mirror of https://github.com/MidnightCommander/mc
* tcputil.c: Split mcfs-specific part to
* mcfsutil.c: ... this. * tcputil.h: Split mcfs-specific part to * mcfsutil.h: ... this. * Makefile.am: Add mcfsutil.c and mcfsutil.h. * mcserv.c: Define own got_sigpipe, which is always 0, since mcserv doesn't call tcp_init().
This commit is contained in:
parent
51a6434b44
commit
b5e7441d98
|
@ -1,5 +1,13 @@
|
|||
2002-10-04 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* tcputil.c: Split mcfs-specific part to
|
||||
* mcfsutil.c: ... this.
|
||||
* tcputil.h: Split mcfs-specific part to
|
||||
* mcfsutil.h: ... this.
|
||||
* Makefile.am: Add mcfsutil.c and mcfsutil.h.
|
||||
* mcserv.c: Define own got_sigpipe, which is always 0, since
|
||||
mcserv doesn't call tcp_init().
|
||||
|
||||
* Makefile.am: Don't link mcserv with glib. It's unreasonable
|
||||
to require a glib port for embedded systems mcserv may run on.
|
||||
* mcserv.c: Replace all glib calls with standard libc calls.
|
||||
|
|
|
@ -28,6 +28,7 @@ VFSHDRS = \
|
|||
ftpfs.h \
|
||||
local.h \
|
||||
mcfs.h \
|
||||
mcfsutil.h \
|
||||
names.h \
|
||||
smbfs.h \
|
||||
tar.h \
|
||||
|
@ -46,7 +47,8 @@ if USE_UNDEL_FS
|
|||
UNDEL_FILES = $(UNDELFILES)
|
||||
endif
|
||||
|
||||
NETFILES = tcputil.c fish.c ftpfs.c mcfs.c utilvfs.c $(SMB_NETFILES)
|
||||
NETFILES = tcputil.c fish.c ftpfs.c mcfs.c mcfsutil.c utilvfs.c \
|
||||
$(SMB_NETFILES)
|
||||
|
||||
NONETFILES = $(BASICFILES) $(UNDEL_FILES)
|
||||
|
||||
|
@ -95,7 +97,7 @@ if USE_MCFS
|
|||
sbin_PROGRAMS = mcserv
|
||||
endif
|
||||
|
||||
mcserv_SOURCES = mcserv.c tcputil.c
|
||||
mcserv_SOURCES = mcserv.c mcfsutil.c
|
||||
|
||||
mcserv_LDADD = $(PAMLIBS) $(LCRYPT)
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
#include "vfs.h"
|
||||
#include "mcfs.h"
|
||||
#include "mcfsutil.h"
|
||||
#include "tcputil.h"
|
||||
#include "../src/dialog.h"
|
||||
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
/* Low-level protocol for MCFS.
|
||||
|
||||
Copyright (C) 1995, 1996 Miguel de Icaza
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License
|
||||
as published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef WITH_MCFS
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PMAP_SET
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#ifdef HAVE_RPC_PMAP_CLNT_H
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "mcfsutil.h"
|
||||
#include "tcputil.h"
|
||||
#include "utilvfs.h"
|
||||
|
||||
#define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
|
||||
{ tcp_invalidate_socket (sock); return got_sigpipe = 0; }
|
||||
|
||||
extern void tcp_invalidate_socket (int);
|
||||
extern void vfs_die (char *);
|
||||
|
||||
/* Reads a block on dest for len bytes from sock */
|
||||
/* Returns a boolean indicating the success status */
|
||||
int
|
||||
socket_read_block (int sock, char *dest, int len)
|
||||
{
|
||||
int nread, n;
|
||||
|
||||
for (nread = 0; nread < len;) {
|
||||
n = read (sock, dest + nread, len - nread);
|
||||
if (n <= 0) {
|
||||
tcp_invalidate_socket (sock);
|
||||
return 0;
|
||||
}
|
||||
nread += n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
socket_write_block (int sock, char *buffer, int len)
|
||||
{
|
||||
int left, status;
|
||||
|
||||
for (left = len; left > 0;) {
|
||||
status = write (sock, buffer, left);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
if (status < 0)
|
||||
return 0;
|
||||
left -= status;
|
||||
buffer += status;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rpc_send (int sock, ...)
|
||||
{
|
||||
long int tmp, len, cmd;
|
||||
char *text;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
tmp = htonl (va_arg (ap, int));
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_STRING:
|
||||
text = va_arg (ap, char *);
|
||||
len = strlen (text);
|
||||
tmp = htonl (len);
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
tmp = htonl (len);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rpc_get (int sock, ...)
|
||||
{
|
||||
long int tmp, len;
|
||||
char *text, **str_dest;
|
||||
int *dest, cmd;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
dest = va_arg (ap, int *);
|
||||
*dest = ntohl (tmp);
|
||||
break;
|
||||
|
||||
/* returns an allocated string */
|
||||
case RPC_LIMITED_STRING:
|
||||
case RPC_STRING:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
len = ntohl (tmp);
|
||||
if (cmd == RPC_LIMITED_STRING)
|
||||
if (len > 16 * 1024) {
|
||||
/* silently die */
|
||||
abort ();
|
||||
}
|
||||
if (len > 128 * 1024)
|
||||
abort ();
|
||||
|
||||
/* Don't use glib functions here - this code is used by mcserv */
|
||||
text = malloc (len + 1);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
free (text);
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
text[len] = '\0';
|
||||
|
||||
str_dest = va_arg (ap, char **);
|
||||
*str_dest = text;
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_MCFS */
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef __MCFSUTIL_H
|
||||
#define __MCFSUTIL_H
|
||||
|
||||
/* Operations of the RPC manager */
|
||||
|
||||
/*
|
||||
* Please note that the RPC manager uses 4-byte integers for the
|
||||
* communication - may be a problem on systems with longer pointers.
|
||||
*/
|
||||
|
||||
enum {
|
||||
RPC_END, /* End of RPC commands */
|
||||
RPC_INT, /* Next argument is integer */
|
||||
RPC_STRING, /* Next argument is a string */
|
||||
RPC_BLOCK, /* Next argument is a len/block */
|
||||
RPC_LIMITED_STRING /* same as STRING, but has a size limit */
|
||||
};
|
||||
|
||||
int rpc_get (int sock, ...);
|
||||
int rpc_send (int sock, ...);
|
||||
int socket_read_block (int sock, char *dest, int len);
|
||||
int socket_write_block (int sock, char *buffer, int len);
|
||||
#endif /* !__MCFSUTIL_H */
|
|
@ -90,12 +90,16 @@ extern char *crypt (const char *, const char *);
|
|||
|
||||
#include "vfs.h"
|
||||
#include "mcfs.h"
|
||||
#include "mcfsutil.h"
|
||||
#include "tcputil.h"
|
||||
|
||||
/* replacement for g_free() from glib */
|
||||
#undef g_free
|
||||
#define g_free(x) do {if (x) free (x);} while (0)
|
||||
|
||||
/* We don't care about SIGPIPE */
|
||||
int got_sigpipe = 0;
|
||||
|
||||
/* The socket from which we accept commands */
|
||||
int msock;
|
||||
|
||||
|
|
183
vfs/tcputil.c
183
vfs/tcputil.c
|
@ -1,5 +1,4 @@
|
|||
/* Server for the Midnight Commander Virtual File System.
|
||||
Routines for the tcp connection, includes the primitive rpc routines.
|
||||
/* Network utilities for the Midnight Commander Virtual File System.
|
||||
|
||||
Copyright (C) 1995, 1996 Miguel de Icaza
|
||||
|
||||
|
@ -18,196 +17,16 @@
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PMAP_SET
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#ifdef HAVE_RPC_PMAP_CLNT_H
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include "tcputil.h"
|
||||
#include "../src/dialog.h" /* for message () */
|
||||
|
||||
#include "utilvfs.h"
|
||||
|
||||
#include "mcfs.h" /* for mcserver_port definition */
|
||||
|
||||
#define CHECK_SIG_PIPE(sock) if (got_sigpipe) \
|
||||
{ tcp_invalidate_socket (sock); return got_sigpipe = 0; }
|
||||
|
||||
extern void tcp_invalidate_socket (int);
|
||||
extern void vfs_die (char *);
|
||||
|
||||
int got_sigpipe;
|
||||
|
||||
#ifdef WITH_MCFS
|
||||
/* Reads a block on dest for len bytes from sock */
|
||||
/* Returns a boolean indicating the success status */
|
||||
int
|
||||
socket_read_block (int sock, char *dest, int len)
|
||||
{
|
||||
int nread, n;
|
||||
|
||||
for (nread = 0; nread < len;) {
|
||||
n = read (sock, dest + nread, len - nread);
|
||||
if (n <= 0) {
|
||||
tcp_invalidate_socket (sock);
|
||||
return 0;
|
||||
}
|
||||
nread += n;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
socket_write_block (int sock, char *buffer, int len)
|
||||
{
|
||||
int left, status;
|
||||
|
||||
for (left = len; left > 0;) {
|
||||
status = write (sock, buffer, left);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
if (status < 0)
|
||||
return 0;
|
||||
left -= status;
|
||||
buffer += status;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
rpc_send (int sock, ...)
|
||||
{
|
||||
long int tmp, len, cmd;
|
||||
char *text;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
tmp = htonl (va_arg (ap, int));
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_STRING:
|
||||
text = va_arg (ap, char *);
|
||||
len = strlen (text);
|
||||
tmp = htonl (len);
|
||||
write (sock, &tmp, sizeof (tmp));
|
||||
CHECK_SIG_PIPE (sock);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
tmp = htonl (len);
|
||||
write (sock, text, len);
|
||||
CHECK_SIG_PIPE (sock);
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
rpc_get (int sock, ...)
|
||||
{
|
||||
long int tmp, len;
|
||||
char *text, **str_dest;
|
||||
int *dest, cmd;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, sock);
|
||||
|
||||
for (;;) {
|
||||
cmd = va_arg (ap, int);
|
||||
switch (cmd) {
|
||||
case RPC_END:
|
||||
va_end (ap);
|
||||
return 1;
|
||||
|
||||
case RPC_INT:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
dest = va_arg (ap, int *);
|
||||
*dest = ntohl (tmp);
|
||||
break;
|
||||
|
||||
/* returns an allocated string */
|
||||
case RPC_LIMITED_STRING:
|
||||
case RPC_STRING:
|
||||
if (socket_read_block (sock, (char *) &tmp, sizeof (tmp)) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
len = ntohl (tmp);
|
||||
if (cmd == RPC_LIMITED_STRING)
|
||||
if (len > 16 * 1024) {
|
||||
/* silently die */
|
||||
abort ();
|
||||
}
|
||||
if (len > 128 * 1024)
|
||||
abort ();
|
||||
|
||||
/* Don't use glib functions here - this code is used by mcserv */
|
||||
text = malloc (len + 1);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
free (text);
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
text[len] = '\0';
|
||||
|
||||
str_dest = va_arg (ap, char **);
|
||||
*str_dest = text;
|
||||
break;
|
||||
|
||||
case RPC_BLOCK:
|
||||
len = va_arg (ap, int);
|
||||
text = va_arg (ap, char *);
|
||||
if (socket_read_block (sock, text, len) == 0) {
|
||||
va_end (ap);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
vfs_die ("Unknown rpc message\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* WITH_MCFS */
|
||||
|
||||
static void
|
||||
sig_pipe (int unused)
|
||||
{
|
||||
|
|
|
@ -1,19 +1,7 @@
|
|||
/* Operations of the rpc manager */
|
||||
|
||||
/* Please note that the RPC manager does not use integers, it only uses */
|
||||
/* 4-byte integers for the comunication */
|
||||
enum {
|
||||
RPC_END, /* End of RPC commands */
|
||||
RPC_INT, /* Next argument is integer */
|
||||
RPC_STRING, /* Next argument is a string */
|
||||
RPC_BLOCK, /* Next argument is a len/block */
|
||||
RPC_LIMITED_STRING /* same as STRING, but has a limit on the size it accepts */
|
||||
};
|
||||
|
||||
int rpc_get (int sock, ...);
|
||||
int rpc_send (int sock, ...);
|
||||
int socket_read_block (int sock, char *dest, int len);
|
||||
int socket_write_block (int sock, char *buffer, int len);
|
||||
void tcp_init (void);
|
||||
#ifndef __TCPUTIL_H
|
||||
#define __TCPUTIL_H
|
||||
|
||||
extern int got_sigpipe;
|
||||
void tcp_init (void);
|
||||
|
||||
#endif /* !__TCPUTIL_H */
|
||||
|
|
Loading…
Reference in New Issue