* autoload.cc: Remove all symbols from advapi32.dll, kernel32.dll and ntdll.dll available on all platforms since NT4. Throughout remove all usage of wincap.is_winnt. * dcrt0.cc (dll_crt0_0): Remove call to mmap_init. * fhandler.h (class fhandler_base): Remove has_changed flag. (fhandler_disk_file::touch_ctime): Remove declaration. (fhandler_disk_file::readdir_9x): Ditto. (fhandler_disk_file::touch_ctime): Remove. (fhandler_disk_file::readdir_9x): Remove. (fhandler_disk_file::closedir): Call NtClose instead of CloseHandle. * mmap.cc: Throughout call CreateMapping and MapView directly. (VirtualProt9x): Remove. (VirtualProtNT): Remove. (VirtualProtEx9x): Remove. (VirtualProtExNT): Remove. (VirtualProtect): Remove define. (VirtualProtectEx): Remove define. (CreateMapping9x): Remove. (CreateMappingNT): Rename to CreateMapping. (MapView9x): Remove. (MapViewNT): Rename to MapView. (struct mmap_func_t): Remove definition. (mmap_funcs_9x): Remove. (mmap_funcs_nt): Remove. (mmap_func): Remove. (mmap_init): Remove. * net.cc (getdomainname): Drop comment. Use NT4 registry key only. (get_95_ifconf): Remove. * pinfo.cc (winpids::enumNT): Rename to winpids::enum_processes. (winpids::enum9x): Remove. (winpids::set): Just call enum_processes directly. (winpids::enum_init): Ditto. * pinfo.h (class winpids): Drop enum_processes pointer. Rename enumNT to enum_processes. Drop enum9x declaration. Drop initialization of enum_processes throughout. * registry.cc (get_registry_hive_path): Just create NT key. (load_registry_hive): Only load NT specific file. * syscalls.cc (unlink_9x): Remove. (unlink): Just call unlink_nt. * wincap.cc: Remove is_winnt flag throughout. * wincap.h: Ditto. * winsup.h: Remove mmap_init declaration.
		
			
				
	
	
		
			416 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			416 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* netdb.cc: network database related routines.
 | 
						|
 | 
						|
   Copyright 2002, 2003, 2007 Red Hat, Inc.
 | 
						|
 | 
						|
This file is part of Cygwin.
 | 
						|
 | 
						|
This software is a copyrighted work licensed under the terms of the
 | 
						|
Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | 
						|
details. */
 | 
						|
 | 
						|
#include "winsup.h"
 | 
						|
#include <windows.h>
 | 
						|
#include <sys/cygwin.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <netdb.h>
 | 
						|
 | 
						|
/* Locate and open a system network database file.  relative_path
 | 
						|
 should be one of the following values:
 | 
						|
 "protocol"
 | 
						|
 "services"
 | 
						|
 "networks"
 | 
						|
 "hosts"
 | 
						|
 | 
						|
 This routine will try to locate these files based on system type.
 | 
						|
 Currently the only distinction made is between NT and non-NT systems.
 | 
						|
 | 
						|
 It is the callers responsibility to close the file.  */
 | 
						|
static FILE *
 | 
						|
