libbind: integrate "netresolv" patches from NetBSD.
libbind development was transferred to the NetBSD project at http://wiki.netbsd.org/individual-software-releases/netresolv/ There isn't an official release yet, but they provide a set of patches against the latest libbind release. * Remove all files we don't use * Merge the changes to the remaining files * Add some new files we need * Move getifaddrs implementation to libnetwork (instead of libbnetapi) so it can be used by netresolv. Fixes #8293 : netresolv uses getifaddrs to determine if there is a local IPv6 address. If there is not, it will not return AAAA records.
This commit is contained in:
@@ -271,7 +271,11 @@ SEARCH on $(driverSettingsFiles)
|
||||
AddFilesToHaikuImage home config settings kernel drivers
|
||||
: $(driverSettingsFiles) ;
|
||||
|
||||
local networkSettingsFiles = <network-settings>services ;
|
||||
local networkSettingsFiles =
|
||||
<network-settings>ports
|
||||
<network-settings>protocols
|
||||
<network-settings>services
|
||||
;
|
||||
SEARCH on $(networkSettingsFiles)
|
||||
= [ FDirName $(HAIKU_TOP) data settings network ] ;
|
||||
AddFilesToHaikuImage system settings network : $(networkSettingsFiles) ;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,278 @@
|
||||
# $NetBSD: protocols,v 1.23.6.2 2014/05/22 11:27:18 yamt Exp $
|
||||
# See also: protocols(5), http://www.sethwklein.net/projects/iana-etc/
|
||||
#
|
||||
# Last Updated
|
||||
# 2013-02-17
|
||||
#
|
||||
# This registry is also available in plain text.
|
||||
#
|
||||
# Registry included below
|
||||
#
|
||||
# * Assigned Internet Protocol Numbers
|
||||
#
|
||||
# Assigned Internet Protocol Numbers
|
||||
#
|
||||
# Registration Procedure(s)
|
||||
#
|
||||
# IESG Approval or Standards Action
|
||||
#
|
||||
# Reference
|
||||
# [RFC5237]
|
||||
#
|
||||
# Note
|
||||
#
|
||||
# In the Internet Protocol version 4 (IPv4) [RFC791] there is a field
|
||||
# called "Protocol" to identify the next level protocol. This is an 8
|
||||
# bit field. In Internet Protocol version 6 (IPv6) [RFC2460], this field
|
||||
# is called the "Next Header" field.
|
||||
#
|
||||
# Decimal Keyword Protocol Reference
|
||||
# protocol num aliases # comments
|
||||
hopopt 0 HOPOPT # IPv6 Hop-by-Hop Option [RFC2460]
|
||||
icmp 1 ICMP # Internet Control Message [RFC792]
|
||||
igmp 2 IGMP # Internet Group Management [RFC1112]
|
||||
ggp 3 GGP # Gateway-to-Gateway [RFC823]
|
||||
ipv4 4 IPv4 # IPv4 encapsulation [RFC2003]
|
||||
st 5 ST # Stream [RFC1190][RFC1819]
|
||||
tcp 6 TCP # Transmission Control [RFC793]
|
||||
cbt 7 CBT # CBT [Tony_Ballardie]
|
||||
egp 8 EGP # Exterior Gateway Protocol [RFC888][David_Mills]
|
||||
igp 9 IGP # any private interior gateway (used by [Internet_Assigned_Numbers_Authority]
|
||||
# Cisco for their IGRP)
|
||||
bbn-rcc-mon 10 BBN-RCC-MON # BBN RCC Monitoring [Steve_Chipman]
|
||||
nvp-ii 11 NVP-II # Network Voice Protocol [RFC741][Steve_Casner]
|
||||
# [Boggs, D., J. Shoch, E. Taft, and R. Metcalfe, "PUP: An Internetwork
|
||||
pup 12 PUP # PUP Architecture", XEROX Palo Alto Research Center, CSL-79-10, July 1979; also in IEEE
|
||||
# Transactions on Communication, Volume COM-28, Number 4, April 1980.][[XEROX]]
|
||||
argus 13 ARGUS # ARGUS [Robert_W_Scheifler]
|
||||
emcon 14 EMCON # EMCON [<mystery contact>]
|
||||
xnet 15 XNET # Cross Net Debugger [Haverty, J., "XNET Formats for Internet Protocol Version 4", IEN 158, October
|
||||
# 1980.][Jack_Haverty]
|
||||
chaos 16 CHAOS # Chaos [J_Noel_Chiappa]
|
||||
udp 17 UDP # User Datagram [RFC768][Jon_Postel]
|
||||
mux 18 MUX # Multiplexing [Cohen, D. and J. Postel, "Multiplexing Protocol", IEN 90, USC/Information
|
||||
# Sciences Institute, May 1979.][Jon_Postel]
|
||||
dcn-meas 19 DCN-MEAS # DCN Measurement Subsystems [David_Mills]
|
||||
hmp 20 HMP # Host Monitoring [RFC869][Bob_Hinden]
|
||||
prm 21 PRM # Packet Radio Measurement [Zaw_Sing_Su]
|
||||
# ["The Ethernet, A Local Area Network: Data Link Layer and Physical Layer
|
||||
# Specification", AA-K759B-TK, Digital Equipment Corporation, Maynard, MA. Also as:
|
||||
# "The Ethernet - A Local Area Network", Version 1.0, Digital Equipment Corporation,
|
||||
xns-idp 22 XNS-IDP # XEROX NS IDP Intel Corporation, Xerox Corporation, September 1980. And: "The Ethernet, A Local
|
||||
# Area Network: Data Link Layer and Physical Layer Specifications", Digital, Intel
|
||||
# and Xerox, November 1982. And: XEROX, "The Ethernet, A Local Area Network: Data
|
||||
# Link Layer and Physical Layer Specification", X3T51/80-50, Xerox Corporation,
|
||||
# Stamford, CT., October 1980.][[XEROX]]
|
||||
trunk-1 23 TRUNK-1 # Trunk-1 [Barry_Boehm]
|
||||
trunk-2 24 TRUNK-2 # Trunk-2 [Barry_Boehm]
|
||||
leaf-1 25 LEAF-1 # Leaf-1 [Barry_Boehm]
|
||||
leaf-2 26 LEAF-2 # Leaf-2 [Barry_Boehm]
|
||||
rdp 27 RDP # Reliable Data Protocol [RFC908][Bob_Hinden]
|
||||
irtp 28 IRTP # Internet Reliable Transaction [RFC938][Trudy_Miller]
|
||||
iso-tp4 29 ISO-TP4 # ISO Transport Protocol Class 4 [RFC905][<mystery contact>]
|
||||
netblt 30 NETBLT # Bulk Data Transfer Protocol [RFC969][David_Clark]
|
||||
# [Shuttleworth, B., "A Documentary of MFENet, a National Computer Network",
|
||||
mfe-nsp 31 MFE-NSP # MFE Network Services Protocol UCRL-52317, Lawrence Livermore Labs, Livermore, California, June
|
||||
# 1977.][Barry_Howard]
|
||||
merit-inp 32 MERIT-INP # MERIT Internodal Protocol [Hans_Werner_Braun]
|
||||
dccp 33 DCCP # Datagram Congestion Control Protocol [RFC4340]
|
||||
3pc 34 3PC # Third Party Connect Protocol [Stuart_A_Friedberg]
|
||||
idpr 35 IDPR # Inter-Domain Policy Routing Protocol [Martha_Steenstrup]
|
||||
xtp 36 XTP # XTP [Greg_Chesson]
|
||||
ddp 37 DDP # Datagram Delivery Protocol [Wesley_Craig]
|
||||
idpr-cmtp 38 IDPR-CMTP # IDPR Control Message Transport Proto [Martha_Steenstrup]
|
||||
tp++ 39 TP++ # TP++ Transport Protocol [Dirk_Fromhein]
|
||||
il 40 IL # IL Transport Protocol [Dave_Presotto]
|
||||
ipv6 41 IPv6 # IPv6 encapsulation [RFC2473]
|
||||
sdrp 42 SDRP # Source Demand Routing Protocol [Deborah_Estrin]
|
||||
ipv6-route 43 IPv6-Route # Routing Header for IPv6 [Steve_Deering]
|
||||
ipv6-frag 44 IPv6-Frag # Fragment Header for IPv6 [Steve_Deering]
|
||||
idrp 45 IDRP # Inter-Domain Routing Protocol [Sue_Hares]
|
||||
rsvp 46 RSVP # Reservation Protocol [RFC2205][RFC3209][Bob_Braden]
|
||||
gre 47 GRE # Generic Routing Encapsulation [RFC1701][Tony_Li]
|
||||
dsr 48 DSR # Dynamic Source Routing Protocol [RFC4728]
|
||||
bna 49 BNA # BNA [Gary Salamon]
|
||||
esp 50 ESP # Encap Security Payload [RFC4303]
|
||||
ah 51 AH # Authentication Header [RFC4302]
|
||||
i-nlsp 52 I-NLSP # Integrated Net Layer Security TUBA [K_Robert_Glenn]
|
||||
swipe 53 SWIPE # IP with Encryption [John_Ioannidis]
|
||||
narp 54 NARP # NBMA Address Resolution Protocol [RFC1735]
|
||||
mobile 55 MOBILE # IP Mobility [Charlie_Perkins]
|
||||
tlsp 56 TLSP # Transport Layer Security Protocol [Christer_Oberg]
|
||||
# using Kryptonet key management
|
||||
skip 57 SKIP # SKIP [Tom_Markson]
|
||||
ipv6-icmp 58 IPv6-ICMP # ICMP for IPv6 [RFC2460]
|
||||
ipv6-nonxt 59 IPv6-NoNxt # No Next Header for IPv6 [RFC2460]
|
||||
ipv6-opts 60 IPv6-Opts # Destination Options for IPv6 [RFC2460]
|
||||
# 61 any host internal protocol [Internet_Assigned_Numbers_Authority]
|
||||
cftp 62 CFTP # CFTP [Forsdick, H., "CFTP", Network Message, Bolt Beranek and Newman, January
|
||||
# 1982.][Harry_Forsdick]
|
||||
# 63 any local network [Internet_Assigned_Numbers_Authority]
|
||||
sat-expak 64 SAT-EXPAK # SATNET and Backroom EXPAK [Steven_Blumenthal]
|
||||
kryptolan 65 KRYPTOLAN # Kryptolan [Paul Liu]
|
||||
rvd 66 RVD # MIT Remote Virtual Disk Protocol [Michael_Greenwald]
|
||||
ippc 67 IPPC # Internet Pluribus Packet Core [Steven_Blumenthal]
|
||||
# 68 any distributed file system [Internet_Assigned_Numbers_Authority]
|
||||
sat-mon 69 SAT-MON # SATNET Monitoring [Steven_Blumenthal]
|
||||
visa 70 VISA # VISA Protocol [Gene_Tsudik]
|
||||
ipcv 71 IPCV # Internet Packet Core Utility [Steven_Blumenthal]
|
||||
cpnx 72 CPNX # Computer Protocol Network Executive [David Mittnacht]
|
||||
cphb 73 CPHB # Computer Protocol Heart Beat [David Mittnacht]
|
||||
wsn 74 WSN # Wang Span Network [Victor Dafoulas]
|
||||
pvp 75 PVP # Packet Video Protocol [Steve_Casner]
|
||||
br-sat-mon 76 BR-SAT-MON # Backroom SATNET Monitoring [Steven_Blumenthal]
|
||||
sun-nd 77 SUN-ND # SUN ND PROTOCOL-Temporary [William_Melohn]
|
||||
wb-mon 78 WB-MON # WIDEBAND Monitoring [Steven_Blumenthal]
|
||||
wb-expak 79 WB-EXPAK # WIDEBAND EXPAK [Steven_Blumenthal]
|
||||
iso-ip 80 ISO-IP # ISO Internet Protocol [Marshall_T_Rose]
|
||||
vmtp 81 VMTP # VMTP [Dave_Cheriton]
|
||||
secure-vmtp 82 SECURE-VMTP # SECURE-VMTP [Dave_Cheriton]
|
||||
vines 83 VINES # VINES [Brian Horn]
|
||||
ttp 84 TTP iptm IPTM # TTP [Jim_Stevens]
|
||||
#iptm 84 IPTM # Protocol Internet Protocol Traffic [Jim_Stevens]
|
||||
# Manager
|
||||
nsfnet-igp 85 NSFNET-IGP # NSFNET-IGP [Hans_Werner_Braun]
|
||||
dgp 86 DGP # Dissimilar Gateway Protocol [M/A-COM Government Systems, "Dissimilar Gateway Protocol Specification, Draft
|
||||
# Version", Contract no. CS901145, November 16, 1987.][Mike_Little]
|
||||
tcf 87 TCF # TCF [Guillermo_A_Loyola]
|
||||
eigrp 88 EIGRP # EIGRP [Cisco Systems, "Gateway Server Reference Manual", Manual Revision B, January 10,
|
||||
# 1988.][Guenther_Schreiner]
|
||||
ospfigp 89 OSPFIGP # OSPFIGP [RFC1583][RFC2328][RFC5340][John_Moy]
|
||||
# [Welch, B., "The Sprite Remote Procedure Call System", Technical Report,
|
||||
sprite-rpc 90 Sprite-RPC # Sprite RPC Protocol UCB/Computer Science Dept., 86/302, University of California at Berkeley, June
|
||||
# 1986.][Bruce Willins]
|
||||
larp 91 LARP # Locus Address Resolution Protocol [Brian Horn]
|
||||
mtp 92 MTP # Multicast Transport Protocol [Susie_Armstrong]
|
||||
ax.25 93 AX.25 # AX.25 Frames [Brian_Kantor]
|
||||
ipip 94 IPIP # IP-within-IP Encapsulation Protocol [John_Ioannidis]
|
||||
micp 95 MICP # Mobile Internetworking Control Pro. [John_Ioannidis]
|
||||
scc-sp 96 SCC-SP # Semaphore Communications Sec. Pro. [Howard_Hart]
|
||||
etherip 97 ETHERIP # Ethernet-within-IP Encapsulation [RFC3378]
|
||||
encap 98 ENCAP # Encapsulation Header [RFC1241][Robert_Woodburn]
|
||||
# 99 any private encryption scheme [Internet_Assigned_Numbers_Authority]
|
||||
gmtp 100 GMTP # GMTP [[RXB5]]
|
||||
ifmp 101 IFMP # Ipsilon Flow Management Protocol [Bob_Hinden][November 1995, 1997.]
|
||||
pnni 102 PNNI # PNNI over IP [Ross_Callon]
|
||||
pim 103 PIM # Protocol Independent Multicast [RFC4601][Dino_Farinacci]
|
||||
aris 104 ARIS # ARIS [Nancy_Feldman]
|
||||
scps 105 SCPS # SCPS [Robert_Durst]
|
||||
qnx 106 QNX # QNX [Michael_Hunter]
|
||||
a/n 107 A/N # Active Networks [Bob_Braden]
|
||||
ipcomp 108 IPComp # IP Payload Compression Protocol [RFC2393]
|
||||
snp 109 SNP # Sitara Networks Protocol [Manickam_R_Sridhar]
|
||||
compaq-peer 110 Compaq-Peer # Compaq Peer Protocol [Victor_Volpe]
|
||||
ipx-in-ip 111 IPX-in-IP # IPX in IP [CJ_Lee]
|
||||
vrrp 112 VRRP # Virtual Router Redundancy Protocol [RFC5798]
|
||||
pgm 113 PGM # PGM Reliable Transport Protocol [Tony_Speakman]
|
||||
# 114 any 0-hop protocol [Internet_Assigned_Numbers_Authority]
|
||||
l2tp 115 L2TP # Layer Two Tunneling Protocol [RFC3931][Bernard_Aboba]
|
||||
ddx 116 DDX # D-II Data Exchange (DDX) [John_Worley]
|
||||
iatp 117 IATP # Interactive Agent Transfer Protocol [John_Murphy]
|
||||
stp 118 STP # Schedule Transfer Protocol [Jean_Michel_Pittet]
|
||||
srp 119 SRP # SpectraLink Radio Protocol [Mark_Hamilton]
|
||||
uti 120 UTI # UTI [Peter_Lothberg]
|
||||
smp 121 SMP # Simple Message Protocol [Leif_Ekblad]
|
||||
sm 122 SM # SM [Jon_Crowcroft]
|
||||
ptp 123 PTP # Performance Transparency Protocol [Michael_Welzl]
|
||||
isis 124 ISIS # over IPv4 [Tony_Przygienda]
|
||||
fire 125 FIRE # [Criag_Partridge]
|
||||
crtp 126 CRTP # Combat Radio Transport Protocol [Robert_Sautter]
|
||||
crudp 127 CRUDP # Combat Radio User Datagram [Robert_Sautter]
|
||||
sscopmce 128 SSCOPMCE # [Kurt_Waber]
|
||||
iplt 129 IPLT # [[Hollbach]]
|
||||
sps 130 SPS # Secure Packet Shield [Bill_McIntosh]
|
||||
pipe 131 PIPE # Private IP Encapsulation within IP [Bernhard_Petri]
|
||||
sctp 132 SCTP # Stream Control Transmission Protocol [Randall_R_Stewart]
|
||||
fc 133 FC # Fibre Channel [Murali_Rajagopal][RFC6172]
|
||||
rsvp-e2e-ignore 134 RSVP-E2E-IGNORE # [RFC3175]
|
||||
mobility 135 Mobility # Header [RFC6275]
|
||||
udplite 136 UDPLite # [RFC3828]
|
||||
mpls-in-ip 137 MPLS-in-IP # [RFC4023]
|
||||
manet 138 MANET # MANET Protocols [RFC5498]
|
||||
hip 139 HIP # Host Identity Protocol [RFC5201]
|
||||
shim6 140 Shim6 # Shim6 Protocol [RFC5533]
|
||||
wesp 141 WESP # Wrapped Encapsulating Security [RFC5840]
|
||||
# Payload
|
||||
rohc 142 ROHC # Robust Header Compression [RFC5858]
|
||||
# 143-252 Unassigned [Internet_Assigned_Numbers_Authority]
|
||||
# 253 Use for experimentation and testing [RFC3692]
|
||||
# 254 Use for experimentation and testing [RFC3692]
|
||||
reserved 255 Reserved # [Internet_Assigned_Numbers_Authority]
|
||||
#
|
||||
# People
|
||||
#
|
||||
# ID Name Contact URI Last Updated
|
||||
# [Barry_Boehm] Barry Boehm mailto:boehm&arpa.mil
|
||||
# [Barry_Howard] Barry Howard mailto:Howard&nmfecc.llnl.gov
|
||||
# [Bernard_Aboba] Bernard Aboba mailto:bernardaµsoft.com 1998-04
|
||||
# [Bernhard_Petri] Bernhard Petri mailto:bernhard.petri&siemens.com 2012-07-09
|
||||
# [Bill_McIntosh] Bill McIntosh mailto:BMcIntosh&fortresstech.com
|
||||
# [Bob_Braden] Bob Braden mailto:braden&isi.edu 1997-07
|
||||
# [Bob_Hinden] Bob Hinden mailto:bob.hinden&gmail.com 2013-02-17
|
||||
# [Brian_Kantor] Brian Kantor mailto:brian&ucsd.edu
|
||||
# [CJ_Lee] CJ Lee mailto:cj_lee&novell.com 1997-10
|
||||
# [Charlie_Perkins] Charlie Perkins mailto:perk&watson.ibm.com 1994-10
|
||||
# [Christer_Oberg] Christer Oberg mailto:chg&bull.se 1994-10
|
||||
# [Criag_Partridge] Criag Partridge mailto:craig&bbn.com 1999-08
|
||||
# [Dave_Cheriton] Dave Cheriton mailto:cheriton&pescadero.stanford.edu
|
||||
# [Dave_Presotto] Dave Presotto mailto:presotto&plan9.att.com 1995-07
|
||||
# [David_Clark] David Clark mailto:ddc&lcs.mit.edu
|
||||
# [David_Mills] David Mills mailto:Mills&huey.udel.edu
|
||||
# [Deborah_Estrin] Deborah Estrin mailto:estrin&usc.edu
|
||||
# [Dino_Farinacci] Dino Farinacci mailto:dino&cisco.com 1996-03
|
||||
# [Dirk_Fromhein] Dirk Fromhein mailto:df&watershed.com
|
||||
# [Gene_Tsudik] Gene Tsudik mailto:tsudik&usc.edu
|
||||
# [Greg_Chesson] Greg Chesson mailto:Greg&sgi.com
|
||||
# [Guenther_Schreiner] Guenther Schreiner mailto:snmp-admin&ira.uka.de
|
||||
# [Guillermo_A_Loyola] Guillermo A. Loyola mailto:LOYOLA&ibm.com
|
||||
# [Hans_Werner_Braun] Hans-Werner Braun mailto:HWB&mcr.umich.edu
|
||||
# [Harry_Forsdick] Harry Forsdick mailto:Forsdick&bbn.com
|
||||
# [Howard_Hart] Howard Hart mailto:hch&hybrid.com
|
||||
# [Internet_Assigned_Numbers_Authority] Internet Assigned Numbers Authority mailto:iana&iana.org 1995-06
|
||||
# [J_Noel_Chiappa] J. Noel Chiappa mailto:JNC&xx.lcs.mit.edu
|
||||
# [Jack_Haverty] Jack Haverty mailto:jhaverty&oracle.com
|
||||
# [Jean_Michel_Pittet] Jean-Michel Pittet mailto:jmp&gandalf.engr.sgi.com 1998-11
|
||||
# [Jim_Stevens] Jim Stevens mailto:jasteven&rockwellcollins.com 2011-01-26
|
||||
# [John_Ioannidis] John Ioannidis mailto:ji&cs.columbia.edu
|
||||
# [John_Moy] John Moy mailto:jmoy&proteon.com
|
||||
# [John_Murphy] John Murphy mailto:john.m.murphy&mci.com 1998-10
|
||||
# [John_Worley] John Worley mailto:worley&milehigh.net 1998-06
|
||||
# [Jon_Crowcroft] Jon Crowcroft mailto:jon&cs.ucl.ac.uk 1999-06
|
||||
# [Jon_Postel] Jon Postel mailto:postel&isi.edu
|
||||
# [K_Robert_Glenn] K. Robert Glenn mailto:glenn&osi.ncsl.nist.gov
|
||||
# [Kurt_Waber] Kurt Waber mailto:kurt.waber&swisscom.com 1999-08
|
||||
# [Leif_Ekblad] Leif Ekblad mailto:leif&rdos.net 2012-08-21
|
||||
# [Manickam_R_Sridhar] Manickam R. Sridhar mailto:msridhar&sitaranetworks.com 1997-09
|
||||
# [Mark_Hamilton] Mark Hamilton mailto:mah&spectralink.com 1998-11
|
||||
# [Marshall_T_Rose] Marshall T. Rose mailto:mrose&dbc.mtview.ca.us
|
||||
# [Martha_Steenstrup] Martha Steenstrup mailto:MSteenst&bbn.com
|
||||
# [Michael_Greenwald] Michael Greenwald mailto:Greenwald&scrc-stony-brook.symbolics.com
|
||||
# [Michael_Hunter] Michael Hunter mailto:mphunter&qnx.com 1997-07
|
||||
# [Michael_Welzl] Michael Welzl mailto:michael&tk.uni-linz.ac.at 1999-08
|
||||
# [Mike_Little] Mike Little mailto:little&macom4.arpa
|
||||
# [Murali_Rajagopal] Murali Rajagopal mailto:murali&gadzoox.com 2000-05
|
||||
# [Nancy_Feldman] Nancy Feldman mailto:nkf&vnet.ibm.com 1997-01
|
||||
# [Peter_Lothberg] Peter Lothberg mailto:roll&stupi.se 1999-03
|
||||
# [Randall_R_Stewart] Randall R. Stewart mailto:rrs&lakerest.net 2000-04
|
||||
# [Robert_Durst] Robert Durst mailto:durst&mitre.org 1997-03
|
||||
# [Robert_Sautter] Robert Sautter mailto:rsautter&acdnj.itt.com 1999-08
|
||||
# [Robert_W_Scheifler] Robert W. Scheifler mailto:RWS&xx.lcs.mit.edu
|
||||
# [Robert_Woodburn] Robert Woodburn mailto:woody&cseic.saic.com
|
||||
# [Ross_Callon] Ross Callon mailto:rcallon&baynetworks.com 1995-12
|
||||
# [Steve_Casner] Steve Casner mailto:casner&isi.edu
|
||||
# [Steve_Chipman] Steve Chipman mailto:Chipman&f.bbn.com
|
||||
# [Steve_Deering] Steve Deering mailto:deering&parc.xerox.com 1995-03
|
||||
# [Steven_Blumenthal] Steven Blumenthal mailto:BLUMENTHAL&vax.bbn.com
|
||||
# [Stuart_A_Friedberg] Stuart A. Friedberg mailto:stuart&cs.wisc.edu
|
||||
# [Sue_Hares] Sue Hares mailto:skh&merit.edu
|
||||
# [Susie_Armstrong] Susie Armstrong mailto:Armstrong.wbst128&xerox.com
|
||||
# [Tom_Markson] Tom Markson mailto:markson&osmosys.ingog.com 1995-09
|
||||
# [Tony_Ballardie] Tony Ballardie mailto:A.Ballardie&cs.ucl.ac.uk
|
||||
# [Tony_Li] Tony Li mailto:tony.li&tony.li 2012-10-17
|
||||
# [Tony_Przygienda] Tony Przygienda mailto:prz&siara.com 1999-08
|
||||
# [Tony_Speakman] Tony Speakman mailto:speakman&cisco.com 1998-01
|
||||
# [Trudy_Miller] Trudy Miller mailto:Trudy&acc.com
|
||||
# [Victor_Volpe] Victor Volpe mailto:vvolpe&smtp.microcom.com 1997-10
|
||||
# [Wesley_Craig] Wesley Craig mailto:Wesley.Craig&terminator.cc.umich.edu
|
||||
# [William_Melohn] William Melohn mailto:Melohn&sun.com
|
||||
# [Zaw_Sing_Su] Zaw-Sing Su mailto:ZSu&tsca.istc.sri.
|
||||
@@ -22,15 +22,15 @@ char* inet_cidr_ntop(int family, const void* source, int bits,
|
||||
char* dest, size_t destSize);
|
||||
int inet_cidr_pton(int family, const char* sourceString, void* dest,
|
||||
int* _bits);
|
||||
u_long inet_lnaof(struct in_addr address);
|
||||
struct in_addr inet_makeaddr(u_long net, u_long host);
|
||||
in_addr_t inet_lnaof(struct in_addr address);
|
||||
struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host);
|
||||
char* inet_net_ntop(int family, const void* source, int bits,
|
||||
char* dest, size_t destSize);
|
||||
int inet_net_pton(int family, const char* sourceString, void* dest,
|
||||
size_t destSize);
|
||||
char* inet_neta(u_long source, char* dest, size_t destSize);
|
||||
u_long inet_netof(struct in_addr address);
|
||||
u_long inet_network(const char* addressString);
|
||||
in_addr_t inet_netof(struct in_addr address);
|
||||
in_addr_t inet_network(const char* addressString);
|
||||
char* inet_ntoa(struct in_addr address);
|
||||
const char* inet_ntop(int family, const void* source, char* dest,
|
||||
socklen_t destSize);
|
||||
|
||||
@@ -586,10 +586,10 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
int ns_msg_getflag(ns_msg, int);
|
||||
u_int ns_get16(const u_char *);
|
||||
u_long ns_get32(const u_char *);
|
||||
void ns_put16(u_int, u_char *);
|
||||
void ns_put32(u_long, u_char *);
|
||||
uint16_t ns_get16(const u_char *);
|
||||
uint32_t ns_get32(const u_char *);
|
||||
void ns_put16(uint16_t, u_char *);
|
||||
void ns_put32(uint32_t, u_char *);
|
||||
int ns_initparse(const u_char *, int, ns_msg *);
|
||||
int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
|
||||
int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
|
||||
|
||||
+17
-13
@@ -95,6 +95,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifndef _PATH_NETWORKS
|
||||
#define _PATH_NETWORKS "/etc/networks"
|
||||
@@ -128,7 +129,7 @@ struct netent {
|
||||
char *n_name; /* official name of net */
|
||||
char **n_aliases; /* alias list */
|
||||
int n_addrtype; /* net address type */
|
||||
unsigned long n_net; /* network # */
|
||||
in_addr_t n_net; /* network # */
|
||||
};
|
||||
|
||||
struct servent {
|
||||
@@ -238,13 +239,13 @@ void endnetent(void);
|
||||
void endprotoent(void);
|
||||
void endservent(void);
|
||||
void freehostent(struct hostent *host);
|
||||
struct hostent *gethostbyaddr(const char *address, int length, int type);
|
||||
struct hostent *gethostbyaddr(const char *address, socklen_t length, int type);
|
||||
struct hostent *gethostbyname(const char *name);
|
||||
struct hostent *gethostbyname2(const char *name, int type);
|
||||
struct hostent *gethostent(void);
|
||||
struct hostent *getipnodebyaddr(const void *, size_t, int, int *);
|
||||
struct hostent *getipnodebyname(const char *, int, int, int *);
|
||||
struct netent *getnetbyaddr(unsigned long, int);
|
||||
struct netent *getnetbyaddr(uint32_t, int);
|
||||
struct netent *getnetbyname(const char *);
|
||||
struct netent *getnetent(void);
|
||||
struct protoent *getprotobyname(const char *);
|
||||
@@ -264,6 +265,7 @@ int getaddrinfo(const char *, const char *,
|
||||
const struct addrinfo *, struct addrinfo **);
|
||||
int getnameinfo(const struct sockaddr *, socklen_t, char *,
|
||||
socklen_t, char *, socklen_t, int);
|
||||
struct addrinfo *allocaddrinfo(socklen_t);
|
||||
void freeaddrinfo(struct addrinfo *);
|
||||
const char *gai_strerror(int);
|
||||
|
||||
@@ -283,21 +285,23 @@ struct netent *getnetent_r(struct netent *, char *, int);
|
||||
void setnetent_r(int);
|
||||
void endnetent_r(void);
|
||||
|
||||
struct protoent_data;
|
||||
struct protoent *getprotobyname_r(const char *,
|
||||
struct protoent *, char *, int);
|
||||
struct protoent *, struct protoent_data *);
|
||||
struct protoent *getprotobynumber_r(int,
|
||||
struct protoent *, char *, int);
|
||||
struct protoent *getprotoent_r(struct protoent *, char *, int);
|
||||
void setprotoent_r(int);
|
||||
void endprotoent_r(void);
|
||||
struct protoent *, struct protoent_data *);
|
||||
struct protoent *getprotoent_r(struct protoent *, struct protoent_data *);
|
||||
void setprotoent_r(int, struct protoent_data *);
|
||||
void endprotoent_r(struct protoent_data *);
|
||||
|
||||
struct servent_data;
|
||||
struct servent *getservbyname_r(const char *name, const char *,
|
||||
struct servent *, char *, int);
|
||||
struct servent *, struct servent_data *);
|
||||
struct servent *getservbyport_r(int port, const char *,
|
||||
struct servent *, char *, int);
|
||||
struct servent *getservent_r(struct servent *, char *, int);
|
||||
void setservent_r(int);
|
||||
void endservent_r(void);
|
||||
struct servent *, struct servent_data *);
|
||||
struct servent *getservent_r(struct servent *, struct servent_data *);
|
||||
void setservent_r(int, struct servent_data *);
|
||||
void endservent_r(struct servent_data *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NETDB_H_ */
|
||||
|
||||
@@ -31,6 +31,15 @@ struct sockaddr_in6 {
|
||||
#define IN6ADDR_LOOPBACK_INIT {{ \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}
|
||||
#define IN6ADDR_NODELOCAL_ALLNODES_INIT {{ \
|
||||
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}
|
||||
#define IN6ADDR_LINKLOCAL_ALLNODES_INIT {{ \
|
||||
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}
|
||||
#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT {{ \
|
||||
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }}
|
||||
|
||||
extern const struct in6_addr in6addr_any;
|
||||
extern const struct in6_addr in6addr_loopback;
|
||||
|
||||
@@ -272,9 +272,16 @@ union res_sockaddr_union {
|
||||
|
||||
/* Things involving an internal (static) resolver context. */
|
||||
__BEGIN_DECLS
|
||||
extern struct __res_state *__res_get_state(void);
|
||||
extern void __res_put_state(struct __res_state *);
|
||||
|
||||
/*
|
||||
* Source and Binary compatibility; _res will not work properly
|
||||
* with multi-threaded programs.
|
||||
*/
|
||||
extern struct __res_state *__res_state(void);
|
||||
__END_DECLS
|
||||
#define _res (*__res_state())
|
||||
__END_DECLS
|
||||
|
||||
#ifndef __BIND_NOSTATIC
|
||||
#define fp_nquery __fp_nquery
|
||||
@@ -409,7 +416,7 @@ const char * loc_ntoa(const u_char *, char *);
|
||||
int dn_skipname(const u_char *, const u_char *);
|
||||
void putlong(u_int32_t, u_char *);
|
||||
void putshort(u_int16_t, u_char *);
|
||||
#if !defined(__ultrix__) && !defined(__HAIKU__)
|
||||
#if !defined(__ultrix__)
|
||||
u_int16_t _getshort(const u_char *);
|
||||
u_int32_t _getlong(const u_char *);
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
SubDir HAIKU_TOP src kits network ;
|
||||
|
||||
UsePrivateHeaders libroot net shared ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||
|
||||
local services = [ FGristFiles services ] ;
|
||||
SEARCH on $(services) = [ FDirName $(SUBDIR) libbind defaults ] ;
|
||||
|
||||
SubDirC++Flags [ FDefines _BSD_SOURCE=1 ] ;
|
||||
|
||||
local architectureObject ;
|
||||
for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
on $(architectureObject) {
|
||||
@@ -16,10 +19,11 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
SharedLibrary $(libnetwork) :
|
||||
init.cpp
|
||||
interfaces.cpp
|
||||
getifaddrs.cpp
|
||||
socket.cpp
|
||||
r5_compatibility.cpp
|
||||
:
|
||||
<libbind!$(architecture)>libbind.o
|
||||
<libbind!$(architecture)>libbind.o libutil.a bsd
|
||||
[ TargetLibsupc++ ]
|
||||
;
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright 2015, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Adrien Destugues, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <net/if.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
|
||||
|
||||
int getifaddrs(struct ifaddrs **ifap)
|
||||
{
|
||||
if (ifap == NULL) {
|
||||
errno = B_BAD_VALUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint32 cookie;
|
||||
#endif
|
||||
|
||||
// get a list of all interfaces
|
||||
|
||||
int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (socket < 0)
|
||||
return errno;
|
||||
|
||||
FileDescriptorCloser closer(socket);
|
||||
|
||||
// get interface count
|
||||
ifconf config;
|
||||
config.ifc_len = sizeof(config.ifc_value);
|
||||
if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
size_t count = (size_t)config.ifc_value;
|
||||
if (count == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// allocate a buffer for ifreqs for all interfaces
|
||||
char* buffer = (char*)malloc(count * sizeof(struct ifreq));
|
||||
if (buffer == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
MemoryDeleter deleter(buffer);
|
||||
|
||||
// get interfaces configuration
|
||||
config.ifc_len = count * sizeof(struct ifreq);
|
||||
config.ifc_buf = buffer;
|
||||
if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
|
||||
return errno;
|
||||
|
||||
ifreq* interfaces = (ifreq*)buffer;
|
||||
ifreq* end = (ifreq*)(buffer + config.ifc_len);
|
||||
|
||||
struct ifaddrs* previous = NULL;
|
||||
struct ifaddrs* current = NULL;
|
||||
|
||||
for (uint32_t i = 0; interfaces < end; i++) {
|
||||
current = new(std::nothrow) ifaddrs();
|
||||
if (current == NULL) {
|
||||
freeifaddrs(previous);
|
||||
errno = B_NO_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Chain this interface with the next one
|
||||
current->ifa_next = previous;
|
||||
previous = current;
|
||||
|
||||
current->ifa_name = strdup(interfaces[0].ifr_name);
|
||||
current->ifa_addr = new sockaddr(interfaces[0].ifr_addr);
|
||||
// still needs: flags, netmask, dst:broadcast addr
|
||||
|
||||
ioctl(socket, SIOCGIFFLAGS, &interfaces[0], sizeof(struct ifconf));
|
||||
current->ifa_flags = interfaces[0].ifr_flags;
|
||||
ioctl(socket, SIOCGIFNETMASK, &interfaces[0], sizeof(struct ifconf));
|
||||
current->ifa_netmask = new sockaddr(interfaces[0].ifr_mask);
|
||||
ioctl(socket, SIOCGIFDSTADDR, &interfaces[0], sizeof(struct ifconf));
|
||||
current->ifa_dstaddr = new sockaddr(interfaces[0].ifr_dstaddr);
|
||||
|
||||
// TODO we may also need to get other addresses for the same interface?
|
||||
#if 0
|
||||
BNetworkInterfaceAddress address;
|
||||
int32 i = 0;
|
||||
while (interface->GetAddressAt(i++, address) == B_OK) {
|
||||
if (interface == NULL) {
|
||||
freeifaddrs(previous);
|
||||
errno = B_NO_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
current = new(std::nothrow) ifaddrs();
|
||||
if (current == NULL) {
|
||||
freeifaddrs(previous);
|
||||
errno = B_NO_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Chain this interface with the next one
|
||||
current->ifa_next = previous;
|
||||
previous = current;
|
||||
|
||||
current->ifa_data = interface;
|
||||
current->ifa_name = interface->Name();
|
||||
// Points to the name in the BNetworkInterface instance, which
|
||||
// is added as ifa_data so freeifaddrs can release it.
|
||||
current->ifa_flags = address.Flags();
|
||||
current->ifa_addr = new sockaddr(address.Address().SockAddr());
|
||||
current->ifa_netmask = new sockaddr(address.Mask().SockAddr());
|
||||
current->ifa_dstaddr = new sockaddr(address.Destination().SockAddr());
|
||||
}
|
||||
|
||||
interface = new(std::nothrow) BNetworkInterface();
|
||||
#endif
|
||||
|
||||
// move on to next interface
|
||||
interfaces = (ifreq*)((uint8_t*)interfaces
|
||||
+ _SIZEOF_ADDR_IFREQ(interfaces[0]));
|
||||
}
|
||||
|
||||
*ifap = current;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
freeifaddrs(struct ifaddrs *ifa)
|
||||
{
|
||||
struct ifaddrs* next;
|
||||
while (ifa != NULL) {
|
||||
free ((void*)ifa->ifa_name);
|
||||
delete ifa->ifa_addr;
|
||||
delete ifa->ifa_netmask;
|
||||
delete ifa->ifa_dstaddr;
|
||||
|
||||
next = ifa->ifa_next;
|
||||
delete ifa;
|
||||
ifa = next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
local architecture = $(TARGET_PACKAGING_ARCH) ;
|
||||
|
||||
UseHeaders [ FDirName $(SUBDIR) include ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
|
||||
: true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers compatibility bsd ] : true ;
|
||||
SubDirSysHdrs $(SUBDIR) ;
|
||||
|
||||
# private sources for this port
|
||||
@@ -22,7 +25,7 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
|
||||
{
|
||||
# we want to have the xxx_r functions, too
|
||||
local defines = _REENTRANT=1 USE_MD5=1 ;
|
||||
local defines = _REENTRANT=1 USE_MD5=1 _BSD_SOURCE ;
|
||||
defines = [ FDefines $(defines) ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
@@ -39,7 +42,6 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
inet_addr.c
|
||||
inet_cidr_ntop.c
|
||||
inet_cidr_pton.c
|
||||
inet_data.c
|
||||
inet_lnaof.c
|
||||
inet_makeaddr.c
|
||||
inet_net_ntop.c
|
||||
@@ -53,48 +55,29 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
nsap_addr.c
|
||||
|
||||
# irs
|
||||
dns.c
|
||||
dns_ho.c
|
||||
dns_nw.c
|
||||
dns_pr.c
|
||||
dns_sv.c
|
||||
gai_strerror.c
|
||||
gen.c
|
||||
gen_ho.c
|
||||
gen_ng.c
|
||||
gen_nw.c
|
||||
gen_pr.c
|
||||
gen_sv.c
|
||||
getaddrinfo.c
|
||||
gethostent.c
|
||||
gethostent_r.c
|
||||
gethnamaddr.c
|
||||
getnameinfo.c
|
||||
getnetent.c
|
||||
getnetent_r.c
|
||||
getnetgrent.c
|
||||
getnetgrent_r.c
|
||||
getnetnamadr.c
|
||||
getprotobyname.c
|
||||
getprotobyname_r.c
|
||||
getprotobynumber.c
|
||||
getprotobynumber_r.c
|
||||
getprotoent.c
|
||||
getprotoent_r.c
|
||||
getservbyname.c
|
||||
getservbyname_r.c
|
||||
getservbyport.c
|
||||
getservbyport_r.c
|
||||
getservent.c
|
||||
getservent_r.c
|
||||
hesiod.c
|
||||
irp.c
|
||||
irp_ho.c
|
||||
irp_ng.c
|
||||
irp_nw.c
|
||||
irp_pr.c
|
||||
irp_sv.c
|
||||
irpmarshall.c
|
||||
irs_data.c
|
||||
lcl.c
|
||||
lcl_ho.c
|
||||
lcl_ng.c
|
||||
lcl_nw.c
|
||||
lcl_pr.c
|
||||
lcl_sv.cpp
|
||||
nis.c
|
||||
nul_ng.c
|
||||
util.c
|
||||
nsdispatch.c
|
||||
nsparser.y
|
||||
nslexer.l
|
||||
sethostent.c
|
||||
vars6.c
|
||||
|
||||
# isc
|
||||
assertions.c
|
||||
@@ -117,30 +100,25 @@ for architectureObject in [ MultiArchSubDirSetup ] {
|
||||
tree.c
|
||||
|
||||
# nameser
|
||||
ns_date.c
|
||||
ns_name.c
|
||||
ns_netint.c
|
||||
ns_parse.c
|
||||
ns_print.c
|
||||
ns_samedomain.c
|
||||
ns_sign.c
|
||||
ns_ttl.c
|
||||
ns_verify.c
|
||||
|
||||
# resolv
|
||||
herror.c
|
||||
h_errno.c
|
||||
mtctxres.c
|
||||
res_comp.c
|
||||
res_data.c
|
||||
res_debug.c
|
||||
res_findzonecut.c
|
||||
res_init.c
|
||||
res_mkquery.c
|
||||
res_mkupdate.c
|
||||
res_query.c
|
||||
res_send.c
|
||||
res_sendsigned.c
|
||||
res_update.c
|
||||
res_state.c
|
||||
|
||||
# private functions
|
||||
strsep.c
|
||||
|
||||
@@ -1,6 +1,33 @@
|
||||
/* $NetBSD: hesiod.h,v 1.5 2008/04/28 20:22:54 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -15,25 +42,47 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* This file is primarily maintained by <[email protected]> and <[email protected]>.
|
||||
*/
|
||||
#ifndef _HESIOD_H_
|
||||
#define _HESIOD_H_
|
||||
|
||||
/*
|
||||
* $Id: hesiod.h,v 1.4 2005/04/27 04:56:14 sra Exp $
|
||||
*/
|
||||
/* Application-visible indication that we have the new interfaces */
|
||||
|
||||
#ifndef _HESIOD_H_INCLUDED
|
||||
#define _HESIOD_H_INCLUDED
|
||||
#define HESIOD_INTERFACES
|
||||
|
||||
int hesiod_init __P((void **));
|
||||
void hesiod_end __P((void *));
|
||||
char * hesiod_to_bind __P((void *, const char *, const char *));
|
||||
char ** hesiod_resolve __P((void *, const char *, const char *));
|
||||
void hesiod_free_list __P((void *, char **));
|
||||
struct __res_state * __hesiod_res_get __P((void *));
|
||||
void __hesiod_res_set __P((void *, struct __res_state *,
|
||||
void (*)(void *)));
|
||||
/* Configuration information. */
|
||||
|
||||
#endif /*_HESIOD_H_INCLUDED*/
|
||||
#ifndef _PATH_HESIOD_CONF /* Configuration file. */
|
||||
#define _PATH_HESIOD_CONF "/etc/hesiod.conf"
|
||||
#endif
|
||||
|
||||
#define DEF_RHS "" /* Defaults if HESIOD_CONF */
|
||||
#define DEF_LHS "" /* file is not present. */
|
||||
|
||||
/* Error codes (for backwards compatibility) */
|
||||
|
||||
#define HES_ER_UNINIT -1 /* uninitialized */
|
||||
#define HES_ER_OK 0 /* no error */
|
||||
#define HES_ER_NOTFOUND 1 /* Hesiod name not found by server */
|
||||
#define HES_ER_CONFIG 2 /* local problem (no config file?) */
|
||||
#define HES_ER_NET 3 /* network problem */
|
||||
|
||||
/* Declaration of routines */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int hesiod_init (void **);
|
||||
char **hesiod_resolve (void *, const char *, const char *);
|
||||
void hesiod_free_list(void *, char **);
|
||||
char *hesiod_to_bind (void *, const char *, const char *);
|
||||
void hesiod_end (void *);
|
||||
|
||||
/* backwards compatibility */
|
||||
int hes_init (void);
|
||||
char *hes_to_bind (const char *, const char *);
|
||||
char **hes_resolve (const char *, const char *);
|
||||
int hes_error (void);
|
||||
void hes_free (char **);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* ! _HESIOD_H_ */
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/* $NetBSD: nsswitch.h,v 1.21 2011/07/17 20:54:34 joerg Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999, 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Luke Mewburn.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _NSSWITCH_H
|
||||
#define _NSSWITCH_H 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define NSS_MODULE_INTERFACE_VERSION 0
|
||||
|
||||
#ifndef _PATH_NS_CONF
|
||||
#define _PATH_NS_CONF "/etc/nsswitch.conf"
|
||||
#endif
|
||||
|
||||
#define NS_CONTINUE 0
|
||||
#define NS_RETURN 1
|
||||
|
||||
/*
|
||||
* Layout of:
|
||||
* uint32_t ns_src.flags
|
||||
*/
|
||||
/* nsswitch.conf status codes and nsdispatch(3) return values */
|
||||
#define NS_SUCCESS (1<<0) /* entry was found */
|
||||
#define NS_UNAVAIL (1<<1) /* source not responding, or corrupt */
|
||||
#define NS_NOTFOUND (1<<2) /* source responded 'no such entry' */
|
||||
#define NS_TRYAGAIN (1<<3) /* source busy, may respond to retrys */
|
||||
#define NS_STATUSMASK 0x000000ff /* bitmask to get the status flags */
|
||||
|
||||
/* internal nsdispatch(3) flags; not settable in nsswitch.conf(5) */
|
||||
#define NS_FORCEALL (1<<8) /* force all methods to be invoked; */
|
||||
|
||||
/*
|
||||
* Currently implemented sources.
|
||||
*/
|
||||
#define NSSRC_FILES "files" /* local files */
|
||||
#define NSSRC_DNS "dns" /* DNS; IN for hosts, HS for others */
|
||||
#define NSSRC_NIS "nis" /* YP/NIS */
|
||||
#define NSSRC_COMPAT "compat" /* passwd,group in YP compat mode */
|
||||
|
||||
/*
|
||||
* Currently implemented databases.
|
||||
*/
|
||||
#define NSDB_HOSTS "hosts"
|
||||
#define NSDB_GROUP "group"
|
||||
#define NSDB_GROUP_COMPAT "group_compat"
|
||||
#define NSDB_NETGROUP "netgroup"
|
||||
#define NSDB_NETWORKS "networks"
|
||||
#define NSDB_PASSWD "passwd"
|
||||
#define NSDB_PASSWD_COMPAT "passwd_compat"
|
||||
#define NSDB_SHELLS "shells"
|
||||
|
||||
/*
|
||||
* Suggested databases to implement.
|
||||
*/
|
||||
#define NSDB_ALIASES "aliases"
|
||||
#define NSDB_AUTH "auth"
|
||||
#define NSDB_AUTOMOUNT "automount"
|
||||
#define NSDB_BOOTPARAMS "bootparams"
|
||||
#define NSDB_ETHERS "ethers"
|
||||
#define NSDB_EXPORTS "exports"
|
||||
#define NSDB_NETMASKS "netmasks"
|
||||
#define NSDB_PHONES "phones"
|
||||
#define NSDB_PRINTCAP "printcap"
|
||||
#define NSDB_PROTOCOLS "protocols"
|
||||
#define NSDB_REMOTE "remote"
|
||||
#define NSDB_RPC "rpc"
|
||||
#define NSDB_SENDMAILVARS "sendmailvars"
|
||||
#define NSDB_SERVICES "services"
|
||||
#define NSDB_TERMCAP "termcap"
|
||||
#define NSDB_TTYS "ttys"
|
||||
|
||||
/*
|
||||
* ns_dtab `callback' function signature.
|
||||
*/
|
||||
typedef int (*nss_method)(void *, void *, va_list);
|
||||
|
||||
/*
|
||||
* ns_dtab - `nsswitch dispatch table'
|
||||
* Contains an entry for each source and the appropriate function to call.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *src;
|
||||
nss_method callback;
|
||||
void *cb_data;
|
||||
} ns_dtab;
|
||||
|
||||
/*
|
||||
* Macros to help build an ns_dtab[]
|
||||
*/
|
||||
#define NS_FILES_CB(F,C) { NSSRC_FILES, F, (void*)(C) },
|
||||
#define NS_COMPAT_CB(F,C) { NSSRC_COMPAT, F, (void*)(C) },
|
||||
|
||||
#ifdef HESIOD
|
||||
# define NS_DNS_CB(F,C) { NSSRC_DNS, F, (void*)(C) },
|
||||
#else
|
||||
# define NS_DNS_CB(F,C)
|
||||
#endif
|
||||
|
||||
#ifdef YP
|
||||
# define NS_NIS_CB(F,C) { NSSRC_NIS, F, (void*)(C) },
|
||||
#else
|
||||
# define NS_NIS_CB(F,C)
|
||||
#endif
|
||||
#define NS_NULL_CB { .src = NULL },
|
||||
|
||||
/*
|
||||
* ns_src - `nsswitch source'
|
||||
* Used by the nsparser routines to store a mapping between a source
|
||||
* and its dispatch control flags for a given database.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name;
|
||||
uint32_t flags;
|
||||
} ns_src;
|
||||
|
||||
|
||||
/*
|
||||
* Default sourcelists (if nsswitch.conf is missing, corrupt,
|
||||
* or the requested database doesn't have an entry)
|
||||
*/
|
||||
extern const ns_src __nsdefaultsrc[];
|
||||
extern const ns_src __nsdefaultcompat[];
|
||||
extern const ns_src __nsdefaultcompat_forceall[];
|
||||
extern const ns_src __nsdefaultfiles[];
|
||||
extern const ns_src __nsdefaultfiles_forceall[];
|
||||
extern const ns_src __nsdefaultnis[];
|
||||
extern const ns_src __nsdefaultnis_forceall[];
|
||||
|
||||
|
||||
/*
|
||||
* ns_mtab - `nsswitch method table'
|
||||
* An nsswitch module provides a mapping from (database name, method name)
|
||||
* tuples to the nss_method and associated callback data. Effectively,
|
||||
* ns_dtab, but used for dynamically loaded modules.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *database;
|
||||
const char *name;
|
||||
nss_method method;
|
||||
void *mdata;
|
||||
} ns_mtab;
|
||||
|
||||
/*
|
||||
* nss_module_register_fn - module registration function
|
||||
* called at module load
|
||||
* nss_module_unregister_fn - module un-registration function
|
||||
* called at module unload
|
||||
*/
|
||||
typedef void (*nss_module_unregister_fn)(ns_mtab *, u_int);
|
||||
typedef ns_mtab *(*nss_module_register_fn)(const char *, u_int *,
|
||||
nss_module_unregister_fn *);
|
||||
|
||||
#ifdef _NS_PRIVATE
|
||||
|
||||
/*
|
||||
* Private data structures for back-end nsswitch implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ns_dbt - `nsswitch database thang'
|
||||
* For each database in /etc/nsswitch.conf there is a ns_dbt, with its
|
||||
* name and a list of ns_src's containing the source information.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /* name of database */
|
||||
ns_src *srclist; /* list of sources */
|
||||
u_int srclistsize; /* size of srclist */
|
||||
} ns_dbt;
|
||||
|
||||
/*
|
||||
* ns_mod - `nsswitch module'
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /* module name */
|
||||
void *handle; /* handle from dlopen() */
|
||||
ns_mtab *mtab; /* method table */
|
||||
u_int mtabsize; /* size of mtab */
|
||||
/* called to unload module */
|
||||
nss_module_unregister_fn unregister;
|
||||
} ns_mod;
|
||||
|
||||
#endif /* _NS_PRIVATE */
|
||||
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
int nsdispatch(void *, const ns_dtab [], const char *,
|
||||
const char *, const ns_src [], ...);
|
||||
|
||||
#ifdef _NS_PRIVATE
|
||||
int _nsdbtaddsrc(ns_dbt *, const ns_src *);
|
||||
void _nsdbtdump(const ns_dbt *);
|
||||
int _nsdbtput(const ns_dbt *);
|
||||
void _nsyyerror(const char *);
|
||||
int _nsyylex(void);
|
||||
#endif /* _NS_PRIVATE */
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_NSSWITCH_H */
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_addr.c,v 1.2 2008/02/16 17:37:13 apb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -98,7 +100,7 @@ inet_addr(const char *cp) {
|
||||
return (INADDR_NONE);
|
||||
}
|
||||
|
||||
/*%
|
||||
/*
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
@@ -107,11 +109,11 @@ inet_addr(const char *cp) {
|
||||
*/
|
||||
int
|
||||
inet_aton(const char *cp, struct in_addr *addr) {
|
||||
u_int32_t val;
|
||||
uint32_t val;
|
||||
int base, n;
|
||||
char c;
|
||||
u_int8_t parts[4];
|
||||
u_int8_t *pp = parts;
|
||||
uint8_t parts[4];
|
||||
uint8_t *pp = parts;
|
||||
int digit;
|
||||
|
||||
c = *cp;
|
||||
@@ -179,22 +181,22 @@ inet_aton(const char *cp, struct in_addr *addr) {
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch (n) {
|
||||
case 1: /*%< a -- 32 bits */
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /*%< a.b -- 8.24 bits */
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffffU)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /*%< a.b.c -- 8.8.16 bits */
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffffU)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /*%< a.b.c.d -- 8.8.8.8 bits */
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xffU)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_cidr_ntop.c,v 1.8 2012/03/13 21:13:38 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998,1999 by Internet Software Consortium.
|
||||
@@ -15,8 +17,13 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 marka Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 marka Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_cidr_ntop.c,v 1.8 2012/03/13 21:13:38 christos Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -27,6 +34,7 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 mar
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -34,6 +42,10 @@ static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 mar
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(inet_cidr_ntop,_inet_cidr_ntop)
|
||||
#endif
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
@@ -73,10 +85,10 @@ inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
|
||||
}
|
||||
|
||||
static int
|
||||
decoct(const u_char *src, int bytes, char *dst, size_t size) {
|
||||
decoct(const u_char *src, size_t bytes, char *dst, size_t size) {
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
int b;
|
||||
size_t b;
|
||||
|
||||
for (b = 1; b <= bytes; b++) {
|
||||
if (size < sizeof "255.")
|
||||
@@ -89,7 +101,8 @@ decoct(const u_char *src, int bytes, char *dst, size_t size) {
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
return (dst - odst);
|
||||
assert(INT_MIN <= (dst - odst) && (dst - odst) <= INT_MAX);
|
||||
return (int)(dst - odst);
|
||||
}
|
||||
|
||||
/*%
|
||||
@@ -221,7 +234,7 @@ inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 ||
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff))) {
|
||||
int n;
|
||||
size_t n;
|
||||
|
||||
if (src[15] || bits == -1 || bits > 120)
|
||||
n = 4;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_cidr_pton.c,v 1.8 2012/03/20 17:08:13 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998,1999 by Internet Software Consortium.
|
||||
@@ -15,8 +17,13 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_cidr_pton.c,v 1.8 2012/03/20 17:08:13 matt Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -32,6 +39,7 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
@@ -42,10 +50,13 @@ static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static int inet_cidr_pton_ipv4 __P((const char *src, u_char *dst,
|
||||
int *bits, int ipv6));
|
||||
static int inet_cidr_pton_ipv6 __P((const char *src, u_char *dst,
|
||||
int *bits));
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(inet_cidr_pton,_inet_cidr_pton)
|
||||
#endif
|
||||
|
||||
static int inet_cidr_pton_ipv4(const char *src, u_char *dst,
|
||||
int *bits, int ipv6);
|
||||
static int inet_cidr_pton_ipv6(const char *src, u_char *dst, int *bits);
|
||||
|
||||
static int getbits(const char *, int ipv6);
|
||||
|
||||
@@ -84,7 +95,8 @@ static const char digits[] = "0123456789";
|
||||
static int
|
||||
inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) {
|
||||
const u_char *odst = dst;
|
||||
int n, ch, tmp, bits;
|
||||
int ch, bits;
|
||||
ptrdiff_t n, tmp;
|
||||
size_t size = 4;
|
||||
|
||||
/* Get the mantissa. */
|
||||
@@ -176,7 +188,7 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) {
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
val |= (int)(pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
@@ -225,7 +237,7 @@ inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) {
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
const ptrdiff_t n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
@@ -264,7 +276,7 @@ getbits(const char *src, int ipv6) {
|
||||
if (cp == NULL) /*%< syntax */
|
||||
return (-2);
|
||||
bits *= 10;
|
||||
bits += cp - digits;
|
||||
bits += (int)(cp - digits);
|
||||
if (bits == 0 && *src != '\0') /*%< no leading zeros */
|
||||
return (-2);
|
||||
if (bits > (ipv6 ? 128 : 32)) /*%< range error */
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1995-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id: inet_data.c,v 1.4 2005/04/27 04:56:19 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT;
|
||||
const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
|
||||
|
||||
/*! \file */
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_lnaof.c,v 1.1 2004/05/20 23:13:02 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -31,8 +33,13 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_lnaof.c,v 1.1 2004/05/20 23:13:02 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -43,16 +50,15 @@ static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*%
|
||||
/*
|
||||
* Return the local network address portion of an
|
||||
* internet address; handles class a/b/c network
|
||||
* number formats.
|
||||
*/
|
||||
u_long
|
||||
inet_lnaof(in)
|
||||
struct in_addr in;
|
||||
in_addr_t
|
||||
inet_lnaof(struct in_addr in)
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
in_addr_t i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return ((i)&IN_CLASSA_HOST);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_makeaddr.c,v 1.1 2004/05/20 23:13:02 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -43,26 +45,26 @@ static const char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*%
|
||||
/*
|
||||
* Formulate an Internet address from network + host. Used in
|
||||
* building addresses stored in the ifnet structure.
|
||||
*/
|
||||
struct in_addr
|
||||
inet_makeaddr(net, host)
|
||||
u_long net, host;
|
||||
inet_makeaddr(in_addr_t net, in_addr_t host)
|
||||
{
|
||||
struct in_addr a;
|
||||
in_addr_t addr;
|
||||
struct in_addr ret;
|
||||
|
||||
if (net < 128U)
|
||||
a.s_addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
|
||||
else if (net < 65536U)
|
||||
a.s_addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
|
||||
if (net < 128)
|
||||
addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
|
||||
else if (net < 65536)
|
||||
addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
|
||||
else if (net < 16777216L)
|
||||
a.s_addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
|
||||
addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
|
||||
else
|
||||
a.s_addr = net | host;
|
||||
a.s_addr = htonl(a.s_addr);
|
||||
return (a);
|
||||
addr = net | host;
|
||||
ret.s_addr = htonl(addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef inet_makeaddr
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.5 2006/06/20 02:50:14 marka Exp $";
|
||||
#ifdef notdef
|
||||
static const char rcsid[] = "Id: inet_net_ntop.c,v 1.1.2.1 2002/08/02 02:17:21 marka Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_net_ntop.c,v 1.3 2012/03/20 17:08:13 matt Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -33,18 +38,22 @@ static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.5 2006/06/20 02:50:14 mark
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(inet_net_ntop,_inet_net_ntop)
|
||||
#endif
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
static char * inet_net_ntop_ipv4(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
static char * inet_net_ntop_ipv6(const u_char *src, int bits,
|
||||
char *dst, size_t size);
|
||||
|
||||
/*%
|
||||
/*
|
||||
* char *
|
||||
* inet_net_ntop(af, src, bits, dst, size)
|
||||
* convert network number from network to presentation format.
|
||||
@@ -55,12 +64,7 @@ static char * inet_net_ntop_ipv6 __P((const u_char *src, int bits,
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_net_ntop(af, src, bits, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
@@ -73,7 +77,7 @@ inet_net_ntop(af, src, bits, dst, size)
|
||||
}
|
||||
}
|
||||
|
||||
/*%
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
* convert IPv4 network number from network to presentation format.
|
||||
@@ -87,11 +91,7 @@ inet_net_ntop(af, src, bits, dst, size)
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
static char *
|
||||
inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
const u_char *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
@@ -148,7 +148,7 @@ inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*%
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv6(src, bits, fakebits, dst, size)
|
||||
* convert IPv6 network number from network to presentation format.
|
||||
@@ -166,17 +166,18 @@ inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
*/
|
||||
|
||||
static char *
|
||||
inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size)
|
||||
{
|
||||
u_int m;
|
||||
int b;
|
||||
int p;
|
||||
int zero_s, zero_l, tmp_zero_s, tmp_zero_l;
|
||||
int i;
|
||||
size_t p;
|
||||
size_t zero_s, zero_l, tmp_zero_s, tmp_zero_l;
|
||||
size_t i;
|
||||
int is_ipv4 = 0;
|
||||
unsigned char inbuf[16];
|
||||
char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
|
||||
char *cp;
|
||||
int words;
|
||||
size_t words;
|
||||
u_char *s;
|
||||
|
||||
if (bits < 0 || bits > 128) {
|
||||
@@ -264,7 +265,7 @@ inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
|
||||
}
|
||||
}
|
||||
/* Format CIDR /width. */
|
||||
sprintf(cp, "/%u", bits);
|
||||
(void)SPRINTF((cp, "/%u", bits));
|
||||
if (strlen(outbuf) + 1 > size)
|
||||
goto emsgsize;
|
||||
strcpy(dst, outbuf);
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 1996, 1998, 1999, 2001, 2003 Internet Software Consortium.
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_net_pton.c,v 1.10 2008/11/14 02:36:51 marka Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_net_pton.c,v 1.4.2.1 2002/08/02 02:17:21 marka Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_net_pton.c,v 1.4 2012/03/20 17:08:13 matt Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -28,6 +33,7 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.10 2008/11/14 02:36:51 mar
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
@@ -36,13 +42,18 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.10 2008/11/14 02:36:51 mar
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(inet_net_pton,_inet_net_pton)
|
||||
#endif
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*%
|
||||
|
||||
/*
|
||||
* static int
|
||||
* inet_net_pton_ipv4(src, dst, size)
|
||||
* convert IPv4 network number from presentation to network format.
|
||||
@@ -59,24 +70,28 @@ static const char rcsid[] = "$Id: inet_net_pton.c,v 1.10 2008/11/14 02:36:51 mar
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
static int
|
||||
inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
inet_net_pton_ipv4(const char *src, u_char *dst, size_t size)
|
||||
{
|
||||
static const char xdigits[] = "0123456789abcdef";
|
||||
static const char digits[] = "0123456789";
|
||||
int n, ch, tmp = 0, dirty, bits;
|
||||
int ch, dirty, bits;
|
||||
ptrdiff_t n, tmp;
|
||||
const u_char *odst = dst;
|
||||
|
||||
tmp = 0;
|
||||
ch = *src++;
|
||||
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||
&& isascii((unsigned char)(src[1]))
|
||||
&& isxdigit((unsigned char)(src[1]))) {
|
||||
&& isascii((u_char)(src[1]))
|
||||
&& isxdigit((u_char)(src[1]))) {
|
||||
/* Hexadecimal: Eat nybble string. */
|
||||
if (size <= 0U)
|
||||
if (size == 0)
|
||||
goto emsgsize;
|
||||
dirty = 0;
|
||||
src++; /*%< skip x or X. */
|
||||
while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
src++; /* skip x or X. */
|
||||
while ((ch = *src++) != '\0' && isascii((u_char)ch)
|
||||
&& isxdigit((u_char)ch)) {
|
||||
if (isupper((u_char)ch))
|
||||
ch = tolower((u_char)ch);
|
||||
n = strchr(xdigits, ch) - xdigits;
|
||||
INSIST(n >= 0 && n <= 15);
|
||||
if (dirty == 0)
|
||||
@@ -84,18 +99,18 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
else
|
||||
tmp = (tmp << 4) | n;
|
||||
if (++dirty == 2) {
|
||||
if (size-- <= 0U)
|
||||
if (size-- == 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
dirty = 0;
|
||||
}
|
||||
}
|
||||
if (dirty) { /*%< Odd trailing nybble? */
|
||||
if (size-- <= 0U)
|
||||
if (dirty) { /* Odd trailing nybble? */
|
||||
if (size-- == 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) (tmp << 4);
|
||||
}
|
||||
} else if (isascii(ch) && isdigit(ch)) {
|
||||
} else if (isascii((u_char)ch) && isdigit((u_char)ch)) {
|
||||
/* Decimal: eat dotted digit string. */
|
||||
for (;;) {
|
||||
tmp = 0;
|
||||
@@ -107,8 +122,8 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
if (size-- <= 0U)
|
||||
isascii((u_char)ch) && isdigit((u_char)ch));
|
||||
if (size-- == 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
if (ch == '\0' || ch == '/')
|
||||
@@ -116,26 +131,27 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
ch = *src++;
|
||||
if (!isascii(ch) || !isdigit(ch))
|
||||
if (!isascii((u_char)ch) || !isdigit((u_char)ch))
|
||||
goto enoent;
|
||||
}
|
||||
} else
|
||||
goto enoent;
|
||||
|
||||
bits = -1;
|
||||
if (ch == '/' && isascii((unsigned char)(src[0])) &&
|
||||
isdigit((unsigned char)(src[0])) && dst > odst) {
|
||||
if (ch == '/' && isascii((u_char)(src[0])) &&
|
||||
isdigit((u_char)(src[0])) && dst > odst) {
|
||||
/* CIDR width specifier. Nothing can follow it. */
|
||||
ch = *src++; /*%< Skip over the /. */
|
||||
ch = *src++; /* Skip over the /. */
|
||||
bits = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
INSIST(n >= 0 && n <= 9);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
bits += (int)n;
|
||||
if (bits > 32)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
goto emsgsize;
|
||||
} while ((ch = *src++) != '\0' && isascii((u_char)ch)
|
||||
&& isdigit((u_char)ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
}
|
||||
@@ -149,29 +165,23 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
goto enoent;
|
||||
/* If no CIDR spec was given, infer width from net class. */
|
||||
if (bits == -1) {
|
||||
if (*odst >= 240) /*%< Class E */
|
||||
if (*odst >= 240) /* Class E */
|
||||
bits = 32;
|
||||
else if (*odst >= 224) /*%< Class D */
|
||||
bits = 8;
|
||||
else if (*odst >= 192) /*%< Class C */
|
||||
else if (*odst >= 224) /* Class D */
|
||||
bits = 4;
|
||||
else if (*odst >= 192) /* Class C */
|
||||
bits = 24;
|
||||
else if (*odst >= 128) /*%< Class B */
|
||||
else if (*odst >= 128) /* Class B */
|
||||
bits = 16;
|
||||
else /*%< Class A */
|
||||
else /* Class A */
|
||||
bits = 8;
|
||||
/* If imputed mask is narrower than specified octets, widen. */
|
||||
if (bits < ((dst - odst) * 8))
|
||||
bits = (dst - odst) * 8;
|
||||
/*
|
||||
* If there are no additional bits specified for a class D
|
||||
* address adjust bits to 4.
|
||||
*/
|
||||
if (bits == 8 && *odst == 224)
|
||||
bits = 4;
|
||||
if (bits >= 8 && bits < ((dst - odst) * 8))
|
||||
bits = (int)(dst - odst) * 8;
|
||||
}
|
||||
/* Extend network to cover the actual mask. */
|
||||
while (bits > ((dst - odst) * 8)) {
|
||||
if (size-- <= 0U)
|
||||
if (size-- == 0)
|
||||
goto emsgsize;
|
||||
*dst++ = '\0';
|
||||
}
|
||||
@@ -187,7 +197,8 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
|
||||
}
|
||||
|
||||
static int
|
||||
getbits(const char *src, int *bitsp) {
|
||||
getbits(const char *src, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int n;
|
||||
int val;
|
||||
@@ -200,11 +211,11 @@ getbits(const char *src, int *bitsp) {
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /*%< no leading zeros */
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 128) /*%< range */
|
||||
val += (int)(pch - digits);
|
||||
if (val > 128) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
@@ -217,7 +228,8 @@ getbits(const char *src, int *bitsp) {
|
||||
}
|
||||
|
||||
static int
|
||||
getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
getv4(const char *src, u_char *dst, int *bitsp)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
u_char *odst = dst;
|
||||
int n;
|
||||
@@ -231,16 +243,16 @@ getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
|
||||
pch = strchr(digits, ch);
|
||||
if (pch != NULL) {
|
||||
if (n++ != 0 && val == 0) /*%< no leading zeros */
|
||||
if (n++ != 0 && val == 0) /* no leading zeros */
|
||||
return (0);
|
||||
val *= 10;
|
||||
val += (pch - digits);
|
||||
if (val > 255) /*%< range */
|
||||
val += (int)(pch - digits);
|
||||
if (val > 255) /* range */
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' || ch == '/') {
|
||||
if (dst - odst > 3) /*%< too many octets? */
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
if (ch == '/')
|
||||
@@ -253,14 +265,15 @@ getv4(const char *src, u_char *dst, int *bitsp) {
|
||||
}
|
||||
if (n == 0)
|
||||
return (0);
|
||||
if (dst - odst > 3) /*%< too many octets? */
|
||||
if (dst - odst > 3) /* too many octets? */
|
||||
return (0);
|
||||
*dst++ = val;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
inet_net_pton_ipv6(const char *src, u_char *dst, size_t size)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
@@ -293,7 +306,7 @@ inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
val |= (int)(pch - xdigits);
|
||||
if (++digits > 4)
|
||||
goto enoent;
|
||||
saw_xdigit = 1;
|
||||
@@ -322,7 +335,7 @@ inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
ipv4 = 1;
|
||||
break; /*%< '\\0' was seen by inet_pton4(). */
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
if (ch == '/' && getbits(src, &bits) > 0)
|
||||
break;
|
||||
@@ -349,7 +362,7 @@ inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
const ptrdiff_t n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
@@ -378,7 +391,7 @@ inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*%
|
||||
/*
|
||||
* int
|
||||
* inet_net_pton(af, src, dst, size)
|
||||
* convert network number from presentation to network format.
|
||||
@@ -392,7 +405,8 @@ inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
int
|
||||
inet_net_pton(int af, const char *src, void *dst, size_t size) {
|
||||
inet_net_pton(int af, const char *src, void *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_pton_ipv4(src, dst, size));
|
||||
|
||||
@@ -1,22 +1,29 @@
|
||||
/* $NetBSD: inet_neta.c,v 1.3 2012/06/25 22:32:44 abs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2005/04/27 04:56:20 sra Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_neta.c,v 1.3 2012/06/25 22:32:44 abs Exp $");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -26,19 +33,14 @@ static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2005/04/27 04:56:20 sra Exp
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*%
|
||||
/*
|
||||
* char *
|
||||
* inet_neta(src, dst, size)
|
||||
* format a u_long network number into presentation format.
|
||||
@@ -50,35 +52,40 @@ static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2005/04/27 04:56:20 sra Exp
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_neta(src, dst, size)
|
||||
u_long src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
inet_neta(u_long src, char *dst, size_t size)
|
||||
{
|
||||
char *odst = dst;
|
||||
char *tp;
|
||||
char *ep;
|
||||
int advance;
|
||||
|
||||
while (src & 0xffffffff) {
|
||||
u_char b = (src & 0xff000000) >> 24;
|
||||
assert(dst != NULL);
|
||||
|
||||
if (src == 0x00000000) {
|
||||
if (size < sizeof "0.0.0.0")
|
||||
goto emsgsize;
|
||||
strlcpy(dst, "0.0.0.0", size);
|
||||
return dst;
|
||||
}
|
||||
ep = dst + size;
|
||||
if (ep <= dst)
|
||||
goto emsgsize;
|
||||
while (src & 0xffffffffUL) {
|
||||
u_char b = (u_char)((src & 0xff000000UL) >> 24);
|
||||
|
||||
src <<= 8;
|
||||
if (b) {
|
||||
if (size < sizeof "255.")
|
||||
if (b || src) {
|
||||
advance = snprintf(dst, (size_t)(ep - dst), "%u", b);
|
||||
if (advance <= 0 || advance >= ep - dst)
|
||||
goto emsgsize;
|
||||
tp = dst;
|
||||
dst += SPRINTF((dst, "%u", b));
|
||||
dst += advance;
|
||||
if (src != 0L) {
|
||||
if (dst + 1 >= ep)
|
||||
goto emsgsize;
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - tp);
|
||||
}
|
||||
}
|
||||
if (dst == odst) {
|
||||
if (size < sizeof "0.0.0.0")
|
||||
goto emsgsize;
|
||||
strcpy(dst, "0.0.0.0");
|
||||
}
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_netof.c,v 1.1 2004/05/20 23:13:02 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -31,8 +33,13 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_netof.c,v 1.1 2004/05/20 23:13:02 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -43,15 +50,14 @@ static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*%
|
||||
/*
|
||||
* Return the network number from an internet
|
||||
* address; handles class a/b/c network #'s.
|
||||
*/
|
||||
u_long
|
||||
inet_netof(in)
|
||||
struct in_addr in;
|
||||
in_addr_t
|
||||
inet_netof(struct in_addr in)
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
in_addr_t i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_network.c,v 1.4 2008/01/20 04:56:08 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -31,8 +33,13 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_network.c,v 1.4 2008/01/20 04:56:08 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -40,42 +47,48 @@ static const char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#ifdef _DIAGNOSTIC
|
||||
#include <stddef.h> /* for NULL */
|
||||
#endif
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*%
|
||||
/*
|
||||
* Internet network address interpretation routine.
|
||||
* The library routines call this routine to interpret
|
||||
* network numbers.
|
||||
*/
|
||||
u_long
|
||||
inet_network(cp)
|
||||
register const char *cp;
|
||||
in_addr_t
|
||||
inet_network(const char *cp)
|
||||
{
|
||||
register u_long val, base, n, i;
|
||||
register char c;
|
||||
u_long parts[4], *pp = parts;
|
||||
int digit;
|
||||
in_addr_t val;
|
||||
size_t i, n;
|
||||
u_char c;
|
||||
in_addr_t parts[4], *pp = parts;
|
||||
int digit, base;
|
||||
|
||||
assert(cp != NULL);
|
||||
|
||||
again:
|
||||
val = 0; base = 10; digit = 0;
|
||||
if (*cp == '0')
|
||||
digit = 1, base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
digit = 0, base = 16, cp++;
|
||||
while ((c = *cp) != 0) {
|
||||
if (isdigit((unsigned char)c)) {
|
||||
if (base == 8U && (c == '8' || c == '9'))
|
||||
if (isdigit(c)) {
|
||||
if (base == 8 && (c == '8' || c == '9'))
|
||||
return (INADDR_NONE);
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
digit = 1;
|
||||
continue;
|
||||
}
|
||||
if (base == 16U && isxdigit((unsigned char)c)) {
|
||||
val = (val << 4) +
|
||||
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
if (base == 16 && isxdigit(c)) {
|
||||
val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
digit = 1;
|
||||
continue;
|
||||
@@ -84,17 +97,17 @@ again:
|
||||
}
|
||||
if (!digit)
|
||||
return (INADDR_NONE);
|
||||
if (pp >= parts + 4 || val > 0xffU)
|
||||
if (pp >= parts + 4 || val > 0xff)
|
||||
return (INADDR_NONE);
|
||||
if (*cp == '.') {
|
||||
*pp++ = val, cp++;
|
||||
goto again;
|
||||
}
|
||||
if (*cp && !isspace(*cp&0xff))
|
||||
if (*cp && !isspace((u_char) *cp))
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val;
|
||||
n = pp - parts;
|
||||
if (n > 4U)
|
||||
if (n > 4)
|
||||
return (INADDR_NONE);
|
||||
for (val = 0, i = 0; i < n; i++) {
|
||||
val <<= 8;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@@ -32,8 +34,11 @@
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
static const char rcsid[] = "$Id: inet_ntoa.c,v 1.2 2005/04/27 04:56:21 sra Exp $";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
// __RCSID("$NetBSD: inet_ntoa.c,v 1.2 2012/03/13 21:13:38 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -56,9 +61,9 @@ static const char rcsid[] = "$Id: inet_ntoa.c,v 1.2 2005/04/27 04:56:21 sra Exp
|
||||
inet_ntoa(struct in_addr in) {
|
||||
static char ret[18];
|
||||
|
||||
strcpy(ret, "[inet_ntoa error]");
|
||||
(void) inet_ntop(AF_INET, &in, ret, sizeof ret);
|
||||
return (ret);
|
||||
strlcpy(ret, "[inet_ntoa error]", sizeof(ret));
|
||||
(void) inet_ntop(AF_INET, &in, ret, (socklen_t)sizeof ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef inet_ntoa
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
@@ -15,8 +17,13 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_ntop.c,v 1.9 2012/03/20 17:08:13 matt Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -29,25 +36,21 @@ static const char rcsid[] = "$Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Ex
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*%
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
|
||||
static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
|
||||
static const char *inet_ntop4(const u_char *src, char *dst, socklen_t size);
|
||||
static const char *inet_ntop6(const u_char *src, char *dst, socklen_t size);
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
@@ -58,12 +61,12 @@ static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(af, src, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
char *dst;
|
||||
socklen_t size;
|
||||
inet_ntop(int af, const void *src, char *dst, socklen_t size)
|
||||
{
|
||||
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
@@ -78,7 +81,7 @@ inet_ntop(af, src, dst, size)
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
@@ -88,19 +91,21 @@ inet_ntop(af, src, dst, size)
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
inet_ntop4(const u_char *src, char *dst, socklen_t size)
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
int l;
|
||||
|
||||
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) {
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
l = snprintf(tmp, sizeof(tmp), "%u.%u.%u.%u",
|
||||
src[0], src[1], src[2], src[3]);
|
||||
if (l <= 0 || (socklen_t) l >= size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
strlcpy(dst, tmp, size);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
@@ -111,10 +116,7 @@ inet_ntop4(src, dst, size)
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
inet_ntop6(const u_char *src, char *dst, socklen_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
@@ -123,10 +125,15 @@ inet_ntop6(src, dst, size)
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
|
||||
char *tp, *ep;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
int advance;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
@@ -165,6 +172,7 @@ inet_ntop6(src, dst, size)
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
ep = tmp + sizeof(tmp);
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
@@ -174,23 +182,35 @@ inet_ntop6(src, dst, size)
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
if (i != 0) {
|
||||
if (tp + 1 >= ep)
|
||||
return (NULL);
|
||||
*tp++ = ':';
|
||||
}
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 && (best.len == 6 ||
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 ||
|
||||
(best.len == 7 && words[7] != 0x0001) ||
|
||||
(best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
if (!inet_ntop4(src+12, tp, (socklen_t)(ep - tp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
advance = snprintf(tp, (size_t)(ep - tp), "%x", words[i]);
|
||||
if (advance <= 0 || advance >= ep - tp)
|
||||
return (NULL);
|
||||
tp += advance;
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ)) {
|
||||
if (tp + 1 >= ep)
|
||||
return (NULL);
|
||||
*tp++ = ':';
|
||||
}
|
||||
if (tp + 1 >= ep)
|
||||
return (NULL);
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
@@ -200,7 +220,7 @@ inet_ntop6(src, dst, size)
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
strlcpy(dst, tmp, size);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
@@ -15,19 +17,29 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: inet_pton.c,v 1.8 2012/03/13 21:13:38 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/*%
|
||||
@@ -35,8 +47,8 @@ static const char rcsid[] = "$Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Ex
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4 __P((const char *src, u_char *dst));
|
||||
static int inet_pton6 __P((const char *src, u_char *dst));
|
||||
static int inet_pton4(const char *src, u_char *dst, int pton);
|
||||
static int inet_pton6(const char *src, u_char *dst);
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
@@ -50,14 +62,15 @@ static int inet_pton6 __P((const char *src, u_char *dst));
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(af, src, dst)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
return (inet_pton4(src, dst, 1));
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
@@ -68,54 +81,123 @@ inet_pton(af, src, dst)
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* inet_pton4(src, dst, pton)
|
||||
* when last arg is 0: inet_aton(). with hexadecimal, octal and shorthand.
|
||||
* when last arg is 1: inet_pton(). decimal dotted-quad only.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* 1 if `src' is a valid input, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
inet_pton4(const char *src, u_char *dst, int pton)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
u_int32_t val;
|
||||
u_int digit, base;
|
||||
ptrdiff_t n;
|
||||
unsigned char c;
|
||||
u_int parts[4];
|
||||
u_int *pp = parts;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (!saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
c = *src;
|
||||
for (;;) {
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if (!isdigit(c))
|
||||
return (0);
|
||||
val = 0; base = 10;
|
||||
if (c == '0') {
|
||||
c = *++src;
|
||||
if (c == 'x' || c == 'X')
|
||||
base = 16, c = *++src;
|
||||
else if (isdigit(c) && c != '9')
|
||||
base = 8;
|
||||
}
|
||||
/* inet_pton() takes decimal only */
|
||||
if (pton && base != 10)
|
||||
return (0);
|
||||
for (;;) {
|
||||
if (isdigit(c)) {
|
||||
digit = c - '0';
|
||||
if (digit >= base)
|
||||
break;
|
||||
val = (val * base) + digit;
|
||||
c = *++src;
|
||||
} else if (base == 16 && isxdigit(c)) {
|
||||
digit = c + 10 - (islower(c) ? 'a' : 'A');
|
||||
if (digit >= 16)
|
||||
break;
|
||||
val = (val << 4) | digit;
|
||||
c = *++src;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (c == '.') {
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16 bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
* a (with a treated as 32 bits)
|
||||
*/
|
||||
if (pp >= parts + 3)
|
||||
return (0);
|
||||
*pp++ = val;
|
||||
c = *++src;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (octets < 4)
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && !isspace(c))
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
/* inet_pton() takes dotted-quad only. it does not take shorthand. */
|
||||
if (pton && n != 4)
|
||||
return (0);
|
||||
switch (n) {
|
||||
|
||||
case 0:
|
||||
return (0); /* initial nondigit */
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (parts[0] > 0xff || val > 0xffffff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if ((parts[0] | parts[1]) > 0xff || val > 0xffff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if ((parts[0] | parts[1] | parts[2] | val) > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if (dst) {
|
||||
val = htonl(val);
|
||||
memcpy(dst, &val, NS_INADDRSZ);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -133,9 +215,7 @@ inet_pton4(src, dst)
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
inet_pton6(const char *src, u_char *dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
@@ -144,6 +224,9 @@ inet_pton6(src, dst)
|
||||
int ch, seen_xdigits;
|
||||
u_int val;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
@@ -161,7 +244,7 @@ inet_pton6(src, dst)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
val |= (int)(pch - xdigits);
|
||||
if (++seen_xdigits > 4)
|
||||
return (0);
|
||||
continue;
|
||||
@@ -173,9 +256,8 @@ inet_pton6(src, dst)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
} else if (*src == '\0') {
|
||||
} else if (*src == '\0')
|
||||
return (0);
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
@@ -185,7 +267,7 @@ inet_pton6(src, dst)
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
inet_pton4(curtok, tp, 1) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
seen_xdigits = 0;
|
||||
break; /*%< '\\0' was seen by inet_pton4(). */
|
||||
@@ -203,7 +285,7 @@ inet_pton6(src, dst)
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
const ptrdiff_t n = tp - colonp;
|
||||
int i;
|
||||
|
||||
if (tp == endp)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* $NetBSD: nsap_addr.c,v 1.6 2009/04/12 17:07:17 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
@@ -15,8 +17,13 @@
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Exp $";
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: nsap_addr.c,v 1.6 2009/04/12 17:07:17 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
@@ -29,6 +36,7 @@ static const char rcsid[] = "$Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Ex
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <resolv_mt.h>
|
||||
@@ -45,6 +53,9 @@ inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) {
|
||||
u_char c, nib;
|
||||
u_int len = 0;
|
||||
|
||||
assert(ascii != NULL);
|
||||
assert(binary != NULL);
|
||||
|
||||
if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X'))
|
||||
return (0);
|
||||
ascii += 2;
|
||||
@@ -83,6 +94,8 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
|
||||
char *tmpbuf = inet_nsap_ntoa_tmpbuf;
|
||||
char *start;
|
||||
|
||||
assert(binary != NULL);
|
||||
|
||||
if (ascii)
|
||||
start = ascii;
|
||||
else {
|
||||
@@ -97,7 +110,7 @@ inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
|
||||
binlen = 255;
|
||||
|
||||
for (i = 0; i < binlen; i++) {
|
||||
nib = *binary >> 4;
|
||||
nib = (u_int32_t)*binary >> 4;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
nib = *binary++ & 0x0f;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
/* $NetBSD: base64.c,v 1.14 2012/06/25 22:32:44 abs Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static const char rcsid[] = "Id: base64.c,v 1.4 2005/04/27 04:56:34 sra Exp";
|
||||
#else
|
||||
__RCSID("$NetBSD: base64.c,v 1.14 2012/06/25 22:32:44 abs Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#define Assert(Cond) if (!(Cond)) abort()
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
-------------------------------------------------
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
|
||||
size_t datalength = 0;
|
||||
u_char input[3];
|
||||
u_char output[4];
|
||||
size_t i;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(target != NULL);
|
||||
|
||||
while (2U < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = (u_int32_t)input[0] >> 2;
|
||||
output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
|
||||
((u_int32_t)input[1] >> 4);
|
||||
output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
|
||||
((u_int32_t)input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
Assert(output[3] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0U != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
|
||||
output[0] = (u_int32_t)input[0] >> 2;
|
||||
output[1] = ((u_int32_t)(input[0] & 0x03) << 4) +
|
||||
((u_int32_t)input[1] >> 4);
|
||||
output[2] = ((u_int32_t)(input[1] & 0x0f) << 2) +
|
||||
((u_int32_t)input[2] >> 6);
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
if (srclength == 1U)
|
||||
target[datalength++] = Pad64;
|
||||
else
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0'; /*%< Returned value doesn't count \\0. */
|
||||
assert (datalength <= (size_t)INT_MAX);
|
||||
return (int)datalength;
|
||||
}
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_pton(char const *src, u_char *target, size_t targsize)
|
||||
{
|
||||
size_t tarindex;
|
||||
int state, ch;
|
||||
char *pos;
|
||||
|
||||
assert(src != NULL);
|
||||
assert(target != NULL);
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while ((ch = (u_char) *src++) != '\0') {
|
||||
if (isspace(ch)) /*%< Skip whitespace anywhere. */
|
||||
continue;
|
||||
|
||||
if (ch == Pad64)
|
||||
break;
|
||||
|
||||
pos = strchr(Base64, ch);
|
||||
if (pos == 0) /*%< A non-base64 character. */
|
||||
return (-1);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] =
|
||||
(unsigned char)(pos - Base64) << 2;
|
||||
}
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |=
|
||||
(u_int32_t)(pos - Base64) >> 4;
|
||||
target[tarindex+1] =
|
||||
(unsigned char)
|
||||
(((pos - Base64) & 0x0f) << 4);
|
||||
}
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |=
|
||||
(u_int32_t)(pos - Base64) >> 2;
|
||||
target[tarindex+1] =
|
||||
(unsigned char)
|
||||
(((pos - Base64) & 0x03) << 6);
|
||||
}
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |=
|
||||
(unsigned char)(pos - Base64);
|
||||
}
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /*%< We got a pad char. */
|
||||
ch = *src++; /*%< Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /*%< Invalid = in first position */
|
||||
case 1: /*%< Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /*%< Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for (; ch != '\0'; ch = (u_char) *src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /*%< Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /*%< Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for (; ch != '\0'; ch = (u_char) *src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target && target[tarindex] != 0)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
assert(tarindex <= (size_t)INT_MAX);
|
||||
return (int)tarindex;
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns.c,v 1.5 2006/03/09 23:57:56 marka Exp $";
|
||||
#endif
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* dns.c --- this is the top-level accessor function for the dns
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* forward */
|
||||
|
||||
static void dns_close(struct irs_acc *);
|
||||
static struct __res_state * dns_res_get(struct irs_acc *);
|
||||
static void dns_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_dns_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct dns_p *dns;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(dns = memget(sizeof *dns))) {
|
||||
errno = ENOMEM;
|
||||
memput(acc, sizeof *acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(dns, 0x5e, sizeof *dns);
|
||||
dns->res = NULL;
|
||||
dns->free_res = NULL;
|
||||
if (hesiod_init(&dns->hes_ctx) < 0) {
|
||||
/*
|
||||
* We allow the dns accessor class to initialize
|
||||
* despite hesiod failing to initialize correctly,
|
||||
* since dns host queries don't depend on hesiod.
|
||||
*/
|
||||
dns->hes_ctx = NULL;
|
||||
}
|
||||
acc->private = dns;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_dns_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_dns_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_dns_sv;
|
||||
acc->pr_map = irs_dns_pr;
|
||||
acc->ho_map = irs_dns_ho;
|
||||
acc->nw_map = irs_dns_nw;
|
||||
acc->ng_map = irs_nul_ng;
|
||||
acc->res_get = dns_res_get;
|
||||
acc->res_set = dns_res_set;
|
||||
acc->close = dns_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* methods */
|
||||
static struct __res_state *
|
||||
dns_res_get(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
|
||||
if (dns->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
dns_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((dns->res->options & RES_INIT) == 0U &&
|
||||
res_ninit(dns->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (dns->res);
|
||||
}
|
||||
|
||||
static void
|
||||
dns_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
|
||||
if (dns->res && dns->free_res) {
|
||||
res_nclose(dns->res);
|
||||
(*dns->free_res)(dns->res);
|
||||
}
|
||||
dns->res = res;
|
||||
dns->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
dns_close(struct irs_acc *this) {
|
||||
struct dns_p *dns;
|
||||
|
||||
dns = (struct dns_p *)this->private;
|
||||
if (dns->res && dns->free_res)
|
||||
(*dns->free_res)(dns->res);
|
||||
if (dns->hes_ctx)
|
||||
hesiod_end(dns->hes_ctx);
|
||||
memput(dns, sizeof *dns);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_gr.c,v 1.4 2005/04/27 04:56:21 sra Exp $";
|
||||
#endif
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* dns_gr.c --- this file contains the functions for accessing
|
||||
* group information from Hesiod.
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
/*
|
||||
* This is our private accessor data. It has a shared hesiod context.
|
||||
*/
|
||||
struct dns_p * dns;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /*%< Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_close(struct irs_gr *);
|
||||
static int gr_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
static struct __res_state * gr_res_get(struct irs_gr *);
|
||||
static void gr_res_set(struct irs_gr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct group * get_hes_group(struct irs_gr *this,
|
||||
const char *name,
|
||||
const char *type);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_gr *
|
||||
irs_dns_gr(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
gr->private = pvt;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->close = gr_close;
|
||||
gr->list = gr_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = gr_res_get;
|
||||
gr->res_set = gr_res_set;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* methods */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
return (get_hes_group(this, name, "group"));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
char name[32];
|
||||
|
||||
sprintf(name, "%ld", (long)gid);
|
||||
return (get_hes_group(this, name, "gid"));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static int
|
||||
gr_list(struct irs_gr *this, const char *name,
|
||||
gid_t basegid, gid_t *groups, int *ngroups)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(name);
|
||||
UNUSED(basegid);
|
||||
UNUSED(groups);
|
||||
|
||||
*ngroups = 0;
|
||||
/* There's some way to do this in Hesiod. */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct group *
|
||||
get_hes_group(struct irs_gr *this, const char *name, const char *type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char **hes_list, *cp, **new;
|
||||
size_t num_members = 0;
|
||||
u_long t;
|
||||
|
||||
hes_list = hesiod_resolve(pvt->dns->hes_ctx, name, type);
|
||||
if (!hes_list)
|
||||
return (NULL);
|
||||
|
||||
/*
|
||||
* Copy the returned hesiod string into storage space.
|
||||
*/
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = strdup(*hes_list);
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
|
||||
cp = pvt->membuf;
|
||||
pvt->group.gr_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->group.gr_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
errno = 0;
|
||||
t = strtoul(cp, NULL, 10);
|
||||
if (errno == ERANGE)
|
||||
goto cleanup;
|
||||
pvt->group.gr_gid = (gid_t) t;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
cp++;
|
||||
|
||||
/*
|
||||
* Parse the members out.
|
||||
*/
|
||||
while (*cp) {
|
||||
if (num_members+1 >= pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
pvt->nmemb += 10;
|
||||
new = realloc(pvt->group.gr_mem,
|
||||
pvt->nmemb * sizeof(char *));
|
||||
if (new == NULL)
|
||||
goto cleanup;
|
||||
pvt->group.gr_mem = new;
|
||||
}
|
||||
pvt->group.gr_mem[num_members++] = cp;
|
||||
if (!(cp = strchr(cp, ',')))
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
if (!pvt->group.gr_mem) {
|
||||
pvt->group.gr_mem = malloc(sizeof(char*));
|
||||
if (!pvt->group.gr_mem)
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->group.gr_mem[num_members] = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
|
||||
cleanup:
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
}
|
||||
if (pvt->membuf) {
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
gr_res_get(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_res_set(struct irs_gr *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,591 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_nw.c,v 1.12 2005/04/27 04:56:22 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
#define MAXPACKET (64*1024)
|
||||
|
||||
struct pvt {
|
||||
struct nwent net;
|
||||
char * ali[MAXALIASES];
|
||||
char buf[BUFSIZ+1];
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
typedef union {
|
||||
long al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
enum by_what { by_addr, by_name };
|
||||
|
||||
/* Forwards. */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static struct nwent * get1101byaddr(struct irs_nw *, u_char *, int);
|
||||
static struct nwent * get1101byname(struct irs_nw *, const char *);
|
||||
static struct nwent * get1101answer(struct irs_nw *,
|
||||
u_char *ansbuf, int anslen,
|
||||
enum by_what by_what,
|
||||
int af, const char *name,
|
||||
const u_char *addr, int addrlen);
|
||||
static struct nwent * get1101mask(struct irs_nw *this, struct nwent *);
|
||||
static int make1101inaddr(const u_char *, int, char *, int);
|
||||
static void normalize_name(char *name);
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Exports. */
|
||||
|
||||
struct irs_nw *
|
||||
irs_dns_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (get1101byname(this, name));
|
||||
default:
|
||||
(void)NULL;
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (get1101byaddr(this, net, len));
|
||||
default:
|
||||
(void)NULL;
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct nwent *
|
||||
get1101byname(struct irs_nw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
u_char *ansbuf;
|
||||
int anslen;
|
||||
struct nwent *result;
|
||||
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
anslen = res_nsearch(pvt->res, name, C_IN, T_PTR, ansbuf, MAXPACKET);
|
||||
if (anslen < 0) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (NULL);
|
||||
}
|
||||
result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_name,
|
||||
AF_INET, name, NULL, 0));
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101byaddr(struct irs_nw *this, u_char *net, int len) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char qbuf[sizeof "255.255.255.255.in-addr.arpa"];
|
||||
struct nwent *result;
|
||||
u_char *ansbuf;
|
||||
int anslen;
|
||||
|
||||
if (len < 1 || len > 32) {
|
||||
errno = EINVAL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
if (make1101inaddr(net, len, qbuf, sizeof qbuf) < 0)
|
||||
return (NULL);
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
anslen = res_nquery(pvt->res, qbuf, C_IN, T_PTR, ansbuf, MAXPACKET);
|
||||
if (anslen < 0) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (NULL);
|
||||
}
|
||||
result = get1101mask(this, get1101answer(this, ansbuf, anslen, by_addr,
|
||||
AF_INET, NULL, net, len));
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (result);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101answer(struct irs_nw *this,
|
||||
u_char *ansbuf, int anslen, enum by_what by_what,
|
||||
int af, const char *name, const u_char *addr, int addrlen)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int type, class, ancount, qdcount, haveanswer;
|
||||
char *bp, *ep, **ap;
|
||||
u_char *cp, *eom;
|
||||
HEADER *hp;
|
||||
|
||||
/* Initialize, and parse header. */
|
||||
eom = ansbuf + anslen;
|
||||
if (ansbuf + HFIXEDSZ > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
hp = (HEADER *)ansbuf;
|
||||
cp = ansbuf + HFIXEDSZ;
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
while (qdcount-- > 0) {
|
||||
int n = dn_skipname(cp, eom);
|
||||
cp += n + QFIXEDSZ;
|
||||
if (n < 0 || cp > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
ancount = ntohs(hp->ancount);
|
||||
if (!ancount) {
|
||||
if (hp->aa)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
else
|
||||
RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Prepare a return structure. */
|
||||
bp = pvt->buf;
|
||||
ep = pvt->buf + sizeof(pvt->buf);
|
||||
pvt->net.n_name = NULL;
|
||||
pvt->net.n_aliases = pvt->ali;
|
||||
pvt->net.n_addrtype = af;
|
||||
pvt->net.n_addr = NULL;
|
||||
pvt->net.n_length = addrlen;
|
||||
|
||||
/* Save input key if given. */
|
||||
switch (by_what) {
|
||||
case by_name:
|
||||
if (name != NULL) {
|
||||
int n = strlen(name) + 1;
|
||||
|
||||
if (n > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
pvt->net.n_name = strcpy(bp, name); /* (checked) */
|
||||
bp += n;
|
||||
}
|
||||
break;
|
||||
case by_addr:
|
||||
if (addr != NULL && addrlen != 0) {
|
||||
int n = addrlen / 8 + ((addrlen % 8) != 0);
|
||||
|
||||
if (INADDRSZ > (ep - bp)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
memset(bp, 0, INADDRSZ);
|
||||
memcpy(bp, addr, n);
|
||||
pvt->net.n_addr = bp;
|
||||
bp += INADDRSZ;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Parse the answer, collect aliases. */
|
||||
ap = pvt->ali;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
int n = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
|
||||
cp += n; /*%< Owner */
|
||||
if (n < 0 || !maybe_dnok(pvt->res, bp) ||
|
||||
cp + 3 * INT16SZ + INT32SZ > eom) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
GETSHORT(type, cp); /*%< Type */
|
||||
GETSHORT(class, cp); /*%< Class */
|
||||
cp += INT32SZ; /*%< TTL */
|
||||
GETSHORT(n, cp); /*%< RDLENGTH */
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
int nn;
|
||||
|
||||
nn = dn_expand(ansbuf, eom, cp, bp, ep - bp);
|
||||
if (nn < 0 || !maybe_hnok(pvt->res, bp) || nn != n) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
normalize_name(bp);
|
||||
switch (by_what) {
|
||||
case by_addr: {
|
||||
if (pvt->net.n_name == NULL)
|
||||
pvt->net.n_name = bp;
|
||||
else if (ns_samename(pvt->net.n_name, bp) == 1)
|
||||
break;
|
||||
else
|
||||
*ap++ = bp;
|
||||
nn = strlen(bp) + 1;
|
||||
bp += nn;
|
||||
haveanswer++;
|
||||
break;
|
||||
}
|
||||
case by_name: {
|
||||
u_int b1, b2, b3, b4;
|
||||
|
||||
if (pvt->net.n_addr != NULL ||
|
||||
sscanf(bp, "%u.%u.%u.%u.in-addr.arpa",
|
||||
&b1, &b2, &b3, &b4) != 4)
|
||||
break;
|
||||
if ((ep - bp) < INADDRSZ) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
return (NULL);
|
||||
}
|
||||
pvt->net.n_addr = bp;
|
||||
*bp++ = b4;
|
||||
*bp++ = b3;
|
||||
*bp++ = b2;
|
||||
*bp++ = b1;
|
||||
pvt->net.n_length = INADDRSZ * 8;
|
||||
haveanswer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
cp += n; /*%< RDATA */
|
||||
}
|
||||
if (!haveanswer) {
|
||||
RES_SET_H_ERRNO(pvt->res, TRY_AGAIN);
|
||||
return (NULL);
|
||||
}
|
||||
*ap = NULL;
|
||||
|
||||
return (&pvt->net);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
get1101mask(struct irs_nw *this, struct nwent *nwent) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char qbuf[sizeof "255.255.255.255.in-addr.arpa"], owner[MAXDNAME];
|
||||
int anslen, type, class, ancount, qdcount;
|
||||
u_char *ansbuf, *cp, *eom;
|
||||
HEADER *hp;
|
||||
|
||||
if (!nwent)
|
||||
return (NULL);
|
||||
if (make1101inaddr(nwent->n_addr, nwent->n_length, qbuf, sizeof qbuf)
|
||||
< 0) {
|
||||
/* "First, do no harm." */
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
ansbuf = memget(MAXPACKET);
|
||||
if (ansbuf == NULL) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
/* Query for the A RR that would hold this network's mask. */
|
||||
anslen = res_nquery(pvt->res, qbuf, C_IN, T_A, ansbuf, MAXPACKET);
|
||||
if (anslen < HFIXEDSZ) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
/* Initialize, and parse header. */
|
||||
hp = (HEADER *)ansbuf;
|
||||
cp = ansbuf + HFIXEDSZ;
|
||||
eom = ansbuf + anslen;
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
while (qdcount-- > 0) {
|
||||
int n = dn_skipname(cp, eom);
|
||||
cp += n + QFIXEDSZ;
|
||||
if (n < 0 || cp > eom) {
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
}
|
||||
ancount = ntohs(hp->ancount);
|
||||
|
||||
/* Parse the answer, collect aliases. */
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
int n = dn_expand(ansbuf, eom, cp, owner, sizeof owner);
|
||||
|
||||
if (n < 0 || !maybe_dnok(pvt->res, owner))
|
||||
break;
|
||||
cp += n; /*%< Owner */
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom)
|
||||
break;
|
||||
GETSHORT(type, cp); /*%< Type */
|
||||
GETSHORT(class, cp); /*%< Class */
|
||||
cp += INT32SZ; /*%< TTL */
|
||||
GETSHORT(n, cp); /*%< RDLENGTH */
|
||||
if (cp + n > eom)
|
||||
break;
|
||||
if (n == INADDRSZ && class == C_IN && type == T_A &&
|
||||
ns_samename(qbuf, owner) == 1) {
|
||||
/* This A RR indicates the actual netmask. */
|
||||
int nn, mm;
|
||||
|
||||
nwent->n_length = 0;
|
||||
for (nn = 0; nn < INADDRSZ; nn++)
|
||||
for (mm = 7; mm >= 0; mm--)
|
||||
if (cp[nn] & (1 << mm))
|
||||
nwent->n_length++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
cp += n; /*%< RDATA */
|
||||
}
|
||||
memput(ansbuf, MAXPACKET);
|
||||
return (nwent);
|
||||
}
|
||||
|
||||
static int
|
||||
make1101inaddr(const u_char *net, int bits, char *name, int size) {
|
||||
int n, m;
|
||||
char *ep;
|
||||
|
||||
ep = name + size;
|
||||
|
||||
/* Zero fill any whole bytes left out of the prefix. */
|
||||
for (n = (32 - bits) / 8; n > 0; n--) {
|
||||
if (ep - name < (int)(sizeof "0."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "0."));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Format the partial byte, if any, within the prefix. */
|
||||
if ((n = bits % 8) != 0) {
|
||||
if (ep - name < (int)(sizeof "255."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "%u.",
|
||||
net[bits / 8] & ~((1 << (8 - n)) - 1)));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Format the whole bytes within the prefix. */
|
||||
for (n = bits / 8; n > 0; n--) {
|
||||
if (ep - name < (int)(sizeof "255."))
|
||||
goto emsgsize;
|
||||
m = SPRINTF((name, "%u.", net[n - 1]));
|
||||
name += m;
|
||||
}
|
||||
|
||||
/* Add the static text. */
|
||||
if (ep - name < (int)(sizeof "in-addr.arpa"))
|
||||
goto emsgsize;
|
||||
(void) SPRINTF((name, "in-addr.arpa"));
|
||||
return (0);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
normalize_name(char *name) {
|
||||
char *t;
|
||||
|
||||
/* Make lower case. */
|
||||
for (t = name; *t; t++)
|
||||
if (isascii((unsigned char)*t) && isupper((unsigned char)*t))
|
||||
*t = tolower((*t)&0xff);
|
||||
|
||||
/* Remove trailing dots. */
|
||||
while (t > name && t[-1] == '.')
|
||||
*--t = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0U) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: dns_p.h,v 1.4 2005/04/27 04:56:22 sra Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DNS_P_H_INCLUDED
|
||||
#define _DNS_P_H_INCLUDED
|
||||
|
||||
#define maybe_ok(res, nm, ok) (((res)->options & RES_NOCHECKNAME) != 0U || \
|
||||
(ok)(nm) != 0)
|
||||
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
|
||||
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
|
||||
|
||||
/*%
|
||||
* Object state.
|
||||
*/
|
||||
struct dns_p {
|
||||
void *hes_ctx;
|
||||
struct __res_state *res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Methods.
|
||||
*/
|
||||
|
||||
extern struct irs_gr * irs_dns_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_dns_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_dns_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_dns_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_dns_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_dns_nw __P((struct irs_acc *));
|
||||
|
||||
#endif /*_DNS_P_H_INCLUDED*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_pr.c,v 1.5 2005/04/27 04:56:22 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct protoent proto;
|
||||
char * prbuf;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
static struct __res_state * pr_res_get(struct irs_pr *);
|
||||
static void pr_res_set(struct irs_pr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct protoent * parse_hes_list(struct irs_pr *, char **);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_pr *
|
||||
irs_dns_pr(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct pvt *pvt;
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x5e, sizeof *pr);
|
||||
pvt->dns = dns;
|
||||
pr->private = pvt;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->close = pr_close;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = pr_res_get;
|
||||
pr->res_set = pr_res_set;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->proto.p_aliases)
|
||||
free(pvt->proto.p_aliases);
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct protoent *proto;
|
||||
char **hes_list;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, name, "protocol")))
|
||||
return (NULL);
|
||||
|
||||
proto = parse_hes_list(this, hes_list);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (proto);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int num) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct protoent *proto;
|
||||
char numstr[16];
|
||||
char **hes_list;
|
||||
|
||||
sprintf(numstr, "%d", num);
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, numstr, "protonum")))
|
||||
return (NULL);
|
||||
|
||||
proto = parse_hes_list(this, hes_list);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (proto);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pr_res_get(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
pr_res_set(struct irs_pr *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct protoent *
|
||||
parse_hes_list(struct irs_pr *this, char **hes_list) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *cp, **cpp, **new;
|
||||
int num = 0;
|
||||
int max = 0;
|
||||
|
||||
for (cpp = hes_list; *cpp; cpp++) {
|
||||
cp = *cpp;
|
||||
|
||||
/* Strip away comments, if any. */
|
||||
if ((p = strchr(cp, '#')))
|
||||
*p = 0;
|
||||
|
||||
/* Skip blank lines. */
|
||||
p = cp;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
|
||||
/* OK, we've got a live one. Let's parse it for real. */
|
||||
if (pvt->prbuf)
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = strdup(cp);
|
||||
|
||||
p = pvt->prbuf;
|
||||
pvt->proto.p_name = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->proto.p_proto = atoi(p);
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p) {
|
||||
if ((num + 1) >= max || !pvt->proto.p_aliases) {
|
||||
max += 10;
|
||||
new = realloc(pvt->proto.p_aliases,
|
||||
max * sizeof(char *));
|
||||
if (!new) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->proto.p_aliases = new;
|
||||
}
|
||||
pvt->proto.p_aliases[num++] = p;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (!pvt->proto.p_aliases)
|
||||
pvt->proto.p_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->proto.p_aliases)
|
||||
goto cleanup;
|
||||
pvt->proto.p_aliases[num] = NULL;
|
||||
return (&pvt->proto);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pvt->proto.p_aliases) {
|
||||
free(pvt->proto.p_aliases);
|
||||
pvt->proto.p_aliases = NULL;
|
||||
}
|
||||
if (pvt->prbuf) {
|
||||
free(pvt->prbuf);
|
||||
pvt->prbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,232 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_pw.c,v 1.3 2005/04/27 04:56:22 sra Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct passwd passwd;
|
||||
char * pwbuf;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
static struct __res_state * pw_res_get(struct irs_pw *);
|
||||
static void pw_res_set(struct irs_pw *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static struct passwd * getpwcommon(struct irs_pw *, const char *,
|
||||
const char *);
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_pw *
|
||||
irs_dns_pw(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->next = pw_next;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = pw_res_get;
|
||||
pw->res_set = pw_res_set;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *nam) {
|
||||
return (getpwcommon(this, nam, "passwd"));
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
char uidstr[16];
|
||||
|
||||
sprintf(uidstr, "%lu", (u_long)uid);
|
||||
return (getpwcommon(this, uidstr, "uid"));
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pw_res_get(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
pw_res_set(struct irs_pw *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static struct passwd *
|
||||
getpwcommon(struct irs_pw *this, const char *arg, const char *type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char **hes_list, *cp;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(pvt->dns->hes_ctx, arg, type)))
|
||||
return (NULL);
|
||||
if (!*hes_list) {
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
memset(&pvt->passwd, 0, sizeof pvt->passwd);
|
||||
if (pvt->pwbuf)
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = strdup(*hes_list);
|
||||
hesiod_free_list(pvt->dns->hes_ctx, hes_list);
|
||||
|
||||
cp = pvt->pwbuf;
|
||||
pvt->passwd.pw_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_uid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gid = atoi(cp);
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_gecos = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_dir = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->passwd.pw_shell = cp;
|
||||
return (&pvt->passwd);
|
||||
|
||||
cleanup:
|
||||
free(pvt->pwbuf);
|
||||
pvt->pwbuf = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
/*! \file */
|
||||
@@ -1,300 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: dns_sv.c,v 1.5 2005/04/27 04:56:23 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "dns_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct dns_p * dns;
|
||||
struct servent serv;
|
||||
char * svbuf;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void sv_close(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *,
|
||||
const char *, const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
#ifdef SV_RES_SETGET
|
||||
static struct __res_state * sv_res_get(struct irs_sv *);
|
||||
static void sv_res_set(struct irs_sv *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
#endif
|
||||
|
||||
static struct servent * parse_hes_list(struct irs_sv *,
|
||||
char **, const char *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_dns_sv(struct irs_acc *this) {
|
||||
struct dns_p *dns = (struct dns_p *)this->private;
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!dns || !dns->hes_ctx) {
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->dns = dns;
|
||||
if (!(sv = memget(sizeof *sv))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
sv->private = pvt;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->next = sv_next;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->close = sv_close;
|
||||
sv->minimize = sv_minimize;
|
||||
#ifdef SV_RES_SETGET
|
||||
sv->res_get = sv_res_get;
|
||||
sv->res_set = sv_res_set;
|
||||
#else
|
||||
sv->res_get = NULL; /*%< sv_res_get; */
|
||||
sv->res_set = NULL; /*%< sv_res_set; */
|
||||
#endif
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->serv.s_aliases)
|
||||
free(pvt->serv.s_aliases);
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct servent *s;
|
||||
char **hes_list;
|
||||
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, name, "service")))
|
||||
return (NULL);
|
||||
|
||||
s = parse_hes_list(this, hes_list, proto);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
struct servent *s;
|
||||
char portstr[16];
|
||||
char **hes_list;
|
||||
|
||||
sprintf(portstr, "%d", ntohs(port));
|
||||
if (!(hes_list = hesiod_resolve(dns->hes_ctx, portstr, "port")))
|
||||
return (NULL);
|
||||
|
||||
s = parse_hes_list(this, hes_list, proto);
|
||||
hesiod_free_list(dns->hes_ctx, hes_list);
|
||||
return (s);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
errno = ENODEV;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct servent *
|
||||
parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *cp, **cpp, **new;
|
||||
int proto_len;
|
||||
int num = 0;
|
||||
int max = 0;
|
||||
|
||||
for (cpp = hes_list; *cpp; cpp++) {
|
||||
cp = *cpp;
|
||||
|
||||
/* Strip away comments, if any. */
|
||||
if ((p = strchr(cp, '#')))
|
||||
*p = 0;
|
||||
|
||||
/* Check to make sure the protocol matches. */
|
||||
p = cp;
|
||||
while (*p && !isspace((unsigned char)*p))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
if (proto) {
|
||||
proto_len = strlen(proto);
|
||||
if (strncasecmp(++p, proto, proto_len) != 0)
|
||||
continue;
|
||||
if (p[proto_len] && !isspace(p[proto_len]&0xff))
|
||||
continue;
|
||||
}
|
||||
/* OK, we've got a live one. Let's parse it for real. */
|
||||
if (pvt->svbuf)
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = strdup(cp);
|
||||
|
||||
p = pvt->svbuf;
|
||||
pvt->serv.s_name = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->serv.s_proto = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (!*p)
|
||||
continue;
|
||||
*p++ = '\0';
|
||||
|
||||
pvt->serv.s_port = htons((u_short) atoi(p));
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p) {
|
||||
if ((num + 1) >= max || !pvt->serv.s_aliases) {
|
||||
max += 10;
|
||||
new = realloc(pvt->serv.s_aliases,
|
||||
max * sizeof(char *));
|
||||
if (!new) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
pvt->serv.s_aliases = new;
|
||||
}
|
||||
pvt->serv.s_aliases[num++] = p;
|
||||
while (*p && !isspace(*p&0xff))
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
}
|
||||
if (!pvt->serv.s_aliases)
|
||||
pvt->serv.s_aliases = malloc(sizeof(char *));
|
||||
if (!pvt->serv.s_aliases)
|
||||
goto cleanup;
|
||||
pvt->serv.s_aliases[num] = NULL;
|
||||
return (&pvt->serv);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (pvt->serv.s_aliases) {
|
||||
free(pvt->serv.s_aliases);
|
||||
pvt->serv.s_aliases = NULL;
|
||||
}
|
||||
if (pvt->svbuf) {
|
||||
free(pvt->svbuf);
|
||||
pvt->svbuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
#ifdef SV_RES_SETGET
|
||||
static struct __res_state *
|
||||
sv_res_get(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
return (__hesiod_res_get(dns->hes_ctx));
|
||||
}
|
||||
|
||||
static void
|
||||
sv_res_set(struct irs_sv *this, struct __res_state * res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct dns_p *dns = pvt->dns;
|
||||
|
||||
__hesiod_res_set(dns->hes_ctx, res, free_res);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*! \file */
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 2001 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <port_before.h>
|
||||
#include <netdb.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
static const char *gai_errlist[] = {
|
||||
"no error",
|
||||
"address family not supported for name",/*%< EAI_ADDRFAMILY */
|
||||
"temporary failure", /*%< EAI_AGAIN */
|
||||
"invalid flags", /*%< EAI_BADFLAGS */
|
||||
"permanent failure", /*%< EAI_FAIL */
|
||||
"address family not supported", /*%< EAI_FAMILY */
|
||||
"memory failure", /*%< EAI_MEMORY */
|
||||
"no address", /*%< EAI_NODATA */
|
||||
"unknown name or service", /*%< EAI_NONAME */
|
||||
"service not supported for socktype", /*%< EAI_SERVICE */
|
||||
"socktype not supported", /*%< EAI_SOCKTYPE */
|
||||
"system failure", /*%< EAI_SYSTEM */
|
||||
"bad hints", /*%< EAI_BADHINTS */
|
||||
"bad protocol", /*%< EAI_PROTOCOL */
|
||||
"unknown error" /*%< Must be last. */
|
||||
};
|
||||
|
||||
static const int gai_nerr = (sizeof(gai_errlist)/sizeof(*gai_errlist));
|
||||
|
||||
#define EAI_BUFSIZE 128
|
||||
|
||||
const char *
|
||||
gai_strerror(int ecode) {
|
||||
#ifndef DO_PTHREADS
|
||||
static char buf[EAI_BUFSIZE];
|
||||
#else /* DO_PTHREADS */
|
||||
#ifndef LIBBIND_MUTEX_INITIALIZER
|
||||
#define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
static pthread_mutex_t lock = LIBBIND_MUTEX_INITIALIZER;
|
||||
static pthread_key_t key;
|
||||
static int once = 0;
|
||||
char *buf;
|
||||
#endif
|
||||
|
||||
if (ecode >= 0 && ecode < (gai_nerr - 1))
|
||||
return (gai_errlist[ecode]);
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
if (!once) {
|
||||
if (pthread_mutex_lock(&lock) != 0)
|
||||
goto unknown;
|
||||
if (!once) {
|
||||
if (pthread_key_create(&key, free) != 0) {
|
||||
(void)pthread_mutex_unlock(&lock);
|
||||
goto unknown;
|
||||
}
|
||||
once = 1;
|
||||
}
|
||||
if (pthread_mutex_unlock(&lock) != 0)
|
||||
goto unknown;
|
||||
}
|
||||
|
||||
buf = pthread_getspecific(key);
|
||||
if (buf == NULL) {
|
||||
buf = malloc(EAI_BUFSIZE);
|
||||
if (buf == NULL)
|
||||
goto unknown;
|
||||
if (pthread_setspecific(key, buf) != 0) {
|
||||
free(buf);
|
||||
goto unknown;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* XXX This really should be snprintf(buf, EAI_BUFSIZE, ...).
|
||||
* It is safe until message catalogs are used.
|
||||
*/
|
||||
sprintf(buf, "%s: %d", gai_errlist[gai_nerr - 1], ecode);
|
||||
return (buf);
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
unknown:
|
||||
return ("unknown error");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,442 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen.c,v 1.7 2005/04/27 04:56:23 sra Exp $";
|
||||
#endif
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* this is the top level dispatcher
|
||||
*
|
||||
* The dispatcher is implemented as an accessor class; it is an
|
||||
* accessor class that calls other accessor classes, as controlled by a
|
||||
* configuration file.
|
||||
*
|
||||
* A big difference between this accessor class and others is that the
|
||||
* map class initializers are NULL, and the map classes are already
|
||||
* filled in with method functions that will do the right thing.
|
||||
*/
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <FindDirectory.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct nameval {
|
||||
const char * name;
|
||||
int val;
|
||||
};
|
||||
|
||||
static const struct nameval acc_names[irs_nacc+1] = {
|
||||
{ "local", irs_lcl },
|
||||
{ "dns", irs_dns },
|
||||
{ "nis", irs_nis },
|
||||
{ "irp", irs_irp },
|
||||
{ NULL, irs_nacc }
|
||||
};
|
||||
|
||||
typedef struct irs_acc *(*accinit) __P((const char *options));
|
||||
|
||||
static const accinit accs[irs_nacc+1] = {
|
||||
irs_lcl_acc,
|
||||
irs_dns_acc,
|
||||
#ifdef WANT_IRS_NIS
|
||||
irs_nis_acc,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
irs_irp_acc,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct nameval map_names[irs_nmap+1] = {
|
||||
{ "group", irs_gr },
|
||||
{ "passwd", irs_pw },
|
||||
{ "services", irs_sv },
|
||||
{ "protocols", irs_pr },
|
||||
{ "hosts", irs_ho },
|
||||
{ "networks", irs_nw },
|
||||
{ "netgroup", irs_ng },
|
||||
{ NULL, irs_nmap }
|
||||
};
|
||||
|
||||
static const struct nameval option_names[] = {
|
||||
{ "merge", IRS_MERGE },
|
||||
{ "continue", IRS_CONTINUE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gen_close(struct irs_acc *);
|
||||
static struct __res_state * gen_res_get(struct irs_acc *);
|
||||
static void gen_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
static int find_name(const char *, const struct nameval nv[]);
|
||||
static void init_map_rules(struct gen_p *, const char *conf_file);
|
||||
static struct irs_rule *release_rule(struct irs_rule *);
|
||||
static int add_rule(struct gen_p *,
|
||||
enum irs_map_id, enum irs_acc_id,
|
||||
const char *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_gen_acc(const char *options, const char *conf_file) {
|
||||
struct irs_acc *acc;
|
||||
struct gen_p *irs;
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(irs = memget(sizeof *irs))) {
|
||||
errno = ENOMEM;
|
||||
memput(acc, sizeof *acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(irs, 0x5e, sizeof *irs);
|
||||
irs->options = strdup(options);
|
||||
irs->res = NULL;
|
||||
irs->free_res = NULL;
|
||||
memset(irs->accessors, 0, sizeof irs->accessors);
|
||||
memset(irs->map_rules, 0, sizeof irs->map_rules);
|
||||
init_map_rules(irs, conf_file);
|
||||
acc->private = irs;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_gen_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_gen_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_gen_sv;
|
||||
acc->pr_map = irs_gen_pr;
|
||||
acc->ho_map = irs_gen_ho;
|
||||
acc->nw_map = irs_gen_nw;
|
||||
acc->ng_map = irs_gen_ng;
|
||||
acc->res_get = gen_res_get;
|
||||
acc->res_set = gen_res_set;
|
||||
acc->close = gen_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static struct __res_state *
|
||||
gen_res_get(struct irs_acc *this) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
|
||||
if (irs->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
gen_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if (((irs->res->options & RES_INIT) == 0U) && res_ninit(irs->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (irs->res);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
#if 0
|
||||
struct irs_rule *rule;
|
||||
struct irs_ho *ho;
|
||||
struct irs_nw *nw;
|
||||
#endif
|
||||
|
||||
if (irs->res && irs->free_res) {
|
||||
res_nclose(irs->res);
|
||||
(*irs->free_res)(irs->res);
|
||||
}
|
||||
|
||||
irs->res = res;
|
||||
irs->free_res = free_res;
|
||||
|
||||
#if 0
|
||||
for (rule = irs->map_rules[irs_ho]; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
|
||||
(*ho->res_set)(ho, res, NULL);
|
||||
}
|
||||
for (rule = irs->map_rules[irs_nw]; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
|
||||
(*nw->res_set)(nw, res, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
gen_close(struct irs_acc *this) {
|
||||
struct gen_p *irs = (struct gen_p *)this->private;
|
||||
int n;
|
||||
|
||||
/* Search rules. */
|
||||
for (n = 0; n < irs_nmap; n++)
|
||||
while (irs->map_rules[n] != NULL)
|
||||
irs->map_rules[n] = release_rule(irs->map_rules[n]);
|
||||
|
||||
/* Access methods. */
|
||||
for (n = 0; n < irs_nacc; n++) {
|
||||
/* Map objects. */
|
||||
if (irs->accessors[n].gr != NULL)
|
||||
(*irs->accessors[n].gr->close)(irs->accessors[n].gr);
|
||||
if (irs->accessors[n].pw != NULL)
|
||||
(*irs->accessors[n].pw->close)(irs->accessors[n].pw);
|
||||
if (irs->accessors[n].sv != NULL)
|
||||
(*irs->accessors[n].sv->close)(irs->accessors[n].sv);
|
||||
if (irs->accessors[n].pr != NULL)
|
||||
(*irs->accessors[n].pr->close)(irs->accessors[n].pr);
|
||||
if (irs->accessors[n].ho != NULL)
|
||||
(*irs->accessors[n].ho->close)(irs->accessors[n].ho);
|
||||
if (irs->accessors[n].nw != NULL)
|
||||
(*irs->accessors[n].nw->close)(irs->accessors[n].nw);
|
||||
if (irs->accessors[n].ng != NULL)
|
||||
(*irs->accessors[n].ng->close)(irs->accessors[n].ng);
|
||||
/* Enclosing accessor. */
|
||||
if (irs->accessors[n].acc != NULL)
|
||||
(*irs->accessors[n].acc->close)(irs->accessors[n].acc);
|
||||
}
|
||||
|
||||
/* The options string was strdup'd. */
|
||||
free((void*)irs->options);
|
||||
|
||||
if (irs->res && irs->free_res)
|
||||
(*irs->free_res)(irs->res);
|
||||
|
||||
/* The private data container. */
|
||||
memput(irs, sizeof *irs);
|
||||
|
||||
/* The object. */
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
find_name(const char *name, const struct nameval names[]) {
|
||||
int n;
|
||||
|
||||
for (n = 0; names[n].name != NULL; n++)
|
||||
if (strcmp(name, names[n].name) == 0)
|
||||
return (names[n].val);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static struct irs_rule *
|
||||
release_rule(struct irs_rule *rule) {
|
||||
struct irs_rule *next = rule->next;
|
||||
|
||||
memput(rule, sizeof *rule);
|
||||
return (next);
|
||||
}
|
||||
|
||||
static int
|
||||
add_rule(struct gen_p *irs,
|
||||
enum irs_map_id map, enum irs_acc_id acc,
|
||||
const char *options)
|
||||
{
|
||||
struct irs_rule **rules, *last, *tmp, *new;
|
||||
struct irs_inst *inst;
|
||||
const char *cp;
|
||||
int n;
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
if (map == irs_gr)
|
||||
return (-1);
|
||||
#endif
|
||||
#ifndef WANT_IRS_PW
|
||||
if (map == irs_pw)
|
||||
return (-1);
|
||||
#endif
|
||||
#ifndef WANT_IRS_NIS
|
||||
if (acc == irs_nis)
|
||||
return (-1);
|
||||
#endif
|
||||
new = memget(sizeof *new);
|
||||
if (new == NULL)
|
||||
return (-1);
|
||||
memset(new, 0x5e, sizeof *new);
|
||||
new->next = NULL;
|
||||
|
||||
new->inst = &irs->accessors[acc];
|
||||
|
||||
new->flags = 0;
|
||||
cp = options;
|
||||
while (cp && *cp) {
|
||||
char option[50], *next;
|
||||
|
||||
next = strchr(cp, ',');
|
||||
if (next)
|
||||
n = next++ - cp;
|
||||
else
|
||||
n = strlen(cp);
|
||||
if ((size_t)n > sizeof option - 1)
|
||||
n = sizeof option - 1;
|
||||
strncpy(option, cp, n);
|
||||
option[n] = '\0';
|
||||
|
||||
n = find_name(option, option_names);
|
||||
if (n >= 0)
|
||||
new->flags |= n;
|
||||
|
||||
cp = next;
|
||||
}
|
||||
|
||||
rules = &irs->map_rules[map];
|
||||
for (last = NULL, tmp = *rules;
|
||||
tmp != NULL;
|
||||
last = tmp, tmp = tmp->next)
|
||||
(void)NULL;
|
||||
if (last == NULL)
|
||||
*rules = new;
|
||||
else
|
||||
last->next = new;
|
||||
|
||||
/* Try to instantiate map accessors for this if necessary & approp. */
|
||||
inst = &irs->accessors[acc];
|
||||
if (inst->acc == NULL && accs[acc] != NULL)
|
||||
inst->acc = (*accs[acc])(irs->options);
|
||||
if (inst->acc != NULL) {
|
||||
if (inst->gr == NULL && inst->acc->gr_map != NULL)
|
||||
inst->gr = (*inst->acc->gr_map)(inst->acc);
|
||||
if (inst->pw == NULL && inst->acc->pw_map != NULL)
|
||||
inst->pw = (*inst->acc->pw_map)(inst->acc);
|
||||
if (inst->sv == NULL && inst->acc->sv_map != NULL)
|
||||
inst->sv = (*inst->acc->sv_map)(inst->acc);
|
||||
if (inst->pr == NULL && inst->acc->pr_map != NULL)
|
||||
inst->pr = (*inst->acc->pr_map)(inst->acc);
|
||||
if (inst->ho == NULL && inst->acc->ho_map != NULL)
|
||||
inst->ho = (*inst->acc->ho_map)(inst->acc);
|
||||
if (inst->nw == NULL && inst->acc->nw_map != NULL)
|
||||
inst->nw = (*inst->acc->nw_map)(inst->acc);
|
||||
if (inst->ng == NULL && inst->acc->ng_map != NULL)
|
||||
inst->ng = (*inst->acc->ng_map)(inst->acc);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
default_map_rules(struct gen_p *irs) {
|
||||
/* Install time honoured and proved BSD style rules as default. */
|
||||
add_rule(irs, irs_gr, irs_lcl, "");
|
||||
add_rule(irs, irs_pw, irs_lcl, "");
|
||||
add_rule(irs, irs_sv, irs_lcl, "");
|
||||
add_rule(irs, irs_pr, irs_lcl, "");
|
||||
add_rule(irs, irs_ho, irs_dns, "continue");
|
||||
add_rule(irs, irs_ho, irs_lcl, "");
|
||||
add_rule(irs, irs_nw, irs_dns, "continue");
|
||||
add_rule(irs, irs_nw, irs_lcl, "");
|
||||
add_rule(irs, irs_ng, irs_lcl, "");
|
||||
}
|
||||
|
||||
static void
|
||||
init_map_rules(struct gen_p *irs, const char *conf_file) {
|
||||
char line[1024], pattern[40], mapname[20], accname[20], options[100];
|
||||
char path[PATH_MAX];
|
||||
FILE *conf;
|
||||
|
||||
if (conf_file == NULL) {
|
||||
if (find_directory(B_SYSTEM_SETTINGS_DIRECTORY, -1, false, path,
|
||||
sizeof(path)) == B_OK) {
|
||||
strlcat(path, "/network/irs.conf", sizeof(path));
|
||||
conf_file = path;
|
||||
} else
|
||||
conf_file = _PATH_IRS_CONF;
|
||||
}
|
||||
|
||||
/* A conf file of "" means compiled in defaults. Irpd wants this */
|
||||
if (conf_file[0] == '\0' || (conf = fopen(conf_file, "r")) == NULL) {
|
||||
default_map_rules(irs);
|
||||
return;
|
||||
}
|
||||
(void) sprintf(pattern, "%%%lus %%%lus %%%lus\n",
|
||||
(unsigned long)sizeof mapname,
|
||||
(unsigned long)sizeof accname,
|
||||
(unsigned long)sizeof options);
|
||||
while (fgets(line, sizeof line, conf)) {
|
||||
enum irs_map_id map;
|
||||
enum irs_acc_id acc;
|
||||
char *tmp;
|
||||
int n;
|
||||
|
||||
for (tmp = line;
|
||||
isascii((unsigned char)*tmp) &&
|
||||
isspace((unsigned char)*tmp);
|
||||
tmp++)
|
||||
(void)NULL;
|
||||
if (*tmp == '#' || *tmp == '\n' || *tmp == '\0')
|
||||
continue;
|
||||
n = sscanf(tmp, pattern, mapname, accname, options);
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (n < 3)
|
||||
options[0] = '\0';
|
||||
|
||||
n = find_name(mapname, map_names);
|
||||
INSIST(n < irs_nmap);
|
||||
if (n < 0)
|
||||
continue;
|
||||
map = (enum irs_map_id) n;
|
||||
|
||||
n = find_name(accname, acc_names);
|
||||
INSIST(n < irs_nacc);
|
||||
if (n < 0)
|
||||
continue;
|
||||
acc = (enum irs_acc_id) n;
|
||||
|
||||
add_rule(irs, map, acc, options);
|
||||
}
|
||||
fclose(conf);
|
||||
}
|
||||
@@ -1,493 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_gr.c,v 1.8 2005/04/27 04:56:23 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_GR
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct irs_gr * gr;
|
||||
/*
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /*%< Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static int gr_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
static struct __res_state * gr_res_get(struct irs_gr *);
|
||||
static void gr_res_set(struct irs_gr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
static int grmerge(struct irs_gr *gr, const struct group *src,
|
||||
int preserve);
|
||||
|
||||
static int countvec(char **vec);
|
||||
static int isnew(char **old, char *new);
|
||||
static int countnew(char **old, char **new);
|
||||
static size_t sizenew(char **old, char **new);
|
||||
static int newgid(int, gid_t *, gid_t);
|
||||
|
||||
/* Macros */
|
||||
|
||||
#define FREE_IF(x) do { if ((x) != NULL) { free(x); (x) = NULL; } } while (0)
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_gr *
|
||||
irs_gen_gr(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_gr];
|
||||
pvt->rule = pvt->rules;
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = gr_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = gr_res_get;
|
||||
gr->res_set = gr_res_set;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *rval;
|
||||
struct irs_gr *gr;
|
||||
|
||||
while (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
rval = (*gr->next)(gr);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
(*gr->rewind)(gr);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct group *tval;
|
||||
struct irs_gr *gr;
|
||||
int dirty;
|
||||
|
||||
dirty = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
gr = rule->inst->gr;
|
||||
tval = (*gr->byname)(gr, name);
|
||||
if (tval) {
|
||||
if (!grmerge(this, tval, dirty++))
|
||||
return (NULL);
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dirty)
|
||||
return (&pvt->group);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct group *tval;
|
||||
struct irs_gr *gr;
|
||||
int dirty;
|
||||
|
||||
dirty = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
gr = rule->inst->gr;
|
||||
tval = (*gr->bygid)(gr, gid);
|
||||
if (tval) {
|
||||
if (!grmerge(this, tval, dirty++))
|
||||
return (NULL);
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (dirty)
|
||||
return (&pvt->group);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_gr *gr;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
gr = pvt->rule->inst->gr;
|
||||
(*gr->rewind)(gr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
gr_list(struct irs_gr *this, const char *name,
|
||||
gid_t basegid, gid_t *groups, int *ngroups)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct irs_gr *gr;
|
||||
int t_ngroups, maxgroups;
|
||||
gid_t *t_groups;
|
||||
int n, t, rval = 0;
|
||||
|
||||
maxgroups = *ngroups;
|
||||
*ngroups = 0;
|
||||
t_groups = (gid_t *)malloc(maxgroups * sizeof(gid_t));
|
||||
if (!t_groups) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
t_ngroups = maxgroups;
|
||||
gr = rule->inst->gr;
|
||||
t = (*gr->list)(gr, name, basegid, t_groups, &t_ngroups);
|
||||
for (n = 0; n < t_ngroups; n++) {
|
||||
if (newgid(*ngroups, groups, t_groups[n])) {
|
||||
if (*ngroups == maxgroups) {
|
||||
rval = -1;
|
||||
goto done;
|
||||
}
|
||||
groups[(*ngroups)++] = t_groups[n];
|
||||
}
|
||||
}
|
||||
if (t == 0) {
|
||||
if (!(rule->flags & IRS_MERGE))
|
||||
break;
|
||||
} else {
|
||||
if (!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
done:
|
||||
free(t_groups);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_gr *gr = rule->inst->gr;
|
||||
|
||||
(*gr->minimize)(gr);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
gr_res_get(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
gr_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_res_set(struct irs_gr *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_gr *gr = rule->inst->gr;
|
||||
|
||||
if (gr->res_set)
|
||||
(*gr->res_set)(gr, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
grmerge(struct irs_gr *this, const struct group *src, int preserve) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *cp, **m, **p, *oldmembuf, *ep;
|
||||
int n, ndst, nnew;
|
||||
size_t used;
|
||||
|
||||
if (!preserve) {
|
||||
pvt->group.gr_gid = src->gr_gid;
|
||||
if (pvt->nmemb < 1) {
|
||||
m = malloc(sizeof *m);
|
||||
if (m == NULL) {
|
||||
/* No harm done, no work done. */
|
||||
return (0);
|
||||
}
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = 1;
|
||||
}
|
||||
pvt->group.gr_mem[0] = NULL;
|
||||
}
|
||||
ndst = countvec(pvt->group.gr_mem);
|
||||
nnew = countnew(pvt->group.gr_mem, src->gr_mem);
|
||||
|
||||
/*
|
||||
* Make sure destination member array is large enough.
|
||||
* p points to new portion.
|
||||
*/
|
||||
n = ndst + nnew + 1;
|
||||
if ((size_t)n > pvt->nmemb) {
|
||||
m = realloc(pvt->group.gr_mem, n * sizeof *m);
|
||||
if (m == NULL) {
|
||||
/* No harm done, no work done. */
|
||||
return (0);
|
||||
}
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = n;
|
||||
}
|
||||
p = pvt->group.gr_mem + ndst;
|
||||
|
||||
/*
|
||||
* Enlarge destination membuf; cp points at new portion.
|
||||
*/
|
||||
n = sizenew(pvt->group.gr_mem, src->gr_mem);
|
||||
INSIST((nnew == 0) == (n == 0));
|
||||
if (!preserve) {
|
||||
n += strlen(src->gr_name) + 1;
|
||||
n += strlen(src->gr_passwd) + 1;
|
||||
}
|
||||
if (n == 0) {
|
||||
/* No work to do. */
|
||||
return (1);
|
||||
}
|
||||
used = preserve ? pvt->membufsize : 0;
|
||||
cp = malloc(used + n);
|
||||
if (cp == NULL) {
|
||||
/* No harm done, no work done. */
|
||||
return (0);
|
||||
}
|
||||
ep = cp + used + n;
|
||||
if (used != 0)
|
||||
memcpy(cp, pvt->membuf, used);
|
||||
oldmembuf = pvt->membuf;
|
||||
pvt->membuf = cp;
|
||||
pvt->membufsize = used + n;
|
||||
cp += used;
|
||||
|
||||
/*
|
||||
* Adjust group.gr_mem.
|
||||
*/
|
||||
if (pvt->membuf != oldmembuf)
|
||||
for (m = pvt->group.gr_mem; *m; m++)
|
||||
*m = pvt->membuf + (*m - oldmembuf);
|
||||
|
||||
/*
|
||||
* Add new elements.
|
||||
*/
|
||||
for (m = src->gr_mem; *m; m++)
|
||||
if (isnew(pvt->group.gr_mem, *m)) {
|
||||
*p++ = cp;
|
||||
*p = NULL;
|
||||
n = strlen(*m) + 1;
|
||||
if (n > ep - cp) {
|
||||
FREE_IF(oldmembuf);
|
||||
return (0);
|
||||
}
|
||||
strcpy(cp, *m); /* (checked) */
|
||||
cp += n;
|
||||
}
|
||||
if (preserve) {
|
||||
pvt->group.gr_name = pvt->membuf +
|
||||
(pvt->group.gr_name - oldmembuf);
|
||||
pvt->group.gr_passwd = pvt->membuf +
|
||||
(pvt->group.gr_passwd - oldmembuf);
|
||||
} else {
|
||||
pvt->group.gr_name = cp;
|
||||
n = strlen(src->gr_name) + 1;
|
||||
if (n > ep - cp) {
|
||||
FREE_IF(oldmembuf);
|
||||
return (0);
|
||||
}
|
||||
strcpy(cp, src->gr_name); /* (checked) */
|
||||
cp += n;
|
||||
|
||||
pvt->group.gr_passwd = cp;
|
||||
n = strlen(src->gr_passwd) + 1;
|
||||
if (n > ep - cp) {
|
||||
FREE_IF(oldmembuf);
|
||||
return (0);
|
||||
}
|
||||
strcpy(cp, src->gr_passwd); /* (checked) */
|
||||
cp += n;
|
||||
}
|
||||
FREE_IF(oldmembuf);
|
||||
INSIST(cp >= pvt->membuf && cp <= &pvt->membuf[pvt->membufsize]);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
countvec(char **vec) {
|
||||
int n = 0;
|
||||
|
||||
while (*vec++)
|
||||
n++;
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
isnew(char **old, char *new) {
|
||||
for (; *old; old++)
|
||||
if (strcmp(*old, new) == 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
countnew(char **old, char **new) {
|
||||
int n = 0;
|
||||
|
||||
for (; *new; new++)
|
||||
n += isnew(old, *new);
|
||||
return (n);
|
||||
}
|
||||
|
||||
static size_t
|
||||
sizenew(char **old, char **new) {
|
||||
size_t n = 0;
|
||||
|
||||
for (; *new; new++)
|
||||
if (isnew(old, *new))
|
||||
n += strlen(*new) + 1;
|
||||
return (n);
|
||||
}
|
||||
|
||||
static int
|
||||
newgid(int ngroups, gid_t *groups, gid_t group) {
|
||||
ngroups--, groups++;
|
||||
for (; ngroups-- > 0; groups++)
|
||||
if (*groups == group)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
/*! \file */
|
||||
@@ -1,391 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: gen_ho.c,v 1.5 2006/03/09 23:57:56 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct irs_ho * ho;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forwards */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Exports */
|
||||
|
||||
struct irs_ho *
|
||||
irs_gen_ho(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
pvt->rules = accpvt->map_rules[irs_ho];
|
||||
pvt->rule = pvt->rules;
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byname)(ho, name);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* The value TRY_AGAIN can mean that the service
|
||||
* is not available, or just that this particular name
|
||||
* cannot be resolved now. We use the errno ECONNREFUSED
|
||||
* to distinguish. If a lookup sets that errno when
|
||||
* H_ERRNO is TRY_AGAIN, we continue to try other lookup
|
||||
* functions, otherwise we return the TRY_AGAIN error.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byname2)(ho, name, af);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
rval = (*ho->byaddr)(ho, addr, len, af);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN || errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *rval;
|
||||
struct irs_ho *ho;
|
||||
|
||||
while (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
rval = (*ho->next)(ho);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
(*ho->rewind)(ho);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ho *ho;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
ho = pvt->rule->inst->ho;
|
||||
(*ho->rewind)(ho);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ho *ho = rule->inst->ho;
|
||||
|
||||
(*ho->minimize)(ho);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ho *ho = rule->inst->ho;
|
||||
|
||||
(*ho->res_set)(ho, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct addrinfo *rval = NULL;
|
||||
struct irs_ho *ho;
|
||||
int therrno = NETDB_INTERNAL;
|
||||
int softerror = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ho = rule->inst->ho;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
errno = 0;
|
||||
if (ho->addrinfo == NULL) /*%< for safety */
|
||||
continue;
|
||||
rval = (*ho->addrinfo)(ho, name, pai);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (softerror == 0 &&
|
||||
pvt->res->res_h_errno != HOST_NOT_FOUND &&
|
||||
pvt->res->res_h_errno != NETDB_INTERNAL) {
|
||||
softerror = 1;
|
||||
therrno = pvt->res->res_h_errno;
|
||||
}
|
||||
if (rule->flags & IRS_CONTINUE)
|
||||
continue;
|
||||
/*
|
||||
* See the comments in ho_byname() explaining
|
||||
* the interpretation of TRY_AGAIN and ECONNREFUSED.
|
||||
*/
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN ||
|
||||
errno != ECONNREFUSED)
|
||||
break;
|
||||
}
|
||||
if (softerror != 0 && pvt->res->res_h_errno == HOST_NOT_FOUND)
|
||||
RES_SET_H_ERRNO(pvt->res, therrno);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
|
||||
if (((pvt->res->options & RES_INIT) == 0U) &&
|
||||
(res_ninit(pvt->res) == -1))
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_ng.c,v 1.3 2005/04/27 04:56:23 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
char * curgroup;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_rewind(struct irs_ng *, const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_gen_ng(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_ng];
|
||||
pvt->rule = pvt->rules;
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ng_minimize(this);
|
||||
if (pvt->curgroup)
|
||||
free(pvt->curgroup);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ng *ng;
|
||||
|
||||
while (pvt->rule) {
|
||||
ng = pvt->rule->inst->ng;
|
||||
if ((*ng->next)(ng, host, user, domain) == 1)
|
||||
return (1);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
ng = pvt->rule->inst->ng;
|
||||
(*ng->rewind)(ng, pvt->curgroup);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *user, const char *host, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct irs_ng *ng;
|
||||
int rval;
|
||||
|
||||
rval = 0;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
ng = rule->inst->ng;
|
||||
rval = (*ng->test)(ng, name, user, host, domain);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_ng *ng;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
if (pvt->curgroup)
|
||||
free(pvt->curgroup);
|
||||
pvt->curgroup = strdup(group);
|
||||
ng = pvt->rule->inst->ng;
|
||||
(*ng->rewind)(ng, pvt->curgroup);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_ng *ng = rule->inst->ng;
|
||||
|
||||
(*ng->minimize)(ng);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_nw.c,v 1.4 2005/04/27 04:56:23 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw*);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_nw *
|
||||
irs_gen_nw(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
pvt->rules = accpvt->map_rules[irs_nw];
|
||||
pvt->rule = pvt->rules;
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->next = nw_next;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
while (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
rval = (*nw->next)(nw);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rules->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
(*nw->rewind)(nw);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
rval = (*nw->byname)(nw, name, type);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN &&
|
||||
!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct nwent *rval;
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
nw = rule->inst->nw;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
rval = (*nw->byaddr)(nw, net, length, type);
|
||||
if (rval != NULL)
|
||||
return (rval);
|
||||
if (pvt->res->res_h_errno != TRY_AGAIN &&
|
||||
!(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_nw *nw;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
nw = pvt->rule->inst->nw;
|
||||
(*nw->rewind)(nw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_nw *nw = rule->inst->nw;
|
||||
|
||||
(*nw->minimize)(nw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_nw *nw = rule->inst->nw;
|
||||
|
||||
(*nw->res_set)(nw, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0U) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: gen_p.h,v 1.3 2005/04/27 04:56:23 sra Exp $
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* Notes:
|
||||
* We hope to create a complete set of thread-safe entry points someday,
|
||||
* which will mean a set of getXbyY() functions that take as an argument
|
||||
* a pointer to the map class, which will have a pointer to the private
|
||||
* data, which will be used preferentially to the static variables that
|
||||
* are necessary to support the "classic" interface. This "classic"
|
||||
* interface will then be reimplemented as stubs on top of the thread
|
||||
* safe modules, and will keep the map class pointers as their only
|
||||
* static data. HOWEVER, we are not there yet. So while we will call
|
||||
* the just-barely-converted map class methods with map class pointers,
|
||||
* right now they probably all still use statics. We're not fooling
|
||||
* anybody, and we're not trying to (yet).
|
||||
*/
|
||||
|
||||
#ifndef _GEN_P_H_INCLUDED
|
||||
#define _GEN_P_H_INCLUDED
|
||||
|
||||
/*%
|
||||
* These are the access methods.
|
||||
*/
|
||||
enum irs_acc_id {
|
||||
irs_lcl, /*%< Local. */
|
||||
irs_dns, /*%< DNS or Hesiod. */
|
||||
irs_nis, /*%< Sun NIS ("YP"). */
|
||||
irs_irp, /*%< IR protocol. */
|
||||
irs_nacc
|
||||
};
|
||||
|
||||
/*%
|
||||
* These are the map types.
|
||||
*/
|
||||
enum irs_map_id {
|
||||
irs_gr, /*%< "group" */
|
||||
irs_pw, /*%< "passwd" */
|
||||
irs_sv, /*%< "services" */
|
||||
irs_pr, /*%< "protocols" */
|
||||
irs_ho, /*%< "hosts" */
|
||||
irs_nw, /*%< "networks" */
|
||||
irs_ng, /*%< "netgroup" */
|
||||
irs_nmap
|
||||
};
|
||||
|
||||
/*%
|
||||
* This is an accessor instance.
|
||||
*/
|
||||
struct irs_inst {
|
||||
struct irs_acc *acc;
|
||||
struct irs_gr * gr;
|
||||
struct irs_pw * pw;
|
||||
struct irs_sv * sv;
|
||||
struct irs_pr * pr;
|
||||
struct irs_ho * ho;
|
||||
struct irs_nw * nw;
|
||||
struct irs_ng * ng;
|
||||
};
|
||||
|
||||
/*%
|
||||
* This is a search rule for some map type.
|
||||
*/
|
||||
struct irs_rule {
|
||||
struct irs_rule * next;
|
||||
struct irs_inst * inst;
|
||||
int flags;
|
||||
};
|
||||
#define IRS_MERGE 0x0001 /*%< Don't stop if acc. has data? */
|
||||
#define IRS_CONTINUE 0x0002 /*%< Don't stop if acc. has no data? */
|
||||
/*
|
||||
* This is the private data for a search access class.
|
||||
*/
|
||||
struct gen_p {
|
||||
char * options;
|
||||
struct irs_rule * map_rules[(int)irs_nmap];
|
||||
struct irs_inst accessors[(int)irs_nacc];
|
||||
struct __res_state * res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_gen_acc __P((const char *, const char *conf_file));
|
||||
extern struct irs_gr * irs_gen_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_gen_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_gen_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_gen_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_gen_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_gen_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_gen_ng __P((struct irs_acc *));
|
||||
|
||||
#endif /*_IRS_P_H_INCLUDED*/
|
||||
@@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_pr.c,v 1.3 2005/04/27 04:56:24 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr*);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
static struct __res_state * pr_res_get(struct irs_pr *);
|
||||
static void pr_res_set(struct irs_pr *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pr *
|
||||
irs_gen_pr(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x5e, sizeof *pr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *pr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_pr];
|
||||
pvt->rule = pvt->rules;
|
||||
pr->private = pvt;
|
||||
pr->close = pr_close;
|
||||
pr->next = pr_next;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = pr_res_get;
|
||||
pr->res_set = pr_res_set;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
while (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
rval = (*pr->next)(pr);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rules->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
(*pr->rewind)(pr);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pr = rule->inst->pr;
|
||||
rval = (*pr->byname)(pr, name);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct protoent *rval;
|
||||
struct irs_pr *pr;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pr = rule->inst->pr;
|
||||
rval = (*pr->bynumber)(pr, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_pr *pr;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
pr = pvt->rule->inst->pr;
|
||||
(*pr->rewind)(pr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pr *pr = rule->inst->pr;
|
||||
|
||||
(*pr->minimize)(pr);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pr_res_get(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
pr_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_res_set(struct irs_pr *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pr *pr = rule->inst->pr;
|
||||
|
||||
if (pr->res_set)
|
||||
(*pr->res_set)(pr, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_pw.c,v 1.3 2005/04/27 04:56:24 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
static struct __res_state * pw_res_get(struct irs_pw *);
|
||||
static void pw_res_set(struct irs_pw *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_pw *
|
||||
irs_gen_pw(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pw, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_pw];
|
||||
pvt->rule = pvt->rules;
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = pw_res_get;
|
||||
pw->res_set = pw_res_set;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
while (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
rval = (*pw->next)(pw);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
(*pw->rewind)(pw);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_pw *pw;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
pw = pvt->rule->inst->pw;
|
||||
(*pw->rewind)(pw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pw = rule->inst->pw;
|
||||
rval = (*pw->byname)(pw, name);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct passwd *rval;
|
||||
struct irs_pw *pw;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
pw = rule->inst->pw;
|
||||
rval = (*pw->byuid)(pw, uid);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pw *pw = rule->inst->pw;
|
||||
|
||||
(*pw->minimize)(pw);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
pw_res_get(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
pw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_res_set(struct irs_pw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_pw *pw = rule->inst->pw;
|
||||
|
||||
if (pw->res_set)
|
||||
(*pw->res_set)(pw, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
/*! \file */
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: gen_sv.c,v 1.3 2005/04/27 04:56:24 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "gen_p.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irs_rule * rules;
|
||||
struct irs_rule * rule;
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
static struct __res_state * sv_res_get(struct irs_sv *);
|
||||
static void sv_res_set(struct irs_sv *,
|
||||
struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_sv *
|
||||
irs_gen_sv(struct irs_acc *this) {
|
||||
struct gen_p *accpvt = (struct gen_p *)this->private;
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(sv = memget(sizeof *sv))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x5e, sizeof *sv);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->rules = accpvt->map_rules[irs_sv];
|
||||
pvt->rule = pvt->rules;
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
sv->res_get = sv_res_get;
|
||||
sv->res_set = sv_res_set;
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
while (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
rval = (*sv->next)(sv);
|
||||
if (rval)
|
||||
return (rval);
|
||||
if (!(pvt->rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
pvt->rule = pvt->rule->next;
|
||||
if (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
(*sv->rewind)(sv);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
sv = rule->inst->sv;
|
||||
rval = (*sv->byname)(sv, name, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
struct servent *rval;
|
||||
struct irs_sv *sv;
|
||||
|
||||
rval = NULL;
|
||||
for (rule = pvt->rules; rule; rule = rule->next) {
|
||||
sv = rule->inst->sv;
|
||||
rval = (*sv->byport)(sv, port, proto);
|
||||
if (rval || !(rule->flags & IRS_CONTINUE))
|
||||
break;
|
||||
}
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_sv *sv;
|
||||
|
||||
pvt->rule = pvt->rules;
|
||||
if (pvt->rule) {
|
||||
sv = pvt->rule->inst->sv;
|
||||
(*sv->rewind)(sv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_sv *sv = rule->inst->sv;
|
||||
|
||||
(*sv->minimize)(sv);
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
sv_res_get(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
sv_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
sv_res_set(struct irs_sv *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct irs_rule *rule;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
|
||||
for (rule = pvt->rules; rule != NULL; rule = rule->next) {
|
||||
struct irs_sv *sv = rule->inst->sv;
|
||||
|
||||
if (sv->res_set)
|
||||
(*sv->res_set)(sv, pvt->res, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getgrent.c,v 1.5 2005/04/27 04:56:24 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_GR) || defined(__BIND_NOSTATIC)
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
void endgrent(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct group *
|
||||
getgrent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrent_p(net_data));
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrnam(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrnam_p(name, net_data));
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrgid(gid_t gid) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrgid_p(gid, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
setgroupent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setgroupent_p(stayopen, net_data));
|
||||
}
|
||||
|
||||
#ifdef SETGRENT_VOID
|
||||
void
|
||||
setgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setgrent_p(net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setgrent_p(net_data));
|
||||
}
|
||||
#endif /* SETGRENT_VOID */
|
||||
|
||||
void
|
||||
endgrent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endgrent_p(net_data);
|
||||
}
|
||||
|
||||
int
|
||||
getgrouplist(GETGROUPLIST_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getgrouplist_p(name, basegid, groups, ngroups, net_data));
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct group *
|
||||
getgrent_p(struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
net_data->gr_last = (*gr->next)(gr);
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrnam_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
if (net_data->gr_stayopen && net_data->gr_last &&
|
||||
!strcmp(net_data->gr_last->gr_name, name))
|
||||
return (net_data->gr_last);
|
||||
net_data->gr_last = (*gr->byname)(gr, name);
|
||||
if (!net_data->gr_stayopen)
|
||||
endgrent();
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
struct group *
|
||||
getgrgid_p(gid_t gid, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (NULL);
|
||||
if (net_data->gr_stayopen && net_data->gr_last &&
|
||||
(gid_t)net_data->gr_last->gr_gid == gid)
|
||||
return (net_data->gr_last);
|
||||
net_data->gr_last = (*gr->bygid)(gr, gid);
|
||||
if (!net_data->gr_stayopen)
|
||||
endgrent();
|
||||
return (net_data->gr_last);
|
||||
}
|
||||
|
||||
int
|
||||
setgroupent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr))
|
||||
return (0);
|
||||
(*gr->rewind)(gr);
|
||||
net_data->gr_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SETGRENT_VOID
|
||||
void
|
||||
setgrent_p(struct net_data *net_data) {
|
||||
(void)setgroupent_p(0, net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setgrent_p(struct net_data *net_data) {
|
||||
return (setgroupent_p(0, net_data));
|
||||
}
|
||||
#endif /* SETGRENT_VOID */
|
||||
|
||||
void
|
||||
endgrent_p(struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if ((net_data != NULL) && ((gr = net_data->gr) != NULL))
|
||||
(*gr->minimize)(gr);
|
||||
}
|
||||
|
||||
int
|
||||
getgrouplist_p(const char *name, gid_t basegid, gid_t *groups, int *ngroups,
|
||||
struct net_data *net_data) {
|
||||
struct irs_gr *gr;
|
||||
|
||||
if (!net_data || !(gr = net_data->gr)) {
|
||||
*ngroups = 0;
|
||||
return (-1);
|
||||
}
|
||||
return ((*gr->list)(gr, name, basegid, groups, ngroups));
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->gr) {
|
||||
net_data->gr = (*net_data->irs->gr_map)(net_data->irs);
|
||||
|
||||
if (!net_data->gr || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->gr->res_set)(net_data->gr, net_data->res,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
/*! \file */
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getgrent_r.c,v 1.7 2005/04/27 04:56:24 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
|
||||
static int getgrent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if (defined(POSIX_GETGRNAM_R) || defined(POSIX_GETGRGID_R)) && \
|
||||
defined(_POSIX_PTHREAD_SEMANTICS)
|
||||
/* turn off solaris remapping in <grp.h> */
|
||||
#define _UNIX95
|
||||
#undef _POSIX_PTHREAD_SEMANTICS
|
||||
#include <grp.h>
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#else
|
||||
#include <grp.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef GROUP_R_RETURN
|
||||
|
||||
static int
|
||||
copy_group(struct group *, struct group *, char *buf, int buflen);
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETGRNAM_R
|
||||
int
|
||||
__posix_getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, int buflen, struct group **result) {
|
||||
#else
|
||||
int
|
||||
getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, size_t buflen, struct group **result) {
|
||||
#endif
|
||||
struct group *ge = getgrnam(name);
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
*result = res ? NULL : gptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETGRNAM_R
|
||||
struct group *
|
||||
getgrnam_r(const char *name, struct group *gptr,
|
||||
char *buf, int buflen) {
|
||||
struct group *ge = getgrnam(name);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (NULL);
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? NULL : gptr);
|
||||
}
|
||||
#endif /* POSIX_GETGRNAM_R */
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETGRGID_R
|
||||
int
|
||||
__posix_getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, int buflen, struct group **result) {
|
||||
#else /* POSIX_GETGRGID_R */
|
||||
int
|
||||
getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, size_t buflen, struct group **result) {
|
||||
#endif /* POSIX_GETGRGID_R */
|
||||
struct group *ge = getgrgid(gid);
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
*result = res ? NULL : gptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETGRGID_R
|
||||
struct group *
|
||||
getgrgid_r(gid_t gid, struct group *gptr,
|
||||
char *buf, int buflen) {
|
||||
struct group *ge = getgrgid(gid);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? NULL : gptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
GROUP_R_RETURN
|
||||
getgrent_r(struct group *gptr, GROUP_R_ARGS) {
|
||||
struct group *ge = getgrent();
|
||||
int res;
|
||||
|
||||
if (ge == NULL) {
|
||||
return (GROUP_R_BAD);
|
||||
}
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? GROUP_R_BAD : GROUP_R_OK);
|
||||
}
|
||||
|
||||
GROUP_R_SET_RETURN
|
||||
setgrent_r(GROUP_R_ENT_ARGS) {
|
||||
|
||||
setgrent();
|
||||
#ifdef GROUP_R_SET_RESULT
|
||||
return (GROUP_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
GROUP_R_END_RETURN
|
||||
endgrent_r(GROUP_R_ENT_ARGS) {
|
||||
|
||||
endgrent();
|
||||
GROUP_R_END_RESULT(GROUP_R_OK);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/* XXX irs does not have a fgetgrent() */
|
||||
GROUP_R_RETURN
|
||||
fgetgrent_r(FILE *f, struct group *gptr, GROUP_R_ARGS) {
|
||||
struct group *ge = fgetgrent(f);
|
||||
int res;
|
||||
|
||||
if (ge == NULL)
|
||||
return (GROUP_R_BAD);
|
||||
|
||||
res = copy_group(ge, gptr, buf, buflen);
|
||||
return (res ? GROUP_R_BAD : GROUP_R_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_group(struct group *ge, struct group *gptr, char *buf, int buflen) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /*%< NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; ge->gr_mem[i]; i++, numptr++) {
|
||||
len += strlen(ge->gr_mem[i]) + 1;
|
||||
}
|
||||
len += strlen(ge->gr_name) + 1;
|
||||
len += strlen(ge->gr_passwd) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (ERANGE);
|
||||
}
|
||||
|
||||
/* copy group id */
|
||||
gptr->gr_gid = ge->gr_gid;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(ge->gr_name) + 1;
|
||||
strcpy(cp, ge->gr_name);
|
||||
gptr->gr_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy member list */
|
||||
gptr->gr_mem = (char **)ALIGN(buf);
|
||||
for (i = 0 ; ge->gr_mem[i]; i++) {
|
||||
n = strlen(ge->gr_mem[i]) + 1;
|
||||
strcpy(cp, ge->gr_mem[i]);
|
||||
gptr->gr_mem[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
gptr->gr_mem[i] = NULL;
|
||||
|
||||
/* copy password */
|
||||
n = strlen(ge->gr_passwd) + 1;
|
||||
strcpy(cp, ge->gr_passwd);
|
||||
gptr->gr_passwd = cp;
|
||||
cp += n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* GROUP_R_RETURN */
|
||||
static int getgrent_r_unknown_system = 0;
|
||||
#endif /* GROUP_R_RETURN */
|
||||
#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
|
||||
/*! \file */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: gethostent_r.c,v 1.9 2005/09/03 12:41:37 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int gethostent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef HOST_R_RETURN
|
||||
|
||||
static HOST_R_RETURN
|
||||
copy_hostent(struct hostent *, struct hostent *, HOST_R_COPY_ARGS);
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostbyname_r(const char *name, struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostbyname(name);
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_ERRNO
|
||||
HOST_R_ERRNO;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostbyaddr_r(const char *addr, int len, int type,
|
||||
struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostbyaddr(addr, len, type);
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_ERRNO
|
||||
HOST_R_ERRNO;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
HOST_R_RETURN
|
||||
gethostent_r(struct hostent *hptr, HOST_R_ARGS) {
|
||||
struct hostent *he = gethostent();
|
||||
#ifdef HOST_R_SETANSWER
|
||||
int n = 0;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_ERRNO
|
||||
HOST_R_ERRNO;
|
||||
#endif
|
||||
|
||||
#ifdef HOST_R_SETANSWER
|
||||
if (he == NULL || (n = copy_hostent(he, hptr, HOST_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = hptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (he == NULL)
|
||||
return (HOST_R_BAD);
|
||||
|
||||
return (copy_hostent(he, hptr, HOST_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_SET_RETURN
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
sethostent_r(int stay_open, HOST_R_ENT_ARGS)
|
||||
#else
|
||||
sethostent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
UNUSED(hdptr);
|
||||
#endif
|
||||
sethostent(stay_open);
|
||||
#ifdef HOST_R_SET_RESULT
|
||||
return (HOST_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
HOST_R_END_RETURN
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
endhostent_r(HOST_R_ENT_ARGS)
|
||||
#else
|
||||
endhostent_r(void)
|
||||
#endif
|
||||
{
|
||||
#ifdef HOST_R_ENT_ARGS
|
||||
UNUSED(hdptr);
|
||||
#endif
|
||||
endhostent();
|
||||
HOST_R_END_RESULT(HOST_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef HOSTENT_DATA
|
||||
static HOST_R_RETURN
|
||||
copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
char **ptr;
|
||||
int i, n;
|
||||
int nptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
nptr = 2; /*%< NULL ptrs */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; he->h_addr_list[i]; i++, nptr++) {
|
||||
len += he->h_length;
|
||||
}
|
||||
for (i = 0; he->h_aliases[i]; i++, nptr++) {
|
||||
len += strlen(he->h_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(he->h_name) + 1;
|
||||
len += nptr * sizeof(char*);
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (HOST_R_BAD);
|
||||
}
|
||||
|
||||
/* copy address size and type */
|
||||
hptr->h_addrtype = he->h_addrtype;
|
||||
n = hptr->h_length = he->h_length;
|
||||
|
||||
ptr = (char **)ALIGN(buf);
|
||||
cp = (char *)ALIGN(buf) + nptr * sizeof(char *);
|
||||
|
||||
/* copy address list */
|
||||
hptr->h_addr_list = ptr;
|
||||
for (i = 0; he->h_addr_list[i]; i++ , ptr++) {
|
||||
memcpy(cp, he->h_addr_list[i], n);
|
||||
hptr->h_addr_list[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_addr_list[i] = NULL;
|
||||
ptr++;
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(he->h_name) + 1;
|
||||
strcpy(cp, he->h_name);
|
||||
hptr->h_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
hptr->h_aliases = ptr;
|
||||
for (i = 0 ; he->h_aliases[i]; i++) {
|
||||
n = strlen(he->h_aliases[i]) + 1;
|
||||
strcpy(cp, he->h_aliases[i]);
|
||||
hptr->h_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
hptr->h_aliases[i] = NULL;
|
||||
|
||||
return (HOST_R_OK);
|
||||
}
|
||||
#else /* !HOSTENT_DATA */
|
||||
static int
|
||||
copy_hostent(struct hostent *he, struct hostent *hptr, HOST_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy address size and type */
|
||||
hptr->h_addrtype = he->h_addrtype;
|
||||
n = hptr->h_length = he->h_length;
|
||||
|
||||
/* copy up to first 35 addresses */
|
||||
i = 0;
|
||||
cp = hdptr->hostbuf;
|
||||
eob = hdptr->hostbuf + sizeof(hdptr->hostbuf);
|
||||
hptr->h_addr_list = hdptr->h_addr_ptrs;
|
||||
while (he->h_addr_list[i] && i < (_MAXADDRS)) {
|
||||
if (n < (eob - cp)) {
|
||||
memcpy(cp, he->h_addr_list[i], n);
|
||||
hptr->h_addr_list[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hptr->h_addr_list[i] = NULL;
|
||||
|
||||
/* copy official name */
|
||||
if ((n = strlen(he->h_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, he->h_name);
|
||||
hptr->h_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
hptr->h_aliases = hdptr->host_aliases;
|
||||
while (he->h_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(he->h_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, he->h_aliases[i]);
|
||||
hptr->h_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
hptr->h_aliases[i] = NULL;
|
||||
|
||||
return (HOST_R_OK);
|
||||
}
|
||||
#endif /* !HOSTENT_DATA */
|
||||
#else /* HOST_R_RETURN */
|
||||
static int gethostent_r_unknown_system = 0;
|
||||
#endif /* HOST_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
/*! \file */
|
||||
@@ -1,19 +1,8 @@
|
||||
/*
|
||||
* Issues to be discussed:
|
||||
* - Thread safe-ness must be checked
|
||||
*/
|
||||
|
||||
#if ( defined(__linux__) || defined(__linux) || defined(LINUX) )
|
||||
#ifndef IF_NAMESIZE
|
||||
# ifdef IFNAMSIZ
|
||||
# define IF_NAMESIZE IFNAMSIZ
|
||||
# else
|
||||
# define IF_NAMESIZE 16
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
/* $NetBSD: getnameinfo.c,v 1.53 2012/09/26 23:13:00 christos Exp $ */
|
||||
/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2000 Ben Harris.
|
||||
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -46,87 +35,222 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <port_before.h>
|
||||
/*
|
||||
* Issues to be discussed:
|
||||
* - Thread safe-ness must be checked
|
||||
* - RFC2553 says that we should raise error on short buffer. X/Open says
|
||||
* we need to truncate the result. We obey RFC2553 (and X/Open should be
|
||||
* modified). ipngwg rough consensus seems to follow RFC2553.
|
||||
* - What is "local" in NI_FQDN?
|
||||
* - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
|
||||
* - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
|
||||
* sin6_scope_id is filled - standardization status?
|
||||
* XXX breaks backward compat for code that expects no scopeid.
|
||||
* beware on merge.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getnameinfo.c,v 1.53 2012/09/26 23:13:00 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/un.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <port_after.h>
|
||||
#include "nsswitch.h"
|
||||
#include "servent.h"
|
||||
|
||||
/*%
|
||||
* Note that a_off will be dynamically adjusted so that to be consistent
|
||||
* with the definition of sockaddr_in{,6}.
|
||||
* The value presented below is just a guess.
|
||||
*/
|
||||
static struct afd {
|
||||
int a_af;
|
||||
int a_addrlen;
|
||||
size_t a_socklen;
|
||||
int a_off;
|
||||
static const struct afd {
|
||||
int a_af;
|
||||
socklen_t a_addrlen;
|
||||
socklen_t a_socklen;
|
||||
int a_off;
|
||||
} afdl [] = {
|
||||
/* first entry is linked last... */
|
||||
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
#ifdef INET6
|
||||
{PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
|
||||
offsetof(struct sockaddr_in6, sin6_addr)},
|
||||
#endif
|
||||
{PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
|
||||
offsetof(struct sockaddr_in, sin_addr)},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
struct sockinet {
|
||||
#ifdef HAVE_SA_LEN
|
||||
u_char si_len;
|
||||
#endif
|
||||
u_char si_family;
|
||||
u_short si_port;
|
||||
};
|
||||
|
||||
static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
|
||||
size_t, int));
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
|
||||
static int getnameinfo_inet(const struct sockaddr *, socklen_t, char *,
|
||||
socklen_t, char *, socklen_t, int);
|
||||
#ifdef INET6
|
||||
static int ip6_parsenumeric(const struct sockaddr *, const char *, char *,
|
||||
socklen_t, int);
|
||||
static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int);
|
||||
#endif
|
||||
static int getnameinfo_atalk(const struct sockaddr *, socklen_t, char *,
|
||||
socklen_t, char *, socklen_t, int);
|
||||
static int getnameinfo_local(const struct sockaddr *, socklen_t, char *,
|
||||
socklen_t, char *, socklen_t, int);
|
||||
|
||||
static int getnameinfo_link(const struct sockaddr *, socklen_t, char *,
|
||||
socklen_t, char *, socklen_t, int);
|
||||
static int hexname(const uint8_t *, size_t, char *, socklen_t);
|
||||
|
||||
/*
|
||||
+ * Top-level getnameinfo() code. Look at the address family, and pick an
|
||||
+ * appropriate function to call.
|
||||
+ */
|
||||
int
|
||||
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
const struct sockaddr *sa;
|
||||
socklen_t salen;
|
||||
char *host;
|
||||
socklen_t hostlen;
|
||||
char *serv;
|
||||
socklen_t servlen;
|
||||
int flags;
|
||||
getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, socklen_t hostlen,
|
||||
char *serv, socklen_t servlen,
|
||||
int flags)
|
||||
{
|
||||
struct afd *afd;
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_APPLETALK:
|
||||
return getnameinfo_atalk(sa, salen, host, hostlen,
|
||||
serv, servlen, flags);
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
return getnameinfo_inet(sa, salen, host, hostlen,
|
||||
serv, servlen, flags);
|
||||
case AF_LINK:
|
||||
return getnameinfo_link(sa, salen, host, hostlen,
|
||||
serv, servlen, flags);
|
||||
case AF_LOCAL:
|
||||
return getnameinfo_local(sa, salen, host, hostlen,
|
||||
serv, servlen, flags);
|
||||
default:
|
||||
return EAI_FAMILY;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getnameinfo_atalk():
|
||||
* Format an AppleTalk address into a printable format.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getnameinfo_atalk(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, socklen_t hostlen, char *serv, socklen_t servlen,
|
||||
int flags)
|
||||
{
|
||||
#if 0
|
||||
char numserv[8];
|
||||
int n, m=0;
|
||||
|
||||
const struct sockaddr_at *sat =
|
||||
(const struct sockaddr_at *)(const void *)sa;
|
||||
|
||||
if (serv != NULL && servlen > 0) {
|
||||
snprintf(numserv, sizeof(numserv), "%u", sat->sat_port);
|
||||
if (strlen(numserv) + 1 > servlen)
|
||||
return EAI_MEMORY;
|
||||
strlcpy(serv, numserv, servlen);
|
||||
}
|
||||
|
||||
n = snprintf(host, hostlen, "%u.%u",
|
||||
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
|
||||
|
||||
if (n < 0 || (socklen_t)(m+n) >= hostlen)
|
||||
goto errout;
|
||||
|
||||
m += n;
|
||||
|
||||
if (sat->sat_range.r_netrange.nr_phase) {
|
||||
n = snprintf(host+m, hostlen-m, " phase %u",
|
||||
sat->sat_range.r_netrange.nr_phase);
|
||||
|
||||
if (n < 0 || (socklen_t)(m+n) >= hostlen)
|
||||
goto errout;
|
||||
|
||||
m += n;
|
||||
}
|
||||
if (sat->sat_range.r_netrange.nr_firstnet) {
|
||||
n = snprintf(host+m, hostlen-m, " range %u - %u",
|
||||
ntohs(sat->sat_range.r_netrange.nr_firstnet),
|
||||
ntohs(sat->sat_range.r_netrange.nr_lastnet ));
|
||||
|
||||
if (n < 0 || (socklen_t)(m+n) >= hostlen)
|
||||
goto errout;
|
||||
|
||||
m += n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
if (host && hostlen>0)
|
||||
host[m] = '\0'; /* XXX ??? */
|
||||
|
||||
#endif
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
|
||||
/*
|
||||
* getnameinfo_local():
|
||||
* Format an local address into a printable format.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getnameinfo_local(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, socklen_t hostlen, char *serv, socklen_t servlen,
|
||||
int flags)
|
||||
{
|
||||
const struct sockaddr_un *sun =
|
||||
(const struct sockaddr_un *)(const void *)sa;
|
||||
|
||||
if (serv != NULL && servlen > 0)
|
||||
serv[0] = '\0';
|
||||
|
||||
if (host && hostlen > 0)
|
||||
strlcpy(host, sun->sun_path,
|
||||
MIN(sizeof(sun->sun_path) + 1, hostlen));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getnameinfo_inet():
|
||||
* Format an IPv4 or IPv6 sockaddr into a printable string.
|
||||
*/
|
||||
static int
|
||||
getnameinfo_inet(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, socklen_t hostlen,
|
||||
char *serv, socklen_t servlen,
|
||||
int flags)
|
||||
{
|
||||
const struct afd *afd;
|
||||
struct servent *sp;
|
||||
struct hostent *hp;
|
||||
u_short port;
|
||||
#ifdef HAVE_SA_LEN
|
||||
size_t len;
|
||||
#endif
|
||||
int family, i;
|
||||
const char *addr;
|
||||
char *p;
|
||||
uint32_t v4a;
|
||||
char numserv[512];
|
||||
char numaddr[512];
|
||||
const struct sockaddr_in6 *sin6;
|
||||
|
||||
/* sa is checked below */
|
||||
/* host may be NULL */
|
||||
/* serv may be NULL */
|
||||
|
||||
if (sa == NULL)
|
||||
return EAI_FAIL;
|
||||
|
||||
#ifdef HAVE_SA_LEN
|
||||
len = sa->sa_len;
|
||||
if (len != salen) return EAI_FAIL;
|
||||
#endif
|
||||
|
||||
family = sa->sa_family;
|
||||
for (i = 0; afdl[i].a_af; i++)
|
||||
@@ -137,38 +261,62 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
return EAI_FAMILY;
|
||||
|
||||
found:
|
||||
if (salen != afd->a_socklen) return EAI_FAIL;
|
||||
if (salen != afd->a_socklen)
|
||||
return EAI_FAIL;
|
||||
|
||||
port = ((const struct sockinet *)sa)->si_port; /*%< network byte order */
|
||||
addr = (const char *)sa + afd->a_off;
|
||||
/* network byte order */
|
||||
port = ((const struct sockinet *)(const void *)sa)->si_port;
|
||||
addr = (const char *)(const void *)sa + afd->a_off;
|
||||
|
||||
if (serv == NULL || servlen == 0U) {
|
||||
if (serv == NULL || servlen == 0) {
|
||||
/*
|
||||
* rfc2553bis says that serv == NULL or servlen == 0 means that
|
||||
* the caller does not want the result.
|
||||
*/
|
||||
} else if (flags & NI_NUMERICSERV) {
|
||||
sprintf(numserv, "%d", ntohs(port));
|
||||
if (strlen(numserv) > servlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(serv, numserv);
|
||||
* do nothing in this case.
|
||||
* in case you are wondering if "&&" is more correct than
|
||||
* "||" here: rfc2553bis-03 says that serv == NULL OR
|
||||
* servlen == 0 means that the caller does not want the result.
|
||||
*/
|
||||
} else {
|
||||
sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp");
|
||||
struct servent_data svd;
|
||||
struct servent sv;
|
||||
|
||||
if (flags & NI_NUMERICSERV)
|
||||
sp = NULL;
|
||||
else {
|
||||
(void)memset(&svd, 0, sizeof(svd));
|
||||
sp = getservbyport_r(port,
|
||||
(flags & NI_DGRAM) ? "udp" : "tcp", &sv, &svd);
|
||||
}
|
||||
if (sp) {
|
||||
if (strlen(sp->s_name) + 1 > servlen)
|
||||
if (strlen(sp->s_name) + 1 > servlen) {
|
||||
endservent_r(&svd);
|
||||
return EAI_MEMORY;
|
||||
strcpy(serv, sp->s_name);
|
||||
} else
|
||||
return EAI_NONAME;
|
||||
}
|
||||
strlcpy(serv, sp->s_name, servlen);
|
||||
endservent_r(&svd);
|
||||
} else {
|
||||
snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
|
||||
if (strlen(numserv) + 1 > servlen)
|
||||
return EAI_MEMORY;
|
||||
strlcpy(serv, numserv, servlen);
|
||||
}
|
||||
}
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
if (ntohl(*(const u_int32_t *)addr) >> IN_CLASSA_NSHIFT == 0)
|
||||
v4a = (uint32_t)
|
||||
ntohl(((const struct sockaddr_in *)
|
||||
(const void *)sa)->sin_addr.s_addr);
|
||||
if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
|
||||
flags |= NI_NUMERICHOST;
|
||||
v4a >>= IN_CLASSA_NSHIFT;
|
||||
if (v4a == 0)
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
sin6 = (const struct sockaddr_in6 *)sa;
|
||||
{
|
||||
const struct sockaddr_in6 *sin6;
|
||||
sin6 = (const struct sockaddr_in6 *)(const void *)sa;
|
||||
switch (sin6->sin6_addr.s6_addr[0]) {
|
||||
case 0x00:
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
|
||||
@@ -179,37 +327,78 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
default:
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
||||
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
|
||||
flags |= NI_NUMERICHOST;
|
||||
}
|
||||
else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
|
||||
flags |= NI_NUMERICHOST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (host == NULL || hostlen == 0U) {
|
||||
if (host == NULL || hostlen == 0) {
|
||||
/*
|
||||
* rfc2553bis says that host == NULL or hostlen == 0 means that
|
||||
* the caller does not want the result.
|
||||
* do nothing in this case.
|
||||
* in case you are wondering if "&&" is more correct than
|
||||
* "||" here: rfc2553bis-03 says that host == NULL or
|
||||
* hostlen == 0 means that the caller does not want the result.
|
||||
*/
|
||||
} else if (flags & NI_NUMERICHOST) {
|
||||
goto numeric;
|
||||
size_t numaddrlen;
|
||||
|
||||
/* NUMERICHOST and NAMEREQD conflicts with each other */
|
||||
if (flags & NI_NAMEREQD)
|
||||
return EAI_NONAME;
|
||||
|
||||
switch(afd->a_af) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((error = ip6_parsenumeric(sa, addr, host,
|
||||
hostlen, flags)) != 0)
|
||||
return(error);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
if (inet_ntop(afd->a_af, addr, numaddr,
|
||||
(socklen_t)sizeof(numaddr)) == NULL)
|
||||
return EAI_SYSTEM;
|
||||
numaddrlen = strlen(numaddr);
|
||||
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
|
||||
return EAI_MEMORY;
|
||||
strlcpy(host, numaddr, hostlen);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
|
||||
|
||||
if (hp) {
|
||||
#if 0
|
||||
/*
|
||||
* commented out, since "for local host" is not
|
||||
* implemented here - see RFC2553 p30
|
||||
*/
|
||||
if (flags & NI_NOFQDN) {
|
||||
char *p;
|
||||
p = strchr(hp->h_name, '.');
|
||||
if (p) *p = '\0';
|
||||
if (p)
|
||||
*p = '\0';
|
||||
}
|
||||
if (strlen(hp->h_name) + 1 > hostlen)
|
||||
#endif
|
||||
if (strlen(hp->h_name) + 1 > hostlen) {
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, hp->h_name);
|
||||
}
|
||||
strlcpy(host, hp->h_name, hostlen);
|
||||
} else {
|
||||
if (flags & NI_NAMEREQD)
|
||||
return EAI_NONAME;
|
||||
numeric:
|
||||
switch(afd->a_af) {
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
{
|
||||
int error;
|
||||
@@ -220,115 +409,210 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
|
||||
return(error);
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
default:
|
||||
if (inet_ntop(afd->a_af, addr, numaddr,
|
||||
sizeof(numaddr)) == NULL)
|
||||
return EAI_NONAME;
|
||||
if (strlen(numaddr) + 1 > hostlen)
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
if (inet_ntop(afd->a_af, addr, host,
|
||||
hostlen) == NULL)
|
||||
return EAI_SYSTEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
static int
|
||||
ip6_parsenumeric(const struct sockaddr *sa, const char *addr, char *host,
|
||||
size_t hostlen, int flags)
|
||||
socklen_t hostlen, int flags)
|
||||
{
|
||||
size_t numaddrlen;
|
||||
char numaddr[512];
|
||||
|
||||
#ifndef HAVE_SIN6_SCOPE_ID
|
||||
UNUSED(sa);
|
||||
UNUSED(flags);
|
||||
#endif
|
||||
_DIAGASSERT(sa != NULL);
|
||||
_DIAGASSERT(addr != NULL);
|
||||
_DIAGASSERT(host != NULL);
|
||||
|
||||
if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr))
|
||||
if (inet_ntop(AF_INET6, addr, numaddr, (socklen_t)sizeof(numaddr))
|
||||
== NULL)
|
||||
return EAI_SYSTEM;
|
||||
|
||||
numaddrlen = strlen(numaddr);
|
||||
if (numaddrlen + 1 > hostlen) /*%< don't forget terminator */
|
||||
return EAI_MEMORY;
|
||||
strcpy(host, numaddr);
|
||||
if (numaddrlen + 1 > hostlen) /* don't forget terminator */
|
||||
return EAI_OVERFLOW;
|
||||
strlcpy(host, numaddr, hostlen);
|
||||
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
|
||||
char scopebuf[MAXHOSTNAMELEN]; /*%< XXX */
|
||||
int scopelen;
|
||||
if (((const struct sockaddr_in6 *)(const void *)sa)->sin6_scope_id) {
|
||||
char zonebuf[MAXHOSTNAMELEN];
|
||||
int zonelen;
|
||||
|
||||
/* ip6_sa2str never fails */
|
||||
scopelen = ip6_sa2str((const struct sockaddr_in6 *)sa,
|
||||
scopebuf, sizeof(scopebuf), flags);
|
||||
|
||||
if (scopelen + 1 + numaddrlen + 1 > hostlen)
|
||||
return EAI_MEMORY;
|
||||
|
||||
/* construct <numeric-addr><delim><scopeid> */
|
||||
memcpy(host + numaddrlen + 1, scopebuf,
|
||||
scopelen);
|
||||
zonelen = ip6_sa2str(
|
||||
(const struct sockaddr_in6 *)(const void *)sa,
|
||||
zonebuf, sizeof(zonebuf), flags);
|
||||
if (zonelen < 0)
|
||||
return EAI_OVERFLOW;
|
||||
if ((size_t) zonelen + 1 + numaddrlen + 1 > hostlen)
|
||||
return EAI_OVERFLOW;
|
||||
/* construct <numeric-addr><delim><zoneid> */
|
||||
memcpy(host + numaddrlen + 1, zonebuf,
|
||||
(size_t)zonelen);
|
||||
host[numaddrlen] = SCOPE_DELIMITER;
|
||||
host[numaddrlen + 1 + scopelen] = '\0';
|
||||
host[numaddrlen + 1 + zonelen] = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIN6_SCOPE_ID
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf,
|
||||
size_t bufsiz, int flags)
|
||||
ip6_sa2str(const struct sockaddr_in6 *sa6, char *buf, size_t bufsiz, int flags)
|
||||
{
|
||||
#ifdef USE_IFNAMELINKID
|
||||
unsigned int ifindex = (unsigned int)sa6->sin6_scope_id;
|
||||
const struct in6_addr *a6 = &sa6->sin6_addr;
|
||||
#endif
|
||||
char tmp[64];
|
||||
unsigned int ifindex;
|
||||
const struct in6_addr *a6;
|
||||
int n;
|
||||
|
||||
_DIAGASSERT(sa6 != NULL);
|
||||
_DIAGASSERT(buf != NULL);
|
||||
|
||||
ifindex = (unsigned int)sa6->sin6_scope_id;
|
||||
a6 = &sa6->sin6_addr;
|
||||
|
||||
#ifdef NI_NUMERICSCOPE
|
||||
if (flags & NI_NUMERICSCOPE) {
|
||||
sprintf(tmp, "%u", sa6->sin6_scope_id);
|
||||
if (bufsiz != 0U) {
|
||||
strncpy(buf, tmp, bufsiz - 1);
|
||||
buf[bufsiz - 1] = '\0';
|
||||
}
|
||||
return(strlen(tmp));
|
||||
if ((flags & NI_NUMERICSCOPE) != 0) {
|
||||
n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
|
||||
if (n < 0 || (size_t)n >= bufsiz)
|
||||
return -1;
|
||||
else
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_IFNAMELINKID
|
||||
/*
|
||||
* For a link-local address, convert the index to an interface
|
||||
* name, assuming a one-to-one mapping between links and interfaces.
|
||||
* Note, however, that this assumption is stronger than the
|
||||
* specification of the scoped address architecture; the
|
||||
* specficication says that more than one interfaces can belong to
|
||||
* a single link.
|
||||
*/
|
||||
|
||||
/* if_indextoname() does not take buffer size. not a good api... */
|
||||
if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6)) &&
|
||||
bufsiz >= IF_NAMESIZE) {
|
||||
char *p = if_indextoname(ifindex, buf);
|
||||
if (p) {
|
||||
return(strlen(p));
|
||||
return (int)strlen(p);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* last resort */
|
||||
sprintf(tmp, "%u", sa6->sin6_scope_id);
|
||||
if (bufsiz != 0U) {
|
||||
strncpy(buf, tmp, bufsiz - 1);
|
||||
buf[bufsiz - 1] = '\0';
|
||||
}
|
||||
return(strlen(tmp));
|
||||
n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
|
||||
if (n < 0 || (size_t) n >= bufsiz)
|
||||
return -1;
|
||||
else
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
#endif /* INET6 */
|
||||
|
||||
/*! \file */
|
||||
|
||||
/*
|
||||
* getnameinfo_link():
|
||||
* Format a link-layer address into a printable format, paying attention to
|
||||
* the interface type.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
getnameinfo_link(const struct sockaddr *sa, socklen_t salen,
|
||||
char *host, socklen_t hostlen, char *serv, socklen_t servlen,
|
||||
int flags)
|
||||
{
|
||||
const struct sockaddr_dl *sdl =
|
||||
(const struct sockaddr_dl *)(const void *)sa;
|
||||
int n;
|
||||
|
||||
if (serv != NULL && servlen > 0)
|
||||
*serv = '\0';
|
||||
|
||||
if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && sdl->sdl_slen == 0) {
|
||||
n = snprintf(host, hostlen, "link#%u", sdl->sdl_index);
|
||||
if (n < 0 || (socklen_t) n > hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (sdl->sdl_type) {
|
||||
#ifdef IFT_ECONET
|
||||
case IFT_ECONET:
|
||||
if (sdl->sdl_alen < 2)
|
||||
return EAI_FAMILY;
|
||||
if (LLADDR(sdl)[1] == 0)
|
||||
n = snprintf(host, hostlen, "%u", LLADDR(sdl)[0]);
|
||||
else
|
||||
n = snprintf(host, hostlen, "%u.%u",
|
||||
LLADDR(sdl)[1], LLADDR(sdl)[0]);
|
||||
if (n < 0 || (socklen_t) n >= hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
} else
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef IFT_IEEE1394
|
||||
case IFT_IEEE1394:
|
||||
{
|
||||
const struct ieee1394_hwaddr *iha;
|
||||
if (sdl->sdl_alen < sizeof(iha->iha_uid))
|
||||
return EAI_FAMILY;
|
||||
iha =
|
||||
(const struct ieee1394_hwaddr *)(const void *)LLADDR(sdl);
|
||||
return hexname(iha->iha_uid, sizeof(iha->iha_uid),
|
||||
host, hostlen);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* The following have zero-length addresses.
|
||||
* IFT_ATM (net/if_atmsubr.c)
|
||||
* IFT_FAITH (net/if_faith.c)
|
||||
* IFT_GIF (net/if_gif.c)
|
||||
* IFT_LOOP (net/if_loop.c)
|
||||
* IFT_PPP (net/if_ppp.c, net/if_spppsubr.c)
|
||||
* IFT_SLIP (net/if_sl.c, net/if_strip.c)
|
||||
* IFT_STF (net/if_stf.c)
|
||||
* IFT_L2VLAN (net/if_vlan.c)
|
||||
* IFT_PROPVIRTUAL (net/if_bridge.h>
|
||||
*/
|
||||
/*
|
||||
* The following use IPv4 addresses as link-layer addresses:
|
||||
* IFT_OTHER (net/if_gre.c)
|
||||
*/
|
||||
#ifdef IFT_ARCNET
|
||||
case IFT_ARCNET: /* default below is believed correct for all these. */
|
||||
#endif
|
||||
case IFT_ETHER:
|
||||
#ifdef IFT_FDDI
|
||||
case IFT_FDDI:
|
||||
#endif
|
||||
#ifdef IFT_HIPPI
|
||||
case IFT_HIPPI:
|
||||
#endif
|
||||
#ifdef IFT_ISO88025
|
||||
case IFT_ISO88025:
|
||||
#endif
|
||||
default:
|
||||
return hexname((const uint8_t *)LLADDR(sdl),
|
||||
(size_t)sdl->sdl_alen, host, hostlen);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hexname(const uint8_t *cp, size_t len, char *host, socklen_t hostlen)
|
||||
{
|
||||
int n;
|
||||
size_t i;
|
||||
char *outp = host;
|
||||
|
||||
*outp = '\0';
|
||||
for (i = 0; i < len; i++) {
|
||||
n = snprintf(outp, hostlen, "%s%02x",
|
||||
i ? ":" : "", cp[i]);
|
||||
if (n < 0 || (socklen_t) n >= hostlen) {
|
||||
*host = '\0';
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
outp += n;
|
||||
hostlen -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,345 +1,167 @@
|
||||
/* $NetBSD: getnetent.c,v 1.21 2012/03/20 17:44:18 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* from getnetent.c 1.1 (Coimbra) 93/06/02
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getnetent.c,v 1.7 2005/04/27 04:56:25 sra Exp $";
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: getnetent.c,v 1.21 2012/03/20 17:44:18 matt Exp $");
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct netent netent;
|
||||
char * aliases[1];
|
||||
char name[MAXDNAME + 1];
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
static struct netent *nw_to_net(struct nwent *, struct net_data *);
|
||||
static void freepvt(struct net_data *);
|
||||
static struct netent *fakeaddr(const char *, int af, struct net_data *);
|
||||
|
||||
/* Portability */
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
# define INADDR_NONE 0xffffffff
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(endnetent,_endnetent)
|
||||
__weak_alias(getnetent,_getnetent)
|
||||
__weak_alias(setnetent,_setnetent)
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
#define MAXALIASES 35
|
||||
|
||||
struct netent *
|
||||
getnetent() {
|
||||
struct net_data *net_data = init();
|
||||
static FILE *netf;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct netent net;
|
||||
static char *net_aliases[MAXALIASES];
|
||||
int _net_stayopen;
|
||||
|
||||
return (getnetent_p(net_data));
|
||||
}
|
||||
static void __setnetent(int);
|
||||
static void __endnetent(void);
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
void
|
||||
setnetent(int stayopen)
|
||||
{
|
||||
|
||||
return (getnetbyname_p(name, net_data));
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(unsigned long net, int type) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getnetbyaddr_p(net, type, net_data));
|
||||
sethostent(stayopen);
|
||||
__setnetent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
endnetent(void)
|
||||
{
|
||||
|
||||
setnetent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
endnetent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endnetent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct netent *
|
||||
getnetent_p(struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
net_data->nww_last = (*nw->next)(nw);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
struct netent *np;
|
||||
char **nap;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
if (net_data->nw_stayopen && net_data->nw_last) {
|
||||
if (!strcmp(net_data->nw_last->n_name, name))
|
||||
return (net_data->nw_last);
|
||||
for (nap = net_data->nw_last->n_aliases; nap && *nap; nap++)
|
||||
if (!strcmp(name, *nap))
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
if ((np = fakeaddr(name, AF_INET, net_data)) != NULL)
|
||||
return (np);
|
||||
net_data->nww_last = (*nw->byname)(nw, name, AF_INET);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
if (!net_data->nw_stayopen)
|
||||
endnetent();
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr_p(unsigned long net, int type, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
u_char addr[4];
|
||||
int bits;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return (NULL);
|
||||
if (net_data->nw_stayopen && net_data->nw_last)
|
||||
if (type == net_data->nw_last->n_addrtype &&
|
||||
net == net_data->nw_last->n_net)
|
||||
return (net_data->nw_last);
|
||||
|
||||
/* cannonize net(host order) */
|
||||
if (net < 256UL) {
|
||||
net <<= 24;
|
||||
bits = 8;
|
||||
} else if (net < 65536UL) {
|
||||
net <<= 16;
|
||||
bits = 16;
|
||||
} else if (net < 16777216UL) {
|
||||
net <<= 8;
|
||||
bits = 24;
|
||||
} else
|
||||
bits = 32;
|
||||
|
||||
/* convert to net order */
|
||||
addr[0] = (0xFF000000 & net) >> 24;
|
||||
addr[1] = (0x00FF0000 & net) >> 16;
|
||||
addr[2] = (0x0000FF00 & net) >> 8;
|
||||
addr[3] = (0x000000FF & net);
|
||||
|
||||
/* reduce bits to as close to natural number as possible */
|
||||
if ((bits == 32) && (addr[0] < 224) && (addr[3] == 0)) {
|
||||
if ((addr[0] < 192) && (addr[2] == 0)) {
|
||||
if ((addr[0] < 128) && (addr[1] == 0))
|
||||
bits = 8;
|
||||
else
|
||||
bits = 16;
|
||||
} else {
|
||||
bits = 24;
|
||||
}
|
||||
}
|
||||
|
||||
net_data->nww_last = (*nw->byaddr)(nw, addr, bits, AF_INET);
|
||||
net_data->nw_last = nw_to_net(net_data->nww_last, net_data);
|
||||
if (!net_data->nw_stayopen)
|
||||
endnetent();
|
||||
return (net_data->nw_last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
setnetent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if (!net_data || !(nw = net_data->nw))
|
||||
return;
|
||||
freepvt(net_data);
|
||||
(*nw->rewind)(nw);
|
||||
net_data->nw_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent_p(struct net_data *net_data) {
|
||||
struct irs_nw *nw;
|
||||
|
||||
if ((net_data != NULL) && ((nw = net_data->nw) != NULL))
|
||||
(*nw->minimize)(nw);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->nw) {
|
||||
net_data->nw = (*net_data->irs->nw_map)(net_data->irs);
|
||||
|
||||
if (!net_data->nw || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->nw->res_set)(net_data->nw, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
endhostent();
|
||||
__endnetent();
|
||||
}
|
||||
|
||||
static void
|
||||
freepvt(struct net_data *net_data) {
|
||||
if (net_data->nw_data) {
|
||||
free(net_data->nw_data);
|
||||
net_data->nw_data = NULL;
|
||||
}
|
||||
__setnetent(int f)
|
||||
{
|
||||
|
||||
if (netf == NULL)
|
||||
netf = fopen(_PATH_NETWORKS, "re");
|
||||
else
|
||||
rewind(netf);
|
||||
_net_stayopen |= f;
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
fakeaddr(const char *name, int af, struct net_data *net_data) {
|
||||
struct pvt *pvt;
|
||||
const char *cp;
|
||||
u_long tmp;
|
||||
static void
|
||||
__endnetent(void)
|
||||
{
|
||||
|
||||
if (af != AF_INET) {
|
||||
/* XXX should support IPv6 some day */
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
if (netf) {
|
||||
fclose(netf);
|
||||
netf = NULL;
|
||||
}
|
||||
if (!isascii((unsigned char)(name[0])) ||
|
||||
!isdigit((unsigned char)(name[0])))
|
||||
return (NULL);
|
||||
for (cp = name; *cp; ++cp)
|
||||
if (!isascii(*cp) || (!isdigit((unsigned char)*cp) && *cp != '.'))
|
||||
return (NULL);
|
||||
if (*--cp == '.')
|
||||
return (NULL);
|
||||
|
||||
/* All-numeric, no dot at the end. */
|
||||
|
||||
tmp = inet_network(name);
|
||||
if (tmp == INADDR_NONE) {
|
||||
RES_SET_H_ERRNO(net_data->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Valid network number specified.
|
||||
* Fake up a netent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
freepvt(net_data);
|
||||
net_data->nw_data = malloc(sizeof (struct pvt));
|
||||
if (!net_data->nw_data) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
pvt = net_data->nw_data;
|
||||
|
||||
strncpy(pvt->name, name, MAXDNAME);
|
||||
pvt->name[MAXDNAME] = '\0';
|
||||
pvt->netent.n_name = pvt->name;
|
||||
pvt->netent.n_addrtype = AF_INET;
|
||||
pvt->netent.n_aliases = pvt->aliases;
|
||||
pvt->aliases[0] = NULL;
|
||||
pvt->netent.n_net = tmp;
|
||||
|
||||
return (&pvt->netent);
|
||||
_net_stayopen = 0;
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
nw_to_net(struct nwent *nwent, struct net_data *net_data) {
|
||||
struct pvt *pvt;
|
||||
u_long addr = 0;
|
||||
int i;
|
||||
int msbyte;
|
||||
struct netent *
|
||||
getnetent(void)
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (!nwent || nwent->n_addrtype != AF_INET)
|
||||
if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "re")) == NULL)
|
||||
return (NULL);
|
||||
freepvt(net_data);
|
||||
net_data->nw_data = malloc(sizeof (struct pvt));
|
||||
if (!net_data->nw_data) {
|
||||
errno = ENOMEM;
|
||||
RES_SET_H_ERRNO(net_data->res, NETDB_INTERNAL);
|
||||
#if (defined(__sparc__) && defined(_LP64)) || \
|
||||
defined(__alpha__) || \
|
||||
(defined(__i386__) && defined(_LP64)) || \
|
||||
(defined(__sh__) && defined(_LP64))
|
||||
net.__n_pad0 = 0;
|
||||
#endif
|
||||
again:
|
||||
p = fgets(line, (int)sizeof line, netf);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
net.n_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
net.n_net = inet_network(cp);
|
||||
net.n_addrtype = AF_INET;
|
||||
q = net.n_aliases = net_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &net_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
pvt = net_data->nw_data;
|
||||
pvt->netent.n_name = nwent->n_name;
|
||||
pvt->netent.n_aliases = nwent->n_aliases;
|
||||
pvt->netent.n_addrtype = nwent->n_addrtype;
|
||||
|
||||
/*%
|
||||
* What this code does: Converts net addresses from network to host form.
|
||||
*
|
||||
* msbyte: the index of the most significant byte in the n_addr array.
|
||||
*
|
||||
* Shift bytes in significant order into addr. When all signicant
|
||||
* bytes are in, zero out bits in the LSB that are not part of the network.
|
||||
*/
|
||||
msbyte = nwent->n_length / 8 +
|
||||
((nwent->n_length % 8) != 0 ? 1 : 0) - 1;
|
||||
for (i = 0; i <= msbyte; i++)
|
||||
addr = (addr << 8) | ((unsigned char *)nwent->n_addr)[i];
|
||||
i = (32 - nwent->n_length) % 8;
|
||||
if (i != 0)
|
||||
addr &= ~((1 << (i + 1)) - 1);
|
||||
pvt->netent.n_net = addr;
|
||||
return (&pvt->netent);
|
||||
*q = NULL;
|
||||
return (&net);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetent_r.c,v 1.6 2005/09/03 12:41:38 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getnetent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef NET_R_RETURN
|
||||
|
||||
static NET_R_RETURN
|
||||
copy_netent(struct netent *, struct netent *, NET_R_COPY_ARGS);
|
||||
|
||||
NET_R_RETURN
|
||||
getnetbyname_r(const char *name, struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetbyname(name);
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef GETNETBYADDR_ADDR_T
|
||||
#define GETNETBYADDR_ADDR_T long
|
||||
#endif
|
||||
NET_R_RETURN
|
||||
getnetbyaddr_r(GETNETBYADDR_ADDR_T addr, int type, struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetbyaddr(addr, type);
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
NET_R_RETURN
|
||||
getnetent_r(struct netent *nptr, NET_R_ARGS) {
|
||||
struct netent *ne = getnetent();
|
||||
#ifdef NET_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (ne == NULL || (n = copy_netent(ne, nptr, NET_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = ne;
|
||||
if (ne == NULL)
|
||||
*h_errnop = h_errno;
|
||||
return (n);
|
||||
#else
|
||||
|
||||
if (ne == NULL)
|
||||
return (NET_R_BAD);
|
||||
|
||||
return (copy_netent(ne, nptr, NET_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
NET_R_SET_RETURN
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
setnetent_r(int stay_open, NET_R_ENT_ARGS)
|
||||
#else
|
||||
setnetent_r(int stay_open)
|
||||
#endif
|
||||
{
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
UNUSED(ndptr);
|
||||
#endif
|
||||
setnetent(stay_open);
|
||||
#ifdef NET_R_SET_RESULT
|
||||
return (NET_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
NET_R_END_RETURN
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
endnetent_r(NET_R_ENT_ARGS)
|
||||
#else
|
||||
endnetent_r()
|
||||
#endif
|
||||
{
|
||||
#ifdef NET_R_ENT_ARGS
|
||||
UNUSED(ndptr);
|
||||
#endif
|
||||
endnetent();
|
||||
NET_R_END_RESULT(NET_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef NETENT_DATA
|
||||
static NET_R_RETURN
|
||||
copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /*%< NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; ne->n_aliases[i]; i++, numptr++) {
|
||||
len += strlen(ne->n_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(ne->n_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (NET_R_BAD);
|
||||
}
|
||||
|
||||
/* copy net value and type */
|
||||
nptr->n_addrtype = ne->n_addrtype;
|
||||
nptr->n_net = ne->n_net;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(ne->n_name) + 1;
|
||||
strcpy(cp, ne->n_name);
|
||||
nptr->n_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
nptr->n_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; ne->n_aliases[i]; i++) {
|
||||
n = strlen(ne->n_aliases[i]) + 1;
|
||||
strcpy(cp, ne->n_aliases[i]);
|
||||
nptr->n_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
nptr->n_aliases[i] = NULL;
|
||||
|
||||
return (NET_R_OK);
|
||||
}
|
||||
#else /* !NETENT_DATA */
|
||||
static int
|
||||
copy_netent(struct netent *ne, struct netent *nptr, NET_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy net value and type */
|
||||
nptr->n_addrtype = ne->n_addrtype;
|
||||
nptr->n_net = ne->n_net;
|
||||
|
||||
/* copy official name */
|
||||
cp = ndptr->line;
|
||||
eob = ndptr->line + sizeof(ndptr->line);
|
||||
if ((n = strlen(ne->n_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, ne->n_name);
|
||||
nptr->n_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
nptr->n_aliases = ndptr->net_aliases;
|
||||
while (ne->n_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(ne->n_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, ne->n_aliases[i]);
|
||||
nptr->n_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
nptr->n_aliases[i] = NULL;
|
||||
|
||||
return (NET_R_OK);
|
||||
}
|
||||
#endif /* !NETENT_DATA */
|
||||
#else /* NET_R_RETURN */
|
||||
static int getnetent_r_unknown_system = 0;
|
||||
#endif /* NET_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
/*! \file */
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 1996-1999, 2001, 2003 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetgrent.c,v 1.6 2008/11/14 02:36:51 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
#ifndef SETNETGRENT_ARGS
|
||||
#define SETNETGRENT_ARGS const char *netgroup
|
||||
#endif
|
||||
void
|
||||
setnetgrent(SETNETGRENT_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setnetgrent_p(netgroup, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endnetgrent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endnetgrent_p(net_data);
|
||||
}
|
||||
|
||||
#ifndef INNETGR_ARGS
|
||||
#define INNETGR_ARGS const char *netgroup, const char *host, \
|
||||
const char *user, const char *domain
|
||||
#endif
|
||||
int
|
||||
innetgr(INNETGR_ARGS) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (innetgr_p(netgroup, host, user, domain, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
getnetgrent(NGR_R_CONST char **host, NGR_R_CONST char **user,
|
||||
NGR_R_CONST char **domain)
|
||||
{
|
||||
struct net_data *net_data = init();
|
||||
const char *ch, *cu, *cd;
|
||||
int ret;
|
||||
|
||||
ret = getnetgrent_p(&ch, &cu, &cd, net_data);
|
||||
if (ret != 1)
|
||||
return (ret);
|
||||
|
||||
DE_CONST(ch, *host);
|
||||
DE_CONST(cu, *user);
|
||||
DE_CONST(cd, *domain);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
void
|
||||
setnetgrent_p(const char *netgroup, struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if ((net_data != NULL) && ((ng = net_data->ng) != NULL))
|
||||
(*ng->rewind)(ng, netgroup);
|
||||
}
|
||||
|
||||
void
|
||||
endnetgrent_p(struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data)
|
||||
return;
|
||||
if ((ng = net_data->ng) != NULL)
|
||||
(*ng->close)(ng);
|
||||
net_data->ng = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
innetgr_p(const char *netgroup, const char *host,
|
||||
const char *user, const char *domain,
|
||||
struct net_data *net_data) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data || !(ng = net_data->ng))
|
||||
return (0);
|
||||
return ((*ng->test)(ng, netgroup, host, user, domain));
|
||||
}
|
||||
|
||||
int
|
||||
getnetgrent_p(const char **host, const char **user, const char **domain,
|
||||
struct net_data *net_data ) {
|
||||
struct irs_ng *ng;
|
||||
|
||||
if (!net_data || !(ng = net_data->ng))
|
||||
return (0);
|
||||
return ((*ng->next)(ng, host, user, domain));
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init(void) {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->ng) {
|
||||
net_data->ng = (*net_data->irs->ng_map)(net_data->irs);
|
||||
if (!net_data->ng) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 1998, 1999, 2001, 2003 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getnetgrent_r.c,v 1.14 2008/11/14 02:36:51 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getnetgrent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef NGR_R_RETURN
|
||||
#ifndef NGR_R_PRIVATE
|
||||
#define NGR_R_PRIVATE 0
|
||||
#endif
|
||||
|
||||
static NGR_R_RETURN
|
||||
copy_protoent(NGR_R_CONST char **, NGR_R_CONST char **, NGR_R_CONST char **,
|
||||
const char *, const char *, const char *, NGR_R_COPY_ARGS);
|
||||
|
||||
NGR_R_RETURN
|
||||
innetgr_r(const char *netgroup, const char *host, const char *user,
|
||||
const char *domain) {
|
||||
char *ng, *ho, *us, *dom;
|
||||
|
||||
DE_CONST(netgroup, ng);
|
||||
DE_CONST(host, ho);
|
||||
DE_CONST(user, us);
|
||||
DE_CONST(domain, dom);
|
||||
|
||||
return (innetgr(ng, ho, us, dom));
|
||||
}
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
NGR_R_RETURN
|
||||
getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
|
||||
NGR_R_CONST char **domainp, NGR_R_ARGS)
|
||||
{
|
||||
NGR_R_CONST char *mp, *up, *dp;
|
||||
int res = getnetgrent(&mp, &up, &dp);
|
||||
|
||||
if (res != 1)
|
||||
return (res);
|
||||
|
||||
return (copy_protoent(machinep, userp, domainp,
|
||||
mp, up, dp, NGR_R_COPY));
|
||||
}
|
||||
|
||||
#if NGR_R_PRIVATE == 2
|
||||
struct private {
|
||||
char *buf;
|
||||
};
|
||||
|
||||
#endif
|
||||
NGR_R_SET_RETURN
|
||||
#ifdef NGR_R_SET_ARGS
|
||||
setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS)
|
||||
#else
|
||||
setnetgrent_r(NGR_R_SET_CONST char *netgroup)
|
||||
#endif
|
||||
{
|
||||
#if NGR_R_PRIVATE == 2
|
||||
struct private *p;
|
||||
#endif
|
||||
char *tmp;
|
||||
#if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
|
||||
UNUSED(buf);
|
||||
UNUSED(buflen);
|
||||
#endif
|
||||
|
||||
DE_CONST(netgroup, tmp);
|
||||
setnetgrent(tmp);
|
||||
|
||||
#if NGR_R_PRIVATE == 1
|
||||
*buf = NULL;
|
||||
#elif NGR_R_PRIVATE == 2
|
||||
*buf = p = malloc(sizeof(struct private));
|
||||
if (p == NULL)
|
||||
#ifdef NGR_R_SET_RESULT
|
||||
return (NGR_R_BAD);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
p->buf = NULL;
|
||||
#endif
|
||||
#ifdef NGR_R_SET_RESULT
|
||||
return (NGR_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
NGR_R_END_RETURN
|
||||
#ifdef NGR_R_END_ARGS
|
||||
endnetgrent_r(NGR_R_END_ARGS)
|
||||
#else
|
||||
endnetgrent_r(void)
|
||||
#endif
|
||||
{
|
||||
#if NGR_R_PRIVATE == 2
|
||||
struct private *p = buf;
|
||||
#endif
|
||||
#if defined(NGR_R_SET_ARGS) && NGR_R_PRIVATE == 0
|
||||
UNUSED(buf);
|
||||
UNUSED(buflen);
|
||||
#endif
|
||||
|
||||
endnetgrent();
|
||||
#if NGR_R_PRIVATE == 1
|
||||
if (*buf != NULL)
|
||||
free(*buf);
|
||||
*buf = NULL;
|
||||
#elif NGR_R_PRIVATE == 2
|
||||
if (p->buf != NULL)
|
||||
free(p->buf);
|
||||
free(p);
|
||||
#endif
|
||||
NGR_R_END_RESULT(NGR_R_OK);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_protoent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
|
||||
NGR_R_CONST char **domainp, const char *mp, const char *up,
|
||||
const char *dp, NGR_R_COPY_ARGS)
|
||||
{
|
||||
#if NGR_R_PRIVATE == 2
|
||||
struct private *p = buf;
|
||||
#endif
|
||||
char *cp;
|
||||
int n;
|
||||
int len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
len = 0;
|
||||
if (mp != NULL) len += strlen(mp) + 1;
|
||||
if (up != NULL) len += strlen(up) + 1;
|
||||
if (dp != NULL) len += strlen(dp) + 1;
|
||||
|
||||
#if NGR_R_PRIVATE == 1
|
||||
if (*buf != NULL)
|
||||
free(*buf);
|
||||
*buf = malloc(len);
|
||||
if (*buf == NULL)
|
||||
return(NGR_R_BAD);
|
||||
cp = *buf;
|
||||
#elif NGR_R_PRIVATE == 2
|
||||
if (p->buf)
|
||||
free(p->buf);
|
||||
p->buf = malloc(len);
|
||||
if (p->buf == NULL)
|
||||
return(NGR_R_BAD);
|
||||
cp = p->buf;
|
||||
#else
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (NGR_R_BAD);
|
||||
}
|
||||
cp = buf;
|
||||
#endif
|
||||
|
||||
if (mp != NULL) {
|
||||
n = strlen(mp) + 1;
|
||||
strcpy(cp, mp);
|
||||
*machinep = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*machinep = NULL;
|
||||
|
||||
if (up != NULL) {
|
||||
n = strlen(up) + 1;
|
||||
strcpy(cp, up);
|
||||
*userp = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*userp = NULL;
|
||||
|
||||
if (dp != NULL) {
|
||||
n = strlen(dp) + 1;
|
||||
strcpy(cp, dp);
|
||||
*domainp = cp;
|
||||
cp += n;
|
||||
} else
|
||||
*domainp = NULL;
|
||||
|
||||
return (NGR_R_OK);
|
||||
}
|
||||
#else /* NGR_R_RETURN */
|
||||
static int getnetgrent_r_unknown_system = 0;
|
||||
#endif /* NGR_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
/*! \file */
|
||||
@@ -0,0 +1,647 @@
|
||||
/* $NetBSD: getnetnamadr.c,v 1.42 2012/03/13 21:13:41 christos Exp $ */
|
||||
|
||||
/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
|
||||
static char rcsid[] = "Id: getnetnamadr.c,v 8.8 1997/06/01 20:34:37 vixie Exp ";
|
||||
#else
|
||||
__RCSID("$NetBSD: getnetnamadr.c,v 1.42 2012/03/13 21:13:41 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <nsswitch.h>
|
||||
#include <resolv.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getnetbyaddr,_getnetbyaddr)
|
||||
__weak_alias(getnetbyname,_getnetbyname)
|
||||
#endif
|
||||
|
||||
extern int _net_stayopen;
|
||||
|
||||
#define BYADDR 0
|
||||
#define BYNAME 1
|
||||
#define MAXALIASES 35
|
||||
|
||||
#define MAXPACKET (64*1024)
|
||||
|
||||
typedef union {
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
typedef union {
|
||||
long al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
#ifdef YP
|
||||
static char *__ypdomain;
|
||||
static char *__ypcurrent;
|
||||
static int __ypcurrentlen;
|
||||
#endif
|
||||
|
||||
static struct netent net_entry;
|
||||
static char *net_aliases[MAXALIASES];
|
||||
|
||||
static int parse_reversed_addr(const char *, in_addr_t *);
|
||||
static struct netent *getnetanswer(querybuf *, int, int);
|
||||
static int _files_getnetbyaddr(void *, void *, va_list);
|
||||
static int _files_getnetbyname(void *, void *, va_list);
|
||||
static int _dns_getnetbyaddr(void *, void *, va_list);
|
||||
static int _dns_getnetbyname(void *, void *, va_list);
|
||||
#ifdef YP
|
||||
static int _yp_getnetbyaddr(void *, void *, va_list);
|
||||
static int _yp_getnetbyname(void *, void *, va_list);
|
||||
static struct netent *_ypnetent(char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* parse_reversed_addr --
|
||||
* parse str, which should be of the form 'd.c.b.a.IN-ADDR.ARPA'
|
||||
* (a PTR as per RFC 1101) and convert into an in_addr_t of the
|
||||
* address 'a.b.c.d'.
|
||||
* returns 0 on success (storing in *result), or -1 on error.
|
||||
*/
|
||||
static int
|
||||
parse_reversed_addr(const char *str, in_addr_t *result)
|
||||
{
|
||||
unsigned long octet[4];
|
||||
const char *sp;
|
||||
char *ep;
|
||||
int octidx;
|
||||
|
||||
sp = str;
|
||||
/* find the four octets 'd.b.c.a.' */
|
||||
for (octidx = 0; octidx < 4; octidx++) {
|
||||
/* ensure it's a number */
|
||||
if (!isdigit((unsigned char)*sp))
|
||||
return -1;
|
||||
octet[octidx] = strtoul(sp, &ep, 10);
|
||||
/* with a trailing '.' */
|
||||
if (*ep != '.')
|
||||
return -1;
|
||||
/* and is 0 <= octet <= 255 */
|
||||
if (octet[octidx] > 255)
|
||||
return -1;
|
||||
sp = ep + 1;
|
||||
}
|
||||
/* ensure trailer is correct */
|
||||
if (strcasecmp(sp, "IN-ADDR.ARPA") != 0)
|
||||
return -1;
|
||||
*result = 0;
|
||||
/* build result from octets in reverse */
|
||||
for (octidx = 3; octidx >= 0; octidx--) {
|
||||
*result <<= 8;
|
||||
*result |= (in_addr_t)(octet[octidx] & 0xff);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
getnetanswer(querybuf *answer, int anslen, int net_i)
|
||||
{
|
||||
static char n_name[MAXDNAME];
|
||||
static char netbuf[PACKETSZ];
|
||||
|
||||
HEADER *hp;
|
||||
u_char *cp;
|
||||
int n;
|
||||
u_char *eom;
|
||||
int type, class, ancount, qdcount, haveanswer;
|
||||
char *in, *bp, **ap, *ep;
|
||||
|
||||
assert(answer != NULL);
|
||||
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*
|
||||
* answer --> +------------+ ( MESSAGE )
|
||||
* | Header |
|
||||
* +------------+
|
||||
* | Question | the question for the name server
|
||||
* +------------+
|
||||
* | Answer | RRs answering the question
|
||||
* +------------+
|
||||
* | Authority | RRs pointing toward an authority
|
||||
* | Additional | RRs holding additional information
|
||||
* +------------+
|
||||
*/
|
||||
eom = answer->buf + anslen;
|
||||
hp = &answer->hdr;
|
||||
ancount = ntohs(hp->ancount); /* #/records in the answer section */
|
||||
qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
|
||||
bp = netbuf;
|
||||
ep = netbuf + sizeof(netbuf);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (!qdcount) {
|
||||
if (hp->aa)
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
else
|
||||
h_errno = TRY_AGAIN;
|
||||
return NULL;
|
||||
}
|
||||
while (qdcount-- > 0) {
|
||||
n = __dn_skipname(cp, eom);
|
||||
if (n < 0 || (cp + n + QFIXEDSZ) > eom) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return(NULL);
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
}
|
||||
ap = net_aliases;
|
||||
*ap = NULL;
|
||||
net_entry.n_aliases = net_aliases;
|
||||
haveanswer = 0;
|
||||
n_name[0] = '\0';
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp));
|
||||
if ((n < 0) || !res_dnok(bp))
|
||||
break;
|
||||
cp += n;
|
||||
(void)strlcpy(n_name, bp, sizeof(n_name));
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT(n, cp);
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, (int)(ep - bp));
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
cp += n;
|
||||
return NULL;
|
||||
}
|
||||
cp += n;
|
||||
*ap++ = bp;
|
||||
bp += strlen(bp) + 1;
|
||||
net_entry.n_addrtype =
|
||||
(class == C_IN) ? AF_INET : AF_UNSPEC;
|
||||
haveanswer++;
|
||||
}
|
||||
}
|
||||
if (haveanswer) {
|
||||
*ap = NULL;
|
||||
switch (net_i) {
|
||||
case BYADDR:
|
||||
net_entry.n_name = *net_entry.n_aliases;
|
||||
net_entry.n_net = 0L;
|
||||
break;
|
||||
case BYNAME:
|
||||
ap = net_entry.n_aliases;
|
||||
next_alias:
|
||||
in = *ap++;
|
||||
if (in == NULL) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NULL;
|
||||
}
|
||||
net_entry.n_name = n_name;
|
||||
if (parse_reversed_addr(in, &net_entry.n_net) == -1)
|
||||
goto next_alias;
|
||||
break;
|
||||
}
|
||||
net_entry.n_aliases++;
|
||||
#if (defined(__sparc__) && defined(_LP64)) || \
|
||||
defined(__alpha__) || \
|
||||
(defined(__i386__) && defined(_LP64)) || \
|
||||
(defined(__sh__) && defined(_LP64))
|
||||
net_entry.__n_pad0 = 0;
|
||||
#endif
|
||||
return &net_entry;
|
||||
}
|
||||
h_errno = TRY_AGAIN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_files_getnetbyaddr(void *cbrv, void *cbdata, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
uint32_t net = va_arg(ap, uint32_t);
|
||||
int type = va_arg(ap, int);
|
||||
|
||||
struct netent *np;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ((np = getnetent()) != NULL)
|
||||
if (np->n_addrtype == type && np->n_net == net)
|
||||
break;
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_dns_getnetbyaddr(void *cbrv, void *cbdata, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
uint32_t net = va_arg(ap, uint32_t);
|
||||
int type = va_arg(ap, int);
|
||||
|
||||
unsigned int netbr[4];
|
||||
int nn, anslen;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
uint32_t net2;
|
||||
struct netent *np;
|
||||
res_state res;
|
||||
|
||||
if (type != AF_INET)
|
||||
return NS_UNAVAIL;
|
||||
|
||||
for (nn = 4, net2 = net; net2; net2 >>= 8)
|
||||
netbr[--nn] = (unsigned int)(net2 & 0xff);
|
||||
switch (nn) {
|
||||
default:
|
||||
return NS_UNAVAIL;
|
||||
case 3: /* Class A */
|
||||
snprintf(qbuf, sizeof(qbuf), "0.0.0.%u.in-addr.arpa", netbr[3]);
|
||||
break;
|
||||
case 2: /* Class B */
|
||||
snprintf(qbuf, sizeof(qbuf), "0.0.%u.%u.in-addr.arpa",
|
||||
netbr[3], netbr[2]);
|
||||
break;
|
||||
case 1: /* Class C */
|
||||
snprintf(qbuf, sizeof(qbuf), "0.%u.%u.%u.in-addr.arpa",
|
||||
netbr[3], netbr[2], netbr[1]);
|
||||
break;
|
||||
case 0: /* Class D - E */
|
||||
snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u.in-addr.arpa",
|
||||
netbr[3], netbr[2], netbr[1], netbr[0]);
|
||||
break;
|
||||
}
|
||||
buf = malloc(sizeof(*buf));
|
||||
if (buf == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
res = __res_get_state();
|
||||
if (res == NULL) {
|
||||
free(buf);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
anslen = res_nquery(res, qbuf, C_IN, T_PTR, buf->buf,
|
||||
(int)sizeof(buf->buf));
|
||||
if (anslen < 0) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (res->options & RES_DEBUG)
|
||||
printf("res_query failed\n");
|
||||
#endif
|
||||
__res_put_state(res);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
__res_put_state(res);
|
||||
np = getnetanswer(buf, anslen, BYADDR);
|
||||
free(buf);
|
||||
if (np) {
|
||||
/* maybe net should be unsigned? */
|
||||
uint32_t u_net = net;
|
||||
|
||||
/* Strip trailing zeros */
|
||||
while ((u_net & 0xff) == 0 && u_net != 0)
|
||||
u_net >>= 8;
|
||||
np->n_net = u_net;
|
||||
}
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(uint32_t net, int net_type)
|
||||
{
|
||||
int rv;
|
||||
struct netent *retval;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_files_getnetbyaddr, NULL)
|
||||
{ NSSRC_DNS, _dns_getnetbyaddr, NULL }, /* force -DHESIOD */
|
||||
NS_NIS_CB(_yp_getnetbyaddr, NULL)
|
||||
NS_NULL_CB
|
||||
};
|
||||
|
||||
retval = NULL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
rv = nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyaddr",
|
||||
__nsdefaultsrc, &retval, net, net_type);
|
||||
if (rv == NS_SUCCESS) {
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return retval;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_files_getnetbyname(void *cbrv, void *cbdata, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
const char *name = va_arg(ap, const char *);
|
||||
|
||||
struct netent *np;
|
||||
char **cp;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ((np = getnetent()) != NULL) {
|
||||
if (strcasecmp(np->n_name, name) == 0)
|
||||
break;
|
||||
for (cp = np->n_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_dns_getnetbyname(void *cbrv, void *cbdata, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
const char *name = va_arg(ap, const char *);
|
||||
|
||||
int anslen;
|
||||
querybuf *buf;
|
||||
char qbuf[MAXDNAME];
|
||||
struct netent *np;
|
||||
res_state res;
|
||||
|
||||
strlcpy(&qbuf[0], name, sizeof(qbuf));
|
||||
buf = malloc(sizeof(*buf));
|
||||
if (buf == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
res = __res_get_state();
|
||||
if (res == NULL) {
|
||||
free(buf);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
anslen = res_nsearch(res, qbuf, C_IN, T_PTR, buf->buf,
|
||||
(int)sizeof(buf->buf));
|
||||
if (anslen < 0) {
|
||||
free(buf);
|
||||
#ifdef DEBUG
|
||||
if (res->options & RES_DEBUG)
|
||||
printf("res_search failed\n");
|
||||
#endif
|
||||
__res_put_state(res);
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
__res_put_state(res);
|
||||
np = getnetanswer(buf, anslen, BYNAME);
|
||||
free(buf);
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name)
|
||||
{
|
||||
int rv;
|
||||
struct netent *retval;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_files_getnetbyname, NULL)
|
||||
{ NSSRC_DNS, _dns_getnetbyname, NULL }, /* force -DHESIOD */
|
||||
NS_NIS_CB(_yp_getnetbyname, NULL)
|
||||
NS_NULL_CB
|
||||
};
|
||||
|
||||
assert(name != NULL);
|
||||
|
||||
retval = NULL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
rv = nsdispatch(NULL, dtab, NSDB_NETWORKS, "getnetbyname",
|
||||
__nsdefaultsrc, &retval, name);
|
||||
if (rv == NS_SUCCESS) {
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return retval;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef YP
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_yp_getnetbyaddr(void *cbrv, void *cb_data, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
uint32_t net = va_arg(ap, uint32_t);
|
||||
int type = va_arg(ap, int);
|
||||
|
||||
struct netent *np;
|
||||
char qbuf[MAXDNAME];
|
||||
unsigned int netbr[4];
|
||||
uint32_t net2;
|
||||
int r;
|
||||
|
||||
if (type != AF_INET)
|
||||
return NS_UNAVAIL;
|
||||
|
||||
if (!__ypdomain) {
|
||||
if (_yp_check(&__ypdomain) == 0)
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
np = NULL;
|
||||
if (__ypcurrent)
|
||||
free(__ypcurrent);
|
||||
__ypcurrent = NULL;
|
||||
for (r = 4, net2 = net; net2; net2 >>= 8)
|
||||
netbr[--r] = (unsigned int)(net2 & 0xff);
|
||||
switch (r) {
|
||||
default:
|
||||
return NS_UNAVAIL;
|
||||
case 3: /* Class A */
|
||||
snprintf(qbuf, sizeof(qbuf), "%u", netbr[3]);
|
||||
break;
|
||||
case 2: /* Class B */
|
||||
snprintf(qbuf, sizeof(qbuf), "%u.%u", netbr[2], netbr[3]);
|
||||
break;
|
||||
case 1: /* Class C */
|
||||
snprintf(qbuf, sizeof(qbuf), "%u.%u.%u", netbr[1], netbr[2],
|
||||
netbr[3]);
|
||||
break;
|
||||
case 0: /* Class D - E */
|
||||
snprintf(qbuf, sizeof(qbuf), "%u.%u.%u.%u", netbr[0], netbr[1],
|
||||
netbr[2], netbr[3]);
|
||||
break;
|
||||
}
|
||||
r = yp_match(__ypdomain, "networks.byaddr", qbuf, (int)strlen(qbuf),
|
||||
&__ypcurrent, &__ypcurrentlen);
|
||||
if (r == 0)
|
||||
np = _ypnetent(__ypcurrent);
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
_yp_getnetbyname(void *cbrv, void *cbdata, va_list ap)
|
||||
{
|
||||
struct netent **retval = va_arg(ap, struct netent **);
|
||||
const char *name = va_arg(ap, const char *);
|
||||
|
||||
struct netent *np;
|
||||
int r;
|
||||
|
||||
if (!__ypdomain) {
|
||||
if (_yp_check(&__ypdomain) == 0)
|
||||
return NS_UNAVAIL;
|
||||
}
|
||||
np = NULL;
|
||||
if (__ypcurrent)
|
||||
free(__ypcurrent);
|
||||
__ypcurrent = NULL;
|
||||
r = yp_match(__ypdomain, "networks.byname", name, (int)strlen(name),
|
||||
&__ypcurrent, &__ypcurrentlen);
|
||||
if (r == 0)
|
||||
np = _ypnetent(__ypcurrent);
|
||||
|
||||
if (np != NULL) {
|
||||
*retval = np;
|
||||
return NS_SUCCESS;
|
||||
} else {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NS_NOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
static struct netent *
|
||||
_ypnetent(char *line)
|
||||
{
|
||||
char *cp, *p, **q;
|
||||
|
||||
assert(line != NULL);
|
||||
|
||||
net_entry.n_name = line;
|
||||
cp = strpbrk(line, " \t");
|
||||
if (cp == NULL)
|
||||
return NULL;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
net_entry.n_net = inet_network(cp);
|
||||
#if (defined(__sparc__) && defined(_LP64)) || \
|
||||
defined(__alpha__) || \
|
||||
(defined(__i386__) && defined(_LP64)) || \
|
||||
(defined(__sh__) && defined(_LP64))
|
||||
net_entry.__n_pad0 = 0;
|
||||
#endif
|
||||
net_entry.n_addrtype = AF_INET;
|
||||
q = net_entry.n_aliases = net_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &net_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
|
||||
return &net_entry;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/* $NetBSD: getprotobyname.c,v 1.4 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getprotobyname.c,v 1.4 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <pthread.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "protoent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getprotobyname,_getprotobyname)
|
||||
#endif
|
||||
|
||||
#ifdef _REENTRANT
|
||||
extern pthread_mutex_t _protoent_mutex;
|
||||
#endif
|
||||
extern struct protoent_data _protoent_data;
|
||||
|
||||
struct protoent *
|
||||
getprotobyname(const char *name)
|
||||
{
|
||||
struct protoent *p;
|
||||
|
||||
pthread_mutex_lock(&_protoent_mutex);
|
||||
p = getprotobyname_r(name, &_protoent_data.proto, &_protoent_data);
|
||||
pthread_mutex_unlock(&_protoent_mutex);
|
||||
return (p);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/* $NetBSD: getprotobyname_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getprotobyname_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "protoent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getprotobyname_r,_getprotobyname_r)
|
||||
#endif
|
||||
|
||||
struct protoent *
|
||||
getprotobyname_r(const char *name, struct protoent *pr,
|
||||
struct protoent_data *pd)
|
||||
{
|
||||
struct protoent *p;
|
||||
char **cp;
|
||||
|
||||
assert(name != NULL);
|
||||
|
||||
setprotoent_r(pd->stayopen, pd);
|
||||
while ((p = getprotoent_r(pr, pd)) != NULL) {
|
||||
if (strcmp(p->p_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->p_aliases; *cp != NULL; cp++)
|
||||
if (strcmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!pd->stayopen)
|
||||
if (pd->fp != NULL) {
|
||||
(void)fclose(pd->fp);
|
||||
pd->fp = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* $NetBSD: getprotobynumber.c,v 1.4 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getprotobynumber.c,v 1.4 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "protoent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getprotobynumber,_getprotobynumber)
|
||||
#endif
|
||||
|
||||
#ifdef _REENTRANT
|
||||
extern pthread_mutex_t _protoent_mutex;
|
||||
#endif
|
||||
extern struct protoent_data _protoent_data;
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(int proto)
|
||||
{
|
||||
struct protoent *p;
|
||||
|
||||
pthread_mutex_lock(&_protoent_mutex);
|
||||
p = getprotobynumber_r(proto, &_protoent_data.proto, &_protoent_data);
|
||||
pthread_mutex_unlock(&_protoent_mutex);
|
||||
return (p);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/* $NetBSD: getprotobynumber_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getprotobynumber_r.c,v 1.3 2005/04/18 19:39:45 kleink Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "protoent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getprotobynumber_r,_getprotobynumber_r)
|
||||
#endif
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber_r(int proto, struct protoent *pr, struct protoent_data *pd)
|
||||
{
|
||||
struct protoent *p;
|
||||
|
||||
setprotoent_r(pd->stayopen, pd);
|
||||
while ((p = getprotoent_r(pr, pd)) != NULL)
|
||||
if (p->p_proto == proto)
|
||||
break;
|
||||
if (!pd->stayopen)
|
||||
if (pd->fp != NULL) {
|
||||
(void)fclose(pd->fp);
|
||||
pd->fp = NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -1,176 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/* $NetBSD: getprotoent.c,v 1.12 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getprotoent.c,v 1.4 2005/04/27 04:56:26 sra Exp $";
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getprotoent.c,v 1.12 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#include "protoent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(endprotoent,_endprotoent)
|
||||
__weak_alias(getprotoent,_getprotoent)
|
||||
__weak_alias(setprotoent,_setprotoent)
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
#ifdef _REENTRANT
|
||||
pthread_mutex_t _protoent_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
struct protoent_data _protoent_data;
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct protoent *
|
||||
getprotoent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotoent_p(net_data));
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotobyname_p(name, net_data));
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(int proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getprotobynumber_p(proto, net_data));
|
||||
void
|
||||
setprotoent(int f)
|
||||
{
|
||||
pthread_mutex_lock(&_protoent_mutex);
|
||||
setprotoent_r(f, &_protoent_data);
|
||||
pthread_mutex_unlock(&_protoent_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setprotoent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endprotoent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct protoent *
|
||||
getprotoent_p(struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
net_data->pr_last = (*pr->next)(pr);
|
||||
return (net_data->pr_last);
|
||||
endprotoent(void)
|
||||
{
|
||||
pthread_mutex_lock(&_protoent_mutex);
|
||||
endprotoent_r(&_protoent_data);
|
||||
pthread_mutex_unlock(&_protoent_mutex);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobyname_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
char **pap;
|
||||
getprotoent(void)
|
||||
{
|
||||
struct protoent *p;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
if (net_data->pr_stayopen && net_data->pr_last) {
|
||||
if (!strcmp(net_data->pr_last->p_name, name))
|
||||
return (net_data->pr_last);
|
||||
for (pap = net_data->pr_last->p_aliases; pap && *pap; pap++)
|
||||
if (!strcmp(name, *pap))
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
net_data->pr_last = (*pr->byname)(pr, name);
|
||||
if (!net_data->pr_stayopen)
|
||||
endprotoent();
|
||||
return (net_data->pr_last);
|
||||
pthread_mutex_lock(&_protoent_mutex);
|
||||
p = getprotoent_r(&_protoent_data.proto, &_protoent_data);
|
||||
pthread_mutex_unlock(&_protoent_mutex);
|
||||
return (p);
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber_p(int proto, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return (NULL);
|
||||
if (net_data->pr_stayopen && net_data->pr_last)
|
||||
if (net_data->pr_last->p_proto == proto)
|
||||
return (net_data->pr_last);
|
||||
net_data->pr_last = (*pr->bynumber)(pr, proto);
|
||||
if (!net_data->pr_stayopen)
|
||||
endprotoent();
|
||||
return (net_data->pr_last);
|
||||
}
|
||||
|
||||
void
|
||||
setprotoent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if (!net_data || !(pr = net_data->pr))
|
||||
return;
|
||||
(*pr->rewind)(pr);
|
||||
net_data->pr_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent_p(struct net_data *net_data) {
|
||||
struct irs_pr *pr;
|
||||
|
||||
if ((net_data != NULL) && ((pr = net_data->pr) != NULL))
|
||||
(*pr->minimize)(pr);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->pr) {
|
||||
net_data->pr = (*net_data->irs->pr_map)(net_data->irs);
|
||||
|
||||
if (!net_data->pr || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->pr->res_set)(net_data->pr, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -1,223 +1,161 @@
|
||||
/* $NetBSD: getprotoent_r.c,v 1.6 2011/10/15 23:00:02 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* 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. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getprotoent_r.c,v 1.6 2006/08/01 01:14:16 marka Exp $";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getprotoent_r.c,v 1.6 2011/10/15 23:00:02 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getprotoent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <port_after.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef PROTO_R_RETURN
|
||||
#include <FindDirectory.h>
|
||||
|
||||
static PROTO_R_RETURN
|
||||
copy_protoent(struct protoent *, struct protoent *, PROTO_R_COPY_ARGS);
|
||||
#include <libutil.h>
|
||||
#include "protoent.h"
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotobyname_r(const char *name, struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotobyname(name);
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(endprotoent_r,_endprotoent_r)
|
||||
__weak_alias(getprotoent_r,_getprotoent_r)
|
||||
__weak_alias(setprotoent_r,_setprotoent_r)
|
||||
#endif
|
||||
}
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotobynumber_r(int proto, struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotobynumber(proto);
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
PROTO_R_RETURN
|
||||
getprotoent_r(struct protoent *pptr, PROTO_R_ARGS) {
|
||||
struct protoent *pe = getprotoent();
|
||||
#ifdef PROTO_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (pe == NULL || (n = copy_protoent(pe, pptr, PROTO_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = pptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (pe == NULL)
|
||||
return (PROTO_R_BAD);
|
||||
|
||||
return (copy_protoent(pe, pptr, PROTO_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
PROTO_R_SET_RETURN
|
||||
#ifdef PROTO_R_ENT_ARGS
|
||||
setprotoent_r(int stay_open, PROTO_R_ENT_ARGS)
|
||||
#else
|
||||
setprotoent_r(int stay_open)
|
||||
#endif
|
||||
void
|
||||
setprotoent_r(int f, struct protoent_data *pd)
|
||||
{
|
||||
#ifdef PROTO_R_ENT_UNUSED
|
||||
PROTO_R_ENT_UNUSED;
|
||||
#endif
|
||||
setprotoent(stay_open);
|
||||
#ifdef PROTO_R_SET_RESULT
|
||||
return (PROTO_R_SET_RESULT);
|
||||
#endif
|
||||
if (pd->fp == NULL) {
|
||||
char buffer[256];
|
||||
find_directory(B_SYSTEM_SETTINGS_DIRECTORY, 0, false, buffer, sizeof(buffer));
|
||||
strlcat(buffer, "/network/protocols", sizeof(buffer));
|
||||
|
||||
pd->fp = fopen(buffer, "re");
|
||||
} else
|
||||
rewind(pd->fp);
|
||||
pd->stayopen |= f;
|
||||
}
|
||||
|
||||
PROTO_R_END_RETURN
|
||||
#ifdef PROTO_R_ENT_ARGS
|
||||
endprotoent_r(PROTO_R_ENT_ARGS)
|
||||
#else
|
||||
endprotoent_r()
|
||||
#endif
|
||||
void
|
||||
endprotoent_r(struct protoent_data *pd)
|
||||
{
|
||||
#ifdef PROTO_R_ENT_UNUSED
|
||||
PROTO_R_ENT_UNUSED;
|
||||
#endif
|
||||
endprotoent();
|
||||
PROTO_R_END_RESULT(PROTO_R_OK);
|
||||
if (pd->fp) {
|
||||
(void)fclose(pd->fp);
|
||||
pd->fp = NULL;
|
||||
}
|
||||
if (pd->aliases) {
|
||||
free(pd->aliases);
|
||||
pd->aliases = NULL;
|
||||
pd->maxaliases = 0;
|
||||
}
|
||||
if (pd->line) {
|
||||
free(pd->line);
|
||||
pd->line = NULL;
|
||||
}
|
||||
pd->stayopen = 0;
|
||||
}
|
||||
|
||||
/* Private */
|
||||
struct protoent *
|
||||
getprotoent_r(struct protoent *pr, struct protoent_data *pd)
|
||||
{
|
||||
char *p, *cp, **q;
|
||||
size_t i = 0;
|
||||
int oerrno;
|
||||
|
||||
#ifndef PROTOENT_DATA
|
||||
static PROTO_R_RETURN
|
||||
copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
if (pd->fp == NULL)
|
||||
setprotoent_r(0, pd);
|
||||
if (pd->fp == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /*%< NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; pe->p_aliases[i]; i++, numptr++) {
|
||||
len += strlen(pe->p_aliases[i]) + 1;
|
||||
}
|
||||
len += strlen(pe->p_name) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (PROTO_R_BAD);
|
||||
}
|
||||
|
||||
/* copy protocol value*/
|
||||
pptr->p_proto = pe->p_proto;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(pe->p_name) + 1;
|
||||
strcpy(cp, pe->p_name);
|
||||
pptr->p_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
pptr->p_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; pe->p_aliases[i]; i++) {
|
||||
n = strlen(pe->p_aliases[i]) + 1;
|
||||
strcpy(cp, pe->p_aliases[i]);
|
||||
pptr->p_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
pptr->p_aliases[i] = NULL;
|
||||
|
||||
return (PROTO_R_OK);
|
||||
}
|
||||
#else /* !PROTOENT_DATA */
|
||||
static int
|
||||
copy_protoent(struct protoent *pe, struct protoent *pptr, PROTO_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy protocol value */
|
||||
pptr->p_proto = pe->p_proto;
|
||||
|
||||
/* copy official name */
|
||||
cp = pdptr->line;
|
||||
eob = pdptr->line + sizeof(pdptr->line);
|
||||
if ((n = strlen(pe->p_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, pe->p_name);
|
||||
pptr->p_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
pptr->p_aliases = pdptr->proto_aliases;
|
||||
while (pe->p_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(pe->p_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, pe->p_aliases[i]);
|
||||
pptr->p_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
for (;;) {
|
||||
if (pd->line)
|
||||
free(pd->line);
|
||||
pd->line = fparseln(pd->fp, NULL, NULL, NULL,
|
||||
FPARSELN_UNESCALL);
|
||||
if (pd->line == NULL)
|
||||
return NULL;
|
||||
pr->p_name = p = pd->line;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
continue;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
pr->p_proto = atoi(cp);
|
||||
if (pd->aliases == NULL) {
|
||||
pd->maxaliases = 10;
|
||||
pd->aliases = malloc(pd->maxaliases * sizeof(char *));
|
||||
if (pd->aliases == NULL) {
|
||||
oerrno = errno;
|
||||
endprotoent_r(pd);
|
||||
errno = oerrno;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
pptr->p_aliases[i] = NULL;
|
||||
q = pr->p_aliases = pd->aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (i == pd->maxaliases - 2) {
|
||||
pd->maxaliases *= 2;
|
||||
q = realloc(q,
|
||||
pd->maxaliases * sizeof(char *));
|
||||
if (q == NULL) {
|
||||
oerrno = errno;
|
||||
endprotoent_r(pd);
|
||||
errno = oerrno;
|
||||
return NULL;
|
||||
}
|
||||
pr->p_aliases = pd->aliases = q;
|
||||
}
|
||||
q[i++] = cp;
|
||||
|
||||
return (PROTO_R_OK);
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
q[i] = NULL;
|
||||
return pr;
|
||||
}
|
||||
}
|
||||
#endif /* PROTOENT_DATA */
|
||||
#else /* PROTO_R_RETURN */
|
||||
static int getprotoent_r_unknown_system = 0;
|
||||
#endif /* PROTO_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
/*! \file */
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getpwent.c,v 1.3 2005/04/27 04:56:26 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_PW) || defined(__BIND_NOSTATIC)
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data * init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct passwd *
|
||||
getpwent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwent_p(net_data));
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam(const char *name) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwnam_p(name, net_data));
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid(uid_t uid) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getpwuid_p(uid, net_data));
|
||||
}
|
||||
|
||||
int
|
||||
setpassent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setpassent_p(stayopen, net_data));
|
||||
}
|
||||
|
||||
#ifdef SETPWENT_VOID
|
||||
void
|
||||
setpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setpwent_p(net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (setpwent_p(net_data));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
endpwent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endpwent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct passwd *
|
||||
getpwent_p(struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
net_data->pw_last = (*pw->next)(pw);
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwnam_p(const char *name, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
if (net_data->pw_stayopen && net_data->pw_last &&
|
||||
!strcmp(net_data->pw_last->pw_name, name))
|
||||
return (net_data->pw_last);
|
||||
net_data->pw_last = (*pw->byname)(pw, name);
|
||||
if (!net_data->pw_stayopen)
|
||||
endpwent();
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
struct passwd *
|
||||
getpwuid_p(uid_t uid, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (NULL);
|
||||
if (net_data->pw_stayopen && net_data->pw_last &&
|
||||
net_data->pw_last->pw_uid == uid)
|
||||
return (net_data->pw_last);
|
||||
net_data->pw_last = (*pw->byuid)(pw, uid);
|
||||
if (!net_data->pw_stayopen)
|
||||
endpwent();
|
||||
return (net_data->pw_last);
|
||||
}
|
||||
|
||||
int
|
||||
setpassent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if (!net_data || !(pw = net_data->pw))
|
||||
return (0);
|
||||
(*pw->rewind)(pw);
|
||||
net_data->pw_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SETPWENT_VOID
|
||||
void
|
||||
setpwent_p(struct net_data *net_data) {
|
||||
(void) setpassent_p(0, net_data);
|
||||
}
|
||||
#else
|
||||
int
|
||||
setpwent_p(struct net_data *net_data) {
|
||||
return (setpassent_p(0, net_data));
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
endpwent_p(struct net_data *net_data) {
|
||||
struct irs_pw *pw;
|
||||
|
||||
if ((net_data != NULL) && ((pw = net_data->pw) != NULL))
|
||||
(*pw->minimize)(pw);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->pw) {
|
||||
net_data->pw = (*net_data->irs->pw_map)(net_data->irs);
|
||||
|
||||
if (!net_data->pw || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->pw->res_set)(net_data->pw, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
/*! \file */
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getpwent_r.c,v 1.8 2005/04/27 04:56:26 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS) || !defined(WANT_IRS_PW)
|
||||
static int getpwent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if (defined(POSIX_GETPWNAM_R) || defined(POSIX_GETPWUID_R))
|
||||
#if defined(_POSIX_PTHREAD_SEMANTICS)
|
||||
/* turn off solaris remapping in <grp.h> */
|
||||
#undef _POSIX_PTHREAD_SEMANTICS
|
||||
#include <pwd.h>
|
||||
#define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#else
|
||||
#define _UNIX95 1
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#else
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include <port_after.h>
|
||||
|
||||
#ifdef PASS_R_RETURN
|
||||
|
||||
static int
|
||||
copy_passwd(struct passwd *, struct passwd *, char *buf, int buflen);
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETPWNAM_R
|
||||
int
|
||||
__posix_getpwnam_r(const char *login, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#else
|
||||
int
|
||||
getpwnam_r(const char *login, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#endif
|
||||
struct passwd *pw = getpwnam(login);
|
||||
int res;
|
||||
|
||||
if (pw == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
*result = res ? NULL : pwptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETPWNAM_R
|
||||
struct passwd *
|
||||
getpwnam_r(const char *login, struct passwd *pwptr, char *buf, int buflen) {
|
||||
struct passwd *pw = getpwnam(login);
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? NULL : pwptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* POSIX 1003.1c */
|
||||
#ifdef POSIX_GETPWUID_R
|
||||
int
|
||||
__posix_getpwuid_r(uid_t uid, struct passwd *pwptr,
|
||||
char *buf, int buflen, struct passwd **result) {
|
||||
#else
|
||||
int
|
||||
getpwuid_r(uid_t uid, struct passwd *pwptr,
|
||||
char *buf, size_t buflen, struct passwd **result) {
|
||||
#endif
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
int res;
|
||||
|
||||
if (pw == NULL) {
|
||||
*result = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
*result = res ? NULL : pwptr;
|
||||
return (res);
|
||||
}
|
||||
|
||||
#ifdef POSIX_GETPWUID_R
|
||||
struct passwd *
|
||||
getpwuid_r(uid_t uid, struct passwd *pwptr, char *buf, int buflen) {
|
||||
struct passwd *pw = getpwuid(uid);
|
||||
int res;
|
||||
|
||||
if (pw == NULL)
|
||||
return (NULL);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? NULL : pwptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
PASS_R_RETURN
|
||||
getpwent_r(struct passwd *pwptr, PASS_R_ARGS) {
|
||||
struct passwd *pw = getpwent();
|
||||
int res = 0;
|
||||
|
||||
if (pw == NULL)
|
||||
return (PASS_R_BAD);
|
||||
|
||||
res = copy_passwd(pw, pwptr, buf, buflen);
|
||||
return (res ? PASS_R_BAD : PASS_R_OK);
|
||||
}
|
||||
|
||||
PASS_R_SET_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
setpassent_r(int stayopen, PASS_R_ENT_ARGS)
|
||||
#else
|
||||
setpassent_r(int stayopen)
|
||||
#endif
|
||||
{
|
||||
|
||||
setpassent(stayopen);
|
||||
#ifdef PASS_R_SET_RESULT
|
||||
return (PASS_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
PASS_R_SET_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
setpwent_r(PASS_R_ENT_ARGS)
|
||||
#else
|
||||
setpwent_r(void)
|
||||
#endif
|
||||
{
|
||||
|
||||
setpwent();
|
||||
#ifdef PASS_R_SET_RESULT
|
||||
return (PASS_R_SET_RESULT);
|
||||
#endif
|
||||
}
|
||||
|
||||
PASS_R_END_RETURN
|
||||
#ifdef PASS_R_ENT_ARGS
|
||||
endpwent_r(PASS_R_ENT_ARGS)
|
||||
#else
|
||||
endpwent_r(void)
|
||||
#endif
|
||||
{
|
||||
|
||||
endpwent();
|
||||
PASS_R_END_RESULT(PASS_R_OK);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAS_FGETPWENT
|
||||
PASS_R_RETURN
|
||||
fgetpwent_r(FILE *f, struct passwd *pwptr, PASS_R_COPY_ARGS) {
|
||||
struct passwd *pw = fgetpwent(f);
|
||||
int res = 0;
|
||||
|
||||
if (pw == NULL)
|
||||
return (PASS_R_BAD);
|
||||
|
||||
res = copy_passwd(pw, pwptr, PASS_R_COPY);
|
||||
return (res ? PASS_R_BAD : PASS_R_OK );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Private */
|
||||
|
||||
static int
|
||||
copy_passwd(struct passwd *pw, struct passwd *pwptr, char *buf, int buflen) {
|
||||
char *cp;
|
||||
int n;
|
||||
int len;
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
len = strlen(pw->pw_name) + 1;
|
||||
len += strlen(pw->pw_passwd) + 1;
|
||||
#ifdef HAVE_PW_CLASS
|
||||
len += strlen(pw->pw_class) + 1;
|
||||
#endif
|
||||
len += strlen(pw->pw_gecos) + 1;
|
||||
len += strlen(pw->pw_dir) + 1;
|
||||
len += strlen(pw->pw_shell) + 1;
|
||||
|
||||
if (len > buflen) {
|
||||
errno = ERANGE;
|
||||
return (ERANGE);
|
||||
}
|
||||
|
||||
/* copy fixed atomic values*/
|
||||
pwptr->pw_uid = pw->pw_uid;
|
||||
pwptr->pw_gid = pw->pw_gid;
|
||||
#ifdef HAVE_PW_CHANGE
|
||||
pwptr->pw_change = pw->pw_change;
|
||||
#endif
|
||||
#ifdef HAVE_PW_EXPIRE
|
||||
pwptr->pw_expire = pw->pw_expire;
|
||||
#endif
|
||||
|
||||
cp = buf;
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(pw->pw_name) + 1;
|
||||
strcpy(cp, pw->pw_name);
|
||||
pwptr->pw_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy password */
|
||||
n = strlen(pw->pw_passwd) + 1;
|
||||
strcpy(cp, pw->pw_passwd);
|
||||
pwptr->pw_passwd = cp;
|
||||
cp += n;
|
||||
|
||||
#ifdef HAVE_PW_CLASS
|
||||
/* copy class */
|
||||
n = strlen(pw->pw_class) + 1;
|
||||
strcpy(cp, pw->pw_class);
|
||||
pwptr->pw_class = cp;
|
||||
cp += n;
|
||||
#endif
|
||||
|
||||
/* copy gecos */
|
||||
n = strlen(pw->pw_gecos) + 1;
|
||||
strcpy(cp, pw->pw_gecos);
|
||||
pwptr->pw_gecos = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy directory */
|
||||
n = strlen(pw->pw_dir) + 1;
|
||||
strcpy(cp, pw->pw_dir);
|
||||
pwptr->pw_dir = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy login shell */
|
||||
n = strlen(pw->pw_shell) + 1;
|
||||
strcpy(cp, pw->pw_shell);
|
||||
pwptr->pw_shell = cp;
|
||||
cp += n;
|
||||
|
||||
return (0);
|
||||
}
|
||||
#else /* PASS_R_RETURN */
|
||||
static int getpwent_r_unknown_system = 0;
|
||||
#endif /* PASS_R_RETURN */
|
||||
#endif /* !def(_REENTRANT) || !def(DO_PTHREADS) || !def(WANT_IRS_PW) */
|
||||
/*! \file */
|
||||
@@ -0,0 +1,59 @@
|
||||
/* $NetBSD: getservbyname.c,v 1.14 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getservbyname.c,v 1.14 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "servent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getservbyname,_getservbyname)
|
||||
#endif
|
||||
|
||||
#ifdef _REENTRANT
|
||||
extern pthread_mutex_t _servent_mutex;
|
||||
#endif
|
||||
extern struct servent_data _servent_data;
|
||||
|
||||
struct servent *
|
||||
getservbyname(const char *name, const char *proto)
|
||||
{
|
||||
struct servent *s;
|
||||
|
||||
pthread_mutex_lock(&_servent_mutex);
|
||||
s = getservbyname_r(name, proto, &_servent_data.serv, &_servent_data);
|
||||
pthread_mutex_unlock(&_servent_mutex);
|
||||
return (s);
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/* $NetBSD: getservbyname_r.c,v 1.9 2012/03/13 21:13:41 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getservbyname_r.c,v 1.9 2012/03/13 21:13:41 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "servent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getservbyname_r,_getservbyname_r)
|
||||
#endif
|
||||
|
||||
static struct servent *
|
||||
_servent_getbyname(struct servent_data *sd, struct servent *sp,
|
||||
const char *name, const char *proto)
|
||||
{
|
||||
|
||||
if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0)
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
if (sd->flags & _SV_CDB) {
|
||||
uint8_t buf[255 * 2 + 2];
|
||||
size_t namelen, protolen;
|
||||
const uint8_t *data, *data_end;
|
||||
const void *data_ptr;
|
||||
size_t datalen;
|
||||
|
||||
namelen = strlen(name);
|
||||
if (namelen == 0 || namelen > 255)
|
||||
return NULL;
|
||||
if (proto != NULL) {
|
||||
protolen = strlen(proto);
|
||||
if (protolen == 0 || protolen > 255)
|
||||
return NULL;
|
||||
} else
|
||||
protolen = 0;
|
||||
if (namelen + protolen > 255)
|
||||
return NULL;
|
||||
|
||||
buf[0] = (uint8_t)namelen;
|
||||
buf[1] = (uint8_t)protolen;
|
||||
memcpy(buf + 2, name, namelen);
|
||||
memcpy(buf + 2 + namelen, proto, protolen);
|
||||
|
||||
if (cdbr_find(sd->cdb, buf, 2 + namelen + protolen,
|
||||
&data_ptr, &datalen))
|
||||
return NULL;
|
||||
|
||||
if (datalen < namelen + protolen + 6)
|
||||
return NULL;
|
||||
|
||||
data = data_ptr;
|
||||
data_end = data + datalen;
|
||||
if (protolen) {
|
||||
if (data[2] != protolen)
|
||||
return NULL;
|
||||
if (memcmp(data + 3, proto, protolen + 1))
|
||||
return NULL;
|
||||
}
|
||||
data += 3 + data[2] + 1;
|
||||
if (data > data_end)
|
||||
return NULL;
|
||||
while (data != data_end) {
|
||||
if (*data == '\0')
|
||||
return NULL;
|
||||
if (data + data[0] + 2 > data_end)
|
||||
return NULL;
|
||||
if (data[0] == namelen &&
|
||||
memcmp(data + 1, name, namelen + 1) == 0)
|
||||
return _servent_parsedb(sd, sp, data_ptr,
|
||||
datalen);
|
||||
data += data[0] + 2;
|
||||
}
|
||||
return NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
while (_servent_getline(sd) != -1) {
|
||||
char **cp;
|
||||
if (_servent_parseline(sd, sp) == NULL)
|
||||
continue;
|
||||
|
||||
if (strcmp(name, sp->s_name) == 0)
|
||||
goto gotname;
|
||||
|
||||
for (cp = sp->s_aliases; *cp; cp++)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
goto gotname;
|
||||
continue;
|
||||
gotname:
|
||||
if (proto == NULL || strcmp(sp->s_proto, proto) == 0)
|
||||
return sp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname_r(const char *name, const char *proto, struct servent *sp,
|
||||
struct servent_data *sd)
|
||||
{
|
||||
assert(name != NULL);
|
||||
/* proto may be NULL */
|
||||
|
||||
setservent_r(sd->flags & _SV_STAYOPEN, sd);
|
||||
sp = _servent_getbyname(sd, sp, name, proto);
|
||||
if (!(sd->flags & _SV_STAYOPEN))
|
||||
_servent_close(sd);
|
||||
return sp;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* $NetBSD: getservbyport.c,v 1.12 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getservbyport.c,v 1.12 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "servent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getservbyport,_getservbyport)
|
||||
#endif
|
||||
|
||||
#ifdef _REENTRANT
|
||||
extern pthread_mutex_t _servent_mutex;
|
||||
#endif
|
||||
extern struct servent_data _servent_data;
|
||||
|
||||
struct servent *
|
||||
getservbyport(int port, const char *proto)
|
||||
{
|
||||
struct servent *s;
|
||||
|
||||
pthread_mutex_lock(&_servent_mutex);
|
||||
s = getservbyport_r(port, proto, &_servent_data.serv, &_servent_data);
|
||||
pthread_mutex_unlock(&_servent_mutex);
|
||||
return (s);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/* $NetBSD: getservbyport_r.c,v 1.9 2012/03/13 21:13:41 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getservbyport_r.c,v 1.9 2012/03/13 21:13:41 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "servent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(getservbyport_r,_getservbyport_r)
|
||||
#endif
|
||||
|
||||
static struct servent *
|
||||
_servent_getbyport(struct servent_data *sd, struct servent *sp, int port,
|
||||
const char *proto)
|
||||
{
|
||||
|
||||
if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0)
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
if (sd->flags & _SV_CDB) {
|
||||
uint8_t buf[255 + 4];
|
||||
size_t protolen;
|
||||
const uint8_t *data;
|
||||
const void *data_ptr;
|
||||
size_t datalen;
|
||||
|
||||
port = ntohs(port);
|
||||
|
||||
if (proto != NULL) {
|
||||
protolen = strlen(proto);
|
||||
if (protolen == 0 || protolen > 255)
|
||||
return NULL;
|
||||
} else
|
||||
protolen = 0;
|
||||
if (port < 0 || port > 65536)
|
||||
return NULL;
|
||||
|
||||
buf[0] = 0;
|
||||
buf[1] = (uint8_t)protolen;
|
||||
be16enc(buf + 2, port);
|
||||
memcpy(buf + 4, proto, protolen);
|
||||
|
||||
if (cdbr_find(sd->cdb, buf, 4 + protolen,
|
||||
&data_ptr, &datalen))
|
||||
return NULL;
|
||||
|
||||
if (datalen < protolen + 4)
|
||||
return NULL;
|
||||
|
||||
data = data_ptr;
|
||||
if (be16dec(data) != port)
|
||||
return NULL;
|
||||
if (protolen) {
|
||||
if (data[2] != protolen)
|
||||
return NULL;
|
||||
if (memcmp(data + 3, proto, protolen + 1))
|
||||
return NULL;
|
||||
}
|
||||
return _servent_parsedb(sd, sp, data, datalen);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
while (_servent_getline(sd) != -1) {
|
||||
if (_servent_parseline(sd, sp) == NULL)
|
||||
continue;
|
||||
if (sp->s_port != port)
|
||||
continue;
|
||||
if (proto == NULL || strcmp(sp->s_proto, proto) == 0)
|
||||
return sp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport_r(int port, const char *proto, struct servent *sp,
|
||||
struct servent_data *sd)
|
||||
{
|
||||
setservent_r(sd->flags & _SV_STAYOPEN, sd);
|
||||
sp = _servent_getbyport(sd, sp, port, proto);
|
||||
if (!(sd->flags & _SV_STAYOPEN))
|
||||
_servent_close(sd);
|
||||
return sp;
|
||||
}
|
||||
@@ -1,179 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
/* $NetBSD: getservent.c,v 1.12 2008/04/28 20:23:00 martin Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: getservent.c,v 1.4 2005/04/27 04:56:26 sra Exp $";
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: getservent.c,v 1.12 2008/04/28 20:23:00 martin Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "servent.h"
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(endservent,_endservent)
|
||||
__weak_alias(getservent,_getservent)
|
||||
__weak_alias(setservent,_setservent)
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
#ifdef _REENTRANT
|
||||
pthread_mutex_t _servent_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
struct servent_data _servent_data;
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(__BIND_NOSTATIC)
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static struct net_data *init(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct servent *
|
||||
getservent(void) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservent_p(net_data));
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname(const char *name, const char *proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservbyname_p(name, proto, net_data));
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport(int port, const char *proto) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
return (getservbyport_p(port, proto, net_data));
|
||||
void
|
||||
setservent(int f)
|
||||
{
|
||||
pthread_mutex_lock(&_servent_mutex);
|
||||
setservent_r(f, &_servent_data);
|
||||
pthread_mutex_unlock(&_servent_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
setservent(int stayopen) {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
setservent_p(stayopen, net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endservent() {
|
||||
struct net_data *net_data = init();
|
||||
|
||||
endservent_p(net_data);
|
||||
}
|
||||
|
||||
/* Shared private. */
|
||||
|
||||
struct servent *
|
||||
getservent_p(struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
net_data->sv_last = (*sv->next)(sv);
|
||||
return (net_data->sv_last);
|
||||
endservent(void)
|
||||
{
|
||||
pthread_mutex_lock(&_servent_mutex);
|
||||
endservent_r(&_servent_data);
|
||||
pthread_mutex_unlock(&_servent_mutex);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyname_p(const char *name, const char *proto,
|
||||
struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
char **sap;
|
||||
getservent(void)
|
||||
{
|
||||
struct servent *s;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
if (net_data->sv_stayopen && net_data->sv_last)
|
||||
if (!proto || !strcmp(net_data->sv_last->s_proto, proto)) {
|
||||
if (!strcmp(net_data->sv_last->s_name, name))
|
||||
return (net_data->sv_last);
|
||||
for (sap = net_data->sv_last->s_aliases;
|
||||
sap && *sap; sap++)
|
||||
if (!strcmp(name, *sap))
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
net_data->sv_last = (*sv->byname)(sv, name, proto);
|
||||
if (!net_data->sv_stayopen)
|
||||
endservent();
|
||||
return (net_data->sv_last);
|
||||
pthread_mutex_lock(&_servent_mutex);
|
||||
s = getservent_r(&_servent_data.serv, &_servent_data);
|
||||
pthread_mutex_unlock(&_servent_mutex);
|
||||
return (s);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservbyport_p(int port, const char *proto, struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return (NULL);
|
||||
if (net_data->sv_stayopen && net_data->sv_last)
|
||||
if (port == net_data->sv_last->s_port &&
|
||||
( !proto ||
|
||||
!strcmp(net_data->sv_last->s_proto, proto)))
|
||||
return (net_data->sv_last);
|
||||
net_data->sv_last = (*sv->byport)(sv, port, proto);
|
||||
return (net_data->sv_last);
|
||||
}
|
||||
|
||||
void
|
||||
setservent_p(int stayopen, struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if (!net_data || !(sv = net_data->sv))
|
||||
return;
|
||||
(*sv->rewind)(sv);
|
||||
net_data->sv_stayopen = (stayopen != 0);
|
||||
if (stayopen == 0)
|
||||
net_data_minimize(net_data);
|
||||
}
|
||||
|
||||
void
|
||||
endservent_p(struct net_data *net_data) {
|
||||
struct irs_sv *sv;
|
||||
|
||||
if ((net_data != NULL) && ((sv = net_data->sv) != NULL))
|
||||
(*sv->minimize)(sv);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct net_data *
|
||||
init() {
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!(net_data = net_data_init(NULL)))
|
||||
goto error;
|
||||
if (!net_data->sv) {
|
||||
net_data->sv = (*net_data->irs->sv_map)(net_data->irs);
|
||||
|
||||
if (!net_data->sv || !net_data->res) {
|
||||
error:
|
||||
errno = EIO;
|
||||
return (NULL);
|
||||
}
|
||||
(*net_data->sv->res_set)(net_data->sv, net_data->res, NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -1,242 +1,336 @@
|
||||
/* $NetBSD: getservent_r.c,v 1.11 2011/10/15 23:00:02 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1998-1999 by Internet Software Consortium.
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
* 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. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: getservent_r.c,v 1.6 2006/08/01 01:14:16 marka Exp $";
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getservent_r.c,v 1.11 2011/10/15 23:00:02 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <port_before.h>
|
||||
#if !defined(_REENTRANT) || !defined(DO_PTHREADS)
|
||||
static int getservent_r_not_required = 0;
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <port_after.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SERV_R_RETURN
|
||||
#include <FindDirectory.h>
|
||||
|
||||
static SERV_R_RETURN
|
||||
copy_servent(struct servent *, struct servent *, SERV_R_COPY_ARGS);
|
||||
#include <libutil.h>
|
||||
#include "servent.h"
|
||||
|
||||
SERV_R_RETURN
|
||||
getservbyname_r(const char *name, const char *proto,
|
||||
struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservbyname(name, proto);
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(endservent_r,_endservent_r)
|
||||
__weak_alias(getservent_r,_getservent_r)
|
||||
__weak_alias(setservent_r,_setservent_r)
|
||||
#endif
|
||||
}
|
||||
|
||||
SERV_R_RETURN
|
||||
getservbyport_r(int port, const char *proto,
|
||||
struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservbyport(port, proto);
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*%
|
||||
* These assume a single context is in operation per thread.
|
||||
* If this is not the case we will need to call irs directly
|
||||
* rather than through the base functions.
|
||||
*/
|
||||
|
||||
SERV_R_RETURN
|
||||
getservent_r(struct servent *sptr, SERV_R_ARGS) {
|
||||
struct servent *se = getservent();
|
||||
#ifdef SERV_R_SETANSWER
|
||||
int n = 0;
|
||||
|
||||
if (se == NULL || (n = copy_servent(se, sptr, SERV_R_COPY)) != 0)
|
||||
*answerp = NULL;
|
||||
else
|
||||
*answerp = sptr;
|
||||
|
||||
return (n);
|
||||
#else
|
||||
if (se == NULL)
|
||||
return (SERV_R_BAD);
|
||||
|
||||
return (copy_servent(se, sptr, SERV_R_COPY));
|
||||
#endif
|
||||
}
|
||||
|
||||
SERV_R_SET_RETURN
|
||||
#ifdef SERV_R_ENT_ARGS
|
||||
setservent_r(int stay_open, SERV_R_ENT_ARGS)
|
||||
#else
|
||||
setservent_r(int stay_open)
|
||||
#endif
|
||||
int
|
||||
_servent_open(struct servent_data *sd)
|
||||
{
|
||||
#ifdef SERV_R_ENT_UNUSED
|
||||
SERV_R_ENT_UNUSED;
|
||||
#endif
|
||||
setservent(stay_open);
|
||||
#ifdef SERV_R_SET_RESULT
|
||||
return (SERV_R_SET_RESULT);
|
||||
char buffer[256];
|
||||
|
||||
if (sd->flags & (_SV_CDB | _SV_PLAINFILE)) {
|
||||
sd->flags |= _SV_FIRST;
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sd->line);
|
||||
sd->line = NULL;
|
||||
free(sd->cdb_buf);
|
||||
sd->cdb_buf = NULL;
|
||||
sd->cdb_buf_len = 0;
|
||||
free(sd->aliases);
|
||||
sd->aliases = NULL;
|
||||
sd->maxaliases = 0;
|
||||
sd->flags |= _SV_FIRST;
|
||||
|
||||
#if 0
|
||||
sd->cdb = cdbr_open(_PATH_SERVICES_CDB, CDBR_DEFAULT);
|
||||
if (sd->cdb != NULL) {
|
||||
sd->flags |= _SV_CDB;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
find_directory(B_SYSTEM_SETTINGS_DIRECTORY, 0, false, buffer, sizeof(buffer));
|
||||
strlcat(buffer, "/network/ports", sizeof(buffer));
|
||||
|
||||
sd->plainfile = fopen(buffer, "re");
|
||||
if (sd->plainfile != NULL) {
|
||||
sd->flags |= _SV_PLAINFILE;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
SERV_R_END_RETURN
|
||||
#ifdef SERV_R_ENT_ARGS
|
||||
endservent_r(SERV_R_ENT_ARGS)
|
||||
#else
|
||||
endservent_r()
|
||||
#endif
|
||||
void
|
||||
_servent_close(struct servent_data *sd)
|
||||
{
|
||||
#ifdef SERV_R_ENT_UNUSED
|
||||
SERV_R_ENT_UNUSED;
|
||||
#if 0
|
||||
if (sd->flags & _SV_CDB) {
|
||||
cdbr_close(sd->cdb);
|
||||
sd->cdb = NULL;
|
||||
sd->flags &= ~_SV_CDB;
|
||||
}
|
||||
#endif
|
||||
endservent();
|
||||
SERV_R_END_RESULT(SERV_R_OK);
|
||||
|
||||
if (sd->flags & _SV_PLAINFILE) {
|
||||
(void)fclose(sd->plainfile);
|
||||
sd->plainfile = NULL;
|
||||
sd->flags &= ~_SV_PLAINFILE;
|
||||
}
|
||||
sd->flags &= ~_SV_STAYOPEN;
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
#ifndef SERVENT_DATA
|
||||
static SERV_R_RETURN
|
||||
copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
|
||||
char *cp;
|
||||
int i, n;
|
||||
int numptr, len;
|
||||
int
|
||||
_servent_getline(struct servent_data *sd)
|
||||
{
|
||||
#if 0
|
||||
if (sd->flags & _SV_CDB)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
/* Find out the amount of space required to store the answer. */
|
||||
numptr = 1; /*%< NULL ptr */
|
||||
len = (char *)ALIGN(buf) - buf;
|
||||
for (i = 0; se->s_aliases[i]; i++, numptr++) {
|
||||
len += strlen(se->s_aliases[i]) + 1;
|
||||
if ((sd->flags & _SV_PLAINFILE) == 0)
|
||||
return -1;
|
||||
|
||||
free(sd->line);
|
||||
sd->line = NULL;
|
||||
|
||||
if (sd->flags & _SV_FIRST) {
|
||||
(void)rewind((FILE *)sd->plainfile);
|
||||
sd->flags &= ~_SV_FIRST;
|
||||
}
|
||||
len += strlen(se->s_name) + 1;
|
||||
len += strlen(se->s_proto) + 1;
|
||||
len += numptr * sizeof(char*);
|
||||
|
||||
if (len > (int)buflen) {
|
||||
errno = ERANGE;
|
||||
return (SERV_R_BAD);
|
||||
}
|
||||
|
||||
/* copy port value */
|
||||
sptr->s_port = se->s_port;
|
||||
|
||||
cp = (char *)ALIGN(buf) + numptr * sizeof(char *);
|
||||
|
||||
/* copy official name */
|
||||
n = strlen(se->s_name) + 1;
|
||||
strcpy(cp, se->s_name);
|
||||
sptr->s_name = cp;
|
||||
cp += n;
|
||||
|
||||
/* copy aliases */
|
||||
sptr->s_aliases = (char **)ALIGN(buf);
|
||||
for (i = 0 ; se->s_aliases[i]; i++) {
|
||||
n = strlen(se->s_aliases[i]) + 1;
|
||||
strcpy(cp, se->s_aliases[i]);
|
||||
sptr->s_aliases[i] = cp;
|
||||
cp += n;
|
||||
}
|
||||
sptr->s_aliases[i] = NULL;
|
||||
|
||||
/* copy proto */
|
||||
n = strlen(se->s_proto) + 1;
|
||||
strcpy(cp, se->s_proto);
|
||||
sptr->s_proto = cp;
|
||||
cp += n;
|
||||
|
||||
return (SERV_R_OK);
|
||||
sd->line = fparseln(sd->plainfile, NULL, NULL, NULL,
|
||||
FPARSELN_UNESCALL);
|
||||
return sd->line == NULL ? -1 : 0;
|
||||
}
|
||||
#else /* !SERVENT_DATA */
|
||||
static int
|
||||
copy_servent(struct servent *se, struct servent *sptr, SERV_R_COPY_ARGS) {
|
||||
char *cp, *eob;
|
||||
int i, n;
|
||||
|
||||
/* copy port value */
|
||||
sptr->s_port = se->s_port;
|
||||
struct servent *
|
||||
_servent_parseline(struct servent_data *sd, struct servent *sp)
|
||||
{
|
||||
size_t i = 0;
|
||||
int oerrno;
|
||||
char *p, *cp, **q;
|
||||
|
||||
/* copy official name */
|
||||
cp = sdptr->line;
|
||||
eob = sdptr->line + sizeof(sdptr->line);
|
||||
if ((n = strlen(se->s_name) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_name);
|
||||
sptr->s_name = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
}
|
||||
if (sd->line == NULL)
|
||||
return NULL;
|
||||
|
||||
/* copy aliases */
|
||||
i = 0;
|
||||
sptr->s_aliases = sdptr->serv_aliases;
|
||||
while (se->s_aliases[i] && i < (_MAXALIASES-1)) {
|
||||
if ((n = strlen(se->s_aliases[i]) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_aliases[i]);
|
||||
sptr->s_aliases[i] = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
break;
|
||||
sp->s_name = p = sd->line;
|
||||
p = strpbrk(p, " \t");
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
cp = strpbrk(p, ",/");
|
||||
if (cp == NULL)
|
||||
return NULL;
|
||||
*cp++ = '\0';
|
||||
sp->s_port = htons((u_short)atoi(p));
|
||||
sp->s_proto = cp;
|
||||
if (sd->aliases == NULL) {
|
||||
sd->maxaliases = 10;
|
||||
sd->aliases = calloc(sd->maxaliases, sizeof(*sd->aliases));
|
||||
if (sd->aliases == NULL) {
|
||||
oerrno = errno;
|
||||
endservent_r(sd);
|
||||
errno = oerrno;
|
||||
return NULL;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
sptr->s_aliases[i] = NULL;
|
||||
|
||||
/* copy proto */
|
||||
if ((n = strlen(se->s_proto) + 1) < (eob - cp)) {
|
||||
strcpy(cp, se->s_proto);
|
||||
sptr->s_proto = cp;
|
||||
cp += n;
|
||||
} else {
|
||||
return (-1);
|
||||
sp->s_aliases = sd->aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (i == sd->maxaliases - 2) {
|
||||
sd->maxaliases *= 2;
|
||||
q = realloc(sd->aliases, sd->maxaliases * sizeof(*q));
|
||||
if (q == NULL) {
|
||||
oerrno = errno;
|
||||
endservent_r(sd);
|
||||
errno = oerrno;
|
||||
return NULL;
|
||||
}
|
||||
sp->s_aliases = sd->aliases = q;
|
||||
}
|
||||
sp->s_aliases[i++] = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
|
||||
return (SERV_R_OK);
|
||||
sp->s_aliases[i] = NULL;
|
||||
return sp;
|
||||
}
|
||||
#endif /* !SERVENT_DATA */
|
||||
#else /*SERV_R_RETURN */
|
||||
static int getservent_r_unknown_system = 0;
|
||||
#endif /*SERV_R_RETURN */
|
||||
#endif /* !defined(_REENTRANT) || !defined(DO_PTHREADS) */
|
||||
/*! \file */
|
||||
|
||||
void
|
||||
setservent_r(int f, struct servent_data *sd)
|
||||
{
|
||||
(void)_servent_open(sd);
|
||||
sd->flags |= f ? _SV_STAYOPEN : 0;
|
||||
}
|
||||
|
||||
void
|
||||
endservent_r(struct servent_data *sd)
|
||||
{
|
||||
_servent_close(sd);
|
||||
free(sd->aliases);
|
||||
sd->aliases = NULL;
|
||||
sd->maxaliases = 0;
|
||||
free(sd->line);
|
||||
sd->line = NULL;
|
||||
free(sd->cdb_buf);
|
||||
sd->cdb_buf = NULL;
|
||||
sd->cdb_buf_len = 0;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservent_r(struct servent *sp, struct servent_data *sd)
|
||||
{
|
||||
|
||||
if ((sd->flags & (_SV_CDB | _SV_PLAINFILE)) == 0 &&
|
||||
_servent_open(sd) == -1)
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
if (sd->flags & _SV_CDB) {
|
||||
const void *data;
|
||||
size_t len;
|
||||
|
||||
if (sd->flags & _SV_FIRST) {
|
||||
sd->cdb_index = 0;
|
||||
sd->flags &= ~_SV_FIRST;
|
||||
}
|
||||
|
||||
if (cdbr_get(sd->cdb, sd->cdb_index, &data, &len))
|
||||
return NULL;
|
||||
++sd->cdb_index;
|
||||
return _servent_parsedb(sd, sp, data, len);
|
||||
}
|
||||
#endif
|
||||
if (sd->flags & _SV_PLAINFILE) {
|
||||
for (;;) {
|
||||
if (_servent_getline(sd) == -1)
|
||||
return NULL;
|
||||
if (_servent_parseline(sd, sp) == NULL)
|
||||
continue;
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
_servent_parsedb(struct servent_data *sd, struct servent *sp,
|
||||
const uint8_t *data, size_t len)
|
||||
{
|
||||
char **q;
|
||||
size_t i;
|
||||
int oerrno;
|
||||
|
||||
if ((sd->flags & _SV_STAYOPEN) == 0) {
|
||||
if (len > sd->cdb_buf_len) {
|
||||
void *tmp = realloc(sd->cdb_buf, len);
|
||||
if (tmp == NULL)
|
||||
goto fail;
|
||||
sd->cdb_buf = tmp;
|
||||
sd->cdb_buf_len = len;
|
||||
}
|
||||
memcpy(sd->cdb_buf, data, len);
|
||||
data = sd->cdb_buf;
|
||||
}
|
||||
|
||||
if (len < 2)
|
||||
goto fail;
|
||||
sp->s_port = *(uint16_t*)data;
|
||||
data += 2;
|
||||
len -= 2;
|
||||
|
||||
if (len == 0 || len < (size_t)data[0] + 2)
|
||||
goto fail;
|
||||
sp->s_proto = __UNCONST(data + 1);
|
||||
|
||||
if (sp->s_proto[data[0]] != '\0')
|
||||
goto fail;
|
||||
|
||||
len -= 2 + data[0];
|
||||
data += 2 + data[0];
|
||||
|
||||
if (len == 0)
|
||||
goto fail;
|
||||
if (len < (size_t)data[0] + 2)
|
||||
goto fail;
|
||||
|
||||
sp->s_name = __UNCONST(data + 1);
|
||||
len -= 2 + data[0];
|
||||
data += 2 + data[0];
|
||||
|
||||
if (sd->aliases == NULL) {
|
||||
sd->maxaliases = 10;
|
||||
sd->aliases = malloc(sd->maxaliases * sizeof(char *));
|
||||
if (sd->aliases == NULL)
|
||||
goto fail;
|
||||
}
|
||||
sp->s_aliases = sd->aliases;
|
||||
i = 0;
|
||||
while (len) {
|
||||
if (len < (size_t)data[0] + 2)
|
||||
goto fail;
|
||||
if (i == sd->maxaliases - 2) {
|
||||
sd->maxaliases *= 2;
|
||||
q = realloc(sd->aliases, sd->maxaliases * sizeof(*q));
|
||||
if (q == NULL)
|
||||
goto fail;
|
||||
sp->s_aliases = sd->aliases = q;
|
||||
}
|
||||
sp->s_aliases[i++] = __UNCONST(data + 1);
|
||||
len -= 2 + data[0];
|
||||
data += 2 + data[0];
|
||||
}
|
||||
sp->s_aliases[i] = NULL;
|
||||
return sp;
|
||||
|
||||
fail:
|
||||
oerrno = errno;
|
||||
endservent_r(sd);
|
||||
errno = oerrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,505 +1,636 @@
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: hesiod.c,v 1.7 2005/07/28 06:51:48 marka Exp $";
|
||||
#endif
|
||||
/* $NetBSD: hesiod.c,v 1.27 2012/03/20 17:44:18 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* hesiod.c --- the core portion of the hesiod resolver.
|
||||
/* Copyright 1996 by the Massachusetts Institute of Technology.
|
||||
*
|
||||
* This file is derived from the hesiod library from Project Athena;
|
||||
* It has been extensively rewritten by Theodore Ts'o to have a more
|
||||
* thread-safe interface.
|
||||
* \author
|
||||
* This file is primarily maintained by <tytso@mit.edu> and <ghudson@mit.edu>.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose and without
|
||||
* fee is hereby granted, provided that the above copyright
|
||||
* notice appear in all copies and that both that copyright
|
||||
* notice and this permission notice appear in supporting
|
||||
* documentation, and that the name of M.I.T. not be used in
|
||||
* advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission.
|
||||
* M.I.T. makes no representations about the suitability of
|
||||
* this software for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*/
|
||||
|
||||
/* Imports */
|
||||
/* This file is part of the hesiod library. It implements the core
|
||||
* portion of the hesiod resolver.
|
||||
*
|
||||
* This file is loosely based on an interim version of hesiod.c from
|
||||
* the BIND IRS library, which was in turn based on an earlier version
|
||||
* of this file. Extensive changes have been made on each step of the
|
||||
* path.
|
||||
*
|
||||
* This implementation is thread-safe because it uses res_nsend().
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__IDSTRING(rcsid_hesiod_c,
|
||||
"#Id: hesiod.c,v 1.18.2.1 1997/01/03 20:48:20 ghudson Exp #");
|
||||
__IDSTRING(rcsid_hesiod_p_h,
|
||||
"#Id: hesiod_p.h,v 1.1 1996/12/08 21:39:37 ghudson Exp #");
|
||||
__IDSTRING(rcsid_hescompat_c,
|
||||
"#Id: hescompat.c,v 1.1.2.1 1996/12/16 08:37:45 ghudson Exp #");
|
||||
__RCSID("$NetBSD: hesiod.c,v 1.27 2012/03/20 17:44:18 matt Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <hesiod.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "port_after.h"
|
||||
#include <libutil.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "hesiod.h"
|
||||
#include "hesiod_p.h"
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(hesiod_init,_hesiod_init)
|
||||
__weak_alias(hesiod_end,_hesiod_end)
|
||||
__weak_alias(hesiod_to_bind,_hesiod_to_bind)
|
||||
__weak_alias(hesiod_resolve,_hesiod_resolve)
|
||||
__weak_alias(hesiod_free_list,_hesiod_free_list)
|
||||
__weak_alias(hes_init,_hes_init)
|
||||
__weak_alias(hes_to_bind,_hes_to_bind)
|
||||
__weak_alias(hes_resolve,_hes_resolve)
|
||||
__weak_alias(hes_error,_hes_error)
|
||||
__weak_alias(hes_free,_hes_free)
|
||||
#endif
|
||||
|
||||
/* Forward */
|
||||
struct hesiod_p {
|
||||
char *lhs; /* normally ".ns" */
|
||||
char *rhs; /* AKA the default hesiod domain */
|
||||
int classes[2]; /* The class search order. */
|
||||
};
|
||||
|
||||
int hesiod_init(void **context);
|
||||
void hesiod_end(void *context);
|
||||
char * hesiod_to_bind(void *context, const char *name,
|
||||
const char *type);
|
||||
char ** hesiod_resolve(void *context, const char *name,
|
||||
const char *type);
|
||||
void hesiod_free_list(void *context, char **list);
|
||||
#define MAX_HESRESP 1024
|
||||
|
||||
static int parse_config_file(struct hesiod_p *ctx, const char *filename);
|
||||
static char ** get_txt_records(struct hesiod_p *ctx, int class,
|
||||
const char *name);
|
||||
static int init(struct hesiod_p *ctx);
|
||||
static int read_config_file(struct hesiod_p *, const char *);
|
||||
static char **get_txt_records(int, const char *);
|
||||
static int init_context(void);
|
||||
static void translate_errors(void);
|
||||
|
||||
/* Public */
|
||||
|
||||
/*%
|
||||
* This function is called to initialize a hesiod_p.
|
||||
/*
|
||||
* hesiod_init --
|
||||
* initialize a hesiod_p.
|
||||
*/
|
||||
int
|
||||
hesiod_init(void **context) {
|
||||
struct hesiod_p *ctx;
|
||||
char *cp;
|
||||
hesiod_init(void **context)
|
||||
{
|
||||
struct hesiod_p *ctx;
|
||||
const char *p, *configname;
|
||||
int serrno;
|
||||
|
||||
ctx = malloc(sizeof(struct hesiod_p));
|
||||
if (ctx == 0) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
assert(context != NULL);
|
||||
|
||||
memset(ctx, 0, sizeof (*ctx));
|
||||
|
||||
if (parse_config_file(ctx, _PATH_HESIOD_CONF) < 0) {
|
||||
#ifdef DEF_RHS
|
||||
ctx = calloc(1, sizeof(struct hesiod_p));
|
||||
if (ctx) {
|
||||
*context = ctx;
|
||||
/*
|
||||
* Use compiled in defaults.
|
||||
* don't permit overrides from environment
|
||||
* for set.id programs
|
||||
*/
|
||||
ctx->LHS = malloc(strlen(DEF_LHS) + 1);
|
||||
ctx->RHS = malloc(strlen(DEF_RHS) + 1);
|
||||
if (ctx->LHS == NULL || ctx->RHS == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
strcpy(ctx->LHS, DEF_LHS); /* (checked) */
|
||||
strcpy(ctx->RHS, DEF_RHS); /* (checked) */
|
||||
#else
|
||||
goto cleanup;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* The default RHS can be overridden by an environment
|
||||
* variable.
|
||||
*/
|
||||
if ((cp = getenv("HES_DOMAIN")) != NULL) {
|
||||
size_t RHSlen = strlen(cp) + 2;
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
ctx->RHS = malloc(RHSlen);
|
||||
if (!ctx->RHS) {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
if (cp[0] == '.') {
|
||||
strcpy(ctx->RHS, cp); /* (checked) */
|
||||
} else {
|
||||
strcpy(ctx->RHS, "."); /* (checked) */
|
||||
strcat(ctx->RHS, cp); /* (checked) */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no default hesiod realm set, we return an
|
||||
* error.
|
||||
*/
|
||||
if (!ctx->RHS) {
|
||||
errno = ENOEXEC;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (res_ninit(ctx->res) < 0)
|
||||
goto cleanup;
|
||||
if (issetugid())
|
||||
configname = NULL;
|
||||
else
|
||||
#endif
|
||||
configname = getenv("HESIOD_CONFIG");
|
||||
if (!configname)
|
||||
configname = _PATH_HESIOD_CONF;
|
||||
if (read_config_file(ctx, configname) >= 0) {
|
||||
/*
|
||||
* The default rhs can be overridden by an
|
||||
* environment variable, unless set.id.
|
||||
*/
|
||||
#if 0
|
||||
if (issetugid())
|
||||
p = NULL;
|
||||
else
|
||||
#endif
|
||||
p = getenv("HES_DOMAIN");
|
||||
if (p) {
|
||||
if (ctx->rhs)
|
||||
free(ctx->rhs);
|
||||
ctx->rhs = malloc(strlen(p) + 2);
|
||||
if (ctx->rhs) {
|
||||
*ctx->rhs = '.';
|
||||
strcpy(ctx->rhs + 1,
|
||||
(*p == '.') ? p + 1 : p);
|
||||
return 0;
|
||||
} else
|
||||
errno = ENOMEM;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
errno = ENOMEM;
|
||||
|
||||
*context = ctx;
|
||||
return (0);
|
||||
|
||||
cleanup:
|
||||
hesiod_end(ctx);
|
||||
return (-1);
|
||||
serrno = errno;
|
||||
if (ctx) {
|
||||
if (ctx->lhs)
|
||||
free(ctx->lhs);
|
||||
if (ctx->rhs)
|
||||
free(ctx->rhs);
|
||||
free(ctx);
|
||||
}
|
||||
errno = serrno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*%
|
||||
* This function deallocates the hesiod_p
|
||||
/*
|
||||
* hesiod_end --
|
||||
* Deallocates the hesiod_p.
|
||||
*/
|
||||
void
|
||||
hesiod_end(void *context) {
|
||||
hesiod_end(void *context)
|
||||
{
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
int save_errno = errno;
|
||||
|
||||
if (ctx->res)
|
||||
res_nclose(ctx->res);
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
if (ctx->res && ctx->free_res)
|
||||
(*ctx->free_res)(ctx->res);
|
||||
assert(context != NULL);
|
||||
|
||||
free(ctx->rhs);
|
||||
if (ctx->lhs)
|
||||
free(ctx->lhs);
|
||||
free(ctx);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
/*%
|
||||
* This function takes a hesiod (name, type) and returns a DNS
|
||||
* name which is to be resolved.
|
||||
/*
|
||||
* hesiod_to_bind --
|
||||
* takes a hesiod (name, type) and returns a DNS
|
||||
* name which is to be resolved.
|
||||
*/
|
||||
char *
|
||||
hesiod_to_bind(void *context, const char *name, const char *type) {
|
||||
hesiod_to_bind(void *context, const char *name, const char *type)
|
||||
{
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
char *bindname;
|
||||
char **rhs_list = NULL;
|
||||
const char *RHS, *cp;
|
||||
char bindname[MAXDNAME], *p, *ret, **rhs_list = NULL;
|
||||
const char *rhs;
|
||||
size_t len;
|
||||
|
||||
/* Decide what our RHS is, and set cp to the end of the actual name. */
|
||||
if ((cp = strchr(name, '@')) != NULL) {
|
||||
if (strchr(cp + 1, '.'))
|
||||
RHS = cp + 1;
|
||||
else if ((rhs_list = hesiod_resolve(context, cp + 1,
|
||||
"rhs-extension")) != NULL)
|
||||
RHS = *rhs_list;
|
||||
else {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
RHS = ctx->RHS;
|
||||
cp = name + strlen(name);
|
||||
}
|
||||
assert(context != NULL);
|
||||
assert(name != NULL);
|
||||
assert(type != NULL);
|
||||
|
||||
if (strlcpy(bindname, name, sizeof(bindname)) >= sizeof(bindname)) {
|
||||
errno = EMSGSIZE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the space we need, including up to three periods and
|
||||
* the terminating NUL.
|
||||
* Find the right right hand side to use, possibly
|
||||
* truncating bindname.
|
||||
*/
|
||||
if ((bindname = malloc((cp - name) + strlen(type) + strlen(RHS) +
|
||||
(ctx->LHS ? strlen(ctx->LHS) : 0) + 4)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
p = strchr(bindname, '@');
|
||||
if (p) {
|
||||
*p++ = 0;
|
||||
if (strchr(p, '.'))
|
||||
rhs = name + (p - bindname);
|
||||
else {
|
||||
rhs_list = hesiod_resolve(context, p, "rhs-extension");
|
||||
if (rhs_list)
|
||||
rhs = *rhs_list;
|
||||
else {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else
|
||||
rhs = ctx->rhs;
|
||||
|
||||
/* See if we have enough room. */
|
||||
len = strlen(bindname) + 1 + strlen(type);
|
||||
if (ctx->lhs)
|
||||
len += strlen(ctx->lhs) + ((ctx->lhs[0] != '.') ? 1 : 0);
|
||||
len += strlen(rhs) + ((rhs[0] != '.') ? 1 : 0);
|
||||
if (len > sizeof(bindname) - 1) {
|
||||
if (rhs_list)
|
||||
hesiod_free_list(context, rhs_list);
|
||||
errno = EMSGSIZE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now put together the DNS name. */
|
||||
memcpy(bindname, name, cp - name);
|
||||
bindname[cp - name] = '\0';
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, type);
|
||||
if (ctx->LHS) {
|
||||
if (ctx->LHS[0] != '.')
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, ctx->LHS);
|
||||
/* Put together the rest of the domain. */
|
||||
strlcat(bindname, ".", sizeof(bindname));
|
||||
strlcat(bindname, type, sizeof(bindname));
|
||||
/* Only append lhs if it isn't empty. */
|
||||
if (ctx->lhs && ctx->lhs[0] != '\0' ) {
|
||||
if (ctx->lhs[0] != '.')
|
||||
strlcat(bindname, ".", sizeof(bindname));
|
||||
strlcat(bindname, ctx->lhs, sizeof(bindname));
|
||||
}
|
||||
if (RHS[0] != '.')
|
||||
strcat(bindname, ".");
|
||||
strcat(bindname, RHS);
|
||||
if (rhs[0] != '.')
|
||||
strlcat(bindname, ".", sizeof(bindname));
|
||||
strlcat(bindname, rhs, sizeof(bindname));
|
||||
|
||||
/* rhs_list is no longer needed, since we're done with rhs. */
|
||||
if (rhs_list)
|
||||
hesiod_free_list(context, rhs_list);
|
||||
|
||||
return (bindname);
|
||||
/* Make a copy of the result and return it to the caller. */
|
||||
ret = strdup(bindname);
|
||||
if (ret == NULL)
|
||||
errno = ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*%
|
||||
* This is the core function. Given a hesiod (name, type), it
|
||||
* returns an array of strings returned by the resolver.
|
||||
/*
|
||||
* hesiod_resolve --
|
||||
* Given a hesiod name and type, return an array of strings returned
|
||||
* by the resolver.
|
||||
*/
|
||||
char **
|
||||
hesiod_resolve(void *context, const char *name, const char *type) {
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
char *bindname = hesiod_to_bind(context, name, type);
|
||||
char **retvec;
|
||||
hesiod_resolve(void *context, const char *name, const char *type)
|
||||
{
|
||||
struct hesiod_p *ctx = (struct hesiod_p *) context;
|
||||
char *bindname, **retvec;
|
||||
|
||||
if (bindname == NULL)
|
||||
return (NULL);
|
||||
if (init(ctx) == -1) {
|
||||
free(bindname);
|
||||
return (NULL);
|
||||
}
|
||||
assert(context != NULL);
|
||||
assert(name != NULL);
|
||||
assert(type != NULL);
|
||||
|
||||
if ((retvec = get_txt_records(ctx, C_IN, bindname))) {
|
||||
free(bindname);
|
||||
return (retvec);
|
||||
}
|
||||
bindname = hesiod_to_bind(context, name, type);
|
||||
if (!bindname)
|
||||
return NULL;
|
||||
|
||||
if (errno != ENOENT)
|
||||
return (NULL);
|
||||
retvec = get_txt_records(ctx->classes[0], bindname);
|
||||
if (retvec == NULL && errno == ENOENT && ctx->classes[1])
|
||||
retvec = get_txt_records(ctx->classes[1], bindname);
|
||||
|
||||
retvec = get_txt_records(ctx, C_HS, bindname);
|
||||
free(bindname);
|
||||
return (retvec);
|
||||
return retvec;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
void
|
||||
hesiod_free_list(void *context, char **list) {
|
||||
char **p;
|
||||
hesiod_free_list(void *context, char **list)
|
||||
{
|
||||
char **p;
|
||||
|
||||
UNUSED(context);
|
||||
assert(context != NULL);
|
||||
|
||||
if (list == NULL)
|
||||
return;
|
||||
for (p = list; *p; p++)
|
||||
free(*p);
|
||||
free(list);
|
||||
}
|
||||
|
||||
/*%
|
||||
* This function parses the /etc/hesiod.conf file
|
||||
|
||||
/* read_config_file --
|
||||
* Parse the /etc/hesiod.conf file. Returns 0 on success,
|
||||
* -1 on failure. On failure, it might leave values in ctx->lhs
|
||||
* or ctx->rhs which need to be freed by the caller.
|
||||
*/
|
||||
static int
|
||||
parse_config_file(struct hesiod_p *ctx, const char *filename) {
|
||||
char *key, *data, *cp, **cpp;
|
||||
char buf[MAXDNAME+7];
|
||||
FILE *fp;
|
||||
read_config_file(struct hesiod_p *ctx, const char *filename)
|
||||
{
|
||||
char *buf, *key, *data, *p, **which;
|
||||
int n;
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Clear the existing configuration variable, just in case
|
||||
* they're set.
|
||||
*/
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
ctx->RHS = ctx->LHS = 0;
|
||||
assert(ctx != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
/*
|
||||
* Now open and parse the file...
|
||||
*/
|
||||
if (!(fp = fopen(filename, "r")))
|
||||
return (-1);
|
||||
/* Set default query classes. */
|
||||
ctx->classes[0] = C_IN;
|
||||
ctx->classes[1] = C_HS;
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
cp = buf;
|
||||
if (*cp == '#' || *cp == '\n' || *cp == '\r')
|
||||
continue;
|
||||
while(*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
key = cp;
|
||||
while(*cp != ' ' && *cp != '\t' && *cp != '=')
|
||||
cp++;
|
||||
*cp++ = '\0';
|
||||
|
||||
while(*cp == ' ' || *cp == '\t' || *cp == '=')
|
||||
cp++;
|
||||
data = cp;
|
||||
while(*cp != ' ' && *cp != '\n' && *cp != '\r')
|
||||
cp++;
|
||||
*cp++ = '\0';
|
||||
|
||||
if (strcmp(key, "lhs") == 0)
|
||||
cpp = &ctx->LHS;
|
||||
else if (strcmp(key, "rhs") == 0)
|
||||
cpp = &ctx->RHS;
|
||||
else
|
||||
continue;
|
||||
|
||||
*cpp = malloc(strlen(data) + 1);
|
||||
if (!*cpp) {
|
||||
/* Try to open the configuration file. */
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp) {
|
||||
/* Use compiled in default domain names. */
|
||||
ctx->lhs = strdup(DEF_LHS);
|
||||
ctx->rhs = strdup(DEF_RHS);
|
||||
if (ctx->lhs && ctx->rhs)
|
||||
return 0;
|
||||
else {
|
||||
errno = ENOMEM;
|
||||
goto cleanup;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ctx->lhs = NULL;
|
||||
ctx->rhs = NULL;
|
||||
for (; (buf = fparseln(fp, NULL, NULL, NULL, FPARSELN_UNESCALL))
|
||||
!= NULL; free(buf)) {
|
||||
p = buf;
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
key = p;
|
||||
while (*p != ' ' && *p != '\t' && *p != '=' && *p)
|
||||
p++;
|
||||
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
|
||||
*p++ = 0;
|
||||
|
||||
while (isspace((u_char) *p) || *p == '=')
|
||||
p++;
|
||||
|
||||
if (*p == '\0')
|
||||
continue;
|
||||
|
||||
data = p;
|
||||
while (!isspace((u_char) *p) && *p)
|
||||
p++;
|
||||
|
||||
*p = 0;
|
||||
|
||||
if (strcasecmp(key, "lhs") == 0 ||
|
||||
strcasecmp(key, "rhs") == 0) {
|
||||
which = (strcasecmp(key, "lhs") == 0)
|
||||
? &ctx->lhs : &ctx->rhs;
|
||||
*which = strdup(data);
|
||||
if (!*which) {
|
||||
errno = ENOMEM;
|
||||
free(buf);
|
||||
(void)fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (strcasecmp(key, "classes") == 0) {
|
||||
n = 0;
|
||||
while (*data && n < 2) {
|
||||
p = data;
|
||||
while (*p && *p != ',')
|
||||
p++;
|
||||
if (*p)
|
||||
*p++ = 0;
|
||||
if (strcasecmp(data, "IN") == 0)
|
||||
ctx->classes[n++] = C_IN;
|
||||
else
|
||||
if (strcasecmp(data, "HS") == 0)
|
||||
ctx->classes[n++] =
|
||||
C_HS;
|
||||
data = p;
|
||||
}
|
||||
while (n < 2)
|
||||
ctx->classes[n++] = 0;
|
||||
}
|
||||
}
|
||||
strcpy(*cpp, data);
|
||||
}
|
||||
fclose(fp);
|
||||
return (0);
|
||||
|
||||
cleanup:
|
||||
fclose(fp);
|
||||
if (ctx->RHS)
|
||||
free(ctx->RHS);
|
||||
if (ctx->LHS)
|
||||
free(ctx->LHS);
|
||||
ctx->RHS = ctx->LHS = 0;
|
||||
return (-1);
|
||||
if (!ctx->rhs || ctx->classes[0] == 0 ||
|
||||
ctx->classes[0] == ctx->classes[1]) {
|
||||
errno = ENOEXEC;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Given a DNS class and a DNS name, do a lookup for TXT records, and
|
||||
* return a list of them.
|
||||
/*
|
||||
* get_txt_records --
|
||||
* Given a DNS class and a DNS name, do a lookup for TXT records, and
|
||||
* return a list of them.
|
||||
*/
|
||||
static char **
|
||||
get_txt_records(struct hesiod_p *ctx, int class, const char *name) {
|
||||
struct {
|
||||
int type; /*%< RR type */
|
||||
int class; /*%< RR class */
|
||||
int dlen; /*%< len of data section */
|
||||
u_char *data; /*%< pointer to data */
|
||||
} rr;
|
||||
HEADER *hp;
|
||||
u_char qbuf[MAX_HESRESP], abuf[MAX_HESRESP];
|
||||
u_char *cp, *erdata, *eom;
|
||||
char *dst, *edst, **list;
|
||||
int ancount, qdcount;
|
||||
int i, j, n, skip;
|
||||
get_txt_records(int qclass, const char *name)
|
||||
{
|
||||
HEADER *hp;
|
||||
unsigned char qbuf[PACKETSZ], abuf[MAX_HESRESP], *p, *eom, *eor;
|
||||
char *dst, **list;
|
||||
int ancount, qdcount, i, j, n, skip, type, class, len;
|
||||
res_state res = __res_get_state();
|
||||
|
||||
/*
|
||||
* Construct the query and send it.
|
||||
*/
|
||||
n = res_nmkquery(ctx->res, QUERY, name, class, T_TXT, NULL, 0,
|
||||
NULL, qbuf, MAX_HESRESP);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
|
||||
assert(name != NULL);
|
||||
|
||||
/* Construct the query. */
|
||||
n = res_nmkquery(res, QUERY, name, qclass, T_TXT, NULL, 0,
|
||||
NULL, qbuf, PACKETSZ);
|
||||
if (n < 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
__res_put_state(res);
|
||||
return NULL;
|
||||
}
|
||||
n = res_nsend(ctx->res, qbuf, n, abuf, MAX_HESRESP);
|
||||
|
||||
/* Send the query. */
|
||||
n = res_nsend(res, qbuf, n, abuf, MAX_HESRESP);
|
||||
__res_put_state(res);
|
||||
if (n < 0) {
|
||||
errno = ECONNREFUSED;
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
if (n < HFIXEDSZ) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* OK, parse the result.
|
||||
*/
|
||||
hp = (HEADER *) abuf;
|
||||
/* Parse the header of the result. */
|
||||
hp = (HEADER *) (void *) abuf;
|
||||
ancount = ntohs(hp->ancount);
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
cp = abuf + sizeof(HEADER);
|
||||
p = abuf + sizeof(HEADER);
|
||||
eom = abuf + n;
|
||||
|
||||
/* Skip query, trying to get to the answer section which follows. */
|
||||
/*
|
||||
* Skip questions, trying to get to the answer section
|
||||
* which follows.
|
||||
*/
|
||||
for (i = 0; i < qdcount; i++) {
|
||||
skip = dn_skipname(cp, eom);
|
||||
if (skip < 0 || cp + skip + QFIXEDSZ > eom) {
|
||||
skip = dn_skipname(p, eom);
|
||||
if (skip < 0 || p + skip + QFIXEDSZ > eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
cp += skip + QFIXEDSZ;
|
||||
p += skip + QFIXEDSZ;
|
||||
}
|
||||
|
||||
/* Allocate space for the text record answers. */
|
||||
list = malloc((ancount + 1) * sizeof(char *));
|
||||
if (!list) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
return NULL;
|
||||
}
|
||||
/* Parse the answers. */
|
||||
j = 0;
|
||||
for (i = 0; i < ancount; i++) {
|
||||
skip = dn_skipname(cp, eom);
|
||||
if (skip < 0) {
|
||||
/* Parse the header of this answer. */
|
||||
skip = dn_skipname(p, eom);
|
||||
if (skip < 0 || p + skip + 10 > eom)
|
||||
break;
|
||||
type = p[skip + 0] << 8 | p[skip + 1];
|
||||
class = p[skip + 2] << 8 | p[skip + 3];
|
||||
len = p[skip + 8] << 8 | p[skip + 9];
|
||||
p += skip + 10;
|
||||
if (p + len > eom) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
break;
|
||||
}
|
||||
cp += skip;
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
rr.type = ns_get16(cp);
|
||||
cp += INT16SZ;
|
||||
rr.class = ns_get16(cp);
|
||||
cp += INT16SZ + INT32SZ; /*%< skip the ttl, too */
|
||||
rr.dlen = ns_get16(cp);
|
||||
cp += INT16SZ;
|
||||
if (cp + rr.dlen > eom) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
}
|
||||
rr.data = cp;
|
||||
cp += rr.dlen;
|
||||
if (rr.class != class || rr.type != T_TXT)
|
||||
/* Skip entries of the wrong class and type. */
|
||||
if (class != qclass || type != T_TXT) {
|
||||
p += len;
|
||||
continue;
|
||||
if (!(list[j] = malloc(rr.dlen)))
|
||||
goto cleanup;
|
||||
}
|
||||
/* Allocate space for this answer. */
|
||||
list[j] = malloc((size_t)len);
|
||||
if (!list[j]) {
|
||||
errno = ENOMEM;
|
||||
break;
|
||||
}
|
||||
dst = list[j++];
|
||||
edst = dst + rr.dlen;
|
||||
erdata = rr.data + rr.dlen;
|
||||
cp = rr.data;
|
||||
while (cp < erdata) {
|
||||
n = (unsigned char) *cp++;
|
||||
if (cp + n > eom || dst + n > edst) {
|
||||
|
||||
/* Copy answer data into the allocated area. */
|
||||
eor = p + len;
|
||||
while (p < eor) {
|
||||
n = (unsigned char) *p++;
|
||||
if (p + n > eor) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
break;
|
||||
}
|
||||
memcpy(dst, cp, n);
|
||||
cp += n;
|
||||
memcpy(dst, p, (size_t)n);
|
||||
p += n;
|
||||
dst += n;
|
||||
}
|
||||
if (cp != erdata) {
|
||||
if (p < eor) {
|
||||
errno = EMSGSIZE;
|
||||
goto cleanup;
|
||||
break;
|
||||
}
|
||||
*dst = '\0';
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we didn't terminate the loop normally, something
|
||||
* went wrong.
|
||||
*/
|
||||
if (i < ancount) {
|
||||
for (i = 0; i < j; i++)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
list[j] = NULL;
|
||||
if (j == 0) {
|
||||
errno = ENOENT;
|
||||
goto cleanup;
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
return (list);
|
||||
|
||||
cleanup:
|
||||
for (i = 0; i < j; i++)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
return (NULL);
|
||||
list[j] = NULL;
|
||||
return list;
|
||||
}
|
||||
|
||||
struct __res_state *
|
||||
__hesiod_res_get(void *context) {
|
||||
struct hesiod_p *ctx = context;
|
||||
/*
|
||||
* COMPATIBILITY FUNCTIONS
|
||||
*/
|
||||
|
||||
if (!ctx->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
__hesiod_res_set(ctx, res, free);
|
||||
}
|
||||
static int inited = 0;
|
||||
static void *context;
|
||||
static int errval = HES_ER_UNINIT;
|
||||
|
||||
return (ctx->res);
|
||||
int
|
||||
hes_init(void)
|
||||
{
|
||||
init_context();
|
||||
return errval;
|
||||
}
|
||||
|
||||
char *
|
||||
hes_to_bind(const char *name, const char *type)
|
||||
{
|
||||
static char *bindname;
|
||||
|
||||
assert(name != NULL);
|
||||
assert(type != NULL);
|
||||
|
||||
if (init_context() < 0)
|
||||
return NULL;
|
||||
if (bindname)
|
||||
free(bindname);
|
||||
bindname = hesiod_to_bind(context, name, type);
|
||||
if (!bindname)
|
||||
translate_errors();
|
||||
return bindname;
|
||||
}
|
||||
|
||||
char **
|
||||
hes_resolve(const char *name, const char *type)
|
||||
{
|
||||
static char **list;
|
||||
|
||||
assert(name != NULL);
|
||||
assert(type != NULL);
|
||||
|
||||
if (init_context() < 0)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* In the old Hesiod interface, the caller was responsible for
|
||||
* freeing the returned strings but not the vector of strings itself.
|
||||
*/
|
||||
if (list)
|
||||
free(list);
|
||||
|
||||
list = hesiod_resolve(context, name, type);
|
||||
if (!list)
|
||||
translate_errors();
|
||||
return list;
|
||||
}
|
||||
|
||||
int
|
||||
hes_error(void)
|
||||
{
|
||||
return errval;
|
||||
}
|
||||
|
||||
void
|
||||
__hesiod_res_set(void *context, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct hesiod_p *ctx = context;
|
||||
|
||||
if (ctx->res && ctx->free_res) {
|
||||
res_nclose(ctx->res);
|
||||
(*ctx->free_res)(ctx->res);
|
||||
}
|
||||
|
||||
ctx->res = res;
|
||||
ctx->free_res = free_res;
|
||||
hes_free(char **hp)
|
||||
{
|
||||
hesiod_free_list(context, hp);
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct hesiod_p *ctx) {
|
||||
|
||||
if (!ctx->res && !__hesiod_res_get(ctx))
|
||||
return (-1);
|
||||
|
||||
if (((ctx->res->options & RES_INIT) == 0U) &&
|
||||
(res_ninit(ctx->res) == -1))
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
init_context(void)
|
||||
{
|
||||
if (!inited) {
|
||||
inited = 1;
|
||||
if (hesiod_init(&context) < 0) {
|
||||
errval = HES_ER_CONFIG;
|
||||
return -1;
|
||||
}
|
||||
errval = HES_ER_OK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
translate_errors(void)
|
||||
{
|
||||
switch (errno) {
|
||||
case ENOENT:
|
||||
errval = HES_ER_NOTFOUND;
|
||||
break;
|
||||
case ECONNREFUSED:
|
||||
case EMSGSIZE:
|
||||
errval = HES_ER_NET;
|
||||
break;
|
||||
default:
|
||||
/* Not a good match, but the best we can do. */
|
||||
errval = HES_ER_CONFIG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: hesiod_p.h,v 1.3 2005/04/27 04:56:27 sra Exp $
|
||||
*/
|
||||
|
||||
#ifndef _HESIOD_P_H_INCLUDED
|
||||
#define _HESIOD_P_H_INCLUDED
|
||||
|
||||
/** \file
|
||||
* \brief
|
||||
* hesiod_p.h -- private definitions for the hesiod library.
|
||||
*
|
||||
* \author
|
||||
* This file is primarily maintained by tytso@mit.edu and ghudson@mit.edu.
|
||||
*/
|
||||
|
||||
#define DEF_RHS ".Athena.MIT.EDU" /*%< Defaults if HESIOD_CONF */
|
||||
#define DEF_LHS ".ns" /*%< file is not */
|
||||
/*%< present. */
|
||||
struct hesiod_p {
|
||||
char * LHS; /*%< normally ".ns" */
|
||||
char * RHS; /*%< AKA the default hesiod domain */
|
||||
struct __res_state * res; /*%< resolver context */
|
||||
void (*free_res)(void *);
|
||||
void (*res_set)(struct hesiod_p *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
struct __res_state * (*res_get)(struct hesiod_p *);
|
||||
};
|
||||
|
||||
#define MAX_HESRESP 1024
|
||||
|
||||
#endif /*_HESIOD_P_H_INCLUDED*/
|
||||
@@ -1,583 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (C) 1996, 1998-2001, 2003 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
||||
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irp.c,v 1.12 2008/11/14 02:36:51 marka Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void irp_close(struct irs_acc *);
|
||||
|
||||
#define LINEINCR 128
|
||||
|
||||
#if !defined(SUN_LEN)
|
||||
#define SUN_LEN(su) \
|
||||
(sizeof (*(su)) - sizeof ((su)->sun_path) + strlen((su)->sun_path))
|
||||
#endif
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
|
||||
/* send errors to syslog if true. */
|
||||
int irp_log_errors = 1;
|
||||
|
||||
/*%
|
||||
* This module handles the irp module connection to irpd.
|
||||
*
|
||||
* The client expects a synchronous interface to functions like
|
||||
* getpwnam(3), so we can't use the ctl_* i/o library on this end of
|
||||
* the wire (it's used in the server).
|
||||
*/
|
||||
|
||||
/*%
|
||||
* irs_acc *irs_irp_acc(const char *options);
|
||||
*
|
||||
* Initialize the irp module.
|
||||
*/
|
||||
struct irs_acc *
|
||||
irs_irp_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct irp_p *irp;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(irp = memget(sizeof *irp))) {
|
||||
errno = ENOMEM;
|
||||
free(acc);
|
||||
return (NULL);
|
||||
}
|
||||
irp->inlast = 0;
|
||||
irp->incurr = 0;
|
||||
irp->fdCxn = -1;
|
||||
acc->private = irp;
|
||||
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_irp_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_irp_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_irp_sv;
|
||||
acc->pr_map = irs_irp_pr;
|
||||
acc->ho_map = irs_irp_ho;
|
||||
acc->nw_map = irs_irp_nw;
|
||||
acc->ng_map = irs_irp_ng;
|
||||
acc->close = irp_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
irs_irp_connection_setup(struct irp_p *cxndata, int *warned) {
|
||||
if (irs_irp_is_connected(cxndata)) {
|
||||
return (0);
|
||||
} else if (irs_irp_connect(cxndata) != 0) {
|
||||
if (warned != NULL && !*warned) {
|
||||
syslog(LOG_ERR, "irpd connection failed: %m\n");
|
||||
(*warned)++;
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*%
|
||||
* int irs_irp_connect(void);
|
||||
*
|
||||
* Sets up the connection to the remote irpd server.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 on success, -1 on failure.
|
||||
*
|
||||
*/
|
||||
int
|
||||
irs_irp_connect(struct irp_p *pvt) {
|
||||
int flags;
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr_in iaddr;
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
struct sockaddr_un uaddr;
|
||||
#endif
|
||||
long ipaddr;
|
||||
const char *irphost;
|
||||
int code;
|
||||
char text[256];
|
||||
int socklen = 0;
|
||||
|
||||
if (pvt->fdCxn != -1) {
|
||||
perror("fd != 1");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
memset(&uaddr, 0, sizeof uaddr);
|
||||
#endif
|
||||
memset(&iaddr, 0, sizeof iaddr);
|
||||
|
||||
irphost = getenv(IRPD_HOST_ENV);
|
||||
if (irphost == NULL) {
|
||||
irphost = "127.0.0.1";
|
||||
}
|
||||
|
||||
#ifndef NO_SOCKADDR_UN
|
||||
if (irphost[0] == '/') {
|
||||
addr = (struct sockaddr *)&uaddr;
|
||||
strncpy(uaddr.sun_path, irphost, sizeof uaddr.sun_path);
|
||||
uaddr.sun_family = AF_UNIX;
|
||||
socklen = SUN_LEN(&uaddr);
|
||||
#ifdef HAVE_SA_LEN
|
||||
uaddr.sun_len = socklen;
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (inet_pton(AF_INET, irphost, &ipaddr) != 1) {
|
||||
errno = EADDRNOTAVAIL;
|
||||
perror("inet_pton");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
addr = (struct sockaddr *)&iaddr;
|
||||
socklen = sizeof iaddr;
|
||||
#ifdef HAVE_SA_LEN
|
||||
iaddr.sin_len = socklen;
|
||||
#endif
|
||||
iaddr.sin_family = AF_INET;
|
||||
iaddr.sin_port = htons(IRPD_PORT);
|
||||
iaddr.sin_addr.s_addr = ipaddr;
|
||||
}
|
||||
|
||||
|
||||
pvt->fdCxn = socket(addr->sa_family, SOCK_STREAM, PF_UNSPEC);
|
||||
if (pvt->fdCxn < 0) {
|
||||
perror("socket");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (connect(pvt->fdCxn, addr, socklen) != 0) {
|
||||
perror("connect");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
flags = fcntl(pvt->fdCxn, F_GETFL, 0);
|
||||
if (flags < 0) {
|
||||
close(pvt->fdCxn);
|
||||
perror("close");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(pvt->fdCxn, F_SETFL, flags) < 0) {
|
||||
close(pvt->fdCxn);
|
||||
perror("fcntl");
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
code = irs_irp_read_response(pvt, text, sizeof text);
|
||||
if (code != IRPD_WELCOME_CODE) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "Connection failed: %s", text);
|
||||
}
|
||||
irs_irp_disconnect(pvt);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*%
|
||||
* int irs_irp_is_connected(struct irp_p *pvt);
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Non-zero if streams are setup to remote.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_is_connected(struct irp_p *pvt) {
|
||||
return (pvt->fdCxn >= 0);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void
|
||||
* irs_irp_disconnect(struct irp_p *pvt);
|
||||
*
|
||||
* Closes streams to remote.
|
||||
*/
|
||||
|
||||
void
|
||||
irs_irp_disconnect(struct irp_p *pvt) {
|
||||
if (pvt->fdCxn != -1) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
irs_irp_read_line(struct irp_p *pvt, char *buffer, int len) {
|
||||
char *realstart = &pvt->inbuffer[0];
|
||||
char *p, *start, *end;
|
||||
int spare;
|
||||
int i;
|
||||
int buffpos = 0;
|
||||
int left = len - 1;
|
||||
|
||||
while (left > 0) {
|
||||
start = p = &pvt->inbuffer[pvt->incurr];
|
||||
end = &pvt->inbuffer[pvt->inlast];
|
||||
|
||||
while (p != end && *p != '\n')
|
||||
p++;
|
||||
|
||||
if (p == end) {
|
||||
/* Found no newline so shift data down if necessary
|
||||
* and append new data to buffer
|
||||
*/
|
||||
if (start > realstart) {
|
||||
memmove(realstart, start, end - start);
|
||||
pvt->inlast = end - start;
|
||||
start = realstart;
|
||||
pvt->incurr = 0;
|
||||
end = &pvt->inbuffer[pvt->inlast];
|
||||
}
|
||||
|
||||
spare = sizeof (pvt->inbuffer) - pvt->inlast;
|
||||
|
||||
p = end;
|
||||
i = read(pvt->fdCxn, end, spare);
|
||||
if (i < 0) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
return (buffpos > 0 ? buffpos : -1);
|
||||
} else if (i == 0) {
|
||||
return (buffpos);
|
||||
}
|
||||
|
||||
end += i;
|
||||
pvt->inlast += i;
|
||||
|
||||
while (p != end && *p != '\n')
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p == end) {
|
||||
/* full buffer and still no newline */
|
||||
i = sizeof pvt->inbuffer;
|
||||
} else {
|
||||
/* include newline */
|
||||
i = p - start + 1;
|
||||
}
|
||||
|
||||
if (i > left)
|
||||
i = left;
|
||||
memcpy(buffer + buffpos, start, i);
|
||||
pvt->incurr += i;
|
||||
buffpos += i;
|
||||
buffer[buffpos] = '\0';
|
||||
|
||||
if (p != end) {
|
||||
left = 0;
|
||||
} else {
|
||||
left -= i;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "read line: %s\n", buffer);
|
||||
#endif
|
||||
return (buffpos);
|
||||
}
|
||||
|
||||
/*%
|
||||
* int irp_read_response(struct irp_p *pvt);
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* The number found at the beginning of the line read from
|
||||
* FP. 0 on failure(0 is not a legal response code). The
|
||||
* rest of the line is discarded.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen) {
|
||||
char line[1024];
|
||||
int code;
|
||||
char *p;
|
||||
|
||||
if (irs_irp_read_line(pvt, line, sizeof line) <= 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
p = strchr(line, '\n');
|
||||
if (p == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (sscanf(line, "%d", &code) != 1) {
|
||||
code = 0;
|
||||
} else if (text != NULL && textlen > 0U) {
|
||||
p = line;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
while (isdigit((unsigned char)*p)) p++;
|
||||
while (isspace((unsigned char)*p)) p++;
|
||||
strncpy(text, p, textlen - 1);
|
||||
p[textlen - 1] = '\0';
|
||||
}
|
||||
|
||||
return (code);
|
||||
}
|
||||
|
||||
/*%
|
||||
* char *irp_read_body(struct irp_p *pvt, size_t *size);
|
||||
*
|
||||
* Read in the body of a response. Terminated by a line with
|
||||
* just a dot on it. Lines should be terminated with a CR-LF
|
||||
* sequence, but we're nt piccky if the CR is missing.
|
||||
* No leading dot escaping is done as the protcol doesn't
|
||||
* use leading dots anywhere.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Pointer to null-terminated buffer allocated by memget.
|
||||
* *SIZE is set to the length of the buffer.
|
||||
*
|
||||
*/
|
||||
|
||||
char *
|
||||
irs_irp_read_body(struct irp_p *pvt, size_t *size) {
|
||||
char line[1024];
|
||||
u_int linelen;
|
||||
size_t len = LINEINCR;
|
||||
char *buffer = memget(len);
|
||||
int idx = 0;
|
||||
|
||||
if (buffer == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (;;) {
|
||||
if (irs_irp_read_line(pvt, line, sizeof line) <= 0 ||
|
||||
strchr(line, '\n') == NULL)
|
||||
goto death;
|
||||
|
||||
linelen = strlen(line);
|
||||
|
||||
if (line[linelen - 1] != '\n')
|
||||
goto death;
|
||||
|
||||
/* We're not strict about missing \r. Should we be?? */
|
||||
if (linelen > 2 && line[linelen - 2] == '\r') {
|
||||
line[linelen - 2] = '\n';
|
||||
line[linelen - 1] = '\0';
|
||||
linelen--;
|
||||
}
|
||||
|
||||
if (linelen == 2 && line[0] == '.') {
|
||||
*size = len;
|
||||
buffer[idx] = '\0';
|
||||
|
||||
return (buffer);
|
||||
}
|
||||
|
||||
if (linelen > (len - (idx + 1))) {
|
||||
char *p = memget(len + LINEINCR);
|
||||
|
||||
if (p == NULL)
|
||||
goto death;
|
||||
memcpy(p, buffer, len);
|
||||
memput(buffer, len);
|
||||
buffer = p;
|
||||
len += LINEINCR;
|
||||
}
|
||||
|
||||
memcpy(buffer + idx, line, linelen);
|
||||
idx += linelen;
|
||||
}
|
||||
death:
|
||||
memput(buffer, len);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*%
|
||||
* int irs_irp_get_full_response(struct irp_p *pvt, int *code,
|
||||
* char **body, size_t *bodylen);
|
||||
*
|
||||
* Gets the response to a command. If the response indicates
|
||||
* there's a body to follow(code % 10 == 1), then the
|
||||
* body buffer is allcoated with memget and stored in
|
||||
* *BODY. The length of the allocated body buffer is stored
|
||||
* in *BODY. The caller must give the body buffer back to
|
||||
* memput when done. The results code is stored in *CODE.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 if a result was read. -1 on some sort of failure.
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_get_full_response(struct irp_p *pvt, int *code, char *text,
|
||||
size_t textlen, char **body, size_t *bodylen) {
|
||||
int result = irs_irp_read_response(pvt, text, textlen);
|
||||
|
||||
*body = NULL;
|
||||
|
||||
if (result == 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*code = result;
|
||||
|
||||
/* Code that matches 2xx is a good result code.
|
||||
* Code that matches xx1 means there's a response body coming.
|
||||
*/
|
||||
if ((result / 100) == 2 && (result % 10) == 1) {
|
||||
*body = irs_irp_read_body(pvt, bodylen);
|
||||
if (*body == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*%
|
||||
* int irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...);
|
||||
*
|
||||
* Sends command to remote connected via the PVT
|
||||
* structure. FMT and args after it are fprintf-like
|
||||
* arguments for formatting.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 0 on success, -1 on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
irs_irp_send_command(struct irp_p *pvt, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char buffer[1024];
|
||||
int pos = 0;
|
||||
int i, todo;
|
||||
|
||||
|
||||
if (pvt->fdCxn < 0) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
(void) vsprintf(buffer, fmt, ap);
|
||||
todo = strlen(buffer);
|
||||
va_end(ap);
|
||||
if (todo > (int)sizeof(buffer) - 3) {
|
||||
syslog(LOG_CRIT, "memory overrun in irs_irp_send_command()");
|
||||
exit(1);
|
||||
}
|
||||
strcat(buffer, "\r\n");
|
||||
todo = strlen(buffer);
|
||||
|
||||
while (todo > 0) {
|
||||
i = write(pvt->fdCxn, buffer + pos, todo);
|
||||
#if 0
|
||||
/* XXX brister */
|
||||
fprintf(stderr, "Wrote: \"");
|
||||
fwrite(buffer + pos, sizeof (char), todo, stderr);
|
||||
fprintf(stderr, "\"\n");
|
||||
#endif
|
||||
if (i < 0) {
|
||||
close(pvt->fdCxn);
|
||||
pvt->fdCxn = -1;
|
||||
return (-1);
|
||||
}
|
||||
todo -= i;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*%
|
||||
* void irp_close(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
irp_close(struct irs_acc *this) {
|
||||
struct irp_p *irp = (struct irp_p *)this->private;
|
||||
|
||||
if (irp != NULL) {
|
||||
irs_irp_disconnect(irp);
|
||||
memput(irp, sizeof *irp);
|
||||
}
|
||||
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \file */
|
||||
@@ -1,357 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright(c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_gr.c,v 1.4 2005/04/27 04:56:27 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
/* Types. */
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* Module for the getnetgrent(3) family to use when connected to a
|
||||
* remote irp daemon.
|
||||
* \brief
|
||||
* See irpd.c for justification of caching done here.
|
||||
*
|
||||
*/
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata; /*%< global IRP data */
|
||||
int warned;
|
||||
struct group group;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
/* Private */
|
||||
static void free_group(struct group *gr);
|
||||
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*%
|
||||
* Initialize the group sub-module.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_gr *
|
||||
irs_irp_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x0, sizeof *gr);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0x0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
/*%
|
||||
* Close the sub-module.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
gr_minimize(this);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Gets the next group out of the cached data and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "getgrent failed: %s", text);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Gets a group by name from irpd and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
|
||||
if (gr->gr_name != NULL && strcmp(name, gr->gr_name) == 0) {
|
||||
return (gr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrnam %s", name) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Gets a group by gid from irpd and returns it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *gr = &pvt->group;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (gr->gr_name != NULL && (gid_t)gr->gr_gid == gid) {
|
||||
return (gr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getgrgid %d", gid) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETGROUP_OK) {
|
||||
free_group(gr);
|
||||
if (irp_unmarshall_gr(gr, body) != 0) {
|
||||
gr = NULL;
|
||||
}
|
||||
} else {
|
||||
gr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void gr_rewind(struct irs_gr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setgrent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETGROUP_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setgrent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Frees up cached data and disconnects(if necessary) from the remote.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
free_group(&pvt->group);
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*%
|
||||
* static void free_group(struct group *gr);
|
||||
*
|
||||
* Deallocate all the memory irp_unmarshall_gr allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_group(struct group *gr) {
|
||||
char **p;
|
||||
|
||||
if (gr == NULL)
|
||||
return;
|
||||
|
||||
if (gr->gr_name != NULL)
|
||||
free(gr->gr_name);
|
||||
|
||||
if (gr->gr_passwd != NULL)
|
||||
free(gr->gr_passwd);
|
||||
|
||||
for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++)
|
||||
free(*p);
|
||||
|
||||
if (gr->gr_mem)
|
||||
free(gr->gr_mem);
|
||||
|
||||
if (p != NULL)
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
/*! \file */
|
||||
@@ -1,405 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996,1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_ho.c,v 1.3 2005/04/27 04:56:28 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports. */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#define Max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct hostent host;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
|
||||
static void free_host(struct hostent *ho);
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*%
|
||||
* struct irs_ho * irs_irp_ho(struct irs_acc *this)
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* Initializes the irp_ho module.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_ho *
|
||||
irs_irp_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x0, sizeof *ho);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ho, sizeof *ho);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
/*%
|
||||
* Closes down the module.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
|
||||
free_host(&pvt->host);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byname(struct irs_ho *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byname2(struct irs_ho *this, const char *name, int af)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (ho->h_name != NULL &&
|
||||
strcmp(name, ho->h_name) == 0 &&
|
||||
af == ho->h_addrtype) {
|
||||
return (ho);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostbyname2 %s %s",
|
||||
name, ADDR_T_STR(af)) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
* int len, int af)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char **p;
|
||||
char paddr[MAXPADDRSIZE];
|
||||
char text[256];
|
||||
|
||||
if (ho->h_name != NULL &&
|
||||
af == ho->h_addrtype &&
|
||||
len == ho->h_length) {
|
||||
for (p = ho->h_addr_list ; *p != NULL ; p++) {
|
||||
if (memcmp(*p, addr, len) == 0)
|
||||
return (ho);
|
||||
}
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (inet_ntop(af, addr, paddr, sizeof paddr) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostbyaddr %s %s",
|
||||
paddr, ADDR_T_STR(af)) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/*%
|
||||
* The implementation for gethostent(3). The first time it's
|
||||
* called all the data is pulled from the remote(i.e. what
|
||||
* the maximum number of gethostent(3) calls would return)
|
||||
* and that data is cached.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *ho = &pvt->host;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "gethostent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETHOST_OK) {
|
||||
free_host(ho);
|
||||
if (irp_unmarshall_ho(ho, body) != 0) {
|
||||
ho = NULL;
|
||||
}
|
||||
} else {
|
||||
ho = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void ho_rewind(struct irs_ho *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "sethostent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETHOST_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "sethostent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* void ho_minimize(struct irs_ho *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
free_host(&pvt->host);
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void free_host(struct hostent *ho)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_host(struct hostent *ho) {
|
||||
char **p;
|
||||
|
||||
if (ho == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ho->h_name != NULL)
|
||||
free(ho->h_name);
|
||||
|
||||
if (ho->h_aliases != NULL) {
|
||||
for (p = ho->h_aliases ; *p != NULL ; p++)
|
||||
free(*p);
|
||||
free(ho->h_aliases);
|
||||
}
|
||||
|
||||
if (ho->h_addr_list != NULL) {
|
||||
for (p = ho->h_addr_list ; *p != NULL ; p++)
|
||||
free(*p);
|
||||
free(ho->h_addr_list);
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy */
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
UNUSED(this);
|
||||
UNUSED(name);
|
||||
UNUSED(pai);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,253 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irp_ng.c,v 1.4 2006/12/07 04:46:27 marka Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
};
|
||||
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_rewind(struct irs_ng *, const char*);
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **, const char **,
|
||||
const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
/*%
|
||||
* Intialize the irp netgroup module.
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_ng *
|
||||
irs_irp_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_close(struct irs_ng *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ng_minimize(this);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_rewind(struct irs_ng *this, const char *group)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata,
|
||||
"setnetgrent %s", group) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETNETGR_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setnetgrent(%s) failed: %s",
|
||||
group, text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next netgroup item from the cache.
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int code;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int rval = 0;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetgrent") != 0)
|
||||
return (0);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNETGR_OK) {
|
||||
if (irp_unmarshall_ng(host, user, domain, body) == 0) {
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a match in a netgroup.
|
||||
*
|
||||
*/
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *body = NULL;
|
||||
size_t bodylen = 0;
|
||||
int code;
|
||||
char text[256];
|
||||
int rval = 0;
|
||||
|
||||
UNUSED(name);
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irp_marshall_ng(host, user, domain, &body, &bodylen) != 0) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "innetgr %s", body) == 0) {
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code == IRPD_GETNETGR_MATCHES) {
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
memput(body, bodylen);
|
||||
|
||||
return (rval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void ng_minimize(struct irs_ng *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Private */
|
||||
|
||||
|
||||
/*! \file */
|
||||
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996,1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_nw.c,v 1.4 2006/03/09 23:57:56 marka Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if 0
|
||||
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/misc.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRSIZE 4
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct nwent net;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
|
||||
static void free_nw(struct nwent *nw);
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
/*%
|
||||
* struct irs_nw * irs_irp_nw(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_nw *
|
||||
irs_irp_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x0, sizeof *nw);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*%
|
||||
* void nw_close(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
|
||||
free_nw(&pvt->net);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct nwent * nw_byaddr(struct irs_nw *this, void *net,
|
||||
* int length, int type)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char paddr[24]; /*%< bigenough for ip4 w/ cidr spec. */
|
||||
char text[256];
|
||||
|
||||
if (inet_net_ntop(type, net, length, paddr, sizeof paddr) == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetbyaddr %s %s",
|
||||
paddr, ADDR_T_STR(type)) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct nwent * nw_byname(struct irs_nw *this, const char *name, int type)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (nw->n_name != NULL &&
|
||||
strcmp(name, nw->n_name) == 0 &&
|
||||
nw->n_addrtype == type) {
|
||||
return (nw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetbyname %s", name) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void nw_rewind(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setnetent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETNET_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setnetent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Prepares the cache if necessary and returns the first, or
|
||||
* next item from it.
|
||||
*/
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *nw = &pvt->net;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getnetent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETNET_OK) {
|
||||
free_nw(nw);
|
||||
if (irp_unmarshall_nw(nw, body) != 0) {
|
||||
nw = NULL;
|
||||
}
|
||||
} else {
|
||||
nw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL)
|
||||
memput(body, bodylen);
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void nw_minimize(struct irs_nw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* private. */
|
||||
|
||||
/*%
|
||||
* deallocate all the memory irp_unmarshall_pw allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_nw(struct nwent *nw) {
|
||||
char **p;
|
||||
|
||||
if (nw == NULL)
|
||||
return;
|
||||
|
||||
if (nw->n_name != NULL)
|
||||
free(nw->n_name);
|
||||
|
||||
if (nw->n_aliases != NULL) {
|
||||
for (p = nw->n_aliases ; *p != NULL ; p++) {
|
||||
free(*p);
|
||||
}
|
||||
free(nw->n_aliases);
|
||||
}
|
||||
|
||||
if (nw->n_addr != NULL)
|
||||
free(nw->n_addr);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: irp_p.h,v 1.5 2005/04/27 04:56:28 sra Exp $
|
||||
*/
|
||||
|
||||
#ifndef _IRP_P_H_INCLUDED
|
||||
#define _IRP_P_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct irp_p {
|
||||
char inbuffer[1024];
|
||||
int inlast; /*%< index of one past the last char in buffer */
|
||||
int incurr; /*%< index of the next char to be read from buffer */
|
||||
int fdCxn;
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_irp_acc __P((const char *));
|
||||
extern struct irs_gr * irs_irp_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_irp_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_irp_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_irp_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_irp_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_irp_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_irp_ng __P((struct irs_acc *));
|
||||
|
||||
int irs_irp_connect(struct irp_p *pvt);
|
||||
int irs_irp_is_connected(struct irp_p *pvt);
|
||||
void irs_irp_disconnect(struct irp_p *pvt);
|
||||
int irs_irp_read_response(struct irp_p *pvt, char *text, size_t textlen);
|
||||
char *irs_irp_read_body(struct irp_p *pvt, size_t *size);
|
||||
int irs_irp_get_full_response(struct irp_p *pvt, int *code,
|
||||
char *text, size_t textlen,
|
||||
char **body, size_t *bodylen);
|
||||
|
||||
extern int irp_log_errors;
|
||||
|
||||
#endif
|
||||
|
||||
/*! \file */
|
||||
@@ -1,327 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_pr.c,v 1.3 2005/04/27 04:56:29 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct protoent proto;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pr_close(struct irs_pr *);
|
||||
static struct protoent * pr_next(struct irs_pr *);
|
||||
static struct protoent * pr_byname(struct irs_pr *, const char *);
|
||||
static struct protoent * pr_bynumber(struct irs_pr *, int);
|
||||
static void pr_rewind(struct irs_pr *);
|
||||
static void pr_minimize(struct irs_pr *);
|
||||
|
||||
static void free_proto(struct protoent *pr);
|
||||
|
||||
/* Public */
|
||||
|
||||
/*%
|
||||
* struct irs_pr * irs_irp_pr(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_pr *
|
||||
irs_irp_pr(struct irs_acc *this) {
|
||||
struct irs_pr *pr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pr, 0x0, sizeof *pr);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pr, sizeof *pr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
pr->private = pvt;
|
||||
pr->close = pr_close;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*%
|
||||
* void pr_close(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pr_minimize(this);
|
||||
|
||||
free_proto(&pvt->proto);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct protoent * pr_byname(struct irs_pr *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
int i;
|
||||
char text[256];
|
||||
|
||||
if (pr->p_name != NULL && strcmp(name, pr->p_name) == 0) {
|
||||
return (pr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
i = irs_irp_send_command(pvt->girpdata, "getprotobyname %s", name);
|
||||
if (i != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct protoent * pr_bynumber(struct irs_pr *this, int proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body = NULL;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
int i;
|
||||
char text[256];
|
||||
|
||||
if (pr->p_name != NULL && proto == pr->p_proto) {
|
||||
return (pr);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
i = irs_irp_send_command(pvt->girpdata, "getprotobynumber %d", proto);
|
||||
if (i != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void pr_rewind(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setprotoent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETPROTO_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setprotoent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Prepares the cache if necessary and returns the next item in it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct protoent *pr = &pvt->proto;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getprotoent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETPROTO_OK) {
|
||||
free_proto(pr);
|
||||
if (irp_unmarshall_pr(pr, body) != 0) {
|
||||
pr = NULL;
|
||||
}
|
||||
} else {
|
||||
pr = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pr);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void pr_minimize(struct irs_pr *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Deallocate all the memory irp_unmarshall_pr allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_proto(struct protoent *pr) {
|
||||
char **p;
|
||||
|
||||
if (pr == NULL)
|
||||
return;
|
||||
|
||||
if (pr->p_name != NULL)
|
||||
free(pr->p_name);
|
||||
|
||||
for (p = pr->p_aliases ; p != NULL && *p != NULL ; p++)
|
||||
free(*p);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_pw.c,v 1.4 2005/04/27 04:56:29 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/memcluster.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata; /*%< global IRP data */
|
||||
int warned;
|
||||
struct passwd passwd; /*%< password structure */
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
|
||||
static void free_passwd(struct passwd *pw);
|
||||
|
||||
/* Public */
|
||||
struct irs_pw *
|
||||
irs_irp_pw(struct irs_acc *this) {
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0, sizeof *pw);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(pw, sizeof *pw);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*%
|
||||
* void pw_close(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pw_minimize(this);
|
||||
|
||||
free_passwd(&pvt->passwd);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct passwd * pw_next(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct passwd * pw_byname(struct irs_pw *this, const char *name)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
char *body = NULL;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
|
||||
if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) {
|
||||
return (pw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct passwd * pw_byuid(struct irs_pw *this, uid_t uid)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *body;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
struct passwd *pw = &pvt->passwd;
|
||||
|
||||
if (pw->pw_name != NULL && pw->pw_uid == uid) {
|
||||
return (pw);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETUSER_OK) {
|
||||
free_passwd(pw);
|
||||
if (irp_unmarshall_pw(pw, body) != 0) {
|
||||
pw = NULL;
|
||||
}
|
||||
} else {
|
||||
pw = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void pw_rewind(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETUSER_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setpwent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* void pw_minimize(struct irs_pw *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*%
|
||||
* Deallocate all the memory irp_unmarshall_pw allocated.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
free_passwd(struct passwd *pw) {
|
||||
if (pw == NULL)
|
||||
return;
|
||||
|
||||
if (pw->pw_name != NULL)
|
||||
free(pw->pw_name);
|
||||
|
||||
if (pw->pw_passwd != NULL)
|
||||
free(pw->pw_passwd);
|
||||
|
||||
#ifdef HAVE_PW_CLASS
|
||||
if (pw->pw_class != NULL)
|
||||
free(pw->pw_class);
|
||||
#endif
|
||||
|
||||
if (pw->pw_gecos != NULL)
|
||||
free(pw->pw_gecos);
|
||||
|
||||
if (pw->pw_dir != NULL)
|
||||
free(pw->pw_dir);
|
||||
|
||||
if (pw->pw_shell != NULL)
|
||||
free(pw->pw_shell);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
/*! \file */
|
||||
@@ -1,346 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996,1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: irp_sv.c,v 1.3 2005/04/27 04:56:29 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef IRS_LCL_SV_DB
|
||||
#include <db.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <irp.h>
|
||||
#include <isc/irpmarshall.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct irp_p *girpdata;
|
||||
int warned;
|
||||
struct servent service;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void sv_close(struct irs_sv*);
|
||||
static struct servent * sv_next(struct irs_sv *);
|
||||
static struct servent * sv_byname(struct irs_sv *, const char *,
|
||||
const char *);
|
||||
static struct servent * sv_byport(struct irs_sv *, int, const char *);
|
||||
static void sv_rewind(struct irs_sv *);
|
||||
static void sv_minimize(struct irs_sv *);
|
||||
|
||||
static void free_service(struct servent *sv);
|
||||
|
||||
|
||||
|
||||
/* Public */
|
||||
|
||||
/*%
|
||||
* struct irs_sv * irs_irp_sv(struct irs_acc *this)
|
||||
*
|
||||
*/
|
||||
|
||||
struct irs_sv *
|
||||
irs_irp_sv(struct irs_acc *this) {
|
||||
struct irs_sv *sv;
|
||||
struct pvt *pvt;
|
||||
|
||||
if ((sv = memget(sizeof *sv)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(sv, 0x0, sizeof *sv);
|
||||
|
||||
if ((pvt = memget(sizeof *pvt)) == NULL) {
|
||||
memput(sv, sizeof *sv);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->girpdata = this->private;
|
||||
|
||||
sv->private = pvt;
|
||||
sv->close = sv_close;
|
||||
sv->next = sv_next;
|
||||
sv->byname = sv_byname;
|
||||
sv->byport = sv_byport;
|
||||
sv->rewind = sv_rewind;
|
||||
sv->minimize = sv_minimize;
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
/*%
|
||||
* void sv_close(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_close(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
sv_minimize(this);
|
||||
|
||||
free_service(&pvt->service);
|
||||
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Fills the cache if necessary and returns the next item from it.
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_next(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
int code;
|
||||
char text[256];
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservent") != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct servent * sv_byname(struct irs_sv *this, const char *name,
|
||||
* const char *proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_byname(struct irs_sv *this, const char *name, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
char text[256];
|
||||
size_t bodylen;
|
||||
int code;
|
||||
|
||||
if (sv->s_name != NULL &&
|
||||
strcmp(name, sv->s_name) == 0 &&
|
||||
strcasecmp(proto, sv->s_proto) == 0) {
|
||||
return (sv);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservbyname %s %s",
|
||||
name, proto) != 0)
|
||||
return (NULL);
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/*%
|
||||
* struct servent * sv_byport(struct irs_sv *this, int port,
|
||||
* const char *proto)
|
||||
*
|
||||
*/
|
||||
|
||||
static struct servent *
|
||||
sv_byport(struct irs_sv *this, int port, const char *proto) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct servent *sv = &pvt->service;
|
||||
char *body;
|
||||
size_t bodylen;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (sv->s_name != NULL &&
|
||||
port == sv->s_port &&
|
||||
strcasecmp(proto, sv->s_proto) == 0) {
|
||||
return (sv);
|
||||
}
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "getservbyport %d %s",
|
||||
ntohs((short)port), proto) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (irs_irp_get_full_response(pvt->girpdata, &code,
|
||||
text, sizeof text,
|
||||
&body, &bodylen) != 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (code == IRPD_GETSERVICE_OK) {
|
||||
free_service(sv);
|
||||
if (irp_unmarshall_sv(sv, body) != 0) {
|
||||
sv = NULL;
|
||||
}
|
||||
} else {
|
||||
sv = NULL;
|
||||
}
|
||||
|
||||
if (body != NULL) {
|
||||
memput(body, bodylen);
|
||||
}
|
||||
|
||||
return (sv);
|
||||
}
|
||||
|
||||
/*%
|
||||
* void sv_rewind(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_rewind(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char text[256];
|
||||
int code;
|
||||
|
||||
if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (irs_irp_send_command(pvt->girpdata, "setservent") != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
|
||||
if (code != IRPD_GETSERVICE_SETOK) {
|
||||
if (irp_log_errors) {
|
||||
syslog(LOG_WARNING, "setservent failed: %s", text);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*%
|
||||
* void sv_minimize(struct irs_sv *this)
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sv_minimize(struct irs_sv *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
irs_irp_disconnect(pvt->girpdata);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
free_service(struct servent *sv) {
|
||||
char **p;
|
||||
|
||||
if (sv == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sv->s_name != NULL) {
|
||||
free(sv->s_name);
|
||||
}
|
||||
|
||||
for (p = sv->s_aliases ; p != NULL && *p != NULL ; p++) {
|
||||
free(*p);
|
||||
}
|
||||
|
||||
if (sv->s_proto != NULL) {
|
||||
free(sv->s_proto);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*! \file */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: irs_data.c,v 1.12 2007/08/27 03:32:26 marka Exp $";
|
||||
#endif
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef __BIND_NOSTATIC
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include <irs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_data.h"
|
||||
#undef _res
|
||||
#if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
|
||||
#undef h_errno
|
||||
extern int h_errno;
|
||||
#endif
|
||||
|
||||
extern struct __res_state _res;
|
||||
|
||||
#ifdef DO_PTHREADS
|
||||
static pthread_key_t key;
|
||||
static int once = 0;
|
||||
#else
|
||||
static struct net_data *net_data;
|
||||
#endif
|
||||
|
||||
void
|
||||
irs_destroy(void) {
|
||||
#ifndef DO_PTHREADS
|
||||
if (net_data != NULL)
|
||||
net_data_destroy(net_data);
|
||||
net_data = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
net_data_destroy(void *p) {
|
||||
struct net_data *net_data = p;
|
||||
|
||||
res_ndestroy(net_data->res);
|
||||
if (net_data->gr != NULL) {
|
||||
(*net_data->gr->close)(net_data->gr);
|
||||
net_data->gr = NULL;
|
||||
}
|
||||
if (net_data->pw != NULL) {
|
||||
(*net_data->pw->close)(net_data->pw);
|
||||
net_data->pw = NULL;
|
||||
}
|
||||
if (net_data->sv != NULL) {
|
||||
(*net_data->sv->close)(net_data->sv);
|
||||
net_data->sv = NULL;
|
||||
}
|
||||
if (net_data->pr != NULL) {
|
||||
(*net_data->pr->close)(net_data->pr);
|
||||
net_data->pr = NULL;
|
||||
}
|
||||
if (net_data->ho != NULL) {
|
||||
(*net_data->ho->close)(net_data->ho);
|
||||
net_data->ho = NULL;
|
||||
}
|
||||
if (net_data->nw != NULL) {
|
||||
(*net_data->nw->close)(net_data->nw);
|
||||
net_data->nw = NULL;
|
||||
}
|
||||
if (net_data->ng != NULL) {
|
||||
(*net_data->ng->close)(net_data->ng);
|
||||
net_data->ng = NULL;
|
||||
}
|
||||
if (net_data->ho_data != NULL) {
|
||||
free(net_data->ho_data);
|
||||
net_data->ho_data = NULL;
|
||||
}
|
||||
if (net_data->nw_data != NULL) {
|
||||
free(net_data->nw_data);
|
||||
net_data->nw_data = NULL;
|
||||
}
|
||||
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof *net_data);
|
||||
}
|
||||
|
||||
/*%
|
||||
* applications that need a specific config file other than
|
||||
* _PATH_IRS_CONF should call net_data_init directly rather than letting
|
||||
* the various wrapper functions make the first call. - brister
|
||||
*/
|
||||
|
||||
struct net_data *
|
||||
net_data_init(const char *conf_file) {
|
||||
#ifdef DO_PTHREADS
|
||||
#ifndef LIBBIND_MUTEX_INITIALIZER
|
||||
#define LIBBIND_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
static pthread_mutex_t keylock = LIBBIND_MUTEX_INITIALIZER;
|
||||
struct net_data *net_data;
|
||||
|
||||
if (!once) {
|
||||
if (pthread_mutex_lock(&keylock) != 0)
|
||||
return (NULL);
|
||||
if (!once) {
|
||||
if (pthread_key_create(&key, net_data_destroy) != 0) {
|
||||
(void)pthread_mutex_unlock(&keylock);
|
||||
return (NULL);
|
||||
}
|
||||
once = 1;
|
||||
}
|
||||
if (pthread_mutex_unlock(&keylock) != 0)
|
||||
return (NULL);
|
||||
}
|
||||
net_data = pthread_getspecific(key);
|
||||
#endif
|
||||
|
||||
if (net_data == NULL) {
|
||||
net_data = net_data_create(conf_file);
|
||||
if (net_data == NULL)
|
||||
return (NULL);
|
||||
#ifdef DO_PTHREADS
|
||||
if (pthread_setspecific(key, net_data) != 0) {
|
||||
net_data_destroy(net_data);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
struct net_data *
|
||||
net_data_create(const char *conf_file) {
|
||||
struct net_data *net_data;
|
||||
|
||||
net_data = memget(sizeof (struct net_data));
|
||||
if (net_data == NULL)
|
||||
return (NULL);
|
||||
memset(net_data, 0, sizeof (struct net_data));
|
||||
|
||||
if ((net_data->irs = irs_gen_acc("", conf_file)) == NULL) {
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
#ifndef DO_PTHREADS
|
||||
(*net_data->irs->res_set)(net_data->irs, &_res, NULL);
|
||||
#endif
|
||||
|
||||
net_data->res = (*net_data->irs->res_get)(net_data->irs);
|
||||
if (net_data->res == NULL) {
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((net_data->res->options & RES_INIT) == 0U &&
|
||||
res_ninit(net_data->res) == -1) {
|
||||
(*net_data->irs->close)(net_data->irs);
|
||||
memput(net_data, sizeof (struct net_data));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (net_data);
|
||||
}
|
||||
|
||||
void
|
||||
net_data_minimize(struct net_data *net_data) {
|
||||
res_nclose(net_data->res);
|
||||
}
|
||||
|
||||
#ifdef _REENTRANT
|
||||
struct __res_state *
|
||||
__res_state(void) {
|
||||
/* NULL param here means use the default config file. */
|
||||
struct net_data *net_data = net_data_init(NULL);
|
||||
if (net_data && net_data->res)
|
||||
return (net_data->res);
|
||||
|
||||
return (&_res);
|
||||
}
|
||||
#else
|
||||
#ifdef __linux
|
||||
struct __res_state *
|
||||
__res_state(void) {
|
||||
return (&_res);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int *
|
||||
__h_errno(void) {
|
||||
/* NULL param here means use the default config file. */
|
||||
struct net_data *net_data = net_data_init(NULL);
|
||||
if (net_data && net_data->res)
|
||||
return (&net_data->res->res_h_errno);
|
||||
#if !(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
|
||||
return(&_res.res_h_errno);
|
||||
#else
|
||||
return (&h_errno);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
__h_errno_set(struct __res_state *res, int err) {
|
||||
|
||||
|
||||
#if (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
|
||||
res->res_h_errno = err;
|
||||
#else
|
||||
h_errno = res->res_h_errno = err;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: irs_data.h,v 1.3 2005/04/27 04:56:30 sra Exp $
|
||||
*/
|
||||
|
||||
#ifndef __BIND_NOSTATIC
|
||||
|
||||
#define net_data_init __net_data_init
|
||||
|
||||
struct net_data {
|
||||
struct irs_acc * irs;
|
||||
|
||||
struct irs_gr * gr;
|
||||
struct irs_pw * pw;
|
||||
struct irs_sv * sv;
|
||||
struct irs_pr * pr;
|
||||
struct irs_ho * ho;
|
||||
struct irs_nw * nw;
|
||||
struct irs_ng * ng;
|
||||
|
||||
struct group * gr_last;
|
||||
struct passwd * pw_last;
|
||||
struct servent * sv_last;
|
||||
struct protoent * pr_last;
|
||||
struct netent * nw_last; /*%< should have been ne_last */
|
||||
struct nwent * nww_last;
|
||||
struct hostent * ho_last;
|
||||
|
||||
unsigned int gr_stayopen :1;
|
||||
unsigned int pw_stayopen :1;
|
||||
unsigned int sv_stayopen :1;
|
||||
unsigned int pr_stayopen :1;
|
||||
unsigned int ho_stayopen :1;
|
||||
unsigned int nw_stayopen :1;
|
||||
|
||||
void * nw_data;
|
||||
void * ho_data;
|
||||
|
||||
struct __res_state * res; /*%< for gethostent.c */
|
||||
};
|
||||
|
||||
extern struct net_data * net_data_init(const char *conf_file);
|
||||
extern void net_data_minimize(struct net_data *);
|
||||
|
||||
#endif /*__BIND_NOSTATIC*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _IRS_P_H_INCLUDED
|
||||
#define _IRS_P_H_INCLUDED
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "pathnames.h"
|
||||
|
||||
#define IRS_SV_MAXALIASES 35
|
||||
|
||||
struct lcl_sv {
|
||||
FILE * fp;
|
||||
char line[BUFSIZ+1];
|
||||
struct servent serv;
|
||||
char * serv_aliases[IRS_SV_MAXALIASES];
|
||||
};
|
||||
|
||||
#define irs_nul_ng __irs_nul_ng
|
||||
#define map_v4v6_address __map_v4v6_address
|
||||
#define make_group_list __make_group_list
|
||||
#define irs_lclsv_fnxt __irs_lclsv_fnxt
|
||||
|
||||
extern void map_v4v6_address(const char *src, char *dst);
|
||||
extern int make_group_list(struct irs_gr *, const char *,
|
||||
gid_t, gid_t *, int *);
|
||||
extern struct irs_ng * irs_nul_ng(struct irs_acc *);
|
||||
extern struct servent * irs_lclsv_fnxt(struct lcl_sv *);
|
||||
|
||||
#endif
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: lcl.c,v 1.4 2005/04/27 04:56:30 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void lcl_close(struct irs_acc *);
|
||||
static struct __res_state * lcl_res_get(struct irs_acc *);
|
||||
static void lcl_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_lcl_acc(const char *options) {
|
||||
struct irs_acc *acc;
|
||||
struct lcl_p *lcl;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
if (!(lcl = memget(sizeof *lcl))) {
|
||||
errno = ENOMEM;
|
||||
free(acc);
|
||||
return (NULL);
|
||||
}
|
||||
memset(lcl, 0x5e, sizeof *lcl);
|
||||
lcl->res = NULL;
|
||||
lcl->free_res = NULL;
|
||||
acc->private = lcl;
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_lcl_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_lcl_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_lcl_sv;
|
||||
acc->pr_map = irs_lcl_pr;
|
||||
acc->ho_map = irs_lcl_ho;
|
||||
acc->nw_map = irs_lcl_nw;
|
||||
acc->ng_map = irs_lcl_ng;
|
||||
acc->res_get = lcl_res_get;
|
||||
acc->res_set = lcl_res_set;
|
||||
acc->close = lcl_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
static struct __res_state *
|
||||
lcl_res_get(struct irs_acc *this) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
lcl_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((lcl->res->options & RES_INIT) == 0U &&
|
||||
res_ninit(lcl->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (lcl->res);
|
||||
}
|
||||
|
||||
static void
|
||||
lcl_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl->res && lcl->free_res) {
|
||||
res_nclose(lcl->res);
|
||||
(*lcl->free_res)(lcl->res);
|
||||
}
|
||||
|
||||
lcl->res = res;
|
||||
lcl->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
lcl_close(struct irs_acc *this) {
|
||||
struct lcl_p *lcl = (struct lcl_p *)this->private;
|
||||
|
||||
if (lcl) {
|
||||
if (lcl->free_res)
|
||||
(*lcl->free_res)(lcl->res);
|
||||
memput(lcl, sizeof *lcl);
|
||||
}
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_gr.c,v 1.3 2005/04/27 04:56:30 sra Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
#include "irp_p.h"
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
|
||||
/* Types. */
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
/*%<
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /*%< Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
static int grstart(struct pvt *);
|
||||
static char * grnext(struct pvt *);
|
||||
static struct group * grscan(struct irs_gr *, int, gid_t, const char *);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_gr *
|
||||
irs_lcl_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = NULL;
|
||||
gr->res_set = NULL;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp)
|
||||
(void)fclose(pvt->fp);
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->fp && !grstart(pvt))
|
||||
return (NULL);
|
||||
return (grscan(this, 0, 0, NULL));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
if (!grstart((struct pvt *)this->private))
|
||||
return (NULL);
|
||||
return (grscan(this, 1, 0, name));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
if (!grstart((struct pvt *)this->private))
|
||||
return (NULL);
|
||||
return (grscan(this, 1, gid, NULL));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
(void) grstart((struct pvt *)this->private);
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
grstart(struct pvt *pvt) {
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return (1);
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_GROUP, "r")))
|
||||
return (0);
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
fclose(pvt->fp);
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
#define INITIAL_NMEMB 30 /*%< about 120 bytes */
|
||||
#define INITIAL_BUFSIZ (INITIAL_NMEMB * 8) /*%< about 240 bytes */
|
||||
static char *
|
||||
grnext(struct pvt *pvt) {
|
||||
char *w, *e;
|
||||
int ch;
|
||||
|
||||
/* Make sure we have a buffer. */
|
||||
if (pvt->membuf == NULL) {
|
||||
pvt->membuf = malloc(INITIAL_BUFSIZ);
|
||||
if (pvt->membuf == NULL) {
|
||||
enomem:
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
pvt->membufsize = INITIAL_BUFSIZ;
|
||||
}
|
||||
|
||||
/* Read until EOF or EOL. */
|
||||
w = pvt->membuf;
|
||||
e = pvt->membuf + pvt->membufsize;
|
||||
while ((ch = fgetc(pvt->fp)) != EOF && ch != '\n') {
|
||||
/* Make sure we have room for this character and a \0. */
|
||||
if (w + 1 == e) {
|
||||
size_t o = w - pvt->membuf;
|
||||
size_t n = pvt->membufsize * 2;
|
||||
char *t = realloc(pvt->membuf, n);
|
||||
|
||||
if (t == NULL)
|
||||
goto enomem;
|
||||
pvt->membuf = t;
|
||||
pvt->membufsize = n;
|
||||
w = pvt->membuf + o;
|
||||
e = pvt->membuf + pvt->membufsize;
|
||||
}
|
||||
/* Store it. */
|
||||
*w++ = (char)ch;
|
||||
}
|
||||
|
||||
/* Hitting EOF on the first character really does mean EOF. */
|
||||
if (w == pvt->membuf && ch == EOF) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Last line of /etc/group need not end with \n; we don't care. */
|
||||
*w = '\0';
|
||||
return (pvt->membuf);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
grscan(struct irs_gr *this, int search, gid_t gid, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
size_t n;
|
||||
char *bp, **m, *p;
|
||||
|
||||
/* Read lines until we find one that matches our search criteria. */
|
||||
for (;;) {
|
||||
if ((bp = grnext(pvt)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* Optimize the usual case of searching for a name. */
|
||||
pvt->group.gr_name = strsep(&bp, ":");
|
||||
if (search && name != NULL &&
|
||||
strcmp(pvt->group.gr_name, name) != 0)
|
||||
continue;
|
||||
if (bp == NULL || *bp == '\0')
|
||||
goto corrupt;
|
||||
|
||||
/* Skip past the password field. */
|
||||
pvt->group.gr_passwd = strsep(&bp, ":");
|
||||
if (bp == NULL || *bp == '\0')
|
||||
goto corrupt;
|
||||
|
||||
/* Checking for a gid. */
|
||||
if ((p = strsep(&bp, ":")) == NULL)
|
||||
continue;
|
||||
/*
|
||||
* Unlike the tests above, the test below is supposed to be
|
||||
* testing 'p' and not 'bp', in case you think it's a typo.
|
||||
*/
|
||||
if (p == NULL || *p == '\0') {
|
||||
corrupt:
|
||||
/* warning: corrupted %s file!", _PATH_GROUP */
|
||||
continue;
|
||||
}
|
||||
pvt->group.gr_gid = atoi(p);
|
||||
if (search && name == NULL && (gid_t)pvt->group.gr_gid != gid)
|
||||
continue;
|
||||
|
||||
/* We want this record. */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count commas to find out how many members there might be.
|
||||
* Note that commas separate, so if there is one comma there
|
||||
* can be two members (group:*:id:user1,user2). Add another
|
||||
* to account for the NULL terminator. As above, allocate
|
||||
* largest of INITIAL_NMEMB, or 2*n.
|
||||
*/
|
||||
n = 1;
|
||||
if (bp != NULL)
|
||||
for (n = 2, p = bp; (p = strpbrk(p, ", ")) != NULL; ++n)
|
||||
p += strspn(p, ", ");
|
||||
if (n > pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
if ((n *= 2) < INITIAL_NMEMB)
|
||||
n = INITIAL_NMEMB;
|
||||
if ((m = realloc(pvt->group.gr_mem, n * sizeof *m)) == NULL)
|
||||
return (NULL);
|
||||
pvt->group.gr_mem = m;
|
||||
pvt->nmemb = n;
|
||||
}
|
||||
|
||||
/* Set the name pointers. */
|
||||
for (m = pvt->group.gr_mem; (p = strsep(&bp, ", ")) != NULL;)
|
||||
if (p[0] != '\0')
|
||||
*m++ = p;
|
||||
*m = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR */
|
||||
/*! \file */
|
||||
@@ -1,599 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include <FindDirectory.h>
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "dns_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) sprintf x
|
||||
#endif
|
||||
|
||||
/* Definitions. */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#define Max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
int index;
|
||||
struct hostent host;
|
||||
char * h_addr_ptrs[MAXADDRS + 1];
|
||||
char * host_aliases[MAXALIASES];
|
||||
char hostbuf[8*1024];
|
||||
u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
struct __res_state *res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
typedef union {
|
||||
int32_t al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static size_t ns_namelen(const char *);
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public. */
|
||||
|
||||
struct irs_ho *
|
||||
irs_lcl_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods. */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
if (pvt->fp)
|
||||
(void) fclose(pvt->fp);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
hp = ho_byname2(this, name, AF_INET6);
|
||||
if (hp)
|
||||
return (hp);
|
||||
}
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
char **hap;
|
||||
size_t n;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
ho_rewind(this);
|
||||
n = ns_namelen(name);
|
||||
while ((hp = ho_next(this)) != NULL) {
|
||||
size_t nn;
|
||||
|
||||
if (hp->h_addrtype != af)
|
||||
continue;
|
||||
nn = ns_namelen(hp->h_name);
|
||||
if (strncasecmp(hp->h_name, name, Max(n, nn)) == 0)
|
||||
goto found;
|
||||
for (hap = hp->h_aliases; *hap; hap++) {
|
||||
nn = ns_namelen(*hap);
|
||||
if (strncasecmp(*hap, name, Max(n, nn)) == 0)
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (!hp) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (hp);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
const u_char *uaddr = addr;
|
||||
struct hostent *hp;
|
||||
int size;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!memcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr = (const u_char *)addr + sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
if (size > len) {
|
||||
errno = EINVAL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the search.
|
||||
*/
|
||||
ho_rewind(this);
|
||||
while ((hp = ho_next(this)) != NULL) {
|
||||
char **hap;
|
||||
|
||||
for (hap = hp->h_addr_list; *hap; hap++) {
|
||||
const u_char *taddr = (const u_char *)*hap;
|
||||
int taf = hp->h_addrtype;
|
||||
int tlen = hp->h_length;
|
||||
|
||||
if (taf == AF_INET6 && tlen == IN6ADDRSZ &&
|
||||
(!memcmp(taddr, mapped, sizeof mapped) ||
|
||||
!memcmp(taddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
taddr += sizeof mapped;
|
||||
taf = AF_INET;
|
||||
tlen = INADDRSZ;
|
||||
}
|
||||
if (taf == af && tlen == len &&
|
||||
!memcmp(taddr, uaddr, tlen))
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
if (!hp) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (hp);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *cp, **q, *p;
|
||||
char *bufp, *ndbuf, *dbuf = NULL;
|
||||
int c, af, len, bufsiz, offset;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (pvt->index > 0)
|
||||
return (NULL);
|
||||
if (!pvt->fp)
|
||||
ho_rewind(this);
|
||||
if (!pvt->fp) {
|
||||
strcpy(pvt->hostbuf, "localhost");
|
||||
pvt->host_aliases[0] = NULL;
|
||||
pvt->h_addr_ptrs[0] = (char *)pvt->host_addr;
|
||||
pvt->h_addr_ptrs[1] = NULL;
|
||||
pvt->host.h_addr_list = pvt->h_addr_ptrs;
|
||||
pvt->host.h_length = INADDRSZ;
|
||||
pvt->host.h_addrtype = AF_INET;
|
||||
pvt->host.h_aliases = pvt->host_aliases;
|
||||
pvt->host.h_name = pvt->hostbuf;
|
||||
((struct in_addr *)pvt->host_addr)->s_addr = htonl(INADDR_LOOPBACK);
|
||||
pvt->index++;
|
||||
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
}
|
||||
|
||||
bufp = pvt->hostbuf;
|
||||
bufsiz = sizeof pvt->hostbuf;
|
||||
offset = 0;
|
||||
again:
|
||||
if (!(p = fgets(bufp + offset, bufsiz - offset, pvt->fp))) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
return (NULL);
|
||||
}
|
||||
if (!strchr(p, '\n') && !feof(pvt->fp)) {
|
||||
#define GROWBUF 1024
|
||||
/* allocate space for longer line */
|
||||
if (dbuf == NULL) {
|
||||
if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
|
||||
strcpy(ndbuf, bufp);
|
||||
} else
|
||||
ndbuf = realloc(dbuf, bufsiz + GROWBUF);
|
||||
if (ndbuf) {
|
||||
dbuf = ndbuf;
|
||||
bufp = dbuf;
|
||||
bufsiz += GROWBUF;
|
||||
offset = strlen(dbuf);
|
||||
} else {
|
||||
/* allocation failed; skip this long line */
|
||||
while ((c = getc(pvt->fp)) != EOF)
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c != EOF)
|
||||
ungetc(c, pvt->fp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
p -= offset;
|
||||
offset = 0;
|
||||
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
if ((cp = strpbrk(p, "#\n")) != NULL)
|
||||
*cp = '\0';
|
||||
if (!(cp = strpbrk(p, " \t")))
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
if (inet_pton(AF_INET6, p, pvt->host_addr) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_aton(p, (struct in_addr *)pvt->host_addr) > 0) {
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
map_v4v6_address((char*)pvt->host_addr,
|
||||
(char*)pvt->host_addr);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
} else {
|
||||
goto again;
|
||||
}
|
||||
pvt->h_addr_ptrs[0] = (char *)pvt->host_addr;
|
||||
pvt->h_addr_ptrs[1] = NULL;
|
||||
pvt->host.h_addr_list = pvt->h_addr_ptrs;
|
||||
pvt->host.h_length = len;
|
||||
pvt->host.h_addrtype = af;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
pvt->host.h_name = cp;
|
||||
q = pvt->host.h_aliases = pvt->host_aliases;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
|
||||
if (find_directory(B_SYSTEM_SETTINGS_DIRECTORY, -1, false, path,
|
||||
sizeof(path)) == B_OK) {
|
||||
strlcat(path, "/network/hosts", sizeof(path));
|
||||
|
||||
if (!(pvt->fp = fopen(path, "r"))) {
|
||||
pvt->index = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
struct lcl_res_target {
|
||||
struct lcl_res_target *next;
|
||||
int family;
|
||||
};
|
||||
|
||||
/* XXX */
|
||||
extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
|
||||
const struct addrinfo *pai));
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
struct lcl_res_target q, q2, *p;
|
||||
struct addrinfo sentinel, *cur;
|
||||
|
||||
memset(&q, 0, sizeof(q2));
|
||||
memset(&q2, 0, sizeof(q2));
|
||||
memset(&sentinel, 0, sizeof(sentinel));
|
||||
cur = &sentinel;
|
||||
|
||||
switch(pai->ai_family) {
|
||||
case AF_UNSPEC: /* INET6 then INET4 */
|
||||
q.family = AF_INET6;
|
||||
q.next = &q2;
|
||||
q2.family = AF_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
q.family = AF_INET6;
|
||||
break;
|
||||
case AF_INET:
|
||||
q.family = AF_INET;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /* ??? */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
for (p = &q; p; p = p->next) {
|
||||
struct addrinfo *ai;
|
||||
|
||||
hp = (*this->byname2)(this, name, p->family);
|
||||
if (hp == NULL) {
|
||||
/* byname2 should've set an appropriate error */
|
||||
continue;
|
||||
}
|
||||
if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
|
||||
(hp->h_addr_list[0] == NULL)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
continue;
|
||||
}
|
||||
|
||||
ai = hostent2addrinfo(hp, pai);
|
||||
if (ai) {
|
||||
cur->ai_next = ai;
|
||||
while (cur->ai_next)
|
||||
cur = cur->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (sentinel.ai_next == NULL)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
|
||||
return(sentinel.ai_next);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static size_t
|
||||
ns_namelen(const char *s) {
|
||||
int i;
|
||||
|
||||
for (i = strlen(s); i > 0 && s[i-1] == '.'; i--)
|
||||
(void)NULL;
|
||||
return ((size_t) i);
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0U) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
@@ -1,446 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static const char rcsid[] = "$Id: lcl_ng.c,v 1.3 2005/04/27 04:56:31 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define NG_HOST 0 /*%< Host name */
|
||||
#define NG_USER 1 /*%< User name */
|
||||
#define NG_DOM 2 /*%< and Domain name */
|
||||
#define LINSIZ 1024 /*%< Length of netgroup file line */
|
||||
/*
|
||||
* XXX Warning XXX
|
||||
* This code is a hack-and-slash special. It realy needs to be
|
||||
* rewritten with things like strdup, and realloc in mind.
|
||||
* More reasonable data structures would not be a bad thing.
|
||||
*/
|
||||
|
||||
/*%
|
||||
* Static Variables and functions used by setnetgrent(), getnetgrent() and
|
||||
* endnetgrent().
|
||||
*
|
||||
* There are two linked lists:
|
||||
* \li linelist is just used by setnetgrent() to parse the net group file via.
|
||||
* parse_netgrp()
|
||||
* \li netgrp is the list of entries for the current netgroup
|
||||
*/
|
||||
struct linelist {
|
||||
struct linelist *l_next; /*%< Chain ptr. */
|
||||
int l_parsed; /*%< Flag for cycles */
|
||||
char * l_groupname; /*%< Name of netgroup */
|
||||
char * l_line; /*%< Netgroup entrie(s) to be parsed */
|
||||
};
|
||||
|
||||
struct ng_old_struct {
|
||||
struct ng_old_struct *ng_next; /*%< Chain ptr */
|
||||
char * ng_str[3]; /*%< Field pointers, see below */
|
||||
};
|
||||
|
||||
struct pvt {
|
||||
FILE *fp;
|
||||
struct linelist *linehead;
|
||||
struct ng_old_struct *nextgrp;
|
||||
struct {
|
||||
struct ng_old_struct *gr;
|
||||
char *grname;
|
||||
} grouphead;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_rewind(struct irs_ng *, const char*);
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *, const char *,
|
||||
const char *, const char *,
|
||||
const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
static int parse_netgrp(struct irs_ng *, const char*);
|
||||
static struct linelist *read_for_group(struct irs_ng *, const char *);
|
||||
static void freelists(struct irs_ng *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_lcl_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL)
|
||||
fclose(pvt->fp);
|
||||
freelists(this);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Parse the netgroup file looking for the netgroup and build the list
|
||||
* of netgrp structures. Let parse_netgrp() and read_for_group() do
|
||||
* most of the work.
|
||||
*/
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL && fseek(pvt->fp, SEEK_CUR, 0L) == -1) {
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
|
||||
if (pvt->fp == NULL || pvt->grouphead.gr == NULL ||
|
||||
strcmp(group, pvt->grouphead.grname)) {
|
||||
freelists(this);
|
||||
if (pvt->fp != NULL)
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = fopen(_PATH_NETGROUP, "r");
|
||||
if (pvt->fp != NULL) {
|
||||
if (parse_netgrp(this, group))
|
||||
freelists(this);
|
||||
if (!(pvt->grouphead.grname = strdup(group)))
|
||||
freelists(this);
|
||||
fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
pvt->nextgrp = pvt->grouphead.gr;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Get the next netgroup off the list.
|
||||
*/
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user,
|
||||
const char **domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->nextgrp) {
|
||||
*host = pvt->nextgrp->ng_str[NG_HOST];
|
||||
*user = pvt->nextgrp->ng_str[NG_USER];
|
||||
*domain = pvt->nextgrp->ng_str[NG_DOM];
|
||||
pvt->nextgrp = pvt->nextgrp->ng_next;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Search for a match in a netgroup.
|
||||
*/
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
const char *ng_host, *ng_user, *ng_domain;
|
||||
|
||||
ng_rewind(this, name);
|
||||
while (ng_next(this, &ng_host, &ng_user, &ng_domain))
|
||||
if ((host == NULL || ng_host == NULL ||
|
||||
!strcmp(host, ng_host)) &&
|
||||
(user == NULL || ng_user == NULL ||
|
||||
!strcmp(user, ng_user)) &&
|
||||
(domain == NULL || ng_domain == NULL ||
|
||||
!strcmp(domain, ng_domain))) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
freelists(this);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
/*%
|
||||
* endnetgrent() - cleanup
|
||||
*/
|
||||
static void
|
||||
freelists(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct linelist *lp, *olp;
|
||||
struct ng_old_struct *gp, *ogp;
|
||||
|
||||
lp = pvt->linehead;
|
||||
while (lp) {
|
||||
olp = lp;
|
||||
lp = lp->l_next;
|
||||
free(olp->l_groupname);
|
||||
free(olp->l_line);
|
||||
free((char *)olp);
|
||||
}
|
||||
pvt->linehead = NULL;
|
||||
if (pvt->grouphead.grname) {
|
||||
free(pvt->grouphead.grname);
|
||||
pvt->grouphead.grname = NULL;
|
||||
}
|
||||
gp = pvt->grouphead.gr;
|
||||
while (gp) {
|
||||
ogp = gp;
|
||||
gp = gp->ng_next;
|
||||
if (ogp->ng_str[NG_HOST])
|
||||
free(ogp->ng_str[NG_HOST]);
|
||||
if (ogp->ng_str[NG_USER])
|
||||
free(ogp->ng_str[NG_USER]);
|
||||
if (ogp->ng_str[NG_DOM])
|
||||
free(ogp->ng_str[NG_DOM]);
|
||||
free((char *)ogp);
|
||||
}
|
||||
pvt->grouphead.gr = NULL;
|
||||
}
|
||||
|
||||
/*%
|
||||
* Parse the netgroup file setting up the linked lists.
|
||||
*/
|
||||
static int
|
||||
parse_netgrp(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *spos, *epos;
|
||||
int len, strpos;
|
||||
char *pos, *gpos;
|
||||
struct ng_old_struct *grp;
|
||||
struct linelist *lp = pvt->linehead;
|
||||
|
||||
/*
|
||||
* First, see if the line has already been read in.
|
||||
*/
|
||||
while (lp) {
|
||||
if (!strcmp(group, lp->l_groupname))
|
||||
break;
|
||||
lp = lp->l_next;
|
||||
}
|
||||
if (lp == NULL &&
|
||||
(lp = read_for_group(this, group)) == NULL)
|
||||
return (1);
|
||||
if (lp->l_parsed) {
|
||||
/*fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);*/
|
||||
return (1);
|
||||
} else
|
||||
lp->l_parsed = 1;
|
||||
pos = lp->l_line;
|
||||
while (*pos != '\0') {
|
||||
if (*pos == '(') {
|
||||
if (!(grp = malloc(sizeof (struct ng_old_struct)))) {
|
||||
freelists(this);
|
||||
errno = ENOMEM;
|
||||
return (1);
|
||||
}
|
||||
memset(grp, 0, sizeof (struct ng_old_struct));
|
||||
grp->ng_next = pvt->grouphead.gr;
|
||||
pvt->grouphead.gr = grp;
|
||||
pos++;
|
||||
gpos = strsep(&pos, ")");
|
||||
for (strpos = 0; strpos < 3; strpos++) {
|
||||
if ((spos = strsep(&gpos, ","))) {
|
||||
while (*spos == ' ' || *spos == '\t')
|
||||
spos++;
|
||||
if ((epos = strpbrk(spos, " \t"))) {
|
||||
*epos = '\0';
|
||||
len = epos - spos;
|
||||
} else
|
||||
len = strlen(spos);
|
||||
if (len > 0) {
|
||||
if(!(grp->ng_str[strpos]
|
||||
= (char *)
|
||||
malloc(len + 1))) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
memcpy(grp->ng_str[strpos],
|
||||
spos,
|
||||
len + 1);
|
||||
}
|
||||
} else
|
||||
goto errout;
|
||||
}
|
||||
} else {
|
||||
spos = strsep(&pos, ", \t");
|
||||
if (spos != NULL && parse_netgrp(this, spos)) {
|
||||
freelists(this);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (pos == NULL)
|
||||
break;
|
||||
while (*pos == ' ' || *pos == ',' || *pos == '\t')
|
||||
pos++;
|
||||
}
|
||||
return (0);
|
||||
errout:
|
||||
/*fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname,
|
||||
spos);*/
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*%
|
||||
* Read the netgroup file and save lines until the line for the netgroup
|
||||
* is found. Return 1 if eof is encountered.
|
||||
*/
|
||||
static struct linelist *
|
||||
read_for_group(struct irs_ng *this, const char *group) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *pos, *spos, *linep = NULL, *olinep;
|
||||
int len, olen, cont;
|
||||
struct linelist *lp;
|
||||
char line[LINSIZ + 1];
|
||||
|
||||
while (fgets(line, LINSIZ, pvt->fp) != NULL) {
|
||||
pos = line;
|
||||
if (*pos == '#')
|
||||
continue;
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
spos = pos;
|
||||
while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
|
||||
*pos != '\0')
|
||||
pos++;
|
||||
len = pos - spos;
|
||||
while (*pos == ' ' || *pos == '\t')
|
||||
pos++;
|
||||
if (*pos != '\n' && *pos != '\0') {
|
||||
if (!(lp = malloc(sizeof (*lp)))) {
|
||||
freelists(this);
|
||||
return (NULL);
|
||||
}
|
||||
lp->l_parsed = 0;
|
||||
if (!(lp->l_groupname = malloc(len + 1))) {
|
||||
free(lp);
|
||||
freelists(this);
|
||||
return (NULL);
|
||||
}
|
||||
memcpy(lp->l_groupname, spos, len);
|
||||
*(lp->l_groupname + len) = '\0';
|
||||
len = strlen(pos);
|
||||
olen = 0;
|
||||
olinep = NULL;
|
||||
|
||||
/*
|
||||
* Loop around handling line continuations.
|
||||
*/
|
||||
do {
|
||||
if (*(pos + len - 1) == '\n')
|
||||
len--;
|
||||
if (*(pos + len - 1) == '\\') {
|
||||
len--;
|
||||
cont = 1;
|
||||
} else
|
||||
cont = 0;
|
||||
if (len > 0) {
|
||||
if (!(linep = malloc(olen + len + 1))){
|
||||
if (olen > 0)
|
||||
free(olinep);
|
||||
free(lp->l_groupname);
|
||||
free(lp);
|
||||
freelists(this);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
if (olen > 0) {
|
||||
memcpy(linep, olinep, olen);
|
||||
free(olinep);
|
||||
}
|
||||
memcpy(linep + olen, pos, len);
|
||||
olen += len;
|
||||
*(linep + olen) = '\0';
|
||||
olinep = linep;
|
||||
}
|
||||
if (cont) {
|
||||
if (fgets(line, LINSIZ, pvt->fp)) {
|
||||
pos = line;
|
||||
len = strlen(pos);
|
||||
} else
|
||||
cont = 0;
|
||||
}
|
||||
} while (cont);
|
||||
lp->l_line = linep;
|
||||
lp->l_next = pvt->linehead;
|
||||
pvt->linehead = lp;
|
||||
|
||||
/*
|
||||
* If this is the one we wanted, we are done.
|
||||
*/
|
||||
if (!strcmp(lp->l_groupname, group))
|
||||
return (lp);
|
||||
}
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,373 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_nw.c,v 1.4 2005/04/27 04:56:31 sra Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include <isc/misc.h>
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRSIZE 4
|
||||
|
||||
struct pvt {
|
||||
FILE * fp;
|
||||
char line[BUFSIZ+1];
|
||||
struct nwent net;
|
||||
char * aliases[MAXALIASES];
|
||||
char addr[MAXADDRSIZE];
|
||||
struct __res_state * res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nw_close(struct irs_nw *);
|
||||
static struct nwent * nw_byname(struct irs_nw *, const char *, int);
|
||||
static struct nwent * nw_byaddr(struct irs_nw *, void *, int, int);
|
||||
static struct nwent * nw_next(struct irs_nw *);
|
||||
static void nw_rewind(struct irs_nw *);
|
||||
static void nw_minimize(struct irs_nw *);
|
||||
static struct __res_state * nw_res_get(struct irs_nw *this);
|
||||
static void nw_res_set(struct irs_nw *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
|
||||
static int init(struct irs_nw *this);
|
||||
|
||||
/* Portability. */
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_nw *
|
||||
irs_lcl_nw(struct irs_acc *this) {
|
||||
struct irs_nw *nw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(nw = memget(sizeof *nw))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nw, 0x5e, sizeof *nw);
|
||||
nw->private = pvt;
|
||||
nw->close = nw_close;
|
||||
nw->byname = nw_byname;
|
||||
nw->byaddr = nw_byaddr;
|
||||
nw->next = nw_next;
|
||||
nw->rewind = nw_rewind;
|
||||
nw->minimize = nw_minimize;
|
||||
nw->res_get = nw_res_get;
|
||||
nw->res_set = nw_res_set;
|
||||
return (nw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
nw_close(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
nw_minimize(this);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
if (pvt->fp)
|
||||
(void)fclose(pvt->fp);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byaddr(struct irs_nw *this, void *net, int length, int type) {
|
||||
struct nwent *p;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
nw_rewind(this);
|
||||
while ((p = nw_next(this)) != NULL)
|
||||
if (p->n_addrtype == type && p->n_length == length)
|
||||
if (bitncmp(p->n_addr, net, length) == 0)
|
||||
break;
|
||||
return (p);
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_byname(struct irs_nw *this, const char *name, int type) {
|
||||
struct nwent *p;
|
||||
char **ap;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
nw_rewind(this);
|
||||
while ((p = nw_next(this)) != NULL) {
|
||||
if (ns_samename(p->n_name, name) == 1 &&
|
||||
p->n_addrtype == type)
|
||||
break;
|
||||
for (ap = p->n_aliases; *ap; ap++)
|
||||
if ((ns_samename(*ap, name) == 1) &&
|
||||
(p->n_addrtype == type))
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
return (p);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_rewind(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->fp) {
|
||||
if (fseek(pvt->fp, 0L, SEEK_SET) == 0)
|
||||
return;
|
||||
(void)fclose(pvt->fp);
|
||||
}
|
||||
if (!(pvt->fp = fopen(_PATH_NETWORKS, "r")))
|
||||
return;
|
||||
if (fcntl(fileno(pvt->fp), F_SETFD, 1) < 0) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct nwent *
|
||||
nw_next(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct nwent *ret = NULL;
|
||||
char *p, *cp, **q;
|
||||
char *bufp, *ndbuf, *dbuf = NULL;
|
||||
int c, bufsiz, offset = 0;
|
||||
|
||||
if (init(this) == -1)
|
||||
return(NULL);
|
||||
|
||||
if (pvt->fp == NULL)
|
||||
nw_rewind(this);
|
||||
if (pvt->fp == NULL) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
bufp = pvt->line;
|
||||
bufsiz = sizeof(pvt->line);
|
||||
|
||||
again:
|
||||
p = fgets(bufp + offset, bufsiz - offset, pvt->fp);
|
||||
if (p == NULL)
|
||||
goto cleanup;
|
||||
if (!strchr(p, '\n') && !feof(pvt->fp)) {
|
||||
#define GROWBUF 1024
|
||||
/* allocate space for longer line */
|
||||
if (dbuf == NULL) {
|
||||
if ((ndbuf = malloc(bufsiz + GROWBUF)) != NULL)
|
||||
strcpy(ndbuf, bufp);
|
||||
} else
|
||||
ndbuf = realloc(dbuf, bufsiz + GROWBUF);
|
||||
if (ndbuf) {
|
||||
dbuf = ndbuf;
|
||||
bufp = dbuf;
|
||||
bufsiz += GROWBUF;
|
||||
offset = strlen(dbuf);
|
||||
} else {
|
||||
/* allocation failed; skip this long line */
|
||||
while ((c = getc(pvt->fp)) != EOF)
|
||||
if (c == '\n')
|
||||
break;
|
||||
if (c != EOF)
|
||||
ungetc(c, pvt->fp);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
|
||||
p -= offset;
|
||||
offset = 0;
|
||||
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
pvt->net.n_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
pvt->net.n_length = inet_net_pton(AF_INET, cp, pvt->addr,
|
||||
sizeof pvt->addr);
|
||||
if (pvt->net.n_length < 0)
|
||||
goto again;
|
||||
pvt->net.n_addrtype = AF_INET;
|
||||
pvt->net.n_addr = pvt->addr;
|
||||
q = pvt->net.n_aliases = pvt->aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
ret = &pvt->net;
|
||||
|
||||
cleanup:
|
||||
if (dbuf)
|
||||
free(dbuf);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_minimize(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
if (pvt->fp != NULL) {
|
||||
(void)fclose(pvt->fp);
|
||||
pvt->fp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
nw_res_get(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
nw_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nw_res_set(struct irs_nw *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_nw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !nw_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0U) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*! \file */
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: lcl_p.h,v 1.3 2005/04/27 04:56:31 sra Exp $
|
||||
*/
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* lcl_p.h - private include file for the local accessor functions.
|
||||
*/
|
||||
|
||||
#ifndef _LCL_P_H_INCLUDED
|
||||
#define _LCL_P_H_INCLUDED
|
||||
|
||||
/*%
|
||||
* Object state.
|
||||
*/
|
||||
struct lcl_p {
|
||||
struct __res_state * res;
|
||||
void (*free_res) __P((void *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Externs.
|
||||
*/
|
||||
|
||||
extern struct irs_acc * irs_lcl_acc __P((const char *));
|
||||
extern struct irs_gr * irs_lcl_gr __P((struct irs_acc *));
|
||||
extern struct irs_pw * irs_lcl_pw __P((struct irs_acc *));
|
||||
extern struct irs_sv * irs_lcl_sv __P((struct irs_acc *));
|
||||
extern struct irs_pr * irs_lcl_pr __P((struct irs_acc *));
|
||||
extern struct irs_ho * irs_lcl_ho __P((struct irs_acc *));
|
||||
extern struct irs_nw * irs_lcl_nw __P((struct irs_acc *));
|
||||
extern struct irs_ng * irs_lcl_ng __P((struct irs_acc *));
|
||||
|
||||
#endif /*_LCL_P_H_INCLUDED*/
|
||||
@@ -1,209 +0,0 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <irs.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
struct private_data {
|
||||
struct protoent proto;
|
||||
char *proto_aliases[MAXALIASES];
|
||||
int index;
|
||||
};
|
||||
|
||||
// TODO: for now, this should later be exported dynamically by the stack
|
||||
const struct protocol {
|
||||
const char *name;
|
||||
const char *alias;
|
||||
int number;
|
||||
} kProtocols[] = {
|
||||
{"ip", "IP", 0}, // internet protocol, pseudo protocol number
|
||||
{"icmp", "ICMP", 1}, // internet control message protocol
|
||||
{"tcp", "TCP", 6}, // transmission control protocol
|
||||
{"udp", "UDP", 17}, // user datagram protocol"
|
||||
};
|
||||
const size_t kProtocolsCount = sizeof(kProtocols) / sizeof(kProtocols[0]);
|
||||
|
||||
|
||||
static void
|
||||
pr_close(struct irs_pr *this)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)this->private;
|
||||
|
||||
memput(data, sizeof *data);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pr_rewind(struct irs_pr *this)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)this->private;
|
||||
data->index = 0;
|
||||
}
|
||||
|
||||
|
||||
static struct protoent *
|
||||
pr_next(struct irs_pr *this)
|
||||
{
|
||||
struct private_data *data = (struct private_data *)this->private;
|
||||
struct protoent *entry = &data->proto;
|
||||
size_t i = data->index++;
|
||||
if (i >= kProtocolsCount)
|
||||
return NULL;
|
||||
|
||||
data->proto_aliases[0] = (char *)kProtocols[i].alias;
|
||||
data->proto_aliases[1] = NULL;
|
||||
|
||||
entry->p_proto = kProtocols[i].number;
|
||||
entry->p_name = (char *)kProtocols[i].name;
|
||||
entry->p_aliases = data->proto_aliases;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
static struct protoent *
|
||||
pr_byname(struct irs_pr *this, const char *name)
|
||||
{
|
||||
struct protoent *p;
|
||||
char **cp;
|
||||
|
||||
pr_rewind(this);
|
||||
while ((p = pr_next(this))) {
|
||||
if (!strcmp(p->p_name, name))
|
||||
return p;
|
||||
for (cp = p->p_aliases; *cp; cp++) {
|
||||
if (!strcmp(*cp, name))
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct protoent *
|
||||
pr_bynumber(struct irs_pr *this, int proto)
|
||||
{
|
||||
struct protoent *p;
|
||||
|
||||
pr_rewind(this);
|
||||
while ((p = pr_next(this))) {
|
||||
if (p->p_proto == proto)
|
||||
break;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pr_minimize(struct irs_pr *this)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
struct irs_pr *
|
||||
irs_lcl_pr(struct irs_acc *this)
|
||||
{
|
||||
struct irs_pr *pr;
|
||||
struct private_data *data;
|
||||
|
||||
if (!(pr = memget(sizeof *pr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
if (!(data = memget(sizeof *data))) {
|
||||
memput(pr, sizeof *this);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(data, 0, sizeof *data);
|
||||
|
||||
pr->private = data;
|
||||
pr->close = pr_close;
|
||||
pr->byname = pr_byname;
|
||||
pr->bynumber = pr_bynumber;
|
||||
pr->next = pr_next;
|
||||
pr->rewind = pr_rewind;
|
||||
pr->minimize = pr_minimize;
|
||||
pr->res_get = NULL;
|
||||
pr->res_set = NULL;
|
||||
return pr;
|
||||
}
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: lcl_pw.c,v 1.3 2005/04/27 04:56:31 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Extern */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_PW
|
||||
static int __bind_irs_pw_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <db.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "lcl_p.h"
|
||||
|
||||
/*! \file
|
||||
* \brief
|
||||
* The lookup techniques and data extraction code here must be kept
|
||||
* in sync with that in `pwd_mkdb'.
|
||||
*/
|
||||
|
||||
|
||||
/* Types */
|
||||
|
||||
struct pvt {
|
||||
struct passwd passwd; /*%< password structure */
|
||||
DB *pw_db; /*%< password database */
|
||||
int pw_keynum; /*%< key counter */
|
||||
int warned;
|
||||
u_int max;
|
||||
char * line;
|
||||
};
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void pw_close(struct irs_pw *);
|
||||
static struct passwd * pw_next(struct irs_pw *);
|
||||
static struct passwd * pw_byname(struct irs_pw *, const char *);
|
||||
static struct passwd * pw_byuid(struct irs_pw *, uid_t);
|
||||
static void pw_rewind(struct irs_pw *);
|
||||
static void pw_minimize(struct irs_pw *);
|
||||
|
||||
static int initdb(struct pvt *);
|
||||
static int hashpw(struct irs_pw *, DBT *);
|
||||
|
||||
/* Public */
|
||||
struct irs_pw *
|
||||
irs_lcl_pw(struct irs_acc *this) {
|
||||
struct irs_pw *pw;
|
||||
struct pvt *pvt;
|
||||
|
||||
UNUSED(this);
|
||||
|
||||
if (!(pw = memget(sizeof *pw))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pw, 0x5e, sizeof *pw);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
free(pw);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pw->private = pvt;
|
||||
pw->close = pw_close;
|
||||
pw->next = pw_next;
|
||||
pw->byname = pw_byname;
|
||||
pw->byuid = pw_byuid;
|
||||
pw->rewind = pw_rewind;
|
||||
pw->minimize = pw_minimize;
|
||||
pw->res_get = NULL;
|
||||
pw->res_set = NULL;
|
||||
return (pw);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
pw_close(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pw_db) {
|
||||
(void)(pvt->pw_db->close)(pvt->pw_db);
|
||||
pvt->pw_db = NULL;
|
||||
}
|
||||
if (pvt->line)
|
||||
memput(pvt->line, pvt->max);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_next(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
DBT key;
|
||||
char bf[sizeof(pvt->pw_keynum) + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
++pvt->pw_keynum;
|
||||
bf[0] = _PW_KEYBYNUM;
|
||||
memcpy(bf + 1, (char *)&pvt->pw_keynum, sizeof(pvt->pw_keynum));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = sizeof(pvt->pw_keynum) + 1;
|
||||
return (hashpw(this, &key) ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
pw_byname(struct irs_pw *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
DBT key;
|
||||
int len, rval;
|
||||
char bf[UT_NAMESIZE + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
bf[0] = _PW_KEYBYNAME;
|
||||
len = strlen(name);
|
||||
memcpy(bf + 1, name, MIN(len, UT_NAMESIZE));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = len + 1;
|
||||
rval = hashpw(this, &key);
|
||||
|
||||
return (rval ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
|
||||
static struct passwd *
|
||||
pw_byuid(struct irs_pw *this, uid_t uid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
DBT key;
|
||||
int keyuid, rval;
|
||||
char bf[sizeof(keyuid) + 1];
|
||||
|
||||
if (!initdb(pvt))
|
||||
return (NULL);
|
||||
|
||||
bf[0] = _PW_KEYBYUID;
|
||||
keyuid = uid;
|
||||
memcpy(bf + 1, &keyuid, sizeof(keyuid));
|
||||
key.data = (u_char *)bf;
|
||||
key.size = sizeof(keyuid) + 1;
|
||||
rval = hashpw(this, &key);
|
||||
|
||||
return (rval ? &pvt->passwd : NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
pw_rewind(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->pw_keynum = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pw_minimize(struct irs_pw *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->pw_db != NULL) {
|
||||
(void) (*pvt->pw_db->close)(pvt->pw_db);
|
||||
pvt->pw_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
initdb(struct pvt *pvt) {
|
||||
const char *p;
|
||||
|
||||
if (pvt->pw_db) {
|
||||
if (lseek((*pvt->pw_db->fd)(pvt->pw_db), 0L, SEEK_CUR) >= 0L)
|
||||
return (1);
|
||||
else
|
||||
(void) (*pvt->pw_db->close)(pvt->pw_db);
|
||||
}
|
||||
pvt->pw_db = dbopen((p = _PATH_SMP_DB), O_RDONLY, 0, DB_HASH, NULL);
|
||||
if (!pvt->pw_db)
|
||||
pvt->pw_db = dbopen((p =_PATH_MP_DB), O_RDONLY,
|
||||
0, DB_HASH, NULL);
|
||||
if (pvt->pw_db)
|
||||
return (1);
|
||||
if (!pvt->warned) {
|
||||
syslog(LOG_ERR, "%s: %m", p);
|
||||
pvt->warned++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
hashpw(struct irs_pw *this, DBT *key) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char *p, *t, *l;
|
||||
DBT data;
|
||||
|
||||
if ((pvt->pw_db->get)(pvt->pw_db, key, &data, 0))
|
||||
return (0);
|
||||
p = (char *)data.data;
|
||||
if (data.size > pvt->max) {
|
||||
size_t newlen = pvt->max + 1024;
|
||||
char *p = memget(newlen);
|
||||
if (p == NULL) {
|
||||
return (0);
|
||||
}
|
||||
if (pvt->line != NULL) {
|
||||
memcpy(p, pvt->line, pvt->max);
|
||||
memput(pvt->line, pvt->max);
|
||||
}
|
||||
pvt->max = newlen;
|
||||
pvt->line = p;
|
||||
}
|
||||
|
||||
/* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
|
||||
t = pvt->line;
|
||||
l = pvt->line + pvt->max;
|
||||
#define EXPAND(e) if ((e = t) == NULL) return (0); else \
|
||||
do if (t >= l) return (0); while ((*t++ = *p++) != '\0')
|
||||
#define SCALAR(v) if (t + sizeof v >= l) return (0); else \
|
||||
(memmove(&(v), p, sizeof v), p += sizeof v)
|
||||
EXPAND(pvt->passwd.pw_name);
|
||||
EXPAND(pvt->passwd.pw_passwd);
|
||||
SCALAR(pvt->passwd.pw_uid);
|
||||
SCALAR(pvt->passwd.pw_gid);
|
||||
SCALAR(pvt->passwd.pw_change);
|
||||
EXPAND(pvt->passwd.pw_class);
|
||||
EXPAND(pvt->passwd.pw_gecos);
|
||||
EXPAND(pvt->passwd.pw_dir);
|
||||
EXPAND(pvt->passwd.pw_shell);
|
||||
SCALAR(pvt->passwd.pw_expire);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_PW */
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis.c,v 1.3 2005/04/27 04:56:32 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifdef WANT_IRS_NIS
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef T_NULL
|
||||
#undef T_NULL /* Silence re-definition warning of T_NULL. */
|
||||
#endif
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "hesiod.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void nis_close(struct irs_acc *);
|
||||
static struct __res_state * nis_res_get(struct irs_acc *);
|
||||
static void nis_res_set(struct irs_acc *, struct __res_state *,
|
||||
void (*)(void *));
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_acc *
|
||||
irs_nis_acc(const char *options) {
|
||||
struct nis_p *nis;
|
||||
struct irs_acc *acc;
|
||||
char *domain;
|
||||
|
||||
UNUSED(options);
|
||||
|
||||
if (yp_get_default_domain(&domain) != 0)
|
||||
return (NULL);
|
||||
if (!(nis = memget(sizeof *nis))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(nis, 0, sizeof *nis);
|
||||
if (!(acc = memget(sizeof *acc))) {
|
||||
memput(nis, sizeof *nis);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(acc, 0x5e, sizeof *acc);
|
||||
acc->private = nis;
|
||||
nis->domain = strdup(domain);
|
||||
#ifdef WANT_IRS_GR
|
||||
acc->gr_map = irs_nis_gr;
|
||||
#else
|
||||
acc->gr_map = NULL;
|
||||
#endif
|
||||
#ifdef WANT_IRS_PW
|
||||
acc->pw_map = irs_nis_pw;
|
||||
#else
|
||||
acc->pw_map = NULL;
|
||||
#endif
|
||||
acc->sv_map = irs_nis_sv;
|
||||
acc->pr_map = irs_nis_pr;
|
||||
acc->ho_map = irs_nis_ho;
|
||||
acc->nw_map = irs_nis_nw;
|
||||
acc->ng_map = irs_nis_ng;
|
||||
acc->res_get = nis_res_get;
|
||||
acc->res_set = nis_res_set;
|
||||
acc->close = nis_close;
|
||||
return (acc);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static struct __res_state *
|
||||
nis_res_get(struct irs_acc *this) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res == NULL) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (res == NULL)
|
||||
return (NULL);
|
||||
memset(res, 0, sizeof *res);
|
||||
nis_res_set(this, res, free);
|
||||
}
|
||||
|
||||
if ((nis->res->options & RES_INIT) == 0 &&
|
||||
res_ninit(nis->res) < 0)
|
||||
return (NULL);
|
||||
|
||||
return (nis->res);
|
||||
}
|
||||
|
||||
static void
|
||||
nis_res_set(struct irs_acc *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res && nis->free_res) {
|
||||
res_nclose(nis->res);
|
||||
(*nis->free_res)(nis->res);
|
||||
}
|
||||
|
||||
nis->res = res;
|
||||
nis->free_res = free_res;
|
||||
}
|
||||
|
||||
static void
|
||||
nis_close(struct irs_acc *this) {
|
||||
struct nis_p *nis = (struct nis_p *)this->private;
|
||||
|
||||
if (nis->res && nis->free_res)
|
||||
(*nis->free_res)(nis->res);
|
||||
free(nis->domain);
|
||||
memput(nis, sizeof *nis);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,354 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_gr.c,v 1.4 2005/04/27 04:56:32 sra Exp $";
|
||||
/* from getgrent.c 8.2 (Berkeley) 3/21/94"; */
|
||||
/* from BSDI Id: getgrent.c,v 2.8 1996/05/28 18:15:14 bostic Exp $ */
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#if !defined(WANT_IRS_GR) || !defined(WANT_IRS_NIS)
|
||||
static int __bind_irs_gr_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
/*%<
|
||||
* Need space to store the entries read from the group file.
|
||||
* The members list also needs space per member, and the
|
||||
* strings making up the user names must be allocated
|
||||
* somewhere. Rather than doing lots of small allocations,
|
||||
* we keep one buffer and resize it as needed.
|
||||
*/
|
||||
struct group group;
|
||||
size_t nmemb; /*%< Malloc'd max index of gr_mem[]. */
|
||||
char * membuf;
|
||||
size_t membufsize;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char group_bygid[] = "group.bygid";
|
||||
static /*const*/ char group_byname[] = "group.byname";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void gr_close(struct irs_gr *);
|
||||
static struct group * gr_next(struct irs_gr *);
|
||||
static struct group * gr_byname(struct irs_gr *, const char *);
|
||||
static struct group * gr_bygid(struct irs_gr *, gid_t);
|
||||
static void gr_rewind(struct irs_gr *);
|
||||
static void gr_minimize(struct irs_gr *);
|
||||
|
||||
static struct group * makegroupent(struct irs_gr *);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_gr *
|
||||
irs_nis_gr(struct irs_acc *this) {
|
||||
struct irs_gr *gr;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(gr = memget(sizeof *gr))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(gr, 0x5e, sizeof *gr);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(gr, sizeof *gr);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
gr->private = pvt;
|
||||
gr->close = gr_close;
|
||||
gr->next = gr_next;
|
||||
gr->byname = gr_byname;
|
||||
gr->bygid = gr_bygid;
|
||||
gr->rewind = gr_rewind;
|
||||
gr->list = make_group_list;
|
||||
gr->minimize = gr_minimize;
|
||||
gr->res_get = NULL;
|
||||
gr->res_set = NULL;
|
||||
return (gr);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
gr_close(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->group.gr_mem)
|
||||
free(pvt->group.gr_mem);
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_next(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct group *rval;
|
||||
int r;
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, group_byname,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, group_byname,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
rval = makegroupent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_byname(struct irs_gr *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_match(pvt->nis_domain, group_byname, name, strlen(name),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makegroupent(this));
|
||||
}
|
||||
|
||||
static struct group *
|
||||
gr_bygid(struct irs_gr *this, gid_t gid) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "4294967295"];
|
||||
int r;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
(void) sprintf(tmp, "%u", (unsigned int)gid);
|
||||
r = yp_match(pvt->nis_domain, group_bygid, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
errno = ENOENT;
|
||||
return (NULL);
|
||||
}
|
||||
return (makegroupent(this));
|
||||
}
|
||||
|
||||
static void
|
||||
gr_rewind(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
gr_minimize(struct irs_gr *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static struct group *
|
||||
makegroupent(struct irs_gr *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
unsigned int num_members = 0;
|
||||
char *cp, **new;
|
||||
u_long t;
|
||||
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
pvt->nmemb = 0;
|
||||
}
|
||||
if (pvt->membuf)
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = pvt->curval_data;
|
||||
pvt->curval_data = NULL;
|
||||
|
||||
cp = pvt->membuf;
|
||||
pvt->group.gr_name = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
pvt->group.gr_passwd = cp;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
*cp++ = '\0';
|
||||
|
||||
errno = 0;
|
||||
t = strtoul(cp, NULL, 10);
|
||||
if (errno == ERANGE)
|
||||
goto cleanup;
|
||||
pvt->group.gr_gid = (gid_t) t;
|
||||
if (!(cp = strchr(cp, ':')))
|
||||
goto cleanup;
|
||||
cp++;
|
||||
|
||||
if (*cp && cp[strlen(cp)-1] == '\n')
|
||||
cp[strlen(cp)-1] = '\0';
|
||||
|
||||
/*
|
||||
* Parse the members out.
|
||||
*/
|
||||
while (*cp) {
|
||||
if (num_members+1 >= pvt->nmemb || pvt->group.gr_mem == NULL) {
|
||||
pvt->nmemb += 10;
|
||||
new = realloc(pvt->group.gr_mem,
|
||||
pvt->nmemb * sizeof(char *));
|
||||
if (new == NULL)
|
||||
goto cleanup;
|
||||
pvt->group.gr_mem = new;
|
||||
}
|
||||
pvt->group.gr_mem[num_members++] = cp;
|
||||
if (!(cp = strchr(cp, ',')))
|
||||
break;
|
||||
*cp++ = '\0';
|
||||
}
|
||||
if (pvt->group.gr_mem == NULL) {
|
||||
pvt->group.gr_mem = malloc(sizeof(char*));
|
||||
if (!pvt->group.gr_mem)
|
||||
goto cleanup;
|
||||
pvt->nmemb = 1;
|
||||
}
|
||||
pvt->group.gr_mem[num_members] = NULL;
|
||||
|
||||
return (&pvt->group);
|
||||
|
||||
cleanup:
|
||||
if (pvt->group.gr_mem) {
|
||||
free(pvt->group.gr_mem);
|
||||
pvt->group.gr_mem = NULL;
|
||||
pvt->nmemb = 0;
|
||||
}
|
||||
if (pvt->membuf) {
|
||||
free(pvt->membuf);
|
||||
pvt->membuf = NULL;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WANT_IRS_GR && WANT_IRS_NIS */
|
||||
/*! \file */
|
||||
@@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_ho.c,v 1.5 2005/04/27 04:56:32 sra Exp $";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef T_NULL
|
||||
#undef T_NULL /* Silence re-definition warning of T_NULL. */
|
||||
#endif
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
struct pvt {
|
||||
int needrewind;
|
||||
char * nis_domain;
|
||||
char * curkey_data;
|
||||
int curkey_len;
|
||||
char * curval_data;
|
||||
int curval_len;
|
||||
struct hostent host;
|
||||
char * h_addr_ptrs[MAXADDRS + 1];
|
||||
char * host_aliases[MAXALIASES + 1];
|
||||
char hostbuf[8*1024];
|
||||
u_char host_addr[16]; /*%< IPv4 or IPv6 */
|
||||
struct __res_state *res;
|
||||
void (*free_res)(void *);
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
static /*const*/ char hosts_byname[] = "hosts.byname";
|
||||
static /*const*/ char hosts_byaddr[] = "hosts.byaddr";
|
||||
static /*const*/ char ipnode_byname[] = "ipnode.byname";
|
||||
static /*const*/ char ipnode_byaddr[] = "ipnode.byaddr";
|
||||
static /*const*/ char yp_multi[] = "YP_MULTI_";
|
||||
|
||||
/* Forwards */
|
||||
|
||||
static void ho_close(struct irs_ho *this);
|
||||
static struct hostent * ho_byname(struct irs_ho *this, const char *name);
|
||||
static struct hostent * ho_byname2(struct irs_ho *this, const char *name,
|
||||
int af);
|
||||
static struct hostent * ho_byaddr(struct irs_ho *this, const void *addr,
|
||||
int len, int af);
|
||||
static struct hostent * ho_next(struct irs_ho *this);
|
||||
static void ho_rewind(struct irs_ho *this);
|
||||
static void ho_minimize(struct irs_ho *this);
|
||||
static struct __res_state * ho_res_get(struct irs_ho *this);
|
||||
static void ho_res_set(struct irs_ho *this,
|
||||
struct __res_state *res,
|
||||
void (*free_res)(void *));
|
||||
static struct addrinfo * ho_addrinfo(struct irs_ho *this, const char *name,
|
||||
const struct addrinfo *pai);
|
||||
|
||||
static struct hostent * makehostent(struct irs_ho *this);
|
||||
static void nisfree(struct pvt *, enum do_what);
|
||||
static int init(struct irs_ho *this);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ho *
|
||||
irs_nis_ho(struct irs_acc *this) {
|
||||
struct irs_ho *ho;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
if (!(ho = memget(sizeof *ho))) {
|
||||
memput(pvt, sizeof *pvt);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ho, 0x5e, sizeof *ho);
|
||||
pvt->needrewind = 1;
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
ho->private = pvt;
|
||||
ho->close = ho_close;
|
||||
ho->byname = ho_byname;
|
||||
ho->byname2 = ho_byname2;
|
||||
ho->byaddr = ho_byaddr;
|
||||
ho->next = ho_next;
|
||||
ho->rewind = ho_rewind;
|
||||
ho->minimize = ho_minimize;
|
||||
ho->res_set = ho_res_set;
|
||||
ho->res_get = ho_res_get;
|
||||
ho->addrinfo = ho_addrinfo;
|
||||
return (ho);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ho_close(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
ho_minimize(this);
|
||||
nisfree(pvt, do_all);
|
||||
if (pvt->res && pvt->free_res)
|
||||
(*pvt->free_res)(pvt->res);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname(struct irs_ho *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
hp = ho_byname2(this, name, AF_INET6);
|
||||
if (hp)
|
||||
return (hp);
|
||||
}
|
||||
return (ho_byname2(this, name, AF_INET));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byname2(struct irs_ho *this, const char *name, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
int r;
|
||||
char *tmp;
|
||||
|
||||
UNUSED(af);
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
|
||||
strcpy(pvt->hostbuf, yp_multi);
|
||||
strncat(pvt->hostbuf, name, sizeof(pvt->hostbuf) - sizeof(yp_multi));
|
||||
pvt->hostbuf[sizeof(pvt->hostbuf) - 1] = '\0';
|
||||
for (r = sizeof(yp_multi) - 1; pvt->hostbuf[r] != '\0'; r++)
|
||||
if (isupper((unsigned char)pvt->hostbuf[r]))
|
||||
tolower(pvt->hostbuf[r]);
|
||||
|
||||
tmp = pvt->hostbuf;
|
||||
r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
|
||||
r = yp_match(pvt->nis_domain, ipnode_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf;
|
||||
r = yp_match(pvt->nis_domain, hosts_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
tmp = pvt->hostbuf + sizeof(yp_multi) - 1;
|
||||
r = yp_match(pvt->nis_domain, hosts_byname, tmp,
|
||||
strlen(tmp), &pvt->curval_data, &pvt->curval_len);
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
return (makehostent(this));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_byaddr(struct irs_ho *this, const void *addr, int len, int af) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
|
||||
const u_char *uaddr = addr;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!memcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!memcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr = (const u_char *)addr + sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
if (inet_ntop(af, uaddr, tmp, sizeof tmp) == NULL) {
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_INTERNAL);
|
||||
return (NULL);
|
||||
}
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_match(pvt->nis_domain, ipnode_byaddr, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0)
|
||||
r = yp_match(pvt->nis_domain, hosts_byaddr, tmp, strlen(tmp),
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
return (makehostent(this));
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
ho_next(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *rval;
|
||||
int r;
|
||||
|
||||
if (init(this) == -1)
|
||||
return (NULL);
|
||||
|
||||
do {
|
||||
if (pvt->needrewind) {
|
||||
nisfree(pvt, do_all);
|
||||
r = yp_first(pvt->nis_domain, hosts_byaddr,
|
||||
&pvt->curkey_data, &pvt->curkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
pvt->needrewind = 0;
|
||||
} else {
|
||||
char *newkey_data;
|
||||
int newkey_len;
|
||||
|
||||
nisfree(pvt, do_val);
|
||||
r = yp_next(pvt->nis_domain, hosts_byaddr,
|
||||
pvt->curkey_data, pvt->curkey_len,
|
||||
&newkey_data, &newkey_len,
|
||||
&pvt->curval_data, &pvt->curval_len);
|
||||
nisfree(pvt, do_key);
|
||||
pvt->curkey_data = newkey_data;
|
||||
pvt->curkey_len = newkey_len;
|
||||
}
|
||||
if (r != 0) {
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
return (NULL);
|
||||
}
|
||||
rval = makehostent(this);
|
||||
} while (rval == NULL);
|
||||
return (rval);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_rewind(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
pvt->needrewind = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
ho_minimize(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res)
|
||||
res_nclose(pvt->res);
|
||||
}
|
||||
|
||||
static struct __res_state *
|
||||
ho_res_get(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res) {
|
||||
struct __res_state *res;
|
||||
res = (struct __res_state *)malloc(sizeof *res);
|
||||
if (!res) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(res, 0, sizeof *res);
|
||||
ho_res_set(this, res, free);
|
||||
}
|
||||
|
||||
return (pvt->res);
|
||||
}
|
||||
|
||||
static void
|
||||
ho_res_set(struct irs_ho *this, struct __res_state *res,
|
||||
void (*free_res)(void *)) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (pvt->res && pvt->free_res) {
|
||||
res_nclose(pvt->res);
|
||||
(*pvt->free_res)(pvt->res);
|
||||
}
|
||||
|
||||
pvt->res = res;
|
||||
pvt->free_res = free_res;
|
||||
}
|
||||
|
||||
struct nis_res_target {
|
||||
struct nis_res_target *next;
|
||||
int family;
|
||||
};
|
||||
|
||||
/* XXX */
|
||||
extern struct addrinfo *hostent2addrinfo __P((struct hostent *,
|
||||
const struct addrinfo *pai));
|
||||
|
||||
static struct addrinfo *
|
||||
ho_addrinfo(struct irs_ho *this, const char *name, const struct addrinfo *pai)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct hostent *hp;
|
||||
struct nis_res_target q, q2, *p;
|
||||
struct addrinfo sentinel, *cur;
|
||||
|
||||
memset(&q, 0, sizeof(q2));
|
||||
memset(&q2, 0, sizeof(q2));
|
||||
memset(&sentinel, 0, sizeof(sentinel));
|
||||
cur = &sentinel;
|
||||
|
||||
switch(pai->ai_family) {
|
||||
case AF_UNSPEC: /*%< INET6 then INET4 */
|
||||
q.family = AF_INET6;
|
||||
q.next = &q2;
|
||||
q2.family = AF_INET;
|
||||
break;
|
||||
case AF_INET6:
|
||||
q.family = AF_INET6;
|
||||
break;
|
||||
case AF_INET:
|
||||
q.family = AF_INET;
|
||||
break;
|
||||
default:
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY); /*%< ??? */
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
for (p = &q; p; p = p->next) {
|
||||
struct addrinfo *ai;
|
||||
|
||||
hp = (*this->byname2)(this, name, p->family);
|
||||
if (hp == NULL) {
|
||||
/* byname2 should've set an appropriate error */
|
||||
continue;
|
||||
}
|
||||
if ((hp->h_name == NULL) || (hp->h_name[0] == 0) ||
|
||||
(hp->h_addr_list[0] == NULL)) {
|
||||
RES_SET_H_ERRNO(pvt->res, NO_RECOVERY);
|
||||
continue;
|
||||
}
|
||||
ai = hostent2addrinfo(hp, pai);
|
||||
if (ai) {
|
||||
cur->ai_next = ai;
|
||||
while (cur && cur->ai_next)
|
||||
cur = cur->ai_next;
|
||||
}
|
||||
}
|
||||
|
||||
if (sentinel.ai_next == NULL)
|
||||
RES_SET_H_ERRNO(pvt->res, HOST_NOT_FOUND);
|
||||
|
||||
return(sentinel.ai_next);
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
/*%
|
||||
ipnodes:
|
||||
::1 localhost
|
||||
127.0.0.1 localhost
|
||||
1.2.3.4 FOO bar
|
||||
1.2.6.4 FOO bar
|
||||
1.2.6.5 host
|
||||
|
||||
ipnodes.byname:
|
||||
YP_MULTI_localhost ::1,127.0.0.1 localhost
|
||||
YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
|
||||
YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
|
||||
host 1.2.6.5 host
|
||||
|
||||
hosts.byname:
|
||||
localhost 127.0.0.1 localhost
|
||||
host 1.2.6.5 host
|
||||
YP_MULTI_foo 1.2.3.4,1.2.6.4 FOO bar
|
||||
YP_MULTI_bar 1.2.3.4,1.2.6.4 FOO bar
|
||||
*/
|
||||
|
||||
static struct hostent *
|
||||
makehostent(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
static const char spaces[] = " \t";
|
||||
char *cp, **q, *p, *comma, *ap;
|
||||
int af = 0, len = 0;
|
||||
int multi = 0;
|
||||
int addr = 0;
|
||||
|
||||
p = pvt->curval_data;
|
||||
if ((cp = strpbrk(p, "#\n")) != NULL)
|
||||
*cp = '\0';
|
||||
if (!(cp = strpbrk(p, spaces)))
|
||||
return (NULL);
|
||||
*cp++ = '\0';
|
||||
ap = pvt->hostbuf;
|
||||
do {
|
||||
if ((comma = strchr(p, ',')) != NULL) {
|
||||
*comma++ = '\0';
|
||||
multi = 1;
|
||||
}
|
||||
if ((ap + IN6ADDRSZ) > (pvt->hostbuf + sizeof(pvt->hostbuf)))
|
||||
break;
|
||||
if ((pvt->res->options & RES_USE_INET6) &&
|
||||
inet_pton(AF_INET6, p, ap) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_pton(AF_INET, p, pvt->host_addr) > 0) {
|
||||
if (pvt->res->options & RES_USE_INET6) {
|
||||
map_v4v6_address((char*)pvt->host_addr, ap);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
} else {
|
||||
if (!multi)
|
||||
return (NULL);
|
||||
continue;
|
||||
}
|
||||
if (addr < MAXADDRS) {
|
||||
pvt->h_addr_ptrs[addr++] = ap;
|
||||
pvt->h_addr_ptrs[addr] = NULL;
|
||||
ap += len;
|
||||
}
|
||||
} while ((p = comma) != NULL);
|
||||
if (ap == pvt->hostbuf)
|
||||
return (NULL);
|
||||
pvt->host.h_addr_list = pvt->h_addr_ptrs;
|
||||
pvt->host.h_length = len;
|
||||
pvt->host.h_addrtype = af;
|
||||
cp += strspn(cp, spaces);
|
||||
pvt->host.h_name = cp;
|
||||
q = pvt->host.h_aliases = pvt->host_aliases;
|
||||
if ((cp = strpbrk(cp, spaces)) != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &pvt->host_aliases[MAXALIASES])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, spaces)) != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
RES_SET_H_ERRNO(pvt->res, NETDB_SUCCESS);
|
||||
return (&pvt->host);
|
||||
}
|
||||
|
||||
static void
|
||||
nisfree(struct pvt *pvt, enum do_what do_what) {
|
||||
if ((do_what & do_key) && pvt->curkey_data) {
|
||||
free(pvt->curkey_data);
|
||||
pvt->curkey_data = NULL;
|
||||
}
|
||||
if ((do_what & do_val) && pvt->curval_data) {
|
||||
free(pvt->curval_data);
|
||||
pvt->curval_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init(struct irs_ho *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->res && !ho_res_get(this))
|
||||
return (-1);
|
||||
if (((pvt->res->options & RES_INIT) == 0) &&
|
||||
res_ninit(pvt->res) == -1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
|
||||
/*! \file */
|
||||
@@ -1,304 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
||||
* Copyright (c) 1996,1999 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char rcsid[] = "$Id: nis_ng.c,v 1.4 2005/04/27 04:56:32 sra Exp $";
|
||||
#endif
|
||||
|
||||
/* Imports */
|
||||
|
||||
#include "port_before.h"
|
||||
|
||||
#ifndef WANT_IRS_NIS
|
||||
static int __bind_irs_nis_unneeded;
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/xdr.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#ifdef T_NULL
|
||||
#undef T_NULL /* Silence re-definition warning of T_NULL. */
|
||||
#endif
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <isc/memcluster.h>
|
||||
#include <irs.h>
|
||||
|
||||
#include "port_after.h"
|
||||
|
||||
#include "irs_p.h"
|
||||
#include "nis_p.h"
|
||||
|
||||
/* Definitions */
|
||||
|
||||
struct tmpgrp {
|
||||
const char * name;
|
||||
const char * host;
|
||||
const char * user;
|
||||
const char * domain;
|
||||
struct tmpgrp * next;
|
||||
};
|
||||
|
||||
struct pvt {
|
||||
char * nis_domain;
|
||||
struct tmpgrp * tmp;
|
||||
struct tmpgrp * cur;
|
||||
char * tmpgroup;
|
||||
};
|
||||
|
||||
enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
|
||||
|
||||
static /*const*/ char netgroup_map[] = "netgroup";
|
||||
|
||||
/* Forward */
|
||||
|
||||
static void ng_close(struct irs_ng *);
|
||||
static int ng_next(struct irs_ng *, const char **,
|
||||
const char **, const char **);
|
||||
static int ng_test(struct irs_ng *,
|
||||
const char *, const char *,
|
||||
const char *, const char *);
|
||||
static void ng_rewind(struct irs_ng *, const char *);
|
||||
static void ng_minimize(struct irs_ng *);
|
||||
|
||||
static void add_group_to_list(struct pvt *, const char *, int);
|
||||
static void add_tuple_to_list(struct pvt *, const char *, char *);
|
||||
static void tmpfree(struct pvt *);
|
||||
|
||||
/* Public */
|
||||
|
||||
struct irs_ng *
|
||||
irs_nis_ng(struct irs_acc *this) {
|
||||
struct irs_ng *ng;
|
||||
struct pvt *pvt;
|
||||
|
||||
if (!(ng = memget(sizeof *ng))) {
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(ng, 0x5e, sizeof *ng);
|
||||
if (!(pvt = memget(sizeof *pvt))) {
|
||||
memput(ng, sizeof *ng);
|
||||
errno = ENOMEM;
|
||||
return (NULL);
|
||||
}
|
||||
memset(pvt, 0, sizeof *pvt);
|
||||
pvt->nis_domain = ((struct nis_p *)this->private)->domain;
|
||||
ng->private = pvt;
|
||||
ng->close = ng_close;
|
||||
ng->next = ng_next;
|
||||
ng->test = ng_test;
|
||||
ng->rewind = ng_rewind;
|
||||
ng->minimize = ng_minimize;
|
||||
return (ng);
|
||||
}
|
||||
|
||||
/* Methods */
|
||||
|
||||
static void
|
||||
ng_close(struct irs_ng *this) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
tmpfree(pvt);
|
||||
memput(pvt, sizeof *pvt);
|
||||
memput(this, sizeof *this);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_next(struct irs_ng *this, const char **host, const char **user, const char **domain) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
if (!pvt->cur)
|
||||
return (0);
|
||||
*host = pvt->cur->host;
|
||||
*user = pvt->cur->user;
|
||||
*domain = pvt->cur->domain;
|
||||
pvt->cur = pvt->cur->next;
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ng_test(struct irs_ng *this, const char *name,
|
||||
const char *host, const char *user, const char *domain)
|
||||
{
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
struct tmpgrp *cur;
|
||||
|
||||
tmpfree(pvt);
|
||||
add_group_to_list(pvt, name, strlen(name));
|
||||
for (cur = pvt->tmp; cur; cur = cur->next) {
|
||||
if ((!host || !cur->host || !strcmp(host, cur->host)) &&
|
||||
(!user || !cur->user || !strcmp(user, cur->user)) &&
|
||||
(!domain || !cur->domain || !strcmp(domain, cur->domain)))
|
||||
break;
|
||||
}
|
||||
tmpfree(pvt);
|
||||
return ((cur == NULL) ? 0 : 1);
|
||||
}
|
||||
|
||||
static void
|
||||
ng_rewind(struct irs_ng *this, const char *name) {
|
||||
struct pvt *pvt = (struct pvt *)this->private;
|
||||
|
||||
/* Either hand back or free the existing list. */
|
||||
if (pvt->tmpgroup) {
|
||||
if (pvt->tmp && !strcmp(pvt->tmpgroup, name))
|
||||
goto reset;
|
||||
tmpfree(pvt);
|
||||
}
|
||||
pvt->tmpgroup = strdup(name);
|
||||
add_group_to_list(pvt, name, strlen(name));
|
||||
reset:
|
||||
pvt->cur = pvt->tmp;
|
||||
}
|
||||
|
||||
static void
|
||||
ng_minimize(struct irs_ng *this) {
|
||||
UNUSED(this);
|
||||
/* NOOP */
|
||||
}
|
||||
|
||||
/* Private */
|
||||
|
||||
static void
|
||||
add_group_to_list(struct pvt *pvt, const char *name, int len) {
|
||||
char *vdata, *cp, *np;
|
||||
struct tmpgrp *tmp;
|
||||
int vlen, r;
|
||||
char *nametmp;
|
||||
|
||||
/* Don't add the same group to the list more than once. */
|
||||
for (tmp = pvt->tmp; tmp; tmp = tmp->next)
|
||||
if (!strcmp(tmp->name, name))
|
||||
return;
|
||||
|
||||
DE_CONST(name, nametmp);
|
||||
r = yp_match(pvt->nis_domain, netgroup_map, nametmp, len,
|
||||
&vdata, &vlen);
|
||||
if (r == 0) {
|
||||
cp = vdata;
|
||||
if (*cp && cp[strlen(cp)-1] == '\n')
|
||||
cp[strlen(cp)-1] = '\0';
|
||||
for ( ; cp; cp = np) {
|
||||
np = strchr(cp, ' ');
|
||||
if (np)
|
||||
*np++ = '\0';
|
||||
if (*cp == '(')
|
||||
add_tuple_to_list(pvt, name, cp);
|
||||
else
|
||||
add_group_to_list(pvt, cp, strlen(cp));
|
||||
}
|
||||
free(vdata);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_tuple_to_list(struct pvt *pvt, const char *name, char *cp) {
|
||||
struct tmpgrp *tmp;
|
||||
char *tp, *np;
|
||||
|
||||
INSIST(*cp++ == '(');
|
||||
|
||||
tmp = malloc(sizeof *tmp + strlen(name) + sizeof '\0' +
|
||||
strlen(cp) - sizeof ')');
|
||||
if (!tmp)
|
||||
return;
|
||||
memset(tmp, 0, sizeof *tmp);
|
||||
tp = ((char *)tmp) + sizeof *tmp;
|
||||
|
||||
/* Name */
|
||||
strcpy(tp, name);
|
||||
tmp->name = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
|
||||
/* Host */
|
||||
if (!(np = strchr(cp, ',')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->host = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
cp = np;
|
||||
|
||||
/* User */
|
||||
if (!(np = strchr(cp, ',')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->user = tp;
|
||||
tp += strlen(tp) + 1;
|
||||
cp = np;
|
||||
|
||||
/* Domain */
|
||||
if (!(np = strchr(cp, ')')))
|
||||
goto cleanup;
|
||||
*np++ = '\0';
|
||||
strcpy(tp, cp);
|
||||
tmp->domain = tp;
|
||||
|
||||
/*
|
||||
* Empty string in file means wildcard, but
|
||||
* NULL string in return value means wildcard.
|
||||
*/
|
||||
if (!*tmp->host)
|
||||
tmp->host = NULL;
|
||||
if (!*tmp->user)
|
||||
tmp->user = NULL;
|
||||
if (!*tmp->domain)
|
||||
tmp->domain = NULL;
|
||||
|
||||
/* Add to list (LIFO). */
|
||||
tmp->next = pvt->tmp;
|
||||
pvt->tmp = tmp;
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
tmpfree(struct pvt *pvt) {
|
||||
struct tmpgrp *cur, *next;
|
||||
|
||||
if (pvt->tmpgroup) {
|
||||
free(pvt->tmpgroup);
|
||||
pvt->tmpgroup = NULL;
|
||||
}
|
||||
for (cur = pvt->tmp; cur; cur = next) {
|
||||
next = cur->next;
|
||||
free(cur);
|
||||
}
|
||||
pvt->tmp = NULL;
|
||||
}
|
||||
|
||||
#endif /*WANT_IRS_NIS*/
|
||||
|
||||
/*! \file */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user