(int (*) (const void *, const void *)) alias_compare);
(int (*) PARAMS ((const void *, const void *))) alias_compare);
read_alias_file (fname, fname_len)     const char *fname;     int fname_len;{  FILE *fp;  char *full_fname;  size_t added;  static const char aliasfile[] = "/locale.alias";  full_fname = (char *) alloca (fname_len + sizeof aliasfile);  memcpy (full_fname, fname, fname_len);  memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);  fp = fopen (full_fname, "r");  if (fp == NULL)    return 0;  added = 0;  while (!feof (fp))    {      /* It is a reasonable approach to use a fix buffer here because	 a) we are only interested in the first two fields	 b) these fields must be usable as file names and so must not	    be that long       */      char buf[BUFSIZ];      char *alias;      char *value;      char *cp;      if (fgets (buf, BUFSIZ, fp) == NULL)	/* EOF reached.  */	break;      cp = buf;      /* Ignore leading white space.  */      while (isspace (cp[0]))	++cp;      /* A leading '#' signals a comment line.  */      if (cp[0] != '\0' && cp[0] != '#')	{	  alias = cp++;	  while (cp[0] != '\0' && !isspace (cp[0]))	    ++cp;	  /* Terminate alias name.  */	  if (cp[0] != '\0')	    *cp++ = '\0';	  /* Now look for the beginning of the value.  */	  while (isspace (cp[0]))	    ++cp;	  if (cp[0] != '\0')	    {	      char *tp;	      size_t len;	      value = cp++;	      while (cp[0] != '\0' && !isspace (cp[0]))		++cp;	      /* Terminate value.  */	      if (cp[0] == '\n')		{		  /* This has to be done to make the following test		     for the end of line possible.  We are looking for		     the terminating '\n' which do not overwrite here.  */		  *cp++ = '\0';		  *cp = '\n';		}	      else if (cp[0] != '\0')		*cp++ = '\0';	      if (nmap >= maxmap)		extend_alias_table ();	      /* We cannot depend on strdup available in the libc.  Sigh!  */	      len = strlen (alias) + 1;	      tp = (char *) malloc (len);	      if (tp == NULL)		return added;	      memcpy (tp, alias, len);	      map[nmap].alias = tp;	      len = strlen (value) + 1;	      tp = (char *) malloc (len);	      if (tp == NULL)		return added;	      memcpy (tp, value, len);	      map[nmap].value = tp;	      ++nmap;	      ++added;	    }	}      /* Possibily not the whole line fitted into the buffer.  Ignore	 the rest of the line.  */      while (strchr (cp, '\n') == NULL)	{	  cp = buf;	  if (fgets (buf, BUFSIZ, fp) == NULL)	    /* Make sure the inner loop will be left.  The outer loop	       will exit at the `feof' test.  */	    *cp = '\n';	}    }  /* Should we test for ferror()?  I think we have to silently ignore     errors.  --drepper  */  fclose (fp);  if (added > 0)    qsort (map, nmap, sizeof (struct alias_map),	   (int (*) (const void *, const void *)) alias_compare);  return added;}