From: joost@cadlab.CAdlab.DE (Michael Joosten)
Subject: Re: GNU make-3.62, SVR4 and long filenames
Reply-To: joost@cadlab.cadlab.de
Organization: CADLAB, Paderborn, FRG
Distribution: gnu
Date: Thu, 10 Sep 1992 18:42:58 GMT

In article <JOOST.92Sep9210420@ori.cadlab.de> joost@cadlab.CAdlab.DE (Michael Joosten) writes:

   again. Eventually I discovered that SVR4 has a special extension for archives,
   allowing them to store filenames longer than 15 chars. This is made by a
   special entry '/' (that is "//<8spaces here>") that contains a "filename
   table". The code in arscan.c doesn't know about that and is thus failing for
   archive files with longer names. 

Well, it wasn't really difficult, the most complicated part was to merge the
#ifdef's (the best would be to separate the AIX AIAMAG stuff in a separate
function). Here it a patch, combined with Chip Salzenberg's patches for SCO :

Note: Now you need also "-DUSGr4" in the "defines" variable in the Makefile:
defines =-O -DUSG -DUSGr3 -DUSGr4 -DHAVE_SYS_WAIT -DPOSIX -DENUM_BITFIELD #for SysVR4

Michael

*** arscan.c	Wed Oct 23 02:30:25 1991
--- /sun4_fw2/joost/arscan.c	Thu Sep 10 19:19:43 1992
***************
*** 43,48 ****
--- 43,52 ----
  #define	ANSI_STRING
  #else	/* No standard headers.  */
  
+ #ifdef USGr4
+ #include <ctype.h>
+ #endif
+ 
  #ifdef	USG
  
  #include <string.h>
***************
*** 70,82 ****
  #endif	/* Standard headers.  */
  
  #ifdef	ANSI_STRING
  #define	index(s, c)	strchr((s), (c))
  #define	rindex(s, c)	strrchr((s), (c))
  
  #define bcmp(s1, s2, n)	memcmp ((s1), (s2), (n))
  #define bzero(s, n)	memset ((s), 0, (n))
  #define bcopy(s, d, n)	memcpy ((d), (s), (n))
! #endif	ANSI_STRING
  #undef	ANSI_STRING
  
  
--- 74,90 ----
  #endif	/* Standard headers.  */
  
  #ifdef	ANSI_STRING
+ #ifndef index
  #define	index(s, c)	strchr((s), (c))
+ #endif
+ #ifndef rindex
  #define	rindex(s, c)	strrchr((s), (c))
+ #endif
  
  #define bcmp(s1, s2, n)	memcmp ((s1), (s2), (n))
  #define bzero(s, n)	memset ((s), 0, (n))
  #define bcopy(s, d, n)	memcpy ((d), (s), (n))
! #endif	/* ANSI_STRING */
  #undef	ANSI_STRING
  
  
***************
*** 135,140 ****
--- 143,153 ----
  #ifdef AIAMAG
    FL_HDR fl_header;
  #endif
+ #ifdef USGr4
+   char *name_table = (char*)0;
+   char *real_name = (char*)0;
+   extern char *malloc();
+ #endif
    register int desc = open (archive, O_RDONLY, 0);
    if (desc < 0)
      return -1;
***************
*** 160,169 ****
    }
  #else
    {
! #ifndef M_XENIX
!     int buf;
! #else
      unsigned short int buf;
  #endif
      register int nread = read(desc, &buf, sizeof (buf));
      if (nread != sizeof (buf) || buf != ARMAG)
--- 173,182 ----
    }
  #else
    {
! #if defined(M_XENIX) && !defined(M_UNIX)
      unsigned short int buf;
+ #else
+     int buf;
  #endif
      register int nread = read(desc, &buf, sizeof (buf));
      if (nread != sizeof (buf) || buf != ARMAG)
***************
*** 187,197 ****
      sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
      sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
  #else
! #ifndef	M_XENIX
!     register long int member_offset = sizeof (int);
! #else	/* Xenix.  */
      register long int member_offset = sizeof (unsigned short int);
! #endif	/* Not Xenix.  */
  #endif
  #endif
  
--- 200,210 ----
      sscanf (fl_header.fl_fstmoff, "%12ld", &member_offset);
      sscanf (fl_header.fl_lstmoff, "%12ld", &last_member_offset);
  #else
! #if defined(M_XENIX) && !defined(M_UNIX)
      register long int member_offset = sizeof (unsigned short int);
! #else	/* Not Xenix.  */
!     register long int member_offset = sizeof (int);
! #endif	/* Xenix.  */
  #endif
  #endif
  
***************
*** 215,220 ****
--- 228,236 ----
  	if (lseek (desc, member_offset, 0) < 0)
  	  {
  	    (void) close (desc);
+ #ifdef USGr4
+             if (name_table) free(name_table);
+ #endif
  	    return -2;
  	  }
  
***************
*** 254,260 ****
  		       dateval, uidval, gidval,
  		       eltmode, arg);
  
! #else
  	nread = read (desc, (char *) &member_header, sizeof (struct ar_hdr));
  	if (nread == 0)
  	  /* No data left means end of file; that is OK.  */
--- 270,276 ----
  		       dateval, uidval, gidval,
  		       eltmode, arg);
  
! #else /* ! AIAMAG */
  	nread = read (desc, (char *) &member_header, sizeof (struct ar_hdr));
  	if (nread == 0)
  	  /* No data left means end of file; that is OK.  */
