wine/misc/winsock_dns.c
Alexandre Julliard 60ce85c965 Release 980201
Sun Feb  1 13:24:54 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Added Device= parameter to drive configuration.

	* [if1632/relay.c]
	Throw() and Catch() now use the correct CATCHBUF layout (untested).

	* [tools/build.c] [include/stackframe.h] [loader/task.c]
	Moved 16-bit stack pointer into thread database.
	Save current %fs while running 16-bit code.

Fri Jan 30 09:25:49 1998  Martin Boehme  <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c]
	Made DPtoLP32 and LPtoDP32 respect world transforms.

	* [graphics/path.c] [graphics/painting.c] [if1632/gdi.spec]
	  [include/path.h]
	More path support.

	* [include/gdi.h] [include/windows.h] [objects/dc.c]
	  [relay/gdi32.spec]
	Support for Get/SetArcDirection and Get/SetWorldTransform

	* [windows/hook.c]
	Fixed a bug in HOOK_Map16To32Common.

Thu Jan 29 23:43:18 1998  Douglas Ridgway <ridgway@taiga.gmcl.com>

	* [graphics/metafiledrv/init.c] [objects/metafile.c]
	Documentation for metafile related API calls. Fixed a bug to avoid
	documenting it.

	* [include/windows.h]
	Declaration for LoadImage.

