1998-08-25 20:00:16 +04:00
|
|
|
/*
|
|
|
|
* Single File fileSystem
|
|
|
|
*
|
2007-09-26 14:22:25 +04:00
|
|
|
* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
|
|
|
|
* Free Software Foundation, Inc.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
1998-08-25 20:00:16 +04:00
|
|
|
*
|
|
|
|
* This defines whole class of filesystems which contain single file
|
|
|
|
* inside. It is somehow similar to extfs, except that extfs makes
|
1998-09-14 12:14:31 +04:00
|
|
|
* whole virtual trees and we do only single virtual files.
|
1998-10-13 02:07:53 +04:00
|
|
|
*
|
1998-10-23 12:26:25 +04:00
|
|
|
* If you want to gunzip something, you should open it with #ugz
|
|
|
|
* suffix, DON'T try to gunzip it yourself.
|
|
|
|
*
|
2001-06-16 02:32:15 +04:00
|
|
|
* Namespace: exports vfs_sfs_ops */
|
1998-08-25 20:00:16 +04:00
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
1999-01-21 01:01:11 +03:00
|
|
|
|
2005-02-19 19:36:38 +03:00
|
|
|
#include "../src/global.h"
|
|
|
|
#include "../src/tty.h" /* enable/disable interrupt key */
|
|
|
|
#include "../src/wtools.h" /* message() */
|
|
|
|
#include "../src/main.h" /* print_vfs_message */
|
1999-01-21 01:01:11 +03:00
|
|
|
#include "utilvfs.h"
|
1998-08-25 20:00:16 +04:00
|
|
|
#include "vfs.h"
|
2004-08-17 03:18:42 +04:00
|
|
|
#include "vfs-impl.h"
|
2003-11-13 11:03:03 +03:00
|
|
|
#include "gc.h" /* vfs_stamp_create */
|
1998-12-15 22:53:55 +03:00
|
|
|
#include "local.h"
|
2003-10-26 01:34:57 +04:00
|
|
|
#include "../src/execute.h" /* EXECUTE_AS_SHELL */
|
1998-08-25 20:00:16 +04:00
|
|
|
|
|
|
|
struct cachedfile {
|
|
|
|
char *name, *cache;
|
|
|
|
struct cachedfile *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct cachedfile *head;
|
2003-10-13 02:25:53 +04:00
|
|
|
static struct vfs_class vfs_sfs_ops;
|
1998-08-25 20:00:16 +04:00
|
|
|
|
|
|
|
#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
|
|
|
|
|
2003-10-28 05:10:33 +03:00
|
|
|
static int
|
|
|
|
sfs_vfmake (struct vfs_class *me, const char *name, char *cache)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
|
|
|
char *inpath, *op;
|
|
|
|
int w;
|
2003-10-28 05:10:33 +03:00
|
|
|
char pad[10240];
|
1998-08-25 20:00:16 +04:00
|
|
|
char *s, *t = pad;
|
|
|
|
int was_percent = 0;
|
2003-11-14 11:25:50 +03:00
|
|
|
char *pname; /* name of parent archive */
|
|
|
|
char *pqname; /* name of parent archive, quoted */
|
1998-08-25 20:00:16 +04:00
|
|
|
|
2003-11-14 11:25:50 +03:00
|
|
|
pname = g_strdup (name);
|
|
|
|
vfs_split (pname, &inpath, &op);
|
1999-01-11 03:48:23 +03:00
|
|
|
if ((w = (*me->which) (me, op)) == -1)
|
2003-10-28 05:10:33 +03:00
|
|
|
vfs_die ("This cannot happen... Hopefully.\n");
|
1998-08-25 20:00:16 +04:00
|
|
|
|
2003-11-14 11:25:50 +03:00
|
|
|
if (!(sfs_flags[w] & F_1) && strcmp (pname, "/")) {
|
|
|
|
g_free (pname);
|
2003-10-28 05:10:33 +03:00
|
|
|
return -1;
|
2003-11-14 11:25:50 +03:00
|
|
|
}
|
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
/* if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
|
1999-08-18 23:08:56 +04:00
|
|
|
if (!(sfs_flags[w] & F_NOLOCALCOPY)) {
|
2003-11-14 11:25:50 +03:00
|
|
|
s = mc_getlocalcopy (pname);
|
|
|
|
if (!s) {
|
|
|
|
g_free (pname);
|
1999-08-18 23:08:56 +04:00
|
|
|
return -1;
|
2003-11-14 11:25:50 +03:00
|
|
|
}
|
|
|
|
pqname = name_quote (s, 0);
|
1999-08-18 23:08:56 +04:00
|
|
|
g_free (s);
|
2003-11-14 11:25:50 +03:00
|
|
|
} else {
|
|
|
|
pqname = name_quote (pname, 0);
|
|
|
|
}
|
|
|
|
g_free (pname);
|
|
|
|
|
|
|
|
#define COPY_CHAR \
|
2004-08-16 08:27:25 +04:00
|
|
|
if ((size_t) (t-pad) > sizeof(pad)) { \
|
2003-11-14 11:25:50 +03:00
|
|
|
g_free (pqname); \
|
|
|
|
return -1; \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
*t++ = *s;
|
|
|
|
|
|
|
|
#define COPY_STRING(a) \
|
|
|
|
if ((t-pad)+strlen(a)>sizeof(pad)) { \
|
|
|
|
g_free (pqname); \
|
|
|
|
return -1; \
|
|
|
|
} else { \
|
|
|
|
strcpy (t, a); \
|
|
|
|
t+= strlen(a); \
|
|
|
|
}
|
|
|
|
|
2000-05-16 18:59:33 +04:00
|
|
|
for (s = sfs_command[w]; *s; s++) {
|
2003-10-28 05:10:33 +03:00
|
|
|
if (was_percent) {
|
2000-05-16 18:59:33 +04:00
|
|
|
|
2003-10-28 05:10:33 +03:00
|
|
|
const char *ptr = NULL;
|
2000-05-16 18:59:33 +04:00
|
|
|
was_percent = 0;
|
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
switch (*s) {
|
2003-10-28 05:10:33 +03:00
|
|
|
case '1':
|
2003-11-14 11:25:50 +03:00
|
|
|
ptr = pqname;
|
2003-10-28 05:10:33 +03:00
|
|
|
break;
|
|
|
|
case '2':
|
|
|
|
ptr = op + strlen (sfs_prefix[w]);
|
|
|
|
break;
|
|
|
|
case '3':
|
|
|
|
ptr = cache;
|
|
|
|
break;
|
|
|
|
case '%':
|
|
|
|
COPY_CHAR;
|
|
|
|
continue;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
2000-05-16 18:59:33 +04:00
|
|
|
COPY_STRING (ptr);
|
1998-08-25 20:00:16 +04:00
|
|
|
} else {
|
1999-01-11 03:48:23 +03:00
|
|
|
if (*s == '%')
|
|
|
|
was_percent = 1;
|
|
|
|
else
|
|
|
|
COPY_CHAR;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-14 11:25:50 +03:00
|
|
|
g_free (pqname);
|
2002-10-04 17:24:10 +04:00
|
|
|
open_error_pipe ();
|
2002-08-20 03:20:03 +04:00
|
|
|
if (my_system (EXECUTE_AS_SHELL, "/bin/sh", pad)) {
|
2002-10-04 17:24:10 +04:00
|
|
|
close_error_pipe (1, NULL);
|
1998-08-25 20:00:16 +04:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-10-04 17:24:10 +04:00
|
|
|
close_error_pipe (0, NULL);
|
2003-10-28 05:10:33 +03:00
|
|
|
return 0; /* OK */
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
2005-09-05 04:52:56 +04:00
|
|
|
static const char *
|
2003-10-28 05:10:33 +03:00
|
|
|
sfs_redirect (struct vfs_class *me, const char *name)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
|
|
|
struct cachedfile *cur = head;
|
2000-05-16 18:59:33 +04:00
|
|
|
char *cache;
|
1998-12-15 18:57:39 +03:00
|
|
|
int handle;
|
1998-08-25 20:00:16 +04:00
|
|
|
|
2002-12-06 05:14:28 +03:00
|
|
|
while (cur) {
|
2006-04-04 13:26:13 +04:00
|
|
|
if (!strcmp (name, cur->name)) {
|
2002-12-06 05:14:28 +03:00
|
|
|
vfs_stamp (&vfs_sfs_ops, cur);
|
|
|
|
return cur->cache;
|
1998-09-14 12:14:31 +04:00
|
|
|
}
|
1998-08-25 20:00:16 +04:00
|
|
|
cur = cur->next;
|
|
|
|
}
|
1999-01-11 03:48:23 +03:00
|
|
|
|
2003-10-29 03:50:36 +03:00
|
|
|
handle = vfs_mkstemps (&cache, "sfs", name);
|
2001-05-21 20:21:07 +04:00
|
|
|
|
2000-05-16 18:59:33 +04:00
|
|
|
if (handle == -1) {
|
|
|
|
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
|
|
|
|
}
|
1998-12-15 18:57:39 +03:00
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
close (handle);
|
|
|
|
|
2003-10-28 03:57:02 +03:00
|
|
|
if (!sfs_vfmake (me, name, cache)) {
|
2000-05-16 18:59:33 +04:00
|
|
|
cur = g_new (struct cachedfile, 1);
|
|
|
|
cur->name = g_strdup (name);
|
1999-01-11 03:48:23 +03:00
|
|
|
cur->cache = cache;
|
1998-08-25 20:00:16 +04:00
|
|
|
cur->next = head;
|
|
|
|
head = cur;
|
1998-09-14 12:14:31 +04:00
|
|
|
|
2003-11-27 00:10:42 +03:00
|
|
|
vfs_stamp_create (&vfs_sfs_ops, head);
|
1998-09-14 12:14:31 +04:00
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
return cache;
|
|
|
|
}
|
2002-12-06 05:14:28 +03:00
|
|
|
|
2000-10-10 02:45:50 +04:00
|
|
|
unlink (cache);
|
2000-05-16 18:59:33 +04:00
|
|
|
g_free (cache);
|
1998-08-25 20:00:16 +04:00
|
|
|
return "/I_MUST_NOT_EXIST";
|
|
|
|
}
|
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
static void *
|
2003-10-28 05:10:33 +03:00
|
|
|
sfs_open (struct vfs_class *me, const char *path, int flags, int mode)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
|
|
|
int *sfs_info;
|
|
|
|
int fd;
|
|
|
|
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
2003-10-28 05:10:33 +03:00
|
|
|
fd = open (path, NO_LINEAR (flags), mode);
|
1998-08-25 20:00:16 +04:00
|
|
|
if (fd == -1)
|
|
|
|
return 0;
|
|
|
|
|
1999-01-21 01:01:11 +03:00
|
|
|
sfs_info = g_new (int, 1);
|
1998-08-25 20:00:16 +04:00
|
|
|
*sfs_info = fd;
|
2003-10-28 05:10:33 +03:00
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
return sfs_info;
|
|
|
|
}
|
|
|
|
|
2004-08-17 00:26:42 +04:00
|
|
|
static int sfs_stat (struct vfs_class *me, const char *path, struct stat *buf)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
return stat (path, buf);
|
|
|
|
}
|
|
|
|
|
2004-08-17 00:26:42 +04:00
|
|
|
static int sfs_lstat (struct vfs_class *me, const char *path, struct stat *buf)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
#ifndef HAVE_STATLSTAT
|
2000-10-10 02:45:50 +04:00
|
|
|
return lstat (path, buf);
|
1998-08-25 20:00:16 +04:00
|
|
|
#else
|
|
|
|
return statlstat (path, buf);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2004-08-17 01:36:39 +04:00
|
|
|
static int sfs_chmod (struct vfs_class *me, const char *path, int mode)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
return chmod (path, mode);
|
|
|
|
}
|
|
|
|
|
2004-08-17 01:36:39 +04:00
|
|
|
static int sfs_chown (struct vfs_class *me, const char *path, int owner, int group)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
return chown (path, owner, group);
|
|
|
|
}
|
|
|
|
|
2004-08-17 01:36:39 +04:00
|
|
|
static int sfs_utime (struct vfs_class *me, const char *path, struct utimbuf *times)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
return utime (path, times);
|
|
|
|
}
|
|
|
|
|
2004-09-02 18:12:21 +04:00
|
|
|
static int
|
|
|
|
sfs_readlink (struct vfs_class *me, const char *path, char *buf, size_t size)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1998-08-25 20:00:16 +04:00
|
|
|
return readlink (path, buf, size);
|
|
|
|
}
|
|
|
|
|
2002-12-06 05:14:28 +03:00
|
|
|
static vfsid
|
2003-11-27 00:10:42 +03:00
|
|
|
sfs_getid (struct vfs_class *me, const char *path)
|
2003-11-13 02:00:16 +03:00
|
|
|
{
|
1999-01-10 02:08:41 +03:00
|
|
|
struct cachedfile *cur = head;
|
1998-08-25 20:00:16 +04:00
|
|
|
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
|
1999-01-10 02:08:41 +03:00
|
|
|
while (cur) {
|
2002-12-06 05:18:10 +03:00
|
|
|
if (!strcmp (path, cur->name))
|
1998-08-25 20:00:16 +04:00
|
|
|
break;
|
1999-01-10 02:08:41 +03:00
|
|
|
cur = cur->next;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return (vfsid) cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void sfs_free (vfsid id)
|
|
|
|
{
|
1998-09-14 12:14:31 +04:00
|
|
|
struct cachedfile *which = (struct cachedfile *) id;
|
1999-01-10 02:08:41 +03:00
|
|
|
struct cachedfile *cur, *prev;
|
1998-08-25 20:00:16 +04:00
|
|
|
|
1999-01-10 02:08:41 +03:00
|
|
|
for (cur = head, prev = 0; cur && cur != which; prev = cur, cur = cur->next)
|
|
|
|
;
|
|
|
|
if (!cur)
|
1998-09-14 12:14:31 +04:00
|
|
|
vfs_die( "Free of thing which is unknown to me\n" );
|
1999-01-10 02:08:41 +03:00
|
|
|
unlink (cur->cache);
|
|
|
|
|
|
|
|
if (prev)
|
|
|
|
prev->next = cur->next;
|
|
|
|
else
|
|
|
|
head = cur->next;
|
2002-07-03 19:27:36 +04:00
|
|
|
|
|
|
|
g_free (cur->cache);
|
|
|
|
g_free (cur->name);
|
|
|
|
g_free (cur);
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
2004-08-16 20:34:11 +04:00
|
|
|
static void sfs_fill_names (struct vfs_class *me, fill_names_f func)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
|
|
|
struct cachedfile *cur = head;
|
|
|
|
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
while (cur){
|
|
|
|
(*func)(cur->name);
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int sfs_nothingisopen (vfsid id)
|
|
|
|
{
|
1998-12-31 18:54:49 +03:00
|
|
|
/* FIXME: Investigate whether have to guard this like in
|
|
|
|
the other VFSs (see fd_usage in extfs) -- Norbert */
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) id;
|
1998-12-31 18:54:49 +03:00
|
|
|
return 1;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
2003-10-28 05:10:33 +03:00
|
|
|
static char *
|
|
|
|
sfs_getlocalcopy (struct vfs_class *me, const char *path)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2003-10-28 03:57:02 +03:00
|
|
|
path = sfs_redirect (me, path);
|
1999-01-21 01:01:11 +03:00
|
|
|
return g_strdup (path);
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
2003-10-28 05:10:33 +03:00
|
|
|
static int
|
2003-10-29 00:52:06 +03:00
|
|
|
sfs_ungetlocalcopy (struct vfs_class *me, const char *path,
|
|
|
|
const char *local, int has_changed)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
(void) path;
|
|
|
|
(void) local;
|
|
|
|
(void) has_changed;
|
1999-11-11 17:23:40 +03:00
|
|
|
return 0;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
2003-10-12 04:24:00 +04:00
|
|
|
static int sfs_init (struct vfs_class *me)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
2001-05-30 16:05:50 +04:00
|
|
|
char *mc_sfsini;
|
|
|
|
FILE *cfg;
|
2004-08-14 14:56:09 +04:00
|
|
|
char key[256];
|
2001-05-30 16:05:50 +04:00
|
|
|
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
|
2002-07-03 19:27:36 +04:00
|
|
|
mc_sfsini = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR "sfs.ini");
|
2001-05-30 16:05:50 +04:00
|
|
|
cfg = fopen (mc_sfsini, "r");
|
1999-01-11 03:48:23 +03:00
|
|
|
|
|
|
|
if (!cfg){
|
2001-06-07 09:08:52 +04:00
|
|
|
fprintf (stderr, _("Warning: file %s not found\n"), mc_sfsini);
|
2001-08-11 08:57:17 +04:00
|
|
|
g_free (mc_sfsini);
|
2001-05-30 16:05:50 +04:00
|
|
|
return 0;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
2001-08-11 08:57:17 +04:00
|
|
|
g_free (mc_sfsini);
|
1998-08-25 20:00:16 +04:00
|
|
|
|
|
|
|
sfs_no = 0;
|
2004-08-14 14:56:09 +04:00
|
|
|
while (sfs_no < MAXFS && fgets (key, sizeof (key), cfg)) {
|
1998-08-25 20:00:16 +04:00
|
|
|
char *c, *semi = NULL, flags = 0;
|
|
|
|
|
2004-08-14 14:56:09 +04:00
|
|
|
if (*key == '#' || *key == '\n')
|
1998-08-25 20:00:16 +04:00
|
|
|
continue;
|
|
|
|
|
2001-06-16 02:32:15 +04:00
|
|
|
for (c = key; *c; c++)
|
|
|
|
if ((*c == ':') || (*c == '/')){
|
|
|
|
semi = c;
|
|
|
|
if (*c == '/'){
|
|
|
|
*c = 0;
|
1999-01-11 03:48:23 +03:00
|
|
|
flags |= F_FULLMATCH;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
1998-08-25 20:00:16 +04:00
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
if (!semi){
|
2004-08-14 14:56:09 +04:00
|
|
|
invalid_line:
|
2002-09-27 02:51:27 +04:00
|
|
|
fprintf (stderr, _("Warning: Invalid line in %s:\n%s\n"),
|
|
|
|
"sfs.ini", key);
|
1998-08-25 20:00:16 +04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = semi + 1;
|
2004-08-14 14:56:09 +04:00
|
|
|
while (*c && (*c != ' ') && (*c != '\t')) {
|
1998-08-25 20:00:16 +04:00
|
|
|
switch (*c) {
|
|
|
|
case '1': flags |= F_1; break;
|
|
|
|
case '2': flags |= F_2; break;
|
|
|
|
case 'R': flags |= F_NOLOCALCOPY; break;
|
|
|
|
default:
|
2002-09-27 02:51:27 +04:00
|
|
|
fprintf (stderr, _("Warning: Invalid flag %c in %s:\n%s\n"),
|
|
|
|
*c, "sfs.ini", key);
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
c++;
|
|
|
|
}
|
2004-08-14 14:56:09 +04:00
|
|
|
if (!*c)
|
|
|
|
goto invalid_line;
|
1998-08-25 20:00:16 +04:00
|
|
|
c++;
|
|
|
|
*(semi+1) = 0;
|
1999-01-11 03:48:23 +03:00
|
|
|
if ((semi = strchr (c, '\n')))
|
1998-08-25 20:00:16 +04:00
|
|
|
*semi = 0;
|
|
|
|
|
1999-01-21 01:01:11 +03:00
|
|
|
sfs_prefix [sfs_no] = g_strdup (key);
|
|
|
|
sfs_command [sfs_no] = g_strdup (c);
|
1998-08-25 20:00:16 +04:00
|
|
|
sfs_flags [sfs_no] = flags;
|
|
|
|
sfs_no++;
|
|
|
|
}
|
1999-01-11 03:48:23 +03:00
|
|
|
fclose (cfg);
|
1998-09-27 23:27:58 +04:00
|
|
|
return 1;
|
1998-08-25 20:00:16 +04:00
|
|
|
}
|
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
static void
|
2003-10-12 04:24:00 +04:00
|
|
|
sfs_done (struct vfs_class *me)
|
1998-09-14 12:14:31 +04:00
|
|
|
{
|
|
|
|
int i;
|
1999-01-11 03:48:23 +03:00
|
|
|
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
for (i = 0; i < sfs_no; i++){
|
1999-01-21 01:01:11 +03:00
|
|
|
g_free (sfs_prefix [i]);
|
|
|
|
g_free (sfs_command [i]);
|
1998-09-14 12:14:31 +04:00
|
|
|
sfs_prefix [i] = sfs_command [i] = NULL;
|
|
|
|
}
|
|
|
|
sfs_no = 0;
|
|
|
|
}
|
|
|
|
|
1999-01-11 03:48:23 +03:00
|
|
|
static int
|
2004-08-16 23:47:21 +04:00
|
|
|
sfs_which (struct vfs_class *me, const char *path)
|
1998-08-25 20:00:16 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2005-02-22 21:35:22 +03:00
|
|
|
(void) me;
|
|
|
|
|
1998-08-25 20:00:16 +04:00
|
|
|
for (i = 0; i < sfs_no; i++)
|
|
|
|
if (sfs_flags [i] & F_FULLMATCH) {
|
|
|
|
if (!strcmp (path, sfs_prefix [i]))
|
|
|
|
return i;
|
|
|
|
} else
|
1999-01-11 03:48:23 +03:00
|
|
|
if (!strncmp (path, sfs_prefix [i], strlen (sfs_prefix [i])))
|
1998-08-25 20:00:16 +04:00
|
|
|
return i;
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
1998-09-27 23:27:58 +04:00
|
|
|
|
2003-10-13 02:25:53 +04:00
|
|
|
void
|
|
|
|
init_sfs (void)
|
|
|
|
{
|
|
|
|
vfs_sfs_ops.name = "sfs";
|
|
|
|
vfs_sfs_ops.init = sfs_init;
|
|
|
|
vfs_sfs_ops.done = sfs_done;
|
|
|
|
vfs_sfs_ops.fill_names = sfs_fill_names;
|
|
|
|
vfs_sfs_ops.which = sfs_which;
|
|
|
|
vfs_sfs_ops.open = sfs_open;
|
|
|
|
vfs_sfs_ops.close = local_close;
|
|
|
|
vfs_sfs_ops.read = local_read;
|
|
|
|
vfs_sfs_ops.stat = sfs_stat;
|
|
|
|
vfs_sfs_ops.lstat = sfs_lstat;
|
|
|
|
vfs_sfs_ops.fstat = local_fstat;
|
|
|
|
vfs_sfs_ops.chmod = sfs_chmod;
|
|
|
|
vfs_sfs_ops.chown = sfs_chown;
|
|
|
|
vfs_sfs_ops.utime = sfs_utime;
|
|
|
|
vfs_sfs_ops.readlink = sfs_readlink;
|
|
|
|
vfs_sfs_ops.ferrno = local_errno;
|
|
|
|
vfs_sfs_ops.lseek = local_lseek;
|
|
|
|
vfs_sfs_ops.getid = sfs_getid;
|
|
|
|
vfs_sfs_ops.nothingisopen = sfs_nothingisopen;
|
|
|
|
vfs_sfs_ops.free = sfs_free;
|
|
|
|
vfs_sfs_ops.getlocalcopy = sfs_getlocalcopy;
|
|
|
|
vfs_sfs_ops.ungetlocalcopy = sfs_ungetlocalcopy;
|
|
|
|
vfs_register_class (&vfs_sfs_ops);
|
|
|
|
}
|