1
1
- SFS-based file systems now work on GNOME edition, I was
	  not waiting for child process to finish decompressing.

	- VFS code cleanup.  I am going to eventually get rid of all
	  the macro-mania that has creeped into the vfs layer.

Miguel
Этот коммит содержится в:
Miguel de Icaza 1999-01-11 00:48:23 +00:00
родитель a7170a4f7a
Коммит 85f17a4dc6
12 изменённых файлов: 385 добавлений и 264 удалений

Просмотреть файл

@ -1,3 +1,18 @@
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gutil.c (my_system_get_child_pid): Acknowledge new EXECUTE_WAIT
flag. This is required by the vfs code.
1999-01-06 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gscreen.c (panel_create_file_list, panel_create_icon_display):
I got excited adding the gtk_drag_source_set. I generate those
events myself, no need to put them here.
1999-01-04 Miguel de Icaza <miguel@nuclecu.unam.mx>
* gwidget.c (stock_from_text): Return this value.
1999-01-08 Jonathan Blandford <jrb@redhat.com>
* glayout.c: now open the new (non-functional) dialog box. If you

Просмотреть файл

@ -73,7 +73,9 @@ int my_system_get_child_pid (int flags, const char *shell, const char *command,
for (i = 3; i < top; i++)
close (i);
*pid = fork ();
if (!(flags & EXECUTE_WAIT))
*pid = fork ();
if (*pid == 0){
if (flags & EXECUTE_AS_SHELL)
execl (shell, shell, "-c", command, (char *) 0);
@ -94,14 +96,15 @@ int my_system_get_child_pid (int flags, const char *shell, const char *command,
*/
_exit (0);
}
if (*pid != 0 && (flags & EXECUTE_WAIT)){
int status;
waitpid (*pid, &status, 0);
}
sigaction (SIGINT, &save_intr, NULL);
sigaction (SIGQUIT, &save_quit, NULL);
sigaction (SIGTSTP, &save_stop, NULL);
#ifdef SCO_FLAVOR
waitpid(-1, NULL, WNOHANG);
#endif /* SCO_FLAVOR */
return WEXITSTATUS(status);
}

Просмотреть файл

@ -108,6 +108,7 @@ void my_putenv (char*, char*);
#define EXECUTE_TEMPFILE 2
#define EXECUTE_AS_SHELL 4
#define EXECUTE_SETUID 8
#define EXECUTE_WAIT 16
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);

Просмотреть файл

@ -1,3 +1,7 @@
1999-01-10 Miguel de Icaza <miguel@nuclecu.unam.mx>
* sfs.c (redirect): tempnam returns a malloc()ed buffer.
Sat Jan 9 19:15:00 1999 Norbert Warmuth <nwarmuth@privat.circular.de>
* vfs.c (vfs_timeout_handler): Guard from recursive invocation.

Просмотреть файл

