mc/vfs/extfs.c

1391 lines
35 KiB
C
Raw Normal View History

1998-02-27 07:54:42 +03:00
/* Virtual File System: External file system.
Copyright (C) 1995 The Free Software Foundation
Written by: 1995 Jakub Jelinek
Rewritten by: 1998 Pavel Machek
Additional changes by: 1999 Andrew T. Veliath
1998-02-27 07:54:42 +03:00
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.
1998-02-27 07:54:42 +03:00
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.
1998-02-27 07:54:42 +03:00
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. */
1998-02-27 07:54:42 +03:00
1998-10-13 02:07:53 +04:00
/* Namespace: exports only vfs_extfs_ops */
1998-02-27 07:54:42 +03:00
#include <config.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include <errno.h>
#include "utilvfs.h"
2003-06-22 13:18:12 +04:00
#include "../src/execute.h" /* For shell_execute */
1998-02-27 07:54:42 +03:00
#include "vfs.h"
#include "extfs.h"
#undef ERRNOR
#define ERRNOR(x,y) do { my_errno = x; return y; } while(0)
struct inode {
nlink_t nlink;
struct entry *first_in_subdir; /* only used if this is a directory */
struct entry *last_in_subdir;
ino_t inode; /* This is inode # */
dev_t dev; /* This is an internal identification of the extfs archive */
struct archive *archive; /* And this is an archive structure */
dev_t rdev;
mode_t mode;
uid_t uid;
gid_t gid;
int size;
time_t mtime;
char linkflag;
char *linkname;
time_t atime;
time_t ctime;
char *local_filename;
};
struct entry {
struct entry *next_in_dir;
struct entry *dir;
char *name;
struct inode *inode;
};
struct pseudofile {
struct archive *archive;
unsigned int has_changed:1;
int local_handle;
struct entry *entry;
};
static struct entry *
find_entry (struct entry *dir, char *name, int make_dirs, int make_file);
static int extfs_which (struct vfs_class *me, char *path);
static void remove_entry (struct entry *e);
static void extfs_free (vfsid id);
static struct vfs_class vfs_extfs_ops;
static struct archive *first_archive = NULL;
static int my_errno = 0;
1998-02-27 07:54:42 +03:00
#define MAXEXTFS 32
static char *extfs_prefixes [MAXEXTFS];
static char extfs_need_archive [MAXEXTFS];
static int extfs_no = 0;
static void extfs_fill_names (struct vfs_class *me, void (*func)(char *))
1998-02-27 07:54:42 +03:00
{
struct archive *a = first_archive;
1998-02-27 07:54:42 +03:00
char *name;
while (a){
name = g_strconcat (a->name ? a->name : "",
"#", extfs_prefixes [a->fstype],
PATH_SEP_STR, a->current_dir->name, NULL);
1998-02-27 07:54:42 +03:00
(*func)(name);
g_free (name);
1998-02-27 07:54:42 +03:00
a = a->next;
}
}
static void make_dot_doubledot (struct entry *ent)
1998-02-27 07:54:42 +03:00
{
struct entry *entry = g_new (struct entry, 1);
struct entry *parentry = ent->dir;
struct inode *inode = ent->inode, *parent;
1998-02-27 07:54:42 +03:00
parent = (parentry != NULL) ? parentry->inode : NULL;
entry->name = g_strdup (".");
1998-02-27 07:54:42 +03:00
entry->inode = inode;
entry->dir = ent;
inode->local_filename = NULL;
inode->first_in_subdir = entry;
inode->last_in_subdir = entry;
inode->nlink++;
entry->next_in_dir = g_new (struct entry, 1);
1998-02-27 07:54:42 +03:00
entry=entry->next_in_dir;
entry->name = g_strdup ("..");
1998-02-27 07:54:42 +03:00
inode->last_in_subdir = entry;
entry->next_in_dir = NULL;
if (parent != NULL) {
entry->inode = parent;
entry->dir = parentry;
parent->nlink++;
} else {
entry->inode = inode;
entry->dir = ent;
inode->nlink++;
}
}
static struct entry *generate_entry (struct archive *archive,
char *name, struct entry *parentry, mode_t mode)
1998-02-27 07:54:42 +03:00
{
mode_t myumask;
struct inode *inode, *parent;
struct entry *entry;
1998-02-27 07:54:42 +03:00
parent = (parentry != NULL) ? parentry->inode : NULL;
entry = g_new (struct entry, 1);
1998-02-27 07:54:42 +03:00
entry->name = g_strdup (name);
1998-02-27 07:54:42 +03:00
entry->next_in_dir = NULL;
entry->dir = parentry;
if (parent != NULL) {
parent->last_in_subdir->next_in_dir = entry;
parent->last_in_subdir = entry;
}
inode = g_new (struct inode, 1);
1998-02-27 07:54:42 +03:00
entry->inode = inode;
inode->local_filename = NULL;
inode->linkname = 0;
inode->inode = (archive->__inode_counter)++;
inode->dev = archive->rdev;
inode->archive = archive;
myumask = umask (022);
umask (myumask);
inode->mode = mode & ~myumask;
mode = inode->mode;
inode->rdev = 0;
inode->uid = getuid ();
inode->gid = getgid ();
inode->size = 0;
inode->mtime = time (NULL);
inode->atime = inode->mtime;
inode->ctime = inode->mtime;
inode->nlink = 1;
if (S_ISDIR (mode))
make_dot_doubledot (entry);
return entry;
}
static void free_entries (struct entry *entry)
1998-02-27 07:54:42 +03:00
{
return;
}
static void free_archive (struct archive *archive)
1998-02-27 07:54:42 +03:00
{
free_entries (archive->root_entry);
if (archive->local_name != NULL) {
struct stat my;
mc_stat (archive->local_name, &my);
mc_ungetlocalcopy (archive->name, archive->local_name,
archive->local_stat.st_mtime != my.st_mtime);
/* ungetlocalcopy frees local_name for us */
}
if (archive->name)
g_free (archive->name);
g_free (archive);
1998-02-27 07:54:42 +03:00
}
static FILE *
open_archive (int fstype, char *name, struct archive **pparc)
1998-02-27 07:54:42 +03:00
{
static dev_t __extfs_no = 0;
FILE *result;
mode_t mode;
char *cmd;
char *mc_extfsdir;
1998-02-27 07:54:42 +03:00
struct stat mystat;
struct archive *current_archive;
struct entry *root_entry;
1998-02-27 07:54:42 +03:00
char *local_name = NULL, *tmp = 0;
int uses_archive = extfs_need_archive[fstype];
if (uses_archive) {
1998-02-27 07:54:42 +03:00
if (mc_stat (name, &mystat) == -1)
return NULL;
if (!vfs_file_is_local (name)) {
local_name = mc_getlocalcopy (name);
if (local_name == NULL)
return NULL;
}
tmp = name_quote (name, 0);
1998-02-27 07:54:42 +03:00
}
mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
cmd =
g_strconcat (mc_extfsdir, extfs_prefixes[fstype], " list ",
local_name ? local_name : tmp, NULL);
1998-02-27 07:54:42 +03:00
if (tmp)
g_free (tmp);
2000-01-13 18:15:42 +03:00
g_free (mc_extfsdir);
open_error_pipe ();
1998-02-27 07:54:42 +03:00
result = popen (cmd, "r");
g_free (cmd);
1998-02-27 07:54:42 +03:00
if (result == NULL) {
close_error_pipe (1, NULL);
if (local_name)
mc_ungetlocalcopy (name, local_name, 0);
return NULL;
1998-02-27 07:54:42 +03:00
}
current_archive = g_new (struct archive, 1);
1998-02-27 07:54:42 +03:00
current_archive->fstype = fstype;
current_archive->name = name ? g_strdup (name) : name;
1998-02-27 07:54:42 +03:00
current_archive->local_name = local_name;
1998-02-27 07:54:42 +03:00
if (local_name != NULL)
mc_stat (local_name, &current_archive->local_stat);
1998-02-27 07:54:42 +03:00
current_archive->__inode_counter = 0;
current_archive->fd_usage = 0;
current_archive->rdev = __extfs_no++;
current_archive->next = first_archive;
first_archive = current_archive;
mode = mystat.st_mode & 07777;
1998-02-27 07:54:42 +03:00
if (mode & 0400)
mode |= 0100;
1998-02-27 07:54:42 +03:00
if (mode & 0040)
mode |= 0010;
1998-02-27 07:54:42 +03:00
if (mode & 0004)
mode |= 0001;
1998-02-27 07:54:42 +03:00
mode |= S_IFDIR;
root_entry = generate_entry (current_archive, "/", NULL, mode);
root_entry->inode->uid = mystat.st_uid;
root_entry->inode->gid = mystat.st_gid;
root_entry->inode->atime = mystat.st_atime;
root_entry->inode->ctime = mystat.st_ctime;
root_entry->inode->mtime = mystat.st_mtime;
1998-02-27 07:54:42 +03:00
current_archive->root_entry = root_entry;
current_archive->current_dir = root_entry;
1998-02-27 07:54:42 +03:00
*pparc = current_archive;
return result;
}
/*
* Main loop for reading an archive.
* Return 0 on success, -1 on error.
1998-02-27 07:54:42 +03:00
*/
static int
read_archive (int fstype, char *name, struct archive **pparc)
1998-02-27 07:54:42 +03:00
{
FILE *extfsd;
char *buffer;
struct archive *current_archive;
char *current_file_name, *current_link_name;
if ((extfsd = open_archive (fstype, name, &current_archive)) == NULL) {
message (1, MSG_ERROR, _("Cannot open %s archive\n%s"),
extfs_prefixes[fstype], name);
1998-02-27 07:54:42 +03:00
return -1;
}
buffer = g_malloc (4096);
1998-02-27 07:54:42 +03:00
while (fgets (buffer, 4096, extfsd) != NULL) {
struct stat hstat;
current_link_name = NULL;
if (vfs_parse_ls_lga
(buffer, &hstat, &current_file_name, &current_link_name)) {
struct entry *entry, *pent;
struct inode *inode;
char *p, *q, *cfn = current_file_name;
if (*cfn) {
if (*cfn == '/')
cfn++;
p = strchr (cfn, 0);
if (p != cfn && *(p - 1) == '/')
*(p - 1) = 0;
p = strrchr (cfn, '/');
if (p == NULL) {
p = cfn;
q = strchr (cfn, 0);
} else {
*(p++) = 0;
q = cfn;
}
if (S_ISDIR (hstat.st_mode)
&& (!strcmp (p, ".") || !strcmp (p, "..")))
goto read_extfs_continue;
pent = find_entry (current_archive->root_entry, q, 1, 0);
if (pent == NULL) {
/* FIXME: Should clean everything one day */
g_free (buffer);
1998-02-27 07:54:42 +03:00
pclose (extfsd);
close_error_pipe (1, _("Inconsistent extfs archive"));
return -1;
}
entry = g_new (struct entry, 1);
entry->name = g_strdup (p);
1998-02-27 07:54:42 +03:00
entry->next_in_dir = NULL;
entry->dir = pent;
if (pent != NULL) {
if (pent->inode->last_in_subdir) {
1998-02-27 07:54:42 +03:00
pent->inode->last_in_subdir->next_in_dir = entry;
pent->inode->last_in_subdir = entry;
}
}
if (!S_ISLNK (hstat.st_mode) && current_link_name != NULL) {
pent =
find_entry (current_archive->root_entry,
current_link_name, 0, 0);
if (pent == NULL) {
/* FIXME: Should clean everything one day */
g_free (buffer);
1998-02-27 07:54:42 +03:00
pclose (extfsd);
close_error_pipe (1,
_("Inconsistent extfs archive"));
return -1;
} else {
1998-02-27 07:54:42 +03:00
entry->inode = pent->inode;
pent->inode->nlink++;
}
} else {
inode = g_new (struct inode, 1);
1998-02-27 07:54:42 +03:00
entry->inode = inode;
inode->local_filename = NULL;
inode->inode = (current_archive->__inode_counter)++;
inode->nlink = 1;
inode->dev = current_archive->rdev;
inode->archive = current_archive;
inode->mode = hstat.st_mode;
#ifdef HAVE_ST_RDEV
1998-02-27 07:54:42 +03:00
inode->rdev = hstat.st_rdev;
#else
inode->rdev = 0;
#endif
1998-02-27 07:54:42 +03:00
inode->uid = hstat.st_uid;
inode->gid = hstat.st_gid;
inode->size = hstat.st_size;
inode->mtime = hstat.st_mtime;
inode->atime = hstat.st_atime;
inode->ctime = hstat.st_ctime;
if (current_link_name != NULL
&& S_ISLNK (hstat.st_mode)) {
inode->linkname = current_link_name;
current_link_name = NULL;
1998-02-27 07:54:42 +03:00
} else {
if (S_ISLNK (hstat.st_mode))
inode->mode &= ~S_IFLNK; /* You *DON'T* want to do this always */
inode->linkname = NULL;
1998-02-27 07:54:42 +03:00
}
if (S_ISDIR (hstat.st_mode))
make_dot_doubledot (entry);
}
}
read_extfs_continue:
g_free (current_file_name);
if (current_link_name != NULL)
g_free (current_link_name);
}
1998-02-27 07:54:42 +03:00
}
/* Check if extfs 'list' returned 0 */
if (pclose (extfsd) != 0) {
g_free (buffer);
extfs_free (current_archive);
close_error_pipe (1, _("Inconsistent extfs archive"));
return -1;
}
close_error_pipe (1, NULL);
1998-02-27 07:54:42 +03:00
*pparc = current_archive;
g_free (buffer);
1998-02-27 07:54:42 +03:00
return 0;
}
/* Returns path inside argument. Returned char* is inside inname, which is
* mangled by this operation (so you must not free it's return value).
*/
static char *
get_path_mangle (char *inname, struct archive **archive, int is_dir,
int do_not_open)
1998-02-27 07:54:42 +03:00
{
char *local, *archive_name, *op;
1998-02-27 07:54:42 +03:00
int result = -1;
struct archive *parc;
1998-02-27 07:54:42 +03:00
struct vfs_stamping *parent;
struct vfs_class *v;
1998-02-27 07:54:42 +03:00
int fstype;
archive_name = inname;
vfs_split (inname, &local, &op);
/*
* FIXME: we really should pass self pointer. But as we know that
* extfs_which does not touch struct vfs_class *me, it does not matter for now
*/
fstype = extfs_which (NULL, op);
if (fstype == -1)
return NULL;
if (!local)
local = "";
1998-02-27 07:54:42 +03:00
/*
* All filesystems should have some local archive, at least
* it can be '/'.
1998-02-27 07:54:42 +03:00
*/
for (parc = first_archive; parc != NULL; parc = parc->next)
if (parc->name) {
if (!strcmp (parc->name, archive_name)) {
vfs_stamp (&vfs_extfs_ops, (vfsid) parc);
1998-02-27 07:54:42 +03:00
goto return_success;
}
}
result = do_not_open ? -1 : read_archive (fstype, archive_name, &parc);
if (result == -1)
ERRNOR (EIO, NULL);
if (archive_name) {
v = vfs_get_class (archive_name);
if (v->flags & VFSF_LOCAL) {
1998-02-27 07:54:42 +03:00
parent = NULL;
} else {
parent = g_new (struct vfs_stamping, 1);
1998-02-27 07:54:42 +03:00
parent->v = v;
parent->next = 0;
parent->id = (*v->getid) (v, archive_name, &(parent->parent));
1998-02-27 07:54:42 +03:00
}
1998-10-13 02:07:53 +04:00
vfs_add_noncurrent_stamps (&vfs_extfs_ops, (vfsid) parc, parent);
1998-02-27 07:54:42 +03:00
}
return_success:
1998-02-27 07:54:42 +03:00
*archive = parc;
return local;
}
static char *
get_path (const char *inname, struct archive **archive, int is_dir,
int do_not_open)
{
char *buf = g_strdup (inname);
char *res = get_path_mangle (buf, archive, is_dir, do_not_open);
char *res2 = NULL;
if (res)
res2 = g_strdup (res);
g_free (buf);
return res2;
}
1998-02-27 07:54:42 +03:00
/* Returns allocated path (without leading slash) inside the archive */
static char *get_path_from_entry (struct entry *entry)
1998-02-27 07:54:42 +03:00
{
struct list {
struct list *next;
char *name;
} *head, *p;
char *localpath;
size_t len;
for (len = 0, head = 0; entry->dir; entry = entry->dir) {
p = g_new (struct list, 1);
1998-02-27 07:54:42 +03:00
p->next = head;
p->name = entry->name;
head = p;
len += strlen (entry->name) + 1;
}
if (len == 0)
2000-01-13 18:15:42 +03:00
return g_strdup ("");
1998-02-27 07:54:42 +03:00
localpath = g_malloc (len);
1998-02-27 07:54:42 +03:00
*localpath = '\0';
2000-01-13 18:15:42 +03:00
while (head) {
1998-02-27 07:54:42 +03:00
strcat (localpath, head->name);
if (head->next)
strcat (localpath, "/");
p = head;
head = head->next;
g_free (p);
1998-02-27 07:54:42 +03:00
}
return (localpath);
}
struct loop_protect {
struct entry *entry;
struct loop_protect *next;
1998-02-27 07:54:42 +03:00
};
static int errloop;
static int notadir;
static struct entry *
__find_entry (struct entry *dir, char *name,
struct loop_protect *list, int make_dirs, int make_file);
1998-02-27 07:54:42 +03:00
static struct entry *
__resolve_symlinks (struct entry *entry,
struct loop_protect *list)
1998-02-27 07:54:42 +03:00
{
struct entry *pent;
struct loop_protect *looping;
1998-02-27 07:54:42 +03:00
if (!S_ISLNK (entry->inode->mode))
return entry;
for (looping = list; looping != NULL; looping = looping->next)
if (entry == looping->entry) { /* Here we protect us against symlink looping */
errloop = 1;
return NULL;
}
looping = g_new (struct loop_protect, 1);
1998-02-27 07:54:42 +03:00
looping->entry = entry;
looping->next = list;
pent = __find_entry (entry->dir, entry->inode->linkname, looping, 0, 0);
g_free (looping);
1998-02-27 07:54:42 +03:00
if (pent == NULL)
my_errno = ENOENT;
1998-02-27 07:54:42 +03:00
return pent;
}
static struct entry *my_resolve_symlinks (struct entry *entry)
1998-02-27 07:54:42 +03:00
{
struct entry *res;
1998-02-27 07:54:42 +03:00
errloop = 0;
notadir = 0;
res = __resolve_symlinks (entry, NULL);
1998-02-27 07:54:42 +03:00
if (res == NULL) {
if (errloop)
my_errno = ELOOP;
1998-02-27 07:54:42 +03:00
else if (notadir)
my_errno = ENOTDIR;
1998-02-27 07:54:42 +03:00
}
return res;
}
static char *get_archive_name (struct archive *archive)
1998-02-27 07:54:42 +03:00
{
char *archive_name;
if (archive->local_name)
archive_name = archive->local_name;
else
archive_name = archive->name;
if (!archive_name || !*archive_name)
return "no_archive_name";
else
return archive_name;
}
/* Don't pass localname as NULL */
static int
extfs_cmd (const char *extfs_cmd, struct archive *archive,
struct entry *entry, const char *localname)
{
char *file;
char *quoted_file;
char *quoted_localname;
char *archive_name;
char *mc_extfsdir;
char *cmd;
int retval;
file = get_path_from_entry (entry);
quoted_file = name_quote (file, 0);
g_free (file);
archive_name = name_quote (get_archive_name (archive), 0);
quoted_localname = name_quote (localname, 0);
mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
cmd = g_strconcat (mc_extfsdir, extfs_prefixes[archive->fstype],
extfs_cmd, archive_name, " ", quoted_file, " ",
quoted_localname, NULL);
g_free (quoted_file);
g_free (quoted_localname);
g_free (mc_extfsdir);
g_free (archive_name);
open_error_pipe ();
retval = my_system (EXECUTE_AS_SHELL, shell, cmd);
g_free (cmd);
close_error_pipe (1, NULL);
return retval;
}
static void
extfs_run (char *file)
1998-02-27 07:54:42 +03:00
{
struct archive *archive;
char *p, *q, *archive_name, *mc_extfsdir;
char *cmd;
1998-02-27 07:54:42 +03:00
if ((p = get_path (file, &archive, 0, 0)) == NULL)
1998-02-27 07:54:42 +03:00
return;
q = name_quote (p, 0);
g_free (p);
archive_name = name_quote (get_archive_name (archive), 0);
mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
cmd = g_strconcat (mc_extfsdir, extfs_prefixes[archive->fstype],
" run ", archive_name, " ", q, NULL);
g_free (mc_extfsdir);
g_free (archive_name);
g_free (q);
shell_execute (cmd, 0);
g_free (cmd);
1998-02-27 07:54:42 +03:00
}
static void *
extfs_open (struct vfs_class *me, char *file, int flags, int mode)
1998-02-27 07:54:42 +03:00
{
struct pseudofile *extfs_info;
struct archive *archive;
char *q;
struct entry *entry;
1998-02-27 07:54:42 +03:00
int local_handle;
int created = 0;
if ((q = get_path_mangle (file, &archive, 0, 0)) == NULL)
1998-02-27 07:54:42 +03:00
return NULL;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL && (flags & O_CREAT)) {
/* Create new entry */
entry = find_entry (archive->root_entry, q, 0, 1);
created = (entry != NULL);
}
if (entry == NULL)
return NULL;
if ((entry = my_resolve_symlinks (entry)) == NULL)
1998-02-27 07:54:42 +03:00
return NULL;
if (S_ISDIR (entry->inode->mode))
ERRNOR (EISDIR, NULL);
1998-02-27 07:54:42 +03:00
if (entry->inode->local_filename == NULL) {
char *local_filename, *suffix;
/* retain original filename as a suffix for a temporary filename */
suffix = g_strconcat ("-", entry->name, NULL);
if ((local_handle =
mc_mkstemps (&local_filename, "extfs", suffix)) == -1) {
/* fallback for the case if the filename is too long */
local_handle = mc_mkstemps (&local_filename, "extfs", NULL);
}
g_free (suffix);
if (local_handle == -1)
return NULL;
close (local_handle);
if (!created && !(flags & O_TRUNC)
&& extfs_cmd (" copyout ", archive, entry, local_filename)) {
unlink (local_filename);
free (local_filename);
my_errno = EIO;
return NULL;
}
entry->inode->local_filename = local_filename;
1998-02-27 07:54:42 +03:00
}
local_handle =
open (entry->inode->local_filename, NO_LINEAR (flags), mode);
if (local_handle == -1)
ERRNOR (EIO, NULL);
extfs_info = g_new (struct pseudofile, 1);
1998-02-27 07:54:42 +03:00
extfs_info->archive = archive;
extfs_info->entry = entry;
extfs_info->has_changed = created;
1998-02-27 07:54:42 +03:00
extfs_info->local_handle = local_handle;
/* i.e. we had no open files and now we have one */
1998-10-13 02:07:53 +04:00
vfs_rmstamp (&vfs_extfs_ops, (vfsid) archive, 1);
1998-02-27 07:54:42 +03:00
archive->fd_usage++;
return extfs_info;
}
static int extfs_read (void *data, char *buffer, int count)
{
struct pseudofile *file = (struct pseudofile *)data;
1998-02-27 07:54:42 +03:00
return read (file->local_handle, buffer, count);
}
static int
extfs_close (void *data)
1998-02-27 07:54:42 +03:00
{
struct pseudofile *file;
int errno_code = 0;
file = (struct pseudofile *) data;
1998-02-27 07:54:42 +03:00
close (file->local_handle);
/* Commit the file if it has changed */
if (file->has_changed) {
if (extfs_cmd
(" copyin ", file->archive, file->entry,
file->entry->inode->local_filename))
1998-02-27 07:54:42 +03:00
errno_code = EIO;
2000-01-13 18:15:42 +03:00
{
struct stat file_status;
if (stat (file->entry->inode->local_filename, &file_status) !=
0)
errno_code = EIO;
2000-01-13 18:15:42 +03:00
else
file->entry->inode->size = file_status.st_size;
}
file->entry->inode->mtime = time (NULL);
1998-02-27 07:54:42 +03:00
}
1998-02-27 07:54:42 +03:00
file->archive->fd_usage--;
if (!file->archive->fd_usage) {
struct vfs_stamping *parent;
struct vfs_class *v;
if (!file->archive->name || !*file->archive->name
|| (v =
vfs_get_class (file->archive->name))->flags & VFSF_LOCAL) {
1998-02-27 07:54:42 +03:00
parent = NULL;
} else {
parent = g_new (struct vfs_stamping, 1);
1998-02-27 07:54:42 +03:00
parent->v = v;
parent->next = 0;
parent->id =
(*v->getid) (v, file->archive->name, &(parent->parent));
1998-02-27 07:54:42 +03:00
}
vfs_add_noncurrent_stamps (&vfs_extfs_ops, (vfsid) (file->archive),
parent);
1998-02-27 07:54:42 +03:00
}
g_free (data);
if (errno_code)
ERRNOR (EIO, -1);
return 0;
1998-02-27 07:54:42 +03:00
}
#define RECORDSIZE 512
static struct entry*
__find_entry (struct entry *dir, char *name,
struct loop_protect *list, int make_dirs, int make_file)
{
struct entry *pent, *pdir;
char *p, *q, *name_end;
char c;
if (*name == '/') { /* Handle absolute paths */
name++;
dir = dir->inode->archive->root_entry;
}
pent = dir;
p = name;
name_end = name + strlen (name);
q = strchr (p, '/');
c = '/';
if (!q)
q = strchr (p, 0);
for (; pent != NULL && c && *p; ){
c = *q;
*q = 0;
if (strcmp (p, ".")){
if (!strcmp (p, ".."))
pent = pent->dir;
else {
if ((pent = __resolve_symlinks (pent, list))==NULL){
*q = c;
return NULL;
}
if (!S_ISDIR (pent->inode->mode)){
*q = c;
notadir = 1;
return NULL;
}
pdir = pent;
for (pent = pent->inode->first_in_subdir; pent; pent = pent->next_in_dir)
/* Hack: I keep the original semanthic unless
q+1 would break in the strchr */
if (!strcmp (pent->name, p)){
if (q + 1 > name_end){
*q = c;
notadir = !S_ISDIR (pent->inode->mode);
return pent;
}
break;
}
/* When we load archive, we create automagically
* non-existant directories
*/
if (pent == NULL && make_dirs) {
pent = generate_entry (dir->inode->archive, p, pdir, S_IFDIR | 0777);
}
if (pent == NULL && make_file) {
pent = generate_entry (dir->inode->archive, p, pdir, S_IFREG | 0666);
}
}
}
/* Next iteration */
*q = c;
p = q + 1;
q = strchr (p, '/');
if (!q)
q = strchr (p, 0);
}
if (pent == NULL)
my_errno = ENOENT;
return pent;
}
static struct entry *find_entry (struct entry *dir, char *name, int make_dirs, int make_file)
{
struct entry *res;
errloop = 0;
notadir = 0;
res = __find_entry (dir, name, NULL, make_dirs, make_file);
if (res == NULL) {
if (errloop)
my_errno = ELOOP;
else if (notadir)
my_errno = ENOTDIR;
}
return res;
}
static int s_errno (struct vfs_class *me)
{
return my_errno;
}
static void * s_opendir (struct vfs_class *me, char *dirname)
{
struct archive *archive;
char *q;
struct entry *entry;
struct entry **info;
if ((q = get_path_mangle (dirname, &archive, 1, 0)) == NULL)
return NULL;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return NULL;
if ((entry = my_resolve_symlinks (entry)) == NULL)
return NULL;
if (!S_ISDIR (entry->inode->mode)) ERRNOR (ENOTDIR, NULL);
info = g_new (struct entry *, 2);
info[0] = entry->inode->first_in_subdir;
info[1] = entry->inode->first_in_subdir;
return info;
}
static void * s_readdir(void *data)
{
static union vfs_dirent dir;
struct entry **info = (struct entry **) data;
if (!*info)
return NULL;
strncpy(dir.dent.d_name, (*info)->name, MC_MAXPATHLEN);
dir.dent.d_name[MC_MAXPATHLEN] = 0;
compute_namelen(&dir.dent);
*info = (*info)->next_in_dir;
return (void *) &dir;
}
static int s_closedir (void *data)
{
g_free (data);
return 0;
}
static void stat_move( struct stat *buf, struct inode *inode )
{
buf->st_dev = inode->dev;
buf->st_ino = inode->inode;
buf->st_mode = inode->mode;
buf->st_nlink = inode->nlink;
buf->st_uid = inode->uid;
buf->st_gid = inode->gid;
#ifdef HAVE_ST_RDEV
buf->st_rdev = inode->rdev;
#endif
buf->st_size = inode->size;
#ifdef HAVE_ST_BLKSIZE
buf->st_blksize = RECORDSIZE;
#endif
#ifdef HAVE_ST_BLOCKS
buf->st_blocks = (inode->size + RECORDSIZE - 1) / RECORDSIZE;
#endif
buf->st_atime = inode->atime;
buf->st_mtime = inode->mtime;
buf->st_ctime = inode->ctime;
}
static int s_internal_stat (char *path, struct stat *buf, int resolve)
{
struct archive *archive;
char *q;
struct entry *entry;
struct inode *inode;
if ((q = get_path_mangle (path, &archive, 0, 0)) == NULL)
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if (resolve && (entry = my_resolve_symlinks (entry)) == NULL)
return -1;
inode = entry->inode;
stat_move( buf, inode );
return 0;
}
static int s_stat (struct vfs_class *me, char *path, struct stat *buf)
{
return s_internal_stat (path, buf, 1);
}
static int s_lstat (struct vfs_class *me, char *path, struct stat *buf)
{
return s_internal_stat (path, buf, 0);
}
static int s_fstat (void *data, struct stat *buf)
{
struct pseudofile *file = (struct pseudofile *)data;
struct inode *inode;
inode = file->entry->inode;
stat_move( buf, inode );
return 0;
}
static int
s_readlink (struct vfs_class *me, char *path, char *buf, int size)
{
struct archive *archive;
char *q;
int i;
struct entry *entry;
if ((q = get_path_mangle (path, &archive, 0, 0)) == NULL)
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if (!S_ISLNK (entry->inode->mode))
ERRNOR (EINVAL, -1);
if (size < (i = strlen (entry->inode->linkname))) {
i = size;
}
strncpy (buf, entry->inode->linkname, i);
return i;
}
1998-02-27 07:54:42 +03:00
static int extfs_chmod (struct vfs_class *me, char *path, int mode)
1998-02-27 07:54:42 +03:00
{
return 0;
}
static int extfs_write (void *data, char *buf, int nbyte)
{
struct pseudofile *file = (struct pseudofile *)data;
1998-02-27 07:54:42 +03:00
file->has_changed = 1;
return write (file->local_handle, buf, nbyte);
}
static int extfs_unlink (struct vfs_class *me, char *file)
{
struct archive *archive;
char *q;
struct entry *entry;
if ((q = get_path_mangle (file, &archive, 0, 0)) == NULL)
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if ((entry = my_resolve_symlinks (entry)) == NULL)
return -1;
if (S_ISDIR (entry->inode->mode)) ERRNOR (EISDIR, -1);
if (extfs_cmd (" rm ", archive, entry, "")){
2000-01-13 18:15:42 +03:00
my_errno = EIO;
return -1;
}
remove_entry (entry);
return 0;
}
static int extfs_mkdir (struct vfs_class *me, char *path, mode_t mode)
{
struct archive *archive;
char *q;
struct entry *entry;
if ((q = get_path_mangle (path, &archive, 0, 0)) == NULL)
2000-01-13 18:15:42 +03:00
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry != NULL) ERRNOR (EEXIST, -1);
entry = find_entry (archive->root_entry, q, 1, 0);
if (entry == NULL)
2000-01-13 18:15:42 +03:00
return -1;
if ((entry = my_resolve_symlinks (entry)) == NULL)
return -1;
if (!S_ISDIR (entry->inode->mode)) ERRNOR (ENOTDIR, -1);
if (extfs_cmd (" mkdir ", archive, entry, "")){
2000-01-13 18:15:42 +03:00
my_errno = EIO;
remove_entry (entry);
return -1;
}
return 0;
}
static int extfs_rmdir (struct vfs_class *me, char *path)
{
struct archive *archive;
char *q;
struct entry *entry;
if ((q = get_path_mangle (path, &archive, 0, 0)) == NULL)
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (entry == NULL)
return -1;
if ((entry = my_resolve_symlinks (entry)) == NULL)
return -1;
if (!S_ISDIR (entry->inode->mode)) ERRNOR (ENOTDIR, -1);
if (extfs_cmd (" rmdir ", archive, entry, "")){
2000-01-13 18:15:42 +03:00
my_errno = EIO;
return -1;
}
remove_entry (entry);
return 0;
}
static int extfs_chdir (struct vfs_class *me, char *path)
1998-02-27 07:54:42 +03:00
{
struct archive *archive;
2000-01-13 18:15:42 +03:00
char *q;
struct entry *entry;
1998-02-27 07:54:42 +03:00
my_errno = ENOTDIR;
if ((q = get_path_mangle (path, &archive, 1, 0)) == NULL)
1998-02-27 07:54:42 +03:00
return -1;
entry = find_entry (archive->root_entry, q, 0, 0);
if (!entry)
1998-02-27 07:54:42 +03:00
return -1;
entry = my_resolve_symlinks (entry);
if ((!entry) || (!S_ISDIR (entry->inode->mode)))
1998-02-27 07:54:42 +03:00
return -1;
entry->inode->archive->current_dir = entry;
my_errno = 0;
1998-02-27 07:54:42 +03:00
return 0;
}
static int extfs_lseek (void *data, off_t offset, int whence)
{
struct pseudofile *file = (struct pseudofile *) data;
1998-02-27 07:54:42 +03:00
return lseek (file->local_handle, offset, whence);
}
static vfsid extfs_getid (struct vfs_class *me, const char *path, struct vfs_stamping **parent)
1998-02-27 07:54:42 +03:00
{
struct archive *archive;
struct vfs_class *v;
1998-02-27 07:54:42 +03:00
vfsid id;
struct vfs_stamping *par;
char *p;
1998-02-27 07:54:42 +03:00
*parent = NULL;
if (!(p = get_path (path, &archive, 1, 1)))
1998-02-27 07:54:42 +03:00
return (vfsid) -1;
g_free(p);
1998-02-27 07:54:42 +03:00
if (archive->name){
v = vfs_get_class (archive->name);
id = (*v->getid) (v, archive->name, &par);
1998-02-27 07:54:42 +03:00
if (id != (vfsid)-1) {
*parent = g_new (struct vfs_stamping, 1);
1998-02-27 07:54:42 +03:00
(*parent)->v = v;
(*parent)->id = id;
(*parent)->parent = par;
(*parent)->next = NULL;
}
}
return (vfsid) archive;
}
static int extfs_nothingisopen (vfsid id)
{
if (((struct archive *)id)->fd_usage <= 0)
1998-02-27 07:54:42 +03:00
return 1;
2000-01-13 18:15:42 +03:00
return 0;
1998-02-27 07:54:42 +03:00
}
static void remove_entry (struct entry *e)
{
int i = --(e->inode->nlink);
struct entry *pe, *ent, *prev;
if (S_ISDIR (e->inode->mode) && e->inode->first_in_subdir != NULL) {
struct entry *f = e->inode->first_in_subdir;
e->inode->first_in_subdir = NULL;
remove_entry (f);
}
pe = e->dir;
if (e == pe->inode->first_in_subdir)
2000-01-13 18:15:42 +03:00
pe->inode->first_in_subdir = e->next_in_dir;
prev = NULL;
for (ent = pe->inode->first_in_subdir; ent && ent->next_in_dir;
ent = ent->next_in_dir)
if (e == ent->next_in_dir) {
2000-01-13 18:15:42 +03:00
prev = ent;
break;
}
if (prev)
2000-01-13 18:15:42 +03:00
prev->next_in_dir = e->next_in_dir;
if (e == pe->inode->last_in_subdir)
2000-01-13 18:15:42 +03:00
pe->inode->last_in_subdir = prev;
if (i <= 0) {
if (e->inode->local_filename != NULL) {
unlink (e->inode->local_filename);
free (e->inode->local_filename);
}
if (e->inode->linkname != NULL)
g_free (e->inode->linkname);
g_free (e->inode);
}
g_free (e->name);
g_free (e);
}
static void free_entry (struct entry *e)
1998-02-27 07:54:42 +03:00
{
int i = --(e->inode->nlink);
if (S_ISDIR (e->inode->mode) && e->inode->first_in_subdir != NULL) {
struct entry *f = e->inode->first_in_subdir;
1998-02-27 07:54:42 +03:00
e->inode->first_in_subdir = NULL;
free_entry (f);
}
if (i <= 0) {
if (e->inode->local_filename != NULL) {
unlink (e->inode->local_filename);
free (e->inode->local_filename);
1998-02-27 07:54:42 +03:00
}
if (e->inode->linkname != NULL)
g_free (e->inode->linkname);
g_free (e->inode);
1998-02-27 07:54:42 +03:00
}
if (e->next_in_dir != NULL)
free_entry (e->next_in_dir);
g_free (e->name);
g_free (e);
1998-02-27 07:54:42 +03:00
}
static void extfs_free (vfsid id)
{
struct archive *parc;
struct archive *archive = (struct archive *)id;
1998-02-27 07:54:42 +03:00
free_entry (archive->root_entry);
if (archive == first_archive) {
first_archive = archive->next;
} else {
for (parc = first_archive; parc != NULL; parc = parc->next)
if (parc->next == archive)
break;
if (parc != NULL)
parc->next = archive->next;
}
free_archive (archive);
}
static char *extfs_getlocalcopy (struct vfs_class *me, char *path)
1998-02-27 07:54:42 +03:00
{
struct pseudofile *fp =
(struct pseudofile *) extfs_open (me, path, O_RDONLY, 0);
1998-02-27 07:54:42 +03:00
char *p;
if (fp == NULL)
return NULL;
if (fp->entry->inode->local_filename == NULL) {
extfs_close ((void *) fp);
return NULL;
}
p = g_strdup (fp->entry->inode->local_filename);
1998-02-27 07:54:42 +03:00
fp->archive->fd_usage++;
extfs_close ((void *) fp);
return p;
}
static int extfs_ungetlocalcopy (struct vfs_class *me, char *path, char *local, int has_changed)
1998-02-27 07:54:42 +03:00
{
struct pseudofile *fp =
(struct pseudofile *) extfs_open (me, path, O_RDONLY, 0);
1998-02-27 07:54:42 +03:00
if (fp == NULL)
return 0;
1998-02-27 07:54:42 +03:00
if (!strcmp (fp->entry->inode->local_filename, local)) {
fp->archive->fd_usage--;
fp->has_changed |= has_changed;
1998-02-27 07:54:42 +03:00
extfs_close ((void *) fp);
return 0;
1998-02-27 07:54:42 +03:00
} else {
/* Should not happen */
extfs_close ((void *) fp);
return mc_def_ungetlocalcopy (me, path, local, has_changed);
1998-02-27 07:54:42 +03:00
}
}
static int extfs_init (struct vfs_class *me)
1998-02-27 07:54:42 +03:00
{
FILE *cfg;
char *mc_extfsini;
mc_extfsini = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR "extfs.ini");
cfg = fopen (mc_extfsini, "r");
/* We may not use vfs_die() message or message or similar,
* UI is not initialized at this time and message would not
* appear on screen. */
if (!cfg) {
fprintf(stderr, _("Warning: file %s not found\n"), mc_extfsini);
g_free (mc_extfsini);
return 0;
}
1998-02-27 07:54:42 +03:00
extfs_no = 0;
while ( extfs_no < MAXEXTFS ) {
char key[256];
char *c;
if (!fgets( key, sizeof (key)-1, cfg ))
break;
1998-02-27 07:54:42 +03:00
/* Handle those with a trailing ':', those flag that the
* file system does not require an archive to work
*/
if (*key == '[') {
fprintf(stderr, "Warning: You need to update your %s file.\n",
mc_extfsini);
fclose(cfg);
g_free (mc_extfsini);
return 0;
}
if (*key == '#')
continue;
1998-02-27 07:54:42 +03:00
if ((c = strchr (key, '\n'))){
*c = 0;
These are a bunch of changes to fix CORBA and session management. They are almost complete (i.e. to handle all nitty gritty cases), but they seem to be working OK right now. SM should be much more stable now. Please tell me if you find any weird behavior - Federico 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * gdesktop-icon.c (desktop_icon_realize): Remove the WM_CLIENT_LEADER property from icon windows so that window managers will not store SM information for them. * gnome-open-dialog.c: Added missing #includes. * gdesktop-init.c (desktop_init_at): Removed an unused variable. * gdesktop.h: Added some missing prototypes. * gmain.h: Added some missing prototypes. * Makefile.in: Added gsession.[ch] to the list of sources. * gmain.c (create_panels): Consider whether we have a CORBA server and session management. * gdesktop.c: #include "gdesktop-init.h" * gdesktop.c: Added a missing cast to GNOME_DIALOG. * gmain.c (create_panels): Removed the run_desktop global variable. * glayout.c (create_container): Set the wmclass of the panel to include its unique ID. * gsession.[ch]: New file with the functions that deal with session management. * glayout.c (gnome_exit): Use session_set_restart(). * gcorba.c (corba_init): Now returns an int with an error value. (corba_init_server): Initialize the server properly. Fixed all the object implementation code. (corba_create_window): New function used to create a window with the CORBA server. * gmain.c (gnome_check_super_user): Now the check for running as root is done here. There should be no GUI code in src/. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * dlg.c (dlg_run_done): Do not call the callback of a NULL current widget. * setup.h: Added missing prototype for setup_init(). * filegui.c (check_progress_buttons): Added a missing return value. * dlg.c (remove_widget): Added a missing return value. * main.c: Removed the global directory_list variable. Removed the main_corba_register_server() function. * main.h: Removed the global run_desktop variable. * panel.h: Now the panel structure has a unique numerical ID used for session management. * screen.c (panel_new): Maintain a unique ID for each panel. * main.c (maybe_display_linksdir): Handle display of the desktop init dir here. (main): Call gnome_check_super_user(). (init_corba_with_args): Call corba_init_server(). * main.c (init_corba_with_args): Do CORBA initialization here. Also removed the global force_activation option. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * vfs.c (vfs_add_current_stamps): Only do stamping of the panels if they exist. * mcserv.c: #include <sys/wait.h> (get_client): Put `#ifdef __EMX__' around an otherwise-unused variable. * utilvfs.c (vfs_split_url): Fix NULL <-> 0 confusion when comparing characters. * ftpfs.c (retrieve_dir): Removed unused variable dot_dot_found. * extfs.c (extfs_init): Assign `key' to c, not `&key'.
1999-03-30 10:09:56 +04:00
c = &key [strlen (key) - 1];
} else {
These are a bunch of changes to fix CORBA and session management. They are almost complete (i.e. to handle all nitty gritty cases), but they seem to be working OK right now. SM should be much more stable now. Please tell me if you find any weird behavior - Federico 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * gdesktop-icon.c (desktop_icon_realize): Remove the WM_CLIENT_LEADER property from icon windows so that window managers will not store SM information for them. * gnome-open-dialog.c: Added missing #includes. * gdesktop-init.c (desktop_init_at): Removed an unused variable. * gdesktop.h: Added some missing prototypes. * gmain.h: Added some missing prototypes. * Makefile.in: Added gsession.[ch] to the list of sources. * gmain.c (create_panels): Consider whether we have a CORBA server and session management. * gdesktop.c: #include "gdesktop-init.h" * gdesktop.c: Added a missing cast to GNOME_DIALOG. * gmain.c (create_panels): Removed the run_desktop global variable. * glayout.c (create_container): Set the wmclass of the panel to include its unique ID. * gsession.[ch]: New file with the functions that deal with session management. * glayout.c (gnome_exit): Use session_set_restart(). * gcorba.c (corba_init): Now returns an int with an error value. (corba_init_server): Initialize the server properly. Fixed all the object implementation code. (corba_create_window): New function used to create a window with the CORBA server. * gmain.c (gnome_check_super_user): Now the check for running as root is done here. There should be no GUI code in src/. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * dlg.c (dlg_run_done): Do not call the callback of a NULL current widget. * setup.h: Added missing prototype for setup_init(). * filegui.c (check_progress_buttons): Added a missing return value. * dlg.c (remove_widget): Added a missing return value. * main.c: Removed the global directory_list variable. Removed the main_corba_register_server() function. * main.h: Removed the global run_desktop variable. * panel.h: Now the panel structure has a unique numerical ID used for session management. * screen.c (panel_new): Maintain a unique ID for each panel. * main.c (maybe_display_linksdir): Handle display of the desktop init dir here. (main): Call gnome_check_super_user(). (init_corba_with_args): Call corba_init_server(). * main.c (init_corba_with_args): Do CORBA initialization here. Also removed the global force_activation option. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * vfs.c (vfs_add_current_stamps): Only do stamping of the panels if they exist. * mcserv.c: #include <sys/wait.h> (get_client): Put `#ifdef __EMX__' around an otherwise-unused variable. * utilvfs.c (vfs_split_url): Fix NULL <-> 0 confusion when comparing characters. * ftpfs.c (retrieve_dir): Removed unused variable dot_dot_found. * extfs.c (extfs_init): Assign `key' to c, not `&key'.
1999-03-30 10:09:56 +04:00
c = key;
}
These are a bunch of changes to fix CORBA and session management. They are almost complete (i.e. to handle all nitty gritty cases), but they seem to be working OK right now. SM should be much more stable now. Please tell me if you find any weird behavior - Federico 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * gdesktop-icon.c (desktop_icon_realize): Remove the WM_CLIENT_LEADER property from icon windows so that window managers will not store SM information for them. * gnome-open-dialog.c: Added missing #includes. * gdesktop-init.c (desktop_init_at): Removed an unused variable. * gdesktop.h: Added some missing prototypes. * gmain.h: Added some missing prototypes. * Makefile.in: Added gsession.[ch] to the list of sources. * gmain.c (create_panels): Consider whether we have a CORBA server and session management. * gdesktop.c: #include "gdesktop-init.h" * gdesktop.c: Added a missing cast to GNOME_DIALOG. * gmain.c (create_panels): Removed the run_desktop global variable. * glayout.c (create_container): Set the wmclass of the panel to include its unique ID. * gsession.[ch]: New file with the functions that deal with session management. * glayout.c (gnome_exit): Use session_set_restart(). * gcorba.c (corba_init): Now returns an int with an error value. (corba_init_server): Initialize the server properly. Fixed all the object implementation code. (corba_create_window): New function used to create a window with the CORBA server. * gmain.c (gnome_check_super_user): Now the check for running as root is done here. There should be no GUI code in src/. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * dlg.c (dlg_run_done): Do not call the callback of a NULL current widget. * setup.h: Added missing prototype for setup_init(). * filegui.c (check_progress_buttons): Added a missing return value. * dlg.c (remove_widget): Added a missing return value. * main.c: Removed the global directory_list variable. Removed the main_corba_register_server() function. * main.h: Removed the global run_desktop variable. * panel.h: Now the panel structure has a unique numerical ID used for session management. * screen.c (panel_new): Maintain a unique ID for each panel. * main.c (maybe_display_linksdir): Handle display of the desktop init dir here. (main): Call gnome_check_super_user(). (init_corba_with_args): Call corba_init_server(). * main.c (init_corba_with_args): Do CORBA initialization here. Also removed the global force_activation option. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * vfs.c (vfs_add_current_stamps): Only do stamping of the panels if they exist. * mcserv.c: #include <sys/wait.h> (get_client): Put `#ifdef __EMX__' around an otherwise-unused variable. * utilvfs.c (vfs_split_url): Fix NULL <-> 0 confusion when comparing characters. * ftpfs.c (retrieve_dir): Removed unused variable dot_dot_found. * extfs.c (extfs_init): Assign `key' to c, not `&key'.
1999-03-30 10:09:56 +04:00
extfs_need_archive [extfs_no] = !(*c == ':');
if (*c == ':')
*c = 0;
if (!(*key))
continue;
1998-02-27 07:54:42 +03:00
extfs_prefixes [extfs_no] = g_strdup (key);
extfs_no++;
1998-02-27 07:54:42 +03:00
}
fclose(cfg);
g_free (mc_extfsini);
return 1;
1998-02-27 07:54:42 +03:00
}
/* Do NOT use me argument in this function */
static int extfs_which (struct vfs_class *me, char *path)
1998-02-27 07:54:42 +03:00
{
int i;
1998-02-27 07:54:42 +03:00
for (i = 0; i < extfs_no; i++)
if (!strcmp (path, extfs_prefixes [i]))
1998-02-27 07:54:42 +03:00
return i;
return -1;
}
static void extfs_done (struct vfs_class *me)
1998-02-27 07:54:42 +03:00
{
int i;
for (i = 0; i < extfs_no; i++ )
g_free (extfs_prefixes [i]);
1998-02-27 07:54:42 +03:00
extfs_no = 0;
}
static int
extfs_setctl (struct vfs_class *me, char *path, int ctlop, void *arg)
1998-10-13 02:07:53 +04:00
{
if (ctlop == VFS_SETCTL_RUN) {
extfs_run (path);
1998-10-13 02:07:53 +04:00
return 1;
}
return 0;
}
void
init_extfs (void)
{
vfs_extfs_ops.name = "extfs";
vfs_extfs_ops.init = extfs_init;
vfs_extfs_ops.done = extfs_done;
vfs_extfs_ops.fill_names = extfs_fill_names;
vfs_extfs_ops.which = extfs_which;
vfs_extfs_ops.open = extfs_open;
vfs_extfs_ops.close = extfs_close;
vfs_extfs_ops.read = extfs_read;
vfs_extfs_ops.write = extfs_write;
vfs_extfs_ops.opendir = s_opendir;
vfs_extfs_ops.readdir = s_readdir;
vfs_extfs_ops.closedir = s_closedir;
vfs_extfs_ops.stat = s_stat;
vfs_extfs_ops.lstat = s_lstat;
vfs_extfs_ops.fstat = s_fstat;
vfs_extfs_ops.chmod = extfs_chmod;
vfs_extfs_ops.readlink = s_readlink;
vfs_extfs_ops.unlink = extfs_unlink;
vfs_extfs_ops.chdir = extfs_chdir;
vfs_extfs_ops.ferrno = s_errno;
vfs_extfs_ops.lseek = extfs_lseek;
vfs_extfs_ops.getid = extfs_getid;
vfs_extfs_ops.nothingisopen = extfs_nothingisopen;
vfs_extfs_ops.free = extfs_free;
vfs_extfs_ops.getlocalcopy = extfs_getlocalcopy;
vfs_extfs_ops.ungetlocalcopy = extfs_ungetlocalcopy;
vfs_extfs_ops.mkdir = extfs_mkdir;
vfs_extfs_ops.rmdir = extfs_rmdir;
vfs_extfs_ops.setctl = extfs_setctl;
vfs_register_class (&vfs_extfs_ops);
}