2006-07-25 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/version.h: Bump DLL version to 1.7.0. 2006-07-25 Corinna Vinschen <corinna@vinschen.de> * select.h: Remove. * fhandler_socket.cc: Don't include select.h. * select.cc: Ditto. 2006-07-25 Corinna Vinschen <corinna@vinschen.de> * cygtls.h: Drop socket related includes. (struct _local_storage): Remove exitsock and exitsock_sin. Add select_sockevt. * cygtls.cc: Accomodate above change throughout. * fhandler.h (class fhandler_socket): Make wsock_evt public. * fhandler_socket.cc (fhandler_socket::fhandler_socket): Accomodate reordering members. (fhandler_socket::evaluate_events): Drop FD_CONNECT event as soon as it gets read once. Never remove FD_WRITE event here. (fhandler_socket::wait_for_events): Wait 50 ms instead of INFINITE for socket events. (fhandler_socket::accept): Fix conditional. Set wsock_events members of accepted socket to useful start values. (fhandler_socket::recv_internal): Always drop FD_READ/FD_OOB events from wsock_events after the call to WSARecvFrom. (fhandler_socket::send_internal): Drop FD_WRITE event from wsock_events if the call to WSASendTo fails with WSAEWOULDBLOCK. Fix return value condition. * select.cc (struct socketinf): Change to accomodate using socket event handling. (peek_socket): Use event handling for peeking socket. (thread_socket): Ditto. (start_thread_socket): Ditto. (socket_cleanup): Same here. * tlsoffsets.h: Regenerate. 2006-07-20 Corinna Vinschen <corinna@vinschen.de> * fhandler.h (class fhandler_socket): Rearrange slightly to keep event handling methods and members together. Drop owner status flag. Split wait method. Rename event handling methods for readability. * fhandler_socket.cc (struct wsa_event): Add owner field. (LOCK_EVENTS): New macro. (UNLOCK_EVENTS): Ditto. (fhandler_socket::init_events): rename from prepare. (fhandler_socket::evaluate_events): First half of former wait method. Do everything but wait. Allow specifiying whether or not events from event_mask should be erased from wsock_events->events. Simplify OOB handling. Allow sending SIGURG to any process (group). (fhandler_socket::wait_for_events): Second half of former wait method. Call evaluate_events and wait in a loop if socket is blocking. (fhandler_socket::release_events): Rename from release. (fhandler_socket::connect): Accomodate above name changes. (fhandler_socket::accept): Ditto. (fhandler_socket::recv_internal): Ditto. (fhandler_socket::send_internal): Ditto. (fhandler_socket::close): Ditto. (fhandler_socket::fcntl): Always set owner to given input value on F_SETOWN. Handle F_GETOWN. * net.cc (fdsock): Accomodate above name changes. 2006-07-20 Corinna Vinschen <corinna@vinschen.de> * fhandler_socket.cc (fhandler_socket::wait): Set Winsock errno to WSAEWOULDBLOCK instead of WSAEINPROGRESS. 2006-07-18 Brian Ford <Brian.Ford@FlightSafety.com> Corinna Vinschen <corinna@vinschen.de> * winsup.h (mmap_region_status): New enum. (mmap_is_attached_or_noreserve_page): Adjust prototype and rename as below. * mmap.cc (mmap_is_attached_or_noreserve_page): Rename mmap_is_attached_or_noreserve. Add region length parameter. Return enum above. * exceptions.cc (_cygtls::handle_exceptions): Accomodate above. * fhandler.cc (fhandler_base::raw_read): Call above for NOACCESS errors and retry on success to allow reads into untouched MAP_NORESERVE buffers. 2006-07-18 Corinna Vinschen <corinna@vinschen.de> * cygwin.din (posix_openpt): Export. * tty.cc (posix_openpt): New function. * include/cygwin/stdlib.h (posix_openpt): Declare. * include/cygwin/version.h: Bump API minor number. 2006-07-14 Corinna Vinschen <corinna@vinschen.de> * security.cc (get_token_group_sidlist): Always add the interactive group to the token. Add comment. Create logon_id group SID by copying it from incoming group list. (create_token): Add subauth_token parameter. Use information in subauth_token if present. Tweak SourceIdentifier if subauth_token is present for debugging purposes. * security.h (create_token): Add subauth_token parameter in declaration. * syscalls.cc (seteuid32): Call subauth first. Call create_token regardless. Use subauth token in call to create_token if subauth succeeded. 2006-07-13 Corinna Vinschen <corinna@vinschen.de> * include/netinet/in.h: Update copyright. 2006-07-13 Corinna Vinschen <corinna@vinschen.de> * fhandler_socket.cc (fhandler_socket::wait): Rework function so that WaitForMultipleObjects is really only called when necessary. 2006-07-12 Corinna Vinschen <corinna@vinschen.de> * include/netdb.h: Declare rcmd, rcmd_af, rexec, rresvport, rresvport_af, iruserok, iruserok_sa, ruserok. 2006-07-12 Corinna Vinschen <corinna@vinschen.de> * Makefile.in (DLL_OFILES): Drop iruserok.o. Add rcmd.o. * autoload.cc (rcmd): Drop definition. * cygwin.din: Export bindresvport, bindresvport_sa, iruserok_sa, rcmd_af, rresvport_af. * net.cc (cygwin_rcmd): Remove. (last_used_bindresvport): Rename from last_used_rrecvport. (cygwin_bindresvport_sa): New function implementing bindresvport_sa. (cygwin_bindresvport): New function implementing bindresvport. (cygwin_rresvport): Remove. * include/cygwin/version.h: Bump API minor number. * include/netinet/in.h: Declare bindresvport and bindresvport_sa. * libc/iruserok.c: Remove file. * libc/rcmd.cc: New file implementing rcmd, rcmd_af, rresvport, rresvport_af, iruserok_sa, iruserok and ruserok. 2006-07-12 Corinna Vinschen <corinna@vinschen.de> * fhandler_socket.cc (fhandler_socket::getsockname): Return valid result for unbound sockets. 2006-07-11 Corinna Vinschen <corinna@vinschen.de> * fhandler_socket.cc (fhandler_socket::fixup_after_fork): Handle wsock_mtx and wsock_evt on fork, thus handling close_on_exec correctly. (fhandler_socket::fixup_after_exec): Drop misguided attempt to handle close_on_exec here. (fhandler_socket::dup): Call fixup_after_fork with NULL parent. Add comment. (fhandler_socket::set_close_on_exec): Handle wsock_mtx and wsock_evt. 2006-07-10 Corinna Vinschen <corinna@vinschen.de> * fhandler.h (class fhandler_socket): Add wsock_mtx, wsock_evt and wsock_events members. Remove closed status flag, add listener status flag. Accomodate new implementation of socket event handling methods. Declare recv* and send* functions ssize_t as the POSIX equivalents. (fhandler_socket::recv_internal): Declare. (fhandler_socket::send_internal): Ditto. * fhandler_socket.cc (EVENT_MASK): Define mask of selected events. (fhandler_socket::fhandler_socket): Initialize new members. (fhandler_socket::af_local_setblocking): Don't actually set the socket to blocking mode. Keep sane event selection. (fhandler_socket::af_local_unsetblocking): Don't actually set the socket to previous blocking setting, just remember it. (struct wsa_event): New structure to keep event data per shared socket. (NUM_SOCKS): Define number of shared sockets concurrently handled by all active Cygwin processes. (wsa_events): New shared datastructure keeping all wsa_event records. (socket_serial_number): New shared variable to identify shared sockets. (wsa_slot_mtx): Global mutex to serialize wsa_events access. (search_wsa_event_slot): New static function to select a new wsa_event slot for a new socket. (fhandler_socket::prepare): Rewrite. Prepare event selection per new socket. (fhandler_socket::wait): Rewrite. Wait for socket events in thread safe and multiple process safe. (fhandler_socket::release): Rewrite. Close per-socket descriptor mutex handle and event handle. (fhandler_socket::dup): Duplicate wsock_mtx and wsock_evt. Fix copy-paste error in debug output. (fhandler_socket::connect): Accomodate new event handling. (fhandler_socket::listen): Set listener flag on successful listen. (fhandler_socket::accept): Accomodate new event handling. (fhandler_socket::recv_internal): New inline method centralizing common recv code. (fhandler_socket::recvfrom): Call recv_internal now. (fhandler_socket::recvmsg): Ditto. Streamline copying from iovec to WSABUF. (fhandler_socket::send_internal): New inline method centralizing common send code. (fhandler_socket::sendto): Call send_internal now. (fhandler_socket::sendmsg): Ditto. Streamline copying from iovec to WSABUF. (fhandler_socket::close): Call release now. (fhandler_socket::ioctl): Never actually switch to blocking mode. Just keep track of the setting. * net.cc (fdsock): Call prepare now. (cygwin_connect): Revert again to event driven technique. (cygwin_accept): Ditto. * poll.cc (poll): Don't call recvfrom on a listening socket. Remove special case for failing recvfrom. * include/sys/socket.h: Declare recv* and send* functions ssize_t as requested by POSIX. 2006-07-07 Corinna Vinschen <corinna@vinschen.de> * net.cc (cygwin_inet_ntop): Fix data type of forth parameter. 2006-07-06 Corinna Vinschen <corinna@vinschen.de> * include/cygwin/in6.h (struct in6_addr): Fix typo. 2006-07-06 Corinna Vinschen <corinna@vinschen.de> * cygwin.din: Export in6addr_any, in6addr_loopback, freeaddrinfo, gai_strerror, getaddrinfo, getnameinfo. * fhandler_socket.cc: Include cygwin/in6.h. (get_inet_addr): Accomodate AF_INET6 usage. (fhandler_socket::connect): Ditto. (fhandler_socket::listen): Ditto. (fhandler_socket::sendto): Ditto. * net.cc: Include cygwin/in6.h. (in6addr_any): Define. (in6addr_loopback): Define. (cygwin_socket): Accomodate AF_INET6 usage. (socketpair): Bind socketpairs only to loopback for security. (inet_pton4): New static function. (inet_pton6): Ditto. (cygwin_inet_pton): New AF_INET6 aware inet_pton implementation. (inet_ntop4): New static function. (inet_ntop6): Ditto. (cygwin_inet_ntop): New AF_INET6 aware inet_ntop implementation. (ga_aistruct): New static function. (ga_clone): Ditto. (ga_echeck): Ditto. (ga_nsearch): Ditto. (ga_port): Ditto. (ga_serv): Ditto. (ga_unix): Ditto. (gn_ipv46): Ditto. (ipv4_freeaddrinfo): Ditto. (ipv4_getaddrinfo): Ditto. (ipv4_getnameinfo): Ditto. (gai_errmap_t): New structure holding error code - error string mapping. (cygwin_gai_strerror): New function implementing gai_strerror. (w32_to_gai_err): New static function. (get_ipv6_funcs): Ditto. (load_ipv6_funcs): Ditto. (cygwin_freeaddrinfo): New function implementing freeaddrinfo. (cygwin_getaddrinfo): New function implementing getaddrinfo. (cygwin_getnameinfo): New function implementing getnameinfo. * include/netdb.h: Include stdint.h and cygwin/socket.h. Define data types and macros used by getaddrinfo and friends. Declare freeaddrinfo, gai_strerror, getaddrinfo and getnameinfo. * include/cygwin/in.h: Add IPv6 related IPPROTOs. Remove definition of struct sockaddr_in6. Include cygwin/in6.h instead. * include/cygwin/in6.h: New header file defining IPv6 releated data types and macros. * include/cygwin/socket.h: Enable AF_INET6 and PF_INET6. Add IPv6 related socket options. * include/cygwin/version.h: Bump API minor number. 2006-07-06 Corinna Vinschen <corinna@vinschen.de> * autoload.cc (DsGetDcNameA): Define. (NetGetAnyDCName): Define. * security.cc: Include dsgetdc.h. (DsGetDcNameA): Declare. (DS_FORCE_REDISCOVERY): Define. (get_logon_server): Add bool parameter to control rediscovery of DC. Use DsGetDcNameA function if supported, NetGetDCName/NetGetAnyDCName otherwise. (get_server_groups): Rediscover DC if get_user_groups fails and try again. (get_reg_security): Use correct error code macro when testing RegGetKeySecurity return value. * security.h (get_logon_server): Remove default vaue from wserver parameter. Add rediscovery parameter. * uinfo.cc (cygheap_user::env_logsrv): Accomodate rediscovery parameter in call to get_logon_server.
This commit is contained in:
		| @@ -1,7 +1,75 @@ | ||||
