Ejemplo n.º 1
0
int main(int argc, char const *argv[])
{
    char line[MAX_BUFFER];
    //char* tokens[MAX_TOKENS];

    if (fgets(line, MAX_BUFFER - 1, stdin) == NULL)
    {
        printf("Error while reading line from stdin.\n");
        return EXIT_FAILURE;
    }

    char *str1, *str2, *token, *subtoken;
    char *saveptr1, *saveptr2;
    int j;

    for (j = 1, str1 = line; ; j++, str1 = NULL)
    {
        token = __strtok_r(str1, "|;", &saveptr1);
        if (token == NULL)
            break;
        printf("%d: %s\n", j, token);

        for (str2 = token; ; str2 = NULL)
        {
            subtoken = __strtok_r(str2, " ", &saveptr2);
            if (subtoken == NULL)
                break;
            printf(" --> %s\n", subtoken);
        }
    }

    return EXIT_SUCCESS;
}
Ejemplo n.º 2
0
static enum nss_status
search (const char *netname, char *result, int *errnop, int secret)
{
  FILE *stream = fopen (DATAFILE, "rce");
  if (stream == NULL)
    return errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;

  for (;;)
    {
      char buffer[HEXKEYBYTES * 2 + KEYCHECKSUMSIZE + MAXNETNAMELEN + 17];
      char *p;
      char *save_ptr;

      buffer[sizeof (buffer) - 1] = '\xff';
      p = fgets_unlocked (buffer, sizeof (buffer), stream);
      if (p == NULL)
	{
	  /* End of file or read error.  */
	  *errnop = errno;
	  fclose (stream);
	  return NSS_STATUS_NOTFOUND;
	}
      else if (buffer[sizeof (buffer) - 1] != '\xff')
	{
	  /* Invalid line in file?  Skip remainder of line.  */
	  if (buffer[sizeof (buffer) - 2] != '\0')
	    while (getc_unlocked (stream) != '\n')
	      continue;
	  continue;
	}

      /* Parse line.  */
      p = __strtok_r (buffer, "# \t:\n", &save_ptr);
      if (p == NULL) /* Skip empty and comment lines.  */
	continue;
      if (strcmp (p, netname) != 0)
	continue;

      /* A hit!  Find the field we want and return.  */
      p = __strtok_r (NULL, ":\n", &save_ptr);
      if (p == NULL)  /* malformed line? */
	continue;
      if (secret)
	p = __strtok_r (NULL, ":\n", &save_ptr);
      if (p == NULL)  /* malformed line? */
	continue;
      fclose (stream);
      strcpy (result, p);
      return NSS_STATUS_SUCCESS;
    }
}
Ejemplo n.º 3
0
static TACommandVerdict __strtok_r_cmd(TAThread thread,TAInputStream stream)
{
    char* stringp, *buff;
    char *delim, *res;

    // Prepare       
    stringp=(char*)readPointer(&stream);
    delim=(char*)readPointer(&stream);
    buff=(char*)readPointer(&stream);    

    ta_debug_printf("strtok_r...\n");
    ta_debug_printf("stringp==%s\n", stringp);  
    ta_debug_printf("delim==%s\n", delim);

    // Execute
    START_TARGET_OPERATION(thread);
    res = __strtok_r(stringp, delim, &buff);
    END_TARGET_OPERATION(thread);

    ta_debug_printf("After...\n");
    ta_debug_printf("stringp==%s\n", stringp);
    ta_debug_printf("delim==%s\n", delim);
    ta_debug_printf("buff==%s\n", buff);

    // Response    
    writePointer(thread, res);
    writePointer(thread, buff);

    sendResponse(thread);

    return taDefaultVerdict;
}
Ejemplo n.º 4
0
char *
strtok(char *s, const char *delim)
{
	static char *last;

	return (__strtok_r(s, delim, &last));
}
Ejemplo n.º 5
0
void process (Graph graph, char** linebuf) {
   for (int i = 1;;) {
      char *row, *col;
      row = __strtok_r (linebuf[i++], " ", &col);
      if (atoi (row) == 0 && atoi (col) == 0) break;
      addArc (graph, atoi (row), atoi (col));
   }
}
Ejemplo n.º 6
0
char *strtok_r(char *s,const char *delim,char **lasts)
{
	return __strtok_r (s, delim, lasts, 1);
}
Ejemplo n.º 7
0
NTSTATUS
RegistryQuerySystemStartOption(
    IN  PCHAR                       Prefix,
    OUT PANSI_STRING                *Value
    )
{
    UNICODE_STRING                  Unicode;
    HANDLE                          Key;
    PANSI_STRING                    Ansi;
    ULONG                           Length;
    PCHAR                           Option;
    PCHAR                           Context;
    NTSTATUS                        status;

    RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
    
    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
    if (!NT_SUCCESS(status))
        goto fail1;

    status = RegistryQuerySzValue(Key, "SystemStartOptions", &Ansi);
    if (!NT_SUCCESS(status))
        goto fail2;

    // SystemStartOptions is a space separated list of options.
    // Scan it looking for the one we want.
    Length = (ULONG)strlen(Prefix);

    Option = __strtok_r(Ansi[0].Buffer, " ", &Context);
    if (strncmp(Prefix, Option, Length) == 0)
        goto found;

    while ((Option = __strtok_r(NULL, " ", &Context)) != NULL)
        if (strncmp(Prefix, Option, Length) == 0)
            goto found;

    status = STATUS_OBJECT_NAME_NOT_FOUND;
    goto fail3;

found:
    *Value = __RegistryAllocate(sizeof (ANSI_STRING) * 2);

    status = STATUS_NO_MEMORY;
    if (*Value == NULL)
        goto fail4;

    Length = (ULONG)strlen(Option);
    (*Value)[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
    (*Value)[0].Buffer = __RegistryAllocate((*Value)[0].MaximumLength);

    status = STATUS_NO_MEMORY;
    if ((*Value)[0].Buffer == NULL)
        goto fail5;

    RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR));

    (*Value)[0].Length = (USHORT)Length * sizeof (CHAR);

    RegistryFreeSzValue(Ansi);

    ZwClose(Key);

    return STATUS_SUCCESS;

