[Glibc-bsd-commits] r1723 - trunk/freebsd-utils
Petr Salinger
ps-guest at alioth.debian.org
Tue Nov 14 20:49:23 CET 2006
Author: ps-guest
Date: 2006-11-14 20:49:23 +0100 (Tue, 14 Nov 2006)
New Revision: 1723
Added:
trunk/freebsd-utils/000_ifconfig_broken_glibc.diff
Log:
* workaround for ifconfig against current glibc
code currently disabled
Added: trunk/freebsd-utils/000_ifconfig_broken_glibc.diff
===================================================================
--- trunk/freebsd-utils/000_ifconfig_broken_glibc.diff 2006-11-14 17:49:39 UTC (rev 1722)
+++ trunk/freebsd-utils/000_ifconfig_broken_glibc.diff 2006-11-14 19:49:23 UTC (rev 1723)
@@ -0,0 +1,327 @@
+
+
+ glibc up to and including 2.3.6.ds1-8 have bad condition in if_iterate()
+ unfortunately glibc is currently frozen
+ workaround is to include fixed version directly into ifconfig.c
+
+ please change "#if 0" bellow into "#if 1"
+ and add line "build-tree/src/sbin/ifconfig/ifconfig /sbin"
+ into debian/net-tools.install to enable this workaround.
+
+
+
+diff -ur src.old/sbin/ifconfig/ifconfig.c src/sbin/ifconfig/ifconfig.c
+--- src.old/sbin/ifconfig/ifconfig.c 2006-05-04 16:40:04.000000000 +0200
++++ src/sbin/ifconfig/ifconfig.c 2006-05-04 16:44:05.000000000 +0200
+@@ -1066,3 +1066,311 @@
+ cmd_register(&basic_cmds[i]);
+ #undef N
+ }
++
++
++
++#if 0
++
++/* Copyright (C) 2002 Free Software Foundation, Inc.
++ This file is part of the GNU C Library.
++ Contributed by Bruno Haible <bruno at clisp.org>, 2002.
++
++ The GNU C Library is free software; you can redistribute it and/or
++ modify it under the terms of the GNU Lesser General Public
++ License as published by the Free Software Foundation; either
++ version 2.1 of the License, or (at your option) any later version.
++
++ The GNU C Library is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ Lesser General Public License for more details.
++
++ You should have received a copy of the GNU Lesser General Public
++ License along with the GNU C Library; if not, write to the Free
++ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++ 02111-1307 USA. */
++
++#include <net/if.h>
++#include <sys/sysctl.h>
++#include <sys/socket.h>
++#include <net/route.h>
++#include <net/if_dl.h>
++#include <alloca.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++
++
++typedef int (*if_fn) (void *private, unsigned int index, const char *name);
++
++/* Iterate through all present interfaces.
++ Call FN once for every interface, returning immediately if FN returns
++ a nonzero value. */
++static void
++if_iterate (if_fn fn, void *private)
++{
++ int request[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
++ char *buf;
++ size_t bufsize = 512;
++ char *bufend;
++ char *p;
++
++ /* Call the kernel function sysctl_iflist() in /usr/src/sys/net/rtsock.c. */
++ for (;;)
++ {
++ buf = alloca (bufsize);
++ if (sysctl (request, 6, buf, &bufsize, NULL, 0) >= 0)
++ break;
++ if (errno != ENOMEM)
++ return;
++ bufsize *= 2;
++ }
++
++ bufend = buf + bufsize;
++ for (p = buf; p < bufend; )
++ {
++ struct if_msghdr *msg = (struct if_msghdr *) p;
++
++ if (msg->ifm_version != RTM_VERSION)
++ abort ();
++
++ switch (msg->ifm_type)
++ {
++ case RTM_IFINFO:
++ if (msg->ifm_addrs & RTA_IFP)
++ {
++ unsigned int index;
++ struct sockaddr_dl *sdl;
++ char namebuf[IFNAMSIZ + 1];
++ size_t namelen;
++
++ index = msg->ifm_index;
++ if (index == 0)
++ abort ();
++
++ sdl = (struct sockaddr_dl *) (msg + 1);
++ namelen = sdl->sdl_nlen;
++ /* Avoid overflowing namebuf[]. */
++ if (namelen > IFNAMSIZ)
++ namelen = IFNAMSIZ;
++ memcpy (namebuf, sdl->sdl_data, namelen);
++ namebuf[namelen] = '\0';
++
++ /* Call FN now. */
++ if (fn (private, index, namebuf))
++ return;
++ }
++ break;
++
++ case RTM_NEWADDR:
++ break;
++
++ default:
++ abort ();
++ }
++
++ p += msg->ifm_msglen;
++ }
++}
++
++/* ------------------------------------------------------------------------- */
++
++struct nametoindex_locals
++ {
++ const char *name;
++ unsigned int index;
++ };
++
++static int
++nametoindex_aux (void *private, unsigned int index, const char *name)
++{
++ struct nametoindex_locals *l = (struct nametoindex_locals *) private;
++ if (strcmp (name, l->name) == 0)
++ {
++ l->index = index;
++ return 1;
++ }
++ return 0;
++}
++
++/* Return the index of an interface given by name. */
++unsigned int
++if_nametoindex (const char *ifname)
++{
++ struct nametoindex_locals l;
++
++ l.name = ifname;
++ l.index = 0;
++ if_iterate (nametoindex_aux, &l);
++
++ return l.index;
++}
++
++/* ------------------------------------------------------------------------- */
++
++struct indextoname_locals
++ {
++ unsigned int index;
++ char *name;
++ char *retval;
++ };
++
++static int
++indextoname_aux (void *private, unsigned int index, const char *name)
++{
++ struct indextoname_locals *l = (struct indextoname_locals *) private;
++ if (index == l->index)
++ {
++ strncpy (l->name, name, IF_NAMESIZE);
++ l->retval = l->name;
++ return 1;
++ }
++ errno = ENXIO;
++ return 0;
++}
++
++/* Return the name of an interface given by name. */
++char *
++if_indextoname (unsigned int ifindex, char *ifname)
++{
++ struct indextoname_locals l;
++
++ l.index = ifindex;
++ l.name = ifname;
++ l.retval = NULL;
++ if_iterate (indextoname_aux, &l);
++ return l.retval;
++}
++
++/* ------------------------------------------------------------------------- */
++
++struct nameindex_locals
++ {
++ /* Resizable array of 'struct if_nameindex'. */
++ struct if_nameindex *s_array;
++ size_t s_len;
++ size_t s_allocated;
++ /* Resizable array of char. */
++ char *c_array;
++ size_t c_len;
++ size_t c_allocated;
++ /* Out-of-memory indicator. */
++ int oom;
++ };
++
++static void
++add_s (struct nameindex_locals *l, unsigned int index, char *name)
++{
++ if (l->s_len == l->s_allocated)
++ {
++ size_t new_allocated = 2 * l->s_allocated + 1;
++ struct if_nameindex *new_array =
++ (struct if_nameindex *)
++ realloc (l->s_array, new_allocated * sizeof (struct if_nameindex));
++ if (new_array == NULL)
++ {
++ l->oom = 1;
++ return;
++ }
++ l->s_array = new_array;
++ l->s_allocated = new_allocated;
++ }
++ /* Now l->s_len < l->s_allocated. */
++ l->s_array[l->s_len].if_index = index;
++ l->s_array[l->s_len].if_name = name;
++ l->s_len++;
++}
++
++static __inline size_t
++add_c (struct nameindex_locals *l, const char *name)
++{
++ size_t n = strlen (name) + 1;
++ size_t result_offset;
++ if (l->c_len + n > l->c_allocated)
++ {
++ size_t new_allocated =
++ (l->c_len + n < 2 * l->c_allocated + 1
++ ? l->c_len + n
++ : 2 * l->c_allocated + 1);
++ char *new_array = (char *) realloc (l->c_array, new_allocated);
++ if (new_array == NULL)
++ {
++ l->oom = 1;
++ return 0;
++ }
++ l->c_array = new_array;
++ l->c_allocated = new_allocated;
++ }
++ /* Now l->c_len + n <= l->c_allocated. */
++ result_offset = l->c_len;
++ memcpy (l->c_array + l->c_len, name, n);
++ l->c_len += n;
++ return result_offset;
++}
++
++static int
++nameindex_aux (void *private, unsigned int index, const char *name)
++{
++ struct nameindex_locals *l = (struct nameindex_locals *) private;
++
++ size_t name_offset = add_c (l, name);
++ if (!l->oom)
++ {
++ add_s (l, index, (char *) NULL + name_offset);
++ if (!l->oom)
++ return 0;
++ }
++ return 1;
++}
++
++/* Return an array of 'struct if_nameindex', one for each present
++ interface. */
++struct if_nameindex *
++if_nameindex (void)
++{
++ struct nameindex_locals l;
++
++ l.s_array = NULL; l.s_len = 0; l.s_allocated = 0;
++ l.c_array = NULL; l.c_len = 0; l.c_allocated = 0;
++ l.oom = 0;
++ if_iterate (nameindex_aux, &l);
++ if (!l.oom)
++ {
++ /* Convert all offsets to real pointers. */
++ struct if_nameindex *p;
++ struct if_nameindex *p_end;
++
++ for (p = l.s_array, p_end = p + l.s_len; p < p_end; p++)
++ p->if_name = l.c_array + (p->if_name - (char *) NULL);
++
++ /* Add a terminating entry. */
++ add_s (&l, 0, NULL);
++ }
++ if (l.oom)
++ {
++ free (l.s_array);
++ free (l.c_array);
++ errno = ENOMEM;
++ return NULL;
++ }
++ return l.s_array;
++}
++
++/* ------------------------------------------------------------------------- */
++
++/* Free an array returned by if_nameindex(). */
++void
++if_freenameindex (struct if_nameindex *ifn)
++{
++ if (ifn != NULL)
++ {
++ /* Free c_array. */
++ free (ifn[0].if_name);
++ /* Free s_array. */
++ free (ifn);
++ }
++}
++
++
++#endif
++
More information about the Glibc-bsd-commits
mailing list