[RFC] per-user ~/.hosts file

Raphaël Droz raphael.droz+floss@gmail.com
Fri Mar 11 13:25:00 GMT 2011


Hello,

I started working on a nss library aimed to resolve hostnames according to
a user "hosts" file (in $HOME/.hosts) [1]

Of course, one has to be root to change /etc/nsswitch.conf in order to
use a ~/.hosts file so the real use is limited
(the reason why such code never landed on the ML before today :p ?)

Anyway it may be useful for completion, to easily give aliases to
friends during ad-hoc lan-parties or when rsync'ing its home between
several machines (while keeping host aliases) and... it may be seen as a
didactic step in setting-up per-user dns :)


In this attempt to reuse the /etc/hosts parser, I ended up with a
copy of some files from glibc/nss/ and a patch (attached) [2]

Other than that, there is just a map-file and two functions which just
call glibc ones.

What I would really like now are advises on how I may have played nicer
with the glibc. I was a bit disappointed when I realized I was not able
to really use shared libraries.

Why glibc #defines DATAFILE, is it for performance reasons only ?
simplicity ? Would it be an enhancement to make this "files-XXX"
nss-databases related functions more reusable ?


Thank you in advance for reviews and suggestions.


Raphaël



[1] http://gitorious.org/nss-dothosts/nss-hostslocal/trees/master
As stated in the README I took the liberty to use the "template"
initially provided on https://github.com/apetresc/nss-hostslocal

[2] generated from git diff 63d53..HEAD glibc/*.*
The files come from glibc 2.11.2
-------------- next part --------------
diff --git a/glibc/files-XXX.c b/glibc/files-XXX.c
index 852b58a..7e1e95d 100644
--- a/glibc/files-XXX.c
+++ b/glibc/files-XXX.c
@@ -60,7 +60,7 @@
 #endif
 
 /* Locks the static variables in this file.  */
-__libc_lock_define_initialized (static, lock)
+__libc_lock_define_initialized (static, *lock)
 

 /* Maintenance of the shared stream open on the database file.  */
 
@@ -77,7 +77,9 @@ internal_setent (int stayopen)
 
   if (stream == NULL)
     {
-      stream = fopen (DATAFILE, "re");
+      char datafile[56];
+      int len = snprintf( datafile, 56, "%s/.hosts", getenv("HOME"));
+      stream = fopen (datafile, "re");
 
       if (stream == NULL)
 	status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
@@ -204,8 +206,8 @@ internal_getent (struct STRUCTURE *result,
     {
       /* Terminate the line so that we can test for overflow.  */
       ((unsigned char *) data->linebuffer)[linebuflen - 1] = '\xff';
+      p = fgets (data->linebuffer, linebuflen, stream);
 
-      p = fgets_unlocked (data->linebuffer, linebuflen, stream);
       if (p == NULL)
 	{
 	  /* End of file or read error.  */
@@ -322,7 +324,6 @@ _nss_files_get##name##_r (proto,					      \
 {									      \
   enum nss_status status;						      \
 									      \
-  __libc_lock_lock (lock);						      \
 									      \
   /* Reset file pointer to beginning or open file.  */			      \
   status = internal_setent (keep_stream);				      \
@@ -341,7 +342,6 @@ _nss_files_get##name##_r (proto,					      \
 	internal_endent ();						      \
     }									      \
 									      \
-  __libc_lock_unlock (lock);						      \
 									      \
   return status;							      \
 }
diff --git a/glibc/files-hosts.c b/glibc/files-hosts.c
index e5f5b48..0c9e12d 100644
--- a/glibc/files-hosts.c
+++ b/glibc/files-hosts.c
@@ -26,8 +26,8 @@
 
 
 /* Get implementation for some internal functions.  */
-#include "../resolv/mapv4v6addr.h"
-#include "../resolv/res_hconf.h"
+#include "mapv4v6addr.h"
+#include "res_hconf.h"
 
 
 #define ENTNAME		hostent
@@ -110,7 +110,6 @@ _nss_files_get##name##_r (proto,					      \
   buffer += pad;							      \
   buflen = buflen > pad ? buflen - pad : 0;				      \
 									      \
-  __libc_lock_lock (lock);						      \
 									      \
   /* Reset file pointer to beginning or open file.  */			      \
   enum nss_status status = internal_setent (keep_stream);		      \
@@ -277,7 +276,6 @@ _nss_files_get##name##_r (proto,					      \
 	internal_endent ();						      \
     }									      \
 									      \
-  __libc_lock_unlock (lock);						      \
 									      \
   return status;							      \
 }
diff --git a/glibc/nsswitch.h b/glibc/nsswitch.h
index b80edef..a05dfca 100644
--- a/glibc/nsswitch.h
+++ b/glibc/nsswitch.h
@@ -29,6 +29,8 @@
 #include <search.h>
 #include <dlfcn.h>
 
+#define attribute_hidden
+
 /* Actions performed after lookup finished.  */
 typedef enum
 {
@@ -105,7 +107,7 @@ typedef struct name_database
 extern int __nss_database_lookup (const char *database,
 				  const char *alternative_name,
 				  const char *defconfig, service_user **ni);
-libc_hidden_proto (__nss_database_lookup)
+//libc_hidden_proto (__nss_database_lookup)
 
 /* Put first function with name FCT_NAME for SERVICE in FCTP.  The
    position is remembered in NI.  The function returns a value < 0 if
@@ -129,14 +131,14 @@ extern int __nss_lookup (service_user **ni, const char *fct_name,
 extern int __nss_next2 (service_user **ni, const char *fct_name,
 			const char *fct2_name, void **fctp, int status,
 			int all_values) attribute_hidden;
-libc_hidden_proto (__nss_next2)
+//libc_hidden_proto (__nss_next2)
 extern int __nss_next (service_user **ni, const char *fct_name, void **fctp,
 		       int status, int all_values);
 
 /* Search for the service described in NI for a function named FCT_NAME
    and return a pointer to this function if successful.  */
 extern void *__nss_lookup_function (service_user *ni, const char *fct_name);
-libc_hidden_proto (__nss_lookup_function)
+//libc_hidden_proto (__nss_lookup_function)
 
 
 /* Called by NSCD to disable recursive calls.  */
@@ -180,6 +182,6 @@ extern int __nss_hostname_digits_dots (const char *name,
 				       struct hostent **result,
 				       enum nss_status *status, int af,
 				       int *h_errnop);
-libc_hidden_proto (__nss_hostname_digits_dots)
+//libc_hidden_proto (__nss_hostname_digits_dots)
 
 #endif	/* nsswitch.h */


More information about the Libc-help mailing list