extfs ulha Bugfix



Hi,

The ulha module from extfs can't handle filenames with spaces inside the
archive (for the record, Giulio Canevari and me found it). I attached a
patch to the module so it works again. I also fixed a small other issue
with the permission string handling. This problem doesn't appear with my
lha version but using a fake output I tried to fix this special case.

I plan to include this fix into avfs (avf.sf.net) too so I welcome some
feedback. Especially I don't really like the filename extraction using
gensub() but I don't know a better method with awk.

Best Regards,

Ralf Hoffmann

-- 
Homepage: http://www.boomerangsworld.de
E-Mail: Ralf Hoffmann <ralf boomerangsworld de>
  english or german




--- ulha.in	2004-12-27 13:10:12.000000000 +0100
+++ ulha.in-new	2006-01-17 20:40:06.000000000 +0100
@@ -14,6 +14,9 @@
 # Tested with lha v1.01 and lharc v1.02
 # Information and sources for other forms of lha/lzh appreciated
 
+# Additional changes for file names with spaces by
+# 2006-01-17 Ralf Hoffmann <ralf boomerangsworld de>
+
 # Nota bene:
 # There are several compression utilities which produce *.lha files.
 # LHArc and LHa in exist several versions, and their listing output varies.
@@ -41,15 +44,17 @@
 {
    # List the contents of the archive and sort it out    
    $LHA_LIST "$1" | $AWK -v uid=`id -nu` -v gid=`id -ng` '
-      # Strip a leading '/' if present in a filepath
-      $(NF) ~ /^\// { $(NF) = substr($NF,2) }
       # Print the line this way if there is no permission string
       $1 ~ /^\[.*\]/ {
+         # Get the filename, everything from seventh field to the end
+         filename = gensub("^[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* (.*)$","\\1","g");
+         # Strip a leading '/' if present in a filepath
+         if (filename ~ /^\//) { filename = substr(filename,2) }
          # Invent a generic permission
-         $1 = ($NF ~ /\/$/) ? "drwxr-xr-x":"-rwxr--r--";
+         $1 = (filename ~ /\/$/) ? "drwxr-xr-x":"-rwxr--r--";
          # Print it
          printf "%s 1 %-8s %-8s %-8d %s %s %s %s\n",
-                 $1, uid, gid, $2, $4, $5, $6, $7;
+                 $1, uid, gid, $2, $4, $5, $6, filename;
          # Get the next line of the list
          next;
       }
@@ -57,17 +62,32 @@
       $1 !~ /^\[.*\]/ {
          # If the permissions and UID run together
          if ($1 ~ /\//) {
+            # Get the filename, everything from seventh field to the end
+            filename = gensub("^[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* (.*)$","\\1","g");
             $8 = $7;
             $7 = $6;
             $6 = $5;
             $5 = $4;
             $3 = $2;
-            $2 = substr($1,10);
-            $1 = substr($1,1,9);
+            # Test whether permission is 9 or 10 characters
+            # it wont always work if UID is not numerical
+            if (substr($1,10,1) ~ /[-tTx]/) {
+              $2 = substr($1,11);
+              $1 = substr($1,1,10);
+            } else {
+              $2 = substr($1,10);
+              $1 = substr($1,1,9);
+            }
+         } else {
+            # Get the filename, everything from eighth field to the end
+            filename = gensub("^[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* *[^ ]* (.*)$","\\1","g");
          }
+         # Strip a leading '/' if present in a filepath
+         if (filename ~ /^\//) { filename = substr(filename,2) }
+
          # If the permission string is missing a type
          if (length($1) == 9) {
-            if ($NF ~ /\/$/)
+            if (filename ~ /\/$/)
                $1 = ("d" $1);
             else
                $1 = ("-" $1);
@@ -76,7 +96,7 @@
          # Well, that is the intent.  At the moment mc is translating them.
          split($2, id, "/");
          printf "%s 1 %-8d %-8d %-8d %s %s %s %s\n",
-                 $1, id[1], id[2], $3, $5, $6, $7, $8;
+                 $1, id[1], id[2], $3, $5, $6, $7, filename;
          # Get the next line of the list
          next;
       }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]