mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-23 04:46:55 +03:00
Added vfs_uid for use by libvfs.so users (rpc.nfsd)
Added single file filesystem (sfs) Added vfs_flags so library users can disable selected filesystems Minor shuffling of functions so garbage collection works for library
This commit is contained in:
parent
e3121ab349
commit
3d0a91d4a8
@ -95,7 +95,8 @@ distclean:
|
||||
rm -f $(srcdir)/mcfn_install
|
||||
@for I in $(alldirs); do cd $$I; $(MAKE) $@ || exit 1; cd ..; done
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/Make.common
|
||||
rm -f lib/mc.ext mcfn_install vfs/extfs/ftplist vfs/extfs/zip vfs/extfs/zoo vfs/extfs/lslR vfs/extfs/lha vfs/extfs/cpio vfs/extfs/deb vfs/extfs/rar
|
||||
rm -f lib/mc.ext mcfn_install
|
||||
rm -f vfs/extfs/{ftplist,uzip,uzoo,lslR,ulha,ucpio,deb,urar,uar}
|
||||
rm -f $(srcdir)/config.log $(srcdir)/config.status
|
||||
|
||||
distdirs:
|
||||
|
@ -107,6 +107,7 @@ void my_putenv (char*, char*);
|
||||
#define EXECUTE_INTERNAL 1
|
||||
#define EXECUTE_TEMPFILE 2
|
||||
#define EXECUTE_AS_SHELL 4
|
||||
#define EXECUTE_SETUID 8
|
||||
int my_system (int flags, const char *shell, const char *command);
|
||||
int my_system_get_child_pid (int flags, const char *shell, const char *command, pid_t *pid);
|
||||
void save_stop_handler (void);
|
||||
|
@ -283,8 +283,10 @@ int my_system (int flags, const char *shell, const char *command)
|
||||
#if 0
|
||||
prepare_environment ();
|
||||
#endif
|
||||
if (flags & EXECUTE_SETUID)
|
||||
setreuid (vfs_uid, vfs_uid);
|
||||
|
||||
if (as_shell_command)
|
||||
if (flags & EXECUTE_AS_SHELL)
|
||||
execl (shell, shell, "-c", command, (char *) 0);
|
||||
else
|
||||
execlp (shell, shell, command, (char *) 0);
|
||||
|
@ -1,3 +1,15 @@
|
||||
Tue Aug 25 17:54:17 1998 Pavel Machek <pavel@ucw.cz>
|
||||
|
||||
* Added vfs_uid for use by libvfs.so users (rpc.nfsd)
|
||||
|
||||
* Added single file filesystem (sfs)
|
||||
|
||||
* Added vfs_flags so library users can disable selected
|
||||
filesystems
|
||||
|
||||
* Minor shuffling of functions so garbage collection works for
|
||||
library
|
||||
|
||||
1998-08-20 Raja R Harinath <harinath@cs.umn.edu>
|
||||
|
||||
* Makefile.am (mad.c, mad.h): Create symlinks to counterparts in
|
||||
|
148
vfs/Makefile.in
Normal file
148
vfs/Makefile.in
Normal file
@ -0,0 +1,148 @@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
rootdir = $(srcdir)/..
|
||||
@MCFG@@MCF@
|
||||
|
||||
CFLAGS = $(XCFLAGS)
|
||||
CPPFLAGS = $(XCPPFLAGS)
|
||||
LDFLAGS = $(XLDFLAGS)
|
||||
DEFS = $(XDEFS)
|
||||
LIBS = @LINTL@ @SHADOWLIB@ $(XLIBS) @TERMNET@ @PAMLIBS@ $(XLIB)
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ -m 755
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
AR = @AR@
|
||||
|
||||
#
|
||||
# VFS code
|
||||
#
|
||||
NETFILES = tcputil.o ftpfs.o mcfs.o utilvfs.o
|
||||
NONETFILES = local.o vfs.o tar.o names.o container.o extfs.o sfs.o @undelfs_o@
|
||||
|
||||
VFSSRCS = local.c vfs.c mcfs.c tcputil.c tar.c names.c \
|
||||
ftpfs.c container.c mcserv.c extfs.c undelfs.c utilvfs.c sfs.c
|
||||
|
||||
VFSHDRS = vfs.h mcfs.h tcputil.h tar.h container.h ftpfs.h names.h \
|
||||
extfs.h
|
||||
|
||||
VFSOBJS = $(NONETFILES) @NETFILES@
|
||||
|
||||
EXTFS_MISC = README extfs.ini
|
||||
EXTFS_CONST = a rpm hp48 mailfs patchfs
|
||||
EXTFS_IN = deb.in lslR.in ucpio.in urar.in uzoo.in ftplist.in uar.in \
|
||||
ulha.in uzip.in
|
||||
EXTFS_OUT = deb lslR ucpio urar uzoo ftplist uar ulha uzip
|
||||
|
||||
EXTFSSTUFF = $(EXTFS_MISC) $(EXTFS_CONST) $(EXTFS_IN)
|
||||
|
||||
#
|
||||
# Commands to build standalone version (.so)
|
||||
#
|
||||
|
||||
VFSSOOBJS = tcputil.so ftpfs.so mcfs.so utilvfs.so local.so vfs.so tar.so names.so container.so extfs.so util-alone.so util.sor utilunix.sor sfs.so
|
||||
|
||||
%.sor: ../src/%.c
|
||||
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
|
||||
|
||||
%.so: %.c
|
||||
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) -DVFS_STANDALONE $< -o $@
|
||||
|
||||
libvfs.so: $(VFSSOOBJS) libvfs.o
|
||||
gcc $(VFSSOOBJS) libvfs.o -shared -o libvfs.so
|
||||
|
||||
|
||||
#
|
||||
# Distribution variables
|
||||
#
|
||||
|
||||
DISTVFS = Makefile.in ChangeLog $(VFSSRCS) $(VFSHDRS)
|
||||
|
||||
all: @LIBVFS@ @mcserv@
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(DEFS) $(CFLAGS) $<
|
||||
|
||||
check:
|
||||
@echo no tests are supplied.
|
||||
|
||||
checklinks:
|
||||
@if test -f $(vfsdir)/mad.c; then echo ok; \
|
||||
else $(MAKE) sourcelinks; fi
|
||||
|
||||
sourcelinks:
|
||||
-cd $(vfsdir); $(LN_S) ../src/mad.c ../src/mad.h . >/dev/null 2>&1; true
|
||||
|
||||
mcserv: checklinks
|
||||
$(MAKE) mcservx
|
||||
|
||||
mcservx: mcserv.o tcputil.o mad.o
|
||||
$(CC) $(LDFLAGS) -o mcserv mcserv.o tcputil.o mad.o $(LIBS)
|
||||
touch mcservx
|
||||
|
||||
libvfs-mc.a: $(VFSOBJS)
|
||||
$(RMF) $@
|
||||
$(AR) cr $@ $(VFSOBJS)
|
||||
-$(RANLIB) $@
|
||||
|
||||
showlibdep:
|
||||
@echo 'OBJS="$(VFSOBJS)"'
|
||||
|
||||
cross:
|
||||
$(MAKE) CC=gcc-linux CPP="gcc-linux -E" \
|
||||
CPPFLAGS="$(CPPFLAGS) -I/usr/local/lib/gcc-lib/i386-linux-linux/include/ncurses "
|
||||
|
||||
TAGS: $(VFSSRCS)
|
||||
etags $(VFSSRCS)
|
||||
|
||||
clean:
|
||||
$(RMF) mcserv *.o core a.out libvfs-mc.a mcservx libvfs.so
|
||||
|
||||
realclean: clean
|
||||
$(RMF) .depend
|
||||
$(RMF) TAGS
|
||||
$(RMF) *~
|
||||
|
||||
distclean:
|
||||
-$(RMF) $(srcdir)/*~ $(srcdir)/mcserv $(srcdir)/*.o $(srcdir)/a.out
|
||||
-$(RMF) $(srcdir)/core $(srcdir)/libvfs-mc.a $(srcdir)/libvfs.so
|
||||
-$(RMF) $(srcdir)/mad.c $(srcdir)/mad.h
|
||||
-if test $(srcdir) = .; then $(MAKE) realclean; fi
|
||||
-$(RMF) $(srcdir)/Makefile
|
||||
|
||||
install: @mcserv@ install.extfs
|
||||
-(if test x@mcserv@ != x; then \
|
||||
$(INSTALL_PROGRAM) mcserv $(DESTDIR)$(bindir)/$(binprefix)mcserv; \
|
||||
fi)
|
||||
|
||||
install.extfs:
|
||||
for I in $(EXTFS_MISC); do \
|
||||
$(INSTALL_DATA) $(srcdir)/extfs/$$I \
|
||||
$(DESTDIR)$(libdir)/extfs/$$I; \
|
||||
done
|
||||
for I in $(EXTFS_CONST) $(EXTFS_OUT); do \
|
||||
$(INSTALL_PROGRAM) $(srcdir)/extfs/$$I \
|
||||
$(DESTDIR)$(libdir)/extfs/$$I; \
|
||||
done
|
||||
|
||||
uninstall:
|
||||
for I in $(EXTFS_MISC); do \
|
||||
$(RMF) $(DESTDIR)$(libdir)/extfs/$$I; \
|
||||
done
|
||||
for I in $(EXTFS_CONST) $(EXTFS_OUT); do \
|
||||
$(RMF) $(DESTDIR)$(libdir)/extfs/$$I; \
|
||||
done
|
||||
-rmdir $(DESTDIR)$(libdir)/extfs
|
||||
-$(RMF) $(DESTDIR)$(bindir)/$(binprefix)mcserv
|
||||
|
||||
distcopy:
|
||||
$(CP) $(DISTVFS) ../../mc-$(VERSION)/vfs
|
||||
cd extfs; $(CP) $(EXTFSSTUFF) ../../../mc-$(VERSION)/vfs/extfs
|
||||
|
||||
depend dep: mcdep
|
||||
|
||||
fastdeploc:
|
||||
|
||||
# ***Dependencies***Do not edit***
|
||||
@DOTDEPEND@
|
||||
# ***End of dependencies***
|
12
vfs/extfs.c
12
vfs/extfs.c
@ -408,6 +408,14 @@ static char *extfs_get_path_mangle (char *inname, struct extfs_archive **archive
|
||||
for (parc = first_archive; parc != NULL; parc = parc->next)
|
||||
if (parc->name) {
|
||||
if (!strcmp (parc->name, archive_name)) {
|
||||
struct stat *s=&(parc->extfsstat);
|
||||
if (vfs_uid && (!(s->st_mode & 0004)))
|
||||
if ((s->st_gid != vfs_gid) || !(s->st_mode & 0040))
|
||||
if ((s->st_uid != vfs_uid) || !(s->st_mode & 0400))
|
||||
return NULL;
|
||||
/* This is not too secure - in some cases (/#mtools) files created
|
||||
under user a are probably visible to everyone else since / usually
|
||||
has permissions 755 */
|
||||
vfs_stamp (&extfs_vfs_ops, (vfsid) parc);
|
||||
goto return_success;
|
||||
}
|
||||
@ -601,7 +609,7 @@ static void *extfs_open (char *file, int flags, int mode)
|
||||
" ", q, " ", entry->inode->local_filename, 0);
|
||||
free (q);
|
||||
free (archive_name);
|
||||
if (my_system (EXECUTE_AS_SHELL, shell, cmd) && !do_create){
|
||||
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, cmd) && !do_create){
|
||||
free (entry->inode->local_filename);
|
||||
entry->inode->local_filename = NULL;
|
||||
free (cmd);
|
||||
@ -664,7 +672,7 @@ static int extfs_close (void *data)
|
||||
file->entry->inode->local_filename, 0);
|
||||
free (archive_name);
|
||||
free (file_name);
|
||||
if (my_system (EXECUTE_AS_SHELL, shell, cmd))
|
||||
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, cmd))
|
||||
errno_code = EIO;
|
||||
free (cmd);
|
||||
{
|
||||
|
17
vfs/extfs/sfs.ini
Normal file
17
vfs/extfs/sfs.ini
Normal file
@ -0,0 +1,17 @@
|
||||
#
|
||||
# This is config for Single File fileSystem
|
||||
#
|
||||
gz/1 gzip < %1 > %3
|
||||
ugz/1 gzip -d < %1 > %3
|
||||
tar/1 tar cf %3 %1
|
||||
tgz/1 tar czf %3 %1
|
||||
uhtml/1 lynx -force_html -dump %1 > %3
|
||||
uman/1 groff -Tascii -man %1 > %3
|
||||
uue/1 uuenpipe < %1 > %3
|
||||
uude/1 uudepipe < %1 > %3
|
||||
crlf/1 todos < %1 > %3
|
||||
cr/1 fromdos < %1 > %3
|
||||
# Fixme: we need it to fail whenever it should
|
||||
url:2 lynx -source `echo "%2" | sed 's-|-/-g'` > %3
|
||||
nop/1 cat %1 > %3
|
||||
strings/1 strings %1 > %3
|
14
vfs/local.c
14
vfs/local.c
@ -13,6 +13,10 @@
|
||||
|
||||
#include "vfs.h"
|
||||
|
||||
/* Note: Some of this functions are not static. This has rather good
|
||||
* reason: exactly same functions would have to appear in sfs.c. This
|
||||
* saves both computer's memory and my work. <pavel@ucw.cz>
|
||||
* */
|
||||
|
||||
static void *local_open (char *file, int flags, int mode)
|
||||
{
|
||||
@ -29,7 +33,7 @@ static void *local_open (char *file, int flags, int mode)
|
||||
return local_info;
|
||||
}
|
||||
|
||||
static int local_read (void *data, char *buffer, int count)
|
||||
int local_read (void *data, char *buffer, int count)
|
||||
{
|
||||
int n;
|
||||
|
||||
@ -48,7 +52,7 @@ static int local_read (void *data, char *buffer, int count)
|
||||
return n;
|
||||
}
|
||||
|
||||
static int local_close (void *data)
|
||||
int local_close (void *data)
|
||||
{
|
||||
int fd;
|
||||
|
||||
@ -60,7 +64,7 @@ static int local_close (void *data)
|
||||
return close (fd);
|
||||
}
|
||||
|
||||
static int local_errno (void)
|
||||
int local_errno (void)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
@ -119,7 +123,7 @@ static int local_lstat (char *path, struct stat *buf)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int local_fstat (void *data, struct stat *buf)
|
||||
int local_fstat (void *data, struct stat *buf)
|
||||
{
|
||||
return fstat (*((int *) data), buf);
|
||||
}
|
||||
@ -185,7 +189,7 @@ static int local_chdir (char *path)
|
||||
return chdir (path);
|
||||
}
|
||||
|
||||
static int local_lseek (void *data, off_t offset, int whence)
|
||||
int local_lseek (void *data, off_t offset, int whence)
|
||||
{
|
||||
int fd = * (int *) data;
|
||||
|
||||
|
399
vfs/sfs.c
Normal file
399
vfs/sfs.c
Normal file
@ -0,0 +1,399 @@
|
||||
/*
|
||||
* Single File fileSystem
|
||||
*
|
||||
* Copyright 1998 Pavel Machek, distribute under GPL
|
||||
*
|
||||
* This defines whole class of filesystems which contain single file
|
||||
* inside. It is somehow similar to extfs, except that extfs makes
|
||||
* whole virtual trees and we do only single virtual files. */
|
||||
|
||||
/*TODO Pridat sfs_fill_names na spravne misto.
|
||||
|
||||
Pridat tam nejake add_noncurrent_stamps().
|
||||
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../src/mad.h"
|
||||
#include "../src/fs.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include "../src/util.h"
|
||||
#include "../src/main.h"
|
||||
|
||||
#include "vfs.h"
|
||||
|
||||
char *shell = "/bin/bash";
|
||||
|
||||
struct cachedfile {
|
||||
char *name, *cache;
|
||||
uid_t uid;
|
||||
struct cachedfile *next;
|
||||
};
|
||||
|
||||
static struct cachedfile *head;
|
||||
|
||||
#define MAXFS 32
|
||||
static int sfs_no = 0;
|
||||
static char *sfs_prefix[ MAXFS ];
|
||||
static char *sfs_command[ MAXFS ];
|
||||
static int sfs_flags[ MAXFS ];
|
||||
#define F_1 1
|
||||
#define F_2 2
|
||||
#define F_NOLOCALCOPY 4
|
||||
#define F_FULLMATCH 8
|
||||
|
||||
static int uptodate( char *name, char *cache )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vfmake( char *name, char *cache )
|
||||
{
|
||||
char *inpath, *op;
|
||||
int w;
|
||||
char pad [10240];
|
||||
char *s, *t = pad;
|
||||
int was_percent = 0;
|
||||
|
||||
vfs_split( name, &inpath, &op );
|
||||
if ((w = sfs_which( op )) == -1)
|
||||
vfs_die( "This cannot happen... Hopefully.\n" );
|
||||
|
||||
if ((sfs_flags[w] & F_1) || (!strcmp( name, "/" ))) ; else return -1;
|
||||
/* if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
|
||||
if (!(sfs_flags[w] & F_NOLOCALCOPY))
|
||||
name = mc_getlocalcopy( name );
|
||||
else
|
||||
name = strdup( name );
|
||||
s = sfs_command[w];
|
||||
#define COPY_CHAR if (t-pad>10200) return -1; else *t++ = *s;
|
||||
#define COPY_STRING(a) if ((t-pad)+strlen(a)>10200) return -1; else { strcpy( t, a ); t+= strlen(a); }
|
||||
while (*s) {
|
||||
if (was_percent) {
|
||||
switch (*s) {
|
||||
case '1': COPY_STRING( name ); break;
|
||||
case '2': COPY_STRING( op + strlen( sfs_prefix[w] ) ); break;
|
||||
case '3': COPY_STRING( cache ); break;
|
||||
case '%': COPY_CHAR; break;
|
||||
}
|
||||
was_percent = 0;
|
||||
} else {
|
||||
if (*s == '%') was_percent = 1;
|
||||
else COPY_CHAR;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
free( name );
|
||||
|
||||
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, shell, pad)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
static char *redirect( char *name )
|
||||
{
|
||||
struct cachedfile *cur = head;
|
||||
uid_t uid = vfs_uid;
|
||||
char *cache, *xname;
|
||||
|
||||
while (cur) {
|
||||
if ((!strcmp( name, cur->name )) &&
|
||||
(uid == cur->uid) &&
|
||||
(uptodate( cur->name, cur->cache )))
|
||||
return cur->cache;
|
||||
cur = cur->next;
|
||||
}
|
||||
cache = tempnam( NULL, "sfs" );
|
||||
xname = strdup( name );
|
||||
if (!vfmake( name, cache )) {
|
||||
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" );
|
||||
cur->name = xname;
|
||||
cur->cache = strdup(cache);
|
||||
cur->uid = uid;
|
||||
cur->next = head;
|
||||
head = cur;
|
||||
return cache;
|
||||
} else {
|
||||
free(xname);
|
||||
fprintf( stderr, "vfmake failed\n" );
|
||||
}
|
||||
return "/I_MUST_NOT_EXIST";
|
||||
}
|
||||
|
||||
#define REDIR path = redirect( path );
|
||||
|
||||
static void *sfs_open (char *path, int flags, int mode)
|
||||
{
|
||||
int *sfs_info;
|
||||
int fd;
|
||||
|
||||
REDIR;
|
||||
fd = open (path, flags, mode);
|
||||
if (fd == -1)
|
||||
return 0;
|
||||
|
||||
sfs_info = (int *) xmalloc (sizeof (int), "SF fs");
|
||||
*sfs_info = fd;
|
||||
|
||||
return sfs_info;
|
||||
}
|
||||
|
||||
static int sfs_stat (char *path, struct stat *buf)
|
||||
{
|
||||
REDIR;
|
||||
return stat (path, buf);
|
||||
}
|
||||
|
||||
static int sfs_lstat (char *path, struct stat *buf)
|
||||
{
|
||||
REDIR;
|
||||
#ifndef HAVE_STATLSTAT
|
||||
return lstat (path,buf);
|
||||
#else
|
||||
return statlstat (path, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int sfs_chmod (char *path, int mode)
|
||||
{
|
||||
REDIR;
|
||||
return chmod (path, mode);
|
||||
}
|
||||
|
||||
static int sfs_chown (char *path, int owner, int group)
|
||||
{
|
||||
REDIR;
|
||||
return chown (path, owner, group);
|
||||
}
|
||||
|
||||
static int sfs_utime (char *path, struct utimbuf *times)
|
||||
{
|
||||
REDIR;
|
||||
return utime (path, times);
|
||||
}
|
||||
|
||||
static int sfs_readlink (char *path, char *buf, int size)
|
||||
{
|
||||
REDIR;
|
||||
return readlink (path, buf, size);
|
||||
}
|
||||
|
||||
#define CUR (*cur)
|
||||
static vfsid sfs_getid (char *path, struct vfs_stamping **parent)
|
||||
{ /* FIXME: what should I do? */
|
||||
vfs *v;
|
||||
vfsid id;
|
||||
struct vfs_stamping *par;
|
||||
struct cachedfile **cur = &head;
|
||||
|
||||
while (CUR) {
|
||||
if ((!strcmp( path, CUR->name )) &&
|
||||
(vfs_uid == CUR->uid))
|
||||
break;
|
||||
CUR = CUR->next;
|
||||
}
|
||||
if (!CUR)
|
||||
vfs_die( "sfs_getid of noncached thingie?" );
|
||||
|
||||
*parent = NULL;
|
||||
|
||||
{
|
||||
char *path2 = strdup( path );
|
||||
v = vfs_split (path2, NULL, NULL);
|
||||
id = (*v->getid) (path2, &par);
|
||||
free( path2 );
|
||||
}
|
||||
|
||||
if (id != (vfsid)-1) {
|
||||
*parent = xmalloc (sizeof (struct vfs_stamping), "vfs stamping");
|
||||
(*parent)->v = v;
|
||||
(*parent)->id = id;
|
||||
(*parent)->parent = par;
|
||||
(*parent)->next = NULL;
|
||||
}
|
||||
return (vfsid) cur;
|
||||
}
|
||||
|
||||
static void sfs_free (vfsid id)
|
||||
{
|
||||
struct cachedfile **cur = (struct cachedfile **) id;
|
||||
|
||||
unlink( CUR->cache );
|
||||
*cur = CUR->next;
|
||||
}
|
||||
#undef CUR
|
||||
|
||||
void sfs_fill_names (void (*func)(char *))
|
||||
{
|
||||
struct cachedfile *cur = head;
|
||||
char *name;
|
||||
|
||||
while (cur){
|
||||
(*func)(cur->name);
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int sfs_nothingisopen (vfsid id)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *sfs_getlocalcopy (char *path)
|
||||
{
|
||||
REDIR;
|
||||
return strdup (path);
|
||||
}
|
||||
|
||||
static void sfs_ungetlocalcopy (char *path, char *local, int has_changed)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
static caddr_t sfs_mmap (caddr_t addr, size_t len, int prot, int flags, void *data, off_t offset)
|
||||
{
|
||||
int fd = * (int *)data;
|
||||
|
||||
return mmap (addr, len, prot, flags, fd, offset);
|
||||
}
|
||||
|
||||
static int sfs_munmap (caddr_t addr, size_t len, void *data)
|
||||
{
|
||||
return munmap (addr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern int local_close (void *data);
|
||||
extern int local_read (void *data, char *buffer, int count);
|
||||
extern int local_fstat (void *data, struct stat *buf);
|
||||
extern int local_errno (void);
|
||||
extern int local_lseek (void *data, off_t offset, int whence);
|
||||
|
||||
vfs sfs_vfs_ops = {
|
||||
sfs_open,
|
||||
local_close,
|
||||
local_read,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
sfs_stat,
|
||||
sfs_lstat,
|
||||
local_fstat,
|
||||
|
||||
sfs_chmod,
|
||||
sfs_chown,
|
||||
sfs_utime,
|
||||
|
||||
sfs_readlink,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
local_errno,
|
||||
local_lseek,
|
||||
NULL,
|
||||
|
||||
sfs_getid,
|
||||
sfs_nothingisopen,
|
||||
sfs_free,
|
||||
|
||||
sfs_getlocalcopy,
|
||||
sfs_ungetlocalcopy,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
#ifdef HAVE_MMAP
|
||||
,sfs_mmap,
|
||||
sfs_munmap
|
||||
#endif
|
||||
};
|
||||
|
||||
void sfs_init (void)
|
||||
{
|
||||
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" );
|
||||
if (!cfg) {
|
||||
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
sfs_no = 0;
|
||||
while ( sfs_no < MAXFS ) {
|
||||
char key[256];
|
||||
char *c, *semi = NULL, flags = 0;
|
||||
int i;
|
||||
|
||||
if (!fgets( key, 250, cfg ))
|
||||
break;
|
||||
|
||||
if (*key == '#')
|
||||
continue;
|
||||
|
||||
for (i=0; i<strlen(key); i++)
|
||||
if ((key[i]==':') || (key[i]=='/'))
|
||||
{ semi = key+i; if (key[i]=='/') { key[i]=0; flags |= F_FULLMATCH; } break; }
|
||||
|
||||
if (!semi) {
|
||||
fprintf( stderr, "Warning: Invalid line %s in sfs.ini.\n", key );
|
||||
continue;
|
||||
}
|
||||
|
||||
c = semi + 1;
|
||||
while ((*c != ' ') && (*c != 9)) {
|
||||
switch (*c) {
|
||||
case '1': flags |= F_1; break;
|
||||
case '2': flags |= F_2; break;
|
||||
case 'R': flags |= F_NOLOCALCOPY; break;
|
||||
default:
|
||||
fprintf( stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", c, key );
|
||||
}
|
||||
c++;
|
||||
}
|
||||
c++;
|
||||
*(semi+1) = 0;
|
||||
if ((semi = strchr( c, '\n')))
|
||||
*semi = 0;
|
||||
|
||||
sfs_prefix [sfs_no] = strdup (key);
|
||||
sfs_command [sfs_no] = strdup (c);
|
||||
sfs_flags [sfs_no] = flags;
|
||||
sfs_no++;
|
||||
}
|
||||
fclose(cfg);
|
||||
}
|
||||
|
||||
int sfs_which (char *path)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sfs_no; i++)
|
||||
if (sfs_flags [i] & F_FULLMATCH) {
|
||||
if (!strcmp (path, sfs_prefix [i]))
|
||||
return i;
|
||||
} else
|
||||
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) ))
|
||||
return i;
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
@ -826,6 +826,10 @@ static char *tarfs_get_path_mangle (char *inname, struct tarfs_archive **archive
|
||||
|
||||
for (parc = first_archive; parc != NULL; parc = parc->next)
|
||||
if (!strcmp (parc->name, archive_name)) {
|
||||
if (vfs_uid && (!(stat_buf.st_mode & 0004)))
|
||||
if ((stat_buf.st_gid != vfs_gid) || !(stat_buf.st_mode & 0040))
|
||||
if ((stat_buf.st_uid != vfs_uid) || !(stat_buf.st_mode & 0400))
|
||||
return NULL;
|
||||
/* Has the cached archive been changed on the disk? */
|
||||
if (parc->tarstat.st_mtime < stat_buf.st_mtime) { /* Yes, reload! */
|
||||
(*tarfs_vfs_ops.free) ((vfsid) parc);
|
||||
@ -1146,8 +1150,8 @@ static vfsid tar_getid (char *path, struct vfs_stamping **parent)
|
||||
{
|
||||
struct tarfs_archive *archive;
|
||||
vfs *v;
|
||||
vfsid id;
|
||||
char *p;
|
||||
vfsid id;
|
||||
struct vfs_stamping *par;
|
||||
|
||||
*parent = NULL;
|
||||
|
50
vfs/vfs.c
50
vfs/vfs.c
@ -19,8 +19,6 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define _VFS_VFS_C 1
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* For atol() */
|
||||
@ -58,6 +56,12 @@ extern int get_other_type (void);
|
||||
extern int extfs_which (char *path);
|
||||
|
||||
int vfs_timeout = 60; /* VFS timeout in seconds */
|
||||
int vfs_flags = /* Flags */
|
||||
#ifdef VFS_STANDALONE
|
||||
0;
|
||||
#else
|
||||
FL_ALWAYS_MAGIC;
|
||||
#endif
|
||||
|
||||
extern int cd_symlinks; /* Defined in main.c */
|
||||
|
||||
@ -65,10 +69,16 @@ extern int cd_symlinks; /* Defined in main.c */
|
||||
static vfs *current_vfs = &local_vfs_ops;
|
||||
char *current_dir = NULL;
|
||||
|
||||
/*
|
||||
* FIXME: this is broken. It depends on mc not crossing border on month!
|
||||
*/
|
||||
static int current_mday;
|
||||
static int current_mon;
|
||||
static int current_year;
|
||||
|
||||
uid_t vfs_uid = 0;
|
||||
gid_t vfs_gid = 0;
|
||||
|
||||
/* Open files managed by the vfs layer */
|
||||
#define MAX_VFS_FILES 100
|
||||
static struct {
|
||||
@ -92,24 +102,36 @@ static int get_bucket ()
|
||||
vfs *vfs_type_from_op (char *path)
|
||||
{
|
||||
#ifdef USE_NETCODE
|
||||
if (!strncmp (path, "mc:", 3))
|
||||
if (!(vfs_flags & FL_NO_MCFS) && !strncmp (path, "mc:", 3))
|
||||
return &mcfs_vfs_ops;
|
||||
if (!strncmp (path, "ftp:", 4))
|
||||
if (!(vfs_flags & FL_NO_FTPFS) && !strncmp (path, "ftp:", 4))
|
||||
return &ftpfs_vfs_ops;
|
||||
#endif
|
||||
#ifdef USE_EXT2FSLIB
|
||||
if (!strcmp (path, "undel"))
|
||||
if (!(vfs_flags & FL_NO_UNDELFS) && !strcmp (path, "undel"))
|
||||
return &undelfs_vfs_ops;
|
||||
#endif
|
||||
if (!strcmp (path, "utar"))
|
||||
if (!(vfs_flags & FL_NO_TARFS) && !strcmp (path, "utar"))
|
||||
return &tarfs_vfs_ops;
|
||||
if (extfs_which (path) != -1)
|
||||
if (!(vfs_flags & FL_NO_EXTFS) && extfs_which (path) != -1)
|
||||
return &extfs_vfs_ops;
|
||||
if (!(vfs_flags & FL_NO_SFS) && sfs_which (path) != -1)
|
||||
return &sfs_vfs_ops;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int path_magic( char *path )
|
||||
{
|
||||
int res;
|
||||
|
||||
res = !strncmp( path, "/#/", 3 );
|
||||
if (res)
|
||||
path[1] = '/';
|
||||
return res || (vfs_flags & FL_ALWAYS_MAGIC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Splits path '/p1:op/inpath' into inpath,op; returns which vfs it is.
|
||||
* Splits path '/p1#op/inpath' into inpath,op; returns which vfs it is.
|
||||
* What is left in path is p1. You still want to free(path), you DON'T
|
||||
* want to free neither *inpath nor *op
|
||||
*/
|
||||
@ -651,7 +673,7 @@ char *vfs_canon (char *path)
|
||||
return result;
|
||||
}
|
||||
/* So we have path of following form:
|
||||
* /p1/p2:op/.././././p3:op/p4. Good luck.
|
||||
* /p1/p2#op/.././././p3#op/p4. Good luck.
|
||||
*/
|
||||
canonicalize_pathname (path);
|
||||
|
||||
@ -673,7 +695,6 @@ vfsid vfs_ncs_getid (vfs *nvfs, char *dir, struct vfs_stamping **par)
|
||||
return nvfsid;
|
||||
}
|
||||
|
||||
#ifndef VFS_STANDALONE
|
||||
static int is_parent (vfs * nvfs, vfsid nvfsid, struct vfs_stamping *parent)
|
||||
{
|
||||
struct vfs_stamping *stamp;
|
||||
@ -682,7 +703,6 @@ static int is_parent (vfs * nvfs, vfsid nvfsid, struct vfs_stamping *parent)
|
||||
break;
|
||||
return (stamp ? 1 : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void vfs_add_noncurrent_stamps (vfs * oldvfs, vfsid oldvfsid, struct vfs_stamping *parent)
|
||||
{
|
||||
@ -762,10 +782,11 @@ void vfs_add_noncurrent_stamps (vfs * oldvfs, vfsid oldvfsid, struct vfs_stampin
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
}
|
||||
}
|
||||
#else
|
||||
vfs_addstamp (oldvfs, oldvfsid, parent);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef VFS_STANDALONE
|
||||
static void vfs_stamp_path (char *path)
|
||||
{
|
||||
vfs *vfs;
|
||||
@ -780,7 +801,6 @@ static void vfs_stamp_path (char *path)
|
||||
vfs_addstamp (stamp->v, stamp->id, stamp->parent);
|
||||
vfs_rm_parents (par);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef VFS_STANDALONE
|
||||
void vfs_add_current_stamps (void)
|
||||
@ -1041,6 +1061,9 @@ void mc_ungetlocalcopy (char *path, char *local, int has_changed)
|
||||
free (path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hmm, as timeout is minute or so, do we need to care about usecs?
|
||||
*/
|
||||
inline int timeoutcmp (struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return ((t1->tv_sec < t2->tv_sec)
|
||||
@ -1082,6 +1105,7 @@ void vfs_init (void)
|
||||
ftpfs_init();
|
||||
#endif
|
||||
extfs_init ();
|
||||
sfs_init ();
|
||||
vfs_setup_wd ();
|
||||
}
|
||||
|
||||
|
17
vfs/vfs.h
17
vfs/vfs.h
@ -2,7 +2,6 @@
|
||||
#define __VFS_H
|
||||
|
||||
#ifdef VFS_STANDALONE
|
||||
#include "util-alone.h"
|
||||
#undef USE_EXT2FSLIB
|
||||
#else
|
||||
#define BROKEN_PATHS
|
||||
@ -27,7 +26,6 @@ struct utimbuf {
|
||||
#endif
|
||||
|
||||
#ifdef USE_VFS
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
@ -95,6 +93,7 @@ struct utimbuf {
|
||||
extern vfs mcfs_vfs_ops;
|
||||
|
||||
extern vfs extfs_vfs_ops;
|
||||
extern vfs sfs_vfs_ops;
|
||||
|
||||
extern vfs undelfs_vfs_ops;
|
||||
|
||||
@ -313,5 +312,19 @@ extern char *vfs_get_password (char *msg);
|
||||
#define MCERR_DATA_ON_STDIN -5
|
||||
/* Data waiting on stdin to be processed */
|
||||
|
||||
extern int vfs_flags;
|
||||
extern uid_t vfs_uid;
|
||||
extern gid_t vfs_gid;
|
||||
|
||||
|
||||
|
||||
#define FL_ALWAYS_MAGIC 1
|
||||
#define FL_NO_MCFS 2
|
||||
#define FL_NO_FTPFS 4
|
||||
#define FL_NO_UNDELFS 8
|
||||
#define FL_NO_TARFS 16
|
||||
#define FL_NO_EXTFS 32
|
||||
#define FL_NO_SFS 64
|
||||
|
||||
#endif /* __VFS_H */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user