Thu Jan 29 21:44:45 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [graphics/win16drv/*]
	Changes to printing code to enable use of printer fonts with the
	win3.1 postscript driver. Remember to add printer=on to [wine]
	section of wine.conf . You will also need to disable truetype
	fonts from control panel. Winword 6.0 and Write seem to be happy
	with this...

	* [include/bitmap.h]
	Fix Widthbytes for 15bpp displays.

Tue Jan 27 20:54:08 1998  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [tsx11/*] [include/ts*] [tools/make_X11wrappers]
	Implemented thread-safe X11 wrappers.

Tue Jan 27 13:54:09 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	* [windows/queue.c]
	Forgot to convert thdb to thread_id.

	* [misc/registry.c]
	Sped up Windows 95 registry reading. Changed code to traverse
	registry as a tree rather than read in all possible keys
	(including dead ones). 

Tue Jan 27 12:46:09 1998  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][Makefile.in][scheduler/thread.c]
	  [libtest/hello5.c]
	Don't exit() on failed to load referenced dlls.
	Fixed static tls allocation for multiple threads.
	WINELIB should now be able to load PE dlls. A sample
	winelib program, that dynamically loads a internal dll
	is included.

	* [graphics/ddraw.c][include/ddraw.h][include/d3d.h]
	Cleaned up and enhanced further. Added several DirectX5
	interface definitions and DirectSurface3 implementation.
	Stubs for D3D (NOT coming soon, just there so it fails safely).

	* [multimedia/dsound.c][include/dsound.h]
	Actually works now for a lot of cases. Some DirectX5 stuff
	added. Still lacking several features.

	* [windows/dinput.c][include/dinput.h]
	Started implementing DirectInput. Doesn't work yet, don't 
	know why.

	* [if1632/thunk.c][misc/callbacks.c]
	  [win32/kernel.c][include/callbacks.h]
	Added WOWCallback16Ex, WOWHandle32.

	* [misc/cpu.c]
	Fixed GetSystemInfo, IsProcessorFeaturePresent.

	* [multimedia/joystick.c][multimedia/time.c]
	Several fixes. Small hack to get timerevents in timeGetTime() loops.

Tue Jan 20 11:26:27 1998  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [configure.in]
	Fixed check for union semun on FreeBSD systems.

Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>

	* [misc/ole2nls.c] [programs/progman/Sw.rc] [programs/winhelp/Sw.rc]
	  [resources/sysres_Sw.rc]
	Added/updated Swedish language support.

Sun Jan 18 18:49:01 1998  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [misc/winsock.c] [misc/winsock_dns.c] [windows/event.c]
	  [windows/win.c] [windows/dce.c] [windows/winpos.c]
	Bug fixes.

Sun Jan 18 12:45:23 1997  Andreas Mohr <100.30936@germany.net>

	* [msdos/int25.c] [msdos/int26.c]
        Implemented "native" absolute disk read/write access.

	* [msdos/int13.c] [msdos/ioports.c]
	Enhanced GET DRIVE PARAMETERS (int13 AH=08).

	* [graphics/win16drv/prtdrv.c] [if1632/gdi.spec]
	Fixed typos, implemented dmEnumDFonts,
	Started implementation of dmRealizeObject.

	* [if1632/compobj.spec] [ole/compobj.c] [relay32/ole32.spec]
	Stubs CoCreateInstance, CoFreeUnusedLibraries, implemented
	CoFileTimeNow.

	* [if1632/kernel.spec] [include/windows.h] [memory/global.c]
	  [memory/string.c] [misc/kernel.c] [misc/Makefile.in]
	  [misc/toolhelp.c] [msdos/int21.c]
	Implemented GlobalHandleNoRIP, GetFreeMemInfo, DebugFillBuffer, 
	stubs GetSetKernelDOSProc, DiagQuery, DiagOutput, ToolHelpHook
	(Undocumented Windows).

	* [if1632/user.spec] [if1632/win32s16.spec] [misc/win32s16.c]
	Misc stubs.

	* [if1632/winaspi.spec] [misc/aspi.c]
	Implemented GetASPIDLLVersion.

	* [if1632/wprocs.spec] [msdos/int20.c] [msdos/Makefile.in]
	Added handler for Int 0x20 (terminate program, _very_ old-fashioned).

	* [misc/w32scomb.c]
	Implemented Get16DLLAddress() partially
	(big thanks to Marcus and Alexandre).

	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/dplay.spec]
	Added built-in DPLAY.DLL.

	* [relay32/winmm.spec] [multimedia/joystick.c]
	Added joySetThreshold.

	* [misc/windebug.c]
	Added WinNotify.

	* [win32/console.c]
	Stubs CreateConsoleScreenBuffer, SetConsoleActiveScreenBuffer,
	WriteConsoleOutput32A.

	* [windows/user.c]
	Stub SetEventHook.

Sat Jan 17 19:30:35 1998  Matthew Toseland  <Paul.Toseland@btinternet.com>

	* [windows/painting.c]
	Fixed broken restore-to-maximized.

Mon Jan 12 21:25:32 1998  Perceval - Marc Huguet Puig <mhp@tinet.fut.es>

	* [documentation/wine.man] [include/options.h]
	  [misc/main.c] [ole/ole2nls.c] [resources/sysres.c]
	  [resources/sysres_Ca.rc] [resources/Makefile.in]
	Added language catalan. (Afegit l'idioma català).
1998-02-01 18:33:27 +00:00

562 lines
15 KiB
C

/*
* asynchronous DNS services
*
* (C) 1996,1997 Alex Korobka.
*
* TODO: Fork dns lookup helper during the startup (with a pipe
* for communication) and make it fork for a database request
* instead of forking the main process (i.e. something like
* Netscape 4.0).
*/
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <errno.h>
#ifdef __EMX__
#include <sys/so_ioctl.h>
#include <sys/param.h>
#endif
#ifdef __svr4__
#include <sys/file.h>
#include <sys/filio.h>
#endif
extern int h_errno;
#include "winsock.h"
#include "windows.h"
#include "heap.h"
#include "ldt.h"
#include "message.h"
#include "miscemu.h"
#include "debug.h"
#ifndef FASYNC
#define FASYNC FIOASYNC
#endif
#define __WS_ASYNC_DEBUG 0
typedef struct /* async DNS op control struct */
{
ws_async_op* ws_aop;
char* buffer;
int type;
union
{
char* init;
char* name;
char* addr;
} rq;
unsigned ilength;
} ws_async_ctl;
extern HANDLE16 __ws_gethandle( void* ptr );
extern void* __ws_memalloc( int size );
extern void __ws_memfree( void* ptr );
/* NOTE: ws_async_op list is traversed inside the SIGIO handler! */
static int __async_io_max_fd = 0;
static fd_set __async_io_fdset;
static ws_async_op* __async_op_list = NULL;
static void fixup_wshe(struct ws_hostent* p_wshe, void* base);
static void fixup_wspe(struct ws_protoent* p_wspe, void* base);
static void fixup_wsse(struct ws_servent* p_wsse, void* base);
extern void EVENT_AddIO( int fd, unsigned flag );
extern void EVENT_DeleteIO( int fd, unsigned flag );
/* ----------------------------------- async/non-blocking I/O */
int WINSOCK_async_io(int fd, int async)
{
int fd_flags;
#ifndef __EMX__
fcntl(fd, F_SETOWN, getpid());
#endif
fd_flags = fcntl(fd, F_GETFL, 0);
if (fcntl(fd, F_SETFL, (async)? fd_flags | FASYNC
: fd_flags & ~FASYNC ) != -1) return 0;
return -1;
}
int WINSOCK_unblock_io(int fd, int noblock)
{
int fd_flags;
fd_flags = fcntl(fd, F_GETFL, 0);
if (fcntl(fd, F_SETFL, (noblock)? fd_flags | O_NONBLOCK
: fd_flags & ~O_NONBLOCK ) != -1) return 0;
return -1;
}
int WINSOCK_check_async_op(ws_async_op* p_aop)
{
ws_async_op* p = __async_op_list;
while( p ) if( p == p_aop ) return 1;
else p = p->next;
return 0;
}
int WINSOCK_cancel_async_op(ws_async_op* p_aop)
{
/* SIGIO unsafe! */
if( WINSOCK_check_async_op(p_aop) )
{
if( !(p_aop->flags & WSMSG_DEAD_AOP) )
{
kill(p_aop->pid, SIGKILL);
waitpid(p_aop->pid, NULL, 0); /* just in case */
close(p_aop->fd[0]);
}
WINSOCK_unlink_async_op(p_aop);
EVENT_DeleteIO( p_aop->fd[0], EVENT_IO_READ );
p_aop->flags = 0;
p_aop->hWnd = p_aop->uMsg = 0;
return 1;
}
return 0;
}
void WINSOCK_cancel_task_aops(HTASK16 hTask, void (*__opfree)(void*))
{
/* SIGIO safe, hTask == 0 cancels all outstanding async ops */
int num = 0;
ws_async_op* p, *next;
dprintf_winsock(stddeb,"\tcancelling async DNS requests... ");
SIGNAL_MaskAsyncEvents( TRUE );
next = __async_op_list;
while( (p = next) )
{
HTASK16 hWndTask = GetWindowTask16(p->hWnd);
next = p->next;
if(!hTask || !hWndTask || (hTask == hWndTask))
{
WINSOCK_cancel_async_op(p);
if( __opfree ) __opfree(p);
num++;
}
}
SIGNAL_MaskAsyncEvents( FALSE );
dprintf_winsock(stddeb,"%i total\n", num );
}
void WINSOCK_link_async_op(ws_async_op* p_aop)
{
/* SIGIO safe */
p_aop->prev = NULL;
SIGNAL_MaskAsyncEvents( TRUE );
if( __async_op_list )
{
ws_async_op* p = __async_op_list;
__async_op_list->prev = p_aop;
/* traverse the list and retire dead ops created
* by the signal handler (see below). */
while( p )
{
if( p->flags & WSMSG_DEAD_AOP )
{
ws_async_op* dead = p;
dprintf_winsock(stddeb,"\treaping dead aop [%08x]\n", (unsigned)p );
p = p->next;
WINSOCK_unlink_async_op( dead );
__ws_memfree( dead );
continue;
}
p = p->next;
}
}
else FD_ZERO(&__async_io_fdset);
p_aop->next = __async_op_list;
__async_op_list = p_aop;
SIGNAL_MaskAsyncEvents( FALSE );
FD_SET(p_aop->fd[0], &__async_io_fdset);
if( p_aop->fd[0] > __async_io_max_fd )
__async_io_max_fd = p_aop->fd[0];
}
void WINSOCK_unlink_async_op(ws_async_op* p_aop)
{
/* SIGIO unsafe! */
if( p_aop == __async_op_list ) __async_op_list = p_aop->next;
else
p_aop->prev->next = p_aop->next;
if( p_aop->next ) p_aop->next->prev = p_aop->prev;
FD_CLR(p_aop->fd[0], &__async_io_fdset);
if( p_aop->fd[0] == __async_io_max_fd )
__async_io_max_fd--;
}
/* ----------------------------------- SIGIO handler -
*
* link_async_op/unlink_async_op allow to install generic
* async IO handlers (provided that aop_control function is defined).
*
* Note: pipe-based handlers must raise explicit SIGIO with kill(2).
*/
void WINSOCK_sigio(int signal)
{
struct timeval timeout;
fd_set check_set;
ws_async_op* p_aop;
check_set = __async_io_fdset;
memset(&timeout, 0, sizeof(timeout));
while( select(__async_io_max_fd + 1,
&check_set, NULL, NULL, &timeout) > 0)
{
for( p_aop = __async_op_list;
p_aop ; p_aop = p_aop->next )
if( FD_ISSET(p_aop->fd[0], &check_set) )
if( p_aop->aop_control(p_aop, AOP_IO) == AOP_CONTROL_REMOVE )
{
/* NOTE: memory management is signal-unsafe, therefore
* we can only set a flag to remove this p_aop later on.
*/
p_aop->flags = WSMSG_DEAD_AOP;
close(p_aop->fd[0]);
FD_CLR(p_aop->fd[0],&__async_io_fdset);
if( p_aop->fd[0] == __async_io_max_fd )
__async_io_max_fd = p_aop->fd[0];
if( p_aop->pid )
{
kill(p_aop->pid, SIGKILL);
waitpid(p_aop->pid, NULL, WNOHANG);
p_aop->pid = 0;
}
}
check_set = __async_io_fdset;
}
}
/* ----------------------------------- getXbyY requests */
static ws_async_ctl async_ctl; /* child process control struct */
static int aop_control(ws_async_op* p_aop, int flag )
{
unsigned lLength;
/* success: LOWORD(lLength) has the length of the struct
* to read.
* failure: LOWORD(lLength) is zero, HIWORD(lLength) contains
* the error code.
*/
read(p_aop->fd[0], &lLength, sizeof(unsigned));
if( LOWORD(lLength) )
{
if( (int)LOWORD(lLength) <= p_aop->buflen )
{
char* buffer = (p_aop->flags & WSMSG_ASYNC_WIN32)
? p_aop->b.lin_base : (char*)PTR_SEG_TO_LIN(p_aop->b.seg_base);
read(p_aop->fd[0], buffer, LOWORD(lLength));
switch( p_aop->flags )
{
case WSMSG_ASYNC_HOSTBYNAME:
case WSMSG_ASYNC_HOSTBYADDR:
fixup_wshe((struct ws_hostent*)buffer, p_aop->b.ptr_base); break;
case WSMSG_ASYNC_PROTOBYNAME:
case WSMSG_ASYNC_PROTOBYNUM:
fixup_wspe((struct ws_protoent*)buffer, p_aop->b.ptr_base); break;
case WSMSG_ASYNC_SERVBYNAME:
case WSMSG_ASYNC_SERVBYPORT:
fixup_wsse((struct ws_servent*)buffer, p_aop->b.ptr_base); break;
default:
if( p_aop->flags ) fprintf(stderr,"Received unknown async request!\n");
return AOP_CONTROL_REMOVE;
}
}
else lLength = ((UINT32)LOWORD(lLength)) | ((unsigned)WSAENOBUFS << 16);
} /* failure */
#if __WS_ASYNC_DEBUG
printf("DNS aop completed: hWnd [%04x], uMsg [%04x], aop [%04x], event [%08x]\n",
p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength);
#endif
/* FIXME: update num_async_rq */
EVENT_DeleteIO( p_aop->fd[0], EVENT_IO_READ );
PostMessage32A( p_aop->hWnd, p_aop->uMsg, __ws_gethandle(p_aop), (LPARAM)lLength );
return AOP_CONTROL_REMOVE; /* one-shot request */
}
HANDLE16 __WSAsyncDBQuery(LPWSINFO pwsi, HWND32 hWnd, UINT32 uMsg, INT32 type, LPSTR init,
INT32 len, LPSTR proto, void* sbuf, INT32 buflen, UINT32 flag)
{
/* queue 'flag' request and fork off its handler */
async_ctl.ws_aop = (ws_async_op*)__ws_memalloc(sizeof(ws_async_op));
if( async_ctl.ws_aop )
{
HANDLE16 handle = __ws_gethandle(async_ctl.ws_aop);
if( pipe(async_ctl.ws_aop->fd) == 0 )
{
async_ctl.rq.init = (char*)init;
async_ctl.ilength = len;
async_ctl.buffer = proto;
async_ctl.type = type;
async_ctl.ws_aop->hWnd = hWnd;
async_ctl.ws_aop->uMsg = uMsg;
async_ctl.ws_aop->b.ptr_base = sbuf;
async_ctl.ws_aop->buflen = buflen;
async_ctl.ws_aop->flags = flag;
async_ctl.ws_aop->aop_control = &aop_control;
WINSOCK_link_async_op( async_ctl.ws_aop );
EVENT_AddIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
pwsi->num_async_rq++;
async_ctl.ws_aop->pid = fork();
if( async_ctl.ws_aop->pid )
{
dprintf_winsock(stddeb, "\tasync_op = %04x (child %i)\n",
handle, async_ctl.ws_aop->pid);
close(async_ctl.ws_aop->fd[1]); /* write endpoint */
if( async_ctl.ws_aop->pid > 0 )
return __ws_gethandle(async_ctl.ws_aop);
/* fork() failed */
pwsi->num_async_rq--;
EVENT_DeleteIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
close(async_ctl.ws_aop->fd[0]);
pwsi->err = WSAEWOULDBLOCK;
}
else
{
/* child process */
close(async_ctl.ws_aop->fd[0]); /* read endpoint */
switch( flag )
{
case WSMSG_ASYNC_HOSTBYADDR:
case WSMSG_ASYNC_HOSTBYNAME:
WS_do_async_gethost(pwsi, flag);
break;
case WSMSG_ASYNC_PROTOBYNUM:
case WSMSG_ASYNC_PROTOBYNAME:
WS_do_async_getproto(pwsi, flag);
break;
case WSMSG_ASYNC_SERVBYPORT:
case WSMSG_ASYNC_SERVBYNAME:
WS_do_async_getserv(pwsi, flag);
break;
}
_exit(0); /* skip atexit()'ed cleanup */
}
}
else pwsi->err = wsaErrno(); /* failed to create pipe */
__ws_memfree((void*)async_ctl.ws_aop);
} else pwsi->err = WSAEWOULDBLOCK;
return 0;
}
static int _async_notify()
{
/* use half-duplex pipe to send variable length packets
* to the parent process */
write(async_ctl.ws_aop->fd[1], &async_ctl.ilength, sizeof(unsigned));
write(async_ctl.ws_aop->fd[1], async_ctl.buffer, async_ctl.ilength );
#ifndef __EMX__
kill(getppid(), SIGIO); /* simulate async I/O */
#endif
#if __WS_ASYNC_DEBUG
printf("handler - notify aop [%d, buf %d]\n", async_ctl.ilength, async_ctl.ws_aop->buflen);
#endif
return 1;
}
static void _async_fail()
{
/* write a DWORD with error code (low word is zero) */
async_ctl.ilength =
(h_errno < 0) ? (unsigned)WSAMAKEASYNCREPLY( 0, wsaErrno() )
: (unsigned)WSAMAKEASYNCREPLY( 0, wsaHerrno() );
write(async_ctl.ws_aop->fd[1], &async_ctl.ilength, sizeof(unsigned) );
#ifndef __EMX__
kill(getppid(), SIGIO); /* simulate async I/O */
#endif
#if __WS_ASYNC_DEBUG
printf("handler - failed aop [%d, buf %d]\n", async_ctl.ilength, async_ctl.ws_aop->buflen);
#endif
}
void dump_ws_hostent_offset(struct ws_hostent* wshe)
{
int i;
char* base = (char*)wshe;
unsigned* ptr;
printf("h_name = %08x\t[%s]\n", (unsigned)wshe->h_name, base + (unsigned)wshe->h_name);
printf("h_aliases = %08x\t[%08x]\n", (unsigned)wshe->h_aliases,
(unsigned)(base + (unsigned)wshe->h_aliases));
ptr = (unsigned*)(base + (unsigned)wshe->h_aliases);
for(i = 0; ptr[i]; i++ )
{
printf("%i - %08x ", i + 1, ptr[i]);
printf(" [%s]\n", ((char*)base) + ptr[i]);
}
printf("h_length = %i\n", wshe->h_length);
}
void WS_do_async_gethost(LPWSINFO pwsi, unsigned flag )
{
int size = 0;
struct hostent* p_he;
close(async_ctl.ws_aop->fd[0]);
p_he = (flag & WSMSG_ASYNC_HOSTBYNAME)
? gethostbyname(async_ctl.rq.name)
: gethostbyaddr(async_ctl.rq.name,
async_ctl.ilength, async_ctl.type);
dprintf_winsock(stddeb,"DNS: got hostent for [%s]\n", async_ctl.rq.name );
if( p_he ) /* convert to the Winsock format with internal pointers as offsets */
size = WS_dup_he(pwsi, p_he, WS_DUP_OFFSET |
((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
async_ctl.buffer = pwsi->buffer;
async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
}
void WS_do_async_getproto(LPWSINFO pwsi, unsigned flag )
{
int size = 0;
struct protoent* p_pe;
close(async_ctl.ws_aop->fd[0]);
p_pe = (flag & WSMSG_ASYNC_PROTOBYNAME)
? getprotobyname(async_ctl.rq.name)
: getprotobynumber(async_ctl.type);
dprintf_winsock(stddeb,"DNS: got protoent for [%s]\n", async_ctl.rq.name );
if( p_pe ) /* convert to the Winsock format with internal pointers as offsets */
size = WS_dup_pe(pwsi, p_pe, WS_DUP_OFFSET |
((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
async_ctl.buffer = pwsi->buffer;
async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
}
void WS_do_async_getserv(LPWSINFO pwsi, unsigned flag )
{
int size = 0;
struct servent* p_se;
close(async_ctl.ws_aop->fd[0]);
p_se = (flag & WSMSG_ASYNC_SERVBYNAME)
? getservbyname(async_ctl.rq.name, async_ctl.buffer)
: getservbyport(async_ctl.type, async_ctl.buffer);
if( p_se ) /* convert to the Winsock format with internal pointers as offsets */
size = WS_dup_se(pwsi, p_se, WS_DUP_OFFSET |
((flag & WSMSG_ASYNC_WIN32) ? WS_DUP_LINEAR : WS_DUP_SEGPTR) );
if( size )
{
async_ctl.buffer = pwsi->buffer;
async_ctl.ilength = (unsigned)WSAMAKEASYNCREPLY( (UINT16)size, 0 );
_async_notify( flag );
}
else _async_fail();
}
/* ----------------------------------- helper functions -
*
* Raw results from pipe contain internal pointers stored as
* offsets relative to the beginning of the buffer and we need
* to apply a fixup before passing them to applications.
*
* NOTE: It is possible to exploit the fact that fork() doesn't
* change the buffer address by storing fixed up pointers right
* in the handler. However, this will get in the way if we ever
* get around to implementing DNS helper daemon a-la Netscape.
*/
void fixup_wshe(struct ws_hostent* p_wshe, void* base)
{
/* add 'base' to ws_hostent pointers to convert them from offsets */
int i;
unsigned* p_aliases,*p_addr;
p_aliases = (unsigned*)((char*)p_wshe + (unsigned)p_wshe->h_aliases);
p_addr = (unsigned*)((char*)p_wshe + (unsigned)p_wshe->h_addr_list);
((unsigned)(p_wshe->h_name)) += (unsigned)base;
((unsigned)(p_wshe->h_aliases)) += (unsigned)base;
((unsigned)(p_wshe->h_addr_list)) += (unsigned)base;
for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
for(i=0;p_addr[i];i++) p_addr[i] += (unsigned)base;
}
void fixup_wspe(struct ws_protoent* p_wspe, void* base)
{
int i;
unsigned* p_aliases = (unsigned*)((char*)p_wspe + (unsigned)p_wspe->p_aliases);
((unsigned)(p_wspe->p_name)) += (unsigned)base;
((unsigned)(p_wspe->p_aliases)) += (unsigned)base;
for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
}
void fixup_wsse(struct ws_servent* p_wsse, void* base)
{
int i;
unsigned* p_aliases = (unsigned*)((char*)p_wsse + (unsigned)p_wsse->s_aliases);
((unsigned)(p_wsse->s_name)) += (unsigned)base;
((p_wsse->s_proto)) += (unsigned)base;
((p_wsse->s_aliases)) += (unsigned)base;
for(i=0;p_aliases[i];i++) p_aliases[i] += (unsigned)base;
}