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:
Adrien Destugues
2015-06-14 15:47:03 +02:00
parent 7c3d316b5d
commit 8d2aee6bc8
147 changed files with 29727 additions and 26889 deletions
+5 -1
View File
@@ -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
+278
View File
@@ -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&microsoft.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.
+4 -4
View File
@@ -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);
+4 -4
View File
@@ -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
View File
@@ -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_ */
+9
View File
@@ -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;
+9 -2
View File
@@ -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
+5 -1
View File
@@ -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++ ]
;
+157
View File
@@ -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;
}
}
+21 -43
View File
@@ -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
+69 -20
View File
@@ -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_ */
+231
View File
@@ -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 */
+10 -8
View File
@@ -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);
+18 -5
View File
@@ -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;
+21 -9
View File
@@ -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 */
-46
View File
@@ -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 */
+12 -6
View 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);
+14 -12
View File
@@ -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
+35 -34
View File
@@ -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);
+79 -65
View File
@@ -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));
+41 -34
View File
@@ -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:
+12 -6
View File
@@ -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);
+31 -18
View File
@@ -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;
+10 -5
View File
@@ -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
+53 -33
View File
@@ -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);
}
+133 -51
View File
@@ -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)
+15 -2
View File
@@ -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');
+346
View File
@@ -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 */
-154
View 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);
}
-294
View File
@@ -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
-591
View File
@@ -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 */
-52
View 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 */
-268
View 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 */
-232
View 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 */
-300
View 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 */
-105
View 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 */
-442
View 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);
}
-493
View File
@@ -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 */
-391
View 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 */
-174
View 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 */
-264
View 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 */
-113
View 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*/
-228
View File
@@ -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 */
-234
View 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 */
-229
View 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
-224
View File
@@ -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 */
-230
View 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
-275
View File
@@ -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 */
+439 -155
View 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;
}
+126 -304
View File
@@ -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 */
-234
View 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 */
-160
View 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 */
+647
View 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;
}
+65 -164
View File
@@ -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 */
+136 -198
View 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 */
-201
View 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 */
-276
View 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;
}
+63 -164
View File
@@ -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 */
+302 -208
View 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;
}
+493 -362
View File
@@ -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 &lt;tytso@mit.edu&gt; and &lt;ghudson@mit.edu&gt;.
* 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;
}
}
-48
View File
@@ -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*/
-583
View File
@@ -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 */
-357
View 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 */
-405
View 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 */
-253
View 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 */
-348
View 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 */
-60
View 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 */
-327
View 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 */
-340
View 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 */
-346
View 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
-246
View File
@@ -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 */
-63
View 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 */
-46
View 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
-142
View File
@@ -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 */
-354
View 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 */
-599
View 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);
}
-446
View File
@@ -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 */
-373
View 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 */
-51
View 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*/
-209
View File
@@ -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;
}
-309
View File
@@ -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 */
-156
View File
@@ -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 */
-354
View 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 */
-535
View 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 */
-304
View 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