[BACK]Return to arch.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / make

Diff for /src/usr.bin/make/arch.c between version 1.5 and 1.6

version 1.5, 1996/07/31 00:01:04 version 1.6, 1996/09/02 16:04:07
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*      $NetBSD: arch.c,v 1.14 1996/03/12 18:04:27 christos Exp $       */  /*      $NetBSD: arch.c,v 1.16 1996/08/13 16:42:00 christos Exp $       */
   
 /*  /*
  * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.   * Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
Line 102 
Line 102 
 #include    <sys/param.h>  #include    <sys/param.h>
 #include    <ctype.h>  #include    <ctype.h>
 #include    <ar.h>  #include    <ar.h>
 #if !defined(__svr4__) && !defined(__SVR4) && !defined(__alpha__)  
 #include    <ranlib.h>  
 #endif  
 #include    <utime.h>  #include    <utime.h>
 #include    <stdio.h>  #include    <stdio.h>
 #include    <stdlib.h>  #include    <stdlib.h>
Line 119 
Line 116 
     char          *name;      /* Name of archive */      char          *name;      /* Name of archive */
     Hash_Table    members;    /* All the members of the archive described      Hash_Table    members;    /* All the members of the archive described
                                * by <name, struct ar_hdr *> key/value pairs */                                 * by <name, struct ar_hdr *> key/value pairs */
       char          *fnametab;  /* Extended name table strings */
       size_t        fnamesize;  /* Size of the string table */
 } Arch;  } Arch;
   
 static int ArchFindArchive __P((ClientData, ClientData));  static int ArchFindArchive __P((ClientData, ClientData));
 static void ArchFree __P((ClientData));  static void ArchFree __P((ClientData));
 static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));  static struct ar_hdr *ArchStatMember __P((char *, char *, Boolean));
 static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));  static FILE *ArchFindMember __P((char *, char *, struct ar_hdr *, char *));
   #if defined(__svr4__) || defined(__SVR4)
   #define SVR4ARCHIVES
   static int ArchSVR4Entry __P((Arch *, char *, size_t, FILE *));
   #endif
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------
Line 154 
Line 157 
         free((Address) Hash_GetValue (entry));          free((Address) Hash_GetValue (entry));
   
     free(a->name);      free(a->name);
       if (a->fnametab)
           free(a->fnametab);
     Hash_DeleteTable(&a->members);      Hash_DeleteTable(&a->members);
     free((Address) a);      free((Address) a);
 }  }
Line 543 
Line 548 
     }      }
   
     ar = (Arch *)emalloc (sizeof (Arch));      ar = (Arch *)emalloc (sizeof (Arch));
     ar->name = strdup (archive);      ar->name = estrdup (archive);
       ar->fnametab = NULL;
       ar->fnamesize = 0;
     Hash_InitTable (&ar->members, -1);      Hash_InitTable (&ar->members, -1);
     memName[AR_MAX_NAME_LEN] = '\0';      memName[AR_MAX_NAME_LEN] = '\0';
   
     while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) {      while (fread ((char *)&arh, sizeof (struct ar_hdr), 1, arch) == 1) {
         if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) {          if (strncmp ( arh.ar_fmag, ARFMAG, sizeof (arh.ar_fmag)) != 0) {
                                  /*              /*
                                   * The header is bogus, so the archive is bad               * The header is bogus, so the archive is bad
                                   * and there's no way we can recover...               * and there's no way we can recover...
                                   */               */
                                  fclose (arch);              goto badarch;
                                  Hash_DeleteTable (&ar->members);  
                                  free ((Address)ar);  
                                  return ((struct ar_hdr *) NULL);  
         } else {          } else {
               /*
                * We need to advance the stream's pointer to the start of the
                * next header. Files are padded with newlines to an even-byte
                * boundary, so we need to extract the size of the file from the
                * 'size' field of the header and round it up during the seek.
                */
               arh.ar_size[sizeof(arh.ar_size)-1] = '\0';
               size = (int) strtol(arh.ar_size, NULL, 10);
   
             (void) strncpy (memName, arh.ar_name, sizeof(arh.ar_name));              (void) strncpy (memName, arh.ar_name, sizeof(arh.ar_name));
             for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {              for (cp = &memName[AR_MAX_NAME_LEN]; *cp == ' '; cp--) {
                 continue;                  continue;
             }              }
             cp[1] = '\0';              cp[1] = '\0';
   
 #if defined(__svr4__) || defined(__SVR4)  #ifdef SVR4ARCHIVES
             /* svr4 names are slash terminated */              /*
             if (cp[0] == '/')               * svr4 names are slash terminated. Also svr4 extended AR format.
                 cp[0] = '\0';               */
               if (memName[0] == '/') {
                   /*
                    * svr4 magic mode; handle it
                    */
                   switch (ArchSVR4Entry(ar, memName, size, arch)) {
                   case -1:  /* Invalid data */
                       goto badarch;
                   case 0:   /* List of files entry */
                       continue;
                   default:  /* Got the entry */
                       break;
                   }
               }
               else {
                   if (cp[0] == '/')
                       cp[0] = '\0';
               }
 #endif  #endif
   
 #ifdef AR_EFMT1  #ifdef AR_EFMT1
Line 580 
Line 610 
   
                 unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);                  unsigned int elen = atoi(&memName[sizeof(AR_EFMT1)-1]);
   
                 if (elen > MAXPATHLEN) {                  if (elen > MAXPATHLEN)
                         fclose (arch);                          goto badarch;
                         Hash_DeleteTable (&ar->members);                  if (fread (memName, elen, 1, arch) != 1)
                         free ((Address)ar);                          goto badarch;
                         return ((struct ar_hdr *) NULL);  
                 }  
                 if (fread (memName, elen, 1, arch) != 1) {  
                         fclose (arch);  
                         Hash_DeleteTable (&ar->members);  
                         free ((Address)ar);  
                         return ((struct ar_hdr *) NULL);  
                 }  
                 memName[elen] = '\0';                  memName[elen] = '\0';
                 fseek (arch, -elen, 1);                  fseek (arch, -elen, 1);
                 if (DEBUG(ARCH) || DEBUG(MAKE)) {                  if (DEBUG(ARCH) || DEBUG(MAKE)) {
Line 605 
Line 627 
             memcpy ((Address)Hash_GetValue (he), (Address)&arh,              memcpy ((Address)Hash_GetValue (he), (Address)&arh,
                 sizeof (struct ar_hdr));                  sizeof (struct ar_hdr));
         }          }
         /*  
          * We need to advance the stream's pointer to the start of the  
          * next header. Files are padded with newlines to an even-byte  
          * boundary, so we need to extract the size of the file from the  
          * 'size' field of the header and round it up during the seek.  
          */  
         arh.ar_size[sizeof(arh.ar_size)-1] = '\0';  
         size = (int) strtol(arh.ar_size, NULL, 10);  
         fseek (arch, (size + 1) & ~1, 1);          fseek (arch, (size + 1) & ~1, 1);
     }      }
   
