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> 1999-01-08 Jonathan Blandford <jrb@redhat.com>
* glayout.c: now open the new (non-functional) dialog box. If you * 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++) for (i = 3; i < top; i++)
close (i); close (i);
*pid = fork (); if (!(flags & EXECUTE_WAIT))
*pid = fork ();
if (*pid == 0){ if (*pid == 0){
if (flags & EXECUTE_AS_SHELL) if (flags & EXECUTE_AS_SHELL)
execl (shell, shell, "-c", command, (char *) 0); 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); _exit (0);
} }
if (*pid != 0 && (flags & EXECUTE_WAIT)){
int status;
waitpid (*pid, &status, 0);
}
sigaction (SIGINT, &save_intr, NULL); sigaction (SIGINT, &save_intr, NULL);
sigaction (SIGQUIT, &save_quit, NULL); sigaction (SIGQUIT, &save_quit, NULL);
sigaction (SIGTSTP, &save_stop, NULL); sigaction (SIGTSTP, &save_stop, NULL);
#ifdef SCO_FLAVOR
waitpid(-1, NULL, WNOHANG);
#endif /* SCO_FLAVOR */
return WEXITSTATUS(status); return WEXITSTATUS(status);
} }

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

@ -108,6 +108,7 @@ void my_putenv (char*, char*);
#define EXECUTE_TEMPFILE 2 #define EXECUTE_TEMPFILE 2
#define EXECUTE_AS_SHELL 4 #define EXECUTE_AS_SHELL 4
#define EXECUTE_SETUID 8 #define EXECUTE_SETUID 8
#define EXECUTE_WAIT 16
int my_system (int flags, const char *shell, const char *command); 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); int my_system_get_child_pid (int flags, const char *shell, const char *command, pid_t *pid);
void save_stop_handler (void); 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> Sat Jan 9 19:15:00 1999 Norbert Warmuth <nwarmuth@privat.circular.de>
* vfs.c (vfs_timeout_handler): Guard from recursive invocation. * 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; vfs_s_inode *ino;
ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode"); ino = xmalloc(sizeof (vfs_s_inode), "Dcache inode");
if (!ino) return NULL; if (!ino)
return NULL;
ino->linkname = ino->localname = 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) if (name)
entry->name = strdup (name); entry->name = strdup (name);
else entry->name = NULL; else
entry->name = NULL;
entry->dir = NULL; entry->dir = NULL;
entry->next = NULL; entry->next = NULL;
entry->prevp = 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) 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 */ /* ==0 can happen if freshly created entry is deleted */
if(ino->st.st_nlink <= 1) { 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; int is_dot = 0;
if (ent->prevp) { /* It is possible that we are deleting freshly created entry */ if (ent->prevp) { /* It is possible that we are deleting freshly created entry */
*ent->prevp = ent->next; *ent->prevp = ent->next;
if (ent->next) ent->next->prevp = ent->prevp; if (ent->next)
ent->next->prevp = ent->prevp;
} }
if (ent->name) { 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; 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->prevp = ep;
ent->next = NULL; ent->next = NULL;
ent->dir = dir; 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) 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; vfs_s_entry* ent = NULL;
if (!(flags & FL_DIR)) { 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); super = vfs_s_new_super (me);
result = MEDATA->open_archive (me, super, archive_name, op); result = MEDATA->open_archive (me, super, archive_name, op);
@ -523,8 +528,10 @@ void * vfs_s_opendir (vfs *me, char *dirname)
struct dirhandle *info; struct dirhandle *info;
dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW); dir = vfs_s_inode_from_path (me, dirname, FL_DIR | FL_FOLLOW);
if (!dir) return NULL; if (!dir)
if (!S_ISDIR (dir->st.st_mode)) ERRNOR (ENOTDIR, NULL); return NULL;
if (!S_ISDIR (dir->st.st_mode))
ERRNOR (ENOTDIR, NULL);
dir->st.st_nlink++; dir->st.st_nlink++;
#if 0 #if 0
@ -556,7 +563,7 @@ void * vfs_s_readdir (void *data)
strcpy (&(dir.dir.d_name [0]), info->cur->name); strcpy (&(dir.dir.d_name [0]), info->cur->name);
else else
vfs_die( "Null in structure-can not happen"); vfs_die( "Null in structure-can not happen");
#ifndef DIRENT_LENGTH_COMPUTED #ifndef DIRENT_LENGTH_COMPUTED
dir.d_namlen = strlen (dir.dir.d_name); dir.d_namlen = strlen (dir.dir.d_name);
#endif #endif
@ -573,7 +580,8 @@ int vfs_s_telldir (void *data)
cur = info->dir->subdir; cur = info->dir->subdir;
while (cur!=NULL) { while (cur!=NULL) {
if (cur == info->cur) return num; if (cur == info->cur)
return num;
num++; num++;
cur = cur->next; 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; 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; *buf = ino->st;
return 0; return 0;
} }
@ -640,9 +649,11 @@ int vfs_s_readlink (vfs *me, char *path, char *buf, int size)
struct vfs_s_inode *ino; struct vfs_s_inode *ino;
ino = vfs_s_inode_from_path(me, path, 0); 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); strncpy (buf, ino->linkname, size);
*(buf+size-1) = 0; *(buf+size-1) = 0;
return strlen(buf); return strlen(buf);
@ -681,7 +692,8 @@ void *vfs_s_open (vfs *me, char *file, int flags, int mode)
was_changed = 1; 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 = (struct vfs_s_fh *) xmalloc (sizeof (struct vfs_s_fh), "Direntry: filehandle");
fh->pos = 0; fh->pos = 0;
@ -810,8 +822,10 @@ int vfs_s_close (void *fh)
res = MEDATA->fh_close (me, fh); res = MEDATA->fh_close (me, fh);
if (FH->changed && MEDATA->file_store) { if (FH->changed && MEDATA->file_store) {
char *s = vfs_s_fullpath( me, FH->ino ); char *s = vfs_s_fullpath( me, FH->ino );
if (!s) res = -1; if (!s)
else res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname); res = -1;
else
res = MEDATA->file_store (me, FH_SUPER, s, FH->ino->localname);
vfs_s_invalidate(me, FH_SUPER); vfs_s_invalidate(me, FH_SUPER);
} }
if (FH->handle) if (FH->handle)
@ -848,7 +862,9 @@ void
vfs_s_dump(vfs *me, char *prefix, vfs_s_inode *ino) 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 ); 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 else
{ {
struct vfs_s_entry *ent; 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; va_list ap;
char *str; char *str;
int n, status; int status;
FILE *logfile = MEDATA->logfile; FILE *logfile = MEDATA->logfile;
va_start (ap, fmt); va_start (ap, fmt);

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

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

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

@ -50,12 +50,12 @@ static int sfs_flags[ MAXFS ];
#define F_NOLOCALCOPY 4 #define F_NOLOCALCOPY 4
#define F_FULLMATCH 8 #define F_FULLMATCH 8
static int uptodate( char *name, char *cache ) static int uptodate (char *name, char *cache)
{ {
return 1; return 1;
} }
static int vfmake( vfs *me, char *name, char *cache ) static int vfmake (vfs *me, char *name, char *cache)
{ {
char *inpath, *op; char *inpath, *op;
int w; int w;
@ -63,72 +63,77 @@ static int vfmake( vfs *me, char *name, char *cache )
char *s, *t = pad; char *s, *t = pad;
int was_percent = 0; int was_percent = 0;
vfs_split( name, &inpath, &op ); vfs_split (name, &inpath, &op);
if ((w = (*me->which)( me, op )) == -1) if ((w = (*me->which) (me, op)) == -1)
vfs_die( "This cannot happen... Hopefully.\n" ); 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_2) || (!inpath) || (!*inpath)); else return -1; */
if (!(sfs_flags[w] & F_NOLOCALCOPY)) if (!(sfs_flags[w] & F_NOLOCALCOPY))
name = mc_getlocalcopy( name ); name = mc_getlocalcopy (name);
else else
name = strdup( name ); name = strdup (name);
s = sfs_command[w]; s = sfs_command[w];
#define COPY_CHAR if (t-pad>10200) return -1; else *t++ = *s; #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) { while (*s) {
if (was_percent) { if (was_percent) {
switch (*s) { switch (*s) {
case '1': COPY_STRING( name ); break; case '1': COPY_STRING (name); break;
case '2': COPY_STRING( op + strlen( sfs_prefix[w] ) ); break; case '2': COPY_STRING (op + strlen (sfs_prefix[w])); break;
case '3': COPY_STRING( cache ); break; case '3': COPY_STRING (cache); break;
case '%': COPY_CHAR; break; case '%': COPY_CHAR; break;
} }
was_percent = 0; was_percent = 0;
} else { } else {
if (*s == '%') was_percent = 1; if (*s == '%')
else COPY_CHAR; was_percent = 1;
else
COPY_CHAR;
} }
s++; 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 -1;
} }
return 0; /* OK */ return 0; /* OK */
} }
static char *redirect( vfs *me, char *name ) static char *
redirect (vfs *me, char *name)
{ {
struct cachedfile *cur = head; struct cachedfile *cur = head;
uid_t uid = vfs_uid; uid_t uid = vfs_uid;
char *cache, *xname; char *cache, *xname;
int handle; int handle;
while (cur) { while (cur){
if ((!strcmp( name, cur->name )) && if ((!strcmp (name, cur->name)) &&
(uid == cur->uid) && (uid == cur->uid) &&
(uptodate( cur->name, cur->cache ))) (uptodate (cur->name, cur->cache)))
/* FIXME: when not uptodate, we might want to kill cache /* FIXME: when not uptodate, we might want to kill cache
* file immediately, not to wait until timeout. */ { * file immediately, not to wait until timeout. */ {
vfs_stamp( &vfs_sfs_ops, cur ); vfs_stamp (&vfs_sfs_ops, cur);
return cur->cache; return cur->cache;
} }
cur = cur->next; 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) if (handle == -1)
return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US"; return "/SOMEONE_PLAYING_DIRTY_TMP_TRICKS_ON_US";
close(handle);
xname = strdup( name ); close (handle);
if (!vfmake( me, name, cache )) {
cur = xmalloc( sizeof(struct cachedfile), "SFS cache" ); xname = strdup (name);
if (!vfmake (me, name, cache)){
cur = xmalloc (sizeof(struct cachedfile), "SFS cache");
cur->name = xname; cur->name = xname;
cur->cache = strdup(cache); cur->cache = cache;
cur->uid = uid; cur->uid = uid;
cur->next = head; cur->next = head;
head = cur; head = cur;
@ -143,14 +148,13 @@ static char *redirect( vfs *me, char *name )
return "/I_MUST_NOT_EXIST"; 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 *sfs_info;
int fd; int fd;
REDIR; path = redirect (me, path);
fd = open (path, flags, mode); fd = open (path, flags, mode);
if (fd == -1) if (fd == -1)
return 0; 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) static int sfs_stat (vfs *me, char *path, struct stat *buf)
{ {
REDIR; path = redirect (me, path);
return stat (path, buf); return stat (path, buf);
} }
static int sfs_lstat (vfs *me, char *path, struct stat *buf) static int sfs_lstat (vfs *me, char *path, struct stat *buf)
{ {
REDIR; path = redirect (me, path);
#ifndef HAVE_STATLSTAT #ifndef HAVE_STATLSTAT
return lstat (path,buf); return lstat (path,buf);
#else #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) static int sfs_chmod (vfs *me, char *path, int mode)
{ {
REDIR; path = redirect (me, path);
return chmod (path, mode); return chmod (path, mode);
} }
static int sfs_chown (vfs *me, char *path, int owner, int group) static int sfs_chown (vfs *me, char *path, int owner, int group)
{ {
REDIR; path = redirect (me, path);
return chown (path, owner, group); return chown (path, owner, group);
} }
static int sfs_utime (vfs *me, char *path, struct utimbuf *times) static int sfs_utime (vfs *me, char *path, struct utimbuf *times)
{ {
REDIR; path = redirect (me, path);
return utime (path, times); return utime (path, times);
} }
static int sfs_readlink (vfs *me, char *path, char *buf, int size) static int sfs_readlink (vfs *me, char *path, char *buf, int size)
{ {
REDIR; path = redirect (me, path);
return readlink (path, buf, size); return readlink (path, buf, size);
} }
@ -220,10 +224,10 @@ static vfsid sfs_getid (vfs *me, char *path, struct vfs_stamping **parent)
*parent = NULL; *parent = NULL;
{ {
char *path2 = strdup( path ); char *path2 = strdup (path);
v = vfs_split (path2, NULL, NULL); v = vfs_split (path2, NULL, NULL);
id = (*v->getid) (v, path2, &par); id = (*v->getid) (v, path2, &par);
free( path2 ); free (path2);
} }
if (id != (vfsid)-1) { if (id != (vfsid)-1) {
@ -272,7 +276,7 @@ static int sfs_nothingisopen (vfsid id)
static char *sfs_getlocalcopy (vfs *me, char *path) static char *sfs_getlocalcopy (vfs *me, char *path)
{ {
REDIR; path = redirect (me, path);
return strdup (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) static int sfs_init (vfs *me)
{ {
FILE *cfg = fopen( LIBDIR "extfs/sfs.ini", "r" ); FILE *cfg = fopen (LIBDIR "extfs/sfs.ini", "r");
if (!cfg) {
fprintf( stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n" ); if (!cfg){
fprintf (stderr, "Warning: " LIBDIR "extfs/sfs.ini not found\n");
return 0; return 0;
} }
sfs_no = 0; sfs_no = 0;
while ( sfs_no < MAXFS ) { while (sfs_no < MAXFS){
char key[256]; char key[256];
char *c, *semi = NULL, flags = 0; char *c, *semi = NULL, flags = 0;
int i; int i;
if (!fgets( key, 250, cfg )) if (!fgets (key, 250, cfg))
break; break;
if (*key == '#') if (*key == '#')
continue; continue;
for (i=0; i<strlen(key); i++) for (i = 0; i < strlen (key); i++)
if ((key[i]==':') || (key[i]=='/')) if ((key[i]==':') || (key[i]=='/')){
{ semi = key+i; if (key[i]=='/') { key[i]=0; flags |= F_FULLMATCH; } break; } semi = key+i;
if (key [i] == '/'){
key [i] = 0;
flags |= F_FULLMATCH;
}
break;
}
if (!semi) { if (!semi){
fprintf( stderr, "Warning: Invalid line %s in sfs.ini.\n", key ); fprintf (stderr, "Warning: Invalid line %s in sfs.ini.\n", key);
continue; continue;
} }
@ -316,13 +327,13 @@ static int sfs_init (vfs *me)
case '2': flags |= F_2; break; case '2': flags |= F_2; break;
case 'R': flags |= F_NOLOCALCOPY; break; case 'R': flags |= F_NOLOCALCOPY; break;
default: 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++;
} }
c++; c++;
*(semi+1) = 0; *(semi+1) = 0;
if ((semi = strchr( c, '\n'))) if ((semi = strchr (c, '\n')))
*semi = 0; *semi = 0;
sfs_prefix [sfs_no] = strdup (key); sfs_prefix [sfs_no] = strdup (key);
@ -330,22 +341,25 @@ static int sfs_init (vfs *me)
sfs_flags [sfs_no] = flags; sfs_flags [sfs_no] = flags;
sfs_no++; sfs_no++;
} }
fclose(cfg); fclose (cfg);
return 1; return 1;
} }
static void sfs_done (vfs *me) static void
sfs_done (vfs *me)
{ {
int i; int i;
for (i=0; i<sfs_no; i++) {
free(sfs_prefix [i]); for (i = 0; i < sfs_no; i++){
free(sfs_command [i]); free (sfs_prefix [i]);
free (sfs_command [i]);
sfs_prefix [i] = sfs_command [i] = NULL; sfs_prefix [i] = sfs_command [i] = NULL;
} }
sfs_no = 0; sfs_no = 0;
} }
static int sfs_which (vfs *me, char *path) static int
sfs_which (vfs *me, char *path)
{ {
int i; int i;
@ -354,7 +368,7 @@ static int sfs_which (vfs *me, char *path)
if (!strcmp (path, sfs_prefix [i])) if (!strcmp (path, sfs_prefix [i]))
return i; return i;
} else } else
if (!strncmp (path, sfs_prefix [i], strlen( sfs_prefix[i]) )) if (!strncmp (path, sfs_prefix [i], strlen (sfs_prefix [i])))
return 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 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 */ return NULL; /* An error has occurred */
current_tar_position += RECORDSIZE; current_tar_position += RECORDSIZE;
return &rec_buf; 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, * Return 1 for success, 0 if the checksum is bad, EOF on eof,
* 2 for a record full of zeros (EOF marker). * 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 int i;
register long sum, signed_sum, recsum; 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); header = get_next_record (archive, tard);
if (NULL == header) if (NULL == header)
return EOF; return STATUS_EOF;
recsum = from_oct (8, header->header.chksum); 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; sum += ' ' * sizeof header->header.chksum;
signed_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
* This is a zeroed record...whole record is 0's except * for the 8 blanks we faked for the checksum field.
* for the 8 blanks we faked for the checksum field. */
*/ if (sum == 8 * ' ')
return 2; return STATUS_EOFMARK;
}
if (sum != recsum && signed_sum != recsum) if (sum != recsum && signed_sum != recsum)
return 0; return STATUS_BADCHECKSUM;
/* /*
* linkflag on BSDI tar (pax) always '\000' * linkflag on BSDI tar (pax) always '\000'
*/ */
if(header->header.linkflag == '\000' && if (header->header.linkflag == '\000' &&
strlen(header->header.arch_name) && strlen(header->header.arch_name) &&
header->header.arch_name[strlen(header->header.arch_name) - 1] == '/') header->header.arch_name[strlen(header->header.arch_name) - 1] == '/')
header->header.linkflag = LF_DIR; header->header.linkflag = LF_DIR;
/* /*
* Good record. Decode file size and return. * Good record. Decode file size and return.
*/ */
if (header->header.linkflag == LF_LINK || header->header.linkflag == LF_DIR) 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; data = get_next_record (archive, tard)->charptr;
if (data == NULL) { if (data == NULL) {
message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file")); message_1s (1, MSG_ERROR, _("Unexpected EOF on archive file"));
return 0; return STATUS_BADCHECKSUM;
} }
written = RECORDSIZE; written = RECORDSIZE;
if (written > size) 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); parent = vfs_s_find_inode (me, archive->root, q, LINK_NO_FOLLOW, FL_MKDIR);
if (parent == NULL) { if (parent == NULL) {
message_1s (1, MSG_ERROR, _("Inconsistent tar archive")); message_1s (1, MSG_ERROR, _("Inconsistent tar archive"));
return 0; return STATUS_BADCHECKSUM;
} }
if (header->header.linkflag == LF_LINK) { 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); while (get_next_record (archive, tard)->ext_hdr.isextended);
inode->u.tar.data_offset = current_tar_position; 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) static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
{ {
int status = 3; /* Initial status at start of archive */ ReadStatus status = STATUS_EOFMARK; /* Initial status at start of archive */
int prev_status; ReadStatus prev_status;
int tard; int tard;
current_tar_position = 0; current_tar_position = 0;
@ -378,33 +389,45 @@ static int open_archive (vfs *me, vfs_s_super *archive, char *name, char *op)
for (;;) { for (;;) {
prev_status = status; prev_status = status;
status = read_header (me, archive, tard); status = read_header (me, archive, tard);
switch (status) { switch (status) {
case 1: /* Valid header */ case STATUS_SUCCESS:
skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE); skip_n_records (archive, tard, (hstat.st_size + RECORDSIZE - 1) / RECORDSIZE);
continue; continue;
/*
* If the previous header was good, tell them /*
* that we are skipping bad ones. * Invalid header:
*/ *
case 0: /* Invalid header */ * If the previous header was good, tell them
switch (prev_status) { * that we are skipping bad ones.
case 3: /* Error on first record */ */
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); message_2s (1, MSG_ERROR, _("Hmm,...\n%s\ndoesn't look like a tar archive."), name);
/* FALL THRU */ /* FALL THRU */
case 2: /* Error after record of zeroes */
case 1: /* Error after header rec */ /* Error after header rec */
#if 0 case STATUS_SUCCESS:
message_1s (0, " Warning ", "Skipping to next file header..."); /* Error after error */
#endif
case 0: /* Error after error */ case STATUS_BADCHECKSUM:
return -1; 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 */ status = prev_status; /* If error after 0's */
/* FALL THRU */ /* FALL THRU */
case EOF: /* End of archive */
case STATUS_EOF: /* End of archive */
break; break;
} }
break; break;

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

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

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

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