X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=interface.c;h=b63e1121c75d8794fb578bd6368f123ab2e98d02;hb=53293ee30678d3db753e51820cc554c0b2b1bd97;hp=a70e6104cae39c7fc99dfedd9215b27cd48ecfc7;hpb=8da5e6cadb5e9e822ad707109cbfbdf5f0795e8e;p=~andy%2Ffetchmail diff --git a/interface.c b/interface.c index a70e6104..b63e1121 100644 --- a/interface.c +++ b/interface.c @@ -11,12 +11,17 @@ * * For license terms, see the file COPYING in this directory. */ + +#include "fetchmail.h" +#ifdef CAN_MONITOR + #include #include -#if (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) +#if defined(linux) +#include +#endif -#include "config.h" #include #include #if defined(STDC_HEADERS) @@ -44,8 +49,6 @@ #include #endif #endif -#include "config.h" -#include "fetchmail.h" #include "socket.h" #include "i18n.h" #include "tunable.h" @@ -60,8 +63,6 @@ struct interface_pair_s { struct in_addr interface_mask; } *interface_pair; -static char *netdevfmt; - /* * Count of packets to see on an interface before monitor considers it up. * Needed because when pppd shuts down the link, the packet counts go up @@ -70,27 +71,29 @@ static char *netdevfmt; */ #define MONITOR_SLOP 5 -#if defined(linux) +#ifdef linux +#define have_interface_init + +static const char *netdevfmt; void interface_init(void) -/* figure out which /proc/dev/net format to use */ +/* figure out which /proc/net/dev format to use */ { - FILE *fp = popen("uname -r", "r"); /* still wins if /proc is out */ + struct utsname utsname; - /* pre-linux-2.2 format -- transmit packet count in 8th field */ - netdevfmt = "%d %d %*d %*d %*d %d %*d %d %*d %*d %*d %*d %d"; + /* Linux 2.2 -- transmit packet count in 10th field */ + netdevfmt = "%d %d %*d %*d %*d %d %*d %*d %*d %d %*d %*d %d"; - if (!fp) - return; + if (uname(&utsname) < 0) + return; else { int major, minor; - if (fscanf(fp, "%d.%d.%*d", &major, &minor) >= 2 - && major >= 2 && minor >= 2) - /* Linux 2.2 -- transmit packet count in 10th field */ - netdevfmt = "%d %d %*d %*d %*d %d %*d %*d %*d %d %*d %*d %d"; - pclose(fp); + if (sscanf(utsname.release, "%d.%d.%*d", &major, &minor) >= 2 + && (major < 2 || (major == 2 && minor < 2))) + /* pre-linux-2.2 format -- transmit packet count in 8th field */ + netdevfmt = "%d %d %*d %*d %*d %d %*d %d %*d %*d %*d %*d %d"; } } @@ -170,13 +173,13 @@ static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo) result = FALSE; else { - char *sp = strchr(ifname, '/'); - + char *tmp = xstrdup(ifname); + char *sp = strchr(tmp, '/'); + /* hide slash and trailing info from ifname */ if (sp) *sp = '\0'; - result = _get_ifinfoGT_(socket_fd, stats_file, ifname, ifinfo); - if (sp) - *sp = '/'; + result = _get_ifinfoGT_(socket_fd, stats_file, tmp, ifinfo); + free(tmp); } if (socket_fd >= 0) SockClose(socket_fd); @@ -224,9 +227,9 @@ openkvm(void) static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo) { - char tname[16]; + char tname[16]; char iname[16]; - struct ifnet ifnet; + struct ifnet ifnet; unsigned long ifnet_addr = ifnet_savedaddr; #if __FreeBSD_version >= 300001 struct ifnethead ifnethead; @@ -241,7 +244,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) if (if_egid) setegid(if_egid); - for (i = 0; ifname[i] && ifname[i] != '/'; i++) + for (i = 0; ifname[i] && ifname[i] != '/' && i < sizeof(iname) - 1; i++) iname[i] = ifname[i]; iname[i] = '\0'; @@ -268,12 +271,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) { kvm_read(kvmfd, ifnet_addr, &ifnet, sizeof(ifnet)); kvm_read(kvmfd, (unsigned long) ifnet.if_name, tname, sizeof tname); -#ifdef HAVE_SNPRINTF - snprintf(tname, sizeof tname, -#else - sprintf(tname, -#endif - "%s%d", tname, ifnet.if_unit); + snprintf(tname + strlen(tname), sizeof(tname) - strlen(tname), "%d", ifnet.if_unit); if (!strcmp(tname, iname)) { @@ -386,7 +384,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) char iname[16]; int mib[6]; - memset(ifinfo, 0, sizeof(ifinfo)); + memset(ifinfo, 0, sizeof(*ifinfo)); /* trim interface name */ @@ -420,7 +418,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) GT_("get_ifinfo: sysctl (iflist estimate) failed")); exit(1); } - if ((buf = malloc(needed)) == NULL) + if ((buf = (char *)malloc(needed)) == NULL) { report(stderr, GT_("get_ifinfo: malloc failed")); @@ -516,7 +514,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) } sin = (struct sockaddr_in *)info.rti_info[RTAX_NETMASK]; - if (!sin) + if (sin) { ifinfo->netmask = sin->sin_addr; } @@ -526,7 +524,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo) * of non point-to-point link */ sin = (struct sockaddr_in *)info.rti_info[RTAX_BRD]; - if (!sin) + if (sin) { ifinfo->dstaddr = sin->sin_addr; } @@ -547,8 +545,7 @@ get_ifinfo_end: #endif /* __FREEBSD_USE_SYSCTL_GET_IFFINFO */ -#endif /* defined __FreeBSD__ */ - +#endif #ifndef HAVE_INET_ATON /* @@ -582,6 +579,7 @@ void interface_parse(char *buf, struct hostdata *hp) /* parse 'interface' specification */ { char *cp1, *cp2; + char mask1[] = "255.255.255.255"; hp->interface = xstrdup(buf); @@ -596,7 +594,7 @@ void interface_parse(char *buf, struct hostdata *hp) /* find and isolate just the netmask */ if (!(cp2 = strchr(cp1, '/'))) - cp2 = "255.255.255.255"; + cp2 = mask1; else *cp2++ = '\000'; @@ -736,4 +734,8 @@ int interface_approve(struct hostdata *hp, flag domonitor) return(TRUE); } -#endif /* (defined(linux) && !defined(INET6_ENABLE)) || defined(__FreeBSD__) */ +#endif /* CAN_MONITOR */ + +#ifndef have_interface_init +void interface_init(void) {} +#endif