@ -35,7 +35,8 @@ vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat
vfs_s_inode *ino;
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
if (!ino) return NULL;
if (!ino)
return NULL;
ino->linkname = ino->localname = NULL;
@ -66,7 +67,8 @@ vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)
if (name)
entry->name = strdup (name);
else entry->name = NULL;
else
entry->name = NULL;
entry->dir = NULL;
entry->next = NULL;
entry->prevp = NULL;
@ -79,7 +81,8 @@ vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode)
void vfs_s_free_inode (vfs *me, vfs_s_inode *ino)
{
if (!ino) vfs_die("Don't pass NULL to me");
if (!ino)
vfs_die ("Don't pass NULL to me");
/* ==0 can happen if freshly created entry is deleted */
if(ino->st.st_nlink <= 1) {
@ -106,7 +109,8 @@ void vfs_s_free_entry (vfs *me, vfs_s_entry *ent)
int is_dot = 0;
if (ent->prevp) { /* It is possible that we are deleting freshly created entry */
*ent->prevp = ent->next;
if (ent->next) ent->next->prevp = ent->prevp;
if (ent->next)
ent->next->prevp = ent->prevp;
}
if (ent->name) {
@ -129,7 +133,8 @@ void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent)
{
vfs_s_entry **ep;
for(ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next));
for (ep = &dir->subdir; *ep != NULL; ep = &((*ep)->next))
;
ent->prevp = ep;
ent->next = NULL;
ent->dir = dir;
@ -251,7 +256,6 @@ static void split_dir_name(vfs *me, char *path, char **dir, char **name, char **
vfs_s_entry *vfs_s_find_entry_linear(vfs *me, vfs_s_inode *root, char *path, int follow, int flags)
{
char *s;
vfs_s_entry* ent = NULL;
if (!(flags & FL_DIR)) {
@ -435,7 +439,8 @@ char *vfs_s_get_path_mangle (vfs *me, char *inname, struct vfs_s_super **archive
}
}
if (flags & FL_NO_OPEN) ERRNOR (EIO, NULL);
if (flags & FL_NO_OPEN)
ERRNOR (EIO, NULL);
super = vfs_s_new_super (me);
result = MEDATA->open_archive (me, super, archive_name, op);
@ -523,8 +528,10 @@ void * vfs_s_opendir (vfs *me, char *dirname)
struct dirhandle *info;
dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
if (!dir) return NULL;
if (!S_ISDIR (dir->st.st_mode)) ERRNOR (ENOTDIR, NULL);
if (!dir)
return NULL;
if (!S_ISDIR (dir->st.st_mode))
ERRNOR (ENOTDIR, NULL);
dir->st.st_nlink++;
#if 0
@ -556,7 +563,7 @@ void * vfs_s_readdir (void *data)
strcpy (&(dir.dir.d_name [0]), info->cur->name);
else
vfs_die( "Null in structure-can not happen");
#ifndef DIRENT_LENGTH_COMPUTED
dir.d_namlen = strlen (dir.dir.d_name);
#endif
@ -573,7 +580,8 @@ int vfs_s_telldir (void *data)
cur = info->dir->subdir;
while (cur!=NULL) {
if (cur == info->cur) return num;
if (cur == info->cur)
return num;
num++;
cur = cur->next;
}
@ -614,7 +622,8 @@ static int vfs_s_internal_stat (vfs *me, char *path, struct stat *buf, int flag)
{
struct vfs_s_inode *ino;
if (!(ino = vfs_s_inode_from_path( me, path, flag ))) return -1;
if (!(ino = vfs_s_inode_from_path( me, path, flag )))
return -1;
*buf = ino->st;
return 0;
}
@ -640,9 +649,11 @@ int vfs_s_readlink (vfs *me, char *path, char *buf, int size)
struct vfs_s_inode *ino;
ino = vfs_s_inode_from_path(me, path, 0);
if (!ino) return -1;
if (!ino)
return -1;
if (!S_ISLNK (ino->st.st_mode)) ERRNOR (EINVAL, -1);
if (!S_ISLNK (ino->st.st_mode))
ERRNOR (EINVAL, -1);
strncpy (buf, ino->linkname, size);
*(buf+size-1) = 0;
return strlen(buf);
@ -681,7 +692,8 @@ void *vfs_s_open (vfs *me, char *file, int flags, int mode)
was_changed = 1;
}
if (S_ISDIR (ino->st.st_mode)) ERRNOR (EISDIR, NULL);
if (S_ISDIR (ino->st.st_mode))
ERRNOR (EISDIR, NULL);
fh = (struct vfs_s_fh *) xmalloc (sizeof (struct vfs_s_fh), "Direntry: filehandle");
fh->pos = 0;
@ -810,8 +822,10 @@ int vfs_s_close (void *fh)
res = MEDATA->fh_close (me, fh);
if (FH->changed && MEDATA->file_store) {
char *s = vfs_s_fullpath( me, FH->ino );
if (!s) res = -1;
else res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
if (!s)
res = -1;
else
res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
vfs_s_invalidate(me, FH_SUPER);
}
if (FH->handle)
@ -848,7 +862,9 @@ void
vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino)
{
printf( "%s %s %d ", prefix, S_ISDIR(ino->st.st_mode) ? "DIR" : "FILE", ino->st.st_mode );
if (!ino->subdir) printf ("FILE\n");
if (!ino->subdir)
printf ("FILE\n");
else
{
struct vfs_s_entry *ent;

Просмотреть файл

@ -104,7 +104,7 @@ static int command (vfs *me, vfs_s_super *super, int wait_reply, char *fmt, ...)
{
va_list ap;
char *str;
int n, status;
int status;
FILE *logfile = MEDATA->logfile;
va_start (ap, fmt);

Просмотреть файл

@ -143,8 +143,8 @@ static struct linklist *connections_list;
#define WANT_STRING 0x02
static char reply_str [80];
static struct direntry *_get_file_entry(struct connection *bucket,
char *file_name, int op, int flags);
static struct direntry *_get_file_entry (struct connection *bucket,
char *file_name, int op, int flags);
static char *ftpfs_get_current_directory (struct connection *bucket);
static int ftpfs_chdir_internal (struct connection *bucket,
@ -184,16 +184,16 @@ get_reply (int sock, char *string_buf, int string_len)
int i;
for (;;) {
if (!get_line(sock, answer, sizeof(answer), '\n')) {
if (!get_line (sock, answer, sizeof (answer), '\n')){
if (string_buf)
*string_buf = 0;
code = 421;
return 4;
}
switch(sscanf(answer, "%d", &code)) {
switch (sscanf(answer, "%d", &code)){
case 0:
if (string_buf) {
strncpy(string_buf, answer, string_len - 1);
strncpy (string_buf, answer, string_len - 1);
*(string_buf + string_len - 1) = 0;
}
code = 500;
@ -201,19 +201,19 @@ get_reply (int sock, char *string_buf, int string_len)
case 1:
if (answer[3] == '-') {
while (1) {
if (!get_line(sock, answer, sizeof(answer), '\n')) {
if (!get_line (sock, answer, sizeof(answer), '\n')){
if (string_buf)
*string_buf = 0;
code = 421;
return 4;
}
if ((sscanf(answer, "%d", &i) > 0) &&
if ((sscanf (answer, "%d", &i) > 0) &&
(code == i) && (answer[3] == ' '))
break;
}
}
if (string_buf) {
strncpy(string_buf, answer, string_len - 1);
if (string_buf){
strncpy (string_buf, answer, string_len - 1);
*(string_buf + string_len - 1) = 0;
}
return code / 100;
@ -226,7 +226,7 @@ command (struct connection *bucket, int wait_reply, char *fmt, ...)
{
va_list ap;
char *str, *fmt_str;
int n, status;
int status;
int sock = qsock (bucket);
va_start (ap, fmt);
@ -275,7 +275,7 @@ connection_close (void *data)
struct connection *bucket = data;
if (qsock (bucket) != -1){
print_vfs_message ("ftpfs: Disconnecting from %s", qhost(bucket));
print_vfs_message ("ftpfs: Disconnecting from %s", qhost (bucket));
command(bucket, NONE, "QUIT");
close(qsock(bucket));
}
@ -294,7 +294,8 @@ static int
changetype (struct connection *bucket, int binary)
{
if (binary != bucket->isbinary) {
if (command (bucket, WAIT_REPLY, "TYPE %c", binary ? 'I' : 'A') != COMPLETE) ERRNOR (EIO, -1);
if (command (bucket, WAIT_REPLY, "TYPE %c", binary ? 'I' : 'A') != COMPLETE)
ERRNOR (EIO, -1);
bucket->isbinary = binary;
}
return binary;
@ -316,19 +317,20 @@ login_server (struct connection *bucket, char *netrcpass)
if (netrcpass)
op = strdup (netrcpass);
else {
if (!strcmp (quser(bucket), "anonymous") ||
!strcmp (quser(bucket), "ftp")) {
op = strdup(ftpfs_anonymous_passwd);
if (!strcmp (quser (bucket), "anonymous") ||
!strcmp (quser (bucket), "ftp")) {
op = strdup (ftpfs_anonymous_passwd);
anon = 1;
} else {
char *p;
if (!bucket->password){
p = copy_strings (" FTP: Password required for ", quser(bucket),
p = copy_strings (" FTP: Password required for ", quser (bucket),
" ", NULL);
op = vfs_get_password (p);
free (p);
if (op == NULL) ERRNOR (EPERM, 0);
if (op == NULL)
ERRNOR (EPERM, 0);
bucket->password = strdup (op);
} else
op = strdup (bucket->password);
@ -347,44 +349,47 @@ login_server (struct connection *bucket, char *netrcpass)
#if defined(HSC_PROXY)
char *p, *host;
int port;
p = my_get_host_and_username(ftpfs_proxy_host, &host, &proxyname,
&port, &proxypass);
p = my_get_host_and_username (ftpfs_proxy_host, &host, &proxyname,
&port, &proxypass);
if (p)
free (p);
free(host);
free (host);
if (proxypass)
wipe_password (proxypass);
p = copy_strings(" Proxy: Password required for ", proxyname, " ",
NULL);
p = copy_strings (" Proxy: Password required for ", proxyname, " ",
NULL);
proxypass = vfs_get_password (p);
free(p);
free (p);
if (proxypass == NULL) {
wipe_password (pass);
free (proxyname);
ERRNOR (EPERM, 0);
}
name = strdup(quser (bucket));
name = strdup (quser (bucket));
#else
name = copy_strings (quser(bucket), "@",
qhost(bucket)[0] == '!' ? qhost(bucket)+1 : qhost(bucket), 0);
name = copy_strings (quser (bucket), "@",
qhost (bucket)[0] == '!' ? qhost (bucket)+1 : qhost (bucket), 0);
#endif
} else
name = strdup (quser (bucket));
if (get_reply (qsock(bucket), NULL, 0) == COMPLETE) {
if (get_reply (qsock (bucket), NULL, 0) == COMPLETE) {
#if defined(HSC_PROXY)
if (qproxy(bucket)) {
print_vfs_message("ftpfs: sending proxy login name");
if (qproxy (bucket)){
print_vfs_message ("ftpfs: sending proxy login name");
if (command (bucket, 1, "USER %s", proxyname) != CONTINUE)
goto proxyfail;
print_vfs_message("ftpfs: sending proxy user password");
print_vfs_message ("ftpfs: sending proxy user password");
if (command (bucket, 1, "PASS %s", proxypass) != COMPLETE)
goto proxyfail;
print_vfs_message("ftpfs: proxy authentication succeeded");
if (command (bucket, 1, "SITE %s", qhost(bucket)+1) != COMPLETE)
print_vfs_message ("ftpfs: proxy authentication succeeded");
if (command (bucket, 1, "SITE %s", qhost (bucket)+1) != COMPLETE)
goto proxyfail;
print_vfs_message("ftpfs: connected to %s", qhost(bucket)+1);
print_vfs_message ("ftpfs: connected to %s", qhost (bucket)+1);
if (0) {
proxyfail:
bucket->failed_on_login = 1;
@ -401,17 +406,17 @@ login_server (struct connection *bucket, char *netrcpass)
free (proxyname);
}
#endif
print_vfs_message("ftpfs: sending login name");
print_vfs_message ("ftpfs: sending login name");
code = command (bucket, WAIT_REPLY, "USER %s", name);
switch (code){
case CONTINUE:
print_vfs_message("ftpfs: sending user password");
print_vfs_message ("ftpfs: sending user password");
if (command (bucket, WAIT_REPLY, "PASS %s", pass) != COMPLETE)
break;
case COMPLETE:
print_vfs_message("ftpfs: logged in");
print_vfs_message ("ftpfs: logged in");
wipe_password (pass);
free (name);
return 1;
@ -426,7 +431,7 @@ login_server (struct connection *bucket, char *netrcpass)
goto login_fail;
}
}
print_vfs_message ("ftpfs: Login incorrect for user %s ", quser(bucket));
print_vfs_message ("ftpfs: Login incorrect for user %s ", quser (bucket));
login_fail:
wipe_password (pass);
free (name);
@ -566,17 +571,17 @@ ftpfs_get_proxy_host_and_port (char *proxy, char **host, int *port)
#else
#define PORT 21
#endif
dir = vfs_split_url(proxy, host, &user, port, &pass, PORT, URL_DEFAULTANON);
dir = vfs_split_url (proxy, host, &user, port, &pass, PORT, URL_DEFAULTANON);
free(user);
free (user);
if (pass)
wipe_password (pass);
if (dir)
free(dir);
free (dir);
}
static int
ftpfs_open_socket(struct connection *bucket)
ftpfs_open_socket (struct connection *bucket)
{
struct sockaddr_in server_address;
struct hostent *hp;
@ -586,7 +591,7 @@ ftpfs_open_socket(struct connection *bucket)
int free_host = 0;
/* Use a proxy host? */
host = qhost(bucket);
host = qhost (bucket);
if (!host || !*host){
print_vfs_message ("ftpfs: Invalid host name.");
@ -595,7 +600,7 @@ ftpfs_open_socket(struct connection *bucket)
}
/* Hosts to connect to that start with a ! should use proxy */
if (qproxy(bucket)) {
if (qproxy (bucket)){
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &port);
free_host = 1;
}
@ -607,9 +612,9 @@ ftpfs_open_socket(struct connection *bucket)
if (server_address.sin_addr.s_addr != -1)
server_address.sin_family = AF_INET;
else {
hp = gethostbyname(host);
hp = gethostbyname (host);
if (hp == NULL){
print_vfs_message("ftpfs: Invalid host address.");
print_vfs_message ("ftpfs: Invalid host address.");
my_errno = EINVAL;
if (free_host)
free (host);
@ -634,20 +639,20 @@ ftpfs_open_socket(struct connection *bucket)
}
setup_source_route (my_socket, server_address.sin_addr.s_addr);
print_vfs_message("ftpfs: making connection to %s", host);
print_vfs_message ("ftpfs: making connection to %s", host);
if (free_host)
free (host);
enable_interrupt_key(); /* clear the interrupt flag */
enable_interrupt_key (); /* clear the interrupt flag */
if (connect (my_socket, (struct sockaddr *) &server_address,
sizeof (server_address)) < 0){
my_errno = errno;
if (errno == EINTR && got_interrupt())
print_vfs_message("ftpfs: connection interrupted by user");
if (errno == EINTR && got_interrupt ())
print_vfs_message ("ftpfs: connection interrupted by user");
else
print_vfs_message("ftpfs: connection to server failed: %s",
unix_error_string(errno));
print_vfs_message ("ftpfs: connection to server failed: %s",
unix_error_string(errno));
disable_interrupt_key();
close (my_socket);
return -1;
@ -665,7 +670,8 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
bucket = xmalloc(sizeof(struct connection),
"struct connection");
if (bucket == NULL) ERRNOR (ENOMEM, NULL);
if (bucket == NULL)
ERRNOR (ENOMEM, NULL);
#ifdef HAVE_MAD
{
extern void *watch_free_pointer;
@ -674,15 +680,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
watch_free_pointer = host;
}
#endif
qhost(bucket) = strdup (host);
quser(bucket) = strdup (user);
qcdir(bucket) = NULL;
qport(bucket) = port;
qlock(bucket) = 0;
qhome(bucket) = NULL;
qproxy(bucket)= 0;
qupdir(bucket)= 0;
qdcache(bucket)=0;
qhost (bucket) = strdup (host);
quser (bucket) = strdup (user);
qcdir (bucket) = NULL;
qport (bucket) = port;
qlock (bucket) = 0;
qhome (bucket) = NULL;
qproxy (bucket)= 0;
qupdir (bucket)= 0;
qdcache (bucket)=0;
bucket->__inode_counter = 0;
bucket->lock = 0;
bucket->use_proxy = ftpfs_check_proxy (host);
@ -696,10 +702,10 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
if (bucket->use_proxy)
bucket->use_passive_connection = 0;
if ((qdcache(bucket) = linklist_init()) == NULL) {
if ((qdcache (bucket) = linklist_init ()) == NULL) {
my_errno = ENOMEM;
free (qhost(bucket));
free (quser(bucket));
free (qhost (bucket));
free (quser (bucket));
free (bucket);
return NULL;
}
@ -708,13 +714,13 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
do {
bucket->failed_on_login = 0;
qsock(bucket) = ftpfs_open_socket(bucket);
if (qsock(bucket) == -1) {
qsock (bucket) = ftpfs_open_socket (bucket);
if (qsock (bucket) == -1) {
free_bucket (bucket);
return NULL;
}
if (login_server(bucket, netrcpass)) {
if (login_server (bucket, netrcpass)) {
/* Logged in, no need to retry the connection */
break;
} else {
@ -743,15 +749,15 @@ open_command_connection (char *host, char *user, int port, char *netrcpass)
}
} while (retry_seconds);
qhome(bucket) = ftpfs_get_current_directory (bucket);
if (!qhome(bucket))
qhome(bucket) = strdup ("/");
qupdir(bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
qhome (bucket) = ftpfs_get_current_directory (bucket);
if (!qhome (bucket))
qhome (bucket) = strdup ("/");
qupdir (bucket) = strdup ("/"); /* FIXME: I changed behavior to ignore last_current_dir */
return bucket;
}
static int
is_connection_closed(struct connection *bucket)
is_connection_closed (struct connection *bucket)
{
fd_set rset;
struct timeval t;
@ -761,16 +767,16 @@ is_connection_closed(struct connection *bucket)
}
t.tv_sec = 0;
t.tv_usec = 0;
FD_ZERO(&rset);
FD_SET(qsock(bucket), &rset);
FD_ZERO (&rset);
FD_SET (qsock (bucket), &rset);
while (1) {
if (select(qsock(bucket) + 1, &rset, NULL, NULL, &t) < 0)
if (select (qsock (bucket) + 1, &rset, NULL, NULL, &t) < 0)
if (errno != EINTR)
return 1;
return 0;
#if 0
if (FD_ISSET(qsock(bucket), &rset)) {
n = read(qsock(bucket), &read_ahead, sizeof(read_ahead));
if (FD_ISSET (qsock(bucket), &rset)) {
n = read (qsock(bucket), &read_ahead, sizeof (read_ahead));
if (n <= 0)
return 1;
} else
@ -790,47 +796,48 @@ open_link (char *host, char *user, int port, char *netrcpass)
for (lptr = connections_list->next;
lptr != connections_list; lptr = lptr->next) {
bucket = lptr->data;
if ((strcmp (host, qhost(bucket)) == 0) &&
(strcmp (user, quser(bucket)) == 0) &&
(port == qport(bucket))) {
if ((strcmp (host, qhost (bucket)) == 0) &&
(strcmp (user, quser (bucket)) == 0) &&
(port == qport (bucket))) {
/* check the connection is closed or not, just hack */
if (is_connection_closed(bucket)) {
flush_all_directory(bucket);
sock = ftpfs_open_socket(bucket);
if (is_connection_closed (bucket)) {
flush_all_directory (bucket);
sock = ftpfs_open_socket (bucket);
if (sock != -1) {
close(qsock(bucket));
qsock(bucket) = sock;
if (login_server(bucket, netrcpass))
close (qsock (bucket));
qsock (bucket) = sock;
if (login_server (bucket, netrcpass))
return bucket;
}
/* connection refused */
lptr->prev->next = lptr->next;
lptr->next->prev = lptr->prev;
connection_destructor(bucket);
connection_destructor (bucket);
return NULL;
}
return bucket;
}
}
bucket = open_command_connection(host, user, port, netrcpass);
bucket = open_command_connection (host, user, port, netrcpass);
if (bucket == NULL)
return NULL;
if (!linklist_insert(connections_list, bucket)) {
if (!linklist_insert (connections_list, bucket)) {
my_errno = ENOMEM;
connection_destructor(bucket);
connection_destructor (bucket);
return NULL;
}
return bucket;
}
/* The returned directory should always contain a trailing slash */
static char *ftpfs_get_current_directory(struct connection *bucket)
static char *
ftpfs_get_current_directory (struct connection *bucket)
{
char buf[4096], *bufp, *bufq;
if (command(bucket, NONE, "PWD") == COMPLETE &&
if (command (bucket, NONE, "PWD") == COMPLETE &&
get_reply(qsock(bucket), buf, sizeof(buf)) == COMPLETE) {
bufp = NULL;
for (bufq = buf; *bufq; bufq++)
@ -900,9 +907,11 @@ initconn (struct connection *bucket)
data_addr.sin_port = 0;
pe = getprotobyname("tcp");
if (pe == NULL) ERRNOR (EIO, -1);
if (pe == NULL)
ERRNOR (EIO, -1);
data = socket (AF_INET, SOCK_STREAM, pe->p_proto);
if (data < 0) ERRNOR (EIO, -1);
if (data < 0)
ERRNOR (EIO, -1);
#ifdef ORIGINAL_CONNECT_CODE
if (bucket->use_source_route){
@ -965,7 +974,8 @@ open_data_connection (struct connection *bucket, char *cmd, char *remote,
j = command (bucket, WAIT_REPLY, "%s %s", cmd, remote);
else
j = command (bucket, WAIT_REPLY, "%s", cmd);
if (j != PRELIM) ERRNOR (EPERM, -1);
if (j != PRELIM)
ERRNOR (EPERM, -1);
enable_interrupt_key();
if (bucket->use_passive_connection)
data = s;
@ -1222,7 +1232,8 @@ retrieve_dir(struct connection *bucket, char *remote_path, int resolve_symlinks)
}
file_list = linklist_init();
if (file_list == NULL) ERRNOR (ENOMEM, NULL);
if (file_list == NULL)
ERRNOR (ENOMEM, NULL);
dcache = xmalloc(sizeof(struct dir),
"struct dir");
if (dcache == NULL) {
@ -1384,7 +1395,8 @@ store_file(struct direntry *fe)
local_handle = open(fe->local_filename, O_RDONLY);
unlink (fe->local_filename);
if (local_handle == -1) ERRNOR (EIO, 0);
if (local_handle == -1)
ERRNOR (EIO, 0);
fstat(local_handle, &s);
sock = open_data_connection(fe->bucket, "STOR", fe->remote_filename, TYPE_BINARY, 0);
if (sock < 0) {
@ -1435,7 +1447,8 @@ store_file(struct direntry *fe)
disable_interrupt_key();
close(sock);
close(local_handle);
if (get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE) ERRNOR (EIO, 0);
if (get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE)
ERRNOR (EIO, 0);
return 1;
error_return:
disable_interrupt_key();
@ -1473,7 +1486,8 @@ linear_read (struct direntry *fe, void *buf, int len)
break;
}
if (n<0) linear_abort(fe);
if (n<0)
linear_abort(fe);
if (!n) {
if ((get_reply (qsock (fe->bucket), NULL, 0) != COMPLETE)) {
@ -1531,7 +1545,8 @@ send_ftp_command(char *filename, char *cmd, int flags)
vfs_add_noncurrent_stamps (&vfs_ftpfs_ops, (vfsid) bucket, NULL);
if (flags & OPT_IGNORE_ERROR)
r = COMPLETE;
if (r != COMPLETE) ERRNOR (EPERM, -1);
if (r != COMPLETE)
ERRNOR (EPERM, -1);
if (flush_directory_cache)
flush_all_directory(bucket);
return 0;

Просмотреть файл

@ -211,7 +211,8 @@ static int mcfs_login_server (int my_socket, char *user, int port,
/* This used to be in utilvfs.c, but as it deals with portmapper, it
is probably usefull for mcfs */
static int open_tcp_link (char *host, int *port, int *version, char *caller)
int
open_tcp_link (char *host, int *port, int *version, char *caller)
{
struct sockaddr_in server_address;
unsigned long inaddr;

140
vfs/sfs.c
Просмотреть файл

@ -50,12 +50,12 @@ static int sfs_flags[ MAXFS ];
#define F_NOLOCALCOPY 4
#define F_FULLMATCH 8
static int uptodate( char *name, char *cache )
static int uptodate (char *name, char *cache)
{
return 1;
}
static int vfmake( vfs *me, char *name, char *cache )
static int vfmake (vfs *me, char *name, char *cache)
{
char *inpath, *op;
int w;
@ -63,72 +63,77 @@ static int vfmake( vfs *me, char *name, char *cache )
char *s, *t = pad;
int was_percent = 0;
vfs_split( name, &inpath, &op );
if ((w = (*me->which)( me, op )) == -1)
vfs_die( "This cannot happen... Hopefully.\n" );
vfs_split (name, &inpath, &op);
if ((w = (*me->which) (me, 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_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 );
name = mc_getlocalcopy (name);
else
name = strdup( name );
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); }
#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 '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;
if (*s == '%')
was_percent = 1;
else
COPY_CHAR;
}
s++;
}
free( name );
free (name);
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID, "/bin/sh", pad)) {
if (my_system (EXECUTE_AS_SHELL | EXECUTE_SETUID | EXECUTE_WAIT, "/bin/sh", pad)) {
return -1;
}
return 0; /* OK */
}
static char *redirect( vfs *me, char *name )
static char *
redirect (vfs *me, char *name)
{
struct cachedfile *cur = head;
uid_t uid = vfs_uid;
char *cache, *xname;
int handle;
while (cur) {
if ((!strcmp( name, cur->name )) &&
while (cur){
if ((!strcmp (name, cur->name)) &&
(uid == cur->uid) &&
(uptodate( cur->name, cur->cache )))
/* FIXME: when not uptodate, we might want to kill cache
* file immediately, not to wait until timeout. */ {
vfs_stamp( &vfs_sfs_ops, cur );
return cur->cache;
(uptodate (cur->name, cur->cache)))
/* FIXME: when not uptodate, we might want to kill cache
* file immediately, not to wait until timeout. */ {
vfs_stamp (&vfs_sfs_ops, cur);
return cur->cache;
}
cur = cur->next;
}
cache = tempnam( NULL, "sfs" );
handle = open(cache, O_RDWR | O_CREAT | O_EXCL, 0600);
cache = tempnam (NULL, "sfs");
handle = open (cache, O_RDWR | O_CREAT | O_EXCL, 0600);
if (handle == -1)
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
close(handle);
xname = strdup( name );
if (!vfmake( me, name, cache )) {
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" );
close (handle);
xname = strdup (name);
if (!vfmake (me, name, cache)){
cur = xmalloc (sizeof(struct cachedfile), "SFS cache");
cur->name = xname;
cur->cache = strdup(cache);
cur->cache = cache;
cur->uid = uid;
cur->next = head;
head = cur;
@ -143,14 +148,13 @@ static char *redirect( vfs *me, char *name )
return "/I_MUST_NOT_EXIST";
}
#define REDIR path = redirect( me, path );
static void *sfs_open (vfs *me, char *path, int flags, int mode)
static void *
sfs_open (vfs *me, char *path, int flags, int mode)
{
int *sfs_info;
int fd;
REDIR;
path = redirect (me, path);
fd = open (path, flags, mode);
if (fd == -1)
return 0;
@ -163,13 +167,13 @@ static void *sfs_open (vfs *me, char *path, int flags, int mode)
static int sfs_stat (vfs *me, char *path, struct stat *buf)
{
REDIR;
path = redirect (me, path);
return stat (path, buf);
}
static int sfs_lstat (vfs *me, char *path, struct stat *buf)
{
REDIR;
path = redirect (me, path);
#ifndef HAVE_STATLSTAT
return lstat (path,buf);
#else
@ -179,25 +183,25 @@ static int sfs_lstat (vfs *me, char *path, struct stat *buf)
static int sfs_chmod (vfs *me, char *path, int mode)
{
REDIR;
path = redirect (me, path);
return chmod (path, mode);
}
static int sfs_chown (vfs *me, char *path, int owner, int group)
{
REDIR;
path = redirect (me, path);
return chown (path, owner, group);
}
static int sfs_utime (vfs *me, char *path, struct utimbuf *times)
{
REDIR;
path = redirect (me, path);
return utime (path, times);
}
static int sfs_readlink (vfs *me, char *path, char *buf, int size)
{
REDIR;
path = redirect (me, path);
return readlink (path, buf, size);
}
@ -220,10 +224,10 @@ static vfsid sfs_getid (vfs *me, char *path, struct vfs_stamping **parent)
*parent = NULL;
{
char *path2 = strdup( path );
char *path2 = strdup (path);
v = vfs_split (path2, NULL, NULL);
id = (*v->getid) (v, path2, &par);
free( path2 );
free (path2);
}
if (id != (vfsid)-1) {
@ -272,7 +276,7 @@ static int sfs_nothingisopen (vfsid id)
static char *sfs_getlocalcopy (vfs *me, char *path)
{
REDIR;
path = redirect (me, path);
return strdup (path);
}
@ -282,30 +286,37 @@ static void sfs_ungetlocalcopy (vfs *me, char *path, char *local, int has_change
static int sfs_init (vfs *me)
{
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" );
if (!cfg) {
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" );
FILE *cfg = fopen (LIBDIR "extfs/sfs.ini", "r");
if (!cfg){
fprintf (stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n");
return 0;
}
sfs_no = 0;
while ( sfs_no < MAXFS ) {
while (sfs_no < MAXFS){
char key[256];
char *c, *semi = NULL, flags = 0;
int i;
if (!fgets( key, 250, cfg ))
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; }
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 );
if (!semi){
fprintf (stderr, "Warning: Invalid line %s in sfs.ini.\n", key);
continue;
}
@ -316,13 +327,13 @@ static int sfs_init (vfs *me)
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 );
fprintf (stderr, "Warning: Invalid flag %c in sfs.ini line %s.\n", *c, key);
}
c++;
}
c++;
*(semi+1) = 0;
if ((semi = strchr( c, '\n')))
if ((semi = strchr (c, '\n')))
*semi = 0;
sfs_prefix [sfs_no] = strdup (key);
@ -330,22 +341,25 @@ static int sfs_init (vfs *me)
sfs_flags [sfs_no] = flags;
sfs_no++;
}
fclose(cfg);
fclose (cfg);
return 1;
}
static void sfs_done (vfs *me)
static void
sfs_done (vfs *me)
{
int i;
for (i=0; i<sfs_no; i++) {
free(sfs_prefix [i]);
free(sfs_command [i]);
for (i = 0; i < sfs_no; i++){
free (sfs_prefix [i]);
free (sfs_command [i]);
sfs_prefix [i] = sfs_command [i] = NULL;
}
sfs_no = 0;
}
static int sfs_which (vfs *me, char *path)
static int
sfs_which (vfs *me, char *path)
{
int i;
@ -354,7 +368,7 @@ static int sfs_which (vfs *me, char *path)
if (!strcmp (path, sfs_prefix [i]))
return i;
} else
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) ))
if (!strncmp (path, sfs_prefix [i], strlen (sfs_prefix [i])))
return i;

101
vfs/tar.c
Просмотреть файл

@ -124,9 +124,13 @@ static int tar_open_archive (vfs *me, char *name, vfs_s_super *archive)
static union record rec_buf;
static union record *get_next_record (vfs_s_super *archive, int tard)
static union record *
get_next_record (vfs_s_super *archive, int tard)
{
if (mc_read (tard, rec_buf.charptr, RECORDSIZE) != RECORDSIZE)
int n;
n = mc_read (tard, rec_buf.charptr, RECORDSIZE);
if (n != RECORDSIZE)
return NULL; /* An error has occurred */
current_tar_position += RECORDSIZE;
return &rec_buf;
@ -183,12 +187,19 @@ static void fill_stat_from_header (vfs *me, struct stat *st, union record *heade
}
typedef enum {
STATUS_BADCHECKSUM,
STATUS_SUCCESS,
STATUS_EOFMARK,
STATUS_EOF,
} ReadStatus;
/*
* Return 1 for success, 0 if the checksum is bad, EOF on eof,
* 2 for a record full of zeros (EOF marker).
*
*/
static int read_header (vfs *me, vfs_s_super *archive, int tard)
static ReadStatus
read_header (vfs *me, vfs_s_super *archive, int tard)
{
register int i;
register long sum, signed_sum, recsum;
@ -204,7 +215,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
header = get_next_record (archive, tard);
if (NULL == header)
return EOF;
return STATUS_EOF;
recsum = from_oct (8, header->header.chksum);
@ -227,25 +238,25 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
sum += ' ' * sizeof header->header.chksum;
signed_sum += ' ' * sizeof header->header.chksum;
if (sum == 8 * ' ') {
/*
* This is a zeroed record...whole record is 0's except
* for the 8 blanks we faked for the checksum field.
*/
return 2;
}
/*
* This is a zeroed record...whole record is 0's except
* for the 8 blanks we faked for the checksum field.
*/
if (sum == 8 * ' ')
return STATUS_EOFMARK;
if (sum != recsum && signed_sum != recsum)
return 0;
return STATUS_BADCHECKSUM;
/*
* linkflag on BSDI tar (pax) always '\000'
*/
if(header->header.linkflag == '\000' &&
strlen(header->header.arch_name) &&
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
if (header->header.linkflag == '\000' &&
strlen(header->header.arch_name) &&
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
header->header.linkflag = LF_DIR;
/*
/*
* Good record. Decode file size and return.
*/
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR)
@ -270,7 +281,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
data = get_next_record (archive, tard)->charptr;
if (data == NULL) {
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
return 0;
return STATUS_BADCHECKSUM;
}
written = RECORDSIZE;
if (written > size)
@ -325,7 +336,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR);
if (parent == NULL) {
message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
return 0;
return STATUS_BADCHECKSUM;
}
if (header->header.linkflag == LF_LINK) {
@ -357,7 +368,7 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
while (get_next_record (archive, tard)->ext_hdr.isextended);
inode->u.tar.data_offset = current_tar_position;
}
return 1;
return STATUS_SUCCESS;
}
}
@ -367,8 +378,8 @@ static int read_header (vfs *me, vfs_s_super *archive, int tard)
*/
static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
{
int status = 3; /* Initial status at start of archive */
int prev_status;
ReadStatus status = STATUS_EOFMARK; /* Initial status at start of archive */
ReadStatus prev_status;
int tard;
current_tar_position = 0;
@ -378,33 +389,45 @@ static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
for (;;) {
prev_status = status;
status = read_header (me, archive, tard);
switch (status) {
case 1: /* Valid header */
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
continue;
/*
* If the previous header was good, tell them
* that we are skipping bad ones.
*/
case 0: /* Invalid header */
switch (prev_status) {
case 3: /* Error on first record */
case STATUS_SUCCESS:
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
continue;
/*
* Invalid header:
*
* If the previous header was good, tell them
* that we are skipping bad ones.
*/
case STATUS_BADCHECKSUM:
switch (prev_status){
/* Error on first record */
case STATUS_EOFMARK:
message_2s (1, MSG_ERROR, _("Hmm,...\n%s\ndoesn't look like a tar archive."), name);
/* FALL THRU */
case 2: /* Error after record of zeroes */
case 1: /* Error after header rec */
#if 0
message_1s (0, " Warning ", "Skipping to next file header...");
#endif
case 0: /* Error after error */
/* Error after header rec */
case STATUS_SUCCESS:
/* Error after error */
case STATUS_BADCHECKSUM:
return -1;
case STATUS_EOF:
return 0;
}
case 2: /* Record of zeroes */
/* Record of zeroes */
case STATUS_EOFMARK:
status = prev_status; /* If error after 0's */
/* FALL THRU */
case EOF: /* End of archive */
case STATUS_EOF: /* End of archive */
break;
}
break;

Просмотреть файл

@ -116,10 +116,13 @@ vfs_register (vfs *vfs)
{
int res;
if (!vfs) vfs_die("You can not register NULL.");
if (!vfs)
vfs_die("You can not register NULL.");
res = (vfs->init) ? (*vfs->init)(vfs) : 1;
if (!res) return 0;
if (!res)
return 0;
vfs->next = vfs_list;
vfs_list = vfs;
@ -132,7 +135,8 @@ vfs_type_from_op (char *path)
{
vfs *vfs;
if (!path) vfs_die( "vfs_type_from_op got NULL: impossible" );
if (!path)
vfs_die ("vfs_type_from_op got NULL: impossible");
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
if (vfs->which) {
@ -156,14 +160,15 @@ vfs_strip_suffix_from_filename (char *filename)
char *semi;
char *p;
if (!filename) vfs_die( "vfs_strip_suffix_from_path got NULL: impossible" );
if (!filename)
vfs_die("vfs_strip_suffix_from_path got NULL: impossible");
p = strdup (filename);
if (!(semi = strrchr (p, '#')))
return p;
for (vfs = vfs_list; vfs != &vfs_local_ops; vfs = vfs->next){
if (vfs->which) {
if (vfs->which){
if ((*vfs->which) (vfs, semi + 1) == -1)
continue;
*semi = '\0'; /* Found valid suffix */
@ -203,7 +208,8 @@ vfs_split (char *path, char **inpath, char **op)
char *slash;
vfs *ret;
if (!path) vfs_die("Can not split NULL");
if (!path)
vfs_die("Can not split NULL");
semi = strrchr (path, '#');
if (!semi || !path_magic(path))
@ -243,7 +249,9 @@ vfs_rosplit (char *path)
char *slash;
vfs *ret;
if (!path) vfs_die( "Can not rosplit NULL" );
if (!path)
vfs_die ("Can not rosplit NULL");
semi = strrchr (path, '#');
if (!semi || !path_magic (path))
@ -463,7 +471,8 @@ mc_setctl (char *path, int ctlop, char *arg)
int result;
if (!path)
vfs_die( "You don't want to pass NULL to mc_setctl." );
vfs_die("You don't want to pass NULL to mc_setctl.");
path = vfs_canon (path);
vfs = vfs_type (path);
result = vfs->setctl ? (*vfs->setctl)(vfs, path, ctlop, arg) : 0;
@ -693,7 +702,8 @@ off_t mc_lseek (int fd, off_t offset, int whence)
char *
vfs_canon (char *path)
{
if (!path) vfs_die("Can not canonize NULL");
if (!path)
vfs_die("Can not canonize NULL");
/* Tilde expansion */
if (*path == '~'){
@ -726,9 +736,9 @@ vfs_canon (char *path)
* So we have path of following form:
* /p1/p2#op/.././././p3#op/p4. Good luck.
*/
mad_check( "(pre-canonicalize)", 0);
mad_check("(pre-canonicalize)", 0);
canonicalize_pathname (path);
mad_check( "(post-canonicalize)", 0);
mad_check("(post-canonicalize)", 0);
return strdup (path);
}
@ -1476,7 +1486,7 @@ int vfs_parse_filedate(int idx, time_t *t)
char *p;
struct tm tim;
int d[3];
int swap, got_year = 0;
int got_year = 0;
/* Let's setup default time values */
tim.tm_year = current_year;
@ -1577,7 +1587,7 @@ int vfs_parse_filedate(int idx, time_t *t)
int
vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
{
int idx, idx2, num_cols, isconc = 0;
int idx, idx2, num_cols;
int i;
char *p_copy;
@ -1644,13 +1654,12 @@ vfs_parse_ls_lga (char *p, struct stat *s, char **filename, char **linkname)
/* This is device */
if (S_ISCHR (s->st_mode) || S_ISBLK (s->st_mode)){
int maj, min;
if (!is_num (idx2) || sscanf(columns [idx2], " %d,", &maj) != 1)
goto error;
if (!is_num (++idx2) || sscanf(columns [idx2], " %li", &min) != 1)
if (!is_num (++idx2) || sscanf(columns [idx2], " %d", &min) != 1)
goto error;
#ifdef HAVE_ST_RDEV

Просмотреть файл

@ -145,35 +145,52 @@ struct vfs_s_data {
};
/* entries and inodes */
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super, struct stat *initstat);
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir, vfs_s_entry *ent);
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir, vfs_s_inode *parent);
struct vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name, struct vfs_s_inode *parent, mode_t mode);
vfs_s_entry *vfs_s_automake(vfs *me, vfs_s_inode *dir, char *path, int flags);
vfs_s_entry *vfs_s_find_entry_tree(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
vfs_s_entry *vfs_s_find_entry_linear(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
vfs_s_inode *vfs_s_find_inode(vfs *me, vfs_s_inode *root, char *path, int follow, int flags);
vfs_s_inode *vfs_s_find_root(vfs *me, vfs_s_entry *entry);
struct vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry, int follow);
vfs_s_inode *vfs_s_new_inode (vfs *me, vfs_s_super *super,
struct stat *initstat);
vfs_s_entry *vfs_s_new_entry (vfs *me, char *name, vfs_s_inode *inode);
void vfs_s_free_entry (vfs *me, vfs_s_entry *ent);
void vfs_s_insert_entry (vfs *me, vfs_s_inode *dir,
vfs_s_entry *ent);
struct stat *vfs_s_default_stat (vfs *me, mode_t mode);
void vfs_s_add_dots (vfs *me, vfs_s_inode *dir,
vfs_s_inode *parent);
vfs_s_entry *vfs_s_generate_entry (vfs *me, char *name,
struct vfs_s_inode *parent, mode_t mode);
vfs_s_entry *vfs_s_automake (vfs *me, vfs_s_inode *dir, char *path,
int flags);
vfs_s_entry *vfs_s_find_entry_tree (vfs *me, vfs_s_inode *root, char *path,
int follow, int flags);
vfs_s_entry *vfs_s_find_entry_linear (vfs *me, vfs_s_inode *root, char *path,
int follow, int flags);
vfs_s_inode *vfs_s_find_inode (vfs *me, vfs_s_inode *root, char *path,
int follow, int flags);
vfs_s_inode *vfs_s_find_root (vfs *me, vfs_s_entry *entry);
vfs_s_entry *vfs_s_resolve_symlink (vfs *me, vfs_s_entry *entry,
int follow);
/* superblock games */
vfs_s_super *vfs_s_new_super (vfs *me);
void vfs_s_free_super (vfs *me, vfs_s_super *super);
vfs_s_super *vfs_s_new_super (vfs *me);
void vfs_s_free_super (vfs *me, vfs_s_super *super);
/* outside interface */
char *vfs_s_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive, int flags);
char *vfs_s_get_path (vfs *me, char *inname, vfs_s_super **archive, int flags);
void vfs_s_invalidate (vfs *me, vfs_s_super *super);
char *vfs_s_get_path_mangle (vfs *me, char *inname, vfs_s_super **archive,
int flags);
char *vfs_s_get_path (vfs *me, char *inname, vfs_s_super **archive,
int flags);
void vfs_s_invalidate (vfs *me, vfs_s_super *super);
char *vfs_s_fullpath (vfs *me, vfs_s_inode *ino);
/* readdir & friends */
vfs_s_super *vfs_s_super_from_path (vfs *me, char *name);
vfs_s_inode *vfs_s_inode_from_path (vfs *me, char *name, int flags);
void * vfs_s_opendir (vfs *me, char *dirname);
void * vfs_s_readdir (void *data);
vfs_s_super *vfs_s_super_from_path (vfs *me, char *name);
vfs_s_inode *vfs_s_inode_from_path (vfs *me, char *name, int flags);
void *vfs_s_opendir (vfs *me, char *dirname);
void *vfs_s_readdir (void *data);
int vfs_s_telldir (void *data);
void vfs_s_seekdir (void *data, int offset);
int vfs_s_closedir (void *data);
int vfs_s_chdir (vfs *me, char *path);
/* stat & friends */
int vfs_s_stat (vfs *me, char *path, struct stat *buf);
int vfs_s_lstat (vfs *me, char *path, struct stat *buf);
@ -184,16 +201,19 @@ int vfs_s_read (void *fh, char *buffer, int count);
int vfs_s_write (void *fh, char *buffer, int count);
int vfs_s_lseek (void *fh, off_t offset, int whence);
int vfs_s_close (void *fh);
/* mc support */
void vfs_s_fill_names (vfs *me, void (*func)(char *));
int vfs_s_ferrno(vfs *me);
void vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino);
char *vfs_s_getlocalcopy (vfs *me, char *path);
/* stamping support */
vfsid vfs_s_getid (vfs *me, char *path, struct vfs_stamping **parent);
int vfs_s_nothingisopen (vfsid id);
void vfs_s_free (vfsid id);
int vfs_s_setctl (vfs *me, char *path, int ctlop, char *arg);
/* network filesystems support */
int vfs_s_select_on_two (int fd1, int fd2);
int vfs_s_get_line (vfs *me, int sock, char *buf, int buf_len, char term);