Initial revision
This commit is contained in:
Executable
+151
@@ -0,0 +1,151 @@
|
||||
# Makefile for lib/ip.
|
||||
#
|
||||
# Note: The oneC_sum.c file is not used if there is an assembly equivalent.
|
||||
|
||||
CFLAGS = -O -D_MINIX -D_POSIX_SOURCE -I. -DNDEBUG
|
||||
CC1 = $(CC) $(CFLAGS) -c
|
||||
MAKE = exec make -$(MAKEFLAGS)
|
||||
|
||||
LIBRARY = ../libc.a
|
||||
all: $(LIBRARY)
|
||||
|
||||
OBJECTS = \
|
||||
$(LIBRARY)(dhcp_gettag.o) \
|
||||
$(LIBRARY)(dhcp_settag.o) \
|
||||
$(LIBRARY)(ether_line.o) \
|
||||
$(LIBRARY)(ethera2n.o) \
|
||||
$(LIBRARY)(ethere2a.o) \
|
||||
$(LIBRARY)(etherh2n.o) \
|
||||
$(LIBRARY)(ethern2h.o) \
|
||||
$(LIBRARY)(getdomain.o) \
|
||||
$(LIBRARY)(gethnmadr.o) \
|
||||
$(LIBRARY)(gethostent.o) \
|
||||
$(LIBRARY)(gethostname.o) \
|
||||
$(LIBRARY)(getnetent.o) \
|
||||
$(LIBRARY)(getnetbyname.o) \
|
||||
$(LIBRARY)(getnetbyaddr.o) \
|
||||
$(LIBRARY)(getproto.o) \
|
||||
$(LIBRARY)(getprotoent.o) \
|
||||
$(LIBRARY)(getservent.o) \
|
||||
$(LIBRARY)(getsrvbyname.o) \
|
||||
$(LIBRARY)(getsrvbyport.o) \
|
||||
$(LIBRARY)(hton.o) \
|
||||
$(LIBRARY)(inet_addr.o) \
|
||||
$(LIBRARY)(inet_network.o) \
|
||||
$(LIBRARY)(inet_ntoa.o) \
|
||||
$(LIBRARY)(memcspn.o) \
|
||||
$(LIBRARY)(rcmd.o) \
|
||||
$(LIBRARY)(res_comp.o) \
|
||||
$(LIBRARY)(res_init.o) \
|
||||
$(LIBRARY)(res_mkquery.o) \
|
||||
$(LIBRARY)(res_query.o) \
|
||||
$(LIBRARY)(res_send.o) \
|
||||
$(LIBRARY)(ruserok.o) \
|
||||
$(LIBRARY)(servxcheck.o) \
|
||||
$(LIBRARY)(strcasecmp.o) \
|
||||
|
||||
$(LIBRARY): $(OBJECTS)
|
||||
aal cr $@ *.o
|
||||
rm *.o
|
||||
|
||||
$(LIBRARY)(dhcp_gettag.o): dhcp_gettag.c
|
||||
$(CC1) dhcp_gettag.c
|
||||
|
||||
$(LIBRARY)(dhcp_settag.o): dhcp_settag.c
|
||||
$(CC1) dhcp_settag.c
|
||||
|
||||
$(LIBRARY)(ether_line.o): ether_line.c
|
||||
$(CC1) ether_line.c
|
||||
|
||||
$(LIBRARY)(ethera2n.o): ethera2n.c
|
||||
$(CC1) ethera2n.c
|
||||
|
||||
$(LIBRARY)(ethere2a.o): ethere2a.c
|
||||
$(CC1) ethere2a.c
|
||||
|
||||
$(LIBRARY)(etherh2n.o): etherh2n.c
|
||||
$(CC1) etherh2n.c
|
||||
|
||||
$(LIBRARY)(ethern2h.o): ethern2h.c
|
||||
$(CC1) ethern2h.c
|
||||
|
||||
$(LIBRARY)(getdomain.o): getdomain.c
|
||||
$(CC1) getdomain.c
|
||||
|
||||
$(LIBRARY)(gethnmadr.o): gethnmadr.c
|
||||
$(CC1) gethnmadr.c
|
||||
|
||||
$(LIBRARY)(gethostent.o): gethostent.c
|
||||
$(CC1) gethostent.c
|
||||
|
||||
$(LIBRARY)(gethostname.o): gethostname.c
|
||||
$(CC1) gethostname.c
|
||||
|
||||
$(LIBRARY)(getnetent.o): getnetent.c
|
||||
$(CC1) getnetent.c
|
||||
|
||||
$(LIBRARY)(getnetbyname.o): getnetbyname.c
|
||||
$(CC1) getnetbyname.c
|
||||
|
||||
$(LIBRARY)(getnetbyaddr.o): getnetbyaddr.c
|
||||
$(CC1) getnetbyaddr.c
|
||||
|
||||
$(LIBRARY)(getproto.o): getproto.c
|
||||
$(CC1) getproto.c
|
||||
|
||||
$(LIBRARY)(getprotoent.o): getprotoent.c
|
||||
$(CC1) getprotoent.c
|
||||
|
||||
$(LIBRARY)(getservent.o): getservent.c
|
||||
$(CC1) getservent.c
|
||||
|
||||
$(LIBRARY)(getsrvbyname.o): getsrvbyname.c
|
||||
$(CC1) getsrvbyname.c
|
||||
|
||||
$(LIBRARY)(getsrvbyport.o): getsrvbyport.c
|
||||
$(CC1) getsrvbyport.c
|
||||
|
||||
$(LIBRARY)(hton.o): hton.c
|
||||
$(CC1) hton.c
|
||||
|
||||
$(LIBRARY)(inet_addr.o): inet_addr.c
|
||||
$(CC1) inet_addr.c
|
||||
|
||||
$(LIBRARY)(inet_network.o): inet_network.c
|
||||
$(CC1) inet_network.c
|
||||
|
||||
$(LIBRARY)(inet_ntoa.o): inet_ntoa.c
|
||||
$(CC1) inet_ntoa.c
|
||||
|
||||
$(LIBRARY)(memcspn.o): memcspn.c
|
||||
$(CC1) memcspn.c
|
||||
|
||||
$(LIBRARY)(oneC_sum.o): oneC_sum.c
|
||||
$(CC1) oneC_sum.c
|
||||
|
||||
$(LIBRARY)(rcmd.o): rcmd.c
|
||||
$(CC1) rcmd.c
|
||||
|
||||
$(LIBRARY)(res_comp.o): res_comp.c
|
||||
$(CC1) res_comp.c
|
||||
|
||||
$(LIBRARY)(res_init.o): res_init.c
|
||||
$(CC1) res_init.c
|
||||
|
||||
$(LIBRARY)(res_mkquery.o): res_mkquery.c
|
||||
$(CC1) res_mkquery.c
|
||||
|
||||
$(LIBRARY)(res_query.o): res_query.c
|
||||
$(CC1) res_query.c
|
||||
|
||||
$(LIBRARY)(res_send.o): res_send.c
|
||||
$(CC1) res_send.c
|
||||
|
||||
$(LIBRARY)(ruserok.o): ruserok.c
|
||||
$(CC1) ruserok.c
|
||||
|
||||
$(LIBRARY)(servxcheck.o): servxcheck.c
|
||||
$(CC1) servxcheck.c
|
||||
|
||||
$(LIBRARY)(strcasecmp.o): strcasecmp.c
|
||||
$(CC1) strcasecmp.c
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
/* dhcp_gettag() Author: Kees J. Bot
|
||||
* 1 Dec 2000
|
||||
*/
|
||||
#define nil ((void*)0)
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/dhcp.h>
|
||||
|
||||
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
int dhcp_gettag(dhcp_t *dp, int searchtag, u8_t **pdata, size_t *plen)
|
||||
{
|
||||
/* Find a tag in the options field, or possibly in the file or sname
|
||||
* fields. Return true iff found, and return the data and/or length if
|
||||
* their pointers are non-null.
|
||||
*/
|
||||
u8_t *p;
|
||||
u8_t *optfield[3];
|
||||
size_t optlen[3];
|
||||
int i, tag, len;
|
||||
|
||||
/* The DHCP magic number must be correct, or no tags. */
|
||||
if (dp->magic != DHCP_MAGIC) return 0;
|
||||
|
||||
optfield[0]= dp->options;
|
||||
optlen[0]= arraysize(dp->options);
|
||||
optfield[1]= dp->file;
|
||||
optlen[1]= 0; /* Unknown if used for options yet. */
|
||||
optfield[2]= dp->sname;
|
||||
optlen[2]= 0;
|
||||
|
||||
for (i= 0; i < 3; i++) {
|
||||
p= optfield[i];
|
||||
while (p < optfield[i] + optlen[i]) {
|
||||
tag= *p++;
|
||||
if (tag == 255) break;
|
||||
len= tag == 0 ? 0 : *p++;
|
||||
if (tag == searchtag) {
|
||||
if (pdata != nil) *pdata= p;
|
||||
if (plen != nil) *plen= len;
|
||||
return 1;
|
||||
}
|
||||
if (tag == DHCP_TAG_OVERLOAD) {
|
||||
/* There are also options in the file or sname field. */
|
||||
if (*p & 1) optlen[1]= arraysize(dp->file);
|
||||
if (*p & 2) optlen[1]= arraysize(dp->sname);
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
/* dhcp_init(), dhcp_settag() Author: Kees J. Bot
|
||||
* 1 Dec 2000
|
||||
*/
|
||||
#define nil ((void*)0)
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/dhcp.h>
|
||||
|
||||
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define arraylimit(a) ((a) + arraysize(a))
|
||||
|
||||
void dhcp_init(dhcp_t *dp)
|
||||
{
|
||||
/* Initialize a DHCP packet. */
|
||||
memset(dp, 0, offsetof(dhcp_t, magic));
|
||||
dp->magic= DHCP_MAGIC;
|
||||
memset(dp->options, 255, sizeof(dp->options));
|
||||
}
|
||||
|
||||
int dhcp_settag(dhcp_t *dp, int tag, void *data, size_t len)
|
||||
{
|
||||
/* Add a tag to a DHCP packet. No padding. Only do the options field.
|
||||
* (This is Minix, we don't need megabytes of silly bits of data.)
|
||||
* The length may be zero to delete a tag.
|
||||
*/
|
||||
u8_t *p;
|
||||
int n;
|
||||
|
||||
if (tag <= 0 || tag >= 255) return 0;
|
||||
|
||||
for (p= dp->options; p < arraylimit(dp->options) && *p != 255; p += n) {
|
||||
n= 1 + 1 + p[1];
|
||||
if (*p == tag) {
|
||||
/* The tag is already there, remove it so it gets replaced. */
|
||||
memmove(p, p + n, arraylimit(dp->options) - (p + n));
|
||||
memset(arraylimit(dp->options) - n, 255, n);
|
||||
n= 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add tag. */
|
||||
if (len == 0) {
|
||||
/* We're merely deleting a tag. */
|
||||
} else
|
||||
if (p + 1 + 1 + len <= arraylimit(dp->options)) {
|
||||
*p++ = tag;
|
||||
*p++ = len;
|
||||
memcpy(p, data, len);
|
||||
} else {
|
||||
/* Oops, it didn't fit? Is this really Minix??? */
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
domainname.c
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/netlib.h>
|
||||
|
||||
int getdomainname(domain, size)
|
||||
char *domain;
|
||||
size_t size;
|
||||
{
|
||||
FILE *domainfile;
|
||||
char *line;
|
||||
|
||||
domainfile= fopen("/etc/domainname", "r");
|
||||
if (!domainfile)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
line= fgets(domain, size, domainfile);
|
||||
fclose(domainfile);
|
||||
if (!line)
|
||||
return -1;
|
||||
line= strchr(domain, '\n');
|
||||
if (line)
|
||||
*line= '\0';
|
||||
return 0;
|
||||
}
|
||||
Executable
+151
@@ -0,0 +1,151 @@
|
||||
/* $Id$ */
|
||||
|
||||
/* Interface definitions for ethernet access library */
|
||||
|
||||
typedef union etheraddr
|
||||
{
|
||||
unsigned char bytes[6]; /* byteorder safe initialization */
|
||||
unsigned short shorts[3]; /* force 2-byte alignment */
|
||||
}
|
||||
ether_addr;
|
||||
|
||||
typedef struct etherpacket
|
||||
{
|
||||
ether_addr dest;
|
||||
ether_addr src;
|
||||
unsigned char type[2]; /* in network byte order! */
|
||||
unsigned short pktlen; /* length of pktbuf ONLY */
|
||||
char *pktbuf;
|
||||
}
|
||||
ether_packet;
|
||||
|
||||
typedef struct ethervec
|
||||
{
|
||||
ether_addr dest;
|
||||
ether_addr src;
|
||||
unsigned char type[2]; /* in network byte order! */
|
||||
unsigned short iovcnt; /* number of iovec to use */
|
||||
struct iovec *iov; /* ptr to array of iovec */
|
||||
}
|
||||
ether_vec;
|
||||
|
||||
#ifndef __ETHER_BCAST_ADDR__
|
||||
extern ether_addr ether_bcast_addr;
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
int ether_open (char *name, unsigned type, ether_addr * address);
|
||||
|
||||
ether_addr *ether_address (int fd, ether_addr * address);
|
||||
|
||||
ether_addr *ether_intfaddr (char *intf, ether_addr * address);
|
||||
|
||||
char **ether_interfaces (void);
|
||||
|
||||
int ether_write (int fd, ether_packet * packet);
|
||||
|
||||
int ether_writev (int fd, ether_vec * packet);
|
||||
|
||||
int ether_read (int fd, ether_packet * packet);
|
||||
|
||||
int ether_readv (int fd, ether_vec * packet);
|
||||
|
||||
int ether_blocking (int fd, int state);
|
||||
|
||||
int ether_send_self (int fd);
|
||||
|
||||
int ether_mcast_self (int fd);
|
||||
|
||||
int ether_bcast_self (int fd);
|
||||
|
||||
char *ether_ntoa (ether_addr *);
|
||||
|
||||
ether_addr *ether_aton (char *);
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
/*
|
||||
* Avoid stupid warnings if structs aren't defined
|
||||
*/
|
||||
|
||||
typedef struct in_addr *_ether_NoNsEnSe;
|
||||
typedef struct hostent *_ether_nOnSeNsE;
|
||||
|
||||
#endif
|
||||
|
||||
char *ether_e2a (ether_addr *, char *);
|
||||
|
||||
ether_addr *ether_a2e (char *, ether_addr *);
|
||||
|
||||
struct in_addr *ether_e2ip (ether_addr *, struct in_addr *);
|
||||
|
||||
ether_addr *ether_ip2e (struct in_addr *, ether_addr *);
|
||||
|
||||
char *ether_e2host (ether_addr *, char *);
|
||||
|
||||
ether_addr *ether_host2e (char *, ether_addr *);
|
||||
|
||||
ether_addr *ether_hostent2e (struct hostent *, ether_addr *);
|
||||
|
||||
#else
|
||||
|
||||
int ether_open ();
|
||||
ether_addr *ether_address ();
|
||||
ether_addr *ether_intfaddr ();
|
||||
char **ether_interfaces ();
|
||||
int ether_write ();
|
||||
int ether_writev ();
|
||||
int ether_read ();
|
||||
int ether_readv ();
|
||||
int ether_blocking ();
|
||||
int ether_send_self ();
|
||||
int ether_mcast_self ();
|
||||
int ether_bcast_self ();
|
||||
|
||||
char *ether_ntoa ();
|
||||
ether_addr *ether_aton ();
|
||||
char *ether_e2a ();
|
||||
ether_addr *ether_a2e ();
|
||||
struct in_addr *ether_e2ip ();
|
||||
ether_addr *ether_ip2e ();
|
||||
char *ether_e2host ();
|
||||
ether_addr *ether_host2e ();
|
||||
ether_addr *ether_hostent2e ();
|
||||
|
||||
#endif
|
||||
|
||||
#undef ether_cmp /* lose def from netinet/if_ether.h */
|
||||
|
||||
#define ether_cmp(addr1,addr2) \
|
||||
((addr1)->shorts[0] != (addr2)->shorts[0] \
|
||||
|| (addr1)->shorts[1] != (addr2)->shorts[1] \
|
||||
|| (addr1)->shorts[2] != (addr2)->shorts[2])
|
||||
|
||||
#define ETHERSTRLEN 18 /* max length of "xx:xx:xx:xx:xx:xx" */
|
||||
|
||||
#ifdef NOFILE /* i.e. we have included sys/param.h */
|
||||
#ifndef MAXHOSTNAMELEN /* but MAXHOSTNAMELEN still isnt set */
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* should be defined in terms of ether_packet struct; need offsetof() macro */
|
||||
|
||||
#define ETHER_DST 0
|
||||
#define ETHER_SRC 6
|
||||
#define ETHER_TYPE 12
|
||||
#define ETHER_PKT 14
|
||||
#define ETHER_MIN 46
|
||||
#define ETHER_MAX 1500
|
||||
|
||||
#define ETHER_MINTYPE 0x5DD /* lowest protocol not valid IEEE802 */
|
||||
#define ETHER_MAXTYPE 0xFFFF /* largest possible protocol */
|
||||
|
||||
#define ETHER_MCAST(addr) (((unsigned char *) (addr))[0] & 0x01)
|
||||
|
||||
#ifdef NT_ALLTYPES
|
||||
#define ETHER_ALLTYPES NT_ALLTYPES
|
||||
#else
|
||||
#define ETHER_ALLTYPES ((unsigned) -1)
|
||||
#endif
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
** ETHER_LINE
|
||||
**
|
||||
** This routine parses the array pointed to by "line" (which should be
|
||||
** from a file in the format of /etc/ethers) and returns in "eaddr" the
|
||||
** ethernet address at the start of the line and the corresponding host
|
||||
** name in "hostname". It assumes either tabs or spaces separate the
|
||||
** two. The buffer pointed to by "hostname" must be big enough to hold
|
||||
** the host name plus a NULL byte.
|
||||
** The function returns 0 on success and 1 on failure.
|
||||
** Arguments are assumed sensible. Null pointers will probably cause
|
||||
** exceptions.
|
||||
** Author: Gregory J. Sharp, July 1990
|
||||
** Adapted to MINIX: Philip Homburg, May 1992
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <net/gen/ether.h>
|
||||
#include <net/gen/if_ether.h>
|
||||
|
||||
int
|
||||
ether_line(line, eaddr, hostname)
|
||||
char * line;
|
||||
struct ether_addr * eaddr;
|
||||
char * hostname;
|
||||
{
|
||||
register int i;
|
||||
register unsigned long val;
|
||||
|
||||
/* skip leading white space */
|
||||
while (*line != '\n' && (*line == ' ' || *line == '\t'))
|
||||
line++;
|
||||
|
||||
/* read the ethernet address */
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
val = (unsigned long) strtol(line, &line, 16);
|
||||
if (val > 255 || *line++ != ':')
|
||||
return 1;
|
||||
eaddr->ea_addr[i] = val & 0xff;
|
||||
}
|
||||
val = (unsigned long) strtol(line, &line, 16);
|
||||
if (val > 255 || (*line != ' ' && *line != '\t'))
|
||||
return 1;
|
||||
eaddr->ea_addr[i] = val & 0xff;
|
||||
|
||||
/* skip leading white space */
|
||||
while (*line != '\n' && (*line == ' ' || *line == '\t'))
|
||||
line++;
|
||||
|
||||
/* read in the hostname */
|
||||
while (!isspace(*line))
|
||||
*hostname++ = *line++;
|
||||
*hostname = '\0';
|
||||
return 0;
|
||||
}
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
ethera2n.c
|
||||
|
||||
Convert an ASCII string with an ethernet address into a struct ether_addr.
|
||||
|
||||
Created: Nov 17, 1992 by Philip Homburg
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <net/netlib.h>
|
||||
#include <net/gen/ether.h>
|
||||
#include <net/gen/if_ether.h>
|
||||
|
||||
struct ether_addr *ether_aton(s)
|
||||
_CONST char *s;
|
||||
{
|
||||
static struct ether_addr ea;
|
||||
|
||||
int i;
|
||||
long v;
|
||||
char *check;
|
||||
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
v= strtol(s, &check, 16);
|
||||
if (v<0 || v>255)
|
||||
return NULL;
|
||||
if ((i<5 && check[0] != ':') || (i == 5 && check[0] != '\0'))
|
||||
return NULL;
|
||||
ea.ea_addr[i]= v;
|
||||
s= check+1;
|
||||
}
|
||||
return &ea;
|
||||
}
|
||||
|
||||
/*
|
||||
* $PchId: ethera2n.c,v 1.3 1996/02/22 21:10:01 philip Exp $
|
||||
*/
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
/* $Id$ */
|
||||
/* This file was part of the etherlib package. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/gen/ether.h>
|
||||
#include <net/gen/if_ether.h>
|
||||
|
||||
#define ETHERSTRLEN 18 /* max length of "xx:xx:xx:xx:xx:xx" */
|
||||
#define ether_addr ether_addr_t
|
||||
#define bytes ea_addr
|
||||
char *ether_e2a _ARGS(( ether_addr_t *a, char *e ));
|
||||
#else
|
||||
#include "libether.h"
|
||||
#endif
|
||||
|
||||
char *
|
||||
ether_e2a (addr, estring)
|
||||
ether_addr *addr;
|
||||
char *estring;
|
||||
{
|
||||
#ifdef lint
|
||||
char *sprintf ();
|
||||
#endif
|
||||
if (estring == NULL)
|
||||
estring = (char *) malloc (ETHERSTRLEN);
|
||||
|
||||
if (estring != NULL)
|
||||
(void) sprintf (estring, "%x:%x:%x:%x:%x:%x",
|
||||
addr->bytes[0], addr->bytes[1], addr->bytes[2],
|
||||
addr->bytes[3], addr->bytes[4], addr->bytes[5]);
|
||||
return (estring);
|
||||
}
|
||||
|
||||
#ifndef ETHERDB
|
||||
|
||||
char *
|
||||
ether_ntoa (addr)
|
||||
ether_addr *addr;
|
||||
{
|
||||
static char estring[ETHERSTRLEN];
|
||||
|
||||
return (ether_e2a (addr, estring));
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
etherh2n.c
|
||||
|
||||
Created: May 20, 1992 by Philip Homburg
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/gen/if_ether.h>
|
||||
|
||||
int
|
||||
ether_hostton(hostname, e)
|
||||
char *hostname;
|
||||
struct ether_addr *e;
|
||||
{
|
||||
FILE *etherf;
|
||||
char b[256], hn[256];
|
||||
|
||||
etherf= fopen(_PATH_ETHERS, "r");
|
||||
if (etherf == NULL)
|
||||
return 1;
|
||||
|
||||
while(fgets(b, sizeof(b), etherf) != NULL)
|
||||
{
|
||||
if (ether_line(b, e, hn) == 0 && strcmp(hn, hostname) == 0)
|
||||
{
|
||||
fclose(etherf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(etherf);
|
||||
return 1;
|
||||
}
|
||||
Executable
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
ethern2h.c
|
||||
|
||||
Created: Nov 12, 1992 by Philip Homburg
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/gen/ether.h>
|
||||
#include <net/gen/if_ether.h>
|
||||
|
||||
int
|
||||
ether_ntohost(hostname, e)
|
||||
char *hostname;
|
||||
struct ether_addr *e;
|
||||
{
|
||||
FILE *etherf;
|
||||
char b[256];
|
||||
struct ether_addr e_tmp;
|
||||
|
||||
etherf= fopen(_PATH_ETHERS, "r");
|
||||
if (etherf == NULL)
|
||||
return 1;
|
||||
|
||||
while(fgets(b, sizeof(b), etherf) != NULL)
|
||||
{
|
||||
if (ether_line(b, &e_tmp, hostname) == 0 &&
|
||||
memcmp(&e_tmp, e, sizeof(e_tmp)) == 0)
|
||||
{
|
||||
fclose(etherf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fclose(etherf);
|
||||
return 1;
|
||||
}
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/* getdomainname() Author: Kees J. Bot
|
||||
* 2 Dec 1994
|
||||
*/
|
||||
#define nil 0
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
int getdomainname(char *domain, size_t size)
|
||||
{
|
||||
char nodename[256];
|
||||
char *dot;
|
||||
|
||||
if (gethostname(nodename, sizeof(nodename)) < 0)
|
||||
return -1;
|
||||
nodename[sizeof(nodename)-1]= 0;
|
||||
if ((dot= strchr(nodename, '.')) == nil) dot= ".";
|
||||
|
||||
strncpy(domain, dot+1, size);
|
||||
if (size > 0) domain[size-1]= 0;
|
||||
return 0;
|
||||
}
|
||||
Executable
+338
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)gethostnamadr.c 6.41 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/resolv.h>
|
||||
#include <net/gen/socket.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#endif /* AMOEABA */
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
static char *h_addr_ptrs[MAXADDRS + 1];
|
||||
|
||||
#ifdef _MINIX
|
||||
struct in_addr
|
||||
{
|
||||
ipaddr_t s_addr;
|
||||
};
|
||||
typedef u32_t u_long;
|
||||
typedef u16_t u_short;
|
||||
typedef u8_t u_char;
|
||||
union querybuf;
|
||||
|
||||
extern int dn_skipname _ARGS(( const u_char *comp_dn, const u_char *eom ));
|
||||
#define getshort _getshort
|
||||
static struct hostent *getanswer _ARGS(( union querybuf *answer, int anslen,
|
||||
int iquery ));
|
||||
#define bcmp memcmp
|
||||
#define bcopy(s, d, l) memcpy(d, s, l)
|
||||
#endif /* _MINIX */
|
||||
|
||||
static struct hostent host;
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static char hostbuf[BUFSIZ+1];
|
||||
static struct in_addr host_addr;
|
||||
|
||||
#ifndef _MINIX
|
||||
char *strpbrk();
|
||||
#endif /* !_MINIX */
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
typedef union querybuf
|
||||
{
|
||||
dns_hdr_t hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf_t;
|
||||
|
||||
typedef union align {
|
||||
long al;
|
||||
char ac;
|
||||
} align_t;
|
||||
|
||||
static struct hostent *
|
||||
getanswer(answer, anslen, iquery)
|
||||
querybuf_t *answer;
|
||||
int anslen;
|
||||
int iquery;
|
||||
{
|
||||
register dns_hdr_t *hp;
|
||||
register u_char *cp;
|
||||
register int n;
|
||||
u_char *eom;
|
||||
char *bp, **ap;
|
||||
int type, class, buflen, ancount, qdcount;
|
||||
int haveanswer, getclass = C_ANY;
|
||||
char **hap;
|
||||
|
||||
eom = answer->buf + anslen;
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*/
|
||||
hp = &answer->hdr;
|
||||
ancount = ntohs(hp->dh_ancount);
|
||||
qdcount = ntohs(hp->dh_qdcount);
|
||||
bp = hostbuf;
|
||||
buflen = sizeof(hostbuf);
|
||||
cp = answer->buf + sizeof(dns_hdr_t);
|
||||
if (qdcount) {
|
||||
if (iquery) {
|
||||
if ((n = dn_expand((u_char *)answer->buf, eom,
|
||||
cp, (u_char *)bp, buflen)) < 0) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return ((struct hostent *) NULL);
|
||||
}
|
||||
cp += n + QFIXEDSZ;
|
||||
host.h_name = bp;
|
||||
n = strlen(bp) + 1;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
} else
|
||||
cp += dn_skipname(cp, eom) + QFIXEDSZ;
|
||||
while (--qdcount > 0)
|
||||
cp += dn_skipname(cp, eom) + QFIXEDSZ;
|
||||
} else if (iquery) {
|
||||
if (hp->dh_flag1 & DHF_AA)
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
else
|
||||
h_errno = TRY_AGAIN;
|
||||
return ((struct hostent *) NULL);
|
||||
}
|
||||
ap = host_aliases;
|
||||
*ap = NULL;
|
||||
host.h_aliases = host_aliases;
|
||||
hap = h_addr_ptrs;
|
||||
*hap = NULL;
|
||||
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
#endif
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
if ((n = dn_expand((u_char *)answer->buf, eom, cp, (u_char *)bp,
|
||||
buflen)) < 0)
|
||||
break;
|
||||
cp += n;
|
||||
type = getshort(cp);
|
||||
cp += sizeof(u_short);
|
||||
class = getshort(cp);
|
||||
cp += sizeof(u_short) + sizeof(u_long);
|
||||
n = getshort(cp);
|
||||
cp += sizeof(u_short);
|
||||
if (type == T_CNAME) {
|
||||
cp += n;
|
||||
if (ap >= &host_aliases[MAXALIASES-1])
|
||||
continue;
|
||||
*ap++ = bp;
|
||||
n = strlen(bp) + 1;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (iquery && type == T_PTR) {
|
||||
if ((n = dn_expand((u8_t *)answer->buf, eom,
|
||||
cp, (u8_t *)bp, buflen)) < 0) {
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
host.h_name = bp;
|
||||
return(&host);
|
||||
}
|
||||
if (iquery || type != T_A) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("unexpected answer type %d, size %d\n",
|
||||
type, n);
|
||||
#endif
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (haveanswer) {
|
||||
if (n != host.h_length) {
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (class != getclass) {
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
host.h_length = n;
|
||||
getclass = class;
|
||||
host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC;
|
||||
if (!iquery) {
|
||||
host.h_name = bp;
|
||||
bp += strlen(bp) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
bp += (size_t)(sizeof(align_t) -
|
||||
((u_long)bp % sizeof(align_t)));
|
||||
|
||||
if (bp + n >= &hostbuf[sizeof(hostbuf)]) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("size (%d) too big\n", n);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
bcopy(cp, *hap++ = bp, n);
|
||||
bp +=n;
|
||||
cp += n;
|
||||
haveanswer++;
|
||||
}
|
||||
if (haveanswer) {
|
||||
*ap = NULL;
|
||||
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
|
||||
*hap = NULL;
|
||||
#else
|
||||
host.h_addr = h_addr_ptrs[0];
|
||||
#endif
|
||||
return (&host);
|
||||
} else {
|
||||
h_errno = TRY_AGAIN;
|
||||
return ((struct hostent *) NULL);
|
||||
}
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname(name)
|
||||
_CONST char *name;
|
||||
{
|
||||
querybuf_t buf;
|
||||
register _CONST char *cp;
|
||||
int n;
|
||||
|
||||
/*
|
||||
* disallow names consisting only of digits/dots, unless
|
||||
* they end in a dot.
|
||||
*/
|
||||
if (isdigit(name[0]))
|
||||
for (cp = name;; ++cp) {
|
||||
if (!*cp) {
|
||||
if (*--cp == '.')
|
||||
break;
|
||||
/*
|
||||
* All-numeric, no dot at the end.
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup. What if someone types
|
||||
* 255.255.255.255? The test below will
|
||||
* succeed spuriously... ???
|
||||
*/
|
||||
if ((host_addr.s_addr = inet_addr(name)) == -1) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return((struct hostent *) NULL);
|
||||
}
|
||||
host.h_name = (char *) name;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
host.h_addrtype = AF_INET;
|
||||
host.h_length = sizeof(u_long);
|
||||
h_addr_ptrs[0] = (char *)&host_addr;
|
||||
h_addr_ptrs[1] = (char *)0;
|
||||
#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
#else
|
||||
host.h_addr = h_addr_ptrs[0];
|
||||
#endif
|
||||
return (&host);
|
||||
}
|
||||
if (!isdigit(*cp) && *cp != '.')
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n = res_search((char*)name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_search failed\n");
|
||||
#endif
|
||||
return ((struct hostent *) NULL);
|
||||
}
|
||||
return (getanswer(&buf, n, 0));
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyaddr(addr, len, type)
|
||||
const char *addr;
|
||||
int len, type;
|
||||
{
|
||||
int n;
|
||||
querybuf_t buf;
|
||||
register struct hostent *hp;
|
||||
char qbuf[MAXDNAME];
|
||||
|
||||
if (type != AF_INET)
|
||||
return ((struct hostent *) NULL);
|
||||
(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
|
||||
((unsigned)addr[3] & 0xff),
|
||||
((unsigned)addr[2] & 0xff),
|
||||
((unsigned)addr[1] & 0xff),
|
||||
((unsigned)addr[0] & 0xff));
|
||||
n = res_query(qbuf, C_IN, T_PTR, (u8_t *)&buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query failed\n");
|
||||
#endif
|
||||
return ((struct hostent *) NULL);
|
||||
}
|
||||
hp = getanswer(&buf, n, 1);
|
||||
if (hp == NULL)
|
||||
return ((struct hostent *) NULL);
|
||||
hp->h_addrtype = type;
|
||||
hp->h_length = len;
|
||||
h_addr_ptrs[0] = (char *)&host_addr;
|
||||
h_addr_ptrs[1] = (char *)0;
|
||||
host_addr = *(struct in_addr *)addr;
|
||||
#if BSD < 43 && !defined(h_addr) /* new-style hostent structure */
|
||||
hp->h_addr = h_addr_ptrs[0];
|
||||
#endif
|
||||
return(hp);
|
||||
}
|
||||
Executable
+168
@@ -0,0 +1,168 @@
|
||||
/* gethostent() - Interface to /etc/hosts Author: Kees J. Bot
|
||||
* 31 May 1999
|
||||
*/
|
||||
|
||||
/* Prefix the functions defined here with underscores to distinguish them
|
||||
* from the newer replacements in the resolver library.
|
||||
*/
|
||||
#define sethostent _sethostent
|
||||
#define endhostent _endhostent
|
||||
#define gethostent _gethostent
|
||||
#define gethostbyname _gethostbyname
|
||||
#define gethostbyaddr _gethostbyaddr
|
||||
|
||||
#define nil 0
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/socket.h>
|
||||
|
||||
#define arraysize(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#define arraylimit(a) ((a) + arraysize(a))
|
||||
#define isspace(c) ((unsigned) (c) <= ' ')
|
||||
|
||||
static char HOSTS[]= _PATH_HOSTS;
|
||||
static char *hosts= HOSTS; /* Current hosts file. */
|
||||
static FILE *hfp; /* Open hosts file. */
|
||||
|
||||
void sethostent(int stayopen)
|
||||
/* Start search. (Same as ending it.) */
|
||||
{
|
||||
endhostent();
|
||||
}
|
||||
|
||||
void endhostent(void)
|
||||
/* End search and reinitialize. */
|
||||
{
|
||||
if (hfp != nil) {
|
||||
fclose(hfp);
|
||||
hfp= nil;
|
||||
}
|
||||
hosts= _PATH_HOSTS;
|
||||
}
|
||||
|
||||
struct hostent *gethostent(void)
|
||||
/* Return the next entry from the hosts files. */
|
||||
{
|
||||
static char line[256]; /* One line in a hosts file. */
|
||||
static ipaddr_t addr; /* IP address found first on the line. */
|
||||
static char *names[16]; /* Pointers to the words on the line. */
|
||||
static char *addrs[2]= { /* List of IP addresses (just one.) */
|
||||
(char *) &addr,
|
||||
nil,
|
||||
};
|
||||
static struct hostent host = {
|
||||
nil, /* h_name, will set to names[1]. */
|
||||
names + 2, /* h_aliases, the rest of the names. */
|
||||
AF_INET, /* h_addrtype */
|
||||
sizeof(ipaddr_t), /* Size of an address in the address list. */
|
||||
addrs, /* List of IP addresses. */
|
||||
};
|
||||
static char nexthosts[128]; /* Next hosts file to include. */
|
||||
char *lp, **np;
|
||||
int c;
|
||||
|
||||
for (;;) {
|
||||
if (hfp == nil) {
|
||||
/* No hosts file open, try to open the next one. */
|
||||
if (hosts == 0) return nil;
|
||||
if ((hfp= fopen(hosts, "r")) == nil) { hosts= nil; continue; }
|
||||
}
|
||||
|
||||
/* Read a line. */
|
||||
lp= line;
|
||||
while ((c= getc(hfp)) != EOF && c != '\n') {
|
||||
if (lp < arraylimit(line)) *lp++= c;
|
||||
}
|
||||
|
||||
/* EOF? Then close and prepare for reading the next file. */
|
||||
if (c == EOF) {
|
||||
fclose(hfp);
|
||||
hfp= nil;
|
||||
hosts= nil;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lp == arraylimit(line)) continue;
|
||||
*lp= 0;
|
||||
|
||||
/* Break the line up in words. */
|
||||
np= names;
|
||||
lp= line;
|
||||
for (;;) {
|
||||
while (isspace(*lp) && *lp != 0) lp++;
|
||||
if (*lp == 0 || *lp == '#') break;
|
||||
if (np == arraylimit(names)) break;
|
||||
*np++= lp;
|
||||
while (!isspace(*lp) && *lp != 0) lp++;
|
||||
if (*lp == 0) break;
|
||||
*lp++= 0;
|
||||
}
|
||||
|
||||
if (np == arraylimit(names)) continue;
|
||||
*np= nil;
|
||||
|
||||
/* Special "include file" directive. */
|
||||
if (np == names + 2 && strcmp(names[0], "include") == 0) {
|
||||
fclose(hfp);
|
||||
hfp= nil;
|
||||
hosts= nil;
|
||||
if (strlen(names[1]) < sizeof(nexthosts)) {
|
||||
strcpy(nexthosts, names[1]);
|
||||
hosts= nexthosts;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* At least two words, the first of which is an IP address. */
|
||||
if (np < names + 2) continue;
|
||||
if (!inet_aton((char *) names[0], &addr)) continue;
|
||||
host.h_name= (char *) names[1];
|
||||
|
||||
return &host;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rest kept in reserve, we probably never need 'em. */
|
||||
#if XXX
|
||||
struct hostent *gethostbyname(const char *name)
|
||||
{
|
||||
struct hostent *he;
|
||||
char **pa;
|
||||
char alias[256];
|
||||
char *domain;
|
||||
|
||||
sethostent(0);
|
||||
while ((he= gethostent()) != nil) {
|
||||
if (strcasecmp(he->h_name, name) == 0) goto found;
|
||||
|
||||
domain= strchr(he->h_name, '.');
|
||||
for (pa= he->h_aliases; *pa != nil; pa++) {
|
||||
strcpy(alias, *pa);
|
||||
if (domain != nil && strchr(alias, '.') == nil) {
|
||||
strcat(alias, domain);
|
||||
}
|
||||
if (strcasecmp(alias, name) == 0) goto found;
|
||||
}
|
||||
}
|
||||
found:
|
||||
endhostent();
|
||||
return he;
|
||||
}
|
||||
|
||||
struct hostent *gethostbyaddr(const char *addr, int len, int type)
|
||||
{
|
||||
struct hostent *he;
|
||||
|
||||
sethostent(0);
|
||||
while ((he= gethostent()) != nil) {
|
||||
if (he->h_name[0] == '%') continue;
|
||||
if (type == AF_INET && memcmp(he->h_addr, addr, len) == 0) break;
|
||||
}
|
||||
endhostent();
|
||||
return he;
|
||||
}
|
||||
#endif
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
/* gethostname(2) system call emulation */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
#define HOSTNAME_FILE "/etc/hostname.file"
|
||||
|
||||
int gethostname(char *buf, size_t len)
|
||||
{
|
||||
int fd;
|
||||
int r;
|
||||
char *nl;
|
||||
|
||||
if ((fd= open(HOSTNAME_FILE, O_RDONLY)) < 0) return -1;
|
||||
|
||||
r= read(fd, buf, len);
|
||||
close(fd);
|
||||
if (r == -1) return -1;
|
||||
|
||||
buf[len-1]= '\0';
|
||||
if ((nl= strchr(buf, '\n')) != NULL) *nl= '\0';
|
||||
return 0;
|
||||
}
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
extern int _net_stayopen;
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(net, type)
|
||||
register long net;
|
||||
register int type;
|
||||
{
|
||||
register struct netent *p;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while (p = getnetent())
|
||||
if (p->n_addrtype == type && p->n_net == net)
|
||||
break;
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
return (p);
|
||||
}
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <string.h>
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
extern int _net_stayopen;
|
||||
|
||||
struct netent *
|
||||
getnetbyname(name)
|
||||
register const char *name;
|
||||
{
|
||||
register struct netent *p;
|
||||
register char **cp;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while (p = getnetent()) {
|
||||
if (strcmp(p->n_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->n_aliases; *cp != 0; cp++)
|
||||
if (strcmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
return (p);
|
||||
}
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/socket.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *netf;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct netent net;
|
||||
static char *net_aliases[MAXALIASES];
|
||||
int _net_stayopen;
|
||||
|
||||
void
|
||||
setnetent(f)
|
||||
int f;
|
||||
{
|
||||
if (netf == NULL)
|
||||
netf = fopen(_PATH_NETWORKS, "r" );
|
||||
else
|
||||
rewind(netf);
|
||||
_net_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
endnetent()
|
||||
{
|
||||
if (netf) {
|
||||
fclose(netf);
|
||||
netf = NULL;
|
||||
}
|
||||
_net_stayopen = 0;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
p = fgets(line, BUFSIZ, 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';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&net);
|
||||
}
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getproto.c 5.6 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef _MINIX
|
||||
#include <ansi.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#endif
|
||||
|
||||
extern int _proto_stayopen;
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(proto)
|
||||
register int proto;
|
||||
{
|
||||
register struct protoent *p;
|
||||
|
||||
setprotoent(_proto_stayopen);
|
||||
while (p = getprotoent())
|
||||
if (p->p_proto == proto)
|
||||
break;
|
||||
if (!_proto_stayopen)
|
||||
endprotoent();
|
||||
return (p);
|
||||
}
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getprotoent.c 5.7 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _MINIX
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
static char *any _ARGS(( char *cp, char *match ));
|
||||
#endif
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *protof = NULL;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct protoent proto;
|
||||
static char *proto_aliases[MAXALIASES];
|
||||
int _proto_stayopen;
|
||||
|
||||
void
|
||||
setprotoent(f)
|
||||
int f;
|
||||
{
|
||||
if (protof == NULL)
|
||||
protof = fopen(_PATH_PROTOCOLS, "r" );
|
||||
else
|
||||
rewind(protof);
|
||||
_proto_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent()
|
||||
{
|
||||
if (protof) {
|
||||
fclose(protof);
|
||||
protof = NULL;
|
||||
}
|
||||
_proto_stayopen = 0;
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotoent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
if ((p = fgets(line, BUFSIZ, protof)) == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = any(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
proto.p_name = p;
|
||||
cp = any(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = any(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
proto.p_proto = atoi(cp);
|
||||
q = proto.p_aliases = proto_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &proto_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = any(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
return (&proto);
|
||||
}
|
||||
|
||||
static char *
|
||||
any(cp, match)
|
||||
register char *cp;
|
||||
char *match;
|
||||
{
|
||||
register char *mp, c;
|
||||
|
||||
while (c = *cp) {
|
||||
for (mp = match; *mp; mp++)
|
||||
if (*mp == c)
|
||||
return (cp);
|
||||
cp++;
|
||||
}
|
||||
return ((char *)0);
|
||||
}
|
||||
Executable
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservent.c 5.8 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *servf = NULL;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct servent serv;
|
||||
static char *serv_aliases[MAXALIASES];
|
||||
int _serv_stayopen;
|
||||
|
||||
static char *any _ARGS(( char *cp, char *match ));
|
||||
|
||||
void
|
||||
setservent(f)
|
||||
int f;
|
||||
{
|
||||
if (servf == NULL)
|
||||
servf = fopen(_PATH_SERVICES, "r" );
|
||||
else
|
||||
rewind(servf);
|
||||
_serv_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
endservent()
|
||||
{
|
||||
if (servf) {
|
||||
fclose(servf);
|
||||
servf = NULL;
|
||||
}
|
||||
_serv_stayopen = 0;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
if ((p = fgets(line, BUFSIZ, servf)) == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = any(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
serv.s_name = p;
|
||||
p = any(p, " \t");
|
||||
if (p == NULL)
|
||||
goto again;
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
cp = any(p, ",/");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
serv.s_port = htons((u16_t)atoi(p));
|
||||
serv.s_proto = cp;
|
||||
q = serv.s_aliases = serv_aliases;
|
||||
cp = any(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &serv_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = any(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&serv);
|
||||
}
|
||||
|
||||
static char *
|
||||
any(cp, match)
|
||||
register char *cp;
|
||||
char *match;
|
||||
{
|
||||
register char *mp, c;
|
||||
|
||||
while (c = *cp) {
|
||||
for (mp = match; *mp; mp++)
|
||||
if (*mp == c)
|
||||
return (cp);
|
||||
cp++;
|
||||
}
|
||||
return ((char *)0);
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservbyname.c 5.6 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
extern int _serv_stayopen;
|
||||
|
||||
struct servent *
|
||||
getservbyname(name, proto)
|
||||
const char *name, *proto;
|
||||
{
|
||||
register struct servent *p;
|
||||
register char **cp;
|
||||
|
||||
setservent(_serv_stayopen);
|
||||
while (p = getservent()) {
|
||||
if (strcmp(name, p->s_name) == 0)
|
||||
goto gotname;
|
||||
for (cp = p->s_aliases; *cp; cp++)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
goto gotname;
|
||||
continue;
|
||||
gotname:
|
||||
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!_serv_stayopen)
|
||||
endservent();
|
||||
return (p);
|
||||
}
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservbyport.c 5.6 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MINIX
|
||||
#include <net/gen/netdb.h>
|
||||
#endif
|
||||
|
||||
extern int _serv_stayopen;
|
||||
|
||||
struct servent *
|
||||
getservbyport(port, proto)
|
||||
int port;
|
||||
const char *proto;
|
||||
{
|
||||
register struct servent *p;
|
||||
|
||||
setservent(_serv_stayopen);
|
||||
while (p = getservent()) {
|
||||
if (p->s_port != port)
|
||||
continue;
|
||||
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!_serv_stayopen)
|
||||
endservent();
|
||||
return (p);
|
||||
}
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
hton.c
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <minix/config.h>
|
||||
#include <net/hton.h>
|
||||
|
||||
u16_t _tmp;
|
||||
u32_t _tmp_l;
|
||||
Executable
+149
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1990 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_addr.c 5.8 (Berkeley) 6/23/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#define _CONST const
|
||||
#else
|
||||
#define _CONST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Ascii internet address interpretation routine.
|
||||
* The value returned is in network order.
|
||||
*/
|
||||
ipaddr_t
|
||||
inet_addr(cp)
|
||||
register _CONST char *cp;
|
||||
{
|
||||
ipaddr_t val;
|
||||
|
||||
if (inet_aton(cp, &val))
|
||||
return (val);
|
||||
errno= EINVAL;
|
||||
return (ipaddr_t)-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*/
|
||||
|
||||
int
|
||||
inet_aton(cp, addr)
|
||||
register _CONST char *cp;
|
||||
ipaddr_t *addr;
|
||||
{
|
||||
register u32_t val, base, n;
|
||||
register char c;
|
||||
u32_t parts[4], *pp = parts;
|
||||
|
||||
for (;;) {
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, other=decimal.
|
||||
*/
|
||||
val = 0; base = 10;
|
||||
if (*cp == '0') {
|
||||
if (*++cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
while ((c = *cp) != '\0') {
|
||||
if (isascii(c) && isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isascii(c) && isxdigit(c)) {
|
||||
val = (val << 4) +
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*cp == '.') {
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16-bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if (pp >= parts + 3 || val > 0xff)
|
||||
return (0);
|
||||
*pp++ = val, cp++;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (*cp && (!isascii(*cp) || !isspace(*cp)))
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch (n) {
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if (addr)
|
||||
*addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
|
||||
#define INADDR_NONE ((ipaddr_t) -1)
|
||||
|
||||
/*
|
||||
* Internet network address interpretation routine.
|
||||
* The library routines call this routine to interpret
|
||||
* network numbers.
|
||||
*/
|
||||
ipaddr_t
|
||||
inet_network(cp)
|
||||
register const char *cp;
|
||||
{
|
||||
register ipaddr_t val, base, n;
|
||||
register char c;
|
||||
ipaddr_t parts[4], *pp = parts;
|
||||
register int i;
|
||||
|
||||
again:
|
||||
val = 0; base = 10;
|
||||
if (*cp == '0')
|
||||
base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
while (c = *cp) {
|
||||
if (isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isxdigit(c)) {
|
||||
val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*cp == '.') {
|
||||
if (pp >= parts + 4)
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val, cp++;
|
||||
goto again;
|
||||
}
|
||||
if (*cp && !isspace(*cp))
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val;
|
||||
n = pp - parts;
|
||||
if (n > 4)
|
||||
return (INADDR_NONE);
|
||||
for (val = 0, i = 0; i < n; i++) {
|
||||
val <<= 8;
|
||||
val |= parts[i] & 0xff;
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 5.5 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
|
||||
char *
|
||||
inet_ntoa(in)
|
||||
ipaddr_t in;
|
||||
{
|
||||
static char b[18];
|
||||
register u8_t *p;
|
||||
|
||||
p = (u8_t *)∈
|
||||
sprintf(b, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
return (b);
|
||||
}
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t
|
||||
memcspn(const char *string, size_t strlen, const char *notin, size_t notinlen)
|
||||
{
|
||||
register const char *s1, *s2;
|
||||
int i,j;
|
||||
|
||||
for (s1 = string, i = 0; i<strlen; s1++, i++) {
|
||||
for(s2 = notin, j = 0; *s2 != *s1 && j < notinlen; s2++, j++)
|
||||
/* EMPTY */ ;
|
||||
if (j != notinlen)
|
||||
break;
|
||||
}
|
||||
return s1 - string;
|
||||
}
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
/* oneC_sum() - One complement's checksum Author: Kees J. Bot
|
||||
* 8 May 1995
|
||||
* See RFC 1071, "Computing the Internet checksum"
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <net/gen/oneCsum.h>
|
||||
|
||||
u16_t oneC_sum(U16_t prev, void *data, size_t size)
|
||||
{
|
||||
u8_t *dptr;
|
||||
size_t n;
|
||||
u16_t word;
|
||||
u32_t sum;
|
||||
int swap= 0;
|
||||
|
||||
sum= prev;
|
||||
dptr= data;
|
||||
n= size;
|
||||
|
||||
swap= ((size_t) dptr & 1);
|
||||
if (swap) {
|
||||
sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
|
||||
if (n > 0) {
|
||||
((u8_t *) &word)[0]= 0;
|
||||
((u8_t *) &word)[1]= dptr[0];
|
||||
sum+= (u32_t) word;
|
||||
dptr+= 1;
|
||||
n-= 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (n >= 8) {
|
||||
sum+= (u32_t) ((u16_t *) dptr)[0]
|
||||
+ (u32_t) ((u16_t *) dptr)[1]
|
||||
+ (u32_t) ((u16_t *) dptr)[2]
|
||||
+ (u32_t) ((u16_t *) dptr)[3];
|
||||
dptr+= 8;
|
||||
n-= 8;
|
||||
}
|
||||
|
||||
while (n >= 2) {
|
||||
sum+= (u32_t) ((u16_t *) dptr)[0];
|
||||
dptr+= 2;
|
||||
n-= 2;
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
((u8_t *) &word)[0]= dptr[0];
|
||||
((u8_t *) &word)[1]= 0;
|
||||
sum+= (u32_t) word;
|
||||
}
|
||||
|
||||
sum= (sum & 0xFFFF) + (sum >> 16);
|
||||
if (sum > 0xFFFF) sum++;
|
||||
|
||||
if (swap) {
|
||||
sum= ((sum & 0xFF) << 8) | ((sum & 0xFF00) >> 8);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
Executable
+284
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)rcmd.c 5.22 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/netlib.h>
|
||||
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#define MAXPATHLEN PATH_MAX
|
||||
|
||||
#ifdef __STDC__
|
||||
#define CONST const
|
||||
#else
|
||||
#define CONST
|
||||
#endif
|
||||
|
||||
extern errno;
|
||||
|
||||
int rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
|
||||
char **ahost;
|
||||
int rport;
|
||||
CONST char *locuser, *remuser, *cmd;
|
||||
int *fd2p;
|
||||
{
|
||||
int fd, fd2, result;
|
||||
struct hostent *hp;
|
||||
int n;
|
||||
static tcpport_t lport;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_tcpcl_t tcpconnopt;
|
||||
pid_t pid;
|
||||
char num[8];
|
||||
char c;
|
||||
char *tcp_device;
|
||||
|
||||
fd= -1;
|
||||
fd2= -1;
|
||||
|
||||
if (lport == 0) {
|
||||
pid = getpid();
|
||||
lport = 1;
|
||||
do {
|
||||
lport = (lport << 1) | (pid & 1);
|
||||
|
||||
pid >>= 1;
|
||||
} while (lport < TCPPORT_RESERVED/2);
|
||||
}
|
||||
|
||||
tcp_device= getenv("TCP_DEVICE");
|
||||
if (tcp_device == NULL)
|
||||
tcp_device= TCP_DEVICE;
|
||||
hp= gethostbyname(*ahost);
|
||||
if (!hp)
|
||||
{
|
||||
fprintf(stderr, "%s: unknown host\n", *ahost);
|
||||
return -1;
|
||||
}
|
||||
*ahost= hp->h_name;
|
||||
n = TCPPORT_RESERVED/2;
|
||||
do
|
||||
{
|
||||
if (--lport < TCPPORT_RESERVED/2)
|
||||
lport = TCPPORT_RESERVED-1;
|
||||
fd= open (tcp_device, O_RDWR);
|
||||
if (fd<0)
|
||||
{
|
||||
fprintf(stderr, "unable to open %s: %s\n",
|
||||
tcp_device, strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
tcpconf.nwtc_flags= NWTC_LP_SET | NWTC_SET_RA | NWTC_SET_RP |
|
||||
NWTC_EXCL;
|
||||
tcpconf.nwtc_locport= htons(lport);
|
||||
tcpconf.nwtc_remport= rport;
|
||||
tcpconf.nwtc_remaddr= *(ipaddr_t *)hp->h_addr;
|
||||
|
||||
result= ioctl(fd, NWIOSTCPCONF, &tcpconf);
|
||||
if (result<0)
|
||||
{
|
||||
if (errno == EADDRINUSE)
|
||||
{
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "unable to ioctl(NWIOSTCPCONF): %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
tcpconf.nwtc_flags= NWTC_SHARED;
|
||||
result= ioctl(fd, NWIOSTCPCONF, &tcpconf);
|
||||
if (result<0)
|
||||
{
|
||||
fprintf(stderr, "unable to ioctl(NWIOSTCPCONF): %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
tcpconnopt.nwtcl_flags= 0;
|
||||
|
||||
do
|
||||
{
|
||||
result= ioctl (fd, NWIOTCPCONN, &tcpconnopt);
|
||||
if (result<0 && errno == EAGAIN)
|
||||
{
|
||||
sleep(2);
|
||||
}
|
||||
} while (result<0 && errno == EAGAIN);
|
||||
if (result<0 && errno != EADDRINUSE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"unable to ioctl(NWIOTCPCONN): %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
if (result>=0)
|
||||
break;
|
||||
} while (--n > 0);
|
||||
if (n == 0)
|
||||
{
|
||||
fprintf(stderr, "can't get port\n");
|
||||
return -1;
|
||||
}
|
||||
if (!fd2p)
|
||||
{
|
||||
if (write(fd, "", 1) != 1)
|
||||
{
|
||||
fprintf(stderr, "unable to write: %s", strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fd2= open (tcp_device, O_RDWR);
|
||||
if (fd2<0)
|
||||
{
|
||||
fprintf(stderr, "unable to open %s: %s\n",
|
||||
tcp_device, strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
tcpconf.nwtc_flags= NWTC_LP_SET | NWTC_UNSET_RA |
|
||||
NWTC_UNSET_RP | NWTC_SHARED;
|
||||
tcpconf.nwtc_locport= htons(lport);
|
||||
|
||||
result= ioctl(fd2, NWIOSTCPCONF, &tcpconf);
|
||||
if (result<0)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"unable to ioctl(NWIOSTCPCONF): %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
pid= fork();
|
||||
if (pid<0)
|
||||
{
|
||||
fprintf(stderr, "unable to fork: %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
if (!pid)
|
||||
{
|
||||
alarm(0);
|
||||
signal(SIGALRM, SIG_DFL);
|
||||
alarm(30); /* give up after half a minute */
|
||||
tcpconnopt.nwtcl_flags= 0;
|
||||
|
||||
do
|
||||
{
|
||||
result= ioctl (fd2, NWIOTCPLISTEN,
|
||||
&tcpconnopt);
|
||||
if (result<0 && errno == EAGAIN)
|
||||
{
|
||||
sleep(2);
|
||||
}
|
||||
} while (result<0 && errno == EAGAIN);
|
||||
if (result<0 && errno != EADDRINUSE)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"unable to ioctl(NWIOTCPLISTEN): %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (result>=0)
|
||||
exit(0);
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* This sleep is a HACK. The command that we are starting
|
||||
* will try to connect to the fd2 port. It seems that for
|
||||
* this to succeed the child process must have already made
|
||||
* the call to ioctl above (the NWIOTCPLISTEN) call.
|
||||
* The sleep gives the child a chance to make the call
|
||||
* before the parent sends the port number to the
|
||||
* command being started.
|
||||
*/
|
||||
sleep(1);
|
||||
|
||||
sprintf(num, "%d", lport);
|
||||
if (write(fd, num, strlen(num)+1) != strlen(num)+1)
|
||||
{
|
||||
fprintf(stderr, "unable to write: %s\n",
|
||||
strerror(errno));
|
||||
goto bad;
|
||||
}
|
||||
|
||||
}
|
||||
write (fd, locuser, strlen(locuser)+1);
|
||||
write (fd, remuser, strlen(remuser)+1);
|
||||
write (fd, cmd, strlen(cmd)+1);
|
||||
if (read(fd, &c, 1) != 1)
|
||||
{
|
||||
fprintf(stderr, "unable to read: %s\n", strerror(errno) );
|
||||
goto bad;
|
||||
}
|
||||
if (c != 0)
|
||||
{
|
||||
while (read(fd, &c, 1) == 1)
|
||||
{
|
||||
write(2, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad;
|
||||
}
|
||||
if (fd2p)
|
||||
{
|
||||
*fd2p= fd2;
|
||||
result= ioctl(fd2, NWIOGTCPCONF, &tcpconf);
|
||||
if (result<0)
|
||||
{
|
||||
fprintf(stderr, "unable to ioctl(NWIOGTCPCONF): %s\n",
|
||||
strerror(errno) );
|
||||
goto bad;
|
||||
}
|
||||
if (ntohs(tcpconf.nwtc_remport) >= TCPPORT_RESERVED)
|
||||
{
|
||||
fprintf(stderr, "unable to setup 2nd channel\n");
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
return fd;
|
||||
|
||||
bad:
|
||||
if (fd>=0)
|
||||
close(fd);
|
||||
if (fd2>=0)
|
||||
close(fd2);
|
||||
return -1;
|
||||
}
|
||||
Executable
+351
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 1985 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_comp.c 6.18 (Berkeley) 6/27/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/resolv.h>
|
||||
|
||||
typedef u8_t u_char;
|
||||
typedef u16_t u_short;
|
||||
typedef u32_t u_long;
|
||||
|
||||
static int dn_find _ARGS(( const u_char *exp_dn, const u_char *msg,
|
||||
u_char **dnptrs, u_char **lastdnptr ));
|
||||
int dn_skipname _ARGS(( const u_char *comp_dn, const u_char *eom ));
|
||||
|
||||
#define getshort _getshort
|
||||
#define getlong _getlong
|
||||
#define putshort __putshort
|
||||
#define putlong __putlong
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
static dn_find();
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#define CONST const
|
||||
#else
|
||||
#define CONST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Expand compressed domain name 'comp_dn' to full domain name.
|
||||
* 'msg' is a pointer to the begining of the message,
|
||||
* 'eomorig' points to the first location after the message,
|
||||
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
|
||||
* Return size of compressed name or -1 if there was an error.
|
||||
*/
|
||||
dn_expand(msg, eomorig, comp_dn, exp_dn, length)
|
||||
CONST u_char *msg, *eomorig, *comp_dn;
|
||||
u_char *exp_dn;
|
||||
int length;
|
||||
{
|
||||
register CONST u_char *cp;
|
||||
register u_char *dn;
|
||||
register int n, c;
|
||||
CONST u_char *eom;
|
||||
int len = -1, checked = 0;
|
||||
|
||||
dn = exp_dn;
|
||||
cp = comp_dn;
|
||||
eom = exp_dn + length;
|
||||
/*
|
||||
* fetch next label in domain name
|
||||
*/
|
||||
while (n = *cp++) {
|
||||
/*
|
||||
* Check for indirection
|
||||
*/
|
||||
switch (n & INDIR_MASK) {
|
||||
case 0:
|
||||
if (dn != exp_dn) {
|
||||
if (dn >= eom)
|
||||
return (-1);
|
||||
*dn++ = '.';
|
||||
}
|
||||
if (dn+n >= eom)
|
||||
return (-1);
|
||||
checked += n + 1;
|
||||
while (--n >= 0) {
|
||||
if ((c = *cp++) == '.') {
|
||||
if (dn + n + 2 >= eom)
|
||||
return (-1);
|
||||
*dn++ = '\\';
|
||||
}
|
||||
*dn++ = c;
|
||||
if (cp >= eomorig) /* out of range */
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
|
||||
case INDIR_MASK:
|
||||
if (len < 0)
|
||||
len = cp - comp_dn + 1;
|
||||
cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));
|
||||
if (cp < msg || cp >= eomorig) /* out of range */
|
||||
return(-1);
|
||||
checked += 2;
|
||||
/*
|
||||
* Check for loops in the compressed name;
|
||||
* if we've looked at the whole message,
|
||||
* there must be a loop.
|
||||
*/
|
||||
if (checked >= eomorig - msg)
|
||||
return (-1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1); /* flag error */
|
||||
}
|
||||
}
|
||||
*dn = '\0';
|
||||
if (len < 0)
|
||||
len = cp - comp_dn;
|
||||
return (len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compress domain name 'exp_dn' into 'comp_dn'.
|
||||
* Return the size of the compressed name or -1.
|
||||
* 'length' is the size of the array pointed to by 'comp_dn'.
|
||||
* 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
|
||||
* is a pointer to the beginning of the message. The list ends with NULL.
|
||||
* 'lastdnptr' is a pointer to the end of the arrary pointed to
|
||||
* by 'dnptrs'. Side effect is to update the list of pointers for
|
||||
* labels inserted into the message as we compress the name.
|
||||
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
|
||||
* is NULL, we don't update the list.
|
||||
*/
|
||||
int
|
||||
dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr)
|
||||
CONST u_char *exp_dn;
|
||||
u_char *comp_dn;
|
||||
int length;
|
||||
u_char **dnptrs, **lastdnptr;
|
||||
{
|
||||
register u_char *cp;
|
||||
register CONST u_char *dn;
|
||||
register int c, l;
|
||||
u_char **cpp, **lpp, *sp, *eob;
|
||||
u_char *msg;
|
||||
|
||||
dn = exp_dn;
|
||||
cp = comp_dn;
|
||||
eob = cp + length;
|
||||
if (dnptrs != NULL) {
|
||||
if ((msg = *dnptrs++) != NULL) {
|
||||
for (cpp = dnptrs; *cpp != NULL; cpp++)
|
||||
;
|
||||
lpp = cpp; /* end of list to search */
|
||||
}
|
||||
} else
|
||||
msg = NULL;
|
||||
for (c = *dn++; c != '\0'; ) {
|
||||
/* look to see if we can use pointers */
|
||||
if (msg != NULL) {
|
||||
if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
|
||||
if (cp+1 >= eob)
|
||||
return (-1);
|
||||
*cp++ = (l >> 8) | INDIR_MASK;
|
||||
*cp++ = l % 256;
|
||||
return (cp - comp_dn);
|
||||
}
|
||||
/* not found, save it */
|
||||
if (lastdnptr != NULL && cpp < lastdnptr-1) {
|
||||
*cpp++ = cp;
|
||||
*cpp = NULL;
|
||||
}
|
||||
}
|
||||
sp = cp++; /* save ptr to length byte */
|
||||
do {
|
||||
if (c == '.') {
|
||||
c = *dn++;
|
||||
break;
|
||||
}
|
||||
if (c == '\\') {
|
||||
if ((c = *dn++) == '\0')
|
||||
break;
|
||||
}
|
||||
if (cp >= eob) {
|
||||
if (msg != NULL)
|
||||
*lpp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*cp++ = c;
|
||||
} while ((c = *dn++) != '\0');
|
||||
/* catch trailing '.'s but not '..' */
|
||||
if ((l = cp - sp - 1) == 0 && c == '\0') {
|
||||
cp--;
|
||||
break;
|
||||
}
|
||||
if (l <= 0 || l > MAXLABEL) {
|
||||
if (msg != NULL)
|
||||
*lpp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*sp = l;
|
||||
}
|
||||
if (cp >= eob) {
|
||||
if (msg != NULL)
|
||||
*lpp = NULL;
|
||||
return (-1);
|
||||
}
|
||||
*cp++ = '\0';
|
||||
return (cp - comp_dn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over a compressed domain name. Return the size or -1.
|
||||
*/
|
||||
dn_skipname(comp_dn, eom)
|
||||
CONST u_char *comp_dn, *eom;
|
||||
{
|
||||
register CONST u_char *cp;
|
||||
register int n;
|
||||
|
||||
cp = comp_dn;
|
||||
while (cp < eom && (n = *cp++)) {
|
||||
/*
|
||||
* check for indirection
|
||||
*/
|
||||
switch (n & INDIR_MASK) {
|
||||
case 0: /* normal case, n == len */
|
||||
cp += n;
|
||||
continue;
|
||||
default: /* illegal type */
|
||||
return (-1);
|
||||
case INDIR_MASK: /* indirection */
|
||||
cp++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (cp - comp_dn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for expanded name from a list of previously compressed names.
|
||||
* Return the offset from msg if found or -1.
|
||||
* dnptrs is the pointer to the first name on the list,
|
||||
* not the pointer to the start of the message.
|
||||
*/
|
||||
static int
|
||||
dn_find(exp_dn, msg, dnptrs, lastdnptr)
|
||||
CONST u_char *exp_dn, *msg;
|
||||
u_char **dnptrs, **lastdnptr;
|
||||
{
|
||||
CONST register u_char *dn, *cp;
|
||||
register u_char **cpp;
|
||||
register int n;
|
||||
CONST u_char *sp;
|
||||
|
||||
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
|
||||
dn = exp_dn;
|
||||
sp = cp = *cpp;
|
||||
while (n = *cp++) {
|
||||
/*
|
||||
* check for indirection
|
||||
*/
|
||||
switch (n & INDIR_MASK) {
|
||||
case 0: /* normal case, n == len */
|
||||
while (--n >= 0) {
|
||||
if (*dn == '.')
|
||||
goto next;
|
||||
if (*dn == '\\')
|
||||
dn++;
|
||||
if (*dn++ != *cp++)
|
||||
goto next;
|
||||
}
|
||||
if ((n = *dn++) == '\0' && *cp == '\0')
|
||||
return (sp - msg);
|
||||
if (n == '.')
|
||||
continue;
|
||||
goto next;
|
||||
|
||||
default: /* illegal type */
|
||||
return (-1);
|
||||
|
||||
case INDIR_MASK: /* indirection */
|
||||
cp = msg + (((n & 0x3f) << 8) | *cp);
|
||||
}
|
||||
}
|
||||
if (*dn == '\0')
|
||||
return (sp - msg);
|
||||
next: ;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to insert/extract short/long's. Must account for byte
|
||||
* order and non-alignment problems. This code at least has the
|
||||
* advantage of being portable.
|
||||
*
|
||||
* used by sendmail.
|
||||
*/
|
||||
|
||||
u16_t
|
||||
getshort(msgp)
|
||||
CONST u8_t *msgp;
|
||||
{
|
||||
return ((msgp[0] << 8) | (msgp[1] << 0));
|
||||
}
|
||||
|
||||
u32_t
|
||||
getlong(msgp)
|
||||
CONST u8_t *msgp;
|
||||
{
|
||||
return ( ((u32_t) msgp[0] << 24)
|
||||
| ((u32_t) msgp[1] << 16)
|
||||
| ((u32_t) msgp[2] << 8)
|
||||
| ((u32_t) msgp[3] << 0));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
putshort(s, msgp)
|
||||
register U16_t s;
|
||||
register u8_t *msgp;
|
||||
{
|
||||
|
||||
msgp[1] = s;
|
||||
msgp[0] = s >> 8;
|
||||
}
|
||||
|
||||
void
|
||||
putlong(l, msgp)
|
||||
register u32_t l;
|
||||
register u8_t *msgp;
|
||||
{
|
||||
|
||||
msgp[3] = l;
|
||||
msgp[2] = (l >>= 8);
|
||||
msgp[1] = (l >>= 8);
|
||||
msgp[0] = l >> 8;
|
||||
}
|
||||
Executable
+197
@@ -0,0 +1,197 @@
|
||||
/*-
|
||||
* Copyright (c) 1985, 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_init.c 6.14 (Berkeley) 6/27/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/resolv.h>
|
||||
#include <net/gen/socket.h>
|
||||
|
||||
#define index(s,c) strchr(s,c)
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Resolver state
|
||||
*/
|
||||
struct state _res;
|
||||
|
||||
/*
|
||||
* Set up default settings. If the configuration file exist, the values
|
||||
* there will have precedence. Otherwise, the server address is set to
|
||||
* 127.0.0.1 (localhost) and the default domain name comes from gethostname().
|
||||
*
|
||||
* The configuration file should only be used if you want to redefine your
|
||||
* domain or run without a server on your machine.
|
||||
*
|
||||
* Return 0 if completes successfully, -1 on error
|
||||
*/
|
||||
int
|
||||
res_init()
|
||||
{
|
||||
register FILE *fp;
|
||||
register char *cp, **pp;
|
||||
register int n;
|
||||
char buf[BUFSIZ];
|
||||
int haveenv = 0;
|
||||
int havesearch = 0;
|
||||
struct servent* servent;
|
||||
u16_t nameserver_port;
|
||||
|
||||
/* Resolver state default settings */
|
||||
_res.retrans = RES_TIMEOUT; /* retransmition time interval */
|
||||
_res.retry = 4; /* number of times to retransmit */
|
||||
_res.options = RES_DEFAULT; /* options flags */
|
||||
_res.nscount = 0; /* number of name servers */
|
||||
_res.defdname[0] = 0; /* domain */
|
||||
|
||||
servent= getservbyname("domain", NULL);
|
||||
if (!servent)
|
||||
{
|
||||
h_errno= NO_RECOVERY;
|
||||
return -1;
|
||||
}
|
||||
nameserver_port= servent->s_port;
|
||||
|
||||
/* Allow user to override the local domain definition */
|
||||
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
|
||||
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname));
|
||||
haveenv++;
|
||||
}
|
||||
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
/* read the config file */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* read default domain name */
|
||||
if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("domain") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
if ((cp = index(_res.defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
havesearch = 0;
|
||||
continue;
|
||||
}
|
||||
/* set search list */
|
||||
if (!strncmp(buf, "search", sizeof("search") - 1)) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("search") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
if ((cp = index(_res.defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
/*
|
||||
* Set search list to be blank-separated strings
|
||||
* on rest of line.
|
||||
*/
|
||||
cp = _res.defdname;
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = cp;
|
||||
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
*cp = 0;
|
||||
n = 1;
|
||||
} else if (n) {
|
||||
*pp++ = cp;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
/* null terminate last domain if there are excess */
|
||||
while (*cp != '\0' && *cp != ' ' && *cp != '\t')
|
||||
cp++;
|
||||
*cp = '\0';
|
||||
*pp++ = 0;
|
||||
havesearch = 1;
|
||||
continue;
|
||||
}
|
||||
/* read nameservers to query */
|
||||
if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
|
||||
_res.nscount < MAXNS) {
|
||||
cp = buf + sizeof("nameserver") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
if (!inet_aton(cp, &_res.nsaddr_list[_res.nscount]))
|
||||
continue;
|
||||
_res.nsport_list[_res.nscount]= nameserver_port;
|
||||
_res.nscount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(void) fclose(fp);
|
||||
}
|
||||
if (_res.nscount == 0) {
|
||||
/* "localhost" is the default nameserver. */
|
||||
_res.nsaddr_list[0]= HTONL(0x7F000001);
|
||||
_res.nsport_list[0]= nameserver_port;
|
||||
_res.nscount= 1;
|
||||
}
|
||||
if (_res.defdname[0] == 0) {
|
||||
if (gethostname(buf, sizeof(_res.defdname)) == 0 &&
|
||||
(cp = index(buf, '.')))
|
||||
(void)strcpy(_res.defdname, cp + 1);
|
||||
}
|
||||
|
||||
/* find components of local domain that might be searched */
|
||||
if (havesearch == 0) {
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = _res.defdname;
|
||||
for (cp = _res.defdname, n = 0; *cp; cp++)
|
||||
if (*cp == '.')
|
||||
n++;
|
||||
cp = _res.defdname;
|
||||
for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch + MAXDFLSRCH;
|
||||
n--) {
|
||||
cp = index(cp, '.');
|
||||
*pp++ = ++cp;
|
||||
}
|
||||
*pp++ = 0;
|
||||
}
|
||||
_res.options |= RES_INIT;
|
||||
return (0);
|
||||
}
|
||||
Executable
+222
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 1985 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_mkquery.c 6.12 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/resolv.h>
|
||||
|
||||
typedef u16_t u_short;
|
||||
typedef unsigned u_int;
|
||||
typedef u32_t u_long;
|
||||
|
||||
#define bzero(b,l) memset(b,0,l)
|
||||
#define bcopy(s,d,l) memcpy(d,s,l)
|
||||
|
||||
#define putshort __putshort
|
||||
#define putlong __putlong
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#define _CONST const
|
||||
#else
|
||||
#define _CONST
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Form all types of queries.
|
||||
* Returns the size of the result or -1.
|
||||
*/
|
||||
res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen)
|
||||
int op; /* opcode of query */
|
||||
_CONST char *dname; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
_CONST char *data; /* resource record data */
|
||||
int datalen; /* length of data */
|
||||
_CONST struct rrec *newrr; /* new rr for modify or append */
|
||||
char *buf; /* buffer to put query */
|
||||
int buflen; /* size of buffer */
|
||||
{
|
||||
register dns_hdr_t *hp;
|
||||
register char *cp;
|
||||
register int n;
|
||||
char *dnptrs[10], **dpp, **lastdnptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_mkquery(%d, %s, %d, %d)\n", op, dname, class, type);
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* Initialize header fields.
|
||||
*/
|
||||
if ((buf == NULL) || (buflen < sizeof(dns_hdr_t)))
|
||||
return(-1);
|
||||
bzero(buf, sizeof(dns_hdr_t));
|
||||
hp = (dns_hdr_t *) buf;
|
||||
hp->dh_id = htons(++_res.id);
|
||||
hp->dh_flag1= 0;
|
||||
hp->dh_flag2= 0;
|
||||
hp->dh_flag1 |= (op << 3) & DHF_OPCODE;
|
||||
hp->dh_flag2 |= ((_res.options & RES_PRIMARY) != 0 ? 1 : 0) << 6;
|
||||
hp->dh_flag1 |= (_res.options & RES_RECURSE) != 0 ? 1 : 0;
|
||||
hp->dh_flag2 |= NOERROR & DHF_RCODE;
|
||||
cp = buf + sizeof(dns_hdr_t);
|
||||
buflen -= sizeof(dns_hdr_t);
|
||||
dpp = dnptrs;
|
||||
*dpp++ = buf;
|
||||
*dpp++ = NULL;
|
||||
lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]);
|
||||
/*
|
||||
* perform opcode specific processing
|
||||
*/
|
||||
switch (op) {
|
||||
case QUERY:
|
||||
if ((buflen -= QFIXEDSZ) < 0)
|
||||
return(-1);
|
||||
if ((n = dn_comp((u8_t *)dname, (u8_t *)cp, buflen,
|
||||
(u8_t **)dnptrs, (u8_t **)lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
putshort(type, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
putshort(class, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
hp->dh_qdcount = HTONS(1);
|
||||
if (op == QUERY || data == NULL)
|
||||
break;
|
||||
/*
|
||||
* Make an additional record for completion domain.
|
||||
*/
|
||||
buflen -= RRFIXEDSZ;
|
||||
if ((n = dn_comp((u8_t *)data, (u8_t *)cp, buflen,
|
||||
(u8_t **)dnptrs, (u8_t **)lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
putshort(T_NULL, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
putshort(class, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
putlong(0, (u8_t *)cp);
|
||||
cp += sizeof(u_long);
|
||||
putshort(0, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
hp->dh_arcount = HTONS(1);
|
||||
break;
|
||||
|
||||
case IQUERY:
|
||||
/*
|
||||
* Initialize answer section
|
||||
*/
|
||||
if (buflen < 1 + RRFIXEDSZ + datalen)
|
||||
return (-1);
|
||||
*cp++ = '\0'; /* no domain name */
|
||||
putshort(type, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
putshort(class, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
putlong(0, (u8_t *)cp);
|
||||
cp += sizeof(u_long);
|
||||
putshort(datalen, (u8_t *)cp);
|
||||
cp += sizeof(u_short);
|
||||
if (datalen) {
|
||||
bcopy(data, cp, datalen);
|
||||
cp += datalen;
|
||||
}
|
||||
hp->dh_ancount = HTONS(1);
|
||||
break;
|
||||
|
||||
#ifdef ALLOW_UPDATES
|
||||
/*
|
||||
* For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA
|
||||
* (Record to be modified is followed by its replacement in msg.)
|
||||
*/
|
||||
case UPDATEM:
|
||||
case UPDATEMA:
|
||||
|
||||
case UPDATED:
|
||||
/*
|
||||
* The res code for UPDATED and UPDATEDA is the same; user
|
||||
* calls them differently: specifies data for UPDATED; server
|
||||
* ignores data if specified for UPDATEDA.
|
||||
*/
|
||||
case UPDATEDA:
|
||||
buflen -= RRFIXEDSZ + datalen;
|
||||
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
putshort(type, cp);
|
||||
cp += sizeof(u_short);
|
||||
putshort(class, cp);
|
||||
cp += sizeof(u_short);
|
||||
putlong(0, cp);
|
||||
cp += sizeof(u_long);
|
||||
putshort(datalen, cp);
|
||||
cp += sizeof(u_short);
|
||||
if (datalen) {
|
||||
bcopy(data, cp, datalen);
|
||||
cp += datalen;
|
||||
}
|
||||
if ( (op == UPDATED) || (op == UPDATEDA) ) {
|
||||
hp->ancount = HTONS(0);
|
||||
break;
|
||||
}
|
||||
/* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */
|
||||
|
||||
case UPDATEA: /* Add new resource record */
|
||||
buflen -= RRFIXEDSZ + datalen;
|
||||
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
putshort(newrr->r_type, cp);
|
||||
cp += sizeof(u_short);
|
||||
putshort(newrr->r_class, cp);
|
||||
cp += sizeof(u_short);
|
||||
putlong(0, cp);
|
||||
cp += sizeof(u_long);
|
||||
putshort(newrr->r_size, cp);
|
||||
cp += sizeof(u_short);
|
||||
if (newrr->r_size) {
|
||||
bcopy(newrr->r_data, cp, newrr->r_size);
|
||||
cp += newrr->r_size;
|
||||
}
|
||||
hp->ancount = HTONS(0);
|
||||
break;
|
||||
|
||||
#endif /* ALLOW_UPDATES */
|
||||
}
|
||||
return (cp - buf);
|
||||
}
|
||||
Executable
+299
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_query.c 5.7 (Berkeley) 6/1/90";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#if _MINIX
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/resolv.h>
|
||||
|
||||
typedef u8_t u_char;
|
||||
|
||||
#define bcopy(s,d,l) memcpy(d,s,l)
|
||||
|
||||
#define hostalias __hostalias
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
#define CONST const
|
||||
#else
|
||||
#define CONST
|
||||
#endif
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
int h_errno;
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await answer.
|
||||
* Returned answer is placed in supplied buffer "answer".
|
||||
* Perform preliminary check of answer, returning success only
|
||||
* if no error is indicated and the answer count is nonzero.
|
||||
* Return the size of the response on success, -1 on error.
|
||||
* Error number is left in h_errno.
|
||||
* Caller must parse answer and determine whether it answers the question.
|
||||
*/
|
||||
int
|
||||
res_query(name, class, type, answer, anslen)
|
||||
char *name; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer buffer */
|
||||
{
|
||||
char buf[MAXPACKET];
|
||||
dns_hdr_t *hp;
|
||||
int n;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return (-1);
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query(%s, %d, %d)\n", name, class, type);
|
||||
#endif
|
||||
n = res_mkquery(QUERY, name, class, type, (char *)NULL, 0, NULL,
|
||||
buf, sizeof(buf));
|
||||
|
||||
if (n <= 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query: mkquery failed\n");
|
||||
#endif
|
||||
h_errno = NO_RECOVERY;
|
||||
return (n);
|
||||
}
|
||||
n = res_send(buf, n, (char *)answer, anslen);
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query: send error(%d)\n", errno);
|
||||
#endif
|
||||
h_errno = TRY_AGAIN;
|
||||
return(n);
|
||||
}
|
||||
|
||||
hp = (dns_hdr_t *) answer;
|
||||
if ((hp->dh_flag2 & DHF_RCODE) != NOERROR ||
|
||||
ntohs(hp->dh_ancount) == 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("rcode = %d, ancount=%d\n",
|
||||
hp->dh_flag2 & DHF_RCODE,
|
||||
ntohs(hp->dh_ancount));
|
||||
#endif
|
||||
switch (hp->dh_flag2 & DHF_RCODE) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
return(n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and retrieve answer in supplied buffer.
|
||||
* Return the size of the response on success, -1 on error.
|
||||
* If enabled, implement search rules until answer or unrecoverable failure
|
||||
* is detected. Error number is left in h_errno.
|
||||
* Only useful for queries in the same name hierarchy as the local host
|
||||
* (not, for example, for host address-to-name lookups in domain in-addr.arpa).
|
||||
*/
|
||||
res_search(name, class, type, answer, anslen)
|
||||
char *name; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
register char *cp, **domain;
|
||||
int n, ret, got_nodata = 0;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return (-1);
|
||||
|
||||
errno = 0;
|
||||
h_errno = HOST_NOT_FOUND; /* default, if we never query */
|
||||
for (cp = name, n = 0; *cp; cp++)
|
||||
if (*cp == '.')
|
||||
n++;
|
||||
if (n == 0 && (cp = hostalias(name)))
|
||||
return (res_query(cp, class, type, answer, anslen));
|
||||
|
||||
/*
|
||||
* We do at least one level of search if
|
||||
* - there is no dot and RES_DEFNAME is set, or
|
||||
* - there is at least one dot, there is no trailing dot,
|
||||
* and RES_DNSRCH is set.
|
||||
*/
|
||||
if ((n == 0 && _res.options & RES_DEFNAMES) ||
|
||||
(n != 0 && *--cp != '.' && _res.options & RES_DNSRCH))
|
||||
for (domain = _res.dnsrch; *domain; domain++) {
|
||||
ret = res_querydomain(name, *domain, class, type,
|
||||
answer, anslen);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
/*
|
||||
* If no server present, give up.
|
||||
* If name isn't found in this domain,
|
||||
* keep trying higher domains in the search list
|
||||
* (if that's enabled).
|
||||
* On a NO_DATA error, keep trying, otherwise
|
||||
* a wildcard entry of another type could keep us
|
||||
* from finding this entry higher in the domain.
|
||||
* If we get some other error (negative answer or
|
||||
* server failure), then stop searching up,
|
||||
* but try the input name below in case it's fully-qualified.
|
||||
*/
|
||||
if (errno == ECONNREFUSED) {
|
||||
h_errno = TRY_AGAIN;
|
||||
return (-1);
|
||||
}
|
||||
if (h_errno == NO_DATA)
|
||||
got_nodata++;
|
||||
if ((h_errno != HOST_NOT_FOUND && h_errno != NO_DATA) ||
|
||||
(_res.options & RES_DNSRCH) == 0)
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If the search/default failed, try the name as fully-qualified,
|
||||
* but only if it contained at least one dot (even trailing).
|
||||
* This is purely a heuristic; we assume that any reasonable query
|
||||
* about a top-level domain (for servers, SOA, etc) will not use
|
||||
* res_search.
|
||||
*/
|
||||
if (n && (ret = res_querydomain(name, (char *)NULL, class, type,
|
||||
answer, anslen)) > 0)
|
||||
return (ret);
|
||||
if (got_nodata)
|
||||
h_errno = NO_DATA;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a call on res_query on the concatenation of name and domain,
|
||||
* removing a trailing dot from name if domain is NULL.
|
||||
*/
|
||||
int
|
||||
res_querydomain(name, domain, class, type, answer, anslen)
|
||||
char *name, *domain;
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
char nbuf[2*MAXDNAME+2];
|
||||
char *longname = nbuf;
|
||||
int n;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_querydomain(%s, %s, %d, %d)\n",
|
||||
name, domain, class, type);
|
||||
#endif
|
||||
if (domain == NULL) {
|
||||
/*
|
||||
* Check for trailing '.';
|
||||
* copy without '.' if present.
|
||||
*/
|
||||
n = strlen(name) - 1;
|
||||
if (name[n] == '.' && n < sizeof(nbuf) - 1) {
|
||||
bcopy(name, nbuf, n);
|
||||
nbuf[n] = '\0';
|
||||
} else
|
||||
longname = name;
|
||||
} else
|
||||
(void)sprintf(nbuf, "%.*s.%.*s",
|
||||
MAXDNAME, name, MAXDNAME, domain);
|
||||
|
||||
return (res_query(longname, class, type, answer, anslen));
|
||||
}
|
||||
|
||||
char *
|
||||
hostalias(name)
|
||||
register CONST char *name;
|
||||
{
|
||||
register char *C1, *C2;
|
||||
FILE *fp;
|
||||
char *file;
|
||||
char buf[BUFSIZ];
|
||||
static char abuf[MAXDNAME];
|
||||
|
||||
file = getenv("HOSTALIASES");
|
||||
if (file == NULL || (fp = fopen(file, "r")) == NULL)
|
||||
return (NULL);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
for (C1 = buf; *C1 && !isspace(*C1); ++C1);
|
||||
if (!*C1)
|
||||
break;
|
||||
*C1 = '\0';
|
||||
if (!strcasecmp(buf, name)) {
|
||||
while (isspace(*++C1));
|
||||
if (!*C1)
|
||||
break;
|
||||
for (C2 = C1 + 1; *C2 && !isspace(*C2); ++C2);
|
||||
abuf[sizeof(abuf) - 1] = *C2 = '\0';
|
||||
(void)strncpy(abuf, C1, sizeof(abuf) - 1);
|
||||
fclose(fp);
|
||||
return (abuf);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return (NULL);
|
||||
}
|
||||
Executable
+905
@@ -0,0 +1,905 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_send.c 6.27 (Berkeley) 2/24/91";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Send query to name server and wait for reply.
|
||||
*/
|
||||
|
||||
#if !_MINIX
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#else /* _MINIX */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/hton.h>
|
||||
|
||||
#include <net/netlib.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/nameser.h>
|
||||
#include <net/gen/resolv.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/udp.h>
|
||||
#include <net/gen/udp_hdr.h>
|
||||
#include <net/gen/udp_io.h>
|
||||
|
||||
typedef u16_t u_short;
|
||||
|
||||
static int tcp_connect _ARGS(( ipaddr_t host, Tcpport_t port, int *terrno ));
|
||||
static int tcpip_writeall _ARGS(( int fd, const char *buf, size_t siz ));
|
||||
static int udp_connect _ARGS(( void ));
|
||||
static int udp_sendto _ARGS(( int fd, const char *buf, unsigned buflen,
|
||||
ipaddr_t addr, Udpport_t port ));
|
||||
static int udp_receive _ARGS(( int fd, char *buf, unsigned buflen,
|
||||
time_t timeout ));
|
||||
static void alarm_handler _ARGS(( int sig ));
|
||||
|
||||
#endif /* !_MINIX */
|
||||
|
||||
static int s = -1; /* socket used for communications */
|
||||
#if !_MINIX
|
||||
static struct sockaddr no_addr;
|
||||
|
||||
#ifndef FD_SET
|
||||
#define NFDBITS 32
|
||||
#define FD_SETSIZE 32
|
||||
#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)))
|
||||
#endif /* FD_SET */
|
||||
#endif /* _MINIX */
|
||||
|
||||
res_send(buf, buflen, answer, anslen)
|
||||
const char *buf;
|
||||
int buflen;
|
||||
char *answer;
|
||||
int anslen;
|
||||
{
|
||||
register int n;
|
||||
int try, v_circuit, resplen, ns;
|
||||
int gotsomewhere = 0, connected = 0;
|
||||
int connreset = 0;
|
||||
#if !_MINIX
|
||||
u_short id, len;
|
||||
#else /* _MINIX */
|
||||
u16_t id, len;
|
||||
#endif /* !_MINIX */
|
||||
char *cp;
|
||||
#if !_MINIX
|
||||
fd_set dsmask;
|
||||
struct timeval timeout;
|
||||
HEADER *hp = (HEADER *) buf;
|
||||
HEADER *anhp = (HEADER *) answer;
|
||||
struct iovec iov[2];
|
||||
#else /* _MINIX */
|
||||
time_t timeout;
|
||||
dns_hdr_t *hp = (dns_hdr_t *) buf;
|
||||
dns_hdr_t *anhp = (dns_hdr_t *) answer;
|
||||
#endif /* !_MINIX */
|
||||
int terrno = ETIMEDOUT;
|
||||
char junk[512];
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf("res_send()\n");
|
||||
__p_query(buf);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
if (!(_res.options & RES_INIT))
|
||||
if (res_init() == -1) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
|
||||
#if !_MINIX
|
||||
id = hp->id;
|
||||
#else /* _MINIX */
|
||||
id = hp->dh_id;
|
||||
#endif /* !_MINIX */
|
||||
/*
|
||||
* Send request, RETRY times, or until successful
|
||||
*/
|
||||
for (try = 0; try < _res.retry; try++) {
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
#ifdef DEBUG
|
||||
#if !_MINIX
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("Querying server (# %d) address = %s\n", ns+1,
|
||||
inet_ntoa(_res.nsaddr_list[ns].sin_addr));
|
||||
#else /* _MINIX */
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("Querying server (# %d) address = %s\n", ns+1,
|
||||
inet_ntoa(_res.nsaddr_list[ns]));
|
||||
#endif /* !_MINIX */
|
||||
#endif /* DEBUG */
|
||||
usevc:
|
||||
if (v_circuit) {
|
||||
#if !_MINIX
|
||||
int truncated = 0;
|
||||
|
||||
/*
|
||||
* Use virtual circuit;
|
||||
* at most one attempt per server.
|
||||
*/
|
||||
try = _res.retry;
|
||||
if (s < 0) {
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("socket (vc) failed");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
if (connect(s,
|
||||
(struct sockaddr *)&(_res.nsaddr_list[ns]),
|
||||
sizeof(struct sockaddr)) < 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("connect failed");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Send length & message
|
||||
*/
|
||||
len = htons((u_short)buflen);
|
||||
iov[0].iov_base = (caddr_t)&len;
|
||||
iov[0].iov_len = sizeof(len);
|
||||
iov[1].iov_base = (char *)buf;
|
||||
iov[1].iov_len = buflen;
|
||||
if (writev(s, iov, 2) != sizeof(len) + buflen) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("write failed");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Receive length & response
|
||||
*/
|
||||
cp = answer;
|
||||
len = sizeof(short);
|
||||
while (len != 0 &&
|
||||
(n = read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
len -= n;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("read failed");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
/*
|
||||
* A long running process might get its TCP
|
||||
* connection reset if the remote server was
|
||||
* restarted. Requery the server instead of
|
||||
* trying a new one. When there is only one
|
||||
* server, this means that a query might work
|
||||
* instead of failing. We only allow one reset
|
||||
* per query to prevent looping.
|
||||
*/
|
||||
if (terrno == ECONNRESET && !connreset) {
|
||||
connreset = 1;
|
||||
ns--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
cp = answer;
|
||||
if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "response truncated\n");
|
||||
#endif /* DEBUG */
|
||||
len = anslen;
|
||||
truncated = 1;
|
||||
} else
|
||||
len = resplen;
|
||||
while (len != 0 &&
|
||||
(n = read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
len -= n;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("read failed");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
if (truncated) {
|
||||
/*
|
||||
* Flush rest of answer
|
||||
* so connection stays in synch.
|
||||
*/
|
||||
anhp->tc = 1;
|
||||
len = resplen - anslen;
|
||||
while (len != 0) {
|
||||
n = (len > sizeof(junk) ?
|
||||
sizeof(junk) : len);
|
||||
if ((n = read(s, junk, n)) > 0)
|
||||
len -= n;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else /* _MINIX */
|
||||
int truncated = 0;
|
||||
int nbytes;
|
||||
|
||||
/*
|
||||
* Use virtual circuit;
|
||||
* at most one attempt per server.
|
||||
*/
|
||||
try = _res.retry;
|
||||
if (s < 0)
|
||||
{
|
||||
s= tcp_connect(_res.nsaddr_list[ns],
|
||||
_res.nsport_list[ns], &terrno);
|
||||
if (s == -1)
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Send length & message
|
||||
*/
|
||||
len = htons((u_short)buflen);
|
||||
nbytes= tcpip_writeall(s, (char *)&len,
|
||||
sizeof(len));
|
||||
if (nbytes != sizeof(len))
|
||||
{
|
||||
terrno= errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "write failed: %s\n",
|
||||
strerror(terrno));
|
||||
#endif /* DEBUG */
|
||||
close(s);
|
||||
s= -1;
|
||||
continue;
|
||||
}
|
||||
nbytes= tcpip_writeall(s, buf, buflen);
|
||||
if (nbytes != buflen)
|
||||
{
|
||||
terrno= errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "write failed: %s\n",
|
||||
strerror(terrno));
|
||||
#endif /* DEBUG */
|
||||
close(s);
|
||||
s= -1;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Receive length & response
|
||||
*/
|
||||
cp = answer;
|
||||
len = sizeof(short);
|
||||
while (len != 0)
|
||||
{
|
||||
n = read(s, (char *)cp, (int)len);
|
||||
if (n <= 0)
|
||||
break;
|
||||
cp += n;
|
||||
assert(len >= n);
|
||||
len -= n;
|
||||
}
|
||||
if (len) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "read failed: %s\n",
|
||||
strerror(terrno));
|
||||
#endif /* DEBUG */
|
||||
close(s);
|
||||
s= -1;
|
||||
/*
|
||||
* A long running process might get its TCP
|
||||
* connection reset if the remote server was
|
||||
* restarted. Requery the server instead of
|
||||
* trying a new one. When there is only one
|
||||
* server, this means that a query might work
|
||||
* instead of failing. We only allow one reset
|
||||
* per query to prevent looping.
|
||||
*/
|
||||
if (terrno == ECONNRESET && !connreset) {
|
||||
connreset = 1;
|
||||
ns--;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
cp = answer;
|
||||
if ((resplen = ntohs(*(u_short *)cp)) > anslen) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "response truncated\n");
|
||||
#endif /* DEBUG */
|
||||
len = anslen;
|
||||
truncated = 1;
|
||||
} else
|
||||
len = resplen;
|
||||
while (len != 0)
|
||||
{
|
||||
n= read(s, (char *)cp, (int)len);
|
||||
if (n <= 0)
|
||||
break;
|
||||
cp += n;
|
||||
assert(len >= n);
|
||||
len -= n;
|
||||
}
|
||||
if (len) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
fprintf(stderr, "read failed: %s\n",
|
||||
strerror(terrno));
|
||||
#endif /* DEBUG */
|
||||
close(s);
|
||||
s= -1;
|
||||
continue;
|
||||
}
|
||||
if (truncated) {
|
||||
/*
|
||||
* Flush rest of answer
|
||||
* so connection stays in synch.
|
||||
*/
|
||||
anhp->dh_flag1 |= DHF_TC;
|
||||
len = resplen - anslen;
|
||||
while (len != 0) {
|
||||
n = (len > sizeof(junk) ?
|
||||
sizeof(junk) : len);
|
||||
n = read(s, junk, n);
|
||||
if (n <= 0)
|
||||
{
|
||||
assert(len >= n);
|
||||
len -= n;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* _MINIX */
|
||||
} else {
|
||||
#if !_MINIX
|
||||
/*
|
||||
* Use datagrams.
|
||||
*/
|
||||
if (s < 0) {
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("socket (dg) failed");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#if BSD >= 43
|
||||
/*
|
||||
* I'm tired of answering this question, so:
|
||||
* On a 4.3BSD+ machine (client and server,
|
||||
* actually), sending to a nameserver datagram
|
||||
* port with no nameserver will cause an
|
||||
* ICMP port unreachable message to be returned.
|
||||
* If our datagram socket is "connected" to the
|
||||
* server, we get an ECONNREFUSED error on the next
|
||||
* socket operation, and select returns if the
|
||||
* error message is received. We can thus detect
|
||||
* the absence of a nameserver without timing out.
|
||||
* If we have sent queries to at least two servers,
|
||||
* however, we don't want to remain connected,
|
||||
* as we wish to receive answers from the first
|
||||
* server to respond.
|
||||
*/
|
||||
if (_res.nscount == 1 || (try == 0 && ns == 0)) {
|
||||
/*
|
||||
* Don't use connect if we might
|
||||
* still receive a response
|
||||
* from another server.
|
||||
*/
|
||||
if (connected == 0) {
|
||||
if (connect(s, (struct sockaddr *)&_res.nsaddr_list[ns],
|
||||
sizeof(struct sockaddr)) < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("connect");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
connected = 1;
|
||||
}
|
||||
if (send(s, buf, buflen, 0) != buflen) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("send");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Disconnect if we want to listen
|
||||
* for responses from more than one server.
|
||||
*/
|
||||
if (connected) {
|
||||
(void) connect(s, &no_addr,
|
||||
sizeof(no_addr));
|
||||
connected = 0;
|
||||
}
|
||||
#endif /* BSD */
|
||||
if (sendto(s, buf, buflen, 0,
|
||||
(struct sockaddr *)&_res.nsaddr_list[ns],
|
||||
sizeof(struct sockaddr)) != buflen) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("sendto");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
#if BSD >= 43
|
||||
}
|
||||
#endif /* BSD */
|
||||
|
||||
/*
|
||||
* Wait for reply
|
||||
*/
|
||||
timeout.tv_sec = (_res.retrans << try);
|
||||
if (try > 0)
|
||||
timeout.tv_sec /= _res.nscount;
|
||||
if (timeout.tv_sec <= 0)
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
wait:
|
||||
FD_ZERO(&dsmask);
|
||||
FD_SET(s, &dsmask);
|
||||
n = select(s+1, &dsmask, (fd_set *)NULL,
|
||||
(fd_set *)NULL, &timeout);
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("select");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
if (n == 0) {
|
||||
/*
|
||||
* timeout
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("timeout\n");
|
||||
#endif /* DEBUG */
|
||||
#if BSD >= 43
|
||||
gotsomewhere = 1;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if ((resplen = recv(s, answer, anslen, 0)) <= 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("recvfrom");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
gotsomewhere = 1;
|
||||
if (id != anhp->id) {
|
||||
/*
|
||||
* response from old query, ignore it
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf("old answer:\n");
|
||||
__p_query(answer);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
goto wait;
|
||||
}
|
||||
if (!(_res.options & RES_IGNTC) && anhp->tc) {
|
||||
/*
|
||||
* get rest of answer;
|
||||
* use TCP with same server.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("truncated answer\n");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
v_circuit = 1;
|
||||
goto usevc;
|
||||
}
|
||||
#else /* _MINIX */
|
||||
/*
|
||||
* Use datagrams.
|
||||
*/
|
||||
if (s < 0) {
|
||||
s = udp_connect();
|
||||
if (s < 0) {
|
||||
terrno = errno;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("udp_connect failed");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (udp_sendto(s, buf, buflen, _res.nsaddr_list[ns],
|
||||
_res.nsport_list[ns]) != buflen) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("sendto");
|
||||
#endif /* DEBUG */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for reply
|
||||
*/
|
||||
timeout= (_res.retrans << try);
|
||||
if (try > 0)
|
||||
timeout /= _res.nscount;
|
||||
if (timeout <= 0)
|
||||
timeout= 1;
|
||||
wait:
|
||||
if ((resplen= udp_receive(s, answer, anslen, timeout))
|
||||
== -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
/*
|
||||
* timeout
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("timeout\n");
|
||||
#endif /* DEBUG */
|
||||
gotsomewhere = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
perror("udp_receive");
|
||||
#endif /* DEBUG */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
gotsomewhere = 1;
|
||||
if (id != anhp->dh_id) {
|
||||
/*
|
||||
* response from old query, ignore it
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf("old answer:\n");
|
||||
__p_query(answer);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
goto wait;
|
||||
}
|
||||
if (!(_res.options & RES_IGNTC) &&
|
||||
(anhp->dh_flag1 & DHF_TC)) {
|
||||
/*
|
||||
* get rest of answer;
|
||||
* use TCP with same server.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("truncated answer\n");
|
||||
#endif /* DEBUG */
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
v_circuit = 1;
|
||||
goto usevc;
|
||||
}
|
||||
#endif /* !_MINIX */
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf("got answer:\n");
|
||||
__p_query(answer);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
/*
|
||||
* If using virtual circuits, we assume that the first server
|
||||
* is preferred * over the rest (i.e. it is on the local
|
||||
* machine) and only keep that one open.
|
||||
* If we have temporarily opened a virtual circuit,
|
||||
* or if we haven't been asked to keep a socket open,
|
||||
* close the socket.
|
||||
*/
|
||||
if ((v_circuit &&
|
||||
((_res.options & RES_USEVC) == 0 || ns != 0)) ||
|
||||
(_res.options & RES_STAYOPEN) == 0) {
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
}
|
||||
return (resplen);
|
||||
}
|
||||
}
|
||||
if (s >= 0) {
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
}
|
||||
if (v_circuit == 0)
|
||||
if (gotsomewhere == 0)
|
||||
errno = ECONNREFUSED; /* no nameservers found */
|
||||
else
|
||||
errno = ETIMEDOUT; /* no answer obtained */
|
||||
else
|
||||
errno = terrno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is for closing the socket if a virtual circuit is used and
|
||||
* the program wants to close it. This provides support for endhostent()
|
||||
* which expects to close the socket.
|
||||
*
|
||||
* This routine is not expected to be user visible.
|
||||
*/
|
||||
void
|
||||
_res_close()
|
||||
{
|
||||
if (s != -1) {
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if _MINIX
|
||||
static int tcp_connect(host, port, terrno)
|
||||
ipaddr_t host;
|
||||
tcpport_t port;
|
||||
int *terrno;
|
||||
{
|
||||
char *dev_name;
|
||||
int fd;
|
||||
int error;
|
||||
nwio_tcpconf_t tcpconf;
|
||||
nwio_tcpcl_t clopt;
|
||||
|
||||
dev_name= getenv("TCP_DEVICE");
|
||||
if (!dev_name)
|
||||
dev_name= TCP_DEVICE;
|
||||
fd= open(dev_name, O_RDWR);
|
||||
if (fd == -1)
|
||||
{
|
||||
*terrno= errno;
|
||||
return -1;
|
||||
}
|
||||
tcpconf.nwtc_flags= NWTC_EXCL | NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;
|
||||
tcpconf.nwtc_remaddr= host;
|
||||
tcpconf.nwtc_remport= port;
|
||||
error= ioctl(fd, NWIOSTCPCONF, &tcpconf);
|
||||
if (error == -1)
|
||||
{
|
||||
*terrno= errno;
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
clopt.nwtcl_flags= 0;
|
||||
error= ioctl(fd, NWIOTCPCONN, &clopt);
|
||||
if (error == -1)
|
||||
{
|
||||
*terrno= errno;
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
*terrno= 0;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int tcpip_writeall(fd, buf, siz)
|
||||
int fd;
|
||||
const char *buf;
|
||||
size_t siz;
|
||||
{
|
||||
size_t siz_org;
|
||||
int nbytes;
|
||||
|
||||
siz_org= siz;
|
||||
|
||||
while (siz)
|
||||
{
|
||||
nbytes= write(fd, buf, siz);
|
||||
if (nbytes <= 0)
|
||||
return siz_org-siz;
|
||||
assert(siz >= nbytes);
|
||||
buf += nbytes;
|
||||
siz -= nbytes;
|
||||
}
|
||||
return siz_org;
|
||||
}
|
||||
|
||||
|
||||
static int udp_connect()
|
||||
{
|
||||
nwio_udpopt_t udpopt;
|
||||
char *dev_name;
|
||||
int fd, r, terrno;
|
||||
|
||||
dev_name= getenv("UDP_DEVICE");
|
||||
if (!dev_name)
|
||||
dev_name= UDP_DEVICE;
|
||||
fd= open(dev_name, O_RDWR);
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
udpopt.nwuo_flags= NWUO_COPY | NWUO_LP_SEL | NWUO_EN_LOC |
|
||||
NWUO_EN_BROAD | NWUO_RP_ANY | NWUO_RA_ANY | NWUO_RWDATALL |
|
||||
NWUO_DI_IPOPT;
|
||||
r= ioctl(fd, NWIOSUDPOPT, &udpopt);
|
||||
if (r == -1)
|
||||
{
|
||||
terrno= errno;
|
||||
close(fd);
|
||||
errno= terrno;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
static int udp_sendto(fd, buf, buflen, addr, port)
|
||||
int fd;
|
||||
const char *buf;
|
||||
unsigned buflen;
|
||||
ipaddr_t addr;
|
||||
udpport_t port;
|
||||
{
|
||||
char *newbuf;
|
||||
udp_io_hdr_t *udp_io_hdr;
|
||||
int r, terrno;
|
||||
|
||||
newbuf= malloc(sizeof(*udp_io_hdr) + buflen);
|
||||
if (newbuf == NULL)
|
||||
{
|
||||
errno= ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
udp_io_hdr= (udp_io_hdr_t *)newbuf;
|
||||
udp_io_hdr->uih_dst_addr= addr;
|
||||
udp_io_hdr->uih_dst_port= port;
|
||||
udp_io_hdr->uih_ip_opt_len= 0;
|
||||
udp_io_hdr->uih_data_len= buflen;
|
||||
|
||||
memcpy(newbuf + sizeof(*udp_io_hdr), buf, buflen);
|
||||
r= write(fd, newbuf, sizeof(*udp_io_hdr) + buflen);
|
||||
terrno= errno;
|
||||
free(newbuf);
|
||||
if (r >= sizeof(*udp_io_hdr))
|
||||
r -= sizeof(*udp_io_hdr);
|
||||
errno= terrno;
|
||||
return r;
|
||||
}
|
||||
|
||||
static void alarm_handler(sig)
|
||||
int sig;
|
||||
{
|
||||
signal(SIGALRM, alarm_handler);
|
||||
alarm(1);
|
||||
}
|
||||
|
||||
static int udp_receive(fd, buf, buflen, timeout)
|
||||
int fd;
|
||||
char *buf;
|
||||
unsigned buflen;
|
||||
time_t timeout;
|
||||
{
|
||||
char *newbuf;
|
||||
udp_io_hdr_t *udp_io_hdr;
|
||||
int r, terrno;
|
||||
void (*u_handler) _ARGS(( int sig ));
|
||||
time_t u_timeout;
|
||||
|
||||
newbuf= malloc(sizeof(*udp_io_hdr) + buflen);
|
||||
if (newbuf == NULL)
|
||||
{
|
||||
errno= ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
u_handler= signal(SIGALRM, alarm_handler);
|
||||
u_timeout= alarm(timeout);
|
||||
|
||||
r= read(fd, newbuf, sizeof(*udp_io_hdr) + buflen);
|
||||
terrno= errno;
|
||||
|
||||
if (r < 0 || r <= sizeof(*udp_io_hdr))
|
||||
{
|
||||
if (r > 0)
|
||||
r= 0;
|
||||
free(newbuf);
|
||||
|
||||
|
||||
alarm(0);
|
||||
signal(SIGALRM, u_handler);
|
||||
alarm(u_timeout);
|
||||
|
||||
errno= terrno;
|
||||
return r;
|
||||
}
|
||||
|
||||
memcpy(buf, newbuf + sizeof(*udp_io_hdr), r - sizeof(*udp_io_hdr));
|
||||
free(newbuf);
|
||||
|
||||
alarm(0);
|
||||
signal(SIGALRM, u_handler);
|
||||
alarm(u_timeout);
|
||||
|
||||
return r-sizeof(*udp_io_hdr);
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+187
@@ -0,0 +1,187 @@
|
||||
/* ruserok() - hosts.equiv and .rhosts check Author: Kees J. Bot
|
||||
* 25 May 2001
|
||||
*
|
||||
* Under Minix one can use IP addresses, CIDR network blocks, and hostnames
|
||||
* with wildcards in .rhosts files. Only the iruserok() interface can be
|
||||
* used, and the IP address is reverse/forward crosschecked if a hostname
|
||||
* match is done. Ruserok() is dead and buried. The superuser parameter is
|
||||
* ignored, because it makes root too special. Most users on Minix can be
|
||||
* root, so hosts.equiv would become useless if root can't use it. Likewise
|
||||
* .rhosts isn't checked to be root or user owned and stuff, users have to
|
||||
* be careful themselves.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/netdb.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/socket.h>
|
||||
#include <net/gen/nameser.h>
|
||||
|
||||
/* Odd global variable. Seems to be used by lpd(8). */
|
||||
int __check_rhosts_file = 1;
|
||||
|
||||
static int cidr_aton(char *word, ipaddr_t *addr, ipaddr_t *mask)
|
||||
/* Try to interpret 'word' as an CIDR spec, e.g. 172.16.102.64/27. */
|
||||
{
|
||||
char *slash;
|
||||
int r;
|
||||
static char S32[]= "/32";
|
||||
|
||||
if (*word == 0) return 0;
|
||||
|
||||
if ((slash= strchr(word, '/')) == NULL) slash= S32;
|
||||
|
||||
*slash= 0;
|
||||
r= inet_aton(word, addr);
|
||||
*slash++= '/';
|
||||
if (!r) return 0;
|
||||
|
||||
r= 0;
|
||||
while ((*slash - '0') < 10u) {
|
||||
r= 10*r + (*slash++ - '0');
|
||||
if (r > 32) return 0;
|
||||
}
|
||||
if (*slash != 0 || slash[-1] == '/') return 0;
|
||||
*mask= htonl(r == 0 ? 0L : (0xFFFFFFFFUL >> (32 - r)) << (32 - r));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int match(const char *word, const char *pattern)
|
||||
/* Match word onto a pattern. Pattern may contain the * wildcard. */
|
||||
{
|
||||
unsigned cw, cp;
|
||||
#define lc(c, d) ((((c)= (d)) - 'A') <= ('Z' - 'A') ? (c)+= ('a' - 'A') : 0)
|
||||
|
||||
for (;;) {
|
||||
lc(cw, *word);
|
||||
lc(cp, *pattern);
|
||||
|
||||
if (cp == '*') {
|
||||
do pattern++; while (*pattern == '*');
|
||||
lc(cp, *pattern);
|
||||
if (cp == 0) return 1;
|
||||
|
||||
while (cw != 0) {
|
||||
if (cw == cp && match(word+1, pattern+1)) return 1;
|
||||
word++;
|
||||
lc(cw, *word);
|
||||
}
|
||||
return 0;
|
||||
} else
|
||||
if (cw == 0 || cp == 0) {
|
||||
return cw == cp;
|
||||
} else
|
||||
if (cw == cp) {
|
||||
word++;
|
||||
pattern++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#undef lc
|
||||
}
|
||||
|
||||
static int get_name(ipaddr_t addr, char *name)
|
||||
/* Do a reverse lookup on the remote IP address followed by a forward lookup
|
||||
* to check if the host has that address. Return true if this is so, return
|
||||
* either the true name or the ascii IP address in name[].
|
||||
*/
|
||||
{
|
||||
struct hostent *he;
|
||||
int ok, i;
|
||||
|
||||
ok= 0;
|
||||
he= gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
|
||||
if (he != NULL) {
|
||||
strcpy(name, he->h_name);
|
||||
he= gethostbyname(name);
|
||||
|
||||
if (he != NULL && he->h_addrtype == AF_INET) {
|
||||
for (i= 0; he->h_addr_list[i] != NULL; i++) {
|
||||
if (memcmp(he->h_addr_list[i], &addr, sizeof(addr)) == 0) {
|
||||
ok= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
strcpy(name, ok ? he->h_name : inet_ntoa(addr));
|
||||
return ok;
|
||||
}
|
||||
|
||||
int __ivaliduser(FILE *hostf, unsigned long raddr,
|
||||
const char *luser, const char *ruser)
|
||||
{
|
||||
register char *p;
|
||||
char buf[MAXDNAME + 128]; /* host + login */
|
||||
char rhost[MAXDNAME]; /* remote host */
|
||||
char *word[2];
|
||||
int i, ch, got_name;
|
||||
ipaddr_t addr, mask;
|
||||
|
||||
got_name = -1;
|
||||
|
||||
while (fgets(buf, sizeof(buf), hostf)) {
|
||||
/* Skip lines that are too long. */
|
||||
if (strchr(buf, '\n') == NULL) {
|
||||
while ((ch = fgetc(hostf)) != '\n' && ch != EOF);
|
||||
continue;
|
||||
}
|
||||
i = 0;
|
||||
p = buf;
|
||||
for (;;) {
|
||||
while (isspace(*p)) *p++ = '\0';
|
||||
if (*p == '\0') break;
|
||||
if (i < 2) word[i] = p;
|
||||
i++;
|
||||
while (*p != '\0' && !isspace(*p)) p++;
|
||||
}
|
||||
if (i != 1 && i != 2) continue;
|
||||
if (word[0][0] == '#') continue;
|
||||
if (strcmp(ruser, i == 2 ? word[1] : luser) != 0) continue;
|
||||
|
||||
if (cidr_aton(word[0], &addr, &mask)) {
|
||||
if (((raddr ^ addr) & mask) == 0) return (0);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (got_name == -1) got_name = get_name(raddr, rhost);
|
||||
if (match(rhost, word[0])) return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int iruserok(unsigned long raddr, int superuser,
|
||||
const char *ruser, const char *luser)
|
||||
{
|
||||
/* Returns 0 if ok, -1 if not ok. */
|
||||
struct passwd *pwd;
|
||||
FILE *hostf;
|
||||
int i, r;
|
||||
char pbuf[PATH_MAX];
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i == 0) {
|
||||
strcpy(pbuf, _PATH_HEQUIV);
|
||||
} else {
|
||||
if (!__check_rhosts_file) return (-1);
|
||||
if ((pwd = getpwnam(luser)) == NULL) return (-1);
|
||||
(void)strcpy(pbuf, pwd->pw_dir);
|
||||
(void)strcat(pbuf, "/.rhosts");
|
||||
}
|
||||
|
||||
if ((hostf = fopen(pbuf, "r")) == NULL) return (-1);
|
||||
|
||||
r = __ivaliduser(hostf, raddr, luser, ruser);
|
||||
(void)fclose(hostf);
|
||||
if (r == 0) return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
Executable
+302
@@ -0,0 +1,302 @@
|
||||
/* servxcheck() - Service access check. Author: Kees J. Bot
|
||||
* 8 Jan 1997
|
||||
*/
|
||||
#define nil 0
|
||||
#define ioctl _ioctl
|
||||
#define open _open
|
||||
#define write _write
|
||||
#define close _close
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/hton.h>
|
||||
#include <net/gen/in.h>
|
||||
#include <net/gen/tcp.h>
|
||||
#include <net/gen/tcp_io.h>
|
||||
#include <net/gen/inet.h>
|
||||
#include <net/gen/socket.h>
|
||||
#include <net/gen/netdb.h>
|
||||
|
||||
/* Default service access file. */
|
||||
static const char *path_servacces = _PATH_SERVACCES;
|
||||
|
||||
#define WLEN 256
|
||||
|
||||
static int getword(FILE *fp, char *word)
|
||||
/* Read a word from the file open by 'fp', skip whitespace and comments.
|
||||
* Colon and semicolon are returned as a one character "word". Returns
|
||||
* word[0] or EOF.
|
||||
*/
|
||||
{
|
||||
int c;
|
||||
char *pw;
|
||||
int wc;
|
||||
|
||||
wc= 0;
|
||||
for (;;) {
|
||||
if ((c= getc(fp)) == EOF) return EOF;
|
||||
if (c == '#') { wc= 1; continue; }
|
||||
if (c == '\n') { wc= 0; continue; }
|
||||
if (wc) continue;
|
||||
if (c <= ' ') continue;
|
||||
break;
|
||||
}
|
||||
|
||||
pw= word;
|
||||
if (c == ':' || c == ';') {
|
||||
*pw++ = c;
|
||||
} else {
|
||||
do {
|
||||
if (pw < word + WLEN-1) *pw++ = c;
|
||||
c= getc(fp);
|
||||
} while (c != EOF && c > ' ' && c != ':' && c != ';');
|
||||
if (c != EOF) ungetc(c, fp);
|
||||
}
|
||||
*pw= 0;
|
||||
return word[0];
|
||||
}
|
||||
|
||||
static int netspec(char *word, ipaddr_t *addr, ipaddr_t *mask)
|
||||
/* Try to interpret 'word' as an network spec, e.g. 172.16.102.64/27. */
|
||||
{
|
||||
char *slash;
|
||||
int r;
|
||||
static char S32[]= "/32";
|
||||
|
||||
if (*word == 0) return 0;
|
||||
|
||||
if ((slash= strchr(word, '/')) == NULL) slash= S32;
|
||||
|
||||
*slash= 0;
|
||||
r= inet_aton(word, addr);
|
||||
*slash++= '/';
|
||||
if (!r) return 0;
|
||||
|
||||
r= 0;
|
||||
while ((*slash - '0') < 10u) {
|
||||
r= 10*r + (*slash++ - '0');
|
||||
if (r > 32) return 0;
|
||||
}
|
||||
if (*slash != 0 || slash[-1] == '/') return 0;
|
||||
*mask= htonl(r == 0 ? 0L : (0xFFFFFFFFUL >> (32 - r)) << (32 - r));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int match(const char *word, const char *pattern)
|
||||
/* Match word onto a pattern. Pattern may contain the * wildcard. */
|
||||
{
|
||||
unsigned cw, cp;
|
||||
#define lc(c, d) ((((c)= (d)) - 'A') <= ('Z' - 'A') ? (c)+= ('a' - 'A') : 0)
|
||||
|
||||
for (;;) {
|
||||
lc(cw, *word);
|
||||
lc(cp, *pattern);
|
||||
|
||||
if (cp == '*') {
|
||||
do pattern++; while (*pattern == '*');
|
||||
lc(cp, *pattern);
|
||||
if (cp == 0) return 1;
|
||||
|
||||
while (cw != 0) {
|
||||
if (cw == cp && match(word+1, pattern+1)) return 1;
|
||||
word++;
|
||||
lc(cw, *word);
|
||||
}
|
||||
return 0;
|
||||
} else
|
||||
if (cw == 0 || cp == 0) {
|
||||
return cw == cp;
|
||||
} else
|
||||
if (cw == cp) {
|
||||
word++;
|
||||
pattern++;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#undef lc
|
||||
}
|
||||
|
||||
static int get_name(ipaddr_t addr, char *name)
|
||||
/* Do a reverse lookup on the remote IP address followed by a forward lookup
|
||||
* to check if the host has that address. Return true if this is so, return
|
||||
* either the true name or the ascii IP address in name[].
|
||||
*/
|
||||
{
|
||||
struct hostent *he;
|
||||
int i;
|
||||
|
||||
he= gethostbyaddr((char *) &addr, sizeof(addr), AF_INET);
|
||||
if (he != NULL) {
|
||||
strcpy(name, he->h_name);
|
||||
he= gethostbyname(name);
|
||||
|
||||
if (he != NULL && he->h_addrtype == AF_INET) {
|
||||
for (i= 0; he->h_addr_list[i] != NULL; i++) {
|
||||
if (memcmp(he->h_addr_list[i], &addr, sizeof(addr)) == 0) {
|
||||
strcpy(name, he->h_name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
strcpy(name, inet_ntoa(addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* "state" and "log" flags, made to be bitwise comparable. */
|
||||
#define DEFFAIL 0x01
|
||||
#define FAIL (0x02 | DEFFAIL)
|
||||
#define PASS 0x04
|
||||
|
||||
int servxcheck(ipaddr_t peer, const char *service,
|
||||
void (*logf)(int pass, const char *name))
|
||||
{
|
||||
FILE *fp;
|
||||
char word[WLEN];
|
||||
char name[WLEN];
|
||||
int c;
|
||||
int got_name, slist, seen, explicit, state, log;
|
||||
ipaddr_t addr, mask;
|
||||
|
||||
/* Localhost? */
|
||||
if ((peer & HTONL(0xFF000000)) == HTONL(0x7F000000)) return 1;
|
||||
|
||||
if ((fp= fopen(path_servacces, "r")) == nil) {
|
||||
/* Succeed on error, fail if simply nonexistent. */
|
||||
return (errno != ENOENT);
|
||||
}
|
||||
|
||||
slist= 1; /* Services list (before the colon.) */
|
||||
seen= 0; /* Given service not yet seen. */
|
||||
explicit= 0; /* Service mentioned explicitly. */
|
||||
got_name= -1; /* No reverse lookup done yet. */
|
||||
log= FAIL; /* By default log failures only. */
|
||||
state= DEFFAIL; /* Access denied until we know better. */
|
||||
|
||||
while ((c= getword(fp, word)) != EOF) {
|
||||
if (c == ':') {
|
||||
slist= 0; /* Switch to access list. */
|
||||
} else
|
||||
if (c == ';') {
|
||||
slist= 1; /* Back to list of services. */
|
||||
seen= 0;
|
||||
} else
|
||||
if (slist) {
|
||||
/* Traverse services list. */
|
||||
|
||||
if (match(service, word)) {
|
||||
/* Service has been spotted! */
|
||||
if (match(word, service)) {
|
||||
/* Service mentioned without wildcards. */
|
||||
seen= explicit= 1;
|
||||
} else {
|
||||
/* Matched by a wildcard. */
|
||||
if (!explicit) seen= 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Traverse access list. */
|
||||
|
||||
if (c == 'l' && strcmp(word, "log") == 0) {
|
||||
if (seen) {
|
||||
/* Log failures and successes. */
|
||||
log= FAIL|PASS;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c != '-' && c != '+') {
|
||||
if (logf == nil) {
|
||||
fprintf(stderr, "%s: strange check word '%s'\n",
|
||||
path_servacces, word);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (seen) {
|
||||
if (state == DEFFAIL) {
|
||||
/* First check determines the default. */
|
||||
state= c == '+' ? FAIL : PASS;
|
||||
}
|
||||
|
||||
if ((state == PASS) == (c == '+')) {
|
||||
/* This check won't change state. */
|
||||
} else
|
||||
if (word[1] == 0) {
|
||||
/* Lone + or - allows all or none. */
|
||||
state= c == '-' ? FAIL : PASS;
|
||||
} else
|
||||
if (netspec(word+1, &addr, &mask)) {
|
||||
/* Remote host is on the specified network? */
|
||||
if (((peer ^ addr) & mask) == 0) {
|
||||
state= c == '-' ? FAIL : PASS;
|
||||
}
|
||||
} else {
|
||||
/* Name check. */
|
||||
if (got_name == -1) {
|
||||
got_name= get_name(peer, name);
|
||||
}
|
||||
|
||||
/* Remote host name matches the word? */
|
||||
if (!got_name) {
|
||||
state= FAIL;
|
||||
} else
|
||||
if (match(name, word+1)) {
|
||||
state= c == '-' ? FAIL : PASS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if ((log & state) != 0) {
|
||||
/* Log the result of the check. */
|
||||
if (got_name == -1) (void) get_name(peer, name);
|
||||
|
||||
if (logf != nil) {
|
||||
(*logf)(state == PASS, name);
|
||||
} else {
|
||||
int lfd;
|
||||
char line[128+WLEN];
|
||||
time_t t;
|
||||
struct tm *tm;
|
||||
char month[][4]= {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
|
||||
};
|
||||
|
||||
if ((lfd= open("/usr/adm/log", O_WRONLY|O_APPEND)) != -1) {
|
||||
time(&t);
|
||||
tm= localtime(&t);
|
||||
sprintf(line, "%s %02d %02d:%02d:%02d service '%s' %s to %s\n",
|
||||
month[tm->tm_mon],
|
||||
tm->tm_mday,
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
service,
|
||||
state == PASS ? "granted" : "denied",
|
||||
name);
|
||||
(void) write(lfd, line, strlen(line));
|
||||
close(lfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return state == PASS;
|
||||
}
|
||||
|
||||
char *servxfile(const char *file)
|
||||
/* Specify a file to use for the access checks other than the default. Return
|
||||
* the old path.
|
||||
*/
|
||||
{
|
||||
const char *oldpath= path_servacces;
|
||||
path_servacces= file;
|
||||
return (char *) oldpath; /* (avoid const poisoning) */
|
||||
}
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
strcasecmp.c
|
||||
|
||||
Created Oct 14, 1991 by Philip Homburg
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
#define _CONST const
|
||||
#else
|
||||
#define _CONST
|
||||
#endif
|
||||
|
||||
int
|
||||
strcasecmp(s1, s2)
|
||||
_CONST char *s1, *s2;
|
||||
{
|
||||
int c1, c2;
|
||||
while (c1= toupper(*s1++), c2= toupper(*s2++), c1 == c2 && (c1 & c2))
|
||||
;
|
||||
if (c1 & c2)
|
||||
return c1 < c2 ? -1 : 1;
|
||||
return c1 ? 1 : (c2 ? -1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
strncasecmp(s1, s2, len)
|
||||
_CONST char *s1, *s2;
|
||||
size_t len;
|
||||
{
|
||||
int c1, c2;
|
||||
do {
|
||||
if (len == 0)
|
||||
return 0;
|
||||
len--;
|
||||
} while (c1= toupper(*s1++), c2= toupper(*s2++), c1 == c2 && (c1 & c2))
|
||||
;
|
||||
if (c1 & c2)
|
||||
return c1 < c2 ? -1 : 1;
|
||||
return c1 ? 1 : (c2 ? -1 : 0);
|
||||
}
|
||||
Reference in New Issue
Block a user