fail5:
    __RegistryFree(*Value);

fail4:
fail3:
    RegistryFreeSzValue(Ansi);

fail2:
    ZwClose(Key);

fail1:
    return status;
}
Ejemplo n.º 8
0
char *strsep(char **source_ptr,const char *delim)
{
  return __strtok_r(*source_ptr, delim, source_ptr, 0);
}
Ejemplo n.º 9
0
/* If we run out of memory, we don't give already allocated memory
   free. The overhead for bringing getnames back in a safe state to
   free it is to big. */
nis_name *
nis_getnames (const_nis_name name)
{
  const char *local_domain = nis_local_directory ();
  size_t local_domain_len = strlen (local_domain);
  size_t name_len = strlen (name);
  char *path;
  int pos = 0;
  char *saveptr = NULL;
  int have_point;
  const char *cp;
  const char *cp2;

  int count = 2;
  nis_name *getnames = malloc ((count + 1) * sizeof (char *));
  if (__glibc_unlikely (getnames == NULL))
      return NULL;

  /* Do we have a fully qualified NIS+ name ? If yes, give it back */
  if (name[name_len - 1] == '.')
    {
      if ((getnames[0] = strdup (name)) == NULL)
	{
	free_null:
	  while (pos-- > 0)
	    free (getnames[pos]);
	  free (getnames);
	  return NULL;
	}

      getnames[1] = NULL;

      return getnames;
    }

  /* If the passed NAME is shared a suffix (the latter of course with
     a final dot) with each other we pass back NAME with a final
     dot.  */
  if (local_domain_len > 2)
    {
      have_point = 0;
      cp = &local_domain[local_domain_len - 2];
      cp2 = &name[name_len - 1];

      while (*cp == *cp2)
	{
	  if (*cp == '.')
	    have_point = 1;
	  --cp;
	  --cp2;
	  if (cp < local_domain)
	    {
	      have_point = cp2 < name || *cp2 == '.';
	      break;
	    }
	  if (cp2 < name)
	    {
	      have_point = *cp == '.';
	      break;
	    }
	}

      if (have_point)
	{
	  getnames[0] = malloc (name_len + 2);
	  if (getnames[0] == NULL)
	    goto free_null;

	  strcpy (stpcpy (getnames[0], name), ".");
	  ++pos;
	}
    }

  /* Get the search path, where we have to search "name" */
  path = getenv ("NIS_PATH");
  if (path == NULL)
    path = strdupa ("$");
  else
    path = strdupa (path);

  have_point = strchr (name, '.') != NULL;

  cp = __strtok_r (path, ":", &saveptr);
  while (cp)
    {
      if (strcmp (cp, "$") == 0)
	{
	  const char *cptr = local_domain;
	  char *tmp;

	  while (*cptr != '\0' && count_dots (cptr) >= 2)
	    {
	      if (pos >= count)
		{
		  count += 5;
		  nis_name *newp = realloc (getnames,
					    (count + 1) * sizeof (char *));
		  if (__glibc_unlikely (newp == NULL))
		    goto free_null;
		  getnames = newp;
		}
	      tmp = malloc (strlen (cptr) + local_domain_len + name_len + 2);
	      if (__glibc_unlikely (tmp == NULL))
		goto free_null;

	      getnames[pos] = tmp;
	      tmp = stpcpy (tmp, name);
	      *tmp++ = '.';
	      if (cptr[1] != '\0')
		stpcpy (tmp, cptr);
	      else
		++cptr;

	      ++pos;

	      while (*cptr != '.' && *cptr != '\0')
		++cptr;
	      if (cptr[0] != '\0' && cptr[1] != '\0')
		/* If we have only ".", don't remove the "." */
		++cptr;
	    }
	}
      else
	{
	  char *tmp;
	  size_t cplen = strlen (cp);

	  if (cp[cplen - 1] == '$')
	    {
	      char *p;

	      tmp = malloc (cplen + local_domain_len + name_len + 2);
	      if (__glibc_unlikely (tmp == NULL))
		goto free_null;

	      p = __stpcpy (tmp, name);
	      *p++ = '.';
	      p = __mempcpy (p, cp, cplen);
	      --p;
	      if (p[-1] != '.')
		*p++ = '.';
	      __stpcpy (p, local_domain);
	    }
	  else
	    {
	      char *p;

	      tmp = malloc (cplen + name_len + 3);
	      if (__glibc_unlikely (tmp == NULL))
		goto free_null;

	      p = __mempcpy (tmp, name, name_len);
	      *p++ = '.';
	      p = __mempcpy (p, cp, cplen);
	      if (p[-1] != '.')
		*p++ = '.';
	      *p = '\0';
	    }

	  if (pos >= count)
	    {
	      count += 5;
	      nis_name *newp = realloc (getnames,
					(count + 1) * sizeof (char *));
	      if (__glibc_unlikely (newp == NULL))
		goto free_null;
	      getnames = newp;
	    }
	  getnames[pos] = tmp;
	  ++pos;
	}
      cp = __strtok_r (NULL, ":", &saveptr);
    }

  if (pos == 0
      && __asprintf (&getnames[pos++], "%s%s%s%s",
		     name, name[name_len - 1] == '.' ? "" : ".",
		     local_domain,
		     local_domain[local_domain_len - 1] == '.' ? "" : ".") < 0)
    goto free_null;

  getnames[pos] = NULL;

  return getnames;
}
Ejemplo n.º 10
0
int
internal_function
__gconv_open (const char *toset, const char *fromset, __gconv_t *handle,
	      int flags)
{
  struct __gconv_step *steps;
  size_t nsteps;
  __gconv_t result = NULL;
  size_t cnt = 0;
  int res;
  int conv_flags = 0;
  const char *errhand;
  const char *ignore;
  struct trans_struct *trans = NULL;

  /* Find out whether any error handling method is specified.  */
  errhand = strchr (toset, '/');
  if (errhand != NULL)
    errhand = strchr (errhand + 1, '/');
  if (__builtin_expect (errhand != NULL, 1))
    {
      if (*++errhand == '\0')
	errhand = NULL;
      else
	{
	  /* Make copy without the error handling description.  */
	  char *newtoset = (char *) alloca (errhand - toset + 1);
	  char *tok;
	  char *ptr;

	  newtoset[errhand - toset] = '\0';
	  toset = memcpy (newtoset, toset, errhand - toset);

	  /* Find the appropriate transliteration handlers.  */
	  tok = strdupa (errhand);

	  tok = __strtok_r (tok, ",", &ptr);
	  while (tok != NULL)
	    {
	      if (__strcasecmp_l (tok, "TRANSLIT", &_nl_C_locobj) == 0)
		{
		  /* It's the builtin transliteration handling.  We only
		     support it for working on the internal encoding.  */
		  static const char *internal_trans_names[1] = { "INTERNAL" };
		  struct trans_struct *lastp = NULL;
		  struct trans_struct *runp;

		  for (runp = trans; runp != NULL; runp = runp->next)
		    if (runp->trans_fct == __gconv_transliterate)
		      break;
		    else
		      lastp = runp;

		  if (runp == NULL)
		    {
		      struct trans_struct *newp;

		      newp = (struct trans_struct *) alloca (sizeof (*newp));
		      memset (newp, '\0', sizeof (*newp));

		      /* We leave the `name' field zero to signal that
			 this is an internal transliteration step.  */
		      newp->csnames = internal_trans_names;
		      newp->ncsnames = 1;
		      newp->trans_fct = __gconv_transliterate;

		      if (lastp == NULL)
			trans = newp;
		      else
			lastp->next = newp;
		    }
		}
	      else if (__strcasecmp_l (tok, "IGNORE", &_nl_C_locobj) == 0)
		/* Set the flag to ignore all errors.  */
		conv_flags |= __GCONV_IGNORE_ERRORS;
	      else
		{
		  /* `tok' is possibly a module name.  We'll see later
		     whether we can find it.  But first see that we do
		     not already a module of this name.  */
		  struct trans_struct *lastp = NULL;
		  struct trans_struct *runp;

		  for (runp = trans; runp != NULL; runp = runp->next)
		    if (runp->name != NULL
			&& __strcasecmp_l (tok, runp->name,
					   &_nl_C_locobj) == 0)
		      break;
		    else
		      lastp = runp;

		  if (runp == NULL)
		    {
		      struct trans_struct *newp;

		      newp = (struct trans_struct *) alloca (sizeof (*newp));
		      memset (newp, '\0', sizeof (*newp));
		      newp->name = tok;

		      if (lastp == NULL)
			trans = newp;
		      else
			lastp->next = newp;
		    }
		}

	      tok = __strtok_r (NULL, ",", &ptr);
	    }
	}
    }

  /* For the source character set we ignore the error handler specification.
     XXX Is this really always the best?  */
  ignore = strchr (fromset, '/');
  if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL
      && *++ignore != '\0')
    {
      char *newfromset = (char *) alloca (ignore - fromset + 1);

      newfromset[ignore - fromset] = '\0';
      fromset = memcpy (newfromset, fromset, ignore - fromset);
    }

  /* If the string is empty define this to mean the charset of the
     currently selected locale.  */
  if (strcmp (toset, "//") == 0)
    {
      const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
      size_t len = strlen (codeset);
      char *dest;
      toset = dest = (char *) alloca (len + 3);
      memcpy (__mempcpy (dest, codeset, len), "//", 3);
    }
  if (strcmp (fromset, "//") == 0)
    {
      const char *codeset = _NL_CURRENT (LC_CTYPE, CODESET);
      size_t len = strlen (codeset);
      char *dest;
      fromset = dest = (char *) alloca (len + 3);
      memcpy (__mempcpy (dest, codeset, len), "//", 3);
    }

  res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags);
  if (res == __GCONV_OK)
    {
      /* Find the modules.  */
      struct trans_struct *lastp = NULL;
      struct trans_struct *runp;

      for (runp = trans; runp != NULL; runp = runp->next)
	{
	  if (runp->name == NULL
	      || __builtin_expect (__gconv_translit_find (runp), 0) == 0)
	    lastp = runp;
	  else
	    {
	      /* This means we haven't found the module.  Remove it.  */
	      if (lastp == NULL)
		trans  = runp->next;
	      else
		lastp->next  = runp->next;
	    }
	}

      /* Allocate room for handle.  */
      result = (__gconv_t) malloc (sizeof (struct __gconv_info)
				   + (nsteps
				      * sizeof (struct __gconv_step_data)));
      if (result == NULL)
	res = __GCONV_NOMEM;
      else
	{
	  size_t n;

	  /* Remember the list of steps.  */
	  result->__steps = steps;
	  result->__nsteps = nsteps;

	  /* Clear the array for the step data.  */
	  memset (result->__data, '\0',
		  nsteps * sizeof (struct __gconv_step_data));

	  /* Call all initialization functions for the transformation
	     step implementations.  */
	  for (cnt = 0; cnt < nsteps; ++cnt)
	    {
	      size_t size;

	      /* Would have to be done if we would not clear the whole
                 array above.  */
#if 0
	      /* Reset the counter.  */
	      result->__data[cnt].__invocation_counter = 0;

	      /* It's a regular use.  */
	      result->__data[cnt].__internal_use = 0;
#endif

	      /* We use the `mbstate_t' member in DATA.  */
	      result->__data[cnt].__statep = &result->__data[cnt].__state;

	      /* Now see whether we can use any of the transliteration
		 modules for this step.  */
	      for (runp = trans; runp != NULL; runp = runp->next)
		for (n = 0; n < runp->ncsnames; ++n)
		  if (__strcasecmp_l (steps[cnt].__from_name,
				      runp->csnames[n], &_nl_C_locobj) == 0)
		    {
		      void *data = NULL;

		      /* Match!  Now try the initializer.  */
		      if (runp->trans_init_fct == NULL
			  || (runp->trans_init_fct (&data,
						    steps[cnt].__to_name)
			      == __GCONV_OK))
			{
			  /* Append at the end of the list.  */
			  struct __gconv_trans_data *newp;
			  struct __gconv_trans_data **lastp;

			  newp = (struct __gconv_trans_data *)
			    malloc (sizeof (struct __gconv_trans_data));
			  if (newp == NULL)
			    {
			      res = __GCONV_NOMEM;
			      goto bail;
			    }

			  newp->__trans_fct = runp->trans_fct;
			  newp->__trans_context_fct = runp->trans_context_fct;
			  newp->__trans_end_fct = runp->trans_end_fct;
			  newp->__data = data;
			  newp->__next = NULL;

			  lastp = &result->__data[cnt].__trans;
			  while (*lastp != NULL)
			    lastp = &(*lastp)->__next;

			  *lastp = newp;
			}
		      break;
		    }

	      /* If this is the last step we must not allocate an
		 output buffer.  */
	      if (cnt < nsteps - 1)
		{
		  result->__data[cnt].__flags = conv_flags;

		  /* Allocate the buffer.  */
		  size = (GCONV_NCHAR_GOAL * steps[cnt].__max_needed_to);

		  result->__data[cnt].__outbuf = (char *) malloc (size);
		  if (result->__data[cnt].__outbuf == NULL)
		    {
		      res = __GCONV_NOMEM;
		      goto bail;
		    }

		  result->__data[cnt].__outbufend =
		    result->__data[cnt].__outbuf + size;
		}
	      else
		{
		  /* Handle the last entry.  */
		  result->__data[cnt].__flags = conv_flags | __GCONV_IS_LAST;

		  break;
		}
	    }
	}

      if (res != __GCONV_OK)
	{
	  /* Something went wrong.  Free all the resources.  */
	  int serrno;
	bail:
	  serrno = errno;

	  if (result != NULL)
	    {
	      while (cnt-- > 0)
		{
		  struct __gconv_trans_data *transp;

		  transp = result->__data[cnt].__trans;
		  while (transp != NULL)
		    {
		      struct __gconv_trans_data *curp = transp;
		      transp = transp->__next;

		      if (__builtin_expect (curp->__trans_end_fct != NULL, 0))
			curp->__trans_end_fct (curp->__data);

		      free (curp);
		    }

		  free (result->__data[cnt].__outbuf);
		}

	      free (result);
	      result = NULL;
	    }

	  __gconv_close_transform (steps, nsteps);

	  __set_errno (serrno);
	}
    }

  *handle = result;
  return res;
}
Ejemplo n.º 11
0
/* Determine the directories we are looking for data in.  */
void
internal_function
__gconv_get_path (void)
{
  struct path_elem *result;
  __libc_lock_define_initialized (static, lock);

  __libc_lock_lock (lock);

  /* Make sure there wasn't a second thread doing it already.  */
  result = (struct path_elem *) __gconv_path_elem;
  if (result == NULL)
    {
      /* Determine the complete path first.  */
      char *gconv_path;
      size_t gconv_path_len;
      char *elem;
      char *oldp;
      char *cp;
      int nelems;
      char *cwd;
      size_t cwdlen;

      if (__gconv_path_envvar == NULL)
	{
	  /* No user-defined path.  Make a modifiable copy of the
	     default path.  */
	  gconv_path = strdupa (default_gconv_path);
	  gconv_path_len = sizeof (default_gconv_path);
	  cwd = NULL;
	  cwdlen = 0;
	}
      else
	{
	  /* Append the default path to the user-defined path.  */
	  size_t user_len = strlen (__gconv_path_envvar);

	  gconv_path_len = user_len + 1 + sizeof (default_gconv_path);
	  gconv_path = alloca (gconv_path_len);
	  __mempcpy (__mempcpy (__mempcpy (gconv_path, __gconv_path_envvar,
					   user_len),
				":", 1),
		     default_gconv_path, sizeof (default_gconv_path));
	  cwd = __getcwd (NULL, 0);
	  cwdlen = strlen (cwd);
	}
      assert (default_gconv_path[0] == '/');

      /* In a first pass we calculate the number of elements.  */
      oldp = NULL;
      cp = strchr (gconv_path, ':');
      nelems = 1;
      while (cp != NULL)
	{
	  if (cp != oldp + 1)
	    ++nelems;
	  oldp = cp;
	  cp =  strchr (cp + 1, ':');
	}

      /* Allocate the memory for the result.  */
      result = (struct path_elem *) malloc ((nelems + 1)
					    * sizeof (struct path_elem)
					    + gconv_path_len + nelems
					    + (nelems - 1) * (cwdlen + 1));
      if (result != NULL)
	{
	  char *strspace = (char *) &result[nelems + 1];
	  int n = 0;

	  /* Separate the individual parts.  */
	  __gconv_max_path_elem_len = 0;
	  elem = __strtok_r (gconv_path, ":", &gconv_path);
	  assert (elem != NULL);
	  do
	    {
	      result[n].name = strspace;
	      if (elem[0] != '/')
		{
		  assert (cwd != NULL);
		  strspace = __mempcpy (strspace, cwd, cwdlen);
		  *strspace++ = '/';
		}
	      strspace = __stpcpy (strspace, elem);
	      if (strspace[-1] != '/')
		*strspace++ = '/';

	      result[n].len = strspace - result[n].name;
	      if (result[n].len > __gconv_max_path_elem_len)
		__gconv_max_path_elem_len = result[n].len;

	      *strspace++ = '\0';
	      ++n;
	    }
	  while ((elem = __strtok_r (NULL, ":", &gconv_path)) != NULL);

	  result[n].name = NULL;
	  result[n].len = 0;
	}

      __gconv_path_elem = result ?: (struct path_elem *) &empty_path_elem;

      if (cwd != NULL)
	free (cwd);
    }
Ejemplo n.º 12
0
/* If we run out of memory, we don't give already allocated memory
   free. The overhead for bringing getnames back in a safe state to
   free it is to big. */
nis_name *
nis_getnames (const_nis_name name)
{
  nis_name *getnames = NULL;
  char local_domain[NIS_MAXNAMELEN + 1];
  char *path;
  char *cp;
  int count;
  int pos = 0;
  int have_point;
  char *saveptr;

  strncpy (local_domain, nis_local_directory (), NIS_MAXNAMELEN);
  local_domain[NIS_MAXNAMELEN] = '\0';

  count = 1;
  getnames = malloc ((count + 1) * sizeof (char *));
  if (__builtin_expect (getnames == NULL, 0))
      return NULL;

  /* Do we have a fully qualified NIS+ name ? If yes, give it back */
  if (name[strlen (name) - 1] == '.')
    {
      if ((getnames[0] = strdup (name)) == NULL)
	{
	free_null:
	  while (pos-- > 0)
	    free (getnames[pos]);
	  free (getnames);
	  return NULL;
	}

      getnames[1] = NULL;

      return getnames;
    }

  /* Get the search path, where we have to search "name" */
  path = getenv ("NIS_PATH");
  if (path == NULL)
    path = strdupa ("$");
  else
    path = strdupa (path);

  have_point = (strchr (name, '.') != NULL);

  cp = __strtok_r (path, ":", &saveptr);
  while (cp)
    {
      if (strcmp (cp, "$") == 0)
	{
	  char *cptr = local_domain;
	  char *tmp;

	  while ((have_point && *cptr != '\0') || (count_dots (cptr) >= 2))
	    {
	      if (pos >= count)
		{
		  count += 5;
		  nis_name *newp = realloc (getnames,
					    (count + 1) * sizeof (char *));
		  if (__builtin_expect (newp == NULL, 0))
		    goto free_null;
		  getnames = newp;
		}
	      tmp = malloc (strlen (cptr) + strlen (local_domain) +
			    strlen (name) + 2);
	      if (__builtin_expect (tmp == NULL, 0))
		goto free_null;

	      getnames[pos] = tmp;
	      tmp = stpcpy (tmp, name);
	      *tmp++ = '.';
	      if (cptr[1] != '\0')
		stpcpy (tmp, cptr);
	      else
		++cptr;

	      ++pos;

	      while (*cptr != '.' && *cptr != '\0')
		++cptr;
	      if (cptr[0] != '\0' && cptr[1] != '\0')
		/* If we have only ".", don't remove the "." */
		++cptr;
	    }
	}
      else
	{
	  char *tmp;
	  size_t cplen = strlen (cp);

	  if (cp[cplen - 1] == '$')
	    {
	      char *p;

	      tmp = malloc (cplen + strlen (local_domain) + strlen (name) + 2);
	      if (__builtin_expect (tmp == NULL, 0))
		goto free_null;

	      p = __stpcpy (tmp, name);
	      *p++ = '.';
	      p = __mempcpy (p, cp, cplen);
	      --p;
	      if (p[-1] != '.')
		*p++ = '.';
	      __stpcpy (p, local_domain);
	    }
	  else
	    {
	      char *p;

	      tmp = malloc (cplen + strlen (name) + 2);
	      if (__builtin_expect (tmp == NULL, 0))
		goto free_null;

	      p = __stpcpy (tmp, name);
	      *p++ = '.';
	      memcpy (p, cp, cplen + 1);
	    }

	  if (pos >= count)
	    {
	      count += 5;
	      nis_name *newp = realloc (getnames,
					(count + 1) * sizeof (char *));
	      if (__builtin_expect (newp == NULL, 0))
		goto free_null;
	      getnames = newp;
	    }
	  getnames[pos] = tmp;
	  ++pos;
	}
      cp = __strtok_r (NULL, ":", &saveptr);
    }

  getnames[pos] = NULL;

  return getnames;
}