open_system_file (const char *relative_path)
 | 
						|
{
 | 
						|
  char win32_name[CYG_MAX_PATH];
 | 
						|
  char posix_name[CYG_MAX_PATH];
 | 
						|
 | 
						|
  if (!GetSystemDirectory (win32_name, CYG_MAX_PATH))
 | 
						|
    return NULL;
 | 
						|
  strcat (win32_name, "\\drivers\\etc\\");
 | 
						|
  strcat (win32_name, relative_path);
 | 
						|
  cygwin_conv_to_full_posix_path (win32_name, posix_name);
 | 
						|
  debug_printf ("netdb file to open %s", win32_name);
 | 
						|
  FILE *result = fopen (posix_name, "rt");
 | 
						|
  debug_printf ("handle to netdb file %p", result);
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
inline static FILE *
 | 
						|
open_protocol_file ()
 | 
						|
{
 | 
						|
  return open_system_file ("protocol");
 | 
						|
}
 | 
						|
 | 
						|
/* Wrapper for open_system_file(), fixing the constant name
 | 
						|
"services".  Returns the open file. */
 | 
						|
inline static FILE *
 | 
						|
open_services_file ()
 | 
						|
{
 | 
						|
  return open_system_file ("services");
 | 
						|
}
 | 
						|
 | 
						|
/* Read an entire line up till the next \n character.  Memory for the
 | 
						|
line is dynamically allocated, and the caller must call free() to
 | 
						|
deallocate it.  When the end of file is reached, NULL is returned.  */
 | 
						|
static char *
 | 
						|
get_entire_line (FILE *fd)
 | 
						|
{
 | 
						|
  static const int BUFF_SIZE = 1024;
 | 
						|
  struct line_fragment
 | 
						|
  {
 | 
						|
    char buffer[BUFF_SIZE];
 | 
						|
    line_fragment *next;
 | 
						|
  };
 | 
						|
 | 
						|
  line_fragment *fragment_list_head = NULL;
 | 
						|
  line_fragment *fragment = NULL;
 | 
						|
  int fragment_count = 0;
 | 
						|
  char *result;
 | 
						|
 | 
						|
  do
 | 
						|
    {
 | 
						|
      line_fragment *new_fragment = (line_fragment *) malloc (sizeof (line_fragment));
 | 
						|
      paranoid_printf ("line fragment allocated %p", new_fragment);
 | 
						|
      if (!fragment_list_head)
 | 
						|
	fragment_list_head = new_fragment;
 | 
						|
      if (fragment)
 | 
						|
	fragment->next = new_fragment;
 | 
						|
      fragment = new_fragment;
 | 
						|
      fragment->next = NULL;
 | 
						|
      *fragment->buffer = '\0';
 | 
						|
      result = fgets (fragment->buffer, BUFF_SIZE, fd);
 | 
						|
      ++fragment_count;
 | 
						|
    }
 | 
						|
  while (result && !strchr (fragment->buffer, '\n'));
 | 
						|
 | 
						|
  if (*fragment_list_head->buffer != '\0')
 | 
						|
    {
 | 
						|
      char *concatenated_line = (char *) calloc (fragment_count * BUFF_SIZE , sizeof (char));
 | 
						|
      paranoid_printf ("concatenated line allocated %p", concatenated_line);
 | 
						|
      *concatenated_line = '\0';
 | 
						|
      fragment = fragment_list_head;
 | 
						|
      while (fragment != NULL)
 | 
						|
	{
 | 
						|
	  line_fragment *previous = fragment;
 | 
						|
	  strcat (concatenated_line, fragment->buffer);
 | 
						|
	  fragment = fragment->next;
 | 
						|
	  free (previous);
 | 
						|
	}
 | 
						|
      return concatenated_line;
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      fragment = fragment_list_head;
 | 
						|
      while (fragment != NULL)
 | 
						|
	{
 | 
						|
	  line_fragment *previous = fragment;
 | 
						|
	  fragment = fragment->next;
 | 
						|
	  free (previous);
 | 
						|
	}
 | 
						|
      return NULL;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/* Characters representing whitespace.  Used by parse_* routines to
 | 
						|
delimit tokens.  */
 | 
						|
static const NO_COPY char *SPACE = " \t\n\r\f";
 | 
						|
 | 
						|
/* Parse a list aliases from a network database file.  Returns a
 | 
						|
char** structure terminated by a NULL. */
 | 
						|
static void
 | 
						|
parse_alias_list (char ***aliases, char **lasts)
 | 
						|
{
 | 
						|
  struct alias_t
 | 
						|
  {
 | 
						|
    char *alias_name;
 | 
						|
    alias_t *next;
 | 
						|
  };
 | 
						|
  alias_t *alias_list_head = NULL, *alias_list_tail = NULL;
 | 
						|
  char *alias;
 | 
						|
  int alias_count = 0;
 | 
						|
  alias = strtok_r (NULL, SPACE, lasts);
 | 
						|
 | 
						|
  while (alias)
 | 
						|
    {
 | 
						|
      ++alias_count;
 | 
						|
      alias_t *new_alias = (alias_t *) malloc (sizeof (alias_t));
 | 
						|
      paranoid_printf ("new alias alloc %p", new_alias);
 | 
						|
      if (!alias_list_head)
 | 
						|
	alias_list_head = new_alias;
 | 
						|
      if (alias_list_tail)
 | 
						|
	alias_list_tail->next = new_alias;
 | 
						|
      new_alias->next = NULL;
 | 
						|
      new_alias->alias_name = alias;
 | 
						|
      alias_list_tail = new_alias;
 | 
						|
      alias = strtok_r (NULL, SPACE, lasts);
 | 
						|
    }
 | 
						|
 | 
						|
  *aliases = (char**) calloc (alias_count + 1, sizeof (char *));
 | 
						|
  paranoid_printf ("aliases alloc %p", *aliases);
 | 
						|
 | 
						|
  char **current_entry = *aliases;
 | 
						|
  while (alias_list_head)
 | 
						|
    {
 | 
						|
      alias_t *previous = alias_list_head;
 | 
						|
      *current_entry = strdup (alias_list_head->alias_name);
 | 
						|
      paranoid_printf ("*current entry strdup %p", *current_entry);
 | 
						|
      alias_list_head = alias_list_head->next;
 | 
						|
      free (previous);
 | 
						|
      ++current_entry;
 | 
						|
    }
 | 
						|
 | 
						|
  *current_entry = NULL;
 | 
						|
}
 | 
						|
 | 
						|
/* Read the next line from svc_file, and parse it into the structure
 | 
						|
pointed to by sep.  sep can point to stack or static data, but it's
 | 
						|
members will be overwritten with pointers to dynamically allocated
 | 
						|
heap data accommodating parsed data.  It is the responsibility of the
 | 
						|
caller to free up the allocated structures. The function returns true
 | 
						|
to indicate that a line was successfully read and parsed.  False is
 | 
						|
used to indicate that no more lines can be read and parsed.  This
 | 
						|
should also interpreted as end of file. */
 | 
						|
static bool
 | 
						|
parse_services_line (FILE *svc_file, struct servent *sep)
 | 
						|
{
 | 
						|
  char *line;
 | 
						|
  while ((line = get_entire_line (svc_file)))
 | 
						|
    {
 | 
						|
      char *name, *port, *protocol, *lasts;
 | 
						|
 | 
						|
      line[strcspn (line, "#")] = '\0'; // truncate at comment marker.
 | 
						|
      name = strtok_r (line, SPACE, &lasts);
 | 
						|
      if (!name)
 | 
						|
	{
 | 
						|
	  free (line);
 | 
						|
	  continue;
 | 
						|
	}
 | 
						|
      port = strtok_r (NULL, SPACE, &lasts);
 | 
						|
      protocol = strchr (port, '/');
 | 
						|
      *protocol++ = '\0';
 | 
						|
      sep->s_name = strdup (name);
 | 
						|
      paranoid_printf ("sep->s_name strdup %p", sep->s_name);
 | 
						|
      sep->s_port = atoi (port);
 | 
						|
      sep->s_proto = strdup (protocol);
 | 
						|
      paranoid_printf ("sep->s_proto strdup %p", sep->s_proto);
 | 
						|
      /* parse_alias_list relies on side effects.  Read the comments
 | 
						|
	 for that function.*/
 | 
						|
      parse_alias_list (& sep->s_aliases, &lasts);
 | 
						|
      free (line);
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static FILE *svc_file = NULL;
 | 
						|
static long int svc_read_pos = 0;
 | 
						|
static struct servent current_servent;
 | 
						|
 | 
						|
/* Steps through a struct servent, and frees all of the internal
 | 
						|
structures.*/
 | 
						|
static void
 | 
						|
free_servent (struct servent *sep)
 | 
						|
{
 | 
						|
  free (sep->s_name);
 | 
						|
  free (sep->s_proto);
 | 
						|
  char ** current = sep->s_aliases;
 | 
						|
  while (current && *current)
 | 
						|
    {
 | 
						|
      free (*current);
 | 
						|
      ++current;
 | 
						|
    }
 | 
						|
  free (sep->s_aliases);
 | 
						|
  sep->s_name = NULL;
 | 
						|
  sep->s_port = 0;
 | 
						|
  sep->s_proto = NULL;
 | 
						|
  sep->s_aliases = NULL;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void
 | 
						|
cygwin_setservent (int stay_open)
 | 
						|
{
 | 
						|
  if (svc_file)
 | 
						|
    fclose (svc_file);
 | 
						|
  if (stay_open)
 | 
						|
    svc_file = open_services_file ();
 | 
						|
  free_servent (¤t_servent);
 | 
						|
  svc_read_pos = 0;
 | 
						|
  syscall_printf ("setservent (%d)", stay_open);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" struct servent *
 | 
						|
cygwin_getservent (void)
 | 
						|
{
 | 
						|
  FILE *fd;
 | 
						|
  if (svc_file)
 | 
						|
    fd = svc_file;
 | 
						|
  else
 | 
						|
    {
 | 
						|
      fd = open_services_file ();
 | 
						|
      if (!fd)
 | 
						|
	{
 | 
						|
	  syscall_printf ("%p = getservent()", NULL);
 | 
						|
	  return NULL;
 | 
						|
	}
 | 
						|
      fseek (fd, svc_read_pos, SEEK_SET);
 | 
						|
    }
 | 
						|
  free_servent (¤t_servent);
 | 
						|
  bool found = parse_services_line (fd, ¤t_servent);
 | 
						|
  if (!svc_file)
 | 
						|
    {
 | 
						|
      svc_read_pos = ftell (fd);
 | 
						|
      fclose (fd);
 | 
						|
    }
 | 
						|
  struct servent *result;
 | 
						|
  if (found)
 | 
						|
    result = ¤t_servent;
 | 
						|
  else
 | 
						|
    result = NULL;
 | 
						|
  syscall_printf ("%p = getservent()", result);
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void
 | 
						|
cygwin_endservent (void)
 | 
						|
{
 | 
						|
  if (svc_file)
 | 
						|
    {
 | 
						|
      fclose (svc_file);
 | 
						|
      svc_file = NULL;
 | 
						|
    }
 | 
						|
  free_servent (¤t_servent);
 | 
						|
  svc_read_pos = 0;
 | 
						|
  syscall_printf ("endservent ()");
 | 
						|
}
 | 
						|
 | 
						|
/* Read the next line from proto_file, and parse it into the structure
 | 
						|
pointed to by pep.  pep can point to stack or static data, but it's
 | 
						|
members will be overwritten with pointers to dynamically allocated
 | 
						|
heap data accommodating parsed data.  It is the responsibility of the
 | 
						|
caller to free up the allocated structures. The function returns true
 | 
						|
to indicate that a line was successfully read and parsed.  False is
 | 
						|
used to indicate that no more lines can be read and parsed.  This
 | 
						|
should also interpreted as end of file. */
 | 
						|
static bool
 | 
						|
parse_protocol_line (FILE *proto_file, struct protoent *pep)
 | 
						|
{
 | 
						|
  char *line;
 | 
						|
  while ((line = get_entire_line (proto_file)))
 | 
						|
    {
 | 
						|
      char *name, *protocol, *lasts;
 | 
						|
 | 
						|
      line[strcspn (line, "#")] = '\0'; // truncate at comment marker.
 | 
						|
      name = strtok_r (line, SPACE, &lasts);
 | 
						|
      if (!name)
 | 
						|
	{
 | 
						|
	  free (line);
 | 
						|
	  continue;
 | 
						|
	}
 | 
						|
      protocol = strtok_r (NULL, SPACE, &lasts);
 | 
						|
      pep->p_name = strdup (name);
 | 
						|
      paranoid_printf ("pep->p_name strdup %p", pep->p_name);
 | 
						|
      pep->p_proto = atoi (protocol);
 | 
						|
      /* parse_alias_list relies on side effects.  Read the comments
 | 
						|
	 for that function.*/
 | 
						|
      parse_alias_list (& pep->p_aliases, &lasts);
 | 
						|
      free (line);
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
static FILE *proto_file = NULL;
 | 
						|
static long int proto_read_pos = 0;
 | 
						|
static struct protoent current_protoent;
 | 
						|
 | 
						|
/* Steps through a struct protoent, and frees all the internal
 | 
						|
structures.  */
 | 
						|
static void
 | 
						|
free_protoent (struct protoent *pep)
 | 
						|
{
 | 
						|
  free (pep->p_name);
 | 
						|
  char ** current = pep->p_aliases;
 | 
						|
  while (current && *current)
 | 
						|
    {
 | 
						|
      free (*current);
 | 
						|
      ++current;
 | 
						|
    }
 | 
						|
  free (pep->p_aliases);
 | 
						|
  pep->p_name = NULL;
 | 
						|
  pep->p_proto = 0;
 | 
						|
  pep->p_aliases = NULL;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void
 | 
						|
cygwin_setprotoent (int stay_open)
 | 
						|
{
 | 
						|
  if (proto_file)
 | 
						|
    fclose (proto_file);
 | 
						|
 | 
						|
  if (stay_open)
 | 
						|
    proto_file = open_protocol_file ();
 | 
						|
 | 
						|
  free_protoent (¤t_protoent);
 | 
						|
  proto_read_pos = 0;
 | 
						|
  syscall_printf ("setprotoent (%d)", stay_open);
 | 
						|
}
 | 
						|
 | 
						|
extern "C" struct protoent *
 | 
						|
cygwin_getprotoent (void)
 | 
						|
{
 | 
						|
  FILE *fd;
 | 
						|
 | 
						|
  if (proto_file)
 | 
						|
    fd = proto_file;
 | 
						|
  else
 | 
						|
    {
 | 
						|
      fd = open_protocol_file ();
 | 
						|
      if (!fd)
 | 
						|
	{
 | 
						|
	  syscall_printf ("%p = getprotoent()", NULL);
 | 
						|
	  return NULL;
 | 
						|
	}
 | 
						|
      fseek (fd, proto_read_pos, SEEK_SET);
 | 
						|
    }
 | 
						|
  free_protoent (¤t_protoent);
 | 
						|
 | 
						|
  bool found = parse_protocol_line (fd, ¤t_protoent);
 | 
						|
  if (!proto_file)
 | 
						|
    {
 | 
						|
      proto_read_pos = ftell (fd);
 | 
						|
      fclose (fd);
 | 
						|
    }
 | 
						|
 | 
						|
  struct protoent *result;
 | 
						|
  if (found)
 | 
						|
    result =  ¤t_protoent;
 | 
						|
  else
 | 
						|
    result =  NULL;
 | 
						|
 | 
						|
  syscall_printf ("%p = getprotoent()", result);
 | 
						|
  return result;
 | 
						|
}
 | 
						|
 | 
						|
extern "C" void
 | 
						|
cygwin_endprotoent (void)
 | 
						|
{
 | 
						|
  if (proto_file)
 | 
						|
    {
 | 
						|
      fclose (proto_file);
 | 
						|
      proto_file = NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  free_protoent (¤t_protoent);
 | 
						|
  proto_read_pos = 0;
 | 
						|
  syscall_printf ("endprotoent ()");
 | 
						|
}
 |