* 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:
Pavel Roskin 2002-10-05 01:02:07 +00:00
parent 51a6434b44
commit b5e7441d98
8 changed files with 251 additions and 201 deletions

View File

@ -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.

View File

@ -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)

View File

@ -52,6 +52,7 @@
#include "vfs.h"
#include "mcfs.h"
#include "mcfsutil.h"
#include "tcputil.h"
#include "../src/dialog.h"

205
vfs/mcfsutil.c Normal file
View File

@ -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 */

23
vfs/mcfsutil.h Normal file
View File

@ -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 */

View File

@ -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;

View File

@ -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)
{

View File

@ -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 */