144743Smarkm /*
244743Smarkm  * Misc routines that are used by tcpd and by tcpdchk.
344743Smarkm  *
444743Smarkm  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
556977Sshin  *
656977Sshin  * $FreeBSD$
744743Smarkm  */
844743Smarkm
944743Smarkm#ifndef lint
1044743Smarkmstatic char sccsic[] = "@(#) misc.c 1.2 96/02/11 17:01:29";
1144743Smarkm#endif
1244743Smarkm
1344743Smarkm#include <sys/types.h>
1444743Smarkm#include <sys/param.h>
1544743Smarkm#include <netinet/in.h>
1644743Smarkm#include <arpa/inet.h>
1744743Smarkm#include <stdio.h>
1844743Smarkm#include <string.h>
1944743Smarkm
2044743Smarkm#include "tcpd.h"
2144743Smarkm
2244743Smarkmextern char *fgets();
2344743Smarkm
2444743Smarkm#ifndef	INADDR_NONE
2544743Smarkm#define	INADDR_NONE	(-1)		/* XXX should be 0xffffffff */
2644743Smarkm#endif
2744743Smarkm
2844743Smarkm/* xgets - fgets() with backslash-newline stripping */
2944743Smarkm
3044743Smarkmchar   *xgets(ptr, len, fp)
3144743Smarkmchar   *ptr;
3244743Smarkmint     len;
3344743SmarkmFILE   *fp;
3444743Smarkm{
3544743Smarkm    int     got;
3644743Smarkm    char   *start = ptr;
3744743Smarkm
3844743Smarkm    while (fgets(ptr, len, fp)) {
3944743Smarkm	got = strlen(ptr);
4044743Smarkm	if (got >= 1 && ptr[got - 1] == '\n') {
4144743Smarkm	    tcpd_context.line++;
4244743Smarkm	    if (got >= 2 && ptr[got - 2] == '\\') {
4344743Smarkm		got -= 2;
4444743Smarkm	    } else {
4544743Smarkm		return (start);
4644743Smarkm	    }
4744743Smarkm	}
4844743Smarkm	ptr += got;
4944743Smarkm	len -= got;
5044743Smarkm	ptr[0] = 0;
5144743Smarkm    }
5244743Smarkm    return (ptr > start ? start : 0);
5344743Smarkm}
5444743Smarkm
5544743Smarkm/* split_at - break string at delimiter or return NULL */
5644743Smarkm
5744743Smarkmchar   *split_at(string, delimiter)
5844743Smarkmchar   *string;
5944743Smarkmint     delimiter;
6044743Smarkm{
6144743Smarkm    char   *cp;
6244743Smarkm
6356977Sshin#ifdef INET6
6456977Sshin    int bracket = 0;
6556977Sshin
6656977Sshin    for (cp = string; cp && *cp; cp++) {
6756977Sshin	switch (*cp) {
6856977Sshin	case '[':
6956977Sshin	    bracket++;
7056977Sshin	    break;
7156977Sshin	case ']':
7256977Sshin	    bracket--;
7356977Sshin	    break;
7456977Sshin	default:
7556977Sshin	    if (bracket == 0 && *cp == delimiter) {
7656977Sshin		*cp++ = 0;
7756977Sshin		return cp;
7856977Sshin	    }
7956977Sshin	    break;
8056977Sshin	}
8156977Sshin    }
8256977Sshin    return (NULL);
8356977Sshin#else
8444743Smarkm    if ((cp = strchr(string, delimiter)) != 0)
8544743Smarkm	*cp++ = 0;
8644743Smarkm    return (cp);
8756977Sshin#endif
8844743Smarkm}
8944743Smarkm
9044743Smarkm/* dot_quad_addr - convert dotted quad to internal form */
9144743Smarkm
9244743Smarkmunsigned long dot_quad_addr(str)
9344743Smarkmchar   *str;
9444743Smarkm{
9544743Smarkm    int     in_run = 0;
9644743Smarkm    int     runs = 0;
9744743Smarkm    char   *cp = str;
9844743Smarkm
9944743Smarkm    /* Count the number of runs of non-dot characters. */
10044743Smarkm
10144743Smarkm    while (*cp) {
10244743Smarkm	if (*cp == '.') {
10344743Smarkm	    in_run = 0;
10444743Smarkm	} else if (in_run == 0) {
10544743Smarkm	    in_run = 1;
10644743Smarkm	    runs++;
10744743Smarkm	}
10844743Smarkm	cp++;
10944743Smarkm    }
11044743Smarkm    return (runs == 4 ? inet_addr(str) : INADDR_NONE);
11144743Smarkm}
112