***************
*** 267,272 ****
--- 283,291 ----
  	    )
  	  {
  	    (void) close (desc);
+ #ifdef USGr4
+             if (name_table) free(name_table);
+ #endif
  	    return -2;
  	  }
  
***************
*** 281,313 ****
  #endif
  	}
  
! #ifndef	M_XENIX
! 	sscanf (member_header.ar_mode, "%o", &eltmode);
! 	eltsize = atol (member_header.ar_size);
! #else	/* Xenix.  */
! 	eltmode = (unsigned short int) member_header.ar_mode;
! 	eltsize = member_header.ar_size;
! #endif	/* Not Xenix.  */
! 
  	fnval =
  	  (*function) (desc, name, member_offset,
  		       member_offset + sizeof (member_header), eltsize,
! #ifndef	M_XENIX
! 		       atol (member_header.ar_date),
! 		       atoi (member_header.ar_uid),
! 		       atoi (member_header.ar_gid),
! #else	/* Xenix.  */
! 		       member_header.ar_date,
! 		       member_header.ar_uid,
! 		       member_header.ar_gid,
! #endif	/* Not Xenix.  */
  		       eltmode, arg);
  
  #endif  /* Not AIAMAG */
  
  	if (fnval)
  	  {
  	    (void) close (desc);
  	    return fnval;
  	  }
  
--- 300,381 ----
  #endif
  	}
  
! #if   defined(M_XENIX) && !defined(M_UNIX)
!       eltmode = (unsigned short int) member_header.ar_mode;
!       eltsize = member_header.ar_size;
! #else /* Not Xenix.  */
!       sscanf (member_header.ar_mode, "%o", &eltmode);
!       eltsize = atol (member_header.ar_size);
! #endif        /* Xenix.  */
! 
! #ifdef USGr4
!         if (name[0] == '/' && name[1] == '\0') {
!             /* this name indicates a SVR4 extension, the string table
!              * of long (>15) file names. just read it in an appropriate
!              * space for later use (mj) */
!             register char *p;
!             if (name_table) free(name_table);
!             name_table = malloc((int)eltsize);
!             nread = read(desc, name_table, eltsize);
!             if (nread <= 0 || nread != eltsize) {
!                 free(name_table);
!                 (void) close (desc);
!                 return -2;
!             }
!             fnval = 0;
!             p = name_table+(int)eltsize;
!             while (p > name_table)
!                 if (*--p == '/') *p = '\0';
!             
!         }
!         else {
!             if (name[0] == '/' && isdigit(name[1])) {
!                 /* this is (was) a long file name. instead of the name the
!                  * decimal index of the string in the string table is 
!                  * stored.  (mj) */
!                 long offset = atol(name+1);
!                 if (offset < 0) {
!                     free(name_table);
!                     (void) close (desc);
!                     return -2;
!                 }
!                 real_name = &name_table[offset];
!             }
!             else real_name = name;
! 
!             fnval =
!                 (*function) (desc, real_name, member_offset,
!                              member_offset + sizeof (member_header), eltsize,
!                              atol (member_header.ar_date),
!                              atoi (member_header.ar_uid),
!                              atoi (member_header.ar_gid),
!                              eltmode, arg);
!         }
! #else
!             
  	fnval =
  	  (*function) (desc, name, member_offset,
  		       member_offset + sizeof (member_header), eltsize,
! #if   defined(M_XENIX) && !defined(M_UNIX)
!                      member_header.ar_date,
!                      member_header.ar_uid,
!                      member_header.ar_gid,
! #else /* Not Xenix.  */
!                      atol (member_header.ar_date),
!                      atoi (member_header.ar_uid),
!                      atoi (member_header.ar_gid),
! #endif        /* Xenix.  */
  		       eltmode, arg);
  
+ #endif  /* ! USGr4 */
  #endif  /* Not AIAMAG */
  
  	if (fnval)
  	  {
  	    (void) close (desc);
+ #ifdef USGr4
+             if (name_table) free(name_table);
+ #endif
  	    return fnval;
  	  }
  
***************
*** 330,335 ****
--- 398,406 ----
    }
  
    close (desc);
+ #ifdef USGr4
+   if (name_table) free(name_table);
+ #endif
    return 0;
  }
  
***************
*** 346,352 ****
    if (p != 0)
      name = p + 1;
  
! #ifndef	APOLLO
  
    if (!strncmp (name, mem, AR_NAMELEN))
      return 1;
--- 417,424 ----
    if (p != 0)
      name = p + 1;
  
! #if !defined(APOLLO) && !defined(USGr4)  /* SVR4 & APOLLO have long 
!                                           * member names (mj) */
  
    if (!strncmp (name, mem, AR_NAMELEN))
      return 1;
***************
*** 365,371 ****
      }
    return 0;
  
! #else	/* APOLLO.  */
    return !strcmp (name, mem);
  #endif
  }
--- 437,443 ----
      }
    return 0;
  
! #else	/* APOLLO, USGr4  */
    return !strcmp (name, mem);
  #endif
  }
--
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Michael Joosten   |       Tel.  : (+49) (+) 5251-284 120                 |
| CADLAB            |       Fax   : (+49) (+) 5251-284 140                 |
| Bahnhofstr. 32    |       E-Mail: joost@cadlab.de                        |
| D-4790 Paderborn  |        	    ...!uunet!unido!cadlab!joost           | 
| FRG               | Mass mail to: joost@pbinfo.uni-paderborn.de          |
|--------------------------------------------------------------------------|
| CADLAB is a cooperation between Uni-GH Paderborn & SNI AG                |
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Newsgroups: gnu.utils.bug