#if !defined(lint) && !defined(SABER) static char sccsid[] = "@(#)db_glue.c 4.4 (Berkeley) 6/1/90"; static char rcsid[] = "$Id: db_glue.c,v 4.9.1.1 1993/05/02 22:43:03 vixie Rel $"; #endif /* not lint */ /* * ++Copyright++ 1986, 1988 * - * Copyright (c) 1986, 1988 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. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #include <sys/types.h> #include <sys/uio.h> #include <sys/param.h> #include <sys/time.h> #include <sys/stat.h> #include <netinet/in.h> #include <arpa/nameser.h> #include <stdio.h> #include <syslog.h> #include <ctype.h> #include <netdb.h> #include <errno.h> #include "../conf/portability.h" #include "../conf/options.h" #include "ns.h" #include "db.h" struct valuelist { struct valuelist *next, *prev; char *name; char *proto; short port; } *servicelist, *protolist; void buildservicelist() { struct servent *sp; struct valuelist *slp; setservent(1); while (sp = getservent()) { slp = (struct valuelist *)malloc(sizeof(struct valuelist)); slp->name = savestr(sp->s_name); slp->proto = savestr(sp->s_proto); slp->port = ntohs((u_short)sp->s_port); slp->next = servicelist; slp->prev = NULL; if (servicelist) servicelist->prev = slp; servicelist = slp; } endservent(); } void buildprotolist() { struct protoent *pp; struct valuelist *slp; setprotoent(1); while (pp = getprotoent()) { slp = (struct valuelist *)malloc(sizeof(struct valuelist)); slp->name = savestr(pp->p_name); slp->port = pp->p_proto; slp->next = protolist; slp->prev = NULL; if (protolist) protolist->prev = slp; protolist = slp; } endprotoent(); } /* * Convert service name or (ascii) number to int. */ int servicenumber(p) char *p; { return (findservice(p, &servicelist)); } /* * Convert protocol name or (ascii) number to int. */ int protocolnumber(p) char *p; { return (findservice(p, &protolist)); } int findservice(s, list) register char *s; register struct valuelist **list; { register struct valuelist *lp = *list; int n; for (; lp != NULL; lp = lp->next) if (strcasecmp(lp->name, s) == 0) { if (lp != *list) { lp->prev->next = lp->next; if (lp->next) lp->next->prev = lp->prev; (*list)->prev = lp; lp->next = *list; *list = lp; } return(lp->port); } if (sscanf(s, "%d", &n) != 1 || n <= 0) n = -1; return(n); } struct servent * cgetservbyport(port, proto) u_short port; char *proto; { register struct valuelist **list = &servicelist; register struct valuelist *lp = *list; static struct servent serv; port = htons(port); for (; lp != NULL; lp = lp->next) { if (port != (u_short)lp->port) continue; if (strcasecmp(lp->proto, proto) == 0) { if (lp != *list) { lp->prev->next = lp->next; if (lp->next) lp->next->prev = lp->prev; (*list)->prev = lp; lp->next = *list; *list = lp; } serv.s_name = lp->name; serv.s_port = htons((u_short)lp->port); serv.s_proto = lp->proto; return(&serv); } } return(0); } struct protoent * cgetprotobynumber(proto) register int proto; { register struct valuelist **list = &protolist; register struct valuelist *lp = *list; static struct protoent prot; for (; lp != NULL; lp = lp->next) if (lp->port == proto) { if (lp != *list) { lp->prev->next = lp->next; if (lp->next) lp->next->prev = lp->prev; (*list)->prev = lp; lp->next = *list; *list = lp; } prot.p_name = lp->name; prot.p_proto = lp->port; return(&prot); } return(0); } char * protocolname(num) int num; { static char number[8]; struct protoent *pp; pp = cgetprotobynumber(num); if(pp == 0) { (void) sprintf(number, "%d", num); return(number); } return(pp->p_name); } char * servicename(port, proto) u_short port; char *proto; { static char number[8]; struct servent *ss; ss = cgetservbyport(htons(port), proto); if(ss == 0) { (void) sprintf(number, "%d", port); return(number); } return(ss->s_name); } void gettime(ttp) struct timeval *ttp; { if (gettimeofday(ttp, (struct timezone *)0) < 0) syslog(LOG_ERR, "gettimeofday failed: %m"); return; } #if !defined(BSD) int getdtablesize() { #if defined(_POSIX_SOURCE) int j; if ((j = (int) sysconf(_SC_OPEN_MAX)) < 0) return(FD_SETSIZE); return(j); #else return(FD_SETSIZE); #endif /* POSIX */ } #endif /* BSD */ int my_close(fd) int fd; { int s = close(fd); if (s < 0) { syslog(LOG_ERR, "close(%d) failed: %m", fd); #ifdef DEBUG if (debug >= 3) fprintf(ddt, "close(%d) failed: %s\n", fd, strerror(errno)); #endif } else { #ifdef DEBUG if (debug >= 3) fprintf(ddt, "close(%d) succeeded\n", fd); #endif } return s; } int my_fclose(fp) FILE *fp; { int fd = fileno(fp), s = fclose(fp); if (s < 0) { syslog(LOG_ERR, "fclose(%d) failed: %m", fd); #ifdef DEBUG if (debug >= 3) fprintf(ddt, "fclose(%d) failed: %s\n", fd, strerror(errno)); #endif } else { #ifdef DEBUG if (debug >= 3) fprintf(ddt, "fclose(%d) succeeded\n", fd); #endif } return s; } /* * Make a copy of a string and return a pointer to it. */ char * savestr(str) char *str; { char *cp; cp = malloc(strlen(str) + 1); if (cp == NULL) { syslog(LOG_ERR, "savestr: %m"); exit(1); } (void) strcpy(cp, str); return (cp); } int writemsg(rfd, msg, msglen) int rfd; u_char *msg; int msglen; { struct iovec iov[2]; u_short len = htons((u_short)msglen); iov[0].iov_base = (caddr_t)&len; iov[0].iov_len = sizeof(len); iov[1].iov_base = (caddr_t)msg; iov[1].iov_len = msglen; if (writev(rfd, iov, 2) != sizeof(len) + msglen) { #ifdef DEBUG if (debug) fprintf(ddt,"write failed %d\n", errno); #endif return (-1); } return (0); }