* Copyright (c) 1986, 1989, 1990 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted provided
* that: (1) source distributions retain this entire copyright notice and
* comment, and (2) distributions including binaries display the following
* acknowledgement: ``This product includes software developed by the
* University of California, Berkeley and its contributors'' in the
* documentation or other materials provided with the distribution and in
* all advertising materials mentioning features or use of this software.
* 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1986, 1989, 1990 Regents of the University of California.\n\
static char sccsid
[] = "@(#)ns_main.c 4.50 (Berkeley) 6/29/90";
* Internet Name server (see rfc883 & others).
#include <sys/resource.h>
#include <arpa/nameser.h>
#ifdef BOOTFILE /* default boot file */
char *bootfile
= BOOTFILE
;
char *bootfile
= _PATH_BOOT
;
#ifdef DEBUGFILE /* default debug output file */
char *debugfile
= DEBUGFILE
;
char *debugfile
= _PATH_DEBUG
;
#ifdef PIDFILE /* file to store current named PID */
char *PidFile
= _PATH_PIDFILE
;
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
FILE *fp
; /* file descriptor for pid file */
int debug
= 0; /* debugging flag */
int ds
; /* datagram socket */
int needreload
= 0; /* received SIGHUP, need to reload db */
int needmaint
= 0; /* need to call ns_maint()*/
int needzoneload
= 0; /* need to reload secondary zone(s) */
int needToDoadump
= 0; /* need to dump database */
int needToChkpt
= 0; /* need to checkpoint cache */
int needStatsDump
= 0; /* need to dump statistics */
int needToExit
= 0; /* need to exit (may need to doadump
* first, if database has changed since
* it was last dumped/booted). Gets
* set by shutdown signal handler
int priming
= 0; /* is cache being primed */
int rbufsize
= 8 * 1024; /* UDP recive buffer size */
struct qstream
*streamq
= QSTREAM_NULL
; /* list of open streams */
struct qdatagram
*datagramq
= QDATAGRAM_NULL
; /* list of datagram interfaces */
struct sockaddr_in nsaddr
;
* We keep a list of favored networks headed by nettab.
* There are three (possibly empty) parts to this list, in this order:
* 1. directly attached (sub)nets.
* 2. logical networks for directly attached subnetted networks.
* 3. networks from the sort list.
* The value (*elocal) points at the first entry in the second part of the list,
* if any, while (*enettab) points at the first entry in the sort list.
struct netinfo
*nettab
= NULL
;
struct netinfo
**elocal
= &nettab
;
struct netinfo
**enettab
= &nettab
;
struct netinfo
*findnetinfo();
struct sockaddr_in from_addr
; /* Source addr of last packet */
int from_len
; /* Source addr size of last packet */
time_t boottime
, resettime
; /* Used by ns_stats */
static fd_set mask
; /* select mask of open descriptors */
static int vs
; /* listening TCP socket */
char **Argv
= NULL
; /* pointer to argument vector */
char *LastArg
= NULL
; /* end of argv */
register struct qstream
*sp
;
register struct qdatagram
*dqp
;
u_long lasttime
, maxctime
;
struct qstream
*candidate
= QSTREAM_NULL
;
extern VOID
onintr(), maint_alarm(), endxfer();
extern VOID
setdumpflg(), onhup();
extern VOID
setIncrDbgFlg(), setNoDbgFlg(), sigprof();
extern VOID
setchkptflg(), setstatsflg();
extern struct qstream
*sqadd();
extern struct qinfo
*qhead
;
ns_port
= htons(NAMESERVER_PORT
);
** Save start and extent of argv for setproctitle.
if (envp
== 0 || *envp
== 0)
LastArg
= envp
[-1] + strlen(envp
[-1]);
ns_port
= htons((u_short
)atoi(*++argv
));
for (n
= getdtablesize() - 1; n
> 2; n
--)
fprintf(ddt
,"Debug turned ON, Level %d\n",debug
);
fprintf(ddt
,"Version = %s\t",Version
);
fprintf(ddt
,"bootfile = %s\n",bootfile
);
openlog("named", LOG_PID
|LOG_CONS
|LOG_NDELAY
, LOG_DAEMON
);
openlog("named", LOG_PID
);
/* tuck my process id away */
fp
= fopen(PidFile
, "w");
fprintf(fp
, "%d\n", getpid());
syslog(LOG_NOTICE
, "restarted\n");
_res
.options
&= ~(RES_DEFNAMES
| RES_DNSRCH
| RES_RECURSE
);
nsaddr
.sin_family
= AF_INET
;
nsaddr
.sin_addr
.s_addr
= INADDR_ANY
;
nsaddr
.sin_port
= ns_port
;
if ((vs
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0) {
syslog(LOG_ERR
, "socket(SOCK_STREAM): %m");
(void)setsockopt(vs
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&on
, sizeof(on
));
if (bind(vs
, (struct sockaddr
*)&nsaddr
, sizeof(nsaddr
))) {
syslog(LOG_ERR
, "bind(vs, %s[%d]): %m",
inet_ntoa(nsaddr
.sin_addr
), ntohs(nsaddr
.sin_port
));
* Get list of local addresses and set up datagram sockets.
** Initialize and load database.
fprintf(ddt
, "Network and sort list:\n");
(void) signal(SIGHUP
, onhup
);
(void) signal(SIGCLD
, endxfer
);
(void) signal(SIGALRM
, maint_alarm
);
bzero((char *)&vec
, sizeof(vec
));
vec
.sv_handler
= maint_alarm
;
vec
.sv_mask
= sigmask(SIGCHLD
);
(void) sigvec(SIGALRM
, &vec
, (struct sigvec
*)NULL
);
vec
.sv_handler
= endxfer
;
vec
.sv_mask
= sigmask(SIGALRM
);
(void) sigvec(SIGCHLD
, &vec
, (struct sigvec
*)NULL
);
(void) signal(SIGPIPE
, SIG_IGN
);
(void) signal(SIGSYS
, sigprof
);
(void) signal(SIGINT
, setdumpflg
);
(void) signal(SIGQUIT
, setchkptflg
);
(void) signal(SIGIOT
, setstatsflg
);
/* Catch SIGTERM so we can dump the database upon shutdown if it
has changed since it was last dumped/booted */
(void) signal(SIGTERM
, onintr
);
#if defined(SIGUSR1) && defined(SIGUSR2)
(void) signal(SIGUSR1
, setIncrDbgFlg
);
(void) signal(SIGUSR2
, setNoDbgFlg
);
(void) signal(SIGEMT
, setIncrDbgFlg
);
(void) signal(SIGFPE
, setNoDbgFlg
);
fprintf(ddt
,"database initialized\n");
* Fork and go into background now that
* we've done any slow initialization
* and are ready to answer queries.
#if defined(BSD) && BSD >= 199006
n
= open(_PATH_DEVNULL
, O_RDONLY
);
* The open below may hang on pseudo ttys if the person
* who starts named logs out before this point.
* needmaint may get set inapropriately if the open
* hangs, but all that will happen is we will see that
* no maintenance is required.
bzero((char *)&ival
, sizeof(ival
));
ival
.it_value
.tv_sec
= 120;
(void) setitimer(ITIMER_REAL
, &ival
,
(struct itimerval
*)NULL
);
n
= open(_PATH_TTY
, O_RDWR
);
ival
.it_value
.tv_sec
= 0;
(void) setitimer(ITIMER_REAL
, &ival
,
(struct itimerval
*)NULL
);
(void) ioctl(n
, TIOCNOTTY
, (char *)NULL
);
#endif /* BSD > 199006 */
/* tuck my process id away again */
fp
= fopen(PidFile
, "w");
fprintf(fp
, "%d\n", getpid());
fprintf(ddt
,"Ready to answer queries.\n");
nfds
= getdtablesize(); /* get the number of file descriptors */
nfds
= FD_SETSIZE
; /* Bulletproofing */
syslog(LOG_ERR
, "Return from getdtablesize() > FD_SETSIZE");
fprintf(ddt
,"Return from getdtablesize() > FD_SETSIZE\n");
for (dqp
= datagramq
; dqp
!= QDATAGRAM_NULL
; dqp
= dqp
->dq_next
)
FD_SET(dqp
->dq_dfd
, &mask
);
fprintf(ddt
,"Debug turned OFF\n");
* Block all blockable signals
* state during final dump
fprintf(ddt
, "Received shutdown signal\n");
for (zp
= zones
; zp
< &zones
[nzones
]; zp
++) {
** Wait until a query arrives
t
.tv_sec
= (long) retryqp
->q_time
- tt
.tv_sec
;
n
= select(nfds
, &tmpmask
, (fd_set
*)NULL
, (fd_set
*)NULL
, tp
);
syslog(LOG_ERR
, "select: %m");
fprintf(ddt
,"select error\n");
for (dqp
= datagramq
; dqp
!= QDATAGRAM_NULL
;
if (FD_ISSET(dqp
->dq_dfd
, &tmpmask
))
for(udpcnt
= 0; udpcnt
< 25; udpcnt
++) {
from_len
= sizeof(from_addr
);
if ((n
= recvfrom(dqp
->dq_dfd
, buf
, sizeof(buf
), 0,
(struct sockaddr
*)&from_addr
, &from_len
)) < 0)
if ((n
== -1) && (errno
== EWOULDBLOCK
))
syslog(LOG_WARNING
, "recvfrom: %m");
"\ndatagram from %s port %d, fd %d, len %d\n",
inet_ntoa(from_addr
.sin_addr
),
ntohs(from_addr
.sin_port
), dqp
->dq_dfd
, n
);
* Consult database to get the answer.
ns_req(buf
, n
, PACKETSZ
, QSTREAM_NULL
, &from_addr
,
** Process stream connection
if (FD_ISSET(vs
, &tmpmask
)) {
from_len
= sizeof(from_addr
);
rfd
= accept(vs
, (struct sockaddr
*)&from_addr
, &from_len
);
if (rfd
< 0 && errno
== EMFILE
&& streamq
!= NULL
) {
candidate
= QSTREAM_NULL
;
for (sp
= streamq
; sp
!= QSTREAM_NULL
;
lasttime
= tt
.tv_sec
- sp
->s_time
;
else if (lasttime
> maxctime
) {
rfd
= accept(vs
, (struct sockaddr
*)&from_addr
, &from_len
);
if ((rfd
< 0) && (errno
== EMFILE
) &&
candidate
!= QSTREAM_NULL
) {
rfd
= accept(vs
, (struct sockaddr
*)&from_addr
, &from_len
);
syslog(LOG_WARNING
, "accept: %m");
(void) fcntl(rfd
, F_SETFL
, FNDELAY
);
(void) setsockopt(rfd
, SOL_SOCKET
, SO_KEEPALIVE
,
(char *)&on
, sizeof(on
));
if ((sp
= sqadd()) == QSTREAM_NULL
) {
sp
->s_rfd
= rfd
; /* stream file descriptor */
sp
->s_size
= -1; /* amount of data to receive */
sp
->s_time
= tt
.tv_sec
; /* last transaction time */
sp
->s_from
= from_addr
; /* address to respond to */
sp
->s_bufp
= (char *)&sp
->s_tempsize
;
"\nTCP connection from %s port %d (fd %d)\n",
inet_ntoa(sp
->s_from
.sin_addr
),
ntohs(sp
->s_from
.sin_port
), rfd
);
if (debug
> 2 && streamq
)
fprintf(ddt
,"streamq = x%x\n",streamq
);
for (sp
= streamq
; sp
!= QSTREAM_NULL
; sp
= nextsp
) {
if (FD_ISSET(sp
->s_rfd
, &tmpmask
)) {
"sp x%x rfd %d size %d time %d ",
sp
, sp
->s_rfd
, sp
->s_size
,
fprintf(ddt
," next x%x \n", sp
->s_next
);
fprintf(ddt
,"\tbufsize %d",sp
->s_bufsize
);
fprintf(ddt
," buf x%x ",sp
->s_buf
);
fprintf(ddt
," bufp x%x\n",sp
->s_bufp
);
(sp
->s_bufp
- (char *)&sp
->s_tempsize
);
(n
= read(sp
->s_rfd
, sp
->s_bufp
, size
)) > 0){
if ((n
== -1) && (errno
== EWOULDBLOCK
))
if ((sp
->s_bufp
- (char *)&sp
->s_tempsize
) ==
sp
->s_size
= htons(sp
->s_tempsize
);
if (sp
->s_bufsize
== 0) {
if ( (sp
->s_buf
= malloc(BUFSIZ
))
sp
->s_size
= sizeof(buf
);
if (sp
->s_size
> sp
->s_bufsize
&&
if ((sp
->s_buf
= realloc(
(unsigned)sp
->s_size
)) == NULL
){
sp
->s_size
= sizeof(buf
);
sp
->s_bufsize
= sp
->s_size
;
(n
= read(sp
->s_rfd
, sp
->s_bufp
, sp
->s_size
)) > 0)
* we don't have enough memory for the query.
* if we have a query id, then we will send an
* error back to the user.
if (sp
->s_bufsize
== 0 &&
(sp
->s_bufp
- sp
->s_buf
> sizeof(u_short
))) {
hp
= (HEADER
*)sp
->s_buf
;
(void) writemsg(sp
->s_rfd
, sp
->s_buf
,
if ((n
== -1) && (errno
== EWOULDBLOCK
))
* Consult database to get the answer.
sp
->s_bufp
= (char *)&sp
->s_tempsize
;
fprintf(stderr
, "Usage: named [-d #] [-p port] [{-b} bootfile]\n");
register struct netinfo
*ntp
;
struct ifreq ifreq
, *ifr
;
char buf
[BUFSIZ
], *cp
, *cplim
;
ifc
.ifc_len
= sizeof(buf
);
if (ioctl(vs
, SIOCGIFCONF
, (char *)&ifc
) < 0) {
syslog(LOG_ERR
, "get interface configuration: %m");
#define max(a, b) (a > b ? a : b)
#define size(p) max((p).sa_len, sizeof(p))
#define size(p) (sizeof (p))
cplim
= buf
+ ifc
.ifc_len
; /*skip over if's with big ifr_addr's */
for (cp
= buf
; cp
< cplim
;
cp
+= sizeof (ifr
->ifr_name
) + size(ifr
->ifr_addr
)) {
ifr
= (struct ifreq
*)cp
;
if (ifr
->ifr_addr
.sa_family
!= AF_INET
)
* Don't test IFF_UP, packets may still be received at this
* address if any other interface is up.
if (ioctl(vs
, SIOCGIFADDR
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "get interface addr: %m");
/* build datagram queue */
* look for an already existing source interface address.
* This happens mostly when reinitializing. Also, if
* the machine has multiple point to point interfaces, then
* the local address may appear more than once.
for (dqp
=datagramq
; dqp
!= NULL
; dqp
= dqp
->dq_next
)
if (((struct sockaddr_in
*)&ifreq
.ifr_addr
)->sin_addr
.s_addr
== dqp
->dq_addr
.s_addr
) {
fprintf(ddt
, "dup interface address %s on %s\n",
inet_ntoa(dqp
->dq_addr
), ifreq
.ifr_name
);
if ((dqp
= (struct qdatagram
*)calloc(1,
sizeof(struct qdatagram
))) == NULL
) {
fprintf(ddt
,"getnetconf: malloc error\n");
syslog(LOG_ERR
, "getnetconf: Out Of Memory");
dqp
->dq_next
= datagramq
;
dqp
->dq_addr
= ((struct sockaddr_in
*)&ifreq
.ifr_addr
)->sin_addr
;
* Add interface to list of directly-attached (sub)nets
* for use in sorting addresses.
ntp
= (struct netinfo
*)malloc(sizeof(struct netinfo
));
((struct sockaddr_in
*)&ifreq
.ifr_addr
)->sin_addr
;
if (ioctl(vs
, SIOCGIFNETMASK
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "get netmask: %m");
ntp
->mask
= net_mask(ntp
->my_addr
);
ntp
->mask
= ((struct sockaddr_in
*)
&ifreq
.ifr_addr
)->sin_addr
.s_addr
;
/* 4.2 does not support subnets */
ntp
->mask
= net_mask(ntp
->my_addr
);
if (ioctl(vs
, SIOCGIFFLAGS
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "get interface flags: %m");
if (ifreq
.ifr_flags
& IFF_LOOPBACK
)
/* test against 127.0.0.1 (yuck!!) */
if (ntp
->my_addr
.s_addr
== htonl(0x7F000001))
if (netloop
.my_addr
.s_addr
== 0) {
netloop
.my_addr
= ntp
->my_addr
;
netloop
.mask
= 0xffffffff;
netloop
.net
= ntp
->my_addr
.s_addr
;
fprintf(ddt
,"loopback address: x%lx\n",
} else if ((ifreq
.ifr_flags
& IFF_POINTOPOINT
)) {
if (ioctl(vs
, SIOCGIFDSTADDR
, (char *)&ifreq
) < 0) {
syslog(LOG_ERR
, "get dst addr: %m");
ntp
->net
= ((struct sockaddr_in
*)
&ifreq
.ifr_addr
)->sin_addr
.s_addr
;
ntp
->net
= ntp
->mask
& ntp
->my_addr
.s_addr
;
* Place on end of list of locally-attached (sub)nets,
* but before logical nets for subnetted nets.
(void) free((char *)ntp
);
* Create separate qdatagram structure for socket
if ((dqp
= (struct qdatagram
*)calloc(1, sizeof(*dqp
))) == NULL
) {
fprintf(ddt
,"getnetconf: malloc error\n");
syslog(LOG_ERR
, "getnetconf: Out Of Memory");
dqp
->dq_next
= datagramq
;
dqp
->dq_addr
.s_addr
= INADDR_ANY
;
ds
= dqp
->dq_dfd
; /* used externally */
* Compute logical networks to which we're connected
* based on attached subnets;
* used for sorting based on network configuration.
for (ntp
= nettab
; ntp
!= NULL
; ntp
= ntp
->next
) {
nm
= net_mask(ntp
->my_addr
);
if (findnetinfo(ntp
->my_addr
))
ontp
= (struct netinfo
*)malloc(sizeof(struct netinfo
));
fprintf(ddt
,"getnetconf: malloc error\n");
syslog(LOG_ERR
, "getnetconf: Out Of Memory");
ontp
->my_addr
= ntp
->my_addr
;
ontp
->net
= ontp
->my_addr
.s_addr
& nm
;
* Find netinfo structure for logical network implied by address "addr",
* if it's on list of local/favored networks.
register struct netinfo
*ntp
;
net
= addr
.s_addr
& mask
;
for (ntp
= nettab
; ntp
!= NULL
; ntp
= ntp
->next
)
if (ntp
->net
== net
&& ntp
->mask
== mask
)
return ((struct netinfo
*) NULL
);
register struct netinfo
*ntp
;
for ( ; ntp
!= NULL
; ntp
= ntp
->next
) {
fprintf(ddt
,"net x%lx mask x%lx", ntp
->net
, ntp
->mask
);
fprintf(ddt
," my_addr x%lx", ntp
->my_addr
.s_addr
);
fprintf(ddt
," %s\n", inet_ntoa(ntp
->my_addr
));
register struct qdatagram
*dqp
;
* Open datagram sockets bound to interface address.
if ((dqp
->dq_dfd
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
syslog(LOG_ERR
, "socket(SOCK_DGRAM): %m");
fprintf(ddt
,"dqp->dq_addr %s d_dfd %d\n",
inet_ntoa(dqp
->dq_addr
), dqp
->dq_dfd
);
(void)setsockopt(dqp
->dq_dfd
, SOL_SOCKET
, SO_REUSEADDR
,
(char *)&on
, sizeof(on
));
(void)setsockopt(dqp
->dq_dfd
, SOL_SOCKET
, SO_RCVBUF
,
(char *)&rbufsize
, sizeof(rbufsize
));
(void) fcntl(dqp
->dq_dfd
, F_SETFL
, FNDELAY
);
* NOTE: Some versions of SunOS have problems with the following
* call to bind. Bind still seems to function on these systems
* if you comment out the exit inside the if. This may cause
* Suns with multiple interfaces to reply strangely.
nsaddr
.sin_addr
= dqp
->dq_addr
;
if (bind(dqp
->dq_dfd
, (struct sockaddr
*)&nsaddr
, sizeof(nsaddr
))) {
syslog(LOG_ERR
, "bind(dfd %d, %s[%d]): %m",
dqp
->dq_dfd
, inet_ntoa(nsaddr
.sin_addr
),
** Set flag saying to reload database upon receiving SIGHUP.
** Must make sure that someone isn't walking through a data
** structure at the time.
(void)signal(SIGHUP
, onhup
);
** Set flag saying to call ns_maint()
** Must make sure that someone isn't walking through a data
** structure at the time.
(void)signal(SIGALRM
, maint_alarm
);
* Signal handler to schedule shutdown. Just set flag, to ensure a consistent
* Signal handler to schedule a data base dump. Do this instead of dumping the
* data base immediately, to avoid seeing it in a possibly inconsistent state
* (due to updates), and to avoid long disk I/O delays at signal-handler
(void)signal(SIGINT
, setdumpflg
);
** Turn on or off debuging by open or closeing the debug file
#if defined(lint) && !defined(DEBUG)
ddt
= freopen(debugfile
, "w+", stderr
);
syslog(LOG_WARNING
, "can't open debug file %s: %m",
setvbuf(ddt
, NULL
, _IOLBF
, BUFSIZ
);
(void) fcntl(fileno(ddt
), F_SETFL
, FAPPEND
);
/* delay closing ddt, we might interrupt someone */
** Catch a special signal and set debug level.
** If debuging is off then turn on debuging else increment the level.
** Handy for looking in on long running name servers.
(void)signal(SIGUSR1
, setIncrDbgFlg
);
fprintf(ddt
,"Debug turned ON, Level %d\n",debug
);
** Catch a special signal to turn off debugging
(void)signal(SIGUSR2
, setNoDbgFlg
);
** Set flag for statistics dump
(void)signal(SIGIOT
, setstatsflg
);
(void)signal(SIGQUIT
, setchkptflg
);
** Catch a special signal SIGSYS
** this is setup to fork and exit to drop to /usr/tmp/gmon.out
** and keep the server running
(void)signal(SIGSYS
, sigprof
);
fprintf(ddt
,"sigprof()\n");
(void) chdir(_PATH_TMPDIR
);
** Routines for managing stream queue
register struct qstream
*sqp
;
if ((sqp
= (struct qstream
*)calloc(1, sizeof(struct qstream
)))
fprintf(ddt
,"sqadd: malloc error\n");
syslog(LOG_ERR
, "sqadd: Out Of Memory");
fprintf(ddt
,"sqadd(x%x)\n", sqp
);
* Remove stream queue structure.
* No current queries may refer to this stream when it is removed.
register struct qstream
*qp
;
register struct qstream
*qsp
;
fprintf(ddt
,"sqrm(%#x, %d ) rfcnt=%d\n",
qp
, qp
->s_rfd
, qp
->s_refcnt
);
FD_CLR(qp
->s_rfd
, &mask
);
for (qsp
= streamq
; qsp
->s_next
!= qp
; qsp
= qsp
->s_next
)
qsp
->s_next
= qp
->s_next
;
register struct qstream
*sp
, *spnext
;
for (sp
= streamq
; sp
!= QSTREAM_NULL
; sp
= spnext
) {
* Initiate query on stream;
* mark as referenced and stop selecting for input.
register struct qstream
*sp
;
FD_CLR(sp
->s_rfd
, &mask
);
* Note that the current request on a stream has completed,
* and that we should continue looking for requests on the stream.
register struct qstream
*sp
;
FD_SET(sp
->s_rfd
, &mask
);
if (getpeername(s
, (struct sockaddr
*)&sin
, &size
) == 0)
(void) sprintf(buf
, "-%s [%s]", a
, inet_ntoa(sin
.sin_addr
));
syslog(LOG_DEBUG
, "getpeername: %m");
(void) sprintf(buf
, "-%s", a
);
(void) strncpy(cp
, buf
, LastArg
- cp
);
register u_long i
= ntohl(in
.s_addr
);
return (htonl(IN_CLASSA_NET
));
return (htonl(IN_CLASSB_NET
));
return (htonl(IN_CLASSC_NET
));
if (gettimeofday(ttp
, (struct timezone
*)0) < 0)
syslog(LOG_ERR
, "gettimeofday failed: %m");