mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-30 08:19:09 +00:00
Bring in a hybrid of SunSoft's transport-independent RPC (TI-RPC) and
associated changes that had to happen to make this possible as well as bugs fixed along the way. Bring in required TLI library routines to support this. Since we don't support TLI we've essentially copied what NetBSD has done, adding a thin layer to emulate direct the TLI calls into BSD socket calls. This is mostly from Sun's tirpc release that was made in 1994, however some fixes were backported from the 1999 release (supposedly only made available after this porting effort was underway). The submitter has agreed to continue on and bring us up to the 1999 release. Several key features are introduced with this update: Client calls are thread safe. (1999 code has server side thread safe) Updated, a more modern interface. Many userland updates were done to bring the code up to par with the recent RPC API. There is an update to the pthreads library, a function pthread_main_np() was added to emulate a function of Sun's threads library. While we're at it, bring in NetBSD's lockd, it's been far too long of a wait. New rpcbind(8) replaces portmap(8) (supporting communication over an authenticated Unix-domain socket, and by default only allowing set and unset requests over that channel). It's much more secure than the old portmapper. Umount(8), mountd(8), mount_nfs(8), nfsd(8) have also been upgraded to support TI-RPC and to support IPV6. Umount(8) is also fixed to unmount pathnames longer than 80 chars, which are currently truncated by the Kernel statfs structure. Submitted by: Martin Blapp <mb@imp.ch> Manpage review: ru Secure RPC implemented by: wpaul
This commit is contained in:
parent
1ac2b9fe97
commit
8360efbd6c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=74462
@ -10,7 +10,7 @@ BIN1= amd.map apmd.conf auth.conf \
|
||||
dhclient.conf dm.conf fbtab ftpusers gettytab group \
|
||||
hosts hosts.allow hosts.equiv hosts.lpd \
|
||||
inetd.conf login.access login.conf \
|
||||
motd modems networks newsyslog.conf \
|
||||
motd modems netconfig networks newsyslog.conf \
|
||||
pam.conf phones pim6dd.conf pim6sd.conf \
|
||||
printcap profile protocols \
|
||||
rc rc.atm rc.devfs rc.diskless1 rc.diskless2 rc.firewall rc.firewall6 \
|
||||
|
@ -101,7 +101,7 @@ ppp_nat="YES" # Use PPP's internal network address translation or NO.
|
||||
ppp_profile="papchap" # Which profile to use from /etc/ppp/ppp.conf.
|
||||
ppp_user="root" # Which user to run ppp as
|
||||
|
||||
### Network daemon (miscellaneous) & NFS options: ###
|
||||
### Network daemon (miscellaneous) ###
|
||||
syslogd_enable="YES" # Run syslog daemon (or NO).
|
||||
syslogd_flags="-s" # Flags to syslogd (if enabled).
|
||||
inetd_enable="NO" # Run the network daemon dispatcher (YES/NO).
|
||||
@ -121,6 +121,19 @@ kadmind_server_enable="NO" # Run kadmind (or NO) -- do not run on
|
||||
kerberos_stash="" # Is the kerberos master key stashed?
|
||||
rwhod_enable="NO" # Run the rwho daemon (or NO).
|
||||
rwhod_flags="" # Flags for rwhod
|
||||
rarpd_enable="NO" # Run rarpd (or NO).
|
||||
rarpd_flags="" # Flags to rarpd.
|
||||
xtend_enable="NO" # Run the X-10 power controller daemon.
|
||||
xtend_flags="" # Flags to xtend (if enabled).
|
||||
pppoed_enable="NO" # Run the PPP over Ethernet daemon.
|
||||
pppoed_provider="*" # Provider and ppp(8) config file entry.
|
||||
pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled).
|
||||
pppoed_interface="fxp0" # The interface that pppoed runs on.
|
||||
sshd_enable="NO" # Enable sshd
|
||||
sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one.
|
||||
sshd_flags="" # Additional flags for sshd.
|
||||
|
||||
### Network daemon (NFS) Need all portmap_enable="YES" ###
|
||||
amd_enable="NO" # Run amd service with $amd_flags (or NO).
|
||||
amd_flags="-a /.amd_mnt -l syslog /host /etc/amd.map /net /etc/amd.map"
|
||||
amd_map_program="NO" # Can be set to "ypcat -k amd.master"
|
||||
@ -135,24 +148,13 @@ weak_mountd_authentication="NO" # Allow non-root mount requests to be served.
|
||||
nfs_reserved_port_only="NO" # Provide NFS only on secure port (or NO).
|
||||
nfs_bufpackets="DEFAULT" # bufspace (in packets) for client (or DEFAULT)
|
||||
rpc_lockd_enable="NO" # Run NFS rpc.lockd (*broken!*) if nfs_server.
|
||||
rpc_statd_enable="YES" # Run NFS rpc.statd if nfs_server (or NO).
|
||||
rpc_statd_enable="NO" # Run NFS rpc.statd if nfs_server (or NO).
|
||||
portmap_enable="NO" # Run the portmapper service (YES/NO).
|
||||
portmap_program="/usr/sbin/portmap" # path to portmap, if you want a different one.
|
||||
portmap_program="/usr/sbin/rpcbind" # path to portmap, if you want a different one.
|
||||
portmap_flags="" # Flags to portmap (if enabled).
|
||||
rpc_ypupdated_enable="NO" # Run if NIS master and SecureRPC (or NO).
|
||||
keyserv_enable="NO" # Run the SecureRPC keyserver (or NO).
|
||||
keyserv_flags="" # Flags to keyserv (if enabled).
|
||||
rarpd_enable="NO" # Run rarpd (or NO).
|
||||
rarpd_flags="" # Flags to rarpd.
|
||||
xtend_enable="NO" # Run the X-10 power controller daemon.
|
||||
xtend_flags="" # Flags to xtend (if enabled).
|
||||
pppoed_enable="NO" # Run the PPP over Ethernet daemon.
|
||||
pppoed_provider="*" # Provider and ppp(8) config file entry.
|
||||
pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled).
|
||||
pppoed_interface="fxp0" # The interface that pppoed runs on.
|
||||
sshd_enable="NO" # Enable sshd
|
||||
sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one.
|
||||
sshd_flags="" # Additional flags for sshd.
|
||||
|
||||
### Network Time Services options: ###
|
||||
timed_enable="NO" # Run the time daemon (or NO).
|
||||
@ -164,7 +166,7 @@ xntpd_enable="NO" # Run ntpd Network Time Protocol (or NO).
|
||||
xntpd_program="ntpd" # path to ntpd, if you want a different one.
|
||||
xntpd_flags="-p /var/run/ntpd.pid" # Flags to ntpd (if enabled).
|
||||
|
||||
# Network Information Services (NIS) options: ###
|
||||
# Network Information Services (NIS) options: Need all portmap_enable="YES" ###
|
||||
nis_client_enable="NO" # We're an NIS client (or NO).
|
||||
nis_client_flags="" # Flags to ypbind (if enabled).
|
||||
nis_ypset_enable="NO" # Run ypset at boot time (or NO).
|
||||
|
17
etc/netconfig
Normal file
17
etc/netconfig
Normal file
@ -0,0 +1,17 @@
|
||||
# The network configuration file. This file is currently only used in
|
||||
# conjunction with the (TI-) RPC code in the C library, unlike its
|
||||
# use in SVR4.
|
||||
#
|
||||
# Entries consist of:
|
||||
#
|
||||
# <network_id> <semantics> <flags> <protofamily> <protoname> \
|
||||
# <device> <nametoaddr_libs>
|
||||
#
|
||||
# The <device> and <nametoaddr_libs> fields are always empty in FreeBSD.
|
||||
#
|
||||
udp6 tpi_clts v inet6 udp - -
|
||||
tcp6 tpi_cots_ord v inet6 tcp - -
|
||||
udp tpi_clts v inet udp - -
|
||||
tcp tpi_cots_ord v inet tcp - -
|
||||
rawip tpi_raw - inet - - -
|
||||
unix tpi_cots_ord - loopback - - -
|
234
etc/network.subr
234
etc/network.subr
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
234
etc/rc.d/routing
234
etc/rc.d/routing
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
234
etc/rc.network
234
etc/rc.network
@ -514,59 +514,61 @@ network_pass2() {
|
||||
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' portmap'; ${portmap_program:-/usr/sbin/portmap} ${portmap_flags}
|
||||
;;
|
||||
esac
|
||||
echo -n ' rpcbind'; ${portmap_program:-/usr/sbin/rpcbind} \
|
||||
${portmap_flags}
|
||||
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
# Start ypserv if we're an NIS server.
|
||||
# Run rpc.ypxfrd and rpc.yppasswdd only on the NIS master server.
|
||||
#
|
||||
case ${nis_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
echo -n ' ypserv'; ypserv ${nis_server_flags}
|
||||
|
||||
case ${nis_ypxfrd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypxfrd'
|
||||
rpc.ypxfrd ${nis_ypxfrd_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nis_yppasswdd_enable} in
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.yppasswdd'
|
||||
rpc.yppasswdd ${nis_yppasswdd_flags}
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypbind if we're an NIS client
|
||||
#
|
||||
case ${nis_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypbind'; ypbind ${nis_client_flags}
|
||||
case ${nis_ypset_enable} in
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' ypset'; ypset ${nis_ypset_flags}
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start keyserv if we are running Secure RPC
|
||||
#
|
||||
case ${keyserv_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' keyserv'; keyserv ${keyserv_flags}
|
||||
;;
|
||||
esac
|
||||
|
||||
# Start ypupdated if we are running Secure RPC and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
# Start ypupdated if we are running Secure RPC
|
||||
# and we are NIS master
|
||||
#
|
||||
case ${rpc_ypupdated_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.ypupdated'; rpc.ypupdated
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -582,99 +584,103 @@ network_pass2() {
|
||||
network_pass3() {
|
||||
echo -n 'Starting final network daemons:'
|
||||
|
||||
case ${nfs_server_enable} in
|
||||
case ${portmap_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 >/dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} \
|
||||
> /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
case ${nfs_server_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
mountd_flags="${mountd_flags} -n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
|
||||
case ${nfs_reserved_port_only} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' NFS on reserved port only=YES'
|
||||
sysctl -w vfs.nfs.nfs_privport=1 > /dev/null
|
||||
;;
|
||||
esac
|
||||
|
||||
echo -n ' nfsd'; nfsd ${nfs_server_flags}
|
||||
|
||||
if [ -n "${nfs_bufpackets}" ]; then
|
||||
sysctl -w vfs.nfs.bufpackets=${nfs_bufpackets} > /dev/null
|
||||
fi
|
||||
|
||||
case ${rpc_lockd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.lockd'; rpc.lockd
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${rpc_statd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' rpc.statd'; rpc.statd
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case ${single_mountd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
if [ -r /etc/exports ]; then
|
||||
echo -n ' mountd'
|
||||
|
||||
case ${weak_mountd_authentication} in
|
||||
[Yy][Ee][Ss])
|
||||
mountd_flags="-n"
|
||||
;;
|
||||
esac
|
||||
|
||||
mountd ${mountd_flags}
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} >/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
case ${nfs_client_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' nfsiod'; nfsiod ${nfs_client_flags}
|
||||
if [ -n "${nfs_access_cache}" ]; then
|
||||
echo -n " NFS access cache time=${nfs_access_cache}"
|
||||
sysctl -w vfs.nfs.access_cache_timeout=${nfs_access_cache} \
|
||||
>/dev/null
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# If /var/db/mounttab exists, some nfs-server has not been
|
||||
# sucessfully notified about a previous client shutdown.
|
||||
# If there is no /var/db/mounttab, we do nothing.
|
||||
if [ -f /var/db/mounttab ]; then
|
||||
rpc.umntall -k
|
||||
fi
|
||||
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval ${amd_map_program}`"
|
||||
;;
|
||||
case ${amd_enable} in
|
||||
[Yy][Ee][Ss])
|
||||
echo -n ' amd'
|
||||
case ${amd_map_program} in
|
||||
[Nn][Oo] | '')
|
||||
;;
|
||||
*)
|
||||
amd_flags="${amd_flags} `eval\
|
||||
${amd_map_program}`"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags} > /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
if [ -n "${amd_flags}" ]; then
|
||||
amd -p ${amd_flags}\
|
||||
> /var/run/amd.pid 2> /dev/null
|
||||
else
|
||||
amd 2> /dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
|
37
etc/rpc
37
etc/rpc
@ -1,8 +1,8 @@
|
||||
#
|
||||
# $FreeBSD$
|
||||
# rpc 88/08/01 4.0 RPCSRC; from 1.12 88/02/07 SMI
|
||||
# rpc 88/08/01 4.0 RPCSRC; from 1.12 99/07/25 SMI
|
||||
#
|
||||
portmapper 100000 portmap sunrpc
|
||||
rpcbind 100000 portmap sunrpc rpcbind
|
||||
rstatd 100001 rstat rstat_svc rup perfmeter
|
||||
rusersd 100002 rusers
|
||||
nfs 100003 nfsprog
|
||||
@ -29,10 +29,39 @@ status 100024
|
||||
bootparamd 100026 bootparam
|
||||
ypupdated 100028 ypupdate
|
||||
keyserv 100029 keyserver
|
||||
sunlink_mapper 100033
|
||||
tfsd 100037
|
||||
nsed 100038
|
||||
nsemntd 100039
|
||||
showfhd 100043 showfh
|
||||
ioadmd 100055 rpc.ioadmd
|
||||
NETlicense 100062
|
||||
sunisamd 100065
|
||||
debug_svc 100066 dbsrv
|
||||
cmsd 100068
|
||||
bugtraqd 100071
|
||||
kerbd 100078
|
||||
ttdbserver 100083 tooltalk
|
||||
event 100101 na.event # SunNet Manager
|
||||
logger 100102 na.logger # SunNet Manager
|
||||
sync 100104 na.sync
|
||||
hostperf 100107 na.hostperf
|
||||
activity 100109 na.activity # SunNet Manager
|
||||
hostmem 100112 na.hostmem
|
||||
sample 100113 na.sample
|
||||
x25 100114 na.x25
|
||||
ping 100115 na.ping
|
||||
rpcnfs 100116 na.rpcnfs
|
||||
hostif 100117 na.hostif
|
||||
etherif 100118 na.etherif
|
||||
iproutes 100120 na.iproutes
|
||||
layers 100121 na.layers
|
||||
snmp 100122 na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk
|
||||
traffic 100123 na.traffic
|
||||
nfs_acl 100227
|
||||
sadmind 100232
|
||||
nisd 100300 rpc.nisd
|
||||
nispasswd 100303 rpc.nispasswdd
|
||||
ufsd 100233 ufsd
|
||||
pcnfsd 150001 pcnfs
|
||||
amd 300019
|
||||
cmsd 100068
|
||||
ttdbserver 100083 tooltalk
|
||||
|
@ -7,13 +7,13 @@
|
||||
# links.
|
||||
|
||||
CLEANFILES= osreldate.h version vers.c
|
||||
SUBDIR= rpcsvc
|
||||
SUBDIR= rpcsvc rpc
|
||||
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
|
||||
dlfcn.h elf.h err.h fnmatch.h fstab.h \
|
||||
fts.h glob.h grp.h strhash.h \
|
||||
hesiod.h histedit.h ieeefp.h ifaddrs.h iso646.h langinfo.h \
|
||||
libgen.h limits.h link.h locale.h malloc.h memory.h mpool.h \
|
||||
ndbm.h netdb.h nl_types.h nlist.h nsswitch.h objformat.h \
|
||||
netconfig.h ndbm.h netdb.h nl_types.h nlist.h nsswitch.h objformat.h \
|
||||
paths.h pthread.h pthread_np.h pwd.h \
|
||||
ranlib.h regex.h regexp.h resolv.h rune.h runetype.h \
|
||||
search.h setjmp.h sgtty.h \
|
||||
@ -28,10 +28,6 @@ ARPAFILES= ftp.h inet.h nameser.h nameser_compat.h telnet.h tftp.h
|
||||
|
||||
PROTOFILES= dumprestore.h routed.h rwhod.h talkd.h timed.h
|
||||
|
||||
RPCFILES= auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h pmap_rmt.h \
|
||||
rpc.h rpc_com.h rpc_msg.h svc.h svc_auth.h types.h xdr.h \
|
||||
auth_des.h des.h des_crypt.h
|
||||
|
||||
MFILES= float.h floatingpoint.h stdarg.h varargs.h
|
||||
|
||||
# posix4/aio.h conflicts with dysons and isn't installed:
|
||||
@ -86,9 +82,6 @@ beforeinstall: ${SHARED}
|
||||
cd ${.CURDIR}/protocols; \
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${PROTOFILES} ${DESTDIR}/usr/include/protocols
|
||||
cd ${.CURDIR}/rpc; \
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${RPCFILES} ${DESTDIR}/usr/include/rpc
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${.OBJDIR}/osreldate.h \
|
||||
${DESTDIR}/usr/include
|
||||
|
96
include/netconfig.h
Normal file
96
include/netconfig.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* $NetBSD: netconfig.h,v 1.1 2000/06/02 22:57:54 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
|
||||
#ifndef _NETCONFIG_H_
|
||||
#define _NETCONFIG_H_
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define NETCONFIG "/etc/netconfig"
|
||||
#define NETPATH "NETPATH"
|
||||
|
||||
struct netconfig {
|
||||
char *nc_netid; /* Network ID */
|
||||
unsigned long nc_semantics; /* Semantics (see below) */
|
||||
unsigned long nc_flag; /* Flags (see below) */
|
||||
char *nc_protofmly; /* Protocol family */
|
||||
char *nc_proto; /* Protocol name */
|
||||
char *nc_device; /* Network device pathname */
|
||||
unsigned long nc_nlookups; /* Number of directory lookup libs */
|
||||
char **nc_lookups; /* Names of the libraries */
|
||||
unsigned long nc_unused[9]; /* reserved */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct netconfig **nc_head;
|
||||
struct netconfig **nc_curr;
|
||||
} NCONF_HANDLE;
|
||||
|
||||
/*
|
||||
* nc_semantics values
|
||||
*/
|
||||
#define NC_TPI_CLTS 1
|
||||
#define NC_TPI_COTS 2
|
||||
#define NC_TPI_COTS_ORD 3
|
||||
#define NC_TPI_RAW 4
|
||||
|
||||
/*
|
||||
* nc_flag values
|
||||
*/
|
||||
#define NC_NOFLAG 0x00
|
||||
#define NC_VISIBLE 0x01
|
||||
#define NC_BROADCAST 0x02
|
||||
|
||||
/*
|
||||
* nc_protofmly values
|
||||
*/
|
||||
#define NC_NOPROTOFMLY "-"
|
||||
#define NC_LOOPBACK "loopback"
|
||||
#define NC_INET "inet"
|
||||
#define NC_INET6 "inet6"
|
||||
#define NC_IMPLINK "implink"
|
||||
#define NC_PUP "pup"
|
||||
#define NC_CHAOS "chaos"
|
||||
#define NC_NS "ns"
|
||||
#define NC_NBS "nbs"
|
||||
#define NC_ECMA "ecma"
|
||||
#define NC_DATAKIT "datakit"
|
||||
#define NC_CCITT "ccitt"
|
||||
#define NC_SNA "sna"
|
||||
#define NC_DECNET "decnet"
|
||||
#define NC_DLI "dli"
|
||||
#define NC_LAT "lat"
|
||||
#define NC_HYLINK "hylink"
|
||||
#define NC_APPLETALK "appletalk"
|
||||
#define NC_NIT "nit"
|
||||
#define NC_IEEE802 "ieee802"
|
||||
#define NC_OSI "osi"
|
||||
#define NC_X25 "x25"
|
||||
#define NC_OSINET "osinet"
|
||||
#define NC_GOSIP "gosip"
|
||||
|
||||
/*
|
||||
* nc_proto values
|
||||
*/
|
||||
#define NC_NOPROTO "-"
|
||||
#define NC_TCP "tcp"
|
||||
#define NC_UDP "udp"
|
||||
#define NC_ICMP "icmp"
|
||||
|
||||
__BEGIN_DECLS
|
||||
void *setnetconfig __P((void));
|
||||
struct netconfig *getnetconfig __P((void *));
|
||||
struct netconfig *getnetconfigent __P((char *));
|
||||
void freenetconfigent __P((struct netconfig *));
|
||||
int endnetconfig __P((void *));
|
||||
|
||||
void *setnetpath __P((void));
|
||||
struct netconfig *getnetpath __P((void *));
|
||||
int endnetpath(void *);
|
||||
|
||||
void nc_perror __P((const char *));
|
||||
char *nc_sperror __P((void));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NETCONFIG_H_ */
|
@ -29,6 +29,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _PTHREAD_NP_H_
|
||||
#define _PTHREAD_NP_H_
|
||||
@ -52,6 +53,7 @@ int pthread_mutexattr_setkind_np __P((pthread_mutexattr_t *, int));
|
||||
void pthread_set_name_np __P((pthread_t, char *));
|
||||
int pthread_switch_add_np __P((pthread_switch_routine_t));
|
||||
int pthread_switch_delete_np __P((pthread_switch_routine_t));
|
||||
int pthread_main_np __P((void));
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
|
37
include/rpc/Makefile
Normal file
37
include/rpc/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
# from: @(#)Makefile 2.3 88/08/11 4.0 RPCSRC
|
||||
# $FreeBSD$
|
||||
|
||||
.SUFFIXES: .x
|
||||
|
||||
RPCCOM = rpcgen -C
|
||||
|
||||
HDRS= rpcb_prot.h
|
||||
|
||||
XFILES= rpcb_prot.x
|
||||
|
||||
HFILES= auth.h auth_unix.h clnt.h clnt_soc.h clnt_stat.h \
|
||||
nettype.h pmap_clnt.h pmap_prot.h pmap_rmt.h raw.h \
|
||||
rpc.h rpc_msg.h rpcb_clnt.h rpcent.h rpc_com.h \
|
||||
svc.h svc_auth.h svc_soc.h svc_dg.h types.h xdr.h
|
||||
|
||||
# Secure RPC
|
||||
HFILES+= auth_des.h des.h des_crypt.h
|
||||
|
||||
# Kerberos
|
||||
HFILES+= auth_kerb.h
|
||||
|
||||
CLEANFILES+= ${HDRS}
|
||||
|
||||
all: ${HDRS}
|
||||
|
||||
beforeinstall:
|
||||
${INSTALL} -C -o ${BINOWN} -g ${BINGRP} -m 444 \
|
||||
${HFILES:S;^;${.CURDIR}/;} \
|
||||
${XFILES:S;^;${.CURDIR}/;} \
|
||||
${HDRS} \
|
||||
${DESTDIR}/usr/include/rpc
|
||||
|
||||
.x.h:
|
||||
${RPCCOM} -h -DWANT_NFS3 ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
.include <bsd.prog.mk>
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: auth.h,v 1.15 2000/06/02 22:57:55 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -28,6 +30,7 @@
|
||||
*
|
||||
* from: @(#)auth.h 1.17 88/02/08 SMI
|
||||
* from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC
|
||||
* from: @(#)auth.h 1.43 98/02/02 SMI
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -43,12 +46,75 @@
|
||||
|
||||
#ifndef _RPC_AUTH_H
|
||||
#define _RPC_AUTH_H
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/clnt_stat.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define MAX_AUTH_BYTES 400
|
||||
#define MAXNETNAMELEN 255 /* maximum length of network user's name */
|
||||
|
||||
/*
|
||||
* Client side authentication/security data
|
||||
*/
|
||||
|
||||
typedef struct sec_data {
|
||||
u_int secmod; /* security mode number e.g. in nfssec.conf */
|
||||
u_int rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */
|
||||
int flags; /* AUTH_F_xxx flags */
|
||||
caddr_t data; /* opaque data per flavor */
|
||||
} sec_data_t;
|
||||
|
||||
#ifdef _SYSCALL32_IMPL
|
||||
struct sec_data32 {
|
||||
uint32_t secmod; /* security mode number e.g. in nfssec.conf */
|
||||
uint32_t rpcflavor; /* rpc flavors:AUTH_UNIX,AUTH_DES,RPCSEC_GSS */
|
||||
int32_t flags; /* AUTH_F_xxx flags */
|
||||
caddr32_t data; /* opaque data per flavor */
|
||||
};
|
||||
#endif /* _SYSCALL32_IMPL */
|
||||
|
||||
/*
|
||||
* AUTH_DES flavor specific data from sec_data opaque data field.
|
||||
* AUTH_KERB has the same structure.
|
||||
*/
|
||||
typedef struct des_clnt_data {
|
||||
struct netbuf syncaddr; /* time sync addr */
|
||||
struct knetconfig *knconf; /* knetconfig info that associated */
|
||||
/* with the syncaddr. */
|
||||
char *netname; /* server's netname */
|
||||
int netnamelen; /* server's netname len */
|
||||
} dh_k4_clntdata_t;
|
||||
|
||||
#ifdef _SYSCALL32_IMPL
|
||||
struct des_clnt_data32 {
|
||||
struct netbuf32 syncaddr; /* time sync addr */
|
||||
caddr32_t knconf; /* knetconfig info that associated */
|
||||
/* with the syncaddr. */
|
||||
caddr32_t netname; /* server's netname */
|
||||
int32_t netnamelen; /* server's netname len */
|
||||
};
|
||||
#endif /* _SYSCALL32_IMPL */
|
||||
|
||||
#ifdef KERBEROS
|
||||
/*
|
||||
* flavor specific data to hold the data for AUTH_DES/AUTH_KERB(v4)
|
||||
* in sec_data->data opaque field.
|
||||
*/
|
||||
typedef struct krb4_svc_data {
|
||||
int window; /* window option value */
|
||||
} krb4_svcdata_t;
|
||||
|
||||
typedef struct krb4_svc_data des_svcdata_t;
|
||||
#endif /* KERBEROS */
|
||||
|
||||
/*
|
||||
* authentication/security specific flags
|
||||
*/
|
||||
#define AUTH_F_RPCTIMESYNC 0x001 /* use RPC to do time sync */
|
||||
#define AUTH_F_TRYNONE 0x002 /* allow fall back to AUTH_NONE */
|
||||
|
||||
|
||||
/*
|
||||
* Status returned from authentication check
|
||||
*/
|
||||
@ -67,18 +133,32 @@ enum auth_stat {
|
||||
*/
|
||||
AUTH_INVALIDRESP=6, /* bogus response verifier */
|
||||
AUTH_FAILED=7 /* some unknown reason */
|
||||
#ifdef KERBEROS
|
||||
/*
|
||||
* kerberos errors
|
||||
*/
|
||||
AUTH_KERB_GENERIC = 8, /* kerberos generic error */
|
||||
AUTH_TIMEEXPIRE = 9, /* time of credential expired */
|
||||
AUTH_TKT_FILE = 10, /* something wrong with ticket file */
|
||||
AUTH_DECODE = 11, /* can't decode authenticator */
|
||||
AUTH_NET_ADDR = 12 /* wrong net address in ticket */
|
||||
#endif /* KERBEROS */
|
||||
};
|
||||
|
||||
union des_block {
|
||||
struct {
|
||||
u_int32_t high;
|
||||
u_int32_t low;
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
} key;
|
||||
char c[8];
|
||||
};
|
||||
typedef union des_block des_block;
|
||||
__BEGIN_DECLS
|
||||
extern bool_t xdr_des_block __P((XDR *, des_block *));
|
||||
#ifdef __STDC__
|
||||
extern bool_t xdr_des_block(XDR *, des_block *);
|
||||
#else
|
||||
extern bool_t xdr_des_block();
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
@ -89,29 +169,26 @@ struct opaque_auth {
|
||||
caddr_t oa_base; /* address of more auth stuff */
|
||||
u_int oa_length; /* not to exceed MAX_AUTH_BYTES */
|
||||
};
|
||||
__BEGIN_DECLS
|
||||
bool_t xdr_opaque_auth __P((XDR *xdrs, struct opaque_auth *ap));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Auth handle, interface to client side authenticators.
|
||||
*/
|
||||
typedef struct __rpc_auth {
|
||||
typedef struct __auth {
|
||||
struct opaque_auth ah_cred;
|
||||
struct opaque_auth ah_verf;
|
||||
union des_block ah_key;
|
||||
struct auth_ops {
|
||||
void (*ah_nextverf) __P((struct __rpc_auth *));
|
||||
void (*ah_nextverf) (struct __auth *);
|
||||
/* nextverf & serialize */
|
||||
int (*ah_marshal) __P((struct __rpc_auth *, XDR *));
|
||||
int (*ah_marshal) (struct __auth *, XDR *);
|
||||
/* validate verifier */
|
||||
int (*ah_validate) __P((struct __rpc_auth *,
|
||||
struct opaque_auth *));
|
||||
int (*ah_validate) (struct __auth *,
|
||||
struct opaque_auth *);
|
||||
/* refresh credentials */
|
||||
int (*ah_refresh) __P((struct __rpc_auth *));
|
||||
int (*ah_refresh) (struct __auth *, void *);
|
||||
/* destroy this structure */
|
||||
void (*ah_destroy) __P((struct __rpc_auth *));
|
||||
void (*ah_destroy) (struct __auth *);
|
||||
} *ah_ops;
|
||||
caddr_t ah_private;
|
||||
} AUTH;
|
||||
@ -140,10 +217,10 @@ typedef struct __rpc_auth {
|
||||
#define auth_validate(auth, verfp) \
|
||||
((*((auth)->ah_ops->ah_validate))((auth), verfp))
|
||||
|
||||
#define AUTH_REFRESH(auth) \
|
||||
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||
#define auth_refresh(auth) \
|
||||
((*((auth)->ah_ops->ah_refresh))(auth))
|
||||
#define AUTH_REFRESH(auth, msg) \
|
||||
((*((auth)->ah_ops->ah_refresh))(auth, msg))
|
||||
#define auth_refresh(auth, msg) \
|
||||
((*((auth)->ah_ops->ah_refresh))(auth, msg))
|
||||
|
||||
#define AUTH_DESTROY(auth) \
|
||||
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||
@ -151,14 +228,16 @@ typedef struct __rpc_auth {
|
||||
((*((auth)->ah_ops->ah_destroy))(auth))
|
||||
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern struct opaque_auth _null_auth;
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* These are the various implementations of client side authenticators.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unix style authentication
|
||||
* System style authentication
|
||||
* AUTH *authunix_create(machname, uid, gid, len, aup_gids)
|
||||
* char *machname;
|
||||
* int uid;
|
||||
@ -167,94 +246,105 @@ extern struct opaque_auth _null_auth;
|
||||
* int *aup_gids;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
struct sockaddr_in;
|
||||
extern AUTH *authunix_create __P((char *, int, int, int, int *));
|
||||
extern AUTH *authunix_create_default __P((void));
|
||||
extern AUTH *authnone_create __P((void));
|
||||
extern AUTH *authunix_create(char *, int, int, int,
|
||||
int *);
|
||||
extern AUTH *authunix_create_default(void); /* takes no parameters */
|
||||
extern AUTH *authnone_create(void); /* takes no parameters */
|
||||
__END_DECLS
|
||||
|
||||
/* Forward compatibility with TI-RPC */
|
||||
#define authsys_create authunix_create
|
||||
#define authsys_create_default authunix_create_default
|
||||
|
||||
/*
|
||||
* DES style authentication
|
||||
* AUTH *authdes_create(servername, window, timehost, ckey)
|
||||
* AUTH *authsecdes_create(servername, window, timehost, ckey)
|
||||
* char *servername; - network name of server
|
||||
* u_int window; - time to live
|
||||
* struct sockaddr *timehost; - optional hostname to sync with
|
||||
* const char *timehost; - optional hostname to sync with
|
||||
* des_block *ckey; - optional conversation key to use
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern AUTH *authdes_create __P(( char *, u_int, struct sockaddr *, des_block * ));
|
||||
#ifdef NOTYET
|
||||
/*
|
||||
* TI-RPC supports this call, but it requires the inclusion of
|
||||
* NIS+-specific headers which would require the inclusion of other
|
||||
* headers which would result in a tangled mess. For now, the NIS+
|
||||
* code prototypes this routine internally.
|
||||
*/
|
||||
extern AUTH *authdes_pk_create __P(( char *, netobj *, u_int,
|
||||
struct sockaddr *, des_block *,
|
||||
nis_server * ));
|
||||
#endif
|
||||
extern AUTH *authdes_create (char *, u_int, struct sockaddr *, des_block *);
|
||||
extern AUTH *authdes_seccreate (const char *, const u_int, const char *,
|
||||
const des_block *);
|
||||
__END_DECLS
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern bool_t xdr_opaque_auth __P((XDR *, struct opaque_auth *));
|
||||
__END_DECLS
|
||||
|
||||
#define authsys_create(c,i1,i2,i3,ip) authunix_create((c),(i1),(i2),(i3),(ip))
|
||||
#define authsys_create_default() authunix_create_default()
|
||||
|
||||
/*
|
||||
* Netname manipulation routines.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern int netname2user __P(( char *, uid_t *, gid_t *, int *, gid_t *));
|
||||
extern int netname2host __P(( char *, char *, int ));
|
||||
extern int getnetname __P(( char * ));
|
||||
extern int user2netname __P(( char *, uid_t, char * ));
|
||||
extern int host2netname __P(( char *, char *, char * ));
|
||||
extern void passwd2des __P(( char *, char * ));
|
||||
extern int getnetname(char *);
|
||||
extern int host2netname(char *, const char *, const char *);
|
||||
extern int user2netname(char *, const uid_t, const char *);
|
||||
extern int netname2user(char *, uid_t *, gid_t *, int *, gid_t *);
|
||||
extern int netname2host(char *, char *, const int);
|
||||
extern void passwd2des ( char *, char * );
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Keyserv interface routines.
|
||||
* XXX Should not be here.
|
||||
*
|
||||
* These routines interface to the keyserv daemon
|
||||
*
|
||||
*/
|
||||
#ifndef HEXKEYBYTES
|
||||
#define HEXKEYBYTES 48
|
||||
#endif
|
||||
typedef char kbuf[HEXKEYBYTES];
|
||||
typedef char *namestr;
|
||||
|
||||
struct netstarg {
|
||||
kbuf st_priv_key;
|
||||
kbuf st_pub_key;
|
||||
namestr st_netname;
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern int key_decryptsession __P(( const char *, des_block * ));
|
||||
extern int key_decryptsession_pk __P(( char *, netobj *, des_block * ));
|
||||
extern int key_encryptsession __P(( const char *, des_block * ));
|
||||
extern int key_encryptsession_pk __P(( char *, netobj *, des_block * ));
|
||||
extern int key_gendes __P(( des_block * ));
|
||||
extern int key_setsecret __P(( const char * ));
|
||||
extern int key_secretkey_is_set __P(( void ));
|
||||
extern int key_setnet __P(( struct netstarg * ));
|
||||
extern int key_get_conv __P(( char *, des_block * ));
|
||||
extern int key_decryptsession(const char *, des_block *);
|
||||
extern int key_encryptsession(const char *, des_block *);
|
||||
extern int key_gendes(des_block *);
|
||||
extern int key_setsecret(const char *);
|
||||
extern int key_secretkey_is_set(void);
|
||||
__END_DECLS
|
||||
|
||||
#ifdef KERBEROS
|
||||
/*
|
||||
* Kerberos style authentication
|
||||
* AUTH *authkerb_seccreate(service, srv_inst, realm, window, timehost, status)
|
||||
* const char *service; - service name
|
||||
* const char *srv_inst; - server instance
|
||||
* const char *realm; - server realm
|
||||
* const u_int window; - time to live
|
||||
* const char *timehost; - optional hostname to sync with
|
||||
* int *status; - kerberos status returned
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern AUTH *authkerb_seccreate(const char *, const char *, const char *,
|
||||
const u_int, const char *, int *);
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Publickey routines.
|
||||
* Map a kerberos credential into a unix cred.
|
||||
*
|
||||
* authkerb_getucred(rqst, uid, gid, grouplen, groups)
|
||||
* const struct svc_req *rqst; - request pointer
|
||||
* uid_t *uid;
|
||||
* gid_t *gid;
|
||||
* short *grouplen;
|
||||
* int *groups;
|
||||
*
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern int getpublickey __P(( char *, char * ));
|
||||
extern int getpublicandprivatekey __P(( char *, char * ));
|
||||
extern int getsecretkey __P(( char *, char *, char * ));
|
||||
extern int authkerb_getucred(/* struct svc_req *, uid_t *, gid_t *,
|
||||
short *, int * */);
|
||||
__END_DECLS
|
||||
#endif /* KERBEROS */
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct svc_req;
|
||||
struct rpc_msg;
|
||||
enum auth_stat _svcauth_null __P((struct svc_req *, struct rpc_msg *));
|
||||
enum auth_stat _svcauth_short __P((struct svc_req *, struct rpc_msg *));
|
||||
enum auth_stat _svcauth_unix __P((struct svc_req *, struct rpc_msg *));
|
||||
__END_DECLS
|
||||
|
||||
#define AUTH_NONE 0 /* no authentication */
|
||||
#define AUTH_NULL 0 /* backward compatibility */
|
||||
#define AUTH_UNIX 1 /* unix style (uid, gids) */
|
||||
#define AUTH_SYS 1 /* forward compatibility */
|
||||
#define AUTH_SYS 1 /* unix style (uid, gids) */
|
||||
#define AUTH_UNIX AUTH_SYS
|
||||
#define AUTH_SHORT 2 /* short hand unix style */
|
||||
#define AUTH_DES 3 /* des style (encrypted timestamps) */
|
||||
#define AUTH_DH 3 /* for Diffie-Hellman mechanism */
|
||||
#define AUTH_DES AUTH_DH /* for backward compatibility */
|
||||
#define AUTH_KERB 4 /* kerberos style */
|
||||
|
||||
#endif /* !_RPC_AUTH_H */
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC; from 1.3 88/02/08 SMI */
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,10 +27,13 @@
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)auth_des.h 2.2 88/07/29 4.0 RPCSRC
|
||||
* from: @(#)auth_des.h 1.14 94/04/25 SMI
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -102,8 +106,21 @@ struct authdes_verf {
|
||||
#define adv_xtimeverf adv_time_u.adv_xtime
|
||||
#define adv_nickname adv_int_u
|
||||
|
||||
/*
|
||||
* Map a des credential into a unix cred.
|
||||
*
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern int authdes_getucred __P(( struct authdes_cred *, uid_t *, gid_t *, int *, gid_t * ));
|
||||
__END_DECLS
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern bool_t xdr_authdes_cred(XDR *, struct authdes_cred *);
|
||||
extern bool_t xdr_authdes_verf(XDR *, struct authdes_verf *);
|
||||
extern int rtime(dev_t, struct netbuf *, int, struct timeval *,
|
||||
struct timeval *);
|
||||
extern void kgetnetname(char *);
|
||||
extern enum auth_stat _svcauth_des(struct svc_req *, struct rpc_msg *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ndef _AUTH_DES_ */
|
||||
|
143
include/rpc/auth_kerb.h
Normal file
143
include/rpc/auth_kerb.h
Normal file
@ -0,0 +1,143 @@
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* auth_kerb.h, Protocol for Kerberos style authentication for RPC
|
||||
*
|
||||
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_AUTH_KERB_H
|
||||
#define _RPC_AUTH_KERB_H
|
||||
|
||||
#ifdef KERBEROS
|
||||
|
||||
#pragma ident "@(#)auth_kerb.h 1.10 94/04/25 SMI"
|
||||
|
||||
#include <kerberos/krb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/t_kuser.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rpc/svc.h>
|
||||
|
||||
/*
|
||||
* There are two kinds of "names": fullnames and nicknames
|
||||
*/
|
||||
enum authkerb_namekind {
|
||||
AKN_FULLNAME,
|
||||
AKN_NICKNAME
|
||||
};
|
||||
/*
|
||||
* A fullname contains the ticket and the window
|
||||
*/
|
||||
struct authkerb_fullname {
|
||||
KTEXT_ST ticket;
|
||||
u_long window; /* associated window */
|
||||
};
|
||||
|
||||
/*
|
||||
* cooked credential stored in rq_clntcred
|
||||
*/
|
||||
struct authkerb_clnt_cred {
|
||||
/* start of AUTH_DAT */
|
||||
unsigned char k_flags; /* Flags from ticket */
|
||||
char pname[ANAME_SZ]; /* Principal's name */
|
||||
char pinst[INST_SZ]; /* His Instance */
|
||||
char prealm[REALM_SZ]; /* His Realm */
|
||||
unsigned long checksum; /* Data checksum (opt) */
|
||||
C_Block session; /* Session Key */
|
||||
int life; /* Life of ticket */
|
||||
unsigned long time_sec; /* Time ticket issued */
|
||||
unsigned long address; /* Address in ticket */
|
||||
/* KTEXT_ST reply; Auth reply (opt) */
|
||||
/* end of AUTH_DAT */
|
||||
unsigned long expiry; /* time the ticket is expiring */
|
||||
u_long nickname; /* Nickname into cache */
|
||||
u_long window; /* associated window */
|
||||
};
|
||||
|
||||
typedef struct authkerb_clnt_cred authkerb_clnt_cred;
|
||||
|
||||
/*
|
||||
* A credential
|
||||
*/
|
||||
struct authkerb_cred {
|
||||
enum authkerb_namekind akc_namekind;
|
||||
struct authkerb_fullname akc_fullname;
|
||||
u_long akc_nickname;
|
||||
};
|
||||
|
||||
/*
|
||||
* A kerb authentication verifier
|
||||
*/
|
||||
struct authkerb_verf {
|
||||
union {
|
||||
struct timeval akv_ctime; /* clear time */
|
||||
des_block akv_xtime; /* crypt time */
|
||||
} akv_time_u;
|
||||
u_long akv_int_u;
|
||||
};
|
||||
|
||||
/*
|
||||
* des authentication verifier: client variety
|
||||
*
|
||||
* akv_timestamp is the current time.
|
||||
* akv_winverf is the credential window + 1.
|
||||
* Both are encrypted using the conversation key.
|
||||
*/
|
||||
#ifndef akv_timestamp
|
||||
#define akv_timestamp akv_time_u.akv_ctime
|
||||
#define akv_xtimestamp akv_time_u.akv_xtime
|
||||
#define akv_winverf akv_int_u
|
||||
#endif
|
||||
/*
|
||||
* des authentication verifier: server variety
|
||||
*
|
||||
* akv_timeverf is the client's timestamp + client's window
|
||||
* akv_nickname is the server's nickname for the client.
|
||||
* akv_timeverf is encrypted using the conversation key.
|
||||
*/
|
||||
#ifndef akv_timeverf
|
||||
#define akv_timeverf akv_time_u.akv_ctime
|
||||
#define akv_xtimeverf akv_time_u.akv_xtime
|
||||
#define akv_nickname akv_int_u
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Register the service name, instance and realm.
|
||||
*/
|
||||
extern int authkerb_create(char *, char *, char *, u_int,
|
||||
struct netbuf *, int *, dev_t, int, AUTH **);
|
||||
extern bool_t xdr_authkerb_cred(XDR *, struct authkerb_cred *);
|
||||
extern bool_t xdr_authkerb_verf(XDR *, struct authkerb_verf *);
|
||||
extern int svc_kerb_reg(SVCXPRT *, char *, char *, char *);
|
||||
extern enum auth_stat _svcauth_kerb(struct svc_req *, struct rpc_msg *);
|
||||
|
||||
#endif KERBEROS
|
||||
#endif /* !_RPC_AUTH_KERB_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: clnt.h,v 1.14 2000/06/02 22:57:55 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,7 +28,7 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)clnt.h 1.31 88/02/08 SMI
|
||||
* from: @(#)clnt.h 1.31 94/04/29 SMI
|
||||
* from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -39,52 +41,28 @@
|
||||
|
||||
#ifndef _RPC_CLNT_H_
|
||||
#define _RPC_CLNT_H_
|
||||
#include <rpc/clnt_stat.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <netconfig.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/*
|
||||
* Rpc calls return an enum clnt_stat. This should be looked at more,
|
||||
* since each implementation is required to live with this (implementation
|
||||
* independent) list of errors.
|
||||
* Well-known IPV6 RPC broadcast address.
|
||||
*/
|
||||
enum clnt_stat {
|
||||
RPC_SUCCESS=0, /* call succeeded */
|
||||
/*
|
||||
* local errors
|
||||
*/
|
||||
RPC_CANTENCODEARGS=1, /* can't encode arguments */
|
||||
RPC_CANTDECODERES=2, /* can't decode results */
|
||||
RPC_CANTSEND=3, /* failure in sending call */
|
||||
RPC_CANTRECV=4, /* failure in receiving result */
|
||||
RPC_TIMEDOUT=5, /* call timed out */
|
||||
/*
|
||||
* remote errors
|
||||
*/
|
||||
RPC_VERSMISMATCH=6, /* rpc versions not compatible */
|
||||
RPC_AUTHERROR=7, /* authentication error */
|
||||
RPC_PROGUNAVAIL=8, /* program not available */
|
||||
RPC_PROGVERSMISMATCH=9, /* program version mismatched */
|
||||
RPC_PROCUNAVAIL=10, /* procedure unavailable */
|
||||
RPC_CANTDECODEARGS=11, /* decode arguments error */
|
||||
RPC_SYSTEMERROR=12, /* generic "other problem" */
|
||||
|
||||
/*
|
||||
* callrpc & clnt_create errors
|
||||
*/
|
||||
RPC_UNKNOWNHOST=13, /* unknown host name */
|
||||
RPC_UNKNOWNPROTO=17, /* unkown protocol */
|
||||
|
||||
/*
|
||||
* _ create errors
|
||||
*/
|
||||
RPC_PMAPFAILURE=14, /* the pmapper failed in its call */
|
||||
RPC_PROGNOTREGISTERED=15, /* remote program is not registered */
|
||||
/*
|
||||
* unspecified error
|
||||
*/
|
||||
RPC_FAILED=16
|
||||
};
|
||||
#define RPCB_MULTICAST_ADDR "ff02::202"
|
||||
|
||||
/*
|
||||
* the following errors are in general unrecoverable. The caller
|
||||
* should give up rather than retry.
|
||||
*/
|
||||
#define IS_UNRECOVERABLE_RPC(s) (((s) == RPC_AUTHERROR) || \
|
||||
((s) == RPC_CANTENCODEARGS) || \
|
||||
((s) == RPC_CANTDECODERES) || \
|
||||
((s) == RPC_VERSMISMATCH) || \
|
||||
((s) == RPC_PROCUNAVAIL) || \
|
||||
((s) == RPC_PROGUNAVAIL) || \
|
||||
((s) == RPC_PROGVERSMISMATCH) || \
|
||||
((s) == RPC_CANTDECODEARGS))
|
||||
|
||||
/*
|
||||
* Error info.
|
||||
@ -95,8 +73,8 @@ struct rpc_err {
|
||||
int RE_errno; /* related system error */
|
||||
enum auth_stat RE_why; /* why the auth error occurred */
|
||||
struct {
|
||||
u_int32_t low; /* lowest verion supported */
|
||||
u_int32_t high; /* highest verion supported */
|
||||
rpcvers_t low; /* lowest version supported */
|
||||
rpcvers_t high; /* highest version supported */
|
||||
} RE_vers;
|
||||
struct { /* maybe meaningful if RPC_FAILED */
|
||||
int32_t s1;
|
||||
@ -112,7 +90,7 @@ struct rpc_err {
|
||||
|
||||
/*
|
||||
* Client rpc handle.
|
||||
* Created by individual implementations, see e.g. rpc_udp.c.
|
||||
* Created by individual implementations
|
||||
* Client is responsible for initializing auth, see e.g. auth_none.c.
|
||||
*/
|
||||
typedef struct __rpc_client {
|
||||
@ -120,7 +98,7 @@ typedef struct __rpc_client {
|
||||
struct clnt_ops {
|
||||
/* call remote procedure */
|
||||
enum clnt_stat (*cl_call) __P((struct __rpc_client *,
|
||||
u_long, xdrproc_t, caddr_t, xdrproc_t,
|
||||
rpcproc_t, xdrproc_t, caddr_t, xdrproc_t,
|
||||
caddr_t, struct timeval));
|
||||
/* abort a call */
|
||||
void (*cl_abort) __P((struct __rpc_client *));
|
||||
@ -134,12 +112,36 @@ typedef struct __rpc_client {
|
||||
void (*cl_destroy) __P((struct __rpc_client *));
|
||||
/* the ioctl() of rpc */
|
||||
bool_t (*cl_control) __P((struct __rpc_client *, u_int,
|
||||
void *));
|
||||
char *));
|
||||
} *cl_ops;
|
||||
caddr_t cl_private; /* private stuff */
|
||||
void *cl_private; /* private stuff */
|
||||
char *cl_netid; /* network token */
|
||||
char *cl_tp; /* device name */
|
||||
} CLIENT;
|
||||
|
||||
|
||||
/*
|
||||
* Timers used for the pseudo-transport protocol when using datagrams
|
||||
*/
|
||||
struct rpc_timers {
|
||||
u_short rt_srtt; /* smoothed round-trip time */
|
||||
u_short rt_deviate; /* estimated deviation */
|
||||
u_long rt_rtxcur; /* current (backed-off) rto */
|
||||
};
|
||||
|
||||
/*
|
||||
* Feedback values used for possible congestion and rate control
|
||||
*/
|
||||
#define FEEDBACK_REXMIT1 1 /* first retransmit */
|
||||
#define FEEDBACK_OK 2 /* no retransmits */
|
||||
|
||||
/* Used to set version of portmapper used in broadcast */
|
||||
|
||||
#define CLCR_SET_LOWVERS 3
|
||||
#define CLCR_GET_LOWVERS 4
|
||||
|
||||
#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
|
||||
|
||||
/*
|
||||
* client side rpc interface ops
|
||||
*
|
||||
@ -151,19 +153,19 @@ typedef struct __rpc_client {
|
||||
* enum clnt_stat
|
||||
* CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
|
||||
* CLIENT *rh;
|
||||
* u_long proc;
|
||||
* rpcproc_t proc;
|
||||
* xdrproc_t xargs;
|
||||
* caddr_t argsp;
|
||||
* xdrproc_t xres;
|
||||
* caddr_t resp;
|
||||
* struct timeval timeout;
|
||||
*/
|
||||
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
|
||||
xres, (caddr_t)resp, secs))
|
||||
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, (caddr_t)argsp, \
|
||||
xres, (caddr_t)resp, secs))
|
||||
#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \
|
||||
(caddr_t)(void *)argsp, xres, (caddr_t)(void *)resp, secs))
|
||||
#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \
|
||||
((*(rh)->cl_ops->cl_call)(rh, proc, xargs, \
|
||||
(caddr_t)(void *)argsp, xres, (caddr_t)(void *)resp, secs))
|
||||
|
||||
/*
|
||||
* void
|
||||
@ -203,42 +205,30 @@ typedef struct __rpc_client {
|
||||
#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
|
||||
|
||||
/*
|
||||
* control operations that apply to udp, tcp and unix transports
|
||||
*
|
||||
* Note: options marked XXX are no-ops in this implementation of RPC.
|
||||
* The are present in TI-RPC but can't be implemented here since they
|
||||
* depend on the presence of STREAMS/TLI, which we don't have.
|
||||
*
|
||||
* control operations that apply to both udp and tcp transports
|
||||
*/
|
||||
#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
|
||||
#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
|
||||
#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
|
||||
#define CLGET_FD 6 /* get connections file descriptor */
|
||||
#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) XXX */
|
||||
#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
|
||||
#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */
|
||||
#define CLGET_XID 10 /* Get xid */
|
||||
#define CLSET_XID 11 /* Set xid */
|
||||
#define CLGET_VERS 12 /* Get version number */
|
||||
#define CLSET_VERS 13 /* Set version number */
|
||||
#define CLGET_PROG 14 /* Get program number */
|
||||
#define CLSET_PROG 15 /* Set program number */
|
||||
#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) XXX */
|
||||
#define CLSET_PUSH_TIMOD 17 /* push timod if not already present XXX */
|
||||
#define CLSET_POP_TIMOD 18 /* pop timod XXX */
|
||||
|
||||
#define CLSET_TIMEOUT 1 /* set timeout (timeval) */
|
||||
#define CLGET_TIMEOUT 2 /* get timeout (timeval) */
|
||||
#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */
|
||||
#define CLGET_FD 6 /* get connections file descriptor */
|
||||
#define CLGET_SVC_ADDR 7 /* get server's address (netbuf) */
|
||||
#define CLSET_FD_CLOSE 8 /* close fd while clnt_destroy */
|
||||
#define CLSET_FD_NCLOSE 9 /* Do not close fd while clnt_destroy */
|
||||
#define CLGET_XID 10 /* Get xid */
|
||||
#define CLSET_XID 11 /* Set xid */
|
||||
#define CLGET_VERS 12 /* Get version number */
|
||||
#define CLSET_VERS 13 /* Set version number */
|
||||
#define CLGET_PROG 14 /* Get program number */
|
||||
#define CLSET_PROG 15 /* Set program number */
|
||||
#define CLSET_SVC_ADDR 16 /* get server's address (netbuf) */
|
||||
#define CLSET_PUSH_TIMOD 17 /* push timod if not already present */
|
||||
#define CLSET_POP_TIMOD 18 /* pop timod */
|
||||
/*
|
||||
* udp only control operations
|
||||
* Connectionless only control operations
|
||||
*/
|
||||
#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */
|
||||
#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */
|
||||
|
||||
/*
|
||||
* Operations which GSSAPI needs. (Bletch.)
|
||||
*/
|
||||
#define CLGET_LOCAL_ADDR 19 /* get local addr (sockaddr) */
|
||||
|
||||
|
||||
/*
|
||||
* void
|
||||
* CLNT_DESTROY(rh);
|
||||
@ -254,16 +244,16 @@ typedef struct __rpc_client {
|
||||
* and network administration.
|
||||
*/
|
||||
|
||||
#define RPCTEST_PROGRAM ((u_long)1)
|
||||
#define RPCTEST_VERSION ((u_long)1)
|
||||
#define RPCTEST_NULL_PROC ((u_long)2)
|
||||
#define RPCTEST_NULL_BATCH_PROC ((u_long)3)
|
||||
#define RPCTEST_PROGRAM ((rpcprog_t)1)
|
||||
#define RPCTEST_VERSION ((rpcvers_t)1)
|
||||
#define RPCTEST_NULL_PROC ((rpcproc_t)2)
|
||||
#define RPCTEST_NULL_BATCH_PROC ((rpcproc_t)3)
|
||||
|
||||
/*
|
||||
* By convention, procedure 0 takes null arguments and returns them
|
||||
*/
|
||||
|
||||
#define NULLPROC ((u_long)0)
|
||||
#define NULLPROC ((rpcproc_t)0)
|
||||
|
||||
/*
|
||||
* Below are the client handle creation routines for the various
|
||||
@ -271,109 +261,113 @@ typedef struct __rpc_client {
|
||||
* creation failure occurs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic client creation routine. Supported protocols are those that
|
||||
* belong to the nettype namespace (/etc/netconfig).
|
||||
* CLIENT *
|
||||
* clnt_create(host, prog, vers, prot);
|
||||
* const char *host; -- hostname
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const char *prot; -- protocol
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clnt_create __P((const char *, const rpcprog_t, const rpcvers_t,
|
||||
const char *));
|
||||
/*
|
||||
*
|
||||
* const char *hostname; -- hostname
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const char *nettype; -- network type
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic client creation routine. Supported protocols are which belong
|
||||
* to the nettype name space.
|
||||
*/
|
||||
extern CLIENT *clnt_create_vers __P((const char *, const rpcprog_t, rpcvers_t *,
|
||||
const rpcvers_t, const rpcvers_t,
|
||||
const char *));
|
||||
/*
|
||||
* const char *host; -- hostname
|
||||
* const rpcprog_t prog; -- program number
|
||||
* rpcvers_t *vers_out; -- servers highest available version
|
||||
* const rpcvers_t vers_low; -- low version number
|
||||
* const rpcvers_t vers_high; -- high version number
|
||||
* const char *nettype; -- network type
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Generic client creation routine. It takes a netconfig structure
|
||||
* instead of nettype
|
||||
*/
|
||||
extern CLIENT *clnt_tp_create __P((const char *, const rpcprog_t,
|
||||
const rpcvers_t, const struct netconfig *));
|
||||
/*
|
||||
* const char *hostname; -- hostname
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const struct netconfig *netconf; -- network config structure
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generic TLI create routine. Only provided for compatibility.
|
||||
*/
|
||||
|
||||
extern CLIENT *clnt_tli_create __P((const int, const struct netconfig *,
|
||||
const struct netbuf *, const rpcprog_t,
|
||||
const rpcvers_t, const u_int, const u_int));
|
||||
/*
|
||||
* const register int fd; -- fd
|
||||
* const struct netconfig *nconf; -- netconfig structure
|
||||
* const struct netbuf *svcaddr; -- servers address
|
||||
* const u_long prog; -- program number
|
||||
* const u_long vers; -- version number
|
||||
* const u_int sendsz; -- send size
|
||||
* const u_int recvsz; -- recv size
|
||||
*/
|
||||
|
||||
/*
|
||||
* Low level clnt create routine for connectionful transports, e.g. tcp.
|
||||
*/
|
||||
extern CLIENT *clnt_vc_create __P((const int, const struct netbuf *,
|
||||
const rpcprog_t, const rpcvers_t,
|
||||
const u_int, const u_int));
|
||||
/*
|
||||
* const int fd; -- open file descriptor
|
||||
* const struct netbuf *svcaddr; -- servers address
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const u_int sendsz; -- buffer recv size
|
||||
* const u_int recvsz; -- buffer send size
|
||||
*/
|
||||
|
||||
/*
|
||||
* Low level clnt create routine for connectionless transports, e.g. udp.
|
||||
*/
|
||||
extern CLIENT *clnt_dg_create __P((const int, const struct netbuf *,
|
||||
const rpcprog_t, const rpcvers_t,
|
||||
const u_int, const u_int));
|
||||
/*
|
||||
* const int fd; -- open file descriptor
|
||||
* const struct netbuf *svcaddr; -- servers address
|
||||
* const rpcprog_t program; -- program number
|
||||
* const rpcvers_t version; -- version number
|
||||
* const u_int sendsz; -- buffer recv size
|
||||
* const u_int recvsz; -- buffer send size
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory based rpc (for speed check and testing)
|
||||
* CLIENT *
|
||||
* clntraw_create(prog, vers)
|
||||
* clnt_raw_create(prog, vers)
|
||||
* u_long prog;
|
||||
* u_long vers;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clntraw_create __P((u_long, u_long));
|
||||
__END_DECLS
|
||||
extern CLIENT *clnt_raw_create __P((rpcprog_t, rpcvers_t));
|
||||
|
||||
|
||||
/*
|
||||
* Generic client creation routine. Supported protocols are "udp", "tcp"
|
||||
* and "unix".
|
||||
* CLIENT *
|
||||
* clnt_create(host, prog, vers, prot);
|
||||
* char *host; -- hostname
|
||||
* u_long prog; -- program number
|
||||
* u_long vers; -- version number
|
||||
* char *prot; -- protocol
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clnt_create __P((char *, u_long, u_long, char *));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* TCP based rpc
|
||||
* CLIENT *
|
||||
* clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long prog;
|
||||
* u_long version;
|
||||
* register int *sockp;
|
||||
* u_int sendsz;
|
||||
* u_int recvsz;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clnttcp_create __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
int *,
|
||||
u_int,
|
||||
u_int));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* UDP based rpc.
|
||||
* CLIENT *
|
||||
* clntudp_create(raddr, program, version, wait, sockp)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long program;
|
||||
* u_long version;
|
||||
* struct timeval wait;
|
||||
* int *sockp;
|
||||
*
|
||||
* Same as above, but you specify max packet sizes.
|
||||
* CLIENT *
|
||||
* clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long program;
|
||||
* u_long version;
|
||||
* struct timeval wait;
|
||||
* int *sockp;
|
||||
* u_int sendsz;
|
||||
* u_int recvsz;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clntudp_create __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
struct timeval,
|
||||
int *));
|
||||
extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
struct timeval,
|
||||
int *,
|
||||
u_int,
|
||||
u_int));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* AF_UNIX based rpc
|
||||
* CLIENT *
|
||||
* clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
|
||||
* struct sockaddr_un *raddr;
|
||||
* u_long prog;
|
||||
* u_long version;
|
||||
* register int *sockp;
|
||||
* u_int sendsz;
|
||||
* u_int recvsz;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clntunix_create __P((struct sockaddr_un *,
|
||||
u_long,
|
||||
u_long,
|
||||
int *,
|
||||
u_int,
|
||||
u_int));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
@ -381,8 +375,8 @@ __END_DECLS
|
||||
* Print why creation failed
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern void clnt_pcreateerror __P((char *)); /* stderr */
|
||||
extern char *clnt_spcreateerror __P((char *)); /* string */
|
||||
extern void clnt_pcreateerror __P((const char *)); /* stderr */
|
||||
extern char *clnt_spcreateerror __P((const char *)); /* string */
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
@ -397,8 +391,8 @@ __END_DECLS
|
||||
* Print an English error message, given the client error code
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern void clnt_perror __P((CLIENT *, char *)); /* stderr */
|
||||
extern char *clnt_sperror __P((CLIENT *, char *)); /* string */
|
||||
extern void clnt_perror __P((CLIENT *, const char *)); /* stderr */
|
||||
extern char *clnt_sperror __P((CLIENT *, const char *)); /* string */
|
||||
__END_DECLS
|
||||
|
||||
|
||||
@ -410,10 +404,94 @@ struct rpc_createerr {
|
||||
struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
|
||||
};
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
__BEGIN_DECLS
|
||||
extern struct rpc_createerr *__rpc_createerr __P((void));
|
||||
__END_DECLS
|
||||
#define rpc_createerr (*(__rpc_createerr()))
|
||||
#else
|
||||
extern struct rpc_createerr rpc_createerr;
|
||||
#endif /* _THREAD_SAFE */
|
||||
|
||||
/*
|
||||
* The simplified interface:
|
||||
* enum clnt_stat
|
||||
* rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
|
||||
* const char *host;
|
||||
* const rpcprog_t prognum;
|
||||
* const rpcvers_t versnum;
|
||||
* const rpcproc_t procnum;
|
||||
* const xdrproc_t inproc, outproc;
|
||||
* const char *in;
|
||||
* char *out;
|
||||
* const char *nettype;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern enum clnt_stat rpc_call __P((const char *, const rpcprog_t,
|
||||
const rpcvers_t, const rpcproc_t,
|
||||
const xdrproc_t, const char *,
|
||||
const xdrproc_t, char *, const char *));
|
||||
__END_DECLS
|
||||
|
||||
#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
|
||||
#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */
|
||||
/*
|
||||
* RPC broadcast interface
|
||||
* The call is broadcasted to all locally connected nets.
|
||||
*
|
||||
* extern enum clnt_stat
|
||||
* rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||
* eachresult, nettype)
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const rpcproc_t proc; -- procedure number
|
||||
* const xdrproc_t xargs; -- xdr routine for args
|
||||
* caddr_t argsp; -- pointer to args
|
||||
* const xdrproc_t xresults; -- xdr routine for results
|
||||
* caddr_t resultsp; -- pointer to results
|
||||
* const resultproc_t eachresult; -- call with each result
|
||||
* const char *nettype; -- Transport type
|
||||
*
|
||||
* For each valid response received, the procedure eachresult is called.
|
||||
* Its form is:
|
||||
* done = eachresult(resp, raddr, nconf)
|
||||
* bool_t done;
|
||||
* caddr_t resp;
|
||||
* struct netbuf *raddr;
|
||||
* struct netconfig *nconf;
|
||||
* where resp points to the results of the call and raddr is the
|
||||
* address if the responder to the broadcast. nconf is the transport
|
||||
* on which the response was received.
|
||||
*
|
||||
* extern enum clnt_stat
|
||||
* rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||
* eachresult, inittime, waittime, nettype)
|
||||
* const rpcprog_t prog; -- program number
|
||||
* const rpcvers_t vers; -- version number
|
||||
* const rpcproc_t proc; -- procedure number
|
||||
* const xdrproc_t xargs; -- xdr routine for args
|
||||
* caddr_t argsp; -- pointer to args
|
||||
* const xdrproc_t xresults; -- xdr routine for results
|
||||
* caddr_t resultsp; -- pointer to results
|
||||
* const resultproc_t eachresult; -- call with each result
|
||||
* const int inittime; -- how long to wait initially
|
||||
* const int waittime; -- maximum time to wait
|
||||
* const char *nettype; -- Transport type
|
||||
*/
|
||||
|
||||
#endif /* !_RPC_CLNT_H */
|
||||
typedef bool_t (*resultproc_t) __P((caddr_t, ...));
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern enum clnt_stat rpc_broadcast __P((const rpcprog_t, const rpcvers_t,
|
||||
const rpcproc_t, const xdrproc_t,
|
||||
caddr_t, const xdrproc_t, caddr_t,
|
||||
const resultproc_t, const char *));
|
||||
extern enum clnt_stat rpc_broadcast_exp __P((const rpcprog_t, const rpcvers_t,
|
||||
const rpcproc_t, const xdrproc_t,
|
||||
caddr_t, const xdrproc_t, caddr_t,
|
||||
const resultproc_t, const int,
|
||||
const int, const char *));
|
||||
__END_DECLS
|
||||
|
||||
/* For backward compatibility */
|
||||
#include <rpc/clnt_soc.h>
|
||||
|
||||
#endif /* !_RPC_CLNT_H_ */
|
||||
|
118
include/rpc/clnt_soc.h
Normal file
118
include/rpc/clnt_soc.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* $NetBSD: clnt_soc.h,v 1.1 2000/06/02 22:57:55 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1984 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* clnt.h - Client side remote procedure call interface.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_CLNT_SOC_H
|
||||
#define _RPC_CLNT_SOC_H
|
||||
|
||||
/* derived from clnt_soc.h 1.3 88/12/17 SMI */
|
||||
|
||||
/*
|
||||
* All the following declarations are only for backward compatibility
|
||||
* with TS-RPC.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */
|
||||
|
||||
/*
|
||||
* TCP based rpc
|
||||
* CLIENT *
|
||||
* clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long prog;
|
||||
* u_long version;
|
||||
* register int *sockp;
|
||||
* u_int sendsz;
|
||||
* u_int recvsz;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clnttcp_create __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
int *,
|
||||
u_int,
|
||||
u_int));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Raw (memory) rpc.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clntraw_create __P((u_long, u_long));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* UDP based rpc.
|
||||
* CLIENT *
|
||||
* clntudp_create(raddr, program, version, wait, sockp)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long program;
|
||||
* u_long version;
|
||||
* struct timeval wait;
|
||||
* int *sockp;
|
||||
*
|
||||
* Same as above, but you specify max packet sizes.
|
||||
* CLIENT *
|
||||
* clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
|
||||
* struct sockaddr_in *raddr;
|
||||
* u_long program;
|
||||
* u_long version;
|
||||
* struct timeval wait;
|
||||
* int *sockp;
|
||||
* u_int sendsz;
|
||||
* u_int recvsz;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern CLIENT *clntudp_create __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
struct timeval,
|
||||
int *));
|
||||
extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
|
||||
u_long,
|
||||
u_long,
|
||||
struct timeval,
|
||||
int *,
|
||||
u_int,
|
||||
u_int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RPC_CLNT_SOC_H */
|
83
include/rpc/clnt_stat.h
Normal file
83
include/rpc/clnt_stat.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991, 1994, 1996, 1997 by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* clnt_stat.h - Client side remote procedure call enum
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RPC_CLNT_STAT_H
|
||||
#define _RPC_CLNT_STAT_H
|
||||
|
||||
#pragma ident "@(#)clnt_stat.h 1.2 97/04/28 SMI"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum clnt_stat {
|
||||
RPC_SUCCESS = 0, /* call succeeded */
|
||||
/*
|
||||
* local errors
|
||||
*/
|
||||
RPC_CANTENCODEARGS = 1, /* can't encode arguments */
|
||||
RPC_CANTDECODERES = 2, /* can't decode results */
|
||||
RPC_CANTSEND = 3, /* failure in sending call */
|
||||
RPC_CANTRECV = 4,
|
||||
/* failure in receiving result */
|
||||
RPC_TIMEDOUT = 5, /* call timed out */
|
||||
RPC_INTR = 18, /* call interrupted */
|
||||
RPC_UDERROR = 23, /* recv got uderr indication */
|
||||
/*
|
||||
* remote errors
|
||||
*/
|
||||
RPC_VERSMISMATCH = 6, /* rpc versions not compatible */
|
||||
RPC_AUTHERROR = 7, /* authentication error */
|
||||
RPC_PROGUNAVAIL = 8, /* program not available */
|
||||
RPC_PROGVERSMISMATCH = 9, /* program version mismatched */
|
||||
RPC_PROCUNAVAIL = 10, /* procedure unavailable */
|
||||
RPC_CANTDECODEARGS = 11, /* decode arguments error */
|
||||
RPC_SYSTEMERROR = 12, /* generic "other problem" */
|
||||
|
||||
/*
|
||||
* rpc_call & clnt_create errors
|
||||
*/
|
||||
RPC_UNKNOWNHOST = 13, /* unknown host name */
|
||||
RPC_UNKNOWNPROTO = 17, /* unknown protocol */
|
||||
RPC_UNKNOWNADDR = 19, /* Remote address unknown */
|
||||
RPC_NOBROADCAST = 21, /* Broadcasting not supported */
|
||||
|
||||
/*
|
||||
* rpcbind errors
|
||||
*/
|
||||
RPC_RPCBFAILURE = 14, /* the pmapper failed in its call */
|
||||
#define RPC_PMAPFAILURE RPC_RPCBFAILURE
|
||||
RPC_PROGNOTREGISTERED = 15, /* remote program is not registered */
|
||||
RPC_N2AXLATEFAILURE = 22,
|
||||
/* Name to address translation failed */
|
||||
/*
|
||||
* Misc error in the TLI library
|
||||
*/
|
||||
RPC_TLIERROR = 20,
|
||||
/*
|
||||
* unspecified error
|
||||
*/
|
||||
RPC_FAILED = 16,
|
||||
/*
|
||||
* asynchronous errors
|
||||
*/
|
||||
RPC_INPROGRESS = 24,
|
||||
RPC_STALERACHANDLE = 25,
|
||||
RPC_CANTCONNECT = 26, /* couldn't make connection (cots) */
|
||||
RPC_XPRTFAILED = 27, /* received discon from remote (cots) */
|
||||
RPC_CANTCREATESTREAM = 28 /* can't push rpc module (cots) */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_RPC_CLNT_STAT_H */
|
@ -33,6 +33,16 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* des_crypt.h, des library routine interface
|
||||
*/
|
||||
|
||||
#ifndef _DES_DES_CRYPT_H
|
||||
#define _DES_DES_CRYPT_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <rpc/rpc.h>
|
||||
@ -75,46 +85,22 @@
|
||||
* Cipher Block Chaining mode
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
#ifdef __STDC__
|
||||
int cbc_crypt __P(( char *, char *, unsigned int, unsigned int, char *));
|
||||
#else
|
||||
cbc_crypt(/* key, buf, len, mode, ivec */); /*
|
||||
char *key;
|
||||
char *buf;
|
||||
unsigned len;
|
||||
unsigned mode;
|
||||
char *ivec;
|
||||
*/
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Electronic Code Book mode
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
__BEGIN_DECLS
|
||||
int ecb_crypt __P(( char *, char *, unsigned int, unsigned int ));
|
||||
#else
|
||||
ecb_crypt(/* key, buf, len, mode */); /*
|
||||
char *key;
|
||||
char *buf;
|
||||
unsigned len;
|
||||
unsigned mode;
|
||||
*/
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#ifndef _KERNEL
|
||||
/*
|
||||
* Set des parity for a key.
|
||||
* DES parity is odd and in the low bit of each byte
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
#ifdef __STDC__
|
||||
void des_setparity __P(( char *));
|
||||
#else
|
||||
void
|
||||
des_setparity(/* key */); /*
|
||||
char *key;
|
||||
*/
|
||||
#endif
|
||||
__END_DECLS
|
||||
#endif
|
||||
|
||||
#endif /* _DES_DES_CRYPT_H */
|
||||
|
64
include/rpc/nettype.h
Normal file
64
include/rpc/nettype.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* $NetBSD: nettype.h,v 1.2 2000/07/06 03:17:19 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* nettype.h, Nettype definitions.
|
||||
* All for the topmost layer of rpc
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RPC_NETTYPE_H
|
||||
#define _RPC_NETTYPE_H
|
||||
|
||||
#include <netconfig.h>
|
||||
|
||||
#define _RPC_NONE 0
|
||||
#define _RPC_NETPATH 1
|
||||
#define _RPC_VISIBLE 2
|
||||
#define _RPC_CIRCUIT_V 3
|
||||
#define _RPC_DATAGRAM_V 4
|
||||
#define _RPC_CIRCUIT_N 5
|
||||
#define _RPC_DATAGRAM_N 6
|
||||
#define _RPC_TCP 7
|
||||
#define _RPC_UDP 8
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern void *__rpc_setconf __P((const char *));
|
||||
extern void __rpc_endconf __P((void *));
|
||||
extern struct netconfig *__rpc_getconf __P((void *));
|
||||
extern struct netconfig *__rpc_getconfip __P((const char *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_NETTYPE_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_clnt.h,v 1.9 2000/06/02 22:57:55 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,7 +28,7 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
|
||||
* from: @(#)pmap_clnt.h 1.11 88/02/08 SMI
|
||||
* from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -60,8 +62,8 @@
|
||||
* address if the responder to the broadcast.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_PMAPCLNT_H
|
||||
#define _RPC_PMAPCLNT_H
|
||||
#ifndef _RPC_PMAP_CLNT_H_
|
||||
#define _RPC_PMAP_CLNT_H_
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
@ -76,10 +78,9 @@ extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *,
|
||||
extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long,
|
||||
xdrproc_t, char *,
|
||||
xdrproc_t, char *,
|
||||
bool_t (*) __P((caddr_t,
|
||||
struct sockaddr_in *))));
|
||||
resultproc_t));
|
||||
extern u_short pmap_getport __P((struct sockaddr_in *,
|
||||
u_long, u_long, u_int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_PMAPCLNT_H */
|
||||
#endif /* !_RPC_PMAP_CLNT_H_ */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_prot.h,v 1.8 2000/06/02 22:57:55 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,7 +28,7 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)pmap_prot.h 1.14 88/02/08 SMI
|
||||
* from: @(#)pmap_prot.h 1.14 88/02/08 SMI
|
||||
* from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC
|
||||
* $FreeBSD$
|
||||
*/
|
||||
@ -68,8 +70,8 @@
|
||||
* The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_PMAPPROT_H
|
||||
#define _RPC_PMAPPROT_H
|
||||
#ifndef _RPC_PMAP_PROT_H
|
||||
#define _RPC_PMAP_PROT_H
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define PMAPPORT ((u_short)111)
|
||||
@ -99,6 +101,7 @@ struct pmaplist {
|
||||
__BEGIN_DECLS
|
||||
extern bool_t xdr_pmap __P((XDR *, struct pmap *));
|
||||
extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **));
|
||||
extern bool_t xdr_pmaplist_ptr __P((XDR *, struct pmaplist *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_PMAPPROT_H */
|
||||
#endif /* !_RPC_PMAP_PROT_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_rmt.h,v 1.7 1998/02/11 23:01:23 lukem Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -38,8 +40,8 @@
|
||||
* Copyright (C) 1986, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_PMAPRMT_H
|
||||
#define _RPC_PMAPRMT_H
|
||||
#ifndef _RPC_PMAP_RMT_H
|
||||
#define _RPC_PMAP_RMT_H
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
struct rmtcallargs {
|
||||
@ -60,4 +62,4 @@ extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *));
|
||||
extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_PMAPRMT_H */
|
||||
#endif /* !_RPC_PMAP_RMT_H */
|
||||
|
58
include/rpc/raw.h
Normal file
58
include/rpc/raw.h
Normal file
@ -0,0 +1,58 @@
|
||||
/* $NetBSD: raw.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_RAW_H
|
||||
#define _RPC_RAW_H
|
||||
|
||||
/* from: @(#)raw.h 1.11 94/04/25 SMI */
|
||||
/* from: @(#)raw.h 1.2 88/10/25 SMI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* raw.h
|
||||
*
|
||||
* Raw interface
|
||||
* The common memory area over which they will communicate
|
||||
*/
|
||||
extern char *__rpc_rawcombuf;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RPC_RAW_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc.h,v 1.13 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -41,6 +43,7 @@
|
||||
#define _RPC_RPC_H
|
||||
|
||||
#include <rpc/types.h> /* some typedefs */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
/* external data representation interfaces */
|
||||
@ -65,30 +68,40 @@
|
||||
#include <rpc/svc.h> /* service manager and multiplexer */
|
||||
#include <rpc/svc_auth.h> /* service side authenticator */
|
||||
|
||||
/*
|
||||
* COMMENT OUT THE NEXT INCLUDE (or add to the #ifndef) IF RUNNING ON
|
||||
* A VERSION OF UNIX THAT USES SUN'S NFS SOURCE. These systems will
|
||||
* already have the structures defined by <rpc/netdb.h> included in <netdb.h>.
|
||||
*/
|
||||
/* routines for parsing /etc/rpc */
|
||||
/* Portmapper client, server, and protocol headers */
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
|
||||
struct rpcent {
|
||||
char *r_name; /* name of server for this rpc program */
|
||||
char **r_aliases; /* alias list */
|
||||
int r_number; /* rpc program number */
|
||||
};
|
||||
#include <rpc/rpcb_clnt.h> /* rpcbind interface functions */
|
||||
|
||||
#include <rpc/rpcent.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern struct rpcent *getrpcbyname __P((char *));
|
||||
extern struct rpcent *getrpcbynumber __P((int));
|
||||
extern struct rpcent *getrpcent __P((void));
|
||||
extern int getrpcport __P((char *host, int prognum, int versnum, int proto));
|
||||
extern void setrpcent __P((int));
|
||||
extern void endrpcent __P((void));
|
||||
|
||||
extern int bindresvport __P((int, struct sockaddr_in *));
|
||||
extern int bindresvport_sa __P((int, struct sockaddr *));
|
||||
extern int get_myaddress __P((struct sockaddr_in *));
|
||||
extern int bindresvport __P((int, struct sockaddr_in *));
|
||||
extern int registerrpc __P((int, int, int, char *(*) __P((char [UDPMSGSIZE])),
|
||||
xdrproc_t, xdrproc_t));
|
||||
extern int callrpc __P((char *, int, int, int, xdrproc_t, char *,
|
||||
xdrproc_t , char *));
|
||||
extern int getrpcport __P((char *, int, int, int));
|
||||
|
||||
char *taddr2uaddr __P((const struct netconfig *, const struct netbuf *));
|
||||
struct netbuf *uaddr2taddr __P((const struct netconfig *, const char *));
|
||||
|
||||
struct sockaddr;
|
||||
extern int bindresvport_sa __P((int, struct sockaddr *));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* The following are not exported interfaces, they are for internal library
|
||||
* and rpcbind use only. Do not use, they may change without notice.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
int __rpc_nconf2fd __P((const struct netconfig *));
|
||||
int __rpc_nconf2sockinfo __P((const struct netconfig *,
|
||||
struct __rpc_sockinfo *));
|
||||
int __rpc_fd2sockinfo __P((int, struct __rpc_sockinfo *));
|
||||
u_int __rpc_get_t_size __P((int, int, int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_RPC_H */
|
||||
|
@ -1,3 +1,6 @@
|
||||
/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -39,17 +42,10 @@
|
||||
#ifndef _RPC_RPCCOM_H
|
||||
#define _RPC_RPCCOM_H
|
||||
|
||||
/* From: #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
|
||||
|
||||
/*
|
||||
* File descriptor to be used on xxx_create calls to get default descriptor
|
||||
*/
|
||||
#define RPC_ANYSOCK -1
|
||||
#define RPC_ANYFD RPC_ANYSOCK
|
||||
/*
|
||||
* The max size of the transport, if the size cannot be determined
|
||||
* by other means.
|
||||
@ -57,22 +53,31 @@ extern "C" {
|
||||
#define RPC_MAXDATASIZE 9000
|
||||
#define RPC_MAXADDRSIZE 1024
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
extern u_int __rpc_get_t_size (int, long);
|
||||
extern u_int __rpc_get_a_size (long);
|
||||
extern int __rpc_dtbsize (void);
|
||||
extern int _rpc_dtablesize (void);
|
||||
extern int _rpc_get_default_domain(char **);
|
||||
#else
|
||||
extern u_int __rpc_get_t_size ();
|
||||
extern u_int __rpc_get_a_size ();
|
||||
extern int __rpc_dtbsize ();
|
||||
extern int _rpc_dtablesize ();
|
||||
extern int _rpc_get_default_domain();
|
||||
#endif
|
||||
#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \
|
||||
(u_int32_t)(now)->tv_usec)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
__BEGIN_DECLS
|
||||
extern u_int __rpc_get_a_size __P((int));
|
||||
extern int __rpc_dtbsize __P((void));
|
||||
extern struct netconfig * __rpcgettp __P((int));
|
||||
extern int __rpc_get_default_domain __P((char **));
|
||||
|
||||
char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *));
|
||||
struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *));
|
||||
int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *));
|
||||
int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **));
|
||||
int __rpc_seman2socktype __P((int));
|
||||
int __rpc_socktype2seman __P((int));
|
||||
void *rpc_nullproc __P((CLIENT *));
|
||||
int __rpc_sockisbound __P((int));
|
||||
|
||||
struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t,
|
||||
const struct netconfig *,
|
||||
const char *, CLIENT **));
|
||||
bool_t __rpc_control __P((int,void *));
|
||||
|
||||
char *_get_next_token __P((char *, int));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RPC_RPCCOM_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc_msg.h,v 1.11 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -38,10 +40,10 @@
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_RPCMSG_H
|
||||
#define _RPC_RPCMSG_H
|
||||
#ifndef _RPC_RPC_MSG_H
|
||||
#define _RPC_RPC_MSG_H
|
||||
|
||||
#define RPC_MSG_VERSION ((u_long) 2)
|
||||
#define RPC_MSG_VERSION ((u_int32_t) 2)
|
||||
#define RPC_SERVICE_PORT ((u_short) 2048)
|
||||
|
||||
/*
|
||||
@ -88,8 +90,8 @@ struct accepted_reply {
|
||||
enum accept_stat ar_stat;
|
||||
union {
|
||||
struct {
|
||||
u_int32_t low;
|
||||
u_int32_t high;
|
||||
rpcvers_t low;
|
||||
rpcvers_t high;
|
||||
} AR_versions;
|
||||
struct {
|
||||
caddr_t where;
|
||||
@ -108,8 +110,8 @@ struct rejected_reply {
|
||||
enum reject_stat rj_stat;
|
||||
union {
|
||||
struct {
|
||||
u_int32_t low;
|
||||
u_int32_t high;
|
||||
rpcvers_t low;
|
||||
rpcvers_t high;
|
||||
} RJ_versions;
|
||||
enum auth_stat RJ_why; /* why authentication did not work */
|
||||
} ru;
|
||||
@ -134,10 +136,10 @@ struct reply_body {
|
||||
* Body of an rpc request call.
|
||||
*/
|
||||
struct call_body {
|
||||
u_int32_t cb_rpcvers; /* must be equal to two */
|
||||
u_int32_t cb_prog;
|
||||
u_int32_t cb_vers;
|
||||
u_int32_t cb_proc;
|
||||
rpcvers_t cb_rpcvers; /* must be equal to two */
|
||||
rpcprog_t cb_prog;
|
||||
rpcvers_t cb_vers;
|
||||
rpcproc_t cb_proc;
|
||||
struct opaque_auth cb_cred;
|
||||
struct opaque_auth cb_verf; /* protocol specific - provided by client */
|
||||
};
|
||||
@ -183,14 +185,30 @@ extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *));
|
||||
*/
|
||||
extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *));
|
||||
|
||||
|
||||
/*
|
||||
* XDR routine to handle a accepted rpc reply.
|
||||
* xdr_accepted_reply(xdrs, rej)
|
||||
* XDR *xdrs;
|
||||
* struct accepted_reply *rej;
|
||||
*/
|
||||
extern bool_t xdr_accepted_reply __P((XDR *, struct accepted_reply *));
|
||||
|
||||
/*
|
||||
* XDR routine to handle a rejected rpc reply.
|
||||
* xdr_rejected_reply(xdrs, rej)
|
||||
* XDR *xdrs;
|
||||
* struct rejected_reply *rej;
|
||||
*/
|
||||
extern bool_t xdr_rejected_reply __P((XDR *, struct rejected_reply *));
|
||||
|
||||
/*
|
||||
* Fills in the error part of a reply message.
|
||||
* _seterr_reply(msg, error)
|
||||
* struct rpc_msg *msg;
|
||||
* struct rpc_err *error;
|
||||
*/
|
||||
struct rpc_err;
|
||||
extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_RPCMSG_H */
|
||||
#endif /* !_RPC_RPC_MSG_H */
|
||||
|
85
include/rpc/rpcb_clnt.h
Normal file
85
include/rpc/rpcb_clnt.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* $NetBSD: rpcb_clnt.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* rpcb_clnt.h
|
||||
* Supplies C routines to get to rpcbid services.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
* success = rpcb_set(program, version, nconf, address);
|
||||
* success = rpcb_unset(program, version, nconf);
|
||||
* success = rpcb_getaddr(program, version, nconf, host);
|
||||
* head = rpcb_getmaps(nconf, host);
|
||||
* clnt_stat = rpcb_rmtcall(nconf, host, program, version, procedure,
|
||||
* xdrargs, argsp, xdrres, resp, tout, addr_ptr)
|
||||
* success = rpcb_gettime(host, timep)
|
||||
* uaddr = rpcb_taddr2uaddr(nconf, taddr);
|
||||
* taddr = rpcb_uaddr2uaddr(nconf, uaddr);
|
||||
*/
|
||||
|
||||
#ifndef _RPC_RPCB_CLNT_H
|
||||
#define _RPC_RPCB_CLNT_H
|
||||
|
||||
/* #pragma ident "@(#)rpcb_clnt.h 1.13 94/04/25 SMI" */
|
||||
/* rpcb_clnt.h 1.3 88/12/05 SMI */
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern bool_t rpcb_set __P((const rpcprog_t, const rpcvers_t,
|
||||
const struct netconfig *, const struct netbuf *));
|
||||
extern bool_t rpcb_unset __P((const rpcprog_t, const rpcvers_t,
|
||||
const struct netconfig *));
|
||||
extern rpcblist *rpcb_getmaps __P((const struct netconfig *, const char *));
|
||||
extern enum clnt_stat rpcb_rmtcall __P((const struct netconfig *,
|
||||
const char *, const rpcprog_t,
|
||||
const rpcvers_t, const rpcproc_t,
|
||||
const xdrproc_t, const caddr_t,
|
||||
const xdrproc_t, const caddr_t,
|
||||
const struct timeval,
|
||||
const struct netbuf *));
|
||||
extern bool_t rpcb_getaddr __P((const rpcprog_t, const rpcvers_t,
|
||||
const struct netconfig *, struct netbuf *,
|
||||
const char *));
|
||||
extern bool_t rpcb_gettime __P((const char *, time_t *));
|
||||
extern char *rpcb_taddr2uaddr __P((struct netconfig *, struct netbuf *));
|
||||
extern struct netbuf *rpcb_uaddr2taddr __P((struct netconfig *, char *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_RPCB_CLNT_H */
|
554
include/rpc/rpcb_prot.x
Normal file
554
include/rpc/rpcb_prot.x
Normal file
@ -0,0 +1,554 @@
|
||||
%/*
|
||||
% * $FreeBSD$
|
||||
% *
|
||||
% * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
% * unrestricted use provided that this legend is included on all tape
|
||||
% * media and as a part of the software program in whole or part. Users
|
||||
% * may copy or modify Sun RPC without charge, but are not authorized
|
||||
% * to license or distribute it to anyone else except as part of a product or
|
||||
% * program developed by the user.
|
||||
% *
|
||||
% * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
% * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
% * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
% *
|
||||
% * Sun RPC is provided with no support and without any obligation on the
|
||||
% * part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
% * modification or enhancement.
|
||||
% *
|
||||
% * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
% * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
% * OR ANY PART THEREOF.
|
||||
% *
|
||||
% * In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
% * or profits or other special, indirect and consequential damages, even if
|
||||
% * Sun has been advised of the possibility of such damages.
|
||||
% *
|
||||
% * Sun Microsystems, Inc.
|
||||
% * 2550 Garcia Avenue
|
||||
% * Mountain View, California 94043
|
||||
% */
|
||||
%/*
|
||||
% * Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
% */
|
||||
|
||||
%/* from rpcb_prot.x */
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%/* #pragma ident "@(#)rpcb_prot.x 1.5 94/04/29 SMI" */
|
||||
%
|
||||
%#ifndef _KERNEL
|
||||
%
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rpcb_prot.x
|
||||
* rpcbind protocol, versions 3 and 4, in RPC Language
|
||||
*/
|
||||
%
|
||||
%/*
|
||||
% * The following procedures are supported by the protocol in version 3:
|
||||
% *
|
||||
% * RPCBPROC_NULL() returns ()
|
||||
% * takes nothing, returns nothing
|
||||
% *
|
||||
% * RPCBPROC_SET(rpcb) returns (bool_t)
|
||||
% * TRUE is success, FALSE is failure. Registers the tuple
|
||||
% * [prog, vers, address, owner, netid].
|
||||
% * Finds out owner and netid information on its own.
|
||||
% *
|
||||
% * RPCBPROC_UNSET(rpcb) returns (bool_t)
|
||||
% * TRUE is success, FALSE is failure. Un-registers tuple
|
||||
% * [prog, vers, netid]. addresses is ignored.
|
||||
% * If netid is NULL, unregister all.
|
||||
% *
|
||||
% * RPCBPROC_GETADDR(rpcb) returns (string).
|
||||
% * 0 is failure. Otherwise returns the universal address where the
|
||||
% * triple [prog, vers, netid] is registered. Ignore address and owner.
|
||||
% *
|
||||
% * RPCBPROC_DUMP() RETURNS (rpcblist_ptr)
|
||||
% * used to dump the entire rpcbind maps
|
||||
% *
|
||||
% * RPCBPROC_CALLIT(rpcb_rmtcallargs)
|
||||
% * RETURNS (rpcb_rmtcallres);
|
||||
% * Calls the procedure on the remote machine. If it is not registered,
|
||||
% * this procedure is quiet; i.e. it does not return error information!!!
|
||||
% * This routine only passes null authentication parameters.
|
||||
% * It has no interface to xdr routines for RPCBPROC_CALLIT.
|
||||
% *
|
||||
% * RPCBPROC_GETTIME() returns (int).
|
||||
% * Gets the remote machines time
|
||||
% *
|
||||
% * RPCBPROC_UADDR2TADDR(strint) RETURNS (struct netbuf)
|
||||
% * Returns the netbuf address from universal address.
|
||||
% *
|
||||
% * RPCBPROC_TADDR2UADDR(struct netbuf) RETURNS (string)
|
||||
% * Returns the universal address from netbuf address.
|
||||
% *
|
||||
% * END OF RPCBIND VERSION 3 PROCEDURES
|
||||
% */
|
||||
%/*
|
||||
% * Except for RPCBPROC_CALLIT, the procedures above are carried over to
|
||||
% * rpcbind version 4. Those below are added or modified for version 4.
|
||||
% * NOTE: RPCBPROC_BCAST HAS THE SAME FUNCTIONALITY AND PROCEDURE NUMBER
|
||||
% * AS RPCBPROC_CALLIT.
|
||||
% *
|
||||
% * RPCBPROC_BCAST(rpcb_rmtcallargs)
|
||||
% * RETURNS (rpcb_rmtcallres);
|
||||
% * Calls the procedure on the remote machine. If it is not registered,
|
||||
% * this procedure IS quiet; i.e. it DOES NOT return error information!!!
|
||||
% * This routine should be used for broadcasting and nothing else.
|
||||
% *
|
||||
% * RPCBPROC_GETVERSADDR(rpcb) returns (string).
|
||||
% * 0 is failure. Otherwise returns the universal address where the
|
||||
% * triple [prog, vers, netid] is registered. Ignore address and owner.
|
||||
% * Same as RPCBPROC_GETADDR except that if the given version number
|
||||
% * is not available, the address is not returned.
|
||||
% *
|
||||
% * RPCBPROC_INDIRECT(rpcb_rmtcallargs)
|
||||
% * RETURNS (rpcb_rmtcallres);
|
||||
% * Calls the procedure on the remote machine. If it is not registered,
|
||||
% * this procedure is NOT quiet; i.e. it DOES return error information!!!
|
||||
% * as any normal application would expect.
|
||||
% *
|
||||
% * RPCBPROC_GETADDRLIST(rpcb) returns (rpcb_entry_list_ptr).
|
||||
% * Same as RPCBPROC_GETADDR except that it returns a list of all the
|
||||
% * addresses registered for the combination (prog, vers) (for all
|
||||
% * transports).
|
||||
% *
|
||||
% * RPCBPROC_GETSTAT(void) returns (rpcb_stat_byvers)
|
||||
% * Returns the statistics about the kind of requests received by rpcbind.
|
||||
% */
|
||||
%
|
||||
%/*
|
||||
% * A mapping of (program, version, network ID) to address
|
||||
% */
|
||||
struct rpcb {
|
||||
rpcprog_t r_prog; /* program number */
|
||||
rpcvers_t r_vers; /* version number */
|
||||
string r_netid<>; /* network id */
|
||||
string r_addr<>; /* universal address */
|
||||
string r_owner<>; /* owner of this service */
|
||||
};
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%typedef rpcb RPCB;
|
||||
%
|
||||
#endif
|
||||
%
|
||||
%/*
|
||||
% * A list of mappings
|
||||
% *
|
||||
% * Below are two definitions for the rpcblist structure. This is done because
|
||||
% * xdr_rpcblist() is specified to take a struct rpcblist **, rather than a
|
||||
% * struct rpcblist * that rpcgen would produce. One version of the rpcblist
|
||||
% * structure (actually called rp__list) is used with rpcgen, and the other is
|
||||
% * defined only in the header file for compatibility with the specified
|
||||
% * interface.
|
||||
% */
|
||||
|
||||
struct rp__list {
|
||||
rpcb rpcb_map;
|
||||
struct rp__list *rpcb_next;
|
||||
};
|
||||
|
||||
typedef rp__list *rpcblist_ptr; /* results of RPCBPROC_DUMP */
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%typedef struct rp__list rpcblist;
|
||||
%typedef struct rp__list RPCBLIST;
|
||||
%
|
||||
%#ifndef __cplusplus
|
||||
%struct rpcblist {
|
||||
% RPCB rpcb_map;
|
||||
% struct rpcblist *rpcb_next;
|
||||
%};
|
||||
%#endif
|
||||
%
|
||||
%#ifdef __cplusplus
|
||||
%extern "C" {
|
||||
%#endif
|
||||
%extern bool_t xdr_rpcblist(XDR *, rpcblist**);
|
||||
%#ifdef __cplusplus
|
||||
%}
|
||||
%#endif
|
||||
%
|
||||
#endif
|
||||
|
||||
%
|
||||
%/*
|
||||
% * Arguments of remote calls
|
||||
% */
|
||||
struct rpcb_rmtcallargs {
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
rpcproc_t proc; /* procedure number */
|
||||
opaque args<>; /* argument */
|
||||
};
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%/*
|
||||
% * Client-side only representation of rpcb_rmtcallargs structure.
|
||||
% *
|
||||
% * The routine that XDRs the rpcb_rmtcallargs structure must deal with the
|
||||
% * opaque arguments in the "args" structure. xdr_rpcb_rmtcallargs() needs to
|
||||
% * be passed the XDR routine that knows the args' structure. This routine
|
||||
% * doesn't need to go over-the-wire (and it wouldn't make sense anyway) since
|
||||
% * the application being called already knows the args structure. So we use a
|
||||
% * different "XDR" structure on the client side, r_rpcb_rmtcallargs, which
|
||||
% * includes the args' XDR routine.
|
||||
% */
|
||||
%struct r_rpcb_rmtcallargs {
|
||||
% rpcprog_t prog;
|
||||
% rpcvers_t vers;
|
||||
% rpcproc_t proc;
|
||||
% struct {
|
||||
% u_int args_len;
|
||||
% char *args_val;
|
||||
% } args;
|
||||
% xdrproc_t xdr_args; /* encodes args */
|
||||
%};
|
||||
%
|
||||
#endif /* def RPC_HDR */
|
||||
%
|
||||
%/*
|
||||
% * Results of the remote call
|
||||
% */
|
||||
struct rpcb_rmtcallres {
|
||||
string addr<>; /* remote universal address */
|
||||
opaque results<>; /* result */
|
||||
};
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%/*
|
||||
% * Client-side only representation of rpcb_rmtcallres structure.
|
||||
% */
|
||||
%struct r_rpcb_rmtcallres {
|
||||
% char *addr;
|
||||
% struct {
|
||||
% u_int32_t results_len;
|
||||
% char *results_val;
|
||||
% } results;
|
||||
% xdrproc_t xdr_res; /* decodes results */
|
||||
%};
|
||||
#endif RPC_HDR
|
||||
%
|
||||
%/*
|
||||
% * rpcb_entry contains a merged address of a service on a particular
|
||||
% * transport, plus associated netconfig information. A list of rpcb_entrys
|
||||
% * is returned by RPCBPROC_GETADDRLIST. See netconfig.h for values used
|
||||
% * in r_nc_* fields.
|
||||
% */
|
||||
struct rpcb_entry {
|
||||
string r_maddr<>; /* merged address of service */
|
||||
string r_nc_netid<>; /* netid field */
|
||||
unsigned int r_nc_semantics; /* semantics of transport */
|
||||
string r_nc_protofmly<>; /* protocol family */
|
||||
string r_nc_proto<>; /* protocol name */
|
||||
};
|
||||
%
|
||||
%/*
|
||||
% * A list of addresses supported by a service.
|
||||
% */
|
||||
struct rpcb_entry_list {
|
||||
rpcb_entry rpcb_entry_map;
|
||||
struct rpcb_entry_list *rpcb_entry_next;
|
||||
};
|
||||
|
||||
typedef rpcb_entry_list *rpcb_entry_list_ptr;
|
||||
|
||||
%
|
||||
%/*
|
||||
% * rpcbind statistics
|
||||
% */
|
||||
%
|
||||
const rpcb_highproc_2 = RPCBPROC_CALLIT;
|
||||
const rpcb_highproc_3 = RPCBPROC_TADDR2UADDR;
|
||||
const rpcb_highproc_4 = RPCBPROC_GETSTAT;
|
||||
|
||||
const RPCBSTAT_HIGHPROC = 13; /* # of procs in rpcbind V4 plus one */
|
||||
const RPCBVERS_STAT = 3; /* provide only for rpcbind V2, V3 and V4 */
|
||||
const RPCBVERS_4_STAT = 2;
|
||||
const RPCBVERS_3_STAT = 1;
|
||||
const RPCBVERS_2_STAT = 0;
|
||||
%
|
||||
%/* Link list of all the stats about getport and getaddr */
|
||||
struct rpcbs_addrlist {
|
||||
rpcprog_t prog;
|
||||
rpcvers_t vers;
|
||||
int success;
|
||||
int failure;
|
||||
string netid<>;
|
||||
struct rpcbs_addrlist *next;
|
||||
};
|
||||
%
|
||||
%/* Link list of all the stats about rmtcall */
|
||||
struct rpcbs_rmtcalllist {
|
||||
rpcprog_t prog;
|
||||
rpcvers_t vers;
|
||||
rpcproc_t proc;
|
||||
int success;
|
||||
int failure;
|
||||
int indirect; /* whether callit or indirect */
|
||||
string netid<>;
|
||||
struct rpcbs_rmtcalllist *next;
|
||||
};
|
||||
|
||||
typedef int rpcbs_proc[RPCBSTAT_HIGHPROC];
|
||||
typedef rpcbs_addrlist *rpcbs_addrlist_ptr;
|
||||
typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr;
|
||||
|
||||
struct rpcb_stat {
|
||||
rpcbs_proc info;
|
||||
int setinfo;
|
||||
int unsetinfo;
|
||||
rpcbs_addrlist_ptr addrinfo;
|
||||
rpcbs_rmtcalllist_ptr rmtinfo;
|
||||
};
|
||||
%
|
||||
%/*
|
||||
% * One rpcb_stat structure is returned for each version of rpcbind
|
||||
% * being monitored.
|
||||
% */
|
||||
|
||||
typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT];
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%/*
|
||||
% * We don't define netbuf in RPCL, since it would contain structure member
|
||||
% * names that would conflict with the definition of struct netbuf in
|
||||
% * <tiuser.h>. Instead we merely declare the XDR routine xdr_netbuf() here,
|
||||
% * and implement it ourselves in rpc/rpcb_prot.c.
|
||||
% */
|
||||
%#ifdef __cplusplus
|
||||
%extern "C" bool_t xdr_netbuf(XDR *, struct netbuf *);
|
||||
%
|
||||
%#else __STDC__
|
||||
%extern bool_t xdr_netbuf(XDR *, struct netbuf *);
|
||||
%
|
||||
%#endif
|
||||
#endif /* def RPC_HDR */
|
||||
|
||||
/*
|
||||
* rpcbind procedures
|
||||
*/
|
||||
program RPCBPROG {
|
||||
version RPCBVERS {
|
||||
bool
|
||||
RPCBPROC_SET(rpcb) = 1;
|
||||
|
||||
bool
|
||||
RPCBPROC_UNSET(rpcb) = 2;
|
||||
|
||||
string
|
||||
RPCBPROC_GETADDR(rpcb) = 3;
|
||||
|
||||
rpcblist_ptr
|
||||
RPCBPROC_DUMP(void) = 4;
|
||||
|
||||
rpcb_rmtcallres
|
||||
RPCBPROC_CALLIT(rpcb_rmtcallargs) = 5;
|
||||
|
||||
unsigned int
|
||||
RPCBPROC_GETTIME(void) = 6;
|
||||
|
||||
struct netbuf
|
||||
RPCBPROC_UADDR2TADDR(string) = 7;
|
||||
|
||||
string
|
||||
RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
|
||||
} = 3;
|
||||
|
||||
version RPCBVERS4 {
|
||||
bool
|
||||
RPCBPROC_SET(rpcb) = 1;
|
||||
|
||||
bool
|
||||
RPCBPROC_UNSET(rpcb) = 2;
|
||||
|
||||
string
|
||||
RPCBPROC_GETADDR(rpcb) = 3;
|
||||
|
||||
rpcblist_ptr
|
||||
RPCBPROC_DUMP(void) = 4;
|
||||
|
||||
/*
|
||||
* NOTE: RPCBPROC_BCAST has the same functionality as CALLIT;
|
||||
* the new name is intended to indicate that this
|
||||
* procedure should be used for broadcast RPC, and
|
||||
* RPCBPROC_INDIRECT should be used for indirect calls.
|
||||
*/
|
||||
rpcb_rmtcallres
|
||||
RPCBPROC_BCAST(rpcb_rmtcallargs) = RPCBPROC_CALLIT;
|
||||
|
||||
unsigned int
|
||||
RPCBPROC_GETTIME(void) = 6;
|
||||
|
||||
struct netbuf
|
||||
RPCBPROC_UADDR2TADDR(string) = 7;
|
||||
|
||||
string
|
||||
RPCBPROC_TADDR2UADDR(struct netbuf) = 8;
|
||||
|
||||
string
|
||||
RPCBPROC_GETVERSADDR(rpcb) = 9;
|
||||
|
||||
rpcb_rmtcallres
|
||||
RPCBPROC_INDIRECT(rpcb_rmtcallargs) = 10;
|
||||
|
||||
rpcb_entry_list_ptr
|
||||
RPCBPROC_GETADDRLIST(rpcb) = 11;
|
||||
|
||||
rpcb_stat_byvers
|
||||
RPCBPROC_GETSTAT(void) = 12;
|
||||
} = 4;
|
||||
} = 100000;
|
||||
#ifdef RPC_HDR
|
||||
%
|
||||
%#define RPCBVERS_3 RPCBVERS
|
||||
%#define RPCBVERS_4 RPCBVERS4
|
||||
%
|
||||
%#define _PATH_RPCBINDSOCK "/var/run/rpcbind.sock"
|
||||
%
|
||||
%#else /* ndef _KERNEL */
|
||||
%#ifdef __cplusplus
|
||||
%extern "C" {
|
||||
%#endif
|
||||
%
|
||||
%/*
|
||||
% * A mapping of (program, version, network ID) to address
|
||||
% */
|
||||
%struct rpcb {
|
||||
% rpcprog_t r_prog; /* program number */
|
||||
% rpcvers_t r_vers; /* version number */
|
||||
% char *r_netid; /* network id */
|
||||
% char *r_addr; /* universal address */
|
||||
% char *r_owner; /* owner of the mapping */
|
||||
%};
|
||||
%typedef struct rpcb RPCB;
|
||||
%
|
||||
%/*
|
||||
% * A list of mappings
|
||||
% */
|
||||
%struct rpcblist {
|
||||
% RPCB rpcb_map;
|
||||
% struct rpcblist *rpcb_next;
|
||||
%};
|
||||
%typedef struct rpcblist RPCBLIST;
|
||||
%typedef struct rpcblist *rpcblist_ptr;
|
||||
%
|
||||
%/*
|
||||
% * Remote calls arguments
|
||||
% */
|
||||
%struct rpcb_rmtcallargs {
|
||||
% rpcprog_t prog; /* program number */
|
||||
% rpcvers_t vers; /* version number */
|
||||
% rpcproc_t proc; /* procedure number */
|
||||
% u_int32_t arglen; /* arg len */
|
||||
% caddr_t args_ptr; /* argument */
|
||||
% xdrproc_t xdr_args; /* XDR routine for argument */
|
||||
%};
|
||||
%typedef struct rpcb_rmtcallargs rpcb_rmtcallargs;
|
||||
%
|
||||
%/*
|
||||
% * Remote calls results
|
||||
% */
|
||||
%struct rpcb_rmtcallres {
|
||||
% char *addr_ptr; /* remote universal address */
|
||||
% u_int32_t resultslen; /* results length */
|
||||
% caddr_t results_ptr; /* results */
|
||||
% xdrproc_t xdr_results; /* XDR routine for result */
|
||||
%};
|
||||
%typedef struct rpcb_rmtcallres rpcb_rmtcallres;
|
||||
%
|
||||
%struct rpcb_entry {
|
||||
% char *r_maddr;
|
||||
% char *r_nc_netid;
|
||||
% unsigned int r_nc_semantics;
|
||||
% char *r_nc_protofmly;
|
||||
% char *r_nc_proto;
|
||||
%};
|
||||
%typedef struct rpcb_entry rpcb_entry;
|
||||
%
|
||||
%/*
|
||||
% * A list of addresses supported by a service.
|
||||
% */
|
||||
%
|
||||
%struct rpcb_entry_list {
|
||||
% rpcb_entry rpcb_entry_map;
|
||||
% struct rpcb_entry_list *rpcb_entry_next;
|
||||
%};
|
||||
%typedef struct rpcb_entry_list rpcb_entry_list;
|
||||
%
|
||||
%typedef rpcb_entry_list *rpcb_entry_list_ptr;
|
||||
%
|
||||
%/*
|
||||
% * rpcbind statistics
|
||||
% */
|
||||
%
|
||||
%#define rpcb_highproc_2 RPCBPROC_CALLIT
|
||||
%#define rpcb_highproc_3 RPCBPROC_TADDR2UADDR
|
||||
%#define rpcb_highproc_4 RPCBPROC_GETSTAT
|
||||
%#define RPCBSTAT_HIGHPROC 13
|
||||
%#define RPCBVERS_STAT 3
|
||||
%#define RPCBVERS_4_STAT 2
|
||||
%#define RPCBVERS_3_STAT 1
|
||||
%#define RPCBVERS_2_STAT 0
|
||||
%
|
||||
%/* Link list of all the stats about getport and getaddr */
|
||||
%
|
||||
%struct rpcbs_addrlist {
|
||||
% rpcprog_t prog;
|
||||
% rpcvers_t vers;
|
||||
% int success;
|
||||
% int failure;
|
||||
% char *netid;
|
||||
% struct rpcbs_addrlist *next;
|
||||
%};
|
||||
%typedef struct rpcbs_addrlist rpcbs_addrlist;
|
||||
%
|
||||
%/* Link list of all the stats about rmtcall */
|
||||
%
|
||||
%struct rpcbs_rmtcalllist {
|
||||
% rpcprog_t prog;
|
||||
% rpcvers_t vers;
|
||||
% rpcproc_t proc;
|
||||
% int success;
|
||||
% int failure;
|
||||
% int indirect;
|
||||
% char *netid;
|
||||
% struct rpcbs_rmtcalllist *next;
|
||||
%};
|
||||
%typedef struct rpcbs_rmtcalllist rpcbs_rmtcalllist;
|
||||
%
|
||||
%typedef int rpcbs_proc[RPCBSTAT_HIGHPROC];
|
||||
%
|
||||
%typedef rpcbs_addrlist *rpcbs_addrlist_ptr;
|
||||
%
|
||||
%typedef rpcbs_rmtcalllist *rpcbs_rmtcalllist_ptr;
|
||||
%
|
||||
%struct rpcb_stat {
|
||||
% rpcbs_proc info;
|
||||
% int setinfo;
|
||||
% int unsetinfo;
|
||||
% rpcbs_addrlist_ptr addrinfo;
|
||||
% rpcbs_rmtcalllist_ptr rmtinfo;
|
||||
%};
|
||||
%typedef struct rpcb_stat rpcb_stat;
|
||||
%
|
||||
%/*
|
||||
% * One rpcb_stat structure is returned for each version of rpcbind
|
||||
% * being monitored.
|
||||
% */
|
||||
%
|
||||
%typedef rpcb_stat rpcb_stat_byvers[RPCBVERS_STAT];
|
||||
%
|
||||
%#ifdef __cplusplus
|
||||
%}
|
||||
%#endif
|
||||
%
|
||||
%#endif /* ndef _KERNEL */
|
||||
#endif /* RPC_HDR */
|
69
include/rpc/rpcent.h
Normal file
69
include/rpc/rpcent.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* $NetBSD: rpcent.h,v 1.1 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* rpcent.h,
|
||||
* For converting rpc program numbers to names etc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _RPC_RPCENT_H
|
||||
#define _RPC_RPCENT_H
|
||||
|
||||
/* #pragma ident "@(#)rpcent.h 1.13 94/04/25 SMI" */
|
||||
/* @(#)rpcent.h 1.1 88/12/06 SMI */
|
||||
|
||||
|
||||
struct rpcent {
|
||||
char *r_name; /* name of server for this rpc program */
|
||||
char **r_aliases; /* alias list */
|
||||
int r_number; /* rpc program number */
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern struct rpcent *getrpcbyname_r __P((const char *, struct rpcent *,
|
||||
char *, int));
|
||||
extern struct rpcent *getrpcbynumber_r __P((int, struct rpcent *, char *, int));
|
||||
extern struct rpcent *getrpcent_r __P((struct rpcent *, char *, int));
|
||||
|
||||
/* Old interfaces that return a pointer to a static area; MT-unsafe */
|
||||
extern struct rpcent *getrpcbyname __P((char *));
|
||||
extern struct rpcent *getrpcbynumber __P((int));
|
||||
extern struct rpcent *getrpcent __P((void));
|
||||
extern void setrpcent __P((int));
|
||||
extern void endrpcent __P((void));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_CENT_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: svc.h,v 1.17 2000/06/02 22:57:56 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,15 +28,15 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)svc.h 1.20 88/02/08 SMI
|
||||
* from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC
|
||||
* from: @(#)svc.h 1.35 88/12/17 SMI
|
||||
* from: @(#)svc.h 1.27 94/04/25 SMI
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* svc.h, Server-side remote procedure call interface.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
* Copyright (C) 1986-1993 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_SVC_H
|
||||
@ -63,21 +65,26 @@
|
||||
* parameters, struct svc_req * and SVCXPRT *, defined below.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Service control requests
|
||||
*/
|
||||
#define SVCGET_VERSQUIET 1
|
||||
#define SVCSET_VERSQUIET 2
|
||||
|
||||
|
||||
enum xprt_stat {
|
||||
XPRT_DIED,
|
||||
XPRT_MOREREQS,
|
||||
XPRT_IDLE
|
||||
};
|
||||
|
||||
struct rpc_msg;
|
||||
|
||||
/*
|
||||
* Server side transport handle
|
||||
*/
|
||||
typedef struct __rpc_svcxprt {
|
||||
int xp_sock;
|
||||
int xp_fd;
|
||||
u_short xp_port; /* associated port number */
|
||||
struct xp_ops {
|
||||
const struct xp_ops {
|
||||
/* receive incoming requests */
|
||||
bool_t (*xp_recv) __P((struct __rpc_svcxprt *,
|
||||
struct rpc_msg *));
|
||||
@ -96,16 +103,45 @@ typedef struct __rpc_svcxprt {
|
||||
void (*xp_destroy) __P((struct __rpc_svcxprt *));
|
||||
} *xp_ops;
|
||||
int xp_addrlen; /* length of remote address */
|
||||
struct sockaddr_in xp_raddr; /* remote address */
|
||||
struct sockaddr_in xp_raddr; /* remote addr. (backward ABI compat) */
|
||||
/* XXX - fvdl stick this here for ABI backward compat reasons */
|
||||
const struct xp_ops2 {
|
||||
/* catch-all function */
|
||||
bool_t (*xp_control) __P((struct __rpc_svcxprt *, const u_int,
|
||||
void *));
|
||||
} *xp_ops2;
|
||||
char *xp_tp; /* transport provider device name */
|
||||
char *xp_netid; /* network token */
|
||||
struct netbuf xp_ltaddr; /* local transport address */
|
||||
struct netbuf xp_rtaddr; /* remote transport address */
|
||||
struct opaque_auth xp_verf; /* raw response verifier */
|
||||
caddr_t xp_p1; /* private */
|
||||
caddr_t xp_p2; /* private */
|
||||
void *xp_p1; /* private: for use by svc ops */
|
||||
void *xp_p2; /* private: for use by svc ops */
|
||||
void *xp_p3; /* private: for use by svc lib */
|
||||
int xp_type; /* transport type */
|
||||
} SVCXPRT;
|
||||
|
||||
/*
|
||||
* Service request
|
||||
*/
|
||||
struct svc_req {
|
||||
u_int32_t rq_prog; /* service program number */
|
||||
u_int32_t rq_vers; /* service protocol version */
|
||||
u_int32_t rq_proc; /* the desired procedure */
|
||||
struct opaque_auth rq_cred; /* raw creds from the wire */
|
||||
void *rq_clntcred; /* read only cooked cred */
|
||||
SVCXPRT *rq_xprt; /* associated transport */
|
||||
};
|
||||
|
||||
/*
|
||||
* Approved way of getting address of caller
|
||||
*/
|
||||
#define svc_getcaller(x) (&(x)->xp_raddr)
|
||||
#define svc_getrpccaller(x) (&(x)->xp_rtaddr)
|
||||
|
||||
/*
|
||||
* FreeBSD-only definition to get the creds of the caller (AF_LOCAL).
|
||||
*/
|
||||
#define __svc_getcallercreds(x) ((struct cmsgcred *)(x)->xp_p2)
|
||||
|
||||
/*
|
||||
* Operations defined on an SVCXPRT handle
|
||||
@ -145,44 +181,36 @@ typedef struct __rpc_svcxprt {
|
||||
#define svc_destroy(xprt) \
|
||||
(*(xprt)->xp_ops->xp_destroy)(xprt)
|
||||
|
||||
|
||||
/*
|
||||
* Service request
|
||||
*/
|
||||
struct svc_req {
|
||||
u_int32_t rq_prog; /* service program number */
|
||||
u_int32_t rq_vers; /* service protocol version */
|
||||
u_int32_t rq_proc; /* the desired procedure */
|
||||
struct opaque_auth rq_cred; /* raw creds from the wire */
|
||||
caddr_t rq_clntcred; /* read only cooked cred */
|
||||
SVCXPRT *rq_xprt; /* associated transport */
|
||||
};
|
||||
|
||||
#define SVC_CONTROL(xprt, rq, in) \
|
||||
(*(xprt)->xp_ops2->xp_control)((xprt), (rq), (in))
|
||||
|
||||
/*
|
||||
* Service registration
|
||||
*
|
||||
* svc_register(xprt, prog, vers, dispatch, protocol)
|
||||
* SVCXPRT *xprt;
|
||||
* u_long prog;
|
||||
* u_long vers;
|
||||
* void (*dispatch)();
|
||||
* int protocol; (like TCP or UDP, zero means do not register)
|
||||
* svc_reg(xprt, prog, vers, dispatch, nconf)
|
||||
* const SVCXPRT *xprt;
|
||||
* const rpcprog_t prog;
|
||||
* const rpcvers_t vers;
|
||||
* const void (*dispatch)();
|
||||
* const struct netconfig *nconf;
|
||||
*/
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern bool_t svc_register __P((SVCXPRT *, u_long, u_long,
|
||||
void (*) __P((struct svc_req *, SVCXPRT *)), int));
|
||||
extern bool_t svc_reg __P((SVCXPRT *, const rpcprog_t, const rpcvers_t,
|
||||
void (*) __P((struct svc_req *, SVCXPRT *)),
|
||||
const struct netconfig *));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Service un-registration
|
||||
*
|
||||
* svc_unregister(prog, vers)
|
||||
* u_long prog;
|
||||
* u_long vers;
|
||||
* svc_unreg(prog, vers)
|
||||
* const rpcprog_t prog;
|
||||
* const rpcvers_t vers;
|
||||
*/
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern void svc_unregister __P((u_long, u_long));
|
||||
extern void svc_unreg __P((const rpcprog_t, const rpcvers_t));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
@ -206,8 +234,6 @@ extern void xprt_unregister __P((SVCXPRT *));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* When the service routine is called, it must first check to see if it
|
||||
* knows about the procedure; if not, it should call svcerr_noproc
|
||||
@ -239,10 +265,13 @@ extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *));
|
||||
extern void svcerr_decode __P((SVCXPRT *));
|
||||
extern void svcerr_weakauth __P((SVCXPRT *));
|
||||
extern void svcerr_noproc __P((SVCXPRT *));
|
||||
extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long));
|
||||
extern void svcerr_progvers __P((SVCXPRT *, rpcvers_t, rpcvers_t));
|
||||
extern void svcerr_auth __P((SVCXPRT *, enum auth_stat));
|
||||
extern void svcerr_noprog __P((SVCXPRT *));
|
||||
extern void svcerr_systemerr __P((SVCXPRT *));
|
||||
extern int rpc_reg __P((rpcprog_t, rpcvers_t, rpcproc_t,
|
||||
char *(*) __P((char *)), xdrproc_t, xdrproc_t,
|
||||
char *));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
@ -261,64 +290,130 @@ __END_DECLS
|
||||
* dynamic; must be inspected before each call to select
|
||||
*/
|
||||
extern int svc_maxfd;
|
||||
#ifdef FD_SETSIZE
|
||||
extern fd_set svc_fdset;
|
||||
#define svc_fds svc_fdset.fds_bits[0] /* compatibility */
|
||||
#else
|
||||
extern int svc_fds;
|
||||
#endif /* def FD_SETSIZE */
|
||||
|
||||
#ifndef _KERNEL
|
||||
/*
|
||||
* a small program implemented by the svc_rpc implementation itself;
|
||||
* also see clnt.h for protocol numbers.
|
||||
*/
|
||||
extern void rpctest_service();
|
||||
#endif
|
||||
__BEGIN_DECLS
|
||||
extern void rpctest_service __P((void));
|
||||
__END_DECLS
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern void svc_getreq __P((int));
|
||||
extern void svc_getreqset __P((fd_set *));
|
||||
extern void svc_getreqset2 __P((fd_set *, int)); /* XXX: nonstd, undoc */
|
||||
extern void svc_getreq_common __P((int));
|
||||
struct pollfd;
|
||||
extern void svc_getreq_poll __P((struct pollfd *, int));
|
||||
|
||||
extern void svc_run __P((void));
|
||||
extern void svc_exit __P((void));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Socket to use on svcxxx_create call to get default socket
|
||||
*/
|
||||
#define RPC_ANYSOCK -1
|
||||
#define RPC_ANYFD RPC_ANYSOCK
|
||||
|
||||
/*
|
||||
* These are the existing service side transport implementations
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory based rpc for testing and timing.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcraw_create __P((void));
|
||||
__END_DECLS
|
||||
/*
|
||||
* Transport independent svc_create routine.
|
||||
*/
|
||||
extern int svc_create __P((void (*) __P((struct svc_req *, SVCXPRT *)),
|
||||
const rpcprog_t, const rpcvers_t, const char *));
|
||||
/*
|
||||
* void (*dispatch)(); -- dispatch routine
|
||||
* const rpcprog_t prognum; -- program number
|
||||
* const rpcvers_t versnum; -- version number
|
||||
* const char *nettype; -- network type
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Udp based rpc.
|
||||
* Generic server creation routine. It takes a netconfig structure
|
||||
* instead of a nettype.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcudp_create __P((int));
|
||||
extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int));
|
||||
__END_DECLS
|
||||
|
||||
extern SVCXPRT *svc_tp_create __P((void (*) __P((struct svc_req *, SVCXPRT *)),
|
||||
const rpcprog_t, const rpcvers_t,
|
||||
const struct netconfig *));
|
||||
/*
|
||||
* void (*dispatch)(); -- dispatch routine
|
||||
* const rpcprog_t prognum; -- program number
|
||||
* const rpcvers_t versnum; -- version number
|
||||
* const struct netconfig *nconf; -- netconfig structure
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Tcp based rpc.
|
||||
* Generic TLI create routine
|
||||
*/
|
||||
extern SVCXPRT *svc_tli_create __P((const int, const struct netconfig *,
|
||||
const struct t_bind *, const u_int,
|
||||
const u_int));
|
||||
/*
|
||||
* const int fd; -- connection end point
|
||||
* const struct netconfig *nconf; -- netconfig structure for network
|
||||
* const struct t_bind *bindaddr; -- local bind address
|
||||
* const u_int sendsz; -- max sendsize
|
||||
* const u_int recvsz; -- max recvsize
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svctcp_create __P((int, u_int, u_int));
|
||||
extern SVCXPRT *svcfd_create __P((int, u_int, u_int));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* AF_UNIX socket based rpc.
|
||||
* Connectionless and connectionful create routines
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcunix_create __P((int, u_int, u_int, char *));
|
||||
extern SVCXPRT *svcunixfd_create __P((int, u_int, u_int));
|
||||
|
||||
extern SVCXPRT *svc_vc_create __P((const int, const u_int, const u_int));
|
||||
/*
|
||||
* const int fd; -- open connection end point
|
||||
* const u_int sendsize; -- max send size
|
||||
* const u_int recvsize; -- max recv size
|
||||
*/
|
||||
|
||||
extern SVCXPRT *svc_dg_create __P((const int, const u_int, const u_int));
|
||||
/*
|
||||
* const int fd; -- open connection
|
||||
* const u_int sendsize; -- max send size
|
||||
* const u_int recvsize; -- max recv size
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* the routine takes any *open* connection
|
||||
* descriptor as its first input and is used for open connections.
|
||||
*/
|
||||
extern SVCXPRT *svc_fd_create __P((const int, const u_int, const u_int));
|
||||
/*
|
||||
* const int fd; -- open connection end point
|
||||
* const u_int sendsize; -- max send size
|
||||
* const u_int recvsize; -- max recv size
|
||||
*/
|
||||
|
||||
/*
|
||||
* Memory based rpc (for speed check and testing)
|
||||
*/
|
||||
extern SVCXPRT *svc_raw_create __P((void));
|
||||
|
||||
/*
|
||||
* svc_dg_enable_cache() enables the cache on dg transports.
|
||||
*/
|
||||
int svc_dg_enablecache __P((SVCXPRT *, const u_int));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/* for backward compatibility */
|
||||
#include <rpc/svc_soc.h>
|
||||
|
||||
#endif /* !_RPC_SVC_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: svc_auth.h,v 1.8 2000/06/02 22:57:57 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,7 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*
|
||||
* from: @(#)svc_auth.h 1.6 86/07/16 SMI
|
||||
* from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
|
||||
* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
@ -37,20 +39,17 @@
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_SVCAUTH_H
|
||||
#define _RPC_SVCAUTH_H
|
||||
|
||||
struct rpc_msg;
|
||||
struct svc_req;
|
||||
#ifndef _RPC_SVC_AUTH_H
|
||||
#define _RPC_SVC_AUTH_H
|
||||
|
||||
/*
|
||||
* Server side authenticator
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *));
|
||||
extern int svc_auth_reg __P((int, enum auth_stat (*)(struct svc_req *,
|
||||
struct rpc_msg *)));
|
||||
extern enum auth_stat _svcauth_des __P((struct svc_req *, struct rpc_msg *));
|
||||
extern int svc_auth_reg __P((int, enum auth_stat (*) __P((struct svc_req *,
|
||||
struct rpc_msg *))));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_SVCAUTH_H */
|
||||
#endif /* !_RPC_SVC_AUTH_H */
|
||||
|
51
include/rpc/svc_dg.h
Normal file
51
include/rpc/svc_dg.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* $NetBSD: svc_dg.h,v 1.1 2000/06/02 23:11:16 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX - this file exists only so that the rpcbind code can pull it in.
|
||||
* This should go away. It should only be include by svc_dg.c and
|
||||
* rpcb_svc_com.c in the rpcbind code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* kept in xprt->xp_p2
|
||||
*/
|
||||
struct svc_dg_data {
|
||||
/* XXX: optbuf should be the first field, used by ti_opts.c code */
|
||||
size_t su_iosz; /* size of send.recv buffer */
|
||||
u_int32_t su_xid; /* transaction id */
|
||||
XDR su_xdrs; /* XDR handle */
|
||||
char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */
|
||||
void *su_cache; /* cached data, NULL if none */
|
||||
};
|
||||
|
||||
#define __rpcb_get_dg_xidp(x) (&((struct svc_dg_data *)(x)->xp_p2)->su_xid)
|
116
include/rpc/svc_soc.h
Normal file
116
include/rpc/svc_soc.h
Normal file
@ -0,0 +1,116 @@
|
||||
/* $NetBSD: svc_soc.h,v 1.1 2000/06/02 22:57:57 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* svc.h, Server-side remote procedure call interface.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_SVC_SOC_H
|
||||
#define _RPC_SVC_SOC_H
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* #pragma ident "@(#)svc_soc.h 1.11 94/04/25 SMI" */
|
||||
/* svc_soc.h 1.8 89/05/01 SMI */
|
||||
|
||||
/*
|
||||
* All the following declarations are only for backward compatibility
|
||||
* with TS-RPC
|
||||
*/
|
||||
|
||||
/*
|
||||
* Approved way of getting address of caller
|
||||
*/
|
||||
#define svc_getcaller(x) (&(x)->xp_raddr)
|
||||
|
||||
/*
|
||||
* Service registration
|
||||
*
|
||||
* svc_register(xprt, prog, vers, dispatch, protocol)
|
||||
* SVCXPRT *xprt;
|
||||
* u_long prog;
|
||||
* u_long vers;
|
||||
* void (*dispatch)();
|
||||
* int protocol; like TCP or UDP, zero means do not register
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern bool_t svc_register __P((SVCXPRT *, u_long, u_long,
|
||||
void (*) __P((struct svc_req *, SVCXPRT *)), int));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Service un-registration
|
||||
*
|
||||
* svc_unregister(prog, vers)
|
||||
* u_long prog;
|
||||
* u_long vers;
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern void svc_unregister __P((u_long, u_long));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Memory based rpc for testing and timing.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcraw_create __P((void));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Udp based rpc.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcudp_create __P((int));
|
||||
extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int));
|
||||
extern int svcudp_enablecache __P((SVCXPRT *, u_long));
|
||||
__END_DECLS
|
||||
|
||||
|
||||
/*
|
||||
* Tcp based rpc.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svctcp_create __P((int, u_int, u_int));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
* Fd based rpc.
|
||||
*/
|
||||
__BEGIN_DECLS
|
||||
extern SVCXPRT *svcfd_create __P((int, u_int, u_int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_SVC_SOC_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: types.h,v 1.13 2000/06/13 01:02:44 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -37,8 +39,18 @@
|
||||
#ifndef _RPC_TYPES_H
|
||||
#define _RPC_TYPES_H
|
||||
|
||||
#define bool_t int32_t
|
||||
#define enum_t int32_t
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef int32_t bool_t;
|
||||
typedef int32_t enum_t;
|
||||
|
||||
typedef u_int32_t rpcprog_t;
|
||||
typedef u_int32_t rpcvers_t;
|
||||
typedef u_int32_t rpcproc_t;
|
||||
typedef u_int32_t rpcprot_t;
|
||||
typedef u_int32_t rpcport_t;
|
||||
typedef int32_t rpc_inline_t;
|
||||
|
||||
#define __dontcare__ -1
|
||||
|
||||
#ifndef FALSE
|
||||
@ -51,12 +63,46 @@
|
||||
# define NULL 0
|
||||
#endif
|
||||
|
||||
#define mem_alloc(bsize) malloc(bsize)
|
||||
#define mem_alloc(bsize) calloc(1, bsize)
|
||||
#define mem_free(ptr, bsize) free(ptr)
|
||||
|
||||
#ifndef makedev /* ie, we haven't already included it */
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <netconfig.h>
|
||||
|
||||
/*
|
||||
* The netbuf structure is defined here, because FreeBSD / NetBSD only use
|
||||
* it inside the RPC code. It's in <xti.h> on SVR4, but it would be confusing
|
||||
* to have an xti.h, since FreeBSD / NetBSD does not support XTI/TLI.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The netbuf structure is used for transport-independent address storage.
|
||||
*/
|
||||
struct netbuf {
|
||||
unsigned int maxlen;
|
||||
unsigned int len;
|
||||
void *buf;
|
||||
};
|
||||
|
||||
/*
|
||||
* The format of the addres and options arguments of the XTI t_bind call.
|
||||
* Only provided for compatibility, it should not be used.
|
||||
*/
|
||||
|
||||
struct t_bind {
|
||||
struct netbuf addr;
|
||||
unsigned int qlen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Internal library and rpcbind use. This is not an exported interface, do
|
||||
* not use.
|
||||
*/
|
||||
struct __rpc_sockinfo {
|
||||
int si_af;
|
||||
int si_proto;
|
||||
int si_socktype;
|
||||
int si_alen;
|
||||
};
|
||||
|
||||
#endif /* !_RPC_TYPES_H */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: xdr.h,v 1.19 2000/07/17 05:00:45 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -97,15 +99,15 @@ enum xdr_op {
|
||||
*/
|
||||
typedef struct __rpc_xdr {
|
||||
enum xdr_op x_op; /* operation; fast additional param */
|
||||
struct xdr_ops {
|
||||
const struct xdr_ops {
|
||||
/* get a long from underlying stream */
|
||||
bool_t (*x_getlong) __P((struct __rpc_xdr *, long *));
|
||||
/* put a long to underlying stream */
|
||||
bool_t (*x_putlong) __P((struct __rpc_xdr *, long *));
|
||||
/* get some bytes from underlying stream */
|
||||
bool_t (*x_getbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
|
||||
/* put some bytes to underlying stream */
|
||||
bool_t (*x_putbytes) __P((struct __rpc_xdr *, caddr_t, u_int));
|
||||
/* put a long to " */
|
||||
bool_t (*x_putlong) __P((struct __rpc_xdr *, const long *));
|
||||
/* get some bytes from " */
|
||||
bool_t (*x_getbytes) __P((struct __rpc_xdr *, char *, u_int));
|
||||
/* put some bytes to " */
|
||||
bool_t (*x_putbytes) __P((struct __rpc_xdr *, const char *, u_int));
|
||||
/* returns bytes off from beginning */
|
||||
u_int (*x_getpostn) __P((struct __rpc_xdr *));
|
||||
/* lets you reposition the stream */
|
||||
@ -114,10 +116,11 @@ typedef struct __rpc_xdr {
|
||||
int32_t *(*x_inline) __P((struct __rpc_xdr *, u_int));
|
||||
/* free privates of this xdr_stream */
|
||||
void (*x_destroy) __P((struct __rpc_xdr *));
|
||||
bool_t (*x_control) __P((struct __rpc_xdr *, int, void *));
|
||||
} *x_ops;
|
||||
caddr_t x_public; /* users' data */
|
||||
caddr_t x_private; /* pointer to private data */
|
||||
caddr_t x_base; /* private used for position info */
|
||||
char * x_public; /* users' data */
|
||||
void * x_private; /* pointer to private data */
|
||||
char * x_base; /* private used for position info */
|
||||
int x_handy; /* extra private word */
|
||||
} XDR;
|
||||
|
||||
@ -128,22 +131,17 @@ typedef struct __rpc_xdr {
|
||||
* The opaque pointer generally points to a structure of the data type
|
||||
* to be decoded. If this pointer is 0, then the type routines should
|
||||
* allocate dynamic storage of the appropriate size and return it.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
typedef bool_t (*xdrproc_t) __P((XDR *, void *, u_int));
|
||||
#else
|
||||
/*
|
||||
* XXX can't actually prototype it, because some take two args!!!
|
||||
*
|
||||
* XXX can't actually prototype it, because some take three args!!!
|
||||
*/
|
||||
typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Operations defined on a XDR handle
|
||||
*
|
||||
* XDR *xdrs;
|
||||
* long *longp;
|
||||
* caddr_t addr;
|
||||
* char * addr;
|
||||
* u_int len;
|
||||
* u_int pos;
|
||||
*/
|
||||
@ -157,6 +155,29 @@ typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
|
||||
#define xdr_putlong(xdrs, longp) \
|
||||
(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
|
||||
|
||||
static __inline int
|
||||
xdr_getint32(XDR *xdrs, int32_t *ip)
|
||||
{
|
||||
long l;
|
||||
|
||||
if (!xdr_getlong(xdrs, &l))
|
||||
return (FALSE);
|
||||
*ip = (int32_t)l;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
xdr_putint32(XDR *xdrs, int32_t *ip)
|
||||
{
|
||||
long l;
|
||||
|
||||
l = (long)*ip;
|
||||
return xdr_putlong(xdrs, &l);
|
||||
}
|
||||
|
||||
#define XDR_GETINT32(xdrs, int32p) xdr_getint32(xdrs, int32p)
|
||||
#define XDR_PUTINT32(xdrs, int32p) xdr_putint32(xdrs, int32p)
|
||||
|
||||
#define XDR_GETBYTES(xdrs, addr, len) \
|
||||
(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
|
||||
#define xdr_getbytes(xdrs, addr, len) \
|
||||
@ -189,6 +210,21 @@ typedef bool_t (*xdrproc_t) __P((/* XDR *, void *, u_int */));
|
||||
if ((xdrs)->x_ops->x_destroy) \
|
||||
(*(xdrs)->x_ops->x_destroy)(xdrs)
|
||||
|
||||
#define XDR_CONTROL(xdrs, req, op) \
|
||||
if ((xdrs)->x_ops->x_control) \
|
||||
(*(xdrs)->x_ops->x_control)(xdrs, req, op)
|
||||
#define xdr_control(xdrs, req, op) XDR_CONTROL(xdrs, req, op)
|
||||
|
||||
/*
|
||||
* Solaris strips the '_t' from these types -- not sure why.
|
||||
* But, let's be compatible.
|
||||
*/
|
||||
#define xdr_rpcvers(xdrs, versp) xdr_u_int32(xdrs, versp)
|
||||
#define xdr_rpcprog(xdrs, progp) xdr_u_int32(xdrs, progp)
|
||||
#define xdr_rpcproc(xdrs, procp) xdr_u_int32(xdrs, procp)
|
||||
#define xdr_rpcprot(xdrs, protp) xdr_u_int32(xdrs, protp)
|
||||
#define xdr_rpcport(xdrs, portp) xdr_u_int32(xdrs, portp)
|
||||
|
||||
/*
|
||||
* Support struct for discriminated unions.
|
||||
* You create an array of xdrdiscrim structures, terminated with
|
||||
@ -220,8 +256,13 @@ struct xdr_discrim {
|
||||
* N.B. and frozen for all time: each data type here uses 4 bytes
|
||||
* of external representation.
|
||||
*/
|
||||
#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++))
|
||||
#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v))
|
||||
#define IXDR_GET_INT32(buf) ((int32_t)ntohl((u_int32_t)*(buf)++))
|
||||
#define IXDR_PUT_INT32(buf, v) (*(buf)++ =(int32_t)htonl((u_int32_t)v))
|
||||
#define IXDR_GET_U_INT32(buf) ((u_int32_t)IXDR_GET_INT32(buf))
|
||||
#define IXDR_PUT_U_INT32(buf, v) IXDR_PUT_INT32((buf), ((int32_t)(v)))
|
||||
|
||||
#define IXDR_GET_LONG(buf) ((long)ntohl((u_int32_t)*(buf)++))
|
||||
#define IXDR_PUT_LONG(buf, v) (*(buf)++ =(int32_t)htonl((u_int32_t)v))
|
||||
|
||||
#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf))
|
||||
#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf))
|
||||
@ -229,11 +270,11 @@ struct xdr_discrim {
|
||||
#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf))
|
||||
#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf))
|
||||
|
||||
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
|
||||
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
|
||||
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
|
||||
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
|
||||
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v)))
|
||||
#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), (v))
|
||||
#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), (v))
|
||||
#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), (v))
|
||||
#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), (v))
|
||||
#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), (v))
|
||||
|
||||
/*
|
||||
* These are the "generic" xdr routines.
|
||||
@ -256,19 +297,23 @@ extern bool_t xdr_bool __P((XDR *, bool_t *));
|
||||
extern bool_t xdr_enum __P((XDR *, enum_t *));
|
||||
extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t));
|
||||
extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int));
|
||||
extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int));
|
||||
extern bool_t xdr_opaque __P((XDR *, char *, u_int));
|
||||
extern bool_t xdr_string __P((XDR *, char **, u_int));
|
||||
extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t));
|
||||
extern unsigned long xdr_sizeof __P((xdrproc_t, void *));
|
||||
extern bool_t xdr_union __P((XDR *, enum_t *, char *, const struct xdr_discrim *, xdrproc_t));
|
||||
extern bool_t xdr_char __P((XDR *, char *));
|
||||
extern bool_t xdr_u_char __P((XDR *, u_char *));
|
||||
extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t));
|
||||
extern bool_t xdr_float __P((XDR *, float *));
|
||||
extern bool_t xdr_double __P((XDR *, double *));
|
||||
extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t));
|
||||
extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t));
|
||||
extern bool_t xdr_quadruple __P((XDR *, long double *));
|
||||
extern bool_t xdr_reference __P((XDR *, char **, u_int, xdrproc_t));
|
||||
extern bool_t xdr_pointer __P((XDR *, char **, u_int, xdrproc_t));
|
||||
extern bool_t xdr_wrapstring __P((XDR *, char **));
|
||||
extern void xdr_free __P((xdrproc_t, char *));
|
||||
extern bool_t xdr_hyper __P((XDR *, quad_t *));
|
||||
extern bool_t xdr_u_hyper __P((XDR *, u_quad_t *));
|
||||
extern bool_t xdr_longlong_t __P((XDR *, quad_t *));
|
||||
extern bool_t xdr_u_longlong_t __P((XDR *, u_quad_t *));
|
||||
__END_DECLS
|
||||
|
||||
/*
|
||||
@ -291,15 +336,15 @@ __BEGIN_DECLS
|
||||
/* XDR using memory buffers */
|
||||
extern void xdrmem_create __P((XDR *, char *, u_int, enum xdr_op));
|
||||
|
||||
#ifdef _STDIO_H_
|
||||
/* XDR using stdio library */
|
||||
#ifdef _STDIO_H_
|
||||
extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op));
|
||||
#endif
|
||||
|
||||
/* XDR pseudo records for tcp */
|
||||
extern void xdrrec_create __P((XDR *, u_int, u_int, char *,
|
||||
int (*) __P((caddr_t, caddr_t, int)),
|
||||
int (*) __P((caddr_t, caddr_t, int))));
|
||||
int (*) __P((char *, char *, int)),
|
||||
int (*) __P((char *, char *, int))));
|
||||
|
||||
/* make end of xdr record */
|
||||
extern bool_t xdrrec_endofrecord __P((XDR *, int));
|
||||
@ -309,6 +354,7 @@ extern bool_t xdrrec_skiprecord __P((XDR *));
|
||||
|
||||
/* true if no more input */
|
||||
extern bool_t xdrrec_eof __P((XDR *));
|
||||
extern u_int xdrrec_readbytes __P((XDR *, caddr_t, u_int));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_RPC_XDR_H */
|
||||
|
@ -44,7 +44,7 @@
|
||||
*/
|
||||
|
||||
%/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
|
||||
%
|
||||
%/* $FreeBSD$ */
|
||||
%/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
|
||||
%
|
||||
%/*
|
||||
|
@ -1,6 +1,3 @@
|
||||
/* @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC */
|
||||
/* @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro */
|
||||
|
||||
/*
|
||||
* Network lock manager protocol definition
|
||||
* Copyright (C) 1986 Sun Microsystems, Inc.
|
||||
@ -12,9 +9,13 @@
|
||||
%#define LM_MAXSTRLEN 1024
|
||||
%#define MAXNAMELEN LM_MAXSTRLEN+1
|
||||
#else
|
||||
%#include <sys/cdefs.h>
|
||||
%#ifndef lint
|
||||
%static const char rcsid[] =
|
||||
% "$FreeBSD$";
|
||||
%/*static char sccsid[] = "from: @(#)nlm_prot.x 1.8 87/09/21 Copyr 1987 Sun Micro";*/
|
||||
%/*static char sccsid[] = "from: * @(#)nlm_prot.x 2.1 88/08/01 4.0 RPCSRC";*/
|
||||
%__RCSID("$NetBSD: nlm_prot.x,v 1.6 2000/06/07 14:30:15 bouyer Exp $");
|
||||
%#endif /* not lint */
|
||||
#endif
|
||||
|
||||
@ -77,20 +78,20 @@ struct nlm_lockargs {
|
||||
};
|
||||
|
||||
struct nlm_cancargs {
|
||||
netobj cookie;
|
||||
netobj cookie;
|
||||
bool block;
|
||||
bool exclusive;
|
||||
struct nlm_lock alock;
|
||||
};
|
||||
|
||||
struct nlm_testargs {
|
||||
netobj cookie;
|
||||
netobj cookie;
|
||||
bool exclusive;
|
||||
struct nlm_lock alock;
|
||||
};
|
||||
|
||||
struct nlm_unlockargs {
|
||||
netobj cookie;
|
||||
netobj cookie;
|
||||
struct nlm_lock alock;
|
||||
};
|
||||
|
||||
@ -140,11 +141,127 @@ struct nlm_notify {
|
||||
long state;
|
||||
};
|
||||
|
||||
#ifdef RPC_HDR
|
||||
%/* definitions for NLM version 4 */
|
||||
#endif
|
||||
enum nlm4_stats {
|
||||
nlm4_granted = 0,
|
||||
nlm4_denied = 1,
|
||||
nlm4_denied_nolock = 2,
|
||||
nlm4_blocked = 3,
|
||||
nlm4_denied_grace_period = 4,
|
||||
nlm4_deadlck = 5,
|
||||
nlm4_rofs = 6,
|
||||
nlm4_stale_fh = 7,
|
||||
nlm4_fbig = 8,
|
||||
nlm4_failed = 9
|
||||
};
|
||||
|
||||
struct nlm4_stat {
|
||||
nlm4_stats stat;
|
||||
};
|
||||
|
||||
struct nlm4_holder {
|
||||
bool exclusive;
|
||||
u_int32_t svid;
|
||||
netobj oh;
|
||||
u_int64_t l_offset;
|
||||
u_int64_t l_len;
|
||||
};
|
||||
|
||||
struct nlm4_lock {
|
||||
string caller_name<MAXNAMELEN>;
|
||||
netobj fh;
|
||||
netobj oh;
|
||||
u_int32_t svid;
|
||||
u_int64_t l_offset;
|
||||
u_int64_t l_len;
|
||||
};
|
||||
|
||||
struct nlm4_share {
|
||||
string caller_name<MAXNAMELEN>;
|
||||
netobj fh;
|
||||
netobj oh;
|
||||
fsh_mode mode;
|
||||
fsh_access access;
|
||||
};
|
||||
|
||||
union nlm4_testrply switch (nlm4_stats stat) {
|
||||
case nlm_denied:
|
||||
struct nlm4_holder holder;
|
||||
default:
|
||||
void;
|
||||
};
|
||||
|
||||
struct nlm4_testres {
|
||||
netobj cookie;
|
||||
nlm4_testrply stat;
|
||||
};
|
||||
|
||||
struct nlm4_testargs {
|
||||
netobj cookie;
|
||||
bool exclusive;
|
||||
struct nlm4_lock alock;
|
||||
};
|
||||
|
||||
struct nlm4_res {
|
||||
netobj cookie;
|
||||
nlm4_stat stat;
|
||||
};
|
||||
|
||||
struct nlm4_lockargs {
|
||||
netobj cookie;
|
||||
bool block;
|
||||
bool exclusive;
|
||||
struct nlm4_lock alock;
|
||||
bool reclaim; /* used for recovering locks */
|
||||
int state; /* specify local status monitor state */
|
||||
};
|
||||
|
||||
struct nlm4_cancargs {
|
||||
netobj cookie;
|
||||
bool block;
|
||||
bool exclusive;
|
||||
struct nlm4_lock alock;
|
||||
};
|
||||
|
||||
struct nlm4_unlockargs {
|
||||
netobj cookie;
|
||||
struct nlm4_lock alock;
|
||||
};
|
||||
|
||||
struct nlm4_shareargs {
|
||||
netobj cookie;
|
||||
nlm4_share share;
|
||||
bool reclaim;
|
||||
};
|
||||
|
||||
struct nlm4_shareres {
|
||||
netobj cookie;
|
||||
nlm4_stats stat;
|
||||
int sequence;
|
||||
};
|
||||
|
||||
/*
|
||||
* argument for the procedure called by rpc.statd when a monitored host
|
||||
* status change.
|
||||
* XXX assumes LM_MAXSTRLEN == SM_MAXSTRLEN
|
||||
*/
|
||||
struct nlm_sm_status {
|
||||
string mon_name<LM_MAXSTRLEN>; /* name of host */
|
||||
int state; /* new state */
|
||||
opaque priv[16]; /* private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Over-the-wire protocol used between the network lock managers
|
||||
*/
|
||||
|
||||
program NLM_PROG {
|
||||
version NLM_SM {
|
||||
void NLM_SM_NOTIFY(struct nlm_sm_status) = 1;
|
||||
} = 0;
|
||||
|
||||
version NLM_VERS {
|
||||
|
||||
nlm_testres NLM_TEST(struct nlm_testargs) = 1;
|
||||
@ -180,5 +297,25 @@ program NLM_PROG {
|
||||
void NLM_FREE_ALL(nlm_notify) = 23;
|
||||
} = 3;
|
||||
|
||||
version NLM_VERS4 {
|
||||
nlm4_testres NLM4_TEST(nlm4_testargs) = 1;
|
||||
nlm4_res NLM4_LOCK(nlm4_lockargs) = 2;
|
||||
nlm4_res NLM4_CANCEL(nlm4_cancargs) = 3;
|
||||
nlm4_res NLM4_UNLOCK(nlm4_unlockargs) = 4;
|
||||
nlm4_res NLM4_GRANTED(nlm4_testargs) = 5;
|
||||
void NLM4_TEST_MSG(nlm4_testargs) = 6;
|
||||
void NLM4_LOCK_MSG(nlm4_lockargs) = 7;
|
||||
void NLM4_CANCEL_MSG(nlm4_cancargs) = 8;
|
||||
void NLM4_UNLOCK_MSG(nlm4_unlockargs) = 9;
|
||||
void NLM4_GRANTED_MSG(nlm4_testargs) = 10;
|
||||
void NLM4_TEST_RES(nlm4_testres) = 11;
|
||||
void NLM4_LOCK_RES(nlm4_res) = 12;
|
||||
void NLM4_CANCEL_RES(nlm4_res) = 13;
|
||||
void NLM4_UNLOCK_RES(nlm4_res) = 14;
|
||||
void NLM4_GRANTED_RES(nlm4_res) = 15;
|
||||
nlm4_shareres NLM4_SHARE(nlm4_shareargs) = 20;
|
||||
nlm4_shareres NLM4_UNSHARE(nlm4_shareargs) = 21;
|
||||
nlm4_res NLM4_NM_LOCK(nlm4_lockargs) = 22;
|
||||
void NLM4_FREE_ALL(nlm_notify) = 23;
|
||||
} = 4;
|
||||
} = 100021;
|
||||
|
||||
|
@ -62,6 +62,7 @@ program SM_PROG {
|
||||
struct sm_stat SM_UNMON_ALL(struct my_id) = 4;
|
||||
|
||||
void SM_SIMU_CRASH(void) = 5;
|
||||
void SM_NOTIFY(struct stat_chge) = 6;
|
||||
|
||||
} = 1;
|
||||
} = 100024;
|
||||
@ -90,6 +91,10 @@ struct mon{
|
||||
opaque priv[16]; /* private information to store at monitor for requesting process */
|
||||
};
|
||||
|
||||
struct stat_chge {
|
||||
string mon_name<SM_MAXSTRLEN>; /* name of the site that had the state change */
|
||||
int state;
|
||||
};
|
||||
|
||||
/*
|
||||
* state # of status monitor monitonically increases each time
|
||||
|
@ -26,7 +26,9 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
|
||||
/*
|
||||
* Weak symbols: All libc internal usage of these functions should
|
||||
@ -37,9 +39,13 @@
|
||||
* between application locks and libc locks (threads holding the
|
||||
* latter can't be allowed to exit/terminate).
|
||||
*/
|
||||
#pragma weak _pthread_cond_init=_pthread_cond_init_stub
|
||||
#pragma weak _pthread_cond_signal=_pthread_cond_signal_stub
|
||||
#pragma weak _pthread_cond_wait=_pthread_cond_wait_stub
|
||||
#pragma weak _pthread_getspecific=_pthread_getspecific_stub
|
||||
#pragma weak _pthread_key_create=_pthread_key_create_stub
|
||||
#pragma weak _pthread_key_delete=_pthread_key_delete_stub
|
||||
#pragma weak _pthread_main_np=_pthread_main_np_stub
|
||||
#pragma weak _pthread_mutex_destroy=_pthread_mutex_destroy_stub
|
||||
#pragma weak _pthread_mutex_init=_pthread_mutex_init_stub
|
||||
#pragma weak _pthread_mutex_lock=_pthread_mutex_lock_stub
|
||||
@ -50,13 +56,40 @@
|
||||
#pragma weak _pthread_mutexattr_settype=_pthread_mutexattr_settype_stub
|
||||
#pragma weak _pthread_once=_pthread_once_stub
|
||||
#pragma weak _pthread_self=_pthread_self_stub
|
||||
#pragma weak _pthread_rwlock_init=_pthread_rwlock_init_stub
|
||||
#pragma weak _pthread_rwlock_rdlock=_pthread_rwlock_rdlock_stub
|
||||
#pragma weak _pthread_rwlock_tryrdlock=_pthread_rwlock_tryrdlock_stub
|
||||
#pragma weak _pthread_rwlock_trywrloc=_pthread_rwlock_trywrlock_stub
|
||||
#pragma weak _pthread_rwlock_unlock=_pthread_rwlock_unlock_stub
|
||||
#pragma weak _pthread_rwlock_wrlock=_pthread_rwlock_wrlock_stub
|
||||
#pragma weak _pthread_setspecific=_pthread_setspecific_stub
|
||||
#pragma weak _pthread_sigmask=_pthread_sigmask_stub
|
||||
|
||||
/* Define a null pthread structure just to satisfy _pthread_self. */
|
||||
struct pthread {
|
||||
};
|
||||
|
||||
static struct pthread main_thread;
|
||||
|
||||
int
|
||||
_pthread_cond_init_stub(pthread_cond_t *cond,
|
||||
const pthread_condattr_t *cond_attr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_signal_stub(pthread_cond_t *cond)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_cond_wait_stub(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *
|
||||
_pthread_getspecific_stub(pthread_key_t key)
|
||||
@ -76,6 +109,12 @@ _pthread_key_delete_stub(pthread_key_t key)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_main_np_stub()
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_mutex_destroy_stub(pthread_mutex_t *mattr)
|
||||
{
|
||||
@ -130,6 +169,49 @@ _pthread_once_stub(pthread_once_t *once_control, void (*init_routine) (void))
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_init_stub(pthread_rwlock_t *rwlock,
|
||||
const pthread_rwlockattr_t *attr)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_destroy_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_rdlock_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_tryrdlock_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_trywrlock_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_unlock_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_rwlock_wrlock_stub(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
pthread_t
|
||||
_pthread_self_stub(void)
|
||||
{
|
||||
@ -141,3 +223,14 @@ _pthread_setspecific_stub(pthread_key_t key, const void *value)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_sigmask_stub(int how, const sigset_t *set, sigset_t *oset)
|
||||
{
|
||||
/*
|
||||
* No need to use _sigprocmask, since we know that the threads
|
||||
* library is not linked in.
|
||||
*
|
||||
*/
|
||||
return (sigprocmask(how, set, oset));
|
||||
}
|
||||
|
@ -58,9 +58,15 @@
|
||||
#define listen _listen
|
||||
#define nanosleep _nanosleep
|
||||
#define open _open
|
||||
#define poll _poll
|
||||
#define pthread_cond_signal _pthread_cond_signal
|
||||
#define pthread_cond_wait _pthread_cond_wait
|
||||
#define pthread_cond_init _pthread_cond_init
|
||||
#define pthread_exit _pthread_exit
|
||||
#define pthread_getspecific _pthread_getspecific
|
||||
#define pthread_key_create _pthread_key_create
|
||||
#define pthread_key_delete _pthread_key_delete
|
||||
#define pthread_main_np _pthread_main_np
|
||||
#define pthread_mutex_destroy _pthread_mutex_destroy
|
||||
#define pthread_mutex_init _pthread_mutex_init
|
||||
#define pthread_mutex_lock _pthread_mutex_lock
|
||||
@ -70,8 +76,13 @@
|
||||
#define pthread_mutexattr_destroy _pthread_mutexattr_destroy
|
||||
#define pthread_mutexattr_settype _pthread_mutexattr_settype
|
||||
#define pthread_once _pthread_once
|
||||
#define pthread_rwlock_init _pthread_rwlock_init
|
||||
#define pthread_rwlock_rdlock _pthread_rwlock_rdlock
|
||||
#define pthread_rwlock_wrlock _pthread_rwlock_wrlock
|
||||
#define pthread_rwlock_unlock _pthread_rwlock_unlock
|
||||
#define pthread_self _pthread_self
|
||||
#define pthread_setspecific _pthread_setspecific
|
||||
#define pthread_sigmask _pthread_sigmask
|
||||
#define read _read
|
||||
#define readv _readv
|
||||
#define recvfrom _recvfrom
|
||||
@ -106,14 +117,9 @@
|
||||
#define msync _msync
|
||||
#define nfssvc _nfssvc
|
||||
#define pause _pause
|
||||
#define poll _poll
|
||||
#define pthread_rwlock_destroy _pthread_rwlock_destroy
|
||||
#define pthread_rwlock_init _pthread_rwlock_init
|
||||
#define pthread_rwlock_rdlock _pthread_rwlock_rdlock
|
||||
#define pthread_rwlock_tryrdlock _pthread_rwlock_tryrdlock
|
||||
#define pthread_rwlock_trywrlock _pthread_rwlock_trywrlock
|
||||
#define pthread_rwlock_unlock _pthread_rwlock_unlock
|
||||
#define pthread_rwlock_wrlock _pthread_rwlock_wrlock
|
||||
#define pthread_rwlockattr_init _pthread_rwlockattr_init
|
||||
#define pthread_rwlockattr_destroy _pthread_rwlockattr_destroy
|
||||
#define sched_yield _sched_yield
|
||||
|
130
lib/libc/include/reentrant.h
Normal file
130
lib/libc/include/reentrant.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*-
|
||||
* Copyright (c) 1997,98 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by J.T. Conklin.
|
||||
*
|
||||
* 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 NetBSD
|
||||
* Foundation, Inc. and its contributors.
|
||||
* 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Requirements:
|
||||
*
|
||||
* 1. The thread safe mechanism should be lightweight so the library can
|
||||
* be used by non-threaded applications without unreasonable overhead.
|
||||
*
|
||||
* 2. There should be no dependency on a thread engine for non-threaded
|
||||
* applications.
|
||||
*
|
||||
* 3. There should be no dependency on any particular thread engine.
|
||||
*
|
||||
* 4. The library should be able to be compiled without support for thread
|
||||
* safety.
|
||||
*
|
||||
*
|
||||
* Rationale:
|
||||
*
|
||||
* One approach for thread safety is to provide discrete versions of the
|
||||
* library: one thread safe, the other not. The disadvantage of this is
|
||||
* that libc is rather large, and two copies of a library which are 99%+
|
||||
* identical is not an efficent use of resources.
|
||||
*
|
||||
* Another approach is to provide a single thread safe library. However,
|
||||
* it should not add significant run time or code size overhead to non-
|
||||
* threaded applications.
|
||||
*
|
||||
* Since the NetBSD C library is used in other projects, it should be
|
||||
* easy to replace the mutual exclusion primitives with ones provided by
|
||||
* another system. Similarly, it should also be easy to remove all
|
||||
* support for thread safety completely if the target environment does
|
||||
* not support threads.
|
||||
*
|
||||
*
|
||||
* Implementation Details:
|
||||
*
|
||||
* The mutex primitives used by the library (mutex_t, mutex_lock, etc.)
|
||||
* are macros which expand to the cooresponding primitives provided by
|
||||
* the thread engine or to nothing. The latter is used so that code is
|
||||
* not unreasonably cluttered with #ifdefs when all thread safe support
|
||||
* is removed.
|
||||
*
|
||||
* The mutex macros can be directly mapped to the mutex primitives from
|
||||
* pthreads, however it should be reasonably easy to wrap another mutex
|
||||
* implementation so it presents a similar interface.
|
||||
*
|
||||
* Stub implementations of the mutex functions are provided with *weak*
|
||||
* linkage. These functions simply return success. When linked with a
|
||||
* thread library (i.e. -lpthread), the functions will override the
|
||||
* stubs.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <pthread_np.h>
|
||||
#include "libc_private.h"
|
||||
|
||||
#define mutex_t pthread_mutex_t
|
||||
#define cond_t pthread_cond_t
|
||||
#define rwlock_t pthread_rwlock_t
|
||||
|
||||
#define thread_key_t pthread_key_t
|
||||
#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
#define RWLOCK_INITIALIZER PTHREAD_RWLOCK_INITIALIZER
|
||||
|
||||
#define mutex_init(m, a) _pthread_mutex_init(m, a)
|
||||
#define mutex_lock(m) if (__isthreaded) \
|
||||
_pthread_mutex_lock(m)
|
||||
#define mutex_unlock(m) if (__isthreaded) \
|
||||
_pthread_mutex_unlock(m)
|
||||
#define mutex_trylock(m) (__isthreaded ? 0 : _pthread_mutex_trylock(m))
|
||||
|
||||
#define cond_init(c, a, p) _pthread_cond_init(c, a)
|
||||
#define cond_signal(m) if (__isthreaded) \
|
||||
_pthread_cond_signal(m)
|
||||
#define cond_wait(c, m) if (__isthreaded) \
|
||||
_pthread_cond_wait(c, m)
|
||||
|
||||
#define rwlock_init(l, a) _pthread_rwlock_init(l, a)
|
||||
#define rwlock_rdlock(l) if (__isthreaded) \
|
||||
_pthread_rwlock_rdlock(l)
|
||||
#define rwlock_wrlock(l) if (__isthreaded) \
|
||||
_pthread_rwlock_wrlock(l)
|
||||
#define rwlock_unlock(l) if (__isthreaded) \
|
||||
_pthread_rwlock_unlock(l)
|
||||
|
||||
#define thr_keycreate(k, d) _pthread_key_create(k, d)
|
||||
#define thr_setspecific(k, p) _pthread_setspecific(k, p)
|
||||
#define thr_getspecific(k) _pthread_getspecific(k)
|
||||
#define thr_sigsetmask(f, n, o) _pthread_sigmask(f, n, o)
|
||||
|
||||
#define thr_self() _pthread_self()
|
||||
#define thr_exit(x) _pthread_exit(x)
|
||||
#define thr_main() _pthread_main_np()
|
@ -1,3 +1,6 @@
|
||||
/* $NetBSD: DISCLAIMER,v 1.2 1998/01/09 04:11:51 perry Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
|
@ -1,25 +1,35 @@
|
||||
# @(#)Makefile 5.11 (Berkeley) 9/6/90
|
||||
# @(#)Makefile 5.11 (Berkeley) 9/6/90
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../libc/rpc ${.CURDIR}/.
|
||||
SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \
|
||||
clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \
|
||||
clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \
|
||||
getrpcport.c mt_misc.c pmap_clnt.c pmap_getmaps.c pmap_getport.c \
|
||||
pmap_prot.c pmap_prot2.c pmap_rmt.c rpc_prot.c rpc_commondata.c \
|
||||
rpc_callmsg.c rpc_generic.c rpc_soc.c rpcb_clnt.c rpcb_prot.c \
|
||||
rpcb_st_xdr.c svc.c svc_auth.c svc_dg.c svc_auth_unix.c svc_generic.c \
|
||||
svc_raw.c svc_run.c svc_simple.c svc_vc.c
|
||||
|
||||
SRCS+= auth_des.c auth_none.c auth_time.c auth_unix.c \
|
||||
authdes_prot.c authunix_prot.c bindresvport.c \
|
||||
clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c clnt_tcp.c \
|
||||
clnt_udp.c clnt_unix.c crypt_client.c des_crypt.c des_soft.c \
|
||||
get_myaddress.c getpublickey.c getrpcent.c getrpcport.c \
|
||||
key_call.c key_prot_xdr.c netname.c netnamer.c \
|
||||
pmap_clnt.c pmap_getmaps.c pmap_getport.c pmap_prot.c \
|
||||
pmap_prot2.c pmap_rmt.c rpc_callmsg.c rpc_commondata.c \
|
||||
rpc_dtablesize.c rpc_prot.c rpcdname.c rtime.c \
|
||||
svc.c svc_auth.c svc_auth_des.c svc_auth_unix.c \
|
||||
svc_raw.c svc_run.c svc_simple.c \
|
||||
svc_tcp.c svc_udp.c svc_unix.c
|
||||
# XDR
|
||||
SRCS+= xdr.c xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c \
|
||||
xdr_stdio.c
|
||||
|
||||
# Secure-RPC
|
||||
SRCS+= auth_time.c auth_des.c authdes_prot.c des_crypt.c des_soft.c \
|
||||
crypt_client.c key_call.c key_prot_xdr.c getpublickey.c \
|
||||
svc_auth_des.c
|
||||
|
||||
# Resolver stuff
|
||||
SRCS+= netname.c netnamer.c rpcdname.c
|
||||
|
||||
# Misc Source
|
||||
SRCS+= rtime.c
|
||||
|
||||
# generated sources
|
||||
SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
|
||||
SRCS+= crypt_clnt.c crypt_xdr.c crypt.h
|
||||
|
||||
CFLAGS+= -DBROKEN_DES
|
||||
CFLAGS+= -DBROKEN_DES -DPORTMAP -DDES_BUILTIN
|
||||
|
||||
CLEANFILES+= crypt_clnt.c crypt_xdr.c crypt.h
|
||||
|
||||
@ -34,79 +44,113 @@ crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h
|
||||
|
||||
crypt.h: ${RPCDIR}/crypt.x
|
||||
${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x
|
||||
|
||||
.if ${LIB} == "c"
|
||||
|
||||
MAN3+= bindresvport.3 des_crypt.3 getrpcent.3 getrpcport.3 publickey.3 rpc.3 \
|
||||
rpc_secure.3 rtime.3
|
||||
MAN5+= publickey.5 rpc.5
|
||||
|
||||
MAN3+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \
|
||||
getrpcport.3 rpc.3 rpc_soc.3 rpc_clnt_auth.3 rpc_clnt_calls.3 \
|
||||
rpc_clnt_create.3 rpc_svc_calls.3 rpc_svc_create.3 rpc_svc_err.3 \
|
||||
rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 xdr.3 publickey.3 rpc_secure.3 \
|
||||
rtime.3
|
||||
MAN5+= publickey.5 rpc.5 netconfig.5
|
||||
MLINKS+= bindresvport.3 bindresvport_sa.3 \
|
||||
getrpcent.3 endrpcent.3 \
|
||||
getnetconfig.3 setnetconfig.3 \
|
||||
getnetconfig.3 getnetconfigent.3 \
|
||||
getnetconfig.3 endnetconfig.3 \
|
||||
getnetconfig.3 nc_perror.3 \
|
||||
getnetconfig.3 nc_sperror.3 \
|
||||
getnetpath.3 setnetpath.3 \
|
||||
getnetpath.3 endnetpath.3 \
|
||||
getrpcent.3 getrpcbyname.3 \
|
||||
getrpcent.3 getrpcbynumber.3 \
|
||||
getrpcent.3 endrpcent.3 \
|
||||
getrpcent.3 setrpcent.3 \
|
||||
rpc.3 auth_destroy.3 \
|
||||
rpc.3 authnone_create.3 \
|
||||
rpc.3 authunix_create.3 \
|
||||
rpc.3 authunix_create_default.3 \
|
||||
rpc.3 callrpc.3 \
|
||||
rpc.3 clnt_broadcast.3 \
|
||||
rpc.3 clnt_call.3 \
|
||||
rpc.3 clnt_control.3 \
|
||||
rpc.3 clnt_create.3 \
|
||||
rpc.3 clnt_destroy.3 \
|
||||
rpc.3 clnt_freeres.3 \
|
||||
rpc.3 clnt_geterr.3 \
|
||||
rpc.3 clnt_pcreateerror.3 \
|
||||
rpc.3 clnt_perrno.3 \
|
||||
rpc.3 clnt_perror.3 \
|
||||
rpc.3 clnt_spcreateerror.3 \
|
||||
rpc.3 clnt_sperrno.3 \
|
||||
rpc.3 clnt_sperror.3 \
|
||||
rpc.3 clntraw_create.3 \
|
||||
rpc.3 clnttcp_create.3 \
|
||||
rpc.3 clntudp_bufcreate.3 \
|
||||
rpc.3 clntudp_create.3 \
|
||||
rpc.3 get_myaddress.3 \
|
||||
rpc.3 pmap_getmaps.3 \
|
||||
rpc.3 pmap_getport.3 \
|
||||
rpc.3 pmap_rmtcall.3 \
|
||||
rpc.3 pmap_set.3 \
|
||||
rpc.3 pmap_unset.3 \
|
||||
rpc.3 regsterrpc.3 \
|
||||
rpc.3 rpc_createerr.3 \
|
||||
rpc.3 svc_destroy.3 \
|
||||
rpc.3 svc_fds.3 \
|
||||
rpc.3 svc_fdset.3 \
|
||||
rpc.3 svc_getargs.3 \
|
||||
rpc.3 svc_getcaller.3 \
|
||||
rpc.3 svc_getreg.3 \
|
||||
rpc.3 svc_getregset.3 \
|
||||
rpc.3 svc_register.3 \
|
||||
rpc.3 svc_run.3 \
|
||||
rpc.3 svc_sendreply.3 \
|
||||
rpc.3 svc_unregister.3 \
|
||||
rpc.3 svcerr_auth.3 \
|
||||
rpc.3 svcerr_decode.3 \
|
||||
rpc.3 svcerr_noproc.3 \
|
||||
rpc.3 svcerr_noprog.3 \
|
||||
rpc.3 svcerr_progvers.3 \
|
||||
rpc.3 svcerr_systemerr.3 \
|
||||
rpc.3 svcerr_weakauth.3 \
|
||||
rpc.3 svcfd_create.3 \
|
||||
rpc.3 svcraw_create.3 \
|
||||
rpc.3 svctcp_create.3 \
|
||||
rpc.3 svcudp_bufcreate.3 \
|
||||
rpc.3 xdr_accepted_reply.3 \
|
||||
rpc.3 xdr_authunix_parms.3 \
|
||||
rpc.3 xdr_callhdr.3 \
|
||||
rpc.3 xdr_callmsg.3 \
|
||||
rpc.3 xdr_opaque_auth.3 \
|
||||
rpc.3 xdr_pmap.3 \
|
||||
rpc.3 xdr_pmaplist.3 \
|
||||
rpc.3 xdr_rejected_reply.3 \
|
||||
rpc.3 xdr_replymsg.3 \
|
||||
rpc.3 xprt_register.3 \
|
||||
rpc.3 xprt_unregister.3
|
||||
.endif
|
||||
rpc_clnt_auth.3 auth_destroy.3 \
|
||||
rpc_clnt_auth.3 authnone_create.3 \
|
||||
rpc_clnt_auth.3 authsys_create.3 \
|
||||
rpc_clnt_auth.3 authsys_create_default.3 \
|
||||
rpc_clnt_calls.3 clnt_call.3 \
|
||||
rpc_clnt_calls.3 clnt_perrno.3 \
|
||||
rpc_clnt_calls.3 clnt_perror.3 \
|
||||
rpc_clnt_calls.3 clnt_sperrno.3 \
|
||||
rpc_clnt_calls.3 clnt_sperror.3 \
|
||||
rpc_clnt_calls.3 rpc_call.3 \
|
||||
rpc_clnt_calls.3 rpc_broadcast.3 \
|
||||
rpc_clnt_calls.3 rpc_broadcast_exp.3 \
|
||||
rpc_clnt_calls.3 clnt_freeres.3 \
|
||||
rpc_clnt_calls.3 clnt_geterr.3 \
|
||||
rpc_clnt_create.3 clnt_control.3 \
|
||||
rpc_clnt_create.3 clnt_create.3 \
|
||||
rpc_clnt_create.3 clnt_create_vers.3 \
|
||||
rpc_clnt_create.3 clnt_destroy.3 \
|
||||
rpc_clnt_create.3 clnt_pcreateerror.3 \
|
||||
rpc_clnt_create.3 clnt_spcreateerror.3 \
|
||||
rpc_clnt_create.3 clnt_dg_create.3 \
|
||||
rpc_clnt_create.3 clnt_raw_create.3 \
|
||||
rpc_clnt_create.3 clnt_tli_create.3 \
|
||||
rpc_clnt_create.3 clnt_tp_create.3 \
|
||||
rpc_clnt_create.3 clnt_vc_create.3 \
|
||||
rpc_svc_calls.3 svc_dg_enablecache.3 \
|
||||
rpc_svc_calls.3 svc_exit.3 \
|
||||
rpc_svc_calls.3 svc_freeargs.3 \
|
||||
rpc_svc_calls.3 svc_getargs.3 \
|
||||
rpc_svc_calls.3 svc_getreq_common.3 \
|
||||
rpc_svc_calls.3 svc_getreq_poll.3 \
|
||||
rpc_svc_calls.3 svc_getreqset.3 \
|
||||
rpc_svc_calls.3 svc_getrpccaller.3 \
|
||||
rpc_svc_calls.3 __svc_getcallercreds.3 \
|
||||
rpc_svc_calls.3 svc_pollset.3 \
|
||||
rpc_svc_calls.3 svc_run.3 \
|
||||
rpc_svc_calls.3 svc_sendreply.3 \
|
||||
rpc_svc_create.3 svc_control.3 \
|
||||
rpc_svc_create.3 svc_create.3 \
|
||||
rpc_svc_create.3 svc_dg_create.3 \
|
||||
rpc_svc_create.3 svc_destroy.3 \
|
||||
rpc_svc_create.3 svc_fd_create.3 \
|
||||
rpc_svc_create.3 svc_raw_create.3 \
|
||||
rpc_svc_create.3 svc_tli_create.3 \
|
||||
rpc_svc_create.3 svc_tp_create.3 \
|
||||
rpc_svc_create.3 svc_vc_create.3 \
|
||||
rpc_svc_err.3 svcerr_auth.3 \
|
||||
rpc_svc_err.3 svcerr_decode.3 \
|
||||
rpc_svc_err.3 svcerr_noproc.3 \
|
||||
rpc_svc_err.3 svcerr_noprog.3 \
|
||||
rpc_svc_err.3 svcerr_progvers.3 \
|
||||
rpc_svc_err.3 svcerr_systemerr.3 \
|
||||
rpc_svc_err.3 svcerr_weakauth.3 \
|
||||
rpc_svc_reg.3 rpc_reg.3 \
|
||||
rpc_svc_reg.3 svc_reg.3 \
|
||||
rpc_svc_reg.3 svc_unreg.3 \
|
||||
rpc_svc_reg.3 svc_auth_reg.3 \
|
||||
rpc_svc_reg.3 xprt_register.3 \
|
||||
rpc_svc_reg.3 xprt_unregister.3 \
|
||||
rpcbind.3 rpcb_getmaps.3 \
|
||||
rpcbind.3 rpcb_getaddr.3 \
|
||||
rpcbind.3 rpcb_gettime.3 \
|
||||
rpcbind.3 rpcb_rmtcall.3 \
|
||||
rpcbind.3 rpcb_set.3 \
|
||||
rpcbind.3 rpcb_unset.3 \
|
||||
rpc_soc.3 authunix_create.3 \
|
||||
rpc_soc.3 authunix_create_default.3 \
|
||||
rpc_soc.3 callrpc.3 \
|
||||
rpc_soc.3 clnt_broadcast.3 \
|
||||
rpc_soc.3 clntraw_create.3 \
|
||||
rpc_soc.3 clnttcp_create.3 \
|
||||
rpc_soc.3 clntudp_bufcreate.3 \
|
||||
rpc_soc.3 clntudp_create.3 \
|
||||
rpc_soc.3 get_myaddress.3 \
|
||||
rpc_soc.3 pmap_getmaps.3 \
|
||||
rpc_soc.3 pmap_getport.3 \
|
||||
rpc_soc.3 pmap_rmtcall.3 \
|
||||
rpc_soc.3 pmap_set.3 \
|
||||
rpc_soc.3 pmap_unset.3 \
|
||||
rpc_soc.3 registerrpc.3 \
|
||||
rpc_soc.3 rpc_createerr.3 \
|
||||
rpc_soc.3 svc_fds.3 \
|
||||
rpc_soc.3 svc_fdset.3 \
|
||||
rpc_soc.3 svc_getcaller.3 \
|
||||
rpc_soc.3 svc_register.3 \
|
||||
rpc_soc.3 svc_unregister.3 \
|
||||
rpc_soc.3 svcfd_create.3 \
|
||||
rpc_soc.3 svcraw_create.3 \
|
||||
rpc_soc.3 svctcp_create.3 \
|
||||
rpc_soc.3 svcudp_bufcreate.3 \
|
||||
rpc_soc.3 xdr_pmap.3 \
|
||||
rpc_soc.3 xdr_pmaplist.3
|
||||
|
@ -1,233 +1,176 @@
|
||||
RPCSRC 4.0 7/11/89
|
||||
$FreeBSD$
|
||||
|
||||
This distribution contains Sun Microsystem's implementation of the
|
||||
RPC and XDR protocols and is compatible with 4.2BSD and 4.3BSD. Also
|
||||
included is complete documentation, utilities, RPC service
|
||||
specification files, and demonstration services in the format used by
|
||||
the RPC protocol compiler (rpcgen). See WHAT'S NEW below for
|
||||
details.
|
||||
PLEASE READ THE DISCLAIMER FILE. DO NOT CALL THE SUN MICROSYSTEMS SUPPORT
|
||||
LINE WITH QUESTIONS ON THIS RELEASE. THEY CANNOT ANSWER QUESTIONS ABOUT THIS
|
||||
UNSUPPORTED SOURCE RELEASE.
|
||||
|
||||
NOTE ABOUT SECURE RPC:
|
||||
TIRPCSRC 2.3 29 Aug 1994
|
||||
|
||||
This release of RPCSRC contains most of the code needed to implement
|
||||
Secure RPC (see "DES Authentication" in the RPC Protocol Specification,
|
||||
doc/rpc.rfc.ms). Due to legal considerations, we are unable to
|
||||
distribute an implementation of DES, the Data Encryption Standard, which
|
||||
Secure RPC requires. For this reason, all of the files, documentation, and
|
||||
programs associated with Secure RPC have been placed into a separate
|
||||
directory, secure_rpc. The RPC library contained in the main body of this
|
||||
release *DOES NOT* support Secure RPC. See secure_rpc/README for more
|
||||
details. (A DES library was posted in Volume 18 of comp.sources.unix.)
|
||||
This distribution contains SunSoft's implementation of transport-independent
|
||||
RPC (TI-RPC), External Data Representation (XDR), and various utilities and
|
||||
documentation. These libraries and programs form the base of Open Network
|
||||
Computing (ONC), and are derived directly from the Solaris 2.3 source.
|
||||
|
||||
If you wish to report bugs found in this release, send mail to:
|
||||
Previous releases of RPC Source based on SunOS 4.x were ported to 4.2BSD and
|
||||
used Sockets as the transport interface. These versions were
|
||||
transport-specific RPC (TS-RPC).
|
||||
|
||||
Portable ONC/NFS
|
||||
Sun Microsystems, Inc
|
||||
MS 12-33
|
||||
2550 Garcia Avenue
|
||||
Mountain View, CA 94043
|
||||
TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V
|
||||
Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface
|
||||
(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported
|
||||
by almost 70 vendors on all major operating systems. TS-RPC source code
|
||||
(RPCSRC 4.0) remains available from several internet sites.
|
||||
|
||||
This release is a native source release, that is, it is compatible for
|
||||
building on Solaris 2.3. This release was built on Solaris 2.3 using SunPro
|
||||
SPARCompiler 2.0.1.
|
||||
|
||||
Solaris 2.3 is based on System V, Release 4 (SVR4), and while this release
|
||||
should be mostly compatible with other SVR4 systems, some Solaris facilities
|
||||
that are assumed may not be available. In particular, this release uses the
|
||||
Makefile format supported by SparcCompiler 2.0.1. Second, the Secure RPC
|
||||
routines use the Solaris Name Service Switch to access public-key credential
|
||||
databases. This code will need to be ported if your system does not support
|
||||
the Name Service Switch. Finally, this release uses the synchronization
|
||||
interfaces of UI Threads to make certain interfaces thread-safe. These
|
||||
interfaces are found in libthread in Solaris 2.3 and later.
|
||||
|
||||
Applications linked with this release's librpc must link with the United
|
||||
States domestic version of libcrypt in order to resolve the cbc_crypt() and
|
||||
ecb_crypt() functions. These routines are used with Secure RPC however all
|
||||
RPC programs that link with this release's librpc will need to link with the
|
||||
domestic libcrypt. Note that the Solaris 2.3 Encryption Kit is only available
|
||||
within the United States. (PLEASE NOTE: The RPC implementation found in
|
||||
Solaris 2.3's libnsl does *not* have this requirement; linking with libcrypt
|
||||
is only a requirement for the TIRPCSRC 2.3 version of librpc.)
|
||||
|
||||
|
||||
DOCUMENTATION NOTE
|
||||
|
||||
The documentation found in the doc directory are derived from the Solaris 2.3
|
||||
Network Interfaces Programming Guide. A small number of compile examples are
|
||||
given, and these use libnsl to link in the RPC library. This release builds
|
||||
the RPC library as librpc. To use this release's librpc, use the link command
|
||||
"-lrpc -lnsl -lcrypt". This links the application with TIRPCSRC 2.3's librpc
|
||||
for RPC routines, Solaris's libnsl for other networking functions, and
|
||||
libcrypt for the cbc_crypt() and ecb_crypt functions.
|
||||
|
||||
|
||||
WHY IS THIS RELEASE BEING DONE?
|
||||
|
||||
This release is being distributed to make the Sun implementation of the ONC
|
||||
technologies available for reference and porting to non-Solaris platforms.
|
||||
The current release is a native source distribution, and provides services
|
||||
that are already available on Solaris 2.3 (such as the RPC headers, the RPC
|
||||
library in libnsl, rpcbind, rpcinfo, etc.). It is not our intention to
|
||||
replace these services. See the DISCLAIMER for further information about the
|
||||
legal status of this release.
|
||||
|
||||
|
||||
WHAT'S NEW IN THIS RELEASE: TIRPCSRC 2.3
|
||||
|
||||
The previous release was TIRPCSRC 2.0.
|
||||
|
||||
1. This release is based on Solaris 2.3. The previous release was
|
||||
based on Solaris 2.0. This release contains a siginificant number of
|
||||
bug fixes and other enhancements over TIRPCSRC 2.0.
|
||||
|
||||
2. The RPC library is thread safe for all client-side interfaces
|
||||
(clnt_create, clnt_call, etc.). The server-side interfaces
|
||||
(svc_create, svc_run, etc.) are not thread safe in this release. The
|
||||
server-side interfaces will be made thread safe in the next release of
|
||||
TIRPCSRC. Please see the manual pages for details about which
|
||||
interfaces are thread safe.
|
||||
|
||||
3. As part of the work to make the RPC library thread-safe, rpcgen has
|
||||
been enhanced to generate thread-safe RPC stubs (the -M option). Note
|
||||
that this modifies the call-signature for the stub functions; the
|
||||
procedure calling the RPC stub must now pass to the stub a pointer to
|
||||
an allocated structure where results will be placed by the stub. See
|
||||
the rpcgen manual page and the rpcgen Programming Guide for details.
|
||||
|
||||
4. The Remote Asynchronous Calls (RAC) library is now included. RAC was
|
||||
first introduced in TIRPCSRC 1.0, and was bundled with librpc. It is
|
||||
now a separate library. The asynchronous call model that RAC provides
|
||||
can be achieved by using threads for making client-side RPC calls.
|
||||
The ONC Technology group recommends using threads (where possible) to
|
||||
achieve asynchrony rather than RAC. See the rpc_rac(3n) manual page
|
||||
for details.
|
||||
|
||||
or send Email to nfsnet@sun.com (the Internet) or sun!nfsnet (Usenet).
|
||||
|
||||
ROADMAP
|
||||
|
||||
The directory hierarchy is as follows:
|
||||
|
||||
demo/ Various demonstration services
|
||||
demo/dir Remote directory lister
|
||||
demo/msg Remote console message delivery service
|
||||
demo/sort Remote sort service
|
||||
cmd/ Utilities
|
||||
cmd/rpcgen The RPC Language compiler (for .x files)
|
||||
cmd/rpcbind The RPC bindery and portmapper
|
||||
cmd/rpcinfo RPC bindery query utility
|
||||
cmd/keyserv The Secure RPC keyserver
|
||||
cmd/demo Some simple ONC demo services
|
||||
|
||||
doc/ Documentation for RPC, XDR and NFS in "-ms" format.
|
||||
doc/ Postscript versions of ONC documentation
|
||||
|
||||
etc/ Utilities (rpcinfo and portmap). portmap must be
|
||||
started by root before any other RPC network services are
|
||||
used. SEE BELOW FOR BUGFIX TO 4.3BSD COMPILER.
|
||||
head/ Header files
|
||||
head/rpcsvc RPCL (.x) specifications for various ONC services, and
|
||||
header files.
|
||||
|
||||
man/ Manual pages for RPC library, rpcgen, and utilities.
|
||||
lib/ Libraries
|
||||
lib/librpc The RPC and XDR library
|
||||
lib/librac The Remote Asynchronous Calls (RAC) library
|
||||
|
||||
rpc/ The RPC and XDR library. SEE BELOW
|
||||
FOR BUGFIX TO 4.2BSD COMPILER.
|
||||
man/ Manual pages for the RPC library and utilities.
|
||||
|
||||
rpcgen/ The RPC Language compiler (for .x files)
|
||||
uts/common/rpc RPC header files
|
||||
|
||||
rpcsvc/ Service definition files for various services and the
|
||||
server and client code for the Remote Status service.
|
||||
|
||||
secure_rpc/ The files in this directory are used to build a version of
|
||||
the RPC library with DES Authentication. See the README
|
||||
file in that directory for more details.
|
||||
|
||||
BUILD INSTRUCTIONS
|
||||
|
||||
Makefiles can be found in all directories except for man. The
|
||||
Makefile in the top directory will cause these others to be invoked
|
||||
(except for in the doc, man and demo directories), in turn building the
|
||||
entire release.
|
||||
Prior to building the release, you must define the SRC environment variable
|
||||
to be the path to the top-level Makefile. For example, if /usr/src/tirpcsrc
|
||||
is where to top-level Makefile is located, execute this command prior to
|
||||
building the release:
|
||||
|
||||
WARNING! THE DEFAULT INSTALLATION PROCEDURES WILL INSTALL FILES
|
||||
IN /usr/include, /usr/lib, /usr/bin and /etc.
|
||||
setenv SRC /usr/src/tirpcsrc (csh)
|
||||
or
|
||||
SRC=/usr/src/tirpcsrc; export SRC (sh)
|
||||
|
||||
The master RPC include file, rpc/rpc.h, is used by all programs and
|
||||
routines that use RPC. It includes other RPC and system include files
|
||||
needed by the RPC system. PLEASE NOTE: If your system has NFS, it
|
||||
may have been based on Sun's NFS Source. The include files installed
|
||||
by this package may duplicate include files you will find on your NFS
|
||||
system. The RPCSRC 4.0 include files are upwardly compatible to all
|
||||
NFS Source include files as of the date of this distribution (not
|
||||
including any new definitions or declarations added by your system
|
||||
vendor). HOWEVER: Please read the comments towards the end of
|
||||
rpc/rpc.h regarding rpc/netdb.h. You may need to uncomment the
|
||||
inclusion of that file if the structures it defines are already
|
||||
defined by your system's include files.
|
||||
The sources in the lib directory depend on header files installed from head
|
||||
and uts/common/rpc, and the programs in the cmd directory depend on libraries
|
||||
from lib. Therefore, you should do a "make install" to build the release.
|
||||
|
||||
After making any compiler fixes that are needed (see below), at
|
||||
the top directory, type:
|
||||
The top-level Makefile builds the release. The "ROOT" macro defines where the
|
||||
headers and libraries are installed. The default for ROOT is "/proto". You
|
||||
may change this by either modifiying Makefile.master, or issuing the build
|
||||
command with a new definition for ROOT:
|
||||
|
||||
make install
|
||||
make install ROOT=/opt/onc
|
||||
|
||||
For all installations, the Makefile macro DESTDIR is prepended to the
|
||||
installation path. It is defined to be null in the Makefiles, so
|
||||
installations are relative to root. (You will probably need root
|
||||
privileges for installing the files under the default path.) To
|
||||
install the files under some other tree (e.g., /usr/local), use the
|
||||
command:
|
||||
You will of course need write privileges for the destination directory.
|
||||
The headers, libraries and executables will be built and installed under the
|
||||
ROOT.
|
||||
|
||||
make install DESTDIR=/usr/local
|
||||
|
||||
This will place the include files in /usr/local/usr/include, the RPC
|
||||
library in /usr/local/usr/lib, rpcgen in /usr/local/usr/bin, and the
|
||||
utilities in /usr/local/etc. You'll have to edit the Makefiles or
|
||||
install the files by hand if you want to do anything other than this
|
||||
kind of relocation of the installation tree.
|
||||
|
||||
The RPC library will be built and installed first. By default it is
|
||||
installed in /usr/lib as "librpclib.a". The directory
|
||||
/usr/include/rpc will also be created, and several header files will
|
||||
be installed there. ALL RPC SERVICES INCLUDE THESE HEADER FILES.
|
||||
|
||||
The programs in etc/ link in routines from librpclib.a. If you change
|
||||
where it is installed, be sure to edit etc/'s Makefile to reflect this.
|
||||
These programs are installed in /etc. PORTMAP MUST BE RUNNING ON
|
||||
YOUR SYSTEM BEFORE YOU START ANY OTHER RPC SERVICE.
|
||||
|
||||
rpcgen is installed in /usr/bin. This program is required to build
|
||||
the demonstration services in demo and the rstat client and server in
|
||||
rpcsvc/.
|
||||
|
||||
The rpcsvc/ directory will install its files in the directory
|
||||
/usr/include/rpcsvc. The Remote Status service (rstat_svc) will be
|
||||
compiled and installed in /etc. If you wish to make this service
|
||||
available, you should either start this service when needed or have
|
||||
it started at boot time by invoking it in your /etc/rc.local script.
|
||||
(Be sure that portmap is started first!) Sun has modified its
|
||||
version of inetd to automatically start RPC services. (Use "make
|
||||
LIB=" when building rstat on a Sun Workstation.) The Remote Status
|
||||
client (rstat) will be installed in /usr/bin. This program queries
|
||||
the rstat_svc on a remote host and prints a system status summary
|
||||
similar to the one printed by "uptime".
|
||||
|
||||
The documentation is not built during the "make install" command.
|
||||
Typing "make" in the doc directory will cause all of the manuals to
|
||||
be formatted using nroff into a single file. We have had a report
|
||||
that certain "troff" equivalents have trouble processing the full
|
||||
manual. If you have trouble, try building the manuals individually
|
||||
(see the Makefile).
|
||||
|
||||
The demonstration services in the demo directory are not built by the
|
||||
top-level "make install" command. To build these, cd to the demo
|
||||
directory and enter "make". The three services will be built.
|
||||
top-level "make install" command. To build these, cd to the cmd/demo
|
||||
directory and enter "make". The four services will be built.
|
||||
RPCGEN MUST BE INSTALLED in a path that make can find. To run the
|
||||
services, start the portmap program as root and invoke the service
|
||||
services, rpcbind must be running, then invoke the service
|
||||
(you probably will want to put it in the background). rpcinfo can be
|
||||
used to check that the service succeeded in getting registered with
|
||||
portmap, and to ping the service (see rpcinfo's man page). You can
|
||||
rpcbind, and to ping the service (see rpcinfo's man page). You can
|
||||
then use the corresponding client program to exercise the service.
|
||||
To build these services on a Sun workstation, you must prevent the
|
||||
Makefile from trying to link the RPC library (as these routines are
|
||||
already a part of Sun's libc). Use: "make LIB=".
|
||||
|
||||
BUGFIX FOR 4.3BSD COMPILER
|
||||
|
||||
The use of a 'void *' declaration for one of the arguments in
|
||||
the reply_proc() procedure in etc/rpcinfo.c will trigger a bug
|
||||
in the 4.3BSD compiler. The bug is fixed by the following change to
|
||||
the compiler file mip/manifest.h:
|
||||
BUILDING ONC APPLICATIONS
|
||||
|
||||
*** manifest.h.r1.1 Thu Apr 30 13:52:25 1987
|
||||
--- manifest.h.r1.2 Mon Nov 23 18:58:17 1987
|
||||
***************
|
||||
*** 21,27 ****
|
||||
/*
|
||||
* Bogus type values
|
||||
*/
|
||||
! #define TNULL PTR /* pointer to UNDEF */
|
||||
#define TVOID FTN /* function returning UNDEF (for void) */
|
||||
|
||||
/*
|
||||
--- 21,27 ----
|
||||
/*
|
||||
* Bogus type values
|
||||
*/
|
||||
! #define TNULL INCREF(MOETY) /* pointer to MOETY -- impossible type */
|
||||
#define TVOID FTN /* function returning UNDEF (for void) */
|
||||
|
||||
/*
|
||||
See the Makefiles in the demonstration services for examples of building
|
||||
ONC applications with this release. The $(ROOT)/usr/include directory
|
||||
must be included in the compiler header file search path (-I), and the
|
||||
$(ROOT)/usr/lib directory must be included in the linker library file search
|
||||
path (-L). Also, to run executables built dynamically, the shared library
|
||||
search path (LD_LIBRARY_PATH) must also include $(ROOT)/usr/lib. In addition
|
||||
to linking in this release's librpc (via -lrpc), you must also link with
|
||||
Solaris's libnsl (-lnsl) and the US domestic version of libcrypt (-lcrypt).
|
||||
|
||||
If you cannot fix your compiler, change the declaration in reply_proc()
|
||||
from 'void *' to 'char *'.
|
||||
|
||||
BUGFIX FOR 4.2BSD COMPILER
|
||||
|
||||
Unpatched 4.2BSD compilers complain about valid C. You can make old
|
||||
compilers happy by changing some voids to ints. However, the fix to
|
||||
the 4.2 VAX compiler is as follows (to mip/trees.c):
|
||||
|
||||
*** trees.c.r1.1 Mon May 11 13:47:58 1987
|
||||
--- trees.c.r1.2 Wed Jul 2 18:28:52 1986
|
||||
***************
|
||||
*** 1247,1253 ****
|
||||
if(o==CAST && mt1==0)return(TYPL+TYMATCH);
|
||||
if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
|
||||
else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
|
||||
! else if( mt12 == 0 ) break;
|
||||
else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
|
||||
else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
|
||||
break;
|
||||
--- 1261,1269 ----
|
||||
if(o==CAST && mt1==0)return(TYPL+TYMATCH);
|
||||
if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
|
||||
else if( (mt1&MENU)||(mt2&MENU) ) return( LVAL+NCVT+TYPL+PTMATCH+PUN );
|
||||
! /* if right is TVOID and looks like a CALL, is not ok */
|
||||
! else if (mt2 == 0 && (p->in.right->in.op == CALL || p->in.right->in.op == UNARY CALL))
|
||||
! break;
|
||||
else if( mt1 & MPTR ) return( LVAL+PTMATCH+PUN );
|
||||
else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
|
||||
break;
|
||||
|
||||
WHAT'S NEW IN THIS RELEASE: RPCSRC 4.0
|
||||
|
||||
The previous release was RPCSRC 3.9. As with all previous releases,
|
||||
this release is based directly on files from Sun Microsystem's
|
||||
implementation.
|
||||
|
||||
Upgrade from RPCSRC 3.9
|
||||
|
||||
1) RPCSRC 4.0 upgrades RPCSRC 3.9. Improvements from SunOS 4.0 have
|
||||
been integrated into this release.
|
||||
|
||||
Secure RPC (in the secure_rpc/ directory)
|
||||
|
||||
2) DES Authentication routines and programs are provided.
|
||||
3) A new manual, "Secure NFS" is provided, which describes Secure RPC
|
||||
and Secure NFS.
|
||||
4) Skeleton routines and manual pages are provided which describe the
|
||||
DES encryption procedures required by Secure RPC. HOWEVER, NO DES
|
||||
ROUTINE IS PROVIDED.
|
||||
|
||||
New Functionality
|
||||
|
||||
5) rpcinfo can now be used to de-register services from the portmapper
|
||||
which may have terminated abnormally.
|
||||
6) A new client, rstat, is provided which queries the rstat_svc and
|
||||
prints a status line similar to the one displayed by "uptime".
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -32,59 +33,58 @@
|
||||
/*
|
||||
* auth_des.c, client-side implementation of DES authentication
|
||||
*/
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <rpc/des_crypt.h>
|
||||
#include <syslog.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/auth.h>
|
||||
#include <rpc/auth_des.h>
|
||||
#include <rpc/clnt.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <netinet/in.h> /* XXX: just to get htonl() and ntohl() */
|
||||
#include <sys/socket.h>
|
||||
#undef NIS
|
||||
#include <rpcsvc/nis.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/* from: static char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; */
|
||||
static const char rcsid[] = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
extern bool_t __rpc_get_time_offset __P(( struct timeval *, nis_server *,
|
||||
char *, char **, struct sockaddr_in * ));
|
||||
extern int rtime __P(( struct sockaddr_in *, struct timeval *, struct timeval *));
|
||||
extern bool_t xdr_authdes_cred __P(( XDR *, struct authdes_cred * ));
|
||||
extern bool_t xdr_authdes_verf __P(( XDR *, struct authdes_verf * ));
|
||||
|
||||
#define MILLION 1000000L
|
||||
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
|
||||
#define USEC_PER_SEC 1000000
|
||||
#define RTIME_TIMEOUT 5 /* seconds to wait for sync */
|
||||
|
||||
#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private
|
||||
#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type))
|
||||
#define FREE(ptr, size) mem_free((char *)(ptr), (int) size)
|
||||
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
|
||||
|
||||
#define debug(msg) /*printf("%s\n", msg) */
|
||||
extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *);
|
||||
extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *);
|
||||
extern int key_encryptsession_pk();
|
||||
|
||||
extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *,
|
||||
char **, char **);
|
||||
|
||||
/*
|
||||
* DES authenticator operations vector
|
||||
*/
|
||||
static void authdes_nextverf();
|
||||
static bool_t authdes_marshal();
|
||||
static bool_t authdes_validate();
|
||||
static bool_t authdes_refresh();
|
||||
static void authdes_destroy();
|
||||
static struct auth_ops authdes_ops = {
|
||||
authdes_nextverf,
|
||||
authdes_marshal,
|
||||
authdes_validate,
|
||||
authdes_refresh,
|
||||
authdes_destroy
|
||||
};
|
||||
#ifdef foo
|
||||
static bool_t synchronize __P(( struct sockaddr *, struct timeval *));
|
||||
#endif
|
||||
static void authdes_nextverf(AUTH *);
|
||||
static bool_t authdes_marshal(AUTH *, XDR *);
|
||||
static bool_t authdes_validate(AUTH *, struct opaque_auth *);
|
||||
static bool_t authdes_refresh(AUTH *, void *);
|
||||
static void authdes_destroy(AUTH *);
|
||||
|
||||
static struct auth_ops *authdes_ops(void);
|
||||
|
||||
/*
|
||||
* This struct is pointed to by the ah_private field of an "AUTH *"
|
||||
*/
|
||||
@ -95,10 +95,10 @@ struct ad_private {
|
||||
u_int ad_servernamelen; /* length of name, rounded up */
|
||||
u_int ad_window; /* client specified window */
|
||||
bool_t ad_dosync; /* synchronize? */
|
||||
struct sockaddr ad_syncaddr; /* remote host to synch with */
|
||||
struct netbuf ad_syncaddr; /* remote host to synch with */
|
||||
char *ad_timehost; /* remote host to synch with */
|
||||
struct timeval ad_timediff; /* server's time - client's time */
|
||||
u_long ad_nickname; /* server's nickname for client */
|
||||
u_int ad_nickname; /* server's nickname for client */
|
||||
struct authdes_cred ad_cred; /* storage for credential */
|
||||
struct authdes_verf ad_verf; /* storage for verifier */
|
||||
struct timeval ad_timestamp; /* timestamp sent */
|
||||
@ -108,106 +108,50 @@ struct ad_private {
|
||||
char *ad_uaddr; /* Timehost uaddr */
|
||||
nis_server *ad_nis_srvr; /* NIS+ server struct */
|
||||
};
|
||||
|
||||
AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *,
|
||||
const des_block *, nis_server *);
|
||||
|
||||
|
||||
/*
|
||||
* Create the client des authentication object
|
||||
*/
|
||||
* documented version of authdes_seccreate
|
||||
*/
|
||||
/*
|
||||
servername: network name of server
|
||||
win: time to live
|
||||
timehost: optional hostname to sync with
|
||||
ckey: optional conversation key to use
|
||||
*/
|
||||
|
||||
AUTH *
|
||||
authdes_create(servername, window, syncaddr, ckey)
|
||||
char *servername; /* network name of server */
|
||||
u_int window; /* time to live */
|
||||
struct sockaddr *syncaddr; /* optional addr of host to sync with */
|
||||
des_block *ckey; /* optional conversation key to use*/
|
||||
authdes_seccreate(const char *servername, const u_int win,
|
||||
const char *timehost, const des_block *ckey)
|
||||
{
|
||||
u_char pkey_data[1024];
|
||||
netobj pkey;
|
||||
AUTH *dummy;
|
||||
|
||||
AUTH *auth;
|
||||
struct ad_private *ad;
|
||||
char namebuf[MAXNETNAMELEN+1];
|
||||
u_char pkey_data[1024];
|
||||
|
||||
if (!getpublickey(servername, pkey_data))
|
||||
return(NULL);
|
||||
|
||||
/*
|
||||
* Allocate everything now
|
||||
*/
|
||||
auth = ALLOC(AUTH);
|
||||
ad = ALLOC(struct ad_private);
|
||||
(void) getnetname(namebuf);
|
||||
|
||||
ad->ad_fullnamelen = RNDUP(strlen(namebuf));
|
||||
ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
|
||||
|
||||
ad->ad_servernamelen = strlen(servername);
|
||||
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
|
||||
|
||||
if (auth == NULL || ad == NULL || ad->ad_fullname == NULL ||
|
||||
ad->ad_servername == NULL) {
|
||||
debug("authdes_create: out of memory");
|
||||
goto failed;
|
||||
if (! getpublickey(servername, (char *) pkey_data)) {
|
||||
syslog(LOG_ERR,
|
||||
"authdes_seccreate: no public key found for %s",
|
||||
servername);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up private data
|
||||
*/
|
||||
bcopy(namebuf, ad->ad_fullname, ad->ad_fullnamelen + 1);
|
||||
bcopy(servername, ad->ad_servername, ad->ad_servernamelen + 1);
|
||||
bcopy(pkey_data, ad->ad_pkey, strlen(pkey_data) + 1);
|
||||
if (syncaddr != NULL) {
|
||||
ad->ad_syncaddr = *syncaddr;
|
||||
ad->ad_dosync = TRUE;
|
||||
} else {
|
||||
ad->ad_dosync = FALSE;
|
||||
}
|
||||
ad->ad_window = window;
|
||||
if (ckey == NULL) {
|
||||
if (key_gendes(&auth->ah_key) < 0) {
|
||||
debug("authdes_create: unable to gen conversation key");
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
auth->ah_key = *ckey;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up auth handle
|
||||
*/
|
||||
auth->ah_cred.oa_flavor = AUTH_DES;
|
||||
auth->ah_verf.oa_flavor = AUTH_DES;
|
||||
auth->ah_ops = &authdes_ops;
|
||||
auth->ah_private = (caddr_t)ad;
|
||||
|
||||
if (!authdes_refresh(auth)) {
|
||||
goto failed;
|
||||
}
|
||||
return (auth);
|
||||
|
||||
failed:
|
||||
if (auth != NULL)
|
||||
FREE(auth, sizeof(AUTH));
|
||||
if (ad != NULL)
|
||||
FREE(ad, sizeof(struct ad_private));
|
||||
if (ad->ad_fullname != NULL)
|
||||
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
|
||||
if (ad->ad_servername != NULL)
|
||||
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
|
||||
return (NULL);
|
||||
pkey.n_bytes = (char *) pkey_data;
|
||||
pkey.n_len = (u_int)strlen((char *)pkey_data) + 1;
|
||||
dummy = authdes_pk_seccreate(servername, &pkey, win, timehost,
|
||||
ckey, NULL);
|
||||
return (dummy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Slightly modified version of authdes_create which takes the public key
|
||||
* Slightly modified version of authdessec_create which takes the public key
|
||||
* of the server principal as an argument. This spares us a call to
|
||||
* getpublickey() which in the nameserver context can cause a deadlock.
|
||||
*/
|
||||
AUTH *
|
||||
authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
char *servername; /* network name of server */
|
||||
netobj *pkey; /* public key of server */
|
||||
u_int window; /* time to live */
|
||||
char *timehost; /* optional hostname to sync with */
|
||||
des_block *ckey; /* optional conversation key to use */
|
||||
nis_server *srvr; /* optional NIS+ server struct */
|
||||
authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
|
||||
const char *timehost, const des_block *ckey, nis_server *srvr)
|
||||
{
|
||||
AUTH *auth;
|
||||
struct ad_private *ad;
|
||||
@ -218,12 +162,12 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
*/
|
||||
auth = ALLOC(AUTH);
|
||||
if (auth == NULL) {
|
||||
debug("authdes_pk_create: out of memory");
|
||||
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
|
||||
return (NULL);
|
||||
}
|
||||
ad = ALLOC(struct ad_private);
|
||||
if (ad == NULL) {
|
||||
debug("authdes_pk_create: out of memory");
|
||||
syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
|
||||
goto failed;
|
||||
}
|
||||
ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
|
||||
@ -242,13 +186,13 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);
|
||||
|
||||
if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
|
||||
debug("authdes_pk_create: out of memory");
|
||||
syslog(LOG_ERR, "authdes_seccreate: out of memory");
|
||||
goto failed;
|
||||
}
|
||||
if (timehost != NULL) {
|
||||
ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
|
||||
if (ad->ad_timehost == NULL) {
|
||||
debug("authdes_pk_create: out of memory");
|
||||
syslog(LOG_ERR, "authdes_seccreate: out of memory");
|
||||
goto failed;
|
||||
}
|
||||
memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
|
||||
@ -264,7 +208,8 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
ad->ad_window = window;
|
||||
if (ckey == NULL) {
|
||||
if (key_gendes(&auth->ah_key) < 0) {
|
||||
debug("authdes_pk_create: unable to gen conversation key");
|
||||
syslog(LOG_ERR,
|
||||
"authdes_seccreate: keyserv(1m) is unable to generate session key");
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
@ -276,10 +221,10 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
*/
|
||||
auth->ah_cred.oa_flavor = AUTH_DES;
|
||||
auth->ah_verf.oa_flavor = AUTH_DES;
|
||||
auth->ah_ops = &authdes_ops;
|
||||
auth->ah_ops = authdes_ops();
|
||||
auth->ah_private = (caddr_t)ad;
|
||||
|
||||
if (!authdes_refresh(auth)) {
|
||||
if (!authdes_refresh(auth, NULL)) {
|
||||
goto failed;
|
||||
}
|
||||
ad->ad_nis_srvr = NULL; /* not needed any longer */
|
||||
@ -296,13 +241,14 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
if (ad->ad_timehost)
|
||||
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
|
||||
if (ad->ad_netid)
|
||||
free(ad->ad_netid);
|
||||
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
|
||||
if (ad->ad_uaddr)
|
||||
free(ad->ad_uaddr);
|
||||
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
|
||||
FREE(ad, sizeof (struct ad_private));
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the five authentication operations
|
||||
*/
|
||||
@ -313,30 +259,27 @@ authdes_pk_create(servername, pkey, window, timehost, ckey, srvr)
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
authdes_nextverf(auth)
|
||||
AUTH *auth;
|
||||
authdes_nextverf(AUTH *auth)
|
||||
{
|
||||
/* what the heck am I supposed to do??? */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 2. Marshal
|
||||
*/
|
||||
static bool_t
|
||||
authdes_marshal(auth, xdrs)
|
||||
AUTH *auth;
|
||||
XDR *xdrs;
|
||||
authdes_marshal(AUTH *auth, XDR *xdrs)
|
||||
{
|
||||
/* LINTED pointer alignment */
|
||||
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||
struct authdes_cred *cred = &ad->ad_cred;
|
||||
struct authdes_verf *verf = &ad->ad_verf;
|
||||
des_block cryptbuf[2];
|
||||
des_block ivec;
|
||||
int status;
|
||||
long len;
|
||||
int32_t *ixdr;
|
||||
int len;
|
||||
register rpc_inline_t *ixdr;
|
||||
|
||||
/*
|
||||
* Figure out the "time", accounting for any time difference
|
||||
@ -345,30 +288,32 @@ authdes_marshal(auth, xdrs)
|
||||
(void) gettimeofday(&ad->ad_timestamp, (struct timezone *)NULL);
|
||||
ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec;
|
||||
ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec;
|
||||
if (ad->ad_timestamp.tv_usec >= MILLION) {
|
||||
ad->ad_timestamp.tv_usec -= MILLION;
|
||||
ad->ad_timestamp.tv_sec += 1;
|
||||
while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) {
|
||||
ad->ad_timestamp.tv_usec -= USEC_PER_SEC;
|
||||
ad->ad_timestamp.tv_sec++;
|
||||
}
|
||||
|
||||
/*
|
||||
* XDR the timestamp and possibly some other things, then
|
||||
* encrypt them.
|
||||
*/
|
||||
ixdr = (int32_t *)cryptbuf;
|
||||
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_sec);
|
||||
IXDR_PUT_LONG(ixdr, ad->ad_timestamp.tv_usec);
|
||||
ixdr = (rpc_inline_t *)cryptbuf;
|
||||
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec);
|
||||
IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec);
|
||||
if (ad->ad_cred.adc_namekind == ADN_FULLNAME) {
|
||||
IXDR_PUT_U_LONG(ixdr, ad->ad_window);
|
||||
IXDR_PUT_U_LONG(ixdr, ad->ad_window - 1);
|
||||
IXDR_PUT_U_INT32(ixdr, ad->ad_window);
|
||||
IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1);
|
||||
ivec.key.high = ivec.key.low = 0;
|
||||
status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf,
|
||||
2*sizeof(des_block), DES_ENCRYPT | DES_HW, (char *)&ivec);
|
||||
(u_int) 2 * sizeof (des_block),
|
||||
DES_ENCRYPT | DES_HW, (char *)&ivec);
|
||||
} else {
|
||||
status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf,
|
||||
sizeof(des_block), DES_ENCRYPT | DES_HW);
|
||||
(u_int) sizeof (des_block),
|
||||
DES_ENCRYPT | DES_HW);
|
||||
}
|
||||
if (DES_FAILED(status)) {
|
||||
debug("authdes_marshal: DES encryption failure");
|
||||
syslog(LOG_ERR, "authdes_marshal: DES encryption failure");
|
||||
return (FALSE);
|
||||
}
|
||||
ad->ad_verf.adv_xtimestamp = cryptbuf[0];
|
||||
@ -391,21 +336,21 @@ authdes_marshal(auth, xdrs)
|
||||
}
|
||||
|
||||
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
|
||||
IXDR_PUT_LONG(ixdr, AUTH_DES);
|
||||
IXDR_PUT_LONG(ixdr, len);
|
||||
IXDR_PUT_INT32(ixdr, AUTH_DES);
|
||||
IXDR_PUT_INT32(ixdr, len);
|
||||
} else {
|
||||
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_cred.oa_flavor));
|
||||
ATTEMPT(xdr_putlong(xdrs, &len));
|
||||
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor));
|
||||
ATTEMPT(xdr_putint32(xdrs, &len));
|
||||
}
|
||||
ATTEMPT(xdr_authdes_cred(xdrs, cred));
|
||||
|
||||
len = (2 + 1)*BYTES_PER_XDR_UNIT;
|
||||
if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) {
|
||||
IXDR_PUT_LONG(ixdr, AUTH_DES);
|
||||
IXDR_PUT_LONG(ixdr, len);
|
||||
IXDR_PUT_INT32(ixdr, AUTH_DES);
|
||||
IXDR_PUT_INT32(ixdr, len);
|
||||
} else {
|
||||
ATTEMPT(xdr_putlong(xdrs, (long *)&auth->ah_verf.oa_flavor));
|
||||
ATTEMPT(xdr_putlong(xdrs, &len));
|
||||
ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor));
|
||||
ATTEMPT(xdr_putint32(xdrs, &len));
|
||||
}
|
||||
ATTEMPT(xdr_authdes_verf(xdrs, verf));
|
||||
return (TRUE);
|
||||
@ -416,89 +361,92 @@ authdes_marshal(auth, xdrs)
|
||||
* 3. Validate
|
||||
*/
|
||||
static bool_t
|
||||
authdes_validate(auth, rverf)
|
||||
AUTH *auth;
|
||||
struct opaque_auth *rverf;
|
||||
authdes_validate(AUTH *auth, struct opaque_auth *rverf)
|
||||
{
|
||||
/* LINTED pointer alignment */
|
||||
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||
struct authdes_verf verf;
|
||||
int status;
|
||||
register u_long *ixdr;
|
||||
register uint32_t *ixdr;
|
||||
des_block buf;
|
||||
|
||||
if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) {
|
||||
return (FALSE);
|
||||
}
|
||||
ixdr = (u_long *)rverf->oa_base;
|
||||
verf.adv_xtimestamp.key.high = (u_long)*ixdr++;
|
||||
verf.adv_xtimestamp.key.low = (u_long)*ixdr++;
|
||||
verf.adv_int_u = (u_long)*ixdr++; /* nickname not XDR'd ! */
|
||||
/* LINTED pointer alignment */
|
||||
ixdr = (uint32_t *)rverf->oa_base;
|
||||
buf.key.high = (uint32_t)*ixdr++;
|
||||
buf.key.low = (uint32_t)*ixdr++;
|
||||
verf.adv_int_u = (uint32_t)*ixdr++;
|
||||
|
||||
/*
|
||||
* Decrypt the timestamp
|
||||
*/
|
||||
status = ecb_crypt((char *)&auth->ah_key, (char *)&verf.adv_xtimestamp,
|
||||
sizeof(des_block), DES_DECRYPT | DES_HW);
|
||||
status = ecb_crypt((char *)&auth->ah_key, (char *)&buf,
|
||||
(u_int)sizeof (des_block), DES_DECRYPT | DES_HW);
|
||||
|
||||
if (DES_FAILED(status)) {
|
||||
debug("authdes_validate: DES decryption failure");
|
||||
syslog(LOG_ERR, "authdes_validate: DES decryption failure");
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* xdr the decrypted timestamp
|
||||
* xdr the decrypted timestamp
|
||||
*/
|
||||
ixdr = (u_long *)verf.adv_xtimestamp.c;
|
||||
verf.adv_timestamp.tv_sec = IXDR_GET_LONG(ixdr) + 1;
|
||||
verf.adv_timestamp.tv_usec = IXDR_GET_LONG(ixdr);
|
||||
/* LINTED pointer alignment */
|
||||
ixdr = (uint32_t *)buf.c;
|
||||
verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1;
|
||||
verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr);
|
||||
|
||||
/*
|
||||
* validate
|
||||
*/
|
||||
if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp,
|
||||
sizeof(struct timeval)) != 0) {
|
||||
debug("authdes_validate: verifier mismatch\n");
|
||||
syslog(LOG_DEBUG, "authdes_validate: verifier mismatch");
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have a nickname now, let's use it
|
||||
*/
|
||||
ad->ad_nickname = verf.adv_nickname;
|
||||
ad->ad_cred.adc_namekind = ADN_NICKNAME;
|
||||
return (TRUE);
|
||||
ad->ad_nickname = verf.adv_nickname;
|
||||
ad->ad_cred.adc_namekind = ADN_NICKNAME;
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* 4. Refresh
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static bool_t
|
||||
authdes_refresh(auth)
|
||||
AUTH *auth;
|
||||
authdes_refresh(AUTH *auth, void *dummy)
|
||||
{
|
||||
/* LINTED pointer alignment */
|
||||
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||
struct authdes_cred *cred = &ad->ad_cred;
|
||||
int ok;
|
||||
netobj pkey;
|
||||
|
||||
if (ad->ad_dosync &&
|
||||
#ifdef old
|
||||
!synchronize(&ad->ad_syncaddr, &ad->ad_timediff)) {
|
||||
#else
|
||||
!__rpc_get_time_offset(&ad->ad_timediff,ad->ad_nis_srvr,
|
||||
ad->ad_timehost, &(ad->ad_uaddr),
|
||||
(struct sockaddr_in *)&(ad->ad_syncaddr))) {
|
||||
#endif
|
||||
/*
|
||||
* Hope the clocks are synced!
|
||||
*/
|
||||
ad->ad_timediff.tv_sec = ad->ad_timediff.tv_usec = 0;
|
||||
ad->ad_dosync = 0;
|
||||
debug("authdes_refresh: unable to synchronize with server");
|
||||
if (ad->ad_dosync) {
|
||||
ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr,
|
||||
ad->ad_timehost, &(ad->ad_uaddr),
|
||||
&(ad->ad_netid));
|
||||
if (! ok) {
|
||||
/*
|
||||
* Hope the clocks are synced!
|
||||
*/
|
||||
ad->ad_dosync = 0;
|
||||
syslog(LOG_DEBUG,
|
||||
"authdes_refresh: unable to synchronize clock");
|
||||
}
|
||||
}
|
||||
ad->ad_xkey = auth->ah_key;
|
||||
pkey.n_bytes = (char *)(ad->ad_pkey);
|
||||
pkey.n_len = strlen((char *)ad->ad_pkey) + 1;
|
||||
pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1;
|
||||
if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) {
|
||||
debug("authdes_create: unable to encrypt conversation key");
|
||||
syslog(LOG_INFO,
|
||||
"authdes_refresh: keyserv(1m) is unable to encrypt session key");
|
||||
return (FALSE);
|
||||
}
|
||||
cred->adc_fullname.key = ad->ad_xkey;
|
||||
@ -512,43 +460,39 @@ authdes_refresh(auth)
|
||||
* 5. Destroy
|
||||
*/
|
||||
static void
|
||||
authdes_destroy(auth)
|
||||
AUTH *auth;
|
||||
authdes_destroy(AUTH *auth)
|
||||
{
|
||||
/* LINTED pointer alignment */
|
||||
struct ad_private *ad = AUTH_PRIVATE(auth);
|
||||
|
||||
FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
|
||||
FREE(ad->ad_servername, ad->ad_servernamelen + 1);
|
||||
FREE(ad, sizeof(struct ad_private));
|
||||
if (ad->ad_timehost)
|
||||
FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
|
||||
if (ad->ad_netid)
|
||||
FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
|
||||
if (ad->ad_uaddr)
|
||||
FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
|
||||
FREE(ad, sizeof (struct ad_private));
|
||||
FREE(auth, sizeof(AUTH));
|
||||
}
|
||||
|
||||
|
||||
#ifdef old
|
||||
/*
|
||||
* Synchronize with the server at the given address, that is,
|
||||
* adjust timep to reflect the delta between our clocks
|
||||
*/
|
||||
static bool_t
|
||||
synchronize(syncaddr, timep)
|
||||
struct sockaddr *syncaddr;
|
||||
struct timeval *timep;
|
||||
static struct auth_ops *
|
||||
authdes_ops(void)
|
||||
{
|
||||
struct timeval mytime;
|
||||
struct timeval timeout;
|
||||
static struct auth_ops ops;
|
||||
extern mutex_t authdes_ops_lock;
|
||||
|
||||
timeout.tv_sec = RTIME_TIMEOUT;
|
||||
timeout.tv_usec = 0;
|
||||
if (rtime((struct sockaddr_in *)syncaddr, timep, NULL /*&timeout*/) < 0) {
|
||||
return (FALSE);
|
||||
}
|
||||
(void) gettimeofday(&mytime, (struct timezone *)NULL);
|
||||
timep->tv_sec -= mytime.tv_sec;
|
||||
if (mytime.tv_usec > timep->tv_usec) {
|
||||
timep->tv_sec -= 1;
|
||||
timep->tv_usec += MILLION;
|
||||
}
|
||||
timep->tv_usec -= mytime.tv_usec;
|
||||
return (TRUE);
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
mutex_lock(&authdes_ops_lock);
|
||||
if (ops.ah_nextverf == NULL) {
|
||||
ops.ah_nextverf = authdes_nextverf;
|
||||
ops.ah_marshal = authdes_marshal;
|
||||
ops.ah_validate = authdes_validate;
|
||||
ops.ah_refresh = authdes_refresh;
|
||||
ops.ah_destroy = authdes_destroy;
|
||||
}
|
||||
mutex_unlock(&authdes_ops_lock);
|
||||
return (&ops);
|
||||
}
|
||||
#endif
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: auth_none.c,v 1.13 2000/01/22 22:19:17 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,10 +29,11 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
static char *sccsid = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -41,96 +44,135 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/auth.h>
|
||||
#define MAX_MARSHEL_SIZE 20
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define MAX_MARSHAL_SIZE 20
|
||||
|
||||
/*
|
||||
* Authenticator operations routines
|
||||
*/
|
||||
static void authnone_verf();
|
||||
static void authnone_destroy();
|
||||
static bool_t authnone_marshal();
|
||||
static bool_t authnone_validate();
|
||||
static bool_t authnone_refresh();
|
||||
|
||||
static struct auth_ops ops = {
|
||||
authnone_verf,
|
||||
authnone_marshal,
|
||||
authnone_validate,
|
||||
authnone_refresh,
|
||||
authnone_destroy
|
||||
};
|
||||
static bool_t authnone_marshal (AUTH *, XDR *);
|
||||
static void authnone_verf (AUTH *);
|
||||
static bool_t authnone_validate (AUTH *, struct opaque_auth *);
|
||||
static bool_t authnone_refresh (AUTH *, void *);
|
||||
static void authnone_destroy (AUTH *);
|
||||
|
||||
extern bool_t xdr_opaque_auth();
|
||||
|
||||
static struct auth_ops *authnone_ops();
|
||||
|
||||
static struct authnone_private {
|
||||
AUTH no_client;
|
||||
char marshalled_client[MAX_MARSHEL_SIZE];
|
||||
char marshalled_client[MAX_MARSHAL_SIZE];
|
||||
u_int mcnt;
|
||||
} *authnone_private;
|
||||
|
||||
AUTH *
|
||||
authnone_create()
|
||||
{
|
||||
register struct authnone_private *ap = authnone_private;
|
||||
struct authnone_private *ap = authnone_private;
|
||||
XDR xdr_stream;
|
||||
register XDR *xdrs;
|
||||
XDR *xdrs;
|
||||
extern mutex_t authnone_lock;
|
||||
|
||||
mutex_lock(&authnone_lock);
|
||||
if (ap == 0) {
|
||||
ap = (struct authnone_private *)calloc(1, sizeof (*ap));
|
||||
if (ap == 0)
|
||||
if (ap == 0) {
|
||||
mutex_unlock(&authnone_lock);
|
||||
return (0);
|
||||
}
|
||||
authnone_private = ap;
|
||||
}
|
||||
if (!ap->mcnt) {
|
||||
ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
|
||||
ap->no_client.ah_ops = &ops;
|
||||
ap->no_client.ah_ops = authnone_ops();
|
||||
xdrs = &xdr_stream;
|
||||
xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
|
||||
XDR_ENCODE);
|
||||
xdrmem_create(xdrs, ap->marshalled_client,
|
||||
(u_int)MAX_MARSHAL_SIZE, XDR_ENCODE);
|
||||
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
|
||||
(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
|
||||
ap->mcnt = XDR_GETPOS(xdrs);
|
||||
XDR_DESTROY(xdrs);
|
||||
}
|
||||
mutex_unlock(&authnone_lock);
|
||||
return (&ap->no_client);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bool_t
|
||||
authnone_marshal(client, xdrs)
|
||||
AUTH *client;
|
||||
XDR *xdrs;
|
||||
authnone_marshal(AUTH *client, XDR *xdrs)
|
||||
{
|
||||
register struct authnone_private *ap = authnone_private;
|
||||
struct authnone_private *ap;
|
||||
bool_t dummy;
|
||||
extern mutex_t authnone_lock;
|
||||
|
||||
if (ap == 0)
|
||||
return (0);
|
||||
return ((*xdrs->x_ops->x_putbytes)(xdrs,
|
||||
ap->marshalled_client, ap->mcnt));
|
||||
assert(xdrs != NULL);
|
||||
|
||||
ap = authnone_private;
|
||||
if (ap == NULL) {
|
||||
mutex_unlock(&authnone_lock);
|
||||
return (FALSE);
|
||||
}
|
||||
dummy = (*xdrs->x_ops->x_putbytes)(xdrs,
|
||||
ap->marshalled_client, ap->mcnt);
|
||||
mutex_unlock(&authnone_lock);
|
||||
return (dummy);
|
||||
}
|
||||
|
||||
/* All these unused parameters are required to keep ANSI-C from grumbling */
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
authnone_verf()
|
||||
authnone_verf(AUTH *client)
|
||||
{
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bool_t
|
||||
authnone_validate()
|
||||
authnone_validate(AUTH *client, struct opaque_auth *opaque)
|
||||
{
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bool_t
|
||||
authnone_refresh()
|
||||
authnone_refresh(AUTH *client, void *dummy)
|
||||
{
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
authnone_destroy()
|
||||
authnone_destroy(AUTH *client)
|
||||
{
|
||||
}
|
||||
|
||||
static struct auth_ops *
|
||||
authnone_ops()
|
||||
{
|
||||
static struct auth_ops ops;
|
||||
extern mutex_t ops_lock;
|
||||
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
mutex_lock(&ops_lock);
|
||||
if (ops.ah_nextverf == NULL) {
|
||||
ops.ah_nextverf = authnone_verf;
|
||||
ops.ah_marshal = authnone_marshal;
|
||||
ops.ah_validate = authnone_validate;
|
||||
ops.ah_refresh = authnone_refresh;
|
||||
ops.ah_destroy = authnone_destroy;
|
||||
}
|
||||
mutex_unlock(&ops_lock);
|
||||
return (&ops);
|
||||
}
|
||||
|
@ -45,20 +45,11 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpc_com.h>
|
||||
#include <rpc/rpcb_prot.h>
|
||||
#undef NIS
|
||||
#include <rpcsvc/nis.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* FreeBSD currently uses RPC 4.0, which uses portmap rather than
|
||||
* rpcbind. Consequently, we need to fake up these values here.
|
||||
* Luckily, the RPCB_GETTIME procedure uses only base XDR data types
|
||||
* so we don't need anything besides these magic numbers.
|
||||
*/
|
||||
#define RPCBPROG (u_long)100000
|
||||
#define RPCBVERS (u_long)3
|
||||
#define RPCBPROC_GETTIME (u_long)6
|
||||
|
||||
#ifdef TESTING
|
||||
#define msg(x) printf("ERROR: %s\n", x)
|
||||
/* #define msg(x) syslog(LOG_ERR, "%s", x) */
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: auth_unix.c,v 1.18 2000/07/06 03:03:30 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,10 +29,11 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
static char *sccsid = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -45,33 +48,31 @@ static char *rcsid = "$FreeBSD$";
|
||||
*
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/auth.h>
|
||||
#include <rpc/auth_unix.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* Unix authenticator operations vector
|
||||
*/
|
||||
static void authunix_nextverf();
|
||||
static bool_t authunix_marshal();
|
||||
static bool_t authunix_validate();
|
||||
static bool_t authunix_refresh();
|
||||
static void authunix_destroy();
|
||||
|
||||
static struct auth_ops auth_unix_ops = {
|
||||
authunix_nextverf,
|
||||
authunix_marshal,
|
||||
authunix_validate,
|
||||
authunix_refresh,
|
||||
authunix_destroy
|
||||
};
|
||||
/* auth_unix.c */
|
||||
static void authunix_nextverf (AUTH *);
|
||||
static bool_t authunix_marshal (AUTH *, XDR *);
|
||||
static bool_t authunix_validate (AUTH *, struct opaque_auth *);
|
||||
static bool_t authunix_refresh (AUTH *, void *);
|
||||
static void authunix_destroy (AUTH *);
|
||||
static void marshal_new_auth (AUTH *);
|
||||
static struct auth_ops *authunix_ops (void);
|
||||
|
||||
/*
|
||||
* This struct is pointed to by the ah_private field of an auth_handle.
|
||||
@ -85,21 +86,6 @@ struct audata {
|
||||
};
|
||||
#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private)
|
||||
|
||||
static void marshal_new_auth();
|
||||
|
||||
/*
|
||||
* This goop is here because some servers refuse to accept a
|
||||
* credential with more than some number (usually 8) supplementary
|
||||
* groups. Blargh!
|
||||
*/
|
||||
static int authunix_maxgrouplist = 0;
|
||||
|
||||
void
|
||||
set_rpc_maxgrouplist(int num)
|
||||
{
|
||||
authunix_maxgrouplist = num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a unix style authenticator.
|
||||
* Returns an auth handle with the given stuff in it.
|
||||
@ -109,60 +95,56 @@ authunix_create(machname, uid, gid, len, aup_gids)
|
||||
char *machname;
|
||||
int uid;
|
||||
int gid;
|
||||
register int len;
|
||||
int len;
|
||||
int *aup_gids;
|
||||
{
|
||||
struct authunix_parms aup;
|
||||
char mymem[MAX_AUTH_BYTES];
|
||||
struct timeval now;
|
||||
XDR xdrs;
|
||||
register AUTH *auth;
|
||||
register struct audata *au;
|
||||
AUTH *auth;
|
||||
struct audata *au;
|
||||
|
||||
/*
|
||||
* Allocate and set up auth handle
|
||||
*/
|
||||
auth = (AUTH *)mem_alloc(sizeof(*auth));
|
||||
au = NULL;
|
||||
auth = mem_alloc(sizeof(*auth));
|
||||
#ifndef _KERNEL
|
||||
if (auth == NULL) {
|
||||
(void)fprintf(stderr, "authunix_create: out of memory\n");
|
||||
return (NULL);
|
||||
warnx("authunix_create: out of memory");
|
||||
goto cleanup_authunix_create;
|
||||
}
|
||||
#endif
|
||||
au = (struct audata *)mem_alloc(sizeof(*au));
|
||||
au = mem_alloc(sizeof(*au));
|
||||
#ifndef _KERNEL
|
||||
if (au == NULL) {
|
||||
(void)fprintf(stderr, "authunix_create: out of memory\n");
|
||||
return (NULL);
|
||||
warnx("authunix_create: out of memory");
|
||||
goto cleanup_authunix_create;
|
||||
}
|
||||
#endif
|
||||
auth->ah_ops = &auth_unix_ops;
|
||||
auth->ah_ops = authunix_ops();
|
||||
auth->ah_private = (caddr_t)au;
|
||||
auth->ah_verf = au->au_shcred = _null_auth;
|
||||
au->au_shfaults = 0;
|
||||
au->au_origcred.oa_base = NULL;
|
||||
|
||||
/*
|
||||
* fill in param struct from the given params
|
||||
*/
|
||||
(void)gettimeofday(&now, (struct timezone *)0);
|
||||
(void)gettimeofday(&now, NULL);
|
||||
aup.aup_time = now.tv_sec;
|
||||
aup.aup_machname = machname;
|
||||
aup.aup_uid = uid;
|
||||
aup.aup_gid = gid;
|
||||
/* GW: continuation of max group list hack */
|
||||
if(authunix_maxgrouplist != 0) {
|
||||
aup.aup_len = ((len < authunix_maxgrouplist) ? len
|
||||
: authunix_maxgrouplist);
|
||||
} else {
|
||||
aup.aup_len = (u_int)len;
|
||||
}
|
||||
aup.aup_len = (u_int)len;
|
||||
aup.aup_gids = aup_gids;
|
||||
|
||||
/*
|
||||
* Serialize the parameters into origcred
|
||||
*/
|
||||
xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
|
||||
if (! xdr_authunix_parms(&xdrs, &aup))
|
||||
if (! xdr_authunix_parms(&xdrs, &aup))
|
||||
abort();
|
||||
au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
|
||||
au->au_origcred.oa_flavor = AUTH_UNIX;
|
||||
@ -170,11 +152,11 @@ authunix_create(machname, uid, gid, len, aup_gids)
|
||||
au->au_origcred.oa_base = mem_alloc((u_int) len);
|
||||
#else
|
||||
if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
|
||||
(void)fprintf(stderr, "authunix_create: out of memory\n");
|
||||
return (NULL);
|
||||
warnx("authunix_create: out of memory");
|
||||
goto cleanup_authunix_create;
|
||||
}
|
||||
#endif
|
||||
memcpy(au->au_origcred.oa_base, mymem, (u_int)len);
|
||||
memmove(au->au_origcred.oa_base, mymem, (size_t)len);
|
||||
|
||||
/*
|
||||
* set auth handle to reflect new cred.
|
||||
@ -182,6 +164,17 @@ authunix_create(machname, uid, gid, len, aup_gids)
|
||||
auth->ah_cred = au->au_origcred;
|
||||
marshal_new_auth(auth);
|
||||
return (auth);
|
||||
#ifndef _KERNEL
|
||||
cleanup_authunix_create:
|
||||
if (auth)
|
||||
mem_free(auth, sizeof(*auth));
|
||||
if (au) {
|
||||
if (au->au_origcred.oa_base)
|
||||
mem_free(au->au_origcred.oa_base, (u_int)len);
|
||||
mem_free(au, sizeof(*au));
|
||||
}
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -191,32 +184,29 @@ authunix_create(machname, uid, gid, len, aup_gids)
|
||||
AUTH *
|
||||
authunix_create_default()
|
||||
{
|
||||
register int len;
|
||||
char machname[MAX_MACHINE_NAME + 1];
|
||||
register int uid;
|
||||
register int gid;
|
||||
int gids[NGRPS];
|
||||
int i;
|
||||
gid_t real_gids[NGROUPS];
|
||||
int len;
|
||||
char machname[MAXHOSTNAMELEN + 1];
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
gid_t gids[NGRPS];
|
||||
|
||||
if (gethostname(machname, MAX_MACHINE_NAME) == -1)
|
||||
if (gethostname(machname, sizeof machname) == -1)
|
||||
abort();
|
||||
machname[MAX_MACHINE_NAME] = 0;
|
||||
uid = (int)geteuid();
|
||||
gid = (int)getegid();
|
||||
if ((len = getgroups(NGROUPS, real_gids)) < 0)
|
||||
machname[sizeof(machname) - 1] = 0;
|
||||
uid = geteuid();
|
||||
gid = getegid();
|
||||
if ((len = getgroups(NGRPS, gids)) < 0)
|
||||
abort();
|
||||
if(len > NGRPS) len = NGRPS; /* GW: turn `gid_t's into `int's */
|
||||
for(i = 0; i < len; i++) {
|
||||
gids[i] = (int)real_gids[i];
|
||||
}
|
||||
return (authunix_create(machname, uid, gid, len, gids));
|
||||
/* XXX: interface problem; those should all have been unsigned */
|
||||
return (authunix_create(machname, (int)uid, (int)gid, len,
|
||||
(int *)gids));
|
||||
}
|
||||
|
||||
/*
|
||||
* authunix operations
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
authunix_nextverf(auth)
|
||||
AUTH *auth;
|
||||
@ -229,22 +219,30 @@ authunix_marshal(auth, xdrs)
|
||||
AUTH *auth;
|
||||
XDR *xdrs;
|
||||
{
|
||||
register struct audata *au = AUTH_PRIVATE(auth);
|
||||
struct audata *au;
|
||||
|
||||
assert(auth != NULL);
|
||||
assert(xdrs != NULL);
|
||||
|
||||
au = AUTH_PRIVATE(auth);
|
||||
return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
|
||||
}
|
||||
|
||||
static bool_t
|
||||
authunix_validate(auth, verf)
|
||||
register AUTH *auth;
|
||||
struct opaque_auth verf;
|
||||
AUTH *auth;
|
||||
struct opaque_auth *verf;
|
||||
{
|
||||
register struct audata *au;
|
||||
struct audata *au;
|
||||
XDR xdrs;
|
||||
|
||||
if (verf.oa_flavor == AUTH_SHORT) {
|
||||
assert(auth != NULL);
|
||||
assert(verf != NULL);
|
||||
|
||||
if (verf->oa_flavor == AUTH_SHORT) {
|
||||
au = AUTH_PRIVATE(auth);
|
||||
xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
|
||||
xdrmem_create(&xdrs, verf->oa_base, verf->oa_length,
|
||||
XDR_DECODE);
|
||||
|
||||
if (au->au_shcred.oa_base != NULL) {
|
||||
mem_free(au->au_shcred.oa_base,
|
||||
@ -265,14 +263,15 @@ authunix_validate(auth, verf)
|
||||
}
|
||||
|
||||
static bool_t
|
||||
authunix_refresh(auth)
|
||||
register AUTH *auth;
|
||||
authunix_refresh(AUTH *auth, void *dummy)
|
||||
{
|
||||
register struct audata *au = AUTH_PRIVATE(auth);
|
||||
struct audata *au = AUTH_PRIVATE(auth);
|
||||
struct authunix_parms aup;
|
||||
struct timeval now;
|
||||
XDR xdrs;
|
||||
register int stat;
|
||||
int stat;
|
||||
|
||||
assert(auth != NULL);
|
||||
|
||||
if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
|
||||
/* there is no hope. Punt */
|
||||
@ -282,7 +281,7 @@ authunix_refresh(auth)
|
||||
|
||||
/* first deserialize the creds back into a struct authunix_parms */
|
||||
aup.aup_machname = NULL;
|
||||
aup.aup_gids = (int *)NULL;
|
||||
aup.aup_gids = NULL;
|
||||
xdrmem_create(&xdrs, au->au_origcred.oa_base,
|
||||
au->au_origcred.oa_length, XDR_DECODE);
|
||||
stat = xdr_authunix_parms(&xdrs, &aup);
|
||||
@ -290,7 +289,7 @@ authunix_refresh(auth)
|
||||
goto done;
|
||||
|
||||
/* update the time and serialize in place */
|
||||
(void)gettimeofday(&now, (struct timezone *)0);
|
||||
(void)gettimeofday(&now, NULL);
|
||||
aup.aup_time = now.tv_sec;
|
||||
xdrs.x_op = XDR_ENCODE;
|
||||
XDR_SETPOS(&xdrs, 0);
|
||||
@ -309,10 +308,13 @@ authunix_refresh(auth)
|
||||
|
||||
static void
|
||||
authunix_destroy(auth)
|
||||
register AUTH *auth;
|
||||
AUTH *auth;
|
||||
{
|
||||
register struct audata *au = AUTH_PRIVATE(auth);
|
||||
struct audata *au;
|
||||
|
||||
assert(auth != NULL);
|
||||
|
||||
au = AUTH_PRIVATE(auth);
|
||||
mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
|
||||
|
||||
if (au->au_shcred.oa_base != NULL)
|
||||
@ -323,7 +325,7 @@ authunix_destroy(auth)
|
||||
if (auth->ah_verf.oa_base != NULL)
|
||||
mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
|
||||
|
||||
mem_free((caddr_t)auth, sizeof(*auth));
|
||||
mem_free(auth, sizeof(*auth));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -332,18 +334,40 @@ authunix_destroy(auth)
|
||||
*/
|
||||
static void
|
||||
marshal_new_auth(auth)
|
||||
register AUTH *auth;
|
||||
AUTH *auth;
|
||||
{
|
||||
XDR xdr_stream;
|
||||
register XDR *xdrs = &xdr_stream;
|
||||
register struct audata *au = AUTH_PRIVATE(auth);
|
||||
XDR xdr_stream;
|
||||
XDR *xdrs = &xdr_stream;
|
||||
struct audata *au;
|
||||
|
||||
assert(auth != NULL);
|
||||
|
||||
au = AUTH_PRIVATE(auth);
|
||||
xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
|
||||
if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
|
||||
(! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
|
||||
perror("auth_none.c - Fatal marshalling problem");
|
||||
} else {
|
||||
(! xdr_opaque_auth(xdrs, &(auth->ah_verf))))
|
||||
warnx("auth_none.c - Fatal marshalling problem");
|
||||
else
|
||||
au->au_mpos = XDR_GETPOS(xdrs);
|
||||
}
|
||||
XDR_DESTROY(xdrs);
|
||||
}
|
||||
|
||||
static struct auth_ops *
|
||||
authunix_ops()
|
||||
{
|
||||
static struct auth_ops ops;
|
||||
extern mutex_t ops_lock;
|
||||
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
mutex_lock(&ops_lock);
|
||||
if (ops.ah_nextverf == NULL) {
|
||||
ops.ah_nextverf = authunix_nextverf;
|
||||
ops.ah_marshal = authunix_marshal;
|
||||
ops.ah_validate = authunix_validate;
|
||||
ops.ah_refresh = authunix_refresh;
|
||||
ops.ah_destroy = authunix_destroy;
|
||||
}
|
||||
mutex_unlock(&ops_lock);
|
||||
return (&ops);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88/02/08 SMI";
|
||||
#endif
|
||||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -30,17 +31,19 @@ static char sccsid[] = "@(#)authdes_prot.c 2.1 88/07/29 4.0 RPCSRC; from 1.6 88
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* authdes_prot.c, XDR routines for DES authentication
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/auth.h>
|
||||
#include <rpc/auth_des.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE)
|
||||
|
||||
@ -55,12 +58,16 @@ xdr_authdes_cred(xdrs, cred)
|
||||
ATTEMPT(xdr_enum(xdrs, (enum_t *)&cred->adc_namekind));
|
||||
switch (cred->adc_namekind) {
|
||||
case ADN_FULLNAME:
|
||||
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, MAXNETNAMELEN));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, sizeof(des_block)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, sizeof(cred->adc_fullname.window)));
|
||||
ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name,
|
||||
MAXNETNAMELEN));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key,
|
||||
sizeof(des_block)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window,
|
||||
sizeof(cred->adc_fullname.window)));
|
||||
return (TRUE);
|
||||
case ADN_NICKNAME:
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, sizeof(cred->adc_nickname)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname,
|
||||
sizeof(cred->adc_nickname)));
|
||||
return (TRUE);
|
||||
default:
|
||||
return (FALSE);
|
||||
@ -76,7 +83,9 @@ xdr_authdes_verf(xdrs, verf)
|
||||
/*
|
||||
* Unrolled xdr
|
||||
*/
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, sizeof(des_block)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, sizeof(verf->adv_int_u)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp,
|
||||
sizeof(des_block)));
|
||||
ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u,
|
||||
sizeof(verf->adv_int_u)));
|
||||
return (TRUE);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: authunix_prot.c,v 1.12 2000/01/22 22:19:17 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,10 +29,11 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
static char *sccsid = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -40,29 +43,34 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/auth.h>
|
||||
#include <rpc/auth_unix.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* XDR for unix authentication parameters.
|
||||
*/
|
||||
bool_t
|
||||
xdr_authunix_parms(xdrs, p)
|
||||
register XDR *xdrs;
|
||||
register struct authunix_parms *p;
|
||||
XDR *xdrs;
|
||||
struct authunix_parms *p;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(p != NULL);
|
||||
|
||||
if (xdr_u_long(xdrs, &(p->aup_time))
|
||||
&& xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
|
||||
&& xdr_int(xdrs, &(p->aup_uid))
|
||||
&& xdr_int(xdrs, &(p->aup_gid))
|
||||
&& xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
|
||||
&(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
|
||||
&(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) {
|
||||
return (TRUE);
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,18 @@
|
||||
.\" @(#)bindresvport.3n 2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
|
||||
.\" $NetBSD: bindresvport.3,v 1.8 2000/07/05 15:45:33 msaitoh Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 27, 2000
|
||||
.Dd November 22, 1987
|
||||
.Dt BINDRESVPORT 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm bindresvport ,
|
||||
.Nm bindresvport_sa
|
||||
.Nd bind a socket to a privileged IP port
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <rpc/rpc.h>
|
||||
.Ft int
|
||||
.Fn bindresvport "int sd" "struct sockaddr_in *sin"
|
||||
@ -23,26 +27,39 @@ are used to bind a socket descriptor to a privileged
|
||||
port, that is, a
|
||||
port number in the range 0-1023.
|
||||
.Pp
|
||||
If
|
||||
.Fa sin
|
||||
is a pointer to a
|
||||
.Ft "struct sockaddr_in"
|
||||
then the appropriate fields in the structure should be defined.
|
||||
Note that
|
||||
.Fa sin->sin_family
|
||||
must be initialized to the address family of the socket, passed by
|
||||
.Fa sd .
|
||||
If
|
||||
.Fa sin->sin_port
|
||||
is
|
||||
.Sq 0
|
||||
then an anonymous port (in the range 600-1023) will be
|
||||
chosen, and if
|
||||
.Xr bind 2
|
||||
is successful, the
|
||||
.Fa sin->sin_port
|
||||
will be updated to contain the allocated port.
|
||||
.Pp
|
||||
If
|
||||
.Fa sin
|
||||
is the
|
||||
.Dv NULL
|
||||
pointer,
|
||||
an anonymous port will be allocated (as above).
|
||||
However, there is no way for
|
||||
.Fn bindresvport
|
||||
to return the allocated port in this case.
|
||||
.Pp
|
||||
Only root can bind to a privileged port; this call will fail for any
|
||||
other users.
|
||||
.Pp
|
||||
When
|
||||
.Va sin
|
||||
is not null,
|
||||
.Va sin->sin_family
|
||||
must be initialized to the address family of the socket, passed by
|
||||
.Va sd .
|
||||
If the value of sin->sin_port is non-zero
|
||||
.Fn bindresvport
|
||||
will attempt to use that specific port. If it fails, it chooses another
|
||||
privileged port automatically.
|
||||
.Pp
|
||||
It is legal to pass null pointer to
|
||||
.Va sin .
|
||||
In this case, the caller cannot get the port number
|
||||
.Fn bindresvport
|
||||
has picked.
|
||||
.Pp
|
||||
Function prototype of
|
||||
.Fn bindresvport
|
||||
is biased to
|
||||
@ -57,50 +74,24 @@ sockets as well as
|
||||
.Dv AF_INET
|
||||
sockets.
|
||||
.Sh RETURN VALUES
|
||||
.Fn bindresvport
|
||||
and
|
||||
.Fn bindresvport_sa
|
||||
return 0 if they are successful, otherwise \-1 is returned and
|
||||
.Va errno
|
||||
set to reflect the cause of the error.
|
||||
.Rv -std bindresvport
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn bindresvport
|
||||
and
|
||||
.Fn bindresvport_sa
|
||||
functions fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EBADF
|
||||
.Fa sd
|
||||
is not a valid descriptor.
|
||||
.It Bq Er ENOTSOCK
|
||||
.Fa sd
|
||||
is not a socket.
|
||||
.It Bq Er EADDRNOTAVAIL
|
||||
The specified address is not available from the local machine.
|
||||
.It Bq Er EADDRINUSE
|
||||
The specified address is already in use.
|
||||
.It Bq Er EINVAL
|
||||
The socket is already bound to an address,
|
||||
or the socket family and the family of specified address mismatch.
|
||||
.It Bq Er EACCES
|
||||
The requested address is protected, and the current user
|
||||
has inadequate permission to access it.
|
||||
.It Bq Er EFAULT
|
||||
The
|
||||
.Fa name
|
||||
parameter is not in a valid part of the user
|
||||
address space.
|
||||
.It Bq Er ENOBUFS
|
||||
Insufficient resources were available in the system
|
||||
to perform the operation.
|
||||
.It Bq Er EPFNOSUPPORT
|
||||
The protocol family has not been configured into the
|
||||
system, no implementation for it exists,
|
||||
or address family did not match between arguments.
|
||||
If second argument was supplied,
|
||||
and address family did not match between arguments.
|
||||
.El
|
||||
.Sh "SEE ALSO"
|
||||
.Pp
|
||||
.Fn bindresvport
|
||||
may also fail and set
|
||||
.Va errno
|
||||
for any of the errors specified for the calls
|
||||
.Xr bind 2 ,
|
||||
.Xr socket 2 ,
|
||||
.Xr rresvport 3 ,
|
||||
.Xr rresvport_af 3
|
||||
.Xr getsockopt 2 ,
|
||||
or
|
||||
.Xr setsockopt 2 .
|
||||
.Sh SEE ALSO
|
||||
.Xr bind 2 ,
|
||||
.Xr getsockopt 2 ,
|
||||
.Xr setsockopt 2 ,
|
||||
.Xr ip 4
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: bindresvport.c,v 1.19 2000/07/06 03:03:59 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
|
||||
/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/
|
||||
@ -42,10 +45,16 @@ static char *rcsid = "$FreeBSD$";
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
@ -61,7 +70,7 @@ bindresvport(sd, sin)
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind a socket to a privileged port for whatever protocol.
|
||||
* Bind a socket to a privileged IP port
|
||||
*/
|
||||
int
|
||||
bindresvport_sa(sd, sa)
|
||||
@ -71,10 +80,12 @@ bindresvport_sa(sd, sa)
|
||||
int old, error, af;
|
||||
struct sockaddr_storage myaddr;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
int proto, portrange, portlow;
|
||||
u_int16_t port;
|
||||
int salen;
|
||||
u_int16_t *portp;
|
||||
socklen_t salen;
|
||||
|
||||
if (sa == NULL) {
|
||||
salen = sizeof(myaddr);
|
||||
@ -84,33 +95,38 @@ bindresvport_sa(sd, sa)
|
||||
return -1; /* errno is correctly set */
|
||||
|
||||
af = sa->sa_family;
|
||||
memset(&myaddr, 0, salen);
|
||||
memset(sa, 0, salen);
|
||||
} else
|
||||
af = sa->sa_family;
|
||||
|
||||
if (af == AF_INET) {
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
proto = IPPROTO_IP;
|
||||
portrange = IP_PORTRANGE;
|
||||
portlow = IP_PORTRANGE_LOW;
|
||||
sin = (struct sockaddr_in *)sa;
|
||||
salen = sizeof(struct sockaddr_in);
|
||||
port = sin->sin_port;
|
||||
} else if (af == AF_INET6) {
|
||||
portp = &sin->sin_port;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
proto = IPPROTO_IPV6;
|
||||
portrange = IPV6_PORTRANGE;
|
||||
portlow = IPV6_PORTRANGE_LOW;
|
||||
sin6 = (struct sockaddr_in6 *)sa;
|
||||
salen = sizeof(struct sockaddr_in6);
|
||||
port = sin6->sin6_port;
|
||||
} else {
|
||||
portp = &sin6->sin6_port;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EPFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
sa->sa_family = af;
|
||||
sa->sa_len = salen;
|
||||
|
||||
if (port == 0) {
|
||||
int oldlen = sizeof(old);
|
||||
if (*portp == 0) {
|
||||
socklen_t oldlen = sizeof(old);
|
||||
|
||||
error = _getsockopt(sd, proto, portrange, &old, &oldlen);
|
||||
if (error < 0)
|
||||
@ -124,10 +140,10 @@ bindresvport_sa(sd, sa)
|
||||
|
||||
error = _bind(sd, sa, salen);
|
||||
|
||||
if (port == 0) {
|
||||
if (*portp == 0) {
|
||||
int saved_errno = errno;
|
||||
|
||||
if (error) {
|
||||
if (error < 0) {
|
||||
if (_setsockopt(sd, proto, portrange, &old,
|
||||
sizeof(old)) < 0)
|
||||
errno = saved_errno;
|
||||
@ -135,7 +151,7 @@ bindresvport_sa(sd, sa)
|
||||
}
|
||||
|
||||
if (sa != (struct sockaddr *)&myaddr) {
|
||||
/* Hmm, what did the kernel assign... */
|
||||
/* Hmm, what did the kernel assign? */
|
||||
if (_getsockname(sd, sa, &salen) < 0)
|
||||
errno = saved_errno;
|
||||
return (error);
|
||||
|
667
lib/libc/rpc/clnt_bcast.c
Normal file
667
lib/libc/rpc/clnt_bcast.c
Normal file
@ -0,0 +1,667 @@
|
||||
/* $NetBSD: clnt_bcast.c,v 1.3 2000/07/06 03:05:20 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)clnt_bcast.c 1.18 94/05/03 SMI" */
|
||||
|
||||
#if !defined(lint) && defined(SCCSIDS)
|
||||
static char sccsid[] = "@(#)clnt_bcast.c 1.15 89/04/21 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* clnt_bcast.c
|
||||
* Client interface to broadcast service.
|
||||
*
|
||||
* Copyright (C) 1988, Sun Microsystems, Inc.
|
||||
*
|
||||
* The following is kludged-up support for simple rpc broadcasts.
|
||||
* Someday a large, complicated system will replace these routines.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <sys/poll.h>
|
||||
#include <rpc/rpc.h>
|
||||
#ifdef PORTMAP
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/pmap_rmt.h>
|
||||
#endif /* PORTMAP */
|
||||
#include <rpc/nettype.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifdef RPC_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "rpc_com.h"
|
||||
|
||||
#define MAXBCAST 20 /* Max no of broadcasting transports */
|
||||
#define INITTIME 4000 /* Time to wait initially */
|
||||
#define WAITTIME 8000 /* Maximum time to wait */
|
||||
|
||||
/*
|
||||
* If nettype is NULL, it broadcasts on all the available
|
||||
* datagram_n transports. May potentially lead to broadacst storms
|
||||
* and hence should be used with caution, care and courage.
|
||||
*
|
||||
* The current parameter xdr packet size is limited by the max tsdu
|
||||
* size of the transport. If the max tsdu size of any transport is
|
||||
* smaller than the parameter xdr packet, then broadcast is not
|
||||
* sent on that transport.
|
||||
*
|
||||
* Also, the packet size should be less the packet size of
|
||||
* the data link layer (for ethernet it is 1400 bytes). There is
|
||||
* no easy way to find out the max size of the data link layer and
|
||||
* we are assuming that the args would be smaller than that.
|
||||
*
|
||||
* The result size has to be smaller than the transport tsdu size.
|
||||
*
|
||||
* If PORTMAP has been defined, we send two packets for UDP, one for
|
||||
* rpcbind and one for portmap. For those machines which support
|
||||
* both rpcbind and portmap, it will cause them to reply twice, and
|
||||
* also here it will get two responses ... inefficient and clumsy.
|
||||
*/
|
||||
|
||||
struct broadif {
|
||||
int index;
|
||||
struct sockaddr_storage broadaddr;
|
||||
TAILQ_ENTRY(broadif) link;
|
||||
};
|
||||
|
||||
typedef TAILQ_HEAD(, broadif) broadlist_t;
|
||||
|
||||
int __rpc_getbroadifs __P((int, int, int, broadlist_t *));
|
||||
void __rpc_freebroadifs __P((broadlist_t *));
|
||||
int __rpc_broadenable __P((int, int, struct broadif *));
|
||||
|
||||
int __rpc_lowvers = 0;
|
||||
|
||||
int
|
||||
__rpc_getbroadifs(int af, int proto, int socktype, broadlist_t *list)
|
||||
{
|
||||
int count = 0;
|
||||
struct broadif *bip;
|
||||
struct ifaddrs *ifap, *ifp;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
struct sockaddr_in *sin;
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
if (getifaddrs(&ifp) < 0)
|
||||
return 0;
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
|
||||
hints.ai_family = af;
|
||||
hints.ai_protocol = proto;
|
||||
hints.ai_socktype = socktype;
|
||||
|
||||
if (getaddrinfo(NULL, "sunrpc", &hints, &res) != 0)
|
||||
return 0;
|
||||
|
||||
for (ifap = ifp; ifap != NULL; ifap = ifap->ifa_next) {
|
||||
if (ifap->ifa_addr->sa_family != af ||
|
||||
!(ifap->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
#ifdef INET6
|
||||
if ((af == AF_INET6 && !(ifap->ifa_flags & IFF_MULTICAST)) ||
|
||||
!(ifap->ifa_flags & IFF_BROADCAST))
|
||||
continue;
|
||||
#endif
|
||||
bip = (struct broadif *)malloc(sizeof *bip);
|
||||
if (bip == NULL)
|
||||
break;
|
||||
bip->index = if_nametoindex(ifap->ifa_name);
|
||||
#ifdef INET6
|
||||
if (af != AF_INET6 && (ifap->ifa_flags & IFF_BROADCAST)) {
|
||||
#else
|
||||
if (ifap->ifa_flags & IFF_BROADCAST) {
|
||||
#endif
|
||||
memcpy(&bip->broadaddr, ifap->ifa_broadaddr,
|
||||
(size_t)ifap->ifa_broadaddr->sa_len);
|
||||
sin = (struct sockaddr_in *)(void *)&bip->broadaddr;
|
||||
sin->sin_port =
|
||||
((struct sockaddr_in *)
|
||||
(void *)res->ai_addr)->sin_port;
|
||||
#ifdef INET6
|
||||
} else if (af == AF_INET6) {
|
||||
sin6 = (struct sockaddr_in6 *)(void *)&bip->broadaddr;
|
||||
inet_pton(af, RPCB_MULTICAST_ADDR, &sin6->sin6_addr);
|
||||
sin6->sin6_family = af;
|
||||
sin6->sin6_len = sizeof *sin6;
|
||||
sin6->sin6_port =
|
||||
((struct sockaddr_in6 *)
|
||||
(void *)res->ai_addr)->sin6_port;
|
||||
sin6->sin6_scope_id = bip->index;
|
||||
#endif
|
||||
}
|
||||
TAILQ_INSERT_TAIL(list, bip, link);
|
||||
count++;
|
||||
}
|
||||
freeifaddrs(ifp);
|
||||
freeaddrinfo(res);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void
|
||||
__rpc_freebroadifs(broadlist_t *list)
|
||||
{
|
||||
struct broadif *bip, *next;
|
||||
|
||||
bip = TAILQ_FIRST(list);
|
||||
|
||||
while (bip != NULL) {
|
||||
next = TAILQ_NEXT(bip, link);
|
||||
free(bip);
|
||||
bip = next;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
/*ARGSUSED*/
|
||||
__rpc_broadenable(int af, int s, struct broadif *bip)
|
||||
{
|
||||
int o = 1;
|
||||
|
||||
#if 0
|
||||
if (af == AF_INET6) {
|
||||
fprintf(stderr, "set v6 multicast if to %d\n", bip->index);
|
||||
if (_setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &bip->index,
|
||||
sizeof bip->index) < 0)
|
||||
return -1;
|
||||
} else
|
||||
#endif
|
||||
if (_setsockopt(s, SOL_SOCKET, SO_BROADCAST, &o, sizeof o) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
enum clnt_stat
|
||||
rpc_broadcast_exp(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||
eachresult, inittime, waittime, nettype)
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
rpcproc_t proc; /* procedure number */
|
||||
xdrproc_t xargs; /* xdr routine for args */
|
||||
caddr_t argsp; /* pointer to args */
|
||||
xdrproc_t xresults; /* xdr routine for results */
|
||||
caddr_t resultsp; /* pointer to results */
|
||||
resultproc_t eachresult; /* call with each result obtained */
|
||||
int inittime; /* how long to wait initially */
|
||||
int waittime; /* maximum time to wait */
|
||||
const char *nettype; /* transport type */
|
||||
{
|
||||
enum clnt_stat stat = RPC_SUCCESS; /* Return status */
|
||||
XDR xdr_stream; /* XDR stream */
|
||||
XDR *xdrs = &xdr_stream;
|
||||
struct rpc_msg msg; /* RPC message */
|
||||
struct timeval t;
|
||||
char *outbuf = NULL; /* Broadcast msg buffer */
|
||||
char *inbuf = NULL; /* Reply buf */
|
||||
int inlen;
|
||||
u_int maxbufsize = 0;
|
||||
AUTH *sys_auth = authunix_create_default();
|
||||
int i;
|
||||
void *handle;
|
||||
char uaddress[1024]; /* A self imposed limit */
|
||||
char *uaddrp = uaddress;
|
||||
int pmap_reply_flag; /* reply recvd from PORTMAP */
|
||||
/* An array of all the suitable broadcast transports */
|
||||
struct {
|
||||
int fd; /* File descriptor */
|
||||
int af;
|
||||
int proto;
|
||||
struct netconfig *nconf; /* Netconfig structure */
|
||||
u_int asize; /* Size of the addr buf */
|
||||
u_int dsize; /* Size of the data buf */
|
||||
struct sockaddr_storage raddr; /* Remote address */
|
||||
broadlist_t nal;
|
||||
} fdlist[MAXBCAST];
|
||||
struct pollfd pfd[MAXBCAST];
|
||||
size_t fdlistno = 0;
|
||||
struct r_rpcb_rmtcallargs barg; /* Remote arguments */
|
||||
struct r_rpcb_rmtcallres bres; /* Remote results */
|
||||
size_t outlen, outlen_pmap;
|
||||
struct netconfig *nconf;
|
||||
int msec;
|
||||
int pollretval;
|
||||
int fds_found;
|
||||
|
||||
#ifdef PORTMAP
|
||||
u_long port; /* Remote port number */
|
||||
int pmap_flag = 0; /* UDP exists ? */
|
||||
char *outbuf_pmap = NULL;
|
||||
struct rmtcallargs barg_pmap; /* Remote arguments */
|
||||
struct rmtcallres bres_pmap; /* Remote results */
|
||||
u_int udpbufsz = 0;
|
||||
#endif /* PORTMAP */
|
||||
|
||||
if (sys_auth == NULL) {
|
||||
return (RPC_SYSTEMERROR);
|
||||
}
|
||||
/*
|
||||
* initialization: create a fd, a broadcast address, and send the
|
||||
* request on the broadcast transport.
|
||||
* Listen on all of them and on replies, call the user supplied
|
||||
* function.
|
||||
*/
|
||||
|
||||
if (nettype == NULL)
|
||||
nettype = "datagram_n";
|
||||
if ((handle = __rpc_setconf(nettype)) == NULL) {
|
||||
return (RPC_UNKNOWNPROTO);
|
||||
}
|
||||
while ((nconf = __rpc_getconf(handle)) != NULL) {
|
||||
int fd;
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (nconf->nc_semantics != NC_TPI_CLTS)
|
||||
continue;
|
||||
if (fdlistno >= MAXBCAST)
|
||||
break; /* No more slots available */
|
||||
if (!__rpc_nconf2sockinfo(nconf, &si))
|
||||
continue;
|
||||
|
||||
TAILQ_INIT(&fdlist[fdlistno].nal);
|
||||
if (__rpc_getbroadifs(si.si_af, si.si_proto, si.si_socktype,
|
||||
&fdlist[fdlistno].nal) == 0)
|
||||
continue;
|
||||
|
||||
fd = _socket(si.si_af, si.si_socktype, si.si_proto);
|
||||
if (fd < 0) {
|
||||
stat = RPC_CANTSEND;
|
||||
continue;
|
||||
}
|
||||
fdlist[fdlistno].af = si.si_af;
|
||||
fdlist[fdlistno].proto = si.si_proto;
|
||||
fdlist[fdlistno].fd = fd;
|
||||
fdlist[fdlistno].nconf = nconf;
|
||||
fdlist[fdlistno].asize = __rpc_get_a_size(si.si_af);
|
||||
pfd[fdlistno].events = POLLIN | POLLPRI |
|
||||
POLLRDNORM | POLLRDBAND;
|
||||
pfd[fdlistno].fd = fdlist[fdlistno].fd = fd;
|
||||
fdlist[fdlistno].dsize = __rpc_get_t_size(si.si_af, si.si_proto,
|
||||
0);
|
||||
|
||||
if (maxbufsize <= fdlist[fdlistno].dsize)
|
||||
maxbufsize = fdlist[fdlistno].dsize;
|
||||
|
||||
#ifdef PORTMAP
|
||||
if (si.si_af == AF_INET && si.si_proto == IPPROTO_UDP) {
|
||||
udpbufsz = fdlist[fdlistno].dsize;
|
||||
if ((outbuf_pmap = malloc(udpbufsz)) == NULL) {
|
||||
_close(fd);
|
||||
stat = RPC_SYSTEMERROR;
|
||||
goto done_broad;
|
||||
}
|
||||
pmap_flag = 1;
|
||||
}
|
||||
#endif /* PORTMAP */
|
||||
fdlistno++;
|
||||
}
|
||||
|
||||
if (fdlistno == 0) {
|
||||
if (stat == RPC_SUCCESS)
|
||||
stat = RPC_UNKNOWNPROTO;
|
||||
goto done_broad;
|
||||
}
|
||||
if (maxbufsize == 0) {
|
||||
if (stat == RPC_SUCCESS)
|
||||
stat = RPC_CANTSEND;
|
||||
goto done_broad;
|
||||
}
|
||||
inbuf = malloc(maxbufsize);
|
||||
outbuf = malloc(maxbufsize);
|
||||
if ((inbuf == NULL) || (outbuf == NULL)) {
|
||||
stat = RPC_SYSTEMERROR;
|
||||
goto done_broad;
|
||||
}
|
||||
|
||||
/* Serialize all the arguments which have to be sent */
|
||||
(void) gettimeofday(&t, NULL);
|
||||
msg.rm_xid = __RPC_GETXID(&t);
|
||||
msg.rm_direction = CALL;
|
||||
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
msg.rm_call.cb_prog = RPCBPROG;
|
||||
msg.rm_call.cb_vers = RPCBVERS;
|
||||
msg.rm_call.cb_proc = RPCBPROC_CALLIT;
|
||||
barg.prog = prog;
|
||||
barg.vers = vers;
|
||||
barg.proc = proc;
|
||||
barg.args.args_val = argsp;
|
||||
barg.xdr_args = xargs;
|
||||
bres.addr = uaddrp;
|
||||
bres.results.results_val = resultsp;
|
||||
bres.xdr_res = xresults;
|
||||
msg.rm_call.cb_cred = sys_auth->ah_cred;
|
||||
msg.rm_call.cb_verf = sys_auth->ah_verf;
|
||||
xdrmem_create(xdrs, outbuf, maxbufsize, XDR_ENCODE);
|
||||
if ((!xdr_callmsg(xdrs, &msg)) ||
|
||||
(!xdr_rpcb_rmtcallargs(xdrs,
|
||||
(struct rpcb_rmtcallargs *)(void *)&barg))) {
|
||||
stat = RPC_CANTENCODEARGS;
|
||||
goto done_broad;
|
||||
}
|
||||
outlen = xdr_getpos(xdrs);
|
||||
xdr_destroy(xdrs);
|
||||
|
||||
#ifdef PORTMAP
|
||||
/* Prepare the packet for version 2 PORTMAP */
|
||||
if (pmap_flag) {
|
||||
msg.rm_xid++; /* One way to distinguish */
|
||||
msg.rm_call.cb_prog = PMAPPROG;
|
||||
msg.rm_call.cb_vers = PMAPVERS;
|
||||
msg.rm_call.cb_proc = PMAPPROC_CALLIT;
|
||||
barg_pmap.prog = prog;
|
||||
barg_pmap.vers = vers;
|
||||
barg_pmap.proc = proc;
|
||||
barg_pmap.args_ptr = argsp;
|
||||
barg_pmap.xdr_args = xargs;
|
||||
bres_pmap.port_ptr = &port;
|
||||
bres_pmap.xdr_results = xresults;
|
||||
bres_pmap.results_ptr = resultsp;
|
||||
xdrmem_create(xdrs, outbuf_pmap, udpbufsz, XDR_ENCODE);
|
||||
if ((! xdr_callmsg(xdrs, &msg)) ||
|
||||
(! xdr_rmtcall_args(xdrs, &barg_pmap))) {
|
||||
stat = RPC_CANTENCODEARGS;
|
||||
goto done_broad;
|
||||
}
|
||||
outlen_pmap = xdr_getpos(xdrs);
|
||||
xdr_destroy(xdrs);
|
||||
}
|
||||
#endif PORTMAP
|
||||
|
||||
/*
|
||||
* Basic loop: broadcast the packets to transports which
|
||||
* support data packets of size such that one can encode
|
||||
* all the arguments.
|
||||
* Wait a while for response(s).
|
||||
* The response timeout grows larger per iteration.
|
||||
*/
|
||||
for (msec = inittime; msec <= waittime; msec += msec) {
|
||||
struct broadif *bip;
|
||||
|
||||
/* Broadcast all the packets now */
|
||||
for (i = 0; i < fdlistno; i++) {
|
||||
if (fdlist[i].dsize < outlen) {
|
||||
stat = RPC_CANTSEND;
|
||||
continue;
|
||||
}
|
||||
for (bip = TAILQ_FIRST(&fdlist[i].nal); bip != NULL;
|
||||
bip = TAILQ_NEXT(bip, link)) {
|
||||
void *addr;
|
||||
|
||||
addr = &bip->broadaddr;
|
||||
|
||||
__rpc_broadenable(fdlist[i].af, fdlist[i].fd,
|
||||
bip);
|
||||
|
||||
/*
|
||||
* Only use version 3 if lowvers is not set
|
||||
*/
|
||||
|
||||
if (!__rpc_lowvers)
|
||||
if (_sendto(fdlist[i].fd, outbuf,
|
||||
outlen, 0, (struct sockaddr*)addr,
|
||||
(size_t)fdlist[i].asize) !=
|
||||
outlen) {
|
||||
#ifdef RPC_DEBUG
|
||||
perror("sendto");
|
||||
#endif
|
||||
warnx("clnt_bcast: cannot send"
|
||||
"broadcast packet");
|
||||
stat = RPC_CANTSEND;
|
||||
continue;
|
||||
};
|
||||
#ifdef RPC_DEBUG
|
||||
if (!__rpc_lowvers)
|
||||
fprintf(stderr, "Broadcast packet sent "
|
||||
"for %s\n",
|
||||
fdlist[i].nconf->nc_netid);
|
||||
#endif
|
||||
#ifdef PORTMAP
|
||||
/*
|
||||
* Send the version 2 packet also
|
||||
* for UDP/IP
|
||||
*/
|
||||
if (fdlist[i].proto == IPPROTO_UDP) {
|
||||
if (_sendto(fdlist[i].fd, outbuf_pmap,
|
||||
outlen_pmap, 0, addr,
|
||||
(size_t)fdlist[i].asize) !=
|
||||
outlen_pmap) {
|
||||
warnx("clnt_bcast: "
|
||||
"Cannot send broadcast packet");
|
||||
stat = RPC_CANTSEND;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#ifdef RPC_DEBUG
|
||||
fprintf(stderr, "PMAP Broadcast packet "
|
||||
"sent for %s\n",
|
||||
fdlist[i].nconf->nc_netid);
|
||||
#endif
|
||||
#endif /* PORTMAP */
|
||||
}
|
||||
/* End for sending all packets on this transport */
|
||||
} /* End for sending on all transports */
|
||||
|
||||
if (eachresult == NULL) {
|
||||
stat = RPC_SUCCESS;
|
||||
goto done_broad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get all the replies from these broadcast requests
|
||||
*/
|
||||
recv_again:
|
||||
|
||||
switch (pollretval = _poll(pfd, fdlistno, msec)) {
|
||||
case 0: /* timed out */
|
||||
stat = RPC_TIMEDOUT;
|
||||
continue;
|
||||
case -1: /* some kind of error - we ignore it */
|
||||
goto recv_again;
|
||||
} /* end of poll results switch */
|
||||
|
||||
for (i = fds_found = 0;
|
||||
i < fdlistno && fds_found < pollretval; i++) {
|
||||
bool_t done = FALSE;
|
||||
|
||||
if (pfd[i].revents == 0)
|
||||
continue;
|
||||
else if (pfd[i].revents & POLLNVAL) {
|
||||
/*
|
||||
* Something bad has happened to this descri-
|
||||
* ptor. We can cause _poll() to ignore
|
||||
* it simply by using a negative fd. We do that
|
||||
* rather than compacting the pfd[] and fdlist[]
|
||||
* arrays.
|
||||
*/
|
||||
pfd[i].fd = -1;
|
||||
fds_found++;
|
||||
continue;
|
||||
} else
|
||||
fds_found++;
|
||||
#ifdef RPC_DEBUG
|
||||
fprintf(stderr, "response for %s\n",
|
||||
fdlist[i].nconf->nc_netid);
|
||||
#endif
|
||||
try_again:
|
||||
inlen = _recvfrom(fdlist[i].fd, inbuf, fdlist[i].dsize,
|
||||
0, (struct sockaddr *)(void *)&fdlist[i].raddr,
|
||||
&fdlist[i].asize);
|
||||
if (inlen < 0) {
|
||||
if (errno == EINTR)
|
||||
goto try_again;
|
||||
warnx("clnt_bcast: Cannot receive reply to "
|
||||
"broadcast");
|
||||
stat = RPC_CANTRECV;
|
||||
continue;
|
||||
}
|
||||
if (inlen < sizeof (u_int32_t))
|
||||
continue; /* Drop that and go ahead */
|
||||
/*
|
||||
* see if reply transaction id matches sent id.
|
||||
* If so, decode the results. If return id is xid + 1
|
||||
* it was a PORTMAP reply
|
||||
*/
|
||||
if (*((u_int32_t *)(void *)(inbuf)) ==
|
||||
*((u_int32_t *)(void *)(outbuf))) {
|
||||
pmap_reply_flag = 0;
|
||||
msg.acpted_rply.ar_verf = _null_auth;
|
||||
msg.acpted_rply.ar_results.where =
|
||||
(caddr_t)(void *)&bres;
|
||||
msg.acpted_rply.ar_results.proc =
|
||||
(xdrproc_t)xdr_rpcb_rmtcallres;
|
||||
#ifdef PORTMAP
|
||||
} else if (pmap_flag &&
|
||||
*((u_int32_t *)(void *)(inbuf)) ==
|
||||
*((u_int32_t *)(void *)(outbuf_pmap))) {
|
||||
pmap_reply_flag = 1;
|
||||
msg.acpted_rply.ar_verf = _null_auth;
|
||||
msg.acpted_rply.ar_results.where =
|
||||
(caddr_t)(void *)&bres_pmap;
|
||||
msg.acpted_rply.ar_results.proc =
|
||||
(xdrproc_t)xdr_rmtcallres;
|
||||
#endif /* PORTMAP */
|
||||
} else
|
||||
continue;
|
||||
xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
|
||||
if (xdr_replymsg(xdrs, &msg)) {
|
||||
if ((msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
|
||||
(msg.acpted_rply.ar_stat == SUCCESS)) {
|
||||
struct netbuf taddr, *np;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
#ifdef PORTMAP
|
||||
if (pmap_flag && pmap_reply_flag) {
|
||||
sin = (struct sockaddr_in *)
|
||||
(void *)&fdlist[i].raddr;
|
||||
sin->sin_port =
|
||||
htons((u_short)port);
|
||||
taddr.len = taddr.maxlen =
|
||||
fdlist[i].raddr.ss_len;
|
||||
taddr.buf = &fdlist[i].raddr;
|
||||
done = (*eachresult)(resultsp,
|
||||
&taddr, fdlist[i].nconf);
|
||||
} else {
|
||||
#endif /* PORTMAP */
|
||||
#ifdef RPC_DEBUG
|
||||
fprintf(stderr, "uaddr %s\n",
|
||||
uaddrp);
|
||||
#endif
|
||||
np = uaddr2taddr(
|
||||
fdlist[i].nconf, uaddrp);
|
||||
done = (*eachresult)(resultsp,
|
||||
np, fdlist[i].nconf);
|
||||
free(np);
|
||||
#ifdef PORTMAP
|
||||
}
|
||||
#endif /* PORTMAP */
|
||||
}
|
||||
/* otherwise, we just ignore the errors ... */
|
||||
}
|
||||
/* else some kind of deserialization problem ... */
|
||||
|
||||
xdrs->x_op = XDR_FREE;
|
||||
msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
|
||||
(void) xdr_replymsg(xdrs, &msg);
|
||||
(void) (*xresults)(xdrs, resultsp);
|
||||
XDR_DESTROY(xdrs);
|
||||
if (done) {
|
||||
stat = RPC_SUCCESS;
|
||||
goto done_broad;
|
||||
} else {
|
||||
goto recv_again;
|
||||
}
|
||||
} /* The recv for loop */
|
||||
} /* The giant for loop */
|
||||
|
||||
done_broad:
|
||||
if (inbuf)
|
||||
(void) free(inbuf);
|
||||
if (outbuf)
|
||||
(void) free(outbuf);
|
||||
#ifdef PORTMAP
|
||||
if (outbuf_pmap)
|
||||
(void) free(outbuf_pmap);
|
||||
#endif /* PORTMAP */
|
||||
for (i = 0; i < fdlistno; i++) {
|
||||
(void)_close(fdlist[i].fd);
|
||||
__rpc_freebroadifs(&fdlist[i].nal);
|
||||
}
|
||||
AUTH_DESTROY(sys_auth);
|
||||
(void) __rpc_endconf(handle);
|
||||
|
||||
return (stat);
|
||||
}
|
||||
|
||||
|
||||
enum clnt_stat
|
||||
rpc_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp,
|
||||
eachresult, nettype)
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
rpcproc_t proc; /* procedure number */
|
||||
xdrproc_t xargs; /* xdr routine for args */
|
||||
caddr_t argsp; /* pointer to args */
|
||||
xdrproc_t xresults; /* xdr routine for results */
|
||||
caddr_t resultsp; /* pointer to results */
|
||||
resultproc_t eachresult; /* call with each result obtained */
|
||||
const char *nettype; /* transport type */
|
||||
{
|
||||
enum clnt_stat dummy;
|
||||
|
||||
dummy = rpc_broadcast_exp(prog, vers, proc, xargs, argsp,
|
||||
xresults, resultsp, eachresult,
|
||||
INITTIME, WAITTIME, nettype);
|
||||
return (dummy);
|
||||
}
|
821
lib/libc/rpc/clnt_dg.c
Normal file
821
lib/libc/rpc/clnt_dg.c
Normal file
@ -0,0 +1,821 @@
|
||||
/* $NetBSD: clnt_dg.c,v 1.4 2000/07/14 08:40:41 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
/* #ident "@(#)clnt_dg.c 1.23 94/04/22 SMI" */
|
||||
|
||||
#if 0
|
||||
#if !defined(lint) && defined(SCCSIDS)
|
||||
static char sccsid[] = "@(#)clnt_dg.c 1.19 89/03/16 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Implements a connectionless client side RPC.
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/poll.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <err.h>
|
||||
#include "un-namespace.h"
|
||||
#include "rpc_com.h"
|
||||
|
||||
|
||||
#define RPC_MAX_BACKOFF 30 /* seconds */
|
||||
|
||||
|
||||
static struct clnt_ops *clnt_dg_ops __P((void));
|
||||
static bool_t time_not_ok __P((struct timeval *));
|
||||
static enum clnt_stat clnt_dg_call __P((CLIENT *, rpcproc_t, xdrproc_t, caddr_t,
|
||||
xdrproc_t, caddr_t, struct timeval));
|
||||
static void clnt_dg_geterr __P((CLIENT *, struct rpc_err *));
|
||||
static bool_t clnt_dg_freeres __P((CLIENT *, xdrproc_t, caddr_t));
|
||||
static void clnt_dg_abort __P((CLIENT *));
|
||||
static bool_t clnt_dg_control __P((CLIENT *, u_int, char *));
|
||||
static void clnt_dg_destroy __P((CLIENT *));
|
||||
static int __rpc_timeval_to_msec __P((struct timeval *));
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This machinery implements per-fd locks for MT-safety. It is not
|
||||
* sufficient to do per-CLIENT handle locks for MT-safety because a
|
||||
* user may create more than one CLIENT handle with the same fd behind
|
||||
* it. Therfore, we allocate an array of flags (dg_fd_locks), protected
|
||||
* by the clnt_fd_lock mutex, and an array (dg_cv) of condition variables
|
||||
* similarly protected. Dg_fd_lock[fd] == 1 => a call is activte on some
|
||||
* CLIENT handle created for that fd.
|
||||
* The current implementation holds locks across the entire RPC and reply,
|
||||
* including retransmissions. Yes, this is silly, and as soon as this
|
||||
* code is proven to work, this should be the first thing fixed. One step
|
||||
* at a time.
|
||||
*/
|
||||
static int *dg_fd_locks;
|
||||
extern mutex_t clnt_fd_lock;
|
||||
static cond_t *dg_cv;
|
||||
#define release_fd_lock(fd, mask) { \
|
||||
mutex_lock(&clnt_fd_lock); \
|
||||
if (__isthreaded) \
|
||||
dg_fd_locks[fd] = 0; \
|
||||
mutex_unlock(&clnt_fd_lock); \
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
|
||||
cond_signal(&dg_cv[fd]); \
|
||||
}
|
||||
|
||||
static const char mem_err_clnt_dg[] = "clnt_dg_create: out of memory";
|
||||
|
||||
/* VARIABLES PROTECTED BY clnt_fd_lock: dg_fd_locks, dg_cv */
|
||||
|
||||
/*
|
||||
* Private data kept per client handle
|
||||
*/
|
||||
struct cu_data {
|
||||
int cu_fd; /* connections fd */
|
||||
bool_t cu_closeit; /* opened by library */
|
||||
struct sockaddr_storage cu_raddr; /* remote address */
|
||||
int cu_rlen;
|
||||
struct timeval cu_wait; /* retransmit interval */
|
||||
struct timeval cu_total; /* total time for the call */
|
||||
struct rpc_err cu_error;
|
||||
XDR cu_outxdrs;
|
||||
u_int cu_xdrpos;
|
||||
u_int cu_sendsz; /* send size */
|
||||
char *cu_outbuf;
|
||||
u_int cu_recvsz; /* recv size */
|
||||
struct pollfd pfdp;
|
||||
char cu_inbuf[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* Connection less client creation returns with client handle parameters.
|
||||
* Default options are set, which the user can change using clnt_control().
|
||||
* fd should be open and bound.
|
||||
* NB: The rpch->cl_auth is initialized to null authentication.
|
||||
* Caller may wish to set this something more useful.
|
||||
*
|
||||
* sendsz and recvsz are the maximum allowable packet sizes that can be
|
||||
* sent and received. Normally they are the same, but they can be
|
||||
* changed to improve the program efficiency and buffer allocation.
|
||||
* If they are 0, use the transport default.
|
||||
*
|
||||
* If svcaddr is NULL, returns NULL.
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_dg_create(fd, svcaddr, program, version, sendsz, recvsz)
|
||||
int fd; /* open file descriptor */
|
||||
const struct netbuf *svcaddr; /* servers address */
|
||||
rpcprog_t program; /* program number */
|
||||
rpcvers_t version; /* version number */
|
||||
u_int sendsz; /* buffer recv size */
|
||||
u_int recvsz; /* buffer send size */
|
||||
{
|
||||
CLIENT *cl = NULL; /* client handle */
|
||||
struct cu_data *cu = NULL; /* private data */
|
||||
struct timeval now;
|
||||
struct rpc_msg call_msg;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
struct __rpc_sockinfo si;
|
||||
int one = 1;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
if (dg_fd_locks == (int *) NULL) {
|
||||
int cv_allocsz;
|
||||
size_t fd_allocsz;
|
||||
int dtbsize = __rpc_dtbsize();
|
||||
|
||||
fd_allocsz = dtbsize * sizeof (int);
|
||||
dg_fd_locks = (int *) mem_alloc(fd_allocsz);
|
||||
if (dg_fd_locks == (int *) NULL) {
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
goto err1;
|
||||
} else
|
||||
memset(dg_fd_locks, '\0', fd_allocsz);
|
||||
|
||||
cv_allocsz = dtbsize * sizeof (cond_t);
|
||||
dg_cv = (cond_t *) mem_alloc(cv_allocsz);
|
||||
if (dg_cv == (cond_t *) NULL) {
|
||||
mem_free(dg_fd_locks, fd_allocsz);
|
||||
dg_fd_locks = (int *) NULL;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
goto err1;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dtbsize; i++)
|
||||
cond_init(&dg_cv[i], 0, (void *) 0);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
|
||||
if (svcaddr == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (!__rpc_fd2sockinfo(fd, &si)) {
|
||||
rpc_createerr.cf_stat = RPC_TLIERROR;
|
||||
rpc_createerr.cf_error.re_errno = 0;
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Find the receive and the send size
|
||||
*/
|
||||
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
|
||||
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
|
||||
if ((sendsz == 0) || (recvsz == 0)) {
|
||||
rpc_createerr.cf_stat = RPC_TLIERROR; /* XXX */
|
||||
rpc_createerr.cf_error.re_errno = 0;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((cl = mem_alloc(sizeof (CLIENT))) == NULL)
|
||||
goto err1;
|
||||
/*
|
||||
* Should be multiple of 4 for XDR.
|
||||
*/
|
||||
sendsz = ((sendsz + 3) / 4) * 4;
|
||||
recvsz = ((recvsz + 3) / 4) * 4;
|
||||
cu = mem_alloc(sizeof (*cu) + sendsz + recvsz);
|
||||
if (cu == NULL)
|
||||
goto err1;
|
||||
(void) memcpy(&cu->cu_raddr, svcaddr->buf, (size_t)svcaddr->len);
|
||||
cu->cu_rlen = svcaddr->len;
|
||||
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
|
||||
/* Other values can also be set through clnt_control() */
|
||||
cu->cu_wait.tv_sec = 15; /* heuristically chosen */
|
||||
cu->cu_wait.tv_usec = 0;
|
||||
cu->cu_total.tv_sec = -1;
|
||||
cu->cu_total.tv_usec = -1;
|
||||
cu->cu_sendsz = sendsz;
|
||||
cu->cu_recvsz = recvsz;
|
||||
(void) gettimeofday(&now, NULL);
|
||||
call_msg.rm_xid = __RPC_GETXID(&now);
|
||||
call_msg.rm_call.cb_prog = program;
|
||||
call_msg.rm_call.cb_vers = version;
|
||||
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, sendsz, XDR_ENCODE);
|
||||
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
|
||||
rpc_createerr.cf_stat = RPC_CANTENCODEARGS; /* XXX */
|
||||
rpc_createerr.cf_error.re_errno = 0;
|
||||
goto err2;
|
||||
}
|
||||
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
|
||||
|
||||
/* XXX fvdl - do we still want this? */
|
||||
#if 0
|
||||
(void)bindresvport_sa(fd, (struct sockaddr *)svcaddr->buf);
|
||||
#endif
|
||||
_ioctl(fd, FIONBIO, (char *)(void *)&one);
|
||||
|
||||
/*
|
||||
* By default, closeit is always FALSE. It is users responsibility
|
||||
* to do a close on it, else the user may use clnt_control
|
||||
* to let clnt_destroy do it for him/her.
|
||||
*/
|
||||
cu->cu_closeit = FALSE;
|
||||
cu->cu_fd = fd;
|
||||
cl->cl_ops = clnt_dg_ops();
|
||||
cl->cl_private = (caddr_t)(void *)cu;
|
||||
cl->cl_auth = authnone_create();
|
||||
cl->cl_tp = NULL;
|
||||
cl->cl_netid = NULL;
|
||||
cu->pfdp.fd = cu->cu_fd;
|
||||
cu->pfdp.events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND;
|
||||
return (cl);
|
||||
err1:
|
||||
warnx(mem_err_clnt_dg);
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
err2:
|
||||
if (cl) {
|
||||
mem_free(cl, sizeof (CLIENT));
|
||||
if (cu)
|
||||
mem_free(cu, sizeof (*cu) + sendsz + recvsz);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clnt_dg_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
|
||||
CLIENT *cl; /* client handle */
|
||||
rpcproc_t proc; /* procedure number */
|
||||
xdrproc_t xargs; /* xdr routine for args */
|
||||
caddr_t argsp; /* pointer to args */
|
||||
xdrproc_t xresults; /* xdr routine for results */
|
||||
caddr_t resultsp; /* pointer to results */
|
||||
struct timeval utimeout; /* seconds to wait before giving up */
|
||||
{
|
||||
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
XDR *xdrs;
|
||||
size_t outlen;
|
||||
struct rpc_msg reply_msg;
|
||||
XDR reply_xdrs;
|
||||
struct timeval time_waited;
|
||||
bool_t ok;
|
||||
int nrefreshes = 2; /* number of times to refresh cred */
|
||||
struct timeval timeout;
|
||||
struct timeval retransmit_time;
|
||||
struct timeval startime, curtime;
|
||||
int firsttimeout = 1;
|
||||
int dtbsize = __rpc_dtbsize();
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
socklen_t fromlen, inlen;
|
||||
ssize_t recvlen = 0;
|
||||
int rpc_lock_value;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (dg_fd_locks[cu->cu_fd])
|
||||
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
|
||||
if (__isthreaded)
|
||||
rpc_lock_value = 1;
|
||||
else
|
||||
rpc_lock_value = 0;
|
||||
dg_fd_locks[cu->cu_fd] = rpc_lock_value;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
if (cu->cu_total.tv_usec == -1) {
|
||||
timeout = utimeout; /* use supplied timeout */
|
||||
} else {
|
||||
timeout = cu->cu_total; /* use default timeout */
|
||||
}
|
||||
|
||||
time_waited.tv_sec = 0;
|
||||
time_waited.tv_usec = 0;
|
||||
retransmit_time = cu->cu_wait;
|
||||
|
||||
call_again:
|
||||
xdrs = &(cu->cu_outxdrs);
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
XDR_SETPOS(xdrs, cu->cu_xdrpos);
|
||||
/*
|
||||
* the transaction is the first thing in the out buffer
|
||||
*/
|
||||
(*(u_int32_t *)(void *)(cu->cu_outbuf))++;
|
||||
if ((! XDR_PUTINT32(xdrs, &proc)) ||
|
||||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
|
||||
(! (*xargs)(xdrs, argsp))) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
|
||||
}
|
||||
outlen = (size_t)XDR_GETPOS(xdrs);
|
||||
|
||||
send_again:
|
||||
if (_sendto(cu->cu_fd, cu->cu_outbuf, outlen, 0,
|
||||
(struct sockaddr *)(void *)&cu->cu_raddr, (socklen_t)cu->cu_rlen)
|
||||
!= outlen) {
|
||||
cu->cu_error.re_errno = errno;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_CANTSEND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hack to provide rpc-based message passing
|
||||
*/
|
||||
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
/*
|
||||
* sub-optimal code appears here because we have
|
||||
* some clock time to spare while the packets are in flight.
|
||||
* (We assume that this is actually only executed once.)
|
||||
*/
|
||||
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||
reply_msg.acpted_rply.ar_results.where = resultsp;
|
||||
reply_msg.acpted_rply.ar_results.proc = xresults;
|
||||
|
||||
|
||||
for (;;) {
|
||||
switch (_poll(&cu->pfdp, 1,
|
||||
__rpc_timeval_to_msec(&retransmit_time))) {
|
||||
case 0:
|
||||
time_waited.tv_sec += retransmit_time.tv_sec;
|
||||
time_waited.tv_usec += retransmit_time.tv_usec;
|
||||
while (time_waited.tv_usec >= 1000000) {
|
||||
time_waited.tv_sec++;
|
||||
time_waited.tv_usec -= 1000000;
|
||||
}
|
||||
/* update retransmit_time */
|
||||
if (retransmit_time.tv_sec < RPC_MAX_BACKOFF) {
|
||||
retransmit_time.tv_usec *= 2;
|
||||
retransmit_time.tv_sec *= 2;
|
||||
while (retransmit_time.tv_usec >= 1000000) {
|
||||
retransmit_time.tv_sec++;
|
||||
retransmit_time.tv_usec -= 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
if ((time_waited.tv_sec < timeout.tv_sec) ||
|
||||
((time_waited.tv_sec == timeout.tv_sec) &&
|
||||
(time_waited.tv_usec < timeout.tv_usec)))
|
||||
goto send_again;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
|
||||
case -1:
|
||||
if (errno == EBADF) {
|
||||
cu->cu_error.re_errno = errno;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||
}
|
||||
if (errno != EINTR) {
|
||||
errno = 0; /* reset it */
|
||||
continue;
|
||||
}
|
||||
/* interrupted by another signal, update time_waited */
|
||||
if (firsttimeout) {
|
||||
/*
|
||||
* Could have done gettimeofday before clnt_call
|
||||
* but that means 1 more system call per each
|
||||
* clnt_call, so do it after first time out
|
||||
*/
|
||||
if (gettimeofday(&startime,
|
||||
(struct timezone *) NULL) == -1) {
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
firsttimeout = 0;
|
||||
errno = 0;
|
||||
continue;
|
||||
};
|
||||
if (gettimeofday(&curtime,
|
||||
(struct timezone *) NULL) == -1) {
|
||||
errno = 0;
|
||||
continue;
|
||||
};
|
||||
time_waited.tv_sec += curtime.tv_sec - startime.tv_sec;
|
||||
time_waited.tv_usec += curtime.tv_usec -
|
||||
startime.tv_usec;
|
||||
while (time_waited.tv_usec < 0) {
|
||||
time_waited.tv_sec--;
|
||||
time_waited.tv_usec += 1000000;
|
||||
};
|
||||
while (time_waited.tv_usec >= 1000000) {
|
||||
time_waited.tv_sec++;
|
||||
time_waited.tv_usec -= 1000000;
|
||||
}
|
||||
startime.tv_sec = curtime.tv_sec;
|
||||
startime.tv_usec = curtime.tv_usec;
|
||||
if ((time_waited.tv_sec > timeout.tv_sec) ||
|
||||
((time_waited.tv_sec == timeout.tv_sec) &&
|
||||
(time_waited.tv_usec > timeout.tv_usec))) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
errno = 0; /* reset it */
|
||||
continue;
|
||||
};
|
||||
|
||||
if (cu->pfdp.revents & POLLNVAL || (cu->pfdp.revents == 0)) {
|
||||
cu->cu_error.re_status = RPC_CANTRECV;
|
||||
/*
|
||||
* Note: we're faking errno here because we
|
||||
* previously would have expected _poll() to
|
||||
* return -1 with errno EBADF. Poll(BA_OS)
|
||||
* returns 0 and sets the POLLNVAL revents flag
|
||||
* instead.
|
||||
*/
|
||||
cu->cu_error.re_errno = errno = EBADF;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* We have some data now */
|
||||
do {
|
||||
if (errno == EINTR) {
|
||||
/*
|
||||
* Must make sure errno was not already
|
||||
* EINTR in case _recvfrom() returns -1.
|
||||
*/
|
||||
errno = 0;
|
||||
}
|
||||
fromlen = sizeof (struct sockaddr_storage);
|
||||
recvlen = _recvfrom(cu->cu_fd, cu->cu_inbuf,
|
||||
cu->cu_recvsz, 0, (struct sockaddr *)(void *)&cu->cu_raddr,
|
||||
&fromlen);
|
||||
} while (recvlen < 0 && errno == EINTR);
|
||||
if (recvlen < 0) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
continue;
|
||||
cu->cu_error.re_errno = errno;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||
}
|
||||
if (recvlen < sizeof (u_int32_t))
|
||||
continue;
|
||||
/* see if reply transaction id matches sent id */
|
||||
if (*((u_int32_t *)(void *)(cu->cu_inbuf)) !=
|
||||
*((u_int32_t *)(void *)(cu->cu_outbuf)))
|
||||
continue;
|
||||
/* we now assume we have the proper reply */
|
||||
break;
|
||||
}
|
||||
inlen = (socklen_t)recvlen;
|
||||
|
||||
/*
|
||||
* now decode and validate the response
|
||||
*/
|
||||
|
||||
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
|
||||
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
|
||||
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
|
||||
if (ok) {
|
||||
if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
|
||||
(reply_msg.acpted_rply.ar_stat == SUCCESS))
|
||||
cu->cu_error.re_status = RPC_SUCCESS;
|
||||
else
|
||||
_seterr_reply(&reply_msg, &(cu->cu_error));
|
||||
|
||||
if (cu->cu_error.re_status == RPC_SUCCESS) {
|
||||
if (! AUTH_VALIDATE(cl->cl_auth,
|
||||
&reply_msg.acpted_rply.ar_verf)) {
|
||||
cu->cu_error.re_status = RPC_AUTHERROR;
|
||||
cu->cu_error.re_why = AUTH_INVALIDRESP;
|
||||
}
|
||||
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||
xdrs->x_op = XDR_FREE;
|
||||
(void) xdr_opaque_auth(xdrs,
|
||||
&(reply_msg.acpted_rply.ar_verf));
|
||||
}
|
||||
} /* end successful completion */
|
||||
/*
|
||||
* If unsuccesful AND error is an authentication error
|
||||
* then refresh credentials and try again, else break
|
||||
*/
|
||||
else if (cu->cu_error.re_status == RPC_AUTHERROR)
|
||||
/* maybe our credentials need to be refreshed ... */
|
||||
if (nrefreshes > 0 &&
|
||||
AUTH_REFRESH(cl->cl_auth, &reply_msg)) {
|
||||
nrefreshes--;
|
||||
goto call_again;
|
||||
}
|
||||
/* end of unsuccessful completion */
|
||||
} /* end of valid reply message */
|
||||
else {
|
||||
cu->cu_error.re_status = RPC_CANTDECODERES;
|
||||
|
||||
}
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (cu->cu_error.re_status);
|
||||
}
|
||||
|
||||
static void
|
||||
clnt_dg_geterr(cl, errp)
|
||||
CLIENT *cl;
|
||||
struct rpc_err *errp;
|
||||
{
|
||||
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
|
||||
*errp = cu->cu_error;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clnt_dg_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
XDR *xdrs = &(cu->cu_outxdrs);
|
||||
bool_t dummy;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (dg_fd_locks[cu->cu_fd])
|
||||
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
|
||||
xdrs->x_op = XDR_FREE;
|
||||
dummy = (*xdr_res)(xdrs, res_ptr);
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||
cond_signal(&dg_cv[cu->cu_fd]);
|
||||
return (dummy);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
clnt_dg_abort(h)
|
||||
CLIENT *h;
|
||||
{
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clnt_dg_control(cl, request, info)
|
||||
CLIENT *cl;
|
||||
u_int request;
|
||||
char *info;
|
||||
{
|
||||
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
struct netbuf *addr;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
int rpc_lock_value;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (dg_fd_locks[cu->cu_fd])
|
||||
cond_wait(&dg_cv[cu->cu_fd], &clnt_fd_lock);
|
||||
if (__isthreaded)
|
||||
rpc_lock_value = 1;
|
||||
else
|
||||
rpc_lock_value = 0;
|
||||
dg_fd_locks[cu->cu_fd] = rpc_lock_value;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
switch (request) {
|
||||
case CLSET_FD_CLOSE:
|
||||
cu->cu_closeit = TRUE;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (TRUE);
|
||||
case CLSET_FD_NCLOSE:
|
||||
cu->cu_closeit = FALSE;
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* for other requests which use info */
|
||||
if (info == NULL) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
switch (request) {
|
||||
case CLSET_TIMEOUT:
|
||||
if (time_not_ok((struct timeval *)(void *)info)) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
cu->cu_total = *(struct timeval *)(void *)info;
|
||||
break;
|
||||
case CLGET_TIMEOUT:
|
||||
*(struct timeval *)(void *)info = cu->cu_total;
|
||||
break;
|
||||
case CLGET_SERVER_ADDR: /* Give him the fd address */
|
||||
/* Now obsolete. Only for backward compatibility */
|
||||
(void) memcpy(info, &cu->cu_raddr, (size_t)cu->cu_rlen);
|
||||
break;
|
||||
case CLSET_RETRY_TIMEOUT:
|
||||
if (time_not_ok((struct timeval *)(void *)info)) {
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
cu->cu_wait = *(struct timeval *)(void *)info;
|
||||
break;
|
||||
case CLGET_RETRY_TIMEOUT:
|
||||
*(struct timeval *)(void *)info = cu->cu_wait;
|
||||
break;
|
||||
case CLGET_FD:
|
||||
*(int *)(void *)info = cu->cu_fd;
|
||||
break;
|
||||
case CLGET_SVC_ADDR:
|
||||
addr = (struct netbuf *)(void *)info;
|
||||
addr->buf = &cu->cu_raddr;
|
||||
addr->len = cu->cu_rlen;
|
||||
addr->maxlen = sizeof cu->cu_raddr;
|
||||
break;
|
||||
case CLSET_SVC_ADDR: /* set to new address */
|
||||
addr = (struct netbuf *)(void *)info;
|
||||
if (addr->len < sizeof cu->cu_raddr)
|
||||
return (FALSE);
|
||||
(void) memcpy(&cu->cu_raddr, addr->buf, addr->len);
|
||||
cu->cu_rlen = addr->len;
|
||||
break;
|
||||
case CLGET_XID:
|
||||
/*
|
||||
* use the knowledge that xid is the
|
||||
* first element in the call structure *.
|
||||
* This will get the xid of the PREVIOUS call
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)cu->cu_outbuf);
|
||||
break;
|
||||
|
||||
case CLSET_XID:
|
||||
/* This will set the xid of the NEXT call */
|
||||
*(u_int32_t *)(void *)cu->cu_outbuf =
|
||||
htonl(*(u_int32_t *)(void *)info - 1);
|
||||
/* decrement by 1 as clnt_dg_call() increments once */
|
||||
break;
|
||||
|
||||
case CLGET_VERS:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the version number field is the fifth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
|
||||
4 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
|
||||
case CLSET_VERS:
|
||||
*(u_int32_t *)(void *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_int32_t *)(void *)info);
|
||||
break;
|
||||
|
||||
case CLGET_PROG:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the program number field is the fourth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)(cu->cu_outbuf +
|
||||
3 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
|
||||
case CLSET_PROG:
|
||||
*(u_int32_t *)(void *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_int32_t *)(void *)info);
|
||||
break;
|
||||
|
||||
default:
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
release_fd_lock(cu->cu_fd, mask);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
clnt_dg_destroy(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
int cu_fd = cu->cu_fd;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (dg_fd_locks[cu_fd])
|
||||
cond_wait(&dg_cv[cu_fd], &clnt_fd_lock);
|
||||
if (cu->cu_closeit)
|
||||
(void)_close(cu_fd);
|
||||
XDR_DESTROY(&(cu->cu_outxdrs));
|
||||
mem_free(cu, (sizeof (*cu) + cu->cu_sendsz + cu->cu_recvsz));
|
||||
if (cl->cl_netid && cl->cl_netid[0])
|
||||
mem_free(cl->cl_netid, strlen(cl->cl_netid) +1);
|
||||
if (cl->cl_tp && cl->cl_tp[0])
|
||||
mem_free(cl->cl_tp, strlen(cl->cl_tp) +1);
|
||||
mem_free(cl, sizeof (CLIENT));
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||
cond_signal(&dg_cv[cu_fd]);
|
||||
}
|
||||
|
||||
static struct clnt_ops *
|
||||
clnt_dg_ops()
|
||||
{
|
||||
static struct clnt_ops ops;
|
||||
extern mutex_t ops_lock;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&ops_lock);
|
||||
if (ops.cl_call == NULL) {
|
||||
ops.cl_call = clnt_dg_call;
|
||||
ops.cl_abort = clnt_dg_abort;
|
||||
ops.cl_geterr = clnt_dg_geterr;
|
||||
ops.cl_freeres = clnt_dg_freeres;
|
||||
ops.cl_destroy = clnt_dg_destroy;
|
||||
ops.cl_control = clnt_dg_control;
|
||||
}
|
||||
mutex_unlock(&ops_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &mask, NULL);
|
||||
return (&ops);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the time is not garbage. -1 value is allowed.
|
||||
*/
|
||||
static bool_t
|
||||
time_not_ok(t)
|
||||
struct timeval *t;
|
||||
{
|
||||
return (t->tv_sec < -1 || t->tv_sec > 100000000 ||
|
||||
t->tv_usec < -1 || t->tv_usec > 1000000);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert from timevals (used by select) to milliseconds (used by poll).
|
||||
*/
|
||||
static int
|
||||
__rpc_timeval_to_msec(t)
|
||||
struct timeval *t;
|
||||
{
|
||||
int t1, tmp;
|
||||
|
||||
/*
|
||||
* We're really returning t->tv_sec * 1000 + (t->tv_usec / 1000)
|
||||
* but try to do so efficiently. Note: 1000 = 1024 - 16 - 8.
|
||||
*/
|
||||
tmp = (int)t->tv_sec << 3;
|
||||
t1 = -tmp;
|
||||
t1 += t1 << 1;
|
||||
t1 += tmp << 7;
|
||||
if (t->tv_usec)
|
||||
t1 += (int)(t->tv_usec / 1000);
|
||||
|
||||
return (t1);
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: clnt_generic.c,v 1.18 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,8 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
/* #ident "@(#)clnt_generic.c 1.20 94/05/03 SMI" */
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
@ -34,104 +38,312 @@ static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (C) 1987, Sun Microsystems, Inc.
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
#include <rpc/rpc.h>
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/nettype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
#include "rpc_com.h"
|
||||
|
||||
/*
|
||||
* Generic client creation: takes (hostname, program-number, protocol) and
|
||||
* returns client handle. Default options are set, which the user can
|
||||
* change using the rpc equivalent of _ioctl()'s.
|
||||
* Generic client creation with version checking the value of
|
||||
* vers_out is set to the highest server supported value
|
||||
* vers_low <= vers_out <= vers_high AND an error results
|
||||
* if this can not be done.
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_create(hostname, prog, vers, proto)
|
||||
char *hostname;
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
char *proto;
|
||||
clnt_create_vers(hostname, prog, vers_out, vers_low, vers_high, nettype)
|
||||
const char *hostname;
|
||||
rpcprog_t prog;
|
||||
rpcvers_t *vers_out;
|
||||
rpcvers_t vers_low;
|
||||
rpcvers_t vers_high;
|
||||
const char *nettype;
|
||||
{
|
||||
struct hostent *h;
|
||||
struct protoent *p;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_un sun;
|
||||
int sock;
|
||||
static struct timeval tv;
|
||||
CLIENT *client;
|
||||
CLIENT *clnt;
|
||||
struct timeval to;
|
||||
enum clnt_stat rpc_stat;
|
||||
struct rpc_err rpcerr;
|
||||
|
||||
if (!strcmp(proto, "unix")) {
|
||||
bzero((char *)&sun, sizeof(sun));
|
||||
sun.sun_family = AF_UNIX;
|
||||
strcpy(sun.sun_path, hostname);
|
||||
sun.sun_len = sizeof(sun.sun_len) + sizeof(sun.sun_family) +
|
||||
strlen(sun.sun_path) + 1;
|
||||
sock = RPC_ANYSOCK;
|
||||
client = clntunix_create(&sun, prog, vers, &sock, 0, 0);
|
||||
if (client == NULL)
|
||||
return(NULL);
|
||||
tv.tv_sec = 25;
|
||||
tv.tv_usec = 0;
|
||||
clnt_control(client, CLSET_TIMEOUT, &tv);
|
||||
return(client);
|
||||
}
|
||||
|
||||
h = gethostbyname(hostname);
|
||||
if (h == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
|
||||
clnt = clnt_create(hostname, prog, vers_high, nettype);
|
||||
if (clnt == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
if (h->h_addrtype != AF_INET) {
|
||||
/*
|
||||
* Only support INET for now
|
||||
*/
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
to.tv_sec = 10;
|
||||
to.tv_usec = 0;
|
||||
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void,
|
||||
(char *) NULL, (xdrproc_t) xdr_void, (char *) NULL, to);
|
||||
if (rpc_stat == RPC_SUCCESS) {
|
||||
*vers_out = vers_high;
|
||||
return (clnt);
|
||||
}
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_family = h->h_addrtype;
|
||||
sin.sin_port = 0;
|
||||
memcpy((char*)&sin.sin_addr, h->h_addr, h->h_length);
|
||||
p = getprotobyname(proto);
|
||||
if (p == NULL) {
|
||||
if (rpc_stat == RPC_PROGVERSMISMATCH) {
|
||||
unsigned long minvers, maxvers;
|
||||
|
||||
clnt_geterr(clnt, &rpcerr);
|
||||
minvers = rpcerr.re_vers.low;
|
||||
maxvers = rpcerr.re_vers.high;
|
||||
if (maxvers < vers_high)
|
||||
vers_high = (rpcvers_t)maxvers;
|
||||
if (minvers > vers_low)
|
||||
vers_low = (rpcvers_t)minvers;
|
||||
if (vers_low > vers_high) {
|
||||
goto error;
|
||||
}
|
||||
CLNT_CONTROL(clnt, CLSET_VERS, (char *)(void *)&vers_high);
|
||||
rpc_stat = clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void,
|
||||
(char *) NULL, (xdrproc_t) xdr_void,
|
||||
(char *) NULL, to);
|
||||
if (rpc_stat == RPC_SUCCESS) {
|
||||
*vers_out = vers_high;
|
||||
return (clnt);
|
||||
}
|
||||
}
|
||||
clnt_geterr(clnt, &rpcerr);
|
||||
|
||||
error:
|
||||
rpc_createerr.cf_stat = rpc_stat;
|
||||
rpc_createerr.cf_error = rpcerr;
|
||||
clnt_destroy(clnt);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Top level client creation routine.
|
||||
* Generic client creation: takes (servers name, program-number, nettype) and
|
||||
* returns client handle. Default options are set, which the user can
|
||||
* change using the rpc equivalent of _ioctl()'s.
|
||||
*
|
||||
* It tries for all the netids in that particular class of netid until
|
||||
* it succeeds.
|
||||
* XXX The error message in the case of failure will be the one
|
||||
* pertaining to the last create error.
|
||||
*
|
||||
* It calls clnt_tp_create();
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_create(hostname, prog, vers, nettype)
|
||||
const char *hostname; /* server name */
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
const char *nettype; /* net type */
|
||||
{
|
||||
struct netconfig *nconf;
|
||||
CLIENT *clnt = NULL;
|
||||
void *handle;
|
||||
enum clnt_stat save_cf_stat = RPC_SUCCESS;
|
||||
struct rpc_err save_cf_error;
|
||||
|
||||
|
||||
if ((handle = __rpc_setconf(nettype)) == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
sock = RPC_ANYSOCK;
|
||||
switch (p->p_proto) {
|
||||
case IPPROTO_UDP:
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
client = clntudp_create(&sin, prog, vers, tv, &sock);
|
||||
if (client == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_SUCCESS;
|
||||
while (clnt == NULL) {
|
||||
if ((nconf = __rpc_getconf(handle)) == NULL) {
|
||||
if (rpc_createerr.cf_stat == RPC_SUCCESS)
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||
break;
|
||||
}
|
||||
#ifdef CLNT_DEBUG
|
||||
printf("trying netid %s\n", nconf->nc_netid);
|
||||
#endif
|
||||
clnt = clnt_tp_create(hostname, prog, vers, nconf);
|
||||
if (clnt)
|
||||
break;
|
||||
else
|
||||
/*
|
||||
* Since we didn't get a name-to-address
|
||||
* translation failure here, we remember
|
||||
* this particular error. The object of
|
||||
* this is to enable us to return to the
|
||||
* caller a more-specific error than the
|
||||
* unhelpful ``Name to address translation
|
||||
* failed'' which might well occur if we
|
||||
* merely returned the last error (because
|
||||
* the local loopbacks are typically the
|
||||
* last ones in /etc/netconfig and the most
|
||||
* likely to be unable to translate a host
|
||||
* name).
|
||||
*/
|
||||
if (rpc_createerr.cf_stat != RPC_N2AXLATEFAILURE) {
|
||||
save_cf_stat = rpc_createerr.cf_stat;
|
||||
save_cf_error = rpc_createerr.cf_error;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to return an error more specific than ``Name to address
|
||||
* translation failed''
|
||||
*/
|
||||
if ((rpc_createerr.cf_stat == RPC_N2AXLATEFAILURE) &&
|
||||
(save_cf_stat != RPC_SUCCESS)) {
|
||||
rpc_createerr.cf_stat = save_cf_stat;
|
||||
rpc_createerr.cf_error = save_cf_error;
|
||||
}
|
||||
__rpc_endconf(handle);
|
||||
return (clnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic client creation: takes (servers name, program-number, netconf) and
|
||||
* returns client handle. Default options are set, which the user can
|
||||
* change using the rpc equivalent of _ioctl()'s : clnt_control()
|
||||
* It finds out the server address from rpcbind and calls clnt_tli_create()
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_tp_create(hostname, prog, vers, nconf)
|
||||
const char *hostname; /* server name */
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
const struct netconfig *nconf; /* net config struct */
|
||||
{
|
||||
struct netbuf *svcaddr; /* servers address */
|
||||
CLIENT *cl = NULL; /* client handle */
|
||||
|
||||
if (nconf == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the address of the server
|
||||
*/
|
||||
if ((svcaddr = __rpcb_findaddr(prog, vers, nconf, hostname,
|
||||
&cl)) == NULL) {
|
||||
/* appropriate error number is set by rpcbind libraries */
|
||||
return (NULL);
|
||||
}
|
||||
if (cl == NULL) {
|
||||
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
|
||||
prog, vers, 0, 0);
|
||||
} else {
|
||||
/* Reuse the CLIENT handle and change the appropriate fields */
|
||||
if (CLNT_CONTROL(cl, CLSET_SVC_ADDR, (void *)svcaddr) == TRUE) {
|
||||
if (cl->cl_netid == NULL)
|
||||
cl->cl_netid = strdup(nconf->nc_netid);
|
||||
if (cl->cl_tp == NULL)
|
||||
cl->cl_tp = strdup(nconf->nc_device);
|
||||
(void) CLNT_CONTROL(cl, CLSET_PROG, (void *)&prog);
|
||||
(void) CLNT_CONTROL(cl, CLSET_VERS, (void *)&vers);
|
||||
} else {
|
||||
CLNT_DESTROY(cl);
|
||||
cl = clnt_tli_create(RPC_ANYFD, nconf, svcaddr,
|
||||
prog, vers, 0, 0);
|
||||
}
|
||||
}
|
||||
free(svcaddr->buf);
|
||||
free(svcaddr);
|
||||
return (cl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generic client creation: returns client handle.
|
||||
* Default options are set, which the user can
|
||||
* change using the rpc equivalent of _ioctl()'s : clnt_control().
|
||||
* If fd is RPC_ANYFD, it will be opened using nconf.
|
||||
* It will be bound if not so.
|
||||
* If sizes are 0; appropriate defaults will be chosen.
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_tli_create(fd, nconf, svcaddr, prog, vers, sendsz, recvsz)
|
||||
int fd; /* fd */
|
||||
const struct netconfig *nconf; /* netconfig structure */
|
||||
const struct netbuf *svcaddr; /* servers address */
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
u_int sendsz; /* send size */
|
||||
u_int recvsz; /* recv size */
|
||||
{
|
||||
CLIENT *cl; /* client handle */
|
||||
bool_t madefd = FALSE; /* whether fd opened here */
|
||||
long servtype;
|
||||
int one = 1;
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (fd == RPC_ANYFD) {
|
||||
if (nconf == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||
return (NULL);
|
||||
}
|
||||
#if 0 /* XXX do we need this? */
|
||||
tv.tv_sec = 25;
|
||||
tv.tv_usec = 0;
|
||||
clnt_control(client, CLSET_TIMEOUT, &tv);
|
||||
#endif
|
||||
|
||||
fd = __rpc_nconf2fd(nconf);
|
||||
|
||||
if (fd == -1)
|
||||
goto err;
|
||||
|
||||
madefd = TRUE;
|
||||
servtype = nconf->nc_semantics;
|
||||
if (!__rpc_fd2sockinfo(fd, &si))
|
||||
goto err;
|
||||
|
||||
bindresvport(fd, NULL);
|
||||
} else {
|
||||
if (!__rpc_fd2sockinfo(fd, &si))
|
||||
goto err;
|
||||
servtype = __rpc_socktype2seman(si.si_socktype);
|
||||
if (servtype == -1) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (si.si_af != ((struct sockaddr *)svcaddr->buf)->sa_family) {
|
||||
rpc_createerr.cf_stat = RPC_UNKNOWNHOST; /* XXX */
|
||||
goto err1;
|
||||
}
|
||||
|
||||
switch (servtype) {
|
||||
case NC_TPI_COTS_ORD:
|
||||
cl = clnt_vc_create(fd, svcaddr, prog, vers, sendsz, recvsz);
|
||||
if (!nconf || !cl)
|
||||
break;
|
||||
/* XXX fvdl - is this useful? */
|
||||
if (strncmp(nconf->nc_protofmly, "inet", 4) == 0)
|
||||
_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
|
||||
sizeof (one));
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
|
||||
if (client == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
#if 0 /* XXX do we need this? */
|
||||
tv.tv_sec = 25;
|
||||
tv.tv_usec = 0;
|
||||
clnt_control(client, CLSET_TIMEOUT, &tv);
|
||||
#endif
|
||||
case NC_TPI_CLTS:
|
||||
cl = clnt_dg_create(fd, svcaddr, prog, vers, sendsz, recvsz);
|
||||
break;
|
||||
default:
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
|
||||
return (NULL);
|
||||
goto err;
|
||||
}
|
||||
return (client);
|
||||
|
||||
if (cl == NULL)
|
||||
goto err1; /* borrow errors from clnt_dg/vc creates */
|
||||
if (nconf) {
|
||||
cl->cl_netid = strdup(nconf->nc_netid);
|
||||
cl->cl_tp = strdup(nconf->nc_device);
|
||||
} else {
|
||||
cl->cl_netid = "";
|
||||
cl->cl_tp = "";
|
||||
}
|
||||
if (madefd) {
|
||||
(void) CLNT_CONTROL(cl, CLSET_FD_CLOSE, NULL);
|
||||
/* (void) CLNT_CONTROL(cl, CLSET_POP_TIMOD, (char *) NULL); */
|
||||
};
|
||||
|
||||
return (cl);
|
||||
|
||||
err:
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
err1: if (madefd)
|
||||
(void)_close(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
/* $NetBSD: clnt_perror.c,v 1.24 2000/06/02 23:11:07 fvdl Exp $ */
|
||||
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +30,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -39,19 +43,24 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/auth.h>
|
||||
#include <rpc/clnt.h>
|
||||
|
||||
static char *auth_errmsg();
|
||||
#define CLNT_PERROR_BUFLEN 256
|
||||
#include "un-namespace.h"
|
||||
|
||||
static char *buf;
|
||||
|
||||
static char *_buf __P((void));
|
||||
static char *auth_errmsg __P((enum auth_stat));
|
||||
#define CLNT_PERROR_BUFLEN 256
|
||||
|
||||
static char *
|
||||
_buf()
|
||||
{
|
||||
@ -67,19 +76,32 @@ _buf()
|
||||
char *
|
||||
clnt_sperror(rpch, s)
|
||||
CLIENT *rpch;
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
struct rpc_err e;
|
||||
char *err;
|
||||
char *str = _buf();
|
||||
char *strstart = str;
|
||||
char *str;
|
||||
char *strstart;
|
||||
size_t len, i;
|
||||
|
||||
assert(rpch != NULL);
|
||||
assert(s != NULL);
|
||||
|
||||
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
|
||||
if (str == 0)
|
||||
return (0);
|
||||
len = CLNT_PERROR_BUFLEN;
|
||||
strstart = str;
|
||||
CLNT_GETERR(rpch, &e);
|
||||
|
||||
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s", s, clnt_sperrno(e.re_status));
|
||||
str += strlen(str);
|
||||
i = snprintf(str, len, "%s: ", s);
|
||||
str += i;
|
||||
len -= i;
|
||||
|
||||
(void)strncpy(str, clnt_sperrno(e.re_status), len - 1);
|
||||
i = strlen(str);
|
||||
str += i;
|
||||
len -= i;
|
||||
|
||||
switch (e.re_status) {
|
||||
case RPC_SUCCESS:
|
||||
@ -99,42 +121,48 @@ clnt_sperror(rpch, s)
|
||||
|
||||
case RPC_CANTSEND:
|
||||
case RPC_CANTRECV:
|
||||
(void) snprintf(str, CLNT_PERROR_BUFLEN - (str - strstart),
|
||||
"; errno = %s\n", strerror(e.re_errno));
|
||||
i = snprintf(str, len, "; errno = %s", strerror(e.re_errno));
|
||||
str += i;
|
||||
len -= i;
|
||||
break;
|
||||
|
||||
case RPC_VERSMISMATCH:
|
||||
(void) sprintf(str,
|
||||
"; low version = %lu, high version = %lu\n",
|
||||
(u_long)e.re_vers.low, (u_long)e.re_vers.high);
|
||||
i = snprintf(str, len, "; low version = %u, high version = %u",
|
||||
e.re_vers.low, e.re_vers.high);
|
||||
str += i;
|
||||
len -= i;
|
||||
break;
|
||||
|
||||
case RPC_AUTHERROR:
|
||||
err = auth_errmsg(e.re_why);
|
||||
(void) sprintf(str,"; why = ");
|
||||
str += strlen(str);
|
||||
i = snprintf(str, len, "; why = ");
|
||||
str += i;
|
||||
len -= i;
|
||||
if (err != NULL) {
|
||||
(void) sprintf(str, "%s\n",err);
|
||||
i = snprintf(str, len, "%s",err);
|
||||
} else {
|
||||
(void) sprintf(str,
|
||||
"(unknown authentication error - %d)\n",
|
||||
i = snprintf(str, len,
|
||||
"(unknown authentication error - %d)",
|
||||
(int) e.re_why);
|
||||
}
|
||||
str += i;
|
||||
len -= i;
|
||||
break;
|
||||
|
||||
case RPC_PROGVERSMISMATCH:
|
||||
(void) sprintf(str,
|
||||
"; low version = %lu, high version = %lu\n",
|
||||
(u_long)e.re_vers.low, (u_long)e.re_vers.high);
|
||||
i = snprintf(str, len, "; low version = %u, high version = %u",
|
||||
e.re_vers.low, e.re_vers.high);
|
||||
str += i;
|
||||
len -= i;
|
||||
break;
|
||||
|
||||
default: /* unknown */
|
||||
(void) sprintf(str,
|
||||
"; s1 = %lu, s2 = %lu\n",
|
||||
(long)e.re_lb.s1, (long)e.re_lb.s2);
|
||||
i = snprintf(str, len, "; s1 = %u, s2 = %u",
|
||||
e.re_lb.s1, e.re_lb.s2);
|
||||
str += i;
|
||||
len -= i;
|
||||
break;
|
||||
}
|
||||
strstart[CLNT_PERROR_BUFLEN-2] = '\n';
|
||||
strstart[CLNT_PERROR_BUFLEN-1] = '\0';
|
||||
return(strstart) ;
|
||||
}
|
||||
@ -142,11 +170,14 @@ clnt_sperror(rpch, s)
|
||||
void
|
||||
clnt_perror(rpch, s)
|
||||
CLIENT *rpch;
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr,"%s\n",clnt_sperror(rpch,s));
|
||||
}
|
||||
|
||||
assert(rpch != NULL);
|
||||
assert(s != NULL);
|
||||
|
||||
(void) fprintf(stderr, "%s\n", clnt_sperror(rpch,s));
|
||||
}
|
||||
|
||||
static const char *const rpc_errlist[] = {
|
||||
"RPC: Success", /* 0 - RPC_SUCCESS */
|
||||
@ -180,6 +211,7 @@ clnt_sperrno(stat)
|
||||
unsigned int errnum = stat;
|
||||
|
||||
if (errnum < (sizeof(rpc_errlist)/sizeof(rpc_errlist[0])))
|
||||
/* LINTED interface problem */
|
||||
return (char *)rpc_errlist[errnum];
|
||||
|
||||
return ("RPC: (unknown error code)");
|
||||
@ -189,53 +221,78 @@ void
|
||||
clnt_perrno(num)
|
||||
enum clnt_stat num;
|
||||
{
|
||||
(void) fprintf(stderr,"%s\n",clnt_sperrno(num));
|
||||
(void) fprintf(stderr, "%s\n", clnt_sperrno(num));
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
clnt_spcreateerror(s)
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
char *str = _buf();
|
||||
char *str;
|
||||
size_t len, i;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
str = _buf(); /* side effect: sets CLNT_PERROR_BUFLEN */
|
||||
if (str == 0)
|
||||
return(0);
|
||||
len = CLNT_PERROR_BUFLEN;
|
||||
i = snprintf(str, len, "%s: ", s);
|
||||
len -= i;
|
||||
(void)strncat(str, clnt_sperrno(rpc_createerr.cf_stat), len - 1);
|
||||
switch (rpc_createerr.cf_stat) {
|
||||
case RPC_PMAPFAILURE:
|
||||
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
|
||||
clnt_sperrno(rpc_createerr.cf_stat),
|
||||
clnt_sperrno(rpc_createerr.cf_error.re_status));
|
||||
(void) strncat(str, " - ", len - 1);
|
||||
(void) strncat(str,
|
||||
clnt_sperrno(rpc_createerr.cf_error.re_status), len - 4);
|
||||
break;
|
||||
|
||||
case RPC_SYSTEMERROR:
|
||||
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s - %s\n", s,
|
||||
clnt_sperrno(rpc_createerr.cf_stat),
|
||||
strerror(rpc_createerr.cf_error.re_errno));
|
||||
(void)strncat(str, " - ", len - 1);
|
||||
(void)strncat(str, strerror(rpc_createerr.cf_error.re_errno),
|
||||
len - 4);
|
||||
break;
|
||||
|
||||
case RPC_CANTSEND:
|
||||
case RPC_CANTDECODERES:
|
||||
case RPC_CANTENCODEARGS:
|
||||
case RPC_SUCCESS:
|
||||
case RPC_UNKNOWNPROTO:
|
||||
case RPC_PROGNOTREGISTERED:
|
||||
case RPC_FAILED:
|
||||
case RPC_UNKNOWNHOST:
|
||||
case RPC_CANTDECODEARGS:
|
||||
case RPC_PROCUNAVAIL:
|
||||
case RPC_PROGVERSMISMATCH:
|
||||
case RPC_PROGUNAVAIL:
|
||||
case RPC_AUTHERROR:
|
||||
case RPC_VERSMISMATCH:
|
||||
case RPC_TIMEDOUT:
|
||||
case RPC_CANTRECV:
|
||||
default:
|
||||
(void) snprintf(str, CLNT_PERROR_BUFLEN, "%s: %s\n", s,
|
||||
clnt_sperrno(rpc_createerr.cf_stat));
|
||||
break;
|
||||
}
|
||||
str[CLNT_PERROR_BUFLEN-2] = '\n';
|
||||
str[CLNT_PERROR_BUFLEN-1] = '\0';
|
||||
return (str);
|
||||
}
|
||||
|
||||
void
|
||||
clnt_pcreateerror(s)
|
||||
char *s;
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr,"%s\n",clnt_spcreateerror(s));
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
(void) fprintf(stderr, "%s\n", clnt_spcreateerror(s));
|
||||
}
|
||||
|
||||
static const char *const auth_errlist[] = {
|
||||
"Authentication OK", /* 0 - AUTH_OK */
|
||||
"Invalid client credential", /* 1 - AUTH_BADCRED */
|
||||
"Server rejected credential", /* 2 - AUTH_REJECTEDCRED */
|
||||
"Invalid client verifier", /* 3 - AUTH_BADVERF */
|
||||
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
|
||||
"Invalid client verifier", /* 3 - AUTH_BADVERF */
|
||||
"Server rejected verifier", /* 4 - AUTH_REJECTEDVERF */
|
||||
"Client credential too weak", /* 5 - AUTH_TOOWEAK */
|
||||
"Invalid server verifier", /* 6 - AUTH_INVALIDRESP */
|
||||
"Failed (unspecified error)" /* 7 - AUTH_FAILED */
|
||||
@ -248,6 +305,7 @@ auth_errmsg(stat)
|
||||
unsigned int errnum = stat;
|
||||
|
||||
if (errnum < (sizeof(auth_errlist)/sizeof(auth_errlist[0])))
|
||||
/* LINTED interface problem */
|
||||
return (char *)auth_errlist[errnum];
|
||||
|
||||
return(NULL);
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: clnt_raw.c,v 1.20 2000/12/10 04:12:03 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -44,9 +47,18 @@ static char *rcsid = "$FreeBSD$";
|
||||
* any interference from the kernal.
|
||||
*/
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <stdlib.h>
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/raw.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
extern mutex_t clntraw_lock;
|
||||
|
||||
#define MCALL_MSG_SIZE 24
|
||||
|
||||
@ -56,46 +68,47 @@ static char *rcsid = "$FreeBSD$";
|
||||
static struct clntraw_private {
|
||||
CLIENT client_object;
|
||||
XDR xdr_stream;
|
||||
char _raw_buf[UDPMSGSIZE];
|
||||
char mashl_callmsg[MCALL_MSG_SIZE];
|
||||
char *_raw_buf;
|
||||
union {
|
||||
struct rpc_msg mashl_rpcmsg;
|
||||
char mashl_callmsg[MCALL_MSG_SIZE];
|
||||
} u;
|
||||
u_int mcnt;
|
||||
} *clntraw_private;
|
||||
|
||||
static enum clnt_stat clntraw_call();
|
||||
static void clntraw_abort();
|
||||
static void clntraw_geterr();
|
||||
static bool_t clntraw_freeres();
|
||||
static bool_t clntraw_control();
|
||||
static void clntraw_destroy();
|
||||
|
||||
static struct clnt_ops client_ops = {
|
||||
clntraw_call,
|
||||
clntraw_abort,
|
||||
clntraw_geterr,
|
||||
clntraw_freeres,
|
||||
clntraw_destroy,
|
||||
clntraw_control
|
||||
};
|
||||
|
||||
void svc_getreq();
|
||||
static enum clnt_stat clnt_raw_call __P((CLIENT *, rpcproc_t, xdrproc_t,
|
||||
caddr_t, xdrproc_t, caddr_t, struct timeval));
|
||||
static void clnt_raw_geterr __P((CLIENT *, struct rpc_err *));
|
||||
static bool_t clnt_raw_freeres __P((CLIENT *, xdrproc_t, caddr_t));
|
||||
static void clnt_raw_abort __P((CLIENT *));
|
||||
static bool_t clnt_raw_control __P((CLIENT *, u_int, char *));
|
||||
static void clnt_raw_destroy __P((CLIENT *));
|
||||
static struct clnt_ops *clnt_raw_ops __P((void));
|
||||
|
||||
/*
|
||||
* Create a client handle for memory based rpc.
|
||||
*/
|
||||
CLIENT *
|
||||
clntraw_create(prog, vers)
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
clnt_raw_create(prog, vers)
|
||||
rpcprog_t prog;
|
||||
rpcvers_t vers;
|
||||
{
|
||||
register struct clntraw_private *clp = clntraw_private;
|
||||
struct clntraw_private *clp = clntraw_private;
|
||||
struct rpc_msg call_msg;
|
||||
XDR *xdrs = &clp->xdr_stream;
|
||||
CLIENT *client = &clp->client_object;
|
||||
|
||||
if (clp == 0) {
|
||||
mutex_lock(&clntraw_lock);
|
||||
if (clp == NULL) {
|
||||
clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
|
||||
if (clp == 0)
|
||||
return (0);
|
||||
if (clp == NULL) {
|
||||
mutex_unlock(&clntraw_lock);
|
||||
return NULL;
|
||||
}
|
||||
if (__rpc_rawcombuf == NULL)
|
||||
__rpc_rawcombuf =
|
||||
(char *)calloc(UDPMSGSIZE, sizeof (char));
|
||||
clp->_raw_buf = __rpc_rawcombuf;
|
||||
clntraw_private = clp;
|
||||
}
|
||||
/*
|
||||
@ -103,12 +116,12 @@ clntraw_create(prog, vers)
|
||||
*/
|
||||
call_msg.rm_direction = CALL;
|
||||
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
call_msg.rm_call.cb_prog = prog;
|
||||
call_msg.rm_call.cb_vers = vers;
|
||||
xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
|
||||
if (! xdr_callhdr(xdrs, &call_msg)) {
|
||||
perror("clnt_raw.c - Fatal header serialization error.");
|
||||
}
|
||||
/* XXX: prog and vers have been long historically :-( */
|
||||
call_msg.rm_call.cb_prog = (u_int32_t)prog;
|
||||
call_msg.rm_call.cb_vers = (u_int32_t)vers;
|
||||
xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
|
||||
if (! xdr_callhdr(xdrs, &call_msg))
|
||||
warnx("clntraw_create - Fatal header serialization error.");
|
||||
clp->mcnt = XDR_GETPOS(xdrs);
|
||||
XDR_DESTROY(xdrs);
|
||||
|
||||
@ -120,38 +133,47 @@ clntraw_create(prog, vers)
|
||||
/*
|
||||
* create client handle
|
||||
*/
|
||||
client->cl_ops = &client_ops;
|
||||
client->cl_ops = clnt_raw_ops();
|
||||
client->cl_auth = authnone_create();
|
||||
mutex_unlock(&clntraw_lock);
|
||||
return (client);
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
/* ARGSUSED */
|
||||
static enum clnt_stat
|
||||
clnt_raw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
CLIENT *h;
|
||||
u_long proc;
|
||||
rpcproc_t proc;
|
||||
xdrproc_t xargs;
|
||||
caddr_t argsp;
|
||||
xdrproc_t xresults;
|
||||
caddr_t resultsp;
|
||||
struct timeval timeout;
|
||||
{
|
||||
register struct clntraw_private *clp = clntraw_private;
|
||||
register XDR *xdrs = &clp->xdr_stream;
|
||||
struct clntraw_private *clp = clntraw_private;
|
||||
XDR *xdrs = &clp->xdr_stream;
|
||||
struct rpc_msg msg;
|
||||
enum clnt_stat status;
|
||||
struct rpc_err error;
|
||||
|
||||
if (clp == 0)
|
||||
assert(h != NULL);
|
||||
|
||||
mutex_lock(&clntraw_lock);
|
||||
if (clp == NULL) {
|
||||
mutex_unlock(&clntraw_lock);
|
||||
return (RPC_FAILED);
|
||||
}
|
||||
mutex_unlock(&clntraw_lock);
|
||||
|
||||
call_again:
|
||||
/*
|
||||
* send request
|
||||
*/
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
XDR_SETPOS(xdrs, 0);
|
||||
((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
|
||||
if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
|
||||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
|
||||
clp->u.mashl_rpcmsg.rm_xid ++ ;
|
||||
if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
|
||||
(! XDR_PUTINT32(xdrs, &proc)) ||
|
||||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
|
||||
(! (*xargs)(xdrs, argsp))) {
|
||||
return (RPC_CANTENCODEARGS);
|
||||
@ -162,7 +184,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
* We have to call server input routine here because this is
|
||||
* all going on in one process. Yuk.
|
||||
*/
|
||||
svc_getreq(1);
|
||||
svc_getreq_common(FD_SETSIZE);
|
||||
|
||||
/*
|
||||
* get results
|
||||
@ -172,8 +194,23 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
msg.acpted_rply.ar_verf = _null_auth;
|
||||
msg.acpted_rply.ar_results.where = resultsp;
|
||||
msg.acpted_rply.ar_results.proc = xresults;
|
||||
if (! xdr_replymsg(xdrs, &msg))
|
||||
if (! xdr_replymsg(xdrs, &msg)) {
|
||||
/*
|
||||
* It's possible for xdr_replymsg() to fail partway
|
||||
* through its attempt to decode the result from the
|
||||
* server. If this happens, it will leave the reply
|
||||
* structure partially populated with dynamically
|
||||
* allocated memory. (This can happen if someone uses
|
||||
* clntudp_bufcreate() to create a CLIENT handle and
|
||||
* specifies a receive buffer size that is too small.)
|
||||
* This memory must be free()ed to avoid a leak.
|
||||
*/
|
||||
int op = xdrs->x_op;
|
||||
xdrs->x_op = XDR_FREE;
|
||||
xdr_replymsg(xdrs, &msg);
|
||||
xdrs->x_op = op;
|
||||
return (RPC_CANTDECODERES);
|
||||
}
|
||||
_seterr_reply(&msg, &error);
|
||||
status = error.re_status;
|
||||
|
||||
@ -183,7 +220,7 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
}
|
||||
} /* end successful completion */
|
||||
else {
|
||||
if (AUTH_REFRESH(h->cl_auth))
|
||||
if (AUTH_REFRESH(h->cl_auth, &msg))
|
||||
goto call_again;
|
||||
} /* end of unsuccessful completion */
|
||||
|
||||
@ -200,43 +237,78 @@ clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
clntraw_geterr()
|
||||
clnt_raw_geterr(cl, err)
|
||||
CLIENT *cl;
|
||||
struct rpc_err *err;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
static bool_t
|
||||
clntraw_freeres(cl, xdr_res, res_ptr)
|
||||
clnt_raw_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
register struct clntraw_private *clp = clntraw_private;
|
||||
register XDR *xdrs = &clp->xdr_stream;
|
||||
struct clntraw_private *clp = clntraw_private;
|
||||
XDR *xdrs = &clp->xdr_stream;
|
||||
bool_t rval;
|
||||
|
||||
if (clp == 0)
|
||||
{
|
||||
mutex_lock(&clntraw_lock);
|
||||
if (clp == NULL) {
|
||||
rval = (bool_t) RPC_FAILED;
|
||||
mutex_unlock(&clntraw_lock);
|
||||
return (rval);
|
||||
}
|
||||
mutex_unlock(&clntraw_lock);
|
||||
xdrs->x_op = XDR_FREE;
|
||||
return ((*xdr_res)(xdrs, res_ptr));
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
clntraw_abort()
|
||||
clnt_raw_abort(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static bool_t
|
||||
clntraw_control()
|
||||
clnt_raw_control(cl, ui, str)
|
||||
CLIENT *cl;
|
||||
u_int ui;
|
||||
char *str;
|
||||
{
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
clntraw_destroy()
|
||||
clnt_raw_destroy(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
}
|
||||
|
||||
static struct clnt_ops *
|
||||
clnt_raw_ops()
|
||||
{
|
||||
static struct clnt_ops ops;
|
||||
extern mutex_t ops_lock;
|
||||
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
mutex_lock(&ops_lock);
|
||||
if (ops.cl_call == NULL) {
|
||||
ops.cl_call = clnt_raw_call;
|
||||
ops.cl_abort = clnt_raw_abort;
|
||||
ops.cl_geterr = clnt_raw_geterr;
|
||||
ops.cl_freeres = clnt_raw_freeres;
|
||||
ops.cl_destroy = clnt_raw_destroy;
|
||||
ops.cl_control = clnt_raw_control;
|
||||
}
|
||||
mutex_unlock(&ops_lock);
|
||||
return (&ops);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: clnt_simple.c,v 1.21 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -26,6 +28,9 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
@ -35,90 +40,156 @@ static char *rcsid = "$FreeBSD$";
|
||||
|
||||
/*
|
||||
* clnt_simple.c
|
||||
* Simplified front end to rpc.
|
||||
* Simplified front end to client rpc.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static struct callrpc_private {
|
||||
CLIENT *client;
|
||||
int socket;
|
||||
int oldprognum, oldversnum, valid;
|
||||
char *oldhost;
|
||||
} *callrpc_private;
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
int
|
||||
callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
|
||||
char *host;
|
||||
int prognum, versnum, procnum;
|
||||
xdrproc_t inproc, outproc;
|
||||
char *in, *out;
|
||||
#ifndef NETIDLEN
|
||||
#define NETIDLEN 32
|
||||
#endif
|
||||
|
||||
struct rpc_call_private {
|
||||
int valid; /* Is this entry valid ? */
|
||||
CLIENT *client; /* Client handle */
|
||||
pid_t pid; /* process-id at moment of creation */
|
||||
rpcprog_t prognum; /* Program */
|
||||
rpcvers_t versnum; /* Version */
|
||||
char host[MAXHOSTNAMELEN]; /* Servers host */
|
||||
char nettype[NETIDLEN]; /* Network type */
|
||||
};
|
||||
static struct rpc_call_private *rpc_call_private_main;
|
||||
|
||||
static void rpc_call_destroy __P((void *));
|
||||
|
||||
static void
|
||||
rpc_call_destroy(void *vp)
|
||||
{
|
||||
register struct callrpc_private *crp = callrpc_private;
|
||||
struct sockaddr_in server_addr;
|
||||
enum clnt_stat clnt_stat;
|
||||
struct hostent *hp;
|
||||
struct timeval timeout, tottimeout;
|
||||
struct rpc_call_private *rcp = (struct rpc_call_private *)vp;
|
||||
|
||||
if (crp == 0) {
|
||||
crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
|
||||
if (crp == 0)
|
||||
return (0);
|
||||
callrpc_private = crp;
|
||||
if (rcp) {
|
||||
if (rcp->client)
|
||||
CLNT_DESTROY(rcp->client);
|
||||
free(rcp);
|
||||
}
|
||||
if (crp->oldhost == NULL) {
|
||||
crp->oldhost = malloc(MAXHOSTNAMELEN);
|
||||
crp->oldhost[0] = 0;
|
||||
crp->socket = RPC_ANYSOCK;
|
||||
}
|
||||
if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
|
||||
&& strcmp(crp->oldhost, host) == 0) {
|
||||
/* reuse old client */
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the simplified interface to the client rpc layer.
|
||||
* The client handle is not destroyed here and is reused for
|
||||
* the future calls to same prog, vers, host and nettype combination.
|
||||
*
|
||||
* The total time available is 25 seconds.
|
||||
*/
|
||||
enum clnt_stat
|
||||
rpc_call(host, prognum, versnum, procnum, inproc, in, outproc, out, nettype)
|
||||
const char *host; /* host name */
|
||||
rpcprog_t prognum; /* program number */
|
||||
rpcvers_t versnum; /* version number */
|
||||
rpcproc_t procnum; /* procedure number */
|
||||
xdrproc_t inproc, outproc; /* in/out XDR procedures */
|
||||
const char *in;
|
||||
char *out; /* recv/send data */
|
||||
const char *nettype; /* nettype */
|
||||
{
|
||||
struct rpc_call_private *rcp = (struct rpc_call_private *) 0;
|
||||
enum clnt_stat clnt_stat;
|
||||
struct timeval timeout, tottimeout;
|
||||
static thread_key_t rpc_call_key;
|
||||
extern mutex_t tsd_lock;
|
||||
int main_thread = 1;
|
||||
|
||||
if ((main_thread = thr_main())) {
|
||||
rcp = rpc_call_private_main;
|
||||
} else {
|
||||
crp->valid = 0;
|
||||
if (crp->socket != -1)
|
||||
(void)_close(crp->socket);
|
||||
crp->socket = RPC_ANYSOCK;
|
||||
if (crp->client) {
|
||||
clnt_destroy(crp->client);
|
||||
crp->client = NULL;
|
||||
if (rpc_call_key == 0) {
|
||||
mutex_lock(&tsd_lock);
|
||||
if (rpc_call_key == 0)
|
||||
thr_keycreate(&rpc_call_key, rpc_call_destroy);
|
||||
mutex_unlock(&tsd_lock);
|
||||
}
|
||||
if ((hp = gethostbyname(host)) == NULL)
|
||||
return ((int) RPC_UNKNOWNHOST);
|
||||
rcp = (struct rpc_call_private *)thr_getspecific(rpc_call_key);
|
||||
}
|
||||
if (rcp == NULL) {
|
||||
rcp = malloc(sizeof (*rcp));
|
||||
if (rcp == NULL) {
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
return (rpc_createerr.cf_stat);
|
||||
}
|
||||
if (main_thread)
|
||||
rpc_call_private_main = rcp;
|
||||
else
|
||||
thr_setspecific(rpc_call_key, (void *) rcp);
|
||||
rcp->valid = 0;
|
||||
rcp->client = NULL;
|
||||
}
|
||||
if ((nettype == NULL) || (nettype[0] == NULL))
|
||||
nettype = "netpath";
|
||||
if (!(rcp->valid && rcp->pid == getpid() &&
|
||||
(rcp->prognum == prognum) &&
|
||||
(rcp->versnum == versnum) &&
|
||||
(!strcmp(rcp->host, host)) &&
|
||||
(!strcmp(rcp->nettype, nettype)))) {
|
||||
int fd;
|
||||
|
||||
rcp->valid = 0;
|
||||
if (rcp->client)
|
||||
CLNT_DESTROY(rcp->client);
|
||||
/*
|
||||
* Using the first successful transport for that type
|
||||
*/
|
||||
rcp->client = clnt_create(host, prognum, versnum, nettype);
|
||||
rcp->pid = getpid();
|
||||
if (rcp->client == NULL) {
|
||||
return (rpc_createerr.cf_stat);
|
||||
}
|
||||
/*
|
||||
* Set time outs for connectionless case. Do it
|
||||
* unconditionally. Faster than doing a t_getinfo()
|
||||
* and then doing the right thing.
|
||||
*/
|
||||
timeout.tv_usec = 0;
|
||||
timeout.tv_sec = 5;
|
||||
memset(&server_addr, 0, sizeof(server_addr));
|
||||
memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
|
||||
server_addr.sin_len = sizeof(struct sockaddr_in);
|
||||
server_addr.sin_family = AF_INET;
|
||||
server_addr.sin_port = 0;
|
||||
if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
|
||||
(u_long)versnum, timeout, &crp->socket)) == NULL)
|
||||
return ((int) rpc_createerr.cf_stat);
|
||||
crp->valid = 1;
|
||||
crp->oldprognum = prognum;
|
||||
crp->oldversnum = versnum;
|
||||
(void) strcpy(crp->oldhost, host);
|
||||
}
|
||||
(void) CLNT_CONTROL(rcp->client,
|
||||
CLSET_RETRY_TIMEOUT, (char *)(void *)&timeout);
|
||||
if (CLNT_CONTROL(rcp->client, CLGET_FD, (char *)(void *)&fd))
|
||||
_fcntl(fd, F_SETFD, 1); /* make it "close on exec" */
|
||||
rcp->prognum = prognum;
|
||||
rcp->versnum = versnum;
|
||||
if ((strlen(host) < (size_t)MAXHOSTNAMELEN) &&
|
||||
(strlen(nettype) < (size_t)NETIDLEN)) {
|
||||
(void) strcpy(rcp->host, host);
|
||||
(void) strcpy(rcp->nettype, nettype);
|
||||
rcp->valid = 1;
|
||||
} else {
|
||||
rcp->valid = 0;
|
||||
}
|
||||
} /* else reuse old client */
|
||||
tottimeout.tv_sec = 25;
|
||||
tottimeout.tv_usec = 0;
|
||||
clnt_stat = clnt_call(crp->client, procnum, inproc, in,
|
||||
/*LINTED const castaway*/
|
||||
clnt_stat = CLNT_CALL(rcp->client, procnum, inproc, (char *) in,
|
||||
outproc, out, tottimeout);
|
||||
/*
|
||||
* if call failed, empty cache
|
||||
*/
|
||||
if (clnt_stat != RPC_SUCCESS)
|
||||
crp->valid = 0;
|
||||
return ((int) clnt_stat);
|
||||
rcp->valid = 0;
|
||||
return (clnt_stat);
|
||||
}
|
||||
|
@ -1,582 +0,0 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* TCP based RPC supports 'batched calls'.
|
||||
* A sequence of calls may be batched-up in a send buffer. The rpc call
|
||||
* return immediately to the client even though the call was not necessarily
|
||||
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
|
||||
* the rpc timeout value is zero (see clnt.h, rpc).
|
||||
*
|
||||
* Clients should NOT casually batch calls that in fact return results; that is,
|
||||
* the server side should be aware that a call is batched and not produce any
|
||||
* return message. Batched calls that produce many result messages can
|
||||
* deadlock (netlock) the client and the server....
|
||||
*
|
||||
* Now go hang yourself.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define MCALL_MSG_SIZE 24
|
||||
|
||||
static int readtcp();
|
||||
static int writetcp();
|
||||
|
||||
static enum clnt_stat clnttcp_call();
|
||||
static void clnttcp_abort();
|
||||
static void clnttcp_geterr();
|
||||
static bool_t clnttcp_freeres();
|
||||
static bool_t clnttcp_control();
|
||||
static void clnttcp_destroy();
|
||||
|
||||
static struct clnt_ops tcp_ops = {
|
||||
clnttcp_call,
|
||||
clnttcp_abort,
|
||||
clnttcp_geterr,
|
||||
clnttcp_freeres,
|
||||
clnttcp_destroy,
|
||||
clnttcp_control
|
||||
};
|
||||
|
||||
struct ct_data {
|
||||
int ct_sock;
|
||||
bool_t ct_closeit;
|
||||
struct timeval ct_wait;
|
||||
bool_t ct_waitset; /* wait set by clnt_control? */
|
||||
struct sockaddr_in ct_addr;
|
||||
struct rpc_err ct_error;
|
||||
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
|
||||
u_int ct_mpos; /* pos after marshal */
|
||||
XDR ct_xdrs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a client handle for a tcp/ip connection.
|
||||
* If *sockp<0, *sockp is set to a newly created TCP socket and it is
|
||||
* connected to raddr. If *sockp non-negative then
|
||||
* raddr is ignored. The rpc/tcp package does buffering
|
||||
* similar to stdio, so the client must pick send and receive buffer sizes,];
|
||||
* 0 => use the default.
|
||||
* If raddr->sin_port is 0, then a binder on the remote machine is
|
||||
* consulted for the right port number.
|
||||
* NB: *sockp is copied into a private area.
|
||||
* NB: It is the clients responsibility to close *sockp.
|
||||
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
|
||||
* something more useful.
|
||||
*/
|
||||
CLIENT *
|
||||
clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
|
||||
struct sockaddr_in *raddr;
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
register int *sockp;
|
||||
u_int sendsz;
|
||||
u_int recvsz;
|
||||
{
|
||||
CLIENT *h;
|
||||
register struct ct_data *ct = NULL;
|
||||
struct timeval now;
|
||||
struct rpc_msg call_msg;
|
||||
static u_int32_t disrupt;
|
||||
|
||||
if (disrupt == 0)
|
||||
disrupt = (u_int32_t)(long)raddr;
|
||||
|
||||
h = (CLIENT *)mem_alloc(sizeof(*h));
|
||||
if (h == NULL) {
|
||||
(void)fprintf(stderr, "clnttcp_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
ct = (struct ct_data *)mem_alloc(sizeof(*ct));
|
||||
if (ct == NULL) {
|
||||
(void)fprintf(stderr, "clnttcp_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no port number given ask the pmap for one
|
||||
*/
|
||||
if (raddr->sin_port == 0) {
|
||||
u_short port;
|
||||
if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
|
||||
mem_free((caddr_t)ct, sizeof(struct ct_data));
|
||||
mem_free((caddr_t)h, sizeof(CLIENT));
|
||||
return ((CLIENT *)NULL);
|
||||
}
|
||||
raddr->sin_port = htons(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* If no socket given, open one
|
||||
*/
|
||||
if (*sockp < 0) {
|
||||
*sockp = _socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
(void)bindresvport(*sockp, (struct sockaddr_in *)0);
|
||||
if ((*sockp < 0)
|
||||
|| (_connect(*sockp, (struct sockaddr *)raddr,
|
||||
sizeof(*raddr)) < 0)) {
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
if (*sockp != -1)
|
||||
(void)_close(*sockp);
|
||||
goto fooy;
|
||||
}
|
||||
ct->ct_closeit = TRUE;
|
||||
} else {
|
||||
ct->ct_closeit = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up private data struct
|
||||
*/
|
||||
ct->ct_sock = *sockp;
|
||||
ct->ct_wait.tv_usec = 0;
|
||||
ct->ct_waitset = FALSE;
|
||||
ct->ct_addr = *raddr;
|
||||
|
||||
/*
|
||||
* Initialize call message
|
||||
*/
|
||||
(void)gettimeofday(&now, (struct timezone *)0);
|
||||
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
|
||||
call_msg.rm_direction = CALL;
|
||||
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
call_msg.rm_call.cb_prog = prog;
|
||||
call_msg.rm_call.cb_vers = vers;
|
||||
|
||||
/*
|
||||
* pre-serialize the static part of the call msg and stash it away
|
||||
*/
|
||||
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
|
||||
XDR_ENCODE);
|
||||
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
|
||||
if (ct->ct_closeit) {
|
||||
(void)_close(*sockp);
|
||||
}
|
||||
goto fooy;
|
||||
}
|
||||
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
|
||||
/*
|
||||
* Create a client handle which uses xdrrec for serialization
|
||||
* and authnone for authentication.
|
||||
*/
|
||||
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
|
||||
(caddr_t)ct, readtcp, writetcp);
|
||||
h->cl_ops = &tcp_ops;
|
||||
h->cl_private = (caddr_t) ct;
|
||||
h->cl_auth = authnone_create();
|
||||
return (h);
|
||||
|
||||
fooy:
|
||||
/*
|
||||
* Something goofed, free stuff and barf
|
||||
*/
|
||||
if (ct)
|
||||
mem_free((caddr_t)ct, sizeof(struct ct_data));
|
||||
if (h)
|
||||
mem_free((caddr_t)h, sizeof(CLIENT));
|
||||
return ((CLIENT *)NULL);
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
|
||||
register CLIENT *h;
|
||||
u_long proc;
|
||||
xdrproc_t xdr_args;
|
||||
caddr_t args_ptr;
|
||||
xdrproc_t xdr_results;
|
||||
caddr_t results_ptr;
|
||||
struct timeval timeout;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *) h->cl_private;
|
||||
register XDR *xdrs = &(ct->ct_xdrs);
|
||||
struct rpc_msg reply_msg;
|
||||
u_long x_id;
|
||||
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
|
||||
register bool_t shipnow;
|
||||
int refreshes = 2;
|
||||
|
||||
if (!ct->ct_waitset) {
|
||||
ct->ct_wait = timeout;
|
||||
}
|
||||
|
||||
shipnow =
|
||||
(xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
|
||||
&& timeout.tv_usec == 0) ? FALSE : TRUE;
|
||||
|
||||
call_again:
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
ct->ct_error.re_status = RPC_SUCCESS;
|
||||
x_id = ntohl(--(*msg_x_id));
|
||||
if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
|
||||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
|
||||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
|
||||
(! (*xdr_args)(xdrs, args_ptr))) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTENCODEARGS;
|
||||
(void)xdrrec_endofrecord(xdrs, TRUE);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (! xdrrec_endofrecord(xdrs, shipnow))
|
||||
return (ct->ct_error.re_status = RPC_CANTSEND);
|
||||
if (! shipnow)
|
||||
return (RPC_SUCCESS);
|
||||
/*
|
||||
* Hack to provide rpc-based message passing
|
||||
*/
|
||||
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||
return(ct->ct_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keep receiving until we get a valid transaction id
|
||||
*/
|
||||
xdrs->x_op = XDR_DECODE;
|
||||
while (TRUE) {
|
||||
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||
reply_msg.acpted_rply.ar_results.where = NULL;
|
||||
reply_msg.acpted_rply.ar_results.proc = xdr_void;
|
||||
if (! xdrrec_skiprecord(xdrs))
|
||||
return (ct->ct_error.re_status);
|
||||
/* now decode and validate the response header */
|
||||
if (! xdr_replymsg(xdrs, &reply_msg)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
continue;
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (reply_msg.rm_xid == x_id)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* process header
|
||||
*/
|
||||
_seterr_reply(&reply_msg, &(ct->ct_error));
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
||||
if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
|
||||
ct->ct_error.re_status = RPC_AUTHERROR;
|
||||
ct->ct_error.re_why = AUTH_INVALIDRESP;
|
||||
} else if (! (*xdr_results)(xdrs, results_ptr)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTDECODERES;
|
||||
}
|
||||
/* free verifier ... */
|
||||
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||
xdrs->x_op = XDR_FREE;
|
||||
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
|
||||
}
|
||||
} /* end successful completion */
|
||||
else {
|
||||
/* maybe our credentials need to be refreshed ... */
|
||||
if (refreshes-- && AUTH_REFRESH(h->cl_auth))
|
||||
goto call_again;
|
||||
} /* end of unsuccessful completion */
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
|
||||
static void
|
||||
clnttcp_geterr(h, errp)
|
||||
CLIENT *h;
|
||||
struct rpc_err *errp;
|
||||
{
|
||||
register struct ct_data *ct =
|
||||
(struct ct_data *) h->cl_private;
|
||||
|
||||
*errp = ct->ct_error;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clnttcp_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
|
||||
register XDR *xdrs = &(ct->ct_xdrs);
|
||||
|
||||
xdrs->x_op = XDR_FREE;
|
||||
return ((*xdr_res)(xdrs, res_ptr));
|
||||
}
|
||||
|
||||
static void
|
||||
clnttcp_abort()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static bool_t
|
||||
clnttcp_control(cl, request, info)
|
||||
CLIENT *cl;
|
||||
int request;
|
||||
char *info;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
|
||||
register struct timeval *tv;
|
||||
int len;
|
||||
|
||||
switch (request) {
|
||||
case CLSET_FD_CLOSE:
|
||||
ct->ct_closeit = TRUE;
|
||||
break;
|
||||
case CLSET_FD_NCLOSE:
|
||||
ct->ct_closeit = FALSE;
|
||||
break;
|
||||
case CLSET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
tv = (struct timeval *)info;
|
||||
ct->ct_wait.tv_sec = tv->tv_sec;
|
||||
ct->ct_wait.tv_usec = tv->tv_usec;
|
||||
ct->ct_waitset = TRUE;
|
||||
break;
|
||||
case CLGET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct timeval *)info = ct->ct_wait;
|
||||
break;
|
||||
case CLGET_SERVER_ADDR:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct sockaddr_in *)info = ct->ct_addr;
|
||||
break;
|
||||
case CLGET_FD:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(int *)info = ct->ct_sock;
|
||||
break;
|
||||
case CLGET_XID:
|
||||
/*
|
||||
* use the knowledge that xid is the
|
||||
* first element in the call structure *.
|
||||
* This will get the xid of the PREVIOUS call
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
|
||||
break;
|
||||
case CLSET_XID:
|
||||
/* This will set the xid of the NEXT call */
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
|
||||
/* decrement by 1 as clnttcp_call() increments once */
|
||||
case CLGET_VERS:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the version number field is the fifth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
|
||||
4 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_VERS:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_PROG:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the program number field is the field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
|
||||
3 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_PROG:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_LOCAL_ADDR:
|
||||
len = sizeof(struct sockaddr);
|
||||
if (_getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
|
||||
return(FALSE);
|
||||
break;
|
||||
case CLGET_RETRY_TIMEOUT:
|
||||
case CLSET_RETRY_TIMEOUT:
|
||||
case CLGET_SVC_ADDR:
|
||||
case CLSET_SVC_ADDR:
|
||||
case CLSET_PUSH_TIMOD:
|
||||
case CLSET_POP_TIMOD:
|
||||
default:
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clnttcp_destroy(h)
|
||||
CLIENT *h;
|
||||
{
|
||||
register struct ct_data *ct =
|
||||
(struct ct_data *) h->cl_private;
|
||||
|
||||
if (ct->ct_closeit) {
|
||||
(void)_close(ct->ct_sock);
|
||||
}
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
mem_free((caddr_t)ct, sizeof(struct ct_data));
|
||||
mem_free((caddr_t)h, sizeof(CLIENT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface between xdr serializer and tcp connection.
|
||||
* Behaves like the system calls, read & write, but keeps some error state
|
||||
* around for the rpc level.
|
||||
*/
|
||||
static int
|
||||
readtcp(ct, buf, len)
|
||||
register struct ct_data *ct;
|
||||
caddr_t buf;
|
||||
register int len;
|
||||
{
|
||||
fd_set *fds, readfds;
|
||||
struct timeval start, after, duration, delta, tmp, tv;
|
||||
int r, save_errno;
|
||||
|
||||
if (len == 0)
|
||||
return (0);
|
||||
|
||||
if (ct->ct_sock + 1 > FD_SETSIZE) {
|
||||
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fds = (fd_set *)malloc(bytes);
|
||||
if (fds == NULL)
|
||||
return (-1);
|
||||
memset(fds, 0, bytes);
|
||||
} else {
|
||||
fds = &readfds;
|
||||
FD_ZERO(fds);
|
||||
}
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
delta = ct->ct_wait;
|
||||
while (TRUE) {
|
||||
/* XXX we know the other bits are still clear */
|
||||
FD_SET(ct->ct_sock, fds);
|
||||
tv = delta; /* in case select writes back */
|
||||
r = _select(ct->ct_sock+1, fds, NULL, NULL, &tv);
|
||||
save_errno = errno;
|
||||
|
||||
gettimeofday(&after, NULL);
|
||||
timersub(&start, &after, &duration);
|
||||
timersub(&ct->ct_wait, &duration, &tmp);
|
||||
delta = tmp;
|
||||
if (delta.tv_sec < 0 || !timerisset(&delta))
|
||||
r = 0;
|
||||
|
||||
switch (r) {
|
||||
case 0:
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||
return (-1);
|
||||
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
ct->ct_error.re_errno = save_errno;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (len = _read(ct->ct_sock, buf, len)) {
|
||||
|
||||
case 0:
|
||||
/* premature eof */
|
||||
ct->ct_error.re_errno = ECONNRESET;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
len = -1; /* it's really an error */
|
||||
break;
|
||||
|
||||
case -1:
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
break;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static int
|
||||
writetcp(ct, buf, len)
|
||||
struct ct_data *ct;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
{
|
||||
register int i, cnt;
|
||||
|
||||
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
|
||||
if ((i = _write(ct->ct_sock, buf, cnt)) == -1) {
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTSEND;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (len);
|
||||
}
|
@ -1,569 +0,0 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clnt_udp.c, Implements a UDP/IP based, client side RPC.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* UDP bases client side rpc operations
|
||||
*/
|
||||
static enum clnt_stat clntudp_call();
|
||||
static void clntudp_abort();
|
||||
static void clntudp_geterr();
|
||||
static bool_t clntudp_freeres();
|
||||
static bool_t clntudp_control();
|
||||
static void clntudp_destroy();
|
||||
|
||||
static struct clnt_ops udp_ops = {
|
||||
clntudp_call,
|
||||
clntudp_abort,
|
||||
clntudp_geterr,
|
||||
clntudp_freeres,
|
||||
clntudp_destroy,
|
||||
clntudp_control
|
||||
};
|
||||
|
||||
/*
|
||||
* Private data kept per client handle
|
||||
*/
|
||||
struct cu_data {
|
||||
int cu_sock;
|
||||
bool_t cu_closeit;
|
||||
struct sockaddr_in cu_raddr;
|
||||
int cu_rlen;
|
||||
struct timeval cu_wait;
|
||||
struct timeval cu_total;
|
||||
struct rpc_err cu_error;
|
||||
XDR cu_outxdrs;
|
||||
u_int cu_xdrpos;
|
||||
u_int cu_sendsz;
|
||||
char *cu_outbuf;
|
||||
u_int cu_recvsz;
|
||||
char cu_inbuf[1];
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a UDP based client handle.
|
||||
* If *sockp<0, *sockp is set to a newly created UPD socket.
|
||||
* If raddr->sin_port is 0 a binder on the remote machine
|
||||
* is consulted for the correct port number.
|
||||
* NB: It is the clients responsibility to close *sockp.
|
||||
* NB: The rpch->cl_auth is initialized to null authentication.
|
||||
* Caller may wish to set this something more useful.
|
||||
*
|
||||
* wait is the amount of time used between retransmitting a call if
|
||||
* no response has been heard; retransmition occurs until the actual
|
||||
* rpc call times out.
|
||||
*
|
||||
* sendsz and recvsz are the maximum allowable packet sizes that can be
|
||||
* sent and received.
|
||||
*/
|
||||
CLIENT *
|
||||
clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
|
||||
struct sockaddr_in *raddr;
|
||||
u_long program;
|
||||
u_long version;
|
||||
struct timeval wait;
|
||||
register int *sockp;
|
||||
u_int sendsz;
|
||||
u_int recvsz;
|
||||
{
|
||||
CLIENT *cl;
|
||||
register struct cu_data *cu = NULL;
|
||||
struct timeval now;
|
||||
struct rpc_msg call_msg;
|
||||
static u_int32_t disrupt;
|
||||
|
||||
if (disrupt == 0)
|
||||
disrupt = (u_int32_t)(long)raddr;
|
||||
|
||||
cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
|
||||
if (cl == NULL) {
|
||||
(void) fprintf(stderr, "clntudp_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
sendsz = ((sendsz + 3) / 4) * 4;
|
||||
recvsz = ((recvsz + 3) / 4) * 4;
|
||||
cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
|
||||
if (cu == NULL) {
|
||||
(void) fprintf(stderr, "clntudp_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
cu->cu_outbuf = &cu->cu_inbuf[recvsz];
|
||||
|
||||
(void)gettimeofday(&now, (struct timezone *)0);
|
||||
if (raddr->sin_port == 0) {
|
||||
u_short port;
|
||||
if ((port =
|
||||
pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
|
||||
goto fooy;
|
||||
}
|
||||
raddr->sin_port = htons(port);
|
||||
}
|
||||
cl->cl_ops = &udp_ops;
|
||||
cl->cl_private = (caddr_t)cu;
|
||||
cu->cu_raddr = *raddr;
|
||||
cu->cu_rlen = sizeof (cu->cu_raddr);
|
||||
cu->cu_wait = wait;
|
||||
cu->cu_total.tv_sec = -1;
|
||||
cu->cu_total.tv_usec = -1;
|
||||
cu->cu_sendsz = sendsz;
|
||||
cu->cu_recvsz = recvsz;
|
||||
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
|
||||
call_msg.rm_direction = CALL;
|
||||
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
call_msg.rm_call.cb_prog = program;
|
||||
call_msg.rm_call.cb_vers = version;
|
||||
xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
|
||||
sendsz, XDR_ENCODE);
|
||||
if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
|
||||
goto fooy;
|
||||
}
|
||||
cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
|
||||
if (*sockp < 0) {
|
||||
int dontblock = 1;
|
||||
|
||||
*sockp = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (*sockp < 0) {
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
/* attempt to bind to priv port */
|
||||
(void)bindresvport(*sockp, (struct sockaddr_in *)0);
|
||||
/* the sockets rpc controls are non-blocking */
|
||||
(void)_ioctl(*sockp, FIONBIO, (char *) &dontblock);
|
||||
cu->cu_closeit = TRUE;
|
||||
} else {
|
||||
cu->cu_closeit = FALSE;
|
||||
}
|
||||
cu->cu_sock = *sockp;
|
||||
cl->cl_auth = authnone_create();
|
||||
return (cl);
|
||||
fooy:
|
||||
if (cu)
|
||||
mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
|
||||
if (cl)
|
||||
mem_free((caddr_t)cl, sizeof(CLIENT));
|
||||
return ((CLIENT *)NULL);
|
||||
}
|
||||
|
||||
CLIENT *
|
||||
clntudp_create(raddr, program, version, wait, sockp)
|
||||
struct sockaddr_in *raddr;
|
||||
u_long program;
|
||||
u_long version;
|
||||
struct timeval wait;
|
||||
register int *sockp;
|
||||
{
|
||||
|
||||
return(clntudp_bufcreate(raddr, program, version, wait, sockp,
|
||||
UDPMSGSIZE, UDPMSGSIZE));
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
|
||||
register CLIENT *cl; /* client handle */
|
||||
u_long proc; /* procedure number */
|
||||
xdrproc_t xargs; /* xdr routine for args */
|
||||
caddr_t argsp; /* pointer to args */
|
||||
xdrproc_t xresults; /* xdr routine for results */
|
||||
caddr_t resultsp; /* pointer to results */
|
||||
struct timeval utimeout; /* seconds to wait before giving up */
|
||||
{
|
||||
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
register XDR *xdrs;
|
||||
register int outlen;
|
||||
register int inlen;
|
||||
int fromlen;
|
||||
fd_set *fds, readfds;
|
||||
struct sockaddr_in from;
|
||||
struct rpc_msg reply_msg;
|
||||
XDR reply_xdrs;
|
||||
struct timeval time_waited, start, after, tmp1, tmp2, tv;
|
||||
bool_t ok;
|
||||
int nrefreshes = 2; /* number of times to refresh cred */
|
||||
struct timeval timeout;
|
||||
|
||||
if (cu->cu_total.tv_usec == -1)
|
||||
timeout = utimeout; /* use supplied timeout */
|
||||
else
|
||||
timeout = cu->cu_total; /* use default timeout */
|
||||
|
||||
if (cu->cu_sock + 1 > FD_SETSIZE) {
|
||||
int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fds = (fd_set *)malloc(bytes);
|
||||
if (fds == NULL)
|
||||
return (cu->cu_error.re_status = RPC_CANTSEND);
|
||||
memset(fds, 0, bytes);
|
||||
} else {
|
||||
fds = &readfds;
|
||||
FD_ZERO(fds);
|
||||
}
|
||||
|
||||
timerclear(&time_waited);
|
||||
|
||||
call_again:
|
||||
xdrs = &(cu->cu_outxdrs);
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
XDR_SETPOS(xdrs, cu->cu_xdrpos);
|
||||
/*
|
||||
* the transaction is the first thing in the out buffer
|
||||
*/
|
||||
(*(u_short *)(cu->cu_outbuf))++;
|
||||
if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
|
||||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
|
||||
(! (*xargs)(xdrs, argsp))) {
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
|
||||
}
|
||||
outlen = (int)XDR_GETPOS(xdrs);
|
||||
|
||||
send_again:
|
||||
if (_sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
|
||||
(struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {
|
||||
cu->cu_error.re_errno = errno;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_CANTSEND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hack to provide rpc-based message passing
|
||||
*/
|
||||
if (!timerisset(&timeout)) {
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
/*
|
||||
* sub-optimal code appears here because we have
|
||||
* some clock time to spare while the packets are in flight.
|
||||
* (We assume that this is actually only executed once.)
|
||||
*/
|
||||
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||
reply_msg.acpted_rply.ar_results.where = resultsp;
|
||||
reply_msg.acpted_rply.ar_results.proc = xresults;
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
for (;;) {
|
||||
/* XXX we know the other bits are still clear */
|
||||
FD_SET(cu->cu_sock, fds);
|
||||
tv = cu->cu_wait;
|
||||
switch (_select(cu->cu_sock+1, fds, NULL, NULL, &tv)) {
|
||||
|
||||
case 0:
|
||||
timeradd(&time_waited, &cu->cu_wait, &tmp1);
|
||||
time_waited = tmp1;
|
||||
if (timercmp(&time_waited, &timeout, <))
|
||||
goto send_again;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
|
||||
case -1:
|
||||
if (errno == EINTR) {
|
||||
gettimeofday(&after, NULL);
|
||||
timersub(&after, &start, &tmp1);
|
||||
timeradd(&time_waited, &tmp1, &tmp2);
|
||||
time_waited = tmp2;
|
||||
if (timercmp(&time_waited, &timeout, <))
|
||||
continue;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
cu->cu_error.re_errno = errno;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||
}
|
||||
|
||||
do {
|
||||
fromlen = sizeof(struct sockaddr);
|
||||
inlen = _recvfrom(cu->cu_sock, cu->cu_inbuf,
|
||||
(int) cu->cu_recvsz, 0,
|
||||
(struct sockaddr *)&from, &fromlen);
|
||||
} while (inlen < 0 && errno == EINTR);
|
||||
if (inlen < 0) {
|
||||
if (errno == EWOULDBLOCK)
|
||||
continue;
|
||||
cu->cu_error.re_errno = errno;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status = RPC_CANTRECV);
|
||||
}
|
||||
if (inlen < sizeof(u_int32_t))
|
||||
continue;
|
||||
/* see if reply transaction id matches sent id */
|
||||
if (*((u_int32_t *)(cu->cu_inbuf)) != *((u_int32_t *)(cu->cu_outbuf)))
|
||||
continue;
|
||||
/* we now assume we have the proper reply */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* now decode and validate the response
|
||||
*/
|
||||
xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
|
||||
ok = xdr_replymsg(&reply_xdrs, &reply_msg);
|
||||
/* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */
|
||||
if (ok) {
|
||||
_seterr_reply(&reply_msg, &(cu->cu_error));
|
||||
if (cu->cu_error.re_status == RPC_SUCCESS) {
|
||||
if (! AUTH_VALIDATE(cl->cl_auth,
|
||||
&reply_msg.acpted_rply.ar_verf)) {
|
||||
cu->cu_error.re_status = RPC_AUTHERROR;
|
||||
cu->cu_error.re_why = AUTH_INVALIDRESP;
|
||||
}
|
||||
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||
xdrs->x_op = XDR_FREE;
|
||||
(void)xdr_opaque_auth(xdrs,
|
||||
&(reply_msg.acpted_rply.ar_verf));
|
||||
}
|
||||
} /* end successful completion */
|
||||
else {
|
||||
/* maybe our credentials need to be refreshed ... */
|
||||
if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
|
||||
nrefreshes--;
|
||||
goto call_again;
|
||||
}
|
||||
} /* end of unsuccessful completion */
|
||||
} /* end of valid reply message */
|
||||
else {
|
||||
/*
|
||||
* It's possible for xdr_replymsg() to fail partway
|
||||
* through its attempt to decode the result from the
|
||||
* server. If this happens, it will leave the reply
|
||||
* structure partially populated with dynamically
|
||||
* allocated memory. (This can happen if someone uses
|
||||
* clntudp_bufcreate() to create a CLIENT handle and
|
||||
* specifies a receive buffer size that is too small.)
|
||||
* This memory must be free()ed to avoid a leak.
|
||||
*/
|
||||
int op = reply_xdrs.x_op;
|
||||
reply_xdrs.x_op = XDR_FREE;
|
||||
xdr_replymsg(&reply_xdrs, &reply_msg);
|
||||
reply_xdrs.x_op = op;
|
||||
cu->cu_error.re_status = RPC_CANTDECODERES;
|
||||
}
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
return (cu->cu_error.re_status);
|
||||
}
|
||||
|
||||
static void
|
||||
clntudp_geterr(cl, errp)
|
||||
CLIENT *cl;
|
||||
struct rpc_err *errp;
|
||||
{
|
||||
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
|
||||
*errp = cu->cu_error;
|
||||
}
|
||||
|
||||
|
||||
static bool_t
|
||||
clntudp_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
register XDR *xdrs = &(cu->cu_outxdrs);
|
||||
|
||||
xdrs->x_op = XDR_FREE;
|
||||
return ((*xdr_res)(xdrs, res_ptr));
|
||||
}
|
||||
|
||||
static void
|
||||
clntudp_abort(/*h*/)
|
||||
/*CLIENT *h;*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static bool_t
|
||||
clntudp_control(cl, request, info)
|
||||
CLIENT *cl;
|
||||
int request;
|
||||
char *info;
|
||||
{
|
||||
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
register struct timeval *tv;
|
||||
int len;
|
||||
|
||||
switch (request) {
|
||||
case CLSET_FD_CLOSE:
|
||||
cu->cu_closeit = TRUE;
|
||||
break;
|
||||
case CLSET_FD_NCLOSE:
|
||||
cu->cu_closeit = FALSE;
|
||||
break;
|
||||
case CLSET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
tv = (struct timeval *)info;
|
||||
cu->cu_total.tv_sec = tv->tv_sec;
|
||||
cu->cu_total.tv_usec = tv->tv_usec;
|
||||
break;
|
||||
case CLGET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct timeval *)info = cu->cu_total;
|
||||
break;
|
||||
case CLSET_RETRY_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
tv = (struct timeval *)info;
|
||||
cu->cu_wait.tv_sec = tv->tv_sec;
|
||||
cu->cu_wait.tv_usec = tv->tv_usec;
|
||||
break;
|
||||
case CLGET_RETRY_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct timeval *)info = cu->cu_wait;
|
||||
break;
|
||||
case CLGET_SERVER_ADDR:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct sockaddr_in *)info = cu->cu_raddr;
|
||||
break;
|
||||
case CLGET_FD:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(int *)info = cu->cu_sock;
|
||||
break;
|
||||
case CLGET_XID:
|
||||
/*
|
||||
* use the knowledge that xid is the
|
||||
* first element in the call structure *.
|
||||
* This will get the xid of the PREVIOUS call
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)cu->cu_outbuf);
|
||||
break;
|
||||
case CLSET_XID:
|
||||
/* This will set the xid of the NEXT call */
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)cu->cu_outbuf = htonl(*(u_long *)info - 1);
|
||||
/* decrement by 1 as clntudp_call() increments once */
|
||||
case CLGET_VERS:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the version number field is the fifth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
|
||||
4 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_VERS:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(cu->cu_outbuf + 4 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_PROG:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the program number field is the field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(cu->cu_outbuf +
|
||||
3 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_PROG:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(cu->cu_outbuf + 3 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_LOCAL_ADDR:
|
||||
len = sizeof(struct sockaddr);
|
||||
if (_getsockname(cu->cu_sock, (struct sockaddr *)info, &len) <0)
|
||||
return(FALSE);
|
||||
break;
|
||||
case CLGET_SVC_ADDR:
|
||||
case CLSET_SVC_ADDR:
|
||||
case CLSET_PUSH_TIMOD:
|
||||
case CLSET_POP_TIMOD:
|
||||
default:
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
clntudp_destroy(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
register struct cu_data *cu = (struct cu_data *)cl->cl_private;
|
||||
|
||||
if (cu->cu_closeit) {
|
||||
(void)_close(cu->cu_sock);
|
||||
}
|
||||
XDR_DESTROY(&(cu->cu_outxdrs));
|
||||
mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
|
||||
mem_free((caddr_t)cl, sizeof(CLIENT));
|
||||
}
|
@ -1,637 +0,0 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)clnt_unix.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)clnt_unix.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clnt_unix.c, Implements a AF_UNIX based, client side RPC.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* AF_UNIX based RPC supports 'batched calls'.
|
||||
* A sequence of calls may be batched-up in a send buffer. The rpc call
|
||||
* return immediately to the client even though the call was not necessarily
|
||||
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
|
||||
* the rpc timeout value is zero (see clnt.h, rpc).
|
||||
*
|
||||
* Clients should NOT casually batch calls that in fact return results; that is,
|
||||
* the server side should be aware that a call is batched and not produce any
|
||||
* return message. Batched calls that produce many result messages can
|
||||
* deadlock (netlock) the client and the server....
|
||||
*
|
||||
* Now go hang yourself.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define MCALL_MSG_SIZE 24
|
||||
|
||||
static int readunix();
|
||||
static int writeunix();
|
||||
|
||||
static enum clnt_stat clntunix_call();
|
||||
static void clntunix_abort();
|
||||
static void clntunix_geterr();
|
||||
static bool_t clntunix_freeres();
|
||||
static bool_t clntunix_control();
|
||||
static void clntunix_destroy();
|
||||
|
||||
static struct clnt_ops unix_ops = {
|
||||
clntunix_call,
|
||||
clntunix_abort,
|
||||
clntunix_geterr,
|
||||
clntunix_freeres,
|
||||
clntunix_destroy,
|
||||
clntunix_control
|
||||
};
|
||||
|
||||
struct ct_data {
|
||||
int ct_sock;
|
||||
bool_t ct_closeit;
|
||||
struct timeval ct_wait;
|
||||
bool_t ct_waitset; /* wait set by clnt_control? */
|
||||
struct sockaddr_un ct_addr;
|
||||
struct rpc_err ct_error;
|
||||
char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */
|
||||
u_int ct_mpos; /* pos after marshal */
|
||||
XDR ct_xdrs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a client handle for a unix/ip connection.
|
||||
* If *sockp<0, *sockp is set to a newly created TCP socket and it is
|
||||
* connected to raddr. If *sockp non-negative then
|
||||
* raddr is ignored. The rpc/unix package does buffering
|
||||
* similar to stdio, so the client must pick send and receive buffer sizes,];
|
||||
* 0 => use the default.
|
||||
* If raddr->sin_port is 0, then a binder on the remote machine is
|
||||
* consulted for the right port number.
|
||||
* NB: *sockp is copied into a private area.
|
||||
* NB: It is the clients responsibility to close *sockp.
|
||||
* NB: The rpch->cl_auth is set null authentication. Caller may wish to set this
|
||||
* something more useful.
|
||||
*/
|
||||
CLIENT *
|
||||
clntunix_create(raddr, prog, vers, sockp, sendsz, recvsz)
|
||||
struct sockaddr_un *raddr;
|
||||
u_long prog;
|
||||
u_long vers;
|
||||
register int *sockp;
|
||||
u_int sendsz;
|
||||
u_int recvsz;
|
||||
{
|
||||
CLIENT *h;
|
||||
register struct ct_data *ct = NULL;
|
||||
struct timeval now;
|
||||
struct rpc_msg call_msg;
|
||||
static u_int32_t disrupt;
|
||||
int len;
|
||||
|
||||
if (disrupt == 0)
|
||||
disrupt = (u_int32_t)(long)raddr;
|
||||
|
||||
h = (CLIENT *)mem_alloc(sizeof(*h));
|
||||
if (h == NULL) {
|
||||
(void)fprintf(stderr, "clntunix_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
ct = (struct ct_data *)mem_alloc(sizeof(*ct));
|
||||
if (ct == NULL) {
|
||||
(void)fprintf(stderr, "clntunix_create: out of memory\n");
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto fooy;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no socket given, open one
|
||||
*/
|
||||
if (*sockp < 0) {
|
||||
*sockp = _socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
len = strlen(raddr->sun_path) + sizeof(raddr->sun_family) +
|
||||
sizeof(raddr->sun_len) + 1;
|
||||
raddr->sun_len = len;
|
||||
if ((*sockp < 0)
|
||||
|| (_connect(*sockp, (struct sockaddr *)raddr, len) < 0)) {
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
if (*sockp != -1)
|
||||
(void)_close(*sockp);
|
||||
goto fooy;
|
||||
}
|
||||
ct->ct_closeit = TRUE;
|
||||
} else {
|
||||
ct->ct_closeit = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up private data struct
|
||||
*/
|
||||
ct->ct_sock = *sockp;
|
||||
ct->ct_wait.tv_usec = 0;
|
||||
ct->ct_waitset = FALSE;
|
||||
ct->ct_addr = *raddr;
|
||||
|
||||
/*
|
||||
* Initialize call message
|
||||
*/
|
||||
(void)gettimeofday(&now, (struct timezone *)0);
|
||||
call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
|
||||
call_msg.rm_direction = CALL;
|
||||
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
call_msg.rm_call.cb_prog = prog;
|
||||
call_msg.rm_call.cb_vers = vers;
|
||||
|
||||
/*
|
||||
* pre-serialize the static part of the call msg and stash it away
|
||||
*/
|
||||
xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
|
||||
XDR_ENCODE);
|
||||
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
|
||||
if (ct->ct_closeit) {
|
||||
(void)_close(*sockp);
|
||||
}
|
||||
goto fooy;
|
||||
}
|
||||
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
|
||||
/*
|
||||
* Create a client handle which uses xdrrec for serialization
|
||||
* and authnone for authentication.
|
||||
*/
|
||||
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
|
||||
(caddr_t)ct, readunix, writeunix);
|
||||
h->cl_ops = &unix_ops;
|
||||
h->cl_private = (caddr_t) ct;
|
||||
h->cl_auth = authnone_create();
|
||||
return (h);
|
||||
|
||||
fooy:
|
||||
/*
|
||||
* Something goofed, free stuff and barf
|
||||
*/
|
||||
if (ct)
|
||||
mem_free((caddr_t)ct, sizeof(struct ct_data));
|
||||
if (h)
|
||||
mem_free((caddr_t)h, sizeof(CLIENT));
|
||||
return ((CLIENT *)NULL);
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clntunix_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
|
||||
register CLIENT *h;
|
||||
u_long proc;
|
||||
xdrproc_t xdr_args;
|
||||
caddr_t args_ptr;
|
||||
xdrproc_t xdr_results;
|
||||
caddr_t results_ptr;
|
||||
struct timeval timeout;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *) h->cl_private;
|
||||
register XDR *xdrs = &(ct->ct_xdrs);
|
||||
struct rpc_msg reply_msg;
|
||||
u_long x_id;
|
||||
u_int32_t *msg_x_id = (u_int32_t *)(ct->ct_mcall); /* yuk */
|
||||
register bool_t shipnow;
|
||||
int refreshes = 2;
|
||||
|
||||
if (!ct->ct_waitset) {
|
||||
ct->ct_wait = timeout;
|
||||
}
|
||||
|
||||
shipnow =
|
||||
(xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
|
||||
&& timeout.tv_usec == 0) ? FALSE : TRUE;
|
||||
|
||||
call_again:
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
ct->ct_error.re_status = RPC_SUCCESS;
|
||||
x_id = ntohl(--(*msg_x_id));
|
||||
if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
|
||||
(! XDR_PUTLONG(xdrs, (long *)&proc)) ||
|
||||
(! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
|
||||
(! (*xdr_args)(xdrs, args_ptr))) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTENCODEARGS;
|
||||
(void)xdrrec_endofrecord(xdrs, TRUE);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (! xdrrec_endofrecord(xdrs, shipnow))
|
||||
return (ct->ct_error.re_status = RPC_CANTSEND);
|
||||
if (! shipnow)
|
||||
return (RPC_SUCCESS);
|
||||
/*
|
||||
* Hack to provide rpc-based message passing
|
||||
*/
|
||||
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||
return(ct->ct_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keep receiving until we get a valid transaction id
|
||||
*/
|
||||
xdrs->x_op = XDR_DECODE;
|
||||
while (TRUE) {
|
||||
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||
reply_msg.acpted_rply.ar_results.where = NULL;
|
||||
reply_msg.acpted_rply.ar_results.proc = xdr_void;
|
||||
if (! xdrrec_skiprecord(xdrs))
|
||||
return (ct->ct_error.re_status);
|
||||
/* now decode and validate the response header */
|
||||
if (! xdr_replymsg(xdrs, &reply_msg)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
continue;
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (reply_msg.rm_xid == x_id)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* process header
|
||||
*/
|
||||
_seterr_reply(&reply_msg, &(ct->ct_error));
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
||||
if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
|
||||
ct->ct_error.re_status = RPC_AUTHERROR;
|
||||
ct->ct_error.re_why = AUTH_INVALIDRESP;
|
||||
} else if (! (*xdr_results)(xdrs, results_ptr)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTDECODERES;
|
||||
}
|
||||
/* free verifier ... */
|
||||
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||
xdrs->x_op = XDR_FREE;
|
||||
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
|
||||
}
|
||||
} /* end successful completion */
|
||||
else {
|
||||
/* maybe our credentials need to be refreshed ... */
|
||||
if (refreshes-- && AUTH_REFRESH(h->cl_auth))
|
||||
goto call_again;
|
||||
} /* end of unsuccessful completion */
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
|
||||
static void
|
||||
clntunix_geterr(h, errp)
|
||||
CLIENT *h;
|
||||
struct rpc_err *errp;
|
||||
{
|
||||
register struct ct_data *ct =
|
||||
(struct ct_data *) h->cl_private;
|
||||
|
||||
*errp = ct->ct_error;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clntunix_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
|
||||
register XDR *xdrs = &(ct->ct_xdrs);
|
||||
|
||||
xdrs->x_op = XDR_FREE;
|
||||
return ((*xdr_res)(xdrs, res_ptr));
|
||||
}
|
||||
|
||||
static void
|
||||
clntunix_abort()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static bool_t
|
||||
clntunix_control(cl, request, info)
|
||||
CLIENT *cl;
|
||||
int request;
|
||||
char *info;
|
||||
{
|
||||
register struct ct_data *ct = (struct ct_data *)cl->cl_private;
|
||||
register struct timeval *tv;
|
||||
int len;
|
||||
|
||||
switch (request) {
|
||||
case CLSET_FD_CLOSE:
|
||||
ct->ct_closeit = TRUE;
|
||||
break;
|
||||
case CLSET_FD_NCLOSE:
|
||||
ct->ct_closeit = FALSE;
|
||||
break;
|
||||
case CLSET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
tv = (struct timeval *)info;
|
||||
ct->ct_wait.tv_sec = tv->tv_sec;
|
||||
ct->ct_wait.tv_usec = tv->tv_usec;
|
||||
ct->ct_waitset = TRUE;
|
||||
break;
|
||||
case CLGET_TIMEOUT:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct timeval *)info = ct->ct_wait;
|
||||
break;
|
||||
case CLGET_SERVER_ADDR:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(struct sockaddr_un *)info = ct->ct_addr;
|
||||
break;
|
||||
case CLGET_FD:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(int *)info = ct->ct_sock;
|
||||
break;
|
||||
case CLGET_XID:
|
||||
/*
|
||||
* use the knowledge that xid is the
|
||||
* first element in the call structure *.
|
||||
* This will get the xid of the PREVIOUS call
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)ct->ct_mcall);
|
||||
break;
|
||||
case CLSET_XID:
|
||||
/* This will set the xid of the NEXT call */
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)ct->ct_mcall = htonl(*(u_long *)info - 1);
|
||||
/* decrement by 1 as clntunix_call() increments once */
|
||||
case CLGET_VERS:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the version number field is the fifth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
|
||||
4 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_VERS:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(ct->ct_mcall + 4 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_PROG:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the program number field is the field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)info = ntohl(*(u_long *)(ct->ct_mcall +
|
||||
3 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
case CLSET_PROG:
|
||||
if (info == NULL)
|
||||
return(FALSE);
|
||||
*(u_long *)(ct->ct_mcall + 3 * BYTES_PER_XDR_UNIT)
|
||||
= htonl(*(u_long *)info);
|
||||
break;
|
||||
case CLGET_LOCAL_ADDR:
|
||||
len = sizeof(struct sockaddr);
|
||||
if (_getsockname(ct->ct_sock, (struct sockaddr *)info, &len) <0)
|
||||
return(FALSE);
|
||||
break;
|
||||
case CLGET_RETRY_TIMEOUT:
|
||||
case CLSET_RETRY_TIMEOUT:
|
||||
case CLGET_SVC_ADDR:
|
||||
case CLSET_SVC_ADDR:
|
||||
case CLSET_PUSH_TIMOD:
|
||||
case CLSET_POP_TIMOD:
|
||||
default:
|
||||
return (FALSE);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clntunix_destroy(h)
|
||||
CLIENT *h;
|
||||
{
|
||||
register struct ct_data *ct =
|
||||
(struct ct_data *) h->cl_private;
|
||||
|
||||
if (ct->ct_closeit) {
|
||||
(void)_close(ct->ct_sock);
|
||||
}
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
mem_free((caddr_t)ct, sizeof(struct ct_data));
|
||||
mem_free((caddr_t)h, sizeof(CLIENT));
|
||||
}
|
||||
|
||||
/*
|
||||
* _read() and _write() are replaced with _recvmsg()/_sendmsg() so that
|
||||
* we can pass ancillary control data. In this case, the data constists
|
||||
* of credential information which the kernel will fill in for us.
|
||||
* XXX: This code is specific to FreeBSD and will not work on other
|
||||
* platforms without the requisite kernel modifications.
|
||||
*/
|
||||
struct cmessage {
|
||||
struct cmsghdr cmsg;
|
||||
struct cmsgcred cmcred;
|
||||
};
|
||||
|
||||
static int __msgread(sock, buf, cnt)
|
||||
int sock;
|
||||
void *buf;
|
||||
size_t cnt;
|
||||
{
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmessage cm;
|
||||
|
||||
bzero((char *)&cm, sizeof(cm));
|
||||
iov[0].iov_base = buf;
|
||||
iov[0].iov_len = cnt;
|
||||
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_control = (caddr_t)&cm;
|
||||
msg.msg_controllen = sizeof(struct cmessage);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
return(_recvmsg(sock, &msg, 0));
|
||||
}
|
||||
|
||||
static int __msgwrite(sock, buf, cnt)
|
||||
int sock;
|
||||
void *buf;
|
||||
size_t cnt;
|
||||
{
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmessage cm;
|
||||
|
||||
bzero((char *)&cm, sizeof(cm));
|
||||
iov[0].iov_base = buf;
|
||||
iov[0].iov_len = cnt;
|
||||
|
||||
cm.cmsg.cmsg_type = SCM_CREDS;
|
||||
cm.cmsg.cmsg_level = SOL_SOCKET;
|
||||
cm.cmsg.cmsg_len = sizeof(struct cmessage);
|
||||
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_control = (caddr_t)&cm;
|
||||
msg.msg_controllen = sizeof(struct cmessage);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
return(_sendmsg(sock, &msg, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface between xdr serializer and unix connection.
|
||||
* Behaves like the system calls, read & write, but keeps some error state
|
||||
* around for the rpc level.
|
||||
*/
|
||||
static int
|
||||
readunix(ct, buf, len)
|
||||
register struct ct_data *ct;
|
||||
caddr_t buf;
|
||||
register int len;
|
||||
{
|
||||
fd_set *fds, readfds;
|
||||
struct timeval start, after, duration, delta, tmp, tv;
|
||||
int r, save_errno;
|
||||
|
||||
if (len == 0)
|
||||
return (0);
|
||||
|
||||
if (ct->ct_sock + 1 > FD_SETSIZE) {
|
||||
int bytes = howmany(ct->ct_sock + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fds = (fd_set *)malloc(bytes);
|
||||
if (fds == NULL)
|
||||
return (-1);
|
||||
memset(fds, 0, bytes);
|
||||
} else {
|
||||
fds = &readfds;
|
||||
FD_ZERO(fds);
|
||||
}
|
||||
|
||||
gettimeofday(&start, NULL);
|
||||
delta = ct->ct_wait;
|
||||
while (TRUE) {
|
||||
/* XXX we know the other bits are still clear */
|
||||
FD_SET(ct->ct_sock, fds);
|
||||
tv = delta; /* in case select writes back */
|
||||
r = _select(ct->ct_sock+1, fds, NULL, NULL, &tv);
|
||||
save_errno = errno;
|
||||
|
||||
gettimeofday(&after, NULL);
|
||||
timersub(&start, &after, &duration);
|
||||
timersub(&delta, &duration, &tmp);
|
||||
delta = tmp;
|
||||
if (delta.tv_sec < 0 || !timerisset(&delta))
|
||||
r = 0;
|
||||
|
||||
switch (r) {
|
||||
case 0:
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||
return (-1);
|
||||
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
ct->ct_error.re_errno = save_errno;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (len = __msgread(ct->ct_sock, buf, len)) {
|
||||
|
||||
case 0:
|
||||
/* premature eof */
|
||||
ct->ct_error.re_errno = ECONNRESET;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
len = -1; /* it's really an error */
|
||||
break;
|
||||
|
||||
case -1:
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
break;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static int
|
||||
writeunix(ct, buf, len)
|
||||
struct ct_data *ct;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
{
|
||||
register int i, cnt;
|
||||
|
||||
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
|
||||
if ((i = __msgwrite(ct->ct_sock, buf, cnt)) == -1) {
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTSEND;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
return (len);
|
||||
}
|
839
lib/libc/rpc/clnt_vc.c
Normal file
839
lib/libc/rpc/clnt_vc.c
Normal file
@ -0,0 +1,839 @@
|
||||
/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char *sccsid = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";
|
||||
static char sccsid[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* clnt_tcp.c, Implements a TCP/IP based, client side RPC.
|
||||
*
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*
|
||||
* TCP based RPC supports 'batched calls'.
|
||||
* A sequence of calls may be batched-up in a send buffer. The rpc call
|
||||
* return immediately to the client even though the call was not necessarily
|
||||
* sent. The batching occurs if the results' xdr routine is NULL (0) AND
|
||||
* the rpc timeout value is zero (see clnt.h, rpc).
|
||||
*
|
||||
* Clients should NOT casually batch calls that in fact return results; that is,
|
||||
* the server side should be aware that a call is batched and not produce any
|
||||
* return message. Batched calls that produce many result messages can
|
||||
* deadlock (netlock) the client and the server....
|
||||
*
|
||||
* Now go hang yourself.
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include "un-namespace.h"
|
||||
#include "rpc_com.h"
|
||||
|
||||
#define MCALL_MSG_SIZE 24
|
||||
|
||||
static enum clnt_stat clnt_vc_call __P((CLIENT *, rpcproc_t, xdrproc_t, caddr_t,
|
||||
xdrproc_t, caddr_t, struct timeval));
|
||||
static void clnt_vc_geterr __P((CLIENT *, struct rpc_err *));
|
||||
static bool_t clnt_vc_freeres __P((CLIENT *, xdrproc_t, caddr_t));
|
||||
static void clnt_vc_abort __P((CLIENT *));
|
||||
static bool_t clnt_vc_control __P((CLIENT *, u_int, char *));
|
||||
static void clnt_vc_destroy __P((CLIENT *));
|
||||
static struct clnt_ops *clnt_vc_ops __P((void));
|
||||
static bool_t time_not_ok __P((struct timeval *));
|
||||
static int read_vc __P((caddr_t, caddr_t, int));
|
||||
static int write_vc __P((caddr_t, caddr_t, int));
|
||||
static int __msgwrite(int, void *, size_t);
|
||||
static int __msgread(int, void *, size_t);
|
||||
|
||||
struct ct_data {
|
||||
int ct_fd; /* connection's fd */
|
||||
bool_t ct_closeit; /* close it on destroy */
|
||||
struct timeval ct_wait; /* wait interval in milliseconds */
|
||||
bool_t ct_waitset; /* wait set by clnt_control? */
|
||||
struct netbuf ct_addr; /* remote addr */
|
||||
struct rpc_err ct_error;
|
||||
union {
|
||||
char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */
|
||||
u_int32_t ct_mcalli;
|
||||
} ct_u;
|
||||
u_int ct_mpos; /* pos after marshal */
|
||||
XDR ct_xdrs; /* XDR stream */
|
||||
};
|
||||
|
||||
struct cmessage {
|
||||
struct cmsghdr cmsg;
|
||||
struct cmsgcred cmcred;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This machinery implements per-fd locks for MT-safety. It is not
|
||||
* sufficient to do per-CLIENT handle locks for MT-safety because a
|
||||
* user may create more than one CLIENT handle with the same fd behind
|
||||
* it. Therfore, we allocate an array of flags (vc_fd_locks), protected
|
||||
* by the clnt_fd_lock mutex, and an array (vc_cv) of condition variables
|
||||
* similarly protected. Vc_fd_lock[fd] == 1 => a call is activte on some
|
||||
* CLIENT handle created for that fd.
|
||||
* The current implementation holds locks across the entire RPC and reply.
|
||||
* Yes, this is silly, and as soon as this code is proven to work, this
|
||||
* should be the first thing fixed. One step at a time.
|
||||
*/
|
||||
static int *vc_fd_locks;
|
||||
extern mutex_t clnt_fd_lock;
|
||||
static cond_t *vc_cv;
|
||||
#define release_fd_lock(fd, mask) { \
|
||||
mutex_lock(&clnt_fd_lock); \
|
||||
if (__isthreaded) \
|
||||
vc_fd_locks[fd] = 0; \
|
||||
mutex_unlock(&clnt_fd_lock); \
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), (sigset_t *) NULL); \
|
||||
cond_signal(&vc_cv[fd]); \
|
||||
}
|
||||
|
||||
static const char clnt_vc_errstr[] = "%s : %s";
|
||||
static const char clnt_vc_str[] = "clnt_vc_create";
|
||||
static const char clnt_read_vc_str[] = "read_vc";
|
||||
static const char __no_mem_str[] = "out of memory";
|
||||
|
||||
/*
|
||||
* Create a client handle for a connection.
|
||||
* Default options are set, which the user can change using clnt_control()'s.
|
||||
* The rpc/vc package does buffering similar to stdio, so the client
|
||||
* must pick send and receive buffer sizes, 0 => use the default.
|
||||
* NB: fd is copied into a private area.
|
||||
* NB: The rpch->cl_auth is set null authentication. Caller may wish to
|
||||
* set this something more useful.
|
||||
*
|
||||
* fd should be an open socket
|
||||
*/
|
||||
CLIENT *
|
||||
clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
|
||||
int fd; /* open file descriptor */
|
||||
const struct netbuf *raddr; /* servers address */
|
||||
rpcprog_t prog; /* program number */
|
||||
rpcvers_t vers; /* version number */
|
||||
u_int sendsz; /* buffer recv size */
|
||||
u_int recvsz; /* buffer send size */
|
||||
{
|
||||
CLIENT *cl; /* client handle */
|
||||
struct ct_data *ct = NULL; /* client handle */
|
||||
struct timeval now;
|
||||
struct rpc_msg call_msg;
|
||||
static u_int32_t disrupt;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (disrupt == 0)
|
||||
disrupt = (u_int32_t)(long)raddr;
|
||||
|
||||
cl = (CLIENT *)mem_alloc(sizeof (*cl));
|
||||
ct = (struct ct_data *)mem_alloc(sizeof (*ct));
|
||||
if ((cl == (CLIENT *)NULL) || (ct == (struct ct_data *)NULL)) {
|
||||
(void) syslog(LOG_ERR, clnt_vc_errstr,
|
||||
clnt_vc_str, __no_mem_str);
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
goto err;
|
||||
}
|
||||
ct->ct_addr.buf = NULL;
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
if (vc_fd_locks == (int *) NULL) {
|
||||
int cv_allocsz, fd_allocsz;
|
||||
int dtbsize = __rpc_dtbsize();
|
||||
|
||||
fd_allocsz = dtbsize * sizeof (int);
|
||||
vc_fd_locks = (int *) mem_alloc(fd_allocsz);
|
||||
if (vc_fd_locks == (int *) NULL) {
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
goto err;
|
||||
} else
|
||||
memset(vc_fd_locks, '\0', fd_allocsz);
|
||||
|
||||
assert(vc_cv == (cond_t *) NULL);
|
||||
cv_allocsz = dtbsize * sizeof (cond_t);
|
||||
vc_cv = (cond_t *) mem_alloc(cv_allocsz);
|
||||
if (vc_cv == (cond_t *) NULL) {
|
||||
mem_free(vc_fd_locks, fd_allocsz);
|
||||
vc_fd_locks = (int *) NULL;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
goto err;
|
||||
} else {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dtbsize; i++)
|
||||
cond_init(&vc_cv[i], 0, (void *) 0);
|
||||
}
|
||||
} else
|
||||
assert(vc_cv != (cond_t *) NULL);
|
||||
|
||||
/*
|
||||
* XXX - fvdl connecting while holding a mutex?
|
||||
*/
|
||||
slen = sizeof ss;
|
||||
if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) < 0) {
|
||||
if (errno != ENOTCONN) {
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
goto err;
|
||||
}
|
||||
if (_connect(fd, (struct sockaddr *)raddr->buf, raddr->len) < 0){
|
||||
rpc_createerr.cf_stat = RPC_SYSTEMERROR;
|
||||
rpc_createerr.cf_error.re_errno = errno;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
if (!__rpc_fd2sockinfo(fd, &si))
|
||||
goto err;
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
|
||||
ct->ct_closeit = FALSE;
|
||||
|
||||
/*
|
||||
* Set up private data struct
|
||||
*/
|
||||
ct->ct_fd = fd;
|
||||
ct->ct_wait.tv_usec = 0;
|
||||
ct->ct_waitset = FALSE;
|
||||
ct->ct_addr.buf = malloc(raddr->maxlen);
|
||||
if (ct->ct_addr.buf == NULL)
|
||||
goto err;
|
||||
memcpy(ct->ct_addr.buf, &raddr->buf, raddr->len);
|
||||
ct->ct_addr.len = raddr->maxlen;
|
||||
ct->ct_addr.maxlen = raddr->maxlen;
|
||||
|
||||
/*
|
||||
* Initialize call message
|
||||
*/
|
||||
(void)gettimeofday(&now, NULL);
|
||||
call_msg.rm_xid = ((u_int32_t)++disrupt) ^ __RPC_GETXID(&now);
|
||||
call_msg.rm_direction = CALL;
|
||||
call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
call_msg.rm_call.cb_prog = (u_int32_t)prog;
|
||||
call_msg.rm_call.cb_vers = (u_int32_t)vers;
|
||||
|
||||
/*
|
||||
* pre-serialize the static part of the call msg and stash it away
|
||||
*/
|
||||
xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE,
|
||||
XDR_ENCODE);
|
||||
if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
|
||||
if (ct->ct_closeit) {
|
||||
(void)_close(fd);
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
|
||||
/*
|
||||
* Create a client handle which uses xdrrec for serialization
|
||||
* and authnone for authentication.
|
||||
*/
|
||||
cl->cl_ops = clnt_vc_ops();
|
||||
cl->cl_private = ct;
|
||||
cl->cl_auth = authnone_create();
|
||||
sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz);
|
||||
recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz);
|
||||
xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
|
||||
cl->cl_private, read_vc, write_vc);
|
||||
return (cl);
|
||||
|
||||
err:
|
||||
if (cl) {
|
||||
if (ct) {
|
||||
if (ct->ct_addr.len)
|
||||
mem_free(ct->ct_addr.buf, ct->ct_addr.len);
|
||||
mem_free((caddr_t)ct, sizeof (struct ct_data));
|
||||
}
|
||||
if (cl)
|
||||
mem_free((caddr_t)cl, sizeof (CLIENT));
|
||||
}
|
||||
return ((CLIENT *)NULL);
|
||||
}
|
||||
|
||||
static enum clnt_stat
|
||||
clnt_vc_call(cl, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
|
||||
CLIENT *cl;
|
||||
rpcproc_t proc;
|
||||
xdrproc_t xdr_args;
|
||||
caddr_t args_ptr;
|
||||
xdrproc_t xdr_results;
|
||||
caddr_t results_ptr;
|
||||
struct timeval timeout;
|
||||
{
|
||||
struct ct_data *ct = (struct ct_data *) cl->cl_private;
|
||||
XDR *xdrs = &(ct->ct_xdrs);
|
||||
struct rpc_msg reply_msg;
|
||||
u_int32_t x_id;
|
||||
u_int32_t *msg_x_id = &ct->ct_u.ct_mcalli; /* yuk */
|
||||
bool_t shipnow;
|
||||
int refreshes = 2;
|
||||
sigset_t mask, newmask;
|
||||
int rpc_lock_value;
|
||||
|
||||
assert(cl != NULL);
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (vc_fd_locks[ct->ct_fd])
|
||||
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
|
||||
if (__isthreaded)
|
||||
rpc_lock_value = 1;
|
||||
else
|
||||
rpc_lock_value = 0;
|
||||
vc_fd_locks[ct->ct_fd] = rpc_lock_value;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
if (!ct->ct_waitset) {
|
||||
/* If time is not within limits, we ignore it. */
|
||||
if (time_not_ok(&timeout) == FALSE)
|
||||
ct->ct_wait = timeout;
|
||||
}
|
||||
|
||||
shipnow =
|
||||
(xdr_results == NULL && timeout.tv_sec == 0
|
||||
&& timeout.tv_usec == 0) ? FALSE : TRUE;
|
||||
|
||||
call_again:
|
||||
xdrs->x_op = XDR_ENCODE;
|
||||
ct->ct_error.re_status = RPC_SUCCESS;
|
||||
x_id = ntohl(--(*msg_x_id));
|
||||
|
||||
if ((! XDR_PUTBYTES(xdrs, ct->ct_u.ct_mcallc, ct->ct_mpos)) ||
|
||||
(! XDR_PUTINT32(xdrs, &proc)) ||
|
||||
(! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
|
||||
(! (*xdr_args)(xdrs, args_ptr))) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTENCODEARGS;
|
||||
(void)xdrrec_endofrecord(xdrs, TRUE);
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (! xdrrec_endofrecord(xdrs, shipnow)) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (ct->ct_error.re_status = RPC_CANTSEND);
|
||||
}
|
||||
if (! shipnow) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (RPC_SUCCESS);
|
||||
}
|
||||
/*
|
||||
* Hack to provide rpc-based message passing
|
||||
*/
|
||||
if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return(ct->ct_error.re_status = RPC_TIMEDOUT);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Keep receiving until we get a valid transaction id
|
||||
*/
|
||||
xdrs->x_op = XDR_DECODE;
|
||||
while (TRUE) {
|
||||
reply_msg.acpted_rply.ar_verf = _null_auth;
|
||||
reply_msg.acpted_rply.ar_results.where = NULL;
|
||||
reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
|
||||
if (! xdrrec_skiprecord(xdrs)) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
/* now decode and validate the response header */
|
||||
if (! xdr_replymsg(xdrs, &reply_msg)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
continue;
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
if (reply_msg.rm_xid == x_id)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* process header
|
||||
*/
|
||||
_seterr_reply(&reply_msg, &(ct->ct_error));
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS) {
|
||||
if (! AUTH_VALIDATE(cl->cl_auth,
|
||||
&reply_msg.acpted_rply.ar_verf)) {
|
||||
ct->ct_error.re_status = RPC_AUTHERROR;
|
||||
ct->ct_error.re_why = AUTH_INVALIDRESP;
|
||||
} else if (! (*xdr_results)(xdrs, results_ptr)) {
|
||||
if (ct->ct_error.re_status == RPC_SUCCESS)
|
||||
ct->ct_error.re_status = RPC_CANTDECODERES;
|
||||
}
|
||||
/* free verifier ... */
|
||||
if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
|
||||
xdrs->x_op = XDR_FREE;
|
||||
(void)xdr_opaque_auth(xdrs,
|
||||
&(reply_msg.acpted_rply.ar_verf));
|
||||
}
|
||||
} /* end successful completion */
|
||||
else {
|
||||
/* maybe our credentials need to be refreshed ... */
|
||||
if (refreshes-- && AUTH_REFRESH(cl->cl_auth, &reply_msg))
|
||||
goto call_again;
|
||||
} /* end of unsuccessful completion */
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (ct->ct_error.re_status);
|
||||
}
|
||||
|
||||
static void
|
||||
clnt_vc_geterr(cl, errp)
|
||||
CLIENT *cl;
|
||||
struct rpc_err *errp;
|
||||
{
|
||||
struct ct_data *ct;
|
||||
|
||||
assert(cl != NULL);
|
||||
assert(errp != NULL);
|
||||
|
||||
ct = (struct ct_data *) cl->cl_private;
|
||||
*errp = ct->ct_error;
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clnt_vc_freeres(cl, xdr_res, res_ptr)
|
||||
CLIENT *cl;
|
||||
xdrproc_t xdr_res;
|
||||
caddr_t res_ptr;
|
||||
{
|
||||
struct ct_data *ct;
|
||||
XDR *xdrs;
|
||||
bool_t dummy;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
|
||||
assert(cl != NULL);
|
||||
|
||||
ct = (struct ct_data *)cl->cl_private;
|
||||
xdrs = &(ct->ct_xdrs);
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (vc_fd_locks[ct->ct_fd])
|
||||
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
|
||||
xdrs->x_op = XDR_FREE;
|
||||
dummy = (*xdr_res)(xdrs, res_ptr);
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
cond_signal(&vc_cv[ct->ct_fd]);
|
||||
|
||||
return dummy;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
clnt_vc_abort(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
}
|
||||
|
||||
static bool_t
|
||||
clnt_vc_control(cl, request, info)
|
||||
CLIENT *cl;
|
||||
u_int request;
|
||||
char *info;
|
||||
{
|
||||
struct ct_data *ct;
|
||||
void *infop = info;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
int rpc_lock_value;
|
||||
|
||||
assert(cl != NULL);
|
||||
|
||||
ct = (struct ct_data *)cl->cl_private;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (vc_fd_locks[ct->ct_fd])
|
||||
cond_wait(&vc_cv[ct->ct_fd], &clnt_fd_lock);
|
||||
if (__isthreaded)
|
||||
rpc_lock_value = 1;
|
||||
else
|
||||
rpc_lock_value = 0;
|
||||
vc_fd_locks[ct->ct_fd] = rpc_lock_value;
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
|
||||
switch (request) {
|
||||
case CLSET_FD_CLOSE:
|
||||
ct->ct_closeit = TRUE;
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (TRUE);
|
||||
case CLSET_FD_NCLOSE:
|
||||
ct->ct_closeit = FALSE;
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (TRUE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* for other requests which use info */
|
||||
if (info == NULL) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
switch (request) {
|
||||
case CLSET_TIMEOUT:
|
||||
if (time_not_ok((struct timeval *)(void *)info)) {
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
ct->ct_wait = *(struct timeval *)infop;
|
||||
ct->ct_waitset = TRUE;
|
||||
break;
|
||||
case CLGET_TIMEOUT:
|
||||
*(struct timeval *)infop = ct->ct_wait;
|
||||
break;
|
||||
case CLGET_SERVER_ADDR:
|
||||
(void) memcpy(info, ct->ct_addr.buf, (size_t)ct->ct_addr.len);
|
||||
break;
|
||||
case CLGET_FD:
|
||||
*(int *)(void *)info = ct->ct_fd;
|
||||
break;
|
||||
case CLGET_SVC_ADDR:
|
||||
/* The caller should not free this memory area */
|
||||
*(struct netbuf *)(void *)info = ct->ct_addr;
|
||||
break;
|
||||
case CLSET_SVC_ADDR: /* set to new address */
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (FALSE);
|
||||
case CLGET_XID:
|
||||
/*
|
||||
* use the knowledge that xid is the
|
||||
* first element in the call structure
|
||||
* This will get the xid of the PREVIOUS call
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli);
|
||||
break;
|
||||
case CLSET_XID:
|
||||
/* This will set the xid of the NEXT call */
|
||||
*(u_int32_t *)(void *)&ct->ct_u.ct_mcalli =
|
||||
htonl(*((u_int32_t *)(void *)info) + 1);
|
||||
/* increment by 1 as clnt_vc_call() decrements once */
|
||||
break;
|
||||
case CLGET_VERS:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the version number field is the fifth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
|
||||
4 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
|
||||
case CLSET_VERS:
|
||||
*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
|
||||
4 * BYTES_PER_XDR_UNIT) =
|
||||
htonl(*(u_int32_t *)(void *)info);
|
||||
break;
|
||||
|
||||
case CLGET_PROG:
|
||||
/*
|
||||
* This RELIES on the information that, in the call body,
|
||||
* the program number field is the fourth field from the
|
||||
* begining of the RPC header. MUST be changed if the
|
||||
* call_struct is changed
|
||||
*/
|
||||
*(u_int32_t *)(void *)info =
|
||||
ntohl(*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
|
||||
3 * BYTES_PER_XDR_UNIT));
|
||||
break;
|
||||
|
||||
case CLSET_PROG:
|
||||
*(u_int32_t *)(void *)(ct->ct_u.ct_mcallc +
|
||||
3 * BYTES_PER_XDR_UNIT) =
|
||||
htonl(*(u_int32_t *)(void *)info);
|
||||
break;
|
||||
|
||||
default:
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (FALSE);
|
||||
}
|
||||
release_fd_lock(ct->ct_fd, mask);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clnt_vc_destroy(cl)
|
||||
CLIENT *cl;
|
||||
{
|
||||
struct ct_data *ct = (struct ct_data *) cl->cl_private;
|
||||
int ct_fd = ct->ct_fd;
|
||||
sigset_t mask;
|
||||
sigset_t newmask;
|
||||
|
||||
assert(cl != NULL);
|
||||
|
||||
ct = (struct ct_data *) cl->cl_private;
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&clnt_fd_lock);
|
||||
while (vc_fd_locks[ct_fd])
|
||||
cond_wait(&vc_cv[ct_fd], &clnt_fd_lock);
|
||||
if (ct->ct_closeit && ct->ct_fd != -1) {
|
||||
(void)_close(ct->ct_fd);
|
||||
}
|
||||
XDR_DESTROY(&(ct->ct_xdrs));
|
||||
if (ct->ct_addr.buf)
|
||||
free(ct->ct_addr.buf);
|
||||
mem_free(ct, sizeof(struct ct_data));
|
||||
mem_free(cl, sizeof(CLIENT));
|
||||
mutex_unlock(&clnt_fd_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
cond_signal(&vc_cv[ct_fd]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface between xdr serializer and tcp connection.
|
||||
* Behaves like the system calls, read & write, but keeps some error state
|
||||
* around for the rpc level.
|
||||
*/
|
||||
static int
|
||||
read_vc(ctp, buf, len)
|
||||
caddr_t ctp;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
{
|
||||
struct sockaddr sa;
|
||||
socklen_t sal;
|
||||
struct ct_data *ct = (struct ct_data *)(void *)ctp;
|
||||
struct pollfd fd;
|
||||
int milliseconds = (int)((ct->ct_wait.tv_sec * 1000) +
|
||||
(ct->ct_wait.tv_usec / 1000));
|
||||
|
||||
if (len == 0)
|
||||
return (0);
|
||||
fd.fd = ct->ct_fd;
|
||||
fd.events = POLLIN;
|
||||
for (;;) {
|
||||
switch (_poll(&fd, 1, milliseconds)) {
|
||||
case 0:
|
||||
ct->ct_error.re_status = RPC_TIMEDOUT;
|
||||
return (-1);
|
||||
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
ct->ct_error.re_errno = errno;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sal = sizeof(sa);
|
||||
if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) &&
|
||||
(sa.sa_family == AF_LOCAL)) {
|
||||
len = __msgread(ct->ct_fd, buf, (size_t)len);
|
||||
} else {
|
||||
len = _read(ct->ct_fd, buf, (size_t)len);
|
||||
}
|
||||
|
||||
switch (len) {
|
||||
case 0:
|
||||
/* premature eof */
|
||||
ct->ct_error.re_errno = ECONNRESET;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
len = -1; /* it's really an error */
|
||||
break;
|
||||
|
||||
case -1:
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTRECV;
|
||||
break;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static int
|
||||
write_vc(ctp, buf, len)
|
||||
caddr_t ctp;
|
||||
caddr_t buf;
|
||||
int len;
|
||||
{
|
||||
struct sockaddr sa;
|
||||
socklen_t sal;
|
||||
struct ct_data *ct = (struct ct_data *)(void *)ctp;
|
||||
int i, cnt;
|
||||
|
||||
sal = sizeof(sa);
|
||||
if ((_getpeername(ct->ct_fd, &sa, &sal) == 0) &&
|
||||
(sa.sa_family == AF_LOCAL)) {
|
||||
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
|
||||
if ((i = __msgwrite(ct->ct_fd, buf,
|
||||
(size_t)cnt)) == -1) {
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTSEND;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (cnt = len; cnt > 0; cnt -= i, buf += i) {
|
||||
if ((i = _write(ct->ct_fd, buf, (size_t)cnt)) == -1) {
|
||||
ct->ct_error.re_errno = errno;
|
||||
ct->ct_error.re_status = RPC_CANTSEND;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static struct clnt_ops *
|
||||
clnt_vc_ops()
|
||||
{
|
||||
static struct clnt_ops ops;
|
||||
extern mutex_t ops_lock;
|
||||
sigset_t mask, newmask;
|
||||
|
||||
/* VARIABLES PROTECTED BY ops_lock: ops */
|
||||
|
||||
sigfillset(&newmask);
|
||||
thr_sigsetmask(SIG_SETMASK, &newmask, &mask);
|
||||
mutex_lock(&ops_lock);
|
||||
if (ops.cl_call == NULL) {
|
||||
ops.cl_call = clnt_vc_call;
|
||||
ops.cl_abort = clnt_vc_abort;
|
||||
ops.cl_geterr = clnt_vc_geterr;
|
||||
ops.cl_freeres = clnt_vc_freeres;
|
||||
ops.cl_destroy = clnt_vc_destroy;
|
||||
ops.cl_control = clnt_vc_control;
|
||||
}
|
||||
mutex_unlock(&ops_lock);
|
||||
thr_sigsetmask(SIG_SETMASK, &(mask), NULL);
|
||||
return (&ops);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the time is not garbage. -1 value is disallowed.
|
||||
* Note this is different from time_not_ok in clnt_dg.c
|
||||
*/
|
||||
static bool_t
|
||||
time_not_ok(t)
|
||||
struct timeval *t;
|
||||
{
|
||||
return (t->tv_sec <= -1 || t->tv_sec > 100000000 ||
|
||||
t->tv_usec <= -1 || t->tv_usec > 1000000);
|
||||
}
|
||||
|
||||
__msgread(sock, buf, cnt)
|
||||
int sock;
|
||||
void *buf;
|
||||
size_t cnt;
|
||||
{
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmessage cm;
|
||||
|
||||
bzero((char *)&cm, sizeof(cm));
|
||||
iov[0].iov_base = buf;
|
||||
iov[0].iov_len = cnt;
|
||||
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_control = (caddr_t)&cm;
|
||||
msg.msg_controllen = sizeof(struct cmessage);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
return(_recvmsg(sock, &msg, 0));
|
||||
}
|
||||
|
||||
static int
|
||||
__msgwrite(sock, buf, cnt)
|
||||
int sock;
|
||||
void *buf;
|
||||
size_t cnt;
|
||||
{
|
||||
struct iovec iov[1];
|
||||
struct msghdr msg;
|
||||
struct cmessage cm;
|
||||
|
||||
bzero((char *)&cm, sizeof(cm));
|
||||
iov[0].iov_base = buf;
|
||||
iov[0].iov_len = cnt;
|
||||
|
||||
cm.cmsg.cmsg_type = SCM_CREDS;
|
||||
cm.cmsg.cmsg_level = SOL_SOCKET;
|
||||
cm.cmsg.cmsg_len = sizeof(struct cmessage);
|
||||
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_control = (caddr_t)&cm;
|
||||
msg.msg_controllen = sizeof(struct cmessage);
|
||||
msg.msg_flags = 0;
|
||||
|
||||
return(_sendmsg(sock, &msg, 0));
|
||||
}
|
@ -28,15 +28,15 @@
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <rpc/des_crypt.h>
|
||||
#include <rpc/des.h>
|
||||
#include <string.h>
|
||||
#include <rpcsvc/crypt.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char rcsid[] = "$FreeBSD$";
|
||||
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get_myaddress.c
|
||||
*
|
||||
* Get client's IP address via ioctl. This avoids using the yellowpages.
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* don't use gethostbyname, which would invoke yellow pages
|
||||
*
|
||||
* Avoid loopback interfaces. We return information from a loopback
|
||||
* interface only if there are no other possible interfaces.
|
||||
*/
|
||||
int
|
||||
get_myaddress(addr)
|
||||
struct sockaddr_in *addr;
|
||||
{
|
||||
int s;
|
||||
char buf[BUFSIZ];
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifreq, *ifr, *end;
|
||||
int loopback = 0, gotit = 0;
|
||||
|
||||
if ((s = _socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
return(-1);
|
||||
}
|
||||
ifc.ifc_len = sizeof (buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (_ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
_close(s);
|
||||
return(-1);
|
||||
}
|
||||
again:
|
||||
ifr = ifc.ifc_req;
|
||||
end = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
|
||||
|
||||
while (ifr < end) {
|
||||
memcpy(&ifreq, ifr, sizeof(ifreq));
|
||||
if (_ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
|
||||
_close(s);
|
||||
return(-1);
|
||||
}
|
||||
if (((ifreq.ifr_flags & IFF_UP) &&
|
||||
ifr->ifr_addr.sa_family == AF_INET &&
|
||||
!(ifreq.ifr_flags & IFF_LOOPBACK)) ||
|
||||
(loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
|
||||
&& (ifr->ifr_addr.sa_family == AF_INET)
|
||||
&& (ifreq.ifr_flags & IFF_UP))) {
|
||||
*addr = *((struct sockaddr_in *)&ifr->ifr_addr);
|
||||
addr->sin_port = htons(PMAPPORT);
|
||||
gotit = 1;
|
||||
break;
|
||||
}
|
||||
if (ifr->ifr_addr.sa_len)
|
||||
ifr = (struct ifreq *) ((caddr_t) ifr +
|
||||
ifr->ifr_addr.sa_len -
|
||||
sizeof(struct sockaddr));
|
||||
ifr++;
|
||||
}
|
||||
if (gotit == 0 && loopback == 0) {
|
||||
loopback = 1;
|
||||
goto again;
|
||||
}
|
||||
(void)_close(s);
|
||||
return (gotit ? 0 : -1);
|
||||
}
|
182
lib/libc/rpc/getnetconfig.3
Normal file
182
lib/libc/rpc/getnetconfig.3
Normal file
@ -0,0 +1,182 @@
|
||||
.\" @(#)getnetconfig.3n 1.28 93/06/02 SMI; from SVr4
|
||||
.\" $NetBSD: getnetconfig.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $
|
||||
.\" $FreeBSD$
|
||||
.\" Copyright 1989 AT&T
|
||||
.Dd April 22, 2000
|
||||
.Dt GETNETCONFIG 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getnetconfig ,
|
||||
.Nm setnetconfig ,
|
||||
.Nm endnetconfig ,
|
||||
.Nm getnetconfigent ,
|
||||
.Nm freenetconfigent ,
|
||||
.Nm nc_perror ,
|
||||
.Nm nc_sperror
|
||||
.Nd get network configuration database entry
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netconfig.h>
|
||||
.Ft "struct netconfig *"
|
||||
.Fn getnetconfig "void *handlep"
|
||||
.Ft "void *"
|
||||
.Fn setnetconfig "void"
|
||||
.Ft int
|
||||
.Fn endnetconfig "void *handlep"
|
||||
.Ft "struct netconfig *"
|
||||
.Fn getnetconfigent "const char *netid"
|
||||
.Ft void
|
||||
.Fn freenetconfigent "struct netconfig *netconfigp"
|
||||
.Ft void
|
||||
.Fn nc_perror "const char *msg"
|
||||
.Ft "char *"
|
||||
.Fn nc_sperror "void"
|
||||
.Sh DESCRIPTION
|
||||
The library routines described on this page
|
||||
provide the application access to
|
||||
the system network configuration database,
|
||||
.Pa /etc/netconfig .
|
||||
.Fn getnetconfig
|
||||
returns a pointer to the
|
||||
current entry in the
|
||||
netconfig
|
||||
database, formatted as a
|
||||
.Ft "struct netconfig" .
|
||||
Successive calls will return successive netconfig
|
||||
entries in the netconfig database.
|
||||
.Fn getnetconfig
|
||||
can be used to search the entire netconfig
|
||||
file.
|
||||
.Fn getnetconfig
|
||||
returns
|
||||
.Dv NULL
|
||||
at the end of the file.
|
||||
.Fa handlep
|
||||
is the handle obtained through
|
||||
.Fn setnetconfig .
|
||||
.Pp
|
||||
A call to
|
||||
.Fn setnetconfig
|
||||
has the effect of
|
||||
.Dq binding
|
||||
to or
|
||||
.Dq rewinding
|
||||
the netconfig database.
|
||||
.Fn setnetconfig
|
||||
must be called before the first call to
|
||||
.Fn getnetconfig
|
||||
and may be called at any other time.
|
||||
.Fn setnetconfig
|
||||
need not be called before a call to
|
||||
.Fn getnetconfigent .
|
||||
.Fn setnetconfig
|
||||
returns a unique handle to be used by
|
||||
.Fn getnetconfig .
|
||||
.Pp
|
||||
.Fn endnetconfig
|
||||
should be called when processing is complete to release resources for reuse.
|
||||
.Fa handlep
|
||||
is the handle obtained through
|
||||
.Fn setnetconfig .
|
||||
Programmers should be aware, however, that the last call to
|
||||
.Fn endnetconfig
|
||||
frees all memory allocated by
|
||||
.Fn getnetconfig
|
||||
for the
|
||||
.Ft "struct netconfig"
|
||||
data structure.
|
||||
.Fn endnetconfig
|
||||
may not be called before
|
||||
.Fn setnetconfig .
|
||||
.Pp
|
||||
.Fn getnetconfigent
|
||||
returns a pointer
|
||||
to the netconfig structure corresponding
|
||||
to
|
||||
.Fa netid .
|
||||
It returns
|
||||
.Dv NULL
|
||||
if
|
||||
.Fa netid
|
||||
is invalid
|
||||
(that is, does not name an entry in the netconfig database).
|
||||
.Pp
|
||||
.Fn freenetconfigent
|
||||
frees the netconfig structure pointed to by
|
||||
.Fa netconfigp
|
||||
(previously returned by
|
||||
.Fn getnetconfigent ) .
|
||||
.Pp
|
||||
.Fn nc_perror
|
||||
prints a message to the standard error indicating why any of the
|
||||
above routines failed.
|
||||
The message is prepended with the string
|
||||
.Fa msg
|
||||
and a colon.
|
||||
A newline character is appended at the end of the message.
|
||||
.Pp
|
||||
.Fn nc_sperror
|
||||
is similar to
|
||||
.Fn nc_perror
|
||||
but instead of sending the message
|
||||
to the standard error, will return a pointer to a string that
|
||||
contains the error message.
|
||||
.Pp
|
||||
.Fn nc_perror
|
||||
and
|
||||
.Fn nc_sperror
|
||||
can also be used with the
|
||||
.Ev NETPATH
|
||||
access routines defined in
|
||||
.Xr getnetpath 3 .
|
||||
.Sh RETURN VALUES
|
||||
.Fn setnetconfig
|
||||
returns a unique handle to be used by
|
||||
.Fn getnetconfig .
|
||||
In the case of an error,
|
||||
.Fn setnetconfig
|
||||
returns
|
||||
.Dv NULL
|
||||
and
|
||||
.Fn nc_perror
|
||||
or
|
||||
.Fn nc_sperror
|
||||
can be used to print the reason for failure.
|
||||
.Pp
|
||||
.Fn getnetconfig
|
||||
returns a pointer to the current entry in the netconfig
|
||||
database, formatted as a
|
||||
.Ft "struct netconfig" .
|
||||
.Fn getnetconfig
|
||||
returns
|
||||
.Dv NULL
|
||||
at the end of the file, or upon failure.
|
||||
.Pp
|
||||
.Fn endnetconfig
|
||||
returns 0 on success and \-1 on failure
|
||||
(for example, if
|
||||
.Fn setnetconfig
|
||||
was not called previously).
|
||||
.Pp
|
||||
On success,
|
||||
.Fn getnetconfigent
|
||||
returns a pointer to the
|
||||
.Ft "struct netconfig"
|
||||
structure corresponding to
|
||||
.Fa netid ;
|
||||
otherwise it returns
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
.Fn nc_sperror
|
||||
returns a pointer to a buffer which contains the error message string.
|
||||
This buffer is overwritten on each call.
|
||||
In multithreaded applications, this buffer is
|
||||
implemented as thread-specific data.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/netconfig -compact
|
||||
.It Pa /etc/netconfig
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr getnetpath 3 ,
|
||||
.Xr netconfig 5
|
674
lib/libc/rpc/getnetconfig.c
Normal file
674
lib/libc/rpc/getnetconfig.c
Normal file
@ -0,0 +1,674 @@
|
||||
/* $NetBSD: getnetconfig.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)getnetconfig.c 1.12 91/12/19 SMI";
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <netconfig.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include "un-namespace.h"
|
||||
#include "rpc_com.h"
|
||||
|
||||
/*
|
||||
* The five library routines in this file provide application access to the
|
||||
* system network configuration database, /etc/netconfig. In addition to the
|
||||
* netconfig database and the routines for accessing it, the environment
|
||||
* variable NETPATH and its corresponding routines in getnetpath.c may also be
|
||||
* used to specify the network transport to be used.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* netconfig errors
|
||||
*/
|
||||
|
||||
#define NC_NONETCONFIG ENOENT
|
||||
#define NC_NOMEM ENOMEM
|
||||
#define NC_NOTINIT EINVAL /* setnetconfig was not called first */
|
||||
#define NC_BADFILE EBADF /* format for netconfig file is bad */
|
||||
|
||||
/*
|
||||
* semantics as strings (should be in netconfig.h)
|
||||
*/
|
||||
#define NC_TPI_CLTS_S "tpi_clts"
|
||||
#define NC_TPI_COTS_S "tpi_cots"
|
||||
#define NC_TPI_COTS_ORD_S "tpi_cots_ord"
|
||||
#define NC_TPI_RAW_S "tpi_raw"
|
||||
|
||||
/*
|
||||
* flags as characters (also should be in netconfig.h)
|
||||
*/
|
||||
#define NC_NOFLAG_C '-'
|
||||
#define NC_VISIBLE_C 'v'
|
||||
#define NC_BROADCAST_C 'b'
|
||||
|
||||
/*
|
||||
* Character used to indicate there is no name-to-address lookup library
|
||||
*/
|
||||
#define NC_NOLOOKUP "-"
|
||||
|
||||
static const char * const _nc_errors[] = {
|
||||
"Netconfig database not found",
|
||||
"Not enough memory",
|
||||
"Not initialized",
|
||||
"Netconfig database has invalid format"
|
||||
};
|
||||
|
||||
struct netconfig_info {
|
||||
int eof; /* all entries has been read */
|
||||
int ref; /* # of times setnetconfig() has been called */
|
||||
struct netconfig_list *head; /* head of the list */
|
||||
struct netconfig_list *tail; /* last of the list */
|
||||
};
|
||||
|
||||
struct netconfig_list {
|
||||
char *linep; /* hold line read from netconfig */
|
||||
struct netconfig *ncp;
|
||||
struct netconfig_list *next;
|
||||
};
|
||||
|
||||
struct netconfig_vars {
|
||||
int valid; /* token that indicates a valid netconfig_vars */
|
||||
int flag; /* first time flag */
|
||||
struct netconfig_list *nc_configs; /* pointer to the current netconfig entry */
|
||||
};
|
||||
|
||||
#define NC_VALID 0xfeed
|
||||
#define NC_STORAGE 0xf00d
|
||||
#define NC_INVALID 0
|
||||
|
||||
|
||||
static int *__nc_error __P((void));
|
||||
static int parse_ncp __P((char *, struct netconfig *));
|
||||
static struct netconfig *dup_ncp __P((struct netconfig *));
|
||||
|
||||
|
||||
static FILE *nc_file; /* for netconfig db */
|
||||
static struct netconfig_info ni = { 0, 0, NULL, NULL};
|
||||
|
||||
#define MAXNETCONFIGLINE 1000
|
||||
|
||||
static int *
|
||||
__nc_error()
|
||||
{
|
||||
extern pthread_mutex_t nc_lock;
|
||||
static thread_key_t nc_key = 0;
|
||||
static thread_key_t rce_key = 0;
|
||||
int *nc_addr = NULL;
|
||||
static int nc_error = 0;
|
||||
|
||||
if ((nc_addr = (int *)thr_getspecific(nc_key)) != 0) {
|
||||
mutex_lock(&nc_lock);
|
||||
if (thr_keycreate(&rce_key, free) != 0) {
|
||||
mutex_unlock(&nc_lock);
|
||||
return nc_addr;
|
||||
}
|
||||
mutex_unlock(&nc_lock);
|
||||
}
|
||||
if (nc_addr == NULL) {
|
||||
nc_addr = (int *)malloc(sizeof (int));
|
||||
if (thr_setspecific(nc_key, (void *) nc_addr) != 0) {
|
||||
if (nc_addr)
|
||||
free(nc_addr);
|
||||
return &nc_error;
|
||||
}
|
||||
*nc_addr = 0;
|
||||
return nc_addr;
|
||||
}
|
||||
return nc_addr;
|
||||
}
|
||||
|
||||
#define nc_error (*(__nc_error()))
|
||||
/*
|
||||
* A call to setnetconfig() establishes a /etc/netconfig "session". A session
|
||||
* "handle" is returned on a successful call. At the start of a session (after
|
||||
* a call to setnetconfig()) searches through the /etc/netconfig database will
|
||||
* proceed from the start of the file. The session handle must be passed to
|
||||
* getnetconfig() to parse the file. Each call to getnetconfig() using the
|
||||
* current handle will process one subsequent entry in /etc/netconfig.
|
||||
* setnetconfig() must be called before the first call to getnetconfig().
|
||||
* (Handles are used to allow for nested calls to setnetpath()).
|
||||
*
|
||||
* A new session is established with each call to setnetconfig(), with a new
|
||||
* handle being returned on each call. Previously established sessions remain
|
||||
* active until endnetconfig() is called with that session's handle as an
|
||||
* argument.
|
||||
*
|
||||
* setnetconfig() need *not* be called before a call to getnetconfigent().
|
||||
* setnetconfig() returns a NULL pointer on failure (for example, if
|
||||
* the netconfig database is not present).
|
||||
*/
|
||||
void *
|
||||
setnetconfig()
|
||||
{
|
||||
struct netconfig_vars *nc_vars;
|
||||
|
||||
if ((nc_vars = (struct netconfig_vars *)malloc(sizeof
|
||||
(struct netconfig_vars))) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* For multiple calls, i.e. nc_file is not NULL, we just return the
|
||||
* handle without reopening the netconfig db.
|
||||
*/
|
||||
ni.ref++;
|
||||
if ((nc_file != NULL) || (nc_file = fopen(NETCONFIG, "r")) != NULL) {
|
||||
nc_vars->valid = NC_VALID;
|
||||
nc_vars->flag = 0;
|
||||
nc_vars->nc_configs = ni.head;
|
||||
return ((void *)nc_vars);
|
||||
}
|
||||
ni.ref--;
|
||||
nc_error = NC_NONETCONFIG;
|
||||
free(nc_vars);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* When first called, getnetconfig() returns a pointer to the first entry in
|
||||
* the netconfig database, formatted as a struct netconfig. On each subsequent
|
||||
* call, getnetconfig() returns a pointer to the next entry in the database.
|
||||
* getnetconfig() can thus be used to search the entire netconfig file.
|
||||
* getnetconfig() returns NULL at end of file.
|
||||
*/
|
||||
|
||||
struct netconfig *
|
||||
getnetconfig(handlep)
|
||||
void *handlep;
|
||||
{
|
||||
struct netconfig_vars *ncp = (struct netconfig_vars *)handlep;
|
||||
char *stringp; /* tmp string pointer */
|
||||
struct netconfig_list *list;
|
||||
struct netconfig *np;
|
||||
|
||||
/*
|
||||
* Verify that handle is valid
|
||||
*/
|
||||
if (ncp == NULL || nc_file == NULL) {
|
||||
nc_error = NC_NOTINIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
switch (ncp->valid) {
|
||||
case NC_VALID:
|
||||
/*
|
||||
* If entry has already been read into the list,
|
||||
* we return the entry in the linked list.
|
||||
* If this is the first time call, check if there are any entries in
|
||||
* linked list. If no entries, we need to read the netconfig db.
|
||||
* If we have been here and the next entry is there, we just return
|
||||
* it.
|
||||
*/
|
||||
if (ncp->flag == 0) { /* first time */
|
||||
ncp->flag = 1;
|
||||
ncp->nc_configs = ni.head;
|
||||
if (ncp->nc_configs != NULL) /* entry already exist */
|
||||
return(ncp->nc_configs->ncp);
|
||||
}
|
||||
else if (ncp->nc_configs != NULL && ncp->nc_configs->next != NULL) {
|
||||
ncp->nc_configs = ncp->nc_configs->next;
|
||||
return(ncp->nc_configs->ncp);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we cannot find the entry in the list and is end of file,
|
||||
* we give up.
|
||||
*/
|
||||
if (ni.eof == 1) return(NULL);
|
||||
break;
|
||||
default:
|
||||
nc_error = NC_NOTINIT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
stringp = (char *) malloc(MAXNETCONFIGLINE);
|
||||
if (stringp == NULL)
|
||||
return (NULL);
|
||||
|
||||
#ifdef MEM_CHK
|
||||
if (malloc_verify() == 0) {
|
||||
fprintf(stderr, "memory heap corrupted in getnetconfig\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read a line from netconfig file.
|
||||
*/
|
||||
do {
|
||||
if (fgets(stringp, MAXNETCONFIGLINE, nc_file) == NULL) {
|
||||
free(stringp);
|
||||
ni.eof = 1;
|
||||
return (NULL);
|
||||
}
|
||||
} while (*stringp == '#');
|
||||
|
||||
list = (struct netconfig_list *) malloc(sizeof (struct netconfig_list));
|
||||
if (list == NULL) {
|
||||
free(stringp);
|
||||
return(NULL);
|
||||
}
|
||||
np = (struct netconfig *) malloc(sizeof (struct netconfig));
|
||||
if (np == NULL) {
|
||||
free(stringp);
|
||||
free(list);
|
||||
return(NULL);
|
||||
}
|
||||
list->ncp = np;
|
||||
list->next = NULL;
|
||||
list->ncp->nc_lookups = NULL;
|
||||
list->linep = stringp;
|
||||
if (parse_ncp(stringp, list->ncp) == -1) {
|
||||
free(stringp);
|
||||
free(np);
|
||||
free(list);
|
||||
return (NULL);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If this is the first entry that's been read, it is the head of
|
||||
* the list. If not, put the entry at the end of the list.
|
||||
* Reposition the current pointer of the handle to the last entry
|
||||
* in the list.
|
||||
*/
|
||||
if (ni.head == NULL) { /* first entry */
|
||||
ni.head = ni.tail = list;
|
||||
}
|
||||
else {
|
||||
ni.tail->next = list;
|
||||
ni.tail = ni.tail->next;
|
||||
}
|
||||
ncp->nc_configs = ni.tail;
|
||||
return(ni.tail->ncp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* endnetconfig() may be called to "unbind" or "close" the netconfig database
|
||||
* when processing is complete, releasing resources for reuse. endnetconfig()
|
||||
* may not be called before setnetconfig(). endnetconfig() returns 0 on
|
||||
* success and -1 on failure (for example, if setnetconfig() was not called
|
||||
* previously).
|
||||
*/
|
||||
int
|
||||
endnetconfig(handlep)
|
||||
void *handlep;
|
||||
{
|
||||
struct netconfig_vars *nc_handlep = (struct netconfig_vars *)handlep;
|
||||
|
||||
struct netconfig_list *q, *p;
|
||||
|
||||
/*
|
||||
* Verify that handle is valid
|
||||
*/
|
||||
if (nc_handlep == NULL || (nc_handlep->valid != NC_VALID &&
|
||||
nc_handlep->valid != NC_STORAGE)) {
|
||||
nc_error = NC_NOTINIT;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 if anyone still needs it.
|
||||
*/
|
||||
nc_handlep->valid = NC_INVALID;
|
||||
nc_handlep->flag = 0;
|
||||
nc_handlep->nc_configs = NULL;
|
||||
if (--ni.ref > 0) {
|
||||
free(nc_handlep);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Noone needs these entries anymore, then frees them.
|
||||
* Make sure all info in netconfig_info structure has been reinitialized.
|
||||
*/
|
||||
q = p = ni.head;
|
||||
ni.eof = ni.ref = 0;
|
||||
ni.head = NULL;
|
||||
ni.tail = NULL;
|
||||
while (q) {
|
||||
p = q->next;
|
||||
if (q->ncp->nc_lookups != NULL) free(q->ncp->nc_lookups);
|
||||
free(q->ncp);
|
||||
free(q->linep);
|
||||
free(q);
|
||||
q = p;
|
||||
}
|
||||
free(nc_handlep);
|
||||
|
||||
fclose(nc_file);
|
||||
nc_file = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* getnetconfigent(netid) returns a pointer to the struct netconfig structure
|
||||
* corresponding to netid. It returns NULL if netid is invalid (that is, does
|
||||
* not name an entry in the netconfig database). It returns NULL and sets
|
||||
* errno in case of failure (for example, if the netconfig database cannot be
|
||||
* opened).
|
||||
*/
|
||||
|
||||
struct netconfig *
|
||||
getnetconfigent(netid)
|
||||
char *netid;
|
||||
{
|
||||
FILE *file; /* NETCONFIG db's file pointer */
|
||||
char *linep; /* holds current netconfig line */
|
||||
char *stringp; /* temporary string pointer */
|
||||
struct netconfig *ncp = NULL; /* returned value */
|
||||
struct netconfig_list *list; /* pointer to cache list */
|
||||
|
||||
if (netid == NULL || strlen(netid) == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up table if the entries have already been read and parsed in
|
||||
* getnetconfig(), then copy this entry into a buffer and return it.
|
||||
* If we cannot find the entry in the current list and there are more
|
||||
* entries in the netconfig db that has not been read, we then read the
|
||||
* db and try find the match netid.
|
||||
* If all the netconfig db has been read and placed into the list and
|
||||
* there is no match for the netid, return NULL.
|
||||
*/
|
||||
if (ni.head != NULL) {
|
||||
for (list = ni.head; list; list = list->next) {
|
||||
if (strcmp(list->ncp->nc_netid, netid) == 0) {
|
||||
return(dup_ncp(list->ncp));
|
||||
}
|
||||
}
|
||||
if (ni.eof == 1) /* that's all the entries */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
if ((file = fopen(NETCONFIG, "r")) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((linep = malloc(MAXNETCONFIGLINE)) == NULL) {
|
||||
fclose(file);
|
||||
return (NULL);
|
||||
}
|
||||
do {
|
||||
int len;
|
||||
char *tmpp; /* tmp string pointer */
|
||||
|
||||
do {
|
||||
if ((stringp = fgets(linep, MAXNETCONFIGLINE, file)) == NULL) {
|
||||
break;
|
||||
}
|
||||
} while (*stringp == '#');
|
||||
if (stringp == NULL) { /* eof */
|
||||
break;
|
||||
}
|
||||
if ((tmpp = strpbrk(stringp, "\t ")) == NULL) { /* can't parse file */
|
||||
nc_error = NC_BADFILE;
|
||||
break;
|
||||
}
|
||||
if (strlen(netid) == (len = tmpp - stringp) && /* a match */
|
||||
strncmp(stringp, netid, (size_t)len) == 0) {
|
||||
if ((ncp = (struct netconfig *)
|
||||
malloc(sizeof (struct netconfig))) == NULL) {
|
||||
break;
|
||||
}
|
||||
ncp->nc_lookups = NULL;
|
||||
if (parse_ncp(linep, ncp) == -1) {
|
||||
free(ncp);
|
||||
ncp = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (stringp != NULL);
|
||||
if (ncp == NULL) {
|
||||
free(linep);
|
||||
}
|
||||
fclose(file);
|
||||
return(ncp);
|
||||
}
|
||||
|
||||
/*
|
||||
* freenetconfigent(netconfigp) frees the netconfig structure pointed to by
|
||||
* netconfigp (previously returned by getnetconfigent()).
|
||||
*/
|
||||
|
||||
void
|
||||
freenetconfigent(netconfigp)
|
||||
struct netconfig *netconfigp;
|
||||
{
|
||||
if (netconfigp != NULL) {
|
||||
free(netconfigp->nc_netid); /* holds all netconfigp's strings */
|
||||
if (netconfigp->nc_lookups != NULL)
|
||||
free(netconfigp->nc_lookups);
|
||||
free(netconfigp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse line and stuff it in a struct netconfig
|
||||
* Typical line might look like:
|
||||
* udp tpi_cots vb inet udp /dev/udp /usr/lib/ip.so,/usr/local/ip.so
|
||||
*
|
||||
* We return -1 if any of the tokens don't parse, or malloc fails.
|
||||
*
|
||||
* Note that we modify stringp (putting NULLs after tokens) and
|
||||
* we set the ncp's string field pointers to point to these tokens within
|
||||
* stringp.
|
||||
*/
|
||||
|
||||
static int
|
||||
parse_ncp(stringp, ncp)
|
||||
char *stringp; /* string to parse */
|
||||
struct netconfig *ncp; /* where to put results */
|
||||
{
|
||||
char *tokenp; /* for processing tokens */
|
||||
char *lasts;
|
||||
|
||||
nc_error = NC_BADFILE; /* nearly anything that breaks is for this reason */
|
||||
stringp[strlen(stringp)-1] = '\0'; /* get rid of newline */
|
||||
/* netid */
|
||||
if ((ncp->nc_netid = strtok_r(stringp, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* semantics */
|
||||
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
if (strcmp(tokenp, NC_TPI_COTS_ORD_S) == 0)
|
||||
ncp->nc_semantics = NC_TPI_COTS_ORD;
|
||||
else if (strcmp(tokenp, NC_TPI_COTS_S) == 0)
|
||||
ncp->nc_semantics = NC_TPI_COTS;
|
||||
else if (strcmp(tokenp, NC_TPI_CLTS_S) == 0)
|
||||
ncp->nc_semantics = NC_TPI_CLTS;
|
||||
else if (strcmp(tokenp, NC_TPI_RAW_S) == 0)
|
||||
ncp->nc_semantics = NC_TPI_RAW;
|
||||
else
|
||||
return (-1);
|
||||
|
||||
/* flags */
|
||||
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
for (ncp->nc_flag = NC_NOFLAG; *tokenp != '\0';
|
||||
tokenp++) {
|
||||
switch (*tokenp) {
|
||||
case NC_NOFLAG_C:
|
||||
break;
|
||||
case NC_VISIBLE_C:
|
||||
ncp->nc_flag |= NC_VISIBLE;
|
||||
break;
|
||||
case NC_BROADCAST_C:
|
||||
ncp->nc_flag |= NC_BROADCAST;
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
/* protocol family */
|
||||
if ((ncp->nc_protofmly = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
/* protocol name */
|
||||
if ((ncp->nc_proto = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
/* network device */
|
||||
if ((ncp->nc_device = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
if ((tokenp = strtok_r(NULL, "\t ", &lasts)) == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
if (strcmp(tokenp, NC_NOLOOKUP) == 0) {
|
||||
ncp->nc_nlookups = 0;
|
||||
ncp->nc_lookups = NULL;
|
||||
} else {
|
||||
char *cp; /* tmp string */
|
||||
|
||||
if (ncp->nc_lookups != NULL) /* from last visit */
|
||||
free(ncp->nc_lookups);
|
||||
/* preallocate one string pointer */
|
||||
ncp->nc_lookups = (char **)malloc(sizeof (char *));
|
||||
ncp->nc_nlookups = 0;
|
||||
while ((cp = tokenp) != NULL) {
|
||||
tokenp = _get_next_token(cp, ',');
|
||||
ncp->nc_lookups[(size_t)ncp->nc_nlookups++] = cp;
|
||||
ncp->nc_lookups = (char **)realloc(ncp->nc_lookups,
|
||||
(size_t)(ncp->nc_nlookups+1) *sizeof(char *)); /* for next loop */
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns a string describing the reason for failure.
|
||||
*/
|
||||
char *
|
||||
nc_sperror()
|
||||
{
|
||||
const char *message;
|
||||
|
||||
switch(nc_error) {
|
||||
case NC_NONETCONFIG:
|
||||
message = _nc_errors[0];
|
||||
break;
|
||||
case NC_NOMEM:
|
||||
message = _nc_errors[1];
|
||||
break;
|
||||
case NC_NOTINIT:
|
||||
message = _nc_errors[2];
|
||||
break;
|
||||
case NC_BADFILE:
|
||||
message = _nc_errors[3];
|
||||
break;
|
||||
default:
|
||||
message = "Unknown network selection error";
|
||||
}
|
||||
/* LINTED const castaway */
|
||||
return ((char *)message);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints a message onto standard error describing the reason for failure.
|
||||
*/
|
||||
void
|
||||
nc_perror(s)
|
||||
const char *s;
|
||||
{
|
||||
fprintf(stderr, "%s: %s", s, nc_sperror());
|
||||
}
|
||||
|
||||
/*
|
||||
* Duplicates the matched netconfig buffer.
|
||||
*/
|
||||
static struct netconfig *
|
||||
dup_ncp(ncp)
|
||||
struct netconfig *ncp;
|
||||
{
|
||||
struct netconfig *p;
|
||||
char *tmp;
|
||||
int i;
|
||||
|
||||
if ((tmp=malloc(MAXNETCONFIGLINE)) == NULL)
|
||||
return(NULL);
|
||||
if ((p=(struct netconfig *)malloc(sizeof(struct netconfig))) == NULL) {
|
||||
free(tmp);
|
||||
return(NULL);
|
||||
}
|
||||
/*
|
||||
* First we dup all the data from matched netconfig buffer. Then we
|
||||
* adjust some of the member pointer to a pre-allocated buffer where
|
||||
* contains part of the data.
|
||||
* To follow the convention used in parse_ncp(), we store all the
|
||||
* neccessary information in the pre-allocated buffer and let each
|
||||
* of the netconfig char pointer member point to the right address
|
||||
* in the buffer.
|
||||
*/
|
||||
*p = *ncp;
|
||||
p->nc_netid = (char *)strcpy(tmp,ncp->nc_netid);
|
||||
tmp = strchr(tmp, NULL) + 1;
|
||||
p->nc_protofmly = (char *)strcpy(tmp,ncp->nc_protofmly);
|
||||
tmp = strchr(tmp, NULL) + 1;
|
||||
p->nc_proto = (char *)strcpy(tmp,ncp->nc_proto);
|
||||
tmp = strchr(tmp, NULL) + 1;
|
||||
p->nc_device = (char *)strcpy(tmp,ncp->nc_device);
|
||||
p->nc_lookups = (char **)malloc((size_t)(p->nc_nlookups+1) * sizeof(char *));
|
||||
if (p->nc_lookups == NULL) {
|
||||
free(p->nc_netid);
|
||||
return(NULL);
|
||||
}
|
||||
for (i=0; i < p->nc_nlookups; i++) {
|
||||
tmp = strchr(tmp, NULL) + 1;
|
||||
p->nc_lookups[i] = (char *)strcpy(tmp,ncp->nc_lookups[i]);
|
||||
}
|
||||
return(p);
|
||||
}
|
154
lib/libc/rpc/getnetpath.3
Normal file
154
lib/libc/rpc/getnetpath.3
Normal file
@ -0,0 +1,154 @@
|
||||
.\" @(#)getnetpath.3n 1.26 93/05/07 SMI; from SVr4
|
||||
.\" $NetBSD: getnetpath.3,v 1.1 2000/06/02 23:11:11 fvdl Exp $
|
||||
.\" $FreeBSD$
|
||||
.\" Copyright 1989 AT&T
|
||||
.Dd April 22, 2000
|
||||
.Dt GETNETPATH 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm getnetpath ,
|
||||
.Nm setnetpath ,
|
||||
.Nm endnetpath
|
||||
.Nd get
|
||||
.Pa /etc/netconfig
|
||||
entry corresponding to
|
||||
.Ev NETPATH
|
||||
component
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netconfig.h>
|
||||
.Ft "struct netconfig *"
|
||||
.Fn getnetpath "void *handlep"
|
||||
.Ft "void *"
|
||||
.Fn setnetpath "void"
|
||||
.Ft int
|
||||
.Fn endnetpath "void *handlep"
|
||||
.Sh DESCRIPTION
|
||||
The routines described in this page provide the application access to the system
|
||||
network configuration database,
|
||||
.Pa /etc/netconfig ,
|
||||
as it is
|
||||
.Dq filtered
|
||||
by the
|
||||
.Ev NETPATH
|
||||
environment variable (see
|
||||
.Xr environ 5 ) .
|
||||
See
|
||||
.Xr getnetconfig 3
|
||||
for other routines that also access the
|
||||
network configuration database directly.
|
||||
The
|
||||
.Ev NETPATH
|
||||
variable is a list of colon-separated network identifiers.
|
||||
.Pp
|
||||
.Fn getnetpath
|
||||
returns a pointer to the
|
||||
netconfig database entry corresponding to the first valid
|
||||
.Ev NETPATH
|
||||
component.
|
||||
The netconfig entry is formatted as a
|
||||
.Ft "struct netconfig" .
|
||||
On each subsequent call,
|
||||
.Fn getnetpath
|
||||
returns a pointer to the netconfig entry that corresponds to the next
|
||||
valid
|
||||
.Ev NETPATH
|
||||
component.
|
||||
.Fn getnetpath
|
||||
can thus be used to search the netconfig database for all networks
|
||||
included in the
|
||||
.Ev NETPATH
|
||||
variable.
|
||||
When
|
||||
.Ev NETPATH
|
||||
has been exhausted,
|
||||
.Fn getnetpath
|
||||
returns
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
A call to
|
||||
.Fn setnetpath
|
||||
.Dq binds
|
||||
to or
|
||||
.Dq rewinds
|
||||
.Ev NETPATH .
|
||||
.Fn setnetpath
|
||||
must be called before the first call to
|
||||
.Fn getnetpath
|
||||
and may be called at any other time.
|
||||
It returns a handle that is used by
|
||||
.Fn getnetpath .
|
||||
.Pp
|
||||
.Fn getnetpath
|
||||
silently ignores invalid
|
||||
.Ev NETPATH
|
||||
components.
|
||||
A
|
||||
.Ev NETPATH
|
||||
component is invalid if there is no corresponding
|
||||
entry in the netconfig database.
|
||||
.Pp
|
||||
If the
|
||||
.Ev NETPATH
|
||||
variable is unset,
|
||||
.Fn getnetpath
|
||||
behaves as if
|
||||
.Ev NETPATH
|
||||
were set to the sequence of
|
||||
.Dq default
|
||||
or
|
||||
.Dq visible
|
||||
networks in the netconfig database, in the
|
||||
order in which they are listed.
|
||||
.\"This proviso holds also for this
|
||||
.\"whole manpage.
|
||||
.Pp
|
||||
.Fn endnetpath
|
||||
may be called to
|
||||
.Dq unbind
|
||||
from
|
||||
.Ev NETPATH
|
||||
when processing is complete, releasing resources for reuse.
|
||||
Programmers should be aware, however, that
|
||||
.Fn endnetpath
|
||||
frees all memory allocated by
|
||||
.Fn getnetpath
|
||||
for the struct netconfig data structure.
|
||||
.Sh RETURN VALUES
|
||||
.Fn setnetpath
|
||||
returns a handle that is used by
|
||||
.Fn getnetpath .
|
||||
In case of an error,
|
||||
.Fn setnetpath
|
||||
returns
|
||||
.Dv NULL .
|
||||
.Pp
|
||||
.Fn endnetpath
|
||||
returns 0 on success and \-1 on failure
|
||||
(for example, if
|
||||
.Fn setnetpath
|
||||
was not called previously).
|
||||
.Fn nc_perror
|
||||
or
|
||||
.Fn nc_sperror
|
||||
can be used to print out the reason for failure.
|
||||
See
|
||||
.Xr getnetconfig 3 .
|
||||
.Pp
|
||||
When first called,
|
||||
.Fn getnetpath
|
||||
returns a pointer to the netconfig database entry corresponding to the first
|
||||
valid
|
||||
.Ev NETPATH
|
||||
component.
|
||||
When
|
||||
.Ev NETPATH
|
||||
has been exhausted,
|
||||
.Fn getnetpath
|
||||
returns
|
||||
.Dv NULL .
|
||||
.Sh SEE ALSO
|
||||
.Xr getnetconfig 3 ,
|
||||
.Xr environ 5 ,
|
||||
.Xr netconfig 5
|
273
lib/libc/rpc/getnetpath.c
Normal file
273
lib/libc/rpc/getnetpath.c
Normal file
@ -0,0 +1,273 @@
|
||||
/* $NetBSD: getnetpath.c,v 1.3 2000/07/06 03:10:34 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user or with the express written consent of
|
||||
* Sun Microsystems, Inc.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)getnetpath.c 1.11 91/12/19 SMI";
|
||||
#endif
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/cdefs.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <netconfig.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* internal structure to keep track of a netpath "session"
|
||||
*/
|
||||
struct netpath_chain {
|
||||
struct netconfig *ncp; /* an nconf entry */
|
||||
struct netpath_chain *nchain_next; /* next nconf entry allocated */
|
||||
};
|
||||
|
||||
|
||||
struct netpath_vars {
|
||||
int valid; /* token that indicates a valid netpath_vars */
|
||||
void *nc_handlep; /* handle for current netconfig "session" */
|
||||
char *netpath; /* pointer to current view-point in NETPATH */
|
||||
char *netpath_start; /* pointer to start of our copy of NETPATH */
|
||||
struct netpath_chain *ncp_list; /* list of nconfs allocated this session*/
|
||||
};
|
||||
|
||||
#define NP_VALID 0xf00d
|
||||
#define NP_INVALID 0
|
||||
|
||||
char *_get_next_token __P((char *, int));
|
||||
|
||||
|
||||
/*
|
||||
* A call to setnetpath() establishes a NETPATH "session". setnetpath()
|
||||
* must be called before the first call to getnetpath(). A "handle" is
|
||||
* returned to distinguish the session; this handle should be passed
|
||||
* subsequently to getnetpath(). (Handles are used to allow for nested calls
|
||||
* to setnetpath()).
|
||||
* If setnetpath() is unable to establish a session (due to lack of memory
|
||||
* resources, or the absence of the /etc/netconfig file), a NULL pointer is
|
||||
* returned.
|
||||
*/
|
||||
|
||||
void *
|
||||
setnetpath()
|
||||
{
|
||||
|
||||
struct netpath_vars *np_sessionp; /* this session's variables */
|
||||
char *npp; /* NETPATH env variable */
|
||||
|
||||
#ifdef MEM_CHK
|
||||
malloc_debug(1);
|
||||
#endif
|
||||
|
||||
if ((np_sessionp =
|
||||
(struct netpath_vars *)malloc(sizeof (struct netpath_vars))) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
if ((np_sessionp->nc_handlep = setnetconfig()) == NULL) {
|
||||
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||
return (NULL);
|
||||
}
|
||||
np_sessionp->valid = NP_VALID;
|
||||
np_sessionp->ncp_list = NULL;
|
||||
if ((npp = getenv(NETPATH)) == NULL) {
|
||||
np_sessionp->netpath = NULL;
|
||||
} else {
|
||||
(void) endnetconfig(np_sessionp->nc_handlep);/* won't need nc session*/
|
||||
np_sessionp->nc_handlep = NULL;
|
||||
if ((np_sessionp->netpath = malloc(strlen(npp)+1)) == NULL) {
|
||||
free(np_sessionp);
|
||||
return (NULL);
|
||||
} else {
|
||||
(void) strcpy(np_sessionp->netpath, npp);
|
||||
}
|
||||
}
|
||||
np_sessionp->netpath_start = np_sessionp->netpath;
|
||||
return ((void *)np_sessionp);
|
||||
}
|
||||
|
||||
/*
|
||||
* When first called, getnetpath() returns a pointer to the netconfig
|
||||
* database entry corresponding to the first valid NETPATH component. The
|
||||
* netconfig entry is formatted as a struct netconfig.
|
||||
* On each subsequent call, getnetpath returns a pointer to the netconfig
|
||||
* entry that corresponds to the next valid NETPATH component. getnetpath
|
||||
* can thus be used to search the netconfig database for all networks
|
||||
* included in the NETPATH variable.
|
||||
* When NETPATH has been exhausted, getnetpath() returns NULL. It returns
|
||||
* NULL and sets errno in case of an error (e.g., setnetpath was not called
|
||||
* previously).
|
||||
* getnetpath() silently ignores invalid NETPATH components. A NETPATH
|
||||
* compnent is invalid if there is no corresponding entry in the netconfig
|
||||
* database.
|
||||
* If the NETPATH variable is unset, getnetpath() behaves as if NETPATH
|
||||
* were set to the sequence of default or visible networks in the netconfig
|
||||
* database, in the order in which they are listed.
|
||||
*/
|
||||
|
||||
struct netconfig *
|
||||
getnetpath(handlep)
|
||||
void *handlep;
|
||||
{
|
||||
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
|
||||
struct netconfig *ncp = NULL; /* temp. holds a netconfig session */
|
||||
struct netpath_chain *chainp; /* holds chain of ncp's we alloc */
|
||||
char *npp; /* holds current NETPATH */
|
||||
|
||||
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (np_sessionp->netpath_start == NULL) { /* NETPATH was not set */
|
||||
do { /* select next visible network */
|
||||
if (np_sessionp->nc_handlep == NULL) {
|
||||
np_sessionp->nc_handlep = setnetconfig();
|
||||
if (np_sessionp->nc_handlep == NULL)
|
||||
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||
}
|
||||
if ((ncp = getnetconfig(np_sessionp->nc_handlep)) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
} while ((ncp->nc_flag & NC_VISIBLE) == 0);
|
||||
return (ncp);
|
||||
}
|
||||
/*
|
||||
* Find first valid network ID in netpath.
|
||||
*/
|
||||
while ((npp = np_sessionp->netpath) != NULL && strlen(npp) != 0) {
|
||||
np_sessionp->netpath = _get_next_token(npp, ':');
|
||||
/*
|
||||
* npp is a network identifier.
|
||||
*/
|
||||
if ((ncp = getnetconfigent(npp)) != NULL) {
|
||||
chainp = (struct netpath_chain *) /* cobble alloc chain entry */
|
||||
malloc(sizeof (struct netpath_chain));
|
||||
chainp->ncp = ncp;
|
||||
chainp->nchain_next = NULL;
|
||||
if (np_sessionp->ncp_list == NULL) {
|
||||
np_sessionp->ncp_list = chainp;
|
||||
} else {
|
||||
np_sessionp->ncp_list->nchain_next = chainp;
|
||||
}
|
||||
return (ncp);
|
||||
}
|
||||
/* couldn't find this token in the database; go to next one. */
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* endnetpath() may be called to unbind NETPATH when processing is complete,
|
||||
* releasing resources for reuse. It returns 0 on success and -1 on failure
|
||||
* (e.g. if setnetpath() was not called previously.
|
||||
*/
|
||||
int
|
||||
endnetpath(handlep)
|
||||
void *handlep;
|
||||
{
|
||||
struct netpath_vars *np_sessionp = (struct netpath_vars *)handlep;
|
||||
struct netpath_chain *chainp, *lastp;
|
||||
|
||||
if (np_sessionp == NULL || np_sessionp->valid != NP_VALID) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
if (np_sessionp->nc_handlep != NULL)
|
||||
endnetconfig(np_sessionp->nc_handlep);
|
||||
if (np_sessionp->netpath_start != NULL)
|
||||
free(np_sessionp->netpath_start);
|
||||
for (chainp = np_sessionp->ncp_list; chainp != NULL;
|
||||
lastp=chainp, chainp=chainp->nchain_next, free(lastp)) {
|
||||
freenetconfigent(chainp->ncp);
|
||||
}
|
||||
free(np_sessionp);
|
||||
#ifdef MEM_CHK
|
||||
if (malloc_verify() == 0) {
|
||||
fprintf(stderr, "memory heap corrupted in endnetpath\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Returns pointer to the rest-of-the-string after the current token.
|
||||
* The token itself starts at arg, and we null terminate it. We return NULL
|
||||
* if either the arg is empty, or if this is the last token.
|
||||
*/
|
||||
|
||||
char *
|
||||
_get_next_token(npp, token)
|
||||
char *npp; /* string */
|
||||
int token; /* char to parse string for */
|
||||
{
|
||||
char *cp; /* char pointer */
|
||||
char *np; /* netpath pointer */
|
||||
char *ep; /* escape pointer */
|
||||
|
||||
if ((cp = strchr(npp, token)) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* did find a token, but it might be escaped.
|
||||
*/
|
||||
if (cp[-1] == '\\') {
|
||||
/* if slash was also escaped, carry on, otherwise find next token */
|
||||
if (cp[-2] != '\\') {
|
||||
/* shift r-o-s onto the escaped token */
|
||||
strcpy(&cp[-1], cp); /* XXX: overlapping string copy */
|
||||
/*
|
||||
* Do a recursive call.
|
||||
* We don't know how many escaped tokens there might be.
|
||||
*/
|
||||
return (_get_next_token(cp, token));
|
||||
}
|
||||
}
|
||||
|
||||
*cp++ = '\0'; /* null-terminate token */
|
||||
/* get rid of any backslash escapes */
|
||||
ep = npp;
|
||||
while ((np = strchr(ep, '\\')) != 0) {
|
||||
if (np[1] == '\\')
|
||||
np++;
|
||||
strcpy(np, (ep = &np[1])); /* XXX: overlapping string copy */
|
||||
}
|
||||
return (cp); /* return ptr to r-o-s */
|
||||
}
|
@ -41,6 +41,7 @@ static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
|
||||
/*
|
||||
* Public key lookup routines
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <rpc/rpc.h>
|
||||
@ -49,6 +50,7 @@ static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define PKFILE "/etc/publickey"
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" @(#)getrpcent.3n 2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
|
||||
.\" $NetBSD: getrpcent.3,v 1.6 1998/02/05 18:49:06 perry Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 14, 1987
|
||||
@ -11,6 +12,8 @@
|
||||
.Nm endrpcent ,
|
||||
.Nm setrpcent
|
||||
.Nd get RPC entry
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <rpc/rpc.h>
|
||||
.Ft struct rpcent *
|
||||
@ -24,19 +27,17 @@
|
||||
.Ft void
|
||||
.Fn endrpcent void
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getrpcent ,
|
||||
.Fn getrpcbyname ,
|
||||
and
|
||||
.Fn getrpcbynumber
|
||||
functions each return a pointer to an object with the
|
||||
each return a pointer to an object with the
|
||||
following structure
|
||||
containing the broken-out
|
||||
fields of a line in the rpc program number data base,
|
||||
.Pa /etc/rpc .
|
||||
.Pa /etc/rpc :
|
||||
.Bd -literal
|
||||
|
||||
struct rpcent {
|
||||
struct rpcent {
|
||||
char *r_name; /* name of server for this rpc program */
|
||||
char **r_aliases; /* alias list */
|
||||
long r_number; /* rpc program number */
|
||||
@ -44,29 +45,28 @@ struct rpcent {
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width r_aliasesxxx
|
||||
.It Fa r_name
|
||||
.Bl -tag -width r_aliases -offset indent
|
||||
.It Va r_name
|
||||
The name of the server for this rpc program.
|
||||
.It Fa r_aliases
|
||||
.It Va r_aliases
|
||||
A zero terminated list of alternate names for the rpc program.
|
||||
.It Fa r_number
|
||||
.It Va r_number
|
||||
The rpc program number for this service.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn getrpcent
|
||||
function reads the next line of the file, opening the file if necessary.
|
||||
The
|
||||
reads the next line of the file, opening the file if necessary.
|
||||
.Pp
|
||||
.Fn setrpcent
|
||||
function opens and rewinds the file. If the
|
||||
opens and rewinds the file. If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
the net data base will not be closed after each call to
|
||||
.Fn getrpcent
|
||||
(either directly, or indirectly through one of
|
||||
the other
|
||||
.Fn getrpcent
|
||||
function family.
|
||||
.Dq getrpc
|
||||
calls).
|
||||
.Pp
|
||||
.Fn endrpcent
|
||||
closes the file.
|
||||
@ -81,7 +81,7 @@ program number is found, or until end-of-file is encountered.
|
||||
.Bl -tag -width /etc/rpc -compact
|
||||
.It Pa /etc/rpc
|
||||
.El
|
||||
.Sh "SEE ALSO"
|
||||
.Sh SEE ALSO
|
||||
.Xr rpc 5 ,
|
||||
.Xr rpcinfo 8 ,
|
||||
.Xr ypserv 8
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: getrpcent.c,v 1.17 2000/01/22 22:19:17 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -28,8 +30,9 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
|
||||
static char *sccsid = "@(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -37,20 +40,29 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (c) 1984 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#ifdef YP
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* Internet version.
|
||||
*/
|
||||
struct rpcdata {
|
||||
static struct rpcdata {
|
||||
FILE *rpcf;
|
||||
int stayopen;
|
||||
#define MAXALIASES 35
|
||||
@ -64,21 +76,21 @@ struct rpcdata {
|
||||
#endif
|
||||
} *rpcdata;
|
||||
|
||||
static struct rpcent *interpret __P((char *val, size_t len));
|
||||
|
||||
#ifdef YP
|
||||
static int __yp_nomap = 0;
|
||||
extern int _yp_check(char **);
|
||||
#endif /* YP */
|
||||
|
||||
static struct rpcent *interpret();
|
||||
struct hostent *gethostent();
|
||||
char *inet_ntoa();
|
||||
#define RPCDB "/etc/rpc"
|
||||
|
||||
static char RPCDB[] = "/etc/rpc";
|
||||
static struct rpcdata *_rpcdata __P((void));
|
||||
|
||||
static struct rpcdata *
|
||||
_rpcdata()
|
||||
{
|
||||
register struct rpcdata *d = rpcdata;
|
||||
struct rpcdata *d = rpcdata;
|
||||
|
||||
if (d == 0) {
|
||||
d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
|
||||
@ -89,14 +101,14 @@ _rpcdata()
|
||||
|
||||
struct rpcent *
|
||||
getrpcbynumber(number)
|
||||
register int number;
|
||||
int number;
|
||||
{
|
||||
register struct rpcdata *d = _rpcdata();
|
||||
register struct rpcent *p;
|
||||
#ifdef YP
|
||||
int reason;
|
||||
char adrstr[16];
|
||||
#endif
|
||||
struct rpcent *p;
|
||||
struct rpcdata *d = _rpcdata();
|
||||
|
||||
if (d == 0)
|
||||
return (0);
|
||||
@ -123,8 +135,9 @@ getrpcbynumber(number)
|
||||
}
|
||||
no_yp:
|
||||
#endif /* YP */
|
||||
|
||||
setrpcent(0);
|
||||
while ((p = getrpcent())) {
|
||||
while ((p = getrpcent()) != NULL) {
|
||||
if (p->r_number == number)
|
||||
break;
|
||||
}
|
||||
@ -139,8 +152,10 @@ getrpcbyname(name)
|
||||
struct rpcent *rpc = NULL;
|
||||
char **rp;
|
||||
|
||||
assert(name != NULL);
|
||||
|
||||
setrpcent(0);
|
||||
while ((rpc = getrpcent())) {
|
||||
while ((rpc = getrpcent()) != NULL) {
|
||||
if (strcmp(rpc->r_name, name) == 0)
|
||||
goto done;
|
||||
for (rp = rpc->r_aliases; *rp != NULL; rp++) {
|
||||
@ -157,7 +172,7 @@ void
|
||||
setrpcent(f)
|
||||
int f;
|
||||
{
|
||||
register struct rpcdata *d = _rpcdata();
|
||||
struct rpcdata *d = _rpcdata();
|
||||
|
||||
if (d == 0)
|
||||
return;
|
||||
@ -181,7 +196,7 @@ setrpcent(f)
|
||||
void
|
||||
endrpcent()
|
||||
{
|
||||
register struct rpcdata *d = _rpcdata();
|
||||
struct rpcdata *d = _rpcdata();
|
||||
|
||||
if (d == 0)
|
||||
return;
|
||||
@ -204,7 +219,7 @@ endrpcent()
|
||||
struct rpcent *
|
||||
getrpcent()
|
||||
{
|
||||
register struct rpcdata *d = _rpcdata();
|
||||
struct rpcdata *d = _rpcdata();
|
||||
#ifdef YP
|
||||
struct rpcent *hp;
|
||||
int reason;
|
||||
@ -255,11 +270,13 @@ getrpcent()
|
||||
static struct rpcent *
|
||||
interpret(val, len)
|
||||
char *val;
|
||||
int len;
|
||||
size_t len;
|
||||
{
|
||||
register struct rpcdata *d = _rpcdata();
|
||||
struct rpcdata *d = _rpcdata();
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
char *cp, **q;
|
||||
|
||||
assert(val != NULL);
|
||||
|
||||
if (d == 0)
|
||||
return (0);
|
||||
|
@ -7,6 +7,8 @@
|
||||
.Sh NAME
|
||||
.Nm getrpcport
|
||||
.Nd get RPC port number
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Ft int
|
||||
.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: getrpcport.c,v 1.16 2000/01/22 22:19:18 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
|
||||
/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)getrpcport.c 1.3 87/08/11 SMI";
|
||||
static char *sccsid = "@(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -37,12 +40,18 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (c) 1985 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
int
|
||||
getrpcport(host, prognum, versnum, proto)
|
||||
@ -52,12 +61,18 @@ getrpcport(host, prognum, versnum, proto)
|
||||
struct sockaddr_in addr;
|
||||
struct hostent *hp;
|
||||
|
||||
assert(host != NULL);
|
||||
|
||||
if ((hp = gethostbyname(host)) == NULL)
|
||||
return (0);
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_len = sizeof(struct sockaddr_in);
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 0;
|
||||
memcpy((char *)&addr.sin_addr, hp->h_addr, hp->h_length);
|
||||
return (pmap_getport(&addr, prognum, versnum, proto));
|
||||
if (hp->h_length > addr.sin_len)
|
||||
hp->h_length = addr.sin_len;
|
||||
memcpy(&addr.sin_addr.s_addr, hp->h_addr, (size_t)hp->h_length);
|
||||
/* Inconsistent interfaces need casts! :-( */
|
||||
return (pmap_getport(&addr, (u_long)prognum, (u_long)versnum,
|
||||
(u_int)proto));
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
* gendeskey(deskey) - generate a secure des key
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -53,6 +54,7 @@
|
||||
#include <rpc/auth_unix.h>
|
||||
#include <rpc/key_prot.h>
|
||||
#include <string.h>
|
||||
#include <netconfig.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
@ -232,7 +234,7 @@ key_gendes(key)
|
||||
|
||||
int
|
||||
key_setnet(arg)
|
||||
struct netstarg *arg;
|
||||
struct key_netstarg *arg;
|
||||
{
|
||||
keystatus status;
|
||||
|
||||
@ -276,7 +278,6 @@ struct key_call_private {
|
||||
};
|
||||
static struct key_call_private *key_call_private_main = NULL;
|
||||
|
||||
#ifdef foo
|
||||
static void
|
||||
key_call_destroy(void *vp)
|
||||
{
|
||||
@ -288,7 +289,6 @@ key_call_destroy(void *vp)
|
||||
free(kcp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Keep the handle cached. This call may be made quite often.
|
||||
@ -297,21 +297,40 @@ static CLIENT *
|
||||
getkeyserv_handle(vers)
|
||||
int vers;
|
||||
{
|
||||
void *localhandle;
|
||||
struct netconfig *nconf;
|
||||
struct netconfig *tpconf;
|
||||
struct key_call_private *kcp = key_call_private_main;
|
||||
struct timeval wait_time;
|
||||
struct utsname u;
|
||||
int main_thread;
|
||||
int fd;
|
||||
struct sockaddr_un name;
|
||||
int namelen = sizeof(struct sockaddr_un);
|
||||
static thread_key_t key_call_key;
|
||||
extern mutex_t tsd_lock;
|
||||
|
||||
#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */
|
||||
#define TOTAL_TRIES 5 /* Number of tries */
|
||||
|
||||
if ((main_thread = thr_main())) {
|
||||
kcp = key_call_private_main;
|
||||
} else {
|
||||
if (key_call_key == 0) {
|
||||
mutex_lock(&tsd_lock);
|
||||
if (key_call_key == 0)
|
||||
thr_keycreate(&key_call_key, key_call_destroy);
|
||||
mutex_unlock(&tsd_lock);
|
||||
}
|
||||
kcp = (struct key_call_private *)thr_getspecific(key_call_key);
|
||||
}
|
||||
if (kcp == (struct key_call_private *)NULL) {
|
||||
kcp = (struct key_call_private *)malloc(sizeof (*kcp));
|
||||
if (kcp == (struct key_call_private *)NULL) {
|
||||
return ((CLIENT *) NULL);
|
||||
}
|
||||
key_call_private_main = kcp;
|
||||
if (main_thread)
|
||||
key_call_private_main = kcp;
|
||||
else
|
||||
thr_setspecific(key_call_key, (void *) kcp);
|
||||
kcp->client = NULL;
|
||||
}
|
||||
|
||||
@ -321,16 +340,6 @@ int vers;
|
||||
kcp->client = NULL;
|
||||
}
|
||||
|
||||
if (kcp->client != NULL) {
|
||||
/* if other side closed socket, build handle again */
|
||||
clnt_control(kcp->client, CLGET_FD, (char *)&fd);
|
||||
if (_getpeername(fd,(struct sockaddr *)&name,&namelen) == -1) {
|
||||
auth_destroy(kcp->client->cl_auth);
|
||||
clnt_destroy(kcp->client);
|
||||
kcp->client = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (kcp->client != NULL) {
|
||||
/* if uid has changed, build client handle again */
|
||||
if (kcp->uid != geteuid()) {
|
||||
@ -348,15 +357,51 @@ int vers;
|
||||
clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
|
||||
return (kcp->client);
|
||||
}
|
||||
if (!(localhandle = setnetconfig())) {
|
||||
return ((CLIENT *) NULL);
|
||||
}
|
||||
tpconf = NULL;
|
||||
#if defined(i386)
|
||||
#if defined(__FreeBSD__)
|
||||
if (uname(&u) == -1)
|
||||
#else
|
||||
if (_nuname(&u) == -1)
|
||||
#endif
|
||||
#elif defined(sparc)
|
||||
if (_uname(&u) == -1)
|
||||
#else
|
||||
#error Unknown architecture!
|
||||
#endif
|
||||
{
|
||||
endnetconfig(localhandle);
|
||||
return ((CLIENT *) NULL);
|
||||
}
|
||||
|
||||
if ((kcp->client == (CLIENT *) NULL))
|
||||
/* Use the AF_UNIX transport */
|
||||
kcp->client = clnt_create("/var/run/keyservsock", KEY_PROG,
|
||||
vers, "unix");
|
||||
while (nconf = getnetconfig(localhandle)) {
|
||||
if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
|
||||
/*
|
||||
* We use COTS_ORD here so that the caller can
|
||||
* find out immediately if the server is dead.
|
||||
*/
|
||||
if (nconf->nc_semantics == NC_TPI_COTS_ORD) {
|
||||
kcp->client = clnt_tp_create(u.nodename,
|
||||
KEY_PROG, vers, nconf);
|
||||
if (kcp->client)
|
||||
break;
|
||||
} else {
|
||||
tpconf = nconf;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((kcp->client == (CLIENT *) NULL) && (tpconf))
|
||||
/* Now, try the CLTS or COTS loopback transport */
|
||||
kcp->client = clnt_tp_create(u.nodename,
|
||||
KEY_PROG, vers, tpconf);
|
||||
endnetconfig(localhandle);
|
||||
|
||||
if (kcp->client == (CLIENT *) NULL) {
|
||||
return ((CLIENT *) NULL);
|
||||
}
|
||||
}
|
||||
kcp->uid = geteuid();
|
||||
kcp->pid = getpid();
|
||||
kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL);
|
||||
|
@ -3,7 +3,9 @@
|
||||
* It was generated using rpcgen.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <rpc/key_prot.h>
|
||||
#include "un-namespace.h"
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -32,8 +34,8 @@
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
#pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI"
|
||||
|
||||
/* From: #pragma ident "@(#)key_prot.x 1.7 94/04/29 SMI" */
|
||||
/* $FreeBSD$ */
|
||||
/* Copyright (c) 1990, 1991 Sun Microsystems, Inc. */
|
||||
|
||||
/*
|
||||
|
125
lib/libc/rpc/mt_misc.c
Normal file
125
lib/libc/rpc/mt_misc.c
Normal file
@ -0,0 +1,125 @@
|
||||
/* $NetBSD: mt_misc.c,v 1.1 2000/06/02 23:11:11 fvdl Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/* #pragma ident "@(#)mt_misc.c 1.24 93/04/29 SMI" */
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <rpc/rpc.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdlib.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/* protects the services list (svc.c) */
|
||||
pthread_rwlock_t svc_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
/* protects svc_fdset and the xports[] array */
|
||||
pthread_rwlock_t svc_fd_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
/* protects the RPCBIND address cache */
|
||||
pthread_rwlock_t rpcbaddr_cache_lock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
/* protects authdes cache (svcauth_des.c) */
|
||||
pthread_mutex_t authdes_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* serializes authdes ops initializations */
|
||||
pthread_mutex_t authdes_ops_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects des stats list */
|
||||
pthread_mutex_t svcauthdesstats_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#ifdef KERBEROS
|
||||
/* auth_kerb.c serialization */
|
||||
pthread_mutex_t authkerb_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
/* protects kerb stats list */
|
||||
pthread_mutex_t svcauthkerbstats_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif /* KERBEROS */
|
||||
|
||||
/* auth_none.c serialization */
|
||||
pthread_mutex_t authnone_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects the Auths list (svc_auth.c) */
|
||||
pthread_mutex_t authsvc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects client-side fd lock array */
|
||||
pthread_mutex_t clnt_fd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* clnt_raw.c serialization */
|
||||
pthread_mutex_t clntraw_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* domainname and domain_fd (getdname.c) and default_domain (rpcdname.c) */
|
||||
pthread_mutex_t dname_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* dupreq variables (svc_dg.c) */
|
||||
pthread_mutex_t dupreq_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects first_time and hostname (key_call.c) */
|
||||
pthread_mutex_t keyserv_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* serializes rpc_trace() (rpc_trace.c) */
|
||||
pthread_mutex_t libnsl_trace_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* loopnconf (rpcb_clnt.c) */
|
||||
pthread_mutex_t loopnconf_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* serializes ops initializations */
|
||||
pthread_mutex_t ops_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects ``port'' static in bindresvport() */
|
||||
pthread_mutex_t portnum_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects proglst list (svc_simple.c) */
|
||||
pthread_mutex_t proglst_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* serializes clnt_com_create() (rpc_soc.c) */
|
||||
pthread_mutex_t rpcsoc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* svc_raw.c serialization */
|
||||
pthread_mutex_t svcraw_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects TSD key creation */
|
||||
pthread_mutex_t tsd_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* protects netconfig list */
|
||||
pthread_mutex_t nc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* xprtlist (svc_generic.c) */
|
||||
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
/* serializes calls to public key routines */
|
||||
pthread_mutex_t serialize_pkey = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
#undef rpc_createerr
|
||||
|
||||
struct rpc_createerr rpc_createerr;
|
||||
|
||||
struct rpc_createerr *
|
||||
__rpc_createerr()
|
||||
{
|
||||
static thread_key_t rce_key = 0;
|
||||
struct rpc_createerr *rce_addr = 0;
|
||||
|
||||
if (thr_main())
|
||||
return (&rpc_createerr);
|
||||
if ((rce_addr =
|
||||
(struct rpc_createerr *)thr_getspecific(rce_key)) != 0) {
|
||||
mutex_lock(&tsd_lock);
|
||||
if (thr_keycreate(&rce_key, free) != 0) {
|
||||
mutex_unlock(&tsd_lock);
|
||||
return (&rpc_createerr);
|
||||
}
|
||||
mutex_unlock(&tsd_lock);
|
||||
}
|
||||
if (!rce_addr) {
|
||||
rce_addr = (struct rpc_createerr *)
|
||||
malloc(sizeof (struct rpc_createerr));
|
||||
if (thr_setspecific(rce_key, (void *) rce_addr) != 0) {
|
||||
if (rce_addr)
|
||||
free(rce_addr);
|
||||
return (&rpc_createerr);
|
||||
}
|
||||
memset(rce_addr, 0, sizeof (struct rpc_createerr));
|
||||
return (rce_addr);
|
||||
}
|
||||
return (rce_addr);
|
||||
}
|
126
lib/libc/rpc/netconfig.5
Normal file
126
lib/libc/rpc/netconfig.5
Normal file
@ -0,0 +1,126 @@
|
||||
.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $
|
||||
.\" $NetBSD: netconfig.5,v 1.2 2000/11/08 13:18:28 lukem Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd November 17, 2000
|
||||
.Dt NETCONFIG 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm netconfig
|
||||
.Nd network configuration data base
|
||||
.Sh SYNOPSIS
|
||||
.Pa /etc/netconfig
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
file defines a list of
|
||||
.Dq transport names ,
|
||||
describing their semantics and protocol.
|
||||
In
|
||||
.Fx ,
|
||||
this file is only used by the RPC library code.
|
||||
.Pp
|
||||
Entries have the following format:
|
||||
.Pp
|
||||
.Ar network_id semantics flags family protoname device libraries
|
||||
.Pp
|
||||
Entries consist of the following fields:
|
||||
.Bl -tag -width network_id
|
||||
.It Ar network_id
|
||||
The name of the transport described.
|
||||
.It Ar semantics
|
||||
Describes the semantics of the transport.
|
||||
This can be one of:
|
||||
.Bl -tag -width tpi_cots_ord -offset indent
|
||||
.It Sy tpi_clts
|
||||
Connectionless transport.
|
||||
.It Sy tpi_cots
|
||||
Connection-oriented transport
|
||||
.It Sy tpi_cots_ord
|
||||
Connection-oriented, ordered transport.
|
||||
.It Sy tpi_raw
|
||||
A raw connection.
|
||||
.El
|
||||
.It Ar flags
|
||||
This field is either blank (specified by
|
||||
.Dq Li - ) ,
|
||||
or contains a
|
||||
.Dq Li v ,
|
||||
meaning visible to the
|
||||
.Xr getnetconfig 3
|
||||
function.
|
||||
.It Ar family
|
||||
The protocol family of the transport.
|
||||
This is currently one of:
|
||||
.Bl -tag -width loopback -offset indent
|
||||
.It Sy inet6
|
||||
The IPv6
|
||||
.Pq Dv PF_INET6
|
||||
family of protocols.
|
||||
.It Sy inet
|
||||
The IPv4
|
||||
.Pq Dv PF_INET
|
||||
family of protocols.
|
||||
.It Sy loopback
|
||||
The
|
||||
.Dv PF_LOCAL
|
||||
protocol family.
|
||||
.El
|
||||
.It Ar protoname
|
||||
The name of the protocol used for this transport.
|
||||
Can currently be either
|
||||
.Sy udp ,
|
||||
.Sy tcp
|
||||
or empty.
|
||||
.It Ar device
|
||||
This field is always empty in
|
||||
.Fx .
|
||||
.It Ar libraries
|
||||
This field is always empty in
|
||||
.Fx .
|
||||
.El
|
||||
.Pp
|
||||
The order of entries in this file will determine which transport will
|
||||
be preferred by the RPC library code, given a match on a specified
|
||||
network type.
|
||||
For example, if a sample network config file would look like this:
|
||||
.Bd -literal -offset indent
|
||||
udp6 tpi_clts v inet6 udp - -
|
||||
tcp6 tpi_cots_ord v inet6 tcp - -
|
||||
udp tpi_clts v inet udp - -
|
||||
tcp tpi_cots_ord v inet tcp - -
|
||||
rawip tpi_raw - inet - - -
|
||||
local tpi_cots_ord - loopback - - -
|
||||
.Ed
|
||||
.Pp
|
||||
then using the network type
|
||||
.Sy udp
|
||||
in calls to the RPC library function (see
|
||||
.Xr rpc 3 )
|
||||
will make the code first try
|
||||
.Sy udp6 ,
|
||||
and then
|
||||
.Sy udp .
|
||||
.Pp
|
||||
.Xr getnetconfig 3
|
||||
and associated functions will parse this file and return structures of
|
||||
the following format:
|
||||
.Bd -literal
|
||||
struct netconfig {
|
||||
char *nc_netid; /* Network ID */
|
||||
unsigned long nc_semantics; /* Semantics (see below) */
|
||||
unsigned long nc_flag; /* Flags (see below) */
|
||||
char *nc_protofmly; /* Protocol family */
|
||||
char *nc_proto; /* Protocol name */
|
||||
char *nc_device; /* Network device pathname (unused) */
|
||||
unsigned long nc_nlookups; /* Number of lookup libs (unused) */
|
||||
char **nc_lookups; /* Names of the libraries (unused) */
|
||||
unsigned long nc_unused[9]; /* reserved */
|
||||
};
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/netconfig -compact
|
||||
.It Pa /etc/netconfig
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr getnetconfig 3 ,
|
||||
.Xr getnetpath 3
|
@ -41,6 +41,7 @@ static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
|
||||
* the sun NIS domain architecture.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpc_com.h>
|
||||
@ -54,6 +55,7 @@ static char sccsid[] = "@(#)netname.c 1.8 91/03/11 Copyr 1986 Sun Micro";
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
@ -101,8 +103,8 @@ getnetname(name)
|
||||
int
|
||||
user2netname(netname, uid, domain)
|
||||
char netname[MAXNETNAMELEN + 1];
|
||||
uid_t uid;
|
||||
char *domain;
|
||||
const uid_t uid;
|
||||
const char *domain;
|
||||
{
|
||||
char *dfltdom;
|
||||
|
||||
@ -126,8 +128,8 @@ user2netname(netname, uid, domain)
|
||||
int
|
||||
host2netname(netname, host, domain)
|
||||
char netname[MAXNETNAMELEN + 1];
|
||||
char *host;
|
||||
char *domain;
|
||||
const char *host;
|
||||
const char *domain;
|
||||
{
|
||||
char *dfltdom;
|
||||
char hostname[MAXHOSTNAMELEN+1];
|
||||
|
@ -38,6 +38,7 @@ static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
|
||||
* will work with any unix system that has adopted the sun NIS domain
|
||||
* architecture.
|
||||
*/
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpc_com.h>
|
||||
@ -52,6 +53,7 @@ static char sccsid[] = "@(#)netnamer.c 1.13 91/03/11 Copyr 1986 Sun Micro";
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static char *OPSYS = "unix";
|
||||
static char *NETID = "netid.byname";
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_clnt.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
@ -44,108 +47,74 @@ static char *rcsid = "$FreeBSD$";
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/nettype.h>
|
||||
#include <netinet/in.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static struct timeval timeout = { 5, 0 };
|
||||
static struct timeval tottimeout = { 60, 0 };
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void clnt_perror();
|
||||
#include "rpc_com.h"
|
||||
|
||||
#ifndef PORTMAPSOCK
|
||||
#define PORTMAPSOCK "/var/run/portmapsock"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set a mapping between program,version and port.
|
||||
* Calls the pmap service remotely to do the mapping.
|
||||
*/
|
||||
bool_t
|
||||
pmap_set(program, version, protocol, port)
|
||||
u_long program;
|
||||
u_long version;
|
||||
int protocol;
|
||||
u_short port;
|
||||
pmap_set(u_long program, u_long version, int protocol, int port)
|
||||
{
|
||||
struct sockaddr_in myaddress;
|
||||
int socket = -1;
|
||||
register CLIENT *client;
|
||||
struct pmap parms;
|
||||
bool_t rslt;
|
||||
struct stat st;
|
||||
struct netbuf *na;
|
||||
struct netconfig *nconf;
|
||||
char buf[32];
|
||||
|
||||
/*
|
||||
* Temporary hack for backwards compatibility. Eventually
|
||||
* this test will go away and we'll use only the "unix" transport.
|
||||
*/
|
||||
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
|
||||
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
|
||||
else {
|
||||
if (get_myaddress(&myaddress) != 0)
|
||||
return (FALSE);
|
||||
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
|
||||
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
||||
}
|
||||
|
||||
if (client == (CLIENT *)NULL)
|
||||
return (FALSE);
|
||||
parms.pm_prog = program;
|
||||
parms.pm_vers = version;
|
||||
parms.pm_prot = protocol;
|
||||
parms.pm_port = port;
|
||||
if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
|
||||
tottimeout) != RPC_SUCCESS) {
|
||||
clnt_perror(client, "Cannot register service");
|
||||
if ((protocol != IPPROTO_UDP) && (protocol != IPPROTO_TCP)) {
|
||||
return (FALSE);
|
||||
}
|
||||
CLNT_DESTROY(client);
|
||||
if (socket != -1)
|
||||
(void)_close(socket);
|
||||
nconf = __rpc_getconfip(protocol == IPPROTO_UDP ? "udp" : "tcp");
|
||||
if (nconf == NULL) {
|
||||
return (FALSE);
|
||||
}
|
||||
snprintf(buf, sizeof buf, "0.0.0.0.%d.%d",
|
||||
(((u_int32_t)port) >> 8) & 0xff, port & 0xff);
|
||||
na = uaddr2taddr(nconf, buf);
|
||||
if (na == NULL) {
|
||||
freenetconfigent(nconf);
|
||||
return (FALSE);
|
||||
}
|
||||
rslt = rpcb_set((rpcprog_t)program, (rpcvers_t)version, nconf, na);
|
||||
free(na);
|
||||
freenetconfigent(nconf);
|
||||
return (rslt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the mapping between program,version and port.
|
||||
* Remove the mapping between program, version and port.
|
||||
* Calls the pmap service remotely to do the un-mapping.
|
||||
*/
|
||||
bool_t
|
||||
pmap_unset(program, version)
|
||||
u_long program;
|
||||
u_long version;
|
||||
pmap_unset(u_long program, u_long version)
|
||||
{
|
||||
struct sockaddr_in myaddress;
|
||||
int socket = -1;
|
||||
register CLIENT *client;
|
||||
struct pmap parms;
|
||||
bool_t rslt;
|
||||
struct stat st;
|
||||
struct netconfig *nconf;
|
||||
bool_t udp_rslt = FALSE;
|
||||
bool_t tcp_rslt = FALSE;
|
||||
|
||||
/*
|
||||
* Temporary hack for backwards compatibility. Eventually
|
||||
* this test will go away and we'll use only the "unix" transport.
|
||||
*/
|
||||
if (stat(PORTMAPSOCK, &st) == 0 && st.st_mode & S_IFSOCK)
|
||||
client = clnt_create(PORTMAPSOCK, PMAPPROG, PMAPVERS, "unix");
|
||||
else {
|
||||
if (get_myaddress(&myaddress) != 0)
|
||||
return (FALSE);
|
||||
myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
|
||||
timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
||||
nconf = __rpc_getconfip("udp");
|
||||
if (nconf != NULL) {
|
||||
udp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
|
||||
nconf);
|
||||
freenetconfigent(nconf);
|
||||
}
|
||||
if (client == (CLIENT *)NULL)
|
||||
return (FALSE);
|
||||
parms.pm_prog = program;
|
||||
parms.pm_vers = version;
|
||||
parms.pm_port = parms.pm_prot = 0;
|
||||
CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
|
||||
tottimeout);
|
||||
CLNT_DESTROY(client);
|
||||
if (socket != -1)
|
||||
(void)_close(socket);
|
||||
return (rslt);
|
||||
nconf = __rpc_getconfip("tcp");
|
||||
if (nconf != NULL) {
|
||||
tcp_rslt = rpcb_unset((rpcprog_t)program, (rpcvers_t)version,
|
||||
nconf);
|
||||
freenetconfigent(nconf);
|
||||
}
|
||||
/*
|
||||
* XXX: The call may still succeed even if only one of the
|
||||
* calls succeeded. This was the best that could be
|
||||
* done for backward compatibility.
|
||||
*/
|
||||
return (tcp_rslt || udp_rslt);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_getmaps.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
@ -42,16 +45,21 @@ static char *rcsid = "$FreeBSD$";
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define NAMELEN 255
|
||||
@ -65,25 +73,27 @@ struct pmaplist *
|
||||
pmap_getmaps(address)
|
||||
struct sockaddr_in *address;
|
||||
{
|
||||
struct pmaplist *head = (struct pmaplist *)NULL;
|
||||
int socket = -1;
|
||||
struct pmaplist *head = NULL;
|
||||
int sock = -1;
|
||||
struct timeval minutetimeout;
|
||||
register CLIENT *client;
|
||||
CLIENT *client;
|
||||
|
||||
assert(address != NULL);
|
||||
|
||||
minutetimeout.tv_sec = 60;
|
||||
minutetimeout.tv_usec = 0;
|
||||
address->sin_port = htons(PMAPPORT);
|
||||
client = clnttcp_create(address, PMAPPROG,
|
||||
PMAPVERS, &socket, 50, 500);
|
||||
if (client != (CLIENT *)NULL) {
|
||||
if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
|
||||
&head, minutetimeout) != RPC_SUCCESS) {
|
||||
PMAPVERS, &sock, 50, 500);
|
||||
if (client != NULL) {
|
||||
if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP,
|
||||
(xdrproc_t)xdr_void, NULL,
|
||||
(xdrproc_t)xdr_pmaplist, &head, minutetimeout) !=
|
||||
RPC_SUCCESS) {
|
||||
clnt_perror(client, "pmap_getmaps rpc problem");
|
||||
}
|
||||
CLNT_DESTROY(client);
|
||||
}
|
||||
if (socket != -1)
|
||||
(void)_close(socket);
|
||||
address->sin_port = 0;
|
||||
return (head);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_getport.c,v 1.16 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
@ -41,16 +44,21 @@ static char *rcsid = "$FreeBSD$";
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static struct timeval timeout = { 5, 0 };
|
||||
static struct timeval tottimeout = { 60, 0 };
|
||||
static const struct timeval timeout = { 5, 0 };
|
||||
static const struct timeval tottimeout = { 60, 0 };
|
||||
|
||||
/*
|
||||
* Find the mapped port for program,version.
|
||||
@ -65,20 +73,24 @@ pmap_getport(address, program, version, protocol)
|
||||
u_int protocol;
|
||||
{
|
||||
u_short port = 0;
|
||||
int socket = -1;
|
||||
register CLIENT *client;
|
||||
int sock = -1;
|
||||
CLIENT *client;
|
||||
struct pmap parms;
|
||||
|
||||
assert(address != NULL);
|
||||
|
||||
address->sin_port = htons(PMAPPORT);
|
||||
client = clntudp_bufcreate(address, PMAPPROG,
|
||||
PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
||||
if (client != (CLIENT *)NULL) {
|
||||
PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
|
||||
if (client != NULL) {
|
||||
parms.pm_prog = program;
|
||||
parms.pm_vers = version;
|
||||
parms.pm_prot = protocol;
|
||||
parms.pm_port = 0; /* not needed or used */
|
||||
if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
|
||||
xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
|
||||
if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT,
|
||||
(xdrproc_t)xdr_pmap,
|
||||
&parms, (xdrproc_t)xdr_u_short, &port, tottimeout) !=
|
||||
RPC_SUCCESS){
|
||||
rpc_createerr.cf_stat = RPC_PMAPFAILURE;
|
||||
clnt_geterr(client, &rpc_createerr.cf_error);
|
||||
} else if (port == 0) {
|
||||
@ -86,8 +98,6 @@ pmap_getport(address, program, version, protocol)
|
||||
}
|
||||
CLNT_DESTROY(client);
|
||||
}
|
||||
if (socket != -1)
|
||||
(void)_close(socket);
|
||||
address->sin_port = 0;
|
||||
return (port);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_prot.c,v 1.10 2000/01/22 22:19:18 mycroft Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -40,9 +43,13 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
|
||||
bool_t
|
||||
@ -51,6 +58,9 @@ xdr_pmap(xdrs, regs)
|
||||
struct pmap *regs;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(regs != NULL);
|
||||
|
||||
if (xdr_u_long(xdrs, ®s->pm_prog) &&
|
||||
xdr_u_long(xdrs, ®s->pm_vers) &&
|
||||
xdr_u_long(xdrs, ®s->pm_prot))
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_prot2.c,v 1.14 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -40,9 +43,13 @@ static char *rcsid = "$FreeBSD$";
|
||||
* Copyright (C) 1984, Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <rpc/types.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
|
||||
/*
|
||||
@ -85,8 +92,8 @@ static char *rcsid = "$FreeBSD$";
|
||||
*/
|
||||
bool_t
|
||||
xdr_pmaplist(xdrs, rp)
|
||||
register XDR *xdrs;
|
||||
register struct pmaplist **rp;
|
||||
XDR *xdrs;
|
||||
struct pmaplist **rp;
|
||||
{
|
||||
/*
|
||||
* more_elements is pre-computed in case the direction is
|
||||
@ -94,10 +101,15 @@ xdr_pmaplist(xdrs, rp)
|
||||
* xdr_bool when the direction is XDR_DECODE.
|
||||
*/
|
||||
bool_t more_elements;
|
||||
register int freeing = (xdrs->x_op == XDR_FREE);
|
||||
register struct pmaplist **next = NULL;
|
||||
int freeing;
|
||||
struct pmaplist **next = NULL; /* pacify gcc */
|
||||
|
||||
while (TRUE) {
|
||||
assert(xdrs != NULL);
|
||||
assert(rp != NULL);
|
||||
|
||||
freeing = (xdrs->x_op == XDR_FREE);
|
||||
|
||||
for (;;) {
|
||||
more_elements = (bool_t)(*rp != NULL);
|
||||
if (! xdr_bool(xdrs, &more_elements))
|
||||
return (FALSE);
|
||||
@ -109,10 +121,23 @@ xdr_pmaplist(xdrs, rp)
|
||||
* before we free the current object ...
|
||||
*/
|
||||
if (freeing)
|
||||
next = &((*rp)->pml_next);
|
||||
next = &((*rp)->pml_next);
|
||||
if (! xdr_reference(xdrs, (caddr_t *)rp,
|
||||
(u_int)sizeof(struct pmaplist), xdr_pmap))
|
||||
(u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap))
|
||||
return (FALSE);
|
||||
rp = (freeing) ? next : &((*rp)->pml_next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* xdr_pmaplist_ptr() is specified to take a PMAPLIST *, but is identical in
|
||||
* functionality to xdr_pmaplist().
|
||||
*/
|
||||
bool_t
|
||||
xdr_pmaplist_ptr(xdrs, rp)
|
||||
XDR *xdrs;
|
||||
struct pmaplist *rp;
|
||||
{
|
||||
return xdr_pmaplist(xdrs, (struct pmaplist **)(void *)rp);
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: pmap_rmt.c,v 1.29 2000/07/06 03:10:34 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,6 +29,7 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/
|
||||
@ -42,24 +45,29 @@ static char *rcsid = "$FreeBSD$";
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/pmap_prot.h>
|
||||
#include <rpc/pmap_clnt.h>
|
||||
#include <rpc/pmap_rmt.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#define MAX_BROADCAST_SIZE 1400
|
||||
|
||||
static struct timeval timeout = { 3, 0 };
|
||||
static const struct timeval timeout = { 3, 0 };
|
||||
|
||||
/*
|
||||
* pmapper remote-call-service interface.
|
||||
@ -69,7 +77,8 @@ static struct timeval timeout = { 3, 0 };
|
||||
* programs to do a lookup and call in one step.
|
||||
*/
|
||||
enum clnt_stat
|
||||
pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
|
||||
pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout,
|
||||
port_ptr)
|
||||
struct sockaddr_in *addr;
|
||||
u_long prog, vers, proc;
|
||||
xdrproc_t xdrargs, xdrres;
|
||||
@ -77,15 +86,18 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
|
||||
struct timeval tout;
|
||||
u_long *port_ptr;
|
||||
{
|
||||
int socket = -1;
|
||||
register CLIENT *client;
|
||||
int sock = -1;
|
||||
CLIENT *client;
|
||||
struct rmtcallargs a;
|
||||
struct rmtcallres r;
|
||||
enum clnt_stat stat;
|
||||
|
||||
assert(addr != NULL);
|
||||
assert(port_ptr != NULL);
|
||||
|
||||
addr->sin_port = htons(PMAPPORT);
|
||||
client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
|
||||
if (client != (CLIENT *)NULL) {
|
||||
client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &sock);
|
||||
if (client != NULL) {
|
||||
a.prog = prog;
|
||||
a.vers = vers;
|
||||
a.proc = proc;
|
||||
@ -94,14 +106,13 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
|
||||
r.port_ptr = port_ptr;
|
||||
r.results_ptr = resp;
|
||||
r.xdr_results = xdrres;
|
||||
stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
|
||||
xdr_rmtcallres, &r, tout);
|
||||
stat = CLNT_CALL(client, (rpcproc_t)PMAPPROC_CALLIT,
|
||||
(xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres,
|
||||
&r, tout);
|
||||
CLNT_DESTROY(client);
|
||||
} else {
|
||||
stat = RPC_FAILED;
|
||||
}
|
||||
if (socket != -1)
|
||||
(void)_close(socket);
|
||||
addr->sin_port = 0;
|
||||
return (stat);
|
||||
}
|
||||
@ -113,11 +124,14 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
|
||||
*/
|
||||
bool_t
|
||||
xdr_rmtcall_args(xdrs, cap)
|
||||
register XDR *xdrs;
|
||||
register struct rmtcallargs *cap;
|
||||
XDR *xdrs;
|
||||
struct rmtcallargs *cap;
|
||||
{
|
||||
u_int lenposition, argposition, position;
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(cap != NULL);
|
||||
|
||||
if (xdr_u_long(xdrs, &(cap->prog)) &&
|
||||
xdr_u_long(xdrs, &(cap->vers)) &&
|
||||
xdr_u_long(xdrs, &(cap->proc))) {
|
||||
@ -144,275 +158,19 @@ xdr_rmtcall_args(xdrs, cap)
|
||||
*/
|
||||
bool_t
|
||||
xdr_rmtcallres(xdrs, crp)
|
||||
register XDR *xdrs;
|
||||
register struct rmtcallres *crp;
|
||||
XDR *xdrs;
|
||||
struct rmtcallres *crp;
|
||||
{
|
||||
caddr_t port_ptr;
|
||||
|
||||
port_ptr = (caddr_t)crp->port_ptr;
|
||||
assert(xdrs != NULL);
|
||||
assert(crp != NULL);
|
||||
|
||||
port_ptr = (caddr_t)(void *)crp->port_ptr;
|
||||
if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
|
||||
xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
|
||||
crp->port_ptr = (u_long *)port_ptr;
|
||||
(xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
|
||||
crp->port_ptr = (u_long *)(void *)port_ptr;
|
||||
return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following is kludged-up support for simple rpc broadcasts.
|
||||
* Someday a large, complicated system will replace these trivial
|
||||
* routines which only support udp/ip .
|
||||
*/
|
||||
|
||||
static int
|
||||
getbroadcastnets(addrs, sock, buf)
|
||||
struct in_addr *addrs;
|
||||
int sock; /* any valid socket will do */
|
||||
char *buf; /* why allocxate more when we can use existing... */
|
||||
{
|
||||
struct ifconf ifc;
|
||||
struct ifreq ifreq, *ifr;
|
||||
struct sockaddr_in *sin;
|
||||
struct in_addr addr;
|
||||
char *cp, *cplim;
|
||||
int n, i = 0;
|
||||
|
||||
ifc.ifc_len = UDPMSGSIZE;
|
||||
ifc.ifc_buf = buf;
|
||||
if (_ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
|
||||
perror("broadcast: ioctl (get interface configuration)");
|
||||
return (0);
|
||||
}
|
||||
#define max(a, b) (a > b ? a : b)
|
||||
#define size(p) max((p).sa_len, sizeof(p))
|
||||
cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */
|
||||
for (cp = buf; cp < cplim;
|
||||
cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) {
|
||||
ifr = (struct ifreq *)cp;
|
||||
if (ifr->ifr_addr.sa_family != AF_INET)
|
||||
continue;
|
||||
memcpy(&ifreq, ifr, sizeof(ifreq));
|
||||
if (_ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
|
||||
perror("broadcast: ioctl (get interface flags)");
|
||||
continue;
|
||||
}
|
||||
if ((ifreq.ifr_flags & IFF_BROADCAST) &&
|
||||
(ifreq.ifr_flags & IFF_UP)) {
|
||||
sin = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||
#ifdef SIOCGIFBRDADDR /* 4.3BSD */
|
||||
if (_ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
|
||||
addr =
|
||||
inet_makeaddr(inet_netof(sin->sin_addr),
|
||||
INADDR_ANY);
|
||||
} else {
|
||||
addr = ((struct sockaddr_in*)
|
||||
&ifreq.ifr_addr)->sin_addr;
|
||||
}
|
||||
#else /* 4.2 BSD */
|
||||
addr = inet_makeaddr(inet_netof(sin->sin_addr),
|
||||
INADDR_ANY);
|
||||
#endif
|
||||
for (n=i-1; n>=0; n--) {
|
||||
if (addr.s_addr == addrs[n].s_addr)
|
||||
break;
|
||||
}
|
||||
if (n<0) {
|
||||
addrs[i++] = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (i);
|
||||
}
|
||||
|
||||
typedef bool_t (*resultproc_t)();
|
||||
|
||||
enum clnt_stat
|
||||
clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
|
||||
u_long prog; /* program number */
|
||||
u_long vers; /* version number */
|
||||
u_long proc; /* procedure number */
|
||||
xdrproc_t xargs; /* xdr routine for args */
|
||||
caddr_t argsp; /* pointer to args */
|
||||
xdrproc_t xresults; /* xdr routine for results */
|
||||
caddr_t resultsp; /* pointer to results */
|
||||
resultproc_t eachresult; /* call with each result obtained */
|
||||
{
|
||||
enum clnt_stat stat;
|
||||
AUTH *unix_auth = authunix_create_default();
|
||||
XDR xdr_stream;
|
||||
register XDR *xdrs = &xdr_stream;
|
||||
int outlen, inlen, fromlen, nets;
|
||||
register int sock;
|
||||
int on = 1;
|
||||
fd_set *fds, readfds;
|
||||
register int i;
|
||||
bool_t done = FALSE;
|
||||
register u_long xid;
|
||||
u_long port;
|
||||
struct in_addr addrs[20];
|
||||
struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
|
||||
struct rmtcallargs a;
|
||||
struct rmtcallres r;
|
||||
struct rpc_msg msg;
|
||||
struct timeval t, tv;
|
||||
char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
|
||||
static u_int32_t disrupt;
|
||||
|
||||
if (disrupt == 0)
|
||||
disrupt = (u_int32_t)(long)resultsp;
|
||||
|
||||
/*
|
||||
* initialization: create a socket, a broadcast address, and
|
||||
* preserialize the arguments into a send buffer.
|
||||
*/
|
||||
if ((sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
perror("Cannot create socket for broadcast rpc");
|
||||
stat = RPC_CANTSEND;
|
||||
goto done_broad;
|
||||
}
|
||||
#ifdef SO_BROADCAST
|
||||
if (_setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
|
||||
perror("Cannot set socket option SO_BROADCAST");
|
||||
stat = RPC_CANTSEND;
|
||||
goto done_broad;
|
||||
}
|
||||
#endif /* def SO_BROADCAST */
|
||||
if (sock + 1 > FD_SETSIZE) {
|
||||
int bytes = howmany(sock + 1, NFDBITS) * sizeof(fd_mask);
|
||||
fds = (fd_set *)malloc(bytes);
|
||||
if (fds == NULL) {
|
||||
stat = RPC_CANTSEND;
|
||||
goto done_broad;
|
||||
}
|
||||
memset(fds, 0, bytes);
|
||||
} else {
|
||||
fds = &readfds;
|
||||
FD_ZERO(fds);
|
||||
}
|
||||
|
||||
nets = getbroadcastnets(addrs, sock, inbuf);
|
||||
memset(&baddr, 0, sizeof (baddr));
|
||||
baddr.sin_len = sizeof(struct sockaddr_in);
|
||||
baddr.sin_family = AF_INET;
|
||||
baddr.sin_port = htons(PMAPPORT);
|
||||
baddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
(void)gettimeofday(&t, (struct timezone *)0);
|
||||
msg.rm_xid = xid = (++disrupt) ^ getpid() ^ t.tv_sec ^ t.tv_usec;
|
||||
t.tv_usec = 0;
|
||||
msg.rm_direction = CALL;
|
||||
msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
msg.rm_call.cb_prog = PMAPPROG;
|
||||
msg.rm_call.cb_vers = PMAPVERS;
|
||||
msg.rm_call.cb_proc = PMAPPROC_CALLIT;
|
||||
msg.rm_call.cb_cred = unix_auth->ah_cred;
|
||||
msg.rm_call.cb_verf = unix_auth->ah_verf;
|
||||
a.prog = prog;
|
||||
a.vers = vers;
|
||||
a.proc = proc;
|
||||
a.xdr_args = xargs;
|
||||
a.args_ptr = argsp;
|
||||
r.port_ptr = &port;
|
||||
r.xdr_results = xresults;
|
||||
r.results_ptr = resultsp;
|
||||
xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
|
||||
if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
|
||||
stat = RPC_CANTENCODEARGS;
|
||||
goto done_broad;
|
||||
}
|
||||
outlen = (int)xdr_getpos(xdrs);
|
||||
xdr_destroy(xdrs);
|
||||
/*
|
||||
* Basic loop: broadcast a packet and wait a while for response(s).
|
||||
* The response timeout grows larger per iteration.
|
||||
*
|
||||
* XXX This will loop about 5 times the stop. If there are
|
||||
* lots of signals being received by the process it will quit
|
||||
* send them all in one quick burst, not paying attention to
|
||||
* the intended function of sending them slowly over half a
|
||||
* minute or so
|
||||
*/
|
||||
for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
|
||||
for (i = 0; i < nets; i++) {
|
||||
baddr.sin_addr = addrs[i];
|
||||
if (_sendto(sock, outbuf, outlen, 0,
|
||||
(struct sockaddr *)&baddr,
|
||||
sizeof (struct sockaddr)) != outlen) {
|
||||
perror("Cannot send broadcast packet");
|
||||
stat = RPC_CANTSEND;
|
||||
goto done_broad;
|
||||
}
|
||||
}
|
||||
if (eachresult == NULL) {
|
||||
stat = RPC_SUCCESS;
|
||||
goto done_broad;
|
||||
}
|
||||
recv_again:
|
||||
msg.acpted_rply.ar_verf = _null_auth;
|
||||
msg.acpted_rply.ar_results.where = (caddr_t)&r;
|
||||
msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
|
||||
/* XXX we know the other bits are still clear */
|
||||
FD_SET(sock, fds);
|
||||
tv = t; /* for _select() that copies back */
|
||||
switch (_select(sock + 1, fds, NULL, NULL, &tv)) {
|
||||
|
||||
case 0: /* timed out */
|
||||
stat = RPC_TIMEDOUT;
|
||||
continue;
|
||||
|
||||
case -1: /* some kind of error */
|
||||
if (errno == EINTR)
|
||||
goto recv_again;
|
||||
perror("Broadcast select problem");
|
||||
stat = RPC_CANTRECV;
|
||||
goto done_broad;
|
||||
|
||||
} /* end of select results switch */
|
||||
try_again:
|
||||
fromlen = sizeof(struct sockaddr);
|
||||
inlen = _recvfrom(sock, inbuf, UDPMSGSIZE, 0,
|
||||
(struct sockaddr *)&raddr, &fromlen);
|
||||
if (inlen < 0) {
|
||||
if (errno == EINTR)
|
||||
goto try_again;
|
||||
perror("Cannot receive reply to broadcast");
|
||||
stat = RPC_CANTRECV;
|
||||
goto done_broad;
|
||||
}
|
||||
if (inlen < sizeof(u_int32_t))
|
||||
goto recv_again;
|
||||
/*
|
||||
* see if reply transaction id matches sent id.
|
||||
* If so, decode the results.
|
||||
*/
|
||||
xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
|
||||
if (xdr_replymsg(xdrs, &msg)) {
|
||||
if ((msg.rm_xid == xid) &&
|
||||
(msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
|
||||
(msg.acpted_rply.ar_stat == SUCCESS)) {
|
||||
raddr.sin_port = htons((u_short)port);
|
||||
done = (*eachresult)(resultsp, &raddr);
|
||||
}
|
||||
/* otherwise, we just ignore the errors ... */
|
||||
}
|
||||
xdrs->x_op = XDR_FREE;
|
||||
msg.acpted_rply.ar_results.proc = xdr_void;
|
||||
(void)xdr_replymsg(xdrs, &msg);
|
||||
(void)(*xresults)(xdrs, resultsp);
|
||||
xdr_destroy(xdrs);
|
||||
if (done) {
|
||||
stat = RPC_SUCCESS;
|
||||
goto done_broad;
|
||||
} else {
|
||||
goto recv_again;
|
||||
}
|
||||
}
|
||||
done_broad:
|
||||
if (fds != &readfds)
|
||||
free(fds);
|
||||
if (sock >= 0)
|
||||
(void)_close(sock);
|
||||
AUTH_DESTROY(unix_auth);
|
||||
return (stat);
|
||||
}
|
||||
|
||||
|
1986
lib/libc/rpc/rpc.3
1986
lib/libc/rpc/rpc.3
File diff suppressed because it is too large
Load Diff
@ -1,36 +1,60 @@
|
||||
.\" $NetBSD: rpc.5,v 1.3 2000/06/15 20:05:54 fvdl Exp $
|
||||
.\" $FreeBSD$
|
||||
.\" @(#)rpc.5 2.2 88/08/03 4.0 RPCSRC; from 1.4 87/11/27 SMI;
|
||||
.Dd September 26, 1985
|
||||
.\" $FreeBSD$
|
||||
.\" @(#)rpc.4 1.17 93/08/30 SMI; from SVr4
|
||||
.\" Copyright 1989 AT&T
|
||||
.Dd December 10, 1991
|
||||
.Dt RPC 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rpc
|
||||
.Nd rpc program number data base
|
||||
.Sh SYNOPSIS
|
||||
/etc/rpc
|
||||
.Pa /etc/rpc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Pa /etc/rpc
|
||||
.Nm
|
||||
file contains user readable names that
|
||||
can be used in place of rpc program numbers.
|
||||
Each line has the following information:
|
||||
can be used in place of RPC program numbers.
|
||||
For each RPC program a single line should be present
|
||||
with the following information:
|
||||
.Pp
|
||||
.Bl -bullet -compact
|
||||
.Bl -enum -compact
|
||||
.It
|
||||
name of server for the rpc program
|
||||
name of the RPC program
|
||||
.It
|
||||
rpc program number
|
||||
RPC program number
|
||||
.It
|
||||
aliases
|
||||
.El
|
||||
.Pp
|
||||
Items are separated by any number of blanks and/or
|
||||
tab characters.
|
||||
A ``#'' indicates the beginning of a comment; characters up to the end of
|
||||
A hash
|
||||
.Pq Dq Li #
|
||||
indicates the beginning of a comment; characters up to the end of
|
||||
the line are not interpreted by routines which search the file.
|
||||
.Sh EXAMPLES
|
||||
Below is an example of an RPC database:
|
||||
.Bd -literal
|
||||
#
|
||||
# rpc
|
||||
#
|
||||
rpcbind 100000 portmap sunrpc portmapper
|
||||
rusersd 100002 rusers
|
||||
nfs 100003 nfsprog
|
||||
mountd 100005 mount showmount
|
||||
walld 100008 rwall shutdown
|
||||
sprayd 100012 spray
|
||||
llockmgr 100020
|
||||
nlockmgr 100021
|
||||
status 100024
|
||||
bootparam 100026
|
||||
keyserv 100029 keyserver
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -compact -width /etc/rpc
|
||||
.It Pa /etc/rpc
|
||||
.Bl -tag -width /etc/nsswitch.conf -compact
|
||||
.It Pa /etc/nsswitch.conf
|
||||
.El
|
||||
.Sh "SEE ALSO"
|
||||
.Sh SEE ALSO
|
||||
.Xr getrpcent 3
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc_callmsg.c,v 1.16 2000/07/14 08:40:42 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -40,21 +43,27 @@ static char *rcsid = "$FreeBSD$";
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include "namespace.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* XDR a call message
|
||||
*/
|
||||
bool_t
|
||||
xdr_callmsg(xdrs, cmsg)
|
||||
register XDR *xdrs;
|
||||
register struct rpc_msg *cmsg;
|
||||
XDR *xdrs;
|
||||
struct rpc_msg *cmsg;
|
||||
{
|
||||
register int32_t *buf;
|
||||
register struct opaque_auth *oa;
|
||||
int32_t *buf;
|
||||
struct opaque_auth *oa;
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(cmsg != NULL);
|
||||
|
||||
if (xdrs->x_op == XDR_ENCODE) {
|
||||
if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
|
||||
@ -68,30 +77,30 @@ xdr_callmsg(xdrs, cmsg)
|
||||
+ 2 * BYTES_PER_XDR_UNIT
|
||||
+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
|
||||
if (buf != NULL) {
|
||||
IXDR_PUT_LONG(buf, cmsg->rm_xid);
|
||||
IXDR_PUT_INT32(buf, cmsg->rm_xid);
|
||||
IXDR_PUT_ENUM(buf, cmsg->rm_direction);
|
||||
if (cmsg->rm_direction != CALL) {
|
||||
return (FALSE);
|
||||
}
|
||||
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
|
||||
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers);
|
||||
if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
|
||||
return (FALSE);
|
||||
}
|
||||
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
|
||||
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
|
||||
IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
|
||||
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog);
|
||||
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers);
|
||||
IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc);
|
||||
oa = &cmsg->rm_call.cb_cred;
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
IXDR_PUT_INT32(buf, oa->oa_length);
|
||||
if (oa->oa_length) {
|
||||
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
|
||||
memmove(buf, oa->oa_base, oa->oa_length);
|
||||
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
|
||||
}
|
||||
oa = &cmsg->rm_call.cb_verf;
|
||||
IXDR_PUT_ENUM(buf, oa->oa_flavor);
|
||||
IXDR_PUT_LONG(buf, oa->oa_length);
|
||||
IXDR_PUT_INT32(buf, oa->oa_length);
|
||||
if (oa->oa_length) {
|
||||
memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
|
||||
memmove(buf, oa->oa_base, oa->oa_length);
|
||||
/* no real need....
|
||||
buf += RNDUP(oa->oa_length) / sizeof (int32_t);
|
||||
*/
|
||||
@ -102,28 +111,30 @@ xdr_callmsg(xdrs, cmsg)
|
||||
if (xdrs->x_op == XDR_DECODE) {
|
||||
buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
|
||||
if (buf != NULL) {
|
||||
cmsg->rm_xid = IXDR_GET_LONG(buf);
|
||||
cmsg->rm_xid = IXDR_GET_U_INT32(buf);
|
||||
cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
|
||||
if (cmsg->rm_direction != CALL) {
|
||||
return (FALSE);
|
||||
}
|
||||
cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
|
||||
cmsg->rm_call.cb_rpcvers = IXDR_GET_U_INT32(buf);
|
||||
if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
|
||||
return (FALSE);
|
||||
}
|
||||
cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
|
||||
cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
|
||||
cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
|
||||
cmsg->rm_call.cb_prog = IXDR_GET_U_INT32(buf);
|
||||
cmsg->rm_call.cb_vers = IXDR_GET_U_INT32(buf);
|
||||
cmsg->rm_call.cb_proc = IXDR_GET_U_INT32(buf);
|
||||
oa = &cmsg->rm_call.cb_cred;
|
||||
oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
|
||||
oa->oa_length = IXDR_GET_LONG(buf);
|
||||
oa->oa_length = (u_int)IXDR_GET_U_INT32(buf);
|
||||
if (oa->oa_length) {
|
||||
if (oa->oa_length > MAX_AUTH_BYTES) {
|
||||
return (FALSE);
|
||||
}
|
||||
if (oa->oa_base == NULL) {
|
||||
oa->oa_base = (caddr_t)
|
||||
mem_alloc(oa->oa_length);
|
||||
mem_alloc(oa->oa_length);
|
||||
if (oa->oa_base == NULL)
|
||||
return (FALSE);
|
||||
}
|
||||
buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
|
||||
if (buf == NULL) {
|
||||
@ -132,7 +143,7 @@ xdr_callmsg(xdrs, cmsg)
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
memcpy(oa->oa_base, (caddr_t)buf,
|
||||
memmove(oa->oa_base, buf,
|
||||
oa->oa_length);
|
||||
/* no real need....
|
||||
buf += RNDUP(oa->oa_length) /
|
||||
@ -149,7 +160,7 @@ xdr_callmsg(xdrs, cmsg)
|
||||
}
|
||||
} else {
|
||||
oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
|
||||
oa->oa_length = IXDR_GET_LONG(buf);
|
||||
oa->oa_length = (u_int)IXDR_GET_U_INT32(buf);
|
||||
}
|
||||
if (oa->oa_length) {
|
||||
if (oa->oa_length > MAX_AUTH_BYTES) {
|
||||
@ -157,7 +168,9 @@ xdr_callmsg(xdrs, cmsg)
|
||||
}
|
||||
if (oa->oa_base == NULL) {
|
||||
oa->oa_base = (caddr_t)
|
||||
mem_alloc(oa->oa_length);
|
||||
mem_alloc(oa->oa_length);
|
||||
if (oa->oa_base == NULL)
|
||||
return (FALSE);
|
||||
}
|
||||
buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
|
||||
if (buf == NULL) {
|
||||
@ -166,7 +179,7 @@ xdr_callmsg(xdrs, cmsg)
|
||||
return (FALSE);
|
||||
}
|
||||
} else {
|
||||
memcpy(oa->oa_base, (caddr_t)buf,
|
||||
memmove(oa->oa_base, buf,
|
||||
oa->oa_length);
|
||||
/* no real need...
|
||||
buf += RNDUP(oa->oa_length) /
|
||||
@ -187,7 +200,6 @@ xdr_callmsg(xdrs, cmsg)
|
||||
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) &&
|
||||
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) &&
|
||||
xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
|
||||
return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
|
||||
return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
95
lib/libc/rpc/rpc_clnt_auth.3
Normal file
95
lib/libc/rpc/rpc_clnt_auth.3
Normal file
@ -0,0 +1,95 @@
|
||||
.\" @(#)rpc_clnt_auth.3n 1.21 93/05/07 SMI; from SVr4
|
||||
.\" Copyright 1989 AT&T
|
||||
.\" @(#)rpc_clnt_auth 1.4 89/07/20 SMI;
|
||||
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||
.\" $NetBSD: rpc_clnt_auth.3,v 1.1 2000/06/03 09:29:50 fvdl Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd May 7, 1993
|
||||
.Dt RPC_CLNT_AUTH 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm auth_destroy ,
|
||||
.Nm authnone_create ,
|
||||
.Nm authsys_create ,
|
||||
.Nm authsys_create_default
|
||||
.Nd library routines for client side remote procedure call authentication
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <rpc/rpc.h>
|
||||
.Ft "void"
|
||||
.Fn auth_destroy "AUTH *auth"
|
||||
.Ft "AUTH *"
|
||||
.Fn authnone_create "void"
|
||||
.Ft "AUTH *"
|
||||
.Fn authsys_create "const char *host" "const uid_t uid" "const gid_t gid" "const int len" "const gid_t *aup_gids"
|
||||
.Ft "AUTH *"
|
||||
.Fn authsys_create_default "void"
|
||||
.Sh DESCRIPTION
|
||||
These routines are part of the
|
||||
RPC library that allows C language programs to make procedure
|
||||
calls on other machines across the network,
|
||||
with desired authentication.
|
||||
.Pp
|
||||
These routines are normally called after creating the
|
||||
.Vt CLIENT
|
||||
handle.
|
||||
The
|
||||
.Va cl_auth
|
||||
field of the
|
||||
.Vt CLIENT
|
||||
structure should be initialized by the
|
||||
.Vt AUTH
|
||||
structure returned by some of the following routines.
|
||||
The client's authentication information
|
||||
is passed to the server when the
|
||||
RPC
|
||||
call is made.
|
||||
.Pp
|
||||
Only the
|
||||
.Dv NULL
|
||||
and the
|
||||
.Dv SYS
|
||||
style of authentication is discussed here.
|
||||
.Sh Routines
|
||||
.Bl -tag -width authsys_create_default()
|
||||
.It Fn auth_destroy
|
||||
A function macro that destroys the authentication
|
||||
information associated with
|
||||
.Fa auth .
|
||||
Destruction usually involves deallocation
|
||||
of private data structures.
|
||||
The use of
|
||||
.Fn auth
|
||||
is undefined after calling
|
||||
.Fn auth_destroy .
|
||||
.It Fn authnone_create
|
||||
Create and return an RPC
|
||||
authentication handle that passes nonusable
|
||||
authentication information with each remote procedure call.
|
||||
This is the default authentication used by RPC.
|
||||
.It Fn authsys_create
|
||||
Create and return an RPC authentication handle that contains
|
||||
.Dv AUTH_SYS
|
||||
authentication information.
|
||||
The parameter
|
||||
.Fa host
|
||||
is the name of the machine on which the information was
|
||||
created;
|
||||
.Fa uid
|
||||
is the user's user ID;
|
||||
.Fa gid
|
||||
is the user's current group ID;
|
||||
.Fa len
|
||||
and
|
||||
.Fa aup_gids
|
||||
refer to a counted array of groups to which the user belongs.
|
||||
.It Fn authsys_create_default
|
||||
Call
|
||||
.Fn authsys_create
|
||||
with the appropriate parameters.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rpc 3 ,
|
||||
.Xr rpc_clnt_calls 3 ,
|
||||
.Xr rpc_clnt_create 3
|
302
lib/libc/rpc/rpc_clnt_calls.3
Normal file
302
lib/libc/rpc/rpc_clnt_calls.3
Normal file
@ -0,0 +1,302 @@
|
||||
.\" @(#)rpc_clnt_calls.3n 1.30 93/08/31 SMI; from SVr4
|
||||
.\" Copyright 1989 AT&T
|
||||
.\" @(#)rpc_clnt_calls 1.4 89/07/20 SMI;
|
||||
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||
.\" $FreeBSD$
|
||||
.Dd May 7, 1993
|
||||
.Dt RPC_CLNT_CALLS 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rpc_clnt_calls ,
|
||||
.Nm clnt_call ,
|
||||
.Nm clnt_freeres ,
|
||||
.Nm clnt_geterr ,
|
||||
.Nm clnt_perrno ,
|
||||
.Nm clnt_perror ,
|
||||
.Nm clnt_sperrno ,
|
||||
.Nm clnt_sperror ,
|
||||
.Nm rpc_broadcast ,
|
||||
.Nm rpc_broadcast_exp ,
|
||||
.Nm rpc_call
|
||||
.Nd library routines for client side calls
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <rpc/rpc.h>
|
||||
.Ft "enum clnt_stat"
|
||||
.Fn clnt_call "CLIENT *clnt" "const rpcproc_t procnum" "const xdrproc_t inproc" "const caddr_t in" "const xdrproc_t outproc" "caddr_t out" "const struct timeval tout"
|
||||
.Ft bool_t
|
||||
.Fn clnt_freeres "CLIENT *clnt" "const xdrproc_t outproc" "caddr_t out"
|
||||
.Ft void
|
||||
.Fn clnt_geterr "const CLIENT * clnt" "struct rpc_err * errp"
|
||||
.Ft void
|
||||
.Fn clnt_perrno "const enum clnt_stat stat"
|
||||
.Ft void
|
||||
.Fn clnt_perror "const CLIENT * clnt" "const char *s"
|
||||
.Ft "char *"
|
||||
.Fn clnt_sperrno "const enum clnt_stat stat"
|
||||
.Ft "char *"
|
||||
.Fn clnt_sperror "const CLIENT *clnt" "const char * s"
|
||||
.Ft "enum clnt_stat"
|
||||
.Fo rpc_broadcast
|
||||
.Fa "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||
.Fa "const rpcproc_t procnum" "const xdrproc_t inproc"
|
||||
.Fa "const caddr_t in" "const xdrproc_t outproc" "caddr_t out"
|
||||
.Fa "const resultproc_t eachresult" "const char *nettype"
|
||||
.Fc
|
||||
.Ft "enum clnt_stat"
|
||||
.Fo rpc_broadcast_exp
|
||||
.Fa "rpcprog_t prognum" "const rpcvers_t versnum"
|
||||
.Fa "const rpcproc_t procnum" "const xdrproc_t xargs"
|
||||
.Fa "caddr_t argsp" "const xdrproc_t xresults"
|
||||
.Fa "caddr_t resultsp" "const int inittime" "const int waittime"
|
||||
.Fa "const resultproc_t eachresult" "const char * nettype"
|
||||
.Fc
|
||||
.Ft "enum clnt_stat"
|
||||
.Fo rpc_call
|
||||
.Fa "const char *host" "const rpcprog_t prognum"
|
||||
.Fa "const rpcvers_t versnum" "const rpcproc_t procnum"
|
||||
.Fa "const xdrproc_t inproc" "const char *in"
|
||||
.Fa "const xdrproc_t outproc" "char *out" "const char *nettype"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
RPC library routines allow C language programs to make procedure
|
||||
calls on other machines across the network.
|
||||
First, the client calls a procedure to send a request to the server.
|
||||
Upon receipt of the request, the server calls a dispatch routine
|
||||
to perform the requested service, and then sends back a reply.
|
||||
.Pp
|
||||
The
|
||||
.Fn clnt_call ,
|
||||
.Fn rpc_call ,
|
||||
and
|
||||
.Fn rpc_broadcast
|
||||
routines handle the client side of the procedure call.
|
||||
The remaining routines deal with error handling in the case of errors.
|
||||
.Pp
|
||||
Some of the routines take a
|
||||
.Vt CLIENT
|
||||
handle as one of the parameters.
|
||||
A
|
||||
.Vt CLIENT
|
||||
handle can be created by an RPC creation routine such as
|
||||
.Fn clnt_create
|
||||
(see
|
||||
.Xr rpc_clnt_create 3 ) .
|
||||
.Pp
|
||||
These routines are safe for use in multithreaded applications.
|
||||
.Vt CLIENT
|
||||
handles can be shared between threads, however in this implementation
|
||||
requests by different threads are serialized (that is, the first request will
|
||||
receive its results before the second request is sent).
|
||||
.Sh Routines
|
||||
See
|
||||
.Xr rpc 3
|
||||
for the definition of the
|
||||
.Vt CLIENT
|
||||
data structure.
|
||||
.Bl -tag -width XXXXX
|
||||
.It Fn clnt_call
|
||||
A function macro that calls the remote procedure
|
||||
.Fa procnum
|
||||
associated with the client handle,
|
||||
.Fa clnt ,
|
||||
which is obtained with an RPC
|
||||
client creation routine such as
|
||||
.Fn clnt_create
|
||||
(see
|
||||
.Xr rpc_clnt_create 3 ) .
|
||||
The parameter
|
||||
.Fa inproc
|
||||
is the XDR function used to encode the procedure's parameters, and
|
||||
.Fa outproc
|
||||
is the XDR function used to decode the procedure's results;
|
||||
.Fa in
|
||||
is the address of the procedure's argument(s), and
|
||||
.Fa out
|
||||
is the address of where to place the result(s).
|
||||
.Fa tout
|
||||
is the time allowed for results to be returned, which is overridden by
|
||||
a time-out set explicitly through
|
||||
.Fn clnt_control ,
|
||||
see
|
||||
.Xr rpc_clnt_create 3 .
|
||||
If the remote call succeeds, the status returned is
|
||||
.Dv RPC_SUCCESS ,
|
||||
otherwise an appropriate status is returned.
|
||||
.It Fn clnt_freeres
|
||||
A function macro that frees any data allocated by the
|
||||
RPC/XDR system when it decoded the results of an RPC call.
|
||||
The parameter
|
||||
.Fa out
|
||||
is the address of the results, and
|
||||
.Fa outproc
|
||||
is the XDR routine describing the results.
|
||||
This routine returns 1 if the results were successfully freed,
|
||||
and 0 otherwise.
|
||||
.It Fn clnt_geterr
|
||||
A function macro that copies the error structure out of the client
|
||||
handle to the structure at address
|
||||
.Fa errp .
|
||||
.It Fn clnt_perrno
|
||||
Print a message to standard error corresponding
|
||||
to the condition indicated by
|
||||
.Fa stat .
|
||||
A newline is appended.
|
||||
Normally used after a procedure call fails for a routine
|
||||
for which a client handle is not needed, for instance
|
||||
.Fn rpc_call .
|
||||
.It Fn clnt_perror
|
||||
Print a message to the standard error indicating why an
|
||||
RPC call failed;
|
||||
.Fa clnt
|
||||
is the handle used to do the call.
|
||||
The message is prepended with string
|
||||
.Fa s
|
||||
and a colon.
|
||||
A newline is appended.
|
||||
Normally used after a remote procedure call fails
|
||||
for a routine which requires a client handle,
|
||||
for instance
|
||||
.Fn clnt_call .
|
||||
.It Fn clnt_sperrno
|
||||
Take the same arguments as
|
||||
.Fn clnt_perrno ,
|
||||
but instead of sending a message to the standard error
|
||||
indicating why an RPC
|
||||
call failed, return a pointer to a string which contains the message.
|
||||
.Fn clnt_sperrno
|
||||
is normally used instead of
|
||||
.Fn clnt_perrno
|
||||
when the program does not have a standard error (as a program
|
||||
running as a server quite likely does not), or if the programmer
|
||||
does not want the message to be output with
|
||||
.Fn printf
|
||||
(see
|
||||
.Xr printf 3 ) ,
|
||||
or if a message format different than that supported by
|
||||
.Fn clnt_perrno
|
||||
is to be used.
|
||||
Note:
|
||||
unlike
|
||||
.Fn clnt_sperror
|
||||
and
|
||||
.Fn clnt_spcreaterror
|
||||
(see
|
||||
.Xr rpc_clnt_create 3 ) ,
|
||||
.Fn clnt_sperrno
|
||||
does not return pointer to static data so the
|
||||
result will not get overwritten on each call.
|
||||
.It Fn clnt_sperror
|
||||
Like
|
||||
.Fn clnt_perror ,
|
||||
except that (like
|
||||
.Fn clnt_sperrno )
|
||||
it returns a string instead of printing to standard error.
|
||||
However,
|
||||
.Fn clnt_sperror
|
||||
does not append a newline at the end of the message.
|
||||
Warning:
|
||||
returns pointer to a buffer that is overwritten
|
||||
on each call.
|
||||
.It Fn rpc_broadcast
|
||||
Like
|
||||
.Fn rpc_call ,
|
||||
except the call message is broadcast to
|
||||
all the connectionless transports specified by
|
||||
.Fa nettype .
|
||||
If
|
||||
.Fa nettype
|
||||
is
|
||||
.Dv NULL ,
|
||||
it defaults to
|
||||
.Qq netpath .
|
||||
Each time it receives a response,
|
||||
this routine calls
|
||||
.Fn eachresult ,
|
||||
whose form is:
|
||||
.Ft bool_t
|
||||
.Fn eachresult "caddr_t out" "const struct netbuf * addr" "const struct netconfig * netconf"
|
||||
where
|
||||
.Fa out
|
||||
is the same as
|
||||
.Fa out
|
||||
passed to
|
||||
.Fn rpc_broadcast ,
|
||||
except that the remote procedure's output is decoded there;
|
||||
.Fa addr
|
||||
points to the address of the machine that sent the results, and
|
||||
.Fa netconf
|
||||
is the netconfig structure of the transport on which the remote
|
||||
server responded.
|
||||
If
|
||||
.Fn eachresult
|
||||
returns 0,
|
||||
.Fn rpc_broadcast
|
||||
waits for more replies;
|
||||
otherwise it returns with appropriate status.
|
||||
Warning:
|
||||
broadcast file descriptors are limited in size to the
|
||||
maximum transfer size of that transport.
|
||||
For Ethernet, this value is 1500 bytes.
|
||||
.Fn rpc_broadcast
|
||||
uses
|
||||
.Dv AUTH_SYS
|
||||
credentials by default (see
|
||||
.Xr rpc_clnt_auth 3 ) .
|
||||
.It Fn rpc_broadcast_exp
|
||||
Like
|
||||
.Fn rpc_broadcast ,
|
||||
except that the initial timeout,
|
||||
.Fa inittime
|
||||
and the maximum timeout,
|
||||
.Fa waittime
|
||||
are specified in milliseconds.
|
||||
.Fa inittime
|
||||
is the initial time that
|
||||
.Fn rpc_broadcast_exp
|
||||
waits before resending the request.
|
||||
After the first resend, the re-transmission interval
|
||||
increases exponentially until it exceeds
|
||||
.Fa waittime .
|
||||
.It Fn rpc_call
|
||||
Call the remote procedure associated with
|
||||
.Fa prognum ,
|
||||
.Fa versnum ,
|
||||
and
|
||||
.Fa procnum
|
||||
on the machine,
|
||||
.Fa host .
|
||||
The parameter
|
||||
.Fa inproc
|
||||
is used to encode the procedure's parameters, and
|
||||
.Fa outproc
|
||||
is used to decode the procedure's results;
|
||||
.Fa in
|
||||
is the address of the procedure's argument(s), and
|
||||
.Fa out
|
||||
is the address of where to place the result(s).
|
||||
.Fa nettype
|
||||
can be any of the values listed on
|
||||
.Xr rpc 3 .
|
||||
This routine returns
|
||||
.Dv RPC_SUCCESS
|
||||
if it succeeds,
|
||||
or an appropriate status is returned.
|
||||
Use the
|
||||
.Fn clnt_perrno
|
||||
routine to translate failure status into error messages.
|
||||
Warning:
|
||||
.Fn rpc_call
|
||||
uses the first available transport belonging
|
||||
to the class
|
||||
.Fa nettype ,
|
||||
on which it can create a connection.
|
||||
You do not have control of timeouts or authentication
|
||||
using this routine.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr printf 3 ,
|
||||
.Xr rpc 3 ,
|
||||
.Xr rpc_clnt_auth 3 ,
|
||||
.Xr rpc_clnt_create 3
|
437
lib/libc/rpc/rpc_clnt_create.3
Normal file
437
lib/libc/rpc/rpc_clnt_create.3
Normal file
@ -0,0 +1,437 @@
|
||||
.\" @(#)rpc_clnt_create.3n 1.36 93/08/31 SMI; from SVr4
|
||||
.\" Copyright 1989 AT&T
|
||||
.\" @(#)rpc_clnt_create 1.5 89/07/24 SMI;
|
||||
.\" Copyright (c) 1988 Sun Microsystems, Inc. - All Rights Reserved.
|
||||
.\" $NetBSD: rpc_clnt_create.3,v 1.2 2000/06/20 00:53:08 fvdl Exp $
|
||||
.\" $FreeBSD$
|
||||
.Dd May 7, 1993
|
||||
.Dt RPC_CLNT_CREATE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rpc_clnt_create ,
|
||||
.Nm clnt_control ,
|
||||
.Nm clnt_create ,
|
||||
.Nm clnt_create_vers ,
|
||||
.Nm clnt_destroy ,
|
||||
.Nm clnt_dg_create ,
|
||||
.Nm clnt_pcreateerror ,
|
||||
.Nm clnt_raw_create ,
|
||||
.Nm clnt_spcreateerror ,
|
||||
.Nm clnt_tli_create ,
|
||||
.Nm clnt_tp_create ,
|
||||
.Nm clnt_vc_create ,
|
||||
.Nm rpc_createerr
|
||||
.Nd "library routines for dealing with creation and manipulation of"
|
||||
.Vt CLIENT
|
||||
handles
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <rpc/rpc.h>
|
||||
.Ft bool_t
|
||||
.Fn clnt_control "CLIENT *clnt" "const u_int req" "char *info"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const char *nettype"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_create_vers "const char * host" "const rpcprog_t prognum" "rpcvers_t *vers_outp" "const rpcvers_t vers_low" "const rpcvers_t vers_high" "char *nettype"
|
||||
.Ft void
|
||||
.Fn clnt_destroy "CLIENT *" "clnt"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_dg_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
|
||||
.Ft void
|
||||
.Fn clnt_pcreateerror "const char *s"
|
||||
.Ft "char *"
|
||||
.Fn clnt_spcreateerror "const char *s"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_raw_create "const rpcprog_t prognum" "const rpcvers_t versnum"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_tli_create "const int fildes" "const struct netconfig *netconf" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_tp_create "const char * host" "const rpcprog_t prognum" "const rpcvers_t versnum" "const struct netconfig *netconf"
|
||||
.Ft "CLIENT *"
|
||||
.Fn clnt_vc_create "const int fildes" "const struct netbuf *svcaddr" "const rpcprog_t prognum" "const rpcvers_t versnum" "const u_int sendsz" "const u_int recvsz"
|
||||
.Sh DESCRIPTION
|
||||
RPC library routines allow C language programs to make procedure
|
||||
calls on other machines across the network.
|
||||
First a
|
||||
.Vt CLIENT
|
||||
handle is created and then the client calls a procedure to send a
|
||||
request to the server.
|
||||
On receipt of the request, the server calls a dispatch routine
|
||||
to perform the requested service, and then sends a reply.
|
||||
.Sh Routines
|
||||
.Bl -tag -width YYYYYYY
|
||||
.It Fn clnt_control
|
||||
A function macro to change or retrieve various information
|
||||
about a client object.
|
||||
.Fa req
|
||||
indicates the type of operation, and
|
||||
.Fa info
|
||||
is a pointer to the information.
|
||||
For both connectionless and connection-oriented transports,
|
||||
the supported values of
|
||||
.Fa req
|
||||
and their argument types and what they do are:
|
||||
.Bl -column "CLSET_FD_NCLOSE" "struct timeval *" "set total timeout"
|
||||
.It Dv CLSET_TIMEOUT Ta "struct timeval *" Ta "set total timeout"
|
||||
.It Dv CLGET_TIMEOUT Ta "struct timeval *" Ta "get total timeout"
|
||||
.El
|
||||
.Pp
|
||||
Note:
|
||||
if you set the timeout using
|
||||
.Fn clnt_control ,
|
||||
the timeout argument passed by
|
||||
.Fn clnt_call
|
||||
is ignored in all subsequent calls.
|
||||
.Pp
|
||||
Note:
|
||||
If you set the timeout value to 0,
|
||||
.Fn clnt_control
|
||||
immediately returns an error
|
||||
.Pq Dv RPC_TIMEDOUT .
|
||||
Set the timeout parameter to 0 for batching calls.
|
||||
.Bl -column CLSET_FD_NCLOSE "struct timeval *" "do not close fd on destroy"
|
||||
.It Dv CLGET_SVC_ADDR Ta "struct netbuf *" Ta "get servers address"
|
||||
.It Dv CLGET_FD Ta "int *" Ta "get fd from handle"
|
||||
.It Dv CLSET_FD_CLOSE Ta "void" Ta "close fd on destroy"
|
||||
.It Dv CLSET_FD_NCLOSE Ta void Ta "don't close fd on destroy"
|
||||
.It Dv CLGET_VERS Ta "unsigned long *" Ta "get RPC program version"
|
||||
.It Dv CLSET_VERS Ta "unsigned long *" Ta "set RPC program version"
|
||||
.It Dv CLGET_XID Ta "unsigned long *" Ta "get XID of previous call"
|
||||
.It Dv CLSET_XID Ta "unsigned long *" Ta "set XID of next call"
|
||||
.El
|
||||
.Pp
|
||||
The following operations are valid for connectionless transports only:
|
||||
.Bl -column CLSET_RETRY_TIMEOUT "struct timeval *" "set total timeout"
|
||||
.It Dv CLSET_RETRY_TIMEOUT Ta "struct timeval *" Ta "set the retry timeout"
|
||||
.It Dv CLGET_RETRY_TIMEOUT Ta "struct timeval *" Ta "get the retry timeout"
|
||||
.El
|
||||
.Pp
|
||||
The retry timeout is the time that RPC
|
||||
waits for the server to reply before retransmitting the request.
|
||||
.Fn clnt_control
|
||||
returns
|
||||
.Dv TRUE
|
||||
on success and
|
||||
.Dv FALSE
|
||||
on failure.
|
||||
.It Fn clnt_create
|
||||
Generic client creation routine for program
|
||||
.Fa prognum
|
||||
and version
|
||||
.Fa versnum .
|
||||
.Fa host
|
||||
identifies the name of the remote host where the server
|
||||
is located.
|
||||
.Fa nettype
|
||||
indicates the class of transport protocol to use.
|
||||
The transports are tried in left to right order in
|
||||
.Ev NETPATH
|
||||
environment variable or in top to bottom order in
|
||||
the netconfig database.
|
||||
.Fn clnt_create
|
||||
tries all the transports of the
|
||||
.Fa nettype
|
||||
class available from the
|
||||
.Ev NETPATH
|
||||
environment variable and the netconfig database,
|
||||
and chooses the first successful one.
|
||||
A default timeout is set and can be modified using
|
||||
.Fn clnt_control .
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
The
|
||||
.Fn clnt_pcreateerror
|
||||
routine can be used to print the reason for failure.
|
||||
.Pp
|
||||
Note:
|
||||
.Fn clnt_create
|
||||
returns a valid client handle even
|
||||
if the particular version number supplied to
|
||||
.Fn clnt_create
|
||||
is not registered with the
|
||||
.Xr rpcbind 8
|
||||
service.
|
||||
This mismatch will be discovered by a
|
||||
.Fn clnt_call
|
||||
later (see
|
||||
.Xr rpc_clnt_calls 3 ) .
|
||||
.It Fn clnt_create_vers
|
||||
Generic client creation routine which is similar to
|
||||
.Fn clnt_create
|
||||
but which also checks for the
|
||||
version availability.
|
||||
.Fa host
|
||||
identifies the name of the remote host where the server
|
||||
is located.
|
||||
.Fa nettype
|
||||
indicates the class transport protocols to be used.
|
||||
If the routine is successful it returns a client handle created for
|
||||
the highest version between
|
||||
.Fa vers_low
|
||||
and
|
||||
.Fa vers_high
|
||||
that is supported by the server.
|
||||
.Fa vers_outp
|
||||
is set to this value.
|
||||
That is, after a successful return
|
||||
.Fa vers_low
|
||||
<=
|
||||
.Fa *vers_outp
|
||||
<=
|
||||
.Fa vers_high .
|
||||
If no version between
|
||||
.Fa vers_low
|
||||
and
|
||||
.Fa vers_high
|
||||
is supported by the server then the routine fails and returns
|
||||
.Dv NULL .
|
||||
A default timeout is set and can be modified using
|
||||
.Fn clnt_control .
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
The
|
||||
.Fn clnt_pcreateerror
|
||||
routine can be used to print the reason for failure.
|
||||
Note:
|
||||
.Fn clnt_create
|
||||
returns a valid client handle even
|
||||
if the particular version number supplied to
|
||||
.Fn clnt_create
|
||||
is not registered with the
|
||||
.Xr rpcbind 8
|
||||
service.
|
||||
This mismatch will be discovered by a
|
||||
.Fn clnt_call
|
||||
later (see
|
||||
.Xr rpc_clnt_calls 3 ) .
|
||||
However,
|
||||
.Fn clnt_create_vers
|
||||
does this for you and returns a valid handle
|
||||
only if a version within
|
||||
the range supplied is supported by the server.
|
||||
.It Fn clnt_destroy
|
||||
A function macro that destroys the client's RPC handle.
|
||||
Destruction usually involves deallocation
|
||||
of private data structures, including
|
||||
.Fa clnt
|
||||
itself.
|
||||
Use of
|
||||
.Fa clnt
|
||||
is undefined after calling
|
||||
.Fn clnt_destroy .
|
||||
If the RPC library opened the associated file descriptor, or
|
||||
.Dv CLSET_FD_CLOSE
|
||||
was set using
|
||||
.Fn clnt_control ,
|
||||
the file descriptor will be closed.
|
||||
The caller should call
|
||||
.Fn auth_destroy "clnt->cl_auth"
|
||||
(before calling
|
||||
.Fn clnt_destroy )
|
||||
to destroy the associated
|
||||
.Vt AUTH
|
||||
structure (see
|
||||
.Xr rpc_clnt_auth 3 ) .
|
||||
.It Fn clnt_dg_create
|
||||
This routine creates an RPC client for the remote program
|
||||
.Fa prognum
|
||||
and version
|
||||
.Fa versnum ;
|
||||
the client uses a connectionless transport.
|
||||
The remote program is located at address
|
||||
.Fa svcaddr .
|
||||
The parameter
|
||||
.Fa fildes
|
||||
is an open and bound file descriptor.
|
||||
This routine will resend the call message in intervals of
|
||||
15 seconds until a response is received or until the
|
||||
call times out.
|
||||
The total time for the call to time out is specified by
|
||||
.Fn clnt_call
|
||||
(see
|
||||
.Fn clnt_call
|
||||
in
|
||||
.Xr rpc_clnt_calls 3 ) .
|
||||
The retry time out and the total time out periods can
|
||||
be changed using
|
||||
.Fn clnt_control .
|
||||
The user may set the size of the send and receive
|
||||
buffers with the parameters
|
||||
.Fa sendsz
|
||||
and
|
||||
.Fa recvsz ;
|
||||
values of 0 choose suitable defaults.
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
.It Fn clnt_pcreateerror
|
||||
Print a message to standard error indicating
|
||||
why a client RPC handle could not be created.
|
||||
The message is prepended with the string
|
||||
.Fa s
|
||||
and a colon, and appended with a newline.
|
||||
.It Fn clnt_spcreateerror
|
||||
Like
|
||||
.Fn clnt_pcreateerror ,
|
||||
except that it returns a string
|
||||
instead of printing to the standard error.
|
||||
A newline is not appended to the message in this case.
|
||||
Warning:
|
||||
returns a pointer to a buffer that is overwritten
|
||||
on each call.
|
||||
.It Fn clnt_raw_create
|
||||
This routine creates an RPC
|
||||
client handle for the remote program
|
||||
.Fa prognum
|
||||
and version
|
||||
.Fa versnum .
|
||||
The transport used to pass messages to the service is
|
||||
a buffer within the process's address space,
|
||||
so the corresponding RPC
|
||||
server should live in the same address space;
|
||||
(see
|
||||
.Fn svc_raw_create
|
||||
in
|
||||
.Xr rpc_svc_create 3 ) .
|
||||
This allows simulation of RPC and measurement of
|
||||
RPC overheads, such as round trip times,
|
||||
without any kernel or networking interference.
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
.Fn clnt_raw_create
|
||||
should be called after
|
||||
.Fn svc_raw_create .
|
||||
.It Fn clnt_tli_create
|
||||
This routine creates an RPC
|
||||
client handle for the remote program
|
||||
.Fa prognum
|
||||
and version
|
||||
.Fa versnum .
|
||||
The remote program is located at address
|
||||
.Fa svcaddr .
|
||||
If
|
||||
.Fa svcaddr
|
||||
is
|
||||
.Dv NULL
|
||||
and it is connection-oriented, it is assumed that the file descriptor
|
||||
is connected.
|
||||
For connectionless transports, if
|
||||
.Fa svcaddr
|
||||
is
|
||||
.Dv NULL ,
|
||||
.Dv RPC_UNKNOWNADDR
|
||||
error is set.
|
||||
.Fa fildes
|
||||
is a file descriptor which may be open, bound and connected.
|
||||
If it is
|
||||
.Dv RPC_ANYFD ,
|
||||
it opens a file descriptor on the transport specified by
|
||||
.Fa netconf .
|
||||
If
|
||||
.Fa fildes
|
||||
is
|
||||
.Dv RPC_ANYFD
|
||||
and
|
||||
.Fa netconf
|
||||
is
|
||||
.Dv NULL ,
|
||||
a
|
||||
.Dv RPC_UNKNOWNPROTO
|
||||
error is set.
|
||||
If
|
||||
.Fa fildes
|
||||
is unbound, then it will attempt to bind the descriptor.
|
||||
The user may specify the size of the buffers with the parameters
|
||||
.Fa sendsz
|
||||
and
|
||||
.Fa recvsz ;
|
||||
values of 0 choose suitable defaults.
|
||||
Depending upon the type of the transport (connection-oriented
|
||||
or connectionless),
|
||||
.Fn clnt_tli_create
|
||||
calls appropriate client creation routines.
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
The
|
||||
.Fn clnt_pcreateerror
|
||||
routine can be used to print the reason for failure.
|
||||
The remote rpcbind
|
||||
service (see
|
||||
.Xr rpcbind 8 )
|
||||
is not consulted for the address of the remote
|
||||
service.
|
||||
.It Fn clnt_tp_create
|
||||
Like
|
||||
.Fn clnt_create
|
||||
except
|
||||
.Fn clnt_tp_create
|
||||
tries only one transport specified through
|
||||
.Fa netconf .
|
||||
.Fn clnt_tp_create
|
||||
creates a client handle for the program
|
||||
.Fa prognum ,
|
||||
the version
|
||||
.Fa versnum ,
|
||||
and for the transport specified by
|
||||
.Fa netconf .
|
||||
Default options are set,
|
||||
which can be changed using
|
||||
.Fn clnt_control
|
||||
calls.
|
||||
The remote rpcbind service on the host
|
||||
.Fa host
|
||||
is consulted for the address of the remote service.
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
The
|
||||
.Fn clnt_pcreateerror
|
||||
routine can be used to print the reason for failure.
|
||||
.It Fn clnt_vc_create
|
||||
This routine creates an RPC
|
||||
client for the remote program
|
||||
.Fa prognum
|
||||
and version
|
||||
.Fa versnum ;
|
||||
the client uses a connection-oriented transport.
|
||||
The remote program is located at address
|
||||
.Fa svcaddr .
|
||||
The parameter
|
||||
.Fa fildes
|
||||
is an open and bound file descriptor.
|
||||
The user may specify the size of the send and receive buffers
|
||||
with the parameters
|
||||
.Fa sendsz
|
||||
and
|
||||
.Fa recvsz ;
|
||||
values of 0 choose suitable defaults.
|
||||
This routine returns
|
||||
.Dv NULL
|
||||
if it fails.
|
||||
The address
|
||||
.Fa svcaddr
|
||||
should not be
|
||||
.Dv NULL
|
||||
and should point to the actual address of the remote program.
|
||||
.Fn clnt_vc_create
|
||||
does not consult the remote rpcbind service for this information.
|
||||
.It Xo
|
||||
.Vt "struct rpc_createerr" Va rpc_createerr ;
|
||||
.Xc
|
||||
A global variable whose value is set by any RPC
|
||||
client handle creation routine
|
||||
that fails.
|
||||
It is used by the routine
|
||||
.Fn clnt_pcreateerror
|
||||
to print the reason for the failure.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr rpc 3 ,
|
||||
.Xr rpc_clnt_auth 3 ,
|
||||
.Xr rpc_clnt_calls 3 ,
|
||||
.Xr rpcbind 8
|
85
lib/libc/rpc/rpc_com.h
Normal file
85
lib/libc/rpc/rpc_com.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* $NetBSD: rpc_com.h,v 1.3 2000/12/10 04:10:08 christos Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* rpc_com.h, Common definitions for both the server and client side.
|
||||
* All for the topmost layer of rpc
|
||||
*
|
||||
* In Sun's tirpc distribution, this was installed as <rpc/rpc_com.h>,
|
||||
* but as it contains only non-exported interfaces, it was moved here.
|
||||
*/
|
||||
|
||||
#ifndef _RPC_RPCCOM_H
|
||||
#define _RPC_RPCCOM_H
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/* #pragma ident "@(#)rpc_com.h 1.11 93/07/05 SMI" */
|
||||
|
||||
/*
|
||||
* The max size of the transport, if the size cannot be determined
|
||||
* by other means.
|
||||
*/
|
||||
#define RPC_MAXDATASIZE 9000
|
||||
#define RPC_MAXADDRSIZE 1024
|
||||
|
||||
#define __RPC_GETXID(now) ((u_int32_t)getpid() ^ (u_int32_t)(now)->tv_sec ^ \
|
||||
(u_int32_t)(now)->tv_usec)
|
||||
|
||||
__BEGIN_DECLS
|
||||
extern u_int __rpc_get_a_size __P((int));
|
||||
extern int __rpc_dtbsize __P((void));
|
||||
extern struct netconfig * __rpcgettp __P((int));
|
||||
extern int __rpc_get_default_domain __P((char **));
|
||||
|
||||
char *__rpc_taddr2uaddr_af __P((int, const struct netbuf *));
|
||||
struct netbuf *__rpc_uaddr2taddr_af __P((int, const char *));
|
||||
int __rpc_fixup_addr __P((struct netbuf *, const struct netbuf *));
|
||||
int __rpc_sockinfo2netid __P((struct __rpc_sockinfo *, const char **));
|
||||
int __rpc_seman2socktype __P((int));
|
||||
int __rpc_socktype2seman __P((int));
|
||||
void *rpc_nullproc __P((CLIENT *));
|
||||
int __rpc_sockisbound __P((int));
|
||||
|
||||
struct netbuf *__rpcb_findaddr __P((rpcprog_t, rpcvers_t,
|
||||
const struct netconfig *,
|
||||
const char *, CLIENT **));
|
||||
bool_t __rpc_control __P((int,void *));
|
||||
|
||||
char *_get_next_token __P((char *, int));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RPC_RPCCOM_H */
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc_commondata.c,v 1.7 2000/06/02 23:11:13 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -5,39 +7,42 @@
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
#include "namespace.h"
|
||||
#include <rpc/rpc.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
/*
|
||||
* This file should only contain common data (global data) that is exported
|
||||
* by public interfaces
|
||||
* by public interfaces
|
||||
*/
|
||||
struct opaque_auth _null_auth;
|
||||
fd_set svc_fdset;
|
||||
int svc_maxfd = -1;
|
||||
struct rpc_createerr rpc_createerr;
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc_dtablesize.c,v 1.14 1998/11/15 17:32:43 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,14 +29,18 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "namespace.h"
|
||||
#include <unistd.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
int _rpc_dtablesize __P((void)); /* XXX */
|
||||
|
||||
/*
|
||||
* Cache the result of getdtablesize(), so we don't have to do an
|
||||
|
816
lib/libc/rpc/rpc_generic.c
Normal file
816
lib/libc/rpc/rpc_generic.c
Normal file
@ -0,0 +1,816 @@
|
||||
/* $NetBSD: rpc_generic.c,v 1.4 2000/09/28 09:07:04 kleink Exp $ */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
* media and as a part of the software program in whole or part. Users
|
||||
* may copy or modify Sun RPC without charge, but are not authorized
|
||||
* to license or distribute it to anyone else except as part of a product or
|
||||
* program developed by the user.
|
||||
*
|
||||
* SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
|
||||
* WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
|
||||
*
|
||||
* Sun RPC is provided with no support and without any obligation on the
|
||||
* part of Sun Microsystems, Inc. to assist in its use, correction,
|
||||
* modification or enhancement.
|
||||
*
|
||||
* SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
|
||||
* INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
|
||||
* OR ANY PART THEREOF.
|
||||
*
|
||||
* In no event will Sun Microsystems, Inc. be liable for any lost revenue
|
||||
* or profits or other special, indirect and consequential damages, even if
|
||||
* Sun has been advised of the possibility of such damages.
|
||||
*
|
||||
* Sun Microsystems, Inc.
|
||||
* 2550 Garcia Avenue
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
/* #pragma ident "@(#)rpc_generic.c 1.17 94/04/24 SMI" */
|
||||
|
||||
/*
|
||||
* rpc_generic.c, Miscl routines for RPC.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "reentrant.h"
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/resource.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <netconfig.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <rpc/nettype.h>
|
||||
#include "un-namespace.h"
|
||||
#include "rpc_com.h"
|
||||
|
||||
struct handle {
|
||||
NCONF_HANDLE *nhandle;
|
||||
int nflag; /* Whether NETPATH or NETCONFIG */
|
||||
int nettype;
|
||||
};
|
||||
|
||||
static const struct _rpcnettype {
|
||||
const char *name;
|
||||
const int type;
|
||||
} _rpctypelist[] = {
|
||||
{ "netpath", _RPC_NETPATH },
|
||||
{ "visible", _RPC_VISIBLE },
|
||||
{ "circuit_v", _RPC_CIRCUIT_V },
|
||||
{ "datagram_v", _RPC_DATAGRAM_V },
|
||||
{ "circuit_n", _RPC_CIRCUIT_N },
|
||||
{ "datagram_n", _RPC_DATAGRAM_N },
|
||||
{ "tcp", _RPC_TCP },
|
||||
{ "udp", _RPC_UDP },
|
||||
{ 0, _RPC_NONE }
|
||||
};
|
||||
|
||||
struct netid_af {
|
||||
const char *netid;
|
||||
int af;
|
||||
int protocol;
|
||||
};
|
||||
|
||||
static const struct netid_af na_cvt[] = {
|
||||
{ "udp", AF_INET, IPPROTO_UDP },
|
||||
{ "tcp", AF_INET, IPPROTO_TCP },
|
||||
#ifdef INET6
|
||||
{ "udp6", AF_INET6, IPPROTO_UDP },
|
||||
{ "tcp6", AF_INET6, IPPROTO_TCP },
|
||||
#endif
|
||||
{ "unix", AF_LOCAL, 0 }
|
||||
};
|
||||
|
||||
#if 0
|
||||
static char *strlocase __P((char *));
|
||||
#endif
|
||||
static int getnettype __P((const char *));
|
||||
|
||||
/*
|
||||
* Cache the result of getrlimit(), so we don't have to do an
|
||||
* expensive call every time.
|
||||
*/
|
||||
int
|
||||
__rpc_dtbsize()
|
||||
{
|
||||
static int tbsize;
|
||||
struct rlimit rl;
|
||||
|
||||
if (tbsize) {
|
||||
return (tbsize);
|
||||
}
|
||||
if (getrlimit(RLIMIT_NOFILE, &rl) == 0) {
|
||||
return (tbsize = (int)rl.rlim_max);
|
||||
}
|
||||
/*
|
||||
* Something wrong. I'll try to save face by returning a
|
||||
* pessimistic number.
|
||||
*/
|
||||
return (32);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find the appropriate buffer size
|
||||
*/
|
||||
u_int
|
||||
/*ARGSUSED*/
|
||||
__rpc_get_t_size(af, proto, size)
|
||||
int af, proto;
|
||||
int size; /* Size requested */
|
||||
{
|
||||
int maxsize;
|
||||
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP:
|
||||
maxsize = 65536; /* XXX */
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
maxsize = 8192; /* XXX */
|
||||
break;
|
||||
default:
|
||||
maxsize = RPC_MAXDATASIZE;
|
||||
break;
|
||||
}
|
||||
if (size == 0)
|
||||
return maxsize;
|
||||
|
||||
/* Check whether the value is within the upper max limit */
|
||||
return (size > maxsize ? (u_int)maxsize : (u_int)size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the appropriate address buffer size
|
||||
*/
|
||||
u_int
|
||||
__rpc_get_a_size(af)
|
||||
int af;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return sizeof (struct sockaddr_in);
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return sizeof (struct sockaddr_in6);
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
return sizeof (struct sockaddr_un);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ((u_int)RPC_MAXADDRSIZE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static char *
|
||||
strlocase(p)
|
||||
char *p;
|
||||
{
|
||||
char *t = p;
|
||||
|
||||
for (; *p; p++)
|
||||
if (isupper(*p))
|
||||
*p = tolower(*p);
|
||||
return (t);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns the type of the network as defined in <rpc/nettype.h>
|
||||
* If nettype is NULL, it defaults to NETPATH.
|
||||
*/
|
||||
static int
|
||||
getnettype(nettype)
|
||||
const char *nettype;
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((nettype == NULL) || (nettype[0] == NULL)) {
|
||||
return (_RPC_NETPATH); /* Default */
|
||||
}
|
||||
|
||||
#if 0
|
||||
nettype = strlocase(nettype);
|
||||
#endif
|
||||
for (i = 0; _rpctypelist[i].name; i++)
|
||||
if (strcasecmp(nettype, _rpctypelist[i].name) == 0) {
|
||||
return (_rpctypelist[i].type);
|
||||
}
|
||||
return (_rpctypelist[i].type);
|
||||
}
|
||||
|
||||
/*
|
||||
* For the given nettype (tcp or udp only), return the first structure found.
|
||||
* This should be freed by calling freenetconfigent()
|
||||
*/
|
||||
struct netconfig *
|
||||
__rpc_getconfip(nettype)
|
||||
const char *nettype;
|
||||
{
|
||||
char *netid;
|
||||
char *netid_tcp = (char *) NULL;
|
||||
char *netid_udp = (char *) NULL;
|
||||
static char *netid_tcp_main;
|
||||
static char *netid_udp_main;
|
||||
struct netconfig *dummy;
|
||||
int main_thread;
|
||||
static thread_key_t tcp_key, udp_key;
|
||||
extern mutex_t tsd_lock;
|
||||
|
||||
if ((main_thread = thr_main())) {
|
||||
netid_udp = netid_udp_main;
|
||||
netid_tcp = netid_tcp_main;
|
||||
} else {
|
||||
if (tcp_key == 0) {
|
||||
mutex_lock(&tsd_lock);
|
||||
if (tcp_key == 0)
|
||||
thr_keycreate(&tcp_key, free);
|
||||
mutex_unlock(&tsd_lock);
|
||||
}
|
||||
netid_tcp = (char *)thr_getspecific(tcp_key);
|
||||
if (udp_key == 0) {
|
||||
mutex_lock(&tsd_lock);
|
||||
if (udp_key == 0)
|
||||
thr_keycreate(&udp_key, free);
|
||||
mutex_unlock(&tsd_lock);
|
||||
}
|
||||
netid_udp = (char *)thr_getspecific(udp_key);
|
||||
}
|
||||
if (!netid_udp && !netid_tcp) {
|
||||
struct netconfig *nconf;
|
||||
void *confighandle;
|
||||
|
||||
if (!(confighandle = setnetconfig())) {
|
||||
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||
return (NULL);
|
||||
}
|
||||
while ((nconf = getnetconfig(confighandle)) != NULL) {
|
||||
if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
|
||||
if (strcmp(nconf->nc_proto, NC_TCP) == 0) {
|
||||
netid_tcp = strdup(nconf->nc_netid);
|
||||
if (main_thread)
|
||||
netid_tcp_main = netid_tcp;
|
||||
else
|
||||
thr_setspecific(tcp_key,
|
||||
(void *) netid_tcp);
|
||||
} else
|
||||
if (strcmp(nconf->nc_proto, NC_UDP) == 0) {
|
||||
netid_udp = strdup(nconf->nc_netid);
|
||||
if (main_thread)
|
||||
netid_udp_main = netid_udp;
|
||||
else
|
||||
thr_setspecific(udp_key,
|
||||
(void *) netid_udp);
|
||||
}
|
||||
}
|
||||
}
|
||||
endnetconfig(confighandle);
|
||||
}
|
||||
if (strcmp(nettype, "udp") == 0)
|
||||
netid = netid_udp;
|
||||
else if (strcmp(nettype, "tcp") == 0)
|
||||
netid = netid_tcp;
|
||||
else {
|
||||
return (NULL);
|
||||
}
|
||||
if ((netid == NULL) || (netid[0] == NULL)) {
|
||||
return (NULL);
|
||||
}
|
||||
dummy = getnetconfigent(netid);
|
||||
return (dummy);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the type of the nettype, which should then be used with
|
||||
* __rpc_getconf().
|
||||
*/
|
||||
void *
|
||||
__rpc_setconf(nettype)
|
||||
const char *nettype;
|
||||
{
|
||||
struct handle *handle;
|
||||
|
||||
handle = (struct handle *) malloc(sizeof (struct handle));
|
||||
if (handle == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
switch (handle->nettype = getnettype(nettype)) {
|
||||
case _RPC_NETPATH:
|
||||
case _RPC_CIRCUIT_N:
|
||||
case _RPC_DATAGRAM_N:
|
||||
if (!(handle->nhandle = setnetpath())) {
|
||||
free(handle);
|
||||
return (NULL);
|
||||
}
|
||||
handle->nflag = TRUE;
|
||||
break;
|
||||
case _RPC_VISIBLE:
|
||||
case _RPC_CIRCUIT_V:
|
||||
case _RPC_DATAGRAM_V:
|
||||
case _RPC_TCP:
|
||||
case _RPC_UDP:
|
||||
if (!(handle->nhandle = setnetconfig())) {
|
||||
syslog (LOG_ERR, "rpc: failed to open " NETCONFIG);
|
||||
free(handle);
|
||||
return (NULL);
|
||||
}
|
||||
handle->nflag = FALSE;
|
||||
break;
|
||||
default:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the next netconfig struct for the given "net" type.
|
||||
* __rpc_setconf() should have been called previously.
|
||||
*/
|
||||
struct netconfig *
|
||||
__rpc_getconf(vhandle)
|
||||
void *vhandle;
|
||||
{
|
||||
struct handle *handle;
|
||||
struct netconfig *nconf;
|
||||
|
||||
handle = (struct handle *)vhandle;
|
||||
if (handle == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
for (;;) {
|
||||
if (handle->nflag)
|
||||
nconf = getnetpath(handle->nhandle);
|
||||
else
|
||||
nconf = getnetconfig(handle->nhandle);
|
||||
if (nconf == NULL)
|
||||
break;
|
||||
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS_ORD))
|
||||
continue;
|
||||
switch (handle->nettype) {
|
||||
case _RPC_VISIBLE:
|
||||
if (!(nconf->nc_flag & NC_VISIBLE))
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case _RPC_NETPATH: /* Be happy */
|
||||
break;
|
||||
case _RPC_CIRCUIT_V:
|
||||
if (!(nconf->nc_flag & NC_VISIBLE))
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case _RPC_CIRCUIT_N:
|
||||
if ((nconf->nc_semantics != NC_TPI_COTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS_ORD))
|
||||
continue;
|
||||
break;
|
||||
case _RPC_DATAGRAM_V:
|
||||
if (!(nconf->nc_flag & NC_VISIBLE))
|
||||
continue;
|
||||
/* FALLTHROUGH */
|
||||
case _RPC_DATAGRAM_N:
|
||||
if (nconf->nc_semantics != NC_TPI_CLTS)
|
||||
continue;
|
||||
break;
|
||||
case _RPC_TCP:
|
||||
if (((nconf->nc_semantics != NC_TPI_COTS) &&
|
||||
(nconf->nc_semantics != NC_TPI_COTS_ORD)) ||
|
||||
(strcmp(nconf->nc_protofmly, NC_INET)
|
||||
#ifdef INET6
|
||||
&& strcmp(nconf->nc_protofmly, NC_INET6))
|
||||
#else
|
||||
)
|
||||
#endif
|
||||
||
|
||||
strcmp(nconf->nc_proto, NC_TCP))
|
||||
continue;
|
||||
break;
|
||||
case _RPC_UDP:
|
||||
if ((nconf->nc_semantics != NC_TPI_CLTS) ||
|
||||
(strcmp(nconf->nc_protofmly, NC_INET)
|
||||
#ifdef INET6
|
||||
&& strcmp(nconf->nc_protofmly, NC_INET6))
|
||||
#else
|
||||
)
|
||||
#endif
|
||||
||
|
||||
strcmp(nconf->nc_proto, NC_UDP))
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (nconf);
|
||||
}
|
||||
|
||||
void
|
||||
__rpc_endconf(vhandle)
|
||||
void * vhandle;
|
||||
{
|
||||
struct handle *handle;
|
||||
|
||||
handle = (struct handle *) vhandle;
|
||||
if (handle == NULL) {
|
||||
return;
|
||||
}
|
||||
if (handle->nflag) {
|
||||
endnetpath(handle->nhandle);
|
||||
} else {
|
||||
endnetconfig(handle->nhandle);
|
||||
}
|
||||
free(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to ping the NULL procedure for clnt handle.
|
||||
* Returns NULL if fails, else a non-NULL pointer.
|
||||
*/
|
||||
void *
|
||||
rpc_nullproc(clnt)
|
||||
CLIENT *clnt;
|
||||
{
|
||||
struct timeval TIMEOUT = {25, 0};
|
||||
|
||||
if (clnt_call(clnt, NULLPROC, (xdrproc_t) xdr_void, NULL,
|
||||
(xdrproc_t) xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
|
||||
return (NULL);
|
||||
}
|
||||
return ((void *) clnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try all possible transports until
|
||||
* one succeeds in finding the netconf for the given fd.
|
||||
*/
|
||||
struct netconfig *
|
||||
__rpcgettp(fd)
|
||||
int fd;
|
||||
{
|
||||
const char *netid;
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (!__rpc_fd2sockinfo(fd, &si))
|
||||
return NULL;
|
||||
|
||||
if (!__rpc_sockinfo2netid(&si, &netid))
|
||||
return NULL;
|
||||
|
||||
/*LINTED const castaway*/
|
||||
return getnetconfigent((char *)netid);
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_fd2sockinfo(int fd, struct __rpc_sockinfo *sip)
|
||||
{
|
||||
socklen_t len;
|
||||
int type, proto;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
len = sizeof ss;
|
||||
if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &len) < 0)
|
||||
return 0;
|
||||
sip->si_alen = len;
|
||||
|
||||
len = sizeof type;
|
||||
if (_getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len) < 0)
|
||||
return 0;
|
||||
|
||||
/* XXX */
|
||||
if (ss.ss_family != AF_LOCAL) {
|
||||
if (type == SOCK_STREAM)
|
||||
proto = IPPROTO_TCP;
|
||||
else if (type == SOCK_DGRAM)
|
||||
proto = IPPROTO_UDP;
|
||||
else
|
||||
return 0;
|
||||
} else
|
||||
proto = 0;
|
||||
|
||||
sip->si_af = ss.ss_family;
|
||||
sip->si_proto = proto;
|
||||
sip->si_socktype = type;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Linear search, but the number of entries is small.
|
||||
*/
|
||||
int
|
||||
__rpc_nconf2sockinfo(const struct netconfig *nconf, struct __rpc_sockinfo *sip)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
|
||||
if (!strcmp(na_cvt[i].netid, nconf->nc_netid)) {
|
||||
sip->si_af = na_cvt[i].af;
|
||||
sip->si_proto = na_cvt[i].protocol;
|
||||
sip->si_socktype =
|
||||
__rpc_seman2socktype((int)nconf->nc_semantics);
|
||||
if (sip->si_socktype == -1)
|
||||
return 0;
|
||||
sip->si_alen = __rpc_get_a_size(sip->si_af);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_nconf2fd(const struct netconfig *nconf)
|
||||
{
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (!__rpc_nconf2sockinfo(nconf, &si))
|
||||
return 0;
|
||||
|
||||
return _socket(si.si_af, si.si_socktype, si.si_proto);
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_sockinfo2netid(struct __rpc_sockinfo *sip, const char **netid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (sizeof na_cvt) / (sizeof (struct netid_af)); i++)
|
||||
if (na_cvt[i].af == sip->si_af &&
|
||||
na_cvt[i].protocol == sip->si_proto) {
|
||||
if (netid)
|
||||
*netid = na_cvt[i].netid;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
taddr2uaddr(const struct netconfig *nconf, const struct netbuf *nbuf)
|
||||
{
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (!__rpc_nconf2sockinfo(nconf, &si))
|
||||
return NULL;
|
||||
return __rpc_taddr2uaddr_af(si.si_af, nbuf);
|
||||
}
|
||||
|
||||
struct netbuf *
|
||||
uaddr2taddr(const struct netconfig *nconf, const char *uaddr)
|
||||
{
|
||||
struct __rpc_sockinfo si;
|
||||
|
||||
if (!__rpc_nconf2sockinfo(nconf, &si))
|
||||
return NULL;
|
||||
return __rpc_uaddr2taddr_af(si.si_af, uaddr);
|
||||
}
|
||||
|
||||
char *
|
||||
__rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf)
|
||||
{
|
||||
char *ret;
|
||||
struct sockaddr_in *sin;
|
||||
struct sockaddr_un *sun;
|
||||
char namebuf[INET_ADDRSTRLEN];
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
char namebuf6[INET6_ADDRSTRLEN];
|
||||
#endif
|
||||
u_int16_t port;
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
sin = nbuf->buf;
|
||||
if (inet_ntop(af, &sin->sin_addr, namebuf, sizeof namebuf)
|
||||
== NULL)
|
||||
return NULL;
|
||||
port = ntohs(sin->sin_port);
|
||||
if (asprintf(&ret, "%s.%u.%u", namebuf, ((u_int32_t)port) >> 8,
|
||||
port & 0xff) < 0)
|
||||
return NULL;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = nbuf->buf;
|
||||
if (inet_ntop(af, &sin6->sin6_addr, namebuf6, sizeof namebuf6)
|
||||
== NULL)
|
||||
return NULL;
|
||||
port = ntohs(sin6->sin6_port);
|
||||
if (asprintf(&ret, "%s.%u.%u", namebuf6, ((u_int32_t)port) >> 8,
|
||||
port & 0xff) < 0)
|
||||
return NULL;
|
||||
break;
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
sun = nbuf->buf;
|
||||
sun->sun_path[sizeof(sun->sun_path) - 1] = '\0'; /* safety */
|
||||
ret = strdup(sun->sun_path);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct netbuf *
|
||||
__rpc_uaddr2taddr_af(int af, const char *uaddr)
|
||||
{
|
||||
struct netbuf *ret = NULL;
|
||||
char *addrstr, *p;
|
||||
unsigned port, portlo, porthi;
|
||||
struct sockaddr_in *sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
struct sockaddr_un *sun;
|
||||
|
||||
addrstr = strdup(uaddr);
|
||||
if (addrstr == NULL)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* AF_LOCAL addresses are expected to be absolute
|
||||
* pathnames, anything else will be AF_INET or AF_INET6.
|
||||
*/
|
||||
if (*addrstr != '/') {
|
||||
p = strrchr(addrstr, '.');
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
portlo = (unsigned)atoi(p + 1);
|
||||
*p = '\0';
|
||||
|
||||
p = strrchr(addrstr, '.');
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
porthi = (unsigned)atoi(p + 1);
|
||||
*p = '\0';
|
||||
port = (porthi << 8) | portlo;
|
||||
}
|
||||
|
||||
ret = (struct netbuf *)malloc(sizeof *ret);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)malloc(sizeof *sin);
|
||||
if (sin == NULL)
|
||||
goto out;
|
||||
memset(sin, 0, sizeof *sin);
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(port);
|
||||
if (inet_pton(AF_INET, addrstr, &sin->sin_addr) <= 0) {
|
||||
free(sin);
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
goto out;
|
||||
}
|
||||
sin->sin_len = ret->maxlen = ret->len = sizeof *sin;
|
||||
ret->buf = sin;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *)malloc(sizeof *sin6);
|
||||
if (sin6 == NULL)
|
||||
goto out;
|
||||
memset(sin6, 0, sizeof *sin6);
|
||||
sin6->sin6_family = AF_INET6;
|
||||
sin6->sin6_port = htons(port);
|
||||
if (inet_pton(AF_INET6, addrstr, &sin6->sin6_addr) <= 0) {
|
||||
free(sin);
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
goto out;
|
||||
}
|
||||
sin6->sin6_len = ret->maxlen = ret->len = sizeof *sin6;
|
||||
ret->buf = sin6;
|
||||
break;
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
sun = (struct sockaddr_un *)malloc(sizeof *sun);
|
||||
if (sun == NULL)
|
||||
goto out;
|
||||
memset(sun, 0, sizeof *sun);
|
||||
sun->sun_family = AF_LOCAL;
|
||||
strncpy(sun->sun_path, addrstr, sizeof(sun->sun_path) - 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
free(addrstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_seman2socktype(int semantics)
|
||||
{
|
||||
switch (semantics) {
|
||||
case NC_TPI_CLTS:
|
||||
return SOCK_DGRAM;
|
||||
case NC_TPI_COTS_ORD:
|
||||
return SOCK_STREAM;
|
||||
case NC_TPI_RAW:
|
||||
return SOCK_RAW;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_socktype2seman(int socktype)
|
||||
{
|
||||
switch (socktype) {
|
||||
case SOCK_DGRAM:
|
||||
return NC_TPI_CLTS;
|
||||
case SOCK_STREAM:
|
||||
return NC_TPI_COTS_ORD;
|
||||
case SOCK_RAW:
|
||||
return NC_TPI_RAW;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXXX - IPv6 scope IDs can't be handled in universal addresses.
|
||||
* Here, we compare the original server address to that of the RPC
|
||||
* service we just received back from a call to rpcbind on the remote
|
||||
* machine. If they are both "link local" or "site local", copy
|
||||
* the scope id of the server address over to the service address.
|
||||
*/
|
||||
int
|
||||
__rpc_fixup_addr(struct netbuf *new, const struct netbuf *svc)
|
||||
{
|
||||
#ifdef INET6
|
||||
struct sockaddr *sa_new, *sa_svc;
|
||||
struct sockaddr_in6 *sin6_new, *sin6_svc;
|
||||
|
||||
sa_svc = (struct sockaddr *)svc->buf;
|
||||
sa_new = (struct sockaddr *)new->buf;
|
||||
|
||||
if (sa_new->sa_family == sa_svc->sa_family &&
|
||||
sa_new->sa_family == AF_INET6) {
|
||||
sin6_new = (struct sockaddr_in6 *)new->buf;
|
||||
sin6_svc = (struct sockaddr_in6 *)svc->buf;
|
||||
|
||||
if ((IN6_IS_ADDR_LINKLOCAL(&sin6_new->sin6_addr) &&
|
||||
IN6_IS_ADDR_LINKLOCAL(&sin6_svc->sin6_addr)) ||
|
||||
(IN6_IS_ADDR_SITELOCAL(&sin6_new->sin6_addr) &&
|
||||
IN6_IS_ADDR_SITELOCAL(&sin6_svc->sin6_addr))) {
|
||||
sin6_new->sin6_scope_id = sin6_svc->sin6_scope_id;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
__rpc_sockisbound(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
|
||||
slen = sizeof (struct sockaddr_storage);
|
||||
if (_getsockname(fd, (struct sockaddr *)(void *)&ss, &slen) < 0)
|
||||
return 0;
|
||||
|
||||
switch (ss.ss_family) {
|
||||
case AF_INET:
|
||||
return (((struct sockaddr_in *)
|
||||
(void *)&ss)->sin_port != 0);
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return (((struct sockaddr_in6 *)
|
||||
(void *)&ss)->sin6_port != 0);
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
/* XXX check this */
|
||||
return (((struct sockaddr_un *)
|
||||
(void *)&ss)->sun_path[0] != '\0');
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
/* $NetBSD: rpc_prot.c,v 1.16 2000/06/02 23:11:13 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
|
||||
* unrestricted use provided that this legend is included on all tape
|
||||
@ -27,9 +29,10 @@
|
||||
* Mountain View, California 94043
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
|
||||
/*static char *sccsid = "from: @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";*/
|
||||
static char *sccsid = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
|
||||
static char *sccsid = "@(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC";
|
||||
static char *rcsid = "$FreeBSD$";
|
||||
#endif
|
||||
|
||||
@ -46,13 +49,20 @@ static char *rcsid = "$FreeBSD$";
|
||||
* routines are also in this program.
|
||||
*/
|
||||
|
||||
#include "namespace.h"
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
static void accepted __P((enum accept_stat, struct rpc_err *));
|
||||
static void rejected __P((enum reject_stat, struct rpc_err *));
|
||||
|
||||
/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
|
||||
|
||||
struct opaque_auth _null_auth;
|
||||
extern struct opaque_auth _null_auth;
|
||||
|
||||
/*
|
||||
* XDR an opaque authentication struct
|
||||
@ -60,10 +70,13 @@ struct opaque_auth _null_auth;
|
||||
*/
|
||||
bool_t
|
||||
xdr_opaque_auth(xdrs, ap)
|
||||
register XDR *xdrs;
|
||||
register struct opaque_auth *ap;
|
||||
XDR *xdrs;
|
||||
struct opaque_auth *ap;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(ap != NULL);
|
||||
|
||||
if (xdr_enum(xdrs, &(ap->oa_flavor)))
|
||||
return (xdr_bytes(xdrs, &ap->oa_base,
|
||||
&ap->oa_length, MAX_AUTH_BYTES));
|
||||
@ -75,10 +88,14 @@ xdr_opaque_auth(xdrs, ap)
|
||||
*/
|
||||
bool_t
|
||||
xdr_des_block(xdrs, blkp)
|
||||
register XDR *xdrs;
|
||||
register des_block *blkp;
|
||||
XDR *xdrs;
|
||||
des_block *blkp;
|
||||
{
|
||||
return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(blkp != NULL);
|
||||
|
||||
return (xdr_opaque(xdrs, (caddr_t)(void *)blkp, sizeof(des_block)));
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
|
||||
@ -88,10 +105,13 @@ xdr_des_block(xdrs, blkp)
|
||||
*/
|
||||
bool_t
|
||||
xdr_accepted_reply(xdrs, ar)
|
||||
register XDR *xdrs;
|
||||
register struct accepted_reply *ar;
|
||||
XDR *xdrs;
|
||||
struct accepted_reply *ar;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(ar != NULL);
|
||||
|
||||
/* personalized union, rather than calling xdr_union */
|
||||
if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
|
||||
return (FALSE);
|
||||
@ -106,7 +126,11 @@ xdr_accepted_reply(xdrs, ar)
|
||||
if (! xdr_u_int32_t(xdrs, &(ar->ar_vers.low)))
|
||||
return (FALSE);
|
||||
return (xdr_u_int32_t(xdrs, &(ar->ar_vers.high)));
|
||||
default:
|
||||
|
||||
case GARBAGE_ARGS:
|
||||
case SYSTEM_ERR:
|
||||
case PROC_UNAVAIL:
|
||||
case PROG_UNAVAIL:
|
||||
break;
|
||||
}
|
||||
return (TRUE); /* TRUE => open ended set of problems */
|
||||
@ -115,12 +139,15 @@ xdr_accepted_reply(xdrs, ar)
|
||||
/*
|
||||
* XDR the MSG_DENIED part of a reply message union
|
||||
*/
|
||||
bool_t
|
||||
bool_t
|
||||
xdr_rejected_reply(xdrs, rr)
|
||||
register XDR *xdrs;
|
||||
register struct rejected_reply *rr;
|
||||
XDR *xdrs;
|
||||
struct rejected_reply *rr;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(rr != NULL);
|
||||
|
||||
/* personalized union, rather than calling xdr_union */
|
||||
if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
|
||||
return (FALSE);
|
||||
@ -134,12 +161,14 @@ xdr_rejected_reply(xdrs, rr)
|
||||
case AUTH_ERROR:
|
||||
return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
|
||||
}
|
||||
/* NOTREACHED */
|
||||
assert(0);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
static struct xdr_discrim reply_dscrm[3] = {
|
||||
{ (int)MSG_ACCEPTED, xdr_accepted_reply },
|
||||
{ (int)MSG_DENIED, xdr_rejected_reply },
|
||||
static const struct xdr_discrim reply_dscrm[3] = {
|
||||
{ (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
|
||||
{ (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
|
||||
{ __dontcare__, NULL_xdrproc_t } };
|
||||
|
||||
/*
|
||||
@ -147,15 +176,19 @@ static struct xdr_discrim reply_dscrm[3] = {
|
||||
*/
|
||||
bool_t
|
||||
xdr_replymsg(xdrs, rmsg)
|
||||
register XDR *xdrs;
|
||||
register struct rpc_msg *rmsg;
|
||||
XDR *xdrs;
|
||||
struct rpc_msg *rmsg;
|
||||
{
|
||||
assert(xdrs != NULL);
|
||||
assert(rmsg != NULL);
|
||||
|
||||
if (
|
||||
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
|
||||
xdr_u_int32_t(xdrs, &(rmsg->rm_xid)) &&
|
||||
xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
|
||||
(rmsg->rm_direction == REPLY) )
|
||||
return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
|
||||
(caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
|
||||
(caddr_t)(void *)&(rmsg->rm_reply.ru), reply_dscrm,
|
||||
NULL_xdrproc_t));
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
@ -167,10 +200,13 @@ xdr_replymsg(xdrs, rmsg)
|
||||
*/
|
||||
bool_t
|
||||
xdr_callhdr(xdrs, cmsg)
|
||||
register XDR *xdrs;
|
||||
register struct rpc_msg *cmsg;
|
||||
XDR *xdrs;
|
||||
struct rpc_msg *cmsg;
|
||||
{
|
||||
|
||||
assert(xdrs != NULL);
|
||||
assert(cmsg != NULL);
|
||||
|
||||
cmsg->rm_direction = CALL;
|
||||
cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
|
||||
if (
|
||||
@ -179,7 +215,7 @@ xdr_callhdr(xdrs, cmsg)
|
||||
xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
|
||||
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
|
||||
xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) )
|
||||
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
|
||||
return (xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)));
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
@ -187,10 +223,12 @@ xdr_callhdr(xdrs, cmsg)
|
||||
|
||||
static void
|
||||
accepted(acpt_stat, error)
|
||||
register enum accept_stat acpt_stat;
|
||||
register struct rpc_err *error;
|
||||
enum accept_stat acpt_stat;
|
||||
struct rpc_err *error;
|
||||
{
|
||||
|
||||
assert(error != NULL);
|
||||
|
||||
switch (acpt_stat) {
|
||||
|
||||
case PROG_UNAVAIL:
|
||||
@ -217,34 +255,35 @@ accepted(acpt_stat, error)
|
||||
error->re_status = RPC_SUCCESS;
|
||||
return;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
/* something's wrong, but we don't know what ... */
|
||||
error->re_status = RPC_FAILED;
|
||||
error->re_lb.s1 = (long)MSG_ACCEPTED;
|
||||
error->re_lb.s2 = (long)acpt_stat;
|
||||
error->re_lb.s1 = (int32_t)MSG_ACCEPTED;
|
||||
error->re_lb.s2 = (int32_t)acpt_stat;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
rejected(rjct_stat, error)
|
||||
register enum reject_stat rjct_stat;
|
||||
register struct rpc_err *error;
|
||||
enum reject_stat rjct_stat;
|
||||
struct rpc_err *error;
|
||||
{
|
||||
|
||||
switch (rjct_stat) {
|
||||
assert(error != NULL);
|
||||
|
||||
case RPC_VERSMISMATCH:
|
||||
switch (rjct_stat) {
|
||||
case RPC_MISMATCH:
|
||||
error->re_status = RPC_VERSMISMATCH;
|
||||
return;
|
||||
|
||||
case AUTH_ERROR:
|
||||
error->re_status = RPC_AUTHERROR;
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* something's wrong, but we don't know what ... */
|
||||
/* NOTREACHED */
|
||||
error->re_status = RPC_FAILED;
|
||||
error->re_lb.s1 = (long)MSG_DENIED;
|
||||
error->re_lb.s2 = (long)rjct_stat;
|
||||
error->re_lb.s1 = (int32_t)MSG_DENIED;
|
||||
error->re_lb.s2 = (int32_t)rjct_stat;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -252,10 +291,13 @@ rejected(rjct_stat, error)
|
||||
*/
|
||||
void
|
||||
_seterr_reply(msg, error)
|
||||
register struct rpc_msg *msg;
|
||||
register struct rpc_err *error;
|
||||
struct rpc_msg *msg;
|
||||
struct rpc_err *error;
|
||||
{
|
||||
|
||||
assert(msg != NULL);
|
||||
assert(error != NULL);
|
||||
|
||||
/* optimized for normal, SUCCESSful case */
|
||||
switch (msg->rm_reply.rp_stat) {
|
||||
|
||||
@ -263,7 +305,7 @@ _seterr_reply(msg, error)
|
||||
if (msg->acpted_rply.ar_stat == SUCCESS) {
|
||||
error->re_status = RPC_SUCCESS;
|
||||
return;
|
||||
};
|
||||
}
|
||||
accepted(msg->acpted_rply.ar_stat, error);
|
||||
break;
|
||||
|
||||
@ -273,7 +315,7 @@ _seterr_reply(msg, error)
|
||||
|
||||
default:
|
||||
error->re_status = RPC_FAILED;
|
||||
error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
|
||||
error->re_lb.s1 = (int32_t)(msg->rm_reply.rp_stat);
|
||||
break;
|
||||
}
|
||||
switch (error->re_status) {
|
||||
@ -291,6 +333,22 @@ _seterr_reply(msg, error)
|
||||
error->re_vers.low = msg->acpted_rply.ar_vers.low;
|
||||
error->re_vers.high = msg->acpted_rply.ar_vers.high;
|
||||
break;
|
||||
|
||||
case RPC_FAILED:
|
||||
case RPC_SUCCESS:
|
||||
case RPC_PROGNOTREGISTERED:
|
||||
case RPC_PMAPFAILURE:
|
||||
case RPC_UNKNOWNPROTO:
|
||||
case RPC_UNKNOWNHOST:
|
||||
case RPC_SYSTEMERROR:
|
||||
case RPC_CANTDECODEARGS:
|
||||
case RPC_PROCUNAVAIL:
|
||||
case RPC_PROGUNAVAIL:
|
||||
case RPC_TIMEDOUT:
|
||||
case RPC_CANTRECV:
|
||||
case RPC_CANTSEND:
|
||||
case RPC_CANTDECODERES:
|
||||
case RPC_CANTENCODEARGS:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user