Browse Source

We got some complaints about much slower ftpfs in 4.1.36 (ok, maybe a bit
exaggerated because I only saw two complaints). I added the old method
to resolve symlinks and made it the default. When someone complains about
4.5.2 we can change defaults at will ;-).


Mon Nov 23 21:19:43 1998 Norbert Warmuth <nwarmuth@privat.circular.de>

* vfs/ftpfs.c (resolve_symlink_with_ls_options): that's resolve_symlinks
we used up to release 4.1.35. It uses LIST -lLa to get symlink stats.

(resolve_symlink_without_ls_options): that's resolve_symlinks
we used in release 4.1.36 and 4.5.[01]. It gets symlink stats from the
directory cache fetching directories if necessary. We got some
complaints about slower ftpfs in the above releases. Now this methode
is no longer the default methode to resolve symbolic links. It is still
needed for ftp servers which don't understand the LIST -lLa command.

(resolve_symlink): Dispatch between the two methods to
resolve symlinks.

Norbert Warmuth 26 years ago
parent
commit
42e0c7ef84
2 changed files with 99 additions and 3 deletions
  1. 15 0
      vfs/ChangeLog
  2. 84 3
      vfs/ftpfs.c

+ 15 - 0
vfs/ChangeLog

@@ -1,3 +1,18 @@
+Mon Nov 23 21:19:43 1998  Norbert Warmuth  <nwarmuth@privat.circular.de>
+
+	* ftpfs.c (resolve_symlink_with_ls_options): that's resolve_symlinks
+	we used up to release 4.1.35. It uses LIST -lLa to get symlink stats.
+
+	(resolve_symlink_without_ls_options): that's resolve_symlinks
+	we used in release 4.1.36 and 4.5.[01]. It gets symlink stats from the
+	directory cache fetching directories if necessary. We got some 
+	complaints about slower ftpfs in the above releases. Now this methode
+	is no longer the default methode to resolve symbolic links. It is still
+	needed for ftp servers which don't understand the LIST -lLa command.
+	
+	(resolve_symlink): Dispatch between the two methods to
+	resolve symlinks.
+
 Sat Nov 21 21:38:08 1998  Pavel Machek  <pavel@bug.ucw.cz>
 
 	* vfs.c (vfs_parse_ls_lga): corrected stupid bug in parse_ls_lga,

+ 84 - 3
vfs/ftpfs.c

@@ -1010,14 +1010,12 @@ my_abort (struct connection *bucket, int dsock)
 }
 
 static void
-resolve_symlink(struct connection *bucket, struct dir *dir)
+resolve_symlink_without_ls_options(struct connection *bucket, struct dir *dir)
 {
     struct linklist *flist;
     struct direntry *fe, *fel;
     char tmp[MC_MAXPATHLEN];
     
-    print_vfs_message("Resolving symlink...");
-
     dir->symlink_status = FTPFS_RESOLVING_SYMLINKS;
     for (flist = dir->file_list->next; flist != dir->file_list; flist = flist->next) {
         /* flist->data->l_stat is alread initialized with 0 */
@@ -1070,7 +1068,90 @@ resolve_symlink(struct connection *bucket, struct dir *dir)
         }
     }
     dir->symlink_status = FTPFS_RESOLVED_SYMLINKS;
+}
+
+static void
+resolve_symlink_with_ls_options(struct connection *bucket, struct dir *dir)
+{
+    char  buffer[2048] = "", *filename;
+    int sock;
+    FILE *fp;
+    struct stat s;
+    struct linklist *flist;
+    struct direntry *fe;
+    
+    dir->symlink_status = FTPFS_RESOLVED_SYMLINKS;
+    if (strchr (dir->remote_path, ' ')) {
+        if (ftpfs_chdir_internal (bucket, dir->remote_path) != COMPLETE) {
+            print_vfs_message("ftpfs: CWD failed.");
+	    return;
+        }
+        sock = open_data_connection (bucket, "LIST -lLa", ".", TYPE_ASCII, 0);
+    }
+    else
+        sock = open_data_connection (bucket, "LIST -lLa", 
+                                     dir->remote_path, TYPE_ASCII, 0);
+
+    if (sock == -1) {
+	print_vfs_message("ftpfs: couldn't resolve symlink");
+	return;
+    }
+    
+    fp = fdopen(sock, "r");
+    if (fp == NULL) {
+	close(sock);
+	print_vfs_message("ftpfs: couldn't resolve symlink");
+	return;
+    }
+    enable_interrupt_key();
+    flist = dir->file_list->next;
+    while (1) {
+	do {
+	    if (flist == dir->file_list)
+		goto done;
+	    fe = flist->data;
+	    flist = flist->next;
+	} while (!S_ISLNK(fe->s.st_mode));
+	while (1) {
+	    if (fgets (buffer, sizeof (buffer), fp) == NULL)
+		goto done;
+	    if (logfile){
+		fputs (buffer, logfile);
+	        fflush (logfile);
+	    }
+	    if (vfs_parse_ls_lga (buffer, &s, &filename, NULL)) {
+		int r = strcmp(fe->name, filename);
+		free(filename);
+		if (r == 0) {
+		    fe->l_stat = xmalloc(sizeof(struct stat), 
+					 "resolve_symlink: struct stat");
+		    if (fe->l_stat == NULL)
+			goto done;
+		    *fe->l_stat = s;
+                    (*fe->l_stat).st_ino = bucket->__inode_counter++;
+		    break;
+		}
+		if (r < 0)
+		    break;
+	    }
+	}
+    }
+done:
+    while (fgets(buffer, sizeof(buffer), fp) != NULL);
+    disable_interrupt_key();
+    fclose(fp);
+    get_reply(qsock(bucket), NULL, 0);
+}
 
+static void
+resolve_symlink(struct connection *bucket, struct dir *dir)
+{
+    print_vfs_message("Resolving symlink...");
+
+    if (bucket->strict_rfc959_list_cmd) 
+	resolve_symlink_without_ls_options(bucket, dir);
+    else
+        resolve_symlink_with_ls_options(bucket, dir);
 }