See ChangeLog: Wed Mar 17 13:09:03 CET 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Wed, 17 Mar 1999 12:12:58 +0000 (12:12 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 17 Mar 1999 12:12:58 +0000 (12:12 +0000)
acinclude.m4
cipher/ChangeLog
cipher/rndegd.c
configure.in

index 2349da6..11ba6fd 100644 (file)
@@ -343,4 +343,256 @@ define(GNUPG_CHECK_MLOCK,
   ])
 
 
+################################################################
+
+# GNUPG_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(GNUPG_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -B"
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+        ac_cv_path_NM="$ac_dir/nm -p"
+      else
+        ac_cv_path_NM="$ac_dir/nm"
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# GNUPG_SYS_NM_PARSE - Check for command ro grab the raw symbol name followed
+# by C symbol name from nm.
+AC_DEFUN(GNUPG_SYS_NM_PARSE,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([GNUPG_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix.  What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  ac_symcode='[BCDTU]'
+  ;;
+sunos* | cygwin32* | mingw32*)
+  ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
+  ac_symxfrm='_\1 \1'
+  ;;
+irix*)
+  # Cannot use undefined symbols on IRIX because inlined functions mess us up.
+  ac_symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  ac_symcode='[BDTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  ac_symcode='[ABCDGISTUW]'
+fi
+
+case "$host_os" in
+cygwin32* | mingw32*)
+  # We do not want undefined symbols on cygwin32.  The user must
+  # arrange to define them via -l arguments.
+  ac_symcode='[ABCDGISTW]'
+  ;;
+esac
+changequote([,])dnl
+
+# Write the raw and C identifiers.
+ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* $ac_symcode $ac_sympat$/$ac_symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+ac_pipe_works=no
+cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+  # Now try to grab the symbols.
+  ac_nlist=conftest.nm
+  if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+    # Try sorting and uniquifying the output.
+    if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+      mv -f "$ac_nlist"T "$ac_nlist"
+      ac_wcout=`wc "$ac_nlist" 2>/dev/null`
+changequote(,)dnl
+      ac_count=`echo "X$ac_wcout" | sed -e 's,^X,,' -e 's/^[    ]*\([0-9][0-9]*\).*$/\1/'`
+changequote([,])dnl
+      (test "$ac_count" -ge 0) 2>/dev/null || ac_count=-1
+    else
+      rm -f "$ac_nlist"T
+      ac_count=-1
+    fi
+
+    # Make sure that we snagged all the symbols we need.
+    if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+      if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+        cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+        # Now generate the symbol file.
+        sed 's/^.* \(.*\)$/extern char \1;/' < "$ac_nlist" >> conftest.c
+
+        cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $ac_count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+  char *name;
+  __ptr_t address;
+}
+changequote(,)dnl
+dld_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+        sed 's/^\(.*\) \(.*\)$/  {"\1", (__ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+        cat <<\EOF >> conftest.c
+  {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+        # Now try linking the two files.
+        mv conftest.$ac_objext conftestm.$ac_objext
+        ac_save_LIBS="$LIBS"
+        ac_save_CFLAGS="$CFLAGS"
+        LIBS="conftestm.$ac_objext"
+        CFLAGS="$CFLAGS$no_builtin_flag"
+        if AC_TRY_EVAL(ac_link) && test -s conftest; then
+          ac_pipe_works=yes
+        else
+          echo "configure: failed program was:" >&AC_FD_CC
+          cat conftest.c >&AC_FD_CC
+        fi
+        LIBS="$ac_save_LIBS"
+        CFLAGS="$ac_save_CFLAGS"
+      else
+        echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+      fi
+    else
+      echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+    fi
+  else
+    echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+  fi
+else
+  echo "$progname: failed program was:" >&AC_FD_CC
+  cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+
+# Do not use the global_symbol_pipe unless it works.
+test "$ac_pipe_works" = yes || ac_cv_sys_global_symbol_pipe=
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+   ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+# GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32
+AC_DEFUN(GNUPG_SYS_LIBTOOL_CYGWIN32,
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+# GNUPG_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
+#                            with an underscore?
+AC_DEFUN(GNUPG_SYS_SYMBOL_UNDERSCORE,
+[AC_REQUIRE([GNUPG_PROG_NM])dnl
+AC_REQUIRE([GNUPG_SYS_NM_PARSE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+  # Now try to grab the symbols.
+  ac_nlist=conftest.nm
+  if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+    # See whether the symbols have a leading underscore.
+    if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+      ac_cv_sys_symbol_underscore=yes
+    else
+      if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+        :
+      else
+        echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+      fi
+    fi
+  else
+    echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+  fi
+else
+  echo "configure: failed program was:" >&AC_FD_CC
+  cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+  AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1,
+  [define if compiled symbols have a leading underscore])
+fi
+])
+
+
 dnl *-*wedit:notab*-*  Please keep this as the last line.
index a9a720f..3ac7d31 100644 (file)
@@ -1,3 +1,8 @@
+Wed Mar 17 13:09:03 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * rndegd.c (do_read): New.
+       (gather_random): Changed the implementation.
+
 Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
        * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
index 6cdc4dd..0777ff8 100644 (file)
@@ -34,6 +34,7 @@
 #include "util.h"
 #include "ttyio.h"
 #include "dynload.h"
+#include "cipher.h"
 
 #ifdef IS_MODULE
   #define _(a) (a)
@@ -64,18 +65,47 @@ do_write( int fd, void *buf, size_t nbytes )
     return 0;
 }
 
+static int
+do_read( int fd, void *buf, size_t nbytes )
+{
+    int n, nread = 0;
 
+    do {
+       do {
+           n = read(fd, (char*)buf + nread, nbytes );
+       } while( n == -1 && errno == EINTR );
+       if( n == -1 )
+           return -1;
+       nread += n;
+    } while( nread < nbytes );
+    return nbytes;
+}
+
+
+/* fixme: level 1 is not yet handled */
 static int
 gather_random( void (*add)(const void*, size_t, int), int requester,
                                          size_t length, int level )
 {
     static int fd = -1;
     int n;
-    int warn=0;
     byte buffer[256+2];
+    int nbytes;
+    int do_restart = 0;
+
+    if( !length )
+       return 0;
+
 
+  restart:
+    if( do_restart ) {
+       if( fd != -1 ) {
+           close( fd );
+           fd = -1;
+       }
+    }
     if( fd == -1 ) {
-       const char *name = "/tmp/entropy";
+       char *name = make_filename( g10_opt_homedir, "entropy", NULL );
        struct sockaddr_un addr;
        int addr_len;
 
@@ -92,73 +122,63 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
        if( connect( fd, (struct sockaddr*)&addr, addr_len) == -1 )
            g10_log_fatal("can't connect to `%s': %s\n",
                                                    name, strerror(errno) );
+       m_free(name);
+    }
+    do_restart = 0;
+
+    nbytes = length < 255? length : 255;
+    /* first time we do it with a non blocking request */
+    buffer[0] = 1; /* non blocking */
+    buffer[1] = nbytes;
+    if( do_write( fd, buffer, 2 ) == -1 )
+       g10_log_fatal("can't write to the EGD: %s\n", strerror(errno) );
+    n = do_read( fd, buffer, 1 );
+    if( n == -1 ) {
+       g10_log_error("read error on EGD: %s\n", strerror(errno));
+       do_restart = 1;
+       goto restart;
+    }
+    if( !n ) {
+       g10_log_error("bad EGD reply: too short\n");
+       do_restart = 1;
+       goto restart;
+    }
+    if( n > 1 ) {
+       n--;
+       (*add)( buffer+1, n, requester );
+       length -= n;
     }
 
-
+    if( length ) {
+      #ifdef IS_MODULE
+       fprintf( stderr,
+      #else
+       tty_printf(
+      #endif
+        _("Please wait, entropy is being gathered. Do some work if it would\n"
+          "keep you from getting bored, because it will improve the quality\n"
+          "of the entropy.\n") );
+    }
     while( length ) {
-       fd_set rfds;
-       struct timeval tv;
-       int rc;
-       int nbytes;
-       int cmd;
-
        nbytes = length < 255? length : 255;
-       /* send request */
-       cmd = level >= 2 ? 2 : 1;
-       buffer[0] = cmd;
+
+       buffer[0] = 2; /* blocking */
        buffer[1] = nbytes;
        if( do_write( fd, buffer, 2 ) == -1 )
            g10_log_fatal("can't write to the EGD: %s\n", strerror(errno) );
-       /* wait on reply */
-       FD_ZERO(&rfds);
-       FD_SET(fd, &rfds);
-       tv.tv_sec = 3;
-       tv.tv_usec = 0;
-       if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) {
-           if( !warn )
-             #ifdef IS_MODULE
-               fprintf( stderr,
-             #else
-               tty_printf(
-             #endif
-                           _(
-"\n"
-"Not enough random bytes available.  Please do some other work to give\n"
-"the OS a chance to collect more entropy! (Need %d more bytes)\n"), length );
-           warn = 1;
-           continue;
-       }
-       else if( rc == -1 ) {
-           g10_log_error("select error on EGD: %s\n", strerror(errno));
-           continue;
-       }
-
-       /* collect reply */
-       do {
-           n = read(fd, buffer, nbytes+2 );
-       } while( n == -1 && errno == EINTR );
-       /* process reply */
-       if( n == -1 )
+       n = do_read( fd, buffer, nbytes );
+       if( n == -1 ) {
            g10_log_error("read error on EGD: %s\n", strerror(errno));
-       else if( cmd == 2 && n != nbytes  ) {
-           g10_log_error("bad EGD reply: too short %d/%d\n", nbytes, n );
-       }
-       else if( cmd == 2 ) {
-           (*add)( buffer, n, requester );
-           length -= n;
+           do_restart = 1;
+           goto restart;
        }
-       else if( !n )
-           g10_log_error("bad EGD reply: too short\n");
-       else if( buffer[0] != n-1 )
-           g10_log_error("bad EGD reply: count mismatch %d/%d\n",
-                                                     n-1, buffer[0] );
-       else if( n==1 )
-           g10_log_info("no data from EGD\n");
-       else {
-           n -= 1;
-           (*add)( buffer+1, n, requester );
-           length -= n;
+       if( n != nbytes  ) {
+           g10_log_error("bad EGD reply: too short %d/%d\n", nbytes, n );
+           do_restart = 1;
+           goto restart;
        }
+       (*add)( buffer, n, requester );
+       length -= n;
     }
     memset(buffer, 0, sizeof(buffer) );
 
index 1e71eb7..e4760fb 100644 (file)
@@ -28,11 +28,11 @@ dnl
 dnl  Check for random module options
 dnl
 dnl  Fixme: get the list of available modules from MODULES_IN_CIPHER
-dnl         and check agiants this list
+dnl         and check against this list
 
 AC_MSG_CHECKING([which static random module to use])
 AC_ARG_ENABLE(static-rnd,
-    [  --enable-static-rnd=[egd|unix|linux|nonde]  ],
+    [  --enable-static-rnd=[egd|unix|linux|none]  ],
 [use_static_rnd=$enableval], [use_static_rnd=default] )
 
 if test "$use_static_rnd" = no; then
@@ -169,7 +169,7 @@ case "${target}" in
 esac
 
 AC_SUBST(MPI_OPT_FLAGS)
-AM_SYS_SYMBOL_UNDERSCORE
+GNUPG_SYS_SYMBOL_UNDERSCORE
 GNUPG_CHECK_PIC
 GNUPG_CHECK_RDYNAMIC
 if test "$NO_PIC" = yes; then