* that either displays or sets the characteristics of
* one or more of the system's networking interfaces.
*
- * Version: $Id: interface.c,v 1.22 2004/04/14 17:57:11 andersen Exp $
+ * Version: $Id: interface.c,v 1.25 2004/08/26 21:45:21 andersen Exp $
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* and others. Copyright 1993 MicroWalt Corporation
return sfd;
}
+#ifdef CONFIG_FEATURE_CLEAN_UP
+static void sockets_close(void)
+{
+ struct aftype **aft;
+ for (aft = aftypes; *aft != NULL; aft++) {
+ struct aftype *af = *aft;
+ if( af->fd != -1 ) {
+ close(af->fd);
+ af->fd = -1;
+ }
+ }
+}
+#endif
+
/* like strcmp(), but knows about numbers */
-static int nstrcmp(const char *astr, const char *b)
+static int nstrcmp(const char *a, const char *b)
{
- const char *a = astr;
+ const char *a_ptr = a;
+ const char *b_ptr = b;
while (*a == *b) {
- if (*a == '\0')
+ if (*a == '\0') {
return 0;
+ }
+ if (!isdigit(*a) && isdigit(*(a+1))) {
+ a_ptr = a+1;
+ b_ptr = b+1;
+ }
a++;
b++;
}
- if (isdigit(*a)) {
- if (!isdigit(*b))
- return -1;
- while (a > astr) {
- a--;
- if (!isdigit(*a)) {
- a++;
- break;
- }
- if (!isdigit(*b))
- return -1;
- b--;
- }
- return atoi(a) > atoi(b) ? 1 : -1;
+
+ if (isdigit(*a) && isdigit(*b)) {
+ return atoi(a_ptr) > atoi(b_ptr) ? 1 : -1;
}
return *a - *b;
}
static char *get_name(char *name, char *p)
{
- while (isspace(*p))
- p++;
- while (*p) {
- if (isspace(*p))
- break;
- if (*p == ':') { /* could be an alias */
- char *dot = p, *dotname = name;
-
- *name++ = *p++;
- while (isdigit(*p))
- *name++ = *p++;
- if (*p != ':') { /* it wasn't, backup */
- p = dot;
- name = dotname;
- }
- if (*p == '\0')
- return NULL;
- p++;
- break;
+ /* Extract <name>[:<alias>] from nul-terminated p where p matches
+ <name>[:<alias>]: after leading whitespace.
+ If match is not made, set name empty and return unchanged p */
+ int namestart=0, nameend=0, aliasend;
+ while (isspace(p[namestart]))
+ namestart++;
+ nameend=namestart;
+ while (p[nameend] && p[nameend]!=':' && !isspace(p[nameend]))
+ nameend++;
+ if (p[nameend]==':') {
+ aliasend=nameend+1;
+ while (p[aliasend] && isdigit(p[aliasend]))
+ aliasend++;
+ if (p[aliasend]==':') {
+ nameend=aliasend;
}
- *name++ = *p++;
+ if ((nameend-namestart)<IFNAMSIZ) {
+ memcpy(name,&p[namestart],nameend-namestart);
+ name[nameend-namestart]='\0';
+ p=&p[nameend];
+ } else {
+ /* Interface name too large */
+ name[0]='\0';
+ }
+ } else {
+ /* first ':' not found - return empty */
+ name[0]='\0';
}
- *name++ = '\0';
- return p;
+ return p + 1;
}
/* If scanf supports size qualifiers for %n conversions, then we can
}
#endif
+#ifdef SIOCGIFMAP
strcpy(ifr.ifr_name, ifname);
- if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
- memset(&ife->map, 0, sizeof(struct ifmap));
+ if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0)
+ ife->map = ifr.ifr_map;
else
- memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap));
-
- strcpy(ifr.ifr_name, ifname);
- if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
+#endif
memset(&ife->map, 0, sizeof(struct ifmap));
- else
- ife->map = ifr.ifr_map;
#ifdef HAVE_TXQUEUELEN
strcpy(ifr.ifr_name, ifname);
#if HAVE_HWETHER
#include <net/if_arp.h>
-#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
+#if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION)
#include <net/ethernet.h>
#else
#include <linux/if_ether.h>
/* Do we have to show the current setup? */
status = if_print(ifname);
- close(skfd);
+#ifdef CONFIG_FEATURE_CLEAN_UP
+ sockets_close();
+#endif
exit(status < 0);
}