Long file name support for smbclient

Rob Riggs rob at devilsthumb.com
Sun Apr 12 01:01:25 GMT 1998


smbclient can create GNU tar files with long file names,
but cannot restore them. The included patch will rectify
this. This patch is against 1.9.18.p4.

-Rob
-- 
Rob Riggs                        Devil's Thumb Entertainment
Network Administrator            Boulder, CO - (303) 938-1200
rob at DevilsThumb.COM              http://www.DevilsThumb.COM/~rob
"The notion of errors is ill-defined." - IRIX 'netstat' man page
-------------- next part --------------
--- clitar.c.orig2	Sat Apr 11 13:45:45 1998
+++ clitar.c	Sat Apr 11 18:08:45 1998
@@ -155,6 +155,7 @@
   long chk, fchk;
   int i;
   char *jp;
+  static char   *long_file_name;
 
   /*
    * read in a "standard" tar format header - we're not that interested
@@ -184,23 +185,43 @@
       return -1;
     }
 
-  strcpy(finfo->name, prefix);
-
-  /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
-  unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
-	       strlen(hb->dbuf.name) + 1);
-
 /* can't handle links at present */
   if (hb->dbuf.linkflag != '0') {
-    if (hb->dbuf.linkflag == 0) {
+    char  *bp;
+    long  tar_size;
+    switch (hb->dbuf.linkflag) {
+    case 0:
       DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
-		finfo->name));
-    } else { 
+        finfo->name));
+	  break;
+    case 'L':
+      tar_size=unoct(hb->dbuf.size, sizeof(hb->dbuf.size)) + 1;
+      if ((bp=(char *) malloc((size_t) tar_size )) == NULL) {
+        DEBUG(0, ("Out of memory!"));
+        return -1;
+      }
+      memcpy((void *) bp, (const void *) hb+TBLOCK, (size_t) tar_size);
+      long_file_name=bp;
+      return tar_size;
+      break;
+    default:
       DEBUG(0, ("this tar file appears to contain some kind of link - ignoring\n"));
       return -2;
     }
+  } else {
+    strcpy(finfo->name, prefix);
+
+    /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
+    if (long_file_name) {
+      unfixtarname(finfo->name + strlen(prefix),
+        long_file_name, strlen(long_file_name));
+      free(long_file_name);
+      long_file_name=NULL;
+    } else
+      unfixtarname(finfo->name + strlen(prefix),
+        hb->dbuf.name, strlen(hb->dbuf.name) + 1);
   }
-    
+
   if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR)
     || (*(finfo->name+strlen(finfo->name)-1) == '\\'))
     {
@@ -1309,7 +1330,9 @@
     do {
       if (!fsize)
 	{
-	  switch (readtarheader((union hblock *) bufferp, &finfo, cur_dir))
+	  int result, skipblks;
+	  result=readtarheader((union hblock *) bufferp, &finfo, cur_dir);
+	  switch (result)
 	    {
 	    case -2:             /* something dodgy but not fatal about this */
 	      DEBUG(0, ("skipping %s...\n", finfo.name));
@@ -1325,8 +1348,18 @@
 		    ("total of %d tar files restored to share\n", ntarf));
 	      free(inbuf); free(outbuf);
 	      return;
-	    default:
+	    case True:
 	      break;
+	    default: /* Long file name */
+	      skipblks=((result/TBLOCK) + 2) * TBLOCK;
+	      if (result > 99) { /* Long file names should always be > 99 */
+            bufferp+=skipblks;
+            continue;
+          } else {
+            DEBUG(0, ("readtarheader returned bogus value\n"));
+	        free(inbuf); free(outbuf);
+	        return;
+          }
 	    }
 
 	  tskip=clipn


More information about the samba mailing list