[v2] batctl: avoid parsing bat-hosts multiple times

Message ID 4B8FBAAA.7060406@tiwoc.de (mailing list archive)
State Accepted, archived
Headers

Commit Message

Daniel Seither March 4, 2010, 1:50 p.m. UTC
  Currently, running batctl from the home directory leads to warnings
("Warning - mac already known") if ~/bat-hosts exists. This is caused by
batctl parsing both "~/bat-hosts" and "bat-hosts" which happen to be the
same file when the working directory is ~

This patch adds duplicate file name detection to bat_hosts_init() to
avoid these warnings.

Signed-off-by: Daniel Seither <post@tiwoc.de>
---
  

Comments

Marek Lindner March 4, 2010, 3:09 p.m. UTC | #1
On Thursday 04 March 2010 21:50:34 Daniel Seither wrote:
> Currently, running batctl from the home directory leads to warnings
> ("Warning - mac already known") if ~/bat-hosts exists. This is caused by
> batctl parsing both "~/bat-hosts" and "bat-hosts" which happen to be the
> same file when the working directory is ~
> 
> This patch adds duplicate file name detection to bat_hosts_init() to
> avoid these warnings.

Applied in rev 1582.
I added a small check add the end of the patch to make sure that we don't 
attempt to free a NULL pointer.

Keep up the good work!  :-)

Cheers,
Marek
  
Marek Lindner March 4, 2010, 3:35 p.m. UTC | #2
On Thursday 04 March 2010 23:09:05 Marek Lindner wrote:
> I added a small check add the end of the patch to make sure that we don't
> attempt to free a NULL pointer.

Sven just informed me that this is not necessary - free() also accepts a NULL 
pointer. Shockingly I was not aware of that. It seems I'm not the only one 
since even manpages do it wrong (e.g. man 3 getline).  :-)

Cheers,
Marek
  

Patch

Index: batctl/bat-hosts.c
===================================================================
--- batctl/bat-hosts.c	(revision 1579)
+++ batctl/bat-hosts.c	(working copy)
@@ -23,6 +23,7 @@ 

 #include <stdio.h>
 #include <stdint.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
@@ -144,9 +145,11 @@ 

 void bat_hosts_init(void)
 {
-	unsigned int i;
+	unsigned int i, j, parse;
 	char confdir[CONF_DIR_LEN];
 	char *homedir;
+	size_t locations = sizeof(bat_hosts_path) / sizeof(char *);
+	char *normalized[locations];

 	host_hash = hash_new(64, compare_mac, choose_mac);

@@ -157,7 +160,7 @@ 

 	homedir = getenv("HOME");

-	for (i = 0; i < sizeof(bat_hosts_path) / sizeof(char *); i++) {
+	for (i = 0; i < locations; i++) {
 		strcpy(confdir, "");

 		if (strlen(bat_hosts_path[i]) >= 2
@@ -169,9 +172,29 @@ 
 			strncpy(confdir, bat_hosts_path[i], CONF_DIR_LEN);
 			confdir[CONF_DIR_LEN - 1] = '\0';
 		}
-
-		parse_hosts_file(&host_hash, confdir);
+		
+		normalized[i] = realpath(confdir, NULL);
+		if (normalized[i] == NULL)
+			continue;
+		
+		/* check for duplicates: don't parse the same file twice */	
+		parse = 1;
+		for (j = 0; j < i; j++) {
+			if (normalized[j] == NULL)
+				continue;
+				
+			if (strncmp(normalized[i], normalized[j], CONF_DIR_LEN) == 0) {
+				parse = 0;
+				break;
+			}
+		}
+	
+		if (parse && (normalized[i] != NULL))
+			parse_hosts_file(&host_hash, normalized[i]);
 	}
+	
+	for (i = 0; i < locations; i++)
+		free(normalized[i]);
 }

 struct bat_host *bat_hosts_find_by_name(char *name)