On Fri, Apr 13, 2007 at 11:07:58AM +0200, Dejan Muhamedagic wrote:
> On Fri, Apr 13, 2007 at 04:02:37PM +0900, Simon Horman wrote:
> > If for some reason the file being scanned is malformed, or
> > overflows one of the feilds for some reason, scanf will neither
> > return EOF nor fill in all of its parameters correctly. In the
> > case that I observed this resulted in an endless loop.
> > 
> > This simple fix just bails out in this case.
> > Perhaps an error message is in order?
> 
> yes, /proc might change. perhaps sth like:
> 
>     for( ;; ) {
>         c=fscanf(...);
>         if( c == EOF )
>             break;
>         else if( c != 13 )
>     }
> 
> besides, having such a large fscanf in a while test looks ugly.

I agree, though I'm not sure if the version below improves
the code's beuaty in any way.

-- 
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/


Subject: [IPv6addr] Merge duplicated code from find_if() and get_if() into 
scan_if()

I notice that find_if() and get_if() share a non-trivial amount of code.
The only difference between these two functions is that the latter
constructs and uses a mask, whereas the former only looks for an exact
match. By creating a new function scan_if(), with a switch telling
it weather or not to construct a mask based on the prefix - the default
mask is all 1s, or in otherwords an exact match - the code
duplication is removed.

Index: heartbeat-ipv6addr/resources/OCF/IPv6addr.c
===================================================================
--- heartbeat-ipv6addr.orig/resources/OCF/IPv6addr.c    2007-04-13 
15:47:38.000000000 +0900
+++ heartbeat-ipv6addr/resources/OCF/IPv6addr.c 2007-04-13 15:47:41.000000000 
+0900
@@ -158,6 +158,8 @@
 int create_pid_directory(const char *pid_file);
 static void byebye(int nsig);
 
+static char* scan_if(struct in6_addr* addr_target, int* plen_target,
+                    int use_mask);
 static char* find_if(struct in6_addr* addr_target, int* plen_target);
 static char* get_if(struct in6_addr* addr_target, int* plen_target);
 static int assign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name);
@@ -425,9 +427,9 @@
        return status;
 }
 
-/* find a proper network interface to assign the address */
+/* find the network interface associated with an address */
 char*
-find_if(struct in6_addr* addr_target, int* plen_target)
+scan_if(struct in6_addr* addr_target, int* plen_target, int use_mask)
 {
        FILE *f;
        char addr6[40];
@@ -477,7 +479,7 @@
 
                /* Make the mask based on prefix length */
                memset(mask.s6_addr, 0xff, 16);
-               if (plen < 128) {
+               if (use_mask && plen < 128) {
                        n = plen / 8;
                        memset(mask.s6_addr + n + 1, 0, 15 - n);
                        s = 8 - plen % 8;
@@ -503,57 +505,17 @@
        fclose(f);
        return NULL;
 }
+/* find a proper network interface to assign the address */
+char*
+find_if(struct in6_addr* addr_target, int* plen_target)
+{
+       return scan_if(addr_target, plen_target, 1);
+}
 /* get the device name and the plen_target of a special address */
 char*
 get_if(struct in6_addr* addr_target, int* plen_target)
 {
-       FILE *f;
-       char addr6[40];
-       static char devname[20]="";
-       struct in6_addr addr;
-       unsigned int plen, scope, dad_status, if_idx;
-       char addr6p[8][5];
-
-       /* open /proc/net/if_inet6 file */
-       if ((f = fopen(IF_INET6, "r")) == NULL) {
-               return NULL;
-       }
-       /* loop for each entry */
-       while ( fscanf(f,"%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
-               addr6p[0], addr6p[1], addr6p[2], addr6p[3],
-               addr6p[4], addr6p[5], addr6p[6], addr6p[7],
-               &if_idx, &plen, &scope, &dad_status, devname) != EOF) {
-
-               sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
-                       addr6p[0], addr6p[1], addr6p[2], addr6p[3],
-                       addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
-
-               /* Only Global address entry would be considered.
-                * maybe change
-                */
-               if (0 != scope) {
-                       continue;
-               }
-
-               /* "if" specified prefix, only same prefix entry
-                * would be considered.
-                */
-               if (*plen_target!=0 && plen != *plen_target) {
-                       continue;
-               }
-               *plen_target = plen;
-
-               /* Convert to sockaddr_in6 */
-               inet_pton(AF_INET6, addr6, &addr);
-
-               /* We found it! */
-               if (0 == memcmp(&addr, addr_target,sizeof(addr))) {
-                       fclose(f);
-                       return devname;
-               }
-       }
-       fclose(f);
-       return NULL;
+       return scan_if(addr_target, plen_target, 0);
 }
 int
 assign_addr6(struct in6_addr* addr6, int prefix_len, char* if_name)

_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to