Line 631 
Line 645 
     } else {      } else {
         return ((struct ar_hdr *) NULL);          return ((struct ar_hdr *) NULL);
     }      }
   
   badarch:
       fclose (arch);
       Hash_DeleteTable (&ar->members);
       if (ar->fnametab)
           free(ar->fnametab);
       free ((Address)ar);
       return ((struct ar_hdr *) NULL);
 }  }
   
   #ifdef SVR4ARCHIVES
   /*-
    *-----------------------------------------------------------------------
    * ArchSVR4Entry --
    *      Parse an SVR4 style entry that begins with a slash.
    *      If it is "//", then load the table of filenames
    *      If it is "/<offset>", then try to substitute the long file name
    *      from offset of a table previously read.
    *
    * Results:
    *      -1: Bad data in archive
    *       0: A table was loaded from the file
    *       1: Name was successfully substituted from table
    *       2: Name was not successfully substituted from table
    *
    * Side Effects:
    *      If a table is read, the file pointer is moved to the next archive
    *      member
    *
    *-----------------------------------------------------------------------
    */
   static int
   ArchSVR4Entry(ar, name, size, arch)
           Arch *ar;
           char *name;
           size_t size;
           FILE *arch;
   {
   #define ARLONGNAMES1 "//"
   #define ARLONGNAMES2 "/ARFILENAMES"
       size_t entry;
       char *ptr, *eptr;
   
       if (strncmp(name, ARLONGNAMES1, sizeof(ARLONGNAMES1) - 1) == 0 ||
           strncmp(name, ARLONGNAMES2, sizeof(ARLONGNAMES2) - 1) == 0) {
   
           if (ar->fnametab != NULL) {
               if (DEBUG(ARCH)) {
                   printf("Attempted to redefine an SVR4 name table\n");
               }
               return -1;
           }
   
           /*
            * This is a table of archive names, so we build one for
            * ourselves
            */
           ar->fnametab = emalloc(size);
           ar->fnamesize = size;
   
           if (fread(ar->fnametab, size, 1, arch) != 1) {
               if (DEBUG(ARCH)) {
                   printf("Reading an SVR4 name table failed\n");
               }
               return -1;
           }
           eptr = ar->fnametab + size;
           for (entry = 0, ptr = ar->fnametab; ptr < eptr; ptr++)
               switch (*ptr) {
               case '/':
                   entry++;
                   *ptr = '\0';
                   break;
   
               case '\n':
                   break;
   
               default:
                   break;
               }
           if (DEBUG(ARCH)) {
               printf("Found svr4 archive name table with %d entries\n", entry);
           }
           return 0;
       }
   
       if (name[1] == ' ' || name[1] == '\0')
           return 2;
   
       entry = (size_t) strtol(&name[1], &eptr, 0);
       if ((*eptr != ' ' && *eptr != '\0') || eptr == &name[1]) {
           if (DEBUG(ARCH)) {
               printf("Could not parse SVR4 name %s\n", name);
           }
           return 2;
       }
       if (entry >= ar->fnamesize) {
           if (DEBUG(ARCH)) {
               printf("SVR4 entry offset %s is greater than %d\n",
                      name, ar->fnamesize);
           }
           return 2;
       }
   
       if (DEBUG(ARCH)) {
           printf("Replaced %s with %s\n", name, &ar->fnametab[entry]);
       }
   
       (void) strncpy(name, &ar->fnametab[entry], MAXPATHLEN);
       name[MAXPATHLEN] = '\0';
       return 1;
   }
   #endif
   
   
 /*-  /*-
  *-----------------------------------------------------------------------   *-----------------------------------------------------------------------

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6