| 2006-07-25  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/cygwin/version.h: Bump DLL version to 1.7.0. | ||||
|  | ||||
| 2006-07-25  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* select.h: Remove. | ||||
| 	* fhandler_socket.cc: Don't include select.h. | ||||
| 	* select.cc: Ditto. | ||||
|  | ||||
| 2006-07-25  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* cygtls.h: Drop socket related includes. | ||||
| 	(struct _local_storage): Remove exitsock and exitsock_sin. Add | ||||
| 	select_sockevt. | ||||
| 	* cygtls.cc: Accomodate above change throughout. | ||||
| 	* fhandler.h (class fhandler_socket): Make wsock_evt public. | ||||
| 	* fhandler_socket.cc (fhandler_socket::fhandler_socket): Accomodate | ||||
| 	reordering members. | ||||
| 	(fhandler_socket::evaluate_events): Drop FD_CONNECT event as soon as | ||||
| 	it gets read once.  Never remove FD_WRITE event here. | ||||
| 	(fhandler_socket::wait_for_events): Wait 50 ms instead of INFINITE for | ||||
| 	socket events. | ||||
| 	(fhandler_socket::accept): Fix conditional.  Set wsock_events members | ||||
| 	of accepted socket to useful start values. | ||||
| 	(fhandler_socket::recv_internal): Always drop FD_READ/FD_OOB events from | ||||
| 	wsock_events after the call to WSARecvFrom. | ||||
| 	(fhandler_socket::send_internal): Drop FD_WRITE event from wsock_events | ||||
| 	if the call to WSASendTo fails with WSAEWOULDBLOCK.  Fix return value | ||||
| 	condition. | ||||
| 	* select.cc (struct socketinf): Change to accomodate using socket event | ||||
| 	handling. | ||||
| 	(peek_socket): Use event handling for peeking socket. | ||||
| 	(thread_socket): Ditto. | ||||
| 	(start_thread_socket): Ditto. | ||||
| 	(socket_cleanup): Same here. | ||||
| 	* tlsoffsets.h: Regenerate. | ||||
|  | ||||
| 2006-07-23  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* include/cygwin/version.h: Bump DLL minor version number to 22. | ||||
|  | ||||
| 2006-07-20  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler.h (class fhandler_socket): Rearrange slightly to keep | ||||
| 	event handling methods and members together.  Drop owner status flag. | ||||
| 	Split wait method.  Rename event handling methods for readability. | ||||
| 	* fhandler_socket.cc (struct wsa_event): Add owner field. | ||||
| 	(LOCK_EVENTS): New macro. | ||||
| 	(UNLOCK_EVENTS): Ditto. | ||||
| 	(fhandler_socket::init_events): rename from prepare. | ||||
| 	(fhandler_socket::evaluate_events): First half of former wait method. | ||||
| 	Do everything but wait.  Allow specifiying whether or not events from | ||||
| 	event_mask should be erased from wsock_events->events.  Simplify | ||||
| 	OOB handling.  Allow sending SIGURG to any process (group). | ||||
| 	(fhandler_socket::wait_for_events): Second half of former wait method. | ||||
| 	Call evaluate_events and wait in a loop if socket is blocking. | ||||
| 	(fhandler_socket::release_events): Rename from release. | ||||
| 	(fhandler_socket::connect): Accomodate above name changes. | ||||
| 	(fhandler_socket::accept): Ditto. | ||||
| 	(fhandler_socket::recv_internal): Ditto. | ||||
| 	(fhandler_socket::send_internal): Ditto. | ||||
| 	(fhandler_socket::close): Ditto. | ||||
| 	(fhandler_socket::fcntl): Always set owner to given input value on | ||||
| 	F_SETOWN.  Handle F_GETOWN. | ||||
| 	* net.cc (fdsock): Accomodate above name changes. | ||||
|  | ||||
| 2006-07-20  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_socket.cc (fhandler_socket::wait): Set Winsock errno to | ||||
| 	WSAEWOULDBLOCK instead of WSAEINPROGRESS. | ||||
|  | ||||
| 2006-07-19  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* pinfo.cc (commune_process): Don't add extra \0 to cmdline. | ||||
| @@ -26,11 +94,32 @@ | ||||
| 	* sec_acl.cc (acltotext32): Add missing handling of default ACL entry | ||||
| 	types. | ||||
|  | ||||
| 2006-07-18  Brian Ford  <Brian.Ford@FlightSafety.com> | ||||
| 	    Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* winsup.h (mmap_region_status): New enum. | ||||
| 	(mmap_is_attached_or_noreserve_page): Adjust prototype and rename | ||||
| 	as below. | ||||
| 	* mmap.cc (mmap_is_attached_or_noreserve_page):  Rename | ||||
| 	mmap_is_attached_or_noreserve.  Add region length parameter. | ||||
| 	Return enum above. | ||||
| 	* exceptions.cc (_cygtls::handle_exceptions): Accomodate above. | ||||
| 	* fhandler.cc (fhandler_base::raw_read): Call above for NOACCESS | ||||
| 	errors and retry on success to allow reads into untouched | ||||
| 	MAP_NORESERVE buffers. | ||||
|  | ||||
| 2006-07-18  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_floppy.cc (fhandler_dev_floppy::ioctl): Fix typo in lint | ||||
| 	directive. | ||||
|  | ||||
| 2006-07-18  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* cygwin.din (posix_openpt): Export. | ||||
| 	* tty.cc (posix_openpt): New function. | ||||
| 	* include/cygwin/stdlib.h (posix_openpt): Declare. | ||||
| 	* include/cygwin/version.h: Bump API minor number. | ||||
|  | ||||
| 2006-07-17  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	GCC 4.1 fixes. | ||||
| @@ -69,6 +158,19 @@ | ||||
| 	* dllfixdbg: Accommodate newer binutils which put the gnu_debuglink at | ||||
| 	the end rather than at the beginning. | ||||
|  | ||||
| 2006-07-14  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* security.cc (get_token_group_sidlist): Always add the interactive | ||||
| 	group to the token.  Add comment.  Create logon_id group SID by | ||||
| 	copying it from incoming group list. | ||||
| 	(create_token): Add subauth_token parameter.  Use information in | ||||
| 	subauth_token if present.  Tweak SourceIdentifier if subauth_token | ||||
| 	is present for debugging purposes. | ||||
| 	* security.h (create_token): Add subauth_token parameter in declaration. | ||||
| 	* syscalls.cc (seteuid32): Call subauth first.  Call create_token | ||||
| 	regardless.  Use subauth token in call to create_token if subauth | ||||
| 	succeeded. | ||||
|  | ||||
| 2006-07-13  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* sigproc.cc (waitq_head): Don't initialize to zero. | ||||
| @@ -81,11 +183,20 @@ | ||||
|  | ||||
| 	* sigproc.cc: Use "Static" where appropriate. | ||||
|  | ||||
| 2006-07-13  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/netinet/in.h: Update copyright. | ||||
|  | ||||
| 2006-07-13  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_socket.cc: Update copyright. | ||||
| 	* include/pthread.h: Ditto. | ||||
|  | ||||
| 2006-07-13  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_socket.cc (fhandler_socket::wait): Rework function so that | ||||
| 	WaitForMultipleObjects is really only called when necessary. | ||||
|  | ||||
| 2006-07-13  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* mmap.cc (mmap64): Drop MAP_NORESERVE flag for non-anonymous, | ||||
| @@ -116,11 +227,104 @@ | ||||
| 	* mmap.cc (mmap_record::alloc_page_map): Don't call VirtualProtect | ||||
| 	on maps created with MAP_NORESERVE. | ||||
|  | ||||
| 2006-07-12  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/netdb.h: Declare rcmd, rcmd_af, rexec, rresvport, | ||||
| 	rresvport_af, iruserok, iruserok_sa, ruserok. | ||||
|  | ||||
| 2006-07-12  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* Makefile.in (DLL_OFILES): Drop iruserok.o.  Add rcmd.o. | ||||
| 	* autoload.cc (rcmd): Drop definition. | ||||
| 	* cygwin.din: Export bindresvport, bindresvport_sa, iruserok_sa, | ||||
| 	rcmd_af, rresvport_af. | ||||
| 	* net.cc (cygwin_rcmd): Remove. | ||||
| 	(last_used_bindresvport): Rename from last_used_rrecvport. | ||||
| 	(cygwin_bindresvport_sa): New function implementing bindresvport_sa. | ||||
| 	(cygwin_bindresvport): New function implementing bindresvport. | ||||
| 	(cygwin_rresvport): Remove. | ||||
| 	* include/cygwin/version.h: Bump API minor number. | ||||
| 	* include/netinet/in.h: Declare bindresvport and bindresvport_sa. | ||||
| 	* libc/iruserok.c: Remove file. | ||||
| 	* libc/rcmd.cc: New file implementing rcmd, rcmd_af, rresvport, | ||||
| 	rresvport_af, iruserok_sa, iruserok and ruserok. | ||||
|  | ||||
| 2006-07-12  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/pthread.h: Define PTHREAD_PRIO_NONE, PTHREAD_PRIO_INHERIT and | ||||
| 	PTHREAD_PRIO_PROTECT only if _POSIX_THREAD_PRIO_INHERIT is defined. | ||||
|  | ||||
| 2006-07-12  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_socket.cc (fhandler_socket::getsockname): Return valid | ||||
| 	result for unbound sockets. | ||||
|  | ||||
| 2006-07-11  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler_socket.cc (fhandler_socket::fixup_after_fork): Handle | ||||
| 	wsock_mtx and wsock_evt on fork, thus handling close_on_exec correctly. | ||||
| 	(fhandler_socket::fixup_after_exec): Drop misguided attempt to handle | ||||
| 	close_on_exec here. | ||||
| 	(fhandler_socket::dup): Call fixup_after_fork with NULL parent. | ||||
| 	Add comment. | ||||
| 	(fhandler_socket::set_close_on_exec): Handle wsock_mtx and wsock_evt. | ||||
|  | ||||
| 2006-07-10  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* fhandler.h (class fhandler_socket): Add wsock_mtx, wsock_evt | ||||
| 	and wsock_events members.  Remove closed status flag, add listener | ||||
| 	status flag.  Accomodate new implementation of socket event handling | ||||
| 	methods.  Declare recv* and send* functions ssize_t as the POSIX | ||||
| 	equivalents. | ||||
| 	(fhandler_socket::recv_internal): Declare. | ||||
| 	(fhandler_socket::send_internal): Ditto. | ||||
| 	* fhandler_socket.cc (EVENT_MASK): Define mask of selected events. | ||||
| 	(fhandler_socket::fhandler_socket): Initialize new members. | ||||
| 	(fhandler_socket::af_local_setblocking): Don't actually set the | ||||
| 	socket to blocking mode.  Keep sane event selection. | ||||
| 	(fhandler_socket::af_local_unsetblocking): Don't actually set the | ||||
| 	socket to previous blocking setting, just remember it. | ||||
| 	(struct wsa_event): New structure to keep event data per shared | ||||
| 	socket. | ||||
| 	(NUM_SOCKS): Define number of shared sockets concurrently handled by | ||||
| 	all active Cygwin processes. | ||||
| 	(wsa_events): New shared datastructure keeping all wsa_event records. | ||||
| 	(socket_serial_number): New shared variable to identify shared sockets. | ||||
| 	(wsa_slot_mtx): Global mutex to serialize wsa_events access. | ||||
| 	(search_wsa_event_slot): New static function to select a new wsa_event | ||||
| 	slot for a new socket. | ||||
| 	(fhandler_socket::prepare): Rewrite.  Prepare event selection | ||||
| 	per new socket. | ||||
| 	(fhandler_socket::wait): Rewrite.  Wait for socket events in thread | ||||
| 	safe and multiple process safe. | ||||
| 	(fhandler_socket::release): Rewrite.  Close per-socket descriptor | ||||
| 	mutex handle and event handle. | ||||
| 	(fhandler_socket::dup): Duplicate wsock_mtx and wsock_evt.  Fix | ||||
| 	copy-paste error in debug output. | ||||
| 	(fhandler_socket::connect): Accomodate new event handling. | ||||
| 	(fhandler_socket::listen): Set listener flag on successful listen. | ||||
| 	(fhandler_socket::accept): Accomodate new event handling. | ||||
| 	(fhandler_socket::recv_internal): New inline method centralizing | ||||
| 	common recv code. | ||||
| 	(fhandler_socket::recvfrom): Call recv_internal now. | ||||
| 	(fhandler_socket::recvmsg): Ditto.  Streamline copying from iovec | ||||
| 	to WSABUF. | ||||
| 	(fhandler_socket::send_internal): New inline method centralizing | ||||
| 	common send code. | ||||
| 	(fhandler_socket::sendto): Call send_internal now. | ||||
| 	(fhandler_socket::sendmsg): Ditto.  Streamline copying from iovec | ||||
| 	to WSABUF. | ||||
| 	(fhandler_socket::close): Call release now. | ||||
| 	(fhandler_socket::ioctl): Never actually switch to blocking mode. | ||||
| 	Just keep track of the setting. | ||||
| 	* net.cc (fdsock): Call prepare now. | ||||
| 	(cygwin_connect): Revert again to event driven technique. | ||||
| 	(cygwin_accept): Ditto. | ||||
| 	* poll.cc (poll): Don't call recvfrom on a listening socket. | ||||
| 	Remove special case for failing recvfrom. | ||||
| 	* include/sys/socket.h: Declare recv* and send* functions ssize_t as  | ||||
| 	requested by POSIX. | ||||
|  | ||||
| 2006-07-10  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* libc/inet_addr.c: Define __INSIDE_CYGWIN_NET__. | ||||
| @@ -131,6 +335,10 @@ | ||||
| 	* fhandler_socket.cc (fhandler_socket::wait): Disable SA_RESTART | ||||
| 	handling for now. | ||||
|  | ||||
| 2006-07-07  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* net.cc (cygwin_inet_ntop): Fix data type of forth parameter. | ||||
|  | ||||
| 2006-07-07  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* Makefile.in (DLL_OFILES): Add inet_addr.o and inet_network.o. | ||||
| @@ -156,6 +364,79 @@ | ||||
| 	* child_info.h: Update copyright. | ||||
| 	* fork.cc: Ditto. | ||||
|  | ||||
| 2006-07-06  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* include/cygwin/in6.h (struct in6_addr): Fix typo. | ||||
|  | ||||
| 2006-07-06  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* cygwin.din: Export in6addr_any, in6addr_loopback, freeaddrinfo, | ||||
| 	gai_strerror, getaddrinfo, getnameinfo. | ||||
| 	* fhandler_socket.cc: Include cygwin/in6.h. | ||||
| 	(get_inet_addr): Accomodate AF_INET6 usage. | ||||
| 	(fhandler_socket::connect): Ditto. | ||||
| 	(fhandler_socket::listen): Ditto. | ||||
| 	(fhandler_socket::sendto): Ditto. | ||||
| 	* net.cc: Include cygwin/in6.h. | ||||
| 	(in6addr_any): Define. | ||||
| 	(in6addr_loopback): Define. | ||||
| 	(cygwin_socket): Accomodate AF_INET6 usage. | ||||
| 	(socketpair): Bind socketpairs only to loopback for security. | ||||
| 	(inet_pton4): New static function. | ||||
| 	(inet_pton6): Ditto. | ||||
| 	(cygwin_inet_pton): New AF_INET6 aware inet_pton implementation. | ||||
| 	(inet_ntop4): New static function. | ||||
| 	(inet_ntop6): Ditto. | ||||
| 	(cygwin_inet_ntop): New AF_INET6 aware inet_ntop implementation. | ||||
| 	(ga_aistruct): New static function. | ||||
| 	(ga_clone): Ditto. | ||||
| 	(ga_echeck): Ditto. | ||||
| 	(ga_nsearch): Ditto. | ||||
| 	(ga_port): Ditto. | ||||
| 	(ga_serv): Ditto. | ||||
| 	(ga_unix): Ditto. | ||||
| 	(gn_ipv46): Ditto. | ||||
| 	(ipv4_freeaddrinfo): Ditto. | ||||
| 	(ipv4_getaddrinfo): Ditto. | ||||
| 	(ipv4_getnameinfo): Ditto. | ||||
| 	(gai_errmap_t): New structure holding error code - error string mapping. | ||||
| 	(cygwin_gai_strerror): New function implementing gai_strerror. | ||||
| 	(w32_to_gai_err): New static function. | ||||
| 	(get_ipv6_funcs): Ditto. | ||||
| 	(load_ipv6_funcs): Ditto. | ||||
| 	(cygwin_freeaddrinfo): New function implementing freeaddrinfo. | ||||
| 	(cygwin_getaddrinfo): New function implementing getaddrinfo. | ||||
| 	(cygwin_getnameinfo): New function implementing getnameinfo. | ||||
| 	* include/netdb.h: Include stdint.h and cygwin/socket.h.  Define | ||||
| 	data types and macros used by getaddrinfo and friends.  Declare | ||||
| 	freeaddrinfo, gai_strerror, getaddrinfo and getnameinfo. | ||||
| 	* include/cygwin/in.h: Add IPv6 related IPPROTOs. Remove definition | ||||
| 	of struct sockaddr_in6.  Include cygwin/in6.h instead. | ||||
| 	* include/cygwin/in6.h: New header file defining IPv6 releated | ||||
| 	data types and macros. | ||||
| 	* include/cygwin/socket.h: Enable AF_INET6 and PF_INET6.  Add | ||||
| 	IPv6 related socket options. | ||||
| 	* include/cygwin/version.h: Bump API minor number. | ||||
|  | ||||
| 2006-07-06  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* autoload.cc (DsGetDcNameA): Define. | ||||
| 	(NetGetAnyDCName): Define. | ||||
| 	* security.cc: Include dsgetdc.h. | ||||
| 	(DsGetDcNameA): Declare. | ||||
| 	(DS_FORCE_REDISCOVERY): Define. | ||||
| 	(get_logon_server): Add bool parameter to control rediscovery of DC. | ||||
| 	Use DsGetDcNameA function if supported, NetGetDCName/NetGetAnyDCName | ||||
| 	otherwise. | ||||
| 	(get_server_groups): Rediscover DC if get_user_groups fails and | ||||
| 	try again. | ||||
| 	(get_reg_security): Use correct error code macro when testing | ||||
| 	RegGetKeySecurity return value. | ||||
| 	* security.h (get_logon_server): Remove default vaue from wserver | ||||
| 	parameter.  Add rediscovery parameter. | ||||
| 	* uinfo.cc (cygheap_user::env_logsrv): Accomodate rediscovery parameter | ||||
| 	in call to get_logon_server. | ||||
|  | ||||
| 2006-07-05  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* sortdin: Ignore all leading underscores when deriving a sort key. | ||||
|   | ||||
| @@ -133,11 +133,11 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ | ||||
| 	fhandler_serial.o fhandler_socket.o fhandler_tape.o fhandler_termios.o \ | ||||
| 	fhandler_tty.o fhandler_virtual.o fhandler_windows.o fhandler_zero.o \ | ||||
| 	flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o grp.o heap.o \ | ||||
| 	hookapi.o inet_addr.o inet_network.o init.o ioctl.o ipc.o iruserok.o \ | ||||
| 	localtime.o lsearch.o malloc_wrapper.o memmem.o miscfuncs.o mktemp.o \ | ||||
| 	mmap.o msg.o net.o netdb.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o \ | ||||
| 	poll.o pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o \ | ||||
| 	resource.o rexec.o scandir.o sched.o sec_acl.o sec_helper.o security.o \ | ||||
| 	hookapi.o inet_addr.o inet_network.o init.o ioctl.o ipc.o localtime.o \ | ||||
| 	lsearch.o malloc_wrapper.o memmem.o miscfuncs.o mktemp.o mmap.o msg.o \ | ||||
| 	net.o netdb.o nftw.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o \ | ||||
| 	pthread.o regcomp.o regerror.o regexec.o regfree.o registry.o resource.o \ | ||||
| 	rexec.o rcmd.o scandir.o sched.o sec_acl.o sec_helper.o security.o \ | ||||
| 	select.o sem.o shared.o shm.o sigfe.o signal.o sigproc.o smallprint.o \ | ||||
| 	spawn.o strace.o strptime.o strsep.o strsig.o sync.o syscalls.o \ | ||||
| 	sysconf.o syslog.o termios.o thread.o timelocal.o timer.o times.o tty.o \ | ||||
|   | ||||
| @@ -370,7 +370,10 @@ LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32) | ||||
| LoadDLLfunc (SetTokenInformation, 16, advapi32) | ||||
| LoadDLLfunc (RegGetKeySecurity, 16, advapi32) | ||||
|  | ||||
| /* 127 == ERROR_PROC_NOT_FOUND */ | ||||
| LoadDLLfuncEx2 (DsGetDcNameA, 24, netapi32, 1, 127) | ||||
| LoadDLLfunc (NetApiBufferFree, 4, netapi32) | ||||
| LoadDLLfuncEx (NetGetAnyDCName, 12, netapi32, 1) | ||||
| LoadDLLfuncEx (NetGetDCName, 12, netapi32, 1) | ||||
| LoadDLLfunc (NetLocalGroupEnum, 28, netapi32) | ||||
| LoadDLLfunc (NetLocalGroupGetMembers, 32, netapi32) | ||||
| @@ -456,8 +459,6 @@ LoadDLLfunc (SetProcessWindowStation, 4, user32) | ||||
| LoadDLLfunc (SetTimer, 16, user32) | ||||
| LoadDLLfunc (SetUserObjectSecurity, 12, user32) | ||||
|  | ||||
| LoadDLLfunc (rcmd, 24, wsock32) | ||||
|  | ||||
| LoadDLLfunc (accept, 12, ws2_32) | ||||
| LoadDLLfunc (bind, 12, ws2_32) | ||||
| LoadDLLfunc (closesocket, 4, ws2_32) | ||||
|   | ||||
| @@ -106,7 +106,7 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) | ||||
|  | ||||
|   thread_id = GetCurrentThreadId (); | ||||
|   initialized = CYGTLS_INITIALIZED; | ||||
|   locals.exitsock = INVALID_SOCKET; | ||||
|   locals.select_sockevt = INVALID_HANDLE_VALUE; | ||||
|   errno_addr = &(local_clib._errno); | ||||
|  | ||||
|   if ((void *) func == (void *) cygthread::stub | ||||
| @@ -137,7 +137,7 @@ _cygtls::fixup_after_fork () | ||||
|       sig = 0; | ||||
|     } | ||||
|   stacklock = spinning = 0; | ||||
|   locals.exitsock = INVALID_SOCKET; | ||||
|   locals.select_sockevt = INVALID_HANDLE_VALUE; | ||||
|   wq.thread_ev = NULL; | ||||
| } | ||||
|  | ||||
| @@ -152,7 +152,7 @@ void | ||||
| _cygtls::remove (DWORD wait) | ||||
| { | ||||
|   initialized = 0; | ||||
|   if (!locals.exitsock || exit_state >= ES_FINAL) | ||||
|   if (!locals.select_sockevt || exit_state >= ES_FINAL) | ||||
|     return; | ||||
|  | ||||
|   debug_printf ("wait %p", wait); | ||||
| @@ -160,10 +160,10 @@ _cygtls::remove (DWORD wait) | ||||
|     { | ||||
|       /* FIXME: Need some sort of atthreadexit function to allow things like | ||||
| 	 select to control this themselves. */ | ||||
|       if (locals.exitsock != INVALID_SOCKET) | ||||
|       if (locals.select_sockevt != INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
| 	  closesocket (locals.exitsock); | ||||
| 	  locals.exitsock = (SOCKET) NULL; | ||||
| 	  CloseHandle (locals.select_sockevt); | ||||
| 	  locals.select_sockevt = (HANDLE) NULL; | ||||
| 	} | ||||
|       free_local (process_ident); | ||||
|       free_local (ntoa_buf); | ||||
|   | ||||
| @@ -18,10 +18,6 @@ details. */ | ||||
| #undef _NOMNTENT_FUNCS | ||||
| #include <setjmp.h> | ||||
| #include <exceptions.h> | ||||
| #ifndef _WINSOCK_H | ||||
| #include <netinet/in.h> | ||||
| typedef unsigned int SOCKET; | ||||
| #endif | ||||
|  | ||||
| #define CYGTLS_INITIALIZED 0xc763173f | ||||
|  | ||||
| @@ -69,8 +65,7 @@ struct _local_storage | ||||
|   char mnt_dir[CYG_MAX_PATH]; | ||||
|  | ||||
|   /* select.cc */ | ||||
|   SOCKET exitsock; | ||||
|   struct sockaddr_in exitsock_sin; | ||||
|   HANDLE select_sockevt; | ||||
|  | ||||
|   /* strerror */ | ||||
|   char strerror_buf[sizeof ("Unknown error 4294967295")]; | ||||
|   | ||||
| @@ -11,6 +11,8 @@ __cygwin_user_data DATA | ||||
| _daylight DATA | ||||
| h_errno DATA | ||||
| _impure_ptr DATA | ||||
| in6addr_any DATA | ||||
| in6addr_loopback DATA | ||||
| __mb_cur_max DATA | ||||
| optarg DATA | ||||
| opterr DATA | ||||
| @@ -145,6 +147,8 @@ _bcmp = bcmp NOSIGFE | ||||
| bcopy NOSIGFE | ||||
| _bcopy = bcopy NOSIGFE | ||||
| bind = cygwin_bind SIGFE | ||||
| bindresvport = cygwin_bindresvport SIGFE | ||||
| bindresvport_sa = cygwin_bindresvport_sa SIGFE | ||||
| bsearch NOSIGFE | ||||
| _bsearch = bsearch NOSIGFE | ||||
| btowc NOSIGFE | ||||
| @@ -471,6 +475,7 @@ fread SIGFE | ||||
| _fread = fread SIGFE | ||||
| free SIGFE | ||||
| _free = free SIGFE | ||||
| freeaddrinfo = cygwin_freeaddrinfo SIGFE | ||||
| freopen SIGFE | ||||
| _freopen = freopen SIGFE | ||||
| _freopen64 = freopen64 SIGFE | ||||
| @@ -524,6 +529,7 @@ funlockfile SIGFE | ||||
| futimes SIGFE | ||||
| fwrite SIGFE | ||||
| _fwrite = fwrite SIGFE | ||||
| gai_strerror = cygwin_gai_strerror NOSIGFE | ||||
| gamma NOSIGFE | ||||
| _gamma = gamma NOSIGFE | ||||
| gamma_r NOSIGFE | ||||
| @@ -538,6 +544,7 @@ gcvtf SIGFE | ||||
| _gcvtf = gcvtf SIGFE | ||||
| get_osfhandle SIGFE | ||||
| _get_osfhandle = get_osfhandle SIGFE | ||||
| getaddrinfo = cygwin_getaddrinfo SIGFE | ||||
| getc SIGFE | ||||
| _getc = getc SIGFE | ||||
| getc_unlocked SIGFE | ||||
| @@ -594,6 +601,7 @@ getmntent SIGFE | ||||
| _getmntent = getmntent SIGFE | ||||
| getmode SIGFE | ||||
| _getmode = getmode SIGFE | ||||
| getnameinfo = cygwin_getnameinfo SIGFE | ||||
| getopt SIGFE | ||||
| getopt_long SIGFE | ||||
| getopt_long_only SIGFE | ||||
| @@ -714,6 +722,7 @@ _ioctl = ioctl SIGFE | ||||
| iprintf SIGFE | ||||
| _iprintf = iprintf SIGFE | ||||
| iruserok SIGFE | ||||
| iruserok_sa SIGFE | ||||
| isalnum NOSIGFE | ||||
| _isalnum = isalnum NOSIGFE | ||||
| isalpha NOSIGFE | ||||
| @@ -967,6 +976,7 @@ poll SIGFE | ||||
| _poll = poll SIGFE | ||||
| popen SIGFE | ||||
| _popen = popen SIGFE | ||||
| posix_openpt SIGFE | ||||
| posix_regcomp SIGFE | ||||
| posix_regerror SIGFE | ||||
| posix_regexec SIGFE | ||||
| @@ -1086,6 +1096,7 @@ _rand = rand NOSIGFE | ||||
| rand_r NOSIGFE | ||||
| random NOSIGFE | ||||
| rcmd = cygwin_rcmd SIGFE | ||||
| rcmd_af = cygwin_rcmd_af SIGFE | ||||
| read SIGFE | ||||
| _read = read SIGFE | ||||
| readdir SIGFE | ||||
| @@ -1128,6 +1139,7 @@ _rmdir = rmdir SIGFE | ||||
| round NOSIGFE | ||||
| roundf NOSIGFE | ||||
| rresvport = cygwin_rresvport SIGFE | ||||
| rresvport_af = cygwin_rresvport_af SIGFE | ||||
| ruserok SIGFE | ||||
| sbrk SIGFE | ||||
| _sbrk = sbrk SIGFE | ||||
|   | ||||
| @@ -526,12 +526,13 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT | ||||
|       break; | ||||
|  | ||||
|     case STATUS_ACCESS_VIOLATION: | ||||
|       switch (mmap_is_attached_or_noreserve_page (e->ExceptionInformation[1])) | ||||
|       switch (mmap_is_attached_or_noreserve ((void *)e->ExceptionInformation[1], | ||||
| 					     1)) | ||||
|         { | ||||
| 	case 2:		/* MAP_NORESERVE page, now commited. */ | ||||
| 	case MMAP_NORESERVE_COMMITED: | ||||
| 	  return 0; | ||||
| 	case 1:		/* MAP_NORESERVE page, commit failed, or | ||||
| 			   access to mmap page beyond EOF. */ | ||||
| 	case MMAP_RAISE_SIGBUS:	/* MAP_NORESERVE page, commit failed, or | ||||
| 				   access to mmap page beyond EOF. */ | ||||
| 	  si.si_signo = SIGBUS; | ||||
| 	  si.si_code = BUS_OBJERR; | ||||
| 	  break; | ||||
|   | ||||
| @@ -223,8 +223,10 @@ fhandler_base::raw_read (void *ptr, size_t& ulen) | ||||
|  | ||||
|   HANDLE h = NULL;	/* grumble */ | ||||
|   int prio = 0;		/* ditto */ | ||||
|   int try_noreserve = 1; | ||||
|   DWORD len = ulen; | ||||
|  | ||||
| retry: | ||||
|   ulen = (size_t) -1; | ||||
|   if (read_state) | ||||
|     { | ||||
| @@ -259,6 +261,20 @@ fhandler_base::raw_read (void *ptr, size_t& ulen) | ||||
| 	      bytes_read = 0; | ||||
| 	      break; | ||||
| 	    } | ||||
| 	  if (try_noreserve) | ||||
| 	    { | ||||
| 	      try_noreserve = 0; | ||||
| 	      switch (mmap_is_attached_or_noreserve (ptr, len)) | ||||
| 		{ | ||||
| 		case MMAP_NORESERVE_COMMITED: | ||||
| 		  goto retry; | ||||
| 		case MMAP_RAISE_SIGBUS: | ||||
| 		  raise(SIGBUS); | ||||
| 		case MMAP_NONE: | ||||
| 		  break; | ||||
| 		} | ||||
| 	    } | ||||
| 	  /*FALLTHRU*/ | ||||
| 	case ERROR_INVALID_FUNCTION: | ||||
| 	case ERROR_INVALID_PARAMETER: | ||||
| 	case ERROR_INVALID_HANDLE: | ||||
|   | ||||
| @@ -378,6 +378,8 @@ class fhandler_mailslot : public fhandler_base | ||||
|   select_record *select_read (select_record *s); | ||||
| }; | ||||
|  | ||||
| struct wsa_event; | ||||
|  | ||||
| class fhandler_socket: public fhandler_base | ||||
| { | ||||
|  private: | ||||
| @@ -385,6 +387,16 @@ class fhandler_socket: public fhandler_base | ||||
|   int type; | ||||
|   int connect_secret[4]; | ||||
|  | ||||
|   wsa_event *wsock_events; | ||||
|   HANDLE wsock_mtx; | ||||
|  public: | ||||
|   HANDLE wsock_evt; | ||||
|   bool init_events (); | ||||
|   int evaluate_events (const long event_mask, long &events, bool erase); | ||||
|  private: | ||||
|   int wait_for_events (const long event_mask); | ||||
|   void release_events (); | ||||
|  | ||||
|   pid_t     sec_pid; | ||||
|   __uid32_t sec_uid; | ||||
|   __gid32_t sec_gid; | ||||
| @@ -414,20 +426,15 @@ class fhandler_socket: public fhandler_base | ||||
|     unsigned saw_shutdown_read     : 1; /* Socket saw a SHUT_RD */ | ||||
|     unsigned saw_shutdown_write    : 1; /* Socket saw a SHUT_WR */ | ||||
|     unsigned saw_reuseaddr         : 1; /* Socket saw SO_REUSEADDR call */ | ||||
|     unsigned closed		   : 1; | ||||
|     unsigned owner		   : 1; | ||||
|     unsigned listener              : 1; /* listen called */ | ||||
|     unsigned connect_state         : 2; | ||||
|    public: | ||||
|     status_flags () : | ||||
|       async_io (0), saw_shutdown_read (0), saw_shutdown_write (0), | ||||
|       closed (0), owner (0), connect_state (unconnected) | ||||
|       listener (0), connect_state (unconnected) | ||||
|       {} | ||||
|   } status; | ||||
|  | ||||
|   bool prepare (HANDLE &event, long event_mask); | ||||
|   int wait (HANDLE event, int flags, DWORD timeout = 10); | ||||
|   void release (HANDLE event); | ||||
|  | ||||
|  public: | ||||
|   fhandler_socket (); | ||||
|   ~fhandler_socket (); | ||||
| @@ -438,8 +445,7 @@ class fhandler_socket: public fhandler_base | ||||
|   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, closed) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, owner) | ||||
|   IMPLEMENT_STATUS_FLAG (bool, listener) | ||||
|   IMPLEMENT_STATUS_FLAG (conn_state, connect_state) | ||||
|  | ||||
|   int bind (const struct sockaddr *name, int namelen); | ||||
| @@ -452,14 +458,19 @@ class fhandler_socket: public fhandler_base | ||||
|  | ||||
|   int open (int flags, mode_t mode = 0); | ||||
|   ssize_t readv (const struct iovec *, int iovcnt, ssize_t tot = -1); | ||||
|   int recvfrom (void *ptr, size_t len, int flags, | ||||
| 		struct sockaddr *from, int *fromlen); | ||||
|   int recvmsg (struct msghdr *msg, int flags, ssize_t tot = -1); | ||||
|   inline ssize_t recv_internal (struct _WSABUF *wsabuf, DWORD wsacnt, | ||||
|   				DWORD flags, | ||||
| 				struct sockaddr *from, int *fromlen); | ||||
|   ssize_t recvfrom (void *ptr, size_t len, int flags, | ||||
| 		    struct sockaddr *from, int *fromlen); | ||||
|   ssize_t recvmsg (struct msghdr *msg, int flags, ssize_t tot = -1); | ||||
|  | ||||
|   ssize_t writev (const struct iovec *, int iovcnt, ssize_t tot = -1); | ||||
|   int sendto (const void *ptr, size_t len, int flags, | ||||
|   inline ssize_t send_internal (struct _WSABUF *wsabuf, DWORD wsacnt, int flags, | ||||
| 				const struct sockaddr *to, int tolen); | ||||
|   ssize_t sendto (const void *ptr, size_t len, int flags, | ||||
| 	      const struct sockaddr *to, int tolen); | ||||
|   int sendmsg (const struct msghdr *msg, int flags, ssize_t tot = -1); | ||||
|   ssize_t sendmsg (const struct msghdr *msg, int flags, ssize_t tot = -1); | ||||
|  | ||||
|   int ioctl (unsigned int cmd, void *); | ||||
|   int fcntl (int cmd, void *); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -28,6 +28,7 @@ typedef uint32_t in_addr_t; | ||||
| enum | ||||
| { | ||||
|   IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/ | ||||
|   IPPROTO_HOPOPTS = 0,		/* IPv6 Hop-by-Hop options		*/ | ||||
|   IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/ | ||||
|   IPPROTO_IGMP = 2,		/* Internet Gateway Management Protocol */ | ||||
|   IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */ | ||||
| @@ -36,12 +37,21 @@ enum | ||||
|   IPPROTO_PUP = 12,		/* PUP protocol				*/ | ||||
|   IPPROTO_UDP = 17,		/* User Datagram Protocol		*/ | ||||
|   IPPROTO_IDP = 22,		/* XNS IDP protocol			*/ | ||||
|   IPPROTO_IPV6 = 41,		/* IPv6 header				*/ | ||||
|   IPPROTO_ROUTING = 43,		/* IPv6 Routing header			*/ | ||||
|   IPPROTO_FRAGMENT = 44,	/* IPv6 fragmentation header		*/ | ||||
|   IPPROTO_ESP = 50,		/* encapsulating security payload	*/ | ||||
|   IPPROTO_AH = 51,		/* authentication header		*/ | ||||
|   IPPROTO_ICMPV6 = 58,		/* ICMPv6				*/ | ||||
|   IPPROTO_NONE = 59,		/* IPv6 no next header			*/ | ||||
|   IPPROTO_DSTOPTS = 60,		/* IPv6 Destination options		*/ | ||||
|   IPPROTO_RAW = 255,		/* Raw IP packets			*/ | ||||
|   IPPROTO_MAX | ||||
| }; | ||||
|  | ||||
| /* Define IPPROTO_xxx values to accomodate SUSv3 */ | ||||
| #define IPPROTO_IP IPPROTO_IP | ||||
| #define IPPROTO_HOPOPTS IPPROTO_HOPOPTS | ||||
| #define IPPROTO_ICMP IPPROTO_ICMP | ||||
| #define IPPROTO_IGMP IPPROTO_IGMP | ||||
| #define IPPROTO_IPIP IPPROTO_IPIP | ||||
| @@ -51,6 +61,14 @@ enum | ||||
| #define IPPROTO_UDP IPPROTO_UDP | ||||
| #define IPPROTO_IDP IPPROTO_IDP | ||||
| #define IPPROTO_RAW IPPROTO_RAW | ||||
| #define IPPROTO_IPV6 IPPROTO_IPV6 | ||||
| #define IPPROTO_ROUTING IPPROTO_ROUTING | ||||
| #define IPPROTO_FRAGMENT IPPROTO_FRAGMENT | ||||
| #define IPPROTO_ESP IPPROTO_ESP | ||||
| #define IPPROTO_AH IPPROTO_AH | ||||
| #define IPPROTO_ICMPV6 IPPROTO_ICMPV6 | ||||
| #define IPPROTO_NONE IPPROTO_NONE | ||||
| #define IPPROTO_DSTOPTS IPPROTO_DSTOPTS | ||||
|  | ||||
| /* Standard well-known ports.  *//* from winsup/include/netinet/in.h */ | ||||
| enum | ||||
| @@ -185,21 +203,7 @@ struct sockaddr_in | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #ifdef USE_IPV6 | ||||
| /* IPv6 definitions as we start to include them. This is just | ||||
|    a beginning dont get excited 8) */ | ||||
| struct in6_addr | ||||
| { | ||||
|   uint8_t 	  s6_addr[16]; | ||||
| }; | ||||
|  | ||||
| struct sockaddr_in6 | ||||
| { | ||||
|   sa_family_t	  sin6_family;		/* AF_INET6 */ | ||||
|   in_port_t	  sin6_port;		/* Port number. */ | ||||
|   uint32_t	  sin6_flowinfo;	/* Traffic class and flow inf. */ | ||||
|   struct in6_addr sin6_addr;		/* IPv6 address. */ | ||||
|   uint32_t	  sin6_scope_id;	/* Set of interfaces for a scope. */ | ||||
| }; | ||||
| #ifdef AF_INET6 | ||||
| #include <cygwin/in6.h> | ||||
| #endif | ||||
| #endif	/* _CYGWIN_IN_H */ | ||||
|   | ||||
							
								
								
									
										119
									
								
								winsup/cygwin/include/cygwin/in6.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								winsup/cygwin/include/cygwin/in6.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| /* cygwin/in6.h | ||||
|  | ||||
|    Copyright 2006 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. */ | ||||
|  | ||||
| /* NOTE:  This file is NOT for direct inclusion.  Use netinet/in.h. */ | ||||
|  | ||||
| #ifndef _CYGWIN_IN6_H | ||||
| #define _CYGWIN_IN6_H | ||||
|  | ||||
| #define INET6_ADDRSTRLEN 46 | ||||
|  | ||||
| #define IN6_ARE_ADDR_EQUAL(a, b) \ | ||||
| 	(((const uint32_t *)(a))[0] == ((const uint32_t *)(b))[0] \ | ||||
| 	 && ((const uint32_t *)(a))[1] == ((const uint32_t *)(b))[1] \ | ||||
| 	 && ((const uint32_t *)(a))[2] == ((const uint32_t *)(b))[2] \ | ||||
| 	 && ((const uint32_t *)(a))[3] == ((const uint32_t *)(b))[3]) | ||||
|  | ||||
| #define IN6_IS_ADDR_UNSPECIFIED(addr) \ | ||||
| 	(((const uint32_t *)(addr))[0] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[1] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[2] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[3] == 0) | ||||
|  | ||||
| #define IN6_IS_ADDR_LOOPBACK(addr) \ | ||||
| 	(((const uint32_t *)(addr))[0] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[1] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[2] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[3] == htonl (1)) | ||||
|  | ||||
| #define IN6_IS_ADDR_MULTICAST(addr) (((const uint8_t *) (addr))[0] == 0xff) | ||||
|  | ||||
| #define IN6_IS_ADDR_LINKLOCAL(addr) \ | ||||
| 	((((const uint16_t *)(addr))[0] & htons (0xffc0)) == htons (0xfe80)) | ||||
|  | ||||
| #define IN6_IS_ADDR_SITELOCAL(addr) \ | ||||
| 	((((const uint16_t *)(addr))[0] & htons (0xffc0)) == htons (0xfec0)) | ||||
|  | ||||
| #define IN6_IS_ADDR_V4MAPPED(addr) \ | ||||
| 	(((const uint32_t *)(addr))[0] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[1] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[2] == htonl (0xffff)) | ||||
|  | ||||
| #define IN6_IS_ADDR_V4COMPAT(addr) \ | ||||
| 	(((const uint32_t *)(addr))[0] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[1] == 0 \ | ||||
| 	 && ((const uint32_t *)(addr))[2] == 0 \ | ||||
| 	 && ntohl (((const uint32_t *)(addr))[3]) > 1) | ||||
|  | ||||
| #define IN6_IS_ADDR_MC_NODELOCAL(addr) \ | ||||
| 	(IN6_IS_ADDR_MULTICAST(addr) \ | ||||
| 	 && (((const uint8_t *)(addr))[1] & 0xf) == 0x1) | ||||
|  | ||||
| #define IN6_IS_ADDR_MC_LINKLOCAL(addr) \ | ||||
| 	(IN6_IS_ADDR_MULTICAST (addr) \ | ||||
| 	 && (((const uint8_t *)(addr))[1] & 0xf) == 0x2) | ||||
|  | ||||
| #define IN6_IS_ADDR_MC_SITELOCAL(addr) \ | ||||
| 	(IN6_IS_ADDR_MULTICAST(addr) \ | ||||
| 	 && (((const uint8_t *)(addr))[1] & 0xf) == 0x5) | ||||
|  | ||||
| #define IN6_IS_ADDR_MC_ORGLOCAL(addr) \ | ||||
| 	(IN6_IS_ADDR_MULTICAST(addr) \ | ||||
| 	 && (((const uint8_t *)(addr))[1] & 0xf) == 0x8) | ||||
|  | ||||
| #define IN6_IS_ADDR_MC_GLOBAL(addr) \ | ||||
| 	(IN6_IS_ADDR_MULTICAST(addr) \ | ||||
| 	 && (((const uint8_t *)(addr))[1] & 0xf) == 0xe) | ||||
|  | ||||
| struct in6_addr | ||||
| { | ||||
|   union | ||||
|     { | ||||
|       uint8_t 	  __s6_addr[16]; | ||||
|       uint16_t 	  __s6_addr16[8]; | ||||
|       uint32_t 	  __s6_addr32[4]; | ||||
|     } __u6; | ||||
| #define s6_addr		__u6.__s6_addr | ||||
| #define s6_addr16	__u6.__s6_addr16 | ||||
| #define s6_addr32	__u6.__s6_addr32 | ||||
| }; | ||||
|  | ||||
| struct ipv6_mreq | ||||
| { | ||||
|   struct in6_addr ipv6mr_multiaddr; | ||||
|   unsigned int    ipv6mr_interface; | ||||
| }; | ||||
|  | ||||
| struct in6_pktinfo | ||||
| { | ||||
|   struct in6_addr ipi6_addr; | ||||
|   unsigned int    ipi6_ifindex; | ||||
| }; | ||||
|  | ||||
| #ifdef __INSIDE_CYGWIN__ | ||||
| typedef uint16_t in_port_t; | ||||
| #endif | ||||
|  | ||||
| struct sockaddr_in6 | ||||
| { | ||||
|   sa_family_t	  sin6_family;		/* AF_INET6 */ | ||||
|   in_port_t	  sin6_port;		/* Port number. */ | ||||
|   uint32_t	  sin6_flowinfo;	/* Traffic class and flow inf. */ | ||||
|   struct in6_addr sin6_addr;		/* IPv6 address. */ | ||||
|   uint32_t	  sin6_scope_id;	/* Set of interfaces for a scope. */ | ||||
| }; | ||||
|  | ||||
| #define IN6ADDR_ANY_INIT	{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } | ||||
| #define IN6ADDR_LOOPBACK_INIT	{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } | ||||
|  | ||||
| extern const struct in6_addr in6addr_any; | ||||
| extern const struct in6_addr in6addr_loopback; | ||||
|  | ||||
| #endif	/* _CYGWIN_IN6_H */ | ||||
| @@ -152,9 +152,7 @@ struct OLD_msghdr | ||||
| #define AF_HYLINK       15              /* NSC Hyperchannel */ | ||||
| #define AF_APPLETALK    16              /* AppleTalk */ | ||||
| #define AF_NETBIOS      17              /* NetBios-style addresses */ | ||||
| #if 0					/* Not yet */ | ||||
| #define AF_INET6        23              /* IP version 6 */ | ||||
| #endif | ||||
|  | ||||
| #define AF_MAX          32 | ||||
| /* | ||||
| @@ -180,9 +178,7 @@ struct OLD_msghdr | ||||
| #define PF_HYLINK       AF_HYLINK | ||||
| #define PF_APPLETALK    AF_APPLETALK | ||||
| #define PF_NETBIOS      AF_NETBIOS | ||||
| #if 0 | ||||
| #define PF_INET6        AF_INET6 | ||||
| #endif | ||||
|  | ||||
| #define PF_MAX          AF_MAX | ||||
|  | ||||
| @@ -236,6 +232,17 @@ struct OLD_msghdr | ||||
| #define IP_UNBLOCK_SOURCE               18 | ||||
| #define IP_PKTINFO                      19 | ||||
|  | ||||
| /* IPv6 options for use with getsockopt/setsockopt */ | ||||
| #define IPV6_UNICAST_HOPS                4 | ||||
| #define IPV6_MULTICAST_IF                9 | ||||
| #define IPV6_MULTICAST_HOPS             10 | ||||
| #define IPV6_MULTICAST_LOOP             11 | ||||
| #define IPV6_ADD_MEMBERSHIP             12 | ||||
| #define IPV6_DROP_MEMBERSHIP            13 | ||||
| #define IPV6_JOIN_GROUP                 IPV6_ADD_MEMBERSHIP | ||||
| #define IPV6_LEAVE_GROUP                IPV6_DROP_MEMBERSHIP | ||||
| #define IPV6_PKTINFO                    19 | ||||
|  | ||||
| /* Old WinSock1 values, needed internally */ | ||||
| #ifdef __INSIDE_CYGWIN__ | ||||
| #define _WS1_IP_OPTIONS          1 | ||||
|   | ||||
| @@ -31,6 +31,8 @@ int grantpt (int); | ||||
| int unlockpt (int); | ||||
| #endif /*__STRICT_ANSI__*/ | ||||
|  | ||||
| int posix_openpt (int); | ||||
|  | ||||
| #ifdef _COMPILING_NEWLIB | ||||
| #define unsetenv UNUSED_unsetenv | ||||
| #define _unsetenv_r UNUSED__unsetenv_r | ||||
|   | ||||
| @@ -42,8 +42,8 @@ details. */ | ||||
| 	 the Cygwin shared library".  This version is used to track important | ||||
| 	 changes to the DLL and is mainly informative in nature. */ | ||||
|  | ||||
| #define CYGWIN_VERSION_DLL_MAJOR 1005 | ||||
| #define CYGWIN_VERSION_DLL_MINOR 22 | ||||
| #define CYGWIN_VERSION_DLL_MAJOR 1007 | ||||
| #define CYGWIN_VERSION_DLL_MINOR 0 | ||||
|  | ||||
|       /* Major numbers before CYGWIN_VERSION_DLL_EPOCH are | ||||
| 	 incompatible. */ | ||||
| @@ -289,12 +289,17 @@ details. */ | ||||
|       154: Export sigset, sigignore. | ||||
|       155: Export __isinff, __isinfd, __isnanf, __isnand. | ||||
|       156: Export __srbuf_r, __swget_r. | ||||
|       157: Export gai_strerror, getaddrinfo, getnameinfo, freeaddrinfo, | ||||
| 	   in6addr_any, in6addr_loopback. | ||||
|       158: Export bindresvport, bindresvport_sa, iruserok_sa, rcmd_af, | ||||
| 	   rresvport_af. | ||||
|       159: Export posix_openpt. | ||||
|      */ | ||||
|  | ||||
|      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ | ||||
|  | ||||
| #define CYGWIN_VERSION_API_MAJOR 0 | ||||
| #define CYGWIN_VERSION_API_MINOR 156 | ||||
| #define CYGWIN_VERSION_API_MINOR 159 | ||||
|  | ||||
|      /* There is also a compatibity version number associated with the | ||||
| 	shared memory regions.  It is incremented when incompatible | ||||
|   | ||||
| @@ -63,6 +63,9 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <cygwin/socket.h> | ||||
|  | ||||
| /* | ||||
|  * Structures returned by network data base library.  All addresses are | ||||
|  * supplied in host order, and returned in network order (suitable for | ||||
| @@ -88,7 +91,7 @@ struct	netent { | ||||
| 	char		*n_name;	/* official name of net */ | ||||
| 	char		**n_aliases;	/* alias list */ | ||||
| 	short		n_addrtype;	/* net address type */ | ||||
| 	unsigned long	n_net;		/* network # */ | ||||
| 	uint32_t	n_net;		/* network # */ | ||||
| }; | ||||
|  | ||||
| struct	servent { | ||||
| @@ -111,6 +114,17 @@ struct rpcent { | ||||
| 	int	r_number;	/* rpc program number */ | ||||
| }; | ||||
|  | ||||
| struct addrinfo { | ||||
|   int             ai_flags;		/* input flags */ | ||||
|   int             ai_family;		/* address family of socket */ | ||||
|   int             ai_socktype;		/* socket type */ | ||||
|   int             ai_protocol;		/* ai_protocol */ | ||||
|   socklen_t       ai_addrlen;		/* length of socket address */ | ||||
|   char            *ai_canonname;	/* canonical name of service location */ | ||||
|   struct sockaddr *ai_addr;		/* socket address of socket */ | ||||
|   struct addrinfo *ai_next;		/* pointer to next in list */ | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Error return codes from gethostbyname() and gethostbyaddr() | ||||
|  * (left in extern int h_errno). | ||||
| @@ -130,6 +144,45 @@ extern __declspec(dllimport) int h_errno; | ||||
| #define	NO_DATA		4 /* Valid name, no data record of requested type */ | ||||
| #define	NO_ADDRESS	NO_DATA		/* no address, look for MX record */ | ||||
|  | ||||
| #define AI_PASSIVE      1 | ||||
| #define AI_CANONNAME    2 | ||||
| #define AI_NUMERICHOST  4 | ||||
| /* | ||||
|  * These are not available in the WinSock implementation.  It wouldn't make | ||||
|  * sense to support them in the ipv4 only case, so we drop them entirely. | ||||
|  * We can define them if we run into problems but they are non-functional, so... | ||||
|  */ | ||||
| #if 0 | ||||
| #define AI_V4MAPPED     16 | ||||
| #define AI_ALL          32 | ||||
| #define AI_ADDRCONFIG   64 | ||||
| #endif | ||||
|  | ||||
| #define NI_NOFQDN       1 | ||||
| #define NI_NUMERICHOST  2 | ||||
| #define NI_NAMEREQD     4 | ||||
| #define NI_NUMERICSERV  8 | ||||
| #define NI_DGRAM        16 | ||||
|  | ||||
| #define NI_MAXHOST      1025 | ||||
| #define NI_MAXSERV      32 | ||||
|  | ||||
| #define EAI_ADDRFAMILY  1 | ||||
| #define EAI_AGAIN       2 | ||||
| #define EAI_BADFLAGS    3 | ||||
| #define EAI_FAIL        4 | ||||
| #define EAI_FAMILY      5 | ||||
| #define EAI_MEMORY      6 | ||||
| #define EAI_NODATA      7 | ||||
| #define EAI_NONAME      8 | ||||
| #define EAI_SERVICE     9 | ||||
| #define EAI_SOCKTYPE    10 | ||||
| #define EAI_SYSTEM      11 | ||||
| #define EAI_BADHINTS    12 | ||||
| #define EAI_PROTOCOL    13 | ||||
|  | ||||
| #define EAI_MAX		14 | ||||
|  | ||||
| #ifndef __INSIDE_CYGWIN_NET__ | ||||
| void		endhostent (void); | ||||
| void		endnetent (void); | ||||
| @@ -158,6 +211,24 @@ void		setnetent (int); | ||||
| void		setprotoent (int); | ||||
| void		setservent (int); | ||||
| void		setrpcent (int); | ||||
| void		freeaddrinfo (struct addrinfo *); | ||||
| const char	*gai_strerror (int); | ||||
| int		getaddrinfo (const char *, const char *, | ||||
| 			     const struct addrinfo *, struct addrinfo **); | ||||
| int		getnameinfo (const struct sockaddr *, socklen_t, char *, | ||||
| 			     socklen_t, char *, socklen_t, int); | ||||
|  | ||||
| int		rcmd (char **, uint16_t, const char *, const char *, | ||||
| 		      const char *, int *); | ||||
| int		rcmd_af (char **, uint16_t, const char *, const char *, | ||||
| 			 const char *, int *, int); | ||||
| int		rexec (char **, uint16_t rport, char *, char *, char *, int *); | ||||
| int		rresvport (int *); | ||||
| int		rresvport_af (int *, int); | ||||
| int		iruserok (unsigned long, int, const char *, const char *); | ||||
| int		iruserok_sa (const void *, int, int, const char *, | ||||
| 			     const char *); | ||||
| int		ruserok (const char *, int, const char *, const char *); | ||||
| #endif | ||||
|  | ||||
| #ifdef __cplusplus | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| /* netinet/in.h | ||||
|  | ||||
|    Copyright 1998, 2001 Red Hat, Inc. | ||||
|    Copyright 1998, 2001, 2006 Red Hat, Inc. | ||||
|  | ||||
| This file is part of Cygwin. | ||||
|  | ||||
| @@ -13,4 +13,16 @@ details. */ | ||||
|  | ||||
| #include <cygwin/in.h> | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" | ||||
| { | ||||
| #endif | ||||
|  | ||||
| extern int bindresvport (int, struct sockaddr_in *); | ||||
| extern int bindresvport_sa (int, struct sockaddr *); | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #endif /* _NETINET_IN_H */ | ||||
|   | ||||
| @@ -32,14 +32,14 @@ extern "C" | ||||
|   int getpeername (int, struct sockaddr *__peer, socklen_t *); | ||||
|   int getsockname (int, struct sockaddr *__addr, socklen_t *); | ||||
|   int listen (int, int __n); | ||||
|   int recv (int, void *__buff, size_t __len, int __flags); | ||||
|   int recvfrom (int, void *__buff, size_t __len, int __flags, | ||||
| 		struct sockaddr *__from, socklen_t *__fromlen); | ||||
|   int recvmsg(int s, struct msghdr *msg, int flags); | ||||
|   int send (int, const void *__buff, size_t __len, int __flags); | ||||
|   int sendmsg(int s, const struct msghdr *msg, int flags); | ||||
|   int sendto (int, const void *, size_t __len, int __flags, | ||||
| 	      const struct sockaddr *__to, socklen_t __tolen); | ||||
|   ssize_t recv (int, void *__buff, size_t __len, int __flags); | ||||
|   ssize_t recvfrom (int, void *__buff, size_t __len, int __flags, | ||||
| 		    struct sockaddr *__from, socklen_t *__fromlen); | ||||
|   ssize_t recvmsg(int s, struct msghdr *msg, int flags); | ||||
|   ssize_t send (int, const void *__buff, size_t __len, int __flags); | ||||
|   ssize_t sendmsg(int s, const struct msghdr *msg, int flags); | ||||
|   ssize_t sendto (int, const void *, size_t __len, int __flags, | ||||
| 		  const struct sockaddr *__to, socklen_t __tolen); | ||||
|   int setsockopt (int __s, int __level, int __optname, const void *optval, | ||||
| 		  socklen_t __optlen); | ||||
|   int getsockopt (int __s, int __level, int __optname, void *__optval, | ||||
|   | ||||
| @@ -1,270 +0,0 @@ | ||||
| /* Based on the rcmd.c.new file distributed with linux libc 5.4.19 | ||||
|    Adapted to inetutils by Bernhard Rosenkraenzer <bero@startrek.in-trier.de> | ||||
|  | ||||
|    Note that a lot in this file is superfluous; hopefully it won't be a | ||||
|    problem for systems that need it for iruserok &c....  */ | ||||
| /* | ||||
|  * Copyright (c) 1983, 1993, 1994 | ||||
|  *	The Regents of the University of California.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "winsup.h" | ||||
| #include <pwd.h> | ||||
| #include <sys/stat.h> | ||||
| #include <malloc.h> | ||||
| #include <string.h> | ||||
| #include <netdb.h> | ||||
| #include <ctype.h> | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| #include <sys/time.h> | ||||
| #include <time.h> | ||||
|  | ||||
| #ifndef PATH_HEQUIV | ||||
| # define PATH_HEQUIV "/etc/hosts.equiv" | ||||
| #endif | ||||
|  | ||||
| int         __check_rhosts_file = 1; | ||||
| const char *__rcmd_errstr; | ||||
|  | ||||
| /* | ||||
|  * Returns "true" if match, 0 if no match. | ||||
|  */ | ||||
| static int | ||||
| __icheckhost(raddr, lhost) | ||||
|   u_long raddr; | ||||
|   register char *lhost; | ||||
| { | ||||
| 	register struct hostent *hp; | ||||
| 	register u_long laddr; | ||||
| 	register char **pp; | ||||
|  | ||||
| 	/* Try for raw ip address first. */ | ||||
| 	if (isdigit(*lhost) && (long)(laddr = cygwin_inet_addr(lhost)) != -1) | ||||
| 		return (raddr == laddr); | ||||
|  | ||||
| 	/* Better be a hostname. */ | ||||
| 	if ((hp = cygwin_gethostbyname(lhost)) == NULL) | ||||
| 		return (0); | ||||
|  | ||||
| 	/* Spin through ip addresses. */ | ||||
| 	for (pp = hp->h_addr_list; *pp; ++pp) | ||||
| 		if (!bcmp(&raddr, *pp, sizeof(u_long))) | ||||
| 			return (1); | ||||
|  | ||||
| 	/* No match. */ | ||||
| 	return (0); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * XXX | ||||
|  * Don't make static, used by lpd(8). | ||||
|  * | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  */ | ||||
| static int | ||||
| __ivaliduser(hostf, raddr, luser, ruser) | ||||
|   struct __sFILE64 *hostf; | ||||
|   u_long raddr; | ||||
|   const char *luser; | ||||
|   const char *ruser; | ||||
| { | ||||
| 	size_t buf_offs = 0; | ||||
| 	size_t buf_len = 256; | ||||
| 	char *buf = malloc (buf_len); | ||||
|  | ||||
| 	if (! buf) | ||||
| 		return -1; | ||||
|  | ||||
| 	while (fgets(buf + buf_offs, buf_len - buf_offs, hostf)) { | ||||
| 		/*int ch;*/ | ||||
| 		register char *user, *p; | ||||
|  | ||||
| 		if (strchr(buf + buf_offs, '\n') == NULL) { | ||||
| 			/* No newline yet, read some more.  */ | ||||
| 			buf_offs += strlen (buf + buf_offs); | ||||
|  | ||||
| 			if (buf_offs >= buf_len - 1) { | ||||
| 				/* Make more room in BUF.  */ | ||||
| 				char *new_buf; | ||||
|  | ||||
| 				buf_len += buf_len; | ||||
| 				new_buf = realloc (buf, buf_len); | ||||
|  | ||||
| 				if (! new_buf) { | ||||
| 					free (buf); | ||||
| 					return -1; | ||||
| 				} | ||||
|  | ||||
| 				buf = new_buf; | ||||
| 			} | ||||
|  | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		buf_offs = 0;			/* Start at beginning next time around.  */ | ||||
|  | ||||
| 		p = buf; | ||||
| 		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { | ||||
| 			/* *p = isupper(*p) ? tolower(*p) : *p;  -- Uli */ | ||||
| 			*p = tolower(*p);	/* works for linux libc */ | ||||
| 			p++; | ||||
| 		} | ||||
| 		if (*p == ' ' || *p == '\t') { | ||||
| 			*p++ = '\0'; | ||||
| 			while (*p == ' ' || *p == '\t') | ||||
| 				p++; | ||||
| 			user = p; | ||||
| 			while (*p != '\n' && *p != ' ' && | ||||
| 			    *p != '\t' && *p != '\0') | ||||
| 				p++; | ||||
| 		} else | ||||
| 			user = p; | ||||
| 		*p = '\0'; | ||||
|  | ||||
| 		if (__icheckhost(raddr, buf) && !strcmp(ruser, *user ? user : luser)) { | ||||
| 			free (buf); | ||||
| 			return (0); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	free (buf); | ||||
|  | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * New .rhosts strategy: We are passed an ip address. We spin through | ||||
|  * hosts.equiv and .rhosts looking for a match. When the .rhosts only | ||||
|  * has ip addresses, we don't have to trust a nameserver.  When it | ||||
|  * contains hostnames, we spin through the list of addresses the nameserver | ||||
|  * gives us and look for a match. | ||||
|  * | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  */ | ||||
| int | ||||
| iruserok(raddr, superuser, ruser, luser) | ||||
|   u_long raddr; | ||||
|   int superuser; | ||||
|   const char *ruser; | ||||
|   const char *luser; | ||||
| { | ||||
| 	register const char *cp; | ||||
| 	struct __stat64 sbuf; | ||||
| 	struct passwd *pwd; | ||||
| 	struct __sFILE64 *hostf; | ||||
|  | ||||
| 	uid_t uid; | ||||
| 	int first = 1; | ||||
| 	char *pbuf; | ||||
|  | ||||
| 	first = 1; | ||||
| 	hostf = superuser ? NULL : fopen64(PATH_HEQUIV, "rt"); | ||||
| again: | ||||
| 	if (hostf) { | ||||
| 		if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { | ||||
| 			(void) fclose(hostf); | ||||
| 			return(0); | ||||
| 		} | ||||
| 		(void) fclose(hostf); | ||||
| 	} | ||||
| 	if (first == 1 && (__check_rhosts_file || superuser)) { | ||||
| 		first = 0; | ||||
| 		if ((pwd = getpwnam(luser)) == NULL) | ||||
| 			return(-1); | ||||
|  | ||||
| 		pbuf = malloc (strlen (pwd->pw_dir) + sizeof "/.rhosts"); | ||||
| 		if (! pbuf) | ||||
| 		  { | ||||
| 		    errno = ENOMEM; | ||||
| 		    return -1; | ||||
| 		  } | ||||
| 		strcpy (pbuf, pwd->pw_dir); | ||||
| 		strcat (pbuf, "/.rhosts"); | ||||
|  | ||||
| 		/* | ||||
| 		 * Change effective uid while opening .rhosts.  If root and | ||||
| 		 * reading an NFS mounted file system, can't read files that | ||||
| 		 * are protected read/write owner only. | ||||
| 		 */ | ||||
| 		uid = geteuid32(); | ||||
| 		(void)seteuid32(pwd->pw_uid); | ||||
| 		hostf = fopen64(pbuf, "rt"); | ||||
| 		(void)seteuid32(uid); | ||||
|  | ||||
| 		if (hostf == NULL) | ||||
| 			return(-1); | ||||
| 		/* | ||||
| 		 * If not a regular file, or is owned by someone other than | ||||
| 		 * user or root or if writeable by anyone but the owner, quit. | ||||
| 		 */ | ||||
| 		cp = NULL; | ||||
| 		if (lstat64(pbuf, &sbuf) < 0) | ||||
| 			cp = ".rhosts not regular file"; | ||||
| 		else if (!S_ISREG(sbuf.st_mode)) | ||||
| 			cp = ".rhosts not regular file"; | ||||
| 		else if (fstat64(fileno(hostf), &sbuf) < 0) | ||||
| 			cp = ".rhosts fstat failed"; | ||||
| 		else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) | ||||
| 			cp = "bad .rhosts owner"; | ||||
| 		else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) | ||||
| 			cp = ".rhosts writeable by other than owner"; | ||||
| 		/* If there were any problems, quit. */ | ||||
| 		if (cp) { | ||||
| 			__rcmd_errstr = (char *) cp; | ||||
| 			fclose(hostf); | ||||
| 			return(-1); | ||||
| 		} | ||||
| 		goto again; | ||||
| 	} | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| int | ||||
| ruserok(rhost, superuser, ruser, luser) | ||||
|   const char *rhost; | ||||
|   int superuser; | ||||
|   const char *ruser; | ||||
|   const char *luser; | ||||
| { | ||||
| 	struct hostent *hp; | ||||
| 	u_long addr; | ||||
| 	char **ap; | ||||
|  | ||||
| 	if ((hp = cygwin_gethostbyname(rhost)) == NULL) | ||||
| 		return (-1); | ||||
| 	for (ap = hp->h_addr_list; *ap; ++ap) { | ||||
| 		bcopy(*ap, &addr, sizeof(addr)); | ||||
| 		if (iruserok(addr, superuser, ruser, luser) == 0) | ||||
| 			return (0); | ||||
| 	} | ||||
| 	return (-1); | ||||
| } | ||||
							
								
								
									
										782
									
								
								winsup/cygwin/libc/rcmd.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										782
									
								
								winsup/cygwin/libc/rcmd.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,782 @@ | ||||
| /* | ||||
|  * Copyright (c) 1983, 1993, 1994 | ||||
|  *	The Regents of the University of California.  All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions | ||||
|  * are met: | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. All advertising materials mentioning features or use of this software | ||||
|  *    must display the following acknowledgement: | ||||
|  *	This product includes software developed by the University of | ||||
|  *	California, Berkeley and its contributors. | ||||
|  * 4. Neither the name of the University nor the names of its contributors | ||||
|  *    may be used to endorse or promote products derived from this software | ||||
|  *    without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||||
|  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||||
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||||
|  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||||
|  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||||
|  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||
|  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
|  * SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #if defined(LIBC_SCCS) && !defined(lint) | ||||
| static char sccsid[] = "@(#)rcmd.c	8.3 (Berkeley) 3/26/94"; | ||||
| #endif /* LIBC_SCCS and not lint */ | ||||
| #include <sys/cdefs.h> | ||||
| #ifndef __CYGWIN__ | ||||
| __FBSDID("$FreeBSD$"); | ||||
| #else | ||||
| #define  __INSIDE_CYGWIN_NET__ | ||||
| #include "winsup.h" | ||||
| #endif | ||||
|  | ||||
| #ifndef __CYGWIN__ | ||||
| #include "namespace.h" | ||||
| #endif | ||||
| #include <sys/param.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/stat.h> | ||||
|  | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| #include <signal.h> | ||||
| #include <fcntl.h> | ||||
| #include <netdb.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <pwd.h> | ||||
| #include <errno.h> | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #ifndef __CYGWIN__ | ||||
| #include <rpc/rpc.h> | ||||
| #endif | ||||
| #ifdef YP | ||||
| #include <rpcsvc/yp_prot.h> | ||||
| #include <rpcsvc/ypclnt.h> | ||||
| #endif | ||||
| #ifndef __CYGWIN__ | ||||
| #include <arpa/nameser.h> | ||||
| #include "un-namespace.h" | ||||
| #endif | ||||
|  | ||||
| #ifndef __CYGWIN__ | ||||
| extern int innetgr( const char *, const char *, const char *, const char * ); | ||||
|  | ||||
| #define max(a, b)	((a > b) ? a : b) | ||||
| #else | ||||
| #include "wininet.h" | ||||
| #include "cygwin/in6.h" | ||||
|  | ||||
| #ifndef _PATH_HEQUIV | ||||
| # define _PATH_HEQUIV "/etc/hosts.equiv" | ||||
| #endif | ||||
|  | ||||
| #define innetgr(a,b,c,d)	(0) | ||||
|  | ||||
| extern int rcmdsh(char **, int, const char *, const char *, const char *, | ||||
| 		  const char *); | ||||
|  | ||||
| extern "C" { | ||||
|   int cygwin_accept (int, struct sockaddr *, socklen_t *); | ||||
|   int cygwin_bindresvport_sa (int, struct sockaddr *); | ||||
|   int cygwin_connect (int, const struct sockaddr *, socklen_t); | ||||
|   void cygwin_freeaddrinfo (struct addrinfo *); | ||||
|   const char * cygwin_gai_strerror (int); | ||||
|   int cygwin_getaddrinfo (const char *, const char *, const struct addrinfo *, | ||||
| 			  struct addrinfo **); | ||||
|   int cygwin_getnameinfo (const struct sockaddr *, socklen_t, char *, size_t, | ||||
|   			  char *, size_t, int); | ||||
|   struct servent *cygwin_getservbyname (const char *, const char *); | ||||
|   int cygwin_listen (int, int); | ||||
|   int cygwin_rresvport_af(int *alport, int family); | ||||
|   int cygwin_select (int, fd_set *, fd_set *, fd_set *, struct timeval *); | ||||
|   int cygwin_socket (int, int, int); | ||||
|   int seteuid32 (__uid32_t); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifndef __CYGWIN__ | ||||
| static int __ivaliduser(FILE *, u_int32_t, const char *, const char *); | ||||
| static int __ivaliduser_af(FILE *,const void *, const char *, const char *, | ||||
| 			   int, int); | ||||
| #endif | ||||
| static int __ivaliduser_sa(FILE *, const struct sockaddr *, socklen_t, | ||||
| 			   const char *, const char *); | ||||
| static int __icheckhost(const struct sockaddr *, socklen_t, const char *); | ||||
|  | ||||
| char paddr[NI_MAXHOST]; | ||||
|  | ||||
| extern "C" int | ||||
| cygwin_rcmd_af(char **ahost, in_port_t rport, const char *locuser, | ||||
| 	       const char *remuser, const char *cmd, int *fd2p, int af) | ||||
| { | ||||
| 	struct addrinfo hints, *res, *ai; | ||||
| 	struct sockaddr_storage from; | ||||
| 	fd_set reads; | ||||
| 	sigset_t oldmask, newmask; | ||||
| 	pid_t pid; | ||||
| 	int s, aport, lport, timo, error; | ||||
| 	char c;//, *p; | ||||
| 	int refused, nres; | ||||
| 	char num[8]; | ||||
| 	static char canonnamebuf[INTERNET_MAX_HOST_NAME_LENGTH + 1];	/* is it proper here? */ | ||||
| #ifndef __CYGWIN__ | ||||
| 	/* call rcmdsh() with specified remote shell if appropriate. */ | ||||
| 	if (!issetugid() && (p = getenv("RSH"))) { | ||||
| 		struct servent *sp = cygwin_getservbyname("shell", "tcp"); | ||||
|  | ||||
| 		if (sp && sp->s_port == rport) | ||||
| 			return (rcmdsh(ahost, rport, locuser, remuser, | ||||
| 			    cmd, p)); | ||||
| 	} | ||||
|  | ||||
| 	/* use rsh(1) if non-root and remote port is shell. */ | ||||
| 	if (geteuid()) { | ||||
| 		struct servent *sp = cygwin_getservbyname("shell", "tcp"); | ||||
|  | ||||
| 		if (sp && sp->s_port == rport) | ||||
| 			return (rcmdsh(ahost, rport, locuser, remuser, | ||||
| 			    cmd, NULL)); | ||||
| 	} | ||||
| #endif | ||||
| 	pid = getpid(); | ||||
|  | ||||
| 	memset(&hints, 0, sizeof(hints)); | ||||
| 	hints.ai_flags = AI_CANONNAME; | ||||
| 	hints.ai_family = af; | ||||
| 	hints.ai_socktype = SOCK_STREAM; | ||||
| 	hints.ai_protocol = 0; | ||||
| 	(void)snprintf(num, sizeof(num), "%d", ntohs(rport)); | ||||
| 	error = cygwin_getaddrinfo(*ahost, num, &hints, &res); | ||||
| 	if (error) { | ||||
| 		fprintf(stderr, "rcmd: getaddrinfo: %s\n", | ||||
| 			cygwin_gai_strerror(error)); | ||||
| 		if (error == EAI_SYSTEM) | ||||
| 			fprintf(stderr, "rcmd: getaddrinfo: %s\n", | ||||
| 				strerror(errno)); | ||||
| 		return (-1); | ||||
| 	} | ||||
|  | ||||
| 	if (res->ai_canonname | ||||
| 	 && strlen(res->ai_canonname) + 1 < sizeof(canonnamebuf)) { | ||||
| 		strncpy(canonnamebuf, res->ai_canonname, sizeof(canonnamebuf)); | ||||
| 		*ahost = canonnamebuf; | ||||
| 	} | ||||
| 	nres = 0; | ||||
| 	for (ai = res; ai; ai = ai->ai_next) | ||||
| 		nres++; | ||||
| 	ai = res; | ||||
| 	refused = 0; | ||||
| 	sigemptyset(&newmask); | ||||
| 	sigaddset(&newmask, SIGURG); | ||||
| 	sigprocmask(SIG_BLOCK, (const sigset_t *)&newmask, &oldmask); | ||||
| 	for (timo = 1, lport = IPPORT_RESERVED - 1;;) { | ||||
| 		s = cygwin_rresvport_af(&lport, ai->ai_family); | ||||
| 		if (s < 0) { | ||||
| 			if (errno != EAGAIN && ai->ai_next) { | ||||
| 				ai = ai->ai_next; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (errno == EAGAIN) | ||||
| 				(void)fprintf(stderr, | ||||
| 				    "rcmd: socket: All ports in use\n"); | ||||
| 			else | ||||
| 				(void)fprintf(stderr, "rcmd: socket: %s\n", | ||||
| 				    strerror(errno)); | ||||
| 			cygwin_freeaddrinfo(res); | ||||
| 			sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, | ||||
| 			    NULL); | ||||
| 			return (-1); | ||||
| 		} | ||||
| 		fcntl(s, F_SETOWN, pid); | ||||
| 		if (cygwin_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0) | ||||
| 			break; | ||||
| 		(void)close(s); | ||||
| 		if (errno == EADDRINUSE) { | ||||
| 			lport--; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (errno == ECONNREFUSED) | ||||
| 			refused = 1; | ||||
| 		if (ai->ai_next == NULL && (!refused || timo > 16)) { | ||||
| 			(void)fprintf(stderr, "%s: %s\n", | ||||
| 				      *ahost, strerror(errno)); | ||||
| 			cygwin_freeaddrinfo(res); | ||||
| 			sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, | ||||
| 			    NULL); | ||||
| 			return (-1); | ||||
| 		} | ||||
| 		if (nres > 1) { | ||||
| 			int oerrno = errno; | ||||
|  | ||||
| 			cygwin_getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, | ||||
| 			    sizeof(paddr), NULL, 0, NI_NUMERICHOST); | ||||
| 			(void)fprintf(stderr, "connect to address %s: ", | ||||
| 				      paddr); | ||||
| 			errno = oerrno; | ||||
| 			perror(0); | ||||
| 		} | ||||
| 		if ((ai = ai->ai_next) == NULL) { | ||||
| 			/* refused && timo <= 16 */ | ||||
| 			struct timespec time_to_sleep, time_remaining; | ||||
|  | ||||
| 			time_to_sleep.tv_sec = timo; | ||||
| 			time_to_sleep.tv_nsec = 0; | ||||
| 			(void)nanosleep(&time_to_sleep, &time_remaining); | ||||
| 			timo *= 2; | ||||
| 			ai = res; | ||||
| 			refused = 0; | ||||
| 		} | ||||
| 		if (nres > 1) { | ||||
| 			cygwin_getnameinfo(ai->ai_addr, ai->ai_addrlen, paddr, | ||||
| 			    sizeof(paddr), NULL, 0, NI_NUMERICHOST); | ||||
| 			fprintf(stderr, "Trying %s...\n", paddr); | ||||
| 		} | ||||
| 	} | ||||
| 	lport--; | ||||
| 	if (fd2p == 0) { | ||||
| 		write(s, "", 1); | ||||
| 		lport = 0; | ||||
| 	} else { | ||||
| 		int s2 = cygwin_rresvport_af(&lport, ai->ai_family), s3; | ||||
| 		socklen_t len = ai->ai_addrlen; | ||||
| 		int nfds; | ||||
|  | ||||
| 		if (s2 < 0) | ||||
| 			goto bad; | ||||
| 		cygwin_listen(s2, 1); | ||||
| 		(void)snprintf(num, sizeof(num), "%d", lport); | ||||
| 		if (write(s, num, strlen(num)+1) != (int)strlen(num)+1) { | ||||
| 			(void)fprintf(stderr, | ||||
| 			    "rcmd: write (setting up stderr): %s\n", | ||||
| 			    strerror(errno)); | ||||
| 			(void)close(s2); | ||||
| 			goto bad; | ||||
| 		} | ||||
| 		nfds = max(s, s2)+1; | ||||
| 		if(nfds > FD_SETSIZE) { | ||||
| 			fprintf(stderr, "rcmd: too many files\n"); | ||||
| 			(void)close(s2); | ||||
| 			goto bad; | ||||
| 		} | ||||
| again: | ||||
| 		FD_ZERO(&reads); | ||||
| 		FD_SET(s, &reads); | ||||
| 		FD_SET(s2, &reads); | ||||
| 		errno = 0; | ||||
| 		if (cygwin_select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){ | ||||
| 			if (errno != 0) | ||||
| 				(void)fprintf(stderr, | ||||
| 				    "rcmd: select (setting up stderr): %s\n", | ||||
| 				    strerror(errno)); | ||||
| 			else | ||||
| 				(void)fprintf(stderr, | ||||
| 				"select: protocol failure in circuit setup\n"); | ||||
| 			(void)close(s2); | ||||
| 			goto bad; | ||||
| 		} | ||||
| 		s3 = cygwin_accept(s2, (struct sockaddr *)&from, &len); | ||||
| 		switch (from.ss_family) { | ||||
| 		case AF_INET: | ||||
| 			aport = ntohs(((struct sockaddr_in *)&from)->sin_port); | ||||
| 			break; | ||||
| #ifdef INET6 | ||||
| 		case AF_INET6: | ||||
| 			aport = ntohs(((struct sockaddr_in6 *)&from)->sin6_port); | ||||
| 			break; | ||||
| #endif | ||||
| 		default: | ||||
| 			aport = 0;	/* error */ | ||||
| 			break; | ||||
| 		} | ||||
| 		/* | ||||
| 		 * XXX careful for ftp bounce attacks. If discovered, shut them | ||||
| 		 * down and check for the real auxiliary channel to connect. | ||||
| 		 */ | ||||
| 		if (aport == 20) { | ||||
| 			close(s3); | ||||
| 			goto again; | ||||
| 		} | ||||
| 		(void)close(s2); | ||||
| 		if (s3 < 0) { | ||||
| 			(void)fprintf(stderr, | ||||
| 			    "rcmd: accept: %s\n", strerror(errno)); | ||||
| 			lport = 0; | ||||
| 			goto bad; | ||||
| 		} | ||||
| 		*fd2p = s3; | ||||
| 		if (aport >= IPPORT_RESERVED || aport < IPPORT_RESERVED / 2) { | ||||
| 			(void)fprintf(stderr, | ||||
| 			    "socket: protocol failure in circuit setup.\n"); | ||||
| 			goto bad2; | ||||
| 		} | ||||
| 	} | ||||
| 	(void)write(s, locuser, strlen(locuser)+1); | ||||
| 	(void)write(s, remuser, strlen(remuser)+1); | ||||
| 	(void)write(s, cmd, strlen(cmd)+1); | ||||
| 	if (read(s, &c, 1) != 1) { | ||||
| 		(void)fprintf(stderr, | ||||
| 		    "rcmd: %s: %s\n", *ahost, strerror(errno)); | ||||
| 		goto bad2; | ||||
| 	} | ||||
| 	if (c != 0) { | ||||
| 		while (read(s, &c, 1) == 1) { | ||||
| 			(void)write(STDERR_FILENO, &c, 1); | ||||
| 			if (c == '\n') | ||||
| 				break; | ||||
| 		} | ||||
| 		goto bad2; | ||||
| 	} | ||||
| 	sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); | ||||
| 	cygwin_freeaddrinfo(res); | ||||
| 	return (s); | ||||
| bad2: | ||||
| 	if (lport) | ||||
| 		(void)close(*fd2p); | ||||
| bad: | ||||
| 	(void)close(s); | ||||
| 	sigprocmask(SIG_SETMASK, (const sigset_t *)&oldmask, NULL); | ||||
| 	cygwin_freeaddrinfo(res); | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| cygwin_rcmd(char **ahost, in_port_t rport, const char *locuser, | ||||
| 	    const char *remuser, const char *cmd, int *fd2p) | ||||
| { | ||||
| 	return cygwin_rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, | ||||
| 			      AF_INET); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| cygwin_rresvport_af(int *alport, int family) | ||||
| { | ||||
| 	int s; | ||||
| 	struct sockaddr_storage ss; | ||||
| 	u_short *sport; | ||||
|  | ||||
| 	memset(&ss, 0, sizeof(ss)); | ||||
| 	ss.ss_family = family; | ||||
| 	switch (family) { | ||||
| 	case AF_INET: | ||||
| 		sport = &((struct sockaddr_in *)&ss)->sin_port; | ||||
| 		((struct sockaddr_in *)&ss)->sin_addr.s_addr = INADDR_ANY; | ||||
| 		break; | ||||
| #ifdef INET6 | ||||
| 	case AF_INET6: | ||||
| 		sport = &((struct sockaddr_in6 *)&ss)->sin6_port; | ||||
| 		((struct sockaddr_in6 *)&ss)->sin6_addr = in6addr_any; | ||||
| 		break; | ||||
| #endif | ||||
| 	default: | ||||
| 		errno = EAFNOSUPPORT; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	s = cygwin_socket(ss.ss_family, SOCK_STREAM, 0); | ||||
| 	if (s < 0) | ||||
| 		return (-1); | ||||
| #if 0 /* compat_exact_traditional_rresvport_semantics */ | ||||
| 	sin.sin_port = htons((u_short)*alport); | ||||
| 	if (_bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) | ||||
| 		return (s); | ||||
| 	if (errno != EADDRINUSE) { | ||||
| 		(void)_close(s); | ||||
| 		return (-1); | ||||
| 	} | ||||
| #endif | ||||
| 	*sport = 0; | ||||
| 	if (cygwin_bindresvport_sa(s, (struct sockaddr *)&ss) == -1) { | ||||
| 		(void)close(s); | ||||
| 		return (-1); | ||||
| 	} | ||||
| 	*alport = (int)ntohs(*sport); | ||||
| 	return (s); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| cygwin_rresvport(int *port) | ||||
| { | ||||
| 	return cygwin_rresvport_af(port, AF_INET); | ||||
| } | ||||
|  | ||||
| int	__check_rhosts_file = 1; | ||||
| char	*__rcmd_errstr; | ||||
|  | ||||
| /* | ||||
|  * AF independent extension of iruserok. | ||||
|  * | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  */ | ||||
| extern "C" int | ||||
| iruserok_sa(const void *ra, int rlen, int superuser, const char *ruser, | ||||
| 	    const char *luser) | ||||
| { | ||||
| 	const char *cp; | ||||
| 	struct __stat64 sbuf; | ||||
| 	struct passwd *pwd; | ||||
| 	FILE *hostf; | ||||
| 	uid_t uid; | ||||
| 	int first; | ||||
| 	char pbuf[MAXPATHLEN]; | ||||
| 	const struct sockaddr *raddr; | ||||
| 	struct sockaddr_storage ss; | ||||
|  | ||||
| 	/* avoid alignment issue */ | ||||
| 	if (rlen > (int) sizeof(ss))  | ||||
| 		return(-1); | ||||
| 	memcpy(&ss, ra, rlen); | ||||
| 	raddr = (struct sockaddr *)&ss; | ||||
|  | ||||
| 	first = 1; | ||||
| 	hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "rt"); | ||||
| again: | ||||
| 	if (hostf) { | ||||
| 		if (__ivaliduser_sa(hostf, raddr, rlen, luser, ruser) == 0) { | ||||
| 			(void)fclose(hostf); | ||||
| 			return (0); | ||||
| 		} | ||||
| 		(void)fclose(hostf); | ||||
| 	} | ||||
| 	if (first == 1 && (__check_rhosts_file || superuser)) { | ||||
| 		first = 0; | ||||
| 		if ((pwd = getpwnam(luser)) == NULL) | ||||
| 			return (-1); | ||||
| 		(void)strcpy(pbuf, pwd->pw_dir); | ||||
| 		(void)strcat(pbuf, "/.rhosts"); | ||||
|  | ||||
| 		/* | ||||
| 		 * Change effective uid while opening .rhosts.  If root and | ||||
| 		 * reading an NFS mounted file system, can't read files that | ||||
| 		 * are protected read/write owner only. | ||||
| 		 */ | ||||
| 		uid = geteuid32(); | ||||
| 		(void)seteuid32(pwd->pw_uid); | ||||
| 		hostf = fopen(pbuf, "rt"); | ||||
| 		(void)seteuid32(uid); | ||||
|  | ||||
| 		if (hostf == NULL) | ||||
| 			return (-1); | ||||
| 		/* | ||||
| 		 * If not a regular file, or is owned by someone other than | ||||
| 		 * user or root or if writeable by anyone but the owner, quit. | ||||
| 		 */ | ||||
| 		cp = NULL; | ||||
| 		if (lstat64(pbuf, &sbuf) < 0) | ||||
| 			cp = ".rhosts lstat failed"; | ||||
| 		else if (!S_ISREG(sbuf.st_mode)) | ||||
| 			cp = ".rhosts not regular file"; | ||||
| 		else if (fstat64(fileno(hostf), &sbuf) < 0) | ||||
| 			cp = ".rhosts fstat failed"; | ||||
| 		else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) | ||||
| 			cp = "bad .rhosts owner"; | ||||
| 		else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) | ||||
| 			cp = ".rhosts writeable by other than owner"; | ||||
| 		/* If there were any problems, quit. */ | ||||
| 		if (cp) { | ||||
| 			__rcmd_errstr = (char *) cp; | ||||
| 			(void)fclose(hostf); | ||||
| 			return (-1); | ||||
| 		} | ||||
| 		goto again; | ||||
| 	} | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * New .rhosts strategy: We are passed an ip address. We spin through | ||||
|  * hosts.equiv and .rhosts looking for a match. When the .rhosts only | ||||
|  * has ip addresses, we don't have to trust a nameserver.  When it | ||||
|  * contains hostnames, we spin through the list of addresses the nameserver | ||||
|  * gives us and look for a match. | ||||
|  * | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  */ | ||||
| extern "C" int | ||||
| iruserok(unsigned long raddr, int superuser, const char *ruser, | ||||
| 	 const char *luser) | ||||
| { | ||||
| 	struct sockaddr_in sin; | ||||
|  | ||||
| 	memset(&sin, 0, sizeof(sin)); | ||||
| 	sin.sin_family = AF_INET; | ||||
| 	memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); | ||||
| 	return iruserok_sa((struct sockaddr *)&sin, sizeof(struct sockaddr_in), | ||||
| 			   superuser, ruser, luser); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| ruserok(const char *rhost, int superuser, const char *ruser, const char *luser) | ||||
| { | ||||
| 	struct addrinfo hints, *res, *r; | ||||
| 	int error; | ||||
|  | ||||
| 	memset(&hints, 0, sizeof(hints)); | ||||
| 	hints.ai_family = PF_UNSPEC; | ||||
| 	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/ | ||||
| 	error = cygwin_getaddrinfo(rhost, "0", &hints, &res); | ||||
| 	if (error) | ||||
| 		return (-1); | ||||
|  | ||||
| 	for (r = res; r; r = r->ai_next) { | ||||
| 		if (iruserok_sa(r->ai_addr, r->ai_addrlen, superuser, ruser, | ||||
| 		    luser) == 0) { | ||||
| 			cygwin_freeaddrinfo(res); | ||||
| 			return (0); | ||||
| 		} | ||||
| 	} | ||||
| 	cygwin_freeaddrinfo(res); | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| #ifndef __CYGWIN__ | ||||
| /* | ||||
|  * XXX | ||||
|  * Don't make static, used by lpd(8). | ||||
|  * | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  */ | ||||
| static int | ||||
| __ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser, const char *ruser) | ||||
| { | ||||
| 	struct sockaddr_in sin; | ||||
|  | ||||
| 	memset(&sin, 0, sizeof(sin)); | ||||
| 	sin.sin_family = AF_INET; | ||||
| 	memcpy(&sin.sin_addr, &raddr, sizeof(sin.sin_addr)); | ||||
| 	return __ivaliduser_sa(hostf, (struct sockaddr *)&sin, | ||||
| 			       sizeof(struct sockaddr_in), luser, ruser); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns 0 if ok, -1 if not ok. | ||||
|  * | ||||
|  * XXX obsolete API. | ||||
|  */ | ||||
| static int | ||||
| __ivaliduser_af(FILE *hostf, const void *raddr, const char *luser, | ||||
| 		const char *ruser, int af, int len) | ||||
| { | ||||
| 	struct sockaddr *sa = NULL; | ||||
| 	struct sockaddr_in *sin = NULL; | ||||
| #ifdef INET6 | ||||
| 	struct sockaddr_in6 *sin6 = NULL; | ||||
| #endif | ||||
| 	struct sockaddr_storage ss; | ||||
| 	int salen = 0; | ||||
|  | ||||
| 	memset(&ss, 0, sizeof(ss)); | ||||
| 	switch (af) { | ||||
| 	case AF_INET: | ||||
| 		if (len != sizeof(sin->sin_addr)) | ||||
| 			return -1; | ||||
| 		sin = (struct sockaddr_in *)&ss; | ||||
| 		sin->sin_family = AF_INET; | ||||
| 		salen = sizeof(struct sockaddr_in); | ||||
| 		memcpy(&sin->sin_addr, raddr, sizeof(sin->sin_addr)); | ||||
| 		break; | ||||
| #ifdef INET6 | ||||
| 	case AF_INET6: | ||||
| 		if (len != sizeof(sin6->sin6_addr)) | ||||
| 			return -1; | ||||
| 		/* you will lose scope info */ | ||||
| 		sin6 = (struct sockaddr_in6 *)&ss; | ||||
| 		sin6->sin6_family = AF_INET6; | ||||
| 		salen = sizeof(struct sockaddr_in6); | ||||
| 		memcpy(&sin6->sin6_addr, raddr, sizeof(sin6->sin6_addr)); | ||||
| 		break; | ||||
| #endif | ||||
| 	default: | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	sa = (struct sockaddr *)&ss; | ||||
| 	return __ivaliduser_sa(hostf, sa, salen, luser, ruser); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int | ||||
| __ivaliduser_sa(FILE *hostf, const struct sockaddr *raddr, socklen_t salen, | ||||
| 		const char *luser, const char *ruser) | ||||
| { | ||||
| 	char *user, *p; | ||||
| 	int ch; | ||||
| 	char buf[MAXHOSTNAMELEN + 128];		/* host + login */ | ||||
| 	char hname[MAXHOSTNAMELEN]; | ||||
| 	/* Presumed guilty until proven innocent. */ | ||||
| 	int userok = 0, hostok = 0; | ||||
| #ifdef YP | ||||
| 	char *ypdomain; | ||||
|  | ||||
| 	if (yp_get_default_domain(&ypdomain)) | ||||
| 		ypdomain = NULL; | ||||
| #else | ||||
| #define	ypdomain NULL | ||||
| #endif | ||||
| 	/* We need to get the damn hostname back for netgroup matching. */ | ||||
| 	if (cygwin_getnameinfo(raddr, salen, hname, sizeof(hname), NULL, 0, | ||||
| 			NI_NAMEREQD) != 0) | ||||
| 		hname[0] = '\0'; | ||||
|  | ||||
| 	while (fgets(buf, sizeof(buf), hostf)) { | ||||
| 		p = buf; | ||||
| 		/* Skip lines that are too long. */ | ||||
| 		if (strchr(p, '\n') == NULL) { | ||||
| 			while ((ch = getc(hostf)) != '\n' && ch != EOF); | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (*p == '\n' || *p == '#') { | ||||
| 			/* comment... */ | ||||
| 			continue; | ||||
| 		} | ||||
| 		while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { | ||||
| 			*p = isupper((unsigned char)*p) ? tolower((unsigned char)*p) : *p; | ||||
| 			p++; | ||||
| 		} | ||||
| 		if (*p == ' ' || *p == '\t') { | ||||
| 			*p++ = '\0'; | ||||
| 			while (*p == ' ' || *p == '\t') | ||||
| 				p++; | ||||
| 			user = p; | ||||
| 			while (*p != '\n' && *p != ' ' && | ||||
| 			    *p != '\t' && *p != '\0') | ||||
| 				p++; | ||||
| 		} else | ||||
| 			user = p; | ||||
| 		*p = '\0'; | ||||
| 		/* | ||||
| 		 * Do +/- and +@/-@ checking. This looks really nasty, | ||||
| 		 * but it matches SunOS's behavior so far as I can tell. | ||||
| 		 */ | ||||
| 		switch(buf[0]) { | ||||
| 		case '+': | ||||
| 			if (!buf[1]) {     /* '+' matches all hosts */ | ||||
| 				hostok = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			if (buf[1] == '@')  /* match a host by netgroup */ | ||||
| 				hostok = hname[0] != '\0' && | ||||
| 				    innetgr(&buf[2], hname, NULL, ypdomain); | ||||
| 			else		/* match a host by addr */ | ||||
| 				hostok = __icheckhost(raddr, salen, | ||||
| 						      (char *)&buf[1]); | ||||
| 			break; | ||||
| 		case '-':     /* reject '-' hosts and all their users */ | ||||
| 			if (buf[1] == '@') { | ||||
| 				if (hname[0] == '\0' || | ||||
| 				    innetgr(&buf[2], hname, NULL, ypdomain)) | ||||
| 					return(-1); | ||||
| 			} else { | ||||
| 				if (__icheckhost(raddr, salen, | ||||
| 						 (char *)&buf[1])) | ||||
| 					return(-1); | ||||
| 			} | ||||
| 			break; | ||||
| 		default:  /* if no '+' or '-', do a simple match */ | ||||
| 			hostok = __icheckhost(raddr, salen, buf); | ||||
| 			break; | ||||
| 		} | ||||
| 		switch(*user) { | ||||
| 		case '+': | ||||
| 			if (!*(user+1)) {      /* '+' matches all users */ | ||||
| 				userok = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			if (*(user+1) == '@')  /* match a user by netgroup */ | ||||
| 				userok = innetgr(user+2, NULL, ruser, ypdomain); | ||||
| 			else	   /* match a user by direct specification */ | ||||
| 				userok = !(strcmp(ruser, user+1)); | ||||
| 			break; | ||||
| 		case '-': 		/* if we matched a hostname, */ | ||||
| 			if (hostok) {   /* check for user field rejections */ | ||||
| 				if (!*(user+1)) | ||||
| 					return(-1); | ||||
| 				if (*(user+1) == '@') { | ||||
| 					if (innetgr(user+2, NULL, | ||||
| 							ruser, ypdomain)) | ||||
| 						return(-1); | ||||
| 				} else { | ||||
| 					if (!strcmp(ruser, user+1)) | ||||
| 						return(-1); | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		default:	/* no rejections: try to match the user */ | ||||
| 			if (hostok) | ||||
| 				userok = !(strcmp(ruser,*user ? user : luser)); | ||||
| 			break; | ||||
| 		} | ||||
| 		if (hostok && userok) | ||||
| 			return(0); | ||||
| 	} | ||||
| 	return (-1); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns "true" if match, 0 if no match. | ||||
|  */ | ||||
| static int | ||||
| __icheckhost(const struct sockaddr *raddr, socklen_t salen, const char *lhost) | ||||
| { | ||||
| 	struct sockaddr_in sin; | ||||
| 	struct sockaddr_in6 *sin6; | ||||
| 	struct addrinfo hints, *res, *r; | ||||
| 	int error; | ||||
| 	char h1[NI_MAXHOST], h2[NI_MAXHOST]; | ||||
|  | ||||
| 	if (raddr->sa_family == AF_INET6) { | ||||
| 		sin6 = (struct sockaddr_in6 *)raddr; | ||||
| 		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { | ||||
| 			memset(&sin, 0, sizeof(sin)); | ||||
| 			sin.sin_family = AF_INET; | ||||
| 			memcpy(&sin.sin_addr, &sin6->sin6_addr.s6_addr[12], | ||||
| 			       sizeof(sin.sin_addr)); | ||||
| 			raddr = (struct sockaddr *)&sin; | ||||
| 			salen = sizeof(struct sockaddr_in); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	h1[0] = '\0'; | ||||
| 	if (cygwin_getnameinfo(raddr, salen, h1, sizeof(h1), NULL, 0, | ||||
| 			NI_NUMERICHOST) != 0) | ||||
| 		return (0); | ||||
|  | ||||
| 	/* Resolve laddr into sockaddr */ | ||||
| 	memset(&hints, 0, sizeof(hints)); | ||||
| 	hints.ai_family = raddr->sa_family; | ||||
| 	hints.ai_socktype = SOCK_DGRAM;	/*XXX dummy*/ | ||||
| 	res = NULL; | ||||
| 	error = cygwin_getaddrinfo(lhost, "0", &hints, &res); | ||||
| 	if (error) | ||||
| 		return (0); | ||||
|  | ||||
| 	for (r = res; r ; r = r->ai_next) { | ||||
| 		h2[0] = '\0'; | ||||
| 		if (cygwin_getnameinfo(r->ai_addr, r->ai_addrlen, h2, sizeof(h2), | ||||
| 				NULL, 0, NI_NUMERICHOST) != 0) | ||||
| 			continue; | ||||
| 		if (strcmp(h1, h2) == 0) { | ||||
| 			cygwin_freeaddrinfo(res); | ||||
| 			return (1); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* No match. */ | ||||
| 	cygwin_freeaddrinfo(res); | ||||
| 	return (0); | ||||
| } | ||||
| @@ -900,44 +900,64 @@ map::del_list (unsigned i) | ||||
| } | ||||
|  | ||||
| /* This function is called from exception_handler when a segmentation | ||||
|    violation has happened.  We have two cases to check here. | ||||
|    violation has occurred.  It should also be called from all Cygwin | ||||
|    functions that want to support passing noreserve mmap page addresses | ||||
|    to Windows system calls.  In that case, it should be called only after | ||||
|    a system call indicates that the application buffer passed had an | ||||
|    invalid virtual address to avoid any performance impact in non-noreserve | ||||
|    cases. | ||||
|     | ||||
|    First, is it an address within "attached" mmap pages (indicated by | ||||
|    the __PROT_ATTACH protection, see there)?  In this case the function | ||||
|    returns 1 and the exception_handler raises SIGBUS, as demanded by the | ||||
|    memory protection extension described in SUSv3 (see the mmap man | ||||
|    page). | ||||
|    Check if the address range is all within noreserve mmap regions.  If so, | ||||
|    call VirtualAlloc to commit the pages and return MMAP_NORESERVE_COMMITED | ||||
|    on success.  If the page has __PROT_ATTACH (SUSv3 memory protection | ||||
|    extension), or if VirutalAlloc fails, return MMAP_RAISE_SIGBUS. | ||||
|    Otherwise, return MMAP_NONE if the address range is not covered by an | ||||
|    attached or noreserve map. | ||||
|  | ||||
|    Second, check if the address is within "noreserve" mmap pages | ||||
|    (indicated by MAP_NORESERVE flag).  If so, the function calls | ||||
|    VirtualAlloc to commit the page and returns 2.  The exception handler | ||||
|    then just returns with 0 and the affected application retries the | ||||
|    failing memory access.  If VirtualAlloc fails, the function returns | ||||
|    1, so that the exception handler raises a SIGBUS, as described in the | ||||
|    MAP_NORESERVE man pages for Linux and Solaris. | ||||
|     | ||||
|    In any other case 0 is returned and a normal SIGSEGV is raised. */ | ||||
| int | ||||
| mmap_is_attached_or_noreserve_page (ULONG_PTR addr) | ||||
|    On MAP_NORESERVE_COMMITED, the exeception handler should return 0 to | ||||
|    allow the application to retry the memory access, or the calling Cygwin | ||||
|    function should retry the Windows system call. */ | ||||
| mmap_region_status | ||||
| mmap_is_attached_or_noreserve (void *addr, size_t len) | ||||
| { | ||||
|   list *map_list; | ||||
|   long record_idx; | ||||
|   caddr_t u_addr; | ||||
|   DWORD u_len; | ||||
|   DWORD pagesize = getsystempagesize (); | ||||
|   list *map_list = mmapped_areas.get_list_by_fd (-1); | ||||
|  | ||||
|   addr = rounddown (addr, pagesize); | ||||
|   if (!(map_list = mmapped_areas.get_list_by_fd (-1))) | ||||
|     return 0; | ||||
|   if ((record_idx = map_list->search_record ((caddr_t)addr, pagesize, | ||||
| 					     u_addr, u_len, -1)) < 0) | ||||
|     return 0; | ||||
|   if (map_list->get_record (record_idx)->attached ()) | ||||
|     return 1; | ||||
|   if (!map_list->get_record (record_idx)->noreserve ()) | ||||
|     return 0; | ||||
|   DWORD new_prot = map_list->get_record (record_idx)->gen_protect (); | ||||
|   return VirtualAlloc ((void *)addr, pagesize, MEM_COMMIT, new_prot) ? 2 : 1; | ||||
|   size_t pagesize = getpagesize (); | ||||
|   caddr_t start_addr = (caddr_t) rounddown ((uintptr_t) addr, pagesize); | ||||
|   len += ((caddr_t) addr - start_addr); | ||||
|   len = roundup2 (len, pagesize); | ||||
|  | ||||
|   if (map_list == NULL) | ||||
|     return MMAP_NONE; | ||||
|  | ||||
|   while (len > 0)  | ||||
|     { | ||||
|       caddr_t u_addr; | ||||
|       DWORD u_len; | ||||
|       long record_idx = map_list->search_record (start_addr, len, | ||||
| 						 u_addr, u_len, -1); | ||||
|       if (record_idx < 0) | ||||
| 	return MMAP_NONE; | ||||
|  | ||||
|       mmap_record *rec = map_list->get_record (record_idx); | ||||
|       if (rec->attached ()) | ||||
| 	return MMAP_RAISE_SIGBUS; | ||||
|       if (!rec->noreserve ()) | ||||
| 	return MMAP_NONE; | ||||
|  | ||||
|       size_t commit_len = u_len - (start_addr - u_addr); | ||||
|       if (commit_len > len) | ||||
| 	commit_len = len; | ||||
|  | ||||
|       if (!VirtualAlloc (start_addr, commit_len, MEM_COMMIT, | ||||
| 			 rec->gen_protect ())) | ||||
| 	return MMAP_RAISE_SIGBUS; | ||||
|  | ||||
|       start_addr += commit_len; | ||||
|       len -= commit_len; | ||||
|     } | ||||
|  | ||||
|     return MMAP_NORESERVE_COMMITED; | ||||
| } | ||||
|  | ||||
| static caddr_t | ||||
|   | ||||
							
								
								
									
										1670
									
								
								winsup/cygwin/net.cc
									
									
									
									
									
								
							
							
						
						
									
										1670
									
								
								winsup/cygwin/net.cc
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -97,6 +97,10 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | ||||
| 		    sock = cygheap->fdtab[fds[i].fd]->is_socket (); | ||||
| 		    if (!sock) | ||||
| 		      fds[i].revents |= POLLIN; | ||||
| 		    else if (sock->listener ()) | ||||
| 		      { | ||||
| 			fds[i].revents |= POLLIN; | ||||
| 		      } | ||||
| 		    else | ||||
| 		      { | ||||
| 			/* The following action can change errno.  We have to | ||||
| @@ -105,18 +109,8 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout) | ||||
| 			switch (sock->recvfrom (peek, sizeof (peek), MSG_PEEK, | ||||
| 						NULL, NULL)) | ||||
| 			  { | ||||
| 			    case -1: /* Something weird happened */ | ||||
| 			      /* When select returns that data is available, | ||||
| 				 that could mean that the socket is in | ||||
| 				 listen mode and a client tries to connect. | ||||
| 				 Unfortunately, recvfrom() doesn't make much | ||||
| 				 sense then.  It returns WSAENOTCONN in that | ||||
| 				 case.  Since that's not actually an error, | ||||
| 				 we must not set POLLERR but POLLIN. */ | ||||
| 			      if (WSAGetLastError () != WSAENOTCONN) | ||||
| 				fds[i].revents |= POLLERR; | ||||
| 			      else | ||||
| 				fds[i].revents |= POLLIN; | ||||
| 			    case -1: | ||||
| 			      fds[i].revents |= POLLERR; | ||||
| 			      break; | ||||
| 			    case 0:  /* Closed on the read side... */ | ||||
| 			      /* ...or shutdown(SHUT_WR) on the write side. | ||||
|   | ||||
| @@ -28,6 +28,7 @@ details. */ | ||||
| #include <ntsecapi.h> | ||||
| #include <subauth.h> | ||||
| #include <aclapi.h> | ||||
| #include <dsgetdc.h> | ||||
| #include "cygerrno.h" | ||||
| #include "security.h" | ||||
| #include "path.h" | ||||
| @@ -208,13 +209,21 @@ close_local_policy (LSA_HANDLE &lsa) | ||||
|   lsa = INVALID_HANDLE_VALUE; | ||||
| } | ||||
|  | ||||
| /* CV, 2006-07-06: Missing in w32api. */ | ||||
| extern "C" DWORD WINAPI DsGetDcNameA (LPCSTR, LPCSTR, GUID *, LPCSTR, ULONG, | ||||
| 				      PDOMAIN_CONTROLLER_INFOA *); | ||||
| #define DS_FORCE_REDISCOVERY	1 | ||||
|  | ||||
| bool | ||||
| get_logon_server (const char *domain, char *server, WCHAR *wserver) | ||||
| get_logon_server (const char *domain, char *server, WCHAR *wserver, | ||||
| 		  bool rediscovery) | ||||
| { | ||||
|   WCHAR wdomain[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||
|   NET_API_STATUS ret; | ||||
|   DWORD dret; | ||||
|   PDOMAIN_CONTROLLER_INFOA pci; | ||||
|   NET_API_STATUS nret; | ||||
|   WCHAR *buf; | ||||
|   DWORD size = INTERNET_MAX_HOST_NAME_LENGTH + 1; | ||||
|   WCHAR wdomain[size]; | ||||
|  | ||||
|   /* Empty domain is interpreted as local system */ | ||||
|   if ((GetComputerName (server + 2, &size)) && | ||||
| @@ -226,18 +235,37 @@ get_logon_server (const char *domain, char *server, WCHAR *wserver) | ||||
|       return true; | ||||
|     } | ||||
|  | ||||
|   /* Try to get the primary domain controller for the domain */ | ||||
|   sys_mbstowcs (wdomain, domain, INTERNET_MAX_HOST_NAME_LENGTH + 1); | ||||
|   if ((ret = NetGetDCName (NULL, wdomain, (LPBYTE *) &buf)) == STATUS_SUCCESS) | ||||
|   /* Try to get any available domain controller for this domain */ | ||||
|   dret = DsGetDcNameA (NULL, domain, NULL, NULL, | ||||
| 		       rediscovery ? DS_FORCE_REDISCOVERY : 0, &pci); | ||||
|   if (dret == ERROR_SUCCESS) | ||||
|     { | ||||
|       sys_wcstombs (server, INTERNET_MAX_HOST_NAME_LENGTH + 1, buf); | ||||
|       if (wserver) | ||||
| 	for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);) | ||||
| 	  ; | ||||
|       NetApiBufferFree (buf); | ||||
|       strcpy (server, pci->DomainControllerName); | ||||
|       sys_mbstowcs (wserver, server, INTERNET_MAX_HOST_NAME_LENGTH + 1); | ||||
|       NetApiBufferFree (pci); | ||||
|       debug_printf ("DC: rediscovery: %d, server: %s", rediscovery, server); | ||||
|       return true; | ||||
|     } | ||||
|   __seterrno_from_win_error (ret); | ||||
|   else if (dret == ERROR_PROC_NOT_FOUND) | ||||
|     { | ||||
|       /* NT4 w/o DSClient */ | ||||
|       sys_mbstowcs (wdomain, domain, INTERNET_MAX_HOST_NAME_LENGTH + 1); | ||||
|       if (rediscovery) | ||||
|         nret = NetGetAnyDCName (NULL, wdomain, (LPBYTE *) &buf); | ||||
|       else | ||||
| 	nret = NetGetDCName (NULL, wdomain, (LPBYTE *) &buf); | ||||
|       if (nret == NERR_Success) | ||||
| 	{ | ||||
| 	  sys_wcstombs (server, INTERNET_MAX_HOST_NAME_LENGTH + 1, buf); | ||||
| 	  if (wserver) | ||||
| 	    for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);) | ||||
| 	      ; | ||||
| 	  NetApiBufferFree (buf); | ||||
| 	  debug_printf ("NT: rediscovery: %d, server: %s", rediscovery, server); | ||||
| 	  return true; | ||||
| 	} | ||||
|     } | ||||
|   __seterrno_from_win_error (nret); | ||||
|   return false; | ||||
| } | ||||
|  | ||||
| @@ -473,7 +501,11 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps, | ||||
| 	grp_list += well_known_network_sid; | ||||
|       if (sid_in_token_groups (my_grps, well_known_batch_sid)) | ||||
| 	grp_list += well_known_batch_sid; | ||||
|       if (sid_in_token_groups (my_grps, well_known_interactive_sid)) | ||||
|       /* This is a problem on 2K3 (only domain controllers?!?) which only | ||||
|          enables tools for selected special groups.  A subauth token is | ||||
| 	 only NETWORK, but NETWORK has no access to these tools.  Therefore | ||||
| 	 we always add INTERACTIVE here. */ | ||||
|       /*if (sid_in_token_groups (my_grps, well_known_interactive_sid))*/ | ||||
| 	grp_list += well_known_interactive_sid; | ||||
|       if (sid_in_token_groups (my_grps, well_known_service_sid)) | ||||
| 	grp_list += well_known_service_sid; | ||||
| @@ -485,11 +517,13 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps, | ||||
|     } | ||||
|   if (get_ll (auth_luid) != 999LL) /* != SYSTEM_LUID */ | ||||
|     { | ||||
|       char buf[64]; | ||||
|       __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart, | ||||
| 		       auth_luid.LowPart); | ||||
|       grp_list += buf; | ||||
|       auth_pos = grp_list.count - 1; | ||||
|       for (DWORD i = 0; i < my_grps->GroupCount; ++i) | ||||
| 	if (my_grps->Groups[i].Attributes & SE_GROUP_LOGON_ID) | ||||
| 	  { | ||||
| 	    grp_list += my_grps->Groups[i].Sid; | ||||
| 	    auth_pos = grp_list.count - 1; | ||||
| 	    break; | ||||
| 	  } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -511,7 +545,9 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw) | ||||
|   grp_list += well_known_world_sid; | ||||
|   grp_list += well_known_authenticated_users_sid; | ||||
|   extract_nt_dom_user (pw, domain, user); | ||||
|   if (get_logon_server (domain, server, wserver)) | ||||
|   if (get_logon_server (domain, server, wserver, false) | ||||
|       && !get_user_groups (wserver, grp_list, user, domain) | ||||
|       && get_logon_server (domain, server, wserver, true)) | ||||
|     get_user_groups (wserver, grp_list, user, domain); | ||||
|   get_unix_group_sidlist (pw, grp_list); | ||||
|   return get_user_local_groups (grp_list, usersid); | ||||
| @@ -780,7 +816,8 @@ done: | ||||
| } | ||||
|  | ||||
| HANDLE | ||||
| create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) | ||||
| create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw, | ||||
| 	      HANDLE subauth_token) | ||||
| { | ||||
|   NTSTATUS ret; | ||||
|   LSA_HANDLE lsa = INVALID_HANDLE_VALUE; | ||||
| @@ -803,7 +840,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) | ||||
|   TOKEN_STATISTICS stats; | ||||
|   memcpy (source.SourceName, "Cygwin.1", 8); | ||||
|   source.SourceIdentifier.HighPart = 0; | ||||
|   source.SourceIdentifier.LowPart = 0x0101; | ||||
|   source.SourceIdentifier.LowPart = (subauth_token ? 0x0102 : 0x0101); | ||||
|  | ||||
|   HANDLE token = INVALID_HANDLE_VALUE; | ||||
|   HANDLE primary_token = INVALID_HANDLE_VALUE; | ||||
| @@ -824,33 +861,60 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) | ||||
|   owner.Owner = usersid; | ||||
|  | ||||
|   /* Retrieve authentication id and group list from own process. */ | ||||
|   if (hProcToken) | ||||
|   HANDLE get_token; | ||||
|   if (subauth_token) | ||||
|     { | ||||
|       debug_printf ("get_token = subauth_token"); | ||||
|       get_token = subauth_token; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       debug_printf ("get_token = hProcToken"); | ||||
|       get_token = hProcToken; | ||||
|     } | ||||
|   if (get_token) | ||||
|     { | ||||
|       /* Switching user context to SYSTEM doesn't inherit the authentication | ||||
| 	 id of the user account running current process. */ | ||||
|       if (usersid != well_known_system_sid) | ||||
| 	if (!GetTokenInformation (hProcToken, TokenStatistics, | ||||
| 	if (!GetTokenInformation (get_token, TokenStatistics, | ||||
| 				  &stats, sizeof stats, &size)) | ||||
| 	  debug_printf | ||||
| 	    ("GetTokenInformation(hProcToken, TokenStatistics), %E"); | ||||
| 	    ("GetTokenInformation(get_token, TokenStatistics), %E"); | ||||
| 	else | ||||
| 	  auth_luid = stats.AuthenticationId; | ||||
|  | ||||
|       /* Retrieving current processes group list to be able to inherit | ||||
| 	 some important well known group sids. */ | ||||
|       if (!GetTokenInformation (hProcToken, TokenGroups, NULL, 0, &size) && | ||||
| 	  GetLastError () != ERROR_INSUFFICIENT_BUFFER) | ||||
| 	debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E"); | ||||
|       if (!GetTokenInformation (get_token, TokenGroups, NULL, 0, &size) | ||||
| 	  && GetLastError () != ERROR_INSUFFICIENT_BUFFER) | ||||
| 	debug_printf ("GetTokenInformation(get_token, TokenGroups), %E"); | ||||
|       else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size))) | ||||
| 	debug_printf ("malloc (my_tok_gsids) failed."); | ||||
|       else if (!GetTokenInformation (hProcToken, TokenGroups, my_tok_gsids, | ||||
|       else if (!GetTokenInformation (get_token, TokenGroups, my_tok_gsids, | ||||
| 				     size, &size)) | ||||
| 	{ | ||||
| 	  debug_printf ("GetTokenInformation(hProcToken, TokenGroups), %E"); | ||||
| 	  debug_printf ("GetTokenInformation(get_token, TokenGroups), %E"); | ||||
| 	  free (my_tok_gsids); | ||||
| 	  my_tok_gsids = NULL; | ||||
| 	} | ||||
|     } | ||||
|   if (subauth_token) | ||||
|     { | ||||
|       if (!GetTokenInformation (subauth_token, TokenPrivileges, NULL, 0, &size) | ||||
| 	  && GetLastError () != ERROR_INSUFFICIENT_BUFFER) | ||||
| 	debug_printf ("GetTokenInformation(subauth_token, TokenPrivileges), %E"); | ||||
|       else if (!(privs = (PTOKEN_PRIVILEGES) malloc (size))) | ||||
| 	debug_printf ("malloc (privs) failed."); | ||||
|       else if (!GetTokenInformation (subauth_token, TokenPrivileges, privs, | ||||
| 				     size, &size)) | ||||
| 	{ | ||||
| 	  debug_printf ("GetTokenInformation(subauth_token, TokenPrivileges), %E"); | ||||
| 	  free (privs); | ||||
| 	  privs = NULL; | ||||
| 	} | ||||
|     } | ||||
|      | ||||
|  | ||||
|   /* Create list of groups, the user is member in. */ | ||||
|   int auth_pos; | ||||
| @@ -878,7 +942,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw) | ||||
|     new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID; | ||||
|  | ||||
|   /* Retrieve list of privileges of that user. */ | ||||
|   if (!(privs = get_priv_list (lsa, usersid, tmp_gsids))) | ||||
|   if (!privs && !(privs = get_priv_list (lsa, usersid, tmp_gsids))) | ||||
|     goto out; | ||||
|  | ||||
|   /* Let's be heroic... */ | ||||
| @@ -1299,7 +1363,7 @@ get_reg_security (HANDLE handle, security_descriptor &sd_ret) | ||||
| 				 | OWNER_SECURITY_INFORMATION, | ||||
| 				 sd_ret, &len); | ||||
|     } | ||||
|   if (ret != STATUS_SUCCESS) | ||||
|   if (ret != ERROR_SUCCESS) | ||||
|     { | ||||
|       __seterrno (); | ||||
|       return -1; | ||||
|   | ||||
| @@ -322,7 +322,8 @@ void __stdcall str2uni_cat (_UNICODE_STRING &, const char *) __attribute__ ((reg | ||||
| /* Try a subauthentication. */ | ||||
| HANDLE subauth (struct passwd *pw); | ||||
| /* Try creating a token directly. */ | ||||
| HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw); | ||||
| HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw, | ||||
| 		     HANDLE subauth_token); | ||||
| /* Verify an existing token */ | ||||
| bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL); | ||||
| /* Get groups of a user */ | ||||
| @@ -331,7 +332,8 @@ bool get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw); | ||||
| /* Extract U-domain\user field from passwd entry. */ | ||||
| void extract_nt_dom_user (const struct passwd *pw, char *domain, char *user); | ||||
| /* Get default logonserver for a domain. */ | ||||
| bool get_logon_server (const char * domain, char * server, WCHAR *wserver = NULL); | ||||
| bool get_logon_server (const char * domain, char * server, WCHAR *wserver, | ||||
| 		       bool rediscovery); | ||||
|  | ||||
| /* sec_helper.cc: Security helper functions. */ | ||||
| int set_privilege (HANDLE token, enum cygpriv_idx privilege, bool enable); | ||||
|   | ||||
| @@ -30,7 +30,6 @@ details. */ | ||||
| #define USE_SYS_TYPES_FD_SET | ||||
| #include <winsock.h> | ||||
| #include "cygerrno.h" | ||||
| #include "select.h" | ||||
| #include "security.h" | ||||
| #include "path.h" | ||||
| #include "fhandler.h" | ||||
| @@ -1260,105 +1259,69 @@ fhandler_base::select_except (select_record *s) | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| struct socketinf | ||||
|   { | ||||
|     cygthread *thread; | ||||
|     winsock_fd_set readfds, writefds, exceptfds; | ||||
|     SOCKET exitsock; | ||||
|     select_record *start; | ||||
|   }; | ||||
|  | ||||
| static int | ||||
| peek_socket (select_record *me, bool) | ||||
| { | ||||
|   winsock_fd_set ws_readfds, ws_writefds, ws_exceptfds; | ||||
|   struct timeval tv = {0, 0}; | ||||
|   WINSOCK_FD_ZERO (&ws_readfds); | ||||
|   WINSOCK_FD_ZERO (&ws_writefds); | ||||
|   WINSOCK_FD_ZERO (&ws_exceptfds); | ||||
|  | ||||
|   HANDLE h; | ||||
|   set_handle_or_return_if_not_open (h, me); | ||||
|   select_printf ("considering handle %p", h); | ||||
|  | ||||
|   if (me->read_selected && !me->read_ready) | ||||
|   fhandler_socket *fh = (fhandler_socket *) me->fh; | ||||
|   long events; | ||||
|   long evt_mask = (FD_CLOSE | ||||
| 		   | (me->read_selected ? (FD_READ | FD_ACCEPT) : 0) | ||||
| 		   | (me->write_selected ? (FD_WRITE | FD_CONNECT) : 0) | ||||
| 		   | (me->except_selected ? (FD_OOB | FD_CONNECT) : 0)); | ||||
|   int ret = fh->evaluate_events (evt_mask, events, false); | ||||
|   if (me->read_selected) | ||||
|     me->read_ready |= !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE)); | ||||
|   if (me->write_selected) | ||||
|     { | ||||
|       select_printf ("adding read fd_set %s, fd %d", me->fh->get_name (), | ||||
| 		     me->fd); | ||||
|       WINSOCK_FD_SET (h, &ws_readfds); | ||||
|     } | ||||
|   if (me->write_selected && !me->write_ready) | ||||
|     { | ||||
|       select_printf ("adding write fd_set %s, fd %d", me->fh->get_name (), | ||||
| 		     me->fd); | ||||
|       WINSOCK_FD_SET (h, &ws_writefds); | ||||
|     } | ||||
|   if ((me->except_selected || me->except_on_write) && !me->except_ready) | ||||
|     { | ||||
|       select_printf ("adding except fd_set %s, fd %d", me->fh->get_name (), | ||||
| 		     me->fd); | ||||
|       WINSOCK_FD_SET (h, &ws_exceptfds); | ||||
|     } | ||||
|   int r; | ||||
|   if ((me->read_selected && !me->read_ready) | ||||
|       || (me->write_selected && !me->write_ready) | ||||
|       || ((me->except_selected || me->except_on_write) && !me->except_ready)) | ||||
|     { | ||||
|       r = WINSOCK_SELECT (0, &ws_readfds, &ws_writefds, &ws_exceptfds, &tv); | ||||
|       select_printf ("WINSOCK_SELECT returned %d", r); | ||||
|       if (r == -1) | ||||
| 	{ | ||||
| 	  select_printf ("error %d", WSAGetLastError ()); | ||||
| 	  set_winsock_errno (); | ||||
| 	  return 0; | ||||
| 	} | ||||
|       if (WINSOCK_FD_ISSET (h, &ws_readfds)) | ||||
| 	me->read_ready = true; | ||||
|       if (WINSOCK_FD_ISSET (h, &ws_writefds)) | ||||
|       if ((events & FD_CONNECT) && !ret) | ||||
| 	me->write_ready = true; | ||||
|       if (WINSOCK_FD_ISSET (h, &ws_exceptfds)) | ||||
| 	me->except_ready = true; | ||||
|       else | ||||
| 	me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE)); | ||||
|     } | ||||
|   if (me->except_selected) | ||||
|     me->except_ready |= ret || !!(events & (FD_OOB | FD_CLOSE)); | ||||
|  | ||||
|   return me->read_ready || me->write_ready || me->except_ready; | ||||
| } | ||||
|  | ||||
| static int start_thread_socket (select_record *, select_stuff *); | ||||
|  | ||||
| struct socketinf | ||||
|   { | ||||
|     cygthread *thread; | ||||
|     int num_w4; | ||||
|     HANDLE w4[MAXIMUM_WAIT_OBJECTS]; | ||||
|     select_record *start; | ||||
|   }; | ||||
|  | ||||
| static DWORD WINAPI | ||||
| thread_socket (void *arg) | ||||
| { | ||||
|   socketinf *si = (socketinf *) arg; | ||||
|   bool event = false; | ||||
|  | ||||
|   select_printf ("stuff_start %p", &si->start); | ||||
|   int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL); | ||||
|   select_printf ("Win32 select returned %d", r); | ||||
|   if (r == -1) | ||||
|     select_printf ("error %d", WSAGetLastError ()); | ||||
|   select_record *s = si->start; | ||||
|   while ((s = s->next)) | ||||
|     if (s->startup == start_thread_socket) | ||||
| 	{ | ||||
| 	  HANDLE h = s->fh->get_handle (); | ||||
| 	  select_printf ("s %p, testing fd %d (%s)", s, s->fd, s->fh->get_name ()); | ||||
| 	  if (WINSOCK_FD_ISSET (h, &si->readfds)) | ||||
|   select_printf ("stuff_start %p", si->start); | ||||
|   while (!event) | ||||
|     { | ||||
|       for (select_record *s = si->start; (s = s->next); ) | ||||
| 	if (s->startup == start_thread_socket) | ||||
| 	  if (peek_socket (s, false)) | ||||
| 	    event = true; | ||||
|       if (!event) | ||||
|         { | ||||
| 	  switch (WaitForMultipleObjects (si->num_w4, si->w4, FALSE, 50)) | ||||
| 	    { | ||||
| 	      select_printf ("read_ready"); | ||||
| 	      s->read_ready = true; | ||||
| 	    } | ||||
| 	  if (WINSOCK_FD_ISSET (h, &si->writefds)) | ||||
| 	    { | ||||
| 	      select_printf ("write_ready"); | ||||
| 	      s->write_ready = true; | ||||
| 	    } | ||||
| 	  if (WINSOCK_FD_ISSET (h, &si->exceptfds)) | ||||
| 	    { | ||||
| 	      select_printf ("except_ready"); | ||||
| 	      s->except_ready = true; | ||||
| 	    case WAIT_OBJECT_0: | ||||
| 	    case WAIT_FAILED: | ||||
| 	      goto out; | ||||
| 	    case WAIT_TIMEOUT: | ||||
| 	    default: | ||||
| 	      break; | ||||
| 	    } | ||||
| 	} | ||||
|  | ||||
|   if (WINSOCK_FD_ISSET (si->exitsock, &si->readfds)) | ||||
|     select_printf ("saw exitsock read"); | ||||
|     } | ||||
| out: | ||||
|   select_printf ("leaving thread_socket"); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -1374,68 +1337,29 @@ start_thread_socket (select_record *me, select_stuff *stuff) | ||||
|     } | ||||
|  | ||||
|   si = new socketinf; | ||||
|   WINSOCK_FD_ZERO (&si->readfds); | ||||
|   WINSOCK_FD_ZERO (&si->writefds); | ||||
|   WINSOCK_FD_ZERO (&si->exceptfds); | ||||
|   select_record *s = &stuff->start; | ||||
|   if (_my_tls.locals.select_sockevt != INVALID_HANDLE_VALUE) | ||||
|     si->w4[0] = _my_tls.locals.select_sockevt; | ||||
|   else if (!(si->w4[0] = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL))) | ||||
|     return 1; | ||||
|   else | ||||
|     _my_tls.locals.select_sockevt = si->w4[0]; | ||||
|   si->num_w4 = 1; | ||||
|   while ((s = s->next)) | ||||
|     if (s->startup == start_thread_socket) | ||||
|       { | ||||
| 	HANDLE h = s->fh->get_handle (); | ||||
| 	select_printf ("Handle %p", h); | ||||
| 	if (s->read_selected && !s->read_ready) | ||||
| 	  { | ||||
| 	    WINSOCK_FD_SET (h, &si->readfds); | ||||
| 	    select_printf ("Added to readfds"); | ||||
| 	  } | ||||
| 	if (s->write_selected && !s->write_ready) | ||||
| 	  { | ||||
| 	    WINSOCK_FD_SET (h, &si->writefds); | ||||
| 	    select_printf ("Added to writefds"); | ||||
| 	  } | ||||
| 	if ((s->except_selected || s->except_on_write) && !s->except_ready) | ||||
| 	  { | ||||
| 	    WINSOCK_FD_SET (h, &si->exceptfds); | ||||
| 	    select_printf ("Added to exceptfds"); | ||||
| 	  } | ||||
| 	HANDLE evt = ((fhandler_socket *) me->fh)->wsock_evt; | ||||
| 	/* No event/socket should show up multiple times. */ | ||||
| 	for (int i = 1; i < si->num_w4; ++i) | ||||
| 	  if (si->w4[i] == evt) | ||||
| 	    goto continue_outer_loop; | ||||
| 	if (si->num_w4 < MAXIMUM_WAIT_OBJECTS) | ||||
| 	  si->w4[si->num_w4++] = evt; | ||||
| 	else /* for now */ | ||||
| 	  goto err; | ||||
|       continue_outer_loop: | ||||
| 	; | ||||
|       } | ||||
|  | ||||
|   if (_my_tls.locals.exitsock != INVALID_SOCKET) | ||||
|     si->exitsock = _my_tls.locals.exitsock; | ||||
|   else | ||||
|     { | ||||
|       si->exitsock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||||
|       if (si->exitsock == INVALID_SOCKET) | ||||
| 	{ | ||||
| 	  set_winsock_errno (); | ||||
| 	  select_printf ("cannot create socket, %E"); | ||||
| 	  return 0; | ||||
| 	} | ||||
|       int sin_len = sizeof (_my_tls.locals.exitsock_sin); | ||||
|       memset (&_my_tls.locals.exitsock_sin, 0, sin_len); | ||||
|       _my_tls.locals.exitsock_sin.sin_family = AF_INET; | ||||
|       _my_tls.locals.exitsock_sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK); | ||||
|       if (bind (si->exitsock, (struct sockaddr *) &_my_tls.locals.exitsock_sin, sin_len) < 0) | ||||
| 	{ | ||||
| 	  select_printf ("cannot bind socket %p, %E", si->exitsock); | ||||
| 	  goto err; | ||||
| 	} | ||||
|  | ||||
|       if (getsockname (si->exitsock, (struct sockaddr *) &_my_tls.locals.exitsock_sin, &sin_len) < 0) | ||||
| 	{ | ||||
| 	  select_printf ("getsockname error"); | ||||
| 	  goto err; | ||||
| 	} | ||||
|       if (wincap.has_set_handle_information ()) | ||||
| 	SetHandleInformation ((HANDLE) si->exitsock, HANDLE_FLAG_INHERIT, 0); | ||||
|       /* else | ||||
| 	   too bad? */ | ||||
|       select_printf ("opened new socket %p", si->exitsock); | ||||
|       _my_tls.locals.exitsock = si->exitsock; | ||||
|     } | ||||
|  | ||||
|   select_printf ("exitsock %p", si->exitsock); | ||||
|   WINSOCK_FD_SET ((HANDLE) si->exitsock, &si->readfds); | ||||
|   stuff->device_specific_socket = (void *) si; | ||||
|   si->start = &stuff->start; | ||||
|   select_printf ("stuff_start %p", &stuff->start); | ||||
| @@ -1444,8 +1368,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) | ||||
|   return 1; | ||||
|  | ||||
| err: | ||||
|   set_winsock_errno (); | ||||
|   closesocket (si->exitsock); | ||||
|   CloseHandle (si->w4[0]); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| @@ -1456,17 +1379,10 @@ socket_cleanup (select_record *, select_stuff *stuff) | ||||
|   select_printf ("si %p si->thread %p", si, si ? si->thread : NULL); | ||||
|   if (si && si->thread) | ||||
|     { | ||||
|       char buf[] = ""; | ||||
|       int res = sendto (_my_tls.locals.exitsock, buf, 1, 0, | ||||
| 			(sockaddr *) &_my_tls.locals.exitsock_sin, | ||||
| 			sizeof (_my_tls.locals.exitsock_sin)); | ||||
|       select_printf ("sent a byte to exitsock %p, res %d", _my_tls.locals.exitsock, res); | ||||
|       SetEvent (si->w4[0]); | ||||
|       /* Wait for thread to go away */ | ||||
|       si->thread->detach (); | ||||
|       /* empty the socket */ | ||||
|       select_printf ("reading a byte from exitsock %p", si->exitsock); | ||||
|       res = recv (si->exitsock, buf, 1, 0); | ||||
|       select_printf ("recv returned %d", res); | ||||
|       ResetEvent (si->w4[0]); | ||||
|       stuff->device_specific_socket = NULL; | ||||
|       delete si; | ||||
|     } | ||||
|   | ||||
| @@ -1,55 +0,0 @@ | ||||
| /* select.h | ||||
|  | ||||
|    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004 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. */ | ||||
|  | ||||
| /* Winsock select() types and macros */ | ||||
|  | ||||
| /* | ||||
|  * Use this struct to interface to | ||||
|  * the system provided select. | ||||
|  */ | ||||
| typedef struct winsock_fd_set | ||||
| { | ||||
|   unsigned int fd_count; | ||||
|   HANDLE fd_array[1024]; /* Dynamically allocated. */ | ||||
| } winsock_fd_set; | ||||
|  | ||||
| /* | ||||
|  * Define the Win32 winsock definitions to have a prefix WINSOCK_ | ||||
|  * so we can be explicit when we are using them. | ||||
|  */ | ||||
| #define WINSOCK_FD_ISSET(fd, set) __WSAFDIsSet ((SOCKET)fd, (fd_set *)set) | ||||
| #define WINSOCK_FD_SET(fd, set) do { \ | ||||
| 	       (set)->fd_array[(set)->fd_count++]=fd;\ | ||||
| } while(0) | ||||
| #define WINSOCK_FD_ZERO(set) ((set)->fd_count = 0) | ||||
| #define WINSOCK_FD_CLR(fd, set) do { \ | ||||
|     u_int __i; \ | ||||
|     for (__i = 0; __i < (set)->fd_count ; __i++) { \ | ||||
| 	if ((set)->fd_array[__i] == fd) { \ | ||||
| 	    while (__i < (set)->fd_count-1) { \ | ||||
| 		(set)->fd_array[__i] = \ | ||||
| 		    (set)->fd_array[__i+1]; \ | ||||
| 		__i++; \ | ||||
| 	    } \ | ||||
| 	    (set)->fd_count--; \ | ||||
| 	    break; \ | ||||
| 	} \ | ||||
|     } \ | ||||
| } while(0) | ||||
|  | ||||
| extern "C" int PASCAL __WSAFDIsSet(SOCKET, fd_set*); | ||||
| extern "C" int PASCAL win32_select(int, fd_set*, fd_set*, fd_set*, const struct timeval*); | ||||
|  | ||||
| /* | ||||
|  * call to winsock's select() - | ||||
|  * type coercion need to appease confused prototypes | ||||
|  */ | ||||
| #define WINSOCK_SELECT(nfd, rd, wr, ex, timeo) \ | ||||
|   win32_select (nfd, (fd_set *) rd, (fd_set *) wr, (fd_set *) ex, timeo) | ||||
| @@ -2172,18 +2172,29 @@ seteuid32 (__uid32_t uid) | ||||
|      authenticate using NtCreateToken () or subauthentication. */ | ||||
|   if (new_token == INVALID_HANDLE_VALUE) | ||||
|     { | ||||
|       new_token = create_token (usersid, groups, pw_new); | ||||
|       new_token = subauth (pw_new); | ||||
|       if (new_token == INVALID_HANDLE_VALUE) | ||||
| 	{ | ||||
| 	  /* create_token failed. Try subauthentication. */ | ||||
| 	  debug_printf ("create token failed, try subauthentication."); | ||||
| 	  new_token = subauth (pw_new); | ||||
| 	  debug_printf ("subauthentication failed, try create token."); | ||||
| 	  new_token = create_token (usersid, groups, pw_new, NULL); | ||||
| 	  if (new_token == INVALID_HANDLE_VALUE) | ||||
| 	    { | ||||
| 	      cygheap->user.reimpersonate (); | ||||
| 	      return -1; | ||||
| 	    } | ||||
| 	} | ||||
|       else | ||||
|         { | ||||
| 	  debug_printf ("subauthentication succeeded, try create token."); | ||||
| 	  HANDLE new_token2 = create_token (usersid, groups, pw_new, new_token); | ||||
| 	  if (new_token2 == INVALID_HANDLE_VALUE) | ||||
| 	    debug_printf ("create token failed, use original token"); | ||||
| 	  else | ||||
| 	    { | ||||
| 	      CloseHandle (new_token); | ||||
| 	      new_token = new_token2; | ||||
| 	    } | ||||
| 	} | ||||
|       /* Keep at most one internal token */ | ||||
|       if (cygheap->user.internal_token != NO_IMPERSONATION) | ||||
| 	CloseHandle (cygheap->user.internal_token); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| //;# autogenerated:  Do not edit. | ||||
|  | ||||
| //; $tls::sizeof__cygtls = 4212; | ||||
| //; $tls::sizeof__cygtls = 4196; | ||||
| //; $tls::func = -12700; | ||||
| //; $tls::pfunc = 0; | ||||
| //; $tls::el = -12696; | ||||
| @@ -39,30 +39,30 @@ | ||||
| //; $tls::p__dontuse = 420; | ||||
| //; $tls::locals = -11216; | ||||
| //; $tls::plocals = 1484; | ||||
| //; $tls::_ctinfo = -9584; | ||||
| //; $tls::p_ctinfo = 3116; | ||||
| //; $tls::andreas = -9580; | ||||
| //; $tls::pandreas = 3120; | ||||
| //; $tls::wq = -9572; | ||||
| //; $tls::pwq = 3128; | ||||
| //; $tls::prev = -9544; | ||||
| //; $tls::pprev = 3156; | ||||
| //; $tls::next = -9540; | ||||
| //; $tls::pnext = 3160; | ||||
| //; $tls::sig = -9536; | ||||
| //; $tls::psig = 3164; | ||||
| //; $tls::incyg = -9532; | ||||
| //; $tls::pincyg = 3168; | ||||
| //; $tls::spinning = -9528; | ||||
| //; $tls::pspinning = 3172; | ||||
| //; $tls::stacklock = -9524; | ||||
| //; $tls::pstacklock = 3176; | ||||
| //; $tls::stackptr = -9520; | ||||
| //; $tls::pstackptr = 3180; | ||||
| //; $tls::stack = -9516; | ||||
| //; $tls::pstack = 3184; | ||||
| //; $tls::initialized = -8492; | ||||
| //; $tls::pinitialized = 4208; | ||||
| //; $tls::_ctinfo = -9600; | ||||
| //; $tls::p_ctinfo = 3100; | ||||
| //; $tls::andreas = -9596; | ||||
| //; $tls::pandreas = 3104; | ||||
| //; $tls::wq = -9588; | ||||
| //; $tls::pwq = 3112; | ||||
| //; $tls::prev = -9560; | ||||
| //; $tls::pprev = 3140; | ||||
| //; $tls::next = -9556; | ||||
| //; $tls::pnext = 3144; | ||||
| //; $tls::sig = -9552; | ||||
| //; $tls::psig = 3148; | ||||
| //; $tls::incyg = -9548; | ||||
| //; $tls::pincyg = 3152; | ||||
| //; $tls::spinning = -9544; | ||||
| //; $tls::pspinning = 3156; | ||||
| //; $tls::stacklock = -9540; | ||||
| //; $tls::pstacklock = 3160; | ||||
| //; $tls::stackptr = -9536; | ||||
| //; $tls::pstackptr = 3164; | ||||
| //; $tls::stack = -9532; | ||||
| //; $tls::pstack = 3168; | ||||
| //; $tls::initialized = -8508; | ||||
| //; $tls::pinitialized = 4192; | ||||
| //; __DATA__ | ||||
|  | ||||
| #define tls_func (-12700) | ||||
| @@ -103,27 +103,27 @@ | ||||
| #define tls_p__dontuse (420) | ||||
| #define tls_locals (-11216) | ||||
| #define tls_plocals (1484) | ||||
| #define tls__ctinfo (-9584) | ||||
| #define tls_p_ctinfo (3116) | ||||
| #define tls_andreas (-9580) | ||||
| #define tls_pandreas (3120) | ||||
| #define tls_wq (-9572) | ||||
| #define tls_pwq (3128) | ||||
| #define tls_prev (-9544) | ||||
| #define tls_pprev (3156) | ||||
| #define tls_next (-9540) | ||||
| #define tls_pnext (3160) | ||||
| #define tls_sig (-9536) | ||||
| #define tls_psig (3164) | ||||
| #define tls_incyg (-9532) | ||||
| #define tls_pincyg (3168) | ||||
| #define tls_spinning (-9528) | ||||
| #define tls_pspinning (3172) | ||||
| #define tls_stacklock (-9524) | ||||
| #define tls_pstacklock (3176) | ||||
| #define tls_stackptr (-9520) | ||||
| #define tls_pstackptr (3180) | ||||
| #define tls_stack (-9516) | ||||
| #define tls_pstack (3184) | ||||
| #define tls_initialized (-8492) | ||||
| #define tls_pinitialized (4208) | ||||
| #define tls__ctinfo (-9600) | ||||
| #define tls_p_ctinfo (3100) | ||||
| #define tls_andreas (-9596) | ||||
| #define tls_pandreas (3104) | ||||
| #define tls_wq (-9588) | ||||
| #define tls_pwq (3112) | ||||
| #define tls_prev (-9560) | ||||
| #define tls_pprev (3140) | ||||
| #define tls_next (-9556) | ||||
| #define tls_pnext (3144) | ||||
| #define tls_sig (-9552) | ||||
| #define tls_psig (3148) | ||||
| #define tls_incyg (-9548) | ||||
| #define tls_pincyg (3152) | ||||
| #define tls_spinning (-9544) | ||||
| #define tls_pspinning (3156) | ||||
| #define tls_stacklock (-9540) | ||||
| #define tls_pstacklock (3160) | ||||
| #define tls_stackptr (-9536) | ||||
| #define tls_pstackptr (3164) | ||||
| #define tls_stack (-9532) | ||||
| #define tls_pstack (3168) | ||||
| #define tls_initialized (-8508) | ||||
| #define tls_pinitialized (4192) | ||||
|   | ||||
| @@ -27,6 +27,12 @@ details. */ | ||||
|  | ||||
| extern fhandler_tty_master *tty_master; | ||||
|  | ||||
| extern "C" int | ||||
| posix_openpt (int oflags) | ||||
| { | ||||
|   return open ("/dev/ptmx", oflags); | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| grantpt (int fd) | ||||
| { | ||||
|   | ||||
| @@ -377,7 +377,7 @@ cygheap_user::env_logsrv (const char *name, size_t namelen) | ||||
|  | ||||
|   char logsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3]; | ||||
|   cfree_and_set (plogsrv, almost_null); | ||||
|   if (get_logon_server (mydomain, logsrv, NULL)) | ||||
|   if (get_logon_server (mydomain, logsrv, NULL, false)) | ||||
|     plogsrv = cstrdup (logsrv); | ||||
|   return plogsrv; | ||||
| } | ||||
|   | ||||
| @@ -299,7 +299,13 @@ size_t getsystempagesize (); | ||||
|  | ||||
| /* mmap functions. */ | ||||
| void mmap_init (); | ||||
| int mmap_is_attached_or_noreserve_page (ULONG_PTR addr); | ||||
| enum mmap_region_status | ||||
|   { | ||||
|     MMAP_NONE, | ||||
|     MMAP_RAISE_SIGBUS, | ||||
|     MMAP_NORESERVE_COMMITED | ||||
|   }; | ||||
| mmap_region_status mmap_is_attached_or_noreserve (void *addr, size_t len); | ||||
|  | ||||
| int winprio_to_nice (DWORD) __attribute__ ((regparm (1))); | ||||
| DWORD nice_to_winprio (int &) __attribute__ ((regparm (1))); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user