oldlocrecarray = (struct oldlocrecent *) alloca (head->namehash_size * sizeof (struct oldlocrecent));
struct oldlocrecent oldlocrecarray[head->namehash_size];
enlarge_archive (struct locarhandle *ah, const struct locarhead *head){  struct stat64 st;  int fd;  struct locarhead newhead;  size_t total;  void *p;  unsigned int cnt, loccnt;  struct namehashent *oldnamehashtab;  struct locrecent *oldlocrectab;  struct locarhandle new_ah;  size_t prefix_len = output_prefix ? strlen (output_prefix) : 0;  char archivefname[prefix_len + sizeof (ARCHIVE_NAME)];  char fname[prefix_len + sizeof (ARCHIVE_NAME) + sizeof (".XXXXXX") - 1];  struct oldlocrecent *oldlocrecarray;  if (output_prefix)    memcpy (archivefname, output_prefix, prefix_len);  strcpy (archivefname + prefix_len, ARCHIVE_NAME);  strcpy (stpcpy (fname, archivefname), ".XXXXXX");  /* Not all of the old file has to be mapped.  Change this now this     we will have to access the whole content.  */  if (fstat64 (ah->fd, &st) != 0      || (ah->addr = mmap64 (NULL, st.st_size, PROT_READ | PROT_WRITE,			     MAP_SHARED, ah->fd, 0)) == MAP_FAILED)    error (EXIT_FAILURE, errno, _("cannot map locale archive file"));  ah->len = st.st_size;  /* Create a temporary file in the correct directory.  */  fd = mkstemp (fname);  if (fd == -1)    error (EXIT_FAILURE, errno, _("cannot create temporary file"));  /* Copy the existing head information.  */  newhead = *head;  /* Create the new archive header.  The sizes of the various tables     should be double from what is currently used.  */  newhead.namehash_size = MAX (next_prime (2 * newhead.namehash_used),			       newhead.namehash_size);  if (verbose)    printf ("name: size: %u, used: %d, new: size: %u\n",	    head->namehash_size, head->namehash_used, newhead.namehash_size);  newhead.string_offset = (newhead.namehash_offset			   + (newhead.namehash_size			      * sizeof (struct namehashent)));  /* Keep the string table size aligned to 4 bytes, so that     all the struct { uint32_t } types following are happy.  */  newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4,			     newhead.string_size);  newhead.locrectab_offset = newhead.string_offset + newhead.string_size;  newhead.locrectab_size = MAX (2 * newhead.locrectab_used,				newhead.locrectab_size);  newhead.sumhash_offset = (newhead.locrectab_offset			    + (newhead.locrectab_size			       * sizeof (struct locrecent)));  newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used),			      newhead.sumhash_size);  total = (newhead.sumhash_offset	   + newhead.sumhash_size * sizeof (struct sumhashent));  /* The new file is empty now.  */  newhead.namehash_used = 0;  newhead.string_used = 0;  newhead.locrectab_used = 0;  newhead.sumhash_used = 0;  /* Write out the header and create room for the other data structures.  */  if (TEMP_FAILURE_RETRY (write (fd, &newhead, sizeof (newhead)))      != sizeof (newhead))    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval, _("cannot initialize archive file"));    }  if (ftruncate64 (fd, total) != 0)    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval, _("cannot resize archive file"));    }  /* Map the header and all the administration data structures.  */  p = mmap64 (NULL, total, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);  if (p == MAP_FAILED)    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval, _("cannot map archive header"));    }  /* Lock the new file.  */  if (lockf64 (fd, F_LOCK, total) != 0)    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval, _("cannot lock new archive"));    }  new_ah.len = total;  new_ah.addr = p;  new_ah.fd = fd;  /* Walk through the hash name hash table to find out what data is     still referenced and transfer it into the new file.  */  oldnamehashtab = (struct namehashent *) ((char *) ah->addr					   + head->namehash_offset);  oldlocrectab = (struct locrecent *) ((char *) ah->addr				       + head->locrectab_offset);  /* Sort the old locrec table in order of data position.  */  oldlocrecarray = (struct oldlocrecent *)		   alloca (head->namehash_size			   * sizeof (struct oldlocrecent));  for (cnt = 0, loccnt = 0; cnt < head->namehash_size; ++cnt)    if (oldnamehashtab[cnt].locrec_offset != 0)      {	oldlocrecarray[loccnt].cnt = cnt;	oldlocrecarray[loccnt++].locrec	  = (struct locrecent *) ((char *) ah->addr				  + oldnamehashtab[cnt].locrec_offset);      }  qsort (oldlocrecarray, loccnt, sizeof (struct oldlocrecent),	 oldlocrecentcmp);  for (cnt = 0; cnt < loccnt; ++cnt)    {      /* Insert this entry in the new hash table.  */      locale_data_t old_data;      unsigned int idx;      struct locrecent *oldlocrec = oldlocrecarray[cnt].locrec;      for (idx = 0; idx < __LC_LAST; ++idx)	if (idx != LC_ALL)	  {	    old_data[idx].size = oldlocrec->record[idx].len;	    old_data[idx].addr	      = ((char *) ah->addr + oldlocrec->record[idx].offset);	    __md5_buffer (old_data[idx].addr, old_data[idx].size,			  old_data[idx].sum);	  }      if (add_locale (&new_ah,	  ((char *) ah->addr	   + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),	  old_data, 0) == 0)	error (EXIT_FAILURE, 0, _("cannot extend locale archive file"));    }  /* Make the file globally readable.  */  if (fchmod (fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1)    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval,	     _("cannot change mode of resized locale archive"));    }  /* Rename the new file.  */  if (rename (fname, archivefname) != 0)    {      int errval = errno;      unlink (fname);      error (EXIT_FAILURE, errval, _("cannot rename new archive"));    }  /* Close the old file.  */  close_archive (ah);  /* Add the information for the new one.  */  *ah = new_ah;}