Index: krb5/.cvsignore
diff -c /dev/null krb5/.cvsignore:1.2
*** /dev/null	Sun Mar 16 20:22:05 2003
--- krb5/.cvsignore	Thu Jun  5 10:37:42 1997
***************
*** 0 ****
--- 1,2 ----
+ .comment
+ configure
Index: krb5/README
diff -c /dev/null krb5/README:1.24
*** /dev/null	Sun Mar 16 20:22:05 2003
--- krb5/README	Thu Aug 29 14:18:16 2002
***************
*** 0 ****
--- 1,234 ----
+ Notes on the NRL Kerberos CVS tree:
+ 
+ This is a working copy of the sources I use for Kerberos development.
+ Changes I (and others) make to Kerberos are made available via this
+ CVS tree.
+ 
+ If you're not familiar with CVS, the documentation that comes with
+ the distribution is a good starting point.  The important things you
+ need to know are:
+ 
+ 	cvs checkout - Gets the initial copy of the source tree
+ 	cvs update   - Brings external changes into your local working
+ 		       directory.
+ 	cvs commit   - Puts changes you made in your working directory
+ 		       into the revision control directory.
+ 
+ This distribution is set up as a "development" distribution, which means
+ it differs slightly from the normal distribution from MIT.  For example,
+ there are no configure scripts included in the CVS tree.  This is because
+ they are automatically generated, and it makes no sense to put automatically
+ generated files under revision control.
+ 
+ To build the distribution from the CVS tree, you will need:
+ 
+ - The latest copy of GNU m4.
+ - The latest copy of GNU make.
+ 
+ Steps for building the distribution:
+ 
+ 1) First, you will need to build Autoconf.  Note that you _must_ use the
+    copy of Autoconf that comes with Kerberos - not the standard GNU
+    Autoconf.  This requires GNU m4.  To build Autoconf, do (from the top
+    of the Kerberos source tree):
+ 
+    cd util/autoconf
+    ./configure
+    make
+ 
+ 2) Generate all of the configure scripts and automatically generated
+    header files.
+ 
+    cd <top of source tree>
+    ./util/reconf
+ 
+ 3) Run configure.  I _highly_ recommend that you build Kerberos in an
+    object directory.  This makes CVS management a lot easier and gives
+    you the ability to build for multiple architectures from the same
+    source code tree.  To do this:
+ 
+    mkdir <object-directory>
+    cd <object-directory>
+    <source-directory>/configure <... your configure options ...>
+ 
+ 4) Build the distribution.  This requires GNU make.
+ 
+    cd <object-directory>
+    gmake (or whatever you call GNU make)
+ 
+ 
+ In addition to the standard configure options, this distribution has
+ a number of extra ones:
+ 
+ --with-afs=AFSDIR
+ 
+ 	Enable AFS compatibility.  This will make the application daemons
+ 	create PAGs and run aklog at the appropriate places.  AFSDIR
+ 	is the location of the AFS client libraries.
+ 
+ --with-afs-setpag-always
+ 
+ 	Always create a PAG at login time, even for root.  Only useful
+ 	with the --with-afs option.
+ 
+ --enable-irix-project-init
+ 
+ 	Have login.krb5 call the right functions to set up the array
+ 	session and project id for Irix 6.4 and newer systems.
+ 
+ --without-session-encrypt
+ 
+ 	Disable session encryption in the client programs.  Should only
+ 	be enabled to create exportable binaries.
+ 
+ --with-afs-name-change
+ 
+ 	Enable extra code to support an AFS cell with a different name
+ 	than your Kerberos realm.
+ 
+ --with-securid-preauth=DIR
+ 
+ 	Enable code to support SecurID cards as a hardware preauthentication
+ 	mechanism.  DIR is the directory containing sdiclient.a and
+ 	the SecurID client include files.  Note: this is very buggy,
+ 	mostly due to the _extremely_ poor interface to the SecurID
+ 	cards.  Not recommended.
+ 
+ --without-strptime
+ 
+ 	Never use the native strptime() library function, but always
+ 	use the one included in the Kerberos library.  Only useful
+ 	for Irix 6.x systems, which have a buggy strptime().
+ 
+ --enable-app-proxy
+ 
+ 	Enable code to support application proxy gateways by allowing
+ 	the addition of extra IP addresses into the ticket.  Experimental.
+ 
+ --enable-btree-db
+ 
+ 	Use a btree database for the KDC instead of a hash database.
+ 	Highly recommended.
+ 
+ --with-cracklib=<full path to cracklib source tree>
+ 
+ 	Use cracklib instead of a flat dictionary file for password checking.
+ 	See lib/kadm5/srv/cracklib/README for details.
+ 
+ --with-hp-exemplar-krshd-hack
+ 
+ 	This hack allows krshd to run consistantly on the HP Exemplar.
+ 	Under HP-UX 10.01 I was seeing a bug (I believe in HP's networking
+ 	code) that caused krshd to fail every other time. This hack allows
+ 	krshd to work, at the cost of being able to do encryption and
+ 	handle signals via the second port.
+ 
+ --with-multihomed-fixes
+ 
+ 	This enables code in some application servers (klogind, kshd, and
+ 	ftpd) that help Kerberos to work in environments with multi-homed
+ 	hosts. In the case of klogind and kshd it caused them not to check
+ 	the IP address in a received ticket against the IP address the
+ 	ticket came from. For ftpd it causes ftpd to use the name of
+ 	interface the connection was received on instead of the local
+ 	hostname to build the name of the service principal to use.
+ 
+ --with-login-conf=<full path to conf file>
+ 
+ 	This enables code in login to parse and use options in a login
+ 	configuration file (e.g. /etc/default/login under IRIX).
+ 	Currently the only option that is used is the CONSOLE
+ 	value which specifies where root may log in using a password.
+ 
+ --with-kadmin-cryptocard
+ 
+ 	Support programming a CRYPTOCard RB-1 token via a special
+ 	interface in kadmin.  This will either generate the front
+ 	panel programming information or talk to a RB-1 Token
+ 	Initializer.
+ 
+ --with-cryptocard-validate
+ 
+ 	This enables KDC code to allow the validation of a CRYPTOCard
+ 	RB-1 token without the entering of a user's password (it
+ 	requires a host key or other encryption key to send the
+ 	response, however).  Note that the utilization of this code
+ 	requires changes to the client libraries that are not in this
+ 	distribution.
+ 
+ --with-krb524-remapping
+ 
+ 	This enables code in the 524 ticket converter to map principals
+ 	in foreign realms to principals in the local realm when getting
+ 	tickets for the AFS service.  This is used to solve the problem
+ 	of foreign cross-realm users having PTS IDs that don't match
+ 	their Unix userid.  Note that this code has a number of
+ 	interesting security implications, so do not enable it unless
+ 	you know what you're doing!
+ 
+ --enable-login-print-issue
+ 
+ 	This enables code that causes login.krb5 to print /etc/issue,
+ 	if it is present, before the use logs in.
+ 
+ --enable-log-preauth-logins
+ 
+ 	This enables code in login.krb5 and ftpd that changes the syslog
+ 	messages generated so that they indicate whether a user login is
+ 	done with a password or if it is preauthenticated.
+ 
+ --enable-dns-lookup
+ 
+ 	This enables code to look up KDC location in DNS (via DNS SRV
+ 	records).  The local file is still looked at first.  For
+ 	more information, see RFC 2052 (note that this code complies
+ 	with the new Internet-Draft and and uses _ to prefix the service
+ 	and protocol labels).  This code also enables the mapping of
+ 	hosts/domains to Kerberos realm via TXT records.  Some examples:
+ 
+ 	_kerberos._udp.my.realm.	IN	SRV	0 0 88 kdc1.my.domain.
+ 	_kerberos._udp.my.realm.	IN	SRV	1 0 88 kdc2.my.domain.
+ 
+ 	_kerberos.my.domain.		IN	TXT	"MY.REALM"
+ 
+ 
+ --without-anonymous-ftp
+ 
+ 	This removes support for anonymous FTP from the FTP daemon.
+ 	This is a useful "defense in depth" against users and careless
+ 	system administrators mis-configuring random hosts to allow
+ 	anonymous FTP where that might conflict with a site's policy.
+ 
+ --with-telnet-service=SRVNAME
+ 
+ 	This option compiles in an alternate service name for the
+ 	TELNET client, which can be a helpful migration aid for sites
+ 	that run regular services and Kerberos services in parallel on
+ 	differnt ports.  SRVNAME must be a valid service name from
+ 	/etc/services that is acceptable to getservbyname().  The
+ 	value "ktelnet" is popular.
+ 
+ --with-ftp-service=SRVNAME
+ 
+ 	This option compiles in an alternate service name for the
+ 	FTP client, which can be a helpful migration aid for sites
+ 	that run regular services and Kerberos services in parallel on
+ 	differnt ports.  SRVNAME must be a valid service name from
+ 	/etc/services that is acceptable to getservbyname().  The
+ 	value "kftp" is popular.
+ 
+ --enable-k5login-dir=DIRECTORY
+ 
+ 	This allows .k5login files to be located in a place _other_
+ 	than the user's home directory.  Note that when this option
+ 	is used, .k5login files will be looked for at:
+ 
+ 	DIRECTORY/USERNAME/.k5login
+ 
+ 	And .k5login files in the user's home directory will NOT be
+ 	respected.
+ 
+ --disable-krb4-compat
+ 
+ 	Disable some of the automatic V4 compatibility code in some of
+ 	the client applications (like kinit and klist).
Index: krb5/aclocal.m4
diff -c krb5/aclocal.m4:1.1.1.4 krb5/aclocal.m4:1.13
*** krb5/aclocal.m4:1.1.1.4	Thu Dec 19 14:05:59 2002
--- krb5/aclocal.m4	Thu Dec 19 14:19:25 2002
***************
*** 42,47 ****
--- 42,48 ----
  WITH_NETLIB dnl
  WITH_HESIOD dnl
  KRB_INCLUDE dnl
+ CHECK_64BIT dnl
  AC_ARG_PROGRAM dnl
  dnl
  dnl This selects the correct autoconf file; either the one in our source tree,
***************
*** 1512,1514 ****
--- 1513,1559 ----
  dnl AC_MSG_RESULT($enable_dns_for_realm)
  
  ])
+ dnl This rule checks for special compilation flags needed for 64 bit
+ dnl operation on some systems (like Solaris).
+ dnl
+ define(CHECK_64BIT,[
+ if test -n "$krb5_cv_host"; then
+ AC_CACHE_CHECK([for 64-bit compile flags], krb5_cv_64bit_flags,
+ [case "$krb5_cv_host" in
+ 	sparc-sun-solaris2*)
+ 		AC_PATH_PROG(GETCONF, getconf)
+ 		if test -n "$ac_cv_path_GETCONF"; then
+ 			krb5_cv_64bit_flags=`$ac_cv_path_GETCONF LFS_CFLAGS`
+ 		fi
+ 		;;
+ 	*)
+ 		;;
+ esac
+ if test -z "$krb5_cv_64bit_flags"; then
+ 	krb5_cv_64bit_flags=no;
+ fi])
+ if test "$krb5_cv_64bit_flags" != "no"; then
+ 	AC_MSG_RESULT([Adding $krb5_cv_64bit_flags to CPPFLAGS])
+ 	CPPFLAGS="$CPPFLAGS $krb5_cv_64bit_flags"
+ fi
+ fi
+ ])dnl
+ dnl
+ dnl AC_SIZEOF_OFF_T - Determine the size of off_t
+ dnl
+ AC_DEFUN(AC_SIZEOF_OFF_T,[
+ AC_CACHE_CHECK([size of off_t], krb5_cv_size_off_t,
+ [AC_TRY_RUN([#include <stdio.h>
+ #include <sys/types.h>
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif
+ main()
+ {
+   FILE *f=fopen("conftestval", "w");
+   if (!f) exit(1);
+   fprintf(f, "%d\n", sizeof(off_t));
+   exit(0);
+ }], krb5_cv_size_off_t=`cat conftestval`, krb5_cv_size_off_t=0)])
+ AC_DEFINE_UNQUOTED(SIZEOF_OFF_T, $krb5_cv_size_off_t)
+ ])dnl
Index: krb5/krb5-config.in
diff -c krb5/krb5-config.in:1.1.1.1 krb5/krb5-config.in:1.2
*** krb5/krb5-config.in:1.1.1.1	Fri Feb 22 16:31:13 2002
--- krb5/krb5-config.in	Tue Jan 14 12:50:00 2003
***************
*** 170,175 ****
--- 170,176 ----
  if test -n "$do_libs"; then
      # Ugly gross hack for our build tree
      lib_flags=`echo $CC_LINK | sed -e 's/\$(CC)//' \
+ 	    -e 's/\$(PURE)//' \
  	    -e 's#\$(PROG_RPATH)#'$libdir'#' \
  	    -e 's#\$(PROG_LIBPATH)#-L'$libdir'#'`
  
Index: krb5/appl/.cvsignore
diff -c /dev/null krb5/appl/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:05 2003
--- krb5/appl/.cvsignore	Thu Jun  5 10:38:02 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/bsd/.cvsignore
diff -c /dev/null krb5/appl/bsd/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:05 2003
--- krb5/appl/bsd/.cvsignore	Thu Jun  5 10:38:07 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/bsd/configure.in
diff -c krb5/appl/bsd/configure.in:1.1.1.3 krb5/appl/bsd/configure.in:1.22
*** krb5/appl/bsd/configure.in:1.1.1.3	Fri Feb 22 16:31:17 2002
--- krb5/appl/bsd/configure.in	Mon Mar 10 15:24:43 2003
***************
*** 2,14 ****
  CONFIG_RULES
  LOGINLIBS=
  AC_ARG_WITH([afs],
! [  --without-afs        don't have afs libraries to build against (default)
!   --with-afs=AFSDIR    use preinstalled AFS library tree],
  ,with_afs=no)dnl
  if test $with_afs != no; then
  	AC_DEFINE(SETPAG)
! 	LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp"
  fi
  AC_PROG_INSTALL
  dnl dbm libs for use of an_to_ln
  AC_CHECK_LIB(util,main)
--- 2,65 ----
  CONFIG_RULES
  LOGINLIBS=
  AC_ARG_WITH([afs],
! [  --without-afs           don't have afs libraries to build against (default)
!   --with-afs=AFSDIR       use preinstalled AFS library tree],
  ,with_afs=no)dnl
  if test $with_afs != no; then
  	AC_DEFINE(SETPAG)
! 	LOGINLIBS="$LOGINLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp -lsys"
! 	case $krb5_cv_host in
! 	*-*-solaris*)
! 		LOGINLIBS="$LOGINLIBS -lc -L/usr/ucblib -lucb -R/usr/ucblib"
! 		;;
! 	*-*-hpux*)
! 		LOGINLIBS="$LOGINLIBS -lBSD -lm"
! 		;;
! 	*-*-netbsd*)
! 		LOGINLIBS="$LOGINLIBS -lcompat"
! 		;;
! 	esac
  fi
+ AC_ARG_ENABLE([irix-project-init],
+ [  --enable-irix-project-init   Initialize the IRIX project id at login
+   --disable-irix-project-init  Don't do IRIX project setup (default)],[
+ AC_MSG_RESULT(Enabling IRIX project initialization support)
+ AC_DEFINE(IRIX_PROJECT_INIT)
+ ])
+ AC_ARG_WITH([multihomed_fixes],
+ [  --with-multihomed-fixes  Includes fixes to help deal with multihomed hosts],
+ AC_DEFINE(KRB5_MULTIHOMED_FIXES))
+ dnl
+ dnl Check for --with-login-conf
+ AC_ARG_WITH([login_conf],
+ [  --with-login-conf=file   Login should use defaults in file],[
+ AC_MSG_RESULT(Enabling login configuration file parsing)
+ AC_DEFINE(USE_LOGIN_CONF)
+ AC_DEFINE_UNQUOTED(LOGIN_CONF_FILE, "${withval}")
+ ])
+ dnl
+ dnl Check for --with-login-print-issue[=<file>]
+ AC_ARG_ENABLE([login-print-issue],
+ [  --enable-login-print-issue  Have login print /etc/issue before login prompt],[
+ AC_MSG_RESULT(Enable printing of /etc/issue by login)
+ AC_DEFINE(PRINT_ISSUE)
+ AC_DEFINE_UNQUOTED(ISSUE_FILE, "/etc/issue")
+ ])
+ dnl
+ dnl Check for --enable-log-preauth-logins
+ AC_ARG_ENABLE([log-preauth-logins],
+ [  --enable-log-preauth-logins  Log whether logins are password or preauthenticated],[
+ AC_MSG_RESULT(Enable logging of preauthenticated logins)
+ AC_DEFINE(LOG_PREAUTH_LOGINS)
+ ])
+ dnl
+ dnl Enable forcing login to always allocate a pag
+ AC_ARG_WITH([afs-setpag-always],
+ [  --with-afs-setpag-always    Always allocate a PAG, even for root],[
+ AC_MSG_RESULT([Always allocate a PAG, even for root])
+ AC_DEFINE(SETPAG_ALWAYS)
+ ])
+ dnl
  AC_PROG_INSTALL
  dnl dbm libs for use of an_to_ln
  AC_CHECK_LIB(util,main)
***************
*** 121,127 ****
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
--- 172,179 ----
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);
!     unsetenv("PATH");],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
***************
*** 159,167 ****
--- 211,273 ----
  AC_DEFINE(HAVE_SHADOW)
  fi
  dnl
+ dnl Check for HPUX Protected password support
+ AC_MSG_CHECKING([libsec])
+ AC_CACHE_VAL(krb5_cv_have_libsec,
+ [AC_CHECK_LIB(sec, getprpwent,
+ krb5_cv_have_libsec=yes, krb5_cv_have_libsec=no)])
+ AC_MSG_RESULT($krb5_cv_have_libsec)
+ dnl
+ AC_MSG_CHECKING([HP-UX protected password support])
+ AC_CACHE_VAL(krb5_cv_protected_pwd,
+ [krb5_cv_protected_pwd=$krb5_cv_have_libsec])
+ AC_MSG_RESULT($krb5_cv_protected_pwd)
+ dnl
+ if test $krb5_cv_protected_pwd = yes; then
+ AC_DEFINE(HAVE_PRPASSWD)
+ LOGINLIBS="$LOGINLIBS -lsec"
+ fi
+ dnl
+ dnl Check for capabilities
+ AC_FUNC_CHECK(cap_set_proc,[
+ 	AC_EGREP_CPP(yes,[
+ #ifdef CAP_ALL_OFF
+ yes
+ #endif], [
+ 	AC_DEFINE(HAS_CAP_SET_PROC)
+ 	AC_CHECK_HEADERS(sys/capability.h)
+ ])])dnl
+ dnl
+ dnl Check for Irix jlimit_startjob
+ AC_FUNC_CHECK(jlimit_startjob,[
+ 	AC_DEFINE(HAS_JLIMIT_STARTJOB)
+ 	AC_CHECK_HEADERS(sys/resource.h)
+ ])
+ dnl
+ dnl
+ AC_MSG_CHECKING([/etc/environment])
+ AC_CACHE_VAL(krb5_cv_etc_environment,
+ [AC_C_CROSS
+ if test "X$ac_cv_c_cross" = Xyes; then
+ errprint(__file__:__line__: warning: Cannot check for file existence when cross compiling
+ )dnl
+ AC_MSG_ERROR(Cannot check for file existence when cross compiling)
+ else
+ if test -r /etc/environment; then
+ krb5_cv_etc_environment=yes
+ else
+ krb5_cv_etc_environment=no
+ fi
+ fi])
+ AC_MSG_RESULT($krb5_cv_etc_environment)
+ if test $krb5_cv_etc_environment = yes; then
+ AC_DEFINE(HAVE_ETC_ENVIRONMENT)
+ fi
+ dnl
  dnl
  K5_AC_CHECK_FILES(/etc/environment /etc/TIMEZONE)
  dnl
+ AC_SIZEOF_OFF_T
  dnl
  KRB5_CHECK_PROTOS
  dnl
***************
*** 176,181 ****
--- 282,306 ----
  	AC_CHECK_FUNCS(krb_get_err_text krb_save_credentials)
  	LIBS=$oldlibs
  fi
+ 
+ dnl Do we want to exclude session encryption?
+ do_encrypt=yes
+ AC_ARG_WITH([session-encrypt],
+ [  --with-session-encrypt     Support session encryption (default)
+   --without-session-encrypt  Disable session encryption],do_encrypt=$withval)
+ if test $do_encrypt = no; then
+ 	AC_DEFINE(NOENCRYPTION)
+ fi
+ dnl
+ dnl Include big hack to make krshd work on HP exemplar
+ AC_ARG_WITH([hp-exemplar-krshd-hack],
+ 	[  --with-hp-exemplar-krshd-hack  Include hack to make rshd/rlogind work right on exemplar],
+ 	hp_exemplar_krshd_hack=$withval,
+ 	hp_exemplar_krshd_hack=no)
+ if test "$hp_exemplar_krshd_hack" = "yes"; then
+ 	AC_DEFINE(HP_EXEMPLAR_KRSHD_HACK)
+ fi
+ 
  
  AC_CHECK_HEADERS(krb4-proto.h)
  
Index: krb5/appl/bsd/kcmd.c
diff -c krb5/appl/bsd/kcmd.c:1.1.1.3 krb5/appl/bsd/kcmd.c:1.9
*** krb5/appl/bsd/kcmd.c:1.1.1.3	Fri Feb 22 16:31:18 2002
--- krb5/appl/bsd/kcmd.c	Mon Feb 25 22:28:54 2002
***************
*** 63,69 ****
  #define _TYPES_
  #endif
  #include <fcntl.h>
!      
  #ifndef MAXPATHLEN
  #define MAXPATHLEN 1024
  #endif
--- 63,73 ----
  #define _TYPES_
  #endif
  #include <fcntl.h>
! 
! #ifdef HAVE_SYS_TIME_H
! #include <sys/time.h>
! #endif
! 
  #ifndef MAXPATHLEN
  #define MAXPATHLEN 1024
  #endif
***************
*** 72,77 ****
--- 76,85 ----
  #include <sys/socket.h>
  #include <sys/stat.h>
  
+ #ifdef HAVE_SYS_SELECT_H
+ #include <sys/select.h>
+ #endif
+ 
  #ifndef POSIX_SIGNALS
  #ifndef sigmask
  #define sigmask(m)    (1 << ((m)-1))
***************
*** 177,183 ****
       int suppress_err;		/* Don't print if authentication fails */
       enum kcmd_proto *protonump;
  {
!     int s, pid;
  #ifdef POSIX_SIGNALS
      sigset_t oldmask, urgmask;
  #else
--- 185,191 ----
       int suppress_err;		/* Don't print if authentication fails */
       enum kcmd_proto *protonump;
  {
!     int i, s, timo = 1, pid, numaddrs;
  #ifdef POSIX_SIGNALS
      sigset_t oldmask, urgmask;
  #else
***************
*** 200,205 ****
--- 208,215 ----
      krb5_auth_context auth_context = NULL;
      char *cksumbuf;
      krb5_data cksumdat;
+     char **save_addr_list;
+     char **addr;
      char *kcmd_version;
      enum kcmd_proto protonum = *protonump;
  
***************
*** 219,225 ****
--- 229,288 ----
  	fprintf(stderr, "%s: unknown host\n", *ahost);
  	return (-1);
      }
+     
+     if ((host_save = (char *) malloc(strlen(hp->h_name) + 1)) == NULL) {
+         fprintf(stderr,"kcmd: no memory\n");
+         return(-1);
+     }
+     strcpy(host_save, hp->h_name);
+ 
+     /*
+      * Save the list of IP address too, for later
+      */
+ 
+     for (addr = hp->h_addr_list, numaddrs = 0; *addr; addr++)
+ 	numaddrs++;
+ 
+     if ((save_addr_list = (char **) malloc(sizeof(char *) * (numaddrs + 1))) ==
+ 									NULL) {
+ 	fprintf(stderr, "kcmd: no memory\n");
+ 	return(-1);
+     }
  
+     for (i = 0; i < numaddrs; i++) {
+ 	if ((save_addr_list[i] = (char *) malloc(hp->h_length)) == NULL) {
+ 	    fprintf(stderr, "kcmd: no memory\n");
+ 	    return(-1);
+ 	}
+ 	memcpy(save_addr_list[i], hp->h_addr_list[i], hp->h_length);
+     }
+     save_addr_list[numaddrs] = NULL;
+ 
+     /* If no service is given set to the default service */
+     if (!service) service = default_service;
+     
+     sin_len = strlen(host_save) + strlen(service)
+       + (realm ? strlen(realm): 0) + 3;
+     if ( sin_len < 20 ) sin_len = 20;
+     
+     if (!(get_cred = (krb5_creds *)calloc(1, sizeof(krb5_creds)))) {
+         fprintf(stderr,"kcmd: no memory\n");
+         return(-1);
+     }
+     status = krb5_sname_to_principal(bsd_context, host_save, service,
+ 				     KRB5_NT_SRV_HST, &get_cred->server);
+     if (status) {
+ 	    fprintf(stderr, "kcmd: krb5_sname_to_principal failed: %s\n",
+ 		    error_message(status));
+ 	    return(-1);
+     }
+ 
+     if (realm && *realm) {
+ 	free(krb5_princ_realm(bsd_context,get_cred->server)->data);
+ 	/*krb5_xfree(krb5_princ_realm(bsd_context,get_cred->server)->data);*/
+ 	krb5_princ_set_realm_length(bsd_context,get_cred->server,strlen(realm));
+ 	krb5_princ_set_realm_data(bsd_context,get_cred->server,strdup(realm));
+    }
  #ifdef POSIX_SIGNALS
      sigemptyset(&urgmask);
      sigaddset(&urgmask, SIGURG);
***************
*** 227,233 ****
  #else
      oldmask = sigblock(sigmask(SIGURG));
  #endif /* POSIX_SIGNALS */
!     
      for (;;) {
          s = getport(0);
      	if (s < 0) {
--- 290,298 ----
  #else
      oldmask = sigblock(sigmask(SIGURG));
  #endif /* POSIX_SIGNALS */
! 
!     addr = save_addr_list;
! 
      for (;;) {
          s = getport(0);
      	if (s < 0) {
***************
*** 240,249 ****
  #else
  	    sigsetmask(oldmask);
  #endif /* POSIX_SIGNALS */
  	    return (-1);
      	}
      	sin.sin_family = hp->h_addrtype;
!     	memcpy((caddr_t)&sin.sin_addr,hp->h_addr, sizeof(sin.sin_addr));
      	sin.sin_port = rport;
      	if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  	    break;
--- 305,318 ----
  #else
  	    sigsetmask(oldmask);
  #endif /* POSIX_SIGNALS */
+ 	    krb5_free_creds(bsd_context, get_cred);
+ 	    for (addr = save_addr_list; *addr; addr++)
+ 		free(*addr);
+ 	    free(save_addr_list);
  	    return (-1);
      	}
      	sin.sin_family = hp->h_addrtype;
!     	memcpy((caddr_t)&sin.sin_addr,addr[0], sizeof(sin.sin_addr));
      	sin.sin_port = rport;
      	if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
  	    break;
***************
*** 251,280 ****
      	if (errno == EADDRINUSE)
  	    continue;
  
! #if !(defined(tek) || defined(ultrix) || defined(sun) || defined(SYSV))
!     	if (hp->h_addr_list[1] != NULL) {
  	    int oerrno = errno;
  	    
  	    fprintf(stderr,
      		    "connect to address %s: ", inet_ntoa(sin.sin_addr));
  	    errno = oerrno;
  	    perror(0);
! 	    hp->h_addr_list++;
! 	    memcpy((caddr_t)&sin.sin_addr,hp->h_addr_list[0],
  		   sizeof(sin.sin_addr));
  	    fprintf(stderr, "Trying %s...\n",
  		    inet_ntoa(sin.sin_addr));
  	    continue;
      	}
! #endif /* !(defined(ultrix) || defined(sun)) */
!     	perror(hp->h_name);
  #ifdef POSIX_SIGNALS
  	sigprocmask(SIG_SETMASK, &oldmask, (sigset_t*)0);
  #else
      	sigsetmask(oldmask);
  #endif /* POSIX_SIGNALS */
      	return (-1);
      }
      /* If no service is given set to the default service */
      if (!service) service = default_service;
      
--- 320,355 ----
      	if (errno == EADDRINUSE)
  	    continue;
  
!     	if (addr[1] != NULL) {
  	    int oerrno = errno;
  	    
  	    fprintf(stderr,
      		    "connect to address %s: ", inet_ntoa(sin.sin_addr));
  	    errno = oerrno;
  	    perror(0);
! 	    addr++;
! 	    memcpy((caddr_t)&sin.sin_addr,addr[0],
  		   sizeof(sin.sin_addr));
  	    fprintf(stderr, "Trying %s...\n",
  		    inet_ntoa(sin.sin_addr));
  	    continue;
      	}
!     	perror(host_save);
  #ifdef POSIX_SIGNALS
  	sigprocmask(SIG_SETMASK, &oldmask, (sigset_t*)0);
  #else
      	sigsetmask(oldmask);
  #endif /* POSIX_SIGNALS */
+ 	krb5_free_creds(bsd_context, get_cred);
+ 	for (addr = save_addr_list; *addr; addr++)
+ 	    free(*addr);
+ 	free(save_addr_list);
      	return (-1);
      }
+     for (addr = save_addr_list; *addr; addr++)
+ 	free(*addr);
+     free(save_addr_list);
+     lport--;
      /* If no service is given set to the default service */
      if (!service) service = default_service;
      
***************
*** 311,316 ****
--- 386,393 ----
      	char num[8];
      	int s2 = getport(&lport), s3;
      	int len = sizeof (from);
+ 	int nfds;
+ 	fd_set reads;
  	
      	if (s2 < 0) {
  	    status = -1;
***************
*** 453,459 ****
  					ret_cred->client, ret_cred->server,
  					0, options & OPTS_FORWARDABLE_CREDS,
  					&outbuf)) {
! 	    fprintf(stderr, "kcmd: Error getting forwarded creds\n");
  	    goto bad2;
  	}
  
--- 530,537 ----
  					ret_cred->client, ret_cred->server,
  					0, options & OPTS_FORWARDABLE_CREDS,
  					&outbuf)) {
! 	    fprintf(stderr, "kcmd: Error getting forwarded creds (%s)\n",
! 		error_message(status));
  	    goto bad2;
  	}
  
Index: krb5/appl/bsd/klogind.M
diff -c krb5/appl/bsd/klogind.M:1.1.1.3 krb5/appl/bsd/klogind.M:1.4
*** krb5/appl/bsd/klogind.M:1.1.1.3	Fri Feb 22 16:31:19 2002
--- krb5/appl/bsd/klogind.M	Mon Feb 25 02:56:33 2002
***************
*** 36,43 ****
  .IP 2)
  Check authorization via the access-control files \fI.k5login\fP, \fI.klogin\fP 
  and \fI.rhosts\fP in the user's home directory.
- .IP 3)
- Prompt for password if any checks fail and the \fI-p\fP option was supplied.
  .PP
  If the authentication succeeds, login the user by calling the accompanying 
  login.krb5 or /bin/login, according to the definition of 
--- 36,41 ----
***************
*** 61,72 ****
  Allow Kerberos V5 and Kerberos V4 as acceptable authentication
  mechanisms.  This is the same as including \fB\-4\fP and \fB\-5\fP.
  
- 
- .IP \fB\-p\fP
-  If all other authorization checks fail, prompt the user
- for a password If this option is not included, access is denied
- without successful authentication and authorization using one of the
- previous mechanisms.
  
  .IP \fB\-P\fP
  Prompt the user for a password.
--- 59,64 ----
Index: krb5/appl/bsd/krcp.c
diff -c krb5/appl/bsd/krcp.c:1.1.1.3 krb5/appl/bsd/krcp.c:1.9
*** krb5/appl/bsd/krcp.c:1.1.1.3	Fri Feb 22 16:31:19 2002
--- krb5/appl/bsd/krcp.c	Wed Sep 18 16:04:03 2002
***************
*** 100,105 ****
--- 100,107 ----
  void 	usage(), sink(), source(), rsource(), verifydir(), answer_auth();
  int	response(), hosteq(), okname(), susystem();
  int	encryptflag = 0;
+ int	encrypt_option_flag = -1;
+ int	forward_flag = -1;
  
  #ifndef UCB_RCP
  #define	UCB_RCP	"/bin/rcp"
***************
*** 146,151 ****
--- 148,154 ----
      char buf[RCP_BUFSIZ], cmdbuf[30];
      char *cmd = cmdbuf;
      struct servent *sp;
+     struct servent defaultservent;
      static char curhost[256];
  #ifdef POSIX_SIGNALS
      struct sigaction sa;
***************
*** 190,202 ****
  	    port = htons(atoi(*argv));
  	    goto next_arg;
  
! 	  case 'N':
  	    forcenet++;
  	    break;
  
  #ifdef KERBEROS
  	  case 'x':
! 	    encryptflag++;
  	    break;
  	  case 'k':		/* Change kerberos realm */
  	    argc--, argv++;
--- 193,208 ----
  	    port = htons(atoi(*argv));
  	    goto next_arg;
  
! 	  case 'n':
  	    forcenet++;
  	    break;
  
  #ifdef KERBEROS
  	  case 'x':
! 	    encrypt_option_flag = 1;
! 	    break;
! 	  case 'X':
! 	    encrypt_option_flag = 0;
  	    break;
  	  case 'k':		/* Change kerberos realm */
  	    argc--, argv++;
***************
*** 228,233 ****
--- 234,253 ----
  	    }
  	    strcpy(krb_config, *argv);	
  	    goto next_arg;
+ 	  case 'F':		/* Forward credentials */
+ 	    if (forward_flag != -1) {
+ 		fprintf(stderr, "Cannot use both -F and -n.\n");
+ 		exit(1);
+ 	    }
+ 	    forward_flag = 1;
+ 	    break;
+ 	  case 'N':		/* Don't forward credentials */
+ 	    if (forward_flag != -1) {
+ 		fprintf(stderr, "Cannot use both -F and -n.\n");
+ 		exit(1);
+ 	    }
+ 	    forward_flag = 0;
+ 	    break;
  	  case 'P':
  	    if (!strcmp (*argv, "O"))
  		kcmd_proto = KCMD_OLD_PROTOCOL;
***************
*** 246,252 ****
  	    iamremote = 1;
  	    rcmd_stream_init_normal();
  #if defined(KERBEROS)
! 	    if (encryptflag)
  	      answer_auth(krb_config, krb_cache);
  #endif /* KERBEROS */
  
--- 266,272 ----
  	    iamremote = 1;
  	    rcmd_stream_init_normal();
  #if defined(KERBEROS)
! 	    if (encryptflag || encrypt_option_flag == 1)
  	      answer_auth(krb_config, krb_cache);
  #endif /* KERBEROS */
  
***************
*** 258,264 ****
  	    iamremote = 1;
  	    rcmd_stream_init_normal();
  #if defined(KERBEROS)
! 	    if (encryptflag)
  	      answer_auth(krb_config, krb_cache);
  #endif /* KERBEROS */
  
--- 278,284 ----
  	    iamremote = 1;
  	    rcmd_stream_init_normal();
  #if defined(KERBEROS)
! 	    if (encryptflag || encrypt_option_flag == 1)
  	      answer_auth(krb_config, krb_cache);
  #endif /* KERBEROS */
  
***************
*** 287,294 ****
      
        if (sp == NULL) {
  #ifdef KERBEROS
! 	fprintf(stderr, "rcp: kshell/tcp: unknown service\n");
! 	try_normal(orig_argv);
  #else
  	fprintf(stderr, "rcp: shell/tcp: unknown service\n");
  	exit(1);
--- 307,314 ----
      
        if (sp == NULL) {
  #ifdef KERBEROS
! 	sp = &defaultservent;
! 	sp->s_port = htons(544);
  #else
  	fprintf(stderr, "rcp: shell/tcp: unknown service\n");
  	exit(1);
***************
*** 298,303 ****
--- 318,349 ----
      }
  
  #ifdef KERBEROS
+ 
+     {
+ 	krb5_data realm;
+ 
+ 	if (krb_realm) {
+ 		realm.data = krb_realm;
+ 	} else {
+ 		krb5_get_default_realm(bsd_context, &realm.data);
+ 	}
+ 
+ 	if (encrypt_option_flag == -1) {
+ 		krb5_appdefault_boolean(bsd_context, "rcp", &realm, "encrypt",
+ 					0, &encryptflag);
+ 	} else {
+ 		encryptflag = encrypt_option_flag;
+ 	}
+ 
+ 	if (forward_flag == -1) {
+ 		krb5_appdefault_boolean(bsd_context, "rcp", &realm, "forward",
+ 					0, &forward_flag);
+ 	}
+ 
+ 	if (! krb_realm)
+ 		free(realm.data);
+     }
+ 
      if (krb_realm != NULL)
  	cmdsiz += strlen(krb_realm);
      if (krb_cache != NULL)
***************
*** 417,423 ****
  				   cmd, targ);
  		    host = thost;
  #ifdef KERBEROS
! 		    authopts = AP_OPTS_MUTUAL_REQUIRED;
  		    status = kcmd(&sock, &host,
  				  port,
  				  pwd->pw_name,
--- 463,470 ----
  				   cmd, targ);
  		    host = thost;
  #ifdef KERBEROS
! 		    authopts = AP_OPTS_MUTUAL_REQUIRED |
! 			       (forward_flag ? OPTS_FORWARD_CREDS : 0);
  		    status = kcmd(&sock, &host,
  				  port,
  				  pwd->pw_name,
***************
*** 547,553 ****
  		}
  		(void) sprintf(buf, "%s -f %s", cmd, src);
  #ifdef KERBEROS
! 		authopts = AP_OPTS_MUTUAL_REQUIRED;
  		status = kcmd(&sock, &host,
  			      port,
  			      pwd->pw_name,  suser,
--- 594,601 ----
  		}
  		(void) sprintf(buf, "%s -f %s", cmd, src);
  #ifdef KERBEROS
! 		authopts = AP_OPTS_MUTUAL_REQUIRED |
! 			   (forward_flag ? OPTS_FORWARD_CREDS : 0);
  		status = kcmd(&sock, &host,
  			      port,
  			      pwd->pw_name,  suser,
***************
*** 809,816 ****
--- 857,869 ----
  		continue;
  	    }
  	}
+ #if SIZEOF_OFF_T == 8
+ 	(void) sprintf(buf, "C%04o %llu %s\n",
+ 		       (int) stb.st_mode&07777, (off_t) stb.st_size, last);
+ #else /* SIZEOF_OFF_T != 8 */
  	(void) sprintf(buf, "C%04o %ld %s\n",
  		       (int) stb.st_mode&07777, (long ) stb.st_size, last);
+ #endif /* SIZEOF_OFF_T == 8 */
  	(void) rcmd_stream_write(rem, buf, strlen(buf), 0);
  	if (response() < 0) {
  	    (void) close(f);
***************
*** 974,982 ****
  {
      mode_t mode;
      mode_t mask = umask(0);
!     off_t i, j;
      char *targ, *whopp, *cp;
!     int of, wrerr, exists, first, count, amt, size;
      struct buffer *bp;
      static struct buffer buffer;
      struct stat stb;
--- 1027,1035 ----
  {
      mode_t mode;
      mode_t mask = umask(0);
!     off_t i, j, size;
      char *targ, *whopp, *cp;
!     int of, wrerr, exists, first, count, amt;
      struct buffer *bp;
      static struct buffer buffer;
      struct stat stb;
Index: krb5/appl/bsd/krlogin.c
diff -c krb5/appl/bsd/krlogin.c:1.1.1.3 krb5/appl/bsd/krlogin.c:1.11
*** krb5/appl/bsd/krlogin.c:1.1.1.3	Fri Feb 22 16:31:20 2002
--- krb5/appl/bsd/krlogin.c	Mon Feb 25 22:28:55 2002
***************
*** 167,172 ****
--- 167,174 ----
  void try_normal();
  char *krb_realm = (char *)0;
  int encrypt_flag = 0;
+ int encrypt_option_flag = -1;
+ int no_forward = 0;
  int fflag = 0, Fflag = 0;
  krb5_creds *cred;
  struct sockaddr_in local, foreign;
***************
*** 237,242 ****
--- 239,245 ----
  { "0", "50", "75", "110", "134", "150", "200", "300",
      "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
  #endif
+ const int maxspeed = sizeof(speeds) / sizeof(char *) - 1;
  char	term[256] = "network";
  
  #ifndef POSIX_SIGNALS
***************
*** 476,482 ****
  	goto another;
      }
      if (argc > 0 && !strcmp(*argv, "-x")) {
! 	encrypt_flag++;
  	argv++, argc--;
  	goto another;
      }
--- 479,490 ----
  	goto another;
      }
      if (argc > 0 && !strcmp(*argv, "-x")) {
! 	encrypt_option_flag = 1;
! 	argv++, argc--;
! 	goto another;
!     }
!     if (argc > 0 && !strcmp(*argv, "-X")) {
! 	encrypt_option_flag = 0;
  	argv++, argc--;
  	goto another;
      }
***************
*** 498,503 ****
--- 506,516 ----
  	argv++, argc--;
  	goto another;
      }
+     if (argc > 0 && !strcmp(*argv, "-N")) {
+ 	no_forward++;
+ 	argv++, argc--;
+ 	goto another;
+     }
      if (argc > 0 && !strcmp(*argv, "-PO")) {
  	kcmd_proto = KCMD_OLD_PROTOCOL;
  	argv++, argc--;
***************
*** 524,529 ****
--- 537,561 ----
  	    com_err(argv[0], status, "while initializing krb5");
  	    exit(1);
      }
+ 
+     {
+ 	krb5_data realm;
+ 	int eflag;
+ 
+ 	if (krb_realm) {
+ 		realm.data = krb_realm;
+ 	} else {
+ 		krb5_get_default_realm(bsd_context, &realm.data);
+ 	}
+ 
+ 	krb5_appdefault_boolean(bsd_context, "rlogin", &realm, "encrypt", 0,
+ 				&eflag);
+ 	
+ 	encrypt_flag = encrypt_option_flag == -1 ? eflag : encrypt_option_flag;
+ 
+ 	if (! krb_realm)
+ 		krb5_free_default_realm(bsd_context, realm.data);
+     }
  #endif
  
  
***************
*** 624,629 ****
--- 656,679 ----
  #ifdef KERBEROS
      authopts = AP_OPTS_MUTUAL_REQUIRED;
  
+     if (! (fflag || Fflag) && ! no_forward) {
+ 	krb5_data realm;
+ 
+ 	if (krb_realm) {
+ 		realm.data = krb_realm;
+ 	} else {
+ 		krb5_get_default_realm(bsd_context, &realm.data);
+ 	}
+ 
+ 	krb5_appdefault_boolean(bsd_context, "rlogin", &realm, "forward", 0,
+ 				&fflag);
+ 	krb5_appdefault_boolean(bsd_context, "rlogin", &realm, "forwardable", 0,
+ 				&Fflag);
+ 	
+ 	if (! krb_realm)
+ 		krb5_free_default_realm(bsd_context, realm.data);
+     }
+ 
      /* Piggy-back forwarding flags on top of authopts; */
      /* they will be reset in kcmd */
      if (fflag || Fflag)
***************
*** 1774,1786 ****
  	    UCB_RLOGIN);
      fflush(stderr);
      
!     host = strrchr(argv[0], '/');
!     if (host)
!       host++;
!     else
!       host = argv[0];
!     if (!strcmp(host, "rlogin"))
!       argv++;
      
  #ifdef POSIX_SIGNALS
      sigemptyset(&mask);
--- 1824,1830 ----
  	    UCB_RLOGIN);
      fflush(stderr);
      
!     argv[0] = "rlogin";
      
  #ifdef POSIX_SIGNALS
      sigemptyset(&mask);
Index: krb5/appl/bsd/krlogind.c
diff -c krb5/appl/bsd/krlogind.c:1.1.1.6 krb5/appl/bsd/krlogind.c:1.15
*** krb5/appl/bsd/krlogind.c:1.1.1.6	Fri Feb 22 16:31:20 2002
--- krb5/appl/bsd/krlogind.c	Mon Feb 25 22:28:55 2002
***************
*** 239,250 ****
--- 239,252 ----
  #endif
  
  int auth_sys = 0;	/* Which version of Kerberos used to authenticate */
+ int require_hwpreauth = 0;
  
  #define KRB5_RECVAUTH_V4	4
  #define KRB5_RECVAUTH_V5	5
  
  int non_privileged = 0; /* set when connection is seen to be from */
  			/* a non-privileged port */
+ int retain_ccache = 0;
  
  AUTH_DAT	*v4_kdata;
  Key_schedule v4_schedule;
***************
*** 261,267 ****
  
  krb5_keytab keytab = NULL;
  
! #define ARGSTR	"k54ciepPD:S:M:L:fw:?"
  #else /* !KERBEROS */
  #define ARGSTR	"rpPD:f?"
  #endif /* KERBEROS */
--- 263,269 ----
  
  krb5_keytab keytab = NULL;
  
! #define ARGSTR	"k54ciepHPD:S:M:L:fw:?"
  #else /* !KERBEROS */
  #define ARGSTR	"rpPD:f?"
  #endif /* KERBEROS */
***************
*** 378,383 ****
--- 380,388 ----
  		   error_message(status));
  	    exit(1);
      }
+ 
+     /* Blow away any KRB5CCNAME passed from inetd */
+     unsetenv("KRB5CCNAME");
  #endif
      
      /* Analyse parameters. */
***************
*** 426,431 ****
--- 431,439 ----
  	case 'M':
  	  krb5_set_default_realm(bsd_context, optarg);
  	  break;
+ 	case 'H':
+ 	  require_hwpreauth = 1;
+ 	  break;
  #endif
  	case 'p':
  	  passwd_if_fail = 1; /* Passwd reqd if any check fails */
***************
*** 1144,1150 ****
  {
      pty_cleanup (line, pid, 1);
      shutdown(netf, 2);
!     if (ccache)
  	krb5_cc_destroy(bsd_context, ccache);
      exit(1);
  }
--- 1152,1158 ----
  {
      pty_cleanup (line, pid, 1);
      shutdown(netf, 2);
!     if (ccache && ! retain_ccache)
  	krb5_cc_destroy(bsd_context, ccache);
      exit(1);
  }
***************
*** 1253,1259 ****
  	}
  #endif
  
!     
  
      if (checksum_required && !valid_checksum) {
  	if (auth_sent & AUTH_KRB5) {
--- 1261,1271 ----
  	}
  #endif
  
!     if (require_hwpreauth && auth_sent & AUTH_KRB5 &&
! 	!(ticket->enc_part2->flags & TKT_FLG_HW_AUTH)) {
! 	    syslog(LOG_WARNING, "Client did not use hardware preauthentication--connection rejected.");
! 	    fatal(netf, "Hardware preauthetication is required on this machine.");
!     }
  
      if (checksum_required && !valid_checksum) {
  	if (auth_sent & AUTH_KRB5) {
***************
*** 1402,1412 ****
  
      if ((status = krb5_auth_con_init(bsd_context, &auth_context)))
          return status;
!  
      /* Only need remote address for rd_cred() to verify client */
      if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
  		 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
  	return status;
  
      status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
      if (status) return status;
--- 1414,1426 ----
  
      if ((status = krb5_auth_con_init(bsd_context, &auth_context)))
          return status;
! 
! #ifndef KRB5_MULTIHOMED_FIXES
      /* Only need remote address for rd_cred() to verify client */
      if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
  		 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
  	return status;
+ #endif /* !KRB5_MULTIHOMED_FIXES */
  
      status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
      if (status) return status;
***************
*** 1455,1460 ****
--- 1469,1480 ----
  	}
  	return status;
      }
+  
+ #ifdef KRB5_MULTIHOMED_FIXES
+     if (status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
+ 			KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
+ 	return status;
+ #endif /* KRB5_MULTIHOMED_FIXES */
  
      getstr(netf, lusername, sizeof (lusername), "locuser");
      getstr(netf, term, sizeof(term), "Terminal type");
***************
*** 1513,1518 ****
--- 1533,1542 ----
        krb5_free_authenticator(bsd_context, authenticator);
      }
  
+     /* Ok, now set addresses here so ticket forwarding will work */
+     if ((status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
+ 		 KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR)))
+ 	return status;
  
  #ifdef KRB5_KRB4_COMPAT
      if (auth_sys == KRB5_RECVAUTH_V4) {
***************
*** 1571,1576 ****
--- 1595,1605 ----
  					  ticket, &ccache))) {
           fatal(netf, "Can't get forwarded credentials");
      }
+ 
+     krb5_appdefault_boolean(bsd_context, "rlogind",
+ 			   krb5_princ_realm(bsd_context, client),
+ 			   "retain_ccache", retain_ccache, &retain_ccache);
+ 
      return 0;
  }
  
Index: krb5/appl/bsd/krsh.c
diff -c krb5/appl/bsd/krsh.c:1.1.1.2 krb5/appl/bsd/krsh.c:1.7
*** krb5/appl/bsd/krsh.c:1.1.1.2	Fri Feb 22 16:31:21 2002
--- krb5/appl/bsd/krsh.c	Mon Feb 25 22:28:56 2002
***************
*** 102,112 ****
--- 102,118 ----
  #endif
  
  int	encrypt_flag = 0;
+ int	encrypt_option_flag = -1;
  char	*krb_realm = (char *)0;
  void	try_normal();
  
  #endif /* KERBEROS */
  
+ #ifdef NOENCRYPTION
+ #define des_read read
+ #define des_write write
+ #endif /* NOENCRYPTION */
+ 
  #ifndef RLOGIN_PROGRAM
  #ifdef KERBEROS
  #define RLOGIN_PROGRAM KRB5_PATH_RLOGIN
***************
*** 148,153 ****
--- 154,160 ----
      krb5_error_code status;
      krb5_auth_context auth_context;
      int fflag = 0, Fflag = 0;
+     int no_forward = 0;
  #ifdef KRB5_KRB4_COMPAT
      KTEXT_ST v4_ticket;
      MSG_DAT v4_msg_data;
***************
*** 213,220 ****
       * Ignore -x from kerberos rlogin
       */
      if (argc > 0 && !strncmp(*argv, "-x", 2)) {
  	argv++, argc--;
! 	encrypt_flag++;
  	goto another;
      }
      if (argc > 0 && !strncmp(*argv, "-f", 2)) {
--- 220,237 ----
       * Ignore -x from kerberos rlogin
       */
      if (argc > 0 && !strncmp(*argv, "-x", 2)) {
+ #ifdef NOENCRYPTION
+ 	fprintf(stderr, "rsh: encryption not supported\n");
+ 	goto usage;
+ #else /* NOENCRYPTION */
  	argv++, argc--;
! 	encrypt_option_flag = 1;
! 	goto another;
! #endif /* NOENCRYPTION */
!     }
!     if (argc > 0 && !strncmp(*argv, "-X", 2)) {
! 	argv++, argc--;
! 	encrypt_option_flag = 0;
  	goto another;
      }
      if (argc > 0 && !strncmp(*argv, "-f", 2)) {
***************
*** 235,240 ****
--- 252,262 ----
  	argv++, argc--;
  	goto another;
      }
+     if (argc > 0 && !strncmp(*argv, "-N", 2)) {
+ 	no_forward++;
+ 	argv++, argc--;
+ 	goto another;
+     }
      if (argc > 0 && !strncmp(*argv, "-A", 2)) {
  	argv++, argc--;
  	goto another;
***************
*** 315,320 ****
--- 337,369 ----
  	fprintf(stderr, "who are you?\n");
  	exit(1);
      }
+ #ifdef KERBEROS
+     status = krb5_init_context(&bsd_context);
+     if (status) {
+ 	    com_err(argv[0], status, "while initializing krb5");
+ 	    exit(1);
+     }
+ 
+     {
+ 	krb5_data realm;
+ 	int eflag;
+ 
+ 	if (krb_realm) {
+ 		realm.data = krb_realm;
+ 	} else {
+ 		krb5_get_default_realm(bsd_context, &realm.data);
+ 	}
+ 
+ 	krb5_appdefault_boolean(bsd_context, "rsh", &realm, "encrypt", 0,
+ 				&eflag);
+ 
+ 	encrypt_flag = encrypt_option_flag == -1 ? eflag : encrypt_option_flag;
+ 
+ 	if (! krb_realm)
+ 		krb5_free_default_realm(bsd_context, realm.data);
+     }
+ #endif
+ 
      cc = 0;
      for (ap = argv; *ap; ap++)
        cc += strlen(*ap) + 1;
***************
*** 353,365 ****
      }
  
  #ifdef KERBEROS
-     status = krb5_init_context(&bsd_context);
-     if (status) {
- 	    com_err(argv[0], status, "while initializing krb5");
- 	    exit(1);
-     }
      authopts = AP_OPTS_MUTUAL_REQUIRED;
  
      /* Piggy-back forwarding flags on top of authopts; */
      /* they will be reset in kcmd */
      if (fflag || Fflag)
--- 402,426 ----
      }
  
  #ifdef KERBEROS
      authopts = AP_OPTS_MUTUAL_REQUIRED;
  
+     if (! (fflag || Fflag) && !no_forward) {
+ 	krb5_data realm;
+ 
+ 	if (krb_realm) {
+ 		realm.data = krb_realm;
+ 	} else {
+ 		krb5_get_default_realm(bsd_context, &realm.data);
+ 	}
+ 
+ 	krb5_appdefault_boolean(bsd_context, "rsh", &realm, "forward", 0,
+ 				&fflag);
+ 	krb5_appdefault_boolean(bsd_context, "rsh", &realm, "forwardable", 0,
+ 				&Fflag);
+ 	if (!krb_realm)
+ 		krb5_free_default_realm(bsd_context, realm.data);
+     }
+ 
      /* Piggy-back forwarding flags on top of authopts; */
      /* they will be reset in kcmd */
      if (fflag || Fflag)
***************
*** 608,622 ****
       * from arglist.
       *
       * We always want to call the Berkeley rsh as 'host mumble'
       */
!     host = strrchr(argv[0], '/');
!     if (host)
!       host++;
!     else
!       host = argv[0];
!     
!     if (!strcmp(host, "rsh"))
!       argv++;
      
      fprintf(stderr,"trying normal rsh (%s)\n",
  	    UCB_RSH);
--- 669,679 ----
       * from arglist.
       *
       * We always want to call the Berkeley rsh as 'host mumble'
+      *
+      * This is broken!  Always invoke it as "rsh ..."
       */
! 
!     argv[0] = "rsh";
      
      fprintf(stderr,"trying normal rsh (%s)\n",
  	    UCB_RSH);
Index: krb5/appl/bsd/krshd.c
diff -c krb5/appl/bsd/krshd.c:1.1.1.5 krb5/appl/bsd/krshd.c:1.15
*** krb5/appl/bsd/krshd.c:1.1.1.5	Fri Feb 22 16:31:22 2002
--- krb5/appl/bsd/krshd.c	Mon Feb 25 02:56:36 2002
***************
*** 71,76 ****
--- 71,77 ----
   */
       
  #define SERVE_NON_KRB     
+ #define LOG_ALL_LOGINS
  #define LOG_REMOTE_REALM
  #define LOG_CMD
     
***************
*** 109,114 ****
--- 110,116 ----
  #include <pwd.h>
  #include <ctype.h>
  #include <string.h>
+ #include <setjmp.h>
       
  #ifdef HAVE_SYS_LABEL_H
  /* only SunOS 4? */
***************
*** 180,186 ****
  #define MAXDNAME 256 /*per the rfc*/
  #endif
  
! #define ARGSTR	"ek54ciD:S:M:AP:?L:w:"
  
  
  
--- 182,188 ----
  #define MAXDNAME 256 /*per the rfc*/
  #endif
  
! #define ARGSTR	"ek54ciHD:S:M:AP:?L:w:"
  
  
  
***************
*** 196,206 ****
--- 198,212 ----
  int require_encrypt = 0;
  int do_encrypt = 0;
  int anyport = 0;
+ int retain_ccache = 0;
+ int afs_retain_token = 0;
+ int run_aklog = 0;
  char *kprogdir = KPROGDIR;
  int netf;
  int maxhostlen = 0;
  int stripdomain = 1;
  int always_ip = 0;
+ int require_hwpreauth = 0;
  
  #else /* !KERBEROS */
  
***************
*** 256,261 ****
--- 262,338 ----
  }
  #endif
  
+ typedef krb5_sigtype sigtype;
+ 
+ #ifndef POSIX_SETJMP
+ #undef sigjmp_buf
+ #undef sigsetjmp
+ #undef siglongjmp
+ #define sigjmp_buf      jmp_buf
+ #define sigsetjmp(j,s)  setjmp(j)
+ #define siglongjmp      longjmp
+ #endif
+ 
+ #if !defined(SIGSYS) && defined(__linux__)
+ /* Linux doesn't seem to have SIGSYS */
+ #define SIGSYS	SIGUNUSED
+ #endif
+ 
+ #ifdef POSIX_SIGNALS
+ typedef struct sigaction handler;
+ #define handler_init(H,F)		(sigemptyset(&(H).sa_mask), \
+ 					 (H).sa_flags=0, \
+ 					 (H).sa_handler=(F))
+ #define handler_swap(S,NEW,OLD)		sigaction(S, &NEW, &OLD)
+ #define handler_set(S,OLD)		sigaction(S, &OLD, NULL)
+ #else
+ typedef sigtype (*handler)();
+ #define handler_init(H,F)		((H) = (F))
+ #define handler_swap(S,NEW,OLD)		((OLD) = signal ((S), (NEW)))
+ #define handler_set(S,OLD)		(signal ((S), (OLD)))
+ #endif
+ 
+ #ifdef SETPAG
+ extern setpag(), ktc_ForgetAllTokens();
+ 
+ static int pagflag = 0;
+ 
+ static sigjmp_buf setpag_buf;
+ 
+ static sigtype sigsys()
+ {
+ 	siglongjmp(setpag_buf, 1);
+ }
+ 
+ static int try_afscall(scall)
+ 	int (*scall)();
+ {
+ 	handler sa, osa;
+ 	volatile int retval = 0;
+ 
+ 	(void) &retval;
+ 	handler_init(sa, sigsys);
+ 	handler_swap(SIGSYS, sa, osa);
+ 	if (sigsetjmp(setpag_buf, 1) == 0) {
+ 	    (*scall)();
+ 	    retval = 1;
+ 	}
+ 	handler_set(SIGSYS, osa);
+ 	return retval;
+ }
+ 
+ #define try_setpag()	try_afscall(setpag)
+ #define try_unlog()	try_afscall(ktc_ForgetAllTokens)
+ #endif /* SETPAG */
+ 
+ static void
+ afs_cleanup()
+ {
+ #ifdef SETPAG
+     if (pagflag)
+ 	try_unlog();
+ #endif /* SETPAG */
+ }
  
  int main(argc, argv)
       int argc;
***************
*** 300,305 ****
--- 377,385 ----
  		   error_message(status));
  	    exit(1);
      }
+ 
+     /* Blow away any KRB5CCNAME passed from inetd */
+     unsetenv("KRB5CCNAME");
  #endif
      
      /* Analyze parameters. */
***************
*** 346,351 ****
--- 426,435 ----
  	case 'M':
  	  krb5_set_default_realm(bsd_context, optarg);
  	  break;
+ 	
+ 	case 'H':
+ 	  require_hwpreauth = 1;
+ 	  break;
  
  	case 'A':
  	  anyport = 1;
***************
*** 581,586 ****
--- 665,671 ----
      syslog(LOG_INFO ,"Daemon terminated via signal %d.", signumber);
      if (ccache)
  	krb5_cc_destroy(bsd_context, ccache);
+     afs_cleanup();
      exit(0);
  }
  
***************
*** 592,597 ****
--- 677,683 ----
      char *cp;
  #ifdef KERBEROS
      krb5_error_code status;
+     int hardware;
  #endif
      int valid_checksum;
      int cnt;
***************
*** 795,801 ****
  	exit(1);
      }
  
!     if ((status = recvauth(f, fromaddr,&valid_checksum))) {
  	error("Authentication failed: %s\n", error_message(status));
  	exit(1);
      }
--- 881,887 ----
  	exit(1);
      }
  
!     if ((status = recvauth(f, fromaddr,&valid_checksum, &hardware))) {
  	error("Authentication failed: %s\n", error_message(status));
  	exit(1);
      }
***************
*** 1106,1111 ****
--- 1192,1202 ----
      }
  #endif /* KERBEROS */
  
+     if (require_hwpreauth && auth_sent & AUTH_KRB5 && !hardware) {
+ 	syslog(LOG_WARNING, "Client did not use hardware preauthentication--connection rejected.");
+ 	error("Hardware preauthetication is required on this machine.\n");
+ 	goto signout_please;
+     }
  
      if (checksum_required && !valid_checksum) {
  	if (auth_sent & AUTH_KRB5) {
***************
*** 1133,1139 ****
  	error("Logins currently disabled.\n");
  	goto signout_please;
      }
!     
      /* Log access to account */
      pwd = (struct passwd *) getpwnam(locuser);
      if (pwd && (pwd->pw_uid == 0)) {
--- 1224,1259 ----
  	error("Logins currently disabled.\n");
  	goto signout_please;
      }
! 
! #ifdef HP_EXEMPLAR_KRSHD_HACK
!     /*
!      * BIG HACK ALERT! vwelch@ncsa.uiuc.edu 4/28/98
!      *
!      * As best that I can tell there is a bug in the HP exemplar's
!      * networking code (at least under 10.01) that gets tickled by
!      * the code that handles the second port and/or encryption.
!      * The symptoms of the bug are that it causes krshd to get
!      * confused on the sequence number state and send a TCP RST
!      * every other connection when the same ports are being reused
!      * on both the client and the server (which is what rsh does).
!      * The result is that a rsh will fail every other time with
!      * a "protocol failure in circuit setup error" when rsh'ing to
!      * the exemplar.
!      *
!      * So, what this hack does is work around this bug by (1) turning
!      * off the second port code and (2) disallowing encryption. This
!      * hamstrings kshd, but at least makes it reliable.
!      */
!     /* Disable second port code */
!     port = 0;
! 
!     /* Disallow encryption */
!     if (do_encrypt) {
!       error("Encryption not supported.\n");
!       goto signout_please;
!     }
! #endif /* HP_EXEMPLAR_KRSHD_HACK */
! 
      /* Log access to account */
      pwd = (struct passwd *) getpwnam(locuser);
      if (pwd && (pwd->pw_uid == 0)) {
***************
*** 1170,1176 ****
  #endif
        }
  #endif
!     
      (void) write(2, "", 1);
      
      if (port||do_encrypt) {
--- 1290,1306 ----
  #endif
        }
  #endif
! 
! #ifdef IRIX_PROJECT_INIT
!     /*
!      * Initialize the magical IRIX array session, and the
!      * default project id.
!      */
! 	
!     newarraysess();
!     setprid(getdfltprojuser(locuser));
! #endif /* IRIX_PROJECT_INIT */
!   
      (void) write(2, "", 1);
      
      if (port||do_encrypt) {
***************
*** 1315,1322 ****
  #endif
  	    /* Finish session in wmtp */
  	    pty_logwtmp(ttyn,"","");
! 	    if (ccache)
  		krb5_cc_destroy(bsd_context, ccache);
  	    exit(0);
  	}
  #if defined(HAVE_SETSID)&&(!defined(ULTRIX))
--- 1445,1454 ----
  #endif
  	    /* Finish session in wmtp */
  	    pty_logwtmp(ttyn,"","");
! 	    if (ccache && ! retain_ccache)
  		krb5_cc_destroy(bsd_context, ccache);
+ 	    if (! afs_retain_token)
+ 		afs_cleanup();
  	    exit(0);
  	}
  #if defined(HAVE_SETSID)&&(!defined(ULTRIX))
***************
*** 1358,1372 ****
        pwd->pw_shell = "/bin/sh";
      (void) close(f);
      (void) setgid((gid_t)pwd->pw_gid);
! #ifndef sgi
      if (getuid() == 0 || getuid() != pwd->pw_uid) {
          /* For testing purposes, we don't call initgroups if we
             already have the right uid, and it is not root.  This is
             because on some systems initgroups outputs an error message
             if not called by root.  */
          initgroups(pwd->pw_name, pwd->pw_gid);
!     }
  #endif
  #ifdef	HAVE_SETLUID
      /*
       * If we're on a system which keeps track of login uids, then
--- 1490,1509 ----
        pwd->pw_shell = "/bin/sh";
      (void) close(f);
      (void) setgid((gid_t)pwd->pw_gid);
! /* #ifndef sgi */
      if (getuid() == 0 || getuid() != pwd->pw_uid) {
          /* For testing purposes, we don't call initgroups if we
             already have the right uid, and it is not root.  This is
             because on some systems initgroups outputs an error message
             if not called by root.  */
          initgroups(pwd->pw_name, pwd->pw_gid);
! #ifdef KERBEROS
! #ifdef SETPAG
! 	    pagflag = try_setpag();
! #endif
  #endif
+     }
+ /* #endif */
  #ifdef	HAVE_SETLUID
      /*
       * If we're on a system which keeps track of login uids, then
***************
*** 1456,1461 ****
--- 1593,1624 ----
      environ = envinit;
      
  #ifdef KERBEROS
+ 
+     /*
+      * Since we have to run aklog as the user, _not_ root, we need to run
+      * it now (if we're supposed to.  Do The Right Thing if run_aklog is
+      * set
+      */
+     if (run_aklog) {
+ 	char *aklog_path;
+ 	struct stat st;
+ 
+ 	krb5_appdefault_string(bsd_context, "rshd",
+ 			       krb5_princ_realm(bsd_context, client),
+ 			       "krb5_aklog_path", KPROGDIR "/aklog",
+ 			       &aklog_path);
+ 		
+ 	/*
+ 	 * Make sure it exists before we try to run it
+ 	 */
+ 		
+ 	if (stat (aklog_path, &st) == 0) {
+ 	    system(aklog_path);
+ 	}
+ 
+ 	free(aklog_path);
+     }
+ 
      /* To make Kerberos rcp work correctly, we must ensure that we
         invoke Kerberos rcp on this end, not normal rcp, even if the
         shell startup files change PATH.  */
***************
*** 1511,1516 ****
--- 1674,1680 ----
    signout_please:
      if (ccache)
  	krb5_cc_destroy(bsd_context, ccache);
+     afs_cleanup();
      ccache = NULL;
      pty_logwtmp(ttyn,"","");
      exit(1);
***************
*** 1773,1782 ****
  					      chars */
  
  krb5_error_code
! recvauth(netf, peersin, valid_checksum)
       int netf;
       struct sockaddr_in peersin;
       int *valid_checksum;
  {
      krb5_auth_context auth_context = NULL;
      krb5_error_code status;
--- 1937,1947 ----
  					      chars */
  
  krb5_error_code
! recvauth(netf, peersin, valid_checksum, hardware)
       int netf;
       struct sockaddr_in peersin;
       int *valid_checksum;
+      int *hardware;
  {
      krb5_auth_context auth_context = NULL;
      krb5_error_code status;
***************
*** 1815,1823 ****
--- 1980,1990 ----
      if (status = krb5_auth_con_init(bsd_context, &auth_context))
  	return status;
  
+ #ifndef KRB5_MULTIHOMED_FIXES
      if (status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
  			KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
  	return status;
+ #endif /* !KRB5_MULTIHOMED_FIXES */
  
      status = krb5_auth_con_getrcache(bsd_context, auth_context, &rcache);
      if (status) return status;
***************
*** 1876,1881 ****
--- 2043,2054 ----
  	return status;
      }
  
+ #ifdef KRB5_MULTIHOMED_FIXES
+     if (status = krb5_auth_con_genaddrs(bsd_context, auth_context, netf,
+ 			KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))
+ 	return status;
+ #endif /* KRB5_MULTIHOMED_FIXES */
+ 
      getstr(netf, locuser, sizeof(locuser), "locuser");
      getstr(netf, cmdbuf, sizeof(cmdbuf), "command");
  
***************
*** 1984,1989 ****
--- 2157,2168 ----
  	exit(1);
      }
  
+     /*
+      * Set the hardware flag if we have hardware preauth
+      */
+ 
+     *hardware = (ticket->enc_part2->flags & KDC_OPT_HW_AUTH) == KDC_OPT_HW_AUTH;
+ 
      if (inbuf.length) { /* Forwarding being done, read creds */
  	pwd = getpwnam(locuser);
  	if (!pwd) {
***************
*** 2003,2008 ****
--- 2182,2206 ----
  		  error_message(errno));
  	    exit(1);
  	}
+ 	/*
+ 	 * Check our appdefaults profile entry to see if we're supposed to
+ 	 * run aklog.  If so, then just set "run_aklog" for later; we
+ 	 * need to run aklog as the user, not as root
+ 	 */
+ 	
+ 	krb5_appdefault_boolean(bsd_context, "rshd",
+ 				krb5_princ_realm(bsd_context, client),
+ 				"krb5_run_aklog", 0, &run_aklog);
+ 	
+ 	krb5_appdefault_boolean(bsd_context, "rshd",
+ 				krb5_princ_realm(bsd_context, client),
+ 				"retain_ccache", retain_ccache,
+ 				&retain_ccache);
+ 	
+ 	krb5_appdefault_boolean(bsd_context, "rshd",
+ 				krb5_princ_realm(bsd_context, client),
+ 				"afs_retain_token", afs_retain_token,
+ 				&afs_retain_token);
      }
      krb5_free_ticket(bsd_context, ticket);
      return 0;
Index: krb5/appl/bsd/login.c
diff -c krb5/appl/bsd/login.c:1.1.1.5 krb5/appl/bsd/login.c:1.33
*** krb5/appl/bsd/login.c:1.1.1.5	Mon Aug 12 15:44:10 2002
--- krb5/appl/bsd/login.c	Mon Mar 10 15:24:44 2003
***************
*** 39,54 ****
     # use password to get v4 tickets
     krb4_convert = 1
     # use kerberos conversion daemon to get v4 tickets
!    krb_run_aklog = 1
     # attempt to run aklog
     aklog_path = $(prefix)/bin/aklog
!    # where to find it [not yet implemented]
     accept_passwd = 0
     # don't accept plaintext passwords [not yet implemented]
  */
  #define KRB5_GET_TICKETS
  int login_krb5_get_tickets = 1;
! 
  #ifdef KRB5_KRB4_COMPAT
  #define KRB4_GET_TICKETS
  int login_krb4_get_tickets = 0;
--- 39,73 ----
     # use password to get v4 tickets
     krb4_convert = 1
     # use kerberos conversion daemon to get v4 tickets
!    krb4_run_aklog = 1
     # attempt to run aklog
     aklog_path = $(prefix)/bin/aklog
!    # where to find it
     accept_passwd = 0
     # don't accept plaintext passwords [not yet implemented]
+    forwardable = 0
+    # The initial TGT is forwardable
+    krb5_run_aklog = 0
+    # Run a Kerberos 5 aklog (doesn't need Kerberos 4 credentials)
+    krb5_aklog_path = $(prefix)/bin/aklog
+    # Path to Kerberos 5 aklog
+    default_lifetime = (null)
+    # Default ticket lifetime (10 hours)
+    retain_ccache = 0
+    # Don't destroy the credential cache upon logout
+    afs_retain_token = 0
+    # Don't destroy AFS tokens upon logout
+    check_quota = 1
+    # Run "quota" to check the user's disk quota
  */
  #define KRB5_GET_TICKETS
  int login_krb5_get_tickets = 1;
! int login_krb5_forwardable_tgt = 0;
! int login_krb5_run_aklog = 0;
! int login_krb5_retain_ccache = 0;
! char *login_krb5_aklog_path = 0;
! char *login_krb5_default_lifetime = 0;
! int login_afs_retain_token = 0;
  #ifdef KRB5_KRB4_COMPAT
  #define KRB4_GET_TICKETS
  int login_krb4_get_tickets = 0;
***************
*** 59,64 ****
--- 78,84 ----
  #endif /* KRB5_KRB4_COMPAT */
  
  int login_accept_passwd = 0;
+ int login_check_quota = 1;
  
  /*
   * login [ name ]
***************
*** 79,86 ****
   * only one of: -r -h -k -K
   */
  
- #include <libpty.h>
- 
  #ifdef HAVE_UNISTD_H
  #include <unistd.h>
  #endif
--- 99,104 ----
***************
*** 108,113 ****
--- 126,139 ----
  #include <lastlog.h>
  #endif
  
+ #ifdef HAVE_SYS_CAPABILITY_H
+ #include <sys/capability.h>
+ #endif
+ 
+ #ifdef HAVE_SYS_RESOURCE_H
+ #include <sys/resource.h>
+ #endif
+ 
  #ifdef linux
  /* linux has V* but not C* in headers. Perhaps we shouldn't be
   * initializing these values anyway -- tcgetattr *should* give
***************
*** 115,120 ****
--- 141,153 ----
  #define NO_INIT_CC
  #endif
  
+ #ifdef sun
+ /* Under solaris: gcc defines __svr4__, cc doesn't define bsd */
+ #if defined(__svr4__) || !defined(bsd)
+ #define solaris
+ #endif /* __svr4 || !bsd */
+ #endif /* sun */
+ 
  #include <errno.h>
  #ifdef HAVE_TTYENT_H
  #include <ttyent.h>
***************
*** 135,140 ****
--- 168,178 ----
  #define siglongjmp	longjmp
  #endif
  
+ #if !defined(SIGSYS) && defined(__linux__)
+ /* Linux doesn't seem to have SIGSYS */
+ #define SIGSYS	SIGUNUSED
+ #endif
+ 
  #ifdef POSIX_SIGNALS
  typedef struct sigaction handler;
  #define handler_init(H,F)		(sigemptyset(&(H).sa_mask), \
***************
*** 154,159 ****
--- 192,216 ----
  #include <shadow.h>
  #endif
  
+ #ifdef HAVE_PRPASSWD
+ /*
+  * HPUX's protected (e.g. shadow) password database
+  * Note that the protected password database might exist, but
+  * be unused and have empty password fields! So if the password
+  * field in the protected password database is empty, fall back
+  * to the password field in the normal database.
+  */
+ #include <sys/types.h>
+ #include <hpsecurity.h>
+ /*
+  * Argh - this sucks. We need to include "/usr/include/prot.h" but
+  * specifying <prot.h> gets us kerberosIV/prot.h, so we have to use
+  * the full path name.
+  */
+ #include "/usr/include/prot.h"
+ 
+ #endif
+ 
  #ifdef KRB5_GET_TICKETS
  /* #include "krb5.h" */
  /* need k5-int.h to get ->profile from krb5_context */
***************
*** 200,205 ****
--- 257,264 ----
  #endif /*HAVE_KRB_GET_ERR_TEXT*/
  #endif /* KRB4 */
  
+ #include <libpty.h>
+ 
  #ifndef __STDC__
  #ifndef volatile
  #define volatile
***************
*** 235,240 ****
--- 294,303 ----
  #define TAB3 0
  #endif
  
+ #ifdef solaris
+ #include <dirent.h>
+ #endif /* solaris */
+ 
  #define	TTYGRPNAME	"tty"		/* name of group to own ttys */
  
  #if defined(_PATH_MAILDIR)
***************
*** 250,256 ****
  #if defined(_PATH_LASTLOG)
  #define LASTLOG		_PATH_LASTLOG
  #else
! #define LASTLOG		"/usr/adm/lastlog"
  #endif
  #if defined(_PATH_BSHELL)
  #define BSHELL		_PATH_BSHELL
--- 313,323 ----
  #if defined(_PATH_LASTLOG)
  #define LASTLOG		_PATH_LASTLOG
  #else
! #ifdef HAVE_VAR_ADM_LASTLOG
! #define	LASTLOG		"/var/adm/lastlog"
! #else /* HAVE_VAR_ADM_LASTLOG */
! #define	LASTLOG		"/usr/adm/lastlog"
! #endif /* HAVE_VAR_ADM_LASTLOG */
  #endif
  #if defined(_PATH_BSHELL)
  #define BSHELL		_PATH_BSHELL
***************
*** 307,323 ****
  					   passsword */
  #endif
  
! #if defined(__SVR4) || defined(sgi)
  #define NO_MOTD
  #define NO_MAILCHECK
  #endif
  
  char *getenv();
  void dofork();
  
  int doremotelogin(), do_krb_login(), rootterm();
  void lgetstr(), getloginname(), checknologin(), sleepexit();
  void dolastlog(), motd(), check_mail();
  
  #ifndef HAVE_STRSAVE
  char * strsave();
--- 374,396 ----
  					   passsword */
  #endif
  
! #if defined(__SVR4) || defined(sgi) || defined(__svr4__) || defined(__hpux)
  #define NO_MOTD
  #define NO_MAILCHECK
  #endif
  
+ #ifdef USE_LOGIN_CONF
+ static char *get_login_conf();
+ static char **read_login_confs();
+ #endif /* USE_LOGIN_CONF */
+ 
  char *getenv();
  void dofork();
  
  int doremotelogin(), do_krb_login(), rootterm();
  void lgetstr(), getloginname(), checknologin(), sleepexit();
  void dolastlog(), motd(), check_mail();
+ void print_issue();
  
  #ifndef HAVE_STRSAVE
  char * strsave();
***************
*** 343,354 ****
--- 416,432 ----
  } login_conf_set[] = {
  #ifdef KRB5_GET_TICKETS
      "krb5_get_tickets", &login_krb5_get_tickets,
+     "forwardable", &login_krb5_forwardable_tgt,
  #endif
  #ifdef KRB5_KRB4_COMPAT
      "krb4_get_tickets", &login_krb4_get_tickets,
      "krb4_convert", &login_krb4_convert,
      "krb4_run_aklog", &login_krb_run_aklog,
  #endif /* KRB5_KRB4_COMPAT */
+     "krb5_run_aklog", &login_krb5_run_aklog,
+     "retain_ccache", &login_krb5_retain_ccache,
+     "afs_retain_token", &login_afs_retain_token,
+     "check_quota", &login_check_quota,
  };
  
  static char *conf_yes[] = {
***************
*** 361,366 ****
--- 439,451 ----
      0
  };
  
+ static struct login_conf_strings {
+ 	char *confname;
+ 	char **varname;
+ } login_string_set[] = {
+ 	"krb5_aklog_path",	&login_krb5_aklog_path,
+ 	"default_lifetime",	&login_krb5_default_lifetime,
+ };
  /* 1 = true, 0 = false, -1 = ambiguous */
  static int conf_affirmative(s)
       char *s;
***************
*** 397,429 ****
      const char* kconf_names[3];
      char **kconf_val;
      int retval;
  
      max_i = sizeof(login_conf_set)/sizeof(struct login_confs);
      for (i = 0; i<max_i; i++) {
! 	kconf_names[0] = "login";
! 	kconf_names[1] = login_conf_set[i].flagname;
! 	kconf_names[2] = 0;
! 	retval = profile_get_values(k->profile, 
! 				    kconf_names, &kconf_val);
! 	if (retval) {
! 	    /* ignore most (all?) errors */
! 	} else if (kconf_val && *kconf_val) {
! 	    switch(conf_affirmative(*kconf_val)) {
! 	    case 1:
! 		*login_conf_set[i].flag = 1;
! 		break;
! 	    case 0:
! 		*login_conf_set[i].flag = 0;
! 		break;
! 	    default:
! 	    case -1:
! 		com_err("login/kconf", 0,
! 			"invalid flag value %s for flag %s",
! 			*kconf_val, kconf_names[1]);
! 		break;
! 	    }
  	}
      }
  }
  
  /* UNIX password support */
--- 482,511 ----
      const char* kconf_names[3];
      char **kconf_val;
      int retval;
+     krb5_data v5_realm;
+ 
+     krb5_get_default_realm(k, &v5_realm.data);
  
      max_i = sizeof(login_conf_set)/sizeof(struct login_confs);
      for (i = 0; i<max_i; i++) {
! 	krb5_appdefault_boolean(k, "login", &v5_realm,
! 				login_conf_set[i].flagname,
! 				*login_conf_set[i].flag,
! 				login_conf_set[i].flag);
!     }
! 
!     max_i = sizeof(login_string_set) / sizeof(struct login_conf_strings);
!     for (i = 0; i < max_i; i++) {
! 	krb5_appdefault_string(k, "login", &v5_realm,
! 			       login_string_set[i].confname,
! 			       "", login_string_set[i].varname);
! 	if (!login_string_set[i].varname[0]) {
! 		free(login_string_set[i].varname);
! 		login_string_set[i].varname = NULL;
  	}
      }
+ 
+     krb5_free_default_realm(k, v5_realm.data);
  }
  
  /* UNIX password support */
***************
*** 435,440 ****
--- 517,526 ----
  struct spwd *spwd;
  #endif
  
+ #ifdef HAVE_PRPASSWD
+ struct pr_passwd *prpwd = NULL;
+ #endif
+ 
  void lookup_user (name)
      char *name;
  {
***************
*** 445,454 ****
--- 531,554 ----
      if (spwd)
  	salt = spwd->sp_pwdp;
  #endif
+ #ifdef HAVE_PRPASSWD
+     prpwd = getprpwnam(name);
+     if (prpwd && (prpwd->ufld.fd_encrypt[0] != 0))
+ 	salt = prpwd->ufld.fd_encrypt;
+ #endif
  }
  
  int unix_needs_passwd ()
  {
+ #ifdef HAVE_PRPASSWD
+     /*
+      * If the password field in the protected password database
+      * is empty, there still might be a password in the normal
+      * password database, so fall through.
+      */
+     if (prpwd && (prpwd->ufld.fd_encrypt[0] != 0))
+ 	return 1;
+ #endif
  #ifdef HAVE_SHADOW
      if (spwd)
  	return spwd->sp_pwdp[0] != 0;
***************
*** 466,471 ****
--- 566,580 ----
  
      assert (pwd != 0);
  
+ #ifdef HAVE_PRPASSWD
+     /*
+      * If the protected password field is empty, fall through
+      * and use the password inthe normal password database.
+      */
+     if (prpwd && (prpwd->ufld.fd_encrypt[0] != 0))
+ 	return prpasswd_ok(pass, salt, prpwd);
+ #endif
+ 
      /* copy the first 8 chars of the password for unix crypt */
      strncpy(user_pwcopy, pass, sizeof(user_pwcopy));
      user_pwcopy[sizeof(user_pwcopy) - 1]='\0';
***************
*** 559,564 ****
--- 668,680 ----
      sprintf(prompt,"Password for %s: ", username);
  
      /* reduce opportunities to be swapped out */
+ #ifdef sgi
+     /*
+      * A bug on IRIX will occasionally eat the first character.  Write
+      * a NUl to fix this
+      */
+     putchar('\0');
+ #endif
      code = krb5_read_password(kcontext, prompt, 0, user_pwstring, &pwsize);
      if (code || pwsize == 0) {
  	fprintf(stderr, "Error while reading password for '%s'\n", username);
***************
*** 579,584 ****
--- 695,716 ----
  {
      krb5_error_code code;
      krb5_principal me;
+     krb5_get_init_creds_opt options;
+ 
+     /*
+      * Set defaults based on the [appdefaults] profile
+      */
+ 
+     krb5_get_init_creds_opt_init(&options);
+ 
+     if (login_krb5_forwardable_tgt)
+ 	krb5_get_init_creds_opt_set_forwardable(&options, 1);
+ 
+     if (login_krb5_default_lifetime && *login_krb5_default_lifetime) {
+ 	krb5_deltat lifetime;
+ 	if (! krb5_string_to_deltat(login_krb5_default_lifetime, &lifetime))
+ 	    krb5_get_init_creds_opt_set_tkt_life(&options, lifetime);
+     }
  
      if (code = krb5_parse_name(kcontext, username, &me)) {
  	com_err ("login", code, "when parsing name %s",username);
***************
*** 589,595 ****
  
      if (code = krb5_get_init_creds_password(kcontext, &my_creds, me, pass,
  					    krb5_prompter_posix, NULL,
! 					    0, NULL, NULL)) {
  	if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
  	    fprintf (stderr,
  		     "%s: Kerberos password incorrect\n", 
--- 721,727 ----
  
      if (code = krb5_get_init_creds_password(kcontext, &my_creds, me, pass,
  					    krb5_prompter_posix, NULL,
! 					    0, NULL, &options)) {
  	if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
  	    fprintf (stderr,
  		     "%s: Kerberos password incorrect\n", 
***************
*** 905,920 ****
  #endif /* SIGSYS */
  #endif /* SETPAG */
  
  void
! afs_login ()
  {
! #if defined(KRB4_GET_TICKETS) && defined(SETPAG)
!     if (login_krb4_get_tickets && pwd->pw_uid) {
  	/* Only reset the pag for non-root users. */
  	/* This allows root to become anything. */
  	pagflag = try_setpag ();
      }
! #endif
  #ifdef KRB_RUN_AKLOG
      if (got_v4_tickets && login_krb_run_aklog) {
  	/* KPROGDIR is $(prefix)/bin */
--- 1037,1081 ----
  #endif /* SIGSYS */
  #endif /* SETPAG */
  
+ /*
+  * Since we have to allocate a PAG _before_ we fork, we need to move
+  * this into a separate function.
+  */
+ 
  void
! krb_afs_setpag()
  {
! 	/* Allocating a PAG isn't that harmful ... */
! #ifdef SETPAG
! #ifdef SETPAG_ALWAYS
! 	/* Always set a pag, even for root */
! 	pagflag = try_setpag ();
! #else /* SETPAG_ALWAYS */
!     if ( (
! #ifdef KRB4_GET_TICKETS
! 	login_krb4_get_tickets
! #else /* KRB4_GET_TICKETS */
! 	1
! #endif
! 	||
! #ifdef KRB5_GET_TICKETS
! 	login_krb5_get_tickets
! #else
! 	1
! #endif /* KRB5_GET_TICKETS */
! 	) && pwd->pw_uid) {
  	/* Only reset the pag for non-root users. */
  	/* This allows root to become anything. */
  	pagflag = try_setpag ();
      }
! #endif /* SETPAG_ALWAYS */
! #endif /* SETPAG */
! }
! 
! void
! afs_login (me)
!     krb5_principal *me;
! {
  #ifdef KRB_RUN_AKLOG
      if (got_v4_tickets && login_krb_run_aklog) {
  	/* KPROGDIR is $(prefix)/bin */
***************
*** 929,940 ****
  	if (stat (aklog_path, &st) == 0) {
  	    system(aklog_path);
  	}
!     }
  #endif /* KRB_RUN_AKLOG */
  }
  
  void
! afs_cleanup ()
  {
  #ifdef SETPAG
      if (pagflag)
--- 1090,1130 ----
  	if (stat (aklog_path, &st) == 0) {
  	    system(aklog_path);
  	}
!     } else
  #endif /* KRB_RUN_AKLOG */
+ #ifdef KRB5_GET_TICKETS
+     /*
+      * Note that we check to see if we have valid credentials already
+      * in place here (because we might have forwarded them)
+      */
+     if (login_krb5_run_aklog && (got_v5_tickets || have_v5_tickets(me))) {
+ 	/*
+ 	 * Check the profile for a path to aklog, otherwise use the
+ 	 * default of KPROGDIR
+ 	 */
+ 	char aklog_path[MAXPATHLEN];
+ 	struct stat st;
+ 
+ 	if (login_krb5_aklog_path && *login_krb5_aklog_path) {
+ 		strcpy(aklog_path, login_krb5_aklog_path);
+ 	} else {
+ 		strcpy(aklog_path, KPROGDIR);
+ 		strcat(aklog_path, "/aklog");
+ 	}
+ 	/*
+ 	 * Make sure it's there
+ 	 */
+ 	if (stat (aklog_path, &st) == 0) {
+ 	    system(aklog_path);
+ 	}
+     }
+ #else
+ 	{ }
+ #endif /* KRB5_GET_TICKETS */
  }
  
  void
! krb_afs_cleanup ()
  {
  #ifdef SETPAG
      if (pagflag)
***************
*** 1216,1221 ****
--- 1406,1414 ----
      openlog("login", LOG_ODELAY, LOG_AUTH);
  #endif /* 4.2 syslog */
  
+ 	/* print /etc/issue */
+ 	print_issue();
+ 
  /******* begin askpw *******/
      /* overall:
         ask for username if we don't have it already
***************
*** 1421,1434 ****
      }
  #endif
  
-     if (chdir(pwd->pw_dir) < 0) {
- 	printf("No directory %s!\n", pwd->pw_dir);
- 	if (chdir("/"))
- 	    exit(0);
- 	pwd->pw_dir = "/";
- 	printf("Logging in with home = \"/\".\n");
-     }
- 
      /* nothing else left to fail -- really log in */
      {
  	struct utmp utmp;
--- 1614,1619 ----
***************
*** 1440,1445 ****
--- 1625,1635 ----
  	    com_err (argv[0], retval, "while updating utmp");
      }
  
+ #if defined(sun)
+ 	/* Set owner/group/permissions of framebuffer devices */
+ 	(void) set_fb_attrs(ttyn, pwd->pw_uid, pwd->pw_gid);
+ #endif
+ 
      quietlog = access(HUSHLOGIN, F_OK) == 0;
      dolastlog(quietlog, tty);
  
***************
*** 1527,1535 ****
--- 1717,1792 ----
  	    perror("login.krb5: sigaction(SIGTTOU, [old handler])");
      }
  
+ #ifdef HAS_JLIMIT_STARTJOB
+ 	/*
+ 	 * If we have jlimit_startjob, we need to do extra stuff at
+ 	 * login time (and we don't do the old project init stuff)
+ 	 */
+ 	{
+ 	    jid_t jid;
+ 	    cap_value_t capv;
+ 	    cap_t ocap;
+ 
+ 	    capv = CAP_SETUID, ocap = cap_acquire (1, &capv);
+ 	    jid = jlimit_startjob(username, pwd->pw_uid, "interactive");
+ 	    if (jid == -1) {
+ 		syslog(LOG_ALERT|LOG_AUTH, "Unable to create job for '%s'.\n",
+ 		       username);
+ 		newarraysess();
+ 	    } else if (jid == 0)
+ 		newarraysess();
+ 	    else
+ 		syslog(LOG_NOTICE, "Created Job Container = 0x%llx\n", jid);
+ 	    setprid(getdfltprojuser(username));
+ 	    cap_surrender(ocap);
+ 	}
+ #else /* HAS_JLIMIT_STARTJOB */
+ #ifdef IRIX_PROJECT_INIT
+ 	/*
+ 	 * Initialize the magical IRIX array session, and the
+ 	 * default project id.
+ 	 */
+ 	
+ 	newarraysess();
+ 	setprid(getdfltprojuser(username));
+ #endif /* IRIX_PROJECT_INIT */
+ #endif /* HAS_JLIMIT_START_JOB */
+ 
+ #ifdef HAS_CAP_SET_PROC
+ 	/*
+ 	 * Initialize process capabilities
+ 	 *
+ 	 * Note that this is currently a hack. We really should read
+ 	 * /etc/capability and set based on it's contents. For now
+ 	 * though we just want to clear the capabilites if we're not
+ 	 * root so users don't run into problems.
+ 	 */
+ 	if (pwd->pw_uid != 0) {
+ 	    cap_set_t cap;
+ 
+ 	    cap.cap_effective = CAP_ALL_OFF;
+ 	    cap.cap_permitted = CAP_ALL_OFF;
+ 	    cap.cap_inheritable = CAP_ALL_OFF;
+ 
+ 	    if (cap_set_proc(&cap) == -1) {
+ 		
+ 		switch(errno) {
+ 		case ENOSYS:
+ 		    /* Function not implemented. Fail silently. */
+ 		    break;
+ 		       
+ 		default:
+ 		    perror("cap_set_proc()");
+ 		}
+ 	    }
+ 	}
+ #endif /* HAS_CAP_SET_PROC */
+ 
      (void) setgid((gid_t) pwd->pw_gid);
      (void) initgroups(username, pwd->pw_gid);
  
+     krb_afs_setpag();
+ 
      /*
       * The V5 ccache and V4 ticket file are both created as root.
       * They need to be owned by the user, and chown (a) assumes
***************
*** 1636,1641 ****
--- 1893,1906 ----
  	sleepexit(1);
      }
  
+     if (chdir(pwd->pw_dir) < 0) {
+ 	printf("No directory %s!\n", pwd->pw_dir);
+ 	if (chdir("/"))
+ 	    exit(0);
+ 	pwd->pw_dir = "/";
+ 	printf("Logging in with home = \"/\".\n");
+     }
+ 
      /*
       * We are the user now.  Re-create the destroyed ccache and
       * ticket file.
***************
*** 1807,1817 ****
  			   tty, hostname);
  #endif
  		} else {
! 		    syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
  		}
  	    }
  
!     afs_login();
  
      if (!quietlog) {
  #ifdef KRB4_KLOGIN
--- 2072,2101 ----
  			   tty, hostname);
  #endif
  		} else {
! 			syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
  		}
  	    }
+ 	else
+ 		if (hostname)
+ 			syslog(LOG_INFO, "%s %slogin on %s from %s",
+ 			       pwd->pw_name,
+ #ifdef LOG_PREAUTH_LOGINS
+ 			       fflag ? "preauthenticated " : "password ",
+ #else /* LOG_PREAUTH_LOGINS */
+ 			       "",
+ #endif /* ! LOG_PREAUTH_LOGINS */
+ 			       tty, hostname);
+ 		else
+ 			syslog(LOG_INFO, "%s %slogin on %s",
+ 			       pwd->pw_name,
+ #ifdef LOG_PREAUTH_LOGINS
+ 			       fflag ? "preauthenticated " : "password ",
+ #else /* LOG_PREAUTH_LOGINS */
+ 			       "",
+ #endif /* ! LOG_PREAUTH_LOGINS */
+ 			       tty);
  
!     afs_login(me);
  
      if (!quietlog) {
  #ifdef KRB4_KLOGIN
***************
*** 1823,1829 ****
      }
  
  #ifndef OQUOTA
!     if (! access( QUOTAWARN, X_OK))
  	(void) system(QUOTAWARN);
  #endif
  
--- 2107,2113 ----
      }
  
  #ifndef OQUOTA
!     if (login_check_quota && ! access( QUOTAWARN, X_OK))
  	(void) system(QUOTAWARN);
  #endif
  
***************
*** 1994,2001 ****
--- 2278,2306 ----
      register int ch;
      register char *p;
      static char nbuf[UT_NAMESIZE + 1];
+ #ifdef solaris
+     char *ttyprompt = NULL;
+     static int firsttime = 1;
+ #endif
  
      for (;;) {
+ #ifdef solaris
+ 	/*
+ 	 * getty prints 'login:' for us, so we want to avoid printing
+ 	 * it again. getty also sets the environment variable TTYPROMPT
+ 	 * so if it is present, don't print the login prompt.
+ 	 *
+ 	 * However, we only want to do this the first time through.
+ 	 */
+ 	ttyprompt = getenv("TTYPROMPT");
+ 		
+ 	if ((ttyprompt) && (*ttyprompt != '\0')) {
+ 		if (! firsttime)
+ 			printf("%s", ttyprompt);
+ 		else
+ 			firsttime = 0;
+ 	} else
+ #endif /* solaris */
  	printf("login: ");
  	for (p = nbuf; (ch = getchar()) != '\n'; ) {
  	    if (ch == EOF)
***************
*** 2029,2034 ****
--- 2334,2363 ----
  int rootterm(tty)
  	char *tty;
  {
+ #ifdef USE_LOGIN_CONF
+ 	{
+ 		/*
+ 		 * Check to see if the tty matches the console tty
+ 		 * specified in the login configuration file
+ 		 */
+ 		char *console_tty;
+ 
+ 		console_tty = get_login_conf("CONSOLE");
+ 
+ 		if (console_tty != NULL) {
+ 		  /* Need to remove '/dev/' if it's there */
+ 		  if (strncmp(console_tty, "/dev/", 5) == 0)
+ 			console_tty += 5;
+ 
+ 		  return (strcmp(console_tty, tty) == 0);
+ 		}
+ 	}
+ #endif /* USE_LOGIN_CONF */
+ 
+ #ifdef __linux
+ 	 return check_securetty(tty);
+ #else /* __linux */
+ 
  #ifndef HAVE_TTYENT_H
      return(root_tty_security);
  #else
***************
*** 2036,2041 ****
--- 2365,2371 ----
  
      return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
  #endif /* HAVE_TTYENT_H */
+ #endif /* __linux */
  }
  
  #ifndef NO_MOTD
***************
*** 2069,2074 ****
--- 2399,2432 ----
  }
  #endif
  
+ #ifdef PRINT_ISSUE
+ sigjmp_buf issue_interrupt;
+ sigtype
+ issue_sigint()
+ {
+ 	siglongjmp(issue_interrupt, 1);
+ }
+ 
+ void print_issue()
+ {
+ 	register int fd, nchars;
+ 	char tbuf[8192];
+ 	handler sa, osa;
+ 
+ 	if ((fd = open(ISSUE_FILE, O_RDONLY, 0)) < 0)
+ 		return;
+ 	handler_init (sa, issue_sigint);
+ 	handler_swap (SIGINT, sa, osa);
+ 	if (sigsetjmp(issue_interrupt, 1) == 0)
+ 		while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
+ 			(void)write(fileno(stdout), tbuf, nchars);
+ 	handler_set (SIGINT, osa);
+ 	(void)close(fd);
+ }
+ #else
+ void print_issue() { }
+ #endif
+ 
  #ifndef NO_MAILCHECK
  void check_mail()
  {
***************
*** 2398,2405 ****
      
      /* Cleanup stuff */
      /* Run destroy_tickets to destroy tickets */
!     (void) destroy_tickets();		/* If this fails, we lose quietly */
!     afs_cleanup ();
  #ifdef _IBMR2
      update_ref_count(-1);
  #endif
--- 2756,2766 ----
      
      /* Cleanup stuff */
      /* Run destroy_tickets to destroy tickets */
!     if (! login_krb5_retain_ccache)
!         (void) destroy_tickets();	/* If this fails, we lose quietly */
! 
!     if (! login_afs_retain_token)
! 	krb_afs_cleanup();
  #ifdef _IBMR2
      update_ref_count(-1);
  #endif
***************
*** 2475,2477 ****
--- 2836,3230 ----
      enduserdb();
  }
  #endif
+ 
+ #if defined(sun)
+ /*
+  * set_fb_attrs -- change owner/group/permissions of framebuffers
+  *		   listed in /etc/fbtab.
+  *
+  * Note:
+  * Exiting from set_fb_attrs upon error is not advisable
+  * since it would disable logins on console devices.
+  *
+  * File format:
+  * console mode device_name[:device_name ...]
+  * # begins a comment and may appear anywhere on a line.
+  *
+  * Example:
+  * /dev/console 0660 /dev/fb:/dev/cgtwo0:/dev/bwtwo0
+  * /dev/console 0660 /dev/gpone0a:/dev/gpone0b
+  *
+  * Description:
+  * The example above sets the owner/group/permissions of the listed
+  * devices to uid/gid/0660 if ttyn is /dev/console
+  */
+ 
+ #define	FIELD_DELIMS 	" \t\n"
+ #define	COLON 		":"
+ #define COLON_C         ':'
+ #define WILDCARD        "/*"
+ #define WILDCARD_LEN    2
+ #define MAX_LINELEN     256
+ #ifdef solaris
+ #define FBTAB           "/etc/logindevperm"
+ #else /* solaris */
+ #define FBTAB           "/etc/fbtab"
+ #endif /* solaris */
+ 
+ 
+ set_fb_attrs(ttyn, uid, gid)
+ 	char *ttyn;
+ 	int uid;
+ 	int gid;
+ {
+ 	char line[MAX_LINELEN];
+ 	char *console;
+ 	char *mode_str;
+ 	char *dev_list;
+ 	char *device;
+ 	char *ptr;
+ 	int  mode;
+ 	long strtol();
+ 	FILE *fp;
+ 
+ 	if ((fp = fopen(FBTAB, "r")) == NULL)
+ 		return;
+ 	while (fgets(line, MAX_LINELEN, fp)) {
+ 		if (ptr = strchr(line, '#'))
+ 			*ptr = '\0';	/* handle comments */
+ 		if ((console = strtok(line, FIELD_DELIMS)) == NULL)
+ 			continue;	/* ignore blank lines */
+ 		if (strcmp(console, ttyn) != 0)
+ 			continue;	/* ignore non-consoles */
+ 		mode_str = strtok((char *)NULL, FIELD_DELIMS);
+ 		if (mode_str == NULL) {
+ 			(void) fprintf(stderr, "%s: invalid entry -- %s\n",
+ 				FBTAB, line);
+ 			continue;
+ 		}
+ 		/* convert string to octal value */
+ 		mode = (int) strtol(mode_str, (char **)NULL, 8);
+ 		if (mode < 0 || mode > 0777) {
+ 			(void) fprintf(stderr, "%s: invalid mode -- %s\n",
+ 				FBTAB, mode_str);
+ 			continue;
+ 		}
+ 		dev_list = strtok((char *)NULL, FIELD_DELIMS);
+ 		if (dev_list == NULL) {
+ 			(void) fprintf(stderr, "%s: %s -- empty device list\n",
+ 				FBTAB, console);
+ 			continue;
+ 		}
+ #ifdef solaris
+ 		device = strtok(dev_list, COLON);
+ 		while (device) {
+ 		    ptr = strstr(device, WILDCARD);
+ 		    if (ptr && 
+ 			(strlen(device) - (ptr - &device[0])) == WILDCARD_LEN){
+ 			/* The device was a (legally-specified) directory. */
+ 			DIR           *dev_dir;
+ 			struct dirent *dir_e;
+ 			char dev_file[MAXPATHLEN];
+ 			
+ 			*ptr = '\0'; /* Remove the wildcard from the dir name. */
+ 
+ 			if ((dev_dir = opendir(device)) == (DIR *) NULL) {
+ 			    syslog(LOG_ERR, "bad device %s%s in %s, ignored",
+ 				   device, WILDCARD, FBTAB);
+ 			    continue;
+ 			}
+ 			
+ 			/* Directory is open; alter its files. */
+ 			/* Must link with /usr/lib/libc.a before 
+ 			   /usr/ucblib/libucb.a or the d_name structs
+ 			   miss the first two characters of the filename */
+ 			while (dir_e = readdir(dev_dir)) {
+ 			    if (strcmp(dir_e->d_name, "..") &&
+ 				strcmp(dir_e->d_name, ".")) {
+ 				strcpy(dev_file, device);
+ 				strcat(dev_file, "/");
+ 				strcat(dev_file, dir_e->d_name);
+ 
+ 				(void) chown(dev_file, uid, gid);
+ 				(void) chmod(dev_file, mode);
+ 			    }
+ 			}
+ 			(void) closedir(dev_dir);
+ 		    } else {
+ 			/* 'device' was not a directory, so we can just do it. */
+ 			(void) chown(device, uid, gid);
+ 			(void) chmod(device, mode);
+ 		    }
+ 		    device = strtok((char *)NULL, COLON); /* Move thru list. */
+ #else /* solaris */
+ 		device = strtok(dev_list, COLON);
+ 		while (device) {
+ 			(void) chown(device, uid, gid);
+ 			(void) chmod(device, mode);
+ 			device = strtok((char *)NULL, COLON);
+ #endif /* solaris */
+ 		}
+ 	}
+ 	(void) fclose(fp);
+ }
+ #endif /* sun */
+ 
+ 
+ #ifdef USE_LOGIN_CONF
+ 
+ static char *get_login_conf(char *value)
+ {
+ 	static char **login_confs = NULL;
+ 	char **string;
+ 
+ 	if (value == NULL) {
+ 		return NULL;
+ 	}
+ 
+ 	if (login_confs == NULL) {
+ 		login_confs = read_login_confs();
+ 
+ 		if (login_confs == NULL)
+ 			return NULL;
+ 	}
+ 
+ 	for (string = login_confs; *string != NULL; string++) {
+ 		char *s;
+ 
+ 		if (strncmp(value, *string, strlen(value)) != 0)
+ 			continue;
+ 
+ 		s = *string + strlen(value);
+ 
+ 		if (*s != '=')
+ 			continue;
+ 
+ 		s++;
+ 
+ 		return s;
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+ #ifndef LOGIN_CONF_BUFFER_SIZE
+ /*
+  * Size of buffer used to read the login configuration file.
+  * If the file has lines longer than this size, you may
+  * run into problems.
+  */
+ #define LOGIN_CONF_BUFFER_SIZE		256
+ #endif
+ 
+ char **read_login_confs()
+ {
+ 	FILE *fconfs = NULL;
+ 	char **confs = NULL;
+ 	int size = 0;
+ 	int num_confs = 0;
+ 
+ 
+ 	fconfs = fopen(LOGIN_CONF_FILE, "r");
+ 
+ 	if (fconfs == NULL) {
+ 		syslog(LOG_ERR, "Could not open login configuration file %s", 
+ 					 LOGIN_CONF_FILE);
+ 		return NULL;
+ 	}
+ 
+ 	while(!feof(fconfs)) {
+ 		char buffer[LOGIN_CONF_BUFFER_SIZE];
+ 		const char *whitespace = " \t\n";
+ 		char *start;
+ 		char *c;
+ 
+ 		if (fgets(buffer, sizeof(buffer), fconfs) == NULL)
+ 		  break;
+ 
+ 		/* Remove comment */
+ 		c = strchr(buffer, '#');
+ 		if (c != NULL)
+ 			*c = '\0';
+ 
+ 		/* Remove preceding whitespace */
+ 		start = buffer + strspn(buffer, whitespace);
+ 
+ 		/* Remove trailing whitespace */
+ 		c = start + strcspn(start, whitespace);
+ 		*c = '\0';
+ 
+ 		/* If there is anything left add it to our array */
+ 		if (strlen(start) > 0) {
+ 			char *copy;
+ 			
+ 			/*
+ 			 * Make sure there is room on the array for this string
+ 			 * and the NULL terminator
+ 			 */
+ 			if ((num_confs + 1) > size) {
+ 
+ 				size += 10;
+ 
+ 				confs = realloc(confs, size * sizeof(char *));
+ 
+ 				if (!confs) {
+ 					syslog(LOG_ERR, "realloc() failed: %m");
+ 					goto error;
+ 				}
+ 			}
+ 
+ 			copy = strdup(start);
+ 
+ 			if (copy == NULL) {
+ 				syslog(LOG_ERR, "strdup() failed: %m");
+ 				goto error;
+ 			}
+ 
+ 			confs[num_confs] = copy;
+ 
+ 			num_confs++;
+ 
+ 			/* Terminate the list */
+ 			confs[num_confs] = NULL;
+ 		}
+ 	}
+ 
+ 	fclose(fconfs);
+ 	return confs;
+ 
+  error:
+ 	/* An unrecoverable error occurred */
+ 
+ 	fclose(fconfs);
+ 
+ 	if (confs != NULL) {
+ 		char **s;
+ 
+ 		for (s = confs; *s != NULL; s++)
+ 			free(*s);
+ 
+ 		free(confs);
+ 	}
+ 
+ 	return NULL;
+ }
+ 
+ #endif /* USE_LOGIN_CONF */
+ 
+ #ifdef __linux
+ 
+ /*
+  * getttynam() fails under Linux (it always returns 0).
+  * I stole this source below from Linux's login program.
+  *                              - vwelch  4/20/98
+  */
+ #ifndef SECURETTY
+ #define SECURETTY	"/etc/securetty"
+ #endif
+ 
+ /* Return 1 if root is allowed to login on this tty, 0 otherwise  */
+ int check_securetty(char *tty)
+ {
+ 	int fd;
+ 	char buf[100],*p;
+ 	int cnt, more;
+     
+ 	fd = open(SECURETTY, O_RDONLY);
+ 	if(fd < 0) return 1;
+     
+ 	/* read each line in /etc/securetty, if a line matches our ttyline
+ 	   then root is allowed to login on this tty, and we should return
+ 	   true. */
+ 	for(;;) {
+ 		p = buf; cnt = 100;
+ 		while(--cnt >= 0 &&
+ 		      (more = read(fd, p, 1)) == 1 &&
+ 		      *p != '\n') p++;
+ 		if(more && *p == '\n') {
+ 			*p = '\0';
+ 			if(!strcmp(buf, tty)) {
+ 				close(fd);
+ 				return 1;
+ 			} else
+ 				continue;
+ 		} else {
+ 			close(fd);
+ 			return 0;
+ 		}
+ 	}
+ }	
+ 
+ #endif /* __linux */
+ 
+ 
+ #ifdef HAVE_PRPASSWD
+ /*
+  * Check a password under HP-UX's protected password scheme.
+  * This function is complicated because of the encrypted scheme
+  * used. Note that this scheme only matter if the password is
+  * greater than 8 characters, otherwise a plain old crypt()
+  * call works great.
+  */
+ int prpasswd_ok(char *pass, char *salt, struct pr_passwd *prpwd)
+ {
+     int segments;		/* number of segments */
+     int segment;		/* current segment number */
+     int encrypted_size;		/* size of encrypted password */
+     char *ppass;		/* pointer to current segment */
+     char *enc_pass;		/* encrypted password */
+     char *penc_pass;		/* pointer to current encrypted segment */
+     int result = 0;		/* Good password? 1 == yes, 0 == no */
+ 
+ 
+     /* Make sure encrypted password is at least of minimum length */
+     if ( strlen(prpwd->ufld.fd_encrypt) <
+ 	 (AUTH_SALT_SIZE+AUTH_CIPHERTEXT_SEG_CHARS) )
+ 	return 0;
+ 
+     /* Determine number of segments in password */
+     segments = AUTH_SEGMENTS(strlen(pass));
+ 
+     /* Size of the encrypted password */
+     encrypted_size = AUTH_CIPHERTEXT_SIZE(segments);
+ 
+     enc_pass = malloc(encrypted_size);
+ 
+     if (enc_pass == NULL)
+ 	return 0;
+ 
+     /* Copy in the salt */
+     penc_pass = enc_pass;
+     strncpy(penc_pass, salt, AUTH_SALT_SIZE);
+     penc_pass += AUTH_SALT_SIZE;
+ 
+     for (segment = 0, ppass = pass;
+ 	 segment < segments;
+ 	 segment++) {
+ 	
+ 	char *enc_segment;
+ 
+ 	/* Encrypt segment */
+ 	enc_segment = crypt(ppass, salt);
+ 	ppass += AUTH_CLEARTEXT_SEG_CHARS;
+ 
+ 	/* Skip over salt */
+ 	enc_segment += AUTH_SALT_SIZE;
+ 
+ 	/* Set salt for next encrypt to result of this encryption */
+ 	salt = enc_segment;
+ 
+ 	/* And append to encrypted password */
+ 	strncpy(penc_pass, enc_segment, AUTH_CIPHERTEXT_SEG_CHARS);
+ 	penc_pass += AUTH_CIPHERTEXT_SEG_CHARS;
+ 	*penc_pass = '\0';
+     }
+ 
+     result = !strcmp(enc_pass, prpwd->ufld.fd_encrypt);
+     
+     free(enc_pass);
+     
+     return result;
+ }
+ 
+ #endif /* HAVE_PRPASSWD */
+     
Index: krb5/appl/bsd/loginpaths.h
diff -c krb5/appl/bsd/loginpaths.h:1.1.1.3 krb5/appl/bsd/loginpaths.h:1.4
*** krb5/appl/bsd/loginpaths.h:1.1.1.3	Fri Feb 22 16:31:24 2002
--- krb5/appl/bsd/loginpaths.h	Mon Feb 25 02:56:37 2002
***************
*** 45,52 ****
--- 45,59 ----
  #endif
  
  #ifdef sgi
+ #ifdef HAVE_PATHS_H
+ #include <paths.h>
+ #define LPATH _PATH_USERPATH
+ #define RPATH _PATH_USERPATH
+ #define LPATH_root _PATH_ROOTPATH
+ #else
  #define LPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
  #define RPATH "/usr/sbin:/usr/bsd:/usr/bin:/bin:/usr/bin/X11"
+ #endif
  #endif
  
  #ifdef linux
Index: krb5/appl/bsd/rcp.M
diff -c krb5/appl/bsd/rcp.M:1.1.1.2 krb5/appl/bsd/rcp.M:1.3
*** krb5/appl/bsd/rcp.M:1.1.1.2	Fri Feb 22 16:31:24 2002
--- krb5/appl/bsd/rcp.M	Mon Feb 25 02:56:37 2002
***************
*** 110,116 ****
  .I port
  on the remote machine.  
  .TP
! .B \-N
  use a network connection, even when copying files on the local machine
  (used for testing purposes).
  .PP
--- 110,116 ----
  .I port
  on the remote machine.  
  .TP
! .B \-n
  use a network connection, even when copying files on the local machine
  (used for testing purposes).
  .PP
Index: krb5/appl/gss-sample/.cvsignore
diff -c /dev/null krb5/appl/gss-sample/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:06 2003
--- krb5/appl/gss-sample/.cvsignore	Thu Jun  5 10:38:08 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/gss-sample/configure.in
diff -c krb5/appl/gss-sample/configure.in:1.1.1.1 krb5/appl/gss-sample/configure.in:removed
*** krb5/appl/gss-sample/configure.in:1.1.1.1	Mon Jun  2 17:54:16 1997
--- krb5/appl/gss-sample/configure.in	Sun Mar 16 20:22:06 2003
***************
*** 1,11 ****
- AC_INIT(gss-client.c)
- CONFIG_RULES
- USE_ANAME
- AC_CHECK_HEADERS(unistd.h stdlib.h)
- AC_CHECK_HEADER(string.h,AC_DEFINE(USE_STRING_H))
- AC_CONST
- AC_PROG_INSTALL
- USE_GSSAPI_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/gssftp/.cvsignore
diff -c /dev/null krb5/appl/gssftp/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:06 2003
--- krb5/appl/gssftp/.cvsignore	Thu Jun  5 10:38:09 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/gssftp/configure.in
diff -c krb5/appl/gssftp/configure.in:1.1.1.2 krb5/appl/gssftp/configure.in:1.5
*** krb5/appl/gssftp/configure.in:1.1.1.2	Fri Feb 22 16:31:27 2002
--- krb5/appl/gssftp/configure.in	Mon Mar 10 15:25:04 2003
***************
*** 13,22 ****
  AC_CHECK_SIZEOF(int)
  AC_CHECK_SIZEOF(long)
  AC_FUNC_VFORK
! AC_HAVE_FUNCS(getcwd getdtablesize)
  AC_HEADER_STDARG
  AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK(cfsetispeed,AC_DEFINE(POSIX_TERMIOS)))
  AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/select.h sys/sockio.h paths.h)
  CHECK_UTMP
  DECLARE_SYS_ERRLIST
  AC_REPLACE_FUNCS(getdtablesize)
--- 13,110 ----
  AC_CHECK_SIZEOF(int)
  AC_CHECK_SIZEOF(long)
  AC_FUNC_VFORK
! AC_HAVE_FUNCS(getcwd getdtablesize strtoq atoll fseeko)
  AC_HEADER_STDARG
  AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK(cfsetispeed,AC_DEFINE(POSIX_TERMIOS)))
  AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/select.h sys/sockio.h paths.h)
+ AC_SIZEOF_OFF_T
+ dnl Check for special "large file" function calls or special SGI direct I/O
+ case $krb5_cv_host in
+     *-*-hpux*)
+         AC_CHECK_HEADERS(sys/cnx_types.h, AC_DEFINE(USE_FILE64_FUNCS))
+         ;;
+     mips-*-irix*)
+        AC_TRY_RUN([#include <stdio.h>
+ #include <fcntl.h>
+ int main () {
+ #ifdef O_DIRECT
+ exit(0);
+ #else
+ exit(1);
+ #endif
+ }], AC_DEFINE(SGI_DIRECT_IO))
+ 	;;
+ esac
+ dnl
+ dnl Do we want to compile in ATM ftp support?
+ AC_ARG_WITH([fore-atm],[
+   --with-fore-atm=dir    Enable file transfer over ATM],
+ [
+        AC_DEFINE(FORE_ATM_FTP)
+        AC_MSG_RESULT(Enabling ATM file transfer support in ftp)
+        if test X$withval != X ; then
+                LIBS="$LIBS -L${withval}/lib"
+                CPPFLAGS="$CPPFLAGS -I${withval}/include"
+        fi
+        LIBS="$LIBS -lnsl -lans -lpmp"
+        case $krb5_cv_host in
+        mips-*-irix*)
+                LIBS="$LIBS -lxnet"
+                ;;
+        esac
+ ])
+ dnl copied (mostly) from appl/bsd/configure.in
+ AFSLIBS=
+ AC_ARG_WITH([afs],
+ [  --without-afs       don't have afs libraries to build against (default)
+   --with-afs=AFSDIR    use preinstalled AFS library tree],
+ ,with_afs=no)dnl
+ if test $with_afs != no; then
+ 	AC_DEFINE(SETPAG)
+ 	AFSLIBS="$AFSLIBS -L$with_afs/lib -L$with_afs/lib/afs -lauth -lsys -lrx -llwp -lsys"
+ 	case $krb5_cv_host in
+ 	*-*-solaris*)
+ 		AFSLIBS="$AFSLIBS -lc -L/usr/ucblib -lucb -R/usr/ucblib"
+ 		;;
+ 	*-*-hpux*)
+ 		AFSLIBS="$AFSLIBS -lBSD -lm"
+ 		;;
+ 	*-*-netbsd*)
+ 		AFSLIBS="$AFSLIBS -lcompat"
+ 		;;
+ 	esac
+ fi
+ AC_SUBST(AFSLIBS)
+ AC_ARG_WITH([multihomed_fixes],
+ [  --with-multihomed-fixes  Includes fixes to help deal with multihomed hosts],
+ AC_DEFINE(KRB5_MULTIHOMED_FIXES))
+ dnl
+ dnl See if we want to disable automatic V4 compatibility (for ftpd)
+ AC_ARG_ENABLE([krb4-compat],
+ [  --enable-krb4-compat    Enable automatic client V4 compatibility (default)
+   --disable-krb4-compat   Disable automatic client V4 compatibility],
+ , enableval=yes
+ )dnl
+ if test $enableval = no; then
+ 	AC_MSG_RESULT(Disabling automatic ftp/ftpd V4 compatibility)
+ 	AC_DEFINE(OMIT_KRB4_COMPAT)
+ fi
+ dnl 
+ dnl Do we want to exclude anonymous FTP support in the FTP daemon?
+ AC_MSG_CHECKING([anonymous FTP support])
+ do_anonymous_ftp=yes
+ AC_ARG_WITH([anonymous-ftp],[],do_anonymous_ftp=$withval)
+ if test $do_anonymous_ftp = no; then
+ 	AC_DEFINE(NO_ANONYMOUS_FTP)
+ fi
+ AC_MSG_RESULT($do_anonymous_ftp)
+ dnl
+ dnl Check for --enable-log-preauth-logins
+ AC_ARG_ENABLE([log-preauth-logins],
+ [  --enable-log-preauth-logins  Log whether logins are password or preauthenticated],[
+ AC_MSG_RESULT(Enable logging of preauthenticated logins)
+ AC_DEFINE(LOG_PREAUTH_LOGINS)
+ ])
  CHECK_UTMP
  DECLARE_SYS_ERRLIST
  AC_REPLACE_FUNCS(getdtablesize)
***************
*** 29,35 ****
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
--- 117,124 ----
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);
!     unsetenv("PATH");],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
Index: krb5/appl/gssftp/ftp/.cvsignore
diff -c /dev/null krb5/appl/gssftp/ftp/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:06 2003
--- krb5/appl/gssftp/ftp/.cvsignore	Thu Jun  5 10:38:10 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/gssftp/ftp/Makefile.in
diff -c krb5/appl/gssftp/ftp/Makefile.in:1.1.1.3 krb5/appl/gssftp/ftp/Makefile.in:1.7
*** krb5/appl/gssftp/ftp/Makefile.in:1.1.1.3	Fri Feb 22 16:31:28 2002
--- krb5/appl/gssftp/ftp/Makefile.in	Thu Aug 29 14:19:15 2002
***************
*** 5,11 ****
  #
  # appl/gssftp/ftp/Makefile.in
  #
! DEFINES = -DGSSAPI -DFTP_BUFSIZ=10240
  PROG_LIBPATH=-L$(TOPLIBD)
  PROG_RPATH=$(KRB5_LIBDIR)
  
--- 5,11 ----
  #
  # appl/gssftp/ftp/Makefile.in
  #
! DEFINES = -DGSSAPI -DKERBEROS5 -DFTP_BUFSIZ=10240
  PROG_LIBPATH=-L$(TOPLIBD)
  PROG_RPATH=$(KRB5_LIBDIR)
  
***************
*** 16,22 ****
  
  
  OBJS	= cmds.o cmdtab.o domacro.o ftp.o getpass.o glob.o main.o pclose.o \
! 	  radix.o ruserpass.o secure.o
  
  LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir) @KRB4_INCLUDES@
  
--- 16,26 ----
  
  
  OBJS	= cmds.o cmdtab.o domacro.o ftp.o getpass.o glob.o main.o pclose.o \
! 	  radix.o ruserpass.o secure.o atoll.o atm.o window.o
! 
! KLIB = -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err
! DEPKLIB = $(TOPLIBD)/gssapi/libgssapi_krb5.a $(TOPLIBD)/libkrb5.a \
! 		$(TOPLIBD)/libcrypto.a $(COMERRLIB)
  
  LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir) @KRB4_INCLUDES@
  
***************
*** 53,57 ****
--- 57,64 ----
  domacro.o: $(srcdir)/domacro.c
  radix.o: $(srcdir)/radix.c
  secure.o: $(srcdir)/secure.c
+ atoll.o: $(srcdir)/atoll.c
+ atm.o: $(srcdir)/atm.c
+ window.o: $(srcdir)/window.c
  
  # NOPOSTFIX
Index: krb5/appl/gssftp/ftp/atm.c
diff -c /dev/null krb5/appl/gssftp/ftp/atm.c:1.2
*** /dev/null	Sun Mar 16 20:22:06 2003
--- krb5/appl/gssftp/ftp/atm.c	Tue Jul 31 21:01:26 2001
***************
*** 0 ****
--- 1,698 ----
+ /*
+   Copyright (C) 1999-2000  Naval Research Laboratory
+ 
+   Permission to use, copy, modify and distribute this software and its
+   documentation is hereby granted, provided that both the copyright
+   notice and this permission notice appear in all copies of the software,
+   derivative works or modified versions, and any portions thereof, and
+   that both notices appear in supporting documentation.
+ 
+   NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
+   DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
+   RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+ 
+ #ifdef FORE_ATM_FTP
+ 
+ #include <stdio.h>
+ #include <stdlib.h>		/* needed for getenv() */
+ #include <errno.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <fore_xti/xti_user_types.h>
+ #include <fore_xti/xti.h>
+ #include <fore_xti/xti_atm.h>
+ #include <fore_xti/netatm/atm.h>
+ #include <fore_xti/ans.h>
+ #ifdef aix
+ #define T_GETPROTADDR(fd, laddr, raddr) t_getprotaddr(fd, laddr, raddr)
+ #else
+ #define T_GETPROTADDR(fd, laddr, raddr) t_getname(fd, laddr.addr, LOCALNAME)
+ #endif /* aix */
+ 
+ #include "ftp_var.h"
+ 
+ #define	CH(x)	((int)(x & 0xff))
+ #define OC3_LINE_RATE   353207  /* OC-3 */
+ #define OC12_LINE_RATE  1412830 /* OC-12 */
+ #define OC48_LINE_RATE	5633207 /* OC-48 */
+ 
+ static int atm_limit_rate( int fd, int hw_type );
+ static int atm_set_orig_addr( int fd );
+ static int atm_bind_listener(int, unsigned char, int *, unsigned char *);
+ static int atm_connect( int fd, unsigned char atm_address[20],
+ 		unsigned char bhli_magic[8], unsigned char selector,
+ 		char *options, size_t optlen);
+ static void atm_local_addr( int fd, unsigned char *address);
+ int atm_set_bufsize( int, uint32_t, uint32_t );
+ static struct t_info info;
+ 
+ /*
+  * This is the ATM glue function for ftp; we do all of the connection
+  * setup here.
+  */
+ 
+ int
+ atminitconn(unsigned char *hw_address, unsigned char *bhli)
+ {
+ 	int fd, hw;
+ 
+ 	/*
+ 	 * First, open the XTI device
+ 	 */
+ 
+ 	fd = atm_open_dev("/dev/xtisvc0");
+ 	if (fd < 0)
+ 		return -1;
+ 	
+ 	/*
+ 	 * Bind the initiator (that's us)
+ 	 */
+ 
+ 	if (atm_bind_initiator(fd, &hw))
+ 		return -1;
+ 	
+ 	/*
+ 	 * Connect to the remote system
+ 	 */
+ 
+ 	if (atm_connect(fd, hw_address, bhli, 0x99, NULL, 0))
+ 		return -1;
+ 	
+ 	return fd;
+ }
+ 
+ /*
+  * Set up things to listen for a connection
+  */
+ 
+ int atminitlisten(unsigned char *hw_address, unsigned char *magic, int pid)
+ {
+ 	int fd, hw, seq;
+ 	char *opt;
+ 	struct t_info info;
+ 	unsigned char bhli[8];
+ 
+ 	snprintf((char *) bhli, sizeof(bhli), "%d", pid);
+ 
+ 	fd = atm_open_dev("/dev/xtisvc0");
+ 	if (fd < 0)
+ 		return -1;
+ 	
+ 	if (atm_bind_listener(fd, 0x99, &hw, bhli))
+ 		return -1;
+ 
+ 	memcpy(magic, bhli, sizeof(bhli));
+ 	atm_local_addr(fd, hw_address);
+ 	return fd;
+ }
+ 
+ static int atm_open_dev( char *preferred ){
+ 	int fd;
+ 	int devcount = 0;
+ 	struct t_info info;
+ 	char *device = (char *)malloc( 80 );
+ 
+ 	if(( fd = t_open( preferred, O_RDWR, &info )) == -1 )
+ 		while(( devcount < 16 ) && ( fd == -1 )){
+ 			snprintf( device, 80, "/dev/xtisvc%u", devcount );
+ 			fd = t_open( device, O_RDWR, &info );
+ 			devcount++;
+ 		}
+ 	if( fd < 0 ) secure_error("Cannot open XTI device: %s",
+ 				  t_strerror(t_errno));
+ 	if( device ) free( device );
+ 	return fd;
+ }
+ 
+ static void atm_clean( int fd ){
+ 	int event = 0;
+ 
+ 	if(( t_unbind( fd ) < 0 ) && ( t_errno == TLOOK )) event = t_look( fd );
+ 	if( event && event != T_DATA ) /* handle_error( fd, "t_unbind" ) */;
+ 	if( t_close( fd ) < 0 ) t_error( "t_close" );
+ }
+ 
+ /* Returns 0 on success */
+ static int atm_bind_listener(int fd, unsigned char selector, int *hw_type,
+ 			     unsigned char *bhli) {
+ 	struct t_bind bind_req;
+ 	ATMSAPAddress addr_req;
+ 	struct t_atm_card_prop card_prop;
+ 
+ 	addr_req.addressType = AF_ATM;
+ 
+ 	/* Note: this approach may be FORE implementation-specific. */
+ 
+ 	addr_req.sap.t_atm_sap_addr.SVE_tag_addr = (int8_t)T_ATM_ABSENT;
+ 	addr_req.sap.t_atm_sap_addr.SVE_tag_selector = (int8_t)T_ATM_PRESENT;
+ 	addr_req.sap.t_atm_sap_addr.address_format = (uint8_t)T_ATM_ENDSYS_ADDR;
+ 	addr_req.sap.t_atm_sap_addr.address_length = 20;
+ 	addr_req.sap.t_atm_sap_addr.address[19] = selector;
+ 	addr_req.sap.t_atm_sap_layer2.SVE_tag = (int8_t)T_ATM_ABSENT;
+ 	addr_req.sap.t_atm_sap_layer3.SVE_tag = (int8_t)T_ATM_ABSENT;
+ 
+ 	/* this is optional; we use BHLI (appl) ID here to avoid conflicts */
+ 	addr_req.sap.t_atm_sap_appl.SVE_tag = (int8_t)T_ATM_PRESENT;
+ 	addr_req.sap.t_atm_sap_appl.ID_type = (uint8_t)T_ATM_USER_APP_ID;
+ 	memcpy(addr_req.sap.t_atm_sap_appl.ID.user_defined_ID, bhli, 8);
+ 
+ 	memset( &bind_req, 0, sizeof( bind_req ));
+ 	bind_req.qlen = 1;
+ 	bind_req.addr.len = sizeof( addr_req );
+ 	bind_req.addr.buf = (char *)&addr_req;
+ 
+ 	/* Binding SVC listening endpoint */
+ 
+ 	if( t_bind( fd, &bind_req, (struct t_bind *)NULL ) < 0 ){
+ 		fprintf( stderr, "t_errno is %d\n", t_errno );
+ 		secure_error("t_bind failed: %s", t_strerror(t_errno));
+ 		return -1;
+ 	}
+ 	/*
+ 	if( get_option_value( fd, T_ATM_CARD_PROP, (char *)&card_prop,
+ 		sizeof( t_atm_card_prop )) != 0 ){
+ 		fprintf(stderr, "Unable to obtain ATM Card properties.\n");
+ 	} else */ *hw_type = card_prop.hw_type;
+ 
+ 	return 0;
+ }
+ 
+ 
+ /* Returns 0 on success, -1 on failure */
+ static int atm_bind_initiator( int fd, int *hw_type ){
+     /* For the initiator it is suggested to set 'req' to NULL, since it is
+      * ignored.	 The local address can be retrieved through 'ret', or later
+      * with t_getname()/t_getprotaddr().
+      */
+ 
+ 	struct t_bind bind_ret;
+ 	ATMSAPAddress addr_ret;
+ 	struct t_atm_card_prop card_prop;
+ 
+ 	memset( &bind_ret, 0, sizeof( bind_ret ));
+ 	bind_ret.addr.maxlen = sizeof( addr_ret );
+ 	bind_ret.addr.buf = (char *)&addr_ret;
+ 
+ 	/* Binding SVC endpoint */
+ 	if( t_bind( fd, (struct t_bind *)NULL, &bind_ret ) < 0 ){
+ 		secure_error("ATM SVC endpoint bind failed: %s",
+ 			     t_strerror(t_errno));
+ 		return -1;
+ 	}
+ 
+ 	/* Initiator local address stored in sap_to_string(addr_ret)) */
+ 	if( get_option_value( fd, T_ATM_CARD_PROP,
+ 		(char *)&card_prop,
+ 		sizeof( t_atm_card_prop )) != 0 ){
+ 		secure_error("Unable to obtain ATM Card properties");
+ 		return -1;
+ 	} else *hw_type = card_prop.hw_type;
+ 
+ 	return 0;
+ }
+ 
+ static int atm_connect( int fd, unsigned char atm_address[20],
+ 		unsigned char bhli_magic[8], unsigned char selector,
+ 		char *options, size_t optlen){
+ 	struct t_call call_req;
+ 	ATMSAPAddress remote_addr;
+ 	struct t_atm_conn_prop conn_prop;
+ 
+ 	remote_addr.addressType = (uint16_t)AF_ATM;
+ 	remote_addr.sap.t_atm_sap_addr.SVE_tag_addr = (int8_t)T_ATM_PRESENT;
+ 	remote_addr.sap.t_atm_sap_addr.SVE_tag_selector = (int8_t)T_ATM_PRESENT;
+ 	remote_addr.sap.t_atm_sap_addr.address_format =
+ 		(uint8_t)T_ATM_ENDSYS_ADDR;
+ 	remote_addr.sap.t_atm_sap_addr.address_length = 20;
+ 	memcpy( remote_addr.sap.t_atm_sap_addr.address, atm_address, 20 );
+ 	remote_addr.sap.t_atm_sap_addr.address[19] = selector;
+ 	remote_addr.sap.t_atm_sap_layer2.SVE_tag = (int8_t)T_ATM_ABSENT;
+ 	remote_addr.sap.t_atm_sap_layer3.SVE_tag = (int8_t)T_ATM_ABSENT;
+ 	remote_addr.sap.t_atm_sap_appl.SVE_tag = (int8_t)T_ATM_PRESENT;
+ 	remote_addr.sap.t_atm_sap_appl.ID_type = T_ATM_USER_APP_ID;
+ 	memcpy( remote_addr.sap.t_atm_sap_appl.ID.user_defined_ID,
+ 		bhli_magic, 8 );
+ 
+ 	/* Remote address is in sap_to_string(remote_addr)) */
+ 
+ 	memset( &call_req, 0, sizeof( call_req ));
+ 	call_req.addr.len = sizeof( remote_addr );
+ 	call_req.addr.buf = (char *)&remote_addr;
+ 
+ 	/* Connecting . . . */
+ 
+ 	if( atm_limit_rate( fd, 0 ) == T_FAILURE ) {
+ 		secure_error("Failed to set rate limit");
+ 		return -1;
+ 	}
+ 	if( atm_set_orig_addr( fd ) == T_FAILURE ) {
+ 		secure_error("Could not set originating address");
+ 		return -1;
+ 	}
+ 	if( t_connect( fd, &call_req, (struct t_call *)NULL ) < 0 ){
+ 		secure_error("t_connect failed: %s", t_strerror(t_errno));
+ 		return -1;
+ 	}
+ 
+         if (get_option_value(fd, T_ATM_CONN_PROP, (char *)&conn_prop,
+                             sizeof(t_atm_conn_prop)) == 0)
+ #if 0
+             fprintf(stderr, "Connected using vpi %d, vci %d\n",
+                     conn_prop.vpi, conn_prop.vci);
+ #endif
+ 
+ 	return 0;
+ }
+ 
+ int atm_accept( int fd ){
+ 	struct t_call incoming;
+ 	ATMSAPAddress remote_addr;
+ 	struct t_atm_conn_prop conn_prop;
+ 
+ 	memset( &incoming, 0, sizeof( incoming ));
+ 	incoming.addr.maxlen = sizeof( remote_addr );
+ 	incoming.addr.buf = (char *)&remote_addr;
+ 
+     /* According to XNS Issue 5, we can set maxlen = 0 to ignore any
+      * return options.	However, most OSes only implement Issue 4
+      * currently, which doesn't have this feature.  Therefore, we
+      * always allocate space for incoming options data.
+      */
+ 
+ 	if( t_getinfo( fd, &info ) < 0 ){
+ 		secure_error("Cannot get device info: %s",
+ 			     t_strerror(t_errno));
+ 		return 1;
+ 	}
+ 
+ 	incoming.opt.buf = (char *)malloc( info.options );
+ 	if( incoming.opt.buf == (char *)NULL ){
+ 		secure_error("Cannot malloc %d bytes for option buffer",
+ 			      info.options);
+ 		return 1;
+ 	}
+ 
+ 	memset( incoming.opt.buf, 0, sizeof( info.options ));
+ 	incoming.opt.maxlen = info.options;
+ 
+ 	if( t_listen( fd, &incoming ) < 0 ){
+ 		/* handle_error( fd, "t_listen" ); */
+ 		secure_error("Cannot listen for connection: %s",
+ 			     t_strerror(t_errno));
+ 		free( incoming.opt.buf );
+ 		return 1;
+ 	}
+ 
+ 	if( t_accept( fd, fd, &incoming ) < 0 ){
+ 		/* handle_error( fd, "t_accept" ); */
+ 		secure_error("Cannot accept new connection: %s",
+ 			     t_strerror(t_errno));
+ 		free(incoming.opt.buf);
+ 		return -1;
+ 	} else{
+ 		/* For information purposes, get vpi, vci for connection */
+ 		if( get_option_value( fd, T_ATM_CONN_PROP, (char *)&conn_prop,
+ 			sizeof( t_atm_conn_prop )) == 0 ){
+ 		}
+ 	}
+ 
+ 	free(incoming.opt.buf);
+ 	return 0;
+ }
+ 
+ int atm_disconnect( int fd ){
+ 	if( t_snddis( fd, (struct t_call *)NULL )){
+ 		t_error( "t_snddis" );
+ 		return -1;
+ 	}
+ 	return 0;
+ }
+ 
+ static void atm_recv_disconnect( int fd ){
+ 	char buf;
+ 	int flags, event, waiting = 1;
+ 	struct t_discon discon;
+ 	struct t_leaf_status change;
+ 
+ 	while( waiting ){
+ 		event = t_look( fd );
+ 		switch( event ){
+ 		case -1:
+ 			fprintf( stderr, "Got t_look error %d\n", t_errno );
+ 			waiting = 0;
+ 			break;
+ 		case 0:
+ 			waiting++;
+ 			break;
+ 		case T_LEAFCHANGE:
+ 			if( t_rcvleafchange( fd, &change ) == 0 ){
+ 				fprintf( stderr, "Got leaf %s: leaf ID %d\n",
+ 				(( change.status == T_LEAF_CONNECTED ) ?
+ 				"connect" : "disconnect" ),
+ 				change.leafid );
+ 			}
+ 			waiting++;
+ 			break;
+ 		case T_DISCONNECT:
+ #ifndef aix 
+ 		case T_ERROR:
+ #endif 
+ 			waiting = 0;
+ 			break;
+ 		}
+ 		sleep( 1 );
+ #		define SHORT_WAIT 3
+ 		if( waiting == SHORT_WAIT*2 ){
+ 			fprintf( stderr,
+ 				"Never received disconnect message.\n" );
+ 			waiting = 0;
+ 		}
+ 
+ 	}
+ 	return;
+ }
+ 
+ ssize_t atm_read( int fd, void *buf, size_t bytes ){
+ 	int flags;
+ 	int result;
+ 	result = t_rcv( fd, buf, (unsigned int)bytes, &flags );
+ 	if( result <= 0 ){
+ 		if( t_errno == TLOOK ){
+ 			int error;
+ 			error = t_look( fd );
+ 			fprintf( stderr, "atm_read(): t_look returned %d\n",
+ 				error );
+ 			if( error == T_DISCONNECT ){
+ 				t_rcvdis( fd, (struct t_discon *)NULL );
+ 				fprintf( stderr, "received disconnect\n" );
+ 			}
+ 		}
+ 		return (ssize_t)(-1);
+ 	}
+ 	return (ssize_t)result;
+ }
+ 
+ ssize_t atm_write( int fd, void *buf, size_t bytes ){
+ 	/* int cnt = t_snd( fd, buf, (unsigned int)bytes, 0 ); */
+ 	int cnt = t_snd( fd, buf, (unsigned int)bytes, 0 | T_PUSH );
+ 	int error;
+ 	if( cnt >= 0 ) return (ssize_t)cnt;
+ 	else if( t_errno == TLOOK ){
+ 		error = t_look( fd );
+ 		if( error == T_DISCONNECT ){
+ 			t_rcvdis( fd, (struct t_discon *) NULL );
+ 			fprintf( stderr, "received disconnect\n" );
+ 		} else fprintf( stderr,
+ 			"unknown error, t_look returned %d\n", error );
+ 	}
+ 	return -1;
+ }
+ 
+ 
+ static int
+ get_option_value(int fd, int name, char *opt_return, int opt_size)
+ {
+     struct t_opthdr *popt, *popt_ret;
+     char *buf_req, *buf_ret;
+     struct t_info info;
+     struct t_optmgmt opt_req, opt_ret;
+ 
+     if (t_getinfo(fd, &info) < 0) {
+ 	t_error("t_getinfo");
+ 	return -1;
+     }
+ 
+     buf_req = (char *) malloc(info.options);
+     if (buf_req == (char *) NULL) {
+ 	fprintf(stderr,"Unable to allocate %ld bytes for options\n",
+ 		info.options);
+ 	return -1;
+     }
+ 
+     buf_ret = (char *) malloc(info.options);
+     if (buf_ret == (char *) NULL) {
+ 	fprintf(stderr,"Unable to allocate %ld bytes for options\n",
+ 		info.options);
+ 	return -1;
+     }
+ 
+     memset(&opt_req, 0, sizeof(opt_req));
+     memset(&opt_ret, 0, sizeof(opt_ret));
+ 
+     popt     = (struct t_opthdr *) buf_req;
+     popt_ret = (struct t_opthdr *) buf_ret;
+ 
+     popt->len= sizeof(struct t_opthdr) + opt_size;
+     popt->level     = T_ATM_SIGNALING;
+     popt->name      = name;
+     popt->status    = 0;
+ 
+     opt_req.opt.len = popt->len;
+     opt_req.opt.buf = (char *)popt;
+     opt_req.flags = T_CURRENT;
+ 
+     popt = T_OPT_NEXTHDR(buf_req, info.options , popt);
+     opt_ret.opt.maxlen  = info.options;
+     opt_ret.opt.buf = (char *)popt_ret;
+ 
+     if (t_optmgmt(fd, &opt_req, &opt_ret) < 0) {
+ 	t_error("t_optmgmt");
+     }
+ 
+     memcpy(opt_return, (char *)popt_ret+sizeof(struct  t_opthdr), opt_size);
+ 
+     free(buf_ret);
+     free(buf_req);
+     return 0;
+ }
+ 
+ /* must be called after t_bind */
+ static void atm_local_addr( int fd, unsigned char *address){
+ 	struct t_bind *b, *p;
+ 	ATMSAPAddress aa;
+ 
+ 	b = (struct t_bind *)malloc( sizeof( struct t_bind ));
+ 	memset( b, 0, sizeof( struct t_bind ));
+ 		b->addr.buf = (char *)&aa;
+ 		b->addr.maxlen = sizeof( aa );
+ 
+ 	/* _xti_getprotaddr( fd, b, NULL );	/* works for solaris 2.6 */
+ 	/* t_getprotaddr( fd, b, NULL );	/* aix?  v5 stuff */
+ 
+ 	t_getname( fd, &(b->addr), LOCALNAME );	/* xti v4 -- everything */
+ 
+ 	memcpy(address, aa.sap.t_atm_sap_addr.address, 20);
+ 
+ 	return;
+ }
+ 
+ int atm_set_orig_addr( int fd ){
+ 	struct t_opthdr *opt;
+ 	struct t_atm_addr source;
+ 	struct t_optmgmt *req, *ret;
+ 	struct t_bind *b;
+ 	ATMSAPAddress aa;
+ 	char *s;
+ 	int val;
+ 
+ 	/* get local address */
+ 	b = (struct t_bind *)malloc( sizeof( struct t_bind ));
+ 	memset( b, 0, sizeof( struct t_bind ));
+ 		b->addr.buf = (char *)&aa;
+ 		b->addr.maxlen = sizeof( aa );
+ 	t_getname( fd, &(b->addr), LOCALNAME );
+ 	s = (char *)&( aa.sap.t_atm_sap_addr.address );
+ 
+ 	/* allocate memory for request and return */
+ 	req = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 	ret = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 	if( req->opt.maxlen == 0 ){
+ 		fprintf( stderr, "option length is zero\n" );
+ 		t_free((void *)req, T_OPTMGMT );
+ 		t_free((void *)ret, T_OPTMGMT );
+ 		return T_FAILURE;
+ 	}
+ 
+ 	/* fill in option header information */
+ 	opt = (struct t_opthdr *)req->opt.buf;
+ 	opt->len    = sizeof( struct t_opthdr ) + sizeof( struct t_atm_addr );
+ 	opt->level  = T_ATM_SIGNALING;
+ 	opt->name   = T_ATM_ORIG_ADDR;
+ 	opt->status = 0;
+ 
+ 	memset( &source, 0, sizeof( struct t_atm_addr ));
+ 	memcpy( &(source.address), s, 20 );
+ 	source.address_format = T_ATM_ENDSYS_ADDR;
+ 	source.address_length = 20;
+ 	memcpy( opt + 1, &source, sizeof( struct t_atm_addr ));
+ 
+ 	req->opt.len = opt->len;
+ 	req->flags = T_NEGOTIATE;
+ 	if( t_optmgmt( fd, req, ret ) < 0 ){
+ 		fprintf( stderr, "Could not set source address\n" );
+ 		t_free((void *)req, T_OPTMGMT );
+ 		t_free((void *)ret, T_OPTMGMT );
+ 		return T_FAILURE;
+ 	}
+ 	val = ret->flags;
+ 	t_free((void *)ret, T_OPTMGMT );
+ 	t_free((void *)req, T_OPTMGMT );
+ 	if( val == T_SUCCESS || val == T_PARTSUCCESS ) return T_SUCCESS;
+ 	return T_FAILURE;
+ }
+ 
+ int atm_limit_rate( int fd, int hw_type ){
+ 	struct t_opthdr *topt, *bopt;
+ 	struct t_optmgmt *req, *ret;
+ 	struct t_atm_traffic traffic;
+ 	struct t_atm_bearer bearer;
+ 	char *env;
+ 	long l_atmpcr;
+ 	int toptlen = sizeof( struct t_atm_traffic );
+ 	int boptlen = sizeof( struct t_atm_bearer );
+ 	int val;
+ 
+ 	l_atmpcr = atmpcr ? atmpcr : OC3_LINE_RATE;
+ 
+ 	req = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 	ret = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 	if( req->opt.maxlen == 0 ){
+ #if 0
+ 		fprintf( stderr, "option length is zero\n" );
+ #endif
+ 		t_free((void *)req, T_OPTMGMT );
+ 		t_free((void *)ret, T_OPTMGMT );
+ 		return T_FAILURE;
+ 	}
+ 
+ 	bopt = (struct t_opthdr *)req->opt.buf;
+ 	bopt->len	= sizeof( struct t_opthdr ) + boptlen;
+ 	bopt->level	= T_ATM_SIGNALING;
+ 	bopt->name	= T_ATM_BEARER_CAP;
+ 	bopt->status	= 0;
+ 
+ 	memset( &bearer, 0, boptlen );
+ 	bearer.bearer_class = T_ATM_CLASS_X;
+ 	bearer.timing_requirements = 0;
+ 	bearer.traffic_type = T_ATM_NULL;
+ 	bearer.clipping_susceptibility = T_ATM_NULL;
+ 	bearer.connection_configuration = T_ATM_1_TO_1;
+ 	memcpy( bopt + 1, &bearer, boptlen );
+ 
+ 	req->opt.len = bopt->len;
+ 	req->flags = T_NEGOTIATE;
+ 	if( t_optmgmt( fd, req, ret ) < 0 ){
+ #if 0
+ 		fprintf( stderr, "Could not set bearer capabilities\n" );
+ #endif
+ 		t_free((void *)req, T_OPTMGMT );
+ 		t_free((void *)ret, T_OPTMGMT );
+ 		return T_FAILURE;
+ 	}
+ 
+ 	topt = (struct t_opthdr *)req->opt.buf;
+ 	topt->len	= sizeof( struct t_opthdr ) + toptlen;
+ 	topt->level	= T_ATM_SIGNALING;
+ 	topt->name	= T_ATM_TRAFFIC;
+ 	topt->status	= 0;
+ 
+ 	/* Set the peak cell rate (should be based on remote hw type) */
+ 	memset( &traffic, 0, toptlen );
+ 	traffic.forward.PCR_all_traffic		= atmpcr;
+ 	traffic.backward.PCR_all_traffic	= OC3_LINE_RATE;
+ 	traffic.forward.PCR_high_priority	= T_ATM_ABSENT;
+ 	traffic.forward.SCR_high_priority	= T_ATM_ABSENT;
+ 	traffic.forward.MBS_high_priority	= T_ATM_ABSENT;
+ 	traffic.backward.PCR_high_priority	= T_ATM_ABSENT;
+ 	traffic.backward.SCR_high_priority	= T_ATM_ABSENT;
+ 	traffic.backward.MBS_high_priority	= T_ATM_ABSENT;
+ 	traffic.forward.SCR_all_traffic		= T_ATM_ABSENT;
+ 	traffic.backward.SCR_all_traffic	= T_ATM_ABSENT;
+ 	traffic.forward.MBS_all_traffic		= T_ATM_ABSENT;
+ 	traffic.backward.MBS_all_traffic	= T_ATM_ABSENT;
+ 	traffic.backward.tagging		= T_NO;
+ 	traffic.forward.tagging			= T_NO;
+ 	traffic.best_effort			= T_YES;
+ 
+ 	memcpy( topt + 1, &traffic, toptlen );
+ 	req->opt.len = topt->len;
+ 	req->flags = T_NEGOTIATE;
+ 	if( t_optmgmt( fd, req, ret ) < 0 ){
+ 		t_free((void *)req, T_OPTMGMT );
+ 		t_free((void *)ret, T_OPTMGMT );
+ 		return T_FAILURE;
+ 	}
+ 
+ 	val = ret->flags;
+ 	t_free((void *)ret, T_OPTMGMT );
+ 	t_free((void *)req, T_OPTMGMT );
+ 	if( val == T_SUCCESS || val == T_PARTSUCCESS ) return T_SUCCESS;
+ 	return T_FAILURE;
+ }
+ 
+ /* which is either XTI_RCVBUF or XTI_SNDBUF */
+ static int __set_bufsize( int fd, uint32_t sz, int which ){
+ 	struct t_opthdr *topt;
+ 	struct t_optmgmt *req, *ret;
+ 
+ 	if( which == XTI_RCVBUF || which == XTI_SNDBUF );
+ 	else return T_FAILURE;
+ 
+ 	req = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 	ret = (struct t_optmgmt *)t_alloc( fd, T_OPTMGMT, T_ALL );
+ 
+ 	topt = (struct t_opthdr *)req->opt.buf;
+ 	topt->level = XTI_GENERIC;
+ 	topt->name = which;
+ 	topt->len = sizeof(struct t_opthdr) + sizeof( sz );
+ 	req->opt.len = topt->len;
+ 	memcpy( topt + 1, &sz, sizeof( sz ));
+ 
+ 	req->flags = T_CURRENT;
+ 	t_optmgmt( fd, req, ret );
+ 	topt = (struct t_opthdr *)ret->opt.buf;
+ 	memcpy( &sz, topt + 1, sizeof( sz ));
+ 	fprintf( stderr, "default %s size is %d\n",
+ 		( which == XTI_SNDBUF ) ? "sndbuf" : "rcvbuf", sz );
+ 
+ 	topt = (struct t_opthdr *)req->opt.buf;
+ 	req->flags = T_NEGOTIATE;
+ 	if( t_optmgmt( fd, req, ret ) < 0 ){
+ 		fprintf( stderr, "t_optmgmt failed in atm_set_bufsize\n" );
+ 		return T_FAILURE;
+ 	} else {
+ 		topt = (struct t_opthdr *)ret->opt.buf;
+ 		if( topt->status == T_SUCCESS || topt->status == T_READONLY ){
+ 			memcpy( &sz, topt + 1, sizeof( sz ));
+ 			fprintf( stderr, "%s size set to %d\n",
+ 			( which == XTI_SNDBUF ) ? "sndbuf" : "rcvbuf", sz );
+ 		}
+ 	}
+ 
+ 	t_free((void *)req, T_ALL );
+ 	t_free((void *)ret, T_ALL );
+ 	return T_SUCCESS;
+ }
+ 
+ /* This should be called after t_bind */
+ /* passing zero for a buffer size indicates that the value should */
+ /* not be changed */
+ 
+ int atm_set_bufsize( int fd, uint32_t sndbuf, uint32_t rcvbuf ){
+ 	int success = 2;
+ 
+ 	if( sndbuf > 0 )
+ 		if( __set_bufsize( fd, sndbuf, XTI_SNDBUF ) == T_FAILURE )
+ 			success--;
+ 	if( rcvbuf > 0 )
+ 		if( __set_bufsize( fd, rcvbuf, XTI_RCVBUF ) == T_FAILURE )
+ 			success--;
+ 
+ 	if( success == 2 ) return T_SUCCESS;
+ 	else if( success == 1 ) return T_PARTSUCCESS;
+ 	return T_FAILURE;
+ }
+ 
+ #endif /* FORE_ATM_FTP */
Index: krb5/appl/gssftp/ftp/atoll.c
diff -c /dev/null krb5/appl/gssftp/ftp/atoll.c:1.2
*** /dev/null	Sun Mar 16 20:22:06 2003
--- krb5/appl/gssftp/ftp/atoll.c	Wed Jun 28 03:54:55 2000
***************
*** 0 ****
--- 1,159 ----
+ /*
+  * 1/11/1999
+  *
+  * Modifications of code taken from the GNU libc version 5.3.12 strtol() and
+  * atol() stdlib functions.
+  */
+ 
+ #if defined(USE_FILE64_FUNCS)
+ 
+ #include <ctype.h>
+ #include <errno.h>
+ #ifndef errno
+ extern int errno;
+ #endif
+ 
+ #include <limits.h>
+ #include <stddef.h>
+ #include <stdlib.h>
+ 
+ 
+ long long int
+ strtoq(nptr, endptr, base)
+      const char *nptr;
+      char **endptr;
+      int base;
+ {
+   int negative;
+   register unsigned long long int cutoff;
+   register unsigned int cutlim;
+   register unsigned long long int i;
+   register const char *s;
+   register unsigned char c;
+   const char *save, *end;
+   int overflow;
+ 
+   if (base < 0 || base == 1 || base > 36)
+     base = 10;
+ 
+   save = s = nptr;
+ 
+   /* Skip white space.  */
+   while (isspace (*s))
+     ++s;
+   if (*s == '\0')
+     goto noconv;
+ 
+   /* Check for a sign.  */
+   if (*s == '-')
+     {
+       negative = 1;
+       ++s;
+     }
+   else if (*s == '+')
+     {
+       negative = 0;
+       ++s;
+     }
+   else
+     negative = 0;
+ 
+   if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
+     s += 2;
+ 
+   /* If BASE is zero, figure it out ourselves.  */
+   if (base == 0)
+     if (*s == '0')
+       {
+ 	if (toupper (s[1]) == 'X')
+ 	  {
+ 	    s += 2;
+ 	    base = 16;
+ 	  }
+ 	else
+ 	  base = 8;
+       }
+     else
+       base = 10;
+ 
+   /* Save the pointer so we can check later if anything happened.  */
+   save = s;
+ 
+     end = NULL;
+ 
+   cutoff = ULONG_LONG_MAX / (unsigned long long int) base;
+   cutlim = ULONG_LONG_MAX % (unsigned long long int) base;
+ 
+   overflow = 0;
+   i = 0;
+   for (c = *s; c != '\0'; c = *++s)
+     {
+       if (s == end)
+ 	break;
+       if (isdigit (c))
+ 	c -= '0';
+       else if (isalpha (c))
+ 	c = toupper (c) - 'A' + 10;
+       else
+ 	break;
+       if (c >= base)
+ 	break;
+       /* Check for overflow.  */
+       if (i > cutoff || (i == cutoff && c > cutlim))
+ 	overflow = 1;
+       else
+ 	{
+ 	  i *= (unsigned long long int) base;
+ 	  i += c;
+ 	}
+     }
+ 
+   /* Check if anything actually happened.  */
+   if (s == save)
+     goto noconv;
+ 
+   /* Store in ENDPTR the address of one character
+      past the last character we converted.  */
+   if (endptr != NULL)
+     *endptr = (char *) s;
+ 
+   /* Check for a value that is within the range of
+      `unsigned long long int', but outside the range of `long long int'.  */
+   if (i > (negative ?
+ 	   -(unsigned long long int) LONG_LONG_MIN :
+ 		(unsigned long long int) LONG_LONG_MAX))
+     overflow = 1;
+ 
+   if (overflow)
+     {
+       errno = ERANGE;
+       return negative ? LONG_LONG_MIN : LONG_LONG_MAX;
+     }
+ 
+   /* Return the result of the appropriate sign.  */
+   return (negative ? -i : i);
+ 
+ noconv:
+   /* We must handle a special case here: the base is 0 or 16 and the
+      first two characters and '0' and 'x', but the rest are no
+      hexadecimal digits.  This is no error case.  We return 0 and
+      ENDPTR points to the `x`.  */
+   if (endptr != NULL)
+     if (save - nptr >= 2 && tolower (save[-1]) == 'x' && save[-2] == '0')
+       *endptr = (char *) &save[-1];
+     else
+       /*  There was no number to convert.  */
+       *endptr = (char *) nptr;
+ 
+   return 0L;
+ }
+ 
+ 
+ long long int
+ atoll(nptr)
+ 	const char *nptr;
+ {
+   return(strtoq(nptr, (char **) NULL, 10));
+ }
+ 
+ #endif /* USE_FILE64_FUNCS */
Index: krb5/appl/gssftp/ftp/cmds.c
diff -c krb5/appl/gssftp/ftp/cmds.c:1.1.1.3 krb5/appl/gssftp/ftp/cmds.c:1.12
*** krb5/appl/gssftp/ftp/cmds.c:1.1.1.3	Fri Feb 22 16:31:29 2002
--- krb5/appl/gssftp/ftp/cmds.c	Sun Feb 24 22:56:37 2002
***************
*** 38,44 ****
--- 38,49 ----
  /*
   * FTP User Program -- Command Routines.
   */
+ 
+ #ifdef HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
  #include <sys/param.h>
+ #include <sys/types.h>
  #include <sys/wait.h>
  #include <sys/stat.h>
  #include <sys/socket.h>
***************
*** 54,59 ****
--- 59,68 ----
  #include <time.h>
  #include <netinet/in.h>
  
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
+ 
  #ifdef HAVE_GETCWD
  #define getwd(x) getcwd(x,MAXPATHLEN)
  #endif
***************
*** 675,680 ****
--- 684,718 ----
  	if (loc && mapflag) {
  		argv[2] = domap(argv[2]);
  	}
+ 
+ 	/*
+ 	 * Handle reput; find out the remote file size and set the restart
+ 	 * pointer from that point
+ 	 */
+ 	if (argv[0][0] == 'r') {
+ 		int overbose = verbose;
+ 		if (debug == 0)
+ 			verbose = -1;
+ 		if (command("SIZE %s", argv[2]) == COMPLETE) {
+ #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T==8
+ 			if (sscanf(reply_string, "%*s %lld", &restart_point)
+ #else
+ 			if (sscanf(reply_string, "%*s %ld", &restart_point)
+ #endif /* defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T==8 */
+ 								!= 1) {
+ 				printf("Couldn't parse size reply: %s\n",
+ 				       reply_string);
+ 				verbose = overbose;
+ 				return;
+ 			}
+ 		} else {
+ 			printf("%s\n", reply_string);
+ 			verbose = overbose;
+ 			return;
+ 		}
+ 		verbose = overbose;
+ 	}
+ 
  	sendrequest(cmd, argv[1], argv[2],
  	    argv[1] != oldargv1 || argv[2] != oldargv2);
  }
***************
*** 816,822 ****
--- 854,864 ----
  	int argc;
  	char *argv[];
  {
+ #ifdef USE_FILE64_FUNCS
+ 	(void) getit(argc, argv, 0, restart_point ? "r+w" : "wl" );
+ #else /* ! USE_FILE64_FUNCS */
  	(void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
+ #endif /* ! USE_FILE64_FUNCS */
  }
  
  /*
***************
*** 1007,1013 ****
--- 1049,1059 ----
  			if (mapflag) {
  				tp = domap(tp);
  			}
+ #ifdef USE_FILE64_FUNCS
+ 			recvrequest("RETR", tp, cp, "wl",
+ #else /* ! USE_FILE64_FUNCS */
  			recvrequest("RETR", tp, cp, "w",
+ #endif /* ! USE_FILE64_FUNCS */
  			    tp != cp || !interactive);
  			if (!mflag && fromatty) {
  				ointer = interactive;
***************
*** 1497,1507 ****
  	int pid;
  	sig_t old1, old2;
  	char shellnam[40], *shell, *namep; 
! #ifdef WAIT_USES_INT
  	int status;
! #else
  	union wait status;
! #endif
  
  	old1 = signal (SIGINT, SIG_IGN);
  	old2 = signal (SIGQUIT, SIG_IGN);
--- 1543,1553 ----
  	int pid;
  	sig_t old1, old2;
  	char shellnam[40], *shell, *namep; 
! #if defined(WAIT_USES_INT) || defined(USE_FILE64_FUNCS)
  	int status;
! #else /* ! WAIT_USES_INT && ! USE_FILE64_FUNCS */
  	union wait status;
! #endif /* ! WAIT_USES_INT && ! USE_FILE64_FUNCS */
  
  	old1 = signal (SIGINT, SIG_IGN);
  	old2 = signal (SIGQUIT, SIG_IGN);
***************
*** 2271,2282 ****
--- 2317,2337 ----
  	int argc;
  	char *argv[];
  {
+ #ifdef USE_FILE64_FUNCS
+ 	extern long long atoll();
+ #else /* ! USE_FILE64_FUNCS */
  	extern long atol();
+ #endif /* ! USE_FILE64_FUNCS */
  	if (argc != 2)
  		printf("restart: offset not specified\n");
  	else {
+ #if defined(USE_FILE64_FUNCS) || defined(HAVE_ATOLL)
+ 		restart_point = atoll(argv[1]);
+ 		printf("restarting at %lld. %s\n", restart_point,
+ #else /* ! USE_FILE64_FUNCS */
  		restart_point = atol(argv[1]);
  		printf("restarting at %ld. %s\n", restart_point,
+ #endif /* ! USE_FILE64_FUNCS */
  		    "execute get, put or append to initiate transfer");
  	}
  }
***************
*** 2360,2365 ****
--- 2415,2429 ----
  		code = -1;
  		return;
  	}
+ 	/*
+ 	 * It turns out that if you did a directory listing right
+ 	 * before this, the FTP server is still in ASCII mode and may
+ 	 * use a really inefficient method for determining file size
+ 	 * (read in the entire file).  Switch back to the "right" mode
+ 	 * if necessary to fix this.
+ 	 */
+ 
+ 	changetype(type, 0);
  	(void) command("SIZE %s", argv[1]);
  }
  
***************
*** 2414,2419 ****
--- 2478,2618 ----
  			argv[1], argv[2]);
  }
  
+ /*
+  * Set local default tcp buffer size
+  */
+ do_lbufsize(argc, argv)
+ 	int argc;
+ 	char *argv[];
+ {
+ 	int val;
+ 
+ 	if (argc > 2) {
+ 		printf("usage: %s [buffer size]\n", argv[0]);
+ 		code = -1;
+ 		return;
+ 	}
+ 
+ 	if (argc > 1) {
+ 		val = atoi(argv[1]);
+ 		if (val < 0) {
+ 			printf("%s: bad buffer size\n", argv[1]);
+ 			code = -1;
+ 			return;
+ 		}
+ 		lbufsize = val;
+ 		if (lbufsize)
+ 			printf("Set local TCP buffer size to %d bytes\n",
+ 				lbufsize);
+ 		else
+ 			printf("Set local TCP buffer size to system default\n");
+ 	} else {
+ 		if (lbufsize)
+ 			printf("Local TCP buffer size is currently set to "
+ 				"%d bytes\n", lbufsize);
+ 		else
+ 			printf("Using system default TCP buffer size\n");
+ 	}
+ }
+ 
+ /*
+  * Set remote default tcp buffer size
+  */
+ 
+ do_rbufsize(argc, argv)
+ 	int argc;
+ 	char *argv[];
+ {
+ 	(void) command(argc > 1 ? "SITE RBUFSZ %s" : "SITE RBUFSZ" , argv[1]);
+ }
+ 
+ #ifdef SGI_DIRECT_IO
+ /*
+  * Set the direct I/O buffer size
+  */
+ 
+ direct(argc, argv)
+ 	int argc;
+ 	char *argv[];
+ {
+ 	int val;
+ 
+ 	if (argc != 2) {
+ 		fprintf(stderr, "Usage: %s buffer-size\n", argv[0]);
+ 		code = -1;
+ 		return;
+ 	}
+ 
+ 	val = atoi(argv[1]);
+ 	if (val < 0) {
+ 		fprintf(stderr, "%s: Bad buffer size.\n", argv[1]);
+ 		code = -1;
+ 		return;
+ 	}
+ 
+ 	directsize = val;
+ 
+ 	printf("Direct I/O buffer size set to %d bytes.\n", directsize);
+ }
+ #endif /* SGI_DIRECT_IO */
+ 
+ #ifdef FORE_ATM_FTP
+ /*
+  * Enable ATM file transfer
+  */
+ 
+ setatm()
+ {
+ 	atm = !atm;
+ 	printf("ATM file transfer %s.\n", onoff(atm));
+ 	code = atm;
+ }
+ 
+ /*
+  * Set ATM Peak cell rate
+  */
+ #define OC3_LINE_RATE   353207  /* OC-3 */
+ #define OC12_LINE_RATE  1412830 /* OC-12 */
+ #define OC48_LINE_RATE  5633207 /* OC-48 */
+ 
+ setatmpcr(argc, argv)
+ 	int argc;
+ 	char *argv[];
+ {
+ 	int val;
+ 
+ 	if (argc != 2) {
+ 		fprintf(stderr, "Usage: %s [cell rate | oc3 | oc12 | "
+ 			"[oc48]\n", argv[0]);
+ 		code = -1;
+ 		return;
+ 	}
+ 
+ 	val = atoi(argv[1]);
+ 
+ 	if (val < 0) {
+ 		if (strcmp(argv[1], "oc3") == 0)
+ 			val = 353207;	/* OC-3 line rate*/
+ 		else if (strcmp(argv[1], "oc12") == 0)
+ 			val = 1412830;	/* OC-12 line rate*/
+ 		else if (strcmp(argv[1], "oc48") == 0)
+ 			val = 5633207;	/* OC-48 line rate */
+ 		else {
+ 			fprintf(stderr, "%s: Invalid cell rate: %s\n",
+ 				argv[0], argv[1]);
+ 			code = -1;
+ 			return;
+ 		}
+ 	}
+ 
+ 	atmpcr = val;
+ 
+ 	printf("ATM Peak Cell Rate set to %d.\n", atmpcr);
+ 
+ 	code = 1;
+ }
+ #endif /* FORE_ATM_FTP */
+ 
  #ifndef NO_PASSIVE_MODE
  /*
   * Start up passive mode interaction
***************
*** 2426,2430 ****
--- 2625,2637 ----
  	passivemode = !passivemode;
  	printf("Passive mode %s.\n", onoff(passivemode));
  	code = passivemode;
+ }
+ #endif
+ 
+ #if defined(KERBEROS) || defined(GSSAPI)
+ /* wrapper command for AUTH */
+ auth()
+ {
+ 	do_auth();
  }
  #endif
Index: krb5/appl/gssftp/ftp/cmdtab.c
diff -c krb5/appl/gssftp/ftp/cmdtab.c:1.1.1.2 krb5/appl/gssftp/ftp/cmdtab.c:1.7
*** krb5/appl/gssftp/ftp/cmdtab.c:1.1.1.2	Fri Feb 22 16:31:30 2002
--- krb5/appl/gssftp/ftp/cmdtab.c	Sun Feb 24 22:56:37 2002
***************
*** 58,71 ****
  int	account(), doproxy(), reset(), setcase(), setntrans(), setnmap();
  int	setsunique(), setrunique(), cdup(), macdef(), domacro();
  int	sizecmd(), modtime(), newer(), rmtstatus();
! int	do_chmod(), do_umask(), siteidle();
  #ifndef NO_PASSIVE_MODE
  int	setpassive();
  #endif
  
  char	accounthelp[] =	"send account command to remote server";
  char	appendhelp[] =	"append to a file";
  char	asciihelp[] =	"set ascii transfer type";
  char	beephelp[] =	"beep when command completed";
  char	binaryhelp[] =	"set binary transfer type";
  char	casehelp[] =	"toggle mget upper/lower case id mapping";
--- 58,88 ----
  int	account(), doproxy(), reset(), setcase(), setntrans(), setnmap();
  int	setsunique(), setrunique(), cdup(), macdef(), domacro();
  int	sizecmd(), modtime(), newer(), rmtstatus();
! int	do_chmod(), do_umask(), siteidle(), do_lbufsize(), do_rbufsize();
  #ifndef NO_PASSIVE_MODE
  int	setpassive();
  #endif
+ #if defined(KERBEROS) || defined(GSSAPI)
+ int auth();
+ #endif
+ #ifdef SGI_DIRECT_IO
+ int	direct();
+ #endif
+ #ifdef FORE_ATM_FTP
+ int	setatm();
+ int	setatmpcr();
+ #endif /* FORE_ATM_FTP */
  
  char	accounthelp[] =	"send account command to remote server";
  char	appendhelp[] =	"append to a file";
  char	asciihelp[] =	"set ascii transfer type";
+ #ifdef FORE_ATM_FTP
+ char	atmhelp[] =	"Toggle ATM file transfer";
+ char	atmpcrhelp[] =	"Set ATM Peak Cell Rate";
+ #endif /* FORE_ATM_FTP */
+ #if defined(KERBEROS) || defined(GSSAPI)
+ char	authhelp[] = "authenticate using kerberos or gssapi";
+ #endif
  char	beephelp[] =	"beep when command completed";
  char	binaryhelp[] =	"set binary transfer type";
  char	casehelp[] =	"toggle mget upper/lower case id mapping";
***************
*** 139,144 ****
--- 156,167 ----
  #ifndef NO_PASSIVE_MODE
  char	setpassivehelp[] = "toggle passive transfer mode";
  #endif
+ char	lbufsizehelp[]= "set local tcp buffer size";
+ char	rbufsizehelp[]= "set remote tcp buffer size";
+ char	reputhelp[]=	"put file starting at end of remote file";
+ #ifdef SGI_DIRECT_IO
+ char	directhelp[]=	"set direct I/O buffer size";
+ #endif
  
  struct cmd cmdtab[] = {
  	{ "!",		shellhelp,	0,	0,	0,	shell },
***************
*** 146,151 ****
--- 169,181 ----
  	{ "account",	accounthelp,	0,	1,	1,	account},
  	{ "append",	appendhelp,	1,	1,	1,	put },
  	{ "ascii",	asciihelp,	0,	1,	1,	setascii },
+ #ifdef FORE_ATM_FTP
+ 	{ "atm",	atmhelp,	0,	1,	0,	setatm },
+ 	{ "atmpcr",	atmpcrhelp,	0,	1,	0,	setatmpcr },
+ #endif /* FORE_ATM_FTP */
+ #if defined(KERBEROS) || defined(GSSAPI)
+ 	{ "auth",	authhelp,	0,	1,	1,	auth }, 
+ #endif
  	{ "bell",	beephelp,	0,	0,	0,	setbell },
  	{ "binary",	binaryhelp,	0,	1,	1,	setbinary },
  	{ "bye",	quithelp,	0,	0,	0,	quit },
***************
*** 161,166 ****
--- 191,199 ----
  	{ "delete",	deletehelp,	0,	1,	1,	delete_file },
  	{ "debug",	debughelp,	0,	0,	0,	setdebug },
  	{ "dir",	dirhelp,	1,	1,	1,	ls },
+ #ifdef SGI_DIRECT_IO
+ 	{ "direct",	direct,		0,	1,	0,	direct },
+ #endif
  	{ "disconnect",	disconhelp,	0,	1,	1,	disconnect },
  	{ "form",	formhelp,	0,	1,	1,	setform },
  	{ "get",	receivehelp,	1,	1,	1,	get },
***************
*** 169,174 ****
--- 202,208 ----
  	{ "help",	helphelp,	0,	0,	1,	help },
  	{ "idle",	idlehelp,	0,	1,	1,	siteidle },
  	{ "image",	binaryhelp,	0,	1,	1,	setbinary },
+ 	{ "lbufsize",	lbufsizehelp,	0,	0,	0,	do_lbufsize },
  	{ "lcd",	lcdhelp,	0,	0,	0,	lcd },
  	{ "ls",		lshelp,		1,	1,	1,	ls },
  	{ "macdef",	macdefhelp,	0,	0,	0,	macdef },
***************
*** 199,209 ****
--- 233,245 ----
  	{ "pwd",	pwdhelp,	0,	1,	1,	pwd },
  	{ "quit",	quithelp,	0,	0,	0,	quit },
  	{ "quote",	quotehelp,	1,	1,	1,	quote },
+ 	{ "rbufsize",	rbufsizehelp,	0,	1,	1,	do_rbufsize },
  	{ "recv",	receivehelp,	1,	1,	1,	get },
  	{ "reget",	regethelp,	1,	1,	1,	reget },
  	{ "rstatus",	rmtstatushelp,	0,	1,	1,	rmtstatus },
  	{ "rhelp",	remotehelp,	0,	1,	1,	rmthelp },
  	{ "rename",	renamehelp,	0,	1,	1,	renamefile },
+ 	{ "reput",	reputhelp,	1,	1,	1,	put },
  	{ "reset",	resethelp,	0,	1,	1,	reset },
  	{ "restart",	restarthelp,	1,	1,	1,	restart },
  	{ "rmdir",	rmdirhelp,	0,	1,	1,	removedir },
Index: krb5/appl/gssftp/ftp/configure.in
diff -c krb5/appl/gssftp/ftp/configure.in:1.1.1.1 krb5/appl/gssftp/ftp/configure.in:removed
*** krb5/appl/gssftp/ftp/configure.in:1.1.1.1	Mon Jun  2 17:54:20 1997
--- krb5/appl/gssftp/ftp/configure.in	Sun Mar 16 20:22:06 2003
***************
*** 1,21 ****
- AC_INIT(ftp.c)
- CONFIG_RULES
- AC_CONST
- AC_PROG_INSTALL
- KRB5_SIGTYPE
- USE_ANAME
- CHECK_SIGPROCMASK
- CHECK_WAIT_TYPE
- DECLARE_SYS_ERRLIST
- AC_CHECK_SIZEOF(short)
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- AC_FUNC_VFORK
- AC_HAVE_FUNCS(getcwd getdtablesize)
- AC_HEADER_STDARG
- AC_CHECK_HEADERS(sys/select.h)
- AC_HEADER_CHECK(termios.h,AC_FUNC_CHECK(cfsetispeed,AC_DEFINE(POSIX_TERMIOS)))
- AC_CHECK_HEADERS(stdlib.h)
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/gssftp/ftp/ftp.M
diff -c krb5/appl/gssftp/ftp/ftp.M:1.1.1.2 krb5/appl/gssftp/ftp/ftp.M:1.4
*** krb5/appl/gssftp/ftp/ftp.M:1.1.1.2	Fri Feb 22 16:31:30 2002
--- krb5/appl/gssftp/ftp/ftp.M	Sun Feb 24 22:56:38 2002
***************
*** 166,171 ****
--- 166,177 ----
  .SM ASCII .
  This is the default type.
  .TP
+ .B auth
+ Uses the
+ .B AUTH/ADAT
+ mechanism (see above) to authenticate the user
+ .SM AUTH
+ .TP
  .B bell
  Arrange that a bell be sounded after each file transfer command is
  completed.
***************
*** 365,370 ****
--- 371,388 ----
  .I seconds
  is omitted, the current inactivity timer is printed.
  .TP
+ \fBlbufsize\fP [\fIbytes\fP]
+ Set the TCP buffer sizes on the local machine to
+ .I bytes
+ bytes. If
+ .I bytes
+ is zero, the TCP buffer sizes are not set; the system default is used. If
+ .I bytes
+ is omitted, the current TCP buffer sizes of the local machine are printed.
+ Usually setting the TCP buffer sizes sets the TCP window size. Use with the
+ .B rbufsize
+ command.
+ .TP
  \fBlcd\fP [\fIdirectory\fP]
  Change the working directory on the local machine.  If no
  .I directory
***************
*** 711,716 ****
--- 729,746 ----
  The arguments specified are sent, verbatim, to the remote
  .SM FTP
  server.
+ .TP
+ \fBrbufsize\fP [\fIbytes\fP]
+ Set the TCP buffer sizes on the remote machine to
+ .I bytes
+ bytes. If
+ .I bytes
+ is zero, the TCP buffer sizes are not set; the system default is used. If
+ .I bytes
+ is omitted, the current TCP buffer sizes of the remote machine are printed.
+ Usually setting the TCP buffer sizes sets the TCP window size. Use with the
+ .B lbufsize
+ command.
  .TP
  \fBrecv\fP \fIremote-file\fP [\fIlocal-file\fP]
  A synonym for get.
Index: krb5/appl/gssftp/ftp/ftp.c
diff -c krb5/appl/gssftp/ftp/ftp.c:1.1.1.3 krb5/appl/gssftp/ftp/ftp.c:1.19
*** krb5/appl/gssftp/ftp/ftp.c:1.1.1.3	Fri Feb 22 16:31:31 2002
--- krb5/appl/gssftp/ftp/ftp.c	Tue Jan  7 17:00:22 2003
***************
*** 67,73 ****
  #include <sys/param.h>
  #include <sys/stat.h>
  #include <sys/ioctl.h>
! #ifndef KRB5_KRB4_COMPAT
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <sys/socket.h>
  #endif
--- 67,73 ----
  #include <sys/param.h>
  #include <sys/stat.h>
  #include <sys/ioctl.h>
! #if !defined(KRB5_KRB4_COMPAT) || defined(OMIT_KRB4_COMPAT)
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <sys/socket.h>
  #endif
***************
*** 86,98 ****
  #include <stdio.h>
  #include <signal.h>
  #include <string.h>
  #include <errno.h>
! #ifndef KRB5_KRB4_COMPAT
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <netdb.h>
  #endif
  #include <fcntl.h>
  #include <pwd.h>
  #ifndef STDARG
  #if (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
  #define STDARG
--- 86,104 ----
  #include <stdio.h>
  #include <signal.h>
  #include <string.h>
+ #include <unistd.h>
  #include <errno.h>
! #if !defined(KRB5_KRB4_COMPAT) || defined(OMIT_KRB4_COMPAT)
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <netdb.h>
  #endif
  #include <fcntl.h>
  #include <pwd.h>
+ 
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
+ 
  #ifndef STDARG
  #if (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
  #define STDARG
***************
*** 111,117 ****
  #define L_INCR 1
  #endif
  
! #ifdef KRB5_KRB4_COMPAT
  #include <krb.h>
  
  KTEXT_ST ticket;
--- 117,123 ----
  #define L_INCR 1
  #endif
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  #include <krb.h>
  
  KTEXT_ST ticket;
***************
*** 161,166 ****
--- 167,179 ----
  #endif
  #endif
  
+ #ifdef SGI_DIRECT_IO
+ static int directinit(char *, int);
+ static off_t directsend(char *, int, int);
+ static off_t directrecv(char *, int, int);
+ struct dioattr dio;
+ #endif /* SGI_DIRECT_IO */
+ 
  extern int connected;
  
  #define herror()	printf("unknown host\n")
***************
*** 392,398 ****
  	int length;
  
  	if (auth_type && clevel != PROT_C) {
! #ifdef KRB5_KRB4_COMPAT
  		if (strcmp(auth_type, "KERBEROS_V4") == 0)
  		    if ((length = clevel == PROT_P ?
  			krb_mk_priv((unsigned char *)cmd, (unsigned char *)out,
--- 405,411 ----
  	int length;
  
  	if (auth_type && clevel != PROT_C) {
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  		if (strcmp(auth_type, "KERBEROS_V4") == 0)
  		    if ((length = clevel == PROT_P ?
  			krb_mk_priv((unsigned char *)cmd, (unsigned char *)out,
***************
*** 665,671 ****
  					code, radix_error(kerror), obuf);
  			    n = '5';
  			}
! #ifdef KRB5_KRB4_COMPAT
  			else if (strcmp(auth_type, "KERBEROS_V4") == 0)
  				if ((kerror = safe ?
  				  krb_rd_safe((unsigned char *)ibuf, len,
--- 678,684 ----
  					code, radix_error(kerror), obuf);
  			    n = '5';
  			}
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  			else if (strcmp(auth_type, "KERBEROS_V4") == 0)
  				if ((kerror = safe ?
  				  krb_rd_safe((unsigned char *)ibuf, len,
***************
*** 762,768 ****
--- 775,785 ----
  
  	t.tv_sec = (long) sec;
  	t.tv_usec = 0;
+ #ifdef USE_FILE64_FUNCS
+ 	return(select(32, (int *) mask, (int *) 0, (int *) 0, &t));
+ #else /* ! USE_FILE64_FUNCS */
  	return(select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));
+ #endif /* ! USE_FILE64_FUNCS */
  }
  
  jmp_buf	sendabort;
***************
*** 805,818 ****
  	char *cmd, *local, *remote;
  	int printnames;
  {
- 	struct stat st;
  	struct timeval start, stop;
  	register int c, d;
  	FILE *volatile fin, *volatile dout = 0, *popen();
  	int (*volatile closefunc)(), pclose(), fclose();
  	volatile sig_t oldintr, oldintp;
! 	volatile long bytes = 0, hashbytes = HASHBYTES;
! 	char *volatile lmode, buf[FTP_BUFSIZ], *bufp;
  	sigtype abortsend();
  
  	if (verbose && printnames) {
--- 822,839 ----
  	char *cmd, *local, *remote;
  	int printnames;
  {
  	struct timeval start, stop;
  	register int c, d;
  	FILE *volatile fin, *volatile dout = 0, *popen();
  	int (*volatile closefunc)(), pclose(), fclose();
  	volatile sig_t oldintr, oldintp;
! #if defined(USE_FILE64_FUNCS)
! 	volatile off64_t bytes = 0LL, hashbytes = (off64_t)HASHBYTES;
! #else
! 	volatile off_t bytes = 0, hashbytes = HASHBYTES;
! #endif /* ! USE_FILE64_FUNCS */
! 	struct stat st;
! 	char *volatile lmode, buf[FTP_BUFSIZ], *volatile bufp;
  	sigtype abortsend();
  
  	if (verbose && printnames) {
***************
*** 861,867 ****
--- 882,892 ----
  		}
  		closefunc = pclose;
  	} else {
+ #ifdef USE_FILE64_FUNCS
+ 		fin = fopen(local, "rl");
+ #else /* ! USE_FILE64_FUNCS */
  		fin = fopen(local, "r");
+ #endif /* ! USE_FILE64_FUNCS */
  		if (fin == NULL) {
  			fprintf(stderr, "local: %s: %s\n", local,
  				strerror(errno));
***************
*** 879,884 ****
--- 904,917 ----
  			return;
  		}
  	}
+ #ifdef SGI_DIRECT_IO
+ 	if (directsize)
+ 		if (directinit(local, fileno(fin)) < 0) {
+ 			fclose(fin);
+ 			code = -1;
+ 			return;
+ 		}
+ #endif /* SGI_DIRECT_IO */
  	if (initconn()) {
  		(void) signal(SIGINT, oldintr);
  		if (oldintp)
***************
*** 893,899 ****
  
  	if (restart_point &&
  	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
! 		if (fseek(fin, (long) restart_point, 0) < 0) {
  			fprintf(stderr, "local: %s: %s\n", local,
  				strerror(errno));
  			restart_point = 0;
--- 926,938 ----
  
  	if (restart_point &&
  	    (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
! #ifdef USE_FILE64_FUNCS
! 		if (fseek(fin, (off64_t) restart_point, 0) < 0) {
! #elif defined(HAVE_FSEEKO) /* ! USE_FILE64_FUNCS */
! 		if (fseeko(fin, restart_point, 0) < 0) {
! #else /* ! USE_FILE64_FUNCS && ! (SIZEOF_OFF_T == 8) */
! 		if (fseek(fin, (off_t) restart_point, 0) < 0) {
! #endif /* ! USE_FILE64_FUNCS */
  			fprintf(stderr, "local: %s: %s\n", local,
  				strerror(errno));
  			restart_point = 0;
***************
*** 901,907 ****
--- 940,952 ----
  				(*closefunc)(fin);
  			return;
  		}
+ #ifdef USE_FILE64_FUNCS
+ 		if (command("REST %lld", (off64_t) restart_point)
+ #elif SIZEOF_OFF_T == 8 /* ! USE_FILE64_FUNCS */
+ 		if (command("REST %lld", (off_t) restart_point)
+ #else
  		if (command("REST %ld", (long) restart_point)
+ #endif /* ! USE_FILE64_FUNCS */
  			!= CONTINUE) {
  			restart_point = 0;
  			if (closefunc != NULL)
***************
*** 939,944 ****
--- 984,1002 ----
  	case TYPE_I:
  	case TYPE_L:
  		errno = d = 0;
+ #ifdef SGI_DIRECT_IO
+ 		if (directsize) {
+ 			bytes = directsend(local, fileno(fin), fileno(dout));
+ 		} else {
+ #endif /* SGI_DIRECT_IO */
+ #ifdef FORE_ATM_FTP
+ 		if (atm) {
+ 			bytes = swp_xmit_go(fileno(dout), fileno(fin));
+ 			atm_disconnect(fileno(dout));
+ 			if (bytes == -1)
+ 				fprintf(stderr, "ATM network write failed\n");
+ 		} else {
+ #endif /* FORE_ATM_FTP */
  		while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
  			bytes += c;
  			for (bufp = buf; c > 0; c -= d, bufp += d)
***************
*** 968,973 ****
--- 1026,1037 ----
  				perror("netout");
  			bytes = -1;
  		}
+ #ifdef FORE_ATM_FTP
+ 		}
+ #endif /* FORE_ATM_FTP */
+ #ifdef SGI_DIRECT_IO
+ 		}
+ #endif /* SGI_DIRECT_IO */
  		break;
  
  	case TYPE_A:
***************
*** 1064,1077 ****
  	volatile sig_t oldintr, oldintp;
  	volatile int is_retr, tcrflag, bare_lfs = 0;
  	char *gunique();
- 	static int bufsize;
  	static char *buf;
  	int blksize;
- 	volatile long bytes = 0, hashbytes = HASHBYTES;
  	register int c, d;
  	struct timeval start, stop;
  	struct stat st;
! 	off_t lseek();
  	sigtype abortrecv();
  
  	is_retr = strcmp(cmd, "RETR") == 0;
--- 1128,1147 ----
  	volatile sig_t oldintr, oldintp;
  	volatile int is_retr, tcrflag, bare_lfs = 0;
  	char *gunique();
  	static char *buf;
  	int blksize;
  	register int c, d;
  	struct timeval start, stop;
+ 	static int bufsize;
+ #ifdef USE_FILE64_FUNCS
+ 	volatile off64_t bytes = 0LL, hashbytes = (off64_t)HASHBYTES;
+ #else  /* ! USE_FILE64_FUNCS */
+ 	volatile off_t bytes = 0, hashbytes = HASHBYTES;
+ #endif /* ! USE_FILE64_FUNCS */
  	struct stat st;
! #ifdef FORE_ATM_FTP
! 	int save_atm;
! #endif /* FORE_ATM_FTP */
  	sigtype abortrecv();
  
  	is_retr = strcmp(cmd, "RETR") == 0;
***************
*** 1153,1167 ****
--- 1223,1257 ----
  			changetype(TYPE_A, 0);
  	} else if (curtype != type)
  		changetype(type, 0);
+ #ifdef FORE_ATM_FTP
+ 	if (!is_retr) {
+ 		save_atm = atm;
+ 		atm = 0;
+ 	}
+ #endif /* FORE_ATM_FTP */
  	if (initconn()) {
+ #ifdef FORE_ATM_FTP
+ 		if (!is_retr)
+ 			atm = save_atm;
+ #endif /* FORE_ATM_FTP */
  		(void) signal(SIGINT, oldintr);
  		code = -1;
  		return;
  	}
+ #ifdef FORE_ATM_FTP
+ 	if (!is_retr)
+ 		atm = save_atm;
+ #endif /* FORE_ATM_FTP */
  	if (setjmp(recvabort))
  		goto abort;
  	if (is_retr && restart_point &&
+ #ifdef USE_FILE64_FUNCS
+ 	    command("REST %lld", (off64_t) restart_point) != CONTINUE)
+ #elif SIZEOF_OFF_T == 8 /* ! USE_FILE64_FUNCS */
+ 	    command("REST %lld", (off_t) restart_point) != CONTINUE)
+ #else
  	    command("REST %ld", (long) restart_point) != CONTINUE)
+ #endif /* ! USE_FILE64_FUNCS */
  		return;
  	if (remote) {
  		if (command("%s %s", cmd, remote) != PRELIM) {
***************
*** 1196,1201 ****
--- 1286,1297 ----
  		}
  		closefunc = fclose;
  	}
+ #if SGI_DIRECT_IO
+ 	if (is_retr && directsize) {
+ 		if (directinit(local, fileno(fout)) < 0)
+ 			goto abort;
+ 	}
+ #endif /* SGI_DIRECT_IO */
  	blksize = FTP_BUFSIZ;
  #ifndef NOSTBLKSIZE
  	if (fstat(fileno(fout), &st) == 0 && st.st_blksize != 0)
***************
*** 1218,1224 ****
  	case TYPE_I:
  	case TYPE_L:
  		if (restart_point &&
! 		    lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
  			fprintf(stderr, "local: %s: %s\n", local,
  				strerror(errno));
  			if (closefunc != NULL)
--- 1314,1324 ----
  	case TYPE_I:
  	case TYPE_L:
  		if (restart_point &&
! #ifdef USE_FILE64_FUNCS
! 		    lseek(fileno(fout), (off64_t) restart_point, L_SET) < 0) {
! #else /* ! USE_FILE64_FUNCS */
! 		    lseek(fileno(fout), (off_t) restart_point, L_SET) < 0) {
! #endif /* ! USE_FILE64_FUNCS */
  			fprintf(stderr, "local: %s: %s\n", local,
  				strerror(errno));
  			if (closefunc != NULL)
***************
*** 1226,1231 ****
--- 1326,1344 ----
  			return;
  		}
  		errno = d = 0;
+ #ifdef SGI_DIRECT_IO
+ 		if (directsize)
+ 			bytes = directrecv(local, fileno(din), fileno(fout));
+ 		else {
+ #endif /* SGI_DIRECT_IO */
+ #ifdef FORE_ATM_FTP
+ 		if (is_retr && atm) {
+ 			bytes = swp_recv_go(fileno(din), fileno(fout));
+ 			atm_disconnect(fileno(din));
+ 			if (bytes == -1)
+ 				fprintf(stderr, "ATM network read failed\n");
+ 		} else {
+ #endif /* FORE_ATM_FTP */
  		while ((c = secure_read(fileno(din), buf, bufsize)) > 0) {
  			if ((d = write(fileno(fout), buf, c)) != c)
  				break;
***************
*** 1256,1261 ****
--- 1369,1380 ----
  			else
  				fprintf(stderr, "%s: short write\n", local);
  		}
+ #ifdef SGI_DIRECT_IO
+ 		}
+ #endif /* SGI_DIRECT_IO */
+ #ifdef FORE_ATM_FTP
+ 		}
+ #endif /* FORE_ATM_FTP */
  		break;
  
  	case TYPE_A:
***************
*** 1369,1374 ****
--- 1488,1638 ----
  	(void) signal(SIGINT, oldintr);
  }
  
+ #ifdef SGI_DIRECT_IO
+ /*
+  * Send a file via the magical SGI "direct" I/O mechanism
+  */
+ 
+ static int
+ directinit(char *local, int fin)
+ {
+ 	int flags;
+ 
+ 	if (fcntl(fin, F_DIOINFO, &dio) == -1) {
+ 		fprintf(stderr, "Cannot do direct I/O on %s: %s\n", local,
+ 			strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	if (directsize < dio.d_miniosz) {
+ 		fprintf(stderr, "Minimum direct I/O size must be %d.\n",
+ 			dio.d_miniosz);
+ 		return -1;
+ 	}
+ 
+ 	if (directsize % dio.d_miniosz) {
+ 		fprintf(stderr, "Direct I/O must be a multiple of %d bytes.\n",
+ 			dio.d_miniosz);
+ 		return -1;
+ 	}
+ 
+ 	if (directsize > dio.d_maxiosz) {
+ 		fprintf(stderr, "Maximum direct I/O size is %d bytes.\n",
+ 			dio.d_maxiosz);
+ 		return -1;
+ 	}
+ 
+ 	if ((flags = fcntl(fin, F_GETFL)) == -1) {
+ 		fprintf(stderr, "Cannot get file flags: %s\n", strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	if (fcntl(fin, F_SETFL, flags | FDIRECT) == -1) {
+ 		fprintf(stderr, "Cannot set FDIRECT flag for file %s: %s\n",
+ 			local, strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static off_t
+ directsend(char *local, int fin, int fout)
+ {
+ 	off_t bytes = 0, c, d;
+ 	char *buffer, *bufp;
+ 
+ 	if (! (buffer = valloc(directsize))) {
+ 		fprintf(stderr, "Cannot alloc %d bytes for transfer buffer.\n",
+ 			directsize);
+ 		return -1;
+ 	}
+ 
+ 	while ((c = read(fin, buffer, directsize)) > 0) {
+ 		bytes += c;
+ 		for (bufp = buffer; c > 0; c -= d, bufp += d)
+ 		if ((d = secure_write(fout, bufp, c)) <= 0)
+ 			break;
+ 	}
+ 
+ 	if (c < 0)
+ 		fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
+ 	if (d < 0 || (d = secure_flush(fout)) < 0) {
+ 		if (d == -1 && errno != EPIPE) 
+ 			perror("netout");
+ 		bytes = -1;
+ 	}
+ 
+ 	free(buffer);
+ 	return bytes;
+ }
+ 
+ static off_t
+ directrecv(char *local, int fin, int fout)
+ {
+ 	off_t bytes = 0, c, d;
+ 	char *buffer, *bufp;
+ 	int direct_turned_off = 0;
+ 	int flags;
+ 
+ 	if ((flags = fcntl(fout, F_GETFL)) == -1) {
+ 		fprintf(stderr, "Cannot get file flags: %s\n", strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	if (! (buffer = valloc(directsize))) {
+ 		fprintf(stderr, "Cannot alloc %d bytes for transfer buffer.\n",
+ 			directsize);
+ 		return -1;
+ 	}
+ 
+ 	while ((c = secure_read(fin, buffer, directsize)) > 0) {
+ 
+ 		while (c < directsize && (d = secure_read(fin, buffer + c,
+ 							  directsize - c)) > 0)
+ 			c += d;
+ 
+ 		bytes += c;
+ 		for (bufp = buffer; c > 0; c -= d, bufp += d) {
+ 			if (!direct_turned_off && (c % directsize)) {
+ 				/*
+ 				 * Before we turn off direct I/O, write
+ 				 * as large of a chunk as we can using it.
+ 				 */
+ 				if (c / dio.d_miniosz) {
+ 					d = write(fout, bufp,
+ 					  (c / dio.d_miniosz) * dio.d_miniosz);
+ 					continue;
+ 				}
+ 
+ 				flags &= ~FDIRECT;
+ 				direct_turned_off = 1;
+ 				fcntl(fout, F_SETFL, flags);
+ 			}
+ 			if ((d = write(fout, bufp, c)) <= 0)
+ 				break;
+ 		}
+ 	}
+ 
+ 	if (c < 0) {
+ 		if (c == -1 && errno != EPIPE)
+ 			perror("netin");
+ 		bytes = -1;
+ 	}
+ 	if (d < c) {
+ 		if (d < 0)
+ 			fprintf(stderr, "local: %s: %s\n", local,
+ 				strerror(errno));
+ 		else
+ 			fprintf(stderr, "%s: short write\n", local);
+ 	}
+ 
+ 	free(buffer);
+ 	return bytes;
+ }
+ 
+ #endif /* SGI_DIRECT_IO */
+ 
  /*
   * Need to start a listen on the data channel before we send the command,
   * otherwise the server's connect may fail.
***************
*** 1380,1386 ****
--- 1644,1693 ----
  	int on = 1;
  #ifndef NO_PASSIVE_MODE
  	int a1,a2,a3,a4,p1,p2;
+ #endif /* NO_PASSIVE_MODE */
  
+ #ifdef FORE_ATM_FTP
+ 	if (atm) {
+ 		unsigned char hw_address[20], bhli[8];
+ 		int hw_scan[20], bhli_scan[8], i;
+ 
+ 		if (command("SITE ATMPASV") != COMPLETE) {
+ 			printf("ATM address query failed; does remote host "
+ 			       "support ATM file transfer?\n");
+ 			return 1;
+ 		}
+ 
+ 		if (sscanf(pasv, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,"
+ 			   "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
+ 			   &hw_scan[0], &hw_scan[1], &hw_scan[2], &hw_scan[3],
+ 			   &hw_scan[4], &hw_scan[5], &hw_scan[6], &hw_scan[7],
+ 			   &hw_scan[8], &hw_scan[9], &hw_scan[10],
+ 			   &hw_scan[11], &hw_scan[12], &hw_scan[13],
+ 			   &hw_scan[14], &hw_scan[15], &hw_scan[16],
+ 			   &hw_scan[17], &hw_scan[18], &hw_scan[19],
+ 			   &bhli_scan[0], &bhli_scan[1], &bhli_scan[2],
+ 			   &bhli_scan[3], &bhli_scan[4], &bhli_scan[5],
+ 			   &bhli_scan[6], &bhli_scan[7]) != 28) {
+ 			printf("ATM address scan failure!  This shouldn't "
+ 			       "happen!\n");
+ 			return 1;
+ 		}
+ 
+ 		for (i = 0; i < sizeof(hw_address); i++)
+ 			hw_address[i] = hw_scan[i];
+ 		
+ 		for (i = 0; i < sizeof(bhli); i++)
+ 			bhli[i] = bhli_scan[i];
+ 
+ 		if ((data = atminitconn(hw_address, bhli)) == -1)
+ 			return 1;
+ 		else
+ 			return 0;
+ 	}
+ 
+ #endif /* FORE_ATM_FTP */
+ 
+ #ifndef NO_PASSIVE_MODE
  	if (passivemode) {
  		data = socket(AF_INET, SOCK_STREAM, 0);
  		if (data < 0) {
***************
*** 1390,1395 ****
--- 1697,1708 ----
  		if (options & SO_DEBUG &&
  		    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
  			perror("ftp: setsockopt (ignored)");
+ 		if (lbufsize) {
+ 			if (setsockopt(data, SOL_SOCKET, SO_SNDBUF, (char *)&lbufsize, sizeof(lbufsize)) < 0)
+ 				perror("ftp: setsockopt(SO_SNDBUF) (ignored)");
+ 			if (setsockopt(data, SOL_SOCKET, SO_RCVBUF, (char *)&lbufsize, sizeof(lbufsize)) < 0)
+ 				perror("ftp: setsockopt(SO_RCVBUF) (ignored)");
+ 		}
  		if (command("PASV") != COMPLETE) {
  			printf("Passive mode refused.  Turning off passive mode.\n");
  			passivemode = 0;
***************
*** 1451,1456 ****
--- 1764,1775 ----
  		perror("ftp: bind");
  		goto bad;
  	}
+ 	if (lbufsize) {
+ 		if (setsockopt(data, SOL_SOCKET, SO_SNDBUF, (char *)&lbufsize, sizeof(lbufsize)) < 0)
+ 			perror("ftp: setsockopt(SO_SNDBUF) (ignored)");
+ 		if (setsockopt(data, SOL_SOCKET, SO_RCVBUF, (char *)&lbufsize, sizeof(lbufsize)) < 0)
+ 			perror("ftp: setsockopt(SO_RCVBUF) (ignored)");
+ 	}
  	if (options & SO_DEBUG &&
  	    setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
  		perror("ftp: setsockopt (ignored)");
***************
*** 1523,1529 ****
  
  ptransfer(direction, bytes, t0, t1)
  	char *direction;
! 	long bytes;
  	struct timeval *t0, *t1;
  {
  	struct timeval td;
--- 1842,1852 ----
  
  ptransfer(direction, bytes, t0, t1)
  	char *direction;
! #ifdef USE_FILE64_FUNCS
! 	off64_t bytes;
! #else /* ! USE_FILE64_FUNCS */
! 	off_t bytes;
! #endif /* ! USE_FILE64_FUNCS */
  	struct timeval *t0, *t1;
  {
  	struct timeval td;
***************
*** 1534,1540 ****
--- 1857,1867 ----
  		s = td.tv_sec + (td.tv_usec / 1000000.);
  #define	nz(x)	((x) == 0 ? 1 : (x))
  		kbs = (bytes / nz(s))/1024.0;
+ #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
+ 		printf("%lld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
+ #else /* ! USE_FILE64_FUNCS */
  		printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
+ #endif /* ! USE_FILE64_FUNCS */
  		    bytes, direction, s, kbs);
  	}
  }
***************
*** 1595,1601 ****
  		char *authtype;
  		int clvl;
  	        int dlvl;
! #ifdef KRB5_KRB4_COMPAT
  		C_Block session;
  		Key_schedule schedule;
  #endif /* KRB5_KRB4_COMPAT */
--- 1922,1931 ----
  		char *authtype;
  		int clvl;
  	        int dlvl;
! #if defined(GSSAPI)
! 		gss_ctx_id_t gcontext;
! #endif /* GSSAPI */
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  		C_Block session;
  		Key_schedule schedule;
  #endif /* KRB5_KRB4_COMPAT */
***************
*** 1675,1681 ****
  	     clevel = PROT_C;
  	if (!dlevel)
  	     dlevel = PROT_C;
! #ifdef KRB5_KRB4_COMPAT
  	memcpy(ip->session, cred.session, sizeof(cred.session));
  	memcpy(cred.session, op->session, sizeof(cred.session));
  	memcpy(ip->schedule, schedule, sizeof(schedule));
--- 2005,2015 ----
  	     clevel = PROT_C;
  	if (!dlevel)
  	     dlevel = PROT_C;
! #if defined(GSSAPI)
! 	ip->gcontext = gcontext;
! 	gcontext = op->gcontext;
! #endif /* GSSAPI */
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	memcpy(ip->session, cred.session, sizeof(cred.session));
  	memcpy(cred.session, op->session, sizeof(cred.session));
  	memcpy(ip->schedule, schedule, sizeof(schedule));
***************
*** 1890,1896 ****
  	return(new);
  }
  
! #ifdef KRB5_KRB4_COMPAT
  char realm[REALM_SZ + 1];
  #endif /* KRB5_KRB4_COMPAT */
  
--- 2224,2230 ----
  	return(new);
  }
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  char realm[REALM_SZ + 1];
  #endif /* KRB5_KRB4_COMPAT */
  
***************
*** 1909,1921 ****
  {
  	extern int setsafe();
  	int oldverbose = verbose;
! #ifdef KRB5_KRB4_COMPAT
  	char *service, inst[INST_SZ];
  	u_long cksum, checksum = (u_long) getpid();
  #endif /* KRB5_KRB4_COMPAT */
  #if defined(KRB5_KRB4_COMPAT) || defined(GSSAPI)
  	u_char out_buf[FTP_BUFSIZ];
  	int i;
  #endif /* KRB5_KRB4_COMPAT */
  
  	if (auth_type) return(1);	/* auth already succeeded */
--- 2243,2257 ----
  {
  	extern int setsafe();
  	int oldverbose = verbose;
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	char *service, inst[INST_SZ];
  	u_long cksum, checksum = (u_long) getpid();
  #endif /* KRB5_KRB4_COMPAT */
  #if defined(KRB5_KRB4_COMPAT) || defined(GSSAPI)
  	u_char out_buf[FTP_BUFSIZ];
  	int i;
+ 	char realhostname[128];
+ 	struct hostent *hp;
  #endif /* KRB5_KRB4_COMPAT */
  
  	if (auth_type) return(1);	/* auth already succeeded */
***************
*** 1928,1934 ****
--- 2264,2272 ----
  	  gss_name_t target_name;
  	  gss_buffer_desc send_tok, recv_tok, *token_ptr;
  	  char stbuf[FTP_BUFSIZ];
+ 	  char **service_name, **end_service_name;
  	  int comcode, trial;
+ 	  int noisyflag = 0;
  	  struct gss_channel_bindings_struct chan;
  	  chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32  */ 
  	  chan.initiator_address.length = 4;
***************
*** 1939,1944 ****
--- 2277,2296 ----
  	  chan.application_data.length = 0;
  	  chan.application_data.value = 0;
  
+  	  /*
+  	  **  Look up actual host name, from connection IP.
+  	  **  Since gss_import_name() -> krb5_sname_to_principal()
+  	  **  will arrive at an actual name anyway, this is not a
+  	  **  question of whether we want the cluster name or the
+  	  **  actual name, but whether we want the actual name to
+  	  **  be the correct one.
+  	  */
+  	  hp = gethostbyaddr(&hisctladdr.sin_addr, 4, AF_INET);
+  	  if (hp)
+  	    strncpy(realhostname, hp->h_name, sizeof(realhostname));
+  	  else
+  	    strncpy(realhostname, hostname, sizeof(realhostname));
+  
  	  if (verbose)
  	    printf("GSSAPI accepted as authentication type\n");
  	  
***************
*** 2065,2071 ****
  	  }
  	}
  #endif /* GSSAPI */
! #ifdef KRB5_KRB4_COMPAT
  	if (command("AUTH %s", "KERBEROS_V4") == CONTINUE) {
  	    if (verbose)
  		printf("%s accepted as authentication type\n", "KERBEROS_V4");
--- 2417,2423 ----
  	  }
  	}
  #endif /* GSSAPI */
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	if (command("AUTH %s", "KERBEROS_V4") == CONTINUE) {
  	    if (verbose)
  		printf("%s accepted as authentication type\n", "KERBEROS_V4");
Index: krb5/appl/gssftp/ftp/ftp_var.h
diff -c krb5/appl/gssftp/ftp/ftp_var.h:1.1.1.2 krb5/appl/gssftp/ftp/ftp_var.h:1.6
*** krb5/appl/gssftp/ftp/ftp_var.h:1.1.1.2	Fri Feb 22 16:31:31 2002
--- krb5/appl/gssftp/ftp/ftp_var.h	Mon Feb 25 22:28:57 2002
***************
*** 67,73 ****
  extern int	mapflag;	/* use mapin mapout templates on file names */
  extern int	code;		/* return/reply code for ftp command */
  extern int	crflag;		/* if 1, strip car. rets. on ascii gets */
! extern char	pasv[64];	/* passive port for proxy data connection */
  #ifndef NO_PASSIVE_MODE
  extern int	passivemode;	/* passive mode enabled */
  #endif
--- 67,73 ----
  extern int	mapflag;	/* use mapin mapout templates on file names */
  extern int	code;		/* return/reply code for ftp command */
  extern int	crflag;		/* if 1, strip car. rets. on ascii gets */
! extern char	pasv[128];	/* passive port for proxy data connection */
  #ifndef NO_PASSIVE_MODE
  extern int	passivemode;	/* passive mode enabled */
  #endif
***************
*** 106,111 ****
--- 106,125 ----
  extern int	mflag;		/* flag: if != 0, then active multi command */
  
  extern int	options;	/* used during socket creation */
+ extern int	lbufsize;	/* default local buffer size */
+ 
+ #ifdef SGI_DIRECT_IO
+ extern int	directsize;	/* Direct I/O buffer size */
+ #endif
+ 
+ #ifdef KERBEROS5
+ extern int	forward;	/* Should we forward credentials? */
+ #endif
+ 
+ #ifdef FORE_ATM_FTP
+ extern int	atm;		/* Are we doing ATM transfers? */
+ extern int	atmpcr;		/* What's the peak cell rate? */
+ #endif
  
  /*
   * Format of command table.
Index: krb5/appl/gssftp/ftp/glob.c
diff -c krb5/appl/gssftp/ftp/glob.c:1.1.1.3 krb5/appl/gssftp/ftp/glob.c:1.5
*** krb5/appl/gssftp/ftp/glob.c:1.1.1.3	Fri Feb 22 16:31:32 2002
--- krb5/appl/gssftp/ftp/glob.c	Sun Feb 24 22:56:39 2002
***************
*** 62,67 ****
--- 62,71 ----
  #define NCARGS 4096
  #endif
  
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
+ 
  #define	QUOTE 0200
  #define	TRIM 0177
  #define	eq(a,b)		(strcmp(a, b)==0)
Index: krb5/appl/gssftp/ftp/largefile.h
diff -c /dev/null krb5/appl/gssftp/ftp/largefile.h:1.1
*** /dev/null	Sun Mar 16 20:22:07 2003
--- krb5/appl/gssftp/ftp/largefile.h	Fri Feb  5 16:15:48 1999
***************
*** 0 ****
--- 1,22 ----
+ /*
+  * This header file contains functions and definitions for platforms
+  * (i.e. SPP-UX) that require separate facilities for accessing large
+  * files (64 bit)
+  */
+ 
+ #include <sys/cnx_types.h>
+ #include <sys/cnx_stat.h>
+ #include <sys/cnx_unistd.h>
+ 
+ #undef off_t
+ #define off_t off64_t
+ #undef stat()
+ #define stat(f, b) stat64(f, b)
+ #undef fstat()
+ #define fstat(f, b) fstat64(f, b)
+ #undef fseek()
+ #define fseek(s, o, w) fseek64(s, o, w)
+ #undef lseek()
+ #define lseek(f, o, w) lseek64(f, o, w)
+ #undef stat
+ #define stat stat64
Index: krb5/appl/gssftp/ftp/main.c
diff -c krb5/appl/gssftp/ftp/main.c:1.1.1.2 krb5/appl/gssftp/ftp/main.c:1.11
*** krb5/appl/gssftp/ftp/main.c:1.1.1.2	Fri Feb 22 16:31:32 2002
--- krb5/appl/gssftp/ftp/main.c	Tue Jan  7 17:00:22 2003
***************
*** 46,57 ****
   */
  #include <stdio.h>
  #include "ftp_var.h"
! #ifndef KRB5_KRB4_COMPAT
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <sys/socket.h>
  #endif
  #include <sys/ioctl.h>
- #include <sys/types.h>
  
  #include <arpa/ftp.h>
  
--- 46,57 ----
   */
  #include <stdio.h>
  #include "ftp_var.h"
! #include <sys/types.h>
! #if !defined(KRB5_KRB4_COMPAT) || defined(OMIT_KRB4_COMPAT)
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <sys/socket.h>
  #endif
  #include <sys/ioctl.h>
  
  #include <arpa/ftp.h>
  
***************
*** 59,65 ****
  #include <string.h>
  #include <errno.h>
  #include <ctype.h>
! #ifndef KRB5_KRB4_COMPAT
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <netdb.h>
  #endif
--- 59,65 ----
  #include <string.h>
  #include <errno.h>
  #include <ctype.h>
! #if !defined(KRB5_KRB4_COMPAT) || defined(OMIT_KRB4_COMPAT)
  /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
  #include <netdb.h>
  #endif
***************
*** 73,83 ****
  sigtype	intr(), lostpeer();
  extern	char *home;
  char	*getlogin();
! #ifdef KRB5_KRB4_COMPAT
  #include <krb.h>
- struct servent staticsp;
  extern char realm[];
  #endif /* KRB5_KRB4_COMPAT */
  
  main(argc, argv)
  	volatile int argc;
--- 73,88 ----
  sigtype	intr(), lostpeer();
  extern	char *home;
  char	*getlogin();
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  #include <krb.h>
  extern char realm[];
  #endif /* KRB5_KRB4_COMPAT */
+ struct servent staticsp;
+ 
+ #ifdef KERBEROS5
+ #include <krb5.h>
+ #include <com_err.h>
+ #endif
  
  main(argc, argv)
  	volatile int argc;
***************
*** 87,92 ****
--- 92,103 ----
  	int top;
  	struct passwd *pw = NULL;
  	char homedir[MAXPATHLEN];
+ #ifdef KERBEROS5
+ 	krb5_context context;
+ 	krb5_ccache ccache;
+ 	krb5_error_code code = 0;
+ 	krb5_principal princ = NULL;
+ #endif
  	char *progname = argv[0];
  
  	sp = getservbyname("ftp", "tcp");
***************
*** 94,111 ****
  		fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
  		exit(1);
  	}
! #ifdef KRB5_KRB4_COMPAT
  /* GDM need to static sp so that the information is not lost
     when kerberos calls getservbyname */
  	memcpy(&staticsp,sp,sizeof(struct servent));
  	sp = &staticsp;
! #endif /* KRB5_KRB4_COMPAT */
  	doglob = 1;
  	interactive = 1;
  	autoauth = 1;
  	autologin = 1;
  	forward = 0;
  	autoencrypt = 0;
  	argc--, argv++;
  	while (argc > 0 && **argv == '-') {
  		for (cp = *argv + 1; *cp; cp++)
--- 105,149 ----
  		fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
  		exit(1);
  	}
! #if defined(KRB5_KRB4_COMPAT) || defined(GSSAPI)
  /* GDM need to static sp so that the information is not lost
     when kerberos calls getservbyname */
  	memcpy(&staticsp,sp,sizeof(struct servent));
  	sp = &staticsp;
! #endif /* KRB5_KRB4_COMPAT || GSSAPI */
! 
  	doglob = 1;
  	interactive = 1;
  	autoauth = 1;
  	autologin = 1;
  	forward = 0;
  	autoencrypt = 0;
+ 
+ #ifdef KERBEROS5
+ 	krb5_init_context(&context);
+ 
+ 	/*
+ 	 * Forward credentials if we get a command-line flag or if we
+ 	 * have the right stuff set in the profile, _AND_ if our TGT
+ 	 * is forwardable
+ 	 */
+ 
+ 	if ((code = krb5_cc_default(context, &ccache)) != 0) {
+ 		com_err(argv[0], code, "while reading credential cache");
+ 	}
+ 
+ 	if ((code == 0) && 
+ 	    (code = krb5_cc_get_principal(context, ccache, &princ)) != 0) {
+ 		com_err(argv[0], code, "while getting primary principal");
+ 	}
+ 
+ 	if (code == 0) {
+ 		krb5_appdefault_boolean(context, "ftp",
+ 					krb5_princ_realm(context, princ),
+ 					"forward", 0, &forward);
+ 	}
+ #endif /* KERBEROS5 */
+ 
  	argc--, argv++;
  	while (argc > 0 && **argv == '-') {
  		for (cp = *argv + 1; *cp; cp++)
***************
*** 116,122 ****
  				debug++;
  				break;
  
! #ifdef KRB5_KRB4_COMPAT
  			case 'k':
  				if (*++cp != '\0')
  					strncpy(realm, ++cp, REALM_SZ);
--- 154,160 ----
  				debug++;
  				break;
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  			case 'k':
  				if (*++cp != '\0')
  					strncpy(realm, ++cp, REALM_SZ);
***************
*** 148,161 ****
  			case 'g':
  				doglob = 0;
  				break;
! 
! 			case 'u':
! 				autoauth = 0;
! 				break;
! 
  			case 'f':
  				forward = 1;
  				break;
  
  			case 'x':
  				autoencrypt = 1;
--- 186,203 ----
  			case 'g':
  				doglob = 0;
  				break;
! #ifdef KERBEROS5
  			case 'f':
  				forward = 1;
  				break;
+ 			
+ 			case 'F':
+ 				forward = 0;
+ 				break;
+ #endif /* KERBEROS5 */
+ 			case 'u':
+ 				autoauth = 0;
+ 				break;
  
  			case 'x':
  				autoencrypt = 1;
***************
*** 172,177 ****
--- 214,265 ----
  	nextopt:
  		argc--, argv++;
  	}
+ 
+ #ifdef KERBEROS5
+ 
+ 	if (code != 0)
+ 		forward = 0;
+ 
+ 	if (forward) {
+ 		krb5_creds creds, mcreds;
+ 
+ 		creds.client = princ;
+ 		code = krb5_build_principal(context, &creds.server,
+ 					    krb5_princ_realm(context, princ)->length,
+ 					    krb5_princ_realm(context, princ)->data,
+ 					    "krbtgt",
+ 					    krb5_princ_realm(context, princ)->data, 0);
+ 		
+ 		if (code != 0) {
+ 			com_err(argv[0], code, "while building TGT principal");
+ 			forward = 0;
+ 		}
+ 
+ 		if (code == 0)
+ 			code = krb5_cc_retrieve_cred(context, ccache, 0,
+ 						     &creds, &mcreds);
+ 		
+ 		if (code == 0) {
+ 			krb5_free_principal(context, creds.server);
+ 
+ 			if ((mcreds.ticket_flags & TKT_FLG_FORWARDABLE) == 0)
+ 				forward = 0;
+ 			
+ 			krb5_free_cred_contents(context, &mcreds);
+ 		}
+ 
+ 		if (code != 0)
+ 			forward = 0;
+ 	}
+ 
+ 	krb5_cc_close(context, ccache);
+ 
+ 	if (princ)
+ 		krb5_free_principal(context, princ);
+ 	krb5_free_context(context);
+ 
+ #endif /* KERBEROS5 */
+ 
  	fromatty = isatty(fileno(stdin));
  	if (fromatty)
  		verbose++;
***************
*** 182,187 ****
--- 270,276 ----
  #endif
  	crflag = 1;	/* strip c.r. on ascii gets */
  	sendport = -1;	/* not using ports */
+ 	lbufsize = 0;	/* take the default buffer size */
  	/*
  	 * Set up the home directory in case we're globbing.
  	 */
Index: krb5/appl/gssftp/ftp/ruserpass.c
diff -c krb5/appl/gssftp/ftp/ruserpass.c:1.1.1.1 krb5/appl/gssftp/ftp/ruserpass.c:1.2
*** krb5/appl/gssftp/ftp/ruserpass.c:1.1.1.1	Mon Jun  2 17:54:21 1997
--- krb5/appl/gssftp/ftp/ruserpass.c	Fri Jan 22 16:13:19 1999
***************
*** 43,48 ****
--- 43,53 ----
  #endif
  #include <ctype.h>
  #include <sys/stat.h>
+ 
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
+ 
  #include <errno.h>
  #include "ftp_var.h"
  
Index: krb5/appl/gssftp/ftp/secure.c
diff -c krb5/appl/gssftp/ftp/secure.c:1.1.1.3 krb5/appl/gssftp/ftp/secure.c:1.2
*** krb5/appl/gssftp/ftp/secure.c:1.1.1.3	Fri Feb 22 16:31:34 2002
--- krb5/appl/gssftp/ftp/secure.c	Wed Sep 25 16:43:55 2002
***************
*** 11,17 ****
  
  #include <secure.h>	/* stuff which is specific to client or server */
  
! #ifdef KRB5_KRB4_COMPAT
  #include <krb.h>
  
  CRED_DECL
--- 11,17 ----
  
  #include <secure.h>	/* stuff which is specific to client or server */
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  #include <krb.h>
  
  CRED_DECL
***************
*** 75,81 ****
  static unsigned int smaxqueue;  /* Maximum allowed to queue before 
  				   flush buffer. < smaxbuf by fudgefactor */
  
! #ifdef KRB5_KRB4_COMPAT
  #define KRB4_FUDGE_FACTOR 32	/* Amount of growth
  				 * from cleartext to ciphertext.
  				 * krb_mk_priv adds this # bytes.
--- 75,81 ----
  static unsigned int smaxqueue;  /* Maximum allowed to queue before 
  				   flush buffer. < smaxbuf by fudgefactor */
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  #define KRB4_FUDGE_FACTOR 32	/* Amount of growth
  				 * from cleartext to ciphertext.
  				 * krb_mk_priv adds this # bytes.
***************
*** 83,89 ****
  				 */
  #endif /* KRB5_KRB4_COMPAT */
  
! #ifdef KRB5_KRB4_COMPAT
  /* XXX - The following must be redefined if KERBEROS_V4 is not used
   * but some other auth type is.  They must have the same properties. */
  #define looping_write krb_net_write
--- 83,89 ----
  				 */
  #endif /* KRB5_KRB4_COMPAT */
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  /* XXX - The following must be redefined if KERBEROS_V4 is not used
   * but some other auth type is.  They must have the same properties. */
  #define looping_write krb_net_write
***************
*** 165,171 ****
      smaxbuf = maxbuf;
      smaxqueue = maxbuf;
  
! #ifdef KRB5_KRB4_COMPAT
      /* For KRB4 - we know the fudge factor to be 32 */
      if (strcmp(auth_type, "KERBEROS_V4") == 0) {
  	smaxqueue = smaxbuf - KRB4_FUDGE_FACTOR;
--- 165,171 ----
      smaxbuf = maxbuf;
      smaxqueue = maxbuf;
  
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
      /* For KRB4 - we know the fudge factor to be 32 */
      if (strcmp(auth_type, "KERBEROS_V4") == 0) {
  	smaxqueue = smaxbuf - KRB4_FUDGE_FACTOR;
***************
*** 283,289 ****
  						     buffer lengths required */
  
  	/* Other auth types go here ... */
! #ifdef KRB5_KRB4_COMPAT
  	if (bufsize < nbyte + fudge) {
  		if (outbuf?
  		    (outbuf = realloc(outbuf, (unsigned) (nbyte + fudge))):
--- 283,289 ----
  						     buffer lengths required */
  
  	/* Other auth types go here ... */
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	if (bufsize < nbyte + fudge) {
  		if (outbuf?
  		    (outbuf = realloc(outbuf, (unsigned) (nbyte + fudge))):
***************
*** 384,390 ****
  			return(ERR);
  		}
  		/* Other auth types go here ... */
! #ifdef KRB5_KRB4_COMPAT
  		if (strcmp(auth_type, "KERBEROS_V4") == 0) {
  		  if (kerror = dlevel == PROT_P ?
  		    krb_rd_priv(ucbuf, length, schedule, SESSION,
--- 384,390 ----
  			return(ERR);
  		}
  		/* Other auth types go here ... */
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  		if (strcmp(auth_type, "KERBEROS_V4") == 0) {
  		  if (kerror = dlevel == PROT_P ?
  		    krb_rd_priv(ucbuf, length, schedule, SESSION,
Index: krb5/appl/gssftp/ftp/window.c
diff -c /dev/null krb5/appl/gssftp/ftp/window.c:1.2
*** /dev/null	Sun Mar 16 20:22:07 2003
--- krb5/appl/gssftp/ftp/window.c	Tue Jul 31 21:01:26 2001
***************
*** 0 ****
--- 1,552 ----
+ /*
+   Copyright (C) 1999-2000  Naval Research Laboratory
+ 
+   Permission to use, copy, modify and distribute this software and its
+   documentation is hereby granted, provided that both the copyright
+   notice and this permission notice appear in all copies of the software,
+   derivative works or modified versions, and any portions thereof, and
+   that both notices appear in supporting documentation.
+ 
+   NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
+   DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
+   RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+ 
+ /* Simple windowing protocol (swp) for ATM SVCs */
+ 
+ #ifdef FORE_ATM_FTP
+ 
+ #include "window.h"
+ #include <stdio.h>
+ #include <stdlib.h>
+ #ifndef WIN32
+ # include <poll.h>
+ # include <sys/time.h>		/* has uint32_t typdef */
+ # include <netinet/in.h>	/* htonl and ntohl */
+ #else
+ # include "atm.h"
+ # include <Winsock2.h>
+ # include <time.h>		/* for _ftime() */
+ # include <sys/timeb.h>		/* for struct _timeb */
+ # include <io.h>
+ # include <fcntl.h>
+ # define read(x,y,z)	_read((x),(y),(z))
+ # define open(x,y)	_open((x),(y))
+ # define close(x)	_close((x))
+ #endif
+ #include <errno.h>
+ #define DEFAULTWS		1024
+ #define	TIMEOUT			15000	/* microseconds */
+ #define	INDEX(x)		(( x ) % WS )
+ #define NEXTAVAIL(s)		INDEX( s - 1 )
+ #define	WINEND(s)		INDEX(( s ) + WS - 1 )
+ #define	WINUSED(r,s)		((( r ) + WS - ( s )) % WS )
+ #define PRT(s)			(fprintf( stderr, s ))
+ #define	DATALEN(x)		(x - sizeof( struct packet ) + 1 )
+ 
+ #define ERR_SEQUENCE		0x0101	/* non-sequential sequence number */
+ #define	ERR_FULL		0x0102	/* window is full */
+ #define ERR_MALLOC		0x0103	/* malloc failed */
+ #define	ERR_FATAL		0x0104	/* this shouldn't happen */
+ #define	ERR_TIMEOUT		0x0105	/* select timed out */
+ #define	ERR_CONCLOSE		0x0106	/* connection closed / end of file */
+ #define ERR_END			0x0107	/* end of stream reached -- stop */
+ #define	ERR_NODATA		0x0108	/* pointer to buffer is NULL */
+ #define	ERR_ACKOLD		0x0109	/* acknowledgement is too old */
+ #define	ERR_ACKOOR		0x010a	/* ack out of range -- too high */
+ #define	ERR_TIMER		0x010b	/* timer expired */
+ #define	ERR_ACKFULL		0x010c	/* receiving side's window is full */
+ #define	ERR_XMIT		0x010d	/* transmit failed */
+ #define SUCCESS			0x0001	/* everything worked */
+ 
+ static uint32_t retrans = 0;
+ static uint32_t trans = 0;
+ static uint32_t expires = 0;
+ static uint32_t pdulen = /* 16 * 1024 */ 8219;
+ static uint32_t WS = DEFAULTWS;
+ 
+ #ifdef WIN32
+ int gettimeofday( struct timeval *tv, void *tz ){
+ 	struct _timeb tmp;
+ 	_ftime( &tmp );
+ 	if( tv != NULL ){
+ 		tv->tv_sec = tmp.time;
+ 		tv->tv_usec = tmp.millitm * 1000;	/* milli to micro */
+ 	}
+ 	return 1;
+ }
+ #endif
+ 
+ void swp_set_ws( uint32_t new_ws ){
+ 	WS = new_ws;
+ }
+ 
+ void swp_set_pdulen( uint32_t new_pdu ){
+ 	if( new_pdu < 18432 ) pdulen = new_pdu;
+ 	else fprintf( stderr, "too large for AAL5 pdu\n" );
+ }
+ 
+ void swp_enqueue_xmit( unsigned char *buf, uint32_t len,
+ 				struct packet *xq[], uint32_t *end ){
+ 	uint32_t na = INDEX(( *end ) - 1 );
+ 
+ 	if(( xq[na] = (struct packet *)malloc( pdulen )) == NULL ){
+ 		fprintf( stderr, "Malloc Failed %d\n", __LINE__ );
+ 		return;
+ 	}
+ 	memset( xq[na], 0, pdulen );
+ 	xq[na]->sequence = ntohl( *end );
+ 	xq[na]->length = htonl( len + sizeof( struct packet ) - 1 );
+ 	memcpy( xq[na]->data, buf, len );
+ 	if( len < DATALEN( pdulen )) xq[na]->flags = FLAG_STOP;
+ 	if( len > DATALEN( pdulen )) fprintf( stderr, "memory problems\n" );
+ }
+ 
+ /*	*xq	= the transmit queue
+ 	*fsp	= free space,
+ 	*es	= end sequence no.
+ */
+ 
+ int swp_fill_xmitq( int fd, struct packet *xq[], uint32_t *fsp, uint32_t *es ){
+ 	unsigned char *buf = (unsigned char *)malloc( pdulen );
+ 	int len = 0;
+ 	int done = 0;	/* (1) */
+ 
+ 	if( !buf ){
+ 		fprintf( stderr, "Malloc Failed %d\n", __LINE__ );
+ 		return ERR_MALLOC;
+ 	}
+ #ifdef DEBUG
+ 	fprintf( stderr, "fsp is %u; end is %u . . . ", *fsp, *es );
+ #endif
+ 	while( !done && ((*fsp) > 0 )){
+ 		len = read( fd, buf, DATALEN( pdulen ));
+ 		if( len > 0 ){
+ 			(*es)++;
+ 			swp_enqueue_xmit( buf, len, xq, es );
+ 			(*fsp)--;
+ 		} else if( len == 0 ){
+ 			done = 1;
+ 		} else if( len < 0 ){
+ 			fprintf( stderr, "read() returned %d\n", len );
+ 			done = 1;
+ 		}
+ 	}
+ #ifdef DEBUG
+ 	fprintf( stderr, "end is %u\n", *es );
+ #endif
+ 	free( buf );
+ 	if( len < 0 ){
+ 		fprintf( stderr, "read failed, errno = %d\n", errno );
+ 		return ERR_FATAL;
+ 	}
+ 	return SUCCESS;
+ }
+ 
+ int swp_tx_init( struct seq *seq, uint32_t *fsp, int fd, struct packet *xq[] ){
+ 	memset( xq, 0, WS * sizeof( struct packet *));
+ 	seq->begin = seq->current = seq->end = 1;
+ 	seq->end = 0;		/* (1) */
+ 	*fsp = WS;
+ 	return swp_fill_xmitq( fd, xq, fsp, &seq->end );
+ }
+ 
+ int swp_rx_init( struct seq *seq, struct packet *rq[] ){
+ 	memset( rq, 0, WS * sizeof( struct packet *));
+ 	seq->begin = 1;
+ 	seq->current = 0;
+ 	seq->end = WS;		/* just added */
+ 	return SUCCESS;
+ }
+ 
+ int swp_enqueue_recv( struct seq *seq, struct packet *in, uint32_t len,
+ 							struct packet *rq[] ){
+ 	struct packet **rtmp;
+ 
+ 	rtmp = &rq[INDEX(seq->current)];
+ 
+ 	if( !in ) return ERR_NODATA;
+ 	if( ntohl( in->sequence ) != ( seq->current + 1 ))
+ 		return ERR_SEQUENCE;
+ 	if( seq->current <= seq->end ){
+ 		if(( *rtmp = (struct packet *)malloc( len )) == NULL ){
+ 			fprintf( stderr, "Malloc Failed %d\n", __LINE__ );
+ 			return ERR_MALLOC;
+ 		}
+ 		memcpy( *rtmp, in, len );
+ 		if( in->flags & FLAG_STOP ) return ERR_END;
+ 		if(( seq->current + 1 ) == seq->end ) return ERR_FULL;
+ 		return SUCCESS;
+ 	} else return ERR_FATAL;
+ }
+ 
+ int swp_send_pkt( int fd, struct packet *tq[], uint32_t current ){
+ 	if( tq[INDEX( current - 1 )] ){
+ 		if( atm_write( fd, (void *)tq[INDEX( current - 1 )],
+ 			ntohl( tq[INDEX( current - 1 )]->length )) < 0 )
+ 			return ERR_FATAL;
+ 		trans++;
+ 		return SUCCESS;
+ 	} else return ERR_NODATA;
+ }
+ 
+ struct packet *swp_recv_pkt( int fd, uint32_t *len, int timeout ){
+ 	int pollres;
+ 	int val;
+ #ifndef WIN32
+ 	struct pollfd fds[1];
+ #else
+ 	fd_set readfds[1];
+ 	struct timeval tv;
+ 	int last_error;
+ #endif
+ 	struct packet *tmp;
+ 
+ #ifndef WIN32
+ 	len[0] = 0;
+ 	fds[0].fd = fd;
+ 	fds[0].events = POLLIN;
+ 	fds[0].events = POLLIN | POLLPRI;
+ 
+ 	pollres = poll(fds, 1, timeout );
+ 	if( pollres <= 0 ){
+ 		if( pollres < 0 )
+ 			fprintf( stderr, "swp_recv_pkt(): poll failed\n" );
+ 		return NULL;
+ 	}
+ #else
+ 	tv.tv_sec = 0;
+ 	tv.tv_usec = timeout * 1000;	/* milliseconds to microseconds */
+ 	FD_ZERO( readfds );
+ 	FD_SET( (SOCKET)fd, readfds );
+ 	pollres = select( 0, (fd_set FAR *)&(readfds[0]), NULL, NULL, &tv );
+ 	if( pollres == SOCKET_ERROR ){
+ 		last_error = WSAGetLastError();
+ 		fprintf( stderr, "swp_recv_pkt(): select failed (%d)\n",
+ 			last_error );
+ 		return NULL;
+ 	} else if( pollres == 0 ) return NULL;
+ #endif
+ 
+ 	if(( tmp = (struct packet *)malloc( pdulen )) == NULL ){
+ 		fprintf( stderr, "Malloc Failed %d\n", __LINE__ );
+ 		return NULL;
+ 	}
+ 	if(( val = atm_read( fd, tmp, pdulen )) == -1 ){
+ 		fprintf( stderr, "read failed\n" );
+ 		return NULL;
+ 	}
+ 	len[0] = (uint32_t)val;
+ 	return tmp;
+ }
+ 
+ /*	int swp_response:						*/
+ /*	Sends a response for the ack just received to synchronize the	*/
+ /*	sender and receiver						*/
+ 
+ int swp_response( int svc, uint32_t acknowledge ){
+ 	struct packet tmp;
+ 
+ 	memset( &tmp, 0, sizeof( tmp ));
+ 	tmp.acknowledge = htonl( acknowledge );
+ 	tmp.flags = FLAG_RESPONSE;
+ 	tmp.length = htonl( sizeof( tmp ));
+ 	tmp.window = htonl( WS );
+ 
+ 	if( atm_write( svc, &tmp, sizeof( tmp )) <= 0 ) return 0;
+ 	return SUCCESS;
+ }
+ 
+ /*	int swp_handle_ack:						*/
+ /*	Returns SUCCESS if ack is ok, ACKOLD if need to back up or	*/
+ /*	ACKOOR if the ack makes no sense				*/
+ 
+ int swp_handle_ack(	int svc, struct packet *buffer, struct packet *xq[],
+ 			struct seq *seq, uint32_t *acknowledge, uint32_t *fsp ){
+ 	int retval = 0;
+ 
+ 	*acknowledge = ntohl( buffer->acknowledge );
+ #ifdef DEBUG
+ 	fprintf( stderr, "Got ack for %d\n", *acknowledge );
+ #endif
+ 	/* First case -- acknowledgement is good */
+ 	if( buffer->acknowledge == htonl( seq->current + 1 ))
+ 		retval = SUCCESS;
+ 	/* Second case -- need to back up */
+ 	else if(( htonl( buffer->acknowledge ) < htonl( seq->current + 1 ))
+ 		&& ( htonl( buffer->acknowledge ) >= seq->begin )){
+ 		retval = ERR_ACKOLD;
+ 		retrans++;
+ 	}
+ 	/* Third case -- receiver ack'd whole window */
+ 	else if( htonl( buffer->acknowledge ) == seq->end + 1 )
+ 		retval = ERR_ACKFULL;
+ 	/* Fourth case -- out of range, don't do anything */
+ 	else retval = ERR_ACKOOR;
+ 
+ 	if(( retval != ERR_ACKOOR) && ( buffer->flags & FLAG_SEQUENCE )){
+ 		swp_response( svc, *acknowledge );
+ 	}
+ 
+ 	/* Free ack'd packets and possibly back up */
+ 	if( retval != ERR_ACKOOR ){
+ 		while( htonl( buffer->acknowledge ) > seq->begin ){
+ #ifdef DEBUG
+ 			fprintf( stderr, "freeing seq %u\n", seq->begin );
+ #endif
+ 			free( xq[INDEX( seq->begin - 1 )] );
+ 			xq[INDEX( seq->begin - 1 )] = (struct packet *)0;
+ 			seq->begin++;
+ 			(*fsp)++;
+ 		}
+ 		seq->current = seq->begin;
+ 	}
+ 	return retval;
+ }
+ 
+ #if 1
+ int swp_generate_ack( int fd, uint32_t sequence, unsigned char flags ){
+ 	struct packet ack;
+ 
+ 	memset( &ack, 0, sizeof( ack ));
+ 	ack.acknowledge = htonl( sequence + 1 );
+ 	ack.window = htonl( WS );
+ 	ack.flags = flags;
+ #ifdef DEBUG
+ 	fprintf( stderr, "sending ack for %u\n", ack.acknowledge );
+ #endif
+ 	if( atm_write( fd, &ack, sizeof( ack )) <= 0 ) return 1;
+ 	return 0;
+ }
+ #else
+ /* this causes the vc to get torn down.  why? */
+ int swp_generate_ack( int fd, uint32_t sequence, unsigned char flags ){
+ 	struct packet *ack = (struct packet *)malloc( pdulen );
+ 	memset( ack, 0, pdulen );
+ 	ack->acknowledge = htonl( sequence + 1 );
+ 	ack->window = htonl( WS );
+ 	ack->flags = flags;
+ 	ack->length = htonl( pdulen );
+ #ifdef DEBUG
+ 	fprintf( stderr, "sending ack for %u\n", sequence + 1 );
+ #endif
+ 	if( atm_write( fd, &ack, pdulen ) <= 0 ) return 1;
+ 	return 0;
+ }
+ #endif
+ 
+ int swp_xmit_go( int svc, int infile ){
+ 	extern int errno;
+ 	char *buffer = NULL;
+ 	uint32_t rlen = 0;
+ 	int ackval = 0;
+ 	uint32_t fsp;		/* free space */
+ 	uint32_t acknowledge;
+ 	struct seq seq;
+ 	struct packet **xmit_queue =
+ 		(struct packet **)malloc( WS * sizeof( struct packet *));
+ 
+ 	swp_set_ws( 10 );
+ 	swp_tx_init( &seq, &fsp, infile, xmit_queue );
+ 
+ 	while(( seq.begin <= seq.current ) && ( seq.current <= seq.end )){
+ 		if( swp_send_pkt( svc, xmit_queue, seq.current ) == ERR_FATAL ){
+ 			if( xmit_queue ) free( xmit_queue );
+ 			return ERR_FATAL;
+ 		}
+ #ifdef DEBUG
+ 		fprintf( stderr, "sent seq %u[%u]\n", seq.current,
+ 			ntohl( xmit_queue[INDEX(seq.current -1 )]->sequence ));
+ #endif
+ 		/* Check for and handle ack */
+ 		buffer = (char *)swp_recv_pkt( svc, &rlen, 0 );
+ 		if(( rlen > 0 ) && ( buffer )){
+ 			ackval = swp_handle_ack( svc, (struct packet*)buffer,
+ 					xmit_queue, &seq, &acknowledge, &fsp );
+ 			if( ackval != ERR_ACKOOR ) swp_fill_xmitq(
+ 					infile, xmit_queue, &fsp, &seq.end );
+ 			else{
+ 				if( xmit_queue ) free( xmit_queue );
+ 				return ERR_FATAL;
+ 			}
+ 			free( buffer ); buffer = NULL;
+ 		}
+ 
+ 		else if( seq.current == seq.end ){
+ 			buffer = (char *)swp_recv_pkt( svc, &rlen, 2000 );
+ 			if( !buffer ){
+ 				seq.current = seq.begin;	/* timeout */
+ 				fprintf( stderr, "timeout\n" );
+ 				expires++;
+ 			}
+ 			else{
+ 				ackval = swp_handle_ack( svc,
+ 					(struct packet*)buffer,
+ 					xmit_queue, &seq, &acknowledge, &fsp );
+ 				if( ackval != ERR_ACKOOR ) swp_fill_xmitq(
+ 					infile, xmit_queue, &fsp, &seq.end );
+ 				else{
+ 					if( xmit_queue ) free( xmit_queue );
+ 					return ERR_FATAL;
+ 				}
+ 				free( buffer ); buffer = NULL;
+ 			}
+ 		}
+ 
+ 		else seq.current++;
+ 	}
+ 
+ 	printf( "%u retransmits\n", retrans );
+ 	printf( "%u transmits\n", trans );
+ 	printf( "%u timeouts\n", expires );
+ 	printf( "%u frames\n", seq.end );
+ 	if( xmit_queue ) free( xmit_queue );
+ 	return SUCCESS;
+ }
+ 
+ int swp_empty_recv( int fd, struct packet *rq[], uint32_t *bs, uint32_t es ){
+ 	struct packet **rtmp;
+ 	int len = 0;
+ 
+ 	/* es++;	 adjust for next to last (*bs)++ */
+ 	while( rq[INDEX(( *bs ) - 1 )] && ( *bs <= es ) && ( len != -1 )){
+ 		rtmp = (struct packet **)&rq[INDEX(( *bs ) - 1 )];
+ 		len = write( fd, (*rtmp)->data, DATALEN((*rtmp)->length ));
+ #ifdef DEBUG
+ 		fprintf( stderr, "freeing seq %u[%u]\n", *bs, (*rtmp)->sequence );
+ #endif
+ 		free( *rtmp );
+ 		*rtmp = NULL;
+ 		(*bs)++;
+ 	}
+ 	/* if((*bs) == (es + 1)) *bs = es; */
+ 	if( len < 0 ) return ERR_FATAL;
+ 	return SUCCESS;
+ }
+ 
+ int swp_recv_go( int svc, int outfile ){
+ 	struct packet **recv_queue =
+ 		(struct packet **)malloc( WS * sizeof( struct packet *));
+ 	struct packet *tmp = NULL;
+ 	struct timeval stime, ctime;
+ 	uint32_t len = 0;
+ 	int val = 0;
+ 	int ack = 0;
+ 	int bp = 0;		/* bad packet flag		*/
+ 	struct seq seq;
+ 
+ 	swp_set_ws( 10 );
+ 	swp_rx_init( &seq, recv_queue );
+ 
+ 	while(( ack != ERR_XMIT ) && ( val != ERR_TIMER ) &&
+ 		( val != ERR_MALLOC ) && ( val != ERR_END ) &&
+ 		( val != ERR_FATAL )){
+ 
+ 		/* tmp = swp_recv_pkt( svc, &len, 1000 ); */
+ 		tmp = swp_recv_pkt( svc, &len, 100 );
+ 		if( tmp && bp && ( tmp->flags & FLAG_RESPONSE )){
+ 			bp = 0;
+ #ifdef DEBUG
+ 			fprintf( stderr, "got ackresp %d\n",
+ 				ntohl( tmp->acknowledge ));
+ #endif
+ 			free( tmp );
+ 			continue;
+ 		} else if( !tmp && bp ){
+ 			if( tmp ) fprintf( stderr, "NOT AN ACK RESPONSE!!\n" );
+ 			/* ack response timed out, send another ack */
+ 			/* check elapsed time */
+ 			gettimeofday( &ctime, NULL );
+ 			if( stime.tv_usec > ctime.tv_usec ){
+ 				ctime.tv_usec += 1000000;
+ 				ctime.tv_sec--;
+ 			}
+ 			if((( ctime.tv_sec - stime.tv_sec ) > 0 ) ||
+ 			   (( ctime.tv_usec - stime.tv_usec ) > 100000 )){
+ #ifdef DEBUG
+ 				fprintf( stderr, "%u:%u to %u:%u\n",
+ 					stime.tv_sec, stime.tv_usec,
+ 					ctime.tv_sec, ctime.tv_usec );
+ #endif
+ 				ack = swp_generate_ack( svc,
+ 					seq.current, FLAG_SEQUENCE);
+ /*				swp_empty_recv( outfile, recv_queue,
+ 						&seq.begin, seq.current + 1 );
+ */
+ 				gettimeofday( &stime, NULL );
+ 			}
+ 		}
+ #ifdef DEBUG
+ 		if( tmp ) fprintf( stderr, "received seq %d",
+ 			ntohl( tmp->sequence ));
+ 		if( tmp && bp ) fprintf( stderr, " (ignored)\n" );
+ 		else if( tmp ) fprintf( stderr, "\n" );
+ #endif
+ 		if( !bp ) val = swp_enqueue_recv( &seq, tmp, len, recv_queue );
+ 		if( !bp ) switch( val ){
+ 		case ERR_FULL:	swp_empty_recv( outfile, recv_queue,
+ 						&seq.begin, seq.end );
+ 				ack = swp_generate_ack(
+ 					svc, ntohl( tmp->sequence ), 0 );
+ 				seq.current++;
+ 				seq.end = seq.begin + WS - 1;
+ #ifdef DEBUG
+ 				fprintf( stderr, "full window\n" );
+ #endif
+ 				break;
+ 		case ERR_END:	swp_empty_recv( outfile, recv_queue,
+ 						&seq.begin, seq.current + 1 );
+ 				ack = swp_generate_ack(
+ 					svc, ntohl( tmp->sequence ), 0 );
+ 				seq.end = seq.begin + WS - 1;
+ 				break;
+ 		case ERR_SEQUENCE:
+ 				if( bp ) break;
+ 				gettimeofday( &stime, NULL );
+ 				bp = 1;
+ 				swp_empty_recv( outfile, recv_queue,
+ 						&seq.begin, seq.current );
+ 				ack = swp_generate_ack( svc, seq.current,
+ 					FLAG_SEQUENCE );
+ 				seq.end = seq.begin + WS - 1;
+ #ifdef DEBUG
+ 				fprintf( stderr, "bad sequence: "
+ 					"incoming: %u  expected: %u\n",
+ 					ntohl(tmp->sequence), seq.current + 1 );
+ #endif
+ 				break;
+ 		case SUCCESS:	seq.current++;
+ 				break;
+ 		case ERR_FATAL:
+ 				fprintf( stderr, "tmp->sequence is %d\n"
+ 				"seq = { %d %d %d }\n",
+ 				ntohl( tmp->sequence ),
+ 				seq.begin, seq.current, seq.end );
+ 				break;
+ 		case ERR_NODATA:
+ 				swp_empty_recv( outfile, recv_queue,
+ 						&seq.begin, seq.current - 1 );
+ 				ack = swp_generate_ack( svc, seq.current, 0 );
+ 				seq.end = seq.begin + WS - 1;
+ #ifdef DEBUG
+ 				fprintf( stderr, "recv timed out\n" );
+ #endif
+ 				break;
+ 		}
+ 		if( tmp ) free( tmp );
+ 		if( ack == 1 ){
+ 			swp_empty_recv( outfile, recv_queue,
+ 					&seq.begin, seq.current );
+ 				seq.end = seq.begin + WS - 1;
+ 			fprintf( stderr, "Ack failed\n" );
+ 			/*exit( 10 ); */
+ 			ack = 0;
+ 		}
+ 	}
+ #ifdef DEBUG
+ 	fprintf( stderr, "val is %d\n", val );
+ #endif
+ 	if( recv_queue ) free( recv_queue );
+ 	return SUCCESS;
+ }
+ #endif /* FORE_ATM_FTP */
Index: krb5/appl/gssftp/ftp/window.h
diff -c /dev/null krb5/appl/gssftp/ftp/window.h:1.2
*** /dev/null	Sun Mar 16 20:22:07 2003
--- krb5/appl/gssftp/ftp/window.h	Tue Jul 31 21:01:27 2001
***************
*** 0 ****
--- 1,65 ----
+ /*
+   Copyright (C) 1999-2000  Naval Research Laboratory
+ 
+   Permission to use, copy, modify and distribute this software and its
+   documentation is hereby granted, provided that both the copyright
+   notice and this permission notice appear in all copies of the software,
+   derivative works or modified versions, and any portions thereof, and
+   that both notices appear in supporting documentation.
+ 
+   NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
+   DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
+   RESULTING FROM THE USE OF THIS SOFTWARE.
+ */
+ 
+ #ifndef __CRAP_H
+ #define __CRAP_H
+ 
+ #ifndef WIN32
+ # include <sys/time.h>			/* has uint32_t */
+ #else
+ # include <Winsock2.h>			/* struct timeval */
+ # include <BASETSD.H>
+ # define uint32_t UINT32
+ #endif
+ #ifdef LINUX
+ # include <stdint.h>
+ #endif
+ 
+ #define	FLAG_STOP	0x1		/* Indicates last packet */
+ #define	FLAG_ACK	0x2		/* acknowledgement */
+ #define	FLAG_SEQUENCE	0x4		/* Indicates that an unexpected	*/
+ 					/* sequence number was received	*/
+ #define FLAG_RESPONSE	0x8		/* sender's response to FLAG_SEQUENCE */
+ 
+ typedef struct packet{
+ 	uint32_t sequence;		/* sequence number */
+ 	uint32_t acknowledge;		/* next expected sequence number */
+ 	uint32_t length;		/* packet size including header */
+ 	uint32_t window;		/* window size in packets */
+ 	unsigned char flags;		/* see FLAG_ defines */
+ 
+ 	char data[1];
+ } PACKET;
+ 
+ typedef struct seq{
+ 	uint32_t begin;			/* seq. no. at beginning of window */
+ 	uint32_t current;		/* seq. no. being processed */
+ 	uint32_t end;			/* last seq. no. in window */
+ } SEQ;
+ 
+ /*
+ 	When FLAG_SEQUENCE is set the first four bytes of the data
+ 	field will contain the received (bad) sequence number.
+ 	FLAG_ACK should be set in all acknowledgements.
+ */
+ 
+ int swp_xmit_go( int svc, int infile );
+ int swp_recv_go( int svc, int outfile );
+ 
+ # ifdef WIN32
+ int gettimeofday( struct timeval *, void * );
+ # endif
+ 
+ #endif
+ 
Index: krb5/appl/gssftp/ftpd/.cvsignore
diff -c /dev/null krb5/appl/gssftp/ftpd/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:07 2003
--- krb5/appl/gssftp/ftpd/.cvsignore	Thu Jun  5 10:38:11 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/gssftp/ftpd/Makefile.in
diff -c krb5/appl/gssftp/ftpd/Makefile.in:1.1.1.3 krb5/appl/gssftp/ftpd/Makefile.in:1.7
*** krb5/appl/gssftp/ftpd/Makefile.in:1.1.1.3	Fri Feb 22 16:31:34 2002
--- krb5/appl/gssftp/ftpd/Makefile.in	Mon Feb 25 22:28:58 2002
***************
*** 5,11 ****
  #
  # appl/gssftp/ftpd/Makefile.in
  #
! DEFINES = -DGSSAPI -DFTP_BUFSIZ=10240 #-DNOCONFIDENTIAL
  PROG_LIBPATH=-L$(TOPLIBD)
  PROG_RPATH=$(KRB5_LIBDIR)
  
--- 5,11 ----
  #
  # appl/gssftp/ftpd/Makefile.in
  #
! DEFINES = -DGSSAPI -DFTP_BUFSIZ=10240 -DKPROGDIR=\"@CLIENT_BINDIR@\" #-DNOCONFIDENTIAL
  PROG_LIBPATH=-L$(TOPLIBD)
  PROG_RPATH=$(KRB5_LIBDIR)
  
***************
*** 13,18 ****
--- 13,22 ----
  SETENVOBJ=@SETENVOBJ@
  LIBOBJS=@LIBOBJS@
  COMERRLIB=$(BUILDTOP)/util/et/libcom_err.a
+ AFSLIBS=@AFSLIBS@
+ LOCAL_LIBRARIES=-lpty
+ DEPLOCAL_LIBRARIES=$(TOPLIBD)/../util/pty/libpty.a
+ 
  FTPD_LIBS=@FTPD_LIBS@
  
  SRCS	= $(srcdir)/ftpd.c ftpcmd.c $(srcdir)/popen.c \
***************
*** 23,36 ****
  	  $(srcdir)/../../bsd/getdtablesize.c $(SETENVSRC)
  
  OBJS	= ftpd.o ftpcmd.o glob.o popen.o vers.o radix.o \
! 	  secure.o $(LIBOBJS) $(SETENVOBJ)
  
  LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir) @KRB4_INCLUDES@
  
  all::	ftpd
  
  ftpd:	$(OBJS) $(PTY_DEPLIB) $(GSS_DEPLIBS) $(UTIL_DEPLIB) $(KRB4COMPAT_DEPLIBS)
! 	$(CC_LINK) -o $@ $(OBJS) $(FTPD_LIBS) $(PTY_LIB) $(GSS_LIBS) $(UTIL_LIB) $(KRB4COMPAT_LIBS)
  
  clean::
  	$(RM) ftpd ftpcmd.c
--- 27,40 ----
  	  $(srcdir)/../../bsd/getdtablesize.c $(SETENVSRC)
  
  OBJS	= ftpd.o ftpcmd.o glob.o popen.o vers.o radix.o \
! 	  secure.o atm.o window.o $(LIBOBJS) $(SETENVOBJ)
  
  LOCALINCLUDES = -I$(srcdir)/.. -I$(srcdir) @KRB4_INCLUDES@
  
  all::	ftpd
  
  ftpd:	$(OBJS) $(PTY_DEPLIB) $(GSS_DEPLIBS) $(UTIL_DEPLIB) $(KRB4COMPAT_DEPLIBS)
! 	$(CC_LINK) -o $@ $(OBJS) $(FTPD_LIBS) $(PTY_LIB) $(GSS_LIBS) $(UTIL_LIB) $(KRB4COMPAT_LIBS) $(AFSLIBS)
  
  clean::
  	$(RM) ftpd ftpcmd.c
***************
*** 57,62 ****
--- 61,70 ----
  	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/radix.c
  secure.o: $(srcdir)/../ftp/secure.c
  	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/secure.c
+ atm.o: $(srcdir)/../ftp/atm.c
+ 	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/atm.c
+ window.o: $(srcdir)/../ftp/window.c
+ 	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../ftp/window.c
  
  getdtablesize.o: $(srcdir)/../../bsd/getdtablesize.c
  	$(CC) -c $(ALL_CFLAGS) $(srcdir)/../../bsd/getdtablesize.c
Index: krb5/appl/gssftp/ftpd/configure.in
diff -c krb5/appl/gssftp/ftpd/configure.in:1.1.1.2 krb5/appl/gssftp/ftpd/configure.in:removed
*** krb5/appl/gssftp/ftpd/configure.in:1.1.1.2	Wed May 12 13:21:12 1999
--- krb5/appl/gssftp/ftpd/configure.in	Sun Mar 16 20:22:07 2003
***************
*** 1,62 ****
- AC_INIT(ftpcmd.y)
- CONFIG_RULES
- AC_CONST
- AC_PROG_INSTALL
- AC_PROG_YACC
- KRB5_SIGTYPE
- CHECK_UTMP
- CHECK_SIGPROCMASK
- CHECK_WAIT_TYPE
- CHECK_SETJMP
- CHECK_SIGNALS
- AC_CHECK_SIZEOF(short)
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- DECLARE_SYS_ERRLIST
- AC_FUNC_VFORK
- AC_HEADER_STDARG
- AC_CHECK_HEADERS(unistd.h stdlib.h string.h sys/sockio.h)
- AC_REPLACE_FUNCS(getdtablesize)
- AC_HAVE_FUNCS(getcwd getusershell seteuid setreuid setresuid)
- AC_CHECK_LIB(crypt,crypt) dnl 
- AC_CHECK_LIB(util,logwtmp)
- dnl 
- dnl copied from appl/bsd/configure.in
- AC_MSG_CHECKING([setenv])
- AC_CACHE_VAL(krb5_cv_setenv,
- [AC_TRY_LINK(
- [],[setenv("PATH","/bin",0);],
- krb5_cv_setenv=yes,krb5_cv_setenv=no)])
- AC_MSG_RESULT($krb5_cv_setenv)
- if test $krb5_cv_setenv = no; then
- SETENVSRC='$(srcdir)/../bsd/setenv.c'
- SETENVOBJ=setenv.o
- AC_SUBST([SETENVSRC])
- AC_SUBST([SETENVOBJ])
- fi
- AC_MSG_CHECKING([shadow password support])
- AC_CACHE_VAL(krb5_cv_shadow_pwd,
- [AC_TRY_LINK(
- [#include <sys/types.h>
- #include <pwd.h>
- #include <shadow.h>],
- [struct spwd *sp = getspnam("root")],
- krb5_cv_shadow_pwd=yes, krb5_cv_shadow_pwd=no)])
- AC_MSG_RESULT($krb5_cv_shadow_pwd)
- if test $krb5_cv_shadow_pwd = yes; then
- AC_DEFINE(HAVE_SHADOW)
- fi
- dnl
- dnl
- case $krb5_cv_host in
- alpha-dec-osf*)
- 	AC_CHECK_LIB(security,setluid,
- 		AC_DEFINE(HAVE_SETLUID)
- 		LIBS="$LIBS -lsecurity"
- 	)
- 	;;
- esac
- USE_ANAME
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/gssftp/ftpd/ftpcmd.y
diff -c krb5/appl/gssftp/ftpd/ftpcmd.y:1.1.1.4 krb5/appl/gssftp/ftpd/ftpcmd.y:1.14
*** krb5/appl/gssftp/ftpd/ftpcmd.y:1.1.1.4	Thu Dec 19 14:06:04 2002
--- krb5/appl/gssftp/ftpd/ftpcmd.y	Thu Dec 19 14:19:29 2002
***************
*** 66,71 ****
--- 66,78 ----
  #include <ctype.h>
  #include <stdlib.h>
  #include <string.h>
+ #ifdef __hpux
+ #include <alloca.h>
+ #endif
+ 
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
  
  extern	char *auth_type;
  
***************
*** 138,143 ****
--- 145,151 ----
  extern	int usedefault;
  extern  int transflag;
  extern  char tmpline[];
+ extern	int rbufsize;
  char	**ftpglob();
  
  off_t	restart_point;
***************
*** 148,153 ****
--- 156,165 ----
  char	cbuf[FTP_BUFSIZ]; /* was 512 */
  char	*fromname;
  
+ #ifdef SGI_DIRECT_IO
+ extern	int directsize;
+ #endif /* SGI_DIRECT_IO */
+ 
  /* bison needs these decls up front */
  extern jmp_buf errcatch;
  
***************
*** 160,165 ****
--- 172,178 ----
  #define	ZSTR2	6	/* optional STRING after SP */
  #define	SITECMD	7	/* SITE command */
  #define	NSTR	8	/* Number followed by a string */
+ #define BIGNUM	9	/* Large (64-bit) number as argument */
  
  struct tab {
  	char	*name;
***************
*** 172,178 ****
  struct tab sitetab[];
  %}
  
! %union { int num; char *str; }
  
  %token
  	SP	CRLF	COMMA	STRING	NUMBER
--- 185,191 ----
  struct tab sitetab[];
  %}
  
! %union { int num; char *str; off_t byte; }
  
  %token
  	SP	CRLF	COMMA	STRING	NUMBER
***************
*** 187,193 ****
  	AUTH	ADAT	PROT    PBSZ
  	CCC
  
! 	UMASK	IDLE	CHMOD
  
  	LEXERR
  
--- 200,206 ----
  	AUTH	ADAT	PROT    PBSZ
  	CCC
  
! 	UMASK	IDLE	CHMOD	RBUFSZ	DIRECT	ATMPASV
  
  	LEXERR
  
***************
*** 367,380 ****
--- 380,401 ----
  	|	STOR check_login SP pathname CRLF
  		{
  			if ($2 && $4 != NULL)
+ #ifdef USE_FILE64_FUNCS
+ 				store_file((char *) $4, "wl", 0);
+ #else /* ! USE_FILE64_FUNCS */
  				store_file((char *) $4, "w", 0);
+ #endif /* ! USE_FILE64_FUNCS */
  			if ($4 != NULL)
  				free((char *) $4);
  		}
  	|	APPE check_login SP pathname CRLF
  		{
  			if ($2 && $4 != NULL)
+ #ifdef USE_FILE64_FUNCS
+ 				store_file((char *) $4, "al", 0);
+ #else /* ! USE_FILE64_FUNCS */
  				store_file((char *) $4, "a", 0);
+ #endif /* ! USE_FILE64_FUNCS */
  			if ($4 != NULL)
  				free((char *) $4);
  		}
***************
*** 561,570 ****
--- 582,635 ----
  				    timeout);
  			}
  		}
+ 	|	SITE SP DIRECT SP NUMBER CRLF
+ 		{
+ #ifdef SGI_DIRECT_IO
+ 			directsize = $5;
+ 			if (directsize)
+ 				reply(200, "Using direct I/O buffer size of "
+ 					"%d bytes", directsize);
+ 			else
+ 				reply(200, "Disabling direct I/O");
+ #else
+ 			reply(500, "Direct I/O not supported on this system");
+ #endif /* SGI_DIRECT_IO */
+ 		}
+ 	|	SITE SP ATMPASV CRLF
+ 		{
+ #ifdef FORE_ATM_FTP
+ 			atmpassive();
+ #else
+ 			reply(500, "FORE ATM file transfer not supported");
+ #endif /* FORE_ATM_FTP */
+ 		}
+ 	|	SITE SP RBUFSZ CRLF
+ 		{
+ 			if (rbufsize)
+ 				reply(200, "Using a TCP buffer size of %d "
+ 					"bytes", rbufsize);
+ 			else
+ 				reply(200, "Using system default for TCP "
+ 					"buffer size");
+ 		}
+ 	|	SITE SP RBUFSZ SP NUMBER CRLF
+ 		{
+ 			rbufsize = $5;
+ 			if (rbufsize) 
+ 				reply(200, "TCP buffer size set to %d bytes",
+ 					rbufsize);
+ 			else
+ 				reply(200, "Using system default for TCP "
+ 					"buffer size");
+ 		}
  	|	STOU check_login SP pathname CRLF
  		{
  			if ($2 && $4 != NULL)
+ #ifdef USE_FILE64_FUNCS
+ 				store_file((char *) $4, "wl", 1);
+ #else /* ! USE_FILE64_FUNCS */
  				store_file((char *) $4, "w", 1);
+ #endif /* ! USE_FILE64_FUNCS */
  			if ($4 != NULL)
  				free((char *) $4);
  		}
***************
*** 614,620 ****
  			if ($2 && $4 != NULL) {
  				struct stat stbuf;
  				if (stat((char *) $4, &stbuf) < 0)
! 					perror_reply(550, "%s", (char *) $4);
  				else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
  					reply(550, "%s: not a plain file.",
  						(char *) $4);
--- 679,685 ----
  			if ($2 && $4 != NULL) {
  				struct stat stbuf;
  				if (stat((char *) $4, &stbuf) < 0)
! 					perror_reply(550, (char *) $4);
  				else if ((stbuf.st_mode&S_IFMT) != S_IFREG) {
  					reply(550, "%s: not a plain file.",
  						(char *) $4);
***************
*** 666,673 ****
  	|	REST SP byte_size CRLF
  		{
  			fromname = (char *) 0;
! 			restart_point = $3;
  			reply(350, "Restarting at %ld. %s", restart_point,
  			    "Send STORE or RETRIEVE to initiate transfer.");
  		}
  	;
--- 731,742 ----
  	|	REST SP byte_size CRLF
  		{
  			fromname = (char *) 0;
! 			restart_point = $<byte>3;
! #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
! 			reply(350, "Restarting at %lld. %s", restart_point,
! #else /* ! USE_FILE64_FUNCS */
  			reply(350, "Restarting at %ld. %s", restart_point,
+ #endif /* ! USE_FILE64_FUNCS */
  			    "Send STORE or RETRIEVE to initiate transfer.");
  		}
  	;
***************
*** 900,906 ****
  	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
  	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
  	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
! 	{ "REST", REST, ARGS, 1,	"(restart command)" },
  	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
  	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
  	{ "ABOR", ABOR, ARGS, 1,	"(abort operation)" },
--- 969,975 ----
  	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
  	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
  	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
! 	{ "REST", REST, BIGNUM, 1,	"(restart command)" },
  	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
  	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
  	{ "ABOR", ABOR, ARGS, 1,	"(abort operation)" },
***************
*** 937,942 ****
--- 1006,1018 ----
  	{ "UMASK", UMASK, ARGS, 1,	"[ <sp> umask ]" },
  	{ "IDLE", IDLE, ARGS, 1,	"[ <sp> maximum-idle-time ]" },
  	{ "CHMOD", CHMOD, NSTR, 1,	"<sp> mode <sp> file-name" },
+ 	{ "RBUFSZ", RBUFSZ, ARGS, 1,	"[ <sp> buffer-size ]" },
+ #ifdef SGI_DIRECT_IO
+ 	{ "DIRECT", DIRECT, ARGS, 1,	"[ <sp> direct-io-size ]" },
+ #endif /* SGI_DIRECT_IO */
+ #ifdef FORE_ATM_FTP
+ 	{ "ATMPASV", ATMPASV, ARGS, 1,	"(specify ATM file transfer)" },
+ #endif /* FORE_ATM_FTP */
  	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
  	{ NULL,   0,    0,    0,	0 }
  };
***************
*** 1332,1337 ****
--- 1408,1414 ----
  			goto dostr1;
  
  		case ARGS:
+ 			doargs:
  			if (isdigit(cbuf[cpos])) {
  				cp = &cbuf[cpos];
  				while (isdigit(cbuf[++cpos]))
***************
*** 1405,1410 ****
--- 1482,1510 ----
  			}
  			break;
  
+ 		case BIGNUM:
+ 			if (cbuf[cpos] == ' ') {
+ 				cpos++;
+ 				return (SP);
+ 			}
+ 			if (isdigit(cbuf[cpos])) {
+ 				cp = &cbuf[cpos];
+ 				while (isdigit(cbuf[++cpos]))
+ 					;
+ 				c = cbuf[cpos];
+ 				cbuf[cpos] = '\0';
+ #if defined(USE_FILE64_FUNCS) || defined(HAVE_ATOLL)
+ 				yylval.byte = atoll(cp);
+ #else /* defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8 */
+ 				yylval.byte = atol(cp);
+ #endif /* defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8 */
+ 				cbuf[cpos] = c;
+ 				state = ARGS;
+ 				return (NUMBER);
+ 			}
+ 			state = ARGS;
+ 			goto doargs;
+ 
  		default:
  			fatal("Unknown state in scanner.");
  		}
***************
*** 1512,1525 ****
  		    (stbuf.st_mode&S_IFMT) != S_IFREG)
  			reply(550, "%s: not a plain file.", filename);
  		else
  			reply(213, "%lu", stbuf.st_size);
  		break;}
  	case TYPE_A: {
  		FILE *fin;
  		register int c;
- 		register long count;
  		struct stat stbuf;
  		fin = fopen(filename, "r");
  		if (fin == NULL) {
  			perror_reply(550, filename);
  			return;
--- 1612,1634 ----
  		    (stbuf.st_mode&S_IFMT) != S_IFREG)
  			reply(550, "%s: not a plain file.", filename);
  		else
+ #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
+ 			reply(213, "%llu", stbuf.st_size);
+ #else /* ! USE_FILE64_FUNCS */
  			reply(213, "%lu", stbuf.st_size);
+ #endif /* ! USE_FILE64_FUNCS */
  		break;}
  	case TYPE_A: {
  		FILE *fin;
  		register int c;
  		struct stat stbuf;
+ #ifdef USE_FILE64_FUNCS
+ 		register long long count;
+ 		fin = fopen(filename, "rl");
+ #else /* ! USE_FILE64_FUNCS */
+ 		register long count;
  		fin = fopen(filename, "r");
+ #endif /* ! USE_FILE64_FUNCS */
  		if (fin == NULL) {
  			perror_reply(550, filename);
  			return;
***************
*** 1539,1545 ****
--- 1648,1658 ----
  		}
  		(void) fclose(fin);
  
+ #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
+ 		reply(213, "%lld", count);
+ #else /* ! USE_FILE64_FUNCS */
  		reply(213, "%ld", count);
+ #endif /* ! USE_FILE64_FUNCS */
  		break;}
  	default:
  		reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]);
Index: krb5/appl/gssftp/ftpd/ftpd.M
diff -c krb5/appl/gssftp/ftpd/ftpd.M:1.1.1.3 krb5/appl/gssftp/ftpd/ftpd.M:1.4
*** krb5/appl/gssftp/ftpd/ftpd.M:1.1.1.3	Fri Feb 22 16:31:36 2002
--- krb5/appl/gssftp/ftpd/ftpd.M	Sun Feb 24 22:56:41 2002
***************
*** 351,356 ****
--- 351,362 ----
  give help information.
  .IR E.g. ,
  SITE HELP
+ .sp -1
+ .TP
+ RBUFSZ
+ set or report the TCP buffer sizes
+ .IR E.g. ,
+ RBUFSZ 32768
  .PP
  The remaining ftp requests specified in Internet
  .I RFC 959
Index: krb5/appl/gssftp/ftpd/ftpd.c
diff -c krb5/appl/gssftp/ftpd/ftpd.c:1.1.1.4 krb5/appl/gssftp/ftpd/ftpd.c:1.30
*** krb5/appl/gssftp/ftpd/ftpd.c:1.1.1.4	Fri Feb 22 16:31:36 2002
--- krb5/appl/gssftp/ftpd/ftpd.c	Mon Nov  4 09:54:38 2002
***************
*** 71,76 ****
--- 71,81 ----
  #ifdef HAVE_SHADOW
  #include <shadow.h>
  #endif
+ 
+ #ifdef USE_FILE64_FUNCS
+ #include "largefile.h"
+ #endif /* USE_FILE64_FUNCS */
+ 
  #include <setjmp.h>
  #ifndef POSIX_SETJMP
  #undef sigjmp_buf
***************
*** 150,155 ****
--- 155,161 ----
  gss_ctx_id_t gcontext;
  gss_buffer_desc client_name;
  static char *gss_services[] = { "ftp", "host", NULL };
+ int hardware_preauth = 0;
  
  #include <krb5.h>
  krb5_context kcontext;
***************
*** 206,211 ****
--- 212,218 ----
  int	usedefault = 1;		/* for data transfers */
  int	pdata = -1;		/* for passive mode */
  int	transflag;
+ int	rbufsize = 0;		/* Buffer size */
  off_t	file_size;
  off_t	byte_count;
  #if !defined(CMASK) || CMASK == 0
***************
*** 220,225 ****
--- 227,244 ----
  char	rhost_addra[16];
  char	*rhost_sane;
  
+ #ifdef SGI_DIRECT_IO
+ int	directsize = 0;
+ struct	dioattr dio;
+ static	int directinit(char *, int);
+ static	off_t directrecv(int, int, off_t *);
+ #endif
+ 
+ #ifdef FORE_ATM_FTP
+ int	atm = -1;
+ extern int atminitlisten(unsigned char *, unsigned char *, int);
+ int	atmpcr = 0;
+ #endif /* FORE_ATM_FTP */
  /* Defines for authlevel */
  #define AUTHLEVEL_NONE		0
  #define AUTHLEVEL_AUTHENTICATE	1
***************
*** 256,261 ****
--- 275,348 ----
  char	proctitle[FTP_BUFSIZ];	/* initial part of title */
  #endif /* SETPROCTITLE */
  
+ /*
+  * AFS PAG and ticket destruction code
+  */
+ 
+ #ifdef SETPAG
+ 
+ typedef krb5_sigtype sigtype;
+ 
+ #ifndef POSIX_SETJMP
+ #undef sigjmp_buf
+ #undef sigsetjmp
+ #undef siglongjmp
+ #define sigjmp_buf	jmp_buf
+ #define sigsetjmp(j,s)	setjmp(j)
+ #define siglongjmp	longjmp
+ #endif
+ 
+ #if !defined(SIGSYS) && defined(__linux__)
+ /* Linux doesn't seem to have SIGSYS */
+ #define SIGSYS	SIGUNUSED
+ #endif
+ 
+ #ifdef POSIX_SIGNALS
+ typedef struct sigaction handler;
+ #define handler_init(H,F)		(sigemptyset(&(H).sa_mask), \
+ 					 (H).sa_flags=0, \
+ 					 (H).sa_handler=(F))
+ #define handler_swap(S,NEW,OLD)		sigaction(S, &NEW, &OLD)
+ #define handler_set(S,OLD)		sigaction(S, &OLD, NULL)
+ #else
+ typedef sigtype (*handler)();
+ #define handler_init(H,F)		((H) = (F))
+ #define handler_swap(S,NEW,OLD)		((OLD) = signal ((S), (NEW)))
+ #define handler_set(S,OLD)		(signal ((S), (OLD)))
+ #endif
+ 
+ extern setpag(), ktc_ForgetAllTokens();
+ 
+ static int pagflag = 0;
+ 
+ static sigjmp_buf setpag_buf;
+ 
+ static sigtype sigsys ()
+ {
+     siglongjmp(setpag_buf, 1);
+ }
+ 
+ static int try_afscall(scall)
+ 	int (*scall)();
+ {
+ 	handler sa, osa;
+ 	volatile int retval = 0;
+ 
+ 	(void) &retval;
+ 	handler_init(sa, sigsys);
+ 	handler_swap(SIGSYS, sa, osa);
+ 	if (sigsetjmp(setpag_buf, 1) == 0) {
+ 	    (*scall)();
+ 	    retval = 1;
+ 	}
+ 	handler_set(SIGSYS, osa);
+ 	return retval;
+ }
+ 
+ #define try_setpag()	try_afscall(setpag);
+ #define try_unlog()	try_afscall(ktc_ForgetAllTokens)
+ #endif /* SETPAG */
+ 
  #ifdef __SCO__
  /* sco has getgroups and setgroups but no initgroups */
  int initgroups(char* name, gid_t basegid) {
***************
*** 277,284 ****
  	char *argv[];
  	char **envp;
  {
! 	int addrlen, on = 1, tos, port = -1;
  	char *cp;
  
  #ifdef KRB5_KRB4_COMPAT
  	keyfile = KEYFILE;
--- 364,373 ----
  	char *argv[];
  	char **envp;
  {
! 	int on = 1, tos, port = -1;
! 	size_t addrlen;
  	char *cp;
+ 	char ccname[35];
  
  #ifdef KRB5_KRB4_COMPAT
  	keyfile = KEYFILE;
***************
*** 296,302 ****
  
  #ifdef GSSAPI
  	krb5_init_context(&kcontext);
! #ifdef KRB5_KRB4_COMPAT
  	krb524_init_ets(kcontext);
  #endif
  #endif
--- 385,391 ----
  
  #ifdef GSSAPI
  	krb5_init_context(&kcontext);
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	krb524_init_ets(kcontext);
  #endif
  #endif
***************
*** 374,379 ****
--- 463,474 ----
  				maxtimeout = timeout;
  			goto nextopt;
  
+ #ifdef GSSAPI
+ 		case 'H':
+ 			hardware_preauth = 1;
+ 			break;
+ #endif /* GSSAPI */
+ 
  		case 'T':
  			maxtimeout = atoi(++cp);
  			if (timeout > maxtimeout)
***************
*** 441,447 ****
  
  	if (port != -1) {
  		struct sockaddr_in sin;
! 		int s, ns, sz;
  
  		/* Accept an incoming connection on port.  */
  		sin.sin_family = AF_INET;
--- 536,543 ----
  
  	if (port != -1) {
  		struct sockaddr_in sin;
! 		int s, ns;
! 		size_t sz;
  
  		/* Accept an incoming connection on port.  */
  		sin.sin_family = AF_INET;
***************
*** 714,719 ****
--- 810,831 ----
  
  	authorized = guest = 0;
  	if (strcmp(name, "ftp") == 0 || strcmp(name, "anonymous") == 0) {
+ #ifdef NO_ANONYMOUS_FTP
+ 	  /* the intent here is to provide additional protection
+ 	     against host mis-configuration.  Even if a user or
+ 	     system admin makes a mistake and enables anonymous
+ 	     FTP via ftpusers, this will prevent the binary from
+ 	     honoring that mistake.
+ 	  */
+ 		reply(530, "User %s access denied.", name);
+ 		if (logging)
+ 			syslog(LOG_NOTICE,
+ 			    "ANONYMOUS FTP LOGIN REFUSED (not supported) FROM %s, %s",
+ 			    remotehost, name);
+ 		pw = (struct passwd *) NULL;
+ 		return;		/* NOTE: cheap sleazy exit if we don't support ANONYMOUS */
+ #else
+ 
  		if (disallowed_user("ftp") || disallowed_user("anonymous"))
  			reply(530, "User %s access denied.", name);
  		else if ((pw = sgetpwnam("ftp")) != NULL) {
***************
*** 723,728 ****
--- 835,841 ----
  		} else
  			reply(530, "User %s unknown.", name);
  		return;
+ #endif
  	}
  
  	/*
***************
*** 896,901 ****
--- 1009,1017 ----
   */
  end_login()
  {
+ #ifdef GSSAPI
+ 	afs_logout();
+ #endif
  
  	(void) krb5_seteuid((uid_t)0);
  	if (logged_in)
***************
*** 1119,1124 ****
--- 1235,1249 ----
  			goto bad;
  		}
  	}
+ 
+ 	/*
+ 	 * For weird reasons, we need to call setpag now while we're still
+ 	 * root
+ 	 */
+ #ifdef SETPAG
+ 		pagflag = try_setpag();
+ #endif /* SETPAG */
+ 
  #ifdef HAVE_SETLUID
    	/*
    	 * If we're on a system which keeps track of login uids, then
***************
*** 1146,1151 ****
--- 1271,1285 ----
  			goto bad;
  		}
  	} else {
+ 
+ 		/*
+ 		 * Do AFS login stuff now
+ 		 */
+ 
+ #ifdef SETPAG
+ 		afs_login(pw->pw_uid);
+ #endif
+ 
  	        if (chdir(restricted ? "/" : pw->pw_dir) < 0) {
  		        if (chdir("/") < 0) {
  			        reply(530, "User %s: can't change directory to %s.",
***************
*** 1180,1186 ****
  		setproctitle(proctitle);
  #endif /* SETPROCTITLE */
  		if (logging)
! 			syslog(LOG_INFO, "FTP LOGIN FROM %s, %s (%s)",
  			    rhost_addra, remotehost, pw->pw_name);
  	}
  	home = pw->pw_dir;		/* home dir for globbing */
--- 1314,1327 ----
  		setproctitle(proctitle);
  #endif /* SETPROCTITLE */
  		if (logging)
! 			syslog(LOG_INFO, "FTP %s LOGIN FROM %s %s, (%s)",
! #ifdef LOG_PREAUTH_LOGINS
! 			       (authorized
! 				? "PREAUTHENTICATED "
! 				: "PASSWORD "),
! #else /* LOG_PREAUTH_LOGINS */
! 			       "",
! #endif /* ! LOG_PREAUTH_LOGINS */
  			    rhost_addra, remotehost, pw->pw_name);
  	}
  	home = pw->pw_dir;		/* home dir for globbing */
***************
*** 1201,1207 ****
--- 1342,1352 ----
  	if (logging > 1 && !cmd)
  	        syslog(LOG_NOTICE, "get %s", path_expand(name));
  	if (cmd == 0) {
+ #ifdef USE_FILE64_FUNCS
+ 		fin = fopen(name, "rl"), closefunc = fclose;
+ #else /* ! USE_FILE64_FUNCS */
  		fin = fopen(name, "r"), closefunc = fclose;
+ #endif /* ! USE_FILE64_FUNCS */
  		st.st_size = 0;
  	} else {
  		char line[FTP_BUFSIZ];
***************
*** 1228,1233 ****
--- 1373,1383 ----
  		reply(550, "%s: not a plain file.", name);
  		goto done;
  	}
+ #ifdef SGI_DIRECT_IO
+ 	if (cmd == 0 && directsize)
+ 		if (directinit(name, fileno(fin)) < 0)
+ 			goto done;
+ #endif /* SGI_DIRECT_IO */
  	if (restart_point) {
  		if (type == TYPE_A) {
  			register int i, n, c;
***************
*** 1258,1263 ****
--- 1408,1416 ----
  	(void) fclose(dout);
  	data = -1;
  	pdata = -1;
+ #ifdef FORE_ATM_FTP
+ 	atm = -1;
+ #endif /* FORE_ATM_FTP */
  done:
  	(*closefunc)(fin);
  	if (logging > 2 && !cmd)
***************
*** 1280,1292 ****
--- 1433,1454 ----
  		return;
  
  	if (restart_point)
+ #ifdef USE_FILE64_FUNCS
+ 		mode = "r+wl";
+ #else /* ! USE_FILE64_FUNCS */
  		mode = "r+w";
+ #endif /* ! USE_FILE64_FUNCS */
  	fout = fopen(name, mode);
  	closefunc = fclose;
  	if (fout == NULL) {
  		perror_reply(553, name);
  		return;
  	}
+ #ifdef SGI_DIRECT_IO
+ 	if (directsize && type == TYPE_I)
+ 		if (directinit(name, fileno(fout)) < 0)
+ 			return;
+ #endif /* SGI_DIRECT_IO */
  	if (restart_point) {
  		if (type == TYPE_A) {
  			register int i, n, c;
***************
*** 1328,1333 ****
--- 1490,1498 ----
  	(void) fclose(din);
  	data = -1;
  	pdata = -1;
+ #ifdef FORE_ATM_FTP
+ 	atm = -1;
+ #endif /* FORE_ATM_FTP */
  done:
  	(*closefunc)(fout);
  	if (logging > 2)
***************
*** 1349,1354 ****
--- 1514,1525 ----
  	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
  	    (char *) &on, sizeof (on)) < 0)
  		goto bad;
+ 	if (rbufsize) {
+ 		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&rbufsize, sizeof(rbufsize)) < 0)
+ 			goto bad;
+ 		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&rbufsize, sizeof(rbufsize)) < 0)
+ 			goto bad;
+ 	}
  	/* anchor socket to avoid multi-homing problems */
  	data_source.sin_family = AF_INET;
  	data_source.sin_addr = ctrl_addr.sin_addr;
***************
*** 1388,1399 ****
  	file_size = size;
  	byte_count = 0;
  	if (size != (off_t) -1)
! 		/* cast size to long in case sizeof(off_t) > sizeof(long) */
! 		(void) sprintf (sizebuf, " (%ld bytes)", (long)size);
  	else
  		(void) strcpy(sizebuf, "");
  	if (pdata >= 0) {
! 		int s, fromlen = sizeof(data_dest);
  
  		s = accept(pdata, (struct sockaddr *)&data_dest, &fromlen);
  		if (s < 0) {
--- 1559,1574 ----
  	file_size = size;
  	byte_count = 0;
  	if (size != (off_t) -1)
! #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
! 		(void) sprintf (sizebuf, " (%lld bytes)", size);
! #else /* ! USE_FILE64_FUNCS */
! 		(void) sprintf (sizebuf, " (%ld bytes)", size);
! #endif /* ! USE_FILE64_FUNCS */
  	else
  		(void) strcpy(sizebuf, "");
  	if (pdata >= 0) {
! 		int s;
! 		size_t fromlen = sizeof(data_dest);
  
  		s = accept(pdata, (struct sockaddr *)&data_dest, &fromlen);
  		if (s < 0) {
***************
*** 1415,1420 ****
--- 1590,1605 ----
  		     type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
  		return(fdopen(pdata, mode));
  	}
+ #ifdef FORE_ATM_FTP
+ 	if (atm >= 0 ) {
+ 		reply(150, "Opening %s mode ATM connection for %s%s.",
+ 		      type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf);
+ 		return(fdopen(atm, mode));
+ 	} else if (atm == -2) {
+ 		reply(435, "Cannot listen for ATM connection");
+ 		return(NULL);
+ 	}
+ #endif /* FORE_ATM_FTP */
  	if (data >= 0) {
  		reply(125, "Using existing data connection for %s%s.",
  		    name, sizebuf);
***************
*** 1491,1496 ****
--- 1676,1684 ----
  	register char *buf;
  	int netfd, filefd;
  	volatile int ret = 0;
+ #ifdef SGI_DIRECT_IO
+ 	volatile int flags;
+ #endif /* SGI_DIRECT_IO */
  
  	transflag++;
  	if (sigsetjmp(urgcatch, 1)) {
***************
*** 1522,1527 ****
--- 1710,1741 ----
  
  	case TYPE_I:
  	case TYPE_L:
+ #ifdef FORE_ATM_FTP
+ 		if (atm >= 0) {
+ 			int retval;
+ 			retval = swp_xmit_go(fileno(outstr), fileno(instr));
+ 			atm_disconnect(fileno(outstr));
+ 			if (retval < 0) {
+ 				transflag = 0;
+ 				reply(450, "ATM Transfer failed!");
+ 				return;
+ 			}
+ 			reply(226, "ATM transfer complete!");
+ 			return;
+ 		} else
+ #endif /* FORE_ATM_FTP */
+ #ifdef SGI_DIRECT_IO
+ 		if (directsize && (flags = fcntl(fileno(instr), F_GETFL)) != -1 &&
+ 		    flags & FDIRECT) {
+ 			blksize = directsize;
+ 			if ((buf = valloc((u_int)blksize)) == NULL) {
+ 				transflag = 0;
+ 				perror_reply(451, "Local resource failure: "
+ 					     "valloc");
+ 				return;
+ 			}
+ 		} else
+ #endif /* SGI_DIRECT_IO */
  		if ((buf = malloc((u_int)blksize)) == NULL) {
  			transflag = 0;
  			perror_reply(451, "Local resource failure: malloc");
***************
*** 1532,1539 ****
  		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
  		    (ret = secure_write(netfd, buf, cnt)) == cnt)
  			byte_count += cnt;
- 		transflag = 0;
  		(void)free(buf);
  		if (cnt != 0) {
  			if (cnt < 0)
  				goto file_err;
--- 1746,1753 ----
  		while ((cnt = read(filefd, buf, (u_int)blksize)) > 0 &&
  		    (ret = secure_write(netfd, buf, cnt)) == cnt)
  			byte_count += cnt;
  		(void)free(buf);
+ 		transflag = 0;
  		if (cnt != 0) {
  			if (cnt < 0)
  				goto file_err;
***************
*** 1584,1589 ****
--- 1798,1816 ----
  
  	case TYPE_I:
  	case TYPE_L:
+ #ifdef SGI_DIRECT_IO
+ 		if (directsize)
+ 			cnt = directrecv(fileno(instr), fileno(outstr),
+ 					 &byte_count);
+ 		else
+ #endif /* SGI_DIRECT_IO */
+ #ifdef FORE_ATM_FTP
+ 		if (atm >= 0) {
+ 			byte_count = cnt =
+ 				swp_recv_go(fileno(instr), fileno(outstr));
+ 			atm_disconnect(fileno(outstr));
+ 		} else
+ #endif /* FORE_ATM_FTP */
  		while ((cnt = secure_read(fileno(instr), buf, sizeof buf)) > 0) {
  			if (write(fileno(outstr), buf, cnt) != cnt)
  				goto file_err;
***************
*** 1647,1652 ****
--- 1874,1970 ----
  	return (-1);
  }
  
+ #ifdef SGI_DIRECT_IO
+ static int
+ directinit(char *name, int fin)
+ {
+ 	int flags;
+ 
+ 	if (fcntl(fin, F_DIOINFO, &dio) == -1) {
+ 		reply(550, "Cannot do direct I/O on %s: %s", name,
+ 		      strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	if (directsize < dio.d_miniosz) {
+ 		reply(550, "Minimum direct I/O size must be %d.",
+ 		      dio.d_miniosz);
+ 		return -1;
+ 	}
+ 
+ 	if (directsize % dio.d_miniosz) {
+ 		reply(550, "Direct I/O must be a multiple of %d bytes.",
+ 		      dio.d_miniosz);
+ 		return -1;
+ 	}
+ 
+ 	if ((flags = fcntl(fin, F_GETFL)) == -1) {
+ 		perror_reply(550, "Cannot get file flags");
+ 		return -1;
+ 	}
+ 
+ 	if (fcntl(fin, F_SETFL, flags | FDIRECT) == -1) {
+ 		reply(550, "Cannot set FDIRECT flag for file %s: %s", name,
+ 		      strerror(errno));
+ 		return -1;
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ static off_t
+ directrecv(int fin, int fout, off_t *byte_count)
+ {
+ 	off_t c, d;
+ 	int flags;
+ 	char *buffer, *bufp;
+ 	int direct_turned_off = 0;
+ 
+ 	*byte_count = 0;
+ 
+ 	if ((flags = fcntl(fout, F_GETFL)) == -1)
+ 		return -1;
+ 	
+ 	if (! (buffer = valloc(directsize)))
+ 		return -1;
+ 	
+ 	while ((c = secure_read(fin, buffer, directsize)) > 0) {
+ 
+ 		while (c < directsize && (d = secure_read(fin, buffer + c,
+ 							  directsize - c)) > 0)
+ 			c += d;
+ 
+ 		*byte_count += c;
+ 		for (bufp = buffer; c > 0; c -= d, bufp += d) {
+ 			if (!direct_turned_off && (c % directsize)) {
+ 				/*
+ 				 * Before we turn off direct I/O, write
+ 				 * as large of a chunk as we can using it.
+ 				 */
+ 				if (c / dio.d_miniosz) {
+ 					d = write(fout, bufp,
+ 					  (c / dio.d_miniosz) * dio.d_miniosz);
+ 					continue;
+ 				}
+ 
+ 				flags &= ~ FDIRECT;
+ 				direct_turned_off = 1;
+ 				fcntl(fout, F_SETFL, flags);
+ 			}
+ 			if ((d = write(fout, bufp, c)) <= 0)
+ 				break;
+ 		}
+ 	}
+ 
+ 	free(buffer);
+ 
+ 	if (c < 0 && d < c)
+ 		return -1;
+ 
+ 	return *byte_count;
+ }
+ #endif /* SGI_DIRECT_IO */
+ 
  statfilecmd(filename)
  	char *filename;
  {
***************
*** 2079,2084 ****
--- 2397,2411 ----
  dologout(status)
  	int status;
  {
+ 	/*
+ 	 * Prevent reception of SIGURG from resulting in a resumption
+ 	 * back to the main program loop.
+ 	 */
+ 	transflag = 0;
+ 
+ #ifdef GSSAPI
+ 	afs_logout();
+ #endif
  	if (logged_in) {
  		(void) krb5_seteuid((uid_t)0);
  		pty_logwtmp(ttyline, "", "");
***************
*** 2122,2131 ****
--- 2449,2465 ----
  	}
  	if (strcmp(cp, "STAT") == 0) {
  		if (file_size != (off_t) -1)
+ #if defined(USE_FILE64_FUNCS) || SIZEOF_OFF_T == 8
+ 			reply(213, "Status: %llu of %llu bytes transferred",
+ 			    byte_count, file_size);
+ 		else
+ 			reply(213, "Status: %llu bytes transferred", byte_count);
+ #else /* ! USE_FILE64_FUNCS */
  			reply(213, "Status: %lu of %lu bytes transferred",
  			    byte_count, file_size);
  		else
  			reply(213, "Status: %lu bytes transferred", byte_count);
+ #endif /* ! USE_FILE64_FUNCS */
  	}
  }
  
***************
*** 2137,2143 ****
   */
  passive()
  {
! 	int len;
  	register char *p, *a;
  
  	pdata = socket(AF_INET, SOCK_STREAM, 0);
--- 2471,2477 ----
   */
  passive()
  {
! 	size_t len;
  	register char *p, *a;
  
  	pdata = socket(AF_INET, SOCK_STREAM, 0);
***************
*** 2152,2157 ****
--- 2486,2501 ----
  		(void) krb5_seteuid((uid_t)pw->pw_uid);
  		goto pasv_error;
  	}
+ 	if (rbufsize) {
+ 		if (setsockopt(pdata, SOL_SOCKET, SO_SNDBUF, (char *)&rbufsize, sizeof(rbufsize)) < 0) {
+ 			perror_reply(425, "Can't set requested socket buffer send size");
+ 			return;
+ 		}
+ 		if (setsockopt(pdata, SOL_SOCKET, SO_RCVBUF, (char *)&rbufsize, sizeof(rbufsize)) < 0) {
+ 			perror_reply(425, "Can't set requested socket buffer receive size");
+ 			return;
+ 		}
+ 	}
  	(void) krb5_seteuid((uid_t)pw->pw_uid);
  	len = sizeof(pasv_addr);
  	if (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)
***************
*** 2174,2179 ****
--- 2518,2575 ----
  	return;
  }
  
+ #ifdef FORE_ATM_FTP
+ /*
+  * Handle our SITE ATMPASV command
+  */
+ atmpassive()
+ {
+ 	unsigned char atm_addr[20], magic[8];
+ 	char reply_string[FTP_BUFSIZ];
+ 	int fd;
+ 
+ 	if (type != TYPE_I) {
+ 		reply(425, "ATM transfer only supported for BINARY");
+ 		return;
+ 	}
+ 
+ 	if ((fd = atminitlisten(atm_addr, magic, getpid())) == -1) {
+ 		reply(425, "Cannot determine ATM endpoint address");
+ 		return;
+ 	}
+ 	
+ 	/* Ouch */
+ 	
+ 	snprintf(reply_string, FTP_BUFSIZ, "Listening for ATM connection. "
+ 		 "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,"
+ 		 "%d,%d,%d,%d,%d,%d,%d,%d)", atm_addr[0],atm_addr[1],
+ 		 atm_addr[2], atm_addr[3], atm_addr[4], atm_addr[5],
+ 		 atm_addr[6], atm_addr[7], atm_addr[8], atm_addr[9],
+ 		 atm_addr[10], atm_addr[11], atm_addr[12], atm_addr[13],
+ 		 atm_addr[14], atm_addr[15], atm_addr[16], atm_addr[17],
+ 		 atm_addr[18], atm_addr[19], magic[0], magic[1], magic[2],
+ 		 magic[3], magic[4], magic[5], magic[6], magic[7]);
+ 	
+ 	reply(227, reply_string);
+ 
+ 	/*
+ 	 * Okay ... this is mega bogus, but here's the problem.  The !@#$%
+ 	 * XTI (who THE FUCK DECIDED THIS API WAS A GOOD IDEA?!??!?!)
+ 	 * can't set up a non-blocking listen for a connection.  So we
+ 	 * have to block here and wait for an incoming connection.  This
+ 	 * isn't a problem ... as long as you open a connection right after
+ 	 * a SITE ATMPASV command.  But if you don't, then the ftp daemon
+ 	 * is going to be hung.  Sigh.
+ 	 */
+ 
+ 	if (atm_accept(fd)) {
+ 		atm_disconnect(fd);
+ 		atm = -2;
+ 	} else
+ 		atm = fd;
+ }
+ #endif /* FORE_ATM_FTP */
+ 
  /*
   * Generate unique name for file with basename "local".
   * The file named "local" is already known to exist.
***************
*** 2337,2343 ****
  		gss_cred_id_t server_creds, deleg_creds;
  		gss_name_t client;
  		int ret_flags;
- 		struct gss_channel_bindings_struct chan;
  		gss_buffer_desc name_buf;
  		gss_name_t server_name;
  		OM_uint32 acquire_maj, acquire_min, accept_maj, accept_min,
--- 2733,2738 ----
***************
*** 2350,2364 ****
  		char service_name[MAXHOSTNAMELEN+10];
  		char **service;
  		struct hostent *hp;
  
- 		chan.initiator_addrtype = GSS_C_AF_INET;
- 		chan.initiator_address.length = 4;
- 		chan.initiator_address.value = &his_addr.sin_addr.s_addr;
- 		chan.acceptor_addrtype = GSS_C_AF_INET;
- 		chan.acceptor_address.length = 4;
- 		chan.acceptor_address.value = &ctrl_addr.sin_addr.s_addr;
- 		chan.application_data.length = 0;
- 		chan.application_data.value = 0;
  
  		if (kerror = radix_encode(data, gout_buf, &length, 1)) {
  			reply(501, "Couldn't decode ADAT (%s)",
--- 2745,2755 ----
  		char service_name[MAXHOSTNAMELEN+10];
  		char **service;
  		struct hostent *hp;
+ #ifdef KRB5_MULTIHOMED_FIXES
+ 		struct sockaddr_in s;
+ 		int slen;
+ #endif /* KRB5_MULTIHOMED_FIXES */
  
  
  		if (kerror = radix_encode(data, gout_buf, &length, 1)) {
  			reply(501, "Couldn't decode ADAT (%s)",
***************
*** 2370,2385 ****
  		tok.value = gout_buf;
  		tok.length = length;
  
  		if (gethostname(localname, MAXHOSTNAMELEN)) {
  			reply(501, "couldn't get local hostname (%d)\n", errno);
  			syslog(LOG_ERR, "Couldn't get local hostname (%d)", errno);
  			return 0;
  		}
  		if (!(hp = gethostbyname(localname))) {
! 			reply(501, "couldn't canonicalize local hostname\n");
! 			syslog(LOG_ERR, "Couldn't canonicalize local hostname");
  			return 0;
  		}
  		strncpy(localname, hp->h_name, sizeof(localname) - 1);
  		localname[sizeof(localname) - 1] = '\0';
  
--- 2761,2802 ----
  		tok.value = gout_buf;
  		tok.length = length;
  
+ #ifndef KRB5_MULTIHOMED_FIXES
  		if (gethostname(localname, MAXHOSTNAMELEN)) {
  			reply(501, "couldn't get local hostname (%d)\n", errno);
  			syslog(LOG_ERR, "Couldn't get local hostname (%d)", errno);
  			return 0;
  		}
  		if (!(hp = gethostbyname(localname))) {
! #ifndef h_errno
! 			extern int h_errno;
! #endif /* h_errno */
! 			reply(501, "couldn't canonicalize local hostname (%d)\n", h_errno);
! 			syslog(LOG_ERR, "Couldn't canonicalize local hostname (%d)", h_errno);
  			return 0;
  		}
+ #else /* KRB5_MULTIHOMED_FIXES */
+ 		slen = sizeof(s);
+ 		if (getsockname(0, (struct sockaddr *) &s, &slen) < 0) {
+ 			reply(501, "couldn't get socket name (%d)\n", errno);
+ 			syslog(LOG_ERR, "Couldn't get socket name (%d)", errno);
+ 			return 0;
+ 		}
+ 		if (!(hp = gethostbyaddr((char *)&s.sin_addr.s_addr,
+ 														 sizeof(s.sin_addr.s_addr),
+ 														 AF_INET))) {
+ #ifndef h_errno
+ 			/*
+ 			 * Under AIX h_errno is a macro.
+ 			 * This should really be a feature test.
+ 			 */
+ 			extern int h_errno;
+ #endif /* h_errno */
+ 			reply(501, "couldn't canonicalize local hostname (%d)\n", h_errno);
+ 			syslog(LOG_ERR, "Couldn't canonicalize local hostname (%d)", h_errno);
+ 			return 0;
+ 		}
+ #endif /* KRB5_MULTIHOMED_FIXES */
  		strncpy(localname, hp->h_name, sizeof(localname) - 1);
  		localname[sizeof(localname) - 1] = '\0';
  
***************
*** 2415,2421 ****
  							    &gcontext, /* context_handle */
  							    server_creds, /* verifier_cred_handle */
  							    &tok, /* input_token */
! 							    &chan, /* channel bindings */
  							    &client, /* src_name */
  							    &mechid, /* mech_type */
  							    &out_tok, /* output_token */
--- 2832,2838 ----
  							    &gcontext, /* context_handle */
  							    server_creds, /* verifier_cred_handle */
  							    &tok, /* input_token */
! 							    GSS_C_NO_CHANNEL_BINDINGS, /* channel bindings */
  							    &client, /* src_name */
  							    &mechid, /* mech_type */
  							    &out_tok, /* output_token */
***************
*** 2451,2456 ****
--- 2868,2900 ----
  			return 0;
  		}
  
+ 		/*
+ 		 * If we're requiring hardware preauth, check for that now
+ 		 * (if we got GSS_S_COMPLETE)
+ 		 */
+ 
+ 		if (hardware_preauth && stat_maj == GSS_S_COMPLETE) {
+ 			krb5_flags flags;
+ 
+ 			stat_maj = gss_krb5_get_tkt_flags(&stat_min, gcontext,
+ 							  &flags);
+ 			
+ 			if (stat_maj != GSS_S_COMPLETE) {
+ 				reply_gss_error(535, stat_maj, stat_min,
+ 						"extracting ticket flags");
+ 				syslog(LOG_ERR, "gssapi error extracting ticket flags");
+ 				gss_release_cred(&stat_min, &server_creds);
+ 				return 0;
+ 			}
+ 
+ 			if (! (flags & TKT_FLG_HW_AUTH)) {
+ 				reply(535, "Hardware preauthentication "
+ 				      "required for access to this machine");
+ 				gss_release_cred(&stat_min, &server_creds);
+ 				return 0;
+ 			}
+ 		}
+ 
  		if (out_tok.length) {
  			if (out_tok.length >= ((FTP_BUFSIZ - sizeof("ADAT="))
  					       / 4 * 3)) {
***************
*** 2505,2511 ****
--- 2949,2957 ----
  
  			(void) gss_release_cred(&stat_min, &server_creds);
  			if (ret_flags & GSS_C_DELEG_FLAG) {
+ #ifndef SETPAG
  			  if (want_creds)
+ #endif /* ! SETPAG */
  			    ftpd_gss_convert_creds(client_name.value,
  						   deleg_creds);
  			  (void) gss_release_cred(&stat_min, &deleg_creds);
***************
*** 2649,2654 ****
--- 3095,3103 ----
  				transflag = 0;
  				data = -1;
  				pdata = -1;
+ #ifdef FORE_ATM_FTP
+ 				atm = -1;
+ #endif /* FORE_ATM_FTP */
  			}
  			return;
  		}
***************
*** 2737,2742 ****
--- 3186,3194 ----
  	  (void) fclose(dout);
  	data = -1;
  	pdata = -1;
+ #ifdef FORE_ATM_FTP
+ 	atm = -1;
+ #endif /* FORE_ATM_FTP */
  }
  
  #ifdef SETPROCTITLE
***************
*** 2841,2846 ****
--- 3293,3389 ----
  	return retval;
  }
  
+ /*
+  * Handle the magic we need for AFS.  Get a PAG and try to run aklog.
+  *
+  * Most of this was taken from login.
+  */
+ 
+ afs_login(uid)
+ 	int uid;
+ {
+ 	krb5_context context;
+ 	krb5_ccache cc;
+ 	int try_aklog = 0;
+ 	char *aklog_path;
+ 	struct stat st;
+ 
+ 	if (!have_creds)
+ 		return;
+ 
+ 	krb5_init_context(&context);
+ 
+ 	krb5_appdefault_boolean(context, "ftpd", NULL,
+ 				"krb5_run_aklog", try_aklog, &try_aklog);
+ 	
+ 	if (try_aklog) {
+ 		krb5_appdefault_string(context, "ftpd", NULL,
+ 				       "krb5_aklog_path", KPROGDIR "/aklog",
+ 				       &aklog_path);
+ 		
+ 		if (stat(aklog_path, &st) == 0) {
+ 			int pid, testpid;
+ 
+ 			/*
+ 			 * Aklog _really_ wants to run as "real user",
+ 			 * and in some cases, aklog breaks when using it
+ 			 * with an NFS translator.  Make sure that we run
+ 			 * aklog as the real user.
+ 			 */
+ 
+ 			if ((pid = fork()) == 0) {
+ 				seteuid(0);
+ 				setuid((uid_t) uid);
+ 				system(aklog_path);
+ 				exit(0);
+ 			} else {
+ 				while ((testpid = wait(NULL)) != pid &&
+ 					testpid != -1);
+ 			}
+ 		}
+ 
+ 		free(aklog_path);
+ 	}
+ 
+ leave:
+ 
+ 	krb5_free_context(context);
+ 
+ }
+ 
+ afs_logout()
+ {
+ 	krb5_context context;
+ 	krb5_ccache cc;
+ 	int afs_retain_token = 0;
+ 	char *realm = NULL;
+ 	krb5_data realmdata;
+ 
+ 	krb5_init_context(&context);
+ 
+ 	krb5_cc_default(context, &cc);
+ 
+ 	krb5_cc_destroy(context, cc);
+ 
+ 	krb5_get_default_realm(context, &realm);
+ 
+ 	realmdata.data = realm;
+ 
+ 	krb5_appdefault_boolean(context, "ftpd", &realmdata, "afs_retain_token",
+ 				afs_retain_token, &afs_retain_token);
+ 	
+ 	krb5_free_default_realm(context, realm);
+ 
+ 	if (!afs_retain_token) {
+ #ifdef SETPAG
+ 		if (pagflag)
+ 			try_unlog();
+ #endif /* SETPAG */
+ 	}
+ 
+ 	krb5_free_context(context);
+ }
+ 
  /* ftpd_gss_convert_creds -- write out forwarded creds */
  /* (code lifted from login.krb5) */
  ftpd_gss_convert_creds(name, creds)
***************
*** 2871,2877 ****
  	if (major_status != GSS_S_COMPLETE)
  		goto cleanup;
  
! #ifdef KRB5_KRB4_COMPAT
  	/* Convert krb5 creds to krb4 */
  
  	if (krb5_build_principal_ext(kcontext, &kpcserver, 
--- 3414,3422 ----
  	if (major_status != GSS_S_COMPLETE)
  		goto cleanup;
  
! 	setenv("KRB5CCNAME", ccname, 1);
! 
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  	/* Convert krb5 creds to krb4 */
  
  	if (krb5_build_principal_ext(kcontext, &kpcserver, 
Index: krb5/appl/gssftp/ftpd/largefile.h
diff -c /dev/null krb5/appl/gssftp/ftpd/largefile.h:1.1
*** /dev/null	Sun Mar 16 20:22:08 2003
--- krb5/appl/gssftp/ftpd/largefile.h	Fri Feb  5 16:19:16 1999
***************
*** 0 ****
--- 1,22 ----
+ /*
+  * This header file contains functions and definitions for platforms
+  * (i.e. SPP-UX) that require separate facilities for accessing large
+  * files (64 bit)
+  */
+ 
+ #include <sys/cnx_types.h>
+ #include <sys/cnx_stat.h>
+ #include <sys/cnx_unistd.h>
+ 
+ #undef off_t
+ #define off_t off64_t
+ #undef stat()
+ #define stat(f, b) stat64(f, b)
+ #undef fstat()
+ #define fstat(f, b) fstat64(f, b)
+ #undef fseek()
+ #define fseek(s, o, w) fseek64(s, o, w)
+ #undef lseek()
+ #define lseek(f, o, w) lseek64(f, o, w)
+ #undef stat
+ #define stat stat64
Index: krb5/appl/gssftp/ftpd/logwtmp.c
diff -c krb5/appl/gssftp/ftpd/logwtmp.c:1.1.1.3 krb5/appl/gssftp/ftpd/logwtmp.c:1.7
*** krb5/appl/gssftp/ftpd/logwtmp.c:1.1.1.3	Fri Feb 22 16:31:37 2002
--- krb5/appl/gssftp/ftpd/logwtmp.c	Sun Feb 24 22:56:42 2002
***************
*** 1,3 ****
--- 1,4 ----
+ #ifndef USE_PTY_LOGWTMP_FTPD
  /*
   * Copyright (c) 1988 The Regents of the University of California.
   * All rights reserved.
***************
*** 79,84 ****
--- 80,133 ----
  	if (fstat(fd, &buf) == 0) {
  		(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
  		(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
+ 
+ 		/*
+ 		 * Fill in as many fields as we can. Accounting on
+ 		 * some systems depends on this. The following code
+ 		 * was taken from util/pty/update_utmp.c and
+ 		 * update_wtmp.c
+ 		 */
+ #ifndef NO_UT_PID
+ 		if (!strcmp (line, "/dev/console")) {
+ #if defined(__sun) && defined(__SVR4)
+ 		    strncpy (ut.ut_id, "co", 2);
+ #else
+ 		    strncpy (ut.ut_id, "cons", 4);
+ #endif
+ 		} else {
+ 		    char *tmpx;
+ 		    char utmp_id[5];
+ 
+ 
+ 		    tmpx = line + strlen(line)-1;
+ 		    if (*(tmpx-1) != '/')
+ 			tmpx--; /* last two characters, unless it's a / */
+ #if defined(__hpux) || defined(__linux__)
+ 		    strcpy(utmp_id, tmpx);
+ #elif defined(sgi)
+ 		    /* Everything after '/dev/tty/' */
+ 		    strcpy(utmp_id, line + 8);   /* 8 == strlen("/dev/tty"); */
+ #else
+ 		    sprintf(utmp_id, "kl%s", tmpx);
+ #endif
+ 		    strncpy(ut.ut_id, utmp_id, sizeof(ut.ut_id));
+ 		}
+ #endif /* !NO_UT_PID */
+ 
+ 		(void)time(&ut.ut_time);
+ #ifndef NO_UT_PID
+ 		if (*name) {
+ 		    ut.ut_pid = getpid();
+ 		    ut.ut_type = USER_PROCESS;
+ 		} else {
+ #ifdef EMPTY
+ 		    ut.ut_type = EMPTY;
+ #else
+ 		    ut.ut_type = DEAD_PROCESS; /* For Linux brokenness*/
+ #endif	    
+ 		}
+ #endif /* ! NO_UT_PID */
+ 
  #ifndef NO_UT_HOST
  		(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
  #endif
***************
*** 88,90 ****
--- 137,140 ----
  			(void)ftruncate(fd, buf.st_size);
  	}
  }
+ #endif /* USE_PTY_LOGWTMP_FTPD */
Index: krb5/appl/sample/.cvsignore
diff -c /dev/null krb5/appl/sample/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:09 2003
--- krb5/appl/sample/.cvsignore	Thu Jun  5 10:38:18 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/sample/configure.in
diff -c krb5/appl/sample/configure.in:1.1.1.1 krb5/appl/sample/configure.in:removed
*** krb5/appl/sample/configure.in:1.1.1.1	Mon Jun  2 17:54:26 1997
--- krb5/appl/sample/configure.in	Sun Mar 16 20:22:09 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- CONFIG_DIRS(sclient sserver)
- DO_SUBDIRS
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/sample/sclient/.cvsignore
diff -c /dev/null krb5/appl/sample/sclient/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:09 2003
--- krb5/appl/sample/sclient/.cvsignore	Thu Jun  5 10:38:19 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/sample/sclient/configure.in
diff -c krb5/appl/sample/sclient/configure.in:1.1.1.1 krb5/appl/sample/sclient/configure.in:removed
*** krb5/appl/sample/sclient/configure.in:1.1.1.1	Mon Jun  2 17:54:27 1997
--- krb5/appl/sample/sclient/configure.in	Sun Mar 16 20:22:09 2003
***************
*** 1,7 ****
- AC_INIT(sclient.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_CHECK_HEADERS(stdlib.h)
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/sample/sserver/.cvsignore
diff -c /dev/null krb5/appl/sample/sserver/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:09 2003
--- krb5/appl/sample/sserver/.cvsignore	Thu Jun  5 10:38:20 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/sample/sserver/configure.in
diff -c krb5/appl/sample/sserver/configure.in:1.1.1.1 krb5/appl/sample/sserver/configure.in:removed
*** krb5/appl/sample/sserver/configure.in:1.1.1.1	Mon Jun  2 17:54:28 1997
--- krb5/appl/sample/sserver/configure.in	Sun Mar 16 20:22:09 2003
***************
*** 1,6 ****
- AC_INIT(sserver.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/simple/.cvsignore
diff -c /dev/null krb5/appl/simple/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:09 2003
--- krb5/appl/simple/.cvsignore	Thu Jun  5 10:38:21 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/simple/configure.in
diff -c krb5/appl/simple/configure.in:1.1.1.1 krb5/appl/simple/configure.in:removed
*** krb5/appl/simple/configure.in:1.1.1.1	Mon Jun  2 17:54:29 1997
--- krb5/appl/simple/configure.in	Sun Mar 16 20:22:09 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- CONFIG_DIRS(client server)
- DO_SUBDIRS
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/simple/client/.cvsignore
diff -c /dev/null krb5/appl/simple/client/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:10 2003
--- krb5/appl/simple/client/.cvsignore	Thu Jun  5 10:38:22 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/simple/client/configure.in
diff -c krb5/appl/simple/client/configure.in:1.1.1.1 krb5/appl/simple/client/configure.in:removed
*** krb5/appl/simple/client/configure.in:1.1.1.1	Mon Jun  2 17:54:34 1997
--- krb5/appl/simple/client/configure.in	Sun Mar 16 20:22:10 2003
***************
*** 1,10 ****
- AC_INIT(sim_client.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_CHECK_HEADERS(stdlib.h)
- if test "$ac_cv_lib_socket" = "yes" -a "$ac_cv_lib_nsl" = "yes"; then
- 	AC_DEFINE(BROKEN_STREAMS_SOCKETS)
- fi
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/simple/server/.cvsignore
diff -c /dev/null krb5/appl/simple/server/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:10 2003
--- krb5/appl/simple/server/.cvsignore	Thu Jun  5 10:38:23 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/simple/server/configure.in
diff -c krb5/appl/simple/server/configure.in:1.1.1.1 krb5/appl/simple/server/configure.in:removed
*** krb5/appl/simple/server/configure.in:1.1.1.1	Mon Jun  2 17:54:35 1997
--- krb5/appl/simple/server/configure.in	Sun Mar 16 20:22:10 2003
***************
*** 1,6 ****
- AC_INIT(sim_server.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/appl/telnet/.cvsignore
diff -c /dev/null krb5/appl/telnet/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:10 2003
--- krb5/appl/telnet/.cvsignore	Thu Jun  5 10:38:24 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/telnet/libtelnet/.cvsignore
diff -c /dev/null krb5/appl/telnet/libtelnet/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:10 2003
--- krb5/appl/telnet/libtelnet/.cvsignore	Thu Jun  5 10:38:25 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/telnet/libtelnet/auth.h
diff -c krb5/appl/telnet/libtelnet/auth.h:1.1.1.2 krb5/appl/telnet/libtelnet/auth.h:1.3
*** krb5/appl/telnet/libtelnet/auth.h:1.1.1.2	Fri Feb 22 16:31:52 2002
--- krb5/appl/telnet/libtelnet/auth.h	Mon Feb 25 02:16:43 2002
***************
*** 90,93 ****
--- 90,101 ----
  #define OPTS_FORWARDABLE_CREDS       0x00000001
  
  extern auth_debug_mode;
+ 
+ struct config_opts {
+ 	char	*optname;
+ 	int	*optvar;
+ };
+ 
+ void kerberos5_defaults P((struct config_opts *));
+ 
  #endif
Index: krb5/appl/telnet/libtelnet/kerberos.c
diff -c krb5/appl/telnet/libtelnet/kerberos.c:1.1.1.3 krb5/appl/telnet/libtelnet/kerberos.c:1.5
*** krb5/appl/telnet/libtelnet/kerberos.c:1.1.1.3	Mon Aug 12 15:44:15 2002
--- krb5/appl/telnet/libtelnet/kerberos.c	Mon Aug 12 15:55:18 2002
***************
*** 180,192 ****
  	Authenticator *ap;
  	int server;
  {
- 	FILE *fp;
- 
  	if (server) {
  		str_data[3] = TELQUAL_REPLY;
- 		if ((fp = fopen(KEYFILE, "r")) == NULL)
- 			return(0);
- 		fclose(fp);
  	} else {
  		str_data[3] = TELQUAL_IS;
  	}
--- 180,187 ----
***************
*** 614,621 ****
  		strncpy(name, UserNameRequested, 255);
  		name[255] = '\0';
  		return(AUTH_VALID);
! 	} else
  		return(AUTH_USER);
  }
  
  #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
--- 609,623 ----
  		strncpy(name, UserNameRequested, 255);
  		name[255] = '\0';
  		return(AUTH_VALID);
! 	} else {
! 		/*
! 		 * Always copy in UserNameRequested if the authentication
! 		 * is valid, because the higher level routines need it.
! 		 */
! 		if (UserNameRequested)
! 			strcpy(name, UserNameRequested);
  		return(AUTH_USER);
+ 	}
  }
  
  #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
Index: krb5/appl/telnet/libtelnet/kerberos5.c
diff -c krb5/appl/telnet/libtelnet/kerberos5.c:1.1.1.5 krb5/appl/telnet/libtelnet/kerberos5.c:1.11
*** krb5/appl/telnet/libtelnet/kerberos5.c:1.1.1.5	Mon Aug 12 15:44:16 2002
--- krb5/appl/telnet/libtelnet/kerberos5.c	Mon Jan 13 11:39:32 2003
***************
*** 126,131 ****
--- 126,132 ----
  krb5_keyblock	*session_key = 0;
  char *		telnet_srvtab = NULL;
  char *		telnet_krb5_realm = NULL;
+ int		require_hwpreauth = 0;
  
  	static int
  Data(ap, type, d, c)
***************
*** 195,207 ****
  {
      krb5_error_code retval;
      krb5_ccache ccache;
      char *ccname;
      
      if (telnet_context == 0)
  	return;
  
      ccname = getenv(KRB5_ENV_CCNAME);
!     if (ccname) {
  	retval = krb5_cc_resolve(telnet_context, ccname, &ccache);
  	if (!retval)
  	    retval = krb5_cc_destroy(telnet_context, ccache);
--- 196,216 ----
  {
      krb5_error_code retval;
      krb5_ccache ccache;
+     krb5_data realm;
      char *ccname;
+     int retain_ccache = 0;
      
      if (telnet_context == 0)
  	return;
  
+     krb5_get_default_realm(telnet_context, &realm.data);
+ 
+     krb5_appdefault_boolean(telnet_context, "telnetd", &realm,
+ 			    "retain_ccache", retain_ccache, &retain_ccache);
+     krb5_xfree(realm.data);
+ 
      ccname = getenv(KRB5_ENV_CCNAME);
!     if (ccname && ! retain_ccache) {
  	retval = krb5_cc_resolve(telnet_context, ccname, &ccache);
  	if (!retval)
  	    retval = krb5_cc_destroy(telnet_context, ccache);
***************
*** 232,238 ****
                  if (auth_debug_mode) {
                          printf(
  			"telnet: Kerberos V5: no user name supplied\r\n");
!                 }
                  return(0);
          }
  
--- 241,250 ----
                  if (auth_debug_mode) {
                          printf(
  			"telnet: Kerberos V5: no user name supplied\r\n");
!                 } else {
!                         printf(
! 			"[ Kerberos V5: no user name supplied ]\r\n");
! 		}
                  return(0);
          }
  
***************
*** 240,245 ****
--- 252,260 ----
  		if (auth_debug_mode) {
  		    printf(
  		    "telnet: Kerberos V5: could not get default ccache\r\n");
+ 		} else {
+ 		    printf(
+ 		    "[ Kerberos V5: could not get default ccache ]\r\n");
  		}
  		return(0);
  	}
***************
*** 250,255 ****
--- 265,272 ----
  					 &creds.server))) {
  	    if (auth_debug_mode)
  		printf("telnet: Kerberos V5: error while constructing service name: %s\r\n", error_message(r));
+ 	    else
+ 		printf("[ Kerberos V5: error while constructing service name: %s ]\r\n", error_message(r));
  	    return(0);
  	}
  
***************
*** 272,277 ****
--- 289,298 ----
  			printf(
  			"telnet: Kerberos V5: failure on principal (%s)\r\n",
  				error_message(r));
+ 		} else {
+ 			printf(
+ 			"[ Kerberos V5: failure on principal (%s) ]\r\n",
+ 				error_message(r));
  		}
  		krb5_free_cred_contents(telnet_context, &creds);
  		return(0);
***************
*** 284,289 ****
--- 305,314 ----
  			printf(
  			"telnet: Kerberos V5: failure on credentials(%s)\r\n",
  			       error_message(r));
+ 		} else {
+ 			printf(
+ 			"[ Kerberos V5: failure on credentials (%s) ]\r\n",
+ 			       error_message(r));
  		}
  		krb5_free_cred_contents(telnet_context, &creds);
  		return(0);
***************
*** 353,358 ****
--- 378,386 ----
  		if (auth_debug_mode) {
  			printf("telnet: Kerberos V5: mk_req failed (%s)\r\n",
  			       error_message(r));
+ 		} else {
+ 			printf("[ Kerberos V5: mk_req failed (%s) ]\r\n",
+ 			       error_message(r));
  		}
  		return(0);
  	}
***************
*** 533,538 ****
--- 561,579 ----
  				      ticket->enc_part2 ->client,
  				      &name))
  			name = 0;
+ 		
+ 		/*
+ 		 * Sigh, if we have the require_hwpreauth flag, then
+ 		 * reject this ticket if we don't have the hwpreauth
+ 		 * ticket flag set
+ 		 */
+ 		
+ 		if (require_hwpreauth && !(ticket->enc_part2->flags &
+ 					   TKT_FLG_HW_AUTH)) {
+ 			(void) strcpy(errbuf, "No hardware preauth flag set");
+ 			goto errout;
+ 		}
+ 
  		Data(ap, KRB_ACCEPT, name, name ? -1 : 0);
  		if (auth_debug_mode) {
  			printf(
***************
*** 729,736 ****
  		strncpy(name, UserNameRequested, 255);
  		name[255] = '\0';
  		return(AUTH_VALID);
! 	} else
  		return(AUTH_USER);
  }
  
  #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
--- 770,785 ----
  		strncpy(name, UserNameRequested, 255);
  		name[255] = '\0';
  		return(AUTH_VALID);
! 	} else {
! 		/*
! 		 * Always copy in UserNameRequested if the authentication
! 		 * is valid, because the higher level routines need it.
! 		 */
! 		if (UserNameRequested)
! 			strcpy(name, UserNameRequested);
! 
  		return(AUTH_USER);
+ 	}
  }
  
  #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
***************
*** 851,859 ****
  				server, ccache,
  				forward_flags & OPTS_FORWARDABLE_CREDS,
  				&forw_creds))) {
! 	if (auth_debug_mode) 
! 	    printf("Kerberos V5: error getting forwarded creds - %s\r\n",
! 	  	   error_message(r));
  	goto cleanup;
      }
      
--- 900,907 ----
  				server, ccache,
  				forward_flags & OPTS_FORWARDABLE_CREDS,
  				&forw_creds))) {
! 	printf("Kerberos V5: error getting forwarded creds - %s\r\n",
! 	       error_message(r));
  	goto cleanup;
      }
      
***************
*** 877,880 ****
--- 925,953 ----
  }
  #endif	/* FORWARD */
  
+ void
+ kerberos5_defaults(opts)
+ 	struct config_opts *opts;
+ {
+ 	struct config_opts *opt;
+ 	krb5_data realm;
+ 
+ 	if (!telnet_context) {
+ 		krb5_init_context(&telnet_context);
+ 		krb5_init_ets(telnet_context);
+ 	}
+ 
+ 	if (! telnet_krb5_realm) {
+ 		krb5_get_default_realm(telnet_context, &realm.data);
+ 	} else {
+ 		realm.data = strdup(telnet_krb5_realm);
+ 	}
+ 
+ 	for (opt = opts; opt->optname != 0; opt++)
+ 		krb5_appdefault_boolean(telnet_context, "telnet", &realm,
+ 					opt->optname, *(opt->optvar),
+ 					opt->optvar);
+ 
+ 	free(realm.data);
+ }
  #endif /* KRB5 */
Index: krb5/appl/telnet/telnet/.cvsignore
diff -c /dev/null krb5/appl/telnet/telnet/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:10 2003
--- krb5/appl/telnet/telnet/.cvsignore	Thu Jun  5 10:38:26 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/telnet/telnet/commands.c
diff -c krb5/appl/telnet/telnet/commands.c:1.1.1.2 krb5/appl/telnet/telnet/commands.c:1.5
*** krb5/appl/telnet/telnet/commands.c:1.1.1.2	Fri Feb 22 16:32:02 2002
--- krb5/appl/telnet/telnet/commands.c	Mon Feb 25 02:16:50 2002
***************
*** 1726,1743 ****
  	/*
  	 * Special case for DISPLAY variable.  If it is ":0.0" or
  	 * "unix:0.0", we have to get rid of "unix" and insert our
! 	 * hostname.
  	 */
  	if ((ep = env_find("DISPLAY"))
  	    && ((*ep->value == ':')
  	        || (strncmp((char *)ep->value, "unix:", 5) == 0))) {
  		char hbuf[256+1];
  		char *cp2 = strchr((char *)ep->value, ':');
  
  		gethostname(hbuf, 256);
  		hbuf[256] = '\0';
! 		cp = (char *)malloc(strlen(hbuf) + strlen(cp2) + 1);
! 		sprintf((char *)cp, "%s%s", hbuf, cp2);
  		free(ep->value);
  		ep->value = (unsigned char *)cp;
  	}
--- 1726,1746 ----
  	/*
  	 * Special case for DISPLAY variable.  If it is ":0.0" or
  	 * "unix:0.0", we have to get rid of "unix" and insert our
! 	 * hostname.  Make it a FQDN if possible.
  	 */
  	if ((ep = env_find("DISPLAY"))
  	    && ((*ep->value == ':')
  	        || (strncmp((char *)ep->value, "unix:", 5) == 0))) {
  		char hbuf[256+1];
+ 		struct hostent *hp;
  		char *cp2 = strchr((char *)ep->value, ':');
  
  		gethostname(hbuf, 256);
  		hbuf[256] = '\0';
! 		hp = gethostbyname(hbuf);
! 		cp = (char *)malloc(strlen(hp ? hp->h_name : hbuf) +
! 				    strlen(cp2) + 1);
! 		sprintf((char *)cp, "%s%s", hp ? hp->h_name : hbuf, cp2);
  		free(ep->value);
  		ep->value = (unsigned char *)cp;
  	}
***************
*** 2498,2514 ****
  	}
      } else {
  	if (sp == 0) {
! 	    sp = getservbyname("telnet", "tcp");
  	    if (sp == 0) {
! 		fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
  		return 0;
  	    }
! 	    sin.sin_port = sp->s_port;
  	}
  	telnetport = 1;
      }
-     printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr));
      do {
  	net = socket(AF_INET, SOCK_STREAM, 0);
  	if (net < 0) {
  	    perror("telnet: socket");
--- 2501,2525 ----
  	}
      } else {
  	if (sp == 0) {
! 	  {
! 	    char service_name[64];
! #if	defined(ALTTELNETPORT)
! 	    strncpy(service_name,ALTTELNETPORT,sizeof(service_name));
! #else
! 	    strncpy(service_name,"telnet",sizeof(service_name));
! #endif
! 	    sp = getservbyname(service_name, "tcp");
  	    if (sp == 0) {
! 		fprintf(stderr, "telnet: tcp/%s: unknown service\n",service_name);
  		return 0;
  	    }
! 	  }
! 	  sin.sin_port = sp->s_port;
  	}
  	telnetport = 1;
      }
      do {
+ 	printf("Trying %s...\r\n", inet_ntoa(sin.sin_addr));
  	net = socket(AF_INET, SOCK_STREAM, 0);
  	if (net < 0) {
  	    perror("telnet: socket");
Index: krb5/appl/telnet/telnet/configure.in
diff -c krb5/appl/telnet/telnet/configure.in:1.1.1.3 krb5/appl/telnet/telnet/configure.in:1.5
*** krb5/appl/telnet/telnet/configure.in:1.1.1.3	Fri Feb 22 16:32:02 2002
--- krb5/appl/telnet/telnet/configure.in	Mon Feb 25 02:16:50 2002
***************
*** 31,35 ****
--- 31,45 ----
  	AC_DEFINE(KRB4)
  fi
  dnl
+ dnl
+ dnl Was an alternate TELNET port specified?
+ AC_MSG_CHECKING([alternate TELNET service port])
+ alt_telnet_port=no
+ AC_ARG_WITH([telnet-service],[],alt_telnet_port=$withval)
+ if test $alt_telnet_port != no; then
+ 	AC_DEFINE_UNQUOTED(ALTTELNETPORT,"${alt_telnet_port}")
+ fi
+ AC_MSG_RESULT($alt_telnet_port)
+ dnl
  KRB5_BUILD_PROGRAM
  V5_AC_OUTPUT_MAKEFILE
Index: krb5/appl/telnet/telnet/externs.h
diff -c krb5/appl/telnet/telnet/externs.h:1.1.1.2 krb5/appl/telnet/telnet/externs.h:1.3
*** krb5/appl/telnet/telnet/externs.h:1.1.1.2	Fri Feb 22 16:32:03 2002
--- krb5/appl/telnet/telnet/externs.h	Mon Feb 25 02:16:50 2002
***************
*** 77,83 ****
  #if defined(USE_TERMIO) && !defined(SYSV_TERMIO)
  # define termio termios
  #endif
! #if defined(NO_CC_T) || !defined(USE_TERMIO)
  # if !defined(USE_TERMIO)
  typedef char cc_t;
  # else
--- 77,83 ----
  #if defined(USE_TERMIO) && !defined(SYSV_TERMIO)
  # define termio termios
  #endif
! #if defined(NO_CC_T)
  # if !defined(USE_TERMIO)
  typedef char cc_t;
  # else
Index: krb5/appl/telnet/telnet/main.c
diff -c krb5/appl/telnet/telnet/main.c:1.1.1.2 krb5/appl/telnet/telnet/main.c:1.6
*** krb5/appl/telnet/telnet/main.c:1.1.1.2	Fri Feb 22 16:32:04 2002
--- krb5/appl/telnet/telnet/main.c	Mon Feb 25 02:16:51 2002
***************
*** 48,53 ****
--- 48,54 ----
  #include "ring.h"
  #include "externs.h"
  #include "defines.h"
+ #include <libtelnet/auth.h>
  
  
  #if 0
***************
*** 103,108 ****
--- 104,123 ----
  	exit(1);
  }
  
+ #ifdef KRB5
+ static int forward = 0, forwardable = 0;
+ static int encrypt = 0, forceencrypt = 0;
+ 
+ static struct config_opts c_opts[] = {
+ 	"forward", &forward,
+ 	"forwardable", &forwardable,
+ 	"encrypt", &encrypt,
+ 	"autologin", &autologin,
+ 	"forceencrypt", &forceencrypt,
+ 	NULL, NULL,
+ };
+ #endif
+ 
  /*
   * main.  Parse arguments, invoke the protocol or command parser.
   */
***************
*** 110,115 ****
--- 125,131 ----
  /* see forward.c -- indicate that we're in telnet, not telnetd. */
  char *line = 0;
  
+ 
  main(argc, argv)
  	int argc;
  	char *argv[];
***************
*** 120,125 ****
--- 136,142 ----
  	char *user;
  #ifdef	FORWARD
  	extern int forward_flags;
+ 	int opt_forward = 0, opt_forwardable = 0;
  #endif	/* FORWARD */
  #ifdef ENCRYPTION
  	extern int auth_enable_encrypt;
***************
*** 142,148 ****
  	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
  	autologin = -1;
  
! 	while ((ch = getopt(argc, argv, "8EKLS:X:acde:fFk:l:n:rt:x")) != -1) {
  		switch(ch) {
  		case '8':
  			eight = 3;	/* binary output and input */
--- 159,173 ----
  	rlogin = (strncmp(prompt, "rlog", 4) == 0) ? '~' : _POSIX_VDISABLE;
  	autologin = -1;
  
! #ifdef KRB5
! 	/*
! 	 * Get the defaults from the Kerberos 5 profile, if we have one
! 	 */
! 	
! 	kerberos5_defaults(c_opts);
! #endif /* KRB5 */
! 
! 	while ((ch = getopt(argc, argv, "8EKLNS:X:acde:fFk:l:n:rt:x")) != -1) {
  		switch(ch) {
  		case '8':
  			eight = 3;	/* binary output and input */
***************
*** 158,163 ****
--- 183,198 ----
  		case 'L':
  			eight |= 2;	/* binary output only */
  			break;
+ 		case 'N':
+ #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+ 			opt_forward = forward = 0;
+ 			opt_forwardable = forwardable = 0;
+ #else
+ 			fprintf(stderr,
+ 			 "%s: Warning: -N ignored, no Kerberos V5 support.\n", 
+ 				prompt);
+ #endif
+ 		break;
  		case 'S':
  		    {
  #if defined(HAVE_GETTOSBYNAME) || (defined(IPPROTO_IP) && defined(IP_TOS))
***************
*** 196,208 ****
  			break;
  		case 'f':
  #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
! 			if (forward_flags & OPTS_FORWARD_CREDS) {
  			    fprintf(stderr, 
  				    "%s: Only one of -f and -F allowed.\n",
  				    prompt);
  			    usage();
  			}
! 			forward_flags |= OPTS_FORWARD_CREDS;
  #else
  			fprintf(stderr,
  			 "%s: Warning: -f ignored, no Kerberos V5 support.\n", 
--- 231,243 ----
  			break;
  		case 'f':
  #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
! 			if (opt_forwardable) {
  			    fprintf(stderr, 
  				    "%s: Only one of -f and -F allowed.\n",
  				    prompt);
  			    usage();
  			}
! 			opt_forward = 1;
  #else
  			fprintf(stderr,
  			 "%s: Warning: -f ignored, no Kerberos V5 support.\n", 
***************
*** 211,224 ****
  			break;
  		case 'F':
  #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
! 			if (forward_flags & OPTS_FORWARD_CREDS) {
  			    fprintf(stderr, 
  				    "%s: Only one of -f and -F allowed.\n",
  				    prompt);
  			    usage();
  			}
! 			forward_flags |= OPTS_FORWARD_CREDS;
! 			forward_flags |= OPTS_FORWARDABLE_CREDS;
  #else
  			fprintf(stderr,
  			 "%s: Warning: -F ignored, no Kerberos V5 support.\n", 
--- 246,258 ----
  			break;
  		case 'F':
  #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
! 			if (opt_forward) {
  			    fprintf(stderr, 
  				    "%s: Only one of -f and -F allowed.\n",
  				    prompt);
  			    usage();
  			}
! 			opt_forwardable = 1;
  #else
  			fprintf(stderr,
  			 "%s: Warning: -F ignored, no Kerberos V5 support.\n", 
***************
*** 284,298 ****
  			break;
  		case 'x':
  #ifdef	ENCRYPTION
! 			encrypt_auto(1);
! 			decrypt_auto(1);
! 			wantencryption = 1;
! 			autologin = 1;
! 			auth_enable_encrypt = 1;
  #else
  			fprintf(stderr,
! 			    "%s: Warning: -x ignored, no ENCRYPT support.\n",
  								prompt);
  #endif
  			break;
  		case '?':
--- 318,330 ----
  			break;
  		case 'x':
  #ifdef	ENCRYPTION
! 			encrypt = 1;
! 			forceencrypt = 1;
  #else
  			fprintf(stderr,
! 			    "%s: encryption not supported.\n",
  								prompt);
+ 			exit(1);
  #endif
  			break;
  		case '?':
***************
*** 301,306 ****
--- 333,360 ----
  			/* NOTREACHED */
  		}
  	}
+ 
+ #if defined(AUTHENTICATION) && defined(KRB5) && defined(FORWARD)
+ 	if (opt_forward || forward) {
+ 		forward_flags |= OPTS_FORWARD_CREDS;
+ 	}
+ 	if (opt_forwardable || forwardable) {
+ 		forward_flags |= OPTS_FORWARD_CREDS;
+ 		forward_flags |= OPTS_FORWARDABLE_CREDS;
+ 	}
+ #endif /* AUTH and KRB5 and FORWARD */
+ 
+ #ifdef  ENCRYPTION
+ 	if (encrypt) {
+ 		encrypt_auto(1);
+ 		decrypt_auto(1);
+ 		if (forceencrypt)
+ 			wantencryption = 1;
+ 		autologin = 1;
+ 		auth_enable_encrypt = 1;
+ 	}
+ #endif
+ 
  	if (autologin == -1)
  		autologin = (rlogin == _POSIX_VDISABLE) ? 0 : 1;
  
Index: krb5/appl/telnet/telnet/telnet.c
diff -c krb5/appl/telnet/telnet/telnet.c:1.1.1.2 krb5/appl/telnet/telnet/telnet.c:1.3
*** krb5/appl/telnet/telnet/telnet.c:1.1.1.2	Fri Feb 22 16:32:06 2002
--- krb5/appl/telnet/telnet/telnet.c	Mon Feb 25 02:16:51 2002
***************
*** 2271,2287 ****
      }
  #endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION)  */
  #   if !defined(TN3270)
  #if	defined(AUTHENTICATION)
!     if (autologin)
! 	send_will(TELOPT_AUTHENTICATION, 1);
  #endif
  #ifdef	ENCRYPTION
-     if (telnetport || wantencryption) {
  	send_do(TELOPT_ENCRYPT, 1);
  	send_will(TELOPT_ENCRYPT, 1);
-     }
  #endif	/* ENCRYPTION */
-     if (telnetport) {
  	send_do(TELOPT_SGA, 1);
  	send_will(TELOPT_TTYPE, 1);
  	send_will(TELOPT_NAWS, 1);
--- 2271,2285 ----
      }
  #endif	/* defined(AUTHENTICATION) || defined(ENCRYPTION)  */
  #   if !defined(TN3270)
+     if (telnetport) {
  #if	defined(AUTHENTICATION)
! 	if (autologin)
! 	    send_will(TELOPT_AUTHENTICATION, 1);
  #endif
  #ifdef	ENCRYPTION
  	send_do(TELOPT_ENCRYPT, 1);
  	send_will(TELOPT_ENCRYPT, 1);
  #endif	/* ENCRYPTION */
  	send_do(TELOPT_SGA, 1);
  	send_will(TELOPT_TTYPE, 1);
  	send_will(TELOPT_NAWS, 1);
***************
*** 2308,2313 ****
--- 2306,2313 ----
  	extern int auth_has_failed;
  	time_t timeout = time(0) + 60;
  
+ 	if (my_want_state_is_wont(TELOPT_AUTHENTICATION))
+ 		send_will(TELOPT_AUTHENTICATION, 1);
  	send_do(TELOPT_ENCRYPT, 1);
  	send_will(TELOPT_ENCRYPT, 1);
  	while (1) {
Index: krb5/appl/telnet/telnetd/.cvsignore
diff -c /dev/null krb5/appl/telnet/telnetd/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:11 2003
--- krb5/appl/telnet/telnetd/.cvsignore	Thu Jun  5 10:38:28 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/telnet/telnetd/sys_term.c
diff -c krb5/appl/telnet/telnetd/sys_term.c:1.1.1.4 krb5/appl/telnet/telnetd/sys_term.c:1.4
*** krb5/appl/telnet/telnetd/sys_term.c:1.1.1.4	Fri Feb 22 16:32:11 2002
--- krb5/appl/telnet/telnetd/sys_term.c	Mon Feb 25 02:16:53 2002
***************
*** 1081,1086 ****
--- 1081,1088 ----
  		autologin = 0;
  
  	if (autologin < auth_level) {
+ 		syslog(LOG_ERR,
+ 		       "Rejected connection that lacked needed preauthentication");
  		fatal(net, "Authorization failed");
  		exit(1);
  	}
Index: krb5/appl/telnet/telnetd/telnetd.8
diff -c krb5/appl/telnet/telnetd/telnetd.8:1.1.1.2 krb5/appl/telnet/telnetd/telnetd.8:1.4
*** krb5/appl/telnet/telnetd/telnetd.8:1.1.1.2	Wed May 12 13:21:37 1999
--- krb5/appl/telnet/telnetd/telnetd.8	Wed May 12 14:55:53 1999
***************
*** 40,45 ****
--- 40,46 ----
  .B /usr/libexec/telnetd
  [\fB\-a\fP \fIauthmode\fP] [\fB\-B\fP] [\fB\-D\fP] [\fIdebugmode\fP]
  [\fB\-edebug\fP] [\fB\-h\fP] [\fB\-I\fP\fIinitid\fP] [\fB\-l\fP]
+ [\fB\-L\fP \fIlogin_program\fP]
  [\fB\-k\fP] [\fB\-n\fP] [\fB\-r\fP\fIlowpty-highpty\fP] [\fB\-s\fP]
  [\fB\-S\fP \fItos\fP] [\fB\-U\fP] [\fB\-X\fP \fIauthtype\fP]
  [\fB\-w\fP [\fBip\fP|\fImaxhostlen\fP[\fB,\fP[\fBno\fP]\fBstriplocal\fP]]]
***************
*** 92,103 ****
  .B debug
  Turns on authentication debugging code.
  .TP
! .B user
  Only allow connections when the remote user can provide valid
  authentication information to identify the remote user, and is allowed
  access to the specified account without providing a password.
  .TP
! .B valid
  Only allow connections when the remote user can provide valid
  authentication information to identify the remote user.  The
  .IR login (1)
--- 93,104 ----
  .B debug
  Turns on authentication debugging code.
  .TP
! .B valid
  Only allow connections when the remote user can provide valid
  authentication information to identify the remote user, and is allowed
  access to the specified account without providing a password.
  .TP
! .B user
  Only allow connections when the remote user can provide valid
  authentication information to identify the remote user.  The
  .IR login (1)
***************
*** 227,232 ****
--- 228,236 ----
  mode.  If the
  .SM LINEMODE
  option is not supported, it will go into kludge linemode.
+ .TP
+ \fB\-L\fP \fIlogin_program\fP
+ This options allows specification of the login program to run.
  .TP
  .B \-n
  Disable
Index: krb5/appl/telnet/telnetd/telnetd.c
diff -c krb5/appl/telnet/telnetd/telnetd.c:1.1.1.5 krb5/appl/telnet/telnetd/telnetd.c:1.5
*** krb5/appl/telnet/telnetd/telnetd.c:1.1.1.5	Fri Feb 22 16:32:13 2002
--- krb5/appl/telnet/telnetd/telnetd.c	Mon Feb 25 02:16:54 2002
***************
*** 179,185 ****
  	's',
  #endif
  #ifdef KRB5
! 	'R', ':', 't', ':',
  #endif
  	'\0'
  };
--- 179,185 ----
  	's',
  #endif
  #ifdef KRB5
! 	'R', ':', 't', ':', 'H',
  #endif
  	'\0'
  };
***************
*** 319,324 ****
--- 319,334 ----
  		case 'h':
  			hostinfo = 0;
  			break;
+ 
+ #ifdef KRB5
+ 		case 'H':
+ 		    {
+ 			extern int require_hwpreauth;
+ 
+ 			require_hwpreauth = 1;
+ 			break;
+ 		    }
+ #endif /* KRB5 */
  
  #if	defined(CRAY) && defined(NEWINIT)
  		case 'I':
Index: krb5/appl/telnet/telnetd/termios-tn.c
diff -c krb5/appl/telnet/telnetd/termios-tn.c:1.1.1.2 krb5/appl/telnet/telnetd/termios-tn.c:1.3
*** krb5/appl/telnet/telnetd/termios-tn.c:1.1.1.2	Wed May 12 13:21:39 1999
--- krb5/appl/telnet/telnetd/termios-tn.c	Wed May 12 14:55:53 1999
***************
*** 5,11 ****
  #include <sys/stream.h>
  #include <sys/ioctl.h>
  #include <termios.h>
! #if !defined(TCSETS) && defined(_AIX) /* kludge for AIX */
  #include <termio.h>
  #endif
  
--- 5,11 ----
  #include <sys/stream.h>
  #include <sys/ioctl.h>
  #include <termios.h>
! #if defined(HAVE_SYS_TERMIO_H) || (!defined(TCSETS) && defined(_AIX))
  #include <termio.h>
  #endif
  
Index: krb5/appl/telnet/telnetd/utility.c
diff -c krb5/appl/telnet/telnetd/utility.c:1.1.1.2 krb5/appl/telnet/telnetd/utility.c:1.5
*** krb5/appl/telnet/telnetd/utility.c:1.1.1.2	Fri Feb 22 16:32:14 2002
--- krb5/appl/telnet/telnetd/utility.c	Mon Feb 25 02:16:54 2002
***************
*** 466,472 ****
  	int f;
  	const char *msg;
  {
! 	char buf[BUFSIZ], *strerror();
  
  	(void) sprintf(buf, "%s: %s\r\n", msg, strerror(errno));
  	fatal(f, buf);
--- 466,476 ----
  	int f;
  	const char *msg;
  {
! 	char buf[BUFSIZ];
! #ifndef __convex__
! 	/* strerror() is a macro under ConvexOS */
! 	char *strerror();
! #endif /* __convex__*/
  
  	(void) sprintf(buf, "%s: %s\r\n", msg, strerror(errno));
  	fatal(f, buf);
Index: krb5/appl/user_user/.cvsignore
diff -c /dev/null krb5/appl/user_user/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:11 2003
--- krb5/appl/user_user/.cvsignore	Thu Jun  5 10:38:29 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/appl/user_user/configure.in
diff -c krb5/appl/user_user/configure.in:1.1.1.1 krb5/appl/user_user/configure.in:removed
*** krb5/appl/user_user/configure.in:1.1.1.1	Mon Jun  2 17:54:48 1997
--- krb5/appl/user_user/configure.in	Sun Mar 16 20:22:11 2003
***************
*** 1,6 ****
- AC_INIT(client.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/clients/.cvsignore
diff -c /dev/null krb5/clients/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:12 2003
--- krb5/clients/.cvsignore	Thu Jun  5 10:38:30 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/clients/configure.in
diff -c krb5/clients/configure.in:1.1.1.2 krb5/clients/configure.in:1.2
*** krb5/clients/configure.in:1.1.1.2	Fri Feb 22 16:32:27 2002
--- krb5/clients/configure.in	Thu Aug 29 14:19:44 2002
***************
*** 11,16 ****
--- 11,25 ----
    SETENVOBJ=
  fi
  AC_SUBST(SETENVOBJ)
+ AC_ARG_ENABLE([krb4-compat],
+ [  --enable-krb4-compat    Enable automatic client V4 compatibility (default)
+   --disable-krb4-compat   Disable automatic client V4 compatibility],
+ , enableval=yes
+ )dnl
+ if test $enableval = no; then
+ 	AC_MSG_RESULT(Disabling automatic client V4 compatibility)
+ 	AC_DEFINE(OMIT_KRB4_COMPAT)
+ fi
  AC_CHECK_HEADERS(unistd.h pwd.h arpa/inet.h)
  case $krb5_cv_host in
  alpha*-dec-osf*)
Index: krb5/clients/kdestroy/.cvsignore
diff -c /dev/null krb5/clients/kdestroy/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:12 2003
--- krb5/clients/kdestroy/.cvsignore	Thu Jun  5 10:38:31 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/clients/kdestroy/configure.in
diff -c krb5/clients/kdestroy/configure.in:1.1.1.1 krb5/clients/kdestroy/configure.in:removed
*** krb5/clients/kdestroy/configure.in:1.1.1.1	Mon Jun  2 17:54:53 1997
--- krb5/clients/kdestroy/configure.in	Sun Mar 16 20:22:12 2003
***************
*** 1,6 ****
- AC_INIT(kdestroy.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/clients/kinit/.cvsignore
diff -c /dev/null krb5/clients/kinit/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:12 2003
--- krb5/clients/kinit/.cvsignore	Thu Jun  5 10:38:32 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/clients/kinit/Makefile.in
diff -c krb5/clients/kinit/Makefile.in:1.1.1.2 krb5/clients/kinit/Makefile.in:1.3
*** krb5/clients/kinit/Makefile.in:1.1.1.2	Fri Feb 22 16:32:29 2002
--- krb5/clients/kinit/Makefile.in	Mon Feb 25 01:36:47 2002
***************
*** 3,8 ****
--- 3,10 ----
  mydir=kinit
  BUILDTOP=$(REL)$(U)$(S)$(U)
  
+ DEFINES= -DKPROGDIR=\"$(CLIENT_BINDIR)\"
+ 
  PROG_LIBPATH=-L$(TOPLIBD)
  PROG_RPATH=$(KRB5_LIBDIR)
  
Index: krb5/clients/kinit/configure.in
diff -c krb5/clients/kinit/configure.in:1.1.1.1 krb5/clients/kinit/configure.in:removed
*** krb5/clients/kinit/configure.in:1.1.1.1	Mon Jun  2 17:54:53 1997
--- krb5/clients/kinit/configure.in	Sun Mar 16 20:22:12 2003
***************
*** 1,7 ****
- AC_INIT(kinit.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_HAVE_HEADERS(pwd.h)
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/clients/kinit/kinit.c
diff -c krb5/clients/kinit/kinit.c:1.1.1.2 krb5/clients/kinit/kinit.c:1.11
*** krb5/clients/kinit/kinit.c:1.1.1.2	Fri Feb 22 16:32:30 2002
--- krb5/clients/kinit/kinit.c	Thu Aug 29 14:19:49 2002
***************
*** 37,42 ****
--- 37,43 ----
  #include <string.h>
  #include <stdio.h>
  #include <time.h>
+ #include <sys/stat.h>
  
  #ifdef GETOPT_LONG
  #include <getopt.h>
***************
*** 126,135 ****
--- 127,139 ----
      int forwardable;
      int proxiable;
      int addresses;
+     int run_aklog;
  
      int not_forwardable;
      int not_proxiable;
      int no_addresses;
+     int no_run_aklog;
+     int hw_auth;
  
      int verbose;
  
***************
*** 174,179 ****
--- 178,185 ----
      { "forwardable", 0, NULL, 'f' },
      { "proxiable", 0, NULL, 'p' },
      { "noaddresses", 0, NULL, 'A' },
+     { "aklog", 0, NULL, 'g' },
+     { "noaklog", 0, NULL, 'G' },
      { NULL, 0, NULL, 0 }
  };
  
***************
*** 191,201 ****
--- 197,209 ----
  #define USAGE_LONG_FORWARDABLE " | --forwardable | --noforwardable"
  #define USAGE_LONG_PROXIABLE   " | --proxiable | --noproxiable"
  #define USAGE_LONG_ADDRESSES   " | --addresses | --noaddresses"
+ #define USAGE_LONG_AKLOG       " | --aklog | --noaklog"
  #define USAGE_BREAK_LONG       USAGE_BREAK
  #else
  #define USAGE_LONG_FORWARDABLE ""
  #define USAGE_LONG_PROXIABLE   ""
  #define USAGE_LONG_ADDRESSES   ""
+ #define USAGE_LONG_AKLOG       ""
  #define USAGE_BREAK_LONG       ""
  #endif
  
***************
*** 208,215 ****
  	    "[-p | -P" USAGE_LONG_PROXIABLE "] "
  	    USAGE_BREAK_LONG
  	    "[-A" USAGE_LONG_ADDRESSES "] "
  	    USAGE_BREAK
! 	    "[-v] [-R] "
  	    "[-k [-t keytab_file]] "
  	    USAGE_BREAK
  	    "[-c cachename] "
--- 216,225 ----
  	    "[-p | -P" USAGE_LONG_PROXIABLE "] "
  	    USAGE_BREAK_LONG
  	    "[-A" USAGE_LONG_ADDRESSES "] "
+ 	    USAGE_BREAK_LONG
+ 	    "[-g | -G" USAGE_LONG_AKLOG "] "
  	    USAGE_BREAK
! 	    "[-v] [-R] [-h] "
  	    "[-k [-t keytab_file]] "
  	    USAGE_BREAK
  	    "[-c cachename] "
***************
*** 255,261 ****
--- 265,274 ----
      ULINE("\t", "-P not proxiable",             OPTTYPE_KRB5);
      ULINE("\t", "-A do not include addresses",  OPTTYPE_KRB5);
      ULINE("\t", "-v validate",                  OPTTYPE_KRB5);
+     ULINE("\t", "-g run aklog",			OPTTYPE_KRB5);
+     ULINE("\t", "-G do not run aklog",		OPTTYPE_KRB5);
      ULINE("\t", "-R renew",                     OPTTYPE_BOTH);
+     ULINE("\t", "-h request hardware preauth",	OPTTYPE_KRB5);
      ULINE("\t", "-k use keytab",                OPTTYPE_BOTH);
      ULINE("\t", "-t filename of keytab to use", OPTTYPE_BOTH);
      ULINE("\t", "-c Kerberos 5 cache name",     OPTTYPE_KRB5);
***************
*** 277,283 ****
      int use_k5 = 0;
      int i;
  
!     while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RS:v"))
  	   != -1) {
  	switch (i) {
  	case 'V':
--- 290,296 ----
      int use_k5 = 0;
      int i;
  
!     while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RhgGS:v"))
  	   != -1) {
  	switch (i) {
  	case 'V':
***************
*** 347,352 ****
--- 360,368 ----
  		opts->keytab_name = optarg;
  	    }
  	    break;
+ 	case 'h':
+ 	    opts->hw_auth = 1;
+ 	    break;
  	case 'R':
  	    opts->action = RENEW;
  	    break;
***************
*** 362,367 ****
--- 378,389 ----
  		opts->k5_cache_name = optarg;
  	    }
  	    break;
+ 	case 'g':
+ 	    opts->run_aklog = 1;
+ 	    break;
+ 	case 'G':
+ 	    opts->no_run_aklog = 1;
+ 	    break;
  #if 0
  	    /*
  	      A little more work is needed before we can enable this
***************
*** 403,408 ****
--- 425,440 ----
  	}
      }
  
+     if (opts->run_aklog && opts->no_run_aklog) {
+ 	fprintf(stderr, "Cannot use both -g and -G.\n");
+ 	errflg++;
+     }
+ 
+     if (opts->run_aklog && opts->starttime) {
+ 	fprintf(stderr, "Cannout use both -g and -s.\n");
+ 	errflg++;
+     }
+ 
      if (opts->forwardable && opts->not_forwardable)
      {
  	fprintf(stderr, "Only one of -f and -F allowed\n");
***************
*** 738,743 ****
--- 770,802 ----
        initialized.
      */
  
+     if (opts->lifetime == 0) {
+ 	/*
+ 	 * If we weren't given a lifetime on the command line, get the
+ 	 * one out of appdefaults
+ 	 */
+ 	
+ 	char *lifetime = NULL;
+ 
+ 	krb5_appdefault_string(k5->ctx, "kinit",
+ 			       krb5_princ_realm(k5->ctx, k5->me),
+ 			       "default_lifetime", "", &lifetime);
+ 	
+ 	if (lifetime && *lifetime)
+ 	    krb5_string_to_deltat(lifetime, &opts->lifetime);
+     }
+ 
+     if (opts->forwardable == 0 && opts->not_forwardable == 0) {
+ 	/*
+ 	 * If we weren't given an option, then check for it in appdefaults
+ 	 */
+ 	
+ 	krb5_appdefault_boolean(k5->ctx, "kinit",
+ 				krb5_princ_realm(k5->ctx, k5->me),
+ 				"forwardable", opts->forwardable,
+ 				&opts->forwardable);
+     }
+ 
      if (opts->lifetime)
  	krb5_get_init_creds_opt_set_tkt_life(&options, opts->lifetime);
      if (opts->rlife)
***************
*** 763,768 ****
--- 822,829 ----
      }
      if (opts->no_addresses)
  	krb5_get_init_creds_opt_set_address_list(&options, NULL);
+     if (opts->hw_auth)
+ 	options.flags |= KRB5_GET_INIT_CREDS_OPT_HW_AUTH;
  
      if ((opts->action == INIT_KT) && opts->keytab_name)
      {
***************
*** 846,851 ****
--- 907,940 ----
      }
  
      notix = 0;
+ 
+     /* Should we run aklog? */
+ 
+     if (!opts->run_aklog && !opts->no_run_aklog) {
+ 	krb5_appdefault_boolean(k5->ctx, "kinit",
+ 				krb5_princ_realm(k5->ctx, k5->me),
+ 				"krb5_run_aklog", 0, &opts->run_aklog);
+     }
+ 
+     if (opts->run_aklog && !opts->no_run_aklog) {
+ 	char *aklog_path;
+ 	struct stat st;
+ 
+ 	krb5_appdefault_string(k5->ctx, "kinit",
+ 			       krb5_princ_realm(k5->ctx, k5->me),
+ 			       "krb5_aklog_path", KPROGDIR "/aklog",
+ 			       &aklog_path);
+ 	
+ 	/*
+ 	 * Make sure it exists before we try to run it
+ 	 */
+ 
+ 	if (stat(aklog_path, &st) == 0) {
+ 	    system(aklog_path);
+ 	} 
+ 
+ 	free(aklog_path);
+     }
  
   cleanup:
      if (my_creds.client == k5->me) {
Index: krb5/clients/klist/.cvsignore
diff -c /dev/null krb5/clients/klist/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:12 2003
--- krb5/clients/klist/.cvsignore	Thu Jun  5 10:38:34 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/clients/klist/configure.in
diff -c krb5/clients/klist/configure.in:1.1.1.1 krb5/clients/klist/configure.in:removed
*** krb5/clients/klist/configure.in:1.1.1.1	Mon Jun  2 17:54:54 1997
--- krb5/clients/klist/configure.in	Sun Mar 16 20:22:12 2003
***************
*** 1,6 ****
- AC_INIT(klist.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/clients/klist/klist.c
diff -c krb5/clients/klist/klist.c:1.1.1.2 krb5/clients/klist/klist.c:1.4
*** krb5/clients/klist/klist.c:1.1.1.2	Fri Feb 22 16:32:31 2002
--- krb5/clients/klist/klist.c	Thu Aug 29 14:19:53 2002
***************
*** 93,99 ****
  static int got_k4 = 0;
  
  static int default_k5 = 1;
! #ifdef KRB5_KRB4_COMPAT
  static int default_k4 = 1;
  #else
  static int default_k4 = 0;
--- 93,99 ----
  static int got_k4 = 0;
  
  static int default_k5 = 1;
! #if defined(KRB5_KRB4_COMPAT) && !defined(OMIT_KRB4_COMPAT)
  static int default_k4 = 1;
  #else
  static int default_k4 = 0;
Index: krb5/clients/kpasswd/kpasswd.M
diff -c krb5/clients/kpasswd/kpasswd.M:1.1.1.1 krb5/clients/kpasswd/kpasswd.M:1.2
*** krb5/clients/kpasswd/kpasswd.M:1.1.1.1	Fri Feb 22 16:32:32 2002
--- krb5/clients/kpasswd/kpasswd.M	Mon Mar 10 15:25:21 2003
***************
*** 21,27 ****
  .\" this software for any purpose.  It is provided "as is" without express
  .\" or implied warranty.
  .\" "
! .so man1/header.doc
  .TH KPASSWD 1 \*h
  .SH NAME
  kpasswd \- change a user's Kerberos password
--- 21,27 ----
  .\" this software for any purpose.  It is provided "as is" without express
  .\" or implied warranty.
  .\" "
! .so man1/tmac.doc
  .TH KPASSWD 1 \*h
  .SH NAME
  kpasswd \- change a user's Kerberos password
Index: krb5/clients/ksu/.cvsignore
diff -c /dev/null krb5/clients/ksu/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:12 2003
--- krb5/clients/ksu/.cvsignore	Thu Jun  5 10:38:35 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/clients/ksu/configure.in
diff -c krb5/clients/ksu/configure.in:1.1.1.2 krb5/clients/ksu/configure.in:removed
*** krb5/clients/ksu/configure.in:1.1.1.2	Wed May 12 13:21:51 1999
--- krb5/clients/ksu/configure.in	Sun Mar 16 20:22:12 2003
***************
*** 1,20 ****
- AC_INIT(krb_auth_su.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- USE_ANAME
- AC_HEADER_STDARG
- AC_CHECK_FUNCS(getusershell lstat )
- AC_CHECK_HEADERS(unistd.h)
- case $krb5_cv_host in
- alpha-dec-osf*)
- 	AC_CHECK_LIB(security,setluid,
- 		AC_DEFINE(HAVE_SETLUID)
- 		KSU_LIBS="$KSU_LIBS -lsecurity"
- 	)
- 	;;
- esac
- AC_SUBST(KSU_LIBS)
- USE_KRB5UTIL_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/clients/ksu/krb_auth_su.c
diff -c krb5/clients/ksu/krb_auth_su.c:1.1.1.3 krb5/clients/ksu/krb_auth_su.c:1.3
*** krb5/clients/ksu/krb_auth_su.c:1.1.1.3	Fri Feb 22 16:32:38 2002
--- krb5/clients/ksu/krb_auth_su.c	Sun Feb 24 20:42:12 2002
***************
*** 345,358 ****
  
  	/* Check to make sure ticket hasn't expired */
  	if (retval = krb5_check_exp(context, tkt->enc_part2->times)) {
! 		if (auth_debug && (retval == KRB5KRB_AP_ERR_TKT_EXPIRED)) {
! 			fprintf(stderr,
! 				"krb5_verify_tkt_def: ticket has expired");
! 		}
! 		krb5_free_ticket(context, tkt);	
! 		krb5_kt_free_entry(context, &ktentry);
! 		krb5_free_keyblock(context, tkt_key);
! 		return KRB5KRB_AP_ERR_TKT_EXPIRED;
  	}
  
  	if (!krb5_principal_compare(context, client, tkt->enc_part2->client)) {
--- 345,358 ----
  
  	/* Check to make sure ticket hasn't expired */
  	if (retval = krb5_check_exp(context, tkt->enc_part2->times)) {
! 	    if (auth_debug && (retval == KRB5KRB_AP_ERR_TKT_EXPIRED)) {
! 		fprintf(stderr,
! 			"krb5_verify_tkt_def: ticket has expired");
! 	    }
! 	    krb5_free_ticket(context, tkt);	
! 	    krb5_kt_free_entry(context, &ktentry);
! 	    krb5_free_keyblock(context, tkt_key);
! 	    return KRB5KRB_AP_ERR_TKT_EXPIRED;
  	}
  
  	if (!krb5_principal_compare(context, client, tkt->enc_part2->client)) {
Index: krb5/clients/ksu/main.c
diff -c krb5/clients/ksu/main.c:1.1.1.3 krb5/clients/ksu/main.c:1.5
*** krb5/clients/ksu/main.c:1.1.1.3	Fri Feb 22 16:32:39 2002
--- krb5/clients/ksu/main.c	Sun Feb 24 20:42:13 2002
***************
*** 729,734 ****
--- 729,744 ----
  	        exit(1);
  	}
  
+ #ifdef IRIX_PROJECT_INIT
+        /*
+ 	* Initialize the magical IRIX array session, and the
+ 	* default project id.
+ 	*/
+ 	
+        newarraysess();
+        setprid(getdfltprojuser(target_user));
+ #endif /* IRIX_PROJECT_INIT */
+ 
         if ( ! strcmp(target_user, source_user)){ 			
         		print_status("Leaving uid as %s (%d)\n",
  				 target_user, target_pwd->pw_uid); 
***************
*** 869,874 ****
--- 879,885 ----
      char *name;
      char *value;
  {
+ #ifdef HAVE_PUTENV
  char * env_var_buf;
  
  	/* allocate extra two spaces, one for the = and one for the \0 */  
***************
*** 876,882 ****
--- 887,898 ----
  					sizeof(char)); 
  
          sprintf(env_var_buf,"%s=%s",name, value);  
+ 
          return putenv(env_var_buf);
+ #else
+ 	/* Assume we have setenv() */
+ 	return setenv(name, value, 1);
+ #endif
  
  }
  
Index: krb5/config/windows.in
diff -c krb5/config/windows.in:1.1.1.1 krb5/config/windows.in:removed
*** krb5/config/windows.in:1.1.1.1	Mon Jun  2 17:54:55 1997
--- krb5/config/windows.in	Sun Mar 16 20:22:13 2003
***************
*** 1,84 ****
- # Microsoft Windows configuration file for Cygnus Kerberos
- # ***copy from K4***
- 
- WHAT=windows
- 
- all:: all-$(WHAT)
- 
- clean:: clean-$(WHAT)
- 
- install:: install-$(WHAT)
- 
- check:: check-$(WHAT)
- 
- all-windiws::
- clean-windows::
- install-windows::
- check-windows::
- 
- 
- # Directory syntax:
- R=\		# root
- C=.\		# current
- S=\		# seperator
- U=..\		# up one level
- 
- srcdir = .
- SRCTOP = $(srcdir)/$(BUILDTOP)
- 
- # /* The name of the C compiler for the target */
- CC=cl /nologo
- CL=
- #
- # CCOPTS for DLL functions
- #
- ##WIN16##CCOPTS=/ALw /Zp /GD2s /Os /Zi /Od /W3 $(XTRA)
- ##WIN32##CCOPTS=/Os /Zi /Od /W3 $(XTRA) -DKRB5_DLL_FILE
- #
- # CCOPTS for non-DLL compiles
- #
- ##WIN16##CCOPTS2=/AL /Zp /G2s  /Os /Zi /Od /W3 -DINTERFACE= -DINTERFACE_C= $(XTRA)
- ##WIN32##CCOPTS2=/Os /Zi /Od /W3 -DINTERFACE= -DINTERFACE_C= $(XTRA)
- CPPFLAGS =  -I$(SRCTOP)/include -I$(SRCTOP)/include/krb5
- DEFS = $(CPPFLAGS)
- CFLAGS2 = $(CCOPTS2) $(DEFS)
- 
- # /Zi gives debug info in each object file.
- # /Zp packs structures: Required for Windows API (but is not default!!!)
- # /Za strict ansi compliance
- # /ALw memory model:  Large model for Windows DLL (SS != DS)
- # /GD DLL code generation for Windows 3.0 and up, and defines _WINDOWS
- # /Gs Avoid stack probes (they don't seem to work anyway)
- # /Os optimize for space.  FIXME:  Do not use /Ox; it miscompiles the DES lib!
- # /G2 generate 286 instructions (it complains if you ask for 386!)
- # /Od disable optimization (for debugging)
- 
- DBG_LIB=/nologo /Zp /ALw /GD /Gs /Os /G2 /Zi /Od
- # /Zi gives debug info in each object file.
- # /Zp packs structures: Required for Windows API (but is not default!!!)
- # /AL large memory model
- # /Mq quickwin ascii stdio window, and defines _WINDOWS
- DBG=/nologo /Zp /AL /Os /Mq /Zi /Od
- 
- RM=$(BUILDTOP)\config\rm.bat
- CP=copy
- MV=ren
- LN=copy
- LIBCMD=lib
- PAGESIZE=/pagesize:128
- AWK=rem
- 
- ARADD=rem
- RANLIB=rem
- ARCHIVE=rem
- 
- LIBEXT=lib
- OBJEXT=obj
- EXEEXT=.exe
- 
- MFLAGS=$(MAKEFLAGS)
- 
- #
- # End of Microsoft Windows config lines
- #
- 
--- 0 ----
Index: krb5/config-files/.cvsignore
diff -c /dev/null krb5/config-files/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:13 2003
--- krb5/config-files/.cvsignore	Thu Jun  5 10:38:36 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/config-files/configure.in
diff -c krb5/config-files/configure.in:1.1.1.1 krb5/config-files/configure.in:removed
*** krb5/config-files/configure.in:1.1.1.1	Mon Jun  2 17:54:56 1997
--- krb5/config-files/configure.in	Sun Mar 16 20:22:13 2003
***************
*** 1,4 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_INSTALL
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/gen-manpages/.cvsignore
diff -c /dev/null krb5/gen-manpages/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:13 2003
--- krb5/gen-manpages/.cvsignore	Thu Jun  5 10:38:37 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/gen-manpages/configure.in
diff -c krb5/gen-manpages/configure.in:1.1.1.1 krb5/gen-manpages/configure.in:removed
*** krb5/gen-manpages/configure.in:1.1.1.1	Mon Jun  2 17:54:57 1997
--- krb5/gen-manpages/configure.in	Sun Mar 16 20:22:13 2003
***************
*** 1,4 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_INSTALL
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/include/.cvsignore
diff -c /dev/null krb5/include/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:13 2003
--- krb5/include/.cvsignore	Thu Jun  5 10:38:38 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/include/k5-int.h
diff -c krb5/include/k5-int.h:1.1.1.3 krb5/include/k5-int.h:1.9
*** krb5/include/k5-int.h:1.1.1.3	Mon Aug 12 15:44:24 2002
--- krb5/include/k5-int.h	Mon Oct  7 14:44:58 2002
***************
*** 394,399 ****
--- 394,432 ----
  	krb5_timestamp	sam_patimestamp;
  } krb5_sam_response;
  
+ typedef struct _krb5_sam_challenge_2 {
+ 	krb5_data	sam_challenge_2_body;
+ 	krb5_checksum	**sam_cksum;		/* Array of checksums */
+ } krb5_sam_challenge_2;
+ 
+ typedef struct _krb5_sam_challenge_2_body {
+ 	krb5_magic	magic;
+ 	krb5_int32	sam_type; /* information */
+ 	krb5_flags	sam_flags; /* KRB5_SAM_* values */
+ 	krb5_data	sam_type_name;
+ 	krb5_data	sam_track_id;
+ 	krb5_data	sam_challenge_label;
+ 	krb5_data	sam_challenge;
+ 	krb5_data	sam_response_prompt;
+ 	krb5_data	sam_pk_for_sad;
+ 	krb5_int32	sam_nonce;
+ 	krb5_enctype	sam_etype;
+ } krb5_sam_challenge_2_body;
+ 
+ typedef struct _krb5_sam_response_2 {
+ 	krb5_magic	magic;
+ 	krb5_int32	sam_type; /* informational */
+ 	krb5_flags	sam_flags; /* KRB5_SAM_* values */
+ 	krb5_data	sam_track_id; /* copied */
+ 	krb5_enc_data	sam_enc_nonce_or_sad; /* krb5_enc_sam_response_enc */
+ 	krb5_int32	sam_nonce;
+ } krb5_sam_response_2;
+ 
+ typedef struct _krb5_enc_sam_response_enc_2 {
+ 	krb5_magic	magic;
+ 	krb5_int32	sam_nonce;
+ 	krb5_data	sam_sad;
+ } krb5_enc_sam_response_enc_2;
  
  /*
   * Begin "ext-proto.h"
***************
*** 674,679 ****
--- 707,715 ----
  		krb5_const krb5_keyblock *key, unsigned int icount,
  		krb5_const krb5_data *input, krb5_data *output));
  
+ krb5_error_code krb5_combine_keys
+ KRB5_PROTOTYPE((krb5_context context, krb5_keyblock *key1,
+ 		krb5_keyblock *key2, krb5_keyblock *outkey));
  
  #ifdef KRB5_OLD_CRYPTO
  /* old provider api */
***************
*** 972,992 ****
--- 1008,1048 ----
  
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge
  	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_2
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge_2 FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_2_body
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge_2_body FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_response
  	KRB5_PROTOTYPE((krb5_context, krb5_sam_response FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_response_2
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_response_2 FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_predicted_sam_response
  	KRB5_PROTOTYPE((krb5_context, krb5_predicted_sam_response FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc
  	KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc_2
+ 	KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc_2 FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_contents
  	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_2_contents
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge_2 FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_challenge_2_body_contents
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_challenge_2_body FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_response_contents
  	KRB5_PROTOTYPE((krb5_context, krb5_sam_response FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_sam_response_2_contents
+ 	KRB5_PROTOTYPE((krb5_context, krb5_sam_response_2 FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_predicted_sam_response_contents
  	KRB5_PROTOTYPE((krb5_context, krb5_predicted_sam_response FAR * ));
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc_contents
  	KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc FAR * ));
+ KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_sam_response_enc_2_contents
+ 	KRB5_PROTOTYPE((krb5_context, krb5_enc_sam_response_enc_2 FAR * ));
   
+ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_sam_combine_keys
+ 	KRB5_PROTOTYPE((krb5_context, krb5_keyblock FAR *,
+ 	krb5_keyblock FAR * ));
+ 
  KRB5_DLLIMP void KRB5_CALLCONV krb5_free_pa_enc_ts
  	KRB5_PROTOTYPE((krb5_context, krb5_pa_enc_ts FAR *));
  
***************
*** 1219,1227 ****
--- 1275,1298 ----
  krb5_error_code encode_krb5_sam_response
  	KRB5_PROTOTYPE((const krb5_sam_response * , krb5_data **));
  
+ krb5_error_code encode_krb5_sam_challenge_2
+ 	KRB5_PROTOTYPE((const krb5_sam_challenge_2 * , krb5_data **));
+ 
+ krb5_error_code encode_krb5_sam_challenge_2_body
+ 	KRB5_PROTOTYPE((const krb5_sam_challenge_2_body * , krb5_data **));
+ 
+ krb5_error_code encode_krb5_enc_sam_response_enc_2
+ 	KRB5_PROTOTYPE((const krb5_enc_sam_response_enc_2 * , krb5_data **));
+ 
+ krb5_error_code encode_krb5_sam_response_2
+ 	KRB5_PROTOTYPE((const krb5_sam_response_2 * , krb5_data **));
+ 
  krb5_error_code encode_krb5_predicted_sam_response
  	KRB5_PROTOTYPE((const krb5_predicted_sam_response * , krb5_data **));
  
+ krb5_error_code encode_krb5_principal
+ 	KRB5_PROTOTYPE((const krb5_principal, krb5_data **));
+ 
  krb5_error_code encode_krb5_sam_challenge
         KRB5_PROTOTYPE((const krb5_sam_challenge * , krb5_data **));
  
***************
*** 1245,1260 ****
         KRB5_PROTOTYPE((const krb5_data *, krb5_sam_challenge **));
  
  krb5_error_code decode_krb5_sam_key
!        KRB5_PROTOTYPE((const krb5_data *, krb5_sam_key **));
  
  krb5_error_code decode_krb5_enc_sam_response_enc
!        KRB5_PROTOTYPE((const krb5_data *, krb5_enc_sam_response_enc **));
  
  krb5_error_code decode_krb5_sam_response
!        KRB5_PROTOTYPE((const krb5_data *, krb5_sam_response **));
  
  krb5_error_code decode_krb5_predicted_sam_response
!        KRB5_PROTOTYPE((const krb5_data *, krb5_predicted_sam_response **));
  
  
  /*************************************************************************
--- 1316,1343 ----
         KRB5_PROTOTYPE((const krb5_data *, krb5_sam_challenge **));
  
  krb5_error_code decode_krb5_sam_key
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_sam_key **));
  
  krb5_error_code decode_krb5_enc_sam_response_enc
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_enc_sam_response_enc **));
  
  krb5_error_code decode_krb5_sam_response
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_sam_response **));
  
  krb5_error_code decode_krb5_predicted_sam_response
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_predicted_sam_response **));
! 
! krb5_error_code decode_krb5_sam_challenge_2
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_sam_challenge_2 **));
! 
! krb5_error_code decode_krb5_sam_challenge_2_body
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_sam_challenge_2_body **));
! 
! krb5_error_code decode_krb5_enc_sam_response_enc_2
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_enc_sam_response_enc_2 **));
! 
! krb5_error_code decode_krb5_sam_response_2
! 	KRB5_PROTOTYPE((const krb5_data *, krb5_sam_response_2 **));
  
  
  /*************************************************************************
***************
*** 1371,1376 ****
--- 1454,1462 ----
  
  krb5_error_code decode_krb5_predicted_sam_response
  	KRB5_PROTOTYPE((const krb5_data *, krb5_predicted_sam_response **));
+ 
+ krb5_error_code decode_krb5_principal
+ 	KRB5_PROTOTYPE((const krb5_data *, krb5_principal *));
  
  /*************************************************************************
   * End of prototypes for krb5_decode.c
Index: krb5/include/krb5.hin
diff -c krb5/include/krb5.hin:1.1.1.3 krb5/include/krb5.hin:1.12
*** krb5/include/krb5.hin:1.1.1.3	Mon Aug 12 15:44:25 2002
--- krb5/include/krb5.hin	Fri Dec 13 19:56:54 2002
***************
*** 362,367 ****
--- 362,371 ----
   * end "hostaddr.h"
   */
  
+ #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM	25
+ #define KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID	26
+ #define KRB5_KEYUSAGE_PA_SAM_RESPONSE		27
+ 
  
  struct _krb5_context;
  typedef struct _krb5_context FAR * krb5_context;
***************
*** 678,684 ****
  #define	KDC_OPT_RENEWABLE		0x00800000
  /* #define	KDC_OPT_UNUSED		0x00400000 */
  /* #define	KDC_OPT_RESERVED	0x00200000 */
! /* #define	KDC_OPT_RESERVED	0x00100000 */
  /* #define	KDC_OPT_RESERVED	0x00080000 */
  /* #define	KDC_OPT_RESERVED	0x00040000 */
  #define	KDC_OPT_REQUEST_ANONYMOUS	0x00020000
--- 682,688 ----
  #define	KDC_OPT_RENEWABLE		0x00800000
  /* #define	KDC_OPT_UNUSED		0x00400000 */
  /* #define	KDC_OPT_RESERVED	0x00200000 */
! #define	KDC_OPT_HW_AUTH			0x00100000
  /* #define	KDC_OPT_RESERVED	0x00080000 */
  /* #define	KDC_OPT_RESERVED	0x00040000 */
  #define	KDC_OPT_REQUEST_ANONYMOUS	0x00020000
***************
*** 842,847 ****
--- 846,852 ----
  #define KRB5_LRQ_ONE_LAST_RENEWAL	(-4)
  #define KRB5_LRQ_ALL_LAST_REQ		5
  #define KRB5_LRQ_ONE_LAST_REQ		(-5)
+ #define KRB5_LRQ_PW_EXPTIME		6
  
  /* PADATA types */
  #define KRB5_PADATA_NONE		0
***************
*** 861,866 ****
--- 866,877 ----
  #define KRB5_PADATA_ETYPE_INFO		11 /* Etype info for preauth */
  #define KRB5_PADATA_SAM_CHALLENGE	12 /* draft challenge system */
  #define KRB5_PADATA_SAM_RESPONSE	13 /* draft challenge system response */
+ #define KRB5_PADATA_PK_AS_REQ		14 /* PKINIT */
+ #define KRB5_PADATA_PK_AS_REP		15 /* PKINIT */
+ 
+ #define KRB5_PADATA_ALT_PRINC		24 /* Matt Crawford */
+ #define KRB5_PADATA_SAM_CHALLENGE_2	30 /* draft challenge system -- updated */
+ #define KRB5_PADATA_SAM_RESPONSE_2	31 /* draft challenge system response -- updated */
      
  #define	KRB5_SAM_USE_SAD_AS_KEY		0x80000000
  #define	KRB5_SAM_SEND_ENCRYPTED_SAD	0x40000000
***************
*** 869,874 ****
--- 880,888 ----
  /* Reserved for SPX pre-authentication. */
  #define KRB5_PADATA_DASS		16
  
+ /* Special experimental pre-auth types */
+ #define KRB5_PADATA_AS_REP		20 /* AS-REP encrypted w/ server key */
+ 
  /* Transited encoding types */
  #define	KRB5_DOMAIN_X500_COMPRESS	1
  
***************
*** 891,896 ****
--- 905,920 ----
   * end "proto.h"
   */
  
+ /*
+  * begin "error_def.h"
+  */
+ 
+ #include <errno.h>
+ 
+ /*
+  * end "error_def.h"
+  */
+ 
  /* Time set */
  typedef struct _krb5_ticket_times {
      krb5_timestamp authtime; /* XXX ? should ktime in KDC_REP == authtime
***************
*** 2526,2531 ****
--- 2550,2556 ----
  #define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST	0x0020
  #define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST	0x0040
  #define KRB5_GET_INIT_CREDS_OPT_SALT		0x0080
+ #define KRB5_GET_INIT_CREDS_OPT_HW_AUTH		0x8000
  
  
  KRB5_DLLIMP void KRB5_CALLCONV
***************
*** 2592,2597 ****
--- 2617,2634 ----
  		krb5_creds *creds,
  		krb5_principal client,
  		krb5_keytab arg_keytab,
+ 		krb5_deltat start_time,
+ 		char *in_tkt_service,
+ 		krb5_get_init_creds_opt *options));
+ 
+ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+ krb5_get_init_creds_keytab_prompter
+ KRB5_PROTOTYPE((krb5_context context,
+ 		krb5_creds *creds,
+ 		krb5_principal client,
+ 		krb5_keytab arg_keytab,
+ 		krb5_prompter_fct prompter,
+ 		void *data,
  		krb5_deltat start_time,
  		char *in_tkt_service,
  		krb5_get_init_creds_opt *options));
Index: krb5/include/kerberosIV/.cvsignore
diff -c /dev/null krb5/include/kerberosIV/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:14 2003
--- krb5/include/kerberosIV/.cvsignore	Thu Jun  5 10:38:39 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/include/kerberosIV/configure.in
diff -c krb5/include/kerberosIV/configure.in:1.1.1.1 krb5/include/kerberosIV/configure.in:removed
*** krb5/include/kerberosIV/configure.in:1.1.1.1	Mon Jun  2 17:55:01 1997
--- krb5/include/kerberosIV/configure.in	Sun Mar 16 20:22:14 2003
***************
*** 1,4 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_INSTALL
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/include/kerberosIV/krb4-proto.h
diff -c krb5/include/kerberosIV/krb4-proto.h:1.1.1.1 krb5/include/kerberosIV/krb4-proto.h:removed
*** krb5/include/kerberosIV/krb4-proto.h:1.1.1.1	Mon Jun  2 17:55:01 1997
--- krb5/include/kerberosIV/krb4-proto.h	Sun Mar 16 20:22:14 2003
***************
*** 1,242 ****
- /*
-  * include/kerberosIV/krb4-proto.h
-  *
-  * Copyright 1991, 1994 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * Kerberos V4 prototypes
-  */
- 
- #ifndef _KRB4_PROTO_H__
- #define _KRB4_PROTO_H__
- 
- #ifndef P_TYPE_
- #if defined(__STDC__) && !defined(KRB5_NO_PROTOTYPES)
- # define	P_TYPE_(s) s
- #else
- # define P_TYPE_(s) ()
- #endif
- #endif /* P_TYPE_ */
- 
- /* add_ticket.c */
- int add_ticket P_TYPE_((KTEXT , int , char *, int , char *, char *, char *, int , KTEXT ));
- 
- /* cr_err_reply.c */
- void cr_err_reply P_TYPE_((KTEXT , char *, char *, char *, u_long , u_long , char *));
- 
- /* create_auth_reply.c */
- KTEXT create_auth_reply P_TYPE_((char *, char *, char *, long , int , unsigned long , int , KTEXT ));
- 
- /* create_ciph.c */
- int create_ciph P_TYPE_((KTEXT , C_Block , char *, char *, char *, unsigned long , int , KTEXT , unsigned long , C_Block ));
- 
- /* create_death_packet.c */
- KTEXT krb_create_death_packet P_TYPE_((char *));
- 
- /* create_ticket.c */
- int krb_create_ticket P_TYPE_((KTEXT , unsigned int , char *, char *, char *, long , char *, int , long , char *, char *, C_Block ));
- 
- /* debug_decl.c */
- 
- /* decomp_ticket.c */
- int decomp_ticket P_TYPE_((KTEXT , unsigned char *, char *, char *, char *, unsigned KRB4_32 *, C_Block , int *, unsigned KRB4_32 *, char *, char *, C_Block , Key_schedule ));
- 
- /* dest_tkt.c */
- int dest_tkt P_TYPE_((void ));
- 
- /* extract_ticket.c */
- int extract_ticket P_TYPE_((KTEXT , int , char *, int *, int *, char *, KTEXT ));
- 
- /* fgetst.c */
- int fgetst P_TYPE_((FILE *, char *, int ));
- 
- /* get_ad_tkt.c */
- int get_ad_tkt P_TYPE_((char *, char *, char *, int ));
- 
- /* get_admhst.c */
- int krb_get_admhst P_TYPE_((char *, char *, int ));
- 
- /* get_cred.c */
- int krb_get_cred P_TYPE_((char *, char *, char *, CREDENTIALS *));
- 
- /* get_in_tkt.c */
- int krb_get_pw_in_tkt P_TYPE_((char *, char *, char *, char *, char *, int , char *));
- int placebo_read_password P_TYPE_((des_cblock *, char *, int ));
- int placebo_read_pw_string P_TYPE_((char *, int , char *, int ));
- 
- /* get_krbhst.c */
- int krb_get_krbhst P_TYPE_((char *, char *, int ));
- 
- /* get_krbrlm.c */
- int krb_get_lrealm P_TYPE_((char *, int ));
- 
- /* get_phost.c */
- char *krb_get_phost P_TYPE_((char *));
- 
- /* get_pw_tkt.c */
- int get_pw_tkt P_TYPE_((char *, char *, char *, char *));
- 
- /* get_request.c */
- int get_request P_TYPE_((KTEXT , int , char **, char **));
- 
- /* get_svc_in_tkt.c */
- int krb_get_svc_in_tkt P_TYPE_((char *, char *, char *, char *, char *, int , char *));
- 
- /* get_tf_fullname.c */
- int krb_get_tf_fullname P_TYPE_((char *, char *, char *, char *));
- 
- /* get_tf_realm.c */
- int krb_get_tf_realm P_TYPE_((char *, char *));
- 
- #if 0    
- /* getopt.c */
- int getopt P_TYPE_((int , char **, char *));
- #endif
- 
- /* getrealm.c */
- char *krb_realmofhost P_TYPE_((char *));
- 
- /* getst.c */
- int getst P_TYPE_((int , char *, int ));
- 
- /* in_tkt.c */
- int in_tkt P_TYPE_((char *, char *));
- 
- /* k_gethostname.c */
- int k_gethostname P_TYPE_((char *, int ));
- 
- /* klog.c */
- char *klog P_TYPE_((int , char *, char * , char * , char * , char * , char * , char * , char * , char * , char * , char * ));
- int kset_logfile P_TYPE_((char *));
- 
- /* kname_parse.c */
- int kname_parse P_TYPE_((char *, char *, char *, char *));
- int k_isname P_TYPE_((char *));
- int k_isinst P_TYPE_((char *));
- int k_isrealm P_TYPE_((char *));
- 
- /* kntoln.c */
- int krb_kntoln P_TYPE_((AUTH_DAT *, char *));
- 
- /* krb_err_txt.c */
- 
- /* krb_get_in_tkt.c */
- int krb_get_in_tkt P_TYPE_((char *, char *, char *, char *, char *, int , int (*key_proc )(), int (*decrypt_proc )(), char *));
- 
- /* kuserok.c */
- int kuserok P_TYPE_((AUTH_DAT *, char *));
- 
- /* log.c */
- void log P_TYPE_((char *, int , int , int , int , int , int , int , int , int , int ));
- int set_logfile P_TYPE_((char *));
- int new_log P_TYPE_((long , char *));
- 
- /* mk_err.c */
- long krb_mk_err P_TYPE_((u_char *, long , char *));
- 
- /* mk_priv.c */
- long krb_mk_priv P_TYPE_((u_char *, u_char *, u_long , Key_schedule , C_Block , struct sockaddr_in *, struct sockaddr_in *));
- 
- /* mk_req.c */
- int krb_mk_req P_TYPE_((KTEXT , char *, char *, char *, long ));
- int krb_set_lifetime P_TYPE_((int ));
- 
- /* mk_safe.c */
- long krb_mk_safe P_TYPE_((u_char *, u_char *, u_long , C_Block *, struct sockaddr_in *, struct sockaddr_in *));
- 
- /* month_sname.c */
- char *month_sname P_TYPE_((int ));
- 
- /* netread.c */
- int krb_net_read P_TYPE_((int , char *, int ));
- 
- /* netwrite.c */
- int krb_net_write P_TYPE_((int , char *, int ));
- 
- /* one.c */
- 
- /* pkt_cipher.c */
- KTEXT pkt_cipher P_TYPE_((KTEXT ));
- 
- /* pkt_clen.c */
- int pkt_clen P_TYPE_((KTEXT ));
- 
- /* rd_err.c */
- int krb_rd_err P_TYPE_((u_char *, u_long , long *, MSG_DAT *));
- 
- /* rd_priv.c */
- long krb_rd_priv P_TYPE_((u_char *, u_long , Key_schedule , C_Block *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
- 
- /* rd_req.c */
- int krb_set_key P_TYPE_((char *, int ));
- int krb_rd_req P_TYPE_((KTEXT , char *, char *, unsigned KRB4_32 , AUTH_DAT *, char *));
- 
- /* rd_safe.c */
- long krb_rd_safe P_TYPE_((u_char *, u_long , C_Block *, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));
- 
- /* read_service_key.c */
- int read_service_key P_TYPE_((char *, char *, char *, int , char *, char *));
- 
- /* recvauth.c */
- int krb_recvauth P_TYPE_((long , int , KTEXT , char *, char *, struct sockaddr_in *, struct sockaddr_in *, AUTH_DAT *, char *, Key_schedule , char *));
- 
- /* save_credentials.c */
- int krb_save_credentials P_TYPE_((char *, char *, char *, C_Block , int , int , KTEXT , long ));
- 
- /* send_to_kdc.c */
- int send_to_kdc P_TYPE_((KTEXT , KTEXT , char *));
- 
- /* sendauth.c */
- int krb_sendauth P_TYPE_((long , int , KTEXT , char *, char *, char *, u_long , MSG_DAT *, CREDENTIALS *, Key_schedule , struct sockaddr_in *, struct sockaddr_in *, char *));
- int krb_sendsvc P_TYPE_((int , char *));
- 
- #if 0    
- /* setenv.c */
- /* int setenv P_TYPE_((char *, char *, int )); -- is also in telnetd/local-proto.h */
- void unsetenv P_TYPE_((char *));
- char *getenv P_TYPE_((char *));
- char *_findenv P_TYPE_((char *, int *));
- #endif
- 
- /* stime.c */
- char *krb_stime P_TYPE_((long *));
- 
- /* tf_shm.c */
- int krb_shm_create P_TYPE_((char *));
- int krb_is_diskless P_TYPE_((void ));
- int krb_shm_dest P_TYPE_((char *));
- 
- /* tf_util.c */
- int tf_init P_TYPE_((char *, int ));
- int tf_get_pname P_TYPE_((char *));
- int tf_get_pinst P_TYPE_((char *));
- int tf_get_cred P_TYPE_((CREDENTIALS *));
- int tf_close P_TYPE_((void ));
- int tf_save_cred P_TYPE_((char *, char *, char *, C_Block , int , int , KTEXT , long ));
- 
- /* tkt_string.c */
- char *tkt_string P_TYPE_((void ));
- void krb_set_tkt_string P_TYPE_((char *));
- 
- /* util.c */
- int ad_print P_TYPE_((AUTH_DAT *));
- int placebo_cblock_print P_TYPE_((des_cblock ));
- 
- #endif /*  _KRB4_PROTO_H__ */
--- 0 ----
Index: krb5/include/kerberosIV/krb_err.h
diff -c krb5/include/kerberosIV/krb_err.h:1.1.1.1 krb5/include/kerberosIV/krb_err.h:removed
*** krb5/include/kerberosIV/krb_err.h:1.1.1.1	Mon Jun  2 17:55:01 1997
--- krb5/include/kerberosIV/krb_err.h	Sun Mar 16 20:22:14 2003
***************
*** 1,92 ****
- /*
-  * krb_err.h:
-  * This file is automatically generated; please do not edit it.
-  */
- #define KRBET_KSUCCESS                           (39525376L)
- #define KRBET_KDC_NAME_EXP                       (39525377L)
- #define KRBET_KDC_SERVICE_EXP                    (39525378L)
- #define KRBET_KDC_AUTH_EXP                       (39525379L)
- #define KRBET_KDC_PKT_VER                        (39525380L)
- #define KRBET_KDC_P_MKEY_VER                     (39525381L)
- #define KRBET_KDC_S_MKEY_VER                     (39525382L)
- #define KRBET_KDC_BYTE_ORDER                     (39525383L)
- #define KRBET_KDC_PR_UNKNOWN                     (39525384L)
- #define KRBET_KDC_PR_N_UNIQUE                    (39525385L)
- #define KRBET_KDC_NULL_KEY                       (39525386L)
- #define KRBET_KRB_RES11                          (39525387L)
- #define KRBET_KRB_RES12                          (39525388L)
- #define KRBET_KRB_RES13                          (39525389L)
- #define KRBET_KRB_RES14                          (39525390L)
- #define KRBET_KRB_RES15                          (39525391L)
- #define KRBET_KRB_RES16                          (39525392L)
- #define KRBET_KRB_RES17                          (39525393L)
- #define KRBET_KRB_RES18                          (39525394L)
- #define KRBET_KRB_RES19                          (39525395L)
- #define KRBET_KDC_GEN_ERR                        (39525396L)
- #define KRBET_GC_TKFIL                           (39525397L)
- #define KRBET_GC_NOTKT                           (39525398L)
- #define KRBET_KRB_RES23                          (39525399L)
- #define KRBET_KRB_RES24                          (39525400L)
- #define KRBET_KRB_RES25                          (39525401L)
- #define KRBET_MK_AP_TGTEXP                       (39525402L)
- #define KRBET_KRB_RES27                          (39525403L)
- #define KRBET_KRB_RES28                          (39525404L)
- #define KRBET_KRB_RES29                          (39525405L)
- #define KRBET_KRB_RES30                          (39525406L)
- #define KRBET_RD_AP_UNDEC                        (39525407L)
- #define KRBET_RD_AP_EXP                          (39525408L)
- #define KRBET_RD_AP_NYV                          (39525409L)
- #define KRBET_RD_AP_REPEAT                       (39525410L)
- #define KRBET_RD_AP_NOT_US                       (39525411L)
- #define KRBET_RD_AP_INCON                        (39525412L)
- #define KRBET_RD_AP_TIME                         (39525413L)
- #define KRBET_RD_AP_BADD                         (39525414L)
- #define KRBET_RD_AP_VERSION                      (39525415L)
- #define KRBET_RD_AP_MSG_TYPE                     (39525416L)
- #define KRBET_RD_AP_MODIFIED                     (39525417L)
- #define KRBET_RD_AP_ORDER                        (39525418L)
- #define KRBET_RD_AP_UNAUTHOR                     (39525419L)
- #define KRBET_KRB_RES44                          (39525420L)
- #define KRBET_KRB_RES45                          (39525421L)
- #define KRBET_KRB_RES46                          (39525422L)
- #define KRBET_KRB_RES47                          (39525423L)
- #define KRBET_KRB_RES48                          (39525424L)
- #define KRBET_KRB_RES49                          (39525425L)
- #define KRBET_KRB_RES50                          (39525426L)
- #define KRBET_GT_PW_NULL                         (39525427L)
- #define KRBET_GT_PW_BADPW                        (39525428L)
- #define KRBET_GT_PW_PROT                         (39525429L)
- #define KRBET_GT_PW_KDCERR                       (39525430L)
- #define KRBET_GT_PW_NULLTKT                      (39525431L)
- #define KRBET_SKDC_RETRY                         (39525432L)
- #define KRBET_SKDC_CANT                          (39525433L)
- #define KRBET_KRB_RES58                          (39525434L)
- #define KRBET_KRB_RES59                          (39525435L)
- #define KRBET_KRB_RES60                          (39525436L)
- #define KRBET_INTK_W_NOTALL                      (39525437L)
- #define KRBET_INTK_BADPW                         (39525438L)
- #define KRBET_INTK_PROT                          (39525439L)
- #define KRBET_KRB_RES64                          (39525440L)
- #define KRBET_KRB_RES65                          (39525441L)
- #define KRBET_KRB_RES66                          (39525442L)
- #define KRBET_KRB_RES67                          (39525443L)
- #define KRBET_KRB_RES68                          (39525444L)
- #define KRBET_KRB_RES69                          (39525445L)
- #define KRBET_INTK_ERR                           (39525446L)
- #define KRBET_AD_NOTGT                           (39525447L)
- #define KRBET_KRB_RES72                          (39525448L)
- #define KRBET_KRB_RES73                          (39525449L)
- #define KRBET_KRB_RES74                          (39525450L)
- #define KRBET_KRB_RES75                          (39525451L)
- #define KRBET_NO_TKT_FIL                         (39525452L)
- #define KRBET_TKT_FIL_ACC                        (39525453L)
- #define KRBET_TKT_FIL_LCK                        (39525454L)
- #define KRBET_TKT_FIL_FMT                        (39525455L)
- #define KRBET_TKT_FIL_INI                        (39525456L)
- #define KRBET_KNAME_FMT                          (39525457L)
- extern void initialize_krb_error_table ();
- #define ERROR_TABLE_BASE_krb (39525376L)
- 
- /* for compatibility with older versions... */
- #define init_krb_err_tbl initialize_krb_error_table
- #define krb_err_base ERROR_TABLE_BASE_krb
--- 0 ----
Index: krb5/include/krb5/.cvsignore
diff -c /dev/null krb5/include/krb5/.cvsignore:1.2
*** /dev/null	Sun Mar 16 20:22:14 2003
--- krb5/include/krb5/.cvsignore	Wed Aug 13 16:56:06 1997
***************
*** 0 ****
--- 1,2 ----
+ configure
+ autoconf.h.in
Index: krb5/include/krb5/Makefile.in
diff -c krb5/include/krb5/Makefile.in:1.1.1.2 krb5/include/krb5/Makefile.in:1.3
*** krb5/include/krb5/Makefile.in:1.1.1.2	Fri Feb 22 16:33:01 2002
--- krb5/include/krb5/Makefile.in	Sun Feb 24 20:50:24 2002
***************
*** 41,49 ****
--- 41,53 ----
  
  SYSCONFDIR = @sysconfdir@
  LOCALSTATEDIR = @localstatedir@
+ BINDIR = @bindir@
+ SBINDIR = @sbindir@
  PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(KRB5RCTMPDIR)+" \
  		  -e "s+@PREFIX+$(INSTALL_PREFIX)+" \
  		  -e "s+@EXEC_PREFIX+$(INSTALL_EXEC_PREFIX)+" \
+ 		  -e "s+@BINDIR+$(BINDIR)+" \
+ 		  -e "s+@SBINDIR+$(SBINDIR)+" \
  	-e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
  	-e 's+@SYSCONFDIR+$(SYSCONFDIR)+' 
  
Index: krb5/include/krb5/autoconf.h.in
diff -c krb5/include/krb5/autoconf.h.in:1.1.1.2 krb5/include/krb5/autoconf.h.in:removed
*** krb5/include/krb5/autoconf.h.in:1.1.1.2	Fri Feb 22 16:33:04 2002
--- krb5/include/krb5/autoconf.h.in	Sun Mar 16 20:22:14 2003
***************
*** 1,145 ****
- /* krb5/autoconf.h.in.  Generated automatically from configure.in by autoheader.  */
- 
- /* Define to empty if the keyword does not work.  */
- #undef const
- 
- /* Define to `int' if <sys/types.h> doesn't define.  */
- #undef gid_t
- 
- /* Define if you have the ANSI C header files.  */
- #undef STDC_HEADERS
- 
- /* Define if you can safely include both <sys/time.h> and <time.h>.  */
- #undef TIME_WITH_SYS_TIME
- 
- /* Define to `int' if <sys/types.h> doesn't define.  */
- #undef uid_t
- 
- #undef ANSI_STDIO
- #undef HAS_VOID_TYPE
- #undef KRB5_NO_PROTOTYPES
- #undef KRB5_PROVIDE_PROTOTYPES
- #undef KRB5_NO_NESTED_PROTOTYPES
- 
- #undef NO_YYLINENO
- #undef POSIX_FILE_LOCKS
- #undef POSIX_SIGTYPE
- #undef POSIX_TERMIOS
- #undef USE_DIRENT_H
- #undef WAIT_USES_INT
- #undef krb5_sigtype
- 
- #undef HAVE_STDARG_H
- #undef HAVE_VARARGS_H
- 
- /* Define if MIT Project Athena default configuration should be used */
- #undef KRB5_ATHENA_COMPAT
- 
- /* Define if Kerberos V4 backwards compatibility should be supported */
- #undef KRB5_KRB4_COMPAT
- 
- /* Define if DNS support for finding realms and KDC locations should
-    be compiled in.  */
- #undef KRB5_DNS_LOOKUP
- #undef KRB5_DNS_LOOKUP_KDC
- #undef KRB5_DNS_LOOKUP_REALM
- 
- /* Define to `long' if <sys/types.h> doesn't define. */
- #undef time_t
- 
- /* Define if we should compile in IPv6 support (even if we may find we
-    can't use it at run time).  */
- #undef KRB5_USE_INET6
- 
- /* The number of bytes in a int.  */
- #undef SIZEOF_INT
- 
- /* The number of bytes in a long.  */
- #undef SIZEOF_LONG
- 
- /* The number of bytes in a short.  */
- #undef SIZEOF_SHORT
- 
- /* Define if you have the bcopy function.  */
- #undef HAVE_BCOPY
- 
- /* Define if you have the getaddrinfo function.  */
- #undef HAVE_GETADDRINFO
- 
- /* Define if you have the getipnodebyaddr function.  */
- #undef HAVE_GETIPNODEBYADDR
- 
- /* Define if you have the getipnodebyname function.  */
- #undef HAVE_GETIPNODEBYNAME
- 
- /* Define if you have the getnameinfo function.  */
- #undef HAVE_GETNAMEINFO
- 
- /* Define if you have the inet_aton function.  */
- #undef HAVE_INET_ATON
- 
- /* Define if you have the inet_ntoa function.  */
- #undef HAVE_INET_NTOA
- 
- /* Define if you have the inet_ntop function.  */
- #undef HAVE_INET_NTOP
- 
- /* Define if you have the inet_pton function.  */
- #undef HAVE_INET_PTON
- 
- /* Define if you have the labs function.  */
- #undef HAVE_LABS
- 
- /* Define if you have the memmove function.  */
- #undef HAVE_MEMMOVE
- 
- /* Define if you have the setvbuf function.  */
- #undef HAVE_SETVBUF
- 
- /* Define if you have the strdup function.  */
- #undef HAVE_STRDUP
- 
- /* Define if you have the <macsock.h> header file.  */
- #undef HAVE_MACSOCK_H
- 
- /* Define if you have the <netinet/in.h> header file.  */
- #undef HAVE_NETINET_IN_H
- 
- /* Define if you have the <stddef.h> header file.  */
- #undef HAVE_STDDEF_H
- 
- /* Define if you have the <stdlib.h> header file.  */
- #undef HAVE_STDLIB_H
- 
- /* Define if you have the <string.h> header file.  */
- #undef HAVE_STRING_H
- 
- /* Define if you have the <sys/file.h> header file.  */
- #undef HAVE_SYS_FILE_H
- 
- /* Define if you have the <sys/param.h> header file.  */
- #undef HAVE_SYS_PARAM_H
- 
- /* Define if you have the <sys/socket.h> header file.  */
- #undef HAVE_SYS_SOCKET_H
- 
- /* Define if you have the <sys/stat.h> header file.  */
- #undef HAVE_SYS_STAT_H
- 
- /* Define if you have the <sys/time.h> header file.  */
- #undef HAVE_SYS_TIME_H
- 
- /* Define if you have the <sys/types.h> header file.  */
- #undef HAVE_SYS_TYPES_H
- 
- /* Define if you have the <unistd.h> header file.  */
- #undef HAVE_UNISTD_H
- 
- /* Define if you have the <xom.h> header file.  */
- #undef HAVE_XOM_H
- 
- /* Define if you have the nsl library (-lnsl).  */
- #undef HAVE_LIBNSL
- 
- /* Define if you have the socket library (-lsocket).  */
- #undef HAVE_LIBSOCKET
--- 0 ----
Index: krb5/include/krb5/configure.in
diff -c krb5/include/krb5/configure.in:1.1.1.1 krb5/include/krb5/configure.in:1.2
*** krb5/include/krb5/configure.in:1.1.1.1	Mon Jun  2 17:55:03 1997
--- krb5/include/krb5/configure.in	Mon Jun  2 18:34:29 1997
***************
*** 99,105 ****
  AC_MSG_CHECKING([for replay cache directory])
  AC_CACHE_VAL(krb5_cv_sys_rcdir,
  [
! for t_dir in /usr/tmp /var/usr/tmp /var/tmp /tmp ; do
  	test -d $t_dir || continue
  	krb5_cv_sys_rcdir=$t_dir
  	break
--- 99,105 ----
  AC_MSG_CHECKING([for replay cache directory])
  AC_CACHE_VAL(krb5_cv_sys_rcdir,
  [
! for t_dir in /var/tmp /usr/tmp /var/usr/tmp /tmp ; do
  	test -d $t_dir || continue
  	krb5_cv_sys_rcdir=$t_dir
  	break
Index: krb5/include/krb5/kdb.h
diff -c krb5/include/krb5/kdb.h:1.1.1.2 krb5/include/krb5/kdb.h:1.5
*** krb5/include/krb5/kdb.h:1.1.1.2	Fri Feb 22 16:33:02 2002
--- krb5/include/krb5/kdb.h	Tue Nov 26 12:47:48 2002
***************
*** 151,156 ****
--- 151,158 ----
  #ifdef SECURID
  #define KRB5_TL_SECURID_STATE           0x0006
  #endif /* SECURID */
+ #define KRB5_TL_RB1_KEYTYPE		0x0007
+ #define KRB5_TL_RB1_CARDINFO		0x0101
      
  /*
   * Determines the number of failed KDC requests before DISALLOW_ALL_TIX is set
Index: krb5/include/krb5/stock/osconf.h
diff -c krb5/include/krb5/stock/osconf.h:1.1.1.3 krb5/include/krb5/stock/osconf.h:1.6
*** krb5/include/krb5/stock/osconf.h:1.1.1.3	Wed Sep 25 15:06:10 2002
--- krb5/include/krb5/stock/osconf.h	Wed Sep 25 15:18:24 2002
***************
*** 65,72 ****
  #define	DEFAULT_KDC_ENCTYPE	ENCTYPE_DES_CBC_CRC
  #define KDCRCACHE		"dfl:krb5kdc_rcache"
  
! #define KDC_PORTNAME		"kerberos" /* for /etc/services or equiv. */
! #define KDC_SECONDARY_PORTNAME	"kerberos-sec" /* For backwards */
  					    /* compatibility with */
  					    /* port 750 clients */
  
--- 65,72 ----
  #define	DEFAULT_KDC_ENCTYPE	ENCTYPE_DES_CBC_CRC
  #define KDCRCACHE		"dfl:krb5kdc_rcache"
  
! #define KDC_PORTNAME		"kerberos5" /* for /etc/services or equiv. */
! #define KDC_SECONDARY_PORTNAME	"kerberos" /* For backwards */
  					    /* compatibility with */
  					    /* port 750 clients */
  
***************
*** 93,100 ****
  #define RCTMPDIR	"@KRB5RCTMPDIR"	/* directory to store replay caches */
  
  #define KRB5_PATH_TTY	"/dev/tty"
! #define KRB5_PATH_LOGIN	"@EXEC_PREFIX/sbin/login.krb5"
! #define KRB5_PATH_RLOGIN "@EXEC_PREFIX/bin/rlogin"
  
  #define KRB5_ENV_CCNAME	"KRB5CCNAME"
  
--- 93,100 ----
  #define RCTMPDIR	"@KRB5RCTMPDIR"	/* directory to store replay caches */
  
  #define KRB5_PATH_TTY	"/dev/tty"
! #define KRB5_PATH_LOGIN	"@SBINDIR/login.krb5"
! #define KRB5_PATH_RLOGIN "@BINDIR/rlogin"
  
  #define KRB5_ENV_CCNAME	"KRB5CCNAME"
  
***************
*** 116,123 ****
  
  #define KPROP_DEFAULT_FILE "@LOCALSTATEDIR/krb5kdc/slave_datatrans"
  #define KPROPD_DEFAULT_FILE "@LOCALSTATEDIR/krb5kdc/from_master"
! #define KPROPD_DEFAULT_KDB5_UTIL "@PREFIX/sbin/kdb5_util"
! #define KPROPD_DEFAULT_KDB5_EDIT "@PREFIX/sbin/kdb5_edit"
  #define KPROPD_DEFAULT_KRB_DB DEFAULT_KDB_FILE
  #define KPROPD_ACL_FILE "@LOCALSTATEDIR/krb5kdc/kpropd.acl"
  
--- 116,123 ----
  
  #define KPROP_DEFAULT_FILE "@LOCALSTATEDIR/krb5kdc/slave_datatrans"
  #define KPROPD_DEFAULT_FILE "@LOCALSTATEDIR/krb5kdc/from_master"
! #define KPROPD_DEFAULT_KDB5_UTIL "@SBINDIR/kdb5_util"
! #define KPROPD_DEFAULT_KDB5_EDIT "@SBINDIR/kdb5_edit"
  #define KPROPD_DEFAULT_KRB_DB DEFAULT_KDB_FILE
  #define KPROPD_ACL_FILE "@LOCALSTATEDIR/krb5kdc/kpropd.acl"
  
Index: krb5/kadmin/.cvsignore
diff -c /dev/null krb5/kadmin/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:15 2003
--- krb5/kadmin/.cvsignore	Thu Jun  5 10:38:41 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/configure.in
diff -c krb5/kadmin/configure.in:1.1.1.2 krb5/kadmin/configure.in:1.2
*** krb5/kadmin/configure.in:1.1.1.2	Fri Feb 22 16:33:06 2002
--- krb5/kadmin/configure.in	Sun Feb 24 21:56:19 2002
***************
*** 3,9 ****
  AC_PROG_INSTALL
  AC_PROG_YACC
  AC_PROG_AWK
! AC_CHECK_HEADERS(unistd.h stdlib.h krb_db.h kdc.h alloca.h sys/time.h sys/select.h)
  AC_CHECK_FUNCS(ftime timezone getcwd strstr waitpid vsprintf)
  AC_REPLACE_FUNCS([memmove strftime])
  AC_HEADER_TIME
--- 3,9 ----
  AC_PROG_INSTALL
  AC_PROG_YACC
  AC_PROG_AWK
! AC_CHECK_HEADERS(unistd.h stdlib.h krb_db.h kdc.h alloca.h sys/time.h sys/select.h pty.h)
  AC_CHECK_FUNCS(ftime timezone getcwd strstr waitpid vsprintf)
  AC_REPLACE_FUNCS([memmove strftime])
  AC_HEADER_TIME
***************
*** 15,20 ****
--- 15,32 ----
  AC_ARG_ENABLE([athena],
  [  --enable-athena         build with MIT Project Athena configuration],
  ath_compat=compat,)
+ dnl
+ dnl --with-kadmin-cryptocard adds the special cryptocard interface to kadmin
+ dnl
+ AC_ARG_WITH([kadmin-cryptocard],
+ [  --with-kadmin-cryptocard    Add support for programming CRYPTOCard RB-1 tokens
+   --without-kadmin-cryptocard  Do not add CRYPTOCard programming support (default)],
+ ,
+ withval=no)dnl
+ if test "$withval" = yes; then
+        AC_MSG_RESULT(Adding CRYPTOCard RB-1 programming support)
+        AC_DEFINE(KADMIN_CRYPTOCARD)
+ fi
  dnl
  dnl The following are tests for the presence of programs required for testing 
  AC_CHECK_PROG(have_RUNTEST,runtest,runtest)
Index: krb5/kadmin/cli/.cvsignore
diff -c /dev/null krb5/kadmin/cli/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:15 2003
--- krb5/kadmin/cli/.cvsignore	Thu Jun  5 10:38:42 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/cli/Makefile.in
diff -c krb5/kadmin/cli/Makefile.in:1.1.1.2 krb5/kadmin/cli/Makefile.in:1.3
*** krb5/kadmin/cli/Makefile.in:1.1.1.2	Fri Feb 22 16:33:07 2002
--- krb5/kadmin/cli/Makefile.in	Sun Feb 24 21:21:26 2002
***************
*** 6,12 ****
  PROG_RPATH=$(KRB5_LIBDIR)
  
  PROG = kadmin
! OBJS = kadmin.o kadmin_ct.o ss_wrapper.o getdate.o keytab.o
  
  all:: $(PROG).local $(PROG)
  
--- 6,12 ----
  PROG_RPATH=$(KRB5_LIBDIR)
  
  PROG = kadmin
! OBJS = kadmin.o kadmin_ct.o ss_wrapper.o getdate.o keytab.o cryptocard.o
  
  all:: $(PROG).local $(PROG)
  
Index: krb5/kadmin/cli/configure.in
diff -c krb5/kadmin/cli/configure.in:1.1.1.1 krb5/kadmin/cli/configure.in:removed
*** krb5/kadmin/cli/configure.in:1.1.1.1	Mon Jun  2 17:55:05 1997
--- krb5/kadmin/cli/configure.in	Sun Mar 16 20:22:15 2003
***************
*** 1,17 ****
- AC_INIT(getdate.y)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_PROG_YACC
- AC_HAVE_HEADERS(unistd.h sys/timeb.h alloca.h)
- AC_HAVE_FUNCS(ftime timezone)
- AC_REPLACE_FUNCS([memmove strftime])
- USE_KADMCLNT_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_DYN_LIBRARY
- USE_KDB5_LIBRARY
- USE_SS_LIBRARY
- V5_USE_SHARED_LIB
- KRB5_LIBRARIES
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/cli/cryptocard.c
diff -c /dev/null krb5/kadmin/cli/cryptocard.c:1.11
*** /dev/null	Sun Mar 16 20:22:15 2003
--- krb5/kadmin/cli/cryptocard.c	Wed Dec 11 11:08:46 2002
***************
*** 0 ****
--- 1,1575 ----
+ /*
+  * cryptocard.c - A set of routines designed to provide an interface for
+  * CRYPTOCard RB-1 challenge-response hardware.
+  *
+  * This code uses kadm5_randkey_principal() to generate a random DES key for
+  * a RB-1 token, and then prints out the necessary info in the format
+  * required by the RB-1.  This also can talk to the RB-1 token initializer
+  * for more convenient token programming, or a KF-1 token initializer (the
+  * initializer type is detected automatically).
+  */
+ 
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ #ifdef HAVE_PTY_H
+ #include <pty.h>
+ #endif
+ #include <fcntl.h>
+ #include <termios.h>
+ #include <errno.h>
+ #ifdef _AIX
+ #include <sys/ioctl.h>
+ #endif
+ 
+ #ifdef KADMIN_CRYPTOCARD
+ 
+ #include <krb5.h>
+ #include <k5-int.h>
+ #include <kadm5/admin.h>
+ 
+ struct initializer_state {
+ 	int	fd;		/* File descriptor of initializer */
+ 	int	init_type;	/* 1 = RB initializer, 0 = KF initializer */
+ 	int	card_type;	/* Type of card (see defines below */
+ 	int	rts;		/* True if RTS is currently asserted */
+ 	struct termios term;	/* Termios info about baud rate */
+ };
+ 
+ /*
+  * Defines needed for the RB-1 and KF-1 initializer
+  *
+  * First we have codes used by the LED's on the front panel.
+  */
+ 
+ #define LED_NONE	0x00	/* No LEDs on at all */
+ #define LED_RESET	0x01	/* Reset LED (really card power toggle) */
+ #define LED_INSERT	0x02	/* Insert LED on */
+ #define LED_INIT	0x04	/* Init LED on */
+ #define LED_DONE	0x08	/* Done LED on */
+ #define LED_ERROR	0x10	/* Error LED on */
+ #define LED_WARN	0x20	/* Warning LEDs on */
+ #define SOL		0x40	/* Solenoid on */
+ 
+ /*
+  * Return bits sent by the initalizer
+  */
+ 
+ #define STS_PRESENT	0x01	/* Card present */
+ #define STS_RBINIT	0x02	/* This is an RB initializer */
+ 
+ /*
+  * Extra codes used by the RB-1 card
+  */
+ 
+ #define	SCROLL_KEY	0x0b	/* Code for the SCROLL (->) key */
+ #define ENT_KEY		0x0c	/* Code for the ENT key */
+ 
+ /*
+  * Extra code needed for the KF-1 initializer
+  */
+ 
+ #define KF_RESET_CTRL	0xaf	/* Reset control for keyfob */
+ 
+ /*
+  * Offsets used by the language tables for different RB-1 responses
+  */
+ 
+ #define KEY1		0x00
+ #define KEY2		0x01
+ #define KEY3		0x02
+ #define USER_ID		0x03
+ #define NEW_PIN		0x04
+ #define VERIFY		0x05
+ #define CARD_OK		0x06
+ #define PIN		0x07
+ #define LOCKED		0x08
+ #define OPTIONS		0x09
+ 
+ /*
+  * Types of possible tokens
+  */
+ 
+ #define	TOKEN_RB1_CLASSIC	0x00
+ #define TOKEN_RB1_SMOS		0x01
+ #define TOKEN_RB3_SMOS		0x02
+ #define TOKEN_KF1_SMOS		0x03
+ #define TOKEN_KF3_SMOS		0x04
+ #define TOKEN_RB1_UMC		0x05
+ #define TOKEN_RB3_UMC		0x06
+ #define TOKEN_KF1_UMC		0x07
+ #define TOKEN_KF3_UMC		0x08
+ #define MAX_TOKEN		0x08
+ 
+ static char *token_types[] = {
+ 	"RB-1 (Classic)",
+ 	"RB-1 (SMOS)",
+ 	"RB-3 (3DES SMOS)",
+ 	"KF-1 (SMOS)",
+ 	"KF-3 (3DES SMOS)",
+ 	"RB-1 (UMC)",
+ 	"RB-3 (3DES UMC)",
+ 	"KF-1 (UMC)",
+ 	"KF-3 (UMC)",
+ };
+ 
+ #define DEFAULT_PORT	"/dev/ttya"
+ 
+ /*
+  * We need to know the responses in each possible language we use.
+  */
+ 
+ struct _language_table {
+ 	char *language_name;
+ 	int lang_code;
+ 	char *response[10];
+ } *lang_ptr, language_table[] = {
+ /*
+  * English (aka "English-1")
+  */
+ 	"english", 0, "Key1?   ", "Key2?   ", "Key3?   ", "User ID?",
+ 	"New PIN?", "Verify  ", "Card OK ", "PIN?    ", "Locked  ",
+ 	"Options?",
+ /*
+  * Alternate English ("English-2")
+  */
+ 	"english2", 1, "Key1?   ", "Key2?   ", "Key3?   ", "User ID?",
+ 	"New PSC?", "Verify  ", "Card OK ", "PSC?    ", "Locked  ",
+ 	"Options?",
+ /*
+  * French
+  */
+ 	"french", 2, "Clef1?  ", "Clef2?  ", "Clef3?  ", "Usag?  ",
+ 	"Nouveau?", "Verifier", "Correct ", "PIN?    ", "Bloqu  ",
+ 	"Options?",
+ /*
+  * German
+  */
+ 	"german", 3, "Chiffre1", "Chiffre2", "Chiffre3", "Ident. #",
+ 	"Neue PIN", "Beweise ", "Karte OK", "PIN?    ", "Gesperrt",
+ 	"Auswahl?",
+ /*
+  * Italian
+  */
+ 	"italian", 4, "Chiave1?", "Chiave2?", "Chiave3?", "ID Usare",
+ 	"Nuovo?  ", "Verifica", "Carta OK", "PIN?    ", "Chiuso  ",
+ 	"Scelta? ",
+ 
+ /*
+  * Portuguese
+  */
+ 	"portuguese", 5, "Codig1?", "Codig2?", "Codig3?", "Nr.Conta",
+ 	"Nvo PIN", "Repetir ", "Correcto", "PIN?    ", "Nulo    ",
+ 	"Opes? ",
+ 
+ /*
+  * Swedish
+  */
+ 	"swedish", 6, "Tangent1", "Tangent2", "Tangent3", "Kund-ID?",
+ 	"Ny PIN? ", "Bekrfta", "Kort OK ", "PIN?    ", "Sprrad ",
+ 	"Val?    ",
+ 
+ /*
+  * Spanish
+  */
+ 	"spanish", 7, "Clave1? ", "Clave2? ", "Clave3? ", "Ident. #",
+ 	"Nuevo?  ", "Asegurar", "Correcto", "PIN?    ", "Atascado",
+ 	"Opciones",
+ 
+ 	NULL, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ 	NULL, NULL,
+ };
+ 
+ /*
+  * Internal functions
+  */
+ 
+ static void ktadd_usage();
+ static void print_card_info(krb5_keyblock *, char *, char *, char [][4]);
+ static void initialize_card(krb5_keyblock *, char *, char *, char *,
+ 			    krb5_principal, char [][4], int);
+ static void get_options(char [4][4], int, int, int, int, int, int);
+ 
+ static int card_in(struct initializer_state *);
+ static int send_byte(struct initializer_state *, int);
+ static int send_byte_initializer(struct initializer_state *, int);
+ static int send_byte_raw(int, int);
+ static int read_byte(struct initializer_state *, unsigned char *);
+ static int read_32bits(struct initializer_state *, unsigned int *);
+ static int read_bytes(struct initializer_state *, char *);
+ static int check_card_buffer(struct initializer_state *, char *);
+ static int send_decimal(struct initializer_state *, char *);
+ static int send_octal(struct initializer_state *, char *);
+ static void send_error(struct initializer_state *);
+ static int initializer_init(struct initializer_state *);
+ 
+ /*
+  * External references needed by kadmin
+  */
+ 
+ extern char *whoami;
+ extern krb5_context context;
+ extern void *handle;
+ 
+ /*
+  * Main routine.  This is the routine called by the kadmin cli
+  */
+ 
+ void
+ kadmin_ktadd_cryptocard(int argc, char **argv)
+ {
+ 	krb5_principal princ = NULL;
+ 	krb5_keyblock *keys, *key;
+ 	krb5_error_code retval;
+ 	int initializer = 0, nkeys = 0, i;
+ 	char options[4][4];
+ 	char *user = NULL;
+ 	char *port = NULL;
+ 	char *initial_pin = "1111";
+ 	int minimum_length = 4;
+ 	int language = -1;
+ 	int tries = -1;
+ 	int single = 0;
+ 	int no_userid = 0;
+ 	int non_changeable = 0;
+ 
+ 	/*
+ 	 * Perform basic argument parsing
+ 	 */
+ 
+ 	argc--; argv++;
+ 
+ 	while (argc) {
+ 		if (strncmp(*argv, "-i", 2) == 0) {
+ 			initializer++;
+ 		} else if (strncmp(*argv, "-u", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc || user) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			if (no_userid) {
+ 				fprintf(stderr, "Both -u and -U are not "
+ 					"permitted\n");
+ 				return;
+ 			}
+ 			user = *argv;
+ 		} else if (strncmp(*argv, "-d", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc || port) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			port = *argv;
+ 		} else if (strncmp(*argv, "-p", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			initial_pin = *argv;
+ 		} else if (strncmp(*argv, "-n", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc || atoi(*argv) == 0) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			minimum_length = atoi(*argv);
+ 			if (minimum_length < 3 || minimum_length > 8) {
+ 				fprintf(stderr, "Minimum PIN length must be "
+ 					"between 3 and 8 characters\n");
+ 				return;
+ 			}
+ 			if (minimum_length == 8)
+ 				minimum_length = 0;
+ 		} else if (strncmp(*argv, "-l", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc || language != -1) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			for (lang_ptr = language_table;
+ 				      lang_ptr->lang_code != -1; lang_ptr++)
+ 				if (!strcmp(*argv, lang_ptr->language_name)) {
+ 					language = lang_ptr->lang_code;
+ 					break;
+ 				}
+ 			if (language == -1) {
+ 				fprintf(stderr, "Invalid language: "
+ 					"\"%s\"\n", *argv);
+ 				return;
+ 			}
+ 		} else if (strncmp(*argv, "-t", 2) == 0) {
+ 			argc--; argv++;
+ 			if (! argc || tries != -1) {
+ 				ktadd_usage();
+ 				return;
+ 			}
+ 			tries = atoi(*argv);
+ 			if (tries < 0 || minimum_length > 7) {
+ 				fprintf(stderr, "Number of PIN tries must be "
+ 					"between 0 and 7\n");
+ 				return;
+ 			}
+ 		} else if (strncmp(*argv, "-U", 2) == 0) {
+ 			if (user) {
+ 				fprintf(stderr, "Both -u and -U are not "
+ 					"permitted\n");
+ 				return;
+ 			}
+ 			no_userid++;
+ 		} else if (strncmp(*argv, "-s", 2) == 0) {
+ 			single++;
+ 		} else if (strncmp(*argv, "-P", 2) == 0) {
+ 			non_changeable++;
+ 		} else	
+ 			break;
+ 		argc--; argv++;
+ 	}
+ 
+ 	if (argc != 1) {
+ 		ktadd_usage();
+ 		return;
+ 	}
+ 
+ 	if (language == -1)
+ 		language = 0;
+ 
+ 	if (tries == -1)
+ 		tries = 0;
+ 
+ 	if (! port && ! (port = getenv("CRYPTOCARD_PORT")))
+ 		port = DEFAULT_PORT;
+ 
+ 	if ((retval = krb5_parse_name(context, argv[0], &princ))) {
+ 		com_err(whoami, retval, "while parsing principal name %s",
+ 			argv[0]);
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * Get a new key for the specified principal.  Note that this
+ 	 * will destroy the current key (I think that it's probably better
+ 	 * to do this checking before we try talking to the initializer)
+ 	 */
+ 
+ 	if ((retval = kadm5_randkey_principal(handle, princ, &keys, &nkeys))) {
+ 		if (retval == KADM5_UNK_PRINC) {
+ 			fprintf(stderr, "%s: Principal %s does not exist.\n",
+ 				whoami, argv[0]);
+ 		} else
+ 			com_err(whoami, retval, "while getting new key for %s",
+ 				argv[0]);
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * The RB-1 can only handle a DES key, so make sure we got one
+ 	 */
+ 
+ 	for (i = 0; i < nkeys; i++) {
+ 		if (keys[i].enctype == ENCTYPE_DES_CBC_CRC ||
+ 		    keys[i].enctype == ENCTYPE_DES_CBC_MD4 ||
+ 		    keys[i].enctype == ENCTYPE_DES_CBC_MD5 ||
+ 		    keys[i].enctype == ENCTYPE_DES_CBC_RAW) {
+ 			key = &keys[i];
+ 			break;
+ 		}
+ 	}
+ 
+ 	if (key == NULL) {
+ 		fprintf(stderr, "%s: No DES key found for principal %s",
+ 			whoami, argv[0]);
+ 		return;
+ 	}
+ 
+ 	get_options(options, minimum_length, language, tries, no_userid,
+ 		    single, non_changeable);
+ 
+ 	if (!user && !no_userid)
+ 		user = krb5_princ_name(context, princ)->data;
+ 
+ 	if (!initializer) {
+ 		print_card_info(key, initial_pin, user, options);
+ 	} else {
+ 		initialize_card(key, initial_pin, user, port, princ, options,
+ 				language);
+ 	}
+ 
+ cleanup:
+ 	if (nkeys) {
+ 		for (i = 0; i < nkeys; i++)
+ 			krb5_free_keyblock_contents(context, &keys[i]);
+ 		free(keys);
+ 	}
+ 	if (princ)
+ 		krb5_free_principal(context, princ);
+ 
+ 	return;
+ }
+ 
+ /*
+  * Print out all of the stuff a human needs to program the card
+  */
+ 
+ static void
+ print_card_info(krb5_keyblock *key, char *pin, char *userid, char options[][4])
+ {
+ 	krb5_error_code retval;
+ 	int i;
+ 	char inputblock[8], outputblock[8];
+ 	krb5_data tmp_data;
+ 	krb5_enc_data tmp_enc_data;
+ 
+ 	printf("Token programming sequence:\n");
+ 	printf("\t225371 after power-on for administrative reset\n");
+ 	printf("After \"Locked\" prompt, press ENT for \"Options?\" prompt\n");
+ 
+ 	printf("\tOptions are:\n");
+ 	printf("\t\t%s -> %s -> %s -> ENT\n", options[0], options[1],
+ 	       options[2]);
+ 	
+ 	/*
+ 	 * Note that the encryption key has to be printed in octal
+ 	 */
+ 
+ 	printf("\tEncryption key:\n\t\t");
+ 
+ 	for (i = 0; i < 8; i++)
+ 		printf("%03o -> ", (unsigned char) key->contents[i]);
+ 
+ 	printf("ENT\n");
+ 
+ 	/*
+ 	 * The RB-1 prints the output of using the encryption block
+ 	 * on all zero's - calculate that and print it out as a
+ 	 * check against data entry errors
+ 	 */
+ 
+ 	memset(inputblock, 0, 8);
+ 
+ 	/* We need to use CBC_RAW to avoid the CRC junk */
+ 
+ 	key->enctype = ENCTYPE_DES_CBC_RAW;
+ 
+ 	tmp_data.data = (char *)&inputblock;
+ 	tmp_data.length = sizeof(inputblock);
+ 
+ 	memset(&tmp_enc_data, 0, sizeof(tmp_enc_data));
+ 	tmp_enc_data.ciphertext.data = (char *)&outputblock;
+ 	tmp_enc_data.ciphertext.length = sizeof(outputblock);
+ 
+ 	retval = krb5_c_encrypt(context, key, /* Usage = 0 */ 0, NULL,
+ 			&tmp_data, &tmp_enc_data);
+ 		
+ 	if (retval) {
+ 	   com_err(whoami, retval, "while processing RB-1 key for key test");
+ 	   return;
+ 	}
+ 
+ 	printf("\tResults of key encryption using binary NULs (press ENT to\n\taccept, CLR to reenter)\n\t\t");
+ 
+ 	for (i = 0; i < 4; i++)
+ 		printf("%02X", (unsigned char) outputblock[i]);
+ 	printf("\n");
+ 
+ 	/*
+ 	 * Because the userid needs to input in octal, print that out
+ 	 * as well
+ 	 */
+ 
+ 	printf("\tUser id:\n\t\t");
+ 
+ 	for (i = 0; (i < 8) && (userid[i] != 0); i++)
+ 		printf("%03o -> ", (unsigned char) userid[i]);
+ 
+ 	for (; i < 8; i++) {
+ 		printf("%03o -> ", ' ');
+ 	}
+ 
+ 	printf("ENT\n");
+ 
+ 	printf("\tASCII format userid (press ENT to accept, CLR to reenter):\n");
+ 	printf("\t\t%s\n", userid);
+ 
+ 	printf("\tInitial PIN:\n\t\t%s\n", pin);
+ 
+ }
+ 
+ /*
+  * Program a card using the RB Initializer hardware
+  *
+  * This box works in the following way:
+  *
+  * When RTS is asserted, you are talking to the initializer box itself.
+  * In this mode, each command is a byte, and controls what you want to
+  * do to the box.  You basically have a choice between lighting any
+  * of the four front LEDs, or engaging the box solenoid (which brings the
+  * initializer in contact with the contacts on the RB-1, and is required
+  * to do further programming).
+  *
+  * You get back a status byte after every command which has the low bit
+  * set if a card is inserted.
+  *
+  * Note that the so-called RESET LED seems to actually be wired to the
+  * on/off switch on the RB-1.  Engaging that will toggle the card on
+  * or off, depending on the card's current state.
+  *
+  * When RTS is deasserted, you are talking to the card itself.  In this
+  * mode characters you sent are equivalant to being entered in on the
+  * front panel.  You can send a number (which is done by sending bytes
+  * 0x00 - 0x09 to indicate digits 0-9), the ASCII character VT (0x0b),
+  * which is equivalant to the "->" key on the old RB1 cards, and the
+  * ASCII character NL (0x0a), which is equivalant th the ENT key.
+  * Thee data you get back in this mode is whatever is printed on the
+  * LCD display.  To converse with the card you simulate everything you
+  * would normally type on the front panel, and read back the results
+  * in ASCII.
+  *
+  * Newer RB1 tokens cannot be programmed via the front panel, but the
+  * programming sequence is mostly the same.
+  *
+  * This is mostly similar to the KF initializer process, except that:
+  *
+  * - There is no solenoid or warning lights
+  * - You talk to the card at 600 baud
+  * - We can't turn the card on
+  * 
+  */
+ 
+ static void
+ initialize_card(krb5_keyblock *key, char *pin, char *userid, char *port,
+ 		krb5_principal princ, char options[][4], int language)
+ {
+ 	char *admincode = "225371";
+ 	char *statuscode = "225374";
+ 	char *serialcode = "225375";
+ 	int fd = -1, i;
+ 	int linkflag = 0, lstate;
+ 	unsigned int cardtype;
+ 	char adminbuf[17], serialnum[10], inputbuf[9];
+ 	unsigned char inputblock[8], outputblock[8], testbytes[9], keybyte[4];
+ 	krb5_error_code retval;
+ 	struct initializer_state state;
+ 	krb5_data tmp_data;
+ 	krb5_enc_data tmp_enc_data;
+ 
+ 	/*
+ 	 * Start by opening up the terminal device and initializing
+ 	 * it to what we need (2400 baud, 8N1)
+ 	 */
+ 
+ 	if ((fd = open(port, O_RDWR | O_NONBLOCK)) < 0) {
+ 		com_err(whoami, errno, "while opening terminal device %s",
+ 			port);
+ 		goto cleanup;
+ 	}
+ 
+ 	state.fd = fd;
+ 
+ 	/*
+ 	 * Set up the initializer.
+ 	 */
+ 
+ 	if (initializer_init(&state) == -1)
+ 		goto cleanup;
+ 
+ 	/*
+ 	 * Okay!  The port's all ready, so let's start talking ...
+ 	 */
+ 
+ 	if ((lstate = card_in(&state)) < 1) {
+ 		if (lstate < 0) {
+ 			fprintf(stderr, "We were unable to find a initializer "
+ 				"on port %s\n", port);
+ 			goto cleanup;
+ 		} else {
+ 			printf("Please insert the CRYPTOCard into the "
+ 			       "initializer\n");
+ 			while (! card_in(&state));
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * Alright, we've (supposedly) got a card in the initializer.
+ 	 * First off, let's engage the solenoid, and try turning the
+ 	 * card on by toggling the RESET LED.
+ 	 */
+ 
+ 	printf("Attempting to probe card type ...\n");
+ 
+ 	sleep(1);	/* Not sure if it's necessary, but their code
+ 			   does it ... */
+ 
+ 	if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 		fprintf(stderr, "Communication with initializer failed during "
+ 			"card link-up\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * We're not sure if the card is on or off at this stage.  LED_RESET
+ 	 * toggles power, so toggle this once and check to see if the
+ 	 * card is on.  If it's not, try again, because the card might
+ 	 * have been on when it was placed in the initializer (and if
+ 	 * that doesn't work, then fail)
+ 	 */
+ 
+ 	for (i = 0; i < 2 ; i++) {
+ 
+ 		if (state.init_type == 1) {
+ 			if (send_byte_initializer(&state, SOL | LED_RESET |
+ 						  LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 			sleep(1);
+ 			if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 		} else {
+ 			/*
+ 			 * For the KF initializer, we need to send the reset
+ 			 * control message
+ 			 */
+ 			
+ 			send_byte(&state, KF_RESET_CTRL);
+ 		}
+ 
+ 		/*
+ 		 * We get 8 spaces at power-on/reset
+ 		 */
+ 
+ 		lstate = check_card_buffer(&state, "        ");
+ 		if (lstate < 0) {
+ 			fprintf(stderr, "Unable to communicate with card "
+ 				"during card probe\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		if (!lstate)
+ 			continue;
+ 
+ 		if (! send_decimal(&state, statuscode)) {
+ 			fprintf(stderr, "Unable to communicate with card "
+ 				"during card probe\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		if (read_32bits(&state, &cardtype) != 0) {
+ 			fprintf(stderr, "Unable to read first status word "
+ 				"during card probe\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		send_byte(&state, ENT_KEY);
+ 
+ 		if (read_32bits(&state, &cardtype) != 0) {
+ 			fprintf(stderr, "Unable to read second status word "
+ 				"during card probe\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		send_byte(&state, ENT_KEY);
+ 
+ 		if (read_32bits(&state, &cardtype) != 0) {
+ 			fprintf(stderr, "Unable to read third status word "
+ 				"during card probe\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		cardtype = (cardtype >> 28) & 0xf;
+ 
+ 		linkflag = 1;
+ 
+ 		if (cardtype == TOKEN_RB1_UMC) {
+ 			if (send_byte_initializer(&state, SOL | LED_RESET |
+ 						  LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"reset\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 			sleep(1);
+ 			if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"reset\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 			sleep(1);
+ 			if (send_byte_initializer(&state, SOL | LED_RESET |
+ 						  LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"reset\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 			sleep(1);
+ 			if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 				fprintf(stderr, "Communication with "
+ 					"initializer failed during card "
+ 					"reset\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 
+ 			lstate = check_card_buffer(&state, "        ");
+ 			if (lstate < 0) {
+ 				fprintf(stderr, "Unable to communicate with "
+ 					"card during version probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 			if (! send_decimal(&state, serialcode)) {
+ 				fprintf(stderr, "Unable to communicate with "
+ 					"card during version probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 
+ 			if (read_bytes(&state, inputbuf) != 0) {
+ 				fprintf(stderr, "Unable to read first "
+ 					"status word during version probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 
+ 			memcpy(serialnum, inputbuf + 1, 2);
+ 
+ 			send_byte(&state, ENT_KEY);
+ 
+ 			if (read_bytes(&state, inputbuf) != 0) {
+ 				fprintf(stderr, "Unable to read second "
+ 					"status word during version probe\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 
+ 			memcpy(serialnum + 2, inputbuf + 1, 7);
+ 
+ 			serialnum[9] = '\0';
+ 
+ 			printf("Card detected: %s, S/N %s\n",
+ 			       token_types[cardtype], serialnum);
+ 		} else {
+ 			printf("Card detected: %s\n", token_types[cardtype]);
+ 		}
+ 
+ 		break;
+ 	}
+ 
+ 	if (! linkflag) {
+ 		fprintf(stderr, "Unable to link up with CRYPTOCard\n");
+ 		if (state.init_type == 0)
+ 			fprintf(stderr, "Was the key fob turned on?\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	if (cardtype != TOKEN_RB1_CLASSIC && cardtype != TOKEN_KF1_SMOS &&
+ 	    cardtype != TOKEN_KF3_SMOS && cardtype != TOKEN_RB1_UMC) {
+ 		fprintf(stderr, "This card is currently not supported\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	printf("Connected to CRYPTOCard %s, starting download\n",
+ 	       state.init_type == 1 ? "RB-1" : "KF-1");
+ 
+ 	/*
+ 	 * First we need to reset the card.  For the RB-1 programmer,
+ 	 * toggle the RESET line.  For the KF-1, send the reset code.
+ 	 *
+ 	 * Because of what we did up above, the RB-1 should already be
+ 	 * turned on.
+ 	 */
+ 
+ 	if (state.init_type == 1) {
+ 		if (send_byte_initializer(&state, SOL | LED_RESET |
+ 					  LED_WARN) < 0) {
+ 			fprintf(stderr, "Communication with "
+ 				"initializer failed during card reset\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 		sleep(1);
+ 		if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 			fprintf(stderr, "Communication with "
+ 				"initializer failed during card reset\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 		sleep(1);
+ 		if (send_byte_initializer(&state, SOL | LED_RESET |
+ 					  LED_WARN) < 0) {
+ 			fprintf(stderr, "Communication with "
+ 				"initializer failed during card reset\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 		sleep(1);
+ 		if (send_byte_initializer(&state, SOL | LED_WARN) < 0) {
+ 			fprintf(stderr, "Communication with "
+ 				"initializer failed during card reset\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	} else
+ 		send_byte(&state, KF_RESET_CTRL);
+ 
+ 	lstate = check_card_buffer(&state, "        ");
+ 	if (lstate < 0) {
+ 		fprintf(stderr, "Unable to communicate with card "
+ 			"during card reset\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	if (! send_decimal(&state, admincode)) {
+ 		fprintf(stderr, "Unable to communicate with card "
+ 			"during card reset\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	strcpy(adminbuf, "        ");
+ 	strcat(adminbuf, language_table[0].response[LOCKED]);
+ 
+ 	lstate = check_card_buffer(&state, adminbuf);
+ 
+ 	if (lstate < 0) {
+ 		fprintf(stderr, "Unable to communicate with card "
+ 		"during card reset\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	if (lstate != 1) {
+ 		fprintf(stderr, "Unable to reset card\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	send_byte_initializer(&state, SOL | LED_WARN | LED_INIT);
+ 
+ 	/*
+ 	 * Okay, the card is in, and we're talking to it.  Start downloading
+ 	 * everything we need.
+ 	 *
+ 	 * First, get out of the "Locked" state
+ 	 */
+ 
+ 	if (send_byte(&state, ENT_KEY) < 1) {
+ 		fprintf(stderr, "CRYPTOCard not responding\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * See if we've got an "Options?" prompt.
+ 	 */
+ 
+ 	if (check_card_buffer(&state,
+ 		      language_table[0].response[OPTIONS]) < 1) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"options programming\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	/* 
+ 	 * Send all of our options
+ 	 */
+ 
+ 	for (i = 0; i < 3; i++) {
+ 		if (! send_octal(&state, options[i])) {
+ 			fprintf(stderr, "No response from CRYPTOCard during "
+ 				"options programming\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	}
+ 
+ 	if (cardtype == TOKEN_RB1_UMC) {
+ 		if (! send_octal(&state, "000")) {
+ 			fprintf(stderr, "No response from CRYPTOCard during "
+ 				"options programming\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	}
+ 
+ 	send_byte(&state, ENT_KEY);
+ 
+ 	/*
+ 	 * Send encryption key
+ 	 */
+ 
+ 	if (check_card_buffer(&state,
+ 			language_table[language].response[KEY1]) < 1) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"key programming\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	for (i = 0; i < 8; i++) {
+ 		sprintf((char *) keybyte, "%03o", key->contents[i]);
+ 		if (! send_octal(&state, (char *) keybyte)) {
+ 			fprintf(stderr, "No response from CRYPTOCard during "
+ 				"key programming\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * Send the ENTER key, and then check the reponse to make sure
+ 	 * it is correct (the CRYPTOCard encrypts a buffer of all
+ 	 * NULs and displays the upper 4 bytes as a check).
+ 	 */
+ 
+ 	send_byte(&state, ENT_KEY);
+ 
+ 	memset(inputblock, 0, 8);
+ 
+ 	/* We need to use CBC_RAW to avoid the CRC junk */
+ 
+ 	key->enctype = ENCTYPE_DES_CBC_RAW;
+ 	memset(&tmp_enc_data, 0, sizeof(tmp_enc_data));
+ 
+ 	tmp_data.data = (char *) &inputblock;
+ 	tmp_data.length = sizeof(inputblock);
+ 
+ 	tmp_enc_data.ciphertext.data = (char *) &outputblock;
+ 	tmp_enc_data.ciphertext.length = sizeof(outputblock);
+ 
+ 	if ((retval = krb5_c_encrypt(context, key, /* Usage = 0 */ 0, NULL,
+ 				     &tmp_data, &tmp_enc_data))) {
+ 		com_err(whoami, retval, "while encrypting key test data");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	for (i = 0; i < 4; i++)
+ 		sprintf((char *) &testbytes[i*2], "%02X", outputblock[i]);
+ 
+ 	if (check_card_buffer(&state, (char *) testbytes) < 1) {
+ 		fprintf(stderr, "Key test response did not match computed "
+ 			"result (%.8s)\n", testbytes);
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	send_byte(&state, ENT_KEY);
+ 
+ 	/*
+ 	 * Time to send the userid (not to a KF-1, though)
+ 	 */
+ 
+ 	if (cardtype != TOKEN_KF1_SMOS && cardtype != TOKEN_KF3_SMOS &&
+ 	    userid != NULL) {
+ 		if (check_card_buffer(&state,
+ 			     language_table[language].response[USER_ID]) < 1) {
+ 			fprintf(stderr, "No response from CRYPTOCard during "
+ 				"UserID programming\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		for (i = 0; i < 8 && userid[i] != 0; i++) {
+ 			sprintf((char *) keybyte, "%03o",
+ 						(unsigned char) userid[i]);
+ 			testbytes[i] = userid[i];
+ 			if (! send_octal(&state, (char *) keybyte)) {
+ 				fprintf(stderr, "No response from CRYPTOCard "
+ 					"during UserID programming\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 		}
+ 
+ 		for (; i < 8; i++) {
+ 			testbytes[i] = 0x20;
+ 			if (! send_octal(&state, "040")) {
+ 				fprintf(stderr, "No response from CRYPTOCard "
+ 					"during UserID programming\n");
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 		}
+ 
+ 		send_byte(&state, ENT_KEY);
+ 
+ 		if (check_card_buffer(&state, (char *) testbytes) < 1) {
+ 			fprintf(stderr, "Userid test response did not "
+ 				"match expected result\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		send_byte(&state, ENT_KEY);
+ 	}
+ 
+ 	/*
+ 	 * Last, but not least, we need to send a PIN
+ 	 */
+ 
+ 	if (check_card_buffer(&state,
+ 			language_table[language].response[NEW_PIN]) < 1) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"PIN programming\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	if (! send_decimal(&state, pin)) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"PIN programming\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	send_byte(&state, ENT_KEY);
+ 
+ 	if (check_card_buffer(&state,
+ 			language_table[language].response[VERIFY]) < 1) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"PIN verification\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	if (! send_decimal(&state, pin)) {
+ 		fprintf(stderr, "No response from CRYPTOCard during "
+ 			"PIN verification\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	send_byte(&state, ENT_KEY);
+ 
+ 	/*
+ 	 * We should get a CARD_OK message now
+ 	 */
+ 
+ 	if (check_card_buffer(&state,
+ 			language_table[language].response[CARD_OK]) < 1) {
+ 		fprintf(stderr, "Did not get final OK message from RB-1\n");
+ 		send_error(&state);
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * If we have a UMC card, check for a final bit.
+ 	 */
+ 	
+ 	if (cardtype == TOKEN_RB1_UMC) {
+ 
+ 		send_byte(&state, ENT_KEY);
+ 
+ 		if (check_card_buffer(&state,
+ 			      language_table[language].response[PIN]) < 1) {
+ 			fprintf(stderr, "Did not get PIN? message from RB-1\n");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	}
+ 
+ 	/*
+ 	 * Note that for the key fob tokens (and the UMC "new" RB1 tokens),
+ 	 * we need to program in the correct "next challenge" into the
+ 	 * database so the KDC can do the right thing.
+ 	 */
+ 
+ 	if (cardtype == TOKEN_KF1_SMOS || cardtype == TOKEN_KF3_SMOS ||
+ 	    cardtype == TOKEN_RB1_UMC) {
+ 		kadm5_principal_ent_rec princrec;
+ 		krb5_tl_data *tl, *tl_tail = NULL;
+ 		unsigned char challenge[8];
+ 
+ 		if ((retval = kadm5_get_principal(handle, princ, &princrec,
+ 						  KADM5_PRINCIPAL |
+ 						  KADM5_TL_DATA))) {
+ 			com_err(whoami, retval, "while retrieving princ "
+ 				"data for initial challenge");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 
+ 		for (tl = princrec.tl_data; tl != NULL; tl_tail = tl,
+ 							tl = tl->tl_data_next)
+ 			if (tl->tl_data_type == KRB5_TL_RB1_CHALLENGE)
+ 				break;
+ 		
+ 		if (tl == NULL) {
+ 			tl = (krb5_tl_data *) malloc(sizeof(krb5_tl_data));
+ 			if (tl != NULL)
+ 				tl->tl_data_contents =
+ 						malloc(sizeof(challenge));
+ 			if (tl == NULL || tl->tl_data_contents == NULL) {
+ 				com_err(whoami, retval, "while allocating "
+ 					"memory for new challenge");
+ 				kadm5_free_principal_ent(handle, &princrec);
+ 				send_error(&state);
+ 				goto cleanup;
+ 			}
+ 
+ 			if (tl_tail == NULL) {
+ 				princrec.tl_data = tl;
+ 				princrec.n_tl_data = 1;
+ 				tl->tl_data_next = NULL;
+ 			} else {
+ 				tl->tl_data_next = tl_tail->tl_data_next;
+ 				tl_tail->tl_data_next = tl;
+ 				princrec.n_tl_data++;
+ 			}
+ 
+ 			tl->tl_data_type = KRB5_TL_RB1_CHALLENGE;
+ 			tl->tl_data_length = sizeof(challenge);
+ 		}
+ 
+ 		for (i = 0; i < 8; i++) {
+ 			tl->tl_data_contents[i] = (outputblock[i] & 0x0f)|0x30;
+ 			if (tl->tl_data_contents[i] > 0x39)
+ 				tl->tl_data_contents[i] -= 10;
+ 		}
+ 
+ 		retval = kadm5_modify_principal(handle, &princrec,
+ 						KADM5_TL_DATA);
+ 		
+ 		kadm5_free_principal_ent(handle, &princrec);
+ 
+ 		if (retval) {
+ 			com_err(whoami, retval, "while storing princ "
+ 				"data for initial challenge");
+ 			send_error(&state);
+ 			goto cleanup;
+ 		}
+ 	}
+ 
+ 	printf("CRYPTOCard programming successful!\n");
+ 
+ 	send_byte_initializer(&state, LED_DONE);
+ 
+ 
+ cleanup:
+ 	if (fd != -1)
+ 		close(fd);
+ 
+ 	return;
+ }
+ 
+ 
+ 
+ /*
+  * Find out if there is a card inserted into the initializer
+  */
+ 
+ static int
+ card_in(struct initializer_state *state)
+ {
+ 	int retval;
+ 
+ 	retval = send_byte_initializer(state, LED_INSERT);
+ 
+ 	if (retval == -1)
+ 		return -1;
+ 	
+ 	/*
+ 	 * If we got something back, the low bit will be set if there's
+ 	 * a card in the initializer (I don't know what the other status
+ 	 * bits mean)
+ 	 */
+ 	
+ 	return retval & 0x01;
+ }
+ 
+ /*
+  * Send a byte to the RB-1/KF-1 CRYPTOCard
+  */
+ 
+ static int send_byte(struct initializer_state *state, int byte) {
+ 
+ 	int rstate;
+ 
+ 	if (state->init_type == 0 && cfgetispeed(&state->term) != B600) {
+ 		cfsetispeed(&state->term, B600);
+ 		cfsetospeed(&state->term, B600);
+ 		if (tcsetattr(state->fd, TCSAFLUSH, &state->term) < 0)
+ 			return -1;
+ 	}
+ 
+ 	if (state->rts) {
+ 		rstate = TIOCM_RTS;
+ 		if (ioctl(state->fd, TIOCMBIC, &rstate) < 0)
+ 			return -1;
+ 		state->rts = 0;
+ 	}
+ 
+ 	return send_byte_raw(state->fd, byte);
+ }
+ 
+ /*
+  * Send a raw byte to the card/initializer
+  */
+ 
+ static int
+ send_byte_raw(int fd, int byte) {
+ 	unsigned char data = byte;
+ 
+ 	return write(fd, &data, 1);
+ }
+ 
+ /*
+  * Read a byte from the CryptoCARD
+  */
+ 
+ static int
+ read_byte(struct initializer_state *state, unsigned char *data)
+ {
+ 	int rstate;
+ 
+ 	if (state->init_type == 0 && cfgetispeed(&state->term) != B600) {
+ 		cfsetispeed(&state->term, B600);
+ 		cfsetospeed(&state->term, B600);
+ 		if (tcsetattr(state->fd, TCSAFLUSH, &state->term) < 0)
+ 			return -1;
+ 	}
+ 
+ 	if (state->rts) {
+ 		rstate = TIOCM_RTS;
+ 		if (ioctl(state->fd, TIOCMBIC, &rstate) < 0)
+ 			return -1;
+ 		state->rts = 0;
+ 	}
+ 
+ 	return read(state->fd, (void *) data, 1);
+ }
+ 
+ /*
+  * Send a byte to the RB Initializer hardware itself (by asserting RTS)
+  */
+ 
+ static int
+ send_byte_initializer(struct initializer_state *state, int byte)
+ {
+ 	int rstate, n;
+ 	unsigned char data;
+ 
+ 	if (cfgetispeed(&state->term) != B2400) {
+ 		cfsetispeed(&state->term, B2400);
+ 		cfsetospeed(&state->term, B2400);
+ 		if (tcsetattr(state->fd, TCSAFLUSH, &state->term) < 0)
+ 			return -1;
+ 	}
+ 
+ 	if (!state->rts) {
+ 		rstate = TIOCM_RTS;
+ 		if (ioctl(state->fd, TIOCMBIS, &rstate) < 0)
+ 			return -1;
+ 		state->rts = 1;
+ 	}
+ 	
+ 	n = send_byte_raw(state->fd, byte);
+ 
+ 	if (n != 1)
+ 		return -1;
+ 	
+ 	n = read(state->fd, &data, 1);
+ 
+ 	if (n != 1)
+ 		return -1;
+ 	
+ 	return data;
+ }
+ 
+ /*
+  * Receive a buffer from the card, and see if it's what we were expecting
+  */
+ 
+ static int
+ check_card_buffer(struct initializer_state *state, char *buffer)
+ {
+ 	char *newbuf;
+ 	int length = strlen(buffer), i, cc;
+ 
+ 	newbuf = malloc(length + 1);
+ 
+ 	if (newbuf == NULL)
+ 		return -1;
+ 	
+ 	for (i = 0; i < length; i++) {
+ 		cc = read_byte(state, (unsigned char *) &newbuf[i]);
+ 		if (cc < 1) {
+ 			free(newbuf);
+ 			return 0;
+ 		}
+ 	}
+ 
+ 	if (strncmp(newbuf, buffer, length) == 0) {
+ 		free(newbuf);
+ 		return 1;
+ 	} else {
+ 		free(newbuf);
+ 		return 0;
+ 	}
+ }
+ 
+ /*
+  * Receive a 32-bit integer from the card
+  */
+ 
+ static int
+ read_32bits(struct initializer_state *state, unsigned int *result)
+ {
+ 	int rstate, i;
+ 	unsigned char byte;
+ 
+ 	*result = 0;
+ 
+ 	for (i = 0; i < 8; i++) {
+ 		if (read_byte(state, &byte) != 1)
+ 			return -1;
+ 		if (byte >= '0' && byte <= '9')
+ 			byte -= '0';
+ 		else if (byte >= 'A' && byte <= 'F')
+ 			byte -= 'A' - 10;
+ 		else
+ 			return -1;
+ 		*result = (*result << 4) + (byte & 0xf);
+ 	}
+ 
+ 	return 0;
+ }
+ 
+ /*
+  * Read a character buffer from the card
+  */
+ 
+ static int
+ read_bytes(struct initializer_state *state, char *result)
+ {
+ 	int i;
+ 
+ 	for (i = 0; i < 8; i++)
+ 		if (read_byte(state, (unsigned char *) result + i) != 1)
+ 			return -1;
+ 	
+ 	return 0;
+ }
+ 
+ /*
+  * Send a decimal string to the CRYPTOCard
+  */
+ 
+ static int
+ send_decimal(struct initializer_state *state, char *buffer)
+ {
+ 	int i, cc;
+ 
+ 	for (i = 0; i < strlen(buffer); i++) {
+ 		cc = send_byte(state, (unsigned char) (buffer[i] - '0'));
+ 		if (cc < 1)
+ 			return 0;
+ 	}
+ 
+ 	return 1;
+ }
+ 
+ /*
+  * Send an octal string (with SCROLL key) to the CRYPTOCard
+  */
+ 
+ static int
+ send_octal(struct initializer_state *state, char *buffer)
+ {
+ 	int i;
+ 	char data;
+ 
+ 	for (i = 0; i < 3; i++) {
+ 		if (send_byte(state, (unsigned char) (buffer[i] - '0')) < 1)
+ 			return 0;
+ 		read(state->fd, &data, 1);
+ 	}
+ 
+ 	if (send_byte(state, SCROLL_KEY) < 1)
+ 		return 0;
+ 	
+ 	read(state->fd, &data, 1);
+ 
+ 	return 1;
+ }
+ 
+ /*
+  * Light error light, and return
+  */
+ 
+ static void
+ send_error(struct initializer_state *state)
+ {
+ 	send_byte_initializer(state, LED_ERROR);
+ }
+ 
+ /*
+  * Set up initializer the first time
+  */
+ 
+ static int
+ initializer_init(struct initializer_state *state)
+ {
+ 	int lstate;
+ 
+ 	if (tcgetattr(state->fd, &state->term) < 0) {
+ 		com_err(whoami, errno, "while getting terminal attributes");
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * Sigh, you think after doing this so many times, I'd remember it
+ 	 * all ...
+ 	 */
+ 
+ #ifdef _AIX
+ 	state->term.c_cflag &= ~(CSIZE | PARENB);
+ #elif sgi
+ 	state->term.c_cflag &= ~(CSIZE | PARENB | CNEW_RTSCTS);
+ #else
+ 	state->term.c_cflag &= ~(CSIZE | PARENB | CRTSCTS);
+ #endif /* sgi && AIX */
+ 	state->term.c_cflag |= CS8 | CLOCAL | CREAD;
+ 	state->term.c_oflag &= ~(OPOST);
+ 	state->term.c_lflag = 0;
+ 	state->term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | IXOFF);
+ 	state->term.c_iflag |= IGNBRK | IGNCR;
+ 	state->term.c_cc[VMIN] = 0;	/* 0 character minimum (this is for a reason! */
+ 	state->term.c_cc[VTIME] = 20;	/* 1 second timeout */
+ 
+ 	cfsetispeed(&state->term, B2400);	/* 2400 baud */
+ 	cfsetospeed(&state->term, B2400);	/* 2400 baud */
+ 
+ 	if (tcsetattr(state->fd, TCSAFLUSH, &state->term) < 0) {
+ 		com_err(whoami, errno, "while setting terminal attributes");
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * Clear RTS and DTR lines (they have special meaning)
+ 	 */
+ 
+ 	lstate = TIOCM_RTS | TIOCM_DTR;
+ 	if (ioctl(state->fd, TIOCMBIC, &lstate) < 0) {
+ 		com_err(whoami, errno, "while clearing DTR and RTS");
+ 		goto cleanup;
+ 	}
+ 
+ 	/*
+ 	 * We really don't want non-blocking (but we need it so the open
+ 	 * doesn't hang if CD isn't asserted)
+ 	 */
+ 
+ 	lstate = fcntl(state->fd, F_GETFL, 0);
+ 	lstate &= ~O_NONBLOCK;
+ 	fcntl(state->fd, F_SETFL, lstate);
+ 
+ 	state->rts = 0;
+ 
+ 	/*
+ 	 * Send a byte to the initializer to determine if this is a KF
+ 	 * initializer or not
+ 	 */
+ 
+ 	if ((lstate = send_byte_initializer(state, 0x00)) < 0) {
+ 		fprintf(stderr, "Unable to probe initializer\n");
+ 		goto cleanup;
+ 	}
+ 	
+ 	if (lstate & STS_RBINIT)
+ 		state->init_type = 1;
+ 	else
+ 		state->init_type = 0;
+ 
+ 	return 0;
+ cleanup:
+ 	return -1;
+ }
+ 
+ /*
+  * Get option strings based on our inputs
+  */
+ 
+ static void
+ get_options(char options[4][4], int length, int language, int tries,
+ 	    int no_userid, int single, int non_changeable)
+ {
+ 	/*
+ 	 * Always default to normal/hex display & PIN entry feedback (but set
+ 	 * PIN changeability and single entry here)
+ 	 */
+ 
+ 	sprintf(options[0], "%03o", ((non_changeable ? 3 : 1) << 6) +
+ 		((single ? 1 : 0) << 5) + 0 /* 0 as placeholder */ );
+ 
+ 	/*
+ 	 * Default to Event-Synchronous (QuickLog), selectable number
+ 	 * of attempts allowed, and selectable minimum PIN length
+ 	 */
+ 
+ 	sprintf(options[1], "%03o", ((no_userid ? 2 : 3) << 6) +
+ 		(tries << 3) + length);
+ 
+ 	/*
+ 	 * Turn-off after 60 seconds, single encryption key,
+ 	 * and selectable language (plus quicklog response, if the
+ 	 * card can do it)
+ 	 */
+ 
+ 	sprintf(options[2], "%03o", (1 << 6) + (language << 3) + 1);
+ }
+ 
+ static void ktadd_usage()
+ {
+ 	fprintf(stderr, "Usage: card_add [options] principal\n");
+ 	fprintf(stderr, "options are: \n");
+ 	fprintf(stderr, "\t-i\t\tUse initializer hardware\n");
+ 	fprintf(stderr, "\t-d /dev/...\tPort initializer is connected to\n");
+ 	fprintf(stderr, "\t\t\t(Also can be set via env variable CRYPTOCARD_PORT)\n");
+ 	fprintf(stderr, "\t-l language\tCard language prompts\n");
+ 	fprintf(stderr, "\t-u userid\tUserid displayed on card (defaults to principal name)\n");
+ 	fprintf(stderr, "\t-U\t\tDon't display userid on card\n");
+ 	fprintf(stderr, "\t-s\t\tSingle response per power cycle\n");
+ 	fprintf(stderr, "\t-p pin\t\tPIN used to unlock card\n");
+ 	fprintf(stderr, "\t-P\t\tMake PIN non-changeable\n");
+ 	fprintf(stderr, "\t-n length\tMinimum length of PIN\n");
+ 	fprintf(stderr, "\t-t max\t\tMaximum number of incorrect pin attempts\n");
+ }
+ 
+ #else /* KADMIN_CRYPTOCARD */
+ 
+ void
+ kadmin_ktadd_cryptocard(int argc, char **argv)
+ {
+ 	fprintf(stderr,"card_add not supported on this system\n");
+ }
+ 
+ #endif /* KADMIN_CRYTPOCARD */
Index: krb5/kadmin/cli/kadmin.c
diff -c krb5/kadmin/cli/kadmin.c:1.1.1.2 krb5/kadmin/cli/kadmin.c:1.7
*** krb5/kadmin/cli/kadmin.c:1.1.1.2	Fri Feb 22 16:33:09 2002
--- krb5/kadmin/cli/kadmin.c	Tue Nov 26 12:48:29 2002
***************
*** 176,181 ****
--- 176,185 ----
      krb5_principal princ;
      kadm5_config_params params;
  
+     extern const char *krb5_default_pwd_prompt1;
+     const char *oldprompt;
+     char prompt[128];
+ 
      memset((char *) &params, 0, sizeof(params));
      
      if (retval = krb5_init_context(&context)) {
***************
*** 800,805 ****
--- 804,825 ----
  	    ++*randkey;
  	    continue;
  	}
+ 	if (strlen(argv[i]) == 13 &&
+ 	    !strcmp("-lastpwchange", argv[i])) {
+ 	    if (++i > argc - 2)
+ 		return -1;
+ 	    else {
+ 		date = get_date(argv[i], NULL);
+  		if (date == (time_t)-1) {
+ 		     fprintf(stderr, "Invalid date specification \"%s\".\n",
+ 			     argv[i]);
+ 		     return -1;
+  		}
+ 		oprinc->last_pwd_change = date;
+ 		*mask |= KADM5_LAST_PWD_CHANGE;
+ 		continue;
+ 	    }
+ 	}
  	if (!strcmp("-e", argv[i])) {
  	    if (++i > argc - 2)
  		return -1;
***************
*** 867,873 ****
  {
       fprintf(stderr, "usage: %s [options] principal\n", func);
       fprintf(stderr, "\toptions are:\n");
!      fprintf(stderr, "\t\t[-expire expdate] [-pwexpire pwexpdate] [-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n\t\t[-maxrenewlife maxrenewlife] [{+|-}attribute]\n");
       fprintf(stderr, "\tattributes are:\n");
       fprintf(stderr, "%s%s%s",
  	     "\t\tallow_postdated allow_forwardable allow_tgs_req allow_renewable\n",
--- 887,893 ----
  {
       fprintf(stderr, "usage: %s [options] principal\n", func);
       fprintf(stderr, "\toptions are:\n");
!      fprintf(stderr, "\t\t[-expire expdate] [-pwexpire pwexpdate] [-maxlife maxtixlife]\n\t\t[-kvno kvno] [-policy policy] [-clearpolicy]\n\t\t[-maxrenewlife maxrenewlife] [-lastpwchange pwchangedate]\n\t\t[{+|-}attribute]\n");
       fprintf(stderr, "\tattributes are:\n");
       fprintf(stderr, "%s%s%s",
  	     "\t\tallow_postdated allow_forwardable allow_tgs_req allow_renewable\n",
***************
*** 892,898 ****
  
      if (dummybuf[0] == 0) {
  	 for (i = 0; i < 256; i++)
! 	      dummybuf[i] = (i+1) % 256;
      }
      
      /* Zero all fields in request structure */
--- 912,919 ----
  
      if (dummybuf[0] == 0) {
  	 for (i = 0; i < 256; i++)
! 	      /* Use (i*2+1) so that results passes cracklib */
! 	      dummybuf[i] = (i*2+1) % 256;
      }
      
      /* Zero all fields in request structure */
***************
*** 1494,1498 ****
--- 1515,1563 ----
  	    printf(" %s", privs[i]);
      }
      printf("\n");
+     return;
+ }
+ 
+ void kadmin_get_rb1_usage(func)
+     char *func;
+ {
+     fprintf(stderr, "Usage: %s principal numresponses\n", func);
+ }
+ 
+ void kadmin_get_rb1(argc, argv)
+     int argc;
+     char *argv[];
+ {
+     krb5_error_code retval;
+     krb5_principal princ;
+     int numresponses, n_responses, i;
+     char **challenges, **responses;
+ 
+     if (argc != 3) {
+ 	kadmin_get_rb1_usage(argv[0]);
+ 	return;
+     }
+ 
+     retval = kadmin_parse_name(argv[1], &princ);
+     if (retval) {
+ 	com_err("get_rb1", retval, "while parsing principal name");
+ 	return;
+     }
+ 
+     numresponses = atoi(argv[2]);
+ 
+     retval = kadm5_get_rb1response(handle, princ, numresponses, &challenges,
+ 				   &responses, &n_responses);
+     if (retval) {
+ 	com_err("get_rb", retval, "while getting challenge/responses");
+ 	return;
+     }
+ 
+     printf("Challenge\t\t\tResponse\n");
+ 
+     for (i = 0; i < n_responses; i++) {
+ 	printf("%s\t\t\t%s\n", challenges[i], responses[i]);
+     }
+ 
      return;
  }
Index: krb5/kadmin/cli/kadmin_ct.ct
diff -c krb5/kadmin/cli/kadmin_ct.ct:1.1.1.2 krb5/kadmin/cli/kadmin_ct.ct:1.4
*** krb5/kadmin/cli/kadmin_ct.ct:1.1.1.2	Fri Feb 22 16:33:10 2002
--- krb5/kadmin/cli/kadmin_ct.ct	Tue Nov 26 12:48:29 2002
***************
*** 68,73 ****
--- 68,79 ----
  request kadmin_keytab_remove, "Remove entry(s) from a keytab",
  	ktremove, ktrem;
  
+ request kadmin_ktadd_cryptocard, "Get/Program an encryption key for a CRYPTOCard RB-1",
+ 	card_add, cardadd;
+ 
+ request kadmin_get_rb1, "Get a series of RB1 challenges and responses",
+ 	get_rb1, getrb1;
+ 
  # list_requests is generic -- unrelated to Kerberos
  request	ss_list_requests, "List available requests.",
  	list_requests, lr, "?";
Index: krb5/kadmin/dbutil/.cvsignore
diff -c /dev/null krb5/kadmin/dbutil/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:15 2003
--- krb5/kadmin/dbutil/.cvsignore	Thu Jun  5 10:38:43 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/dbutil/configure.in
diff -c krb5/kadmin/dbutil/configure.in:1.1.1.1 krb5/kadmin/dbutil/configure.in:removed
*** krb5/kadmin/dbutil/configure.in:1.1.1.1	Mon Jun  2 17:55:08 1997
--- krb5/kadmin/dbutil/configure.in	Sun Mar 16 20:22:15 2003
***************
*** 1,16 ****
- AC_INIT(kdb5_create.c)
- CONFIG_RULES
- AC_HAVE_FUNCS(getcwd strstr)
- AC_PROG_INSTALL
- AC_PROG_AWK
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KDB5_LIBRARY
- USE_DYN_LIBRARY
- USE_KRB4_LIBRARY
- USE_GSSAPI_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- AC_CHECK_HEADERS(krb_db.h kdc.h) dnl 
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/dbutil/dump.c
diff -c krb5/kadmin/dbutil/dump.c:1.1.1.3 krb5/kadmin/dbutil/dump.c:1.5
*** krb5/kadmin/dbutil/dump.c:1.1.1.3	Wed Sep 25 15:06:12 2002
--- krb5/kadmin/dbutil/dump.c	Mon Mar 10 15:25:42 2003
***************
*** 1009,1015 ****
  /*
   * usage is:
   *	dump_db [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
!  *		[-new_mkey_file mkey_file] [-rev] [-recurse]
   *		[filename [principals...]]
   */
  void
--- 1009,1015 ----
  /*
   * usage is:
   *	dump_db [-old] [-b6] [-b7] [-ov] [-verbose] [-mkey_convert]
!  *		[-new_mkey_file mkey_file] [-rev] [-recurse] [-new_mkey_enctype]
   *		[filename [principals...]]
   */
  void
***************
*** 1028,1033 ****
--- 1028,1034 ----
      krb5_boolean	locked;
      extern osa_adb_policy_t policy_db;
      char		*new_mkey_file = 0;
+     krb5_enctype	new_mkey_enctype = ENCTYPE_UNKNOWN;
  	
      /*
       * Parse the arguments.
***************
*** 1067,1072 ****
--- 1068,1082 ----
  	    backwards = 1;
  	else if (!strcmp(argv[aindex], "-recurse"))
  	    recursive = 1;
+ 	else if (!strcmp(argv[aindex], "-new_mkey_enctype")) {
+ 	    retval = krb5_string_to_enctype(argv[++aindex], &new_mkey_enctype);
+ 	    if (retval) {
+ 		com_err(argv[0], retval,
+ 			"while parsing new master key enctype");
+ 		exit_status++;
+ 		return;
+ 	    }
+ 	}
  	else
  	    break;
      }
***************
*** 1118,1124 ****
  			    exit(1);
  		    }
  	    }
! 	    new_master_keyblock.enctype = global_params.enctype;
  	    if (new_master_keyblock.enctype == ENCTYPE_UNKNOWN)
  		    new_master_keyblock.enctype = DEFAULT_KDC_ENCTYPE;
  	    if (!new_mkey_file)
--- 1128,1137 ----
  			    exit(1);
  		    }
  	    }
! 	    if (new_mkey_enctype != ENCTYPE_UNKNOWN)
! 		    new_master_keyblock.enctype = new_mkey_enctype;
! 	    else
! 		    new_master_keyblock.enctype = global_params.enctype;
  	    if (new_master_keyblock.enctype == ENCTYPE_UNKNOWN)
  		    new_master_keyblock.enctype = DEFAULT_KDC_ENCTYPE;
  	    if (!new_mkey_file)
Index: krb5/kadmin/dbutil/ovload.c
diff -c krb5/kadmin/dbutil/ovload.c:1.1.1.2 krb5/kadmin/dbutil/ovload.c:1.3
*** krb5/kadmin/dbutil/ovload.c:1.1.1.2	Fri Feb 22 16:33:17 2002
--- krb5/kadmin/dbutil/ovload.c	Sun Feb 24 21:21:32 2002
***************
*** 1,7 ****
--- 1,9 ----
  #include    <unistd.h>
  #include    <string.h>
  #include    <stdlib.h>
+ #ifdef HAVE_MEMORY_H
  #include    <memory.h>
+ #endif
  
  #include    <kadm5/adb.h>
  #include    "import_err.h"
Index: krb5/kadmin/kdbkeys/.cvsignore
diff -c /dev/null krb5/kadmin/kdbkeys/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:16 2003
--- krb5/kadmin/kdbkeys/.cvsignore	Thu Jun  5 10:38:46 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/kdbkeys/configure.in
diff -c krb5/kadmin/kdbkeys/configure.in:1.1.1.1 krb5/kadmin/kdbkeys/configure.in:removed
*** krb5/kadmin/kdbkeys/configure.in:1.1.1.1	Mon Jun  2 17:55:11 1997
--- krb5/kadmin/kdbkeys/configure.in	Sun Mar 16 20:22:16 2003
***************
*** 1,11 ****
- AC_INIT(kdbkeys.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_PROG_AWK
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_DYN_LIBRARY
- USE_KDB5_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/ktutil/.cvsignore
diff -c /dev/null krb5/kadmin/ktutil/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:16 2003
--- krb5/kadmin/ktutil/.cvsignore	Thu Jun  5 10:38:49 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/ktutil/configure.in
diff -c krb5/kadmin/ktutil/configure.in:1.1.1.1 krb5/kadmin/ktutil/configure.in:removed
*** krb5/kadmin/ktutil/configure.in:1.1.1.1	Mon Jun  2 17:55:12 1997
--- krb5/kadmin/ktutil/configure.in	Sun Mar 16 20:22:16 2003
***************
*** 1,8 ****
- AC_INIT(ktutil.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- USE_KRB4_LIBRARY
- USE_SS_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/passwd/.cvsignore
diff -c /dev/null krb5/kadmin/passwd/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:16 2003
--- krb5/kadmin/passwd/.cvsignore	Thu Jun  5 10:38:50 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/passwd/configure.in
diff -c krb5/kadmin/passwd/configure.in:1.1.1.1 krb5/kadmin/passwd/configure.in:removed
*** krb5/kadmin/passwd/configure.in:1.1.1.1	Mon Jun  2 17:55:14 1997
--- krb5/kadmin/passwd/configure.in	Sun Mar 16 20:22:16 2003
***************
*** 1,34 ****
- AC_INIT(kpasswd.c)
- CONFIG_RULES
- AC_CONFIG_SUBDIRS(unit-test)
- DO_SUBDIRS
- AC_PROG_INSTALL
- AC_PROG_AWK
- USE_KADMCLNT_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_DYN_LIBRARY
- 
- dnl 
- dnl The following is a kludge to get around a shared library problem
- dnl for NetBSD and Linux.  We have to include -lkdb5 under Linux, and 
- dnl we can't include -lkdb5 under NetBSD, due to various breakages in
- dnl each system's shared library implementation
- dnl
- AC_MSG_CHECKING([for build host])
- AC_CACHE_VAL(krb5_cv_host, [export CC
- AC_CANONICAL_HOST
- krb5_cv_host=$host])
- AC_MSG_RESULT($krb5_cv_host)
- case $krb5_cv_host in
- *-*-*bsd*)
-   echo "Skipping USE KDB5 LIBRARY on BSD to avoid libdb incompatibilites"
-   ;;
- *)
-   USE_KDB5_LIBRARY
-   ;;
- esac
- 
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/passwd/unit-test/.cvsignore
diff -c /dev/null krb5/kadmin/passwd/unit-test/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:16 2003
--- krb5/kadmin/passwd/unit-test/.cvsignore	Thu Jun  5 10:38:51 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/passwd/unit-test/configure.in
diff -c krb5/kadmin/passwd/unit-test/configure.in:1.1.1.1 krb5/kadmin/passwd/unit-test/configure.in:removed
*** krb5/kadmin/passwd/unit-test/configure.in:1.1.1.1	Mon Jun  2 17:55:15 1997
--- krb5/kadmin/passwd/unit-test/configure.in	Sun Mar 16 20:22:16 2003
***************
*** 1,12 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- dnl The following are tests for the presence of programs required for testing 
- AC_CHECK_PROG(RUNTEST,runtest,runtest)
- AC_CHECK_PROG(PERL,perl,perl)
- AC_KRB5_TCL	
- if test "$PERL" = perl -a "$RUNTEST" = runtest -a "$TCL_LIB" != ""; then
-  	DO_TEST=ok
- fi
- AC_SUBST(DO_TEST) 
- dnl
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/server/.cvsignore
diff -c /dev/null krb5/kadmin/server/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:16 2003
--- krb5/kadmin/server/.cvsignore	Thu Jun  5 10:38:52 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/server/configure.in
diff -c krb5/kadmin/server/configure.in:1.1.1.1 krb5/kadmin/server/configure.in:removed
*** krb5/kadmin/server/configure.in:1.1.1.1	Mon Jun  2 17:55:18 1997
--- krb5/kadmin/server/configure.in	Sun Mar 16 20:22:16 2003
***************
*** 1,17 ****
- AC_INIT(ovsec_kadmd.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- dnl AC_CHECK_FUNCS(waitpid vsprintf)
- dnl AC_CHECK_HEADERS(sys/select.h)
- dnl CHECK_SIGNALS
- dnl CHECK_SETJMP
- dnl CHECK_WAIT_TYPE
- dnl ET_RULES
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KDB5_LIBRARY
- USE_DYN_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/server/kadm_rpc_svc.c
diff -c krb5/kadmin/server/kadm_rpc_svc.c:1.1.1.3 krb5/kadmin/server/kadm_rpc_svc.c:1.5
*** krb5/kadmin/server/kadm_rpc_svc.c:1.1.1.3	Fri Feb 22 16:33:30 2002
--- krb5/kadmin/server/kadm_rpc_svc.c	Tue Nov 26 12:48:56 2002
***************
*** 1,18 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   *
!  * $Id: kadm_rpc_svc.c,v 1.1.1.3 2002/02/22 21:33:30 kenh Exp $
   *
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/kadm_rpc_svc.c,v 1.1.1.3 2002/02/22 21:33:30 kenh Exp $";
  #endif
  
  #include <stdio.h>
  #include <gssrpc/rpc.h>
  #include <syslog.h>
- #include <memory.h>
  #include <kadm5/kadm_rpc.h>
  #include <krb5.h>
  #include <kadm5/admin.h>
--- 1,17 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   *
!  * $Id: kadm_rpc_svc.c,v 1.5 2002/11/26 17:48:56 kenh Exp $
   *
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/kadm_rpc_svc.c,v 1.5 2002/11/26 17:48:56 kenh Exp $";
  #endif
  
  #include <stdio.h>
  #include <gssrpc/rpc.h>
  #include <syslog.h>
  #include <kadm5/kadm_rpc.h>
  #include <krb5.h>
  #include <kadm5/admin.h>
***************
*** 56,61 ****
--- 55,61 ----
  	  chpass3_arg chpass_principal3_1_arg;
  	  chrand3_arg chrand_principal3_1_arg;
  	  setkey3_arg setkey_principal3_1_arg;
+ 	  getrb1response_arg get_rb1response_1_arg;
       } argument;
       char *result;
       bool_t (*xdr_argument)(), (*xdr_result)();
***************
*** 200,205 ****
--- 200,211 ----
  	  xdr_argument = xdr_setkey3_arg;
  	  xdr_result = xdr_generic_ret;
  	  local = (char *(*)()) setkey_principal3_1;
+ 	  break;
+ 
+      case GET_RB1RESPONSE:
+ 	  xdr_argument = xdr_getrb1response_arg;
+ 	  xdr_result = xdr_getrb1response_ret;
+ 	  local = (char *(*)()) get_rb1response_1;
  	  break;
  
       default:
Index: krb5/kadmin/server/misc.c
diff -c krb5/kadmin/server/misc.c:1.1.1.3 krb5/kadmin/server/misc.c:1.5
*** krb5/kadmin/server/misc.c:1.1.1.3	Thu Dec 19 14:07:03 2002
--- krb5/kadmin/server/misc.c	Thu Dec 19 16:57:35 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.c,v 1.1.1.3 2002/12/19 19:07:03 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.c,v 1.1.1.3 2002/12/19 19:07:03 kenh Exp $";
  #endif
  
  #include    <kadm5/adb.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.c,v 1.5 2002/12/19 21:57:35 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.c,v 1.5 2002/12/19 21:57:35 kenh Exp $";
  #endif
  
  #include    <kadm5/adb.h>
Index: krb5/kadmin/server/misc.h
diff -c krb5/kadmin/server/misc.h:1.1.1.2 krb5/kadmin/server/misc.h:1.2
*** krb5/kadmin/server/misc.h:1.1.1.2	Mon Nov  3 16:33:07 1997
--- krb5/kadmin/server/misc.h	Mon Jun  8 15:09:30 1998
***************
*** 1,9 ****
  /*
   * Copyright 1994 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.h,v 1.1.1.2 1997/11/03 21:33:07 kenh Exp $
   * 
   * $Log: misc.h,v $
   * Revision 1.1.1.2  1997/11/03 21:33:07  kenh
   * Import of Kerberos 5, Release 1.0.2
   *
--- 1,13 ----
  /*
   * Copyright 1994 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/misc.h,v 1.2 1998/06/08 19:09:30 kenh Exp $
   * 
   * $Log: misc.h,v $
+  * Revision 1.2  1998/06/08 19:09:30  kenh
+  * More fixes from Marc Horowitz for the minimum password lifetime bug
+  * in schpw.c.
+  *
   * Revision 1.1.1.2  1997/11/03 21:33:07  kenh
   * Import of Kerberos 5, Release 1.0.2
   *
***************
*** 47,52 ****
--- 51,58 ----
  				      krb5_principal principal,
  				      krb5_keyblock **key,
  				      int *n_keys);
+ kadm5_ret_t check_policy_minlife(void *server_handle,
+ 				 krb5_principal principal);
  
  kadm5_ret_t kadm5_get_principal_v1(void *server_handle,
  				   krb5_principal principal, 
Index: krb5/kadmin/server/ovsec_kadmd.c
diff -c krb5/kadmin/server/ovsec_kadmd.c:1.1.1.4 krb5/kadmin/server/ovsec_kadmd.c:1.6
*** krb5/kadmin/server/ovsec_kadmd.c:1.1.1.4	Fri Feb 22 16:33:31 2002
--- krb5/kadmin/server/ovsec_kadmd.c	Sun Feb 24 21:21:36 2002
***************
*** 441,447 ****
   	  krb5_klog_close(context);
  	  exit(1);
       }
!      
       transp = svctcp_create(s, 0, 0);
       if(transp == NULL) {
  	  fprintf(stderr, "%s: Cannot create RPC service.\n", whoami);
--- 441,447 ----
   	  krb5_klog_close(context);
  	  exit(1);
       }
! 
       transp = svctcp_create(s, 0, 0);
       if(transp == NULL) {
  	  fprintf(stderr, "%s: Cannot create RPC service.\n", whoami);
***************
*** 773,778 ****
--- 773,779 ----
  
  void request_exit(int signum)
  {
+      signal(signum, request_exit);	/* Reset signal */
       krb5_klog_syslog(LOG_DEBUG, "Got signal to request exit");
       signal_request_exit = 1;
       return;
***************
*** 789,794 ****
--- 790,796 ----
   */
  void sig_pipe(int unused)
  {
+      signal(SIGPIPE, sig_pipe);		/* Reset signal */
       krb5_klog_syslog(LOG_NOTICE, "Warning: Received a SIGPIPE; probably a "
  	    "client aborted.  Continuing.");
       return;
Index: krb5/kadmin/server/schpw.c
diff -c krb5/kadmin/server/schpw.c:1.1.1.1 krb5/kadmin/server/schpw.c:1.5
*** krb5/kadmin/server/schpw.c:1.1.1.1	Fri Feb 22 16:33:31 2002
--- krb5/kadmin/server/schpw.c	Thu Dec 19 16:57:35 2002
***************
*** 1,9 ****
--- 1,14 ----
  #define NEED_SOCKETS
  #include "k5-int.h"
  #include <kadm5/admin.h>
+ /* sigh */
+ #include "kadm5/server_internal.h"
+ #include <krb5/adm_proto.h>
  
  #include <stdio.h>
  #include <errno.h>
+ #include <time.h>
+ #include <syslog.h>
  
  krb5_error_code
  process_chpw_request(context, server_handle, realm, s, keytab, sin, req, rep)
***************
*** 32,37 ****
--- 37,47 ----
      krb5_error krberror;
      int numresult;
      char strresult[1024];
+     char *name;
+     kadm5_server_handle_t handle = (kadm5_server_handle_t) server_handle;
+     kadm5_policy_ent_rec pol;
+     kadm5_principal_ent_rec princ;
+     krb5_int32 now;
  
      ret = 0;
      rep->length = 0;
***************
*** 42,47 ****
--- 52,58 ----
      ticket = NULL;
      clear.length = 0;
      cipher.length = 0;
+     name = NULL;
  
      if (req->length < 4) {
  	/* either this, or the server is printing bad messages,
***************
*** 121,126 ****
--- 132,145 ----
  	goto chpwfail;
      }
  
+     ret = krb5_unparse_name(context, ticket->enc_part2->client, &name);
+ 
+     if (ret) {
+ 	numresult = KRB5_KPASSWD_HARDERROR;
+ 	strcpy(strresult, "Failed unparsing client name");
+ 	goto chpwfail;
+     }
+ 
      /* set up address info */
  
      addrlen = sizeof(local_addr);
***************
*** 222,227 ****
--- 241,304 ----
  	goto chpwfail;
      }
  
+     /* make sure the principal's min_life has been exceeded */
+ 
+     if ((ret = krb5_timeofday(context, &now))) {
+ 	numresult = KRB5_KPASSWD_HARDERROR;
+ 	strcpy(strresult, "Failed getting time of day");
+ 	goto chpwfail;
+     }
+ 
+     if ((ret = kadm5_get_principal(handle->lhandle, ticket->enc_part2->client,
+ 				   &princ,
+ 				   KADM5_PRINCIPAL_NORMAL_MASK)) != KADM5_OK) {
+ 	numresult = KRB5_KPASSWD_HARDERROR;
+ 	strcpy(strresult, "Failed retrieving principal record");
+ 	goto chpwfail;
+     }
+ 
+     if (princ.aux_attributes & KADM5_POLICY) {
+ 	if ((ret = kadm5_get_policy(handle->lhandle, princ.policy,
+ 				    &pol)) != KADM5_OK) {
+ 	    kadm5_free_principal_ent(handle->lhandle, &princ);
+ 	    numresult = KRB5_KPASSWD_HARDERROR;
+ 	    strcpy(strresult, "Failed retrieving policy record");
+ 	    goto chpwfail;
+ 	}
+ 
+ 	if ((now - princ.last_pwd_change) < pol.pw_min_life &&
+ 	    !(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
+ 	    time_t until;
+ 	    char *time_string, *ptr;
+ 
+ 	    /* zap the password */
+ 	    memset(clear.data, 0, clear.length);
+ 	    krb5_xfree(clear.data);
+ 	    clear.length = 0;
+ 
+ 	    /* most of this is stolen from chpass_util.c */
+ 
+ 	    until = princ.last_pwd_change + pol.pw_min_life;
+ 
+ 	    time_string = ctime(&until);
+ 	    if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
+ 	    *ptr = '\0';
+ 
+ 	    sprintf(strresult, error_message(CHPASS_UTIL_PASSWORD_TOO_SOON), 
+ 		    time_string);
+ 
+ 	    kadm5_free_principal_ent(server_handle, &princ);
+ 	    kadm5_free_policy_ent(server_handle, &pol);
+ 
+ 	    numresult = KRB5_KPASSWD_SOFTERROR;
+ 	    goto chpwfail;
+ 	}
+ 
+         kadm5_free_policy_ent(server_handle, &pol);
+     }
+ 
+     kadm5_free_principal_ent(server_handle, &princ);
+ 	  
      /* change the password */
  
      ptr = (char *) malloc(clear.length+1);
***************
*** 245,250 ****
--- 322,328 ----
  	    numresult = KRB5_KPASSWD_HARDERROR;
  	else
  	    numresult = KRB5_KPASSWD_SOFTERROR;
+ 
  	/* strresult set by kadb5_chpass_principal_util() */
  	goto chpwfail;
      }
***************
*** 256,261 ****
--- 334,344 ----
  
  chpwfail:
  
+     krb5_klog_syslog(LOG_NOTICE, "Request: chpw, %s, %s, addr=%s",
+ 		     name ? name : "<unknown>",
+ 		     ret == 0 ? "success" : error_message(ret),
+ 		     inet_ntoa(sin->sin_addr));
+ 
      clear.length = 2 + strlen(strresult);
      clear.data = (char *) malloc(clear.length);
  
***************
*** 371,376 ****
--- 454,461 ----
  	krb5_xfree(cipher.data);
      if (allocated_mem) 
          krb5_xfree(local_kaddr.contents);
+     if (name)
+ 	krb5_free_unparsed_name(context, name);
  
      return(ret);
  }
Index: krb5/kadmin/server/server_stubs.c
diff -c krb5/kadmin/server/server_stubs.c:1.1.1.5 krb5/kadmin/server/server_stubs.c:1.3
*** krb5/kadmin/server/server_stubs.c:1.1.1.5	Thu Dec 19 14:07:03 2002
--- krb5/kadmin/server/server_stubs.c	Thu Dec 19 14:19:29 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/server_stubs.c,v 1.1.1.5 2002/12/19 19:07:03 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/server_stubs.c,v 1.1.1.5 2002/12/19 19:07:03 kenh Exp $";
  #endif
  
  #include <gssapi/gssapi.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/server_stubs.c,v 1.3 2002/12/19 19:19:29 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/kadmin/server/server_stubs.c,v 1.3 2002/12/19 19:19:29 kenh Exp $";
  #endif
  
  #include <gssapi/gssapi.h>
***************
*** 1437,1442 ****
--- 1437,1500 ----
       gss_release_buffer(&minor_stat, &client_name);
       gss_release_buffer(&minor_stat, &service_name);
       return &ret;
+ }
+ 
+ getrb1response_ret * get_rb1response_1(getrb1response_arg *arg,
+ 				       struct svc_req *rqstp)
+ {
+     static getrb1response_ret	ret;
+     char			*prime_arg;
+     gss_buffer_desc		client_name,
+ 				service_name;
+     kadm5_server_handle_t	handle;
+     OM_uint32			minor_stat;
+ 
+     xdr_free(xdr_getrb1response_ret, &ret);
+ 
+     if (ret.code = new_server_handle(arg->api_version, rqstp, &handle))
+ 	return &ret;
+ 
+     if (ret.code = check_handle((void *)handle)) {
+ 	free_server_handle(handle);
+ 	return &ret;
+     }
+ 
+     ret.api_version = handle->api_version;
+ 
+     if (krb5_unparse_name(handle->context, arg->princ, &prime_arg)) {
+ 	ret.code = KADM5_BAD_PRINCIPAL;
+ 	free_server_handle(handle);
+ 	return &ret;
+     }
+ 
+     if (setup_gss_names(rqstp, &client_name, &service_name) < 0) {
+ 	ret.code = KADM5_FAILURE;
+ 	free_server_handle(handle);
+ 	free(prime_arg);
+ 	return &ret;
+     }
+ 
+     if (!acl_check(handle->context, rqstp->rq_clntcred, ACL_MODIFY,
+ 		   arg->princ, NULL)) {
+ 	ret.code = KADM5_AUTH_MODIFY;
+ 	krb5_klog_syslog(LOG_NOTICE, LOG_UNAUTH, "kadm5_get_rb1response",
+ 		prime_arg, client_name.value, service_name.value,
+ 		inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
+     } else {
+     	ret.code = kadm5_get_rb1response(handle, arg->princ, arg->numresponses,
+ 					 &ret.challenges, &ret.responses,
+ 					 &ret.n_responses);
+ 	krb5_klog_syslog(LOG_NOTICE, LOG_DONE, "kadm5_get_rb1response",
+ 			 prime_arg, ((ret.code == 0) ? "success" :
+ 			 error_message(ret.code)), client_name.value,
+ 			 service_name.value,
+ 			 inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr));
+     }
+     free_server_handle(handle);
+     free(prime_arg);
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+     return &ret;
  }
  
  generic_ret *init_1(krb5_ui_4 *arg, struct svc_req *rqstp)
Index: krb5/kadmin/testing/.cvsignore
diff -c /dev/null krb5/kadmin/testing/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:17 2003
--- krb5/kadmin/testing/.cvsignore	Thu Jun  5 10:38:53 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/testing/configure.in
diff -c krb5/kadmin/testing/configure.in:1.1.1.1 krb5/kadmin/testing/configure.in:removed
*** krb5/kadmin/testing/configure.in:1.1.1.1	Mon Jun  2 17:55:21 1997
--- krb5/kadmin/testing/configure.in	Sun Mar 16 20:22:17 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- CONFIG_DIRS(scripts util)
- DO_SUBDIRS
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/testing/scripts/.cvsignore
diff -c /dev/null krb5/kadmin/testing/scripts/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:17 2003
--- krb5/kadmin/testing/scripts/.cvsignore	Thu Jun  5 10:38:53 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/testing/scripts/configure.in
diff -c krb5/kadmin/testing/scripts/configure.in:1.1.1.1 krb5/kadmin/testing/scripts/configure.in:removed
*** krb5/kadmin/testing/scripts/configure.in:1.1.1.1	Mon Jun  2 17:55:23 1997
--- krb5/kadmin/testing/scripts/configure.in	Sun Mar 16 20:22:17 2003
***************
*** 1,10 ****
- AC_INIT(init_db)
- CONFIG_RULES
- AC_PATH_PROG(PERL,perl)
- AC_PATH_PROG(EXPECT,expect)
- KRB5_RUN_FLAGS
- RBUILD=`pwd`/../../..
- AC_SUBST(RBUILD)
- dnl The following are substituted into env-setup.sh
- AC_SUBST(SRCTOP)
- V5_AC_OUTPUT_MAKEFILE( ,env-setup.sh:env-setup.shin)
--- 0 ----
Index: krb5/kadmin/testing/util/.cvsignore
diff -c /dev/null krb5/kadmin/testing/util/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:17 2003
--- krb5/kadmin/testing/util/.cvsignore	Thu Jun  5 10:38:54 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/testing/util/configure.in
diff -c krb5/kadmin/testing/util/configure.in:1.1.1.1 krb5/kadmin/testing/util/configure.in:removed
*** krb5/kadmin/testing/util/configure.in:1.1.1.1	Mon Jun  2 17:55:27 1997
--- krb5/kadmin/testing/util/configure.in	Sun Mar 16 20:22:17 2003
***************
*** 1,20 ****
- AC_INIT(tcl_kadm5.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- dnl Test for tcl
- AC_KRB5_TCL	
- if test "$TCL_LIB" != "" ;  then
- 	DO_ALL=tcl
- fi
- AC_SUBST(DO_ALL)
- dnl
- USE_KADMCLNT_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_DYN_LIBRARY
- USE_KDB5_LIBRARY
- USE_SS_LIBRARY
- V5_USE_SHARED_LIB
- KRB5_LIBRARIES
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/v4server/.cvsignore
diff -c /dev/null krb5/kadmin/v4server/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:17 2003
--- krb5/kadmin/v4server/.cvsignore	Thu Jun  5 10:38:55 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/v4server/configure.in
diff -c krb5/kadmin/v4server/configure.in:1.1.1.1 krb5/kadmin/v4server/configure.in:removed
*** krb5/kadmin/v4server/configure.in:1.1.1.1	Mon Jun  2 17:55:30 1997
--- krb5/kadmin/v4server/configure.in	Sun Mar 16 20:22:17 2003
***************
*** 1,17 ****
- AC_INIT(admin_server.c)
- CONFIG_RULES
- AC_CONFIG_SUBDIRS(unit-test)
- AC_PROG_INSTALL
- AC_CHECK_HEADERS(sys/time.h unistd.h stdlib.h)
- CHECK_SIGNALS
- CHECK_WAIT_TYPE
- AC_PROG_AWK
- USE_KADMCLNT_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_DYN_LIBRARY
- USE_KDB5_LIBRARY
- USE_KRB4_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/v4server/unit-test/.cvsignore
diff -c /dev/null krb5/kadmin/v4server/unit-test/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:17 2003
--- krb5/kadmin/v4server/unit-test/.cvsignore	Thu Jun  5 10:38:56 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/v5passwdd/.cvsignore
diff -c /dev/null krb5/kadmin/v5passwdd/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:18 2003
--- krb5/kadmin/v5passwdd/.cvsignore	Thu Jun  5 10:38:57 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin/v5passwdd/configure.in
diff -c krb5/kadmin/v5passwdd/configure.in:1.1.1.1 krb5/kadmin/v5passwdd/configure.in:removed
*** krb5/kadmin/v5passwdd/configure.in:1.1.1.1	Mon Jun  2 17:55:35 1997
--- krb5/kadmin/v5passwdd/configure.in	Sun Mar 16 20:22:18 2003
***************
*** 1,17 ****
- AC_INIT(proto_serv.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_FUNC_CHECK(waitpid,AC_DEFINE(HAVE_WAITPID))
- AC_FUNC_CHECK(vsprintf,AC_DEFINE(HAVE_VSPRINTF))
- AC_CHECK_HEADERS(sys/select.h)
- CHECK_SIGNALS
- CHECK_SETJMP
- CHECK_WAIT_TYPE
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KDB5_LIBRARY
- USE_DYN_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/kadmin/v5passwdd/srv_net.c
diff -c krb5/kadmin/v5passwdd/srv_net.c:1.1.1.2 krb5/kadmin/v5passwdd/srv_net.c:1.4
*** krb5/kadmin/v5passwdd/srv_net.c:1.1.1.2	Fri Feb 22 16:33:50 2002
--- krb5/kadmin/v5passwdd/srv_net.c	Sun Feb 24 21:21:40 2002
***************
*** 293,298 ****
--- 293,299 ----
  {
      krb5_error_code	kret;
      net_slave_info	*slent;
+     size_t		sock_len = sizeof(struct sockaddr_in);
  
      DPRINT(DEBUG_CALLS, net_debug_level,
  	   ("* net_dispatch_client(listen=%d)\n", listen_sock));
***************
*** 307,315 ****
      memcpy((char *) &slent->sl_remote_addr,
  	   (char *) client_addr,
  	   sizeof(struct sockaddr_in));
!     memcpy((char *) &slent->sl_local_addr,
! 	   (char *) &net_server_addr,
! 	   sizeof(struct sockaddr_in));
  
  #ifdef	DEBUG
      if ((net_debug_level & DEBUG_NOSLAVES) == 0) {
--- 308,323 ----
      memcpy((char *) &slent->sl_remote_addr,
  	   (char *) client_addr,
  	   sizeof(struct sockaddr_in));
! 
!     /*
!      * Get our "local address" entry from the socket using getsockname()
!      */
! 
!     if (getsockname(conn_sock, (struct sockaddr *) &slent->sl_local_addr,
! 		    &sock_len) < 0) {
! 	kret = errno;
! 	goto done;
!     }
  
  #ifdef	DEBUG
      if ((net_debug_level & DEBUG_NOSLAVES) == 0) {
***************
*** 501,509 ****
  
      /* Now initialize our network address */
      net_server_addr.sin_family = AF_INET;
!     memcpy((char *) &net_server_addr.sin_addr,
! 	   (char *) our_hostent->h_addr,
! 	   sizeof(net_server_addr.sin_addr));
      DPRINT(DEBUG_HOST, net_debug_level,
  	   ("- address of host is %x\n",
  	    ntohl(net_server_addr.sin_addr.s_addr)));
--- 509,515 ----
  
      /* Now initialize our network address */
      net_server_addr.sin_family = AF_INET;
!     net_server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
      DPRINT(DEBUG_HOST, net_debug_level,
  	   ("- address of host is %x\n",
  	    ntohl(net_server_addr.sin_addr.s_addr)));
***************
*** 635,642 ****
  	goto done;
      }
  
!     /* If we have a non-default port number, then allow reuse of address */
!     if (net_server_addr.sin_port != htons(KRB5_ADM_DEFAULT_PORT)) {
  	int	allowed;
  
  	allowed = 1;
--- 641,648 ----
  	goto done;
      }
  
!     /* Allow reuse of address */
!     {
  	int	allowed;
  
  	allowed = 1;
Index: krb5/kadmin.v4/.cvsignore
diff -c /dev/null krb5/kadmin.v4/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:18 2003
--- krb5/kadmin.v4/.cvsignore	Thu Jun  5 10:38:58 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kadmin.v4/server/.cvsignore
diff -c /dev/null krb5/kadmin.v4/server/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:18 2003
--- krb5/kadmin.v4/server/.cvsignore	Thu Jun  5 10:39:00 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kdc/.cvsignore
diff -c /dev/null krb5/kdc/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:18 2003
--- krb5/kdc/.cvsignore	Thu Jun  5 10:39:01 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/kdc/Makefile.in
diff -c krb5/kdc/Makefile.in:1.1.1.2 krb5/kdc/Makefile.in:1.4
*** krb5/kdc/Makefile.in:1.1.1.2	Fri Feb 22 16:32:16 2002
--- krb5/kdc/Makefile.in	Thu Sep 12 23:06:39 2002
***************
*** 47,53 ****
  	policy.o \
  	extern.o \
  	replay.o \
! 	kerberos_v4.o
  
  RT_OBJS= rtest.o \
  	kdc_util.o \
--- 47,53 ----
  	policy.o \
  	extern.o \
  	replay.o \
! 	kerberos_v4.o @EXTRA_OBJS@
  
  RT_OBJS= rtest.o \
  	kdc_util.o \
***************
*** 60,65 ****
--- 60,67 ----
  	$(RM) $@
  	$(CP) $(SRCTOP)/lib/kadm5/logger.c $@
  
+ kdc_preauth.o: sam2.c kdc_preauth.c
+ 
  logger.o: logger.c
  
  kdc5_err.c: kdc5_err.et
***************
*** 69,75 ****
  kdc5_err.o: kdc5_err.h
  
  krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB4COMPAT_DEPLIBS)
! 	$(CC_LINK) -o krb5kdc $(OBJS) $(KADMSRV_LIBS) $(KRB4COMPAT_LIBS)
  
  rtest: $(RT_OBJS) $(KADM_COMM_DEPLIBS) $(KRB5_BASE_DEPLIBS)
  	$(CC_LINK) -o rtest $(RT_OBJS) $(KADM_COMM_LIBS) $(KRB5_BASE_LIBS) 
--- 71,77 ----
  kdc5_err.o: kdc5_err.h
  
  krb5kdc: $(OBJS) $(KADMSRV_DEPLIBS) $(KRB4COMPAT_DEPLIBS)
! 	$(CC_LINK) -o krb5kdc $(OBJS) $(KADMSRV_LIBS) $(KRB4COMPAT_LIBS) @EXTRA_LIBS@
  
  rtest: $(RT_OBJS) $(KADM_COMM_DEPLIBS) $(KRB5_BASE_DEPLIBS)
  	$(CC_LINK) -o rtest $(RT_OBJS) $(KADM_COMM_LIBS) $(KRB5_BASE_LIBS) 
Index: krb5/kdc/configure.in
diff -c krb5/kdc/configure.in:1.1.1.2 krb5/kdc/configure.in:1.6
*** krb5/kdc/configure.in:1.1.1.2	Fri Feb 22 16:32:18 2002
--- krb5/kdc/configure.in	Thu Aug 15 13:46:25 2002
***************
*** 34,39 ****
--- 34,72 ----
  	AC_MSG_RESULT(Updating KDC database with each request)
  	AC_DEFINE(KRBCONF_KDC_MODIFIES_KDB)
  fi
+ dnl
+ dnl --with-afs-name-change enables code that supports the case where
+ dnl the name of the realm (cell) changed when going from AFS to Kerberos 5
+ dnl
+ AC_ARG_WITH([afs-name-change],
+ [  --with-afs-name-change	Support an AFS cell with a different name],
+ if test "$withval" = yes; then
+ 	AC_DEFINE(KRB5_KDC_AFS3_USE_CONTENTS)
+ fi)
+ dnl
+ dnl --with-securid-preauth turns on code from ARL to allow the use of a
+ dnl SecurID token to be used as a hardware preauthentication mechanism
+ dnl
+ AC_ARG_WITH([securid-preauth],
+ [  --with-securid-preuath=DIR	Support SecurID as preauth, client libs in DIR
+   --without-securid-preauth	Do not add in SecurID support (default)],
+ ,
+ withval=no)dnl
+ if test "$withval" != "no"; then
+ 	if test ! -f $withval/libaceclnt.a; then
+ 		echo "Cannot find libaceclnt.a in $withval, exiting"
+ 		exit 1
+ 	fi
+ 	if test ! -f $withval/acexport.h; then
+ 		echo "Cannot find acexport.h in $withval, exiting"
+ 		exit 1
+ 	fi
+ 	AC_MSG_RESULT(Enabling support for SecurID tokens)
+ 	AC_DEFINE(ARL_SECURID_PREAUTH)
+ 	CPPFLAGS="$CPPFLAGS -I$withval"
+ 	EXTRA_LIBS="$withval/libaceclnt.a -lpthread"
+ 	EXTRA_OBJS=securid2.o
+ fi
  dnl XXX This will go away soon. -- tlyu
  AC_ARG_ENABLE([athena],
  [  --enable-athena         build with MIT Project Athena configuration
***************
*** 64,70 ****
--- 97,117 ----
  	AC_DEFINE(NOCACHE)
  fi
  dnl
+ dnl --with-cryptocard-validate turns on code that enables a special preauth
+ dnl to allow one to simply validate a CRYPTOCard RB-1 hardware token for
+ dnl a user without having that user's secret key
+ dnl
+ AC_ARG_WITH([cryptocard-validate],
+ [  --with-cryptocard-validate	Allow validation of a RB-1 with a host key
+   --without-cryptocard-validate	Don't enable RB-1 validation code (default)],
+ ,
+ withval=no)dnl
+ if test "$withval" = yes; then
+ 	AC_DEFINE(KRB5_CRYPTOCARD_VALIDATE)
+ fi
  dnl
+ AC_SUBST(EXTRA_LIBS)
+ AC_SUBST(EXTRA_OBJS)
  KRB5_RUN_FLAGS
  KRB5_BUILD_PROGRAM
  V5_AC_OUTPUT_MAKEFILE
Index: krb5/kdc/do_as_req.c
diff -c krb5/kdc/do_as_req.c:1.1.1.4 krb5/kdc/do_as_req.c:1.8
*** krb5/kdc/do_as_req.c:1.1.1.4	Thu Dec 19 14:06:12 2002
--- krb5/kdc/do_as_req.c	Fri Dec 20 15:20:16 2002
***************
*** 82,87 ****
--- 82,88 ----
      char *cname = 0, *sname = 0, *fromstring = 0;
      char ktypestr[128];
      char rep_etypestr[128];
+     void *opaque = NULL;
  
      ticket_reply.enc_part.ciphertext.data = 0;
      e_data.data = 0;
***************
*** 265,271 ****
       * Check the preauthentication if it is there.
       */
      if (request->padata) {
! 	errcode = check_padata(kdc_context, &client, request, &enc_tkt_reply);
  	if (errcode) {
  #ifdef KRBCONF_KDC_MODIFIES_KDB
  	    /*
--- 266,273 ----
       * Check the preauthentication if it is there.
       */
      if (request->padata) {
! 	errcode = check_padata(kdc_context, &client, request, &enc_tkt_reply,
! 			       &opaque);
  	if (errcode) {
  #ifdef KRBCONF_KDC_MODIFIES_KDB
  	    /*
***************
*** 295,319 ****
       * preauthentication, verify that the proper kind of
       * preauthentication was carried out.
       */
!     status = missing_required_preauth(&client, &server, &enc_tkt_reply);
      if (status) {
  	errcode = KRB5KDC_ERR_PREAUTH_REQUIRED;
! 	get_preauth_hint_list(request, &client, &server, &e_data);
  	goto errout;
      }
  
      ticket_reply.enc_part2 = &enc_tkt_reply;
  
      /*
!      * Find the server key
       */
!     if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 					 -1, /* ignore keytype */
! 					 -1,		/* Ignore salttype */
! 					 0,		/* Get highest kvno */
! 					 &server_key))) {
! 	status = "FINDING_SERVER_KEY";
! 	goto errout;
      }
  
      /* convert server.key into a real key (it may be encrypted
--- 297,341 ----
       * preauthentication, verify that the proper kind of
       * preauthentication was carried out.
       */
!     status = missing_required_preauth(&client, &server, &enc_tkt_reply,
! 				      request);
      if (status) {
  	errcode = KRB5KDC_ERR_PREAUTH_REQUIRED;
! 	get_preauth_hint_list(request, &client, &server, &e_data, opaque);
  	goto errout;
      }
  
      ticket_reply.enc_part2 = &enc_tkt_reply;
  
      /*
!      * Find the server key.  Note that if "kdc_limit_service_enctypes" is set,
!      * then restrict non-TGS tickets to one of the requested enctypes
       */
! 
!     if (! krb5kdc_limit_service_enctypes ||
! 	krb5_is_tgs_principal(request->server)) {
! 	if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 					     -1, /* ignore keytype */
! 					     -1, /* Ignore salttype */
! 					     0,  /* Get highest kvno */
! 					     &server_key))) {
! 	    status = "FINDING_SERVER_KEY";
! 	    goto errout;
! 	}
!     } else {
! 	for (i = 0; i < request->nktypes; i++) {
! 	    errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 					    request->ktype[i],
! 					    -1, /* Ignore salttype */
! 					    0,  /* Get highest kvno */
! 					    &server_key);
! 	    if (! errcode)
! 		break;
! 	}
! 	if (errcode) {
! 	    status = "FINDING_SERVER_KEY";
! 	    goto errout;
! 	}
      }
  
      /* convert server.key into a real key (it may be encrypted
***************
*** 387,393 ****
  
      /* Fetch the padata info to be returned */
      errcode = return_padata(kdc_context, &client, request, &reply, client_key,
! 			    &encrypting_key);
      if (errcode) {
  	status = "KDC_RETURN_PADATA";
  	goto errout;
--- 409,415 ----
  
      /* Fetch the padata info to be returned */
      errcode = return_padata(kdc_context, &client, request, &reply, client_key,
! 			    &encrypting_key, opaque);
      if (errcode) {
  	status = "KDC_RETURN_PADATA";
  	goto errout;
***************
*** 486,491 ****
--- 508,515 ----
      }
  
      krb5_free_data_contents(kdc_context, &e_data);
+ 
+     cleanup_padata_opaque(kdc_context, opaque);
      
      return errcode;
  }
Index: krb5/kdc/do_tgs_req.c
diff -c krb5/kdc/do_tgs_req.c:1.1.1.4 krb5/kdc/do_tgs_req.c:1.6
*** krb5/kdc/do_tgs_req.c:1.1.1.4	Fri Feb 22 16:32:19 2002
--- krb5/kdc/do_tgs_req.c	Tue Sep 24 17:33:50 2002
***************
*** 565,580 ****
  	st_idx++;
      } else {
  	/*
! 	 * Find the server key
  	 */
! 	if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 					     -1, /* ignore keytype */
! 					     -1, /* Ignore salttype */
! 					     0,		/* Get highest kvno */
! 					     &server_key))) {
! 	    status = "FINDING_SERVER_KEY";
! 	    goto cleanup;
  	}
  	/* convert server.key into a real key (it may be encrypted
  	 *        in the database) */
  	if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context,
--- 565,600 ----
  	st_idx++;
      } else {
  	/*
! 	 * Find the server key.  A bit of a wrinkle here .... if
! 	 * "kdc_limit_service_enctypes" is set, then restrict the service
! 	 * key to one of the enctypes in the initial request.
  	 */
! 	if (! krb5kdc_limit_service_enctypes ||
! 	    krb5_is_tgs_principal(request->server)) {
! 	    if ((errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 						 -1, /* ignore keytype */
! 						 -1, /* Ignore salttype */
! 						 0,  /* Get highest kvno */
! 						 &server_key))) {
! 		status = "FINDING_SERVER_KEY";
! 		goto cleanup;
! 	    }
! 	} else {
! 	    for (i = 0; i < request->nktypes; i++) {
! 		errcode = krb5_dbe_find_enctype(kdc_context, &server,
! 						request->ktype[i],
! 						-1, /* Ignore salttype */
! 						0,  /* Get highest kvno */
! 						&server_key);
! 		if (! errcode)
! 		    break;
! 	    }
! 	    if (errcode) {
! 		status = "FINDING_SERVER_KEY";
! 		goto cleanup;
! 	    }
  	}
+ 
  	/* convert server.key into a real key (it may be encrypted
  	 *        in the database) */
  	if ((errcode = krb5_dbekd_decrypt_key_data(kdc_context,
Index: krb5/kdc/extern.c
diff -c krb5/kdc/extern.c:1.1.1.2 krb5/kdc/extern.c:1.6
*** krb5/kdc/extern.c:1.1.1.2	Fri Feb 22 16:32:19 2002
--- krb5/kdc/extern.c	Tue Sep 24 17:33:50 2002
***************
*** 36,42 ****
--- 36,47 ----
  krb5_data empty_string = {0, 0, ""};
  krb5_timestamp kdc_infinity = KRB5_INT32_MAX; /* XXX */
  krb5_rcache	kdc_rcache = (krb5_rcache) NULL;
+ krb5_deltat	kdc_warn_pwexpire = 0;
  krb5_keyblock	psr_key;
+ krb5_boolean	krb5kdc_sam_allow_old_sam = FALSE;
+ krb5_boolean	krb5kdc_sam_warn_old_sam = FALSE;
+ krb5_enctype	*krb5kdc_session_enctypes = (krb5_enctype *) NULL;
+ krb5_boolean	krb5kdc_limit_service_enctypes = FALSE;
  
  volatile int signal_requests_exit = 0;	/* gets set when signal hits */
  volatile int signal_requests_hup = 0;   /* ditto */
Index: krb5/kdc/extern.h
diff -c krb5/kdc/extern.h:1.1.1.2 krb5/kdc/extern.h:1.6
*** krb5/kdc/extern.h:1.1.1.2	Fri Feb 22 16:32:20 2002
--- krb5/kdc/extern.h	Tue Sep 24 17:33:50 2002
***************
*** 98,104 ****
--- 98,109 ----
  extern krb5_data 	empty_string;	/* an empty string */
  extern krb5_timestamp 	kdc_infinity;	/* greater than all other timestamps */
  extern krb5_rcache	kdc_rcache;	/* replay cache */
+ extern krb5_deltat	kdc_warn_pwexpire; /* Time to warn about exp pw's */
  extern krb5_keyblock	psr_key;	/* key for predicted sam response */
+ extern krb5_boolean	krb5kdc_sam_allow_old_sam;
+ extern krb5_boolean	krb5kdc_sam_warn_old_sam;
+ extern krb5_enctype	*krb5kdc_session_enctypes;
+ extern krb5_boolean	krb5kdc_limit_service_enctypes;
  
  extern volatile int signal_requests_exit;
  extern volatile int signal_requests_hup;
Index: krb5/kdc/kdc_preauth.c
diff -c krb5/kdc/kdc_preauth.c:1.1.1.5 krb5/kdc/kdc_preauth.c:1.22
*** krb5/kdc/kdc_preauth.c:1.1.1.5	Wed Sep 25 15:06:02 2002
--- krb5/kdc/kdc_preauth.c	Fri Dec 20 15:20:17 2002
***************
*** 61,72 ****
  typedef krb5_error_code (*verify_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data));
  
  typedef krb5_error_code (*edata_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data));
  
  typedef krb5_error_code (*return_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
--- 61,73 ----
  typedef krb5_error_code (*verify_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
! 		    void **opaque));
  
  typedef krb5_error_code (*edata_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data, void *opaque));
  
  typedef krb5_error_code (*return_proc)
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
***************
*** 74,80 ****
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa));
  
  typedef struct _krb5_preauth_systems {
      char *	name;
--- 75,82 ----
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
  
  typedef struct _krb5_preauth_systems {
      char *	name;
***************
*** 85,124 ****
      return_proc return_padata;
  } krb5_preauth_systems;
  
  static krb5_error_code verify_enc_timestamp
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data));
  
  static krb5_error_code get_etype_info
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data));
  static krb5_error_code return_pw_salt
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
  		    krb5_db_entry *client,
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa));
  
  /* SAM preauth support */
  static krb5_error_code verify_sam_response
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data));
  
  static krb5_error_code get_sam_edata
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data));
  static krb5_error_code return_sam_data
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
  		    krb5_db_entry *client,
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa));
  /*
   * Preauth property flags
   */
--- 87,188 ----
      return_proc return_padata;
  } krb5_preauth_systems;
  
+ typedef struct _krb5_rb1_track_data {
+     char ascii_response[9];
+     char new_challenge[8];
+     char pad[1];
+ } krb5_rb1_track_data;
+ 
  static krb5_error_code verify_enc_timestamp
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
! 		    void **opaque));
  
  static krb5_error_code get_etype_info
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data, void *opaque));
  static krb5_error_code return_pw_salt
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
  		    krb5_db_entry *client,
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
! 
! static krb5_error_code return_pa_as_rep
!     KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
! 		    krb5_db_entry *client,
! 		    krb5_kdc_req *request, krb5_kdc_rep *reply,
! 		    krb5_key_data *client_key,
! 		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
  
  /* SAM preauth support */
  static krb5_error_code verify_sam_response
      KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
  		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
! 		    void **opaque));
  
  static krb5_error_code get_sam_edata
      KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
  		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data, void *opaque));
  static krb5_error_code return_sam_data
      KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
  		    krb5_db_entry *client,
  		    krb5_kdc_req *request, krb5_kdc_rep *reply,
  		    krb5_key_data *client_key,
  		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
! 
! /* SAM2 preauth support */
! static krb5_error_code verify_sam_response_2
!     KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
! 		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
! 		    void **opaque));
! 
! static krb5_error_code get_sam_edata_2
!     KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
! 		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data, void *opaque));
! static krb5_error_code return_sam_data_2
!     KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata, 
! 		    krb5_db_entry *client,
! 		    krb5_kdc_req *request, krb5_kdc_rep *reply,
! 		    krb5_key_data *client_key,
! 		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
! 
! /*
!  * ALT-PRINC support
!  */
! 
! static krb5_error_code get_alt_princ_edata
!     KRB5_PROTOTYPE((krb5_context, krb5_kdc_req *request,
! 		    krb5_db_entry *client, krb5_db_entry *server,
! 		    krb5_pa_data *data, void *opaque));
! static krb5_error_code cache_alt_princ
!     KRB5_PROTOTYPE((krb5_context, krb5_db_entry *client,
! 		    krb5_kdc_req *request,
! 		    krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
! 		    void **opaque));
! static krb5_error_code return_alt_princ
!     KRB5_PROTOTYPE((krb5_context, krb5_pa_data * padata,
! 		    krb5_db_entry *client,
! 		    krb5_kdc_req *request, krb5_kdc_rep *reply,
! 		    krb5_key_data *client_key,
! 		    krb5_keyblock *encrypting_key,
! 		    krb5_pa_data **send_pa,
! 		    void *opaque));
! 
  /*
   * Preauth property flags
   */
***************
*** 154,159 ****
--- 218,247 ----
  	return_pw_salt
      },
      {
+ 	"alt-princ-val",
+ 	KRB5_PADATA_ALT_PRINC,
+ 	PA_HARDWARE,
+ 	get_alt_princ_edata,
+ 	cache_alt_princ,
+ 	return_alt_princ,
+     },
+     {
+ 	"sam-response-2",
+ 	KRB5_PADATA_SAM_RESPONSE_2,
+ 	0,
+ 	0,
+ 	verify_sam_response_2,
+ 	return_sam_data_2
+     },
+     {
+ 	"sam-challenge-2",
+ 	KRB5_PADATA_SAM_CHALLENGE_2,
+ 	PA_HARDWARE,		/* causes get_preauth_hint_list to use this */
+ 	get_sam_edata_2,
+ 	0,
+ 	0
+     },
+     {
  	"sam-response",
  	KRB5_PADATA_SAM_RESPONSE,
  	0,
***************
*** 169,174 ****
--- 257,272 ----
  	0,
  	0
      },
+ #ifdef KRB5_CRYPTOCARD_VALIDATE
+     {
+ 	"cryptocard-val",
+ 	KRB5_PADATA_AS_REP,
+ 	0,
+ 	0,
+ 	0,
+ 	return_pa_as_rep,
+     },
+ #endif /* KRB5_CRYPTOCARD_VALIDATE */
      { "[end]", -1,}
  };
  
***************
*** 189,197 ****
      return 0;
  } 
  
! const char *missing_required_preauth(client, server, enc_tkt_reply)
      krb5_db_entry *client, *server;
      krb5_enc_tkt_part *enc_tkt_reply;
  {
  #if 0
      /*
--- 287,296 ----
      return 0;
  } 
  
! const char *missing_required_preauth(client, server, enc_tkt_reply, request)
      krb5_db_entry *client, *server;
      krb5_enc_tkt_part *enc_tkt_reply;
+     krb5_kdc_req *request;
  {
  #if 0
      /*
***************
*** 223,235 ****
  	!isflagset(enc_tkt_reply->flags, TKT_FLG_HW_AUTH))
  	return "NEEDED_HW_PREAUTH";
  
      return 0;
  }
  
! void get_preauth_hint_list(request, client, server, e_data)
      krb5_kdc_req *request;
      krb5_db_entry *client, *server;
      krb5_data *e_data;
  {
      int hw_only;
      krb5_preauth_systems *ap;
--- 322,347 ----
  	!isflagset(enc_tkt_reply->flags, TKT_FLG_HW_AUTH))
  	return "NEEDED_HW_PREAUTH";
  
+     /*
+      * Sigh, this is a bit weird.
+      *
+      * We want the client to be able to initiatate hardware preauthentication,
+      * because he may not always want it (for example, a "trusted" client
+      * may require hardware preauth for root access, but not otherwise).
+      */
+ 
+     if (isflagset(request->kdc_options, KDC_OPT_HW_AUTH) &&
+ 	!isflagset(enc_tkt_reply->flags, TKT_FLG_HW_AUTH))
+ 	return "REQUESTED_HW_PREAUTH";
+ 
      return 0;
  }
  
! void get_preauth_hint_list(request, client, server, e_data, opaque)
      krb5_kdc_req *request;
      krb5_db_entry *client, *server;
      krb5_data *e_data;
+     void *opaque;
  {
      int hw_only;
      krb5_preauth_systems *ap;
***************
*** 241,247 ****
      e_data->length = 0;
      e_data->data = 0;
      
!     hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
      pa_data = malloc(sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
      if (pa_data == 0)
  	return;
--- 353,360 ----
      e_data->length = 0;
      e_data->data = 0;
      
!     hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH) ||
! 	      isflagset(request->kdc_options, KDC_OPT_HW_AUTH);
      pa_data = malloc(sizeof(krb5_pa_data *) * (MAX_PREAUTH_SYSTEMS+1));
      if (pa_data == 0)
  	return;
***************
*** 260,266 ****
  	(*pa)->magic = KV5M_PA_DATA;
  	(*pa)->pa_type = ap->type;
  	if (ap->get_edata) {
! 	  retval = (ap->get_edata)(kdc_context, request, client, server, *pa);
  	  if (retval) {
  	    /* just failed on this type, continue */
  	    free(*pa);
--- 373,380 ----
  	(*pa)->magic = KV5M_PA_DATA;
  	(*pa)->pa_type = ap->type;
  	if (ap->get_edata) {
! 	  retval = (ap->get_edata)(kdc_context, request, client, server, *pa,
! 				   opaque);
  	  if (retval) {
  	    /* just failed on this type, continue */
  	    free(*pa);
***************
*** 274,279 ****
--- 388,405 ----
  	krb5_klog_syslog (LOG_INFO,
  			  "%spreauth required but hint list is empty",
  			  hw_only ? "hw" : "");
+ 	if (hw_only) {
+ 	   /* We are requiring Hardware authentication but have no way of
+ 	    * dealing with it (no SAM methods defined or no preauth mechs
+ 	    * available for KDC to suggest to client.
+ 	    *
+ 	    * Don't send back ANY error text to client since this will cause
+ 	    * get_in_tkt() to loop.  This should only happen when the user
+ 	    * has not been set up properly in the database (w/ SAM hwauth
+ 	    * principal.  This gives admins a better error message.  [tadhack]
+ 	    */
+ 	   goto errout;
+ 	}
      }
      retval = encode_krb5_padata_sequence((const krb5_pa_data **) pa_data,
  					 &edat);
***************
*** 296,306 ****
   */
  
  krb5_error_code
! check_padata (context, client, request, enc_tkt_reply)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
  {
      krb5_error_code retval = 0;
      krb5_pa_data **padata;
--- 422,433 ----
   */
  
  krb5_error_code
! check_padata (context, client, request, enc_tkt_reply, opaque)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
+     void **		opaque;
  {
      krb5_error_code retval = 0;
      krb5_pa_data **padata;
***************
*** 322,332 ****
  #ifdef DEBUG
  	krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name);
  #endif
  	if (pa_sys->verify_padata == 0)
  	    continue;
  	pa_found++;
  	retval = pa_sys->verify_padata(context, client, request,
! 				       enc_tkt_reply, *padata);
  	if (retval) {
  	    krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
  			      pa_sys->name, error_message (retval));
--- 449,460 ----
  #ifdef DEBUG
  	krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name);
  #endif
+ 
  	if (pa_sys->verify_padata == 0)
  	    continue;
  	pa_found++;
  	retval = pa_sys->verify_padata(context, client, request,
! 				       enc_tkt_reply, *padata, opaque);
  	if (retval) {
  	    krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
  			      pa_sys->name, error_message (retval));
***************
*** 364,376 ****
   */
  krb5_error_code
  return_padata(context, client, request, reply,
! 	      client_key, encrypting_key)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_kdc_rep *	reply;
      krb5_key_data *	client_key;
      krb5_keyblock *	encrypting_key;
  {
      krb5_error_code		retval;
      krb5_pa_data **		padata;
--- 492,505 ----
   */
  krb5_error_code
  return_padata(context, client, request, reply,
! 	      client_key, encrypting_key, opaque)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_kdc_rep *	reply;
      krb5_key_data *	client_key;
      krb5_keyblock *	encrypting_key;
+     void *		opaque;
  {
      krb5_error_code		retval;
      krb5_pa_data **		padata;
***************
*** 404,410 ****
  	    }
  	}
  	if ((retval = ap->return_padata(context, pa, client, request, reply,
! 					client_key, encrypting_key, send_pa)))
  	    goto cleanup;
  
  	if (*send_pa)
--- 533,540 ----
  	    }
  	}
  	if ((retval = ap->return_padata(context, pa, client, request, reply,
! 					client_key, encrypting_key, send_pa,
! 					opaque)))
  	    goto cleanup;
  
  	if (*send_pa)
***************
*** 426,437 ****
  }
  
  static krb5_error_code
! verify_enc_timestamp(context, client, request, enc_tkt_reply, pa)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
      krb5_pa_data *	pa;
  {
      krb5_pa_enc_ts *		pa_enc = 0;
      krb5_error_code		retval;
--- 556,568 ----
  }
  
  static krb5_error_code
! verify_enc_timestamp(context, client, request, enc_tkt_reply, pa, opaque)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
      krb5_pa_data *	pa;
+     void **		opaque;
  {
      krb5_pa_enc_ts *		pa_enc = 0;
      krb5_error_code		retval;
***************
*** 443,455 ****
      krb5_int32			start;
      krb5_timestamp		timenow;
      
!     scratch.data = pa->contents;
      scratch.length = pa->length;
  
      enc_ts_data.data = 0;
      
!     if ((retval = decode_krb5_enc_data(&scratch, &enc_data)) != 0)
  	goto cleanup;
  
      enc_ts_data.length = enc_data->ciphertext.length;
      if ((enc_ts_data.data = (char *) malloc(enc_ts_data.length)) == NULL)
--- 574,588 ----
      krb5_int32			start;
      krb5_timestamp		timenow;
      
!     scratch.data = (char *) pa->contents;
      scratch.length = pa->length;
  
      enc_ts_data.data = 0;
      
!     if ((retval = decode_krb5_enc_data(&scratch, &enc_data)) != 0) {
! 	enc_data = NULL;
  	goto cleanup;
+     }
  
      enc_ts_data.length = enc_data->ciphertext.length;
      if ((enc_ts_data.data = (char *) malloc(enc_ts_data.length)) == NULL)
***************
*** 475,482 ****
  	    break;
      }
  
!     if ((retval = decode_krb5_pa_enc_ts(&enc_ts_data, &pa_enc)) != 0)
  	goto cleanup;
  
      if ((retval = krb5_timeofday(context, &timenow)) != 0)
  	goto cleanup;
--- 608,617 ----
  	    break;
      }
  
!     if ((retval = decode_krb5_pa_enc_ts(&enc_ts_data, &pa_enc)) != 0) {
! 	pa_enc = NULL;
  	goto cleanup;
+     }
  
      if ((retval = krb5_timeofday(context, &timenow)) != 0)
  	goto cleanup;
***************
*** 507,518 ****
   * message.
   */
  static krb5_error_code
! get_etype_info(context, request, client, server, pa_data)
      krb5_context 	context;
      krb5_kdc_req *	request;
      krb5_db_entry *	client;
      krb5_db_entry *	server;
      krb5_pa_data *	pa_data;
  {
      krb5_etype_info_entry **	entry = 0;
      krb5_key_data		*client_key;
--- 642,654 ----
   * message.
   */
  static krb5_error_code
! get_etype_info(context, request, client, server, pa_data, opaque)
      krb5_context 	context;
      krb5_kdc_req *	request;
      krb5_db_entry *	client;
      krb5_db_entry *	server;
      krb5_pa_data *	pa_data;
+     void *		opaque;
  {
      krb5_etype_info_entry **	entry = 0;
      krb5_key_data		*client_key;
***************
*** 557,563 ****
  		goto cleanup;
  	    if (salt.length >= 0) {
  		entry[i]->length = salt.length;
! 		entry[i]->salt = salt.data;
  		salt.data = 0;
  	    }
  	    i++;
--- 693,699 ----
  		goto cleanup;
  	    if (salt.length >= 0) {
  		entry[i]->length = salt.length;
! 		entry[i]->salt = (unsigned char *) salt.data;
  		salt.data = 0;
  	    }
  	    i++;
***************
*** 575,581 ****
  				    &scratch);
      if (retval)
  	goto cleanup;
!     pa_data->contents = scratch->data;
      pa_data->length = scratch->length;
      free(scratch);
  
--- 711,717 ----
  				    &scratch);
      if (retval)
  	goto cleanup;
!     pa_data->contents = (unsigned char *) scratch->data;
      pa_data->length = scratch->length;
      free(scratch);
  
***************
*** 591,597 ****
  
  static krb5_error_code
  return_pw_salt(context, in_padata, client, request, reply, client_key,
! 	       encrypting_key, send_pa)
      krb5_context	context;
      krb5_pa_data *	in_padata;
      krb5_db_entry *	client;
--- 727,733 ----
  
  static krb5_error_code
  return_pw_salt(context, in_padata, client, request, reply, client_key,
! 	       encrypting_key, send_pa, opaque)
      krb5_context	context;
      krb5_pa_data *	in_padata;
      krb5_db_entry *	client;
***************
*** 600,605 ****
--- 736,742 ----
      krb5_key_data *	client_key;
      krb5_keyblock *	encrypting_key;
      krb5_pa_data **	send_pa;
+     void *		opaque;
  {
      krb5_error_code	retval;
      krb5_pa_data *	padata;
***************
*** 635,640 ****
--- 772,799 ----
  	   do the work. In the future, add a kdc configuration
  	   variable that specifies the old cell name. */
  	padata->pa_type = KRB5_PADATA_AFS3_SALT;
+ #ifdef KRB5_KDC_AFS3_USE_CONTENTS
+ 	/*
+ 	 * Check to see if key_data_contents[1] contains information
+ 	 * and if it does, use that for the salt instead of our realm.
+ 	 * The intention is that afs2k5db will put the old AFS cell
+ 	 * name here and we want to use that in cases where it
+ 	 * differs from the Kerberos 5 realm name.
+ 	 */
+ 	if (client_key->key_data_length[1]) {
+ 	    	padata->length = client_key->key_data_length[1];
+ 		if ((padata->contents = malloc(padata->length)) == NULL) {
+ 		    retval = ENOMEM;
+ 		    goto cleanup;
+ 		}
+ 		memcpy(padata->contents, client_key->key_data_contents[1],
+ 		       client_key->key_data_length[1]);
+ 		padata->length = client_key->key_data_length[1];
+ 		break;
+ 	}
+ 	/* else fall through */
+ #endif /* KRB5_KDC_AFS3_USE_CONTENTS */
+ 
  	/* it would be just like ONLYREALM, but we need to pass the 0 */
  	scratch = krb5_princ_realm(kdc_context, request->client);
  	if ((padata->contents = malloc(scratch->length+1)) == NULL) {
***************
*** 677,685 ****
      return retval;
  }
  
  static krb5_error_code
  return_sam_data(context, in_padata, client, request, reply, client_key,
! 	        encrypting_key, send_pa)
      krb5_context	context;
      krb5_pa_data *	in_padata;
      krb5_db_entry *	client;
--- 836,1019 ----
      return retval;
  }
  
+ #ifdef KRB5_CRYPTOCARD_VALIDATE
+ static krb5_error_code
+ return_pa_as_rep(context, in_padata, client, request, reply, client_key,
+ 	         encrypting_key, send_pa, opaque)
+     krb5_context	context;
+     krb5_pa_data *	in_padata;
+     krb5_db_entry *	client;
+     krb5_kdc_req *	request;
+     krb5_kdc_rep *	reply;
+     krb5_key_data *	client_key;
+     krb5_keyblock *	encrypting_key;
+     krb5_pa_data **	send_pa;
+     void *		opaque;
+ {
+     int c_nprincs = 0;
+     krb5_principal	sprinc = NULL;
+     krb5_db_entry	server;
+     krb5_key_data *	server_key;
+     krb5_keyblock 	server_keyblock;
+     krb5_error_code	code = 0;
+     krb5_boolean	more;
+     krb5_pa_data *	padata;
+     krb5_data		encoded_data;
+     krb5_data *		response;
+     krb5_enc_kdc_rep_part reply_encpart;
+     krb5_timestamp	kdc_time;
+     char *		sname = NULL;
+ 
+     /*
+      * Don't send anything if we didn't ask for it, or if we don't have
+      * hardware preauth.
+      */
+ 
+     if (! in_padata || !isflagset(reply->ticket->enc_part2->flags,
+ 				  TKT_FLG_HW_AUTH))
+ 	return 0;
+ 
+     server_keyblock.contents = NULL;
+ 
+     /*
+      * Decode the principal that was sent in this message
+      */
+ 
+     encoded_data.data = (char *) in_padata->contents;
+     encoded_data.length = in_padata->length;
+ 
+     if ((code = decode_krb5_principal(&encoded_data, &sprinc))) {
+ 	krb5_klog_syslog(LOG_INFO, "Can't decode encryption principal for "
+ 			 "PA-AS-REP: %s", error_message(code));
+ 	sprinc = NULL;
+ 	goto out;
+     }
+ 
+     if ((code = krb5_unparse_name(kdc_context, sprinc, &sname))) {
+ 	krb5_klog_syslog(LOG_INFO, "Can't unparse encrpytion principal for "
+ 			 "PA-AS-REP: %s", error_message(code));
+ 	goto out;
+     }
+ 
+     limit_string(sname);
+ 
+     /*
+      * The principal the key is encrypted in is sent in the in_padata
+      * field.
+      */
+ 
+     c_nprincs = 1;
+     
+     if ((code = krb5_db_get_principal(kdc_context, sprinc,
+ 				      &server, &c_nprincs, &more))) {
+ 	krb5_klog_syslog(LOG_INFO, "Can't find encryption principal %s for "
+ 			 " PA-AS-REP: %s", sname, error_message(code));
+ 	goto out;
+     }
+ 
+     if (more) {
+ 	krb5_klog_syslog(LOG_INFO, "More than one principal %s for PA-AS-REP",
+ 			 sname);
+ 	goto out;
+     } else if (c_nprincs != 1) {
+ 	
+ 	krb5_klog_syslog(LOG_INFO, "%s not found for PA-AS-REP", sname);
+ 	goto out;
+     }
+ 
+     if ((code = krb5_dbe_find_enctype(kdc_context, &server,
+ 				      -1, /* Ignore keytype */
+ 				      -1, /* Ignore salttype */
+ 				      0, /* Get highest kvno */
+ 				      &server_key))) {
+ 	krb5_klog_syslog(LOG_INFO, "Error while looking up key for principal "
+ 			 "%s for PA-AS-REP: %s", sname, error_message(code));
+ 	goto out;
+     }
+ 
+     if ((code = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock,
+ 					    server_key, &server_keyblock,
+ 					    NULL))) {
+ 	krb5_klog_syslog(LOG_INFO, "Error while decrypting principal %s key "
+ 			 "data for PA-AS-REP: %s", sname, error_message(code));
+ 	goto out;
+     }
+ 
+     /*
+      * _Whew_!  We've got the principal key, _FINALLY_.  Make a complete
+      * AS-REP, but put it in the preauth message.
+      */
+ 
+     if ((padata = malloc(sizeof(krb5_pa_data))) == NULL) {
+ 	code = ENOMEM;
+ 	goto errout;
+     }
+ 
+     /*
+      * Unfortunately, since we didn't get passed in the reply_encpart,
+      * we need to generate our own here.
+      */
+ 
+     reply_encpart.session = reply->ticket->enc_part2->session;
+     if ((code = fetch_last_req_info(client, &reply_encpart.last_req))) {
+ 	krb5_klog_syslog(LOG_INFO, "Cannot fetch client LAST-REQ info: %s",
+ 			 error_message(code));
+ 	goto out;
+     }
+ 
+     reply_encpart.nonce = request->nonce;
+     reply_encpart.key_exp = client->expiration;
+     reply_encpart.flags = reply->ticket->enc_part2->flags;
+     reply_encpart.server = reply->ticket->server;
+     reply_encpart.times = reply->ticket->enc_part2->times;
+ 
+     if ((code = krb5_timeofday(kdc_context, &kdc_time))) {
+ 	krb5_klog_syslog(LOG_INFO, "Cannot get time of day for PA-AS-REP: %s",
+ 			 error_message(code));
+ 	goto out;
+     }
+ 
+     reply_encpart.times.authtime = kdc_time;
+     reply_encpart.caddrs = reply->ticket->enc_part2->caddrs;
+     reply->enc_part.enctype = server_keyblock.enctype;
+ 
+     if ((code = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
+ 				    0, &server_keyblock, reply, &response))) {
+ 	krb5_klog_syslog(LOG_INFO, "Failed to encode KDC reply for PA-AS-REP: "
+ 			 "%s", error_message(code));
+ 	goto out;
+     }
+ 
+     padata->pa_type = KRB5_PADATA_AS_REP;
+     padata->length = response->length;
+     padata->contents = (unsigned char *) response->data;
+     krb5_xfree(response);
+     *send_pa = padata;
+     padata = NULL;
+ 
+ out:
+     code = 0;
+ errout:
+     if (padata)
+ 	free(padata);
+     if (sname)
+ 	free(sname);
+     if (server_keyblock.contents) {
+ 	memset((char *) server_keyblock.contents, 0, server_keyblock.length);
+ 	krb5_xfree(server_keyblock.contents);
+     }
+     if (sprinc)
+ 	krb5_free_principal(kdc_context, sprinc);
+     if (c_nprincs)
+ 	krb5_db_free_principal(kdc_context, &server, c_nprincs);
+ 
+     return code;
+ }
+ #endif /* KRB5_CRYPTOCARD_VALIDATE */
+ 
  static krb5_error_code
  return_sam_data(context, in_padata, client, request, reply, client_key,
! 	        encrypting_key, send_pa, opaque)
      krb5_context	context;
      krb5_pa_data *	in_padata;
      krb5_db_entry *	client;
***************
*** 688,693 ****
--- 1022,1028 ----
      krb5_key_data *	client_key;
      krb5_keyblock *	encrypting_key;
      krb5_pa_data **	send_pa;
+     void *		opaque;
  {
      krb5_error_code	retval;
      krb5_data		scratch;
***************
*** 696,702 ****
      krb5_sam_response		*sr = 0;
      krb5_predicted_sam_response	*psr = 0;
  
!     if (in_padata == 0)
  	return 0;
  
      /*
--- 1031,1037 ----
      krb5_sam_response		*sr = 0;
      krb5_predicted_sam_response	*psr = 0;
  
!     if ((!krb5kdc_sam_allow_old_sam) || (in_padata == 0))
  	return 0;
  
      /*
***************
*** 706,721 ****
       * all this once.
       */
  
!     scratch.data = in_padata->contents;
      scratch.length = in_padata->length;
      
      if ((retval = decode_krb5_sam_response(&scratch, &sr))) {
  	com_err("krb5kdc", retval,
  		"return_sam_data(): decode_krb5_sam_response failed");
  	goto cleanup;
      }
  
!     {
  	krb5_enc_data tmpdata;
  
  	tmpdata.enctype = ENCTYPE_UNKNOWN;
--- 1041,1061 ----
       * all this once.
       */
  
!     scratch.data = (char *) in_padata->contents;
      scratch.length = in_padata->length;
      
      if ((retval = decode_krb5_sam_response(&scratch, &sr))) {
  	com_err("krb5kdc", retval,
  		"return_sam_data(): decode_krb5_sam_response failed");
+ 	sr = NULL;
  	goto cleanup;
      }
  
!     if (sr && ((sr->sam_type == PA_SAM_TYPE_SECURID) ||
! 		(sr->sam_type == PA_SAM_TYPE_CRYPTOCARD))) {
! 	/* We don't need to do anything here */
!     } else {
!       {
  	krb5_enc_data tmpdata;
  
  	tmpdata.enctype = ENCTYPE_UNKNOWN;
***************
*** 734,770 ****
  	    free(scratch.data);
  	    goto cleanup;
  	}
!     }
  
!     if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) {
  	com_err("krb5kdc", retval,
  		"return_sam_data(): decode_krb5_predicted_sam_response failed");
  	free(scratch.data);
  	goto cleanup;
!     }
  
!     /* We could use sr->sam_flags, but it may be absent or altered. */
!     if (psr->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) {
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Unsupported SAM flag must-pk-encrypt-sad");
  	goto cleanup;
!     }
!     if (psr->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
  	/* No key munging */
  	goto cleanup;
!     }
!     if (psr->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) {
  	/* Use sam_key instead of client key */
  	krb5_free_keyblock_contents(context, encrypting_key);
  	krb5_copy_keyblock_contents(context, &psr->sam_key, encrypting_key);
  	/* XXX Attach a useful pa_data */
  	goto cleanup;
!     }
  
!     /* Otherwise (no flags set), we XOR the keys */
!     /* XXX The passwords-04 draft is underspecified here wrt different
  	   key types. We will do what I hope to get into the -05 draft. */
!     {
  	krb5_octet *p = encrypting_key->contents;
  	krb5_octet *q = psr->sam_key.contents;
  	int length = ((encrypting_key->length < psr->sam_key.length)
--- 1074,1111 ----
  	    free(scratch.data);
  	    goto cleanup;
  	}
!       }
  
!       if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) {
  	com_err("krb5kdc", retval,
  		"return_sam_data(): decode_krb5_predicted_sam_response failed");
+ 	psr = NULL;
  	free(scratch.data);
  	goto cleanup;
!       }
  
!       /* We could use sr->sam_flags, but it may be absent or altered. */
!       if (psr->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) {
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Unsupported SAM flag must-pk-encrypt-sad");
  	goto cleanup;
!       }
!       if (psr->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
  	/* No key munging */
  	goto cleanup;
!       }
!       if (psr->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) {
  	/* Use sam_key instead of client key */
  	krb5_free_keyblock_contents(context, encrypting_key);
  	krb5_copy_keyblock_contents(context, &psr->sam_key, encrypting_key);
  	/* XXX Attach a useful pa_data */
  	goto cleanup;
!       }
  
!       /* Otherwise (no flags set), we XOR the keys */
!       /* XXX The passwords-04 draft is underspecified here wrt different
  	   key types. We will do what I hope to get into the -05 draft. */
!       {
  	krb5_octet *p = encrypting_key->contents;
  	krb5_octet *q = psr->sam_key.contents;
  	int length = ((encrypting_key->length < psr->sam_key.length)
***************
*** 773,795 ****
  
  	for (i = 0; i < length; i++)
  	    p[i] ^= q[i];
!     }
  
!     /* Post-mixing key correction */
!     switch (encrypting_key->enctype) {
!     case ENCTYPE_DES_CBC_CRC:
!     case ENCTYPE_DES_CBC_MD4:
!     case ENCTYPE_DES_CBC_MD5:
!     case ENCTYPE_DES_CBC_RAW:
  	mit_des_fixup_key_parity(encrypting_key->contents);
  	if (mit_des_is_weak_key(encrypting_key->contents))
  	    ((krb5_octet *) encrypting_key->contents)[7] ^= 0xf0;
  	break;
  
!     /* XXX case ENCTYPE_DES3_CBC_MD5: listed in 1510bis-04 draft */
!     case ENCTYPE_DES3_CBC_SHA: /* XXX deprecated? */
!     case ENCTYPE_DES3_CBC_RAW:
!     case ENCTYPE_DES3_CBC_SHA1:
  	for (i = 0; i < 3; i++) {
  	    mit_des_fixup_key_parity(encrypting_key->contents + i * 8);
  	    if (mit_des_is_weak_key(encrypting_key->contents + i * 8))
--- 1114,1136 ----
  
  	for (i = 0; i < length; i++)
  	    p[i] ^= q[i];
!       }
  
!       /* Post-mixing key correction */
!       switch (encrypting_key->enctype) {
!       case ENCTYPE_DES_CBC_CRC:
!       case ENCTYPE_DES_CBC_MD4:
!       case ENCTYPE_DES_CBC_MD5:
!       case ENCTYPE_DES_CBC_RAW:
  	mit_des_fixup_key_parity(encrypting_key->contents);
  	if (mit_des_is_weak_key(encrypting_key->contents))
  	    ((krb5_octet *) encrypting_key->contents)[7] ^= 0xf0;
  	break;
  
!       /* XXX case ENCTYPE_DES3_CBC_MD5: listed in 1510bis-04 draft */
!       case ENCTYPE_DES3_CBC_SHA: /* XXX deprecated? */
!       case ENCTYPE_DES3_CBC_RAW:
!       case ENCTYPE_DES3_CBC_SHA1:
  	for (i = 0; i < 3; i++) {
  	    mit_des_fixup_key_parity(encrypting_key->contents + i * 8);
  	    if (mit_des_is_weak_key(encrypting_key->contents + i * 8))
***************
*** 797,807 ****
  	}
  	break;
  
!     default:
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Unimplemented keytype for SAM key mixing");
  	goto cleanup;
!     }
  
      /* XXX Attach a useful pa_data */
  cleanup:
--- 1138,1149 ----
  	}
  	break;
  
!       default:
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Unimplemented keytype for SAM key mixing");
  	goto cleanup;
!       }
!     } /* sr->sam_type != SecurID */
  
      /* XXX Attach a useful pa_data */
  cleanup:
***************
*** 820,835 ****
    { "SNK4", PA_SAM_TYPE_DIGI_PATH, },
    { "SECURID", PA_SAM_TYPE_SECURID, },
    { "GRAIL", PA_SAM_TYPE_GRAIL, },
    { 0, 0 },
  };
  
  static krb5_error_code
! get_sam_edata(context, request, client, server, pa_data)
      krb5_context 	context;
      krb5_kdc_req *	request;
      krb5_db_entry *	client;
      krb5_db_entry *	server;
      krb5_pa_data *	pa_data;
  {
      krb5_error_code		retval;
      krb5_sam_challenge		sc;
--- 1162,1189 ----
    { "SNK4", PA_SAM_TYPE_DIGI_PATH, },
    { "SECURID", PA_SAM_TYPE_SECURID, },
    { "GRAIL", PA_SAM_TYPE_GRAIL, },
+   { "RB1", PA_SAM_TYPE_CRYPTOCARD, },
    { 0, 0 },
  };
  
+ typedef struct _preauth_info {
+     int			slot;
+     krb5_principal	altprinc;
+     char		*altprincstring;
+     krb5_db_entry	*entry;
+ } preauth_info;
+ 
+ #define	RB1_CHALLENGE_LENGTH	8	/* Must be <= sizeof(inputblock) */
+ #include "sam2.c"
+ 
  static krb5_error_code
! get_sam_edata(context, request, client, server, pa_data, opaque)
      krb5_context 	context;
      krb5_kdc_req *	request;
      krb5_db_entry *	client;
      krb5_db_entry *	server;
      krb5_pa_data *	pa_data;
+     void *		opaque;
  {
      krb5_error_code		retval;
      krb5_sam_challenge		sc;
***************
*** 839,844 ****
--- 1193,1209 ----
      char response[9];
      char inputblock[8];
      krb5_data predict_response;
+     krb5_db_entry assoc;
+     int npr = 0;
+ 
+     if (!krb5kdc_sam_allow_old_sam)
+ 	return(KRB5KDC_ERR_PREAUTH_REQUIRED);
+ 
+     /*
+      * Make sure we don't segfault in cleanup if encrypting.key_length
+      * isn't initialized.
+      */
+     memset((char *) &encrypting_key, 0, sizeof(encrypting_key));
  
      memset(&sc, 0, sizeof(sc));
      memset(&psr, 0, sizeof(psr));
***************
*** 859,865 ****
      {
        int npr = 1;
        krb5_boolean more;
-       krb5_db_entry assoc;
        krb5_key_data  *assoc_key;
        krb5_principal newp;
        int probeslot;
--- 1224,1229 ----
***************
*** 881,887 ****
  	krb5_princ_component(kdc_context,newp,probeslot)->data = sam_ptr->name;
  	krb5_princ_component(kdc_context,newp,probeslot)->length = 
  	  strlen(sam_ptr->name);
- 	npr = 1;
  	retval = krb5_db_get_principal(kdc_context, newp, &assoc, &npr, &more);
  	if(!retval && npr) {
  	  sc.sam_type = sam_ptr->sam_type;
--- 1245,1250 ----
***************
*** 942,947 ****
--- 1305,1327 ----
  #endif /* USE_RCACHE */
  
      switch (sc.sam_type) {
+ #ifdef ARL_SECURID_PREAUTH
+     case PA_SAM_TYPE_SECURID:
+       if (pa_data->length) {
+ 	retval = 0;
+ 	break;
+       }
+       if (retval = get_securid_edata(context, client, &sc))
+ 	goto cleanup;
+       if (retval = encode_krb5_sam_challenge(&sc, &scratch))
+ 	goto cleanup;
+       pa_data->magic = KV5M_PA_DATA;
+       pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
+       pa_data->contents = scratch->data;
+       pa_data->length = scratch->length;
+       retval = 0;
+       break;
+ #endif /* ARL_SECURID_PREAUTH */
      case PA_SAM_TYPE_GRAIL:
        sc.sam_type_name.data = "Experimental System";
        sc.sam_type_name.length = strlen(sc.sam_type_name.data);
***************
*** 1018,1024 ****
        if (retval) goto cleanup;
        pa_data->magic = KV5M_PA_DATA;
        pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
!       pa_data->contents = scratch->data;
        pa_data->length = scratch->length;
        
        retval = 0;
--- 1398,1404 ----
        if (retval) goto cleanup;
        pa_data->magic = KV5M_PA_DATA;
        pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
!       pa_data->contents = (unsigned char *) scratch->data;
        pa_data->length = scratch->length;
        
        retval = 0;
***************
*** 1054,1060 ****
  	if (session_key.length != 8) {
  	  com_err("krb5kdc", retval = KRB5KDC_ERR_ETYPE_NOSUPP,
  		  "keytype didn't match code expectations");
! 	  return retval;
  	}
  	for(i = 0; i<6; i++) {
  	  inputblock[i] = '0' + ((session_key.contents[i]/2) % 10);
--- 1434,1440 ----
  	if (session_key.length != 8) {
  	  com_err("krb5kdc", retval = KRB5KDC_ERR_ETYPE_NOSUPP,
  		  "keytype didn't match code expectations");
! 	  goto cleanup;
  	}
  	for(i = 0; i<6; i++) {
  	  inputblock[i] = '0' + ((session_key.contents[i]/2) % 10);
***************
*** 1071,1079 ****
--- 1451,1476 ----
  
  	if (retval) {
  	  com_err("krb5kdc", retval, "snk4 processing key");
+ 	  goto cleanup;
  	}
  
  	{
+ #if 0
+ 	/* Old code */
+ 	  char ivec[8];
+ 	  memset(ivec,0,8);
+ 	  retval = krb5_encrypt(kdc_context, inputblock, outputblock, 8,
+ 				&eblock, ivec);
+ 	}
+ 	if (retval) {
+ 	  com_err("krb5kdc", retval, "snk4 response generation failed");
+ 	  goto cleanup;
+ 	}
+ 	retval = krb5_finish_key(kdc_context, &eblock);
+ 	if (retval) {
+ 	  com_err("krb5kdc", retval, "snk4 key post-processing");
+ 	  goto cleanup;
+ #endif
  	    krb5_data plain;
  	    krb5_enc_data cipher;
  
***************
*** 1186,1210 ****
        if (retval) goto cleanup;
        pa_data->magic = KV5M_PA_DATA;
        pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
!       pa_data->contents = scratch->data;
        pa_data->length = scratch->length;
        
        retval = 0;
        break;
      }
  
  cleanup:
      krb5_free_keyblock_contents(context, &encrypting_key);
      return retval;
  }
  
  static krb5_error_code
! verify_sam_response(context, client, request, enc_tkt_reply, pa)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
      krb5_pa_data *	pa;
  {
      krb5_error_code		retval;
      krb5_data			scratch;
--- 1583,1846 ----
        if (retval) goto cleanup;
        pa_data->magic = KV5M_PA_DATA;
        pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
!       pa_data->contents = (unsigned char *) scratch->data;
        pa_data->length = scratch->length;
        
        retval = 0;
        break;
+ 
+     /*
+      * The CryptoCard RB-1 is sort of like the Digital Pathways cards;
+      * they're straight DES encryptors, but the output is slightly
+      * different.  They also have a way of doing challenge precomputation
+      */
+     case PA_SAM_TYPE_CRYPTOCARD:
+     {
+       krb5_tl_data tl_data;
+       krb5_rb1_track_data rb1_track_data;
+       krb5_data rb1_data;
+       krb5_enc_data rb1_enc_data;
+       char outputblock[8];
+       int i;
+ 
+       sc.sam_type_name.data = "CryptoCard RB-1";
+       sc.sam_type_name.length = strlen(sc.sam_type_name.data);
+ 
+       tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE;
+ 
+       memset(&rb1_enc_data, 0, sizeof(rb1_enc_data));
+ 
+       if ((retval = krb5_dbe_lookup_tl_data(kdc_context, &assoc, &tl_data)) ||
+ 	  (tl_data.tl_data_length == 0)) {
+ 	  /*
+ 	   * No precomputed challenge, so let's make a new one
+ 	   *
+ 	   * What happens here is close to the Digital Pathways challenge
+ 	   * generation: We generate a random key and take each byte,
+ 	   * divide by 2 and do a mod 10.  Note that we do this for
+ 	   * 8 bytes, instead of the SNK 6 bytes.  The challenge length
+ 	   * should probably be configurable ...
+ 	   */
+ 	  memset(inputblock, 0, sizeof(inputblock));
+ 
+ 	  rb1_data.data = inputblock;
+ 	  rb1_data.length = RB1_CHALLENGE_LENGTH;
+ 
+ 	  if (retval = krb5_c_random_make_octets(kdc_context, &rb1_data)) {
+ 	    com_err("krb5kdc", retval,"generating random challenge for preauth");
+ 	    return retval;
+ 	  }
+ 
+ 	  for(i = 0; i<RB1_CHALLENGE_LENGTH; i++) {
+ 	    inputblock[i] = '0' + ((inputblock[i] & 0x7f ) % 10);
+ 	  }
+ 
+           sc.sam_challenge_label.data = "Press CH/MAC and enter this on the keypad";
+ 	  sc.sam_challenge.data = inputblock;
+ 	  sc.sam_challenge.length = RB1_CHALLENGE_LENGTH;
+       } else {
+ 	  /*
+ 	   * We had precomputed a challenge from before.  Use that instead
+ 	   */
+ 	  sc.sam_challenge_label.data =
+ 		"Press ENTER and compare this challenge to the one on your display";
+ 	  sc.sam_challenge.data = (char *) tl_data.tl_data_contents;
+ 	  sc.sam_challenge.length = tl_data.tl_data_length;
+ 	  if (tl_data.tl_data_length > sizeof(inputblock))
+ 		tl_data.tl_data_length = sizeof(inputblock);
+ 	  memcpy(inputblock, tl_data.tl_data_contents, tl_data.tl_data_length);
+ 	  rb1_data.data = inputblock;
+ 	  rb1_data.length = tl_data.tl_data_length;
+       }
+ 
+       sc.sam_challenge_label.length = strlen(sc.sam_challenge_label.data);
+ 
+       /* We really want to choose the RAW version of the specified cipher */
+       /* Should save real enctype in case we want to use it later on	  */
+ 
+       encrypting_key.enctype = ENCTYPE_DES_CBC_RAW;
+ 
+       retval = krb5_c_encrypt_length(kdc_context, encrypting_key.enctype,
+                 rb1_data.length,
+ 		(unsigned int *) &rb1_enc_data.ciphertext.length);
+       if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while getting encrypt_length to encrypt RB1 challenge");
+ 	goto cleanup;
+       }
+       if (rb1_enc_data.ciphertext.length > sizeof(outputblock)) {
+ 	com_err("krb5kdc", KRB5_BAD_MSIZE, "while encrypting RB1 challenge");
+ 	goto cleanup;
+       }
+ 
+       rb1_enc_data.ciphertext.length = sizeof(outputblock);
+       rb1_enc_data.ciphertext.data = outputblock;
+ 
+       retval = krb5_c_encrypt(kdc_context, &encrypting_key, /* Usage = 0 */  0,
+ 			NULL, &rb1_data, &rb1_enc_data);
+ 
+       /* We should restore original enctype to encrypting_key */
+ 
+       if (retval) {
+ 	com_err("krb5kdc", retval, "Trying to encrypt challenge");
+ 	goto cleanup;
+       }
+ 
+       /*
+        * Now convert the output block to something visible.  Turn
+        * the upper four bytes into ASCII (Also from SNK code).  Note
+        * that we want to use raw hex as the output from the RB-1,
+        * so it's a little different than the SNK code.
+        */
+ 
+       for (i=0; i<4; i++) {
+ 	char n[2];
+ 	n[0] = outputblock[i] & 0xf;
+ 	n[1] = (outputblock[i]>>4) & 0xf;
+ 	/* for v4, we keygen: *(j+(char*)&key1) = (n[1]<<4) | n[0]; */
+ 	/* for v5, we just generate a string */
+ 	rb1_track_data.ascii_response[2*i+0] = n[1] > 9 ?
+ 		n[1] - 10 + 'A' : '0' + n[1];
+ 	rb1_track_data.ascii_response[2*i+1] = n[0] > 9 ?
+ 		n[0] - 10 + 'A' : '0' + n[0];
+ 	/* and now, response has what we work with. */
+       }
+       rb1_track_data.ascii_response[8] = 0;
+       predict_response.data = rb1_track_data.ascii_response;
+       predict_response.length = 8;
+ 
+       /*
+        * We diverge from the SNK code here.
+        *
+        * Since we want to include both the response and the precomputed
+        * challenge for next time, we don't use predicted_sam_response
+        * but create our own structure for the track data (that's allowed
+        * by the spec).  First off, let's use the current response
+        * to generate the new challenge.
+        */
+ 
+       /*
+        * Simply take the full encrypted response block, convert it
+        * to ASCII numerals, and convert 0xa - 0xf to 0x0 - 0x05
+        */
+ 
+       for (i = 0; i < 8; i++) {
+ 	rb1_track_data.new_challenge[i] = (outputblock[i] & 0x0f) | 0x30;
+ 	if (rb1_track_data.new_challenge[i] > 0x39)
+ 		rb1_track_data.new_challenge[i] -= 10;
+       }
+ 
+       rb1_data.data = (void *) &rb1_track_data;
+       rb1_data.length = sizeof(rb1_track_data);
+ 
+       retval = krb5_c_encrypt_length(kdc_context, master_keyblock.enctype,
+ 		rb1_data.length,
+ 		(unsigned int *) &rb1_enc_data.ciphertext.length);
+       if (retval) {
+ 	com_err("krb5kdc", ENOMEM, "while getting length to encrypt RB1 sam_track_id");
+ 	goto cleanup;
+       }
+ 
+       rb1_enc_data.ciphertext.data = (char *) malloc(rb1_enc_data.ciphertext.length);
+       if (rb1_enc_data.ciphertext.data == NULL) {
+ 	com_err("krb5kdc", ENOMEM, "while allocating memory for RB1 sam_track_id");
+ 	goto cleanup;
+       }
+ 
+       retval = krb5_c_encrypt(kdc_context, &master_keyblock, /* Usage = 0 */ 0,
+ 		NULL, &rb1_data, &rb1_enc_data);
+       if (retval) {
+ 	free(rb1_enc_data.ciphertext.data);
+ 	com_err("krb5kdc", retval, "while encrypting RB1 sam_track_id");
+ 	goto cleanup;
+       }
+ 
+       sc.sam_track_id = rb1_enc_data.ciphertext;
+ 
+       sc.sam_response_prompt.data = "Enter the displayed response";
+       sc.sam_response_prompt.length = strlen(sc.sam_response_prompt.data);
+       sc.sam_pk_for_sad.length = 0;
+       sc.sam_nonce = 0;
+ 
+       /* Generate checksum */
+       retval = krb5_c_checksum_length(kdc_context, CKSUMTYPE_RSA_MD5_DES,
+ 		(unsigned int *) &sc.sam_cksum.length);
+       if (retval) {
+ 	com_err("krb5kdc", retval, "while computing length for RB1 sam_checksum");
+ 	goto cleanup;
+       }
+ 
+       sc.sam_cksum.contents = (krb5_octet *) malloc(sc.sam_cksum.length);
+       if (sc.sam_cksum.contents == NULL) {
+ 	retval = ENOMEM;
+ 	goto cleanup;
+       }
+ 
+       retval = krb5_c_string_to_key(kdc_context, ENCTYPE_DES_CBC_MD5,
+ 		&predict_response, NULL, &psr.sam_key);
+       if (retval) {
+ 	com_err("krb5kdc", retval, "while deriving RB1 sam_checksum key");
+ 	if (sc.sam_cksum.contents) {
+ 	   free(sc.sam_cksum.contents);
+ 	   sc.sam_cksum.contents = NULL;
+ 	}
+ 	goto cleanup;
+       }
+       retval = krb5_c_make_checksum(kdc_context, CKSUMTYPE_RSA_MD5_DES,
+ 			&psr.sam_key, /* Usage = 0 */ 0,
+ 			&sc.sam_challenge, &sc.sam_cksum);
+       krb5_free_keyblock_contents(kdc_context, &psr.sam_key);
+ 
+       if (retval) {
+ 	com_err("krb5kdc", retval, "while making RB1 sam_checksum");
+ 	if (sc.sam_cksum.contents) {
+ 	   free(sc.sam_cksum.contents);
+ 	   sc.sam_cksum.contents = NULL;
+ 	}
+ 	goto cleanup;
+       }
+ 
+       retval = encode_krb5_sam_challenge(&sc, &scratch);
+       if (rb1_enc_data.ciphertext.data) free(rb1_enc_data.ciphertext.data);
+       if (sc.sam_cksum.contents) {
+ 	free(sc.sam_cksum.contents);
+ 	sc.sam_cksum.contents = NULL;
+       }
+       if (retval) goto cleanup;
+ 
+       pa_data->magic = KV5M_PA_DATA;
+       pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
+       pa_data->contents = (unsigned char *) scratch->data;
+       pa_data->length = scratch->length;
+ 
+       break;
+     }
+ #ifdef ARL_SECURID_PREAUTHx	/* Don't really know why this is here.  This	*/
+     default:			/*  causes the ASN.1 missing req'd field msg	*/
+       pa_data->magic = KV5M_PA_DATA;
+       pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE;
+       pa_data->contents = 0;
+       pa_data->length = 0;
+       return(retval);
+       break;
+ #endif /* ARL_SECURID_PREAUTHx */
      }
  
  cleanup:
+     if (npr)
+        krb5_db_free_principal(kdc_context, &assoc, npr);
      krb5_free_keyblock_contents(context, &encrypting_key);
      return retval;
  }
  
  static krb5_error_code
! verify_sam_response(context, client, request, enc_tkt_reply, pa, opaque)
      krb5_context	context;
      krb5_db_entry *	client;
      krb5_kdc_req *	request;
      krb5_enc_tkt_part * enc_tkt_reply;
      krb5_pa_data *	pa;
+     void **		opaque;
  {
      krb5_error_code		retval;
      krb5_data			scratch;
***************
*** 1214,1230 ****
      krb5_timestamp		timenow;
      char			*princ_req = 0, *princ_psr = 0;
  
!     scratch.data = pa->contents;
      scratch.length = pa->length;
      
      if ((retval = decode_krb5_sam_response(&scratch, &sr))) {
  	scratch.data = 0;
  	com_err("krb5kdc", retval, "decode_krb5_sam_response failed");
  	goto cleanup;
      }
  
!     /* XXX We can only handle the challenge/response model of SAM.
! 	   See passwords-04, par 4.1, 4.2 */
      {
        krb5_enc_data tmpdata;
  
--- 1850,2105 ----
      krb5_timestamp		timenow;
      char			*princ_req = 0, *princ_psr = 0;
  
!     if (!krb5kdc_sam_allow_old_sam) {
!       char *user = NULL;
! 
!       if (krb5kdc_sam_warn_old_sam) {
! 	krb5_unparse_name(context, client->princ, &user);
! 	krb5_klog_syslog (LOG_INFO, "KDC denies use of old SAM protocol (%s)",
! 	     user ? user : "<unknown user>");
! 	if (user) krb5_xfree(user);
!       }
!       return(KRB5KDC_ERR_PREAUTH_FAILED);
!     }
! 
!     if (krb5kdc_sam_warn_old_sam) {
!       char *user = NULL;
! 
!       krb5_unparse_name(context, client->princ, &user);
!       krb5_klog_syslog (LOG_INFO, "Client uses old SAM protocol (%s)",
! 	user ? user : "<unknown user>");
!       if (user) krb5_xfree(user);
!     }
! 
!     scratch.data = (char *) pa->contents;
      scratch.length = pa->length;
      
      if ((retval = decode_krb5_sam_response(&scratch, &sr))) {
  	scratch.data = 0;
+ 	sr = NULL;
  	com_err("krb5kdc", retval, "decode_krb5_sam_response failed");
  	goto cleanup;
      }
  
!     switch (sr->sam_type) {
! #ifdef ARL_SECURID_PREAUTH
!       case PA_SAM_TYPE_SECURID:
! 	retval =  verify_securid_data(context, client, sr, enc_tkt_reply, pa);
! 
! 	/* In the case of next cardcode required (and new PIN procedure)
! 	 * the verify routine will return KRB5KDC_ERR_PREAUTH_REQUIRED,
! 	 * which indicates "successful for this round, but I need more".
! 	 * This should be returned upwards as a success, but do not set
! 	 * TKT_FLG_HW_AUTH or TKT_FLG_PRE_AUTH flags in ticket (do this
! 	 * by going directly to cleanup).  This way, the dialog with the
! 	 * client continues, since there is still insufficient preauth for
! 	 * the client principal.
! 	 */
! 
! 	if (retval == KRB5KDC_ERR_PREAUTH_REQUIRED) {
! 	   retval = 0;
! 	   goto cleanup;
! 	}
! 	if (retval) goto cleanup;
! 	break;
! #endif /* ARL_SECURID_PREAUTH */
! 
!       case PA_SAM_TYPE_CRYPTOCARD:
! 	/* The CryptoCard verification differs from the generic challenge/response  */
! 	/* verification in that it does not encode a predicted SAM response in the  */
! 	/* track_id.  Instead, it uses a mechanism-specific track_id format	    */
! 
! 
! 	if (sr->sam_track_id.data && (sr->sam_track_id.length > 0)) {
! 	   krb5_data tmp_data;
! 	   krb5_enc_data tmp_enc_data;
! 	   krb5_rb1_track_data *rb1_track_data;
! 	   krb5_keyblock rb1_keyblock;
! 	   krb5_principal newp;
! 	   krb5_db_entry rb1_db_entry;
! 	   krb5_tl_data tl_data;
! 	   krb5_boolean more;
! 	   int npr = 0, probeslot;
! 
! 	   memset(&tmp_enc_data, 0, sizeof(tmp_enc_data));
! 	   tmp_enc_data.ciphertext = sr->sam_track_id;
! 	   tmp_enc_data.enctype = master_keyblock.enctype;
! 
! 	   scratch.length = tmp_enc_data.ciphertext.length;
! 	   scratch.data = (char *) malloc(scratch.length);
! 	   if (!scratch.data) {
! 		com_err("krb5kdc", ENOMEM, "while decrypting RB1 track_id");
! 		goto cleanup;
! 	   }
! 
! 	   retval = krb5_c_decrypt(kdc_context, &master_keyblock, /* Usage = 0 */ 0,
! 			NULL, &tmp_enc_data, &scratch);
! 	   if (retval) {
! 		com_err("krb5kdc", retval, "RB1: decrypt track_id failed");
! 		goto cleanup;
! 	   }
! 
! 	   rb1_track_data = (krb5_rb1_track_data *) scratch.data;
! 	   tmp_data.data = rb1_track_data->ascii_response;
! 	   tmp_data.length = strlen(rb1_track_data->ascii_response);
! 	   if (tmp_data.length > sizeof(rb1_track_data->ascii_response) - 1)
! 		tmp_data.length = sizeof(rb1_track_data->ascii_response) - 1;
! 
! 	   retval = krb5_c_string_to_key(kdc_context, ENCTYPE_DES_CBC_MD5,
! 		&tmp_data, NULL, &rb1_keyblock);
! 	   if (retval) {
! 		com_err("krb5kdc", retval,
! 			"trying to convert RB1 response to encryption key");
! 		goto cleanup;
! 	   }
! 
! 	   scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length;
! 	   scratch.data = (char *) malloc(scratch.length);
! 
! 	   if (!scratch.data) {
! 		com_err("krb5kdc", ENOMEM, "while decrypting RB1 enc_nonce_or_ts");
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   retval = krb5_c_decrypt(kdc_context, &rb1_keyblock, /* Usage = 0 */ 0,
! 			NULL, &sr->sam_enc_nonce_or_ts, &scratch);
! 	   krb5_free_keyblock_contents(kdc_context, &rb1_keyblock);
! 	   if (retval) {
! 		com_err("krb5kdc", retval, "while decrypting RB1 nonce_or_ts");
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   /* Decode sam_enc_nonce_or_ts */
! 
! 	   retval = decode_krb5_enc_sam_response_enc(&scratch, &esre);
! 	   if (retval) {
! 		com_err("krb5kdc", retval,
! 			"RB1 decode_krb5_enc_sam_response_enc failed");
! 		esre = NULL;
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   if (esre->sam_timestamp != sr->sam_patimestamp) {
! 		retval = KRB5KDC_ERR_PREAUTH_FAILED;
! 		com_err("krb5kdc", retval, "RB1 timestamp compare failed");
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   if (retval = krb5_timeofday(context, &timenow)) {
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   if (labs(timenow - sr->sam_patimestamp) > kdc_context->clockskew) {
! 		retval = KRB5KRB_AP_ERR_SKEW;
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! #ifdef LOG_SAM_SUCCESS
! 	   {
! 		char *username = NULL;
! 		retval = krb5_unparse_name(kdc_context, client->princ, &username);
! 		if (!retval) {
! 		   limit_string(username);
! 		   com_err("krb5kdc", KRB5KDC_ERR_NONE,
! 			"Successful RB1 preauthentication for user %s", username);
! 		   free(username);
! 		} else {
! 		   com_err("krb5kdc", ENOMEM,
! 			"while unparsing name for SAM success log message");
! 		}
! 	   }
! #endif
! 	   retval = krb5_copy_principal(kdc_context, client->princ, &newp);
! 	   if (retval) {
! 		com_err("krb5kdc", retval,
! 			"while copying client name for RB1 challenge update");
! 		krb5_xfree(rb1_track_data);
! 		goto cleanup;
! 	   }
! 
! 	   /*  Look up SAM principal in Kerberos database so we can update the	*/
! 	   /*  challenge information.						*/
! 
! 	   for (sam_ptr = sam_inst_map; sam_ptr->name; sam_ptr++)
! 		if (sam_ptr->sam_type == PA_SAM_TYPE_CRYPTOCARD)
! 		   break;
!  
! 	   if (sam_ptr->name == 0) {
! 		com_err("krb5kdc", KRB5_PREAUTH_BAD_TYPE,
! 			"while getting CryptoCard info - this shouldn't happen!");
! 		krb5_free_principal(kdc_context, newp);
! 		goto noupdate;
! 	   }
!  
! 	   probeslot = krb5_princ_size(kdc_context, newp)++;
! 	   krb5_princ_name(kdc_context, newp) =
! 	   		realloc(krb5_princ_name(kdc_context, newp),
! 				krb5_princ_size(context, newp) * sizeof(krb5_data));
!  
! 	   krb5_princ_component(kdc_context, newp, probeslot)->data =
! 			strdup(sam_ptr->name);
! 	   krb5_princ_component(kdc_context, newp, probeslot)->length =
! 			strlen(sam_ptr->name);
!  
! 	   retval = krb5_db_get_principal(kdc_context, newp, &rb1_db_entry,&npr,&more);
!  
! 	   if (retval) {
! 		com_err("krb5kdc", retval,
! 			"while getting preauth principal - this shouldn't happen!");
! 		krb5_free_principal(kdc_context, newp);
! 		goto noupdate;
! 	   }
! 
! 	   /*
! 	    * Set up tl_data for database entry (use rb1_track_id.new_challenge)
! 	    */
! 
! 	   tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE;
! 	   tl_data.tl_data_length = sizeof(rb1_track_data->new_challenge);
! 	   tl_data.tl_data_contents = (unsigned char *) rb1_track_data->new_challenge;
! 
! 	   retval = krb5_dbe_update_tl_data(kdc_context, &rb1_db_entry, &tl_data);
! 	   if (retval) {
! 		com_err("krb5kdc", retval, "while updating RB-1 challenge tl_data");
! 		krb5_free_principal(kdc_context, newp);
! 		krb5_db_free_principal(kdc_context, &rb1_db_entry, npr);
! 		goto noupdate;
! 	   }
! 
! 	   retval = krb5_db_put_principal(kdc_context, &rb1_db_entry, &npr);
! 	   if (retval) {
! 		com_err("krb5kdc", retval, "while storing RB-1 challenge tl_data");
! 		krb5_free_principal(kdc_context, newp);
! 		krb5_db_free_principal(kdc_context, &rb1_db_entry, npr);
! 		goto noupdate;
! 	   }
!  
! 	   krb5_free_principal(kdc_context, newp);
! 	   krb5_db_free_principal(kdc_context, &rb1_db_entry, npr);
! 
! 	   /* noupdate is not a critical error.  It just means that we can't	*/
! 	   /* store the next challenge in the database and we need to generate	*/
! 	   /* new random challenges at each use.  It's very inconvenient for	*/
! 	   /* the user (boo hoo)						*/
! noupdate:
! 	   krb5_xfree(rb1_track_data);
! 	   /* At this point, things are non-fatal */
! 	   retval = 0;
! 
! 	} else {
! 	   retval = KRB5KDC_ERR_PREAUTH_FAILED;
! 	   com_err("krb5kdc",retval,"CryptoCard track_id data not found");
! 	   goto cleanup;
! 	}
! 	break;
! 
!       default:
      {
        krb5_enc_data tmpdata;
  
***************
*** 1242,1271 ****
  	  com_err("krb5kdc", retval, "decrypt track_id failed");
  	  goto cleanup;
        }
-     }
  
!     if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) {
  	com_err("krb5kdc", retval,
  		"decode_krb5_predicted_sam_response failed -- replay attack?");
  	goto cleanup;
!     }
  
!     /* Replay detection */
!     if ((retval = krb5_unparse_name(context, request->client, &princ_req)))
  	goto cleanup;
!     if ((retval = krb5_unparse_name(context, psr->client, &princ_psr)))
  	goto cleanup;
!     if (strcmp(princ_req, princ_psr) != 0) {
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Principal mismatch in SAM psr! -- replay attack?");
  	goto cleanup;
!     }
  
!     if ((retval = krb5_timeofday(context, &timenow)))
  	goto cleanup;
  
  #ifdef USE_RCACHE
!     {
  	krb5_donot_replay rep;
  	extern krb5_deltat rc_lifetime;
  	/*
--- 2117,2146 ----
  	  com_err("krb5kdc", retval, "decrypt track_id failed");
  	  goto cleanup;
        }
  
!       if ((retval = decode_krb5_predicted_sam_response(&scratch, &psr))) {
  	com_err("krb5kdc", retval,
  		"decode_krb5_predicted_sam_response failed -- replay attack?");
+ 	psr = NULL;
  	goto cleanup;
!       }
  
!       /* Replay detection */
!       if ((retval = krb5_unparse_name(context, request->client, &princ_req)))
  	goto cleanup;
!       if ((retval = krb5_unparse_name(context, psr->client, &princ_psr)))
  	goto cleanup;
!       if (strcmp(princ_req, princ_psr) != 0) {
  	com_err("krb5kdc", retval = KRB5KDC_ERR_PREAUTH_FAILED,
  		"Principal mismatch in SAM psr! -- replay attack?");
  	goto cleanup;
!       }
  
!       if ((retval = krb5_timeofday(context, &timenow)))
  	goto cleanup;
  
  #ifdef USE_RCACHE
!       {
  	krb5_donot_replay rep;
  	extern krb5_deltat rc_lifetime;
  	/*
***************
*** 1288,1298 ****
  	    com_err("krb5kdc", retval, "SAM psr replay attack!");
  	    goto cleanup;
  	}
!     }
  #endif /* USE_RCACHE */
  
  
!     {
  	free(scratch.data);
  	scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length;
  	if ((scratch.data = (char *) malloc(scratch.length)) == NULL) {
--- 2163,2173 ----
  	    com_err("krb5kdc", retval, "SAM psr replay attack!");
  	    goto cleanup;
  	}
!       }
  #endif /* USE_RCACHE */
  
  
!       {
  	free(scratch.data);
  	scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length;
  	if ((scratch.data = (char *) malloc(scratch.length)) == NULL) {
***************
*** 1305,1336 ****
  	    com_err("krb5kdc", retval, "decrypt nonce_or_ts failed");
  	    goto cleanup;
  	}
!     }
  
!     if ((retval = decode_krb5_enc_sam_response_enc(&scratch, &esre))) {
  	com_err("krb5kdc", retval, "decode_krb5_enc_sam_response_enc failed");
  	goto cleanup;
!     }
  
!     if (esre->sam_timestamp != sr->sam_patimestamp) {
!       retval = KRB5KDC_ERR_PREAUTH_FAILED;
!       goto cleanup;
!     }
      
!     if (labs(timenow - sr->sam_patimestamp) > context->clockskew) {
  	retval = KRB5KRB_AP_ERR_SKEW;
  	goto cleanup;
!     }
  
      setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
  
    cleanup:
      if (retval)
  	com_err("krb5kdc", retval, "sam verify failure");
!     if (scratch.data) free(scratch.data);
      if (sr) free(sr);
      if (psr) free(psr);
      if (esre) free(esre);
  
      return retval;
  }
--- 2180,2446 ----
  	    com_err("krb5kdc", retval, "decrypt nonce_or_ts failed");
  	    goto cleanup;
  	}
!       }
  
!       if ((retval = decode_krb5_enc_sam_response_enc(&scratch, &esre))) {
  	com_err("krb5kdc", retval, "decode_krb5_enc_sam_response_enc failed");
+ 	esre = NULL;
  	goto cleanup;
!       }
  
!       if (esre->sam_timestamp != sr->sam_patimestamp) {
!         retval = KRB5KDC_ERR_PREAUTH_FAILED;
!         goto cleanup;
!       }
      
!       if (labs(timenow - sr->sam_patimestamp) > context->clockskew) {
  	retval = KRB5KRB_AP_ERR_SKEW;
  	goto cleanup;
!       }  
!     }    /* end default case of sr->sam_type switch statement */
!     }  /* end switch (sr->sam_type) */
  
+     /* Successful HW Preautentication */
      setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+     setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
  
    cleanup:
      if (retval)
  	com_err("krb5kdc", retval, "sam verify failure");
!     if ((sr->sam_type != PA_SAM_TYPE_SECURID) &&
! 		scratch.data) free(scratch.data);
      if (sr) free(sr);
      if (psr) free(psr);
      if (esre) free(esre);
  
      return retval;
+ }
+ 
+ /*
+  * Handle the PA-ALT-PRINC preauth.
+  *
+  * This is going to be confusing, so pay attention.  The call sequence is
+  * "confusing".
+  *
+  * First, do_as_req() calls check_padata(), which calls the preauth system's
+  * verify function.
+  *
+  * (If there's no PA-ALT-PRINC preauth, then of course we do nothing).
+  *
+  * Next, do_as_req() calls get_preauth_hint_list, which calls the get_edata()
+  * preauth function.  We don't do anything for this.  get_sam_edata_2()
+  * will use the alt-princ if we give it one; otherwise, it doesn't allocate
+  * anything.  If we _do_ give it an alt-princ, then we handle it inside
+  * of get_sam_edata_2() (we need the alt-princ so we can use the right
+  * key for the sam_edata_2 response).
+  *
+  * If we're _PROCESSING_ a SAM-CHALLENGE-2 message, it's different.
+  * Start out the same as before (check_padata()), but this time down in
+  * return_padata() we're going to use it in the verify function to construct
+  * the proper return key (which is really in return_sam_data_2).  But since
+  * as part of the protocol, we need to return the PA-ALT-PRINC, we send
+  * back in our verify function.
+  *
+  * Anything we allocate and stick in the "opaque" pointer, we free in
+  * cleanup_padata_opaque() (it got too complicated otherwise).
+  */
+ 
+ void
+ cleanup_padata_opaque(krb5_context context, void *opaque)
+ {
+     preauth_info *pi = (preauth_info *) opaque;
+ 
+     if (pi == NULL)
+ 	return;
+ 
+     if (pi->altprinc)
+ 	krb5_free_principal(context, pi->altprinc);
+ 
+     if (pi->altprincstring)
+ 	krb5_free_unparsed_name(context, pi->altprincstring);
+ 
+     if (pi->entry) {
+ 	krb5_db_free_principal(context, pi->entry, 1);
+ 	free(pi->entry);
+     }
+ 
+     free(pi);
+ }
+ 
+ static krb5_error_code
+ cache_alt_princ(krb5_context context, krb5_db_entry *client,
+ 		krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
+ 		krb5_pa_data *data, void **opaque)
+ {
+     krb5_error_code retval;
+     krb5_data pa;
+     krb5_principal princ;
+     krb5_db_entry *entry;
+     preauth_info *pi;
+     char *name;
+     int nprincs = 1;
+     krb5_boolean more;
+ 
+     /* 
+      * The "check_padata" function (which is what this is) is only called
+      * when we have an PA-ALT-PRINC preauth in the request.  Cache it for
+      * later.  But _only_ do this if:
+      * - We're requesting hardware preauth
+      * - It's a "host" principal.
+      */
+ 
+     if (!isflagset(request->kdc_options, KDC_OPT_HW_AUTH))
+ 	return 0;
+ 
+     pa.length = data->length;
+     pa.data = (char *) data->contents;
+ 
+     if ((retval = decode_krb5_principal(&pa, &princ))) {
+ 	com_err("krb5kdc", retval, "decoding principal for pa-alt-princ");
+ 	return retval;
+     }
+ 
+     if (krb5_princ_name(context, princ)->length != 4 ||
+ 	strncmp(krb5_princ_name(context, princ)->data, "host", 4) != 0) {
+ 	krb5_klog_syslog(LOG_INFO, "Client requested ALT-PRINC for non-host "
+ 			 "principal");
+ 	krb5_free_principal(context, princ);
+ 	return 0;
+     }
+ 
+     if ((retval = krb5_unparse_name(context, princ, &name))) {
+ 	com_err("krb5kdc", retval, "unparsing principal for pa-alt-princ");
+ 	krb5_free_principal(context, princ);
+ 	return 0;
+     }
+ 
+     if (!(entry = malloc(sizeof(*entry)))) {
+ 	com_err("krb5kdc", ENOMEM, "allocating memory for alt-princ cache");
+ 	krb5_free_principal(context, princ);
+ 	krb5_free_unparsed_name(context, name);
+ 	return ENOMEM;
+     }
+ 
+     if ((retval = krb5_db_get_principal(context, princ, entry, &nprincs,
+ 					&more))) {
+ 	com_err("krb5kdc", 0, "while looking up alt-princ principal");
+ 	krb5_free_principal(context, princ);
+ 	krb5_free_unparsed_name(context, name);
+ 	return retval;
+     }
+ 
+     if (more) {
+ 	retval = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE;
+ 	com_err("krb5kdc", 0, "while looking up alt-princ principal");
+ 	krb5_free_principal(context, princ);
+ 	krb5_db_free_principal(context, entry, nprincs);
+ 	krb5_free_unparsed_name(context, name);
+ 	return retval;
+     }
+ 
+     if (!(pi = malloc(sizeof(*pi)))) {
+ 	com_err("krb5kdc", ENOMEM, "allocating memory for alt-princ cache");
+ 	krb5_free_principal(context, princ);
+ 	krb5_db_free_principal(context, entry, nprincs);
+ 	krb5_free_unparsed_name(context, name);
+ 	return ENOMEM;
+     }
+ 
+     memset(pi, 0, sizeof(*pi));
+ 
+     pi->altprinc = princ;
+     pi->entry = entry;
+     pi->altprincstring = name;
+ 
+     *opaque = pi;
+ 
+     /*
+      * For security, clamp down on ticket lifetime here
+      */
+ 
+     enc_tkt_reply->times.renew_till = 0;
+     enc_tkt_reply->times.endtime = enc_tkt_reply->times.starttime + 300;
+ 
+     return 0;
+ }
+ 
+ /*
+  * Simply return the encoded principal given to us
+  */
+ 
+ static krb5_error_code
+ get_alt_princ_edata(krb5_context context, krb5_kdc_req *request,
+ 		    krb5_db_entry *client, krb5_db_entry *server,
+ 		    krb5_pa_data *data, void *opaque)
+ {
+     krb5_error_code retval;
+     krb5_data *encoded_princ;
+ 
+     preauth_info *pi = (preauth_info *) opaque;
+ 
+     if (pi == NULL)
+ 	return KRB5KDC_ERR_PREAUTH_REQUIRED;
+ 
+     if (pi->altprinc == NULL)
+ 	return KRB5KDC_ERR_PREAUTH_REQUIRED;
+ 
+     retval = encode_krb5_principal(pi->altprinc, &encoded_princ);
+ 
+     if (retval) {
+ 	com_err("krb5kdc", retval, "While reencoding alt-princ principal");
+ 	return retval;
+     }
+ 
+     data->contents = (unsigned char *) encoded_princ->data;
+     data->length = encoded_princ->length;
+ 
+     free(encoded_princ);
+ 
+     return 0;
+ }
+ 
+ /*
+  * Essentially the same as get_alt_princ_edata
+  */
+ 
+ static krb5_error_code
+ return_alt_princ(krb5_context context, krb5_pa_data * padata,
+ 		 krb5_db_entry *client, krb5_kdc_req *request,
+ 		 krb5_kdc_rep *reply, krb5_key_data *client_key,
+ 		 krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
+ 		 void *opaque)
+ {
+     krb5_error_code retval;
+     krb5_data *encoded_princ;
+     krb5_pa_data *pa;
+ 
+     preauth_info *pi = (preauth_info *) opaque;
+ 
+     if (pi == NULL)
+ 	return 0;
+ 
+     if (pi->altprinc == NULL)
+ 	return 0;
+ 
+     retval = encode_krb5_principal(pi->altprinc, &encoded_princ);
+ 
+     if (retval) {
+ 	com_err("krb5kdc", retval, "While reencoding alt-princ principal");
+ 	return retval;
+     }
+ 
+     if ((pa = malloc(sizeof(krb5_pa_data))) == NULL) {
+ 	krb5_free_data(context, encoded_princ);
+ 	return ENOMEM;
+     }
+ 
+     pa->magic = KV5M_PA_DATA;
+     pa->pa_type = KRB5_PADATA_ALT_PRINC;
+     pa->contents = (unsigned char *) encoded_princ->data;
+     pa->length = encoded_princ->length;
+     *send_pa = pa;
+ 
+     free(encoded_princ);
+ 
+     return 0;
  }
Index: krb5/kdc/kdc_util.c
diff -c krb5/kdc/kdc_util.c:1.1.1.6 krb5/kdc/kdc_util.c:1.12
*** krb5/kdc/kdc_util.c:1.1.1.6	Thu Dec 19 14:06:12 2002
--- krb5/kdc/kdc_util.c	Thu Dec 19 14:19:30 2002
***************
*** 364,372 ****
      if (pkt && (fetch_asn1_field((unsigned char *) pkt->data,
  				 1, 4, &scratch1) >= 0)) {
  	if (comp_cksum(kdc_context, &scratch1, *ticket, his_cksum)) {
! 	    if (!(retval = encode_krb5_kdc_req_body(request, &scratch))) 
  	        retval = comp_cksum(kdc_context, scratch, *ticket, his_cksum);
! 	    krb5_free_data(kdc_context, scratch);
  	}
      }
  
--- 364,375 ----
      if (pkt && (fetch_asn1_field((unsigned char *) pkt->data,
  				 1, 4, &scratch1) >= 0)) {
  	if (comp_cksum(kdc_context, &scratch1, *ticket, his_cksum)) {
! 	    if (!(retval = encode_krb5_kdc_req_body(request, &scratch))) {
  	        retval = comp_cksum(kdc_context, scratch, *ticket, his_cksum);
! 	    	krb5_free_data(kdc_context, scratch);
! 	    } else {
! 		scratch = NULL;
! 	    }
  	}
      }
  
***************
*** 452,463 ****
  static krb5_last_req_entry nolrentry = { KV5M_LAST_REQ_ENTRY, KRB5_LRQ_NONE, 0 };
  static krb5_last_req_entry *nolrarray[] = { &nolrentry, 0 };
  
  krb5_error_code
  fetch_last_req_info(dbentry, lrentry)
  krb5_db_entry *dbentry;
  krb5_last_req_entry ***lrentry;
  {
!     *lrentry = nolrarray;
      return 0;
  }
  
--- 455,489 ----
  static krb5_last_req_entry nolrentry = { KV5M_LAST_REQ_ENTRY, KRB5_LRQ_NONE, 0 };
  static krb5_last_req_entry *nolrarray[] = { &nolrentry, 0 };
  
+ static krb5_last_req_entry pwexpentry = { KV5M_LAST_REQ_ENTRY,
+ 					  KRB5_LRQ_PW_EXPTIME, 0 };
+ static krb5_last_req_entry *pwexparray[] = { &pwexpentry, 0 };
+ 
  krb5_error_code
  fetch_last_req_info(dbentry, lrentry)
  krb5_db_entry *dbentry;
  krb5_last_req_entry ***lrentry;
  {
!     krb5_timestamp timenow;
!     krb5_error_code retval;
! 
!     if (kdc_warn_pwexpire == 0 || dbentry->pw_expiration == 0) {
! 	*lrentry = nolrarray;
! 	return 0;
!     }
! 
!     if ((retval = krb5_timeofday(kdc_context, &timenow)) != 0)
! 	return retval;
! 		    
!     if (dbentry->pw_expiration > timenow + kdc_warn_pwexpire) {
! 	*lrentry = nolrarray;
! 	return 0;
!     }
! 
!     pwexpentry.value = dbentry->pw_expiration;
! 
!     *lrentry = pwexparray;
! 
      return 0;
  }
  
***************
*** 852,858 ****
   */
  #define AS_OPTIONS_HANDLED (KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE | \
  			     KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \
! 			     KDC_OPT_RENEWABLE | KDC_OPT_RENEWABLE_OK)
  int
  validate_as_request(request, client, server, kdc_time, status)
  register krb5_kdc_req *request;
--- 878,885 ----
   */
  #define AS_OPTIONS_HANDLED (KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE | \
  			     KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \
! 			     KDC_OPT_RENEWABLE | KDC_OPT_RENEWABLE_OK | \
! 			     KDC_OPT_HW_AUTH)
  int
  validate_as_request(request, client, server, kdc_time, status)
  register krb5_kdc_req *request;
***************
*** 1453,1459 ****
      krb5_enctype	*ktype;
  {
      int		i;
!     krb5_enctype dfl = 0;
      
      for (i = 0; i < nktypes; i++) {
  	if (!valid_enctype(ktype[i]))
--- 1480,1486 ----
      krb5_enctype	*ktype;
  {
      int		i;
!     krb5_enctype dfl = 0, *ptr;
      
      for (i = 0; i < nktypes; i++) {
  	if (!valid_enctype(ktype[i]))
***************
*** 1461,1466 ****
--- 1488,1501 ----
  
  	if (!krb5_is_permitted_enctype(context, ktype[i]))
  	    continue;
+ 
+ 	if (krb5kdc_session_enctypes) {
+ 	    for (ptr = krb5kdc_session_enctypes; *ptr; ptr++)
+ 		if (*ptr == ktype[i])
+ 		    break;
+ 	    if (! *ptr)
+ 		continue;
+ 	}
  
  	if (dbentry_supports_enctype(context, server, ktype[i]))
  	    return ktype[i];
Index: krb5/kdc/kdc_util.h
diff -c krb5/kdc/kdc_util.h:1.1.1.3 krb5/kdc/kdc_util.h:1.6
*** krb5/kdc/kdc_util.h:1.1.1.3	Fri Feb 22 16:32:22 2002
--- krb5/kdc/kdc_util.h	Fri Dec 13 19:57:17 2002
***************
*** 143,162 ****
  /* kdc_preauth.c */
  const char * missing_required_preauth
      PROTOTYPE((krb5_db_entry *client, krb5_db_entry *server,
! 	       krb5_enc_tkt_part *enc_tkt_reply));
  void get_preauth_hint_list PROTOTYPE((krb5_kdc_req * request,
  				      krb5_db_entry *client,
  				      krb5_db_entry *server,
! 				      krb5_data *e_data));
  krb5_error_code check_padata
      PROTOTYPE((krb5_context context, krb5_db_entry *client,
! 	       krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply));
      
  krb5_error_code return_padata
      PROTOTYPE((krb5_context context, krb5_db_entry *client,
  	       krb5_kdc_req *request, krb5_kdc_rep *reply,
! 	       krb5_key_data *client_key, krb5_keyblock *encrypting_key));
!     
  /* replay.c */
  krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, const krb5_fulladdr *,
  					    krb5_data **));
--- 143,168 ----
  /* kdc_preauth.c */
  const char * missing_required_preauth
      PROTOTYPE((krb5_db_entry *client, krb5_db_entry *server,
! 	       krb5_enc_tkt_part *enc_tkt_reply, krb5_kdc_req *request));
  void get_preauth_hint_list PROTOTYPE((krb5_kdc_req * request,
  				      krb5_db_entry *client,
  				      krb5_db_entry *server,
! 				      krb5_data *e_data,
! 				      void *opaque));
  krb5_error_code check_padata
      PROTOTYPE((krb5_context context, krb5_db_entry *client,
! 	       krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
! 	       void **opaque));
      
  krb5_error_code return_padata
      PROTOTYPE((krb5_context context, krb5_db_entry *client,
  	       krb5_kdc_req *request, krb5_kdc_rep *reply,
! 	       krb5_key_data *client_key, krb5_keyblock *encrypting_key,
! 	       void *opaque));
! 
! void cleanup_padata_opaque
!     PROTOTYPE((krb5_context context, void *opaque));
! 
  /* replay.c */
  krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, const krb5_fulladdr *,
  					    krb5_data **));
Index: krb5/kdc/kerberos_v4.c
diff -c krb5/kdc/kerberos_v4.c:1.1.1.5 krb5/kdc/kerberos_v4.c:1.11
*** krb5/kdc/kerberos_v4.c:1.1.1.5	Wed Sep 25 15:06:02 2002
--- krb5/kdc/kerberos_v4.c	Wed Sep 25 15:18:31 2002
***************
*** 1022,1029 ****
  
      adjusted_time = *t /* - CONVERT_TIME_EPOCH */;
      tm = localtime(&adjusted_time);
!     (void) sprintf(st,"%4d-%s-%02d %02d:%02d:%02d",tm->tm_mday+1900,
!                    month_sname(tm->tm_mon + 1),tm->tm_year,
                     tm->tm_hour, tm->tm_min, tm->tm_sec);
      return st;
  }
--- 1022,1029 ----
  
      adjusted_time = *t /* - CONVERT_TIME_EPOCH */;
      tm = localtime(&adjusted_time);
!     (void) sprintf(st,"%4d-%s-%2d %02d:%02d:%02d",tm->tm_year+1900,
!                    month_sname(tm->tm_mon + 1),tm->tm_mday,
                     tm->tm_hour, tm->tm_min, tm->tm_sec);
      return st;
  }
Index: krb5/kdc/main.c
diff -c krb5/kdc/main.c:1.1.1.3 krb5/kdc/main.c:1.8
*** krb5/kdc/main.c:1.1.1.3	Fri Feb 22 16:32:23 2002
--- krb5/kdc/main.c	Tue Sep 24 17:33:50 2002
***************
*** 552,558 ****
  krb5_error_code
  setup_sam()
  {
!     return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key);
  }
  
  void
--- 552,576 ----
  krb5_error_code
  setup_sam()
  {
!     krb5_pointer        aprof = 0;
!     const char          *hierarchy[4];
!     krb5_boolean	allow_old_sam;
!     krb5_boolean	warn_old_sam;
! 
!     if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
! 	hierarchy[0] = "kdcdefaults";
! 	hierarchy[1] = "allow_old_sam";
! 	hierarchy[2] = NULL;
! 	krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
! 					&krb5kdc_sam_allow_old_sam);
! 	hierarchy[1] = "warn_old_sam";
! 	krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
! 					&krb5kdc_sam_warn_old_sam);
! 	if (aprof)
! 	   krb5_aprof_finish(aprof);
!     }
! 
!     return krb5_c_make_random_key(kdc_context, ENCTYPE_DES3_CBC_SHA1, &psr_key);
  }
  
  void
***************
*** 581,586 ****
--- 599,606 ----
      char		*default_ports = 0;
      krb5_pointer	aprof;
      const char		*hierarchy[3];
+     krb5_int32		pw_warn_expire;
+     char		*session_enctypes;
  #ifdef KRB5_KRB4_COMPAT
      char                *v4mode = 0;
  #endif
***************
*** 596,606 ****
--- 616,635 ----
  	hierarchy[2] = (char *) NULL;
  	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_ports))
  	    default_ports = 0;
+ 	hierarchy[1] = "kdc_warn_pwexpire";
+ 	if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &kdc_warn_pwexpire))
+ 		kdc_warn_pwexpire = 0;
  #ifdef KRB5_KRB4_COMPAT
  	hierarchy[1] = "v4_mode";
  	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
  	    v4mode = 0;
  #endif
+ 	hierarchy[1] = "kdc_session_enctypes";
+ 	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &session_enctypes))
+ 	    session_enctypes = 0;
+ 	hierarchy[1] = "kdc_limit_service_enctypes";
+ 	krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
+ 					&krb5kdc_limit_service_enctypes);
  	/* aprof_init can return 0 with aprof == NULL */
  	if (aprof)
  	     krb5_aprof_finish(aprof);
***************
*** 720,725 ****
--- 749,812 ----
  	exit(1);
      }
  #endif
+ 
+     /*
+      * If we were given any session key encryption types, process that list
+      * now
+      */
+ 
+     if (session_enctypes) {
+ 	/*
+ 	 * Some of this was lifted from get_profile_etype_list
+ 	 */
+ 	char *sp = session_enctypes, *ep;
+ 	int i, j, count = 0;
+ 
+ 	while (sp) {
+ 	    for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++)
+ 		;
+ 	    if (*ep) {
+ 		*ep++ = '\0';
+ 		while (isspace(*ep))
+ 		    ep++;
+ 	    } else
+ 		ep = (char *) NULL;
+ 	
+ 	    count++;
+ 	    sp = ep;
+ 	}
+ 
+ 	krb5kdc_session_enctypes = (krb5_enctype *)
+ 				malloc(sizeof(krb5_enctype) * (count + 1));
+ 	
+ 	if (! krb5kdc_session_enctypes) {
+ 	    com_err(argv[0], ENOMEM, "while allocating %d element session "
+ 		    "enctype array, count");
+ 	    exit(1);
+ 	}
+ 
+ 	sp = session_enctypes;
+ 	j = 0;
+ 	i = 1;
+ 	while (1) {
+ 	    if (retval = krb5_string_to_enctype(sp,
+ 						&krb5kdc_session_enctypes[j])) {
+ 		com_err(argv[0], retval, "while processing session "
+ 			"enctype %s", sp);
+ 		exit(1);
+ 	    }
+ 	    j++;
+ 
+ 	    if (i++ >= count)
+ 		break;
+ 	
+ 	    /* skip to next token */
+ 	    while (*sp) sp++;
+ 	    while (! *sp) sp++;
+ 	}
+ 
+ 	krb5kdc_session_enctypes[j] = (krb5_enctype) 0;
+     }
  
      /* Ensure that this is set for our first request. */
      kdc_active_realm = kdc_realmlist[0];
Index: krb5/kdc/network.c
diff -c krb5/kdc/network.c:1.1.1.2 krb5/kdc/network.c:1.7
*** krb5/kdc/network.c:1.1.1.2	Fri Feb 22 16:32:24 2002
--- krb5/kdc/network.c	Tue Jan 21 15:09:21 2003
***************
*** 58,63 ****
--- 58,64 ----
  extern int errno;
  
  static int *udp_port_fds = (int *) NULL;
+ static u_short *udp_fd_ports = (u_short *) NULL;
  static u_short *udp_port_nums = (u_short *) NULL;
  static int n_udp_ports = 0;
  static int n_sockets = 0;
***************
*** 295,304 ****
  };
  
  static int
! add_fd (struct socksetup *data, int sock)
  {
      if (n_sockets == max_udp_sockets) {
  	int *new_fds;
  	int new_max = max_udp_sockets + n_udp_ports;
  	new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int));
  	if (new_fds == 0) {
--- 296,306 ----
  };
  
  static int
! add_fd (struct socksetup *data, int sock, u_short port)
  {
      if (n_sockets == max_udp_sockets) {
  	int *new_fds;
+ 	u_short *new_ports;
  	int new_max = max_udp_sockets + n_udp_ports;
  	new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int));
  	if (new_fds == 0) {
***************
*** 306,315 ****
  	    com_err(data->prog, data->retval, "cannot save socket info");
  	    return 1;
  	}
  	udp_port_fds = new_fds;
  	max_udp_sockets = new_max;
      }
!     udp_port_fds[n_sockets++] = sock;
      return 0;
  }
  
--- 308,325 ----
  	    com_err(data->prog, data->retval, "cannot save socket info");
  	    return 1;
  	}
+ 	new_ports = safe_realloc(udp_port_fds, new_max * sizeof(u_short));
+ 	if (new_ports == 0) {
+ 	    data->retval = errno;
+ 	    com_err(data->prog, data->retval, "cannot save socket info");
+ 	    return 1;
+ 	}
  	udp_port_fds = new_fds;
+ 	udp_fd_ports = new_ports;
  	max_udp_sockets = new_max;
      }
!     udp_port_fds[n_sockets] = sock;
!     udp_fd_ports[n_sockets++] = port;
      return 0;
  }
  
***************
*** 346,352 ****
  		select_nfds = sock;
  	    krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock,
  			     inet_ntoa (sin->sin_addr), udp_port_nums[i]);
! 	    if (add_fd (data, sock))
  		return 1;
  	}
      }
--- 356,362 ----
  		select_nfds = sock;
  	    krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock,
  			     inet_ntoa (sin->sin_addr), udp_port_nums[i]);
! 	    if (add_fd (data, sock, udp_port_nums[i]))
  		return 1;
  	}
      }
***************
*** 510,516 ****
      }
      /* this address is in net order */
      if ((retval = dispatch(&request, &faddr, portnum, &response))) {
! 	com_err(prog, retval, "while dispatching");
  	return;
      }
      cc = sendto(port_fd, response->data, response->length, 0,
--- 520,531 ----
      }
      /* this address is in net order */
      if ((retval = dispatch(&request, &faddr, portnum, &response))) {
! 	char addrbuf[46];
! 	int portno;
! 	sockaddr2p ((struct sockaddr *) &saddr, addrbuf, sizeof(addrbuf),
! 		    &portno);
! 	com_err(prog, retval, "while dispatching from %s/%d", addrbuf,
! 		ntohs(portno));
  	return;
      }
      cc = sendto(port_fd, response->data, response->length, 0,
***************
*** 561,567 ****
  	}
  	for (i=0; i<n_sockets; i++) {
  	    if (FD_ISSET(udp_port_fds[i], &readfds)) {
! 		process_packet(udp_port_fds[i], prog, udp_port_nums[i]);
  		nfound--;
  		if (nfound == 0)
  		    break;
--- 576,582 ----
  	}
  	for (i=0; i<n_sockets; i++) {
  	    if (FD_ISSET(udp_port_fds[i], &readfds)) {
! 		process_packet(udp_port_fds[i], prog, udp_fd_ports[i]);
  		nfound--;
  		if (nfound == 0)
  		    break;
***************
*** 585,590 ****
--- 600,606 ----
  	    (void) close(udp_port_fds[i]);
      }
      free(udp_port_fds);
+     free(udp_fd_ports);
      free(udp_port_nums);
  
      return 0;
Index: krb5/kdc/sam2.c
diff -c /dev/null krb5/kdc/sam2.c:1.10
*** /dev/null	Sun Mar 16 20:22:19 2003
--- krb5/kdc/sam2.c	Mon Mar 10 15:26:11 2003
***************
*** 0 ****
--- 1,1053 ----
+ krb5_error_code sam_get_db_entry(krb5_context context,
+ 			krb5_principal *client,
+ 			int *sam_type,
+ 			krb5_db_entry **db_entry) {
+    int npr;
+    krb5_boolean more;
+    krb5_db_entry *assoc;
+    krb5_principal newp;
+    int probeslot;
+    int retval;
+ 		
+    retval = krb5_copy_principal(kdc_context, *client, &newp);
+    if (retval) {
+ 	com_err("krb5kdc", retval, "copying client name for preauth probe");
+ 	return retval;
+    }
+ 
+    assoc = (krb5_db_entry *)malloc(sizeof(krb5_db_entry));
+    if (!assoc) {
+ 	com_err("krb5kdc", ENOMEM,
+ 		"while allocating memory for SAM principal lookup");
+ 	return ENOMEM;
+    }
+ 
+    probeslot = krb5_princ_size(context, newp)++;
+    krb5_princ_name(kdc_context, newp) =
+ 	realloc(krb5_princ_name(kdc_context, newp),
+ 		krb5_princ_size(context, newp) * sizeof(krb5_data));
+ 
+    for(sam_ptr = sam_inst_map; sam_ptr->name; sam_ptr++) {
+ 	if (*sam_type && (*sam_type != sam_ptr->sam_type)) continue;
+ 
+ 	krb5_princ_component(kdc_context,newp,probeslot)->data = sam_ptr->name;
+ 	krb5_princ_component(kdc_context,newp,probeslot)->length =
+ 	strlen(sam_ptr->name);
+ 	retval = krb5_db_get_principal(kdc_context, newp, assoc, &npr, &more);
+ 	if(!retval && npr) {
+ 	   break;
+ 	}
+    }
+    krb5_princ_component(kdc_context,newp,probeslot)->data = 0;
+    krb5_princ_component(kdc_context,newp,probeslot)->length = 0;
+    krb5_princ_size(context, newp)--;
+ 
+    krb5_free_principal(kdc_context, newp);
+ 
+    if (sam_ptr->sam_type)  {
+ 	/* Found entry of type sam_ptr->sam_type */
+ 	if (sam_type) *sam_type = sam_ptr->sam_type;
+ 	if (db_entry) *db_entry = assoc;
+ 	return(0);
+    } else {
+ 	return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+    }
+ }
+ 
+ krb5_error_code sam_get_key(krb5_context context,
+ 			krb5_db_entry *db_entry,
+ 			krb5_enctype key_type,
+ 			krb5_int32 salt_type,
+ 			krb5_keyblock *key) {
+    krb5_error_code retval;
+    krb5_key_data  *key_data = NULL;
+ 
+    if (!db_entry || !key) return(KRB5KDC_ERR_NULL_KEY);
+ 
+    retval = krb5_dbe_find_enctype(kdc_context, db_entry,
+ 			key_type, salt_type, 0, &key_data);
+    if (retval) {
+ 	com_err("krb5kdc", retval, "while retrieving key for SAM preauth");
+ 	return(retval);
+    }
+ 
+    retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock,
+ 			key_data, key, NULL);
+    if (retval) {
+ 	com_err("krb5kdc", retval, "while decrypting key for SAM preauth");
+ 	return(retval);
+    }
+    return(0);
+ }
+ 
+ /*
+  * Verify the SAM response (SAM_RESPONSE_2)
+  */
+ 
+ static krb5_error_code verify_sam_response_2 (
+ 				krb5_context context,
+ 				krb5_db_entry *client,
+ 				krb5_kdc_req *request,
+ 				krb5_enc_tkt_part * enc_tkt_reply,
+ 				krb5_pa_data *pa_data,
+ 				void **opaque) {
+ 
+   krb5_error_code retval;
+   krb5_sam_response_2 *sr2 = NULL;
+   krb5_enc_sam_response_enc_2 *esre2 = NULL;
+   krb5_data scratch;
+   krb5_data defsalt;
+   krb5_data sad_data;
+   krb5_keyblock sad_key;
+   krb5_keyblock client_key;
+   krb5_keyblock combined_key;
+   char *client_name = NULL;
+ 
+   scratch.data = (char *) pa_data->contents;
+   scratch.length = pa_data->length;
+ 
+   retval = krb5_unparse_name(context, client->princ, &client_name);
+   if (retval)
+      goto cleanup;
+ 
+   retval = decode_krb5_sam_response_2(&scratch, &sr2);
+   if (retval) {
+      com_err("krb5kdc", retval,
+ 		"while decoding SAM_RESPONSE_2 in verify_sam_response_2");
+      sr2 = NULL;
+      goto cleanup;
+   }
+ 
+   switch (sr2->sam_type) {
+      case PA_SAM_TYPE_CRYPTOCARD:
+ 	{
+ 	  krb5_rb1_track_data *rb1_track_data;
+ 	  krb5_enc_data tmp_enc_data;
+ 	  krb5_tl_data tl_data;
+ 	  krb5_db_entry *rb1_db_entry;
+ 	  int npr, sam_type, num_rbtrack, i;
+ 
+ 	  /*
+ 	   * Handle ALT-PRINC keying
+ 	   */
+ 	  
+ 	  if (*opaque) {
+ 	     preauth_info *pi = (preauth_info *) *opaque;
+ 
+ 	     retval = sam_get_key(context, pi->entry, -1, /* default enctype */
+ 				  KRB5_KDB_SALTTYPE_NORMAL, &client_key);
+ 	     krb5_klog_syslog(LOG_INFO, "Doing PA-ALT-PRINC keying for "
+ 			      "verification, using host key %s",
+ 			      pi->altprincstring);
+ 	  } else
+ 	     retval = sam_get_key(context, client, -1, /* default enctype */
+ 				  KRB5_KDB_SALTTYPE_NORMAL, &client_key);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		"while retriving client key in verify_sam_response_2");
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  tmp_enc_data.enctype = ENCTYPE_UNKNOWN;
+ 	  tmp_enc_data.ciphertext = sr2->sam_track_id;
+ 	  scratch.length = tmp_enc_data.ciphertext.length;	  
+ 	  scratch.data = (char *) malloc(scratch.length);
+ 	  if (!scratch.data) {
+ 	     retval = ENOMEM;
+ 	     com_err("krb5kdc", retval,
+ 		"while decrypting sam_track_id in verify_sam_response_2");
+ 	     krb5_free_keyblock_contents(context, &client_key);
+ 	     goto cleanup;
+ 	  }
+ 	  retval = krb5_c_decrypt(context, &master_keyblock,
+ 			KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, NULL,
+ 			&tmp_enc_data, &scratch);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", ENOMEM,
+ 		"while decrypting sam_track_id in verify_sam_response_2");
+ 	     krb5_free_keyblock_contents(context, &client_key);
+ 	     krb5_free_data_contents(context, &scratch);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  rb1_track_data = (krb5_rb1_track_data *)scratch.data;
+ 
+ #if 1
+ 	  if (scratch.length % sizeof(krb5_rb1_track_data) != 0)
+ 		scratch.length -= scratch.length % sizeof(krb5_rb1_track_data);
+ #endif
+ 
+ 	  if (scratch.length % sizeof(krb5_rb1_track_data) != 0) {
+ 	     retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	     com_err("krb5kdc", retval,
+ 		     "Decrypted RB1 track data length (%d) was not a "
+ 		     "multiple of track data size (%d)", scratch.length,
+ 		     sizeof(krb5_rb1_track_data));
+ 	     krb5_free_keyblock_contents(context, &client_key);
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  num_rbtrack = scratch.length / sizeof(krb5_rb1_track_data);
+ 
+ 	  memset(&defsalt, 0, sizeof(defsalt));
+ 
+ 	  retval = krb5_principal2salt(context, client->princ, &defsalt);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		 "while generating salt for SAD key in verify_sam_response_2");
+ 	     krb5_free_keyblock_contents(context, &client_key);
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  /*
+ 	   * Initialize the combined_key before we start going any further
+ 	   */
+ 
+ 	  memset(&combined_key, 0, sizeof(combined_key));
+ 
+ 	  /*
+ 	   * Okay, now we need to loop over ALL of the possible responses
+ 	   * (which were stored in the rb1_track_data array)
+ 	   */
+ 
+ 	  for (i = 0; i < num_rbtrack; i++) {
+ 
+ 	     sad_data.data = rb1_track_data[i].ascii_response;
+ 	     sad_data.length = 8;  /* yuck */
+ 
+ 	     memset(&sad_key, 0, sizeof(sad_key));
+ 	     retval = krb5_c_string_to_key(context, client_key.enctype,
+ 					   &sad_data, &defsalt, &sad_key);
+ 
+ 	     if (retval) {
+ 	        com_err("krb5kdc", retval, "while generating SAD enc key in "
+ 			"verify_sam_response_2");
+ 	        krb5_free_keyblock_contents(context, &client_key);
+ 	        krb5_free_data_contents(context, &defsalt);
+ 	        krb5_xfree(rb1_track_data);
+ 	        goto cleanup;
+ 	     }
+ 
+ 	     retval = krb5_combine_keys(context, &client_key, &sad_key,
+ 					&combined_key);
+ 
+ 	     krb5_free_keyblock_contents(context, &sad_key);
+ 
+ 	     if (retval) {
+ 		com_err("krb5kdc", retval, "while combining keys in "
+ 			"verify_sam_response_2");
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 	        krb5_free_data_contents(context, &defsalt);
+ 		krb5_xfree(rb1_track_data);
+ 	        goto cleanup;
+ 	     }
+ 	  
+ 	     tmp_enc_data = sr2->sam_enc_nonce_or_sad;
+ 	     scratch.length = tmp_enc_data.ciphertext.length;
+ 	     scratch.data = (char *) malloc(scratch.length);
+ 	     if (!scratch.data) {
+ 		retval = ENOMEM;
+ 		com_err("krb5kdc", retval, "while decrypting "
+ 			"enc_sam_nonce_or_sad in verify_sam_response_2");
+ 		krb5_free_keyblock_contents(context, &combined_key);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 	        krb5_free_data_contents(context, &defsalt);
+ 	     	krb5_xfree(rb1_track_data);
+ 		goto cleanup;
+ 	     }
+ 
+ 	     retval = krb5_c_decrypt(context, &combined_key,
+ 				     KRB5_KEYUSAGE_PA_SAM_RESPONSE, NULL,
+ 				     &tmp_enc_data, &scratch);
+ 	     krb5_free_keyblock_contents(context, &combined_key);
+ 
+ 	     if (retval && retval != KRB5KRB_AP_ERR_BAD_INTEGRITY) {
+ 	        com_err("krb5kdc", retval, "while decrypting "
+ 			"enc_sam_nonce_or_sad in verify_sam_response_2");
+ 		krb5_xfree(rb1_track_data);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		krb5_free_data_contents(context, &scratch);
+ 		goto cleanup;
+ 	     }
+ 
+ 	     if (retval == 0) {
+ 		preauth_info *pi;
+ 		if (! *opaque) {
+ 		    if (!(*opaque = malloc(sizeof(*pi)))) {
+ 			retval = ENOMEM;
+ 			com_err("krb5kdc", retval, "While allocating "
+ 				"index cache");
+ 			krb5_xfree(rb1_track_data);
+ 			krb5_free_keyblock_contents(context, &client_key);
+ 			krb5_free_data_contents(context, &scratch);
+ 			goto cleanup;
+ 		    }
+ 		    memset(*opaque, 0, sizeof(*pi));
+ 		}
+ 
+ 		pi = (preauth_info *) *opaque;
+ 		    
+ 		pi->slot = i;
+ 		
+ 		break;
+ 	     }
+ 	  }
+ 
+ 	  krb5_free_data_contents(context, &defsalt);
+ 	  krb5_free_keyblock_contents(context, &client_key);
+ 
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval, "while trying %d keys to decrypt "
+ 		     "enc_sam_nonce_or_sad in verify_sam_response_2",
+ 		     num_rbtrack);
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2);
+ 	  krb5_free_data_contents(context, &scratch);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 	       "while decoding enc_sam_nonce_or_sad in verify_sam_response_2");
+ 	     esre2 = NULL;
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 	  
+ 	  if (esre2->sam_nonce != sr2->sam_nonce) {
+ 	     krb5_xfree(rb1_track_data);
+ 	     retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	     goto cleanup;
+ 	  } else {
+ 	     setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+ 	     setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 	  }
+ 
+ 	  /* Now update tl_data in database.  If we fail to update the	 */
+ 	  /* data, try to delete tl_data so challenge will not be reused */
+ 
+ 	  sam_type = PA_SAM_TYPE_CRYPTOCARD;
+ 	  retval = sam_get_db_entry(context, &client->princ, &sam_type,
+ 			&rb1_db_entry);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		"while retrieving %s/RB1 principal to store new challenge",
+ 			client_name);
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE;
+ 	  tl_data.tl_data_length = sizeof(rb1_track_data->new_challenge);
+ 	  tl_data.tl_data_contents = (unsigned char *) rb1_track_data->new_challenge;
+ 
+ 	  retval = krb5_dbe_update_tl_data(context, rb1_db_entry, &tl_data);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		"while updating %s/RB1 principal to store new challenge",
+ 			client_name);
+ 	     krb5_xfree(rb1_track_data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  npr = 1;
+ 	  krb5_xfree(rb1_track_data);
+ 
+ 	  retval = krb5_db_put_principal(context, rb1_db_entry, &npr);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,"while storing RB-1 challenge tl_data");
+ 	     goto cleanup;
+ 	  }
+ 	  krb5_db_free_principal(context, rb1_db_entry, npr);
+ 	  
+ 	  retval = 0;
+ 	  goto cleanup;
+ 
+ 	}  /* end case PA_SAM_TYPE_CRYPTOCARD */
+ 	break;
+ #ifdef ARL_SECURID_PREAUTH
+ 	case PA_SAM_TYPE_SECURID:
+ 	  retval = verify_securid_data_2(context, client, sr2,
+ 			enc_tkt_reply, pa_data);
+ 	  if (retval) goto cleanup;
+ 	  break;
+ #endif  /* ARL_SECURID_PREAUTH */
+ 	default:
+ 	  retval = KRB5_PREAUTH_BAD_TYPE;
+ 	  com_err("krb5krc", retval, "while verifying SAM 2 data");
+ 	  break;
+   }
+ 
+   /* It is up to the method-specific verify routine to set the ticket flags */
+   /* to indicate TKT_FLG_HW_AUTH and/or TKT_FLG_PRE_AUTH.  Some methods     */
+   /* may require more than one round of dialog with the client and must     */
+   /* return successfully from their verify routine.  If does not set the    */
+   /* TGT flags, the required_preauth conditions will not be met and it will */
+   /* try again to get enough preauth data from the client.  Do not set TGT  */
+   /* flags here.                                                            */
+ 
+ cleanup:
+ 
+   if (sr2)
+      krb5_free_sam_response_2(context, sr2);
+   if (esre2)
+      krb5_free_enc_sam_response_enc_2(context, esre2);
+   if (client_name)
+      krb5_xfree(client_name);
+ 
+   return(retval);
+ 
+ }
+ 
+ krb5_enctype get_raw_enctype(krb5_enctype etype) {
+   switch (etype) {
+     case ENCTYPE_DES_CBC_CRC:
+     case ENCTYPE_DES_CBC_MD4:
+     case ENCTYPE_DES_CBC_MD5:
+     case ENCTYPE_DES_CBC_RAW:
+     case ENCTYPE_DES_HMAC_SHA1:
+ 	return ENCTYPE_DES_CBC_RAW;
+     case ENCTYPE_DES3_CBC_RAW:
+     case ENCTYPE_DES3_CBC_SHA1:
+ 	return ENCTYPE_DES3_CBC_RAW;
+     default:
+ 	return ENCTYPE_UNKNOWN;
+   }
+ }
+ 
+ krb5_error_code
+ sam_cksumtype(krb5_context context, krb5_enctype etype, krb5_cksumtype *cksum)
+ {
+   int retval;
+   krb5_cksumtype retcksum, *types;
+   unsigned int count;
+ 
+   retval = krb5_c_keyed_checksum_types(context, etype, &count, &types);
+ 
+   if (retval)
+      return retval;
+ 
+   if (count == 0)
+      return KRB5KDC_ERR_SUMTYPE_NOSUPP;
+ 
+   *cksum = types[0];
+ 
+   krb5_free_cksumtypes(context, types);
+ 
+   return 0;
+ }
+ 
+ 
+ static krb5_error_code get_sam_edata_2 (
+ 				krb5_context context,
+ 				krb5_kdc_req *request,
+ 				krb5_db_entry *client,
+ 				krb5_db_entry *server,
+ 				krb5_pa_data *pa_data,
+ 				void *opaque) {
+   krb5_error_code retval;
+   krb5_sam_challenge_2 sc2;
+   krb5_sam_challenge_2_body sc2b;
+   int sam_type = 0;		/* unknown */
+   krb5_keyblock sam_key;
+   char response[9];
+   char inputblock[8];
+   krb5_data sad_data;
+   krb5_db_entry *sam_db_entry = NULL;
+   krb5_checksum **cksum_array = NULL;
+   krb5_checksum **cksum = NULL;
+   krb5_data *encoded_challenge_body = NULL;
+   krb5_data *encoded_challenge = NULL;
+ 
+   retval = sam_get_db_entry(kdc_context, &client->princ, &sam_type,
+ 			&sam_db_entry);
+   if (retval) return (retval);
+ 
+   if (sam_type == 0) {
+      retval = KRB5_PREAUTH_BAD_TYPE;
+      goto cleanup;
+   }
+ 
+   /* Defer getting the key for the SAM principal associated with the	*/
+   /* client until the mechanism-specific code.  The mechanism may want	*/
+   /* to get a specific keytype						*/
+ 
+   memset(&sam_key, 0, sizeof(sam_key));
+   memset(&sc2, 0, sizeof(sc2));
+   memset(&sc2b, 0, sizeof(sc2b));
+   sc2b.magic = KV5M_SAM_CHALLENGE_2;
+   sc2b.sam_type = sam_type;
+ 
+   switch (sam_type) {
+      case PA_SAM_TYPE_CRYPTOCARD:
+ 	{
+ 	  krb5_tl_data tl_data;
+ #define NUM_CKSUMS	2
+ 	  krb5_rb1_track_data rb1_track_data[NUM_CKSUMS];
+ 	  krb5_data rb1_data;
+ 	  krb5_enc_data rb1_enc_data;
+ 	  krb5_keyblock client_key, sad_key[NUM_CKSUMS];
+ 	  krb5_data defsalt;
+ 	  krb5_enctype rb1_etype;
+ 	  krb5_cksumtype cksumtype;
+ 	  char outputblock[8];
+ 	  int i;
+ 
+ 	  sc2b.sam_type_name.data = "CryptoCard RB-1";
+ 	  sc2b.sam_type_name.length = strlen(sc2b.sam_type_name.data);
+ 	  sc2b.sam_flags = 0;
+ 
+ 	  tl_data.tl_data_type = KRB5_TL_RB1_CHALLENGE;
+ 	  
+ 	  if ((retval = krb5_dbe_lookup_tl_data(kdc_context, sam_db_entry,
+ 			&tl_data)) || (tl_data.tl_data_length == 0)) {
+ 	    /*
+ 	     * No precomputed challenge, so let's make a new one
+ 	     *
+ 	     * What happens here is close to the Digital Pathways challenge
+ 	     * generation: We generate a random key and take each byte,
+ 	     * divide by 2 and do a mod 10.  Note that we do this for
+ 	     * 8 bytes, instead of the SNK 6 bytes.  The challenge length
+ 	     * should probably be configurable ...
+ 	     */
+ 
+ 	     memset(inputblock, 0, sizeof(inputblock));
+ 	     rb1_data.data = inputblock;
+ 	     rb1_data.length = RB1_CHALLENGE_LENGTH;
+ 
+ 	     if (retval = krb5_c_random_make_octets(kdc_context, &rb1_data)) {
+ 		com_err("krb5kdc", retval,
+ 			"generating random challenge for preauth");
+ 		return (retval);
+ 	     }
+ 	     for (i = 0; i<RB1_CHALLENGE_LENGTH; i++)
+ 		inputblock[i] = '0' + ((inputblock[i] & 0x7f ) % 10);
+ 
+ 	     sc2b.sam_challenge_label.data =
+ 			"Press CH/MAC and enter this on the keypad";
+ 	     sc2b.sam_challenge.data = inputblock;
+ 	     sc2b.sam_challenge.length = RB1_CHALLENGE_LENGTH;
+ 	  } else {
+ 	     /*
+ 	      * We had precomputed a challenge from before.  Use that instead
+ 	      */
+ 	     sc2b.sam_challenge_label.data =
+ 		"Press ENTER and compare this challenge to the one on your display";
+ 	     sc2b.sam_challenge.data = (char *) tl_data.tl_data_contents;
+ 	     sc2b.sam_challenge.length = tl_data.tl_data_length;
+ 	     if (tl_data.tl_data_length > sizeof(inputblock))
+ 		tl_data.tl_data_length = sizeof(inputblock);
+ 	     memcpy(inputblock, tl_data.tl_data_contents,
+ 		tl_data.tl_data_length);
+ 	     rb1_data.data = inputblock;
+ 	     rb1_data.length = tl_data.tl_data_length;
+ 	  }
+ 	  sc2b.sam_challenge_label.length= strlen(sc2b.sam_challenge_label.data);
+ 
+ 	  /* TL_DATA can store enctype for RB1 card.  If this TL_DATA	*/
+ 	  /* not exist, default to ENCTYPE_DES_CBC_RAW.			*/
+ 
+ 	  tl_data.tl_data_type = KRB5_TL_RB1_KEYTYPE;
+ 	  if ((retval = krb5_dbe_lookup_tl_data(kdc_context, sam_db_entry,
+ 			&tl_data)) || (tl_data.tl_data_length == 0)) {
+ 		rb1_etype = ENCTYPE_DES_CBC_RAW;
+ 	  } else {
+ 	     if ((tl_data.tl_data_length == sizeof(krb5_enctype)) &&
+ 			tl_data.tl_data_contents)
+ 		/* This is not very portable! requires krb5_enctype == long) */
+ 		rb1_etype = ntohl(*(krb5_enctype *)tl_data.tl_data_contents);
+ 	     else
+ 		rb1_etype = ENCTYPE_DES_CBC_RAW;
+ 	  }
+ 
+   	  if (retval = sam_get_key(kdc_context, sam_db_entry, rb1_etype,
+ 			KRB5_KDB_SALTTYPE_NORMAL, &sam_key))
+      		goto cleanup;
+ 
+ 	  sam_key.enctype = get_raw_enctype(sam_key.enctype);
+ 
+ 	  retval = krb5_c_encrypt_length(kdc_context, sam_key.enctype,
+ 		rb1_data.length,
+ 		(unsigned int *) &rb1_enc_data.ciphertext.length);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		"while getting encrypt_length to encrypt RB1 challenge");
+ 	     goto cleanup;
+ 	  }
+ 	  if (rb1_enc_data.ciphertext.length > sizeof(outputblock)) {
+ 	     com_err("krb5kdc", KRB5_BAD_MSIZE,
+ 		"while encrypting RB1 challenge");
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  memset(&rb1_enc_data, 0, sizeof(rb1_enc_data));
+ 	  rb1_enc_data.ciphertext.length = sizeof(outputblock);
+ 	  rb1_enc_data.ciphertext.data = outputblock;
+ 
+ 	  /* This is to reflect the encryption of the challenge on the	*/
+ 	  /* CryptoCard which does not know about key usage.		*/
+ 
+ 	  retval = krb5_c_encrypt(kdc_context, &sam_key, 0, /* usage = 0 */
+ 			NULL, &rb1_data, &rb1_enc_data);
+ 
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval, "Trying to encrypt challenge");
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  /*
+ 	   * Now convert the output block to something visible.  Turn
+ 	   * the upper four bytes into ASCII (Also from SNK code).  Note
+ 	   * that we want to use raw hex as the output from the RB-1,
+ 	   * so it's a little different than the SNK code.
+ 	   *
+ 	   * Note that we're doing this twice: One for all-uppercase, once
+ 	   * for all lowercase.  If later-on we do extra challenges ahead,
+ 	   * we need to include more.
+ 	   */
+ 
+ 	  for (i=0; i<4; i++) {
+ 	     char n[2];
+ 	     n[0] = outputblock[i] & 0xf;
+ 	     n[1] = (outputblock[i]>>4) & 0xf;
+ 	     /* for v4, we keygen: *(j+(char*)&key1) = (n[1]<<4) | n[0]; */
+ 	     /* for v5, we just generate a string */
+ 	     rb1_track_data[0].ascii_response[2*i+0] = n[1] > 9 ?
+ 			n[1] - 10 + 'A' : '0' + n[1];
+ 	     rb1_track_data[1].ascii_response[2*i+0] = n[1] > 9 ?
+ 			n[1] - 10 + 'a' : '0' + n[1];
+ 	     rb1_track_data[0].ascii_response[2*i+1] = n[0] > 9 ?
+ 			n[0] - 10 + 'A' : '0' + n[0];
+ 	     rb1_track_data[1].ascii_response[2*i+1] = n[0] > 9 ?
+ 			n[0] - 10 + 'a' : '0' + n[0];
+ 	     /* and now, response has what we work with. */
+ 	  }
+ 	  rb1_track_data[0].ascii_response[8] = 0;
+ 	  rb1_track_data[1].ascii_response[8] = 0;
+ 
+ 	  /*
+ 	   * We diverge from the SNK code here.
+ 	   *
+ 	   * Since we want to include both the response and the precomputed
+ 	   * challenge for next time, we don't use predicted_sam_response
+ 	   * but create our own structure for the track data (that's allowed
+ 	   * by the spec).  First off, let's use the current response
+ 	   * to generate the new challenge.
+ 	   */
+ 
+ 	  /*
+ 	   * Simply take the full encrypted response block, convert it
+ 	   * to ASCII numerals, and convert 0xa - 0xf to 0x0 - 0x05
+ 	   */
+ 
+ 	  for (i = 0; i < 8; i++) {
+ 	     rb1_track_data[0].new_challenge[i] =
+ 						(outputblock[i] & 0x0f) | 0x30;
+ 	     rb1_track_data[1].new_challenge[i] =
+ 						(outputblock[i] & 0x0f) | 0x30;
+ 	     if (rb1_track_data[0].new_challenge[i] > 0x39)
+ 		rb1_track_data[0].new_challenge[i] -= 10;
+ 	     if (rb1_track_data[1].new_challenge[i] > 0x39)
+ 		rb1_track_data[1].new_challenge[i] -= 10;
+ 	  }
+ 
+ 	  rb1_data.data = (void *) &rb1_track_data;
+ 	  rb1_data.length = sizeof(rb1_track_data);
+ 
+ 	  retval = krb5_c_encrypt_length(kdc_context, master_keyblock.enctype,
+ 			rb1_data.length,
+ 			(unsigned int *) &rb1_enc_data.ciphertext.length);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", ENOMEM,
+ 			"while getting length to encrypt RB1 sam_track_id");
+ 	     goto cleanup;
+ 	  }
+ 	  rb1_enc_data.ciphertext.data =
+ 			(char *)malloc(rb1_enc_data.ciphertext.length);
+ 	  if (rb1_enc_data.ciphertext.data == NULL) {
+ 	     retval = ENOMEM;
+ 	     com_err("krb5kdc", retval,
+ 			"while allocating memory for RB1 sam_track_id");
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  retval = krb5_c_encrypt(kdc_context, &master_keyblock,
+ 			KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, NULL,
+ 			&rb1_data, &rb1_enc_data);
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval, "while encrypting RB1 sam_track_id");
+ 	     krb5_xfree(rb1_enc_data.ciphertext.data);
+ 	     goto cleanup;
+ 	  }
+ 	  sc2b.sam_flags = 0;
+ 	  sc2b.sam_track_id = rb1_enc_data.ciphertext;
+ 	  sc2b.sam_response_prompt.data = "Enter the displayed response";
+ 	  sc2b.sam_response_prompt.length= strlen(sc2b.sam_response_prompt.data);
+ 	  sc2b.sam_pk_for_sad.length = 0;
+ 
+ 	  rb1_data.data = (void *)&sc2b.sam_nonce;
+ 	  rb1_data.length = sizeof(sc2b.sam_nonce);
+ 	  if (retval = krb5_c_random_make_octets(kdc_context, &rb1_data)) {
+ 	     com_err("krb5kdc", retval,"generating random data for sam_nonce");
+ 	     krb5_xfree(rb1_enc_data.ciphertext.data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  /*
+ 	   * Handle PA-ALT-PRINC keying
+ 	   */
+ 
+ 	  if (opaque) {
+ 	     preauth_info *pi = (preauth_info *) opaque;
+ 
+ 	     retval = sam_get_key(kdc_context, pi->entry,
+ 				  -1 /* default key-type */,
+ 				   KRB5_KDB_SALTTYPE_NORMAL,
+ 				   &client_key);
+ 	     krb5_klog_syslog(LOG_INFO, "Doing PA-ALT-PRINC keying for "
+ 			      "request, using host key %s",
+ 			      pi->altprincstring);
+ 	  } else
+ 	     retval = sam_get_key(kdc_context, client,
+ 				  -1  /* default key-type */,
+ 				  KRB5_KDB_SALTTYPE_NORMAL,
+ 				  &client_key);
+ 	
+ 	  if (retval) {
+ 	     krb5_xfree(rb1_enc_data.ciphertext.data);
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  /* what about salt ??? */
+ 	  memset(&defsalt, 0, sizeof(defsalt));
+ 	  retval = krb5_principal2salt(context, client->princ, &defsalt);
+ 	  if (retval) {
+ 		com_err("krb5kdc", retval,
+ 			"while generating salt for SAD key generation");
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 	  	goto cleanup;
+ 	  }
+ 
+ 	  /*
+ 	   * We need to do the key mixing for all included keys.
+ 	   * Do that here.
+ 	   */
+ 
+ 	  memset(sad_key, 0, sizeof(sad_key));
+ 
+ 	  for (i = 0; i < NUM_CKSUMS; i++) {
+ 	     sad_data.data = rb1_track_data[i].ascii_response;
+ 	     sad_data.length = 8;
+ 	     retval = krb5_c_string_to_key(context, client_key.enctype,
+ 					   &sad_data, &defsalt, &sad_key[i]);
+ 	     if (retval) {
+ 		com_err("krb5kdc", retval, "while running string2key for "
+ 			"client SAD in SAM_CHALLENGE_2");
+ 		if (defsalt.length)
+ 		   krb5_xfree(defsalt.data);
+ 		for (i = 0; i < NUM_CKSUMS; i++)
+ 		   krb5_free_keyblock_contents(context, &sad_key[i]);
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		goto cleanup;
+ 	     }
+ 
+ 	     /*
+ 	      * Now combine the (single) client key with every sad_key.
+ 	      */
+ 
+ 	     retval = krb5_combine_keys(context, &client_key, &sad_key[i],
+ 					&sad_key[i]);
+ 
+ 	     if (retval) {
+ 		com_err("krb5kdc", retval, "while combining keys for "
+ 			"SAM_CHALLENGE_2");
+ 		if (defsalt.length)
+ 		   krb5_xfree(defsalt.data);
+ 		for (i = 0; i < NUM_CKSUMS; i++)
+ 		   krb5_free_keyblock_contents(context, &sad_key[i]);
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		goto cleanup;
+ 	     }
+ 	  }
+ 
+ 	  krb5_free_keyblock_contents(context, &client_key);
+ 
+ 	  if (defsalt.length)
+ 	     krb5_xfree(defsalt.data);
+ 
+ 	  /* Now we have the combined key in sad_key - note that all enctypes
+ 	   * should be the same (we hope) */
+ 	  sc2b.sam_etype = sad_key[0].enctype;
+ 
+ 	  retval = encode_krb5_sam_challenge_2_body(&sc2b,
+ 						    &encoded_challenge_body);
+ 	  if (retval) {
+ 		com_err("krb5kdc", retval,
+ 			"while encoding RB1 SAM_CHALLENGE_2_BODY");
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		goto cleanup;
+ 	  }
+ 
+ 	  cksum_array = (krb5_checksum **)
+ 			calloc(NUM_CKSUMS + 1, sizeof(*cksum_array));
+ 	  if (!cksum_array) {
+ 	     retval = ENOMEM;
+ 	     com_err("krb5kdc", retval, "while allocating checksum array");
+ 	     krb5_xfree(rb1_enc_data.ciphertext.data);
+ 	     krb5_free_keyblock_contents(context, &client_key);
+ 	     krb5_free_data(context, encoded_challenge_body);
+ 	     goto cleanup;
+ 	  }
+ 	  cksum_array[NUM_CKSUMS] = (krb5_checksum *)NULL;
+ 		
+ 	  for (i=0; i<NUM_CKSUMS; i++) {
+ 	     cksum_array[i] = (krb5_checksum *)malloc(sizeof(*cksum_array[i]));
+ 	     if (!cksum_array[i]) {
+ 		int j;
+ 		retval = ENOMEM;
+ 		for (j=i-1; j>=0; j--)
+ 		  krb5_xfree(cksum_array[j]);
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 		krb5_free_keyblock_contents(context, &client_key);
+ 		krb5_free_data(context, encoded_challenge_body);
+ 		goto cleanup;
+ 	     }
+ 	  }
+ 
+ 	  /*
+ 	   * Now we compute the checksums over the encoded challenge
+ 	   * Note that we do it twice currently (once for uppercase, once
+ 	   * for lowercase).  Maybe later on we'll do more.
+ 	   */
+ 
+ 	  for (i = 0; i < NUM_CKSUMS; i++) {
+ 	     retval = sam_cksumtype(context, sad_key[i].enctype, &cksumtype);
+ 
+ 	     if (!retval) 
+ 	        retval = krb5_c_make_checksum(context, cksumtype, &sad_key[i],
+ 					KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
+ 					encoded_challenge_body, cksum_array[i]);
+ 	     if (retval) {
+ 		cksum = cksum_array;
+ 		while (*cksum) {
+ 		   krb5_free_checksum(context, *cksum);
+ 		   cksum++;
+ 		}
+ 		for (i = 0; i < NUM_CKSUMS; i++)
+ 		   krb5_free_keyblock_contents(context, &sad_key[i]);
+ 		krb5_xfree(cksum_array);
+ 		krb5_xfree(rb1_enc_data.ciphertext.data);
+ 		krb5_free_data(context, encoded_challenge_body);
+ 		goto cleanup;
+ 	     }
+ 	  }
+ 	  
+ 	  /* Free the keys used for checksumming */
+ 	  for (i = 0; i < NUM_CKSUMS; i++)
+ 	     krb5_free_keyblock_contents(context, &sad_key[i]);
+ 
+ 	  /* Add in the checksums, and encode the final challenge*/
+ 	  sc2.sam_challenge_2_body.data = encoded_challenge_body->data;
+ 	  sc2.sam_challenge_2_body.length = encoded_challenge_body->length;
+ 	  sc2.sam_cksum = cksum_array;
+ 	  retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge);
+ 
+ 	  krb5_free_data(context, encoded_challenge_body);
+ 
+ 	  cksum = cksum_array;
+ 	  while (*cksum) {
+ 	     krb5_free_checksum(context, *cksum);
+ 	     cksum++;
+ 	  }
+ 	  krb5_xfree(cksum_array);
+ 	  krb5_xfree(rb1_enc_data.ciphertext.data);
+ 
+ 	  if (retval) {
+ 	     com_err("krb5kdc", retval, "while encoding RB1 SAM_CHALLENGE_2");
+ 	     goto cleanup;
+ 	  }
+ 
+ 	  /* Make pa-data */
+ 	  pa_data->magic = KV5M_PA_DATA;
+ 	  pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2;
+ 	  pa_data->contents = (unsigned char *) encoded_challenge->data;
+ 	  pa_data->length = encoded_challenge->length;
+ 	  retval = 0;
+ 
+ 	}
+ 	break;
+ #ifdef ARL_SECURID_PREAUTH
+      case PA_SAM_TYPE_SECURID:
+ 	if (retval = get_securid_edata_2(context, client, &sc2b, &sc2))
+ 	   goto cleanup;
+ 
+ 	retval = encode_krb5_sam_challenge_2(&sc2, &encoded_challenge);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval,"while encoding SECURID SAM_CHALLENGE_2");
+ 	   return(retval);
+ 	}
+ 
+ 	pa_data->magic = KV5M_PA_DATA;
+ 	pa_data->pa_type = KRB5_PADATA_SAM_CHALLENGE_2;
+ 	pa_data->contents = encoded_challenge->data;
+ 	pa_data->length = encoded_challenge->length;
+ 
+ 	retval = 0;
+ 	break;
+ #endif  /* ARL_SECURID_PREAUTH */
+      default:
+ 	retval = KRB5_PREAUTH_BAD_TYPE;
+ 	goto cleanup;
+   }
+ 
+ cleanup:
+   if (sam_key.contents)
+ 	krb5_free_keyblock_contents(kdc_context, &sam_key);
+   if (sam_db_entry)
+ 	krb5_db_free_principal(kdc_context, sam_db_entry, 1);
+   return (retval);
+ }
+ 
+ static krb5_error_code return_sam_data_2 (
+ 		krb5_context context,
+ 		krb5_pa_data * padata,
+ 		krb5_db_entry *client,
+ 		krb5_kdc_req *request,
+ 		krb5_kdc_rep *reply,
+ 		krb5_key_data *client_key,
+ 		krb5_keyblock *encrypting_key,
+ 		krb5_pa_data **send_pa,
+ 		void *opaque) {
+ 
+    krb5_error_code retval;
+    krb5_data scratch;
+    krb5_enc_data tmp_enc_data;
+    krb5_sam_response_2 *sr2 = NULL;
+    int i, index;
+ 
+    if (padata == NULL)
+ 	return(0);
+ 
+    scratch.data = (char *) padata->contents;
+    scratch.length = padata->length;
+ 
+    retval = decode_krb5_sam_response_2(&scratch, &sr2);
+    if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while decoding SAM_RESPONSE_2 in return_padata()");
+ 	sr2 = NULL;
+ 	goto cleanup;
+    }
+ 
+    switch (sr2->sam_type) {
+      case PA_SAM_TYPE_SECURID:
+ 	/* Nothing to do here for SecurID, since we still use the client's */
+ 	/* key to encrypt the AS_REP */
+ 	goto cleanup;
+ 
+      case PA_SAM_TYPE_CRYPTOCARD: {
+ 	krb5_rb1_track_data *rb1_track_data;
+ 	krb5_data sad_data;
+ 	krb5_data defsalt;
+ 	krb5_keyblock sad_key;
+ 	krb5_keyblock client_key;
+ 
+         /*
+ 	 * Handle PA-ALT-PRINC keying
+ 	 */
+ 
+ 	if (opaque && ((preauth_info *)opaque)->entry) {
+ 	   preauth_info *pi = (preauth_info *) opaque;
+ 
+ 	   retval = sam_get_key(kdc_context, pi->entry,
+ 				-1, /* default key-type */
+ 				KRB5_KDB_SALTTYPE_NORMAL, &client_key);
+ 	} else
+ 	   retval = sam_get_key(kdc_context, client, -1, /* default key-type */
+ 				KRB5_KDB_SALTTYPE_NORMAL, &client_key);
+ 
+ 	if (retval)
+ 	   goto cleanup;
+ 
+ 	/* decrypt track ID with master key */
+ 	tmp_enc_data.ciphertext = sr2->sam_track_id;
+ 	tmp_enc_data.enctype = ENCTYPE_UNKNOWN;
+ 	scratch.length = tmp_enc_data.ciphertext.length;
+ 	scratch.data = (char *) malloc(scratch.length);
+ 	if (!scratch.data) {
+ 	   retval = ENOMEM;
+ 	   com_err("krb5kdc", retval,
+ 		"while decrpyting track_id data in return_padata()");
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 	   goto cleanup;
+ 	}
+ 	retval = krb5_c_decrypt(context, &master_keyblock,
+ 			KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, NULL,
+ 			&tmp_enc_data, &scratch);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval,
+ 		"while decrpyting track_id data in return_padata()");
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 	   krb5_free_data(context, &scratch);
+ 	   goto cleanup;
+ 	}
+ 	rb1_track_data = (krb5_rb1_track_data *)scratch.data;
+ 	index = ((preauth_info *) opaque)->slot;
+ 	sad_data.data = rb1_track_data[index].ascii_response;
+ 	sad_data.length = 8;  /* yuck */
+ 	
+ 	memset(&sad_key, 0, sizeof(sad_key));
+ 	memset(&defsalt, 0, sizeof(defsalt));
+ 
+ 	retval = krb5_principal2salt(context, client->princ, &defsalt);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval,
+ 	      "while generating salt for SAD key generation in return_padata");
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 	   krb5_free_data_contents(context, &scratch);
+ 	   goto cleanup;
+ 	}
+ 	retval = krb5_c_string_to_key(context, client_key.enctype,
+ 			&sad_data, &defsalt, &sad_key);
+ 	krb5_free_data_contents(context, &scratch);
+ 	if (defsalt.length)
+ 	   krb5_xfree(defsalt.data);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval,
+ 		"while generating SAD key in return_padata");
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 	}
+ 
+ 	retval = krb5_combine_keys(context, &client_key, &sad_key, &client_key);
+ 	krb5_free_keyblock_contents(context, &sad_key);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval, "while combining keys in return_padata");
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 	   goto cleanup;
+ 	}
+ 
+ 	krb5_free_keyblock_contents(context, encrypting_key);
+ 	encrypting_key->enctype = client_key.enctype;
+ 	encrypting_key->length = client_key.length;
+ 	encrypting_key->contents = client_key.contents;
+ 	memset(&client_key, 0, sizeof(client_key));
+ 	
+ 	retval = 0;
+ 	goto cleanup;
+      } /* end case PA_SAM_TYPE_CRYPTOCARD */
+      default:
+ 	goto cleanup;
+ 
+    }
+ cleanup:
+    if (sr2)
+      krb5_free_sam_response_2(context, sr2);
+    return retval;
+ 
+ }
Index: krb5/kdc/securid2.c
diff -c /dev/null krb5/kdc/securid2.c:1.7
*** /dev/null	Sun Mar 16 20:22:19 2003
--- krb5/kdc/securid2.c	Mon Mar 10 15:26:11 2003
***************
*** 0 ****
--- 1,1448 ----
+ /* This is to pick up the KRB5_TL_SECURID_STATE definition in	*/
+ /* include/krb5/kdb.h						*/
+ 
+ #define SECURID
+ 
+ #include "k5-int.h"
+ #include "kdc_util.h"
+ #include "extern.h"
+ #include <stdio.h>
+ 
+ #include <syslog.h>
+ 
+ #include <acexport.h>
+ #include <sdi_defs.h>
+ #include <sdi_athd.h>
+ 
+ #define KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC		0x5ec1d000
+ 
+ struct securid_track_data {
+ 	SDI_HANDLE handle;
+ 	char state;
+ 	char passcode[LENPRNST+1];
+ };
+ 
+ #define SECURID_STATE_NEW_PIN           1       /* Ask for a new pin */
+ #define SECURID_STATE_NEW_PIN_AGAIN     2       /* Ask for new pin again */
+ #define SECURID_STATE_NEXT_CODE         3       /* Ask for the next pin code */ 
+ 
+ extern krb5_error_code sam_get_db_entry(krb5_context , krb5_principal *,
+                         int *, krb5_db_entry **);
+ 
+ static char *PASSCODE_message = 	"SecurID Passcode";
+ static char *NEXT_PASSCODE_message = 	"Next Passcode";
+ static char *NEW_PIN_message = 		"New PIN";
+ static char *NEW_PIN_AGAIN_message = 	"New PIN Again";
+ static char PIN_message[64];		/* Max length should be 50 chars */
+ 
+ /*	krb5_error_code get_securid_key():
+  *		inputs:  context:  from KDC process
+  *			 client:   database entry of client executing
+  *				   SecurID SAM preauthentication
+  *		outputs: client_securid_key: pointer to krb5_keyblock
+  *				   which is key for the client's SecurID
+  *				   database entry.
+  *		returns: 0 on success
+  *			 KRB5 error codes otherwise
+  *
+  *		builds pricipal name with final instance of "SECURID" and
+  *		finds the database entry, decrypts the key out of the database
+  *		and passes the key back to the calling process
+  */
+ 
+ krb5_error_code get_securid_key(context, client, client_securid_key)
+     krb5_context context;
+     krb5_db_entry *client;
+     krb5_keyblock *client_securid_key;
+ {
+     krb5_db_entry client_securid_entry;
+     krb5_key_data *client_securid_key_data = 0;
+     krb5_error_code retval = 0;
+     krb5_principal newp;
+     krb5_int32 slot = 0;
+     int nprinc, more;
+     char *user = NULL;
+     char *def_user = "<unknown username>";
+ 
+     if (!client_securid_key) return(KRB5_PREAUTH_NO_KEY);
+ 
+     krb5_unparse_name(context, client->princ, &user);
+ 
+     retval = krb5_copy_principal(context, client->princ, &newp);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 	   "while copying name for SecurID SAM principal lookup (%s)",
+ 	   user ? user : def_user);
+ 	if (user) krb5_xfree(user);
+ 	return(KRB5_PREAUTH_NO_KEY);
+     }
+     slot = krb5_princ_size(context, newp)++;
+     krb5_princ_name(kdc_context, newp) =
+ 		realloc(krb5_princ_name(kdc_context, newp),
+ 		krb5_princ_size(context, newp) * sizeof(krb5_data));
+     krb5_princ_component(context,newp,slot)->data = "SECURID";
+     krb5_princ_component(context,newp,slot)->length =
+ 		strlen("SECURID");
+     nprinc = 1;
+     retval = krb5_db_get_principal(context, newp,
+ 		&client_securid_entry, &nprinc, &more);
+ 
+     krb5_princ_component(context,newp,slot)->length = 0;
+     krb5_princ_component(context,newp,slot)->data = 0;
+     krb5_princ_size(context, newp)--;
+     krb5_free_principal(context,newp);
+ 
+     if (retval || (nprinc != 1)) {
+ 	com_err("krb5kdc", retval,
+ 	   "while looking up client's SAM SecurID entry in DB (%s)",
+ 	   user ? user : def_user);
+ 	if (user) krb5_xfree(user);
+ 	return(KRB5_PREAUTH_NO_KEY);
+     }
+ 
+     /* Find key with key_type = salt_type = kvno = -1.  This finds the	*/
+     /* latest kvno in the list.  					*/
+ 
+     retval = krb5_dbe_find_enctype(context, &client_securid_entry,
+ 		-1, -1, -1, &client_securid_key_data);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while getting key from client's SAM SecurID entry (%s)",
+ 		user ? user : def_user);
+ 	if (user) krb5_xfree(user);
+ 	return(KRB5_PREAUTH_NO_KEY);
+     }
+     retval = krb5_dbekd_decrypt_key_data(context, &master_keyblock,
+ 		client_securid_key_data, client_securid_key, NULL);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while decrypting key from client's SAM SecurID entry (%s)",
+ 		user ? user : def_user);
+ 	if (user) krb5_xfree(user);
+ 	return(KRB5_PREAUTH_NO_KEY);
+     }
+     return(0);
+ }
+ 
+ /* decrypt_track_data()							*/
+ /* Decrypt track data for "old" SAM preauth.  Notice no key usage value */
+ 
+ krb5_error_code
+ decrypt_track_data(krb5_context context, krb5_db_entry *client,
+         krb5_data *enc_track_data, krb5_data *output) {
+   int retval;
+   krb5_keyblock client_securid_key;
+   krb5_enc_data tmp_enc_data;
+  
+   if (!output || !enc_track_data) return(KRB5KDC_ERR_PREAUTH_FAILED);
+ 
+   output->length = enc_track_data->length;
+   output->data = (krb5_octet *)malloc(output->length);
+   if (!output->data)
+ 	return(ENOMEM);
+ 
+   if (retval = get_securid_key(context, client, &client_securid_key)) {
+ 	free(output->data);
+ 	return(retval);
+   }
+ 
+   tmp_enc_data.ciphertext.data = enc_track_data->data;
+   tmp_enc_data.ciphertext.length = enc_track_data->length;
+   tmp_enc_data.enctype = client_securid_key.enctype;
+   tmp_enc_data.kvno = 0;
+  
+   retval = krb5_c_decrypt(context, &client_securid_key, 0, 0,
+ 	&tmp_enc_data, output);
+  
+   krb5_free_keyblock_contents(context, &client_securid_key);
+ 
+   if (retval) {
+      free(output->data);
+      output->data = NULL;
+   }
+   return(retval);
+ }
+ 
+ /* encrypt_track_data()							*/
+ /* Encrypt track data for "old" SAM preauth.  Notice no key usage value */
+ 
+ krb5_error_code
+ encrypt_track_data(krb5_context context, krb5_db_entry *client,
+         krb5_data *input, krb5_data *enc_track_data) {
+   int retval = 0;
+   krb5_keyblock client_securid_key;
+   krb5_enc_data tmp_enc_data;
+  
+   if (!input || !enc_track_data) return(KRB5KDC_ERR_PREAUTH_FAILED);
+ 
+   if (retval = get_securid_key(context, client, &client_securid_key))
+ 	return(retval);
+ 
+   if (retval = krb5_c_encrypt_length(context, client_securid_key.enctype,
+ 		input->length, &tmp_enc_data.ciphertext.length))
+ 	goto cleanup;
+ 
+   if (!(tmp_enc_data.ciphertext.data =
+ 		(char *)malloc(tmp_enc_data.ciphertext.length))){
+ 	retval = ENOMEM;
+ 	goto cleanup;
+   }
+ 
+   if (retval = krb5_c_encrypt(context, &client_securid_key, 0, 0,
+ 		input, &tmp_enc_data))
+ 	goto cleanup;
+ 
+   enc_track_data->data = tmp_enc_data.ciphertext.data;
+   enc_track_data->length= tmp_enc_data.ciphertext.length;
+ 
+ cleanup:
+   if (client_securid_key.contents)
+      krb5_free_keyblock_contents(context, &client_securid_key);
+  
+   return(retval);
+ }
+ 
+ /*  krb5_error_code get_securid_edata()
+  *		inputs:  context from KDC
+  *			 possibly e_data from verify_securid_data which
+  *			   holds a new sam_challnge
+  *		outputs: sam_challenge structure contents to be encoded
+  *			 and sent as a AS_ERR message by calling routine
+  *		returns: 0 on success
+  *			 KRB5 error codes otherwise
+  *
+  *		This routine is called when insufficient preauth data is
+  *		sent to the KDC.  The edata returned is either a generic
+  *		SecurID prompt or a "Next Card Code" prompt with associated
+  *		(encrypted) sam_track_id data.  If SecurID card is in NEXT
+  *		PRN mode, the e_data field of the client's DB entry contains
+  *		an sam_challenge struct that was allocated and filled in
+  *		by the preceeding call to verify_securid_data().
+  */
+ 
+ krb5_error_code get_securid_edata(context, client, sc)
+     krb5_context context;
+     krb5_db_entry *client;
+     krb5_sam_challenge *sc;
+ {
+     krb5_data *tmp_data;
+     krb5_sam_challenge *scp;
+ 
+     /* If e_data is the right length, has the right magic, and has a	*/
+     /* data pointer then we can assume it was sent from			*/
+     /* verify_securid_data() as the next challenge (NEXT_CODE, NEW_PIN) */
+ 
+     if ((tmp_data = (krb5_data *)client->e_data) &&
+ 	(client->e_length == sizeof(krb5_data)) && (tmp_data->data) &&
+ 	(tmp_data->magic == KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC) ) {
+ 
+ 	   scp = (krb5_sam_challenge *)tmp_data->data;
+ 	   
+ 	   /* We shouldn't just memcpy this because get_sam_edata() has	*/
+ 	   /* already set some fields that we don't necessarily want to	*/
+ 	   /* overwrite							*/
+ 
+ 	   sc->sam_flags =		scp->sam_flags;
+ 	   sc->sam_type_name = 		scp->sam_type_name;
+ 	   sc->sam_track_id =		scp->sam_track_id;
+ 	   sc->sam_challenge_label =	scp->sam_challenge_label;
+ 	   sc->sam_challenge = 		scp->sam_challenge;
+ 	   sc->sam_response_prompt = 	scp->sam_response_prompt;
+ 	   sc->sam_pk_for_sad =		scp->sam_pk_for_sad;
+ 	   sc->sam_nonce =		scp->sam_nonce;
+ 	   sc->sam_cksum =		scp->sam_cksum;
+ 
+ 	   /* This was memory allocated by verify_securid_data() */
+ 
+ 	   free(scp);
+ 	   client->e_data = NULL;
+ 	   client->e_length = 0;
+ 	   free(tmp_data);
+     } else {
+ 
+ 	   sc->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 	   sc->sam_type_name.length = 0;
+ 	   sc->sam_challenge_label.length = 0;
+ 	   sc->sam_challenge.length = 0;
+ 	   sc->sam_response_prompt.data = PASSCODE_message;
+ 	   sc->sam_response_prompt.length =
+ 				strlen(sc->sam_response_prompt.data);
+ 	   sc->sam_pk_for_sad.length = 0;
+ 	   sc->sam_nonce = 0;
+ 	   sc->sam_cksum.contents = (char *)0;
+ 	   sc->sam_cksum.length = 0;
+ 	   sc->sam_track_id.length = 0;
+     }
+ 
+     return (0);
+ }
+ 
+ /*	krb5_error_code verify_securid_data()
+  *		inputs:   context: context from KDC
+  *			  client: db entry of client executing SecurID preauth
+  *			  sr: sam_response from client
+  *			  enc_tkt_reply: encrypted part of TGT reply for
+  *					 setting flags
+  *		outputs:  static sam_challenge structure
+  *		returns:  0 if passcode check was successful (even if
+  *				card is in NEXT_PRN mode)
+  *			  KRB5_PREAUTH_FAILED for invalid SecurID code
+  *			  other KRB5 error codes
+  *
+  *		Zeroes out static sam_challenge structure, decrypts and
+  *		decodes enc_sam_response_enc (using client's "password")
+  *		to get passcode data.  If sam_track_id.data is present,
+  *		decrypt this data with client's SecurID key and use it as
+  *		sd_dat structure to pass to sd_next().  If sd_next is
+  *		successful, set enc_tkt_reply flags and return.  If no
+  *		sam_track_id.data is present, initialize SecurID communications
+  *		and check passcode.  If passcode is correct, set enc_tkt_reply
+  *		flags and return success, if card in NEXT_PRN mode, set
+  *		PREAUTH flag, but not HW_AUTH flag, build sam_challnge in
+  *		static space, and set sam_track_id to encrypted sd_dat struct.
+  *		get_securid_edata will pick this data up and pass it back in
+  *		AS_ERR message.
+  */
+ 
+ krb5_error_code verify_securid_data(context, client, sr, enc_tkt_reply, pa)
+     krb5_context context;
+     krb5_db_entry *client;
+     krb5_sam_response *sr;
+     krb5_enc_tkt_part *enc_tkt_reply;
+     krb5_pa_data *pa;
+ {
+     krb5_error_code retval = -1;
+     krb5_keyblock client_key;
+     krb5_key_data *client_key_data;
+     krb5_data scratch;
+     krb5_enc_data tmp_enc_data;
+     krb5_enc_sam_response_enc *esre = 0;
+     struct securid_track_data s_track, *trackp;
+     char passcode[LENPRNST+1];
+     char *cp, *user = NULL;
+     char *securid_user = NULL;
+     krb5_data *tmp_data_ptr;
+     SDI_HANDLE sd_handle = SDI_HANDLE_NONE;
+ 
+     client_key.contents = NULL;
+ 
+     if (retval = krb5_unparse_name(context, client->princ, &user)) {
+ 	com_err("krb5kdc", retval, "while unparsing client principal name");
+ 	goto securid_cleanup;
+     }
+ 
+     /* Find client key to decrypt SAM_RESPONSE */
+     if (retval = krb5_dbe_find_enctype(context, client,
+ 		sr->sam_enc_nonce_or_ts.enctype, KRB5_KDB_SALTTYPE_NORMAL,
+ 		0, &client_key_data) ) {
+ 	com_err("krb5kdc", retval,
+ 		"while looking for key to decrypt SecurID SAM_RESPONSE (%s)",
+ 		user);
+ 	goto securid_cleanup;
+     }
+ 
+     /* If key is close-enough to enctype of SAD, then we can still use it. */
+     if (client_key_data->key_data_type[0] != sr->sam_enc_nonce_or_ts.enctype) {
+ 	krb5_boolean similar;
+ 	retval = krb5_c_enctype_compare(context,
+ 			client_key_data->key_data_type[0],	
+ 			sr->sam_enc_nonce_or_ts.enctype, &similar);
+ 	if (!retval && similar) {
+ 	  client_key_data->key_data_type[0] = sr->sam_enc_nonce_or_ts.enctype;
+ 	} else {
+ 	  com_err("krb5kdc", retval,
+ 		"while finding proper keytype to decrypt SecurID code (%s)",
+ 		user);
+ 	  retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	  goto securid_cleanup;
+ 	}
+     }
+ 
+     if (retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock,
+               client_key_data, &client_key, NULL) ) {
+       com_err("krb5kdc", retval,
+ 	"while decrypting client's key to decrypt SecurID SAM_RESPONSE (%s)",
+ 	user);
+       goto securid_cleanup;
+     }
+ 
+     if (!(sr->sam_enc_nonce_or_ts.ciphertext.data)) {
+       retval = KRB5KDC_ERR_PREAUTH_FAILED;
+       com_err("krb5kdc", retval,
+ 		"No SecurID passcode found (%s)", user);
+       goto securid_cleanup;
+     }
+ 
+     scratch.length = sr->sam_enc_nonce_or_ts.ciphertext.length;
+     if ((scratch.data = (krb5_octet *) malloc(scratch.length)) == NULL) {
+ 	com_err("krb5kdc", ENOMEM,
+ 		"while decrypting SAM_RESPONSE SecurID data (%s)", user);
+ 	retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	goto securid_cleanup;
+     }
+     retval = krb5_c_decrypt(context, &client_key, 0, 0,
+ 			&sr->sam_enc_nonce_or_ts, &scratch);
+     if (retval) {
+ 	com_err("krb5kdc", retval, "while decrypting SecurID SAD (%s)", user);
+         goto securid_cleanup;
+     }
+ 
+     retval = decode_krb5_enc_sam_response_enc(&scratch, &esre);
+     if (retval) {
+ 	com_err("krb5kdc", retval, "while decoding SecurID SAD (%s)", user);
+ 	esre = NULL;
+         goto securid_cleanup;
+     }
+ 
+     /* Check nonce */
+     if (esre->sam_nonce != sr->sam_nonce) {
+ 	retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	com_err("krb5kdc", retval, "bad nonce in SecurID SAM_RESPONSE (%s)",
+ 		user);
+         goto securid_cleanup;
+     }
+ 
+     /* Check for passcode */
+     if (!(esre->sam_sad.length) || !(esre->sam_sad.data) ) {
+         retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	com_err("krb5kdc", retval,
+ 		"zero-length passcode in SecurID SAM_RESPONSE (%s)", user);
+         goto securid_cleanup;
+     }
+ 
+     /* Copy out passcode so it can be NULL-terminated and used as a string */
+     if (esre->sam_sad.length > (sizeof(passcode) - 1))
+        esre->sam_sad.length = (sizeof(passcode) - 1);
+     memcpy(&passcode, esre->sam_sad.data, esre->sam_sad.length);
+     passcode[esre->sam_sad.length] = (char)0;
+ 
+     /* We could consult a Kerberos principal to SecurID username lookup	*/
+     /* table here.							*/
+ 
+     securid_user = strdup(user);
+     if (!securid_user) {
+ 	com_err("krb5kdc", ENOMEM,
+ 		"while copying user name in verify_securid_data (%s)", user);
+ 	goto securid_cleanup;
+     }
+     if (cp = strchr(securid_user, '@'))
+     	*cp = (char)0;
+ 
+     /* If this is the 2nd time around (or greater), we'll have a	*/
+     /* track_id which will have our SecurID client state. Decrypt this	*/
+     /* with the <user>/SECURID key and use it in the call to the ACE	*/
+     /* server.								*/
+ 
+     if (sr->sam_track_id.length) {
+ 	krb5_data tmp_data;
+ 
+         /* This is second time around to this routine, either NEXT_PRN
+          * or NEW_PIN
+          */
+ 	memset(&tmp_data, 0, sizeof(tmp_data));
+ 	if (retval = decrypt_track_data(context, client, &sr->sam_track_id,
+ 			&tmp_data))
+ 	   goto securid_cleanup;
+ 
+ 	trackp = (struct securid_track_data *)tmp_data.data;
+ 	switch (trackp->state) {
+ 	  case SECURID_STATE_NEW_PIN_AGAIN:
+ 	     {
+ 		int pin1_len, pin2_len;
+ 
+ 		trackp->handle = ntohl(trackp->handle);
+ 		/* passcode has been null-terminated */
+ 		pin2_len = strlen(passcode);
+ 		pin1_len = strlen(trackp->passcode);	
+ 
+ 		if ((pin1_len != pin2_len) ||
+ 		      (memcmp(passcode, trackp->passcode, pin1_len) != 0)) {
+ 		  retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		  krb5_klog_syslog(LOG_INFO,
+ 			"SecurID new PIN mis-match for user %s", securid_user);
+ 		  break;
+ 		}
+ 		
+ 		retval = SD_Pin(trackp->handle, passcode);
+ 		SD_Close(trackp->handle);
+ 
+ 		if (retval == ACM_NEW_PIN_ACCEPTED) {
+ 		   setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+         	   setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		   krb5_klog_syslog(LOG_INFO,
+ 			"New SecurID PIN Accepted for user %s", securid_user);
+ 		   retval = 0;
+ 		} else {
+ 		   krb5_klog_syslog(LOG_INFO,
+ 		     "New SecurID PIN rejected for %s (AceServer returns %d)",
+ 		     securid_user, retval);
+ 		   retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		}
+ 		break;
+ 	     }
+ 	  case SECURID_STATE_NEW_PIN:
+ 	     {
+ 		krb5_data new_track_data;
+ 		krb5_sam_challenge *scp;
+ 
+ 		scp = (krb5_sam_challenge *)malloc (sizeof(krb5_sam_challenge));
+ 		if (!scp) {
+ 		  retval = ENOMEM;
+ 		  goto securid_cleanup;
+ 		}
+ 		scp->sam_type_name.length = 0;
+ 		scp->sam_challenge_label.length = 0;
+ 		scp->sam_challenge.length = 0;
+ 		scp->sam_nonce = 0;
+ 		scp->sam_response_prompt.data = NEW_PIN_AGAIN_message;
+ 		scp->sam_response_prompt.length = strlen(scp->sam_response_prompt.data);                scp->sam_pk_for_sad.length = 0;
+ 		scp->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		scp->sam_cksum.contents = (char *)0;
+ 		scp->sam_cksum.length = 0;   
+ 
+ 		/* Pascode holds first copy of new PIN, put it into	*/
+ 		/* track_data and challenge user for PIN again.  Leave	*/
+ 		/* s_track.handle alone					*/
+ 
+ 		s_track.state = SECURID_STATE_NEW_PIN_AGAIN;
+ 		s_track.handle = trackp->handle;
+ 		memcpy(s_track.passcode, passcode, sizeof(s_track.passcode));
+ 
+                 new_track_data.data = (char *)&s_track;
+                 new_track_data.length = sizeof(s_track);
+  
+                 if (retval = encrypt_track_data(context, client,
+ 			&new_track_data, &scp->sam_track_id)) {
+                   if (scp) free(scp);
+                   break;
+                 }
+  
+                 tmp_data_ptr = (krb5_data *)malloc(sizeof(*tmp_data_ptr));
+                 if (!tmp_data_ptr) {
+                    if (scp) free(scp);
+                    break;
+                 }
+                 tmp_data_ptr->magic = KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC;
+                 tmp_data_ptr->length = sizeof(*scp);
+                 tmp_data_ptr->data = (char *)scp;
+  
+                 /* Shove this data into the e_data pointer in the client's  */	
+                 /* DB entry.  It will get picked up by get_edata() later on */
+                 if (client->e_data) {
+                   /* Generate warning that this user may lose e_data */
+                 }
+                 client->e_data = (krb5_octet *)tmp_data_ptr;
+                 client->e_length = sizeof(*tmp_data_ptr);
+ 
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "Requesting verification of new PIN for user %s",
+ 		   securid_user);
+ 		/* This indicates to to caller that we were successful thus
+ 		 * far, but still need additional preauth to consider success
+ 		 */
+ 		retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
+ 		
+ 		break;
+ 	     }
+ 	  case SECURID_STATE_NEXT_CODE:
+ 		trackp->handle = ntohl(trackp->handle);
+ 		retval = SD_Next(trackp->handle, passcode);
+ 		SD_Close(trackp->handle);
+ 		if (retval == ACM_OK) {
+ 		   setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+         	   setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		   krb5_klog_syslog(LOG_INFO,
+ 		      "Next SecurID Code Accepted for user %s", securid_user);
+ 		   retval = 0;
+ 		} else {
+ 		   krb5_klog_syslog(LOG_INFO,
+ 		      "Next SecurID Code Failed for %s (AceServer returns %d)",
+ 		      securid_user, retval);
+ 		   retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		}
+ 		break;
+ 	}
+ 	
+ 	if (tmp_data.data)
+ 	  krb5_xfree(tmp_data.data);
+ 	goto securid_cleanup;
+     } else {
+ 	krb5_data tmp_data;
+ 	krb5_sam_challenge *scp;
+ 
+         /* Treat this as a first attempt at SecurID checking */
+ 
+ 	memset(&tmp_data, 0, sizeof(tmp_data));
+ 	if (retval = SD_Init(&sd_handle)) {
+ 	  com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 		"SD_Init() failed (AceServer returns %d) for %s",
+ 		retval, securid_user);
+ 	  retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	  goto securid_cleanup;
+ 	}
+ 	  
+ 	retval = SD_Check(sd_handle, passcode, securid_user);
+ 	switch (retval) {
+ 	  case ACM_OK:
+ 		SD_Close(sd_handle);
+ 		setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+ 		setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "SecurID passcode accepted for user %s", securid_user);
+ 		retval = 0;
+ 		break;
+ 	  case ACM_ACCESS_DENIED:
+ 		SD_Close(sd_handle);
+ 		retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "AceServer returned Access Denied: user %s", securid_user);
+ 		break;
+ 	  case ACM_NEXT_CODE_REQUIRED:
+ 		scp = (krb5_sam_challenge *)malloc (sizeof(krb5_sam_challenge));
+ 		if (!scp) {
+ 			retval = ENOMEM;
+ 			goto securid_cleanup;
+ 		}
+ 		scp->sam_type_name.length = 0;
+ 		scp->sam_challenge_label.length = 0;
+ 		scp->sam_challenge.length = 0;
+ 		scp->sam_response_prompt.data = NEXT_PASSCODE_message;
+ 		scp->sam_response_prompt.length = strlen(scp->sam_response_prompt.data);
+ 		scp->sam_pk_for_sad.length = 0;
+ 		scp->sam_nonce = 0;
+ 		scp->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		scp->sam_cksum.contents = (char *)0;
+ 		scp->sam_cksum.length = 0;
+ 
+ 		memset(&s_track, 0, sizeof(s_track));
+ 		s_track.state = SECURID_STATE_NEXT_CODE;
+ 		s_track.handle = htonl(sd_handle);
+ 
+ 		tmp_data.data = (char *)&s_track;
+ 		tmp_data.length = sizeof(s_track);
+ 
+ 		if (retval = encrypt_track_data(context, client, &tmp_data,
+ 			&scp->sam_track_id)) {
+ 		  if (scp) free(scp);
+ 		  break;
+ 		}
+ 
+ 		tmp_data_ptr = (krb5_data *)malloc(sizeof(*tmp_data_ptr));
+ 		if (!tmp_data_ptr) {
+ 		   retval = ENOMEM;
+ 		   if (scp) free(scp);
+ 		   break;
+ 		}
+ 		tmp_data_ptr->magic = KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC;
+ 		tmp_data_ptr->length = sizeof(*scp);
+ 		tmp_data_ptr->data = (char *)scp;
+ 
+ 		/* Shove this data into the e_data pointer in the client's  */
+ 		/* DB entry.  It will get picked up by get_edata() later on */
+ 		if (client->e_data) {
+ 		  /* Generate warning that this user may lose e_data */
+ 		}
+ 		client->e_data = (krb5_octet *)tmp_data_ptr;
+ 		client->e_length = sizeof(*tmp_data_ptr);
+ 
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "Next SecurID passcode required for user %s", securid_user);
+ 
+ 		/* This indicates to to caller that we were successful thus
+ 		 * far, but still need additional preauth to consider success
+ 		 */
+ 		retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
+ 		break;
+ 	     case ACM_NEW_PIN_REQUIRED:
+ 	      {
+ 		char min_pin_len, max_pin_len, alpha_pin;
+ 
+ 		scp = (krb5_sam_challenge *)malloc (sizeof(krb5_sam_challenge));
+ 		if (!scp) {
+ 			retval = ENOMEM;
+ 			goto securid_cleanup;
+ 		}
+ 		scp->sam_type_name.length = 0;
+ 		if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS) &&
+ 		  (AceGetMinPinLen(sd_handle, &min_pin_len) == ACE_SUCCESS) &&
+ 		  (AceGetAlphanumeric(sd_handle, &alpha_pin) == ACE_SUCCESS) )
+ 		{
+ 		  sprintf(PIN_message, "New PIN must contain %d to %d %sdigits",
+ 			min_pin_len, max_pin_len,
+ 			(alpha_pin == 0) ? "" : "alphanumeric ");
+ 		  scp->sam_challenge_label.data = PIN_message;
+ 		  scp->sam_challenge_label.length =
+ 				strlen(scp->sam_challenge_label.data);
+ 		} else {
+ 		  scp->sam_challenge_label.length = 0;
+ 		}
+ 		scp->sam_challenge.length = 0;
+ 		scp->sam_response_prompt.data = NEW_PIN_message;
+ 		scp->sam_response_prompt.length =
+ 				strlen(scp->sam_response_prompt.data);
+ 		scp->sam_pk_for_sad.length = 0;
+ 		scp->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		scp->sam_nonce = 0;
+ 		scp->sam_cksum.contents = (char *)0;
+ 		scp->sam_cksum.length = 0;
+ 
+ 		memset(&s_track, 0, sizeof(s_track));
+ 		s_track.state = SECURID_STATE_NEW_PIN;
+ 		s_track.handle = htonl(sd_handle);
+  
+ 		tmp_data.data = (char *)&s_track;
+ 		tmp_data.length = sizeof(s_track);
+  
+ 		if (retval = encrypt_track_data(context, client, &tmp_data,
+ 			&scp->sam_track_id)) {
+ 		  if (scp) free(scp);
+ 		  break;
+ 		}
+ 
+ 		tmp_data_ptr = (krb5_data *)malloc(sizeof(*tmp_data_ptr));
+ 		if (!tmp_data_ptr) {
+ 		   if (scp) free(scp);
+ 		   retval = ENOMEM;
+ 		   break;
+ 		}
+ 		tmp_data_ptr->magic = KRB5_SAM_SECURID_NEXT_CHALLENGE_MAGIC;
+ 		tmp_data_ptr->length = sizeof(*scp);
+ 		tmp_data_ptr->data = (char *)scp;
+ 
+ 		/* Shove this data into the e_data pointer in the client's  */
+ 		/* DB entry.  It will get picked up by get_edata() later on */
+ 		if (client->e_data) {
+ 		  /* Generate warning that this user may lose e_data */
+ 		}
+ 		client->e_data = (krb5_octet *)tmp_data_ptr;
+ 		client->e_length = sizeof(*tmp_data_ptr);
+ 
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "New SecurID PIN required for user %s", securid_user);
+ 
+ 		/* This indicates to to caller that we were successful thus
+ 		 * far, but still need additional preauth to consider success
+ 		 */
+ 		retval = KRB5KDC_ERR_PREAUTH_REQUIRED;
+ 		break;
+ 	      }
+ 	  default:
+ 		com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 		   "AceServer: unknown error (%d) for user %s",
+ 		   retval, securid_user);
+ 		retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		break;
+ 	}
+     }
+ securid_cleanup:
+     if (client_key.contents)
+ 	krb5_free_keyblock_contents(context, &client_key);
+     if (user)
+ 	krb5_xfree(user);
+     if (securid_user)
+ 	krb5_xfree(securid_user);
+     if (scratch.data)
+ 	krb5_xfree(scratch.data);
+     if (esre) {
+       if (esre->sam_sad.data)
+ 	krb5_xfree(esre->sam_sad.data);
+       krb5_xfree(esre);
+     }
+     return(retval);
+ }
+ 
+ 
+ 
+ 
+ krb5_error_code
+ securid_make_sam_challenge_2_and_cksum (krb5_context context,
+ 		krb5_sam_challenge_2 *sc2, krb5_sam_challenge_2_body *sc2b,
+ 		krb5_keyblock *cksum_key) {
+   krb5_error_code retval;
+   krb5_checksum **cksum_array = NULL;
+   krb5_checksum *cksum = NULL;
+   krb5_cksumtype cksumtype;
+   krb5_data *encoded_challenge_body = NULL;
+ 
+   if (!cksum_key) return(KRB5_PREAUTH_NO_KEY);
+   if (!sc2 || !sc2b) return(KRB5KDC_ERR_PREAUTH_FAILED);
+ 
+   retval = encode_krb5_sam_challenge_2_body(sc2b, &encoded_challenge_body);
+   if (retval || !encoded_challenge_body) {
+ 	encoded_challenge_body = NULL;
+ 	goto cksum_cleanup;
+   }
+ 
+   cksum_array = calloc(2, sizeof(krb5_checksum *));
+   if (!cksum_array) {
+      retval = ENOMEM;
+      goto cksum_cleanup;
+   }
+ 
+   cksum = (krb5_checksum *)malloc(sizeof(krb5_checksum));
+   if (!cksum) {
+      retval = ENOMEM;
+      goto cksum_cleanup;
+   }
+ 
+   cksum_array[0] = cksum;
+   cksum_array[1] = NULL;
+ 
+   retval = sam_cksumtype(context, cksum_key->enctype, &cksumtype);
+   if (retval) goto cksum_cleanup;
+ 
+   retval = krb5_c_make_checksum(context, cksumtype,
+ 		cksum_key, KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
+ 		encoded_challenge_body, cksum);
+   if (retval) goto cksum_cleanup;
+ 
+   sc2->sam_cksum = cksum_array;
+   sc2->sam_challenge_2_body = *encoded_challenge_body;
+   return(0);
+ 
+ cksum_cleanup:
+   if (encoded_challenge_body) krb5_free_data(context, encoded_challenge_body);
+   if (cksum_array) krb5_xfree(cksum_array);
+   if (cksum) krb5_xfree(cksum);
+   return (retval);
+ }
+ 
+ 
+ krb5_error_code
+ securid_decrypt_track_data_2(krb5_context context, krb5_db_entry *client,
+                         krb5_data *enc_track_data, krb5_data *output) {
+     krb5_error_code retval;
+     krb5_db_entry *sam_db_entry;
+     krb5_keyblock sam_key;
+     krb5_enc_data tmp_enc_data;
+     int sam_type = PA_SAM_TYPE_SECURID;
+     
+     if (retval = sam_get_db_entry(context, &client->princ, &sam_type,
+ 			&sam_db_entry))
+ 	return(retval);
+ 
+     retval = sam_get_key(context, sam_db_entry, -1,
+                                         KRB5_KDB_SALTTYPE_NORMAL, &sam_key);
+     krb5_db_free_principal(context, sam_db_entry, 1);
+     if (retval)
+ 	return(retval);
+ 
+     tmp_enc_data.ciphertext = *enc_track_data;
+     tmp_enc_data.enctype = ENCTYPE_UNKNOWN;
+     tmp_enc_data.kvno = 0;
+ 
+     output->length = tmp_enc_data.ciphertext.length;
+     if (output->data)
+ 	free(output->data);
+     output->data = (krb5_octet *)malloc(output->length);
+ 
+     if (!output->data) {
+ 	krb5_free_keyblock_contents(context, &sam_key);
+ 	return(ENOMEM);
+     }
+ 
+     retval = krb5_c_decrypt(context, &sam_key,
+ 	KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, &tmp_enc_data, output);
+     krb5_free_keyblock_contents(context, &sam_key);
+ 
+     if (retval) {
+ 	output->data = NULL;
+ 	output->length = 0;
+ 	krb5_xfree(output->data);
+ 	return(retval);
+     }
+ 
+     return(0);
+ }
+ 
+ krb5_error_code
+ securid_encrypt_track_data_2(krb5_context context, krb5_db_entry *client,
+                         krb5_data *track_data, krb5_data *output) {
+     krb5_error_code retval;
+     krb5_db_entry *sam_db_entry;
+     krb5_keyblock sam_key;
+     krb5_enc_data tmp_enc_data;
+     int sam_type = PA_SAM_TYPE_SECURID;
+     
+     if (retval = sam_get_db_entry(context, &client->princ, &sam_type,
+ 			&sam_db_entry))
+ 	return(retval);
+ 
+     retval = sam_get_key(context, sam_db_entry, -1,
+                                         KRB5_KDB_SALTTYPE_NORMAL, &sam_key);
+     krb5_db_free_principal(context, sam_db_entry, 1);
+     if (retval)
+ 	return(retval);
+ 
+     if (retval = krb5_c_encrypt_length(context, sam_key.enctype,
+ 			track_data->length, &output->length)) {
+ 	krb5_free_keyblock_contents(context, &sam_key);
+ 	return(retval);
+     }
+ 
+     if (output->data) free(output->data);
+     output->data = (krb5_octet *)malloc(output->length);
+ 
+     if (!output->data) {
+ 	krb5_free_keyblock_contents(context, &sam_key);
+ 	return(ENOMEM);
+     }
+ 
+     tmp_enc_data.ciphertext = *output;
+     tmp_enc_data.enctype = sam_key.enctype;
+     tmp_enc_data.kvno = 0;
+ 
+     retval = krb5_c_encrypt(context, &sam_key,
+ 	KRB5_KEYUSAGE_PA_SAM_CHALLENGE_TRACKID, 0, track_data, &tmp_enc_data);
+     krb5_free_keyblock_contents(context, &sam_key);
+ 
+     if (retval) {
+ 	output->length = 0;
+ 	krb5_xfree(output->data);
+ 	output->data = NULL;
+ 	return(retval);
+     }
+     return(0);
+ }
+ 
+ krb5_error_code store_next_sam_challenge_2_in_tl_data(krb5_context context,
+ 			krb5_db_entry *client, krb5_sam_challenge_2 *sc2p) {
+    krb5_tl_data securid_tl_data;
+    krb5_error_code retval;
+ 
+    memset(&securid_tl_data, 0, sizeof(securid_tl_data));
+ 
+    /* This really isn't state information to keep in the DB, */
+    /* it's only the next challenge to be sent to the user    */
+    /* by the next call to securid_get_edata*.  This should   */
+    /* never get stored in database, although it won't really */
+    /* hurt anything if it is.                                */
+ 
+    securid_tl_data.tl_data_type = KRB5_TL_SECURID_STATE;
+    securid_tl_data.tl_data_length = sizeof(sc2p);
+    securid_tl_data.tl_data_contents =
+ 			(krb5_octet *)malloc(securid_tl_data.tl_data_length);
+    if (!securid_tl_data.tl_data_contents) return (ENOMEM);
+ 
+    memcpy(securid_tl_data.tl_data_contents, &sc2p, sizeof(sc2p));
+    retval = krb5_dbe_update_tl_data(context, client, &securid_tl_data);
+    return (retval);
+ }
+ 
+ 
+ krb5_error_code get_securid_edata_2(krb5_context context,
+ 				krb5_db_entry *client,
+ 				krb5_sam_challenge_2_body *sc2b,
+ 				krb5_sam_challenge_2 *sc2) {
+ 	krb5_error_code retval;
+ 	krb5_data scratch;
+ 	unsigned long nonce;
+ 	krb5_keyblock client_key;
+ 	krb5_tl_data securid_tl_data;
+ 	krb5_tl_data *tldp, *tmp_tldp;
+ 	krb5_sam_challenge_2 *tmp_sc2;
+ 	char *user = NULL;
+ 	char *def_user = "<unknown user>";
+ 
+ 	(void) krb5_unparse_name(context, client->princ, &user);
+ 
+ 	/* Look for a challenge in the client's tl_data.  One may have */
+ 	/* placed there by the verify routine that did not have	*/
+ 	/* sufficient data (next CODE or new PIN required) */
+ 
+ 	memset(&securid_tl_data, 0, sizeof(securid_tl_data));
+ 	securid_tl_data.tl_data_type = KRB5_TL_SECURID_STATE;
+ 	retval = krb5_dbe_lookup_tl_data(context, client, &securid_tl_data);
+ 
+ 	if (retval || (securid_tl_data.tl_data_length
+ 				!= sizeof(krb5_sam_challenge_2 *))) {
+ 	   /* No previous data (or cannot find any).  Create new challenge */
+ 	   /* that requests the user's SecurID passcode */
+ 
+ 	   sc2b->sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 	   sc2b->sam_type_name.length = 0;
+ 	   sc2b->sam_challenge_label.length = 0;
+ 	   sc2b->sam_challenge.length = 0;
+ 	   sc2b->sam_response_prompt.data = PASSCODE_message;
+ 	   sc2b->sam_response_prompt.length =
+ 			strlen(sc2b->sam_response_prompt.data);
+ 	   sc2b->sam_pk_for_sad.length = 0;
+ 
+ 	   scratch.data = (char *)&sc2b->sam_nonce;
+ 	   scratch.length = sizeof(sc2b->sam_nonce);
+ 	   retval = krb5_c_random_make_octets(kdc_context, &scratch);
+ 	   if (retval) {
+ 	     com_err("krb5kdc", retval,
+ 		"while generating nonce data in get_securid_edata_2 (%s)",
+ 		user ? user : def_user);
+ 	     if (user) krb5_xfree(user);
+ 	     return(retval);
+ 	   }
+ 	   sc2b->sam_track_id.length = 0;
+ 
+ 	   /* Get the client's key */
+ 	   if (retval = sam_get_key(context, client, -1, /* default enctype */
+ 		KRB5_KDB_SALTTYPE_NORMAL, &client_key)) {
+ 	     com_err("krb5kdc", retval,
+ 		"while getting SecurID SAM key in get_securid_edata_2 (%s)",
+ 		user ? user : def_user);
+ 	     if (user) krb5_xfree(user);
+ 	     return(retval);
+ 	   }
+ 	   sc2b->sam_etype = client_key.enctype;
+ 
+ 	   retval = securid_make_sam_challenge_2_and_cksum(context,
+ 			sc2, sc2b, &client_key);
+ 	   krb5_free_keyblock_contents(context, &client_key);
+ 
+ 	   if (retval) {
+ 	      com_err("krb5kdc", retval,
+ 		"while making SAM_CHALLENGE_2 checksum (%s)",
+ 		user ? user : def_user);
+ 	   }
+ 	} else {
+ 	   /* There is already a challenge that has been built by a call */
+ 	   /* to verify_securid_data*().  Use it and release the tl_data */
+ 	   /* resources in the client DB record				 */
+ 
+ 	   tmp_sc2 = *(krb5_sam_challenge_2 **) securid_tl_data.tl_data_contents;
+ 	   tldp = client->tl_data;
+ 	   if (client->tl_data->tl_data_type == KRB5_TL_SECURID_STATE) {
+ 	      client->tl_data = client->tl_data->tl_data_next;
+ 	      krb5_xfree(tldp->tl_data_contents);
+ 	      krb5_xfree(tldp);
+ 	   } else {
+ 	      while ((tldp->tl_data_next) &&
+ 		(tldp->tl_data_next->tl_data_type != KRB5_TL_SECURID_STATE))
+ 			tldp = tldp->tl_data_next;
+ 	      if (tldp->tl_data_next) {
+ 		 tmp_tldp = tldp->tl_data_next;
+ 		 tldp->tl_data_next = tldp->tl_data_next->tl_data_next;
+ 		 krb5_xfree(tmp_tldp->tl_data_contents);
+ 		 krb5_xfree(tmp_tldp);
+ 	      }
+ 	   }
+ 	   sc2->sam_challenge_2_body = tmp_sc2->sam_challenge_2_body;
+ 	   sc2->sam_cksum = tmp_sc2->sam_cksum;
+ 	   krb5_xfree(tmp_sc2);
+ 	   retval = 0;
+ 	}
+ 	if (user) krb5_xfree(user);
+ 	return(retval);
+ }
+ 
+ krb5_error_code verify_securid_data_2(context, client, sr2, enc_tkt_reply, pa)
+     krb5_context context;
+     krb5_db_entry *client;
+     krb5_sam_response_2 *sr2;
+     krb5_enc_tkt_part *enc_tkt_reply;
+     krb5_pa_data *pa;
+ {
+     krb5_error_code retval;
+     krb5_key_data *client_key_data = NULL;
+     krb5_keyblock client_key;
+     krb5_data scratch;
+     krb5_enc_sam_response_enc_2 *esre2 = NULL;
+     struct securid_track_data sid_track_data, *trackp = NULL;
+     krb5_data tmp_data;
+     SDI_HANDLE sd_handle = SDI_HANDLE_NONE;
+     krb5_tl_data securid_tl_data;
+     krb5_sam_challenge_2 *sc2p;
+     char *cp, *user = NULL;
+     char *securid_user = NULL;
+     char passcode[LENPRNST+1];
+     char max_pin_len, min_pin_len, alpha_pin;
+ 
+     memset(&client_key, 0, sizeof(client_key));
+     memset(&scratch, 0, sizeof(scratch));
+ 
+     if (retval = krb5_unparse_name(context, client->princ, &user)) {
+ 	com_err("krb5kdc", retval,
+ 		"while unparsing client name in verify_securid_data_2");
+ 	return(KRB5KDC_ERR_PREAUTH_FAILED);
+     }
+ 
+     if ((sr2->sam_enc_nonce_or_sad.ciphertext.data == NULL) ||
+ 	(sr2->sam_enc_nonce_or_sad.ciphertext.length <= 0)) {
+ 	  retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	  com_err("krb5kdc", retval,
+ 		"No preauth data supplied in verify_securid_data_2 (%s)", user);
+ 	  goto cleanup;
+     }
+ 
+     memset(&client_key, 0, sizeof(client_key));
+     retval = krb5_dbe_find_enctype(context, client,
+ 		sr2->sam_enc_nonce_or_sad.enctype, KRB5_KDB_SALTTYPE_NORMAL,
+ 		sr2->sam_enc_nonce_or_sad.kvno , &client_key_data);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while getting client key in verify_securid_data_2 (%s)", user);
+ 	goto cleanup;
+     }
+ 
+     if (retval = krb5_dbekd_decrypt_key_data(kdc_context, &master_keyblock,
+ 		client_key_data, &client_key, NULL)) {
+ 	com_err("krb5kdc", retval,
+ 		"while decrypting client key in verify_securid_data_2 (%s)",
+ 		user);
+ 	goto cleanup;
+     }
+     
+     scratch.length = sr2->sam_enc_nonce_or_sad.ciphertext.length;
+     scratch.data = (krb5_octet *)malloc(scratch.length);
+     if (!scratch.data) {
+ 	retval = ENOMEM;
+ 	com_err("krb5kdc", retval,
+ 		"while decrypting SAD in verify_securid_data_2 (%s)", user);
+ 	goto cleanup;
+     }
+     retval = krb5_c_decrypt(context, &client_key,
+ 		KRB5_KEYUSAGE_PA_SAM_RESPONSE, 0,
+ 		&sr2->sam_enc_nonce_or_sad, &scratch);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while decrypting SAD in verify_securid_data_2 (%s)", user);
+ 	goto cleanup;
+     }
+ 
+     retval = decode_krb5_enc_sam_response_enc_2(&scratch, &esre2);
+     if (retval) {
+ 	com_err("krb5kdc", retval,
+ 		"while decoding SAD in verify_securid_data_2 (%s)", user);
+ 	esre2 = NULL;
+ 	goto cleanup;
+     }
+ 
+     if (sr2->sam_nonce != esre2->sam_nonce) {
+ 	com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 		"while checking nonce in verify_securid_data_2 (%s)", user);
+ 	retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	goto cleanup;
+     }
+     
+     if ((esre2->sam_sad.length == 0) || (esre2->sam_sad.data == NULL)) {
+ 	com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 		"No SecurID passcode in verify_securid_data_2 (%s)", user);
+ 	retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	goto cleanup;
+     }
+ 
+     /* Copy out SAD to null-terminated buffer */
+     memset(passcode, 0, sizeof(passcode));
+     if (esre2->sam_sad.length > (sizeof(passcode) - 1)) {
+ 	retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 	com_err("krb5kdc", retval,
+ 		"SecurID passcode/PIN too long (%d bytes) in verify_securid_data_2 (%s)",
+ 		esre2->sam_sad.length, user);
+ 	goto cleanup;
+     }
+     memcpy(passcode, esre2->sam_sad.data, esre2->sam_sad.length);
+ 
+     securid_user = strdup(user);
+     if (!securid_user) {
+ 	com_err("krb5kdc", ENOMEM,
+ 		"while copying user name in verify_securid_data_2 (%s)", user);
+ 	goto cleanup;
+     }
+     if (cp = strchr(securid_user, '@'))
+     	*cp = (char)0;
+ 
+     /* Check for any track_id data that may have state from a previous	*/
+     /* attempt at SecurID authentication 				*/
+ 
+     if (sr2->sam_track_id.data && (sr2->sam_track_id.length > 0)) {
+ 	krb5_data track_id_data;
+ 	memset(&track_id_data, 0, sizeof(track_id_data));
+ 	retval = securid_decrypt_track_data_2(context, client,
+ 			&sr2->sam_track_id, &track_id_data);
+ 	if (retval) {
+ 	   com_err("krb5kdc", retval,
+ 	      "while decrypting SecurID trackID in verify_securid_data_2 (%s)",
+ 			user);
+ 	   goto cleanup;
+ 	}
+ 	trackp = (struct securid_track_data *)track_id_data.data;
+ 	switch(trackp->state) {
+ 	  case SECURID_STATE_NEW_PIN_AGAIN:
+ 		{
+ 		  int pin1_len, pin2_len;
+ 
+ 		  trackp->handle = ntohl(trackp->handle);
+ 		  pin2_len = strlen(passcode);
+ 		  pin1_len = strlen(trackp->passcode);
+ 
+ 		  if ((pin1_len != pin2_len) ||
+ 			(memcmp(passcode, trackp->passcode, pin1_len) != 0)) {
+ 		     retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		     krb5_klog_syslog(LOG_INFO,
+ 			"New SecurID PIN Failed for user %s: PIN mis-match",
+ 			user);
+ 		     break;
+ 		  }
+ 		  retval = SD_Pin(trackp->handle, passcode);
+ 		  SD_Close(trackp->handle);
+ 		  if (retval == ACM_NEW_PIN_ACCEPTED) {
+ 		     setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+ 		     setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		     krb5_klog_syslog(LOG_INFO,
+ 			"SecurID PIN Accepted for %s in verify_securid_data_2",
+ 			securid_user);
+ 		     retval = 0;
+ 		  } else {
+ 		     retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		     krb5_klog_syslog(LOG_INFO,
+ 			"SecurID PIN Failed for user %s (AceServer returns %d) in verify_securid_data_2",
+                         user, retval);
+ 		  }
+ 		  break;
+ 		}
+ 	  case SECURID_STATE_NEW_PIN: {
+ 		krb5_sam_challenge_2_body sc2b;
+ 
+ 		sc2p = (krb5_sam_challenge_2 *)
+ 			malloc(sizeof(krb5_sam_challenge_2));
+ 		if (!sc2p) {
+ 		   retval = ENOMEM;
+ 		   goto cleanup;
+ 		}
+ 		memset(sc2p, 0, sizeof(*sc2p));
+ 		memset(&sc2b, 0, sizeof(sc2b));
+ 		sc2b.sam_type = PA_SAM_TYPE_SECURID;
+ 		sc2b.sam_response_prompt.data = NEW_PIN_AGAIN_message;
+ 		sc2b.sam_response_prompt.length =
+ 				strlen(sc2b.sam_response_prompt.data);
+ 		sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		sc2b.sam_etype = client_key.enctype;
+ 
+ 		tmp_data.data = (char *)&sc2b.sam_nonce;
+ 		tmp_data.length = sizeof(sc2b.sam_nonce);
+ 		if (retval = krb5_c_random_make_octets(kdc_context, &tmp_data)){
+ 		  com_err("krb5kdc", retval,
+ 		  	"while making nonce for SecurID new PIN2 SAM_CHALLENGE_2 (%s)", user);
+ 		  goto cleanup;
+ 		}
+ 		sid_track_data.state = SECURID_STATE_NEW_PIN_AGAIN;
+ 		sid_track_data.handle = trackp->handle;
+ 		/* Should we complain if sizes don't work ??  */
+ 		memcpy(sid_track_data.passcode, passcode,
+ 			sizeof(sid_track_data.passcode));
+ 		tmp_data.data = (krb5_octet *)&sid_track_data;
+ 		tmp_data.length = sizeof(sid_track_data);
+ 		if (retval = securid_encrypt_track_data_2(context, client,
+ 			&tmp_data, &sc2b.sam_track_id)) {
+ 		   com_err("krb5kdc", retval,
+ 			"while encrypting NEW PIN2 SecurID track data for SAM_CHALLENGE_2 (%s)",
+ 			securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
+ 			&sc2b, &client_key);
+ 		if (retval) {
+ 		   com_err("krb5kdc", retval,
+ 		      "while making cksum for SAM_CHALLENGE_2 (new PIN2) (%s)",
+ 		      securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		if (retval = store_next_sam_challenge_2_in_tl_data(context,
+ 						client, sc2p)) {
+ 		   com_err("krb5kdc", retval,
+ 		     "while storing SAM_CHALLENGE_2 (new PIN2) in tl_data (%s)",
+ 		     securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "Requesting verification of new PIN for user %s",
+ 		   securid_user);
+ 		goto cleanup;
+ 	  }
+ 	  case SECURID_STATE_NEXT_CODE:
+ 		trackp->handle = ntohl(trackp->handle);
+ 		retval = SD_Next(trackp->handle, passcode);
+ 		SD_Close(trackp->handle);
+ 		if (retval == ACM_OK) {
+ 		   setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+ 		   setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		   krb5_klog_syslog(LOG_INFO,
+ 			"Next SecurID Code Accepted for user %s", securid_user);
+ 		   retval = 0;
+ 		} else {
+ 		   krb5_klog_syslog(LOG_INFO,
+ 			"Next SecurID Code Failed for user %s (AceServer returns %d) in verify_securid_data_2",
+ 			user, retval);
+ 		   retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		}
+ 		break;
+ 	}
+     } else {		/* No track data, this is first of N attempts */
+ 	if (retval = SD_Init(&sd_handle)) {
+ 	   com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 		"SD_Init() returns error %d in verify_securid_data_2 (%s)",
+ 			retval, securid_user);
+ 	   goto cleanup;	   
+ 	}
+ 	retval = SD_Check(sd_handle, passcode, securid_user);
+ 	switch (retval) {
+ 	   case ACM_OK:
+ 		SD_Close(sd_handle);
+ 		setflag(enc_tkt_reply->flags, TKT_FLG_HW_AUTH);
+ 		setflag(enc_tkt_reply->flags, TKT_FLG_PRE_AUTH);
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "SecurID passcode accepted for user %s", user);
+ 		retval = 0;
+ 		break;
+ 	   case ACM_ACCESS_DENIED:
+ 		SD_Close(sd_handle);
+ 		retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "AceServer returns Access Denied for user %s (SAM2)",user);
+ 		goto cleanup;
+ 	   case ACM_NEXT_CODE_REQUIRED: {
+ 		krb5_sam_challenge_2_body sc2b;
+ 
+ 		sc2p = (krb5_sam_challenge_2 *)
+ 			malloc(sizeof(krb5_sam_challenge_2));
+ 		if (!sc2p) {
+ 		   retval = ENOMEM;
+ 		   goto cleanup;
+ 		}
+ 		memset(sc2p, 0, sizeof(*sc2p));
+ 		memset(&sc2b, 0, sizeof(sc2b));
+ 
+ 		sc2b.sam_type = PA_SAM_TYPE_SECURID;
+ 		sc2b.sam_response_prompt.data = NEXT_PASSCODE_message;
+ 		sc2b.sam_response_prompt.length =
+ 				strlen(sc2b.sam_response_prompt.data);
+ 		sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		sc2b.sam_etype = client_key.enctype;
+ 
+ 		tmp_data.data = (char *)&sc2b.sam_nonce;
+ 		tmp_data.length = sizeof(sc2b.sam_nonce);
+ 		if (retval = krb5_c_random_make_octets(kdc_context, &tmp_data)){
+ 		   com_err("krb5kdc", retval,
+ 			"while making nonce for SecurID NEXT CODE SAM_CHALLENGE_2 (%s)", user);
+ 		   goto cleanup;
+ 		}
+ 		sid_track_data.state = SECURID_STATE_NEXT_CODE;
+ 		sid_track_data.handle = htonl(sd_handle);
+ 		tmp_data.data = (krb5_octet *)&sid_track_data;
+ 		tmp_data.length = sizeof(sid_track_data);
+ 		if (retval = securid_encrypt_track_data_2(context, client,
+ 			&tmp_data, &sc2b.sam_track_id)) {
+ 		   com_err("krb5kdc", retval,
+ 			"while encrypting NEXT CODE SecurID track data for SAM_CHALLENGE_2 (%s)",
+ 			securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
+ 			&sc2b, &client_key);
+ 		if (retval) {
+ 		   com_err("krb5kdc", retval,
+ 		      "while making cksum for SAM_CHALLENGE_2 (NEXT CODE) (%s)",
+ 		      securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		if (retval = store_next_sam_challenge_2_in_tl_data(context,
+ 						client, sc2p)) {
+ 		   com_err("krb5kdc", retval,
+ 		    "while storing SAM_CHALLENGE_2 (NEXT CODE) in tl_data (%s)",
+ 		    securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "Next SecurID passcode required for user %s", securid_user);
+ 		goto cleanup;
+ 	   }
+ 	   case ACM_NEW_PIN_REQUIRED: {
+ 		krb5_sam_challenge_2_body sc2b; 
+ 
+ 		sc2p = (krb5_sam_challenge_2 *)
+ 			malloc(sizeof(krb5_sam_challenge_2));
+ 		if (!sc2p) {
+ 		   retval = ENOMEM;
+ 		   goto cleanup;
+ 		}
+ 		memset(sc2p, 0, sizeof(*sc2p));
+ 		memset(&sc2b, 0, sizeof(sc2b));
+ 		if ((AceGetMaxPinLen(sd_handle, &max_pin_len) == ACE_SUCCESS)
+ 		 && (AceGetMinPinLen(sd_handle, &min_pin_len) == ACE_SUCCESS)
+ 		 && (AceGetAlphanumeric(sd_handle, &alpha_pin) == ACE_SUCCESS))
+ 		{
+ 		   sprintf(PIN_message,
+ 				"New PIN must contain %d to %d %sdigits",
+ 				min_pin_len, max_pin_len,
+ 				(alpha_pin == 0) ? "" : "alphanumeric ");
+ 		   sc2b.sam_challenge_label.data = PIN_message;
+ 		   sc2b.sam_challenge_label.length =
+ 				strlen(sc2b.sam_challenge_label.data);
+ 		} else {
+ 		   sc2b.sam_challenge_label.length = 0;
+ 		}
+ 		sc2b.sam_type = PA_SAM_TYPE_SECURID;
+ 		sc2b.sam_response_prompt.data = NEW_PIN_message;
+ 		sc2b.sam_response_prompt.length =
+ 				strlen(sc2b.sam_response_prompt.data);
+ 		sc2b.sam_flags = KRB5_SAM_SEND_ENCRYPTED_SAD;
+ 		sc2b.sam_etype = client_key.enctype;
+ 		tmp_data.data = (char *)&sc2b.sam_nonce;
+ 		tmp_data.length = sizeof(sc2b.sam_nonce);
+ 		if (retval = krb5_c_random_make_octets(kdc_context, &tmp_data)){
+ 		  com_err("krb5kdc", retval,
+ 		  	"while making nonce for SecurID new PIN SAM_CHALLENGE_2 (%s)", user);
+ 		  goto cleanup;
+ 		}
+ 		sid_track_data.state = SECURID_STATE_NEW_PIN;
+ 		sid_track_data.handle = htonl(sd_handle);
+ 		tmp_data.data = (krb5_octet *)&sid_track_data;
+ 		tmp_data.length = sizeof(sid_track_data);
+ 		if (retval = securid_encrypt_track_data_2(context, client,
+ 			&tmp_data, &sc2b.sam_track_id)) {
+ 		   com_err("krb5kdc", retval,
+ 			"while encrypting new PIN SecurID track data for SAM_CHALLENGE_2 (%s)",
+ 			securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		retval = securid_make_sam_challenge_2_and_cksum(context, sc2p,
+ 			&sc2b, &client_key);
+ 		if (retval) {
+ 		   com_err("krb5kdc", retval,
+ 			"while making cksum for SAM_CHALLENGE_2 (new PIN) (%s)",
+ 			securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		if (retval = store_next_sam_challenge_2_in_tl_data(context,
+ 						client, sc2p)) {
+ 		   com_err("krb5kdc", retval,
+ 		      "while storing SAM_CHALLENGE_2 (new PIN) in tl_data (%s)",
+ 		      securid_user);
+ 		   krb5_free_sam_challenge_2(context, sc2p);
+ 		   goto cleanup;
+ 		}
+ 		krb5_klog_syslog(LOG_INFO,
+ 		   "New SecurID PIN required for user %s", securid_user);
+ 		goto cleanup;
+ 	   }
+ 	   default:
+ 		com_err("krb5kdc", KRB5KDC_ERR_PREAUTH_FAILED,
+ 			"AceServer returns unknown error code %d in verify_securid_data_2\n", retval);
+ 		retval = KRB5KDC_ERR_PREAUTH_FAILED;
+ 		goto cleanup;
+ 	}
+     }	/* no track_id data */
+ 
+ cleanup:
+     if (client_key.contents) krb5_free_keyblock_contents(context, &client_key);
+     if (scratch.data) krb5_xfree(scratch.data);
+     if (esre2) krb5_free_enc_sam_response_enc_2(context, esre2);
+     if (user) krb5_xfree(user);
+     if (securid_user) krb5_xfree(securid_user);
+     if (trackp) krb5_xfree(trackp);
+     return(retval);
+ }
Index: krb5/krb524/.cvsignore
diff -c /dev/null krb5/krb524/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:19 2003
--- krb5/krb524/.cvsignore	Thu Jun  5 10:39:03 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/krb524/Makefile.in
diff -c krb5/krb524/Makefile.in:1.1.1.2 krb5/krb524/Makefile.in:1.3
*** krb5/krb524/Makefile.in:1.1.1.2	Fri Feb 22 16:33:51 2002
--- krb5/krb524/Makefile.in	Mon Feb 25 00:39:16 2002
***************
*** 37,47 ****
  
  LOCALINCLUDES= $(KRB4_INCLUDES) -I. -I$(srcdir)
  
  # Library sources
  SRCS	= conv_creds.c conv_princ.c cnv_tkt_skey.c \
  	encode.c misc.c globals.c sendmsg.c krb524_err.et
  STLIBOBJS = conv_creds.o conv_princ.o cnv_tkt_skey.o \
! 	encode.o misc.o globals.o sendmsg.o krb524_err.o
  
  GENS	= krb524_err.c krb524_err.h
  
--- 37,49 ----
  
  LOCALINCLUDES= $(KRB4_INCLUDES) -I. -I$(srcdir)
  
+ EXTRA_OBJS=@EXTRA_OBJS@
+ 
  # Library sources
  SRCS	= conv_creds.c conv_princ.c cnv_tkt_skey.c \
  	encode.c misc.c globals.c sendmsg.c krb524_err.et
  STLIBOBJS = conv_creds.o conv_princ.o cnv_tkt_skey.o \
! 	encode.o misc.o globals.o sendmsg.o krb524_err.o $(EXTRA_OBJS)
  
  GENS	= krb524_err.c krb524_err.h
  
Index: krb5/krb524/RELEASE_NOTES
diff -c krb5/krb524/RELEASE_NOTES:1.1.1.1 krb5/krb524/RELEASE_NOTES:removed
*** krb5/krb524/RELEASE_NOTES:1.1.1.1	Mon Jun  2 17:55:40 1997
--- krb5/krb524/RELEASE_NOTES	Sun Mar 16 20:22:19 2003
***************
*** 1,16 ****
- 
- Kerberos V5 to Kerberos V4 Credentials Converting Service, ALPHA RELEASE
- ========================================================================
- 
- This is the ALPHA RELEASE of krb524.  Treat it accordingly.
- 
- Soon, krb524 will be integrated into the standard MIT Kerberos 5
- distribution.  krb524's existence as a distinct distribution is
- temporary.
- 
- If you have any questions, contact
- 
- Barry Jaspan, bjaspan@cam.ov.com
- OpenVision Technologies, Inc.
- (617) 374-2225
- 
--- 0 ----
Index: krb5/krb524/configure.in
diff -c krb5/krb524/configure.in:1.1.1.2 krb5/krb524/configure.in:1.5
*** krb5/krb524/configure.in:1.1.1.2	Fri Feb 22 16:33:52 2002
--- krb5/krb524/configure.in	Mon Feb 25 22:29:00 2002
***************
*** 4,11 ****
--- 4,29 ----
  KRB5_BUILD_LIBRARY_STATIC
  KRB5_BUILD_LIBOBJS
  AC_PROG_AWK
+ dnl
+ dnl --with-afs-name-change enables code that supports the case where
+ dnl the name of the realm (cell) changed when going from AFS to Kerberos 5
+ dnl
+ AC_ARG_WITH([afs-name-change],
+ [  --with-afs-name-change	Support an AFS cell with a different name],
+ if test "$withval" = yes; then
+ 	AC_DEFINE(KRB524_DO_AFS_CONV)
+ fi)
+ dnl
+ AC_ARG_WITH([krb524-remapping],
+ [  --with-krb524-remapping	Support mapping foreign realm users to local realm users],
+ if test "$withval" = yes; then
+ 	AC_DEFINE(KRB524_DO_REMAPPING)
+ 	EXTRA_OBJS=remap.o
+ fi)
+ dnl
  AC_CHECK_HEADERS(sys/select.h) dnl
  AC_TYPE_SIGNAL
+ AC_SUBST(EXTRA_OBJS)
  
  KRB5_BUILD_PROGRAM
  V5_AC_OUTPUT_MAKEFILE
Index: krb5/krb524/conv_creds.c
diff -c krb5/krb524/conv_creds.c:1.1.1.4 krb5/krb524/conv_creds.c:1.5
*** krb5/krb524/conv_creds.c:1.1.1.4	Wed Sep 25 15:06:21 2002
--- krb5/krb524/conv_creds.c	Wed Sep 25 15:18:31 2002
***************
*** 181,194 ****
       /* XXX perhaps we should use the addr of the client host if */
       /* v5creds contains more than one addr.  Q: Does V4 support */
       /* non-INET addresses? */
!      if (!v5creds->addresses || !v5creds->addresses[0] ||
! 	 v5creds->addresses[0]->addrtype != ADDRTYPE_INET ||
! 	 v5creds->addresses[0]->length != sizeof(addr)) {
  	  if (krb524_debug)
  	       fprintf(stderr, "Invalid v5creds address information.\n");
  	  return KRB524_BADADDR;
       } else
! 	  memcpy((char *) &addr, v5creds->addresses[0]->contents,
  		 sizeof(addr));
  #endif
       return 0;
--- 181,195 ----
       /* XXX perhaps we should use the addr of the client host if */
       /* v5creds contains more than one addr.  Q: Does V4 support */
       /* non-INET addresses? */
!      if (v5creds->addresses && v5creds->addresses[0] &&
! 	 (v5creds->addresses[0]->addrtype != ADDRTYPE_INET ||
! 	  v5creds->addresses[0]->length != sizeof(addr))) {
  	  if (krb524_debug)
  	       fprintf(stderr, "Invalid v5creds address information.\n");
  	  return KRB524_BADADDR;
       } else
! 	  if (v5creds->addresses && v5creds->addresses[0])
! 	      memcpy((char *) &addr, v5creds->addresses[0]->contents,
  		 sizeof(addr));
  #endif
       return 0;
Index: krb5/krb524/conv_princ.c
diff -c krb5/krb524/conv_princ.c:1.1.1.3 krb5/krb524/conv_princ.c:1.5
*** krb5/krb524/conv_princ.c:1.1.1.3	Mon Aug 12 15:44:36 2002
--- krb5/krb524/conv_princ.c	Mon Aug 12 15:58:32 2002
***************
*** 26,31 ****
--- 26,35 ----
  #include <sys/time.h>
  #include <sys/signal.h>
  #include <netinet/in.h>
+ #ifdef KRB524_DO_AFS_CONV
+ #include <ctype.h>
+ #endif
+ 
  #if TARGET_OS_MAC
  #include <Kerberos/krb.h>
  #include <Kerberos/krb524.h>
***************
*** 42,51 ****
  {
       char dummy[REALM_SZ];
       int ret;
       
       if ((ret = krb5_524_conv_principal(context, client, pname, pinst, 
  					prealm)))
  	  return ret;
       
!      return krb5_524_conv_principal(context, server, sname, sinst, dummy);
  }
--- 46,116 ----
  {
       char dummy[REALM_SZ];
       int ret;
+ 
+ #ifdef KRB524_DO_REMAPPING
+ #ifndef KRB524_AFS_SERVICE_NAME
+ #define KRB524_AFS_SERVICE_NAME		"afs"
+ #endif
+ 
+      krb5_principal new_client;
+ 
+      /*
+       * We ONLY do principal remapping for the AFS service.  Remap based
+       * on the V5 principal, since that's more digestable (to me, at least).
+       * And _ONLY_ remap foreign principals!
+       */
+ 
+      if (strncmp(KRB524_AFS_SERVICE_NAME,
+ 		  krb5_princ_name(context, server)[0].data,
+ 		  krb5_princ_name(context, server)[0].length) == 0 &&
+ 	 krb5_realm_compare(context, client, server) == FALSE &&
+ 	 remap_principal(context, client, &new_client) == 0) {
+ 
+ 	  if ((ret = krb5_524_conv_principal(context, new_client, pname,
+ 					     pinst, prealm))) {
+ 	       krb5_free_principal(context, new_client);
+ 	       return ret;
+ 	  }
+ 	  krb5_free_principal(context, new_client);
+      } else
+ 
+ #endif /* KRB524_DO_REMAPPING */
       
       if ((ret = krb5_524_conv_principal(context, client, pname, pinst, 
  					prealm)))
  	  return ret;
       
!      if ((ret = krb5_524_conv_principal(context, server, sname, sinst,
! 					dummy)))
! 	  return ret;
! 
! #ifdef KRB524_DO_AFS_CONV
! 
! #ifndef KRB524_AFS_SERVICE_NAME
! #define KRB524_AFS_SERVICE_NAME		"afs"
! #endif
! 
!     /*
!      * If this request is for an afs ticket (service == KRB524_AFS_CONV)
!      * and had a non-null instance (which is assumed to be
!      * the afs cell name), and the REALMs on the user and service
!      * match, then we want to change the user's realm to be the
!      * afs cell name.
!      */
! 
!     if ((strcmp(sname, KRB524_AFS_SERVICE_NAME) == 0) &&
! 	(sinst && sinst[0]) &&
! 	(strcmp(dummy, prealm) == 0)) {
! 	
! 	char *c;
! 
! 	strncpy(prealm, sinst, REALM_SZ);
! 	prealm[REALM_SZ - 1] = NULL;	/* Just to be sure... */
! 
! 	for (c = prealm; *c != NULL; c++)
! 	    *c = (char) toupper((int) *c);
!     }
! #endif /* KRB524_DO_AFS_CONV */
! 
!     return ret;
  }
Index: krb5/krb524/krb524.h
diff -c krb5/krb524/krb524.h:1.1.1.4 krb5/krb524/krb524.h:1.5
*** krb5/krb524/krb524.h:1.1.1.4	Wed Sep 25 15:06:21 2002
--- krb5/krb524/krb524.h	Wed Sep 25 15:18:31 2002
***************
*** 122,125 ****
--- 122,138 ----
  
  KRB524INT_END_DECLS
  
+ #ifdef KRB524_DO_REMAPPING
+ 
+ /* remap.c */
+ 
+ int init_remap
+ 	KRB5_PROTOTYPE((krb5_context context, char *file));
+ 
+ int remap_principal
+ 	KRB5_PROTOTYPE((krb5_context context, krb5_principal input,
+ 			krb5_principal *output));
+ 
+ #endif /* KRB524_DO_REMAPPING */
+ 
  #endif /* __KRB524_H__ */
Index: krb5/krb524/krb524d.c
diff -c krb5/krb524/krb524d.c:1.1.1.3 krb5/krb524/krb524d.c:1.6
*** krb5/krb524/krb524d.c:1.1.1.3	Wed Sep 25 15:06:21 2002
--- krb5/krb524/krb524d.c	Wed Sep 25 15:18:31 2002
***************
*** 60,66 ****
  #include <krb.h>
  #include "krb524.h"
  
- #define TIMEOUT 60
  #define TKT_BUFSIZ 2048
  #define MSGSIZE 8192
  
--- 60,65 ----
***************
*** 70,75 ****
--- 69,78 ----
  void *handle;
  
  int use_keytab, use_master;
+ #ifdef KRB524_DO_REMAPPING
+ int use_remap_file = 0;
+ char *remap_file = NULL;
+ #endif /* KRB524_DO_REMAPPING */
  char *keytab = NULL;
  krb5_keytab kt;
  
***************
*** 86,92 ****
  void usage(context)
       krb5_context context;
  {
!      fprintf(stderr, "Usage: %s [-k[eytab]] [-m[aster] [-r realm]] [-nofork]\n", whoami);
       cleanup_and_exit(1, context);
  }
  
--- 89,99 ----
  void usage(context)
       krb5_context context;
  {
! #ifdef KRB524_DO_REMAPPING
!      fprintf(stderr, "Usage: %s [-m[aster]] [-k[eytab]] [-f map_config_file] [-r realm] [-nofork]\n", whoami);
! #else /* KRB524_DO_REMAPPING */
!      fprintf(stderr, "Usage: %s [-m[aster]] [-k[eytab]] [-r realm] [-nofork]\n", whoami);
! #endif /* KRB524_DO_REMAPPING */
       cleanup_and_exit(1, context);
  }
  
***************
*** 115,124 ****
       struct servent *serv;
       struct sockaddr_in saddr;
       struct timeval timeout;
!      int ret, s, nofork;
!      fd_set rfds;
       krb5_context context;
       krb5_error_code retval;
       kadm5_config_params config_params;
  
       retval = krb5_init_context(&context);
--- 122,134 ----
       struct servent *serv;
       struct sockaddr_in saddr;
       struct timeval timeout;
!      int ret, s, i, numfds, maxfd, nofork;
!      fd_set rfds, select_fds;
       krb5_context context;
       krb5_error_code retval;
+      int *addr_fds = NULL;
+      krb5_address **localaddrs;
+      const int on = 1;
       kadm5_config_params config_params;
  
       retval = krb5_init_context(&context);
***************
*** 138,143 ****
--- 148,162 ----
  	       use_keytab = 1;
  	  else if (strncmp(*argv, "-m", 2) == 0)
  	       use_master = 1;
+ #ifdef KRB524_DO_REMAPPING
+ 	  else if (strncmp(*argv, "-f", 2) == 0) {
+ 	       use_remap_file = 1;
+ 	       if (!argc)
+ 		   usage(context);
+ 	       argv++; argc--;
+ 	       remap_file = *argv;
+ 	  }
+ #endif /* KRB524_DO_REMAPPING */
  	  else if (strcmp(*argv, "-nofork") == 0)
  	       nofork = 1;
  	  else if (strcmp(*argv, "-r") == 0) {
***************
*** 164,170 ****
       if (use_keytab)
  	  init_keytab(context);
       if (use_master)
! 	  init_master(context, &config_params);
  
       memset((char *) &saddr, 0, sizeof(struct sockaddr_in));
       saddr.sin_family = AF_INET;
--- 183,200 ----
       if (use_keytab)
  	  init_keytab(context);
       if (use_master)
! 	  init_master(context, NULL);
! 
! #ifdef KRB524_DO_REMAPPING
!      if (use_remap_file)
! 	  init_remap(context, remap_file);
! #endif /* KRB524_DO_REMAPPING */
! 
!      /*
!       * We need to bind to all of interface addresses, in addition to
!       * wildcard address, so we can reply to messages using the correct
!       * source address
!       */
  
       memset((char *) &saddr, 0, sizeof(struct sockaddr_in));
       saddr.sin_family = AF_INET;
***************
*** 180,223 ****
  	  com_err(whoami, errno, "creating main socket");
  	  cleanup_and_exit(1, context);
       }
       if ((ret = bind(s, (struct sockaddr *) &saddr,
  		     sizeof(struct sockaddr_in))) < 0) {
  	  com_err(whoami, errno, "binding main socket");
  	  cleanup_and_exit(1, context);
       }
       if (!nofork && daemon(0, 0)) {
  	  com_err(whoami, errno, "while detaching from tty");
  	  cleanup_and_exit(1, context);
       }
       
       while (1) {
! 	  FD_ZERO(&rfds);
! 	  FD_SET(s, &rfds);
! 	  timeout.tv_sec = TIMEOUT;
! 	  timeout.tv_usec = 0;
  
! 	  ret = select(s+1, &rfds, NULL, NULL, &timeout);
  	  if (signalled)
  	       cleanup_and_exit(0, context);
! 	  else if (ret == 0) {
! 	       if (use_master) {
! 		    ret = kadm5_flush(handle);
! 		    if (ret && ret != KRB5_KDB_DBNOTINITED) {
! 			 com_err(whoami, ret, "closing kerberos database");
! 			 cleanup_and_exit(1, context);
! 		    }
! 	       }
! 	  } else if (ret < 0 && errno != EINTR) {
  	       com_err(whoami, errno, "in select");
  	       cleanup_and_exit(1, context);
! 	  } else if (FD_ISSET(s, &rfds)) {
! 	       if (debug)
! 		    printf("received packet\n");
! 	       if ((ret = do_connection(s, context))) {
! 		    com_err(whoami, ret, "handling packet");
  	       }
! 	  } else
! 	       com_err(whoami, 0, "impossible situation occurred!");
       }
  
       cleanup_and_exit(0, context);
--- 210,305 ----
  	  com_err(whoami, errno, "creating main socket");
  	  cleanup_and_exit(1, context);
       }
+ 
+      /*
+       * Set SO_REUSEADDR so that we can bind to the non-wildcard addresses
+       * later
+       */
+ 
+      if ((ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
+ 			   sizeof(on))) < 0) {
+ 	  com_err(whoami, errno, "setting SO_REUSEADDR on main socket");
+      }
+ 
       if ((ret = bind(s, (struct sockaddr *) &saddr,
  		     sizeof(struct sockaddr_in))) < 0) {
  	  com_err(whoami, errno, "binding main socket");
  	  cleanup_and_exit(1, context);
       }
+ 
+      numfds = 1;
+      addr_fds = (int *) malloc(sizeof(int));
+      addr_fds[0] = s;
+      maxfd = s + 1;
+      FD_ZERO(&select_fds);
+      FD_SET(s, &select_fds);
+ 
+      /*
+       * Now lets go through and bind a socket to each interface
+       */
+ 
+      if ((ret = krb5_os_localaddr(context, &localaddrs)) != 0) {
+ 	  com_err(whoami, ret, "getting local addresses");
+ 	  cleanup_and_exit(1, context);
+      }
+ 
+      for (i = 0; localaddrs[i] != NULL; i++) {
+ 	  if (localaddrs[i]->addrtype == ADDRTYPE_INET) {
+ 	       memcpy((char *) &saddr.sin_addr, localaddrs[i]->contents,
+ 		      localaddrs[i]->length);
+ 	       if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ 		    com_err(whoami, errno, "creating interface socket");
+ 		    cleanup_and_exit(1, context);
+ 	       }
+ 	       if ((ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &on,
+ 				     sizeof(on))) < 0) {
+ 		    com_err(whoami, errno, "setting SO_REUSEADDR on interface socket");
+ 	       }
+ 	       if ((ret = bind(s, (struct sockaddr *) &saddr,
+ 			       sizeof(struct sockaddr))) < 0) {
+ 		    com_err(whoami, errno, "binding on interface socket");
+ 		    cleanup_and_exit(1, context);
+ 	       }
+ 	       numfds++;
+ 	       addr_fds = (int *) realloc(addr_fds, numfds * sizeof(int));
+ 	       if (addr_fds == NULL) {
+ 		    com_err(whoami, ENOMEM, "allocating descriptor memory");
+ 		    cleanup_and_exit(1, context);
+ 	       }
+ 	       addr_fds[numfds - 1] = s;
+ 	       FD_SET(s, &select_fds);
+ 	       if (s + 1 > maxfd)
+ 		    maxfd = s + 1;
+ 	  }
+      }
+ 
+      krb5_free_addresses(context, localaddrs);
+ 
       if (!nofork && daemon(0, 0)) {
  	  com_err(whoami, errno, "while detaching from tty");
  	  cleanup_and_exit(1, context);
       }
       
       while (1) {
! 	  rfds = select_fds;
  
! 	  ret = select(maxfd, &rfds, NULL, NULL, NULL);
  	  if (signalled)
  	       cleanup_and_exit(0, context);
! 	  else if (ret < 0 && errno != EINTR) {
  	       com_err(whoami, errno, "in select");
  	       cleanup_and_exit(1, context);
! 	  } else if (ret > 0) {
! 	       for (i = 0; i < numfds; i++) {
! 		    if (FD_ISSET(addr_fds[i], &rfds)) {
! 			 if (debug)
! 			      printf("received packet\n");
! 			 if ((ret = do_connection(addr_fds[i], context))) {
! 			      com_err(whoami, ret, "handling packet");
! 			 }
! 		    }
  	       }
! 	  }
       }
  
       cleanup_and_exit(0, context);
Index: krb5/krb524/remap.c
diff -c /dev/null krb5/krb524/remap.c:1.1
*** /dev/null	Sun Mar 16 20:22:20 2003
--- krb5/krb524/remap.c	Mon Sep 14 14:36:49 1998
***************
*** 0 ****
--- 1,98 ----
+ /*
+  * Kerberos 5-2-4 remapping code
+  *
+  * This code implements a special principal "remapping" function.
+  * This motivation for this is as follows:
+  *
+  * When doing cross-realm authentication with AFS, the PTS id for
+  * foreign realm users ends up not matching the Unix userid.  This
+  * subtly breaks a number of things.
+  *
+  * This remapping changes a V4 principal from a principal in a foreign
+  * realm to one in a local realm, based on a set of mapping criteria.
+  * Note that we only do this when getting service tickets for AFS.
+  *
+  * The security implications here are nasty; be careful.
+  */
+ 
+ #include "krb5.h"
+ 
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <ctype.h>
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+ #include <sys/signal.h>
+ #include <netinet/in.h>
+ 
+ #include <krb.h>
+ #include "krb524.h"
+ #include "k5-int.h"
+ 
+ static int remap_initialized = 0;
+ static profile_t remap_profile;
+ 
+ /*
+  * Initialize the remapping library
+  */
+ 
+ int init_remap(context, file)
+ 	krb5_context context;
+ 	char *file;
+ {
+ 	krb5_error_code code;
+ 
+ 	if (remap_initialized)
+ 		return 0;
+ 
+ 	/*
+ 	 * Because I'm lazy, I decided to use the already-existing
+ 	 * Kerberos profile routines, even though it's perhaps not the
+ 	 * best file format.
+ 	 */
+ 
+ 	code = profile_init_path(file, &remap_profile);
+ 
+ 	if (code)
+ 		return code;
+ 	
+ 	remap_initialized = 1;
+ 	return 0;
+ }
+ 
+ int remap_principal(context, input, output)
+ 	krb5_context context;
+ 	krb5_principal input;
+ 	krb5_principal *output;
+ {
+ 	krb5_error_code code;
+ 	char *inprinc;
+ 	char *newname;
+ 
+ 	if (! remap_initialized)
+ 		return 1;
+ 	
+ 	/*
+ 	 * First off, check to see if we've can remap this principal
+ 	 * via the user-specific rules
+ 	 */
+ 
+ 	if ((code = krb5_unparse_name(context, input, &inprinc)))
+ 		return code;
+ 
+ 	code = profile_get_string(remap_profile, "users", inprinc, NULL,
+ 				  NULL, &newname);
+ 
+ 	if (code == 0 && newname != NULL) {
+ 		if ((code = krb5_parse_name(context, newname, output)) == 0) {
+ 			krb5_xfree(newname);
+ 			return 0;
+ 		}
+ 		krb5_xfree(newname);
+ 	}
+ 
+ 	return 1;
+ 
+ }
Index: krb5/lib/.cvsignore
diff -c /dev/null krb5/lib/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:20 2003
--- krb5/lib/.cvsignore	Thu Jun  5 10:39:04 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/configure.in
diff -c krb5/lib/configure.in:1.1.1.1 krb5/lib/configure.in:removed
*** krb5/lib/configure.in:1.1.1.1	Mon Jun  2 17:55:43 1997
--- krb5/lib/configure.in	Sun Mar 16 20:22:20 2003
***************
*** 1,14 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- if test $krb5_cv_build_krb4_libs = yes ; then
- 	AC_MSG_RESULT(building Kerberos 4 libraries)
- 	krb4=krb4
- else
- 	AC_MSG_RESULT(skipping Kerberos 4 libraries)
- 	krb4=
- fi
- CONFIG_DIRS(crypto krb5 des425 $krb4 krb5util kdb gssapi rpc kadm5)
- AC_PROG_ARCHIVE
- AC_PROG_RANLIB
- DO_SUBDIRS
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/gssapi.def
diff -c krb5/lib/gssapi.def:1.1.1.1 krb5/lib/gssapi.def:removed
*** krb5/lib/gssapi.def:1.1.1.1	Mon Jun  2 17:55:43 1997
--- krb5/lib/gssapi.def	Sun Mar 16 20:22:20 2003
***************
*** 1,72 ****
- ;----------------------------------------------------
- ;   GSSAPI.DEF - GSSAPI.DLL module definition file
- ;----------------------------------------------------
- 
- LIBRARY		GSSAPI
- DESCRIPTION	'Base Generic Security Service API'
- EXETYPE		WINDOWS
- CODE		PRELOAD MOVEABLE DISCARDABLE
- DATA		PRELOAD MOVEABLE SINGLE
- HEAPSIZE	8192
- 
- EXPORTS
- 	WEP					@1001 RESIDENTNAME
- 	LIBMAIN					@1002
- 	GSS_ACQUIRE_CRED			@1
- 	GSS_RELEASE_CRED			@2
- 	GSS_INIT_SEC_CONTEXT			@3
- 	GSS_ACCEPT_SEC_CONTEXT			@4
- 	GSS_PROCESS_CONTEXT_TOKEN		@5
- 	GSS_DELETE_SEC_CONTEXT			@6
- 	GSS_CONTEXT_TIME			@7
- 	GSS_SIGN				@8
- 	GSS_VERIFY				@9
- 	GSS_SEAL				@10
- 	GSS_UNSEAL				@11
- 	GSS_DISPLAY_STATUS			@12
- 	GSS_INDICATE_MECHS			@13
- 	GSS_COMPARE_NAME			@14
- 	GSS_DISPLAY_NAME			@15
- 	GSS_IMPORT_NAME				@16
- 	GSS_RELEASE_NAME			@17
- 	GSS_RELEASE_BUFFER			@18
- 	GSS_RELEASE_OID_SET			@19
- 	GSS_INQUIRE_CRED			@20
- 
- ; GSS-API v2  additional credential calls
- ;
- ; XXX we need to add the numbers to this!
- ;
- 	GSS_ADD_CRED
- 	GSS_INQUIRE_CRED_BY_MECH
- 
- ; GSS-API v2  additional context-level calls
- ;
- 	GSS_INQUIRE_CONTEXT
- 	GSS_WRAP_SIZE_LIMIT
- 	GSS_EXPORT_SEC_CONTEXT
- 	GSS_IMPORT_SEC_CONTEXT
- 
- ; GSS-API v2  additional calls for OID and OID_set operations
- ;
- 	GSS_RELEASE_OID
- 	GSS_CREATE_EMPTY_OID_SET
- 	GSS_ADD_OID_SET_MEMBER
- 	GSS_TEST_OID_SET_MEMBER
- 	GSS_OID_TO_STR
- 	GSS_STR_TO_OID
- 
- ; GSS-API v2  renamed message protection calls
- ;
- 	GSS_WRAP
- 	GSS_UNWRAP
- 	GSS_GET_MIC
- 	GSS_VERIFY_MIC
- 
- ; GSS-API v2  future extensions
- ;
- 	GSS_INQUIRE_NAMES_FOR_MECH
- ;	GSS_INQUIRE_MECHS_FOR_NAME
- ;	GSS_CANONICALIZE_NAME
- ;	GSS_EXPORT_NAME
- 
--- 0 ----
Index: krb5/lib/krb5_16.def
diff -c krb5/lib/krb5_16.def:1.1.1.2 krb5/lib/krb5_16.def:removed
*** krb5/lib/krb5_16.def:1.1.1.2	Mon Jun  2 23:31:10 1997
--- krb5/lib/krb5_16.def	Sun Mar 16 20:22:20 2003
***************
*** 1,65 ****
- ;----------------------------------------------------
- ;   KRB5_16.DEF - KRB5_16.DLL module definition file
- ;----------------------------------------------------
- 
- LIBRARY   	KRB5_16
- DESCRIPTION 	'DLL for Kerberos 5'
- EXETYPE   	WINDOWS
- CODE      	PRELOAD MOVEABLE DISCARDABLE
- DATA      	PRELOAD MOVEABLE SINGLE
- HEAPSIZE  	8192
- 
- EXPORTS
- 	WEP                                     @1001 RESIDENTNAME
- 	LIBMAIN                         	@1002
- 	GSS_ACQUIRE_CRED			@1
- 	GSS_RELEASE_CRED			@2
- 	GSS_INIT_SEC_CONTEXT			@3
- 	GSS_ACCEPT_SEC_CONTEXT			@4
- 	GSS_PROCESS_CONTEXT_TOKEN		@5
- 	GSS_DELETE_SEC_CONTEXT			@6
- 	GSS_CONTEXT_TIME			@7
- 	GSS_SIGN				@8
- 	GSS_VERIFY				@9
- 	GSS_SEAL				@10
- 	GSS_UNSEAL				@11
- 	GSS_DISPLAY_STATUS			@12
- 	GSS_INDICATE_MECHS			@13
- 	GSS_COMPARE_NAME			@14
- 	GSS_DISPLAY_NAME			@15
- 	GSS_IMPORT_NAME				@16
- 	GSS_RELEASE_NAME			@17
- 	GSS_RELEASE_BUFFER			@18
- 	GSS_RELEASE_OID_SET			@19
- 	GSS_INQUIRE_CRED			@20
- ; Kerberos 5
- 	_krb5_build_principal_ext
- 	KRB5_CC_DEFAULT
- 	KRB5_FREE_ADDRESSES
- 	KRB5_FREE_AP_REP_ENC_PART
- 	KRB5_FREE_CRED_CONTENTS
- 	KRB5_FREE_CREDS
- 	KRB5_FREE_PRINCIPAL
- 	KRB5_GET_CREDENTIALS
- 	KRB5_GET_DEFAULT_REALM
- 	KRB5_GET_IN_TKT_WITH_PASSWORD
- 	KRB5_GET_NOTIFICATION_MESSAGE
- 	KRB5_INIT_CONTEXT
- 	KRB5_INIT_ETS
- 	KRB5_MK_REQ_EXTENDED
- 	KRB5_OS_LOCALADDR
- 	KRB5_PARSE_NAME
- 	KRB5_RD_REP
- 	KRB5_SNAME_TO_PRINCIPAL
- 	KRB5_TIMEOFDAY
- 	KRB5_US_TIMEOFDAY
- 	KRB5_UNPARSE_NAME
- ;Kadm routines
- 	KRB5_ADM_CONNECT
- 	KRB5_ADM_DISCONNECT
- 	KRB5_FREE_ADM_DATA
- 	KRB5_READ_ADM_REPLY
- 	KRB5_SEND_ADM_CMD
- ;Com_err routines
-         _com_err
-         ERROR_MESSAGE
--- 0 ----
Index: krb5/lib/sapkrb5.def
diff -c krb5/lib/sapkrb5.def:1.1.1.1 krb5/lib/sapkrb5.def:removed
*** krb5/lib/sapkrb5.def:1.1.1.1	Mon Jun  2 17:55:44 1997
--- krb5/lib/sapkrb5.def	Sun Mar 16 20:22:20 2003
***************
*** 1,72 ****
- ;----------------------------------------------------
- ;   GSSAPI.DEF - GSSAPI.DLL module definition file
- ;----------------------------------------------------
- 
- LIBRARY		SAPKRB5
- DESCRIPTION	'Base Generic Security Service API for SAP R/3'
- EXETYPE		WINDOWS
- CODE		PRELOAD MOVEABLE DISCARDABLE
- DATA		PRELOAD MOVEABLE SINGLE
- HEAPSIZE	8192
- 
- EXPORTS
- 	WEP					@1001 RESIDENTNAME
- 	LIBMAIN					@1002
- 	GSS_ACQUIRE_CRED			@1
- 	GSS_RELEASE_CRED			@2
- 	GSS_INIT_SEC_CONTEXT			@3
- 	GSS_ACCEPT_SEC_CONTEXT			@4
- 	GSS_PROCESS_CONTEXT_TOKEN		@5
- 	GSS_DELETE_SEC_CONTEXT			@6
- 	GSS_CONTEXT_TIME			@7
- 	GSS_SIGN				@8
- 	GSS_VERIFY				@9
- 	GSS_SEAL				@10
- 	GSS_UNSEAL				@11
- 	GSS_DISPLAY_STATUS			@12
- 	GSS_INDICATE_MECHS			@13
- 	GSS_COMPARE_NAME			@14
- 	GSS_DISPLAY_NAME			@15
- 	GSS_IMPORT_NAME				@16
- 	GSS_RELEASE_NAME			@17
- 	GSS_RELEASE_BUFFER			@18
- 	GSS_RELEASE_OID_SET			@19
- 	GSS_INQUIRE_CRED			@20
- 
- ; GSS-API v2  additional credential calls
- ;
- ; XXX we need to add the numbers to this!
- ;
- 	GSS_ADD_CRED
- 	GSS_INQUIRE_CRED_BY_MECH
- 
- ; GSS-API v2  additional context-level calls
- ;
- 	GSS_INQUIRE_CONTEXT
- 	GSS_WRAP_SIZE_LIMIT
- 	GSS_EXPORT_SEC_CONTEXT
- 	GSS_IMPORT_SEC_CONTEXT
- 
- ; GSS-API v2  additional calls for OID and OID_set operations
- ;
- 	GSS_RELEASE_OID
- 	GSS_CREATE_EMPTY_OID_SET
- 	GSS_ADD_OID_SET_MEMBER
- 	GSS_TEST_OID_SET_MEMBER
- 	GSS_OID_TO_STR
- 	GSS_STR_TO_OID
- 
- ; GSS-API v2  renamed message protection calls
- ;
- 	GSS_WRAP
- 	GSS_UNWRAP
- 	GSS_GET_MIC
- 	GSS_VERIFY_MIC
- 
- ; GSS-API v2  future extensions
- ;
- 	GSS_INQUIRE_NAMES_FOR_MECH
- ;	GSS_INQUIRE_MECHS_FOR_NAME
- ;	GSS_CANONICALIZE_NAME
- ;	GSS_EXPORT_NAME
- 
--- 0 ----
Index: krb5/lib/winsock.def
diff -c krb5/lib/winsock.def:1.1.1.1 krb5/lib/winsock.def:removed
*** krb5/lib/winsock.def:1.1.1.1	Mon Jun  2 17:55:44 1997
--- krb5/lib/winsock.def	Sun Mar 16 20:22:20 2003
***************
*** 1,90 ****
- ;  
- ;         File: winsock.def 
- ;       System: MS-Windows 3.x 
- ;      Summary: Module definition file for Windows Sockets DLL.  
- ;  
- ;	This file is from
- ;  ftp://sunsite.unc.edu/pub/micro/pc-stuff/ms-windows/winsock/winsock-1.1
- ;	except that we made all the routine names uppercase, to match what
- ;	MicroSoft C does when you declare an interface routine PASCAL
- ;	(the way all these routines are declared in .../include/winsock.h).
- ;
- 
- LIBRARY         WINSOCK         ; Application's module name 
- 
- DESCRIPTION     'BSD Socket API for Windows' 
- 
- EXETYPE         WINDOWS         ; required for all windows applications 
- 
- STUB            'WINSTUB.EXE'   ; generates error message if application 
-                                 ; is run without Windows 
- 
- ;CODE can be FIXED in memory because of potential upcalls 
- CODE            PRELOAD         FIXED 
- 
- ;DATA must be SINGLE and at a FIXED location since this is a DLL 
- DATA            PRELOAD         FIXED           SINGLE
- 
- HEAPSIZE        1024 
- STACKSIZE       16384 
- 
- ; All functions that will be called by any Windows routine 
- ; must be exported.  Any additional exports beyond those defined
- ; here must have ordinal numbers 1000 or above. 
- 
- EXPORTS 
-         ACCEPT                         @1 
-         BIND                           @2 
-         CLOSESOCKET                    @3 
-         CONNECT                        @4 
-         GETPEERNAME                    @5 
-         GETSOCKNAME                    @6 
-         GETSOCKOPT                     @7 
-         HTONL                          @8 
-         HTONS                          @9 
-         INET_ADDR                      @10 
-         INET_NTOA                      @11 
-         IOCTLSOCKET                    @12 
-         LISTEN                         @13 
-         NTOHL                          @14 
-         NTOHS                          @15 
-         RECV                           @16 
-         RECVFROM                       @17 
-         SELECT                         @18 
-         SEND                           @19 
-         SENDTO                         @20 
-         SETSOCKOPT                     @21 
-         SHUTDOWN                       @22 
-         SOCKET                         @23 
- 
-         GETHOSTBYADDR                  @51 
-         GETHOSTBYNAME                  @52 
-         GETPROTOBYNAME                 @53 
-         GETPROTOBYNUMBER               @54 
-         GETSERVBYNAME                  @55 
-         GETSERVBYPORT                  @56 
-         GETHOSTNAME                    @57
- 
-         WSAASYNCSELECT                 @101 
-         WSAASYNCGETHOSTBYADDR          @102 
-         WSAASYNCGETHOSTBYNAME          @103 
-         WSAASYNCGETPROTOBYNUMBER       @104 
-         WSAASYNCGETPROTOBYNAME         @105 
-         WSAASYNCGETSERVBYPORT          @106 
-         WSAASYNCGETSERVBYNAME          @107 
-         WSACANCELASYNCREQUEST          @108 
-         WSASETBLOCKINGHOOK             @109 
-         WSAUNHOOKBLOCKINGHOOK          @110 
-         WSAGETLASTERROR                @111 
-         WSASETLASTERROR                @112 
-         WSACANCELBLOCKINGCALL          @113 
-         WSAISBLOCKING                  @114 
-         WSASTARTUP                     @115 
-         WSACLEANUP                     @116 
- 
-         __WSAFDISSET                   @151 
- 
-         WEP                            @500    RESIDENTNAME 
- 
- ;eof 
- 
--- 0 ----
Index: krb5/lib/crypto/.cvsignore
diff -c /dev/null krb5/lib/crypto/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:20 2003
--- krb5/lib/crypto/.cvsignore	Thu Jun  5 10:39:05 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/crypto/Makefile.in
diff -c krb5/lib/crypto/Makefile.in:1.1.1.2 krb5/lib/crypto/Makefile.in:1.2
*** krb5/lib/crypto/Makefile.in:1.1.1.2	Fri Feb 22 16:33:59 2002
--- krb5/lib/crypto/Makefile.in	Thu Sep 12 23:06:53 2002
***************
*** 26,31 ****
--- 26,32 ----
  	cksumtype_to_string.o	\
  	cksumtypes.o		\
  	coll_proof_cksum.o	\
+ 	combine_keys.o		\
  	crypto_libinit.o	\
  	decrypt.o		\
  	encrypt.o		\
***************
*** 54,59 ****
--- 55,61 ----
  	$(OUTPRE)cksumtype_to_string.$(OBJEXT)	\
  	$(OUTPRE)cksumtypes.$(OBJEXT)		\
  	$(OUTPRE)coll_proof_cksum.$(OBJEXT)	\
+ 	$(OUTPRE)combine_keys.$(OBJEXT)		\
  	$(OUTPRE)crypto_libinit.$(OBJEXT)	\
  	$(OUTPRE)decrypt.$(OBJEXT)		\
  	$(OUTPRE)encrypt.$(OBJEXT)		\
***************
*** 82,87 ****
--- 84,90 ----
  	$(subdir)/cksumtype_to_string.c	\
  	$(subdir)/cksumtypes.c		\
  	$(subdir)/coll_proof_cksum.c	\
+ 	$(subdir)/combine_keys.c	\
  	$(subdir)/crypto_libinit.c	\
  	$(subdir)/decrypt.c		\
  	$(subdir)/encrypt.c		\
Index: krb5/lib/crypto/combine_keys.c
diff -c /dev/null krb5/lib/crypto/combine_keys.c:1.2
*** /dev/null	Sun Mar 16 20:22:20 2003
--- krb5/lib/crypto/combine_keys.c	Tue Nov 26 12:49:56 2002
***************
*** 0 ****
--- 1,334 ----
+ /*
+  * Copyright (c) 2002 Naval Research Laboratory (NRL/CCS)
+  *
+  * Permission to use, copy, modify and distribute this software and its
+  * documentation is hereby granted, provided that both the copyright
+  * notice and this permission notice appear in all copies of the software,
+  * derivative works or modified versions, and any portions thereof.
+  * 
+  * NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
+  * DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
+  * RESULTING FROM THE USE OF THIS SOFTWARE.
+  *
+  * Key combination function.
+  *
+  * If Key1 and Key2 are two keys to be combined, the algorithm to combine
+  * them is as follows.
+  *
+  * Definitions:
+  *
+  * k-truncate is defined as truncating to the key size the input.
+  *
+  * DR is defined as the generate "random" data from a key
+  * (defined in crypto draft)
+  *
+  * DK is defined as the key derivation function (krb5_derive_key())
+  *
+  * (note: | means "concatenate")
+  *
+  * Combine key algorithm:
+  *
+  * R1 = DR(Key1, n-fold(Key2)) [ Output is length of Key1 ]
+  * R2 = DR(Key2, n-fold(Key1)) [ Output is length of Key2 ]
+  *
+  * rnd = n-fold(R1 | R2) [ Note: output size of nfold must be appropriately
+  *			   sized for random-to-key function ]
+  * tkey = random-to-key(rnd)
+  * Combine-Key(Key1, Key2) = DK(tkey, CombineConstant)
+  *
+  * CombineConstant is defined as the byte string:
+  *
+  * { 0x63 0x6f 0x6d 0x62 0x69 0x6e 0x65 }, which corresponds to the
+  * ASCII encoding of the string "combine"
+  */
+ 
+ #include "k5-int.h"
+ #include "etypes.h"
+ #include "dk.h"
+ 
+ static krb5_error_code dr
+ KRB5_PROTOTYPE((krb5_const struct krb5_enc_provider *enc,
+ 		krb5_const krb5_keyblock *inkey, unsigned char *outdata,
+ 		krb5_const krb5_data *in_constant));
+ 
+ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+ krb5_combine_keys(context, key1, key2, outkey)
+     krb5_context context;
+     krb5_keyblock *key1;
+     krb5_keyblock *key2;
+     krb5_keyblock *outkey;
+ {
+     unsigned char *r1, *r2, *combined, *rnd, *output;
+     size_t keybytes, keylength;
+     const struct krb5_enc_provider *enc;
+     krb5_data input, randbits;
+     krb5_keyblock tkey;
+     krb5_error_code ret;
+     int i, myalloc = 0;
+ 
+     if (key1->length != key2->length || key1->enctype != key2->enctype)
+ 	return (KRB5_CRYPTO_INTERNAL);
+ 
+     /*
+      * Find our encryption algorithm
+      */
+ 
+     for (i = 0; i < krb5_enctypes_length; i++) {
+ 	if (krb5_enctypes_list[i].etype == key1->enctype)
+ 	    break;
+     }
+ 
+     if (i == krb5_enctypes_length)
+ 	return (KRB5_BAD_ENCTYPE);
+ 
+     enc = krb5_enctypes_list[i].enc;
+ 
+     (*(enc->keysize))(&keybytes, &keylength);
+ 
+     /*
+      * Allocate and set up buffers
+      */
+ 
+     if ((r1 = (unsigned char *) malloc(keybytes)) == NULL)
+ 	return (ENOMEM);
+ 
+     if ((r2 = (unsigned char *) malloc(keybytes)) == NULL) {
+ 	free(r1);
+ 	return (ENOMEM);
+     }
+ 
+     if ((rnd = (unsigned char *) malloc(keybytes)) == NULL) {
+ 	free(r1);
+ 	free(r2);
+ 	return (ENOMEM);
+     }
+ 
+     if ((combined = (unsigned char *) malloc(keybytes * 2)) == NULL) {
+ 	free(r1);
+ 	free(r2);
+ 	free(rnd);
+ 	return (ENOMEM);
+     }
+ 
+     if ((output = (unsigned char *) malloc(keylength)) == NULL) {
+ 	free(r1);
+ 	free(r2);
+ 	free(rnd);
+ 	free(combined);
+ 	return (ENOMEM);
+     }
+ 
+     /*
+      * Get R1 and R2 (by running the input keys through the DR algorithm.
+      * Note this is most of derive-key, but not all.
+      */
+ 
+     input.length = key2->length;
+     input.data = (char *) key2->contents;
+     if ((ret = dr(enc, key1, r1, &input)))
+ 	goto cleanup;
+ 
+ #if 0
+     {
+ 	int i;
+ 	printf("R1 =");
+ 	for (i = 0; i < keybytes; i++)
+ 	    printf(" %02x", (unsigned char) r1[i]);
+ 	printf("\n");
+     }
+ #endif
+ 
+     input.length = key1->length;
+     input.data = (char *) key1->contents;
+     if ((ret = dr(enc, key2, r2, &input)))
+ 	goto cleanup;
+ 
+ #if 0
+     {
+ 	int i;
+ 	printf("R2 =");
+ 	for (i = 0; i < keybytes; i++)
+ 	    printf(" %02x", (unsigned char) r2[i]);
+ 	printf("\n");
+     }
+ #endif
+ 
+     /*
+      * Concatenate the two keys together, and then run them through
+      * n-fold to reduce them to a length appropriate for the random-to-key
+      * operation.  Note here that krb5_nfold() takes sizes in bits, hence
+      * the multiply by 8.
+      */
+ 
+     memcpy(combined, r1, keybytes);
+     memcpy(combined + keybytes, r2, keybytes);
+ 
+     krb5_nfold((keybytes * 2) * 8, combined, keybytes * 8, rnd);
+ 
+ #if 0
+     {
+ 	int i;
+ 	printf("rnd =");
+ 	for (i = 0; i < keybytes; i++)
+ 	    printf(" %02x", (unsigned char) rnd[i]);
+ 	printf("\n");
+     }
+ #endif
+ 
+     /*
+      * Run the "random" bits through random-to-key to produce a encryption
+      * key.
+      */
+ 
+     randbits.length = keybytes;
+     randbits.data = (char *) rnd;
+     tkey.length = keylength;
+     tkey.contents = output;
+ 
+     if ((ret = (*(enc->make_key))(&randbits, &tkey)))
+ 	goto cleanup;
+ 
+ #if 0
+     {
+ 	int i;
+ 	printf("tkey =");
+ 	for (i = 0; i < tkey.length; i++)
+ 	    printf(" %02x", (unsigned char) tkey.contents[i]);
+ 	printf("\n");
+     }
+ #endif
+ 
+     /*
+      * Run through derive-key one more time to produce the final key.
+      * Note that the input to derive-key is the ASCII string "combine".
+      */
+ 
+     input.length = 7; /* Note; change this if string length changes */
+     input.data = "combine";
+ 
+     /*
+      * Just FYI: _if_ we have space here in the key, then simply use it
+      * without modification.  But if the key is blank (no allocated storage)
+      * then allocate some memory for it.  This allows programs to use one of
+      * the existing keys as the output key, _or_ pass in a blank keyblock
+      * for us to allocate.  It's easier for us to allocate it since we already
+      * know the crypto library internals
+      */
+ 
+     if (outkey->length == 0 || outkey->contents == NULL) {
+ 	outkey->contents = (krb5_octet *) malloc(keylength);
+ 	if (!outkey->contents) {
+ 	    ret = ENOMEM;
+ 	    goto cleanup;
+ 	}
+ 	outkey->length = keylength;
+ 	outkey->enctype = key1->enctype;
+ 	myalloc = 1;
+     }
+ 
+     if ((ret = krb5_derive_key(enc, &tkey, outkey, &input))) {
+ 	if (myalloc) {
+ 	    free(outkey->contents);
+ 	    outkey->contents = NULL;
+ 	}
+ 	goto cleanup;
+     }
+ 
+ #if 0
+     {
+ 	int i;
+ 	printf("output =");
+ 	for (i = 0; i < outkey->length; i++)
+ 	    printf(" %02x", (unsigned char) outkey->contents[i]);
+ 	printf("\n");
+     }
+ #endif
+ 
+     ret = 0;
+ 
+ cleanup:
+     memset(r1, 0, keybytes);
+     memset(r2, 0, keybytes);
+     memset(rnd, 0, keybytes);
+     memset(combined, 0, keybytes * 2);
+     memset(output, 0, keylength);
+ 
+     free(r1);
+     free(r2);
+     free(rnd);
+     free(combined);
+     free(output);
+ 
+     return (ret);
+ }
+ 
+ /*
+  * Our DR function; mostly taken from derive.c
+  */
+ 
+ static krb5_error_code
+ dr(enc, inkey, out, in_constant)
+      krb5_const struct krb5_enc_provider *enc;
+      krb5_const krb5_keyblock *inkey;
+      unsigned char *out;
+      krb5_const krb5_data *in_constant;
+ {
+     size_t blocksize, keybytes, keylength, n;
+     unsigned char *inblockdata, *outblockdata;
+     krb5_data inblock, outblock;
+ 
+     (*(enc->block_size))(&blocksize);
+     (*(enc->keysize))(&keybytes, &keylength);
+ 
+     /* allocate and set up buffers */
+ 
+     if ((inblockdata = (unsigned char *) malloc(blocksize)) == NULL)
+ 	return(ENOMEM);
+ 
+     if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) {
+ 	free(inblockdata);
+ 	return(ENOMEM);
+     }
+ 
+     inblock.data = (char *) inblockdata;
+     inblock.length = blocksize;
+ 
+     outblock.data = (char *) outblockdata;
+     outblock.length = blocksize;
+ 
+     /* initialize the input block */
+ 
+     if (in_constant->length == inblock.length) {
+ 	memcpy(inblock.data, in_constant->data, inblock.length);
+     } else {
+ 	krb5_nfold(in_constant->length*8, (unsigned char *) in_constant->data,
+ 		   inblock.length*8, (unsigned char *) inblock.data);
+     }
+ 
+     /* loop encrypting the blocks until enough key bytes are generated */
+ 
+     n = 0;
+     while (n < keybytes) {
+ 	(*(enc->encrypt))(inkey, 0, &inblock, &outblock);
+ 
+ 	if ((keybytes - n) <= outblock.length) {
+ 	    memcpy(out+n, outblock.data, (keybytes - n));
+ 	    break;
+ 	}
+ 
+ 	memcpy(out+n, outblock.data, outblock.length);
+ 	memcpy(inblock.data, outblock.data, outblock.length);
+ 	n += outblock.length;
+     }
+ 
+     /* clean memory, free resources and exit */
+ 
+     memset(inblockdata, 0, blocksize);
+     memset(outblockdata, 0, blocksize);
+ 
+     free(outblockdata);
+     free(inblockdata);
+ 
+     return(0);
+ }
+ 
Index: krb5/lib/crypto/cryptoconf.c
diff -c krb5/lib/crypto/cryptoconf.c:1.1.1.1 krb5/lib/crypto/cryptoconf.c:removed
*** krb5/lib/crypto/cryptoconf.c:1.1.1.1	Mon Jun  2 17:57:38 1997
--- krb5/lib/crypto/cryptoconf.c	Sun Mar 16 20:22:20 2003
***************
*** 1,168 ****
- /*
-  * lib/crypto/cryptoconf.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * Cryptosystem configurations
-  */
- 
- #include "k5-int.h"
- 
- #if defined(PROVIDE_DES_CBC_CRC) || defined(PROVIDE_CRC32)
- #include "crc-32.h"
- #define CRC32_CKENTRY &crc32_cksumtable_entry
- #else
- #define CRC32_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_RSA_MD4
- #include "rsa-md4.h"
- #define MD4_CKENTRY &rsa_md4_cksumtable_entry
- #define MD4_DES_CKENTRY &rsa_md4_des_cksumtable_entry
- #else
- #define MD4_CKENTRY 0
- #define MD4_DES_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_RSA_MD5
- #include "rsa-md5.h"
- #define MD5_CKENTRY &rsa_md5_cksumtable_entry
- #define MD5_DES_CKENTRY &rsa_md5_des_cksumtable_entry
- #else
- #define MD5_CKENTRY 0
- #define MD5_DES_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_NIST_SHA
- #include "shs.h"
- /* #define SHA_CKENTRY &nist_sha_cksumtable_entry */
- /* #define HMAC_SHA_CKENTRY &hmac_sha_cksumtable_entry */
- #define SHA_CKENTRY 0
- #define HMAC_SHA_CKENTRY 0
- #else
- #define SHA_CKENTRY 0
- #define HMAC_SHA_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_SNEFRU
- #define XEROX_CKENTRY &snefru_cksumtable_entry
- #else
- #define XEROX_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_DES_CBC_CKSUM
- #include "des_int.h"
- #define _DES_DONE__
- #define DES_CBC_CKENTRY &krb5_des_cbc_cksumtable_entry
- #else
- #define DES_CBC_CKENTRY 0
- #endif
- 
- #ifdef PROVIDE_DES_CBC_CRC
- #ifndef _DES_DONE__
- #include "des_int.h"
- #define _DES_DONE__
- #endif
- #define DES_CBC_CRC_CSENTRY &krb5_des_crc_cst_entry
- #else
- #define DES_CBC_CRC_CSENTRY 0
- #endif
- 
- #ifdef PROVIDE_DES_CBC_MD5
- #ifndef _DES_DONE__
- #include "des_int.h"
- #define _DES_DONE__
- #endif
- #define DES_CBC_MD5_CSENTRY &krb5_des_md5_cst_entry
- #else
- #define DES_CBC_MD5_CSENTRY 0
- #endif
-     
- #ifdef PROVIDE_DES_CBC_RAW
- #ifndef _DES_DONE__
- #include "des_int.h"
- #define _DES_DONE__
- #endif
- #define DES_CBC_RAW_CSENTRY &krb5_raw_des_cst_entry
- #else
- #define DES_CBC_RAW_CSENTRY 0
- #endif
- 
- #ifdef PROVIDE_DES3_CBC_SHA
- #ifndef _DES_DONE__
- #include "des_int.h"
- #define _DES_DONE__
- #endif
- /* Don't try to enable triple DES unless you know what you are doing; */
- /* the current implementation of triple DES is NOT the final and */
- /* correct implementation.!!!  */
- /* #define DES3_CBC_SHA_CSENTRY &krb5_des3_sha_cst_entry */
- #define DES3_CBC_SHA_CSENTRY 0
- #else
- #define DES3_CBC_SHA_CSENTRY 0
- #endif
- 
- #ifdef PROVIDE_DES3_CBC_RAW
- #ifndef _DES_DONE__
- #include "des_int.h"
- #define _DES_DONE__
- #endif
- /* #define DES3_CBC_RAW_CSENTRY &krb5_des3_raw_cst_entry */
- #define DES3_CBC_RAW_CSENTRY 0
- #else
- #define DES3_CBC_RAW_CSENTRY 0
- #endif
- 
- 
- /* WARNING:
-    make sure the order of entries in these tables matches the #defines in
-    "krb5/encryption.h"
-  */
- 
- krb5_cs_table_entry * NEAR krb5_enctype_array[] = {
-     0,				/* ENCTYPE_NULL */
-     DES_CBC_CRC_CSENTRY,	/* ENCTYPE_DES_CBC_CRC */
-     0,				/* ENCTYPE_DES_CBC_MD4 */
-     DES_CBC_MD5_CSENTRY,	/* ENCTYPE_DES_CBC_MD5 */
-     DES_CBC_RAW_CSENTRY,	/* ENCTYPE_DES_CBC_RAW */
-     DES3_CBC_SHA_CSENTRY,	/* ENCTYPE_DES3_CBC_SHA */
-     DES3_CBC_RAW_CSENTRY	/* ENCTYPE_DES3_CBC_RAW */
- };
- 
- krb5_enctype krb5_max_enctype = sizeof(krb5_enctype_array)/sizeof(krb5_enctype_array[0]) - 1;
- 
- krb5_checksum_entry * NEAR krb5_cksumarray[] = {
-     0,
-     CRC32_CKENTRY,		/* 1 - CKSUMTYPE_CRC32 */
-     MD4_CKENTRY,		/* 2 - CKSUMTYPE_RSA_MD4 */
-     MD4_DES_CKENTRY,		/* 3 - CKSUMTYPE_RSA_MD4_DES */
-     DES_CBC_CKENTRY,		/* 4 - CKSUMTYPE_DESCBC */
-     0,				/* 5 - des-mac-k */
-     0,				/* 6 - rsa-md4-des-k */
-     MD5_CKENTRY,		/* 7 - CKSUMTYPE_RSA_MD5 */
-     MD5_DES_CKENTRY,		/* 8 - CKSUMTYPE_RSA_MD5_DES */
-     SHA_CKENTRY,		/* 9 - CKSUMTYPE_NIST_SHA */
-     HMAC_SHA_CKENTRY		/* 10 - CKSUMTYPE_NIST_SHA_DES3 */
- };
- 
- krb5_cksumtype krb5_max_cksum = sizeof(krb5_cksumarray)/sizeof(krb5_cksumarray[0]);
- 
- #undef _DES_DONE__
--- 0 ----
Index: krb5/lib/crypto/decrypt_data.c
diff -c krb5/lib/crypto/decrypt_data.c:1.1.1.1 krb5/lib/crypto/decrypt_data.c:removed
*** krb5/lib/crypto/decrypt_data.c:1.1.1.1	Mon Jun  2 17:57:38 1997
--- krb5/lib/crypto/decrypt_data.c	Sun Mar 16 20:22:20 2003
***************
*** 1,66 ****
- /*
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- #include "k5-int.h"
- 
- /*
-  * This routine takes a key and a krb5_enc_data structure as input, and
-  * outputs the decrypted data in a krb5_data structure.  Note that
-  * the krb5_data structure is not allocated.
-  */
- krb5_error_code
- krb5_decrypt_data(context, key, ivec, enc_data, data)
-     krb5_context	context;
-     krb5_keyblock *	key;
-     krb5_pointer	ivec;
-     krb5_enc_data *	enc_data;
-     krb5_data *		data;
- {
-     krb5_error_code	retval;
-     krb5_encrypt_block	eblock;
- 
-     krb5_use_enctype(context, &eblock, key->enctype);
-     data->length = enc_data->ciphertext.length;
-     if (!(data->data = malloc(data->length)))
- 	return ENOMEM;
- 
-     if ((retval = krb5_process_key(context, &eblock, key)) != 0)
- 	goto cleanup;
- 
-     if ((retval = krb5_decrypt(context,
- 			       (krb5_pointer) enc_data->ciphertext.data,
- 			       (krb5_pointer) data->data,
- 			       enc_data->ciphertext.length, &eblock, ivec))) {
-     	krb5_finish_key(context, &eblock);
-         goto cleanup;
-     }
-     (void) krb5_finish_key(context, &eblock);
- 
-     return 0;
- 
- cleanup:
-     if (data->data) {
- 	free(data->data);
- 	data->data = 0;
-     }
-     return retval;
- }
--- 0 ----
Index: krb5/lib/crypto/des3_raw.c
diff -c krb5/lib/crypto/des3_raw.c:1.1.1.1 krb5/lib/crypto/des3_raw.c:removed
*** krb5/lib/crypto/des3_raw.c:1.1.1.1	Mon Jun  2 17:57:38 1997
--- krb5/lib/crypto/des3_raw.c	Sun Mar 16 20:22:20 2003
***************
*** 1,104 ****
- /*
-  * lib/crypto/des3_raw.c
-  *
-  * Copyright 1996 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- krb5_error_code mit_des3_raw_encrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- krb5_error_code mit_des3_raw_decrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- static krb5_cryptosystem_entry mit_des3_raw_cryptosystem_entry = {
-     0,
-     mit_des3_raw_encrypt_func,
-     mit_des3_raw_decrypt_func,
-     mit_des3_process_key,
-     mit_des_finish_key,
-     mit_des3_string_to_key,
-     mit_des_init_random_key,
-     mit_des_finish_random_key,
-     mit_des_random_key,
-     sizeof(mit_des_cblock),
-     0,
-     sizeof(mit_des3_cblock),
-     ENCTYPE_DES3_CBC_RAW
-     };
- 
- krb5_cs_table_entry krb5_des3_raw_cst_entry = {
-     0,
-     &mit_des3_raw_cryptosystem_entry,
-     0
-     };
- 
- krb5_error_code
- mit_des3_raw_decrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     return (mit_des3_cbc_encrypt((const mit_des_cblock *) in, 
- 				 out, 
- 				 size, 
- 				 (struct mit_des_ks_struct *)key->priv,
- 				 ((struct mit_des_ks_struct *)key->priv) + 1,
- 				 ((struct mit_des_ks_struct *)key->priv) + 2,
- 				 ivec ? ivec : (krb5_pointer)key->key->contents,
- 				 MIT_DES_DECRYPT));
- }
- 
- krb5_error_code
- mit_des3_raw_encrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-    int sumsize;
- 
-    /* round up to des block size */
- 
-    sumsize =  krb5_roundup(size, sizeof(mit_des_cblock));
- 
-    /* assemble crypto input into the output area, then encrypt in place. */
- 
-    memset((char *)out, 0, sumsize);
-    memcpy((char *)out, (char *)in, size);
- 
-     /* We depend here on the ability of this DES implementation to
-        encrypt plaintext to ciphertext in-place. */
-     return (mit_des3_cbc_encrypt(out, 
- 				 out, 
- 				 sumsize, 
- 				 (struct mit_des_ks_struct *)key->priv,
- 				 ((struct mit_des_ks_struct *)key->priv) + 1,
- 				 ((struct mit_des_ks_struct *)key->priv) + 2,
- 				 ivec ? ivec : (krb5_pointer)key->key->contents,
- 				 MIT_DES_ENCRYPT));
- }
--- 0 ----
Index: krb5/lib/crypto/des3_sha.c
diff -c krb5/lib/crypto/des3_sha.c:1.1.1.1 krb5/lib/crypto/des3_sha.c:removed
*** krb5/lib/crypto/des3_sha.c:1.1.1.1	Mon Jun  2 17:57:38 1997
--- krb5/lib/crypto/des3_sha.c	Sun Mar 16 20:22:20 2003
***************
*** 1,178 ****
- /*
-  * lib/crypto/des3-sha.c
-  *
-  * Copyright 1996 by Lehman Brothers, Inc.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Lehman Brothers or M.I.T. not be used in advertising or
-  * publicity pertaining to distribution of the software without
-  * specific, written prior permission.  Lehman Brothers and
-  * M.I.T. make no representations about the suitability of this
-  * software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "shs.h"
- #include "des_int.h"
- 
- 
- #define DES3_SHA_CONFOUNDER_SIZE	sizeof(mit_des3_cblock)
- 
- static krb5_error_code
- mit_des3_sha_encrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- static krb5_error_code
- mit_des3_sha_decrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- static mit_des_cblock zero_ivec = { 0 };
- 
- static krb5_cryptosystem_entry mit_des3_sha_cryptosystem_entry = {
-     0,
-     mit_des3_sha_encrypt_func,
-     mit_des3_sha_decrypt_func, 
-     mit_des3_process_key,
-     mit_des_finish_key,
-     mit_des3_string_to_key,
-     mit_des_init_random_key,
-     mit_des_finish_random_key,
-     mit_des_random_key,
-     sizeof(mit_des_cblock),
-     NIST_SHA_CKSUM_LENGTH + DES3_SHA_CONFOUNDER_SIZE,
-     sizeof(mit_des3_cblock),
-     ENCTYPE_DES3_CBC_SHA
-     };
- 
- krb5_cs_table_entry krb5_des3_sha_cst_entry = {
-     0,
-     &mit_des3_sha_cryptosystem_entry,
-     0
-     };
- 
- 
- static krb5_error_code
- mit_des3_sha_encrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents[NIST_SHA_CKSUM_LENGTH];
-     int sumsize;
-     krb5_error_code retval;
- 
-     /* caller passes data size, and saves room for the padding. */
-     /* format of ciphertext, per RFC is:
-       +-----------+----------+-------------+-----+
-       |confounder |   check  |   msg-seq   | pad |
-       +-----------+----------+-------------+-----+
-       
-       our confounder is 24 bytes
-       our checksum is NIST_SHA_CKSUM_LENGTH
-      */
-     sumsize =  krb5_roundup(size + mit_des3_sha_cryptosystem_entry.pad_minimum,
- 			    mit_des3_sha_cryptosystem_entry.block_length);
- 
-     /* assemble crypto input into the output area, then encrypt in place. */
- 
-     memset((char *)out, 0, sumsize);
- 
-     /* put in the confounder */
-     if ((retval = krb5_random_confounder(DES3_SHA_CONFOUNDER_SIZE, out)))
- 	return retval;
- 
-     memcpy((char *)out + mit_des3_sha_cryptosystem_entry.pad_minimum,
- 	   (char *)in, size);
- 
-     cksum.length = sizeof(contents);
-     cksum.contents = contents; 
- 
-     /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_SHA,...)
-        but avoids use of the cryptosystem config table which can not be
-        referenced here if this object is to be included in a shared library. */
-     retval = nist_sha_cksumtable_entry.sum_func((krb5_pointer) out, sumsize,
- 						0, 0, &cksum);
-     if (retval)
- 	return retval;
- 
-     memcpy((char *)out + DES3_SHA_CONFOUNDER_SIZE,
- 	   (char *)contents, NIST_SHA_CKSUM_LENGTH);
- 
-     /* We depend here on the ability of this DES-3 implementation to
-        encrypt plaintext to ciphertext in-place. */
-     retval = mit_des3_cbc_encrypt(out,
- 				  out,
- 				  sumsize,
- 				  (struct mit_des_ks_struct *) key->priv,
- 				  ((struct mit_des_ks_struct *) key->priv) + 1,
- 				  ((struct mit_des_ks_struct *) key->priv) + 2,
- 				  ivec ? ivec : (krb5_pointer)zero_ivec,
- 				  MIT_DES_ENCRYPT);
-     return retval;
- }
- 
- static krb5_error_code
- mit_des3_sha_decrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents_prd[NIST_SHA_CKSUM_LENGTH];
-     krb5_octet  contents_get[NIST_SHA_CKSUM_LENGTH];
-     char 	*p;
-     krb5_error_code   retval;
- 
-     if ( size < krb5_roundup(mit_des3_sha_cryptosystem_entry.pad_minimum,
- 			     mit_des3_sha_cryptosystem_entry.block_length))
- 	return KRB5_BAD_MSIZE;
- 
-     retval = mit_des3_cbc_encrypt((const mit_des_cblock *) in,
- 				  out,
- 				  size,
- 				  (struct mit_des_ks_struct *) key->priv,
- 				  ((struct mit_des_ks_struct *) key->priv) + 1,
- 				  ((struct mit_des_ks_struct *) key->priv) + 2,
- 				  ivec ? ivec : (krb5_pointer)zero_ivec,
- 				  MIT_DES_DECRYPT);
-     if (retval)
- 	return retval;
- 
-     cksum.length = sizeof(contents_prd);
-     cksum.contents = contents_prd;
-     p = (char *)out + DES3_SHA_CONFOUNDER_SIZE;
-     memcpy((char *)contents_get, p, NIST_SHA_CKSUM_LENGTH);
-     memset(p, 0, NIST_SHA_CKSUM_LENGTH);
- 
-     retval = nist_sha_cksumtable_entry.sum_func(out, size, 0, 0, &cksum);
-     if (retval)
- 	return retval;
- 
-     if (memcmp((char *)contents_get,
- 	       (char *)contents_prd,
- 	       NIST_SHA_CKSUM_LENGTH))
-         return KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 
-     memmove((char *)out, (char *)out +
- 	    mit_des3_sha_cryptosystem_entry.pad_minimum,
- 	    size - mit_des3_sha_cryptosystem_entry.pad_minimum);
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des_crc.c
diff -c krb5/lib/crypto/des_crc.c:1.1.1.1 krb5/lib/crypto/des_crc.c:removed
*** krb5/lib/crypto/des_crc.c:1.1.1.1	Mon Jun  2 17:57:39 1997
--- krb5/lib/crypto/des_crc.c	Sun Mar 16 20:22:20 2003
***************
*** 1,170 ****
- /*
-  * lib/crypto/des-crc.32
-  *
-  * Copyright 1994 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "crc-32.h"
- #include "des_int.h"
- 
- krb5_error_code mit_des_crc_encrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- krb5_error_code mit_des_crc_decrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- 
- static krb5_cryptosystem_entry mit_des_crc_cryptosystem_entry = {
-     0,
-     mit_des_crc_encrypt_func,
-     mit_des_crc_decrypt_func, 
-     mit_des_process_key,
-     mit_des_finish_key,
-     mit_des_string_to_key,
-     mit_des_init_random_key,
-     mit_des_finish_random_key,
-     mit_des_random_key,
-     sizeof(mit_des_cblock),
-     CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock),
-     sizeof(mit_des_cblock),
-     ENCTYPE_DES_CBC_CRC
-     };
- 
- krb5_cs_table_entry krb5_des_crc_cst_entry = {
-     0,
-     &mit_des_crc_cryptosystem_entry,
-     0
-     };
- 
- 
- krb5_error_code
- mit_des_crc_encrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents[CRC32_CKSUM_LENGTH];
-     int sumsize;
-     krb5_error_code retval;
- 
- /*    if ( size < sizeof(mit_des_cblock) )
- 	return KRB5_BAD_MSIZE; */
- 
-     /* caller passes data size, and saves room for the padding. */
-     /* format of ciphertext, per RFC is:
-       +-----------+----------+-------------+-----+
-       |confounder |   check  |   msg-seq   | pad |
-       +-----------+----------+-------------+-----+
-       
-       our confounder is 8 bytes (one cblock);
-       our checksum is CRC32_CKSUM_LENGTH
-      */
-     sumsize =  krb5_roundup(size+CRC32_CKSUM_LENGTH+sizeof(mit_des_cblock),
- 			    sizeof(mit_des_cblock));
- 
-     /* assemble crypto input into the output area, then encrypt in place. */
- 
-     memset((char *)out, 0, sumsize);
- 
-     /* put in the confounder */
-     if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out)))
- 	return retval;
- 
-     memcpy((char *)out+sizeof(mit_des_cblock)+CRC32_CKSUM_LENGTH, (char *)in,
- 	   size);
- 
-     cksum.length = sizeof(contents);
-     cksum.contents = contents; 
- 
-     /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_CRC32,...)
-        but avoids use of the cryptosystem config table which can not be
-        referenced here if this object is to be included in a shared library.  */
-     if ((retval = crc32_cksumtable_entry.sum_func((krb5_pointer) out,
- 						  sumsize,
- 						  (krb5_pointer)key->key->contents,
- 						  sizeof(mit_des_cblock),
- 						  &cksum)))
- 	return retval;
- 
-     memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents,
- 	   CRC32_CKSUM_LENGTH);
- 
-     /* We depend here on the ability of this DES implementation to
-        encrypt plaintext to ciphertext in-place. */
-     return (mit_des_cbc_encrypt(out, 
- 				out,
- 				sumsize, 
- 				(struct mit_des_ks_struct *) key->priv, 
- 				ivec ? ivec : (krb5_pointer)key->key->contents,
- 				MIT_DES_ENCRYPT));
-     
- }
- 
- krb5_error_code
- mit_des_crc_decrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents_prd[CRC32_CKSUM_LENGTH];
-     krb5_octet  contents_get[CRC32_CKSUM_LENGTH];
-     char 	*p;
-     krb5_error_code   retval;
- 
-     if ( size < 2*sizeof(mit_des_cblock) )
- 	return KRB5_BAD_MSIZE;
- 
-     retval = mit_des_cbc_encrypt((const mit_des_cblock FAR *) in,
- 				 out,
- 				 size,
- 				 (struct mit_des_ks_struct *) key->priv,
- 				 ivec ? ivec : (krb5_pointer)key->key->contents,
- 				 MIT_DES_DECRYPT);
-     if (retval)
- 	return retval;
- 
-     cksum.length = sizeof(contents_prd);
-     cksum.contents = contents_prd;
-     p = (char *)out + sizeof(mit_des_cblock);
-     memcpy((char *)contents_get, p, CRC32_CKSUM_LENGTH);
-     memset(p, 0, CRC32_CKSUM_LENGTH);
- 
-     if ((retval = crc32_cksumtable_entry.sum_func(out, size,
- 						  (krb5_pointer)key->key->contents,
- 						  sizeof(mit_des_cblock),
- 						  &cksum)))
- 	return retval;
- 
-     if (memcmp((char *)contents_get, (char *)contents_prd, CRC32_CKSUM_LENGTH) )
-         return KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     memmove((char *)out, (char *)out +
- 	   sizeof(mit_des_cblock) + CRC32_CKSUM_LENGTH,
- 	   size - sizeof(mit_des_cblock) - CRC32_CKSUM_LENGTH);
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des_md5.c
diff -c krb5/lib/crypto/des_md5.c:1.1.1.1 krb5/lib/crypto/des_md5.c:removed
*** krb5/lib/crypto/des_md5.c:1.1.1.1	Mon Jun  2 17:57:39 1997
--- krb5/lib/crypto/des_md5.c	Sun Mar 16 20:22:20 2003
***************
*** 1,171 ****
- /*
-  * lib/crypto/des-md5.32
-  *
-  * Copyright 1994 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "rsa-md5.h"
- #include "des_int.h"
- 
- krb5_error_code mit_des_md5_encrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- krb5_error_code mit_des_md5_decrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- static mit_des_cblock zero_ivec = { 0 };
- 
- static krb5_cryptosystem_entry mit_des_md5_cryptosystem_entry = {
-     0,
-     mit_des_md5_encrypt_func,
-     mit_des_md5_decrypt_func, 
-     mit_des_process_key,
-     mit_des_finish_key,
-     mit_des_string_to_key,
-     mit_des_init_random_key,
-     mit_des_finish_random_key,
-     mit_des_random_key,
-     sizeof(mit_des_cblock),
-     RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock),
-     sizeof(mit_des_cblock),
-     ENCTYPE_DES_CBC_MD5
-     };
- 
- krb5_cs_table_entry krb5_des_md5_cst_entry = {
-     0,
-     &mit_des_md5_cryptosystem_entry,
-     0
-     };
- 
- 
- krb5_error_code
- mit_des_md5_encrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents[RSA_MD5_CKSUM_LENGTH];
-     int sumsize;
-     krb5_error_code retval;
- 
- /*    if ( size < sizeof(mit_des_cblock) )
- 	return KRB5_BAD_MSIZE; */
- 
-     /* caller passes data size, and saves room for the padding. */
-     /* format of ciphertext, per RFC is:
-       +-----------+----------+-------------+-----+
-       |confounder |   check  |   msg-seq   | pad |
-       +-----------+----------+-------------+-----+
-       
-       our confounder is 8 bytes (one cblock);
-       our checksum is RSA_MD5_CKSUM_LENGTH
-      */
-     sumsize =  krb5_roundup(size+RSA_MD5_CKSUM_LENGTH+sizeof(mit_des_cblock),
- 			    sizeof(mit_des_cblock));
- 
-     /* assemble crypto input into the output area, then encrypt in place. */
- 
-     memset((char *)out, 0, sumsize);
- 
-     /* put in the confounder */
-     if ((retval = krb5_random_confounder(sizeof(mit_des_cblock), out)))
- 	return retval;
- 
-     memcpy((char *)out+sizeof(mit_des_cblock)+RSA_MD5_CKSUM_LENGTH, (char *)in,
- 	   size);
- 
-     cksum.length = sizeof(contents);
-     cksum.contents = contents; 
- 
-     /* This is equivalent to krb5_calculate_checksum(CKSUMTYPE_MD5,...)
-        but avoids use of the cryptosystem config table which can not be
-        referenced here if this object is to be included in a shared library.  */
-     if ((retval = rsa_md5_cksumtable_entry.sum_func((krb5_pointer) out,
- 						    sumsize,
- 						    (krb5_pointer)key->key->contents,
- 						    sizeof(mit_des_cblock),
- 						    &cksum)))
- 	return retval;
- 
-     memcpy((char *)out+sizeof(mit_des_cblock), (char *)contents,
- 	   RSA_MD5_CKSUM_LENGTH);
- 
-     /* We depend here on the ability of this DES implementation to
-        encrypt plaintext to ciphertext in-place. */
-     return (mit_des_cbc_encrypt(out, 
- 				out,
- 				sumsize, 
- 				(struct mit_des_ks_struct *) key->priv, 
- 				ivec ? ivec : (krb5_pointer)zero_ivec,
- 				MIT_DES_ENCRYPT));
-     
- }
- 
- krb5_error_code
- mit_des_md5_decrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     krb5_checksum cksum;
-     krb5_octet 	contents_prd[RSA_MD5_CKSUM_LENGTH];
-     krb5_octet  contents_get[RSA_MD5_CKSUM_LENGTH];
-     char 	*p;
-     krb5_error_code   retval;
- 
-     if ( size < 2*sizeof(mit_des_cblock) )
- 	return KRB5_BAD_MSIZE;
- 
-     retval = mit_des_cbc_encrypt((const mit_des_cblock *) in,
- 				 out,
- 				 size,
- 				 (struct mit_des_ks_struct *) key->priv,
- 				 ivec ? ivec : (krb5_pointer)zero_ivec,
- 				 MIT_DES_DECRYPT);
-     if (retval)
- 	return retval;
- 
-     cksum.length = sizeof(contents_prd);
-     cksum.contents = contents_prd;
-     p = (char *)out + sizeof(mit_des_cblock);
-     memcpy((char *)contents_get, p, RSA_MD5_CKSUM_LENGTH);
-     memset(p, 0, RSA_MD5_CKSUM_LENGTH);
- 
-     if ((retval = rsa_md5_cksumtable_entry.sum_func(out, size,
- 						    (krb5_pointer)key->key->contents,
- 						    sizeof(mit_des_cblock),
- 						    &cksum)))
- 	return retval;
- 
-     if (memcmp((char *)contents_get, (char *)contents_prd, RSA_MD5_CKSUM_LENGTH) )
-         return KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     memmove((char *)out, (char *)out +
- 	   sizeof(mit_des_cblock) + RSA_MD5_CKSUM_LENGTH,
- 	   size - sizeof(mit_des_cblock) - RSA_MD5_CKSUM_LENGTH);
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/encrypt_data.c
diff -c krb5/lib/crypto/encrypt_data.c:1.1.1.1 krb5/lib/crypto/encrypt_data.c:removed
*** krb5/lib/crypto/encrypt_data.c:1.1.1.1	Mon Jun  2 17:57:39 1997
--- krb5/lib/crypto/encrypt_data.c	Sun Mar 16 20:22:20 2003
***************
*** 1,70 ****
- /*
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- #include "k5-int.h"
- 
- /*
-  * This routine takes a key and a krb5_data structure as input, and
-  * outputs the encrypted data in a krb5_enc_data structure.  Note that
-  * the krb5_enc_data structure is not allocated, and the kvno field is
-  * not filled in.
-  */
- krb5_error_code
- krb5_encrypt_data(context, key, ivec, data, enc_data)
-     krb5_context	context;
-     krb5_keyblock *	key;
-     krb5_pointer	ivec;
-     krb5_data *		data;
-     krb5_enc_data *	enc_data;
- {
-     krb5_error_code	retval;
-     krb5_encrypt_block	eblock;
- 
-     krb5_use_enctype(context, &eblock, key->enctype);
- 
-     enc_data->magic = KV5M_ENC_DATA;
-     enc_data->kvno = 0;
-     enc_data->enctype = key->enctype;
-     enc_data->ciphertext.length = krb5_encrypt_size(data->length,
- 						    eblock.crypto_entry);
-     enc_data->ciphertext.data = malloc(enc_data->ciphertext.length);
-     if (enc_data->ciphertext.data == 0)
- 	return ENOMEM;
- 
-     if ((retval = krb5_process_key(context, &eblock, key)) != 0)
- 	goto cleanup;
- 
-     if ((retval = krb5_encrypt(context, (krb5_pointer) data->data,
- 			       (krb5_pointer) enc_data->ciphertext.data,
- 			       data->length, &eblock, ivec))) {
-     	krb5_finish_key(context, &eblock);
-         goto cleanup;
-     }
-     (void) krb5_finish_key(context, &eblock);
- 
-     return 0;
- 
- cleanup:
-     free(enc_data->ciphertext.data);
-     return retval;
- }
-     
--- 0 ----
Index: krb5/lib/crypto/raw_des.c
diff -c krb5/lib/crypto/raw_des.c:1.1.1.1 krb5/lib/crypto/raw_des.c:removed
*** krb5/lib/crypto/raw_des.c:1.1.1.1	Mon Jun  2 17:57:39 1997
--- krb5/lib/crypto/raw_des.c	Sun Mar 16 20:22:20 2003
***************
*** 1,100 ****
- /*
-  * lib/crypto/raw-des.c
-  *
-  * Copyright 1994, 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- krb5_error_code mit_raw_des_encrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- krb5_error_code mit_raw_des_decrypt_func
-     PROTOTYPE(( krb5_const_pointer, krb5_pointer, const size_t,
-                krb5_encrypt_block *, krb5_pointer ));
- 
- static krb5_cryptosystem_entry mit_raw_des_cryptosystem_entry = {
-     0,
-     mit_raw_des_encrypt_func,
-     mit_raw_des_decrypt_func,
-     mit_des_process_key,
-     mit_des_finish_key,
-     mit_des_string_to_key,
-     mit_des_init_random_key,
-     mit_des_finish_random_key,
-     mit_des_random_key,
-     sizeof(mit_des_cblock),
-     0,
-     sizeof(mit_des_cblock),
-     ENCTYPE_DES_CBC_RAW
-     };
- 
- krb5_cs_table_entry krb5_raw_des_cst_entry = {
-     0,
-     &mit_raw_des_cryptosystem_entry,
-     0
-     };
- 
- krb5_error_code
- mit_raw_des_decrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-     return (mit_des_cbc_encrypt ((const mit_des_cblock *) in, 
- 				 out, 
- 				 size, 
- 				 (struct mit_des_ks_struct *)key->priv, 
- 				 ivec ? ivec : (krb5_pointer)key->key->contents,
- 				 MIT_DES_DECRYPT));
- }
- 
- krb5_error_code
- mit_raw_des_encrypt_func(in, out, size, key, ivec)
-     krb5_const_pointer in;
-     krb5_pointer out;
-     const size_t size;
-     krb5_encrypt_block * key;
-     krb5_pointer ivec;
- {
-    int sumsize;
- 
-    /* round up to des block size */
- 
-    sumsize =  krb5_roundup(size, sizeof(mit_des_cblock));
- 
-    /* assemble crypto input into the output area, then encrypt in place. */
- 
-    memset((char *)out, 0, sumsize);
-    memcpy((char *)out, (char *)in, size);
- 
-     /* We depend here on the ability of this DES implementation to
-        encrypt plaintext to ciphertext in-place. */
-     return (mit_des_cbc_encrypt (out, 
- 				 out, 
- 				 sumsize, 
- 				 (struct mit_des_ks_struct *)key->priv, 
- 				 ivec ? ivec : (krb5_pointer)key->key->contents,
- 				 MIT_DES_ENCRYPT));
- }
--- 0 ----
Index: krb5/lib/crypto/crc32/.cvsignore
diff -c /dev/null krb5/lib/crypto/crc32/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:20 2003
--- krb5/lib/crypto/crc32/.cvsignore	Thu Jun  5 10:39:07 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/crypto/crc32/configure.in
diff -c krb5/lib/crypto/crc32/configure.in:1.1.1.1 krb5/lib/crypto/crc32/configure.in:removed
*** krb5/lib/crypto/crc32/configure.in:1.1.1.1	Mon Jun  2 17:57:43 1997
--- krb5/lib/crypto/crc32/configure.in	Sun Mar 16 20:22:20 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/des/.cvsignore
diff -c /dev/null krb5/lib/crypto/des/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:21 2003
--- krb5/lib/crypto/des/.cvsignore	Thu Jun  5 10:39:08 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/crypto/des/.rconf
diff -c krb5/lib/crypto/des/.rconf:1.1.1.1 krb5/lib/crypto/des/.rconf:removed
*** krb5/lib/crypto/des/.rconf:1.1.1.1	Mon Jun  2 17:57:39 1997
--- krb5/lib/crypto/des/.rconf	Sun Mar 16 20:22:21 2003
***************
*** 1,8 ****
- ignore fp.c
- ignore ip.c
- ignore key_perm.h
- ignore odd.h
- ignore p.c
- ignore p_table.h
- ignore s_table.h
- ignore doc
--- 0 ----
Index: krb5/lib/crypto/des/FUNCTIONS
diff -c krb5/lib/crypto/des/FUNCTIONS:1.1.1.1 krb5/lib/crypto/des/FUNCTIONS:removed
*** krb5/lib/crypto/des/FUNCTIONS:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/FUNCTIONS	Sun Mar 16 20:22:21 2003
***************
*** 1,26 ****
- File		Function				Where?
- 
- weak_key.c	mit_des_is_weak_key			crypto
- string2key.c	mit_des_string_to_key			?
- random_key.c	mit_des_random_key			?
- process_ky.c	mit_des_process_key			?
- new_rn_key.c	mit_des_new_random_key			?
- 		mit_des_init_random_number_generator	?
- 		mit_des_set_random_generator_seed	?
- 		mit_des_set_sequence_number		?
- 		mit_des_generate_random_block		?
- krb_glue.c	mit_des_encrypt_func			?
- 		mit_des_decrypt_func			?
- key_sched.c	mit_des_key_sched			crypto
- key_parity.c	mit_des_fixup_key_parity		crypto
- 		mit_des_check_key_parity		crypto
- init_rkey.c	mit_des_init_random_key			crypto
- finish_key.c	mit_des_finish_key			crypto
- fin_rndkey.c	mit_des_finish_random_key		crypto
- enc_dec.c	mit_des_cbc_encrypt			crypto
- des.c		mit_des_ecb_encrypt			crypto
- cs_entry.c	(var) mit_des_cryptosystem_entry	krb5
- 		(var) krb5_des_cst_entry		krb5
- 		(var) mit_des_cbc_cksumtable_entry	krb5
- cksum.c		mit_des_cbc_cksum			crypto
- cbc_cksum.c	mit_des_cbc_checksum			crypto
--- 0 ----
Index: krb5/lib/crypto/des/cbc_cksum.c
diff -c krb5/lib/crypto/des/cbc_cksum.c:1.1.1.1 krb5/lib/crypto/des/cbc_cksum.c:removed
*** krb5/lib/crypto/des/cbc_cksum.c:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/cbc_cksum.c	Sun Mar 16 20:22:21 2003
***************
*** 1,157 ****
- /*
-  * lib/crypto/des/cbc_cksum.c
-  *
-  * Copyright 1985, 1986, 1987, 1988, 1990 by the Massachusetts Institute
-  * of Technology.
-  * All Rights Reserved.
-  *
-  * Under U.S. law, this software may not be exported outside the US
-  * without license from the U.S. Commerce department.
-  *
-  * These routines form the library interface to the DES facilities.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
- 	produces cbc cheksum of sequence "in" of the length "in_length" 
- 	with the help of key "key" of size "key_size" (which should be 8);
- 	fills out krb5_checksum structure.
- 
- 	caller is responsible for allocating & freeing "contents" element in 
- 	krb5_checksum structure.
- 
- 	returns: errors
- */
- 
- static krb5_error_code mit_des_cbc_checksum
-     PROTOTYPE((krb5_pointer, size_t,krb5_pointer,size_t, krb5_checksum FAR * ));
- 
- static krb5_error_code mit_des_cbc_verf_cksum
-     PROTOTYPE ((krb5_checksum FAR *, krb5_pointer, size_t, krb5_pointer,
-                 size_t ));
- 
- static krb5_error_code
- mit_des_cbc_checksum(in, in_length, key, key_size, cksum)
-     krb5_pointer in;
-     size_t in_length;
-     krb5_pointer key;
-     size_t key_size;
-     krb5_checksum FAR * cksum;
- {
-     struct mit_des_ks_struct       *schedule;      /* pointer to key schedules */
- 
-     if (cksum->length < sizeof(mit_des_cblock))
- 	return KRB5_BAD_MSIZE;
-     if (key_size != sizeof(mit_des_cblock))
- 	return KRB5_BAD_KEYSIZE;
- 
-     if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule))))
-         return ENOMEM;
- 
- #define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\
- 		    free( (char *) schedule); }
- 
-     switch (mit_des_key_sched ((krb5_octet *)key, schedule)) {
-     case -1:
-         cleanup();
-         return KRB5DES_BAD_KEYPAR;
- 
-     case -2:
-         cleanup();
-         return KRB5DES_WEAK_KEY;
- 
-     default:
-         ;
-     }
- 
-     cksum->checksum_type = CKSUMTYPE_DESCBC;
-     cksum->length = sizeof(mit_des_cblock);
-     mit_des_cbc_cksum(in, cksum->contents, in_length, schedule, key);
- 
-     cleanup();
- 
-     return 0;
- }
-     
- static krb5_error_code
- mit_des_cbc_verf_cksum(cksum, in, in_length, key, key_size)
-     krb5_checksum FAR * cksum;
-     krb5_pointer in;
-     size_t in_length;
-     krb5_pointer key;
-     size_t key_size;
- {
-     struct mit_des_ks_struct       *schedule;      /* pointer to key schedules */
-     mit_des_cblock	contents;
-     krb5_error_code	retval;
- 
-     if (key_size != sizeof(mit_des_cblock))
- 	return KRB5_BAD_KEYSIZE;
- 
-     if (!(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule))))
-         return ENOMEM;
- 
- #define cleanup() { memset((char *)schedule, 0, sizeof(mit_des_key_schedule));\
- 		    free( (char *) schedule); }
- 
-     switch (mit_des_key_sched ((krb5_octet *)key, schedule)) {
-     case -1:
-         cleanup();
-         return KRB5DES_BAD_KEYPAR;
- 
-     case -2:
-         cleanup();
-         return KRB5DES_WEAK_KEY;
- 
-     default:
-         ;
-     }
- 
-     mit_des_cbc_cksum(in, contents, in_length, schedule, key);
- 
-     retval = 0;
-     if (cksum->checksum_type == CKSUMTYPE_DESCBC) {
- 	if (cksum->length == sizeof(mit_des_cblock)) {
- 	    if (memcmp((char *) cksum->contents,
- 		       (char *) contents,
- 		       sizeof(mit_des_cblock)))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	}
- 	else
- 	    retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     }
-     else
- 	retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
-     cleanup();
- 
-     return retval;
- }
- 
- krb5_checksum_entry krb5_des_cbc_cksumtable_entry = {
-     0,
-     mit_des_cbc_checksum,
-     mit_des_cbc_verf_cksum,
-     sizeof(mit_des_cblock),
-     1,					/* is collision proof */
-     1,					/* is keyed */
- };
--- 0 ----
Index: krb5/lib/crypto/des/configure.in
diff -c krb5/lib/crypto/des/configure.in:1.1.1.1 krb5/lib/crypto/des/configure.in:removed
*** krb5/lib/crypto/des/configure.in:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/configure.in	Sun Mar 16 20:22:21 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- KRB5_RUN_FLAGS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/des/d3_ecb.c
diff -c krb5/lib/crypto/des/d3_ecb.c:1.1.1.1 krb5/lib/crypto/des/d3_ecb.c:removed
*** krb5/lib/crypto/des/d3_ecb.c:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/d3_ecb.c	Sun Mar 16 20:22:21 2003
***************
*** 1,48 ****
- /*
-  * Copyright 1995 by Richard P. Basch.  All Rights Reserved.
-  * Copyright 1995 by Lehman Brothers, Inc.  All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
-  * in advertising or publicity pertaining to distribution of the software
-  * without specific, written prior permission.  Richard P. Basch,
-  * Lehman Brothers and M.I.T. make no representations about the suitability
-  * of this software for any purpose.  It is provided "as is" without
-  * express or implied warranty.
-  */
- 
- #include "des.h"
- #include "des_int.h"
- #include "f_tables.h"
- 
- /*
-  * Triple-DES ECB encryption mode.
-  */
- 
- int
- mit_des3_ecb_encrypt(in, out, sched1, sched2, sched3, encrypt)
- 	const mit_des_cblock FAR *in;
- 	mit_des_cblock FAR *out;
- 	mit_des_key_schedule sched1, sched2, sched3;
- 	int encrypt;
- {
- 	if (encrypt) {
- 		mit_des_ecb_encrypt(in, out, sched1, encrypt);
- 		mit_des_ecb_encrypt(out, out, sched2, !encrypt);
- 		mit_des_ecb_encrypt(out, out, sched3, encrypt);
- 	} else {
- 		mit_des_ecb_encrypt(in, out, sched3, encrypt);
- 		mit_des_ecb_encrypt(out, out, sched2, !encrypt);
- 		mit_des_ecb_encrypt(out, out, sched1, encrypt);
- 	}
- 	return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/d3_procky.c
diff -c krb5/lib/crypto/des/d3_procky.c:1.1.1.1 krb5/lib/crypto/des/d3_procky.c:removed
*** krb5/lib/crypto/des/d3_procky.c:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/d3_procky.c	Sun Mar 16 20:22:21 2003
***************
*** 1,60 ****
- /*
-  * Copyright 1995 by Richard P. Basch.  All Rights Reserved.
-  * Copyright 1995 by Lehman Brothers, Inc.  All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
-  * in advertising or publicity pertaining to distribution of the software
-  * without specific, written prior permission.  Richard P. Basch,
-  * Lehman Brothers and M.I.T. make no representations about the suitability
-  * of this software for any purpose.  It is provided "as is" without
-  * express or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- krb5_error_code
- mit_des3_process_key (eblock, keyblock)
-     krb5_encrypt_block * eblock;
-     const krb5_keyblock * keyblock;
- {
-     struct mit_des_ks_struct       *schedule;      /* pointer to key schedules */
- 
-     if ((keyblock->enctype != ENCTYPE_DES3_CBC_SHA) &&
- 	(keyblock->enctype != ENCTYPE_DES3_CBC_RAW))
- 	return KRB5_PROG_ETYPE_NOSUPP;
- 
-     if (keyblock->length != sizeof (mit_des3_cblock))
- 	return KRB5_BAD_KEYSIZE;
- 
-     if ( !(schedule = (struct mit_des_ks_struct *) malloc(3*sizeof(mit_des_key_schedule))) )
-         return ENOMEM;
- #define cleanup() { free( (char *) schedule); }
- 
-     switch (mit_des3_key_sched (*(mit_des3_cblock *)keyblock->contents,
- 				*(mit_des3_key_schedule *)schedule)) {
-     case -1:
- 	cleanup();
- 	return KRB5DES_BAD_KEYPAR;
- 
-     case -2:
- 	cleanup();
- 	return KRB5DES_WEAK_KEY;
-     }
- 
-     eblock->key = (krb5_keyblock *) keyblock;
-     eblock->priv = (krb5_pointer) schedule;
-     eblock->priv_size = (krb5_int32) 3*sizeof(mit_des_key_schedule);
- 
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/d3_str2ky.c
diff -c krb5/lib/crypto/des/d3_str2ky.c:1.1.1.1 krb5/lib/crypto/des/d3_str2ky.c:removed
*** krb5/lib/crypto/des/d3_str2ky.c:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/d3_str2ky.c	Sun Mar 16 20:22:21 2003
***************
*** 1,137 ****
- /*
-  * Copyright 1995 by Richard P. Basch.  All Rights Reserved.
-  * Copyright 1995 by Lehman Brothers, Inc.  All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
-  * in advertising or publicity pertaining to distribution of the software
-  * without specific, written prior permission.  Richard P. Basch,
-  * Lehman Brothers and M.I.T. make no representations about the suitability
-  * of this software for any purpose.  It is provided "as is" without
-  * express or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
-  * Triple-DES string-to-key algorithm
-  *
-  * 168-fold the input string (appended with any salt), and treat the resulting
-  * 168 bits as three DES keys sans parity.  Process each set of 56 bits into
-  * a usable DES key with odd parity, and twice encrypt the set of three usable
-  * DES keys using Triple-DES CBC mode.  The result is then treated as three
-  * DES keys, and should be corrected for parity.  Any DES key that is weak or
-  * semi-weak is to be corrected by eXclusive-ORing with 00000000000000F0.
-  */
- 
- static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 };
- 
- krb5_error_code
- mit_des3_string_to_key (eblock, keyblock, data, salt)
- const krb5_encrypt_block FAR * eblock;
- krb5_keyblock FAR * keyblock;
- const krb5_data FAR * data;
- const krb5_data FAR * salt;
- {
-     char *copystr;
-     mit_des_cblock *key;
-     unsigned int j;
- 
-     int length;
-     mit_des3_key_schedule ks;
-     krb5_enctype enctype = eblock->crypto_entry->proto_enctype;
- 
-     if ((enctype == ENCTYPE_DES3_CBC_SHA) ||
- 	(enctype == ENCTYPE_DES3_CBC_RAW))
- 	keyblock->length = sizeof(mit_des3_cblock);
-     else
- 	return (KRB5_PROG_ETYPE_NOSUPP);
- 
-     if ( !(keyblock->contents = (krb5_octet *)malloc(keyblock->length)) )
- 	return(ENOMEM);
- 
-     keyblock->magic = KV5M_KEYBLOCK;
-     keyblock->enctype = enctype;
-     key = (mit_des_cblock *)keyblock->contents;
- 
-     if (salt)
- 	length = data->length + salt->length;
-     else
- 	length = data->length;
- 
-     if (length < keyblock->length)
- 	length = keyblock->length;
- 
-     copystr = malloc((size_t) length);
-     if (!copystr) {
- 	free(keyblock->contents);
- 	keyblock->contents = 0;
- 	return ENOMEM;
-     }
- 
-     memset(copystr, 0, length);
-     memcpy(copystr, (char *) data->data, data->length);
-     if (salt)
- 	memcpy(copystr + data->length, (char *)salt->data, salt->length);
- 
-     /* n-fold into des3 key sans parity */
-     if (mit_des_n_fold(copystr, length, keyblock->contents,
- 		       keyblock->length * 7 / 8))
- 	return EINVAL;
- 
-     /* Add space for parity (low bit) */
-     for (j = keyblock->length; j--; ) {
- 	register int k;
- 
- 	k = (8-(j%8)) & 7;
- 	keyblock->contents[j] =
- 	    ((keyblock->contents[j*7/8] << k) & 0xfe) +
- 	    ((k>1) ? keyblock->contents[j*7/8 +1] >> (8-k) : 0);
-     }
- 	
-     /* fix key parity */
-     for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) {
- 	mit_des_fixup_key_parity(key[j]);
- 	if (mit_des_is_weak_key(key[j]))
- 	    ((krb5_octet *)(key[j]))[7] ^= 0xf0;
-     }
- 
-     /* Now, CBC encrypt with itself */
-     (void) mit_des3_key_sched(*((mit_des3_cblock *)key), ks);
-     (void) mit_des3_cbc_encrypt(key, key, keyblock->length,
- 				((mit_des_key_schedule *)ks)[0],
- 				((mit_des_key_schedule *)ks)[1],
- 				((mit_des_key_schedule *)ks)[2],
- 				zero_ivec, TRUE);
-     (void) mit_des3_cbc_encrypt(key, key, keyblock->length,
- 				((mit_des_key_schedule *)ks)[0],
- 				((mit_des_key_schedule *)ks)[1],
- 				((mit_des_key_schedule *)ks)[2],
- 				key[2], TRUE);
- 
-     /* erase key_sked */
-     memset((char *)ks, 0, sizeof(ks));
- 
-     /* clean & free the input string */
-     memset(copystr, 0, (size_t) length);
-     krb5_xfree(copystr);
- 
-     /* now fix up key parity again */
-     for (j = 0; j < keyblock->length/sizeof(mit_des_cblock); j++) {
- 	mit_des_fixup_key_parity(key[j]);
- 	if (mit_des_is_weak_key(key[j]))
- 	    ((krb5_octet *)(key[j]))[7] ^= 0xf0;
-     }
- 
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/des.h
diff -c krb5/lib/crypto/des/des.h:1.1.1.1 krb5/lib/crypto/des/des.h:removed
*** krb5/lib/crypto/des/des.h:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/des.h	Sun Mar 16 20:22:21 2003
***************
*** 1,53 ****
- /*
-  * include/des.h
-  *
-  * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
-  *
-  * For copying and distribution information, please see the file
-  * <mit-copyright.h>.
-  *
-  * Include file for the Data Encryption Standard library.
-  */
- 
- /* only do the whole thing once	 */
- #ifndef DES_DEFS
- #define DES_DEFS
- 
- #include "k5-int.h"
- 
- #ifndef KRB_INT32
- #if (SIZEOF_LONG == 4)
- #define KRB_INT32 long
- #elif (SIZEOF_INT == 4)
- #define KRB_INT32 int
- #elif (SIZEOF_SHORT == 4)
- #define KRB_INT32 short
- #else
-   ?== No 32 bit type available
- #endif
- #endif /* !KRB_INT32 */
- #ifndef KRB_UINT32
- #define KRB_UINT32 unsigned KRB_INT32
- #endif
- 
- #ifndef NCOMPAT
- #define C_Block des_cblock
- #define Key_schedule des_key_schedule
- #define ENCRYPT DES_ENCRYPT
- #define DECRYPT DES_DECRYPT
- #define KEY_SZ DES_KEY_SZ
- #define string_to_key des_string_to_key
- #define read_pw_string des_read_pw_string
- #define random_key des_random_key
- #define pcbc_encrypt des_pcbc_encrypt
- #define key_sched des_key_sched
- #define cbc_encrypt des_cbc_encrypt
- #define cbc_cksum des_cbc_cksum
- #define C_Block_print des_cblock_print
- #define quad_cksum des_quad_cksum
- typedef struct des_ks_struct bit_64;
- #endif
- 
- #define des_cblock_print(x) des_cblock_print_file(x, stdout)
- 
- #endif /* DES_DEFS */
--- 0 ----
Index: krb5/lib/crypto/des/f_README
diff -c krb5/lib/crypto/des/f_README:1.1.1.1 krb5/lib/crypto/des/f_README:removed
*** krb5/lib/crypto/des/f_README:1.1.1.1	Mon Jun  2 17:57:40 1997
--- krb5/lib/crypto/des/f_README	Sun Mar 16 20:22:21 2003
***************
*** 1,69 ****
- /*
-  * Copyright (c) 1990 Dennis Ferguson.  All rights reserved.
-  *
-  * Commercial use is permitted only if products which are derived from
-  * or include this software are made available for purchase and/or use
-  * in Canada.  Otherwise, redistribution and use in source and binary
-  * forms are permitted.
-  */
- 
- Sorry about the poor quality of installation instructions.  Included
- here are replacements for the DES portions of Eric Young's kerberos
- DES library replacement.  To use this you will need his distribution.
- Untar the latter and:
- 
- (1) Copy all .c and .h files into the distribution directory.  This will
-     overwrite some files and add others.
- 
- (2) Apply the patch included here to set_key.c in the distribution directory.
- 
- (3) Edit the Imakefile (or the Makefile) to include the following files
-     on the SRCS= line:
- 
- 	des_tables.c ecb_buffer.c make_sched.c
- 
-     Add the following files to the OBJS= line:
- 
- 	des_tables.o ecb_buffer.o make_sched.o
- 
-     Add the following file to the CODE= line:
- 
- 	des_tables.h
- 
- Recompile and you're done.
- 
- The salient differences between this DES and Eric Young's are as follows:
- 
- (1) There are no dependencies on byte ordering, the ability to do
-     unaligned loads and stores, or any other machine dependencies
-     that I know of.  There are no #ifdef's.  The code could probably
-     be made faster by adding such things, but not enough to be worth
-     it.
- 
- (2) Combined S and P tables are used for the inner loop of the cipher
-     routine and the E expansion is computed on the fly, like Eric
-     Young's code, but the computation is reordered from the standard
-     to save instructions.
- 
- (3) The initial and final permutations are table driven, and take
-     about the same amount of work as a single round of the inner
-     loop (i.e. only about 12% of the work done for an ecb encryption
-     is spent in the IP and FP code).
- 
- (4) Since NTP (for which this DES was originally implemented) uses
-     lots of keys to encrypt small things, the key permutation code
-     has been well worked over and is quite speedy (the amount of
-     work required to permute a key is on the order of that required
-     to do a single ECB encryption, more or less).
- 
- (5) Since the code required to do an ECB encryption using the tables
-     is actually fairly compact, even with lots of inlining, it was
-     implemented as a macro and is expanded in situ where needed.
- 
- On the one machine I ran a comparison on this code ran 80% faster than
- Eric's, compiled into a slightly smaller space, and did pass destest.
- I suspect this stuff is also faster, and not a lot larger, than the
- library MIT doesn't export with kerberos.  You mileage may vary.
- 
- The silly copyright was a (probably ineffective) afterthought.  If it
- really inconveniences you give me a call.
--- 0 ----
Index: krb5/lib/crypto/des/f_ecb.c
diff -c krb5/lib/crypto/des/f_ecb.c:1.1.1.1 krb5/lib/crypto/des/f_ecb.c:removed
*** krb5/lib/crypto/des/f_ecb.c:1.1.1.1	Mon Jun  2 17:57:41 1997
--- krb5/lib/crypto/des/f_ecb.c	Sun Mar 16 20:22:21 2003
***************
*** 1,96 ****
- /*
-  * Copyright (c) 1990 Dennis Ferguson.  All rights reserved.
-  *
-  * Commercial use is permitted only if products which are derived from
-  * or include this software are made available for purchase and/or use
-  * in Canada.  Otherwise, redistribution and use in source and binary
-  * forms are permitted.
-  */
- 
- /*
-  * des_ecb_encrypt.c - do an encryption in ECB mode
-  */
- #include "des.h"
- #include "des_int.h"
- #include "f_tables.h"
- 
- /*
-  * des_ecb_encrypt - {en,de}crypt a block in ECB mode
-  */
- int
- mit_des_ecb_encrypt(in, out, schedule, encrypt)
- 	const mit_des_cblock *in;
- 	mit_des_cblock *out;
- 	mit_des_key_schedule schedule;
- 	int encrypt;
- {
- 	register unsigned KRB_INT32 left, right;
- 	register unsigned KRB_INT32 temp;
- 	register int i;
- 
- 	{
- 		/*
- 		 * Need a temporary for copying the data in
- 		 */
- 		register unsigned char *datap;
- 
- 		/*
- 		 * Copy the input block into the registers
- 		 */
- 		datap = (unsigned char *)in;
- 		GET_HALF_BLOCK(left, datap);
- 		GET_HALF_BLOCK(right, datap);
- 	}
- 
- 	/*
- 	 * Do the initial permutation.
- 	 */
- 	DES_INITIAL_PERM(left, right, temp);
- 
- 	/*
- 	 * Now the rounds.  Use different code depending on whether it
- 	 * is an encryption or a decryption (gross, should keep both
- 	 * sets of keys in the key schedule instead).
- 	 */
- 	if (encrypt) {
- 		register unsigned KRB_INT32 *kp;
- 
- 		kp = (unsigned KRB_INT32 *)schedule;
- 		for (i = 0; i < 8; i++) {
- 			DES_SP_ENCRYPT_ROUND(left, right, temp, kp);
- 			DES_SP_ENCRYPT_ROUND(right, left, temp, kp);
- 		}
- 	} else {
- 		register unsigned KRB_INT32 *kp;
- 
- 		/*
- 		 * Point kp past end of schedule
- 		 */
- 		kp = ((unsigned KRB_INT32 *)schedule) + (2 * 16);;
- 		for (i = 0; i < 8; i++) {
- 			DES_SP_DECRYPT_ROUND(left, right, temp, kp);
- 			DES_SP_DECRYPT_ROUND(right, left, temp, kp);
- 		}
- 	}
- 
- 	/*
- 	 * Do the final permutation
- 	 */
- 	DES_FINAL_PERM(left, right, temp);
- 
- 	/*
- 	 * Finally, copy the result out a byte at a time
- 	 */
- 	{
- 		register unsigned char *datap;
- 
- 		datap = (unsigned char *)out;
- 		PUT_HALF_BLOCK(left, datap);
- 		PUT_HALF_BLOCK(right, datap);
- 	}
- 
- 	/*
- 	 * return nothing
- 	 */
- 	return (0);
- }
--- 0 ----
Index: krb5/lib/crypto/des/f_pcbc.c
diff -c krb5/lib/crypto/des/f_pcbc.c:1.1.1.1 krb5/lib/crypto/des/f_pcbc.c:removed
*** krb5/lib/crypto/des/f_pcbc.c:1.1.1.1	Mon Jun  2 17:57:41 1997
--- krb5/lib/crypto/des/f_pcbc.c	Sun Mar 16 20:22:21 2003
***************
*** 1,208 ****
- /*
-  * Copyright (c) 1990 Dennis Ferguson.  All rights reserved.
-  *
-  * Commercial use is permitted only if products which are derived from
-  * or include this software are made available for purchase and/or use
-  * in Canada.  Otherwise, redistribution and use in source and binary
-  * forms are permitted.
-  */
- 
- /*
-  * des_pcbc_encrypt.c - encrypt a string of characters in error propagation mode
-  */
- #include "des.h"
- #include "des_int.h"
- #include "f_tables.h"
- 
- /*
-  * des_pcbc_encrypt - {en,de}crypt a stream in PCBC mode
-  */
- int
- mit_des_pcbc_encrypt(in, out, length, schedule, ivec, encrypt)
- 	mit_des_cblock *in;
- 	mit_des_cblock *out;
- 	long length;
- 	mit_des_key_schedule schedule;
- 	mit_des_cblock ivec;
- 	int encrypt;
- {
- 	register unsigned KRB_INT32 left, right;
- 	register unsigned KRB_INT32 temp;
- 	register unsigned KRB_INT32 *kp;
- 	register unsigned char *ip, *op;
- 
- 	/*
- 	 * Copy the key pointer, just once
- 	 */
- 	kp = (unsigned KRB_INT32 *)schedule;
- 
- 	/*
- 	 * Deal with encryption and decryption separately.
- 	 */
- 	if (encrypt) {
- 		register unsigned KRB_INT32 plainl;
- 		register unsigned KRB_INT32 plainr;
- 
- 		/*
- 		 * Initialize left and right with the contents of the initial
- 		 * vector.
- 		 */
- 		ip = (unsigned char *)ivec;
- 		GET_HALF_BLOCK(left, ip);
- 		GET_HALF_BLOCK(right, ip);
- 
- 		/*
- 		 * Suitably initialized, now work the length down 8 bytes
- 		 * at a time.
- 		 */
- 		ip = (unsigned char *)in;
- 		op = (unsigned char *)out;
- 		while (length > 0) {
- 			/*
- 			 * Get block of input.  If the length is
- 			 * greater than 8 this is straight
- 			 * forward.  Otherwise we have to fart around.
- 			 */
- 			if (length > 8) {
- 				GET_HALF_BLOCK(plainl, ip);
- 				GET_HALF_BLOCK(plainr, ip);
- 				left ^= plainl;
- 				right ^= plainr;
- 				length -= 8;
- 			} else {
- 				/*
- 				 * Oh, shoot.  We need to pad the
- 				 * end with zeroes.  Work backwards
- 				 * to do this.  We know this is the
- 				 * last block, though, so we don't have
- 				 * to save the plain text.
- 				 */
- 				ip += (int) length;
- 				switch(length) {
- 				case 8:
- 					right ^=  *(--ip) & FF_UINT32;
- 				case 7:
- 					right ^= (*(--ip) & FF_UINT32) <<  8;
- 				case 6:
- 					right ^= (*(--ip) & FF_UINT32) << 16;
- 				case 5:
- 					right ^= (*(--ip) & FF_UINT32) << 24;
- 				case 4:
- 					left  ^=  *(--ip) & FF_UINT32;
- 				case 3:
- 					left  ^= (*(--ip) & FF_UINT32) <<  8;
- 				case 2:
- 					left  ^= (*(--ip) & FF_UINT32) << 16;
- 				case 1:
- 					left  ^= (*(--ip) & FF_UINT32) << 24;
- 					break;
- 				}
- 				length = 0;
- 			}
- 
- 			/*
- 			 * Encrypt what we have
- 			 */
- 			DES_DO_ENCRYPT(left, right, temp, kp);
- 
- 			/*
- 			 * Copy the results out
- 			 */
- 			PUT_HALF_BLOCK(left, op);
- 			PUT_HALF_BLOCK(right, op);
- 
- 			/*
- 			 * Xor with the old plain text
- 			 */
- 			left ^= plainl;
- 			right ^= plainr;
- 		}
- 	} else {
- 		/*
- 		 * Decrypting is harder than encrypting because of
- 		 * the necessity of remembering a lot more things.
- 		 * Should think about this a little more...
- 		 */
- 		unsigned KRB_INT32 ocipherl, ocipherr;
- 		unsigned KRB_INT32 cipherl, cipherr;
- 
- 		if (length <= 0)
- 			return 0;
- 
- 		/*
- 		 * Prime the old cipher with ivec.
- 		 */
- 		ip = (unsigned char *)ivec;
- 		GET_HALF_BLOCK(ocipherl, ip);
- 		GET_HALF_BLOCK(ocipherr, ip);
- 
- 		/*
- 		 * Now do this in earnest until we run out of length.
- 		 */
- 		ip = (unsigned char *)in;
- 		op = (unsigned char *)out;
- 		for (;;) {		/* check done inside loop */
- 			/*
- 			 * Read a block from the input into left and
- 			 * right.  Save this cipher block for later.
- 			 */
- 			GET_HALF_BLOCK(left, ip);
- 			GET_HALF_BLOCK(right, ip);
- 			cipherl = left;
- 			cipherr = right;
- 
- 			/*
- 			 * Decrypt this.
- 			 */
- 			DES_DO_DECRYPT(left, right, temp, kp);
- 
- 			/*
- 			 * Xor with the old cipher to get plain
- 			 * text.  Output 8 or less bytes of this.
- 			 */
- 			left ^= ocipherl;
- 			right ^= ocipherr;
- 			if (length > 8) {
- 				length -= 8;
- 				PUT_HALF_BLOCK(left, op);
- 				PUT_HALF_BLOCK(right, op);
- 				/*
- 				 * Save current cipher block here
- 				 */
- 				ocipherl = cipherl ^ left;
- 				ocipherr = cipherr ^ right;
- 			} else {
- 				/*
- 				 * Trouble here.  Start at end of output,
- 				 * work backwards.
- 				 */
- 				op += (int) length;
- 				switch(length) {
- 				case 8:
- 					*(--op) = (unsigned char) (right & 0xff);
- 				case 7:
- 					*(--op) = (unsigned char) ((right >> 8) & 0xff);
- 				case 6:
- 					*(--op) = (unsigned char) ((right >> 16) & 0xff);
- 				case 5:
- 					*(--op) = (unsigned char) ((right >> 24) & 0xff);
- 				case 4:
- 					*(--op) = (unsigned char) (left & 0xff);
- 				case 3:
- 					*(--op) = (unsigned char) ((left >> 8) & 0xff);
- 				case 2:
- 					*(--op) = (unsigned char) ((left >> 16) & 0xff);
- 				case 1:
- 					*(--op) = (unsigned char) ((left >> 24) & 0xff);
- 					break;
- 				}
- 				break;		/* we're done */
- 			}
- 		}
- 	}
- 
- 	/*
- 	 * Done, return nothing.
- 	 */
- 	return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/fin_rndkey.c
diff -c krb5/lib/crypto/des/fin_rndkey.c:1.1.1.1 krb5/lib/crypto/des/fin_rndkey.c:removed
*** krb5/lib/crypto/des/fin_rndkey.c:1.1.1.1	Mon Jun  2 17:57:41 1997
--- krb5/lib/crypto/des/fin_rndkey.c	Sun Mar 16 20:22:21 2003
***************
*** 1,51 ****
- /*
-  * lib/crypto/des/fin_rndkey.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * Copyright 1996 by Lehman Brothers, Inc.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. or Lehman Brothers not be used in advertising or
-  * publicity pertaining to distribution of the software without
-  * specific, written prior permission.  M.I.T. and Lehman Brothers
-  * make no representations about the suitability of this software for
-  * any purpose.  It is provided "as is" without express or implied
-  * warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
-         free any resources held by "seed" and assigned by init_random_key()
-  */
- 
- krb5_error_code mit_des_finish_random_key (eblock, p_state)
-     const krb5_encrypt_block * eblock;
-     krb5_pointer * p_state;
- {
-     mit_des_random_state * state = *p_state;
- 
-     if (! state) return 0;
- 
-     if (state->sequence.data) {
- 	memset((char *)state->sequence.data, 0, state->sequence.length);
- 	krb5_xfree(state->sequence.data);
-     }
- 
-     mit_des_finish_key(&state->eblock);
- 
-     krb5_xfree(state);
-     *p_state = 0;
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/finish_key.c
diff -c krb5/lib/crypto/des/finish_key.c:1.1.1.1 krb5/lib/crypto/des/finish_key.c:removed
*** krb5/lib/crypto/des/finish_key.c:1.1.1.1	Mon Jun  2 17:57:41 1997
--- krb5/lib/crypto/des/finish_key.c	Sun Mar 16 20:22:21 2003
***************
*** 1,48 ****
- /*
-  * lib/crypto/des/finish_key.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
- 	does any necessary clean-up on the eblock (such as releasing
- 	resources held by eblock->priv).
- 
- 	returns: errors
-  */
- 
- krb5_error_code
- mit_des_finish_key (eblock)
-     krb5_encrypt_block FAR * eblock;
- {
-     if (eblock->priv) {
- 	memset((char *)eblock->priv, 0, (size_t) eblock->priv_size);
- 	free(eblock->priv);
-     }
-     eblock->priv = 0;
-     eblock->priv_size = 0;
-     /* free/clear other stuff here? */
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/init_rkey.c
diff -c krb5/lib/crypto/des/init_rkey.c:1.1.1.1 krb5/lib/crypto/des/init_rkey.c:removed
*** krb5/lib/crypto/des/init_rkey.c:1.1.1.1	Mon Jun  2 17:57:41 1997
--- krb5/lib/crypto/des/init_rkey.c	Sun Mar 16 20:22:21 2003
***************
*** 1,161 ****
- /*
-  * lib/crypto/des/init_rkey.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
-         initialize the random key generator using the encryption key,
-         "seedblock", and allocating private sequence information, filling
-         in "seed" with the address of such information.
-         "seed" is later passed to the random_key() function to provide
-         sequence information.
-  */
- 
- #ifndef min
- #define min(a,b) (((a) > (b)) ? (b) : (a))
- #endif
- 
- krb5_error_code
- mit_des_init_random_key (eblock, seedblock, state)
-     const krb5_encrypt_block * eblock;
-     const krb5_keyblock * seedblock;
-     krb5_pointer * state;
- {
-     mit_des_random_state * p_state = 0;
-     krb5_keyblock *new_key;
-     krb5_enctype enctype = eblock->crypto_entry->proto_enctype;
-     krb5_error_code kret = 0;
-     krb5_address **addrs = 0;
-     krb5_data seed;
-     struct tval {
- 	krb5_int32 seconds;
- 	krb5_int32 microseconds;
-     } timenow;
- 
-     switch (enctype)
-     {
-     case ENCTYPE_DES_CBC_CRC:
-     case ENCTYPE_DES_CBC_MD4:
-     case ENCTYPE_DES_CBC_MD5:
-     case ENCTYPE_DES_CBC_RAW:
- 	enctype = ENCTYPE_DES_CBC_RAW;
- 	break;
- 
-     case ENCTYPE_DES3_CBC_SHA:
-     case ENCTYPE_DES3_CBC_RAW:
- 	enctype = ENCTYPE_DES3_CBC_RAW;
- 	break;
- 
-     default:
- 	return KRB5_BAD_ENCTYPE;
-     }
- 
-     p_state = (mit_des_random_state *) malloc(sizeof(mit_des_random_state));
-     *state = (krb5_pointer) p_state;
- 
-     if (! p_state) {
- 	kret = ENOMEM;
- 	goto cleanup;
-     }
- 
-     memset(p_state, 0, sizeof(*p_state));
-     p_state->eblock.crypto_entry = krb5_enctype_array[enctype]->system;
-     p_state->sequence.length = p_state->eblock.crypto_entry->keysize;
-     p_state->sequence.data = (krb5_pointer) malloc(p_state->sequence.length);
- 
-     if (! p_state->sequence.data) {
- 	kret = ENOMEM;
- 	goto cleanup;
-     }
- 
-     /*
-      * Generate a temporary value that is based on the
-      * input seed and the hostid (sequence number)
-      * such that it gives no useful information about the input.
-      *
-      * Then use the temporary value as the new seed and the current
-      * time as a sequence number to give us a stream that was not
-      * previously used.
-      *
-      * This result will be the seed for the random number stream
-      * (the sequence number will start at zero).
-      */
- 
-     /* seed = input */
-     seed.data = seedblock->contents;
-     seed.length = seedblock->length;
-     kret = mit_des_set_random_generator_seed(&seed, p_state);
-     if (kret) goto cleanup;
- 
-     /* sequence = hostid */
-     if (!krb5_crypto_os_localaddr(&addrs) && addrs && *addrs) {
- 	memcpy((char *)p_state->sequence.data, (char *)addrs[0]->contents,
- 	      min(p_state->sequence.length, addrs[0]->length));
- 	/* XXX may not do all of the sequence number. */
-     }
-     if (addrs) {
- 	/* can't use krb5_free_addresses due to circular dependencies in
- 	   libraries */
- 	register krb5_address **addr2;
- 	for (addr2 = addrs; *addr2; addr2++) {
- 	    krb5_xfree((*addr2)->contents);
- 	    krb5_xfree(*addr2);
- 	}
- 	krb5_xfree(addrs);
-     }
- 
-     /* tmp.seed = random(input,hostid) */
-     kret = mit_des_random_key(NULL, p_state, &new_key);
-     if (kret) goto cleanup;
-     seed.data = new_key->contents;
-     seed.length = new_key->length;
-     kret = mit_des_set_random_generator_seed(&seed, p_state);
-     (void) memset(new_key->contents, 0, new_key->length);
-     krb5_xfree(new_key->contents);
-     krb5_xfree(new_key);
-     if (kret) goto cleanup;
- 
-     /* sequence = time */
-     (void) krb5_crypto_us_timeofday(&timenow.seconds,
- 				    &timenow.microseconds);
-     memcpy((char *)p_state->sequence.data, (char *)&timenow, sizeof(timenow));
- 
-     /* seed = random(tmp.seed, time) */
-     kret = mit_des_random_key(NULL, p_state, &new_key);
-     if (kret) goto cleanup;
-     seed.data = new_key->contents;
-     seed.length = new_key->length;
-     kret = mit_des_set_random_generator_seed(&seed, p_state);
-     (void) memset(new_key->contents, 0, new_key->length);
-     krb5_xfree(new_key->contents);
-     krb5_xfree(new_key);
-     if (kret) goto cleanup;
-     
-     return 0;
- 
- cleanup:
-     if (kret)
- 	mit_des_finish_random_key(eblock, state);
-     return kret;
- }
--- 0 ----
Index: krb5/lib/crypto/des/process_ky.c
diff -c krb5/lib/crypto/des/process_ky.c:1.1.1.1 krb5/lib/crypto/des/process_ky.c:removed
*** krb5/lib/crypto/des/process_ky.c:1.1.1.1	Mon Jun  2 17:57:42 1997
--- krb5/lib/crypto/des/process_ky.c	Sun Mar 16 20:22:21 2003
***************
*** 1,70 ****
- /*
-  * lib/crypto/des/process_ky.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- /*
-         does any necessary key preprocessing (such as computing key
-                 schedules for DES).
-         eblock->crypto_entry must be set by the caller; the other elements
-         of eblock are to be assigned by this function.
-         [in particular, eblock->key must be set by this function if the key
-         is needed in raw form by the encryption routine]
- 
-         The caller may not move or reallocate "keyblock" before calling
-         finish_key on "eblock"
- 
-         returns: errors
-  */
- 
- krb5_error_code
- mit_des_process_key (eblock, keyblock)
-     krb5_encrypt_block * eblock;
-     const krb5_keyblock * keyblock;
- {
-     struct mit_des_ks_struct       *schedule;      /* pointer to key schedules */
-     
-     if (keyblock->length != sizeof (mit_des_cblock))
- 	return KRB5_BAD_KEYSIZE;
- 
-     if ( !(schedule = (struct mit_des_ks_struct *) malloc(sizeof(mit_des_key_schedule))) )
-         return ENOMEM;
- #define cleanup() { free( (char *) schedule); }
- 
-     switch (mit_des_key_sched (keyblock->contents, schedule)) {
-     case -1:
- 	cleanup();
- 	return KRB5DES_BAD_KEYPAR;
- 
-     case -2:
- 	cleanup();
- 	return KRB5DES_WEAK_KEY;
- 
-     default:
- 	eblock->key = (krb5_keyblock *) keyblock;
- 	eblock->priv = (krb5_pointer) schedule;
- 	eblock->priv_size = (krb5_int32) sizeof(mit_des_key_schedule);
- 	return 0;
-     }
- }
--- 0 ----
Index: krb5/lib/crypto/des/random_key.c
diff -c krb5/lib/crypto/des/random_key.c:1.1.1.1 krb5/lib/crypto/des/random_key.c:removed
*** krb5/lib/crypto/des/random_key.c:1.1.1.1	Mon Jun  2 17:57:42 1997
--- krb5/lib/crypto/des/random_key.c	Sun Mar 16 20:22:21 2003
***************
*** 1,95 ****
- /*
-  * lib/crypto/des/random_key.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * Copyright 1996 by Lehman Brothers, Inc.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. or Lehman Brothers not be used in advertising or
-  * publicity pertaining to distribution of the software without
-  * specific, written prior permission.  M.I.T. and Lehman Brothers
-  * make no representations about the suitability of this software for
-  * any purpose.  It is provided "as is" without express or implied
-  * warranty.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- static void mit_des_generate_random_key
- 	PROTOTYPE((mit_des_random_state * state, krb5_keyblock * randkey));
- 
- 
- /*
-         generate a random encryption key, allocating storage for it and
-         filling in the keyblock address in *keyblock
-  */
- 
- krb5_error_code
- mit_des_random_key (eblock, state, keyblock)
-     const krb5_encrypt_block * eblock;
-     krb5_pointer state;
-     krb5_keyblock ** keyblock;
- {
-     krb5_keyblock *randkey;
-     int keysize = ((mit_des_random_state *)state)->eblock.crypto_entry->keysize;
- 
-     if (eblock == NULL)
- 	/* We are being called from the random number initialization routine */
- 	eblock = &((mit_des_random_state *)state)->eblock;
- 
-     if (!(randkey = (krb5_keyblock *)malloc(sizeof(*randkey))))
- 	return ENOMEM;
-     if (!(randkey->contents = (krb5_octet *)malloc(keysize))) {
- 	krb5_xfree(randkey);
- 	return ENOMEM;
-     }
-     randkey->magic = KV5M_KEYBLOCK;
-     randkey->length = keysize;
-     randkey->enctype = eblock->crypto_entry->proto_enctype;
- 
-     do {
- 	mit_des_generate_random_key(state, randkey);
- 	mit_des_fixup_keyblock_parity(randkey);
-     } while (mit_des_is_weak_keyblock(randkey));
- 
-     *keyblock = randkey;
-     return 0;
- }
- 
- static mit_des_cblock zero_ivec = { 0, 0, 0, 0, 0, 0, 0, 0 };
- 
- static void
- mit_des_generate_random_key(state, randkey)
-     mit_des_random_state * state;
-     krb5_keyblock * randkey;
- {
-     krb5_encrypt_block *eblock = &state->eblock;
-     int i;
- 
-     (* state->eblock.crypto_entry->encrypt_func)
- 	(state->sequence.data /*in*/, randkey->contents /*out*/,
- 	 state->sequence.length, eblock, zero_ivec);
-     if (state->sequence.length > sizeof(mit_des_cblock))
- 	(* state->eblock.crypto_entry->encrypt_func)
- 	    (randkey->contents /*in*/, randkey->contents /*out*/,
- 	     randkey->length, eblock,
- 	     randkey->contents + randkey->length - sizeof(mit_des_cblock));
- 
-     /* Increment the sequence number, with wraparound (LSB) */
-     for (i = 0; i < state->sequence.length; i++) {
- 	state->sequence.data[i] = (state->sequence.data[i] + 1) & 0xff;
- 	if (state->sequence.data[i])
- 	    break;
-     }
- }
--- 0 ----
Index: krb5/lib/crypto/des/t_random.c
diff -c krb5/lib/crypto/des/t_random.c:1.1.1.1 krb5/lib/crypto/des/t_random.c:removed
*** krb5/lib/crypto/des/t_random.c:1.1.1.1	Mon Jun  2 17:57:42 1997
--- krb5/lib/crypto/des/t_random.c	Sun Mar 16 20:22:21 2003
***************
*** 1,118 ****
- /*
-  * lib/crypto/des/t_random.c
-  *
-  * Copyright 1996 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * Test a DES implementation against known inputs & outputs
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- #include <stdio.h>
- #include "com_err.h"
- 
- extern krb5_cryptosystem_entry mit_des_cryptosystem_entry;
- 
- char *progname;
- int nflag = 2;
- int vflag;
- int mflag;
- int zflag;
- int pid;
- int mit_des_debug;
- 
- krb5_data kdata;
- 
- unsigned char key2[8] = { 0x08,0x19,0x2a,0x3b,0x4c,0x5d,0x6e,0x7f };
- unsigned char zerokey[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- 
- void print_key(key)
- 	krb5_keyblock *key;
- {
- 	int 	i;
- 
- 	printf("key type: %d, length = %d, contents =", key->enctype,
- 	       key->length);
- 	for (i=0; i < key->length; i++) {
- 		printf(" %02x", key->contents[i]);
- 	}
- 	printf("\n");
- }
- 
- /*
-  * Can also add :
-  * plaintext = 0, key = 0, cipher = 0x8ca64de9c1b123a7 (or is it a 1?)
-  */
- 
- void
- main(argc,argv)
-     int argc;
-     char *argv[];
- {
-     /* Local Declarations */
-     krb5_context context;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock, *randkey;
-     void *random_seed = 0;
- 
- #ifdef WINDOWS
-     /* Set screen window buffer to infinite size -- MS default is tiny.  */
-     _wsetscreenbuf (fileno (stdout), _WINBUFINF);
- #endif
- 
-     /* do some initialisation */
-     krb5_init_context(&context);
-     krb5_init_ets(context);
- 
-     krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_CRC);
-     keyblock.enctype = ENCTYPE_DES_CBC_CRC;
-     keyblock.length = sizeof(mit_des_cblock);
- 
-     keyblock.contents = key2;
- 
-     printf("init_random: ");
-     print_key(&keyblock);
-     krb5_init_random_key(context, &eblock, &keyblock, &random_seed);
-     krb5_random_key(context, &eblock, random_seed, &randkey);
-     print_key(randkey);
-     krb5_free_keyblock(context, randkey);
-     krb5_random_key(context, &eblock, random_seed, &randkey);
-     print_key(randkey);
-     krb5_free_keyblock(context, randkey);
-     krb5_finish_random_key(context, &eblock, &random_seed);
- 
-     keyblock.contents = zerokey;
- 
-     printf("\n\ninit_random: ");
-     print_key(&keyblock);
- 
-     krb5_init_random_key(context, &eblock, &keyblock, &random_seed);
-     krb5_random_key(context, &eblock, random_seed, &randkey);
-     print_key(randkey);
-     krb5_free_keyblock(context, randkey);
-     krb5_random_key(context, &eblock, random_seed, &randkey);
-     print_key(randkey);
-     krb5_free_keyblock(context, randkey);
-     krb5_finish_random_key(context, &eblock, &random_seed);
- 
-     krb5_free_context(context);
- }
- 
--- 0 ----
Index: krb5/lib/crypto/des/u_nfold.c
diff -c krb5/lib/crypto/des/u_nfold.c:1.1.1.1 krb5/lib/crypto/des/u_nfold.c:removed
*** krb5/lib/crypto/des/u_nfold.c:1.1.1.1	Mon Jun  2 17:57:42 1997
--- krb5/lib/crypto/des/u_nfold.c	Sun Mar 16 20:22:21 2003
***************
*** 1,99 ****
- /*
-  * Copyright 1995 by Richard P. Basch.  All Rights Reserved.
-  * Copyright 1995 by Lehman Brothers, Inc.  All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
-  * in advertising or publicity pertaining to distribution of the software
-  * without specific, written prior permission.  Richard P. Basch,
-  * Lehman Brothers and M.I.T. make no representations about the suitability
-  * of this software for any purpose.  It is provided "as is" without
-  * express or implied warranty.
-  *
-  *
-  * N-folding algorithm
-  *    Described in "A Better Key Schedule for DES-like Ciphers"
-  *    by Uri Blumenthal and Steven M. Bellovin
-  *    based on the work done by Lars Knudsen.
-  *
-  * To n-fold a number X, replicate the input value X to a length that is
-  * the least common multiple of n and the length of X.  Before each
-  * repetition, the input value is rotated to the right by 13 bit positions.
-  * The successive n-bit chunks are added together using 1's complement
-  * addition (addition with end-around carry) to yield a n-bit result.
-  *
-  * The algorithm here assumes that the input and output are padded to
-  * octet boundaries (8-bit multiple).
-  */
- 
- #include "k5-int.h"
- 
- #define ROTATE_VALUE 13
- 
- krb5_error_code
- mit_des_n_fold(inbuf, inlen, outbuf, outlen)
-     krb5_octet *inbuf;
-     size_t inlen;
-     krb5_octet *outbuf;
-     size_t outlen;
- {
-     register int bytes;
-     register krb5_octet *tempbuf;
-     
-     if (inbuf == (krb5_octet *)NULL)
- 	return EINVAL;
-     if (outbuf == (krb5_octet *)NULL)
- 	return EINVAL;
- 
-     tempbuf = (krb5_octet *)malloc(inlen);
-     if (tempbuf == (krb5_octet *)NULL)
- 	return ENOMEM;
- 
-     memset(outbuf, 0, outlen);
-     bytes = 0;
- 
- #ifndef min
- #define min(a,b) ((a) < (b) ? (a) : (b))
- #endif
- 
-     do {
- 	unsigned int j, k;
- 
- 	/* Rotate input */
- 	k = ((bytes/inlen) * ROTATE_VALUE) % (inlen*8);
- 	for (j = (k+7)/8; j < inlen + (k+7)/8; j++)
- 	    tempbuf[j % inlen] =
- 		((inbuf[((8*j-k)/8)%inlen] << ((8-(k&7))&7)) +
- 		 ((k&7) ? (inbuf[((8*j-k)/8 +1)%inlen] >> (k&7)) : 0))
- 		& 0xff;
- 
- 	for (k=0, j=inlen; j--; ) {
- 	    k += outbuf[(bytes+j) % outlen] + tempbuf[j];
- 	    outbuf[(bytes+j) % outlen] = k & 0xff;
- 	    k >>= 8;
- 	}
- 	j = bytes % outlen;
- 	while (k) {
- 	    if (j == 0)
- 		j = outlen;
- 	    j--;
- 	    k += outbuf[j];
- 	    outbuf[j] = k & 0xff;
- 	    k >>= 8;
- 	}
- 	bytes += inlen;
-     } while (bytes % outlen);
- 
-     free(tempbuf);
-     
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/des/u_rn_key.c
diff -c krb5/lib/crypto/des/u_rn_key.c:1.1.1.1 krb5/lib/crypto/des/u_rn_key.c:removed
*** krb5/lib/crypto/des/u_rn_key.c:1.1.1.1	Mon Jun  2 17:57:42 1997
--- krb5/lib/crypto/des/u_rn_key.c	Sun Mar 16 20:22:21 2003
***************
*** 1,139 ****
- /*
-  * Copyright 1996 by Richard P. Basch.  All Rights Reserved.
-  * Copyright 1996 by Lehman Brothers, Inc.  All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of Richard P. Basch, Lehman Brothers and M.I.T. not be used
-  * in advertising or publicity pertaining to distribution of the software
-  * without specific, written prior permission.  Richard P. Basch,
-  * Lehman Brothers and M.I.T. make no representations about the suitability
-  * of this software for any purpose.  It is provided "as is" without
-  * express or implied warranty.
-  *
-  *
-  * Based on the version written by Mark Lillibridge, MIT Project Athena.
-  *
-  * Under U.S. law, this software may not be exported outside the US
-  * without license from the U.S. Commerce department.
-  */
- 
- #include "k5-int.h"
- #include "des_int.h"
- 
- int
- mit_des_is_weak_keyblock(keyblock)
-     krb5_keyblock * keyblock;
- {
-     int i;
-     
-     for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++)
- 	if (mit_des_is_weak_key(*((mit_des_cblock *)keyblock->contents + i)))
- 	    return 1;
-     return 0;
- }
- 
- void
- mit_des_fixup_keyblock_parity(keyblock)
-     krb5_keyblock * keyblock;
- {
-     int i;
-     
-     for (i = 0; i < keyblock->length/sizeof(mit_des_cblock); i++)
- 	mit_des_fixup_key_parity(*((mit_des_cblock *)keyblock->contents + i));
- }
- 
- /*
-  * mit_des_set_random_generator_seed: this routine is used to select a random
-  *                                number stream.  The stream that results is
-  *                                totally determined by the passed in key.
-  *                                (I.e., calling this routine again with the
-  *                                same key allows repeating a sequence of
-  *                                random numbers)
-  */
- krb5_error_code
- mit_des_set_random_generator_seed(seed, p_state)
-     const krb5_data * seed;
-     krb5_pointer p_state;
- {
-     krb5_error_code kret;
-     register int i;
-     mit_des_cblock *new_key;
-     mit_des_random_state *state = p_state;
- 
-     if (state->eblock.key) {
- 	if (state->eblock.key->contents) {
- 	    memset(state->eblock.key->contents, 0, state->eblock.key->length);
- 	    krb5_xfree(state->eblock.key->contents);
- 	}
-     }
- 
-     state->eblock.key = (krb5_keyblock *)malloc(sizeof(krb5_keyblock));
-     if (! state->eblock.key)
- 	return ENOMEM;
- 
-     state->eblock.key->enctype = state->eblock.crypto_entry->proto_enctype;
-     state->eblock.key->length = state->eblock.crypto_entry->keysize;
-     state->eblock.key->contents = (krb5_octet *)malloc(state->eblock.key->length);
-     if (! state->eblock.key->contents) {
- 	krb5_xfree(state->eblock.key);
- 	state->eblock.key = 0;
- 	return ENOMEM;
-     }
- 
-     kret = mit_des_n_fold(seed->data, seed->length,
- 		state->eblock.key->contents, state->eblock.key->length);
-     if (kret) return kret;
- 
-     mit_des_fixup_keyblock_parity(state->eblock.key);
- 
-     for (i = 0; i < state->eblock.key->length/sizeof(mit_des_cblock); i++) {
- 	new_key = (mit_des_cblock *)state->eblock.key->contents + i;
- 	if (mit_des_is_weak_key(*new_key)) {
- 	    (*new_key)[0] ^= 0xF0;
- 	    mit_des_fixup_key_parity(*new_key);
- 	}
-     }
- 
-     /* destroy any old key schedule */
-     mit_des_finish_key(&state->eblock);
-     
-     /* compute the key schedule */
-     (* state->eblock.crypto_entry->process_key)
- 	(&state->eblock, state->eblock.key);
- 
-     /* now we can destroy the key... */
-     memset(state->eblock.key->contents, 0, state->eblock.key->length);
-     krb5_xfree(state->eblock.key->contents);
-     krb5_xfree(state->eblock.key);
-     state->eblock.key = (krb5_keyblock *) 0;
- 
-     /* "seek" to the start of the stream: */
-     memset(state->sequence.data, 0, state->sequence.length);
- 
-     return 0;
- }
- 
- krb5_error_code
- mit_des_set_random_sequence_number(sequence, p_state)
-     const krb5_data *sequence;
-     krb5_pointer p_state;
- {
-     mit_des_random_state *state = p_state;
-     int length = state->eblock.crypto_entry->keysize;
- 
-     if (length > sequence->length)
- 	length = sequence->length;
- 
-     memcpy(state->sequence.data, sequence->data, length);
-     
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/md4/.cvsignore
diff -c /dev/null krb5/lib/crypto/md4/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:21 2003
--- krb5/lib/crypto/md4/.cvsignore	Thu Jun  5 10:39:09 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/crypto/md4/.rconf
diff -c krb5/lib/crypto/md4/.rconf:1.1.1.1 krb5/lib/crypto/md4/.rconf:removed
*** krb5/lib/crypto/md4/.rconf:1.1.1.1	Mon Jun  2 17:57:43 1997
--- krb5/lib/crypto/md4/.rconf	Sun Mar 16 20:22:22 2003
***************
*** 1,2 ****
- ignore RFC1186.TXT
- ignore RFC1186B.TXT
--- 0 ----
Index: krb5/lib/crypto/md4/configure.in
diff -c krb5/lib/crypto/md4/configure.in:1.1.1.1 krb5/lib/crypto/md4/configure.in:removed
*** krb5/lib/crypto/md4/configure.in:1.1.1.1	Mon Jun  2 17:57:43 1997
--- krb5/lib/crypto/md4/configure.in	Sun Mar 16 20:22:22 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- KRB5_RUN_FLAGS
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/md4/md4crypto.c
diff -c krb5/lib/crypto/md4/md4crypto.c:1.1.1.1 krb5/lib/crypto/md4/md4crypto.c:removed
*** krb5/lib/crypto/md4/md4crypto.c:1.1.1.1	Mon Jun  2 17:57:44 1997
--- krb5/lib/crypto/md4/md4crypto.c	Sun Mar 16 20:22:22 2003
***************
*** 1,366 ****
- /*
-  * lib/crypto/md4/md4crypto.c
-  *
-  * Copyright 1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * Kerberos glue for MD4 sample implementation.
-  */
- 
- #include "k5-int.h"
- #include "rsa-md4.h"
- #include "des_int.h"	/* we cheat a bit and call it directly... */
- 
- /* Windows needs to these prototypes for the assignment below */
- 
- krb5_error_code
- krb5_md4_crypto_sum_func PROTOTYPE((krb5_pointer in, size_t in_length,
-     krb5_pointer seed, size_t seed_length, krb5_checksum *outcksum));
- 
- krb5_error_code
- krb5_md4_crypto_verify_func PROTOTYPE((krb5_checksum FAR *cksum, krb5_pointer in,
- 	size_t in_length, krb5_pointer seed, size_t seed_length));
- 
- static mit_des_cblock zero_ivec = { 0 };
- 
- /*
-  * In Kerberos V5 Beta 5 and previous releases the RSA-MD4-DES implementation
-  * did not follow RFC1510.  The folowing definitions control the compatibility
-  * with these releases.
-  *
-  * If MD4_K5BETA_COMPAT is defined, then compatability mode is enabled.  That
-  * means that both checksum functions are compiled and available for use and
-  * the additional interface md4_crypto_compat_ctl() is defined.
-  *
-  * If MD4_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then
-  * the compatible behaviour becomes the default.
-  *
-  */
- #define MD4_K5BETA_COMPAT
- #define MD4_K5BETA_COMPAT_DEF
- 
- static void
- krb5_md4_calculate_cksum(md4ctx, confound, confound_length, in, in_length)
-     krb5_MD4_CTX		*md4ctx;
-     krb5_pointer	confound;
-     size_t		confound_length;
-     krb5_pointer	in;
-     size_t		in_length;
- {
-     krb5_MD4Init(md4ctx);
-     if (confound && confound_length)
- 	krb5_MD4Update(md4ctx, confound, confound_length);
-     krb5_MD4Update(md4ctx, in, in_length);
-     krb5_MD4Final(md4ctx);
- }
- 
- #ifdef	MD4_K5BETA_COMPAT
- /*
-  * Generate the RSA-MD4-DES checksum in a manner which is compatible with
-  * K5 Beta implementations.  Sigh...
-  */
- krb5_error_code
- krb5_md4_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet outtmp[OLD_RSA_MD4_DES_CKSUM_LENGTH];
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
-     krb5_MD4_CTX working;
- 
-     if (outcksum->length < OLD_RSA_MD4_DES_CKSUM_LENGTH)
- 	return KRB5_BAD_MSIZE;
- 
-     krb5_MD4Init(&working);
-     krb5_MD4Update(&working, input, in_length);
-     krb5_MD4Final(&working);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES;
-     outcksum->length = OLD_RSA_MD4_DES_CKSUM_LENGTH;
- 
-     memcpy((char *)outtmp, (char *)&working.digest[0], 16);
- 
-     memset((char *)&working, 0, sizeof(working));
- 
-     keyblock.length = seed_length;
-     keyblock.contents = (krb5_octet *)seed;
-     keyblock.enctype = ENCTYPE_DES_CBC_MD4;
- 
-     if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 	return retval;
-     /* now encrypt it */
-     retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0],
- 				 (mit_des_cblock *)outcksum->contents,
- 				 OLD_RSA_MD4_DES_CKSUM_LENGTH,
- 				 (struct mit_des_ks_struct *)eblock.priv,
- 				 keyblock.contents,
- 				 MIT_DES_ENCRYPT);
-     if (retval) {
- 	(void) mit_des_finish_key(&eblock);
- 	return retval;
-     }
-     return mit_des_finish_key(&eblock);
- }
- #endif	/* MD4_K5BETA_COMPAT */
- 
- /*
-  * Generate the RSA-MD4-DES checksum correctly.
-  */
- krb5_error_code
- krb5_md4_crypto_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH];
-     mit_des_cblock	tmpkey;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
-     size_t i;
- 
-     krb5_MD4_CTX working;
- 
-     /* Generate the confounder in place */
-     if ((retval = krb5_random_confounder(RSA_MD4_DES_CONFOUND_LENGTH, outtmp)))
- 	return(retval);
- 
-     /* Calculate the checksum */
-     krb5_md4_calculate_cksum(&working,
- 			(krb5_pointer) outtmp,
- 			(size_t) RSA_MD4_DES_CONFOUND_LENGTH,
- 			in,
- 			in_length);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD4_DES;
-     outcksum->length = NEW_RSA_MD4_DES_CKSUM_LENGTH;
- 
-     /* Now blast in the digest */
-     memcpy((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH],
- 	   (char *) &working.digest[0],
- 	   RSA_MD4_CKSUM_LENGTH);
- 
-     /* Clean up droppings */
-     memset((char *)&working, 0, sizeof(working));
- 
-     /* Set up the temporary copy of the key (see RFC 1510 section 6.4.3) */
-     memset((char *) tmpkey, 0, sizeof(mit_des_cblock));
-     for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++)
- 	tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0;
- 
-     keyblock.length = sizeof(mit_des_cblock);
-     keyblock.contents = (krb5_octet *) tmpkey;
-     keyblock.enctype = ENCTYPE_DES_CBC_MD4;
- 
-     if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 	return retval;
-     /* now encrypt it */
-     retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0],
- 				 (mit_des_cblock *)outcksum->contents,
- 				 NEW_RSA_MD4_DES_CKSUM_LENGTH,
- 				 (struct mit_des_ks_struct *)eblock.priv,
- 				 zero_ivec,
- 				 MIT_DES_ENCRYPT);
-     if (retval) {
- 	(void) mit_des_finish_key(&eblock);
- 	return retval;
-     }
-     return mit_des_finish_key(&eblock);
- }
- 
- krb5_error_code
- krb5_md4_crypto_verify_func(cksum, in, in_length, seed, seed_length)
- krb5_checksum FAR *cksum;
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- {
-     krb5_octet outtmp[NEW_RSA_MD4_DES_CKSUM_LENGTH];
-     mit_des_cblock	tmpkey;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
-     size_t i;
- 
-     krb5_MD4_CTX working;
- 
-     retval = 0;
-     if (cksum->checksum_type == CKSUMTYPE_RSA_MD4_DES) {
- #ifdef	MD4_K5BETA_COMPAT
- 	/*
- 	 * We have a backwards compatibility problem here.  Kerberos
- 	 * version 5 Beta 5 and previous releases did not correctly
- 	 * generate RSA-MD4-DES checksums.  The way that we can
- 	 * differentiate is by the length of the provided checksum.
- 	 * If it's only OLD_RSA_MD4_DES_CKSUM_LENGTH, then it's the
- 	 * old style, otherwise it's the correct implementation.
- 	 */
- 	if (cksum->length == OLD_RSA_MD4_DES_CKSUM_LENGTH) {
- 	    /*
- 	     * If we're verifying the Old Style (tm) checksum, then we can just
- 	     * recalculate the checksum and encrypt it and see if it's the
- 	     * same.
- 	     */
- 
- 	    /* Recalculate the checksum with no confounder */
- 	    krb5_md4_calculate_cksum(&working,
- 				(krb5_pointer) NULL,
- 				(size_t) 0,
- 				in,
- 				in_length);
- 
- 	    /* Use the key "as-is" */
- 	    keyblock.length = seed_length;
- 	    keyblock.contents = (krb5_octet *) seed;
- 	    keyblock.enctype = ENCTYPE_DES_CBC_MD4;
- 
- 	    if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 		return retval;
- 	    /* now encrypt the checksum */
- 	    retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0],
- 					 (mit_des_cblock *)&outtmp[0],
- 					 RSA_MD4_CKSUM_LENGTH,
- 					 (struct mit_des_ks_struct *)
- 					 	eblock.priv,
- 					 keyblock.contents,
- 					 MIT_DES_ENCRYPT);
- 	    if (retval) {
- 		(void) mit_des_finish_key(&eblock);
- 		return retval;
- 	    }
- 	    if ((retval = mit_des_finish_key(&eblock)))
- 		return(retval);
- 
- 	    /* Compare the encrypted checksums */
- 	    if (memcmp((char *) &outtmp[0],
- 		       (char *) cksum->contents,
- 		       OLD_RSA_MD4_DES_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	}
- 	else
- #endif	/* MD4_K5BETA_COMPAT */
- 	if (cksum->length == (NEW_RSA_MD4_DES_CKSUM_LENGTH)) {
- 	    /*
- 	     * If we're verifying the correct implementation, then we have
- 	     * to do a little more work because we must decrypt the checksum
- 	     * because it contains the confounder in it.  So, figure out
- 	     * what our key variant is and then do it!
- 	     */
- 
- 	    /* Set up the variant of the key (see RFC 1510 section 6.4.3) */
- 	    memset((char *) tmpkey, 0, sizeof(mit_des_cblock));
- 	    for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++)
- 		tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0;
- 
- 	    keyblock.length = sizeof(mit_des_cblock);
- 	    keyblock.contents = (krb5_octet *) tmpkey;
- 	    keyblock.enctype = ENCTYPE_DES_CBC_MD4;
- 
- 	    if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 		return retval;
- 	    /* now decrypt it */
- 	    retval = mit_des_cbc_encrypt((mit_des_cblock *)cksum->contents,
- 					 (mit_des_cblock *)&outtmp[0],
- 					 NEW_RSA_MD4_DES_CKSUM_LENGTH,
- 					 (struct mit_des_ks_struct *)
- 					 	eblock.priv,
- 					 zero_ivec,
- 					 MIT_DES_DECRYPT);
- 	    if (retval) {
- 		(void) mit_des_finish_key(&eblock);
- 		return retval;
- 	    }
- 	    if ((retval = mit_des_finish_key(&eblock)))
- 		return(retval);
- 
- 	    /* Now that we have the decrypted checksum, try to regenerate it */
- 	    krb5_md4_calculate_cksum(&working,
- 				(krb5_pointer) outtmp,
- 				(size_t) RSA_MD4_DES_CONFOUND_LENGTH,
- 				in,
- 				in_length);
- 
- 	    /* Compare the checksums */
- 	    if (memcmp((char *) &outtmp[RSA_MD4_DES_CONFOUND_LENGTH],
- 		       (char *) &working.digest[0],
- 		       RSA_MD4_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	}
- 	else 
- 	    retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     }
-     else
- 	retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
- 
-     /* Clean up droppings */
-     memset((char *)&working, 0, sizeof(working));
-     return(retval);
- }
- 
- krb5_checksum_entry rsa_md4_des_cksumtable_entry = 
- #if	defined(MD4_K5BETA_COMPAT) && defined(MD4_K5BETA_COMPAT_DEF)
- {
-     0,
-     krb5_md4_crypto_compat_sum_func,
-     krb5_md4_crypto_verify_func,
-     OLD_RSA_MD4_DES_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     1,					/* uses key */
- };
- #else	/* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */
- {
-     0,
-     krb5_md4_crypto_sum_func,
-     krb5_md4_crypto_verify_func,
-     NEW_RSA_MD4_DES_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     1,					/* uses key */
- };
- #endif	/* MD4_K5BETA_COMPAT && MD4_K5BETA_COMPAT_DEF */
- 
- #ifdef	MD4_K5BETA_COMPAT
- /*
-  * Turn on/off compatible checksum generation.
-  */
- void
- krb5_md4_crypto_compat_ctl(scompat)
-     krb5_boolean	scompat;
- {
-     if (scompat) {
- 	rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_compat_sum_func;
- 	rsa_md4_des_cksumtable_entry.checksum_length =
- 	    OLD_RSA_MD4_DES_CKSUM_LENGTH;
-     }
-     else {
- 	rsa_md4_des_cksumtable_entry.sum_func = krb5_md4_crypto_sum_func;
- 	rsa_md4_des_cksumtable_entry.checksum_length =
- 	    NEW_RSA_MD4_DES_CKSUM_LENGTH;
-     }
- }
- #endif	/* MD4_K5BETA_COMPAT */
--- 0 ----
Index: krb5/lib/crypto/md4/md4driver.c
diff -c krb5/lib/crypto/md4/md4driver.c:1.1.1.1 krb5/lib/crypto/md4/md4driver.c:removed
*** krb5/lib/crypto/md4/md4driver.c:1.1.1.1	Mon Jun  2 17:57:44 1997
--- krb5/lib/crypto/md4/md4driver.c	Sun Mar 16 20:22:22 2003
***************
*** 1,202 ****
- /*
-  *	lib/crypto/md4/md4driver.c
-  */
- 
- /*
-  **********************************************************************
-  ** md4driver.c -- sample routines to test                           **
-  ** RSA Data Security, Inc. MD4 message digest algorithm.            **
-  ** Created: 2/16/90 RLR                                             **
-  ** Updated: 1/91 SRD                                                **
-  **********************************************************************
-  */
- 
- /*
-  **********************************************************************
-  ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
-  **                                                                  **
-  ** RSA Data Security, Inc. makes no representations concerning      **
-  ** either the merchantability of this software or the suitability   **
-  ** of this software for any particular purpose.  It is provided "as **
-  ** is" without express or implied warranty of any kind.             **
-  **                                                                  **
-  ** These notices must be retained in any copies of any part of this **
-  ** documentation and/or software.                                   **
-  **********************************************************************
-  */
- 
- #include "k5-int.h"
- #include "rsa-md4.h"
- 
- /* Prints message digest buffer in mdContext as 32 hexadecimal digits.
-    Order is from low-order byte to high-order byte of digest.
-    Each byte is printed with high-order hexadecimal digit first.
-  */
- static void MDPrint (mdContext)
- krb5_MD4_CTX *mdContext;
- {
-   int i;
- 
-   for (i = 0; i < 16; i++)
-     printf ("%02x", mdContext->digest[i]);
- }
- 
- /* size of test block */
- #define TEST_BLOCK_SIZE 1000
- 
- /* number of blocks to process */
- #define TEST_BLOCKS 2000
- 
- /* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
- static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
- 
- /* A time trial routine, to measure the speed of MD4.
-    Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
-    characters.
-  */
- static void MDTimeTrial ()
- {
-   krb5_MD4_CTX mdContext;
-   time_t endTime, startTime;
-   unsigned char data[TEST_BLOCK_SIZE];
-   unsigned int i;
- 
-   /* initialize test data */
-   for (i = 0; i < TEST_BLOCK_SIZE; i++)
-     data[i] = (unsigned char)(i & 0xFF);
- 
-   /* start timer */
-   printf ("MD4 time trial. Processing %ld characters...\n", TEST_BYTES);
-   time (&startTime);
- 
-   /* digest data in TEST_BLOCK_SIZE byte blocks */
-   krb5_MD4Init (&mdContext);
-   for (i = TEST_BLOCKS; i > 0; i--)
-     krb5_MD4Update (&mdContext, data, TEST_BLOCK_SIZE);
-   krb5_MD4Final (&mdContext);
-   /* stop timer, get time difference */
-   time (&endTime);
-   MDPrint (&mdContext);
-   printf (" is digest of test input.\n");
-   printf
-     ("Seconds to process test input: %ld\n", (long)(endTime-startTime));
-   printf
-     ("Characters processed per second: %ld\n",
-      TEST_BYTES/(endTime-startTime));
- }
- 
- /* Computes the message digest for string inString.
-    Prints out message digest, a space, the string (in quotes) and a
-    carriage return.
-  */
- static void MDString (inString)
- char *inString;
- {
-   krb5_MD4_CTX mdContext;
-   unsigned int len = strlen (inString);
- 
-   krb5_MD4Init (&mdContext);
-   krb5_MD4Update (&mdContext, inString, len);
-   krb5_MD4Final (&mdContext);
-   MDPrint (&mdContext);
-   printf (" \"%s\"\n\n", inString);
- }
- 
- /* Computes the message digest for a specified file.
-    Prints out message digest, a space, the file name, and a carriage
-    return.
-  */
- static void MDFile (filename)
- char *filename;
- {
- #ifdef __STDC__
-   FILE *inFile = fopen (filename, "rb");
- #else
-   FILE *inFile = fopen (filename, "r");
- #endif
-   krb5_MD4_CTX mdContext;
-   int bytes;
-   unsigned char data[1024];
- 
-   if (inFile == NULL) {
-     printf ("%s can't be opened.\n", filename);
-     return;
-   }
- 
-   krb5_MD4Init (&mdContext);
-   while ((bytes = fread (data, 1, 1024, inFile)) != 0)
-     krb5_MD4Update (&mdContext, data, bytes);
-   krb5_MD4Final (&mdContext);
-   MDPrint (&mdContext);
-   printf (" %s\n", filename);
-   fclose (inFile);
- }
- 
- 
- /* Writes the message digest of the data from stdin onto stdout,
-    followed by a carriage return.
-  */
- static void MDFilter ()
- {
-   krb5_MD4_CTX mdContext;
-   int bytes;
-   unsigned char data[16];
- 
-   krb5_MD4Init (&mdContext);
-   while ((bytes = fread (data, 1, 16, stdin)) != 0)
-     krb5_MD4Update (&mdContext, data, bytes);
-   krb5_MD4Final (&mdContext);
-   MDPrint (&mdContext);
-   printf ("\n");
- }
- 
- /* Runs a standard suite of test data.
-  */
- static void MDTestSuite ()
- {
-   printf ("MD4 test suite results:\n\n");
-   MDString ("");
-   MDString ("a");
-   MDString ("abc");
-   MDString ("message digest");
-   MDString ("abcdefghijklmnopqrstuvwxyz");
-   MDString
-     ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
-   MDString
-     ("1234567890123456789012345678901234567890\
- 1234567890123456789012345678901234567890");
-   /* Contents of file foo are "abc" */
-   MDFile ("foo");
- }
- 
- void main (argc, argv)
- int argc;
- char *argv[];
- {
-   int i;
- 
-   /* For each command line argument in turn:
-   ** filename          -- prints message digest and name of file
-   ** -sstring          -- prints message digest and contents of string
-   ** -t                -- prints time trial statistics for 1M characters
-   ** -x                -- execute a standard suite of test data
-   ** (no args)         -- writes messages digest of stdin onto stdout
-   */
-   if (argc == 1)
-     MDFilter ();
-   else
-     for (i = 1; i < argc; i++)
-       if (argv[i][0] == '-' && argv[i][1] == 's')
-         MDString (argv[i] + 2);
-       else if (strcmp (argv[i], "-t") == 0)
-         MDTimeTrial ();
-       else if (strcmp (argv[i], "-x") == 0)
-         MDTestSuite ();
-       else MDFile (argv[i]);
- }
- 
- /*
-  **********************************************************************
-  ** End of md4driver.c                                               **
-  ******************************* (cut) ********************************
-  */
--- 0 ----
Index: krb5/lib/crypto/md4/md4glue.c
diff -c krb5/lib/crypto/md4/md4glue.c:1.1.1.1 krb5/lib/crypto/md4/md4glue.c:removed
*** krb5/lib/crypto/md4/md4glue.c:1.1.1.1	Mon Jun  2 17:57:44 1997
--- krb5/lib/crypto/md4/md4glue.c	Sun Mar 16 20:22:22 2003
***************
*** 1,107 ****
- /*
-  * lib/crypto/md4/md4glue.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  * Kerberos glue for MD4 sample implementation.
-  */
- 
- #include "k5-int.h"
- #include "rsa-md4.h"
- 
- /* Windows needs to these prototypes for the assignment below */
- 
- krb5_error_code
- krb5_md4_sum_func PROTOTYPE((krb5_pointer in, size_t in_length,
-     krb5_pointer seed, size_t seed_length, krb5_checksum *outcksum));
- 
- krb5_error_code
- krb5_md4_verify_func PROTOTYPE((krb5_checksum FAR *cksum, krb5_pointer in,
- 	size_t in_length, krb5_pointer seed, size_t seed_length));
- 
- krb5_error_code
- krb5_md4_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_MD4_CTX working;
- 
-     if (outcksum->length < RSA_MD4_CKSUM_LENGTH)
- 	return KRB5_BAD_MSIZE;
-     
-     krb5_MD4Init(&working);
-     krb5_MD4Update(&working, input, in_length);
-     krb5_MD4Final(&working);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD4;
-     outcksum->length = RSA_MD4_CKSUM_LENGTH;
- 
-     memcpy((char *)outcksum->contents, (char *)&working.digest[0],
- 	   RSA_MD4_CKSUM_LENGTH);
- 
-     memset((char *)&working, 0, sizeof(working));
-     return 0;
- }
- 
- krb5_error_code
- krb5_md4_verify_func(cksum, in, in_length, seed, seed_length)
- krb5_checksum FAR *cksum;
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_MD4_CTX working;
-     krb5_error_code retval;
- 
-     retval = 0;
-     if (cksum->checksum_type == CKSUMTYPE_RSA_MD4) {
- 	if (cksum->length == RSA_MD4_CKSUM_LENGTH) {
- 	    krb5_MD4Init(&working);
- 	    krb5_MD4Update(&working, input, in_length);
- 	    krb5_MD4Final(&working);
- 
- 	    if (memcmp((char *) cksum->contents,
- 		       (char *) &working.digest[0],
- 		       RSA_MD4_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	    memset((char *)&working, 0, sizeof(working));
- 	}
- 	else
- 	    retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     }
-     else
- 	retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
-     return retval;
- }
- 
- krb5_checksum_entry rsa_md4_cksumtable_entry = {
-     0,
-     krb5_md4_sum_func,
-     krb5_md4_verify_func,
-     RSA_MD4_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     0,					/* doesn't use key */
- };
--- 0 ----
Index: krb5/lib/crypto/md5/.cvsignore
diff -c /dev/null krb5/lib/crypto/md5/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:22 2003
--- krb5/lib/crypto/md5/.cvsignore	Thu Jun  5 10:39:10 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/crypto/md5/configure.in
diff -c krb5/lib/crypto/md5/configure.in:1.1.1.1 krb5/lib/crypto/md5/configure.in:removed
*** krb5/lib/crypto/md5/configure.in:1.1.1.1	Mon Jun  2 17:57:44 1997
--- krb5/lib/crypto/md5/configure.in	Sun Mar 16 20:22:22 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- KRB5_RUN_FLAGS
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/md5/md5crypto.c
diff -c krb5/lib/crypto/md5/md5crypto.c:1.1.1.1 krb5/lib/crypto/md5/md5crypto.c:removed
*** krb5/lib/crypto/md5/md5crypto.c:1.1.1.1	Mon Jun  2 17:57:45 1997
--- krb5/lib/crypto/md5/md5crypto.c	Sun Mar 16 20:22:22 2003
***************
*** 1,334 ****
- #include "k5-int.h"
- #include "rsa-md5.h"
- #include "des_int.h"	/* we cheat a bit and call it directly... */
- 
- /* Windows needs to these prototypes for the assignment below */
- 
- krb5_error_code
- krb5_md5_crypto_sum_func PROTOTYPE((krb5_pointer in, size_t in_length,
- 	krb5_pointer seed, size_t seed_length, krb5_checksum FAR *outcksum));
- 
- krb5_error_code
- krb5_md5_crypto_verify_func PROTOTYPE((krb5_checksum FAR *cksum, krb5_pointer in,
- 	size_t in_length, krb5_pointer seed, size_t seed_length));
- 
- static mit_des_cblock zero_ivec = { 0 };
- 
- /*
-  * In Kerberos V5 Beta 5 and previous releases the RSA-MD5-DES implementation
-  * did not follow RFC1510.  The folowing definitions control the compatibility
-  * with these releases.
-  *
-  * If MD5_K5BETA_COMPAT is defined, then compatability mode is enabled.  That
-  * means that both checksum functions are compiled and available for use and
-  * the additional interface krb5_md5_crypto_compat_ctl() is defined.
-  *
-  * If MD5_K5BETA_COMPAT_DEF is defined and compatability mode is enabled, then
-  * the compatible behaviour becomes the default.
-  *
-  */
- #define MD5_K5BETA_COMPAT
- #define MD5_K5BETA_COMPAT_DEF
- 
- static void
- krb5_md5_calculate_cksum(md5ctx, confound, confound_length, in, in_length)
-     krb5_MD5_CTX		*md5ctx;
-     krb5_pointer	in;
-     size_t		in_length;
-     krb5_pointer	confound;
-     size_t		confound_length;
- {
-     krb5_MD5Init(md5ctx);
-     if (confound && confound_length)
- 	krb5_MD5Update(md5ctx, confound, confound_length);
-     krb5_MD5Update(md5ctx, in, in_length);
-     krb5_MD5Final(md5ctx);
- }
- 
- #ifdef	MD5_K5BETA_COMPAT
- krb5_error_code
- krb5_md5_crypto_compat_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet outtmp[OLD_RSA_MD5_DES_CKSUM_LENGTH];
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
- 
-     krb5_MD5_CTX working;
- 
-     krb5_MD5Init(&working);
-     krb5_MD5Update(&working, input, in_length);
-     krb5_MD5Final(&working);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES;
-     outcksum->length = OLD_RSA_MD5_DES_CKSUM_LENGTH;
- 
-     memcpy((char *)outtmp, (char *)&working.digest[0], 16);
- 
-     memset((char *)&working, 0, sizeof(working));
- 
-     keyblock.length = seed_length;
-     keyblock.contents = (krb5_octet *)seed;
-     keyblock.enctype = ENCTYPE_DES_CBC_MD5;
- 
-     if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 	return retval;
-     /* now encrypt it */
-     retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0],
- 				 (mit_des_cblock *)outcksum->contents,
- 				 OLD_RSA_MD5_DES_CKSUM_LENGTH,
- 				 (struct mit_des_ks_struct *)eblock.priv,
- 				 keyblock.contents,
- 				 MIT_DES_ENCRYPT);
-     if (retval) {
- 	(void) mit_des_finish_key(&eblock);
- 	return retval;
-     }
-     return mit_des_finish_key(&eblock);
- }
- #endif	/* MD5_K5BETA_COMPAT */
- 
- krb5_error_code
- krb5_md5_crypto_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH];
-     mit_des_cblock	tmpkey;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
-     size_t i;
-     krb5_MD5_CTX working;
- 
-     if (outcksum->length < NEW_RSA_MD5_DES_CKSUM_LENGTH)
- 	return KRB5_BAD_MSIZE;
- 
-     /* Generate the confounder in place */
-     if ((retval = krb5_random_confounder(RSA_MD5_DES_CONFOUND_LENGTH, outtmp)))
- 	return(retval);
- 
-     /* Calculate the checksum */
-     krb5_md5_calculate_cksum(&working,
- 			(krb5_pointer) outtmp,
- 			(size_t) RSA_MD5_DES_CONFOUND_LENGTH,
- 			in,
- 			in_length);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD5_DES;
-     outcksum->length = NEW_RSA_MD5_DES_CKSUM_LENGTH;
- 
-     /* Now blast in the digest */
-     memcpy((char *)&outtmp[RSA_MD5_DES_CONFOUND_LENGTH],
- 	   (char *)&working.digest[0],
- 	   RSA_MD5_CKSUM_LENGTH);
- 
-     /* Clean up the droppings */
-     memset((char *)&working, 0, sizeof(working));
- 
-     /* Set up the temporary copy of the key (see RFC 1510 section 6.4.5) */
-     memset((char *) tmpkey, 0, sizeof(mit_des_cblock));
-     for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++)
- 	tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0;
- 
-     keyblock.length = sizeof(mit_des_cblock);
-     keyblock.contents = (krb5_octet *) tmpkey;
-     keyblock.enctype = ENCTYPE_DES_CBC_MD5;
- 
-     if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 	return retval;
-     /* now encrypt it */
-     retval = mit_des_cbc_encrypt((mit_des_cblock *)&outtmp[0],
- 				 (mit_des_cblock *)outcksum->contents,
- 				 NEW_RSA_MD5_DES_CKSUM_LENGTH,
- 				 (struct mit_des_ks_struct *)eblock.priv,
- 				 zero_ivec,
- 				 MIT_DES_ENCRYPT);
-     if (retval) {
- 	(void) mit_des_finish_key(&eblock);
- 	return retval;
-     }
-     return mit_des_finish_key(&eblock);
- }
- 
- krb5_error_code
- krb5_md5_crypto_verify_func(cksum, in, in_length, seed, seed_length)
- krb5_checksum FAR *cksum;
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- {
-     krb5_octet outtmp[NEW_RSA_MD5_DES_CKSUM_LENGTH];
-     mit_des_cblock	tmpkey;
-     krb5_encrypt_block eblock;
-     krb5_keyblock keyblock;
-     krb5_error_code retval;
-     size_t i;
- 
-     krb5_MD5_CTX working;
- 
-     retval = 0;
-     if (cksum->checksum_type == CKSUMTYPE_RSA_MD5_DES) {
- #ifdef	MD5_K5BETA_COMPAT
- 	/*
- 	 * We have a backwards compatibility problem here.  Kerberos
- 	 * version 5 Beta 5 and previous releases did not correctly
- 	 * generate RSA-MD5-DES checksums.  The way that we can
- 	 * differentiate is by the length of the provided checksum.
- 	 * If it's only OLD_RSA_MD5_DES_CKSUM_LENGTH, then it's the
- 	 * old style, otherwise it's the correct implementation.
- 	 */
- 	if (cksum->length == OLD_RSA_MD5_DES_CKSUM_LENGTH) {
- 	    /*
- 	     * If we're verifying the Old Style (tm) checksum, then we can just
- 	     * recalculate the checksum and encrypt it and see if it's the
- 	     * same.
- 	     */
- 
- 	    /* Recalculate the checksum with no confounder */
- 	    krb5_md5_calculate_cksum(&working,
- 				(krb5_pointer) NULL,
- 				(size_t) 0,
- 				in,
- 				in_length);
- 
- 	    /* Use the key "as-is" */
- 	    keyblock.length = seed_length;
- 	    keyblock.contents = (krb5_octet *) seed;
- 	    keyblock.enctype = ENCTYPE_DES_CBC_MD5;
- 
- 	    if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 		return retval;
- 	    /* now encrypt the checksum */
- 	    retval = mit_des_cbc_encrypt((mit_des_cblock *)&working.digest[0],
- 					 (mit_des_cblock *)&outtmp[0],
- 					 OLD_RSA_MD5_DES_CKSUM_LENGTH,
- 					 (struct mit_des_ks_struct *)
- 					 	eblock.priv,
- 					 keyblock.contents,
- 					 MIT_DES_ENCRYPT);
- 	    if (retval) {
- 		(void) mit_des_finish_key(&eblock);
- 		return retval;
- 	    }
- 	    if ((retval = mit_des_finish_key(&eblock)))
- 		return(retval);
- 
- 	    /* Compare the encrypted checksums */
- 	    if (memcmp((char *) &outtmp[0],
- 		       (char *) cksum->contents,
- 		       OLD_RSA_MD5_DES_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	}
- 	else
- #endif	/* MD5_K5BETA_COMPAT */
- 	if (cksum->length == (NEW_RSA_MD5_DES_CKSUM_LENGTH)) {
- 	    /*
- 	     * If we're verifying the correct implementation, then we have
- 	     * to do a little more work because we must decrypt the checksum
- 	     * because it contains the confounder in it.  So, figure out
- 	     * what our key variant is and then do it!
- 	     */
- 
- 	    /* Set up the variant of the key (see RFC 1510 section 6.4.5) */
- 	    memset((char *) tmpkey, 0, sizeof(mit_des_cblock));
- 	    for (i=0; (i<seed_length) && (i<sizeof(mit_des_cblock)); i++)
- 		tmpkey[i] = (((krb5_octet *) seed)[i]) ^ 0xf0;
- 
- 	    keyblock.length = sizeof(mit_des_cblock);
- 	    keyblock.contents = (krb5_octet *) tmpkey;
- 	    keyblock.enctype = ENCTYPE_DES_CBC_MD5;
- 
- 	    if ((retval = mit_des_process_key(&eblock, &keyblock)))
- 		return retval;
- 	    /* now decrypt it */
- 	    retval = mit_des_cbc_encrypt((mit_des_cblock *)cksum->contents,
- 					 (mit_des_cblock *)&outtmp[0],
- 					 NEW_RSA_MD5_DES_CKSUM_LENGTH,
- 					 (struct mit_des_ks_struct *)
- 					 	eblock.priv,
- 					 zero_ivec,
- 					 MIT_DES_DECRYPT);
- 	    if (retval) {
- 		(void) mit_des_finish_key(&eblock);
- 		return retval;
- 	    }
- 	    if ((retval = mit_des_finish_key(&eblock)))
- 		return(retval);
- 
- 	    /* Now that we have the decrypted checksum, try to regenerate it */
- 	    krb5_md5_calculate_cksum(&working,
- 				(krb5_pointer) outtmp,
- 				(size_t) RSA_MD5_DES_CONFOUND_LENGTH,
- 				in,
- 				in_length);
- 
- 	    /* Compare the checksums */
- 	    if (memcmp((char *) &outtmp[RSA_MD5_DES_CONFOUND_LENGTH],
- 		       (char *) &working.digest[0],
- 		       RSA_MD5_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	}
- 	else 
- 	    retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     }
-     else
- 	retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
- 
-     /* Clean up droppings */
-     memset((char *)&working, 0, sizeof(working));
-     return(retval);
- }
- 
- krb5_checksum_entry rsa_md5_des_cksumtable_entry =
- #if	defined(MD5_K5BETA_COMPAT) && defined(MD5_K5BETA_COMPAT_DEF)
- {
-     0,
-     krb5_md5_crypto_compat_sum_func,
-     krb5_md5_crypto_verify_func,
-     OLD_RSA_MD5_DES_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     1,					/* uses key */
- };
- #else	/* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */
- {
-     0,
-     krb5_md5_crypto_sum_func,
-     krb5_md5_crypto_verify_func,
-     NEW_RSA_MD5_DES_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     1,					/* uses key */
- };
- #endif	/* MD5_K5BETA_COMPAT && MD5_K5BETA_COMPAT_DEF */
- 
- #ifdef	MD5_K5BETA_COMPAT
- /*
-  * Turn on/off compatible checksum generation.
-  */
- void
- krb5_md5_crypto_compat_ctl(scompat)
-     krb5_boolean	scompat;
- {
-     if (scompat) {
- 	rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_compat_sum_func;
- 	rsa_md5_des_cksumtable_entry.checksum_length =
- 	    OLD_RSA_MD5_DES_CKSUM_LENGTH;
-     }
-     else {
- 	rsa_md5_des_cksumtable_entry.sum_func = krb5_md5_crypto_sum_func;
- 	rsa_md5_des_cksumtable_entry.checksum_length =
- 	    NEW_RSA_MD5_DES_CKSUM_LENGTH;
-     }
- }
- #endif	/* MD5_K5BETA_COMPAT */
- 
--- 0 ----
Index: krb5/lib/crypto/md5/md5glue.c
diff -c krb5/lib/crypto/md5/md5glue.c:1.1.1.1 krb5/lib/crypto/md5/md5glue.c:removed
*** krb5/lib/crypto/md5/md5glue.c:1.1.1.1	Mon Jun  2 17:57:45 1997
--- krb5/lib/crypto/md5/md5glue.c	Sun Mar 16 20:22:22 2003
***************
*** 1,81 ****
- #include "k5-int.h"
- #include "rsa-md5.h"
- 
- /* Windows needs to these prototypes for the assignment below */
- 
- krb5_error_code
- krb5_md5_sum_func PROTOTYPE((krb5_pointer in, size_t in_length,
-     krb5_pointer seed, size_t seed_length, krb5_checksum *outcksum));
- 
- krb5_error_code
- krb5_md5_verify_func PROTOTYPE((krb5_checksum FAR *cksum, krb5_pointer in,
- 	size_t in_length, krb5_pointer seed, size_t seed_length));
- 
- krb5_error_code
- krb5_md5_sum_func(in, in_length, seed, seed_length, outcksum)
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- krb5_checksum FAR *outcksum;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_MD5_CTX working;
- 
-     if (outcksum->length < RSA_MD5_CKSUM_LENGTH)
- 	return KRB5_BAD_MSIZE;
-     
-     krb5_MD5Init(&working);
-     krb5_MD5Update(&working, input, in_length);
-     krb5_MD5Final(&working);
- 
-     outcksum->checksum_type = CKSUMTYPE_RSA_MD5;
-     outcksum->length = RSA_MD5_CKSUM_LENGTH;
- 
-     memcpy((char *)outcksum->contents, (char *)&working.digest[0], 16);
- 
-     memset((char *)&working, 0, sizeof(working));
-     return 0;
- }
- 
- krb5_error_code
- krb5_md5_verify_func(cksum, in, in_length, seed, seed_length)
- krb5_checksum FAR *cksum;
- krb5_pointer in;
- size_t in_length;
- krb5_pointer seed;
- size_t seed_length;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     krb5_MD5_CTX working;
-     krb5_error_code retval;
- 
-     retval = 0;
-     if (cksum->checksum_type == CKSUMTYPE_RSA_MD5) {
- 	if (cksum->length == RSA_MD5_CKSUM_LENGTH) {
- 	    krb5_MD5Init(&working);
- 	    krb5_MD5Update(&working, input, in_length);
- 	    krb5_MD5Final(&working);
- 
- 	    if (memcmp((char *) cksum->contents,
- 		       (char *) &working.digest[0],
- 		       RSA_MD5_CKSUM_LENGTH))
- 		retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 	    memset((char *)&working, 0, sizeof(working));
- 	}
- 	else
- 	    retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     }
-     else
- 	retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
-     return retval;
- }
- 
- krb5_checksum_entry rsa_md5_cksumtable_entry = {
-     0,
-     krb5_md5_sum_func,
-     krb5_md5_verify_func,
-     RSA_MD5_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     0,					/* doesn't use key */
- };
--- 0 ----
Index: krb5/lib/crypto/os/ChangeLog
diff -c krb5/lib/crypto/os/ChangeLog:1.1.1.1 krb5/lib/crypto/os/ChangeLog:removed
*** krb5/lib/crypto/os/ChangeLog:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/ChangeLog	Sun Mar 16 20:22:22 2003
***************
*** 1,145 ****
- Wed Jun 12 00:12:52 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
- 
- 	* c_ustime.c: Fix WIN32 to be _WIN32
- 
- 	* c_localaddr.c: Add #ifdef _WIN32 in places where we had #ifdef _MSDOS
- 	
- 
- Sat Feb 24 00:34:15 1996  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* c_ustime.c (krb5_crypto_us_timeofday): Add Windows 95/NT time
- 		function.  (Does this time function work under Windows?
- 		We'll find out....)
- 
- Thu Feb 15 10:57:27 1996  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* c_localaddr.c: Set magic number in krb5_address.
- 
- Fri Oct  6 22:00:48 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Remove ##DOS!include of config/windows.in.
- 		config/windows.in is now included by wconfig.
- 
- Mon Sep 25 16:49:15 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the
- 		Makefile. 
- 
- Fri Sep 22 12:00:00 1995  James Mattly  <mattly@fusion.com>
- 
- 	* c_localaddr.c:  change close on a socket to closesocket, sockets on
- 		macintosh arn't files
- 
- Wed Sep 13 10:33:53 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Makefile.in: PC builds all C files because of function name changes.
- 	* c_localtime.c, c_ustime.c: removed INTERFACE keyword.
- 
- Wed Sep 13 17:32:36 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* c_localaddr.c (krb5_crypto_os_localaddr): Clear the buffer
- 		before calling the SIOCGIFCONF ioctl.  This makes purify
- 		happy.
- 
- Thu Sep  7 12:00:00 1995  James Mattly <mattly@fusion.com>
- 	
- 	* Renamed ustime.c to c_ustime.c
- 	* Renamed localaddr.c to c_localaddr.c because Mac can't have
- 	  two files with the same name.
- 	* Makefile.in, .Sanitize updated for the above change.
- 
- Thu Aug 24 18:40:48 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* .Sanitize: Update file list
- 
- Sat Jul 29 03:17:21 1995  Tom Yu  <tlyu@lothlorien.MIT.EDU>
- 
- 	* localaddr.c (krb5_crypto_os_localaddr): Don't bash the return
- 		from SIOCGIFCONF with the output of a SIOCGIFFLAGS.  Duh.
- 
- Wed Jul 19 17:17:54 1995  Tom Yu  <tlyu@lothlorien.MIT.EDU>
- 
- 	* localaddr.c: also add definition of max if it's not there.
- 
- 	* localaddr.c: fix definition of ifreq_size so it actually works
- 
- Mon Jul 17 16:04:00 1995  Sam Hartman  <hartmans@tertius.mit.edu>
- 
- 	* localaddr.c (krb5_crypto_os_localaddr): Deal with variable sized
-         ifreq structures if sockaddr contains sa_len field.
- 
- 	* configure.in: Check to see if struct sockaddr has sa_len.
- 
- Thu Jul  6 17:13:11 1995  Tom Yu  <tlyu@lothlorien.MIT.EDU>
- 
- 	* localaddr.c: migrated from lib/krb5/os
- 
- 	* ustime.c: migrated from lib/krb5/os; removed context variable
- 		from arglist.
- 
- 	* Makefile.in: don't copy or remove localaddr.c and ustime.c;
- 		they're local now.
- 
- Fri Jun  9 19:18:41 1995    <tytso@rsx-11.mit.edu>
- 
- 	* configure.in: Remove standardized set of autoconf macros, which
- 		are now handled by CONFIG_RULES.
- 
- Thu May 25 22:16:35 1995  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* configure.in, Makefile.in: Add support for shared libraries.
- 
- Thu Apr 13 15:49:16 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* *.[ch]: removed unneeded INTERFACE from non-api functions.
- 
- Sat Mar 25 15:38:23 1995  Mark Eichin  <eichin@cygnus.com>
- 
- 	* Makefile.in (memmove.c): memmove.c is in krb5/posix, not krb5/os.
- 
- Wed Mar 22 11:44:07 1995    <tytso@rsx-11.mit.edu>
- 
- 	* Makefile.in: Use $(SRCTOP) instead of $(srcdir), since Mac's
- 		don't like dealing with $(U)$(U).
- 
- Fri Mar 17 16:21:46 1995  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* Makefile.in: Fix rules for localdr.c, ustime.c, and memmove.c so
- 		that they reference $(srcdir) where appropriate.
- 
- Thu Mar 16 21:24:43 1995  John Gilmore  (gnu at toad.com)
- 
- 	* Makefile.in (LDFLAGS):  Eliminate, comes in from pre.in.
- 	(all-mac):  Add.
- 	(localaddr.c, ustime.c, memmove.c):  Fix paths to work on Mac.
- 
- Tue Mar 14 17:23:02 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Makefile.in: no longer need to bring in ustime and localaddr for
- 	   windows since everything's going into one DLL in the end.
- 
- Thu Mar 2 17:56:48 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Makefile.in: changed LIBNAME for the PC, and  brought in ustime
-            and localaddr from the krb/os directory.
-         * rnd_conf.c: added cast to the seed assignment.
- 
- Mon Feb 20 16:25:36 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Makfile.in: made to work for the PC
-         * rnd_confoun.c: added windows INTERFACE keyword
- 
- Wed Jan 25 20:24:35 1995  John Gilmore  (gnu at toad.com)
- 
- 	* rnd_confoun.c: Replace <.../...> includes with "..."s.
- 
- Mon Oct 24 14:58:14 1994    (tytso@rsx-11)
- 
- 	* configure.in:
- 	* rnd_confoun.c (krb5_random_confounder): Use the srand48/lrand48
- 		functions if available.
- 
- Fri Oct 14 00:21:05 1994  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* Makefile.in: Remove symlinked files on make clean.
- 
--- 0 ----
Index: krb5/lib/crypto/os/Makefile.in
diff -c krb5/lib/crypto/os/Makefile.in:1.1.1.1 krb5/lib/crypto/os/Makefile.in:removed
*** krb5/lib/crypto/os/Makefile.in:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/Makefile.in	Sun Mar 16 20:22:22 2003
***************
*** 1,41 ****
- CFLAGS = $(CCOPTS) $(DEFS)
- 
- ##DOSBUILDTOP = ..\..\..
- ##DOSLIBNAME=..\crypto.lib
- 
- LIBOBJS = @LIBOBJS@
- 
- .c.o:
- 	$(CC) $(CFLAGS) -c $(srcdir)/$*.c
- @SHARED_RULE@
- 
- COBJS=	rnd_confoun.$(OBJEXT) c_localaddr.$(OBJEXT) c_ustime.$(OBJEXT) 
- OBJS= $(COBJS) $(LIBOBJS)
- 
- SRCS=	rnd_confoun.c c_localaddr.c c_ustime.c
- 
- all-unix:: shared $(OBJS)
- 
- all-mac:: $(OBJS)
- 
- all-windows: $(COBJS)
- 
- shared:
- 	mkdir shared
- 	
- memmove.c: $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c
- 	-$(LN) $(SRCTOP)$(S)lib$(S)krb5$(S)posix$(S)memmove.c $@
- 
- memmove.o: memmove.c
- 	$(CC) $(CFLAGS) -c $*.c
- @SHARED_RULE_LOCAL@
- 	
- 
- clean:: 
- 	$(RM) memmove.c
- 
- clean-unix::
- 	$(RM) shared/*
- clean-mac::
- 	$(RM) shared/*
- clean-windows::
--- 0 ----
Index: krb5/lib/crypto/os/c_localaddr.c
diff -c krb5/lib/crypto/os/c_localaddr.c:1.1.1.1 krb5/lib/crypto/os/c_localaddr.c:removed
*** krb5/lib/crypto/os/c_localaddr.c:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/c_localaddr.c	Sun Mar 16 20:22:22 2003
***************
*** 1,295 ****
- /*
-  * lib/crypto/os/c_localaddr.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * Return the protocol addresses supported by this host.
-  *
-  * XNS support is untested, but "Should just work".
-  */
- 
- 
- #define NEED_SOCKETS
- #include "k5-int.h"
- 
- #if !defined(HAVE_MACSOCK_H) && !defined(_MSDOS) && !defined(_WIN32)
- 
- /* needed for solaris, harmless elsewhere... */
- #define BSD_COMP
- #include <sys/ioctl.h>
- #include <sys/time.h>
- #include <errno.h>
- 
- /*
-  * The SIOCGIF* ioctls require a socket.
-  * It doesn't matter *what* kind of socket they use, but it has to be
-  * a socket.
-  *
-  * Of course, you can't just ask the kernel for a socket of arbitrary
-  * type; you have to ask for one with a valid type.
-  *
-  */
- #ifdef KRB5_USE_INET
- 
- #include <netinet/in.h>
- 
- #ifndef USE_AF
- #define USE_AF AF_INET
- #define USE_TYPE SOCK_DGRAM
- #define USE_PROTO 0
- #endif
- 
- #endif
- 
- #ifdef KRB5_USE_NS
- 
- #include <netns/ns.h>
- 
- #ifndef USE_AF
- #define USE_AF AF_NS
- #define USE_TYPE SOCK_DGRAM
- #define USE_PROTO 0		/* guess */
- #endif
- 
- #endif
- /*
-  * Add more address families here.
-  */
- 
- /*
-  * BSD 4.4 defines the size of an ifreq to be
-  * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
-  * However, under earlier systems, sa_len isn't present, so the size is 
-  * just sizeof(struct ifreq)
-  */
- #ifdef HAVE_SA_LEN
- #ifndef max
- #define max(a,b) ((a) > (b) ? (a) : (b))
- #endif
- #define ifreq_size(i) max(sizeof(struct ifreq),\
-      sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
- #else
- #define ifreq_size(i) sizeof(struct ifreq)
- #endif /* HAVE_SA_LEN*/
- 
- 
- 
- extern int errno;
- 
- /*
-  * Return all the protocol addresses of this host.
-  *
-  * We could kludge up something to return all addresses, assuming that
-  * they're valid kerberos protocol addresses, but we wouldn't know the
-  * real size of the sockaddr or know which part of it was actually the
-  * host part.
-  *
-  * This uses the SIOCGIFCONF, SIOCGIFFLAGS, and SIOCGIFADDR ioctl's.
-  */
- 
- krb5_error_code
- krb5_crypto_os_localaddr(addr)
-     krb5_address ***addr;
- {
-     struct ifreq *ifr, ifreq;
-     struct ifconf ifc;
-     int s, code, n, i;
-     char buf[1024];
-     krb5_address *addr_temp [ 1024/sizeof(struct ifreq) ];
-     int n_found;
-     int mem_err = 0;
-     
-     memset(buf, 0, sizeof(buf));
-     ifc.ifc_len = sizeof(buf);
-     ifc.ifc_buf = buf;
-     
-     s = socket (USE_AF, USE_TYPE, USE_PROTO);
-     if (s < 0)
- 	return errno;
- 
-     code = ioctl (s, SIOCGIFCONF, (char *)&ifc);
-     if (code < 0) {
- 	int retval = errno;
- 	closesocket (s);
- 	return retval;
-     }
-     n = ifc.ifc_len;
-     
- n_found = 0;
-     for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
- 	krb5_address *address;
- 	ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i);
- 
- 	strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name));
- 	if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0)
- 	    continue;
- 
- #ifdef IFF_LOOPBACK
- 	if (ifreq.ifr_flags & IFF_LOOPBACK) 
- 	    continue;
- #endif
- 
- 	if (!(ifreq.ifr_flags & IFF_UP)) 
- 	    /* interface is down; skip */
- 	    continue;
- 
- 	/* ifr->ifr_addr has what we want! */
- 	switch (ifr->ifr_addr.sa_family) {
- #ifdef KRB5_USE_INET
- 	case AF_INET:
- 	    {
- 		struct sockaddr_in *in =
- 		    (struct sockaddr_in *)&ifr->ifr_addr;
- 		
- 		address = (krb5_address *)
- 		    malloc (sizeof(krb5_address));
- 		if (address) {
- 		    address->magic = KV5M_ADDRESS;
- 		    address->addrtype = ADDRTYPE_INET;
- 		    address->length = sizeof(struct in_addr);
- 		    address->contents = (unsigned char *)malloc(address->length);
- 		    if (!address->contents) {
- 			krb5_xfree(address);
- 			address = 0;
- 			mem_err++;
- 		    } else {
- 			memcpy ((char *)address->contents,
- 				(char *)&in->sin_addr, 
- 				address->length);
- 			break;
- 		    }
- 		} else mem_err++;
- 	    }
- #endif
- #ifdef KRB5_USE_NS
- 	    case AF_XNS:
- 	    {  
- 		struct sockaddr_ns *ns =
- 		    (struct sockaddr_ns *)&ifr->ifr_addr;
- 		address = (krb5_address *)
- 		    malloc (sizeof (krb5_address) + sizeof (struct ns_addr));
- 		if (address) {
- 		    address->magic = KV5M_ADDRESS;
- 		    address->addrtype = ADDRTYPE_XNS; 
- 
- 		    /* XXX should we perhaps use ns_host instead? */
- 
- 		    address->length = sizeof(struct ns_addr);
- 		    address->contents = (unsigned char *)malloc(address->length);
- 		    if (!address->contents) {
- 			krb5_xfree(address);
- 			address = 0;
- 			mem_err++;
- 		    } else {
- 			memcpy ((char *)address->contents,
- 				(char *)&ns->sns_addr,
- 				address->length);
- 			break;
- 		    }
- 		} else mem_err++;
- 		break;
- 	    }
- #endif
- 	/*
- 	 * Add more address families here..
- 	 */
- 	default:
- 	    continue;
- 	}
- 	if (address)
- 	    addr_temp[n_found++] = address;
- 	address = 0;
-     }
-     closesocket(s);
- 
-     *addr = (krb5_address **)malloc (sizeof (krb5_address *) * (n_found+1));
-     if (*addr == 0)
- 	mem_err++;
-     
-     if (mem_err) {
- 	for (i=0; i<n_found; i++) {
- 	    krb5_xfree(addr_temp[i]);
- 	    addr_temp[i] = 0;
- 	}
- 	return ENOMEM;
-     }
-     
-     for (i=0; i<n_found; i++) {
- 	(*addr)[i] = addr_temp[i];
-     }
-     (*addr)[n_found] = 0;
-     return 0;
- }
- 
- #else /* Windows/Mac version */
- 
- /* No ioctls in winsock so we just assume there is only one networking 
-  * card per machine, so gethostent is good enough. 
-  */
- 
- krb5_error_code
- krb5_crypto_os_localaddr (krb5_address ***addr) {
-     char host[64];                              /* Name of local machine */
-     struct hostent *hostrec;
-     int err;
- 
-     *addr = calloc (2, sizeof (krb5_address *));
-     if (*addr == NULL)
-         return ENOMEM;
- 
- #ifdef HAVE_MACSOCK_H
-     hostrec = getmyipaddr();
- #else /* HAVE_MACSOCK_H */
-     if (gethostname (host, sizeof(host))) {
-         err = WSAGetLastError();
-         return err;
-     }
- 
-     hostrec = gethostbyname (host);
-     if (hostrec == NULL) {
-         err = WSAGetLastError();
-         return err;
-     }
- #endif /* HAVE_MACSOCK_H */
- 
-     (*addr)[0] = calloc (1, sizeof(krb5_address));
-     if ((*addr)[0] == NULL) {
-         free (*addr);
-         return ENOMEM;
-     }
-     (*addr)[0]->magic = KV5M_ADDRESS;
-     (*addr)[0]->addrtype = hostrec->h_addrtype;
-     (*addr)[0]->length = hostrec->h_length;
-     (*addr)[0]->contents = (unsigned char *)malloc((*addr)[0]->length);
-     if (!(*addr)[0]->contents) {
-         free((*addr)[0]);
-         free(*addr);
-         return ENOMEM;
-     } else {
-         memcpy ((*addr)[0]->contents,
-                 hostrec->h_addr,
-                 (*addr)[0]->length);
-     }
- 	/* FIXME, deal with the case where gethostent returns multiple addrs */
- 
-     return(0);
- }
- #endif
--- 0 ----
Index: krb5/lib/crypto/os/c_ustime.c
diff -c krb5/lib/crypto/os/c_ustime.c:1.1.1.1 krb5/lib/crypto/os/c_ustime.c:removed
*** krb5/lib/crypto/os/c_ustime.c:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/c_ustime.c	Sun Mar 16 20:22:22 2003
***************
*** 1,316 ****
- /*
-  * lib/crypto/os/c_ustime.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_mstimeofday for BSD 4.3
-  */
- 
- #define	NEED_SOCKETS
- #include "k5-int.h"
- 
- #ifdef _MACINTOSH
- 
- /* We're a Macintosh -- do Mac time things.  */
- 
- /*
-  * This code is derived from kerberos/src/lib/des/mac_time.c from
-  * the Cygnus Support release of Kerberos V4:
-  *
-  * mac_time.c
-  * (Originally time_stuff.c)
-  * Copyright 1989 by the Massachusetts Institute of Technology.
-  * Macintosh ooperating system interface for Kerberos.
-  */
- 
- #include "AddressXlation.h"	/* for ip_addr, for #if 0'd net-time stuff  */
- 
- #include <script.h>		/* Defines MachineLocation, used by getTimeZoneOffset */
- #include <ToolUtils.h>		/* Defines BitTst(), called by getTimeZoneOffset() */
- #include <OSUtils.h>		/* Defines GetDateTime */
- 
- /* Mac Cincludes */
- #include <string.h>
- #include <stddef.h>
- 
- static krb5_int32 last_sec = 0, last_usec = 0;
- 
- /*
-  * The Unix epoch is 1/1/70, the Mac epoch is 1/1/04.
-  *
-  * 70 - 4 = 66 year differential
-  *
-  * Thus the offset is:
-  *
-  * (66 yrs) * (365 days/yr) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
-  * plus
-  * (17 leap days) * (24 hours/day) * (60 mins/hour) * (60 secs/min)
-  *
-  * Don't forget the offset from GMT.
-  */
- 
- /* returns the offset in hours between the mac local time and the GMT  */
- /* unsigned krb5_int32 */
- krb5_int32
- getTimeZoneOffset()
- {
-     MachineLocation macLocation;
-     long gmtDelta;
- 
-     macLocation.u.gmtDelta=0L;
-     ReadLocation(&macLocation); 
-     gmtDelta=macLocation.u.gmtDelta & 0x00FFFFFF;
-     if (BitTst((void *)&gmtDelta,23L))
- 	gmtDelta |= 0xFF000000;
-     gmtDelta /= 3600L;
-     return(gmtDelta);
- }
- 
- /* Returns the GMT in seconds (and fake microseconds) using the Unix epoch */
- 
- krb5_error_code
- krb5_crypto_us_timeofday(seconds, microseconds)
-     krb5_int32 *seconds, *microseconds;
- {
-     krb5_int32 sec, usec;
-     time_t the_time;
- 
-     GetDateTime (&the_time);
- 
-     sec = the_time - 
-     	((66 * 365 * 24 * 60 * 60) + (17 *  24 * 60 * 60) + 
-     	(getTimeZoneOffset() * 60 * 60));
- 
-     usec = 0;	/* Mac is too slow to count faster than once a second */
- 
-     if ((sec == last_sec) && (usec == last_usec)) {
- 	    if (++last_usec >= 1000000) {
- 		    last_usec = 0;
- 		    last_sec++;
- 	    }
- 	    sec = last_sec;
- 	    usec = last_usec;
-     }
-     else {
- 	    last_sec = sec;
- 	    last_usec = usec;
- 	}
- 
-     *seconds = sec;
-     *microseconds = usec;
- 
-     return 0;
- }
- 
- 
- #elif defined(_WIN32) || defined(_MSDOS)
- 
-    /* Microsoft Windows NT and 95   (32bit)  */
-    /* This one works for WOW (Windows on Windows, ntvdm on Win-NT) */
- 
- #include <time.h>
- #include <sys/timeb.h>
- #include <string.h>
- 
- krb5_error_code
- krb5_crypto_us_timeofday(seconds, microseconds)
- register krb5_int32 *seconds, *microseconds;
- {
-     struct _timeb timeptr;
-     krb5_int32 sec, usec;
-     static krb5_int32 last_sec = 0;
-     static krb5_int32 last_usec = 0;
- 
-     _ftime(&timeptr);                           /* Get the current time */
-     sec  = timeptr.time;
-     usec = timeptr.millitm;
- 
-     if (sec == last_sec) {                      /* Same as last time??? */
-         usec = ++last_usec;                     /* Yep, so do microseconds */
-         if (usec >= 1000000) {
-             ++sec;
-             usec = 0;
-         }
-     }
-     last_sec = sec;                             /* Remember for next time */
-     last_usec = usec;
- 
-     *seconds = sec;                             /* Return the values */
-     *microseconds = usec;
- 
-     return 0;
- }
- 
- #elif defined (_MSDOS)
- 
- 
- /*
-  * Originally written by John Gilmore, Cygnus Support, May '94.
-  * Public Domain.
-  */
- 
- #include <time.h>
- #include <sys/timeb.h>
- #include <dos.h>
- #include <string.h>
- 
- /*
-  * Time handling.  Translate Unix time calls into Kerberos internal 
-  * procedure calls.
-  *
-  * Due to the fact that DOS time can be unreliable we have reverted
-  * to using the AT hardware clock and converting it to Unix time.
-  */
- 
- static time_t win_gettime ();
- static long win_time_get_epoch();               /* Adjust for MSC 7.00 bug */
- 
- krb5_error_code
- krb5_crypto_us_timeofday(seconds, microseconds)
- register krb5_int32 *seconds, *microseconds;
- {
-     krb5_int32 sec, usec;
-     static krb5_int32 last_sec = 0;
-     static krb5_int32 last_usec = 0;
- 
-     sec = win_gettime ();                       /* Get the current time */
-     usec = 0;                                   /* Can't do microseconds */
- 
-     if (sec == last_sec) {                      /* Same as last time??? */
-         usec = ++last_usec;                     /* Yep, so do microseconds */
-         if (usec >= 1000000) {
-             ++sec;
-             usec = 0;
-         }
-     }
-     last_sec = sec;                             /* Remember for next time */
-     last_usec = usec;
- 
-     *seconds = sec;                             /* Return the values */
-     *microseconds = usec;
- 
-     return 0;
- }
- 
- 
- static time_t
- win_gettime () {
-     struct tm tm;
-     union _REGS inregs;                         /* For calling BIOS */
-     union _REGS outregs;
-     struct _timeb now;
-     time_t time;
-     long convert;                               /* MSC 7.00 bug work around */
- 
-     _ftime(&now);                               /* Daylight savings time */
- 
-     /* Get time from AT hardware clock INT 0x1A, AH=2 */
-     memset(&inregs, 0, sizeof(inregs));
-     inregs.h.ah = 2;
-     _int86(0x1a, &inregs, &outregs);
- 
-     /* 0x13 = decimal 13, hence the decoding below */
-     tm.tm_sec = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F);
-     tm.tm_min = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
-     tm.tm_hour = 10 * ((outregs.h.ch & 0xF0) >> 4) + (outregs.h.ch & 0x0F);
- 
-     /* Get date from AT hardware clock INT 0x1A, AH=4 */
-     memset(&inregs, 0, sizeof(inregs));
-     inregs.h.ah = 4;
-     _int86(0x1a, &inregs, &outregs);
- 
-     tm.tm_mday = 10 * ((outregs.h.dl & 0xF0) >> 4) + (outregs.h.dl & 0x0F);
-     tm.tm_mon = 10 * ((outregs.h.dh & 0xF0) >> 4) + (outregs.h.dh & 0x0F) - 1;
-     tm.tm_year = 10 * ((outregs.h.cl & 0xF0) >> 4) + (outregs.h.cl & 0x0F);
-     tm.tm_year += 100 * ((10 * (outregs.h.ch & 0xF0) >> 4)
- 	            + (outregs.h.ch & 0x0F) - 19);
- 
-     tm.tm_wday = 0;
-     tm.tm_yday = 0;
-     tm.tm_isdst = now.dstflag;
- 
-     time = mktime(&tm);
- 
-     convert = win_time_get_epoch();
-     return time + convert;
- 
- }
- 
- 
- /*
-  * This routine figures out the current time epoch and returns the
-  * conversion factor.  It exists because 
-  * Microloss screwed the pooch on the time() and _ftime() calls in
-  * its release 7.0 libraries.  They changed the epoch to Dec 31, 1899!
-  * Idiots...   We try to cope.
-  */
- 
- static struct tm jan_1_70 = {0, 0, 0, 1, 0, 70};
- static long epoch = 0;
- static int epoch_set = 0;
- 
- long
- win_time_get_epoch()
- {
- 
-     if (!epoch_set) {
-         epoch = 0 - mktime (&jan_1_70);	/* Seconds til 1970 localtime */
-         epoch += _timezone;		/* Seconds til 1970 GMT */
-         epoch_set = 1;
-     }
-     return epoch;
- }
- 
- 
- #else
- 
- 
- /* We're a Unix machine -- do Unix time things.  */
- 
- extern int errno;
- 
- static struct timeval last_tv = {0, 0};
- 
- krb5_error_code
- krb5_crypto_us_timeofday(seconds, microseconds)
-     register krb5_int32 *seconds, *microseconds;
- {
-     struct timeval tv;
- 
-     if (gettimeofday(&tv, (struct timezone *)0) == -1) {
- 	/* failed, return errno */
- 	return (krb5_error_code) errno;
-     }
-     if ((tv.tv_sec == last_tv.tv_sec) && (tv.tv_usec == last_tv.tv_usec)) {
- 	    if (++last_tv.tv_usec >= 1000000) {
- 		    last_tv.tv_usec = 0;
- 		    last_tv.tv_sec++;
- 	    }
- 	    tv = last_tv;
-     } else 
- 	    last_tv = tv;
- 	    
-     *seconds = tv.tv_sec;
-     *microseconds = tv.tv_usec;
-     return 0;
- }
- 
- #endif
--- 0 ----
Index: krb5/lib/crypto/os/configure.in
diff -c krb5/lib/crypto/os/configure.in:1.1.1.1 krb5/lib/crypto/os/configure.in:removed
*** krb5/lib/crypto/os/configure.in:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/configure.in	Sun Mar 16 20:22:22 2003
***************
*** 1,9 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- AC_LN_S
- AC_REPLACE_FUNCS(memmove)
- AC_HAVE_FUNCS(srand48 srand srandom getpid)
- KRB5_SOCKADDR_SA_LEN
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/os/rnd_confoun.c
diff -c krb5/lib/crypto/os/rnd_confoun.c:1.1.1.1 krb5/lib/crypto/os/rnd_confoun.c:removed
*** krb5/lib/crypto/os/rnd_confoun.c:1.1.1.1	Mon Jun  2 17:57:46 1997
--- krb5/lib/crypto/os/rnd_confoun.c	Sun Mar 16 20:22:22 2003
***************
*** 1,98 ****
- /*
-  * lib/crypto/os/rnd_confoun.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_random_confounder()
-  */
- 
- #include "k5-int.h"
- 
- #ifdef HAVE_SYS_TIME_H
- #include <sys/time.h>
- #ifdef TIME_WITH_SYS_TIME
- #include <time.h>
- #endif
- #else
- #include <time.h>
- #endif
- 
- #ifdef HAVE_SRAND48
- #define SRAND	srand48
- #define RAND	lrand48
- #define RAND_TYPE	long
- #endif
- 
- #if !defined(RAND_TYPE) && defined(HAVE_SRAND)
- #define SRAND	srand
- #define RAND	rand
- #define RAND_TYPE	int
- #endif
- 
- #if !defined(RAND_TYPE) && defined(HAVE_SRANDOM)	
- #define SRAND	srandom
- #define RAND	random
- #define RAND_TYPE	long
- #endif
- 
- #if !defined(RAND_TYPE)
- You need a random number generator!
- #endif
- 
- /*
-  * Generate a random confounder
-  */
- krb5_error_code
- krb5_random_confounder(size, fillin)
- int size;
- krb5_pointer fillin;
- {
-     static int seeded = 0;
-     register krb5_octet *real_fill;
-     RAND_TYPE	rval;
- 
-     if (!seeded) {
- 	/* time() defined in 4.12.2.4, but returns a time_t, which is an
- 	   "arithmetic type" (4.12.1) */
- 	rval = (RAND_TYPE) time(0);
- 	SRAND(rval);
- #ifdef HAVE_GETPID
- 	rval = RAND();
- 	rval ^= getpid();
- 	SRAND(rval);
- #endif
- 	seeded = 1;
-     }
- 
-     real_fill = (krb5_octet *)fillin;
-     while (size > 0) {
- 	rval = RAND();
- 	*real_fill = rval & 0xff;
- 	real_fill++;
- 	size--;
- 	if (size) {
- 	    *real_fill = (rval >> 8) & 0xff;
- 	    real_fill++;
- 	    size--;
- 	}
-     }
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/sha/ChangeLog
diff -c krb5/lib/crypto/sha/ChangeLog:1.1.1.1 krb5/lib/crypto/sha/ChangeLog:removed
*** krb5/lib/crypto/sha/ChangeLog:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/ChangeLog	Sun Mar 16 20:22:22 2003
***************
*** 1,45 ****
- Wed Aug 28 17:40:53 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
- 
- 	* shs.c: Only include sys/types.h if present.
- 
- 	* configure.in: Check for sys/types.h
- 
- Thu Jun 13 10:54:27 1996  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* hmac_sha.c: Include string.h for memcpy prototype
- 
- Sat Jun  8 07:44:35 1996  Ezra Peisach  (epeisach@mit.edu)
- 
- 	* shs.c (longReverse): Test for big vs little endian failed for
- 		little endian machines.
- 
- Thu Jun  6 15:43:26 1996  Theodore Y. Ts'o  <tytso@mit.edu>
- 
- 	* shs.c (longReverse): Don't use htonl(); it doesn't exist under
- 		Windows.  Instead do the test by casting a pointer to an
- 		integer to a char *.
- 
- Mon May 20 17:15:32 1996  Theodore Y. Ts'o  <tytso@mit.edu>
- 
- 	* t_shs.c (main): Don't do timing tests; it takes too long!
- 
- Tue May 14 17:09:36 1996  Richard Basch  <basch@lehman.com>
- 
- 	* .Sanitize: reflect current files
- 	* Makefile.in: added hmac-sha
- 	* hmac_sha.c: implement HMAC-SHA
- 	* sha_crypto.c: use hmac-sha
- 	* sha_glue.c: sanity check the passed in checksum length
- 	* shs.h: replaced sha-des3 with hmac-sha
- 
- Fri May 10 11:19:53 1996  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* shs.c (longReverse): Remove extraneous \.
- 		(expand): Start #define in first column.
- 
- Fri May 10 01:19:18 1996  Richard Basch  <basch@lehman.com>
- 
- 	* Makefile.in configure.in t_shs.c sha_glue.c sha_crypto.c shs.c shs.h:
- 	Initial check-in of the functions to support the NIST FIPS 180
- 	SHA algorithm.  Provide interfaces for cksum-sha, cksum-sha-des3.
- 	(enctype-des3-sha is also being defined)
--- 0 ----
Index: krb5/lib/crypto/sha/Makefile.in
diff -c krb5/lib/crypto/sha/Makefile.in:1.1.1.1 krb5/lib/crypto/sha/Makefile.in:removed
*** krb5/lib/crypto/sha/Makefile.in:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/Makefile.in	Sun Mar 16 20:22:22 2003
***************
*** 1,47 ****
- CFLAGS = $(CCOPTS) $(DEFS) -I$(srcdir)/../des
- 
- ##DOSBUILDTOP = ..\..\..
- ##DOSLIBNAME=..\crypto.lib
- 
- .c.o:
- 	$(CC) $(CFLAGS) -c $(srcdir)/$*.c
- @SHARED_RULE@
- 
- OBJS=	shs.$(OBJEXT)		\
- 	hmac_sha.$(OBJEXT)	\
- 	sha_crypto.$(OBJEXT)	\
- 	sha_glue.$(OBJEXT)
- 
- SRCS=	$(srcdir)/shs.c		\
- 	$(srcdir)/hmac_sha.c	\
- 	$(srcdir)/sha_crypto.c	\
- 	$(srcdir)/sha_glue.c
- 
- 
- all-unix:: shared $(OBJS) 
- all-mac:: shared $(OBJS) 
- all-windows:: $(OBJS)
- 
- shared:
- 	mkdir shared
- 
- t_shs: t_shs.o shs.o
- 	$(CC) $(CFLAGS) $(LDFLAGS) -o t_shs t_shs.o shs.o
- 
- t_shs.exe:
- 	$(CC) $(CFLAGS2) -o t_shs.exe t_shs.c shs.c
- 
- check-unix:: t_shs
- 	$(C)t_shs -x
- 
- check-windows:: t_shs$(EXEEXT)
- 	$(C)t_shs$(EXEEXT) -x
- 
- clean:: 
- 	$(RM) t_shs$(EXEEXT) t_shs.$(OBJEXT)
- 
- clean-unix::
- 	$(RM) shared/*
- clean-mac::
- 	$(RM) shared/*
- clean-windows::
--- 0 ----
Index: krb5/lib/crypto/sha/configure.in
diff -c krb5/lib/crypto/sha/configure.in:1.1.1.1 krb5/lib/crypto/sha/configure.in:removed
*** krb5/lib/crypto/sha/configure.in:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/configure.in	Sun Mar 16 20:22:22 2003
***************
*** 1,7 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- dnl AC_DEFINE(NEW_SHS)
- V5_SHARED_LIB_OBJS
- AC_CHECK_HEADERS(sys/types.h)
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/crypto/sha/hmac_sha.c
diff -c krb5/lib/crypto/sha/hmac_sha.c:1.1.1.1 krb5/lib/crypto/sha/hmac_sha.c:removed
*** krb5/lib/crypto/sha/hmac_sha.c:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/hmac_sha.c	Sun Mar 16 20:22:22 2003
***************
*** 1,78 ****
- #include <string.h>
- #include "shs.h"
- 
- #define PAD_SZ	64
- 
- 
- krb5_error_code
- hmac_sha(text, text_len, key, key_len, digest)
-     krb5_octet	* text;			/* pointer to data stream */
-     int		text_len;		/* length of data stream */
-     krb5_octet	* key;			/* pointer to authentication key */
-     int		key_len;		/* length of authentication key */
-     krb5_octet	* digest;		/* caller digest to be filled in */
- {
-     SHS_INFO context;
-     krb5_octet k_ipad[PAD_SZ];	/* inner padding - key XORd with ipad */
-     krb5_octet k_opad[PAD_SZ];	/* outer padding - key XORd with opad */
-     int i;
-  
-     /* sanity check parameters */
-     if (!text || !key || !digest)
- 	/* most heinous, probably should log something */
- 	return EINVAL;
- 
-     /* if key is longer than 64 bytes reset it to key=MD5(key) */
-     if (key_len > sizeof(k_ipad)) {
- 	shsInit(&context);
- 	shsUpdate(&context, key, key_len);
- 	shsFinal(&context);
- 
- 	memcpy(digest, context.digest, SHS_DIGESTSIZE);
- 	key = digest;
- 	key_len = SHS_DIGESTSIZE;
-     }
-  
-     /*
-      * the HMAC_SHA transform looks like:
-      *
-      * SHA(K XOR opad, SHA(K XOR ipad, text))
-      *
-      * where K is an n byte key
-      * ipad is the byte 0x36 repeated 64 times
-      * opad is the byte 0x5c repeated 64 times
-      * and text is the data being protected
-      */
-  
-     /* start out by storing key in pads */
-     memset(k_ipad, 0x36, sizeof(k_ipad));
-     memset(k_opad, 0x5c, sizeof(k_opad));
- 
-     /* XOR key with ipad and opad values */
-     for (i = 0; i < key_len; i++) {
- 	k_ipad[i] ^= key[i];
- 	k_opad[i] ^= key[i];
-     }
- 
-     /*
-      * perform inner SHA
-      */
-     shsInit(&context);
-     shsUpdate(&context, k_ipad, sizeof(k_ipad));
-     shsUpdate(&context, text, text_len);
-     shsFinal(&context);
- 
-     memcpy(digest, context.digest, SHS_DIGESTSIZE);
-     
-     /*
-      * perform outer SHA
-      */
-     shsInit(&context);
-     shsUpdate(&context, k_opad, sizeof(k_opad));
-     shsUpdate(&context, digest, SHS_DIGESTSIZE);
-     shsFinal(&context);
- 
-     memcpy(digest, context.digest, SHS_DIGESTSIZE);
- 
-     return 0;
- }
--- 0 ----
Index: krb5/lib/crypto/sha/sha_crypto.c
diff -c krb5/lib/crypto/sha/sha_crypto.c:1.1.1.1 krb5/lib/crypto/sha/sha_crypto.c:removed
*** krb5/lib/crypto/sha/sha_crypto.c:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/sha_crypto.c	Sun Mar 16 20:22:22 2003
***************
*** 1,78 ****
- #include "k5-int.h"
- #include "shs.h"
- #include "des_int.h"	/* we cheat a bit and call it directly... */
- 
- /* Windows needs to these prototypes for the assignment below */
- 
- static krb5_error_code
- krb5_sha_crypto_sum_func
- 	PROTOTYPE((krb5_pointer in,
- 		   size_t in_length,
- 		   krb5_pointer seed,
- 		   size_t seed_length,
- 		   krb5_checksum FAR *outcksum));
- 
- static krb5_error_code
- krb5_sha_crypto_verify_func
- 	PROTOTYPE((krb5_checksum FAR *cksum,
- 		   krb5_pointer in,
- 		   size_t in_length,
- 		   krb5_pointer seed,
- 		   size_t seed_length));
- 
- static krb5_error_code
- shs_crypto_sum_func(in, in_length, seed, seed_length, outcksum)
-     krb5_pointer in;
-     size_t in_length;
-     krb5_pointer seed;
-     size_t seed_length;
-     krb5_checksum FAR *outcksum;
- {
-     krb5_error_code retval;
- 
-     if (outcksum->length < HMAC_SHA_CKSUM_LENGTH)
- 	return KRB5_BAD_MSIZE;
- 
-     outcksum->checksum_type = CKSUMTYPE_HMAC_SHA;
-     outcksum->length = HMAC_SHA_CKSUM_LENGTH;
- 
-     retval = hmac_sha(in, in_length, seed, seed_length, outcksum->contents);
-     return retval;
- }
- 
- static krb5_error_code
- shs_crypto_verify_func(cksum, in, in_length, seed, seed_length)
-     krb5_checksum FAR *cksum;
-     krb5_pointer in;
-     size_t in_length;
-     krb5_pointer seed;
-     size_t seed_length;
- {
-     krb5_octet digest[HMAC_SHA_CKSUM_LENGTH];
-     krb5_error_code retval;
- 
-     if (cksum->checksum_type != CKSUMTYPE_HMAC_SHA)
- 	return KRB5KRB_AP_ERR_INAPP_CKSUM;
-     if (cksum->length != HMAC_SHA_CKSUM_LENGTH)
- 	return KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 
-     retval = hmac_sha(in, in_length, seed, seed_length, digest);
-     if (retval) goto cleanup;
- 
-     if (memcmp((char *)digest, (char *)cksum->contents, cksum->length))
- 	retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 
- cleanup:
-     memset((char *)digest, 0, sizeof(digest));
-     return retval;
- }
- 
- krb5_checksum_entry hmac_sha_cksumtable_entry =
- {
-     0,
-     shs_crypto_sum_func,
-     shs_crypto_verify_func,
-     HMAC_SHA_CKSUM_LENGTH,
-     1,					/* is collision proof */
-     1,					/* uses key */
- };
--- 0 ----
Index: krb5/lib/crypto/sha/sha_glue.c
diff -c krb5/lib/crypto/sha/sha_glue.c:1.1.1.1 krb5/lib/crypto/sha/sha_glue.c:removed
*** krb5/lib/crypto/sha/sha_glue.c:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/sha_glue.c	Sun Mar 16 20:22:22 2003
***************
*** 1,85 ****
- #include "k5-int.h"
- #include "shs.h"
- 
- krb5_error_code
- krb5_sha_sum_func
- 	PROTOTYPE((krb5_pointer		in,
- 		   size_t		in_length,
- 		   krb5_pointer		seed,
- 		   size_t		seed_length,
- 		   krb5_checksum	*outcksum));
- 
- krb5_error_code
- krb5_sha_verify_func
- 	PROTOTYPE((krb5_checksum	FAR *cksum,
- 		   krb5_pointer		in,
- 		   size_t		in_length,
- 		   krb5_pointer		seed,
- 		   size_t		seed_length));
- 
- krb5_error_code
- krb5_sha_sum_func(in, in_length, seed, seed_length, outcksum)
- 	krb5_pointer	in;
- 	size_t		in_length;
- 	krb5_pointer	seed;
- 	size_t		seed_length;
- 	krb5_checksum	*outcksum;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     SHS_INFO working;
- 
-     if (outcksum->length < SHS_DIGESTSIZE)
- 	return KRB5_BAD_MSIZE;
-     
-     shsInit(&working);
-     shsUpdate(&working, input, in_length);
-     shsFinal(&working);
- 
-     outcksum->checksum_type = CKSUMTYPE_NIST_SHA;
-     outcksum->length = SHS_DIGESTSIZE;
- 
-     memcpy((char *)outcksum->contents,
- 	   (char *)&working.digest[0],
- 	   outcksum->length);
-     memset((char *)&working, 0, sizeof(working));
-     return 0;
- }
- 
- krb5_error_code
- krb5_sha_verify_func(cksum, in, in_length, seed, seed_length)
- 	krb5_checksum	FAR *cksum;
- 	krb5_pointer	in;
- 	size_t		in_length;
- 	krb5_pointer	seed;
- 	size_t		seed_length;
- {
-     krb5_octet *input = (krb5_octet *)in;
-     SHS_INFO working;
-     krb5_error_code retval;
- 
-     if (cksum->checksum_type != CKSUMTYPE_NIST_SHA)
- 	return KRB5KRB_AP_ERR_INAPP_CKSUM;
-     if (cksum->length != SHS_DIGESTSIZE)
- 	return KRB5KRB_AP_ERR_BAD_INTEGRITY;
- 
-     shsInit(&working);
-     shsUpdate(&working, input, in_length);
-     shsFinal(&working);
- 
-     retval = 0;
-     if (memcmp((char *) cksum->contents,
- 	       (char *) &working.digest[0],
- 	       cksum->length))
- 	retval = KRB5KRB_AP_ERR_BAD_INTEGRITY;
-     memset((char *) &working, 0, sizeof(working));
-     return retval;
- }
- 
- krb5_checksum_entry nist_sha_cksumtable_entry = {
-     0,
-     krb5_sha_sum_func,
-     krb5_sha_verify_func,
-     SHS_DIGESTSIZE,
-     1,					/* is collision proof */
-     0,					/* doesn't use key */
- };
--- 0 ----
Index: krb5/lib/crypto/sha/shs.c
diff -c krb5/lib/crypto/sha/shs.c:1.1.1.1 krb5/lib/crypto/sha/shs.c:removed
*** krb5/lib/crypto/sha/shs.c:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/shs.c	Sun Mar 16 20:22:22 2003
***************
*** 1,338 ****
- #ifdef HAVE_SYS_TYPES_H
- #include <sys/types.h>
- #endif
- #include <string.h>
- #include "shs.h"
- 
- /* The SHS f()-functions.  The f1 and f3 functions can be optimized to
-    save one boolean operation each - thanks to Rich Schroeppel,
-    rcs@cs.arizona.edu for discovering this */
- 
- #define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
- #define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
- #define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
- #define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
- 
- /* The SHS Mysterious Constants */
- 
- #define K1  0x5A827999L                                 /* Rounds  0-19 */
- #define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
- #define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
- #define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
- 
- /* SHS initial values */
- 
- #define h0init  0x67452301L
- #define h1init  0xEFCDAB89L
- #define h2init  0x98BADCFEL
- #define h3init  0x10325476L
- #define h4init  0xC3D2E1F0L
- 
- /* Note that it may be necessary to add parentheses to these macros if they
-    are to be called with expressions as arguments */
- 
- /* 32-bit rotate left - kludged with shifts */
- 
- #define ROTL(n,X)  ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
- 
- /* The initial expanding function.  The hash function is defined over an
-    80-word expanded input array W, where the first 16 are copies of the input
-    data, and the remaining 64 are defined by
- 
-         W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
- 
-    This implementation generates these values on the fly in a circular
-    buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
-    optimization.
- 
-    The updated SHS changes the expanding function by adding a rotate of 1
-    bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
-    for this information */
- 
- #ifdef NEW_SHS
- #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
-                                                  W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )))
- #else
- #define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^ \
- 		      W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )
- #endif /* NEW_SHS */
- 
- /* The prototype SHS sub-round.  The fundamental sub-round is:
- 
-         a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
-         b' = a;
-         c' = ROTL( 30, b );
-         d' = c;
-         e' = d;
- 
-    but this is implemented by unrolling the loop 5 times and renaming the
-    variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
-    This code is then replicated 20 times for each of the 4 functions, using
-    the next 20 values from the W[] array each time */
- 
- #define subRound(a, b, c, d, e, f, k, data) \
-     ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
- 
- /* Initialize the SHS values */
- 
- void shsInit(shsInfo)
-     SHS_INFO *shsInfo;
- {
-     /* Set the h-vars to their initial values */
-     shsInfo->digest[ 0 ] = h0init;
-     shsInfo->digest[ 1 ] = h1init;
-     shsInfo->digest[ 2 ] = h2init;
-     shsInfo->digest[ 3 ] = h3init;
-     shsInfo->digest[ 4 ] = h4init;
- 
-     /* Initialise bit count */
-     shsInfo->countLo = shsInfo->countHi = 0;
- }
- 
- /* Perform the SHS transformation.  Note that this code, like MD5, seems to
-    break some optimizing compilers due to the complexity of the expressions
-    and the size of the basic block.  It may be necessary to split it into
-    sections, e.g. based on the four subrounds
- 
-    Note that this corrupts the shsInfo->data area */
- 
- static void SHSTransform KRB5_PROTOTYPE((LONG *digest, LONG *data));
- 
- static
- void SHSTransform(digest, data)
-     LONG *digest;
-     LONG *data;
- {
-     LONG A, B, C, D, E;     /* Local vars */
-     LONG eData[ 16 ];       /* Expanded data */
- 
-     /* Set up first buffer and local data buffer */
-     A = digest[ 0 ];
-     B = digest[ 1 ];
-     C = digest[ 2 ];
-     D = digest[ 3 ];
-     E = digest[ 4 ];
-     memcpy( eData, data, SHS_DATASIZE );
- 
-     /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
-     subRound( A, B, C, D, E, f1, K1, eData[  0 ] );
-     subRound( E, A, B, C, D, f1, K1, eData[  1 ] );
-     subRound( D, E, A, B, C, f1, K1, eData[  2 ] );
-     subRound( C, D, E, A, B, f1, K1, eData[  3 ] );
-     subRound( B, C, D, E, A, f1, K1, eData[  4 ] );
-     subRound( A, B, C, D, E, f1, K1, eData[  5 ] );
-     subRound( E, A, B, C, D, f1, K1, eData[  6 ] );
-     subRound( D, E, A, B, C, f1, K1, eData[  7 ] );
-     subRound( C, D, E, A, B, f1, K1, eData[  8 ] );
-     subRound( B, C, D, E, A, f1, K1, eData[  9 ] );
-     subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
-     subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
-     subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
-     subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
-     subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
-     subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
-     subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
-     subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
-     subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
-     subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
- 
-     subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
-     subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
-     subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
-     subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
-     subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
-     subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
-     subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
-     subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
-     subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
-     subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
-     subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
-     subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
-     subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
-     subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
-     subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
-     subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
-     subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
-     subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
-     subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
-     subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
- 
-     subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
-     subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
-     subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
-     subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
-     subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
-     subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
-     subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
-     subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
-     subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
-     subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
-     subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
-     subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
-     subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
-     subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
-     subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
-     subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
-     subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
-     subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
-     subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
-     subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
- 
-     subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
-     subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
-     subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
-     subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
-     subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
-     subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
-     subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
-     subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
-     subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
-     subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
-     subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
-     subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
-     subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
-     subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
-     subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
-     subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
-     subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
-     subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
-     subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
-     subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
- 
-     /* Build message digest */
-     digest[ 0 ] += A;
-     digest[ 1 ] += B;
-     digest[ 2 ] += C;
-     digest[ 3 ] += D;
-     digest[ 4 ] += E;
- }
- 
- /* When run on a little-endian CPU we need to perform byte reversal on an
-    array of longwords.  It is possible to make the code endianness-
-    independant by fiddling around with data at the byte level, but this
-    makes for very slow code, so we rely on the user to sort out endianness
-    at compile time */
- 
- void longReverse( LONG *buffer, int byteCount )
- {
-     LONG value;
-     static int init = 0;
-     char *cp;
- 
-     switch (init) {
-     case 0:
- 	init=1;
- 	cp = (char *) &init;
- 	if (*cp == 1) {
- 	    init=2;
- 	    break;
- 	}
- 	init=1;
- 	/* fall through - MSB */
-     case 1:
- 	return;
-     }
- 
-     byteCount /= sizeof( LONG );
-     while( byteCount-- ) {
-         value = *buffer;
-         value = ( ( value & 0xFF00FF00L ) >> 8  ) | 
-                 ( ( value & 0x00FF00FFL ) << 8 );
-         *buffer++ = ( value << 16 ) | ( value >> 16 );
-     }
- }
- 
- /* Update SHS for a block of data */
- 
- void shsUpdate(shsInfo, buffer, count)
-     SHS_INFO *shsInfo;
-     BYTE *buffer;
-     int count;
- {
-     LONG tmp;
-     int dataCount;
- 
-     /* Update bitcount */
-     tmp = shsInfo->countLo;
-     if ( ( shsInfo->countLo = tmp + ( ( LONG ) count << 3 ) ) < tmp )
-         shsInfo->countHi++;             /* Carry from low to high */
-     shsInfo->countHi += count >> 29;
- 
-     /* Get count of bytes already in data */
-     dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
- 
-     /* Handle any leading odd-sized chunks */
-     if( dataCount )
-         {
-         BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
- 
-         dataCount = SHS_DATASIZE - dataCount;
-         if( count < dataCount )
-             {
-             memcpy( p, buffer, count );
-             return;
-             }
-         memcpy( p, buffer, dataCount );
-         longReverse( shsInfo->data, SHS_DATASIZE );
-         SHSTransform( shsInfo->digest, shsInfo->data );
-         buffer += dataCount;
-         count -= dataCount;
-         }
- 
-     /* Process data in SHS_DATASIZE chunks */
-     while( count >= SHS_DATASIZE )
-         {
-         memcpy( shsInfo->data, buffer, SHS_DATASIZE );
-         longReverse( shsInfo->data, SHS_DATASIZE );
-         SHSTransform( shsInfo->digest, shsInfo->data );
-         buffer += SHS_DATASIZE;
-         count -= SHS_DATASIZE;
-         }
- 
-     /* Handle any remaining bytes of data. */
-     memcpy( shsInfo->data, buffer, count );
- }
- 
- /* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
-    1 0* (64-bit count of bits processed, MSB-first) */
- 
- void shsFinal(shsInfo)
-     SHS_INFO *shsInfo;
- {
-     int count;
-     BYTE *dataPtr;
- 
-     /* Compute number of bytes mod 64 */
-     count = ( int ) shsInfo->countLo;
-     count = ( count >> 3 ) & 0x3F;
- 
-     /* Set the first char of padding to 0x80.  This is safe since there is
-        always at least one byte free */
-     dataPtr = ( BYTE * ) shsInfo->data + count;
-     *dataPtr++ = 0x80;
- 
-     /* Bytes of padding needed to make 64 bytes */
-     count = SHS_DATASIZE - 1 - count;
- 
-     /* Pad out to 56 mod 64 */
-     if( count < 8 )
-         {
-         /* Two lots of padding:  Pad the first block to 64 bytes */
-         memset( dataPtr, 0, count );
-         longReverse( shsInfo->data, SHS_DATASIZE );
-         SHSTransform( shsInfo->digest, shsInfo->data );
- 
-         /* Now fill the next block with 56 bytes */
-         memset( shsInfo->data, 0, SHS_DATASIZE - 8 );
-         }
-     else
-         /* Pad block to 56 bytes */
-         memset( dataPtr, 0, count - 8 );
- 
-     /* Append length in bits and transform */
-     shsInfo->data[ 14 ] = shsInfo->countHi;
-     shsInfo->data[ 15 ] = shsInfo->countLo;
- 
-     longReverse( shsInfo->data, SHS_DATASIZE - 8 );
-     SHSTransform( shsInfo->digest, shsInfo->data );
- }
--- 0 ----
Index: krb5/lib/crypto/sha/shs.h
diff -c krb5/lib/crypto/sha/shs.h:1.1.1.1 krb5/lib/crypto/sha/shs.h:removed
*** krb5/lib/crypto/sha/shs.h:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/shs.h	Sun Mar 16 20:22:22 2003
***************
*** 1,60 ****
- #ifndef _SHS_DEFINED
- 
- #include <krb5.h>
- 
- #define _SHS_DEFINED
- 
- /* Some useful types */
- 
- typedef krb5_octet	BYTE;
- typedef krb5_ui_4	LONG;
- 
- /* Exit status of functions. */
- 
- #define OK      0
- #define ERROR   -1
- 
- /* Define the following to use the updated SHS implementation */
- 
- #define NEW_SHS         /**/
- 
- /* The SHS block size and message digest sizes, in bytes */
- 
- #define SHS_DATASIZE    64
- #define SHS_DIGESTSIZE  20
- 
- /* The structure for storing SHS info */
- 
- typedef struct {
-                LONG digest[ 5 ];            /* Message digest */
-                LONG countLo, countHi;       /* 64-bit bit count */
-                LONG data[ 16 ];             /* SHS data buffer */
-                } SHS_INFO;
- 
- /* Message digest functions (shs.c) */
- void shsInit
- 	KRB5_PROTOTYPE((SHS_INFO *shsInfo));
- void shsUpdate
- 	KRB5_PROTOTYPE((SHS_INFO *shsInfo, BYTE *buffer, int count));
- void shsFinal
- 	KRB5_PROTOTYPE((SHS_INFO *shsInfo));
- 
- 
- /* Keyed Message digest functions (hmac_sha.c) */
- krb5_error_code hmac_sha
- 	KRB5_PROTOTYPE((krb5_octet *text,
- 			int text_len,
- 			krb5_octet *key,
- 			int key_len,
- 			krb5_octet *digest));
- 
- 
- #define NIST_SHA_CKSUM_LENGTH		SHS_DIGESTSIZE
- #define HMAC_SHA_CKSUM_LENGTH		SHS_DIGESTSIZE
- 
- 
- extern krb5_checksum_entry
-     nist_sha_cksumtable_entry,
-     hmac_sha_cksumtable_entry;
- 
- #endif /* _SHS_DEFINED */
--- 0 ----
Index: krb5/lib/crypto/sha/t_shs.c
diff -c krb5/lib/crypto/sha/t_shs.c:1.1.1.1 krb5/lib/crypto/sha/t_shs.c:removed
*** krb5/lib/crypto/sha/t_shs.c:1.1.1.1	Mon Jun  2 17:57:47 1997
--- krb5/lib/crypto/sha/t_shs.c	Sun Mar 16 20:22:22 2003
***************
*** 1,120 ****
- /****************************************************************************
- *                                                                           *
- *                               SHS Test Code                               *
- *                                                                           *
- ****************************************************************************/
- 
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include "shs.h"
- 
- /* Test the SHS implementation */
- 
- #ifdef NEW_SHS
- 
- static LONG shsTestResults[][ 5 ] = {
-     { 0xA9993E36L, 0x4706816AL, 0xBA3E2571L, 0x7850C26CL, 0x9CD0D89DL, },
-     { 0x84983E44L, 0x1C3BD26EL, 0xBAAE4AA1L, 0xF95129E5L, 0xE54670F1L, },
-     { 0x34AA973CL, 0xD4C4DAA4L, 0xF61EEB2BL, 0xDBAD2731L, 0x6534016FL, }
-     };
- 
- #else
- 
- static LONG shsTestResults[][ 5 ] = {
-     { 0x0164B8A9L, 0x14CD2A5EL, 0x74C4F7FFL, 0x082C4D97L, 0xF1EDF880L },
-     { 0xD2516EE1L, 0xACFA5BAFL, 0x33DFC1C4L, 0x71E43844L, 0x9EF134C8L },
-     { 0x3232AFFAL, 0x48628A26L, 0x653B5AAAL, 0x44541FD9L, 0x0D690603L }
-     };
- #endif /* NEW_SHS */
- 
- static int compareSHSresults(shsInfo, shsTestLevel)
- SHS_INFO *shsInfo;
- int shsTestLevel;
- {
-     int i;
- 
-     /* Compare the returned digest and required values */
-     for( i = 0; i < 5; i++ )
-         if( shsInfo->digest[ i ] != shsTestResults[ shsTestLevel ][ i ] )
-             return( ERROR );
-     return( OK );
- }
- 
- main()
- {
-     SHS_INFO shsInfo;
-     unsigned int i;
-     time_t secondCount;
-     BYTE data[ 200 ];
- 
-     /* Make sure we've got the endianness set right.  If the machine is
-        big-endian (up to 64 bits) the following value will be signed,
-        otherwise it will be unsigned.  Unfortunately we can't test for odd
-        things like middle-endianness without knowing the size of the data
-        types */
- 
-     /* Test SHS against values given in SHS standards document */
-     printf( "Running SHS test 1 ... " );
-     shsInit( &shsInfo );
-     shsUpdate( &shsInfo, ( BYTE * ) "abc", 3 );
-     shsFinal( &shsInfo );
-     if( compareSHSresults( &shsInfo, 0 ) == ERROR )
-         {
-         putchar( '\n' );
-         puts( "SHS test 1 failed" );
-         exit( ERROR );
-         }
- #ifdef NEW_SHS
-     puts( "passed, result= A9993E364706816ABA3E25717850C26C9CD0D89D" );
- #else
-     puts( "passed, result= 0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880" );
- #endif /* NEW_SHS */
- 
-     printf( "Running SHS test 2 ... " );
-     shsInit( &shsInfo );
-     shsUpdate( &shsInfo, ( BYTE * ) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56 );
-     shsFinal( &shsInfo );
-     if( compareSHSresults( &shsInfo, 1 ) == ERROR )
-         {
-         putchar( '\n' );
-         puts( "SHS test 2 failed" );
-         exit( ERROR );
-         }
- #ifdef NEW_SHS
-     puts( "passed, result= 84983E441C3BD26EBAAE4AA1F95129E5E54670F1" );
- #else
-     puts( "passed, result= D2516EE1ACFA5BAF33DFC1C471E438449EF134C8" );
- #endif /* NEW_SHS */
- 
-     printf( "Running SHS test 3 ... " );
-     shsInit( &shsInfo );
-     for( i = 0; i < 15625; i++ )
-         shsUpdate( &shsInfo, ( BYTE * ) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64 );
-     shsFinal( &shsInfo );
-     if( compareSHSresults( &shsInfo, 2 ) == ERROR )
-         {
-         putchar( '\n' );
-         puts( "SHS test 3 failed" );
-         exit( ERROR );
-         }
- #ifdef NEW_SHS
-     puts( "passed, result= 34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" );
- #else
-     puts( "passed, result= 3232AFFA48628A26653B5AAA44541FD90D690603" );
- #endif /* NEW_SHS */
- 
- #if 0
-     printf( "\nTesting speed for 100MB data... " );
-     shsInit( &shsInfo );
-     secondCount = time( NULL );
-     for( i = 0; i < 500000U; i++ )
-         shsUpdate( &shsInfo, data, 200 );
-     secondCount = time( NULL ) - secondCount;
-     printf( "done.  Time = %ld seconds, %ld kbytes/second.\n", \
-             secondCount, 100500L / secondCount );
- #endif
- 
-     puts( "\nAll SHS tests passed" );
-     exit( OK );
- }
--- 0 ----
Index: krb5/lib/des425/.cvsignore
diff -c /dev/null krb5/lib/des425/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:23 2003
--- krb5/lib/des425/.cvsignore	Thu Jun  5 10:39:12 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/gssapi/.cvsignore
diff -c /dev/null krb5/lib/gssapi/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:23 2003
--- krb5/lib/gssapi/.cvsignore	Thu Jun  5 10:39:14 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/gssapi/generic/.cvsignore
diff -c /dev/null krb5/lib/gssapi/generic/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:23 2003
--- krb5/lib/gssapi/generic/.cvsignore	Thu Jun  5 10:39:15 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/gssapi/generic/configure.in
diff -c krb5/lib/gssapi/generic/configure.in:1.1.1.1 krb5/lib/gssapi/generic/configure.in:removed
*** krb5/lib/gssapi/generic/configure.in:1.1.1.1	Mon Jun  2 17:55:50 1997
--- krb5/lib/gssapi/generic/configure.in	Sun Mar 16 20:22:23 2003
***************
*** 1,14 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_PROG_AWK
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- AC_CHECK_HEADERS(stdlib.h sys/types.h limits.h)
- AC_SIZE_T
- AC_CHECK_SIZEOF(short)
- AC_CHECK_SIZEOF(int)
- AC_CHECK_SIZEOF(long)
- CopyHeader(gssapi.h,[$(EHDRDIR)])
- CopySrcHeader(gssapi_generic.h,[$(EHDRDIR)])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/gssapi/generic/util_token.c
diff -c krb5/lib/gssapi/generic/util_token.c:1.1.1.2 krb5/lib/gssapi/generic/util_token.c:1.3
*** krb5/lib/gssapi/generic/util_token.c:1.1.1.2	Fri Feb 22 16:34:34 2002
--- krb5/lib/gssapi/generic/util_token.c	Sun Feb 24 21:26:20 2002
***************
*** 21,30 ****
   */
  
  #include "gssapiP_generic.h"
  #include <memory.h>
  
  /*
!  * $Id: util_token.c,v 1.1.1.2 2002/02/22 21:34:34 kenh Exp $
   */
  
  /* XXXX this code currently makes the assumption that a mech oid will
--- 21,32 ----
   */
  
  #include "gssapiP_generic.h"
+ #ifdef HAVE_MEMORY_H
  #include <memory.h>
+ #endif
  
  /*
!  * $Id: util_token.c,v 1.3 2002/02/25 02:26:20 kenh Exp $
   */
  
  /* XXXX this code currently makes the assumption that a mech oid will
Index: krb5/lib/gssapi/krb5/.cvsignore
diff -c /dev/null krb5/lib/gssapi/krb5/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:23 2003
--- krb5/lib/gssapi/krb5/.cvsignore	Thu Jun  5 10:39:16 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/gssapi/krb5/accept_sec_context.c
diff -c krb5/lib/gssapi/krb5/accept_sec_context.c:1.1.1.4 krb5/lib/gssapi/krb5/accept_sec_context.c:1.5
*** krb5/lib/gssapi/krb5/accept_sec_context.c:1.1.1.4	Mon Aug 12 15:44:49 2002
--- krb5/lib/gssapi/krb5/accept_sec_context.c	Mon Aug 12 15:58:36 2002
***************
*** 76,82 ****
  #include <assert.h>
  
  /*
!  * $Id: accept_sec_context.c,v 1.1.1.4 2002/08/12 19:44:49 kenh Exp $
   */
  
  /* Decode, decrypt and store the forwarded creds in the local ccache. */
--- 76,82 ----
  #include <assert.h>
  
  /*
!  * $Id: accept_sec_context.c,v 1.5 2002/08/12 19:58:36 kenh Exp $
   */
  
  /* Decode, decrypt and store the forwarded creds in the local ccache. */
Index: krb5/lib/gssapi/krb5/configure.in
diff -c krb5/lib/gssapi/krb5/configure.in:1.1.1.1 krb5/lib/gssapi/krb5/configure.in:removed
*** krb5/lib/gssapi/krb5/configure.in:1.1.1.1	Mon Jun  2 17:55:53 1997
--- krb5/lib/gssapi/krb5/configure.in	Sun Mar 16 20:22:23 2003
***************
*** 1,9 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_AWK
- AC_PROG_INSTALL
- AC_CHECK_HEADERS(stdlib.h)
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- CopySrcHeader(gssapi_krb5.h,[$](BUILDTOP)/include/gssapi)
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/gssapi/krb5/gssapiP_krb5.h
diff -c krb5/lib/gssapi/krb5/gssapiP_krb5.h:1.1.1.5 krb5/lib/gssapi/krb5/gssapiP_krb5.h:1.7
*** krb5/lib/gssapi/krb5/gssapiP_krb5.h:1.1.1.5	Mon Aug 12 15:44:49 2002
--- krb5/lib/gssapi/krb5/gssapiP_krb5.h	Mon Aug 12 15:58:36 2002
***************
*** 48,54 ****
  #define _GSSAPIP_KRB5_H_
  
  /*
!  * $Id: gssapiP_krb5.h,v 1.1.1.5 2002/08/12 19:44:49 kenh Exp $
   */
  
  #if TARGET_OS_MAC
--- 48,54 ----
  #define _GSSAPIP_KRB5_H_
  
  /*
!  * $Id: gssapiP_krb5.h,v 1.7 2002/08/12 19:58:36 kenh Exp $
   */
  
  #if TARGET_OS_MAC
Index: krb5/lib/gssapi/krb5/init_sec_context.c
diff -c krb5/lib/gssapi/krb5/init_sec_context.c:1.1.1.5 krb5/lib/gssapi/krb5/init_sec_context.c:1.5
*** krb5/lib/gssapi/krb5/init_sec_context.c:1.1.1.5	Mon Aug 12 15:44:50 2002
--- krb5/lib/gssapi/krb5/init_sec_context.c	Mon Aug 12 15:58:36 2002
***************
*** 76,82 ****
  #include <assert.h>
  
  /*
!  * $Id: init_sec_context.c,v 1.1.1.5 2002/08/12 19:44:50 kenh Exp $
   */
  
  /* XXX This is for debugging only!!!  Should become a real bitfield
--- 76,82 ----
  #include <assert.h>
  
  /*
!  * $Id: init_sec_context.c,v 1.5 2002/08/12 19:58:36 kenh Exp $
   */
  
  /* XXX This is for debugging only!!!  Should become a real bitfield
Index: krb5/lib/gssapi/krb5/k5unseal.c
diff -c krb5/lib/gssapi/krb5/k5unseal.c:1.1.1.2 krb5/lib/gssapi/krb5/k5unseal.c:1.3
*** krb5/lib/gssapi/krb5/k5unseal.c:1.1.1.2	Fri Feb 22 16:34:44 2002
--- krb5/lib/gssapi/krb5/k5unseal.c	Sun Feb 24 21:26:25 2002
***************
*** 47,56 ****
   */
  
  #include "gssapiP_krb5.h"
  #include <memory.h>
  
  /*
!  * $Id: k5unseal.c,v 1.1.1.2 2002/02/22 21:34:44 kenh Exp $
   */
  
  /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
--- 47,58 ----
   */
  
  #include "gssapiP_krb5.h"
+ #ifdef HAVE_MEMORY_H
  #include <memory.h>
+ #endif
  
  /*
!  * $Id: k5unseal.c,v 1.3 2002/02/25 02:26:25 kenh Exp $
   */
  
  /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX
Index: krb5/lib/gssapi/krb5/util_cksum.c
diff -c krb5/lib/gssapi/krb5/util_cksum.c:1.1.1.2 krb5/lib/gssapi/krb5/util_cksum.c:1.3
*** krb5/lib/gssapi/krb5/util_cksum.c:1.1.1.2	Fri Feb 22 16:34:47 2002
--- krb5/lib/gssapi/krb5/util_cksum.c	Sun Feb 24 21:26:26 2002
***************
*** 21,27 ****
   */
  
  /*
!  * $Id: util_cksum.c,v 1.1.1.2 2002/02/22 21:34:47 kenh Exp $
   */
  
  #include "gssapiP_krb5.h"
--- 21,27 ----
   */
  
  /*
!  * $Id: util_cksum.c,v 1.3 2002/02/25 02:26:26 kenh Exp $
   */
  
  #include "gssapiP_krb5.h"
Index: krb5/lib/gssapi/krb5/util_crypt.c
diff -c krb5/lib/gssapi/krb5/util_crypt.c:1.1.1.3 krb5/lib/gssapi/krb5/util_crypt.c:1.4
*** krb5/lib/gssapi/krb5/util_crypt.c:1.1.1.3	Mon Aug 12 15:44:51 2002
--- krb5/lib/gssapi/krb5/util_crypt.c	Mon Aug 12 15:58:36 2002
***************
*** 51,57 ****
  #include <memory.h>
  
  /*
!  * $Id: util_crypt.c,v 1.1.1.3 2002/08/12 19:44:51 kenh Exp $
   */
  
  int
--- 51,57 ----
  #include <memory.h>
  
  /*
!  * $Id: util_crypt.c,v 1.4 2002/08/12 19:58:36 kenh Exp $
   */
  
  int
Index: krb5/lib/gssapi/krb5/util_seed.c
diff -c krb5/lib/gssapi/krb5/util_seed.c:1.1.1.2 krb5/lib/gssapi/krb5/util_seed.c:1.3
*** krb5/lib/gssapi/krb5/util_seed.c:1.1.1.2	Fri Feb 22 16:34:48 2002
--- krb5/lib/gssapi/krb5/util_seed.c	Sun Feb 24 21:26:27 2002
***************
*** 24,30 ****
  #include <memory.h>
  
  /*
!  * $Id: util_seed.c,v 1.1.1.2 2002/02/22 21:34:48 kenh Exp $
   */
  
  static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
--- 24,30 ----
  #include <memory.h>
  
  /*
!  * $Id: util_seed.c,v 1.3 2002/02/25 02:26:27 kenh Exp $
   */
  
  static unsigned char zeros[16] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
Index: krb5/lib/gssapi/mechglue/.cvsignore
diff -c /dev/null krb5/lib/gssapi/mechglue/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:24 2003
--- krb5/lib/gssapi/mechglue/.cvsignore	Thu Jun  5 10:39:18 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/gssapi/mechglue/configure.in
diff -c krb5/lib/gssapi/mechglue/configure.in:1.1.1.1 krb5/lib/gssapi/mechglue/configure.in:removed
*** krb5/lib/gssapi/mechglue/configure.in:1.1.1.1	Mon Jun  2 17:55:59 1997
--- krb5/lib/gssapi/mechglue/configure.in	Sun Mar 16 20:22:24 2003
***************
*** 1,26 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_PROG_INSTALL
- AC_CHECK_HEADERS(stdlib.h)
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- CopySrcHeader(mechglue.h,[$(EHDRDIR)])
- AC_CANONICAL_HOST
- case $host in
-      *-*-aix*) # don't build libgssapi.a on AIX
-        ;;
-      *)
-        V5_MAKE_SHARED_LIB(libgssapi,1.0,.., ./mechglue)
-        AppendRule([install:: libgssapi.[$](LIBEXT)
- 	       [$](INSTALL_DATA) libgssapi.[$](LIBEXT) [$](DESTDIR)[$](KRB5_LIBDIR)[$](S)libgssapi.[$](LIBEXT)])
-        LinkFileDir([$](TOPLIBD)/libgssapi.[$](LIBEXT),libgssapi.[$](LIBEXT),./gssapi/mechglue)
-        AppendRule([all:: [$](TOPLIBD)/libgssapi.[$](LIBEXT)])
- 
-       ;;
- esac
- 
- V5_AC_OUTPUT_MAKEFILE
- 
--- 0 ----
Index: krb5/lib/kadm/ChangeLog
diff -c krb5/lib/kadm/ChangeLog:1.1.1.1 krb5/lib/kadm/ChangeLog:removed
*** krb5/lib/kadm/ChangeLog:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/ChangeLog	Sun Mar 16 20:22:24 2003
***************
*** 1,344 ****
- Tue Sep 24 13:25:50 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
- 
- 	* Makefile.in: Eliminate extra files not needed for Macintosh and
-  		Windows.  (This directory is only used for Windows and
-  		Macintosh at this point.)
- 
- Tue Sep 10 14:37:47 1996  Tom Yu  <tlyu@mit.edu>
- 
- 	* krb5strings.M: remove extra args to .TH
- 
- Thu Jun 13 22:12:21 1996  Tom Yu  <tlyu@voltage-multiplier.mit.edu>
- 
- 	* configure.in: remove ref to ET_RULES
- 
- Mon Jun 10 21:42:26 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
- 
- 	* adm_conn.c:
- 	* adm_kw_dec.c:
- 	* adm_kw_enc.c: Change use of _WINDOWS to _MSDOS, and add check
- 		for _WIN32
- 
- Tue May 21 20:51:06 1996  Sam Hartman  <hartmans@mit.edu>
- 
- 	* Makefile.in (check-unix):  Use KRB5_RUN_FLAGS
- 
- Sun May 12 00:46:57 1996  Marc Horowitz  <marc@mit.edu>
- 
- 	* alt_prof.c (krb5_read_realm_params): added "acl_file" variable
-  	for the admin server.
- 
- Wed Mar 13 17:37:00 1996  Ken Raeburn  <raeburn@cygnus.com>
- 
- 	* configure.in: Use AC_HEADER_STDARG.
- 
- Sun Dec 10 11:02:56 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* str_conv.c (krb5_input_flag_to_string): Add new routine.
- 
- Wed Nov  8 02:46:54 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* alt_prof.c (krb5_free_realm_params): Free the realm_kdc_ports
- 		element of the structure.
- 
- Fri Oct  6 00:30:16 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Remove ##DOS!include of config/windows.in.
- 		config/windows.in is now included by wconfig.
- 
- 	* logger.c (klog_vsyslog): Make the logs less verbose, by omitting
- 		the hostname, pid, etc. information.
- 
- Thu Oct  5 19:46:40 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* alt_prof.c (krb5_read_realm_params): Remove the profile
- 		relation, since it's really a bad idea.  Removed the
- 		"port" and "secondary_port" relations, and replaced them
- 		with the "kdc_port" relation, which takes a list of ports.
- 
- Mon Oct  2 15:08:53 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* logger.c (krb5_klog_init): If the log file can't be opened,
- 		print an intelligent error message.
- 
- Thu Oct  5 12:06:35 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* alt_prof.c (krb5_read_realm_params): If secure flag is set in
- 		context, do not allow for environment variables to specify
- 		configuration files.
- 
- Tue Sep 26 02:31:38 1995  Mark Eichin  <eichin@cygnus.com>
- 
- 	* adm_conn.c (kadm_get_creds): zero out creds->server after
- 	freeing it to protect later attempts.
- 
- Fri Sep 29 17:06:18 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* logger.c: #ifdef the entire file so it's not built under Windows.
- 
- Tue Sep 27 12:00:00 1995    <jrivlin@fusion.com>
- 
- 	* adm_kw_dec.c (krb5_adm_proto_to_dbent): Routine removed for 
- 		Windows and Mac to match with the prototype.
- 
- 	* adm_kw_dec.c (krb5_adm_dbent_to_proto): Routine removed for 
- 		Windows and Mac to match with the prototype.
- 
- Tue Sep 26 16:24:00 1995    <tytso@rsts-11.mit.edu>
- 
- 	* alt_prof.c (krb5_read_realm_params): On an error, initialize the
- 		returned rparams pointer to NULL.
- 
- Mon Sep 25 16:54:18 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the
- 		Makefile. 
- 
- Fri Sep 22 12:00:00 1995  James Mattly  <mattly@fusion.com>
- 
- 	* adm_conn.c:  for sockets changed close to closesocket, sockets on
- 		macintosh arn't files.
- 
- Fri Sep 22 15:44:02 1995  Mark Eichin  <eichin@cygnus.com>
- 
- 	* logger.c (klog_com_err_proc): pass whoami in failure messages
- 	for error log failures to match format string.
- 
- Wed Sep 13 10:45:25 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* keysalt.c: 16/32 bit integer mismatch.
- 	* str_conv.c: 	sftime_format_table is conditional upon HAVE_STRFTIME,
- 		cast some constants to long so that math wouldn't overflow,
- 		16/32 bit integer size mismatch.
- 
- Wed Sep 13 18:17:30 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* alt_prof.c (krb5_read_realm_params): Fix memory leak.  Free the
- 		default realm when we're done.  Remove the "profile"
- 		parameter from the kdc.conf file.  This is bad idea,
- 		architecturally.
- 
- Tue Sep 12 13:18:42 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* adm_conn.c: For Macintosh hardwire cache name. Various casting
- 		fixes. 
- 
- Thu Sep  7 17:50:15 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* adm_conn.c (kadm_get_creds): Use KRB5_ADM_SERVICE_INSTANCE for
- 		the instance name, instead of KRB5_ADM_SERVICE_NAME.
- 
- Wed Sep 06 14:20:57 1995   Chris Provenzano (proven@mit.edu)
- 
-         * adm_kt_dec.c, adm_kt_enc.c, alt_prof.c, keysalt.c, str_conv.c : 
- 		s/keytype/enctype/g, s/KEYTYPE/ENCTYPE/g
- 
- Tue Sep 05 22:10:34 1995   Chris Provenzano (proven@mit.edu)
- 
-         * adm_kt_dec.c, adm_kt_enc.c, alt_prof.c, str_conv.c: 
- 		Remove krb5_enctype references, and replace 
- 		with krb5_keytype where appropriate
- 
- Tue Aug 29 15:31:50 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* .Sanitize, krb5strings.M - Add new manpage describing string syntax
- 		for common datatypes handled by str_conv.c.
- 
- Thu Aug 24 18:53:32 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* .Sanitize: Update file list
- 
- Mon Aug 21 17:07:56 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* str_conv.c - Add krb5_timestamp_to_sfstring().  This converts time
- 		to a short string, potentially filled.  Use strftime() for
- 		krb5_timestamp_to_string() if present so that locale-dependent
- 		time format is used.
- 
- 
- Tue Aug 8 17:35:10 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* str_conv.c - Fix Purify complaint.
- 
- 
- Mon Aug 7 17:38:45 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* keysalt.c(krb5_string_to_keysalt) - Don't do the silly whitespace
- 		filling logic.  If the string has imbedded whitespace, then
- 		it's just tough rocks.  Save replaced string separators and
- 		terminators so that they string looks the same coming out as
- 		going in.
- 
- 
- Fri Aug 4 16:21:50 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* Makefile.in, .Sanitize, keysalt.c - Add keysalt.c modules.
- 
- 
- Thu Aug 3 11:51:14 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* alt_prof.c - Actually pass back the parsed string value in krb5_aprof_
- 		get_deltat().
- 
- 
- Mon Jul 31 15:52:40 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* adm_kw_{enc,dec}.c - Add support for new kadmin protocol.
- 	* alt_prof.c - Remove string conversion routine, use the ones in str_
- 		conv.c.  Convert krb5_read_realm_params() to use these string
- 		conversion routines so that the KDC profile is more textual
- 		as opposed to being numeric.
- 	* str_conv.c - String conversion routines.
- 	* Makefile.in, configure.in - Add support for str_conv.c
- 	* t_dbentry.c - Test new kadmin protocol.
- 
- Mon Jul 17 15:16:26 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* alt_prof.c - Add krb5_{read,free}_realm_params() to read in per-
- 		realm KDC data and to free the allocated structure.
- 
- Mon Jul 10 17:59:23 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* adm_kt_dec.c, adm_kt_enc.c, adm_kw_dec.c, adm_kw_enc.c,
- 		alt_prof.c, logger.c: Include adm_proto.h for prototypes.
- 
- Fri Jul 7 16:23:57 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* Makefile.in - Remove LDFLAGS, it's set by configure.  Find com_err
- 		library in TOPLIBD now.
- 
- Thu Jul  6 17:34:22 1995  Tom Yu  <tlyu@lothlorien.MIT.EDU>
- 
- 	* adm_conn.c (kadm_get_creds): Pass kcontext to os_localaddr.
- 
- Tue Jun 27 15:50:31 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* alt_prof.c - Change filename and hierarchy lists to be const char.
- 
- 
- Thu Jun 22 11:56:15 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* alt_prof.c - New jacket routines for handling profiles.  This includes
- 		the ability to parse certain string values to appropriate types
- 		(e.g. delta time or 32-bit integer).
- 	* Makefile.in - Add alt_prof.c
- 
- 
- Thu Jun 15 18:03:40 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* Makefile.in - Remove explicit copying of archive library to library
- 		directory.
- 	* configure.in - Create symlink for archive when we build it.
- 
- Wed Jun 14 14:36:13 1995  Sam Hartman  <hartmans@tardis.MIT.EDU>
- 
- 	* t_dbentry.c (main): option should be an int so that comparisons
-         against EOF work when char unsigned.
- 
- Tue Jun 13 14:37:25 1995  Sam Hartman  <hartmans@tardis.MIT.EDU>
- 
- 	* logger.c: Don't check to make sure unix is defined for
-         DEVICE_OPEN et al.  Currently, there are no special cases where
-         special handling is required; if they are, then they should be
-         checked for, and the generic case taken if no special case fits.
-         The previous behavior broke under AIX.
- 
- 
- Sun Jun 11 09:24:06 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* Makefile.in (clean-unix): Remove $(UNIX_OBJS)
- 
- Sat Jun 10 23:05:23 1995  Tom Yu  (tlyu@dragons-lair)
- 
- 	* adm_conn.c, adm_rw.c: krb5_auth_context redefinitions
- 
- Fri Jun  9 19:26:44 1995    <tytso@rsx-11.mit.edu>
- 
- 	* configure.in: Remove standardized set of autoconf macros, which
- 		are now handled by CONFIG_RULES.
- 
- Thu Jun  8 23:32:28 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: $($(WHAT)_OBJS) is not accepted by all Makes!  We
- 		assume for now that libkadm.a rule is only used by Unix,
- 		which should be a valid assumption, and build handle
- 		$(UNIX_OBJS) there.
- 
- Thu Jun 8 14:32:33 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* logger.c - New module to provide profile-controlled logging.  This
- 		can optionally take over control of com_err(3) output to also
- 		direct this output to where the profile specifies.  Also
- 		includes a syslog(3) compatible interface which also follows
- 		the profile's direction.
- 	* Makefile.in, configure.in - update for logger.c
- 
- 
- Mon Jun 5 14:15:37 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* adm_conn.c - Rework kadm_get_ccache() and kadm_get_creds() so that
- 		we can specify differing credentials caches and the lifetime
- 		of obtained tickets if not using an existing ccache.  This
- 		changes the calling sequence of krb5_adm_connect(), adding
- 		two arguments: a ccache name and a (delta) lifetime.  Default
- 		ccache name changes formats to tkt_kadm_<pid> and default
- 		lifetime is 10 minutes.
- 
- Fri Jun 2 17:56:03 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* adm_conn.c: used SOCKET_ERRNO instead of errno and 
- 	   added prototypes for the local functions.
- 	* adm_rw.c: added prototypes for the local functions so that
- 	   ints get promoted to longs correctly on the PC.
- 
- Wed May 31 08:10:13 1995  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* Makefile.in (DB_OBJS): Change DBOBJS to DB_OBJS to match rest of
- 		Makefile.in 
- 
- Tue May 30 17:36:47 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* adm_rw.c: removed INTERFACE from two routines.
- 
- Tue May 30 10:35:07 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* adm_conn.c: used Windows specific way of creating a temp file.
- 	* Makefile.in: PC doesn't need to compile adm_kw_*.c files.
- 
- Thu May 25 17:49:06 1995 Keith Vetter (keithv@fusion.com)
- 
- 	First pass to make the code compile cleanly on the PC.
- 	* Makefile.in: made to work on the PC.
- 	* adm_conn.c: used atoi instead of sscanf since it can't be
- 	   used in a windows DLL. Why not? Ask Microsoft.
- 	* adm_kt_e.c, adm_kw_e.c, adm_rw.c: made the explicit the
- 	   cast to a char when pulling out bytes from an int.
- 	* adm_kw_d.c: size_t != off_t on the PC. Fixed the equation.
- 	* adm_rw.c: two parameters were declared as int but prototyped
- 	   as krb5_int32.
- 
- Tue May 16 13:58:30 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* configure.in	- Check for srand48, srand and srandom along with
- 			  network libraries.
- 	* t_ktentry.c, t_dbentry.c - Use available random number generator
- 			  and also make sure memory is freed so we don't
- 			  chew up memory in tester.
- 
- 
- Tue May 16 13:19:04 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* t_dbentry.c	- Change isset to is_a_set to keep Ultrix happy.  Also
- 			  correctly calculate the length of the standard pwd.
- 			  so that we don't overwrite the end of the malloc()ed
- 			  string.
- 	* t_ktentry.c	- Remove isset logic, no differentiation for keytabs.
- 
- 
- Tue May 16 10:35:54 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* t_dbentry.c, t_ktentry.c - new test modules for encode/decode
- 		functions.  These convert to and from krb5_db_entry and
- 		krb5_keytab_entry and verify contents.
- 	* adm_kt_enc.c	- Fix bug encoding integer values.
- 
- 
- Tue May 9 15:21:49 EDT 1995	Paul Park	(pjpark@mit.edu)
- 	* adm_conn.c	- use profile information to locate the admin_server.
- 			  Also, return the correct value from krb5_adm_connect
- 			  instead of always returning zero.
- 	* adm_{kw,kt}_{enc,dec}.c - New modules to [en/de]code administrative
- 			  protocol keyword=value pairs and keytab entries.
- 
- 
- Fri Apr 28 09:47:29 EDT 1995	Paul Park	(pjpark@mit.edu)
- 
- 	Create a new library consisting of functions which communicate with
- 	the administrative server here.  These modules replace the originals
- 	which used to be in libkrb5.
- 
- 	adm_rw.c	- Remove ntohl/htonl in favor of byte blasting.
- 
--- 0 ----
Index: krb5/lib/kadm/Makefile.in
diff -c krb5/lib/kadm/Makefile.in:1.1.1.1 krb5/lib/kadm/Makefile.in:removed
*** krb5/lib/kadm/Makefile.in:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/Makefile.in	Sun Mar 16 20:22:24 2003
***************
*** 1,98 ****
- CFLAGS = $(CCOPTS) $(DEFS) 
- 
- ##DOSBUILDTOP = ..\..
- ##DOSLIBNAME=kadm.lib
- RUN_SETUP=@KRB5_RUN_ENV@
- BASE_OBJS= adm_conn.$(OBJEXT)	\
- 	adm_kt_dec.$(OBJEXT)	\
- 	adm_kt_enc.$(OBJEXT)	\
- 	adm_rw.$(OBJEXT)
- 
- # Unused for Macintosh and windows....
- #	alt_prof.$(OBJEXT)	\
- #	str_conv.$(OBJEXT)	\
- #	keysalt.$(OBJEXT)
- 
- 
- UNIX_OBJS = logger.$(OBJEXT)
- 
- DB_OBJS= adm_kw_dec.$(OBJEXT)	\
- 	adm_kw_enc.$(OBJEXT)
- 
- OBJS=	$(BASE_OBJS) $(DB_OBJS) 
- 
- SRCS=	$(srcdir)/adm_conn.c	\
- 	$(srcdir)/adm_kt_dec.c	\
- 	$(srcdir)/adm_kt_enc.c	\
- 	$(srcdir)/adm_rw.c
- 
- # Unused for Macintosh and windows
- #	$(srcdir)/logger.c	\
- #	$(srcdir)/alt_prof.c	\
- #	$(srcdir)/str_conv.c	\
- #	$(srcdir)/keysalt.c
- #	$(srcdir)/adm_kw_dec.c	\
- #	$(srcdir)/adm_kw_enc.c
- 
- 
- all:: $(BASE_OBJS) 
- 
- all-unix:: $(DB_OBJS) $(UNIX_OBJS)
- all-unix:: libkadm.a
- all-mac:: $(DB_OBJS)
- all-windows::
- 
- libkadm.a: $(OBJS) $(UNIX_OBJS)
- 	$(RM) $@
- 	$(ARADD) $@ $(OBJS) $(UNIX_OBJS)
- 	$(RANLIB) $@
- 
- install:: libkadm.a
- 	$(INSTALL_DATA) libkadm.a $(DESTDIR)$(KRB5_LIBDIR)/libkadm.a
- 	$(RANLIB) $(DESTDIR)$(KRB5_LIBDIR)/libkadm.a
- 
- clean-unix::
- 	$(RM) libkadm.$(LIBEXT) $(UNIX_OBJS)
- clean-mac::
- 	$(RM) libkadm.$(LIBEXT)
- clean-windows::
- 	$(RM) kadm.lib kadm.bak
- 
- #
- # t_dbentry
- #
- T_DBENTRY_OBJS =  t_dbentry.$(OBJEXT) \
- 		$(TOPLIBD)/libkadm.a $(TOPLIBD)/libkdb5.a \
- 		$(TOPLIBD)/libkrb5.a $(TOPLIBD)/libcrypto.a \
- 		$(TOPLIBD)/libcom_err.a
- 
- t_dbentry:	$(T_DBENTRY_OBJS)
- 	$(LD) -o t_dbentry $(T_DBENTRY_OBJS) $(LIBS)
- 
- #
- # t_ktentry
- #
- T_KTENTRY_OBJS =  t_ktentry.$(OBJEXT) \
- 		$(TOPLIBD)/libkadm.a $(TOPLIBD)/libkrb5.a	\
- 		$(TOPLIBD)/libcrypto.a $(TOPLIBD)/libcom_err.a
- 
- t_ktentry:	$(T_KTENTRY_OBJS)
- 	$(LD) -o t_ktentry $(T_KTENTRY_OBJS) $(LIBS)
- 
- TEST_PROGS	= t_dbentry t_ktentry
- 
- check-unix::	$(TEST_PROGS)
- 	$(RUN_SETUP) ./t_dbentry -r 100
- 	$(RUN_SETUP) ./t_ktentry -r 100
- 
- check-mac::
- 
- check-windows::
- 
- clean-unix::
- 	$(RM) t_dbentry$(EXEEXT) t_dbentry.$(OBJEXT)
- 	$(RM) t_ktentry$(EXEEXT) t_ktentry.$(OBJEXT)
- clean-mac::
- 	$(RM) t_dbentry$(EXEEXT) t_dbentry.$(OBJEXT)
- 	$(RM) t_ktentry$(EXEEXT) t_ktentry.$(OBJEXT)
- 
--- 0 ----
Index: krb5/lib/kadm/adm_conn.c
diff -c krb5/lib/kadm/adm_conn.c:1.1.1.1 krb5/lib/kadm/adm_conn.c:removed
*** krb5/lib/kadm/adm_conn.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_conn.c	Sun Mar 16 20:22:24 2003
***************
*** 1,762 ****
- /*
-  * lib/kadm/adm_conn.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- /*
-  * Routines to contact an administrative protocol server.
-  */
- #define	NEED_SOCKETS
- #define	NEED_LOWLEVEL_IO
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- #if	HAVE_PWD_H
- #include <pwd.h>
- #endif	/* HAVE_PWD_H */
- 
- /* Default ticket life is 10 minutes */
- #define	KADM_DEFAULT_LIFETIME	(10*60)
- 
- /*
-  * Strings
-  */
- static char *kadm_cache_name_fmt =	"FILE:/tmp/tkt_kadm_%d";
- 
- /*
-  * Prototypes for local functions
-  */
- static krb5_error_code kadm_get_ccache
- 	PROTOTYPE((krb5_context,
- 		   char *,
- 		   char *,
- 		   krb5_ccache *,
- 		   krb5_principal *));
- static krb5_error_code kadm_get_creds
- 	PROTOTYPE((krb5_context,
- 		krb5_ccache ,
- 		krb5_principal,
- 		krb5_creds  *,
- 		char *,
- 		char *,
- 		krb5_timestamp));
- static krb5_error_code kadm_contact_server
- 	PROTOTYPE((krb5_context,
- 		krb5_data *,
- 		int *,
- 		krb5_address **,
- 		krb5_address **));
- static krb5_error_code kadm_get_auth
- 	PROTOTYPE((krb5_context,
- 		krb5_auth_context *,
- 		krb5_address *,
- 		krb5_address *));
- 
- /*
-  * kadm_get_ccache()	- Initialze a credentials cache.
-  * 
-  * Cleanup after success by calling krb5_cc_destroy() and krb5_free_principal()
-  * Allocates new ccache and client.
-  */
- static krb5_error_code
- kadm_get_ccache(kcontext, user, ccname, ccache, client)
-     krb5_context	kcontext;
-     char		*user;
-     char		*ccname;
-     krb5_ccache		*ccache;
-     krb5_principal	*client;
- {
-     krb5_error_code	kret;
-     char		*name;
-     int 		did_malloc = 0;
-     char		new_cache[MAXPATHLEN];
-     krb5_principal	tprinc;
- 
-     /* Initialize. */
-     *client = (krb5_principal) NULL;
-     tprinc = (krb5_principal) NULL;
- 
-     /*
-      * If a name specified, then use that one, else get it from our
-      * current uid.
-      */
-     if (user) {
- 	name = user;
-     }
-     else {
- #if	HAVE_PWD_H
- 	struct passwd *pw;
- 
- 	pw = getpwuid(getuid());
- 	if (pw) {
- 	    name = (char *) malloc(strlen(pw->pw_name)+1);
- 	    did_malloc = 1;
- 	    strcpy(name, pw->pw_name);
- 	}
- 	else {
- 	    kret = errno;
- 	    goto cleanup;
- 	}
- #else	/* HAVE_PWD_H */
- 	kret = ENOENT;
- 	goto cleanup;
- #endif	/* HAVE_PWD_H */
-     }
- 
-     /* Parse the name and form our principal */
-     if (kret = krb5_parse_name(kcontext, name, client))
- 	goto cleanup;
- 
-     if (!ccname) {
- #if defined(_MSDOS) || defined(_WIN32)
- 	strcpy (new_cache, "FILE:");
- 	GetTempFileName (0, "tkt", 0, new_cache+5);
- #else
- #ifdef _MACINTOSH
- 	(void) sprintf(new_cache, "STDIO:admcc");
- #else
- 	(void) sprintf(new_cache, kadm_cache_name_fmt, getpid());
- #endif /* _MACINTOSH */
- #endif /* _MSDOS || _WIN32 */
-     }
-     else
- 	sprintf(new_cache, "FILE:%s", ccname);
- 
-     /*
-      * We only need to resolve the credentials cache if one hasn't
-      * been supplied to us.
-      */
-     if (!(*ccache) && (kret = krb5_cc_resolve(kcontext, new_cache, ccache)))
- 	goto cleanup;
- 
-     /* XXX assumes a file ccache */
-     if ((kret = krb5_cc_get_principal(kcontext, *ccache, &tprinc)) ==
- 	KRB5_FCC_NOFILE)
- 	kret = krb5_cc_initialize(kcontext, *ccache, *client);
- 
- 
-  cleanup:
-     if (did_malloc)
- 	free(name);
- 
-     if (tprinc)
- 	krb5_free_principal(kcontext, tprinc);
- 
-     if (kret) {
- 	if (*client)
- 	    krb5_free_principal(kcontext, *client);
-     }
- 
-     return(kret);
- }
- 
- /*
-  * kadm_get_creds()	- Get initial credentials.
-  *
-  * Cleanup after success by calling krb5_free_principal().
-  * Allocates new principal for creds->server.
-  */
- static krb5_error_code
- kadm_get_creds(kcontext, ccache, client, creds, prompt, oldpw, tlife)
-     krb5_context	kcontext;
-     krb5_ccache		ccache;
-     krb5_principal	client;
-     krb5_creds		*creds;
-     char		*prompt;
-     char		*oldpw;
-     krb5_timestamp	tlife;
- {
-     char		*client_name;
-     krb5_error_code	kret;
-     krb5_address	**my_addresses;
-     int			old_pwsize;
-     krb5_creds		tcreds;
- 
-     /* Initialize */
-     my_addresses = (krb5_address **) NULL;
-     client_name = (char *) NULL;
- 
-     /* Get the string form for our principal */
-     if (kret = krb5_unparse_name(kcontext, client, &client_name))
- 	return(kret);
- 
-     if (kret = krb5_os_localaddr(kcontext, &my_addresses))
- 	goto cleanup;
- 
-     creds->client = client;
-     /*
-      * Build server principal name:
-      *	"changepw" is service
-      *	realm name is instance
-      *	realm name is realm name
-      */
-     if (kret = krb5_build_principal_ext(kcontext,
- 					&creds->server,
- 					client->realm.length,
- 					client->realm.data,
- 					strlen(KRB5_ADM_SERVICE_INSTANCE),
- 					KRB5_ADM_SERVICE_INSTANCE,
- 					client->realm.length,
- 					client->realm.data,
- 					0))
- 	goto cleanup;
- 
-     /* Attempt to retrieve an appropriate entry from the credentials cache. */
-     if ((kret = krb5_cc_retrieve_cred(kcontext,
- 				      ccache,
- 				      KRB5_TC_MATCH_SRV_NAMEONLY,
- 				      creds,
- 				      &tcreds))
- 	== KRB5_CC_NOTFOUND) {
- 	krb5_timestamp	jetzt;
- 
- 	if (prompt != (char *) NULL) {
- 	    /* Read the password */
- 	    old_pwsize = KRB5_ADM_MAX_PASSWORD_LEN;
- 	    if (kret = krb5_read_password(kcontext,
- 					  prompt,
- 					  (char *) NULL,
- 					  oldpw,
- 					  &old_pwsize))
- 		goto cleanup;
- 	}
- 	if (kret = krb5_timeofday(kcontext, &jetzt))
- 	    goto cleanup;
- 	if (tlife > 0)
- 	    creds->times.endtime = jetzt + tlife;
- 	else
- 	    creds->times.endtime = jetzt + KADM_DEFAULT_LIFETIME;
- 
- 	/* Get our initial ticket */
- 	kret = krb5_get_in_tkt_with_password(kcontext,
- 					     0,
- 					     my_addresses,
- 					     NULL,
- 					     NULL,
- 					     oldpw,
- 					     ccache,
- 					     creds,
- 					     0);
-     }
-     else {
- 	krb5_principal sclient, sserver;
- 
- 	if (!kret) {
- 	    /*
- 	     * We found the credentials cache entry - copy it out.
- 	     *
- 	     * We'd like to just blast tcreds on top of creds, but we cannot.
- 	     * other logic uses the client data, and rather than going and
- 	     * chasing all that logic down, might as well pretend that we just
- 	     * filled in all the other muck.
- 	     */
- 	    sclient = creds->client;
- 	    sserver = creds->server;
- 	    memcpy((char *) creds, (char *) &tcreds, sizeof(tcreds));
- 	    if (creds->client)
- 		krb5_free_principal(kcontext, creds->client);
- 	    if (creds->server)
- 		krb5_free_principal(kcontext, creds->server);
- 	    creds->client = sclient;
- 	    creds->server = sserver;
- 	}
-     }
- 
-  cleanup:
-     if (kret) {
- 	if (creds->server) {
- 	    krb5_free_principal(kcontext, creds->server);
- 	    creds->server = 0;
- 	}
-     }
-     if (my_addresses)
- 	krb5_free_addresses(kcontext, my_addresses);
-     if (client_name)
- 	krb5_xfree(client_name);
-     return(kret);
- }
- 
- /*
-  * kadm_contact_server()	- Establish a connection to the server.
-  *
-  * Cleanup after success by calling close() and free().
-  * Opens/connects socket *sockp.  Allocates address storage for local/remote.
-  */
- static krb5_error_code
- kadm_contact_server(kcontext, realmp, sockp, local, remote)
-     krb5_context	kcontext;
-     krb5_data		*realmp;
-     int			*sockp;
-     krb5_address	**local;
-     krb5_address	**remote;
- {
-     struct hostent	*remote_host;
-     struct servent	*service;
-     char 		**hostlist;
-     int			i, count;
- 
-     krb5_error_code	kret;
- 
-     struct sockaddr_in	in_local;
-     struct sockaddr_in	in_remote;
-     int			addr_len;
- 
-     const char		*realm_admin_names[4];
-     char		*realm_name;
-     krb5_boolean	found;
- 
-     /* Initialize */
-     hostlist = (char **) NULL;
-     *sockp = -1;
-     realm_name = (char *) NULL;
- 
-     /*
-      * XXX - only know ADDRTYPE_INET.
-      */
- #ifdef	KRB5_USE_INET
-     *local = (krb5_address *) malloc(sizeof(krb5_address));
-     *remote = (krb5_address *) malloc(sizeof(krb5_address));
-     realm_name = (char *) malloc((size_t) realmp->length + 1);
-     if ((*local == (krb5_address *) NULL) ||
- 	(*remote == (krb5_address *) NULL) ||
- 	(realm_name == (char *) NULL)) {
- 	kret = ENOMEM;
- 	goto cleanup;
-     }
-     (*local)->addrtype = (*remote)->addrtype = ADDRTYPE_INET;
-     (*local)->length = (*remote)->length = sizeof(struct in_addr);
-     (*local)->contents = (krb5_octet *) malloc(sizeof(struct in_addr));
-     (*remote)->contents = (krb5_octet *) malloc(sizeof(struct in_addr));
-     if (((*local)->contents == NULL) || ((*remote)->contents == NULL)) {
- 	kret = ENOMEM;
- 	goto cleanup;
-     }
- 
-     /*
-      * First attempt to find addresses from our config file, if we cannot
-      * find an entry, then try getservbyname().
-      */
-     found = 0;
- #ifndef	OLD_CONFIG_FILES
-     strncpy(realm_name, realmp->data, (size_t) realmp->length);
-     realm_name[realmp->length] = '\0';
-     realm_admin_names[0] = "realms";
-     realm_admin_names[1] = realm_name;
-     realm_admin_names[2] = "admin_server";
-     realm_admin_names[3] = (char *) NULL;
-     if (!(kret = profile_get_values(kcontext->profile,
- 				    realm_admin_names,
- 				    &hostlist))) {
- 	int		hi;
- 	char		*cport;
- 	char		*cp;
- 	krb5_int32	pport;
- 
- 	for (hi = 0; hostlist[hi]; hi++) {
- 	    /*
- 	     * This knows a little too much about the format of profile
- 	     * entries.  Shouldn't it just be some sort of tuple?
- 	     *
- 	     * The form is assumed to be:
- 	     *	admin_server = <hostname>[:<portname>[<whitespace>]]
- 	     */
- 	    cport = (char *) NULL;
- 	    pport = (u_short) KRB5_ADM_DEFAULT_PORT;
- 	    cp = strchr(hostlist[hi], ' ');
- 	    if (cp)
- 		*cp = '\0';
- 	    cp = strchr(hostlist[hi], '\t');
- 	    if (cp)
- 		*cp = '\0';
- 	    cport = strchr(hostlist[hi], ':');
- 	    if (cport) {
- 		*cport = '\0';
- 		cport++;
- 
- 		pport = atoi (cport);
- 		if (pport == 0) {
- 		    kret = KRB5_CONFIG_BADFORMAT;
- 		    goto cleanup;
- 		}
- 	    }
- 
- 	    /*
- 	     * Now that we have a host name, get the host entry.
- 	     */
- 	    remote_host = gethostbyname(hostlist[hi]);
- 	    if (remote_host == (struct hostent *) NULL) {
- 		kret = KRB5_CONFIG_BADFORMAT;
- 		goto cleanup;
- 	    }
- 
- 	    /*
- 	     * Fill in our address values.
- 	     */
- 	    in_remote.sin_family = remote_host->h_addrtype;
- 	    (void) memcpy((char *) &in_remote.sin_addr,
- 			  (char *) remote_host->h_addr,
- 			  sizeof(in_remote.sin_addr));
- 	    in_remote.sin_port = htons((u_short) pport);
- 
- 	    /* Open a tcp socket */
- 	    *sockp = (int) socket(PF_INET, SOCK_STREAM, 0);
- 	    if (*sockp < 0) {
- 		kret = SOCKET_ERRNO;
- 		goto cleanup;
- 	    }
- 	    else kret = 0;
- 
- 	    /* Attempt to connect to the remote address. */
- 	    if (connect(*sockp,
- 			(struct sockaddr *) &in_remote,
- 			sizeof(in_remote)) < 0) {
- 		/* Failed, go to next address */
- 		kret = SOCKET_ERRNO;
- 		closesocket((SOCKET)*sockp);
- 		*sockp = -1;
- 		continue;
- 	    }
- 
- 	    /* Find out local address */
- 	    addr_len = sizeof(in_local);
- 	    if (getsockname((SOCKET) *sockp,
- 			    (struct sockaddr *) &in_local,
- 			    &addr_len) < 0) {
- 		/* Couldn't get our local address? */
- 		kret = SOCKET_ERRNO;
- 		goto cleanup;
- 	    }
- 	    else {
- 		/* Connection established. */
- 		memcpy((char *) (*remote)->contents,
- 		       (char *) &in_remote.sin_addr,
- 		       sizeof(struct in_addr));
- 		memcpy((char *) (*local)->contents,
- 		       (char *) &in_local.sin_addr,
- 		       sizeof(struct in_addr));
- 		found = 1;
- 		break;
- 	    }
- 	}
- 	if (!found) {
- 	    krb5_xfree(hostlist);
- 	    hostlist = (char **) NULL;
- 	}
-     }
- #endif	/* OLD_CONFIG_FILES */
-     if (!found) {
- 	/*
- 	 * Use the old way of finding our administrative server.
- 	 *
- 	 * This consists of looking up an entry in /etc/services and if
- 	 * we don't find it, then we are just out of luck.  Then, we use
- 	 * that port number along with the address of the kdc.
- 	 */
- 	if ((service = getservbyname(KRB5_ADM_SERVICE_NAME, "tcp")) == NULL) {
- 	    kret = ENOENT;
- 	    goto cleanup;
- 	}
- 	in_remote.sin_port = service->s_port;
- 	
- 	if (kret = krb5_get_krbhst(kcontext, realmp, &hostlist))
- 	    goto cleanup;
- 	
- 	/* Now count the number of hosts in the realm */
- 	count = 0;
- 	for (i=0; hostlist[i]; i++)
- 	    count++;
- 	if (count == 0) {
- 	    kret = ENOENT;	/* something better? */
- 	    goto cleanup;
- 	}
- 	
- 	/* Now find an available host */
- 	for (i=0; hostlist[i]; i++) {
- 	    remote_host = gethostbyname(hostlist[i]);
- 	    if (remote_host != (struct hostent *) NULL) {
- 		in_remote.sin_family = remote_host->h_addrtype;
- 		(void) memcpy((char *) &in_remote.sin_addr,
- 			      (char *) remote_host->h_addr,
- 			      sizeof(in_remote.sin_addr));
- 	
- 		/* Open a tcp socket */
- 		*sockp = (int) socket(PF_INET, SOCK_STREAM, 0);
- 		if (*sockp < 0) {
- 		    kret = SOCKET_ERRNO;
- 		    goto cleanup;
- 		}
- 		else kret = 0;
- 	
- 		if (connect(*sockp,
- 			    (struct sockaddr *) &in_remote,
- 			    sizeof(in_remote)) < 0) {
- 		    kret = SOCKET_ERRNO;
- 		    closesocket((SOCKET)*sockp);
- 		    *sockp = -1;
- 		    continue;
- 		}
- 
- 		/* Find out local address */
- 		addr_len = sizeof(in_local);
- 		if (getsockname((SOCKET)*sockp,
- 				(struct sockaddr *) &in_local,
- 				&addr_len) < 0) {
- 		    kret = SOCKET_ERRNO;
- 		    goto cleanup;
- 		}
- 		else {
- 		    memcpy((char *) (*remote)->contents,
- 			   (char *) &in_remote.sin_addr,
- 			   sizeof(struct in_addr));
- 	
- 		    memcpy((char *) (*local)->contents,
- 			   (char *) &in_local.sin_addr,
- 			   sizeof(struct in_addr));
- 		    found = 1;
- 		    break;
- 		}
- 	    }
- 	}
- 	if (!found)
- 	    kret = KRB5_SERVICE_UNKNOWN;
-     }
- #else	/* KRB5_USE_INET */
-     kret = ENOENT;
- #endif	/* KRB5_USE_INET */
- 
-  cleanup:
-     if (kret) {
- 	if (*sockp >= 0)
- 	    closesocket((SOCKET)*sockp);
- 	if (*local && (*local)->contents)
- 	    free((*local)->contents);
- 	if (*remote && (*remote)->contents)
- 	    free((*remote)->contents);
- 	if (*local) {
- 	    memset((char *) (*local), 0, sizeof(krb5_address));
- 	    free(*local);
- 	    *local = (krb5_address *) NULL;
- 	}
- 	if (*remote) {
- 	    memset((char *) (*remote), 0, sizeof(krb5_address));
- 	    free(*remote);
- 	    *remote = (krb5_address *) NULL;
- 	}
-     }
-     if (realm_name)
- 	free(realm_name);
-     if (hostlist)
- 	krb5_xfree(hostlist);
-     return(kret);
- }
- 
- /*
-  * kadm_get_auth()	- Get authorization context.
-  *
-  * Cleanup after success by calling krb5_xfree().
-  * New krb5_auth_context allocated in *ctxp
-  */
- static krb5_error_code
- kadm_get_auth(kcontext, ctxp, local, remote)
-     krb5_context	kcontext;
-     krb5_auth_context	*ctxp;
-     krb5_address	*local;
-     krb5_address	*remote;
- {
-     krb5_auth_con_init(kcontext, ctxp);
-     krb5_auth_con_setflags(kcontext, *ctxp, 
- 			   KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- 			   KRB5_AUTH_CONTEXT_DO_SEQUENCE);
-     krb5_auth_con_setaddrs(kcontext, *ctxp, local, remote);
-     return(0);
- }
- 
- /*
-  * krb5_adm_connect()	- Establish the connection to the service.
-  *
-  * If *ccachep is not null, then that ccache is used to establish the identity
-  * of the caller.  (Argument list is ugly, I know)
-  *
-  * Errors are not reported by this routine.
-  * Cleanup after successful invocation must:
-  *	destroy/close ccache.
-  *	free auth_context
-  *	close socket.
-  */
- krb5_error_code INTERFACE
- krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp,
- 		 ccachep, ccname, tlife)
-     krb5_context	kcontext;	/* Context handle	(In ) */
-     char		*user;		/* User specified	(In ) */
-     char		*prompt;	/* Old password prompt	(In ) */
-     char		*opassword;	/* Old Password		(I/O) */
-     int			*sockp;		/* Socket for conn.	(Out) */
-     krb5_auth_context	*ctxp;		/* Auth context		(Out) */
-     krb5_ccache		*ccachep;	/* Credentials cache	(I/O) */
-     char		*ccname;	/* Cred cache name	(In ) */
-     krb5_timestamp	tlife;		/* Ticket lifetime	(In ) */
- {
-     krb5_error_code	kret;
-     krb5_principal	client;
-     krb5_creds		creds;
-     krb5_data		server_realm;
-     krb5_data		request_data, suppl_data;
-     krb5_data		response_data;
-     krb5_address	*local_addr;
-     krb5_address	*remote_addr;
-     krb5_boolean	ccache_supplied;
- 
-     char		*server;
- 
-     /* Initialize */
-     memset((char *) &creds, 0, sizeof(krb5_creds));
-     server = (char *) NULL;
-     *sockp = -1;
-     local_addr = remote_addr = (krb5_address *) NULL;
-     client = (krb5_principal) NULL;
-     *ctxp = (krb5_auth_context) NULL;
-     ccache_supplied = (*ccachep != (krb5_ccache) NULL);
- 
-     /*
-      * Find the appropriate credentials cache and set up our identity.
-      */
-     if (kret = kadm_get_ccache(kcontext, user, ccname, ccachep, &client))
- 	goto cleanup;
- 
-     /*
-      * Get initial credentials.
-      */
-     if (kret = kadm_get_creds(kcontext,
- 			      *ccachep,
- 			      client,
- 			      &creds,
- 			      prompt,
- 			      opassword,
- 			      tlife))
- 	goto cleanup;
- 
-     /*
-      * Establish connection to server.
-      */
-     if ((server_realm.data = (char *) malloc(client->realm.length+1)) ==
- 	(char *) NULL)
- 	goto cleanup;
- 
-     server_realm.length = client->realm.length;
-     memcpy(server_realm.data, client->realm.data, server_realm.length);
-     server_realm.data[server_realm.length] = '\0';
-     if (kret = kadm_contact_server(kcontext,
- 				   &server_realm,
- 				   sockp,
- 				   &local_addr,
- 				   &remote_addr))
- 	goto cleanup;
- 
-     /*
-      * Obtain our authorization context
-      */
-     if (kret = kadm_get_auth(kcontext, ctxp, local_addr, remote_addr))
- 	goto cleanup;
- 
-     /*
-      * Format, then send the KRB_AP_REQ
-      */
-     suppl_data.data = NULL;
-     suppl_data.length = 0;
-     if (kret = krb5_mk_req_extended(kcontext,
- 				    ctxp,
- 				    AP_OPTS_MUTUAL_REQUIRED,
- 				    &suppl_data,
- 				    &creds,
- 				    &request_data))
- 	goto cleanup;
- 
-     if (kret = krb5_write_message(kcontext, sockp, &request_data))
- 	goto cleanup;
- 
-     /*
-      * Now read back the response.
-      */
-     if (kret = krb5_read_message(kcontext, sockp, &response_data)) {
- 	goto cleanup;
-     }
-     else {
- 	krb5_ap_rep_enc_part	*reply = NULL;
- 
- 	kret = krb5_rd_rep(kcontext, *ctxp, &response_data, &reply);
- 	if (reply)
- 	    krb5_free_ap_rep_enc_part(kcontext, reply);
-     }
-  cleanup:
-     if (server)
- 	free(server);
-     if (kret) {
- 	if (*ctxp) {
- 	    krb5_xfree(*ctxp);
- 	    *ctxp = (krb5_auth_context) NULL;
- 	}
- 	if (*sockp >= 0) {
- 	    closesocket((SOCKET)*sockp);
- 	    *sockp = -1;
- 	}
- 	if (local_addr && local_addr->contents)
- 	    free(local_addr->contents);
- 	if (remote_addr && remote_addr->contents)
- 	    free(remote_addr->contents);
- 	if (local_addr)
- 	    free(local_addr);
- 	if (remote_addr)
- 	    free(remote_addr);
- 	if (creds.server)
- 	    krb5_free_principal(kcontext, creds.server);
- 	if (client)
- 	    krb5_free_principal(kcontext, client);
- 	if (*ccachep && !ccache_supplied) {
- 	    krb5_cc_destroy(kcontext, *ccachep);
- 	    *ccachep = (krb5_ccache) NULL;
- 	}
-     }
-     return(kret);
- 
- }
- 
- /*
-  * krb5_adm_disconnect()	- Disconnect from the administrative service.
-  *
-  * If ccache is supplied, then it is destroyed.  Otherwise, the ccache is
-  * the caller's responsibility to close.
-  */
- void INTERFACE
- krb5_adm_disconnect(kcontext, socketp, auth_context, ccache)
-     krb5_context	kcontext;
-     int			*socketp;
-     krb5_auth_context	auth_context;
-     krb5_ccache		ccache;
- {
-     if (ccache)
- 	krb5_cc_destroy(kcontext, ccache);
-     if (auth_context)
- 	krb5_xfree(auth_context);
-     if (*socketp >= 0)
- 	closesocket((SOCKET)*socketp);
- }
- 
--- 0 ----
Index: krb5/lib/kadm/adm_kt_dec.c
diff -c krb5/lib/kadm/adm_kt_dec.c:1.1.1.1 krb5/lib/kadm/adm_kt_dec.c:removed
*** krb5/lib/kadm/adm_kt_dec.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_kt_dec.c	Sun Mar 16 20:22:24 2003
***************
*** 1,127 ****
- /*
-  * lib/kadm/adm_kt_dec.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * adm_kt_dec.c	- Decode keytab entry according to protocol.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- /*
-  * krb5_adm_proto_to_ktent()	- Convert a list of reply components to
-  *				  a keytab entry according to procotol.
-  *
-  * Successful callers of this routine should free ktentp->principal
-  * and ktentp->key.contents.
-  */
- krb5_error_code
- krb5_adm_proto_to_ktent(kcontext, ncomp, complist, ktentp)
-     krb5_context	kcontext;
-     krb5_int32		ncomp;
-     krb5_data		*complist;
-     krb5_keytab_entry	*ktentp;
- {
-     krb5_error_code	kret;
-     char		*v;
- 
-     /*
-      * Clear out the keytab entry.
-      */
-     memset((char *) ktentp, 0, sizeof(krb5_keytab_entry));
- 
-     /*
-      * Figure out how many components we have.  We expect KRB5_ADM_KT_NCOMPS
-      * components.
-      */
-     if (ncomp != KRB5_ADM_KT_NCOMPS)
- 	return(EINVAL);
- 
-     /* Parse the supplied principal name */
-     if (kret = krb5_parse_name(kcontext,
- 			       complist[KRB5_ADM_KT_PRINCIPAL].data,
- 			       &ktentp->principal))
- 	goto done;
- 
-     /* Parse the supplied timestamp */
-     if (complist[KRB5_ADM_KT_TIMESTAMP].length < sizeof(krb5_timestamp)) {
- 	kret = EINVAL;
- 	goto done;
-     }
-     v = complist[KRB5_ADM_KT_TIMESTAMP].data;
-     ktentp->timestamp = (krb5_timestamp)
- 	(((krb5_int32) ((unsigned char) v[0]) << 24) +
- 	 ((krb5_int32) ((unsigned char) v[1]) << 16) +
- 	 ((krb5_int32) ((unsigned char) v[2]) << 8) +
- 	 ((krb5_int32) ((unsigned char) v[3])));
- 
-     /* Parse the supplied vno */
-     if (complist[KRB5_ADM_KT_VNO].length < sizeof(krb5_kvno)) {
- 	kret = EINVAL;
- 	goto done;
-     }
-     v = complist[KRB5_ADM_KT_VNO].data;
-     ktentp->vno = (krb5_kvno)
- 	(((krb5_int32) ((unsigned char) v[0]) << 24) +
- 	 ((krb5_int32) ((unsigned char) v[1]) << 16) +
- 	 ((krb5_int32) ((unsigned char) v[2]) << 8) +
- 	 ((krb5_int32) ((unsigned char) v[3])));
- 
-     /* Parse the supplied key_enctype */
-     if (complist[KRB5_ADM_KT_KEY_ENCTYPE].length < sizeof(krb5_enctype)) {
- 	kret = EINVAL;
- 	goto done;
-     }
-     v = complist[KRB5_ADM_KT_KEY_ENCTYPE].data;
-     ktentp->key.enctype = (krb5_enctype)
- 	(((krb5_int32) ((unsigned char) v[0]) << 24) +
- 	 ((krb5_int32) ((unsigned char) v[1]) << 16) +
- 	 ((krb5_int32) ((unsigned char) v[2]) << 8) +
- 	 ((krb5_int32) ((unsigned char) v[3])));
- 
-     /* Finally, shuck the key contents */
-     if (ktentp->key.contents = (krb5_octet *)
- 	malloc((size_t) complist[KRB5_ADM_KT_KEY_KEY].length)) {
- 	ktentp->key.length = complist[KRB5_ADM_KT_KEY_KEY].length;
- 	memcpy(ktentp->key.contents,
- 	       complist[KRB5_ADM_KT_KEY_KEY].data,
- 	       (size_t) ktentp->key.length);
- 	kret = 0;
-     }
-     else
- 	kret = ENOMEM;
- 	
-  done:
-     if (kret) {
- 	if (ktentp->principal)
- 	    krb5_free_principal(kcontext, ktentp->principal);
- 	if (ktentp->key.contents) {
- 	    memset((char *) ktentp->key.contents, 0,
- 		   (size_t) ktentp->key.length);
- 	    krb5_xfree(ktentp->key.contents);
- 	}
- 	memset((char *) ktentp, 0, sizeof(krb5_keytab_entry));
-     }
-     return(kret);
- }
--- 0 ----
Index: krb5/lib/kadm/adm_kt_enc.c
diff -c krb5/lib/kadm/adm_kt_enc.c:1.1.1.1 krb5/lib/kadm/adm_kt_enc.c:removed
*** krb5/lib/kadm/adm_kt_enc.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_kt_enc.c	Sun Mar 16 20:22:24 2003
***************
*** 1,162 ****
- /*
-  * lib/kadm/adm_kt_enc.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * adm_kt_enc.c	- Encode keytab entry according to protocol.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- 
- /*
-  * krb5_adm_ktent_to_proto()	- Convert a keytab entry into an external
-  *				  list of reply components.
-  *
-  * Successful callers must free the storage for complistp and complistp->data
-  * either manually or by using krb5_free_adm_data().
-  */
- krb5_error_code
- krb5_adm_ktent_to_proto(kcontext, ktentp, ncompp, complistp)
-     krb5_context	kcontext;
-     krb5_keytab_entry	*ktentp;
-     krb5_int32		*ncompp;
-     krb5_data		**complistp;
- {
-     krb5_error_code	kret;
-     krb5_data		*clist;
-     krb5_int32		nents;
- 
-     kret = ENOMEM;
-     nents = 0;
-     if (clist = (krb5_data *) malloc((size_t) KRB5_ADM_KT_NCOMPS *
- 				     sizeof(krb5_data))) {
- 	memset((char *) clist, 0, ((size_t) KRB5_ADM_KT_NCOMPS *
- 				   sizeof(krb5_data)));
- 	/*
- 	 * Fill in the principal field.
- 	 */
- 	if (kret = krb5_unparse_name(kcontext,
- 				     ktentp->principal,
- 				     &clist[KRB5_ADM_KT_PRINCIPAL].data))
- 	    goto done;
- 	clist[KRB5_ADM_KT_PRINCIPAL].length =
- 	    strlen(clist[KRB5_ADM_KT_PRINCIPAL].data);
- 	nents++;
- 
- 	/*
- 	 * Fill in timestamp.
- 	 */
- 	if (kret = krb5_timeofday(kcontext, &ktentp->timestamp))
- 	    goto done;
- 	if (clist[KRB5_ADM_KT_TIMESTAMP].data = 
- 	    (char *) malloc(sizeof(krb5_ui_4))) {
- 	    clist[KRB5_ADM_KT_TIMESTAMP].length = sizeof(krb5_ui_4);
- 	    clist[KRB5_ADM_KT_TIMESTAMP].data[0] =
- 		(char) ((ktentp->timestamp >> 24) & 0xff);
- 	    clist[KRB5_ADM_KT_TIMESTAMP].data[1] =
- 		(char) ((ktentp->timestamp >> 16) & 0xff);
- 	    clist[KRB5_ADM_KT_TIMESTAMP].data[2] =
- 		(char) ((ktentp->timestamp >> 8) & 0xff);
- 	    clist[KRB5_ADM_KT_TIMESTAMP].data[3] =
- 		(char) (ktentp->timestamp & 0xff);
- 	    nents++;
- 	}
- 	else {
- 	    kret = ENOMEM;
- 	    goto done;
- 	}
- 
- 	/*
- 	 * Fill in vno.
- 	 */
- 	if (clist[KRB5_ADM_KT_VNO].data = 
- 	    (char *) malloc(sizeof(krb5_ui_4))) {
- 	    clist[KRB5_ADM_KT_VNO].length = sizeof(krb5_ui_4);
- 	    clist[KRB5_ADM_KT_VNO].data[0] = (ktentp->vno >> 24) & 0xff;
- 	    clist[KRB5_ADM_KT_VNO].data[1] = (ktentp->vno >> 16) & 0xff;
- 	    clist[KRB5_ADM_KT_VNO].data[2] = (ktentp->vno >> 8) & 0xff;
- 	    clist[KRB5_ADM_KT_VNO].data[3] = ktentp->vno & 0xff;
- 	    nents++;
- 	}
- 	else {
- 	    kret = ENOMEM;
- 	    goto done;
- 	}
- 
- 	/*
- 	 * Fill in key_enctype.
- 	 */
- 	if (clist[KRB5_ADM_KT_KEY_ENCTYPE].data = 
- 	    (char *) malloc(sizeof(krb5_ui_4))) {
- 	    clist[KRB5_ADM_KT_KEY_ENCTYPE].length = sizeof(krb5_ui_4);
- 	    clist[KRB5_ADM_KT_KEY_ENCTYPE].data[0] =
- 		(ktentp->key.enctype >> 24) & 0xff;
- 	    clist[KRB5_ADM_KT_KEY_ENCTYPE].data[1] =
- 		(ktentp->key.enctype >> 16) & 0xff;
- 	    clist[KRB5_ADM_KT_KEY_ENCTYPE].data[2] =
- 		(ktentp->key.enctype >> 8) & 0xff;
- 	    clist[KRB5_ADM_KT_KEY_ENCTYPE].data[3] =
- 		ktentp->key.enctype & 0xff;
- 	    nents++;
- 	}
- 	else {
- 	    kret = ENOMEM;
- 	    goto done;
- 	}
- 
- 	/*
- 	 * Fill in key_key.
- 	 */
- 	if (clist[KRB5_ADM_KT_KEY_KEY].data = 
- 	    (char *) malloc((size_t) ktentp->key.length)) {
- 	    memcpy(clist[KRB5_ADM_KT_KEY_KEY].data,
- 		   ktentp->key.contents,
- 		   (size_t) ktentp->key.length);
- 	    clist[KRB5_ADM_KT_KEY_KEY].length = ktentp->key.length;
- 	    nents++;
- 	    kret = 0;
- 	}
- 	else
- 	    kret = ENOMEM;
-     }
-  done:
-     if (kret) {
- 	if (clist) {
- 	    int i;
- 	    for (i=0; i<KRB5_ADM_KT_NCOMPS; i++) {
- 		if (clist[i].data) {
- 		    memset(clist[i].data, 0, (size_t) clist[i].length);
- 		    krb5_xfree(clist[i].data);
- 		}
- 	    }
- 	    krb5_xfree(clist);
- 	}
- 	clist = (krb5_data *) NULL;
- 	nents = 0;
-     }
-     *complistp = clist;
-     *ncompp = nents;
-     return(kret);
- }
--- 0 ----
Index: krb5/lib/kadm/adm_kw_dec.c
diff -c krb5/lib/kadm/adm_kw_dec.c:1.1.1.1 krb5/lib/kadm/adm_kw_dec.c:removed
*** krb5/lib/kadm/adm_kw_dec.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_kw_dec.c	Sun Mar 16 20:22:24 2003
***************
*** 1,578 ****
- /*
-  * lib/kadm/adm_kw_dec.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * adm_kw_dec.c	- routines to decode keyword-value pairs.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- #define	char2int(c)	((c) - '0')
- 
- /*
-  * keyword_value()	- Find index of keyword value if keyword is present.
-  *
-  * If a value is required, then the index of the keyword value is returned,
-  * otherwise the index of the first character past the end of the keyword
-  * string is returned.
-  */
- static off_t
- keyword_value(dataentp, keyword, value_req)
-     krb5_data		*dataentp;
-     char		*keyword;
-     krb5_boolean	value_req;
- {
-     off_t	len_req;
- 
-     len_req = strlen(keyword);
-     if (value_req)
- 	len_req++;
-     if ((dataentp->length >= len_req) &&
- 	(!strncmp(dataentp->data, keyword, strlen(keyword))) &&
- 	(!value_req || (dataentp->data[strlen(keyword)] == '=')))
- 	return(len_req);
-     else
- 	return(-1);
- }
- 
- /*
-  * decode_kw_string()	- Decode a keyword=<string> pair and return the
-  *			  string value if the pair is present.
-  *
-  * Note: successful callers must free the string storage.
-  */
- static krb5_error_code
- decode_kw_string(dataentp, keyword, stringp)
-     krb5_data	*dataentp;
-     char	*keyword;
-     char	**stringp;
- {
-     krb5_error_code	kret;
-     off_t		valueoff;
-     size_t		len2copy;
- 
-     kret = ENOENT;
-     if ((valueoff = keyword_value(dataentp, keyword, 1)) >= 0) {
- 	kret = ENOMEM;
- 	len2copy = (size_t) ((off_t) dataentp->length - valueoff);
- 	*stringp = (char *) malloc(len2copy+1);
- 	if (*stringp) {
- 	    strncpy(*stringp, &dataentp->data[valueoff], len2copy);
- 	    (*stringp)[len2copy] = '\0';
- 	    kret = 0;
- 	}
-     }
-     return(kret);
- }
- 
- /*
-  * decode_kw_integer()	- Decode a keyword=<integer> pair and return the value
-  *			  if the pair is present.
-  */
- static krb5_error_code
- decode_kw_integer(dataentp, keyword, uintp)
-     krb5_data	*dataentp;
-     char	*keyword;
-     krb5_ui_4	*uintp;
- {
-     krb5_error_code	kret;
-     off_t		voff;
-     size_t		len2copy;
- 
-     kret = ENOENT;
-     if ((voff = keyword_value(dataentp, keyword, 1)) >= 0) {
- 	kret = EINVAL;
- 	len2copy = (size_t) ((off_t) dataentp->length - voff);
- 	if (len2copy == sizeof(krb5_ui_4)) {
- 	    *uintp = (((krb5_int32) ((unsigned char) dataentp->data[voff])
- 		       << 24) +
- 		      ((krb5_int32) ((unsigned char) dataentp->data[voff+1])
- 		       << 16) +
- 		      ((krb5_int32) ((unsigned char) dataentp->data[voff+2])
- 		       << 8) +
- 		      ((krb5_int32) ((unsigned char) dataentp->data[voff+3])));
- 	    kret = 0;
- 	}
-     }
-     return(kret);
- }
- 
- /*
-  * decode_kw_gentime()	- Decode a keyword=<general-time> pair and return the
-  *			  time result if the pair is present.
-  *
-  * XXX - this knows too much about how Kerberos time is encoded.
-  */
- static krb5_error_code
- decode_kw_gentime(dataentp, keyword, gtimep)
-     krb5_data		*dataentp;
-     char		*keyword;
-     krb5_timestamp	*gtimep;
- {
-     krb5_error_code	kret;
-     char		*timestring;
-     struct tm		tval;
-     time_t		temp_time;
- 
-     memset((char *) &tval, 0, sizeof(tval));
-     timestring = (char *) NULL;
-     if (!(kret = decode_kw_string(dataentp, keyword, &timestring))) {
- 	kret = EINVAL;
- 	if ((strlen(timestring) == 15) &&
- 	    (timestring[14] == 'Z')) {
- 	    tval.tm_year = 1000*char2int(timestring[0]) +
- 		100*char2int(timestring[1]) +
- 		    10*char2int(timestring[2]) +
- 			char2int(timestring[3]) - 1900;
- 	    tval.tm_mon = 10*char2int(timestring[4]) +
- 		char2int(timestring[5]) - 1;
- 	    tval.tm_mday = 10*char2int(timestring[6]) +
- 		char2int(timestring[7]);
- 	    tval.tm_hour = 10*char2int(timestring[8]) +
- 		char2int(timestring[9]);
- 	    tval.tm_min = 10*char2int(timestring[10]) +
- 		char2int(timestring[11]);
- 	    tval.tm_sec = 10*char2int(timestring[12]) +
- 		char2int(timestring[13]);
- 	    tval.tm_isdst = -1;
- 	    temp_time = gmt_mktime(&tval);
- 	    if (temp_time >= 0) {
- 		kret = 0;
- 		*gtimep = (krb5_timestamp) temp_time;
- 	    }
- 	}
- 	free(timestring);
-     }
-     return(kret);
- }
- 
- /*
-  * decode_kw_tagged()	- Decode a keyword=<taglist>...<data> list and return
-  *			  the values of the tags and the data if the list is
-  *			  present.
-  */
- static krb5_error_code
- decode_kw_tagged(dataentp, keyword, ntags, taglist, lenp, datap)
-     krb5_data		*dataentp;
-     char		*keyword;
-     krb5_int32		ntags;
-     krb5_int32		*taglist;
-     size_t		*lenp;
-     krb5_octet		**datap;
- {
-     krb5_error_code	kret;
-     off_t		valueoff;
-     size_t		len2copy;
-     unsigned char	*cp, *ep;
-     int			i;
- 
-     kret = ENOENT;
-     if ((valueoff = keyword_value(dataentp, keyword, 1)) >= 0) {
- 	/*
- 	 * Blast through the tags.
- 	 */
- 	kret = 0;
- 	cp = (unsigned char *) &dataentp->data[valueoff];
- 	ep = (unsigned char *) &dataentp->data[dataentp->length];
- 	for (i=0; i<ntags; i++) {
- 	    if (&cp[sizeof(krb5_int32)] > ep) {
- 		kret = EINVAL;
- 		break;
- 	    }
- 	    taglist[i] = (((krb5_int32) ((unsigned char) cp[0]) << 24) +
- 			  ((krb5_int32) ((unsigned char) cp[1]) << 16) +
- 			  ((krb5_int32) ((unsigned char) cp[2]) << 8) +
- 			  ((krb5_int32) ((unsigned char) cp[3])));
- 	    cp += sizeof(krb5_int32);
- 	}
- 	if (!kret) {
- 	    /*
- 	     * If we were successful, copy out the remaining bytes for value.
- 	     */
- 	    len2copy = (size_t) (ep - cp);
- 	    if (len2copy &&
- 		(*datap = (krb5_octet *) malloc(len2copy+1))) {
- 		memcpy(*datap, cp, len2copy);
- 		(*datap)[len2copy] = '\0';
- 	    }
- 	    if (len2copy && !*datap)
- 		kret = ENOMEM;
- 	    else
- 		*lenp = len2copy;
- 	}
-     }
-     return(kret);
- }
- 
- #if !defined(_MSDOS) && !defined(_WIN32) && !defined(_MACINTOSH)
- /*
-  * krb5_adm_proto_to_dbent()	- Convert external attribute list into a
-  *				  database entry.
-  *
-  * Scan through the keyword=value pairs in "data" until either the end of
-  * the list (as determined from "nent") is reached, or an error occurs.
-  * Return a mask of attributes which are set in "validp", the actual
-  * attribute values in "dbentp" and "pwordp" if a password is specified.
-  *
-  * Successful callers must allocate the storage for "validp", "dbentp" and
-  * must free the storage allocated for "pwordp" if a password is specified
-  * and free the storage allocated for "validp->mod_name" if a modifier name
-  * is specified.
-  */
- krb5_error_code
- krb5_adm_proto_to_dbent(kcontext, nent, data, validp, dbentp, pwordp)
-     krb5_context	kcontext;	/* Kerberos context	*/ /* In */
-     krb5_int32		nent;		/* Number of components	*/ /* In */
-     krb5_data		*data;		/* Component list	*/ /* In */
-     krb5_ui_4		*validp;	/* Valid bitmask	*/ /* Out */
-     krb5_db_entry	*dbentp;	/* Database entry	*/ /* Out */
-     char		**pwordp;	/* Password string	*/ /* Out */
- {
-     int			i;
-     krb5_error_code	retval;
-     krb5_ui_4		parsed_mask;
-     krb5_int32		taglist[4];
-     size_t		data_length;
-     krb5_octet		*tagged_data;
-     struct key_tag_correlator {
- 	krb5_int32	key_tag;
- 	int		key_data_index;
-     } *correlators, *correlation;
-     int			ncorrelations;
- 
-     /* Initialize */
-     retval = 0;
-     parsed_mask = 0;
-     *pwordp = (char *) NULL;
-     correlators = (struct key_tag_correlator *) NULL;
-     ncorrelations = 0;
- 
-     /* Loop through all the specified keyword=value pairs. */
-     for (i=0; i<nent; i++) {
- 	/* Check for password */
- 	if (!(retval = decode_kw_string(&data[i],
- 					KRB5_ADM_KW_PASSWORD,
- 					pwordp))) {
- 	    parsed_mask |= KRB5_ADM_M_PASSWORD;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for maximum lifetime */
- 	if (!(retval = decode_kw_integer(&data[i],
- 					 KRB5_ADM_KW_MAXLIFE,
- 					 (krb5_ui_4 *) &dbentp->max_life))) {
- 	    parsed_mask |= KRB5_ADM_M_MAXLIFE;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for maximum renewable lifetime */
- 	if (!(retval = decode_kw_integer(&data[i],
- 					 KRB5_ADM_KW_MAXRENEWLIFE,
- 					 (krb5_ui_4 *)
- 					 &dbentp->max_renewable_life))) {
- 	    parsed_mask |= KRB5_ADM_M_MAXRENEWLIFE;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for principal expiration */
- 	if (!(retval = decode_kw_gentime(&data[i],
- 					 KRB5_ADM_KW_EXPIRATION,
- 					 &dbentp->expiration))) {
- 	    parsed_mask |= KRB5_ADM_M_EXPIRATION;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for password expiration */
- 	if (!(retval = decode_kw_gentime(&data[i],
- 					 KRB5_ADM_KW_PWEXPIRATION,
- 					 &dbentp->pw_expiration))) {
- 	    parsed_mask |= KRB5_ADM_M_PWEXPIRATION;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* random key - value optional */
- 	if (keyword_value(&data[i],
- 			  KRB5_ADM_KW_RANDOMKEY,
- 			  0) >= 0) {
- 	    krb5_ui_4	value;
- 
- 	    if (retval = decode_kw_integer(&data[i],
- 					   KRB5_ADM_KW_RANDOMKEY,
- 					   &value)) {
- 		value = 1;
- 		retval = 0;
- 	    }
- 	    if (value)
- 		parsed_mask |= KRB5_ADM_M_RANDOMKEY;
- 	    else
- 		parsed_mask &= ~KRB5_ADM_M_RANDOMKEY;
- 	    continue;
- 	}
- 
- 	/* Check for flags */
- 	if (!(retval = decode_kw_integer(&data[i],
- 					 KRB5_ADM_KW_FLAGS,
- 					 (krb5_ui_4 *) &dbentp->attributes))) {
- 	    parsed_mask |= KRB5_ADM_M_FLAGS;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for last successful password entry */
- 	if (!(retval = decode_kw_gentime(&data[i],
- 					 KRB5_ADM_KW_LASTSUCCESS,
- 					 &dbentp->last_success))) {
- 	    parsed_mask |= KRB5_ADM_M_LASTSUCCESS;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for last failed entry */
- 	if (!(retval = decode_kw_gentime(&data[i],
- 					 KRB5_ADM_KW_LASTFAILED,
- 					 &dbentp->last_failed))) {
- 	    parsed_mask |= KRB5_ADM_M_LASTFAILED;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for failure count */
- 	if (!(retval = decode_kw_integer(&data[i],
- 					 KRB5_ADM_KW_FAILCOUNT,
- 					 (krb5_ui_4 *)
- 					 &dbentp->fail_auth_count))) {
- 	    parsed_mask |= KRB5_ADM_M_FAILCOUNT;
- 	    continue;
- 	}
- 	else {
- 	    if (retval != ENOENT)
- 		break;
- 	}
- 
- 	/* Check for auxiliary data */
- 	if (!(retval = decode_kw_tagged(&data[i],
- 					KRB5_ADM_KW_AUXDATA,
- 					1,
- 					taglist,
- 					&data_length,
- 					&tagged_data))) {
- 	    krb5_tl_data	**fixupp;
- 	    krb5_tl_data	*tl_data, *new_tl;
- 
- 	    /*
- 	     * We've got a tagged data value here.  We've got to do a little
- 	     * work to put it in the right place.  First, find the right place.
- 	     */
- 	    fixupp = &dbentp->tl_data;
- 	    for (tl_data = dbentp->tl_data;
- 		 tl_data; 
- 		 tl_data = tl_data->tl_data_next)
- 		fixupp = &tl_data->tl_data_next;
- 
- 	    /* Get memory */
- 	    if (new_tl = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) {
- 		/* Fill in the supplied values */
- 		new_tl->tl_data_type = (krb5_int16) taglist[0];
- 		new_tl->tl_data_length = (krb5_int16) data_length;
- 		new_tl->tl_data_contents = tagged_data;
- 
- 		/* Link in the right place */
- 		new_tl->tl_data_next= *fixupp;
- 		*fixupp = new_tl;
- 
- 		/* Update counters and flags */
- 		dbentp->n_tl_data++;
- 		parsed_mask |= KRB5_ADM_M_AUXDATA;
- 	    }
- 	    else {
- 		retval = ENOMEM;
- 		break;
- 	    }
- 	    continue;
- 	}
- 	else {
- 	    if ((retval != ENOENT) && (retval != EINVAL))
- 		break;
- 	}
- 
- 	/* Check for key data */
- 	if (!(retval = decode_kw_tagged(&data[i],
- 					KRB5_ADM_KW_KEYDATA,
- 					3,
- 					taglist,
- 					&data_length,
- 					&tagged_data))) {
- 	    krb5_boolean	corr_found;
- 	    int			cindex, kindex;
- 	    krb5_key_data	*kdata;
- 
- 	    /*
- 	     * See if we already have a correlation betwen our key-tag and
- 	     * an index into the key table.
- 	     */
- 	    corr_found = 0;
- 	    for (cindex = 0; cindex < ncorrelations; cindex++) {
- 		if (correlators[cindex].key_tag == taglist[0]) {
- 		    correlation = &correlators[cindex];
- 		    corr_found = 1;
- 		    break;
- 		}
- 	    }
- 
- 	    /* If not, then we had better make one up */
- 	    if (!corr_found) {
- 		/* Get a new list */
- 		if (correlation = (struct key_tag_correlator *)
- 		    malloc((ncorrelations+1)*
- 			   sizeof(struct key_tag_correlator))) {
- 		    /* Save the contents of the old one. */
- 		    if (ncorrelations) {
- 			memcpy(correlation, correlators,
- 			       ncorrelations*
- 			       sizeof(struct key_tag_correlator));
- 			/* Free the old one */
- 			free(correlators);
- 		    }
- 		    /* Point us at the new relation */
- 		    correlators = correlation;
- 		    correlation = &correlators[ncorrelations];
- 		    ncorrelations++;
- 		    correlation->key_tag = taglist[0];
- 		    /* Make a new key data entry */
- 		    if (kdata = (krb5_key_data *)
- 			malloc((dbentp->n_key_data+1)*sizeof(krb5_key_data))) {
- 			/* Copy the old list */
- 			if (dbentp->n_key_data) {
- 			    memcpy(kdata, dbentp->key_data,
- 				   dbentp->n_key_data*sizeof(krb5_key_data));
- 			    free(dbentp->key_data);
- 			}
- 			dbentp->key_data = kdata;
- 			correlation->key_data_index = dbentp->n_key_data;
- 			memset(&kdata[dbentp->n_key_data], 0,
- 			       sizeof(krb5_key_data));
- 			kdata[dbentp->n_key_data].key_data_ver = 1;
- 			dbentp->n_key_data++;
- 			corr_found = 1;
- 		    }
- 		    else
- 			retval = ENOMEM;
- 		}
- 		else
- 		    retval = ENOMEM;
- 	    }
- 
- 	    /* Check to see if we either found a correlation or made one */
- 	    if (corr_found) {
- 		/* Special case for key version number */
- 		if (taglist[1] == -1) {
- 		    dbentp->key_data[correlation->key_data_index].
- 			key_data_kvno = taglist[2];
- 		}
- 		else {
- 		    dbentp->key_data[correlation->key_data_index].
- 			key_data_type[taglist[1]] = taglist[2];
- 		    dbentp->key_data[correlation->key_data_index].
- 			key_data_length[taglist[1]] = (krb5_int16) data_length;
- 		    dbentp->key_data[correlation->key_data_index].
- 			key_data_contents[taglist[1]] = tagged_data;
- 		}
- 		parsed_mask |= KRB5_ADM_M_KEYDATA;
- 	    }
- 	    else
- 		break;
- 	    continue;
- 	}
- 	else {
- 	    if ((retval != ENOENT) && (retval != EINVAL))
- 		break;
- 	}
- 
- 	/* Check for extra data */
- 	if (!(retval = decode_kw_tagged(&data[i],
- 					KRB5_ADM_KW_EXTRADATA,
- 					0,
- 					taglist,
- 					&data_length,
- 					&dbentp->e_data))) {
- 	    dbentp->e_length = (krb5_int16) data_length;
- 	    parsed_mask |= KRB5_ADM_M_EXTRADATA;
- 	    continue;
- 	}
- 	else {
- 	    if ((retval != ENOENT) && (retval != EINVAL))
- 		break;
- 	}
- 
- 	/* If we fall through here, we've got something unrecognized */
- 	if (retval) {
- 	    retval = EINVAL;
- 	    break;
- 	}
-     }
- 
-     if (retval) {
- 	if (*pwordp) {
- 	    memset(*pwordp, 0, strlen(*pwordp));
- 	    free(*pwordp);
- 	    *pwordp = (char *) NULL;
- 	}
- 	parsed_mask = 0;
-     }
-     if (correlators)
- 	free(correlators);
-     *validp |= parsed_mask;
-     return(retval);
- }
- #endif
--- 0 ----
Index: krb5/lib/kadm/adm_kw_enc.c
diff -c krb5/lib/kadm/adm_kw_enc.c:1.1.1.1 krb5/lib/kadm/adm_kw_enc.c:removed
*** krb5/lib/kadm/adm_kw_enc.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_kw_enc.c	Sun Mar 16 20:22:24 2003
***************
*** 1,433 ****
- /*
-  * lib/kadm/adm_kw_enc.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * adm_kw_enc.c	- routines to encode principal attributes in keyword-value
-  *		  pairs.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- 
- /*
-  * format_kw_string()	- Format a keyword=<string> pair.
-  * 
-  * Work routine for other string-based formatters also.
-  */
- static krb5_error_code
- format_kw_string(datap, kwordp, valp)
-     krb5_data	*datap;
-     char	*kwordp;
-     char	*valp;
- {
-     krb5_error_code	retval;
-     char		fbuffer[BUFSIZ];
- 
-     retval = ENOMEM;
-     sprintf(fbuffer,"%s=%s", kwordp, valp);
-     datap->data = (char *) malloc(strlen(fbuffer)+1);
-     if (datap->data) {
- 	datap->length = strlen(fbuffer);
- 	strcpy(datap->data, fbuffer);
- 	retval = 0;
-     }
-     return(retval);
- }
- 
- /*
-  * format_kw_integer()	- Format a keyword=<integer> pair.
-  */
- static krb5_error_code
- format_kw_integer(datap, kwordp, val)
-     krb5_data	*datap;
-     char	*kwordp;
-     krb5_ui_4	val;
- {
-     krb5_error_code	retval;
-     char		fbuffer[BUFSIZ];
- 
-     retval = ENOMEM;
-     sprintf(fbuffer,"%s=", kwordp);
-     datap->data = (char *) malloc(strlen(fbuffer)+sizeof(krb5_ui_4));
-     if (datap->data) {
- 	datap->length = strlen(fbuffer);
- 	strcpy(datap->data, fbuffer);
- 	datap->data[datap->length]   = (unsigned char) ((val >> 24) & 0xff);
- 	datap->data[datap->length+1] = (unsigned char) ((val >> 16) & 0xff);
- 	datap->data[datap->length+2] = (unsigned char) ((val >> 8) & 0xff);
- 	datap->data[datap->length+3] = (unsigned char) (val & 0xff);
- 	datap->length += sizeof(krb5_ui_4);
- 	retval = 0;
-     }
-     return(retval);
- }
- 
- /*
-  * format_kw_gentime()	- Format a keyword=<general-time> pair.
-  *
-  * XXX - should this routine know so much about how generaltime is encoded?
-  */
- static krb5_error_code
- format_kw_gentime(datap, kwordp, timep)
-     krb5_data		*datap;
-     char		*kwordp;
-     krb5_timestamp	*timep;
- {
-     krb5_error_code	retval;
-     char		fbuffer[BUFSIZ];
-     time_t		tval;
-     struct tm		*time_gmt;
- 
-     retval = EINVAL;
-     tval = (time_t) *timep;
-     time_gmt = gmtime(&tval);
-     if (time_gmt) {
- 	sprintf(fbuffer,"%04d%02d%02d%02d%02d%02dZ",
- 		time_gmt->tm_year+1900,
- 		time_gmt->tm_mon+1,
- 		time_gmt->tm_mday,
- 		time_gmt->tm_hour,
- 		time_gmt->tm_min,
- 		time_gmt->tm_sec);
- 	retval = format_kw_string(datap, kwordp, fbuffer);
-     }
-     return(retval);
- }
- 
- /*
-  * format_kw_tagged()	- Format a <tagged>=<taglist>...<value> list.
-  */
- static krb5_error_code
- format_kw_tagged(datap, kwordp, ntags, taglist, vallen, val)
-     krb5_data	*datap;
-     char	*kwordp;
-     const int	ntags;
-     krb5_int32	*taglist;
-     krb5_int32	vallen;
-     krb5_octet	*val;
- {
-     krb5_error_code	retval;
-     unsigned char	*cp;
-     int			i;
- 
-     /* Calculate the size required:
-      *	strlen(kwordp) + 1 for "kword"=
-      *	4 * ntags for tags
-      *	vallen for value;
-      */
-     datap->data = (char *) malloc(strlen(kwordp)+
- 				  1+
- 				  (ntags*sizeof(krb5_int32))+
- 				  vallen+1);
-     if (datap->data) {
- 	datap->length = strlen(kwordp)+1+(ntags*sizeof(krb5_int32))+vallen;
- 	cp = (unsigned char *) datap->data;
- 	cp[datap->length] = '\0';
- 	sprintf((char *) cp, "%s=", kwordp);
- 	cp += strlen((char *) cp);
- 	for (i=0; i<ntags; i++) {
- 	    cp[0] = (unsigned char) ((taglist[i] >> 24) & 0xff);
- 	    cp[1] = (unsigned char) ((taglist[i] >> 16) & 0xff);
- 	    cp[2] = (unsigned char) ((taglist[i] >> 8) & 0xff);
- 	    cp[3] = (unsigned char) (taglist[i] & 0xff);
- 	    cp += sizeof(krb5_int32);
- 	}
- 	if (val && vallen)
- 	    memcpy(cp, val, vallen);
- 	retval = 0;
-     }
-     return(retval);
- }
- 
- #if !defined(_MSDOS) && !defined(_WIN32) && !defined(_MACINTOSH)
- /*
-  * krb5_adm_dbent_to_proto()	- Convert database a database entry into
-  *				  an external attribute list.
-  *
-  * "valid" controls the generation of "datap" and "nentp".  For each
-  * corresponding bit in "valid" a keyword-value pair is generated from
-  * values in "dbentp" or "password" and put into "datap".  The number of
-  * generated pairs is returned in "nentp".  Additionally, the KRB5_ADM_M_SET
-  * and KRB5_ADM_M_GET bits control whether we are generating attribute lists
-  * for a "set" operation or a "get" operation.  One of these bits must be
-  * specified.
-  *
-  * Successful callers must free the storage for datap and datap->data
-  * either manually or using krb5_free_adm_data().
-  */
- krb5_error_code
- krb5_adm_dbent_to_proto(kcontext, valid, dbentp, password, nentp, datap)
-     krb5_context	kcontext;	/* Kerberos context	*/ /* In */
-     krb5_ui_4		valid;		/* Valid bitmask	*/ /* In */
-     krb5_db_entry	*dbentp;	/* Database entry	*/ /* In */
-     char		*password;	/* New password for set	*/ /* In */
-     krb5_int32		*nentp;		/* Number of components	*/ /* Out */
-     krb5_data		**datap;	/* Output list		*/ /* Out */
- {
-     krb5_error_code	kret;
-     krb5_data		*outlist;
-     size_t		n2alloc;
-     int			outindex;
-     krb5_boolean	is_set;
-     krb5_ui_4		tmp;
-     krb5_int32		taglist[4];
-     krb5_tl_data	*tl_data;
-     int			keyind, attrind;
- 
-     kret = 0;
-     /* First check out whether this is a set or get and the mask */
-     is_set = ((valid & KRB5_ADM_M_SET) == KRB5_ADM_M_SET);
-     if ((is_set && ((valid & ~KRB5_ADM_M_SET_VALID) != 0)) ||
- 	(!is_set && ((valid & ~KRB5_ADM_M_GET_VALID) != 0)) ||
- 	(!is_set && ((valid & KRB5_ADM_M_GET) == 0)))
- 	return(EINVAL);
- 
-     /*
-      * Compute the number of elements to allocate.  First count set bits.
-      */
-     n2alloc = 0;
-     for (tmp = valid & ~(KRB5_ADM_M_SET|KRB5_ADM_M_GET);
- 	 tmp;
- 	 tmp >>= 1) {
- 	if (tmp & 1)
- 	    n2alloc++;
-     }
-     if (valid & KRB5_ADM_M_AUXDATA)
- 	n2alloc += (dbentp->n_tl_data - 1);
-     /*
-      * NOTE: If the number of per-key attributes increases, you must increase
-      * the 3 below.  The 3 represents 1 for key version, 1 for key type and
-      * one for salt type.
-      */
-     if (valid & KRB5_ADM_M_KEYDATA)
- 	n2alloc += ((dbentp->n_key_data*3)-1);
- 
-     n2alloc *= sizeof(krb5_data);
-     outindex = 0;
-     outlist = (krb5_data *) malloc(n2alloc);
-     if (outlist) {
- 	/* Clear out the output data list */
- 	memset((char *) outlist, 0, n2alloc);
- 
- 	/* Handle password only for set request */
- 	if (is_set &&
- 	    ((valid & KRB5_ADM_M_PASSWORD) != 0) &&
- 	    password) {
- 	    if (kret = format_kw_string(&outlist[outindex],
- 					KRB5_ADM_KW_PASSWORD,
- 					password))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle maximum ticket lifetime */
- 	if ((valid & KRB5_ADM_M_MAXLIFE) != 0) {
- 	    if (kret = format_kw_integer(&outlist[outindex],
- 					 KRB5_ADM_KW_MAXLIFE,
- 					 (krb5_ui_4) dbentp->max_life))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle maximum renewable ticket lifetime */
- 	if ((valid & KRB5_ADM_M_MAXRENEWLIFE) != 0) {
- 	    if (kret =
- 		format_kw_integer(&outlist[outindex],
- 				  KRB5_ADM_KW_MAXRENEWLIFE,
- 				  (krb5_ui_4) dbentp->max_renewable_life))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle principal expiration */
- 	if ((valid & KRB5_ADM_M_EXPIRATION) != 0) {
- 	    if (kret = format_kw_gentime(&outlist[outindex],
- 					 KRB5_ADM_KW_EXPIRATION,
- 					 &dbentp->expiration))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle password expiration */
- 	if ((valid & KRB5_ADM_M_PWEXPIRATION) != 0) {
- 	    if (kret = format_kw_gentime(&outlist[outindex],
- 					 KRB5_ADM_KW_PWEXPIRATION,
- 					 &dbentp->pw_expiration))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Random key */
- 	if ((valid & KRB5_ADM_M_RANDOMKEY) != 0) {
- 	    if (kret = format_kw_integer(&outlist[outindex],
- 					 KRB5_ADM_KW_RANDOMKEY,
- 					 1))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle flags */
- 	if ((valid & KRB5_ADM_M_FLAGS) != 0) {
- 	    if (kret = format_kw_integer(&outlist[outindex],
- 					 KRB5_ADM_KW_FLAGS,
- 					 (krb5_ui_4) dbentp->attributes))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle last successful password entry */
- 	if (!is_set &&
- 	    ((valid & KRB5_ADM_M_LASTSUCCESS) != 0)) {
- 	    if (kret = format_kw_gentime(&outlist[outindex],
- 					 KRB5_ADM_KW_LASTSUCCESS,
- 					 &dbentp->last_success))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle last failed password attempt */
- 	if (!is_set &&
- 	    ((valid & KRB5_ADM_M_LASTFAILED) != 0)) {
- 	    if (kret = format_kw_gentime(&outlist[outindex],
- 					 KRB5_ADM_KW_LASTFAILED,
- 					 &dbentp->last_failed))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 	/* Handle number of failed password attempts */
- 	if (!is_set &&
- 	    ((valid & KRB5_ADM_M_FAILCOUNT) != 0)) {
- 	    if (kret = format_kw_integer(&outlist[outindex],
- 					 KRB5_ADM_KW_FAILCOUNT,
- 					 (krb5_ui_4) dbentp->fail_auth_count))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
- 
- 	/* Handle the auxiliary data */
- 	if ((valid & KRB5_ADM_M_AUXDATA) != 0) {
- 	    for (tl_data = dbentp->tl_data; tl_data; tl_data =
- 		 tl_data->tl_data_next) {
- 		taglist[0] = (krb5_int32) tl_data->tl_data_type;
- 		if (kret = format_kw_tagged(&outlist[outindex],
- 					    KRB5_ADM_KW_AUXDATA,
- 					    1,
- 					    taglist,
- 					    (krb5_int32) tl_data->
- 					        tl_data_length,
- 					    tl_data->tl_data_contents))
- 		    goto choke;
- 		else
- 		    outindex++;
- 	    }
- 	}
- 
- 	/* Handle the key data */
- 	if (!is_set &&
- 	    ((valid  & KRB5_ADM_M_KEYDATA) != 0)) {
- 	    for (keyind = 0; keyind < dbentp->n_key_data; keyind++) {
- 		/*
- 		 * First handle kvno
- 		 */
- 		taglist[0] = (krb5_int32) keyind;
- 		taglist[1] = (krb5_int32) -1;
- 		taglist[2] = (krb5_int32) dbentp->key_data[keyind].
- 		    key_data_kvno;
- 		if (kret = format_kw_tagged(&outlist[outindex],
- 					    KRB5_ADM_KW_KEYDATA,
- 					    3,
- 					    taglist,
- 					    0,
- 					    (krb5_octet *) NULL))
- 		    goto choke;
- 		else
- 		    outindex++;
- 
- 		/*
- 		 * Then each attribute as supported.
- 		 */
- 		for (attrind = 0;
- 		     attrind < KRB5_KDB_V1_KEY_DATA_ARRAY;
- 		     attrind++) {
- 		    taglist[1] = (krb5_int32) attrind;
- 		    taglist[2] = (krb5_int32) dbentp->key_data[keyind].
- 			key_data_type[attrind];
- 		    if (kret = format_kw_tagged(&outlist[outindex],
- 						KRB5_ADM_KW_KEYDATA,
- 						3,
- 						taglist,
- 						(krb5_int32) dbentp->
- 						    key_data[keyind].
- 						    key_data_length[attrind],
- 						dbentp->key_data[keyind].
- 						    key_data_contents[attrind])
- 			)
- 			goto choke;
- 		    else
- 			outindex++;
- 		}
- 	    }
- 	}
- 
- 	/* Finally, handle the extra data */
- 	if ((valid & KRB5_ADM_M_EXTRADATA) != 0) {
- 	    if (kret = format_kw_tagged(&outlist[outindex],
- 					KRB5_ADM_KW_EXTRADATA,
- 					0,
- 					(krb5_int32 *) NULL,
- 					(krb5_int32) dbentp->e_length,
- 					dbentp->e_data))
- 		goto choke;
- 	    else
- 		outindex++;
- 	}
-     }
-     else {
- 	if (n2alloc)
- 	    kret = ENOMEM;
-     }
-  choke:
-     if (kret) {
- 	if (outlist) {
- 	    int i;
- 	    for (i=0; i<outindex; i++) {
- 		if (outlist[i].data) {
- 		    memset(outlist[i].data, 0, (size_t) outlist[i].length);
- 		    free(outlist[i].data);
- 		}
- 	    }
- 	    free(outlist);
- 	}
- 	outlist = (krb5_data *) NULL;
- 	outindex = 0;
-     }
-     *datap = outlist;
-     *nentp = outindex;
-     return(kret);
- }
- #endif
- 
--- 0 ----
Index: krb5/lib/kadm/adm_rw.c
diff -c krb5/lib/kadm/adm_rw.c:1.1.1.1 krb5/lib/kadm/adm_rw.c:removed
*** krb5/lib/kadm/adm_rw.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/adm_rw.c	Sun Mar 16 20:22:24 2003
***************
*** 1,534 ****
- /*
-  * lib/kadm/adm_rw.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * Routines to engage in the administrative (password changing) protocol.
-  */
- #define NEED_SOCKETS
- #include "k5-int.h"
- #include "adm_proto.h"
- 
- /*
-  * Local prototypes (needed or else the PC will pass fail).
-  */
- static void kadm_copyin_int32 PROTOTYPE((char *, krb5_int32 *));
- static void kadm_copyout_int32 PROTOTYPE((krb5_int32, char *));
- 
- /*
-  * Routines to [de]serialize integers.
-  *
-  * kadm_copyin_int32	- Move a 32-bit integer fron network byte order to
-  *			  host byte order.
-  * kadm_copyout_int32	- Move a 32-bit integer from host byte order to
-  *			  network byte order.
-  */
- static void
- kadm_copyin_int32(cp, ip)
-     char	*cp;
-     krb5_int32	*ip;
- {
-     *ip = (((krb5_int32) ((unsigned char) cp[0]) << 24) +
- 	   ((krb5_int32) ((unsigned char) cp[1]) << 16) +
- 	   ((krb5_int32) ((unsigned char) cp[2]) << 8) +
- 	   ((krb5_int32) ((unsigned char) cp[3])));
- }
- 
- static void
- kadm_copyout_int32(outint, cp)
-     krb5_int32	outint;
-     char	*cp;
- {
-     cp[0] = (char) ((outint >> 24) & 0xff);
-     cp[1] = (char) ((outint >> 16) & 0xff);
-     cp[2] = (char) ((outint >> 8) & 0xff);
-     cp[3] = (char) (outint & 0xff);
- }
- 
- /*
-  * krb5_free_adm_data()	- Free data blocks allocated by read_adm... routines.
-  */
- void INTERFACE
- krb5_free_adm_data(kcontext, ncomp, datap)
-     krb5_context	kcontext;
-     krb5_int32		ncomp;
-     krb5_data		*datap;
- {
-     int i;
-     
-     if (datap) {
- 	for (i=0; i<ncomp; i++)
- 	    if (datap[i].data && (datap[i].length > 0))
- 		krb5_xfree(datap[i].data);
- 
- 	krb5_xfree(datap);
-     }
- }
- 
- /*
-  * krb5_send_adm_cmd()	- Send an administrative command.
-  *
-  * Send a list of data in a KRB_PRIV message.  Data takes the format:
-  *	nargs (4 octets in network order)
-  *		arg size 1 (4 octets in network order)
-  *		arg data 1 ("arg size 1" octets)
-  *		.
-  *		.
-  *		.
-  */
- krb5_error_code INTERFACE
- krb5_send_adm_cmd(kcontext, sock, ctx, nargs, arglist)
-     krb5_context	kcontext;	/* Context handle	(In ) */
-     krb5_pointer	sock;		/* Socket to write to	(In ) */
-     krb5_auth_context	ctx;		/* Auth context		(In ) */
-     krb5_int32			nargs;		/* Number of arguments	(In ) */
-     krb5_data		*arglist;	/* Components to write	(In ) */
- {
-     int	writebufsize;
-     int i;
-     char *writebuf;
-     krb5_error_code ret;
-     krb5_int32	ac_flags;
- 
-     /*
-      * First check that our auth context has the right flags in it.
-      */
-     if (ret = krb5_auth_con_getflags(kcontext, ctx, &ac_flags))
- 	return(ret);
- 
-     if ((ac_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- 		     KRB5_AUTH_CONTEXT_DO_SEQUENCE)) !=
- 	(KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- 	/* XXX - need a better error */
- 	return(KRB5KRB_AP_ERR_MSG_TYPE);
-     }
- 
-     ret = 0;
-     /* Calculate write buffer size */
-     writebufsize = sizeof(krb5_int32);
-     for (i=0; i<nargs; i++) {
- 	writebufsize += sizeof(krb5_int32);	/* for argument size */
- 	writebufsize += arglist[i].length;	/* for actual arg */
-     }
- 
-     if (writebuf = (char *) malloc(writebufsize)) {
- 	char 			*curr;
- 	krb5_data		write_data, out_data;
- 	krb5_replay_data	replay_data;
- 
- 	/* Serialize into write buffer - first number of arguments */
- 	curr = writebuf;
- 	kadm_copyout_int32(nargs, curr);
- 	curr += sizeof(krb5_int32);
- 
- 	/* Then the arguments */
- 	for (i=0; i<nargs; i++) {
- 	    kadm_copyout_int32(arglist[i].length, curr);
- 	    curr += sizeof(krb5_int32);
- 	    memcpy(curr, arglist[i].data, arglist[i].length);
- 	    curr += arglist[i].length;
- 	}
- 
- 	/* Set up the message */
- 	write_data.length = writebufsize;
- 	write_data.data = writebuf;
- 
- 	/* Generate the message */
- 	if (!(ret = krb5_mk_priv(kcontext,
- 				 ctx,
- 				 &write_data,
- 				 &out_data,
- 				 &replay_data))) {
- 	    /* Write the message */
- 	    if (ret = krb5_write_message(kcontext, sock, &out_data))
- 		goto cleanup;
- 	    krb5_xfree(out_data.data);
- 	}
- 
-     cleanup:
- 	/* Paranoia */
- 	memset(writebuf, 0, writebufsize);
- 	free(writebuf);
-     }
-     else {
- 	/* error */
- 	ret = ENOMEM;
-     }
-     return(ret);
- }
- 
- /*
-  * krb5_send_adm_reply()	- Send an administrative reply.
-  *
-  * Send a reply in a KRB_PRIV message.  Data takes the format:
-  *	status (4 octets in network order)
-  *	ncomps (4 octets in network order)
-  *		comp size 1 (4 octets in network order)
-  *		comp data 1 ("comp size 1" octets)
-  *		.
-  *		.
-  *		.
-  */
- krb5_error_code
- krb5_send_adm_reply(kcontext, sock, ctx, cmd_stat, ncomps, complist)
-     krb5_context	kcontext;	/* Context handle	(In ) */
-     krb5_pointer	sock;		/* Socket to write to	(In ) */
-     krb5_auth_context	ctx;		/* Auth context		(In ) */
-     krb5_int32		cmd_stat;	/* Command status	(In ) */
-     krb5_int32			ncomps;		/* Number of arguments	(In ) */
-     krb5_data		*complist;	/* Components to write	(In ) */
- {
-     int	writebufsize;
-     int i;
-     char *writebuf;
-     krb5_error_code ret;
-     krb5_int32	ac_flags;
- 
-     /*
-      * First check that our auth context has the right flags in it.
-      */
-     if (ret = krb5_auth_con_getflags(kcontext, ctx, &ac_flags))
- 	return(ret);
- 
-     if ((ac_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- 		     KRB5_AUTH_CONTEXT_DO_SEQUENCE)) !=
- 	(KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- 	/* XXX - need a better error */
- 	return(KRB5KRB_AP_ERR_MSG_TYPE);
-     }
- 
-     ret = 0;
-     /* Calculate write buffer size */
-     writebufsize = 2 * sizeof(krb5_int32);
-     for (i=0; i<ncomps; i++) {
- 	writebufsize += sizeof(krb5_int32);	/* for argument size */
- 	writebufsize += complist[i].length;	/* for actual arg */
-     }
- 
-     if (writebuf = (char *) malloc(writebufsize)) {
- 	char 			*curr;
- 	krb5_data		write_data, out_data;
- 	krb5_replay_data	replay_data;
- 
- 	/* Serialize into write buffer - first command status */
- 	curr = writebuf;
- 	kadm_copyout_int32(cmd_stat, curr);
- 	curr += sizeof(krb5_int32);
- 
- 	/* Now number of reply components */
- 	kadm_copyout_int32(ncomps, curr);
- 	curr += sizeof(krb5_int32);
- 
- 	/* Then the arguments */
- 	for (i=0; i<ncomps; i++) {
- 	    kadm_copyout_int32(complist[i].length, curr);
- 	    curr += sizeof(krb5_int32);
- 	    memcpy(curr, complist[i].data, complist[i].length);
- 	    curr += complist[i].length;
- 	}
- 
- 	/* Set up the message */
- 	write_data.length = writebufsize;
- 	write_data.data = writebuf;
- 
- 	/* Generate the message */
- 	if (!(ret = krb5_mk_priv(kcontext,
- 				 ctx,
- 				 &write_data,
- 				 &out_data,
- 				 &replay_data))) {
- 	    /* Write the message */
- 	    if (ret = krb5_write_message(kcontext, sock, &out_data))
- 		goto cleanup;
- 	    krb5_xfree(out_data.data);
- 	}
- 
-     cleanup:
- 	/* Paranoia */
- 	memset(writebuf, 0, writebufsize);
- 	free(writebuf);
-     }
-     else {
- 	/* error */
- 	ret = ENOMEM;
-     }
-     return(ret);
- }
- 
- /*
-  * krb5_read_adm_cmd()	- Read an administrative protocol command.
-  *
-  * Read an administrative command from the socket.  Expect data in the
-  * same format as send_adm_cmd shoots them out in.
-  *
-  * It is the caller's responsibility to free the memory allocated for
-  * the read in argument list.
-  */
- krb5_error_code
- krb5_read_adm_cmd(kcontext, sock, ctx, nargs, arglist)
-     krb5_context	kcontext;	/* Context handle	(In ) */
-     krb5_pointer	sock;		/* Socket to read from	(In ) */
-     krb5_auth_context	ctx;		/* Auth context		(In ) */
-     krb5_int32		*nargs;		/* Number of arguments	(Out) */
-     krb5_data		**arglist;	/* List of arguments	(Out) */
- {
-     krb5_data		read_data;
-     krb5_error_code	ret;
-     krb5_data		msg_data;
-     krb5_replay_data	replay_data;
-     krb5_int32		ac_flags;
-     krb5_int32		len32;
- 
-     /*
-      * First check that our auth context has the right flags in it.
-      */
-     if (ret = krb5_auth_con_getflags(kcontext, ctx, &ac_flags))
- 	return(ret);
- 
-     if ((ac_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- 		     KRB5_AUTH_CONTEXT_DO_SEQUENCE)) !=
- 	(KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- 	/* XXX - need a better error */
- 	return(KRB5KRB_AP_ERR_MSG_TYPE);
-     }
- 
-     if (!(ret = krb5_read_message(kcontext, sock, &read_data))) {
- 	if (!(ret = krb5_rd_priv(kcontext,
- 				 ctx,
- 				 &read_data,
- 				 &msg_data,
- 				 &replay_data))) {
- 	    char *curr;
- 	    int replyok;
- 	    int i;
- 
- 	    replyok = 0;
- 	    /* We'd better have at least one reply component */
- 	    if (msg_data.length >= sizeof(krb5_int32)) {
- 		curr = msg_data.data;
- 		kadm_copyin_int32(curr, nargs);
- 		curr += sizeof(krb5_int32);
- 
- 		/* Are there any components to copy? */
- 		if (*nargs > 0) {
- 
- 		    /* Get the memory for the list */
- 		    if (*arglist = (krb5_data *)
- 			malloc((size_t) (*nargs) * sizeof(krb5_data))) {
- 			krb5_data *xarglist;
- 
- 			xarglist = *arglist;
- 			memset((char *) (xarglist), 0,
- 				(size_t) (*nargs) * sizeof(krb5_data));
- 
- 			replyok = 1;
- 			/* Copy out each list entry */
- 			for (i=0; i<*nargs; i++) {
- 
- 			    /* First get the length of the reply component */
- 			    if (curr + sizeof(krb5_int32) - msg_data.data <=
- 				msg_data.length) {
- 
- 				kadm_copyin_int32(curr, &len32);
- 				xarglist[i].length = (int) len32;
- 				curr += sizeof(krb5_int32);
- 
- 				/* Then get the memory for the actual data */
- 				if ((curr + xarglist[i].length -
- 				     msg_data.data <= msg_data.length) &&
- 				    (xarglist[i].data = (char *)
- 				     malloc(xarglist[i].length+1))) {
- 
- 				    /* Then copy it out */
- 				    memcpy(xarglist[i].data,
- 					   curr,
- 					   xarglist[i].length);
- 				    curr += xarglist[i].length;
- 
- 				    /* Null terminate for convenience */
- 				    xarglist[i].data[xarglist[i].length] 
- 					    = '\0';
- 				}
- 				else {
- 				    /* Not enough remaining data. */
- 				    replyok = 0;
- 				    break;
- 				}
- 			    }
- 			    else {
- 				/* Not enough remaining data */
- 				replyok = 0;
- 				break;
- 			    }
- 			}
- 			if (!replyok)
- 			    krb5_free_adm_data(kcontext, *nargs, *arglist);
- 		    }
- 		}
- 		else {
- 		    if (*nargs == 0) {
- 			*arglist = (krb5_data *) NULL;
- 			replyok = 1;
- 		    }
- 		}
- 	    }
- 	    if (!replyok) {
- 		ret = KRB5KRB_AP_ERR_MSG_TYPE;	/* syntax error */
- 	    }
- 	    memset(msg_data.data, 0, msg_data.length);
- 	    krb5_xfree(msg_data.data);
- 	}
- 	krb5_xfree(read_data.data);
-     }
-     return(ret);
- }
- 
- /*
-  * krb5_read_adm_reply()	- Read an administrative protocol response.
-  *
-  * Expect to read them out in the same format as send_adm_reply shoots them
-  * in.
-  *
-  * It is the caller's responsibility to free the memory allocated for
-  * the read in component list.
-  */
- krb5_error_code INTERFACE
- krb5_read_adm_reply(kcontext, sock, ctx, cmd_stat, ncomps, complist)
-     krb5_context	kcontext;	/* Context handle	(In ) */
-     krb5_pointer	sock;		/* Socket to read from	(In ) */
-     krb5_auth_context	ctx;		/* Auth context		(In ) */
-     krb5_int32		*cmd_stat;	/* Command status	(Out) */
-     krb5_int32		*ncomps;	/* # of reply components(Out) */
-     krb5_data		**complist;	/* List of components	(Out) */
- {
-     krb5_data		read_data;
-     krb5_error_code	ret;
-     krb5_data		msg_data;
-     krb5_replay_data	replay_data;
-     krb5_int32		ac_flags;
-     krb5_int32		len32;
- 
-     /*
-      * First check that our auth context has the right flags in it.
-      */
-     if (ret = krb5_auth_con_getflags(kcontext, ctx, &ac_flags))
- 	return(ret);
- 
-     if ((ac_flags & (KRB5_AUTH_CONTEXT_RET_SEQUENCE|
- 		     KRB5_AUTH_CONTEXT_DO_SEQUENCE)) !=
- 	(KRB5_AUTH_CONTEXT_RET_SEQUENCE|KRB5_AUTH_CONTEXT_DO_SEQUENCE)) {
- 	/* XXX - need a better error */
- 	return(KRB5KRB_AP_ERR_MSG_TYPE);
-     }
- 
-     if (!(ret = krb5_read_message(kcontext, sock, &read_data))) {
- 	if (!(ret = krb5_rd_priv(kcontext,
- 				 ctx,
- 				 &read_data,
- 				 &msg_data,
- 				 &replay_data))) {
- 	    char *curr;
- 	    int replyok;
- 	    int i;
- 
- 	    replyok = 0;
- 	    /* We'd better have at least two reply components */
- 	    if (msg_data.length >= (2*sizeof(krb5_int32))) {
- 		curr = msg_data.data;
- 		kadm_copyin_int32(curr, cmd_stat);
- 		curr += sizeof(krb5_int32);
- 		kadm_copyin_int32(curr, ncomps);
- 		curr += sizeof(krb5_int32);
- 
- 		/* Are there any components to copy? */
- 		if (*ncomps > 0) {
- 
- 		    /* Get the memory for the list */
- 		    if (*complist = (krb5_data *)
- 			malloc((size_t) ((*ncomps) * sizeof(krb5_data)))) {
- 			krb5_data *xcomplist;
- 
- 			xcomplist = *complist;
- 			memset((char *) (xcomplist), 0, 
- 			       (size_t) ((*ncomps) * sizeof(krb5_data)));
- 
- 			replyok = 1;
- 			/* Copy out each list entry */
- 			for (i=0; i<*ncomps; i++) {
- 
- 			    /* First get the length of the reply component */
- 			    if (curr + sizeof(krb5_int32) - msg_data.data <=
- 				msg_data.length) {
- 				kadm_copyin_int32(curr, &len32);
- 				xcomplist[i].length = (int) len32;
- 				curr += sizeof(krb5_int32);
- 
- 				/* Then get the memory for the actual data */
- 				if ((curr + xcomplist[i].length -
- 				     msg_data.data <= msg_data.length) &&
- 				    (xcomplist[i].data = (char *)
- 				     malloc(xcomplist[i].length+1))) {
- 
- 				    /* Then copy it out */
- 				    memcpy(xcomplist[i].data,
- 					   curr,
- 					   xcomplist[i].length);
- 				    curr += xcomplist[i].length;
- 
- 				    /* Null terminate for convenience */
- 				    xcomplist[i].data[xcomplist[i].length] 
- 					    = '\0';
- 				}
- 				else {
- 				    /* Not enough remaining data. */
- 				    replyok = 0;
- 				    break;
- 				}
- 			    }
- 			    else {
- 				/* Not enough remaining data */
- 				replyok = 0;
- 				break;
- 			    }
- 			}
- 			if (!replyok)
- 			    krb5_free_adm_data(kcontext, *ncomps, *complist);
- 		    }
- 		}
- 		else {
- 		    if (*ncomps == 0) {
- 			*complist = (krb5_data *) NULL;
- 			replyok = 1;
- 		    }
- 		}
- 	    }
- 	    if (!replyok) {
- 		ret = KRB5KRB_AP_ERR_MSG_TYPE;	/* syntax error */
- 	    }
- 	    memset(msg_data.data, 0, msg_data.length);
- 	    krb5_xfree(msg_data.data);
- 	}
- 	krb5_xfree(read_data.data);
-     }
-     return(ret);
- }
--- 0 ----
Index: krb5/lib/kadm/alt_prof.c
diff -c krb5/lib/kadm/alt_prof.c:1.1.1.1 krb5/lib/kadm/alt_prof.c:removed
*** krb5/lib/kadm/alt_prof.c:1.1.1.1	Mon Jun  2 17:56:02 1997
--- krb5/lib/kadm/alt_prof.c	Sun Mar 16 20:22:24 2003
***************
*** 1,447 ****
- /*
-  * lib/kadm/alt_prof.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * alt_prof.c - Implement alternate profile file handling.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- #include <stdio.h>
- #include <ctype.h>
- 
- /*
-  * krb5_aprof_init()	- Initialize alternate profile context.
-  *
-  * Parameters:
-  *	fname		- default file name of the profile.
-  *	envname		- environment variable name which can override fname.
-  *	acontextp	- Pointer to opaque context for alternate profile.
-  *
-  * Returns:
-  *	error codes from profile_init()
-  */
- krb5_error_code
- krb5_aprof_init(fname, envname, acontextp)
-     char		*fname;
-     char		*envname;
-     krb5_pointer	*acontextp;
- {
-     krb5_error_code	kret;
-     const char		*namelist[2];
-     profile_t		profile;
-     
-     namelist[1] = (char *) NULL;
-     profile = (profile_t) NULL;
-     if (envname) {
- 	if ((namelist[0] = getenv(envname))) {
- 	    if (!(kret = profile_init(namelist, &profile))) {
- 		*acontextp = (krb5_pointer) profile;
- 		return(0);
- 	    }
- 	}
-     }
-     namelist[0] = fname;
-     profile = (profile_t) NULL;
-     if (!(kret = profile_init(namelist, &profile))) {
- 	*acontextp = (krb5_pointer) profile;
- 	return(0);
-     }
-     return(kret);
- }
- 
- /*
-  * krb5_aprof_getvals()	- Get values from alternate profile.
-  *
-  * Parameters:
-  *	acontext	- opaque context for alternate profile.
-  *	hierarchy	- hierarchy of value to retrieve.
-  *	retdata		- Returned data values.
-  *
-  * Returns:
-  * 	error codes from profile_get_values()
-  */
- krb5_error_code
- krb5_aprof_getvals(acontext, hierarchy, retdata)
-     krb5_pointer	acontext;
-     const char		**hierarchy;
-     char		***retdata;
- {
-     return(profile_get_values((profile_t) acontext,
- 			      hierarchy,
- 			      retdata));
- }
- 
- /*
-  * krb5_aprof_get_deltat()	- Get a delta time value from the alternate
-  *				  profile.
-  *
-  * Parameters:
-  *	acontext		- opaque context for alternate profile.
-  *	hierarchy		- hierarchy of value to retrieve.
-  *	uselast			- if true, use last value, otherwise use
-  *				  first value found.
-  *	deltatp			- returned delta time value.
-  *
-  * Returns:
-  * 	error codes from profile_get_values()
-  *	error codes from krb5_string_to_deltat()
-  */
- krb5_error_code
- krb5_aprof_get_deltat(acontext, hierarchy, uselast, deltatp)
-     krb5_pointer	acontext;
-     const char		**hierarchy;
-     krb5_boolean	uselast;
-     krb5_deltat		*deltatp;
- {
-     krb5_error_code	kret;
-     char		**values;
-     char		*valp;
-     int			index;
- 
-     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
- 	index = 0;
- 	if (uselast) {
- 	    for (index=0; values[index]; index++);
- 	    index--;
- 	}
- 	valp = values[index];
- 	kret = krb5_string_to_deltat(valp, deltatp);
- 
- 	/* Free the string storage */
- 	for (index=0; values[index]; index++)
- 	    krb5_xfree(values[index]);
- 	krb5_xfree(values);
-     }
-     return(kret);
- }
- 
- /*
-  * krb5_aprof_get_string()	- Get a string value from the alternate
-  *				  profile.
-  *
-  * Parameters:
-  *	acontext		- opaque context for alternate profile.
-  *	hierarchy		- hierarchy of value to retrieve.
-  *	uselast			- if true, use last value, otherwise use
-  *				  first value found.
-  *	stringp			- returned string value.
-  *
-  * Returns:
-  * 	error codes from profile_get_values()
-  */
- krb5_error_code
- krb5_aprof_get_string(acontext, hierarchy, uselast, stringp)
-     krb5_pointer	acontext;
-     const char		**hierarchy;
-     krb5_boolean	uselast;
-     char		**stringp;
- {
-     krb5_error_code	kret;
-     char		**values;
-     int			index, i;
- 
-     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
- 	index = 0;
- 	if (uselast) {
- 	    for (index=0; values[index]; index++);
- 	    index--;
- 	}
- 
- 	*stringp = values[index];
- 
- 	/* Free the string storage */
- 	for (i=0; values[i]; i++)
- 	    if (i != index)
- 		krb5_xfree(values[i]);
- 	krb5_xfree(values);
-     }
-     return(kret);
- }
- 
- /*
-  * krb5_aprof_get_int32()	- Get a 32-bit integer value from the alternate
-  *				  profile.
-  *
-  * Parameters:
-  *	acontext		- opaque context for alternate profile.
-  *	hierarchy		- hierarchy of value to retrieve.
-  *	uselast			- if true, use last value, otherwise use
-  *				  first value found.
-  *	intp			- returned 32-bit integer value.
-  *
-  * Returns:
-  * 	error codes from profile_get_values()
-  *	EINVAL			- value is not an integer
-  */
- krb5_error_code
- krb5_aprof_get_int32(acontext, hierarchy, uselast, intp)
-     krb5_pointer	acontext;
-     const char		**hierarchy;
-     krb5_boolean	uselast;
-     krb5_int32		*intp;
- {
-     krb5_error_code	kret;
-     char		**values;
-     int			index;
- 
-     if (!(kret = krb5_aprof_getvals(acontext, hierarchy, &values))) {
- 	index = 0;
- 	if (uselast) {
- 	    for (index=0; values[index]; index++);
- 	    index--;
- 	}
- 
- 	if (sscanf(values[index], "%d", intp) != 1)
- 	    kret = EINVAL;
- 
- 	/* Free the string storage */
- 	for (index=0; values[index]; index++)
- 	    krb5_xfree(values[index]);
- 	krb5_xfree(values);
-     }
-     return(kret);
- }
- 
- /*
-  * krb5_aprof_finish()	- Finish alternate profile context.
-  *
-  * Parameter:
-  *	acontext	- opaque context for alternate profile.
-  *
-  * Returns:
-  *	0 on success, something else on failure.
-  */
- krb5_error_code
- krb5_aprof_finish(acontext)
-     krb5_pointer	acontext;
- {
-     profile_release(acontext);
-     return(0);
- }
- 
- /*
-  * krb5_read_realm_params()	- Read per-realm parameters from KDC
-  *				  alternate profile.
-  */
- krb5_error_code
- krb5_read_realm_params(kcontext, realm, kdcprofile, kdcenv, rparamp)
-     krb5_context	kcontext;
-     char		*realm;
-     char		*kdcprofile;
-     char		*kdcenv;
-     krb5_realm_params	**rparamp;
- {
-     char		*filename;
-     char		*envname;
-     char		*lrealm;
-     krb5_pointer	aprofile = 0;
-     krb5_realm_params	*rparams;
-     const char		*hierarchy[4];
-     char		*svalue;
-     krb5_int32		ivalue;
-     krb5_deltat		dtvalue;
- 
-     krb5_error_code	kret;
- 
-     filename = (kdcprofile) ? kdcprofile : DEFAULT_KDC_PROFILE;
-     envname = (kdcenv) ? kdcenv : KDC_PROFILE_ENV;
- 
-     if (kcontext->profile_secure == TRUE) envname = 0;
- 
-     rparams = (krb5_realm_params *) NULL;
-     if (realm)
- 	lrealm = strdup(realm);
-     else {
- 	kret = krb5_get_default_realm(kcontext, &lrealm);
- 	if (kret)
- 	    goto cleanup;
-     }
- 
-     kret = krb5_aprof_init(filename, envname, &aprofile);
-     if (kret)
- 	goto cleanup;
-     
-     rparams = (krb5_realm_params *) malloc(sizeof(krb5_realm_params));
-     if (rparams == 0) {
- 	kret = ENOMEM;
- 	goto cleanup;
-     }
- 
-     /* Initialize realm parameters */
-     memset((char *) rparams, 0, sizeof(krb5_realm_params));
- 
-     /* Get the value for the database */
-     hierarchy[0] = "realms";
-     hierarchy[1] = lrealm;
-     hierarchy[2] = "database_name";
-     hierarchy[3] = (char *) NULL;
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
- 	rparams->realm_dbname = svalue;
- 	
-     /* Get the value for the KDC port list */
-     hierarchy[2] = "kdc_ports";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
- 	rparams->realm_kdc_ports = svalue;
- 	    
-     /* Get the name of the acl file */
-     hierarchy[2] = "acl_file";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
- 	rparams->realm_acl_file = svalue;
- 	    
-     /* Get the value for the kadmind port */
-     hierarchy[2] = "kadmind_port";
-     if (!krb5_aprof_get_int32(aprofile, hierarchy, TRUE, &ivalue)) {
- 	rparams->realm_kadmind_port = ivalue;
- 	rparams->realm_kadmind_port_valid = 1;
-     }
- 	    
-     /* Get the value for the master key name */
-     hierarchy[2] = "master_key_name";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
- 	rparams->realm_mkey_name = svalue;
- 	    
-     /* Get the value for the master key type */
-     hierarchy[2] = "master_key_type";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
- 	if (!krb5_string_to_enctype(svalue, &rparams->realm_enctype))
- 	    rparams->realm_enctype_valid = 1;
- 	krb5_xfree(svalue);
-     }
- 	    
-     /* Get the value for the stashfile */
-     hierarchy[2] = "key_stash_file";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue))
- 	rparams->realm_stash_file = svalue;
- 	    
-     /* Get the value for maximum ticket lifetime. */
-     hierarchy[2] = "max_life";
-     if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
- 	rparams->realm_max_life = dtvalue;
- 	rparams->realm_max_life_valid = 1;
-     }
- 	    
-     /* Get the value for maximum renewable ticket lifetime. */
-     hierarchy[2] = "max_renewable_life";
-     if (!krb5_aprof_get_deltat(aprofile, hierarchy, TRUE, &dtvalue)) {
- 	rparams->realm_max_rlife = dtvalue;
- 	rparams->realm_max_rlife_valid = 1;
-     }
- 	    
-     /* Get the value for the default principal expiration */
-     hierarchy[2] = "default_principal_expiration";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
- 	if (!krb5_string_to_timestamp(svalue,
- 				      &rparams->realm_expiration))
- 	    rparams->realm_expiration_valid = 1;
- 	krb5_xfree(svalue);
-     }
- 	    
-     /* Get the value for the default principal flags */
-     hierarchy[2] = "default_principal_flags";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
- 	char *sp, *ep, *tp;
- 
- 	sp = svalue;
- 	rparams->realm_flags = 0;
- 	while (sp) {
- 	    if ((ep = strchr(sp, (int) ',')) ||
- 		(ep = strchr(sp, (int) ' ')) ||
- 		(ep = strchr(sp, (int) '\t'))) {
- 		/* Fill in trailing whitespace of sp */
- 		tp = ep - 1;
- 		while (isspace(*tp) && (tp < sp)) {
- 		    *tp = '\0';
- 		    tp--;
- 		}
- 		*ep = '\0';
- 		ep++;
- 		/* Skip over trailing whitespace of ep */
- 		while (isspace(*ep) && (*ep)) ep++;
- 	    }
- 	    /* Convert this flag */
- 	    if (krb5_string_to_flags(sp,
- 				     "+",
- 				     "-",
- 				     &rparams->realm_flags))
- 		break;
- 	    sp = ep;
- 	}
- 	if (!sp)
- 	    rparams->realm_flags_valid = 1;
- 	krb5_xfree(svalue);
-     }
- 
-     /* Get the value for the supported enctype/salttype matrix */
-     hierarchy[2] = "supported_enctypes";
-     if (!krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue)) {
- 	krb5_string_to_keysalts(svalue,
- 				", \t",	/* Tuple separators	*/
- 				":.-",	/* Key/salt separators	*/
- 				0,	/* No duplicates	*/
- 				&rparams->realm_keysalts,
- 				&rparams->realm_num_keysalts);
- 	krb5_xfree(svalue);
-     }
- 
- cleanup:
-     if (aprofile)
- 	krb5_aprof_finish(aprofile);
-     if (lrealm)
- 	free(lrealm);
-     if (kret) {
- 	if (rparams)
- 	    krb5_free_realm_params(kcontext, rparams);
- 	rparams = 0;
-     }
-     *rparamp = rparams;
-     return(kret);
- }
- 
- /*
-  * krb5_free_realm_params()	- Free data allocated by above.
-  */
- krb5_error_code
- krb5_free_realm_params(kcontext, rparams)
-     krb5_context	kcontext;
-     krb5_realm_params	*rparams;
- {
-     if (rparams) {
- 	if (rparams->realm_profile)
- 	    krb5_xfree(rparams->realm_profile);
- 	if (rparams->realm_dbname)
- 	    krb5_xfree(rparams->realm_dbname);
- 	if (rparams->realm_mkey_name)
- 	    krb5_xfree(rparams->realm_mkey_name);
- 	if (rparams->realm_stash_file)
- 	    krb5_xfree(rparams->realm_stash_file);
- 	if (rparams->realm_keysalts)
- 	    krb5_xfree(rparams->realm_keysalts);
- 	if (rparams->realm_kdc_ports)
- 	    krb5_xfree(rparams->realm_kdc_ports);
- 	krb5_xfree(rparams);
-     }
-     return(0);
- }
- 
--- 0 ----
Index: krb5/lib/kadm/configure.in
diff -c krb5/lib/kadm/configure.in:1.1.1.1 krb5/lib/kadm/configure.in:removed
*** krb5/lib/kadm/configure.in:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/configure.in	Sun Mar 16 20:22:24 2003
***************
*** 1,16 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_PROG_INSTALL
- AC_HEADER_STDARG
- AC_HAVE_HEADERS(pwd.h syslog.h)
- AC_HAVE_FUNCS(srand48 srand srandom syslog openlog closelog)
- AC_FUNC_CHECK(vsprintf,AC_DEFINE(HAVE_VSPRINTF))
- AC_PROG_AWK
- KRB5_RUN_FLAGS
- LinkFileDir(../libkadm.a, libkadm.a, ./kadm)
- AppendRule([all-unix:: ../libkadm.a])
- AppendRule([all:: all-$(WHAT)])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/kadm/keysalt.c
diff -c krb5/lib/kadm/keysalt.c:1.1.1.1 krb5/lib/kadm/keysalt.c:removed
*** krb5/lib/kadm/keysalt.c:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/keysalt.c	Sun Mar 16 20:22:25 2003
***************
*** 1,207 ****
- /*
-  * lib/kadm/keysalt.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * keysalt.c	- Routines to handle key/salt tuples.
-  */
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- static const char default_tupleseps[]	= ", \t";
- static const char default_ksaltseps[]	= ":.";
- 
- /*
-  * krb5_keysalt_is_present()	- Determine if a key/salt pair is present
-  *				  in a list of key/salt tuples.
-  *
-  *	Salttype may be negative to indicate a search for only a enctype.
-  */
- krb5_boolean
- krb5_keysalt_is_present(ksaltlist, nksalts, enctype, salttype)
-     krb5_key_salt_tuple	*ksaltlist;
-     krb5_int32		nksalts;
-     krb5_enctype	enctype;
-     krb5_int32		salttype;
- {
-     krb5_boolean	foundit;
-     int			i;
- 
-     foundit = 0;
-     if (ksaltlist) {
- 	for (i=0; i<nksalts; i++) {
- 	    if ((ksaltlist[i].ks_enctype == enctype) &&
- 		((ksaltlist[i].ks_salttype == salttype) ||
- 		 (salttype < 0))) {
- 		foundit = 1;
- 		break;
- 	    }
- 	}
-     }
-     return(foundit);
- }
- 
- /*
-  * krb5_keysalt_iterate()	- Do something for each unique key/salt
-  *				  combination.
-  *
-  * If ignoresalt set, then salttype is ignored.
-  */
- krb5_error_code
- krb5_keysalt_iterate(ksaltlist, nksalt, ignoresalt, iterator, arg)
-     krb5_key_salt_tuple	*ksaltlist;
-     krb5_int32		nksalt;
-     krb5_boolean	ignoresalt;
-     krb5_error_code	(*iterator) KRB5_NPROTOTYPE((krb5_key_salt_tuple *,
- 						     krb5_pointer));
-     krb5_pointer	arg;
- {
-     int			i;
-     krb5_error_code	kret;
-     krb5_key_salt_tuple	scratch;
- 
-     kret = 0;
-     for (i=0; i<nksalt; i++) {
- 	scratch.ks_enctype = ksaltlist[i].ks_enctype;
- 	scratch.ks_salttype = (ignoresalt) ? -1 : ksaltlist[i].ks_salttype;
- 	if (!krb5_keysalt_is_present(ksaltlist,
- 				     i,
- 				     scratch.ks_enctype,
- 				     scratch.ks_salttype)) {
- 	    if (kret = (*iterator)(&scratch, arg))
- 		break;
- 	}
-     }
-     return(kret);
- }
- 
- /*
-  * krb5_string_to_keysalts()	- Convert a string representation to a list
-  *				  of key/salt tuples.
-  */
- krb5_error_code
- krb5_string_to_keysalts(string, tupleseps, ksaltseps, dups, ksaltp, nksaltp)
-     char		*string;
-     const char		*tupleseps;
-     const char		*ksaltseps;
-     krb5_boolean	dups;
-     krb5_key_salt_tuple	**ksaltp;
-     krb5_int32		*nksaltp;
- {
-     krb5_error_code	kret;
-     char 		*kp, *sp, *ep;
-     char		sepchar, trailchar;
-     krb5_enctype	ktype;
-     krb5_int32		stype;
-     krb5_key_salt_tuple	*savep;
-     const char		*tseplist;
-     const char		*ksseplist;
-     const char		*septmp;
-     size_t		len;
-     
-     kret = 0;
-     kp = string;
-     tseplist = (tupleseps) ? tupleseps : default_tupleseps;
-     ksseplist = (ksaltseps) ? ksaltseps : default_ksaltseps;
-     while (kp) {
- 	/* Attempt to find a separator */
- 	ep = (char *) NULL;
- 	if (*tseplist) {
- 	    septmp = tseplist;
- 	    for (ep = strchr(kp, (int) *septmp);
- 		 *(++septmp) && !ep;
- 		 ep = strchr(kp, (int) *septmp));
- 	}
- 
- 	if (ep) {
- 	    trailchar = *ep;
- 	    *ep = '\0';
- 	    ep++;
- 	}
- 	/*
- 	 * kp points to something (hopefully) of the form:
- 	 *	<enctype><ksseplist><salttype>
- 	 *	or
- 	 *	<enctype>
- 	 */
- 	sp = (char *) NULL;
- 	/* Attempt to find a separator */
- 	septmp = ksseplist;
- 	for (sp = strchr(kp, (int) *septmp);
- 	     *(++septmp) && !sp;
- 	     ep = strchr(kp, (int) *septmp));
- 
- 	if (sp) {
- 	    /* Separate enctype from salttype */
- 	    sepchar = *sp;
- 	    *sp = '\0';
- 	    sp++;
- 	}
- 	else
- 	    stype = -1;
- 
- 	/*
- 	 * Attempt to parse enctype and salttype.  If we parse well
- 	 * then make sure that it specifies a unique key/salt combo
- 	 */
- 	if (!krb5_string_to_enctype(kp, &ktype) &&
- 	    (!sp || !krb5_string_to_salttype(sp, &stype)) &&
- 	    (dups ||
- 	     !krb5_keysalt_is_present(*ksaltp, *nksaltp, ktype, stype))) {
- 
- 	    /* Squirrel away old keysalt array */
- 	    savep = *ksaltp;
- 	    len = (size_t) *nksaltp;
- 
- 	    /* Get new keysalt array */
- 	    if (*ksaltp = (krb5_key_salt_tuple *)
- 		malloc((len + 1) * sizeof(krb5_key_salt_tuple))) {
- 
- 		/* Copy old keysalt if appropriate */
- 		if (savep) {
- 		    memcpy(*ksaltp, savep,
- 			   len * sizeof(krb5_key_salt_tuple));
- 		    krb5_xfree(savep);
- 		}
- 
- 		/* Save our values */
- 		(*ksaltp)[(*nksaltp)].ks_enctype = ktype;
- 		(*ksaltp)[(*nksaltp)].ks_salttype = stype;
- 		(*nksaltp)++;
- 	    }
- 	    else {
- 		*ksaltp = savep;
- 		break;
- 	    }
- 	}
- 	if (sp)
- 	    sp[-1] = sepchar;
- 	if (ep)
- 	    ep[-1] = trailchar;
- 	kp = ep;
-     }
-     return(kret);
- }
- 
- 
--- 0 ----
Index: krb5/lib/kadm/krb5strings.M
diff -c krb5/lib/kadm/krb5strings.M:1.1.1.1 krb5/lib/kadm/krb5strings.M:removed
*** krb5/lib/kadm/krb5strings.M:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/krb5strings.M	Sun Mar 16 20:22:25 2003
***************
*** 1,250 ****
- .\" lib/kadm/krb5strings.M
- .\" Copyright 1995 by the Massachusetts Institute of Technology.
- .\"
- .\" Export of this software from the United States of America may
- .\"   require a specific license from the United States Government.
- .\"   It is the responsibility of any person or organization contemplating
- .\"   export to obtain such a license before exporting.
- .\" 
- .\" WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
- .\" distribute this software and its documentation for any purpose and
- .\" without fee is hereby granted, provided that the above copyright
- .\" notice appear in all copies and that both that copyright notice and
- .\" this permission notice appear in supporting documentation, and that
- .\" the name of M.I.T. not be used in advertising or publicity pertaining
- .\" to distribution of the software without specific, written prior
- .\" permission.  M.I.T. makes no representations about the suitability of
- .\" this software for any purpose.  It is provided "as is" without express
- .\" or implied warranty.
- .\" 
- .\"
- .TH KRB5STRINGS 3
- .SH NAME
- krb5strings \- String representations of Kerberos V5 internal data.
- .SH KEY TYPES
- The following strings specify valid key types for use by Kerberos V5.
- .TP 2i
- .I null
- Specifies KEYTYPE_NULL.
- .TP 2i
- .I des
- Specifies KEYTYPE_DES.
- 
- .SH SALT TYPES
- The following strings specify valid salt types for use by Kerberos V5.
- .TP 2i
- .I normal
- Specifies KRB5_KDB_SALTTYPE_NORMAL.
- .TP 2i
- .I v4
- Specifies KRB5_KDB_SALTTYPE_V4.
- .TP 2i
- .I norealm
- Specifies KRB5_KDB_SALTTYPE_NOREALM.
- .TP 2i
- .I onlyrealm
- Specifies KRB5_KDB_SALTTYPE_ONLYREALM.
- .TP 2i
- .I afs3
- Specifies KRB5_KDB_SALTTYPE_AFS3.
- .TP 2i
- .I special
- Specifies KRB5_KDB_SALTTYPE_SPECIAL.
- 
- .SH ENCRYPTION TYPES
- The following strings specify valid encryption types for use by Kerberos V5.
- .TP 2i
- .I null
- Specifies ETYPE_NULL.
- .TP 2i
- .I des-cbc-crc
- Specifies ETYPE_DES_CBC_CRC.
- .TP 2i
- .I des-cbc-md4
- Specifies ETYPE_DES_CBC_MD4.
- .TP 2i
- .I des-cbc-md5
- Specifies ETYPE_DES_CBC_MD5.
- .TP 2i
- .I raw-des-cbc
- Specifies ETYPE_RAW_DES_CBC.
- 
- .SH CHECKSUM TYPES
- The following strings specify valid checksum types for use by Kerberos V5.
- .TP 2i
- .I crc32
- Specifies CKSUMTYPE_CRC32.
- .TP 2i
- .I md4
- Specifies CKSUMTYPE_RSA_MD4.
- .TP 2i
- .I md4-des
- Specifies CKSUMTYPE_RSA_MD4_DES.
- .TP 2i
- .I des-cbc
- Specifies CKSUMTYPE_DESCBC.
- .TP 2i
- .I md5
- Specifies CKSUMTYPE_RSA_MD5.
- .TP 2i
- .I md5-des
- Specifies CKSUMTYPE_RSA_MD5_DES.
- 
- .SH PRINCIPAL FLAGS
- The following strings specify particular principal attributes for use by
- Kerberos V5.
- .TP 2i
- .I postdateable
- In the negative sense, specifies KRB5_KDB_DISALLOW_POSTDATED.
- .TP 2i
- .I forwardable
- In the negative sense, specifies KRB5_KDB_DISALLOW_FORWARDABLE.
- .TP 2i
- .I tgt-based
- In the negative sense, specifies KRB5_KDB_DISALLOW_TGT_BASED.
- .TP 2i
- .I renewable
- In the negative sense, specifies KRB5_KDB_DISALLOW_RENEWABLE.
- .TP 2i
- .I proxiable
- In the negative sense, specifies KRB5_KDB_DISALLOW_PROXIABLE.
- .TP 2i
- .I dup-skey
- In the negative sense, specifies KRB5_KDB_DISALLOW_DUP_SKEY.
- .TP 2i
- .I allow-tickets
- In the negative sense, specifies KRB5_KDB_DISALLOW_ALL_TIX.
- .TP 2i
- .I preauth
- Specifies KRB5_KDB_REQUIRES_PRE_AUTH.
- .TP 2i
- .I hwauth
- Specifies KRB5_KDB_REQUIRES_HW_AUTH.
- .TP 2i
- .I pwchange
- Specifies KRB5_KDB_REQUIRES_PWCHANGE.
- .TP 2i
- .I service
- In the negative sense, specifies KRB5_KDB_DISALLOW_SVR.
- .TP 2i
- .I pwservice
- Specifies KRB5_KDB_PWCHANGE_SERVICE.
- .TP 2i
- .I md5
- Specifies KRB5_KDB_SUPPORT_DESMD5.
- 
- .SH ABSOLUTE TIME
- The following formats specify valid absolute time strings for use by Kerberos
- V5.  In the description the following abbreviations are used:
- .in +1i
- .B yy
- denotes the last two digits of the year.
- 
- .B mm
- denotes the two digits representing the month (01 = January, 12 = December).
- 
- .B dd
- denotes the two digits representing the day of the month.
- 
- .B HH
- denotes the two digits representing the hour of the day (24-hour format).
- 
- .B MM
- denotes the two digits representing the minute of the hour.
- 
- .B SS
- denotes the two digits representing the second of the minute.
- .in -1i
- 
- .TP 2i
- .I yymmddHHMMSS
- e.g. 951225093023 specifies 9:30:23 a.m. on 25 December 1995.
- .TP 2i
- .I yy.mm.dd.HH.MM.SS
- e.g. 95.12.25.09.30.23 specifies 9:30:23 a.m. on 25 December 1995.
- .TP 2i
- .I yymmddHHMM
- e.g. 9512250930 specifies 9:30 a.m. on 25 December 1995.
- .TP 2i
- .I HHMMSS
- e.g. 123056 specifies 12:30:56 p.m. today.
- .TP 2i
- .I HHMM
- e.g. 2130 specifies 9:30 p.m. today.
- .TP 2i
- .I HH:MM:SS
- e.g. 12:30:56 specifies 12:30:56 p.m. today.
- .TP 2i
- .I HH:MM
- e.g. 21:30 specifies 9:30 p.m. today.
- .PP
- The following formats are recognized if the target operating system supports
- the
- .B strptime(3)
- function.  See the
- .B strptime(3)
- manual page for a description of the format fields:
- .TP 2i
- .I %x:%X
- Specifies the locale-dependent short date format concatenated by a colon with
- the locale-dependent short time format.
- .TP 2i
- .I %d-%b-%Y:%T
- e.g. 10-January-1995:16:42:23 in U.S. locales.
- .TP 2i
- .I %d-%b-%Y:%R
- e.g. 10-January-1995:16:42 in U.S. locales.
- 
- .SH DELTA TIME
- The following formats specify valid delta time strings for use by Kerberos
- V5.  In the description the following abbreviations are used:
- .in +1i
- .B d
- denotes a number of days.
- 
- .B h[h]
- denotes one or two digits representing a number of hours.
- 
- .B m[m]
- denotes one or two digits representing a number of minutes.
- 
- .B s[s]
- denotes one or two digits representing a number of seconds.
- .in -1i
- .TP 2i
- .I d-hh:mm:ss
- e.g. 7-04:30:01 specifies seven days, four hours 30 minutes and one second.
- .TP 2i
- .I ddhhmmss
- e.g. 7d4h30m1s specifies seven days, four hours 30 minutes and one second.
- .TP 2i
- .I h:mm:ss
- e.g. 6:23:16 specifies six hours, 23 minutes and 16 seconds.
- .TP 2i
- .I hhmmss
- e.g. 6h23m16s specifies six hours 23 minutes and 16 seconds.
- .TP 2i
- .I h:mm
- e.g. 2:30 specifies two hours and 30 minutes.
- .TP 2i
- .I hhmm
- e.g. 2h30m specifies two hours and 30 minutes.
- .TP 2i
- .I dd
- e.g. 2d specifies two days.
- .TP 2i
- .I hh
- e.g. 4h specifies four hours.
- .TP 2i
- .I mm
- e.g. 30m specifies 30 minutes.
- .TP 2i
- .I ss
- e.g. 3600s specifies 3600 seconds.
- 
- .SH SEE ALSO
- kdc.conf(5), krb5kdc(8), kdb5_edit(8), kadmin5(8), strptime(3)
- 
-  
- 
- 
--- 0 ----
Index: krb5/lib/kadm/logger.c
diff -c krb5/lib/kadm/logger.c:1.1.1.1 krb5/lib/kadm/logger.c:removed
*** krb5/lib/kadm/logger.c:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/logger.c	Sun Mar 16 20:22:25 2003
***************
*** 1,940 ****
- /*
-  * lib/kadm/logger.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- #if !defined(_MSDOS)
- 
- /*
-  * logger.c	- Handle logging functions for those who want it.
-  */
- #include "k5-int.h"
- #include "adm_proto.h"
- #include "com_err.h"
- #include <stdio.h>
- #if	HAVE_SYSLOG_H
- #include <syslog.h>
- #endif	/* HAVE_SYSLOG_H */
- #if	HAVE_STDARG_H
- #include <stdarg.h>
- #else	/* HAVE_STDARG_H */
- #include <varargs.h>
- #endif	/* HAVE_STDARG_H */
- 
- #define	KRB5_KLOG_MAX_ERRMSG_SIZE	1024
- #ifndef	MAXHOSTNAMELEN
- #define	MAXHOSTNAMELEN	256
- #endif	/* MAXHOSTNAMELEN */
- 
- /* This is to assure that we have at least one match in the syslog stuff */
- #ifndef	LOG_AUTH
- #define	LOG_AUTH	0
- #endif	/* LOG_AUTH */
- #ifndef	LOG_ERR
- #define	LOG_ERR		0
- #endif	/* LOG_ERR */
- 
- static const char lspec_parse_err_1[] =	"%s: cannot parse <%s>\n";
- static const char lspec_parse_err_2[] =	"%s: warning - logging entry syntax error\n";
- static const char log_file_err[] =	"%s: error writing to %s\n";
- static const char log_device_err[] =	"%s: error writing to %s device\n";
- static const char log_ufo_string[] =	"???";
- static const char log_emerg_string[] =	"EMERGENCY";
- static const char log_alert_string[] =	"ALERT";
- static const char log_crit_string[] =	"CRITICAL";
- static const char log_err_string[] =	"Error";
- static const char log_warning_string[] =	"Warning";
- static const char log_notice_string[] =	"Notice";
- static const char log_info_string[] =	"info";
- static const char log_debug_string[] =	"debug";
- 
- /*
-  * Output logging.
-  *
-  * Output logging is now controlled by the configuration file.  We can specify
-  * the following syntaxes under the [logging]->entity specification.
-  *	FILE<opentype><pathname>
-  *	SYSLOG[=<severity>[:<facility>]]
-  *	STDERR
-  *	CONSOLE
-  *	DEVICE=<device-spec>
-  *
-  * Where:
-  *	<opentype> is ":" for open/append, "=" for open/create.
-  *	<pathname> is a valid path name.
-  *	<severity> is one of: (default = ERR)
-  *		EMERG
-  *		ALERT
-  *		CRIT
-  *		ERR
-  *		WARNING
-  *		NOTICE
-  *		INFO
-  *		DEBUG
-  *	<facility> is one of: (default = AUTH)
-  *		KERN
-  *		USER
-  *		MAIL
-  *		DAEMON
-  *		AUTH
-  *		LPR
-  *		NEWS
-  *		UUCP
-  *		CRON
-  *		LOCAL0..LOCAL7
-  *	<device-spec> is a valid device specification.
-  */
- struct log_entry {
-     enum log_type { K_LOG_FILE,
- 			K_LOG_SYSLOG,
- 			K_LOG_STDERR,
- 			K_LOG_CONSOLE,
- 			K_LOG_DEVICE,
- 			K_LOG_NONE } log_type;
-     krb5_pointer log_2free;
-     union log_union {
- 	struct log_file {
- 	    FILE	*lf_filep;
- 	    char	*lf_fname;
- 	} log_file;
- 	struct log_syslog {
- 	    int		ls_facility;
- 	    int		ls_severity;
- 	} log_syslog;
- 	struct log_device {
- 	    FILE	*ld_filep;
- 	    char	*ld_devname;
- 	} log_device;
-     } log_union;
- };
- #define	lfu_filep	log_union.log_file.lf_filep
- #define	lfu_fname	log_union.log_file.lf_fname
- #define	lsu_facility	log_union.log_syslog.ls_facility
- #define	lsu_severity	log_union.log_syslog.ls_severity
- #define	ldu_filep	log_union.log_device.ld_filep
- #define	ldu_devname	log_union.log_device.ld_devname
- 
- struct log_control {
-     struct log_entry	*log_entries;
-     int			log_nentries;
-     char		*log_whoami;
-     char		*log_hostname;
-     krb5_boolean	log_opened;
- };
- 
- static struct log_control log_control = {
-     (struct log_entry *) NULL,
-     0,
-     (char *) NULL,
-     (char *) NULL,
-     0
- };
- static struct log_entry	def_log_entry;
- 
- /*
-  * These macros define any special processing that needs to happen for
-  * devices.  For unix, of course, this is hardly anything.
-  */
- #define	DEVICE_OPEN(d, m)	fopen(d, m)
- #define	CONSOLE_OPEN(m)		fopen("/dev/console", m)
- #define	DEVICE_PRINT(f, m)	((fprintf(f, m) >= 0) ? 		\
- 				 (fprintf(f, "\r\n"), fflush(f), 0) :	\
- 				 -1)
- #define	DEVICE_CLOSE(d)		fclose(d)
- 
- 
- /*
-  * klog_com_err_proc()	- Handle com_err(3) messages as specified by the
-  *			  profile.
-  */
- static void
- klog_com_err_proc(whoami, code, format, ap)
-     const char	*whoami;
-     long	code;
-     const char	*format;
-     va_list	ap;
- {
-     char	outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
-     int		lindex;
-     char	*actual_format;
- #if	HAVE_SYSLOG
-     int		log_pri = -1;
- #endif	/* HAVE_SYSLOG */
-     char	*cp;
-     char	*syslogp;
- 
-     /* Make the header */
-     sprintf(outbuf, "%s: ", whoami);
-     /*
-      * Squirrel away address after header for syslog since syslog makes
-      * a header
-      */
-     syslogp = &outbuf[strlen(outbuf)];
- 
-     /* If reporting an error message, separate it. */
-     if (code) {
- 	strcat(outbuf, error_message(code));
- 	strcat(outbuf, " - ");
-     }
-     cp = &outbuf[strlen(outbuf)];
-     
-     actual_format = (char *) format;
- #if	HAVE_SYSLOG
-     /*
-      * This is an unpleasant hack.  If the first character is less than
-      * 8, then we assume that it is a priority.
-      *
-      * Since it is not guaranteed that there is a direct mapping between
-      * syslog priorities (e.g. Ultrix and old BSD), we resort to this
-      * intermediate representation.
-      */
-     if ((((unsigned char) *format) > 0) && (((unsigned char) *format) <= 8)) {
- 	actual_format = (char *) (format + 1);
- 	switch ((unsigned char) *format) {
- #ifdef	LOG_EMERG
- 	case 1:
- 	    log_pri = LOG_EMERG;
- 	    break;
- #endif /* LOG_EMERG */
- #ifdef	LOG_ALERT
- 	case 2:
- 	    log_pri = LOG_ALERT;
- 	    break;
- #endif /* LOG_ALERT */
- #ifdef	LOG_CRIT
- 	case 3:
- 	    log_pri = LOG_CRIT;
- 	    break;
- #endif /* LOG_CRIT */
- 	default:
- 	case 4:
- 	    log_pri = LOG_ERR;
- 	    break;
- #ifdef	LOG_WARNING
- 	case 5:
- 	    log_pri = LOG_WARNING;
- 	    break;
- #endif /* LOG_WARNING */
- #ifdef	LOG_NOTICE
- 	case 6:
- 	    log_pri = LOG_NOTICE;
- 	    break;
- #endif /* LOG_NOTICE */
- #ifdef	LOG_INFO
- 	case 7:
- 	    log_pri = LOG_INFO;
- 	    break;
- #endif /* LOG_INFO */
- #ifdef	LOG_DEBUG
- 	case 8:
- 	    log_pri = LOG_DEBUG;
- 	    break;
- #endif /* LOG_DEBUG */
- 	}
-     } 
- #endif	/* HAVE_SYSLOG */
- 
-     /* Now format the actual message */
- #if	HAVE_VSPRINTF
-     vsprintf(cp, actual_format, ap);
- #else	/* HAVE_VSPRINTF */
-     sprintf(cp, actual_format, ((int *) ap)[0], ((int *) ap)[1],
- 	    ((int *) ap)[2], ((int *) ap)[3],
- 	    ((int *) ap)[4], ((int *) ap)[5]);
- #endif	/* HAVE_VSPRINTF */
-     
-     /*
-      * Now that we have the message formatted, perform the output to each
-      * logging specification.
-      */
-     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
- 	switch (log_control.log_entries[lindex].log_type) {
- 	case K_LOG_FILE:
- 	case K_LOG_STDERR:
- 	    /*
- 	     * Files/standard error.
- 	     */
- 	    if (fprintf(log_control.log_entries[lindex].lfu_filep,
- 			outbuf) < 0) {
- 		/* Attempt to report error */
- 		fprintf(stderr, log_file_err, whoami,
- 			log_control.log_entries[lindex].lfu_fname);
- 	    }
- 	    else {
- 		fprintf(log_control.log_entries[lindex].lfu_filep, "\n");
- 		fflush(log_control.log_entries[lindex].lfu_filep);
- 	    }
- 	    break;
- 	case K_LOG_CONSOLE:
- 	case K_LOG_DEVICE:
- 	    /*
- 	     * Devices (may need special handling)
- 	     */
- 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
- 			     outbuf) < 0) {
- 		/* Attempt to report error */
- 		fprintf(stderr, log_device_err, whoami,
- 			log_control.log_entries[lindex].ldu_devname);
- 	    }
- 	    break;
- #if	HAVE_SYSLOG
- 	case K_LOG_SYSLOG:
- 	    /*
- 	     * System log.
- 	     */
- 	    /*
- 	     * If we have specified a priority through our hackery, then
- 	     * use it, otherwise use the default.
- 	     */
- 	    if (log_pri >= 0)
- 		log_pri |= log_control.log_entries[lindex].lsu_facility;
- 	    else
- 		log_pri = log_control.log_entries[lindex].lsu_facility |
- 		    log_control.log_entries[lindex].lsu_severity;
- 					       
- 	    /* Log the message with our header trimmed off */
- 	    syslog(log_pri, syslogp);
- 	    break;
- #endif /* HAVE_SYSLOG */
- 	default:
- 	    break;
- 	}
-     }
- }
- 
- /*
-  * krb5_klog_init()	- Initialize logging.
-  *
-  * This routine parses the syntax described above to specify destinations for
-  * com_err(3) or krb5_klog_syslog() messages generated by the caller.
-  *
-  * Parameters:
-  *	kcontext	- Kerberos context.
-  *	ename		- Entity name as it is to appear in the profile.
-  *	whoami		- Entity name as it is to appear in error output.
-  *	do_com_err	- Take over com_err(3) processing.
-  *
-  * Implicit inputs:
-  *	stderr		- This is where STDERR output goes.
-  *
-  * Implicit outputs:
-  *	log_nentries	- Number of log entries, both valid and invalid.
-  *	log_control	- List of entries (log_nentries long) which contains
-  *			  data for klog_com_err_proc() to use to determine
-  *			  where/how to send output.
-  */
- krb5_error_code
- krb5_klog_init(kcontext, ename, whoami, do_com_err)
-     krb5_context	kcontext;
-     char		*ename;
-     char		*whoami;
-     krb5_boolean	do_com_err;
- {
-     const char	*logging_profent[3];
-     const char	*logging_defent[3];
-     char	**logging_specs;
-     int		i, ngood;
-     char	*cp, *cp2;
-     char	savec;
-     int		error;
-     int		do_openlog, log_facility;
-     FILE	*f;
- 
-     /* Initialize */
-     do_openlog = 0;
-     log_facility = 0;
- 
-     /*
-      * Look up [logging]-><ename> in the profile.  If that doesn't
-      * succeed, then look for [logging]->default.
-      */
-     logging_profent[0] = "logging";
-     logging_profent[1] = ename;
-     logging_profent[2] = (char *) NULL;
-     logging_defent[0] = "logging";
-     logging_defent[1] = "default";
-     logging_defent[2] = (char *) NULL;
-     logging_specs = (char **) NULL;
-     ngood = 0;
-     log_control.log_nentries = 0;
-     if (!profile_get_values(kcontext->profile,
- 			    logging_profent,
- 			    &logging_specs) ||
- 	!profile_get_values(kcontext->profile,
- 			    logging_defent,
- 			    &logging_specs)) {
- 	/*
- 	 * We have a match, so we first count the number of elements
- 	 */
- 	for (log_control.log_nentries = 0;
- 	     logging_specs[log_control.log_nentries];
- 	     log_control.log_nentries++);
- 
- 	/*
- 	 * Now allocate our structure.
- 	 */
- 	log_control.log_entries = (struct log_entry *)
- 	    malloc(log_control.log_nentries * sizeof(struct log_entry));
- 	if (log_control.log_entries) {
- 	    /*
- 	     * Scan through the list.
- 	     */
- 	    for (i=0; i<log_control.log_nentries; i++) {
- 		log_control.log_entries[i].log_type = K_LOG_NONE;
- 		log_control.log_entries[i].log_2free = logging_specs[i];
- 		/*
- 		 * The format is:
- 		 *	<whitespace><data><whitespace>
- 		 * so, trim off the leading and trailing whitespace here.
- 		 */
- 		for (cp = logging_specs[i]; isspace(*cp); cp++);
- 		for (cp2 = &logging_specs[i][strlen(logging_specs[i])-1];
- 		     isspace(*cp2); cp2--);
- 		cp2++;
- 		*cp2 = '\0';
- 		/*
- 		 * Is this a file?
- 		 */
- 		if (!strncasecmp(cp, "FILE", 4)) {
- 		    /*
- 		     * Check for append/overwrite, then open the file.
- 		     */
- 		    if (cp[4] == ':' || cp[4] == '=') {
- 			f = fopen(&cp[5], (cp[4] == ':') ? "a+" : "w");
- 			if (f) {
- 			    log_control.log_entries[i].lfu_filep = f;
- 			    log_control.log_entries[i].log_type = K_LOG_FILE;
- 			    log_control.log_entries[i].lfu_fname = &cp[5];
- 			} else {
- 			    fprintf(stderr,"Couldn't open log file %s: %s\n",
- 				    &cp[5], error_message(errno));
- 			    continue;
- 			}
- 		    }
- 		}
- #if	HAVE_SYSLOG
- 		/*
- 		 * Is this a syslog?
- 		 */
- 		else if (!strncasecmp(cp, "SYSLOG", 6)) {
- 		    error = 0;
- 		    log_control.log_entries[i].lsu_facility = LOG_AUTH;
- 		    log_control.log_entries[i].lsu_severity = LOG_ERR;
- 		    /*
- 		     * Is there a severify specified?
- 		     */
- 		    if (cp[6] == ':') {
- 			/*
- 			 * Find the end of the severity.
- 			 */
- 			if (cp2 = strchr(&cp[7], ':')) {
- 			    savec = *cp2;
- 			    *cp2 = '\0';
- 			    cp2++;
- 			}
- 
- 			/*
- 			 * Match a severity.
- 			 */
- 			if (!strcasecmp(&cp[7], "ERR")) {
- 			    log_control.log_entries[i].lsu_severity = LOG_ERR;
- 			}
- #ifdef	LOG_EMERG
- 			else if (!strcasecmp(&cp[7], "EMERG")) {
- 			    log_control.log_entries[i].lsu_severity =
- 				LOG_EMERG;
- 			}
- #endif	/* LOG_EMERG */
- #ifdef	LOG_ALERT
- 			else if (!strcasecmp(&cp[7], "ALERT")) {
- 			    log_control.log_entries[i].lsu_severity =
- 				LOG_ALERT;
- 			}
- #endif	/* LOG_ALERT */
- #ifdef	LOG_CRIT
- 			else if (!strcasecmp(&cp[7], "CRIT")) {
- 			    log_control.log_entries[i].lsu_severity = LOG_CRIT;
- 			}
- #endif	/* LOG_CRIT */
- #ifdef	LOG_WARNING
- 			else if (!strcasecmp(&cp[7], "WARNING")) {
- 			    log_control.log_entries[i].lsu_severity =
- 				LOG_WARNING;
- 			}
- #endif	/* LOG_WARNING */
- #ifdef	LOG_NOTICE
- 			else if (!strcasecmp(&cp[7], "NOTICE")) {
- 			    log_control.log_entries[i].lsu_severity =
- 				LOG_NOTICE;
- 			}
- #endif	/* LOG_NOTICE */
- #ifdef	LOG_INFO
- 			else if (!strcasecmp(&cp[7], "INFO")) {
- 			    log_control.log_entries[i].lsu_severity = LOG_INFO;
- 			}
- #endif	/* LOG_INFO */
- #ifdef	LOG_DEBUG
- 			else if (!strcasecmp(&cp[7], "DEBUG")) {
- 			    log_control.log_entries[i].lsu_severity =
- 				LOG_DEBUG;
- 			}
- #endif	/* LOG_DEBUG */
- 			else
- 			    error = 1;
- 
- 			/*
- 			 * If there is a facility present, then parse that.
- 			 */
- 			if (cp2) {
- 			    if (!strcasecmp(cp2, "AUTH")) {
- 				log_control.log_entries[i].lsu_facility = LOG_AUTH;
- 			    }
- #ifdef	LOG_KERN
- 			    else if (!strcasecmp(cp2, "KERN")) {
- 				log_control.log_entries[i].lsu_facility = LOG_KERN;
- 			    }
- #endif	/* LOG_KERN */
- #ifdef	LOG_USER
- 			    else if (!strcasecmp(cp2, "USER")) {
- 				log_control.log_entries[i].lsu_facility = LOG_USER;
- 			    }
- #endif	/* LOG_USER */
- #ifdef	LOG_MAIL
- 			    else if (!strcasecmp(cp2, "MAIL")) {
- 				log_control.log_entries[i].lsu_facility = LOG_MAIL;
- 			    }
- #endif	/* LOG_MAIL */
- #ifdef	LOG_DAEMON
- 			    else if (!strcasecmp(cp2, "DAEMON")) {
- 				log_control.log_entries[i].lsu_facility = LOG_DAEMON;
- 			    }
- #endif	/* LOG_DAEMON */
- #ifdef	LOG_LPR
- 			    else if (!strcasecmp(cp2, "LPR")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LPR;
- 			    }
- #endif	/* LOG_LPR */
- #ifdef	LOG_NEWS
- 			    else if (!strcasecmp(cp2, "NEWS")) {
- 				log_control.log_entries[i].lsu_facility = LOG_NEWS;
- 			    }
- #endif	/* LOG_NEWS */
- #ifdef	LOG_UUCP
- 			    else if (!strcasecmp(cp2, "UUCP")) {
- 				log_control.log_entries[i].lsu_facility = LOG_UUCP;
- 			    }
- #endif	/* LOG_UUCP */
- #ifdef	LOG_CRON
- 			    else if (!strcasecmp(cp2, "CRON")) {
- 				log_control.log_entries[i].lsu_facility = LOG_CRON;
- 			    }
- #endif	/* LOG_CRON */
- #ifdef	LOG_LOCAL0
- 			    else if (!strcasecmp(cp2, "LOCAL0")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL0;
- 			    }
- #endif	/* LOG_LOCAL0 */
- #ifdef	LOG_LOCAL1
- 			    else if (!strcasecmp(cp2, "LOCAL1")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL1;
- 			    }
- #endif	/* LOG_LOCAL1 */
- #ifdef	LOG_LOCAL2
- 			    else if (!strcasecmp(cp2, "LOCAL2")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL2;
- 			    }
- #endif	/* LOG_LOCAL2 */
- #ifdef	LOG_LOCAL3
- 			    else if (!strcasecmp(cp2, "LOCAL3")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL3;
- 			    }
- #endif	/* LOG_LOCAL3 */
- #ifdef	LOG_LOCAL4
- 			    else if (!strcasecmp(cp2, "LOCAL4")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL4;
- 			    }
- #endif	/* LOG_LOCAL4 */
- #ifdef	LOG_LOCAL5
- 			    else if (!strcasecmp(cp2, "LOCAL5")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL5;
- 			    }
- #endif	/* LOG_LOCAL5 */
- #ifdef	LOG_LOCAL6
- 			    else if (!strcasecmp(cp2, "LOCAL6")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL6;
- 			    }
- #endif	/* LOG_LOCAL6 */
- #ifdef	LOG_LOCAL7
- 			    else if (!strcasecmp(cp2, "LOCAL7")) {
- 				log_control.log_entries[i].lsu_facility = LOG_LOCAL7;
- 			    }
- #endif	/* LOG_LOCAL7 */
- 			    cp2--;
- 			    *cp2 = savec;
- 			}
- 		    }
- 		    if (!error) {
- 			log_control.log_entries[i].log_type = K_LOG_SYSLOG;
- 			do_openlog = 1;
- 			log_facility = log_control.log_entries[i].lsu_facility;
- 		    }
- 		}
- #endif	/* HAVE_SYSLOG */
- 		/*
- 		 * Is this a standard error specification?
- 		 */
- 		else if (!strcasecmp(cp, "STDERR")) {
- 		    if (log_control.log_entries[i].lfu_filep =
- 			fdopen(fileno(stderr), "a+")) {
- 			log_control.log_entries[i].log_type = K_LOG_STDERR;
- 			log_control.log_entries[i].lfu_fname =
- 			    "standard error";
- 		    }
- 		}
- 		/*
- 		 * Is this a specification of the console?
- 		 */
- 		else if (!strcasecmp(cp, "CONSOLE")) {
- 		    if (log_control.log_entries[i].ldu_filep =
- 			CONSOLE_OPEN("a+")) {
- 			log_control.log_entries[i].log_type = K_LOG_CONSOLE;
- 			log_control.log_entries[i].ldu_devname = "console";
- 		    }
- 		}
- 		/*
- 		 * Is this a specification of a device?
- 		 */
- 		else if (!strncasecmp(cp, "DEVICE", 6)) {
- 		    /*
- 		     * We handle devices very similarly to files.
- 		     */
- 		    if (cp[6] == '=') {
- 			if (log_control.log_entries[i].ldu_filep =
- 			    DEVICE_OPEN(&cp[7], "w")) {
- 			    log_control.log_entries[i].log_type = K_LOG_DEVICE;
- 			    log_control.log_entries[i].ldu_devname = &cp[7];
- 			}
- 		    }
- 		}
- 		/*
- 		 * See if we successfully parsed this specification.
- 		 */
- 		if (log_control.log_entries[i].log_type == K_LOG_NONE) {
- 		    fprintf(stderr, lspec_parse_err_1, whoami, cp);
- 		    fprintf(stderr, lspec_parse_err_2, whoami);
- 		}
- 		else
- 		    ngood++;
- 	    }
- 	}
- 	/*
- 	 * If we didn't find anything, then free our lists.
- 	 */
- 	if (ngood == 0) {
- 	    for (i=0; i<log_control.log_nentries; i++)
- 		free(logging_specs[i]);
- 	}
- 	free(logging_specs);
-     }
-     /*
-      * If we didn't find anything, go for the default which is to log to
-      * the system log.
-      */
-     if (ngood == 0) {
- 	if (log_control.log_entries)
- 	    free(log_control.log_entries);
- 	log_control.log_entries = &def_log_entry;
- 	log_control.log_entries->log_type = K_LOG_SYSLOG;
- 	log_control.log_entries->log_2free = (krb5_pointer) NULL;
- 	log_control.log_entries->lsu_facility = LOG_AUTH;
- 	log_control.log_entries->lsu_severity = LOG_ERR;
- 	log_control.log_nentries = 1;
-     }
-     if (log_control.log_nentries) {
- 	if (log_control.log_whoami = (char *) malloc(strlen(whoami)+1))
- 	    strcpy(log_control.log_whoami, whoami);
- 	if (log_control.log_hostname = (char *) malloc(MAXHOSTNAMELEN))
- 	    gethostname(log_control.log_hostname, MAXHOSTNAMELEN);
- #if	HAVE_OPENLOG
- 	if (do_openlog) {
- 	    openlog(whoami, LOG_NDELAY|LOG_PID, log_facility);
- 	    log_control.log_opened = 1;
- 	}
- #endif /* HAVE_OPENLOG */
- 	if (do_com_err)
- 	    (void) set_com_err_hook(klog_com_err_proc);
-     }
-     return((log_control.log_nentries) ? 0 : ENOENT);
- }
- 
- /*
-  * krb5_klog_close()	- Close the logging context and free all data.
-  */
- void
- krb5_klog_close(kcontext)
-     krb5_context	kcontext;
- {
-     int lindex;
-     (void) reset_com_err_hook();
-     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
- 	switch (log_control.log_entries[lindex].log_type) {
- 	case K_LOG_FILE:
- 	case K_LOG_STDERR:
- 	    /*
- 	     * Files/standard error.
- 	     */
- 	    fclose(log_control.log_entries[lindex].lfu_filep);
- 	    break;
- 	case K_LOG_CONSOLE:
- 	case K_LOG_DEVICE:
- 	    /*
- 	     * Devices (may need special handling)
- 	     */
- 	    DEVICE_CLOSE(log_control.log_entries[lindex].ldu_filep);
- 	    break;
- #if	HAVE_SYSLOG
- 	case K_LOG_SYSLOG:
- 	    /*
- 	     * System log.
- 	     */
- 	    break;
- #endif	/* HAVE_SYSLOG */
- 	default:
- 	    break;
- 	}
- 	if (log_control.log_entries[lindex].log_2free)
- 	    free(log_control.log_entries[lindex].log_2free);
-     }
-     if (log_control.log_entries != &def_log_entry)
- 	free(log_control.log_entries);
-     log_control.log_entries = (struct log_entry *) NULL;
-     log_control.log_nentries = 0;
-     if (log_control.log_whoami)
- 	free(log_control.log_whoami);
-     log_control.log_whoami = (char *) NULL;
-     if (log_control.log_hostname)
- 	free(log_control.log_hostname);
-     log_control.log_hostname = (char *) NULL;
- #if	HAVE_CLOSELOG
-     if (log_control.log_opened)
- 	closelog();
- #endif	/* HAVE_CLOSELOG */
- }
- 
- /*
-  * severity2string()	- Convert a severity to a string.
-  */
- static char *
- severity2string(severity)
-     int	severity;
- {
-     int s;
-     const char *ss;
- 
-     s = severity & LOG_PRIMASK;
-     ss = log_ufo_string;
-     switch (s) {
- #ifdef	LOG_EMERG
-     case LOG_EMERG:
- 	ss = log_emerg_string;
- 	break;
- #endif	/* LOG_EMERG */
- #ifdef	LOG_ALERT
-     case LOG_ALERT:
- 	ss = log_alert_string;
- 	break;
- #endif	/* LOG_ALERT */
- #ifdef	LOG_CRIT
-     case LOG_CRIT:
- 	ss = log_crit_string;
- 	break;
- #endif	/* LOG_CRIT */
-     case LOG_ERR:
- 	ss = log_err_string;
- 	break;
- #ifdef	LOG_WARNING
-     case LOG_WARNING:
- 	ss = log_warning_string;
- 	break;
- #endif	/* LOG_WARNING */
- #ifdef	LOG_NOTICE
-     case LOG_NOTICE:
- 	ss = log_notice_string;
- 	break;
- #endif	/* LOG_NOTICE */
- #ifdef	LOG_INFO
-     case LOG_INFO:
- 	ss = log_info_string;
- 	break;
- #endif	/* LOG_INFO */
- #ifdef	LOG_DEBUG
-     case LOG_DEBUG:
- 	ss = log_debug_string;
- 	break;
- #endif	/* LOG_DEBUG */
-     }
-     return((char *) ss);
- }
- 
- /*
-  * krb5_klog_syslog()	- Simulate the calling sequence of syslog(3), while
-  *			  also performing the logging redirection as specified
-  *			  by krb5_klog_init().
-  */
- static int
- klog_vsyslog(priority, format, arglist)
-     int		priority;
-     const char	*format;
-     va_list	arglist;
- {
-     char	outbuf[KRB5_KLOG_MAX_ERRMSG_SIZE];
-     int		lindex;
-     char	*syslogp;
-     char	*cp;
-     time_t	now;
- #if	HAVE_STRFTIME
-     size_t	soff;
- #endif	/* HAVE_STRFTIME */
- 
-     /*
-      * Format a syslog-esque message of the format:
-      *
-      * (verbose form)
-      * 		<date> <hostname> <id>[<pid>](<priority>): <message>
-      *
-      * (short form)
-      *		<date> <message>
-      */
-     cp = outbuf;
-     (void) time(&now);
- #if	HAVE_STRFTIME
-     /*
-      * Format the date: mon dd hh:mm:ss
-      */
-     soff = strftime(outbuf, sizeof(outbuf), "%b %d %H:%M:%S", localtime(&now));
-     if (soff > 0)
- 	cp += soff;
-     else
- 	return(-1);
- #else	/* HAVE_STRFTIME */
-     /*
-      * Format the date:
-      * We ASSUME here that the output of ctime is of the format:
-      *	dow mon dd hh:mm:ss tzs yyyy\n
-      *  012345678901234567890123456789
-      */
-     strncpy(outbuf, ctime(&now) + 4, 15);
-     cp += 15;
- #endif	/* HAVE_STRFTIME */
- #ifdef VERBOSE_LOGS
-     sprintf(cp, " %s %s[%d](%s): ", 
- 	    log_control.log_hostname, log_control.log_whoami, getpid(),
- 	    severity2string(priority));
- #else
-     sprintf(cp, " ");
- #endif
-     syslogp = &outbuf[strlen(outbuf)];
- 
-     /* Now format the actual message */
- #if	HAVE_VSPRINTF
-     vsprintf(syslogp, format, arglist);
- #else	/* HAVE_VSPRINTF */
-     sprintf(syslogp, format, ((int *) arglist)[0], ((int *) arglist)[1],
- 	    ((int *) arglist)[2], ((int *) arglist)[3],
- 	    ((int *) arglist)[4], ((int *) arglist)[5]);
- #endif	/* HAVE_VSPRINTF */
- 
-     /*
-      * Now that we have the message formatted, perform the output to each
-      * logging specification.
-      */
-     for (lindex = 0; lindex < log_control.log_nentries; lindex++) {
- 	switch (log_control.log_entries[lindex].log_type) {
- 	case K_LOG_FILE:
- 	case K_LOG_STDERR:
- 	    /*
- 	     * Files/standard error.
- 	     */
- 	    if (fprintf(log_control.log_entries[lindex].lfu_filep, 
- 			outbuf) < 0) {
- 		/* Attempt to report error */
- 		fprintf(stderr, log_file_err,
- 			log_control.log_entries[lindex].lfu_fname);
- 	    }
- 	    else {
- 		fprintf(log_control.log_entries[lindex].lfu_filep, "\n");
- 		fflush(log_control.log_entries[lindex].lfu_filep);
- 	    }
- 	    break;
- 	case K_LOG_CONSOLE:
- 	case K_LOG_DEVICE:
- 	    /*
- 	     * Devices (may need special handling)
- 	     */
- 	    if (DEVICE_PRINT(log_control.log_entries[lindex].ldu_filep,
- 			     outbuf) < 0) {
- 		/* Attempt to report error */
- 		fprintf(stderr, log_device_err,
- 			log_control.log_entries[lindex].ldu_devname);
- 	    }
- 	    break;
- #if	HAVE_SYSLOG
- 	case K_LOG_SYSLOG:
- 	    /*
- 	     * System log.
- 	     */
- 					       
- 	    /* Log the message with our header trimmed off */
- 	    syslog(priority, syslogp);
- 	    break;
- #endif /* HAVE_SYSLOG */
- 	default:
- 	    break;
- 	}
-     }
-     return(0);
- }
- 
- #if	HAVE_STDARG_H
- int
- krb5_klog_syslog(int priority, const char *format, ...)
- #else	/* HAVE_STDARG_H */
- int
- krb5_klog_syslog(priority, format, va_alist)
-     int		priority;
-     const char	*format;
-     va_dcl
- #endif	/* HAVE_STDARG_H */
- {
-     int		retval;
-     va_list	pvar;
- 
- #if	HAVE_STDARG_H
-     va_start(pvar, format);
- #else	/* HAVE_STDARG_H */
-     va_start(pvar);
- #endif	/* HAVE_STDARG_H */
-     retval = klog_vsyslog(priority, format, pvar);
-     va_end(pvar);
-     return(retval);
- }
- #endif /* !defined(_MSDOS) */
--- 0 ----
Index: krb5/lib/kadm/str_conv.c
diff -c krb5/lib/kadm/str_conv.c:1.1.1.1 krb5/lib/kadm/str_conv.c:removed
*** krb5/lib/kadm/str_conv.c:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/str_conv.c	Sun Mar 16 20:22:25 2003
***************
*** 1,221 ****
- /*
-  * lib/kadm/str_conv.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * str_conv.c - Convert between strings and Kerberos internal data.
-  */
- 
- /*
-  * Table of contents:
-  *
-  * String decoding:
-  * ----------------
-  * krb5_string_to_flags()	- Convert string to krb5_flags.
-  *
-  * String encoding:
-  * ----------------
-  * krb5_flags_to_string()	- Convert krb5_flags to string.
-  */
- 
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- /*
-  * Local data structures.
-  */
- struct flags_lookup_entry {
-     krb5_flags		fl_flags;		/* Flag			*/
-     krb5_boolean	fl_sense;		/* Sense of the flag	*/
-     const char *	fl_specifier;		/* How to recognize it	*/
-     const char *	fl_output;		/* How to spit it out	*/
- };
- 
- /*
-  * Local strings
-  */
- 
- /* Keytype strings */
- /* Flags strings */
- static const char flags_pdate_in[]	= "postdateable";
- static const char flags_fwd_in[]	= "forwardable";
- static const char flags_tgtbased_in[]	= "tgt-based";
- static const char flags_renew_in[]	= "renewable";
- static const char flags_proxy_in[]	= "proxiable";
- static const char flags_dup_skey_in[]	= "dup-skey";
- static const char flags_tickets_in[]	= "allow-tickets";
- static const char flags_preauth_in[]	= "preauth";
- static const char flags_hwauth_in[]	= "hwauth";
- static const char flags_pwchange_in[]	= "pwchange";
- static const char flags_service_in[]	= "service";
- static const char flags_pwsvc_in[]	= "pwservice";
- static const char flags_md5_in[]	= "md5";
- static const char flags_pdate_out[]	= "Not Postdateable";
- static const char flags_fwd_out[]	= "Not Forwardable";
- static const char flags_tgtbased_out[]	= "No TGT-based requests";
- static const char flags_renew_out[]	= "Not renewable";
- static const char flags_proxy_out[]	= "Not proxiable";
- static const char flags_dup_skey_out[]	= "No DUP_SKEY requests";
- static const char flags_tickets_out[]	= "All Tickets Disallowed";
- static const char flags_preauth_out[]	= "Preauthorization required";
- static const char flags_hwauth_out[]	= "HW Authorization required";
- static const char flags_pwchange_out[]	= "Password Change required";
- static const char flags_service_out[]	= "Service Disabled";
- static const char flags_pwsvc_out[]	= "Password Changing Service";
- static const char flags_md5_out[]	= "RSA-MD5 supported";
- static const char flags_default_neg[]	= "-";
- static const char flags_default_sep[]	= " ";
- 
- /*
-  * Lookup tables.
-  */
- 
- static const struct flags_lookup_entry flags_table[] = {
- /* flag				sense	input specifier	   output string     */
- /*----------------------------- -------	------------------ ------------------*/
- { KRB5_KDB_DISALLOW_POSTDATED,	0,	flags_pdate_in,	   flags_pdate_out   },
- { KRB5_KDB_DISALLOW_FORWARDABLE,0,	flags_fwd_in,	   flags_fwd_out     },
- { KRB5_KDB_DISALLOW_TGT_BASED,	0,	flags_tgtbased_in, flags_tgtbased_out},
- { KRB5_KDB_DISALLOW_RENEWABLE,	0,	flags_renew_in,	   flags_renew_out   },
- { KRB5_KDB_DISALLOW_PROXIABLE,	0,	flags_proxy_in,	   flags_proxy_out   },
- { KRB5_KDB_DISALLOW_DUP_SKEY,	0,	flags_dup_skey_in, flags_dup_skey_out},
- { KRB5_KDB_DISALLOW_ALL_TIX,	0,	flags_tickets_in,  flags_tickets_out },
- { KRB5_KDB_REQUIRES_PRE_AUTH,	1,	flags_preauth_in,  flags_preauth_out },
- { KRB5_KDB_REQUIRES_HW_AUTH,	1,	flags_hwauth_in,   flags_hwauth_out  },
- { KRB5_KDB_REQUIRES_PWCHANGE,	1,	flags_pwchange_in, flags_pwchange_out},
- { KRB5_KDB_DISALLOW_SVR,	0,	flags_service_in,  flags_service_out },
- { KRB5_KDB_PWCHANGE_SERVICE,	1,	flags_pwsvc_in,	   flags_pwsvc_out   },
- { KRB5_KDB_SUPPORT_DESMD5,	1,	flags_md5_in,	   flags_md5_out     }
- };
- static const int flags_table_nents = sizeof(flags_table)/
- 				     sizeof(flags_table[0]);
- 
- 
- krb5_error_code
- krb5_string_to_flags(string, positive, negative, flagsp)
-     char	* string;
-     const char	* positive;
-     const char	* negative;
-     krb5_flags	* flagsp;
- {
-     int 	i;
-     int 	found;
-     const char	*neg;
-     size_t	nsize, psize;
-     int		cpos;
-     int		sense;
- 
-     found = 0;
-     /* We need to have a way to negate it. */
-     neg = (negative) ? negative : flags_default_neg;
-     nsize = strlen(neg);
-     psize = (positive) ? strlen(positive) : 0;
- 
-     cpos = 0;
-     sense = 1;
-     /* First check for positive or negative sense */
-     if (!strncasecmp(neg, string, nsize)) {
- 	sense = 0;
- 	cpos += (int) nsize;
-     }
-     else if (psize && !strncasecmp(positive, string, psize)) {
- 	cpos += (int) psize;
-     }
- 
-     for (i=0; i<flags_table_nents; i++) {
- 	if (!strcasecmp(&string[cpos], flags_table[i].fl_specifier)) {
- 	    found = 1;
- 	    if (sense == (int) flags_table[i].fl_sense)
- 		*flagsp |= flags_table[i].fl_flags;
- 	    else
- 		*flagsp &= ~flags_table[i].fl_flags;
- 
- 	    break;
- 	}
-     }
-     return((found) ? 0 : EINVAL);
- }
- 
- krb5_error_code
- krb5_flags_to_string(flags, sep, buffer, buflen)
-     krb5_flags	flags;
-     const char	* sep;
-     char	* buffer;
-     size_t	buflen;
- {
-     int			i;
-     krb5_flags		pflags;
-     const char		*sepstring;
-     char		*op;
-     int			initial;
-     krb5_error_code	retval;
- 
-     retval = 0;
-     op = buffer;
-     pflags = 0;
-     initial = 1;
-     sepstring = (sep) ? sep : flags_default_sep;
-     /* Blast through the table matching all we can */
-     for (i=0; i<flags_table_nents; i++) {
- 	if (flags & flags_table[i].fl_flags) {
- 	    /* Found a match, see if it'll fit into the output buffer */
- 	    if ((op+strlen(flags_table[i].fl_output)+strlen(sepstring)) <
- 		(buffer + buflen)) {
- 		if (!initial) {
- 		    strcpy(op, sep);
- 		    op += strlen(sep);
- 		}
- 		initial = 0;
- 		strcpy(op, flags_table[i].fl_output);
- 		op += strlen(flags_table[i].fl_output);
- 	    }
- 	    else {
- 		retval = ENOMEM;
- 		break;
- 	    }
- 	    /* Keep track of what we matched */
- 	    pflags |= flags_table[i].fl_flags;
- 	}
-     }
-     if (!retval) {
- 	/* See if there's any leftovers */
- 	if (flags & ~pflags)
- 	    retval = EINVAL;
- 	else if (initial)
- 	    *buffer = '\0';
-     }
-     return(retval);
- }
- 
- krb5_error_code
- krb5_input_flag_to_string(flag, buffer, buflen)
-     int		flag;
-     char	* buffer;
-     size_t	buflen;
- {
-     if(flag < 0 || flag >= flags_table_nents) return ENOENT; /* End of list */
-     if(strlen(flags_table[flag].fl_specifier) > buflen) return ENOMEM;
-     strcpy(buffer, flags_table[flag].fl_specifier);
-     return  0;
- }
--- 0 ----
Index: krb5/lib/kadm/t_dbentry.c
diff -c krb5/lib/kadm/t_dbentry.c:1.1.1.1 krb5/lib/kadm/t_dbentry.c:removed
*** krb5/lib/kadm/t_dbentry.c:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/t_dbentry.c	Sun Mar 16 20:22:25 2003
***************
*** 1,965 ****
- /*
-  * lib/kadm/t_dbentry.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * t_dbentry.c	- Test function of krb5_adm_{proto_to_dbent,dbent_to_proto}.
-  */
- 
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- #if	HAVE_SRAND48
- #define	SRAND	srand48
- #define	RAND	lrand48
- #define	RAND_TYPE	long
- #endif	/* HAVE_SRAND48 */
- 
- #if	!defined(RAND_TYPE) && defined(HAVE_SRAND)
- #define	SRAND	srand
- #define	RAND	rand
- #define	RAND_TYPE	int
- #endif	/* !defined(RAND_TYPE) && defined(HAVE_SRAND) */
- 
- #if	!defined(RAND_TYPE) && defined(HAVE_SRANDOM)
- #define	SRAND	srandom
- #define	RAND	random
- #define	RAND_TYPE	long
- #endif	/* !defined(RAND_TYPE) && defined(HAVE_SRANDOM) */
- 
- #if	!defined(RAND_TYPE)
- There is no random number generator.
- #endif	/* !defined(RAND_TYPE) */
- 
- /*
-  * Generate a random event that has an a/b chance of succeeding
-  */
- #define	RANDOM_EVENT(a,b)	((RAND() % b) < a)
- /* Define probabilities of generating each attribute type */
- #define	PASSWORD_EVENT		RANDOM_EVENT(3,5)
- #define	KVNO_EVENT		RANDOM_EVENT(2,5)
- #define	MAXLIFE_EVENT		RANDOM_EVENT(1,4)
- #define	MAXRENEWLIFE_EVENT	RANDOM_EVENT(1,4)
- #define	EXPIRATION_EVENT	RANDOM_EVENT(1,3)
- #define	PWEXPIRATION_EVENT	RANDOM_EVENT(1,3)
- #define	RANDOMKEY_EVENT		RANDOM_EVENT(1,8)
- #define	FLAGS_EVENT		RANDOM_EVENT(9,10)
- #define	SALT_EVENT		RANDOM_EVENT(7,16)
- #define	MKVNO_EVENT		RANDOM_EVENT(2,5)
- #define	LASTPWCHANGE_EVENT	RANDOM_EVENT(2,5)
- #define	LASTSUCCESS_EVENT	RANDOM_EVENT(2,5)
- #define	LASTFAILED_EVENT	RANDOM_EVENT(2,5)
- #define	FAILCOUNT_EVENT		RANDOM_EVENT(2,5)
- #define	MODNAME_EVENT		RANDOM_EVENT(2,5)
- #define	MODDATE_EVENT		RANDOM_EVENT(2,5)
- #define	EXTRA_EVENT		RANDOM_EVENT(1,5)
- #define	SET_EVENT		RANDOM_EVENT(1,4)
- 
- /*
-  * Convert a time value to a string for output messages.
-  */
- static char *
- time2string(ts)
-     krb5_timestamp	ts;
- {
-     static char buf[1024];
- 
-     strcpy(buf, ctime((time_t *) &ts));
-     /* Remove trailing \n */
-     buf[strlen(buf)-1] = '\0';
-     return(buf);
- }
- 
- static krb5_boolean
- aux_data_inequal(in, out)
-     krb5_db_entry	*in, *out;
- {
-     krb5_tl_data	*intl, *outtl;
-     krb5_boolean	found;
- 
-     if (in->n_tl_data != out->n_tl_data)
- 	return(1);
-     found = 1;
-     for (intl = in->tl_data; intl; intl = intl->tl_data_next) {
- 	found = 0;
- 	for (outtl = out->tl_data; outtl; outtl = outtl->tl_data_next) {
- 	    if ((intl->tl_data_type == outtl->tl_data_type) &&
- 		(intl->tl_data_length == outtl->tl_data_length) &&
- 		!memcmp(intl->tl_data_contents,
- 			outtl->tl_data_contents,
- 			intl->tl_data_length)) {
- 		outtl->tl_data_length = -outtl->tl_data_length;
- 		found = 1;
- 	    }
- 	}
- 	if (!found)
- 	    break;
-     }
-     for (outtl = out->tl_data; outtl; outtl = outtl->tl_data_next) {
- 	if (outtl->tl_data_length < 0)
- 	    outtl->tl_data_length = -outtl->tl_data_length;
-     }
-     return(!found);
- }
- 
- static void
- print_auxdata(entp)
-     krb5_db_entry	*entp;
- {
-     krb5_tl_data	*tl;
-     int			i;
- 
-     for (tl = entp->tl_data; tl; tl = tl->tl_data_next) {
- 	printf("tl_data(%d)[len=%d] ", tl->tl_data_type, tl->tl_data_length);
- 	for (i=0; i<tl->tl_data_length; i++)
- 	    printf("%02x ", tl->tl_data_contents[i]);
- 	printf("\n");
-     }
- }
- 
- static krb5_boolean
- key_data_inequal(in, out)
-     krb5_db_entry	*in, *out;
- {
-     krb5_boolean	found;
-     int 		i, j;
- 
-     if (in->n_key_data != out->n_key_data)
- 	return(1);
-     found = 1;
-     for (i=0; i<in->n_key_data; i++) {
- 	found = 0;
- 	for (j=0; j<out->n_key_data; j++) {
- 	    if ((in->key_data[i].key_data_kvno ==
- 		 out->key_data[j].key_data_kvno) &&
- 		(in->key_data[i].key_data_type[0] ==
- 		 out->key_data[j].key_data_type[0]) &&
- 		(in->key_data[i].key_data_type[1] ==
- 		 out->key_data[j].key_data_type[1]) &&
- 		(in->key_data[i].key_data_length[0] ==
- 		 out->key_data[j].key_data_length[0]) &&
- 		(in->key_data[i].key_data_length[1] ==
- 		 out->key_data[j].key_data_length[1]) &&
- 		!memcmp(in->key_data[i].key_data_contents[0],
- 			out->key_data[j].key_data_contents[0],
- 			in->key_data[i].key_data_length[0]) &&
- 		(!in->key_data[i].key_data_length[1] ||
- 		 !memcmp(in->key_data[i].key_data_contents[1],
- 			out->key_data[j].key_data_contents[1],
- 			in->key_data[i].key_data_length[1]))) {
- 		out->key_data[j].key_data_length[0] = 
- 		    -out->key_data[j].key_data_length[0];
- 		found = 1;
- 	    }
- 	}
- 	if (!found)
- 	    break;
-     }
-     for (j=0; j<out->n_key_data; j++) {
- 	if (out->key_data[j].key_data_length[0] < 0)
- 	    out->key_data[j].key_data_length[0] = 
- 		-out->key_data[j].key_data_length[0];
-     }
-     return(!found);
- }
- 
- static void
- print_keydata(entp)
-     krb5_db_entry	*entp;
- {
-     int			i, j;
- 
-     for (j=0; j<entp->n_key_data; j++) {
- 	printf("key(vno=%d):key(type=%d)[contents= ",
- 	       entp->key_data[j].key_data_kvno,
- 	       entp->key_data[j].key_data_type[0]);
- 	for (i=0; i<entp->key_data[j].key_data_length[0]; i++)
- 	    printf("%02x ", entp->key_data[j].key_data_contents[0][i]);
- 	printf("] salt(type=%d)", entp->key_data[j].key_data_type[1]);
- 	if (entp->key_data[j].key_data_length[1]) {
- 	    printf("[contents= ");
- 	    for (i=0; i<entp->key_data[j].key_data_length[1]; i++)
- 		printf("%02x ", entp->key_data[j].key_data_contents[1][i]);
- 	    printf("]");
- 	}
- 	printf("\n");
-     }
- }
- 
- static krb5_boolean
- extra_data_inequal(in, out)
-     krb5_db_entry	*in, *out;
- {
-     if (in->e_length != out->e_length)
- 	return(1);
-     if (in->e_length && memcmp(in->e_data, out->e_data, (size_t) in->e_length))
- 	return(1);
-     return(0);
- }
- 
- static void
- print_extradata(entp)
-     krb5_db_entry	*entp;
- {
-     int i;
- 
-     printf("extra:");
-     for (i=0; i<entp->e_length; i++)
- 	printf("%02x ", entp->e_data[i]);
-     printf("\n");
- }
- 
- /*
-  * Generate a database entry, either randomly, or using well known values.
-  */
- static void
- gen_dbent(kcontext, dbentp, isrand, validp, pwdp, expectp)
-     krb5_context	kcontext;
-     krb5_db_entry	*dbentp;
-     krb5_boolean	isrand;
-     krb5_ui_4		*validp;
-     char		**pwdp;
-     krb5_boolean	*expectp;
- {
-     time_t		now;
-     krb5_boolean	is_set;
-     size_t		pwlen;
-     int			i;
-     static char		*defpass = "testpassword";
-     static char		*defprinc = "testprinc/instance@realm";
- 
-     now = time((time_t *) NULL);
-     is_set = ((*validp & KRB5_ADM_M_SET) != 0);
- 
-     /* Do password on set */
-     if (isrand) {
- 	if (PASSWORD_EVENT) {
- 	    pwlen = 9 + (RAND() % 56);
- 	    *pwdp = (char *) malloc(pwlen);
- 	    for (i=0; i<pwlen-1; i++) {
- 		(*pwdp)[i] = RAND() % 128;
- 		while (!isalnum((int) (*pwdp)[i]))
- 		    (*pwdp)[i] = RAND() % 128;
- 	    }
- 	    (*pwdp)[pwlen-1] = '\0';
- 	    *validp |= KRB5_ADM_M_PASSWORD;
- 	}
-     }
-     else {
- 	if (is_set) {
- 	    *pwdp = (char *) malloc(strlen(defpass)+1);
- 	    strcpy(*pwdp, defpass);
- 	    *validp |= KRB5_ADM_M_PASSWORD;
- 	}
-     }
- 
-     /* Do maxlife */
-     if (isrand) {
- 	if (MAXLIFE_EVENT) {
- 	    dbentp->max_life = RAND();
- 	    *validp |= KRB5_ADM_M_MAXLIFE;
- 	}
-     }
-     else {
- 	dbentp->max_life = KRB5_KDB_MAX_LIFE;
- 	*validp |= KRB5_ADM_M_MAXLIFE;
-     }
- 
-     /* Do maxrenewlife */
-     if (isrand) {
- 	if (MAXRENEWLIFE_EVENT) {
- 	    dbentp->max_renewable_life = RAND();
- 	    *validp |= KRB5_ADM_M_MAXRENEWLIFE;
- 	}
-     }
-     else {
- 	dbentp->max_renewable_life = KRB5_KDB_MAX_RLIFE;
- 	*validp |= KRB5_ADM_M_MAXRENEWLIFE;
-     }
- 
-     /* Do expiration */
-     if (isrand) {
- 	if (EXPIRATION_EVENT) {
- 	    dbentp->expiration = RAND();
- 	    *validp |= KRB5_ADM_M_EXPIRATION;
- 	}
-     }
-     else {
- 	dbentp->expiration = KRB5_KDB_EXPIRATION;
- 	*validp |= KRB5_ADM_M_EXPIRATION;
-     }
- 
-     /* Do pw_expiration */
-     if (isrand) {
- 	if (PWEXPIRATION_EVENT) {
- 	    dbentp->pw_expiration = RAND();
- 	    *validp |= KRB5_ADM_M_PWEXPIRATION;
- 	}
-     }
-     else {
- 	dbentp->pw_expiration = (krb5_timestamp) now + 3600;
- 	*validp |= KRB5_ADM_M_PWEXPIRATION;
-     }
- 
-     /* Do randomkey - 1/8 probability of doing randomkey */
-     if (isrand && (RANDOMKEY_EVENT)) {
- 	*validp |= KRB5_ADM_M_RANDOMKEY;
-     }
- 
-     /* Do flags */
-     if (isrand) {
- 	if (FLAGS_EVENT) {
- 	    dbentp->attributes = RAND();
- 	    *validp |= KRB5_ADM_M_FLAGS;
- 	}
-     }
-     else {
- 	dbentp->attributes = KRB5_KDB_DEF_FLAGS;
- 	*validp |= KRB5_ADM_M_FLAGS;
-     }
- 
-     /* Do lastsuccess */
-     if (isrand) {
- 	if (LASTSUCCESS_EVENT) {
- 	    dbentp->last_success = RAND();
- 	    *validp |= KRB5_ADM_M_LASTSUCCESS;
- 	}
-     }
-     else {
- 	if (!is_set) {
- 	    dbentp->last_success = (krb5_timestamp) now - 3600;
- 	    *validp |= KRB5_ADM_M_LASTSUCCESS;
- 	}
-     }
- 
-     /* Do lastfailed */
-     if (isrand) {
- 	if (LASTFAILED_EVENT) {
- 	    dbentp->last_failed = RAND();
- 	    *validp |= KRB5_ADM_M_LASTFAILED;
- 	}
-     }
-     else {
- 	if (!is_set) {
- 	    dbentp->last_failed = (krb5_timestamp) now - 3600;
- 	    *validp |= KRB5_ADM_M_LASTFAILED;
- 	}
-     }
- 
-     /* Do failcount */
-     if (isrand) {
- 	if (FAILCOUNT_EVENT) {
- 	    dbentp->fail_auth_count = RAND();
- 	    *validp |= KRB5_ADM_M_FAILCOUNT;
- 	}
-     }
-     else {
- 	if (!is_set) {
- 	    dbentp->fail_auth_count = 0;
- 	    *validp |= KRB5_ADM_M_FAILCOUNT;
- 	}
-     }
- 
-     /*
-      * Generate auxiliary data.
-      */
-     if (isrand) {
- 	krb5_octet *lpw_change;
- 	krb5_tl_data *tldata;
- 	krb5_timestamp lpw;
- 	krb5_tl_mod_princ mprinc;
- 	int	didone;
- 
- 	didone = 0;
- 	if (LASTPWCHANGE_EVENT) {
- 	    if ((tldata = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) &&
- 		(lpw_change = (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
- 		lpw = (krb5_timestamp) RAND();
- 		lpw_change[0] = (unsigned char) ((lpw >> 24) & 0xff);
- 		lpw_change[1] = (unsigned char) ((lpw >> 16) & 0xff);
- 		lpw_change[2] = (unsigned char) ((lpw >> 8) & 0xff);
- 		lpw_change[3] = (unsigned char) (lpw & 0xff);
- 		tldata->tl_data_next = (krb5_tl_data *) NULL;
- 		tldata->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
- 		tldata->tl_data_length = sizeof(krb5_timestamp);
- 		tldata->tl_data_contents = lpw_change;
- 		dbentp->n_tl_data = 1;
- 		dbentp->tl_data = tldata;
- 		didone++;
- 	    }
- 	}
- 	if (MODNAME_EVENT || MODDATE_EVENT) {
- 	    mprinc.mod_date = (krb5_timestamp) RAND();
- 	    if (!krb5_parse_name(kcontext, defprinc, &mprinc.mod_princ)) {
- 		if (!krb5_dbe_encode_mod_princ_data(kcontext, &mprinc, dbentp))
- 		    didone++;
- 	    }
- 	}
- 	if (didone)
- 	    *validp |= KRB5_ADM_M_AUXDATA;
-     }
-     else {
- 	krb5_octet *lpw_change;
- 	krb5_tl_data *tldata;
- 	krb5_timestamp lpw;
- 	krb5_tl_mod_princ mprinc;
- 
- 	if ((tldata = (krb5_tl_data *) malloc(sizeof(krb5_tl_data))) &&
- 	    (lpw_change = (krb5_octet *) malloc(sizeof(krb5_timestamp)))) {
- 	    lpw = (krb5_timestamp) now - 3600;
- 	    lpw_change[0] = (unsigned char) ((lpw >> 24) & 0xff);
- 	    lpw_change[1] = (unsigned char) ((lpw >> 16) & 0xff);
- 	    lpw_change[2] = (unsigned char) ((lpw >> 8) & 0xff);
- 	    lpw_change[3] = (unsigned char) (lpw & 0xff);
- 	    tldata->tl_data_next = (krb5_tl_data *) NULL;
- 	    tldata->tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
- 	    tldata->tl_data_length = sizeof(krb5_timestamp);
- 	    tldata->tl_data_contents = lpw_change;
- 	    dbentp->n_tl_data = 1;
- 	    dbentp->tl_data = tldata;
- 	}
- 	mprinc.mod_date = (krb5_timestamp) now;
- 	if (!krb5_parse_name(kcontext, defprinc, &mprinc.mod_princ))
- 	    krb5_dbe_encode_mod_princ_data(kcontext, &mprinc, dbentp);
- 	*validp |= KRB5_ADM_M_AUXDATA;
-     }
- 
-     /* Make key data */
-     if (isrand) {
- 	int i, j, kl, sl;
- 
- 	if (!is_set) {
- 	    for (i=0; i<(1+(RAND()%8)); i++) {
- 		if (!krb5_dbe_create_key_data(kcontext, dbentp)) {
- 		    dbentp->key_data[i].key_data_kvno = RAND() % 32768;
- 		    dbentp->key_data[i].key_data_type[0] = RAND() % 32768;
- 		    dbentp->key_data[i].key_data_type[1] = RAND() % 32768;
- 		    kl = dbentp->key_data[i].key_data_length[0] =
- 			8 + (RAND() % 128);
- 		    sl = dbentp->key_data[i].key_data_length[1] =
- 			0 + (RAND() % 128);
- 		    if (dbentp->key_data[i].key_data_contents[0] =
- 			(krb5_octet *) malloc(kl)) {
- 			for (j=0; j<kl; j++) {
- 			    dbentp->key_data[i].key_data_contents[0][j] =
- 				RAND() % 256;
- 			}
- 		    }
- 		    if (dbentp->key_data[i].key_data_contents[1] =
- 			(krb5_octet *) malloc(sl)) {
- 			for (j=0; j<sl; j++) {
- 			    dbentp->key_data[i].key_data_contents[1][j] =
- 				RAND() % 256;
- 			}
- 		    }
- 		    *validp |= KRB5_ADM_M_KEYDATA;
- 		}
- 	    }
- 	}
-     }
-     else {
- 	if (!is_set) {
- 	    if (!krb5_dbe_create_key_data(kcontext, dbentp)) {
- 		int i;
- 
- 		dbentp->key_data[0].key_data_kvno = 1;
- 		dbentp->key_data[0].key_data_type[0] = 1;
- 		dbentp->key_data[0].key_data_type[1] = 0;
- 		dbentp->key_data[0].key_data_length[0] = 24;
- 		dbentp->key_data[0].key_data_length[1] = 0;
- 		if (dbentp->key_data[0].key_data_contents[0] =
- 		    (krb5_octet *) malloc(24)) {
- 		    for (i=0; i<24; i++)
- 			dbentp->key_data[0].key_data_contents[0][i] = RAND() % 256;
- 		}
- 		dbentp->key_data[0].key_data_contents[1] = (krb5_octet *) NULL;
- 		*validp |= KRB5_ADM_M_KEYDATA;
- 	    }
- 	}
-     }
- 
-     /* Make extra data */
-     if (isrand && EXTRA_EVENT) {
- 	dbentp->e_length = 8 + (RAND() % 504);
- 	if (dbentp->e_data = (krb5_octet *)
- 	    malloc((size_t) dbentp->e_length)) {
- 	    int j;
- 	    for (j=0; j<dbentp->e_length; j++) {
- 		dbentp->e_data[j] = RAND() % 256;
- 	    }
- 	    *validp |= KRB5_ADM_M_EXTRADATA;
- 	}
- 	else
- 	    dbentp->e_length = 0;
-     }
- 
-     if (is_set) {
- 	/* Only 25% may fail at most */
- 	if (isrand && ((RAND() % 100) < 75)) {
- 	    *validp &= KRB5_ADM_M_SET_VALID;
- 	}
- #ifdef	notdef
- 	if ((*validp & KRB5_ADM_M_PASSWORD) != 0)
- 	    *validp &= ~KRB5_ADM_M_RANDOMKEY;
- #endif	/* notdef */
- 	*expectp = ((*validp & ~KRB5_ADM_M_SET_VALID) != 0) ? 1 : 0;
-     }
-     else {
- 	/* Only 25% may fail at most */
- 	if (isrand && ((RAND() % 100) < 75))
- 	    *validp &= KRB5_ADM_M_GET_VALID;
- 	*expectp = ((*validp & ~KRB5_ADM_M_GET_VALID) != 0) ? 1 : 0;
-     }
- }
- 
- /*
-  * Compare two entries.
-  */
- static krb5_boolean
- compare_entries(kcontext, ivalid, ientp, ipwd, ovalid, oentp, opwd)
-     krb5_context	kcontext;
-     krb5_ui_4		ivalid;
-     krb5_db_entry	*ientp;
-     char		*ipwd;
-     krb5_ui_4		ovalid;
-     krb5_db_entry	*oentp;
-     char		*opwd;
- {
-     /* Handle/compare password */
-     if (((ivalid & KRB5_ADM_M_PASSWORD) != 0) &&
- 	(((ovalid & KRB5_ADM_M_PASSWORD) == 0) ||
- 	 strcmp(ipwd, opwd)))
- 	    return(0);
- 
-     /* Handle/compare maxlife */
-     if (((ivalid & KRB5_ADM_M_MAXLIFE) != 0) &&
- 	(((ovalid & KRB5_ADM_M_MAXLIFE) == 0) ||
- 	 (ientp->max_life != oentp->max_life)))
- 	return(0);
- 
-     /* Handle/compare maxrenewlife */
-     if (((ivalid & KRB5_ADM_M_MAXRENEWLIFE) != 0) &&
- 	(((ovalid & KRB5_ADM_M_MAXRENEWLIFE) == 0) ||
- 	 (ientp->max_renewable_life != oentp->max_renewable_life)))
- 	return(0);
- 
-     /* Handle/compare expiration */
-     if (((ivalid & KRB5_ADM_M_EXPIRATION) != 0) &&
- 	(((ovalid & KRB5_ADM_M_EXPIRATION) == 0) ||
- 	 (ientp->expiration != oentp->expiration)))
- 	return(0);
- 
-     /* Handle/compare pwexpiration */
-     if (((ivalid & KRB5_ADM_M_PWEXPIRATION) != 0) &&
- 	(((ovalid & KRB5_ADM_M_PWEXPIRATION) == 0) ||
- 	 (ientp->pw_expiration != oentp->pw_expiration)))
- 	return(0);
- 
- #ifdef	notdef
-     /* Handle/compare random key */
-     if (((ivalid & KRB5_ADM_M_RANDOMKEY) != 0) &&
- 	((ovalid & KRB5_ADM_M_PASSWORD) != 0))
- 	return(0);
- #endif	/* notdef */
- 
-     /* Handle/compare flags */
-     if (((ivalid & KRB5_ADM_M_FLAGS) != 0) &&
- 	(((ovalid & KRB5_ADM_M_FLAGS) == 0) ||
- 	 (ientp->attributes != oentp->attributes)))
- 	return(0);
- 
-     /* Handle/compare lastsuccess */
-     if (((ivalid & KRB5_ADM_M_LASTSUCCESS) != 0) &&
- 	(((ovalid & KRB5_ADM_M_LASTSUCCESS) == 0) ||
- 	 (ientp->last_success != oentp->last_success)))
- 	return(0);
- 
-     /* Handle/compare lastfailed */
-     if (((ivalid & KRB5_ADM_M_LASTFAILED) != 0) &&
- 	(((ovalid & KRB5_ADM_M_LASTFAILED) == 0) ||
- 	 (ientp->last_failed != oentp->last_failed)))
- 	return(0);
- 
-     /* Handle/compare failcount */
-     if (((ivalid & KRB5_ADM_M_FAILCOUNT) != 0) &&
- 	(((ovalid & KRB5_ADM_M_FAILCOUNT) == 0) ||
- 	 (ientp->fail_auth_count != oentp->fail_auth_count)))
- 	return(0);
- 
-     /* Handle/compare auxiliary data */
-     if (((ivalid & KRB5_ADM_M_AUXDATA) != 0) &&
- 	(((ovalid & KRB5_ADM_M_AUXDATA) == 0) ||
- 	 aux_data_inequal(ientp, oentp)))
- 	return(0);
- 
-     /* Handle/compare key data */
-     if (((ivalid & KRB5_ADM_M_KEYDATA) != 0) &&
- 	(((ovalid & KRB5_ADM_M_KEYDATA) == 0) ||
- 	 key_data_inequal(ientp, oentp)))
- 	return(0);
- 
-     /* Handle/compare extra data */
-     if (((ivalid & KRB5_ADM_M_EXTRADATA) != 0) &&
- 	(((ovalid & KRB5_ADM_M_EXTRADATA) == 0) ||
- 	 extra_data_inequal(ientp, oentp)))
- 	return(0);
- 
-     return(1);
- }
- 
- /*
-  * Print out an entry.
-  */
- static void
- print_dbent(kcontext, ivalid, ientp, ipwd)
-     krb5_context	kcontext;
-     krb5_ui_4		ivalid;
-     krb5_db_entry	*ientp;
-     char		*ipwd;
- {
-     printf("Valid mask:\t%08x\n", ivalid);
- 
-     /* Print password */
-     if ((ivalid & KRB5_ADM_M_PASSWORD) != 0)
- 	printf("Password:\t%s\n", ipwd);
- 
-     /* Print maxlife */
-     if ((ivalid & KRB5_ADM_M_MAXLIFE) != 0)
- 	printf("max_life:\t%8d\t%08x\n", ientp->max_life, ientp->max_life);
- 
-     /* Print maxrenewlife */
-     if ((ivalid & KRB5_ADM_M_MAXRENEWLIFE) != 0)
- 	printf("max_rlife:\t%8d\t%08x\n", ientp->max_renewable_life,
- 	       ientp->max_renewable_life);
- 
-     /* Print expiration */
-     if ((ivalid & KRB5_ADM_M_EXPIRATION) != 0)
- 	printf("expires:\t%8d\t%08x\t%s\n", ientp->expiration,
- 	       ientp->expiration, time2string(ientp->expiration));
- 
-     /* Print pwexpiration */
-     if ((ivalid & KRB5_ADM_M_PWEXPIRATION) != 0)
- 	printf("pw expires:\t%8d\t%08x\t%s\n", ientp->pw_expiration,
- 	       ientp->pw_expiration, time2string(ientp->pw_expiration));
- 
-     /* Print random key */
-     if ((ivalid & KRB5_ADM_M_RANDOMKEY) != 0)
- 	printf("random key\n");
- 
-     /* Print flags */
-     if ((ivalid & KRB5_ADM_M_FLAGS) != 0)
- 	printf("flags:\t\t%8d\t%08x\n", ientp->attributes, ientp->attributes);
- 
-     /* Print lastsuccess */
-     if ((ivalid & KRB5_ADM_M_LASTSUCCESS) != 0)
- 	printf("lastsucc:\t%8d\t%08x\t%s\n", ientp->last_success,
- 	       ientp->last_success, time2string(ientp->last_success));
- 
-     /* Print lastfailed */
-     if ((ivalid & KRB5_ADM_M_LASTFAILED) != 0)
- 	printf("lastfail:\t%8d\t%08x\t%s\n", ientp->last_failed,
- 	       ientp->last_failed, time2string(ientp->last_failed));
- 
-     /* Print failcount */
-     if ((ivalid & KRB5_ADM_M_FAILCOUNT) != 0)
- 	printf("failcount:\t%8d\t%08x\n", ientp->fail_auth_count,
- 	       ientp->fail_auth_count);
- 
-     /* Print auxiliary data */
-     if ((ivalid & KRB5_ADM_M_AUXDATA) != 0)
- 	print_auxdata(ientp);
- 
-     /* Print key data */
-     if ((ivalid & KRB5_ADM_M_KEYDATA) != 0)
- 	print_keydata(ientp);
- 
-     /* Print extra data */
-     if ((ivalid & KRB5_ADM_M_EXTRADATA) != 0)
- 	print_extradata(ientp);
- }
- 
- /*
-  * Do a test case.
-  *
-  * Strategy: Generate the desired database entry type, then convert it using
-  *	krb5_adm_dbent_to_proto, then convert it back to a database entry
-  *	using krb5_adm_proto_to_dbent.  Then verify the match.
-  */
- static krb5_int32
- do_test(pname, verbose, isrand, is_a_set, title, passno)
-     char		*pname;
-     krb5_boolean	verbose;
-     krb5_boolean	isrand;
-     krb5_boolean	is_a_set;
-     char		*title;
-     krb5_int32		passno;
- {
-     krb5_context	kcontext;
-     krb5_db_entry	*in_dbent;
-     krb5_db_entry	*out_dbent;
-     krb5_error_code	kret;
-     krb5_int32		ncomps;
-     krb5_data		*complist;
-     krb5_ui_4		in_validmask;
-     krb5_ui_4		out_validmask;
-     char		*in_password;
-     char		*out_password;
-     krb5_boolean	should_fail;
- 
-     if (verbose) {
- 	printf("* Begin %s", title);
- 	if (isrand)
- 	    printf(" pass %d", passno);
- 	printf("\n");
-     }
- 
-     kret = 0;
-     krb5_init_context(&kcontext);
-     krb5_init_ets(kcontext);
-     in_dbent = (krb5_db_entry *) malloc(sizeof(krb5_db_entry));
-     out_dbent = (krb5_db_entry *) malloc(sizeof(krb5_db_entry));
-     if (in_dbent && out_dbent) {
- 	/* Initialize our data */
- 	memset((char *) in_dbent, 0, sizeof(krb5_db_entry));
- 	memset((char *) out_dbent, 0, sizeof(krb5_db_entry));
- 	in_password = out_password = (char *) NULL;
- 	out_validmask = 0;
- 	ncomps = 0;
- 	complist = (krb5_data *) NULL;
- 	should_fail = 0;
- 	if (!isrand) {
- 	    if (is_a_set)
- 		in_validmask = KRB5_ADM_M_SET;
- 	    else
- 		in_validmask = KRB5_ADM_M_GET;
- 	}
- 	else {
- 	    if (SET_EVENT)
- 		in_validmask = KRB5_ADM_M_SET;
- 	    else
- 		in_validmask = KRB5_ADM_M_GET;
- 	}
- 
- 	/* Generate the database entry. */
- 	gen_dbent(kcontext,
- 		  in_dbent, isrand, &in_validmask, &in_password, &should_fail);
- 
- 	/* Convert it to the o-t-w protocol */
- 	if (!(kret = krb5_adm_dbent_to_proto(kcontext,
- 					     in_validmask,
- 					     in_dbent,
- 					     in_password,
- 					     &ncomps,
- 					     &complist))) {
- 	    /* If this should fail, then we've got a problem here */
- 	    if (!should_fail) {
- 
- 		/* Otherwise, convert it back to a database entry */
- 		if (!(kret = krb5_adm_proto_to_dbent(kcontext,
- 						     ncomps,
- 						     complist,
- 						     &out_validmask,
- 						     out_dbent,
- 						     &out_password))) {
- 		    /* Compare the entries */
- 		    if (compare_entries(kcontext,
- 					in_validmask,
- 					in_dbent,
- 					in_password,
- 					out_validmask,
- 					out_dbent,
- 					out_password)) {
- 			/* Success */
- 			if (verbose) {
- 			    printf("Successful translation");
- 			    printf(" during %s", title);
- 			    if (isrand)
- 				printf(" pass %d", passno);
- 			    printf(" of:\n");
- 			    print_dbent(kcontext,
- 					in_validmask, in_dbent, in_password);
- 			}
- 		    }
- 		    else {
- 			/* Failed */
- 			fprintf(stderr, "%s: comparison mismatch", pname);
- 			fprintf(stderr, " during %s", title);
- 			if (isrand)
- 			    fprintf(stderr, " pass %d", passno);
- 			fprintf(stderr, "\n");
- 			if (verbose) {
- 			    printf("Input entry is as follows:\n");
- 			    print_dbent(kcontext,
- 					in_validmask, in_dbent, in_password);
- 			    printf("Output entry is as follows:\n");
- 			    print_dbent(kcontext,
- 					out_validmask,
- 					out_dbent,
- 					out_password);
- 			}
- 			kret = KRB5KRB_ERR_GENERIC;
- 		    }
- 		    if (out_password)
- 			krb5_xfree(out_password);
- 		}
- 		else {
- 		    /* Conversion to database entry failed */
- 		    fprintf(stderr, "%s: protocol decode failed with %d",
- 			pname, kret);
- 		    fprintf(stderr, " during %s", title);
- 		    if (isrand)
- 			fprintf(stderr, " pass %d", passno);
- 		    fprintf(stderr, "\n");
- 		}
- 	    }
- 	    else {
- 		/* Should have failed */
- 		fprintf(stderr, "%s: protocol encode unexpectedly succeeded",
- 			pname);
- 		kret = KRB5KRB_ERR_GENERIC;
- 		fprintf(stderr, " during %s", title);
- 		if (isrand)
- 		    fprintf(stderr, " pass %d", passno);
- 		fprintf(stderr, "\n");
- 	    }
- 	    krb5_free_adm_data(kcontext, ncomps, complist);
- 	}
- 	else {
- 	    /* Convert to protocol failed */
- 	    if (!should_fail) {
- 		/* Unexpected failure */
- 		fprintf(stderr, "%s: protocol encode failed with %d",
- 			pname, kret);
- 		fprintf(stderr, " during %s", title);
- 		if (isrand)
- 		    fprintf(stderr, " pass %d", passno);
- 		fprintf(stderr, "\n");
- 	    }
- 	    else {
- 		/* Success */
- 		if (verbose)
- 		    printf("- Expected failure OK\n");
- 		kret = 0;
- 	    }
- 	}
- 	/* Cleanup */
- 	if (in_password)
- 	    free(in_password);
- 	if (in_dbent->tl_data) {
- 	    krb5_tl_data *xxx, *xxx1;
- 
- 	    for (xxx=in_dbent->tl_data; xxx; ) {
- 		xxx1 = xxx;
- 		xxx = xxx->tl_data_next;
- 		free(xxx1);
- 	    }
- 	}
- 	free(in_dbent);
- 	if (out_dbent->tl_data) {
- 	    krb5_tl_data *xxx, *xxx1;
- 
- 	    for (xxx=out_dbent->tl_data; xxx; ) {
- 		xxx1 = xxx;
- 		xxx = xxx->tl_data_next;
- 		free(xxx1);
- 	    }
- 	}
- 	free(out_dbent);
-     }
-     else {
- 	fprintf(stderr, "%s: no memory\n", pname);
- 	kret = ENOMEM;
-     }
- 
-     krb5_free_context(kcontext);
-     if (verbose) {
- 	printf("* End %s ", title);
- 	if (isrand)
- 	    printf(" pass %d ", passno);
- 	printf("%s", (kret) ? "FAILURE" : "SUCCESS");
- 	if (kret)
- 	    printf("%d - %s", kret, error_message(kret));
- 	printf("\n");
-     }
-     return((kret) ? 1 : 0);
- }
- 
- /*
-  * usage is: t_dbentry [-r <nnn>] [-v]
-  */
- int
- main(argc, argv)
-     int		argc;
-     char	*argv[];
- {
-     krb5_boolean	verbose;
-     krb5_int32		randompasses;
-     krb5_int32		error;
-     int		option;
-     extern char		*optarg;
-     char		*programname;
-     int			i;
-     time_t		now;
- 
-     randompasses = 0;
-     verbose = 0;
-     error = 0;
-     programname = argv[0];
- 
-     now = time((time_t *) NULL);
-     SRAND((RAND_TYPE) now);
-     while ((option = getopt(argc, argv, "r:v")) != EOF) {
- 	switch (option) {
- 	case 'r':
- 	    if (sscanf(optarg, "%d", &randompasses) != 1) {
- 		fprintf(stderr, "%s: %s is not a number\n", argv[0], optarg);
- 		error++;
- 	    }
- 	    break;
- 	case 'v':
- 	    verbose = 1;
- 	    break;
- 	default:
- 	    fprintf(stderr, "%s: usage is %s [-r number] [-v]\n",
- 		    argv[0], argv[0]);
- 	    error++;
- 	    break;
- 	}
-     }
-     if (error)
- 	return(error);
- 
-     error += do_test(programname, verbose, 0, 1, "Standard set test", 0);
-     error += do_test(programname, verbose, 0, 0, "Standard get test", 0);
-     for (i=0; i<randompasses; i++)
- 	error += do_test(programname, verbose, 1, 0, "Random test", i+1);
-     if (verbose) {
- 	if (error)
- 	    printf("%s: %d errors in %d tests (%5.2f%%)\n", argv[0], error,
- 		   randompasses+2,
- 		   (float) (error*100) / (float) (randompasses+2));
-     }
-     return(error);
- }
- 
--- 0 ----
Index: krb5/lib/kadm/t_ktentry.c
diff -c krb5/lib/kadm/t_ktentry.c:1.1.1.1 krb5/lib/kadm/t_ktentry.c:removed
*** krb5/lib/kadm/t_ktentry.c:1.1.1.1	Mon Jun  2 17:56:03 1997
--- krb5/lib/kadm/t_ktentry.c	Sun Mar 16 20:22:25 2003
***************
*** 1,402 ****
- /*
-  * lib/kadm/t_ktentry.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  *
-  */
- 
- /*
-  * t_ktentry.c	- Test function of krb5_adm_{proto_to_ktent,ktent_to_proto}.
-  */
- 
- #include "k5-int.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- #if	HAVE_SRAND48
- #define	SRAND	srand48
- #define	RAND	lrand48
- #define	RAND_TYPE	long
- #endif	/* HAVE_SRAND48 */
- 
- #if	!defined(RAND_TYPE) && defined(HAVE_SRAND)
- #define	SRAND	srand
- #define	RAND	rand
- #define	RAND_TYPE	int
- #endif	/* !defined(RAND_TYPE) && defined(HAVE_SRAND) */
- 
- #if	!defined(RAND_TYPE) && defined(HAVE_SRANDOM)
- #define	SRAND	srandom
- #define	RAND	random
- #define	RAND_TYPE	long
- #endif	/* !defined(RAND_TYPE) && defined(HAVE_SRANDOM) */
- 
- #if	!defined(RAND_TYPE)
- There is no random number generator.
- #endif	/* !defined(RAND_TYPE) */
- 
- /*
-  * Generate a principal name.
-  */
- static char *
- gen_princname(isrand)
-     krb5_boolean	isrand;
- {
-     static char	*defprinc = "testprinc/instance@realm";
-     char *pptr;
- 
-     if (isrand) {
- 	int i, j;
- 	int ncomps;
- 	size_t compsize[9];
- 	char * complist[9];
- 	size_t	totsize;
- 
- 	for (i=0; i<9; i++) {
- 	    compsize[i] = 0;
- 	    complist[i] = (char *) NULL;
- 	}
- 	ncomps = 2 + (RAND() % 7);
- 	totsize = 0;
- 	for (i=0; i<ncomps; i++) {
- 	    compsize[i] = 1 + (RAND() % 32);
- 	    complist[i] = (char *) malloc(compsize[i]+1);
- 	    if (complist[i]) {
- 		for (j=0; j<compsize[i]; j++) {
- 		    (complist[i])[j] = RAND() % 128;
- 		    while (!isalnum((int) (complist[i])[j]))
- 			(complist[i])[j] = RAND() % 128;
- 		}
- 		(complist[i])[compsize[i]] = '\0';
- 		totsize += (compsize[i] + 1);
- 	    }
- 	    else
- 		break;
- 	}
- 	pptr = (char *) malloc(totsize+1);
- 	if (pptr) {
- 	    pptr[0] = '\0';
- 	    for (i=1; i<ncomps; i++) {
- 		if (complist[i]) {
- 		    strcat(pptr, complist[i]);
- 		    strcat(pptr, "/");
- 		    free(complist[i]);
- 		}
- 		else
- 		    break;
- 	    }
- 	    pptr[strlen(pptr)-1] = '\0';
- 	    strcat(pptr, "@");
- 	    strcat(pptr, complist[0]);
- 	    free(complist[0]);
- 	}
-     }
-     else {
- 	pptr = (char *) malloc(strlen(defprinc)+1);
- 	if (pptr)
- 	    strcpy(pptr, defprinc);
-     }
-     return(pptr);
- }
- 
- static void
- gen_key(ktentp, isrand)
-     krb5_keytab_entry	*ktentp;
-     krb5_boolean	isrand;
- {
-     static unsigned char defkey[8] = { 0x01, 0xfe, 0xab, 0xc3,
- 					   0x23, 0x16, 0x84, 0x23 };
- 
-     if (isrand) {
- 	size_t keylen;
- 	int i;
- 
- 	keylen = 4 + (RAND() % 64);
- 	ktentp->key.contents = (krb5_octet *) malloc(keylen);
- 	if (ktentp->key.contents) {
- 	    ktentp->key.length = keylen;
- 	    for (i=0; i<keylen; i++)
- 		ktentp->key.contents[i] = RAND() & 255;
- 	}
-     }
-     else {
- 	ktentp->key.contents = (krb5_octet *) malloc(sizeof(defkey));
- 	if (ktentp->key.contents) {
- 	    ktentp->key.length = 8;
- 	    memcpy(ktentp->key.contents, defkey, sizeof(defkey));
- 	}
-     }
- }
- 
- /*
-  * Generate a keytab entry.
-  */
- static void
- gen_ktent(kcontext, ktentp, isrand)
-     krb5_context	kcontext;
-     krb5_keytab_entry	*ktentp;
-     krb5_boolean	isrand;
- {
-     char	*princname;
- 
-     princname = gen_princname(isrand);
-     if (princname && !krb5_parse_name(kcontext,
- 				      princname,
- 				      &ktentp->principal)
- 	) {
- 	ktentp->vno = (isrand) ? RAND() : 1;
- 	gen_key(ktentp, isrand);
- 	free(princname);
-     }
- }
- 
- /*
-  * Compare two entries.
-  */
- static krb5_boolean
- compare_entries(kcontext, ientp, oentp)
-     krb5_context	kcontext;
-     krb5_keytab_entry	*ientp;
-     krb5_keytab_entry	*oentp;
- {
-     if (ientp->vno != oentp->vno)
- 	return(0);
- 
-     if ((ientp->key.length != oentp->key.length) ||
- 	memcmp(ientp->key.contents, oentp->key.contents, ientp->key.length))
- 	return(0);
- 
-     if (!krb5_principal_compare(kcontext, ientp->principal, oentp->principal))
- 	return(0);
-     return(1);
- }
- 
- /*
-  * Print out an entry.
-  */
- static void
- print_ktent(kcontext, ientp)
-     krb5_context	kcontext;
-     krb5_keytab_entry	*ientp;
- {
-     char *princname;
-     int i;
- 
-     if (!krb5_unparse_name(kcontext, ientp->principal, &princname)) {
- 	printf("Principal: %s (version %d[%x])\n", princname, ientp->vno);
- 	printf("Key:");
- 	for (i=0; i<ientp->key.length; i++)
- 	    printf(" %02x", ientp->key.contents[i]);
- 	printf("\n");
- 	krb5_xfree(princname);
-     }
- }
- 
- /*
-  * Do a test case.
-  *
-  * Strategy: Generate the desired keytab entry type, then convert it using
-  *	krb5_adm_ktent_to_proto, then convert it back to a keytab entry
-  *	using krb5_adm_proto_to_ktent.  Then verify the match.
-  */
- static krb5_int32
- do_test(pname, verbose, isrand, title, passno)
-     char		*pname;
-     krb5_boolean	verbose;
-     krb5_boolean	isrand;
-     char		*title;
-     krb5_int32		passno;
- {
-     krb5_context	kcontext;
-     krb5_keytab_entry	*in_ktent;
-     krb5_keytab_entry	*out_ktent;
-     krb5_error_code	kret;
-     krb5_int32		ncomps;
-     krb5_data		*complist;
- 
-     if (verbose) {
- 	printf("* Begin %s", title);
- 	if (isrand)
- 	    printf(" pass %d", passno);
- 	printf("\n");
-     }
- 
-     kret = 0;
-     krb5_init_context(&kcontext);
-     krb5_init_ets(kcontext);
-     in_ktent = (krb5_keytab_entry *) malloc(sizeof(krb5_keytab_entry));
-     out_ktent = (krb5_keytab_entry *) malloc(sizeof(krb5_keytab_entry));
-     if (in_ktent && out_ktent) {
- 	/* Initialize our data */
- 	memset((char *) in_ktent, 0, sizeof(krb5_keytab_entry));
- 	memset((char *) out_ktent, 0, sizeof(krb5_keytab_entry));
- 	ncomps = 0;
- 	complist = (krb5_data *) NULL;
- 
- 	/* Generate the keytab entry. */
- 	gen_ktent(kcontext, in_ktent, isrand);
- 
- 	/* Convert it to the o-t-w protocol */
- 	if (!(kret = krb5_adm_ktent_to_proto(kcontext,
- 					     in_ktent,
- 					     &ncomps,
- 					     &complist))) {
- 		/* Otherwise, convert it back to a keytab entry */
- 		if (!(kret = krb5_adm_proto_to_ktent(kcontext,
- 						     ncomps,
- 						     complist,
- 						     out_ktent))) {
- 		    /* Compare the entries */
- 		    if (compare_entries(kcontext,
- 					in_ktent,
- 					out_ktent)) {
- 			/* Success */
- 			if (verbose) {
- 			    printf("Successful translation");
- 			    printf(" during %s", title);
- 			    if (isrand)
- 				printf(" pass %d", passno);
- 			    printf(" of:\n");
- 			    print_ktent(kcontext, in_ktent);
- 			}
- 		    }
- 		    else {
- 			/* Failed */
- 			fprintf(stderr, "%s: comparison mismatch", pname);
- 			fprintf(stderr, " during %s", title);
- 			if (isrand)
- 			    fprintf(stderr, " pass %d", passno);
- 			fprintf(stderr, "\n");
- 			if (verbose) {
- 			    printf("Input entry is as follows:\n");
- 			    print_ktent(kcontext, in_ktent);
- 			    printf("Output entry is as follows:\n");
- 			    print_ktent(kcontext, out_ktent);
- 			}
- 			kret = KRB5KRB_ERR_GENERIC;
- 		    }
- 		}
- 		else {
- 		    /* Conversion to keytab entry failed */
- 		    fprintf(stderr, "%s: protocol decode failed with %d",
- 			pname, kret);
- 		    fprintf(stderr, " during %s", title);
- 		    if (isrand)
- 			fprintf(stderr, " pass %d", passno);
- 		    fprintf(stderr, "\n");
- 		}
- 	    krb5_free_adm_data(kcontext, ncomps, complist);
- 	}
- 	else {
- 	    /* Convert to protocol failed */
- 		fprintf(stderr, "%s: protocol encode failed with %d",
- 			pname, kret);
- 		fprintf(stderr, " during %s", title);
- 		if (isrand)
- 		    fprintf(stderr, " pass %d", passno);
- 		fprintf(stderr, "\n");
- 	}
- 	/* Cleanup */
- 	if (in_ktent->principal)
- 	    krb5_free_principal(kcontext, in_ktent->principal);
- 	if (in_ktent->key.contents)
- 	    free(in_ktent->key.contents);
- 	free(in_ktent);
- 	if (out_ktent->principal)
- 	    krb5_free_principal(kcontext, out_ktent->principal);
- 	if (out_ktent->key.contents)
- 	    free(out_ktent->key.contents);
- 	free(out_ktent);
-     }
-     else {
- 	fprintf(stderr, "%s: no memory\n", pname);
- 	kret = ENOMEM;
-     }
- 
-     krb5_free_context(kcontext);
-     if (verbose) {
- 	printf("* End %s ", title);
- 	if (isrand)
- 	    printf(" pass %d ", passno);
- 	printf("%s", (kret) ? "FAILURE" : "SUCCESS");
- 	if (kret)
- 	    printf("%d - %s", kret, error_message(kret));
- 	printf("\n");
-     }
-     return((kret) ? 1 : 0);
- }
- 
- /*
-  * usage is: t_ktentry [-r <nnn>] [-v]
-  */
- int
- main(argc, argv)
-     int		argc;
-     char	*argv[];
- {
-     krb5_boolean	verbose;
-     krb5_int32		randompasses;
-     krb5_int32		error;
-     int		option;
-     extern char		*optarg;
-     char		*programname;
-     int			i;
-     time_t		now;
- 
-     randompasses = 0;
-     verbose = 0;
-     error = 0;
-     programname = argv[0];
- 
-     now = time((time_t *) NULL);
-     SRAND((RAND_TYPE) now);
-     while ((option = getopt(argc, argv, "r:v")) != EOF) {
- 	switch (option) {
- 	case 'r':
- 	    if (sscanf(optarg, "%d", &randompasses) != 1) {
- 		fprintf(stderr, "%s: %s is not a number\n", argv[0], optarg);
- 		error++;
- 	    }
- 	    break;
- 	case 'v':
- 	    verbose = 1;
- 	    break;
- 	default:
- 	    fprintf(stderr, "%s: usage is %s [-r number] [-v]\n",
- 		    argv[0], argv[0]);
- 	    error++;
- 	    break;
- 	}
-     }
-     if (error)
- 	return(error);
- 
-     error += do_test(programname, verbose, 0, "Standard test", 0);
-     for (i=0; i<randompasses; i++)
- 	error += do_test(programname, verbose, 1, 0, "Random test", i+1);
-     if (verbose) {
- 	if (error)
- 	    printf("%s: %d errors in %d tests (%5.2f%%)\n", argv[0], error,
- 		   randompasses+2,
- 		   (float) (error*100) / (float) (randompasses+2));
-     }
-     return(error);
- }
- 
--- 0 ----
Index: krb5/lib/kadm5/.cvsignore
diff -c /dev/null krb5/lib/kadm5/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:25 2003
--- krb5/lib/kadm5/.cvsignore	Thu Jun  5 10:39:25 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kadm5/admin.h
diff -c krb5/lib/kadm5/admin.h:1.1.1.3 krb5/lib/kadm5/admin.h:1.6
*** krb5/lib/kadm5/admin.h:1.1.1.3	Fri Feb 22 16:35:02 2002
--- krb5/lib/kadm5/admin.h	Tue Nov 26 12:50:16 2002
***************
*** 27,33 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/admin.h,v 1.1.1.3 2002/02/22 21:35:02 kenh Exp $
   */
  
  #ifndef __KADM5_ADMIN_H__
--- 27,33 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/admin.h,v 1.6 2002/11/26 17:50:16 kenh Exp $
   */
  
  #ifndef __KADM5_ADMIN_H__
***************
*** 121,126 ****
--- 121,127 ----
  #define KADM5_CONFIG_DICT_FILE		0x020000
  #define KADM5_CONFIG_MKEY_FROM_KBD	0x040000
  #define KADM5_CONFIG_KPASSWD_PORT	0x080000
+ #define KADM5_CONFIG_ADMIN_ADDRS	0x100000
      
  /*
   * permission bits
***************
*** 217,222 ****
--- 218,225 ----
       int		kpasswd_port;
  
       char *		admin_server;
+      struct sockaddr *	admin_addrs;
+      int		nadmin_addrs;
  
       char *		dbname;
       char *		admin_dbname;
***************
*** 454,459 ****
--- 457,469 ----
  kadm5_ret_t    kadm5_get_policies(void *server_handle,
  				  char *exp, char ***pols,
  				  int *count);
+ 
+ kadm5_ret_t    kadm5_get_rb1response(void *server_handle,
+ 				     krb5_principal princ,
+ 				     int numresponses,
+ 				     char ***challenges,
+ 				     char ***responses,
+ 				     int *n_responses);
  
  #if USE_KADM5_API_VERSION > 1
  kadm5_ret_t    kadm5_free_key_data(void *server_handle,
Index: krb5/lib/kadm5/alt_prof.c
diff -c krb5/lib/kadm5/alt_prof.c:1.1.1.2 krb5/lib/kadm5/alt_prof.c:1.5
*** krb5/lib/kadm5/alt_prof.c:1.1.1.2	Fri Feb 22 16:35:03 2002
--- krb5/lib/kadm5/alt_prof.c	Mon Feb 25 22:29:00 2002
***************
*** 430,435 ****
--- 430,447 ----
  	      *p = '\0';
  	 }
      }
+ #ifdef KRB5_DNS_LOOKUP
+     else {
+ 	 krb5_data cur_realm;
+ 
+ 	 cur_realm.data = params.realm;
+ 	 cur_realm.length = strlen(params.realm);
+ 	 if (!krb5_locate_srv_dns(&cur_realm, "_kadmin", "_tcp",
+ 				  &params.admin_addrs,
+ 				  &params.nadmin_addrs))
+ 	      params.mask |= KADM5_CONFIG_ADMIN_ADDRS;
+     }
+ #endif /* KRB5_DNS_LOOKUP */
  
      /* Get the value for the database */
      hierarchy[2] = "database_name";
Index: krb5/lib/kadm5/chpass_util.c
diff -c krb5/lib/kadm5/chpass_util.c:1.1.1.3 krb5/lib/kadm5/chpass_util.c:1.4
*** krb5/lib/kadm5/chpass_util.c:1.1.1.3	Fri Feb 22 16:35:03 2002
--- krb5/lib/kadm5/chpass_util.c	Sun Feb 24 23:11:52 2002
***************
*** 1,7 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   * 
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/chpass_util.c,v 1.1.1.3 2002/02/22 21:35:03 kenh Exp $
   *
   *
   */
--- 1,7 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   * 
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/chpass_util.c,v 1.4 2002/02/25 04:11:52 kenh Exp $
   *
   *
   */
Index: krb5/lib/kadm5/chpass_util_strings.et
diff -c krb5/lib/kadm5/chpass_util_strings.et:1.1.1.1 krb5/lib/kadm5/chpass_util_strings.et:1.2
*** krb5/lib/kadm5/chpass_util_strings.et:1.1.1.1	Mon Jun  2 17:56:05 1997
--- krb5/lib/kadm5/chpass_util_strings.et	Tue Jun  2 09:57:47 1998
***************
*** 17,24 ****
  
  error_code CHPASS_UTIL_PASSWORD_IN_DICTIONARY,
  "New password was found in a dictionary of possible passwords and\n\
! therefore may be easily guessed. Please choose another password.\n\
! See the ovpasswd man page for help in choosing a good password."
  
  error_code CHPASS_UTIL_PASSWORD_NOT_CHANGED, "Password not changed."
  
--- 17,23 ----
  
  error_code CHPASS_UTIL_PASSWORD_IN_DICTIONARY,
  "New password was found in a dictionary of possible passwords and\n\
! therefore may be easily guessed. Please choose another password."
  
  error_code CHPASS_UTIL_PASSWORD_NOT_CHANGED, "Password not changed."
  
Index: krb5/lib/kadm5/configure.in
diff -c krb5/lib/kadm5/configure.in:1.1.1.2 krb5/lib/kadm5/configure.in:1.7
*** krb5/lib/kadm5/configure.in:1.1.1.2	Fri Feb 22 16:35:03 2002
--- krb5/lib/kadm5/configure.in	Thu Aug 29 14:20:36 2002
***************
*** 8,13 ****
--- 8,37 ----
  AC_PROG_AWK
  AC_CHECK_HEADERS(syslog.h)
  AC_CHECK_FUNCS(openlog syslog closelog strftime vsprintf)
+ dnl Use cracklib?
+ AC_ARG_WITH([cracklib],
+ [  --with-cracklib               Use cracklib for password checking],
+ [CRACKLIB_SRC=$withval])
+ case "x$CRACKLIB_SRC" in
+ x|xno)
+   CRACKLIB_OBJS=""
+   ;;
+ *)
+   AC_DEFINE(KADM5_USE_CRACKLIB)
+   if test -d "$CRACKLIB_SRC/cracklib"; then
+     CRACKLIB_SRC="$CRACKLIB_SRC/cracklib"
+   fi
+   if test -f "$CRACKLIB_SRC/fascist.c"; then :; else
+     AC_MSG_WARN([Cracklib source not present in $CRACKLIB_SRC])
+   fi
+   CRACKLIB_SUBDIR=cracklib
+   CRACKLIB_OBJLIST=cracklib/OBJS.ST
+   ;;
+ esac
+ AC_SUBST(CRACKLIB_SRC)
+ AC_SUBST(CRACKLIB_SUBDIR)
+ AC_SUBST(CRACKLIB_OBJLIST)
+ 
  KRB5_AC_REGEX_FUNCS
  dnl
  dnl AIX is unusual in that it wants all symbols resolved at link time
***************
*** 39,44 ****
--- 63,69 ----
  K5_GEN_MAKEFILE(., libobj)
  K5_GEN_MAKEFILE(clnt, lib libobj)
  K5_GEN_MAKEFILE(srv, lib libobj)
+ K5_GEN_MAKEFILE(srv/cracklib, libobj)
  K5_GEN_MAKEFILE(unit-test)
  K5_AC_OUTPUT
  
Index: krb5/lib/kadm5/kadm_rpc.h
diff -c krb5/lib/kadm5/kadm_rpc.h:1.1.1.2 krb5/lib/kadm5/kadm_rpc.h:1.2
*** krb5/lib/kadm5/kadm_rpc.h:1.1.1.2	Fri Feb 22 16:35:04 2002
--- krb5/lib/kadm5/kadm_rpc.h	Tue Nov 26 12:50:17 2002
***************
*** 134,139 ****
--- 134,147 ----
  typedef struct chrand3_arg chrand3_arg;
  bool_t xdr_chrand3_arg();
  
+ struct getrb1response_arg {
+ 	krb5_ui_4 api_version;
+ 	krb5_principal princ;
+ 	int numresponses;
+ };
+ typedef struct getrb1response_arg getrb1response_arg;
+ bool_t xdr_getrb1response_arg();
+ 
  struct chrand_ret {
  	krb5_ui_4 api_version;
  	kadm5_ret_t code;
***************
*** 231,236 ****
--- 239,254 ----
  typedef struct getprivs_ret getprivs_ret;
  bool_t xdr_getprivs_ret();
  
+ struct getrb1response_ret {
+ 	krb5_ui_4 api_version;
+ 	kadm5_ret_t code;
+ 	char **challenges;
+ 	char **responses;
+ 	int n_responses;
+ };
+ typedef struct getrb1response_ret getrb1response_ret;
+ bool_t xdr_getrb1response_ret();
+ 
  #define KADM ((krb5_ui_4)2112)
  #define KADMVERS ((krb5_ui_4)2)
  #define CREATE_PRINCIPAL ((krb5_ui_4)1)
***************
*** 275,277 ****
--- 293,297 ----
  extern chrand_ret *chrand_principal3_1();
  #define SETKEY_PRINCIPAL3 ((krb5_ui_4) 21)
  extern generic_ret *setkey_principal3_1();
+ #define GET_RB1RESPONSE ((krb5_ui_4) 30)
+ extern getrb1response_ret *get_rb1response_1();
Index: krb5/lib/kadm5/kadm_rpc_xdr.c
diff -c krb5/lib/kadm5/kadm_rpc_xdr.c:1.1.1.4 krb5/lib/kadm5/kadm_rpc_xdr.c:1.2
*** krb5/lib/kadm5/kadm_rpc_xdr.c:1.1.1.4	Mon Aug 12 15:44:54 2002
--- krb5/lib/kadm5/kadm_rpc_xdr.c	Tue Nov 26 12:50:17 2002
***************
*** 927,932 ****
--- 927,972 ----
       return TRUE;
  }
  
+ bool_t xdr_getrb1response_arg(XDR *xdrs, getrb1response_arg *objp)
+ {
+      if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ 	  return (FALSE);
+      }
+      if (!xdr_krb5_principal(xdrs, &objp->princ)) {
+ 	  return (FALSE);
+      }
+      if (!xdr_int(xdrs, &objp->numresponses)) {
+ 	  return (FALSE);
+      }
+      return (TRUE);
+ }
+ 
+ bool_t xdr_getrb1response_ret(XDR *xdrs, getrb1response_ret *objp)
+ {
+      if (!xdr_ui_4(xdrs, &objp->api_version)) {
+ 	  return (FALSE);
+      }
+      if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
+ 	  return (FALSE);
+      }
+      if (objp->code == KADM5_OK) {
+ 	  if (!xdr_int(xdrs, &objp->n_responses)) {
+ 	       return (FALSE);
+ 	  }
+ 	  if (!xdr_array(xdrs, (caddr_t *) &objp->challenges,
+ 			 (unsigned int *) &objp->n_responses, ~0,
+ 			 sizeof(char *), xdr_nullstring)) {
+ 	       return (FALSE);
+ 	  }
+ 	  if (!xdr_array(xdrs, (caddr_t *) &objp->responses,
+ 			 (unsigned int *) &objp->n_responses, ~0,
+ 			 sizeof(char *), xdr_nullstring)) {
+ 	       return (FALSE);
+ 	  }
+      }
+      return (TRUE);
+ }
+ 
  bool_t
  xdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
  {
Index: krb5/lib/kadm5/server_internal.h
diff -c krb5/lib/kadm5/server_internal.h:1.1.1.2 krb5/lib/kadm5/server_internal.h:1.4
*** krb5/lib/kadm5/server_internal.h:1.1.1.2	Mon Nov  3 16:35:10 1997
--- krb5/lib/kadm5/server_internal.h	Sun Feb 24 23:11:53 2002
***************
*** 1,7 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/server_internal.h,v 1.1.1.2 1997/11/03 21:35:10 kenh Exp $
   */
  
  /*
--- 1,7 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/server_internal.h,v 1.4 2002/02/25 04:11:53 kenh Exp $
   */
  
  /*
Index: krb5/lib/kadm5/clnt/.cvsignore
diff -c /dev/null krb5/lib/kadm5/clnt/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:25 2003
--- krb5/lib/kadm5/clnt/.cvsignore	Thu Jun  5 10:39:26 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kadm5/clnt/client_init.c
diff -c krb5/lib/kadm5/clnt/client_init.c:1.1.1.3 krb5/lib/kadm5/clnt/client_init.c:1.5
*** krb5/lib/kadm5/clnt/client_init.c:1.1.1.3	Fri Feb 22 16:35:08 2002
--- krb5/lib/kadm5/clnt/client_init.c	Sun Feb 24 23:11:57 2002
***************
*** 1,7 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_init.c,v 1.1.1.3 2002/02/22 21:35:08 kenh Exp $
   */
  
  /*
--- 1,7 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_init.c,v 1.5 2002/02/25 04:11:57 kenh Exp $
   */
  
  /*
***************
*** 31,37 ****
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_init.c,v 1.1.1.3 2002/02/22 21:35:08 kenh Exp $";
  #endif
  
  #include <stdio.h>
--- 31,37 ----
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_init.c,v 1.5 2002/02/25 04:11:57 kenh Exp $";
  #endif
  
  #include <stdio.h>
***************
*** 150,160 ****
  				   krb5_ui_4 api_version,
  				   void **server_handle)
  {
!      struct sockaddr_in addr;
       struct hostent *hp;
       struct servent *srv;
       int fd;
       int i;
  
       char full_service_name[BUFSIZ], host[MAXHOSTNAMELEN], *ccname_orig;
       char *realm;
--- 150,161 ----
  				   krb5_ui_4 api_version,
  				   void **server_handle)
  {
!      struct sockaddr_in addr, *addr_p;
       struct hostent *hp;
       struct servent *srv;
       int fd;
       int i;
+      int num;
  
       char full_service_name[BUFSIZ], host[MAXHOSTNAMELEN], *ccname_orig;
       char *realm;
***************
*** 263,273 ****
  	  return(code);
       }
  
! #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | \
! 			 KADM5_CONFIG_ADMIN_SERVER | \
! 			 KADM5_CONFIG_KADMIND_PORT) 
! 
!      if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) {
  	  krb5_free_context(handle->context);
  	  free(handle);
  	  return KADM5_MISSING_CONF_PARAMS;
--- 264,277 ----
  	  return(code);
       }
  
! #define REQUIRED_PARAMS1 (KADM5_CONFIG_REALM)
! #define REQUIRED_PARAMS2 (KADM5_CONFIG_ADMIN_SERVER | \
! 			  KADM5_CONFIG_KADMIND_PORT) 
! #define REQUIRED_PARAMS3 (KADM5_CONFIG_ADMIN_ADDRS)
! 
!      if (!((handle->params.mask & REQUIRED_PARAMS1) == REQUIRED_PARAMS1 &&
! 	   ((handle->params.mask & REQUIRED_PARAMS2) == REQUIRED_PARAMS2 ||
! 	    (handle->params.mask & REQUIRED_PARAMS3) == REQUIRED_PARAMS3))) {
  	  krb5_free_context(handle->context);
  	  free(handle);
  	  return KADM5_MISSING_CONF_PARAMS;
***************
*** 411,431 ****
        * We have ticket; open the RPC connection.
        */
  
!      hp = gethostbyname(handle->params.admin_server);
!      if (hp == (struct hostent *) NULL) {
  	  code = KADM5_BAD_SERVER_NAME;
  	  goto cleanup;
       }
- 
-      memset(&addr, 0, sizeof(addr));
-      addr.sin_family = hp->h_addrtype;
-      (void) memcpy((char *) &addr.sin_addr, (char *) hp->h_addr,
- 		   sizeof(addr.sin_addr));
-      addr.sin_port = htons((u_short) handle->params.kadmind_port);
-      
-      fd = RPC_ANYSOCK;
       
!      handle->clnt = clnttcp_create(&addr, KADM, KADMVERS, &fd, 0, 0);
       if (handle->clnt == NULL) {
  	  code = KADM5_RPC_ERROR;
  	  goto error;
--- 415,451 ----
        * We have ticket; open the RPC connection.
        */
  
!      if (handle->params.mask & KADM5_CONFIG_ADMIN_SERVER) {
! 	  hp = gethostbyname(handle->params.admin_server);
! 	  if (hp == (struct hostent *) NULL) {
! 	       code = KADM5_BAD_SERVER_NAME;
! 	       goto cleanup;
! 	  }
! 
! 	  memset(&addr, 0, sizeof(addr));
! 	  addr.sin_family = hp->h_addrtype;
! 	  (void) memcpy((char *) &addr.sin_addr, (char *) hp->h_addr,
! 			 sizeof(addr.sin_addr));
! 	  addr.sin_port = htons((u_short) handle->params.kadmind_port);
! 
! 	  addr_p = &addr;
! 	  num = 1;
!      } else if (handle->params.mask & KADM5_CONFIG_ADMIN_ADDRS) {
! 	  addr_p = (struct sockaddr_in *) handle->params.admin_addrs;
! 	  num = handle->params.nadmin_addrs;
!      } else {
! 	  /* Shouldn't happen, but just in case ... */
  	  code = KADM5_BAD_SERVER_NAME;
  	  goto cleanup;
       }
       
!      for (i = 0; i < num; i++) {
! 	  fd = RPC_ANYSOCK;
! 	  handle->clnt = clnttcp_create(&addr_p[i], KADM, KADMVERS, &fd, 0, 0);
! 	  if (handle->clnt != NULL)
! 	       break;
!      }
! 
       if (handle->clnt == NULL) {
  	  code = KADM5_RPC_ERROR;
  	  goto error;
***************
*** 549,554 ****
--- 569,576 ----
  	  AUTH_DESTROY(handle->clnt->cl_auth);
       if(handle->clnt)
  	  clnt_destroy(handle->clnt);
+      if(handle->params.admin_addrs)
+ 	  free(handle->params.admin_addrs);
  
  cleanup:
       krb5_free_cred_contents(handle->context, &creds);
***************
*** 582,587 ****
--- 604,611 ----
  	  AUTH_DESTROY(handle->clnt->cl_auth);
       if (handle->clnt)
  	  clnt_destroy(handle->clnt);
+      if (handle->params.admin_addrs)
+           free(handle->params.admin_addrs);
       if (handle->lhandle)
            free (handle->lhandle);
  
Index: krb5/lib/kadm5/clnt/client_principal.c
diff -c krb5/lib/kadm5/clnt/client_principal.c:1.1.1.3 krb5/lib/kadm5/clnt/client_principal.c:1.5
*** krb5/lib/kadm5/clnt/client_principal.c:1.1.1.3	Fri Feb 22 16:35:08 2002
--- krb5/lib/kadm5/clnt/client_principal.c	Tue Nov 26 12:50:34 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_principal.c,v 1.1.1.3 2002/02/22 21:35:08 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_principal.c,v 1.1.1.3 2002/02/22 21:35:08 kenh Exp $";
  #endif
  
  #include    <gssrpc/rpc.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_principal.c,v 1.5 2002/11/26 17:50:34 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/clnt/client_principal.c,v 1.5 2002/11/26 17:50:34 kenh Exp $";
  #endif
  
  #include    <gssrpc/rpc.h>
***************
*** 538,541 ****
--- 538,574 ----
  			      krb5_keysalt *keysalt, int *kvnop)
  {
       return EINVAL;
+ }
+ 
+ kadm5_ret_t
+ kadm5_get_rb1response(void *server_handle, krb5_principal princ,
+ 		      int numresponses, char ***challenges,
+ 		      char ***responses, int *n_responses)
+ {
+     getrb1response_arg arg;
+     getrb1response_ret *r;
+     kadm5_server_handle_t handle = server_handle;
+ 
+     CHECK_HANDLE(server_handle);
+ 
+     arg.princ = princ;
+     arg.numresponses = numresponses;
+     arg.api_version = handle->api_version;
+ 
+     r = get_rb1response_1(&arg, handle->clnt);
+ 
+     if (r == NULL)
+ 	return KADM5_RPC_ERROR;
+ 
+     if (r->code == 0) {
+ 	*challenges = r->challenges;
+ 	*responses = r->responses;
+ 	*n_responses = r->n_responses;
+     } else {
+ 	*challenges = NULL;
+ 	*responses = NULL;
+ 	*n_responses = 0;
+     }
+ 
+     return r->code;
  }
Index: krb5/lib/kadm5/clnt/client_rpc.c
diff -c krb5/lib/kadm5/clnt/client_rpc.c:1.1.1.2 krb5/lib/kadm5/clnt/client_rpc.c:1.4
*** krb5/lib/kadm5/clnt/client_rpc.c:1.1.1.2	Fri Feb 22 16:35:09 2002
--- krb5/lib/kadm5/clnt/client_rpc.c	Tue Nov 26 12:50:35 2002
***************
*** 289,294 ****
--- 289,309 ----
       return (&res);
  }
  
+ getrb1response_ret *
+ get_rb1response_1(argp, clnt)
+ 	getrb1response_arg *argp;
+ 	CLIENT *clnt;
+ {
+ 	static getrb1response_ret res;
+ 
+ 	memset((char *) &res, 0, sizeof(res));
+ 	if (clnt_call(clnt, GET_RB1RESPONSE, xdr_getrb1response_arg, argp,
+ 		      xdr_getrb1response_ret, &res, TIMEOUT) != RPC_SUCCESS) {
+ 		return (NULL);
+ 	}
+ 	return (&res);
+ }
+ 
  generic_ret *
  init_1(argp, clnt)
     void *argp;
Index: krb5/lib/kadm5/clnt/configure.in
diff -c krb5/lib/kadm5/clnt/configure.in:1.1.1.1 krb5/lib/kadm5/clnt/configure.in:removed
*** krb5/lib/kadm5/clnt/configure.in:1.1.1.1	Mon Jun  2 17:56:10 1997
--- krb5/lib/kadm5/clnt/configure.in	Sun Mar 16 20:22:25 2003
***************
*** 1,28 ****
- AC_INIT(client_rpc.c)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_PROG_INSTALL
- V5_SHARED_LIB_OBJS
- V5_MAKE_SHARED_LIB(libkadm5clnt, 1.0, ../.., ./kadm5/clnt)
- 
- GSSRPC_SH_VERS=$krb5_cv_shlib_version_libgssrpc
- AC_SUBST(GSSRPC_SH_VERS)
- GSSAPI_KRB5_SH_VERS=$krb5_cv_shlib_version_libgssapi_krb5
- AC_SUBST(GSSAPI_KRB5_SH_VERS)
- KDB5_SH_VERS=$krb5_cv_shlib_version_libkdb5
- AC_SUBST(KDB5_SH_VERS)
- KRB5_SH_VERS=$krb5_cv_shlib_version_libkrb5
- AC_SUBST(KRB5_SH_VERS)
- CRYPTO_SH_VERS=$krb5_cv_shlib_version_libcrypto
- AC_SUBST(CRYPTO_SH_VERS)
- COMERR_SH_VERS=$krb5_cv_shlib_version_libcom_err
- AC_SUBST(COMERR_SH_VERS)
- DYN_SH_VERS=$krb5_cv_shlib_version_libdyn
- AC_SUBST(DYN_SH_VERS)
- 
- SubdirLibraryRule([$(OBJS)])
- 
- CopySrcHeader(client_internal.h,[$](BUILDTOP)/include/kadm5)
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/kadm5/srv/.cvsignore
diff -c /dev/null krb5/lib/kadm5/srv/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:25 2003
--- krb5/lib/kadm5/srv/.cvsignore	Thu Jun  5 10:39:27 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kadm5/srv/Makefile.in
diff -c krb5/lib/kadm5/srv/Makefile.in:1.1.1.3 krb5/lib/kadm5/srv/Makefile.in:1.5
*** krb5/lib/kadm5/srv/Makefile.in:1.1.1.3	Fri Feb 22 16:35:10 2002
--- krb5/lib/kadm5/srv/Makefile.in	Thu Aug 15 17:48:45 2002
***************
*** 4,9 ****
--- 4,10 ----
  BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)
  LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5
  DEFINES = @HESIOD_DEFS@
+ MY_SUBDIRS=@CRACKLIB_SUBDIR@
  
  ##DOSBUILDTOP = ..\..\..
  ##DOSLIBNAME = libkadm5srv.lib
***************
*** 11,17 ****
  LIB=kadm5srv
  LIBMAJOR=5
  LIBMINOR=0
! STOBJLISTS=../OBJS.ST OBJS.ST
  SHLIB_EXPDEPS=\
  	$(TOPLIBD)/libgssrpc$(SHLIBEXT) \
  	$(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \
--- 12,18 ----
  LIB=kadm5srv
  LIBMAJOR=5
  LIBMINOR=0
! STOBJLISTS=../OBJS.ST OBJS.ST @CRACKLIB_OBJLIST@
  SHLIB_EXPDEPS=\
  	$(TOPLIBD)/libgssrpc$(SHLIBEXT) \
  	$(TOPLIBD)/libgssapi_krb5$(SHLIBEXT) \
***************
*** 47,53 ****
  	server_init.$(OBJEXT) \
  	server_dict.$(OBJEXT) \
  	svr_iters.$(OBJEXT) \
! 	svr_chpass_util.$(OBJEXT) \
  	adb_xdr.$(OBJEXT) \
  	adb_policy.$(OBJEXT) \
  	adb_free.$(OBJEXT) \
--- 48,54 ----
  	server_init.$(OBJEXT) \
  	server_dict.$(OBJEXT) \
  	svr_iters.$(OBJEXT) \
! 	sr_chpass_util.$(OBJEXT) \
  	adb_xdr.$(OBJEXT) \
  	adb_policy.$(OBJEXT) \
  	adb_free.$(OBJEXT) \
Index: krb5/lib/kadm5/srv/adb_free.c
diff -c krb5/lib/kadm5/srv/adb_free.c:1.1.1.2 krb5/lib/kadm5/srv/adb_free.c:1.4
*** krb5/lib/kadm5/srv/adb_free.c:1.1.1.2	Mon Nov  3 16:35:31 1997
--- krb5/lib/kadm5/srv/adb_free.c	Sun Feb 24 23:11:59 2002
***************
*** 1,9 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_free.c,v 1.1.1.2 1997/11/03 21:35:31 kenh Exp $
   * 
   * $Log: adb_free.c,v $
   * Revision 1.1.1.2  1997/11/03 21:35:31  kenh
   * Import of Kerberos 5, Release 1.0.2
   *
--- 1,21 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_free.c,v 1.4 2002/02/25 04:11:59 kenh Exp $
   * 
   * $Log: adb_free.c,v $
+  * Revision 1.4  2002/02/25 04:11:59  kenh
+  * Merging in changes from MIT Kerberos 5 1.2.3.
+  *
+  * Revision 1.3  1997/11/03 22:14:38  kenh
+  * Fix up conflicts from Release 1.0.2 import.
+  *
+  * Revision 1.2  1997/09/18 20:38:30  vwelch
+  * ConvexOS Port.
+  *
+  * Revision 1.1.1.1  1997/06/02 21:56:07  kenh
+  * Initial import of R1.0 from MIT.
+  *
   * Revision 1.1.1.2  1997/11/03 21:35:31  kenh
   * Import of Kerberos 5, Release 1.0.2
   *
***************
*** 51,57 ****
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_free.c,v 1.1.1.2 1997/11/03 21:35:31 kenh Exp $";
  #endif
  
  #include	"adb.h"
--- 63,69 ----
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_free.c,v 1.4 2002/02/25 04:11:59 kenh Exp $";
  #endif
  
  #include	"adb.h"
Index: krb5/lib/kadm5/srv/adb_xdr.c
diff -c krb5/lib/kadm5/srv/adb_xdr.c:1.1.1.3 krb5/lib/kadm5/srv/adb_xdr.c:1.4
*** krb5/lib/kadm5/srv/adb_xdr.c:1.1.1.3	Fri Feb 22 16:35:12 2002
--- krb5/lib/kadm5/srv/adb_xdr.c	Sun Feb 24 23:12:00 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_xdr.c,v 1.1.1.3 2002/02/22 21:35:12 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_xdr.c,v 1.1.1.3 2002/02/22 21:35:12 kenh Exp $";
  #endif
  
  #include <sys/types.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_xdr.c,v 1.4 2002/02/25 04:12:00 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/adb_xdr.c,v 1.4 2002/02/25 04:12:00 kenh Exp $";
  #endif
  
  #include <sys/types.h>
Index: krb5/lib/kadm5/srv/configure.in
diff -c krb5/lib/kadm5/srv/configure.in:1.1.1.1 krb5/lib/kadm5/srv/configure.in:removed
*** krb5/lib/kadm5/srv/configure.in:1.1.1.1	Mon Jun  2 17:56:07 1997
--- krb5/lib/kadm5/srv/configure.in	Sun Mar 16 20:22:26 2003
***************
*** 1,50 ****
- AC_INIT(server_kdb.c)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_PROG_INSTALL
- AC_PROG_LEX
- AC_PROG_AWK
- 
- save_LIBS="$LIBS"
- LIBS=-lgen
- AC_CHECK_FUNCS(compile step)
- if test "$ac_cv_func_compile" = true ; then
- 	LIBS="$save_LIBS -lgen"
- else
- 	LIBS="$save_LIBS"
- fi
- 
- AC_CHECK_FUNCS(re_comp re_exec regcomp regexec)
- dnl AIX is unusual in that it wants all symbols resolved at link time
- dnl  Fortunately, it will allow us to link the kdb library now, even if
- dnl it is linked again later.
- case $krb5_cv_host in
- *-*-aix*)
- 	LIBS="$LIBS -ldb"
- 	;;
- esac
- 
- V5_SHARED_LIB_OBJS
- V5_MAKE_SHARED_LIB(libkadm5srv, 1.0, ../.., ./kadm5/srv)
- 
- GSSRPC_SH_VERS=$krb5_cv_shlib_version_libgssrpc
- AC_SUBST(GSSRPC_SH_VERS)
- GSSAPI_KRB5_SH_VERS=$krb5_cv_shlib_version_libgssapi_krb5
- AC_SUBST(GSSAPI_KRB5_SH_VERS)
- KDB5_SH_VERS=$krb5_cv_shlib_version_libkdb5
- AC_SUBST(KDB5_SH_VERS)
- KRB5_SH_VERS=$krb5_cv_shlib_version_libkrb5
- AC_SUBST(KRB5_SH_VERS)
- CRYPTO_SH_VERS=$krb5_cv_shlib_version_libcrypto
- AC_SUBST(CRYPTO_SH_VERS)
- COMERR_SH_VERS=$krb5_cv_shlib_version_libcom_err
- AC_SUBST(COMERR_SH_VERS)
- DYN_SH_VERS=$krb5_cv_shlib_version_libdyn
- AC_SUBST(DYN_SH_VERS)
- 
- SubdirLibraryRule([$(OBJS)])
- 
- CopySrcHeader(server_acl.h,[$](BUILDTOP)/include/kadm5)
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/kadm5/srv/server_dict.c
diff -c krb5/lib/kadm5/srv/server_dict.c:1.1.1.2 krb5/lib/kadm5/srv/server_dict.c:1.6
*** krb5/lib/kadm5/srv/server_dict.c:1.1.1.2	Mon Nov  3 16:35:35 1997
--- krb5/lib/kadm5/srv/server_dict.c	Sun Feb 24 23:12:00 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/server_dict.c,v 1.1.1.2 1997/11/03 21:35:35 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/server_dict.c,v 1.1.1.2 1997/11/03 21:35:35 kenh Exp $";
  #endif
  
  #include    <sys/types.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/server_dict.c,v 1.6 2002/02/25 04:12:00 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/server_dict.c,v 1.6 2002/02/25 04:12:00 kenh Exp $";
  #endif
  
  #include    <sys/types.h>
***************
*** 21,29 ****
--- 21,37 ----
  #include    <syslog.h>
  #include    "server_internal.h"
  
+ #ifndef KADM5_USE_CRACKLIB
  static char	    **word_list = NULL;	    /* list of word pointers */
  static char	    *word_block = NULL;	    /* actual word data */
  static int	    word_count = 0;	    /* number of words */
+ 
+ #else /* KADM5_USE_CRACKLIB */
+ static char		*dict_path = NULL;
+ extern char 		*FascistCheck();
+ 
+ #endif /* KADM5_USE_CRACKLIB */
+ 
  extern int	    errno;
  
  /*
***************
*** 47,52 ****
--- 55,61 ----
      return (strcasecmp(*(char **)s1, *(char **)s2));
  }
  
+ #ifndef KADM5_USE_CRACKLIB
  /*
   * Function: init-dict
   * 
***************
*** 196,198 ****
--- 205,285 ----
  	word_count = 0;
      return;
  }
+ 
+ #else /* KADM5_USE_CRACKLIB */
+ 
+ /*
+  * Get dictionary file path from params, check it and store for later
+  * use by find_word().
+  */
+ int init_dict(kadm5_config_params *params)
+ {
+     struct stat st;
+     char *dict_file;
+ 
+ 
+     if (dict_path)	/* Already been initialized */
+ 	return KADM5_OK;
+ 
+     if (! (params->mask & KADM5_CONFIG_DICT_FILE)) {
+ 	syslog(LOG_INFO, "No dictionary file specified, continuing "
+ 	       "without one.");
+ 	return KADM5_OK;
+     }
+ 
+     /*
+      * Check for one of the cracklib dictionary files. We'll
+      * assume that if it's there, then the other two are.
+      *
+      * Note that for cracklib the path specified is just the
+      * prefix filename. The actual files will be the path
+      * plus an appened ".hwm", ".pwd", and ".pwi".
+      */
+      
+     dict_file = malloc(strlen(params->dict_file) + 5);
+     
+     if (dict_file == NULL) {
+ 	syslog(LOG_ERR, "malloc() failed.");
+ 	return errno;
+     }
+ 
+     strcpy(dict_file, params->dict_file);
+     strcat(dict_file, ".hwm");
+ 
+     if (stat(dict_file, &st) == 0) {
+ 	dict_path = params->dict_file;
+ 	syslog(LOG_INFO, "Using cracklib dictionary with prefix %s", dict_path);
+     } else {
+ 	syslog(LOG_ERR, "WARNING!  Cannot find cracklib dictionary file %s, "
+ 	       "continuing without one.", dict_file);
+     }
+ 
+     free(dict_file);
+     return KADM5_OK;
+ }
+   
+ int
+ find_word(const char *word)
+ {
+     char *msg;
+ 
+ 
+     if (dict_path == NULL)
+ 	return WORD_NOT_FOUND;
+ 
+     if (msg = FascistCheck(word, dict_path)) {
+ 	syslog(LOG_INFO, "cracklib rejected new change: %s", msg);
+ 	return KADM5_OK;
+     } else {
+ 	return WORD_NOT_FOUND;
+     }
+ }
+ 
+ void
+ destroy_dict(void)
+ {
+     dict_path = NULL;
+     return;
+ }
+ 
+ #endif /* KADM5_USE_CRACKLIB */
Index: krb5/lib/kadm5/srv/svr_principal.c
diff -c krb5/lib/kadm5/srv/svr_principal.c:1.1.1.5 krb5/lib/kadm5/srv/svr_principal.c:1.9
*** krb5/lib/kadm5/srv/svr_principal.c:1.1.1.5	Thu Dec 19 14:07:27 2002
--- krb5/lib/kadm5/srv/svr_principal.c	Thu Dec 19 14:19:30 2002
***************
*** 1,11 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/svr_principal.c,v 1.1.1.5 2002/12/19 19:07:27 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/svr_principal.c,v 1.1.1.5 2002/12/19 19:07:27 kenh Exp $";
  #endif
  
  #include	<sys/types.h>
--- 1,11 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
   *
!  * $Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/svr_principal.c,v 1.9 2002/12/19 19:19:30 kenh Exp $
   */
  
  #if !defined(lint) && !defined(__CODECENTER__)
! static char *rcsid = "$Header: /afs/cmf/project/cvsroot/krb5/lib/kadm5/srv/svr_principal.c,v 1.9 2002/12/19 19:19:30 kenh Exp $";
  #endif
  
  #include	<sys/types.h>
***************
*** 235,247 ****
  	return(ret);
      }
  
-     if (ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now)) {
- 	krb5_dbe_free_contents(handle->context, &kdb);
- 	if (mask & KADM5_POLICY)
- 	     (void) kadm5_free_policy_ent(handle->lhandle, &polent);
- 	return(ret);
-     }
- 
      /* initialize the keys */
  
      if (ret = krb5_dbe_cpw(handle->context, &master_keyblock,
--- 235,240 ----
***************
*** 389,395 ****
  
      CHECK_HANDLE(server_handle);
  
!     if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) ||
         (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) ||
         (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
         (mask & KADM5_KEY_DATA) || (mask & KADM5_LAST_SUCCESS) ||
--- 382,388 ----
  
      CHECK_HANDLE(server_handle);
  
!     if((mask & KADM5_PRINCIPAL) ||
         (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) ||
         (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
         (mask & KADM5_KEY_DATA) || (mask & KADM5_LAST_SUCCESS) ||
***************
*** 404,410 ****
      if (mask & KADM5_TL_DATA) {
  	 tl_data_orig = entry->tl_data;
  	 while (tl_data_orig) {
! 	      if (tl_data_orig->tl_data_type < 256)
  		   return KADM5_BAD_TL_TYPE;
  	      tl_data_orig = tl_data_orig->tl_data_next;
  	 }
--- 397,404 ----
      if (mask & KADM5_TL_DATA) {
  	 tl_data_orig = entry->tl_data;
  	 while (tl_data_orig) {
! 	      if (tl_data_orig->tl_data_type < 256 &&
! 		  tl_data_orig->tl_data_type != KRB5_TL_RB1_CHALLENGE)
  		   return KADM5_BAD_TL_TYPE;
  	      tl_data_orig = tl_data_orig->tl_data_next;
  	 }
***************
*** 560,565 ****
--- 554,572 ----
  	 }
      }
  
+     /*
+      * I'm not sure if client programs should be forced to modify the
+      * TL_DATA directly, or use the obvious mechanism of modifying
+      * KADM5_LAST_PW_CHANGE.  To me, the latter seems to make more
+      * sense.
+      */
+ 
+     if (mask & KADM5_LAST_PWD_CHANGE) {
+ 	if ((ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb,
+ 						  entry->last_pwd_change)))
+ 	    goto done;
+     }
+ 
      ret = kdb_put_entry(handle, &kdb, &adb);
      if (ret) goto done;
  
***************
*** 1749,1752 ****
--- 1756,1955 ----
  	 *kvnop = key_data->key_data_kvno;
  
      return KADM5_OK;
+ }
+ 
+ /*
+  * Return a list of valid CRYPTOCard challenge/responses
+  */
+ 
+ #define RB1_DATA_SIZE	8
+ 
+ kadm5_ret_t
+ kadm5_get_rb1response(void *server_handle, krb5_principal princ,
+ 		      int numresponses, char ***challenges,
+ 		      char ***responses, int *n_responses)
+ {
+     krb5_db_entry		kdb;
+     osa_princ_ent_rec		adb;
+     krb5_key_data		*key_data;
+     krb5_keyblock		key;
+     krb5_data			rb1_data;
+     krb5_enc_data		rb1_enc_data;
+     osa_adb_ret_t		ret = 0;
+     krb5_tl_data		*tl;
+     char			**ret_challenges = NULL, **ret_responses = NULL;
+     char			challenge[RB1_DATA_SIZE],
+    				response[RB1_DATA_SIZE];
+     int 			i, j;
+     kadm5_server_handle_t handle = server_handle;
+ 
+     key.contents = NULL;
+ 
+     CHECK_HANDLE(server_handle)
+ 
+     if (princ == NULL || numresponses <= 0)
+ 	return EINVAL;
+ 
+     /* Right now limit this to 20 */
+ 
+     if (numresponses > 20)
+ 	numresponses = 20;
+ 
+     if ((ret = kdb_get_entry(handle, princ, &kdb, &adb)))
+ 	return ret;
+ 
+     tl = kdb.tl_data;
+     memset(challenge, 0, sizeof(challenge));
+     while (tl) {
+ 	if (tl->tl_data_type == KRB5_TL_RB1_CHALLENGE) {
+ 		i = tl->tl_data_length < sizeof(challenge) ?
+ 		    tl->tl_data_length : sizeof(challenge);
+ 		strncpy(challenge, (char *) tl->tl_data_contents, i);
+ 		break;
+ 	}
+ 	tl = tl->tl_data_next;
+     }
+ 
+     if (! tl) {
+ 	ret = KADM5_BAD_PRINCIPAL;
+ 	goto done;
+     }
+ 
+     /*
+      * Right now we assume CRYPTOCard is single-DES.  Note that we force
+      * DES_CBC_RAW.
+      */
+ 
+     if ((ret = krb5_dbe_find_enctype(handle->context, &kdb,
+ 				     ENCTYPE_DES_CBC_CRC, -1, -1, &key_data)))
+ 	goto done;
+ 
+     if ((ret = krb5_dbekd_decrypt_key_data(handle->context, &master_keyblock,
+ 					   key_data, &key, NULL)))
+ 	goto done;
+ 
+     key.enctype = ENCTYPE_DES_CBC_RAW;
+ 
+     /*
+      * We've got the challenge, and the key.  Now simply start computing
+      * the next N responses.  Note that we're doing upper-case responses.
+      *
+      * First we have to allocate all of the memory we need.
+      */
+ 
+     ret_challenges = (char **) malloc(sizeof(char *) * numresponses);
+     if (! ret_challenges) {
+ 	ret = ENOMEM;
+ 	goto done;
+     }
+     memset(ret_challenges, 0, sizeof(char *) * numresponses);
+ 
+     ret_responses = (char **) malloc(sizeof(char *) * numresponses);
+     if (! ret_responses) {
+ 	ret = ENOMEM;
+ 	goto done;
+     }
+     memset(ret_responses, 0, sizeof(char *) * numresponses);
+ 
+     for (i = 0; i < numresponses; i++) {
+ 	ret_challenges[i] = (char *) malloc(RB1_DATA_SIZE + 1);
+ 	if (! ret_challenges[i]) {
+ 	    ret = ENOMEM;
+ 	    goto done;
+ 	}
+ 	ret_responses[i] = (char *) malloc(RB1_DATA_SIZE + 1);
+ 	if (! ret_responses[i]) {
+ 	    ret = ENOMEM;
+ 	    goto done;
+ 	}
+     }
+ 
+     /*
+      * Seed things with the first challenge
+      */
+ 
+     memcpy(ret_challenges[0], challenge, RB1_DATA_SIZE);
+     (ret_challenges[0])[RB1_DATA_SIZE] = '\0';
+ 
+     ret = krb5_c_encrypt_length(handle->context, key.enctype, RB1_DATA_SIZE,
+ 			(unsigned int *) &rb1_enc_data.ciphertext.length);
+ 
+     if (ret)
+ 	goto done;
+ 
+     if (rb1_enc_data.ciphertext.length > RB1_DATA_SIZE)
+ 	ret = KRB5_BAD_MSIZE;
+ 
+     rb1_enc_data.ciphertext.data = response;
+ 
+     rb1_data.length = RB1_DATA_SIZE;
+ 
+     /*
+      * Loop over the list, doing all of the challenges
+      */
+ 
+     for (i = 0; i < numresponses; i++) {
+ 	rb1_data.data = ret_challenges[i];
+ 
+ 	ret = krb5_c_encrypt(handle->context, &key, 0 /* Usage = 0 */,
+ 			     NULL, &rb1_data, &rb1_enc_data);
+ 	
+ 	if (ret)
+ 	    goto done;
+ 
+ 	/*
+ 	 * Note: This is essentially sprintf("%02X") on the upper 4 bytes
+ 	 * of the output block.
+ 	 */
+ 	
+ 	for (j = 0; j < RB1_DATA_SIZE / 2; j++) {
+ 	    char n[2];
+ 	    n[0] = response[j] & 0xf;
+ 	    n[1] = (response[j] >> 4) & 0xf;
+ 	    (ret_responses[i])[j*2] = n[1] > 9 ? n[1] - 10 + 'A' : '0' + n[1];
+ 	    (ret_responses[i])[j*2+1] = n[0] > 9 ? n[0] - 10 + 'A' : '0' + n[0];
+ 	}
+ 
+ 	ret_responses[i][RB1_DATA_SIZE] = '\0';
+ 
+ 	/*
+ 	 * The next challenge is the whole block converted to ASCII numerals
+ 	 * (lower nybble of each byte) with wraparound if the number is
+ 	 * in the 0x0a - 0x0f range.
+ 	 */
+ 	
+ 	if (i + 1 < numresponses) {
+ 	    for (j = 0; j < RB1_DATA_SIZE; j++) {
+ 		(ret_challenges[i + 1])[j] = (response[j] & 0x0f) + 0x30;
+ 		if ((ret_challenges[i + 1])[j] > 0x39)
+ 		    (ret_challenges[i + 1])[j] -= 10;
+ 	    }
+ 	    ret_challenges[i + 1][RB1_DATA_SIZE] = '\0';
+ 	}
+     }
+ 
+     *challenges = ret_challenges;
+     *responses = ret_responses;
+     *n_responses = numresponses;
+ 
+ done:
+     kdb_free_entry(handle, &kdb, &adb);
+     if (key.contents)
+ 	krb5_free_keyblock_contents(handle->context, &key);
+     if (ret != 0) {
+ 	if (ret_challenges) {
+ 	    for (i = 0; i < numresponses; i++)
+ 		if (ret_challenges[i])
+ 		    free(ret_challenges[i]);
+ 	    free(ret_challenges);
+ 	}
+ 	if (ret_responses) {
+ 	    for (i = 0; i < numresponses; i++)
+ 		if (ret_responses[i])
+ 		    free(ret_responses[i]);
+ 	    free(ret_responses);
+ 	}
+     }
+ 
+     return ret;
  }
Index: krb5/lib/kadm5/srv/cracklib/.cvsignore
diff -c /dev/null krb5/lib/kadm5/srv/cracklib/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:26 2003
--- krb5/lib/kadm5/srv/cracklib/.cvsignore	Fri Feb 27 15:08:40 1998
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kadm5/srv/cracklib/Makefile.in
diff -c /dev/null krb5/lib/kadm5/srv/cracklib/Makefile.in:1.3
*** /dev/null	Sun Mar 16 20:22:26 2003
--- krb5/lib/kadm5/srv/cracklib/Makefile.in	Thu Aug 15 17:48:56 2002
***************
*** 0 ****
--- 1,31 ----
+ #
+ # Makefile for cracklib support in krb5
+ # Requires GNU Make !!
+ #
+ thisconfigdir=./../..
+ myfulldir=lib/kadm5/srv/cracklib
+ mydir=cracklib
+ BUILDTOP=$(REL)$(U)$(S)$(U)$(S)$(U)$(S)$(U)
+ CRACKLIB_SRC=@CRACKLIB_SRC@
+ LOCALINCLUDES = -I$(BUILDTOP)/include/kadm5 -I$(CRACKLIB_SRC) -DIN_CRACKLIB
+ 
+ vpath %.c $(CRACKLIB_SRC)
+ 
+ STLIBOBJS=\
+ 	fascist.o	\
+ 	packlib.o	\
+ 	rules.o		\
+ 	stringlib.o
+ 
+ OBJS=	$(OUTPRE)fascist.$(OBJEXT)	\
+ 	$(OUTPRE)packlib.$(OBJEXT)	\
+ 	$(OUTPRE)rules.$(OBJEXT)	\
+ 	$(OUTPRE)stringlib.$(OBJEXT)
+ 
+ SRCS=	$(CRACKLIB_SRC)/fascist.c	\
+ 	$(CRACKLIB_SRC)/packlib.c	\
+ 	$(CRACKLIB_SRC)/rules.c		\
+ 	$(CRACKLIB_SRC)/stringlib.c
+ 
+ all-unix:: all-libobjs
+ clean-unix:: clean-libobjs
Index: krb5/lib/kadm5/srv/cracklib/README
diff -c /dev/null krb5/lib/kadm5/srv/cracklib/README:1.2
*** /dev/null	Sun Mar 16 20:22:26 2003
--- krb5/lib/kadm5/srv/cracklib/README	Fri Aug 20 15:25:39 1999
***************
*** 0 ****
--- 1,103 ----
+ --------------------------------------------------------
+ CrackLib support for password changing in Kerberos 5 KDC
+ --------------------------------------------------------
+ 
+ 1) Building Kerberos to use libcrack
+ 2) Configuring Kerberos to use libcrack
+ 
+ ===================================
+ Building Kerberos to use libcrack.a
+ ===================================
+ 
+ 1) Get libcrack. I got it from
+ 
+  ftp://coast.cs.purdue.edu/pub/tools/unix/cracklib/
+ 
+ and it was dated June 16th, 1993.
+ 
+ 2) Cracklib does some checks based on the uid of the process
+ it's running as. Since the Kerberos process are running as root
+ these checks don't do us any good and I was seeing problems
+ with them, so I ifdef'ed them out as follows.
+ 
+ *** fascist.c   1998/05/28 14:35:38     1.1
+ --- fascist.c   1998/05/28 15:01:24     1.2
+ ***************
+ *** 390,399 ****
+ --- 390,406 ----
+         return ("it looks like a National Insurance number.");
+       }
+   
+ + #ifndef KRB5_KDC
+ +     /*
+ +      * If we're running in the Kerberos 5 KDC then we are root so this
+ +      * call doesn't make much sense.
+ +      */
+ + 
+       if (ptr = FascistGecos(password, getuid()))
+       {
+         return (ptr);
+       }
+ + #endif /* KRB5_KDC */    
+   
+       for (i = 0; r_destructors[i]; i++)
+       {
+ 
+ 
+ 3) To enable libcrack support in kebreros you need to specify
+    '--with-cracklib=<path to cracklib src tree>' at configure time.
+ 
+ For example, assuming you had untarred craclib in /usr/local/src/cracklib,2.7,
+ you would need to append '--with-cracklib=/usr/localsrc/cracklib,2.7' to
+ your configure arguments.
+ 
+ ======================================
+ Configuring Kerberos to use libcrack.a
+ ======================================
+ 
+ With libcrack.a built into Kerberos, you then need to
+ install the Cracklib dictionary files (i.e. pw_dict.hwm,
+ pw_dict.pwd, and pw_dict.pwi) where the Kerberos programs
+ can find them. These files are create from dictionary templates
+ you supply; read the README that comes with cracklib for more
+ information.  You then specify the location of these
+ dictionary files in the kdc.conf file on your KDC with
+ the dict_file specification. You specify the same thing
+ there as you did in the Cracklib Makefile for DICTPATH.
+ 
+ So if you install the dictionary files in /usr/dict/
+ (i.e. /usr/dict/pw_dict.hwm, /usr/dict/pw_dict.pwd,
+ /usr/dict/pw_dict.pwi), then your kdc.conf would look
+ like:
+ 
+ 
+ [realms]
+     YOUR.REALM = {
+          < ... >
+          dict_file = /usr/dict/pw_dict
+          < ... >
+     }
+ 
+ =======
+ CAVEATS
+ =======
+ 
+  -Note that the Kerberos code will only do a dictionary check
+ on a passwd if the principal has a policy. So you must set a
+ principal's policy if you want their passwords check with
+ CrackLib.
+ 
+  -Note that because the Kerberos code that does dictionary checking
+ does not have any clue as to who the principal is, it cannot check
+ for passwords based off the principal name.
+ 
+  -Note that the way of configuring cracklib has changed from previous releases
+ (you used to specify the location of the library, but now you specify the
+ location of the source code).
+ 
+ ======
+ THANKS
+ ======
+ 
+ Thanks should go to Von Welch at NCSA for originally doing this code, and
+ to Matt Crawford of Fermilab for cleaning up the build process.
Index: krb5/lib/kadm5/unit-test/.cvsignore
diff -c /dev/null krb5/lib/kadm5/unit-test/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:26 2003
--- krb5/lib/kadm5/unit-test/.cvsignore	Thu Jun  5 10:39:28 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kadm5/unit-test/configure.in
diff -c krb5/lib/kadm5/unit-test/configure.in:1.1.1.1 krb5/lib/kadm5/unit-test/configure.in:removed
*** krb5/lib/kadm5/unit-test/configure.in:1.1.1.1	Mon Jun  2 17:56:11 1997
--- krb5/lib/kadm5/unit-test/configure.in	Sun Mar 16 20:22:26 2003
***************
*** 1,22 ****
- AC_INIT(init-test.c)
- CONFIG_RULES
- AC_CANONICAL_HOST
- dnl The following are tests for the presence of programs required for testing 
- AC_CHECK_PROG(RUNTEST,runtest,runtest)
- AC_CHECK_PROG(PERL,perl,perl)
- AC_KRB5_TCL	
- if test "$PERL" = perl -a "$RUNTEST" = runtest -a "$TCL_LIB" != ""; then
-  	DO_TEST=ok
- fi
- AC_SUBST(DO_TEST) 
- dnl
- USE_KADMCLNT_LIBRARY
- USE_GSSAPI_LIBRARY
- USE_KADMSRV_LIBRARY
- USE_GSSRPC_LIBRARY
- USE_DYN_LIBRARY
- USE_KDB5_LIBRARY
- USE_SS_LIBRARY
- V5_USE_SHARED_LIB
- KRB5_LIBRARIES
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/kdb/.cvsignore
diff -c /dev/null krb5/lib/kdb/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:27 2003
--- krb5/lib/kdb/.cvsignore	Thu Jun  5 10:39:30 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/kdb/configure.in
diff -c krb5/lib/kdb/configure.in:1.1.1.2 krb5/lib/kdb/configure.in:1.3
*** krb5/lib/kdb/configure.in:1.1.1.2	Fri Feb 22 16:34:14 2002
--- krb5/lib/kdb/configure.in	Sun Feb 24 23:00:00 2002
***************
*** 15,20 ****
--- 15,30 ----
  	LIBS="$LIBS -ldb"
  	;;
  esac
+ dnl
+ dnl --with-afs-name-change enables code that supports the case where
+ dnl the name of the realm (cell) changed when going from AFS to Kerberos 5
+ dnl
+ AC_ARG_WITH([afs-name-change],
+ [  -with-afs-name-change	Support an AFS cell with a different name],
+ if test "$withval" = yes; then
+ 	AC_DEFINE(CPW_PRESERVE_AFS_SALT)
+ fi)
+ dnl
  KRB5_RUN_FLAGS
  dnl The following is for check...
  KRB5_BUILD_PROGRAM
Index: krb5/lib/kdb/kdb_cpw.c
diff -c krb5/lib/kdb/kdb_cpw.c:1.1.1.2 krb5/lib/kdb/kdb_cpw.c:1.6
*** krb5/lib/kdb/kdb_cpw.c:1.1.1.2	Fri Feb 22 16:34:16 2002
--- krb5/lib/kdb/kdb_cpw.c	Mon Feb 25 22:29:01 2002
***************
*** 56,61 ****
--- 56,66 ----
  #include <stdio.h>
  #include <errno.h>
  
+ #ifdef CPW_PRESERVE_AFS_SALT
+ static char *default_afs_key_salt = NULL;
+ static char *afs_key_salt;
+ #endif
+ 
  static int
  get_key_data_kvno(context, count, data)
      krb5_context	  context;
***************
*** 378,394 ****
              key_salt.data.length = 0;
              key_salt.data.data = 0;
              break;
!     	case KRB5_KDB_SALTTYPE_AFS3: {
  #if 0
              krb5_data * saltdata;
              if (retval = krb5_copy_data(context, krb5_princ_realm(context,
  					db_entry->princ), &saltdata))
  	 	return(retval);
  
  	    key_salt.data = *saltdata;
  	    key_salt.data.length = -1; /*length actually used below...*/
  	    krb5_xfree(saltdata);
  #else
  	    /* Why do we do this? Well, the afs_mit_string_to_key needs to
  	       use strlen, and the realm is not NULL terminated.... */
  	    int slen = (*krb5_princ_realm(context,db_entry->princ)).length;
--- 383,431 ----
              key_salt.data.length = 0;
              key_salt.data.data = 0;
              break;
!     	case KRB5_KDB_SALTTYPE_AFS3:
  #if 0
              krb5_data * saltdata;
+ 	    char *terminated_string;
              if (retval = krb5_copy_data(context, krb5_princ_realm(context,
  					db_entry->princ), &saltdata))
  	 	return(retval);
  
  	    key_salt.data = *saltdata;
+ 	    /*
+ 	     * The krb5_string_to_key function expects a null-terminated realm
+ 	     * name.  Re-allocate storage with room for a terminator and
+ 	     * terminate the string.
+ 	     */
+ 	    if ((terminated_string = malloc(key_salt.data.length + 1)) == NULL)
+ 	    {
+ 		if (key_salt.data.data)
+ 		    free(key_salt.data.data);
+ 		krb5_xfree(saltdata);
+ 		return(ENOMEM);
+ 	    }
+ 	    memcpy(terminated_string, key_salt.data.data, key_salt.data.length);
+ 	    terminated_string[key_salt.data.length] = '\0';
+ 	    free(key_salt.data.data);
+ 	    key_salt.data.data = terminated_string;
  	    key_salt.data.length = -1; /*length actually used below...*/
  	    krb5_xfree(saltdata);
  #else
+ #ifdef CPW_PRESERVE_AFS_SALT
+ 	    /*
+ 	     * If a salt string for AFS was specified then use it instead
+ 	     * of calling krb5_princ_realm()
+ 	     */
+ 	if (afs_key_salt) {
+ 	    key_salt.data.data = strdup(afs_key_salt);
+ 	    if (!key_salt.data.data)
+ 		return ENOMEM; 
+ 
+ 	    key_salt.data.length = -1;
+ 		
+ 	} else
+ #endif /* CPW_PRESERVE_AFS_SALT */
+ 	{
  	    /* Why do we do this? Well, the afs_mit_string_to_key needs to
  	       use strlen, and the realm is not NULL terminated.... */
  	    int slen = (*krb5_princ_realm(context,db_entry->princ)).length;
***************
*** 418,425 ****
  	}
  
  	if (key_salt.data.length == -1)
! 	    key_salt.data.length = 
! 	      krb5_princ_realm(context, db_entry->princ)->length;
  
  	if (retval = krb5_dbekd_encrypt_key_data(context, master_key, &key,
  		     (const krb5_keysalt *)&key_salt,
--- 455,471 ----
  	}
  
  	if (key_salt.data.length == -1)
! #ifdef CPW_PRESERVE_AFS_SALT
! 	    /*
! 	     * Again, use specified salt string, if specified, instead
! 	     * of krb5_princ_realm().
! 	     */
! 	    if (afs_key_salt)
! 		key_salt.data.length = strlen(afs_key_salt);
! 	    else	
! #endif /* CPW_PRESERVE_AFS_SALT */
! 		key_salt.data.length = 
! 		    krb5_princ_realm(context, db_entry->princ)->length;
  
  	if (retval = krb5_dbekd_encrypt_key_data(context, master_key, &key,
  		     (const krb5_keysalt *)&key_salt,
***************
*** 469,474 ****
--- 515,582 ----
      db_entry->key_data = NULL;
      db_entry->n_key_data = 0;
  
+ #ifdef CPW_PRESERVE_AFS_SALT
+     /*
+      * See if the user has an old AFS key and if so then we'll use it's
+      * salt to salt their new AFS key.
+      *
+      * If the user doesn't have an old AFS key then check the krb5.conf
+      * file for a default string to use. If it's there then use it.
+      *
+      * Otherwise then just leave afs_key_salt NULL and the default will
+      * be used.
+      *
+      */
+     {
+ 	int i;
+ 
+ 	afs_key_salt = NULL;
+ 
+ 	/* Check for an old AFS key */
+ 	for (i = 0; i < key_data_count; i++) {
+ 	    if ((key_data[i].key_data_type[1] == KRB5_KDB_SALTTYPE_AFS3) &&
+ 		key_data[i].key_data_length[1]) {
+ 
+ 		int len = key_data[i].key_data_length[1];
+ 		
+ 		/*
+ 		 * We need to copy out the contents and terminate it with
+ 		 * a null, since it's not guarenteed to be null
+ 		 * terminated as it is.
+ 		 */
+ 		afs_key_salt = malloc(len + 1);
+ 
+ 		if (!afs_key_salt)
+ 		    return ENOMEM;	
+ 
+ 		memcpy(afs_key_salt, key_data[i].key_data_contents[1], len);
+ 		afs_key_salt[len] = '\0';
+ 	    }
+ 	}
+ 
+ 	if (!afs_key_salt) {
+ 	    /* Check for default in krb5.conf */
+ 	    const char *names[3];
+ 	    char **values = NULL;
+ 
+ 	    names[0] = "kdc";
+ 	    names[1] = "afs_salt";
+ 	    names[2] = NULL;
+ 
+ 	    retval = profile_get_values(context->profile, names, &values);
+ 	    if (retval == 0 && values && values[0])
+ 		afs_key_salt = strdup(values[0]);
+ 
+ 	    if (values) {
+ 		char **cpp;
+ 		for (cpp = values; *cpp; cpp++)
+ 			free(*cpp);
+ 		free(values);
+ 	    }
+ 	}
+     }
+ #endif /* CPW_PRESERVE_AFS_SALT */
+ 
      /* increment the kvno.  if the requested kvno is too small, 
         increment the old kvno */
      if (new_kvno < old_kvno+1)
***************
*** 495,500 ****
--- 603,614 ----
      } else {
  	cleanup_key_data(context, key_data_count, key_data);
      }
+ #ifdef CPW_PRESERVE_AFS_SALT
+     if (afs_key_salt) {
+ 	free(afs_key_salt);
+ 	afs_key_salt = NULL;
+     }
+ #endif
      return(retval);
  }
  
Index: krb5/lib/krb4/.cvsignore
diff -c /dev/null krb5/lib/krb4/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:27 2003
--- krb5/lib/krb4/.cvsignore	Thu Jun  5 10:39:31 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb4/g_krbrlm.c
diff -c krb5/lib/krb4/g_krbrlm.c:1.1.1.3 krb5/lib/krb4/g_krbrlm.c:1.4
*** krb5/lib/krb4/g_krbrlm.c:1.1.1.3	Fri Feb 22 16:35:33 2002
--- krb5/lib/krb4/g_krbrlm.c	Fri Feb 22 19:12:59 2002
***************
*** 12,17 ****
--- 12,18 ----
  #include <stdio.h>
  #include "krb.h"
  #include <string.h>
+ #include "k5-int.h"
  
  /*
   * krb_get_lrealm takes a pointer to a string, and a number, n.  It fills
***************
*** 44,51 ****
      cnffile = krb__get_cnffile();
      if (!cnffile) {
  	if (n == 1) {
! 	    (void) strncpy(r, KRB_REALM, REALM_SZ);
  	    r[REALM_SZ - 1] = '\0';
  	    return(KSUCCESS);
  	}
  	else
--- 45,69 ----
      cnffile = krb__get_cnffile();
      if (!cnffile) {
  	if (n == 1) {
! 	    krb5_context context;
! 	    krb5_error_code retcode;
! 	    char *realm = NULL;
! 
! 	    retcode = krb5_init_context(&context);
! 
! 	    if (retcode || krb5_get_default_realm(context, &realm)) {
! 	        (void) strncpy(r, KRB_REALM, REALM_SZ);
! 	    } else {
! 		(void) strncpy(r, realm, REALM_SZ);
! 	    }
! 
  	    r[REALM_SZ - 1] = '\0';
+ 
+ 	    if (realm)
+ 		free(realm);
+ 
+ 	    if (! retcode)
+ 	        krb5_free_context(context);
  	    return(KSUCCESS);
  	}
  	else
Index: krb5/lib/krb4/kerberos.def
diff -c krb5/lib/krb4/kerberos.def:1.1.1.1 krb5/lib/krb4/kerberos.def:removed
*** krb5/lib/krb4/kerberos.def:1.1.1.1	Mon Jun  2 17:56:24 1997
--- krb5/lib/krb4/kerberos.def	Sun Mar 16 20:22:27 2003
***************
*** 1,68 ****
- ;-----------------------------
- ;   KERBEROS.DEF - module definition file
- ;-----------------------------
- 
- LIBRARY   KERBEROS
- DESCRIPTION 'DLL for Kerberos support'
- EXETYPE   WINDOWS
- CODE	  PRELOAD MOVEABLE DISCARDABLE
- DATA	  PRELOAD MOVEABLE SINGLE
- HEAPSIZE  8192
- 
- EXPORTS
- 	WEP @1 RESIDENTNAME
- 	LIBMAIN				@2
- 
- 	DES_CBC_ENCRYPT			@3
- 	DES_KEY_SCHED 			@4
- 	DES_STRING_TO_KEY 		@5
- 	DEST_TKT			@6
- 	KNAME_PARSE			@7
- 	KRB_CHECK_AUTH			@8
- 	KRB_END_SESSION			@9
- 	KRB_GET_ADMHST			@10
- 	KRB_GET_CRED			@11
- 	KRB_GET_DEFAULT_USER		@12
- 	KRB_GET_ERR_TEXT		@14
- 	KRB_GET_LREALM			@15
- 	KRB_GET_PHOST			@16
- 	KRB_GET_PW_IN_TKT		@17
- 	KRB_MK_AUTH			@18
- 	KRB_MK_PRIV			@19
- 	KRB_MK_REQ			@20
- 	KRB_RD_PRIV			@21
- 	KRB_REALMOFHOST			@22
- 	KRB_SAVE_CREDENTIALS		@23
- 	KRB_START_SESSION		@24
- 	KRB_GET_PW_IN_TKT_PREAUTH	@25
- 	KRB_GET_NOTIFICATION_MESSAGE	@26
- 	KADM_CHANGE_PW2			@27
- 	KADM_INIT_LINK			@28
- 	KADM_GET_ERR_TEXT		@29
- 	KADM_CHANGE_PW			@30
- 	DES_ECB_ENCRYPT			@31
- 	DES_PCBC_ENCRYPT		@32
- 	DES_IS_WEAK_KEY			@33
- 	DES_FIXUP_KEY_PARITY		@34
- 	DES_CHECK_KEY_PARITY		@35
- 	IN_TKT				@36
- 	KRB_DELETE_CRED			@37
- 	KRB_GET_KRBHST			@38
- 	KRB_GET_NTH_CRED		@39
- 	KRB_GET_NUM_CRED		@40
- 	KRB_GET_TF_FULLNAME		@41
- 	KRB_GET_TICKET_FOR_SERVICE	@42
- 	KRB_MK_ERR			@43
- 	KRB_MK_SAFE			@44
- 	KRB_RD_ERR			@45
- 	KRB_RD_SAFE			@46
- 	KRB_SET_DEFAULT_USER		@47
- 	KSTREAM_CREATE_FROM_FD		@48
- 	KSTREAM_CREATE_RLOGIN_FROM_FD	@49
- 	KSTREAM_CREATE_RCP_FROM_FD	@50
- 	KSTREAM_WRITE			@51
- 	KSTREAM_READ			@52
- 	KSTREAM_FLUSH			@53
- 	KSTREAM_DESTROY			@54
- 	KSTREAM_SET_BUFFER_MODE		@55
- 
--- 0 ----
Index: krb5/lib/krb4/tf_util.c
diff -c krb5/lib/krb4/tf_util.c:1.1.1.3 krb5/lib/krb4/tf_util.c:1.4
*** krb5/lib/krb4/tf_util.c:1.1.1.3	Fri Feb 22 16:35:49 2002
--- krb5/lib/krb4/tf_util.c	Fri Feb 22 19:13:01 2002
***************
*** 709,715 ****
      long    issue_date;		/* The issue time */
  {
  
-     off_t   lseek();
      int     count;		/* count for write */
  #ifdef TKT_SHMEM
      int	    *skey_check;
--- 709,714 ----
***************
*** 721,727 ****
  	  return TKT_FIL_INI;
      }
      /* Find the end of the ticket file */
!     (void) lseek(fd, (off_t)0, 2);
  #ifdef TKT_SHMEM
      /* scan to end of existing keys: pick first 'empty' slot.
         we assume that no real keys will be completely zero (it's a weak
--- 720,726 ----
  	  return TKT_FIL_INI;
      }
      /* Find the end of the ticket file */
!     (void) lseek(fd, 0, SEEK_END);
  #ifdef TKT_SHMEM
      /* scan to end of existing keys: pick first 'empty' slot.
         we assume that no real keys will be completely zero (it's a weak
Index: krb5/lib/krb4/winsock.def
diff -c krb5/lib/krb4/winsock.def:1.1.1.1 krb5/lib/krb4/winsock.def:removed
*** krb5/lib/krb4/winsock.def:1.1.1.1	Mon Jun  2 17:56:37 1997
--- krb5/lib/krb4/winsock.def	Sun Mar 16 20:22:28 2003
***************
*** 1,90 ****
- ;  
- ;         File: winsock.def 
- ;       System: MS-Windows 3.x 
- ;      Summary: Module definition file for Windows Sockets DLL.  
- ;  
- ;	This file is from
- ;  ftp://sunsite.unc.edu/pub/micro/pc-stuff/ms-windows/winsock/winsock-1.1
- ;	except that we made all the routine names uppercase, to match what
- ;	MicroSoft C does when you declare an interface routine PASCAL
- ;	(the way all these routines are declared in .../include/winsock.h).
- ;
- 
- LIBRARY         WINSOCK         ; Application's module name 
- 
- DESCRIPTION     'BSD Socket API for Windows' 
- 
- EXETYPE         WINDOWS         ; required for all windows applications 
- 
- STUB            'WINSTUB.EXE'   ; generates error message if application 
-                                 ; is run without Windows 
- 
- ;CODE can be FIXED in memory because of potential upcalls 
- CODE            PRELOAD         FIXED 
- 
- ;DATA must be SINGLE and at a FIXED location since this is a DLL 
- DATA            PRELOAD         FIXED           SINGLE
- 
- HEAPSIZE        1024 
- STACKSIZE       16384 
- 
- ; All functions that will be called by any Windows routine 
- ; must be exported.  Any additional exports beyond those defined
- ; here must have ordinal numbers 1000 or above. 
- 
- EXPORTS 
-         ACCEPT                         @1 
-         BIND                           @2 
-         CLOSESOCKET                    @3 
-         CONNECT                        @4 
-         GETPEERNAME                    @5 
-         GETSOCKNAME                    @6 
-         GETSOCKOPT                     @7 
-         HTONL                          @8 
-         HTONS                          @9 
-         INET_ADDR                      @10 
-         INET_NTOA                      @11 
-         IOCTLSOCKET                    @12 
-         LISTEN                         @13 
-         NTOHL                          @14 
-         NTOHS                          @15 
-         RECV                           @16 
-         RECVFROM                       @17 
-         SELECT                         @18 
-         SEND                           @19 
-         SENDTO                         @20 
-         SETSOCKOPT                     @21 
-         SHUTDOWN                       @22 
-         SOCKET                         @23 
- 
-         GETHOSTBYADDR                  @51 
-         GETHOSTBYNAME                  @52 
-         GETPROTOBYNAME                 @53 
-         GETPROTOBYNUMBER               @54 
-         GETSERVBYNAME                  @55 
-         GETSERVBYPORT                  @56 
-         GETHOSTNAME                    @57
- 
-         WSAASYNCSELECT                 @101 
-         WSAASYNCGETHOSTBYADDR          @102 
-         WSAASYNCGETHOSTBYNAME          @103 
-         WSAASYNCGETPROTOBYNUMBER       @104 
-         WSAASYNCGETPROTOBYNAME         @105 
-         WSAASYNCGETSERVBYPORT          @106 
-         WSAASYNCGETSERVBYNAME          @107 
-         WSACANCELASYNCREQUEST          @108 
-         WSASETBLOCKINGHOOK             @109 
-         WSAUNHOOKBLOCKINGHOOK          @110 
-         WSAGETLASTERROR                @111 
-         WSASETLASTERROR                @112 
-         WSACANCELBLOCKINGCALL          @113 
-         WSAISBLOCKING                  @114 
-         WSASTARTUP                     @115 
-         WSACLEANUP                     @116 
- 
-         __WSAFDISSET                   @151 
- 
-         WEP                            @500    RESIDENTNAME 
- 
- ;eof 
- 
--- 0 ----
Index: krb5/lib/krb5/.cvsignore
diff -c /dev/null krb5/lib/krb5/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:28 2003
--- krb5/lib/krb5/.cvsignore	Thu Jun  5 10:39:34 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/configure.in
diff -c krb5/lib/krb5/configure.in:1.1.1.2 krb5/lib/krb5/configure.in:1.4
*** krb5/lib/krb5/configure.in:1.1.1.2	Fri Feb 22 16:35:53 2002
--- krb5/lib/krb5/configure.in	Thu Jan 16 15:42:48 2003
***************
*** 3,8 ****
--- 3,17 ----
  AC_PROG_INSTALL
  AC_PROG_AWK
  dnl
+ AC_ARG_ENABLE([k5login-dir],
+ [  --enable-k5login-dir=DIR   Look for .k5login files in DIR/username],[
+ if test X$enableval = Xyes; then
+ 	AC_MSG_ERROR(An argument to --enable-k5login-dir is required)
+ fi
+ if test X$enableval != Xno; then
+ 	AC_MSG_RESULT([Setting k5login directory to $enableval])
+ 	AC_DEFINE_UNQUOTED(KRB5_K5LOGIN_DIR, "$enableval")
+ fi])
  AC_CONST
  AC_TYPE_UID_T
  HAS_ANSI_VOLATILE
Index: krb5/lib/krb5/asn.1/.cvsignore
diff -c /dev/null krb5/lib/krb5/asn.1/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:28 2003
--- krb5/lib/krb5/asn.1/.cvsignore	Thu Jun  5 10:39:36 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/asn.1/KRB5-asn.py
diff -c krb5/lib/krb5/asn.1/KRB5-asn.py:1.1.1.2 krb5/lib/krb5/asn.1/KRB5-asn.py:1.3
*** krb5/lib/krb5/asn.1/KRB5-asn.py:1.1.1.2	Fri Feb 22 16:35:53 2002
--- krb5/lib/krb5/asn.1/KRB5-asn.py	Mon Oct  7 15:01:53 2002
***************
*** 368,380 ****
      sam-cksum[9]                Checksum OPTIONAL
  }
  
! -- these are [0].. [2] in the draft
! SAMFlags ::= BIT STRING {
!     use-sad-as-key(0),
!     send-encrypted-sad(1),
!     must-pk-encrypt-sad(2)
  }
  
  PA-SAM-RESPONSE ::= SEQUENCE {
      sam-type[0]                 INTEGER,
      sam-flags[1]                SAMFlags,
--- 368,399 ----
      sam-cksum[9]                Checksum OPTIONAL
  }
  
! PA-SAM-CHALLENGE-2 ::= SEQUENCE {
!     sam-body[0]                 PA-SAM-CHALLENGE-2-BODY,
!     sam-cksum[1]                SEQUENCE (1..MAX) OF Checksum,
!     ...
! }
! 
! PA-SAM-CHALLENGE-2-BODY ::= SEQUENCE {
!     sam-type[0]                 INTEGER,
!     sam-flags[1]                SAMFlags,
!     sam-type-name[2]            GeneralString OPTIONAL,
!     sam-track-id[3]             GeneralString OPTIONAL,
!     sam-challenge-label[4]      GeneralString OPTIONAL,
!     sam-challenge[5]            GeneralString OPTIONAL,
!     sam-response-prompt[6]      GeneralString OPTIONAL,
!     sam-pk-for-sad[7]           EncryptionKey OPTIONAL,
!     sam-nonce[8]                INTEGER,
!     sam-etype[9]		INTEGER,
!     ...
  }
  
+ -- these are [0].. [2] in the draft
+ SAMFlags ::= BIT STRING (SIZE (32..MAX))
+     -- use-sad-as-key(0)
+     -- send-encrypted-sad(1)
+     -- must-pk-encrypt-sad(2)
+ 
  PA-SAM-RESPONSE ::= SEQUENCE {
      sam-type[0]                 INTEGER,
      sam-flags[1]                SAMFlags,
***************
*** 388,393 ****
--- 407,422 ----
      sam-patimestamp[6]          KerberosTime OPTIONAL
  }
  
+ PA-SAM-RESPONSE-2 ::= SEQUENCE {
+     sam-type[0]                 INTEGER,
+     sam-flags[1]                SAMFlags,
+     sam-track-id[2]             GeneralString OPTIONAL,
+     sam-enc-nonce-or-sad[3]     EncryptedData,
+                                    -- PA-ENC-SAM-RESPONSE-ENC
+     sam-nonce[4]                INTEGER,
+     ...
+ }
+ 
  PA-ENC-SAM-KEY ::= SEQUENCE {
               sam-key[0]                 EncryptionKey
  }
***************
*** 397,401 ****
--- 426,436 ----
       sam-timestamp[1]           KerberosTime OPTIONAL,
       sam-usec[2]                INTEGER OPTIONAL,
       sam-passcode[3]            GeneralString OPTIONAL
+ }
+ 
+ PA-ENC-SAM-RESPONSE-ENC-2 ::= SEQUENCE {
+      sam-nonce[0]               INTEGER,
+      sam-sad[1]                 GeneralString OPTIONAL,
+      ...
  }
  END
Index: krb5/lib/krb5/asn.1/asn1_k_decode.c
diff -c krb5/lib/krb5/asn.1/asn1_k_decode.c:1.1.1.3 krb5/lib/krb5/asn.1/asn1_k_decode.c:1.3
*** krb5/lib/krb5/asn.1/asn1_k_decode.c:1.1.1.3	Fri Feb 22 16:35:57 2002
--- krb5/lib/krb5/asn.1/asn1_k_decode.c	Mon Oct  7 14:45:49 2002
***************
*** 723,728 ****
--- 723,735 ----
    cleanup();
  }
  
+ asn1_error_code asn1_decode_sequence_of_checksum(buf, val)
+      asn1buf * buf;
+      krb5_checksum *** val;
+ {
+   decode_array_body(krb5_checksum, asn1_decode_checksum);
+ }
+ 
  asn1_error_code asn1_decode_etype_info_entry(buf, val)
       asn1buf * buf;
       krb5_etype_info_entry * val;
***************
*** 808,813 ****
--- 815,866 ----
    }
    cleanup();
  }
+ asn1_error_code asn1_decode_sam_challenge_2(buf,val)
+      asn1buf * buf;
+      krb5_sam_challenge_2 *val;
+ {
+   setup();
+   { char *save, *end;
+     begin_structure();
+     if (tagnum != 0) return ASN1_MISSING_FIELD;
+     if (class != CONTEXT_SPECIFIC || construction != CONSTRUCTED) 
+       return ASN1_BAD_ID;
+     save = subbuf.next;
+     { sequence_of(&subbuf);
+       end_sequence_of(&subbuf);
+     }
+     end = subbuf.next;
+     if ((val->sam_challenge_2_body.data = (char *) malloc(end - save)) == NULL)
+ 	return ENOMEM;
+     val->sam_challenge_2_body.length = end - save;
+     memcpy(val->sam_challenge_2_body.data, save, end - save);
+     next_tag();
+     get_field(val->sam_cksum, 1, asn1_decode_sequence_of_checksum);
+     end_structure();
+   }
+   cleanup();
+ }
+ asn1_error_code asn1_decode_sam_challenge_2_body(buf,val)
+      asn1buf * buf;
+      krb5_sam_challenge_2_body *val;
+ {
+   setup();
+   { begin_structure();
+     get_field(val->sam_type,0,asn1_decode_int32);
+     get_field(val->sam_flags,1,asn1_decode_sam_flags);
+     opt_string(val->sam_type_name,2,asn1_decode_charstring);
+     opt_string(val->sam_track_id,3,asn1_decode_charstring);
+     opt_string(val->sam_challenge_label,4,asn1_decode_charstring);
+     opt_string(val->sam_challenge,5,asn1_decode_charstring);
+     opt_string(val->sam_response_prompt,6,asn1_decode_charstring);
+     opt_string(val->sam_pk_for_sad,7,asn1_decode_charstring);
+     get_field(val->sam_nonce,8,asn1_decode_int32);
+     get_field(val->sam_etype, 9, asn1_decode_int32);
+     end_structure();
+     val->magic = KV5M_SAM_CHALLENGE;
+   }
+   cleanup();
+ }
  asn1_error_code asn1_decode_enc_sam_key(buf, val)
       asn1buf * buf;
       krb5_sam_key * val;
***************
*** 838,843 ****
--- 891,910 ----
    cleanup();
  }
  
+ asn1_error_code asn1_decode_enc_sam_response_enc_2(buf, val)
+      asn1buf * buf;
+      krb5_enc_sam_response_enc_2 * val;
+ {
+   setup();
+   { begin_structure();
+     get_field(val->sam_nonce,0,asn1_decode_int32);
+     opt_string(val->sam_sad,1,asn1_decode_charstring);
+     end_structure();
+     val->magic = KV5M_ENC_SAM_RESPONSE_ENC_2;
+   }
+   cleanup();
+ }
+ 
  #define opt_encfield(fld,tag,fn) \
      if(tagnum == tag){ \
        get_field(fld,tag,fn); } \
***************
*** 862,867 ****
--- 929,951 ----
      get_field(val->sam_enc_nonce_or_ts,4,asn1_decode_encrypted_data);
      opt_field(val->sam_nonce,5,asn1_decode_int32,0);
      opt_field(val->sam_patimestamp,6,asn1_decode_kerberos_time,0);
+     end_structure();
+     val->magic = KV5M_SAM_RESPONSE;
+   }
+   cleanup();
+ }
+ 
+ asn1_error_code asn1_decode_sam_response_2(buf, val)
+      asn1buf * buf;
+      krb5_sam_response_2 * val;
+ {
+   setup();
+   { begin_structure();
+     get_field(val->sam_type,0,asn1_decode_int32);
+     get_field(val->sam_flags,1,asn1_decode_sam_flags);
+     opt_string(val->sam_track_id,2,asn1_decode_charstring);
+     get_field(val->sam_enc_nonce_or_sad,3,asn1_decode_encrypted_data);
+     get_field(val->sam_nonce,4,asn1_decode_int32);
      end_structure();
      val->magic = KV5M_SAM_RESPONSE;
    }
Index: krb5/lib/krb5/asn.1/asn1_k_decode.h
diff -c krb5/lib/krb5/asn.1/asn1_k_decode.h:1.1.1.2 krb5/lib/krb5/asn.1/asn1_k_decode.h:1.3
*** krb5/lib/krb5/asn.1/asn1_k_decode.h:1.1.1.2	Fri Feb 22 16:35:57 2002
--- krb5/lib/krb5/asn.1/asn1_k_decode.h	Mon Oct  7 14:45:49 2002
***************
*** 143,154 ****
--- 143,162 ----
  	PROTOTYPE((asn1buf *buf, krb5_etype_info_entry *val));
  asn1_error_code asn1_decode_sam_challenge
  	PROTOTYPE((asn1buf *buf, krb5_sam_challenge *val));
+ asn1_error_code asn1_decode_sam_challenge_2
+ 	PROTOTYPE((asn1buf *buf, krb5_sam_challenge_2 *val));
+ asn1_error_code asn1_decode_sam_challenge_2_body
+ 	PROTOTYPE((asn1buf *buf, krb5_sam_challenge_2_body *val));
  asn1_error_code asn1_decode_enc_sam_key
  	PROTOTYPE((asn1buf *buf, krb5_sam_key *val));
  asn1_error_code asn1_decode_enc_sam_response_enc
  	PROTOTYPE((asn1buf *buf, krb5_enc_sam_response_enc *val));
+ asn1_error_code asn1_decode_enc_sam_response_enc_2
+ 	PROTOTYPE((asn1buf *buf, krb5_enc_sam_response_enc_2 *val));
  asn1_error_code asn1_decode_sam_response
  	PROTOTYPE((asn1buf *buf, krb5_sam_response *val));
+ asn1_error_code asn1_decode_sam_response_2
+ 	PROTOTYPE((asn1buf *buf, krb5_sam_response_2 *val));
  asn1_error_code asn1_decode_predicted_sam_response
  	PROTOTYPE((asn1buf *buf, krb5_predicted_sam_response *val));
  
***************
*** 168,173 ****
--- 176,183 ----
  
  asn1_error_code asn1_decode_sequence_of_enctype
  	PROTOTYPE((asn1buf *buf, int *num, krb5_enctype **val));
+ asn1_error_code asn1_decode_sequence_of_checksum
+ 	PROTOTYPE((asn1buf *buf, krb5_checksum ***val));
  
  asn1_error_code asn1_decode_sequence_of_passwdsequence
  	PROTOTYPE((asn1buf *buf, passwd_phrase_element ***val));
Index: krb5/lib/krb5/asn.1/asn1_k_encode.c
diff -c krb5/lib/krb5/asn.1/asn1_k_encode.c:1.1.1.2 krb5/lib/krb5/asn.1/asn1_k_encode.c:1.3
*** krb5/lib/krb5/asn.1/asn1_k_encode.c:1.1.1.2	Fri Feb 22 16:35:58 2002
--- krb5/lib/krb5/asn.1/asn1_k_encode.c	Mon Oct  7 14:45:49 2002
***************
*** 677,682 ****
--- 677,703 ----
    asn1_cleanup();
  }
  
+ asn1_error_code asn1_encode_sequence_of_checksum(buf, val, retlen)
+      asn1buf * buf;
+      krb5_checksum ** val;
+      int * retlen;
+ {
+   asn1_setup();
+   int i;
+ 
+   if(val == NULL) return ASN1_MISSING_FIELD;
+ 
+   for (i=0; val[i] != NULL; i++);
+   for (i--; i>=0; i--){
+     retval = asn1_encode_checksum(buf,val[i],&length);
+     if(retval) return retval;
+     sum += length;
+   }
+   asn1_makeseq();
+ 
+   asn1_cleanup();
+ }
+ 
  asn1_error_code asn1_encode_kdc_req(msg_type, buf, val, retlen)
       int msg_type;
       asn1buf * buf;
***************
*** 892,897 ****
--- 913,964 ----
    asn1_cleanup();
  }
  
+ asn1_error_code asn1_encode_sam_challenge_2(buf, val, retlen)
+      asn1buf * buf;
+      const krb5_sam_challenge_2 * val;
+      int * retlen;
+ {
+   asn1_setup();
+ 
+   if ( (!val) || (!val->sam_cksum) || (!val->sam_cksum[0]))
+ 	return ASN1_MISSING_FIELD;
+ 
+   asn1_addfield(val->sam_cksum, 1, asn1_encode_sequence_of_checksum);
+   asn1buf_insert_octetstring(buf, val->sam_challenge_2_body.length,
+ 			     val->sam_challenge_2_body.data);
+   sum += val->sam_challenge_2_body.length;
+   retval = asn1_make_etag(buf, CONTEXT_SPECIFIC, 0,
+ 			  val->sam_challenge_2_body.length, &length);
+   if(retval) return retval;
+   sum += length;
+ 
+   asn1_makeseq();
+   asn1_cleanup();
+ }
+ 
+ asn1_error_code asn1_encode_sam_challenge_2_body(buf, val, retlen)
+      asn1buf * buf;
+      const krb5_sam_challenge_2_body * val;
+      int * retlen;
+ {
+   asn1_setup();
+ 
+   asn1_addfield(val->sam_etype, 9, asn1_encode_integer);
+   asn1_addfield(val->sam_nonce,8,asn1_encode_integer);
+   add_optstring(val->sam_pk_for_sad,7,asn1_encode_octetstring);
+   add_optstring(val->sam_response_prompt,6,asn1_encode_charstring);
+   add_optstring(val->sam_challenge,5,asn1_encode_charstring);
+   add_optstring(val->sam_challenge_label,4,asn1_encode_charstring);
+   add_optstring(val->sam_track_id,3,asn1_encode_charstring);
+   add_optstring(val->sam_type_name,2,asn1_encode_charstring);
+ 
+   asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags);
+   asn1_addfield(val->sam_type,0,asn1_encode_integer);
+ 
+   asn1_makeseq();
+   asn1_cleanup();
+ }
+ 
  asn1_error_code asn1_encode_sam_key(buf, val, retlen)
       asn1buf * buf;
       const krb5_sam_key * val;
***************
*** 922,927 ****
--- 989,1008 ----
    asn1_cleanup();
  }
  
+ asn1_error_code asn1_encode_enc_sam_response_enc_2(buf, val, retlen)
+      asn1buf * buf;
+      const krb5_enc_sam_response_enc_2 * val;
+      int * retlen;
+ {
+   asn1_setup();
+   add_optstring(val->sam_sad,1,asn1_encode_charstring);
+   asn1_addfield(val->sam_nonce,0,asn1_encode_integer);
+ 
+   asn1_makeseq();
+ 
+   asn1_cleanup();
+ }
+ 
  asn1_error_code asn1_encode_sam_response(buf, val, retlen)
       asn1buf * buf;
       const krb5_sam_response * val;
***************
*** 936,941 ****
--- 1017,1040 ----
    asn1_addfield(&(val->sam_enc_nonce_or_ts),4,asn1_encode_encrypted_data);
    if (val->sam_enc_key.ciphertext.length)
      asn1_addfield(&(val->sam_enc_key),3,asn1_encode_encrypted_data);
+   add_optstring(val->sam_track_id,2,asn1_encode_charstring);
+   asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags);
+   asn1_addfield(val->sam_type,0,asn1_encode_integer);
+ 
+   asn1_makeseq();
+ 
+   asn1_cleanup();
+ }
+ 
+ asn1_error_code asn1_encode_sam_response_2(buf, val, retlen)
+      asn1buf * buf;
+      const krb5_sam_response_2 * val;
+      int * retlen;
+ {
+   asn1_setup();
+ 
+   asn1_addfield(val->sam_nonce,4,asn1_encode_integer);
+   asn1_addfield(&(val->sam_enc_nonce_or_sad),3,asn1_encode_encrypted_data);
    add_optstring(val->sam_track_id,2,asn1_encode_charstring);
    asn1_addfield(val->sam_flags,1,asn1_encode_sam_flags);
    asn1_addfield(val->sam_type,0,asn1_encode_integer);
Index: krb5/lib/krb5/asn.1/asn1_k_encode.h
diff -c krb5/lib/krb5/asn.1/asn1_k_encode.h:1.1.1.2 krb5/lib/krb5/asn.1/asn1_k_encode.h:1.3
*** krb5/lib/krb5/asn.1/asn1_k_encode.h:1.1.1.2	Fri Feb 22 16:35:58 2002
--- krb5/lib/krb5/asn.1/asn1_k_encode.h	Mon Oct  7 14:45:49 2002
***************
*** 69,74 ****
--- 69,75 ----
      asn1_encode_sequence_of_pa_data
      asn1_encode_sequence_of_ticket
      asn1_encode_sequence_of_enctype
+     asn1_encode_sequence_of_checksum
      asn1_encode_sequence_of_krb_cred_info
  */
  
***************
*** 184,189 ****
--- 185,193 ----
  		   const int len, const krb5_enctype *val,
  		   int *retlen));
  
+ asn1_error_code asn1_encode_sequence_of_checksum
+ 	PROTOTYPE((asn1buf *buf, krb5_checksum **val, int * retlen));
+ 
  asn1_error_code asn1_encode_kdc_req
  	PROTOTYPE((int msg_type,
  		   asn1buf *buf,
***************
*** 234,239 ****
--- 238,249 ----
  asn1_error_code asn1_encode_sam_challenge
  	PROTOTYPE((asn1buf *buf, const krb5_sam_challenge * val, int *retlen));
  
+ asn1_error_code asn1_encode_sam_challenge_2
+ 	PROTOTYPE((asn1buf *buf, const krb5_sam_challenge_2 * val, int *retlen));
+ 
+ asn1_error_code asn1_encode_sam_challenge_2_body
+ 	PROTOTYPE((asn1buf *buf, const krb5_sam_challenge_2_body * val, int *retlen));
+ 
  asn1_error_code asn1_encode_sam_key
  	PROTOTYPE((asn1buf *buf, const krb5_sam_key *val, int *retlen));
  
***************
*** 241,248 ****
--- 251,265 ----
  	PROTOTYPE((asn1buf *buf, const krb5_enc_sam_response_enc *val,
  		   int *retlen));
  
+ asn1_error_code asn1_encode_enc_sam_response_enc_2
+ 	PROTOTYPE((asn1buf *buf, const krb5_enc_sam_response_enc_2 *val,
+ 		   int *retlen));
+ 
  asn1_error_code asn1_encode_sam_response
  	PROTOTYPE((asn1buf *buf, const krb5_sam_response *val, int *retlen));
+ 
+ asn1_error_code asn1_encode_sam_response_2
+ 	PROTOTYPE((asn1buf *buf, const krb5_sam_response_2 *val, int *retlen));
  
  asn1_error_code asn1_encode_predicted_sam_response
  	PROTOTYPE((asn1buf *buf, const krb5_predicted_sam_response *val, 
Index: krb5/lib/krb5/asn.1/configure.in
diff -c krb5/lib/krb5/asn.1/configure.in:1.1.1.1 krb5/lib/krb5/asn.1/configure.in:removed
*** krb5/lib/krb5/asn.1/configure.in:1.1.1.1	Mon Jun  2 17:57:06 1997
--- krb5/lib/krb5/asn.1/configure.in	Sun Mar 16 20:22:28 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/asn.1/krb5_decode.c
diff -c krb5/lib/krb5/asn.1/krb5_decode.c:1.1.1.2 krb5/lib/krb5/asn.1/krb5_decode.c:1.5
*** krb5/lib/krb5/asn.1/krb5_decode.c:1.1.1.2	Fri Feb 22 16:36:01 2002
--- krb5/lib/krb5/asn.1/krb5_decode.c	Mon Oct  7 14:45:49 2002
***************
*** 813,818 ****
--- 813,844 ----
    cleanup(free);
  }
  
+ krb5_error_code decode_krb5_sam_challenge_2(code, rep)
+      const krb5_data * code;
+      krb5_sam_challenge_2 **rep;
+ {
+   setup_buf_only();
+   alloc_field(*rep,krb5_sam_challenge_2);
+ 
+   retval = asn1_decode_sam_challenge_2(&buf,*rep);
+   if(retval) clean_return(retval);
+ 
+   cleanup(free);
+ }
+ 
+ krb5_error_code decode_krb5_sam_challenge_2_body(code, rep)
+     const krb5_data * code;
+     krb5_sam_challenge_2_body **rep;
+ {
+   setup_buf_only();
+   alloc_field(*rep, krb5_sam_challenge_2_body);
+ 
+   retval = asn1_decode_sam_challenge_2_body(&buf, *rep);
+   if(retval) clean_return(retval);
+ 
+   cleanup(free);
+ }
+ 
  krb5_error_code decode_krb5_enc_sam_key(code, rep)
       const krb5_data * code;
       krb5_sam_key **rep;
***************
*** 839,844 ****
--- 865,883 ----
    cleanup(free);
  }
  
+ krb5_error_code decode_krb5_enc_sam_response_enc_2(code, rep)
+      const krb5_data * code;
+      krb5_enc_sam_response_enc_2 **rep;
+ {
+   setup_buf_only();
+   alloc_field(*rep,krb5_enc_sam_response_enc_2);
+ 
+   retval = asn1_decode_enc_sam_response_enc_2(&buf,*rep);
+   if(retval) clean_return(retval);
+ 
+   cleanup(free);
+ }
+ 
  krb5_error_code decode_krb5_sam_response(code, rep)
       const krb5_data * code;
       krb5_sam_response **rep;
***************
*** 852,857 ****
--- 891,909 ----
    cleanup(free);
  }
  
+ krb5_error_code decode_krb5_sam_response_2(code, rep)
+      const krb5_data * code;
+      krb5_sam_response_2 **rep;
+ {
+   setup_buf_only();
+   alloc_field(*rep,krb5_sam_response_2);
+ 
+   retval = asn1_decode_sam_response_2(&buf,*rep);
+   if(retval) clean_return(retval);
+ 
+   cleanup(free);
+ }
+ 
  krb5_error_code decode_krb5_predicted_sam_response(code, rep)
       const krb5_data * code;
       krb5_predicted_sam_response **rep;
***************
*** 865,867 ****
--- 917,931 ----
    cleanup(free);
  }
  
+ krb5_error_code decode_krb5_principal(code, rep)
+      const krb5_data * code;
+      krb5_principal * rep;
+ {
+   setup();
+   alloc_field(*rep, krb5_principal_data);
+   { begin_structure();
+     get_field(*rep, 0, asn1_decode_realm);
+     get_field(*rep, 1, asn1_decode_principal_name);
+     end_structure(); }
+   cleanup(free);
+ }
Index: krb5/lib/krb5/asn.1/krb5_encode.c
diff -c krb5/lib/krb5/asn.1/krb5_encode.c:1.1.1.2 krb5/lib/krb5/asn.1/krb5_encode.c:1.5
*** krb5/lib/krb5/asn.1/krb5_encode.c:1.1.1.2	Fri Feb 22 16:36:02 2002
--- krb5/lib/krb5/asn.1/krb5_encode.c	Mon Oct  7 14:45:49 2002
***************
*** 807,812 ****
--- 807,834 ----
    krb5_cleanup();
  }
  
+ krb5_error_code encode_krb5_sam_challenge_2(rep, code)
+      const krb5_sam_challenge_2 * rep;
+      krb5_data ** code;
+ {
+   krb5_setup();
+   retval = asn1_encode_sam_challenge_2(buf,rep,&length);
+   if(retval) return retval;
+   sum += length;
+   krb5_cleanup();
+ }
+ 
+ krb5_error_code encode_krb5_sam_challenge_2_body(rep, code)
+      const krb5_sam_challenge_2_body * rep;
+      krb5_data ** code;
+ {
+   krb5_setup();
+   retval = asn1_encode_sam_challenge_2_body(buf,rep,&length);
+   if(retval) return retval;
+   sum += length;
+   krb5_cleanup();
+ }
+ 
  krb5_error_code encode_krb5_sam_key(rep, code)
       const krb5_sam_key * rep;
       krb5_data ** code;
***************
*** 829,834 ****
--- 851,867 ----
    krb5_cleanup();
  }
  
+ krb5_error_code encode_krb5_enc_sam_response_enc_2(rep, code)
+      const krb5_enc_sam_response_enc_2 * rep;
+      krb5_data ** code;
+ {
+   krb5_setup();
+   retval = asn1_encode_enc_sam_response_enc_2(buf,rep,&length);
+   if(retval) return retval;
+   sum += length;
+   krb5_cleanup();
+ }
+ 
  krb5_error_code encode_krb5_sam_response(rep, code)
       const krb5_sam_response * rep;
       krb5_data ** code;
***************
*** 840,845 ****
--- 873,889 ----
    krb5_cleanup();
  }
  
+ krb5_error_code encode_krb5_sam_response_2(rep, code)
+      const krb5_sam_response_2 * rep;
+      krb5_data ** code;
+ {
+   krb5_setup();
+   retval = asn1_encode_sam_response_2(buf,rep,&length);
+   if(retval) return retval;
+   sum += length;
+   krb5_cleanup();
+ }
+ 
  krb5_error_code encode_krb5_predicted_sam_response(rep, code)
       const krb5_predicted_sam_response * rep;
       krb5_data ** code;
***************
*** 848,852 ****
--- 892,910 ----
    retval = asn1_encode_predicted_sam_response(buf,rep,&length);
    if(retval) return retval;
    sum += length;
+   krb5_cleanup();
+ }
+ 
+ krb5_error_code encode_krb5_principal(rep, code)
+      const krb5_principal rep;
+      krb5_data ** code;
+ {
+   krb5_setup();
+ 
+   krb5_addfield(rep, 1, asn1_encode_principal_name);
+   krb5_addfield(rep, 0, asn1_encode_realm);
+ 
+   krb5_makeseq();
+ 
    krb5_cleanup();
  }
Index: krb5/lib/krb5/ccache/.cvsignore
diff -c /dev/null krb5/lib/krb5/ccache/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:28 2003
--- krb5/lib/krb5/ccache/.cvsignore	Thu Jun  5 10:39:37 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/ccache/configure.in
diff -c krb5/lib/krb5/ccache/configure.in:1.1.1.1 krb5/lib/krb5/ccache/configure.in:removed
*** krb5/lib/krb5/ccache/configure.in:1.1.1.1	Mon Jun  2 17:57:08 1997
--- krb5/lib/krb5/ccache/configure.in	Sun Mar 16 20:22:29 2003
***************
*** 1,10 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- CONFIG_DIRS(stdio file memory)
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- DO_SUBDIRS
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([$(OBJS)])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/ccache/file/.cvsignore
diff -c /dev/null krb5/lib/krb5/ccache/file/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:29 2003
--- krb5/lib/krb5/ccache/file/.cvsignore	Thu Jun  5 10:39:38 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/ccache/file/configure.in
diff -c krb5/lib/krb5/ccache/file/configure.in:1.1.1.1 krb5/lib/krb5/ccache/file/configure.in:removed
*** krb5/lib/krb5/ccache/file/configure.in:1.1.1.1	Mon Jun  2 17:57:09 1997
--- krb5/lib/krb5/ccache/file/configure.in	Sun Mar 16 20:22:29 2003
***************
*** 1,7 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_HAVE_HEADERS(unistd.h)
- AC_FUNC_CHECK(flock,AC_DEFINE(HAVE_FLOCK))
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/ccache/memory/.cvsignore
diff -c /dev/null krb5/lib/krb5/ccache/memory/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:29 2003
--- krb5/lib/krb5/ccache/memory/.cvsignore	Thu Jun  5 10:39:39 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/ccache/memory/configure.in
diff -c krb5/lib/krb5/ccache/memory/configure.in:1.1.1.1 krb5/lib/krb5/ccache/memory/configure.in:removed
*** krb5/lib/krb5/ccache/memory/configure.in:1.1.1.1	Mon Jun  2 17:57:14 1997
--- krb5/lib/krb5/ccache/memory/configure.in	Sun Mar 16 20:22:29 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/ccache/stdio/.cvsignore
diff -c /dev/null krb5/lib/krb5/ccache/stdio/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:29 2003
--- krb5/lib/krb5/ccache/stdio/.cvsignore	Thu Jun  5 10:39:41 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/ccache/stdio/configure.in
diff -c krb5/lib/krb5/ccache/stdio/configure.in:1.1.1.1 krb5/lib/krb5/ccache/stdio/configure.in:removed
*** krb5/lib/krb5/ccache/stdio/configure.in:1.1.1.1	Mon Jun  2 17:57:18 1997
--- krb5/lib/krb5/ccache/stdio/configure.in	Sun Mar 16 20:22:29 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/error_tables/.cvsignore
diff -c /dev/null krb5/lib/krb5/error_tables/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:29 2003
--- krb5/lib/krb5/error_tables/.cvsignore	Thu Jun  5 10:39:42 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/error_tables/configure.in
diff -c krb5/lib/krb5/error_tables/configure.in:1.1.1.1 krb5/lib/krb5/error_tables/configure.in:removed
*** krb5/lib/krb5/error_tables/configure.in:1.1.1.1	Mon Jun  2 17:57:22 1997
--- krb5/lib/krb5/error_tables/configure.in	Sun Mar 16 20:22:29 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_AWK
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/error_tables/krb5_err.et
diff -c krb5/lib/krb5/error_tables/krb5_err.et:1.1.1.2 krb5/lib/krb5/error_tables/krb5_err.et:1.2
*** krb5/lib/krb5/error_tables/krb5_err.et:1.1.1.2	Fri Feb 22 16:37:02 2002
--- krb5/lib/krb5/error_tables/krb5_err.et	Thu Aug 15 13:46:30 2002
***************
*** 170,176 ****
  error_code KRB5PLACEHOLD_126,	"KRB5 error code 126"
  error_code KRB5PLACEHOLD_127,	"KRB5 error code 127"
  
! error_code KRB5_ERR_RCSID,	"$Id: krb5_err.et,v 1.1.1.2 2002/02/22 21:37:02 kenh Exp $"
  
  error_code KRB5_LIBOS_BADLOCKFLAG,	"Invalid flag for file lock mode"
  error_code KRB5_LIBOS_CANTREADPWD,	"Cannot read password"
--- 170,176 ----
  error_code KRB5PLACEHOLD_126,	"KRB5 error code 126"
  error_code KRB5PLACEHOLD_127,	"KRB5 error code 127"
  
! error_code KRB5_ERR_RCSID,	"$Id: krb5_err.et,v 1.2 2002/08/15 17:46:30 kenh Exp $"
  
  error_code KRB5_LIBOS_BADLOCKFLAG,	"Invalid flag for file lock mode"
  error_code KRB5_LIBOS_CANTREADPWD,	"Cannot read password"
***************
*** 310,315 ****
--- 310,318 ----
  error_code KRB5_CONFIG_NODEFREALM,	"Configuration file does not specify default realm"
  
  error_code KRB5_SAM_UNSUPPORTED,  "Bad SAM flags in obtain_sam_padata"
+ error_code KRB5_SAM_INVALID_ETYPE,	"Invalid encryption type in SAM challenge"
+ error_code KRB5_SAM_NO_CHECKSUM,	"Missing checksum in SAM challenge"
+ error_code KRB5_SAM_BAD_CHECKSUM,	"Bad checksum in SAM challenge"
  error_code KRB5_KT_NAME_TOOLONG,	"Keytab name too long"
  error_code KRB5_KT_KVNONOTFOUND,	"Key version number for principal in key table is incorrect"
  error_code KRB5_APPL_EXPIRED,	"This application has expired"
Index: krb5/lib/krb5/error_tables/kv5m_err.et
diff -c krb5/lib/krb5/error_tables/kv5m_err.et:1.1.1.2 krb5/lib/krb5/error_tables/kv5m_err.et:1.2
*** krb5/lib/krb5/error_tables/kv5m_err.et:1.1.1.2	Fri Feb 22 16:37:02 2002
--- krb5/lib/krb5/error_tables/kv5m_err.et	Thu Aug 15 13:46:30 2002
***************
*** 76,84 ****
--- 76,87 ----
  error_code KV5M_CCACHE,		"Bad magic number for krb5_ccache structure"
  error_code KV5M_PREAUTH_OPS,	"Bad magic number for krb5_preauth_ops"
  error_code KV5M_SAM_CHALLENGE,	"Bad magic number for krb5_sam_challenge"
+ error_code KV5M_SAM_CHALLENGE_2,	"Bad magic number for krb5_sam_challenge_2"
  error_code KV5M_SAM_KEY,	"Bad magic number for krb5_sam_key"
  error_code KV5M_ENC_SAM_RESPONSE_ENC,	"Bad magic number for krb5_enc_sam_response_enc"
+ error_code KV5M_ENC_SAM_RESPONSE_ENC_2,	"Bad magic number for krb5_enc_sam_response_enc"
  error_code KV5M_SAM_RESPONSE,	"Bad magic number for krb5_sam_response"
+ error_code KV5M_SAM_RESPONSE_2,	"Bad magic number for krb5_sam_response 2"
  error_code KV5M_PREDICTED_SAM_RESPONSE,	"Bad magic number for krb5_predicted_sam_response"
  error_code KV5M_PASSWD_PHRASE_ELEMENT,	"Bad magic number for passwd_phrase_element"
  error_code KV5M_GSS_OID,	"Bad magic number for GSSAPI OID"
Index: krb5/lib/krb5/free/ChangeLog
diff -c krb5/lib/krb5/free/ChangeLog:1.1.1.1 krb5/lib/krb5/free/ChangeLog:removed
*** krb5/lib/krb5/free/ChangeLog:1.1.1.1	Mon Jun  2 17:57:22 1997
--- krb5/lib/krb5/free/ChangeLog	Sun Mar 16 20:22:30 2003
***************
*** 1,96 ****
- Fri Aug  2 14:03:44 1996  Barry Jaspan  <bjaspan@DUN-DUN-NOODLES>
- 
- 	* f_keyblock.c (krb5_free_keyblock_contents): added
-         krb5_free_keyblock_contents
- 
- Wed Nov  8 17:51:51 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* f_einfo.c (krb5_free_etype_info): Added new function to free a
- 		krb5_etype_info structure.
- 
- Fri Oct  6 22:03:59 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Remove ##DOS!include of config/windows.in.
- 		config/windows.in is now included by wconfig.
- 
- Mon Sep 25 16:57:16 1995  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* Makefile.in: Removed "foo:: foo-$(WHAT)" lines from the
- 		Makefile. 
- 
- Tue Sep 05 22:10:34 1995   Chris Provenzano (proven@mit.edu)
- 
-         * f_kdc_rq.c : Remove krb5_enctype references, and replace with
-                 krb5_keytype where appropriate
- 
- Fri Jun  9 19:34:18 1995    <tytso@rsx-11.mit.edu>
- 
- 	* configure.in: Remove standardized set of autoconf macros, which
- 		are now handled by CONFIG_RULES.
- 
- Fri May 26 20:20:10 1995  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* configure.in, Makefile.in: Add support for building shared libraries.
- 
- Thu Apr 13 15:49:16 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* *.[ch]: removed unneeded INTERFACE from non-api functions.
- 
- Fri Mar 17 19:45:01 1995  John Gilmore  (gnu at toad.com)
- 
- 	* Makefile.in (LDFLAGS):  Elim duplicate.
- 
- Wed Mar 15 12:21:24 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* f_cksum.c renamed to f_chksum.c because of module name conflicts
- 	   with crypto/des/f_cksum.
- 	* Makefile.in: reflected above name change.
- 
- Tue Mar 7 21:40:18 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Makefile.in: changed library name for the PC.
- 
- Tue Mar  7 19:53:33 1995  Mark Eichin  <eichin@cygnus.com>
- 
- 	* configure.in: take out ISODE_DEFS, ISODE_INCLUDE.
- 
- Wed Mar 1 16:00:00 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* f_princ.h: changed int to krb5_int32 for the PC.
- 
- Tue Feb 28 00:38:44 1995  John Gilmore  (gnu at toad.com)
- 
- 	* *.c:  Avoid <krb5/...> includes.
- 
- Tue Feb 21 23:39:19 1995  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* f_cred_enc.c (krb5_free_cred_enc_part): Remove call to xfree at
- 		the end.  This routine only frees the contents of
- 		the cred_enc_part structure.
- 
- Tue Feb 21 0:1:55 1995 Keith Vetter (keithv@fusion.com)
- 
- 	* Every C file (*.c): added windows INTERFACE keyword
-         * Makefile.in: made to work for PC
- 
- Fri Feb  3 01:45:04 1995  John Gilmore  <gnu@cygnus.com>
- 
- 	Rename files for DOS 8.3 uniqueness:
- 	* f_kdc_rep.c => f_kdc_rp.c
- 	* f_kdc_req.c => f_kdc_rq.c
- 	* f_ticket.c  => f_tckt.c
- 	* f_tickets.c => f_tckts.c
- 	* Makefile.in was updated to match.
- 
- Fri Jan 13 15:23:47 1995  Chris Provenzano (proven@mit.edu)
- 
-     * Added krb5_context to all krb5_routines
- 
- Thu Oct 13 17:24:51 1994  Theodore Y. Ts'o  (tytso@maytag)
- 
- 	* configure.in: Add ISODE_DEFS
- 
- Tue Oct  4 22:05:04 1994  Theodore Y. Ts'o  (tytso@dcl)
- 
- 	* f_princ.c (krb5_free_principal): Don't blow up if principal is NULL.
- 
--- 0 ----
Index: krb5/lib/krb5/free/Makefile.in
diff -c krb5/lib/krb5/free/Makefile.in:1.1.1.1 krb5/lib/krb5/free/Makefile.in:removed
*** krb5/lib/krb5/free/Makefile.in:1.1.1.1	Mon Jun  2 17:57:22 1997
--- krb5/lib/krb5/free/Makefile.in	Sun Mar 16 20:22:30 2003
***************
*** 1,91 ****
- CFLAGS = $(CCOPTS) $(DEFS)
- 
- ##DOSBUILDTOP = ..\..\..
- ##DOSLIBNAME=..\krb5.lib
- 
- .c.o:
- 	$(CC) $(CFLAGS) -c $(srcdir)/$*.c
- @SHARED_RULE@
- 
- OBJS=	\
- 	f_addr.$(OBJEXT)	\
- 	f_address.$(OBJEXT)	\
- 	f_ap_rep.$(OBJEXT)	\
- 	f_ap_req.$(OBJEXT)	\
- 	f_arep_enc.$(OBJEXT)	\
- 	f_authdata.$(OBJEXT)	\
- 	f_authent.$(OBJEXT)	\
- 	f_auth_cnt.$(OBJEXT)	\
- 	f_chksum.$(OBJEXT)	\
- 	f_creds.$(OBJEXT)	\
- 	f_cred_cnt.$(OBJEXT)	\
- 	f_enc_kdc.$(OBJEXT)	\
- 	f_enc_tkt.$(OBJEXT)	\
- 	f_einfo.$(OBJEXT)	\
- 	f_error.$(OBJEXT)	\
- 	f_kdc_rp.$(OBJEXT)	\
- 	f_kdc_rq.$(OBJEXT)	\
- 	f_keyblock.$(OBJEXT)	\
- 	f_last_req.$(OBJEXT)	\
- 	f_padata.$(OBJEXT)	\
- 	f_princ.$(OBJEXT)	\
- 	f_priv.$(OBJEXT)	\
- 	f_priv_enc.$(OBJEXT)	\
- 	f_safe.$(OBJEXT)	\
- 	f_tckt.$(OBJEXT)	\
- 	f_tckts.$(OBJEXT)	\
- 	f_tgt_cred.$(OBJEXT)	\
- 	f_tkt_auth.$(OBJEXT)	\
- 	f_pwd_data.$(OBJEXT)	\
- 	f_pwd_seq.$(OBJEXT)	\
- 	f_cred.$(OBJEXT)	\
- 	f_cred_enc.$(OBJEXT)
- 
- SRCS=	\
- 	$(srcdir)/f_addr.c	\
- 	$(srcdir)/f_address.c	\
- 	$(srcdir)/f_arep_enc.c	\
- 	$(srcdir)/f_ap_rep.c	\
- 	$(srcdir)/f_ap_req.c	\
- 	$(srcdir)/f_authdata.c	\
- 	$(srcdir)/f_authent.c	\
- 	$(srcdir)/f_auth_cnt.c	\
- 	$(srcdir)/f_chksum.c	\
- 	$(srcdir)/f_creds.c	\
- 	$(srcdir)/f_cred_cnt.c	\
- 	$(srcdir)/f_enc_kdc.c	\
- 	$(srcdir)/f_enc_tkt.c	\
- 	$(srcdir)/f_einfo.c	\
- 	$(srcdir)/f_error.c	\
- 	$(srcdir)/f_kdc_rp.c	\
- 	$(srcdir)/f_kdc_rq.c	\
- 	$(srcdir)/f_keyblock.c	\
- 	$(srcdir)/f_last_req.c	\
- 	$(srcdir)/f_padata.c	\
- 	$(srcdir)/f_princ.c	\
- 	$(srcdir)/f_priv.c	\
- 	$(srcdir)/f_priv_enc.c	\
- 	$(srcdir)/f_safe.c	\
- 	$(srcdir)/f_tckt.c	\
- 	$(srcdir)/f_tckts.c	\
- 	$(srcdir)/f_tgt_cred.c	\
- 	$(srcdir)/f_tkt_auth.c	\
- 	$(srcdir)/f_pwd_data.c	\
- 	$(srcdir)/f_pwd_seq.c	\
- 	$(srcdir)/f_cred.c	\
- 	$(srcdir)/f_cred_enc.c
- 
- all-unix:: shared $(OBJS)
- all-mac:: $(OBJS)
- all-windows:: $(OBJS)
- 
- shared:
- 	mkdir shared
- 
- clean-unix::
- 	$(RM) shared/*
- 
- clean-mac::
- clean-windows::
- 
- 
--- 0 ----
Index: krb5/lib/krb5/free/configure.in
diff -c krb5/lib/krb5/free/configure.in:1.1.1.1 krb5/lib/krb5/free/configure.in:removed
*** krb5/lib/krb5/free/configure.in:1.1.1.1	Mon Jun  2 17:57:22 1997
--- krb5/lib/krb5/free/configure.in	Sun Mar 16 20:22:30 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/free/f_addr.c
diff -c krb5/lib/krb5/free/f_addr.c:1.1.1.1 krb5/lib/krb5/free/f_addr.c:removed
*** krb5/lib/krb5/free/f_addr.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_addr.c	Sun Mar 16 20:22:30 2003
***************
*** 1,37 ****
- /*
-  * lib/krb5/free/f_addr.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_address()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_address(context, val)
-     krb5_context context;
-     krb5_address *val;
- {
-     if (val->contents)
- 	krb5_xfree(val->contents);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_address.c
diff -c krb5/lib/krb5/free/f_address.c:1.1.1.1 krb5/lib/krb5/free/f_address.c:removed
*** krb5/lib/krb5/free/f_address.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_address.c	Sun Mar 16 20:22:30 2003
***************
*** 1,43 ****
- /*
-  * lib/krb5/free/f_address.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_addresses()
-  */
- 
- #include "k5-int.h"
- 
- void INTERFACE
- krb5_free_addresses(context, val)
-     krb5_context context;
-     krb5_address **val;
- {
-     register krb5_address **temp;
- 
-     for (temp = val; *temp; temp++) {
- 	if ((*temp)->contents)
- 	    krb5_xfree((*temp)->contents);
- 	krb5_xfree(*temp);
-     }
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_ap_rep.c
diff -c krb5/lib/krb5/free/f_ap_rep.c:1.1.1.1 krb5/lib/krb5/free/f_ap_rep.c:removed
*** krb5/lib/krb5/free/f_ap_rep.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_ap_rep.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_ap_rep.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_ap_rep()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_ap_rep(context, val)
-     krb5_context context;
-     register krb5_ap_rep *val;
- {
-     if (val->enc_part.ciphertext.data)
- 	krb5_xfree(val->enc_part.ciphertext.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_ap_req.c
diff -c krb5/lib/krb5/free/f_ap_req.c:1.1.1.1 krb5/lib/krb5/free/f_ap_req.c:removed
*** krb5/lib/krb5/free/f_ap_req.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_ap_req.c	Sun Mar 16 20:22:30 2003
***************
*** 1,40 ****
- /*
-  * lib/krb5/free/f_ap_req.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_ap_req()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_ap_req(context, val)
-     krb5_context context;
-     register krb5_ap_req *val;
- {
-     if (val->ticket)
- 	krb5_free_ticket(context, val->ticket);
-     if (val->authenticator.ciphertext.data)
- 	krb5_xfree(val->authenticator.ciphertext.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_arep_enc.c
diff -c krb5/lib/krb5/free/f_arep_enc.c:1.1.1.1 krb5/lib/krb5/free/f_arep_enc.c:removed
*** krb5/lib/krb5/free/f_arep_enc.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_arep_enc.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_arep_enc.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_ap_rep_enc_part()
-  */
- 
- #include "k5-int.h"
- 
- void INTERFACE
- krb5_free_ap_rep_enc_part(context, val)
-     krb5_context context;
-     krb5_ap_rep_enc_part *val;
- {
-     if (val->subkey)
- 	krb5_free_keyblock(context, val->subkey);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_auth_cnt.c
diff -c krb5/lib/krb5/free/f_auth_cnt.c:1.1.1.1 krb5/lib/krb5/free/f_auth_cnt.c:removed
*** krb5/lib/krb5/free/f_auth_cnt.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_auth_cnt.c	Sun Mar 16 20:22:30 2003
***************
*** 1,44 ****
- /*
-  * lib/krb5/free/f_auth_cnt.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_authenticator()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_authenticator_contents(context, val)
-     krb5_context context;
-     krb5_authenticator *val;
- {
-     if (val->checksum)
- 	krb5_free_checksum(context, val->checksum);
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->subkey)
- 	krb5_free_keyblock(context, val->subkey);
-     if (val->authorization_data)        
-        krb5_free_authdata(context, val->authorization_data);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_authdata.c
diff -c krb5/lib/krb5/free/f_authdata.c:1.1.1.1 krb5/lib/krb5/free/f_authdata.c:removed
*** krb5/lib/krb5/free/f_authdata.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_authdata.c	Sun Mar 16 20:22:30 2003
***************
*** 1,43 ****
- /*
-  * lib/krb5/free/f_authdata.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_authdata()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_authdata(context, val)
-     krb5_context context;
- krb5_authdata **val;
- {
-     register krb5_authdata **temp;
- 
-     for (temp = val; *temp; temp++) {
- 	if ((*temp)->contents)
- 	    krb5_xfree((*temp)->contents);
- 	krb5_xfree(*temp);
-     }
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_authent.c
diff -c krb5/lib/krb5/free/f_authent.c:1.1.1.1 krb5/lib/krb5/free/f_authent.c:removed
*** krb5/lib/krb5/free/f_authent.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_authent.c	Sun Mar 16 20:22:30 2003
***************
*** 1,45 ****
- /*
-  * lib/krb5/free/f_authent.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_authenticator()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_authenticator(context, val)
-     krb5_context context;
-     krb5_authenticator *val;
- {
-     if (val->checksum)
- 	krb5_free_checksum(context, val->checksum);
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->subkey)
- 	krb5_free_keyblock(context, val->subkey);
-     if (val->authorization_data)        
-        krb5_free_authdata(context, val->authorization_data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_chksum.c
diff -c krb5/lib/krb5/free/f_chksum.c:1.1.1.1 krb5/lib/krb5/free/f_chksum.c:removed
*** krb5/lib/krb5/free/f_chksum.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_chksum.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_chksum.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_checksum()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_checksum(context, val)
-     krb5_context context;
-     register krb5_checksum *val;
- {
-     if (val->contents)
- 	krb5_xfree(val->contents);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_cred.c
diff -c krb5/lib/krb5/free/f_cred.c:1.1.1.1 krb5/lib/krb5/free/f_cred.c:removed
*** krb5/lib/krb5/free/f_cred.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_cred.c	Sun Mar 16 20:22:30 2003
***************
*** 1,40 ****
- /*
-  * lib/krb5/free/f_cred.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_cred()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_cred(context, val)
-     krb5_context context;
-     register krb5_cred *val;
- {
-     if (val->tickets)
-         krb5_free_tickets(context, val->tickets);
-     if (val->enc_part.ciphertext.data)
- 	krb5_xfree(val->enc_part.ciphertext.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_cred_cnt.c
diff -c krb5/lib/krb5/free/f_cred_cnt.c:1.1.1.1 krb5/lib/krb5/free/f_cred_cnt.c:removed
*** krb5/lib/krb5/free/f_cred_cnt.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_cred_cnt.c	Sun Mar 16 20:22:30 2003
***************
*** 1,56 ****
- /*
-  * lib/krb5/free/f_cred_cnt.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_cred_contents()
-  */
- 
- #include "k5-int.h"
- 
- /*
-  * krb5_free_cred_contents zeros out the session key, and then frees
-  * the credentials structures 
-  */
- 
- void INTERFACE
- krb5_free_cred_contents(context, val)
-     krb5_context context;
-     krb5_creds *val;
- {
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->server)
- 	krb5_free_principal(context, val->server);
-     if (val->keyblock.contents) {
- 	memset((char *)val->keyblock.contents, 0, val->keyblock.length);
- 	krb5_xfree(val->keyblock.contents);
-     }
-     if (val->ticket.data)
- 	krb5_xfree(val->ticket.data);
-     if (val->second_ticket.data)
- 	krb5_xfree(val->second_ticket.data);
-     if (val->addresses)
- 	krb5_free_addresses(context, val->addresses);
-     if (val->authdata)
- 	krb5_free_authdata(context, val->authdata);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_cred_enc.c
diff -c krb5/lib/krb5/free/f_cred_enc.c:1.1.1.1 krb5/lib/krb5/free/f_cred_enc.c:removed
*** krb5/lib/krb5/free/f_cred_enc.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_cred_enc.c	Sun Mar 16 20:22:30 2003
***************
*** 1,56 ****
- /*
-  * lib/krb5/free/f_cred_enc.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_cred_enc_part()
-  */
- 
- #include "k5-int.h"
- 
- void 
- krb5_free_cred_enc_part(context, val)
-     krb5_context context;
-     register krb5_cred_enc_part *val;
- {
-     register krb5_cred_info **temp;
-     
-     if (val->r_address)
-       krb5_free_address(context, val->r_address);
-     if (val->s_address)
-       krb5_free_address(context, val->s_address);
- 
-     if (val->ticket_info) {
- 	for (temp = val->ticket_info; *temp; temp++) {
- 	    if ((*temp)->session)
- 		krb5_free_keyblock(context, (*temp)->session);
- 	    if ((*temp)->client)
- 		krb5_free_principal(context, (*temp)->client);
- 	    if ((*temp)->server)
- 		krb5_free_principal(context, (*temp)->server);
- 	    if ((*temp)->caddrs)
- 		krb5_free_addresses(context, (*temp)->caddrs);
- 	    krb5_xfree((*temp));
- 	}
- 	krb5_xfree(val->ticket_info);
-     }
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_creds.c
diff -c krb5/lib/krb5/free/f_creds.c:1.1.1.1 krb5/lib/krb5/free/f_creds.c:removed
*** krb5/lib/krb5/free/f_creds.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_creds.c	Sun Mar 16 20:22:30 2003
***************
*** 1,37 ****
- /*
-  * lib/krb5/free/f_creds.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_creds()
-  */
- 
- #include "k5-int.h"
- 
- void INTERFACE
- krb5_free_creds(context, val)
-     krb5_context context;
-     krb5_creds *val;
- {
-     krb5_free_cred_contents(context, val);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_einfo.c
diff -c krb5/lib/krb5/free/f_einfo.c:1.1.1.1 krb5/lib/krb5/free/f_einfo.c:removed
*** krb5/lib/krb5/free/f_einfo.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_einfo.c	Sun Mar 16 20:22:30 2003
***************
*** 1,42 ****
- /*
-  * lib/krb5/free/f_einfo.c
-  *
-  * Copyright 1995 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_etype_info()
-  */
- 
- #include "k5-int.h"
- 
- void krb5_free_etype_info(context, info)
-     krb5_context context;
-     krb5_etype_info info;
- {
-   int i;
- 
-   for(i=0; info[i] != NULL; i++) {
-       if (info[i]->salt)
- 	  free(info[i]->salt);
-       free(info[i]);
-   }
-   free(info);
- }
-     
--- 0 ----
Index: krb5/lib/krb5/free/f_enc_kdc.c
diff -c krb5/lib/krb5/free/f_enc_kdc.c:1.1.1.1 krb5/lib/krb5/free/f_enc_kdc.c:removed
*** krb5/lib/krb5/free/f_enc_kdc.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_enc_kdc.c	Sun Mar 16 20:22:30 2003
***************
*** 1,44 ****
- /*
-  * lib/krb5/free/f_enc_kdc.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_enc_kdc_rep_part()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_enc_kdc_rep_part(context, val)
-     krb5_context context;
-     register krb5_enc_kdc_rep_part *val;
- {
-     if (val->session)
- 	krb5_free_keyblock(context, val->session);
-     if (val->last_req)
- 	krb5_free_last_req(context, val->last_req);
-     if (val->server)
- 	krb5_free_principal(context, val->server);
-     if (val->caddrs)
- 	krb5_free_addresses(context, val->caddrs);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_enc_tkt.c
diff -c krb5/lib/krb5/free/f_enc_tkt.c:1.1.1.1 krb5/lib/krb5/free/f_enc_tkt.c:removed
*** krb5/lib/krb5/free/f_enc_tkt.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_enc_tkt.c	Sun Mar 16 20:22:30 2003
***************
*** 1,46 ****
- /*
-  * lib/krb5/free/f_enc_tkt.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_enc_tkt_part()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_enc_tkt_part(context, val)
-     krb5_context context;
-     krb5_enc_tkt_part *val;
- {
-     if (val->session)
- 	krb5_free_keyblock(context, val->session);
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->transited.tr_contents.data)
- 	krb5_xfree(val->transited.tr_contents.data);
-     if (val->caddrs)
- 	krb5_free_addresses(context, val->caddrs);
-     if (val->authorization_data)
- 	krb5_free_authdata(context, val->authorization_data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_error.c
diff -c krb5/lib/krb5/free/f_error.c:1.1.1.1 krb5/lib/krb5/free/f_error.c:removed
*** krb5/lib/krb5/free/f_error.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_error.c	Sun Mar 16 20:22:30 2003
***************
*** 1,44 ****
- /*
-  * lib/krb5/free/f_error.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_error()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_error(context, val)
-     krb5_context context;
-     register krb5_error *val;
- {
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->server)
- 	krb5_free_principal(context, val->server);
-     if (val->text.data)
- 	krb5_xfree(val->text.data);
-     if (val->e_data.data)
- 	krb5_xfree(val->e_data.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_kdc_rp.c
diff -c krb5/lib/krb5/free/f_kdc_rp.c:1.1.1.1 krb5/lib/krb5/free/f_kdc_rp.c:removed
*** krb5/lib/krb5/free/f_kdc_rp.c:1.1.1.1	Mon Jun  2 17:57:23 1997
--- krb5/lib/krb5/free/f_kdc_rp.c	Sun Mar 16 20:22:30 2003
***************
*** 1,46 ****
- /*
-  * lib/krb5/free/f_kdc_rep.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_kdc_rep()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_kdc_rep(context, val)
-     krb5_context context;
- krb5_kdc_rep *val;
- {
-     if (val->padata)
- 	krb5_free_pa_data(context, val->padata);
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->ticket)
- 	krb5_free_ticket(context, val->ticket);
-     if (val->enc_part.ciphertext.data)
- 	krb5_xfree(val->enc_part.ciphertext.data);
-     if (val->enc_part2)
- 	krb5_free_enc_kdc_rep_part(context, val->enc_part2);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_kdc_rq.c
diff -c krb5/lib/krb5/free/f_kdc_rq.c:1.1.1.1 krb5/lib/krb5/free/f_kdc_rq.c:removed
*** krb5/lib/krb5/free/f_kdc_rq.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_kdc_rq.c	Sun Mar 16 20:22:30 2003
***************
*** 1,52 ****
- /*
-  * lib/krb5/free/f_kdc_req.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_kdc_req()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_kdc_req(context, val)
-     krb5_context context;
-     krb5_kdc_req *val;
- {
-     if (val->padata)
- 	krb5_free_pa_data(context, val->padata);
-     if (val->client)
- 	krb5_free_principal(context, val->client);
-     if (val->server)
- 	krb5_free_principal(context, val->server);
-     if (val->ktype)
- 	krb5_xfree(val->ktype);
-     if (val->addresses)
- 	krb5_free_addresses(context, val->addresses);
-     if (val->authorization_data.ciphertext.data)
- 	krb5_xfree(val->authorization_data.ciphertext.data);
-     if (val->unenc_authdata)
- 	krb5_free_authdata(context, val->unenc_authdata);
-     if (val->second_ticket)
- 	krb5_free_tickets(context, val->second_ticket);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_keyblock.c
diff -c krb5/lib/krb5/free/f_keyblock.c:1.1.1.1 krb5/lib/krb5/free/f_keyblock.c:removed
*** krb5/lib/krb5/free/f_keyblock.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_keyblock.c	Sun Mar 16 20:22:30 2003
***************
*** 1,51 ****
- /*
-  * lib/krb5/free/f_keyblock.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_keyblock()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_keyblock_contents(context, key)
-      krb5_context context;
-      register krb5_keyblock *key;
- {
-      if (key->contents) {
- 	  memset(key->contents, 0, key->length);
- 	  krb5_xfree(key->contents);
-      }
-      return;
- }
- 
- void
- krb5_free_keyblock(context, val)
-     krb5_context context;
-     register krb5_keyblock *val;
- {
-     krb5_free_keyblock_contents(context, val);
-     krb5_xfree(val);
-     return;
- }
- 
- 
--- 0 ----
Index: krb5/lib/krb5/free/f_last_req.c
diff -c krb5/lib/krb5/free/f_last_req.c:1.1.1.1 krb5/lib/krb5/free/f_last_req.c:removed
*** krb5/lib/krb5/free/f_last_req.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_last_req.c	Sun Mar 16 20:22:30 2003
***************
*** 1,40 ****
- /*
-  * lib/krb5/free/f_last_req.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_last_req()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_last_req(context, val)
-     krb5_context context;
-     krb5_last_req_entry **val;
- {
-     register krb5_last_req_entry **temp;
- 
-     for (temp = val; *temp; temp++)
- 	krb5_xfree(*temp);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_padata.c
diff -c krb5/lib/krb5/free/f_padata.c:1.1.1.1 krb5/lib/krb5/free/f_padata.c:removed
*** krb5/lib/krb5/free/f_padata.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_padata.c	Sun Mar 16 20:22:30 2003
***************
*** 1,43 ****
- /*
-  * lib/krb5/free/f_padata.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_padata()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_pa_data(context, val)
-     krb5_context context;
-     krb5_pa_data **val;
- {
-     register krb5_pa_data **temp;
- 
-     for (temp = val; *temp; temp++) {
- 	if ((*temp)->contents)
- 	    krb5_xfree((*temp)->contents);
- 	krb5_xfree(*temp);
-     }
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_princ.c
diff -c krb5/lib/krb5/free/f_princ.c:1.1.1.1 krb5/lib/krb5/free/f_princ.c:removed
*** krb5/lib/krb5/free/f_princ.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_princ.c	Sun Mar 16 20:22:30 2003
***************
*** 1,49 ****
- /*
-  * lib/krb5/free/f_princ.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_principal()
-  */
- 
- #include "k5-int.h"
- 
- void INTERFACE
- krb5_free_principal(context, val)
-     krb5_context context;
-     krb5_principal val;
- {
-     register krb5_int32 i;
- 
-     if (!val)
- 	return;
-     
-     if (val->data) {
- 	i = krb5_princ_size(context, val);
- 	while(--i >= 0)
- 	    free(krb5_princ_component(context, val, i)->data);
- 	krb5_xfree(val->data);
-     }
-     if (val->realm.data)
- 	krb5_xfree(val->realm.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_priv.c
diff -c krb5/lib/krb5/free/f_priv.c:1.1.1.1 krb5/lib/krb5/free/f_priv.c:removed
*** krb5/lib/krb5/free/f_priv.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_priv.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_priv.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_priv()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_priv(context, val)
-     krb5_context context;
- register krb5_priv *val;
- {
-     if (val->enc_part.ciphertext.data)
- 	krb5_xfree(val->enc_part.ciphertext.data);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_priv_enc.c
diff -c krb5/lib/krb5/free/f_priv_enc.c:1.1.1.1 krb5/lib/krb5/free/f_priv_enc.c:removed
*** krb5/lib/krb5/free/f_priv_enc.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_priv_enc.c	Sun Mar 16 20:22:30 2003
***************
*** 1,42 ****
- /*
-  * lib/krb5/free/f_priv_enc.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_priv_enc_part()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_priv_enc_part(context, val)
-     krb5_context context;
-     register krb5_priv_enc_part *val;
- {
-     if (val->user_data.data)
- 	krb5_xfree(val->user_data.data);
-     if (val->r_address)
- 	krb5_free_address(context, val->r_address);
-     if (val->s_address)
- 	krb5_free_address(context, val->s_address);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_pwd_data.c
diff -c krb5/lib/krb5/free/f_pwd_data.c:1.1.1.1 krb5/lib/krb5/free/f_pwd_data.c:removed
*** krb5/lib/krb5/free/f_pwd_data.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_pwd_data.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_pwd_data.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_pwd_data()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_pwd_data(context, val)
-     krb5_context context;
- krb5_pwd_data *val;
- {
-     if (val->element)
- 	krb5_free_pwd_sequences(context, val->element);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_pwd_seq.c
diff -c krb5/lib/krb5/free/f_pwd_seq.c:1.1.1.1 krb5/lib/krb5/free/f_pwd_seq.c:removed
*** krb5/lib/krb5/free/f_pwd_seq.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_pwd_seq.c	Sun Mar 16 20:22:30 2003
***************
*** 1,39 ****
- /*
-  * lib/krb5/free/f_pwd_seq.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_pwd_sequences()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_pwd_sequences(context, val)
-     krb5_context context;
-     passwd_phrase_element **val;
- {
-     if ((*val)->passwd)
- 	krb5_xfree((*val)->passwd);
-     if ((*val)->phrase)
- 	krb5_xfree((*val)->phrase);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_safe.c
diff -c krb5/lib/krb5/free/f_safe.c:1.1.1.1 krb5/lib/krb5/free/f_safe.c:removed
*** krb5/lib/krb5/free/f_safe.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_safe.c	Sun Mar 16 20:22:30 2003
***************
*** 1,44 ****
- /*
-  * lib/krb5/free/f_safe.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_safe()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_safe(context, val)
-     krb5_context context;
-     register krb5_safe *val;
- {
-     if (val->user_data.data)
- 	krb5_xfree(val->user_data.data);
-     if (val->r_address)
- 	krb5_free_address(context, val->r_address);
-     if (val->s_address)
- 	krb5_free_address(context, val->s_address);
-     if (val->checksum)
- 	krb5_free_checksum(context, val->checksum);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_tckt.c
diff -c krb5/lib/krb5/free/f_tckt.c:1.1.1.1 krb5/lib/krb5/free/f_tckt.c:removed
*** krb5/lib/krb5/free/f_tckt.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_tckt.c	Sun Mar 16 20:22:30 2003
***************
*** 1,42 ****
- /*
-  * lib/krb5/free/f_ticket.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_ticket()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_ticket(context, val)
-     krb5_context context;
-     krb5_ticket *val;
- {
-     if (val->server)
- 	krb5_free_principal(context, val->server);
-     if (val->enc_part.ciphertext.data)
- 	krb5_xfree(val->enc_part.ciphertext.data);
-     if (val->enc_part2)
- 	krb5_free_enc_tkt_part(context, val->enc_part2);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_tckts.c
diff -c krb5/lib/krb5/free/f_tckts.c:1.1.1.1 krb5/lib/krb5/free/f_tckts.c:removed
*** krb5/lib/krb5/free/f_tckts.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_tckts.c	Sun Mar 16 20:22:30 2003
***************
*** 1,40 ****
- /*
-  * lib/krb5/free/f_tickets.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_tickets()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_tickets(context, val)
-     krb5_context context;
-     krb5_ticket **val;
- {
-     register krb5_ticket **temp;
- 
-     for (temp = val; *temp; temp++)
-         krb5_free_ticket(context, *temp);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_tgt_cred.c
diff -c krb5/lib/krb5/free/f_tgt_cred.c:1.1.1.1 krb5/lib/krb5/free/f_tgt_cred.c:removed
*** krb5/lib/krb5/free/f_tgt_cred.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_tgt_cred.c	Sun Mar 16 20:22:30 2003
***************
*** 1,38 ****
- /*
-  * lib/krb5/free/f_tgt_cred.c
-  *
-  * Copyright 1990 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_tgt_creds()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_tgt_creds(context, tgts)
-     krb5_context context;
-     krb5_creds **tgts;
- {
-     register krb5_creds **tgtpp;
-     for (tgtpp = tgts; *tgtpp; tgtpp++)
- 	krb5_free_creds(context, *tgtpp);
-     krb5_xfree(tgts);
- }
--- 0 ----
Index: krb5/lib/krb5/free/f_tkt_auth.c
diff -c krb5/lib/krb5/free/f_tkt_auth.c:1.1.1.1 krb5/lib/krb5/free/f_tkt_auth.c:removed
*** krb5/lib/krb5/free/f_tkt_auth.c:1.1.1.1	Mon Jun  2 17:57:24 1997
--- krb5/lib/krb5/free/f_tkt_auth.c	Sun Mar 16 20:22:30 2003
***************
*** 1,40 ****
- /*
-  * lib/krb5/free/f_tkt_auth.c
-  *
-  * Copyright 1990,1991 by the Massachusetts Institute of Technology.
-  * All Rights Reserved.
-  *
-  * Export of this software from the United States of America may
-  *   require a specific license from the United States Government.
-  *   It is the responsibility of any person or organization contemplating
-  *   export to obtain such a license before exporting.
-  * 
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  * 
-  *
-  * krb5_free_tkt_authent()
-  */
- 
- #include "k5-int.h"
- 
- void
- krb5_free_tkt_authent(context, val)
-     krb5_context context;
-     krb5_tkt_authent *val;
- {
-     if (val->ticket)
- 	    krb5_free_ticket(context, val->ticket);
-     if (val->authenticator)
- 	    krb5_free_authenticator(context, val->authenticator);
-     krb5_xfree(val);
-     return;
- }
--- 0 ----
Index: krb5/lib/krb5/keytab/.cvsignore
diff -c /dev/null krb5/lib/krb5/keytab/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:30 2003
--- krb5/lib/krb5/keytab/.cvsignore	Thu Jun  5 10:39:46 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/keytab/configure.in
diff -c krb5/lib/krb5/keytab/configure.in:1.1.1.1 krb5/lib/krb5/keytab/configure.in:removed
*** krb5/lib/krb5/keytab/configure.in:1.1.1.1	Mon Jun  2 17:57:25 1997
--- krb5/lib/krb5/keytab/configure.in	Sun Mar 16 20:22:30 2003
***************
*** 1,10 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- CONFIG_DIRS(file)
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- DO_SUBDIRS
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([$(OBJS)])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/keytab/db/.cvsignore
diff -c /dev/null krb5/lib/krb5/keytab/db/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:30 2003
--- krb5/lib/krb5/keytab/db/.cvsignore	Thu Jun  5 10:39:47 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/keytab/db/configure.in
diff -c krb5/lib/krb5/keytab/db/configure.in:1.1.1.1 krb5/lib/krb5/keytab/db/configure.in:removed
*** krb5/lib/krb5/keytab/db/configure.in:1.1.1.1	Mon Jun  2 17:57:26 1997
--- krb5/lib/krb5/keytab/db/configure.in	Sun Mar 16 20:22:30 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/keytab/file/.cvsignore
diff -c /dev/null krb5/lib/krb5/keytab/file/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:31 2003
--- krb5/lib/krb5/keytab/file/.cvsignore	Thu Jun  5 10:39:47 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/keytab/file/configure.in
diff -c krb5/lib/krb5/keytab/file/configure.in:1.1.1.1 krb5/lib/krb5/keytab/file/configure.in:removed
*** krb5/lib/krb5/keytab/file/configure.in:1.1.1.1	Mon Jun  2 17:57:26 1997
--- krb5/lib/krb5/keytab/file/configure.in	Sun Mar 16 20:22:31 2003
***************
*** 1,5 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/krb/.cvsignore
diff -c /dev/null krb5/lib/krb5/krb/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:31 2003
--- krb5/lib/krb5/krb/.cvsignore	Thu Jun  5 10:39:48 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/krb/Makefile.in
diff -c krb5/lib/krb5/krb/Makefile.in:1.1.1.4 krb5/lib/krb5/krb/Makefile.in:1.7
*** krb5/lib/krb5/krb/Makefile.in:1.1.1.4	Mon Aug 12 15:45:04 2002
--- krb5/lib/krb5/krb/Makefile.in	Fri Dec 20 15:41:58 2002
***************
*** 277,282 ****
--- 277,285 ----
  $(srcdir)/deltat.c : # x-deltat.y
  	$(BISON) $(BISONFLAGS) -o $(srcdir)/deltat.c $(srcdir)/x-deltat.y
  
+ init_ctx.o: init_ctx.c brand.c
+ $(OUTPRE)init_ctx.$(OBJEXT): init_ctx.c brand.c
+ 
  ##DOS##LIBOBJS = $(OBJS)
  
  all-unix:: all-libobjs
Index: krb5/lib/krb5/krb/brand.c
diff -c krb5/lib/krb5/krb/brand.c:1.1.1.9 krb5/lib/krb5/krb/brand.c:1.23
*** krb5/lib/krb5/krb/brand.c:1.1.1.9	Thu Dec 19 14:07:37 2002
--- krb5/lib/krb5/krb/brand.c	Mon Mar 10 16:04:21 2003
***************
*** 12,15 ****
  
  /* Format: "KRB5_BRAND: <cvs tag> <date>" */
  
! static char krb5_brand[] = "KRB5_BRAND: krb5-1-2-7-final 1.2.7 20021115";
--- 12,15 ----
  
  /* Format: "KRB5_BRAND: <cvs tag> <date>" */
  
! static char krb5_brand[] = "@(#) $NRL: NRL_RELEASE_20030310 20030310 $";
Index: krb5/lib/krb5/krb/configure.in
diff -c krb5/lib/krb5/krb/configure.in:1.1.1.1 krb5/lib/krb5/krb/configure.in:removed
*** krb5/lib/krb5/krb/configure.in:1.1.1.1	Mon Jun  2 17:56:54 1997
--- krb5/lib/krb5/krb/configure.in	Sun Mar 16 20:22:31 2003
***************
*** 1,14 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_HEADER_STDARG
- V5_SHARED_LIB_OBJS
- AC_HAVE_FUNCS(strftime strptime geteuid)
- KRB5_RUN_FLAGS
- SubdirLibraryRule([$(OBJS)])
- USE_ANAME
- USE_KDB5_LIBRARY
- KRB5_LIBRARIES
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/krb/cp_key_cnt.c
diff -c krb5/lib/krb5/krb/cp_key_cnt.c:1.1.1.2 krb5/lib/krb5/krb/cp_key_cnt.c:1.3
*** krb5/lib/krb5/krb/cp_key_cnt.c:1.1.1.2	Fri Feb 22 16:36:11 2002
--- krb5/lib/krb5/krb/cp_key_cnt.c	Sun Feb 24 23:20:50 2002
***************
*** 39,47 ****
      krb5_keyblock FAR *to;
  {
      *to = *from;
!     to->contents = (krb5_octet *)malloc(to->length);
!     if (!to->contents)
! 	return ENOMEM;
!     memcpy((char *)to->contents, (char *)from->contents, to->length);
      return 0;
  }
--- 39,49 ----
      krb5_keyblock FAR *to;
  {
      *to = *from;
!     if (from->length > 0) {
! 	to->contents = (krb5_octet *)malloc(to->length);
! 	if (!to->contents)
! 	    return ENOMEM;
!         memcpy((char *)to->contents, (char *)from->contents, to->length);
!     }
      return 0;
  }
Index: krb5/lib/krb5/krb/get_in_tkt.c
diff -c krb5/lib/krb5/krb/get_in_tkt.c:1.1.1.3 krb5/lib/krb5/krb/get_in_tkt.c:1.5
*** krb5/lib/krb5/krb/get_in_tkt.c:1.1.1.3	Mon Aug 12 15:45:06 2002
--- krb5/lib/krb5/krb/get_in_tkt.c	Thu Aug 29 14:21:40 2002
***************
*** 922,927 ****
--- 922,933 ----
  	salt.data = NULL;
      }
  
+     /* A little bit of magic; if this flag is set, then set this flag in
+        the KDC options */
+ 
+     if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_HW_AUTH))
+ 	request.kdc_options |= KDC_OPT_HW_AUTH;
+ 
      /* now, loop processing preauth data and talking to the kdc */
  
      for (loopcount = 0; loopcount < MAX_IN_TKT_LOOPS; loopcount++) {
Index: krb5/lib/krb5/krb/gic_keytab.c
diff -c krb5/lib/krb5/krb/gic_keytab.c:1.1.1.1 krb5/lib/krb5/krb/gic_keytab.c:1.2
*** krb5/lib/krb5/krb/gic_keytab.c:1.1.1.1	Fri Feb 22 16:36:15 2002
--- krb5/lib/krb5/krb/gic_keytab.c	Fri Dec 13 19:57:54 2002
***************
*** 124,126 ****
--- 124,205 ----
  
     return(ret);
  }
+ 
+ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+ krb5_get_init_creds_keytab_prompter(context, creds, client, arg_keytab,
+ 				    prompter, data, start_time,
+ 				    in_tkt_service, options)
+      krb5_context context;
+      krb5_creds *creds;
+      krb5_principal client;
+      krb5_keytab arg_keytab;
+      krb5_prompter_fct prompter;
+      void *data;
+      krb5_deltat start_time;
+      char *in_tkt_service;
+      krb5_get_init_creds_opt *options;
+ {
+    krb5_error_code ret, ret2;
+    int use_master;
+    krb5_keytab keytab;
+ 
+    if (arg_keytab == NULL) {
+        if (ret = krb5_kt_default(context, &keytab))
+ 	   return ret;
+    } else {
+        keytab = arg_keytab;
+    }
+ 
+    use_master = 0;
+ 
+    /* first try: get the requested tkt from any kdc */
+ 
+    ret = krb5_get_init_creds(context, creds, client, prompter, data,
+ 			     start_time, in_tkt_service, options,
+ 			     krb5_get_as_key_keytab, (void *) keytab,
+ 			     use_master,NULL);
+ 
+    /* check for success */
+ 
+    if (ret == 0)
+       goto cleanup;
+ 
+    /* If all the kdc's are unavailable fail */
+ 
+    if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE))
+       goto cleanup;
+ 
+    /* if the reply did not come from the master kdc, try again with
+       the master kdc */
+ 
+    if (!use_master) {
+       use_master = 1;
+ 
+       ret2 = krb5_get_init_creds(context, creds, client, prompter, data,
+ 				 start_time, in_tkt_service, options,
+ 				 krb5_get_as_key_keytab, (void *) keytab,
+ 				 use_master, NULL);
+       
+       if (ret2 == 0) {
+ 	 ret = 0;
+ 	 goto cleanup;
+       }
+ 
+       /* if the master is unreachable, return the error from the
+ 	 slave we were able to contact */
+ 
+       if ((ret2 == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE))
+ 	 goto cleanup;
+ 
+       ret = ret2;
+    }
+ 
+    /* at this point, we have a response from the master.  Since we don't
+       do any prompting or changing for keytabs, that's it. */
+ 
+ cleanup:
+    if (arg_keytab == NULL)
+        krb5_kt_close(context, keytab);
+ 
+    return(ret);
+ }
Index: krb5/lib/krb5/krb/gic_pwd.c
diff -c krb5/lib/krb5/krb/gic_pwd.c:1.1.1.1 krb5/lib/krb5/krb/gic_pwd.c:1.3
*** krb5/lib/krb5/krb/gic_pwd.c:1.1.1.1	Fri Feb 22 16:36:15 2002
--- krb5/lib/krb5/krb/gic_pwd.c	Thu Aug 29 14:21:40 2002
***************
*** 143,148 ****
--- 143,149 ----
        user interrupt, fail */
  
     if ((ret == KRB5_KDC_UNREACH) ||
+        (ret == KRB5_PREAUTH_FAILED) ||
         (ret == KRB5_LIBOS_PWDINTR) ||
  	   (ret == KRB5_REALM_CANT_RESOLVE))
        goto cleanup;
***************
*** 297,302 ****
--- 298,304 ----
  
     if (ret == 0) {
        krb5_timestamp now;
+       krb5_last_req_entry **last_req;
        int hours;
  
        /* XXX 7 days should be configurable.  This is all pretty ad hoc,
***************
*** 304,310 ****
  	 with timezones, etc. */
  
        if (prompter &&
! 	  (in_tkt_service &&
  	   (strcmp(in_tkt_service, "kadmin/changepw") != 0)) &&
  	  ((ret = krb5_timeofday(context, &now)) == 0) &&
  	  as_reply->enc_part2->key_exp &&
--- 306,312 ----
  	 with timezones, etc. */
  
        if (prompter &&
! 	  (!in_tkt_service ||
  	   (strcmp(in_tkt_service, "kadmin/changepw") != 0)) &&
  	  ((ret = krb5_timeofday(context, &now)) == 0) &&
  	  as_reply->enc_part2->key_exp &&
***************
*** 323,328 ****
--- 325,368 ----
  	 /* ignore an error here */
           /* PROMPTER_INVOCATION */
  	 (*prompter)(context, data, 0, banner, 0, 0);
+       } else if (prompter &&
+ 		 (!in_tkt_service ||
+ 		  (strcmp(in_tkt_service, "kadmin/changepw") != 0)) &&
+ 		 as_reply->enc_part2 && as_reply->enc_part2->last_req) {
+ 	 /*
+ 	  * Check the last_req fields
+ 	  */
+ 
+ 	 for (last_req = as_reply->enc_part2->last_req; *last_req; last_req++)
+ 	    if ((*last_req)->lr_type == KRB5_LRQ_PW_EXPTIME) {
+ 	       krb5_deltat delta;
+ 	       char ts[256];
+ 
+ 	       if ((ret = krb5_timeofday(context, &now)))
+ 		  break;
+ 
+ 	       if ((ret = krb5_timestamp_to_string((*last_req)->value,
+ 						   ts, sizeof(ts))))
+ 		  break;
+ 
+ 	       delta = (*last_req)->value - now;
+ 
+ 	       if (delta < 3600)
+ 		  sprintf(banner,
+ 		    "Warning: Your password will expire in less than one "
+ 		     "hour on %s", ts);
+ 	       else if (delta < 86400*2)
+ 		  sprintf(banner,
+ 		     "Warning: Your password will expire in %d hour%s on %s",
+ 		     delta / 3600, delta < 7200 ? "" : "s", ts);
+ 	       else
+ 		  sprintf(banner,
+ 		     "Warning: Your password will expire in %d days on %s",
+ 		     delta / 86400, ts);
+ 	       /* ignore an error here */
+ 	       /* PROMPTER_INVOCATION */
+ 	       (*prompter)(context, data, 0, banner, 0, 0);
+ 	    }
        }
     }
  
Index: krb5/lib/krb5/krb/init_ctx.c
diff -c krb5/lib/krb5/krb/init_ctx.c:1.1.1.3 krb5/lib/krb5/krb/init_ctx.c:1.5
*** krb5/lib/krb5/krb/init_ctx.c:1.1.1.3	Mon Aug 12 15:45:06 2002
--- krb5/lib/krb5/krb/init_ctx.c	Thu Aug 15 14:29:31 2002
***************
*** 56,61 ****
--- 56,64 ----
  #include <ctype.h>
  #include "brand.c"
  
+ static const char *const krb5_brand_id[] = { (char *) krb5_brand_id,
+ 					     (char *) krb5_brand };
+ 
  #if (defined(_MSDOS) || defined(_WIN32))
  extern krb5_error_code krb5_vercheck();
  extern void krb5_win_ccdll_load(krb5_context context);
Index: krb5/lib/krb5/krb/kfree.c
diff -c krb5/lib/krb5/krb/kfree.c:1.1.1.1 krb5/lib/krb5/krb/kfree.c:1.3
*** krb5/lib/krb5/krb/kfree.c:1.1.1.1	Fri Feb 22 16:36:15 2002
--- krb5/lib/krb5/krb/kfree.c	Mon Oct  7 14:46:10 2002
***************
*** 588,593 ****
--- 588,602 ----
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_challenge_2(krb5_context ctx, krb5_sam_challenge_2 FAR *sc2)
+ {
+     if (!sc2)
+ 	return;
+     krb5_free_sam_challenge_2_contents(ctx, sc2);
+     krb5_xfree(sc2);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
  krb5_free_sam_challenge_contents(krb5_context ctx, krb5_sam_challenge FAR *sc)
  {
      if (!sc)
***************
*** 611,616 ****
--- 620,676 ----
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_challenge_2_contents(krb5_context ctx,
+ 		krb5_sam_challenge_2 FAR *sc2)
+ {
+     krb5_checksum **cksump;
+ 
+     if (!sc2)
+ 	return;
+     if (sc2->sam_challenge_2_body.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_challenge_2_body);
+     if (sc2->sam_cksum) {
+ 	cksump = sc2->sam_cksum;
+ 	while (*cksump) {
+ 	   krb5_free_checksum(ctx, *cksump);
+ 	   cksump++;
+ 	}
+ 	krb5_xfree(sc2->sam_cksum);
+ 	sc2->sam_cksum = 0;
+     }
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_challenge_2_body(krb5_context ctx,
+ 		krb5_sam_challenge_2_body FAR *sc2)
+ {
+     if (!sc2)
+ 	return;
+     krb5_free_sam_challenge_2_body_contents(ctx, sc2);
+     krb5_xfree(sc2);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_challenge_2_body_contents(krb5_context ctx,
+ 		krb5_sam_challenge_2_body FAR *sc2)
+ {
+     if (!sc2)
+ 	return;
+     if (sc2->sam_type_name.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_type_name);
+     if (sc2->sam_track_id.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_track_id);
+     if (sc2->sam_challenge_label.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_challenge_label);
+     if (sc2->sam_challenge.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_challenge);
+     if (sc2->sam_response_prompt.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_response_prompt);
+     if (sc2->sam_pk_for_sad.data)
+ 	krb5_free_data_contents(ctx, &sc2->sam_pk_for_sad);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
  krb5_free_sam_response(krb5_context ctx, krb5_sam_response FAR *sr)
  {
      if (!sr)
***************
*** 620,625 ****
--- 680,694 ----
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_response_2(krb5_context ctx, krb5_sam_response_2 FAR *sr2)
+ {
+     if (!sr2)
+ 	return;
+     krb5_free_sam_response_2_contents(ctx, sr2);
+     krb5_xfree(sr2);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
  krb5_free_sam_response_contents(krb5_context ctx, krb5_sam_response FAR *sr)
  {
      if (!sr)
***************
*** 633,638 ****
--- 702,719 ----
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_sam_response_2_contents(krb5_context ctx,
+ 		krb5_sam_response_2 FAR *sr2)
+ {
+     if (!sr2)
+ 	return;
+     if (sr2->sam_track_id.data)
+ 	krb5_free_data_contents(ctx, &sr2->sam_track_id);
+     if (sr2->sam_enc_nonce_or_sad.ciphertext.data)
+ 	krb5_free_data_contents(ctx, &sr2->sam_enc_nonce_or_sad.ciphertext);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
  krb5_free_predicted_sam_response(krb5_context ctx,
  				 krb5_predicted_sam_response FAR *psr)
  {
***************
*** 669,674 ****
--- 750,765 ----
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_enc_sam_response_enc_2(krb5_context ctx,
+ 			       krb5_enc_sam_response_enc_2 FAR *esre2)
+ {
+     if (!esre2)
+ 	return;
+     krb5_free_enc_sam_response_enc_2_contents(ctx, esre2);
+     krb5_xfree(esre2);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
  krb5_free_enc_sam_response_enc_contents(krb5_context ctx,
  			       krb5_enc_sam_response_enc FAR *esre)
  {
***************
*** 676,681 ****
--- 767,782 ----
  	return;
      if (esre->sam_sad.data)
  	krb5_free_data_contents(ctx, &esre->sam_sad);
+ }
+ 
+ KRB5_DLLIMP void KRB5_CALLCONV
+ krb5_free_enc_sam_response_enc_2_contents(krb5_context ctx,
+ 			       krb5_enc_sam_response_enc_2 FAR *esre2)
+ {
+     if (!esre2)
+ 	return;
+     if (esre2->sam_sad.data)
+ 	krb5_free_data_contents(ctx, &esre2->sam_sad);
  }
  
  KRB5_DLLIMP void KRB5_CALLCONV
Index: krb5/lib/krb5/krb/preauth2.c
diff -c krb5/lib/krb5/krb/preauth2.c:1.1.1.1 krb5/lib/krb5/krb/preauth2.c:1.8
*** krb5/lib/krb5/krb/preauth2.c:1.1.1.1	Fri Feb 22 16:36:21 2002
--- krb5/lib/krb5/krb/preauth2.c	Thu Dec 19 14:25:36 2002
***************
*** 269,274 ****
--- 269,292 ----
  	return(KRB5_SAM_UNSUPPORTED);
      }
  
+     /* If we need the password from the user (USE_SAD_AS_KEY not set),	*/
+     /* then get it here.  Exception for "old" KDCs with CryptoCard 	*/
+     /* support which uses the USE_SAD_AS_KEY flag, but still needs pwd	*/ 
+ 
+     if (!(sam_challenge->sam_flags & KRB5_SAM_USE_SAD_AS_KEY) ||
+ 	(sam_challenge->sam_type == PA_SAM_TYPE_CRYPTOCARD)) {
+ 
+ 	/* etype has either been set by caller or by KRB5_PADATA_ETYPE_INFO */
+ 	/* message from the KDC.  If it is not set, pick an enctype that we */
+ 	/* think the KDC will have for us.				    */
+ 
+ 	if (etype && *etype == 0)
+ 	   *etype = ENCTYPE_DES_CBC_CRC;
+ 
+ 	if (ret = (gak_fct)(context, request->client, *etype, prompter,
+ 			prompter_data, salt, as_key, gak_data))
+ 	   return(ret);
+     }
      sprintf(name, "%.*s",
  	    SAMDATA(sam_challenge->sam_type_name, "SAM Authentication",
  		    sizeof(name) - 1));
***************
*** 289,295 ****
--- 307,317 ----
      response_data.length = sizeof(response);
  
      kprompt.prompt = prompt;
+ #ifdef WACK_O_LAND
      kprompt.hidden = sam_challenge->sam_challenge.length?0:1;
+ #else
+     kprompt.hidden = 1;
+ #endif
      kprompt.reply = &response_data;
      prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
  
***************
*** 318,323 ****
--- 340,350 ----
      /* XXX What if more than one flag is set?  */
      if (sam_challenge->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
  
+ 	/* Most of this should be taken care of before we get here.  We	*/
+ 	/* will need the user's password and as_key to encrypt the SAD	*/
+ 	/* and we want to preserve ordering of user prompts (first	*/
+ 	/* password, then SAM data) so that user's won't be confused.	*/
+ 
  	if (as_key->length) {
  	    krb5_free_keyblock_contents(context, as_key);
  	    as_key->length = 0;
***************
*** 444,449 ****
--- 471,863 ----
      return(0);
  }
  
+ static
+ krb5_error_code pa_sam_2(krb5_context context,
+ 				krb5_kdc_req *request,
+ 				krb5_pa_data *in_padata,
+ 				krb5_pa_data **out_padata,
+ 				krb5_data *salt,
+ 				krb5_enctype *etype,
+ 				krb5_keyblock *as_key,
+ 				krb5_prompter_fct prompter,
+ 				void *prompter_data,
+ 				krb5_gic_get_as_key_fct gak_fct,
+ 				void *gak_data) {
+ 
+    krb5_error_code retval;
+    krb5_sam_challenge_2 *sc2 = NULL;
+    krb5_sam_challenge_2_body *sc2b = NULL;
+    krb5_data tmp_data;
+    krb5_data response_data;
+    char name[100], banner[100], prompt[100], response[100];
+    krb5_prompt kprompt;
+    krb5_prompt_type prompt_type;
+    krb5_data defsalt;
+    krb5_checksum **cksum;
+    krb5_data *scratch = NULL;
+    krb5_boolean valid_cksum = 0;
+    krb5_enc_sam_response_enc_2 enc_sam_response_enc_2;
+    krb5_sam_response_2 sr2;
+    krb5_pa_data *sam_padata;
+ 
+    if (prompter == NULL)
+ 	return KRB5_LIBOS_CANTREADPWD;
+ 
+    tmp_data.length = in_padata->length;
+    tmp_data.data = (char *)in_padata->contents;
+ 
+    if (retval = decode_krb5_sam_challenge_2(&tmp_data, &sc2))
+ 	return(retval);
+ 
+    retval = decode_krb5_sam_challenge_2_body(&sc2->sam_challenge_2_body, &sc2b);
+ 
+    if (retval) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	return(retval);
+    }
+ 
+    if (!sc2->sam_cksum || ! *sc2->sam_cksum) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(KRB5_SAM_NO_CHECKSUM);
+    }
+ 
+    if (sc2b->sam_flags & KRB5_SAM_MUST_PK_ENCRYPT_SAD) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(KRB5_SAM_UNSUPPORTED);
+    }
+ 
+    if (!valid_enctype(sc2b->sam_etype)) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(KRB5_SAM_INVALID_ETYPE);
+    }
+ 
+    /* All of the above error checks are KDC-specific, that is, they	*/
+    /* assume a failure in the KDC reply.  By returning anything other	*/
+    /* than KRB5_KDC_UNREACH, KRB5_PREAUTH_FAILED,		*/
+    /* KRB5_LIBOS_PWDINTR, or KRB5_REALM_CANT_RESOLVE, the client will	*/
+    /* most likely go on to try the AS_REQ against master KDC		*/
+ 
+    if (!(sc2b->sam_flags & KRB5_SAM_USE_SAD_AS_KEY)) {
+ 	/* We will need the password to obtain the key used for	*/
+ 	/* the checksum, and encryption of the sam_response.	*/
+ 	/* Go ahead and get it now, preserving the ordering of	*/
+ 	/* prompts for the user.				*/
+ 
+ 	retval = (gak_fct)(context, request->client,
+ 			sc2b->sam_etype, prompter,
+ 			prompter_data, salt, as_key, gak_data);
+ 	if (retval) {
+ 	   krb5_free_sam_challenge_2(context, sc2);
+ 	   krb5_free_sam_challenge_2_body(context, sc2b);
+ 	   return(retval);
+ 	}
+    }
+ 
+    sprintf(name, "%.*s",
+ 	SAMDATA(sc2b->sam_type_name, "SAM Authentication",
+ 	sizeof(name) - 1));
+ 
+    sprintf(banner, "%.*s",
+ 	SAMDATA(sc2b->sam_challenge_label,
+ 	sam_challenge_banner(sc2b->sam_type),
+ 	sizeof(banner)-1));
+ 
+    sprintf(prompt, "%s%.*s%s%.*s",
+ 	sc2b->sam_challenge.length?"Challenge is [":"",
+ 	SAMDATA(sc2b->sam_challenge, "", 20),
+ 	sc2b->sam_challenge.length?"], ":"",
+ 	SAMDATA(sc2b->sam_response_prompt, "passcode", 55));
+ 
+    response_data.data = response;
+    response_data.length = sizeof(response);
+    kprompt.prompt = prompt;
+    kprompt.hidden = 1;
+    kprompt.reply = &response_data;
+ 
+    prompt_type = KRB5_PROMPT_TYPE_PREAUTH;
+    krb5int_set_prompt_types(context, &prompt_type);
+ 
+    if (retval = ((*prompter)(context, prompter_data, name,
+ 				banner, 1, &kprompt))) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	krb5int_set_prompt_types(context, 0);
+ 	return(retval);
+    }
+ 
+    krb5int_set_prompt_types(context, (krb5_prompt_type *)NULL);
+ 
+    /* Generate salt used by string_to_key() */
+    if ((salt->length == -1) && (salt->data == NULL)) {
+ 	if (retval = krb5_principal2salt(context, request->client, &defsalt)) {
+ 	   krb5_free_sam_challenge_2(context, sc2);
+ 	   krb5_free_sam_challenge_2_body(context, sc2b);
+ 	   return(retval);
+ 	}
+ 	salt = &defsalt;
+    } else {
+ 	defsalt.length = 0;
+    }
+ 
+    /* Get encryption key to be used for checksum and sam_response */
+    if (!(sc2b->sam_flags & KRB5_SAM_USE_SAD_AS_KEY)) {
+ 	/*
+ 	 * as_key = string_to_key(password)
+ 	 * Use gak_fct to get this from either the user or a keytab
+ 	 */
+ 	int i;
+ 
+ 	if (as_key->length) {
+ 	   krb5_free_keyblock_contents(context, as_key);
+ 	   as_key->length = 0;
+ 	}
+ 
+ 	/* generate a key using the supplied password/key */
+ 	retval = (*gak_fct)(context, request->client, sc2b->sam_etype,
+ 			    prompter, prompter_data, salt, as_key, gak_data);
+ 
+ 	if (retval) {
+ 	   krb5_free_sam_challenge_2(context, sc2);
+ 	   krb5_free_sam_challenge_2_body(context, sc2b);
+ 	   if (defsalt.length) krb5_xfree(defsalt.data);
+ 	   return(retval);
+ 	}
+ 
+ 	if (!(sc2b->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD)) {
+ 	   /* as_key = combine_key (as_key, string_to_key(SAD)) */
+ 	   krb5_keyblock tmp_kb;
+ 
+ 	   retval = krb5_c_string_to_key(context, sc2b->sam_etype,
+ 				&response_data, salt, &tmp_kb);
+ 
+ 	   if (retval) {
+ 		krb5_free_sam_challenge_2(context, sc2);
+ 	        krb5_free_sam_challenge_2_body(context, sc2b);
+ 		if (defsalt.length) krb5_xfree(defsalt.data);
+ 		return(retval);
+ 	   }
+ 
+ 	   /* This should be a call to the crypto library some day */
+ 	   /* key types should already match the sam_etype */
+ 	   retval = krb5_combine_keys(context, as_key, &tmp_kb, as_key);
+ 
+ 	   if (retval) {
+ 		krb5_free_sam_challenge_2(context, sc2);
+ 	        krb5_free_sam_challenge_2_body(context, sc2b);
+ 		if (defsalt.length) krb5_xfree(defsalt.data);
+ 		return(retval);
+ 	   }
+ 	   krb5_free_keyblock_contents(context, &tmp_kb);
+ 	}
+ 
+ 	if (defsalt.length)
+ 	   krb5_xfree(defsalt.data);
+ 
+    } else {
+ 	/* as_key = string_to_key(SAD) */
+ 
+ 	if (as_key->length) {
+ 	   krb5_free_keyblock_contents(context, as_key);
+ 	   as_key->length = 0;
+ 	}
+ 
+ 	retval = krb5_c_string_to_key(context, sc2b->sam_etype,
+ 				&response_data, salt, as_key);
+ 
+ 	if (defsalt.length)
+ 	   krb5_xfree(defsalt.data);
+ 
+ 	if (retval) {
+ 	   krb5_free_sam_challenge_2(context, sc2);
+ 	   krb5_free_sam_challenge_2_body(context, sc2b);
+ 	   return(retval);
+ 	}
+    }
+ 
+    /* Now we have a key, verify the checksum on the sam_challenge */
+ 
+    cksum = sc2->sam_cksum;
+    
+    while (*cksum) {
+ 	/* Check this cksum */
+ 
+         if (! krb5_c_is_keyed_cksum((*cksum)->checksum_type))
+ 	    retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
+ 
+ 	if (! retval)
+ 	    retval = krb5_c_verify_checksum(context, as_key,
+ 			KRB5_KEYUSAGE_PA_SAM_CHALLENGE_CKSUM,
+ 			&sc2->sam_challenge_2_body,
+ 			*cksum, &valid_cksum);
+ 	if (retval) {
+ 	   krb5_free_sam_challenge_2(context, sc2);
+ 	   krb5_free_sam_challenge_2_body(context, sc2b);
+ 	   return(retval);
+ 	}
+ 	if (valid_cksum)
+ 	   break;
+ 	cksum++;
+    }
+ 
+    if (!valid_cksum) {
+ 
+ 	/* If KRB5_SAM_SEND_ENCRYPTED_SAD is set, then password is only	*/
+ 	/* source for checksum key.  Therefore, a bad checksum means a	*/
+ 	/* bad password.  Don't give that direct feedback to someone	*/
+ 	/* trying to brute-force passwords.				*/
+ 
+ 	if (!(sc2b->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD))
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	/*
+ 	 * Note: We return AP_ERR_BAD_INTEGRITY so upper-level applications
+ 	 * can interpret that as "password incorrect", which is probably
+ 	 * the best error we can return in this situation.
+ 	 */
+ 	return(KRB5KRB_AP_ERR_BAD_INTEGRITY);
+    }
+  
+    /* fill in enc_sam_response_enc_2 */
+    enc_sam_response_enc_2.magic = KV5M_ENC_SAM_RESPONSE_ENC_2;
+    enc_sam_response_enc_2.sam_nonce = sc2b->sam_nonce;
+    if (sc2b->sam_flags & KRB5_SAM_SEND_ENCRYPTED_SAD) {
+ 	enc_sam_response_enc_2.sam_sad = response_data;
+    } else {
+ 	enc_sam_response_enc_2.sam_sad.data = NULL;
+ 	enc_sam_response_enc_2.sam_sad.length = 0;
+    }
+ 
+    /* encode and encrypt enc_sam_response_enc_2 with as_key */
+    retval = encode_krb5_enc_sam_response_enc_2(&enc_sam_response_enc_2,
+ 		&scratch);
+    if (retval) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(retval);
+    }
+ 
+    /* Fill in sam_response_2 */
+    memset(&sr2, 0, sizeof(sr2));
+    sr2.sam_type = sc2b->sam_type;
+    sr2.sam_flags = sc2b->sam_flags;
+    sr2.sam_track_id = sc2b->sam_track_id;
+    sr2.sam_nonce = sc2b->sam_nonce;
+ 
+    /* Now take care of sr2.sam_enc_nonce_or_sad by encrypting encoded	*/
+    /* enc_sam_response_enc_2 from above */
+ 
+    retval = krb5_c_encrypt_length(context, as_key->enctype, scratch->length,
+ 		(unsigned int *) &sr2.sam_enc_nonce_or_sad.ciphertext.length);
+    if (retval) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(retval);
+    }
+ 
+    sr2.sam_enc_nonce_or_sad.ciphertext.data =
+ 	(char *)malloc(sr2.sam_enc_nonce_or_sad.ciphertext.length);
+ 
+    if (!sr2.sam_enc_nonce_or_sad.ciphertext.data) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	return(ENOMEM);
+    }
+ 
+    retval = krb5_c_encrypt(context, as_key, KRB5_KEYUSAGE_PA_SAM_RESPONSE,
+ 		NULL, scratch, &sr2.sam_enc_nonce_or_sad);
+    if (retval) {
+ 	krb5_free_sam_challenge_2(context, sc2);
+ 	krb5_free_sam_challenge_2_body(context, sc2b);
+ 	krb5_free_data(context, scratch);
+ 	krb5_free_data_contents(context, &sr2.sam_enc_nonce_or_sad.ciphertext);
+ 	return(retval);
+    }
+    krb5_free_data(context, scratch);
+    scratch = NULL;
+ 
+    /* Encode the sam_response_2 */
+    retval = encode_krb5_sam_response_2(&sr2, &scratch);
+    krb5_free_sam_challenge_2(context, sc2);
+    krb5_free_sam_challenge_2_body(context, sc2b);
+    krb5_free_data_contents(context, &sr2.sam_enc_nonce_or_sad.ciphertext);
+ 
+    if (retval) {
+ 	return (retval);
+    }
+ 
+    /* Almost there, just need to make padata !  */
+    sam_padata = malloc(sizeof(krb5_pa_data));
+    if (sam_padata == NULL) {
+ 	krb5_free_data(context, scratch);
+ 	return(ENOMEM);
+    }
+ 
+    sam_padata->magic = KV5M_PA_DATA;
+    sam_padata->pa_type = KRB5_PADATA_SAM_RESPONSE_2;
+    sam_padata->length = scratch->length;
+    sam_padata->contents = (krb5_octet *) scratch->data;
+ 
+    *out_padata = sam_padata;
+ 
+    return(0);
+ }
+ 
+ static 
+ krb5_error_code pa_alt_princ(krb5_context context,
+ 				krb5_kdc_req *request,
+ 				krb5_pa_data *in_padata,
+ 				krb5_pa_data **out_padata,
+ 				krb5_data *salt,
+ 				krb5_enctype *etype,
+ 				krb5_keyblock *as_key,
+ 				krb5_prompter_fct prompter,
+ 				void *prompter_data,
+ 				krb5_gic_get_as_key_fct gak_fct,
+ 				void *gak_data)
+ {
+     krb5_principal host;
+     krb5_data *tmp;
+     krb5_error_code code;
+     krb5_pa_data *pa;
+ 
+     if (in_padata->length) {
+ 	if (!(tmp = (krb5_data *) malloc(sizeof(*tmp))))
+ 	    return ENOMEM;
+ 	tmp->length = in_padata->length;
+ 	if (!(tmp->data = malloc(tmp->length)))
+ 	    return ENOMEM;
+ 	memcpy(tmp->data, in_padata->contents, tmp->length);
+     } else {
+ 	if ((code = krb5_sname_to_principal(context, NULL, NULL,
+ 					    KRB5_NT_SRV_HST, &host)))
+ 	    return code;
+ 	if ((code = encode_krb5_principal(host, &tmp))) {
+ 	    krb5_free_principal(context, host);
+ 	    return code;
+ 	}
+ 	krb5_free_principal(context, host);
+     }
+ 
+     if ((pa = (krb5_pa_data *) malloc(sizeof(krb5_pa_data))) == NULL) {
+ 	krb5_free_data(context, tmp);
+ 	return ENOMEM;
+     }
+ 
+     pa->magic = KV5M_PA_DATA;
+     pa->pa_type = KRB5_PADATA_ALT_PRINC;
+     pa->length = tmp->length;
+     pa->contents = (krb5_octet *) tmp->data;
+ 
+     *out_padata = pa;
+ 
+     krb5_xfree(tmp);
+ 
+     return 0;
+ }
+ 
  static pa_types_t pa_types[] = {
      {
  	KRB5_PADATA_PW_SALT,
***************
*** 461,469 ****
--- 875,893 ----
  	PA_REAL,
      },
      {
+ 	KRB5_PADATA_SAM_CHALLENGE_2,
+ 	pa_sam_2,
+ 	PA_REAL,
+     },
+     {
  	KRB5_PADATA_SAM_CHALLENGE,
  	pa_sam,
  	PA_REAL,
+     },
+     {
+ 	KRB5_PADATA_ALT_PRINC,
+ 	pa_alt_princ,
+ 	PA_INFO,
      },
      {
  	-1,
Index: krb5/lib/krb5/krb/vfy_increds.c
diff -c krb5/lib/krb5/krb/vfy_increds.c:1.1.1.1 krb5/lib/krb5/krb/vfy_increds.c:1.2
*** krb5/lib/krb5/krb/vfy_increds.c:1.1.1.1	Fri Feb 22 16:36:32 2002
--- krb5/lib/krb5/krb/vfy_increds.c	Thu Sep 26 17:05:54 2002
***************
*** 187,204 ****
     if (ccache_arg && ccache) {
         if (*ccache_arg == NULL) {
  	   krb5_ccache retcc;
- 
  	   retcc = NULL;
! 
! 	   if ((ret = krb5_cc_resolve(context, "MEMORY:rd_req2", &retcc)) ||
! 	       (ret = krb5_cc_initialize(context, retcc, creds->client)) ||
! 	       (ret = krb5_cc_copy_creds_except(context, ccache, retcc,
! 						creds->server))) {
! 	       if (retcc)
! 		   krb5_cc_destroy(context, retcc);
! 	   } else {
! 	       *ccache_arg = retcc;
! 	   }
         } else {
  	   ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg,
  					   server);
--- 187,194 ----
     if (ccache_arg && ccache) {
         if (*ccache_arg == NULL) {
  	   krb5_ccache retcc;
  	   retcc = NULL;
! 	   *ccache_arg = retcc;
         } else {
  	   ret = krb5_cc_copy_creds_except(context, ccache, *ccache_arg,
  					   server);
Index: krb5/lib/krb5/os/DNR.c
diff -c krb5/lib/krb5/os/DNR.c:1.1.1.1 krb5/lib/krb5/os/DNR.c:removed
*** krb5/lib/krb5/os/DNR.c:1.1.1.1	Mon Jun  2 17:57:28 1997
--- krb5/lib/krb5/os/DNR.c	Sun Mar 16 20:22:32 2003
***************
*** 1,387 ****
- /* 	
- 
- 	File:		DNR.c 
- 	
- 	Contains:	DNR library for MPW
- 
-   	Copyright:	 1989-1995 by Apple Computer, Inc., all rights reserved
- 
- 	Version:	Technology:			Networking
- 				Package:			Use with MacTCP 2.0.6 and the Universal
- 									Interfaces 2.1b1	
- 		
- 	Change History (most recent first):
- 		<3>	 1/23/95	rrk  	implemented use of universal procptrs
- 		 						Changed selector name HINFO to HXINFO
- 		 						due to conflict of name in MacTCP header
- 		 						Removed use of TrapAvailable and exchanged
- 		 						for the TrapExists call.
- 								Changed symbol codeHandle to gDNRCodeHndl
- 								Changed symbol dnr to gDNRCodePtr
- 	Further modifications by Steve Falkenburg, Apple MacDTS 8/91
- 	Modifications by Jim Matthews, Dartmouth College, 5/91
- 
- 	
- */
- 
- #include "k5-int.h"
- #ifdef HAVE_MACSOCK_H           /* Only build this on the Macintosh */
- 
- #ifndef __OSUTILS__
- #include <OSUtils.h>
- #endif
- 
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
- 
- #ifndef __FILES__
- #include <Files.h>
- #endif
- 
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
- 
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
- 
- #ifndef __TRAPS__
- #include <Traps.h>
- #endif
- 
- #ifndef __GESTALTEQU__
- #include <GestaltEqu.h>
- #endif
- 
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
- 
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
- 
- 
- #ifndef __MACTCP__
- #include "MacTCP.h"
- #endif
- 
- #ifndef __ADDRESSXLATION__
- #include "AddressXlation.h"
- #endif
- 
- // think C compatibility stuff
- 
- #ifndef	_GestaltDispatch
- #define	_GestaltDispatch	_Gestalt
- #endif
- 
- 
- /* RRK Modification 1/95 - commenting out the following defines as they are
- 	defined in the DNRCalls.h header file
- */
- 
- void GetSystemFolder(short *vRefNumP, long *dirIDP);
- void GetCPanelFolder(short *vRefNumP, long *dirIDP);
- short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID);
- short OpenOurRF(void);
- short	NumToolboxTraps(void);
- TrapType	GetTrapType(short theTrap);
- Boolean TrapExists(short theTrap);
- 
- static Handle 			gDNRCodeHndl = nil;
- static ProcPtr			gDNRCodePtr = nil;
- 
- /*	Check the bits of a trap number to determine its type. */
- 
- /* InitGraf is always implemented (trap $A86E).  If the trap table is big
- ** enough, trap $AA6E will always point to either Unimplemented or some other
- ** trap, but will never be the same as InitGraf.  Thus, you can check the size
- ** of the trap table by asking if the address of trap $A86E is the same as
- ** $AA6E. */
- 
- #pragma segment UtilMain
- short	NumToolboxTraps(void)
- {
- 	if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- 		return(0x200);
- 	else
- 		return(0x400);
- }
- 
- #pragma segment UtilMain
- TrapType	GetTrapType(short theTrap)
- {
- 	/* OS traps start with A0, Tool with A8 or AA. */
- 	if ((theTrap & 0x0800) == 0)					/* per D.A. */
- 		return(OSTrap);
- 	else
- 		return(ToolTrap);
- }
- 
- Boolean TrapExists(short theTrap)
- {
- 	TrapType	theTrapType;
- 
- 	theTrapType = GetTrapType(theTrap);
- 	if ((theTrapType == ToolTrap) && ((theTrap &= 0x07FF) >= NumToolboxTraps()))
- 		theTrap = _Unimplemented;
- 
- 	return(NGetTrapAddress(_Unimplemented, ToolTrap) != NGetTrapAddress(theTrap, theTrapType));
- }
- 
- void GetSystemFolder(short *vRefNumP, long *dirIDP)
- {
- 	SysEnvRec info;
- 	long wdProcID;
- 	
- 	SysEnvirons(1, &info);
- 	if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) 
- 	{
- 		*vRefNumP = 0;
- 		*dirIDP = 0;
- 	}
- }
- 
- void GetCPanelFolder(short *vRefNumP, long *dirIDP)
- {
- 	Boolean hasFolderMgr = false;
- 	long feature;
- 	
- 	if (TrapExists(_GestaltDispatch)) if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
- 	if (!hasFolderMgr) 
- 	{
- 		GetSystemFolder(vRefNumP, dirIDP);
- 		return;
- 	}
- 	else 
- 	{
- 		if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) 
- 		{
- 			*vRefNumP = 0;
- 			*dirIDP = 0;
- 		}
- 	}
- }
- 	
- /* SearchFolderForDNRP is called to search a folder for files that might 
- 	contain the 'dnrp' resource */
- short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID)
- {
- 	HParamBlockRec fi;
- 	Str255 filename;
- 	short refnum;
- 	
- 	fi.fileParam.ioCompletion = nil;
- 	fi.fileParam.ioNamePtr = filename;
- 	fi.fileParam.ioVRefNum = vRefNum;
- 	fi.fileParam.ioDirID = dirID;
- 	fi.fileParam.ioFDirIndex = 1;
- 	
- 	while (PBHGetFInfo(&fi, false) == noErr) 
- 	{
- 		/* scan system folder for driver resource files of specific type & creator */
- 		if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
- 			fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) 
- 		{
- 			/* found the MacTCP driver file? */
- 			refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
- 			if (GetIndResource('dnrp', 1) == NULL)
- 				CloseResFile(refnum);
- 			else
- 				return refnum;
- 		}
- 		/* check next file in system folder */
- 		fi.fileParam.ioFDirIndex++;
- 		fi.fileParam.ioDirID = dirID;	/* PBHGetFInfo() clobbers ioDirID */
- 	}
- 	return(-1);
- }	
- 
- /* OpenOurRF is called to open the MacTCP driver resources */
- 
- short OpenOurRF(void)
- {
- 	short refnum;
- 	short vRefNum;
- 	long dirID;
- 	
- 	/* first search Control Panels for MacTCP 1.1 */
- 	GetCPanelFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	/* next search System Folder for MacTCP 1.0.x */
- 	GetSystemFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	/* finally, search Control Panels for MacTCP 1.0.x */
- 	GetCPanelFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	return -1;
- }	
- 
- 
- OSErr OpenResolver(char *fileName)
- {
- 	short 			refnum;
- 	OSErr 			rc;
- 	
- 	if (gDNRCodePtr != nil)
- 		/* resolver already loaded in */
- 		return(noErr);
- 		
- 	/* open the MacTCP driver to get DNR resources. Search for it based on
- 	   creator & type rather than simply file name */	
- 	refnum = OpenOurRF();
- 
- 	/* ignore failures since the resource may have been installed in the 
- 	   System file if running on a Mac 512Ke */
- 	   
- 	/* load in the DNR resource package */
- 	gDNRCodeHndl = GetIndResource('dnrp', 1);
- 	if (gDNRCodeHndl == nil)
- 	{
- 		/* can't open DNR */
- 		return(ResError());
- 	}
- 	
- 	DetachResource(gDNRCodeHndl);
- 	if (refnum != -1) 
- 	{
- 		CloseResFile(refnum);
- 	}
- 		
- 	/* lock the DNR resource since it cannot be reloated while opened */
- 	MoveHHi(gDNRCodeHndl);
- 	HLock(gDNRCodeHndl);
- 	
- 	gDNRCodePtr = (ProcPtr)*gDNRCodeHndl;
- 	
- 	/* call open resolver */
- 	// RRK modification 1/95 use CallOpenResolverProc define to call UPP
- 	
- 	rc = CallOpenResolverProc(gDNRCodePtr, OPENRESOLVER, fileName);
- 	if (rc != noErr) 
- 	{
- 		/* problem with open resolver, flush it */
- 		HUnlock(gDNRCodeHndl);
- 		DisposeHandle(gDNRCodeHndl);
- 		gDNRCodePtr = nil;
- 	}
- 	return(rc);
- }
- 
- 
- OSErr CloseResolver(void)
- {
- 	
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	/* call close resolver */
- 	// RRK modification 1/95 use CallCloseResolverProc define to call UPP
- 	// (void) (*dnr)(CLOSERESOLVER);
- 
- 	CallCloseResolverProc(gDNRCodePtr, CLOSERESOLVER);
- 	
- 	/* release the DNR resource package */
- 	HUnlock(gDNRCodeHndl);
- 	DisposeHandle(gDNRCodeHndl);
- 	gDNRCodePtr = nil;
- 	return(noErr);
- }
- 
- 	// RRK modification 1/95 declare parameter resultProc to be of type 
- 	// ResultProcUPP instead of a long
- 	
- OSErr StrToAddr(char *hostName, struct hostInfo *rtnStruct, 
- 			ResultUPP resultproc, Ptr userDataPtr)
- {
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallStrToAddrProc define to call UPP
- 	// return((*dnr)(STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
- 			
- 	return (CallStrToAddrProc(gDNRCodePtr, STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
- }
- 	
- OSErr AddrToStr(unsigned long addr, char *addrStr)
- {
- 	OSErr	err;
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallAddrToStrProc define to call UPP
- 	// (*dnr)(ADDRTOSTR, addr, addrStr);
- 	
- 	err = CallAddrToStrProc(gDNRCodePtr, ADDRTOSTR, addr, addrStr);
- 	return(noErr);
- }
- 	
- OSErr EnumCache(EnumResultUPP resultproc, Ptr userDataPtr)
- {
- 
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallEnumCacheProc define to call UPP
- 	// return((*dnr)(ENUMCACHE, resultproc, userDataPtr));
- 
- 	return (CallEnumCacheProc(gDNRCodePtr, ENUMCACHE, resultproc, userDataPtr));
- }
- 	
- 	
- OSErr AddrToName(unsigned long addr, struct hostInfo *rtnStruct, 
- 			ResultUPP resultproc, Ptr userDataPtr)
- {
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallAddrToNameProc define to call UPP
- 	// return((*dnr)(ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
- 
- 	return(CallAddrToNameProc(gDNRCodePtr, ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
- }
- 
- 
- extern OSErr HInfo(char *hostName, struct returnRec *returnRecPtr, 
- 			ResultProc2UPP resultProc, Ptr userDataPtr)
- {
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallHInfoProc define to call UPP
- 	// return((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- 	return(CallHInfoProc(gDNRCodePtr, HXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- }
- 	
- extern OSErr MXInfo(char *hostName, struct returnRec *returnRecPtr, 
- 			ResultProc2UPP resultProc, Ptr userDataPtr)
- {
- 	if (gDNRCodePtr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	// RRK modification 1/95 use CallHInfoProc define to call UPP
- 	// return((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- 	return(CallMXInfoProc(gDNRCodePtr, MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- }	/* removed ; (causes syntax err in Think C 5.0 */
- 
- #endif /* HAVE_MACSOCK_H */
--- 0 ----
Index: krb5/lib/krb5/os/configure.in
diff -c krb5/lib/krb5/os/configure.in:1.1.1.1 krb5/lib/krb5/os/configure.in:removed
*** krb5/lib/krb5/os/configure.in:1.1.1.1	Mon Jun  2 17:57:29 1997
--- krb5/lib/krb5/os/configure.in	Sun Mar 16 20:22:32 2003
***************
*** 1,36 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- dnl time checks are for timeofday.c (which gets them from osconf.h)
- dnl and gmt_mktime.c (which only gets them from here...)
- AC_TIME_WITH_SYS_TIME
- AC_HAVE_HEADERS(unistd.h sys/time.h regex.h regexp.h regexpr.h)
- 
- dnl regcomp is present but non-functional on Solaris 2.4
- AC_C_CROSS
- AC_MSG_CHECKING(for working regcomp)
- AC_CACHE_VAL(ac_cv_func_regcomp,[
- AC_TRY_RUN([
- #include <sys/types.h>
- #include <regex.h>
- regex_t x; regmatch_t m;
- int main() { return regcomp(&x,"pat.*",0) || regexec(&x,"pattern",1,&m,0); }
- ], ac_cv_func_regcomp=yes, ac_cv_func_regcomp=no)])
- AC_MSG_RESULT($ac_cv_func_regcomp)
- test $ac_cv_func_regcomp = yes && AC_DEFINE(HAVE_REGCOMP)
- save_LIBS="$LIBS"
- LIBS=-lgen
- dnl this will fail if there's no compile/step in -lgen, or if there's
- dnl no -lgen.  This is fine.
- AC_CHECK_FUNCS(compile step)
- LIBS="$save_LIBS"
- AC_HAVE_FUNCS(re_comp)
- AC_HEADER_EGREP(time_t, sys/types.h, AC_DEFINE(POSIX_TYPES))
- HAS_ANSI_VOLATILE
- AC_DEFINE(AN_TO_LN_RULES)
- USE_ANAME
- V5_SHARED_LIB_OBJS
- V5_USE_SHARED_LIB
- KRB5_LIBRARIES
- KRB5_RUN_FLAGS
- SubdirLibraryRule([${OBJS}])
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/os/kuserok.c
diff -c krb5/lib/krb5/os/kuserok.c:1.1.1.2 krb5/lib/krb5/os/kuserok.c:1.4
*** krb5/lib/krb5/os/kuserok.c:1.1.1.2	Fri Feb 22 16:37:19 2002
--- krb5/lib/krb5/os/kuserok.c	Mon Feb 25 00:17:21 2002
***************
*** 80,87 ****
--- 80,98 ----
      if ((pwd = getpwnam(luser)) == NULL) {
  	return(FALSE);
      }
+ #ifdef KRB5_K5LOGIN_DIR
+     /*
+      * If specified by configure, look for the .k5login file in a different
+      * spot.
+      */
+ 
+     (void) strncpy(pbuf, KRB5_K5LOGIN_DIR "/", sizeof(pbuf) - 1);
+     pbuf[sizeof(pbuf) - 1] = '\0';
+     strncat(pbuf, luser, sizeof(pbuf) - 1 - strlen(pbuf));
+ #else /* KRB5_K5LOGIN_DIR */
      (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1);
      pbuf[sizeof(pbuf) - 1] = '\0';
+ #endif /* KRB5_K5LOGIN_DIR */
      (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf));
  
      if (access(pbuf, F_OK)) {	 /* not accessible */
Index: krb5/lib/krb5/os/macsock.c
diff -c krb5/lib/krb5/os/macsock.c:1.1.1.1 krb5/lib/krb5/os/macsock.c:removed
*** krb5/lib/krb5/os/macsock.c:1.1.1.1	Mon Jun  2 17:57:30 1997
--- krb5/lib/krb5/os/macsock.c	Sun Mar 16 20:22:32 2003
***************
*** 1,826 ****
- /*
-  * macsock.c
-  *
-  * Macintosh socket implementation using MacTCP.
-  *
-  * This only implements what's needed for Cygnus Kerberos -- a warped
-  * subset of UDP.
-  *
-  * Written by John Gilmore, Cygnus Support, June 1994.
-  * Adapted from:
- 	Interface into the UDP class.
- 	Written by Timothy Miller for Brown University.
-  */
- 
- #include "k5-int.h"
- #ifdef	HAVE_MACSOCK_H
- 
- /* C includes */
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- 
- /* Mac includes */
- #include <Memory.h>
- #include <Devices.h>
- #include <errno.h>		/* For ENOMEM */
- 
- #ifndef ENOMEM			/* Think C <errno.h> doesn't have ENOMEM */
- #define	ENOMEM	ENOSPC
- #endif
- 
- /* Our own include file */
- #include "macsock.h"
- 
- /* MacTCP headers from Apple */
- #include "AddressXlation.h"		/* MacTCP Domain name resolver decls */
- #include "MacTCP.h"
- 
- typedef union {
- 	UDPiopb		udppb;
- 	TCPiopb		tcppb;
- } sockunion;
- 
- /* This WinSock-ism is just too ugly to use everywhere.  */
- #define	SOCKET_SET_ERRNO	WSASetLastError
- 
- /* Description of our WinSock implementation... */
- struct WSAData macsock_data = {
- 	0x0101,		/* wVersion = 1.1 */
- 	0x0101,		/* wHighVersion = 1.1 */
- 	"Mac Sockets implemented on top of MacTCP, by John Gilmore of\
- Cygnus Support (email info@cygnus.com).",
- 	"It only implements a small subset of UDP for now.",
- 	107,		/* iMaxSockets, arbitrary number */
- 	UDPbuflen,	/* iMaxUDPDg, max datagram size */
- 	0			/* lpVendorInfo, nonexistent */
- };
- 
- #define kMaxIPPOpenTries 3
- 	
- /* This variable implements a kludge in which select() always says that
-    sockets are ready for I/O, but recvfrom() actually implements the
-    timeout that select() had requested.  This hack happens to work
-    for Kerberos, which is all that we care about right now.  */
- static struct timeval last_timeout;
- 
- /* IH 04.03.96: Need UPP for PPC port */
- static ResultUPP gDNRresultupp = NULL;
- 
- 
- /* Forward declarations of static functions */
- 
- static pascal void	DNRresultproc(struct hostInfo *hinfo, char *userdata);
- 
- 
- /* Start using sockets */
- int
- WSAStartup(WORD wVersionRequested, WSADATA *data)
- {
- 	if (LOBYTE (wVersionRequested) < 1 ||
- 	    (LOBYTE (wVersionRequested) == 1 && HIBYTE (wVersionRequested) < 1))
- 		return WSAVERNOTSUPPORTED;
- 	if (data)
- 		*data = macsock_data;
- 	return 0;
- }
- 
- /* Finish using sockets */
- int
- WSACleanup()
- {
- 	return 0;
- }
- 
- /* Get a particular socket */
- SOCKET
- socket(af, type, protocol)
- 	int af;
- 	int type;
- 	int protocol;
- {
- 	SOCKET  theUDP;
- 	short	refNum;
- //	UDPiopb		pb;
- 	sockunion	pb;
- 	OSErr	err;
- 	int		tries;
- 
- 	if (af != AF_INET) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return INVALID_SOCKET;
- 	}
- 	if (type != SOCK_DGRAM && type != SOCK_STREAM) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return INVALID_SOCKET;
- 	}
- 	if (protocol != 0) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return INVALID_SOCKET;
- 	}
- 
- 	theUDP = malloc (sizeof (*theUDP));
- 	if (theUDP == 0) {
- 		SOCKET_SET_ERRNO (ENOMEM);
- 		return INVALID_SOCKET;
- 	}
- 
- 	err = -1;
- 	for(tries=0;tries<kMaxIPPOpenTries && err != noErr;tries++)
- 	{
- 		err = OpenDriver( "\p.IPP", &refNum );
- 	}
- 	if (err) {
- 		free (theUDP);
- 		SOCKET_SET_ERRNO (EIO);
- 		return INVALID_SOCKET;
- 	}
- 	theUDP->fMacTCPRef = refNum;
- 	theUDP->fType = type;
- 	switch(theUDP->fType)
- 	{
- 	case SOCK_DGRAM:
- 		/* Set up param blocks and create the socket (called a 
- 		   stream by MacTCP).  */
- 		pb.udppb.ioCRefNum					= theUDP->fMacTCPRef;
- 		pb.udppb.csCode						= UDPCreate;
- 		pb.udppb.csParam.create.rcvBuff		= theUDP->fRecvBuf;
- 		pb.udppb.csParam.create.rcvBuffLen	= UDPbuflen;
- 		pb.udppb.csParam.create.notifyProc	= NULL;
- 		pb.udppb.csParam.create.localPort		= 0;
- 	
- 		err = PBControl( (ParamBlockRec *) &pb.udppb, false );
- 		if (err) {
- 			free (theUDP);
- 			SOCKET_SET_ERRNO (EIO);
- 			return INVALID_SOCKET;
- 		}
- 		theUDP->fStream = (unsigned long)pb.udppb.udpStream;
- 	
- 		theUDP->connect_addr.sin_family = 0;
- 		theUDP->connect_addr.sin_port = 0;
- 		theUDP->connect_addr.sin_addr.s_addr = 0;
- 		break;
- 
- 	case SOCK_STREAM:
- 		memset((char *) &pb, '\0', sizeof(pb));	
- 		pb.tcppb.ioCRefNum = theUDP->fMacTCPRef;
- 		pb.tcppb.csCode = TCPCreate;
- 		pb.tcppb.csParam.create.rcvBuff = theUDP->fRecvBuf;
- 		pb.tcppb.csParam.create.rcvBuffLen = TCPbuflen;
- 		pb.tcppb.csParam.create.notifyProc = NULL;
- 		err = PBControl((ParamBlockRec *)&pb,false);
- 		if (err) {
- 			free(theUDP);
- 			SOCKET_SET_ERRNO (EIO);
- 			return INVALID_SOCKET;
- 		}
- 		theUDP->fStream = (unsigned long)pb.tcppb.tcpStream;
- 
- 		theUDP->connect_addr.sin_family = 0;
- 		theUDP->connect_addr.sin_port = 0;
- 		theUDP->connect_addr.sin_addr.s_addr = 0;
- 		break;
- 	}
- 	return theUDP;
- }
- 
- /* Finish using a particular socket.  */
- int
- closesocket (theUDP)
- 	SOCKET theUDP;
- {
- //	UDPiopb		pb;
- 	sockunion	pb;
- 
- 	switch(theUDP->fType)
- 	{
- 	case SOCK_DGRAM:
- 		if (theUDP->fStream) {
- 			pb.udppb.ioCRefNum	= theUDP->fMacTCPRef;
- 			pb.udppb.csCode		= UDPRelease;
- 			pb.udppb.udpStream	= (StreamPtr) theUDP->fStream;
- 	
- 			(void) PBControl( (ParamBlockRec *) &pb.udppb, false );
- 		}
- 		break;
- 	case SOCK_STREAM:
- 		if (theUDP->fStream) {
- 			pb.tcppb.ioCRefNum	= theUDP->fMacTCPRef;
- 			pb.tcppb.csCode		= TCPRelease;
- 			pb.tcppb.tcpStream	= (StreamPtr) theUDP->fStream;
- 	
- 			(void) PBControl( (ParamBlockRec *) &pb.tcppb, false );
- 		}
- 		break;
- 	}
- 
- 	free(theUDP);
- 	return 0;
- }
- 
- 
- /* Bind a socket to a particular address.
-    In our case, this is just a no-op for bug-compatability with
-    the FTP Software WINSOCK library.  */
- int
- bind (s, name, namelen)
- 	SOCKET s;
- 	const struct sockaddr *name;
- 	int namelen;
- {
- 	if (name->sin_family != AF_INET) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- #if 0
- 	if (namelen != sizeof (struct sockaddr_in)) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 	if (name->sin_addr.s_addr != INADDR_ANY) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- #endif
- 	/* OK, then, it's a no-op.  */
- 	s - s;		/* lint */
- 	return 0;
- }
- 
- 
- /* Send a packet to a UDP peer.  */
- int
- sendto (theUDP, buf, len, flags, to_param, tolen)
- 	SOCKET theUDP;
- 	const char *buf;
- 	const int len; 
- 	int flags;
- 	const struct sockaddr *to_param;
- 	int tolen;
- {
- 	OSErr		err;
-     /* really 1 wds + extra space for terminating null */
- 	wdsEntry	wds[2];
- 	UDPiopb		pb;
- 	struct sockaddr_in *to = (struct sockaddr_in *)to_param;
- 
- 	if (tolen != sizeof (struct sockaddr_in)) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 	if (to->sin_family != AF_INET) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 
- 	wds[0].length	= len;
- 	wds[0].ptr		= (char *) buf;
- 	wds[1].length	= 0;
- 
- 	pb.ioCRefNum				= theUDP->fMacTCPRef;
- 	pb.csCode					= UDPWrite;
- 	pb.udpStream				= (StreamPtr) theUDP->fStream;
- 	pb.csParam.send.remotePort	= to->sin_port;
- 	pb.csParam.send.wdsPtr		= (Ptr) wds;
- 	pb.csParam.send.checkSum	= 1;			// TRUE
- 	pb.csParam.send.sendLength	= 0;			// reserved
- 	pb.csParam.send.remoteHost	= to->sin_addr.s_addr;
- 
- 	err = PBControl( (ParamBlockRec *) &pb, false );
- 	if (err != noErr) {
- 		SOCKET_SET_ERRNO (EIO);
- 		return SOCKET_ERROR;
- 	}
- 	return len;
- }
- 
- /* Select for sockets that are ready for I/O.
-    This version just remembers the timeout for a future receive...
-    It always reports that one socket is ready for I/O.
-  */
- int
- select (nfds, readfds, writefds, exceptfds, timeout)
- 	int nfds;
- 	fd_set *readfds;
- 	fd_set *writefds;
- 	fd_set *exceptfds;
- 	const struct timeval *timeout;
- {
- 	if (timeout)
- 		last_timeout = *timeout;
- 	return 1;	/* Claim that a single FD is ready */
- 	/* Note that readfd, writefds, and exceptfds still have all
- 	   of their current values, indicating that they're all ready
-  	   for I/O.  */
- }
- 
- 
- /* Receive a packet from a UDP peer.  */
- int
- recvfrom (theUDP, buf, len, flags, from_param, fromlen)
- 	SOCKET theUDP;	
- 	char *buf;
- 	int len; 
- 	int flags;
- 	struct sockaddr *from_param;
- 	int *fromlen;
- {
- 	OSErr		err;
- 	UDPiopb		pb;
- 	int			packet_len;
- 	struct sockaddr_in *from = (struct sockaddr_in *)from_param;
- 	
- 	if (*fromlen < sizeof (*from)) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 
- 	pb.ioCRefNum						= theUDP->fMacTCPRef;
- 	pb.csCode							= UDPRead;
- 	pb.udpStream						= (StreamPtr) theUDP->fStream;
- 	pb.csParam.receive.timeOut			= last_timeout.tv_sec;
- 	pb.csParam.receive.secondTimeStamp	= 0;			// reserved
- 
- 	err = PBControl( (ParamBlockRec *) &pb, false );
- 	if( err ) {
- 		SOCKET_SET_ERRNO (EIO);
- 		return SOCKET_ERROR;
- 	}
- 
- 	packet_len = pb.csParam.receive.rcvBuffLen;
- 	if( len > packet_len )
- 		len = packet_len;	/* only move as much as we got */
- 	BlockMove( pb.csParam.receive.rcvBuff, buf, len );
- 	*fromlen = sizeof (*from);
- 	from->sin_family = AF_INET;
- 	from->sin_port = pb.csParam.receive.remotePort;
- 	from->sin_addr.s_addr = pb.csParam.receive.remoteHost;
- 
- 	if( pb.csParam.receive.rcvBuffLen ) {
- 		pb.csCode = UDPBfrReturn;
- 		err = PBControl( (ParamBlockRec *) &pb, false );
- 	}
- 
- 	if (len < packet_len) {
- 		/* Only got first part of packet, rest was dropped. */
- 		SOCKET_SET_ERRNO (EMSGSIZE);
- 		return SOCKET_ERROR;
- 	}
- 	return len;
- }
- 
- /* On BSD systems, a connected UDP socket will get connection
-    refused and net unreachable errors while an unconnected
-    socket will time out, so K5 uses connect, send, recv instead of
-    sendto, recvfrom.  We happily fake this too...   */
- 
- int
- connect (s, addr, tolen)
- 	SOCKET s;
- 	struct sockaddr *addr;
- 	int tolen;
- {
- 	sockunion pb;
- 	OSErr err;
- 	
- 	if (tolen != sizeof (struct sockaddr_in)) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 	if (addr->sin_family != AF_INET) {
- 		SOCKET_SET_ERRNO (EINVAL);
- 		return SOCKET_ERROR;
- 	}
- 
- 	s->connect_addr = *addr;		/* Save the connect address */
- 	switch(s->fType)
- 	{
- 	case SOCK_DGRAM:
- 		break;
- 	case SOCK_STREAM:
- 		memset((char *) &pb, '\0', sizeof(pb));	
- 		pb.tcppb.ioCRefNum = s->fMacTCPRef;
- 		pb.tcppb.csCode = TCPActiveOpen;
- 		pb.tcppb.tcpStream = s->fStream;
- 		pb.tcppb.csParam.open.ulpTimeoutValue = 15 /* seconds */;
- 		pb.tcppb.csParam.open.ulpTimeoutAction = 1 /* 1:abort 0:report */;
- 		pb.tcppb.csParam.open.validityFlags = timeoutValue | timeoutAction;
- 		pb.tcppb.csParam.open.commandTimeoutValue = 0;		/* jfm timeout in 0 secs ? */
- 		pb.tcppb.csParam.open.remoteHost = addr->sin_addr.s_addr;
- 		pb.tcppb.csParam.open.remotePort = addr->sin_port;
- 		pb.tcppb.csParam.open.localHost = 0;
- 		pb.tcppb.csParam.open.localPort = 0; /* we'll get the port back later */
- 		pb.tcppb.csParam.open.tosFlags = 0;	/* jfm ? */
- 		pb.tcppb.csParam.open.precedence = 0;	/* jfm ? */
- 		pb.tcppb.csParam.open.dontFrag = 0;
- 		pb.tcppb.csParam.open.timeToLive = 0;
- 		pb.tcppb.csParam.open.security = 0;
- 		pb.tcppb.csParam.open.optionCnt = 0;
- 		pb.tcppb.csParam.open.userDataPtr = 0;	/* jfm */
- 		err = PBControl((ParamBlockRec *)&pb.tcppb,false);
- 		if (err) {
- 			SOCKET_SET_ERRNO (EINVAL);
- 			return SOCKET_ERROR;
- 		}
- 		
- 		s->connect_addr.sin_addr.s_addr = pb.tcppb.csParam.open.localHost;
- 		s->connect_addr.sin_port = pb.tcppb.csParam.open.localPort;
- 
- 		break;
- 	}
- 	return 0;
- }
- 
- /* Receive a packet from a UDP peer.  */
- int
- recv (theUDP, buf, len, flags)
- 	SOCKET theUDP;	
- 	char *buf;
- 	int len; 
- 	int flags;
- {
- 	sockunion pb;
- 	struct sockaddr_in from;
- 	int fromlen;
- 	OSErr err;
- 
- 	switch(theUDP->fType)
- 	{
- 	case SOCK_DGRAM:
- 		fromlen = sizeof(from);
- 		return recvfrom (theUDP, buf, len, flags, &from, &fromlen);
- 		/* We could check if the packet is from the right place, but 
- 		   it isn't clear this is required, so punt.  */
- 	case SOCK_STREAM:
- 		pb.tcppb.ioCRefNum = theUDP->fMacTCPRef;
- 		pb.tcppb.csCode = TCPRcv;
- 		pb.tcppb.csParam.receive.commandTimeoutValue = 0 /* infinity */;
- 		pb.tcppb.csParam.receive.rcvBuff = buf;
- 		pb.tcppb.csParam.receive.rcvBuffLen = len;
- 		pb.tcppb.tcpStream = theUDP->fStream;
- 		err = PBControl((ParamBlockRec *)&pb.tcppb,false);
- 		if (err) {
- 			SOCKET_SET_ERRNO (EIO);
- 			return SOCKET_ERROR;
- 		}
- 		return pb.tcppb.csParam.receive.rcvBuffLen;
- 	}
- }
- 
- /* Send a packet to a UDP peer.  */
- int
- send (theUDP, buf, len, flags)
- 	SOCKET theUDP;
- 	const char *buf;
- 	const int len; 
- 	int flags;
- {
- 	OSErr		err;
- 	sockunion	pb;
- 	wdsEntry	wds[2];
- 
- 	switch(theUDP->fType)
- 	{
- 	case SOCK_DGRAM:
- 		return sendto (theUDP, buf, len, flags,
- 			       &theUDP->connect_addr, sizeof(theUDP->connect_addr));
- 
- 	case SOCK_STREAM:
- 		wds[0].length	= len;
- 		wds[0].ptr		= (char *) buf;
- 		wds[1].length	= 0;
- 		pb.tcppb.ioCRefNum = theUDP->fMacTCPRef;
- 		pb.tcppb.csCode = TCPSend;
- 		pb.tcppb.csParam.send.validityFlags = timeoutValue | timeoutAction;
- 		pb.tcppb.csParam.send.ulpTimeoutValue = 60 /* seconds */;
- 		pb.tcppb.csParam.send.ulpTimeoutAction = 1 /* 1:abort 0:report */;
- 		pb.tcppb.csParam.send.pushFlag = true;
- 		pb.tcppb.csParam.send.urgentFlag = false;
- 		pb.tcppb.csParam.send.wdsPtr = (Ptr) wds;
- 		pb.tcppb.tcpStream = theUDP->fStream;
- 		err = PBControl((ParamBlockRec *)&pb.tcppb,false);
- 		if (err) {
- 			SOCKET_SET_ERRNO (EIO);
- 			return SOCKET_ERROR;
- 		}
- 		return len;
- 	}
- }
- 
- /*
- 	Interface UNIX routine inet_ntoa with mac equivalent.
- 
- 	The input argument is a struct containing the internet address.
- 	struct type defined in config-mac.h
- 
- 	The routine inet_ntoa() returns a pointer to a string in the
- 	base 256 notation ``d.d.d.d'' 
- */
-  
-  
- char* 
- inet_ntoa(struct in_addr ina) {
- 	OSErr err;
- #define	max_addr_str 16
- 	char addrStr[max_addr_str];
- 
- 	err = AddrToStr(ina.s_addr, addrStr);
- 	return addrStr;
- 
- }
- 
- /* Static variables which provide space for the last result from getXbyY.  */
- 
- static struct hostInfo		host;
- static char *				ipaddr_ptrs[NUM_ALT_ADDRS+1];
- static struct hostent		result;
- static struct in_addr		ourAddr;
- 	
- /*
-    Performs a domain name resolution of host, returning an IP address for it,
-    or 0 if any error occurred. 
- 	   
-    FIXME -- this routine has the potential to go asynchronous, but it
-    loops until the asynchronous call to MacTCP finishes.  
-  */
- 	
- struct hostent *
- gethostbyname (char *hostname)
- {
- 	OSErr						err;
- 	char						done = false;
- 	int							i;
- 		
- 	if (err = OpenResolver(NULL))
- 		return(0);	// make sure resolver is open
- 	
- 	//  IH 04.03.96: Need UPP when running on PPC
- 	if (gDNRresultupp == NULL)
- 		gDNRresultupp = NewResultProc(DNRresultproc);
- 	err = StrToAddr(hostname, &host, gDNRresultupp, &done);
- 	
- 	if (err == cacheFault) {
- 		while(!done) ;			/* LOOP UNTIL CALLBACK IS RUN */
- 		err = host.rtnCode;		/* Pick up final result code */
- 		}
- 	
- 	if (err != noErr) {
- 		return 0;
- 		}
- 	/* take off a period from the end of the connonical host name */
- 	{
- 	int hostnamelen = strlen(host.cname);
- 		if (host.cname[hostnamelen-1] == '.')
- 			host.cname[hostnamelen-1] = 0;
- 	}
- 	
- 	
- 	/* Build result in hostent structure, which we will return to caller.  */
- 	
- 	result.h_name = host.cname;
- 	result.h_aliases = 0;			/* We don't know about aliases.  */
- 	result.h_addrtype = AF_INET;
- 	result.h_length = sizeof (host.addr[0]);	/* Length of each address */
- 	result.h_addr_list = ipaddr_ptrs;
-     for (i = 0; i < NUM_ALT_ADDRS; i++)
- 		if (host.addr[i] != 0)				/* Assume addrs terminated with 0 addr */
- 			ipaddr_ptrs[i] = (char*) &host.addr[i];		/* Point at good IP addresses */
- 		else
- 			break;					/* Quit when we see first zero address */
- 	ipaddr_ptrs[i] = 0;
- 	
- 	return &result;
- }
- 
- /* Does a reverse DNS lookup of addr, to find the canonical name of its host.
-    FIXME, set errno for failures.  */
- 
- struct hostent *
- gethostbyaddr (char *addr, int len, int type)
- {
- 	OSErr				err;
- 	char				done = false;
- 	ip_addr				macaddr;
- 	
- 	if (type != AF_INET)
- 		return 0;			/* We only do Internet addresses */
- 	if (len != sizeof (ip_addr))
- 		return 0;			/* We only handle IP addrs *this* long... */
- 	memcpy ((void *)&macaddr, (void *)addr, (size_t)len);
- 		
- 	if (err = OpenResolver(NULL))
- 		return 0;	// make sure resolver is open
- 	//  IH 04.03.96: Need UPP when running on PPC
- 	if (gDNRresultupp == NULL)
- 		gDNRresultupp = NewResultProc(DNRresultproc);
- 	err = AddrToName(macaddr, &host, gDNRresultupp, &done);
- 	
- 	if (err == cacheFault) {
- 		while(!done) ;			/* LOOP UNTIL CALLBACK IS RUN */
- 		err = host.rtnCode;		/* Pick up final result code */
- 		}
- 	
- 	if (err != noErr) {
- 		/* Set errno? FIXME.  */
- 		return 0;
- 		}
- 
- 	/* take off a period from the end of the connonical host name */
- 	{
- 	int hostnamelen = strlen(host.cname);
- 		if (host.cname[hostnamelen-1] == '.')
- 			host.cname[hostnamelen-1] = 0;
- 	}
- 
- 	/* Build result in hostent structure, which we will return to caller.  */
- 	
- 	result.h_name = host.cname;
- 	result.h_aliases = 0;			/* We don't know about aliases.  */
- 	result.h_addrtype = AF_INET;
- 	result.h_length = sizeof (host.addr[0]);	/* Length of each address */
- 	result.h_addr_list = 0;		/* MacTCP doesn't give us this info on addr->name */
- 	
- 	return &result;
- }
- 
- /* Tell calling program that the asynchronous operation has finished.
-    FIXME, this will require significant work if we support async calls to
-    Kerberos in the future.  */
- static pascal void
- DNRresultproc(struct hostInfo *hinfo, char *userdata)
- {
- 	*userdata = true;
- }
- 
- /* Return a hostent filled in with my own IP address(es).   The rest of
-    the hostent is probably not useful.  */
- 
- struct hostent *
- getmyipaddr ()
- {
- 	SOCKET sock;
- 	struct GetAddrParamBlock pb;
- 	int err;
- 	
- 	sock = socket (AF_INET, SOCK_DGRAM, 0);
- 	if (sock == INVALID_SOCKET)
- 		return 0;
- 	pb.ioCRefNum	= sock->fMacTCPRef;
- 	pb.csCode		= ipctlGetAddr;
- 	err = PBControl( (ParamBlockRec *) &pb, false );
- 	if (err) {
- 		closesocket (sock);
- 		SOCKET_SET_ERRNO (EIO);
- 		return 0;
- 	}
- 	ourAddr.s_addr = pb.ourAddress;
- 
- 	/* Build result in hostent structure, which we will return to caller. */
- 	
- 	result.h_name = 0;
- 	result.h_aliases = 0;		/* We don't know about aliases.  */
- 	result.h_addrtype = AF_INET;
- 	result.h_length = sizeof (host.addr[0]);  /* Length of each address */
- 	result.h_addr_list = ipaddr_ptrs;
- 	ipaddr_ptrs[0] = (char*) &ourAddr.s_addr;	/* h_addr_list is a pointer to a list of pointers... */
- 	ipaddr_ptrs[1] = 0;
- 
- 	closesocket (sock);
- 
- 	return &result;
- }
- 
- 
- #define MACHOSTNAME "unknownmac"
- 
- int
- gethostname(char *name, int namelen)
- {
- short int					refnum;
- int							err;
- ip_addr						ipaddr;
- struct hostent				*hp;
- struct GetAddrParamBlock	pb;
- 
- /* get my ip address from mactcp */
- 	err = OpenDriver( "\p.IPP", &refnum );
- 	pb.ioCRefNum	= refnum;
- 	pb.csCode		= ipctlGetAddr;
- 	err = PBControl( (ParamBlockRec *) &pb, false );
- 	if (err) {
- 		SOCKET_SET_ERRNO (EIO);
- 		return 0;
- 	}
- /*jfm we never close this driver */
- 
- /* from that address find my name by asking the nameserver to resolve
-  * the name from an address
-  */
- 	ipaddr = pb.ourAddress;
- 	hp = gethostbyaddr((char*) &ipaddr, sizeof(ip_addr), AF_INET);
- 	if( hp == NULL)  
- 		strcpy( name, MACHOSTNAME);				/* give the default name */
- 	else
- 	{
- 		strncpy( name, hp->h_name, namelen);	/* use the name given */
- 		name[namelen-1] = 0;					/* terminate the string just in case */
- 	}
- 
- 	return 0;
- }
- 
- #if 0
- /* FIXME:  THIS WAS A STAB AT GETHOSTNAME, which I abandoned for lack of need,
-    and since the required header files didn't seem to be handy.
- 						-- gnu@cygnus.com  june94 */
- /*
-  * gethostname
-  *
-  * Gets our own host name, by getting our IP address and asking what name
-  * corresponds.  There seems to be no better way in MacTCP to do this.
-  */
-  int
-  gethostname(name, namelen)
-  	char *name;
- 	int namelen;
- {
- 	ip_addr ourAddress;
- 	SOCKET sock;
- 	struct IPParamBlock pb;
- 	struct hostent *host;
- 	struct sockaddr_in hostaddr;
- 	
- 	sock = socket (AF_INET, SOCK_DGRAM, 0);
- 	if (sock == INVALID_SOCKET)
- 		return -1;
- 	pb.ioCRefNum	= sock->fMacTCPRef;
- 	pb.csCode		= ipctlGetAddr;
- 	err = PBControl( (ParamBlockRec *) &pb, false );
- 	if (err) {
- 		free (theUDP);
- 		SOCKET_SET_ERRNO (EIO);
- 		return -1;
- 	}
- 	
- 
- 	pb.csParam.xxxx
- 	
- 	host = gethostbyaddr (&hostaddr, sizeof (hostaddr), AF_INET);
- 	if (!host)
- 		return -1;
- 	len = strlen (host->h_name);
- 	if (len > namelen)
- 		return -1;
- 	memcpy (name, host->h_name, len+1);
- 	return 0;
- }
- 
- #endif
- 
- int
- getsockname(s, name, namelen)
-         SOCKET s;
-         struct sockaddr_in *name;
-         int *namelen;
- {
-     struct hostent *hp;
- 
-     hp = getmyipaddr();
- 
-     if (hp == NULL)
- 	return -1;
- 
-     if (*namelen < sizeof(struct sockaddr_in)) {
- 	SOCKET_SET_ERRNO(EIO);
- 	return -1;
-     }
-     
-     name->sin_family = hp->h_addrtype;
-     memcpy((char *)&name->sin_addr, hp->h_addr, hp->h_length);
-     
-     *namelen = sizeof(struct sockaddr_in);
- 
-     return (0);
- }
- 
- int
- getpeername(s, name, namelen)
-         SOCKET s;
-         struct sockaddr_in *name;
-         int *namelen;
- {
- 
-         if (s == NULL)
-                 return(EINVAL);
- 
-         if (*namelen < sizeof(struct sockaddr_in))
-                 return(EINVAL);
- 
-         *namelen = sizeof(struct sockaddr_in);
-         *name = s->connect_addr;
- 
-         return(0);
- }
- #endif /* HAVE_MACSOCK_H */
--- 0 ----
Index: krb5/lib/krb5/os/read_msg.c
diff -c krb5/lib/krb5/os/read_msg.c:1.1.1.2 krb5/lib/krb5/os/read_msg.c:1.2
*** krb5/lib/krb5/os/read_msg.c:1.1.1.2	Fri Feb 22 16:37:23 2002
--- krb5/lib/krb5/os/read_msg.c	Fri Dec 13 19:58:12 2002
***************
*** 57,63 ****
--- 57,69 ----
  	if (ilen) {
  		/*
  		 * We may want to include a sanity check here someday....
+ 		 *
+ 		 * "today" is someday.
  		 */
+ 		
+ 		if (ilen > 1E6) {
+ 			return(ENOMEM);
+ 		}
  		if (!(buf = malloc(ilen))) {
  			return(ENOMEM);
  		}
Index: krb5/lib/krb5/posix/.cvsignore
diff -c /dev/null krb5/lib/krb5/posix/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:33 2003
--- krb5/lib/krb5/posix/.cvsignore	Thu Jun  5 10:39:55 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/posix/configure.in
diff -c krb5/lib/krb5/posix/configure.in:1.1.1.1 krb5/lib/krb5/posix/configure.in:removed
*** krb5/lib/krb5/posix/configure.in:1.1.1.1	Mon Jun  2 17:57:32 1997
--- krb5/lib/krb5/posix/configure.in	Sun Mar 16 20:22:33 2003
***************
*** 1,10 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- SubdirLibraryRule([${OBJS}])
- V5_SHARED_LIB_OBJS
- AC_CONST
- AC_HEADER_CHECK(paths.h,AC_DEFINE(HAS_PATHS_H))
- AC_HAVE_FUNCS(setenv unsetenv getenv)
- AC_REPLACE_FUNCS(vfprintf vsprintf strdup strcasecmp strerror memmove daemon getuid sscanf syslog)
- AC_FUNC_CHECK(setsid,AC_DEFINE(HAS_SETSID))
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/rcache/.cvsignore
diff -c /dev/null krb5/lib/krb5/rcache/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:33 2003
--- krb5/lib/krb5/rcache/.cvsignore	Thu Jun  5 10:39:56 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/krb5/rcache/configure.in
diff -c krb5/lib/krb5/rcache/configure.in:1.1.1.1 krb5/lib/krb5/rcache/configure.in:removed
*** krb5/lib/krb5/rcache/configure.in:1.1.1.1	Mon Jun  2 17:57:34 1997
--- krb5/lib/krb5/rcache/configure.in	Sun Mar 16 20:22:33 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- V5_SHARED_LIB_OBJS
- SubdirLibraryRule([${OBJS}])
- AC_TYPE_UID_T
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/lib/krb5/rcache/rc_dfl.c
diff -c krb5/lib/krb5/rcache/rc_dfl.c:1.1.1.2 krb5/lib/krb5/rcache/rc_dfl.c:1.3
*** krb5/lib/krb5/rcache/rc_dfl.c:1.1.1.2	Fri Feb 22 16:37:32 2002
--- krb5/lib/krb5/rcache/rc_dfl.c	Sun Feb 24 20:38:37 2002
***************
*** 115,120 ****
--- 115,121 ----
    krb5_rc_iostuff d;
  #endif
    char recovering;
+   char expunging;
   }
  ;
  
***************
*** 293,298 ****
--- 294,300 ----
      t->d.fd = -1;
  #endif
      t->recovering = 0;
+     t->expunging = 0;
      return 0;
      
  cleanup:
***************
*** 467,473 ****
      krb5_rc_free_entry(context, &rep);
      if (retval)
  	krb5_rc_io_close(context, &t->d);
!     else if (expired_entries > EXCESSREPS)
  	retval = krb5_rc_dfl_expunge(context, id);
      t->recovering = 0;
      return retval;
--- 469,475 ----
      krb5_rc_free_entry(context, &rep);
      if (retval)
  	krb5_rc_io_close(context, &t->d);
!     else if (! t->expunging && expired_entries > EXCESSREPS)
  	retval = krb5_rc_dfl_expunge(context, id);
      t->recovering = 0;
      return retval;
***************
*** 588,597 ****
--- 590,601 ----
  	free(name);
  	if (retval)
  	    return retval;
+ 	((struct dfl_data *)id->data)->expunging = 1;
  	retval = krb5_rc_dfl_recover(context, id);
  	if (retval)
  	    return retval;
  	t = (struct dfl_data *)id->data; /* point to recovered cache */
+ 	t->expunging = 0;
      }
  
      tmp = (krb5_rcache) malloc(sizeof(*tmp));
Index: krb5/lib/krb5util/.cvsignore
diff -c /dev/null krb5/lib/krb5util/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:33 2003
--- krb5/lib/krb5util/.cvsignore	Thu Jun  5 10:39:57 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/rpc/.cvsignore
diff -c /dev/null krb5/lib/rpc/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:33 2003
--- krb5/lib/rpc/.cvsignore	Thu Jun  5 10:39:58 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/lib/rpc/getrpcent.c
diff -c krb5/lib/rpc/getrpcent.c:1.1.1.2 krb5/lib/rpc/getrpcent.c:1.3
*** krb5/lib/rpc/getrpcent.c:1.1.1.2	Fri Feb 22 16:37:44 2002
--- krb5/lib/rpc/getrpcent.c	Sun Feb 24 21:46:55 2002
***************
*** 116,122 ****
--- 116,127 ----
  
  struct rpcent *
  getrpcbyname(name)
+ #ifdef __convex__
+ 	char *name;
+ #else
  	const char *name;
+ 
+ #endif
  {
  	struct rpcent *rpc;
  	char **rp;
Index: krb5/lib/rpc/netdb.h
diff -c krb5/lib/rpc/netdb.h:1.1.1.2 krb5/lib/rpc/netdb.h:1.3
*** krb5/lib/rpc/netdb.h:1.1.1.2	Fri Feb 22 16:37:43 2002
--- krb5/lib/rpc/netdb.h	Sun Feb 24 21:46:55 2002
***************
*** 46,51 ****
--- 46,54 ----
  };
  #endif /*STRUCT_RPCENT_IN_RPC_NETDB_H*/
  
+ #ifndef __convex__
+ /* Convex defines these slightly differently and makes gcc barf	*/
  struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent();
+ #endif
  
  #endif
Index: krb5/lib/rpc/svc_auth_gssapi.c
diff -c krb5/lib/rpc/svc_auth_gssapi.c:1.1.1.3 krb5/lib/rpc/svc_auth_gssapi.c:1.4
*** krb5/lib/rpc/svc_auth_gssapi.c:1.1.1.3	Fri Feb 22 16:37:52 2002
--- krb5/lib/rpc/svc_auth_gssapi.c	Sun Feb 24 21:46:55 2002
***************
*** 1,7 ****
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   *
!  * $Id: svc_auth_gssapi.c,v 1.1.1.3 2002/02/22 21:37:52 kenh Exp $
   *
   */
  
--- 1,7 ----
  /*
   * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
   *
!  * $Id: svc_auth_gssapi.c,v 1.4 2002/02/25 02:46:55 kenh Exp $
   *
   */
  
Index: krb5/lib/rpc/unit-test/.cvsignore
diff -c /dev/null krb5/lib/rpc/unit-test/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:34 2003
--- krb5/lib/rpc/unit-test/.cvsignore	Thu Jun  5 10:40:01 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/mac/GSSLibrary.SAP.exp
diff -c krb5/mac/GSSLibrary.SAP.exp:1.1.1.1 krb5/mac/GSSLibrary.SAP.exp:removed
*** krb5/mac/GSSLibrary.SAP.exp:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/GSSLibrary.SAP.exp	Sun Mar 16 20:22:34 2003
***************
*** 1,39 ****
- __terminate
- __initializeSAPglue
- gss_acquire_cred			
- gss_release_cred			
- gss_init_sec_context		
- gss_accept_sec_context		
- gss_process_context_token		
- gss_delete_sec_context			
- gss_context_time			
- gss_sign				
- gss_verify				
- gss_seal				
- gss_unseal				
- gss_display_status			
- gss_indicate_mechs			
- gss_compare_name			
- gss_display_name			
- gss_import_name				
- gss_release_name			
- gss_release_buffer			
- gss_release_oid_set			
- gss_inquire_cred			
- gss_add_cred
- gss_inquire_cred_by_mech
- gss_inquire_context
- gss_wrap_size_limit
- gss_export_sec_context
- gss_import_sec_context
- gss_release_oid
- gss_create_empty_oid_set
- gss_add_oid_set_member
- gss_test_oid_set_member
- gss_oid_to_str
- gss_str_to_oid
- gss_wrap
- gss_unwrap
- gss_get_mic
- gss_verify_mic
- gss_inquire_names_for_mech
--- 0 ----
Index: krb5/mac/Makefile.tmpl
diff -c krb5/mac/Makefile.tmpl:1.1.1.1 krb5/mac/Makefile.tmpl:removed
*** krb5/mac/Makefile.tmpl:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/Makefile.tmpl	Sun Mar 16 20:22:34 2003
***************
*** 1,127 ****
- KH = /mac/libraries/
- KH68K = {KH}KerberosHeaders68K
- KHCFM-68K = {KH}KerberosHeadersCFM-68K
- KHPPC = {KH}KerberosHeadersPPC
- 
- GSSRTLCFM68K = "{MW68KLibraries}ANSI (4i%8d) C.CFM68K.Lib" \
- 	{MW68KLibraries}SIOUX.CFM68K.Lib \
- 	{MW68KLibraries}InterfaceLib \
- 	{MW68KLibraries}MWCFM68KRuntime.Lib \
- 	"{MW68KLibraries}MathLibCFM68K (4i%8d).Lib"
- 
- GSSRTLCFMPPC = "{MWPPCLibraries}ANSI C.PPC.Lib" \
- 	{MWPPCLibraries}SIOUX.PPC.Lib {MWPPCLibraries}MWCRuntime.Lib \
- 	{SharedLibraries}InterfaceLib {SharedLibraries}MathLib
- 
- OPTIONS = {INCLUDES} -enum int -opt all -strings pool -mapcr \
-         -mpw_pointers -warnings off -fatext -nosyspath -maxerrors 1000 \
-         -align mac68k -opt off -toc_data on -fp_contract on -sym fullpath
- 
- all : build link
- 
- libs : {KH68K} {KHPPC} {GSSOBJS68K} {GSSOBJS68KCFM} {GSSOBJSPPC} link
- 
- build : build-PPC build-68K build-68KCFM
- 
- build-68K : {KH68K}
- 	MWC68K {OPTIONS} -o "/bin/68K/" -prefix {KH68K} -model far {SRCS}
- 
- build-68KCFM : {KHCFM-68K} 
- 	MWC68K {OPTIONS} -o "/bin/CFM-68K/" -prefix {KHCFM-68K} \
- 		-model cfmflat {SRCS}
- 
- build-PPC : {KHPPC}
- 	MWCPPC {OPTIONS} -o "/bin/PPC/" -prefix {KHPPC} {SRCS}
- 
- .c.68K.o : .c
- 	MWC68K {DepDir}{Default}.c {OPTIONS} -prefix {KH68K} -model far
- 
- .c.PPC.o : .c
- 	MWCPPC {DepDir}{Default}.c {OPTIONS} -prefix {KHPPC}
- 
- {KH68K} : {KH}KerberosHeaders.pch {KH}KerberosHeaders.h
- 	MWC68K {KH}KerberosHeaders.pch -precompile {KH68K} {OPTIONS} -i {KH}
- 
- {KHCFM-68K} : {KH}KerberosHeaders.pch {KH}KerberosHeaders.h
- 	MWC68K {KH}KerberosHeaders.pch -precompile {KHCFM-68K} {OPTIONS} \
- 		-i {KH} -model cfmflat
- 
- {KHPPC} : {KH}KerberosHeaders.pch {KH}KerberosHeaders.h
- 	MWCPPC {KH}KerberosHeaders.pch -precompile {KHPPC} {OPTIONS} -i {KH}
- 
- link : link-68K link-68KCFM link-PPC link-CFMFAT
- 
- link-68K :
- 	MWLink68K -library -model far -o libkrb5.68K {K5OBJS68K}
- 	MWLink68K -library -model far -o libgss.68K {GSSOBJS68K}
- 	Rez "/mac/version.r" -a -o libkrb5.68K
- 	Rez "/mac/version.r" -a -o libgss.68K
- 
- link-68KCFM :
-         MWLink68K -xm sharedlibrary -name GSSLibrary -m "" \
- 		-model cfmflat -@export "/mac/GSSLibrary.exp" -sym fullpath \
-                 -map libgss.68K.MAP -o GSSLibrary68K \
- 		{GSSRTLCFM68K} {GSSOBJS68KCFM}
- 	Rez "/mac/version.r" -a -o GSSLibrary68K
- 
- link-PPC :
- 	MWLinkPPC -library -o libkrb5.PPC {K5OBJSPPC}
- 	MWLinkPPC -library -o libgss.PPC {GSSOBJSPPC}
- 	MWLinkPPC -sharedlibrary -name GSSLibrary -m "" \
- 		-@export "/mac/GSSLibrary.exp" -sym fullpath \
-         -map libgss.ppc.MAP -o GSSLibraryPPC \
- 		{GSSRTLCFMPPC} {GSSOBJSPPC}
- 	Rez "/mac/version.r" -a -o libkrb5.PPC
- 	Rez "/mac/version.r" -a -o libgss.PPC
- 	Rez "/mac/version.r" -a -o GSSLibraryPPC
- 
- 
- link-CFMFAT :
- 	Duplicate -y GSSLibrary68K GSSLib
- 	MergeFragment GSSLibraryPPC GSSLib
- 	
- clean :
- 	Delete -i {GSSOBJS68K} {GSSOBJSPPC} {GSSOBJS68KCFM}
- 
- # ---------------------
- # SAP related commands
- # ---------------------
- SRCS-SAP = /mac/SAP/macSAPglue.c
- GSSOBJS68KCFM-SAP = /bin/CFM-68K/macSAPglue.c.68k.o
- GSSOBJSPPC-SAP = /bin/PPC/macSAPglue.c.PPC.o
- INCLUDES-SAP = -i /mac/SAP/
- 
- OPTIONS-SAP = {INCLUDES-SAP} -enum int -opt all -strings pool -mapcr \
-         -mpw_pointers -warnings off -fatext -nosyspath -maxerrors 1000 \
-         -align mac68k -opt off -toc_data on -fp_contract on -sym fullpath
- 
- sap : build-SAP link-SAP
- 
- build-SAP : build-68KCFM build-PPC build-SAPINIT
- 
- build-SAPINIT : {KHCFM-68K} {KHPPC}
- 	MWC68K {OPTIONS-SAP} -o "/bin/CFM-68K/" -prefix {KHCFM-68K} \
- 		-model cfmflat {SRCS-SAP}
- 	MWCPPC {OPTIONS-SAP} -o "/bin/PPC/" -prefix {KHPPC} {SRCS-SAP}
- 
- link-SAP : link-68KCFM-SAP link-PPC-SAP link-CFMFAT-SAP
- 
- link-68KCFM-SAP :
- 	MWLink68K -xm sharedlibrary -name GSSLibrary -m "" \
- 		-model cfmflat -@export "/mac/GSSLibrary.SAP.exp" \
- 		-init "__initializeSAPglue" \
- 	        -sym fullpath -map libgss.68K.MAP -o GSSLibrarySAP.68K \
- 		{GSSRTLCFM68K} {GSSOBJS68KCFM-SAP} {GSSOBJS68KCFM}
- 	Rez "/mac/SAP/GSSforSAP.r" -a -o GSSLibrarySAP.68K
- 
- link-PPC-SAP :
- 	MWLinkPPC -sharedlibrary -name GSSLibrary -m "" \
- 		-@export "/mac/GSSLibrary.SAP.exp" \
- 		-init "__initializeSAPglue" \
- 	        -sym fullpath -map libgss.PPC.MAP -o GSSLibrarySAP.PPC \
- 		{GSSRTLCFMPPC} {GSSOBJSPPC-SAP} {GSSOBJSPPC}
- 	Rez "/mac/SAP/GSSforSAP.r" -a -o GSSLibrarySAP.PPC
- 	
- link-CFMFAT-SAP : 
- 	Duplicate -y GSSLibrarySAP.68K GSSLibSAP
- 	MergeFragment GSSLibrarySAP.PPC GSSLibSAP
--- 0 ----
Index: krb5/mac/macfiles.sh
diff -c krb5/mac/macfiles.sh:1.1.1.1 krb5/mac/macfiles.sh:removed
*** krb5/mac/macfiles.sh:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/macfiles.sh	Sun Mar 16 20:22:34 2003
***************
*** 1,12 ****
- #!/bin/sh
- 
- for DIR do
-   for SDIR in `sed -n -e 's/MAC_SUBDIRS.*=//p' $DIR/Makefile.in`; do
-     awk '/^MACSRCS?[ 	]*=/, /[^\\]$/' $DIR/$SDIR/Makefile.in | \
-       tr ' 	' '\012\012' | sed -n -e 's|.*[/)]\([A-Za-z0-9_]*\.c\).*|\1|' -e 's|\(.*\.c\)|'$DIR/$SDIR'/\1|p';
-     awk '/^SRCS?[ 	]*=/, /[^\\]$/' $DIR/$SDIR/Makefile.in | \
-       tr ' 	' '\012\012' | sed -n -e 's|.*[/)]\([A-Za-z0-9_]*\.c\).*|\1|' -e 's|\(.*\.c\)|'$DIR/$SDIR'/\1|p';
-     ls -1 $DIR/$SDIR/*.h 2> /dev/null
-     /bin/sh mac/macfiles.sh $DIR/$SDIR;
-   done
- done
--- 0 ----
Index: krb5/mac/mkbindirs.sh
diff -c krb5/mac/mkbindirs.sh:1.1.1.1 krb5/mac/mkbindirs.sh:removed
*** krb5/mac/mkbindirs.sh:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/mkbindirs.sh	Sun Mar 16 20:22:34 2003
***************
*** 1,13 ****
- #!/bin/sh
- #
- # This shell script creates the Macintosh binary hierarchies.
- 
- topbin=$1
- shift
- 
- for DIR do
-   mkdir $topbin/$DIR
-   for SDIR in `sed -n -e 's/MAC_SUBDIRS.*=//p' $DIR/Makefile.in`; do
-     /bin/sh mac/mkbindirs.sh $topbin $DIR/$SDIR;
-   done
- done
--- 0 ----
Index: krb5/mac/version.r
diff -c krb5/mac/version.r:1.1.1.1 krb5/mac/version.r:removed
*** krb5/mac/version.r:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/version.r	Sun Mar 16 20:22:34 2003
***************
*** 1,14 ****
- #ifdef mw_rez
- #include <SysTypes.r>
- #include <Types.r>
- #else
- #include "SysTypes.r"
- #include "Types.r"
- #endif
- 
- resource 'vers' (1) {
- 	0x01, 0x00, final, 0x00,
- 	verUS,
- 	"1.0",
- 	"1.0, Copyright 1996 Massachusetts Institute of Technology"
- };
--- 0 ----
Index: krb5/mac/SAP/GSSforSAP.r
diff -c krb5/mac/SAP/GSSforSAP.r:1.1.1.1 krb5/mac/SAP/GSSforSAP.r:removed
*** krb5/mac/SAP/GSSforSAP.r:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/SAP/GSSforSAP.r	Sun Mar 16 20:22:35 2003
***************
*** 1,129 ****
- #ifdef mw_rez
- #include <SysTypes.r>
- #include <Types.r>
- #else
- #include "SysTypes.r"
- #include "Types.r"
- #endif
- 
- resource 'vers' (1) {
- 	0x01, 0x00, final, 0x00,
- 	verUS,
- 	"1.0",
- 	"1.0(SAP), Copyright 1996 Massachusetts Institute of Technology"
- };
- 
- resource 'DITL' (135, nonpurgeable) {
- 	{	/* array DITLarray: 2 elements */
- 		/* [1] */
- 		{96, 292, 116, 360},
- 		Button {
- 			enabled,
- 			"OK"
- 		},
- 		/* [2] */
- 		{16, 64, 84, 360},
- 		StaticText {
- 			disabled,
- 			"This version of the SAP client has expir"
- 			"ed. Please consult: http://web.mit.edu/r"
- 			"eeng/www/saphelp/ for instructions on ob"
- 			"taining a new version."
- 		}
- 	}
- };
- 
- resource 'DITL' (136, nonpurgeable) {
- 	{	/* array DITLarray: 2 elements */
- 		/* [1] */
- 		{116, 300, 136, 368},
- 		Button {
- 			enabled,
- 			"OK"
- 		},
- 		/* [2] */
- 		{16, 64, 100, 360},
- 		StaticText {
- 			disabled,
- 			"This version of the SAP client will expi"
- 			"re on January 15, 1997. Please consult: "
- 			"http://web.mit.edu/reeng/www/saphelp/ fo"
- 			"r instructions on obtaining a new versio"
- 			"n when it is available."
- 		}
- 	}
- };
- 
- data 'DLGX' (135) {
- 	$"0743 6869 6361 676F 0000 0000 0000 0000"            /* .Chicago........ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"000C 0000 0000 0001 0004 0004 0000 0000"            /* ................ */
- 	$"0002 0000 0000 0000 0000 0000 0000 0006"            /* ................ */
- 	$"0000 0000 0000 0000 0000"                           /* .......... */
- };
- 
- data 'DLGX' (136) {
- 	$"0743 6869 6361 676F 0000 0000 0000 0000"            /* .Chicago........ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"0000 0000 0000 0000 0000 0000 0000 0000"            /* ................ */
- 	$"000C 0000 0000 0001 0004 0004 0000 0000"            /* ................ */
- 	$"0002 0000 0000 0000 0000 0000 0000 0006"            /* ................ */
- 	$"0000 0000 0000 0000 0000"                           /* .......... */
- };
- 
- data 'ictb' (136) {
- 	$"0000 0000 0000 0000"                                /* ........ */
- };
- 
- resource 'ALRT' (135, nonpurgeable) {
- 	{383, 390, 511, 770},
- 	135,
- 	{	/* array: 4 elements */
- 		/* [1] */
- 		OK, visible, sound1,
- 		/* [2] */
- 		OK, visible, sound1,
- 		/* [3] */
- 		OK, visible, sound1,
- 		/* [4] */
- 		OK, visible, sound1
- 	}
- 	/****** Extra bytes follow... ******/
- 	/* $"0000"                                               /* .. */
- };
- 
- resource 'ALRT' (136, nonpurgeable) {
- 	{383, 390, 531, 774},
- 	136,
- 	{	/* array: 4 elements */
- 		/* [1] */
- 		OK, visible, sound1,
- 		/* [2] */
- 		OK, visible, sound1,
- 		/* [3] */
- 		OK, visible, sound1,
- 		/* [4] */
- 		OK, visible, sound1
- 	}
- 	/****** Extra bytes follow... ******/
- 	/* $"0000"                                               /* .. */
- };
- 
- resource 'actb' (136) {
- 	{	/* array ColorSpec: 5 elements */
- 		/* [1] */
- 		wContentColor, 65535, 65535, 65535,
- 		/* [2] */
- 		wFrameColor, 0, 0, 0,
- 		/* [3] */
- 		wTextColor, 0, 0, 0,
- 		/* [4] */
- 		wHiliteColor, 0, 0, 0,
- 		/* [5] */
- 		wTitleBarColor, 65535, 65535, 65535
- 	}
- };
- 
--- 0 ----
Index: krb5/mac/SAP/macSAPglue.c
diff -c krb5/mac/SAP/macSAPglue.c:1.1.1.1 krb5/mac/SAP/macSAPglue.c:removed
*** krb5/mac/SAP/macSAPglue.c:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/SAP/macSAPglue.c	Sun Mar 16 20:22:35 2003
***************
*** 1,50 ****
- #include <CodeFragments.h>
- #define TBALERTID	135
- #define TB30ALERTID	136
- 
- OSErr __initializeSAPglue(InitBlockPtr ibp);
- 
- OSErr __initializeSAPglue(InitBlockPtr ibp)
- {
- 	OSErr	err = noErr;
- 	short	fileRefNum;
- 	DateTimeRec		goalTimeBomb;
- 	long			currentTime, goalTimeBombInSecs;
- 	
- 	__initialize();
- 	
- 	if (ibp->fragLocator.where == kDataForkCFragLocator) {
- 		fileRefNum = FSpOpenResFile(ibp->fragLocator.u.onDisk.fileSpec, fsRdPerm);
- 	
- 		if ( fileRefNum == -1 )
- 			err = ResError();
- 	}
- 	
- 	goalTimeBomb.year = 1997;
- 	goalTimeBomb.month = 1;
- 	goalTimeBomb.day = 15;
- 	goalTimeBomb.hour = 0; /* Let's use midnight for simplicity */
- 	goalTimeBomb.minute = 0;
- 	goalTimeBomb.second = 0;
- 	
- 	DateToSeconds( &goalTimeBomb, &goalTimeBombInSecs );
- 	
- 	GetDateTime(&currentTime);
- 	
- 	if ( (goalTimeBombInSecs - currentTime) <= 0 ) {
- 		StopAlert(TBALERTID, NULL);
- 		/* if we just reported an error, then the SAP client would continue running. We
- 			don't want that so instead we'll just call ExitToShell and hope it doesn't
- 			leave anything hangin. If we just wanted the error, report non-zero */
- 		//err = -1;
- 		ExitToShell();
-     } else if ( (goalTimeBombInSecs - currentTime) < 1209600 ) { /* num seconds in 14 days */
- 		NoteAlert(TB30ALERTID, NULL);
- 	}
- 
- 	if ( fileRefNum != -1 )
- 		CloseResFile( fileRefNum );
- 	
- 	return err;
- }
- 
--- 0 ----
Index: krb5/mac/gss-sample/ChangeLog
diff -c krb5/mac/gss-sample/ChangeLog:1.1.1.1 krb5/mac/gss-sample/ChangeLog:removed
*** krb5/mac/gss-sample/ChangeLog:1.1.1.1	Mon Jun  2 17:57:50 1997
--- krb5/mac/gss-sample/ChangeLog	Sun Mar 16 20:22:35 2003
***************
*** 1,10 ****
- Fri Nov 22 15:51:55 1996  unknown  <bjaspan@mit.edu>
- 
- 	* gss-client.c (connect_to_server): use sizeof instead of h_length
-  	to determine number of bytes of addr to copy from DNS response
-  	[krb5-misc/211]
- 
- 
- Thu 26 12:00:00 1995  John Rivlin <jrivlin@fusion.com>
- 
- 	* Created GSS Sample program
--- 0 ----
Index: krb5/mac/gss-sample/gss-misc.c
diff -c krb5/mac/gss-sample/gss-misc.c:1.1.1.1 krb5/mac/gss-sample/gss-misc.c:removed
*** krb5/mac/gss-sample/gss-misc.c:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/gss-sample/gss-misc.c	Sun Mar 16 20:22:35 2003
***************
*** 1,360 ****
- /*
- 
-  * Copyright 1994 by OpenVision Technologies, Inc.
- 
-  * 
- 
-  * Permission to use, copy, modify, distribute, and sell this software
- 
-  * and its documentation for any purpose is hereby granted without fee,
- 
-  * provided that the above copyright notice appears in all copies and
- 
-  * that both that copyright notice and this permission notice appear in
- 
-  * supporting documentation, and that the name of OpenVision not be used
- 
-  * in advertising or publicity pertaining to distribution of the software
- 
-  * without specific, written prior permission. OpenVision makes no
- 
-  * representations about the suitability of this software for any
- 
-  * purpose.  It is provided "as is" without express or implied warranty.
- 
-  * 
- 
-  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- 
-  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- 
-  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- 
-  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
- 
-  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
- 
-  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- 
-  * PERFORMANCE OF THIS SOFTWARE.
- 
-  */
- 
- 
- 
- #include "gss.h"
- 
- #include <string.h>
- 
- #include <errno.h>
- 
- #include <stdio.h>
- 
- #include <stdlib.h>
- 
- 
- 
- /*
- 
-  * Function: send_token
- 
-  *
- 
-  * Purpose: Writes a token to a file descriptor.
- 
-  *
- 
-  * Arguments:
- 
-  *
- 
-  *	s		(r) an open file descriptor
- 
-  *	tok		(r) the token to write
- 
-  *
- 
-  * Returns: 0 on success, -1 on failure
- 
-  *
- 
-  * Effects:
- 
-  *
- 
-  * send_token writes the token length (as a network long) and then the
- 
-  * token data to the file descriptor s.	 It returns 0 on success, and
- 
-  * -1 if an error occurs or if it could not write all the data.
- 
-  */
- 
- int send_token(SOCKET s, gss_buffer_t tok) {
- 
-     size_t ret;
- 
- 
- 
-     ret = send(s, (char *) &tok->length, 4, 0);
- 
- 
- 
- 	if (ret < 0) {
- 
- 		fprintf(stderr, "Error sending token length\r");
- 
- 		return -1;
- 
- 	}
- 
- 	else if (ret != 4) {
- 
- 		fprintf(stderr, "sending token length: %d of %d bytes written\r", ret, 4);
- 
- 		return -1;
- 
- 	}
- 
- 
- 
-     ret = send(s, tok->value, tok->length, 0);
- 
- 
- 
- 	if (ret < 0) {
- 
- 		fprintf(stderr, "Error sending data\r");
- 
- 		return -1;
- 
- 	}
- 
- 	else if (ret != tok->length) {
- 
- 		fprintf(stderr, "sending token data: %d of %d bytes written\r", ret, tok->length);
- 
- 		return -1;
- 
- 	}
- 
- 
- 
-     return 0;
- 
- 
- 
- } /* send_token */
- 
- 
- 
- 
- 
- /*
- 
-  * Function: recv_token
- 
-  *
- 
-  * Purpose: Reads a token from a file descriptor.
- 
-  *
- 
-  * Arguments:
- 
-  *
- 
-  *	s		(r) an open file descriptor
- 
-  *	tok		(w) the read token
- 
-  *
- 
-  * Returns: 0 on success, -1 on failure
- 
-  *
- 
-  * Effects:
- 
-  * 
- 
-  * recv_token reads the token length (as a network long), allocates
- 
-  * memory to hold the data, and then reads the token data from the
- 
-  * file descriptor s.  It blocks to read the length and data, if
- 
-  * necessary.  On a successful return, the token should be freed with
- 
-  * gss_release_buffer.	It returns 0 on success, and -1 if an error
- 
-  * occurs or if it could not read all the data.
- 
-  */
- 
- int
- 
- recv_token (SOCKET s, gss_buffer_t tok) {
- 
-     int ret;
- 
-     unsigned long len;
- 
- 
- 
-     ret = recv(s, (char *) &len, 4, 0);
- 
- 
- 
-     if (ret < 0) {
- 
- 		fprintf(stderr, "Error reading token length\r");
- 
- 	    return -1;
- 
-      } 
- 
-      else if (ret != 4) {
- 
- 	     fprintf(stderr, "Error reading token length: %d of %d bytes read\r", ret, 4);
- 
- 	     return -1;
- 
-      }
- 
- 
- 
-     tok->length = (size_t) len;
- 
- 
- 
-     tok->value = (char *) malloc(tok->length);
- 
- 
- 
-     if (tok->value == NULL) {
- 
-         fprintf(stderr, "Out of memory allocating token data\r");
- 
-         return -1;
- 
-      }
- 
- 
- 
-     ret = recv (s, (char *) tok->value, tok->length, 0);
- 
- 
- 
-     if (ret < 0) {
- 
- 	     fprintf(stderr, "Error reading token data\r");
- 
- 	     free(tok->value);
- 
- 	     return -1;
- 
-     }
- 
- 
- 
-     return 0;
- 
- } /* recv_token */
- 
- 
- 
- 
- 
- /*
- 
-  * Function: display_status
- 
-  *
- 
-  * Purpose: displays GSS-API messages
- 
-  *
- 
-  * Arguments:
- 
-  *
- 
-  *	msg		a string to be displayed with the message
- 
-  *	maj_stat	the GSS-API major status code
- 
-  *	min_stat	the GSS-API minor status code
- 
-  *
- 
-  * Effects:
- 
-  *
- 
-  * The GSS-API messages associated with maj_stat and min_stat are
- 
-  * displayed on stderr, each preceeded by "GSS-API error <msg>: " and
- 
-  * followed by a newline.
- 
-  */
- 
- void
- 
- display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) {
- 
-     display_status_1(msg, maj_stat, GSS_C_GSS_CODE);
- 
-     display_status_1(msg, min_stat, GSS_C_MECH_CODE);
- 
- }
- 
- 
- 
- static void
- 
- display_status_1(char *m, OM_uint32 code, int type) {
- 
-     OM_uint32 maj_stat, min_stat;
- 
-     gss_buffer_desc msg;
- 
-     #ifdef GSSAPI_V2
- 
-         OM_uint32 msg_ctx;
- 
-     #else	/* GSSAPI_V2 */
- 
-         int msg_ctx;
- 
-     #endif	/* GSSAPI_V2 */
- 
-      
- 
-     msg_ctx = 0;
- 
-     while (1) {
- 
-         maj_stat = gss_display_status(
- 
-         	&min_stat, code, type, GSS_C_NULL_OID, &msg_ctx, &msg);
- 
- 
- 
-         fprintf (stderr, "GSS-API error %s: %s\r", m, (char *)msg.value);
- 
-         
- 
-         (void) gss_release_buffer(&min_stat, &msg);
- 
- 	  
- 
-         if (!msg_ctx)
- 
-             break;
- 
-     }
- 
- } /* display_status */
- 
--- 0 ----
Index: krb5/mac/gss-sample/gss-sample.sit.hqx
diff -c krb5/mac/gss-sample/gss-sample.sit.hqx:1.1.1.1 krb5/mac/gss-sample/gss-sample.sit.hqx:removed
*** krb5/mac/gss-sample/gss-sample.sit.hqx:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/gss-sample/gss-sample.sit.hqx	Sun Mar 16 20:22:35 2003
***************
*** 1,48 ****
- (This file must be converted with BinHex 4.0)
- :$QGcFbecB@e`E'8ZFfPd!&0*9%46593K!!!!!!G*!!!"4V`K8dP8)3!#!!!(5A*
- -BA8#!3!!!"B!!!d0$%G68b"6B@e`E'8ZYA0bB`!!!!!!!!!!!!!!!!!!!!$I'J!
- !!!!!!!!!!!!!!!!!!!!!!!!!"T!!!!!!!2rrrrp069"568e$3`%!V$aa3kb3!*a
- +!!!*m3!!#U)!!!)e!!!$eD"kNV-!!!!!!!!50#0%$L)Uq`C4+5ScT300hITKF$j
- mZT@4#)Y)kBc#IAqDGT+61M[$hCfGJB#$FQr3Y(I`EJH2,0X8)#UrMFMpYaB"!e"
- Z*bT'CFE6IDpqD1,9S*JFF&HPm`50Sa-cDlN1cNZ4D2Gdp%H+TZGb"82F$!Y6@pJ
- !#pY[B3-&aPaKUe"XUffBBQd&ICkFP[Cc9(5!0Qb3!&ACP#9&hXcrr4$mrYfi`6!
- PhIar5%[k09a2bkTNrPIlq(BLd6qpC,c8F0JDGl'5*U,eqrpI`IhcBi4c#C[Sf1e
- `1Xmpb[HPSVp6C3@,HFED&4k'h[qrIH84i'9LUM8PRCSUaE3r"X&6,C8l[ZJF(ZN
- l(ed1V!@&LahS1"&X13FHKB,b2EclEl6D'#UfjIpqZD!#9G(QIBV2Reaj@()T1G'
- 4bb&XbGkA3483ip+P5f8eTQ6MI'QIhVY`U@H-S&Zk9*&lG8QAZE(d1"!"68`DKT5
- 4PbDjbR8jYR6#-4Ve)(-S1#-Qa9,m'+IDjQ!1UT(d@"`ra"14a6dRq$R2r&XY@p!
- 6c!4SaDUb[bI&qY51R[Vrbj,Va2cp(iArm'-(0p*hR4-FV`YSbeDL5&SJp)c&(UV
- MP`EcRE[D*S9!-6R'jImS'%Eq+"c*re%iqArlSk!Gqk0!6`h1GNrr,R$2@KJV-1N
- D9ePB['f3!'*Q#q-YE+U&+5eXYS@T,B`Q60`@GXR#pJK-CCmX#J[c'jd4jJl,AT1
- 9`8X#-i4eE512Q3aj@f90I4m!!!X!YrCqjZ8PNc$#MM$*d`JMJl8MaeC#Mc#6X*-
- ``XiMc#6d#205GREN+'&(MTeiLNqbRS3kL1![*U&('$Pf*Q'%(@(Nf*PN`2c)-I+
- 8X*-`mN`*)j3FNi`BHAD5Ta&+'+'4b8U15Bk4Cq3CB8FQ02,X##22##2(b+h!I8N
- "++'%HB3HRP#C(D%5GZ3B1AEN'%%*!b"i))$$kM+m')f'%%)B[N8)f5VKH`cZI2$
- 0KZm`bN*PS$fj)EPG%44C8XZ(iIll)E`LXaSpUiM552A0$Ck*q61$[i#UrZ3aTJF
- 0QPkMQT%5K$pIQRpB-@lDIh%,[FSqk%,SbML`I[1b2Ma$k2+3!2E3NeFP+MfGX@K
- 9f&pKK1#i"b*)r5h`r**Um(Cp3@MVm5@HU)J'$rG$L)8TRNAM*CqrQcCi19CJ@P-
- m@e@(dVkl5P!Mj3B2Yli%9C,Lf4P2&!8a+"P$4dLk[`,1Jil!eI4GET-J0VGiBCD
- 0M-DQBU@BG)eQL9%he4aTD5Mf9-JPa3HpPAX1HaXAq@06MIQFQU94Qi4B%%J!T1a
- PDYFK6XeQ9%G,3r1*eK@A'[ATp4fFQX2bYN-el44$XK5*H9I'06i`r*&6cBcUj&4
- &AClcq%"AQ&-YM'SMe,#XLUY1UGF16V@bA#eUc#p([F'ebSc[2E#0YM`lZC!!%B'
- $9k&66Q2MjbEIF+U0HE@U-8@1"0,8XFQhTcJeMq@D!ekrj80b(GV-Fl9$Uj!!S-+
- #U%E&MM9br)DePP-GfM4)LK*CRiEl-mj(2+&mQ(-bYQ`(@8qSq`AhkY5R`3rJY&R
- `qTKlG@N*pA3*SI9j'([B0mfT"ArRP5INCP3ASji*5"&*NF8PHRbJVj96S5UKjhZ
- 4(rc2[k)hQAjIT-'T3r8`9fimHkZDI,9AEAMf0VR[eHjpH1Td+hU#%md61(&N&#I
- 3HF0rCP23$pY5I[MAlJT6rZ(p#1dGK)VAr'HfKrN4qZIIcrf68jh1If2Rd3rYcMr
- qZeIp"m"cDSidrjQ04MqdGq$dSVjIrUparmA8IcmD!'hlkMqcKqQ(pMNT,0+)&j,
- )5[BId%l5aU"YC%F"l5)p#cU2E"qJ#`M[C"PbNdi%E5Il"HK"q"1LEc,cH@4f0Ie
- B01dJQiG*BEQ!TVQ!TVQ!TVQ!TVQ!TVQ!TVPmHXpb!8ec!8hQK24%DYkeA$+EM(l
- bpCX*q0)r"6Ka9H[Pl@dim3$Qd6h+lMhlm164qS@HaQCX,Ad&6$V[V+c`h"h`BDU
- $%TVaeB9S#(MZ,[ae-E[*EZ&V9'1mU'Z*m,9)J@45I`4rSN`HmSCBqJm!!!d!$fG
- cFbeME'PPER3ZFR0bB`!!!!!!!!!!!!!!!!!!!!!JS!!!!!!!!!!!!!!!!!!!!!!
- !&J!!!!!!!!!!rrrrre*68N0%Eh9R)3#VATi%V*!!GQd!!!%H!!!!!!!!!%N!!!!
- !C,B!!!!!!!!!!$"L%3!)XY&i[PR#$ejfDQCQMC6d#'A5*c*&LXIaK)*G@bIbV05
- bS0jk6lhUJ`DrhI[`f'b&I0rfp!K[I2mRqID&%Kf&3QQP,!!!!'Z2!!!"!!!!!43
- !!!!8!!!!-J!)!!%!"!!!!!N!!!!)!!%!!!!!!!`!!!!)!!%!!`!!$@aTBR*KFQP
- PFbjcDA3#!!!!8dP84&0*9#%"!2rrrrm!!&0*9%46593K!3$rrrrr!!!!!!!!!!!
- !!!!!!!!!!!!!V)p&eJ!!FJS!!!&'!!!!!!!!!!!!!"9$E'PMDb"25b"dEb"MEfj
- dD@jeC5i!!!!!!!!!T!!#!!!!!!!!!!!!!!!#!!3"!!"+!!%!!!!!!!!!!!!!!!!
- e9'mJBfpZG'PZG@8JG'KP)'0eFR*PER3JEh"PFQ&dD@pZ,#"ME'PMDb"dD'Pc)'*
- eG(4[ELi!!!!!!"!"F!$Y!Pd#hJ!!!!!!!!-!!!!"!!!!!43!!!!8!!!!-J)qMAJ
- F5!!!!"`!-J!!8f9dC`!!!!S!!2rr!!!!!!)qch3`@!:
--- 0 ----
Index: krb5/mac/gss-sample/gss.h
diff -c krb5/mac/gss-sample/gss.h:1.1.1.1 krb5/mac/gss-sample/gss.h:removed
*** krb5/mac/gss-sample/gss.h:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/gss-sample/gss.h	Sun Mar 16 20:22:35 2003
***************
*** 1,88 ****
- /*+*************************************************************************
- 
- ** 
- 
- ** gss.h
- 
- ** 
- 
- ***************************************************************************/
- 
- /*
- 
-  * Use the internal mac kerberos sockets library
- 
-  * (it is 'just enough' sockets for kerberos, and perhaps other uses)
- 
-  */
- 
- #define socket			krb5_socket
- 
- #define closesocket		krb5_closesocket
- 
- #define connect			krb5_connect
- 
- #define bind			krb5_bind
- 
- #define send			krb5_send
- 
- #define recv			krb5_recv
- 
- #define sendto			krb5_sendto
- 
- #define select			krb5_select
- 
- #define recvfrom		krb5_recvfrom
- 
- #define inet_ntoa		krb5_inet_ntoa
- 
- #define gethostbyname	krb5_gethostbyname
- 
- #define gethostbyaddr	krb5_gethostbyaddr
- 
- #define gethostname		krb5_gethostname
- 
- #define getsockname		krb5_getsockname
- 
- #define getmyipaddr		krb5_getmyipaddr
- 
- #include "macsock.h"
- 
- 
- 
- #include <string.h>
- 
- 
- 
- #include "gssapi.h"
- 
- #include "gssapi_generic.h"
- 
- 
- 
- typedef unsigned short u_short;
- 
- 
- 
- // gss-misc.c
- 
- int send_token(SOCKET s, gss_buffer_t tok);
- 
- int recv_token(SOCKET s, gss_buffer_t tok);
- 
- void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat);
- 
- static void display_status_1(char *m, OM_uint32 code, int type);
- 
- 
- 
- // gss-client.c
- 
- int gss (char *host, char *name, char *msg, int port);
- 
- int call_server(char *host, u_short port, int dov2, char *service_name, char *msg);
- 
- SOCKET connect_to_server(char *host, u_short port);
- 
- int client_establish_context(SOCKET s, char *service_name, gss_ctx_id_t *gss_context);
- 
--- 0 ----
Index: krb5/mac/kconfig/ChangeLog
diff -c krb5/mac/kconfig/ChangeLog:1.1.1.1 krb5/mac/kconfig/ChangeLog:removed
*** krb5/mac/kconfig/ChangeLog:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/ChangeLog	Sun Mar 16 20:22:35 2003
***************
*** 1,39 ****
- Thu Mar 28 17:59:43 1996  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* kadm.c: Use new MacTCP Header files.
- 
- Wed Mar 27 18:51:43 1996  Theodore Y. Ts'o  <tytso@dcl>
- 
- 	* kconfig.c, getpasswd.c: Use universal procedure pointers (UPP)
- 		which are necessary for the Mac Power PC.
- 
- Tue Nov 7 12:00:00 1995  John Rivlin <jrivlin@fusion.com>
- 
- 	* kconfig.c, kconfig.h: Cleaned out dead code and improved 
- 		credential display to show full Kerberos principal.
- 				
- 	* getpasswd.c: Improved password dialog to allow CR to
- 		act as at TAB when the dialog has not been completed.
- 
- Wed Sep 27 12:00:00 1995  John Rivlin <jrivlin@fusion.com>
- 
- 	* autoconf.h: Removed this file.  Now taken from libraries
- 		directory.
- 		
- 	* KerberosHeaders.pch: Removed this file.  Now taken from
- 		libraries directory.
- 
- Wed Sep 20 12:00:00 1995  James Mattly <mattly@fusion.com>
- 
- 	* kconfig.sit.hqx: update project files to include kadm source for 
- 		change password.
- 
- 	* KerberosHeaders.pch: updated to handle compilation of kadm for 
- 		change password.
- 
- Sun Sep 10 12:00:00 1995  James Mattly <mattly@fusion.com>
- 
- 	* ChangeLog created
- 	
- 	* kconfig.sit.hqx: Project file changed to include new files 
- 		and renamed files.
--- 0 ----
Index: krb5/mac/kconfig/MakeFile
diff -c krb5/mac/kconfig/MakeFile:1.1.1.1 krb5/mac/kconfig/MakeFile:removed
*** krb5/mac/kconfig/MakeFile:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/MakeFile	Sun Mar 16 20:22:35 2003
***************
*** 1,250 ****
- #
- # Copyright 1991-1994 by The University of Texas at Austin
- # All rights reserved.
- #
- # For infomation contact:
- # Rick Watson
- # University of Texas
- # Computation Center, COM 1
- # Austin, TX 78712
- # r.watson@utexas.edu
- # 512-471-3241
- #
- #
- # MPW-style lines for the MakeFile.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- #
- # This first part is long enough that NFS/Share doesn't notice the non-ASCII
- # characters in the rest of the file, so it claims that the file is type
- # TEXT, which is what we want.  The non-ASCII chars are necessary for MPW 
- # Make.
- 
- all  'CNS Config'
- 
- #define dangerouspattersn
- INCFOLDER= :::include:
- 
- OBJS = 
- 	kconfig.c.o 
- 	WindowUtil.c.o 
- 	kadm.c.o 
- 	mac_stubs.c.o 
- 	des_cornell.c.o 
- 	dnr.c.o
- 
- COptions = -sym full -w -mbg ch8 -b -r -i "{INCFOLDER}"
- 
- #
- # our ldef
- #
- ldef.rsrc  ldef.c.o
- 	Link -w -rt LDEF=128 ldef.c.o -o ldef.rsrc
- 	
- #
- # kconfig
- #
- 'CNS Config'  kconfig.r kconfig.rsrc kconfig.vers ldef.rsrc {OBJS}
- 	Delete -i 'CNS Config'
- 	Link -sym Full -map -mf -ra =resProtected -msg nodup -o 'CNS Config' 
- 		-t APPL -c 'RWkc' -l 
- 		{OBJS} 
- 		"{Libraries}"Interface.o 
- 		"{CLibraries}"StdCLib.o 
- 		"{Libraries}"Runtime.o 
- 		> 'CNS Config.map'
- 	Rez -append -o 'CNS Config' kconfig.r
- 	setfile -a B 'CNS Config'
- 	
- SRCS= 
- 	glue.h 
- 	ldef.c 
- 	Makefile 
- 	kconfig.c 
- 	kconfig.h 
- 	kconfig.r 
- 	kconfig.rsrc 
- 	kconfig.vers 
- 	WindowUtil.c 
- 	WindowUtil.h 
- 	ReleaseNotes 
- 	kadm.c 
- 	kadm.h 
- 	dnr.c 
- 	encrypt.h
- 
- mac_stubs.c  :::lib:krb:mac_stubs.c
- 	duplicate -y :::lib:krb:mac_stubs.c mac_stubs.c
- 
- # version 8.0 is K8 10/08/93
- # version 9.0 is K9 10/14/93
- # version 10.0 is version released to Cygnus, 9/8/94
- 	
- newversion 
- 	set newversion 10.0
- 	project kconfigProject
- 	for i in {SRCS}
- 	  checkin -m -y -t "b{newversion}" "{i},{newversion}"
- 	end
- 
- orphans 
- 	for i in {SRCS}
- 		Echo "Delete 'ckid';" | Rez -a -m -o "{i}"
- 	end
- 
- #
- # Xport disk
- #
- xportdisk 
- 	for i in {SRCS}
- 		duplicate -y {i} xport:kconfig:{i}
- 	end
- 
- clean 
- 	delete -y Ŷ~
- 	delete -y Ŷ#
- 
- #
- # Prototypes.
- #
- # Prototypes are not automatically built -- use target "proto" or "depend".
- #
- # Builds {file}.proto.h.new and then duplicates that file as
- # {file}.proto.h only if the files are different. This prevents
- # recompiles due to proto.h files that didn't actually change.
- # 
- # Building {file}.proto.h.new instead of {file}.proto.h also prevents 
- # spurious invocations of mkptypes whenever a file that {file}.proto.h 
- # depends on changes.
- #
- 
- PTYPES = 
- 	:proto:kconfig.proto.h.new 
- 	:proto:WindowUtil.proto.h.new 
- 	:proto:kadm.proto.h.new 
- 
- # default rule for relating prototype.h.new files to source files
- ":proto:"  ":"
- 
- proto  {PTYPES}
- 
- .proto.h.new  .c
- 	mkptypes -A -e -W "{Default}.c" > "{TargDir}{Default}.proto.h.new"
- 	equal -d -q "{Default}.proto.h" "{TargDir}{Default}.proto.h.new" || 
- 		duplicate -y "{TargDir}{Default}.proto.h.new" "{Default}.proto.h"
- 
- #
- # Dependancies
- #
- CPP = 
- 	:cpp:kconfig.cpp 
- 	:cpp:WindowUtil.cpp 
- 	:cpp:kadm.cpp 
- 	:cpp:des_cornell.cpp
- 
- # default rule for relating object files to source files
- ":cpp:"  
- 	":"
- 
- # Rule to build .cpp preprocessor output files. Syntax check only and write cpp output.
- .cpp  .c
- 	C "{DepDir}{Default}.c" -e2 -c {COptions} > "{TargDir}{Default}.cpp"
- 	
- depend  {CPP} proto
- 	perl "{mpw}local:depend.perl" Makefile ":cpp:" ":obj:" {CPP}
- 	Rename -y Makefile Makefile.bak
- 	Rename -y Makefile.new Makefile
- 	Echo "Include "Makefile.bak" 'ckid';" | Rez -m -a -o "Makefile" #Transfer the ckid
- 
- 
- # DO NOT DELETE THIS LINE -- mkdep uses it.
- # DO NOT PUT ANYTHING AFTER THIS LINE. IT WILL GO AWAY.
- 
- kconfig.c.o  "kconfig.proto.h"
- kconfig.c.o  "kconfig.c"
- kconfig.c.o  "kconfig.vers"
- kconfig.c.o  "glue.h"
- kconfig.c.o  "kconfig.h"
- 
- WindowUtil.c.o  "glue.h"
- WindowUtil.c.o  "WindowUtil.c"
- WindowUtil.c.o  "WindowUtil.h"
- 
- kadm.c.o  "kconfig.proto.h"
- kadm.c.o  "kadm.c"
- kadm.c.o  "desproto.h"
- kadm.c.o  "kadm.h"
- kadm.c.o  "glue.h"
- kadm.c.o  "kadm.proto.h"
- kadm.c.o  "kconfig.h"
- 
- des_cornell.c.o  "glue.h"
- des_cornell.c.o  "des_cornell.c"
- des_cornell.c.o  "desproto.h"
- des_cornell.c.o  "encrypt.h"
- 
- # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
- 
--- 0 ----
Index: krb5/mac/kconfig/ReleaseNotes
diff -c krb5/mac/kconfig/ReleaseNotes:1.1.1.1 krb5/mac/kconfig/ReleaseNotes:removed
*** krb5/mac/kconfig/ReleaseNotes:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/ReleaseNotes	Sun Mar 16 20:22:35 2003
***************
*** 1,172 ****
- Relase notes for Kerberized NCSA/Telnet, Brown/TN3270, Kdriver, and KConfig.
- 
- Please direct comments and questions to:
- 
-   Rick Watson
-   The University of Texas at Austin
-   Computation Center / Networking Services
-   Austin  TX  78712
-   R.Watson@utexas.edu.
- 
- ---------------------------------------------------------------------------	
- Release K11 11/2/93
- 
-  Telnet: Fix a problem with recovering the screen pointer in netwrite.
-  Telnet/tn3270/krb: Dynamically allocate encryption data when needed.
-  Telnet: Fix memory leaks and pointer bugs.
- 
- ---------------------------------------------------------------------------	
- Release K10 
- 
-  Fixed some MPW-version specific bugs including garbled strings.
- 
- ---------------------------------------------------------------------------	
- Release K9 10/14/93
- 
-  Telnet: fixed crashes when using Finger.
- 
-  KConfig: added password changing code.
-  KConfig: updated icons.
-  KConfig: remember window position.
-  KConfig: make sure that DeviceLoop is available before using it.
- 
-  kDriver: added more functions to cKrbGetDesPointers. fixed a bug in cKrbSetPassword.
- 
- WARNING: Do not mix different versions of the K8 and K9 clients and kDriver. There are incompatible changes. If you mix them, you will probably crash.
- 
- ---------------------------------------------------------------------------	
- Release K8 10/08/93
- 
- The changes to support Kerberos authentication and DES encryption for Telnet and TN3270 were both made to beta versions of those programs. I hope that the authors of each will take back these changes for the release versions of these applications. For NCSA/Telnet, I have rewritten the Kerberos changes that you may have seen in releases K1-K7 of NCSA/Telnet.
- 
- Both applications now use Cornell's Kdriver package for Kerberos and encryption support routines. I have written KConfig, an application to configure settings for Kdriver.
- I have made some additions to Kdriver and fixed some bugs, so you should probably use the version that I have included in this test package.  If you use an unmodified Cornell driver, encryption will not be supported, some settings changes made by KConfig won't be saved in the preferences file, and the ticket display may show garbage for the user realm.
- 
- Kdriver supports Kerberos V4. Kdriver requires that each Kerberos server host also be running a UDP daytime server.
- 
- NCSA/Telnet and TN3270 support the Telnet Authentication and Encryption options described in RFC1411/1416 and IETF drafts dated July 1991. Future versions may support the IETF draft AUTH_ENCRYPT option described in the draft dated April 1993.
- 
- Kerberos support for TN3270 has not been tested for 3270 sessions yet since we don't currently have a Kerberized tn3270 server running. I don't expect any problems related to 3270 sessions.
- 
-  INSTALLATION / KConfig
- 
- Kdriver must be installed in your System Folder to work. Drag the file "Kerberos Client" file to your closed System Folder. On System 7 machines, you will be asked to verify that the file will be placed into your Extensions folder.
- 
- Reboot your Macintosh and use KConfig to configure settings for your Kerberos envrionment.
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- Domain/Hostname to Realm maps are useful if you are supporting more than one Kerberos realm. The map will attempt to match up a Kerberos realm with IP domain names.
- 
- Enter Kerberos server IP addresses or hostnames for each Kerberos realm that you are using. After you have entered your Kerberos servers, you can pick your local realm using the popup menu at the top of the configuration dialog.
- 
- The "Login" button will allow you to authenticate to a Kerberos server and obtain an initial ticket granting ticket for other services. You don't have to login using KConfig -- the individual client applications will prompt you when a password is needed.
- 
- The "Logout" button destroys all tickets.
- 
- Use the "File/Show Credentials" menu item to display all your Kerberos tickets.
- 
- The "Change Password" button allows you to change your Kerberos password.
- 
- You may (or may not) have to reboot after making initial settings. 
- 
-  NCSA/Telnet
- 
- Options to Authenticate and/or Encrypt a session occur in two places in Telnet.
- 
- This is the session configuration dialog.
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- Select the appropriate options for each session that you configure, including the Default session. Options for the default session will be presented in the Open Connection dialog box. 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- You may select the Authenticate and Encrypt options when opening a session. The Authenticate options is required for Encryption. Ftp sessions cannot currently be authenticated or encrypted.
- 
-  TN3270
- 
- The authenticate and encrypt options are for TN3270 are in the "Special" dialog box, entered from the Open Connection dialog.
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- Authenticate is required to Encrypt.
- 
-  Encryption Active Indicators.
- 
- Padlock indicators serve as a visual indicator that a session is encrypted. For Telnet, this is  displayed next to the zoom box in the window's titlebar.
- 
- 
- 
- 
- 
- 
- 
- For TN3270, the indicator is displayed in the bottom status line, adjacent to the date and time. 
- 
- 
- 
- 
- 
- 
- 
- If anything other than the padlock is displayed, the session is not two-way encrypted. An arrow indicates that the session is encryted in one direction only. This is probably evidence of a bug in the Telnet/TN3270 code or your Telnet server. The absence of any indicator means that no encryption is taking place.
- 
--- 0 ----
Index: krb5/mac/kconfig/WindowUtil.c
diff -c krb5/mac/kconfig/WindowUtil.c:1.1.1.1 krb5/mac/kconfig/WindowUtil.c:removed
*** krb5/mac/kconfig/WindowUtil.c:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/WindowUtil.c	Sun Mar 16 20:22:35 2003
***************
*** 1,311 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- #ifndef __MWERKS__
- #include <Memory.h>
- #include <OSUtils.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <SysEqu.h>
- #include <Traps.h>
- #include <Types.h>
- #include <Windows.h>
- #endif
- #include "WindowUtil.h"
- 
- #if 0
- #include "glue.h"
- #endif
- 
- #define topLeft(r)	(((Point *) &(r))[0])
- #define botRight(r)	(((Point *) &(r))[1])
- #undef GrayRgn
- #define getGrayRgn() (* (RgnHandle*) 0x09EE)
- 
- void FindBestScreen(Rect *WindowRect, Rect *ScreenRect);
- void FitRects(Rect *BaseRect, Rect *VictimRect);
- 
- Point PositionTemplate (Rect *BaseRect, ResType Type, register int ID, 
- 					   int PercentH, int	PercentV)
- {
- 	Point TopLeft;
- 	Handle TemplateHand;
- 	
- 	TopLeft.v = LMGetMBarHeight() << 1;
- 	TopLeft.h = TopLeft.v;
- 	
- 	TemplateHand = GetResource(Type, ID);
- 	if (TemplateHand != NULL) {
- 		
- 		LoadResource(TemplateHand);
- 		if (ResError() == noErr) {
- 			int	TemplateState;
- 			
- 			TemplateState = HGetState(TemplateHand);
- 			HLock(TemplateHand);
- 			
- 			TopLeft = PositionRect(BaseRect, (Rect *) *TemplateHand, 
- 								   PercentH, PercentV);
- 
- 			HSetState(TemplateHand, TemplateState);
- 		}	
- 	}
- 	
- 	return (TopLeft);
- }
- 
- 
- Point PositionRect (Rect *BaseRect, Rect *VictimRect, int PercentH, 
- 					int PercentV)
- {
- 	char *dummy;
- 	Point TopLeft;
- 	BitMap *ScreenBits;
- 	Rect ScreenRect;
- 	Rect WindowRect;
- 	
- 	ScreenBits = &qd.screenBits;
- 	
- 	ScreenRect = ScreenBits->bounds;
- 	ScreenRect.top += LMGetMBarHeight();
- 	
- 	if (BaseRect == NULL) {
- 		
- 		WindowRect = ScreenRect;
- 		
- 	} else if (BaseRect == (Rect *) -1) {
- 		WindowPtr				Front;
- 		
- 		Front = FrontWindow();
- 		if (Front != NULL) {
- 			GrafPtr					OrigPort;
- 			
- 			GetPort(&OrigPort);
- 			SetPort(Front);
- 			
- 			WindowRect = Front->portRect;
- 			
- 			LocalToGlobal(&topLeft(WindowRect));
- 			LocalToGlobal(&botRight(WindowRect));
- 			
- 			SetPort(OrigPort);
- 			
- 		} else
- 			WindowRect = ScreenRect;
- 		
- 	} else if (BaseRect == (Rect *) -2) {
- 		GrafPtr					OrigPort;
- 		
- 		GetPort(&OrigPort);
- 		if (OrigPort != NULL) {
- 			
- 			WindowRect = OrigPort->portRect;
- 			
- 			LocalToGlobal(&topLeft(WindowRect));
- 			LocalToGlobal(&botRight(WindowRect));
- 			
- 		} else
- 			WindowRect = ScreenRect;
- 		
- 	} else {
- 		
- 		WindowRect = *BaseRect;
- 		
- 		LocalToGlobal(&topLeft(WindowRect));
- 		LocalToGlobal(&botRight(WindowRect));
- 	}
- 	
- 	/*	Make the first attempt to position the window. */
- 	
- 	AlignRect(&WindowRect, VictimRect, PercentH, PercentV);
- 	
- 	/*	Make certain that the window wont be positioned off-screen.
- 		If it would have been, find the closest on-screen position for it. */
- 	
- 	PositionRectOnScreen(VictimRect, true);
- 	
- 	/*	Finish-up the positioning process. */
- 	
- 	TopLeft = topLeft(*VictimRect);
- 	
- 	return (TopLeft);
- }
- 
- 
- void AlignRect (register Rect *BaseRect, register Rect *VictimRect, 
- 				int	PercentH, int PercentV)
- {
- 	Rect FixedRect;
- 	int	BaseLenH;
- 	int	BaseLenV;
- 	int	VictLenH;
- 	int	VictLenV;
- 	int DivH;
- 	int DivV;
- 	
- 	DivH = 100 / PercentH;
- 	DivV = 100 / PercentV;
- 	
- 	BaseLenH = (BaseRect->right - BaseRect->left) / DivH;
- 	BaseLenV = (BaseRect->bottom - BaseRect->top) / DivV;
- 	
- 	VictLenH = VictimRect->right - VictimRect->left;
- 	VictLenV = VictimRect->bottom - VictimRect->top;
- 	
- 	FixedRect.left = (BaseRect->left + BaseLenH) - (VictLenH >> 1);
- 	FixedRect.right = FixedRect.left + VictLenH;
- 	FixedRect.top = (BaseRect->top + BaseLenV) - (VictLenV >> 1);
- 	FixedRect.bottom = FixedRect.top + VictLenV;
- 	
- 	*VictimRect = FixedRect;
- }
- 
- 
- Point PositionRectOnScreen (Rect *VictimRect, int TotallyOnScreen)
- {
- 	RgnHandle WindowRgn;
- 	RgnHandle ResultRgn;
- 	RgnHandle GrayRgn = getGrayRgn();
- 	
- 	WindowRgn = NewRgn();
- 	ResultRgn = NewRgn();
- 	if (WindowRgn != NULL && ResultRgn != NULL) {
- 		int						Reposition;
- 		
- 		Reposition = false;
- 		
- 		RectRgn(WindowRgn, VictimRect);
- 		
- 		if (TotallyOnScreen) {
- 			
- 		/*	GrayRgn tends to be set to 0xFFFFFFFF (-1) during startup. */
- 			
- 			if ((long) GrayRgn != -1) {
- 				
- 				UnionRgn(GrayRgn, WindowRgn, ResultRgn);
- 				Reposition = EqualRgn(GrayRgn, ResultRgn) == 0;
- 			}
- 			
- 		} else {
- 			
- 			if ((long) GrayRgn != -1) {
- 				
- 				SectRgn(GrayRgn, WindowRgn, ResultRgn);
- 				Reposition = EmptyRgn(ResultRgn);
- 			}
- 		}
- 		
- 		if (Reposition) {
- 			Rect					ScreenRect;
- 			
- 			FindBestScreen(VictimRect, &ScreenRect);
- 			FitRects(&ScreenRect, VictimRect);
- 		}
- 	}
- 	
- 	if (WindowRgn != NULL)
- 		DisposeRgn(WindowRgn);
- 	if (ResultRgn != NULL)
- 		DisposeRgn(ResultRgn);
- 	
- 	return (topLeft(VictimRect));
- }
- 
- 
- void FitRects (register Rect *BaseRect, register Rect *VictimRect)
- {
- 	int						VOff;
- 	int						HOff;
- 	
- 	if (VictimRect->top < BaseRect->top)
- 		VOff = (BaseRect->top - VictimRect->top) + 8;
- 	else if (VictimRect->bottom > BaseRect->bottom)
- 		VOff = (BaseRect->bottom - VictimRect->bottom) - 8;
- 	else
- 		VOff = 0;
- 	
- 	if (VictimRect->left < BaseRect->left)
- 		HOff = (BaseRect->left - VictimRect->left) + 8;
- 	else if (VictimRect->right > BaseRect->right)
- 		HOff = (BaseRect->right - VictimRect->right) - 8;
- 	else
- 		HOff = 0;
- 	
- 	OffsetRect(VictimRect, HOff, VOff);
- }
- 
- 
- void FindBestScreen (WindowRect, ScreenRect)
- Rect					*WindowRect;
- Rect					*ScreenRect;
- {
- 	SysEnvRec				Environment;
- 	
- 	SysEnvirons(1, &Environment);
- 	if (Environment.hasColorQD) {
- 		GDHandle				GDHand;
- 		GDHandle				BestGD;
- 		unsigned long			BestBitCount;
- 		
- 		GDHand = GetDeviceList();
- 		BestGD = NULL;
- 		BestBitCount = 0;
- 		
- 		while (GDHand != NULL) {
- 			Rect					WindSect;
- 			unsigned long			BitCount;
- 			
- 			WindSect = (*GDHand)->gdRect;
- 			if (GDHand == GetMainDevice())
- 				WindSect.top += LMGetMBarHeight();
- 			
- 			SectRect(WindowRect, &WindSect, &WindSect);
- 			if (EmptyRect(&WindSect) == false)
- 				BitCount = (unsigned long) (WindSect.right - WindSect.left) * (unsigned long) (WindSect.bottom - WindSect.top);
- 			else
- 				BitCount = 0;
- 			
- 			if (BitCount > BestBitCount) {
- 				
- 				BestBitCount = BitCount;
- 				BestGD = GDHand;
- 			}
- 			
- 			GDHand = GetNextDevice(GDHand);
- 		}
- 		
- 		if (BestGD == NULL)
- 			BestGD = GetMainDevice();
- 		
- 		*ScreenRect = (*BestGD)->gdRect;
- 	
- 	} else {
- 		BitMap *ScreenBits;
- 		char *dummy;
- 		
- 		ScreenBits = &qd.screenBits;
- 
- 		*ScreenRect = ScreenBits->bounds;
- 		ScreenRect->top += LMGetMBarHeight();
- 	}
- }
- 
- 
- /*
-  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
-  * Should be at end of file.
-  * 
-  * Local Variables:
-  * tab-width: 4
-  * End:
-  */
- 
--- 0 ----
Index: krb5/mac/kconfig/WindowUtil.h
diff -c krb5/mac/kconfig/WindowUtil.h:1.1.1.1 krb5/mac/kconfig/WindowUtil.h:removed
*** krb5/mac/kconfig/WindowUtil.h:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/WindowUtil.h	Sun Mar 16 20:22:35 2003
***************
*** 1,27 ****
-  
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- #ifndef _WindowUtil_
- #define _WindowUtil_
- 
- #ifndef NULL
- #define NULL			0L
- #endif
- 
- Point PositionTemplate(Rect *BaseRect, ResType, int ResID, int, int);
- Point PositionRect(Rect *BaseRect, Rect *VictimRect, int PercentH, int PercentV);
- Point PositionRectOnScreen(Rect *VictimRect, int TotallyOnScreen);
- void AlignRect(Rect *BaseRect, Rect *VictimRect, int PercentH, int PercentV);
- 
- #endif
--- 0 ----
Index: krb5/mac/kconfig/WindowUtil.proto.h
diff -c krb5/mac/kconfig/WindowUtil.proto.h:1.1.1.1 krb5/mac/kconfig/WindowUtil.proto.h:removed
*** krb5/mac/kconfig/WindowUtil.proto.h:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/WindowUtil.proto.h	Sun Mar 16 20:22:35 2003
***************
*** 1,9 ****
- /*
-  * WindowUtil.c
-  */
- extern Point PositionTemplate(Rect *BaseRect, ResType Type, register int ID, int PercentH, int PercentV);
- extern Point PositionRect(Rect *BaseRect, Rect *VictimRect, int PercentH, int PercentV);
- extern void AlignRect(register Rect *BaseRect, register Rect *VictimRect, int PercentH, int PercentV);
- extern Point PositionRectOnScreen(Rect *VictimRect, int TotallyOnScreen);
- extern void FitRects(register Rect *BaseRect, register Rect *VictimRect);
- extern void FindBestScreen(Rect *WindowRect, Rect *ScreenRect);
--- 0 ----
Index: krb5/mac/kconfig/des_cornell.c
diff -c krb5/mac/kconfig/des_cornell.c:1.1.1.1 krb5/mac/kconfig/des_cornell.c:removed
*** krb5/mac/kconfig/des_cornell.c:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/des_cornell.c	Sun Mar 16 20:22:35 2003
***************
*** 1,222 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- 
- /*
-  * Des stub routines to use DES routines from Cornell's Kdriver.
-  */
- 
- #ifdef TN3270
- #pragma segment 3270tcp
- #define bzero xbzero
- #endif
- 
- #ifdef NCSA
- #pragma segment 22
- #define bzero xbzero
- #endif
-  
- #include <Devices.h>
- #include <Files.h>
- #include <Traps.h>
- #include <SysEqu.h>
- 
- #include "krb_driver.h"
- #include "glue.h"
- #include "encrypt.h"
- #include "desproto.h"
- 
- void bzero(void *, long);
- 
- static short kdriver = 0;		/* .Kerberos driver ref */
- long driverA4;					/* a4 in driver environment */
- 
- long (*c_des_new_random_key)(des_cblock key) = 0;
- long (*c_des_ecb_encrypt)(unsigned long *clear, unsigned long *cipher, des_key_schedule schedule, long encrypt) = 0;
- long (*c_des_set_random_generator_seed)(des_cblock *key) = 0;
- long (*c_des_key_sched)(des_cblock k, des_key_schedule schedule) = 0;
- void (*c_des_init_random_number_generator)(des_cblock key) = 0;
- long (*c_des_pcbc_encrypt)(unsigned char *in, unsigned char * out, register long length,
- 						des_key_schedule key, unsigned char *iv, long encrypt) = 0;
- long (*c_des_string_to_key)(char *str, unsigned char *key) = 0;
- unsigned long (*c_des_quad_cksum) (unsigned char *in, unsigned long *out, long length,
- 							   long out_count, unsigned char *c_seed) = 0;
- long (*c_gettimeofdaynet) (struct timeval *tp, struct timezone *tz) = 0;
- 
- /*
-  * init_cornell_des
-  * Returns -2 if no kdriver
-  * Returns other error if this kdriver does not have the DES hooks.
-  */
- long init_cornell_des ()
- {
- 	short s;
- 	ParamBlockRec pb;
- 	long addrs[10];
- 	
- 	/*
- 	 * Open the .Kerberos driver if not already open
- 	 */
- 	if (!kdriver) {
- 		if (s = OpenDriver("\p.Kerberos", &kdriver)) {
- 			return -2;
- 		}
- 	}
- 
- 	bzero(&pb, sizeof(ParamBlockRec));
- 	((long *)pb.cntrlParam.csParam)[0] = (long)&addrs[0];
- 	((long *)pb.cntrlParam.csParam)[1] = sizeof(addrs)/sizeof(long);
- 	pb.cntrlParam.ioCompletion = nil;
- 	pb.cntrlParam.ioCRefNum = kdriver;
- 
- 	pb.cntrlParam.csCode = cKrbGetDesPointers;
- 	if (s = PBControl(&pb, false))
- 		return s;
- 	if (s = pb.cntrlParam.ioResult)
- 		return s;
- 
- 	driverA4 = addrs[0];
- 	c_des_new_random_key = (long(*)()) addrs[1];
- 	c_des_ecb_encrypt = (long(*)()) addrs[2];
- 	c_des_set_random_generator_seed = (long(*)()) addrs[3];
- 	c_des_key_sched = (long(*)()) addrs[4];
- 	c_des_init_random_number_generator = (void(*)()) addrs[5];
- 	c_des_pcbc_encrypt = (long(*)()) addrs[6];
- 	c_des_string_to_key = (long(*)()) addrs[7];
- 	c_des_quad_cksum = (unsigned long(*)()) addrs[8];
- 	c_gettimeofdaynet = (long(*)()) addrs[9];
- 
- 	return 0;
- }
- 
- 
- long des_new_random_key(des_cblock key)
- {
- 	long oldA4;
- 	long s = 0;
- 	
- 	if (c_des_new_random_key) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_new_random_key)(key);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- long des_ecb_encrypt(unsigned long *clear, unsigned long *cipher, des_key_schedule schedule, long encrypt)
- {
- 	long oldA4;
- 	long s = 0;
- 	
- 	if (c_des_ecb_encrypt) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_ecb_encrypt)(clear, cipher, schedule, encrypt);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- long des_set_random_generator_seed(des_cblock *key)
- {
- 	long oldA4;
- 	long s = 0;
- 
- 	if (c_des_set_random_generator_seed) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_set_random_generator_seed)(key);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- long des_key_sched(des_cblock k, des_key_schedule schedule)
- {
- 	long oldA4;
- 	long s = 0;
- 	
- 	if (c_des_key_sched) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_key_sched)(k, schedule);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- void des_init_random_number_generator(des_cblock key)
- {
- 	long oldA4;
- 	
- 	if (c_des_init_random_number_generator) {
- 		oldA4 = swapA4(driverA4);
- 		(*c_des_init_random_number_generator)(key);
- 		swapA4(oldA4);
- 	}
- }
- 
- 
- long des_pcbc_encrypt (unsigned char *in, unsigned char * out, register long length,
- 						des_key_schedule key, unsigned char *iv, long encrypt)
- {
- 	long oldA4, s = 0;
- 	
- 	if (c_des_pcbc_encrypt) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_pcbc_encrypt)(in, out, length, key, iv, encrypt);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- long des_string_to_key (char *str, unsigned char *key)
- {
- 	long oldA4, s = 0;
- 	
- 	if (c_des_string_to_key) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_string_to_key)(str, key);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- unsigned long des_quad_cksum (unsigned char *in, unsigned long *out, long length,
- 							   long out_count, unsigned char *c_seed)
- {
- 	long oldA4;
- 	unsigned long s = 0;
- 	
- 	if (c_des_quad_cksum) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_des_quad_cksum)(in, out, length, out_count, c_seed);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
- 
- 
- long gettimeofdaynet (struct timeval *tp, struct timezone *tz)
- {
- 	long oldA4, s = 0;
- 	
- 	if (c_gettimeofdaynet) {
- 		oldA4 = swapA4(driverA4);
- 		s = (*c_gettimeofdaynet)(tp, tz);
- 		swapA4(oldA4);
- 	}
- 	return s;
- }
--- 0 ----
Index: krb5/mac/kconfig/desproto.h
diff -c krb5/mac/kconfig/desproto.h:1.1.1.1 krb5/mac/kconfig/desproto.h:removed
*** krb5/mac/kconfig/desproto.h:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/desproto.h	Sun Mar 16 20:22:35 2003
***************
*** 1,34 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- struct timeval {
- 	long tv_sec;
- 	long tv_usec;
- };
- 
- struct timezone {
- 	long dummy;
- };
- 
- extern long init_cornell_des(void);
- extern long des_new_random_key(des_cblock key);
- extern long des_ecb_encrypt(unsigned long *clear, unsigned long *cipher, des_key_schedule schedule, long encrypt);
- extern long des_set_random_generator_seed(des_cblock *key);
- extern long des_key_sched(des_cblock k, des_key_schedule schedule);
- extern void des_init_random_number_generator(des_cblock key);
- extern long des_pcbc_encrypt(unsigned char *in, unsigned char * out, register long length,
- 						des_key_schedule key, unsigned char *iv, long encrypt);
- extern long des_string_to_key(char *str, unsigned char *key);
- extern unsigned long des_quad_cksum (unsigned char *in, unsigned long *out, long length,
- 							   long out_count, unsigned char *c_seed);
- long gettimeofdaynet(struct timeval *tp, struct timezone *tz);
--- 0 ----
Index: krb5/mac/kconfig/dnr.c
diff -c krb5/mac/kconfig/dnr.c:1.1.1.1 krb5/mac/kconfig/dnr.c:removed
*** krb5/mac/kconfig/dnr.c:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/dnr.c	Sun Mar 16 20:22:35 2003
***************
*** 1,293 ****
- /* 	DNR.c - DNR library for MPW
- 
- 	(c) Copyright 1988 by Apple Computer.  All rights reserved
- 	
- 	Modifications by Jim Matthews, Dartmouth College, 5/91
- 	
- */
- 
- #include <OSUtils.h>
- #include <Errors.h>
- #include <Files.h>
- #include <Resources.h>
- #include <Memory.h>
- #include <Traps.h>
- #include <GestaltEqu.h>
- #include <Folders.h>
- #include <ToolUtils.h>
- 
- #define OPENRESOLVER	1L
- #define CLOSERESOLVER	2L
- #define STRTOADDR		3L
- #define	ADDRTOSTR		4L
- #define	ENUMCACHE		5L
- #define ADDRTONAME		6L
- #define	HINFO			7L
- #define MXINFO			8L
- 
- Handle codeHndl = nil;
- 
- typedef OSErr (*OSErrProcPtr)(long,...);
- OSErrProcPtr dnr = nil;
- 
- 
- TrapType GetTrapType(theTrap)
- unsigned long theTrap;
- {
- 	if (BitAnd(theTrap, 0x0800) > 0)
- 		return(ToolTrap);
- 	else
- 		return(OSTrap);
- 	}
- 	
- Boolean TrapAvailable(trap)
- unsigned long trap;
- {
- TrapType trapType = ToolTrap;
- unsigned long numToolBoxTraps;
- 
- 	if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
- 		numToolBoxTraps = 0x200;
- 	else
- 		numToolBoxTraps = 0x400;
- 
- 	trapType = GetTrapType(trap);
- 	if (trapType == ToolTrap) {
- 		trap = BitAnd(trap, 0x07FF);
- 		if (trap >= numToolBoxTraps)
- 			trap = _Unimplemented;
- 		}
- 	return(NGetTrapAddress(trap, trapType) != NGetTrapAddress(_Unimplemented, ToolTrap));
- 
- }
- 
- void GetSystemFolder(short *vRefNumP, long *dirIDP)
- {
- 	SysEnvRec info;
- 	long wdProcID;
- 	
- 	SysEnvirons(1, &info);
- 	if (GetWDInfo(info.sysVRefNum, vRefNumP, dirIDP, &wdProcID) != noErr) {
- 		*vRefNumP = 0;
- 		*dirIDP = 0;
- 		}
- 	}
- 
- void GetCPanelFolder(short *vRefNumP, long *dirIDP)
- {
- 	Boolean hasFolderMgr = false;
- 	long feature;
- 	
- //	if (TrapAvailable(_Gestalt)) if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
-     if (Gestalt(gestaltFindFolderAttr, &feature) == noErr) hasFolderMgr = true;
- 	if (!hasFolderMgr) {
- 		GetSystemFolder(vRefNumP, dirIDP);
- 		return;
- 		}
- 	else {
- 		if (FindFolder(kOnSystemDisk, kControlPanelFolderType, kDontCreateFolder, vRefNumP, dirIDP) != noErr) {
- 			*vRefNumP = 0;
- 			*dirIDP = 0;
- 			}
- 		}
- 	}
- 	
- /* SearchFolderForDNRP is called to search a folder for files that might 
- 	contain the 'dnrp' resource */
- short SearchFolderForDNRP(long targetType, long targetCreator, short vRefNum, long dirID)
- {
- 	HParamBlockRec fi;
- 	Str255 filename;
- 	short refnum;
- 	
- 	fi.fileParam.ioCompletion = nil;
- 	fi.fileParam.ioNamePtr = filename;
- 	fi.fileParam.ioVRefNum = vRefNum;
- 	fi.fileParam.ioDirID = dirID;
- 	fi.fileParam.ioFDirIndex = 1;
- 	
- 	while (PBHGetFInfo(&fi, false) == noErr) {
- 		/* scan system folder for driver resource files of specific type & creator */
- 		if (fi.fileParam.ioFlFndrInfo.fdType == targetType &&
- 			fi.fileParam.ioFlFndrInfo.fdCreator == targetCreator) {
- 			/* found the MacTCP driver file? */
- 			refnum = HOpenResFile(vRefNum, dirID, filename, fsRdPerm);
- 			if (GetIndResource('dnrp', 1) == NULL)
- 				CloseResFile(refnum);
- 			else
- 				return refnum;
- 			}
- 		/* check next file in system folder */
- 		fi.fileParam.ioFDirIndex++;
- 		fi.fileParam.ioDirID = dirID;	/* PBHGetFInfo() clobbers ioDirID */
- 		}
- 	return(-1);
- 	}	
- 
- /* OpenOurRF is called to open the MacTCP driver resources */
- 
- short OpenOurRF()
- {
- 	short refnum;
- 	short vRefNum;
- 	long dirID;
- 	
- 	/* first search Control Panels for MacTCP 1.1 */
- 	GetCPanelFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'ztcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	/* next search System Folder for MacTCP 1.0.x */
- 	GetSystemFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	/* finally, search Control Panels for MacTCP 1.0.x */
- 	GetCPanelFolder(&vRefNum, &dirID);
- 	refnum = SearchFolderForDNRP('cdev', 'mtcp', vRefNum, dirID);
- 	if (refnum != -1) return(refnum);
- 		
- 	return -1;
- 	}	
- 
- 
- OSErr OpenResolver(fileName)
- char *fileName;
- {
- 	short refnum;
- 	OSErr rc;
- 	
- 	if (dnr != nil)
- 		/* resolver already loaded in */
- 		return(noErr);
- 		
- 	/* open the MacTCP driver to get DNR resources. Search for it based on
- 	   creator & type rather than simply file name */	
- 	refnum = OpenOurRF();
- 
- 	/* ignore failures since the resource may have been installed in the 
- 	   System file if running on a Mac 512Ke */
- 	   
- 	/* load in the DNR resource package */
- 	codeHndl = GetIndResource('dnrp', 1);
- 	if (codeHndl == nil) {
- 		/* can't open DNR */
- 		return(ResError());
- 		}
- 	
- 	DetachResource(codeHndl);
- 	if (refnum != -1) {
- 		CloseWD(refnum);
- 		CloseResFile(refnum);
- 		}
- 		
- 	/* lock the DNR resource since it cannot be reloated while opened */
- 	HLock(codeHndl);
- 	dnr = (OSErrProcPtr) *codeHndl;
- 	
- 	/* call open resolver */
- 	rc = (*dnr)(OPENRESOLVER, fileName);
- 	if (rc != noErr) {
- 		/* problem with open resolver, flush it */
- 		HUnlock(codeHndl);
- 		DisposHandle(codeHndl);
- 		dnr = nil;
- 		}
- 	return(rc);
- 	}
- 
- 
- OSErr CloseResolver()
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	/* call close resolver */
- 	(void) (*dnr)(CLOSERESOLVER);
- 
- 	/* release the DNR resource package */
- 	HUnlock(codeHndl);
- 	DisposHandle(codeHndl);
- 	dnr = nil;
- 	return(noErr);
- 	}
- 
- OSErr StrToAddr(hostName, rtnStruct, resultproc, userDataPtr)
- char *hostName;
- struct hostInfo *rtnStruct;
- long resultproc;
- char *userDataPtr;
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	return((*dnr)(STRTOADDR, hostName, rtnStruct, resultproc, userDataPtr));
- 	}
- 	
- OSErr AddrToStr(addr, addrStr)
- unsigned long addr;
- char *addrStr;									
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	(*dnr)(ADDRTOSTR, addr, addrStr);
- 	return(noErr);
- 	}
- 	
- OSErr EnumCache(resultproc, userDataPtr)
- long resultproc;
- char *userDataPtr;
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	return((*dnr)(ENUMCACHE, resultproc, userDataPtr));
- 	}
- 	
- 	
- OSErr AddrToName(addr, rtnStruct, resultproc, userDataPtr)
- unsigned long addr;
- struct hostInfo *rtnStruct;
- long resultproc;
- char *userDataPtr;									
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	return((*dnr)(ADDRTONAME, addr, rtnStruct, resultproc, userDataPtr));
- 	}
- 
- 
- extern OSErr HInfo(hostName, returnRecPtr, resultProc, userDataPtr)
- char *hostName;
- struct returnRec *returnRecPtr;
- long resultProc;
- char *userDataPtr;
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	return((*dnr)(HINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- 	}
- 	
- extern OSErr MXInfo(hostName, returnRecPtr, resultProc, userDataPtr)
- char *hostName;
- struct returnRec *returnRecPtr;
- long resultProc;
- char *userDataPtr;
- {
- 	if (dnr == nil)
- 		/* resolver not loaded error */
- 		return(notOpenErr);
- 		
- 	return((*dnr)(MXINFO, hostName, returnRecPtr, resultProc, userDataPtr));
- 
- 	}
\ No newline at end of file
--- 0 ----
Index: krb5/mac/kconfig/encrypt.h
diff -c krb5/mac/kconfig/encrypt.h:1.1.1.1 krb5/mac/kconfig/encrypt.h:removed
*** krb5/mac/kconfig/encrypt.h:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/encrypt.h	Sun Mar 16 20:22:35 2003
***************
*** 1,92 ****
- #pragma once
- 
- /*-
-  * Copyright (c) 1991 The Regents of the University of California.
-  * All rights reserved.
-  *
-  * Redistribution and use in source and binary forms are permitted provided
-  * that: (1) source distributions retain this entire copyright notice and
-  * comment, and (2) distributions including binaries display the following
-  * acknowledgement:  ``This product includes software developed by the
-  * University of California, Berkeley and its contributors'' in the
-  * documentation or other materials provided with the distribution and in
-  * all advertising materials mentioning features or use of this software.
-  * Neither the name of the University nor the names of its contributors may
-  * be used to endorse or promote products derived from this software without
-  * specific prior written permission.
-  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-  *
-  *	@(#)encrypt.h	5.1 (Berkeley) 2/28/91
-  */
- 
- /*
-  * Copyright (C) 1990 by the Massachusetts Institute of Technology
-  *
-  * Export of this software from the United States of America is assumed
-  * to require a specific license from the United States Government.
-  * It is the responsibility of any person or organization contemplating
-  * export to obtain such a license before exporting.
-  *
-  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-  * distribute this software and its documentation for any purpose and
-  * without fee is hereby granted, provided that the above copyright
-  * notice appear in all copies and that both that copyright notice and
-  * this permission notice appear in supporting documentation, and that
-  * the name of M.I.T. not be used in advertising or publicity pertaining
-  * to distribution of the software without specific, written prior
-  * permission.  M.I.T. makes no representations about the suitability of
-  * this software for any purpose.  It is provided "as is" without express
-  * or implied warranty.
-  */
- 
- #ifndef	__ENCRYPT__
- #define	__ENCRYPT__
- 
- #define	DIR_DECRYPT		1
- #define	DIR_ENCRYPT		2
- 
- typedef	unsigned char Block[8];
- typedef unsigned char *BlockT;
- typedef struct { Block _; } Schedule[16];
- 
- #define	VALIDKEY(key)	( key[0] | key[1] | key[2] | key[3] | \
- 			  key[4] | key[5] | key[6] | key[7])
- 
- #define	SAMEKEY(k1, k2)	(!bcmp((void *)k1, (void *)k2, sizeof(Block)))
- 
- typedef	struct {
- 	short		type;
- 	long		length;
- 	unsigned char	*data;
- } Session_Key;
- 
- #define P(x)	x
- 
- typedef struct {
- 	char *name;
- 	long	type;
- 	void (*output) (void *, unsigned char *, long);
- 	long	(*input) (void *, long);
- 	void (*init) (void *, long);
- 	long	(*start) (void *, long, long);
- 	long	(*is) (void *, unsigned char *, long);
- 	long	(*reply) (void *, unsigned char *, long);
- 	void (*session) (void *, Session_Key *, long);
- 	long	(*keyid) (void *, long, unsigned char *, long *);
- 	void (*printsub) (unsigned char *, long, unsigned char *, long);
- } Encryptions;
- 
- #define	SK_DES		1	/* Matched Kerberos v5 KEYTYPE_DES */
- 
- extern long encrypt_debug_mode;
- 
- #ifdef notdef
- extern long (*decrypt_input) P((long));
- extern void (*encrypt_output) P((unsigned char *, long));
- #endif
- #endif
- 
- #define ENCTYPE_DES_CFB64	1
- #define ENCTYPE_DES_OFB64	2
--- 0 ----
Index: krb5/mac/kconfig/getpasswd.c
diff -c krb5/mac/kconfig/getpasswd.c:1.1.1.1 krb5/mac/kconfig/getpasswd.c:removed
*** krb5/mac/kconfig/getpasswd.c:1.1.1.1	Mon Jun  2 17:57:51 1997
--- krb5/mac/kconfig/getpasswd.c	Sun Mar 16 20:22:35 2003
***************
*** 1,230 ****
- /*
-  * getpasswd.c
-  * ripped from krb4
-  */
- 
- #define cKrbUserCancelled	2
- #define kLoginDLOGID		-4081
- #define kErrorALERTID		-4082
- #define kLoginOKItem		1
- #define kLoginCnclItem		2
- #define kLoginNameItem		10
- #define kLoginVisPwItem		9
- #define kLoginFrameItem		5
- #define kLoginIvisPwItem	6
- #define kBadUserError		1
- #define kNotUniqueError		2
- #define kGenError			3
- #define kIntegrityError		4
- #define kBadPasswordError	5
- #define cr 					0x0D
- #define enter 				0x03
- #define bs 					0x08
- #define tab 				0x09
- #define larrow 				0x1C
- #define rarrow 				0x1D
- #define uarrow 				0x1E
- #define darrow 				0x1F
- #define DialogNotDone 		1
- 
- typedef union {								// used to convert ProcPtr to Handle
- 	Handle		H;
- 	ProcPtr		P;
- } Proc2Hand;
- 
- 
- 	//  IH 05.03.96: PPC port, we have to use UPP instead of Procedure Ptrs
- static ModalFilterUPP 	gTwoItemFilterUPP = NULL;
- static UserItemUPP		gFrameOKbtnUPP = NULL;
- 
- 
- static pascal void FrameOKbtn( WindowPtr myWindow, short itemNo )
- {
- 	short		tempType;
- 	Handle		tempHandle;
- 	Rect		itemRect;
- 
- 	GetDItem( (DialogPtr) myWindow, itemNo, &tempType, &tempHandle, &itemRect );
- 	PenSize( 3, 3 );
- 	FrameRoundRect( &itemRect, 16, 16 );		// make it an OK button suitable for framing
- }
- 
- 
- static pascal Boolean TwoItemFilter( DialogPtr dlog, EventRecord *event, short *itemHit )
- {
- 	DialogPtr	evtDlog;
- 	short		selStart, selEnd;
- 	Handle		okBtnHandle;
- 	short		tempType;
- 	Rect		tempRect;
- 	long		tempTicks;
- 
- 	if( event->what != keyDown && event->what != autoKey )
- 		return false;				// don't care about this event
- 
- 	switch( event->message & charCodeMask )
- 	{
- 	case cr:						// Return  (hitting return or enter is the same as hitting the OK button)
- 	case enter:						// Enter
- 	
- 		if (!OKIsEnabled(dlog)) {
- 			event->what = nullEvent;
- 			return false;
- 		}
- 		
- 		GetDItem( dlog, kLoginOKItem, &tempType, &okBtnHandle, &tempRect );
- 		HiliteControl( (ControlHandle) okBtnHandle, 1 );	// hilite the OK button
- 		Delay( 10, &tempTicks );	// wait a little while
- 		HiliteControl( (ControlHandle) okBtnHandle, 0 );
- 
- 		*itemHit = kLoginOKItem;		// OK Button
- 		return true;				// We handled the event
- 
- 	case tab:						// Tab
- 	case larrow:					// Left arrow  (Keys that just change the selection)
- 	case rarrow:					// Right arrow
- 	case uarrow:					// Up arrow
- 	case darrow:					// Down arrow
- 		return false;				// Let ModalDialog handle them
- 
- 	default:
- 	
- 		// First see if we're in password field, do stuff to make  displayed
- 		
- 		if( ((DialogPeek) dlog)->editField == kLoginVisPwItem - 1 ) {
- 
- 			selStart = (**((DialogPeek) dlog)->textH).selStart;	// Get the selection in the visible item
- 			selEnd = (**((DialogPeek) dlog)->textH).selEnd;
- 
- 			SelIText( dlog, kLoginIvisPwItem, selStart, selEnd );	// Select text in invisible item
- 			DialogSelect( event,&evtDlog, itemHit );			// Input key
- 
- 			SelIText( dlog, kLoginVisPwItem, selStart, selEnd );	// Select same area in visible item
- 			if( ( event->message & charCodeMask ) != bs )		// If it's not a backspace (backspace is the only key that can affect both the text and the selection- thus we need to process it in both fields, but not change it for the hidden field.
- 				event->message = '';							// Replace with character to use
- 		}
- 		
- 		// Do the key event and set the hilite on the OK button accordingly
- 		
- 		DialogSelect( event,&evtDlog, itemHit );			// Input key
- 		SetOKEnable(dlog);
- 		
- 		// Pass a NULL event back to DialogMgr
- 		
- 		event->what = nullEvent;
- 		
- 		return false;
- 	}
- }
- 
- static int SetOKEnable( DialogPtr dlog )
- {
- 	short		itemType,state;
- 	Handle		itemHandle;
- 	Rect		itemRect;
- 	Str255		tpswd,tuser;
- 	ControlHandle okButton;
- 
- 	GetDItem( dlog, kLoginNameItem, &itemType, &itemHandle, &itemRect );
- 	GetIText( itemHandle, tuser );
- 	GetDItem( dlog, kLoginVisPwItem, &itemType, &itemHandle, &itemRect );
- 	GetIText( itemHandle, tpswd );
- 	GetDItem( dlog, kLoginOKItem, &itemType, (Handle *) &okButton, &itemRect );
- 	state = (tuser[0] && tpswd[0]) ? 0 : 255;
- 	HiliteControl(okButton,state);
- }
- 
- static int OKIsEnabled( DialogPtr dlog )
- {
- 	short		itemType;
- 	Rect		itemRect;
- 	ControlHandle okButton;
- 
- 	GetDItem( dlog, kLoginOKItem, &itemType, (Handle *) &okButton, &itemRect );
- 	return ((**okButton).contrlHilite != 255);
- }
- 
- #define ANAME_SZ	100
- #define	INST_SZ		100
- #define REALM_SZ	100
- #define MAX_K_NAME_SZ	100
- 
- OSErr GetUserInfo( char *UserName, char *password )
- {
- 	DialogPtr		myDLOG;
- 	short			itemHit;
- 	short			itemType;
- 	Handle			itemHandle;
- 	Rect			itemRect;
- 	OSErr			rc = DialogNotDone;
- 	Str255			tempStr,tpswd,tuser;
- 	Proc2Hand		procConv;
- 	short			rf;
- 	char uname[ANAME_SZ]="\0";
- 	char uinst[INST_SZ]="\0";
- 	char realm[REALM_SZ]="\0";
- 	CursHandle		aCursor;
- 		
- 	/////////////////////////
- 	// Ask user for password
- 	/////////////////////////
- 	password[0] = 0;
- 	myDLOG = GetNewDialog( kLoginDLOGID, (void *) NULL, (WindowPtr) -1 );
- 	if( myDLOG == NULL ) {
- 		return -1;
- 	}
- 
- 	// Insert user's name in dialog
- 	if (*UserName) {
- 		tempStr[0] = strlen(UserName);
- 		memcpy( &(tempStr[1]), UserName, tempStr[0]);
- 		GetDItem( myDLOG, kLoginNameItem, &itemType, &itemHandle, &itemRect );
- 		SetIText( itemHandle, tempStr );
- 		SelIText( myDLOG, kLoginVisPwItem,0,0 );
- 	}
- 	else SelIText( myDLOG, kLoginNameItem,0,0 );
- 	
- 		//  IH 05.03.96: Create the Universal Proc Pointers here
- 	if (gTwoItemFilterUPP == NULL)
- 		gTwoItemFilterUPP = NewModalFilterProc(TwoItemFilter);
- 	if (gFrameOKbtnUPP == NULL)
- 		gFrameOKbtnUPP = NewUserItemProc(FrameOKbtn);
- 			
- 	// Establish a user item around the OK button to draw the default button frame in
- 	GetDItem( myDLOG, kLoginOKItem, &itemType, &itemHandle, &itemRect );
- 	InsetRect( &itemRect, -4, -4 );				// position user item around OK button
- 	procConv.P = (ProcPtr) FrameOKbtn;			// convert ProcPtr to a Handle
- 		//  IH 05.03.96: PPC Port - Use UPP instead of Procedure Ptrs
- 	SetDItem( myDLOG, kLoginFrameItem, userItem, (Handle) gFrameOKbtnUPP, &itemRect );
- 	
- 	InitCursor();
- 	do {
- 		do {										// display the dialog & handle events
- 			SetOKEnable(myDLOG);
- 				//  IH 05.03.96: PPC Port - Use UPP instead of Procedure Ptrs
- 			ModalDialog(gTwoItemFilterUPP, (short *) &itemHit );
- 		} while( itemHit != kLoginOKItem && itemHit != kLoginCnclItem );
- 		
- 		if( itemHit == kLoginOKItem ) {				// OK button pressed?			
- 			GetDItem( myDLOG, kLoginNameItem, &itemType, &itemHandle, &itemRect );
- 			GetIText( itemHandle, tempStr );
- 		
- 			tempStr[0] = ( tempStr[0] < MAX_K_NAME_SZ ) ? tempStr[0] : MAX_K_NAME_SZ-1 ;
- 			memcpy ((void*) UserName, (void*) &(tempStr[1]), tempStr[0]);
- 			UserName[tempStr[0]] = 0;
- 			
- 			GetDItem( myDLOG, kLoginIvisPwItem, &itemType, &itemHandle, &itemRect );
- 			GetIText( itemHandle, tempStr );
- 		
- 			tempStr[0] = ( tempStr[0] < ANAME_SZ ) ? tempStr[0] : ANAME_SZ-1 ;
- 			memcpy( (void*) password, (void*) &(tempStr[1]), tempStr[0]);
- 			password[tempStr[0]] = 0;
- 
- 			rc = !DialogNotDone;
- 		}
- 		else rc = cKrbUserCancelled;						// pressed the Cancel button
- 	} while( rc == DialogNotDone );
- 
- 	DisposDialog( myDLOG );
- 	return rc;
- }
--- 0 ----
Index: krb5/mac/kconfig/glue.h
diff -c krb5/mac/kconfig/glue.h:1.1.1.1 krb5/mac/kconfig/glue.h:removed
*** krb5/mac/kconfig/glue.h:1.1.1.1	Mon Jun  2 17:57:52 1997
--- krb5/mac/kconfig/glue.h	Sun Mar 16 20:22:35 2003
***************
*** 1,48 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- #pragma parameter __D0 getA5
- long getA5 () = {
- 	0x200d					/* move.l a5, d0 */
- };
- 
- #pragma parameter setD0(__D0)
- void setD0 () = {
- 	0x4e71					/* nop */
- };
- 
- /*
-  * getA0
-  * returns the current value of register A0
-  */
- #pragma parameter _D0 getA0()
- long getA0 () = {
- 	0x2008					// move.l a0, d0
- };
- 
- /*
-  * swap bytes in a long
-  */
- #pragma parameter __D0 swapl(__A0)
- unsigned long swapl (unsigned long target) = {
- 	0x2008,							// move.l a0, d0
- 	0xe058,							// ror.w d0, 8
- 	0x4840,							// swap d0
- 	0xe058							// ror.w d0, 8
- };
- 
- #pragma parameter __D0 swapA4(__D0)
- long swapA4(long);
- long swapA4 () = {
- 	0xc18c					/* exg d0, a4 */
- };
--- 0 ----
Index: krb5/mac/kconfig/k.bw
Index: krb5/mac/kconfig/k.color
Index: krb5/mac/kconfig/kadm.c
diff -c krb5/mac/kconfig/kadm.c:1.1.1.1 krb5/mac/kconfig/kadm.c:removed
*** krb5/mac/kconfig/kadm.c:1.1.1.1	Mon Jun  2 17:57:52 1997
--- krb5/mac/kconfig/kadm.c	Sun Mar 16 20:22:35 2003
***************
*** 1,1279 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- #include <AppleTalk.h>
- #include <Devices.h>
- #include <Lists.h>
- #include <Menus.h>
- #include <Packages.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
- 
- #include "AddressXlation.h"
- #include "MacTCP.h"
- 
- #include "kadm.h"
- #include "krb_driver.h"
- #include "glue.h"
- #include "kconfig.h"
- 
- #include "kconfig.proto.h"
- #include "kadm.proto.h"
- #include "desproto.h"
- 
- int private_msg_ver = KRB_PROT_VERSION;
- Boolean kerberos_debug = 0;				/* ddd */
- int kerberos_debug_packet = 0;
- static int ONE = 1;
- static short mactcp = 0;
- 
- extern queuetype serverQ;
- extern krbHiParmBlock khipb;
- extern krbParmBlock klopb;
- 
- /*
-  * kerberos_changepw
-  * Return error or zero if ok
-  */
- int kerberos_changepw (char *name, char *password, char *new, char **reason)
- {
- 	int s;
- 	int rc = 0;
- 	int life = 255;						/* 255 * 5 minutes */
- 	char *realm, *instance, *sinstance;
- 	char uname[ANAME_SZ], uinstance[INST_SZ], urealm[REALM_SZ];
- 	char service[256];
- 	servertype *sp;
- 	des_cblock newkey;
- 	unsigned char snewkey[1+8];
- 	CREDENTIALS *cr;
- 	unsigned char buf[1300];				/* changepw credentials buffer */
- 	des_cblock sessionKey;
- 
- 	*reason = "unknown";
- 	krb_parse_principal(name, uname, uinstance, urealm);
- 
- 	/*
- 	 * If the user specified a realm, try to match it up with 
- 	 * a realm that we know about. Try case-sensitive first,
- 	 * then case insensitive so the user doesn't have to worry about
- 	 * case matching. If no match, bomb out immediately.
- 	 */
- 	if (urealm[0]) {
- 		for (sp = (servertype *)serverQ; sp; sp = sp->next)
- 			if (sp->admin && (strcmp(urealm, sp->realm) == 0))
- 				break;
- 		if (!sp) 
- 			for (sp = (servertype *)serverQ; sp; sp = sp->next)
- 				if (sp->admin && (ustrcmp(urealm, sp->realm) == 0))
- 					break;
- 		if (!sp) {
- 			*reason = "Could not find admin server for specified realm.";
- 			return -1;
- 		}
- 		strcpy(urealm, sp->realm);		/* insure correct case */
- 		realm = urealm;
- 	} else {							/* get local realm */
- 		klopb.uRealm = urealm;
- 		if (s = lowcall(cKrbGetLocalRealm))
- 			strcpy(urealm, "");
- 		realm = urealm;
- 	}
- 
- 	if (uinstance[0])
- 		instance = uinstance;
- 	else
- 		instance = "";
- 
- 	sinstance = realm;
- 
- 	/*
- 	 * Get password changing credentials.
- 	 * changepw.kerberos@realm user.instance
- 	 * We shouldn't keep these around after using them.
- 	 * 
- 	 * First, setup the username and old password the user typed in.
- 	 */
- 	khipb.user = uname;
- 	if (s = hicall(cKrbSetUserName)) {
- 		*reason = "cKrbSetUserName";
- 		return s;
- 	}
- 	khipb.user = password;
- 	if (s = hicall(cKrbSetPassword)) {
- 		*reason = "cKrbSetPassword";
- 		return s;
- 	}
- 	
- 	strcpy(service, "changepw.kerberos@");
- 	strcat(service, realm);
- 	bzero(&khipb, sizeof(krbHiParmBlock));
- 	khipb.service = service;
- 	khipb.buf = (char *)buf;				/* where to build it */
- 	khipb.checksum = 0;
- 	khipb.buflen = sizeof(buf);
- 	if (s = hicall(cKrbCacheInitialTicket)) {
- 		*reason = "cKrbCacheInitialTicket";	/* ddd */
- 		return s;
- 	}
- 	bcopy(khipb.sessionKey, sessionKey, sizeof(sessionKey));	/* save the session key */
- 
- 	/*
- 	 * Change the new password to a key.
- 	 */
-     (void)des_string_to_key(new, (unsigned char *)newkey);
- 
-     /* 
- 	 * insert code, change key to stream 
- 	 */
- 	snewkey[0]  = (unsigned char) CHANGE_PW;
-     bcopy((char *) (((long *) newkey) + 1), &snewkey[1], 4);
-     bcopy((char *) (((long *) newkey)), &snewkey[5], 4);
- 
-     s = kadm_cli_send(snewkey, sizeof(snewkey), uname, uinstance, urealm);
- 	if (s) {
- 		*reason = "kadm_cli_send";			/* ddd */
- 		rc = s;
- 		goto xit;
- 	}
- 
- 	rc = 0;
- 
- xit:
- #ifdef notdef /* ddd */	
- 	/* 
- 	 * destroy changepw credentials
- 	 */
- 	if (cr = krb_get_cred("changepw", "kerberos", urealm)) {
- 		qunlink(&k_credentialsQ, cr);
- 		freecredentials(cr);
- 	}
- #endif
- 
- 	return rc;
- }
- 
- 
- /*
-  * kadm_cli_send
-  *	recieves   : opcode, packet, packet length, serv_name, serv_inst
-  *	returns    : return code from the packet build, the server, or
-  *			 something else 
-  *
-  * It assembles a packet as follows:
-  *	 8 bytes    : VERSION STRING
-  *	 4 bytes    : LENGTH OF MESSAGE DATA and OPCODE
-  *		    : KTEXT
-  *		    : OPCODE       \
-  *		    : DATA          > Encrypted (with make priv)
-  *		    : ......       / 
-  *
-  * If it builds the packet and it is small enough, then it attempts to open the
-  * connection to the admin server.  If the connection is succesfully open
-  * then it sends the data and waits for a reply. 
-  */
- 
- /*
-  * unsigned char *st_dat:	theactual data
-  * int st_siz:		length of said data
-  * unsigned char **ret_dat: 	to give return info
-  * int *ret_siz:	length of returned info
-  */
- 
- int kadm_cli_send (unsigned char *st_dat, int st_siz, char *uname, char *uinstance, char *urealm)
- {
- 	int s;
-     unsigned char *priv_pak = 0;		/* private version of the packet */
-     int priv_len;						/* length of private packet */
-     unsigned long cksum;				/* checksum of the packet */
-     MSG_DAT mdat;
- 	CREDENTIALS cred, *cr = &cred;
- 	paktype *pak = 0;
- 	unsigned char *pp;					/* packet build pointer */
- 	long tmpl;
- 	tcprequest *tcprequest = 0;
- 	long error = KRBE_FAIL;				/* preset general failure */
- 	des_cblock sess_key;
- 	Key_schedule sess_sched;
- 	servertype *sp;
- 
-     if (!(pak = newpaktype(2048)))
- 		goto err;
- 	pp = pak->data;
- 
-     strncpy((char *)pp, KADM_VERSTR, KADM_VERSIZE);
- 	pp += KADM_VERSIZE;
- 
- 	/*
- 	 * Find password changing credentials that we previously requested.
- 	 */
- 	bzero(cr, sizeof(CREDENTIALS));
- 	strcpy(cr->service, "changepw");
- 	strcpy(cr->instance, "kerberos");
- 	strcpy(cr->realm, urealm);
- 	bzero(&klopb, sizeof(klopb));
- 	klopb.uName = uname;
- 	klopb.uInstance = uinstance;
- 	klopb.uRealm = urealm;
- 	klopb.cred = &cred;
- 	if (s = lowcall(cKrbGetCredentials)) {
- 		error = s;
- 		goto err;
- 	}
- 
- 	/*
- 	 * Open a socket so that we will have addresses and ports for
- 	 * idiotic krb_mk_priv().
- 	 */
- 	if (!(tcprequest = (struct tcprequest *)NewPtrClear(sizeof(struct tcprequest)))) {
- 		error = KRBE_MEM;
- 		goto err;
- 	}
- 	tcprequest->remotePort = 751;						/* admin port */
- 
- 	/*
- 	 * Find admin server with the correct realm.
- 	 * ... may need to make better way to map realms to servers/admin servers.
- 	 */
- 	for (sp = (servertype *)serverQ; sp; sp = sp->next)
- 		if (sp->admin && (strcmp(urealm, sp->realm) == 0))
- 			break;
- 
- 	if (sp)
- 		tcprequest->remoteHost = lookupaddr(sp->host);
- 	else
- 		goto err;
- 		
- 	if (!tcprequest->remoteHost)
- 		goto err;
- 		
- 	if (!tcp_open(tcprequest))
- 		goto err;
- 
- 	bcopy((char *)cr->session, (char *) sess_key, sizeof(des_cblock));
- 	/* bzero((char *)cr->session, sizeof(des_cblock)); ??? */
- 	des_key_sched(sess_key, sess_sched);
- 
-     /* 
- 	 * 200 bytes for extra info case 
- 	 */
-     priv_pak = (unsigned char *)NewPtrClear(st_siz + 200);
-     if ((priv_len = krb_mk_priv(st_dat, priv_pak, (unsigned long)st_siz,
- 								sess_sched, sess_key, tcprequest)) < 0)
- 		goto err;
- 
-     /* 
- 	 * here is the length of priv data.  receiver calcs
- 	 * size of authenticator by subtracting vno size, priv size, and
- 	 * sizeof(unsigned long) (for the size indication) from total size 
- 	 */
- 	tmpl = htonl(priv_len);
- 	bcopy(&tmpl, pp, sizeof(long));
- 	pp += sizeof(long);							/* priv_len: length of priv_pak */
- 
- #ifdef notdef
- 	if (kerberos_debug_packet)
- 		khexout(priv_pak, priv_len, "KRB:", "priv_pak ");
- #endif
- 
-     cksum = des_quad_cksum(priv_pak, (unsigned long *)0, (long)priv_len, 0,
- 					   (unsigned char *)sess_key);
- 
- #ifdef notdef
- 	if (kerberos_debug_packet) {
- 		khexout(&cksum, 4, "KRB:", "quad checksum ");
- 		khexout(sess_key, 8, "KRB:", "session key ");
- 		khexout(priv_pak, priv_len, "KRB:", "priv pak");
- 	}
- #endif
- 
- 	pp += krb_build_ap(pp, cr, urealm, cksum);	/* KRB_AP_REQ msg */
- 
-     bcopy(priv_pak, pp, priv_len);				/* priv_pak */
- 	pp += priv_len;
-     DisposePtr((Ptr)priv_pak);
- 	priv_pak = 0;
- 
- 	/*
-      * Transmit request packet and get reply packet.
- 	 */
- 	pak->len = pp - pak->data;
- #ifdef notdef
- 	if (kerberos_debug_packet)
- 		khexout(pak->data, pak->len, "KRB:", "kpasswd request packet ");
- #endif
- 	pak = krb_ask_tcp(pak, urealm, tcprequest);
- 	if (!pak) {
- 		error = KRBE_TIMO;				/* Timeout */
- 		goto err;
- 	}
- 
- 	/*
- 	 * Process reply packet.
- 	 */
- #ifdef notdef
- 	if (kerberos_debug_packet)
- 		khexout(pak->data, pak->len, "KRB:", "kpasswd response packet ");
- #endif
- 
-     /* 
- 	 * first see if it's a YOULOSE 
- 	 */
-     if ((pak->len >= KADM_VERSIZE) &&
- 		!strncmp(KADM_ULOSE, (char *)pak->data, KADM_VERSIZE)) {
- 
- 		/* it's a youlose packet */
- 		if (pak->len < KADM_VERSIZE + sizeof(long)) {
- 			goto err;
- 		}
- 
- 		bcopy(pak->data + KADM_VERSIZE, (char *)&error, sizeof(long));
- 		error = ntohl(error);
- 		goto err;
-     }
- 
-     /* 
- 	 * need to decode the ret_dat 
- 	 */
-     if (error = krb_rd_priv(pak->data, (unsigned long)pak->len, sess_sched,
- 							 sess_key, tcprequest, &mdat))
- 		goto err;
- 
-     if (mdat.app_length < KADM_VERSIZE + 4)	{			/* if too short */
- 		goto err;
- 	}
-     if (strncmp((char *)mdat.app_data, KADM_VERSTR, KADM_VERSIZE)) { /* if bad ver */
- 		goto err;
- 	}
-     bcopy((char *)mdat.app_data+KADM_VERSIZE, (char *)&error, sizeof(unsigned long));
-     error = ntohl((unsigned long)error);
- 
- #ifdef notdef	/* don't care about rest of data */
-     if (!(return_dat = (unsigned char *)xmalloc((unsigned)(mdat.app_length -
- 												   KADM_VERSIZE - sizeof(unsigned long)))))
- 		RET_N_FREE2(KADM_NOMEM);
-     bcopy((char *) mdat.app_data + KADM_VERSIZE + sizeof(unsigned long),
- 		  (char *)return_dat,
- 		  (int)mdat.app_length - KADM_VERSIZE - sizeof(unsigned long));
- 
-     free((char *)*ret_dat);
-     clear_secrets();
-     *ret_dat = return_dat;
-     *ret_siz = mdat.app_length - KADM_VERSIZE - sizeof(unsigned long);
- #endif
- 
- err:	
- 	if (priv_pak)
- 		DisposePtr((Ptr)priv_pak);
- 	if (pak)
- 		DisposePtr((Ptr)pak);
- 	if (tcprequest)
- 		tcp_freerequest(tcprequest);
- 
-     return error;
- }
- 
- 
- /*
-  * krb_ask_tcp
-  * Sends a request to a Kerberos server and waits for a response.
-  * Timeouts SHOULD... cause other servers in the list to be tried.
-  * 
-  * The respose packet, if any, is returned.
-  * The request packet is discarded.
-  *
-  * PROBABLY SHOULD USE REALM TO SPECIFY WHICH SERVERS ARE USABLE. ???
-  */
- paktype *krb_ask_tcp (paktype *pak, char *realm, tcprequest *tcprequest)
- {
- 	paktype *newpak;
- 	servertype *sp;
- 		
- 	/*
- 	 * Find a server with the correct realm.
- 	 */
- 	for (sp = (servertype *)serverQ; sp; sp = sp->next)
- 		if (strcmp(realm, sp->realm) == 0)
- 			break;
- 	if (!sp) {
- 		disposepak(pak);
- #ifdef notdef
- 		if (kerberos_debug || kerberos_debug_packet)
- 			buginf("\nKRB: krb_ask_tcp: no server for realm \"%s\"", realm);
- #endif
- 		return 0;
- 	}
- 	
- 	/*
- 	 * Build and transmit the request
- 	 */
- 	tcprequest->pak = pak;		
- 	tcprequest->timeout = 2;				/* timeout period in seconds */
- 	tcprequest->retries = 8;				/* number of retransmits allowed */
- 	tcprequest->remoteHost = lookupaddr(sp->host);
- 	if (!tcp_transmit(tcprequest))
- 		return ((paktype *)0);
- 
- 	/*
- 	 * Wait for request complete
- 	 */
- 	for (;;) {
- 		/* ... wait next event or spincursor ... */
- 		
- 		switch (tcprequest->result) {
- 		case UR_READERROR:
- 			disposepak(pak);
- 			return 0;
- 
- 		case UR_TIMEOUT:
- 			disposepak(pak);
- 			return 0;
- 
- 		case UR_READDONE:
- 			disposepak(pak);
- 			newpak = newpaktype(tcprequest->rpb.csParam.receive.rcvBuffLen);
- 			if (newpak) {
- 				bcopy(tcprequest->rpb.csParam.receive.rcvBuff, newpak->data,
- 				      tcprequest->rpb.csParam.receive.rcvBuffLen);
- 				newpak->len = tcprequest->rpb.csParam.receive.rcvBuffLen;
- 			}
- 			return newpak;
- 		} /* switch tcprequest->result */
- 	}
- }
- 
- 
- /*
-  * krb_parse_principal
-  * Parse a name which may include an instance and realm. 
-  * The return locations are assumed to be of sufficient
-  * size, bounded by the _SZ constants.
-  * 
-  * If periods are allowed in kerberos names, this code will need
-  * to be smarter. The case of rick.watson@realm is ambiguous and
-  * joe.smith.rcmd@realm is parsed incorrectly.
-  */
- void krb_parse_principal (char *user, char *uname, char *uinst, char *urealm)
- {
- 	char *cp;
- 	char tmp[ANAME_SZ + INST_SZ + REALM_SZ];
- 
- 	strncpy(tmp, user, ANAME_SZ + INST_SZ + REALM_SZ);
- 
- 	if (cp = strchr(tmp, '@')) {
- 		*cp++ = '\0';
- 		strncpy(urealm, cp, REALM_SZ);
- 	} else
- 		*urealm = '\0';
- 
- 	if (cp = strchr(tmp, '.')) {
- 		*cp++ = '\0';
- 		strncpy(uinst, cp, INST_SZ);
- 	} else
- 		*uinst = '\0';
- 
- 	strncpy(uname, tmp, ANAME_SZ);
- }
- 
- 
- /*
-  * krb_build_ap
-  *
-  * Build a KRB_AP_REQ message.
-  * Returns the message length.
-  *
-  * cp:    where to build the message
-  */
- 
- int krb_build_ap (char *cp, CREDENTIALS *cr, char *srealm, long checksum)
- {
- 	int len;
- 	long gmtunixtime;
- 	unsigned char *sp, *ap, *lenAp;
- 	KTEXT_ST *ticket;
- 	Key_schedule key_s;
- 	struct timeval tv;
- 	struct timezone tz;
- 
- 	ticket = &cr->ticket_st;
- 
- 	sp = cp;
- 	/*
- 	 * pvno, type, kvno, srealm, ticket length, authenticator length.
- 	 */
- 	*cp++ = KRB_PROT_VERSION;					/* pvno */
- 	*cp++ = AUTH_MSG_APPL_REQUEST | HOST_BYTE_ORDER; /* type | B */
- 	*cp++ = (unsigned char) cr->kvno;			/* kvno */
- 	cp = stringcopy(cp, srealm);				/* srealm */
- 	*cp++ = (unsigned char) ticket->length;		/* len_T */
- 	lenAp = cp++;								/* save pointer to len_A */
- 	/*
- 	 * ticket
- 	 */
- 	bcopy((char *)(ticket->dat), cp, ticket->length); /* ticket */
- 	cp += ticket->length;
- 	/*
- 	 * Build authenticator and encrypt it using the session key.
- 	 */
- 	ap = cp;
- 	cp = stringcopy(cp, cr->pname);				/* Principal's cname */
- 	cp = stringcopy(cp, cr->pinst);				/* Principal's instance */
- 	cp = stringcopy(cp, cr->realm);				/* Authentication domain */
- 	bcopy((char *)&checksum, (char *)cp, 4);	/* Checksum */
- 	cp += 4;
- #ifdef notdef /* ... */
- 	*cp++ = (char)(msclock & 0xff);				/* times */
- #else
- 	*cp++ = 1;
- #endif
- 	gettimeofdaynet(&tv, &tz);
- 	gmtunixtime = tv.tv_sec;
- 	bcopy(&gmtunixtime, cp,	 4);
- 	cp += 4;
- 	len = cp - ap;
- 	len = ((len+7)/8)*8;		/* Fill to a multiple of 8 bytes for DES */
- 	*lenAp = len;
- 	cp = ap + len;
- #ifdef notdef
- 	if (kerberos_debug_packet)					/* temp !!! ??? */
- 		khexout((char *)sp, cp - sp, "KRB:", 
- 				"krb_build_ap (unencrypted) message:");
- #endif
- 	des_key_sched((des_cblock)cr->session, key_s);
- 
- 	/*
- 	 * The cblock must be word aligned or we'll crash on a 68000, so copy it.
- 	 */
- 	des_pcbc_encrypt((unsigned char *)ap, (unsigned char *)ap, (long) len, key_s, 
- 				 (unsigned char *)cr->session, 1);
- 	bzero((char *) key_s, sizeof(key_s));		/* clean up */
- 	len = cp - sp;								/* data length */
- 	return len;
- }
- 
- 
- /*
-  * tcp_open
-  */
- #define TCP_RBUFSIZE	4096					/* size of receive buffer */
- Boolean tcp_open (tcprequest *tcprequest)
- {
- 	int s;
- 	TCPiopb pb;
- 	struct GetAddrParamBlock my;
- 		
- 	if (!mactcp) {
- 		if (s = OpenDriver("\p.ipp", &mactcp)) {
- 			doalert("Could not open .ipp driver: %d", s);
- 			getout(0);
- 		}
- 	}
- 
- 	if (tcprequest->stream)						/* if stream already open */
- 		return true;
- 
- 	if (!(tcprequest->tcpbuf = (char *)NewPtrClear(TCP_RBUFSIZE)))
- 		return false;
- 
- 	/*
- 	 * Create a TCP stream
- 	 */
- 	pb.csParam.create.rcvBuff = tcprequest->tcpbuf;
- 	pb.csParam.create.rcvBuffLen = TCP_RBUFSIZE;
- 	pb.csParam.create.notifyProc = 0;				/* no ASR */
- 	pb.csParam.create.userDataPtr = (Ptr)tcprequest;
- 	pb.ioCompletion = 0;
- 	pb.ioCRefNum = mactcp;
- 	pb.csCode = TCPCreate;
- 	s = PBControl((ParmBlkPtr)&pb, false);
- 	if (s)
- 		return false;
- 	tcprequest->stream = pb.tcpStream;
- 		
- 
- 	/*
- 	 * Open the connection
- 	 */
- 	pb.ioCRefNum = mactcp;
- 	pb.csCode = TCPActiveOpen;
- 	pb.csParam.open.validityFlags = timeoutValue | timeoutAction;
- 	pb.csParam.open.ulpTimeoutValue = 60 	/* seconds */;
- 	pb.csParam.open.ulpTimeoutAction = 1 	/* 1:abort 0:report */;
- 	pb.csParam.open.commandTimeoutValue = 0;
- 	pb.csParam.open.remoteHost = tcprequest->remoteHost;
- 	pb.csParam.open.remotePort = tcprequest->remotePort;
- 	pb.csParam.open.localHost = 0;
- 	pb.csParam.open.localPort = 0;
- 	pb.csParam.open.dontFrag = 0;
- 	pb.csParam.open.timeToLive = 0;
- 	pb.csParam.open.security = 0;
- 	pb.csParam.open.optionCnt = 0;
- 	s = PBControl((ParmBlkPtr)&pb, false);	
- 	if (s) {
- 		tcp_close(tcprequest);
- 		return false;
- 	}
- 	tcprequest->localPort = pb.csParam.open.localPort;
- 
- 	/*
- 	 * Fill in our local ip address
- 	 */
- 	bzero(&my, sizeof(my));
- 	my.ioCRefNum = mactcp;
- 	my.csCode = ipctlGetAddr;
- 	s = PBControl((ParmBlkPtr)&my, false);
- 	if (s)
- 		return false;
- 	tcprequest->localHost = my.ourAddress;
- 
- 	return true;
- }
- 	
- 
- /*
-  * tcp_close
-  * Close the stream associated with a request entry
-  */
- void tcp_close (tcprequest *tcprequest)
- {
- 	int s;
- 	TCPiopb pb;
- 	
- 	if (!tcprequest->stream)
- 		return;
- 		
- #ifdef notdef
- 	pb.csParam.close.validityFlags = timeoutValue | timeoutAction;
- 	pb.csParam.close.ulpTimeoutValue = 60 /* seconds */;
- 	pb.csParam.close.ulpTimeoutAction = 1 /* 1:abort 0:report */;
- #endif
- 	pb.ioCompletion = 0;
- 	pb.ioCRefNum = mactcp;
- 	pb.tcpStream = tcprequest->stream;
- 	pb.csCode = TCPRelease;
- 
- 	s = PBControl((ParmBlkPtr)&pb, false);
- 	/* ignore error */
- 
- 	tcprequest->stream = 0;
- 
- 	if (tcprequest->tcpbuf)
- 		DisposePtr((Ptr)tcprequest->tcpbuf);
- 	tcprequest->tcpbuf = 0;
- }
- 
- 
- /*
-  * tcp_transmit
-  */
- Boolean tcp_transmit (tcprequest *tcprequest)
- {
- 	int s;
- 	TCPiopb *pb;
- 
- 	/*
- 	 * Get a socket so that we will be able to identify responses.
- 	 */
- 	if (!tcp_open(tcprequest))
- 		return false;
- 		
- 	pb = &tcprequest->wpb;
- 	if (pb->ioResult == 1) {				/* if busy */
- 		DebugStr("\ptcp_transmit: pb is busy");
- 		return false;
- 	}
- 	bzero(pb, sizeof(struct TCPiopb));
- 	pb->csCode = TCPSend;
- 	pb->ioCompletion = 0;
- 	pb->ioCRefNum = mactcp;
- 	pb->tcpStream = tcprequest->stream;
- 
- 	pb->csParam.send.validityFlags = timeoutValue | timeoutAction;
- 	pb->csParam.send.ulpTimeoutValue = 30 	/* seconds */;
- 	pb->csParam.send.ulpTimeoutAction = 1 	/* 1:abort 0:report */;
- 	pb->csParam.send.pushFlag = true;
- 	pb->csParam.send.urgentFlag = false;
- 
- 	pb->csParam.send.wdsPtr = (Ptr)&tcprequest->wds[0];
- 	pb->csParam.send.userDataPtr = (Ptr)tcprequest;
- 
- 	tcprequest->wds[0].length = sizeof(tcprequest->xlen); /* transmit length */
- 	tcprequest->wds[0].ptr = (Ptr)&tcprequest->xlen;
- 	tcprequest->xlen = tcprequest->pak->len;
- 	tcprequest->wds[1].length = tcprequest->pak->len;
- 	tcprequest->wds[1].ptr = tcprequest->pak->data;
- 	tcprequest->wds[2].length = 0;
- 	tcprequest->wds[2].ptr = 0;
- 
- 	s = PBControl((ParmBlkPtr)pb, true);
- 	if (s)
- 		return false;
- 		
- 	tcprequest->readheader = true;
- 	if (!tcp_startread(tcprequest))				/* setup read/timeout */
- 		return false;
- 
- 	return true;
- }
- 
- /*
-  * tcp_startread
-  * Start a read with a timeout. A timeout will trigger a 
-  * request failure.
-  */
- Boolean tcp_startread (tcprequest *tcprequest)
- {
- 	int s;
- 	TCPiopb *pb;
- 	
- 	pb = &tcprequest->rpb;
- 	if (pb->ioResult == 1)						/* if read busy */
- 		return false;
- 		
- 	bzero(pb, sizeof(struct TCPiopb));
- 
- 	pb->csCode = TCPRcv;
- 	pb->csParam.receive.commandTimeoutValue = 30;
- 
- 	/*
- 	 * First, read a  length header.
- 	 */
- 	if (tcprequest->readheader) {
- 		pb->csParam.receive.rcvBuffLen = sizeof(tcprequest->header);
- 		pb->csParam.receive.rcvBuff = (Ptr)&tcprequest->header;
- 	} else {
- 		pb->csParam.receive.rcvBuffLen = tcprequest->header;
- 		pb->csParam.receive.rcvBuff = tcprequest->rbuf;
- 	}
- 
- 	pb->ioCRefNum = mactcp;
- 	pb->tcpStream = tcprequest->stream;
- 	pb->ioCompletion = (TCPIOCompletionProc)tcp_readdone;
- 	pb->csParam.receive.userDataPtr = (Ptr)tcprequest;
- 
- 	s = PBControl((ParmBlkPtr)pb, true);
- 	if (s)
- 		return false;
- 	return true;
- }
- 
- 
- /*
-  * tcp_readdone
-  * IO Completion routine called when a read request completes or times out
-  */
- void tcp_readdone ()
- {
- 	TCPiopb *pb;
- 	tcprequest *tcprequest;
- 	
- 	pb = (TCPiopb *)getA0();					/* recover pb */
- 	tcprequest = (struct tcprequest *)pb->csParam.receive.userDataPtr;
- 
- 	if (pb->ioResult == commandTimeout) {		/* if command timeout */
- 		tcprequest->result = UR_TIMEOUT;
- 		return;
- 	} 
- 	
- 	if (pb->ioResult != noErr) { 				/* error */
- 		tcprequest->result = UR_READERROR;
- 		return;
- 	}
- 	
- 	if (tcprequest->readheader) {		/* if we just read header */
- 		tcprequest->readheader = false;	/* read the packet now */
- 		tcp_startread(tcprequest);
- 		return;
- 	}
- 
- 	/*
- 	 * Read has completed successfully. Data pointers are in the rpb.
- 	 * Signal success to user-level code.
- 	 */
- 	tcprequest->result = UR_READDONE;			/* read has completed */
- }
- 
- 
- /*
-  * tcp_freerequest
-  */
- void tcp_freerequest (tcprequest *request)
- {
- 	if (request->stream)
- 		tcp_close(request);
- 
- 	DisposePtr((Ptr)request);
- }
- 
- 
- paktype *newpaktype (int len)
- {
- 	paktype *pak;
- 	
- 	if (pak = (paktype *)NewPtrClear(sizeof(paktype) + len)) {
- 		pak->len = len;
- 		pak->data = (unsigned char *)pak + sizeof(paktype);
- 	}
- 	return pak;
- }
- 
- 
- void disposepak (paktype *pak)
- {
- 	DisposePtr((Ptr)pak);
- }
- 
- 
- /*
-  * stringcopy
-  * This version of strcpy writes a null string into dst
-  * if the src string is a null pointer.	 It returns 
-  * a pointer to the byte after the string terminator.
-  */
- void *stringcopy (void *dst, void *src)
- {
- 	char *d = dst;
- 	char *s = src;
- 
- 	if (s)
- 		while (*s)
- 			*d++ = *s++;
- 	*d++ = '\0';
- 
- 	return (void *)d;
- }
- 
- 
- /*
-  * ustrcmp
-  * Compare strings, ignoring case.
-  * Return 0 if strings are equal
-  */
- int ustrcmp (char *src, char *dst)
- {
- 	Boolean s;
- 	
- 	c2pstr(src);
- 	c2pstr(dst);
- 	s = EqualString(src, dst, false, false);
- 	p2cstr(src);
- 	p2cstr(dst);
- 	return (s)? 0 : 1;
- }
- 
- 
- /*
-  * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message.  It takes
-  * some user data "in" of "length" bytes and creates a packet in "out"
-  * consisting of the user data, a timestamp, and the sender's network
-  * address.
-  * The packet is encrypted by pcbc_encrypt(), using the given
-  * "key" and "schedule".
-  * The length of the resulting packet "out" is
-  * returned.
-  *
-  * It is similar to krb_mk_safe() except for the additional key
-  * schedule argument "schedule" and the fact that the data is encrypted
-  * rather than appended with a checksum.  Also, the protocol version
-  * number is "private_msg_ver", defined in krb_rd_priv.c, rather than
-  * KRB_PROT_VERSION, defined in "krb.h".
-  *
-  * The "out" packet consists of:
-  *
-  * Size			Variable		Field
-  * ----			--------		-----
-  *
-  * 1 byte		private_msg_ver		protocol version number
-  * 1 byte		AUTH_MSG_PRIVATE |	message type plus local
-  *			    HOST_BYTE_ORDER		byte order in low bit
-  *
-  * 4 bytes		c_length		length of encrypted data
-  *
-  * ===================== begin encrypt ================================
-  * 
-  * 4 bytes		length				length of user data
-  * length		in					user data
-  * 1 byte		msg_time_5ms		timestamp milliseconds
-  * 4 bytes		sender->sin.addr.s_addr	sender's IP address
-  *
-  * 4 bytes		msg_time_sec or		timestamp seconds with
-  *				-msg_time_sec		direction in sign bit
-  *
-  * 0<=n<=7  bytes	pad to 8 byte multiple	zeroes
-  *			(done by pcbc_encrypt())
-  *
-  * ======================= end encrypt ================================
-  */
- 
- /*
-  * unsigned char *in                   application data
-  * unsigned char *out                  put msg here, leave room for
-  *                                header! breaks if in and out
-  *                                (header stuff) overlap
-  * unsigned long length                length of in data
-  * Key_schedule schedule        precomputed key schedule
-  * C_Block key                  encryption key for seed and ivec
-  * struct tcprequest *			tcp request struct for send/rcvr addresses
-  */
- 
- long krb_mk_priv (unsigned char *in, unsigned char *out, unsigned long length, 
- 				  des_key_schedule schedule, C_Block key, 
- 				  struct tcprequest *tcprequest)
- {
-     register unsigned char *p, *q;
-     static unsigned  char *c_length_ptr;
- 	long msg_time_sec;
- 	unsigned char msg_time_5ms;
- 	unsigned long c_length;
- 	struct timeval tv;
- 	struct timezone tz;
- 
-     /*
-      * get the current time to use instead of a sequence #, since
-      * process lifetime may be shorter than the lifetime of a session
-      * key.
-      */
- 	
- 	gettimeofdaynet(&tv, &tz);
-     msg_time_sec = (long)tv.tv_sec;
-     msg_time_5ms = 1;
- 
-     p = out;
- 
-     *p++ = private_msg_ver;
-     *p++ = AUTH_MSG_PRIVATE | HOST_BYTE_ORDER;
- 
-     /* calculate cipher length */
-     c_length_ptr = p;
-     p += sizeof(c_length);
- 
-     /* start for encrypted stuff */
-     q = p;
- 
-     /* stuff input length */
-     bcopy((char *)&length, (char *)p, sizeof(length));
-     p += sizeof(length);
- 
-     /* make all the stuff contiguous for checksum and encryption */
-     bcopy((char *)in, (char *)p, (int)length);
-     p += length;
- 
-     /* stuff time 5ms */
-     bcopy((char *)&msg_time_5ms, (char *)p, sizeof(msg_time_5ms));
-     p += sizeof(msg_time_5ms);
- 
-     /* stuff source address */
-     bcopy((char *)&tcprequest->localHost, (char *)p, sizeof(tcprequest->localHost));
-     p += sizeof(tcprequest->localHost);
- 
-     /*
-      * direction bit is the sign bit of the timestamp.  Ok
-      * until 2038??
-      */
-     /* 
- 	 * For compatibility with broken old code, compares are done in VAX 
-      * byte order (LSBFIRST) 
- 	 */ 
-     if (lsb_net_ulong_less(tcprequest->localHost,	 /* src < recv */ 
- 			   tcprequest->remoteHost) == -1) 
-         msg_time_sec =  -msg_time_sec; 
-     else if (lsb_net_ulong_less(tcprequest->localHost, 
- 								tcprequest->remoteHost) == 0) 
-         if (lsb_net_ushort_less(tcprequest->localPort, tcprequest->remotePort) == -1) 
-             msg_time_sec = -msg_time_sec; 
-     /* stuff time sec */
-     bcopy((char *)&msg_time_sec, (char *)p, sizeof(msg_time_sec));
-     p += sizeof(msg_time_sec);
- 
-     /*
-      * All that for one tiny bit!  Heaven help those that talk to
-      * themselves.
-      */
- 
- #ifdef NOTDEF
-     /*
-      * calculate the checksum of the length, address, sequence, and
-      * inp data
-      */
-     cksum =  quad_cksum(q,NULL,p-q,0,key);
-     if (krb_debug)
-         printf("\ncksum = %u",cksum);
-     /* stuff checksum */
-     bcopy((char *) &cksum,(char *) p,sizeof(cksum));
-     p += sizeof(cksum);
- #endif
- 
-     /*
-      * All the data have been assembled, compute length and encrypt
-      * starting with the length, data, and timestamps use the key as
-      * an ivec.
-      */
- 
-     c_length = p - q;
-     c_length = ((c_length + sizeof(C_Block) -1)/sizeof(C_Block)) *
-         sizeof(C_Block);
- 
-     /* stuff the length */
-     bcopy((char *) &c_length, (char *)c_length_ptr, sizeof(c_length));
- 
- #ifdef notdef
- 	if (kerberos_debug_packet)
- 		khexout(q, p-q, "KRB:", "krb_mk_priv unencrypted ");
- #endif
- 
-     /* pcbc encrypt, pad as needed, use key as ivec */
-     des_pcbc_encrypt((des_cblock) q, (des_cblock) q, (long) (p-q), schedule,
-                  (des_cblock)key, 1); /* ENCRYPT */
- 
-     return (q - out + c_length);        /* resulting size */
- }
- 
- 
- /*
-  * krb_rd_priv() decrypts and checks the integrity of an
-  * AUTH_MSG_PRIVATE message.  Given the message received, "in",
-  * the length of that message, "in_length", the key "schedule"
-  * and "key" to decrypt with, and the network addresses of the
-  * "sender" and "receiver" of the message, krb_rd_safe() returns
-  * RD_AP_OK if the message is okay, otherwise some error code.
-  *
-  * The message data retrieved from "in" are returned in the structure
-  * "m_data".  The pointer to the decrypted application data
-  * (m_data->app_data) refers back to the appropriate place in "in".
-  *
-  * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
-  * message.  The structure containing the extracted message
-  * information, MSG_DAT, is defined in "krb.h".
-  */
- 
- /*
-  * unsigned char *in				pointer to the msg received
-  * unsigned long in_length;		length of "in" msg
-  * Key_schedule schedule;	precomputed key schedule
-  * C_Block key				encryption key for seed and ivec
-  * struct tcprequest *tcprequest;
-  * MSG_DAT *m_data			various input/output data from msg
-  */
- 
- /*
-  * NOTE: the original routine had sender and receiver where we only
-  * have tcprequest. So, we have to reverse the sense of the sender
-  * and receiver.
-  */
- #define sender remoteHost
- #define receiver localHost
- #define senderp remotePort
- #define receiverp localPort
- 
- long krb_rd_priv (unsigned char *in, unsigned long in_length, Key_schedule schedule,
- 				 C_Block key, struct tcprequest *tcprequest, 
- 				 MSG_DAT *m_data)
- {
-     register unsigned char *p, *q;
-     static unsigned long src_addr;	/* Can't send structs since no guarantees on size */
- 	int swap_bytes = 0;
- 	unsigned long c_length;
- 	long delta_t;
- 	struct timeval tv;
- 	struct timezone tz;
- 	
-     p = in;			/* beginning of message */
-     swap_bytes = 0;
- 
-     if (*p++ != KRB_PROT_VERSION && *(p-1) != 3)
-         return KRBE_FAIL;
- 
-     /* ...??? private_msg_ver = *(p-1); */
-     if (((*p) & ~1) != AUTH_MSG_PRIVATE)
-         return KRBE_FAIL;
- 
-     if ((*p++ & 1) != HOST_BYTE_ORDER)
-         swap_bytes++;
- 
-     /* get cipher length */
-     bcopy((char *)p, (char *)&c_length, sizeof(c_length));
-     if (swap_bytes)
-         c_length = swapl(c_length);
-     p += sizeof(c_length);
-     /* check for rational length so we don't go comatose */
-     if (VERSION_SZ + MSG_TYPE_SZ + c_length > in_length)
-         return KRBE_FAIL;
- 
-     /*
-      * decrypt to obtain length, timestamps, app_data, and checksum
-      * use the session key as an ivec
-      */
- 
-     q = p;			/* mark start of encrypted stuff */
- 
-     /* pcbc decrypt, use key as ivec */
-     des_pcbc_encrypt((des_cblock)q, (des_cblock)q, (long) c_length,
-                  schedule, (des_cblock)key, 0);	/* DECRYPT */
- 
-     /* safely get application data length */
-     bcopy((char *)p, (char *)&(m_data->app_length), sizeof(m_data->app_length));
-     if (swap_bytes)
-         m_data->app_length = swapl(m_data->app_length);
-     p += sizeof(m_data->app_length);    /* skip over */
- 
-     if (m_data->app_length + sizeof(c_length) + sizeof(in_length) +
-         sizeof(m_data->time_sec) + sizeof(m_data->time_5ms) +
-         sizeof(src_addr) + VERSION_SZ + MSG_TYPE_SZ
-         > in_length)
-         return KRBE_FAIL;
- 
-     /* we're now at the decrypted application data */
-     m_data->app_data = p;
- 
-     p += m_data->app_length;
- 
-     /* safely get time_5ms */
-     bcopy((char *) p, (char *)&(m_data->time_5ms),
- 	  sizeof(m_data->time_5ms));
-     /*  don't need to swap-- one byte for now */
-     p += sizeof(m_data->time_5ms);
- 
-     /* safely get src address */
-     bcopy((char *) p,(char *)&src_addr,sizeof(src_addr));
-     /* don't swap, net order always */
-     p += sizeof(src_addr);
- 
-     if (src_addr != (unsigned long) tcprequest->sender)
- 		return KRBE_FAIL;
- 
-     /* safely get time_sec */
-     bcopy((char *) p, (char *)&(m_data->time_sec), sizeof(m_data->time_sec));
-     if (swap_bytes) 
- 		m_data->time_sec = swapl(m_data->time_sec);
- 
-     p += sizeof(m_data->time_sec);
- 
-     /* 
- 	 * check direction bit is the sign bit.
-      * For compatibility with broken old code, compares are done in VAX 
- 	 * byte order (LSBFIRST) 
- 	 */ 
-     if (lsb_net_ulong_less(tcprequest->sender, tcprequest->receiver) == -1) 
- 		/* src < recv */ 
- 		m_data->time_sec =  - m_data->time_sec; 
-     else if (lsb_net_ulong_less(tcprequest->sender, 
- 								tcprequest->receiver) == 0) 
- 		if (lsb_net_ushort_less(tcprequest->senderp, tcprequest->receiverp) == -1)
- 			/* src < recv */
- 			m_data->time_sec =  - m_data->time_sec; 
-     /*
-      * all that for one tiny bit!
-      * Heaven help those that talk to themselves.
-      */
- 
-     /* check the time integrity of the msg */
- 
- 	gettimeofdaynet(&tv, &tz);
-     delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
-     if (delta_t > CLOCK_SKEW)
- 		return KRBE_SKEW;
- 
-     /*
-      * caller must check timestamps for proper order and
-      * replays, since server might have multiple clients
-      * each with its own timestamps and we don't assume
-      * tightly synchronized clocks.
-      */
- 
- #ifdef notdef
-     bcopy((char *) p,(char *)&cksum,sizeof(cksum));
-     if (swap_bytes) 
- 		cksum = swapl(cksum)
-     /*
-      * calculate the checksum of the length, sequence,
-      * and input data, on the sending byte order!!
-      */
-     calc_cksum = quad_cksum(q,NULL,p-q,0,key);
- 
-     if (krb_debug)
- 	printf("\ncalc_cksum = %u, received cksum = %u",
- 	       calc_cksum, cksum);
-     if (cksum != calc_cksum)
- 	return RD_AP_MODIFIED;
- #endif
- 
-     return 0;        /* OK == 0 */
- }
- 
- 
- /*
-  * lookupaddr
-  * Lookup address
-  * Return 0 if not found
-  */
- unsigned long lookupaddr (char *hostname)
- {
- 	int s;
- 	struct hostInfo *rtnStruct = 0;
- 	char done = 0;
- 	unsigned long addr;
- 
- 	if (!(rtnStruct = (struct hostInfo *) NewPtrClear(sizeof(struct hostInfo)))) {
- 		goto xit;
- 	}
- 
- 	s = StrToAddr(hostname, rtnStruct, dnsDone, (char *)&done);
- 	if (s && (s != cacheFault)) {
- 		goto xit;
- 	}	
- 
- 	/*
- 	 * wait for the result
- 	 * ... should timeout? (dnr probably does)
- 	 * ... should run minimal event loop
- 	 * ... should finish processing in netevent loop
- 	 */
- 	if (s) {
- 		while (!done)
- 			;
- 	}
- 	
- 	if (rtnStruct->rtnCode == noErr) {				/* if success */
- 		addr = rtnStruct->addr[0];
- 	} else {
- 		addr = 0;
- 	}
- 	
- xit:
- 	if (rtnStruct)
- 		DisposPtr((Ptr)rtnStruct);
- 	
- 	return addr;
- }
- 
- 
- /*
-  * dnsDone
-  * completion routine for dns
-  */
- pascal void dnsDone (struct hostInfo *info, char *userdata)
- {
- 	#pragma unused(info)
- 	*userdata = 1;
- }
- 
- 
- /*
-  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
-  * Should be at end of file.
-  * 
-  * Local Variables:
-  * tab-width: 4
-  * End:
-  */
--- 0 ----
Index: krb5/mac/kconfig/kadm.h
diff -c krb5/mac/kconfig/kadm.h:1.1.1.1 krb5/mac/kconfig/kadm.h:removed
*** krb5/mac/kconfig/kadm.h:1.1.1.1	Mon Jun  2 17:57:52 1997
--- krb5/mac/kconfig/kadm.h	Sun Mar 16 20:22:36 2003
***************
*** 1,130 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- #define			KRB_PROT_VERSION		4
- 
- #define ntohl(x) (x)
- #define ntohs(x) (x)
- #define htonl(x) (x)
- #define htons(x) (x)
- 
- typedef struct pak_ {
- 	int len;							/* data length */
- 	unsigned char *data;				/* pointer to data */
- 	/* data goes here */
- } paktype;
- 
- struct tcprequest {
- 	struct tcprequest *next;
- 	paktype *pak;
- 	char *tcpbuf;						/* buffer for mactcp */
- 	StreamPtr stream;					/* udp stream pointer */
- 	TCPiopb wpb;						/* pb for writes */
- 	TCPiopb rpb;						/* pb for reads */
- 	wdsEntry wds[3];					/* wds for writing */
- 	ip_addr remoteHost;					/* address of kerberos server */
- 	ip_addr localHost;
- 	unsigned short remotePort;			/* remote port */
- 	unsigned short localPort;			/* local port */
- 	int timeout;						/* timeout in seconds */
- 	int retries;						/* number of times to retry */
- 	short result;						/* request result */
- 	unsigned short xlen;				/* transmit length */
- 	unsigned char rbuf[750];			/* receive buffer */
- 	Boolean readheader;					/* true if reading 4 byte header */
- 	unsigned short header;				/* length header */
- };
- typedef struct tcprequest tcprequest;
- /*
-  * result values
-  */
- #define UR_TIMEOUT 1					/* request timed out */
- #define UR_READERROR 2					/* read error */
- #define UR_READDONE 3					/* read finished successfully */
- 
- /*
-  * Kadm constants
-  */
- #define CHANGE_PW		2
- #define KADM_VERSTR		"KADM0.0A"
- #define KADM_VERSIZE	strlen(KADM_VERSTR)
- #define KADM_ULOSE	"KYOULOSE"	/* sent back when server can't decrypt client's msg */
- 
- #define HOST_BYTE_ORDER (*(char *)&ONE)
- 
- /*
-  * Errors and associated text for get ticket routines.
-  * See krbe_text[].
-  */
- enum KRBE {
- 	KRBE_OK = 0,						/* no error */
- 	KRBE_FAIL,							/* General failure */
- 	KRBE_SKEW,							/* Clock Skew */
- 	KRBE_PROT,							/* Protocol Error */
- 	KRBE_PASS,							/* Invalid login or password */
- 	KRBE_TIMO,							/* Timeout */
- 	KRBE_MEM,							/* No memory */
- 	KRBE_N								/* must be last */
- };
- 
- /* Message types , always leave lsb for byte order */
- 
- #define			AUTH_MSG_KDC_REQUEST					 1<<1
- #define			AUTH_MSG_KDC_REPLY						 2<<1
- #define			AUTH_MSG_APPL_REQUEST					 3<<1
- #define			AUTH_MSG_APPL_REQUEST_MUTUAL			 4<<1
- #define			AUTH_MSG_ERR_REPLY						 5<<1
- #define			AUTH_MSG_PRIVATE						 6<<1
- #define			AUTH_MSG_SAFE							 7<<1
- #define			AUTH_MSG_APPL_ERR						 8<<1
- #define			AUTH_MSG_DIE							63<<1
- 
- 
- /* include space for '.' and '@' */
- #define			MAX_K_NAME_SZ	(ANAME_SZ + INST_SZ + REALM_SZ + 2)
- #define			KKEY_SZ			100
- #define			VERSION_SZ		1
- #define			MSG_TYPE_SZ		1
- #define			DATE_SZ			26		/* RTI date output */
- #define			MAX_KTXT_LEN	1250
- #define KRB_SENDAUTH_VLEN 8			/* length for version strings */
- #define K_FLAG_ORDER	0		/* bit 0 --> lsb */
- 
- /* 
-  * Maximum alloable clock skew in seconds 
-  */
- #define			CLOCK_SKEW		5*60
- 
- #define MSBFIRST					/* macintosh 68000 */
- 
- #ifdef LSBFIRST
- #define lsb_net_ulong_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
- #define lsb_net_ushort_less(x,y) ((x < y) ? -1 : ((x > y) ? 1 : 0))
- #else
- /* MSBFIRST */
- #define uchar_comp(x,y) \
-         (((x)>(y))?(1):(((x)==(y))?(0):(-1)))
- /* This is gross, but... */
- #define lsb_net_ulong_less(x, y) long_less_than((unsigned char *)&x, (unsigned char *)&y)
- #define lsb_net_ushort_less(x, y) short_less_than((unsigned char *)&x, (unsigned char *)&y)
- 
- #define long_less_than(x,y) \
-         (uchar_comp((x)[3],(y)[3])?uchar_comp((x)[3],(y)[3]): \
- 	 (uchar_comp((x)[2],(y)[2])?uchar_comp((x)[2],(y)[2]): \
- 	  (uchar_comp((x)[1],(y)[1])?uchar_comp((x)[1],(y)[1]): \
- 	   (uchar_comp((x)[0],(y)[0])))))
- #define short_less_than(x,y) \
- 	  (uchar_comp((x)[1],(y)[1])?uchar_comp((x)[1],(y)[1]): \
- 	   (uchar_comp((x)[0],(y)[0])))
- 
- #endif /* LSBFIRST */
--- 0 ----
Index: krb5/mac/kconfig/kadm.proto.h
diff -c krb5/mac/kconfig/kadm.proto.h:1.1.1.1 krb5/mac/kconfig/kadm.proto.h:removed
*** krb5/mac/kconfig/kadm.proto.h:1.1.1.1	Mon Jun  2 17:57:52 1997
--- krb5/mac/kconfig/kadm.proto.h	Sun Mar 16 20:22:36 2003
***************
*** 1,22 ****
- /*
-  * kadm.c
-  */
- extern int kerberos_changepw(char *name, char *password, char *new, char **reason);
- extern int kadm_cli_send(unsigned char *st_dat, int st_siz, char *uname, char *uinstance, char *urealm);
- extern paktype *krb_ask_tcp(paktype *pak, char *realm, tcprequest *tcprequest);
- extern void krb_parse_principal(char *user, char *uname, char *uinst, char *urealm);
- extern int krb_build_ap(char *cp, CREDENTIALS *cr, char *srealm, long checksum);
- extern Boolean tcp_open(tcprequest *tcprequest);
- extern void tcp_close(tcprequest *tcprequest);
- extern Boolean tcp_transmit(tcprequest *tcprequest);
- extern Boolean tcp_startread(tcprequest *tcprequest);
- extern void tcp_readdone(void);
- extern void tcp_freerequest(tcprequest *request);
- extern paktype *newpaktype(int len);
- extern void disposepak(paktype *pak);
- extern void *stringcopy(void *dst, void *src);
- extern int ustrcmp(char *src, char *dst);
- extern long krb_mk_priv(unsigned char *in, unsigned char *out, unsigned long length, des_key_schedule schedule, C_Block key, struct tcprequest *tcprequest);
- extern long krb_rd_priv(unsigned char *in, unsigned long in_length, Key_schedule schedule, C_Block key, struct tcprequest *tcprequest, MSG_DAT *m_data);
- extern unsigned long lookupaddr(char *hostname);
- extern pascal void dnsDone(struct hostInfo *info, char *userdata);
--- 0 ----
Index: krb5/mac/kconfig/kconfig.c
diff -c krb5/mac/kconfig/kconfig.c:1.1.1.1 krb5/mac/kconfig/kconfig.c:removed
*** krb5/mac/kconfig/kconfig.c:1.1.1.1	Mon Jun  2 17:57:52 1997
--- krb5/mac/kconfig/kconfig.c	Sun Mar 16 20:22:36 2003
***************
*** 1,3594 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- /*
-  * Kconfig
-  */
- #include <stdio.h>
- #ifndef __MWERKS__
- #include <Controls.h>
- #include <Desk.h>
- #include <DiskInit.h>
- #include <Devices.h>
- #include <Dialogs.h>
- #include <Errors.h>
- #include <Events.h>
- #include <Folders.h>
- #include <Fonts.h>
- #include <GestaltEqu.h>
- #include <Lists.h>
- #include <Memory.h>
- #include <Menus.h>
- #include <Notification.h>
- #include <OSEvents.h>
- #include <OSUtils.h>
- #include <Packages.h>
- #include <Printing.h>
- #include <QuickDraw.h>
- #include <Resources.h>
- #include <Scrap.h>
- #include <Script.h>
- #include <StdArg.h>
- #include <StdLib.h>
- #include <String.h>
- #include <Strings.h>
- #include <SysEqu.h>
- #include <TextEdit.h>
- #include <ToolUtils.h>
- #include <Traps.h>
- #include <Windows.h>
- #include <StdLib.h>
- 
- #define TRUE 1
- #define FALSE 0
- #endif
- 
- #define CELLH 12						/* list cell height */
- 
- #ifdef KRB4
- #	define	DEFINE_SOCKADDR
- #	include "krb.h"
- #	include "kconfig.h"
- #	include "kconfig.proto.h"
- #	include "krb_driver.h"
- #	include "kconfig.vers"
- #	include "glue.h"
- #endif
- 
- #ifdef KRB5
- #	include "k5-int.h"
- #	include "com_err.h"
- #	include "kconfig.h"
- #	include "kconfig.proto.h"
- #	include "kconfig.vers"
- #	include "prof_int.h"
- #	include "adm_proto.h"
- #endif
- 
- #include "WindowUtil.h"
- 
- #define num_WaitNextEvent	0x60
- #define num_JugglDispatch	0x8F	/* The Temp Memory calls (RWR) */
- #define num_UnknownTrap		0x9F
- #define num_ScriptTrap		0xBF
- #define switchEvt	 1 /* Switching event (suspend/resume )	 for app4evt */
- 
- //#define dangerousPattern 1
- #define KFAILURE 255
- #define KSUCCESS 0
- 
- 
- 	//  IH 05.03.96: PPC Port, must use UPPs instead of Procedure Ptrs
- static DeviceLoopDrawingUPP	gpictdrawprocUPP = NULL;
- static ModalFilterUPP 		gklistFilterUPP = NULL;
- static ModalFilterUPP		gokFilterUPP = NULL;
- static ModalFilterUPP		ginternalBufferFilterUPP = NULL;
- static UserItemUPP			gdooutlineUPP = NULL;
- static UserItemUPP			gdopictUPP = NULL;
- static UserItemUPP			gdrawRealmUPP = NULL;
- static UserItemUPP			gdolistUPP = NULL;
- 
- 
- /*
-  * Globals
-  */
- #ifdef KRB4
- 	krbHiParmBlock khipb;
- 	krbParmBlock klopb;
- 	/* We use the mac stubs to open the driver. */
- #	define	kdriver	mac_stubs_kdriver		/* .Kerberos driver reference */
- #endif
- 
- #ifdef KRB5
- 	krb5_context kcontext;
- 	krb5_ccache k5_ccache;
-     static char ccname[FILENAME_MAX] = "ccredcache";           /* ccache file location */
- #endif
- 
- MenuHandle menus[NUM_MENUS];
- DialogPtr maind = 0;					/* main dialog window */
- Rect oldzoom;
- ParamBlockRec pb;
- queuetype domainQ = 0;
- queuetype serverQ = 0;
- queuetype credentialsQ = 0;
- ListHandle dlist;						/* domain list */
- ListHandle slist;						/* server list */
- struct listfilter lf;					/* lf for maind */
- Handle ddeleteHandle, deditHandle;
- Handle sdeleteHandle, seditHandle;
- preferences prefs;						/* preferences */
- 
- #ifdef KRB4
- char *prefsFilename = "\pCNS Config Preferences";
- #endif
- 
- #ifdef KRB5
- char *prefsFilename = "\pCNSk5 Config Preferences";
- #define kUNKNOWNUSERNAME "Unknown"
- char gUserName[255];					/* last user name */
- char gRealmName[255];					/* last realm name */
- #endif
- 
- /*+
-  * Function: Initializes ccache and catches illegal caches such as
-  *  bad format or no permissions.
-  *
-  * Parameters:
-  *  ccache - credential cache structure to use
-  *
-  * Returns: krb5_error_code
-  */
- static krb5_error_code
- k5_init_ccache (krb5_ccache *ccache) {
-     krb5_error_code code;
-     krb5_principal princ;
-     FILE *fp;
- 
-     code = krb5_cc_default (kcontext, ccache); // Initialize the ccache
-     if (code)
-         return code;
- 
-     code = krb5_cc_get_principal (kcontext, *ccache, &princ);
-     if (code == KRB5_FCC_NOFILE) {              // Doesn't exist yet
-         fp = fopen (krb5_cc_get_name(kcontext, *ccache), "w");
-         if (fp == NULL)                         // Can't open it
-             return KRB5_FCC_PERM;
-         fclose (fp);
-     }
- 
-     if (code) {                                 // Bad, delete and try again
-         remove (krb5_cc_get_name(kcontext, *ccache));
-         code = krb5_cc_get_principal (kcontext, *ccache, &princ);
-         if (code == KRB5_FCC_NOFILE)            // Doesn't exist yet
-             return 0;
-         if (code)
-             return code;
-     }
- 
-     krb5_free_principal (kcontext, princ);
-     return 0;
- }
- 
- int main (void)
- {
- 	int i, s;
- 	MenuHandle menuhandle;
- 
- 	/*	
- 	 * Setup
- 	 */
- 	InitGraf (&qd.thePort); /* Init the graf port */
- 	InitFonts();
- 	InitWindows();
- 	InitMenus();
- 	TEInit();
- 	InitDialogs(0);
- 	InitCursor();
- 	FlushEvents(everyEvent, 0);
- #ifdef KRB4
- 	init_cornell_des();
- #endif
- #ifdef KRB5
- 	k5_init_ccache (&k5_ccache);
- 	strcpy(gUserName, kUNKNOWNUSERNAME);
- #endif
- 	
- 		//  IH 05.03.95: Create the UPPs for ToolBox callback routines
- 	gpictdrawprocUPP = NewDeviceLoopDrawingProc(pictdrawproc);
- 	if (gpictdrawprocUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gklistFilterUPP = NewModalFilterProc(klistFilter);
- 	if (gklistFilterUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gokFilterUPP = NewModalFilterProc(okFilter);
- 	if (gokFilterUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	ginternalBufferFilterUPP = NewModalFilterProc(internalBufferFilter);
- 	if (ginternalBufferFilterUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gdooutlineUPP = NewUserItemProc(dooutline);	
- 	if (gdooutlineUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gdopictUPP = NewUserItemProc(dopict);	
- 	if (gdopictUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gdrawRealmUPP = NewUserItemProc(drawRealm);	
- 	if (gdrawRealmUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 	gdolistUPP = NewUserItemProc(dolist);	
- 	if (gdolistUPP == NULL)
- 		doalert("Error creating a Universal Proc Pointer");
- 
- 	readprefs();
- 	
- 	/*
- 	 *	Setup the menus.  Assumes the menu resources start at 128 and are
- 	 *	contiguous.
- 	 */
- 	for (i = 0; i < NUM_MENUS; i++) {
- 		menuhandle = GetMenu(i + MENU_OFFSET);
- 		if (menuhandle == 0) 
- 			break;
- 
- 		if (i < MENU_SUBMENUS)			/* if not a submenu */
- 			InsertMenu(menuhandle, 0);
- 		else
- 			InsertMenu(menuhandle, -1);
- 		menus[i] = menuhandle;
- 	}
- 	AddResMenu (menus[APPL_MENU], 'DRVR');
- 	DrawMenuBar();
- 
- #ifdef KRB4
- 	s = krb_start_session((char *)0);
- 	if (s != KSUCCESS) {
- 		doalert("Kerberos driver is not installed");
- 		getout(0);
- 	}
- #endif
- 
- #ifdef KRB5
-     krb5_init_context(&kcontext);
-     if (kcontext->profile == 0)
-     {
-     	doalert("Kerberos configuration file not present");
-     	getout(0);
-     }
-     krb5_init_ets(kcontext);
- #endif
- 
- 	/*
- 	 * build the main window
- 	 */
- 	bzero(&oldzoom, sizeof(oldzoom));
- #ifdef KRB4
- 	getRealmMaps();
- 	getServerMaps();
- #endif
- #ifdef KRB5
- 	getServerMaps();	/* Get Servers first */
- 	getRealmMaps();		/* Need servers to get realms */
- #endif
- 
- 	buildmain();
- 
- 	/*
- 	 * Run the main event loop.
- 	 */
- 	mainEvent();
- }
- 
- 
- /*
-  * mainEvent
-  * The main event loop.
-  */
- void mainEvent ()
- {
- 	int s, state;
- 	int aborted;
- 	int in_background;
- 	int running = TRUE;
- 	unsigned long curtime;
- 	short item;
- 	EventRecord event;
- 	DialogPtr mydlg;
- 	Point cell;
- 	
- 	while (running) {
- 		WaitNextEvent (everyEvent, &event, 30, NULL);
- 		
- 		/*
- 		 * Update display items.
- 		 */
- 		updatedisplay();
- 
- 		/*
- 		 * Set the state of the edit and delete buttons depending on if any
- 		 * cells are selected or not.
- 		 */
- 		SetPt(&cell, 0, 0);
- 		if (LGetSelect(true, &cell, dlist))
- 			state = 0;
- 		else
- 			state = 255;					/* disable */
- 		HiliteControl((ControlHandle) ddeleteHandle, state);
- 		HiliteControl((ControlHandle) deditHandle, state);
- 
- 		SetPt(&cell, 0, 0);
- 		if (LGetSelect(true, &cell, slist))
- 			state = 0;
- 		else
- 			state = 255;					/* disable */
- 		HiliteControl((ControlHandle) sdeleteHandle, state);
- 		HiliteControl((ControlHandle) seditHandle, state);
- 
- 		/*
- 		 * First handle some events we want to see before the
- 		 * Dialog Manager sees them. If we continue, we will
- 		 * bypass letting the Dialog Manager look at the
- 		 * events.
- 		 */
- 		switch (event.what) {
- 		case mouseDown:
- 			if (HandleMouseDown(&event))
- 				continue;
- 			break;
- 
- 		case keyDown:
- 			if ((event.modifiers & cmdKey) && 
- 				((event.message & 0x7f) == '.')) {
- 				aborted = TRUE;
- 				SysBeep(20);
- 				continue;
- 			} else if (event.modifiers & cmdKey) {
- 				HandleMenu(MenuKey(event.message&charCodeMask), 
- 						   event.modifiers);
- 				continue;
- 			}
- 			break;
- 
- 		case app4Evt:					/* really a suspend/resume event */
- 			switch ((event.message>>24) & 0xff) {
- 			case switchEvt:
- 				/* Treat switch events as activate events too */
- 				if (event.message & 0x01) { /* Resume Event */
- 					in_background = FALSE;
- 					doactivate(FrontWindow(), activeFlag);
- 					break;
- 				} else {				/* Suspend Event */
- 					in_background = TRUE;
- 					doactivate(FrontWindow(), 0);
- 					break;
- 				}
- 			}
- 			break;
- 
- 		case updateEvt:
- 			if (doupdate((WindowPtr) event.message)) /* handle updates */
- 				continue;
- 			break;
- 
- 		case activateEvt:				/* (de)active a window */
- 			if (doactivate((WindowPtr) event.message, event.modifiers))
- 				continue;
- 			break;
- 
- 		case diskEvt:					/* disk inserted */
- 			if (((event.message >> 16) & 0xFFFF) != noErr) {
- 				DILoad();
- 				DIBadMount(event.where, event.message);
- 				DIUnload();
- 				continue;
- 			}
- 			break;
- 		} /* switch */
- 
- 		/*
- 		 * Let the Dialog Manager have a crack at it.
- 		 */
- 		if (IsDialogEvent (&event))
- 			if (DialogSelect (&event, &mydlg, &item))
- 				if (mydlg == maind)
- 					mainhit(&event, mydlg, item);
- 	}									/* while */
- 	
- 	getout(0);
- }
- 
- 
- int HandleMouseDown (event)
- 	EventRecord *event;
- {
- 	struct cmdw *cmdw;
- 	WindowPtr window;
- 
- 	int windowCode = FindWindow (event->where, &window);
- 	
- 	switch (windowCode) {
- 	
- 	case inSysWindow: 
- 		SystemClick (event, window);
- 		return TRUE;
- 		
- 	case inMenuBar:
- 		HandleMenu(MenuSelect(event->where), event->modifiers);
- 		return TRUE;
- 		
- 	case inContent:
- 		if (window != FrontWindow ()) {
- 			if (window == (WindowPtr)maind) {
- 				SelectWindow(window);
- 				return TRUE;
- 			}
- 		} else if (window == (WindowPtr)maind) {
- #ifdef notdef
- 			(void) listevents(maind, event);
- 			return TRUE;
- #endif
- 		}
- 		break;
- 
- 	case inDrag:						/* Wanna drag? */
- 		SelectWindow(window);
- 		DragWindow (window, event->where, &qd.screenBits.bounds);
- 		writeprefs();
- 		return TRUE;
- 
- 	case inGoAway:
- 		if (window == (WindowPtr)maind)
- 			if (TrackGoAway (window, event->where))
- 				getout(0);
- 		break;
- 
- #ifdef notdef
- 	case inGrow:
- 		if (window != FrontWindow()) {
- 			SelectWindow(window);
- 			return TRUE;
- 		} else {
- 			if (window == (WindowPtr)maind) {
- 				dogrow(window, event->where);
- 				return TRUE;
- 			}
- 		}
- 		break;
- #endif
- 		
- 	case inZoomOut:
- 		if (window == (WindowPtr)maind) {
- 		}
- 		break;
- 		
- 	} /* switch */
- 
- 	return FALSE;
- }
- 
- 
- /*
-  * HandleMenu - handle menu events.
-  */
- HandleMenu (long which, short modifiers)
- {
- 	int id;								/* menu id */
- 	int item;							/* menu item */
- 	int s;
- 	short num;
- 	WindowPtr window;
- 	struct cmdw *cmdw;
- 	char fname[256];
- 	Point pt;
- 	SFReply reply;
- 	
- 	item = which & 0xFFFF;
- 	id = which >> 16;
- 	
- 	switch (id - MENU_OFFSET) {
- 	case APPL_MENU:						/* Mac system menu item */
- 		handapple(item);
- 		break;
- 
- 	case FILE_MENU:						/* File menu */
- 		switch (item) {
- 		case LOGIN_FILE:
- 			doLogin();
- 			break;
- 		
- 		case LOGOUT_FILE:
- 			doLogout();
- 			break;
- 		
- 		case PASSWORD_FILE:
- 			kpass_dialog();
- 			break;
- 
- 		case LIST_FILE:
- 			klist_dialog();
- 			break;
- 
- 		case QUIT_FILE:					/* Quit */
- 		case CLOSE_FILE:				/* Close Window */
- 			getout(0);
- 		}
- 		break;
- 
- 	case EDIT_MENU:
- 		window = FrontWindow();
- 	
- 		switch(item) {
- 		case UNDO_EDIT:					/* undo */
- 			SysBeep(3);
- 			break;
- 
- 		case CUT_EDIT:					/* cut */
- 			break;
- 
- 		case COPY_EDIT:					/* copy */
- 			break;
- 
- 		case PASTE_EDIT:				/* paste */
- 			break;
- 
- 		case CLEAR_EDIT:				/* clear */
- 			break;
- 		}
- 		break;
- 
- 	}
- 
- 	HiliteMenu(0);
- }
- 
- 	
- /*
-  * doupdate
-  */
- int doupdate (WindowPtr window)
- {
- #ifdef notdef
- 	GrafPtr savePort;
- 
- 	GetPort (&savePort);
- 	SetPort (window);
- 
- 	if (window == (WindowPtr)maind) {
- 		BeginUpdate (window);
- 
- 		DrawGrowIcon(window);
- 
- 		EndUpdate(window);
- 		return FALSE;
- 	}
- 
- 	SetPort(savePort);
- #endif
- 	return FALSE;
- }
- 
- 
- /*
-  * doactivate
-  */
- int doactivate (WindowPtr window, int mod)
- {
- 	GrafPtr savePort;
- 	struct cmdw *cmdw;
- 	
- 	if (!window)
- 		return FALSE;
- 
- 	GetPort (&savePort);
- 	SetPort (window);
- 
- 	HiliteWindow (window, ((mod & activeFlag) != 0));
- 	
- #ifdef notdef
- 	if (window == (WindowPtr)maind)
- 		DrawGrowIcon(window);
- #endif
- 
- 	SetPort (savePort);
- 	return FALSE;
- }
- 
- 
- #ifdef notdef
- /*
-  * dogrow
-  */
- void dogrow (WindowPtr window, Point p)
- {
-     long gr;
-     int height;
-     int width;
-     Rect growRect;
-     GrafPtr savePort;
- 
-     growRect = qd.screenBits.bounds;
-     growRect.top = 50;					/* minimal horizontal size */
-     growRect.left = 50;					/* minimal vertical size */
- 
-     gr = GrowWindow(window, p, &growRect);
- 
-     if (gr == 0)
- 		return;
-     height = HiWord (gr);
-     width = LoWord (gr);
- 
-     SizeWindow (window, width, height, FALSE); /* resize the window */
- 
-     GetPort (&savePort);
-     SetPort (window);
- 	/* setsizes(false); */
-     InvalRect(&window->portRect);		/* invalidate whole window rectangle */
-     EraseRect(&window->portRect);
-     SetPort (savePort);
- }
- #endif
- 
- 
- /* 
-  * handapple - Handle the apple menu, either running a desk accessory
-  *			   or calling a routine to display information about our
-  *			   program.	 Use the practice of
-  *			   checking for available memory, and saving the GrafPort
-  *			   described in the DA Manager's Guide.
-  */
- handapple (accitem)
- 	int accitem;
- {
- 	GrafPtr savePort;					/* Where to save current port */
- 	Handle acchdl;						/* holds ptr to accessory resource */
- 	Str255 accname;						/* string holds accessory name */
- 	long accsize;						/* holds size of the acc + stack */
- 
- 	if (accitem == 1) {
- 		about ();
- 		return;
- 	}
- 	GetItem (menus[APPL_MENU], accitem, accname); /* get the pascal name */
- 	SetResLoad (FALSE);					/* don't load into memory */
- 
- 	/* figure out acc size + heap */
- 	accsize = SizeResource (GetNamedResource ((ResType) 'DRVR', accname));
- 	acchdl = NewHandle (accsize);		/* try for a block this size */
- 	SetResLoad (TRUE);					/* reset flag for rsrc mgr */
- 	if (!acchdl) {						/* if not able to get a chunk */
- 		SysBeep(3);
- 		return;
- 	}
- 	DisposHandle (acchdl);				/* get rid of this handle */
- 	GetPort (&savePort);				/* save the current port */
- 	OpenDeskAcc (accname);				/* run desk accessory */
- 	SetPort (savePort);					/* and put back our port */
- }
- 
- 
- #define DTH 14							/* dialog text height */
- void about ()
- {
- 	int ok;
- 	GrafPtr savePort;
- 	DialogPtr dialog;
- 	short item;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 
- 	GetPort(&savePort);
- 
- 	PositionTemplate((Rect *)0, 'DLOG', DLOG_ABOUT, 50, 50);
- 	dialog = GetNewDialog(DLOG_ABOUT, (Ptr)0, (WindowPtr)-1);
- 	SetPort((GrafPtr)dialog);
- 
- 	/*
- 	 * Set the draw procedure for the user items.
- 	 */
- 	GetDItem(dialog, ABOUT_OUT, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, ABOUT_OUT, itemType, (Handle)gdooutlineUPP, &itemRect);
- 	GetDItem(dialog, ABOUT_PICT, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, ABOUT_PICT, itemType, (Handle)gdopictUPP, &itemRect);
- 
- 	ok = 0;
- 	do {
- 		/* 
- 		 * process hits in the dialog.
- 		 */
- 		ModalDialog(0, &item);
- 				
- 		switch(item) {
- 		case ABOUT_OK:
- 			ok = 1;
- 			break;
- 		} /* switch */
- 	} while (ok == 0);
- 
- 	DisposDialog(dialog);
- 	SetPort(savePort);
- }
- 
- 
- pascal void pictdrawproc (short depth, short flags, GDHandle device, DialogPtr dialog)
- {
- 	#pragma unused (device, flags)
- 	
- 	if (depth < 8)
- 		drawpict(dialog, PICT_ABOUT_BW);
- 	else
- 		drawpict(dialog, PICT_ABOUT_C);
- }
- 
- 
- void drawpict (DialogPtr dialog, int id)
- {
- 	Handle h;
- 	Rect rect;
-     short itemType;
-     Handle itemHandle;
-     Rect itemRect;
- 	GrafPtr savePort;
- 
- 	GetPort(&savePort);
- 	SetPort(dialog);
- 
- 	GetDItem(dialog, ABOUT_PICT, &itemType, &itemHandle, &itemRect);
- 	if (h = Get1Resource('PICT', id)) {
- 		LoadResource(h);
- 		if (!ResError()) {
- 			HLock(h);
- 
- 			bcopy(((char *)*h)+2, &rect, sizeof(Rect));
- 			AlignRect(&itemRect, &rect, 50, 50);
- 			DrawPicture((PicHandle)h, &rect);
- 			HUnlock(h);
- 		}
- 	}
- 	SetPort(savePort);
- }
- 
- 
- /*
-  * this routine will be called by the Dialog Manager to draw the pict
-  */
- pascal void dopict (DialogPtr dialog, short itemNo)
- {
- 	long qdv;
- 	
- 	if (!trapAvailable(_DeviceLoop) || Gestalt('qd  ', &qdv) || ((qdv&0xff) == 0)) { /* if old mac */
- 		drawpict(dialog, PICT_ABOUT_BW);
- 	} else {
- 			//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 		DeviceLoop(dialog->visRgn, gpictdrawprocUPP, 
- 				   (long)dialog, 0);
- 	}
- }
- 
- 
- /*
-  * this routine will be called by the Dialog Manager to draw the outline of the
-  * default button.
-  */
- pascal void dooutline (DialogPtr dialog, short itemNo)
- {
- 	short		itemType;
- 	Handle		itemHandle;
- 	Rect		itemRect;
- 	
- 	GetDItem(dialog, itemNo, &itemType, &itemHandle, &itemRect);
- 	/* 
- 	 * outline the default button (see IM I-407).  in this case it 
- 	 * is the OK button. this lets the user know that pressing 
- 	 * the return will have the same effect as clicking this button.
- 	 */
- 	PenSize(3, 3);
- 	InsetRect(&itemRect, -4, -4);
- 	FrameRoundRect(&itemRect, 16, 16);
- 	PenSize(1, 1);
- }
- 
- 
- /*
-  * ------------------ routines ------------------
-  */
- 
- 
- /*
-  * updatedisplay
-  * Update the main display window.
-  */
- void updatedisplay ()
- {
- 	int s, savemode;
- 	Str255 scratch;
- 	static Str255 oldrealm = "", olduser = "";
- 	GrafPtr savePort;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 	Point pt;
- 		
- 	if (!maind)
- 		return;
- 		
- 	GetPort(&savePort);
- 	SetPort(maind);
- 	
- 	/*
- 	 * Display the local realm
- 	 */
- #ifdef KRB4
- 	klopb.uRealm = scratch;
- 	if (s = lowcall(cKrbGetLocalRealm))
- 		strcpy(scratch, "None");
- #endif
- #ifdef KRB5
- {
- char *ptr;
- 	if (krb5_get_default_realm(kcontext, &ptr) == 0)
- 	{
- 		strcpy(scratch, ptr);
- 		free(ptr);
- 	}
- 	else
- 		strcpy(scratch, "None");
- }
- #endif
- 
- 	if (strcmp(scratch, oldrealm)) {
- 		GetDItem(maind, MAIN_REALM, &itemType, &itemHandle, &itemRect);
- 		savemode = maind->txMode;
- 		MoveTo(itemRect.left+4, itemRect.bottom-4);
- 		strcpy(oldrealm, scratch);
- 		c2pstr(scratch);
- 		TextMode(srcCopy);
- 		DrawString(scratch);
- 		GetPen(&pt);
- 		itemRect.right -= 17;	/* room for triangle */
- 		itemRect.left = pt.h;
- 		InsetRect(&itemRect, 1, 1);
- 		EraseRect(&itemRect);	/* erase remainder of space in rect */
- 		TextMode(savemode);
- 	}
- 	
- 	/*
- 	 * Display the local user
- 	 */
- #ifdef KRB4
- 	bzero(&khipb, sizeof(krbHiParmBlock));
- 	khipb.user = scratch;
- 	if (s = hicall(cKrbGetUserName))
- 		strcpy(scratch, "None");
- #endif
- #ifdef KRB5
- 	if (strcmp(gUserName, kUNKNOWNUSERNAME))
- 	{
- 		strcpy(scratch, gUserName);
- 		strcat(scratch, "@");
- 		strcat(scratch, gRealmName);
- 	}
- 	else
- 		strcpy(scratch, kUNKNOWNUSERNAME);
- #endif
- 	if (strcmp(scratch, olduser)) {
- 		strcpy(olduser, scratch);
- 		c2pstr(scratch);
- 		setText(maind, MAIN_USER, scratch);
- 	}
- 	SetPort(savePort);
- }
- 
- 
- void setText (DialogPtr dialog, int item, char *text)
- {
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 
- 	GetDItem(dialog, item, &itemType, &itemHandle, &itemRect);
- 	SetIText(itemHandle, text);
- }
- 
- 
- /*
-  * buildmain
-  * Build the main window.
-  */
- void buildmain ()
- {
- 	int h;
- 	int n, cellw;
- 	int ndomains, nservers;
- 	int listwidth;
- 	short itemNo;				/* the item in the dialog selected */
- 	short itemType;				/* dummy parameter for call to GetDItem */
- 	Handle itemHandle;			/* dummy parameter for call to GetDItem */
- 	Rect itemRect;				/* the location of the list in the dialog */
- 	Rect dataBounds;			/* the dimensions of the data in the list */
- 	Point cellSize;				/* width and height of a cells rectangle */
- 	Point cell;					/* an index through the list */
- 	char string[255];
- 	short length;
- 	short checked;				/* flag for check box value */
- 	short bit;					/* used as a mask to test selection flags */ 
- 	struct user *user, *save, *tmp;
- 	char *cp;
- 	GrafPtr savePort;
-     Handle wh;					/* window handle */
-     Rect *rectp;
- 	DialogPtr dialog;
- 	Rect dRect, sRect;
- 	domaintype *dp;
- 	servertype *sp;
- 	
-     /*
-      * Get the dialog resource and modify the location.
-      * Since it will already be in memory, GetNewDialog will use
-      * the values we just set.
- 	 * ??? WE SHOULD MAKE SURE THE WINDOW IS ON THE SCREEN ???
-      */
- 	if (prefs.wrect.top != prefs.wrect.bottom) {
- 		if (wh = GetResource('DLOG', DLOG_MAIN)) {
- 			rectp = (Rect *)*wh;
- 			bcopy(&prefs.wrect, rectp, sizeof(Rect));
- 			PositionRectOnScreen(rectp, false);
- /*			PositionRect(rectp, rectp, 50, 50);			/* make sure on screen */
- 		}
- 	}
- 	maind = dialog = GetNewDialog(DLOG_MAIN, (Ptr)0, (WindowPtr) -1);
- 	if (!maind) {
- 		doalert("DLOG %d missing", DLOG_MAIN);
- 		getout(0);
- 	}
- 	GetPort(&savePort);
- 	SetPort((GrafPtr)maind);
- 
- 	/* 
- 	 * allow the dialog manager routines to access various things
- 	 */
- 	((DialogPeek)dialog)->window.refCon = (long)&lf;
- 		
- 	/* 
- 	 * set the procedure pointer for the user items in the dialog.
- 	 * this will allow he default button to be outlined and the list 
- 	 * to be drawn by the Dialog Manger.
-      * Also, set the correct list heights.
- 	 */
- 	GetDItem(dialog, MAIN_REALM, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, MAIN_REALM, itemType, (Handle)gdrawRealmUPP, &itemRect);
- 	
- 	GetDItem(dialog, MAIN_DMAP, &itemType, &itemHandle, &dRect);
- 	h = (((dRect.bottom - dRect.top) / CELLH) * CELLH);
- 	dRect.bottom = dRect.top + h;
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, MAIN_DMAP, itemType, (Handle) gdolistUPP, &dRect);
- 
- 	GetDItem(dialog, MAIN_SERVERS, &itemType, &itemHandle, &sRect);
- 	h = (((sRect.bottom - sRect.top) / CELLH) * CELLH);
- 	sRect.bottom = sRect.top + h;
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, MAIN_SERVERS, itemType, (Handle) gdolistUPP, &sRect);
- 
- 	GetDItem(dialog, MAIN_DDELETE, &itemType, &ddeleteHandle, &itemRect);
- 	GetDItem(dialog, MAIN_SDELETE, &itemType, &sdeleteHandle, &itemRect);
- 	GetDItem(dialog, MAIN_DEDIT, &itemType, &deditHandle, &itemRect);
- 	GetDItem(dialog, MAIN_SEDIT, &itemType, &seditHandle, &itemRect);
- 
- 	listwidth = dRect.right - dRect.left;
- 
- 	/* 
- 	 * make room for scroll bars (see IM IV-270)
- 	 */
- 	dRect.right -= 15;
- 	sRect.right -= 15;	
- 
- 	/* 
- 	 * create domain list
- 	 */
- 	ndomains = 0;								/* count items */
- 	for (dp = (domaintype *)domainQ; dp; dp = dp->next)
- 		ndomains++;
- 	SetRect(&dataBounds, 0, 0, 1, ndomains);
- 	SetPt(&cellSize, dRect.right-dRect.left, CELLH);
- 	dlist = LNew(&dRect, &dataBounds, cellSize, 128,
- 				(WindowPtr) dialog, false, false, false, true);
- 
- 	/* 
- 	 * use the default selection flags
- 	 */
- 	(*dlist)->selFlags = 0;
- 
- 	/*
- 	 * Initialize the cells in the list.
- 	 */
- 	dp = (domaintype *)domainQ;
- 	cell.h = cell.v = 0;
- 	while (dp) {
- 		setdcellstring(string, dp);
- 		LSetCell(string, strlen(string), cell, dlist);
- 		cell.v++;
- 		dp = dp->next;
- 	}
- 
- 	/* 
- 	 * create servers list
- 	 */
- 	nservers = 0;								/* count items */
- 	for (sp = (servertype *)serverQ; sp; sp = sp->next)
- 		nservers++;
- 	SetRect(&dataBounds, 0, 0, 1, nservers);
- 	SetPt(&cellSize, sRect.right-sRect.left, CELLH);
- 	slist = LNew(&sRect, &dataBounds, cellSize, 128, 
- 				(WindowPtr) dialog, false, false, false, true);
- 
- 	/* 
- 	 * use the default selection flags
- 	 */
- 	(*slist)->selFlags = 0;
- 
- 	/*
- 	 * Initialize the cells in the list.
- 	 */
- 	sp = (servertype *)serverQ;
- 	cell.h = cell.v = 0;
- 	while (sp) {
- 		setscellstring(string, sp);
- 		LSetCell(string, strlen(string), cell, slist);
- 		cell.v++;
- 		sp = sp->next;
- 	}
- 
- 	lf.nlists = 2;
- 	lf.list[0] = dlist;
- 	lf.list[1] = slist;
- 	lf.listitem[0] = MAIN_DMAP;
- 	lf.listitem[1] = MAIN_SERVERS;
- 	lf.edititem[0] = MAIN_DEDIT;
- 	lf.edititem[1] = MAIN_SEDIT;
- 
- 	/* 
- 	 * turn cell drawing on only after the cell contents have been initialized.
- 	 * this will avoid watching the delay between the LSetCells 
- 	 * calls and is faster.
- 	 */
- 	LDoDraw(true, dlist);
- 	LDoDraw(true, slist);
- 		
- 	DrawMenuBar();
- 	SetPort (savePort);					/* and put back our port */
- }
- 
- 
- /*
-  * setdcellstring
-  */
- void setdcellstring (unsigned char *string, domaintype *dp)
- {
- 	unsigned char *cp;
- 
- 	cp = string;
- 	strcpy(cp, dp->host);
- 	cp += strlen(cp);
- 		
- 	strcpy(cp, "\x09" "170;");			/* tab over */
- 	cp += strlen(cp);
- 
- 	strcpy(cp, dp->realm);
- 	cp += strlen(cp);
- 
- 	*cp = '\0';
- }
- 
- 
- /*
-  * setscellstring
-  */
- void setscellstring (unsigned char *string, servertype *sp)
- {
- 	unsigned char *cp;
- 
- 	cp = string;
- 	strcpy(cp, sp->host);
- 	cp += strlen(cp);
- 		
- 	strcpy(cp, "\x09" "170;");			/* tab over */
- 	cp += strlen(cp);
- 
- 	strcpy(cp, sp->realm);
- 	cp += strlen(cp);
- 
- 	if (sp->admin) {
- 		strcpy(cp, "\x09" "360;");
- 		cp += strlen(cp);
- 		strcpy(cp, "Admin");
- 		cp += strlen(cp);
- 	}
- 
- 	*cp = '\0';
- }
- 
- 
- /*
-  * setrcellstring
-  */
- void setrcellstring (unsigned char *string, credentialstype *rp)
- {
- #ifdef KRB4
- 	unsigned char *cp;
- 	
- 	cp = string;				/* name */
- 	strcpy(cp, rp->name);	
- 	cp += strlen(cp);
- 	if (rp->instance[0]) {		/* instance */
- 		*cp++ = '.';
- 		strcpy(cp, rp->instance);
- 		cp += strlen(cp);
- 	}
- 	if (rp->realm[0]) {			/* realm */
- 		*cp++ = '@';
- 		strcpy(cp, rp->realm);
- 		cp += strlen(cp);
- 	}
- 	strcpy(cp, "\x09" "170;");	/* tab */
- 	cp += strlen(cp);
- 	strcpy(cp, rp->sname);		/* sname */
- 	cp += strlen(cp);
- 	if (rp->sinstance[0]) {		/* sinstance */
- 		*cp++ = '.';
- 		strcpy(cp, rp->sinstance);
- 		cp += strlen(cp);
- 	}
- 	if (rp->srealm[0]) {		/* srealm */
- 		*cp++ = '@';
- 		strcpy(cp, rp->srealm);
- 		cp += strlen(cp);
- 	}
- 	*cp = '\0';
- #endif
- #ifdef KRB5
- 	unsigned char *cp;
- 	
- 	cp = string;
- 
- 	strcpy(cp, rp->pname);		/* name */
- 	cp += strlen(cp);
- 
- 	strcpy(cp, "\x09" "170;");	/* tab */
- 	cp += strlen(cp);
- 
- 	strcpy(cp, rp->cname);		/* credential name */
- 	cp += strlen(cp);
- 
- 	*cp = '\0';
- #endif
- }
- 
- 
- /*
-  * drawRealm
-  * Called by the Dialog manager to draw user items
-  */
- pascal void drawRealm (DialogPtr dialog, short item)
- {
- 	int s, savemode;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 	Str255 scratch;
- 	GrafPtr savePort;
- 	Point pt;
- 	
- 	GetPort(&savePort);
- 	SetPort(dialog);
- 
- 	/*
- 	 * Display the local realm
- 	 */
- #ifdef KRB4
- 	klopb.uRealm = scratch;
- 	if (s = lowcall(cKrbGetLocalRealm))
- 		strcpy(scratch, "None");
- #endif
- #ifdef KRB5
- {
- char *ptr;
- 	if (krb5_get_default_realm(kcontext, &ptr) == 0)
- 	{
- 		strcpy(scratch, ptr);
- 		free(ptr);
- 	}
- 	else
- 		strcpy(scratch, "None");
- }
- #endif
- 
- 	GetDItem(dialog, item, &itemType, &itemHandle, &itemRect);
- 	EraseRect(&itemRect);
- 	doshadow(&itemRect);
- 	dotriangle(&itemRect);
- 
- 	savemode = dialog->txMode;
- 	MoveTo(itemRect.left+4, itemRect.bottom-4);
- 	c2pstr(scratch);
- 	TextMode(srcCopy);
- 	DrawString(scratch);
- 	TextMode(savemode);
- 	GetPen(&pt);
- 	itemRect.right -= 17;	/* room for triangle */
- 	itemRect.left = pt.h;
- 	InsetRect(&itemRect, 1, 1);
- 	EraseRect(&itemRect);	/* erase remainder of space in rect */
- 
- 	SetPort(savePort);
- }
- 
- 
- /*
-  * this routine will be called by the Dialog Manager to draw the list. 
-  */
- pascal void dolist (DialogPtr dialog, short itemNo)
- {
- 	int i;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 	ListHandle list;
- 	struct listfilter *lf;
- 
- 	/*
- 	 * figure out which list is being updated
- 	 */
- 	lf = (struct listfilter *) ((DialogPeek)dialog)->window.refCon;
- 	for (i = 0; i < lf->nlists; i++)
-  		if (lf->listitem[i] == itemNo)
- 			break;
- 	if (i == lf->nlists)
- 		return;
- 		
- 	list = lf->list[i];
- 	GetDItem(dialog, itemNo,  &itemType, &itemHandle, &itemRect);
- 	
- 	/* 
- 	 *let the List Manager draw the list
- 	 */
- 	LUpdate(dialog->visRgn, list);
- 	
- 	/* 
- 	 * draw the lists framing rectangle OUTSIDE the view rectangle.
- 	 * if the frame is drawn inside the view rectangle then these lines
- 	 * will be erased, drawn onto or scrolled by the List Manager 
- 	 * since the lines are within the rectangle LM expects to be 
- 	 * able to draw in.
- 	 */
- 	InsetRect(&itemRect, -1, -1);
- 	FrameRect(&itemRect);
- }
- 
- 
- /*
-  * mainhit
-  * Called when an item in the dialog box is hit.
-  */
- void mainhit (EventRecord *event, DialogPtr dlg, int item)
- {
- 	int s, i, n;
- 	int admin;
- 	int listwidth;
- 	short itemType;				/* dummy parameter for call to GetDItem */
- 	Handle itemHandle;			/* dummy parameter for call to GetDItem */
- 	Rect itemRect;				/* the location of the list in the dialog */
- 	Point where;
- 	Point cell;
- 	GrafPtr savePort;
- 	char e1[256];
- 	char e2[256];
- 	domaintype *dp;
- 	servertype *sp;
- 	Str255 string, oldh, oldr;
- 	
- 	GetPort(&savePort);
- 	SetPort(dlg);
- 
- 	switch (item) {
- 	case MAIN_LOGIN:						/* login button */
- 		doLogin();
- 		break;
- 		
- 	case MAIN_LOGOUT: 						/* logout button */
- 		doLogout();
- 		break;
- 		
- 	case MAIN_DMAP:							/* domain map ui */
- 		where = event->where;
- 		GlobalToLocal(&where);
- 		/*
- 		 * Unselect cells in other list
- 		 */
- 		cell.h = cell.v = 0;
- 		 while (LGetSelect(true, &cell, slist))
- 			LSetSelect(false, cell, slist);
- 
- 		/* 
- 		 * let the List Manager process the mouse down. this includes 
- 		 * cell selection dragging, scrolling and double clicks by the 
- 		 * user.
- 		 */
- 		if (LClick(where, event->modifiers, dlist)) {
- 			/* 
- 			 * a double click in a cell has occured. find out in which 
- 			 * one of the cells the user has double clicked in.
- 			 */
- 			cell = LLastClick(dlist);
- 			goto dedit;
- 		}
- 
- 		break;
- 		
- 	case MAIN_SERVERS:						/* servers map ui */
- 		where = event->where;
- 		GlobalToLocal(&where);
- 		/*
- 		 * Unselect cells in other list
- 		 */
- 		cell.h = cell.v = 0;
- 		 while (LGetSelect(true, &cell, dlist))
- 			LSetSelect(false, cell, dlist);
- 
- 		/* 
- 		 * let the List Manager process the mouse down. this includes 
- 		 * cell selection dragging, scrolling and double clicks by the 
- 		 * user.
- 		 */
- 		if (LClick(where, event->modifiers, slist)) {
- 			/* 
- 			 * a double click in a cell has occured. find out in which 
- 			 * one of the cells the user has double clicked in.
- 			 */
- 			cell = LLastClick(slist);
- 			goto sedit;
- 		}
- 		break;
- 		
- 	case MAIN_PASSWORD:						/* change password button */
- 		kpass_dialog();
- 		break;
- 
- 	case MAIN_DNEW:							/* domain new */
- 		e1[0] = e2[0] = '\0';
- 		if (editlist(DLOG_DEDIT, e1, e2, 0)) {
- 			if (!(dp = (domaintype *)NewPtrClear(sizeof(domaintype)))) {
- 				SysBeep(20);
- 				break;
- 			}
- 			if (newdp(dp, e1, e2)) {
- 				qlink(&domainQ, dp);
- 				cell.v = (*dlist)->dataBounds.bottom;
- 				cell.h = 0;
- 				setdcellstring(string, dp);
- 				LAddRow(1, cell.v, dlist);
- 				LSetCell(string, strlen(string), cell, dlist);
- 			}
- 			addRealmMap(e1, e2);					
- 		}
- 		break;
- 		
- 	case MAIN_DDELETE:						/* domain delete */
- 		/*
- 		 * Loop for selected cells.
- 		 */
- 		 SetPt(&cell, 0, 0);
- 		 while (LGetSelect(true, &cell, dlist)) {
- 			dp = (domaintype *)domainQ;
- 			i = cell.v;
- 			while (dp && (i-- > 0))		/* find selected credential */
- 				dp = dp->next;
- 			if (dp) {
- 				qunlink(&domainQ, dp);
- 				deleteRealmMap(dp->host);
- 				DisposePtr((Ptr)dp);
- 				LSetSelect(false, cell, dlist);
- 				LDelRow(1, cell.v, dlist);
- 				SetPt(&cell, 0, 0);
- 			} else {						/* we are broken */
- 				SysBeep(20);
- 				break;
- 			}
- 		}
- 		break;
- 		
- 	case MAIN_DEDIT:						/* domain edit */
- 	dedit:
- 		/*
- 		 * Loop for selected cells.
- 		 */
- 		SetPt(&cell, 0, 0);
- 		while (LGetSelect(true, &cell, dlist)) {
- 			dp = (domaintype *)domainQ;
- 			i = cell.v;
- 			while (dp && (i-- > 0))		/* find selected item */
- 				dp = dp->next;
- 			if (dp) {
- 				strcpy(e1, dp->host);
- 				strcpy(e2, dp->realm);
- 				strcpy(oldh, dp->host);
- 				if (editlist(DLOG_DEDIT, e1, e2, 0)) {
- 					if (newdp(dp, e1, e2)) {
- 						setdcellstring(string, dp);
- 						LSetCell(string, strlen(string), cell, dlist);
- 					}
- 					deleteRealmMap(oldh);
- 					addRealmMap(e1, e2);					
- 				}
- 				LSetSelect(false, cell, dlist);		/* unselect item */
- 				SetPt(&cell, 0, 0);
- 			} else {						/* we are broken */
- 				SysBeep(20);
- 				break;
- 			}
- 		}
- 		break;
- 
- 	case MAIN_SNEW:							/* server new */
- 		e1[0] = e2[0] = '\0';
- 		admin = 0;
- 		if (editlist(DLOG_SEDIT, e1, e2, &admin)) {
- 			if (!(sp = (servertype *)NewPtrClear(sizeof(servertype)))) {
- 				SysBeep(20);
- 				break;
- 			}
- 			if (newsp(sp, e1, e2, admin)) {
- 				qlink(&serverQ, sp);
- 				cell.v = (*slist)->dataBounds.bottom;
- 				cell.h = 0;
- 				setscellstring(string, sp);
- 				LAddRow(1, cell.v, slist);
- 				LSetCell(string, strlen(string), cell, slist);
- 			}
- 			addServerMap(e1, e2, admin);
- 		}
- 		break;
- 		
- 	case MAIN_SDELETE:						/* server delete */
- 		/*
- 		 * Loop for selected cells.
- 		 */
- 		 SetPt(&cell, 0, 0);
- 		 while (LGetSelect(true, &cell, slist)) {
- 			sp = (servertype *)serverQ;
- 			i = cell.v;
- 			while (sp && (i-- > 0))		/* find selected credential */
- 				sp = sp->next;
- 			if (sp) {
- 				qunlink(&serverQ, sp);
- 				deleteServerMap(sp->host, sp->realm);
- 				DisposePtr((Ptr)sp);
- 				LSetSelect(false, cell, slist);
- 				LDelRow(1, cell.v, slist);
- 				SetPt(&cell, 0, 0);
- 			} else {						/* we are broken */
- 				SysBeep(20);
- 				break;
- 			}
- 		}
- 		break;
- 
- 	case MAIN_SEDIT:						/* server edit */
- 	sedit:
- 		/*
- 		 * Loop for selected cells.
- 		 */
- 		SetPt(&cell, 0, 0);
- 		while (LGetSelect(true, &cell, slist)) {
- 			sp = (servertype *)serverQ;
- 			i = cell.v;
- 			while (sp && (i-- > 0))		/* find selected item */
- 				sp = sp->next;
- 			if (sp) {
- 				strcpy(e1, sp->host);
- 				strcpy(e2, sp->realm);
- 				strcpy(oldh, sp->host);
- 				strcpy(oldr, sp->realm);
- 				admin = sp->admin;
- 				if (editlist(DLOG_SEDIT, e1, e2, &admin)) {
- 					if (newsp(sp, e1, e2, admin)) {
- 						setscellstring(string, sp);
- 						LSetCell(string, strlen(string), cell, slist);
- 					}
- 					deleteServerMap(oldh, oldr);
- 					addServerMap(e1, e2, admin);
- 				}
- 
- 				LSetSelect(false, cell, slist);		/* unselect item */
- 				SetPt(&cell, 0, 0);
- 			} else {						/* we are broken */
- 				SysBeep(20);
- 				break;
- 			}
- 		}
- 		break;
- 		
- 	case MAIN_REALM:
- 		GetDItem(dlg, MAIN_REALM, &itemType, &itemHandle, &itemRect);
- 		if (popRealms(&itemRect, &string)) {
- 			trimstring(string);
- #ifdef KRB4
- 			bzero(&klopb, sizeof(klopb));
- 			klopb.uRealm = string;
- 			if (s = lowcall(cKrbSetLocalRealm))
- 				kerror("Error in cKrbSetLocalRealm", s);
- #endif
- #ifdef KRB5
- {
- int		code;
- struct profile_node *node;
- char	*nam, *val;
- void	*state;
- 
- 			if ((s = krb5_set_default_realm(kcontext, string)) != 0)
- 				kerror("Error in cKrbSetLocalRealm", s);
- /*also change the profile string to match */
- 	state = NULL;
- 	code = profile_find_node_subsection(kcontext->profile->first_file->root, "libdefaults", &state, &nam, &node);
- 	code = profile_delete_node_relation(node, "default_realm");
- 	code = profile_add_node(node, "default_realm", string, &node);
- }			
- #endif
- 		}			
- 		break;
- 
- 	default:
- 		break;
- 	}
- 
- 	SetPort(savePort);
- }
- 
- 
- /*
-  * klist_dialog
-  * Display credentials and allow selection/deletion
-  */
- void klist_dialog ()
- {
- 	int i, ncredentials, listwidth;
- 	DialogPtr dialog;			/* the dialog */
- 	short itemNo;				/* the item in the dialog selected */
- 	short itemType;				/* dummy parameter for call to GetDItem */
- 	Handle itemHandle;			/* dummy parameter for call to GetDItem */
- 	Rect itemRect;				/* the location of the list in the dialog */
- 	Handle deleteHandle;		/* handle of delete button */
- 	ListHandle list;			/* the list constructed in the dialog */
- 	Rect dataBounds;			/* the dimensions of the data in the list */
- 	Point cellSize;				/* width and height of a cells rectangle */
- 	Point cell;					/* an index through the list */
- 	GrafPtr savePort;
- 	unsigned char string[512+4];
- 	int state;
- 	int changed = false;
- 	credentialstype *rp;
- 	struct listfilter lf;
- 	
- 	getCredentialsList();
- 	
- 	/*
-      * Get the dialog resource and modify the location.
-      * Since it will already be in memory, GetNewDialog will use
-      * the values we just set.
-      */
- 	PositionTemplate((Rect *)-1, 'DLOG', DLOG_KLIST, 50, 50);
- 	dialog = GetNewDialog(DLOG_KLIST, (Ptr) 0, (WindowPtr) -1);
- 	GetPort(&savePort);
- 	SetPort((GrafPtr) dialog);
- 
- 	GetDItem(dialog, KLIST_DELETE, &itemType, &deleteHandle, &itemRect);
- 
- #ifdef KRB5
- /* use logout to delete credentials */
- 	HideDItem(dialog, KLIST_DELETE);
- #endif
- 
- 	/* 
- 	 * allow the dialog manager routines to access various things
- 	 */
- 	((DialogPeek)dialog)->window.refCon = (long)&lf;
- 		
- 	/* 
- 	 * set the procedure pointer for the user items in the dialog.
- 	 * this will allow he default button to be outlined and the list 
- 	 * to be drawn by the Dialog Manger.
- 	 */
- 	GetDItem(dialog, KLIST_OUT, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, KLIST_OUT, itemType, (Handle) gdooutlineUPP, &itemRect);
- 		
- 	GetDItem(dialog, KLIST_LIST, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, KLIST_LIST, itemType, (Handle) gdolistUPP, &itemRect);
- 	/* note item rect used later */
- 
- 	ShowWindow(dialog);
- 
- 	listwidth = itemRect.right - itemRect.left;
- 
- 	/* 
- 	 * make room for scroll bars (see IM IV-270)
- 	 */
- 	itemRect.right -= 15;
- 
- 	/* 
- 	 * create a list
- 	 */
- 	ncredentials = 0;								/* count credentials */
- 	for (rp = (credentialstype *)credentialsQ; rp; rp = rp->next)
- 		ncredentials++;
- 	SetRect(&dataBounds, 0, 0, 1, ncredentials);
- 	SetPt(&cellSize, itemRect.right-itemRect.left, CELLH);
- 	list = LNew(&itemRect, &dataBounds, cellSize, 128, 
- 				(WindowPtr) dialog, false, false, false, true);
- 
- 	/* 
- 	 * use the default selection flags
- 	 */
- 	(*list)->selFlags = 0;
- 
- 	/*
- 	 * Initialize the cells in the list.
- 	 */
- 	rp = (credentialstype *)credentialsQ;
- 	cell.h = cell.v = 0;
- 	while (rp) {
- 		setrcellstring(string, rp);
- 		LSetCell(string, strlen(string), cell, list);
- 		cell.v++;
- 		rp = rp->next;
- 	}
- 
- 	lf.nlists = 1;
- 	lf.list[0] = list;
- 	lf.listitem[0] = KLIST_LIST;
- 	lf.edititem[0] = 0;
- 
- 	/* 
- 	 * turn cell drawing on only after the cell contents have been initialized.
- 	 * this will avoid watching the delay between the LSetCells 
- 	 * calls and is faster.
- 	 */
- 	LDoDraw(true, list);
- 		
- 	do {
- 		/*
- 		 * Set the state of the edit and delete buttons depending on if any
- 		 * cells are selected or not.
- 		 */
- 		SetPt(&cell, 0, 0);
- 		if (LGetSelect(true, &cell, list))
- 			state = 0;
- 		else
- 			state = 255;					/* disable */
- 		HiliteControl((ControlHandle) deleteHandle, state);
- 
- 		/* 
- 		 * process hits in the dialog.
- 		 */
- 			//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 		ModalDialog(gklistFilterUPP, &itemNo);
- 				
- 		switch(itemNo) {
- 			/* 
- 			 * process hits in the OK button.
- 			 */ 
- 		case KLIST_OK:
- 			/* 
- 			 * find out which cells have been selected.
- 			 */
- 			SetPt(&cell, 0, 0);
- 			while(LGetSelect(true, &cell, list)) {
- 				/* 
- 				 * there is nothing to do with the user's selections in 
- 				 * this sample so i'll just deselect the cells the 
- 				 * users has selected.
- 				 */
- 				LSetSelect(false, cell, list);
- 			}
- 			break;
- 			
- 		case KLIST_DELETE:
- 			changed = true;
- 			/*
- 			 * Loop for selected cells.
- 			 */
- 			 SetPt(&cell, 0, 0);
- 			 while (LGetSelect(true, &cell, list)) {
- 				rp = (credentialstype *)credentialsQ;
- 				i = cell.v;
- 				while (rp && (i-- > 0))		/* find selected credential */
- 					rp = rp->next;
- 			 	if (rp) {
- 					qunlink(&credentialsQ, rp);
- 					deleteCredentials(rp);
- 					DisposePtr((Ptr)rp);
- 					LSetSelect(false, cell, list);
- 					LDelRow(1, cell.v, list);
- 					SetPt(&cell, 0, 0);
- 				} else {						/* we are broken */
- 					SysBeep(20);
- 					break;
- 				}
- 			}
- 			break;
- 		}
- 	} while (itemNo != ok);
- 	
- 	/*	
- 	 * kill the list and dialog.
- 	 */
- 	SetPort(savePort);
- 	LDispose(list);
- 	DisposDialog(dialog);
- }
- 
- 
- /* 
-  * we need to be able to process mouse clicks in the list. the Dialog 
-  * Manager makes this possible through filter procedures like this one. 
-  * since the default filter procedure will be replaced we also need to 
-  * handle return key presses.
-  */
- pascal Boolean klistFilter (DialogPtr dialog, EventRecord *event, short *itemHit)
- {
- 	int i;
- 	ListHandle list;
- 	Point cell;
- 	char character;
- 	Point where;
- 	Rect itemRect;
- 	short itemType;
- 	Handle itemHandle;
- 	struct listfilter *lf;
- 	
- 	lf = (struct listfilter *) ((DialogPeek)dialog)->window.refCon;
- 
- 	switch (event->what) {
- 	
- 		/* 
- 		 * watch for mouse clicks in the List
- 		 */
- 	case mouseDown :
- 		for (i = 0; i < lf->nlists; i++) {
- 			GetDItem(dialog, lf->listitem[i], &itemType, &itemHandle, &itemRect);
- 			where = event->where;
- 			GlobalToLocal(&where);
- 		
- 			/* 
- 			 * if the user has clicked in the list then we'll handle the 
- 			 * processing here
- 			 */
- 			if (PtInRect(where, &itemRect)) {
- 				/* 
- 				 * recover the list handle. it was stuffed into the dialog 
- 				 * window's refCon field when it was created.
- 				 */
- 				list = lf->list[i];
- 				
- 				/* 
- 				 * let the List Manager process the mouse down. this includes 
- 				 * cell selection dragging, scrolling and double clicks by the 
- 				 * user.
- 				 */
- 				if (LClick(where, event->modifiers, list)) {
- 					/* 
- 					 * a double click in a cell has occured. find out in which 
- 					 * one of the cells the user has double clicked in.
- 					 */
- 					cell = LLastClick(list);
- 
- 					if (lf->edititem[i])
- 						*itemHit = lf->edititem[i];		/* fake an edit hit if double click */
- 				} else {
- 					/* 
- 					 * tell the application that the list has been clicked in.
- 					 */
- 					*itemHit = lf->listitem[i];
- 				}
- 				return true;	/* event has been handled */
- 			}
- 		} /* for */
- 		break;
- 	
- 		/* 
- 		 * be sure and return this information so the Dialog Manager will 
- 		 * process the return and enter key presses as clicks by the user in 
- 		 * the OK button. this is only required because we have overridden 
- 		 * the Dialog Manager's default filtering.
- 		 */
- 	case keyDown :	
- 	case autoKey :
- 		character = event->message & charCodeMask;
- 		switch (character) {
- 		case '\n':			/* Return */
- 		case '\003':		/* Enter */
- 			/* 
- 			 * tell the application that the OK button has been clicked by 
- 			 * the user.
- 			 */
- 			*itemHit = 1;				/* item 1 must be ok button */
- 			return true;				/* we handled the event */
- 		}
- 		break;
- 	}
- 	
- 	/* 
- 	 * tell the Dialog Manger that the event has NOT been handled and that 
- 	 * it should take further action on this event.
- 	 */
- 	return false;
- }
- 
- 
- Boolean editlist (int dlog, char *e1, char *e2, int *admin)
- {
- 	int ok, ret = false;
- 	short item;
- 	GrafPtr savePort;
- 	DialogPtr dialog;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 	char s1[256], s2[256];
- 	int astate;
- 
- 	PositionTemplate((Rect *)-1, 'DLOG', dlog, 50, 50);
- 	dialog = GetNewDialog(dlog, (Ptr) 0, (WindowPtr) -1);
- 	GetPort(&savePort);
- 	SetPort((GrafPtr) dialog);
- 
- 	/*
- 	 * Set the draw procedure for the user items.
- 	 */
- 	GetDItem(dialog, EDIT_OUT, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, EDIT_OUT, itemType, (Handle)gdooutlineUPP, &itemRect);
- 
- 	GetDItem(dialog, EDIT_E1, &itemType, &itemHandle, &itemRect);
- 	c2pstr(e1);
- 	SetIText(itemHandle, e1);
- 	p2cstr(e1);
- 
- 	GetDItem(dialog, EDIT_E2, &itemType, &itemHandle, &itemRect);
- 	c2pstr(e2);
- 	SetIText(itemHandle, e2);
- 	p2cstr(e2);
- 
- 	if (admin) {
- 		astate = *admin;
- 		GetDItem(dialog, EDIT_ADMIN, &itemType, &itemHandle, &itemRect);
- 		SetCtlValue((ControlHandle)itemHandle, astate);
- 	}
- 
- 	SelIText(dialog, EDIT_E1, 0, 32767);				/* select E1 */
- 
- 	ok = 0;
- 	do {
- 		/* 
- 		 * process hits in the dialog.
- 		 */
- 			//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 		ModalDialog(gokFilterUPP, &item);
- 		switch (item) {
- 		case EDIT_OK:							/* ok button */
- 			ok = 1;
- 			break;
- 			
- 		case EDIT_CANCEL:
- 			ok = 2;
- 			break;
- 
- 		case EDIT_ADMIN:
- 			astate ^= 1;
- 			GetDItem(dialog, EDIT_ADMIN, &itemType, &itemHandle, &itemRect);
- 			SetCtlValue((ControlHandle)itemHandle, astate);
- 			break;
- 		}
- 	} while (ok == 0);
- 	
- 	if (ok == 1) {
- 		GetDItem(dialog, EDIT_E1, &itemType, &itemHandle, &itemRect);
- 		GetIText(itemHandle, s1);
- 		p2cstr(s1);
- 
- 		GetDItem(dialog, EDIT_E2, &itemType, &itemHandle, &itemRect);
- 		GetIText(itemHandle, s2);
- 		p2cstr(s2);
- 
- 		if (admin) {
- 			*admin = astate;
- 		}
- 
- 		if (!s1[0] || !s2[0])				/* if either is empty */
- 			goto xit;
- 
- 		strcpy(e1, s1);
- 		strcpy(e2, s2);
- 
- 		ret = true;
- 	}
- 	
- xit:
- 	DisposDialog(dialog);
- 	SetPort(savePort);
- 	return ret;
- }
- 
- 
- pascal Boolean okFilter (DialogPtr dialog, EventRecord *event, short *itemHit)
- {
- 	#pragma unused (dialog)
- 	char character;
- 
- 	switch (event->what) {
- 	case keyDown :	
- 	case autoKey :
- 		character = event->message & charCodeMask;
- 		switch (character) {
- 		case '\n':			/* Return */
- 		case '\003':		/* Enter */
- 			/* 
- 			 * tell the application that the OK button has been clicked by 
- 			 * the user.
- 			 */
- 			*itemHit = 1;				/* item 1 must be ok button */
- 			return true;				/* we handled the event */
- 		}
- 		break;
- 	}
- 	
- 	/* 
- 	 * tell the Dialog Manger that the event has NOT been handled and that 
- 	 * it should take further action on this event.
- 	 */
- 	return false;
- }
- 
- 
- int popRealms (Rect *rect, char *retstring)
- {   
-     int i, s, itsID, selected;
-     MenuHandle theMenu;
-     long theChoice;
- 	Point pt;
- 	servertype *sp;
- 	Str255 scratch, localrealm;
-                 
- 	/*
- 	 * Get the local realm
- 	 */
- #ifdef KRB4
- 	klopb.uRealm = localrealm;
- 	if (s = lowcall(cKrbGetLocalRealm))
- 		strcpy(localrealm, "None");
- #endif
- #ifdef KRB5
- {
- char *ptr;
- 	if (krb5_get_default_realm(kcontext, &ptr) == 0)
- 	{
- 		strcpy(scratch, ptr);
- 		free(ptr);
- 	}
- 	else
- 		strcpy(scratch, "None");
- }
- #endif
- 
-     /* 
- 	 * get an id for the menu and create it. 
- 	 */
-     itsID = 0;
-     while (itsID < 128)
-         itsID = UniqueID('MENU');
-     theMenu = NewMenu(itsID,"\pxxx");        /* create the menu */
-     InsertMenu(theMenu, -1);                 /* add it to the menu list */
-     
-     /* 
- 	 * add the items 
- 	 */
- 	selected = 0;
- 	for (i = 1, sp = (servertype *)serverQ; sp; sp = sp->next, i++) {
- 		strcpy(scratch, sp->realm);
- 		if (strcmp(scratch, localrealm) == 0)
- 			selected = i;
- 		c2pstr(scratch);
- 		AppendMenu(theMenu, scratch);
- 	}
-     SetItemMark(theMenu, selected, checkMark);
- 	fixmenuwidth(theMenu, rect->right - rect->left);
- 
-     /* 
- 	 *pop it up 
- 	 */
- 	pt.h = rect->left+1;
- 	pt.v = rect->top;
- 	LocalToGlobal(&pt);
-     theChoice = PopUpMenuSelect(theMenu, pt.v, pt.h, selected);
- 	theChoice = theChoice & 0xffff;
-     
- 	if (theChoice) {
- 		GetItem(theMenu, theChoice, retstring);		
- 		p2cstr(retstring);
- 	}
- 
-     DeleteMenu(itsID);
- 	DisposeMenu(theMenu);
- 	
- 	return(theChoice);
- }
- 
- 
- Boolean newdp (domaintype *dp, char *e1, char *e2)
- {
- 	char *s1, *s2;
- 	
- 	if (!e1[0] || !e2[0])					/* if empty strings */
- 		return false;
- 		
- 	strcpy(dp->host, e1);
- 	strcpy(dp->realm, e2);
- 	return true;
- }
- 
- 
- Boolean newsp (servertype *sp, char *e1, char *e2, int admin)
- {
- 	char *s1, *s2;
- 	
- 	if (!e1[0] || !e2[0])					/* if empty strings */
- 		return false;
- 		
- 	strcpy(sp->host, e1);
- 	strcpy(sp->realm, e2);
- 	sp->admin = admin;
- 
- 	return true;
- }
- 
- 
- /*
-  * bzero
-  * Block zero
-  */
- void bzero (void *dst, long n)
- {
- 	int i;
- 	register char *d = dst;
- 
- 	while (n--)
- 	*d++ = 0;
- }
- 
- 
- /*
-  * bcopy
-  * Block copy
-  */
- void bcopy (void *src, void *dst, int n)
- {
- 	int i;
- 	register char *s = src;
- 	register char *d = dst;
- 
- 	for (i = 0; i < n; i++)
- 		*d++ = *s++;
- }
- 
- 
- /*
-  * getmem
-  * malloc a block of zeroed memory
-  */
- Ptr getmem (size)
- 	size_t size;
- {
- 	Ptr p;
- 
- 	p = (Ptr) malloc(size);
- 	if (!p) {
- 		doalert("getmem: request for %ld failed", size);
- 		getout(1);
- 	}
- 	bzero(p, size);
- 
- 	return p;
- }
- 
- 
- /*
-  * getout
-  * clean up and get out
-  */
- getout (exit)
- 	int exit;
- {
- #ifdef KRB4
- 	krb_end_session((char *)0);		/* Clean up nicely */
- 	ExitToShell();
- #endif
- #ifdef KRB5
- /*try to dump the profile as it exists in memory to a file */
- 
- 	if (kcontext->profile)
- 	{
- 	FILE	*daFile;
- 	char	*profilepath;
- 	extern char* GetMacProfilePathName(void);
- 		profilepath = GetMacProfilePathName();
- 		daFile = fopen(profilepath, "w+");
- 		dump_profile_to_file(kcontext->profile->first_file->root, 0, daFile);
- 		fclose(daFile);
- 		free(profilepath);
- 	}
- 	ExitToShell();
- 	/* FIXME */
- #endif
- }
- 
- 
- /*
-  * doalert
-  * Bring up an alert box
-  */
- void doalert (char *format, ...)
- {
- 	char string[256];
- 	va_list args;
- 
- 	va_start(args, format);
- 
- 	vsprintf(&string[1], format, args);
- 	string[0] = strlen(&string[1]);
- 	va_end(args);
- 
- 	ParamText(string, "", "", "");
- 
- 	PositionTemplate((Rect *)-1, 'ALRT', ALERT_DOALERT, 50, 50);
- 	Alert(ALERT_DOALERT, NULL);
- }
- 
- 
- /*
-  * Return 0 if strings (ignoring case) match
-  */
- static int strcasecmp (char *a, char *b)
- {
- 	for (;;) {
- 		if (toupper(*a) != toupper(*b))
- 			return 1;
- 		if (*a == '\0')
- 			return 0;
- 		a++;
- 		b++;
- 	}
- }
- 
- 
- fatal (char *string)
- {
- 	doalert(string);
- 	getout(0);
- }
- 
- 
- char *copystring (char *src)
- {
- 	int n;
- 	char *dst;
- 
- 	if (!src || (*src == '\0'))
- 		return NULL;
- 
- 	n = strlen(src);
- 	dst = malloc(n+1);
- 	strcpy(dst, src);
- 
- 	return dst;
- }
- 
- 
- /*
-  * isPressed
-  * k =  any keyboard scan code, 0-127
-  */
- short isPressed (unsigned short k)
- {
- 	unsigned char km[16];
- 
- 	GetKeys((long *)km);
- 	return (( km[k>>3] >> (k & 7) ) & 1);
- }
- 
- 
- void doLogin ()
- {
- #ifdef KRB4
- 	int s;
- 
- 	/*
- 	 * Get a TGT
- 	 */
- 	bzero(&khipb, sizeof(krbHiParmBlock));
- 	khipb.service = 0;
- 	if (s = hicall(cKrbCacheInitialTicket))
- 		if (s != cKrbUserCancelled)
- 			kerror("Error in cKrbCacheInitialTicket", s);
- #endif
- 
- #ifdef KRB5
-     long lifetime = 8*60;	// 8 hours
-     krb5_error_code code;
-     krb5_principal principal;
-     krb5_creds creds;
-     krb5_principal server;
-     krb5_int32 sec, usec;
-     char usernm[100] = "";
-     char passwd[100];
-     char credname[100];
-     char realm[100];
-     char *ptr;
- 
- 	/* if the gUserName isn't uknown, we'll use that name */
- 	if (strcmp(gUserName, kUNKNOWNUSERNAME))
- 		strcpy(usernm, gUserName);
- 
- 	if (GetUserInfo(usernm, passwd) == 2)
- 		return;
- 
- 	if (krb5_get_default_realm(kcontext, &ptr) == 0)
- 	{
- 		strcpy(realm, ptr);
- 		free(ptr);
- 	}
- 	else
- 		strcpy(realm, "None");
- 
- 	do {
- 	    principal = server = NULL;
- 		memset(&creds, 0, sizeof(creds));
- 	
- 	    sprintf (credname, "%s@%s", usernm, realm);
- 	    code = krb5_parse_name(kcontext, credname, &principal);
- 	    if (code) break;
- 	
- 		code = krb5_cc_initialize(kcontext, k5_ccache, principal);
- 	    if (code) break;
- 	
- 		code = krb5_build_principal_ext(kcontext, &server,
- 			krb5_princ_realm(kcontext, principal)->length,
- 			krb5_princ_realm(kcontext, principal)->data,
- 	        KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME,
- 		    krb5_princ_realm(kcontext, principal)->length,
- 			krb5_princ_realm(kcontext, principal)->data, 0);
- 	    if (code) break;
- 	
- 		creds.client = principal;
- 		creds.server = server;
- 	
- 	    code = krb5_crypto_us_timeofday(&sec, &usec);
- 	    if (code) break;
- 	    creds.times.starttime = 0;
- 		creds.times.endtime = sec + 60L * lifetime;
- 		creds.times.renew_till = 0;
- 	
- 		code = krb5_get_in_tkt_with_password(kcontext, 0, NULL,
- 	        NULL, NULL, passwd, k5_ccache, &creds, 0);
- 	} while (0);
- 	
- 	if (principal)
- 	    krb5_free_principal(kcontext, principal);
- 	if (server) 
- 		krb5_free_principal(kcontext, server);
- 
- 	if (code)
- 	{
- 		com_err (NULL, code, "while logging in.");
- 	}
- 	else
- 	{
- 		strcpy(gUserName, usernm);	/* copy the user name over to the global username */
- 		strcpy(gRealmName, realm);	/* copy the realm name over to the global realmname */
- 	}
- #endif
- }
- 
- 
- #ifdef KRB5
- /*+
-  * Function: destroys all tickets in a k5 ccache
-  *
-  * Parameters:
-  *  none
-  *
-  * Returns: K5 error code (0 == success)
-  */
- static krb5_error_code
- k5_dest_tkt (void) {
-     krb5_error_code code;
-     krb5_principal princ;
- 
-     if (code = krb5_cc_get_principal(kcontext, k5_ccache, &princ)) {
-         kerror ("while retrieving principal name", code);
-         return code;
-     }
- 
-     code = krb5_cc_initialize (kcontext, k5_ccache, princ);
-     if (code != 0) {
-         kerror ("when re-initializing cache", code);
-         krb5_free_principal (kcontext, princ);
-         return code;
-     }
- 
-     krb5_free_principal (kcontext, princ);
-     return code;
- }
- #endif
- 
- void doLogout ()
- {
- #ifdef KRB4
- 	int s;
- 	
- 	pb.cntrlParam.csCode = cKrbDeleteAllSessions;
- 	if ((s = PBControl(&pb, false)) || (s = pb.cntrlParam.ioResult))
- 		kerror("Error in cKrbDeleteAllSessions", s);
- #endif
- #ifdef KRB5
- 	k5_dest_tkt();
- 	strcpy(gUserName, kUNKNOWNUSERNAME);
- #endif
- }
- 
- 
- void getRealmMaps ()
- {
- #ifdef KRB4
- 	int i, s;
- 	Str255 host, realm;
- 	domaintype *dp;
- 
- 	for (i = 1; ;i++) {
- 		klopb.itemNumber = &i;
- 		klopb.host = host;
- 		klopb.uRealm = realm;
- 		if (s = lowcall(cKrbGetNthRealmMap))
- 			break;
- 			
- 		if (!(dp = (domaintype *)NewPtrClear(sizeof(domaintype))))
- 			return;
- 		strcpy(dp->realm, realm);
- 		strcpy(dp->host, host);
- 		qlink(&domainQ, dp);
- 	}
- #endif
- #ifdef KRB5
- int count;
- char **domainlist;
- char	*realm;
- int		code;
- int		i;
- domaintype *dp;
- const char	*realm_kdc_names[4];
- 
-     realm_kdc_names[0] = "domain_realm";
-     realm_kdc_names[1] = 0;
- 
-     code = profile_get_first_values(kcontext->profile, realm_kdc_names, &domainlist);
- 
-     count = 0;
-     while (domainlist && domainlist[count])
- 	{
- 		code = profile_get_string(kcontext->profile, "domain_realm", domainlist[count], NULL, "", &realm);
- 
- 		if (!(dp = (domaintype *)NewPtrClear(sizeof(domaintype))))
- 			return;
- 		strcpy(dp->realm, realm);
- 		strcpy(dp->host, domainlist[count]);
- 		qlink(&domainQ, dp);
- 
- 	    count++;
- 	}
- 	free(domainlist);
- #endif
- }
- 
- 
- void getServerMaps ()
- {
- #ifdef KRB4
- 	int i, s, ar;
- 	Str255 host, realm;
- 	servertype *sp;
- 
- 	for (i = 1; ;i++) {
- 		klopb.itemNumber = &i;
- 		klopb.host = host;
- 		klopb.uRealm = realm;
- 		klopb.adminReturn = &ar;
- 		if (s = lowcall(cKrbGetNthServerMap))
- 			break;
- 			
- 		if (!(sp = (servertype *)NewPtrClear(sizeof(servertype))))
- 			return;
- 		strcpy(sp->realm, realm);
- 		strcpy(sp->host, host);
- 		sp->admin = ar;
- 		qlink(&serverQ, sp);
- 	}
- #endif
- #ifdef KRB5
- int i, s, ar = 1;
- Str255 realm;
- servertype *sp;
- int count;
- char **realmlist;
- char	*host;
- int		code;
- const char	*realm_kdc_names[4];
- 
-     realm_kdc_names[0] = "realms";
-     realm_kdc_names[1] = 0;
- 
-     code = profile_get_first_values(kcontext->profile, realm_kdc_names, &realmlist);
- 
-     count = 0;
-     while (realmlist && realmlist[count])
- 	{
- 	    realm_kdc_names[0] = "realms";
-     	realm_kdc_names[1] = realmlist[count];
-     	realm_kdc_names[2] = "kdc";
-     	realm_kdc_names[3] = 0;
- 
- 		code = profile_get_string(kcontext->profile, "realms", realmlist[count], "kdc", "", &host);
- 	
- 		if (!(sp = (servertype *)NewPtrClear(sizeof(servertype))))
- 			return;
- 		strcpy(sp->realm, realmlist[count]);
- 		strcpy(sp->host, host);
- 		code = profile_get_string(kcontext->profile, "realms", realmlist[count], "kdc", "", &host);
- 		sp->admin = ar;
- 		qlink(&serverQ, sp);
- 
- 	    count++;
- 	}
- 	free(realmlist);
- 
- #endif
- }
- 
- 
- void getCredentialsList ()
- {
- #ifdef KRB4
- 	int i, j, s;
- 	Str255 scratch;
- 	Str255 name, instance, realm, sname, sinstance, srealm, tktfile;
- 	credentialstype *rp;
- 
- 	killCredentialsList();
- 
- 	/*
- 	 * list credentials
- 	 */
- 	bzero(&klopb, sizeof(krbParmBlock));
- 	klopb.uName = name;
- 	klopb.uInstance = instance;
- 	klopb.uRealm = realm;
- 	klopb.sName = sname;
- 	klopb.sInstance = sinstance;
- 	klopb.sRealm = srealm;
- 	
- 	i = 1;
- 	for (j = 1; ;j++) {
- 		klopb.itemNumber = &i;
- 		if (s = lowcall(cKrbGetNthSession)) {
- 			if (s != cKrbSessDoesntExist)
- 				kerror("cKrbGetNthSession: ", s);
- 			return;
- 		}
- 
- 		klopb.itemNumber = &j;
- 		if (s = lowcall(cKrbGetNthCredentials)) {
- 			if ((s != cKrbCredsDontExist) & 
- 				(cKrbKerberosErrBlock - s != KFAILURE)) {
- 				kerror("cKrbGetNthCredentials: ", s);
- 				break;
- 			}
- 			i += 1;
- 		    j = 0;
- 			continue;
- 		}
- 
- 		if (!(rp = (credentialstype *)NewPtrClear(sizeof(credentialstype))))
- 			return;
- 				
- 		strcpy(rp->sname, sname);
- 		strcpy(rp->sinstance, sinstance);
- 		strcpy(rp->srealm, srealm);
- 		
- 		/*	
- 		cKrbGetNthCredentials no longer returns the principal's, name
- 		instance and realm.  Instead it returns the cache name, 
- 		"fixed user", "fixed instance", "fixed realm".  Must get the 
- 		principal's name, instance, and realm by calling a routine 
- 		added by cns.
- 		*/
- 
- 		bzero(&klopb, sizeof(krbParmBlock));
- 		klopb.fullname = tktfile;
- 		klopb.uName = name;
- 		klopb.uInstance = instance;
- 		klopb.uRealm = realm;
- 		klopb.sName = sname;
- 		klopb.sInstance = sinstance;
- 		klopb.sRealm = srealm;
- 		
- 		if (s = lowcall(cKrbGetTfFullname)) {
- 			if (s != KSUCCESS)
- 				kerror("cKrbGetTfFullname: ", s);
- 			return;
- 			}
- 		
- 		strcpy(rp->name, name);
- 		strcpy(rp->instance, instance);
- 		strcpy(rp->realm, realm);
- 		
- 		qlink(&credentialsQ, rp);
- 	}
- #endif
- #ifdef KRB5
- 	int i, j, s;
- 	Str255 scratch;
- 	Str255 name, instance, realm, sname, sinstance, srealm, tktfile;
- 	credentialstype *rp;
- 	krb5_cc_cursor cursor;
- 	krb5_creds creds;
- 	char *tmpstr;
- 	
- 	killCredentialsList();
- 
- 	/*
- 	 * list credentials
- 	 */
- 	cursor = 0;
- 	krb5_fcc_start_seq_get(kcontext, k5_ccache, &cursor);
- 	while (0 == krb5_fcc_next_cred(kcontext, k5_ccache, &cursor, &creds)) {
- 		/* Get Cred info here */
- 		if (!(rp = (credentialstype *)NewPtrClear(sizeof(credentialstype))))
- 			return;
- 
- 		strncpy(rp->name, (char*) creds.client->data->data, sizeof(Str255));
- 		strcpy(rp->instance, "instance");
- 		strncpy(rp->realm, (char*) creds.client->realm.data, sizeof(Str255));
- 		strncpy(rp->sname, (char*) creds.server->data->data, sizeof(Str255));
- 		strcpy(rp->sinstance, "sinstance");
- 		strncpy(rp->srealm, (char*) creds.server->realm.data, sizeof(Str255));
- 		krb5_unparse_name(kcontext, creds.client, &tmpstr);
- 		strcpy(rp->pname, tmpstr);
- 		free(tmpstr);
- 		krb5_unparse_name(kcontext, creds.server, &tmpstr);
- 		strcpy(rp->cname, tmpstr);
- 		free(tmpstr);
- 		qlink(&credentialsQ, rp);
- 	}
- 	krb5_fcc_end_seq_get(kcontext, k5_ccache, &cursor);
- 	krb5_cc_default (kcontext, &k5_ccache);
- #endif
- }
- 
- 
- void killCredentialsList ()
- {
- 	credentialstype *rp;
- 	
- 	while (rp = credentialsQ) {
- 		qunlink(&credentialsQ, rp);
- 		DisposePtr((Ptr)rp);
- 	}
- }
- 
- 
- void addRealmMap (char *host, char *realm)
- {
- #ifdef KRB4
- 	int s;
- 
- 	klopb.host = host;
- 	klopb.uRealm = realm;
- 	if (s = lowcall(cKrbAddRealmMap))
- 		kerror("Error calling cKrbAddRealmMap", s);
- #endif
- #ifdef KRB5
- int		code;
- struct profile_node *node;
- char	*nam, *val;
- void	*state;
- 
- 	state = NULL;
- 	code = profile_find_node_subsection(kcontext->profile->first_file->root, "domain_realm", &state, &nam, &node);
- 	code = profile_delete_node_relation(node, host);
- 	code = profile_add_node(node, host, realm, &node);
- 
- #endif
- }
- 
- void deleteRealmMap (char *host)
- {
- #ifdef KRB4
- 	int s;
- 	
- 	klopb.host = host;
- 	if (s = lowcall(cKrbDeleteRealmMap))
- 		kerror("Error calling cKrbDeleteRealmMap", s);
- #endif
- #ifdef KRB5
- int		code;
- struct profile_node *node;
- char	*nam, *val;
- void	*state;
- 
- 	state = NULL;
- 	code = profile_find_node_subsection(kcontext->profile->first_file->root, "domain_realm", &state, &nam, &node);
- 	code = profile_delete_node_relation(node, host);
- #endif
- }
- 
- 
- void deleteCredentials (credentialstype *rp)
- {
- #ifdef KRB4
- 	int s;
- 	
- 	klopb.uName = rp->name;
- 	klopb.uInstance = rp->instance;
- 	klopb.uRealm = rp->realm;
- 	klopb.sName = rp->sname;
- 	klopb.sInstance = rp->sinstance;
- 	klopb.sRealm = rp->srealm;
- 	if (s = lowcall(cKrbDeleteCredentials))
- 		kerror("Error calling cKrbDeleteCredentials: ", s);
- #endif
- #ifdef KRB5
- 	/* FIXME */
- #endif
- }
- 
- 
- 
- void addServerMap (char *host, char *realm, int admin)
- {
- #ifdef KRB4
- 	int s;
- 
- 	klopb.host = host;
- 	klopb.uRealm = realm;
- 	klopb.admin = admin;
- 	if (s = lowcall(cKrbAddServerMap))
- 		kerror("Error calling cKrbAddServerMap", s);
- #endif
- #ifdef KRB5
- int		code;
- struct profile_node *node, *node2;
- char	*nam, *val;
- void	*state;
- 
- 	state = NULL;
- 	code = profile_find_node_subsection(kcontext->profile->first_file->root, "realms", &state, &nam, &node);
- 	code = profile_delete_node_relation(node, realm);	/* possible memory leak here */
- 	code = profile_add_node(node, realm, 0, &node);		/* Create the realm node */
- 	code = profile_add_node(node, "kdc", host, &node2);		/* Create the realm node */
- 	code = profile_add_node(node, "admin_server", host, &node2);		/* Create the realm node */
- #endif
- }
- 
- 
- void deleteServerMap (char *host, char *realm)
- {
- #ifdef KRB4
- 	int s;
- 	
- 	klopb.host = host;
- 	klopb.uRealm = realm;
- 	if (s = lowcall(cKrbDeleteServerMap))
- 		kerror("Error calling cKrbDeleteServerMap", s);
- #endif
- #ifdef KRB5
- int		code;
- struct profile_node *node;
- char	*nam, *val;
- void	*state;
- 
- 	state = NULL;
- 	code = profile_find_node_subsection(kcontext->profile->first_file->root, "realms", &state, &nam, &node);
- 	code = profile_delete_interior_node_relation(node, realm);	/* possible memory leak here */
- #endif
- }
- 
- 
- void kerror (char *text, int error)
- {
- #ifdef KRB4
- 	int k;
- 	Str255 scratch;
- 	char *etext;
- 
- 	switch (error) {
- 	case cKrbCorruptedFile:
- 		etext = "Couldn't find a needed resource";
- 		break;
- 	case cKrbNoKillIO:
- 		etext = "Can't killIO because all calls sync";
- 		break;
- 	case cKrbBadSelector:
- 		etext = "csCode passed doesn't select a recognized function";
- 		break;
- 	case cKrbCantClose:
- 		etext = "We must always remain open";
- 		break;
- 	case cKrbMapDoesntExist:
- 		etext = "Tried to access a map that doesn't exist";
- 		break;
- 	case cKrbSessDoesntExist:
- 		etext = "Tried to access a session that doesn't exist";
- 		break;
- 	case cKrbCredsDontExist:
- 		etext = "Tried to access credentials that don't exist";
- 		break;
- 	case cKrbTCPunavailable:
- 		etext = "Couldn't open MacTCP driver";
- 		break;
- 	case cKrbUserCancelled:
- 		etext = "User cancelled a log in operation";
- 		break;
- 	case cKrbConfigurationErr:
- 		etext = "Kerberos Preference file is not configured properly";
- 		break;
- 	case cKrbServerRejected:
- 		etext = "A server rejected our ticket";
- 		break;
- 	case cKrbServerImposter:
- 		etext = "Server appears to be a phoney";
- 		break;
- 	case cKrbServerRespIncomplete:
- 		etext = "Server response is not complete";
- 		break;
- 	case cKrbNotLoggedIn:
- 		etext = "Returned by cKrbGetUserName if user is not logged in";
- 		break;
- 	default:
- 		k = cKrbKerberosErrBlock - error;
- 		if ((k > 0) && (k < 256)) {
- 			etext = krb_get_err_text(k);
- 			break;
- 		}
- 
- 		sprintf(scratch, "Mac Kerberos error #%d", error);
- 		etext = scratch;
- 		break;
- 	}
- 
- 	doalert("%s: %s", text, etext);
- #endif
- #ifdef KRB5
- 	/* FIXME */
- #endif
- }
- 
- #ifdef KRB4
- int lowcall (int cscode)
- {
- 	short s;
- 	
- 	bzero(&pb, sizeof(ParamBlockRec));
- 	*(long *)pb.cntrlParam.csParam = (long)&klopb;
- 	pb.cntrlParam.ioCompletion = nil;
- 	pb.cntrlParam.ioCRefNum = kdriver;
- 
- 	pb.cntrlParam.csCode = cscode;
- 	if (s = PBControl(&pb, false))
- 		return s;
- 	if (s = pb.cntrlParam.ioResult)
- 		return s;
- 	return 0;
- }
- 
- 
- int hicall (int cscode)
- {
- 	short s;
- 	
- 	bzero(&pb, sizeof(ParamBlockRec));
- 	*(long *)pb.cntrlParam.csParam = (long)&khipb;
- 	pb.cntrlParam.ioCompletion = nil;
- 	pb.cntrlParam.ioCRefNum = kdriver;
- 
- 	pb.cntrlParam.csCode = cscode;
- 	if (s = PBControl(&pb, false))
- 		return s;
- 	if (s = pb.cntrlParam.ioResult)
- 		return s;
- 	return 0;
- }
- #endif
- 
- /*
-  * qlink
-  * Add an entry to the end of a linked list
-  */
- void qlink (void **flist, void *fentry)
- {
-     struct dummy {
- 		struct dummy *next;
-     } **list, *entry;
- 
-     list = flist;
-     entry = fentry;
-     
-     /*
-      * Find address of last entry in the list.
-      */
-     while (*list)
- 	list = &(*list)->next;
- 
-     /*
-      * Link entry
-      */
-     *list = entry;
-     entry->next = 0;
- }
- 
- 
- /*
-  * qunlink
-  * Remove an entry from linked list
-  * Returns the entry or NULL if not found.
-  */
- void *qunlink (void **flist, void *fentry)
- {
-     struct dummy {
- 	struct dummy *next;
-     } **list, *entry;
- 
-     list = flist;
-     entry = fentry;
-     
-     /*
-      * Find entry and unlink it
-      */
-     while (*list) {
- 	if ((*list) == entry) {
- 	    *list = entry->next;
- 	    return entry;
- 	}
- 
- 	list = &(*list)->next;
-     }
-     return NULL;
- }
- 
- 
- /*
-  * fixmenuwidth
-  * set minimum menu width by widening item
-  */
- void fixmenuwidth (MenuHandle themenu, int minwidth)
- {
- 	Str255 scratch;
- 	
- 	minwidth -= 27;
- 	GetItem(themenu, 1, scratch);
- 	if (StringWidth(scratch) >= minwidth)
- 		return;
- 	while (StringWidth(scratch) < minwidth)
- 		scratch[scratch[0]++ + 1] = ' ';
- 	SetItem(themenu, 1, scratch);
- }
- 
- 
- /*
-  * doshadow
-  * Draw shadowed frame
-  * Also in sldef.c
-  */
- doshadow (Rect *rect)
- {
- 	FrameRect(rect);
- 	MoveTo(rect->left+2, rect->bottom);	/* shadow */
- 	LineTo(rect->right, rect->bottom);
- 	LineTo(rect->right, rect->top+2);
- }
- 
- 
- /*
-  * dotriangle
-  * Also in sldef.c
-  */
- void dotriangle (Rect *rect)
- {
- 	int i;
- 	PolyHandle poly;
- 	Pattern black;
- 	
- 	for (i = 0; i < sizeof(black); i++)
- #ifdef dangerousPattern
- 		black[i] = 0xff;
- #else
- 		black.pat[i] = 0xff;		/* ... should use qd-> */
- #endif
- 
- 	poly = OpenPoly();							/* should make permanent ??? */
- 	MoveTo(rect->right - 16, rect->top + 5);
- 	LineTo(rect->right - 5, rect->top + 5);
- 	LineTo(rect->right - 10, rect->top + 10);
- 	LineTo(rect->right - 16, rect->top + 5);
- 	ClosePoly();
- #ifdef dangerousPattern
- 	FillPoly(poly, black);
- #else
- 	FillPoly(poly, &black);
- #endif
- 	KillPoly(poly);
- }
- 
- 
- /*
-  * trimstring
-  * Trim trailing blanks from a string
-  */
- void trimstring (char *cp)
- {
- 	int n;
- 	
- 	if (*cp == ' ')
- 		return;
- 	
- 	if (!(n = strlen(cp)))
- 		return;
- 	cp += n - 1;
- 	while (*cp == ' ')
- 		cp--;
- 	*++cp = '\0';
- }
- 
- 
- /* changing passwords doesn't work presently because :src:lib:kadm doesn't
- compile.  kadm doesn't compile 'cause SOCKET_STREAM isn't an available socket
- type in macsock.  I'm not even real sure this is the right way to change
- a password, this is the only example I've seen yet
- */
- 
- #ifdef KRB5
- 	krb5_error_code
- 	k5_change_password (
- 	    krb5_context k5context,
- 		char *user,
- 		char *realm,
- 		char *opasswd,
- 		char *npasswd,
- 	    char **text);
- #endif
- 
- /*
-  * kpass_dialog
-  */
- void kpass_dialog ()
- {
- 	int s = 0, ok;
- 	short item;
- 	GrafPtr savePort;
- 	DialogPtr dialog;
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 	char *reason = NULL, username[256], realm[256];
- 	struct valcruft valcruft;
- 	Str255 scratch;
- 
- 	PositionTemplate((Rect *)-1, 'DLOG', DLOG_KPASS, 50, 50);
- 	dialog = GetNewDialog(DLOG_KPASS, (Ptr) 0, (WindowPtr) -1);
- 	GetPort(&savePort);
- 	SetPort((GrafPtr) dialog);
- 
- 	/*
- 	 * Set the draw procedure for the user items.
- 	 */
- 	GetDItem(dialog, KPASS_OUT, &itemType, &itemHandle, &itemRect);
- 		//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 	SetDItem(dialog, KPASS_OUT, itemType, (Handle)gdooutlineUPP, &itemRect);
- 
- 	/* preset dialog ... */
- 	SetWRefCon(dialog, (long)&valcruft);	/* Stash the cruft's address */
- 	bzero(&valcruft, sizeof(valcruft));
- 
- #ifdef KRB4
- 	/* preset initial user */
- 	khipb.user = scratch;
- 	if (!(s = hicall(cKrbGetUserName))) {
- 		c2pstr(scratch);
- 		GetDItem(dialog, KPASS_USER, &itemType, &itemHandle, &itemRect);
- 		SetIText(itemHandle, scratch);
- 		SelIText(dialog, KPASS_PASS, 0, 32767);
- 	}
- 
- 	/* get local realm */
- 	klopb.uRealm = realm;
- 	if (s = lowcall(cKrbGetLocalRealm))
- 		strcpy(realm, "");
- 
- #endif
- #ifdef KRB5
- {
- char *ptr;
- 	GetDItem(dialog, KPASS_USER, &itemType, &itemHandle, &itemRect);
- 	SetIText(itemHandle, "\p");
- 	SelIText(dialog, KPASS_PASS, 0, 32767);
- 
- // Get default realm
- 	if (krb5_get_default_realm(kcontext, &ptr) == 0)
- 	{
- 		strcpy(realm, ptr);
- 		free(ptr);
- 	}
- 	else
- 		strcpy(realm, "None");
- }
- #endif
- 	
- 	retry:
- 	
- 	ok = 0;
- 	do {
- 		/* 
- 		 * process hits in the dialog.
- 		 */
- 			//  IH 05.03.96: PPC Port - Replace Procedure Pointer by UPP
- 		ModalDialog(ginternalBufferFilterUPP, &item);
- 		switch (item) {
- 		case KPASS_OK:					/* ok button */
- 			ok = 1;
- 			break;
- 			
- 		case KPASS_CANCEL:
- 			ok = 2;
- 			break;
- 
- 		case KPASS_JPW:					/* jump to password */
- 			SelIText(dialog, KPASS_PASS, 0, 32767);			
- 			break;
- 
- 		case KPASS_JNEW:				/* jump to new */
- 			SelIText(dialog, KPASS_NEW, 0, 32767);			
- 			break;
- 
- 		case KPASS_JNEW2:
- 			SelIText(dialog, KPASS_NEW2, 0, 32767);
- 			break;
- 		}
- 	} while (ok == 0);
- 	
- 	if (ok == 1) {
- 		GetDItem(dialog, KPASS_USER, &itemType, &itemHandle, &itemRect);
- 		GetIText(itemHandle, username);
- 		p2cstr(username);
- 
- #ifndef KRB5
- 		/*
- 		 * If user put an @ in the username, ignore the realm, otherwise
- 		 * tack on the realm. 
- 		 */
- 		if ((strchr(username, '@') == 0) && realm[0]) {
- 			strcat(username, "@");
- 			strcat(username, realm);
- 		}
- #endif
- 
- 		p2cstr(valcruft.buffer1);				/* password */
- 		p2cstr(valcruft.buffer2);				/* new */
- 		p2cstr(valcruft.buffer3);				/* new2 */
- 
- 		if (strcmp(valcruft.buffer2, valcruft.buffer3) != 0) {
- 			doalert("New passwords do not match");
- 			c2pstr(valcruft.buffer1);				/* password */
- 			c2pstr(valcruft.buffer2);				/* new */
- 			c2pstr(valcruft.buffer3);				/* new2 */
- 			goto retry;
- 		}
- 
- #ifdef KRB4
- 		OpenResolver(0);
- 		s = kerberos_changepw(username, valcruft.buffer1, valcruft.buffer2,
- 							  &reason);
- 		CloseResolver();
- #endif
- 
- #ifdef KRB5
- 		{
- 			char *text;
- 			// Change the password from old to new
- 			s = k5_change_password(kcontext, username, realm, valcruft.buffer1, valcruft.buffer2, &text);
- 			if (s)
- 			{
- 				SysBeep(10);	// change password failed
- 		        com_err (NULL, s, "while logging in.");
- 			}
- 		}
- #endif
- 
- 		if (s) {
- 			kerror(reason, s);
- 			SelIText(dialog, KPASS_PASS, 0, 32767);		/* hilite password */
- 			c2pstr(valcruft.buffer1);				/* password */
- 			c2pstr(valcruft.buffer2);				/* new */
- 			c2pstr(valcruft.buffer3);				/* new2 */
- 			goto retry;
- 		}
- 	}
- 	
- 	DisposDialog(dialog);
- 	SetPort (savePort);
- }
- 
- 
- /*
-  * Routines from Apple for hiding passwords
-  */
- pascal Boolean internalBufferFilter (DialogPtr dlog, EventRecord *event, short *itemHit)
- {	
- 	char key;
- 	short start,end;
- 	struct valcruft *valcruft;
- 	unsigned char *buffer;
- 	Handle h;
- 	int i, len;
- 	char *cp;
- 	long offset;
- 	unsigned char scratch[256];
- 	int editevent;
- 	
- 	valcruft = (struct valcruft *)GetWRefCon(dlog);
- 
- 	if (((DialogPeek)dlog)->editField == (KPASS_PASS - 1))
- 		buffer = valcruft->buffer1;
- 	else if (((DialogPeek)dlog)->editField == (KPASS_NEW - 1))
- 		buffer = valcruft->buffer2;
- 	else if (((DialogPeek)dlog)->editField == (KPASS_NEW2 - 1))
- 		buffer = valcruft->buffer3;
- 	else
- 		buffer = 0;
- 
- 	start = (**((DialogPeek)dlog)->textH).selStart;	/* Get current selection */
- 	end = (**((DialogPeek)dlog)->textH).selEnd;
- 	
- 	/*
- 	 * Preprocess events, looking for edit events.
- 	 */
- 	editevent = 0;
- 	switch (event->what) {
- 	case keyDown:
- 	case autoKey:
- 		if (event->modifiers & cmdKey) {
- 			if (((DialogPeek)dlog)->editField != (KPASS_PASS - 1))
- 				return false;
- 			switch (event->message & charCodeMask) {
- 			case 'v':
- 			case 'V':
- 				editevent = EV_PASTE;
- 				break;
- 			case 'c':
- 			case 'C':
- 				editevent = EV_COPY;
- 				break;
- 			case 'x':
- 			case 'X':
- 				editevent = EV_CUT;
- 				break;
- 			default:
- 				return false;			/* unknown cmd key */
- 			}
- 		}
- 		break;
- 
- 	default:							/* not key */
- 		return false;
- 	}
- 
- 	/*
- 	 * Handle cut, copy, paste events.
- 	 */
- 	if (editevent) {
- 		switch (editevent) {
- 		case EV_PASTE:
- 			if (!buffer)
- 				break;
- 			if (start != end)
- 				DeleteRange(buffer, start, end);
- 			h = NewHandle(100);
- 			if ((len = GetScrap(h, 'TEXT', &offset)) < 0) {
- 				SysBeep(3);
- 			} else {
- 				cp = (char *)*h;
- 				for (i = 0; i < len; i++)
- 					InsertChar(buffer, start+i, cp[i]);
- 			}
- 			DisposHandle(h);
- 			buffer[(*buffer) + 1] = '\0';		/* terminate string */
- 			strcpy(scratch, &buffer[1]);
- 			hidestring(scratch);
- 			setctltxt(dlog, KPASS_PASS, scratch);	/* update display */
- 			SelIText(dlog, KPASS_PASS, start+i, start+i);
- 			break;
- 			
- 		case EV_COPY:
- 			SysBeep(3);						/* can't copy hidden field */
- 			return true;
- 		
- 		case EV_CUT:
- 			SysBeep(3);
- 			return true;
- 		}
- 		return true;						/* we handled it */
- 	}
- 	
- 	key = event->message & charCodeMask;
- 	switch (key) {	
- 	case '\n':							/* Return */
- 	case '\003':						/* Enter */
- 		/*
- 		 * If return, check to see that the password has been filled
- 		 * in. If not, jump to it unless we're already in the password
- 		 * field.
- 		 */
- 		switch (((DialogPeek)dlog)->editField + 1) {
- 		case KPASS_USER:
- 			if (*valcruft->buffer1 == 0) {
- 				*itemHit = KPASS_JPW;
- 				return true;
- 			} else if (*valcruft->buffer2 == 0) {
- 				*itemHit = KPASS_JNEW;
- 				return true;
- 			} else if (*valcruft->buffer3 == 0) {
- 				*itemHit = KPASS_JNEW2;
- 				return true;
- 			}
- 			break;
- 
- 		case KPASS_PASS:
- 			if (*valcruft->buffer2 == 0) {
- 				*itemHit = KPASS_JNEW;
- 				return true;
- 			} else if (*valcruft->buffer3 == 0) {
- 				*itemHit = KPASS_JNEW2;
- 				return true;
- 			}
- 			break;
- 
- 		case KPASS_NEW:
- 			if (*valcruft->buffer1 == 0) {
- 				*itemHit = KPASS_JPW;
- 				return true;
- 			} else if (*valcruft->buffer3 == 0) {
- 				*itemHit = KPASS_JNEW2;
- 				return true;
- 			}
- 			break;
- 
- 		case KPASS_NEW2:
- 			if (*valcruft->buffer1 == 0) {
- 				*itemHit = KPASS_JPW;
- 				return true;
- 			} else if (*valcruft->buffer2 == 0) {
- 				*itemHit = KPASS_JNEW;
- 				return true;
- 			}
- 		}
- 		*itemHit = 1;					/* OK Button */
- 		return true;					/* We handled the event */
- 	case '\t':							/* Tab */
- 	case '\034':						/* Left arrow */
- 	case '\035':						/* Right arrow */
- 	case '\036':						/* Up arrow */
- 	case '\037':						/* Down arrow */
- 		return false;					/* Let ModalDialog handle them */
- 	default:							/* Everything else falls through */
- 		break;
- 	}
- 	
- 	switch (((DialogPeek)dlog)->editField + 1) {
- 	case KPASS_PASS:
- 	case KPASS_NEW:
- 	case KPASS_NEW2:
- 		break;
- 
- 	default:
- 		return false;
- 	}
- 
- 	if (start != end) {					/* If there's a selection, delete it */
- 		DeleteRange(buffer,start,end);
- 		if (key == '\010')
- 			return false;
- 	}
- 	
- 	if (key == '\010') {					// Backspace
- 		if (start != 0)
- 		DeleteRange(buffer,start-1,start);	// Delete the character to the left
- 	} else {
- 		if (*buffer >= (VCL-1))	{			/* if buffer full */
- 			SysBeep(10);
- 			return true;					/* eat event */
- 		}
- 		InsertChar(buffer,start,key);		// Insert the real key into the buffer
- 		event->message = '';			// Character to use in field
- 	}
- 	
- 	return false; 							// Let ModalDialog insert the fake char
- }
- 
- 
- void DeleteRange (unsigned char *buffer, short start, short end)
- {	
- 	register unsigned char	*src,*dest,*last;
- 	
- 	last = buffer + *buffer;
- 	
- 	src = buffer + end + 1;
- 	dest = buffer + start + 1;
- 	
- 	while (src <= last)			// Shift character to the left over the removed characters
- 		*(dest++) = *(src++);
- 	
- 	(*buffer) -= (end-start);	// Adjust the buffer's length
- }
- 
- void InsertChar (unsigned char *buffer, short pos, char c)
- {	
- 	register short	index, len;
- 	
- 	len = *buffer;
- 	
- 	if (len >= (VCL-1))		// if the string is full
- 		return;
- 	
- 	for (index = len; index > pos; index--)	// Shift characters to the right to make room
- 		buffer[index+1] = buffer[index];
- 	
- 	buffer[pos+1] = c;		// Fill in the new character
- 	
- 	(*buffer)++;			// Add one to the length of the string
- }
- 
- 
- void hidestring (unsigned char *cp)
- {
- 	while (*cp)
- 		*cp++ = 0xa5;			/* bullet */
- }
- 
- 
- /*
-  * setctltxt
-  * Set a control's text
-  */
- void setctltxt (DialogPtr dialog, int ctl, unsigned char *text)
- {
- 	short itemType;
- 	Handle itemHandle;
- 	Rect itemRect;
- 
- 	GetDItem(dialog, ctl, &itemType, &itemHandle, &itemRect);
- 	c2pstr(text);
- 	SetIText(itemHandle, (StringPtr)text);
- 	p2cstr(text);
- }
- 
- 
- /*
-  * readprefs
-  */
- void readprefs ()
- {
- 	short rf = -1;
- 	Handle h = 0;
- 	
- 	if ((rf = openprefres(true)) == -1)
- 		goto defaults;
- 	
- 	if ((h = Get1Resource(PREFS_TYPE, PREFS_ID)) == 0)
- 		goto defaults;
- 
- 	HLock(h);
- 	bcopy(*h, &prefs, sizeof(prefs));
- 	
- 	if (prefs.version != PVERS)
- 		goto defaults;
- 		
- xit:
- 	if (h)
- 		ReleaseResource(h);
- 	if (rf != -1)
- 		CloseResFile(rf);
- 	return;
- 
- defaults:
- 	bzero(&prefs, sizeof(prefs));
- 	prefs.version = PVERS;
- 	goto xit;
- }
- 
- 
- 
- /*
-  * writeprefs
-  */
- void writeprefs ()
- {
- 	OSErr s;
- 	short rf = -1;
- 	Handle h = 0;
-     Rect *rectp;
- 	Point pt;
- 	GrafPtr savePort;
- 	
- 	if ((rf = openprefres(true)) == -1) {
- 		doalert("Could not open preferences file");
- 		return;
- 	}
- 	
- 	if ((h = Get1Resource(PREFS_TYPE, PREFS_ID)) == 0) {
- 		if (!(h = NewHandle(sizeof(prefs)))) {
- 			doalert("Could not create prefs handle");
- 			goto xit;
- 		}
- 		AddResource(h, PREFS_TYPE, PREFS_ID, "\pPrefs");
- 		if (s = ResError())
- 			doalert("Error creating Prefs resource: %d", s);
- 	} else {
- 		SetHandleSize(h, sizeof(prefs));
- 		if (s = MemError()) {
- 			doalert("Could not resize prefs handle: %d", s);
- 			goto xit;
- 		}
- 	}		
- 
- 	/*
- 	 * Update window position
- 	 */
- 	GetPort(&savePort);
- 	SetPort(maind);
- 	rectp = &maind->portRect;
- 	pt.h = rectp->left;
- 	pt.v = rectp->top;
- 	LocalToGlobal(&pt);
- 	prefs.wrect.left = pt.h;
- 	prefs.wrect.top = pt.v;
- 	pt.h = rectp->right;
- 	pt.v = rectp->bottom;
- 	LocalToGlobal(&pt);
- 	prefs.wrect.right = pt.h;
- 	prefs.wrect.bottom = pt.v;
- 	SetPort(savePort);
- 
- 	HLock(h);
- 	bcopy(&prefs, *h, sizeof(prefs));
- 	ChangedResource(h);
- 	
- xit:
- 	if (rf != -1)
- 		CloseResFile(rf);
- }
- 
- 
- /*
-  * openprefres
-  * Open CNS Config Preferences resource file
-  * return rf or -1 if error
-  */
- int openprefres (int create)
- {
- 	int s;
- 	int rf;
- 	short vref;
- 	long dirid = 0, fold;
- 	SysEnvRec theWorld;
- 	HParamBlockRec pb;
-  
- 	/*
- 	 * Try to find the Preferences folder, else use the system folder.
- 	 */
- 	if (Gestalt('fold', &fold)  || 
- 		((fold & 1) != 1) ||
- 		FindFolder(kOnSystemDisk, 'pref', false, &vref, &dirid)) {
- 		if (SysEnvirons (1, &theWorld) == 0)
- 			vref = theWorld.sysVRefNum;
- 		else
- 			vref = 0;
- 	}
- 
- 	if ((rf = HOpenResFile(vref, dirid, prefsFilename, fsRdWrPerm)) == -1) {
- 		s = ResError();
- 		if (((s == fnfErr) || (s == eofErr)) && create) {
- 			HCreateResFile(vref, dirid, prefsFilename);				/* create the file */
- 			if (s = ResError()) {
- 				return -1;
- 			}
- 			/*
- 			 * set finder info for new file, ignore errors.
- 			 */
- 			bzero(&pb, sizeof(pb));
- 			pb.fileParam.ioNamePtr = prefsFilename;
- 			pb.fileParam.ioVRefNum = vref;
- 			pb.fileParam.ioFDirIndex = 0;
- 			pb.fileParam.ioDirID = dirid;
- 			if (!(rf = PBHGetFInfo(&pb, false))) {
- 				pb.fileParam.ioFlFndrInfo.fdType = PREFS_TYPE;
- 				pb.fileParam.ioFlFndrInfo.fdCreator = KCONFIG_CREATOR;
- 				pb.fileParam.ioNamePtr = prefsFilename;
- 				pb.fileParam.ioVRefNum = vref;
- 				pb.fileParam.ioDirID = dirid;
- 				(void) PBHSetFInfo(&pb, false);
- 			}
- 			/*
- 			 * retry open
- 			 */
- 			if ((rf = HOpenResFile(vref, dirid, prefsFilename, fsRdWrPerm)) == -1) {
- 				s = ResError();
- 				return -1;
- 			}
- 		} else {
- 			return -1;
- 		}
- 	}
- 	return rf;
- }
- 
- 
- Boolean trapAvailable (int theTrap)
- {
- 	int tType, numToolBoxTraps;
- 	
- 	if (theTrap & 0x800) {
- 		tType = ToolTrap;
- 		theTrap &= 0x7ff;
- 		if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xaa6e, ToolTrap))
- 			numToolBoxTraps = 0x200;
- 		else
- 			numToolBoxTraps = 0x400;
- 		if (theTrap > numToolBoxTraps)
- 			theTrap = _Unimplemented;
- 	} else {
- 		tType = OSTrap;
- 	}
- 	
- 	return (NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap));
- }
- 
- 
- /*
-  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
-  * Should be at end of file.
-  * 
-  * Local Variables:
-  * tab-width: 4
-  * End:
-  */
- 
--- 0 ----
Index: krb5/mac/kconfig/kconfig.h
diff -c krb5/mac/kconfig/kconfig.h:1.1.1.1 krb5/mac/kconfig/kconfig.h:removed
*** krb5/mac/kconfig/kconfig.h:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kconfig.h	Sun Mar 16 20:22:36 2003
***************
*** 1,220 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- typedef void *queuetype;
- 
- /*
-  * Resource ids
-  */
- #define ALERT_DOALERT	128
- #define DLOG_ABOUT		129
- #define DLOG_MAIN		130				/* main dialog box */
- #define DLOG_DEDIT		131				/* domain edit */
- #define DLOG_SEDIT		132				/* server edit */
- #define DLOG_KLIST		133				/* credentials edit */
- #define DLOG_KPASS		134				/* password change */
- 
- /*
-  * Menu resources
-  */
- #define MENU_OFFSET 128					/* offset to real menu id */
- enum MENUS {
- 	APPL_MENU = 0,						/* must be first */
- 	FILE_MENU,
- 	EDIT_MENU,
- 	NUM_MENUS							/* must be last */
- }; 
- #define MENU_SUBMENUS NUM_MENUS			/* first submenu in list */
- 
- enum FILE_MENU {
- 	LOGIN_FILE = 1,						/* login */
- 	LOGOUT_FILE,						/* logout */
- 	PASSWORD_FILE,						/* change password */
- 	LIST_FILE,							/* show credentials */
- 	S1_FILE,							/* --- */
- 	CLOSE_FILE,							/* Close Window */
- 	QUIT_FILE							/* Quit */
- };
- 
- enum EDIT_MENU {
- 	UNDO_EDIT = 1,						/* undo */
- 	SPACE1_EDIT,						/* --- */
- 	CUT_EDIT,							/* cut */
- 	COPY_EDIT,							/* copy */
- 	PASTE_EDIT,							/* paste */
- 	CLEAR_EDIT							/* clear */
- };
- 
- enum MAIN {								/* main dialog */
- 	MAIN_REALM = 1, 					/* realm static text */
- 	MAIN_L1,							/* realm label */
- 	MAIN_USER,							/* user static text */
- 	MAIN_L2,							/* user label */
- 	MAIN_LABEL,							/* title static text */
- 	MAIN_LOGIN,							/* login button */
- 	MAIN_LOGOUT, 						/* logout button */
- 	MAIN_DMAP,							/* domain map ui */
- 	MAIN_SERVERS,						/* servers map ui */
- 	MAIN_PASSWORD,						/* change password button */
- 	MAIN_DNEW,							/* domain new */
- 	MAIN_DDELETE,						/* domain delete */
- 	MAIN_DEDIT,							/* domain edit */
- 	MAIN_SNEW,							/* server new */
- 	MAIN_SDELETE,						/* server delete */
- 	MAIN_SEDIT							/* server edit */
- };
- 
- 
- /*
-  * D/S EDIT DITL
-  */
- enum EDIT {
- 	EDIT_OK = 1,					/* ok button */
- 	EDIT_OUT,						/* button outline */
- 	EDIT_CANCEL,					/* cancel button */
- 	EDIT_E1,						/* edit field 1 */
- 	EDIT_L1,
- 	EDIT_E2,						/* edit field 2 */
- 	EDIT_L2,
- 	EDIT_ADMIN						/* admin checkbox (server only) */
- };
- 
- /*
-  * KLIST DITL definition
-  */
- enum KLIST {
- 	KLIST_OK = 1,					/* ok button */
- 	KLIST_TITLE,					/* static text title */
- 	KLIST_DELETE,					/* delete button */
- 	KLIST_LIST,						/* listing ui */
- 	KLIST_OUT						/* ok button outline */
- };
- 
- /*
-  * About picts
-  */
- #define PICT_ABOUT_C	128
- #define PICT_ABOUT_BW	129
- 
- enum ABOUT {							/* about dialog item list */
- 	ABOUT_OK = 1,						/* ok button */
- 	ABOUT_OUT, 							/* outline ui */
- 	ABOUT_PICT							/* pict */
- };
- 
- 
- typedef struct domaintype_ {
- 	struct domaintype_ *next;
- 	Str255 host;
- 	Str255 realm;
- } domaintype;
- 
- typedef struct servertype_ {
- 	struct servertype_ *next;
- 	Str255 host;
- 	Str255 realm;
- 	int admin;
- } servertype;
- 
- typedef struct credentials_ {
- 	struct credentials_ *next;
- 	Str255 name;
- 	Str255 instance;
- 	Str255 realm;
- 	Str255 sname;
- 	Str255 sinstance;
- 	Str255 srealm;
- 	Str255 pname;
- 	Str255 cname;
- } credentialstype;
- 
- 
- /*
-  * struct for list filter
-  */
- #define NNL 2
- struct listfilter {
- 	int nlists;							/* number of lists */
- 	int listitem[NNL];					/* item number of list */
- 	int edititem[NNL];					/* item number of edit button */
- 	ListHandle list[NNL];				/* list handle */
- };
- 
- 
- /*
-  * KPASS DITL definition
-  */
- enum KPASS {
- 	KPASS_OK = 1,					/* ok button */
- 	KPASS_OUT,						/* ok button outline */
- 	KPASS_CANCEL,					/* cancel button */
- 	KPASS_TITLE,					/* title static text */
- 	KPASS_USER,						/* username ei */
- 	KPASS_L1,
- 	KPASS_PASS,						/* password ei */
- 	KPASS_L3,
- 
- 	KPASS_NEW,						/* new password ei */
- 	KPASS_L4,
- 	KPASS_NEW2,						/* verify password ei */
- 	KPASS_L5,
- 
- 	KPASS_JPW = 30,					/* pseudo item to force password field */
- 	KPASS_JNEW,						/* pseudo item to force new pw field */
- 	KPASS_JNEW2
- };
- 
- 
- /*
-  * struct for password hiding filter
-  */
- #define VCL 255							/* length of buffer */
- struct valcruft {						/* for password filter */
- 	int flags;
- 	unsigned char buffer1[VCL+1+1];
- 	unsigned char buffer2[VCL+1+1];
- 	unsigned char buffer3[VCL+1+1];
- };
- 
- 
- enum EV {								/* edit menu */
- 	EV_UNDO = 1,
- 	EV_BAR,
- 	EV_CUT,
- 	EV_COPY,
- 	EV_PASTE
- };
- 
- 
- /*
-  * Preferences
-  */
- #define PVERS		1
- #define PREFS_ID	1
- #define PREFS_TYPE 'Pref'
- 
- typedef struct prefs_ {
- 	unsigned short version;				/* prefs version */
- 	Rect wrect;							/* position rect for main window */
- } preferences;
- 
- 
- 
- /*
-  * Junk so Emacs will set local variables to be compatible with Mac/MPW.
-  * Should be at end of file.
-  * 
-  * Local Variables:
-  * tab-width: 4
-  * End:
-  */
--- 0 ----
Index: krb5/mac/kconfig/kconfig.proto.h
diff -c krb5/mac/kconfig/kconfig.proto.h:1.1.1.1 krb5/mac/kconfig/kconfig.proto.h:removed
*** krb5/mac/kconfig/kconfig.proto.h:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kconfig.proto.h	Sun Mar 16 20:22:36 2003
***************
*** 1,71 ****
- /*
-  * kconfig.c
-  */
- extern int main(void);
- extern void mainEvent(void);
- extern int HandleMouseDown(EventRecord *event);
- extern int HandleMenu(long which, short modifiers);
- extern int doupdate(WindowPtr window);
- extern int doactivate(WindowPtr window, int mod);
- extern void dogrow(WindowPtr window, Point p);
- extern int handapple(int accitem);
- extern void about(void);
- extern pascal void pictdrawproc(short depth, short flags, GDHandle device, DialogPtr dialog);
- extern void drawpict(DialogPtr dialog, int id);
- extern pascal void dopict(DialogPtr dialog, short itemNo);
- extern pascal void dooutline(DialogPtr dialog, short itemNo);
- extern void updatedisplay(void);
- extern void setText(DialogPtr dialog, int item, char *text);
- extern void buildmain(void);
- extern void setdcellstring(unsigned char *string, domaintype *dp);
- extern void setscellstring(unsigned char *string, servertype *sp);
- extern void setrcellstring(unsigned char *string, credentialstype *rp);
- extern pascal void drawRealm(DialogPtr dialog, short item);
- extern pascal void dolist(DialogPtr dialog, short itemNo);
- extern void mainhit(EventRecord *event, DialogPtr dlg, int item);
- extern void klist_dialog(void);
- extern pascal Boolean klistFilter(DialogPtr dialog, EventRecord *event, short *itemHit);
- extern Boolean editlist(int dlog, char *e1, char *e2, int *admin);
- extern pascal Boolean okFilter(DialogPtr dialog, EventRecord *event, short *itemHit);
- extern int popRealms(Rect *rect, char *retstring);
- extern Boolean newdp(domaintype *dp, char *e1, char *e2);
- extern Boolean newsp(servertype *sp, char *e1, char *e2, int admin);
- extern void bzero(void *dst, long n);
- extern void bcopy(void *src, void *dst, int n);
- extern Ptr getmem(size_t size);
- extern int getout(int exit);
- extern void doalert(char *format, ...);
- extern int strcasecmp(char *a, char *b);
- extern int fatal(char *string);
- extern char *copystring(char *src);
- extern short isPressed(unsigned short k);
- extern void doLogin(void);
- extern void doLogout(void);
- extern void getRealmMaps(void);
- extern void getServerMaps(void);
- extern void getCredentialsList(void);
- extern void killCredentialsList(void);
- extern void addRealmMap(char *host, char *realm);
- extern void deleteRealmMap(char *host);
- extern void deleteCredentials(credentialstype *rp);
- extern void addServerMap(char *host, char *realm, int admin);
- extern void deleteServerMap(char *host, char *realm);
- extern void kerror(char *text, int error);
- extern int lowcall(int cscode);
- extern int hicall(int cscode);
- extern void qlink(void **flist, void *fentry);
- extern void *qunlink(void **flist, void *fentry);
- extern void fixmenuwidth(MenuHandle themenu, int minwidth);
- extern int doshadow(Rect *rect);
- extern void dotriangle(Rect *rect);
- extern void trimstring(char *cp);
- extern void kpass_dialog(void);
- extern pascal Boolean internalBufferFilter(DialogPtr dlog, EventRecord *event, short *itemHit);
- extern void DeleteRange(unsigned char *buffer, short start, short end);
- extern void InsertChar(unsigned char *buffer, short pos, char c);
- extern void hidestring(unsigned char *cp);
- extern void setctltxt(DialogPtr dialog, int ctl, unsigned char *text);
- extern void readprefs(void);
- extern void writeprefs(void);
- extern int openprefres(int create);
- extern Boolean trapAvailable(int theTrap);
--- 0 ----
Index: krb5/mac/kconfig/kconfig.r
diff -c krb5/mac/kconfig/kconfig.r:1.1.1.1 krb5/mac/kconfig/kconfig.r:removed
*** krb5/mac/kconfig/kconfig.r:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kconfig.r	Sun Mar 16 20:22:36 2003
***************
*** 1,91 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- #include "Types.r"		/* To get system types */
- #include "SysTypes.r"	/* get more system types */
- #include "kconfig.vers"
- 
- include "kconfig.rsrc" not 'ckid';
- include "ldef.rsrc";
- 
- type KCONFIG_CREATOR {
- 	pstring;
- };
- 
- resource KCONFIG_CREATOR (0,purgeable) {
- 	"CNS Config"
- };
- 
- resource 'vers' (1, purgeable) {
-     VERSION,             /* version */
-     VERSION2,			 /* 2nd part of version */
-     0x60,                /* beta */
-     BETAPART,            /* beta part */
-     verUS,
-     SHORTVERS,
- 	LONGVERS
-     };
- 
- resource 'vers' (2, purgeable) {
-     VERSION,             /* version */
-     VERSION2,			 /* 2nd part of version */
-     0x60,                /* beta */
-     BETAPART,            /* beta part */
-     verUS,
-     SHORTVERS,
-     "Program"
-     };
- 
- 
- resource 'SIZE' (-1) {
- 	dontSaveScreen,
- 	acceptSuspendResumeEvents,
- 	enableOptionSwitch,
- 	canBackground,
- 	doesActivateOnFGSwitch,
- 	backgroundAndForeground,
- 	dontGetFrontClicks,
- 	ignoreAppDiedEvents,
- 	not32BitCompatible,
- 	notHighLevelEventAware,
- 	onlyLocalHLEvents,
- 	notStationeryAware,
- 	dontUseTextEditServices,
- 	reserved,
- 	reserved,
- 	reserved,
- 	524288,
- 	524288
- };
- 
- resource 'SIZE' (0) {
- 	dontSaveScreen,
- 	acceptSuspendResumeEvents,
- 	enableOptionSwitch,
- 	canBackground,
- 	doesActivateOnFGSwitch,
- 	backgroundAndForeground,
- 	dontGetFrontClicks,
- 	ignoreAppDiedEvents,
- 	not32BitCompatible,
- 	notHighLevelEventAware,
- 	onlyLocalHLEvents,
- 	notStationeryAware,
- 	dontUseTextEditServices,
- 	reserved,
- 	reserved,
- 	reserved,
- 	524288,
- 	524288
- };
- 
--- 0 ----
Index: krb5/mac/kconfig/kconfig.sit.hqx
diff -c krb5/mac/kconfig/kconfig.sit.hqx:1.1.1.1 krb5/mac/kconfig/kconfig.sit.hqx:removed
*** krb5/mac/kconfig/kconfig.sit.hqx:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kconfig.sit.hqx	Sun Mar 16 20:22:36 2003
***************
*** 1,324 ****
- (This file must be converted with BinHex 4.0)
- :#fYMEfjQD@FZFfPd!&0*9%46593K!!!!!$Uj!!!"4J1C8dP8)3!#!!!kZA*-BA8
- #!3!!!"B!!!d!$'YMEfjQD@FZFR0bBm@$P!!6*,S!!!#!!!!!!!(1Cq#&r!!!!!!
- !!!!!!!!!!!!!!!!!!!!!-3-!!!!!rrrrre*68N0%Eh9R)3#VATi%V'1L!!!!EUJ
- !!!!!!!!`I3!!!!!jk`!!!!!!!!!!-@31!2@GAG'FE(DGZ9P(jACjGL[A[X%LE@[
- kRIbpcXc-@rHlH+bMQGb6qhi1Z,qe8eQpG%rB,fTjAADkm&q-Iq[LG9lTjA8HjBX
- Zh+$(0VZ@dmAip6lPQ@IAXEb9qq[EQ`GdeA80ZZblfJmhj%X%5L!C3,,*3h+3!%!
- M"b8('B%!(I$l66UP$+A8M5mVeBDrreY`rZG6YVUPSrf'YT@eAGeG,5YpL&KmcH+
- j64fp+dp6$Xiarp(cK@@r(p#HpJIHBRZFK&1R++05eaYPUXHi01#lkJVa9b"bQM'
- h[f6Cp'8cPTfhl(`hDSbDTXkjakIki,e9&8[8qib69DGa64lEp41#A[@2m&B%LZF
- fYlHdVT'B8e5hQQSXVG3)TkVaUPDYlMpKANGhcl5QMVA0EHdkXKii#r-ipDT"A3@
- FSX@Yc@[@-Z+c+RMF!!8#DUVUk+qJ!U(jLd,0+eCdYACh[k(#E0@N&J+VS!)C[NZ
- eUrZ,bKTAV'eV$h@hGYh8fSAU8Uj1N!$iMaYRUAZ-jV`qVYr9jq0U%0k*)rS8Uf[
- 9L8C9ri3V@VZ@YhCeG)F@0AGhVqrS@K'DZkUjI@@VS)68A@UkFCfV6%LY9Y29*rX
- $#j[Ak[LCL*qIMjqT6PEc%9mjYlHVUl@p*dp*SKF$DhNHDc%bFMQ`bKDfVKr&@3f
- FQr-i0kU*kK2!152%-``fGNTADmr'cYC36dF)fG"f`mDcN4(I9&@#1dlpVMV6Z0Q
- Y3LHU4R@QZV1rE%&(5r1DN!"NeVXNmQcJc$4ZlMIHSh(29TA3mFlqUS@Y2@#j1Y5
- ,C'Z(hZmk8H,pkN(e0Q0Prm5j#km*jA0RVT6YhUlQRVB1+5h)c'TMXPS3+&V3XE+
- YAHSBBL+)f4iS4Na(Eir`@3+q[fmmj1VdG99T"$`[m$jM6$BQ"5Td4SBkAHAp'YR
- iXPTPl![iN45k6Uj"4"mLLTYDel6fk!bp$6&h)5C`bBSfcIMVL0JpJ[X2L(Ma#1l
- ,L-Q0i-k&8YFB$r5IU3[S0*Bb*SBNjXJT&+i(JINA`*abM95XSFVhRe#05FJaURq
- Dm3RM3Q1R9p-m[e[6aL$$imDMVYG5*aQcMIlq3@&b56[bTD9e4@MjaY$FM5[EHlY
- $er4fGRCdpE"@V'eHh4TLpZUNV4fVXkZED*GhV'S2R4Qk[(G0@h2Y-BQ'a9V6fYc
- G'TTjiG8cDXGHfY%9kQPY@4AUeM62$E8L4GD%fR80QGVGfY,EeGDcXD&&e+KYk9K
- llYKId3Z"%!V9QP"i4ZL#'4H'CNir2c6MJZR6Dk(eH(@1#KKA'bPBdPrLE+%aALe
- 3PkV(M!H8N3qmlCm$2kJ$&kS9+QRmh9$JKhAJH$A@@'+mT2cj`#Mq&peldEhLI0*
- BTDTm6TPbE(MRZAm[8[)9+HVjlilU'#q@Ti"C!Ub5NDEaX[IZKBAfPNdZfPb$eUj
- GbNIldjp@IYShh+!#Y-mrAa@jcA!a8H!*dJCH#@hJPG)'hKMD`$Y"f+$I*K[JMD@
- 0L(,D`+ZJ$Ea+fX#V%YC+9C-em0j''hMMD#0b2'hJR8JEH#H*1NT0S$V!1jNfm#E
- 5"YlED30K%QhJR5)USNfNL[MAd!CHL$E`6U-0[-QdJA5kfrUI3EAKH`GYi*e*'hK
- Rd3EH&0V!1eZb3UPcQ"A`K'N$leaD`*Y+'hLeY)%h6D+9QXjSi-fJMBMcD!-2@NT
- qA%!EH"F+#k9qLbb!pdlD`+ZMMFLCY)(h,YV!ZdMB+M@,E)&h-@hJcDB0[(VD3'L
- J$Ea'88@T193&H(0Tipp%'hLAd!EHTE5"G*QSKrT#pB!hRcCL,UF0[#YS!fm"EH"
- G+5SVYC!!+X0c&@hJ,D)0[+YT!fmaEH"G)pQ!&ScC!,bPY"%4S3fmGp-#hRYS!qq
- p%UA8YB`#hQr6"YllD#2brE5"Yi`fm+i6G!a0L!kmCYV!@diEH#fdJE##0["DK59
- 5J#b"Yj)fm&E4aVq00["ZT!fNeD)''NDU!EbeY)(A6KZa(E5"edNEH1Y%0D@kU"S
- mhE5"ed-EH,fdJAF6EH#Y&h@9fN"eJEH40L)q3"Yi0p-'hLED`,Y&XJ!$(fB"m$E
- 6"PiIE84'D30[#bhJh5CH0$(d!Zp$Y)(hBGV!Zjdf%2TT!qmMJUV84iN+[)r4"Yl
- (D32[%l6ahdSE50Z%R9,Eb3ji[d-EH*qN$E`lD!0M"fhJh5NU+28TUJ$2AE5"GcG
- Yi%Rf!ZmcY)(hZk)@aNY8#hLr4aX4[dmEH*qM$EalD!2[$d49THkPUX#lMcE`lUH
- 0b$qN$Ec2d`EH(iRk5Me!pB(h)'hJ283EH&qJ$B3BEH$pX9K+IC%@m,j%'hKr3KY
- iIdSEH&qQMIpA"%fT2p-GQ[S2Y)(hjl5"peAD`2XDE@$pKE$LH!1Xi2N'EH$p*@h
- Jr49Yi(f60[!`+*Am'#"li$e-'a&r64YihkB0[%GS!qp[4#@P(U9+`0Y*'hL2d8E
- NIk30[,qP$Ebr%c9"NQS#lcZdJEHE0[$fd!E#il5"prHL1JBP&"eihk80[#GS!qm
- ID32[Hl5"p%rlpqYqpqQRaAlU'e!FjrX2kG(1$rVlaIlKq[9L2ledUGM20$@*rHc
- Nb@)29ZQKe(0+#D-I!BU-RPG+'2eB+@(dJP,#k%@PK"'kCf(dNP,##-0RBI36TB6
- 46dN+M2B*qDI9+l6"5&3$S`1d`5K1'iaHT3e'"fQ$d5(DB(5B0KJPpXY4bDIPU03
- hj#Mc)6NUh5p(CGE,8GQPFT69*%IP*XY4GT8FG[ljimd-Y&dFa4`#UAlm$([L0Z9
- ,U%35+8El-4@!T4,IBfcp$Q8N9#j4aJM[5q35KNUN90#,b#AmY*q!)q!'!1"T%VJ
- 8rf3bidmR%XPdaXRiNiM2+(mU%l0YTb`@04-)b*Q%I8SC+FYf5Q,4C#+4XCe-,S%
- X5ca,(JXrVAc*6#cY"#e3#@HbYZ9-LNA$4%m!*"9c($XD-8hJfP%ckTL@eQ"-&S&
- T-qIB+4J+BFq3!-rPRm*%,JYr,QNR&%#060K*@L"X*+2`aT)30CP)fcR(-"'(NTD
- fR@!fNE3G*aI01Ej-%Q'$SXeG5*+8jDLF(ED66U,)!YPNNXam+KQc%CK*qK2*&"4
- ATSd`+21X8R#$44UU42KRS'Kp*E3a35GQTab)iXXk1A#")%BbPR2mCM)CYT)qmL'
- bS+S8&)Q')lC6&!Y(N3%fJ'dYcq+lQGI3amLCGLS36S)2C!U,mP$5X*1@k&D5c$K
- 1*"P1DNS3TM)D4U*DN93iK9pB)S96EeiL-j!!#QHGE$DTK!0j&N8&c%iDb*C%)1G
- %k-`PJPi"5DRbSA+#,j0c!Y&8bM4c+4qS8MaGF`SBqdPl)fL$B$!ALCL`XeE5##H
- *T5b)NFiKAe3bQr#C6X3#p3R*9)S&`[fNGX%!3lG3JAG4&V46TTAbDmdF*UHG-T)
- SBN8Dq&95[iP*6XPcGX4[19BiNe3NMQ`+!KrjJ6+A+%fRQ$q*C)D&)jHf%Q2#-BY
- I*'(Q%"*P88KEF"ACZCKPTV1aNM36+j&)jjLLd9`'Q55&la"jVp@5Pd0b#pN*+(i
- X"LU#4$Cp)%kiA-*+RS#+i+36bDMMX(iC+6,1S1`',"$-Q%iJCkCBdK6U3fNbR%-
- T-a1Qc6TS*3k5lLfDVLqA4YdbFUQFC+kK-XLkQ)Rk#J&X+IFUQbJRh`c86U,kjPJ
- F**0M6XD-)P05Z56p+SZ-3B*NSAQ88S0C!#SP89",Fp%-5LA68Y5q@GF9!kQ"'Lb
- &3#@F"!Di##L9Y)IHk%$BPPKS0&!#8FKBQe(+K+jKQhCB@H#GYX-SjMP8EH!#'#j
- 8QA#B&4GP',8I'ZP#+H5lTBiIGSUc)!QG(0%Ca-H3!,M**&@*V),+B!$8-1XfbPq
- 5*&8fPj*UQJ8P1PcC`blV&"9*jT!!Fi,JJ*f3!1jK`L%"FaQR+#2LHR+cdMJT"A9
- -k#*YK"9QS3Fcc6#U+51E8`CjZN,6"Bb83VIJK&%JL)PQ!U8IU51X1`TTMZU3!+E
- FE&B5++-PXE3V0QNV3QHK@L!'%+fcL6p84$0"pX%XbJ+%dcUE+C!!YNJiCk1@XbB
- F(QSBr,Pd1TG&(8*,JIV*6JL9"Ce3"$+Kl*R5b4La-&XIYP%kNd!CGP(@c@,4@FX
- 4B!b,$09!3TF)"NZ%k0cVYQB"m-kJc[PM`'A#Uc6UGMT#'C,S4k3@a0Jr#'RSL`3
- b$GBXlG!TCIV"@TFda+$i)(9388%lV6X!PrC01Vf3!!0T&Fdi[U`C4U155f54ij!
- !MXQQP5k15HY!eL+aNBeSae(@ZX6BCLQl@&4YQ,Bc"S@+HF#k*&Q@jjd6hNC''L+
- ScEc1HX86e*1JRY28N82`Q'p+MY`@$&GbCJE+%$X$1ffKjRL9dbhEaEP)'MPPC9"
- lMC3dJ&"$PfdTRTB+T0MZfb)mT'1KX+!iH`2SBhU+jf8BNYj1"G0f,"V0TXfX@mZ
- NCGRNjMMD,44-%q8+#4"%CK-#I8Ke"KP(hGN!USL6`A!"1@3k%*!!"4`TE"l0Z*(
- 8Fp82TS!@3mCPh2SYl,ISP#Z"p-`[0P05C0#-S"+@jkLb0$JU%8(IMBB48V0K$+0
- R+C)Xq&AUHH*M2)$LJ,+)5JAab8R'#*,fYd)$G)FXS`'#SM%-1&RGJSHC@K!%#BL
- qMDdkfLD3!-(-!rTMh%*#KB,hZ[jHpP22dP`XKTm9ME$,!52*!641bXbJ38a6l6$
- D'3I6L"5Q&'c)aQ!ZJji9SMJC$&LN@I-M2@%D*K3eT$(1XI#")E5#@)J)fP+[`Qa
- A-@C3XF11cf*4F42[H[a65A38U6$'3KLPC&&'N`CU!a-PPaL([M54M+!cC4[%E%L
- P)Xa11afa8C2&#Z3b5&Pk8qP$MYq52XK,UpC2+E5!53$E+"B1UD1E-Xd5DE+Be4+
- 4MPTfl)4SQQfrI)PFXXK-4k2T9#+F43GYT5cm1A""Hj%bdP#5DH89chE54&S)KJ8
- -)i@K#VAR4-K1CM&U`23SJIi"%kT`X3`!U$@'3j+&1HRa*"m4iB5cX1f8(aNFc@B
- 0#f1QJ)`Bh&CXfGhXkc!c%!+8&3-2JB3I-bh+C($%K'P1-ThB$mijr,-b*5*8,Ka
- %9U8jVf(",89k53IT0Mrc2J9bGK,0(h"cm+L`%dBDSH&2Q&T*Y&`JqL,q+"%QFKH
- jQ6((B'kK1qq%9ZVpGf+XNF9BK91!R"iRS8P&N!$"h)-rJdQ!#CRScZL3!"`&4%L
- @c$'J+$C"$J8Al3-53[LjL6$l$TNG@SNd1Qk-b04"2FHd9-UGBriJ%C!!m@%fj8r
- ((-ZGamNBLI9K"a*A+I"'FEIKbf+b58m+(5@'U##J4b8)+G)M+$Y4iFj3me-T'b-
- &QE%D'@5U(F1mc,%LPR5T)Y251m%N+F6iIj9c9ifGJjdK06Saq)E66bG9b'QA4@*
- SA++"0'G((1HiJiG62SP`6-d6Ab!5"H")Je9#`XG(1C*2I"2k(*)*N!!@ScbUlTH
- N61NU2$DU2Nrj$L6LE[LpkV!S*9-cX2LFc)P&,iBGB0K*8A@I'Z[+k"U[r'T'2Ih
- (DXc3`2!VUYMef&"*UKN%ZJI,!RTfr4@P1U&H+TY"SE!bJBLE)#Mj)Z9he9Jc'SY
- &)jLk#IrpULbCa6JZ%BR*52N*94b1#HS,ULJCe80,6F$"($1+F5G#APC"iZPTZGV
- kNLVL3!aP-P'+2NXQfjaVM8NJTGfNrjkU3-H0&K408L`Q#!UT8iUa-ZDf%63V-VI
- qS4U,q3L'6`iU$*(hUQ#'94#Z0)3SeC4-Y&3Lr3%)5L("AP2k*ka8le@P`-qJi+E
- XG)B`Kj42)Z"k5[R$',&EQ%Bk&ZDB-[X(-G6J4-c"G#5GGDI[*4L(JP2%bETcrTG
- "%c-ReNLTPUqU%ZU%dQZRXTTQ59J%ccS4#F"N[f+[+X%!%e0cddjcTMKfC,b,$#j
- 'Z'jc6KXC$VrjCC(Tb$98H32$9Fc-X2%i!T!!%$DT,"!FP1Dh+-8F6)Ua*A,dbkJ
- !NK*0'&K)QCa`"%$cj'FPUNFP440L)beHLj)8-Xjl#CR&E03*)Fe0F6+55E-@TmD
- LYdNR'BqeL66D@BDb)+(lPe#d@'NR-3i4iA4'McI`T9&!f(pL1i"*(5N'0X,3fih
- &dJ4m#8aF(00-fK'132h!cU#j6@*XB#E#ZC5"fA2U41`pC!!Pc#NaHU#dLA8$%c0
- m)+,K5U!Q"-+*5-D8mT2&`"+6"-L)4%b"$-B"jkG4VX,JTD!TjD'@BFi+fGp&-KP
- 1JP3UNiN`Q"0N-j9!RirCI""4M%kLi8VkS)@3!2b*-LlBUeJPSUCYk9@,NT3G`m5
- 4&Fij'AXE6TBTBd9MQ+Fa+)C*JJ42d-&Tfm*Z#-Tq"#5b'"C"518(C$6$m8J5F*2
- 0Y"2&N!!-H*b"ff'1AKfXQQ!j)KE'd0U1B!KfGLC-a53)L30Zq0Z*+$TK$)N!$hI
- 13YI*iP%9a83mPdXPX#b!q3[TSMY&Bi%8jQj(80KLXM89`dI24jIN2fBf6K4P-aI
- $M!I92)DC%SXi9f5Ff-Q5meJ*L@(,aBiP4B`-4ai4k54HND`C`kbJSM)8'Sr+MeB
- (qF$UPFC%+XVmXm0RaM$'4lDi`Hcb'Cb##SNNQR0d(8M@V!Re($p+1EJ%1I!!5-4
- *91H`I##Je%4AVecBF@TMB9L3!*!!3G`a3@FNG3SZ#m8&BeG33jR&8J#MlH3%kJi
- IFKG$-dbL333Y2P,*NU@-6"3+RX#'9NL#ch6NLqHMLhU'`q!84G1,K!F[L!))p$F
- SPT!!(9-#Cc`5ad+fBf2#%MQb#5KPC42lP((4ALN-k-NRfAVF!e'4f&4'j!PM%8H
- bCJ+!X@5"%2!Y"&Y1c%kHJ'NiL&UbY'&"`N!'(TRXq-R(59CMAFF&"6GNLA"DJ*b
- )LAj-'mJ%hF"AA-`4J)8"N5BQ%T%KS#AP!PdGq"GLbBHc)e8-q5%m5UH6,0)G@a!
- D4$4#SqI#JJ66"NBi'E%YbTjb1@YT`5e'EK%4h)Y&N!#lfV4I'4HL&bEA+)CmeCK
- @)hhBkU#UHA42eR*K0N1f,)P$`CMZ#KfXNYKF&m(+",H9r+b-U#MFc3+jj(KG,d3
- @RHY##9d$D`kcL9TKU+IhQLJEQQ`XdFJ`+K01`BRk`""N-D%&NeTDP$DU*5,e!"C
- Nd$e`c`#c,"%T+!L5VG9#AZ38$m6"[+`-IBq*)&"h+q(*-9F+b8cbGPAKf!@91Va
- A-6'MBA3V99biN!#f+'*'81TB`F0MGB*k1@0&!LP'B&VNP+,+kQJ-6r@D'C2%iXJ
- (,ZD)&"X[bI2j`[,lGS"Rd(&3(Ha9L-8#*#l56Q0D)S!k@6J!&!DS*FiBADL%M*k
- -'`Sl!,,R3MP4-L4AG(b9jj,-ch*aMm1Z-SbCXk`!@K231SQEE23,i*!!*Y360HD
- G,k1"9L`b+9NEj)JAAK6H-+FFfI"B58J@-ZbB3$A)`8!VA')cjm$6YX2P5'U@#$D
- Pb%SE+cC-G`8Th(c"I*N'8bj&YA5qB1+DX@1a,*FBmYTJ#`Cee`V2aE"3#SM%TP(
- N[1)#M5L0MK9H`KbDSKS$5eS0U@IK8pN4k83KHGFP-XMi04Fq'keD4LKV,T!!JJR
- #GN5b*Zh'XTDkHBP*N9'(BC*8'9NL+FkNL)K-aPS#1@BP5j!!ip5H5Br*UBlNN!#
- CfiKfZ-`'M!9G-FA5@h1X04Qb$#E5-6CciA(XA'e4djA0balX+#)dR8PGRYF(Hce
- ))NjRfBC)INJ)TX`kr8!i*@A6MG@jcH6*S&00XQZ&NJ)'kGJ@%-*1[FecZ4U`b82
- Uc'"q5e%4+PaBC1U!)"K,0k9M44UGSbJjXpbC$9+(bb$P%@5%Bd-Z##U9j56@9T!
- !L9%LkEI6-FP0+e`02a28"P2JTU'N*-iB0)V-ef3+H`3*T&ika"i1%)8Dk@DhP"L
- 1SqaB0CBbU91'KUe6*4HH+M8DI&#@i-T%T&53!#`J-Nc9I"k5$UC1@!P&$eSQU5)
- D)Kf[cM(Af+paf8Ll2#%`9m#5Pe6Y#*hBHf*YcD5p*-D+"MTUk413!%P5%k@lBIC
- JkX8G&qaX4D*Bkr"6B``5!-N&h"Mk#[3hQA3Z'V14(#P6JM&MFB-Vd%eKJ"YMVE@
- c84ZYM3pc#6X4a(!q&m258blK5fEYBL35%JU`3BYc'!`r355'!JSL'BahZ)d)Aa%
- '$&D'DbJf+PF9ma8d+6Z9MD'q1fAS$,KdC%-M&NZ$9,#a&"l$RLiA5D$'B8*3%M1
- PFZEX#ZB,X`-qZY$)PFDd#-+j(%MX1,*)*cZ#K46ZVD"lUC*Z0*ZeN6U-cjPXD9#
- DpGBKYYhhlj8e%9[@5AaS#YQTX,NV!J6QDTQ`,j+@)1jVR*!!iQSENJL4U0TBi-!
- %-BapYb4'Q5VXMmJ%)5L,ZM$-m)PTc+0c&)i,4%JafIR&fL)BPQ&QKmj@)L*X@5-
- +L-8%PbV#9BZXY(TK-hd#1b)T'5B'8Z"HSh&)*JACU'LB,6L%B4L8#"[BR3TMNe,
- @@,MiJ#hr2p`V1bU(CA8%Q"KTBPX%1fGQ'0X3Q('@NJKq-Nl"V%[#1BC9XUA#jF-
- i&eN`jNbMV'%MaN6YLXX5Li8j'9C%8$qS(k'i&QM+FS[ZIM#(e0eLkK@dmU"p5!#
- 44++'AXk"6(IKrL(CLFHD#rpBPdQm,,[DLF28JM[a-Kl'`%jfT"AN'j0"qm5G&j4
- PfF6e2NiK*D2*mV$3-E@bf%H3!-l#NM`6"fS3-d#qP)JULc[2bLa"I@B[0P[LlY)
- -q!X2DTp0&X[-$Y2a4+P)iik[CD[h),ElXILH6"b3!#a#D8@ADl&P1JJ*pdRQ3@k
- pDB-PF9*#`I+K+ZI#XNJILq6#Vh!5a!c!%&FbPm3a5p6M)6Ah"I@RL@)p&mHkb22
- JP%(f&1P"qU[)i+GNcSGI4Q6P1)9Pl59UNdMqJ!,rpSZbY2-L19RUTc4P,IL`RNM
- VR4U'`N1'A%Lb3)iE4$m@hTCH)m%[LhLCQN1NEf(5V,lrBe8p2,Ch6G2EYU%P0b$
- SZ"I*a-@Up!$cbbdBFQ,h+ErqRP8RHQ#[E4Y`SmAEEA&AH(,Z,K'QKjK)C*%2Z6F
- f&5`erSh&"XT8@*C4Q'bUHlm21qeGhc!+N!!25R+iiJU)Zc5JI+NEL4mZeB!Xc,k
- X6NMEh8A5('QrkUlL-)kV+A(STe"ad*i`+q0%KfCkEmRPV61-Nhiel52#ihNKQ@%
- aB$Mf$"*I4eUMc`-@aXa#6#9`fFTC89a"!XRFldXZI@kC$#AE(q'H[DKk@LI@&eJ
- CQ!NUF4pZDq1U%IfI2jl$94aBRm+9Q+,)MrqG"c)`q*(bD2NIP'0[#(G@iPrqN5H
- M6pllT((Cq)`bQM0U3rR-m62((jrKjibrjAJ0a,hIpFFr)-Mm1rl'06#HIHh,f2R
- (,6kiHN!jd"&ECmV"'U'6`pr'A06NPTRF!SI5LbL04%6kZ"aQ+HkU-B,BD083SCa
- "A%D'bLiS6lVF8N#M(kd1#G'&'SqG0d0MHJaaUj&$E$)p0-)-[Fa6M%`V61*%)Gl
- h&b!E42L%(hIP`!pY28*)i3KP-MfX+3Y-$M"8*iIEqXL$`2b6'IpNDT!!([mkP,B
- 1ciJ21c5LT3Y&'J`L-kd8!A`)*2m#+iq1b)!VNN4d5L%K3kB),-*Tm+$iA6GciiM
- %185l%[-f,*H&cVEF+,VqMr!XL15a+D"lFF`VVBG1[Mc*%Di&Y),iH3$q039UT"c
- F$EA[Ra0!c!+M%3k[kcp59BjSiX)8Y$p+NjLk(V`P[Ik$TLikP%+A*&D$)q6)D"J
- 9DJrqQpS@pL"Xr(@pcXZ-(%23kaUMH8Ik%9%6Bf9k5epV**ke5LZPrk-#HpAZ0B@
- Iq6H&bBqi4a3@(&h5ha4BFr,%H5Z"53l8[$"#$-1NdGFF,@C(p-hU$ZGeEIqVa'M
- l4e,U[pFV)J`9dQ&"MKG3UkQ,KBY*hHY1Ab[@HI&hXR9NLm0'c+Z!@M(YdjTJZd+
- `lD%rPFqVVDY(1Yr0&FJ56-[M94Gf5eLSG[d8pNM644+D$*P6$Dr&N!"-*rRKhNk
- %R2J$P`[l6pbm"hki`mjjL[haQBcedJ1$-,&a+amSIY(e#NleGm(Y)2k2U$q'pH6
- a-AVr8lC+Zi$FSF"-!1be1lK+d*(VYpka0Gm`$d'mL06#h+`!XfS%TP![G)2,qU"
- VK0YV$rF8E&Lmm1%qJVd'l8)CN4XBSKj6DM(8e3lA[ha4+r1UPrb`L6NNc4'SSp9
- `T!MRSd5#$UB-UhD4e&&h5P*3*BmheUfdVM(+fp8qVl"Z@0iNh,P9N!#)i&)H,C*
- HkVa&qeJlPhAE`D1-efl9!F0G9+%h'"@T5'IAD18QB#EIN!"jl3@6DL4$A,SEQG4
- Hhh'8laYTkU(T@F9[NPNQ(i39kUfkRZ5R"KT1G`jH)5SS`Bb4,X),,fLZQij#rD*
- IS)6Qm6Y'JmF2X*&HTBY,&hYhCPEKCZrm4GahirVqBhGUZVE[lrrIVqS3CRV21Ah
- "H!MGbDf6AT')qVlCDYDTeb2LqGQ[U'T%e1$Y"jh"3B`4M,hIp%*#DY"JL,m3dQ!
- -+"hL8UP4IAi*-Ib$qh5%SB)$kRShiX4$UV,'Ti*p+P66CmqUX'br-a$AB3&9JF[
- L0`c1Y[f$YeE8)'cm)994-d(#i[(kH[rJl&-V$ZLS1NBCJaYQelK43Q(6F06XLMk
- AQFd`rq#Q)f(eEi3j0H9pEk*9$!b&RFS`%D*L%2)@`PajJ['KU)T6h5LrLH3ihih
- bQ`I8Z%1U[-D`M%(9l)T@[&m(+4ZAjcrXkEYIik[0DP1`,akAS(TELelIYlQ[aQ(
- He2MMXqXG9brRH@FJD+UD2UGqMq9mLf%P,bKI$G10MU$RU21lMZZ0[--&Zpi24r!
- &l-`@(a#l!TVphrVc$V4)0AX'N!$rPLVbih*FBcpkS%jd#J(-,%kYJk-Z,5K"2$(
- !6j6b@A$-GP(+J&,ZSTa*&$bP3P!QP@(PieC8X",#P#1d[!kN!(-'BA"j[F"-)-a
- dY%!6d0m!4IjPTMUG)(M2!N%#G5!9"1%kB+"d#-BN8dfee9R"8("EppGQhEcYpX%
- kYHRQEFr8f)GqZ1R@1+lm1#RiY96jKPQckcGXZKNX"#eHY[-E2lcKiKrZ$Y@T&br
- H@EjZklS$@q[@lEUjlb6rVSeEkrE[R&6hiX8$,YU'5A[I[R9[RENr9'IXR!QdhHY
- flUlVhYVGGrTY@pIYVYZpGp,-R6-pY&Q6p[U"9RHJ,irfm"$Dc&'d8fZ!jY69l4h
- 3D$0fVaZB,@LE[dfdJCTKY)T*3Ir@`EUkj`BR#&T0qEU"rB,@U0(@&p#Fi$YFY*F
- '*idPf[4b6`Q00MLN"0#fV[4rYVYZ`Q1$j4-H"GVQVHQ(GhpphFHlqajqrV2G@qX
- 1lRerhD1H%M9lpQlEXQ(@TSTY!bLQYaaiG[21PN&R%ZlVHrMj3qEQQNfc0QrGY1Q
- @38Z0aId"p30B+[$hG4i5Em1SYmrcPQ&[SKi$q1#!L3Z"MJ238Jhrm&L(lh(fHY`
- !1ZHJm-4Y99lTmkP3r&A6Mj(!(0@!@M8(PI-f-kH+$$cI3@h*U#QiZGFS35IZ+eA
- 0T5@9H%f&QS1#KkGpq&5$"p5A89-GGCDKRRrNLMmjZ&1G9PS58Sh0!h2HmmKP*pA
- YV$*fUSBIRAklHVj[5Y1k4mr0%XdahP&paS+UYddQf[@UmC1K15ZDjYhG0+I+0eN
- e9Tma,eUPTM6eEcQ[J$D[UPV3S%*eD%j6dlcY$4UYDZjMZ#kTUDP[bq3MD#(F+kF
- DhcBiTfR1YZee'Lhq`FZ-+U"ejY'#(TTG-K(F&0$k+`-Dc@KUJ"*f8iQ,GTC4kU&
- 99VP+0*CX(p&Ybi*qSTeVUj,imppqV2,JDAdKHh"LAf29`+bQaQ"PAH-fikqC%MY
- 9I'$,"Ch,!9D0K85NP+T%Kp#(!D#a6iF%'Sa+0"Di19G9l90MX8[Mle1$Q+#@lr[
- h)S"'1e#$!S!N9J%3,$QJhRC)P9CZS3KST0`BYRb9@bEA2IIYMj8d,Cc8e$PBYl&
- 5Gi+9d61DjTbai)llQbBhID352lHK0CE-QK1BY`0K8cDUI0JiBdP6ib--QehC2lM
- *#kY@r8d0Cmblij'Qd*6qbJB[V!TKFmkBeapi4(1ElP,HhMpVaVIlErI2RG5di8G
- e'al(`Z0a"LVYX4p[*1rEM%N8KJ@'ppq'rhC-",l8S)`(KrjIDV#-l9'IFCI2-(B
- %"U)lJU('(4[YLhH8$*bb)k"1ZHY(kT6YTr@GFYIJjYqlDe$GXMf%Q%&Pm!qIm6R
- B`ccj*hGS8)E4bEAUcr&%N!!qZH(pM-A[AYd#flKdm5@AbNXYS)H+cTqlm25#&hD
- `FG'L"IT#pH#LVYBE*&LG+mpXNB1PS+`aVV*a14iQ-[3k$SBD8cf3!#lKiZ%p'lL
- dE8fVIZ!)hRfL['H0A)@G52I&)[Q(R5a5U[+D94hV3h1l@PIJD5KYc@Zkm5S0Pe[
- Ch$8GH%c(Zp[D9h5X9qp'+EUk&km1ZGTl+BBmEm0PlFL,4!*,!B9-F!Riji,hHi!
- lYk0c)eiUSSV!(#mCLF!c&bre`&YCh%GTZ%r+m-l)9I0#N!!!bIb"XkLSU""!2ll
- AiLdFqJH"6hF*$L1dA`iL(-H,2jm!*EEYqS&r2N+mH2,$PFE`8immIeFa(Hq&$-@
- lrQ%"YAY)lb-ji+UHF)mEJ,X3H)-4r,KU6V+#)NZm)1JNF#'(iJNUrS5%``A2,ra
- (m3Tmk"F4#RJ!S*LMm80m'$q%j`VSk61D!UL,H1)(6ebH1)##&AFX2NPKMe09Sqd
- DekkUfEerhkipm9HY`9$Y2YK!p98iiJp0Slhl4q*hGZhHI`!fF8%-IZ*V2fcp**%
- p(Zqm"["8P1&!PiSpcX#!&9F9VeCCH*S)l&IM!`0la&pK95!HBmX+q#YUbZ)9fVm
- RV[ePCH)(6IUVV,MMqJ@[#XX(p$ZD6b%4'MEEIFEAM%H-*ibrHHkKNlqdmk(JJlI
- (eYpI%62Z0rl5f'a[aL,Q,mjQpL30Q`FETVp[b[*C0`D@VeLb!pq+*B()iF9r&RP
- LmH&PJFh@jX(0mFdQl*prV%R(IqLYq2q9dXFh1,Uh-r$X%`YcP',mLr!2p&A'!`e
- 9*B&3pH&J[(S(ZQ6jPeG@(kkUV#UTh9l9LAm$rr!hP112PTRr@qZh9rPQE+qkp4c
- mci#20[f-3lb0(KS0fI!I6dk*Nhm0T)#2ImapR3(m"hAXm4$qR#DjYFNlARhf6N9
- F2eh&1hZ1qA@KcI[h9&9*CIImU0p5NI0qDmp[r),r(AQ3!%b"hl-qRimdiDp"i(I
- LH--0Ap&#2dfIS`&Fr`&RP`B3ralR)'8rL1I0Z2(a%!QJ[FMMbkN32eD6!C!!MmH
- $+DaGH`k1aS-KNNIMLhmhhQH"%!p2cZi$KAJGX(r8lqSlP%$`Jm@`rerbmGIqSrR
- 1'M"8"0bXCi2%8k(,3F@!HrEJT4iMmEX%!2%SABcI*3!9C4838H)&S'+!@Fai6E'
- Ll0@ip&$54NNmr#l&iAM(mZ)&(kf8'krjaCdifM6')iZ!$6rD-iNAGX2aQPXHAl2
- 2mp2a"IkH1Tiqc0)i4(BmIXa5p*!!E"-,mA%F$apCLkC4HI(!1aCr&2mS[b(q$"h
- 5Th"dI1(mDrc4rK`l%VpZQBl1EBiH)"5'1+qIIidIa2PPr##'(N8r"d$mB"(aKfB
- caq*"m6J(m3Aqf+dHR3Z0kSG("HLd'Bhhp%Fiae-P*AN!0plc+Vk$CKKJ*"i[XX!
- $*L3H-kiMm4Kj15AFc#`-bD$6#$kSFFG4i`[!8Ii!b)F2ar13!$!H)C-2(iUA)i,
- SKaMa[)QIa(fflT%RiE`@MjZrp((cl#Lr`K')er'(%E,$m@p@Q#&q[iKhcrqTImF
- hL(qV[NX2m'BA-&VR[FPPrS`#["k[4jUrM"m'N!$i`M"4a`m"-)l$crci8Z),!!M
- 6mpmm`+L+1KjfJ8"qD[QriVh"lFrjkqRS52b`IT+@!MS52c4-r9Pm3CCIarqFrj!
- !YXId'idrT[prLjG65,lApIIQfe*cIS'[Pm*r'5m,clrJpaEq@rcrLhirdcq2qV2
- i0mja&1*rf3$Jq2'1!Jc+p9[J3[Lm8hJp@!#$8rI*Hd0(4hL))plM2dakM`Za4F5
- $E8)hd`a,(EUPD"TI9lELSlk2+f`4mm-!'ZY"3#eU`#iBYX%iZ6NkV(PM3ZYed[V
- 8(r-AQQhaeeG9(4VfFlBfiMp8raZri&mJ[AU"he@BMj)Qr$8)[%!QY+kITNaS!H$
- kVh21e`$LVbp-D0hir)3fMqp1D)@IF`J!qAM-cJkGAqp1D,ei-*3*EGjr)9l%K"!
- 26mk&eaALGF$58EqVle!#`3m@`rjrbFGIqip0D)frA4KaRTQhYf*#ADdUQefVbZH
- e1pB$25&BdkHSTRN$8aZF`r"F,Kkcdeq[(VLpXa6@4d2YUZ5HYP-DR*q)jfaDS89
- 6jcN[KPDT44,j8r$3AN4Vcp4&cMimIQlLDQ98Pc8SIlXbaMcH-2dL9E`3Lj,BD#V
- (2VZk([G16UY9iakilr+Q$Vc@#Yc'33AI[!(b1'm+G(Vi(rVHC5bjK*'c+U(D-`p
- m$,(ljXFleEbGmai*"4rri'Aa%M9eJ41IFaRip(GLCa'-5eF'[VTVq6R6LakrV&j
- 0Vh@HHIa5U(P(U'cl&jhibZTTY3iBe+[*CCpXG`l@'`pmk+Zl@KB"Ha+aEfJ!P`Z
- %#9jEJAImDFr-j5I1frR-lD(J#pZHkDXFec9pZp'PUY8cM5lZ4F,j-@Vae9dVP(2
- 6jE9U`XV+H4Y+kcVa5XB(VK1Ylkq[GC)2h!iV`qc5q9*CkrcdRKZC@r$mj*iE&qb
- I%(FHAEJXG0e9Z"CJiH2IDCbrN!$P55Vf#@0'p[dZ4L,KN9M&-fUR,jmaBjSfc`d
- p'*SaFqEjSD@e5fT$MEhG2@hYjiDkDYFhph4hY$IdpV4ZD1kZE9h4#`,M4`KJhE"
- MC9Fch`-i"KYkI1LGIZcGU,FFDhq,e%['Jr(bT8ZRmmD+bHl$mhVa9Vf2U#IbEeX
- FJqhMeFD5IYmbAQEa*+l1j,N2l`EmUY'54lP2r4DH)ECTj-f,TH"kYTSbi--FR1I
- YH'[MaFD'rR-@kFImB5m4Ea6Ff0(EKBFQkYFIcQmDfpbq)[rb3[eQa([`qXH['cI
- Sh8QM3Zd`DS`VhIFUAS8UF,hkG2m*"3BD9+e&j+ei99HTYa5CMlY,hD+qQmHr5ee
- RY)KhJVT%A@U8i"B-A1+K$jAV4(BBql!Cl$@eqL&q`k-a*VEA,([hIa$TlMiGpE0
- @1[m32q21qh'KS(61C)R,%Va@dAhJPcc%Mqhl812RF4,EppcV[q*pFJ25',aU`l&
- `Hb$fkRPIc%%IhTIM`fEl"!YAaS!DIlMLhZIBq$0`SS@Rr,Q"3'@3!"F+c1&3!qq
- Bd@41(!k8+h'%FI9`@%Ed+,D8kH$Q#@VNP1!HQ4F-A+d84-Up!*&,IJUq"U"qkI#
- %4E*!'0km-q3U"!F!CX"9$5A8!5F!QSBKpbMbkSRpN!!0H'aQ',&IEVUKKcrMGPA
- dpL@V@Z8jNL&jGQ0EGkLpSbGd8r1DYK@eh@r'pVDhVHYYa8-@hp[4LhF[EJbYDVk
- T0E5fS`Z2TX5#EULM[6A8h0ZcUU1Vl32bG-R3QYDE@YF!d+f)0r5Z@E-aY+iA('r
- BU#YMRQ6YpBYDZpDfGAF6Ge8chXrBfYSH`R*['erHL#hL(NM5"4S)KakplD[E1pD
- h&lMKUD-pc5dDaRdS)ai(LHGYYRAhi#'9(9felkHSE5M++rPiaP$($50BHFTi6@0
- R9`H8D&ha2pKGH%e(9pI'Fl@UAS'R8QhY,BKXEHNTX1RTfKKUASPA6r)"ML[FHG)
- ZBbRZV0Nfe*KX8a108rV(&Ck&1E6XV"((!['bNBG@6J(ZAaRhZB[B,LIaEJh1AGA
- @dV`5VHcr2QJbhIQA9UaS*&SrrP)Ir8K6IA5lF-c(KQ5+QQ+--jl`hJ5*mb'[baK
- jk'VdGcjijRD%62*AUh&0mjFX3'2a801#Ubj6aFD*LqE2AB+lIfkF2rHUK8$HfVK
- Jm4+d1*qCXl#*+q&IeV[XaMH[['6K8Z"mVkfPZ`lq$1`,P1'VKShYGYmjHX[G0kH
- YC3hMVS80(&pA5eX,(Z(TqqL#*["3[NrT(ARI[AL"CMIL[hM0r'X[JIhS08X@Rik
- iCjS@A)CHe2H6`MBmcQf5(lJH"ZH$D"89AkH(mf(HS@3X%pm@E1-VAkIiSZTL*0T
- jdU6K(C%S%p,Ia6%qJ3qM"-Q9Mq%'0hNp(V#jTUl[DEU0$9M4DTIVqq'6jeQ#+aE
- ALhl2jIF"q2$#2QN#NA@Y@TX2iC'UUJhhk1(dN@Z4hSR$'`'8DQ3rlQV3#SdpM-[
- a!Ml2G`AfpI1D64Q+Zfl)GhZ"da8bNhAMA'h%TcAB3Ym#D+Xa3QS""T`D)k5Z[+-
- 3KjHpjH1ZBRkjF9GpELJ1,phciKDG9BLl1Pb)@cbY%,G%[dY3iL,[,-4GHe&"XfA
- efUI3#cI,brhBhSC8#qkTCL%6hjGe945I[(C20l`Vh)SU[SQ&[&QT'qJ2dGFQA)X
- Del4fp44DJ4AbD0*3+qiZ+!6TGla+82!+D8&@"+i%6*&F`b#ZrmPJ#&cIc9#C4qY
- TDeRGfY2p@X$r"`!0$3PVBfpZCQPR,VAa8!(&Jj3!%b5k!!!!J!!!!!!"cQIJ)4S
- !!!!!!!!!!!!!!!!!!!!!!"B!!!!!!!!!!2rrrrp069"568e$3`%!V$aa3kb3!,N
- Z!!!+jJ!!'+i!!!+T!!!'R6K2PmN!!!!!!!!$"50%$L*b2dj8KXT-k8"6YhiBR!q
- ITLqQU3NjkIY6*cQTXc2FhGNC#$JSKiIm+jb1pmLb63'LbIF4PIqe4F!!P0Z*LP'
- CmA6IUaqDH$8S*JFF9ZNm3H2Sa-aDVS2c8L6D24hpND,TSpDi'4DQYV!"&VEI`JB
- +M,R#9U(B9YX`aGS+qM`j,HhRU1J!EGJJUl)T5iUmQIrl)IMpZh'$B8UkqIq3!*E
- dDlLHPPA*r+rfmHe%SRpkbALTiE!elQ)P686VprqrJ[[Ra`MR%ME4XG[KG*jlP1p
- ,4AqRbJS@mibe+c`-[IprqmSM`-[%9'Y+1M99LQPr$)+R@LThI0%j20*h2VSF@!X
- +&c[3F5,BFJim#JAPHhMhhfLe-94Xbc2M9h1pPqZDdFDP10H04B[lhR0)jE9jRq,
- c*eFHPPa+&RANFS"LCpd-98#-5jFZPG@BNShcTAeklm+PRM'#$l"bZAGT6"r+Q0T
- 5c9JkrKKM6RcKHj6iGbM&h&Jkm4KPKKkE2frTZ'-N@CEQ8'LS[XDP%ij3CX5N@)S
- [2H%)Td6A0Af$+I8U-#RR4CQP1ZI(p'rL3a"+&*%l10@p5bZ2%*`K8la+-q6"Bck
- Ul4c3aea69TCQG#dK+p`D(8SS-CG@&!3,ifN"!PBYk6*#`ZP6MB`XLiZ2H#*b1U0
- `jZFmmfqeV(j2-"1J&I[CrTi80i-f%)U`J2@,ihpCbPhA&b[FeErrMI)[chNY%mF
- #4mjj4p(a!YZbPHLCqbf@j,,M2`lcRE[DMNZ"BR+-brp'-Bcm4MQ5riebm[rf'd8
- lpKZ&hPHFlClq8Z'HY6"@B0)[#*@&aGX'+@Df-0l#TPUBdX*Q@jKDB)TA,%aMBHF
- XE)r!9'pCQ%*JDLXR+IN'bek6PF&,!M1%G@dMMjN-H9YP6AdI!!!-!-8mcd*!jhA
- f+cZ22+h"5QKj4LLRK0ZYV2-NE'3V2mTp1@(Nq-V`&*pX68j0+F%rEHfi%8k2Nq1
- %ND0pjj1RR$$bR2#6m$Gb6#AXM2#6m#HX)m`)2eXCH4Bj4MKj6XPaF[`T*mmbFZ`
- ))ja`-Q94J4[85HAdNKaEf@[F*mIN*q'%N`NR!dl'P(#!pB!!$J[i[!i[bR)!)F6
- "IaP#*8r#rr0`jiEr02JrL'DJ+Y#9pS#r54%8[k3Z2JMhN`IcbUbUh+k)dL&Alaf
- HKGCRJrTDP+CUc)[#XDcYfZhUVA[j1hC'UIrb-QY&TE00NfYE[GA*4Z6T)*UK(f1
- mT8PHp[[AH9j*6I+@A%@Sp0PV2&%4NccZGE"JNF'c-9ldUmYRNlad(TLm`FZSaHk
- S&G6JiL52Dr`@e#+$Pd9jSLL)c9,5U*J8UbrIj%&'F#lbcVj"%$Ff1-'E%iERF0D
- `NLLeF%9p`aT(j9,r)XG6cQ8ekjcVarNQG3DMEK#dCL!"N!#`le$6+$@lBFh'6Bd
- hUla'65FTL2L@kSIp3FhCR!SbNfUPe!bKAC0&1EJpa6@T0NUeBQ2p8@Q#bZ1q([R
- 8*LP+8*l!pTh,28P5RKilH"E$CI91Ia+eCY"DH9AcJX9[8D(@8fDYQ6'UiJrkEP(
- $TbpX0DPCP'V9r+e5UMp3kfQ6QXhF!"hbTpbJ2rV%(*1D3pf3!0lLR@MUZ"Yb+G8
- 19)qhUA@5E&,cU-[YEBUmh4qBE1d)04m9%kSSYhV!kIHT"A'r#XU%mrV1&DDEELL
- N9,[R0KDF0fK5Lq#()`,heA-l+md1&Bp3EcI@T-kN8iLp"BHAhqHm-8'08QG4DYB
- @Ip!VKcCTrX!YX%NY'Dhe,qH98QUZ3BAqDMIbb+61CKdbU$XNjFB`18+G-plAQdd
- bU@@BqR9rV&C&[6k)kZ)l)p5jY0C-Rk5e#DSDmNjick61SdQC+AKE25NRM&,RXe3
- 'kMqTl$$mHVFr#HS#5!FiaPEKIUd,fBc5([4hT&S82VERCc-TbpQ-)QUGEDRm$lm
- GH-kN9Y!1&Db6P#C*NGA9NZ#&H&K@dc,C)C66M6)XMFJ,PF4INCZT@6e1Je1(9X0
- G&SVXq)Amdl-049jd*(JR-T[4!)SF@3Vrje&Nb3"#hXY`9i-LlkdNQb@%)N'Ub9h
- e5r$D&Beb[b,1YSecK(Y4*15'[Z**U3VUFI30fmb@IYB0I8K$Acl5(kmKe!qm2,K
- aB4lUiDbV[(j09[MYT"r`RS,i)46CLrqKKkqj%)S1dhk'KK,m9lLd1MQSaITjj34
- XU8SIdTIcjFLQ1e#N`kJFDZRZKhY(JVm,kZr3&%(YLQ,qKDeG8@i$RP9"V`6qP3r
- I"#m2kXYYAG`U8Xqf",qEipF,39qli*-`2dIcK)4!LdI4&%PbLSjp29$(dcV9+r4
- +i"p+m2G`r"C"#F+mV@*q`Mq4N!#,qUHU,IkQirIqlqEXEN8@*9@9&HSIF(6RIUi
- S1QbTYlLjLi2R,CZ6Z6+ec5'(ET+QFJA2L'lQBj`E@56RFCm3HJcq+dQZa0rMh+$
- [c9`ahNrIP5Y6QcYbb(lPlecaQVQ"M`[HicZ5+b4hm0Y)b1JTH!VHMq3+I6qGela
- bEip-$YP'`0K5EkQrPbXGdk,PbZCBV[LJ%Q1HCEPbGl-@1r$G$B(@KhY2$h!1,K[
- f(fF8PL93e*NH"hQA4pqM$l*Ub(dqipQB,Q0k0Y2&6"FblR$iq)pAiAi@HrF#hM#
- "RX[Z5m-RIeX,HKkl6fIDbR3Ddpl`XIbMS(Pf2jrT+UCKId2d!UBAKNm1Gi*fX[Y
- bTLZB4NbAX$l93cBHIf-SCUAM4r-5Z3,[ZBq['PNla(e5k%MNbNG,cNl[N5ZN[j!
- !+m3(1!"'Ff9UpdV1A+BVp2ep2ZKM$SIVCc[QH$e6@h4bCM*GMR-$mTc(hj5!,X$
- I$i$1aPp9J-k!GkG!Cq)[1N"R89qLKAJ2#VS3lJG"cp2h0@5!YZS(E(Y"jqXl[eJ
- $1PhIppBhS%[dRCmr!,S8p)1JCi1Z!Td$lhm#R3[k)QM@AjK($YKHa3h9Gaeq*KU
- &$lUJ,[LfSaMdRX-m+Y*lq!MS19"(!A#1)M`,jBcli8phiBRY2cq-q@#q[R2JLZN
- (``GMIGf-'XN81MCRh2ZHJ4bb2ilR!I9"G)M8KHGL0YmDG8hY`XPCB&`mAK)Vi)H
- ZEU)[[9X"%9B(e4ade`A)a`cFTF13!)[flr&ZfVeHTE-PRA9@BZ&ZN!"mi&jc1V*
- 8iMHi+rm$!!!!$3)!!!%!!!!"&!!!!"3!!!!b!!!!!!!Q3!)!!+aV#P"bD@jdD@j
- R,QJ!!!!!!!!!!!!,Df0[EQCTCbjcDA3#!!!!8dP84&0*9#%"!2rrrrm!!!!!8dP
- 84&0*9#%"!2rrrrm!!!!!!!!!!!!!!!!!!!!!!!#XN!#RJ3!!2aN!!!&'!!!!+%!
- #!!#XD`P%CACTBf9c,QJ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!UjA"`!!"!!!!!!!
- !!!!!+8!#!!#XD`T%DA0V5@jTG#jS!!!!!!!!!!!!!!!!!!!!!!!!!!!!UjA"`!!
- "!!!!!!!!!!!!+N!#!!#XDaC'D@aP9(P`CA0"EJ!!!"!!,J!&!4X"J3!!!!!!!!-
- !!!!"!!!!!43!!!!8!!!!-J')mIJB2J!!!"`!-J!!8f9dC`!!!!S!!2rr!!!!!!'
- *-ra,m!:
--- 0 ----
Index: krb5/mac/kconfig/kconfig.vers
diff -c krb5/mac/kconfig/kconfig.vers:1.1.1.1 krb5/mac/kconfig/kconfig.vers:removed
*** krb5/mac/kconfig/kconfig.vers:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kconfig.vers	Sun Mar 16 20:22:36 2003
***************
*** 1,42 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
-  
- #define beta_v
- 
- #ifdef beta_v
- #define SHORTVERS "1.0b11"		/* vvv b */
- #define BETAPART     0x11		/* vvv b */
- #define RELE beta
- #endif
- 
- /*
-  * the release version
-  */
- #ifndef SHORTVERS
- #define SHORTVERS "1.0"			/* vvv */
- #endif
- 
- #ifndef RELE
- #define RELE release
- #endif
- 
- #ifndef BETAPART
- #define BETAPART 0				/* vvv */
- #endif
- 
- #define LONGVERS  SHORTVERS ", \251 1993 U.T. Austin, r.watson@utexas.edu"
- 
- #define VERSION 0x01			/* vvv */
- #define VERSION2 0x00			/* vvv */
- 
- #define KCONFIG_CREATOR 'RWkc'
--- 0 ----
Index: krb5/mac/kconfig/kpasswd.c
diff -c krb5/mac/kconfig/kpasswd.c:1.1.1.1 krb5/mac/kconfig/kpasswd.c:removed
*** krb5/mac/kconfig/kpasswd.c:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/kpasswd.c	Sun Mar 16 20:22:36 2003
***************
*** 1,216 ****
- /*+*************************************************************************
- ** 
- ** k5passwd
- ** 
- ** Changes your password in the Kerberos V5. This should have been
- ** part of the kadm stuff but we're forced to build a nicer API on top
- ** of the calls they provide.
- ** 
- ***************************************************************************/
- #ifdef KRB5
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "krb5.h"
- #include "com_err.h"
- #include "adm.h"
- #include "adm_proto.h"
- 
- static const char *kadm_replies[] = {
- 	"Operation successful",             	/* KRB5_ADM_SUCCESS */
- 	"Command not recognized",           	/* KRB5_ADM_CMD_UNKNOWN */
- 	"Password unacceptable to server",  	/* KRB5_ADM_PW_UNACCEPT */
- 	"Old password incorrect",           	/* KRB5_ADM_BAD_PW */
- 	"Invalid ticket (TKT_FLAG_INITIAL not set)",/* KRB5_ADM_NOT_IN_TKT */
- 	"Server refused password change",   	/* KRB5_ADM_CANT_CHANGE */
- 	"Language not supported",				/* KRB5_ADM_LANG_NOT_SUPPORTED */
- };
- static const char *kadm_replies_unknown = "UNKNOWN ERROR";
- static char errbuf[1024];					/* For response from kadm */
- 
- /*+*************************************************************************
- ** 
- ** get_admin_response
- ** 
- ** Builds into a static buffer the replies sent back by the admin server.
- ** 
- ***************************************************************************/
- static char *
- get_admin_response (
- 	krb5_int32 		status,						// Type of error
- 	krb5_int32 		nreplies,					// Size of reply
- 	krb5_data *		reply)						// Buffer of messages
- {
- 	char *ptr;									// For building the response
- 	char *end = errbuf + sizeof (errbuf);		// So we don't overflow
- 	int i;										// Index
- 	int n;										// Length
- 
- 	if (status <= KRB5_ADM_LANG_NOT_SUPPORTED)	// Is it of a known type???
- 		strcpy (errbuf, kadm_replies[status]);
- 	else
- 		strcpy (errbuf, kadm_replies_unknown);	// Unknown error type
- 	ptr = errbuf + strlen (errbuf);				// Point at the end
- 
- 	if (nreplies > 0) {							// Are there more message?
- 		*ptr++ = ':';
- 		*ptr = '\0';
- 	}
- 
- 	for (i = 0; i < nreplies; ++i) {			// Append additional messages
- 		*ptr++ = '\n';
- 
- 		n = reply[i].length;					// Easier to work with
- 		if (ptr + n + 2 >= errbuf)				// Check for overflow
- 			break;
- 		memcpy (ptr, reply[i].data, n);			// Add the message
- 		ptr += n;								// Point to the end
- 		*ptr = '\0';
- 	}
- 
- 	return errbuf;
- }
- /*+*************************************************************************
- ** 
- ** keyadmin_send_recieve
- ** 
- ** Sends a command to the key admin and reads the reply.
- ** 
- ***************************************************************************/
- static krb5_error_code
- keyadmin_send_receive (
- 	krb5_context 		k5context,
- 	int *				conn_socket,
- 	krb5_auth_context 	auth_context,
- 	krb5_int32 			nargs,
- 	krb5_data *			arglist,
- 	krb5_int32 *		cmd_stat,
- 	krb5_int32 *		nreplies,
- 	krb5_data **		reply)
- {
- 	krb5_error_code	kret;
- 
- 	kret = krb5_send_adm_cmd (k5context, conn_socket, auth_context,
- 		nargs, 	arglist);
- 
- 	if (! kret)
- 		kret = krb5_read_adm_reply (k5context, conn_socket, auth_context,
- 			cmd_stat, nreplies, reply);
- 
- 	return kret;
- }
- /*+*************************************************************************
- ** 
- ** k5_change_password
- ** 
- ** Bundles all the crude needed to change the password into one file.
- ** 
- ***************************************************************************/
- krb5_error_code
- k5_change_password (
-     krb5_context k5context,
- 	char *user,
- 	char *realm,
- 	char *opasswd,
- 	char *npasswd,
-     char **text)
- {
- 	krb5_error_code		kret, kret2;
- 	krb5_auth_context  auth_context;
- 	krb5_ccache			ccache;
- 	int					conn_socket;			/* Socket for talking over */
- 	krb5_int32			nreplies;
- 	krb5_data			data[3];
- 	krb5_data * 		reply;
- 	krb5_int32			status;
- 	char *				name;
- 
- 	*text = NULL;								/* Be safe */
- 	name = malloc (strlen (user) + strlen (realm) + 2);
- 	if (name == NULL)
- 		return ENOMEM;
- 	sprintf (name, "%s@%s", user, realm);
- 	ccache = (krb5_ccache) NULL;
- 
- /*
- ** Establish the connection.
- */
- 	kret = krb5_adm_connect (k5context, name,	NULL, opasswd, &conn_socket,
- 							&auth_context, &ccache, NULL, 0);
- 	if (kret)
- 		goto done;
- /*
- ** Check to see if it's an acceptable password
- */
- 	data[0].data = KRB5_ADM_CHECKPW_CMD;
- 	data[0].length = strlen (data[0].data);
- 	data[1].data = npasswd;
- 	data[1].length = strlen (npasswd);
- 
- 	kret = keyadmin_send_receive (k5context, &conn_socket, auth_context,
- 		2, data, &status, &nreplies, &reply);
- 	if (kret) 									/* Some external error */
- 		goto cleanup;
- 
- 	if (status != KRB5_ADM_SUCCESS) {			/* Some problem??? */
- 		kret = status;
- 		*text = get_admin_response (status, nreplies, reply);
- 		krb5_free_adm_data (k5context, nreplies, reply);
- 
- 		goto quit;
- 	}
- 	krb5_free_adm_data (k5context, nreplies, reply);
- 
- /*
- ** The new password is ok, so now actually change the password
- */
- 	data[0].data = KRB5_ADM_CHANGEPW_CMD;
- 	data[0].length = strlen (data[0].data);
- 	data[1].data = opasswd;
- 	data[1].length = strlen (opasswd);
- 	data[2].data = npasswd;
- 	data[2].length = strlen (npasswd);
- 
- 	kret = keyadmin_send_receive (k5context, &conn_socket, auth_context,
- 		3, data, &status, &nreplies, &reply);
- 	if (kret)
- 		goto cleanup;
- 
- 	if (status != KRB5_ADM_SUCCESS) {
- 		kret = status;
- 		*text = get_admin_response (status, nreplies, reply);
- 		krb5_free_adm_data (k5context, nreplies, reply);
- 
- 		goto quit;
- 	}
- 
- 	krb5_free_adm_data (k5context, nreplies, reply);
- /*+
- ** Need to send quit command.
- */
-  quit:
- 	data[0].data = KRB5_ADM_QUIT_CMD;
- 	data[0].length = strlen (data[0].data);
- 
- 	kret2 = keyadmin_send_receive (k5context, &conn_socket, auth_context,
- 		1, data, &status, &nreplies, &reply);
- 	if (kret2) {
- 		if (! kret)
- 			kret = kret2;
- 	} else if (status != KRB5_ADM_SUCCESS) {
- 		if (! kret)
- 			kret = status;
- 		if (*text == NULL)
- 			*text = get_admin_response (status, nreplies, reply);
- 	}
- 	krb5_free_adm_data (k5context, nreplies, reply);
- 
-  cleanup:
- 	krb5_adm_disconnect (k5context, &conn_socket, auth_context, ccache);
-  done:
- 	free (name);
- 
- 	return kret;
- }
- 
- #endif /* KRB5 */
--- 0 ----
Index: krb5/mac/kconfig/ldef.c
diff -c krb5/mac/kconfig/ldef.c:1.1.1.1 krb5/mac/kconfig/ldef.c:removed
*** krb5/mac/kconfig/ldef.c:1.1.1.1	Mon Jun  2 17:57:53 1997
--- krb5/mac/kconfig/ldef.c	Sun Mar 16 20:22:36 2003
***************
*** 1,165 ****
- /*
-  * Copyright 1991-1994 by The University of Texas at Austin
-  * All rights reserved.
-  *
-  * For infomation contact:
-  * Rick Watson
-  * University of Texas
-  * Computation Center, COM 1
-  * Austin, TX 78712
-  * r.watson@utexas.edu
-  * 512-471-3241
-  */
- 
- /*
-  * LDEF to draw text with tabs to specific offsets
-  *
-  * The offset is set when a tab (9) is encountered.
-  * The format is <tab>nnn; where nnn is the decimal offset 
-  * from the beginning of the line.
-  */
-  
- #include <Controls.h>
- #include <Errors.h>
- #include <Fonts.h>
- #include <Lists.h>
- #include <OSEvents.h>
- #include <OSUtils.h>
- #include <Packages.h>
- #include <QuickDraw.h>
- #include <String.h>
- #include <Strings.h>
- #include <SysEqu.h>
- #include <Traps.h>
- #include <ToolUtils.h>
- 
- /* constants for spacing */
- 
- #define kLeftOffset	2
- #define kTopOffset	0
- #define kIconSpace	2
- 
- /* prototypes */
- 
- void DrawSICN(Ptr theSICN,short left,short top,GrafPtr drawPort);
- 
- /* main LDEF entry point */
- 
- pascal void	main(short lMessage, Boolean lSelect, Rect *lRect, Cell lCell,
- 			     short lDataOffset, short lDataLen, ListHandle lHandle)
- {
- 	FontInfo fontInfo;						/* font information (ascent/descent/etc) */
- 	ListPtr listPtr;						/* pointer to store dereferenced list */
- 	SignedByte hStateList, hStateCells;		/* state variables for HGetState/SetState */
- 	Ptr cellData;							/* points to start of cell data for list */
- 	short leftDraw,topDraw;					/* left/top offsets from topleft of cell */
- 	unsigned char *cp, *cp1, *lim;
- 	unsigned short w; 
- 	int savefont, savesize;
- 	GrafPtr current;
- 	
- 	#pragma unused (lCell)
- 	
- 	/* lock and dereference list mgr handles */
- 	
- 	GetPort(&current);
- 	savefont = current->txFont;
- 	savesize = current->txSize;
- 	TextFont(geneva);
- 	TextSize(9);
- 
- 	hStateList = HGetState((Handle)lHandle);
- 	HLock((Handle)lHandle);
- 	listPtr = *lHandle;
- 	hStateCells = HGetState(listPtr->cells);
- 	HLock(listPtr->cells);
- 	cellData = *(listPtr->cells);
- 	
- 	switch (lMessage) {
- 	  case lInitMsg:
- 	  	/* we don't need any initialization */
- 	  	break;
- 
- 	  case lDrawMsg:
- 		EraseRect(lRect);
- 		
- 	  	if (lDataLen > 0) {
- 	  	
- 	  		/* determine starting point for drawing */
- 	  		
- 	  		leftDraw =	lRect->left+listPtr->indent.h+kLeftOffset;
- 	  		/* topDraw =	lRect->top+listPtr->indent.v+kTopOffset; */
- 	  		topDraw =	lRect->top+kTopOffset;
- 	  			  		
- 			GetFontInfo(&fontInfo);
- 
- 			/*
- 			 * break text at tabs, setting offset when a tab is encountered.
- 			 */
- 			cp = &cellData[lDataOffset];
- 			lim = &cellData[lDataOffset + lDataLen];
- 			cp1 = cp;
- 			w = 0;
- 			while (cp <= lim) {
- 				if ((*cp == 9) || (cp >= lim)) {			/* draw previous */
- 					MoveTo(leftDraw + w, topDraw + fontInfo.ascent);
- 					if (cp - cp1)
- 						DrawText(cp1, 0, cp - cp1);
- 				}
- 				if (cp >= lim)
- 					break;
- 				if (*cp++ == 9) {
- 					/*
- 					 * Decode offset
- 					 */
- 					w = 0;
- 					while (cp < lim) {
- 						if ((*cp >= '0') && (*cp <= '9')) {
- 							w *= 10;
- 							w += (*cp - '0');
- 						}
- 						if (*cp++ == ';')
- 							break;
- 					}
- 					cp1 = cp;
- 				}
- 			}
- 	  	}
- 
- 		if (!lSelect)
- 	  		break;
- 		
- 	  case lHiliteMsg:
- 	  	/* do hilite color */
- 	  	BitClr((Ptr)HiliteMode,pHiliteBit);
- 	  	InvertRect(lRect);
- 	  	break;
- 
- 	  case lCloseMsg:
- 	  	break;
- 	}
- 	
- 	TextFont(savefont);
- 	TextSize(savesize);
- 
- 	HSetState(listPtr->cells, hStateCells);
- 	HSetState((Handle)lHandle, hStateList);
- }
- 
- #ifdef notdef
- /* this procedure draws a small icon using CopyBits */
- 
- void DrawSICN(Ptr theSICN,short left,short top,GrafPtr drawPort)
- {
- 	BitMap iconMap;
- 	Rect destRect;
- 
- 	iconMap.baseAddr = theSICN;
- 	iconMap.rowBytes = 2;
- 	SetRect(&iconMap.bounds,0,0,16,16);
- 	SetRect(&destRect,0,0,16,16);
- 	OffsetRect(&destRect,left,top);
- 	CopyBits(&iconMap,&drawPort->portBits,&iconMap.bounds,&destRect,
- 			srcCopy,nil);
- }
- #endif
--- 0 ----
Index: krb5/mac/libraries/libraries.sit.hqx
diff -c krb5/mac/libraries/libraries.sit.hqx:1.1.1.1 krb5/mac/libraries/libraries.sit.hqx:removed
*** krb5/mac/libraries/libraries.sit.hqx:1.1.1.1	Mon Jun  2 17:57:54 1997
--- krb5/mac/libraries/libraries.sit.hqx	Sun Mar 16 20:22:36 2003
***************
*** 1,803 ****
- (This file must be converted with BinHex 4.0)
- :$@aTBR*KFQPPFbjcDA3!8dP84&0*9#%!!!!!P'B!!!&'2#e6593K!!3!!*4QFNa
- KG3)"!!!!&J!!$3d04e06)%a*BR*KFRNZYB1%!"-NZJ!!!)!!!!!!!FjRi%#'!!!
- !!!!!!!!!!!!!!!!!!!!!!!!`l!!!!!$rrrrr68e38Ne03d-"!+`mF81XN!#GE!!
- !#`S!!@-1!!!#Z3!!,DhrlVM!!!!!!!!!b1%M4!iLF[q8U!b9QG+"TQlp-$JI2Zq
- 9N3MVD1r9*Ah)pkG1--CeKVXl1`-""qA`ZR(hHf6CTJ!jBZ1)218@!303ELFU4QA
- 'dhf[IQMLeD#B(%jbCR5HS(&dBQBYem&j+4,YRSlq50(d8@[F$!Y6@pJ!#pY[B3-
- &aPaKUe"XUffBBQd&ICkFP[Cc9(5!0Qb3!&ACP#9&hXcrr4$mrYfi`6!PhIar5%[
- k09a2bkTNrPIlq(BLd6qpC,c8F0JDGl'5*U,eqrpI`IhcBi4c#C[Sf1e`1Xmpb[H
- PSVp6C5e@*RD&TU468k@BpXF4ikQ@bKeIG!k2p1i34%ri`X@d1*D*,HI!Se"3[SG
- hrie@'d2&YM`cD6AAHlQZ'@eFLR2G#,4f,PVFpcZ(9&kEpbNqIh,PBFQPC&&(,JF
- SGYB"%&fkZ-jJme,,`ri0K"Re@25Bkc(6-0r'T8ZAbQT-bFEjdMkpGq&5caM""eL
- jh,XdTJpP6'fTCL`GIi`a*ll`28Vm1j4LELbGH)`b3ir0RlGdh$'5,%Yc+$48Aq2
- 5#8FS-f*5,-@ARR#%8k,VQVl"P(S9Q*6cSXa5RI0MqMIa)3JPLXJGR1VHTC9(#-k
- 3!#PHT4Rbi$%IeAB1k'1Z+5Y,-lU@N!!9ESd1*C5B5bX+JSAap0,MmZ"-`j!!-[,
- 5*&Hj,XG'6%NdkJeR8c@bEPRFJm36NG-CK6-rjjPrUf9CHB+C!1h41hSAEMq&arV
- l8@EprC!!f[q`0#146KSTTIII$SM)H8X6HXJjeIReSUb!AX5IPEb"84hjN!$Yq0I
- $I2cXjbEG#iV*-5lrUm8`mU[P52jAbmPr3q"A#bX`GVD&U5aXZQf+BZ8@aP[B-R[
- q+(DIK5N&aQqd-,A!P2BPVV%`SiAY%CKkXS8T,#aXE!)D,+Y09Kl0!M1%G@dMMjN
- -H9YP6AdI!!!!$UYd5cXRjHGP`pMf1[26BTRAarCjXFl12Xr,VGmNVj@[1DL9VjG
- AUeIACCFfXB'pACkGMEcphU+TLlVMAEahSZ9qmpc'PY21@aciAI`b&hkCRGGj$6b
- "!!CG!"8qPUpf0SelK"qdII!*[(d%lL,l!!J%S!G3@!"!6F`EMBCG,TH#rcZkP0C
- 2irqpq$B9rlI![`YGflT'ip[Z,FG-'hPdX$AQL3Ap+RlJ(-TV'Zq0cHR3SZ1MkJ0
- j@KhM0HZmGYqi2r,'rLI29j3[aI2'[$AH3-jEqkhRqr9Z'Kq+YBiEle%Mqr6c@KM
- 2kr9iCrUV[+%QEh`J'2D[IAMY`hAhrSLI&'qV*%r9I-&SMHH2aD)aYqCT$I[92)r
- V(BMjrIp0lj!!I`iHpjEHM&I9Zj(cBUe[aQX$idA96I(Gc(JG868iqffpBj[MHp$
- iZ"B-Mqq)4BR@&9iMib&Hhp5[IRc)ifYAPNjBY-rLY6Ke(cRViJQ,*Rh#MUI"ipY
- 8eG-4(0rQMrKM`@c1026Q2#*l33pbUVa6EJ2X#XUVFqhZ@VekYE,UjVXRh2K,e$)
- ,aLShhEdMIVQ8N!#8@cpeUX[9GEAq2Q@%-U*ZTffAeZfdbh,qQ&2VGYTe([QGrPH
- hdhBMmIXer2F6dVprNImHhhDGPj54rAljFbjA%rQpDqKV0lZDkKj3cUjl6&QiaCP
- e1c`r"-c4q(d$IMmD[rq$mXbPMbR2,0"Fld"p9NpH-5J@mEQpd8JJ'SrX[6l'ZZI
- fI&XKYC`H1`2)Y4iee3DDS(j680r"U-fJXTUQMpfp)(#IS'l"U)fJYSAMI[ZpS+i
- 3e(VA3+l3f+*#Aa28!B`+KFB@&ET(8!Fb+K3D@e6SAN&YS2(SD[DfHYhHN!!DEdq
- rG@l2&`5eN9'E[+VE(p&LFp+2YDK0M0S5#%D#kN`hLTQ0A&#r)UM0#DSEq@%6YB9
- 4"`EF8$BEHk$H)DL$',84e'`X81SA"A9,ikeqEf[qV5Ce-)qKJ,X$A3I0L5'61S4
- 4'd$0#GXpppN@34eUk+ULr[)jZYiTU&XC#V%+1+[3P`9e'-mS#(,0(E2$04@[`cN
- 9[*a'S(j98,IQZ5(Lld*Zb'@8Z`9e"+HLZ[6k9G8GbP$0r,S0TmBm%9qd2IG@-lp
- ZbkQU&JY'fXCXSQl()kr,l`PPANUT+`9eHq4PR(VdG2,9aS+!'H8ld)V0eF*+$9*
- pf3VG*UJl-QSMqNeZjlhG#jIX,UJl#DT6YB'kKk$Zc+Na6jFEC)HkTk#q%j8$SC)
- H9'Zm6e5UkdU2S)jNe%'%LXGkSlk0P45S-`6eA5E9(mP3jppbUk$Z`UK0P0VQec*
- 4[[)i3Gf983G6DLLM%DJR#ZUlHkQf4XJ0c`VUHaLeQ9,E2D&d9BQhZJ9eYb3eU+D
- c!kLR#ZTlH3b4$NJZmKBZ19p3GcHT6Z3Y#$`RU(ZJ2X4Tm(TE2@UQ9#B+"34e6dC
- YpRTprS!R(Ni(,+KYJ[Sq4QfLe'K(YST+8[ILE`ei8CH(SlC)S)B%G45MYK#UmeU
- ,ZRH5LNV&VP&@KJAer9aA3NAIcG(9T)ifUDTr9TED,UMl#)A3J81jCbX8%G3a5DS
- @mI39p"CeAa&jE4fSfM+4Ce,(#Pe*jC[9eD51%fpYpmaTYD0m3H"&3Ge2[$@5Mk%
- 13GfI84X*0CZ'8Y3$a&YMISrG1J"ePU"q31JDmk[KcN`-a34eI*+UaE*869!r++*
- F$B3pECQFCe)r*(493m'1V+ja36h3T1BMVe03$a+kUPSdPXhP*[A$JYU&"P'@fL@
- S%cK9,GF0C`VU`6b'#,930j`PU)FNUEQk`D41j$&%U)@ki6a"2G5NjL22T"iQ&#V
- 8$@C015P*cG80*[9`%AQ&ZQ'qS"iKG#h8$5Ee52(@A0d`Gq8&J[S4mGC#h@"5Mq*
- e!k%@kJD6HV4iDk&ZZ&"3*`YG#h@$5Cf5T1EUKSX%p4J4jB@ki@*"R5Td,G30*[@
- M*M8IH5Ee@+&VS@i`UG-%Y9!h,"68kHKpNbM(9!c*bYNHfmhc"(8'Sl)19KB,kLF
- %p6K1T4eL[qC8!&F+k['F'[+46XrQYjkJ8fPr+%FeDj36G@VRZ&`i@056-!Q!Jpk
- maqI,K"$4GE'JISa4QaN9rHK-[&iVU#Fc+RVcRJiN25F2QG46HUP1(M+T(fI8&P$
- a8Y*PXc1P5A8RU(&YTXqMH@V88a24!#U'5rUM`C0mUpZEaPV89L-D[$1GF3p3Va0
- 8Va(PhPKfP#*&p6%UQ5`"09G&A5qSIN0A3XhTDVied%YeiY@NYKQ4"k!lj-YfE8f
- &CLDT@LJEVbBeD%3$RE$F&!fR'I%+GG`a*qHCe&![eFPj*M9Xa"$',eV$8@r)ML'
- 6fQj3`ai9dbrT$'Y4)iC#(Cj-RU68'`3eDX33D6CN*c"kU4e'pJ)eA5Lr3CePk%U
- SZBaL8Q-*DTI2RDX!6+TUC"4#c46,&P8cG&8pJAa(rdC"M4Y8c@ZRVMHSR8EN%@S
- ZPj[8,L-DY$BY@cYBe0N*DNLMe8f01JI6C6J$3aTUbYa%fXSPJRSkScD%Y0*8K%Q
- GbkM0)Ddd&@&5cf$8PT!!&SJj-i5J,KA8-aQe+D6&r1h46PXMLrS*rPE5Kd*#LA8
- 'lEGq5P$2BY4'+%3UFbI+2bfSmiaS32@9llqDe,-6d9$X[hj'8-m49(r%Cdm3@G4
- cK8*Y*23b#TR8mm4EfpaSLIB*De(20q)ei)liCc[GcCX&GEk)[%,(dD4H)"4bXS0
- &[6"*9D2TPU0&[8M%N!#UCNDh,1V&)KV)Z(Sf'MiVU!X%Y5Xr2f45,a'kGQ9EUD#
- D%fQABVk8k%Sk84M%ENqAf+!Z&p6,',@&8U-aRlq[S,HS#mfhUM&[Af&$U1Emkq@
- -fX6k20&dNje3c4R(+rKE@m1qA,8-UMQ6qNQZ+k1klIaP8DrNEd92bDeK@$6Ecc-
- R@DpLe%%Nk$bNFq$G',#JhL@SLlK##)414eK3cIRAU`eUaacDG-a8'bEe'N-K3Y9
- QHV@0B@j4&q[43+Pfq8USjUcYYDC#f9&XLhTGNTTTXeR8kdf&XZdALhS$cd18QT[
- 3A@R1pGjS+T529j0kNkQ3!"C-Yk))eA3X@++rYB2SNqXGQY5PR-S'-$0Y3)[kU35
- 96"'M9e'MITT6fGKQlUdpJ[UC",Ai9T0k-kF5KaCh$1f$6(9S8QrKe$D[1a$$c(G
- @)A-1qam5e-kJ*p-8a65`@D0m9UIk)k6V&FRQ221YYjV8H'YQ[VchVCrM'3@9Dki
- IMEIH,kLh'@r9-+Z8eA9"i(9"AFBc*Chfm'UcXjRbki,DcGr+hZP'5mU1KP@#qSq
- p9$33EDVTYr(jAUUDm30)8QrR90T9aPK%0MHBZLlRNBGj&$*U(fc,4*j*r3+M0VD
- (mN-(S(j$82q*4akSZ6Dl4EdMmGCFLaM8"`6eLicD!'Tf'S9565q@,jP8Zc1rM[V
- 222)B09ZAclr&p+@i-k&VVN@-Yhj,8,r-U!2KdH'd4!ReB8(p#PH)PRMC4JUSD`6
- eU`E9V88K8VU9#UVTJR-Aec@'qC!!A'lScFThmp`!DM%hI%G3ldQmYCJE(K(8HhQ
- 8JeV-$5Ee2T1Dc`hI&G392)BBPIJ)e(*$6d,AI'kBIi[Ck9QTaa#D0GR@4STk2kH
- UD0N@U'CrD*@JBS$!k3)q+UKIip'JaMVGc([,MJDcUr4e(JfB8mJdHYPEIbDShq$
- 8H#5I+bhU!ebK,NmBf6aAPjZq&0q%S`f*"JmUYUJll(3"Ib'S$c)Umfr)+JZU1@h
- r%+H#55CC`aQ(T#4e0D2@(cVPf),cdmUI#qUh'*9e+@CLSVU[4`cU,`AeBC1+`R*
- QTZpP8VqY8q2KX$Z)bD0-epDNVZ'4Khj$YR1iM[S[#DUl)aTcjJ"-kVrbb#28@$j
- H6HThZ+kN5d'$)90&r8T3(p'TlCUl2D3&Xr-0*[@lA#%mXTJEAK,8lc(U)0S4LF)
- rTkmTBP%Ij@q&TX36,fLlJ[95(p1TC$SR(d-[#qUr-@TM+)jaQ@LkhlL1qRhq9Nc
- ,HF,C%9L,qJ-HHB5UjEZ!*[@(LEH'h#3H-QrpYD$qL1[Dl['UpNJISClr`Y1#qMM
- 2AZJF"*c*AVce0i,k"+G'N!#(#K2`*[9*VLZK&UDhAa(8(r1h4Y9F8bP&r3Q2"T+
- 4af4'f928IqG[TG08lHUQYcjP8Zfqh$VUdc`DD'je`hBV%`f[#ZT2H8BKY6,+3bH
- Mr&C3Rq%+UC%aZB&+LrScVK#T'+)"RbIMGVEbGi,k,&FS(JRRdKHS[aI8rf$8KVL
- DU8mip3q#qKaAL'D6E-"f,fLV&p6RiIj'hSSU+KjdTT`A0N`9e*mc+R%lmf+%d*[
- THph[%Y3Aq&Y"pF9cr5%dSa28Am"T$QGJM&6cZFlFr3f#qL+M0XDmlYb3!#1SCM6
- m-N%PScDEU,pLe!C3I3&lfSY5"`MU5iDZEV['ip5"J[Vb"1SNfM!CNfqBTCbCTLj
- Ee,1#ZL'cmfY'E6aQfJc-SkNfeU,qKVre-0)ic%"6e&FBGH!NC,XX0%9pP5YdU,m
- c#,1q63VpPP-R4F1B4YY-r4fR(Ji['p*mYDPh[6j(8(r2U-h(BRS`(XYSC,he$cb
- 'TRPM`Bl-8r(@aP-%p6AqeZQ`YABLeRVVkccbTXFm'"rF((PVL8-f&!U0'aA%l*!
- !MHeHH02h%RP)JA8XTF*LQD4PQhVEkX(LVH"6+TRUB`k%IGcZKEZ+6UT5aa3D3,`
- pXV*DML$+1hJdS1dGL@Da81JZSG!@m)dPZV)+1aX0mfmj9Vbe2K%0i@"V,KVZ%fm
- GB&#*Cf3f0r3mr6&"(FLS!fKYQ)d'[,9(8"Yi0&",E#FhI1h`P`5eN89$2EaBR+F
- LmSlG6d4$%k-fJZVfYEEEC'58C`5eQ6[[aP62+1)CD92RpM`NU#dX0c4b"qRX@fm
- q9e"ereIL6qNN2Fa5L(kjXL9hhQ8+MA88%K-c#[GrVFGEmc'8p0"9Z2pV`T-eR5Q
- 6lUV+8$LP%S8`L8,YE$)+V6T58,G+C#p2,*Z(EPXpV&lNKQ'mLS*P83k,225SS!j
- RhU80m")GYHqBE(kGfp-Y&0VDm[M-k,Ub99"(F#VU"J*fU(j"hBC(3cMB(S6TJj2
- ,la'kEV[H6h3pZYG290NZj3aU4lRT$+TX[pk&Y1qY*R@(G4kI'arEkpDTl,M4KA3
- G'G56"(@RGFkJYEIZ[0'lG-0E6a(8Gc)IV(ViB"AbkmSc"(9N`MeV&'S(H'rE#Xd
- 9e(IaYm+VVrK@iEZTl-*VV`"QFm01lAAld-q,M,*V`KH`U0"TiUh[jV@Ah[R1e%-
- 0K`VUH`a(N!"F%@@j##LlT@Ed-pP,c+3UlqA4i0AQG$J&l,)Pi40&01c1hJUhDDd
- B$@+H8YRMVGk'H1ZHl+f0hV$I%d'M-PXhL-NYjAe-eaEH96TX9R`MZ,IlSZaPG24
- cXPVpFQ98EmFa'kpQae(CfqU*CR3eZj[+qj0pbNbmp[CIPG'm5a'2"'FlUA,Cl3Y
- q*U*K(ak[kK`e(-e@SYec9c`LU'0BcKXffH1G2R(Ua'KlHc3b(FR&+Yj!I9iSY#q
- M$Taak05TKq4dA5%QYj5aM$VNB1EKGN,BS`AACcj3Ra,8FB`kk(#r0RR1N9-*[+p
- L@b(FLjAphZTlL@MB(alV*+13!)j)`G2Z(2(@!aLeQ9*cFcDV6KE8$jM8V+ePpd8
- 0CPBHckM%PjfDiUIEmhLVF*Y@2XLS@e)UCJjSh,h""G@X+6pN+T3C1da4$l6k+*R
- jSFI0r(S3S`jQff5d)ceifYDr&p%J*[Z9$r1hBK#S-)@jDV+J6Z"8lUfiLAU`Q4Z
- b&4%8%T2LbL'TM*+QpQD8L8bKiHLLM&+$(DfML+e&,0JfXrI9PN+(-ZSJXC&(AkC
- FGC5J(XDSm"l3r*JJY#XLkkf6H!@!SZ(Y#Z"`AVm'8I%@Zqb#HJ6II-,VcNr0SH-
- SR"L8)aQebH[1c`*Ce)p`AbA-p-&3)HZ)[b!JTUQ8Sl![!ANVF3D&Y*PCf`Z['bZ
- S4c-U2)&JQk&Pjl$RVU`6e-Qp9-GRcU41-DPN4B!dGH&d-r+1kD9QhVT`aQ@#1T9
- 4'`JeeZFQc"8bUpk2kM%8KLN&XQ@QpPVL%p4M'E84TKiC-`!@Vf,Q@jR'&8+Kh*C
- fBPT2RFi9`Xa"EX3*e-F%G3DI!d!d&2TH+ei3e1-B&Fj2l53D-MfEKG1D"29i2Uf
- S43-"09ICQ*0fbJQm2i5F&r5%JkGRjbPr)UJR'Y2f-EFRleRbI8%p+I&@f#VPR)4
- q)+JI-pqDRbieU5HE9-G&B%&JVD#H)K6+ErZamJP"r6LMdVSK'`aiDjZBkP2F3L&
- rDpJHYX9EIbbSTiUhCQf98P52d,AJlf95@rN@#&6Ah#iGjQB'LTIhf!M9@E6#kR[
- j@(8iiZ!TdiiFZI[Bi"iM*qipFG,Nr3iiDQrX(@43PkhqR(!89[b-fR)NU9m$(Ur
- IC#A1XR120LZE!(rVC,Kd!FLH54pY[I@@a`@eM9'(66kH!Bq04fKTD6dC91([TFa
- Ne#(6MMaQaJNE&0@TRaAZG%U3!2@PYMl+(f[&J,Pk"+D#-DG(m5'c!VMBR0XiM90
- p3E@$Q+U3!*i$TN`m@MaT3i!CN4m*DJLEHa"G+EAGFaVD"fm`+G@-KM#M$QGVfG#
- AmY9[NPMd0Xi@e(C'(F+T'iMmV@+qA)N`DQ-dk-[l(5i)#"FF*FUSF,8-Zc(l%XL
- il[@Bde3GM$U)8-Pldj88U-+P3jR&UF5ed(QX4BhaD+"8VbF5MFb-VRGMX+JUScC
- 4DRBHf+*U*KA#CZZK"`8ecQ1)8V9Sb0rAhE$HfXRbd(#2eqZ(!4PkMU4NeP)q4*J
- &&)li5KGf3F(CdZ1G&3r'r,CC$a356N,+E%kP[S#JTPZ"8-MXBFmaU&3@Q-E9U+F
- ckR#I2qc(U,LMUh$I9qBbDM20VcQ(L4kc@hB'S`kLe!hjf+#DRB-cZ8,qfF5cB,0
- #Rf$8`F34K"KmTFhqVEHHaDK$439!'qi@ekS!jR&G1A8$N5XNGK&3cZE8B$[9eBi
- L+#5F6T4cH$4`UK-0BMm!j9a'(4+-q),8FD2Gleh[')1h#UF6j6a'hBVfPHfAdVF
- Z%06cG9dMXp*!rDh#Xd5CckMSfS+DYE5bU"I`2%5S*)!bRRBp`NG%)4Z!i@!55)A
- (4+jE*MbhP)Zi3U&aF5c5N!$K)KSZ%G5,H4kLZ`JJ3EMlpM3#eH`i,Q$8EI4YGBb
- FhPZZ@04,Z%+NcL[%N!$Ckle88*fK!iYk'D-fmTV5f5l)T#jNe!(jZ+14*cc5P-Z
- j3U6lSMUGZ38"i3UQA+'r0GKQpkrA8cr*Fd-qaQRNA5kS9c)UUbPchU8p`YY$Z5T
- **FD@0P9iHbL,H-kM90A[E%hdQU"HcE-bTpT@NaEe'PBVmhTSUY(FX(Uh9QpM-D-
- f-'TZVYHFLlSffhdaAp#lMB4bA9rhjBdCV+4#elqPN!#BTVU"9pKk0+4RXG$40fH
- 9EPaI(@kFBZN4AQ,+6@rT+K4DNUjI8r(D@lmZj6Q[%dm-C0U[M'93BA4`!UC,PQ,
- ,"5@K!2Y5kRJD-"rr--Pe"#BKEe)DPLe5EMfRJrfS$PZ0,9j$IpG-*b9[8QlY(%,
- [,Ial(Ep[`qpEmrX3GXII8Zc6X%kI8Qr9J1PEU$Rk*)-$qPK2U1[SkYJ38%`4SXq
- 'q#PfF3eBS+E2bDYJCr@mV3piA%0PMG!cVdqTAfc!f[VeH4,kV-&3hfTjJ$kPcV3
- "ihQaENVG&#Hq2i6rZq2r9+k2ZIhF'rSS%aq%cGB2k8rZK6FPj1!E[aRkP(CHXl)
- %jU6*"24CDj9h%)F5h"Z)0`IZpIKq(qi$L#m)lJ2a[3Ihd@5@&RH&Z+HFYGDePN`
- eihXMFHI![3RIRm%p5,VYZ0I4ZG'GP#f)PmQG8j8@I$rAjiFV*0QXEZJkrBU6D`E
- X#,Q#IVLrQmbbhr%Lda(IUBjh[1MkMHY9b,"05XI5,*d"1l*24pH[5Cf"qaq)C`p
- q4ceZ+[UkAQ0F3qHaC%EiVhU2!IpjI%rTVXF[REe+k&lDRLk4hH3+m4Y9Hr020+3
- d%iHA"jI#lC,Nf+e51TEfZ6-1jrjG4f83FB&j1cjY2G0a@GSdccKd&PbUN!"ANcV
- LRY+4kb(b5hlh2H23L9DTJijE3XF(4(kaG#aYifFFkPBNImJ[3XpdA*Ef"$31p6D
- 53X5PVL22%dCF&MFA0!le6C*"a+@YBfQA3Z03Rb4jJij26'!kJT[@XE6GSA(S6RH
- kMYiBda&hUL2Z9%IFUBki8aeaTcVL6RA%RHVSM6%GmChUL$[9%AHU)qj8aqd[CcV
- L6R9%GR0dc1fED"cU654rd((lbq%Ur"KN'*E5XE3"Sh(S,+`83-I"a,%XSDFb"0r
- aZcGeaIZTV[K1G8AH6qYDfY(41(56*jQ'VU8Y)Se$pm+48ZLUemqTqUDijk4aU%H
- &M%"Aq8#FPMD`0!l[BXXciV5d)kCaU"Z$9#*1XhNR[lfQFDJ(X94!clr(Tph[+1l
- 9D4cU8L"KU%ZAmlTd1Dq[b6B*I6S@0rdd$[8BNMrSZ2hb6*qJZ(ZSFDJ6NG4#aq)
- fT-DK2M&5#af,qjNDKml855ed,'k-DK`kVbHcd,'d`kTaYT01k-Mlq,U1TDeDME1
- p0%$(iF6VpUmk2SjG%NMea2[h4PiTl[PUR"eN!cVq25lC(!$dS2-Qd&H[pbep5a[
- *'SIXbbb9d$H[Cfe'DbGC42jF0`q8dV1iaDeaGTC'e!0krir2MaJk&[I+0Fil64e
- $A%IFYm(p(YbTRVK62A'RHZ*1pF5GkSRleX6&'RHUDiMVLHp86pbTRVK62A(AqdS
- M`-9D6Z[k5cr&lK,'"X8*A8ZElaTRT(4!efeaRi(lGVJIpaHGmChUM(ZrcYQ0FBh
- c,ZQ!cYYcIAI!r95TJ-jk[@ITA0SZf$Ll5!GdPJr%X6khDqPEfS2B1,Y+$r,9MVL
- IK2Y1FS'iISKXad'f,ZFl5lqKHcQ$[G[8AFb,8GhIRKZMZZ01maIZ1q01jTaT([X
- Imq9T[AIYX20BD3GPila(1U$hrp-h0BHpDf*1UdrIc,E-aYP0'T!!arjhRS+19&G
- pAJ&hAGGdRLVYmfbFpdS(iTEQCpaTIXDGjZFraI'APM+pRcL9jbQ9jqAP"EfVG59
- aNC!!816PKjEha6Ide[dVq2bTVRGTKfVMl*(1@j[ceArQUCFkQ(ki8rf1L0MkPED
- j0XkHdJIpp2kJT9pTVfcM[%qZS*qH2i)Vp(PKC56CQH(PjFSlF6rMj@`q+EUa'M"
- Zj#*,Q%YIGM[6mj%KZTj'(FIRQ)em8YcBfcKlTIAEKHclm,rQZAG&A*f'qlY`$fh
- @p6BHT`IcZ@i)NYDeY&1iF8E*)A3GXC6TqZdR0qQDf9lD1([,)A30RmKdIC6A"9P
- G5hZC'qIpFSPihDaVGSGQiib@9ZLUplFfj#&R4fhMl#1(d"9Ede#rS4CHTqTpJTD
- 1I*jeYZNfcKJjK,ir(m*dh5daajUVpjap[ifcVaa#efZj(pCdhIqLN!"RRBh%M60
- @$U'VhQqBXDD8CdZleKYRR$4#9jTRGAd2'pNIYmjfjmEC6`kKll)HTZZUd59G5h[
- V'fGr1B5Z,kaKZUjjX6pHRIhJM(1!(%*Ap9#Qkk#PrA@4Xm1lF6iJKp$ei(Qm$lC
- Cemb@mFBCEqSUqUe8errCGf@kiNjehGb(R6LDk6UlA$I3qYcCJpii(j4$k+VaH$f
- jA$I3r1TXDQmFiZ`TJG$eDPih22CQ(mcC*Gmi"mSKG*h,rDS3YlAmkQblEjb$j"#
- kZTUBVS[,HBMUkQadD*`2bb&deHIbK+lkr!Rh1c0daDC8rI-1%p+k5JVQ6r3mLM[
- 9$hFkIi)lR6qjHSfYC`[4XcERF,"N3mr+I--KXJ`pQiLHYEQ'LA)02DYe((U!%Se
- m8jYM1%bbS@GPEQ'5,%02@Ur9jK81PfVNcpUF3Y*rA(S4RlAjK+32ZI3L2Q[c#"q
- 4CHMC525Xc5%F*G@)cpVm`G&5MIaCQcZB,0R3Xc*[-%@U88rAjJb1N@VNcpTm`95
- jKTl9HZfM8Shm@CXR`!bV4%22fKc"01Q%RP0S"Uc6IFD0HTTXJHEXdQHFk4c+hff
- rKrPG94md`hU2lNH4HJrIT+pFm"mR9iLhqkHbH-0GRmq`i`(EYX+2TK)2afq+,qC
- [8hR2#C[IdcQZ2`'FQ)jAlZqZ[`Hqh+9940Jj5Di3VkXQm$RAK-p'@VpQTKqFH)X
- 5INbZS*mq$e64$hlERSlmR[ImR#bld+pFrjiLUp#["ISKqM,l$"VRic),rE$2ARC
- p2[fiC4AkNI`0rE$+46'"R#UjL$mhGT)Y#1L4@14[lmcDBK"*rbLCK(kSAjep[F6
- K!2Q%IQ3[#qKAQBrJqcj*+I)IdDq5rrJq82)+rFVe(pmA5NT42d'kc0,fLF2hLC)
- Pk,H#q`hJc[4V,1U(2I1+q[&pSf3*qQhl+Sqr8k[jQqlB@XlI38P$rLMVKrS2ZF-
- G+rHI6T0Gk&IZ2r%p+H86qU(q`,)(VGJ*bpliNjq`a%+rX%I&KKfP$Q#la#*rG$M
- ,TbC14&DK(qS2Ci06FD+b#[h)AM#aB'PB$iG[PLDPb(p%[dVrB*E-3VmZRlZ5!@1
- b#[h32b$k93E`9)P&rP-pJDSIY#Dad%rcPTXh1('*4Ie%p+[dAcXP&[PEDp1U2I!
- ZQB9qf$(9fFQB(lijS!4#2lj(P+lI`*!!K[QckUBVFf39qQ&Ar6Ipk%qA9HMA(0,
- Hp+1I+k[3V`@EK@2KjmSQDfI)+[4V#Q%Eq2CSCcQ$R#PTd#rKff[((r(b32XJeKN
- X+!K[@4Q$IS-5qZRl`I"p[ick&IQ$6-#@%rKCdJAphS-jpPZKhbBGNFFaL92eaCX
- RKp"ad1@fML5Ipr[KR5h&d0%ImC8hB6P(GU%Mc5YYT-!UjK@5Qq3AmGL@fc+BRr0
- N&cULAJbi)qR&PXec[Za#4eTheAbYjNXamNUYJVp!NU'M'LdC@9dSaDKA9,@bJ0"
- &dJJGGGqG$AQHE-aF5T!!&mX9G)5r$Y842Ved6`$FNr[d,"kGbIGd`hkY[,m8pMU
- @3X4P9NFDPeh9`Q@"(%*(#*!!brGG9H1k5d`Gj3GlVf$HQHVSc$mRYM6QH`c"[BC
- XjemD`,e8VU$Mb1%m$[Nq&mMcDIeDU(l4Q#qp6lpa,T-Vk+I[N964Mm@I'[-@adp
- F#k82qZPjd0+[LEQ24%[fY+l,rkEIEXKVGdS"G06Va93FYSCprC1X9k4eh1UfeF2
- UhpCc',ir+J(3-l'(A#S[-MhGj8lA*q85HS*VjdQia,Je,)YB+Kb[P$[N5E&RVDA
- I)&*LHFLFZVG3-&iPAG![fBI3ppj#r@lA@dMeRE9%Z8Mk%)GCr6VQ8-ZfBL+j@PD
- K(r))d8qEkG8+"HmeXJVpQTPqjA&,ef+j4IkSVV*lVH4#[iVPdh9bLra40FbiAPD
- KAa29VlTIj`ebLra4VIpZP&[N$beBXV["I[V5L[MV)0QMiRHf4&UK(eXYVf)BYP4
- QS4rCb"5Z!3Ap2L@Yd)qYZPH*[dr,,26VMlr25#[d#m6mIRF-3q[&HEHET3rkTIZ
- B,@eHGb#'IAe,qH-@@B"qbZlSqhpG9U"MCp"6-Ill"cQ%MZMcfrN%ZjX3pk&)U4r
- e@EP$2LRT&fmYGd4ZP9ASeia*bAi(eFp*,1*2`ciQP6aiQka#2qEhlp9QPrTTbk3
- 9mFGL$k1Ga5ALZf8AqX%%VD$I2mSZp&0,Hh4rAPUK(h8IKB&mU4krA9T42f%r"E,
- FG,#YQ-#A5arddrI%X[4VE!qpD3$qKE4qHh!pA2Lqi[r13bTli[YAT3*e&A6Y0aE
- q*lP$A)+ERRmNFGP[l(R(hr4,ak&mS&r9!$fV@cUiA&q8$HJT+p#al*EXFRe*$U%
- MmU2G2f3k9ZCVreNDSD16*rX031mXeLr5L,TPB)FR9V-6G(eCqP#hf28m(DfU'M*
- m4@+KReZ,)U@8$"'r+Rh3cklRBpJPS9E2hb@RU1HGZ82SfPr2hbfYU1HKAhmpIip
- FSNjakQ$Sf9r2hbZpU1HTMY9krMjT4"eXpb(KVa6dK)1R&fY(4Gq6KqTBahf*F+F
- kiNjea*hUL$[9%AHU)qj8[cVZ5i6[9$rFUAki8re`TrSpbrG)a6hP4j6+lp$2lDR
- -35MkAMj5LcL%280j[PY*lJ-NPCK(BIU90aT5N[X!b5IdUpJc+-PpJ+35m`4%[kS
- pJj,F"dJQS4reHDZ1-bR*IB#N%rR$haSZMGFVbAf!T"2a9l9R8*,l!%NRmPr9RN&
- *lJ-NCG$2lUZcIJ,C3,mJ)&&I$P((1[fUrVjk6eT(H80IrDHZRd'1VGIRpBL[@KH
- klNrVq4FrXC5Z3l[RVMT5CZ"[4AA'5JYPImT9FSImkI6Ie9LR1qEeH'F@8mrAC"A
- k0@+EL)V*0-lAT3rkfI9,PbH-bD#+[`1K5`(dN`$i)pMjRKM9eI,p5YP([Qq-4pk
- F'2U'0#*I$VALe)2jjDJlA2EIr+BdSPpKkGIXp@*EJ@V'Ie"DS4r8)rYiKNX,M$d
- NHp"2f9)KQ@rlP(leKdijYMSYjh+YlY22pCYPLhS`jq4kKGprbqqr@hEAkh2!H4r
- rrM+rrjVIImrZ*IeGVh(Hkj`R2BKRjXmc%rXA&jh$[b@VU!HBIKLUReRXB$`XIG"
- 2ljZYdbmH$VZ$f)QT1%(aEHQ#IRTGZ4IUdeGd289pQGDc#Iif9EG4&kA,*I68qa[
- VpA4h4'2Pr4Rq4EUJ*p84q@96RS&[6m3GUpDGrbUGL%Xlla-I(jVfLj(j(HP$h[m
- ihD4`LcIdDpIFl5%Y@!V)4cK8ed[AKlrEcP[0#)cq1[fldSCiTh'L$#h&q5$UGa4
- 9bc0#hj-la,Nb0"1(b&'"B0JIM"EMm0'dIR5[GRQ"MRM[TRc,p[kTeJpNbYc38Ak
- `ai)HKbZ'P2S%MD%i*S@LT6%YPq[Ij!VkkA[R924VaXCbRR"ed2,ldJIpdRQ`KHL
- R9AdiIb"Gd)r9)h`2#Q-[MF6q#Z[M-13Q'EdBKcq81m3KHCI5J1G[Ybi2YRZmDRR
- j2C`IpHVRHTAd)a-kX[iQ[P2IKlGe(GXpGm96#Af9FIMqh*rL&6U2!IGjh&1k6m,
- [IJlGpQAh6*m+2M#"fLDfMdXDmY&beJr4ipV)5iRjZj5H%I4$DRYb2j(@NpDCmJ*
- Gm9kUUej[,ZCl''IMXjRS@GXMq8RTK*lfh%T8lEGpFreBcP!hL,dhdr(B5(UJBbT
- VC,Yq)QR)Pf[5qA*0TUp,pp"U9m[aq1r5"Me61YTjKHTBGU0dZCk51q39X3pc+Xr
- 6(UAE&bhe+Cq@-qLRprI!eIf68Rd0-Mq,JE4bAq1RTRj5KIkHAUI3r(JYll[LR[*
- A5H8906+QIp(*Cp+k5JVd['SNdr1D&8a([*[UH-f+6(iK(ICS`1FT14b3!+P3LB+
- 1qr1q"Hl&ZV%P(JRh0jbHP5[SYj,[Lidle5mBXI9VL+Z9'3GbrN2kS*rG[kFpL'U
- Kq*ad36r@"q0l$qRpqaAc-[e[,4S)U18YTeb+[QHjT#%1`GAh-0r+bL1BpiN(UiX
- I2XqKr*e'2&M[DF(%SaH,'(T,[S1NKbKhL)HdIJh3caH[qUQp))h3EeK+2rLfa#T
- VY#V*2D+P$2VTGB'Phm!BQH1Z6K,r3[DJRc+UHqlp!e!AT(9XM(RGr3Y*[LKAd$'
- ecaAZHd2(qS+1C&@IXSkrP%ESq$MYA!pIPaHKSbp3hZ,-jIU9UD2SKe%I(AP"Abb
- V*mXcd12pZ$HXR)#kJf5-%H[cTVXm#dI15qNieIYPqr(j,rP"hbcCCm+GkSdlckY
- -E`LPekh$Hr9ZkSK&kFV54FQ9rDfkG6lGR+iapCjQqTj+1dJjJ0mhjcGGrd1J-hC
- -9!lZ[UL"H)$NG5$$Q88G2["I1U#1S6SJRea'0qTU5ZN!rehS8,%d8FEr1Hrr-5k
- fT(UJVk!&mcZ#+4q8(F3&Lmq+,Brb)HP!A&a00ePUKX01Ehd'KqGU'R3T"eTaNI,
- 9dAA3rA-1K9r18EJIc[db$X2hb8+ILH3liL5Ybf"U%ZaZpkZUTmf*&H@J2qV#IA`
- -I6EUJMS`3MGY(V!ZAM$q921&8MjXkC*r,d!"ZYPjrEVhdMRVDRp`!VrVZZ[[6F@
- EAYq1X1SKMkqG&1SPralPU',pYlRZQi%j`"G`2kjliE5Q[pH"aRjjL6NT5erXCiG
- PBE5bRjpbp*rcVL4!er9pVU+HTAfV&C*E*"*k)[rNpHbUa1F8fBDHjIJm4TDKC`2
- 4-pC9k3Z6EXYrkINA(HfjLl5H69J-!2kNd9+V@2QSA#)qXhSf`LZfXZ`!B1LC55E
- bMHllPmShi@KE@fQA4J+EPYDcj2Zh$h4mC,fqHTr!d[HrqrqpP9HE-#p5Dj!!+p1
- P%h@ThNIHTPI2VAe"Y31#dUD5@p8m@RbMjC4bfTrMYVM[SG(I@G`pYqFTh+r"r@R
- FVi9ZmrlN[l*X%G2lS#('R+QPpc#UGl[R0$5VXQS$&[TEr1Vk5J*dGI%jda(,MIk
- iTH[`0M6H1S)dLQ&4KD8%qZTB*Fc[r*efR!cKlmQpKF,Dj4*aiJQc1"N`ckK6,&d
- ESd&IEIpG*C,@pAUZNc4!Aq8kp[hrq!a"jh6mBMrXX,Xe(JJ8Dc)P+TH)hiUZJiL
- Z*)D,-jJ+k3E,0A3P1qG@!eDC*Dh39Hp6TqS)UU[A%iP'CNBGMcNP*Sh30GQR(T!
- !k&1RilD*kPZC)&98Z86F(ML5kEV0QS+Z5,3PA6AC4MjUSETUdC!![c!jSF6lG0A
- pD182qKUq[0YDI3#2eq[(QRZBR#*Y+XhH-dMT,0Dh0r'k9"kJp`hG#jHi4Gfl"2H
- cFEm4[hraVh(3$$imNJfI,LXHY[4iCm@$-ApT14ZP5aS5$hBFd$eL%3I&B5KPYJ3
- P$QK5a#UAK6LB)cZ*Jq%qIpJ23ijbRA#kh#-1p(RMlCEDFG"-qm'9#8&PVM3N(qb
- XM)5-1kELB"#0Jea(R-21q'-Fb![Q!q3,qG)rQcLh9I,PQE+6ZQ%`mBXQLqm&`Tl
- FXKX+hL3(L30MhX++Jk&LhJ,@a12X5&$1iRIpRHQi'X6INhX,KFf6Hm49BMiM%`I
- "GTTR5a@CFVEF)`jd2m,Y9f6U$4i(jAS$RJ%bN!$kr*8Al6JB%SciJY6aZ0h[GAC
- 68%L2AQT5Gfe&I39+f3#`mf3RF3!IqeR&%'#`mf8RFB$p44%(PBAMP2QbNcKS*R&
- !LXAL4*pbJ63N$Y*c(`fKF5SFB#[cem4Y4q)4"h[YcZ*JKkA'h%Fk(TT#iq+4DN3
- S&dP$mN*a$QB`D5bjd@4bYiAM1AqHLf8RpF)fm*!!m-+N5+mKl9%`CB(NSkrbAKB
- (1ckCU4r*('fYIVa%lK%(h3Zj(m$bI"a8$D+85f8RHE'4ce@Ajq)[Njh%`B$q+KU
- `KG+6rK,aP9@VHb%5ecc*56i)YT9hT#+`+f3RFG$3hdd"l*1bNcKJmq1944'9+b8
- TF8"@ULr%`9@bNcKSTR'JqNZ0&'@4l#31Q(p*CD&ij@TC5"bi*VQ1S0URkU41f#8
- &bQY!ZT5PiP[h(,KBeQ0Mr10A6*d8TNiKq!eF5%i*Z*6k%kBHVA+A$A,UbBErG91
- RqG[@VM9qY#0qGb(j$9(Kr`-!!!!0$44,CA*LCA*[Fb!e)%a*BR*KFRNZY3!!J!!
- !!!!"cQIJD1d!!!!!!!!!!!!!!!!!!!!!!"B!!&e'!!!!!2rrrrp069"568e$3`%
- !V$aa3kb3!*f#!!!+h`!"12B!!!+P!!!T4F+)qp8!!!!!!!!AIL0%$L*b2dT8KXT
- -k8"6YhiBR!qIrfUZph*G-pK#eY(HUd[kN!$[6h8RQ1-k`pfGRB8q,H#J(&khJdH
- @E3U3!'2a'd6P,eJ%$%#jRDJBP4P2plhkSBPAJf*b1-QCdAQ#aY'*QE9F"qHP5,4
- l1[SM4G0(VA%c,%aYB3-XE,q&$43BFi@Y3V'YYQ'+Y4AdHA*DfXp4d3(DX%&@C91
- @&(NcrrG$m2Yhi`E$P(6crb%YkGG`25fVN[PIlH2EL86rp*,a8X0KDpc&5TU)eZr
- rI`Ahcim4cL9XSQ1h`qNmpbMIPiVq6T@e@*RB&CU56Nf9BYSI4ibR@LThI0%j20+
- l3a!pi3XAdq*B*VDF!ip#3INHh[dh@Qd-&G[bc+6#'V4`+Fje)p$DZ@KahqmF8RP
- YhUHd2SNV$dXZ*BXkFMP!XE-1J1M5a4dY@alfEb$-U-HLabLBDCK[ip+P5f8eTQ6
- MI'QIhVY`U@H-i!1XA1jG'Y1(-UDf9$1@MMr'Q"0Iq"iPrKe+-6H@6Ma'QD((jXp
- E1ZiB5CDP143DUUpakB3MP"Na+CEL5dmi`LR4G8hIB%Up#Nc+H9&QUFlj-IfEq"#
- %%NAN$Njelp,+)`4Rb"5[dJajm*L2DMX(p$(AP*@P'9e,b!Uh4SF55XbP&3A"`RK
- kU4JieFJ1CA(N%8p%6QF8c[bFCrkYPJhN#@B#Y%H2iedik"6MMrc5+,0qDIb(T4Q
- *G0*)+EhrGN"%cJ1Cd%21UFk[&f8&p')j8@4J9%Hq6MYqi$!I2rZj5IH#BR+-brm
- r-Bcm2cQ5rhpbmYm3q(r##SbGE@%U#jYZQk*BZBAa&VE-RMq+h@GK5S(a'be-,6$
- &Gbe-Bf'rXV!p!P2pc-)8&RCaE!)D,+Y09Kl0!M1%G@dMMjN-H9YP6AdI!!!1Uh4
- ,1bFeXE0KE(X0r)jeC[ifYLIXFY$C1C!!1fL5emV@(06+edNFrhA*E@!61l1hcM-
- %j,Qpe2hHiZH!GHRR0VDIEA-jlEcHEj!!lbrmXTRIq`)"$$S+%$em,0VTfh9+rIV
- 0J[YG##5rMm!cXJ-J%)!H3'%"!$8aIb)4pAJm#[l[l9%1[aMr2ij[pILr(IkGi0R
- 0-acI$ULE2R2SP(#$kP2$33drb"h+flPH$IS6XDC`0"JBHP63&`LU$kerU1,,6r#
- 6iY@-mDZY6ATL6%*Efr1k#XDV0ALa`+Lrm8EqK4FSb*hLq99rQ6H3!22@Ir1jIVe
- VaN68KP&MI&Vmd(jH(H2jr6lrh'#*Yj2&'a0#f+l[MPI1flQ$TqQ"F+,-#kTU3[A
- U[SCS81[KFEe$DM$i[r51"&[aZ'ek-ej*lfV18aXfafX9ib@d,I&GbhK0#5dmlh@
- peDha2@K-8Jp(ac5T#D*eN9I0H)MAcIT9MSRi!M(PPV&,$leQ28l&d@GI2(ETT,1
- kiSRm2m#cEYdkCFhYpikpmGHS04D29'kkGfrmmKD#81kmGBl(-h,PAhNY9rf$T`a
- 4KP6XXrXY&I[XGcGAD8l&2[X[),mcrLVff@-SI[m`rrhBp1praAq2ErX[k!J6p[Z
- lRr9iDXM[26ZpFVZRTQ+YFNl&BmU5lFkXf1Zj(F%FMYpAiII$mIZAPDFZI8ajDV(
- ZH42UXdVbLN&U21$e*q+K4$*qF&HGd6CreEF88XXCX6D!A#Y4)ffN#HVA"290M&S
- ,+UY4ZYPYLd2h#qTfM&S0DQ-d'Fbm&p59JPVT'FJ9'PP3k#Z#1S"4SG$)JN,h#HT
- !4S9#)`X+I9P3UfJmHQVp$Ak[2k)PBqQhcPpeMk"@-fU0Ar-'ilVDQRkX6DeKe,T
- 31"l@jRT4R'cLJ[T&3DeYThU4(lC3kaKeB-J,CChB!r8cJMU)8DY"G@+"8MmVU0Z
- EE`hk'hVHDP&hi$%8mMDKkk$RBXLLlXLS9D$QK@fErdbGS1jNkUUKRJVNG2fmS1j
- X+X3U@NHK,`MUB*j4%15k9mf%DbTHGq&8m2)DJISP3Gf9jiCiX!@j)Cp4lKA8)Cb
- +DY%Ie$4[*%ZemZYZR+VkiS&%,2p@+lrZcUQDVSEMM51f82IJNGF5p%@b,kA8eB+
- k*r)b6L9k0$h9aZ+3!"APHp'+c92(5Je5I@88ZNY3pfE8D[52[,RhYLfjq3""h8G
- 3Fe8EU!F+kVkFU[TD[#$RU!F*kTY414!Uk5Ne*,Y&TEUZpJRU8%BG4+KiV$m4f&4
- *J6TE80pL8B2a,(AKXMX&G6p'VD(8aU#HMI,9a`RUrSbk!k9'XKU"HU+J[V@6QY%
- )ZH%C3AdESpC5DX`A59H9H+YA80rH33eVkH`!kKa"I3H2)G,ib8IHNTX[%03$,'S
- ZmKD(RKA8!e%IiP6jr3dq,9XU%i9#JRS3SpEkrB&Jb*H-TJ-@e%C"I5HMeP"USXQ
- TSMUSlq*[$IP4PdF6'C&!M3MU-%DY)p6FDfhU`4e89#UC'Q9e9&!2iES5+[TS19d
- YkR#,UJ92FkJa36e8+03BM+2FbbJ8&p34(93plZXZk'hUB5,b'TY3Y@8Mck+1&,U
- 5bYI4eD+1%Qq0q9SE-P'q123V34dYhKV[LD%Q3AdhSeB6UT1'8Y6$a9Y9c$NiEce
- 080mMG&@$@V3j'd1US)lTS1UU3p8&pEdLbV93e0HBcAN@pAe#9bd5ER*d63VUqbe
- U6q3e#qS(K+kDRP#GA'j42bLS,@J31G3@34h,U9TIhA#QS)lM-85S[AA$fB*k4!F
- eAcGBe2%mKJLeYfiiAe!R@05Hb,1S%i9#[A@$9901kU$Qk`D,HU5)[0kkBD'J(L9
- dlDdE,1TNmGCmh6"rpB@#HV4iDfrGB&'2iA8$SIE@$4CeLRKVEpe`ND"1&EVfeJd
- @G9S(09mh,",8k5,+HqZ'L`@eAZMD@cGBe'-YDNrN@G3C3YIHZX'LcK68hVTKLD$
- 13ZqE4$QQA%K@GRTXYbm3e0Q-bMTB$KE8X`6e1%kP(H+JRUX!VK$8icNe%L#GRUe
- [2F'Jd[j3RQV9+#FDe1C4qA#`U5GK%J!([API)*!!$5'Lkc@#qL&'V@98p+1cmAU
- YS*l-U1M0qjU3!24bHFLLRY**cH8KLrTK4Ud$&5mPAEC-TV5ShRCU8TmEm1Qq-R9
- 1Hc5!LZ'5rQM`GEc9kdpME@U$'3hqZEPa$e#[%e5r'H9qe4QP5&%$M%SQ5d$09e(
- A#fV3e*93mlTDE`ee8R2aDP%EcFJ$d"X*1&eE5k'j(93piX5V43fEd8!R*VG%`kP
- Q[%)GVjV,H4BedNR0j6b,'M9M#1-A$G'%2j+*)BXD-kP4RiETPh5'YDPa8k%QAcC
- 28ZS0JTS`BiJd'j`*M%jUNjQp3%dAbUp46c0e*G4m4V'SDMZe*H$09`!@96-c#U&
- QLf@EUTZkDVj36dIr4N&0QP6GRdPGVe'EcFJMe(`ZYkJYCM6SMET61pM8HHh8L%k
- VQc+e&G0P1!-M1QV+r%6DkTX&pA4'VBVSlP5%4Ch2U,84hCf+X+KR-'TG4!qTZ4P
- #8'm4e$-CY5DLUm&BSMQMN8dpLlq9p+'3!&$8jR$QVEF+kYQ-@Jf&5'@HLr+2#HS
- #-aT3IIAdAbhU1Hh481LrhLDSj`TU-"l)6"$Ce21%3SdNp,)+@G6ca9XE[@L*GJY
- V8bm`icANM3IRjEUEY`[U3K&j[4e(LhUK8#LA(@cU44e8,C&Z1GV845+'0#dlZQ9
- 6,aE43-E2R@Li3e!A#fT,crb3!%@p41MDiV453E8QdLl&I#R4PA5L-)JG5jIBS0i
- YU*FaDKfP*P4iB@6HDP'A@'r99(phB81Se[cVjBaD`rSmLA56R9#Y'FH2m,Ff4!2
- jDKP8DbEeSeaA4[9QmTG0[B+r&6dPVijK8DHICdfbAXQSJdM3q8MR`,mTB%&G)DK
- ,Z8))K1DFX+"DmkpAQG5Q9YTdc&BE&[9U8b&#eHIkp8eKEP1[-D+"8M2P+k&DXlE
- A@JSjSpJfpES1DVE0CP1[Ya4bfLmfp3DHKbJe2k'lfTVV[G&5U#GH,HT0PN*k10f
- +)P6,XH"Qike04*pmlp#LhX+TE!!cf`DdUEHf8mN8-AS9CHV(1*@0EHEIZNT3EfZ
- R&YjU8@rR91+iiPA42XK@KaCe'DFfqVdK&62IMN,@(2E(fkR0B9qf+BTTB+Y'ZF1
- J"Z1Nka9hFTleeMXYDV)K1erHqGC2m)b#bMAIMmCE(a$8ZmbhkTK9FR4G((T98*I
- c6%QR2Ick2#G62LLSEIbYl*eHY+3bdE"'8$rC588$-81er$Bqe8R9XRi!(G42FbV
- Y+Q-X`XN0PUjhmmM$2!SCY3mhCL22SYl$U0@a5-r3!DKI&G4riC%(DVl0EP-rdrl
- @I)XBe,@#qPP'V3,9Q8DK9-Z,jA-@0G1Chd$p9ajjM1V8j3ZA@Ei8RfrA0GmLaPZ
- r+DKIB05"m1M)Y83*p5&"r5*AL*Ci6L-&e)F&p8XQeDXR)&+kP3UUjB+cJZZUBMi
- NRaXkXr+p2$H!@XJ0haE8qpVI@XJ0M`MUPhQ8JeV)$4EeIS[DNaZq)kJVH3`a+[%
- 4+1H'9HfkpZ5'KFZX6XpU)iE3V(&D'bRU!jbUS@AE5lAk3fX%&3-%Z5lJSi,k&4i
- 0QYVXC9jDQ@L`ZNS2mQM!R%+fdF[HqV5JIT96Nr'HA'P6eh+&@Ra4C20mA@lj8R`
- 0MMBN'RbSf",HD+i,q%Y"r6UM-[m'4eP3V@RlEh!UQ'550CTe51UJVQ28bJR6C[3
- k2khqKD"qNe&CPf)Z*UUlHm5JrPT3(l+S+#cRC[YH&[9E"M8CMAV$Q$c+GQdYkX-
- mmY"[F$U('kMreNle0LA8h"b!4Ieh(RQ%U[E%UdAp0YH9G#PS-'5VU0m)kL-'0DC
- lBa%pl-`h@06[F)A`b%*Zq+fJITG4"p'15!,q1Ge0%C[k+(mV0#8HGq'-+eJRp6'
- $5UCcHQ,SGi,k28DYML3a,T0)paXh8,r2hiTT19r8'B'eU6rJN8HSHNmAd+)qh[l
- @L*I%3rDY[aI8*lLZ-CpIbicd%HS&crp-8*rNf3ZGJe"ZXKG[I8&3ImLTFH5KhJP
- iLrSMVLZKpNj[[bLS2qC[6@MjTP++qK-H$53MMmL1XUHSrm(I5UHTBYU@Yrl8SQE
- kFKZS2q243(1V&lCEf@Ki59"rcM-+UC94(ZBbbKm%p5QZN!!@(j%IU,5T6h1&5-@
- 3!!J&I&QhXp9r&04RZ%,*H$5I[N$pNk$q*k0@*E9XIF+T,`[UXe`KQNfFJ'eEh&J
- TU-r"rBfm&998-TbEFPj595qS[f"8iREQa`LK2p[hHX!MU-rcYi)D51El3fK'Ye0
- r#DFjR)%UUHEcREN(UJ6e9iaDVIUpq5&(8+eSq(8lPBcDE+(qKP'V3!f%-Y0HP$T
- !8(pVkZV0e(LF1P"3IcH@1)0kUUCLmJfcP(26e19,9kfNEXMXr*j4UkI2R)ej0#f
- $YDN[m,G1*)h$,$4&IC&4"dj#YR1J+HT,A+%*`HB`c2Uf+23(6Tf8L')DE5[eMja
- k*,aX52-e3ehaDUZJrSP4DfGJHM#TCM@bhrSbMk'CIMAFP(dUhPTpLU#q`Ymk#lE
- @ZBLehrSUMlaCUJrMJeXMEceab)C#N9($`TJGbQ$EPYcdhIBmT-!kPP*KQ8c5FSC
- kelSGa&["Te3beFFF#,ZjE8[f&je8TB)T0)"iHcLbfSiJbTYi0+$Y(8mi@#Ld3LL
- d(AaMLDkX`RDLBH'b'H+YPHh4%!dhj+2KI[(@!5D9H%BkZ@(9cciNU!-CG3#Y$Ce
- S`&YA#@S9M`CUFCh,$9mjmVH#@XfLS4*H,,QR)[*QM"E48-1SeD"k!`fa$"NCj5P
- "VHA1ZkVQ'dBm)c28qDZq)DKe,$G8FdGSjkfhRbHSK[mVmDI-*6h-8SKqZE)pGpj
- P#Sh-+53QCK6ZreU*YrE%8)H(VX,pApXp@G1CXX0G9GN*6UP%)8bL8$ZEV%*V*J[
- UcZhCbkFkHHLZGB-V4@iBc+XS@"EPXFK$M`VU,XblY!THSX-1'q(NerQVfS4#ZpS
- HRePG9cF)kK"14Ge!`$PU8&"hip%3$FI#-(h)jI,lK+klGrQ*GU%lr85929,1S*N
- SYja"P6flA%LlhfT4ppVJmERTXCeZRFVHQea)0j!!36e*82ICi!aDIZZqQla,0ll
- e&%&p-r2"US329QpqAAf'S!jYGmmDKYS"hYXCKHB,kP[i@q(99hLVm0e8pZ1e9`L
- cZG&FlIATR6iP-XVqlEk!"B91&@pp+kqpM-jhYKkUQL#SEc-G3I*&P1dLS,`p0D1
- Ic9jL*P9j"im'[plDP#YJPpmF29&%``(XVA#EeJ[4)1BTP31hp6E%@`pLEkhf4i1
- q1"U96YdJ*VH8Gc*GkhKADH*Tb8hJcZk,mLkcSjqAeHkA+m-k1ij1[&SG4q9JZbH
- DeGAUELU(G23TXr(DfAp9K[-Z46)HRTG,PFXr[IKT%3f(mRM9@V9S`UP%fqD[I%4
- 34l#F0hLUccpVI2hi4#b@L-p#FV',0e#I%`SGaUJ$CdqSVcmLVqY+-EQPM'68(FF
- a$lF6SMiph*Aj32fTS)jLe%&("[@TVC2V#EblBPXTh)Z9dG[kAL)DhJf2GC*45%H
- Nep2ZA2(@`aQePP,cFcCV6KE8peK8apDbE9'9PCA(-#VaCDHQq1Rf20iUh+D9pc,
- UpT5+Q3-DGkpa3E9Ub[GC#QA($P28ppYpP1cmd*0@I[d!Sql!YX1))6hi'V[HLfJ
- 3Nrh+"rPE-3M81i@jCUUJMZ98lUfiK6V1bJe1435&a+5iFN3USk5TR4PP2&0S&h4
- 4KQRKTSCKa0C#$6I1lAbeVG!%4KdN0ZcScT4VMK(8LB`+l`%pL!R#6%9N[h85V`"
- 30,aH!4c*kpF`+Yj#Pee3Mq+E6rLp290ck$J+*`CP-U2@q,dpXd!fp@MZUi5C2KJ
- U1)liLd0LQNSj"[X5N!#h%QG35*ZGYEhSZT'#1S94i3N%f`cGQF1H[lT#8+Gf8R-
- qFaCeQN8P+`+NU8YQ@C%h[C1DIHZ5fCF*DMfM9K'UfZdQc"@bUYjMM4L+`T3#f6*
- EHpdF%03CM&S08iqX'3#,9c(cVFcN#U&3EN`l-A94Ch'&-(13!"pa![8a3Ch0j`!
- 3$EepVjA2#qTaM!VRTaL*KQc2CXR-'N%pRNmVkSP35-YA0YDNRA)#l`mKji9pdI$
- TcMcP6`6e4(2DA[AkHMa,[LqS*l@r&EC+H5HK(`MUKkbhpNbA@Y56,@V14@"aD,f
- JRL)8kYRfBr82"IA$M%VV"LFBm0C'-G@RH)9#`BCSCYJ@ErfaS-i4Eh9XP9*8Rp#
- eepr,SME`,4#SV[PG1Uc0$"3rll%4DQl4#V[[&@$9iC!!FG0Q6Kjk`-M`J82((ca
- qdY64Kapc-2B1-UR,ehe#1!SV38DYQdcUej!!caqd@1eRqAP6V-SQa0mk&5jG!,*
- RdNIEEehfT+!f-ZVJUFFci)aNR*D@pT0"&IjHbPa'hA(Qj1Qc6pLSU%'p3lM6+@%
- flcANQ+$DJ!&cM@e3T!&rF*1r[4KS@l*)H*BSTl*ZeNif098pY#eC)#CdP3L[beZ
- EIFk%)a6kc,PV4EFXbUJ$d,0eqX1JI[DS+B)DBp3UG$FarC,PSU2r3d'0FiAJ#CJ
- Ih9Tqp5%2#QU#8DZ6ZNEl3fRZmN@l2#'S6HcEVUp&hZM$)eB-h5#FZT66Z%*GhG1
- 1YkjB[jeiUmScb[K%2"!QE6PI&+eB2,Vc"F[[qI(,JUSaDZfa56LG"E$c4hR'8G%
- jG@TiAM!`06hjXS'DC03Gc,I1)QC#'mJfYCP6NC@MZDP2QpTL6-df`h0ckp5X-Xq
- Bq)3`Ijli9&U0qGI`2&)%E*jr98lRe3D#e%LY'kZEj3mmmcQ4'qCcKFC0R0j`+YU
- [Qa8kJqIALIAeir2jYC0kT[(@TUCSF"BXBrVIHKEA&8mPJl-0LHl*!jYk0RpV2GX
- 5C[0FVl+!83G4KCa3YkRR-1Vfda*k1"5'$mE'fB%0e(-jGGc%HTmr`U+[5$f24m1
- iL61#M5K6dY2L0[9m4YeTh-6C+(aR"GABTPV!TPl!mp#iD"L$*9[QX*@&9J`j!p)
- fp8*'VC`qFebq&f96,q,4J1Q3!+C%2*ZCEHSL4UdK@ANLDT[dJfhUa9cAmBPS3Ue
- (aB(fA&(Aa6b'MJpMljb@V6&d#9F)YCHZ*V+&VdfpP0Gj8i2aj*mRaCA,Z%)6d'&
- ,`*SUSp#+9ii@e#@mLKSrPF4j0ZRCElfFkeU2,SrZ6%IEe)p`kK'qD$6KY1GYkNF
- jG8*BLd`Q3bcpe#XBG3Ma1D!jFP`m-"i'*PMJ`AUh6Eh5F%G!['k,[+@F1J9jI"[
- e+Pk*6NQd`#jLDb9kY4&jU$8`[l)PKUlK89irC5DGCTq8M2Zld*pB1mZLAXYe4I,
- hCHIX0Vce1Tk(CJBETb4JZ,-j8el2UkLC1KBlmUN"%VFEUkKlIM*E8'm`hNT9hHS
- `iAPmGmc!hS*Y%"6a+rV&l3bDX!$r--Pc&0jfNe+eI+PbjlP0l%F9f2lVQSITlfV
- Tffp5lQcHNGlVq2F+IYq0hhIPpahC(AqhB1q%$IUi28J6CQaIPY2(`K&pl#G80,8
- dE@`m-%@)2K[MTp$Y0''KXMiRVi(Ydh-CIF$M'LS2#celp((lULDXX9qI(d'IKc(
- mYNiHS)rE`69K20096+ZBPS[[pq(r!IKIcr@aYRjl64pPr0GK4r8irI&a&5GJUiM
- aV%-XiV[3+cCKBAkI6r*Ca6R+ZIaq(VqIcqmAm2X#IPr)lfIbqdIiI3QrAmc[&r'
- l5[U@Z&r#[lq$6#CAR10jLAqrM05lZ(q8Icq$h6d[m1mYr,iIQHr'lelNhkrJpeE
- 1q`2rILArrNIL2i2[cIah5rRp+[llhr([Pr+lcZrRm2Z&R20lr[eUIVq'e'#iRm@
- rAml[Cr1laZp*c[m6rhiYrribmDV"pq[ilkiR&42Z8G)Malf+H)MJIJ2rr5*qRmI
- [!iNc#Gla#Rr2UrahTj'Z-ZiadMA(I6LC$FBp6[VKZ#G)Ka[haC`A)Cemh%mPF`#
- iRdlkP8pF$KG5XR(GMQcfU$f[Z$[(fG8(jY4*R*qpARN6p&U"1p89pdTm[arh!F5
- A"AHU*qj8,p`9iPjcpRV2HM*9MZr9a"d&paTmI`Vh*Y*calf#c1hZ'eHf)eib`pF
- UGIKq(Ka'(S4A*YRN,+9IBA,3K"dP9p"[fYl+@iQA`1L96-I@+jQ1SeGkA[#m""P
- f5qRScM+DX-RG1V*mKM[03rJGp4JUkX[bMG"j**R4IN2["qF`[A%I!6iU4kBllP6
- h"qHBm8YRYpYeGlIADkqDj!Va'e(Yr+-TYF4Kji+9F"XPYG[1+4hGIIV-`q2qIh4
- 8"K%ARUekiTl4-afAlUCrjZ&F@8*FTR6%2D8MR3cZb#mpZ`HDKh-P$MTZ$ahAL[a
- LkqKZ3fJHkKBPImJ[3XpdA,Tl'TU(HNY*)H,5d*((PaQAKFd4c80pUf33FCR4dGe
- Pd6c8TdTQSD1lAD0jk%jpXJXGmrXqQSGk3mNAG24FdUPM-h&eIJ`b$%lTk'iJD4i
- kLb`&d(%(iKMAVUHb)llr1ImEI3YmTlTH@*r4eGf4dMadNbUCKUlZ&TIQSA[j5#P
- d0HVR9(e6f$26203M4%DJUh`J6Yd01-h$Tb2N'A(UlZKT(ZU')C@)8bI[p'`2DKl
- U!5d9d20riM26lbMX0@SHkK)KJHKcNQdHZR8XE&TU(ZVa*,AS%a4f2c82GB+5@ZK
- Bf%E9205R4fUKBf%r9[2X*Vh3XE#aUhPfPehSk1i3DjipT"-kmVkhSD1leDajpT3
- 'k,J,m4Vq[cSqL9dHc,ef49iTl&PVRVeN!cV+!ZBCS!HG0i'q4Ve[kqYZK'XHXUq
- d4%*IF20kPQHdpT&$j%pmTr%TqKFT23YEp*TRAfP%2@$drrMFKDPMBDpIml`jVH0
- ZZ0rhZTkl%KIa0qCTm1iKi!B0A89rkHIB(B0d*@aGhFf$c6081U$VlVM2aRd2h)r
- lKmkH'Mlh@,0CCfGMAr1m46UJmjjFhle`Rb-9L'HMhV0eGVFl0XpqdJ'GremFGqP
- Vc1hDqVTl+*YRIqP"[YSEpj0`hdFk%0I2BfF3dR9,kpkA`GiU,FKIqq*1jTbP#AR
- -h3(D2'q6$ZJY(p!hA8qkfdUEjqh5!(fP#AR+hDID21q3!#ENjlrSI@%pdr[4"Ar
- 9Ze4A%RF5#89H0[6ZLQr$[i,2E4TkZcYXQqG!@8!rCl114VcLE[6Ad[Ujfh5Ejb$
- TJhj'Ip$@cphVfcc[P$hST``P1dXJ[l`Cpc0bqD6JKQ[#Z%'3!-3K(SdkMXrrQ[Q
- NX$'jHGk9eSrkmIc[2ZIqL+Y6FAm,lT%hG%9F'[0DD9hGRFl0-dc5S@YfHfcc(#b
- (d0@B%bcUkZl&ETj$C"[akQlZETlKdJTGMIl@aMb8fa(F2)G+)r)3p4Xbp$9mKKj
- Gd*0RFpZ-QfH%E#-IZA[DQqF`+8HHc@f%ETk4FSQkk)Dq21[ZZQqH8A+*20ZPEcj
- ZFpZeQfHdY#*ZdlT@%ee,E5l2Zq83ZMjfq9rL0EHIRAN1Pfh%+mfcZ4hUcI-Hf8D
- mFPfc@pkECi`F3YI[hFed[A&1IamXYiHqHGiVKp$e"m1CVMIaIQ`K[qBfj6F2FBb
- 9F1KDU[2H,p[3PHCA$@EPERhq!EP%2E4&epa'MHEjS,4#9f2qK2Z%QETL8khqHBH
- aD9dP"I-Dd+e$2pcTr!RZG2lNTJ8C2HZ)RZ8jKh'5$6f,m`e(b$,dV#&kPZFDaXX
- ep#c9FHJ"5M6b6AQ1BD*N3mrLh-)N@BDHY&iVcbXF+GA)Rq8j"FQ#rrJril-mRj!
- !pL'A9-4RH4lKD&Q'RY9%cr)F`M&5MIJXcap-N@VNcr,F`96*KTl&HB0T8SekZMa
- R-&fUN6r,m`AeFJdp5rADX9+0r&QH*m!-Ud4$cr)F`8cTK*l6D!DX-2bicAUDE1'
- @ffA32,-iP,mlmalQGe9kd'cl2BBI4HSpI*2"[S,r1,P#["Rc0,McH-['!lDGK4p
- 0-4k1ha*Ic0qQq*i6YVkRH94r!MJa(DrF"pei$hbjh99%f$P*qK#[DIeUQAj`iLe
- )q#&CKAl`frBepHcCcmr*XJ[pqZVI8f39qY9"2d4IGTp%mhaBCU%IpJPdeKFdMPG
- QNEqK(eDj+#53!$Q5LrMcBLIFAJ&p%S[mlCpEAJa#XZ!IY8dre+pqYE4qJBF$j"2
- kNEdXS&pa2S,[N5@Pb(p%[f,qihYQb5[dkk[rq"jD8SVk#G*PPqC[2ha2,@Q&IRV
- %VIrikPK5L[a0GjcYbpr'RPXbL[S2ZF1Vp[@I6T8Vk2Fie`phUPp%GIAVkcraE5P
- P#ISp`IA$RHTheF1jqJ2,(M4J*kc-aUAm4#8@qN9p'MEXF$Z!-9Q&IR62PQ,hc11
- *bbVd3rf4fk"9R)5X3Mqb&i`DGSIeF2M'FP++r%Id+rB26T0Ck0F5m"BcS#UVd!r
- p!k*IF3"2NeMN2mdA+[P"ka),rA4rAr-'*bQaU*q)IXAq+eD'NPENEle4,rA!@f3
- @qQ&el0a1c2c`M43P%2VaICX-r3C'G-bIP6CGDC99k&F9d6IldCmZUp#[0U*[pU1
- I,k[3V`kER@2KkZ)QDfI)+[5VL@!EqeLLZ5q$R#QYL$rLjB(fJGSFlP83(Qq5"rf
- -r@$DY`GPp5[b"jQ!l8[JCdXAp(XEjYM[h+BMmMJQF8UqH![N%$Sq-6bM)mRRrAj
- ijdJaG!c'!hfEX*`VZp#4jT9'8Q!9mJVaE*4Ia'1MPki1hL2NqE),(9%[KVaaXVC
- hS@#j3(DK)kflbVj@#k8BHD9F`9mSbG"45lK'9KG*-HS965XZ),4)'U'MiEZc-Fp
- M3rUSQb![PL[SH+Z(kBJlh4-!pikpA@jYhlmZPHr*RLA3e*96N5cimQALdY'4aQ9
- ,UA"C,-A)pbdPilT,T"%k'[e([JHLQHq*H`d@'Skj!lLA5KGdh+*I(G8[S@,(jei
- ",j09k-IL6e2pKI%6ca,TJhj'(V6eUf(Z)eM&[C!!cbrrThj[4ell["4!4k0H6-9
- K3c632mRkNE511pqeER$PkhS1a[G(C3CkeM%p[AfGVSp+*r6-j%Qia(Ke,)[S&Sj
- Ab#Vbj#"5B[R)R,UrYf#m8VUJAkB2NDQhN!$UQmZ*FURF)3k&hpaVqM@e8XZf3L+
- j5PDK(r))d8qIkpGl#pkVC4Ake6,pqXBY2GI),I*(DCAGDb8AqK8YRkk6@q52NQ(
- 'pE)+r@USIUAp1Qq3!&[NMe,pGk2F)RrSBGIZaR16[#,qQNMf+2UGh5bYd)qYPPF
- d$,Y&CU%IfFJ8VJ'pqU'&)UR3Mkfk9ibrMmNXp1Z2[pZN&IU&e'$3Uf*S[6$[GV[
- d3Epd(l1ZdHm0UGMAemdIbf3"qLN(S1rrS+a!aqD`VfMmph%jK)kjq4IXEN,FKq*
- Z2qS1Z8-qFI9,0[4e41k89HKALdR*IJI96dJXiNr(2LE&2(LAV%)rj[I[eqHjrE6
- PdSViBl'(dFl#%[&YXJ[pB),@UpmRC4IkDHiHhCq59ZK(h8GK)1r@ijq@9Y42f%q
- ",$FGEL`Nm,ZP$rSCHf,CqPA()TX0`1p*khFJem1$lb[rccbNFK#qIdNU8&G"ehj
- MiAq41m5Pf,1d+bllM6drmdrpdR%S(qKA98(2dTB1(XpRC30kbJIQ)*Q1I@l*(Xr
- RC"FkeM%GLr1erbU0d$'A*rX03$pIU&qN%AA,`#DI@VB6p(a"@P(2dp'UNL($&b8
- @qRRe"&++DiMi*@P&2DpLPi4b2Ep#ZP(23pIqH[jHD88p$rhkkrRlj"*e5UkHKjl
- ppIbAT4Ie20@a9-rI,ih3-G1(K,p5f"F0RekS(49M6aljK!m,p22kLR-3LV'AMp3
- L$Q(2d$IIV8J@pJ&k[FjLq[9Y0+4)&[B"HN1rSMf$)PRB"qK[qD0Nck")&[B"fUB
- IpANVM6-TNS9pJ*jFbI6$hGJ[-jmrJJe4GlaHN5cX!l402qDc9l4R8#3,q`"Ydir
- Q[j)pJb*Cf!HS5lp-Ajhe%mJ'qVd#%[8P$(9XPikjIP9rAhe9@NG*3VmUTHH6+cd
- rpc`01AEYbZ[a3+NZp$b3!0Ec(hjL+9ehDTZrC[,Vm8VpV6jQqe["h-#TAq)"V,6
- 3jdqj4Uk3!$q0r9k(VfAk$9bBlEpVDV0ApI[mF`ZTjbYb"Ie`hk*I0ED*+*T-drT
- "pU"ITRjTm88a'96dGb"d+B"qIr89k0)aNqq*89djhkq@5q4lh'QqAcDd-pm['jV
- 00mRijSQKVmSGmSh`%pRCMP-IjTF6hQLIrqEAC"AkeIVpf&DJP2'r,Uh3$qU4I6b
- MlJ*Mhj!!2HLRE+m3"q-p8rT96TJfSc3Yjr'XkpE2mm,bTDX`jq4jNGrr`1prA,l
- Le9C`hXQrrilIImr[If*h9hr2+jch+ZG*$q+CqI2-aIl&"HI`EmSUmK(6$d2eF`X
- GM)HN$rSCIE-0qL@M8@mB1c%9*LLq*9h3ckJVhiAkp%9$6e&IT[@XJEp0b@h83qP
- b#6f0rNDARYkQK0Uh2m1r54IdT$SL[fc*-r$YLA[98Yhjlp+*Z-cNIH,M3p0q)6+
- r,Ah)qaqQQa4ZpjTq-GdELqKK0b!Ii9"$,d-IrZj-hUT&B26AkGq40X3lM422pQk
- F$k*q4`QYEdESZh+(1-H@4CNi4)i+KD2"F+)3KiqQpI[lAZerlE-AmbhEqkG82j!
- !+A-T4CqJ1T,%T&$#(G2bH,iRUp#[&K[,qD+P3F[[5ard5qI"1U+IA[,Kr)(FS4i
- Tj8(S'2'5M&k)`mGP$h'S$&#Um2`p0Z6"Q-q[p5frKr0%ThkHPhJrdZL$m[lQIrN
- qM'bE[r+RBYjK&,irqdDm3ZF4i$lh@[p$QB6Ir3+k(FEZf6i9I'"#j8eXRj41p%-
- bHXE4$bR[bIe$D81G5A8ekNhSQjSR619CSQGjMq3I55Idc-bY*,4qfcI2Mb82IBa
- X2&D6(ZL)iKVCRTp)*r*PTUp,pp#+DAhaq"qbLhU8kGMR4ZRar&4DdGHJ28T[)1(
- f+AmQIG$2m%p+p6A)r#`'d[Vk'MqA2Y3T0$mDH8A8+jRmU-9(p#mkqC6dSPp$1Zb
- *8-$R1Kb3!+P3+89qV%['Srd0TfGN&IT9*EALM!-jrbPpd#r6[kFpL&+Kq+cX)Jp
- @kiP351[EFXUM'(Z@ba[Ld0M$I,#G4c$[N`bA&MpmMN06HjMElkR$a+-ILaMkAGp
- "dN183q699$a![d#bj+If[$4#[ee5qX'h45fZdDT)&[D)cY8&YRi$96,(ACSNrUA
- X36pP@0[m"`D)2TLYBlAUprB[*2NVZB+1Yeh1G-5GkSMl`G#amVE,mcU59AhkG2b
- e0%,(*fRRHTF0H4%k"N*p@jaj2,p*krL'Miid3%q@Ck$()EKA$9q,ZS0NM#&GHG2
- E0`Y(cQr6qKVpXY%mhdN1kZY82aPhURGlAQ9k3bLMEYfe8qqD*M9"9jBZ5+kmfkj
- E&p,0kDT6lkQPlbQfJj6$qAeVIM2d2`)kBmG%C9cESLVL!G+M!aR1,1M`R[r@!A8
- -e3(jj$+k89G05JIild+(SU@*-ZE[H6qM4cSZYUGkS+qJKhYf"&2H+cZ)#aDI49X
- HjAh5JELiLQkb9)[-heQI`H'jP!Bpb[[YZ%MjkKJk'2ij%q#AF`cZ4r*jY)Ri2PA
- S-jjpcqLb!c8*pXD#QZCVc-@+mS'rkF*pI%ap0ZQ#ZMa10fdHX#&H-2j8pS952QM
- Vd[0Ha%')ERCHZH'pG-kke"mFbqq'lXCl8qmdkY[Gl(V)&iL43Yhele'1+G4r@qZ
- qfCJ$I"lhipU@c+b4%XbYfITL2cXX#k2hqINT8rkHGb8"ZREeZ3TkZ[Y@+e2P'RU
- f&10cQQa$clliR#l,d,1+k+Qf&2[#T0[bhhVq3mI-h%9DcaSX"J"rdS6E+PD1P8[
- %Tk0R0EaLLmX1!$C$1T&[$0qr9,k**KSEh9dD#@aQ@NrApqp3k2K)Plj'Rm$@plr
- mrlENe4V-Lj3Ej-SXk86F%LhD@Sp#b`+E+4hhG2fN+0dX(Ep"*q*NE$Rjq1le8c5
- qV6NjP@56U)VkQF('pC41cplih8AN0b3DrMm!!!!0$3KXD@*RFh-ZYCha8!(&Ji3
- !%b5k!!!!J!!!!!!"cQIJcC!!!!!!!!!!!!!!!!!!!!!!!$$X!!"S[!!!!!$rrrr
- r68e38Ne03d-"!+`mF81XN!#j2`!!#48!!%%5!!!#H3!!#)fF4B@'!!!!!!!!&`!
- M4!iL+LXL+N9PaRHJU9Xr$-k(6kh)[8R$m2eTVj1Fe0NClZlX$!3FP-0$rK91ahY
- NfDB!8I0i)[FNLi!"+,F6&D-biqQq9cmdm@T36!iiV0*jJXE4LCQeA!IRT8LdHcV
- k)dA64kea-ba-E@%$,'brK3d8'(1&V8+aVECKLV89p(Pb@YV28G%"fV""9Q96PK4
- j-rrh3r$lGq-'`j4dmrmK,HRAF$dYUj,jAqhMfiP%rr55m9,$B@[Fa8UDL0E[rhm
- &pmq2%FiPE+*MYm2T22FShjH`KlSHDl%bX5Xd*CfD+X@d2iiB6l98l[LLFhLNGiF
- JHX)A,UE&X8aX13FHKB,b2EclEl6D'#UfjCRaUlRHbhA0D105R1['SX9plcQNmYU
- m6r(jNbX25biPLcTb18#aXeC!&4$MdU9,C6@QC10mDCrHZh#TCicJ!`bfF@*-(mU
- BfP,0@$Vq''01I1&lP2Kh+-AF@$Va''@'(TXrEqQiBb4CPZC3D+LqaU86MP"Qa+4
- BLLmpi3LR40FeIB-Tp5S`+HG&QD8kjmIdEq*$%%S8N6XieEe,+im3R#&6[%Scj-&
- M2UVY(0$(A&0@PQCd,5%Vh"SG5LJaPakA&i4,TM!M,debPHYbE-5(4+0fF"a9)c2
- -iPJJRSLFcLLFq6R2r"X)qp*$aI-%-`(DSdI@Nq+)90URmE$rTb8mM*c(N3H!eql
- &iJ`l(bPk88"EYK)pmbG(P$Tq!6$IZD[YZ"3SRK)ZF&CJl'`,8eRBG0X8aFSYM,H
- `C4DQY,$l,%`Y-,l'`M3@0X6#pJK-D8qL`X,JPi-pl3E,AT193E2!$'&GfmKM*N2
- '9PP6h`F!!!!1q1TmZac)[$,cj*4ldH0Q[PIfY$cj32NEjE34SB3IQA$#bH-jRZ+
- 6'Tk[lmA`(b2d##2(MJ`Bi@Fqi8E*8h+F6,KN`SmFeb2(#5F$6SirHAk8%dkH6`K
- r-Z"HC-#Z*lICf5EFMP!q)-r*m5F8Z-%+3!&@TKfRPhMUG5N!*j`m2m)LcmQB(jN
- !%!j-9Q"m@-"HJiKZfc&&83,`@k-S,5r#lp[`V4eq&m,[FmS#j9E)ea6(c)kSdp(
- 8dVIaZ4')JKd(Ml6dY4ii3`-BUF#mXZD)kcC($-Y`6*hrH5)+#+m%me#&&pqG``%
- 2aHmmE3h!HP1m[r4$08TfH0!M!LhBCm(G4YafHKUlI22fp`fqKAY0UJl8Bj4JY+R
- "Y,`XGH$imkF#Sp3&a01P@Y+cGG[Up,N$aqYHip5&T0BL*&Uf8U$f&KrLe%+LDl(
- K1*DG`jlmX2)0VQX4D)4dYGeCID$@*epiQ0GD6$hNHQ%`9jB+YEl*D`dbUQ0DNCc
- c"XmpaUNPK&VNQA&MeJe3kb#RPP)hJ%,QV"X'YQaG`DQ,L"X+Sq'FU-6PjlNEbJL
- e"+KUZ#-q3`EU%+H@JrF3eA'eKRJiDr5"rB-IF'S&k3dP#FIZ0'0C3d"[1-DTPFS
- eQ+VEF4Ak3kl@GlCcDQM8jCU6mq[*$kX,ZBF@%fU*1Sm&[jlQe#VUSELQZlBHcAN
- SZ)dV9%eGVRXpLGRQd(mLpLL[G3RY+%R,l*keHIr,4bp`kMA+8Tb'66HK8L1"aTU
- AG"[jf!Kq2F-9@NUSeCJDejk`TjLBHTC6VbA8*6!iDJN69dVRddYBF2R6R,U-8%1
- 81N@NYClMe1X)YF`aBQT(XV26F#D)P*VZAXX*Y4a4E61XZSBhK3AU"8jG3DP*cj`
- V0N1YSETLUUjCYY9PZlq@Qk&H6kLPQ"T1*LkV1N'Y690"f"RUdFlh1I8'kL&-pHb
- SBFei+&hV5YT4NPj-YH`ZcHe5pfNa-kaj4UDMr*p69d&h3,e"dh8MiB(aG1K'PQG
- dMcN#*VDR129'3Uh3p,e*dc&8h6'QY!9G2q,81NU&GTI3J'TT-)008[F2AZ68HNE
- &XUKiF[Z0HK290@c%$-qBdr8`TkiQe%@i[rVbN!"D[qE8Q`Qe(&1RqM'MIX1TD`L
- e-Q+!TP&2lBaTN8PZKRS,S5lQ[4`2pKNZp2)MR,U@+N5T8d6UK[3%X)j5cAM#GVb
- X(d#KEcPe2D''6#YXkY"me,LKGrdU,&#rip3'3Udb,62AKE"#4cQe-D@3!,AA"kC
- UrCj60a"U+DC1Gkj*kUf%#MXEep"L2K2h[)mjG51Y0GU8Y'DjS'Yk`Vk0pJCN9"9
- -UdCLb8R[!I8C6VfG8+q&D9ih!-SkjYJ)ND(H349#XpHm'hlNe#C1c6A+FHSQ3Lf
- kiL$XS8mipFi8eBa-6d+-qLQREUCq[H)ll)CR1A8,SC,C5iqkbIM-l286TcCISMS
- pLFYY#&&rjY5lk,5"UDiaBcfJrX+TGp1H4kPlV@Q*-Y4lb(4)jiCf0XjR&KDCDIj
- H3Jd5DQkIYhr`Ijbk0EG[5&F!-dTkpQUKFej+)ApI1A$mK-UTpde10T-bJ8,$R(V
- rp'jM($c3@k6bRFd$9ph!UG[mL@hFH@-6fi0Nej[D0QGlhV1[TYh35K3U36X81h&
- j#U@GmMe1IHLU'cLeM8lB4MHH$[qBX,G6+TdTCkPT0qbJR4*0E'MDm*8&jrh!U6X
- *YB4ZPE*Z'*Y4GY(*aM9JZDClhEQG6AVDf%hm@VA6F$S-ahEE$#eX11kQcG'-Adp
- '1(82R9(fJH%kHqCQP&j194U$-)eqSS5Kbicq#hm4rB,h&a*Rd@A#`C&!X,m[m2N
- "4IP''8EIPDA`IHMdil5diF$3QCAiImXSEqJ8iG54lmSUQYI3I$R0#rYIqI*Rb'[
- TppeSH`Tj2Id1pF+*3SMNd)I)e3V68qa(@H#00%3eVDm3A5C!(N,lC-K,d@iHmQ,
- ihjZ3!!I4A3$N*I"p%2)PD$m,q@,iIKVb"HL+![*+Y-@'r&l8e5'r"de)N!"[4G-
- ,j!AS4J2b4C!!RiHm$2)KT$0b1Z3,JA-)G#P#0`qV'j8+q(l-$5QRP-q3!&VMHS[
- 0,J[FX5IerP2RP,k5!&hKHdVA2IL#UQ"F9l&lCS(l)HURY%lI*f)Vc@+CA-)RUL(
- m,rEQ,+k69[MIee9XpPNXPflSQVmpB,&#@U(V@H8,e*iRqQ[q1S)&h%j+)R5Y3VF
- m+Ae"9k`[I2Gp+qii@&`[Pr"YI4[4YAEP[+kcbij8e%SQjL+AkHVh)h%,`q)'ApF
- !h6G)([TYcVILDSI&5MR&(!'kRPFZi#e-4PHaL@64kZ[k!09*(U$[3fL,qBr1JBT
- !#%qTq,k3!1mhm[G6,&EPGEkIkL-2k&FYD&r1pGm'q4()li2r$rrVph,JI`$L&`@
- #H"Z4mB1i$'0aSbc%$eNIj'rG@04*8(a`jAU24EhXa!IL(T(&6E)6(iJ,5aDVT5%
- qU!fJbEeQh!ILCT6&cArl3&j`pb"Gk"2L1TB&[(NL#CQV8rF6'4q)Hem@Yp#FeMR
- M+h%*c'+Yl'31%EI0,0E*6R`JVV9CV*HGq%$FRl0SN!#Ip-AjLhS@ME)6(iJh!PK
- XN!#'q-$IEiYA$eLJ0mhN)(0iDVrYqd'mjm"LSh6%$c0lQ[a,&5aZNjh-#q,Y$4D
- h5drQT[aV)LcZN!#Lq1$h06HmTb)jmB&imBA&*[Q*$qEIX'&aTqc%"q*9(KDEC5F
- q%1m-XGJL5I&"pZ8N&Xfb%aq)Yk"Bh#8lmB&ihBV&hE)6(iMAP9Ld58pmN!"r,iV
- &GZR*I*!!I`',a3lCL3r%QeiXGNT2pS[j9mTBl*+Hl*2b,kLaf#-,m3%@rUX6&q&
- 8&&l1#(RYV6'Ar1HP`h$&pMTk)kjpPqZ0#Pq!AXFTD(r%L)b-X$r"kcd&Dp"rN!#
- ,rJ-0$3PXD@*VFQ)e,VAa8!(&Jf`!%b5k!!!!J!!!!!!"cQIJ8S8!!!!!!!!!!!!
- !!!!!!!!!A8B!!!!!!!!!!2rrrrp069"568e$3`%!V$aa3kb3!,P0!!!+f3!"0-J
- !!!+9!!!ST8k4lBX!!!!!!!#pr#0%$L*bIjDS$*@CdS'QE[d`1"mqM5,hpZQp#he
- rkL3RGAD'ZcXl!`%(jI#3!(q&dr%H@EBT3)i&Ma19ImFLB!$+l86&U-aiZZr9$df
- m'K56!`kVG*kJFA4LCLhA`ANT%ZfHM[j)dI44Dp`-#e0Ef!!,ffpK!`A'A''V8'b
- VECKLE39pRTb@pR08G)!fE*!!9GQ8*8AHc2rp%2cqhEM"-#AGr(p)5rSeA%r,UQ6
- q9r[iGL,42leN[04`f"ThXC)QS[Alrer"rI0MK(-*QqMBlA!kcch+pk@L[e0P"BY
- jaYS9(SEHrlppj4(JC@+U05@GQLV&Y$m'`9-YP6Zqk"`Hk6XIA3kX"B@,(HJi%@`
- j"ak&J[)p[2Y[Y0SB+VEPQI'VZGl,GFeSie+FkmDLaAh[1D6bfVa2mIQ6+`p,,L@
- ,1R)j3,'cbU%+L((TdU@b'P1bFEj8h&+*RM'#$c#iX4*MqP$'e*CUaY,aaaKciJ[
- ISm5r3bRQaY+*abJcp0MmH8[((52*XM5(3N2e05kGF)3b)bE&8RcT#8Fi*EUZk4Y
- -U9H"56N[bLc916qQIa-IJP#LL0c"UHjG@RQ%i!bCiP@D)3mHme&Yji!qjTUbXM5
- MD`PCiGES8%+*ZE5L)&JB6bm9!kFDQ9)@4ala414d4Z(-chRQhfVCpTjJ*N"lp$K
- q8KcrU[`[MIr(%KkdcU2@!m"Vpe,KZ+)SAR5+J,CX*AVQ6iiSGIbkBEjc9pYa+9"
- -MR(j2bH'N6mR4r*r6NlqhrkFD-IqR0#6LV-2,rSAKA[@`PL"5B1PXV"ifb$&c"E
- '@pK8#e0Df'`,8`Y-m9d,deMBVbaXMm"82l-`KB9G(%Zq`E,AC'A`NX!-B9hEb'-
- Q3pj@@92I"`!!!!kVP"rYR*56dNCThm#*RCRA`'fHPi21cZ[SeQqkmM8(RAbp[$M
- qklVF6QhJIPB$"pP!pi!Y[VTihU,P`%brbbc0A%ilEr(bcGl,[-`QIZFP"3)BG"3
- JH[MBjkeqebRekaF@j)Y#!XP#MT1$"*+&!4!)3!qJX!#!QPJiR8i'!J%&rhF0+"2
- 2a2m&q0D)rp[Lhpk"(3,Mm@h[8BeU0*aZEBXRSj'aadC$NDMk30F$9Gri#6pJ')I
- bkLD(eB9YHRTb@VY2r(EYU@+mHS2A'TRdGpl%ehL4U2BD,kb'+lbKR0IehDF(pDk
- ER&#E*Nd1DDQ$"RN0M"F1Km)Yd6*[T-@E(%2BGQf)9miEeF26p%JmAH&&96@Y"[9
- 38c+UpI'ihM%e'[eIHLHL#r'i,AScAPR[@Xj6QcE'D`hMTE90m9h2H'eT,8lbk@D
- peFha2@ab4SmR*lHTDD*eL9I,H)MAMIT96dk%)Uh+XLRA(A4M&dl9F4GG-q@kQ4H
- ZLbGbbV`C0`8#GCqP[+V!hS(VUakMC18[P`H'Ah3rIFU4PkkX1[+5'pR$pVm@PeX
- *VqZPVKHVGYYa@GF,AFph2GIejkirGIfak`pG[qpkYZYhAFpdrEEVkDkRZRl6pD3
- b60P1'Dk-8%BUSj64b[E+Qj3GV,qUhICX6#LNVJPFA,AEAKIhrRE(CIMpV9c9FpE
- qIUHaq2f$r2G6FVprP[mHhrDkZ#HXf1p[I3T"3(iI'2Qh6`IUUZj6,UPk4&Qkl39
- 9Zc`p!Xcaq(d0IMmH[hp*HH+pMbK2,0%$fk!qUbD['+DQ)X&`1K9,Ce)(V+Y,1KH
- YqTj#DMNM0SH3!'XeDUTAD),kE8(GKP(V3@8ec3Cfjj,BAB+k,D2@JYUFc%5Gpi+
- k8P#V!d1j3K1,#Re68)F`+K5D@&6S6N%GbUK3D'*4S@m)DJf0ad"pZ#NF$#Hd6'[
- ZVBY@h5DSYBaD&pD#dC5Z,X`peUE@-@T$,*k+Dbe"&$2VZD"q99$VZkP"j)G0e!C
- '(4S,3PN[pN$pSU!1Bp4D8,eBS06E"A8lmkh4F&2I@bhUF"j$X@"E5)hVq4LbU#-
- BY3E8JV#GLjjX%054TUiDkUp)AYF[#qSS8b&@!AX+I8934r1-JL$AJkS6VYPihCj
- 6`5YS"1VA"2902$HNSKh)$B@-mR9"hB&689f'SjS@6,K8+lq1i93eP)UN@`Y[YI,
- VMTbUk@Sme6aK%h8R(RNGd9$#I5QPVKE8RC'AFDV4dqQV0TE%V#MIK9CXJ3C@DT!
- !kXY4k"C"hC94Dp&[#ZEIflRdjVd&G6G"c9GYS1iMU'rQ9$A8%33j6peA8(G(j8#
- ST!I9P0NJ+Y9eG8K3ac,U-%,&Bm2Tb2T+#Y6jJVU(4BfQA1VLjCm9e$dCYBj5Qk1
- k'q@V6aE8[4Ke1+8QA)e!28e3hp*,G64#ERK580r+U2@8fKT+j+T+[$8SU'rVSFD
- eA(B!p4a"I6Z2)G)S+N6HdTZ[%05p,@SqmTE%RK,8I9!IiY5%`ddKc5f9L8)a3Gf
- A8H[$i8Jd&XSNF`%,DV1JlXHSGC5DE[1UU"lUr[bYX6$UmQ6D%3R8K+#1Bp3'3Xf
- reUBHd%0&TH,8++Z6JRSJej93dAI,kfT4aeY8,AUH4fd9e)1%3Xh4&-Sp4k'8S%l
- SSHUTd)D#hUBH,#+[Z3e9QaYj&R@Ld*98[TkZ&R@5H'YVD''6%q9,BXm+kL(LVDQ
- q''S6e%-CYCC3[658T4iQhUTL,X*lkhQ#HVM39BeUbABhKP4"RGa$e9@2UJ[U1d5
- 8Dl&NU0R0H4Ee#+'VPSLhHETQ"2@G&V8[mYS&p8LKUkDR95qA@p5M",8$$5+2fL'
- S8cK9'kJE,K$8U6b'#,@rEVK)8)rZS4EU"SXkMFF3SIEA$CF,kR5,fKGj&R@'8+L
- rEV"UbTNpe%,GB&'2%C(AAcFX&Y4MKDlpGB0&R5AH@UJE&Ufq8P#2%frYVaXXk['
- mEL$8rVV"SXi@Eqf['ki5e$P#erkk`D+Hd%-Ye!eA#qU*)XVlkiCV",94k0TI0eM
- 8GeR8[XLcU#F*AI[V"SXk9e$lkiDPJMS2[@m5jCKb)9RCMI,h$l8LEckMXJk@K`A
- 9bT3RFbVY%%IeI!A`38%pK9-6%G,T+Ec9bT5R'P6D(bT3VHaeQN&YRe3)"jYk1LB
- "F0#E$d8LEJJ4A@m8e$-BYCj4dBpfirA$JRSQSk)h(fT$dX[R)BYk9LmeRiFXkYQ
- -fJ!UANUkE%kQY+M"EQT'EiQ%p&#&HNjh0)#+iC,"D!Me[$8BcQ&YDT-C$H'@r,J
- (U$F*DYL-mV$UM9*NU4&'*C-PS"DUU)m)DY68P9!,ZPT[MI95mr&U8C[0b!-`Q)K
- iA9Y,SCBHUTl`iY@LaXeSS"1@Qk,KA$0HS8j3cHFmLjVSTHCcRN90QM'%mBZQC$U
- FF',)SVDDe'4)`r4,,X2De*5T8&[)cC18qP&"6CXa4*S0hJ4',lA0c&kJjJVPYG6
- c6&d*YC!!85bUfNhYL!3,&B"&eFb-3UKZX@a6G90A,46VkqKr6&!c*P821kPV,EA
- GM$a#,H4bLpTK4S2HV(ZeJdeGd%e0k,5kU9!ABVS-CfK#4deCQ%KEIE1JRXqS03R
- GRiU`U)XBY6kKqe-4&[AGM0U3!0"MDRk'%04PJRS"SpBPG$ADQQjh0,+T&r+hNMi
- 8%SVD(RIHqJP"[BK4Dk%3UFcc8Ij*3EhBM!C8Ahhp9iYk5AFd&2Z[Ra,85`8eQSS
- i%d3fp6+K8$-*29FKLiSTC[1Yc8'd4$F)De1[-1-e&Na&&q5lQjm@e-8Lm[SlMKE
- e5U&32M[Be+YkU&Skeh+dU9H,'0)dGh6,TPiMSS'-Uh[4m"P"A5+S(Ahc3aEe28,
- A$Uq9#USeNICHc*F5A8NR#S2BVEN5'p4E"I9pM0T!U@N9hKR1@bhU8ZZYQKVH80J
- 3UMArHLfMeV%q6cVAC#G8DmEarIbY6FP)S9S'eCT*r3$AP9'$6[kbU4rNEd92+DK
- M@06VjeQ6V"pLe'%Nk%+NFa"H(l#JhL'Seh'&%!MYH@&"YHCIVcHTE3YTdp'Y0Lc
- U$DC#K+UhK2AeB@j6Ec5LJ9+GmT93V9RE$eX+HD2B0[@Q(UVECV1T(l%8mYS[0[@
- M2!p4DQ&#Gl8eerXa5k'qH,@S(lF8dZ1j9K5K@Si&0aY[E52k&(U(&R8CTl)"6,F
- 0D&-rd8dP8m6S995SRq480VCCH1XU3Ie80lAi9S[kD8iP$Le"&Hd$YcUdU-XjY6N
- FM+QBqIB8XZD`rk'EfKi2Z8h4cQY[ri@JIXDJ4P1NkjAbFTleeXpDe%b61eqqH,P
- 9$hf1Ca48VS9q00jkYk$HBVj9akb5TqZ5f-Z#ZS*R5MVY%GBAH*RbAN(Yj'pPl`b
- L*H9%`cf#qSqp9$33(DVPYr(jAUVQqJ(d8,r!UE5VM,%),cGBZYl+)`rc+'682Yl
- X4Tj&[Be4DeX6I8-(S(j,82q*4akSK6Dl6IeLpeX,,@*3la28faQe"P4['S95,5q
- @,eP8Tc1rK[V222)BeD[,&bqhI#Qqh+eVS8@-YhjA8,r#U%2KdC&[L4,U!i,k9Di
- 3,I'm4JUS$`VUedaU8%p$T&`V&96,"HF1VUZ+qC!!3QlScFTIjlN"e'*Zq,kJhYR
- peQ*ZH%K3[m'M(04LEV#SGeR8[Yc`!d&Gb@1)8BQ23#8hV1V@Y5mh,&jZGAT@'c'
- %CShAfXK5lqC8$5hEIUV9(lT(8$&!N!$[!MiXU0rNdD#Tl8(Q[H9%Jp99ZTG(!qB
- 8h%B[HqZ["I9ER*T*pH9+QhSI9kJMP%3f,p6PPLr&Yq&S3k)KK)SY(8cQZi#r%p4
- rB96Qhq!T#kSeEImG6J@66,)QABHN(ZVpM&SprB56qTfI9[p@8,r,U+a,dB+*kJd
- pBP"r,kJ2@&38PLeZhmZLIXqJCT,*B"b64flAeU)qb#-2r3D[FlL'qUrGe'"E@Xh
- 2!9M8Iq144kKUAlaDe1pcA8QAJJD$@dAp39!I-ULYHV!eSFHpq3D,qJ1Z%"jCc!e
- r&03I-ZS`fK&*`cpR3e2%TMl-h`T0L5GHh(%&kk8qBP$*G%jI$2e*82qG8@X6'Bc
- ,T(2paMA8(r'hBPSZP24'B'hUMhRN%DVHe`@dU2r4rGC%N!$%Jr[@2`[U6lLZVD'
- `jScd%HS9cra+8(r+XaFk"l(mC#rHqTbJrSa68mK$r42`&[94VLZKpNp[2bqS2qG
- [6@Z&TP+@qKL2"T+4*lLMl&RU,rKEk649UlETVEqdU%jIEJhe9c`DD'i0`RE,MBB
- A"29aRP&)VBcb-*p4rL+S6h#&Y05%`N#P6Ide9iK8$1PB*15kRDhqUk!qb4A+T*+
- &p!AULi,k'dDYb@KZIF+T,`RU8e`KQNfmJ1eFdP`YU%r$rBfm&998*TkIFPjDdbL
- S[f98iRB@aJKKf1elh4d3e'Ii@d'0C!Vp)65MZkQrJp-FcP#9921&cYcG0B,k,+2
- @UZ&JBFJ49#XDIYp0*D-fQkKrB03D8#-aCpU,8SF)kKp0AB01MFHT3`Ae6mbTG26
- a8E8**C['2)be!pV#,EhaHX'KJ[VR+C6D-#F80S#[2(M&h8pq59#IBp6k1I%&dFJ
- FiVM9mdD6HYfUPG4jQChR'AAS[)9Ym("E6k681lUf&G3A'(AdY(3U%YIMk93S#E%
- JF1m,9YcfmjF%p5pFSDNc6Q`k0aV'M'j&SEmbDXdF6!pL(Y@4b+Dqb+Le*mkGMjN
- q9eQEqK*Ak&dCc20%i'`hU0$I'(@i5Ce(QYpVb$EeCDlVM(C-HhUKCe1l'(A)M-E
- 'D9kifP3&eV(XVD5T[2QYLQ,%DeYE-MS2VF"+0#K92+2-42e8b#Lpe'eicS1Xmq!
- 1hT4HX"jY8lIP#M8bcdMR[6DeQP'(89fpm,1T3aKeZa25HM`@4eF%D@mGeUB1jG5
- T-aT$i36,Hb9U$Bq'U601LME(UBG614TU'AANe"Rcd5#D&e9EefGeQeV(-qA8C"b
- PekC-UG4E-63hV-EEAT%e5feJe1S6jdl0*kmXG4L2KQQBf%LRh'aT8lGMe$U5M'H
- J5XNpf+B1jlT15bI6DL2b1FCQ5lU1i$&d5K`ZT"fEBfJN9`K9P+kQh5,&TSlLqA9
- 10*ACNPp(Fi@Qad2*0!B9()AZq0YaJVSpVfbQc5&alLBpqke[iVSfSQ'M`epeSki
- lF1V4S@3bRFD!lL"eM+&VY$f1%Q"6j1h)hcSpVL9Q%Aq[`EIZa+JlN!$+KQE@UDR
- )0$6"B!*P2GbQlX`9QTP1dP*qSd+l'&88FX1@+0q9[r8Bq,k4358hbPpH++LlmEI
- 14U@ajDe[jMAPl(3(5[200HAZ[')l#92p'G@0@*XkeXJSU+&#c@kBfp3pH2CUR$f
- Aq[c1c+6#kp#IZfqH4Gf64`1+QP$EIdE$AMcbjNDECkI49YiBj@rKeH&F(IE&)69
- #-XXVeH&YMmdAe,FDEk@UEXiSEq144qUKI%r%TVkG4lPAi['-8RZ@S1l0)fp@5Nr
- Q)peqkck'3QJ!E&&SAb1raKI-`3$mTQMBcqKl)FLhj,cpUBmr[&JQM80Tif)lPhl
- mKpfG1@8FMb%XZ%#DSJleP[Z(@fmpJ#ZdX$hNpDqJd"F[[8p3$f3G4q,%`&bM0i!
- lPqiPTYq8m8cA)F52,9qB`eP0q$JU"h'&-+UB5RYBk(U(8'J#[2j*0,#T##q'&Lm
- r5Ecei1iB5XDE#M&dPhMV4*0+-U@A[9EpkJa"RF5S3fJrhiX'[(@9S"l#Si'Z-H&
- K1`mrDKG"2C4&3cAmm`SG%@58ad8d(-DSYD!')deZm3AU%i*k10q@309#iiM2Yd0
- GY1SlJMUCjBCD[[@$5hhrd2F)kMZiYcha&-qR5XbrLKP(j3Lq,3&6D'*H)6(PV,b
- 6[E8DEqf,SCkp"j3MXclkZ8cCiiL[(!9hHk)3TSHT"D'Vd$fc"(9+GrB+U9iHZZA
- qdG8L0dcPP3eX*JYBj+'("I9SjMGI!rrhF3G2m2,VSP@G3U&TYLqlUq[U*N'GcUQ
- S'`Ji6id+kJ`H$FPiDccIF)#ZG`TGCklcJ&q(l[@!9il*ZVNl8@kjZ5[(VR11hr"
- @LcTVM5rlqXIf1U`VakehMPp$"[9d36eqMCYljDfcer[0[r,@X`59qlp@`lZd2lq
- ZIVHJ#[rAFDJGX#q&Sp!L3HAqVpA`9bkq9ALP+ifmpSV"6b@CVj@r-2,c)U0`reI
- Lj9a8k&caeT0il@9-+lUe9med3CeVZVJ9LLMEq8QCPr99FV1Am"&4j[0S#1YS8ZD
- MiHEND5)D6QC[aBB3HM%DK!H'FXU@MSKikkRXVEAKC$58`R#C9cH)DA[P0&ihC,#
- SKZkff%L8rdbmpA4'EH!pd4RRC5V6!fHBXjZ&B,!R)j8cHfI,[#LhCXZ8XqcT0cF
- DV$NfjHbHL65[hp!cDDF%H@m$-E4K`XD)S5@r&Y&`$UFLJV`B"rAfBfF,DSMR)EL
- U&4ST+fiim&j"EH*9EdEAk'4dMV[LkZer)UKKRSHdK4VQ'r+4Yr)K3Bf`A$iD`f[
- cTM9L[U3eR9Sh-`2Udb+'SS`kG2ldaXDM#j'h8VJ)+$&'(6'9q3QIQY``6!(U,`@
- eQ9'((429jbbFe8MJ'bV4P@+6"U9P5cp24%-Fqhk3!*a(1MhprXT,a&[2CG4k5Lh
- -I0pcTU!Q,+TRXGjjGBe9E53CPH`)3KFdbBf+iUeLm`QPP9'hSe6-[p+i@mX&eDU
- 98jC#VJ9'PTUfqd2Z,2Y2V3UJM9'(Xmf'@T%H-1@`PSeS%#j6bRRmV4K+lhF%Z@H
- 1S+UFbRfq0e%e+cGiP4i8%Uj&LTl0+$PUEdE*-)@f4hGSR"C[DaT(,0E8H(0,lkY
- YKGSCGCMB$QP$TVcRH%(YB&6iB1P4Z&Ni0C[peJ@m!N$4m'S&X*!!ed0a92,&Q30
- "2Cp[i4-1pMNiS*-UA-'84BaD&`lfcDAE91lr@S[a3CKlHGZC,)Q*bAlP!ZcZ3Yj
- +A1SKVH[lFY90%`Ae3ND&2b8Xh(62%fM4kLT"[DLAQ[FmYUJA@e5bVNU1ZR5H&AQ
- Ap&,GYbkGrcj"[C44D`K9hE$C!PI)UXX[-f)S#B-dC%XRKTEH("(8baQe&JCcVM%
- 9LeIK2k4F`49#SGbFF`9G4eh-&F)X4@(F(Y4("29+2Yq!D1M[jkem4P#[BP5iN!#
- fNQK`He&,jpB*kYAF1802af*DSE+aA"q8DhMI#cN2Xj(amce[MmF%GBRTr+3'3hh
- qH6m5e2Gd[a8@R`9Abam,+[GrC@rYFcUaU0crP9(cMPC,BPf#D[Lr%QVIjNQVIbD
- Sh2q9eJeH-1#YcF*K3Z(qVe5KD"2'beeGIbkSh2q9e5LZa@H@D[Lr%QUreka&r4$
- I5)EU@YMVb0S54VQ1G`%*0ErdMpfCZjj0ESh-HNABQDpckFA#k85jJ9&(fG4$$N[
- d8Uqp45J%!k)AP"fV6X@H!01%Y`$piRY9Q1G2r2iA8UqU8@8S[pI`Hbfrer&l0Er
- Aml[#lc[`qrEm2TcIKl&li!AL)S([)rR[jT1q0HjMq2I4C'BCpadjVi[rMYE4q2i
- brpj)Z[qi9r([1r(l[[bq-lr[`ZqlNLPCh2IQhhIMpcIcGrf9Iar&[cr([`rKp`E
- qZaIjpl(m[JHC0m9p'rlp6Ibq,HHpa1prilrERGrhj2HhNeP,h2ILhpp#TN0a2iG
- dAh%rK%bBiIj@r[[Yq2eYr$k*c+hK[Jrr[Kprlr2%i`2I6b2pFpb$T!H-HiMdCh&
- [)KeAh%G`lJ&NmK$hkdP'![r2a)pNbPMi#Uj%9KM"mP*hA['h#1ZPi8VMr+)Zj5$
- SG3IZ9&IF$mEhZh#I5+EfF+GkiNle`[e!-YZ)qrjNjJ$h3h&r(2I$F(m#paY),X4
- p21PqkSh+"$*TZ,a'QBc[liQH!TmpXU[Db$Ak&IX[*ZamZB*qfPMP*$*TXQ3%dc'
- P-afAM!Jm&hJ"-Sc*kZKhK%cBSJdkXRb'lc32i6i1[b2IIAeT[K%kadLRqh@pF6I
- dMS$r0,j6hA%hG$ILPhB3ZRAhpe%c$imA@8,m'[SCq3II$bIcPp$a!EMkN@frE"h
- p$GR-`lN5!"hI3@BdT3"kjZ,5hph02(5L3Gi3PlKRGH4kL2c5YdfFH@KI9ZUJia(
- 3m6k4Af`GrIhQc%0RLH82q8ASQBY,Ir-kmp$*BbP%A"SkmMaKaQ9a&cccd+PQ'84
- F1MVkfqQCKdia'cTZ%f-kiNjea*hUL$[9%AHU)qj84pbTMVK6(A'R1Z*1GF5GkSJ
- le4&hUZ1h(f3kiNje(+Xi1[VlmTQ(EXNQAiK(p!&kiP%G@p#aX-'IHHMNX"3LVr`
- 3lUPNRceE4hqR3223MUi83-Gh%Mm"SHH4q2kIq4r[lqPEM,r9dGAIHY!mG$FLQBD
- ZrPk'jU'EYNJTG$AUjfap8p`Fd6addNT+S1YVHVBYC(V1@1E%UEr6SRRSI)8m)Ni
- lPc*G6hr3L90rkdEcd*NLq81FiNle6+r-jjfqI5$03eeGT3*krRGmV[J#dr2bCpe
- q4h&65I23@4[j3PhDZDLh,S8!MSl&h5R03bGP*3`k,YfXSlr0TARS2+em3FI!bPi
- G1`phG5cZPfNH1ZdSBG#4jdFc(LpdG5aZ['QH-A)'(9HXXZ0aXDYMF3G2mq`SCp#
- akYaH(@XZG[ZDaDe!cE16R%((I(q@pr%0(Idp4FfcXc4!ak1*%p9Q(HG0lG8ahBi
- p!"kPe42[hjYjTEJjUAPfN3lSq&TF*U2fr"Nmd2!14#DE0d'F'[@qVDqrikPjGT8
- lk2ZKC8aIh)hkXU"RC8CV0cP$rXcUL$Z0crfAQANdUfGa,eEc[&N@SDICrq2c)kD
- 1a8eGcE0l6XFCZ0rjUTl6L-IFkr-dH2GdF+2CH8$%jq2B"X(F5EGE9hqA@21-P3l
- S1K2hqEJIJr[*mJ5G[4eFcE1(G%$RBlQqXh!r4bUJXe([f6VlqpUDCdrTJ-lbJ6J
- fjRCYIIh0FXfcPr3JAaf(qqQi(bmGL1YRX!@%Z3Ab@Yd(-YKET!AjDcEZC-jC-T!
- !amDXG2+B[p@[HGiU(G"E2U"[VTldp`mfcpZN!IT+"[)8G-hP+Ap$B[1mACU3!*p
- Idh[-5UlhSrqPGlQZh&Y1NCG0[GI'Yq&I`HG2$EhpVC60XimdS*qcXDpVa1ZMaVb
- pSjqr(l0jpT8qk'Id"fhpr%fGcE1Il%%rj36LD)[m-JIhGqIc5G&6b)4p52S3MdB
- GaqHBcAa5h)(D22[Rp+0q22p(ahFKVXl&r86F%krVLVJdqY!jAIdYVFdc6Y+KUlX
- 2XRN1N!"$k'V-3C9dp6IG0Xq"XSeipAIa0XpiDB@Z4RrVP6b8hrVC2!G*)r)3p4X
- bp$AQF#pkY#r2j[H60Xm%f8BqmMF[0mr"8SimQprafM`6T49e85l2qYZVQfH5A#,
- 2rVhZbqr,ECj$C"[eV,m*[(N1PA,NfIc'CHBj6,B4VrifpHBjA-T4lqAh0MI2C0Q
- 'V[j'qZCjKj3M[qChAcI2%A)1AFYehMZP(2Ne[cqmHBk8FY4$q4hjc(18Y%*ABrk
- %qjfCZT,0l5[c$P0bZNS+jM@J@ipqZ'IR6h*kdJhl+h-18b8EHTEQ'ik@CHKC4r5
- Xc$9-Nf[S@DlMd!18D15EbKc$$-Q'RU@jKCQb$$eT[9DC9cK'UT%r+h-+adSeiV-
- bRc",UK'IPAQ%if3CHYB525Yc#-G,0H+c-Rm`@kU42bYc"h-N'hU@jJe1N!"Ue01
- 91B-6T4VjXc*Id#MAd,0FVle,UT%r+r-%Q''9D1KCQ51B+jh3m`5D!DX-Rh'cRLD
- lc13h3M,22!lPlhEH`rbZbJqDElr(m+2)[SI[Jc43m*mX9iLhV"q&&epef)82IM5
- PH$KP8h`aIj[5HdlGr*lf5B-*i,4F[(*rGq-pm1Af9a&Kjh5j3VaQr@ZlA2hUQAj
- `iLe+H)DX3MriEBIDqMCRjqG-ZB*q8blYeDrUA&qrJIVh,,Q#IPff6kdAI`h3$p(
- REZ9NRV2P#[Spc2G``ChUee*9d!pE'AP,)"NR+(H)[bQA&[)hp--U&m8%FSl-)Rr
- 3VITm!80b"IeDURVemr)(mRHiTE)B4*0F3EmaihPrC$c6,jV+ekpKYEaq3B!$C!R
- klE&0Erb0ZYc4MqaP!Ie+ma%4Z82pLSGlqBrS9mTr89P&r@(S0e$raH3+qTh#kcr
- F@Ib0b0G2N!$1AB1pqc6,(HS2,hp`rI5%ArralE&N#IU0VGPF2b&rddha"[*hA+k
- Jhk@mIX+p'(qSrj!!1i,U32rTA,Q#ITGarA#RqSfYmI8Ek$ra4FEN%rUKrX#b"dh
- B#F[C@ifIT-4#[f4)`iBGIJH`9@+42pVb+p4eRj5X3Mr8(rNpj-4*bbVd)h["U(&
- r@!qR6@+4riKqTIl"H6),r6SL`9)'9'89qU&r323V$H"T%S[mTi9LC6pSA@+KRai
- HD0lJC#3@p424Vp4rECGBj'qp@5rh`$YN&[TK!FrmCT(m,*!!4ZM(piJbp"ZDd$&
- r9YjdCD'X3MpXNVc4MekbX)rJ&[hU%rT'2rVF(S,b"rdDX"mVeYBXEE,fEPQ&IR8
- *l,6EQQiIb#!A5#[LMhKjS(fJYXIl&Ea3qU#IX4m-hrI,V&q42mJ%l%!#[dLkS0p
- FXS2f&Kf4ac'*8rE&ZeJ1SH0PiadG56iIp-1l4)UKBc39'GL%j9,CKBidVc56!UZ
- B9bk6BX4MFpq#cZaJGNpZS52Ua9J`&9d`d$'m3RDK)kfl+Vj@Lk8BHD95`9mTbG"
- 45rY'9PG*-HS965XY)(5e0%*(`hIRP6b2MGf6IS+m4UkJic(BS*rSL$[G%`$hRVe
- GB1,Sj2[L,YXQ6,l3TeXIPjk10#ilbSA,%LP'[ZmS'pH4f9FjK)j'rj([YfMQHq*
- HJi@'@rd"h2G+&h6FT"qf'SGqD48l2[F,q$jCKAiXrM3eA"`r#5b92ZKRj%&E[cV
- Q2V*q%rfHFqhrk$F2HHh,8J!GMASa'iG0bFMJ*1[lFcT1ZHAqdG@[kMN9haq@'HM
- C`23-$R5k2L#Gd02*Nh#*#HTB&Y%[($mSUmL6`dL*&5*ckZ(qJP'bX#F4G(2k%%k
- p4ADQVb6+kq31F5MmjYEUelD3!&Uf&42*pE)+rC!!4iKqHNYBlbpiEj!!9HKAcr3
- E',F-h#Lhb"rP9ABr,,R3Vf6jG*2F)Rq8$6-q)U[3VilU9pk[mk0bLra4V[mq*VI
- )(hVFYlX*I&aH%ApY*(Z8r-jZPPESaeE,+aQ',C0Ck%Ff-S9V3,pqRj!!9ZM(9Yd
- VaGmRC4Ek$FEITk39qXA8D$5SBQLp11rfDHQ$IVNqCN0c1"K6XDq[Rcq@5`2d1aP
- prhYP"6Ufad-PilprN!"$k*LIIm(Z*X4p+1AhSciMGmJR[RkCTS'1b'GP&IV9Be*
- bd%(eFa+,q01aMdNT$piLUp#2qIf(p39q2ff&Y#,q@1aKY,1i4(bRl%)rQ+$ekrH
- 2XJ[p0(q2lXp,+r5MlU-`N!$hkr%[5#[U*qbR3*DEMMFA%rLYdJIpM$faE2eU@a-
- E$F"[bqPh#YGM(,k[r,rcN!#Ri[[AT!*e&A3G0"Eq*lP$A)Sp5pI&jD#ajaIr4cm
- R$U8$rDSDk&RHdL%3Z&dkS+GdB!k5k6MJPK`)I%PfS@-$dl%dAr[2dJJGmhPbd!$
- dbmAk44T4Y`aY#kN91m(!9k39p6`GV5SE-Ra9BU&I8%mMTIL'L&q69Y6c+RC*U06
- cGdJhkRRS1PM2IeeD8Fp$[m&krNkj4*f5VqHKjf!pr`hT46e2G5cAmhG*,qTjTL2
- CI,YI5j*Gj4Ee2(3FV1GA55IUH@2[qc9e#``cbRB"JG8j2Gr`-FRUHP6RSRYQ[4U
- [MUq'Sl-'XmZ+cRG,-h4fkP#L-bc$"rbrlT%qe+&1Id06fi0U1"4Z+DEBEmSUp+Z
- &@h[*a"2RAQQ&ITR8aJlIYk32qMPeCNFSLFjaDIkAd18!qQfGRhAQGZ"('!mPiqF
- AC93N#rk+VrU@3EpJU$3hU'ce)C3(e2[j1)5GdB!ILL*Im#(Fh*GNqJeX!+C)+r`
- (QAkPZPf49rJ2%[h+GND+r-&rd+N(UAkPm9pPUrqJh#"r4*Z5[Kf0i[J1bL(LVfa
- RT$JqJh+)r&Hf-e,N$lk#KRiMlI`4`[ab1TJFm0rmYUa#[rT`'0X+P$Y5rb+Yd!r
- UNAdmNri#Bpq42HLRE+H3!-bhFeDrkZNRR&5HPJX%lXrT&eKah5Sbje6&lc[cqki
- VlRKj)HkRXqq"[r,lLrchZr1lVrmqR,-I[dX2iTRjml4Jrq+LFrKhj3la,2TbkrA
- $8(e,XF2qJ24"2f0qCBeqQ@3b'-G16-@1d2HN#rSCF`jRS*rh2(kARAI)k9N(IjZ
- bffL!dZ85HKTpdh9k"Y[5kX$q$2mUAG#6kVJPcm#h*a98bhAR[dNRiY,*qm6(KkE
- pBQ4qArU3!2I2TTX8EVY@[eBpf*V3ihj!2X5KKPk'2[cG6YkU4f!-eZNrN!!fa2Z
- Q1"p'rBl5fN$2miI5KcKhiK!j+KC24Z2TBK`qR02[MEhDApXlX"5(E1qIF[e!TXb
- P&(f#fN3'RFqdhhB1"2jG9U&I26D@#bA,Jb-rNPAN`3DLRelfiIbal+)H)A'B#*+
- -ASc$rj!!2F5K-N5T`I0h@T-(@d0KE@$j2CbIf2U0iIe)VU24hrcI[JqacN8VIbR
- dEFEhTek29p`Mi$kp6[F&q0e[S9Z8hGdq&AaJBT90E(mURHL(1(UQd!qTl-Rp-fP
- $R8Pe0HT0k'[XbHMdUiLHP6f5(j91k1R-VD5e3GZh`-rP$R@$&iqeT!FkSE4'GZ!
- ak85qG2UkG!qY9QdJ(RmKZkK(QBi$ET5"`#qP&Ad0fU--4Y*qRr*AdJIp$2qNE&q
- $q$YJ)'fJVr'ip+&1SIR4b#ZLAR(bSjDD-,MSj"25Lhi0kE#RBj'3!$qa59a+T"6
- jX5'65JifR*k89HKANp&+-`lNr%EkS*r6[kFpL(+Kq*6X)Jr@kZPB6"[BFLUJb"I
- fR-V'SE'(q5JlMf$H*a-[,hli0)GQpc#hhp1!LFF`&M%-qlk$T)FSKmLVfAL!IT&
- -f8rY'@Q%IU1cqQ%1A5fYdDV)(rDU-HS#@lqK+TRM,Nm5rdlfS*pbCZHLZiH)2TL
- YBkdD$JiZ*2QXA%((E*m#pl1JBh@rMQ49R`%GIbq0d2'RY(1prCUm#"dMXB%YcJ+
- "2q4dI0h26KUJ*mXcd10Xh'X`Eri-c4JlV-ZE`B&C1(,qQ02Ak*He%$hN#Ieph(Q
- rM1Q01mqV6'm)CG5YfrIUAGHQTZR+dNA*&@0IDD0ZA8`hTk[0[UHH[UI8$P+-rD%
- hjcG$Iadk``0+d6U[VL'HBRdkN!$Kc+)1aKl3rkd$kKLU!r,*qqK'AA9C(H#r#ae
- +&QR+'rXmrcdZYU0kS+qJarYf"&1-rCbP"A("iV0NZkDmX@Hc%aIAddf@kZ(if&Z
- I`H'jR!B$LV%hXq2cD1KJq$Qf`lraH0`AmRQd$RbI)r6*N!$[L*1F,X1T5A#`0DT
- TSHCmV#M'2XbEG6&m*3epeZZ#1M"&0fdHXLCH-2j8m5e8M$fA$9hkhJY3M'jfAVh
- Q[A61ZY`I02C50R3hhTZ00k1qhF'ZKd+49P+SqripLV1rkZ[c%PGL$[!Ch+rUA$U
- h6NS`YfEVLrhXX#b-2Z#VUfcGErArkCVhMFMTkHpEV@cGGe8bS+I`#ek[CdFT2VI
- Z[5TGd(-J2VIZ[bT0d,1'k+PfP2V#@rGJI80(CqiLTfFG&J1!heVDEa8V@rGKP3c
- %TkGR,Ec[5XX1!,Ce,eEj3,iaI+Lcq5DCEQlfGfNN-'Fr9Yq(1J`G(eURVp%Rb1V
- lZKreTVaDKhQ45S0FfESrUhbJ,L9D2,8F[CYUE+BdrdH0-j0dXh6m"Rf6-e#P2I*
- #ifb0EfY16MAC*+UUF@kdZB[5kGN9[lZ+r)C%`rm(!$pV!!!"!!!!!43!!!!8!!!
- !-J!)!!%!"!!!!!N!!!!)!!%!!!!!!!`!!!!)!!%!!`!!$@aTBR*KFQPPFbjcDA3
- #!!)!8dP84&0*9#%"!2rrrrm#!&0*9%46593K!3$rrrrr!!!!!!!!!!!!!!!!!!!
- !!!!!V*!!Ti`!!'Lm!!!"4J!!!!!!!!!!!!!93faTBfXJ6dXJG'mJBfpZG'PZG@8
- Z!!!!!!!!!+3!!J!!!!!!!!!!!!!!!J!%!3!!5J!"!!!!!!!!!!!!!!!!094[)'0
- [ER4TER9P)(4SC5"MGA*bC@jd)'p`CA*KG'P[EL`JBfaTBfXJG'KTFb"LGA4dEfi
- Z!!!!!!!3!'m"fJ&F!q-!!!!!!!!$!!!!!3!!!!%8!!!!&!!!!$)"a8'i&JS!!!!
- F!$)!!&0PG'F!!!!+!!$rr`!!!!!"aB-Fq&N:
--- 0 ----
Index: krb5/mac/telnet-k5-auth/ChangeLog
diff -c krb5/mac/telnet-k5-auth/ChangeLog:1.1.1.1 krb5/mac/telnet-k5-auth/ChangeLog:removed
*** krb5/mac/telnet-k5-auth/ChangeLog:1.1.1.1	Mon Jun  2 17:57:54 1997
--- krb5/mac/telnet-k5-auth/ChangeLog	Sun Mar 16 20:22:36 2003
***************
*** 1,9 ****
- Fri Jan 19 23:20:51 1996  Ezra Peisach  <epeisach@kangaroo.mit.edu>
- 
- 	* krb5auth.c (k5_auth_send): krb5_get_credentials does not take
- 		the same flags as kdc_options.
- 
- Wed Sep 27 12:00:00 1995  John Rivlin <jrivlin@fusion.com>
- 
- 	* Directory created with NCSA Telnet Kerberos Authentication
- 		module project.
--- 0 ----
Index: krb5/mac/telnet-k5-auth/krb5auth.c
diff -c krb5/mac/telnet-k5-auth/krb5auth.c:1.1.1.1 krb5/mac/telnet-k5-auth/krb5auth.c:removed
*** krb5/mac/telnet-k5-auth/krb5auth.c:1.1.1.1	Mon Jun  2 17:57:54 1997
--- krb5/mac/telnet-k5-auth/krb5auth.c	Sun Mar 16 20:22:36 2003
***************
*** 1,406 ****
- #include "tnae.h"
- #include <SetupA4.h>
- /*
-  * The intrinsic Authorization Module, usefull for debugging a module built in to the app
-  * long AuthModule(long, char*);
-  */
- 
- 
- #ifdef KRB5
- #	include "k5-int.h"
- #	include "com_err.h"
- #	include "prof_int.h"
- #	include "krb5.h"
- #endif
- #define KRB_SERVICE_NAME    "host"
- #define K5_REJECT				1
- #define K5_ACCEPT				2
- #define K5_RESPONSE				3           // They had to make it different
- #define KSUCCESS    0
- #define KFAILURE    255
- 
- static krb5_context k5_context;
- static krb5_auth_context *auth_context;
- 
- long	main(long func, char *parameters);
- static int 	k5_auth_send (int how, char *szHostName, char *szUserName, krb5_data *auth);
- static int	k5_auth_reply (int how, unsigned char *data, int cnt);
- static	void tn_sendsub (tnParams *tn, int code, int request, char *scp, int length);
- static	void tn_sendauthsub (tnParams *tn, int code, int request, int vers, int how, int auth, char *scp, int length);
- 
- long
- main(long func, char *parameters)
- {
- tnParams *tn;
- char *so;
- char *cp;
- long					err;
- long					oldA4;
- 
- 	oldA4 = SetUpA4();
- 		
- 	switch (func) {
- 		case TNFUNC_INIT_CODE:
- 			/*
- 			 * Initialize this code module.
- 			 *
- 			 * parameters: points to area to save type/modifier pairs
- 			 * returns: the number of pairs entered.
- 			 */
- 			cp = (unsigned char *)parameters;
- //			*cp++ = AUTH_KERBEROS_V5;
- //			*cp++ = AUTH_HOW_MUTUAL;		/* also need AUTH_CLIENT_TO_SERVER ??? ddd */
- 			*cp++ = AUTH_KERBEROS_V5;
- 			*cp++ = AUTH_HOW_ONE_WAY;
- 			err = 2;						/* 2 pairs */
- 
- 			/* initialize krb5 */
- 		    krb5_init_context(&k5_context);
- 		    krb5_init_ets(k5_context);
- 			break;
- 	
- 		case TNFUNC_INIT_SESSION_AUTH:
- 			/*
- 			 * Initialize auth session data.
- 			 *
- 			 * parameters: pointer to where to save pointer to auth data.
- 			 */
- 			*parameters = (long) NewPtr(10);
- 			
- 			break;
- 
- /* we don't do session encryption now */
- 		case TNFUNC_INIT_SESSION_ENCRYPT:
- 			err = 0;	/* we do NOT do option 38 encrypt */
- 			break;
- 		case TNFUNC_ENCRYPT_SB:
- 			err = 0;	/* we do NOT do option 38 encrypt */
- 			break;
- 	
- 		case TNFUNC_DECRYPT:
- 			err = 0;	/* we do NOT do option 38 encrypt */
- 			break;
- 	
- 		case TNFUNC_ENCRYPT:
- 			err = 0;	/* we do NOT do option 38 encrypt */
- 			break;
- 
- 		case TNFUNC_QUERY_ENCRYPT:
- 			err = 0;	/* we do NOT do option 38 encrypt */
- 			break;	
- 	
- 		case TNFUNC_AUTH_SEND:
- 		{
- 		krb5_data	auth;
- 		char		szUserName[100] = "";
- 		char		server[100];
- 			/*
- 			 * Process [IAC SB] AUTH SEND <type-modifier-list> [IAC SE] sub-option.
- 			 *
- 			 * parameters: k4aeAuthMan *
- 			 */
- 			/* Use k5 to get the credentials to send in as response */
- 			tn = (tnParams *)parameters;
- 			so = &tn->subbuffer[SB_TYPE];
- 			strcpy(server, tn->cname);
- 			server[strlen(server) - 1] = 0;	// knock last character off "."
- 			if (k5_auth_send(so[1], server, szUserName, &auth))
- 			{
- 				tn_sendsub(tn, OPT_AUTHENTICATION, TNQ_NAME, szUserName, strlen(szUserName));
- 				tn_sendauthsub(tn, OPT_AUTHENTICATION, TNQ_IS, AUTH_KERBEROS_V5, so[1] | AUTH_CLIENT_TO_SERVER, KRB_AUTH, auth.data, auth.length);
- 			}
- 			else
- 				err = 1;
- 		}
- 		break;
- 	
- 		case TNFUNC_AUTH_REPLY:
- 			/*
- 			 * Process an [IAC SB] AUTH REPLY <type-modifier-list> [IAC SE] sub-option.
- 			 *
- 			 * parameters: k4aeAuthMan *
- 			 */
- 			tn = (tnParams *)parameters;
- 			so = &tn->subbuffer[SB_TYPE];
- 			k5_auth_reply(so[1], tn->subbuffer, tn->sublength);
- 			break;
- 
- 		default:
- 			err = TNREP_ERROR;
- 	}
- 
- 	RestoreA4(oldA4);
- 	return err;
- }
- 
- /*
- ** 
- ** K5_auth_send - gets authentication bits we need to send to KDC.
- ** 
- ** Code lifted from wintel code in the windows directory.)
- ** (Code lifted from telnet sample code in the appl directory.)
- **
- ** Result is left in auth
- **
- ** Returns: 0 on failure, 1 on success
- ** 
- */
- 
- static int 
- k5_auth_send (int how, char *szHostName, char *szUserName, krb5_data *auth)
- {
- 	krb5_error_code r;
- 	krb5_ccache ccache;
-     krb5_creds cred;
- 	krb5_creds * new_cred;
- 	krb5_flags ap_opts;
-     int len;
- 
- 	if (r = krb5_cc_default(k5_context, &ccache)) {
-         com_err (NULL, r, "while authorizing.");
- 		return(0);
- 	}
- 
- 	memset((char *)&cred, 0, sizeof(cred));
- 	if (r = krb5_sname_to_principal(k5_context, szHostName, KRB_SERVICE_NAME,
-             KRB5_NT_SRV_HST, &cred.server)) {
-         com_err (NULL, r, "while authorizing.");
-         return(0);
-     }
- 
- 	if (r = krb5_cc_get_principal(k5_context, ccache, &cred.client)) {
-         com_err (NULL, r, "while authorizing.");
-         krb5_free_cred_contents(k5_context, &cred);
- 		return(0);
- 	}
-     if (szUserName[0] == '\0') {                /* Get user name now */
-         len  = krb5_princ_component(k5_context, cred.client, 0)->length;
-         memcpy (szUserName,
-             krb5_princ_component(k5_context, cred.client, 0)->data,
-             len);
-         szUserName[len] = '\0';
-     }
- 
- 
- 	if (r = krb5_get_credentials(k5_context, 0,
- 				     ccache, &cred, &new_cred)) {
-         com_err (NULL, r, "while authorizing.");
- 		krb5_free_cred_contents(k5_context, &cred);
- 		return(0);
- 	}
- 
-     ap_opts = 0;
- 	if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
- 	    ap_opts = AP_OPTS_MUTUAL_REQUIRED;
- 
- 	r = krb5_mk_req_extended(k5_context, (void*) &auth_context, ap_opts,
- 				 NULL, new_cred, auth);
- 
- 	krb5_free_cred_contents(k5_context, &cred);
- 	krb5_free_creds(k5_context, new_cred);
- 
- 	if (r) {
-         com_err (NULL, r, "while authorizing.");
- 		return(0);
- 	}
- 
- 	return(1);
- }
- 
- /*+
- ** 
- ** K5_auth_reply -- checks the reply for mutual authentication.
- **
- ** Code lifted from telnet sample code in the appl directory.
- ** 
- */
- static int
- k5_auth_reply (int how, unsigned char *data, int cnt) {
-     static int mutual_complete = 0;
- 	char strTmp[100];
- 
-     data += 4;                                  /* Point to status byte */
- 
- 	switch (*data++) {
- 	case K5_REJECT:
-         if (cnt > 0)
-             sprintf (strTmp,
-                 "Kerberos V5 refuses authentication because %.*s",
-                 cnt, data);
- 		else
- 			sprintf (strTmp, "Kerberos V5 refuses authentication");
-         com_err (NULL, 0, strTmp);
- 
- 		return KFAILURE;
- 
- 	case K5_ACCEPT:
- 		if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL && !mutual_complete) {
- 		    sprintf(strTmp, "Kerberos V5 accepted you, " 
-               "but didn't provide mutual authentication");
-         	com_err (NULL, 0, strTmp);
- 		    return KSUCCESS;
- 		}
- 
-         return KSUCCESS;
- 		break;
- 
- 	case K5_RESPONSE:
- 		if ((how & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
- 		    /* the rest of the reply should contain a krb_ap_rep */
- 		    krb5_ap_rep_enc_part *reply;
- 		    krb5_data inbuf;
- 		    krb5_error_code r;
- 
- 		    inbuf.length = cnt;
- 		    inbuf.data = (char *)data;
- 
- 		    if (r = krb5_rd_rep (k5_context, (void*) auth_context, &inbuf, &reply)) {
-                 com_err (NULL, r, "while authorizing.");
-                 return KFAILURE;
- 		    }
- 		    krb5_free_ap_rep_enc_part(k5_context, reply);
- 
- 		    mutual_complete = 1;
- 		}
- 		return KSUCCESS;
- 
- 	default:
- 		return KSUCCESS;                        // Unknown reply type
- 	}
- }
- 
- 
- /*+
-  * Function: Copy data to buffer, doubling IAC character if present.
-  *
-  * Parameters:
-  *	kstream - kstream to send abort message to.
-  */
- static int
- copy_for_net(
- 	unsigned char *to,
- 	unsigned char *from,
- 	int c)
- {
- 	int n;
- 
- 	n = c;
- 
- 	while (c-- > 0) {
- 		if ((*to++ = *from++) == IAC) {
- 			n++;
- 			*to++ = IAC;
- 		}
- 	}
- 
- 	return n;
- 
- } /* copy_for_net */
- 
- 
- /*
-  * Insert a suboption into the suboption buffer.
-  */
- static	void tn_sendsub (tnParams *tn, int code, int request, char *scp, int length)
- {
- 	int len;
- 	unsigned char *src, *lp, *limit;
- 	char start[] = {IAC, SB, 0, 0};
- 	char end[] = {IAC, SE};
- 	unsigned char *dst = tn->sendbuffer;
- 
- 	src = (unsigned char *)scp;
- 	limit = src + length;
- 	start[2] = code;
- 	start[3] = request;
- 
- 	BlockMoveData(start, dst, sizeof(start));
- 	dst += sizeof(start);
- 
- 	/*
- 	 * Encode the buffer. IACs must be doubled
- 	 */
- 	if (*src == IAC) {						/* check initial iac in buffer */
- 		*dst++ = IAC;
- 	}
- 	while (src < limit) {
- 		lp = src+1;							/* dont check first char */
- 		while (lp < limit) {				/* scan for IAC */
- 			if (*lp == IAC)
- 				break;
- 			lp++;		
- 		}
- 		len = lp - src;
- 		if (lp < limit)						/* if stopped on IAC */
- 			len++;							/* include IAC in xmit */
- 
- 		BlockMoveData(src, dst, len);
- 		dst += len;
- 
- 		src = lp;							/* resume scanning */
-     }
- 
- 	BlockMoveData(end, dst, 2);
- 	dst += 2;
- 
- 	len = dst - tn->sendbuffer;
- 	*tn->sendlength -= len;
- 	tn->sendbuffer += len;
- }
- 
- 
- /*
-  * Insert a suboption into the suboption buffer.
-  */
- static	void tn_sendauthsub (tnParams *tn, int code, int request, int vers, int how, int auth, char *scp, int length)
- {
- 	int len;
- 	unsigned char *src, *lp, *limit;
- 	char start[] = {IAC, SB, 0, 0, 0, 0, 0};
- 	char end[] = {IAC, SE};
- 	unsigned char *dst = tn->sendbuffer;
- 
- 	src = (unsigned char *)scp;
- 	limit = src + length;
- 	start[2] = code;
- 	start[3] = request;
- 	start[4] = vers;
- 	start[5] = how;
- 	start[6] = auth;
- 
- 	BlockMoveData(start, dst, sizeof(start));
- 	dst += sizeof(start);
- 
- 	/*
- 	 * Encode the buffer. IACs must be doubled
- 	 */
- 	if (*src == IAC) {						/* check initial iac in buffer */
- 		*dst++ = IAC;
- 	}
- 	while (src < limit) {
- 		lp = src+1;							/* dont check first char */
- 		while (lp < limit) {				/* scan for IAC */
- 			if (*lp == IAC)
- 				break;
- 			lp++;		
- 		}
- 		len = lp - src;
- 		if (lp < limit)						/* if stopped on IAC */
- 			len++;							/* include IAC in xmit */
- 
- 		BlockMoveData(src, dst, len);
- 		dst += len;
- 
- 		src = lp;							/* resume scanning */
-     }
- 
- 	BlockMoveData(end, dst, 2);
- 	dst += 2;
- 
- 	len = dst - tn->sendbuffer;
- 	*tn->sendlength -= len;
- 	tn->sendbuffer += len;
- }
- 
- extern void (*__exit_proc__)(void);
- void (*__exit_proc__)(void);
--- 0 ----
Index: krb5/mac/telnet-k5-auth/telnet-2.7b4-68k.sit.hqx
diff -c krb5/mac/telnet-k5-auth/telnet-2.7b4-68k.sit.hqx:1.1.1.1 krb5/mac/telnet-k5-auth/telnet-2.7b4-68k.sit.hqx:removed
*** krb5/mac/telnet-k5-auth/telnet-2.7b4-68k.sit.hqx:1.1.1.1	Mon Jun  2 17:57:55 1997
--- krb5/mac/telnet-k5-auth/telnet-2.7b4-68k.sit.hqx	Sun Mar 16 20:22:36 2003
***************
*** 1,2919 ****
- (This file must be converted with BinHex 4.0)
- 
- :&&4PE'jPG#db,MGL0#df1'XZFfPd!&0*9%46593K!3!!!KqG!!!"4M"m8dP8)3!
- #!!)IRA*-BA8#53#3!aC(A`d!&dj$8d%J9'9XEQ9d)$)Z0f)d)#Jf1%XT!*!%!@p
- L)0pd!*!6!J6c!*!%rj!%39"36%j$8d%K!+`A$PLX&`jC!!5d+`#3"3)%E3#3"0q
- h!*!)-B3'!29GDpI+IQ9QFXV0&-pTFXSTTleR$H58HhELqcjEZG(RDpGP&pZkPZG
- hhCV2kD#mBTYjMD)0-Vq*fpMfc#k2ANeXBQkff6E+"hPZ-aEYFK[V-YE+lFh-cmb
- 3!kK!eAGpJ`E&Vf`%QTmA"Vc%%&`%m`3$BXL"R"bqbma-YLBc-lP46PXj68ijjC6
- 6r14QP&01Z31cLh,+cHLQh@Djf@EESlejjDDI#qdb0pYXi@G[EqCQQG[-c)8[E*X
- ,AfJY(2+&,hcK#emBb"B11@6EK$Zfm)@"20EP`KHHZI$B`M0MQffff@DEC8BjjA3
- !e(F0qVkcE*!!$H,,S$2"Fp)j5"`N4c'hRMSdMc'"-GfD)dchmb1-RA-TqlIIL%*
- VL9NXGAUmcMTaD0SP8iH,+CPCPefXJHrNiZ,amSZ$[*["JqIdR-30RLF'rAZfJb2
- mA03"p(2hY$Z[VDqUF9D)*I99GFl"H61FhVTDXDkbV%jdcR$@c",,r(j29APCACA
- 2+pC@qZSp&@*Y[Gr[UkQVF9jE%8l&B&%6l1190'E@PANVbQU8V-)ZAidi`9Z&Cj0
- SGpEkkQ[+RH*i(l*D@P2,aL)Zjq'+G$[VkQXmJiVm6UpB*YE*,EI3jr8kbq8#Y$M
- ,Uea9+0F#9#C-J5NkI9'EeZiecYTk$d@XFc*@QMHTe"$+JQ*&IN'@J[mAK@ICeJN
- 6'1)Cjl#j`P#f8[JTRa"89cpMh9lN-m"SC`kKTc!Vj*SBGVf$6@(hXGHrFC@SNlj
- *U*)p!HG8f5rZJ2CSUG0H6Dk('XQM&Yr0CaUh*aMm+2MqF@h`IEc0Am6rk)pGim+
- 05Vme1[i-iDprPFSAB`'aD,V4llQ[Di"I&hf[#IjT`K6qC[ZlQ9Xrj+6mA#IC*cq
- 05%G9p1qMUU[I@bMmMS6hm4kXSHUa(p8GhcFRA-RIC"pXS1UG19qmpF9EKh[*rhr
- Aklj6Q3`+8(8UleY[bGqrZ[,8pcrhHJ8pNJ0rqqXJb3'pq09Iq5I3*18meS5rHHY
- 2f@A9XEkI,$ePjcbS9lJHm&RATkel@lH!6K``-p)4k6#BZVHGYmXBkLEYRa")1%k
- [j--KrcKNSZZk3bpfAk(AGkr8kk1hiYfQabrjH+LZ1e$PJlf1RrQVc[AL9D5%3Yr
- U(V+k5Xde&F(X298PYJh1%(r`RTLA+6&@#1Hb*8+*6P0d'EF2B`1C9E!eMCRJ,C[
- UFBTe2T'[a4HAPCGDLbqU&E(V0[U`SKH)BUk[ZUc++hV,UTfeiR99(SrSpG@*erP
- UTUFKNiIi6$&B08YQFjNMP1&Tl(+@*I4G%C9A898(I'0PA4Rh1je&X#`fXLQ#mLQ
- Yi$l6f4@X61Kh0YE&U1KR@'&6P,qXYKB*eihd+(-eJjdRR0FdS0MM,+YeLRRH1QH
- 0@)L%`N!'`X9+0)l9M!Ak1YDQLl5@HFZG&,pHkC2PJXLDK+[PpF@SBlYK6GITVJ#
- SS2V-cj*BkPUeZcbS@k0`GG1&ejKkM+1-QmXmSV1Q"[$$k'XbHU"e,LN*fBXTiKb
- P-h@QJ`[NYZCdEVV[6Q4@A8USbe+rXdC'@aD@HDQ0&cL"Cc6j2FikJMd@PCI9Sjr
- qU3M6P%kkM"eR0F,3MKiMRppM0HbY8&f5!)QFbG*#G8P#A@B,3jXdep"FUe%b+@$
- EQ%A3Kk)@X"ZBK6h6P9N)XfD8S&2@c@6B`kbbU9HKmcVabLT[KHmk2JR)Gqhrf5-
- c5bZT(8a!#&2a-P0(Tk"lQM[EC1aAE9*mZNh1S[bf+(@i4#KKjF+0S6U%80p+B9Q
- 6rkUUkFlD#d39"V`#mrG+VlI+kaCpp@MDHV(D@HfVQB9KI#(`X3DhXlC1R1@V&i'
- Z,FFd[SU2[5Zmj69m(%S@'1*e6PFC)9B52H`[UkQVSX,5h+E1mE*dPS`ZS1V-9@S
- d20M1FS4)IBpaa@*KII98Cme)&&VkC!*06eFh2G8BDd+iSUB++i,ZSA,@Pfh9pbj
- deY&Z%$CA9'#*@1DX*HpC5RpA!K5EabT#(9$*YV,*JNiABCi+c%mbmD%[-J56[KG
- k$jf`X,kQ"V"K)m!aqQA"Hlb3!+lAm+,X96E,M@`A@bI%K[+kPFeQpl"0AA-ML*Q
- 6,H6V6I+km&RR,%#45d9d-[UUh&2QR5iLcpBUE$RcDjaL498YV8CeD6,Z@XG5f3a
- @S%bG1Q5mJMdBXKl#KK95V'0B2eE-(2SqI$Lde[[VHK6Aq-V4#f%j&84BJ`MId[F
- XU3IQf&c4SkLqcPm[Phm-fmZ+KF(k(S!bVkafGVLqb&%*JkeQll-(KB'kEPCj8NP
- 1Gl*EfB0XHeI&Kf"61SAjp&%&2J`-@VJNeK"@bmiAcJ[9+i'04T5Ndp162*HadD%
- i8jQIAFAD)icjTF8LqRSCMFMFh[NAFqpD61@PE*X#M+b#pHD3!,@@[BBCR+,6dAk
- Rr&pJbcXm+T6T%iq*H",lY6l@5PK`md8KI"DG@XSMR)))BpN@p,rX`fFMmUICql"
- Me,VQ!IUNhalKARC8f"HD"hXBl-DlAGe"Nb2-iR@DhR)Qp+VNGKPh"+UhF$X[A)c
- jh-RY2050CRahF2Xi*Cpf*JT'f-p@mQR(G#IlH#@IGZERpR18I0VCDQi[8I*TCkh
- F,NF$2P3RPqe6ZUm)eZU3!(81V#Y$eM@`EJPCff$G'E,kK(L@)J68,'#Y$PRR`,S
- bC&d$kjD3!,80eTdKkaiK&redZbjUA$@"m`9TDA+rlQ%(i&HQLmUEfH%A$Z1L,Sf
- `60,SC2Yq&J($Bpa@V(4m0AZ,93MRSP-rUf!CIRDTF%kS[mq$I4&l8*Rh,a$mMGq
- Af"fXKEd@kZm[!FrBbUCdpIG3YJJSa$0+)FE#1T@pSPJr!HZLN!$eYf#p)@40`Bc
- *BJ[dKN*F&'#e)ca#"[GCm*`#ck'+ChPCqA4hMDrH+d-0aJ6i,i$r%)ZRbMZGeMH
- +hF"p@q&l2Ab(KA`Md9hpXCh3EldJX&m)46SGi6%+h[Nc9UcjSbkbS+UL3[(j1[V
- S6i6LVRUIMQhS21&(bXbY3)6CL"#I0bfd)h`'2N[*Ti)@0r%jR4RBVl"cD1X2B6f
- L@&HcNqbR3UQ5ND'jK6Ne4jYNicIB#IBUGZSK*9KB+h$NX4$R&QT(q`BfM-0XRlj
- J4jIcGl!e0-*%&b#dAbNh,+jeG!1#c4S`%lQfq2ceIQbYcI9Lf95J80KAADZ"@G(
- [Tm*jJL"F'HVmRl+Hk*LUVNiiNj9KEMcB632NKhkPX&Gaq`hFIL(XRqU`A`%di(2
- #D0L[jrDjX#rTX+q%I9f(r5EB[paK[`2fqc[X$f(lHB+Y-1UZa%pjI!XH2ql`H*!
- !IBPTIkkZ@pl--X*IT(1H`54lK@hUL20rXZICfi*&&e2#HbGX$Pr-X,mAXbZ0[G(
- %Yl+CcKSXj1(L'UH,Vph'B*E!XYR8TZk+jmAmGN8UNS@+,'RUCDRbPU%*Te8"!rU
- F2q4p$lbrfG60#NJ"6DUVm`P8Ch16JBp%br8jC5TrMDeR6f,,dVhj0I6CRl#IGrA
- Q5Xb'G8*bU&Im32p1BYZ82H0d@-m*@5GJ(rX-fkG-R&Tdf6,f*efmYE,-khD+Z3U
- k%4dqIU!3)pQi*[f%@N*Qe#Tl1Vc1)Dm)0ML"aE)V@8&6lfp6QDjJ&KA!"ZF!5p"
- 9VF"q-`G)Te299##5fFc4&*h[mpD**9AA1q9Y0C9ji(FlVqF"9*jqI`*Nl#rBfk&
- m(X8XfXPZ2Ch2@ZaqZj6"Q`rV*%`#0GPKR41bcS1e*@4G$ZZkN!"e!kaE3YBTf)B
- ZC6pTLVc+kI(iVP-Qj@NX"claBfZF6UqmN3f$cqR`LE-l+f526m0M+6`m&Nqph%r
- ,i(%62")Z,h-$0*N[alN&AVp,FDE-+U2T9"4#TJff@E"*'Uemah%['iXY80mX*,+
- *U-(Vm1lQmd&Ld[ib4mJ0G8N!#&-q5e,3+V+2`cBlUDQ!-,[jRUUb@Jj`m$8Bl4#
- 0@#J!HXM'`B$R8Um,Na2Eae99GC9!c-,1Q9@eGE5*8@$#a+i'rN#r2f0Yl"@J%cV
- hkHM2@L&*&f8(N!#f`LRfYXXe+)*I"IQTL63d6rC,K9mZr,b%53iY91C5)VVqQmS
- ZY4J49L0#),GH(ZF)6[FG"a@-jhC"M`fm)S6a5&khXdhBlJph6BS%r,1"hJ`PM+H
- `4)&P#-14Q,r"HL41&1Y*%K+"XCiVDC4,Pm@B-D[BLBMHjRSd9h1GA,,FhQCqTfL
- `@I#rKIdj`T!!"a$bFrikZ%k9F5&"r"Bhk8ZG0G9B0D4UPBKA#e4@0L'j)&J0G'8
- 6faRUZY@)XSNYk+Vf"HMl6l0Ep6%b0%R3k"5ITllD@b[2f`Z3!-1RfC0'EFD`SA*
- PmK(a21`XSA$%k99HTa)[$r(14cch8"R$#3"G2)AYD)TAYUfCJ&4a&P&AK@@8'JY
- EPAX(,KeSBrF)j`Ma`K9U[9`kYKhfT+jk63'b2)[0$ffL3!pJIlE$[TZ9#ZH&l*G
- L&LjQDc[X@f$I'l*r&[kV1r`r#rr9l%$)IJhQakh-'pUZ0X*q6iIpGf$r9ahf"f&
- r[-2qCl$rCBIp,f(rASIp*GMhGGKr$2[E(AB2Z`bibeH8+A)5V$RXQ')YJ28mGTd
- aBS3*2qR1ZF#%&JZpMGUKUXIRK(5f@-KABYi1khdKkar#qQp8+lEq8U%hZehC)Ri
- #a1%Gi3V&QJiF-*IP0HPT+TTEB"bQ`6"iaCYTAj!!I![`R`!I6l%+3%p"l*PX@*1
- f01mb1FDPQ&!0V+M*J1d4BqpLCefP6piJ2`[2cj0R"HB&A'F#cCA0qh2X#p3aYbN
- UK!+V'BkpjMlKSUCZ#[BVARq)kI&[i1@989p9h`$UHmlTbIN6p2$El+1QhU8eCGj
- DE$NdlQF48LfC2)hqINNiYbP@aH(,2ElbkA`P$FXclbq%"2DQ-0BB[VDj!Pk0bPj
- 9+@3"N9rHJG$[KcfhDkV4,P-Le1N[-3-RTcZ%KFkD1VS4)YY9CGL!JDX[p2K`Ld#
- V@1p&a86NkpCK5kIIbd)Q1bc8K2*pQEd$qkLZI$GJ,Yr0r*JbDlPp#q`2GpL[``c
- E,)LK+E3CpRXll"Q`jh1la-Z([Dc$AJElG'kA+6SGpRNGpRQ`0hEBliApNBlm@Q'
- rVX1HMMdmPpdD3QkABh[AeMr$c2ff-1*l21GaE)qlf,90XGBb2mk9&h&JaXCDU#-
- *Mp$j9+)AjL"HJ0p[cF+LJT-4KCFXapDZihb0hFJHCEm-e56!c-cAC+#"&BQk(*i
- h-DqZZlQ`C"`Y9cLLPXR`1$D0AH`A5JEhBP2r)lDS5609aPh5%6HAA8[)IFXXH5#
- KqA%"XYMRN@IPjBL`P"8h49'kbe"dQPMZGQ!'20GFh9K3-)Hf+Dr36HJ(Zc-(6N2
- RRiep4(kPX&D&V*I!HRR)ZJM@+d2@df%j4aM6T1+f`!J@bFLV9,B-rY-lr"H%N!"
- CmIm%r1I$hm*ZHc0S3)5VZL,%FX"mpq-FZlNTaZbY[FjC3qjB**E9!Mp4rUe#(lE
- ('*@ECadbX64$hBIS`U@GM8@RbLTkD99&ADAL14fHLibD,"NThiZ,P(DfUDQ(%UR
- 5@H@Z9,D1[CJll@aAD-reB1Y*CE1DHULlKBd%H)!JTE)[MEV3h[3Af)QrbiBhk3M
- G8KlMX3[HU[6AdpM#AQ+2'S9,j3cq%R2LHbcB&)e+,29iU0ELjp+`[`K$1lDpdi"
- kRmd@KLEa10JV1Za6B*rCBAm8H-C6E%a69&je[Ecl5"ieL,1J)mj'f1rTX-q(rEF
- kl#f`VqQ`A`2lV9ej6NDH'd)6re'f%[DA3rE2XdrB-SliL[e@f(qh`hi[l)m)BcV
- LI4RcGhp6VlcUX[*DfL$RLjFjCr'&M0%%r)CL,mPP6c6eYG4AH5VN+B09UK%J&Hi
- U+)+Ehh5Zk'DYa-E3i!YKDrra&e$H([aP,hCqJXE),h,VlDVj!B,-dlZmR@Yk#cN
- FE-&'PpD$-pK1e!1cE4##VU2IG6p!N!#9P9Y[,cX6aDQj`8lm!%%9JYpA3C!!eF%
- !E%ierjGYX)**,TFBr99cr!C$f#'F[5&DmlYqJ#$cD(iIchLR,k+cpS8I)+K18PH
- '(dr&%hj1"c[GjYLFf%k9$AEI$a"80MV*reGP)ahX6[i"JNUGrRfPj0jMX!hEi!6
- Ejq!(ZmlJ!EESc"RmB)Xj-G--iEBI)-Mmj"qiQ&%ISaErFHUIL(%#MIRlRGVGl`F
- )1P2MFrfG1EJ#F[!IpkMrk1I8kH2B(dm0*rEJ$C-VLJjFpJ-%dm&e1X2"#Y#k88#
- ijl#p`U0d&U4qDk,T[,#LUXcMSa2ci6L'@!Gir8mSK!Tb,6f'ilCR1QkQriq1fEA
- P1dFLZ4T`r%2CF3Q1BAiNV1XS`k1bicV%r+i`[b2j*lj,jCYb44F!GGmP,!T(G'P
- 29A386PK@X@H&64dKJUG#R)ETA)4lTeAKJZ#DM+l12mRC1q6@Mh1C"NUDYi4P(B&
- 11T2ZG0`02#SdGU4EH#T%*Nj&r%+Qd0k4aH&)X+'dqQTCAMj2)T-0%%4KI8F5Ehk
- 9jdVNHAFiK2Yd,irLl)(I!`@$'5,ZJc2Y6VpZ`4&ZV15ljBl,`R&6NA"hf2(NUfA
- (kEK5mJVAKT-kqFIdbJ(4`fCKX-EE8E1XAN8ih@S93rI-l*BPA#NmTdRA2094Phf
- GPd)5"5FFXq(28d*&kHQUhNUi6%!Ih5EFSAQlBjCm1CP(ZE"d[*Jac#5kDRc9B[9
- ekCPCdhmjC)K-De038eY6,NG,aq&HR6"!lQQ9`aeSTN+UJEY!%p!Fe`hVk06d8af
- %AbjQjK+-eCT`P1'c[aSIR&%kcVl2&3U%Rh@dccaFMY"*4KB1'DHaTiAR`li*fcZ
- cl6R"SkaMEF*#$E)e1r06hHPBIa%BEN!3SkUDaHc#H"#B@(Pq@JQATc%+E4U,jU'
- 1LPmAmp@pL(M5iA(9rl9q-)4m@K4H,Vb`M*aQ`-Z&&ae+'6MLr-mrbZKQDJTK01A
- qU,"-'#[[qJR@SN+&5LTKA(&KNEch*"$$TUabGPJQk*Z)ArQi3R0GhFbkMZNaD-J
- 223%Ha#jBKS$%E6HjG,lm-V'6*,rmmXZ(ZIh!)@jrjY!"fEkr9EE[-XMf2Cc0*(N
- E8qc4q)SHMLNIHllmDa[FGchhbPrI`R0ApQ('l3K)i5MJlUjiX-F+aRCaYZf[i2I
- p(c#`Qp54Ir2A[j)2[HP(j5ArAVZ1Tqf4qU(GGP1cSHI)428r509(cj!!DII*3fL
- Mj'd"XX1dqq3"EUHHJkQ,l&erI3[f[rNVGqfNYNYZT4jN8rXfY'Rb-ZTC0XAbSpl
- K%U%iBSTG*Acm1p$jdi05rB)`4Z`JaBRBG`9JP`kQp)-[Ei1GT`!2M1$,,`GJrcD
- jXadT`Xi"C-"3LTDG3MMfj#ilGq%(rXCK*Ii15QcABAL,AGA$M!mM5%clr#RpL&h
- jfa1!l6,H&1X2f4fQ8@SC,Sc93V[qHZK`qm%hH9@8[pe#6[[pV*fhi'!!Hm$J#cq
- R3p5q)#d#jK*-cH5AUEVlbEi(4$#dEq"(Be$E[aemj@6V+chNf8[qRDqm![m$"`m
- GfRdS`1h`Mm5,a)rP``3SJA!qZKik(c,f"$[LQI8kEVI)C2I`3c%C%@DpHqY2[iJ
- 4+9JMi6GfcU8hS8%mCS#fkaQJl,TRNe&Uahi3V8#crB5GQY'*TeURcer0!$1qVSG
- YjaQJmqqV9mcH5bJm#-B-)$6NEENUEbXZ-61b2*2rG&9MCR,Sa-rfMjMC)5reddj
- ram`1EhlDjHqBIj9rM%,D-AIJTm1G1@MA)(*`c!KRqdY+-62mhmq2r6rkfIi$j1+
- 1rpXRPIqJ(2jpE0l8Hp4qC[$S6kGJa[q9rl[ml,rT2aPR2-f1QR6rFcj(6H6IH9+
- C4NG0l+qR@Eq*jiqbd1cT0A%NFpS0Q(VH3DV+kCMTSrVTeV'lU-m8[DdHR1"(#m(
- aRr*(X3Gq+X$lrNGiJ!rm13$l4mD(j8m"b0mHr03jPMm#+(mcZZ@[IZcINkVq$09
- I4hRAhmcL4(aj$[MEKIariT0c0(mD1I,MqPSPe2k4rZM2AhPbJr`Q[KhJAIpBr1L
- [ccq53-4Gqjm)VrbGMZQG3Qm1qZcijbHq12PPqkIYAjlmiX6RacmEG1cEq-HRf)N
- I)%CV#JlZm"X-B3FB$1,hSEi(Ff9bPRqXLHD$rFfq0IfTGIQKF!hedr"&Vcm5aeI
- m)rZZMJpI4*!!q-McE8U@(lDrL[pHIKrNre&p)J[!dIV%qU1[2T%&i&KqrIhe(rb
- 2!3#br[8hm0(qrPArkbLr(#+r$2!rr2XJTN%BjZ1J06Y!c,p["iMkpmjBeG%Rr2N
- Mlrr(2cBXMXeiCq,m*Rjd"qM22pBIlrTE1d"[rArGAarjrd+N55b"`APf!&-)aZ!
- 8-8PXbZ!([m&$FT4,XX%qIS0'eG$&FPSE'N9*DNbAVQP-NBVjPq`p(`IE'a0BBQ0
- [PJMEU`MQCJf(0@a#mEII11#Gi0KfdcFZf%i(D1lfK1G1c$0DSKq,Xlbd,YDbr*k
- MFjTJpph4ae**lp@pjKkQr)pp+ApX5Dp5lT(mhre5rT5hrZVml5rPdikhqDAmHhZ
- ![UVqHcBN1-BdIU`0jaqAZSjTqeTBVjI@-H1&&QC-A-IkA'"Kjkc&1dc[,,cGH,Z
- C%Hp4J9!2E$r(XKrI!lrqE-iqUMhPIk2bIVIqHe#[lUlkFrkMRQ@pAYR$%YjrPL@
- mJrIIiVd(lcd@I%'r[BIRVEqrkJ(k4YPTH%2G!IlZ@RbVmDfm)GLDfm4%bq+Jf,!
- %@Kr`[4EIb8[B)fr,lh[R,JiQ#8dXrHfQA[ILRB9[@,JT'"$!31p#I&HMN3P,$Ud
- &5iBKr2[k5rRM5r@RUpefI!'Rmc`B41"hE"Cqq*X)N[P*JNiXqMc59"`4DEV5fA$
- 52L'RhHk%EDVXFmRR$5FP)DGGqQQN54,Nlc9"$8d#MNqNk#bl5AflFe5*$,rj8Ia
- VJMUa)8JjdIHDN`h"R2D`rB52fdLarb(rMhX!R,R!M+XMiPZ,)bi8jHmSf1,K-kU
- ek2-,48R!plIM@bN@IBRVBM#"(Y$Ip0D'i1L!r"d&@`*mk+epb0q+pqpl!#9VeqJ
- d4c8,m2Id#Xi@jJQ2"pGTeV&jkqm!,qYU*KcARP6rbBUqTQi`%RH[aaIqP!1Q@(Z
- MiDlSY6Fp[,Mj0mf,ekkmlcGV9piP0',kU5RAMUNf-00d(H3jJCQ6VTTc4G)95HB
- jPbHCBIH"CcH9hF-jGe"GSb'TB3kqmM,pId$9YR,)ZQV#&@1ZL$@2ZAb#1I(V(,)
- DVQXBdp!IhkXD3[kF!cA)+iF1(D4!qer'M6qp$ab5hrYEjIFH@6'(mNFir2"k'3`
- 4cm!*RehE$K`bF,rp"`ad"Vmlp$B-"h'R[IZ$E8K$NZ!hMZ0e6jT0bJQ!4B!$3"[
- $(Nl#X$m3i)`)m1`-%K9!-($b*&%'b*[YB&4)a[epqbXRC6r%)lX`*qLlI(@2hr2
- 0(IjlJdSS)2KQQ1k,QI)"D4hN9!pX9fp31l$I,P!kN!"GhaHECllUU5q"eI[r$1"
- br@pH*VcK(fZ!l+J'p+2FG5f3!!r9J1fS!IZVH2qq"RT(i0X3R)MS#J!eTjpjmG3
- T(`XlpM-(X5ilASlGLDqbNa6PTBplN43(dQ!`*GQ*4+`II+h%hZDC4qfFZ(N!dmN
- [,Xe#U%TBGMPbr'K2kMepG1l'b+(c8q8ZPHc)V9-jDU1M0)i*1bD4[Ti6ZhN0k0J
- YIkULZXBMq`q3!%!NRXT2qE1MH4dCZf[V1ehl'$[k6crl5PIQAZ6@`$Upe@Z3!(P
- +DrR(l(*+Dm96Tl1QIqaBS(reMeVlm2Z)r8aqVN5Mk'dD4S-4p!$A6IH!rTXeMr@
- %USej6KcV!5Yq0,p"#(TJN!!%c0X5L@Epl[j"K,crebrrribRG[9"#2SN5TBHrGh
- jJaEp)q)0"P2ik5-j)8paAJ(`L8'$J&X![Jfq-EI,!4DBLh2"h+IfmFNRJSF+Vbf
- m&U-`P$K&R,,f`V6'D4V,lBAE#bIL)+D!aEZMTdX6*(IDY*%1BhSDSfpUi@E@9(b
- 6)`8f(lk"$Vp[&Ah%M)kH(4l"iTX+Va'R`#qPX+e`B["i`IZ#+GR,p,Hq**D--9V
- ZcqR@XL9TLKMY6KAY3bT"qYq1PcGidT3@E&rK$Ci35c)NTS'e%pCfE[@-Im[3@(K
- 0BEf56qMf2iM)+&`maLLr@i)EQPQd+eV1,QH+)pjb[epS'j[$b"VZlY+VRZ(ZERe
- kGkTLfl(aEqR9V!i9[*p!93SNH9RXE0!bAXf'H*NaH(3'kmV3%!bbrIcLi"(,rHR
- CaACVD8jDm%M,fX%*YN@Z5)XG[E9Ac&pl-EbpKC[EldK,f(Z6Q*pUY&b8RKBmQYk
- pq5&E![MjEMIe@HN0(M80BKUmMmaNM[jbK,#ZS2ApTVD&kBa(mX`3AXZejckGkp2
- CV1ihEACIkNDl1eR--m93R$&qrA&d8)[qC2"N!ITP)[+Cf+HjQ@aYpb,5l1(crfZ
- XfX(),IHraLUhSm*jk-TfkKm-PS,`LSQYl4dK0JD+Yk$YbeErq"INl"ULKKQU5%H
- 3!)JpFRKS5BNkHFGkI&0PD5#*UTB(jK(d+9*Jf1J2L`2L5'3QI6cX6,qA`JY`6r"
- *Rij%Ci5iSJ`P3!DCF(e%CXC-8XU)V%qHab+XT22$+PhLH&mCP$QUFLD@P%%[MEC
- +K&6`C5V434H1JhBh9YPPZ3G++L&-KLSdADCT&,H8iTSUSU,8HQk8*)BKa4"333P
- Hk9Fm**`PY3frh`jc"!,JIBH,c[*-J!!D+ekF9GDri5(j'Q5)jeT2f$)&+Z1iEra
- KE4Y@C%JV@Nkkk8!"bN@1%$UH,,IV48+)@"TGHlKlZ+Q@'3T*5j&U9U*X6&A%j#L
- &0V1UkMc1dk1K"fSac(6Hr+bE)[8%a*83md'G-m9AA3e*D"3Jb*e--@G@)X1jBaC
- *12N8C*Y!4NqV-bH42)FTRL6*,#cV$f-rL+)K2e23#R3QXD`aGNk6RDI@N!!#0C5
- `YD`FBGKeD+FV-@UbPe3K@C("%PCUk05(jS"b8p@6$Z1"C6&MI6#`,[Rl`)+kTX%
- B"PEe[`mXT9qQQ,C6FekdrheH4-C#QRBIIf1ATHA!#i%C,@@m81RDrCfH[[ak,mq
- 'I'E,,-&U12ESL1c9a9@#Z,J1-AF'[`0eCh"9C1i-,SE-RF%MZ$1iG$%TJBmcaUU
- LFYpB+$GPEDS('DSpm09Q-e6,la)L6UiP1%266NrmpV0Z5YN656VA-RpC14r$APP
- lM98)2iRrE"6cbL[jJ%qmXUE-(e)q05c[FV1e"!VI@Y'd6G!I#Z*8ET',%D6D2F'
- IAZc1p9hR65r`96[6mq3KQY3KYXBiE`',jbZ"9JG%)f0CL'RBJ1V4C9J*(08f5EE
- kDMq&JaS5SQ40JV3Fb"4XF#VGFM,C@F"S[4-bZ"C5GX[%@TkH99FQTY8jSd[Y%89
- ,##4cSH-a)QGLQR#[RGc)H$XEjmePNCbJPd-1#42f4NE3#&9bM'Sc8QY$Fe94[VU
- @!MSCK+3E1Cr"$EU4C[YrlFEdllV4l%&Sk2Rl,4#me,eEi)ArYJ9#bqE!&MMj(e[
- JTrkq"8)0k0%Ym*2rcaBi9*(V%YNNIP[chEB2'QalfiHq1pRfTi5fI@"malIpmQq
- hrB[rYZh(mff8-SMXPTqGeLReGMEU5&eGR*ECSj!!Mc)-b5Q3!&B&dQh-RL%PpC!
- !kNM5(+rN%V9XQ8$,),N0VE+JhXhe#d*3$%b6[1@eC@Re9IAPDFk+HY"eqM3VU"E
- I"A))BD8JU8r5RJmHCTVJ)J(R`pqCK9M4AB*Z$PkH4XLdLMGUTYeb*NT%DJQ$dh3
- 9'RSYI0Yd$-9fIUi#ZcjQ*8Fc*%mM4EH"*4TlQ(6cK"@9+k6K"D*@@+P9KC!!i8G
- "Z)U*I%V`lkmZ2E"DBYe[cjTbhCX"e[rp@EZ$Iid[erpZph@r12j#aNh(YrGpf4*
- l4fHHIhlT@d[AQ5qH@+$25keq92r,53[XYm`E&e'blIUfdDh#5Ne$B1$MM4V)hi*
- iT"pPXiJV@DbfPEhefQ1rY$2$c1IE'XZ0jS(a,f3X'"M[l,%hBpR8JKG5QbURcbd
- SDEVYELM$DUFmXjX@TVaJHRNUNV#T&-T@aGC2[5"GX)Z*0Z&#+HPPR!X8kaVC`2J
- f&Rh9"F)*L5fdll6XBE(&#kmjA0l[kIQlAZLpi),iUZMA-TBj#Pj)DVThl)HAEAV
- RL&QYCqk98ISAM!p1rH`h(reNcIXMlBrM-ACCbDK9AcT[HlMAMTmNjDaF15ATjFP
- lT)Zb+-pRTHL(0HXd%V[T9`A@+AI&AY(2h25,hLa[bSRHRperr&VpYM%hV8'HRdL
- b0YE%0Ll)#3BEZ`9`lRK`a%m6fJHX+8IG0q"4mc+h9%q-qZ+p5BfDkjmmNEYUX@h
- J%p1(cl(NM9Z4Frb0hi,UH#(9FrL6&JY,XRGlHh(LiDFAld-p4rH[dVpJ@QBTH1(
- Ha%4cl-$ieJ9'Nea2GdTHRkBAM*6Lf'8j`ADlE+Qf4haHIPYMVeG(AA$A,5YYSXi
- hb@Uje&i`-(i(E[kiRXE%aj)d,+NdpiV&L8DcS+Iqc("5RJX+(TL@P#Laa0MjliE
- bc&li8r*GH1QffM8Ak#dmcf9V@LF1[EDmM1RXSULljCHfLdkdV(jfRQ8SjBR"GZT
- !e(20b-[""[r0ZcB9AYYr2p2[qhchbI22ZqIilpVU*Sq0bEMSipE8a0M'EMc28A0
- e'T&GS2rG@d[A[2EN3p0hIrDdIHQDpbppD,SdDV[J`3Mp6'[`h3prDK-MGlm[cG0
- qF'[j1D2T%#F6miERCeJq*iN``BUm&VhQk(T1$&K9+J2RRLR88akDJ[qBme2p6*1
- Nq5($%1Gj$G96+6GlMjm@HA)PY*3&'U1rAMVqmHG#L4+aH`c$bR%5dKS&q@YR3-K
- F%53HRJe48'9B8UF"XUM'HMNANU$U)!DU!5cr5b(6kLSFp9i,`Abh3&JD58MmAFL
- #r$eSA[K$U&Mi2dM`(Q5jrCq3!,2hej!!SI@h%%Ai%aa4[JN#b8k`lEZ&#2cp3Lm
- K9MJAUJ0'#mR#)1JX1&[)%NB*1B*9'#F8#41%(`PPJPZB,RL&1Z&ki5G#Jc"I@#`
- X&fi@EX(r+m+G`Me#Xr#3!2#Bm*5`4AK'H%(iJp!Qr%Pi3hK,H&Ii3$JN("D1#*m
- +ai8[FD@5S$&SHQ[L01GT4-f&QP60%%f'*P-c#U[*9)e08k3Te9bPQD)Tde4SUM4
- H6DeQTZDRQNE0I%f6jNE05XeYQTpVeQTqU@R42+4j6218CS[Q'FfcQKFe,fZfDel
- 6r!8+#AkSfBrrch!PrEDQAD[94QS0@U-f9KZRMGHHVdh8AU3GSKh'j61V[jcS*G"
- @b4[hacIk#C(D5%dNT#I`Rfaah%)qiLPfjdpqj'R&MASImqV2J,kq,LmR(e4l)#[
- p0Q3ELG(kqfbPB[hrihj16e!-UbIkShV14NmiA91+&UdR#BT-R+LJ!!PdfJi"(d(
- YLjM+0,C&T1C([q&FaE&2TmIjZ+mhl3laZCV(cJ)"d4p2IX+[Xek6(9l'(Q0[![d
- 6r4ZY,(UVNLQp1&-M9ej&)La%%FK"PKb+SR!'eq3rA6VB,M,0Hp[1qH0R@8aS(EA
- YXrCpcmARThfbj52XN!$AL!AKQTUC*K!B!0#K8JBGGJ"d'-DfDppN"!BBJP%E&!D
- mch50"$kHZfdQk`2j%r1!"G3d-qf!M1('q1IeL@*qaV),iTp,m@)e6S&YLPM+SMp
- r(NZ9NbQ[SLEXN!"i)@#(aqIU)mUhT618EG2DSDR#`2K'A50*!Cb@XCBPrBc&V[Q
- 6I8ICY5`LpS*5-IjjSc'G-[8p9h!P-R96TU'Tl0CadHDj&jr1Y"Gi5&dC'c(eJM3
- !$kG'(Bk+TNc4C!K*QCi$QDYh,mcBH3&PQR2lPS[blppDr')ECESZre'HkD`mSb5
- mp2XQblJ@C!VGcC,TcUqKKh0MkTeBeCpc*1S+eLcjI'$mVjj[,,bfZj5IX3ijZ`C
- 1[QPed`@2Y%E&QSm$1GQKZkhGG00[FTl6jeplG2DHr)c%aAT*qfP4G-fiD5"P-,6
- (F@cr@Y2#V"Hq!KmZAIbP%q$$eEmqU6eqVqf+!IYHUcLCZcKfEAl'Ep"l(IG-AYL
- hp)),HLf1R@ZF@V$PSUfhS324Tq[b-aC-4CpqSVFH0EhKZ[0rQm4DHIH%0)"6NY[
- 2`Jq6VSMiiTh9J"r14NfI@R)&dqpZAT!!@p0Fh2$a,i1Y6&FqQI9pl'k"pHiV)01
- e4Z-j20-I&-LCRVhi!Ke%`(NX+r6@4MA6SK%!)&5Q'S#J6,-q,jrBU,12ZN"Im,[
- S+h)q,6(GN!!lVlNi2q1A0&@r2VPaiU-ac(K&A1rBU39,QX39I2Em)!@C,Sc*qa(
- 2e,qJ2&j[$YH8)"8&G5b-IeD&1MkCFHh8#k"C"E2R`TG5Vf!4%c-DRpH9SRYqMfJ
- e4NpZ(&Qi#[H,2cV8CmhBSBhXTV(E2J[Xqf[##fRceqh*@VNi4f-qf4FeR4$1P%!
- 9$AEFrIkB%0MaM&!03JQ!(Gf&MqqrJ[AieEE'h'jrX,f3!(Bp`B@M*[-G)D6J#Ji
- lJK)NmNhX#'XY+k$LM$*01'iN@%9(LX!G#Z-3Q-6D%G3[$TSp0)cBHrIG5mUJDmV
- !5RqQ88"'C-$B0lSUdlrrk8a2D(`I*1&R)5XR3CcI+HL4db#3!$%IZ%Saa(1@JAa
- N#S$mLb&&jP+SJ*N2)Fd0N!"1fJ4FC38%V[AL+P[r&ebP"kK+!XG8dL$Vp&6K)Q'
- `N!!"A5LP`&-UJ+GF,&`"4196JJ1)5V03,mc'Iif`!*FSQi'RI&RiZA#hF*r`J2!
- JrRmNE"4q,E3+[a0H%Pi4GJU[#lZ&Gi4p`N'J+@m**h(ckpAS0G'D(KUMTUqQRbC
- "Nk5j@*1Q'DE*dSb'TT+TQR'D3Nf*CT,QajUT'VI'SlP@FjeQPQDfCUjQN@DTCSA
- Q9XdGQVXdp`*0H8McZ'D6jMHRXC5reHc9I+JjV2P8Fd)6e1Ud8IJ(YAd8*18dEDS
- fA6YFQkR0dSl@@V4MYCGT#dmK+bk!V$lDe2mGXZ,VTZZQl3D8#(mAYiQ9ATk3!#A
- kea(TjIVDZpHMrdq4GA6dVrSl0JrqPT@UT2hNEFJficpcPAVTZKkVK20Rj-2ZLBq
- ckrA`ICdIeG2dJ,aZ$1[dXrF9ZFTpaFI)5Ym[9BTDMr2!k%q%!DXIdc23PM'&blN
- a&irrkjF3B'YM@PQ60,`e4KpTAQGQfm9'3f4ZV`kNJ&FGbZbd"d-q(@Z1ZA&XFmi
- P@3edC1(DGYd[2[Vb,bqZiG$++jqG(haINPU"2jfc6!9YKM`qqIdjDBYe[la+[##
- fCH2cLEG1l@fc4bAe,EVd3`NG8a%9E&bq$6e$Q5jEFjMeRFb+HrPCm)XIHpi5@3l
- R#MZBm!NIG1qmZ-@AmeE`VYfIr5EiIX$45[JAmdC`TRrk6[ac'536eUEb1e4`aCq
- D&Qb*+'KFR++lPGe-jiXlBb!QFU(%,UjBd1d$)h[f9pjiVmLUIrA(pYE2I[28'`f
- lDlH8*laiS1(AlCmYfRhXi%h$eUCrFZIHKUGqqpTeGlRE2j[ddF%RliQh2,S896K
- 3ZqB$'lET[5pNM$pdfDHhAEdTCpb"&HhjHE0[cUKGc0D!k'e$H4j,h46G&'9N,lj
- jEhc$mH29MjrAm2%[$MX-E`8IrHe2'PjmHFiAadlZhAeXl(R$@%)`q0[JCb5m[c2
- cXaprp2UQR12AAbXM!J[2[Bb$(Q20Nblkk0DT,'VrRcq)X9fBXRclJpXrMqUE,!A
- IQ4CXeAjm%p9diql9&H,a2fiXHZF[B`jIXQ[h@jpXqFP22M[JrFN,ac*hYqmCGKi
- lGrFPahCrGZMAZcql2I1ccc`hEKJBEq(j&B(2T%V*Y2+FpjCIcA,'(eJdajkAdYM
- l0f8pp1q0%jH9AiET`$8edRpXD"AC+lp&Giih*4b1hpd3I1H,i'm2jEci@HBA6ch
- @F&I#AF(JS[E2R[je-$MhYhrpmXZ$b26*M'A[AlV0[q##+-VdT'fe`U6Irql'"Da
- h3@0MM2h@P,[fheFH(DAr26)Pl6TVUDBlcNqqS9(ElBDF6GlDrJFEf5Y[rH+MYrr
- belX1T6fhFHqe!f-DENUimC2GaqCmGZH[Vl[VT[-+QRq,6%I-5DZpqV8R(rR*lXp
- YDE9VpMlj%2XS0f)$8-'VY-'E(rSdTI'mRra#Sqpehi4PNcqPLEF5XiGR84bG-G%
- q(-%$C,6)[%d($ZRP#hm!me6pR-Z*59NUQ%!,J6P2HiHfPJi9P4hQr&S!R%UQT*R
- S&d-IQ8SHpL4(43F,q,R"R1'((TC8B!-RiqCL0,36M8'QCh0NB$)8(ef)ir@C1+V
- l$)3p0B$cSaP3cC@F+1*kk"lk!N4jIKP-,epMpl%()0lc%IB8"'9q!l+)ra,+8[i
- +mL'rcpk&6-QI3NVh@lLhF''25a4k#%DK$kiY6SDLTY1%9#&G')jVLr-&#p#"#k#
- 4D)C3)N`5ILa-"6l3+&`,K'!9lLh@+[F@AmDeaHm)kr$rrIr%"ebJQR4VJ4%NIBd
- 2R+I*dH5HaJHD0$j0$4!#M3pX91iY,)6J6c@reV4UIUGj5I1+TNhc*mdEQVFdlfS
- qd"c5I+)jMRqA9S1p0U$YMAZ,NGS"`!LbYFRD39U6GS4fP"DRPS-9A&eBY`Ap9a6
- kiZ)rA&e%BqQVLfJdL5%H[9RdaPIqJhGFAG$[H[bhB*)p)N6f&YC#GCA)+m-8Q,3
- #Hm)@`&q231'[#Q'qXI0#3MJ,r`jdI8F(Pl%,JV"eilXDha*m3kGLd"Fl-`5ZG#+
- Kk`&4$0h9HaF`dJ#8DllG'a3BA!0A301i'X&14CT2!Fe8rZEEJ#!Vq3"Gl3kb9[N
- lY"A*p4cZr2BJ!T4`'4I)hk%LADVj1Vmk`PMj#jhPm!TdIK(K&'(8ibaMe(Q22cU
- XCG!'FIblc$!H4),mhDY%1$@e-50QhF8CU52AQjJ0FQ#VjLRIp8U%X46KLaNC`e)
- I-)RMRdGXrB8'*LZ(pFJK$cP8,Q#'JLCmN30p1F,S"eM'b-GE-JDep0NJmJJEm8@
- f+X*[DKQ032e`,))RBp$MMIq5J`G9qP81j`hlecTmR-1C$raV(Aj6bm%"qQ(3R4a
- S+Kq8[d-2LjM%RCeIQQ3J5Zd"FDTm#9KUlrcfX-LM1)$i'FeiC4P%BG5II-r2(ad
- fXM&Mf!10hjEr&#%amB+-e(@0'DNA!efi)-!-1,hJVaPKf-!,S1jj6FDJhJ`je$*
- $[[+p!&%iJKmjC+Nj1"(-(-lkpFmb%Rr&-1TM1EcEKUS'ld8)QaYPlbQSQ"hKT)a
- c(rmeIBZB'S'bM86)5Nem&0q(3cP3YT%)+F1'2SV[`c`(lJHm)a(mb!(IKlmE+5G
- PC$b`q9&m(rkKX&(Ir[mlkNmqb8FpF),q)Cm*jPNU5[K,A',e6rK6&2FL"1q[PJj
- HT!52Z8H#dl$'S*`F'R64i(!&CdN!["cmM3DI6*-DAMS#"rG!,,8%,eF@!IS#3T2
- JF-rN`5Z8!8aM&T`HC[#*F[!,$SIGcE,"rCT'Y@a4E`RHdbUA$@k8Abbi+aK3JdG
- A'3j1hZmeM"6Q4,GCC4Ym)ILrkr2"0)+290hICSE6VKPmBKkNZ2h,0TcMD23Ljm%
- NpZ`2GSmCf`jm[A[S[C+'FZ@p5ll1J6C1(Tk)-[hHPrmT"aTbp$kHJij!QFkiGlq
- mL60[`d4m-EmP"aU3!-kZML-'L4$%VNi4G"j@K)0+K'3P"pS,)K&F`8BH!@qeUm1
- 6kkNMa)8Ll*!!Fp$BJaNK!4%`VZRl,REK4$L1Ih#@2Ddmbq-jF+@ZS6c@r&-16V@
- 2jm!GNbPhc,Xj80F&j+iEj!C5dahcrTiY%BE3J(q6D@9Vi[ZU*HUAmJN`rRH#HMl
- Xa@AB8E#T62U#kG84Vm+3!)YG)c1-ir-'%kcBj"fIe+0-)qBlb)Q(S"QSemF1&-f
- SefF`J%#p06T@bhmXqD!QB@JZf)XPK4N&&hZG0#mck,E$deZ(-qU!X2cVfikI-$d
- 1S%JV2[ZElqKYa`1X8Ii1E@5TkpFhGhka6I2Bj'mA&4%'mp[*YqN`62b&M3P#p"I
- ,GTc3ZcIlSRFI36#+ZEP-&rU#UjM(D6Le8G5X5a&aM4('1D'KMjkRI0G6!Z%)50m
- hHKZrl0d(""c4&2#e8PL[T1"Va!4&'MkN3&qNd#hd3`C$"E6(8+cmN!$6DRjaV#H
- )`!FeP,eKU2bP""$8qA)#(K&BpBF*H(VMcZDM",,qR`Smm#m9q&8#J`$d`'!i#4M
- Y%eLar(89Lc$-k[cb--23hD*qM@K-B1Il,T)dU-%!2e@$XGRGqa`MkpeEN!!"XeM
- 46cfA*5D+I2cPT@$RF+m&j5#'-(e9$UI`d6X81@#B)`I-ITVrp*dUl`%RX@MNJ&-
- 0b3%I(bJ`q#XjJ'UXUhFmH"jTaiQQ)'8B&DlM%#5J#Q!Pd0ZpJ)3jqZ61$)D,qRA
- Vq9FbN!!62#H$NhU,'12i@KP3,H`-8K)6ep,AUS(9#*)"VRETqqi%mBNL@TqqJkc
- 0F6V(`!`(I0`r`8F3*[hf9l-l$CYm'0rHT9Y"f#%&iBj90jfL[X1LDEjL9Y1B1KD
- ATL[LdC5ME`mlPq+L2Z$mmq(%h2cU-`+2(,KFQHVdPF!M[f#DD%SjU-a6(Zefj1&
- bj+R&mM#eKMT&aR)[aG+4c@)KmLHPF,(k)Q1+UM*(TM"(GUQ4qpZ$FRkhVDaD$CB
- 3pm-frRqEIe#)U(4'JG(*-lC[FX)jMNBQjXbJ%-Z[XbN-19ALESiqf9[Rd)kY%f2
- 9YhE*2fqG2,$`2jB"(hlMrAi'&*hfeJU!@,`m)f3B$%db*$N(PBHjJ)-&FbKQd&#
- DdTb$cX0FiR%V,MPJ9%XP%6Z5JfZ#R!2HUT+kQMS(0a!ScS(HR)-#!m`FiT%$CLp
- pMif--#J*+6C'0hf2YU3U`bp5i25a0p"l)!@c'q+r(9b8!R88G3+qae-!QS&QNSB
- DE'B,pT5'"X*l@l$NB"p&)*lhhDqG#2l1qf+pMXpcLCV#`A5S#F889e'#%"*JemD
- %fqebdJ'#'rZe%iF[&5U`#2MNH@J&`U,Vi41`,e!X)`4k0k2r(LK@Sf1er,Yb$rB
- 4!LeZL#Hk0N-D"2i[eZXlpN(R$L,a`UJ,f3A!*Zi6RMYp"j'Qq1e8rFfhSIP3qBc
- S!fT*D(q+IJ'p$!1rNI[-9rR&RIQ5hl$960YR%lkEP1pYXPq+b,3aHRacP@paSab
- [#$&#bMFGha6CMf2!Kpm89rZ4Mr-G+ZGhSKk$EIQPX9ii2iYp+4cB!,[2I$%"pI`
- DeZ[-l(S(2Vec5rP%FLBIQP($EPDqQf@IP''B,8@0mKHcLZ0JeTMIBE)2cCq8'*T
- &L)1[k32rP$kbhiQm"d[b56Nc6bK-lb`"#UPR53!Db6"$hJQbNjr"b-2M(6b8-Bk
- -F6qNB%cZEV`bRdVT"DBNpPPjC)m(6D,B9h"rbciVpj6pdVU1q)-d&2&p)mM8U#X
- l`"dCd2&Z410eIrB$!U2pLiem"HA[(bQMABedr[V2M(E%`kTTMABCkbQ*(6lkHqi
- 2+iha`3&'1r'9INrr&rBKH25D[`C+a'qRkQqq(D#N&jFA,#D9'HN5`2RL3!92b+L
- ,IQQEa5dBEM(Yle#)#)3IlM[F'MfqZFShUr&[mI#&Aj!!ad"1r2DaGSdJa`["2r,
- Pr0iV"jV*GHBl#&@i0"B"*$$f*6FhlMpLh`JbdMZXhJ&f(aP8l5cQ6,Sd4fNSQ9m
- -%I*a*f,3K"[P,iC6Aaami80$U9X$&Q!h3aamHAc$erab2J0TpcE%)%0K8Xi-%(+
- *$Bm)&-*$ijheV2NcA-2`Y$M)SLNAh"pS4-4&Ul`,UraJ"(i!,ckC5qAd!,b!Dc+
- BA9e85lVH%2pCXMr!$[J(P9*ElTmXl3JrU%,P6[MjjFlVQ%!QlVL1p9eSab!"ieV
- 'F,)kT[RVrhTFbeKAieT'Y4lVNA(0q3b#0Di"Ek3DBf84'1-K3@#S"PbT%A9ma08
- qAV&PJNqAd3q1G@FMqBUYrqG$,'&E6YfXb$P)UX3$ebY+Ub"d80$Id"aRp$Hd4aR
- p$4eTFB3%arJ$M2j'j$k`'d1I9F+li$QQLbH52JRZk-3hSBRJCGbi[-MSEh6IbHK
- ['0V!Ll`Eh1Dl'2f0RPZKS3!L1C+I"dhV8aL(1m")$8lUS9[!Sr`ij'CYBr3hqM`
- "c3@2SPi2JfAjB8MiH*!!dGq)DfEd0mkj&pS-lJ1&p4CFrZ&DrD3eB'8'NrV)eG#
- 3!!F9H5II`ZK[p&q"KN",R,+-dGmBd!3@Ce#XMeS!c88JJJmhiY#2"0'XKUB@51A
- -QJQ'DR"8MkjMp$H5r'!K![hdD4j`380Q8diPSlpa8388Z8"*4ki$K2DJY$pM-V3
- NS,Ab*S%l'T+-cLb&q#6)6mS[aV8HPTXaiaRpME3#D%q!G)r#A("0i`+a5%)6SJh
- (CS0rZJ`5HNV!PJqqr,1'3pm3&!k0-i(M#%cBC`q'JJ8Sq"ZI!XEUA"$BCd-[6$D
- SpHR5$p[4ZIfK)3ELC%VMSGd"kKh1)lQFUC!!kB2Y!hpMY!%F56J-R+$()-!SQ!M
- q%2`M)[rdl1#hCbllQ"PSrpN#SAPaN!!48R#54@Pd1PVKB$p)AZiMX1'ffa$qV#a
- Y4qMYCX*"ZTLQX8JQ3rJ8dGaiiI&G%*2lSS5rXL,)1i,bYk6Z84K2i%Nqb(5DU#J
- $*P!U+E5#iT9!llKciQ*k40%TQe[!"4@QP#%Fe84VGEVZL50($Y"3mTlZ89(4N3G
- CC3qNi8NDP6hQNMl3&1AkQ(A6*S`F-c*@Le(X4BD*24-ZD4mYM"R62VVEQ*(*-4$
- 4jcV'BX!`iqS@hHZFK15,"`dCG2'J`B1(Y+GV-iB0(p8ZD5meDV8R@E5'pFND-bT
- lX&k,-YAS8)hi)9p+fN(GGESM,!VAifG)8NkX6R-5L4U4m52'j(`U4B`H%U-90*r
- $(e*TJqF2cmiHFd$5jC`6SF%eVeq)()bBNl*l4k#AP[$DRC%$K`N$)b1%)e#@i,N
- S4aVG'bRjYFb3!*T0`5EPI$QkHcDL6*!!T*'*N4SUV&XM'&0'MMiTIC'M(6-Q*kG
- pM(Edk'bSI[@-kD[9S#Q6"0CcY$3D88G&D!kcULpCe%$%2eqkT)F'ipec`4JTZqG
- *ePmV4+G+8MDX*30l4HTdd4GF-NBD29V+2NqM4F''#KTG[dc8B%,fU+%ApMrhR,L
- qArB4BRUhaqKl'Xl2bT''pm51l1Z24#IPj*Md(l(*Ac*YdKL*+M*+Td8rHK*4dH3
- [@AHdckNjBl+Pd@Pp)Nk`k-Kc-T(9T%Yk#eSUPcZbAjBdCY5Pb6'4KeQ%d1hmLe2
- kI-kk4`b9FNB2(bf0`TAYcpPNLR3k-N8K5hS,1L8lV0Kqb#)FPCf$I%C%('1ad4I
- PM"NYT8C#6T9,%h&qPR6TN!$cZQ2(!BIfb"%MKrG$dBB)V2XSDA4bhj&50QlBIXk
- FU&%18LY&FVN4'S`j6`)eBcHZrSbB5k94NXPi$(Gif)2bT'aT9#m-XMLKc`KT4!,
- 8bX4hMleJd,#4SdCPMcU4,Bc-ETFd`k)`"`)$XU8aXC%MT4a6K)!@[aaCSMp+"eb
- DNc1U,p-HB6'8*Ge$'0f')+pa1*!!`i3DJIir4aScjMa8d"@9*Sdi4k1,5ETN92C
- K+6*RY#6eSIC-&PM%#%b&**D#&JP50JeI-X2!dG+Ph3DLM'-"9lc"HTp2CD3*2QV
- dQ*a4FFJ24jZZ!HeMHU4"&j!!d@INb(KGRd'ASQEGBliFVFNH2ITNYM!+db3ZXkG
- 1JdYj&qZ"+ZC&X&jiRSB"m`DEK[0bei@B'jkSS6PMa[3AY*m`(5@+PGJARBAN4qX
- ScNJXV#KA@466kP,(*%DH2a+Ml,bXP(0k4RGVMqLTe89S04%4QNJaFh4Q2q%%5SV
- U6Bc$,R)H#KYJ5'(1Pkc(3!a02iY(jFG(#lUM6$F!3h-B91'-()dD$'@BFF-L4ic
- 1[U3Rj[*jf6elMC!!XNF1LG0M3RMddITZaeP%a#ASl8!lLab%FBBMqcHS&i-LR2`
- XFS3dQQU)E@A)H4L!`p$3Bk8adK$p3DE94d9eDfG4hE-[LNSHIHQ)a1jIXLq`lrL
- d1SeKd+K,"U,,)3GMb#LdKJF95FAd1bX5+iY4K[c3h+9J4cmCC5VTaA5IXTim2c3
- lkMXKAK#`Ae-RCfEhlR2*b'5dD@,[K24,4jh-MKLGR6ek&1dMCAdL-E$LKF4X+6[
- Q5pC0Mp"P')L(U68#b2!m,(AB4Y"ch9M'!Y5'U1"`61A5lKpL!U+(!d0(pKLFFf&
- hV6(aNZbF)e)NYS%4N64%8$[ITG+B)C&IBUr)`jS44Q[8J3%#Sl8X!YfF-M)(#a@
- Q"K!b*$ZK,cCHc2Xml9i@&cNUc6!UXdGhH@fBJ#8%dk0X9$Y'B#QfNC+Hf0C!%)0
- 9#S2r*+SdpFHN,'arEl)IbdQH(i8NABNShcLMJ21L*"U)U8biK"VNKdc8Mdb+(ph
- I-"K6Xr#mARS"8JF-$IJTX&FQTBbkj(cdAlcQ)Jc!)9qJ0c"Tc`IJmLDl%ZX,P4"
- i#4K@5c"DDDUhXqiB(@J2edLN&hU2pHNfq2a"Q6d5T8X[0Q+23lX(Hd4mMQA2'rN
- CLiK#Cq4')#ph-MSM*`*9q`5UGLVPeBRTJqAV[,iD(E+LYXCT2E@Qrcd@THhEIpL
- j28CQa8DLZ,k"@GJ-5JFC$V')1$4#'JCG3LrDjj)BCMdUaDY'%NkV%iDL8'G'd!V
- *+B8BGIYjJ&k'4*`r-NV-aN+!*Ik--9p)f[4S@[@`9m9K[,N[aYBf"+2)Pi81`%5
- 8[$!,bU*4[h5-rV*BTN0D'HMK&'E!FPQQIiIeL,ZN4qD3!%JY9[b64NYMfU@)-G+
- BIM3bd&mSN`XDJbD0'4b"&&%262mhf99b[FVdG""p*ZT9U"Hd*eMhFq%2ZL1-qr1
- 3!&L')EPRjMQNkb&q1(TliKLNM4@4eRbA(LV$iM%5*T`,3d)8MISN3PST-l4RQ4k
- *$m85FIljK-%QaD-4NPNI*&D+a$bkZ&lT8BMN(BAeZ(Y-Glc1ir*&[2(G8'T)-mN
- EJfR`&VS@frAjI5Nc6%S2kNFe`qTq#PEFF`adMU5+0KbjPA6E`l6Gqb4VXF,'BcT
- dM6&J(6b['md2Ae)FF)J%$61-T%AS#)Z)3G`cGFIBeC3B5TEi1G0(BJC26-4bhXR
- c3[1Q)Ura1Z6PkRiZ@LSZ!LAV(0-$JcN4'epFE%S5*L''SKXliB4c")cB"&S-cX0
- FD1FeSrj04)q%4ZANA0U,!CG)kXIAZ4$kYe5,@h)d%r8#YQFXhGdjJJN(kI(kLj-
- Z0'+a4M2i,d8qJ8q4)f%,)`8N0P0*c(FFSrPde1`d)$9B6+PQDM,%!pm$NK-h%#Y
- lGdk2l$&M"Y#+1Z55rKIelhf54Cb$MMi$LeKmEk`lK4'IKBDB$b9-4T18BKJL*@V
- G%)[L``E&LY1L0c*lA)*e#mX#d!J$`c`c1biM-3R)M+&0!jL4rJQ'@*Q83chp0Xq
- ,4`+Z'9b*@!$2L##S9G9+jZfV3*%),F,m(*NjHM6fdI%Ja3h&MVUN6fErSEe3Yk5
- 4k'6r%4B*Y11mH+)QZN`G#1KP2pDrmrZh#`#R+#hX(NMVr*LhS8`-Ui#hqrQ$-iH
- *hGYC[+EAL*ccqPlDpe)XU0LQ*qCNG0GTG*%klFN)'1+djk%V#P()$PDZT*Ii+B[
- MbaqQN!"NKp8$(6NK8I-1Lqac8@UXP[SX6k#jk1h@mm*,T)ZM"idaMMa2`b)c-GN
- QCQ81baUC15ccNXa,,Vedq)K,D#-m$aY1"qf[[()M4fmNB3GRBC0+S)%'V5MjlC)
- `,')[Za#kMNT3p$22lhGZhcjpccNRYNmFN!#+%M6%Z*kp4er5Dq3!,HZ*h6m1Z8i
- m*S(NFj)@Uck+!N6%Jf@K6)mf6`%X-Z(mGYB6$8hTMF$f3P2UTacNkfD#Y[p*+3V
- G5hf08GqGBd545p*LS`H0lYpRj(P!93%SZ,%&[#P&)`LKAZIe)F#m&PQLCT4P'NJ
- @!1%!XX551!%V,1E'a0(Rdii-5-bMk3H8k3fTlqK4)ml[(D8lImb)(KH1MQ-kl#F
- 64k4r1D62i%'$Kk6K$c4[c+!d$+&*&k00!(jjqP'#El*c!IUFLhQ(@CD'C3GBD6c
- -Nc,3JcpM*Jdd8[#`(iqK-Xk8-A4S1NrQM!('EK%S3IV`R)YkA$UQ&qY1D!J'pa[
- !R3`K&[$CZ9Mi1pP%Y@(HB1F)!c'VcSR#jXmE-q65BHJ(#DJ)DK25KJqKY63KB9M
- QH3#D3PV$Z4P59Uaa$0D#F(E1k,L$V"[+1T'3!)e1[Q*`!3qal[SK+0pS)4l,e!K
- XPXQASQ&1"cEj"YhC*2'GeM!QAc)i9Sp909A34IG0bE`dCm`&3-61d%D-b*%ZM6i
- )[()-@ZCd0"rYqGam2fI4[4'Ra0!EQCd%Z-0p)4)Y1iITX2!"QhAeTiBG%T@*[Mm
- hIA$U44F2qM)erZ+834PCSdCKbCN`+PNIPhhT1D`(fZi-h3&XR"3TNEBEfQ0J,G-
- ICP(R!b3Bh4Fl-!CdBSp-DRHJB&M3KN"RD!K,c+5,0"JMjhm*%H2SpH6XV)acY6f
- (5aG(DC1!X)ciN!#[La2'p+2%D)CM%*dIK31R4&21k*'$d'`R`p%I2`UCRBd6Q$M
- -iJ#3!'%rcFGcHc,p*FLXE24RBrS56R(ZN!"q[EUaAN1N%I'X'q$-m`#AH,8AS`T
- M)dqbU8VG["qaU,MX-3"B*q93GMi0`,8b+E-IYQNXN`"UDCd"kB`[)5YRe-9pHrA
- Sm@@[FhYd0d!-6$`f(R6kL,6XNBR4Y$e1[&Lc(jS%D5%DFT,Cj3T5LVl))6RC0"G
- ""*BBP5jP!f2-*RJeT1fG6[N@STP3L-aBc+UJVNIr%D2(T"NeJSKKP2i"m#f#5X(
- *4UJ+0BA[%,#@Fh03Y!RpJ,F1(3'i&5-S*bDk2DT[G1m8G-J%kC)i*Jbij0+8hTL
- !,RC-L0&fLcjRd#8!4S[kBXmDKbS&pa(1-9(+`%l3`fG41T!!"Q6RdebBN`d6`AB
- *aR6XJILm`l&U61r#[KS@N`NiiEb4fD0'MMU@(B1'`dLBQ*AF5`Y!Y63R*`f(*3N
- !B5H1LLBLL3YS&Y%kJq%A"2Bj+BHJRELS#l,'(*1kBcDG3N-i!m[$6k5Sl%X[MX(
- BJjMFESQGqclQ&G$i#31`qdY2PBkjY"IbF#9J2*hEMql+I((T3'GTld3jcMS[kL4
- ZUALA1Lmlql24AfC(M-T+kKf0"6Xq1R28k%Yll@Akf%Y(MaU#*FI)`HVZkKlGI6r
- 6484'k)(Y*8(r5ZLFmmlVDiM8SNF6G"H2'MRB'+(l4)[e(qR'4AEV([dZdaULZd8
- ![hbFDE83B2+h'!AIBc%RkBl#G6FKFkr5!dXp(8dm#9[FVlJ@CYI&`X@3!,b@`*i
- 4VJM*-&(f)TMml,G#dGhX0PPJMIZ#Zk&F#S`VX%%4k4Df@XZd29MdS-%r6S3Xb[$
- A)Kh$BC'1Cfb)q8URiaEf-jj6$iilM*Yj6VP3SMFbX3b#0*(5*le98'5lV+TZPZK
- cLH-mRLU[VkT@K2FR,llch*UTCGkb)4"4fH3[Uh*lSE-55MDEkfT()UdYl2BcKH[
- "R4dNeP#5(Y30r$(V@Grc1b9(8X8JdC6N5d+CkY,D5MN4%BYbla[VhK!QDCSeTEU
- Fm!'9'aG$,K*+14&jiLT(kF6bKb,G"A[2r'c&$PCeT8%(dLMj5cFdFH$EiYpB,S4
- (acCc`2#rYL%SIhi!MHpM(QS)(UY)q,3K+&3N9#4mh"$mV#,KZ'*&J1k+K"X8kfD
- %1aH"IPk4F,JKH+3Li@"$m&"&`JNHj$$hJj*kf&jV#(jCNE#V)IKk4F*E$F(MFZL
- *#(f3!'H)d$pV#(l13m-CdZX4$Yl[F)mhe35qfa$Fa@e[b!P-rB6RL0!)HU!KH)*
- RIEJLi4J2r4B[h3qjl5@H4KF[,G+$(dUTdcM%+i!%%!J[e!%e35!N!!qN"!mc$D5
- +QL#"GlLIP2-f5N-+L343+NN$PC(Q3@JNLISJ$Ebqaer`JrIEh0Y+if+jPC!!!"T
- (ZJ*Y"@F*"'qmAZGq,kYP4UfF02j!kFmI)jf,N!##Y"I53A#%r3PraG*"f,pT#*l
- N[B0d8"[BN!!1)L%Ga0E*5,2$!H9'd(fmP1J)[1#0S$rLC88bdX1`S8+`3D!5NRQ
- 3!0Yd-Y,q5!EGJ@6fULf2C+52c'4NSX#'qX!Qb@"8)H'qC$!@%!LKi5aGDLD$dU+
- SNJaXNSadc8-m(NV!bIb-ef3J'E3Mr"!)%m9-"M&3E%N'-C!!$#T*bAa5EMe3f+-
- 0NB`C$U-!08&+-V`N*3`[N!$FFrG+iRS15m(rN!#h"UAe#6NY9`18mb-aT!3VJU'
- S'*!!X#%aK%GL(&j5free5JrcP&"IBea(5ZKb+@FX*GJ348mA*2iFphQ@Tr*([*D
- 8bQ3j&8aD*#*0*SPJkR*`T)*kr,@D!UU#fL#&2qC4+)@CFJSBf3JK+H#&PX2`K!F
- Q-9+6d"KI+#(D96UG%j6aKKV"%r-(lE`I59dU*i@Y"#R!6C*#aT)18T0@4@fHjhj
- )!#QMGLLX,!,5X*J"m%15+V'&FQ*`4Q)BRQCLf&N`Pf5!QBQKCTLEU!mD"#p%NS%
- -EqNa'F[LMA%B64)15",KB%-083FNLEd,Jd0k$QRm&8m5NekQPU`*CT+S2k*L@-D
- md8KfNQJ)@H8N5Da[2ke)f(-f593'D5#5QBDd#cSA-G#9TMIk3MBTSdT1%Y9!NUL
- !Nq42e0%S#@"'S#(3Ep)+NJE5Nb44##N(%X2!G'+S9$mVT`S(0)f6+K,EadH0$!4
- *&I@89'9q5"V5q%L5*`YLL8mX#LAE+#H,"*'Xl,k5l!Xm@8cK@,+bG#)0f3I0C#&
- VijUJ-LLPSm``H+(`P1d519Z-$f5,EM'caBK"YZKqD@4NL`NKSeX5-,Y)XRA,Z5)
- 8M%M(#3)26(qM-T3V1PDk6R,p$Xm93b#@+dDBT1&8&KPM[G"l2K+)KD"-93m*VX$
- ,L*NVeScp[%%a(@55B@kMLf5[PC,*#$TD9h-!QN%Sfd9bYSL((STQLid%fFTUK[,
- %XT8j)k0E&MUNCUCTMN18QG*88a8M#QPL$c#6I)C29A0X)%PXp@JI$'FR54PiNL4
- XdLe1#3LkqBbF"NBZ&JC*EaHhbF+13*+H@80-)V3H%KZSSH0YTiI+B+14lHET$Mc
- !58qUKj'%"&"cXrQPE[)5Er%lPKkUpaHmA9"2J4+3!"i@+6-pY*&!0@Ck6R1)Ybb
- &@&Vd2SPDb8SUQb42G(M+T[)DAiUPq`!1#E!NLiBNKFB3[fK5JV&%Nm+83L*)kJF
- F%j!!UX&$d*GB1jKqP*4Dl6&iN!#VV-fbQ#)PT)&qHV8M*36&@Q'12"RVNKL@9pJ
- S*EAh)J%8fNN*FaXK"*C!-[$qfila)`R%'N$mm%)NR4M531N&8m%%1*'B1AJN!DQ
- BT05Ef0*[%m-FJ)H%PVk$Yj-Br!`e'Da1X-N#j56Ta-#-Jih`KQ[PK0''5"9e``X
- lPJBV*('CCT)i+SV1-K-AY%5D4"Brf400$mi%-mq-*D-@Z@Q!4TF!d!$5`Z33D!1
- T)cb@D(5[$%ai5!%`0QA6NV90#S#fdqP+#Fa+fb8`SpQHGKG)i`[fLmS)6Z@8`"`
- Q@'i33bDPi"l4G*hf3qUk,,&SfT-!L-r,*C!!S5BP3%I)aLF!VB#bm("+))JVBX$
- 26%SJ'5N!#ZGi5#6T&pPR+IPVj164#S*R`KPp,i(J)EJ-CS$-!b52S'K"*#pY*`#
- US!@b%*Xc@5qAX[Y+,&N3Y5IYp,3&)6P8Ac"3'6!55[V"V$j'&4B%!684#AZHl%M
- QZJZE)&5bQY%HqKQjJJ+dQ[Z%Z@1+6E!0e"IT#Fb*50LDi#HJPk3('ek#&-,'1jb
- *ik*L-NTP[6F48K034m@`jb''J0e)9BDZc#583q+*(fbmaX!"i@3FB%B"H)#cP&`
- 53cL%KKmD"5p8@jBCQ6Gi5Ce4*PR1B1-e4K*$5Y,mjXk-0N@"%5L@Q%`KY!AU,"X
- b#J'EiiF9cEM`Mq(,#B'af#V3[aaGS!9L*aMrc4SRSPVAj'GFZZf(AEk$`6@!rfq
- 1'0!b)3GlkBjT'6m%e`$q[cQD%h*`faebX!#XjKI@6,UiA-hS4'`e@`-XD6@$'fc
- `*j!!pZ,eH+aQJ"MaSX1`e3c)*PlhU$B2X3)5UULM%1DpQJ&f-Q-4f,LD,F4VST`
- 1)G#V'3(LUpPDrJ*3'NGT8$+!`m`%*!E"TC,!)jhe`-X-#TZ,hNjBmH%#%ac,$RM
- "'5mqHe,Hb"i[i'GQ!QD#d35!-$VC58TZZ32-c%a(Y0'Y#28hU*PAl4&j`cp"c9p
- l)MF%0)0cCDfZLVf3!,2+3ebNdF5'1aqTBhr56M#c8rScj8iDb0Z-,LmUljqIEXP
- B#1#P6XY)Vjp)h(`jhK,lfppdCb`cFqJiX4dEYdh85eTk)elErNXKpD#Ld'BK*4k
- hQr@9U$TT302rVSBB`J0G`,-)DH$@M$bN)&r!kdpqX+"bCMaF4reMmjRYIV6YT08
- Np`eiIH2r,TXcmF6Ma-a`-[LIaH[2lKDmrZVr0Ic%Slm!CJPMfFK5iK4lS)5a&T&
- 1qlYj(Ur'YIUHCRSEbQUY',,Fb1Q)p8EZQ%@bVk#UXNBjAH#X3RMp*8iTY%dbNTF
- CJkXNUaMU*cZAAVpNXj)HP,USj@Uih)"B9f9'`8!,k,YZ)m!*`'Q+)e+#!8F9rhq
- @L6Z)6q#08pV1M'8F-KflM(L@aLiM5!RUj"&Jl$)kNafl,'-C)8jMPq()'$j%,M9
- f'Dj[BD-daLiMlU@abhi,@k1FNLF$!+CmFBFE4aDbi9#"Xh&m#"8EZia3XE(,k#j
- Dfe"BML8CJP((p*6-`8$L+P4`Ul(,#*YMIp3"aD6!!0hFFJQ`3-6,&NND-4,Pj(8
- 46$qIE)pj59lb)Zb3!*-6$c0V(%bBmFbDFJ(BaIp0`MUfB)CXjEiJIi,GZ(6LeeY
- !*j5NLeI-Vbqj$j2!MBYV"3E!1r%[J#)($5i$!!3f8XUNViTR0M!hUT4+YB'9Ql,
- jeBRJ[1`1mRD@4[X4l'ah8hm-*d2T&V[[qL+JK0(ml5UJK(TiN!!(*Tf9Jq5N)cJ
- 9MN@9r-dUa,aMeIJ`(r5XG'3$$E[6,UBLT,m!PLGc#1*!RVY1qY-FIp`LrEdT,B6
- #G(eE$B6R-'BD6Te-'lV4QQFm9C!!6AaRZYE%`rb3!'cKFMaRXkqXp80FV0C$1Dc
- B!l8aZmhXZIlm"QU*E+bm-HPF(f$dSF8`eh8R$$NeED,6'rRU1,%aE0D*r@8%bdD
- PI55#lMRT!$ZIhL%YLm!((@jY18kFrNES(BdIYIS(hZBkC)lSJICcQQeJh82X52-
- l!3FEk(9cLd#VZp24kNiJEMKlHj2bHXmZDVeaC"0%GV'@M$AF4e9b)KdY4#bJQI+
- *@4!VZKNTNKU'DY)hLj!!+XP!13FQ3RrqCMPMVGTE@ZcI!fYBV$8qQN-IMBRheX"
- rbBKfJce%-q-X)UDhQ@NXUK0$DJJ2DkXjNAZXRja)aq0,[35fdAXqPSeflQNZ([)
- 5$`!FcKT[lC[mpR`2HjLGC@D#V0!8HJq8+1)[VeLQBkDI@S@L&E1fC+G`GJ#N+*l
- 4S#BqdZFC39qdDc3&k4j!A-C6k2!2QLr@jLU[Gd)e-eZFphIi4@B2l*%Y1GE!1UD
- &)D!d)2#894J[SUA4a3+,(&krcepdEhb($(qCZpq[*a-Gf2A2*1`9NEd383CQQ49
- 4mT!!IH34AM*!G'K5)(,JjM-HNZ[LE#5afIc"LQ41rCLhZ90m0-d"2Vi2%CN6(Lm
- ,#Id#XA"CF)Ncq*`4'YhUd3,fjQk#F0%-qP!#(8mLb%"bbN(Ai-Nrlh!!Xjp4KYY
- c1"#9lpKPa1PN$df&GF)G4F3,T)m)!R`)38c!PP2')1%hmAdTM%P@"dVaTPp`%e)
- d1`D*pU)&CTCLNp&%%p5'E8fEX`pL8QMS9dCAE$m52a`GZLkA)H4H!$8khH9PJ4r
- 43D"kcJSHf6"L8A3A[BI%5R0TC1MBVQ%10B9b(NGj9DqD,Hm8`E4Ck"FX-F3PdZ`
- Qh"[$RTh%#'qrlQ`lpBh&5!mK,aZp4fPmC`$IAY3fXM2fiS(picQ'LYU)Q`d5("[
- GU)`XQT*6k%a9"X#-a'rm)cJ[9p[XV"MUG`cJq#@m%+X[!3LeAimd+DACDMbZqhU
- [Ie8kmIT(J-0FX2SAaIjZqbL2ITJS![6'5S58lG*L'rJeMR5dcF6HQbCef19rQh)
- fq+56dahrAhV-[28i!H(d!YMrSlI-U4AVX"2)SEQ+pj!$2l6AZhLMe@!YFS-0B)2
- p645j[IN[3mc"(cjS(k`Q[m%3c@Lp'#3[`2qMf5,,bXIc,$+BP'9J%+L1+dE(%9q
- rM9VC$5IiX`8*pL-9d4X8aePMGT%91EV4!JLdd@,l9X'%cFa+B'r"5i%Z9VE!)+2
- `R91"b$iZjeQ4,FbZQQ#C`-IXeGc%'jh-L$9R2(S'02VQ6"*8!9cpFMCQGKP4@1S
- B"&H0N!#K&J"CA'H"XJ#N$)T!-45e0N&i!KS+Kh"iN6`!Y4Vc'jJD["b%4@jX5(B
- "M`2cDXZ"4H(4c5q)m#+'H$iX8LGe[l[L,*MMJ$EQ$9S-f%%VDFc,E#NEA1Sl8V*
- 4-Ai6RHpT&r1Lm"ZalCe-Ci)#ZEbK!NA@&"lC[EFj*J3Y!421E2)1UUH(L9QY5(S
- 4V+K[iBLL!`1$plfdSJLLQ9fN1f+`ZpaGHUP2+"9kRABaM3693I'bThLMamdc*+H
- @&[$%a%S$"F4`F,@Jhb,lYBeQp&fcp@-b`EpGf%@[rBM[edP$09@XP6pHNim#-0(
- 1BiZ#G0iVLA1ET!D,pHh,Y"G-3'2UTU3[jD-EPBD3!01fp(,'+ekTC`ECqj9beLi
- DNCm+M8EZ8HZ5URrP(QLN[QA8cX3%%bb`U[F-ld4D[GeRK8CV(Md)0)H)FS&4hAR
- D,5T,RP9L,#Da[U2K*RH5qQAH1#"ij+`h"PhS$8@9M+iZ[d6U04Jh0im`*"`G#Bj
- G&VV$M'carerE+BZX@dF"V)rc1JTepFr&%eFKr8$9EfDKHA2!R@K0Z0J%M2@MQIX
- !kQ*1&`XpXY[b#ERp*!@L`H19Q2[hH'-1P,LrMAU"SF$rXX(djKPEBL,$VDrpSa"
- 0V20LRIUIYTHMCIMPpY,IZfUe20'l`rpcAl&H8NQ#![keI"5N6d'FX`HCmHDBlVr
- J88'`e%HKHGNS6Yc1bK9-haemE&Xh35aNDRC+(e6Ja(,3TbK`*[Z'h#M*fCYjL@P
- 'M&bk#94MAVK&ViC0m+rr3QAJCNAGK@Li"bp2Z-&00`FG3T*[R6QhXr###*!!GTI
- F[TMl[31c&r@2!Kh4HkcB%)kHIE`,3i1&%ailq1YarYV@84Xk2lT5hTe-l'-!Zj9
- `cL*`)P+rYm3@S!l8%l!4hVMdK`r5PPD9Y,G6`R,N-*K"`V,D@!RI%&T+2lTbMX$
- KCZV[Yli0hIrU3)r+m&@83DEVXE0kl$GU&SUMHB4Nm9*Sp2`SdZEFi+'T0Gq*R((
- Dq*a`IMKJ(iTc28+8!BNC10%@k-#jc(!f6d5r'BB@4&F,QJPCp1ia[3AYkc`l9R5
- @4b)MikmJl'S`!pTA6qB`i98cfT1@(GARYHmB+0!IpGM%32Ch)G9'e0Y'Hq@+-V,
- bk`idGfSV0iZkTHr#lYeX5FQ4[EFI2@@e3!Dc8dq!%pBLI6cEeFJf-JN&*$&lP4P
- )MZ9QaSPGYIe,Cl@LXb,c65DEZZ93%a,iEaq!(3-Pe6@'Xf$hEiI)QDj8"emiN!#
- SN!!2*&34K!VScj4b3mJ0V(LT0U80c4VTG&0$Eebi'Mp'&ZSq`1SLB%JF3$BHHFR
- 9Jaa95(p!&`p(`A8)0J4+4NFK'QEfF0Q*HM-+F%JVbY&Qp!TG[mdpT3qPq)$"4hD
- 5b*!!0c-pb[D$&jJI2Ma52CUM#4HBaG5A4`aZp"iBf$YDl#6h'!i6+Ch*UZ4F5mY
- 4XZZK8%rC'&$XXVar44eB@Q-Aj1m0CI[m!@`J6K4c8ALh&Y)*$V22F8Lh[cc[*Zb
- `bX4ZTc#&!&KqF!,E4hYNprCaBTl!9ah4"k0q3'j%lIU*8,Y'$JRNB(lJE%%J3,f
- -1Cl@R9V[NB1$c4p08X!kqh"Zi-,43Z3NkJPi28+e-h$pbTR'PUQ2f8CkEb$kFkH
- @ZZ4d5lehmc,!ZK"MJ)JKafEC6h![Q0#%HATqJS@Q2l-6Cl"BQhk*@2qkP`EZ)cj
- L)l)DkYE['QT3Ji9LJ&BMKK!08'EdRNES%eZ,Yq@M(%p8qB-Q21&hSPE[h8"mc0K
- %$6N*!%EI+DUf1VYclq@UXcG%#9lkRIT2liiQka$Gb'bhEP`9NdhdZP@bNKT&kdH
- LM5`IKPpLR!Qaqm(qNKhM[(&1Ab9j`L*1"N`L#$P8*CP6!djd'T1-pqdU5`X4ad@
- KP3+CjNLZ3f@c3Mdl3PZ*h)G+21*k[&bq"j!!6U*M638QpSd0mU2M3RVIeh&("4P
- *p['1[##F3F-VaLp#pkFfciV0Rq,FicY8C$(3*3E$f-LR4"HZ(CXNa5`'ZS*pj+j
- )PK%"re%HeqmlZAF'"U,G#FH"F,0Nah!%D`jm5*rRE'Lk!mdKB6''`)Kbi6ANe$i
- IVC!!#HG%ciAk6c2kVQ2kQ*9dN`k`R244i%A19a4h90qF00YCSLN3@Fh[D!'F%UN
- Q`%3E!*I3bZlHR5bL%DUYhK-rHrEdRp6ecDE)aLEC1@ISXIfXE`JJ(rZ#`Z5h1-B
- fSTHJINB@"iAUhejM[*afjNk@bGpXJV'c(8@BCmr@prKF"MCV4VllZ@EHaFIXMII
- BKGha+r()V[d"J%A6rG(1JhHETLZ+m6JAB`-MS6q'3mfJjjdX1K)G`rS$AMd6m4V
- !0[T2633#XqNF)V#D6G9K3@8$S%XrC"3jf6d"Srcb@YX%h#)P1('b+`I%lbe$e,A
- r"Pelp-6$4,J'X+-21#cl@b"b+L*pDql+J`hdEDaLJY[eqm9!b`qDYVr#XI18rpU
- jrGN0`%CQK6r!j'J61bR8+(bIFH`8p*r3UApTk`&[E)8$ZeVrrZ)dJVQR$4$1R'M
- erfmlqaLRHqp@,pE8IC3k4r(&$`$IrV(3[j(pr@L)HG"Xrl-3J8!IQCjeEr[ZMDa
- j@G+(p&NaqJPUSTHeQSl&hKfe#3#I[@,&'+*-,$(+N50Rd(d%REfBAqmlJ[YD0m[
- [9[!BEk&c9bbhKT(l1JGPXH(3b*i@1aq18&If!j1%jHA*TeTd,QNIQCUE%ekN4QA
- XXQI`bT640m55'dX5J+BV3T!!I3T*[p0)T++!Md+CfC!!rF)9KiK!IZp8hP)&aDT
- Bh-Pq)jGFN!#a'9ZQp&@BL[Ni,XH1Aea&m6!jc$'2lIla11XAf0Ea+bq*ehFA(f-
- &429)AG[23K8r"MLD&h&4YJ2V2P*[*!2)c-$Cd`!%mak-miZEUJ(Hc`m2-URJhqT
- Xm3qfcclb[9mIBd31PcjFN!!r2&"kEmpf6U"*[G`hrVQ1-BmS`Gh(4b9(qFNq+Z0
- (21(@ML$"88,LQ[V12jI`hFPMdFKp429XH[qDbZfMFJi-'SX#aePVeAcj)q`Mabp
- )SNKdK'$h9pFQlkpIae-e%IrH`phSrSU5NF!'1K'K6@EXXKG1RBMJ(-2SLcH8k#!
- QR193K!j*"JY3aCH*3Jd+Uq3Mm6ZP+c`I"hp4!M-BA!-NrT21PF&[pmGI)$'Ab"`
- aV%UG85%)8)qp#3JbZ,B`IL%814UN6kq,-5*$0"J"H3BM&3S,C$+KC$@KhTHf5&C
- %k+`pB)-(B9)'!b"PqK'V,'9MjILmR#1THlIc)M6-)#9NEYN1#qc`FSU,0ekTh&9
- 93eZFA,50Uc,d9!fGYr@5ZZ(&YF)ED6+RUK2'G[H%Q`'45+rDkk'U@Th#9H53!(5
- d*KkSL2p[h@A@)(!UKeJ-Xl13!&[K9jhTf)rhF'qAp(D$%`A&"CL[lHKHeb9%3rl
- VHB-UGkScJBDBlQHkSM)B(GMTHK1GMqjqmB!hp``TS6$BLfGlLP"A54mT`ZMlYNd
- NR8KSVJr$qqb,m8IA!9CN12!eKSi(qiLr0p$a&N0-[R'-qP(M6!D%rqrRUMPJV"N
- LI355Dl0N"L-#4M9Iq%hmQ3E$lA[+QAPh['$5+1LqT(q0J2`i`[Yc#f-"3[LY(!K
- @ehENPrDr0a&(j0D0YY#$D+&IVJedK'5eJcN(P,H-6h-@Q&2(XDP3X0Y66Bpq*!U
- VkR"RM%S-*fA*5I`5[jQfpMS4b4a5&Q91+HGMdeC'-pd6p)8i@R-cS&e'$#TYPD%
- 65i1P3PV,82#EV5P5ISa1UmSNbcG2lYD2eL(T9q6)8c`k#T!!&'MKqJF%-5[d$MC
- N&1X6ZkAYh1aiXDBdKeRSQb(9Pqh*reLVMUe5[G94BM-0"Nhf,ZeA[4*CFmcY'Qe
- VE6$4h8AjbD*PGlVCffEhf$ZX'4eZ4pY%Ve$(0e"8CGKrRHLaeF[-!%e!SYd0pJ6
- UPBBQq*HpaF%Fc,*'YK"c2BK9dBc@haD4q(Upr,ZZL(PJ4*ad#Q[iF&-rhPrSMM[
- 4&r%NlH3I0J*ciqK(6FcjE)emf4qFb'*6QF)&-k3rZ#a"5&)"'9%SaXl$h#(-L)!
- fMJ-`GP3EGK"[48UB6(SefBS2X3,1ajN@)T%[ep*HDHJbf1!55[9m)+jE[4q,"af
- BDKZ*d,ChAFk"q''@)&ASXV(A*%'Nc*PKfL4AZR(9FdNMAj)cCVdp)94lQ5mkapU
- $A1r[k%XChC)eE#Gf5!ZTL[550@bY29#hK[)`emH"j99")8HRYpjD)`YQrmCZ*XE
- a)-M"&D[Sq6!B0$QBI@,fPEaXT+"rQITS&TZe!QZ*%m1#"a!YlfpBiI[,hR(8SYH
- R2fYc&M1HGc`,p,dV$5f"3(33DT!!+&PZ&cVEdre)j%9kA-QqM-2Rf2TM`U@4p[N
- 0j",Vqk2,$R,#![T4'@1,9'4D$+c6d8j#mFbplk-ApFZPT+&'1dMAN!"@#MhLCC`
- )a#J,YR31ZS8l#p(aqSlUdlmBfT[prkqAJ&(dPGRarkLIJ[qa*XD!lH248-m2iPK
- ['XrITX0I,K0#pNrKI`H(kj98pXIq98'f3BCfH[&k1bFELHrGD!DbFPEDhYh&!E1
- 1CSPKi##!!JcV#"qYV0DUVG1*EV,[R0UbE6baEhH2)@jf0VhPa"XM'I9#TAVaGhl
- $MbEP)VQK%FL%)NiX9Hq#ra#iGfaZS+3fHM5`qTcjll2cRkEXEaBY%lmFp9rRpIZ
- e!26+E8p(i(UV-)m5c#@9+1Ze(l(G&BAD,2@rSc`R$J@L1$2,#qa2!Fk!hIi"8%H
- DrF2[leBbjb#MGk1$NIRQ6Q6pVhJ)G!pHk"Ych+&[m+,"9)3PE14r'3!$P`%I,%i
- B"ELaq,!i(1-iTQG[-hBqrDM'2beHTriA(1&AM3M)K0K4$J%Nd2@aN5"VG+24H9J
- 2B2-m-#-M9!D-ZALBqi`*@UJQ8+P&VQ2-Y!3Tqf"&L@,4jPkMF'd(QV5#)dr8R'J
- PLNN4@HqG"!Qli3Xcd`0%iG)R)2%fIJ`%cGk'S$)!,iPJVk2)%E@6mb(i#d"!![*
- dMd625-4+Q09XT4f2i9h1GCec'3H!fl6T,TEaDZ9eKjbAY)H030Y!S1!@dTrQjQ"
- epAY(,[eVXpQ+&K3SF%9dGMb"jk0dfXE0p45I1rd6bX6YN!!2pL"F#4eIh'*9bIJ
- I#er[+`*J-XMLC%)FTLr,4f95DQNbTq&)M"QI8pN0)BH3!#LJI68"B2QMNJZf0"$
- $h%Nr2+a5Fr$i+SJD#1l'`d00B+VZhk*q'XQ0((p*G8NH'&N&LKEX8'E(2eE9'@)
- IV9V[iPcQL(%``EiScSBTec[L#D*EP`-&Ldf5SlHDaeB,fmF%K(LHfL!0YVrHc-b
- eapkqjF$Kf&@TJdV&8"Y**,CbIredSjUYKJCAipR"iRXK(3G-FZ#PhTh,aYfFLkq
- q&HT*@)GKe2A"!2di(`)1rprh9E1GNGX*@%REd@A($l2H(bMr0lMGIrIc*D84(-"
- BXJ1&X[%@XFRbYZcN%GQKc%D2B62kj9b4($pTBdSjX`1L4eM1()b01B(kZ,QYYF'
- qcHf[0CBfQ33S-ejIK-q2j10G-m'"43"qriM'Qh2-AR+13H)N,XAaKGhXm@2PPZ1
- mMf$(BaZiR!B492GYZC1GKR8QTjk8*T!!H!)TPUZiilL[,!TU1qYG(U+cZaG`MKE
- 5A-DM2ZDY%m',kI)L6UTBf'dp0r`HAV0*03[l#)bYCT8J*0,kNI%P9b0QkdB@%rh
- qer#ZPl1-(5f"HNpfCh1ipGihf$Qp#m9C,i)BL)f+9+AEDpF(Tdjp-%EX&N#J@'H
- B5&EQ-ZMXT,(a3G@iYl-DTrd0S[c08G+lZ$82F22LeDP3E1VV(ZSr8k3DhGGCSek
- `+2RIalCec([LpA'&qMF9ai1Up,!m2l,r"rVr+rMAl[BB82IV@[hp*0SXDhH*A8'
- E)cpfX1+X!Xjk)@KTp),413%am9FEZ,$[eHdM4TV#TmSV!$&F4Lm@CGL5%(jLGm1
- (4$pb#,aZJ0YrChFlA6E*RCjjBSDN5&kE"T4`VYXA+0Ce428KJEE)I48jBE8Ef4P
- GamHTYNAR[l1YB9$D"e2pSk1hiHc&qIp3CK8Ue(r#bp2V9a2Uf,IIBKilfV2SH$6
- %'2+258N9qkTFXH-33cp3%2V23`XE(TH*C'0r4fZ*T04aIRpa(T!!Lp2(qI$4d(F
- @L2H`)BAP(E[fH+qChV[jS&Tpl4q0C-iA69KJYCHjMXD3!!ScLMPSS[N-)!f4h#*
- [+Y'(dpUJ&2B`(IkCq(YB%Pi6m+l!qc*B2E"QiTf0p`5m+[#k$+pX[#D`#[KI$Im
- kf+rQpJUm,i0A-lc@iEd4lcDm(m*l*pl2i,dAdCS4E4hH'r&Z`rXK[(ILr3cHHj&
- &-l*BKrG'[0[`IJM[RAJrJrGHj0Q-20IK[4([0V`I`RXRhXq`1q'r&[lh`'mYr1k
- "Rm&QIPpM$k*Q)VS(d6)4l860Xa&R!Z*8`2mbq%X2A2Cp$p6KIcAq"K2I$cbaYR(
- &GPE$0'2B8*Ba*L19T@T6)e2MJaXD'i10L*&q6U'ea#b@1MeHCjeBA10d1@ZFhR*
- R,Aa[B,S"GC91d9APFBVP[RT2KHMeeBP6B@aePY8j+p,1rj[l8Vr6#qm`[&ZGBP8
- Ype[NpG@l+d9AMG-T9MZVI6@cdT)Sr$,N[G$RV5ZVmYD+C9kabMZMc&09)8jhcVV
- 19e14KU'5aD,1mER%-Y'0[&V,2'*ZS9edeY6iDRL1iF[,bNZYaG`,b5kYVa-46H9
- i"J@Sme8M[E#hV*VbEChKV"&VR(Ae0DJ5T5bT&-RPZUU-kJ@hCGFK6(f0VaUfchf
- G3X&jCe*$mUTkNGU(+jbZXRT2A9I`i943U[CbCidA*C8D(2I+1T0S3p8-TjGA5ZF
- ,@,f-*D81(@ULEN$mTE@9SYeC@eAKp0D*qDA&5Ylj+2cmLPNpST1(MmJ3mbJpj"$
- ferM3mmZU['l48e9,$GP8AHDYk"(GBqM3$('XceFaGCDc4h6k8*0*,+e%9CIjbmT
- 4AY5TZDl+Ke)ecK)p6KID[l(-1eh-&N9a6)rSq)`4*V%)di!53j-h1mXTfT!!k(1
- '$Xd85f[3C*JhP'f,aeQ("(0jJTrcbf0KZ8md$aE0*GCaim3k09L6V`+"cMJ6k-,
- "iY3UEeR0V$14-NBJdK5jRMb)V[4@1'YUke$6)G(4P-BPdm[3%+P$KjR%#HL5X-I
- RGQ-`A)%kTBj!!DI4J+2)p6l%(K)pD)3T3mbYUN%a-@(BXkA'@8Z0KQjD0JZcE+A
- FZ81LM814`*6+LUSDdFI6M"mkiK)aXAmLM3CUkiAe04Libd9%N!"m+'RNej[dQ"'
- Qi@*a@3hD(l1"2HHAPc[p'-2jh(S&p9!68PQ%D"P8ejPe0I9LrQ"j3#q$F5&'(MV
- L*(+q'-d4,KP-IS[+UT9H1@HSDDKSpRKmj4M['%4eSVNFNahPS3aERGI@SdTe+%N
- VDNG6J'I+N!"SG-PBd9VQT5Jdr#9PG199099ecX&LHD@cI$S2+l1GKKMe%AAFc$`
- lcl6DA&)56K'ajf0@V+!k8+`4`iCPS2c,DQNR----LBkK(+Elh*KKp@9)@YFH3l"
- F(JGFk%AHXURFqC5[RHZUDKA[["%MKU+cPdfA#bG0R%r6F3%LB!NJerTkMkG(G-E
- 3M1&$1RFRCmBZUrIlI6AS4$e)PihX%Cf(Q5MP$KFAf8Y&dCjA#Y[NmH1,i%(9$jH
- 8&X&MbT@jSMK*IPA6DrUi%S5E-EkNY%Id5-UL-QpmX5KH-@%Fh#iZbN9QXkiUaQY
- QUAd#-TTLTA#A&#('j',bZpKXYI5)(NkKb85caqS"DVkQHJapE'je2LmfS#[U+Z@
- %,Z`4RBNkUf((aF5!S6@Y6TaDlmB%@bV@16d`6I+@ejDPe9I9PkFj+qTl4)rqEr-
- jr#-Ub)@&C[Y9BPkKf6)q,rI(2D,(r'r4QmV+&8IGa3L2QAXfVrb-A0(R4GpDrBJ
- j-E"2B-XmM3d6FS3,G"LVbb2+DXZVUR46R4k2EUVE@4FT*qQCkUq[df)9FTGA4*4
- lI,A1b!SRE5la&8id34b'H"bLHG`Hhe4GC9PYTDl5kI&hjqXFMl0&@NpjKFj$F4S
- pY4T2VBi+Q&!YCq'TKU1R'KR%9dqR'%d8!2Aa9#2[S0H(2FV-a%1$eS[4e15[de*
- C@UkVd'%X,SqiYYk(A0#a+k*VX!3[Ge)4[0Jb-(AG0G8406a0l#YeHRT3Cb6@HP#
- YHNq92l+fVUbZ[KC2fKFmG@K#6chQ@J)'f`)8(,3Y2f($%R+LS[`eU!D@TBAB8bP
- $p"BQI&-CEAKT&d4&1@[,bp$"0#*Sc8H)aRl8@c5&m&[QGjCAZ6"qC-2)iKh(RSR
- 8p')fZj6U8%MY+-%6TcUGI['k5U`DDX+D5f5G1!3j0lJpcJ6Uh-3S2!!Gm%D#lPI
- 6JVTUY',6+IG1'-Tj&(8mDJe-B5#(-c!-9%%6dCT0m-6H8&rRaq6#2Vh8bfIPSTP
- 9GDRP&8UJF&4jCCRAlF3D3pdCaNVc@9U3!-d9--a(b`G*R5I2#`kJ6#SA,Y%B&)N
- A*1!$pE5pB%43JJ510#Ia8D@5iciTT1+c&pDS"Pl@I&TB9E%8)-#V2K+S9e-ebc@
- #1N`&JmXL$#HZ`rNd"R9[F+CBjCDASIJd`Y"JLfEkd@V8*-K+"JRAM`E9XT%d2k2
- 4HH*3L@S(AX5hb89)"SY)2Hp@eECB#drRidK#IcLPaRH-8`T'L"!ka1iB5V)*d-d
- 9'#hQ,RF'CRLXNb@r[NE1S8QIq&8(56Jcc'RB"Ai6CBbR0M4!Q[qM+8I6BS%Kc)Y
- [SE)FKF2V%Up2DZq`aiKCE'V%CCI3TR"L$*LKBUPIiD`pRhBB&CFXdD`+qA)MhNe
- PdcZ+4Xe(bi,+#09DA19eCQ%0HVr`(j6K9&jNDkF39-*Cr$*TX6)Mm#,X9'VmUC9
- ,$BMkcTQ+L[80L&-j"U)'K+"HY!DT!Lh()#q6%h#'Qj2R4qQPKfUQLNC,1p9V(&C
- !l5KcVhqe3%,4lMU$GXDrhf"1iiZPRIImQUP9D#GN4H&8H8E3iRPd'mJ*lk)m%hJ
- B-lbUkL(J5CUmTkV`E+,Sb6A98E!hqC4Xa[)P9QI*EVqF)ZQmC%HlTP4GJUeHa-*
- ,Si9KQSA9-Z$&ZdCG@9eC"j!!HACSEGD4H4qJMLZNMTp(T3!HhH#6!9$ThdajaCC
- +,2CG&m)!a5p(AVhIR9SQMRFUVDI[$6GbcUDphDPiXr-k+LdK[ZB1P+RXpIBNdKi
- d)(%'-*Red-jbeJUc0$j[T))pS!L,)J$P!G$iA,dIlLf4#,'XUUClQFY9a90EiG4
- -+p-4A)FFh#GBlaLN@+4!cPGkThYpehR2&c0-@BS,lEc8*B5PS@X`8Fi3#I1F,Up
- Z5c(f%D8"`qQU-KPdaAlEi[0@)'JH)T@)q@M14MQE8V'm$!d&@&UJ6$S2N!!p-4H
- KcZ9f&8KJ3qT@QNVN+'eB*Sl)!!KP"H,HYk)",CYI85(E2L'Q8+!C51"5!Jl2b%$
- `XAr2mX*LLShk,406j11&-`BKBR&Ra#Pd8B%DmSC%R5ZP)E4f!Q+Ge4Q,VbpScF9
- b41JV'N9(Y)D9QHVT#$qZ-la9G&fRA'UrLBKcGQFFAQ[3M9M618`"BEi+mH8FPTC
- 24h9eRZ@)$j6ILUp21a6Qh)+TL)fM!1JP&BSa$jfr5J%MB1`PCdSe%)RkTq4-T&B
- XYI2rPP9N"T!!DIj8@J&LN6,&%822YNS0pKZ*NbeQQ5i4#rjP0T8#@NaLhEkHIQG
- LqK@,K6lPQ)+aK[RP0E"MLjN29%%''S23Cb$@@H)iEbf'f"AP9E3Yb)%,Kjf9GjR
- SVLRc9eD9ebBJdVM[)mdZSCPlcUQX&FMDk#ZV'-NRFNdCjNJVJ1$Q#PT2q0T((pc
- -#0rbU,`3QNC!MTL"X@,"i0&$(!E4FD#!5aAMb,IY-!QTM`q024U6[-ddmM@&'QT
- TIBe5-+bSI(4#kjE#NP"$&!#9jDZ5hU"![KEkDQVUk9`L3b4d@9*Re)2hE&`[d3B
- e(-lfAFa-&cm%5)@A1JbB"[4Ir22&BA$5pH)KU"U'5Y3UYj!!lNT8r5pBGmf3!!a
- Fd&hLFTe6j"e-2GLLA$6J6'L4NjB*mU-M&&jmFlkkH"K43JXM04QZ9-*PI'GXVD[
- h$ac[mdf[pq-'DUCm)S6'dk-IjDAeDCN4L4(ZVa#J#mF0a)%3fXabQHrLX"aYZRU
- 6(%C",b`TkZ`V&(-ddr&LRX`[CV"XbHBEJ9m3j[GC$!q6--jE@3@``$2FP$&F0cc
- $0#,LL[UUmZN4&LaSRih-jH"6SU@XI$UI5SRj2R6YXV)CcPL,XfBk[$mR$NmE*PV
- YI#N0dSR+9GKfQM&DkTaa02jDD'!Za,K[a9N+*YBLErH#-Sp,V+J(G,,5B+i()J$
- `N!#f`B3mEhR0,(pGY,aD6Lf[p+%V0l-HTD9!$A$+SfrJC+HHlrIcV'6R-mF)eTB
- ,HH(Rep8j#FZ"2cNcf-0jb,aEDKCR90%F0iG40+'Q+[RZLJD12D@3!&ke[,bd1[d
- HQY58P,Se33D09%UDFAbY-Cr[H`YprPPT%bG`b%m!TjBbJ#45M@K9NGkRI2Abh3F
- $3!6b+!a`)0jGChS$UI-jc(bFZA(kQ!1BqS`B,FFX80d"5ae2&i1,6J3[a-5k!L1
- 8QMYb!'ARPLm#cfQPb8Z0X4c$#b1)EP01Va0T9F!iZiVU+lP0('e@6[M#[R+H64d
- Z!lKcT6-j#GP4R(2"ZKTJ&+eTe5JXP4"IDeI'$1%U+6b18T-V0K35JfXjciNUF4@
- 2`UXM8QZ#Hi92R)A1`Xj%0h&A93(%4[*eG!9a4@e18VJle9Se[r2UNXqq#Q+90PG
- $IjPBN!"INTCB,!m8DALUimaCYARH'98e9+k&Q)-&Jmr%aAj!-f3jK8)VQ2dj2Xf
- 80[$lB'1(CNdAl8@APk30kYK!X3jKefM%d'd3cCJrLr*`J`JBMhZ`Y6E0rTppe0m
- G""p3+r"'$aHZUfa4bh*`6@lmK[A5$"dDDbiX`6KCkZ(,kQr9mej*RN4`T@ARp@C
- f+8khj[[jQZ!V,#UPJkX+Bak1M'DL0+hS@0b9,ZYj18*8ZbIi"i[1Z[+d[RP9lNU
- krf"N@CFZTB4'&+m8Q#LdE#`cf*h9L(b4FjDrV#*LBQQ'bB3AMLk6V%#N@hfH)GE
- ULXJLM*bPAPVc#2R#9lpqbRVbE5Mc5VR#DU3ei0D0F!-d*MI#d*+k-P`J8YBU8%#
- pAd6Qbmk9Ll!!bj)!XQLJU59@h0TNmZ93UX-$I9Up9iCq,RCkkfX0&K6aXk+e[UE
- @9b0[ASN6k"L5DKZBk+bKpDK4Y*69$"b()aINee"$aiGmAdLR1S`GBV'NijYPBYj
- -2qB'qUPeUV2'Kh8'qp`L`Z49'B&lj,("1YT'2E4rHQUVVRG'BcGEk[&3FSRdi(9
- 2(9&jd*T&p"K,Mf*kR%@2FI3iQalMkA%128VSF@jh"9+PRSi(HVl-'A&G989GTEl
- 11CdhEX+-1ZlJUA&20G&M,$f+kA'@cS@HMAG49E`i+d"l*e!Hbhhq#,`EI25k`Kp
- 4$M5c4DrZQMiRM3T-LMJJC&ld`a9P(Kf"adNGB%8mdPp8(5fI%&19!f@GkbHQ&Df
- IAPTCVr4()Nhd+lTP%M[AJ$BQF*IhJ+4#l(3cC4!q3,CC-McIf)-Q(68MpGEjhA'
- JU'##mk1XI**L2ilRPK(+$MN6$BDpP*+B3P288`MdfkIN9USTQKi**'qKdp10N!!
- &R&-QmpQ(4BNDHjC[C!pP@4#2&)`VfFf`!G,q1YpMQ1VN5baIILI,aNC!%TKK9rT
- l+)Q'#e'[8N0*"p`8i)Q+4fQdNLA-DI,`P@i!EVTS*Tf%P4Ua+kfSmJ'SY2S#RXV
- )FpDPdHSL)V[TSk+l'hVdl'AX(G-RYQrF1I(RpMZ[rrN$%X3,%JFQACKm8FV&UB-
- '$dP,0f8-(6Cm41BP@CH1(*8pHNb1C,CBFr2baaD-Xedfr[,#SZ)Vl#@P%bCH1HQ
- UUhmdqFIA6('865h(2AG$CG@dkCjUVmpr,@k*VjaahFaCerpNpNrR0$61R6Gr`F*
- &0c3YAV*dfBh,EeUaFYA0YpakfqfVIhE(cpImiXkleMkclTjlRlM[hVqdr2V&"ap
- kq*'l(hhXm5HH[1rY6CpZfEVP0dqhrZ(ppejZR2[`[!rQlpehF2q("pS@I(cSScm
- Zh2E)d51I,(Tppre00baHZQ6CdcIHY(c&bTYAhA,ViGY@hrkcRprabQprXHE1ZhD
- e"hriSIj2rHl&hfprlFfh!h[HIHHppcrBYrr$J`F1II6a*dH1([[da1GIR"3hV,[
- RIR(M@f),h59mDjIiU#MqmNQbKGG[&[FHrqhGh2B([aE&eZIqp1I2e*1RVVq+cGc
- `TrJqqG)cIpMkaff[[2cU6R(('hpjr9GUP,$i`a!ci,UlPLpHdV6XaK8VElVePTX
- EjmjrqZ'IhE(kcPrX@VMSYrFmmZIREeKeqjVE&[ak5f[cXjYqpFb,@lpX$ll`fI[
- [rD(P0lrFm05k*pjjpm6RalCpXI6PaarkhA1Eerrq,hppFqqq$cl&-$Lijr@GVac
- FIZMqMclqq4qII'[hN8q1"YBHIk$YdBf2hAI[DbI[I[$Y2qeipBfAI[LKrKY[DPc
- abjrGXAEKr!8[,,TKhT+QaAIIZ'cT[HYZ[IQ@GqqjrEDj"irrCXfRQiqqhE,TMaq
- erhl9,hlpm5GERpjlC-X$$ljmhrfr@[Rcj[82rZ'ZPajrq*&Y`DGHI1rj[ajqkq5
- AEhjal-l9IfPrCA[E[[F2R(MMYkdEGccjq-lArVaVGf$2kqpmX2r$2chha+&RRrR
- GCaXHIHb()@E!C,-eVl"S3KRr,A6LG`9qc6lkABRIQElbm5@qiK+l0G'410"FP$8
- `Hma9p48PaIk5-Pp4Q5qRDXK%eqL+l$&TSYPF913E-L3adH&)pmdD(Cje(ri'dkM
- rV)ZqVIqTApArp)Y3rdqPql,(Z&b$dLj+[0#FCml,'iII*89LdB3*%kUZQ62NQM6
- Ii-6"er`3aLiB[ZXPl),IHq+9Har%,[KN@r2aZappGFF$f!8lrl4Pkkmf2ACf&ha
- ChJArQZq#@llD"Ip'hJ9Ii,[JRVGfrI$&,[JhbLli8)[i4$2I"CrJZq#rhU,ZJJm
- UZq!@l),Kqai5(hp-r09RI`k+iVeYKhHhIrR0,JLA2m4h'pm&MB5)92U"1U%mdJa
- #P)9epMaVDFKTkJpN3!CI!f6`HrIGhpbbrJ'#$,$K!$*il+P0[pVmDd!'rkEeQ@H
- IHrjh,lbipIF[rH&PG-,Zl6YHhINRV%EIIH-[ErjepeZ"YrHmmqjlHprIKbeTrm&
- $(ahq'([MQmFq1rljL5p1B[FF"+EqJd,-J0pErp#'ajrDr*[RI[Ill6YIIf2M#pY
- 3Xi2(2N1*8+%hRrq"Q&9K$Dd+ecl421q&AI-IIAV",jqmDH&[YLaD[rN'[LUXZf[
- aLJGq[B4@KG[ZHfMTiimYSeAK#mZ993%ca9i9[N5V`MfhhIi)KX`f6"QX#MND[`0
- 8T[&$dbkC1[aFrJTIIQ9'fY#d$$(&9SpViE'AAMVLBN6+l)`dY*-%KMd3i@5@`P+
- %8Q%6"J[qp210$Cq#M@3(Q%%Bcd#NV(mDHBATC4i4#4VDZVUCG8`3+)GNr!F*qEQ
- QSTSMJPJl`)iQ([50kp-l+MYACXUDm%qK'ED'IcL&%cNYFeC31pUr90cNd"P+!E$
- R&N,HLBhQrki20GkJ)9h'[alPGqV&!jk8,DGme2miqNmhAc@,Ce&JUm1BS9RM[4b
- RP3Ya%QIqc&JIr#3cX[Mj4FclFIiTMd%bIQ8drDQ,,V3@iLB5PMAB*UpM@MDI-r[
- &XiAjpVammJ6GAX`6dA+92*K392T4GB#F$-(6l!KJHMfdU(ci'c`JaLE'#D6Irlh
- be0Q3!&r[Y,lZHRcBZAHFL["AcjkD!erj@DIh(`rG5h3$lmf"UGZS1hjRfe8hT@G
- E3AT9lQjC+jlMCX)!84+,dq)('e[Zm62amT8[1$6'eNIr@(h#I*!!T9JrRFQir5q
- U6e$N#R1TQ8Hq904MfASe[BGBA&#*c@)lHl2i*ZZ*i*T"ilCGRAKji@C0EQ,eYU[
- a,QZj"kmR,81f66&P0ppeIhkkhT4ppqTlmKppbaephQ`QE*[L&qjHEFTZ1AarrU#
- #E40Kq6Qhe-"bQ&YQN!$hj"1D"IH0*Hr**l4Ch(,BI)*PhcHfm&IB1cE6+rkaJZY
- CS@e)-1M@@0`@0rRiQbEI*([-ZNNFXUh1V41P`K@&Ql8,8QG'k5L,F2@f3Tl239K
- QbcR#8R2If*DMe$Z9lrFhA9@8l'2pd3eJfFlmHF+2Q)#['pqi*"m6rr6RZ2-+jTZ
- d'SNeZRYUV+`KpLmP9T[9FpbaPhY0F[INliPfUD$e6kf10Qi0Zk-4Dj6GfZmmKq`
- IFK[KNAap-2Ch5[cl69U$a(46+pSNdbJ@@IJ&CPXYLfEpf@"QQE3NpQ3`b,rILrf
- ,J`@[9caJCIX5@,ILHl"d#AR8i!@[@DSAf@frXTaXeU[PprCF3bl69V0J[(MCT+,
- aEaQb#Z[6)kiU5[3a`i#I*9b&fRm+YIm8dkDH8mFFif2103UmmS%GJP%SD#aShGR
- S5"N`Pb+ajb5h`A61H`9l8(Yi"YASfHHmYf6220((M')kLpfq)B@9,,3Yp'i3add
- U5Ne!c[kNFHNpdU26pB@EJihT3lCGVGL@ibf@*88IXD5N+@UXLYX9[aU+CPSVdU0
- $YK)eiTqGB#NZ6@&p`IYX3HVeV$reIK8UA+qMhLmXB0(MhlU!P4B9mK9imSRJ#I(
- '`RTdL!YC2&9D92"q)$$K%4D2rNr(A+Pe4iY56LSkG&2T6FA(Skp4*bhjd+bYMd1
- 84TI1M`kc)Y@qBF[UrKM0T#di@0abX6K&,"EeDbH)8VSqX@$l2SDDG4mATb4HrZS
- qTM1P-%fLhQ%B0V[`FdLBfFSdaBZ[f"SmBX0dEG$4(%@1GCf9Q2j@Yfkf,'')@p-
- 5j08c8$e[D4(kC5R6'kC4([9q`c4-&@pejGQDH5EGj,$6KQ$@iNl-rZSceGKk'&S
- $c'UJMRRLP,AMZUUbZ,-Uf925lLUXTkkYM4eNhqE2b3i'de1CATb'A@,6j++NkQe
- q-GVe,[9TjIXQN!#d9PUHIbCC+,#qd,V6@Q#a@&UIDCXhrLeQ82aG&NZ"aG8rNeQ
- N!XNGfIM-F%3XdY)lV*(MM11qPCCNSDEAcRRE'cI-GqT@c,GVV[Jp+UCL9$9k$,Q
- 0YVNHBqlF`K2"qfacUh9ih`2VpZ$Uh-CrcjEXlfAVAM%IZ4k@rG(4P6YfECMNd44
- Zhc$*KeGar)C*,PeE@f&ED3(&QE'pX$jaLTK`pi#dTX,YX&bqpS+daQNDbqf+pE5
- 3!(@8Q-!p#K,0KG[pm4BhZV!chFG'XKLaD#h$K"e[`U6#ZaM6Em+BaX+fa#Na#DB
- %Qq$@hCr[d0b66cR#2i!Clr-cBhb"C$cAPXjdlTjiHGfkHl-GaVAC$S0X[6rES9Q
- A6EarSl#cK+FJUd"K@q(%i$Da+-1,l6GpV6"DBY'&eiK65QmUE,[L'BHQq"RCre6
- b$b0+L-8RHTRKJLYBNU@5$EBdXc5Ei0+Ye6JdDl@)RN,H@FdXTI#D4-V3MikB(Gc
- !-`Lb''33B('@&0B2d62@'LMLj(e-4&5IhlJfV5[U$Kie`',@aL*1L')80l-iLP&
- p8dF%2mr,aq,@pN@F)2R2NrfPXJ&8GLKj8JDS6FBh%EM#'@YM[XmJ[5-$VP-N3T!
- !aI-iq6b2JV@j9$&GUD`TaJ4aLNZhVUp$FepIG,,PN3U2e!i2VlrE1SG$jqpfRk-
- V$MEkqeQAKamHrLi2(camA4k*m%MXmJM!)p$P-33H3lM(8UDcA#(1M$k`pN*ESkm
- R0JE-PH,9j&Hm3Ta5A&6BKVfVL$E+FZ`0CU5FT1*5fp"dCRcXDQqr%R0eR'McDpT
- 5Q&iM"GZ,TCfYDp0+c)jpf%N0FFTNC'&'cK@,5`X3fI2B*'pr4%jhah4'hYf+Z2X
- `BpbB5)MlYDP8Lk`QUNY@)hVV%ZT!`$ZB5c4hc"PB`25BJ38X'M1`'M1`'M13!+h
- h&f-'9U-h8fR+Q40`9hUh)FLKCrH%Q`Um`CIp,!%E9rIN-3R),'"k1,J(EjriF2$
- Nk,%X0LdYZ$8FrDD#XAQP%i['BdG$(XJL'0`p'P&lpX$Q#jlXc+MVq1JT,%D*lDI
- B-m1aEdc[KVKT`6@)Qa,Fb$1jdj)@A(XqCI-e2aXL"GIaE'j8XRQ0emH(qYb$ZU5
- M,YFTZB8+faB@&)%0p,pPG[Fr-VZ*CeD6,qG@qEk@$8jMXFJ`(4P1irQ&j2`L1Fd
- GNq$+Y(K2ClSBAQ&%$!6AmhkjRc+)4*Jc*J%e'$Rq%'X0cP'UN!"#9CKLcc26140
- 9!GQ(H(d$2(rI9rPh(MM6Ha9jir18q1KrC*!!'Yb$qVc1qb%b#6SVH$q%d!rlD5,
- 3*&!6B5pUNpBa%B+&EBXa%#l0(9HBAm4cfe[`ILpp2#C5,MD9[$6@-cZ0a4KQ4M,
- KkZVKK+jp,Ap)3A$I96IPC$Ihm`Z8EdHmQ"EFYq%ZGqb%Qh)Ldb25$3QkjRkSAbU
- 3!+cGSfF$*Y`IpN5G$Q"DTD16![!U)'Y(kTJ%feLhhM!fq!Si'6C2Z-R2dKNL(F6
- h%,SUJ'LVH$6b1)*[1lkGb1-32'[PH*3KBZA#Bq5%Qd6$fJRTc-pb@)+ZjIR48kJ
- '@amCNq$AE(JiH0`9Tm4%4S9TP'2RiD`%Kc(XKDV-b%*9kM9MG"N[4MY'Hi-(@1c
- i3mE$`ChKHET*RLj65r,(MFmE1hi#'T5kD&r"qpfSJhcSS!!k++4d8(kSJrEa$MT
- ClU$fep""qp""!EP,fXj$jcbYpJaeYA40jjl1VQNr1LB"(I0AVP$I8Hd+D3UP86q
- KNkilddR[2)X-PRc659h0m+cZl+4hGX2$RfjSHI4I1qHGM502GmlEX52PcSQRcN(
- 2l!Qq%CjPQj9Cf0FeUc&ldT240HLF`-Jd&SG*R@,463"L9!rq*p4T0A$HekN(d#q
- V#3"[d-`8E$ShqReL4(TN!MUYd*!!hYh2QJGLrU5MLrBC&S'cDjREBPK%A$-0)`f
- ,L-LQBDKK%BJ*`%`A@&4H9q0a*aS@P99lkphp$)[!IVEF(80aQZ[FdCKIcr"-Y["
- *ZpQ3!0I)A-QMCdC2`Y4Z$UlaDq#ehASSf#L1mq[A1FB!km+XH$4iQd-h1LpiQcm
- 5r[HC$`92S1Zh+('++!jkpaQh%Ae5+QE60F%1c1Rk0*i6CIS5[Jr,mHlYKUa'fKi
- 1[Z'1cRSiH&Xb,,A4FrlNL+3ZZrT2Y29-2a4r1&J4hR[@jimVc-d['TqECqIGCE#
- VLY+c38!p1JHljGDeY)'@paB6h)Q%[4A&$k8Y01daD@U-Rj@BhC('q1fYMQ0'Sed
- LR!2l0$#@UTQDjG-66GNi*CL@@)!hX2BrhZSf%M*8P*!!(V9f43j`C#"2f([Kl8S
- XF%4Uqh6A#!c@d"kT4,*-)YbSH![Yiqk(Kmf'&J@h)39U%a,G&KXfk@B42VLYi%b
- ,KJ'l*eY5iV3Nf0a-iqK[UH)4hBJ9FZ[KjB'A&qmiTS'[aj!!a64#ZMIDQ#@Nfk8
- q%Z['F`RUXjLZHk)lXJrPj$2-c!PUPNq9VBR',-d!S+qI(TV0G"[%+hmI2'Nh$c1
- cD&Z@CZAdq*JXi3Z8-0Q!+krkD06Yj6k9V"[V-@bQaXKkfQCUMeAR)[-JSTF"&d0
- dB#bB$dBmcB2kT)a+0Tc&VH[QkRG"*EZDQ5kBR@FIGaRVlaIJl4e@bH*B6r6X+R%
- F8*T,aQcC[d$"#B#NbM8$@EBma1mCJL)fLUmpa*'GGBjNA#H-0fA[[b)4ASqXGNI
- D9VYM(-HX*jMiDKX`%SUbaL,*k)ld-+,91!i4d4$'3LeaEq*G9cZVGJEHkdKR!0k
- EAIjkZXkpjeS`FZ+pGrV8#VaGrFVU202a,UqZ*RpA"HMZkEh1!`1pp5e)Lq#BPiJ
- 1Ep%CUPJp*NZ+S8ScJqPG1V[NL$4Q'4kIh)KVJ&Sr-f8*9m-b'fJ)GbaX9HKKMj!
- !lXj5HRDF@(3%acP[A'3k*kh!)#A%Zq--8NkmfiKALEXR2%VF3"4VHb*V[ar6S%A
- Vd-#1X5*phYaI[J[*jThd"pVlmqRYBNmdZ5)4dA"%NTf1(VUhbE2!L%XXL)PhXrB
- GMc(AXC@r&rA`IB62-QmhAB3q#TXP6iHdVZRJSqN35Q(G%'fY2)QDiULbJ8FKHm2
- P0Z!99kdVNH6kG$Xkkp*f%qT5)ZLID(*(dhCSa$AI*#BJ5QNG%+@*QR6p3ar8%9C
- mZ)lKG3"6eSFSVKDbH-6'`K1X*lF8-MdZD!l)'"MKZqJMVfDj+h,YK$3JCcXfDI[
- 4'h%mk4*k-dH8%JZ-jlS(a251D68+VZ-hEa@M5L3$HXi)qRK['%%M%+`j3,!SRi*
- 'Gi`SSDiKKmkiM`QBk4d@Bq&fE"M)(6MfblJam"A@Kqahb2E#lVK`m5@@i!BLk1S
- *eVTeb8fQG'C)"JCIe4YSBJpC`Z2Xm![e,QJNkfH+c-!TjM5P0D@IJfa5#RciIJk
- AK''k["Rc,MD19153!)S*QLC[(Sbh)DZ`hMBAHmah5qDk6SM5GYVAJDf(6+K"+1m
- M&MYT#Hie#PPmHRHHch@86rE9QFaQT3fU5@FCCQ)Q,A"!9!ja`lKQ#&K5JA%[B3D
- MXD#4iX8[&iDb#h%R'F,V'CE(*V1aE",qdpL2"$dVCfP3He(+R0"q8FmNjQECV)U
- P3S9'1I1a4!b46&E,&Q&#TL'(&)Xl2CUb1UAIj#*XR#r*eT0HQN6@AE)e,BeERl#
- PXMKA[L'99E*cA$'6e[2,"TpB'6aT@Xq-MX(`E'6RZ,rb6$&0BdEbbS*A9PA`C')
- 6jQBM64)lqhPf4+QF#Cmm6*5D`K@C$$G#Ta8AiEV%j4KMX1,D+E8%-FVG19Se4R@
- 43dFql1h"K(2lJiiBIRPKCBE*0rdY(HqT6&244m%(d9FYYQNi$I@DXKZ#$TdTPF@
- 1!0*q!ISHfD6!0m@MThT30VeeU5l+C,1C`FS'Z52a'Z0+LA[Z[dE&T9AZIi[N3QC
- &lKe!'Maa*jRTHZE)015a*%pNh(2f2)I'R[rImm$-M"-aEBEZd*Y`B@Li0T%eq8'
- D*ip*rk0f9ANZ[b1ej(r,QqZhfjE['8ReUmPh$1Aeme$prNIY(NFr3!X5FPX%l'i
- +b`2LY1Hr9h!3KSkPL[[qRiTr02HUG+jifPEqG+X,PE9RS-(ZXr6K%pYJGjL`dCI
- IMcdQ$Gm3cF9aZELN5@9AijA1VXR"&D!aY5mK%qRb&+GpT(j!jb322m*X&rKB)G0
- Pq*LGk4d@4*U1HCq*R+V`pH4N'idY(hE&r,+MrcpbD"'3!1FXl$XVD6D2SYQm"l0
- jdVHcqDprb+$,9c&e`jV)D$-,[%Xp8[+Q&AGNJAGArTkrAcCQ0,'#aLc+X'KbNFY
- r[I#r9@3PVmJF9kBY&jB+p&Eq610rV`d`Y`UACUBHX9-4f`rmS3)lY-FIKdl(68Y
- ,p*MrE8UY8UG8[*[2jGVKjMrM[QM88eXV02pEYb!(6*U4TV(TqK`YljIpe#rR("2
- eK,I@2rK[-b[H&@IqmpF6ke"SBVe1rCKK,&KNb'F9k*KTV-Te6Bk1cc![j9TFNma
- #m`Vl+1FGh6b[4dEhI,Z6NZIDVVPd[D1Q-lZc+pAXU!i")r2cr(L(Y@018(EKL"q
- bbe'bl[8,RSV2dbq-kGGH@*q8cU*MdPN8S3Qe+8!Ea`$E5Ah-k)aq$-MM!Qc!-qS
- R0Pdjcf&ic%Mlm)akHe2*2,rfLFD+(DGmUZDj$[XCRkHPQ+G(-%q,Xp0CTJACV@4
- bC5jYcF8N!ilKc8(hTZ`(iMR0!bbZCMd`$+RiCE`[f8TH0"Xc'6EfcbMqRh&(NJ8
- i&N9B9e!X6mbF!V%lCU-AXA%i'EjXjAkNl--H&&HGBSUBJ&YC)2CPE!K&aBfeUh0
- Z0%3QF'b8Thr3PXrhIU#kcKBJmm%e'AL10paIqHLR@LENUrCFf6lHPZmM,%aY9#%
- `%1"ZY`,a+hQpEm6GAk*VJ!diD9%Hc6*-UN"A4A"*VQ0JhJh%`,6Uq#U$M+df5Fl
- !H21Vf0SEXCqJ5YE(cY3SNqqkq1INb9-l)m'+3LeP'TUrH#ILbp(2XK%#&F!&''p
- TAZ$4,NH"`3F8fq-Dr"rlSJHcPV&!B`22fGIrch,'m%FGrQ%(U*&FV(hG[q8k$C-
- E@(P$["jF"r8pmF)P*'I[iK8S3$@#A6Y!"Up)J(Hhai,pTM`@RHUjm$,FVY'da2A
- b2%a,c$CF2(I[5[)*iq26KH+d9HQiXF8'LYihp-QShJSJ0+KLPNFrBMD,C)Q1H,,
- @ak!H$E`U&lJLiHPLLEJ5(XB5I@6&'aPNX@5M6XADF)mq&4LD"km8i'`T`0Am`09
- #m2(DI5`C8cAE)FqYE23RSA[mR3Jd%2CLbU*d%U*N`(SH[U#'0mC`ViH`YerJ$pS
- EEI'Z%lJiR8De3BdcJ@a3IE$"Vf*c#"%SC#RM2Q)TZeSGFFEBJXC)+GMfc)YYH@p
- )*FX+ARcP*)Xfa!)2#H"&QfmU0YmAqFZGQfI)#jkXRVbC1Q'fA#9-dU`9H585CNM
- 1re-aUPBJ(H`4CmJE4BddNZE+RBL6Dc!aCc($aPV%dSUC5c0E)+qd`mA-8D02aHh
- %'DjNUM2UKVVApm2-Z+A%DKM%6*J(Kr%Z#!CGh)Fl0bM(E)M%ePTJYr,)IVbQBRB
- X`ZbB'YFUGmUQ[!Q5biKc(j8YEEQcV(BF!)RrGXQ(+`"9J8UH"mf$"PFf+SRqU"q
- 1Z9@Nj1qPr'X6jDVmUNESfb8d8HVl+E9+86,bBjG4G6[Eb[TK3dQaQ)$djV%8l#1
- Bj*MLkE$QV,#ZQ-ELX1I3Y%Vhk#aiAI+4N!!brUhqI1SaHSQTCq6faiP9)**0FZ[
- 0K%dmlBMNlfh*j,88AHIPQ!-LB1+'##2!&k$mL[M8'(M46Zh&6ZfeVI*SFX&2J*P
- ,A8EBK!qeU"!M%[9m!NiVXD+63VdIec08c26cl%TUG!`hjDEVd`NICjqa)Y#N!)[
- &#eI3fBm!-!I@cI%cj2Kd`9DebUHc@Eh2md`cP%j*T4`a+G!9$IS5DqmYC#QbqZ0
- A0+%E4J)r(TP)Qef+&A'QI'aLR8Jl1QIN"TT`UAbf)4CeN!"l@K!6!$X'HHCfpGT
- )hQ[S0(c6+4l3c8Nq(AS6h@DJf`525UGZfi4Zfm#hj,e-3QAAXN+meM'laFFU-5@
- RS2U6#QC#`E`IPN[NrBcbSGfXfB",Ac8[J3-9!V'IiYDCY0KRidUN,-SkKrF36H#
- jf2hR&Ui!4m0PI,--d(8#YYJlANHQ4GBrE9ALdqhk&0F#A#!XK[G+e+%1h`AieZ*
- l'Elcm*f,Ek0M!*m+Mb4H4[F9ZaZjpAk65FrQ`VYQL6%QK(Jp%YVIIGMIGaTL@+S
- VTI34YJ*9fC46LDZT*GM+PRL-b(Y*,Qd25h"2i+%XDV13!1X5a`#$$c+qPRKL+D[
- @k1FqBY0f5*(QB&Z1Q8fc,m(d6HRD`m1ZEFLb`+h2SIZVHSIG[S4RRG+9GEf5Alf
- 5Ahe(I[@Kr"$P@(jfIHq9km[9pDBeBYrd'2X90'+,D5EXFP3r[1l!G`E&bCR(qcI
- S)Vc8JfmPHCdje5B9&hPBHl3r#1m@c)PdIUG"1-Xqc)Q#&1a2DF"DF1p4BY5U1f6
- F)Rk[NF`Ze(TBRR!('b[FaLD&EM9@-UH`L,Q%HF`Yc-'YaQ,QeD5LYrBb[kD#e@S
- @i&EMC84jN@-hHHkidP[%8Nb`01cPDHFd%b01,G11*+ra+F&fS!DTQ%[$4e"ACD&
- fUI)P4&kKA,difZN0V8(**N"aLp&Ti5L(IK*XiC6JbD4'MQcPZ5)aHGe*6GJ53U'
- -(`FfKGdGNpZ&bHhi35P[E4cm$2J&1ra`Va@qV'drLlZ`J-8ND19kC"fJLa2h[2q
- e$VLB3MjZl"a")!4j,YaHL9hY$hQf9HjNJjE[2((BH@M#kq`a$8cVpAq[K1Xial2
- ch+Rqk1h)[l!bH!bEmH)JETai%U@N23)llSL!-q!L#!KiQKbTS$PiM-Iam$LqT0X
- [T-RS'B'pb0$VBeLhVLiC*+"l4KhM0DY3qL2%1dEZEE,K*lFiH8$)SRkTk1IX5EF
- NPXTA12"`8i6XCZ#49SjPE'CRCaLlP@a`T8I46N-q4Sc5H5@dAc80S0f-VV0S$fZ
- +T$fXPZpVj'0CD*F$QTL#R0EcZ!@S4aCZ%aU!(DA)U&Sq0K$'aRcNLbXiReJ)&$%
- &&N)M8p4pLR+TY9!p#M%T)M-Z(a-ZVk1$S(i4q%mF0Z(6-28aPiY9hc@!GQNV631
- Z*2G"`*9k0Q+@,m%XEqBeNQSb$PR+iLq&C1#e"3Yf630kmY3Bj*bb9pNY2GMA*Qe
- UR+V(&C&rTZ5)5pGaT0T,1p8F`N3*ifkEc4`c#Uj-L&@hj['(P'h4lpA0$MUZXFA
- +'q*-UdQl@DSZT$VZYKDdEQUXL!8HN!#6hPfZpCP6B8dV,M*C`6f&'*-r3Eq1`Rl
- XlYb0raSaN!#4cllX$UXYclZS+hS1CB$01q@TVF9&lZMdlZ4C9$'Tb"5*HP3"GH!
- p1)2Zd&)cX62IJAMiTZ-l%Ym-I$2a$BFkS0TQpBdIUAANQ[,miU1Y8b00HHKEYer
- %VP[K'dbl,QpMDp$[3A5c[h!&*Nj3hRFE)Pr(G-)Y*IV%(AP(,ZUe$4fBjM0K%U4
- K5`BQ04$A6r9r0K6Ep4+LT[X+4q*blYH9Z1cI+q'D(DV%5&k*NDJ%TY9lP4MC83Q
- kC-RJPFMi)B"+'%G#PFMdCD%5QEM6a85NR#[pM(eINFa`4Bb(%6f-(XeMSX2bE8A
- brYH+%)jEbqZaAHhqKN*dIe@@&RP9+(P9b(R4K52b`U6kX2XaUb3[hfUV,GHlQ9r
- YJD8,D'mB8rQ9QBcM-+rKKK5)T+((UabJ#Uk2J$rMMJQ@DAch6H"E1f%bJQ)1Ne'
- C8K@9SC[99(@2+#98-)&`!ST5fUm'UjhJ##NQ)p1B@@jTNAXmX0jdMS'$a3A43h5
- Gf"m*YiS[F$`lV36a'"-hi`%9Ad*HY48FadR!P)r(9K&I)N(B(qT4Qrp0MLNa"A-
- I`dk$lIEp[$cN9D6$[*PZAe)beME@m`4ep,0!i&5ZK"NP!,&rM8I*SIVMKL02ZI'
- !Y3Dak-B$H%JQHLR$NF64PJ`2m5Za*b-Z'5(%*B-LNQq'%CZGpc6bmU3a-S5mc$f
- ,[24Q2%V088@Fe4'akJF#1Sml4'pFU@r3aM@Rb'[!4C8((H('[K9#Ki6G'RXZeD@
- @IENCNb),miGa9b1H-q@&a1lBJHp2[1bUaAlpKT96)re#kdSh1XTBPEE54V[J(VI
- qF@"X+B%+id#D9G#c12Vhp+l06qEf@PhbG+Dc2B"TkAhm3c$J(8bjl29A(hrC@IL
- Vhq1@HqMfQa-[Fr6MrRjah2EYMe+-iS')DHJZ'SI)@q'Ca6erM(dVh8*C[bb#K5"
- Xh,k5hU2"A'MSL1%Z(9G!RbJ#"K[#EA)Uak+bdaTK6ddmKkbH6I!,V@T-0b-kN!$
- Em1fic80Xh(!cqTQ,50P8YCI"@PDF4h9pHG)54iaShl4LDU4S3pf[%qf6QT)+E+Y
- FqadMZCm(INY#A[ZT5e2H6#i143q&SP6)8IjdKqY!-Zkpel#0#bSdbETd,Cr@ZFV
- @(0Li`+9EZG84YfHTBhIbr!*dJYj5F@fr3-AJT&SYlFQkUqHrd,Ka`95+1F1[hpK
- BSCQKPh-D1dR*LAb,NdV%Q#[!B&BAQE`H0eITSQhlFmP0BXN&r*)N(,0L[PJL0LE
- 0(rJ(hJ&9NjT#ZCCF934d)!-6)5afGfR'rMPT2#jbqa()#YGq)*TMF+H3!),,$)p
- rN!#-1DBch&TNUjXihCVpbDXFmA!R,r[9UbkGEEkV2bi5cR6T$I-E3'@cS#HXBh!
- YF6fGabmF-1`NEP5-Q%2NeB!lIST"I!,NAFYMJAN2#%*BQpY)Fb!$95[8BS,K`U0
- U2[JFiSKp$9bA([&+KfEPeNP&bH!P""2+5&3e1`dh%VKRcaF0VVLK0&eHSTS1b68
- C09)[ZZlBeHpL,-9'm[MBhVBEA)DBHAhbQ1"[KqFMaSL#4N,B'e2*8YRkAK-KcN0
- b"rY"MKCdapVc$IQp$PF3$p@`YXDX6$ec'9"0D"001B5pVf@N6T2AL`8Z0qNd8L0
- cap$E#-CS#ZCUc%%f6iS9b!2(0bP'68'Mk[Zhie42R,[lEAhFNIDP*6I-CZ34aU&
- 1cp@f4c$E[CKaBH-mZ9ki60XPkXHr0HN`lfK#F*mHM*Y8E'+cdGGcd5Z%T)p,XAh
- AfGJQN[!P(+G-lZ65E8$)+rK09SEDSpJBd0APYeNH"RFBZ$(3*3r#abIDfMjL`j1
- EN!"M%"N%1D[#6f!*i9[!XeQEP4h*+%2iaV9m5)`$1l$R0#5VZGAfYmp2fb*TeM,
- ,)mJ1fdhPP43GmE`Y(pVQ9`FFr8ZqLq#K#-d"B*Tjf*X,1+CCM%Zk,`rK1m$j(,Y
- %,FF$'H1T0fVN&66eL-YJA'BkbrSrCPi'%)!Q!fj2AI`50YYRN!!lJql3A)P!"m,
- `#Z%'*i@CA*R!'l(aiCiQ$l`',PGbk4,Fi-#c36FMfN%ARikhGiB4rTMb"EKai4Z
- #)[IaQ5cGKUQHNlD!hc`8*"EH[$8ebQ39GFVpbVDBL)+j"FrXD%`4l%X)QG#9$'h
- $GSPD6K6i,XUpD+15$cfp")`XZREeSQhP4dc(li0paJ`6EU!U@eHfTZPY0e52Y0h
- J6C(RB*CZ9H1QZFjqB5XUi9)UmH+'fpdpeCl1(Mmc1(X3ER2SHQXYch1pL)h-ZR[
- l*(9K6R`k5m@XiLNpMUEdLkHRp![pJ$"Ic5aAcQDKU6bKDbTlNQNU*lP6M$+QZ@C
- $[Uqrr8V$PCM3UA3"4r1e&82KZEQC`q*26HS9)lA+T!Dr+dpU[$'02HUN6KI)JbH
- ebS4mD9+,*qCbTKbc2T)Ld!jH('R22aH),2L&A*BVbAX5`iA5"CMJ%rTLCKH"i9-
- ZSE#hqS(Db,@XIi14'%paqhUYEDlVb-UY[%p`dQI%BbI-&-Ie5fIRcfBcQ'd"Y[F
- eZ(c14+r(cfEp)piZA!C1ND,)c-JkihX2,'S%6V$@q$[%mIQeLITR'ef(4GhqTM6
- Q6K,R6fVkahIQ$Dihr3QY#pkPD$l&Spf[D9d!K1('8["G`1)f,K6(J5N6&5`dS)Y
- pU&&!T$QkcQCdRA$Sl%hfaFD9VZ2Lq"6`N!"mXJMep5CJcm"pC`!4[#Zh%R0V640
- `GPb@e4mJ+c%1%Nm)i41)NJ+8'hF%08[X5ida'rUi$p&V%9h5iVk5'!BMZ40'BZF
- 2c(L0VG'Y!c2+B3XmU3V%Ai,m3XJ[&9Y4ZL14jaAXc+Xf9XNl3(R2R)m0pL9#liM
- (T#pERD@IXUc9@H,*UQZ1DTB5'SDBkECB9hrJ"%@$EFRMl8YYIF"K@q9)Y#mhaP&
- GFEf%@mL*60kp5Yj-NLqARPZj&E-59DEEClk*$I+Edeb1eEm!j,f3!28*Bqmcj6Y
- FQ[k&B(9#,FNZdE%ET@!h5Z1ld8MJMB9m9r2JRBd0+URP`h!Xa4-$$J3MUZ9$p'e
- 3492!G##E&#)K#N82i#YEh3'b-LCPJ1Q'q(j4qk+BY`Z'0m+6-Jja[KJrhpJ1Q')
- #d["'iSp9V)iqf`Th[19qXK3DdiNe"jFbEDP$TZ!b1fLj2ad-@q#%$T!!IFBea%j
- l`cKSm+MJh'F82a9XAiBr*h%AF@6"RSjmFRNqkHP'X*mCb##%Ei!b3AiKKXYZcLr
- $-B$RPhiQ#[M5GT%rX6qpFK+idql&ikaJr+XQcR0Q"80fIZ5C`I2dTa["S8DjZ9Q
- %NP[3%F0cmj2RM-dkbJHFSm+0HG-iUb9[l$M1h-Lj"*&,Q1F56$H#D8cAbXY`Bmc
- jT$MLH$j"eA['jSKMj+GU")Di6H1Xa&ifTDJ`IpaBiSJ6IVMfJ[F&cUTAGB[EJ"a
- 5`3Pq6eU#)aUf31&QrE+dK(3$1'T($4R,$12I-ME+AAEM1#YdHeE,1A3U19"mkP#
- `G1pX6lR,iKkc551D%JTDdaJif(iIGb`qZ6E'JV3%0h9[UQch`9je!qic8LR6&TE
- 5L'a$FVE#Z)5HQ&PUYTHU0BYMFZpc[VJJENY05m#0$6aDp-fTP(-q!hEM6SZ8kfD
- dbR9$(UT`b1-`mZ#k8FD)APEZppDKf`mAERjeTff++jEU59eGQ$h1#[P2TcDRTYa
- PZm@P6`-5Y8C`B)j)"9%&h(p,&4U)F5JeA!@lQUL"9(-GV`+A8rHi$raL4AkGq$V
- 0UD+9a&DRq-83Er-iUae#)bC2'&p+R6[$I$Qk0bef(&G-'j1`5rfSjk*E'M)&Pd0
- Xmlil"*b%HNULIf[iQ%5mE["6MSSr-bZ*-c#rMjmP0m)6&h9Ki0UjNM`4F6rP+[#
- fIe#i@EJk,H(+9MjA&l2a9cl6#[5M!0a%A5lE$9HffY+#l-TRE)Yqr+cYB@DBq0c
- cfRND4($2fBEH"2dD',9Zcb*HcI5F&$DqC6AXIkM-#b#[e(dS8cA0hcBaC8VB'jL
- !Q@8p66j-UQrGQjVJefeBk*-pkq"C+NCFeBMkc3*R@bKa"Dr"$Y[0%kP+Q9YZpU#
- 2%@Q"3c1iMaJlU4%mMc3p[FLP2NIAXPSdZ(9JD[bk8[-#UVH40Q4+qh(NjNP,Dcq
- 1[Xi!#YdHhJ6@Sf$Q+X#p(5)1`*!!21h"VEQ!6hrX'1K[Fq*M0YIB`88kZ54[(%4
- I95Lc'A-eM[9(6@JqB&[&r(mmK49Hf9UM!@I'M#ZIU41HL,cbf@FeMH#$[TSjS&N
- +Z`)mkl&jd$B`#V8dr'R8BF"Vk))pe1L3!2YM%@UA)Xp&[5&X4"@Q&GQYR6931aM
- Pj20[3mh!Km'e8h1%BNiTb,0HePNhc1GNeJpe[eVHK"!GI4Grj61SNr3q68edJkH
- Br-(YjJ%LmMdq%lCES$%-YrUj,$)Gh)9Jd!KBh!PJcM6H0583VqI6'l)akI8ND2R
- 6"Y5epIA(EZ$CV5,mCbDi[I(e16b@I(4&r9FCb6bAeic0[mrQ-bJ5BFEQ2bcr[K*
- cP8VNG&B#eD-1p@INXr(d(TV(#NhGG&,`*AINMb3h'25ilqDMli,SZi0Ulf-AU&(
- @2A0HQ$Ad1ibMLG2!lc$J(BFhBDc#cihBYp*iR'Ur[,3S[i6Hh(f(`*0+Nbb)qAm
- 3q0Jd5m3@l$LIDBf*L!DI(QCI0UqXca6jc%N@5AG90$G3AfmkBKVVqL@!bfUA-F)
- eeH+@'8jGKq3DBk)El[(T62D,4'f-!CZjbLq22-FLJK&*PP1a8B'e"*DX!M$a"+`
- IX'*r,hR6iBR&NfNSlU[860S6RNQhd8b+VDfUaQ(D5l#aG#6Z!MFe+Tb0QS*r,6L
- jU60$VP8(h`h4eFE9YLPA[TMEcGM0P6CES+KJ)[I+-F$3+M('8lAcQ$hI,faBk(l
- $YT!!)Ti#hQGFbqMDJ+Gf23lr3I&VXS%5bc,98pF%M+8G`A@dGI9XSAkEe`5fdRX
- i-h3EchL$1-8I"GE50@"IKFKPCPZqPplSQ)0-S`GQhE0qBQXLRe122"amF#,01-m
- F`5(4YJTCLFZ3!-@0KC[rQ)bU8QrQ)UB4A-`hR!aj(jCGV@FT[Z[pKZD"Ba)`Jee
- J0de*5`MhfFhj440!EDVlkh89&D!m&8rXki@EAhjDb612jrPMHC-Uj(FCKC!!plR
- )4GN@'JSm(*P!VV8T(2G3A,Yr'BY+Tq&fU3"E+8H"hclX@qJ!9%6K#f(L40bpR0U
- HpUJ)hkV#$p)lGa$Xp0$G)MZpfPH`LcEdj$[PAAahJThIf%6X[@9k%IDYD6**0Zp
- EDKjiq"Z6MGiYl!,`15T2fX6)Nl)Kq`bqCl%A*Q%eq)1,DH11EZmdiI@fEl$"d)G
- ajR2"B'$S!f(T*bIrD1M`8DB#62V6+Y,8Mh(0KH9XjIcEf%d,ETjRRRrVUVNVc%Y
- [86AM'$FZYp`P+ic""FJ9E$UVaNQpT6"QlIajFeH+YdRL6A0[[S@LIqP-p0rlYqM
- q(MmLK#&Fd`4aIX!BS*BkA$[[ap%pc-CP4eR`bdLdK3rLZiHB&d*,X,m(4[LIQXZ
- Rbp+45E3GY#4HkBH#c%8A-![%ZBR%18JcVEZ!p6VY-&5kSCHLDLaFZ`#baJS,c6I
- d#(PF"ir*Fk2(LVj2)I!0%YD@36HKYTKG"'f*TMC'9KT)fJ!KB42k9DqSZi#4AY-
- aAV'M`e!fFSTk1"f)!rQH6kR8NifV82+h@2!i1qp(1CG8mPHMqClc$%bEkkYNe$K
- AcCUlB0jm8[%$36qEd'@hSYNf,eaTARlpc2)CD,BkCc9%NAlf@[0mX#NRj6B+BaH
- (LeFZ#Nq*$)V8))kZ(Ld"MAbfXND@*dL#qdC69j&#Z[*CaE!E+4F1V,hBh)McYQ[
- pY@L4@R`AipZ#ldVcmZK'0X%qIL5$B'8!4D9LZV5S"L)DVr$#02RaN8@b@XP2e$[
- VR@+H,+8D5J3KG)m%Y)P'`QAdAMJGb[9JDS'%bPZUd0fRbLerQAN9DEL"H$X)k5a
- 9"65'Dhi(,@b)i2LH"L'%#fE93A3I0+T#e6FL&(`I`NcNGk%+888aTA0$Gpj#6ch
- Tc)6Ra#%j3biH-VG(Y2QK$KQ@5'pj&5B2"%k5fPD5BPFUXJ[Vdp32iYejBDf5Q3S
- +ZDM)#GC`lAeFXEGa1CU'Y)-EH,-S5Y5)M5heYC9NQr`c#[&E(UHAaeT8@mIIV!9
- [mMaGfML)R,iRZS"PAeJaKZ84ANFCcR*1Pi@QRX)5cM1Bjjph$6[2E*al)X%mpm*
- bbk),bl(qpC``'jFFCKI@APL10D$R5l1aX4hIGr$Y0'rL5QGCdEPSMd5j`N@&V&1
- @$e&cXjE(d5MC&+klX&6-%qh,)EFD(Y0+5+-iHp`ZHm`Z+EBA&Bk%))'T4IRNpq8
- L1rXfdA#qG'0aMFdh04G+m*DkH4+hb8P8ee"D&EjblV5@1deH9Pc$PGPT0c0@G98
- jLEjMTe[9ZR!Sak95PNSCMF+D8pPPRHc5Fq*#Lr'T`aH5l,c,DqZRqVJL3FbNjQZ
- RN!#F50)S'LCRdV5DQ(DC)Z%2iSLALB86a2(5-[q3!$&FFjebQ,b)6k(bHY&eKl0
- QC!9%R%)T)3E&FU3VfJL4G"BDpb#,QD[YDekUeI9Vk(Y16&c[2R(YjdP'b4Ji3QY
- 5ci(J`4j-(TLb-P&2FeqV*p+)#ak@Ab3Ub9+D"0e*3dKANN&ZPS!Nb%QkQ,ZG1V3
- a3aakIml3R'(imiYL&d1&kPL@-@ciT5-bFblPIL8j'6R$%qFX0-h*QR-*-d8NkKC
- %k2#I[&!JrI56aEVl1S4$+Rfjh2iXK[*AMIQlXX[*45*f)hcTlGJq,BSVjS"Dl0b
- **9`1)3N9#SY$0N0!+`3b3kaZ!d3X,U8A5Ae%Gj'-2KBqE+Ur,90#Bb'kUJck3-0
- $I[mrSjrmS`XV4PeBB8FTLVbd[idI1LTM9'Bj0beN[5f0&eJDrfLH+db`01EKq49
- ,if)miCGTRUZID9iN,hj$,(-MfXb24qc++%(UT+FAQTf9LNaSpP1#-C@-6PBPUM9
- `RQTq+,cZ*A&eMka,F"Q)ePLdCX5(@[+'#$fYX&0@4KMj,QZ%idqH'b(LQiY[NAP
- q4"D,a6jjiAc5jaJfcF-c2(5HLCfE1dpJrFMcfJKXKTjiI"(@Bm+h"0p+I+[0mbi
- FAQ&Zrq%$-96[ql-BUV"j!4I2PQeZY#EQ*BjV,"aBP$MK[Y-kZ#ijTB2VS5*&"eF
- iFHl[)Iam6C(im0bfl@+LH0'[A[[c9Ip0#eFT`clD##f'f1bZUKd*#1Qk1[p)md*
- J!k8-XM2r%-m'RamDQdSC4#!LJPUR$@@A0ZUm`iCHBKV*X,K$`f5THG&eP6k+-h6
- ZIK1qaIL@iMX*h`[`RBj[$EjcmDh&Gc'q,ILZa2IDh$[iaMkN!&U4&pAm8Lj0NQ)
- 0HfqVml0SaBS#D8H8k5Qr'P1+T9fTC0T6#U@Y8LjJ9bS3&Ffer`98iARPqlIilXH
- h[IIF$b1Y`SFaH)Gl,rm`r5FA9Ja@2lpYASV*EbUER,cm*aI@$qDIhfB%h%kI@qi
- 6UeFSQLA$SdA)*Kl#b1H1X%qcV`H$#C[9q@+LZ6Qa"q0#(m1*&pE#4JZmYK%1FMj
- fM5'-YS'`Cc9P,JiXKa)*b$JHB[kGkQ!@"d'KI4)HN3)1BBTQ5MK5(PT+TDV9j'#
- (!a8+8LUj8&DKKc"59NQeiaUa`NV*4@4@LNeTV650$Ek3!1N+aBZP9jT9@&3YQpl
- X8&UTFl5N9TSHYZ*+h@Ba(kUHdQ+T)eKQFKD"PVV`A`QC9Aq5bNlPqq@3!*PmEGL
- -ai(9bcHL-V2b*T9H[PbE!J5!&Er5*PPh3GV0bX+N*)i[F'+D,NY-Nal-Vq5D-d[
- 4RZ&mhTPXQSAeI#Bk#dCMV,-Z[pJ(e-MD4k'KdR44d-1kr")l!"affG`*895MX1c
- eS1aP&S%U6[P4!!R(HkmC6a+EFY0@4F+[3I,fM@+c@#)Y*$#TT3`3'H[A[H3bU&*
- [K2VP,h!4pJTX)[q0h&rT,Ki$U'pK)d#RGCKEc9@NbArbVdMR[N%Dq!f5`-q@F#U
- 22e1"U85I2UN-CK`,d[N0Dqk%BLDQ53Y*8lpK&SZAjc%5h'mSUV$,a#&h)9SK$dK
- Lp`d5SQq3!14VJe6h'rK1AN+#qJe5f)m-TXmV`Q[+$D@-j2FEK@,4SQ*@FK8U%Kj
- kc`J5eRp*L5Ud&@*+@9NRFX0(T4`HFYZB8-T82YC6D[#fZ)A+b(hK!M9*J64[*,[
- 5h#LBEp33%UlrER0M,RPGVbPQQXXD,cFhDXb,0EL,aark*+BfjT2h*JdZjUfBS1D
- P1,GSF(b[)deTY-Xq,Cdq&mSqB1UeI+E)q8,9eN@0*@5l3G0%18d&2VqQ`[c)!(B
- "qk-`3ILCd*XYCRN3#)VCX45LCj9d9H0(T2Eh-b,HN!$qqaR4,)V52,&(Y#8i[#+
- M,U-bBfU'DpKe)qVBm1Z'e`f['$k9$EdZUh,iG9QZSFkXUF-VXZ#*apLC`bSbA4N
- c%+ijXc,$LrH+6"I,QT9C0Y3eG1V3bU&eQH@UaFLUb+b"FIR`bZ%cKNr&kh2)kLc
- RX&R)TEKQH0e3-[3-R39,DcLp&CRACAST!LT42(0B@@BP'eU1Q'HK)-E3#XU--N6
- 5X)kVP-12F`e&LXAHS@@UfrbXZU%c@0CeQCA`@N(qa914!-bISh$)$fr8ERc3L9)
- [3*RV-fFTlZ0G`qXSfDZ3!*`1cr8D9iQd5ea+iT*fXAIiG80Ve%LaQX!C9VYXL+8
- ,@&`qI"C5A"k8'`BP(eH$&KQ,1U2@p@ciV1(8&QM1j4QZM+N8kUc+M&P$kc*3S,%
- cf#AACFbL*Kb2*La'aFE1c+JC"XGL0#F&-Y$*Ra[Z49Y30VUbijA#PdaP-#fLf[D
- Sa5hfmM"82!j38T(PbN)RM*Z*"%c$1Fk-LSbD%8V(F5-X(dEqm+D4JEL,Kk2pm18
- HiK$M-3i3J)E!Z1Z(HjA8b+Gjq+`Ja9bHjB9$Id[$maa8'99GF3PeRP8XH&0R,U*
- dl"MS)kNMji$1a!5KkF,e`%"34D1+A)@aK2c("FQ'1BGfSD*m,UXXLdB3'UKe1,U
- 8R"GRcD$a86FFCD-aF"8L8,&J4DYH4D&4GrJ99`ccSSR4TYbGD0k9e*&MVk9414B
- GI9@i9*4Xh5A`kU&``2*+-'h*VX`dK*%!pcXP3C@Nm(A$VXY!FC(#!TC4J660U8"
- 4cN%ARXdR-p)YU4Xa8kl%@90j54&D$Aa$EJ4fkH%c"L*'LLZS%iU[bk!'@SAf1lX
- #RUfAB!'J#I1jS6`64&3@&'4XjA$ZF,EXd&m3BqM-6"kFbN#9jmT%ir6`bY804hr
- '8P+"1%`VjF!pJ",2[`3Kar&*Gp8`Q"$XFaRP'4L&e*!!k'Xm-9QE88MkmR$jh2!
- b0'Vac+%9Q65)`,9a&3B),5KrKZkV`rbNhU1eTBlAjR03EX,VMaUpU(TaQ4`$-fm
- m0J6+$E$D`9I`hBh[pr(GLqrE[HGq()[[QIK1`(FU[M2`[46IHRbAi3YilHFraAF
- G[VIJHbqqr`VI*r"&2Mpr%pmIip[GHqi4,EkCq*k&Eb@qb1230IJfi0Z)ldhiYZ(
- l*rMZa2Glq+)1Kcl&&r(Ik)Y['&r8iie-I+IJ@iA[6(`"qle4MHmUI'r$&h9iie&
- mYq2ljrJqKqrIi2XD[Mr$&q$EB3&I,ll*q+EKHa+qb1r`+(b4ef(8jc$UI(J@[Z[
- ahBV[BrMq@haIa"Ge2AbNppa2Sr!GLHmBI-[ar65q5r$p2,iEm2dGI1r$piraI4a
- Ie100e100a(rc81rJ-Hh3#P-G,BXd*kMIDI@%D6PD(!-0R[Ai,XC)TKDQeUBT!YY
- 93mX`DmCLG*p9KK'(S6JHBd(@,9l'B2JFlEM&f(H,[633N4G'#RC4,%!BKf6[bF!
- !T@P'+`"Q#kEpI+`@Cb&Pl"md$6&X2TFKHf!#UI`S($eiSQ#+m3k(T#JP1#!&c%X
- D-1*2LcEm-8fjNTLL9%[N2GB9a$E'*[*(CFEA$CZ4J8A,$#1cLYC`mViU!hX968Z
- G!FBB8Piq$%CX-TbpbXa*M$CqP'kqE%%BDSHcZ(12l)0"59j8AGSH+,#"'LkNiY2
- ZLZ62UX%H6me)6@N-Qc8-ijHEPf+S!SlM-rMX8&r!LB%#2(MMSmJSXHU*XeaSa4l
- &4-[b98SIUIJ)KAQ!R31V1$GeI5EkB1ce!"BSMA'9`fCQP-'%fU"Qf'ZLXFGKK+"
- [99Y38pBK$GeBJ%XSa&NcJYMiJ&T3Eb*IUJBULYN#lfCDIFb)0#QSbTJ,6Jf2qQ0
- 3,%!ld8EQ4-,Q4mZPeEdmcCCM#((&-2+@$bfM-Y!#D"B*DbjY+4L49#9ZYT9$[93
- A)!6icXr!'M`@L%6G-,5C1"!@J%k&*lUE*eFaHJF`aGPBVFLk'&EDI+N[MH!`2R&
- S1XTqU)BXY3#02lAhB633T+'f,0QY%'("8*Sf[#VbP$d,Z8S%QAhFJ$351!m-@'V
- #P@Tpaek2A([#-iU'VC8f,k68[1LYqJaRaR8Qe!Qa+4#'#TNj'#h#+e%GXp04@pU
- 6DACJ#-ZU#d$+N!-HVbKA$mV(Hki1BGDlH#B9'@l4)P[*m'kT&a0dQ'SMM&&UBR1
- pjBem*9pZe9C,*[D%U6K)4F9)*Yb)GPb+)N((FM5!dU1pQ(CGfJ4SEP$#Y1A`i+$
- ac9Ea4+-M,dUr#+iV8@BJHe6-j3#Z-$'Te(9B0&E3UJ6cf(I+8,4&D*VI3UUV-1,
- 13UIf6TK9`&5`fb-"G$(YcL[3)9J",$mBd5VLDmG$99FL6eQdhm,#r"B@eEI@i2Z
- (q1*#j#dXU'mGaIHGhR12kr!GJQm'[UIK@i![&ZIfE(`RicXEhiAiBJ&[[aRIHr$
- &`YZ1aERp9A`lHXrp()[YfeKShmCLq[C`I-r(&`[UfeLBhmD#q[Ceq'l%pf[i2S6
- [[mBAmGp'(Gl'i[df&Zm1e+X$#fk(%Gp6m-h"peamTq',r$[Um2d#[RIJqh9mN8F
- (mZKi'9mXm"h)Sq0MI)rdEM`4-rF,l0YNIUFl[X!#hXR!&pM#1bM*1pLehd&*hVN
- &Aj6NRFI`r3Dqcq$lAAchiIY@llNRSr%GK5m`J%kd3QFa[[2aaEP2*hEZ6T5dmeC
- m(m!A1hIRXrKLjqjm$9pJ'jelm2d*[QLe,Q!5AGMpZbl'&bh5PB-[6SQkVJ*%2DA
- a1)l9I2L'm-@GP`YhALkFKlP`kqA#VCG,`KIhAUjLI1IJLhX`&bk&AEJ8GXh%G`f
- qkr$GC'PXY$3f@4TK1'KTA-eI@bb0cCE'$CE'6CE'J+@aeG+ieG+ilp4RMq@j!-Y
- L`m$c0SV)F-"G9m0'J*hmB6$"ab"c)ibC9iqcPNk`jiQqHPc9,QG4&jMQLDRL"5C
- 5Q#P5-A1efT4cY0TRcp(Uf$PDCSM6XM(iVSM6DUE'DEAYF9VG[MKYj$6i"2TU@6+
- qdr'YarG'I"r"GaHq4rTUK8hi`ZCk&pp1q!4LY5`*he*mTq-Ek)2i`q!r6+XaiPZ
- $ldCmGrI4DR2aAG0(Ui2GXa(IAILqLQpl(fd%iXD,q)l(GcUq#r"GhNFE1Eb2YYX
- GIE6kkr&pVSmfDNdIEA3U[[2`AGP(fler(kfaUBmfCQmIEIq*q'lTScdrYSmf!6Q
- -Rih[[MlDV'*mRd"0TX9SKD[a[5Y''c%[4KYj@ibfff"m@f+dHNZ-0KVfT0RiEX,
- h[KLYS5e'fqYNM0Ci0%EEHdb-0LB6-9lTVBeZlkhY2KMI$IJqee[EijEHf[kEHfX
- [`2[8"r'&rqJp[E9*L*&GeaXp%G)bMe'V'@N%@a+q,aUe8GI!*p!,[B2[V&jDcCC
- H@PeD,fh%pEfd8CR`#I68'L`pY6eZkkRYH6fqMrI8XUYlD+-d2E5'66fd2DELqd3
- 2a!'Cr54mPq0l2li($&SK%Gmjq'l(Yp1Je@`cD,AAi2X`[[X-fSM*q"idD#26m&f
- !liX'EEG'JeErJN%E[FDJlBkF!L+qb#'`$PrN%AJ*hchiGKLd2B`'EFmfJlBABN&
- %9*aaMd(EQdMe!ph4qdRDETVZfZkYhE@peREA'Y1kDq0Fq"lUVSh2`KFq*b&1eSc
- ZfL'hGGHDVZQZc6MHA6[XqHlD%32`49c$%+ePLG&DlFaSVHljD'h%l'KYC'DdYPY
- +Y&BIMqmUq!HLY1b1++dQ*8UV5i3YS0Hb1IMHVpGU,2MHU0GUEILZd'YeUrADk'A
- i[UlApKb2lcDpY[GD[EE2%EdfEJ#q#r6DFjl9DrYjmGfKejiAVpIf,p9V"`6dfS3
- B[6ET'R`4rm`pHZhJjAVYN!!i[6CYSPjVbY*V4dMi2UIACKl6Dl1DmGfReelk[&i
- l%[QGYdq[c9kPeij'MZIILqmZ[AC--Vk2i,YIVmdjV0G+4RcEp9VcF,h@FNL[,8$
- p,PQLejDJ"Tp'[(NZI!rVYGIBpGSTU-RPU2(Pb'h"#Rb4`m,*q$kKeeCZe@ZV',j
- hirZLAMY0KfqZAMXGlkCjq1l@Dldcp9TI0,iYq,kJeek,ZLp$69G%kVAAShkrM6b
- [IN+[E8!0ek#(VNY#2`@kSDIahG30mc)"F`qf3+5@h4QTMAJc%MhTeIE-aRGeT$B
- f1P+ER"LT6Gf-lrj)lD!eq(C%DSIXMG5Q6m2h,RaILG5Di[#GKZmQj"')!%-6[Td
- 4@U%#hed4@XfD#'hNQ!KYe*i)VH&kI*q-d"SILp$'D2"&V06"%GUqGRah4'MMi[!
- Ya[HT#1dj"ILq&+'0AaDKlEFP3RYH0Vl)*m-ES6hr[JMYJ0RiES[3*N4(D-9LI$F
- Lli"1bd5G9PL%l`2ilY*T03`q'*A'FRbIa[FeV9C`DE@DLIJqTY9U%r'YaAHp9UZ
- cDE84p0f%liYDED31hb+YYYY@VGD`6kXp,k$9$R`$kpFmV6Ee&Uh@&)P[T9ClbAL
- YpP,N02f!9RYjQeCla6'YYQ5S9R[9BeVYMc$k,NFZ#j!!ai+AYGVbklADLNbYY[)
- fVEBU(prRY0TTU-0R,9UY*ajIj09i3UZY[JEITl6DU-%Dmm),q[EZf3--UZ(SJ9%
- AkJGeNqi*haZrVkTim[abUrG(j[Q9R[&XM-Nm4M62JfPb%af%H8"5'$,I+JiD-K$
- #1maNj#TjmNeRdTXm2jVTSbm`5VqSJ26kPC0!SYNEJ502QGZMkDIiIVj4X!3$,#!
- %0!&Y3"H)#%3'ZJAdJDK!G+"l`"$S%HJCk"8`"RS(BJ*p!V'"[S'i`$Q"q-#jJAk
- "m`,p!qF("J35!Q,JJN"LB'!J+A"K)$P`85!PF(%J06!S-$J`**!!&NJ2Q!)CJD'
- "BB(KJ4'"c-!PJDc!TB'4J9'"l-$S`*K!6M!J"F`"5m!Db!hN"I)$B`-&JA%"@q#
- b`2M!jB(#3&'J1("&`"iS#C3'*J3Q"Ui-6!TF&EJkm+2!j-#2!pF%TJ3FJE,!e%"
- jS#,J$,J#lN"PS#S`,6!pi!P8"l`"Am!IZ$C3%kJ0e!AU!c-#e`9Q"QB&VJrm*$!
- lm02!R%"$-0!BQ"ZB&jJI@""B'&J8Z#(3&&JF@"*B'PJ@Z$'`2("6B%9JC@"9i1E
- !,B&E!lF&EJqX$[`XF%IJji%eJ9m%lJcF&9JEZ$Z`,R"2i0l!,`2h"Hi20!GD!ZX
- $$`3H$$`8H$M`5'"$i0(!Bi((!dm%RJaX$$`9f"6i9@"ci0H",B(I"*i1r2DhJGE
- !-i&R!mm&RJrm,["#i-A!eX$[!bm&rK"i1I$(`,E!+i'f`2E!MX#VJCf"2`9H#r`
- jX#[`HZ#0`&m#E`Eq'YJGH1Z#`"ESFGlc6Z$G`(Z"[B(h!rX#(`6f"ci-(!JF$"`
- +I"3i(2JiF#6`5H"Si02!XF"RJH1"c`-R!Pm%6JDq$,3(JZDj-3HqqqBdQ1Iff[U
- Yph8a"p)X`9lEIJ""N[3[V[#r(G+PrD-r[0Ii-N`rhVY[rm%2$b`ip2&(#hpqj#K
- N9Ip#PrC$Mjc5T4hHGS-U6$[mqLrrkcAqj+"aa`m!Y-(l1m,I+E0''k`(KFmGGpc
- ehq4j2r(EIjER[@lTcm9A`Qh`BQFEh,cLKT8h3CRf&frrfH(9Dqlm4@FEA0[lYBX
- D"dUQaNEG%(h+"4IUNl4$08RkT0j$MBRkaXB,0CFB"qY&$EkK&(fM,P(6D%c@cc9
- U,YCIV'R8NrPd[86XQ'80LqIpepr9ZrpES-%!ITp[q+'$r&BR,99q9rpLcZpNRa[
- Rc@YBhKRNQN[DqHm(q"ljiSrYRmq*DcLI(,ip`EI@R"L+5VrVTAR5[!jPaZA56bi
- lh("$`lSEc,HH@#)YPpk5DLhH"G,$NZr3$C+rlGH@j"[-2fX3T&FERQViYI5k1I,
- &KYNI5[Iq6&VpTj2i6EVTj(YI5(0[Irb*ZrGXJ)V$D6ZNHXRccQeVe[eLrQdhh'U
- 'Q(XM6r,1(rImr&r1AbhGrZSc0paJhLqYNPC[I%4D)mdie2#801[MKk8RTGN0pdX
- 9$IHE5jBYN4C)IfaB)5eBqR2caMR,cIdDDT(kldSHU@V&Vppqd1bj@IVGqe+qp0-
- E)+Ai,ZNbkEhlT8GZIpKmcmmPSQl%,kQ@02@"kjYX)H*6+hrSPD2iYPZUAcQ#GlI
- PS6B0E*hJkf8P4BQ18E2Cd$Cpi6@&pFZ)!QN&X3f!INNaYN'ThRD+ijIiLeQ*hEX
- SfNd8"4%T6[IkG+hPiIB(E80H'3m@b%eJ&hd!hiFTQXpMm$+KIEel*RmrA1fI)6K
- Fd1A9h(kFqfmb2%`d%pdRA)8jA!H"lc9SJc5XKpShJI8B(+5NhRK,fS5L(("f)ZS
- Mq$k+li-8+kR#P'!qe(lFEd`AL5p`)YI!&lF#I-E6l0D0U-(5@k!H!2@kZEc5@6k
- G-Z@+JH8b**,@bm*X()lRil9'`jV[,jLTQm`V[@03`5XHUK%Bm)Cdfd%qbAF3Ral
- e9lMke@E8*TFCFdJY9L,hJSl2lZ1`TX0Dc)MhP1ZE%"#VAr'B'ZNeN@YEmqN6B4Y
- GS-NLRh#P*LYM0MLd'f'Y"qZGZf9eHRDTdejG8"dBfLb+8j)+dU0E9SNfk"5Z!CH
- PKf+!!p,-*k%YMR&2BVYNrB0(I82`*4CrppHqDI"P[ZHBEpADJI"+3"h+`TjHAM@
- `k%'a-Emj)e63aAAZcZ"+pY"[kfNqJ1)%(#YUPU$MLM,"!!KZ@VrPjUZ+FV3Y[k,
- UIV+)@$K*JdIp8#LTU*!!qbqR5HBI*VpC45j`6'pGea(**pS65rbjDp0X9RH-l@C
- S4CLj0X&mF0Y-F&4HPNaD'+3+MEkbL[,kQPTIM9U&TPHD8&@STqla`,D"HJ+f@YM
- @jQ!@`$B,YM@+jZ4+f*E$MfaPX+f%,3Zf)KXB#9([E,F4AU[K"Hl*(P,c&e#VJ!Q
- b1Rh)+l1EVq$cKrUKL8V"mqG`ZKD-ljLAV(&M0QE(BAb2G%c-`jba[)cEMRM)9S6
- *QAeUFPCB*Sc&j!bSNj2d2[,F1q*l$Hbr22R@mmPAjjaD,hFL-EbQLdQc-5H2f&C
- G`j94T6(SMi&+,X`ZL!LPA$aYNiX`Fp%&U#mVhNJ181m&V2[R+C%5`j%#eC(XP8N
- Hf3m5KE9I9I8V%a@[T-km#V0*2bAV,)A28"YPeU!RCGVI[Yb4"1C1+2pX-(*pTCh
- %GNp[lJGSmkTX2%pkjI)Cc!,YT5Z-Q#0P8"e6YJ$k0pZH&"15*'KXp&1Ap"a[H8j
- -`,"FLl,h3(I%jf39@$4RadUN2IVEVYl9VraB@)qCP8kGXRQF&fajVFimli`Um&%
- 4Rjjdc(kq,65pBQRf0VHha,5B@Pkfh0rbNqELJTN#hd0iAkM(p(U&@lH"lEeUEFA
- DL`ICAldAAR[1HV89c,c5&)VF-S08hT!!%X@iCdlU*U-b,4PEJZek(C4N35p4dcl
- NN!!Vji"SP@!L,TdK3'&'L$Ud*iKD(fbjeJK0fiJ@U0j2rE9S"QI$CZ9cdPmd0F(
- c$`fdZT234p2j$$,B5BSjhcQM,MhE9qEhT`rCXm*b[q8L8hC83R-FldlTBUb@6KH
- VL(@qFN4FpcmLYXJ40rb2L%4RL)LhrjH)&i#$5Eh'l&Rpla&T$TaD[@dEDmEV1IE
- J989TQk+J&40E@[h!!VD*r-%2qM#LT[1YTaiDV"qk5XV"(XLf"mR@GVqkqI"Q$"Q
- K2$NHa*4kN!$LB&2b+@qrmJiSEkrb$LV[618GjT1+eCpLmlRGP+"-,Ui"r%2+1d9
- jTmVaX)QP+4lTr0h'eLVfNBVpFH@p3hNrT@EUZL0NZCXX,CS,*1(1N!$PAP6c5@c
- R$kq0TAfmj`@P0hBUlkFaFFbpR(2,CGYS4Ud"`baDBKNac%SX&kmfhVa9"V29H#l
- +M10T4PS9CjEbRRdkhP`e(P%Q8Mc-k4Tm@5N9aD'Hh*6V+kedM[AiTTCjaU%p5HS
- TZ[-)U90!Ad1lHcKKl9$Sb3@$IVH0)XFhmGFQ8PN4[k,PBhTlCKE-$!BYpqGNDi0
- mHXc"EMlQ!qLj0$5bcJ12%A[UYE`$dVN1B1PBlNGXf@P3JNXliEVQ+i!Kh+GL#"b
- [#(k[NL944$jT22ZpA"&1PTYBdXZ-PBa[HCj@[JRF#ACDXYjCZ2Nc[NQi$Y2,RF9
- IQrJ,XbZ@CDikHp4Q#Tqi5IbeNfG&HQ`llMir%E1Fl%E++1Q9#QaaGC1,h#BSXHh
- QqpBDD"&%*fbG,8j*,NM[hM,A%Bdq')RZlfjCDF1Vi6#mVZFC61GjFe@5H+Ea@`X
- hI`VYRP[R8dqj0mQp&Eqej@2NIS4bjce`'RqacRMIF4Yck5e$AKQ,lc5H93Z[rED
- #Q60C`FaBAPYr-qR3J)))p2YD"F2#llcEEjNrAlVLlPmZPZa(MKajkR(Ti+G(2j5
- HH1H*hCp+IhSI[mRAcTqrS'Ra`Y8,&bi&I(lpr2Q,PmbIhh6[r2Nh,&LqH2i05#*
- C+PLaq,D0jZ'h,(lN)@Q$q9)Tpm!qq,Rb#KLl9SaZJY*IL*ihQ,G#KMV5)HKL"9Y
- E$S'@RV@CA0alBM9Il`1bL"bMj@0H5*Eb12)!Y5@)Md'0cb1!KirV`AK'FLeA-%F
- -e[-JAmGhB['m`C3`Jip&LYL`#D6E[,kZ*@*@6I`ZhN&[)Qm0(V)'(a0Z2MlLfN,
- ,!SLB%C[f+`[dHk,P+(RG$,,'K8lCPHZ+bVRfb3hV0LP$mD$mMLY@r0$)E!mVlhA
- bfpLP[&I+EppUaAq(r2C28JE"'R3'FYmi`8[Jc8bRQr2DbX$ZTK&d*U#AEkr"+r$
- +DLlq0JY,mHdN'X5r!CC0U1bQYCIaX8pMi'*`@EA1XY5l`$kV+Pced#ZhF2Q'qBK
- e1`3kN!#0eUhEa5'[V&jldB3L'AaLF!E50,P[h*64lACR1DJe@qe16MXVZ5PBKE+
- #Z!l1U*lJS$X`YLJ$"KSef*&)JR9pE3qpXSC!MFp`5))bZeA1CI)-m)V0"dF[jp5
- CVK9lN!"NINJIlV30#H5k8hL@@8VG4Y+b'TFL6RRd),aSSEaplD"Ne"##8d$+eA2
- bQ4[6!5!3%%6%fHX[[fUX[HM+UiX+9C%#3XRGBl&"i!8,cdQh)%ZUd0F63AMH58-
- BGUSGDR4,pDa#jh8&i2h6pE%Lk4KIl)Ja"65[i+k$PN8VeqlA[XiemkYFer%mUZ[
- NRP@CFK`GBC-D`8T6!Bf3!)5PT%D[)*(([*V&[daJd,D&RPJaBX8#%JAG29kZ4-X
- Y$Lq[4*8BX6C*VS+H!!4ipGcL5LEJ"V*[`C@qCIcIB`'-*(&Fi8d,UkR[)Ad$-U*
- ITbaPNL#UCff5raBZ()Tk[QN@@1qN9iJC6pF[R@@KfTMlEVZ9j[4MQ153!,KQJN2
- Er2TNelZU*h,YF8`dj4*J8A3aT#YG!GNhN!$43[E46IU8,P#T4jrFD6F%rG$6GQm
- 1Pc$NJVaR%V3LZmA'#QFGP"&I8&2QVk`UPkFa"(fKbeUT5T1T&Sp3P9*-JTV0Xkf
- 2lp0NZIDS[P`RYdQJI,iNNkfKHBY,bQZF6ZmiEi9cTTa9S9DC5[I`lZY4TN8JA+G
- R@f9SmrC`&Q6"E0Ec!K*5N81X0U&`E4k&Z"MTS0l+V#2qlJ@c*TCdE&+m*i8i*%`
- Eh&k+Xk(@@HHQGK"-eia&`%`ddXCklpHaIPdIeH(X5IX*b"rXD+RSY-QLrVdQXKG
- E(MqX6`Pe@LU2"kBmKU0QMiA@J"Arhl1PX@XkI$`pDJZlFN[eQ#!Q4pHT3Ui6T!&
- 0kI#DNKMehQ)qV4l@Tm5R!-3mTAShHFj%I*P'ERei&YeD!DEZ9YqXm$$kMrd8kIG
- TR)pppPLP,`ZeN!"K3Y2R3IRdS+QM0k6#kU!%21"6[HUQCXGGVX30KZ1@qp@Ska'
- eSUT@$NYlcI-3CNJb(@Jch%hE,@$G-##f3kDdB,XXp3I@)f6GhCSaPc%lBZ!S`"0
- XVpj&8Jc`lF#h(GmM10@BKQbHTfa5ei8X%,""0J#K[pqbp"53!1@5)58#XJ"FF4a
- !1,"G6m!6T,c3r&T@kEZZd&PA@&m0dQfeLEp'd"RJEiCHiK)"EIZaj4MDPdlR0e6
- 1$c!4!dk&hHRi!PRZaEF$hhdY0h+IH0KHSdk`IEb`[Dk)-SG2HBaTb#[6`MY!+%8
- BAY!S5b&FQ[q0VepLJ'E4&6Ab$TLk6RP$$Nc2%96j9NKGAXNLFL"5DZXFbU-[Ll-
- T`k2C`HmAf4d*CHIpjqc're0fm2Y&GKfKl#$T4QG(d`1-Q5-"a@8UI5b40LQ4)5'
- *T4D&*a9"E"&Xb(dm[IpcVUTrrRGQ!afSHZGrCcE3ICLDFF&f,fX2F)M5D0m&$hH
- `hD8RX"+G3lP(qJ9LR5l$9%XleCp$#4iIldJ'X!S45q(UALr*FpT[CY,T5*1&c$1
- GmN&1irjE6Z21p-J(1Chphh)kQhV!fPYTfa)Sp@EXVPIkLIYBbq'A$C)44T`5-1T
- 8Mc1bajYV(3UXc2*UqEaRD`eHqeYQa+8&2p&B)4#Y`Y8I*aSN)@2-+aZDjaS6h)D
- 0eDmm,%ZbG4f!j$A16"mP!---3Gi5,1&+pMa3VZ9Z)b)[*`#GcMDqAFHHakjV#)m
- Td9+!N!"0FA9'A-NMVJa&A+P%j%-JR'p!e,LVP15Di'Z`!r#F4[94N!!p#l0-!"!
- 2!*c%F5Q[mSY8#m@LIBEMV-1FJB3ICEh6aK!eccENeAZkDVJDQ4a4UV'D25rh$%4
- 4[3Vmb)P$JU#H8H+XjA(@mMME1f+X3B`(P"KVH)`e2-BGTr1pm@bqe*QGcAkj'e@
- dap((+jVhS5[jq%6&hq$19k*[i0%h)2UiV[abcQDALNkQ[S20mMd6'Apl`bMV+`q
- 6r#ECjMI)+M1QG"lT4Fj8V$1@(I*4AYIeI'qIiC24(pP(F9$hUD+@*(%+%-,$U1K
- KIMJ!DAp&Q&9cLR35Ud8AV%H2"kqN2VpMJZ5'Y(EM@H9dEK*Y6"URC8%Tl1HG5C[
- h*[MJe&-mDVR8@a,![qlrLVeBL6eGMDcmj[MTR'[m[qH$ADEVG#C!H34Cq)+9c[b
- )k2SLG9BI*%&H3%,6Cl$QLF"2r5"&aUh,+9)`Q%a@b-hXBB'Pk*!!0)dNX)NFLdk
- RMS(GTpJc&(Y)X@FUGVGL(mPbBK)J0(B8afNmc66ckU%a(f*Mh5`H!VQm%$4F$iD
- HF5kM)3dE@)p,$leE3b!+,Kr5Je-JH#X)[f,iH5h)ScDZ`fXmH5&DCM")dVVG1%6
- pcVf3!+36JJfC09b$REF64dP()-`P,AL8a"5I$k6FlB9UP65UdlA`lcd4c+86`3"
- K*i3Yd*&JML4fPhZ$,03IN!$rFTM&A9A%6j!!Hh*BbaJe#JNDEBJ"eT-Q#j)X658
- 4QYkVD8B&L)Jk@"d*%BZifi"A"5bdA`438d2!MN2Cd$EE(!P4DmJ6BU0pU22PU21
- NQA65H(!QLpI+p9Z(Q[E@,SGUPj4$#-T"AMQ$ZKJp$C`83KGVZ-Ji%K@lc8fLBUX
- K)l-DBYk`#aVR#CGdH64M1cc(`5,@)PUe,ci([TA6K%[`GR-dDK[N9eBA&k(l6Jk
- H1"r4HVj!T(ah2l`bh(3`6!*JX#rcc0U*DH32aDC*cGj@0Z52E)Y$29"86CZTf-l
- epT0Y*"jBLqD+Uk61LSI)0F1"rX$C(2Iq8*F0dq3XGkk$k6LLepYeRQdiDVcB&De
- *B`R")#j`4X+(GkDq52FK0h3Ka,T"Pa*0*[5TKkD3!-SC*h@5-q5!38!Rpd)2C3m
- C[K!)f4#2kHE"C++*jX2XbX3EH[F``b`rXP0Nq#1Qep8IVdThR$'9%#TXj-Mf%3J
- 'BVR(9*P80d4bKE6SLXNHX[YF*%id$JGFflq)Y`'6VfID!fU%*XKl$P5cL&HZJAM
- N1!K1pm`SG1KKQH(5c-MMd9PL0'*phN2#pXK5LbZK(I"0FrG(T1PZ0F)R['U%+EL
- PZ$Fd6mVj2#RVR"ii[$X(XH)K3QL#q@"JiRD50ab(l[dh%#r+8E*X1jk"!LQ$CNa
- FpVr1Q11CR),SQ,ejE$$Y&a1j!&0[!Fd%0lCdpcji"M&Mq"3[-8ZY&MCZkV"Y3%1
- 16M[hBr$GlBj*KhJ[LHaVjKRGGDSIkhXLcM5h([Aa`RXe[)(iQGiKlZfAHaEqmq!
- 2c-ldRc2fB'!(CZ!)98DKEq[TfGJ8q$$F"4(I12JH#2YbMZ@BRTP!*Jlc#8c5X6'
- $X9F9K#ES+*mrC,['8a'D)(1aKr@`BLiqZ,FE`Preih$Zb6R6l+HThmf2`,'41T-
- HY9M-jf#@h0N39&fYe!jS9b61*-c5iCLPfBli-a%S+N@K(*Vh)&CUU'ieIjX9b!@
- E)f3'UMh##a33qjV8U#N!9%ae@hr08ZABpC2#hBDm`j!!cjQQG'4l1&H)XT30TbR
- `4DFApjrfM(E%l02E%H@[C2j,",-r)306qar,q'q&6Lq@P%Il[C`*BEQ[)0d+kMU
- -d"Y)Hb1N,CmZN!#+U(Ym8m%3X9XbMB*Fp(G`Z!DGRXBkB4rE)B`"R@03k+PZq!d
- Q1TLP6,2EDD2&ESPXYSi@S8*1GY[bLf4[eF[leGhILRcDq(p%2Qfm%[Q4[d9KQEK
- h&*!!3$MXieXIKh@GJJp5T%`J8BB`Jq`8,fX$bDTdZ@5Njim1J4aJT)THe"[9UYC
- $#K4b'D9QS3qiYek)f(RKl#CUQdIar"JTS+S56U0c69L,MX4f"Hi`f[8KJJPbkl6
- [MN`Z&VT)1`QE'j!!T#T(+3lafGF68+0iMT+3!-pj4G9Ci8Z3!)NQ2HpX2cV9`Pp
- &RRVp!U+23"lGFKkcH+A)jQT@,k%D+UQ2G#d%#h)&U"DeK4eG)GddbM(5I!L%*'(
- PVl,a6H)h%kQHrZ64"KP54NccYCheGHdU*Y'9G'XM8qGL(j3rQ(2R)-dG66a!'c*
- 33krPrQD(-B')*"VmbYDFiTiNek53!"2(%"T(`NDE,*hSmf0dL99%5"PhF3C(k3p
- L)fpQ%F($)@U,NY)L"fJGf$DTY)Jb*pXT-CJ)3#G9[N483LM`50I3Ec221*ZjcUQ
- SY-ML,YcmmB"5TI,VFReja)DMll8BL8N,)c&R5UqXac`V)`(%m2)`Jq*e2irNlST
- d,`kA[mDR1&52A1'[ZfaU"CfK5fC!+llQ6L,L!XjPc#[hT@I2dl1Hc8qD%LJZ%4D
- !RFE6r#4PX"%AJdT(c%A@JT!!Y#UJRp'XFpM'KejCjl0r8cIFN!!qi"l1m`DacV'
- mMd@P@TaTI@@Gh"phFEa493)hI+JU+N-L2(6(X$4$%XD9!Y3e(e-5U$Hr$X)q$Pp
- FA2#VFJTHF8eAi"829#Gq[(Nr"2ZTU3A8)if6BaJ4`b(+eJh%[K&SVKplMQFUBlH
- %pa`-9IV2B)-Ki*DRE%)cG6hdXAGJUa*mFJYY%*lpDJ6h"LA#LkFMl&3MZ(L%qRi
- Kqij*4I)a[3pB$#,GFcVb4YJc1ZaARlUeU#`q9Ge$NfJ@)mjXE0eec)$A5P"%)0Y
- @ijjQ3L@"6aQi&d9'`bDK@r-J5P$9BPJPk!hS[3$a#Hm)3V+NU`6Ljpdpe4LdK3!
- cIjPk(R8X$qmG!([FqRLALHC!r84-p$'[2)LZ$q1UkdM("$+R$arNI`fS,Ff0R(#
- mf-3bir(-Sah`VTC,1UY4CF8NVZLX!pd9,L@CaUJICR*Delk8`q0@PB)`#"N[)HX
- jih&$X'35p3*RCFjh)2`bca23YGMXU6C2S%D"PNYKHC,,905@K*C,(30#rU8KIfe
- *D"QTl!Der)+"m'bq51"Vd(5695%)%A)0mcTKrj[8p@jqf4L*#63m&ZQ4d%cCLId
- 1115m)ZMT9c4BVMECCaEj8%hHVk1U8cbNjrEf#1rA[0-jA@MfLpjqFL&)E[ZK4BL
- eQdqHG(Rb'-%5b+f%ehB3ac`!UIbBhCT+"+33fpa%1I,SfLRd`Le)D1e!N!#,E92
- U%KIU*&I)iQdC+HpP4"X4U83MjR`*cDMk&$jIX[jc(N@kmk,rdTXr3DEBkIGcSEb
- [3lDr'c,4J3L2fm,dU-Z9BX+&%S[%M2@h2'C-3+3R3H*alpqUFQ,UQ9A!(ClU!pf
- TVT!!aGYbUGS(qJh"Xj01pi6HIG'GY8QS@CJU"Z(`hGp9$$2P5BH"V%ACQ[1)m%B
- 6BGdLlr'md@TjJL&q*BqTkqa6"cVfUEhBTXVBmq`qe,6a5EVP0YK1C4,j,4Hej(8
- 3fQKb-pk*M)F91K4'3(JZhheklr#SQrfL6%4F,G['(Z&6ZrPriLAPFUCZl&UbPEP
- AJdDNNfK%U'[%fpVC[2GeH(ZaUH8r%-4Ff+#5pfcJFR%QGe`@d@i0,J@&+c5!G!G
- B!eQmI!+k(EKe0C,N+eL`6cb+DI%S0XS&0"-a"hbFVSFXQ$13!%`+'l!SZK"I`iP
- R$&0fK2$!laAf!,TpHa6c#PRbQqFVhV3jd*Y)UajGH`e)qeb[E&)ZLQIikUTFXbD
- !Md,9Lqq3!+R@Y00r#jQ1S&kP@*YiGDH8q8P5&@RhXZqYLN%30p0X-hY`L9(Ehb5
- 8Q09qUr+M@qQLh![[ere"bZ4QdR'dM+6im$4"Mk3KDf!rRKQ4i*j))0Q2%l1llC!
- !qcVj$Q9U%#fAd6*@VY`ADk(hDQ&PUDq)Lrfkf1QYPqq@R'a`iE6Lh+qcH8C"8-e
- X0U[Cc+bXFS(dJj1KE$T#Gf%GQ,'3!%VCF`*h)$lQUDCV4Di+0N%3f#KE+CJKpZ1
- +U"X6dH9K`Q6&%lY,hlEilSjcE*G8[5Kab1)1@531@H*$PX53!-8IXL5&,&)"XJ`
- *@C*$PU%K5dV)-LaN53eCKSFX)lMPk9"pb#,e)B[8Kba5(l*)PFNLY5@,,f4"cG6
- %p!(I)CB9*X$5hM52#1dh1i[f)ZN1EA'(,,,T5RHFDk[H-G&(HE`+mBlD,c&NmBF
- X55',l-c5+pU5(,)-$9P53TCK)FZ)PNYj(A1&p@kUP[52pKl1,G)efL*eNkl4&Y6
- 0l"TY!ITJGSffS(UmUdfZQ&CIUii`f8#)12'akVHcd8dCSka[Ca09iGC-[&cmjHB
- [$lhLp[(A2RUjH3`hMq(Q-Gb)J6fMNI!pH2mEF3TfPLHieD9BRq4@Yf,p&VGk&1[
- 6C%@'BRfG@rFTeRhU90jU*`YfUiN@Gh1bBaT&3EAXA&%e1eG8cmi99Ib[Z9C6VL"
- )6*0j*5BII'9cZNQ2VF'PE4R"LI(LUh%YaMMa-(kCqMSQb0Pilk-hd)FAP)RPjGi
- dPeKq)bD9hK0mkXk,+2j3&2rT+1CQc012SR"[fe(-'DLL"(hpDD)i1''454pYahd
- l43&Z-qD90fMc+CbT6L-JHE5aU(NZ'p!YmJCNcihcX0rrE6E(FRA(EHFp&UGBRq'
- qDa6VFpakV@*pJ9Z[8k`[FH[eL[89EPfV@&rp4kIqpdQ$kQj2cmke6l5hA%ifeDh
- 2d2[p2XBEGeHJ*L2,#b(,5b(,Ub(,+b%,dlZHZ5rFCF,NdENSI2m1$USVUDHkfT@
- E@T*(DK+fdKd!K&H",M9jEA-#4h15A#l&(f*8qrdYMf&0j*&,0'UE)9KeFcJVh)k
- C86(K,Qpj)"hL4h98H#aTHF!4me8QiC*-)flJ5@UQ9b`GAI`PlT3+Xr1,#NYE,ZG
- )8E8T)3YA,9hYEGC0NMY1[-b[@CXNPPL+aI(F-XY52%H`3C!!Zl&KYM!b%P-9q)d
- Le64D`$$5MENkV#Q(Fj8Phc'"VM&`(p20D-E*hBmh%CFe3BUje9k5@`)GS%abLVM
- *Dh-LrLfZajlR5&%V04km55U2+6DVpkK5,Di8**DRJZkd`JHTjDM4GCalC)h+2@,
- -NlP(m[6T%5ecCp#pG0"4fPR((Si*&8LF"bSVA#dL)-iD(kBIh[U4@'S[GX4a[iZ
- kr'EDLhN&fT!!irASi3I3``rJrA@m[alUjDqS9ebEbbSU,[GjI58NCkf15k!djF*
- QJM&ZTAaRiJPIAN#%VQY,Sdc61T*,k'4Z$`-AdTGa%XCZS*!!EKC*+#3Nj%pejb)
- $m'P`$ZSU*BG"@(QZiMHMdbp2LbZ$hpZ-M)3F0BdjSX(Iijd*rU#9!LjBmbM$YKX
- ipea"mifQ",U[CZZPC(dBPfFkFNL,Qrk9-ZrD-LSbDhEM)NZ0Zm1cMDj1CMT,[-d
- pH%EGX'2k8VmMSfihE8PU&N01+280AjYFiLra1mY,kUI+icL#Blih,`CbCV5Y#$0
- d15kqf)ZbrDb&q-Ai2Saa`kCV90Df+hCJHU5T+1&QA,TFkIqU'LE[hLph51i4i6f
- JEBeVkh")r@-')"*UmC60JKU6mLT[QF*$eh8mR9-%ip[4Z9%#5C@VP4B3DB0jTqY
- iFj!!cd5rB`cIQY48T+RFKHJpf$dMXjaMU&V3lJNV9D,'bR[h1HUpab6I%d6[cEZ
- A2@94#qkLB9i65,`IpVDhZbJIa,$cJCAbBD*[-"TeYlGSP,cKb6K*H5K13iY&bIX
- &*Hm0#KV+[@629H`q&L-4N!"D3J6H9$Q2`Y'd%p#95*6%-mD$j*GjN!"Z"M&ZShN
- UT+j3CYdRC(B,iTH`N!$T`K40&UVGh3,-XVZG'*Ik1CF5YX[jMbPS2d(#F([SZM*
- )YG@m2F*,dh`S(ChJX,+)(bl!&B%[Ere350ISQF@4AB[HQ4KDN!",1a'(ZKU&aZE
- l&9DhGYc4S!FN)cI,4'm+8ER4KLlM'-cFdYlm#C&cXqAc)Fp3me%CJh@$bikUTUQ
- 6epR(e[P)$)cQ&I3VE&JY5A6Kd#NQ%)-KNCKrUUL6N3qbMFXSE'&-5hXS4PjkG21
- RT89+ej&f4UEkdTPCqC!!'&R"ZRh'T!*rm%RJr2@J1AGaqP1kS+`eLG(Z`Ar,Qf6
- Y4I2'Gl5Fp6V+QJ6VQI@dU`MdJICk*hGL[eUBpVrR@@[!pR'eHLGQehT@L2far63
- L*0Ii)VCl*r$6fc[pJG*AqkDHR[MUcMRQ9Ahk)QdaQ#'1aGh@k381-ll9rP34c45
- U+9mGGiN*YNBID0%85qCMDNaFi,5mfSSER%Mf0#'0eP2ad4@45MrE#[R"(5b8LIM
- J[QM(fSZrmSRP@mffG-DBI&J2HAmJQiM%*ADK2SqGThXJaYD&MSp9"*9mR2G*TAT
- cPFLC2'r`Pd&5(qpL(6*bUcB&mi)&[Hc"j@-C[Qk(Sr1b4ID(,Q9r)%RM@R`!HHQ
- GBZY5Keha(kVk@eP8q[AS,605VK)TjGmMaCMEJZU@d[9[@mV4r36LkIX[H25p$ql
- f#Vl%AU0iDqVN,9CNa0TiYlpcXq)E&0U)Rb'[13SbbREFB%rN#",EqBT!qC,0VGS
- LhFIBUX5dr*!!BlBRlZaG"@iYDU@c&`5i+SK%cZ,l1XH`ph@f8`8LX3T#X4*2adS
- m'bXr&-Yc1TERE+bm8+cidl(L6mA5@%$mBAj[TD111"f9liBL'BC#XEbRBhR2aNS
- 0a8Si(5Z"BY&e)ULVUlZU`M2RSKAU$6DN#mb(b%fk0E+iAB'4V9,CMi-q51B(AQ@
- c8Y+N)-(rpV@C#l-$D*BLdhmHU&E)FK(9M#IFhRj!ri#Q&901iqN+DST$r-ImQSR
- le5UVjdd(h86K-S[[`6,F2*Y%Q@Pj)qHhBSlApI,Ph5G8IZA1RB6dj@1+B8F2T%B
- 5rTB6bEQBHN`4f!LDFBehMC[eBV""DM'rG[(ALr3+fH'rfZdRQjZf#-#%p)ScdX[
- 6$1p1YjeXVVhFQcL[$-d4lVeH*`R[)SF(k!ilY-("M"[4%biA0[8M1f&Y)k5G*5D
- m*#0"H$pQ`L9ND$PRPNLHbS`,`KH#SCP-a$F2hl[CIAJpB33M*,k,K4Um9P-[c!4
- A5kMBT11A[DQG9rR#jK!D2S0[$iYaqkIkFSMFPfR8Ph'S%c-ir%YR'Vfi%)1ieE!
- mhm(mBr4kJIZe`Br[4A&0lZf5KF"Nr)brTCc'hiaH5cS410KA+4RiZc*JHRqq%-N
- lG5&LbkXJ`[a'f[@f*Y#pC$+4[cZh)j&VbQ61I"-(YV*NhMGa@3l@Xahh#3Ia2M+
- Kb+3Y`6Dcp9PMJS[eh'[5AJ9-RlRXAZ(ApQ[iDbpLiD,'kMlh@Z851p+6lQEUbH$
- D6Kqq6QEfLD9dXlRp'$K6%'2e'BB&ZPC'$+2R9"jP&Sp#Gq9d*bI98GHZar0kFbZ
- 2Q2epAR5Y[2eB$88C`V&NhG9$$X0[0lbBGbpZ*Lb[m,Q'(V$L,'8pYY)FFM2AeCd
- jHSlDT8c-'Q+YMHd4pV54Up8',PX!24qd5d!GRl&CUhQr-`rcA'`LXdpP0P2*E1D
- Cc1`EGj@C"j2VaDjmf#*cVaFM!,H(!6e88jMQe%cpa%MUAkLP!YGL%c2X#PHV@2X
- Mmf-5501ISJN4U38BENR#!VDa'G4EJA9RF!jh&ZC5KKb&XBlYakq@*cV`Y[5[SR&
- ejRhPah-`!lk6q$B4Q-S-QH&Y)T!!b[UaISC8i9Q03E0)bl3f3kVf&Rcj-N[hHN"
- h'[A+GhGPbMKBe3m()&l9G+-L[1flDD+JhUY*rJPA`qh+9ZE*1*8RMYrGbVY,HB2
- r$eMIlb!6hNT5eh%qLrVr*5E%VN4L+YDMAm4mkP4-h+bmiJrD'fhaVK2`Kqp[+Np
- G"BiPL%ciGA5jULiKVKcrY-iqpAGeTB9&+SkMhAqVJV!&q6RlT*P*K2Hh,j2[r'F
- pQEHjA'DIqY[A[XmmaF'Lk0EGc$aapEpNrVdI'-LFVf60c$2r*I0hHeLkamGj`(8
- Q[ThrNXRIrNXQGbVlJkpV`aAZ9lTZT"hCZ@i%h9cdaYI(j9ViX,(ka[1C2f)UeQG
- Vj[Y!@@8X`fZIF&bc4U[6CfSpZXd4@6UQ'kl2e+h4CdC-e'IL94Ya'ei2GeBfJ5i
- `hVZDM%eb[TBm&NYA,S&cZjUjhI2IFq-1rdef-lUbLr$[$SD``cJHa5Epi#ZIb48
- +jRC9m9Vpi,-e+5!Xp9L12VU9Y$&*fMQpRZqMlHP%,$R@T-jZm!ipRAQH+rGXKa'
- @BL1EC-(dHZh[fdMmQkIl`-b!UU$Llr[Rq#b!40FSI[RT(JTpfd1Kdj8-m3RTi+9
- J1()38fBeF[,-1CeRkVGjTTl1-c@8TmCD$GfER@JVl,Xkmr3mI6V2JQrc,$MG(jJ
- )3#Q2p8c,kBS8J)G4ed5Mh#"qGh"Zf%P-N!"9NcaP*rRj'FBNKdr3`q@[k*Kaadl
- A-H[E1QDGVNj@U$BDV6Hd$hELpE"(qMpZZAVMF8Nr`NMLjR4jYf6#qmq9r-DEXP+
- rlC()"-G%+VGTJEjRrqFXL`[KqUSfI#@SXhFI#GfIV+6DZ,Q-&"r336I(Im`i6iH
- i$!a09rrVE(d&22kpS6L-DFGcf5Dq&I$Fm%e8G88`mUc[pVp`V-jY2q1Tka82B5I
- %[Z8Qr01j3$!dA!50)2aZkP@q6qcD4IH%AEZ!5lrB`R#P8Y#qkpXk,LlF[2FBGBj
- ,[HT((UkA`KH$*@`6b8eUr[+e!Zr*-aZbH5ICp4TCCJc(KG*,R'121(hiXV(c0DT
- %*k,hm$[9B9jFMI+9qA[eU1IeQ)Cl8hAE@V16Xc10ihYar&4`%eTlX@X!*+)3,eX
- Diq+,2-F45Dl+L#HGPCM%&i3[9q-K0qDe1bP$iehZ1dN@%5@ql,H,qeAM%Ra@FAf
- (hk-GYa4Y-TBX9aKLklf+iMN6`Ic-@E@T"(1J,k,iVL(2m[Zrp5fL6)[Kq8eeBUq
- *lmRaVM3CfDm"qjGQrkYC6Nap@l28@q2E&)C#ZU0G@Pd0BdcTK-Z4D0,CT3e@IR2
- kDYI0+Dab`eSdC-G%MZJqVr+5#jrf$#lD@a5--%HHHAqde9kiqI9e&1N@R!QfPTA
- AU4`"QUp$-9-F0QNR)PjEF[KD#9IFrTDaBAXS$G$i'Z48JCaQ+2SLF#Pq"@P3iTa
- kfX%Jr([J%l8VB(*69e#m030aP%aGF(&CcA6Le)%Dl@Ch[Ur'2"EU,jTPP4fDdFM
- 1!Vf%V&rNSVl@3*qfRF0d"1j,32H@16@iVXJ#6#Na9JDkP5*@KR0E,J%6Nd3",d`
- X#YeC8C65PNYQiJ+q0[B88Pk[XHH'P@SdlB'5'VH(,SQ%rk18pl(BcS@k!,VI)XB
- GaD3MHG85GiYi88h)#cA4RAiV&`IN('*6M8RJ9AfB2fk!dmIQMa[JPk2XEPGDDKN
- kD5D8V5qNJ5+AfKfK5phSj4eVYU(lj,CL,J`UL#QpFBCJbNh(6@rh#Ej[A%F@bPG
- aCHmKp3qm)8F[p&biTLFZ6G+jm,VbpY0GFe'ZU(INBJ0bXX"QKDVJqP*fQTBSD*6
- TS+b@3Nm-01K!632GRY*96SqIXS$'Q!le"RJ6+Rd**+'hd[Qeb&QK+N0NdE%U$qI
- A35+KL+iM89r29aY&C5YfVb0IHfiKrJAi8R@!RVU--c"959''L1JD0Jp@k-ES8Uc
- Njh3,HF,Z9Hfi%MIe6CMAMURIA$ZDQL&3IH5GG6ScfNf4YqkJ@*l8Aq3Y9@Rf4b[
- pPHU,pNG60E'YT"SH4Z1X$Cl`43q"5#qbV""iT#0+P#1K+$[*Kk2!XN)!Ti(Zd#N
- ZeRk)DN6D3)lfcjh%bpD)@fR0@SX0Ua+a1Vq+"H64p-&%a[eQ``"&FBJGcF4TGKG
- c[KP,4i4-KbpL1XJ189'&VBE%TSX8-M#U'#D)3[0a9Vj0%089Q42'dl`qYCJ65H(
- ,H[M&GI8Z-34dY-a4TQ$k[de"f1Yaj4l*id8j2l*piKK0&HSHVB*LNj9I)JS[h!a
- SfipaR+*q!9Z-1e&Qm$0C,P-Q@BN"I#[K"XpJmmI@TaRj[JKHQFZpcZZQA-GcZT`
- %mdY1X4djhhc`lH1dVBf#GSZ"rEQ5mVN*c0#dCjc)i99L1IjP$Z[bklhPFK,FQH#
- 038cFZ3GN,JH@9k9B8aS@dG8lY"jJKX5&C`JiAmMfkHMcTACFEFPGqkeFXcfZ1)N
- `i`TeQdE[P+4iQ4(p%k$q$pLCeP@B$2j*d65!Hj[*lNLmjS-4P,P"AFaYb!6ci83
- 5aCAYQ!MIU6c#SY-4%T8)ij!!N`[FVHM"3J2(2"D$Sph)-6-6ah-J0JZF1RkPDdY
- -#6N55`*A#cSd2)8Lc'LlXEM)QMZqD'cqZ2'PN!#+6aX0,MM6XfB)k+Nmb04l,A'
- Ar*Fp*VE,TCrLQUJ(memF[e,MEX&,YJeeSqeAEl5C#qPZ2Zr'FNkIJ#Z@6r0SG%E
- UMV'E9&E[!5YSP0QNHeHkJ@rP3-fN'iMIT(ZAc'm#aJB5H`HQ$L9'lZ@@'dGlfhH
- $S`)fNVER[J0C6HAem0N@d)5XMaI(VahiG9f`B4+[G2GaVLq$NDKSA63fTHT#&@'
- '#DFLBh,ESIkPqef&6B%PAm9[!,I54@X[4Zq9S[HkrEh@TUP61hk6-Y(0,FrCkX)
- P3"hZ!QXM*'4TrJaQ`X!Qap(DHB5[mJJAG%9)9#03E05p$,J!iKS+Zh[F2Lk'cV3
- L3NJX!FYMZPa6(,8BSkhYqcYVL4ULEmMf+Fl&M8f5a+VPb"X,X@'$%lN+9j`qI)Q
- "YB!B0AK1f2dCKL9Fc$8a3'-%qDXD(1c)$CLjF4Kk*i6Y+Y"#h&1)KBi'Z`KBdj+
- )"iLQ$CMKVXF'pT5SP9Q(cjID6r*)P(&h5cjRQX)m)5X*%b5@+m5lrCYDmc6KU4V
- [i2jcIpLJ,h@eLAF*&Fp4GR@Mr@&Pjf28-RkQXV16X%0R6VaS!pX-G8SX6JAQdZZ
- S2cUAN!"RmCebk-ZGA#$CkHVFD9K%RB"0k1L%GM&8Ea1*BU6ZSDP(Z9$hC*8N0SN
- Pk8B`IL@j`2b[Se)1&0NJ2&ceJ)Icb)0lG#BB,caL-G4FZ0JG$S0UKmbfZm,p-"$
- YUeh4[NSc91aE,PDk`F3SG$FdF(d@hF5$1G(,e3YdYpXPG"q3!"H)EZa1,,&q`24
- Vdj3mmT!!%jKEL!9,0N#khmBZaG[r9iYVS*LVZBi@`5NqVeH'`5U`#j)q4-BNrE4
- (pp8mc,[HDmTQ8'c83Jcp9Yr["Aj0NpLH[@c9qM(DD4,,"[S&E0XcRE@ea$+aL1-
- 1A@#1bXL#4LaI#[CEfN1aJkC5h-@h*49!!iBK'P#DlE6[)LZ2ZTQ"H8cG3q*dE8U
- kAQ8$Bp'5"m(I0%SF[blYca3rb8hE$%@29k2h4N-IZAKR'H[5k28XaEhS2c+m5-k
- `#Ym'QC@XKRV4BLDl0bfGXkbP'X8mSl'JNAc#HBRfa#UQ5l`#XHDZ5l-Y!*+6,Fp
- YU1D"TT!!,S@P+@bA*m9BF)iB'["eU*fHqjPC$EjdUT'ReILU)EH28B1AUDr38i4
- rXp!j[N"*aHl,'QmmA)P-+@k5k9d$6,F)fLmmNj1!4[a9kiMCB$IfL,NNNc#F+aD
- ,a5%,c4MEPP-XqqIb0cB%RfZDkKXZjU,Rj[+UQci3j6Jh-CGA(e1VD-LHI([eR[b
- #9Y*fd2fQJK-fl5QJL0KBj)*l(IP'2@LU6)`SQ-kZ*VZrQ-qT8Na`9[(N#5Ke'af
- U'LciLTiT%Q'TX,%@ZJ`hY$2)1[f!EG#C,@LiT,XDAV(0"ekIYUcA5+3+$PSZ[QP
- *d8#0',mKHE2)kYFmfZVFDdR94Br`X'3q%mjN28G)E!!Xq5`6PX#)kD"qQX(YCm'
- HcLeMB5%9*[RXCl#NS4-K2*!!SiGJ,d%P3VKDjek0i(eJ,kVd-*RebXL*N!$caDh
- `5LEN$'D$LFQ,XbU'B%,94r$,`cFAh`,C4fjE%J,$'fefp&H'4d)r[I&IqNQkTlH
- Vh++X&m5R[j!!K(BZi5)l!macURk&UE*F2J-+J9'KFDKc#&e6`&*3`p5#4YKTlcQ
- 6pB)Pc#dTX'6aD1I!3[SlmTN*PL,dP)FPbC@'2BpEcSBPYHpd&LF-afZ%-!+[i8+
- Qq80fYA8r+q8CmC6DNQBq`'E#jhDrZ$D0kqmSKYk0mIK1`VHFGf-1,$Ai9R0r,b`
- 6m#h&Y`cI#Zie$CC+16krmRQ1`e#($(J'&FBh&KYS-ljpPPe+YKJ2SirZFK!jf(%
- Imbh,H[Bm[M[aI4cI(FMU-G6HbcEKj@1Ed`GMXmmRLD,5J53P&$jqq,!idBKA#&i
- d%GeGAQR`BN'LPKFU-b`d2ALcQ3kP"1J*ci@j8)8M%b)[0#(bS+#$Ea8P!kqrBcj
- 3"q"k52DBZk`e6P)I&0PNUXYUbUTPrVKhJ%jRF0QLZ'!)BN1deB#aEJ%2D5e`f"Q
- b+cACZ%-aK!(b&X8lLpUR!TA3GA12TfGS[eT0pSPDe3iNlajqAl@*Ddi`"0aQ-GG
- BDNF%0ed2FC6fSGU1LbQhf"dhqeQBZpATh6XV8PQTir(1*6k!J#19)ZKm#*Pj2jE
- M@CkLZdUTk'LmD4k$a5abUq2f+$GDa1NH8dhQN6fR1cLfmE+-H[ChL,fh+3rDfUB
- FqU*pECSKpjI(Uh[LeH29Mp4&jPdGlG"F$cbDd)Z%R5UV+((hGA&FCYJmq@+Q8l&
- @HY(0L#C-@ThYCaL[M1G#@X@5@[U'f+k8V%@j'J!R(h45pIH"9AIJqcaC[S*VY"B
- 2*09DXdAGC%AdSL&URDSdEA'ABM3SbHY&k41fIX8$dXq,lp[9U3*"@kCcBCE6$e"
- I+rleD'9-E3$#XP4+b$rhP&QIjHVG2l5@1(h[G8'Jj-3)BLY6ZP9Dq*C4N61NM5k
- e$XKj*$CRX4`GfBr@E+G*833K2'jKrIB@pMbb5&&jP1aU9C69PB@U4@caZT2!""6
- T+9aJV!lR5ZUhI+9fFm%ck8,B#`aaXm3%U!)`#%Q@fiC8BVS!ET0dN9a26qZTQc6
- USBC1r3)fQiZP6Q#1`Q,eTBlY!Z)1&e9dG&Vr&-"0MPP0C&BXCjNimlpV)Y$+6Hb
- XQ4[5bITG&ALfPMZS`(1lh[d29UdReGK0rB#FA-4lC3[eAEdZ-e[l[NQE#lb`L(K
- K'39F6rFcjE2S%X4NEmd`859@-IQ55&!J3BjB3C6(P@UB4VX[1),b@%J,"P6@21B
- cdZi*65!lX2R4kd*&!FXq+&A!CP!&P+3K%V[rT,8*Z2(3ZhjPFS'b9l+#P)b4BRH
- 1GRS)NaImDEc1!ED+QK",cV0+rmYX+XS@iK*hNGcJD2recQE1GT,G@X`PTK),cda
- Xd%hhEDTqCCT(9i+AL3Na"RF4ei)jrB#U8+%U$eI9`V%mrE3b-jk)YbJkq)3H$FL
- E`P"epra6edJhU#YZ[fc0AS*lAGQG3jeqh[K59&-aRM&(e@)`LbR9QU+0!A8'RLd
- jJFQ0H)@kic$**P%(%Kl+&ead#E)k0'p*UjjB3R)8i")M4maZf-)d3$%`"4KcXhY
- !80he0G"-Z5,-$iIl2ecQ!-[&C)0U$+k"qaLKmjK)AQK)T#YS8J8NYd!lj#Y@,EU
- BEKX+$E,NBZ,cV"r!SccF)F"i1XGCjrUPY@RB$C8AY(M1[-!Qbh+9A+U!+%2r8j`
- l98Ap`hDkND$Fq*D(jhYm-eLrLI&lTVM-!3($jE,B91MIe#*-Q5Yd*["kb"d'3b8
- d5%%K4!hB-B(+KLp6XIAEk4jYPSrQ2BQ+XG%,3X,02RJXU8#ZCjBGV*`HGEqQ[+3
- D3)H4XElCqUSG(-HYANAJ5fpbP0Yb"Vf&1@'0K@T(-1fDHDr'BMFEc-5m9m3eG(l
- *bi8%dR@aYD1SR040Q)pZ`PB)3#Ui8q)Fk1%Dh%TiFA@bc[)!9Dr3+(GaBcbZZpL
- b*$DTP&q0Hj1JlkV'DPX2P9FMSEN#XHM5)SCZ[86SPYaki6kJe9Q#+6,9ij49rdS
- Y$,N@Xm!K1c)C1G8#ZH&pIe65CFR!qm,4VN-@U,R-i$H#kbY`hV[F1EkU0Xa@L'N
- NNTHK4$1FLdX3,c#U@a`Z-9I'VE1T"rdZ1pQJBF4$YDf&*'DU&pA0UPPL)V%@i2S
- Cpfa8fAS$e)"`2&b$TU6BU1Ded4I$jh6-)Yb#aT%b9*N3QkZJ3,+eETbADVbSiVX
- +ZF6F*%JDeMh(R26SZ0`Qbi1%bD0k2Y4T!eJ2aq&UML3dCq!#`qQfG,RE#VZIlV@
- AP9lMDYb'+e"JEM0m&8kcYi*+`YX,lS6PEJ$)!peM"#%TZa-h'12$&F'Y@'Hk6Th
- 4G-G%pFR#643Q&ekBCHLQ"YceE,d(A6%2%B!lYI@84966aE5kcM9DQZRbVarcV%r
- ZR$NFL@F1hiCfBT1K#jH[&aH"mhfUEbhPV*(%6A*9MhCB+!YUfhbSD%#d*K@,eZ4
- L4f3bleHU3E6,Z3CHhYm[LpBRfk"!E)TBR'K0T-UUf92Emb,%YZakKURjFb'%m*U
- jmf9YJ,E#@KePV,ZdX2YAH6IXrTXIUqpdLcEe&TB9FP,haQB)9AL&N!#8QjcVd-[
- eMFlJ3X1TD9BMZAGecSAE+5r'+TE98AT+%UKjCiY+UVfJ0K1e*mb`fT!!!TB-&bk
- [NV"2AYmb$0VBJ+CL8lJ!,2"Fbkh$%#Y2VJBQlEI8qpX[J&q"fR5@,h`eUbq4+8[
- QCdX"CP5-MA-b&+U&ZZa&RRjfdQ@@dRF,U5FbE@-CFa$QRQ)BbLi&(N1h&H3hjR3
- -ZXY)X5-A[MlGhQiA3DpF$adUdQ-EhFikm`4[eEAe6ZAD'(b*"EI1[kNCmR4rCd(
- (lalcIHDa8Xf66Fe0&XFY0dM25$rkp*dpNRhARX@5p5r,*+IerNphI2T5`f1r2p,
- `dcQI[Qkjlk2Yaerpk%$$cqIi,9FhM$XbTqBHFr5bAeJ-baplmqEEEeUp8UTmlXj
- &kk82Ih[mRBqD9MCC-KTQ02bkSA+ap'P$aU0,c"%0'HB,(ebaF)RdNpbI0*QET*m
- X[['"TPrIX'MKM3ZPJL92V0f`4VTPS96@p%[T*@RH,6G,[lceaQ@5G-ZLKIFXhEM
- ckCe5[V@K)I%[IpQ(rc@rDCLr2(I8R-f"Rrj+H[d[cchh&r-lYdY((TA+(PflG2k
- 0[j!!kKSfVC2',PbipZL4TQAh,&fqh$brkICl(QfkkFElMfrj@#TY@Rll28dhhL[
- pH0dkbElmPdf@[Zr0q8R$%fp,l3ehc&mZl@`B,KhpU#([ShXrPaBe,2N9j,-h($N
- JhG``5kVm3,VqMXp@Q!GpYP,Dd$"*QRPIbmh5+jpqqUPNN5EG,0h6*"AH,*QA,Vr
- R3HQb`iZN#9,a`XHN#FYZ@!l[Il9d`c)dj)AQ[Y)@bmb&jYTAAheTqhET#(p1GVr
- ffV1[[MVZlDB&eZ,lVHqmHrqljVfr0(IEmS6jXJm2jrAEZcGh[bAV-FRjZ@6rf0,
- IFZ"YbA2J$ZQRjS9QYPqUZI&cmrRQ63[0`k5VTFP)Ze`U1,S*bAjZcIbPdSZ@L&[
- 0GHCpPYZX04rrqZ!lGhqm8ETbYA5(HBad4m1[c,U'dHZNRc9iTDAQFDX@hAl(`pB
- -kH'&dR&Tfe00#md@XeeU[pRF@bTD*5fkmBDlcH0HP9b@bb`ZU96kjB05NC5rb2+
- D0(QY9(161EEK#DN8)Z9R0$aPRYU`H)IdYV48qV'dc$*ecZ''#G*p$@AQRjPY$3Y
- ZP*Bm[($q(G,96bjEIBp8Flq80hr*`PrFIZ[b"fk(R2R,PLq8lTFDI`pdiBES5EJ
- 4JFTIf"E6V190BR*H29Ij+qM0CLj-($F@T1@J-(X)ISAC(XaSl'(hQV,e-BU%Deq
- 1P5h(E@@DFNf,Qe0FXQN[JqZ+)%6T(P1fVYZTQ-BH+&Z!qMQ*J9fbc&9E5hchd##
- 'r*Z$kl(rN@D"ZdcCaQJj0ZQb8G([ih%KEVlRX,rEHVXT`I"`SEA%($cU5T*Pc%1
- aeNMFiahm4T!!I'eq+&Uki@&L3%Fd8M$h!)qa"RG,b%*&'#Q,1dF%PRNYXUiTMQH
- $IF'QKi0h3[0%Q9a&D2hab*8Upl(P-Yq#[PlIF2P9"HE#h2&j4EP&9P8IcZV25h(
- Tf"qM1K`$Q4b,F)QjZ&L*3,9)+VC4Ckd10Z+#fI02-6maBCbX#J"AbpJ8HrYEQ1$
- jSVN6[8FA'ZfQl*kp`hd,ACa3m02Ekqce!1iRS3biqlJ&&a*6&G[-4[*kYT@d2!$
- IA[mNm03k!c4bKYe((,S5U#iQMiA4T#-iB)6AI[L@ZH)8q`4hj)aYb+h+[S4LN4F
- 31-+L20JaIdHZ`lP6ZBDbJ%XcD3Nm%q'Tp)GUciB"LYq$Trdi1q0!m4,l%LAM3QJ
- ET#a$P#raM8T%6rqI[8b-1$Nfe+F8YceH[#Hjp$cqJh*G&e"G5aA2rEbZhZ6ZYrr
- "-B2mkV-Xr9*XDJp%Bl'r"lR8NVdKQU,Q'RlfXL2EdXqKXI4,aR@0LT[#ie*di1P
- i&B*$Jh+Jk&RFef1*3Iq26!(,!Y!i6cUr@8LD+FYDTek9(Ep[0T!!4R-,4C!!hIX
- L92F"C(8DVUDK39LdLiDfaB'jJUd3R"rD&LpE)9Prk!iME+4lUm%$$k#`YXGF0BE
- 2"1)XU$d,D3XDS5e`Ud1[@("ETU1D-6bK'',C(Bm)PBdafS+j(icE)F8p-h'*)c,
- Z$BFQlJeEM)X&5bepa-Y+QU#'1*!!50,c'Fhi8R'0Va`AakM`e0Vb-Mq`6Z$eSZY
- !kEEc346j&E@ekGQTq&(I%`mrhM6rKX[c,f$pr%ImmM-!4KGF3EpG5[F8kRlRiPP
- MIA9fdQIGkU`)`Ej%r[AEUfk4mXfpB)Xc0acpK0i25XG`-fSNeN90)X!#,q1#9R8
- 4Z`&hdFZQKk#@-"fm99PpBacp-F3Bj[G[*IAb8`kqFU6&CkpZdmY8fr8"a`#FE"a
- @2*X*I#0)DLBL!2bCiYUM5ZDi65C3q85pXpijhZPeemPb(N"B8&AG&Zf1aD$md`H
- #1&+R6$TE[#!$pb'cEN!fqr%P`Ei&)XC$dAT3G+24m-E3"0(#!m``'M)AF8bQUS2
- F[85J)$$f,9j),`BUCTrFq*8X85q9j@%P5cm*DpSGM9cc8'-kX25-3-j'*&jqTXF
- V`+)["$3*+%rUY062`RQfe(IQ#CVhF,B-CrU*kKdJB*!!+PUV5E+M6p+hN!!Bb-1
- E8E[k3jXJ*V*qhdE8%L+1d80Sq""1Jc`3E1)&c%T5+rcS*#BmZeR1p%SRZPNIme#
- r%VKfp'4XQrPJQk(YZ5b6L3jMbfAV4&LMKeMkU#Mdf$q1Y&#(&&ZZGc-8e4r0Y2F
- !TUffdb0FLF-15*rDQN*Rj%Vmk642I@dPY!9IjD["q0(ej2RMa-Djb@1JZ'rjUPk
- TJrPj#KfJJ9B%5r*e!00'bV3AFD#CYR1!k)H'c%i2PJ%4Y80HZC9(&iNq34lZije
- 4@M3E%'GTKq5!Ce[YCb,IU84qiZZ+lD5+,HfU@&HP%Jmdqj'UEh10l24J%4+4,S2
- FLEi-8rTR39GMEBH-VYJ"daPXm`Cd9(2(3GHcV9NTE,1Mil#224l,k6K$r#MIQ'b
- &[(p%MT*k1RjI39f1RJ*'BY-d`$@Q1VL5Nc(hY0q#qF!qDaUY(LMMb!fLL1P%(T5
- @jlJJ2CSNCC*p&1b1V%cML#Um-A8`RAmKaJi!c-1&5c"K$,D$BX)q"&N8be5PViB
- LTT!!k%`Lc9BL(Prpp*3-5Z-*q,NS!b,ZlBYD5Ti3IR`1&cXmbJH*),Ep'NqrcZL
- 4c%KDClilNhbp+8a#ELb&mP@&&%@N8"k0R%URIcKM`$Pj%f[IiiMTR%FGZj50JkI
- dc9c3KUJK!B`$@E(T)R6A0m2#3Q@lMb,L1**k4ZXpk&!KqBQNU@eD8$0c`pab8*K
- Kaa[R*X%!m-T&C#&!FaqhJG4X6T'h*qVe$[IBM4eP&RE1BVjclJM*LJEKj1lKT4!
- f`,4Z6HmSd"p6R)2'5AQGfqNP0RFElD0cLL!m"Q6mk1,A3DcMJp6!5NcE*deDL#-
- )3$$"52MQ`10K)Y'"%%5+[*F6#Ga$(Q42AmE*6$HHYPqYfJ22iX"ZNMX0QC!!*-K
- 84a*j+VNXHhJZ04dHNKdf&-3Mk3iCq*EJ#e&$ELkkKk)NiB!1pT%KqjhFcP4!E0p
- #GKF*`"Cl'lI[ihA0J45)&(F&9Gf9MeFHC3LI+f$I"(p$f)4B6i$NjU!Drp4V1#A
- T!k23elZ(Urd+Mc[4ACI*r8466bcPk'SQ0B83KZmdir"[Z"Y5(El6c)qi@E3$#@V
- JZM$4,i1B*,5'crL5M-KTTCV6$hk[@(#FVRZI23i5,Ci5DJ1D2cVJ)D)rmJeVE0J
- l&2Qq6B,2lhH80p(@0lfc[`#l[%fN6q4[2)2Se"FR38h[I(iUJVEUqB%*IVXLBmb
- ZS+ilpS2h+SrFZ,HibQDpG3rar#S*p5pQ+(,*9HfZ6GbH([+($()3SC*eqr'GBA+
- p@h*p@++eANPp`NeE0+%2[22rficjaB#6h-aM81b2DeJa5H%ri"VJVfLc%K'+)$f
- 3!&peJ2a`!RNCX"!kS`)H3,la6iXi3U0Sfb52"A8qX$EKqpKCG(j[HB8K`jKa(*h
- rfQ*dU$l[hJ5#(LMCUE0iI1A63q54k((J,eP!6`"*TSY#b9aESqXBaGZ!HPm+hIH
- ,VRE@J,K@B8P%reIe80Y'Pa&cT&E&VG#p3&jfEa6aRA+`l3R#UHKN[6!lkL6MdpM
- 6bQ2GL92G+KR2Z3QJdF`VFk%#APH")bp9cNlT0&,F(ImR&2q,Ca9Ej"MQ'5DUXS0
- AKBralDVX3&9fm0JI9)AL3Q)JEc3PF4b65JF1&@$p16+&lGD5+A3$+PGYk549SZL
- )[Eep!dH`+(+)4`kbIXA+ZHG0j4jR@BdDPqS*0#4!lbdkmYmiXpL#DdhF'cH@c2*
- LTl2c1kfkl5AQi[8!,RDI6XlSeR$%bE8m*%8X*Q4aFR8U6UJb28QbK(R-Jc,E"XK
- 463hE`a$R14DeGEAaq3Eb5,SDRcA,Vj!!*2k(2)T5K$C3jl"`[9['RXQ%J'F-#p$
- -%L@URB8AajDCeI[ibqXRDHAMF%c,P0$qV80caDMhQY#hCC!!f'pJ6kATjX9dJkM
- 0bTQL-Je2Sd0EmNbR,F,+Vacj85aM6eFX2iq9#Ic#XcEKRb)q$$bMc"rjc(1@'Re
- 2rRi%Y2-3[IBM(1m#`eV-YR9CGhGBfpJ1,S)PA2hdL0N!JB-A!RFdF"$ZfQCC,j!
- !B0d%6S54#H+'R8#PTL8Am&2$m%@J'%@ml)ZUflDa&$TBkhT$&Yi1b5DB@(kX-M+
- a-%rqJ2@R#*hl6$T#qJ31AepG0Th1e4H9KBm6qGJ(TpV5IHLcX#FD&Ah+KSV@(q,
- f'P5l2&a")$r2Z,QJI,'$f,N#`S'pL6C)rd'YMCl$+YP1m$a%qN&UhNMp(+jq60f
- CEUTaPR[+UP!1238dN5I6%0FS8HhHSZcVpr(qS6h'VJY[YXp3lF+AE@mGDK@MhQr
- L0DPQEDL)Kqd%eN)9$LN9rQ23+q#i3AI(1MH1S4H8PBFad!cH'kZBBrEe![UM4HN
- ,YlYL4S*M-[8p@k[*VcAbZHIUf2#KmB`XiCTicICR(cf#$)XT$RbH-Kq"V1YL2GY
- 1mGMM0%42ebMc3pkYHRBp)p&FM@[PEQaD!MPKN!"AJr`RJ!,)dfDPAU1mkk2*5N+
- QQrDUPXCi03*e"0@&1L"Vep"GQ+`kf[D5A%FXq9,@ZRXTFmlhGI5Q8"XX"(N+'11
- @Z5T#qqbS,+)N+F!q#e3pD-ZVMM6NK5CcKLP2RC3jQ2LJe"-rN!!-'N*k(labjCR
- @880(pj!!HcG5Q9mT"GA[pX21e5A[p$6"!U!U-SC$HKELG#6k3@1+ZEXpFc$,hQ,
- ekN`3Z&LNc@)mUp-S+ikcqH+a,1R5A*D#5K,&8!!NeI"lH`mRT&V&BpbI"9Y$,*q
- B!6AI&XJCVVdk#h4Bfk`Hq$T%+Ui+,Sri$i3GlM4aZV!$@%1f1bPT,!JU5,4c#Z4
- &R5P`DVP%&YYSAd)S,$TiNRF2cleHRX!L2HdQh!eJr#TkG"*cZT[h'Yd6I,,'(D*
- 6`Ge##5%(11IeSq1#N!#N3K5VZY0H8JAflFj1SNlc+jhfT#e2%I'q$GK%+jG!jc9
- &`0j'ZfGR6b!U3H`0@60B9J3UAUG-SQpHK'N[NfJE0TUk*,+FX`$E$Yk6MqKlrUc
- BP%Zf+8Id4Q$"Yf%DjDLachP-hc1H4lT6hBEXVDM'UXc*%-5e9(LAEm5HXe3h`LT
- XNf[4H9Yfa*VFQE,dPiT0eZS6b1db2P'0SF2d,&hJ8fbCAN1NIP[5E0L4)#CV#Hr
- $,(ILQ8L&`r5Dp&5P(hdd!k`)iI(ERdNTi&RH`qFI0J"q,b14JL"e)P3T5jj4Efe
- ,+F!KImkjdp$@)$VlcVhR9V*cQ(JZE4QRRMXlf-S5E82DXMKYLGm##hYQiei&j"q
- lGe$[Ydr0"$B'*!R#3eiEH)TS!p-1""*kqM#"YYX8L6R"pbAV-!qZ)Q4&8"8q[CC
- l)$8(21MhP[!8821@[)MN-kjcfVkPSm0l[%&Z`p-fQpHMk'`pZY4k8$A'Tl+4&2A
- )ICG3AA%*`RXNha(4&'["cBKe&YjAQmZqV8dP*rbdDh1N8UN0#%l-6H$mcPT8&k%
- 5CE`5'AqVa'pj1LMaeG@8A3RH%#1cNVcb+D2fGRN'GF4J(XCK(Y*Hq-eGQ&l@e+S
- rB0+&YP@DhNYpI&[YHC-NKk*cALlFI260dG9Y@i0(3DL9($b'dp1AeqTX%MSIH$j
- U#3SrA8[JEJH#ah'Nj[2VeUDTR3k`k!VSl$EP)ZiHU9iceB-*692,[0YTpGpf'JR
- "pRCffZ&fZG2H[%rTY$4dfV616PY"1e!3!R#`GiQXq2&%iVRpk,fG(AFMUJ)-`DB
- %3'G1S!0GZbDc[Uh*"%iX5M8CTG4N59)"ap%+-$&IiY8TiY9*84!0b,[4R8-%4P)
- "fTAS)0RUHYd9MC6PNQpcKc4S8*EDrI$')ENI$Yr@KD'i`aN$Gr2MXLd(lb!ZhBV
- `6X%Ej"1)[SNf5UFLk1(k1M5ae49[TP"A02,0c'MkYLT%LHIR93NV93&*06!mJ&Q
- -%ZD1U'iEbG,kHU&%+YbAEal$qHB"e"m5#+4RhMLTp)cXY((KVB,kQ3Ri)0RSF0I
- FT+QcdXH9SjV)Lj!!89APSSm&E5-F,6q-ITNl2BkhAA4KNp6C6iIZP2[TMAaPbmJ
- a@1mEi)V(P)(B3EqZUbU3!$#lJU''iahpiP,Cm),jZ#`CMfZrmF!RX-Z+,kC*LXH
- #PpZAc620iAXqFMbd(V9rJ@F,mA6)0T92-mSc2N`@KMaaM&TEb@2RK@)hmpF@hM-
- Jde4a[9he'5H#@!EShfGC0&iARF%!J3r`A8,Q*XVPj`[m9!0FkLJF#Efe8&D#CrB
- @cDH9i4R*[@AFHfBcDDK!T3*m#ceGlUUIJbL,F,bI(mk5ZdUQ9%)B*q&S8Pf+XiQ
- rRP5UQmkM4@ZEMrl09G"0))m+ic3V3I@P(!iqV%`iXkEcTiBPJ"9Ua4kT-k0dJk5
- fPi$6-6jRa@I8,V0k[`9i1lj2SCZI`2XaI,I$pLK1jT[H[DS!1a2I-qcP4qBN'J,
- 8lAcr&#m-jKAE29N9JRda#R!&9fYYbX'Yl4I1QV&L(mfjENM682R[N@26eVDX8KB
- -#2J8R3M+*$HR3mVd**j'VIHH3UdIAH&kMH)`eZJfFE&r'iJLCF'X$Kb94+$MP$J
- 99k,hU+)$V0U-34ip*edDae53!2qRB-*jTdlU%2Jl!aF!fIL@iMp$ZIm+bEF(aNP
- qACBAmZ+TSl`)T4)['k@LL[1"GkL`E9&K8HQir+[8#['9!)3Pecpc)dRJNcZ'M!F
- K(U,cQ4Y9`UP0-U@`N!!QLMVZL-"(L&I13)pYqll+)15#L19@S$Pd%aH#)"@m#Y'
- C(p52CjPiFI4a0(H8&'#R(MDC$p8LGaT,9ZV"QeDd(QTEiBaqZJIe'-NY,b*LMM)
- TJG$mY*Pk4C2hE#KaJ[c'bADJElB(VcrG08lFplUQDplhAC1Kp))2'S@i&lK@qCc
- qXS6hNEj8050%HJMAdG%HfRmih%0IN!!&"jYPIDqU-dj9pEDZZ&SUHFp*jHV$Umc
- &ENJl-@HQULGji@kPjq3&G$hbR*rIYhq48#0LCQSZVjRPVkXP&R$Tk-N(Sm9""@e
- [i&f%p`Yijq,p(0lTH$p$d6FL1KdSIl+iZ'-2U(aI4j6K2U*"@`9CS$@,(AT$EbD
- kA2E&`'C"#E#lpI'Yj3FJ8f%S5h2&fr1!9mIjk,ClbGY,U'jV'l%0M%HXS4fN"@&
- h[i*RRM[*LBH(%[R!Fa+UhH2VLEM&P&m$D)4U8lTb[)FbNkYaR4RGb)IRqBAaEqP
- &4FikU)jQe+[A&p)AYjI@P(PV2HL'#i[VI,Q&*E)+#GPcd'[)`TGMj&HK21Q0Nc6
- MUiX+ffl),E6R&KAQI5@$!ThYIZE'C'abh0Q2LGTRET4hIiPmLa,j`N,L"C&C*84
- V3,@QUlGrZ,4K-RCr+j!!C$r`,!rIrfr(lVTqq-2-`'q1h+"!Ua6(JcDCk*45C5*
- P*Y$!I1fH60H"$IfaD9CD9Y$V9(LkG%TG3)GG1`BB(&qST4)0djKhV`'0P2)`XN"
- ml$9-qf8lLq4EIJKdP#"GKV4kMYqpQkihK2J0[38"+5KVp,,&6cRRT!JkHZ1@fNe
- [A-"lF&p[dRiQ0C'AE-,)-k$LI9q@CFe8q+V,UVbj2LrdU5bV,A2,6&!AhQ(ZrBI
- lc1mH1rKU`de5V[4Vmp`[[[K,`e0Ir1@,KNPr"N16@r*Z[fp08e16p2Z'qG,dKVY
- ZPUk$mG1IlT(F0mprmZEjdLIl$dV,c$rE#SkKR9+*9!"QT(T3!-hiP93QrIcGPk@
- R2j!!r*ER6dL@*j!!Ee,Z64r01I+Tq3,TGZRCh!&5J9@bkZ"hNVQRHIkF2dPAQ52
- IDjLceIcim4A591R+h'YcHjK(IAVEck@m6k@(2[f)L#L+cp1hXMki2Gi"!4V2RjN
- C`#K#Z)N1BU0Jm3#&SRSKRGL+(B5&4bk0Kdpe`E6`pA6L*L,$KY`34,9me%9eL,a
- Ndc6Z9$!5%Gj"'p2-ZKS`m8kZ(HHL3c#qL5#N1ce,TIm#)K9+XH&ZqUPN[@%k&"F
- 9ZeL%$T[r(&#6R1bQk8clp08qZMj0S4[6emS,TQ[ic@VU1[1('XM40'@6`@pL(eR
- 1%D2Y6'8*L3c+KqMNDTCXc+fq&r6ipjX'-63N4"(G4cHklQRFGV9b)@`)UlJpc&r
- MF-dlR14"a"PYdeN5CRX(UK0`4k0LTi#Ja@$lbBlh&RL!%Va"McKCX'q5lD!IDRU
- h-L4@2Y8`A5%029-Q$IA[+Lf5ICU,FrSSGp%'d4#b*,Z55h+"M-QGE(Vk))@iNq9
- Dbe4&(S46'cPpj#JZiN8)J5VQXda#*A!T$9cGcBBUp8Uh,j'[eeqlAUf!1`@id8J
- HLbR"iEZkdjFb`89d+ZTmQ5X4fAK!R!iIZF*rE5k2-mQq*-A',j[h)e2N@aqRj,Q
- f+mpmH#0q2Er`*@q*MXLQKp@cNVQ,*"h3*1Ka'9*!'D5mJ-Z&qU%lplY&q+C-VEK
- +URE!lUmfZJ[3Zp5r*)%ri%LNL#$T!Cm"UTHJf#TJLe0X*E$j&&XqVl$B`[`Q!6C
- N-"efc#Z92Hj`3[dJ-iKRU6p*pU2k'`Fk2C1HlI$%TQaj"UlTm0c@k6RNPJl2Hd+
- eAfeISYK!J&@c"*L8%P@5m*SFMqqFLD"(iU9JbNfhSfkd`3kp@P2J+1lb@-f#QS)
- ZMaT03@G@U,fAdG9V!16,[EQBm`88kY9i"ec*M[jUlJh$06'XJ8ra2,a1F5H"jZL
- EcS#M2lhViVJRNre40&`0)NEpZmLL((0cV6)raSQfP5q,HR5&15[G+9Q-[)Tc(pp
- DA15C&*kKfH0h2Sqll@R+G!'hJiiYmm@+1kr))hGe-F@XMHh)dT`lZ6C8D5A9"r2
- NC(FDYJ5b[!STS63e[+!FASmYK5GUJaiHH%Y(`'q5D#eTHR)VYYNmB2`ZL+,*BpH
- !3*(QF$b23$)44U,berKLRhb1j+TJ8l'c4kFBAebM8MC#kQLV)MYf[hV2L9dZU,'
- b)((HZ(1K%`J860ccRVKX4P)32,)e(9CVbd1HS0GklBE`(NH4H+rDJ!eL[laAm95
- (04)PMNHjV5X+54Z`Sf"1&+LE050Y-maAPP4jAI,PZ-&ZrMdK(98TZQLhRLjNTRb
- JLaDMh#R!P9iI9,$GjS!8`fGYpSHffi`rXr9f(9'Yj8D+!(,-#q8V6U$[0S,#8Si
- C3f%*K3h!0jJ1$[6l)PPG`9%X5N1NENEZUUY5G9HlL@RN0,@5`DIT%X1G#mp2ij+
- 3!,DBR01q%0K'2@YkPFNb%+JRBMi3%@i-9(f5k3TY9$JA5cV(9qZF(J"JPd1q4pd
- 8`VmJfZ0b(jIXcVHCEfm-SD+i+ap6rHjY*rU2VRlhMXmh%PfAZ`#c+Gdp!+p%E+r
- 2mahfb5[T0BGXaLVX+`F`K9bDFCM@VjNKJ@(+SFmhN3b'5ZrRQq3p%Z+RdNm-X+5
- G#&9)6BcQ%rh$A@lj!V(UB@!RHAX6*J1%&liG82Eb!jm(1Z8-[KhSQK'jU-8#NP-
- 8rfE`C%+U*JrI#`MYkAS6)MK)8#rSf6T%i-V6B9fL+F!AN!#*`5iqKRZP2)fNCZ2
- 2iP%l56)LmXTaLB4bm-hQ-0aX)K*&bGXFefKI@Pcde-[1[5,%i-HrZ3)%F%#X6"[
- 9U#1-K@c$C4!ba[AKD(610V+"QQid[9RN54CfXRZrV9r'[pB[0cQF-qU9iElk(c@
- STCXif(`Ni,1)GrQ&ET!!Qc1255UqkBjq3'DQ1@*P54+eN!$UJ$IYCF#k01*pQem
- Q5,ZmYRkU2%iXrM'e4d#!!LB&mCJ-Ge[!fe,,@8Y)0LhQ"Xd3iePZ1ibq,3IZ8iS
- *)Z)R)-I$RRG2S%kJ6d@%#BL3!--Md%8B)8T1"+N6C,)lNe!a"$'9ZE*"6JPCUE2
- H)A3`J,lEMHa+h2hj&DFC@r8*pBc"(Zld6HBb0B`lE+NDL)8`9[&CRbj2pqM%4jc
- @6Jq1A)Zi8eeAdakJST+N2AXA3!bDlkB(4me$M5TF5Ec+&4#*i%3$pZE%dJMqcFV
- dVm1Ue0qGk-`XGc)kdFZPl0Ejrp*Q*GBN%L85cDHf!,R[GT-84VX(i&-0(-P'qrS
- a2X,Z-$GfirX-[V[8bY`5USc&l%D9`D9,!0A)a+bS4'AUqCCXX0I!mV1!6iXld(H
- [FGBNi#()+*mN-QLC$%Pd*fT[6pbjhd+d-R3T@"28hQ6[8Yc(pb'2FVc[4Pp13k6
- E1rTj@PFr8lcPA4kViE%!F5p`6HlSj`ZkqTQLdX5b2#KU2ZpR5$AKILjM&h6')pP
- 16M6&8kHkjUSU6eL'Nph40-(41@ASR&RSR&(Z8RK81bUTAqUR+V[NqrfbQVB$kTB
- 'NLi5l45U@*MhbFL113&"G%k%hZkq5ZRZRT2B+Hm,RMbrqYhl))DYQA8(Nj,#d(N
- AT)fr-q5aMA+iLDqX-VNiIKZ2rm"rM`rTlacIVX#$2)1(rSm-G+pa"Jrc$"lj2c2
- 30EJEiVkEhRe#4Qaa'Gl#Q5GQN`AX(R0bKVcUKIpINKfA"XcBP!U48,BeK-iPdI`
- 3*#PHKGNjq!N4+qqZpp"0(0r`i3kbTmeYSJlI#XQbb(%aQmJ[Z&p$THi1AA#caE0
- @NDVf1#5raR)%0b&S10NfMpG@lZjS-[CQpZBhQIAQ`j-Rfm3[*QTYS"H((lMajXN
- LT"1Z-5@iKjr+VE,k29RZlhZjc#SU[&DqfVYaBSQrTUK3*UfpQZi8%(eNZ1I!!c+
- EbaDF(XUZZAeeFeekpPE%E2Z5)X89*%%@p(Hiq#SI@*YBZY[G,HI+PiC#J&ZXdc8
- eI`RLG81!P2I#l-dm1RG'*[A#$b&3m(LANF4X)JXYc)D5Gm3N-8ka$(,PqR-H4'4
- rSPYI8k[NhkF)d-#pcfkH"m[8"MK)JXZY$Y2a40)I99@MXR%QNUc[BlS&c9pfeJ+
- CTLN9rFahP3ME`Ca98G!)-4(9RC@XYmL9*Q,8lMRTfBk)f-EQ,lrYPYE[FR2U#ED
- c1jYV`a1$+lQ!Cd&#((A(h2KpRAMQiL*LhPG66Nq5@#jhITH,a52'SLk%9B"Rcl4
- m2Zh[9!L6q8DQ(&K-,[(KP)KfB#iK5'4"hPNTE0,ELhG!QZPhr"HBf54k"jV2qp(
- `+MB*em`ZSK5ZSHrQNK*EL3mLFaYD`af[14A4bC!!GXJ#XKL6,S3!9qN2G8h&r8i
- #&#"e50F@H1d2L3VlcP"Yf5+e"IFV1$FD)"+KFiZ+&UqPfXTpiL(LFk%F)@phQS2
- ehU[19Fc#Z3@S0Vi3TGapN[2,94+'5M@rA!*fR!UTM!8G9k`2XkIC(RC#k-rH%$5
- 3!*2D+L4qmcG5l9E-1`M#jdc"*8J@b2,)Ba,Mr321YMaJlXS,YhMAU&lQTN8lrL0
- +"K2qAaPJ8bJ(PU1k,`&G9eY"IT!!!!,aVja6[XHZ4-Thm&XLlbi(4qJ5L&A"46G
- jl1A$r8@ZiXqp5K(l)[$'ipePIjMT5p"6k-Ndb"S-q)aU2c%RMp'q$Tk'GKAh0E5
- JTBDQp4#UY`E-LkXlBQha-+hRUqR"3Lq`ib#('@SdB!GV%I(NUDcAZafp@X)X[AE
- efX9+kF@@&YA5rcHZ9bfUdNB[#*+9@TXHN!!6K5Q)ErKLGPqLK,l,ll-&P%9JSNR
- Q#)8A3ML614GFJM4$SrB#bGc-95+$$l@JS2@p*V)93l*5EK9Z[jEV@BS(@QUqNF5
- h[2(8SdPY[-YK+dMXrYjLXZ9!fP41E6b$(!cIRrP%RS$1ThFCpKP)e8D$IFFr'Y(
- "8'cPQ`rqe6!NDC*mE1VlmC!!ka@Y,'mD&!hm8@%f11QE@S((0"ZebJCr%J3Zq(B
- qJiZeIkQ9e!8cEG2h1i%p8`T&@ciZkb!P6ID@K%N3Ji*q6ef4HB2D9ldeEZaCZK4
- %jr#!e+Ym4h+ShKb*I%$)cl@hDJhT,M5*c&R#8fS54"@9G8iQh!a(*P22Q(p-TKi
- q*@NkE!*(i%Z5,GpY`Pe,[,,RF-ILA4#+-T@N,UY*[BE[bR@M%CRPhe2IJ&Rbr$b
- )l3HA+Eld2S3[D1a*K++)+[3fFbk%G&FUq+L2&!$")GQ%1Q2BL,Hc-j6P5Vi6aL[
- E&ZDhc'0A-deRelT6-pZeUV-AZM*2p8)Aq#VHli8Z2ADU'M8LZ&$Vq)d'q'mC8pr
- r)hVYieMTA[jk#Ij$h(5*f-*p(q&H@hiXZHYJ@F@M2XNpVq14F"N'2lT-!RD++"8
- 1eKe#V'1E$Rc0A3Im@M+KH8GlL0YU%E@0@aE$`X+B[+ddUr6X6q*caGN'NMLr*Nh
- m*+rL@`VEJY$q4PC'Z4*-X&60d$UN'6T(pS`)E0A[l4&*i'AUl5C`(%-)E)0Q4Q4
- SZq*Zp3fJQim'l&53!$bFdY&M3&V3'bHj@6FZa6b"GeR#A[NZ4[ACUrce-Rqp`&q
- lqHYTrRU+[jlJVfhmp3LrKjJ"C0X38XJMrMjkZHM#d"$ZjDm$p(+2T"MZ#SSAYii
- miLEcH-4l#e@ae-(aGk)@`b!5rAQbZSQ,eZK'm[1-b(Gj4#rjHAQPiPE6br-%HIL
- j#2Ai*C!!X0ca9BmR3&#jlR%[pbqZC+9LP,bG-+IHM4kq4dIp%*%hZkKA5r3cqm*
- q@9%ljR+rEf$$[P(Y0EUClir`,2*""9BUmhd@0SpC"DeUAN"dZVNribIN#a[[I5b
- HpNB2lVqiXJAKA39Ch,Lb5YiB8-8#$f3aFkAC3qpUf)%U)IM+fQmU@4UI2qQB$a"
- N'md3QFFbI&E*d-kRbYHC6e9(2X6$fjY2rYPmH&SQm-dcZShk5*bT[BFKSpb[Hb#
- @%AT!C35CblcG`'YG#53H-r+KCd%ClTUXM'mXNGV3#bT'!D5XU@c-Z,U[mN0paCP
- %+KEENArGLHPG%G0$1@CMdNe3SpHcET!!JLqj`mBE+qm1i)H@VSR1*(4(2&[N!Y*
- ed%&Fiai9rlN4!PIS)SUZ89,i944f&0j2pX$b$,G!eUhhHH**iJjLZHpH%[ee)Mi
- ME!RBhlc,Z58%#emTHb(QhRXpq1[!HIKr69RL&p*fS(%hBY[N,R&AXNDJ@GJbX0(
- i2*!!j6T6UK(HVL,IkbZjjjh`(1lVKeH'*pErBCZ9r+HC+F)h+F++ErHQ)Za0mcK
- ,6LjH1Cj%rjifkpYm&K36DMEjH(#Ha-cJ8+(1Qi`m#K!RPdFV3V3AN@IJRFT`[&Y
- j[$@KH$@jC0Q'5LpPlEJ0LjqUERcaI,j6Ef(lSYd'#(Km,[I'l9rm5'i*`e*dCZl
- a",L41PAYlcIbVL1qFL-#NL6q2YT1LZD")2eMdCa)#Ib5Jf0#,3&LmYh"4c'pN!$
- &K%JVP0QPiU$$+lqHVYaYL,,1diQpT$0E+*Be`4P63Uc+d&cPk)L4,XIJ(8I(96i
- k4kjC9GF'K#cYZ9cep9afr#YTifRL%ePbD9,R+q44kNc0UP@#YGqZQYiDp#l!HiL
- Kj4LVYBq48J36df)*c(%QQHY!@E18l1-`jrQLc`[Qp$L1B&'R0A0"cNI4!e$Q!QG
- m$H`1#L0J`IBc##PSCTqpkmMY`!Imf,k,h*JpEMlr)eXd9jahD-iq!A,+hFXlFSV
- $aGNM2+Z(-*AE1V,+3&DjlQX)MF&h0Uc*lL4B+%rHEb0j-KV0HFj9,(SV`ZflQqp
- [[EJfmZ"pJqH4(Feek&YX()+FlET"2*haK0`02@!`q+I+!I[k6H9i$P!YJ)%`rY0
- I14HI%9`j*aS%H3p8,U1MF[%Z[9+h'E"k`Eaa5-Cr`,J"1cLF88P)1bPbNdS0XK5
- lSV[Q3)+VQ%HX8[c2FdRN54&UV*BKf`[0"lFAfTX'&H`S"0mT$UZI,H4m")`TC9A
- [+,3rY+-`CS8GIRC@2SL$SUa5PD`53[QIl0V-rIQ@)ZBjMXFX1(f[e,5pN!#X5C9
- U4'#rD598(d5VjE0Xk@!H@D1k1@$"PeL9%+SPICJcJh8LC-hX%0p$aeTC[XT-LlX
- 3*9QTCbqZA$VSZUIHjkP3G5)-YH%1+-m[Y%)Y`Xa'PiM,Ql*'X)C#N!"#-mR`*!d
- +SJJJQ)h,VbcbCk'bVj02FJ$4IF"Z$`2TpSl'l3kZA!4lC8lp(#k5'rSN@"ihYLP
- QKX[CCAYS"dP4$)"Ab8A5-kP5YjA9ee918Flfq4LHEm4Z"'HZ39Sr))2*2d0!$6H
- 2cJqZJBM-,D1Y`A9$FS-E)8RQ4JL5)8(p0kicM'5Z`C!!J$1Mc"Qmcc@JS(U((IG
- hX1,'k8B5BYR$0lV6+Ip8)+)2U@+Red0*5R-q@Q14I%I$+N0)I&-UEZr6EiA!lDf
- hQ("XKrXQBQl+CG$,!&BrF0R!5@k0GTJ54M*$AM!)r(!0H@hpq3`K,*3+E%Xqb0C
- 86!@Q!SF+5-(D$$E#+R`Keqqd%YcH,m'9$N64%*rIM"9J5r,K4JY#I-8q(&`R@R6
- YQ5+Aj![QTDhhS*UEFb*DlXL*E&NGBT`P#8!NMm@Xk5M1``1Zjp6"D94A9$1`r4!
- 1cAffQedQC-QB&lLKeYPZjScT02dJdJE(DN(c`IHf*)leNc$4D9G!Y,LV)U@%r&Q
- E!C!!@4GGY"+ZBV"Mp()"RAC*b$G3ZY3aP-YP"10fHTqhacG*5HM-fRLJ1Z#ehrh
- F*Vr*i%Br3M1&VrS3U6LTIlGdk91rFli%5mUC[)d$YPYFi*T'Y9ab6p"p(I3UT0X
- JTkXq"U)T2I!P9LMfVBDHPSD[XVMrB[JE!bj'I3`pAL&Q!00dk1*m&JYV"ZYhVKG
- lCMTH@HaFRQfmk'%$e'`Ec[6$,&3&Xrf(cd0Y5qArc-UVCN9mU!h43**&QUcES5Q
- m9ThN'rPmY!rk)k,1[[35FNm2GfpZNqd@cTU2,GPS6#ke3FaBr8MHFq#q)$C1lM&
- 5jd,FC[-J8c,5-9aIMerRX(#@qXb,H$Aa3MAa5Q9'[0*C,&kSk!KH8EbSSNR))`%
- FQea4iZXd@3RdF)qa%LLP!j4K$TF[kd-9%"f#G-i)D5LSFr,BXBJKPXcMJVd9F42
- PZ'C-PDqYGS'f+cFNM@jbR4!A@eC5P"ZZp94jZ6kERJeFA$JT5DM'R[!`[lKV'B+
- B25pMlhJFqmE1dH!HkhN*QmE$DhA8V`e3BP),MUfH9Ql",U2ZA"GAPCI4D6,P05N
- p1Zp3d%,mQ$q%i&RCMBJImh`T+,Q5N!$[iiSX)3KM*kd0m#$@b@Eb*eDV'GI+&Gf
- B+m[5Qe992KhXPj,G`c66*f"$`TENreD!FMLj)!9h531qi&XSJ5lM!Gp0EG1KiFq
- B)H$HE3BQ"94Pr2!SVp-@cYbq!",%)&J4APa4j68pTaYBf-!hV0M'['&V8Ai5Z2p
- 4d4!NRMdNLf#[V0lE5qdf[R58[J1$2q)%eHPh#f5J0pGDkPdZ@XpN"V!![*U5mA6
- 9[A@Y,#d2qN!ZDAR%"&'#,##2j8p+lp`"G3UDNJqMTmCCkkZ[+3qa`P$RqcC@ljM
- S*5jAPbI1N!#'RFGr*@G-*J6eZBUf9SGibUYB@f+ZLhS2Z1ecNm6LYQID@ZAZhbJ
- ,[*Y90YAM,+j6pdP)9SCJ[jjFi!jJK(8*X*A!9S[SYHCp!S0YRLTVr%Vr&%8HhZ8
- m#qPe%PBV8Sl+85R%Id#qb[C[3QcJVlaMHdK`hr)bbrL@0A49@TA,&EDm5ZbfiXH
- lkQi5r%DbC%R@VCC35e,FZNj#kKQ%#5XH+c#p3*`EElFV0(4YM(eL!dP"%i'Me)1
- 8%eP&1TcdAld$RL)VDTHBB)$SB6GcMEHMDY3V@b$LrlQ*09([9*+kMF)K1lJ-IMp
- Z5q",23[TIa3"U$KLN!"A9V(eBmc`'Z*1F801*"Kb)4D1P"1`G&)ML*XN,4&3Xp[
- H@&F6BZddZC!!!jD,-#r!$YiGR9``Jp%HJCP&'fa+l1-3NLCXF3I9(,j39c1ehJ8
- &fFZR9*GaR48plCcR'`b5Q-ki1hc13BU)8MC!hmp32UR!&hej9Dd[(%q*0)G-2FU
- f0[CmHc#)IZP"rci#C3()H%i4FYkVXLLTR#N2PB2&k%HS!ZS($XBZ'p8[$98V3Ze
- XlR6%T(S0e'VHel@LH+LAVP@'5#,a8+qJ8UmdUKFZNU9Lbq@+c5[DQ"I@P+!U&XR
- mJkS[rZHU8`l-Z)hI,AHX2QECp-bFjaZ5MdQAQaqDFmf5T6HE[A2HHZ1)qGSjE@q
- EYcpbm+$NP6BFNEBd20h`m0YJ@P`Qc9Ld@VTem5CTY@4CI2[LeIK2HZ#09aXfQAH
- rmFD1KPqrfI$E@aG**I#kHmX$dLf@jXrQq"TZrUaKc8H(&jL2ca%rbT[ddiU'UaU
- ZElLcSDrPmMRGc+r05FqEm*-5U@l0l9,6`SA@!6rYCQljmljG8[[#'fjCZ&"DZr#
- ffqqi99VrqFfr0CYZN!$D`IAiIHQA6cf`I2R6Eh`UEIhC,3XI46&2PHUN"CC4"k@
- 6peVrr1Vf'eBq*K@mFD0j[&b85BrF*eAI0#lYeLA5$CCcT#A5Eap!c,'hhQpZZ2(
- ''bAVRmarHH2)2FGZNHi#mq1Ni!I[lGlcb8I5k[h[[5201bVpDYplqck5+Mji6eV
- id4(,ZjEZBfGm+PdZ99L+E`$Kh#AkeD5q#LqMqb&9PY6'm99H+(bXFdi)Ud66Lc@
- S8mHC$ql05V6YH+D2(dbq`mQ+-9+%lCm)a[b!E,i"HU3A30i&#`L5h1`eQASC+QB
- 9Q3bqZqA9D`1KH6TImdLGU9(m)$6CKI9N(88%$@J2+mBj$)KUDN"IJpafp%BpA*F
- i"[q$aJC%kSM""#T-CmN%0#aG"S!T5IiKlEKLZmB6,`1B@JZc&K%82aRI1FMm'3$
- CEP6N`1MU[C1#l60ij)G6KAKAp!`Yb,*q'J`kBK5I$#J'5i$2J@!3HT%*pQ1+6+C
- 6l-X4&DlZSYJLZM@,TQfE,%[)H!hjXlEXKX'S`&`FXCSaqI@`%YRbBaSI1hVB2AK
- )pGl*`H1m)mUlFUDeVIe8C"bfe#Tepk'#ef(&6F4D,qHHNc)Cp(SkrELDLF)P*'9
- MU9lZekD!r+j2qNH28[@j0kGiRrplMq$dihQP&S!6h3G3Lb'Sa6a%V2E&IT89#%U
- M(G@deh8UCmU9ZdQ*4hUpkR5qG8S[Mh)PKZS#DSRA2CeaCL)6a#T4BThN5R8-q0G
- S9,(Q0a(6Sm3-riqBlMBPjLQZBXb!fZ#a[pIIQAepdqA)Q8jhce!bbh39),-&`D0
- rcfaJAKdqQe'fNY'TVM(rAPqD)cJX%ZP2Q#)!L&G3rSe3$qVb+(PN3I@m8)(PFX&
- &6bPqSeh4[-Uli21`iT2YkSRidk#4$B+ri(HRiRIDDEmeLPq11eUee"1TfFFcK@G
- 8raa$9P$2b[X+kD2[h9G!9r8I0TCDMc,T+Y#9GF'3!23TXqmX$pi`2TaSaUTre-r
- FMjCdl%HNZPR[4d,IfMZAbj5T(),`&BlPaCCb#MB'MYDdepmTL5S@269%2+9Tk6l
- VK"T6"Pajha5D1cV$j+2V0"`NGG!4["aVSp1SQd[Jk8@F+P5"MTXk&0ZS$GJh%@F
- Ick)+aa,2i,c)Sl%"f-S#`3,4&ADJ3N4KSd"'S6IXf4$Z#Sjb8-k!)FR2Gd@MVFQ
- 1KTS@1'EblS@fHr**f!r4*qrX(BDAHqr`V[j,3$C&AE'$d)'hK1e!V-lr&Y&2LPM
- CZN)P'pX-e*VhkD-R!3&'X-p+lIA#-+V4mij+F9cEmh5Ni5lJqrY)NJf$Fli,feT
- $AJGG1NL8UE"&Z'ee$),Jc)M&QKhQCb(MUNKhTI4q3CYPk-9XCiNCrYrS,E&2l98
- 3B&0ZX1"XBaH13a'e#M&Ci-rSkUBXa!*'!#qJ"@mUdQF!VKNQMN&!Q0)dAmeeC68
- 9Ph10G$36fPAK&i!jD6S%XFYH&caq[KAd%0Ka6kPNV`@rK!VB&(FNe'5[#B*kL,a
- FI5&2DDBV2K1+Q&9rfhYZG4%A,%9kfhYF4*d@fk$98C-GXGq$$feNYiR%TJ-(JGi
- JAQQCh`F'l1QbeN256$Z+N`b4H+CFflJ$3YpNfpJ2f@Xc0H4"e)UShP1!mG!cC6T
- l2UcIkJqE1jmeQR5PI&I+K,e8Cmq$lGrf)em3dR2h`TIkNr##8k6JPkGp`[$TI(U
- iLEPL1cdI(QCLQ*BlE4'Zi8EBC0-f0TflK390c!+2UNK-ecB#'NRA+B[UfYj1)YU
- )LR'6)3)RNH-*$cTTJ`Q-31JVj-KpjDASYC(R3&NZ-MQp)hSHMekc'Ii,BlXm3pb
- cj0`E61bFKFJGBV23efFaLGXkZ5h-Dj*kUL*GVe(NfERB5kCI+@d#"0bpd3EIKQ4
- X8$IL"+ehJl)mH+,U`i)0AUIE"pj9b%[9A3ZeV%,EKmQc,RJFq@`)(L08LbFqN5A
- ZqQV#V""!T`3CIlZISkRTkXXl)NK6#kGUAIKf!`+&&@L4Zh0QpFm68M9-*pa,(r[
- hI9l[9HXVI"hS'RjPPLrHh[2AKS9rEVMqK6m%pMEm`R)Al$p[Z1@MI4mfh26aRrl
- `cM[`HHEi"hpU'0q`BZm("lBfH,G*NjibMc(2Ihr2"e,Hqp+4SjppGPKUAba02IL
- A4j!!NY[kL`rimf'`eUrp6F3qKP8$,f1qTP2fXR#46fiDPIZUae,pUTFZi(r8T#M
- BfM'Si&@A#2B99T+3!)[EVda&je(6Ubj5Q'&E)AdDef!9e9`,J#MD!hHFV4'K#!f
- USa@Cp&a*e4F3J33Ki[K#LF(Z@T5Z(9,pIXbA5b`2IlR)014pSlhkII"lN6$j,Rl
- R6q+eZcH3!!i$I394NpDqJ3[(IaLAK3rhjVI'&)hLD1(bA44aK"Ua-1h,*H4$%9K
- QiQ1FafXI4YKMZ"'#YJ2F64B%Ym$c89SP%BZ[%*-U6!RFme&F6F+VKjL$lX1p*"M
- XSTb"a"CB$e'D6Lc0LIB2'G!&R+L3!(2*0c`[iUTR`DRBa#@)[S*@+ZQV5XJ1YMJ
- &c3cF`UHK$(!akN6%lC!!*m`8+0HGFK1$hL4P+Y+G5L%%acDlQ'*VcMM($l1!Zh[
- Ma")Z`-4-39h%m,SB-&P*P'B4CSk1bk+*FDe#Srb#3eqHa,`KS)1iam-HNP`jK%Z
- Z6!4lpNZ15&Q5*XQmrb-)Xfak$IVT1Rf&U*!!R4&95*Kq4FirmEBeT(i9`kbLl8G
- 90*A&S**1(cM9&P9GaN5qR0!mDm%XJdJ59&,GU&9@[br,&Geb*Qk8G3ph2cCAhSm
- b[lQb)MMLRpMfIN4FK`-C5)H,XSaUT9c6)-IEeK2@p1Sd62eh()@2S5IijV!#PND
- [cQD'[TX14qBS-lB&k+Z3!'SbSj)A&iKGM[jKVc04Bea$rkYArFLJ5ldFAMHaC%D
- CTiVN6('qc2+j2FJC(&5hA9ATV(&@KI41'5C!("8Q#qRES#KCB1r+ZPE2NUY`*HG
- iKFJ,2'"d%Z'cr#Mf*%k3!*L$ij&+,'J(l0$TpKhr%m5b!1eE)LmAf9jBlU&E&Te
- Y*KGmMZh)6h1+&&C"8dD44h1pb66Ne@NEd!@L(-E65"Y6VFj1Ha2ZaFN6aa$f$&&
- GmBVUVH*@PPKa-FK59hR(DKP+-8NR&f+5KM+PS!b!JiFc$H"#R0P@L&1L"MGi&$Q
- h"Y&D)&qD@5ZJk"(-LI@Ff@Y,JJ8G&jPPT*J-fF4Y1jY&KC)&mbSJLe4N`3aJN!"
- %(B)@LirbZ4TeC-i9IkZ5are+([HMJX`HJ$a5j6cq2L2Q-3!2`I9X!$J6XfLDN8G
- ,"MKbdT@DhDhN5TGJB69#T+Tf"&82RiXc-U!'piHUmFpeF82aRV"DC)&P$K+8#8K
- PVT2q["%K&5+F9Bj9+p!*2+QajI&9C3PR92Pr+m&+#CP2J#X-!I+',Q4K&Jl+"S+
- T*9rHE-lJA%KJZdNRR@jkIZTB%&Z0Q8Q5[F@ZZ%E59@Dp,+1)HY+f%TjVbmA0YV$
- 64,2KI+PkX@a#hfB6NV2K6Tm+aAE#MT!!F@EliK`HReKLYC[!UDhB*hM#MFePR)F
- %UZK#,%Q*VjJT`8I+FkHAl`4[R[kDbF2LZS$(H1A0c'Gi-rX6hQA+QePdm*l@bIU
- #UDbC9@BTEmf#@pe4-@CB35bH!C`e-dNKLXP9E&B1plcXQ80XkY5lqFpfGX9BJ+A
- !@E#Ed8DKQ4"ZQ9MLG9jA#p(9@SZ6E&3G`lPL3YUm9[1jXcBm(k`j4$-IV!E-N!"
- M65,D*d`I0C0SUTXqQ&fded&82%qVf2l[(B9UIXGEJNV*cSFY5dPdGqjh#4KmHcP
- 9UClhU'BGa&ZcVKCBh,*+52pHqAhkSV"XIqcEN!$lfPTf(F&TXQp$ND9F9p2Z4TV
- 05,h)a'l)-iGhJaIGB'MjV-$NVYj1@!KX,k&RkIf#dX-[iJf1$VmRdS*AVEapB50
- NVLf1#0l$-%icTRS!``[RcREbjGPFUY32'@ENiYkeN8pQ-%TPj&VP@"#+Rbl(JTI
- Hl4!,@K)j&M5bC16QbV(!hU4L`5ZGAl4hJQqa'rIYKdER"Spa(JpL@b30Q[3Q&NE
- L!5%@4XBpXTI*l)ZS2V(`j+-IZ*1!*4hK1L`,F,"#r)[X0hf6M@kq!lL'[rG8YP@
- j(Td*2!FY3GbRrR2HpAc5j9E+'`VB3+FlG#QPp[`YeZVMfFLpPNqL,(#-2VF2Xa1
- 9U,b@-d3H4[Gl`j@T[)qL%S,a1,*G#Xe,d%N&UDrrUbH`pKp8qQpk'rPM8p&E65j
- fQAGp8iI!YdHZ(TJTb#X(pAX"p50qdQ)k,`+h@$C!Cq)MrD[@,&54+N[!ILRdlB#
- $!1K9l9$B[lRC$j!!2kHJ&V4(F5Yb`EB*VE032+YUAU+P'+A3+8Z9"mU+5LlGZJQ
- [CT((4!G[bU8G0"UASZ@@3[p2qj!!iZ"aG"[eM"'F''+`eV0@cB1FHh(NF!MI6LJ
- S@aXmkXHYNiEGJGR)T)hFhf0#"MNf9%Q6r-hR3rY'L6UVkABER#YbA(43hG8MZA1
- NR(XjId")d3S&"%KNYe'Z[9ah8$X%r6q+mbcIELB98DSVlcGNX*P'*QmT`(c#eHr
- brR@Y)'C-C2BPS$f3!+Ba!h`jZ01[J(kaq9iL&9"F+iE+bd!he9AjeI(3eXHEmZ2
- )TCPRK5QIlS21''KJKI9ZCFZm#e[Q5JfaSd`qZ+1bp`)6XqG$pHmdD#DC`YUVp`1
- ,K3SEX0XXPRYYiH6LSTQif,ELcFa$[+QqIm3,GHA(mAk4(a4mfIPa26l-$rZNF$H
- !QhTT,C(Y6ldmV0qh&a1E'!(GAmrah3dFe,$fFYX"M`,ql)@Q!@MhaHR)2CbrQVG
- km#19bLbrX*5i)r-1[Rqe3iIACCMRkG$Ra6f([8Ie('p,e(2-NRURdR0hS1HJ$k'
- #D4`aGY*m!%dX8JHU*M,C"qpbmTjT2HXpa8[HNhRXSpiF'ka1L(ddXqEpi-`YN6e
- 1jlJP%!P"VUD`Y'qR(-I+ZEG,[E$CCjE54D960%$cp&"GH'0eJpGpS--@mr-q2c$
- bYGl*)GZeeF@b$DGjelS(i$![#er5TH&f$+#6&ZbdDAKlm3lL(F,ELhH3!%8V"i&
- q1Gq&b)RlP[605'ke(PN"MKe$cV@N#NYRKfaIp2M9EUph88ca"#[T06K)fPJ!eJ#
- G398HlLib[iqarBYP(6PZ9PATr'KQC`8`(jKcNkF,Bb`mA6)a9qTRDNrP0G`2&B&
- ZfYbXRQQd)&*V+-i@a$N-pL149fhj2)lB1+b*q,c)IH)F%p8mNFm0(XTm5DJ12Nb
- 85jMJ')$hTr%Q"55k6fJ#,Z!6X2QE1S%*a1`elT5!iV(p4"e9A[-kB%[ll&4jS-4
- 3PS-TSGfX50h0k$@'RirqBLGM0@1mNq&FEP&Bd62I$b%r2fk)YRr%P4aMPpl9XDh
- 9B1YL9)A`N!#l1"j'Q-YZkiBm'8-C(i%CASeG"#Saj"**TZPI+h(a0[N*bbjQKGL
- f'*e"MDUakh,%kQfdBC!!jF*l[pjXf62RhKb18cPeQ3L#ZekI69EXd+MQQh5ZPDR
- LDd#C!+iYpG48Z5[$l#64qKp3kmrXP,he"q)4AX2VMdfQ1S6l81@E1q[qC58HhQE
- G5e&hE*G@hE(K4qXqBpXrecdHLK9)*phfSqpfeK3l(YHddHP51PS```1bkPUqil!
- V14hSH`Ck3l'ITdfP(0BV15b(mQY,DDhH%fRRqqPMi3h'*@0Z([3%ea+EI!EBpe@
- 11$bG$X`Y!lZ9F'"eGQjAK,pXiKJXm&51$SmC)BmCQ6UFRM2c(T!!b3"`5SmV%Y[
- "UJFijbMj+)`F%L'8+NcHhXPV22S,8dMh&k1dH'YlKPb(6h!Z48,LUSZmq8#P`"'
- (&rYHr1$ArDIf[5)`3NrN#!Dm`ZK%fTVRSK-c((%jA!H'l9G1dpE5JDYl9-53!"l
- VVrhf-rfPmACdf3`F@6VpPBkpHFBrpCF(rFd90rZ,2!5ae[h&L$[hebEHABqHlLj
- )kP@ppF,rAfp9RHUYLfEm[EHXrL'&dS5EFG6Y(jri@hrpI-qTrX*p'[GA[Ac5E$(
- ZQ6d'0-M%1[EYlHLe!,$Jd)UaP*rG19aI3SV!18R9pk,fiBfj2NfQEV9eM9@TFV@
- EGqTiREcl3'&@(1AAXCj8V"4TFcQ1Kihh,YJcS"cE+mmjB&hK99+1)&HrHYYNIYN
- #h)%hKV(jiBd"r6q$-mNbHQchB6TT0q,0BrTYBl&l3,LjcVl6JQb,`pPhVB+G1rl
- $[TAG8e!Ml*lB$P[GkPQll"-rhK$D*h)-B"1#GM'Z!HRC04+j4b$N!D@0FLfJ1h1
- KV*NhQY&PSB`B!m6T[(pSXp`&X!9KicV"PJ+EG%8cLi0Y4ZMq$""JAk@mSEai2m1
- '`@VKX18dPFfmVUU#C,UEQYCi!R2F[GYiA*p)L(1A``,F+9A@U@MHaJ!TVJhh2&F
- R'e-6![bR*0Q"4,AMQR%+8')SdQJk*YT8KU9EJ9@#")eZ'b#,b9+IDF5MRU3`+6J
- FCr8jieil"*8hYcJd*8X0ID#jc[28lbZ1iZX4ac[bE4CAYN-6rrVMIbM(c4kp&d4
- bCAD((rp$4@)L$Y4UGI'[fbA9Vq()"NYeY'Lfcc9ZB9%TCX6G*BiIreBmlacd`S8
- iiPMSmq1-3qQ9ifX,1[a2!6pP'LCRTY`A2pVBJ9k42S@4UYUNmA`I`Le$@0ES)*F
- 2$mYU,%clq4)cc!Q5JKeiKV"C2mK9h("ZhGFR&cb0qXmTmX51(KYX*d`50`$"i%R
- 8)Z5)i6Eb#X'EI$#[Hdk5fSA+eJf,2#P3PZ"A25Cbr"`(pf$F)l3*fGf99-$2h(-
- S$Z[1mUjSqMT1Ua`(5(`R-0!kUR&U'lD$Z@V9rUNkQ-&Fekjeb3ABN!"9R9"GVS"
- ip1IIGH5reURV*6Q1e+I'QPcLX"(&!2I#5$P$ZKiS(-4VF,H5&DDmNjAb[VScPj`
- 5A#0F),0V%dEEe%b@*cKDLbX-[RG3HA)fBMGc+IkA6&2$hG9-1[H4,mI`U6F*`%m
- aajFV@Xce(2rK''@1Gm[EMYcRUHQ&H-6$S5p2JH)8UEVd59hq$cAb,#r+2JT0j*i
- p*ARUKFjfUmc0kH%AP-jYf3"qaVGE1IGfh1N"HG#k-p6m$jNLrRl,5CYU2EHHDN1
- NXZ0JE2IB1b)HZp[8'lUkek,)r,k)a5SCX"dhGdbUC@HMlaC$L8h`G(rYD9ddKQa
- Jl#30$YD&)kb2TA0GC,JTJdl2k"dLaC5,-lP%""UDaGQ%Qf8&MQ&SpXMKqaY&)XA
- )Z"@%6pB+@FQ`FpZEY95*DGdE)K,Z$C1JG$S5lI63(5*3a!`L)5VN0%@SN!"5-Hk
- k-ea4eLaZ9kV%*&q1U[TUEr0bENi4IkrYc-RTJ2rGAk`iL(RJ*ApX2brphlALDJ!
- MHEFDrCkph@jHPU)@M%EmpdS8C4q'PJeAddL1cG!NFLj&J5&TVQa'(fdrlZ6S,$e
- fk4UC!HrGZ"ERm4N6Zfl9X`NhVRchbG-S'NPGVNBR6HrY+j3R+2hFIEIUMTGjUii
- V(4pGUTIrb-ia)Qa5G+YHX5R2YkRVhR4Uk0j8%+HTV$#NfS3`,Q``Vh0P,31B$Hm
- NJVA46N3mYEL"&bjYaQkFc8KfUHmI8ABT+&8h8CY`k+)6-4Ik2-U9[SUi)a3aJU,
- )VQC&Jf*-*YSK2HZNP3hN3DR3K*UHQSE1,lF99rF8,DDB0Y#2P65+jX`92*F8S&S
- eAPk*SMk`6BHU@e,`HJIh5#9[G5HTF"q1-N2f'3rm4emJh#ClNi8[Gl2-X%eIHBA
- L0AePL5NQ9a,c6)eLRUhBSa2c,-8fZdGMXBYQETpX+6E&VV"Mbbj($03,'0CN8jm
- 9a6B*l!M3U-U++,RbZ*X![`!*#bDb*,l)#0+0REiKKAB@jQ&AbPR`*X8rT*c&)2+
- F6Z!-ZjAV6FTX('%,Qq",$+&m#HM"*5&TTm)pPd*)"*PLp05ji-!G`iAP&8j2Z-r
- r@cdQrIr8iq)(cpEM#K$mf[A!jD',q$SiGhSMEed$A"&Zra)hKT4l2A6J4h1EFLr
- ABEL4EK+aMjTDH!J0TCX$B95&(G8KG,5*hhaM-[)'JVHH#HNbfQ,H@bJP!#FP8q@
- J-ia`UK5H[I)Fm5cTKD3qB248HD90aBkSq5@ZV+Q9fE0lZ1BL5`-2UkHKHdXAVl6
- @6+0ee&!(30pq*c"'VVVJAe6YDQLdXV*EkZ,X&ImYZaBP1j[GIj0DYGBC9E99)$5
- 1X2Mm8'8)fNQa[SKB1%#IAeGA3kdm[kDQ6,Rb2KD08%e%LdA#C3-V(bBN4[9KTPe
- kj[PRIKI@ddpmr,K8cr,hE(eHp4'em3f48$rU`ik#cIZfVBiCq,CbmLG`e9Fh6@j
- +DTSK1&5XNI*#9RrGkZr*0A)(k(hD8VfHhU6Ar"002flL2Z[d1Y@(XP!qi"`'cp%
- MP[8-Yp!c*DJf$d*K0h3VBT[5GaZk`MD$L9E6#@D52&QTUpi14bm"JicM%4Ui&2[
- L6("[Dqk5G"qd[JPI#@'`T,ZjZ3+#E%`m@ZqZSL`&PNTA#2hAbM*)(DH,lhqpl!h
- Cf%4*ViQac,B+Jq5kMUZ4NEJDb9KY"4&FR8mcX`,h)kaC)4X-''V[p3&RmMJiF`&
- 2cbRfcL[fp093qmkkf(#$e"fAe-6le5IDH95qfHR,*B6+kddi(4I,MDJ0UjT3f""
- 9"e`DHKprC)9FDiU[836C2U(j4H-)`T+KF!4'$S!CQ0M"p[DVLFE,c*P99864KS'
- G@XekZS63U$e0C$THN!#*,,d[@Qe&-`MZ1!T1pEq*$N4Q`%G-0RSDJ'2V3UG(eZl
- BFc4G5c4ed@e1@G*TYm*HGd5C$lQN4k[V@A3@ha(f6,4$ljKCrrdG9r1d+E#1)pN
- @fLh+YJ#F(i4U@VN4lAbU'kE,",H4$T+0l`DUPTU*T0"@Aff,2K$4+i**PHREUmj
- 4b&eHk-'LB1P04UfHl)UmdX5+`lJ*UqH+U!r*P,8,539SHL)RQjI-39LLUNYXAJr
- 0qr%,RT!!#2H)CJc4DVH1Fj%SlJp@qm@X*2#FrC8L-c1l$j5@SC[4RGe[+"FZ&bV
- (QZE0#1dIT+F!L%X)L%XU+8`!H`Gd*)4AfPCL)RrL!YJ-h89Qc-S0YVP3Q6YCA#T
- #mm8CiaLBX13#K(U5YSmQh`aCkbES(dGP%BC19b"9Bq8C"peAA1HLEQhj*4,AkD1
- C(kV@M,ARfmE+h%#iP8VhTTVb1qFHmbTdG[NSVJ9Ki5#N$A`'21&SMX2@EKVEQ3&
- Y-j+j`q@3!*-KFcPJpkRUh(eb%#fh$j5%2Z@1IHSjYc'G92(LhKZpp#h#B51jTAk
- E@qSrjCBUjhBdXdE+,$FDc#'jBLjZ!Ra*i)iiMJ1'Fe1-B,fBZMQrQUZP)H@q81q
- 1fBX[d*Lh94efdiZ,UJFS9CKqKTZ(N8QSe3)c2&r#BVT83IF"6HcYRa*CT%Q`5"e
- ZJ86rAiIc4181jmP'+Q8fjG-e5'q[[q[pIhFpppUCmNjh,&IUh)(q4qqLqrr5(EY
- T2RSd#9h+2GT*9,Lal[pPMM`G"ZB!FMbDBAei#P$rbb3i2JA!ii%jm2i8H1Z1rfF
- +[((Nc"5`S$QYD-"'&&K$8M26m'S`mU#9Ve5k1Lq("AR3q%5fLk-(b*Ze-Z,+NG9
- QZTGrJdV3"PbeNT6lfRH-)h&"P`%1#k!4+bT`[lL#B`[%2V*G`B)%+6LD5aEAb0A
- VH9VS-N#M"ErDp%QKPh0VDh*EfCL%A"1mbj,PklT'X$!,eQEcB9B$5!G[P[p8Zhp
- !3plNXDPIFIZKEdDVC%`&&LKe*hdTjRhYG(Q#r&cNb)$I$B88qST2EI66C8e%d+Q
- MPIE-N!$a11Gk@,,Ua@hjUPG9m+)CP*pXrdlNBraQ'P8j-3hH[lb`@4mCbG(U-'2
- 6VmU&Hi[1[3l1AqC-4GQ3!0#4"HSZ$UAULe5dVTI04[BQ9Qkf2FLR1&ehiPU9qjS
- fGYJi%m)ZVUSTmhYp-JX2%"SeNhX4Aa2pB6i-TG$03Arbj9XaeRM&qaAV5FTaUE8
- !rpJEpi8aRji#D-ET$*i``8S+UI$Z604rSk5122A'4$GZTKkl!h*p-$dbEd-@K,C
- TA)[%#636fU34*d+EE(ckTmVp!b01K$B4kR38FE*e)elSG0,CX25)D1Shqm45,DF
- ljQLI+,BSZRDBcVA1-Bj'M$6945%ZVV$F$dH4[+LI1@q)m`NFZTifDpr(J)iEC#'
- PaPQAlAKZ'&4HJ0@(ja"Gc@c+K8i1hUl3-q(EFX%9&HS,R+b))H)h,@#-XQI@kep
- hMkVIrP9+pk6KVPki[NbGG98c1"NfijCUliIfhYE`aPH5M-l*YYlq"bJeb8UaJpB
- GH&$fdQ4EdRJS)YlRk!Np1HKl8HHI-akka$%p46d-iIceS+5M&C)3)f[k-3mL00V
- V'a!G4GmHaHCTTB[IF9NlieXHl)cFJk4#68pUd*MbN!$9Fa%SU0A9ZZHG+@PeZVk
- $@"#DFZB-Lh@eifG[%GBX8qaF@[qHlNIZ4HV,'CXra)eTC*T*4p*8HhqD,3K2-b&
- E*j`AA'IfT)G99E6+kZNIVZSlbq5UdZbKU0#XBej34UVVH%8f*&eCDd0kIeE[5rS
- rCM8M`UUfM&jV0+M!MJY`Hd,hiGM@K1YBEeG3ElSmXMGAV5La3&CaaRX2FE8`4`e
- Y18G4ETA6MbGrMA*(CUI8%GQ[P"(dJe"$j#$SI9ZKA*VCQeqcjHrjlhhc[qC[F[2
- 3aL0i(IV)RJV1M1X!@RJeh@$2j,f&MZQJVX(Nfm9R'0IaCq1TMR*$rTK8IB")fTX
- k+k8[`e4'HiGf9)SUT$ZqirY+,C!!+f9!,ElUbr&Z63hIr2Y9cY%ZY*YI2U"RmN2
- DbT52VDVZRlA1Q4LjU61D09YVAJ,1#&XAjd%lhe,FG0SA+5C[Spc0brdX'&&q(YC
- G$F9"qc[9081"YHU'KC0PL3h#NAlca&,LD`)2Q0DF3pU[Ia6URB9FBFjk13TTpGI
- hQFI8a%'V&ZZJpL1$RR!'k'b534"I8,d[ZY0,YMl1l)S+TkSFQ+k*L,N(9kcjhpq
- VHV%4J(p1G86BGcLN-bkpQL[jLb)i4lQA61fXrVd+*aVh`dd65d%06G3F2"r!PN"
- A-EBf`4iSGjZ-@jUpkS@'4NEQqj9$%HVQETRjUMG[m`B3qYpQ3@FDp$K#5J(TY&9
- Hkm$'P6!9A"1f6XmYB%IE!Y9-@eJG@m!i8JQ@0qK1)heiFQr&I-A%4,a@VHT[iIT
- 2N!!Kq&l#IFe,3[,9eiAU(9CpLGF&iPRL92[X0j!!KqD!,T2j3'%C,qqrX&5%EbP
- ala%4&N(aJrb#')S2QIf3!+k&F2eLFRI),QPYEfpbj!jS@F%r)fQ1VcN6604L#[8
- B*NiqE4$&fKh)Ll!1b$qMh3aBKrJ!mIJ')4iK9J+VICHClq%FIdU0jdMb)Y3$f)L
- +Aij,@YVh9-EjB"1$YIQeN!#S"d'Z#FH)i3QBrINXK'($@X"N"KQajV(KkSDbV%b
- qET(Bf#h'9I0l&4@T++br%0CLl"2E[q#CS"lM)0#"HC&)+CZZ"fjaP[X8"Rc0bRD
- HpGAEr&Hh(RceYJke"CYRF(h3,9IMkV$Te9AEbBFQcNCaLldNPcDHMCKjK0,4Qh"
- 3HY0f3qm8E#*6F)p)0hkE`4HGZV(keGZU(lZUU(QA1!@CV!*I1A'@Aih[GIL#$rM
- E,PZ+X"i#F@!*9`VhV4dScj1El9bl!8ZLSTSKfMTmEd4P$["Zhc`+kJ@rXkc,A[$
- U%Pla'VS-R`*0j(TENBU$hFC,&9P+($Y9'k[h'GeCDU@V8#hFRhC#G9LNpZGCpaN
- jPc#TPG`)j#LeZ4CAUY`"bUSZZe!aC(d98##CEST9RQiC0`l"&1XjH9945j)iKG3
- #%0-qGaAmF%-9DViAmpR(&4,E2V@4XKGI@2%YpihfNUNiMBP8eDaJNEl8eE2$QZ(
- 512Tad43dUcC#8!I0mBh),G"mEfP4U'TmCUZ["Aq9%pp`JP-6@4(AbNEL*)B160S
- M0Q,Lm#5!6`!qG!G!2Y3Vpf%bZ8Z,E&!S#Jj)8UJp`8(FM"Xa`cE#G`Dd8(*2XId
- -eK1X9MSRfMNS4S$Ijj&(L&pMELa9*JpmJb&IMUDb##JFBK+6*Zplq4f,5(@$[[-
- 8M[pYj+V1l3k5rPQRp)mPTL3$c,U3!-E54$1M)3EcCL@KfYqf2(V`e6T)8[%0JZd
- lGCLq+deDVKL9Q0bVQQqJAUAXe18%[DZSmkFPFDBYpQYE`Q2kpQ$IEfXLQiqj$9R
- D3#l8h5G-bR9SCJ)0F%Z0c0ecT,E'X-F*m4m*Nr)FQZZ"EXLXEBMM18!c'ZhkEBX
- G+4BhAPQ+9l#JqT@KcE2a+QhqKF2!hf3YE[j&+!2`R5%@'%+3!)&lrHeiaDeIMDh
- 4!eXm,*),r!Z(l%YVRSTA5R1j`m$IC#eS,PFjd'4UdZQfp!p%kAP)14rHL@#J5D&
- C`T*$U&SAS8[!aQcSQfp3j[`XN!$[611#V*8qL-a089R'"%5m*S(eILZ+jlJKeeG
- 3j3'Glm8K18PlZC!!',ULaiaqKr5`dK6*@5QcFC-Y&cDH5-T26aVb#h%QE[J`iq,
- k%0Y5%0V2r-($H!@$4ad'rLDVRpr&Bblf(-(Y0kBPGP6#%mRM)%e+f!NV*[Z48!5
- Hf[!ic$dS"P4K%2E&SNEf0UmhiZDb4lEGKkPFV&DP85rAS6C5VS$f@bVl(9EmrV%
- Qf)5,3V8iq)pD3*meei*`29flrehGlX&b4K3(V!J(JBkiI+3USTfcmYN9BBb(CL4
- 2HCdjTZ6[Ij99efYb9L+-KMI0&64)p,@Kk'mJCNeF(BD`rIcEd#i%rDr%6[IfJj3
- PUGAk#fA2+G+U236HUAD6YSdZGMGfeCSC$DR1SLIXR4dfkk3L,kNJl!Ve5bF3L$b
- A$[J#Sr9Ypq!ba42U*mj4+XhC9++qA`5lG3UaP,FY*$rX+kHi"e"XYD(5,4kpXkK
- ZAD53!$j)hPY695C1l*3QVlELiiMZIa$h3[YHqbB&Vie0"EP[d"R6V+RJ28jh8i9
- $AVfqq50kE59YL-LkGfI%0AV4+QQdqHqCkDTLCcjH9p5Q-bfX+J2p6'FNLZP&qTP
- UUPQedEA14N[eIBTbH'XAG'CZ2d'Ae"Y0N9d6-IkIjL&BP26XNULlL49Vic-IX',
- d-GL'PK+fK5kZGB6k!jJEqZ1T[hF(Gc"0X9A3YBCAZ"Ml*LPpk+[k1h3&[QSYLD@
- "lMRTCZa%eK&0Ere023,4qXXqIf3AIpe1AI"fTLdAkV*jKR%pmX'mReX!r19B(6S
- f+2M#+93*[SlEL-XBMS&h&Vm"i%jbGJQH!@CAP86DFfQ@%QXEfHR+lmpTlM)HJNa
- A@G`b1f4E3*lrBT8H8LKQ(UE8DVQIc*RTAC%RGbRI(0JG60JjGDjd(URqGMUSMk1
- QGbEZiMHIB2a&cYcPcQ46-eVK)+B9+!9j+dC@mJM*Y5(m[ZeqA$TdR0i)-"eah8c
- iSYirmbHSGbPNKDjMH(H'[22#0@fljprf!CVT4m*cmbClLE1QV$Cd95mi"['K(*f
- BqbMkiI[iD`(e`&Yd[FRCBQi34dh)NrcG['JR00fF&`26)6*aUBqLNpDD#DVZ-fL
- LkXRJq261@1A0qHNqT+fa+++0,JKSBe2GD'j*M#&J+X5BJJDQ`QDUlaY3IS0-Ilp
- c)m@l3-iT1LH1E3&@G)S6R4Q5amFld9[pZRBLJU6YR@J8emLTqI4a@4p%Tp0H31L
- hhJXma1KeU$9808r(E+0GY(IVaKf+hVV0Q04TGTfI!"k'U[P)%FAK0QJEMGAp4*l
- BGiN,N6GUl4R09ZCGIfbba(EPq2rBP9(h0pp3pLUj4qF1![HSdJPN)AeU3JE856"
- fJ6j&Y@hckr2Gr99VS8Nr[#2+Y"aG5lPUhqlAjrj6T"[dZ9$TZ8LG4"[Xi)0YG3-
- GEhBT[#[3cTFTUMb5e-r8ae!"XIP2VE4eb%f%m+pP"NSNiTFUB51JplFS!VbR5eJ
- f1M)AYj9P,L180jD3!"GNFCAPX*B+e3DPP#9L-9$49#MZK!jLLS--*Z9S@mSh6B2
- qpZ#)A1JDN5J9,#kN-3#)pC8ZZ95-,bHT2#$P9d!h`bG-[D&,jJi2l4I28VArp,!
- qbl92m5)qU,c[iicVL!2PQbh"C&NmANd*mUe6$kG0CDE%pJD'f!!BhTKr"(9)4pp
- QS&mb56pLf)lE%VFB0IGjcVY@J`d#qccaE&clI#EXm2E!qjYL[Z,YDl0blfq#)Dj
- UEDUBcjRCTPQ+1cMECS'cECDY"+qCUX*5E"+Y6VFAe-)V3Y9*TdN5LXGd)RD[aMK
- SrJMBG"aI*@i"aHDP*`,BI!+2iGTKUDKkR!pVEd4L"6-M)TqXU2Q(pB@Mc9clDp!
- 66hXAY1&(BJiIhj9P%&N@G@9CG#CLDQI%)ReaB0bKF6[mqZ)pjKh)%YQDQb0U%13
- eU#iaGrT"Le-19*!!Q2-6pPcBJk5r-r``-i3ZeCTp0G@ic9SPEkLGi"kQlHY*LYP
- kpA22!RRC2$3M2K%ebr64&3GlM[(V%i-Rcm3C[8%r)$j4p6S9bSem!ll,TAlmejl
- Cm!cr[l1N5Ri"Q2I5QMUcYlc5&lje2Vj0)*G[8Ll,$qr-+hKfiFIaKEp$&jZl`AA
- kY,14IVScPdHU4U6UMNK&rX0YH45&l@[L8f'[k,$RGpc#P,K$rBPGT+4P8SI[Z#l
- IF@&I@&0EG*eaY3dDPbD&Gah1Ed*R(-b6N!$rNcESI0mkZ5[qJ6C5)`+qN!#Y9hA
- 9ip+ZHMLjM%-H(0-`GZ8b$PPdqMrQ16UjM![RmQ`VN!!fU*'bUfEf"'ajcIHIZPT
- BTXiLA,aUR3Xr)HAqIZa6$Q*5l)iR,q!$$h9j3CZlYUI!IZNcZ8,"A09Mk&`pEVV
- 8aF@XMSUP@padqIV!ccYpP2bd`kHm10,Kp@ZqMY64j89h6-S+RJqq2pUDSPcfBB1
- $!)#''Ppp50F$f$1CciR`9-cKS-VT"!l+'l,Q*D*Ui($GPRK&k@,Fe(KA6'HDcC,
- 2S0S3C3eXRK8P8"RambFNRekfPM5#jBR[R$ELUQDaXh`k*cjA@IIXkp#RND(*dbM
- D,FUceFTPSh+XGc11&*pSR5dcie[UaB38eP(Y,1+XDCYV6!$6+K3+1jkf,C-L%*2
- MTiV50QN1L`Q*ZP82[EVQXFDT09"&M!b!AGc*BbcSb[UJR,A1"(2r)0mZ,'[@%%6
- K1i!-ZBBVkN*G6`Tl6KQ8qqUD3DMIGeB63`riDA+`afGS*)'j*e1H8YPjVKS@%kT
- Vb+3r[k#ae3cm,5KR&EH"#b)%9UFMaQfbXE2q6mZ+V@$C%FlERP1RS!GHYH@jTK+
- Hjr5(dcH5dE4PACh!YmL46YJIlM#fCU)6pJG2SXSMNEp5l6)VY0m8SflBY,*+LkT
- $Q)Vf!6jPSQr`kBB25)b-SkS2lf5Q9@p(jNkQDh"B2`#AY%pde@h[fEVYlHVJ[Eb
- $pr+0cqjDjK*[96+K20STMeAcS$d99qR@2+*Zl*dcc&[MJaE@CFB%ejBcR8B4GBI
- CGF!q+AUm11U0rcE*c)fN($eG'l*+lD*640LBNab%LLYP(l6a0$V,j8XVZYePc-+
- (+qdPiQ`ia9YaelKP9',MIjN5rcPL65iUR3%@5(Ie#K84f*M[+DZY,1&PFH3-mVd
- $+9K"j1aVXN)68Xq!8YdI2Sj2I!2cS[*hChc,G(rm1(l!QpMZ+erB[!MhAD6eCQ5
- QlN9FQEj!$,6Ih,L`@VpaN9IK+Y9A!jZ+IC!!-ADKpe3e''PP(Dk&dFfeXL6$TRQ
- CbZCb-RMKba4ECQ!-5ji'jXZC@8Da"(T&h'!d18-X`5EQ)k8KjU6c2SHYhQYQIAE
- Nj3JKV`4icB"AD%GZMJ"mq++e8$K-(,'MdPL[jT(3"aeU[LFVPF@YRXCL4UDbf$[
- J3ETS*2Y2%Pp(K'G4r%DfK[VMi)kmJQF)3F,eG'H*1Calkm%GZGbc'TlGj'NbER!
- 1*a(,a8"ZZ(GU"aE*M2b`GF!'cJHqc9H+QkKZ@qQq"IUd!ab(aEA5+Tp28DL0lK,
- KIEfG9Akp6CTFT,!cI`[+EiPYL("U[MR#HmBCKPrJQHN8ZHCkIS8&$f30lNpMAKH
- MK&P9e1ESC542mB$&c@mLAEL%T#[IcF#CLeed#fPH2r)YT(NC+II&L*MB[!DemX$
- L)`[9C'X*2%CcK5emABijI+@r!ZS$eE5clTpPFU[YQFlCC"3Y8RGf+p,3KeQdR[-
- @S*Z@65GUD-9!)E1+p&F65VU5c@%3)[M@$-KmeIe9*8%9JUKiHP#-d%#R,hC5XGq
- YG-EH-@$5R-d9$d05iPYb&)J$ijFS)8j(4Qfehda")0AlE6VXU2lXl%*aC(CK!K5
- AUdP6'[N(QRe6@4r9!qUAp[q4*YmdeKYGI!!-AL!e%RClA-6p2PMj)48@L'9H"ij
- METH`951LKf3L8[D'JcBidL&Ff)Hbf6T)6%KPL+l%9"U9NiTX#pdQD%AJQS,&cK!
- MDSaleUV@mSYDcXGd6F0d6FR'P,dEmk[@40hKQU2kk8TVj1dEKq-,Xp%2T*f*iXm
- U)XXrcq9ThmpPQGMrD5jAkG!(ip!jGhG1D2%H"HA!(ZQ``pe6*fRhUDrD'&c1'q`
- 1UV4a#qP9-qLDdCcS%[ZhTN,Ii&YJb*YJkYE"'M,HRIEG*Q$&!6CA66RifVM5R[F
- LpZi1`[GYE`m#fQPq+FD6V*d"1)05Tq0CR95Jc'9-BAb*hejPTQrrYrDPHD%R-q@
- f@'&'8hIdc'V!q0e)P6GECHNRhI,3XMF&Y`ZLcB-b5LH9c)CKrCS`Zi$$#,!ea5m
- S,,+-2q+HCkR+-9%S+lMJq8[+#j(M10br@!UYY6")TBIUU+r0NJ2-6rKHj0b&YS1
- eUK*ddU0#Yd*d2iflSA68QDT,ZUhMkAT"*MpVY@(&kI(*T#QDFT0pc01-#8AD(@a
- fLE&M1H2Y4[#*N!!bk,A02P*G*XUJTL9"$IYkXPa0LJ6A0[r8"TjBD),NM!Zl!aR
- ,1M-PeT!!eKc#d$P2DfFZ'L3MN!!2Qhhp6RNr"bq+F)kC4BBmip@Y'R'"6b)UB8+
- flh-Pj)fB(M8cl#m(ab$D25A!#*-80I2EQMm!2[2VHTPX'01[+V,F$jj12lEh8fJ
- EV*`C$-)fbT5EVQrT)dkK+e1P[@)M1(b*CfSMDE!!*PBY+qp*h1p[*h3[EZ3rFRN
- Jle3ZR!0`!5F$ph&Sl0[0*mXf@B&m2I(+b!4-24eVPha*!mkC%C!!%9i$6K!2f(U
- #LNl,'LKcJk*qc$j20ILT81dfi6jCCk!Ec#1eZ'HPIR(KVK#GIQMpcdhD5EL`SFM
- 2YS*ap"#,cJ!(P0%cl'GQ&+TqpLV5'C'H(QfjIrh+8&h68C(45Qh6rlPbc!*"RRS
- @%ilh`+hK5Ba0d3KqfFaj3+!N,48Dh+p$VI(+KT!!fkc,50Alq59J[-)8k$PaHVT
- Jbk,TJMYRh$Gqfk9`c6a%bQ1qlF,Gid2"pY16"EXCc4C%l$6[ChTJCHdm3lU@E2F
- ID4Y,Yj!!Z)m!NJa,"c)kH#@r$2d8CiZJQ[&qel6[%XY&Q!#iKm$'!rhc@dY$[8(
- h`p3A*HK"8T86a(d%jG91ZP#3!#PBfeSq8M,m$hN49`hP08l1bpLSh(X5!aRaa"!
- I,lhjeKT[jZj3R0Ad*QjUH[2p-H+HdXPIJRFaYYL$T"TGGQ5jkHcRcE"B-fam*Z$
- LbJR"H1%KhJYX,'P3#5EX9#9b4N&`f"D"F9SadGD3!,Sp1N1Jj8jB*QL$X[!8Z4Y
- THmLB3(KmND$Fq$6jkQZG!!90I5LDliJfG,R1kpA8p@`V0!Bd[9+3!&L-I@,FMYB
- 5U*!!JfEfG0b6-"Vd`-eJrFH@U#DAFhFcZmZDUPU*KBIff,h3kU8CLV$GIEE+ie&
- ,bX*MZCV%Gb%h)YMaj-C%VV"k6Q$ZGS1C9AC289*KlTkpZkdjBp18[AJak,hk8#L
- k-e(pKAbXrZ,EBfE-e"14EK$U)k'T!'UjT%02MKp*QE#hHAZPVCR"im3e#*E2pS,
- RE20,LcbDh2RfqDD)8Z`-@8b8prYYbGLC)eZ0+1MTF8$kl*D,NqfS+RM-pSi"9h,
- 5@DCjVN*'D6*8&`"T*6CPdD0HK3N69R8BS-p)3la!FG*RHp3C)*a)P,P8ePdJHk$
- rNec!QpTHjel&+MB4Z@VBhf(0$")6Q@)Tk5(@2m95dR1S`dr(),ppf"Af!q(FUl+
- Ap"b#G4qaPq!@!h`PZ'aJpK+mbEVrK`EB5`MYahX2FA(`PF5HjVG)f+kZ#V'A8"f
- )TB3US2f)[B4USI`'#@![19D,rmeH%XN)kZJT)pUqdG%rl')aUIjrXjKmQ&eKpqE
- AZ3B)B6peCNq0bQG(c,l3F`#pHTJJhk!*mXH(pE(Z5#JV[D1DpJRf)5iXj81-@'j
- jSm'FTV[D&@''+lPk)r5`,A5r*,GN[CGCFKQ),6'cZHX+d,Q6qmfGSBQQXBKSS1Y
- HC(4UFcQrjPS@3UlUR'@i`&LKBZ6@V3ViYrJ5M2,BeXcZp9fMB(fX6DfH)c'R[`Z
- 1UQP+6A2E1%2CU4+l9kh%j-2krY&3Z(lmGSih3A"$58AdR3SkKcLL&S!pJ(9dkFk
- *F(@9R1SM[XTalX(Ibe,UMRh6c&%Tr6LDC3-KD(D@Z!6kjacT+Xr-N3M$N!"Ppb&
- &MC5[!%Sk2$-*A3*5@UEpJ(G@E4)djjmhQqPfNJ6YS#1I0+-4YJ11%A"CcCE-"hF
- DfTl,D)3`C1mccjN2[[VJpPCV'pJV$rNMekEK2Q)R43'2!fpB(U1GP%'#9H[j`G9
- 2@,cYKr%p!(dKF551f9L!H,Z3!&ehbdT#@#k9&HIj&FBa0r'EU`Nb"mTl$`'lm+Q
- +I'QR4bhK*C("BZH9Ue(**c9ICa3B%q+B63YTdl%Bf*!!fl%KJa%I[&9ZX(8B`4Q
- bT6i5pa[A1`U"ESA$&FCfl-D8"bj1UM4q$Ne-K)pb99p50eQc(pPUA@952UE@#h3
- N0()hq@AZ)Pa`b"8aUm05Qk1mTa6,5Y$%QNfm5XG[FK#&GLPpT9#U-*9SK*hfRpN
- UeaT[+BS"P@)S40lQIL-'8hUEpaI&1X,$jR%Q35M*S+Q3!1%*AGSjhQ20,(4p+jL
- BLTRRLI[+$p%B4@He2B[C$,%BR([Zi!'m['%0PK5Ka3JfL$ajdf*E[Xb25[@qp#A
- F4+Xi9&HfmUC*0A333KhCbBLZ0dlirZUH`qDJb`1R!$S)QB-R9l*3R[RFXaUHhEb
- Arr'H`m4M22pj04'j0c!V[V9+R5,SeqU3!$ii6*rjR[,V3RI3qqK#Pi93!e8M0Q5
- MRmDU)6DYNCSmV[$%EEHU[IXRI20NKNJ6bC,0Nhhi9X$e00d*mFlb@mV0,Gp9E[@
- B%ZLU!,F*qddkD%a-a8lG0*8*bkk5F"Zf!ajA3*IReB9b90DS8(jr5b9&a3hKYF$
- *S@5C2,Fkb%IRRiAFX"'AZ-Cd+2FN,ZdM(6GV"p%eKrL01ICcjM4AhUc3KT3qHEq
- ,MPL%Ca!+F%6*i"!bL%3hYSCVKRfQ@+iDr"iqIHd+F60'k)CEAF8@`'HG,FqGCEP
- )[[UeVR#,KV`bVH2Q)aqjlmIhJ*apD#5b6hAB`VI#UakQ'lS'fNYrSZDL,MVfi)l
- R*l62eIFc(f,pddAP,eHUfrH8`KIU%[AY+*L&)%")DmJcEq@2)J5r`!DL0rp4E1$
- 5d&e-G2GrA@@r@K@FHICH2(SKc&MD3G`#910U(VJIBGUSrHY+c`*RiRipb(Z@-mN
- S(FaXT!Bfh4h,jD*MHJlGBB4H4r!29VKe-`9S-mB%`*ak%(HbrANG9[5[(LCXbGV
- 12Xi,V,9(+#q+$(6XN!#ED82G`eI0cSfcIAmZeliIAp`5pa"GR&1I4br'hAHS+Pp
- J@`XdVM0iA,jkGVTC6ajerdb+AZclCjT`IAI2MbUhPiHKB%jCkR[b@`P8Zj(URUh
- k0Am9i4"BXX%$Xc*Sb!X'AA9d+e`IBY'4RU#k)r1$rhT2MFLZVXLif&H4$rpEj+Q
- )E,!RH1iQLfiNGmUJAFe!q9!h(2`q+e`pSjl(+aR**YVa9)pYH5l1`U8llKH9FbZ
- 9Fh99cUSpGFfabKhqrkTF**[r9EP5R6)pM#pRU0IBYa@8H5XmcPaI2C3M69&h$mS
- %Q"E[NeYVP-Z'6SVh"G,PYK6,,0pX5#aX8)L'L)a`bZ650ffC!@*GSqaa"ikYYS8
- MT"YjTKGk`6bmR01C+d`QNb2qa1b5'lT,,bFPDKZK9S@a%lccD'S4IcVV6f4pJh,
- "3UUljKAC&T!!jNkkC)&("4X[hm0C&l3PS3[D8N)cD2Xd05!i1!"Y-V4prK,*S4e
- ABG[rM15NrA!!NN1l!ljm`A!-Vh&3#X&Y"JI!CXL(pG&pPPpfiC9G$#5bhBVl+lU
- pLYEfa%dAp8(XVXZZm)QlVJplYJmA1[`p,L4ET0iX,9cS[Ga-A%Ke210#DN*mM!Z
- KfL@ULM0Jlb#HK++"qM!MEr3fL,@*m3fH8Xh)9jpD0D25GFEh3*)#jLGAVDf1-lc
- G`ZF$,%B")9QSG`HqI)Z"b36Yl8"TVfLqdC3!"2-3Yej+9YS0jHjF4DS*qbU2DJ9
- $Tl5ES-haLR+C+Hm)e,-M3kdJZ%DA5G09DijJA3Z%`%Nri3V4MAiBkDV$lZ`M9+V
- "#0`jM#pB("[bJH(XiXaC+L+aEF&R@kF2m@R"KaK['DRMERDLdEe1c*0MYL"lPfY
- D+(0#[M2`cH0Ffc@G14+A@+h8kF%+`ZLQQK$")q(-1&,D9hi8Ma#Am*6*4B9Y5k#
- 3!2Z5mH1,l8A@,QEbMe%'Kj2%9JEr5Dr-f'c6D3b`Njq#@a"5$l@K0-4p-TEB$8c
- d!pD!2UR$'JcA!GB3H$lqZ8SQciZUdhUj5V-U55Um9ZpTFLLXJ1bReHakPK8$(S8
- PE$Lkph8lhZV#$hcrcl9Za)9ISpi`MI8"arqVb2%q3`SS&C+KEFh&04B3FhVk-r[
- Cm#cF(8lBe(fp+5%5rEdl0l24(pf@HiR%0,B)&fQj64LUA8Alh(h2l@2aVq)+Y6B
- 5HNJRl3ChSPHU0b%5p))T#p6hJ+0*'#C6X1H"XABh)L)c8Lchd$9m@SjNb!bFL'B
- NBLZP51"YiMJ2qQ,!'MM1R@5hJPYN(+qaHlCJLh5c),BTUmSeU,+q`ImbBFCAHJ$
- 4AFT[rUTpY99UKf1LiPD(*QYE(4!cU*N&Rk2&&1"aai6YV'hHilUq+d+4HeVB$T5
- 6H@c8A@)e0*MKSY5q-+El4RAY5aI&I!F!AL`V!lV8F'HGZF,RHq1%kLG)F`3ZLF"
- #hm5#Ni"5(!RIr1$qkT1FTk1kc%-D)6%HF&cd&DP#@[#@HH"EEjQp$@YbCdJI5ip
- H0[EfPQ1fTHEhT&FZ5cfmf(b1j6cTabZNCk@9bjHEHjXIP(ll5m[FTQE,Fp+A5''
- i9((hqaXIIqZQaqriK64KqG-EhVUjp-#UX9XRVV4fJrZEbbe[h#2Grra(NQ16Y2Z
- q*ZR+"HDNKXHHAlT-HZIGKNA5)bfh5UhlpZf6h[ciiimhhQDqS'&Ti+e$dX(jbcI
- rE1'0dK9i22LNP,XFTNN@[+k4,*B9Yrl-21L6&cjTq2%RjQ%I[r6aLbH1Ihb`i4&
- ccT`fUG*mPI5C92$`KKZA2Q*q8EV"qR,$1ZQhCS1d4[U$j*2ZEC9ZP@kirF&2T@*
- TeT%e6@XYGqGI*,hjXcYqCM'E*qeXZ,IK*lq6l$qA6M38h51jTAA[Ej6',9cdfmd
- le[eLpF*Ih#*Gri$dNiDP8K-F[RVRaTrGF10GdLa,pNrIA5K90c5EqcEFXrmYFhf
- ,9#+0He+b2QRqN95kb&aT[QM1Afq3!)lYD-KYNQCZH(LGp-ME$lmY&DjBr0KQkBU
- GjPppq-kaYqMlJiCP[f`brhMKhDY@,&KNlVZM)9RbVT-mkqk@bTG[q1$H[G,B$qr
- HY`A*lB%)VY5)V5!+-I!b)Sl+ae@!kF[!R%d8D``2$E@C%SKkS9l[&eS",$&e%+#
- KNk9All%0HI8HY`84aqc,YG`2LMRA!`H9D0RFDa,hFUYH$5"eNPJY@[+"KmH#(06
- DFI'XA#4qS5SLV!G(@"PCA-BJb9`BmqSkGb4HAh0&jm`qrPXf"LF*&HN![Vld%V,
- LdrU@FbNVXTB6H5V"!`ImjkXq0)"EHT)9N!!V4*L6$jpYYIYlU6(i4+'X0'p5+G@
- rT3rjP6,3K,AJT$9$25)`Mf[(jm`1hN+9-$B6`3VjaVmX*V5K6`U9ibjr'm8R`8G
- QV)edLK[0YM#'mN9IT&,'m-q$8%A8Db%,AYfCf4LFC&BKZiCXhSf(h0'84dZ#%[@
- -G!lNq30dF!Y+%NJ"`*UINYkG[(bYA%!DFS2X(!rHSbdq0JB(i6KR#%q"Ek#`lCE
- ,Vl,R@I2'6Fc,Y4F9&jJ,FmIRfH9ZI)81Q,'STQ)4$!(bmp&UhY#6qV*HMdbQSam
- Ii6kTH,QjjjD3!1HGU"2efUYbMaCTFGS5Mp1@e@&*)0!S(@!ZYN"`#Ilc)%[K1p5
- K&,0$lPSX1LAN`8Y1CkKR5Dj9CkKRMrKMe*jYd'1fh)[FdlPmR)lbCf%,m-bfB$8
- 0-!q2X!8GH36[Vq&0%QaHDDkMmab9qcldj%M+U%@(IR[9245(!IY`J)&6KlCVP3l
- I!bQB$0MjiT-,8)hAFE5kPilUm2kZ!r,&35#V6lF1m01Y3cS[ka8mbPq!G""c(md
- U1VC[X0LdVM&mcK9aRpqLbGCfVATDcBGl"jVIiTAhdi&#b`#U$fVfA9lEVcPL+6T
- 2"Smm'DLkb2'9jPT(TaFk8ikkZIZ$K@dV,lqUe'kfAMDZF'bSpHA80$-,*,-%pK)
- KBJT"!&pkkIBr@#M6VmX56Pea-VcVLkICL-06m4*DJ3#UJik3!"0`mM2f3BlE0+b
- SI[r!"`l#Nk-C1q)"4@L4`MjMFS%rq&3VjKL%L0C(h[i(2MY"))D*b"10*Q)H-Z4
- j%"rD24E2&15c+MT+8I0e@(S%1MNK&+0#QDRSGAirb+F)cKTEHUJaF#B%@HFpM5k
- 3!'qd[5jRe",**qe&Dd&H9CX)%U9!ParQ+X8#3C1(BK4T9AVFGE6CL"S$k5LHpQf
- 0p'lc%ab[KHLd"5MHT['%fmrbMIAiTTE*Pmi4bB0k'Y#CG0ZE1*9QN9GYEj-G8qG
- eUS)@XrH&SRSZ3V2'kCBCh0"DNqkiEI05kF'&dVaI`ZaC)IhZ9I0'@0b@KJ8JB6J
- 5d3LK%JCH4Y4@bT[bZ+ABRTGI-X(VmC@&T*@(4+)R5ALaCE0bpJpT&AX,(JMbZAL
- R[1F3R)#c8-J!BGUBTp0M-,@BDL#TPD$+ElX!98)+`,GGKNU3!2HkA5PU6"F)i#Q
- QbrJrBi+1Jf21rSqB!#k245h-,V5@Q01cr691&krM263250JlZL`"TaM`mE54I)h
- Hb13j*"+('hpS5R$(b@mFq8DLrTFk[CX*[9d"9-CMdT)m!HibGmYUR0*q28bYpX8
- L[p0EM&)ZUR&#Nrfbr#T5(DQkY`56Y+bi*JmbdK0HD&P,25bjeZ[3bpJ9b)BTASf
- F0P1XDDA&Y@UXR(!XN!!lQ,'bdl[,X@Bk5lam0L"@EMK@)"c,1*jZN!"McA,DUp9
- B1A3iaE'UjRI%fT@ZEB'!4&ePe@@@ri-d"98Yraa6k2-Y$jb0X3lc8GF`'N2PA&Z
- 4$X&NZR+)X2TXK(,Xl@Dp"L*!PTZUdPHS&p%2AdHG[ilkI9f1S-9FE5adAYI4QKT
- QjM1,ie9faACd,(I,mBie$XL84B!ila0"m@2XaYNjDQ(hm)I4(`T&Eq24pmM4c80
- c(+9E0D)0i(6MqP9%P20Yem!#iEi3#4,%Ih)8Ma)Pq8`8!LfGVYBqQ,k0GA@8&cV
- XaTB(`KeP4@@k'!Kl&m%EYil(@K*T*VfKB2rZl5IGU5[qTCYd&"!Kk9i#0AZeC`!
- r#e3cfl-[MKQd6!!D4-KBpJ`5h(4ISVfMkaii03qXfEbj")Ti*[[pAmf!ApCYjEr
- dXBj5%qjLVPXBb%,'2pH1k#6EP-T*ahp8145JYh*!QqcTT5Fl6FNf8GN3$ECHh@G
- 3KfEiIT%,%+0km)iSmk)r-XM4R%h)cAcU*N6ELG-V%V[0b%pQ8"%eVl&K4qDeNdd
- FmjrDke600iXfHEjX"[&)KG099Zm"rdKVGC@h6#'rkDXiE3mI9,cZlaA[MGaAm89
- rVcM&GLV11ma(&HIYp[f+haDZq%aRE@hiA19S[3R"8&AMQB2$M9af0FNiK,l1[Ha
- USQL4(8*bZ`1j9ITUk`V,UThjS(S`%d5'h84Y`U4m+b(+$DGN"Tp)2@[6J!$5U6d
- G$aXE*Dm"Cfc3S%hLh4VfU9j,pCBq(%[D3'FL8a(KqGE[SYE['`IELmqT[Sh$CFX
- Q+m8B#[S1HPG#&"`S0"Mj(HDe2GaqdQF`2)b#p,5Ip'KQ#Z,iP5q93)"T+J36J$$
- 0-1,dT,*eE4T1-31QKp[EM85kaHF6AbUZm@&5,U2+0k2b-cZ%0r#46$9`8k)C)i[
- ,3fGrpi&d,TQ4[%1aD"mrTmHlcl3&+X#hIm%TU@kc%VNi6H4P%jde5MY"HmlAT)I
- rmTiP3VT'+T!!c+p,8r#!@i+dZH("[AZPNYZY(m(XPPie!qdjj`RGBE"p'AJC)h!
- 4)-M2VGDL`[aaBbIBmqT$k%mh&md@T8Fjq5Sq84CM#U!f2!1#I1BT+UNiSK`5[f6
- Z"l6-mJ1KE$+*kDq2"@eS'H[EI"&rRp4m%5J@k*6c2K)F1'CFq`Q3!*V3X4UI`3b
- E4aD+Th,C-d13!)@5+YT"d1M#Hd6c4D(F3cahL111e@3Sp`-''20,iAk+MYIf'mE
- p%MVp-"9(`JGiTeeAi,jbU-Ia%MYp@5#Jike)@8e[GjFhd,e)VKR`'D,kR!*#'Xa
- +H',LqM%hAAiG2m'Nb-!`T6[)(aLd[jhS3+LM20ph9&#0#AU+PHMNXSCJbab+#K5
- 2b##LdG#e9SE)+rAl[&*14dVl2P*bZ!*Eqi)8KqL,9`%&fC)qj!0)h1MQP$MGlEJ
- P')&EJ[8GY`4AdaqdZHAib[p4YPH))`[l6T-MU2r+('5KFMe)JSGGBcSp3PUj"iN
- Q"cYChha#223+fd"N`lkjrf0HdE4LI!Zc3C2faZ%Z"$0HhC!!X$8TE%A%G%5mLdG
- dB[Lli[G'A2ae['L'CR51"j+-lQ0N6mUACm[N3qh([TXV6)6%BMb+VL'5S'l3"A9
- IE8120V"fZqa"XaLd3BCQbHN*mb,CN@f(['2aMS10#k,GSV-P&JG6bBe[RHS4iY2
- [9&KP2YQcjN5'41MJ6*S6FG*1erY&E)BZ3S5QI)!E"UXIG&HIb)1%+UM0`m1V045
- 5SU`0bI3K-4TU%c&pKSBh*Y-R1EbCQ$j%r+Lf%Y0R@(JV%4pJc,5TU1h"p+'03Qd
- C(PBLbA0[0mL6ZSq'Ya2EXlQGL)3S-L2@LSjb,4&88b3I*'Bl@)&'pGS5&&*!N!"
- PpL1%6"HTSK*LDf1"Ghf$"4CfTqh6d+qr'eLVJeN"HA@f2TjPZI5+*j3F*)UD@'k
- GeHQG89@M)K"hT8F2UGjhArZDdr[Yh)lpYZhdAZIXZ'eRpcTRdbA[k&lRl+*Y(6Z
- UXiZ+RqbScXiTI[dlU[J02lYcLPrDU@f6YjD%jSY#1f3EGNM2k9Q[YeVDfmLIc[`
- GIlfGbVkB&0SA+9EJG#alYc3hZdEX8AHFhHb5XGPK!TQEhA,k3ajF(EX0!ZE8Rhd
- kmGejGT1Vi&LAXaIKiY'faTrCUebi!%&%*iC*TRimSK(i1Q)daqKQ"B3G0GiLleC
- 9%#G(Y16BVVCmeb@m)kl%(RNhA955G""k)iG(%FAGXYq@e[k%Ha*G3R8rM3lBM[G
- p&0Rl[#NKY,ZeIGI2m,h[Zej'jUQKIDj1fHIQRGVR)+R(hNb`+pc9ZHAXPV!PN!!
- %dcED%XM([H[dGY1QE%(1eN)qY2%if`hjd(DMjTRT-lac0e%qHQ269GBE@aXf0Xr
- APAEmI9rhS1-I)(rH)lC3"k"(+Q9FFkh99DF)$pL-q*[4qh@XSVPab'acFI(ii(f
- i&GXXGc$6*Gh2le3I8hZiCk-E`MhJ3C4DMq0pKpV$b2dZ`P!TEb#8MkQ)0)i(`-i
- bRbl0CmhbKqQKdNNB$XPr*aR`,0-K8-+dEMeHm5kQD8SHa$5Dq3MAJe[0)A6RCZ!
- fS!6AGe3Ce8QjZ&M&%NY60#i'e,e",Y9MMNLaJ48D34fpkYb**BeZ`a@0H+9F"H&
- [YI())ml4$bqh)aB[Mk-RAPj)hPc+,0Mq[j@Ml201KZi0N!!!l0EJqUb("CBCG3@
- 0Q2fI"pdCbfM(&cKUC50))$l255!Qi&[+k3qA6bLLQ`DkT#XFXV-3p5YVH4phP'Q
- @Lf5b-IDCer)qb+8k(B@865fZ*IiK*NN@)fU2j`[&BT)`cc5#R@SPAC!!l@4j%RP
- 1)qk`SV%JIkV63f,(1LRMD(E+%S+&d(fp-HcYfLEf)YFD@6!*L1")Y-PKIJImZNc
- mZHQKR5-h2"cF@ij,kZI6C*mcTCdMME$@i&[CD#FkbS,Hk(EG5Hp@2h5QqTA91d&
- @qEbGlbPlUCSIeM!`K%A[6)2i&+l%Ka@9DKUE-BfmVM&2IXK[mA#rTDBLAH(52Hc
- KPKYjh,MQRj1e%&*RF"qj9EB"l!NeEh$8)3HAbmYMajq+2@BkbB@$lD"#XdHf`rc
- 'GJ,Q8EcX-a&cM5kXYjiM*SK536(b51IGN!"#8ma'CR)R&r&T93k+EA5rB2VkEKU
- AXaAMLmCH1AjF5@RqZ2'PbZ9XKbVPBJ8$RJ$#k91Upce'paQ885SRCK$EZ@fLRM*
- Td-a3TQqUdDLG4%*&4+lU&E9QUmr2CEhh(1%bll$[%!f0)Q`K3TRfPKZElk3hi4A
- F*qh0Ga2"GUbqG5h[dlBL0#GIS**9M#[0ZeaQ1Z&E"&3-iQF#)Zjp(eRKdBKc0kc
- `D83Z`q)@#bQQ@FC[$5KDpdkk$UB,IC+K&-9,$,krH"`T"84QfRdd(5+CU8ZlhmA
- hHAaI4iHc$hE@em!-m#Mhf8KhdGfJ5ZTq%rX4ERK*#PAh,Z!"qeGifrI*-RMSGVB
- EGpMGEf)VKXLe3J1)fr&Apdd9,HrcDj5DhV1$mpK&Jf`l#h(Cjfr"eB5*,-8epj!
- !,m9*e#U`T5FJC)#T8C,DKK5dNiJ`2hVpSICMbF""9`T!+6!pZpXGa(L!$Ccf**D
- bq#0FEFiN@5-XDXe&Ef!X3("3'9!l)XBF9'2QfP5)qIABFqh)BeZHEl1D$bl93r*
- F9G%`9GP1Y[b@p`FKqqIYN!#BN!#'$RN!&6r-XC($%b4h($BJJffMPfXMl)CQ*(B
- e#29#CVJZeR0Hj596hY"kdBhG(*%QAd+RaEqNjIhc[HeI"1@,DNJ[hFX&a*4Ia,I
- 3,#)MLaZUi*U##p-H$lSG&6qEGUaZC8H`DZPd(%@R1b(Fb5He2#6MFmVl+ebbp(2
- r@M[hBrpH1mS3AP)Im##3!$fFAlM#4T4r!@63)PFhA*,1ZmkTVVX8A6Vk+Zkr04*
- 9`VfS@HYY)#1,9I[mh2D6h!IBKji%9"Qj)SVfIfpA-$Ee'S5)F-@N3S3$ZGUk1Qa
- R&[ZU$dMX$ZeU9MC-r45T!e!BZM,rqeUJ%R2rYHpF)l'rE!-TFG1q,He(rYk$dDS
- FlmMHHE$eEY`(dai$%I)G,pXJQEDqrp@SQ96Z8a,GB%h"24*3UJ2qL(8FPc(cJ@#
- eVFr3&-H1`cH0a!QJT(pZ5`Ep[-88%-i9La0,eU@4A25*Y#XDR9Lb6$bekqiFb8E
- R+Ed0(1XrpMCIr(TDlU%ppaGpPD9XbFcDB@l*bXTEFTK(k1Q+B&ST!T!!1&Il85r
- liPfH9bkb$l6-$md2X#GS$S+0H499T"qd[XSG`STB-(i!q-!%43,U*+!Z[ZT$I01
- Ekkca&GCA&hNpI1m859p%LLehH"ceQjY`(GFJCr"0'fceHm0qJR#E8VFZp(CN)p*
- `14[d%SLGkGD$0R5Lb$-hfEDlkDAB$@LM2E6qA-UG5+8E+@[3E&1Qp3I#0059aHZ
- jQ)HfG6bH%S8VfqiQDp(i)VZPD&*ii48kYKKLjU"PaTeKY)``UMh,#+@+)'H%ElN
- i1M!HZ-Ecm#P`4DZ)@Ed"pT0GX5#K2*Y(FSFL23$2SQV+i9aI*PiqY`Q[4(FU49a
- +IZ(U!5#EZSpSkb!FFV@0J8`aN!$ed-ia5Jle(%1Cc6%8A1NV"-9'"'`%"AeN)LM
- 88ibJi,B10c,55400*XUb6Zk[*LiB+A%5d)laTp%1h88A&q@D&BBda8l"I$hST!$
- GE`EX`'C'FNi+RPKR28p5)LD#1*(bU)h"(SfG("-DPF99kL35QC!!JBY$-drJ+"H
- 2+c522jdRiam"C"H(rUY"MiE&9"@6E"8hc(8C#F%S8VXNhB'l9mbB%()9qDUcH,E
- T-JSLZ@iUb5XT'9G8f*%UFZhD43*4)"[(CckiEjIe82Z"a&hb2hBCmQRe-S54$Q`
- 1lMZ`2rqi*B2[ZQ0HfG&56#`5+`@)Z-8HrqdG01p`j6#0EjMG,F2!pc2&YhI)CCb
- ZIEq-!Cdp!+,E3N!R+ZCdh),VUqV##0UNmh(YA8Jb,jiJp%2[XJeCI"B-9@l88R#
- MPX2hS,E"qMP#HJ40"8d5$k['q0SKCAdDN!#-D5R&k4'GPhVBHL$bPT%AI3(9cRh
- 'FTq6ZRb+ZFp)e5F`'02lV)jVPp%GRZiZcfc9XfT`PppTAIQ0iciCA6jRFjp6ZRc
- 'Fjr-,TpcZ!rBFP5HM5bj)mp63j9T4-dFckbZ,,l#IF+U6j'(T3!afSXGF#peXll
- ckfl[[1&!P,c[Sf!fQ9(b[ipLhJ`L5X(h88DS85SpM!3BQAFHL(C!RN1BHIFk"T1
- Gf*4S$[(Y5$FLPTa#44TdSkhY4dK-HRdEj!dm!pN$3hH1`5Zi8m)VY01#er#GZAL
- 0f*P[UGjC)2G1JhahH`VGh5V@L0QUD),Dh1p%%P3@NbdmIRXVESEFL92q@5k"#!Y
- i$!JGhZAH,`2i[X)[Mh!K3TG(G&Q%lFE3,%-'3&@k6lDXK-`"8)jMCdjT2`R,r6-
- )DD'HXHm%F6m8IkS(J%LXiRjk6Zi4pCM+pE*%JaMQq@9HScR*"I`L%J+Ck*k*a"X
- !&ELHYR8)+GM(K90&*Ua61H5&qXKGU'XEX,l1+fN[cm)Pe!kLJRH9iJiL#Hp(J-`
- mq'2bD,Y5UKi!kaCBdpc*3!3[ipMJ(I`&jLX$&0q%2GLA8FZa"CcDGGQ8&EjD`ND
- aVfYfU'l@SXBiYR2MP"A1",%2IKdl9ijYJ+h,51U+I9UAGI6CDkQR[ilK@,224J5
- E3Pq-D-E4L2@K+6@[`2[PRM-L'VTfNjGdBP4%3rFH984$1SPUbM`6)ra`qajFIVi
- 1'"cB2Yp0GAVCPf"-`1`YD-H@6Y1AYldGXRGp[+fE1a*lf'L(,Md55")ZM&L+&#3
- cU"VPBUjPUT15K*4D%e4QTYVJAbDdLUrS*[SLF3FfXEdG+&Uhp3$,NMf&UF$DkMc
- XA0!Q@aXGfmH'YcQf&iGh1!qN8e(r01M2*5("CcN'K,FimJ955ClBmM#RXG0CHaY
- R![PkHQGMqpRKIBhYim1l'Y[2#@pGE2p+H$1ME%@NdEN559#2l&imeI&P4)2[KQR
- DhX!pYRr8me*[qhk@FRS61ak61Kia$lc"Bi,51E+ApFFNH5$T5XclH8b)P)KXDId
- addQ8ccI96&Yi9+#H(0@mCV-k'rehiqRZAYRChC%pid9E0dj1ArS9A`VKU1G,Ali
- *&M6&P`*EI#G'5Y1S0M-FZ4"AePe[iXXeh0UF$KR$((-V)MPhZ(U+Z96j14X)Lic
- `U#!(h*%3Vb#3!"CFQAHrkip)h(A&9R#P4C'@HDH3!*BFB,B1fS+Y',61CS@iNR6
- R!BTMZ["3h%ebjA&Q`8illA5BaDpc$p#hGqqeZ&XZ$5("S*2@pmR)mUXG@8+@er)
- bbhJj0e3'QC(GbSaaDZ`'*Xl#8Mb!1TqPj(`JP21"Eh0'rFkmM2,!EBc'JbTX4[6
- [H(IZl01)%,1`H!J4bL0%#(,A"a!K)%(mcJJK3JqRkQF,i")%cQa@bY1&#%d&)M3
- eTGMJ!CEQqHEL'5L+ifIH1M-5i(LDGmk)k1h`-qqF1D,MD9ik-iU8fZ&ThMS$+h,
- mc&YR4QU%Im5mFfBIi4iaZ66B4qkY6Gi1pT'EDT0IJhf%md2[&H*c&rI4$!,LmeA
- ZShF*mEQEq``0EFQ0l'VBKi@fC,UL0I%!)$cZG2NUBS"P!rkqVre0K#MJ`@("2CJ
- 9@lb4PmiQ'b,Hmh9%c!1*L!h#(@4iA4B8$)24kb3%c1p141@'&c4'3dBeK+qjPDK
- TRCI*(#f04dSl'mP%Sma))hLN%@FM19`5a&1*@5aS&509Vh2H6d0'UR#Vd5L,QBS
- K9IYNT)UM+kc,`VNLdFrp1mj&L")fVeH"9Th-XDj8MR80hfRj&Pqk#rJ5AE1pLbr
- eme!8kVl"Pq"h&&r#E[Khq",GbfYm#CIDJLp&jXPlq0,,K&KJMd`(ZV5limlq+IS
- EZG!hdXEHB1e#ST!!Mk[lb0reV"c&98Rr2RcTZ[rVmTk%brh,jEeV`2peHEmIAYk
- ZV%!aEFHJbp5G2)D64d*A(K6M2RMjZ[+`Z998M$8mKT1(cI$#-B!fB6jBRF0l2HB
- [EL'S2aZcCAZ9j"XUcfHakmNTdcU@Jl!&1'K6,CqI"Hed'BXCD'&2AE[2BNpHB%p
- 61IB8(mDHiUEa[)d`NN5-!VM,fXrLC8r"'XM@YIY8P+lGL(+Zl'RL65Bl!"!(ZL)
- dq8qqF6)BE!1L!"5(jTI*%P#P-)l!M`A%fbK3DZIe2qc%R@*bQ-"1(#NQp`RXa$4
- JmTl!6S`#DU0M1h'PU'f1lF4QS$BjYRme[-@arHjrBURC%d*d`%+,da4Fc-&RqlY
- h!Y&j&F`eaaPMV+LBf#'k'+1B5hK-hYlXR9'Q"AFPH[lUdjdjYl-cIa(Crir)N6f
- #Uf6[Ibq#YB#Z#9,GrAK-X-!N[i3V(mJkmCZCG+kCpA9%RNYA1-02li-kX[rlb'P
- +j$lZR9p((U&%(R&kaqhV-6G%RS9NMqh[42)HZmG'FX,6cL"NK+m)3YDpQqjRK&m
- 20NmA3SDC'8()k0UCX11Aq14Y!aBR-EFLNS13!1PC5`JCAq[G3JLCcE[A"4%"B%2
- [Nk4dmSmlm6#k,DGTLUX,3BU#a-5ckM4@"1,'+f@X+,G!(!pCB,234fH5Q'3(eH'
- qeeM1RKPk6!JIjfP*`F8JF%E)4[Jp%k10Z4PhHia1DRaR6m&d0T!!@d*dKmUED[(
- e!QCDUhbCUI-Qi@rG*rfDLb!"*VV*)@D!Cd9lcCNXPhX4NNTjDVa)YPV85HrM,2G
- QA[MQ3JPQmPiPZ@-FZC`0hGT3ak&+&5UcRdIkcfaCr)P)BETEIQ0ILXHq0*h[5m6
- aU[BPPkCcTaNKX3,U#06+64Pb0VkZrQ)%eHkJ&`eT`9rbEXYfMe3[I)JaS)Zf#,E
- 'F5[lKE"PG9Ka!mKE9SFmYfQr4(9LFiakAmfa$Z+k*6YUdR&kMU'@N6P'[BM--B8
- %k3dS-EFLNM2(G!r3("-j466(N!$N*fZGA!`rXL$H`*9!'@J5l!#MH94Le6kC-b!
- (3K@0b*f$Cp#N6h(B6Pd-DHBRNNY0Gd%3L'X,V3VE6Ym0m3e`j'lSBHAk[J0C"RD
- 18F4@V6JMYBTCkQX,V`e,eZ8lS&k*9Gb6r4+VH"CE!U[5cd3)VmUBK['Jj99G&a*
- A"55R&T@[j6)PV$T(EPc[9Qmm+*VQX9T[pYC@J@@5Y92aV54*j`!Rb@b(IN1a5q2
- 3&cICLPe(9fkPD$IR3kY%YFpIMmYIG1BcZ)*P85qSjJ[0Ur(Dflb8hqE5M4JKA(4
- &KCY5&UGaAe,"%&Ll)DDYqf3la2jdRb$'%r!+,J%A'$%K"*ZAQ4+'iP*lXc3"iTL
- "VL%H[KfPL)J[A6f3!-"YMJIfak!Ep`6GKj[["Bqk&`,ah#iG*QN'"+5kNdZ+Pdj
- HLPj,8R,US*`Q#XJDJNQ)%`)bZ*1D&i$Y`JeCNmcqYM8IhYeJM1K!9ClK&r)T*)j
- NPS6ickb5XX!56h%SSr&XBki2V$"J9[S,LR'R0+')0Z$+4YU)5D33SF[NHBG8!Mp
- %mp)@@Vr,MTF9DHL@i1p*5Tr1&EAT+1Ab8k`kFFjVUIE#dk'ZQh'KLfli'[844D3
- pSHeQ[(JRD9Y*&XU#I0Y@mJlp#VVH['bq1GGZ[V+iU(K#F8JL%M2&Jd-9Yl,%q-J
- b@3jc,T3N%VLcGB%T`5jP%JEJmN3DUGGBGNMA5c+$[qT"pM3135iH)DL%)*(k!8`
- "+#&S9h*UiEEpA$34b8VL58$+"RTR3Fm4H4Ed(!)E$fC"$fC"$fB"VZK%l(KN&[3
- FJ&3ckQL5bRbffY[8@eYcbEU9l[[*5dZ$JAGEGc&K-&0MiDkL3XjTSV%PdlE)h5m
- e8V13!,KEYdpMN@l$L$b)"X(&FY(mQ3*9'+,lfiQ[9D5rE15cm@*5c`0*(dVm,14
- JKAKRd3dbH%9QBqk3!2LHJme,(G1SBaUQ)K25mk#jD1J+QkXPPB!)I(FNT$h50J!
- "+KhJRI96cqcQJXD9""L5k(8)hb2`kD4m80m$f'Y*`'"lbr,L*6DlDj8kp@rQG4,
- K&1SqQLCqN!"A`mYc,qB4$mJX94Yi[#NHCjQA4MpqVVM96HDh2rrmf1HIIrVjj`h
- R([[iib2(MKipqZa4mm''Ac5Xq[$$$rBfA'Zqq$2c`--($Vac30Veb6(P0kP''MI
- rYLEc!"kDSYq#`)H2I[bafAeNHd2erX05UI3&46TiI*9dpH($$jJrRE2q&I2Jca[
- Zr&bkc0bh5ET+ZX9mEX-PpdR('[+N&FXP2qV`J2N#bmdrrD**ZZ)Qbk!p$4XDKKi
- rH2"J`c8@VjVRMr'rqKI(2MP+Z4hq"!@C20Tbjl[[lGflGdlIQeG+4HCTaqRhmb0
- i6(RjTie08Y'VN[8&q[c@6CD(N!#$r0ARkLDeT%MQm#G(,9XESKXQI[MKHqmI2[b
- jpE&hhRRRq,[[l(f[BF#F`cbl+hPfq"dqHYbmTNQUI%CDr2ZA2eLc9#Vjr5mA2l6
- dTZ0h5&-A0+e(Ha@C(q%pG-f9&[ZED*rbqk3pjJ1,&TZIDPKTR[*TENV$R$PrXGc
- r8lrd(SSmj6b8F2++KJFXKQIIRR161IVp`pEe$BA[@C+A5Ep"0SQ@U0YrBlPkl!a
- TYH8c5frV%!Eplh'lk0i4,k2h)Fi4a*S5#%-aTC-G`KaLi8P'cjB9I'k3!*LqUE)
- XKEq,H5Z21I1rai4AX1A(&20'@9#-iPTi2k*SD5$aBK!+`bT$)'Yl)CpBdca9IXi
- j91kEq4pjF1BFGafU0F9E9k0`GEmEdmUEGfKd"@)f6P3C[SRh`T3rJeKqZLXTB@$
- "`1eKp+i%6*6fc99p*(EdLZSh5!F%E@VJD#DaJE*9,2,@MkYc3YGCV#i1Gi2bSYf
- '1P"Q2k-URk6BNi%1LJM#RJhTdD04SCi0K1qY!2dcbjpQC[L`hMe8BH5'H&('542
- XjS*RdS@`eq6$V*ZB!!l!E6*,0kie#i+Eq1jI%0b!["r"&qa-9"A'&frLb-CkA[9
- YI,FcZ%Kfc$@peiaM!GXKfdjTMf8RV,HEFc6`l*a!qb[Y`0ZD&h5`8-h1Xa2l`S`
- *PeYNlLaQ'k'Zdd`5FDk*bF6b)$`FX"cPi3KNUM`FfBkK#JY(AKF,4`TRiD!i`X+
- 4lH"i'l0FC+[lY$"#h0c&1Y&cL'6!,XhmjkP$(IFC,J+DQ$%2N!!)D2,$$XT6m"B
- Zl,Qm[Uj1C9*AV"4+N!#9h!6*p2#NFBB+5-R8eEL*miYGFYPhNDf,S[lB'jABPe[
- 0KGDmm5(1N`aL@8p$Mk@!Y52BMl,",XZpYZSrHLd6f#*ar!PM)(&i[-`lDKVGrZ!
- 'kPMh,HEG"m'm`1lRF5B8A"ebl#fKf-Z42eMKN!"Gk92l5H`BYYrra'V#c#0Kj1P
- cpe-i4ZM@FE(#2c+GqX,Zr%NG+PK5#YZ@b@aZQXL0ZZ84cLJ5bXAd'[Z@*KE@3,V
- aJVHdZ!T0*SiDaR56jK&H9el-ZrlhXDhRb%bGX'64$+9BX+84lVYe2m@U+XD&G#C
- *)(,(QK*b*ClP'Q,jLeX0aL*N+DaVYmU5N5UUD["D@U2`m3$E#`#p53,I#A)"&ca
- Q(rSLk##[J%[MMm)F#+ScGKhU1E@JL%D)bI+'kCm*q@dKGk3P(4hK6CJ0qX9!i69
- TGp(1GFRih$al4aGBBNma0raJldd$M[X!ah&hJYI*4cS5)2#c'&jhbahRHb&(Lca
- 6#PIJ2KDS%rDbe5&Y!a3,f$U%#*N#,cGLpi)S#LM"ZD,-ie0%qN)23-Jd)iUQ`0L
- hSX%hK@X8*ILAK9KY$lU5#LaZmJe(F`&hP"R39j*XfED%iVEG!"4abj!!D@aCm+4
- B!N'qe4#TU$3Bq!l"!rG[PNGL"IFBD8YPAZ)cT-X#UdCI9'Xd%m,p'p9#i8)$HR8
- bZF66GfX&8BcG@djA5J5JiVlh@+fkU$,r@#YFT-bb$mc4bFSmU"G4&2"XGj%82a8
- VQ5kC)#5A[15HB%k4c*9eGL81kfH10"*ce3U5Hq9h&+4$6[(ZI&NqNQ`khGKdJ&%
- R"%qi8N4iK)X0c9!5m1FXb8@h%KfUk$qkGHCi(5e6X!&2p6h"ZiFaYEZkZJF+#%K
- DPphY&[YJVFB5,`SPFff0VQ-8qHBVD`!L%#N96i@$bXCl%#prm!MfeF2i[JPqbb0
- !mef3!(Y,V`lqJZaE[#$fPR#kV3*0)'bqHDa(6#SBZUlG)A&VX-d-59)TN!!GYJp
- E%50PK!9-GjC9K!3M$a+3!(9[PS6$6+iYjqVDY-SAM6HJ#m%j"4P6hK9!$r(eKMG
- Yi0r$9YL(3TMajT*9Z#4icJjTe*e-Zd1#A2)f9Ir,E4"be9S"JZ[PcKSleSF,PHh
- cIfEj(0#$rMbrA1)XphNV[Xd@QaNBYCrC&Mb1eh1%p)MSUfHaXa&L-AQm[C4QZ8)
- Xr+iBmU)Pc2&US+fl(6TEYVHr89`Npij6A@X@$d+3!#m%@NZqr9@fXckSBX-NeGh
- --bk8C5L8THR6-%Dd$bP'RD$%S1FNVpP"AV2$(69M&P1U"G$j2CGJ(KZD6)Mc"*H
- 8rj,CB"Kf!mqS8rH6c59ed)Nh[kD#T,j)L@,UF3K9`53DC[f%#C!!kdDFGLRJ&8l
- ChNIYjC[m8%N0AZ(q5F&a$hA'RI`K%b!QMUc$N!$&X1daDKEV+BXV[,MmdGFSj3r
- Y[&VKJVX#iM)@e#[U*mMR"MpdkUMCT%5cFB5,R,-805Hb#8110[Z*d#l,Fce*NjK
- D8q1VNE@)G,@V)Nl4MF`B4Qb,j@RYN!!14PaKRFaY*`CM(h2(+'mr[8--V-,6XF2
- f+-+*hD9&iE[jFpIac5hJ6U8)*0bb@r%MVpTBe8Y()br@`b5S#I04bXf@MN`@[NS
- %3m@2"p&hke*`6Da"*VK1a18$Emc!$8CLEk-lEpaA-6-X)iShjITicIQ#Kfi%@4K
- NN9DZF+bqr%Cp8aaa@GPAllLq0jLCbkjqpITZMNLmrqVkEKUV0JK%XqN$BLPK"X(
- 8GE+HLYTXUT+eiCPe4)e)T`&bec9I`$PK3LipAF6-EA,djc[J$L@qZBZ+YjEGZ3(
- bk"E9e(5)mqkNA8XBP[Jf,U&0P9fAI!G8BJDT*lX8jL[B3f6[l'$#)QrbJ%61@dl
- Id$2cZRFUZNSajR9#q&`RYYc1`i6PGG,HlQqCSP`8"Kh4iBY#GDYeJ,T3hfZ*fL(
- C$cEPPp@9HDaPN!$%dQMfU*1[NcE#%jAdRkjNi(p@NY%Alp3K"95ccK-GpF+d828
- LaLRQ'['[jR15+f6A"MH4NHSmq`-#eIP$YFm%lF!Y#MUUeN!-H,heSAk5$VSGLS9
- D1DAjY$*X-(AK5Q&rD+$D)$1k3*Y'd@k"ZU9,A*FlUa98V+YMDR5G109Vj%(XkdF
- VpDKD+F)Q'CQCTmk',N9qDKGQ!r1GiVVFiR3K6m)j1"TZZSp'#h`6$Ah`rP4"4d#
- 4$9JfYEUG$HEDkA4"UAX"2lrj6ZQ6*G)pZIC(0UjjA*S!Pj1P&kecAQjDD(R`dk-
- YAdLP$lkeF2'M+ij$H&Zl0"EIhrhJciJba,ch6ZNhdQ,*[PLkI,(P8HQ!j*5++)&
- JXRB$F5cJCI6JkNp))a,fL9$H`3rijJLF1%!A[ddaf2BbJ+DH($28b"iEbU$!TFV
- kBiA[8p30h3+-ChP0BGkepA4)S543Kk%KbaG@H!9%T1G*@H'9Rklp$+iC5QjJAB2
- TDT*aV1ZJ8XH($5U14ER'bl%69Q4Q&d#l+bki4FMZ1Fdh!IH1!a-dp"Z-`Dm`'iT
- 9TXX[LP&q2f(Nh1H,4p*9DDBM*B&[-i'ASDjl,5lHdYAFN!!$lhkq"6`5T0D,k01
- EC3Q@b-Lm8H#EE)GpGM`6Fj1+8h*65RFp9l)-E+AV$6&-G"[`5N308eJ2Prl*Pjh
- l(*U5C@Fp2H3*5jQ,iUDb-5j%N6[KbZVpc`#*@-+CM2eZcD3PT$bQTLPCM`YXdFr
- eB,,0N@MSJca'QUb*PphmNRfaU&qaQ$EdV-[@TC9BH6eZHHTPjaXNAKekC5S5VeL
- A*ZBQ&PXbF&9EN9a-rXLJe'dJ[YcGcj8d2EA9HB#de%$,639bf[ei+`3d'iia-iL
- ,)Zkp*[2"r8e*IMfM$SCI$Uj[Hqb0YRMA#EV-$HHQ'i&D2+T8c@283MjUR10j942
- 0ZZ+bQPUjS@K'6##TJ64T)-)qJ*dp#!D9PD`5)P1EJkZT`dVL,!m(li@8miI`IJ!
- lj*eqFCf$p(TaIK!(5(S8bZKUj@KFi(52$,NX#%([mjU'&!6AMmi2EZ!jR%ij31h
- AAmPC`2+-5fr+2J"0%XC'k*6M[)`(Kpp`)3NLGY-9%$+Ei1qfhUiS#T-1A(qp-20
- [&CXUCijXDll*AHTARih+e[!l5P+c0N1j"Rq0r)&%MpcdF,#`)MBP,9K)H8cCi6I
- +(&R&ZqajMLEE!PFNVaRf"Le-m&DkmB9-K%Zm%hfHqQTC"ZMYB9jke3RhMlB(ek-
- l(JEZl!iqMqaZpdI*G@&p@AjqLr"3%%bJTJBN`NERepCGlU[)K56!@9@8('AAQUk
- G`9$ccIMHbG&5D*[SUD%X@f+KA)#kpNDr5FkZ(Lcc2A@%9S5BULd2ZIU0M5DYV![
- [9K5ZXU`feeNl[FlRcl@SNJSc6-6,ULk%3UKNNYZ%[4dX()9mLXI[b@4aZ)RJcJS
- SrIQ!TBr"qQ@cdXphdkAZ'V"d0C@9eeSZ8T!!EXBpJYPbAh2e@dI$XkGp*SRcT9Y
- 0%ZED3AIj29pbmC!!fi24LQ)dLPD"bq!Z0hMZb"Hef2jP#Xf@r4jj!L*#PKfm!eT
- `HIbpI2,m$9e%Y2c*%BQFlq3ABlaaE&6kPe85AD'Jd!mV(IBi[Nrb$U1jm[$DEYJ
- pd$Y&$`GI8,YR!lVd3Qq&f[`8r5QkV++YKI!mp!pkTh`9*,K$FUV`H0-QCGDqb*q
- 0RRd+QHl%r+)E2CTm6b&1D9FF(fE6LkiYI2,`C2m+9DkQhZX&S)-#PXp#qCV,kZT
- Vj"Pd(h8`ESkS#N&8)40)AID3!1UGFi,2ih8GXQhD151i"Dp9`9DmF(q'9fY`%el
- eK1Xq2ih`dZH[#6k)ei)JQ)aA30TM3r53!*,J[G"qi!NfSeCPrPU[L(VGKjP-'0j
- 6TQcpKFeabXc'a60I8Y'0"V'-S+U%"p#f@*6G26BFa`K3,U`N$JVkp(j65,[RikF
- b-ME+SXD4%5%Fm2BD1lc[4)@J(d"*lA`39B(H1D!33%r+lcGPpcJR&+X4+18N$A0
- 9)(1kJ$S[e'deMQ)Pal)b[lm-PNH4C9`SFM(GCQbj'(+9rF%hBGX'I2R`k0RMVF%
- GIK'pr$`Q4PC`eqMFi"ZB'VYDML!UZT[8'8U(Z(@8#haf+$kSSZQc6I&"cUC2Tq+
- $VM&p(PCm(P4pV*RfeI&PpGlb5Jb&5k[U+[0Q!+1Hl+d)Uf(UHCMQfrQc#eJ31NQ
- i8ri)hdGNpZC1ME)YKIMF'BFTqa#fIVTH'pMl+I+SY1#MQ-2V-jP*5jZrc-EE5"Y
- ETG-$[)N+SEEkRKH)mhQ&!,k6)F%AVbI9&,Z"(2H!)%F*TI@ZYG0pqh1N5mV92[G
- 3F!HXcmXUTFKD+C%db`BGlYUI0q%EeXr&cNKHp55Gq(N)ZAr1ERha%,bRT(0X#S`
- S2RRI,X"lbm9mHracmUEp'4[(mb95q#,M18amiMlSf8(#@(ZpLI&KNaNb9`NVNhU
- Y%h06LMQ64SE$B&m'A'')klKpQGek*[CMjQU`R"V4a#$bAHclfBKD'hmp5CbHDZK
- (86%aAJ!(a`dQaP892Pqp*fPmm[L5TA)QieRJXN1A[5EYXGUYMY+5*@,ZNfh1!4c
- P51FS4`TH3cML8FB4MbcA'q44RfM56L#QraID@N&#EQ#rHXi9@3)0TV8pdBFZ#0J
- RKL+mX9[eZ#)TV`AV4PZ$E6`6Mhd*5I6XV`(eEHe%)"jrAX&aNBEqH)@4q6!J54j
- `A39JQF$Y@DjG&)%U-I0X*@U@STj(+p&`hdJYcm"GX[6*2cMeR2YPYRh*NhqSL10
- 92mbVIS"AR4!I4+Q,i68i6$@!*e9&%"qT"C!!0H4!-5BS'JUpDG&*PkQpl'[%I-J
- ldlFejP@B8Y,jQ%@lcXk%q"AQ%ZK`-I6`hJR[A4YJJdV$&'")Ick8V[N59c6"paR
- (d0NND6Y&l[-LY!$0JTFEqDcBA5*YP+VI"3jd`FeY0lp3XPL-STM`h%Rje-F5ATa
- PZrPPqq*AYh,ITaeThqF6cl0j(GP886B5$aMT6RahKHUpcXr[$c4ck'ED+M'T*pH
- 3!!k0DPp95*3YHDmECe8&#Y)NIj4`MUSK1frJb%)MXH-BHN+XIT,GJ9M0mZH5VNT
- JH'0f0UNBiANEa)4N8T8!(pjikITjQhVTH9k@Q,!)GjVN6IE5if5(AMd[d)aY-[i
- L+-NA51NBVaJAHPhbjGVHG#eZ`TU3!"FV$D6iC@XT@f*$kYRRek!Dqq6Fe18VFm1
- HGj*L9-fAHG"1PREH)'ma0ikc9S8dFhC5YD($aDa-f@4C05EhcM)!+"I539!c6Ya
- C#B*JbEk0d[JGZ@0D(T(f5R4HRb6GCBjqlPhcm&af8p2D96rRHX'Q2Y4dSpNUr9`
- UK@$6Yl40(#PH"eYVk!*RCPjTL5S46&h1DjbTPK$MBQ,Z#@hV#hbCpJHk@RfXNL9
- @[iYEHP)l#IkTZ9ZrZM#alQQ-[Ibf*1$@FlQU3h`[d3YbP4NVeceh5jR,9996M4Z
- #&BV@`46d2EM85&2-UC!!kqYba"X%`MMa1Jr6hm9'UhJlGp6-UYTDTkcMaQ#NZiE
- 3,qa!0pYkZhXDHmYj0"f'acUEdCeQ0)BmXSbp0aMGmH4KJ--[TAI"A'CQiQ-5Pci
- ldViB%BHkG6DMkc9EEjFHEeYUmcT[1CeG0FQCGh'&CG3p96(b*T!!b$8M3PY-*V,
- 0RmUL4SEj'SfVK6L06M09Xe9c8Q[8*Q[(D#GTDl6,Y2GT@l9[D)rUHZT5G-0e,Yd
- Yq1k)-%Bi)MC%JL$&kiqm-r,Pb"2G8VUjZUhUpR5hPlUpTYIT-r89qY[dVIVp84"
- mqq[H9Hc%Fem-pkjQV1),+5"Nh4Zl1RH-lfAqJM"Si@bND*jGIS'ZahdHbJkAVma
- r",9-m9#&4XTUEVG`-FbiX9iFm[A#&pV`bAXSF9#ErXL$p&8BDb5CD8TG++IK(V[
- -#&QiR2%1Ia"AG%Dh%p"VbGSESHST$1aZc%k1h5C"maGZeZkN1`6dB"iLlEE"AXp
- C%j-fJ1FAQJ@IAlff!KbjH)H,)DM@FmTkC[(1@a4VGBGR0I`fUGGLFPpc,K4,L)8
- C[ES6%5RV#Y)M"&D[EP*b`lVLl2T$#Cb,-d@#E6*K1,+Cq,GXj#j&V2'Y()Y2Gd-
- Mfr1hC-$6d#MChSjFjhk6Dbf,I%eQrb,qX5iZa,kbqN1rSP9QeP8b#lMAVd'NKq3
- +3p*bYd!jXUhVT'!)f6T)fD@b(4(ipEV+XNA*l"SeXjRbe2"LHKU4Q(r2Vk#m5,L
- e'4-DXU+6!6l3ApBr$laJ-5ah8eja$Y@,jNdm90MSZl5BTh$Amkb)HAk,Hr+mLhQ
- +NKh'GQ1HQlNRSp-acjAFNbr*BTkAFFq%VcfKB45HM"r&221iCq,ARRD[aB-MqLI
- cj$il9f16F&r!%i%k#AMrdIla3*h,XHlNZ0+Ak$XcfRf)X[hc%ecA#[@qj*0#!T!
- !1FZ8MPJV6dq@,kJCANSC3Mir64C2Z2r"q8L@,T`i+JXdRpRjJ-hplr*4XC%2e86
- b8E9%2ULCcSIiqAk66p`6SAaS[NNqY,G)2RDpijVqehcU3[QJ#e8qd!+SmQ%Y1bU
- INVr2IMAE0f'fPh`cff9lF02pjNHp$4RP1Prhe[q)"MRGCM6Dj8p%ZlfhPcJql@L
- 0ra&Y4%Hd#Im4EAK(0,Ue24BY"6UGZMZQ9(*S5L@(SlYfd%4l+qAd4!Z&BYR6&DV
- 8%1[)b9#X66c@H"jV%f)aZk++"GRXTJeDi8cEJRr89Xp"-aVYIe"(3,jJA$YAZ9D
- fVDQKqNM2ZqKHmI$ImqXk5Y09jfIX$1@h#4Qa$PA1cl6fjQHXSajimrMTIVNVe#p
- 3"DDb@m%M2A-kdPG$N5"T@N@DcL2GGlU[cRC!0b2heGN1E$q)F0hT#&paB2jbK+p
- 39T)0AkZ)`LCFpGH(Y,%@DZ0)iA!FX'B@9`h-*FX1Y!-CE,!!&3BqX!(G6A+U'6&
- !TZQGQ)'&&lMd%)H16P14XP`N)CXXfDiBA"pZrh3Uer3LedN[Kh`$h"IDd)$4mN3
- !dV'6*IVi(Ja"qh()T$J8MIZ1XB"XRJI`KQM052d92&FKVYmp!+mKEVip()da@r@
- E#GRGcbq$8NUS`UMR(6164cV4$@m@i[T)qSUMi!fTpiJ3JJaY&PB1K!YGYY`hhDP
- `kG'&2UlPA,*HRae!8cEm8!#Z!SaQ!cS`p46@3dL2k0"&EA,#0H)hUhE9Z!V9%,G
- KQ!&d#9k*#b@PQ)YhUX4pA-Z,iCLU5NF2CK8ddK@A-4$pbTX9pf@f`hJU`U`LA(V
- e!(HF)PmCiYlJP3iEGaNk+iHk[fYQ&Z,KiJ`FScS,le45L2[mXVA3%#ZUHYEAJ*k
- %CjIFKR92!VTp*rLRjUP+CA!0A4FNc8pe3@a@hC1"LD9fA#5cMkP)$CDB)M@kKGL
- "I&C`VZ8GmZl)&5'&DS6AY#+$1Ea[klK5YFImaR54VK)RLX$p4[,T5ZTF`F8QGm!
- Y!K$T$VQre-dG+`Ef3J81EJ$D$9,`G4GG@3!14mip2)1,ClP!%E#3!'I339GZqJS
- ,ZH!U6H9#6(@mbhJEH5iG&2X,9[QfD*C29Erl6LPa3e"2G&l0Ah-))80R$&FlSp,
- la56Bdm+G)M()MhUNFc*e$29)jf3hLl5E$jed@3qGI*!!ZU6649eb,qq56Za`RII
- KfiE)Xp3ZB8qSJ51[cJG9aF%NXe-V$Li",fG2Q`XXlY&BQ%2BfJ4GT6P83KGK)BV
- 4M4XbmNUiKQB%kqN-ZD'Cm#FYj)Y1h!N%+!MliiTpfq3LB,Ze1GN#lYJkMm[BEC`
- I&3@c5%-qm8$mC&X)K5Fe4F4+5T'[j[(%eXSj`hrkiHZLh[LkLr!-(@81h4XafZZ
- [[J1C'K%a*ZdT%HV889[2TCI*E`ce+$q"TSbM@B293NFR&MXIY%S6LjhP0IQ`[T4
- Bl,U1%ppj,#IST1R2UHZ*F(3)Djq"1-4SfKm(DP,Y1,Q)3ibPrA(U`R%Jh*fB"+C
- 6$ql[UIKAb$fi2d'aMjYFe0N6fC@DV,"Dl-l$H(P2JYZdmaLqp$k%ld(%CaeH[GP
- hlZfU%[YlJIE-+J+,8p1"-2H)%r14VSTPS@)j['+c&Ir05X9`6FEfkf5pX-b'A)-
- GU$)(9hK1eX4Mbh1)*J5i'-%,"GjDk"eU1M$Mf`S8fA14G5Dii6c9i"RXK!+ScN0
- I9G,R4qh"UGTj[$P),phGi1jS1X!9CICQpXjVL,JIhPrqeR[Eepfb5HN9MY-AmFE
- 1AJfP!(%"+c#LdC9LIl3jTk1GV86lXfqMjCf10Pk*pUe[SR@Fl+SGj2l[hrjYR1H
- liQ3McX"XlAL`D`S%dBqEh+4EkG@`Aj&*hj0BU(PQ6cXcArHrrfeHXj!!59TRCCP
- amREDM`TaLfRj3Hr2lGr0l[dKpD41EQmIliaIPD+lQR+PfI96BLHR##r)XqZRSQ,
- reUPTLjLIj[(18[c[9q+9+rBl1Z1K,e*jY'V&Hk85lA,&[[Kd0+P&Sq*GT86l[')
- [R9`8ZU+"e2k1[I)1TlGmNpq(P"EcjScI5HD,(ekkiLET4p*RRkLr+@R5QS82Q'q
- @p[fQq6(%+(pNSI6k3Z[KYMNRjfKHYcVDjTbJphPY$5dId1qDAqrDYHZ9KSaATEH
- YYrrQrZDepperr1'9YbbeH(IX2(!!!AldmDX0[phlc)%$Vrh1-R*(3dj$lpFX42i
- BYcRraj!!LTYdYEDB*&2JCA5298qr0PaZYYU,1Sqr$&E$(%D6@H3(Gmq[X@c3-l[
- CB-BbZ)mLVUHM0GcGYrV#STFc6GN+Z@"92Q4a6@042T!!JQ!PZNKGpQYNQ+A(Tmr
- %fPSqL&05ZPa$6IPURPA)%c*m6(XBKhk3!'*ZfUN1*,dY'V&qF2J8YcKIM(U[b3V
- 2d8ekGLS15h4VSeL@Ak'b22MEX)aAi)c#%"DGc[q-8rEXiTNiLX4C,H""b,q$1+0
- 9)-pLHBYClKQ3!'b8$mZjlYPi$A(hr*(N6S1!J6))[+Ybc,CCIC'acmHq1S2&RQ5
- !&ShRZcbkiI&)P`H*Lph5j6%%(KZl2"*2jjAPm-$ZMhhqHS(%[YGH!jpjMNP8)jb
- HRHY09La&eIf*eUSaMZaH!"E&Z[GaF&SLf+hA#ii8SRHSbRAT+AVUUilif1GRX*+
- P$L11@qHj3%f1(X$4AHUVpU@f2Ll@IJ`jZf1IYm5FkKE)kE1l2pCCHGreBM@*1aA
- alFZFmU!4d(%[NGU3!-Jc)QN$P3e"EiN!9JQQR85d+2C8N!!$A13BkqD)2EXifDB
- HD5DfNB`pib@L4N0rp,JU40[+2iKk%L%J)XKmY!)9"$m%R6qppbR[(bY[8-4M5F"
- j5-m"HH%"[,)r6+K#IMU2(*Yp+3P%U*fNC0[Y+[`UfiQaRB[Y6frpRjPPfTIJp0!
- )$[mUUeK(j2N9QKbKrVQjeZQY8&T18rN5%4[*9N6A"@fjk,U+80HPQA+lZXjRi8I
- 34R[BMl)%1Bh"hN#YKf%Z*VSRBdj1KlL(-PJ[FDIJGDmlPN[#R-(R65HV`[NiK*S
- SkfKZ[81acZ2@GBUe&GC9LUdCYQE&YKbf"C4aZ,Vh$T)"!,,8#@iGCYPdLN#Ha@b
- r16$ZA8bprHC)-c2&2N0HS(IXC"$FA-cHKIFqH,pqaYYA)%9LJUDfAQNYXG)%K1#
- i+5c#`i)$U2kD4Q-G8%pVHT&)Jj!!L-9mGI-9TbLXA%GPB6$C"Ic32qL!,#)#pV!
- Z!dcZjJ*Mj%L$41l[YP,(GlqQp2'"pPd&k$"i200bBpL(TLR&hAS6Pml!X(96-f3
- c[%#c8NQ2HB(,8A`"r6I#E82r%Bh63i$l#Vl1Be-(ECbU6!G)XQPfF'klb$HK&4Q
- m5[4h2&((cm$@&DeQei-r*&$0fKPFqXS,2LrH3pTImlJb8Fe,V9hj-[RGrmaAabb
- %8!f$YFcKfA2@%0@k(D*DAi#S9Y!$b`PL%SRkJbp1#BJ`lAT(p[rST[C0RGe%dI9
- 4p)fAKhIYGbV5Y34lGhRiD`P!Y#8!Zi-Gi$ICNm2JYm3J2kD2K6ak!Eql`0MK`R&
- reda!0dp`q4NV`q"h9aeLi@Lq#i*Nhq&b`cAih39bFI,UHPS&[iPF4B2IjdYI9(6
- #heDdA[LE)Kd$`0%a%291(Gc96Rhac[8%Crm8SLEkJ#4BipDLNL5f)af3!!e&02h
- Q&FR`pNr[13e[XhF0+(qidfir"Gl)XF[k@N!hGYIe6&62i5FI2(JI6LVQGTeSF#r
- f6!-T`A+FCD$2c+1-ZI`SSb9dP0&#e,kSbbVN)0[NUSkc$!*Cd5YmRM'lXqGk0L-
- [mYUK(,-dKipCDN&#26''T#*8J[behaqEI"SbB!prNQT43*9)cb$Nakjf9a[K186
- hYT,0C[cNSc2[8(XE1M2Ve*EGB$bp6Bj@MJCHa&(40XGX9)EN1LTj1h3N8X)FFAD
- 3!-rhqc(4"RC,(*!![)*CZ4[8%MZ6SbM[#`jpf3B#MLQJ-FPb4k1HKafkZ$GJ"`N
- *$[+RZ)jBqU$hGqG%)ZY@LPJ$1R,+"([C0&6$#-i-#B0S)G)b,VCFP0![*(QPGaT
- 'QM95l8Gl$lljDqP!Nl4(f[Ra8IJ10qpjeEaeDm22T2d09dQ[!A$ldV*9$dRMlMT
- mTj42!H+Xk6HB)4h$hedVN[3J[)bS&e4dE@-acPH@ii,&)EFik)$BY*jf,XSf&E3
- 6Ka3"K!8331M"AJejKCJB)'B'qA!,a!JmTj!!UN,04'[C9"ra##),L)(GHSXX'el
- Sd%RD4jA%$qHH%S[jkGa81MrD+T0(YP!PPRQF#Me#cfiLE!0C'f0RLGF385RYTN3
- 69CJp9+GVD[k5#mLF3#*8DDB9CZZBJ69r5669L&+f'AQdI3RTqN5$$5(210Jbp(V
- ieea3IA!Mb`FplQ)3A"&"EL"i%Y3jhEIKC+J%"00h%Z'3!1HpJKVYFmmp*RPL4fV
- pfQHHbfClmJ1&"`VIP0l0GaLbG50eleeHm,ZPS#XZdUh)$e1L3)3'!140H9dH(9a
- qa64d3bHAC$'9qQ)L2ljf(5F%4HpSEJC"BFLIE%BEk,JjKPX-@8,b1BeE6`+Qdk(
- aT1e,)TFRUirT&M4rL@eN1prBYi4l!"XIk-Z%SK,C[C+HlBL)E83[9+dG'0i1@EB
- dNk&)0ej38qD[j0hBZB@SLiLN%A-h&9dj%RKU*NI`)0QQkfP)YVP8B[CFB#ph9"m
- 55h()ji8FP8Fj(Y%0Q56VZ8p+,X6XGLra4@,6Aip6F2Cj&MDfT!HN%XR&6pcEETJ
- C"6&rb%&$kQ%FX%!+6%Ac$@Hm'2J(RAKEdaR2%V![6Y3eii5MHdEc#)J'+@LIdIC
- `qrAiATh1QMeFV-`',V6P1X9k@8QZ@*TBDVUBp9`"D5-3HE*qY(4b#a&1G6eYFCX
- Lk&#KEC%TBB2hj"E[1T11l0M3,X0h!cV["qLZZd*l)&XmDfd2XcMUdBBNR*HPiD!
- 3,m,f-,P!$kET(E((h%&8J*LZ#DT%ii3j*Ua-$30b)JZU$j&`NElF#*'jp1(JE45
- 91PPYUPXkiY+N(SKl`D(f9AarfUcN60+5cB-j-rkChm@R6LP"Tpb*6VQ6Gc(E!l$
- l#''lpP$l-LlGC52kI6R`pXf3!#LlR-M,ZeHJmVl`6(EQYCNhB52[jLd6($fh((%
- qm@h20E2qLN`KN!$*GJ)0-2USU!2LVJHbY1NCe%G%3h3q$BN[S#0Y@k$NK11kESH
- +CRBl9$5c""62L(UC@$S88P)f5b@b9*K0U+ZG$C6F0Q$Zh%"HK*P3rf06UA4N!CR
- hf1IEmcDLBaXM1I%9b5INDMJj91Aj-0q446bbZ$lC4[kBR"["i*T+X5&2d4#LCa,
- 5hmchp"kJC(i3SdhL)TEG$X0-`9'+Ec@qdc'eTU++QhXrM+0e``i42IqcjlPb(Kb
- 2VM[648l0!ML@a)Nc5-Qk9m!@J!hdKYh,LGkXHmArRAr0r&![q(JR'#38&ZHdDKF
- DQ#6!Ppk[CK2lFKV[8",XNVBf95@%NKfSZXcY9&!@5*pKdPULQH8Gc'FNUHP-*,[
- YAlG8Bm&A@fVZU5dePm5&+2Qr*"L'6qaS-k6$8aBkZ[h%6%+55&b4E(TK1cDILS*
- 'E%di+VCcFADped1lhN9Vai9h2GVmD0p6Z$VA@SX[)D%[KGPEH6DS@jQYU)#N1'm
- 08FX$dk%)H6UU3JK##KfT4V8f)+amYZrIK(j!R,"1KrbGL,B!*(MTr0#TehD+43)
- p1L5$&'Dhm8S)BE%J&Y59Z&eLN6&%"e8)NAbkAPZ6a#RbaBeV+bI!l*P8j)1F%K!
- X2&"Dj-MXM1!6%@%5Mj!!UISa!RT5cT!!9fKU#-EY+8BA5"8%JC-UL(B+eP'PZQD
- J@e,PEUR4k9BVhE,C%Iqh(TP6"1%h6iNfZGDEP#a4CbJH@&T$q!aq*cdYhAM$SS8
- ,&kaFEERZpGD'L3HH$lbl`ha``d125p*+bB`33keciEMQ0Hljj@9Vc&Hh0N4+9#H
- hp'0V#@-A[kMCa(V![)faP$YimH**(`2@qm"3$#+F@19LX8KrZq"aR"SXCijBNk#
- 4'TPE[m-FE6CHi0$X-0XY"J[61rH#EffU6I+fQB48hK`EV'@HmRS2U&Y"P+IZm9P
- CDmU&Z(FhBNBJ6b-10Mmc@9*C2mXdePqdV6-3*#+&[`AFCS4rQFaQ(mFIdK%I2H2
- %Y`j&S#IDVr##JV1(&IY#28A204I1*TLBE[@rdh`K!#(5'QPkVk&lBhdfXH(bXZP
- 1QT3+S$1Vii-#"c#"39&ER@c"iFaNcb3FZXb#hSXU9b&H0Di#,+*3FN*-%J3Yp,5
- ,0P`SVKEei!2XaSPA',&AmGKVI,'`IClEV[84QeF3(!eq9(a4*i2h,9@e`![,SAG
- 4H-Tl6S"4&AIVe-d68rLT!62,*B"h&[PfJ)qN``hed9"C!DK,!2cbfUVVP9SqV1S
- lSNN!,YFJJ*i8-#RFVDUUBUiV9TIKQNVGJQ[`0(GFq*!!6UZL5M6KR[HL4*YI"#1
- -kGfDX'%Z&)ARUHSV8if'9*E'"-TTq'`fK3PJr3SEKV*dU2m0i9f+Y`r[)G$Lkqf
- lKBR%%8CR5Bp*[PhrNMm8N!#FR5IS,X`9iNIN#f"@KZ*LX&eM+i`VQ#Bc3`J%hH!
- KIZEkUDC)(1'ih&HVN5Ll3LKd9'mjiX-4!8l&+"+8Ik'hS)m'HVZ)LrFZ@LK2C0Q
- J4mF8iC[2BiGT+CLB+K$Xj`j$0ZA6K-J4J%GFHPM!"kYKBA6S8M#+QUT&,08ik0$
- 3N!$Fi%N`e#)f&XhpY[8#e-5%8`8$e*YhHL+(6"-!EdUf$'TcGa#,!9Je-!&Z3lb
- r2J63%p%S0V*m!VRi!CYZi,A`qa[DeJ['4(CJEQ!ar9pG[+2ad0b2&PpS&U"DKr)
- U6"Ai-4JG5)L("[%T)a`BNSm(8D#dcHN-[`84eVV(8`@29kM@K%i`(+QK2%0URU5
- ppeK%5a22M91[)f%I#Y6@R(I80H(,V2Z&rTaAGFhD0&jP,lM-Cm)VPC63`hBTE#'
- bFI96reCpkP*m`IAVe0bT0LrEfHMr%+hqiDhbqNf-)C2h#qI,dj&la'#,[ZX50DA
- !pF*cDJiLI`B('Zfm8[Z%-YJkbHE%&fe&!L26c2S`0q6H4ZGXq'lj4kHL"[0i"@B
- T&6MB8B($AeIJ-,i(rld#P"P1Zl)GLImjE65RcKHJ4'`K*-aGE#N!5BQei@N0'YM
- b3RjKBb-B'3h(j"5YEEUJGfFE5(A1'ZG`db""JaQmaXAjI$V!RJX)"qT3-8@fIrP
- DhRl@U114+)2U)Sp1e$RL!6#`IbIf1qD0Sd-)YdL+VZ5DqQ+,-Q``Dm$6aZb+U$"
- Bb-(-$E"P&2DPN!!T9FNF6$[+jU,ZShQV0i,)M+06Ler-9l@"S+ZSZh#QGE[5Ql[
- p4YkE9h9-LXqVNm,YE3m'GaP6KEQS3-pFEh!AYS33p)%X%@+j#UpS6Vcr!NE8&4X
- AQV`2UL#eUP1"iY&ATeVDM'`lGB6XVqLFK4jIVG`j$a"h0dpTG$$k&Rh4b%mjh30
- SEX2Z`abF"2"N$HC("TqP,FU4kLJ[@(*$-AB*Zh%BQJ+U--&2iIS%)p9mLhK&GX2
- h-p3K1-CiNATJZ#6-e82APmZ&@UHTh*R`DV+N#Lj%I"d4Pr)q`Yb$ECPLDiIY+XA
- @#G[Rb6CmGR#ZF"YrI9RHplPDfiqYaJC1,282)0+GIXhD0,$q[bl%iR8`2"f!!P6
- *XdTUldT%lfBNAUEZ+aGm'*T3(q`QXYA8pV`32Be0"619YN[D9UVQ!a4jHSJe5+F
- 'USr9"J8)YT6GpR$`3@b'$bUEiB1'2$T98VXK`EDarDj4Kq`#k$#S2*+1[)-Lla1
- SArfSCXer6REHJHK8l,dGS6D10X'c`@6VLJB+BYV#ZK@N8Slj[l%R%fZ4eR[6p(U
- QT4)Cd-C!T!#A9dqG3P4F5[8*q9I"[`&k+EkELGNqE9)4aGV)jj%Gc0+)!Vej-jd
- eN!""THqPH20SHJekFqIq@ZDhKTjZG@5J6TISN!"Z$#*3R,0$AYXSRaZXpV`5VUZ
- 0Q-%)XG%S"T-49([TK0cPd6KLSA+)pGCpfj2$Y`0[9V(#I(@6UmjIM9e)ea5)#"K
- H'RL@!HEJc)q",6+,l[+bQVS*IK44ieBie[3`F-3hrAQjTIVeD*c3UI1La,8Pa$3
- ZR+UCeI[j#kHb4PpjDaa2LTYGVkIDV+9&e51jRR@*HkIji+jji2&q2"Jd-GLQY6e
- RJBjb@2bUjDqhNEqaeB6cfmN(AqpK2AKSJA`%@IA3kfQZ'$#EGkZ8#@F@[*kQFRc
- GL(0l&&Z$VA%G95[YV&TpUQce!ehTJHS8XbjpY5#Q$+lX$Z544pRM#+$TpE5e!q@
- -ep9$BibGXeD@MRVc2TC)#M168G(0EFrRQ("cVFl+rcT@T3Y)2*j*q6k"LUrPQ9r
- ApRc'I%3LYRLFY3[AeJe)XB%MPHqmTQJpmXpQ0Y5NJI9)PY8F*,Eb#MiebLqa2br
- R0@6EGk'a("h&YJ2cj&U88Lh'r(Nj@,j!qF"+R4mR&IqZ6,+j624b6m,*b"Jhklk
- 'RiiBh6Fl@2G$T"%%I0Y'phI4A4[S8,3Rb(AN5EdASdGbU(,eaS+C#6D9AHflbC1
- +i*P&AKERfRF6Z4FBGL0HQG`VaffJL0##4a'%1lG9CMheY2*BQiU,D-DJah&-JqP
- mKrRJDc[ERLp!R@'j8lCB(8H(dUT6$SDpcS6AAa[Pb039k(2IHE0Cp1X'j&Emjq8
- d,m'!jfDN65R&&3f[Z%2c(#ckA9MLZH@P-c&*P``fKKbF+c#VR0)P%h$C-6Yb3NL
- RGm2F#S0Pb1Xpb![XJ2')#cipa!A[F'Aekceil([TGHT@c*%4919h0L"(ck&j-Xq
- KrjU1A'rVbK@-TG&-XVM#rBB"L(3(mRJ)'E%bU(HZN5Y*((9qm-3FH!)qQq#GcVe
- *Ib`U6Yk*KcZbr9jAYU5%e-hMK8CKkrTZ*!lR!r"*)jq1Nj1S8lP[%Kq8Hd4bPUk
- KrU(-N!$9(XV1bDbK[q,j`c1H)$ZK$5h56iY`22VGC%-+%10i&jK3[jZ-h@'I[$Y
- -2[LRiBRNm@-@)A[3p(MqA6SR1Dp5Z'2REV+F@5RFZ42-2mp[,DMqdh$+pr6(-*1
- +-B@+XDQ5JY-3VfNZ+QcSGr2*ik8CVLF)EcbN"$91h5biqVQ[mm0&L[FfH+DkhT!
- !ceKFR)N55K[[S9MCG,Eq8SL"k#A8rHFiB(p"28f#CI[R4e(p,15q!*f"dr+I'Fj
- f"TJMZIHC3l-5Y99[c[%d@6Pe`%fe$2"kc11e*$@U3lKp1VHljFllQI&XIYAJR([
- "H[#M[ZTTHZGVrcA6pL18@8+cQQRl(Qkr8mN86*E(ZrpRjhrGrESqrElT0Z`QR$9
- dD5(,e6c,iYQ#`Sm)TE%8S6ib-jXe3UmX0LPB2Fc+*&ZqQpi3deDN"BmkG1$TrV6
- k9HBUCHb1a@`BMpN`RZG0'3rR'IXTBfmVqMl`1R5LIjI8J[DSN9'[6(QfFlIK#-Q
- C(XJNH'Cqk-RaeQ2)+20e16[UIkTrePHpBE6rCk@KMqcrUQ`5Vd!4j4kr9klXmDV
- L`2'pkGDY6$H+4PE8$qT(1Q8[4)CPqfFa[)FHlZ`,j*[k1SlR8BfLllVMb#fm0R4
- H4Re4qR9I3#FE0JBk#)iRlDlJ',d3(+0&I)rF%1SCU[DT2+0bbXK$+QqbZ,fBfrH
- Hc3)h9H$m4'mKNTG(`K8-)Md"qe#b[hQFfap5DM2aE'fQRmeT+R*LVP6Q9bAeN5I
- a6"j#*TSEQla'FLrd!H@6*#(,5LA,LUmli1%Nj$Ph5E)0U%JjdHb`'STmee'CDJH
- A$`H#Rd'C$9ZKp*IBQBqS&#!iZXHq,"TQDj!!3id9j$'%3AQV0jl[$EiGI!1[(`E
- rJYH2JfrLpG2JAm1lpUN2"pm!U4,d42jY8p[$`52bPMkf8GhAUFqjXe(2`eZTAq,
- Q+0[Ipmj@-PIG1!rILHiY!`V`qcQN*6XNFkiQqMN9MD(09RVK`V1la8KPIjTa0MG
- 54ahNZC@6lr&CTU1QGQfKZ#k#Rm)CYL'2C-VMM40FpBqK8IVr!*6K$r6rImF'H*0
- riaD&89[hrmbc@B**QrIMDGL2DFVaT(f$lhpZf[pi9Vh"pcqhZPr0q6k,Q8S@`hM
- 80)VUHMQ8"@%!KV"&bH)chrBIH5iiQarPP%Sj((U@j`#U)Bl8F$E5b"R3&3,U!iT
- eKpdkL8K46UdqK*J95Xc'El0,j"(VH(Dk$Vpe0P*B4GB3m@4%@+(fY5LB0J,`mr&
- -4P)Q4K[e4G'3!0Ie-80H0c`'dUEkLD1U$mhlmh+(VJ3BKrB@aF!JT$ZeHTqp`im
- BM6'94bUE!"4Vd#C!Q-8`4IX#UZZT$MKFL1EGMXL%UqVSN!$iT['YYP(5kj(%Upr
- -JPj(PPT&eSC#FifXHlM9*k-eYH!VlTZHIZ#,AJKSZT1f`!C#!FD6Em)N#qb%c"*
- @1Cl[V%Xc98694J4(m%`@bh%)lk8jcdJRBlr8BCMFG6*'LbrY64BU+e@kXb-I3CB
- A&flqQ'i`J0N4fMRfS6m[jhN"l4cld1Z3!#FYD1IBK`l0icDJR@-A5N4UaCGb0p3
- !5M8[JM+cL2B2Y"9q+2S*'U$2e-2NQ`TM)h6p%0*l"Qbhjq!SQkb&4T!!Y(#(9ED
- #1`+A'-dad0lK)Ie$BG,eX`Da`DRqh6630dcrmh2SjZQf)ApHiHk((F[[LS`M#Ma
- 59H%K5cNmDe0NA8j!`Pb`S[I9aD,5"CfB%JH98V@DZ"hf*IEj'aG8Ea![@rPbXPk
- -L'`-3K$5BifJKm'G*5U9*q+b663FheMLkVKc)'S1)NUK1ZHMcU6+@&Af-CNd*(&
- V35X8IZ#FA&Ar3ES[S9i)4m"kMaLjBU%"*#pZjY1Ri-V%$CU#h-M9#j2'rqPhP%X
- 1UA8TiT8-8'Aap8-C#aM(96@9LZP%+Dl9[S6Amb9Hc9e[,+$iT1iT*iS3#HiaUFQ
- fJPDkVe+AFAm4[ScE[JJeVe4U(UqHipp8iJTG@%(4'[5S%383+A#6U91#HHUJiTL
- C3,@K6!1+*B&f3p&-!p2'm0Ic9q"P"-MQQX`Thhb`NES$Vb'2k9b4I'VQ`qCb-Hd
- 46,%c--&BL6dZMp8%9IM%$U*a`J`[9V#bTSq)d)"hk**0j+Yh[P,j0J2G`MS-JTa
- LL123TDTB98lE0Q1f0j!!QNFAE4mrA52AJcIQ1R[ecRHr`Lp*ecPU03fe5RXGZdY
- FpYH9c)Ah+&35F`Rcf'fThY9ZH@JA+3G61Tk2iMPD+BRJ1EKKq4N4rGP89kK21Cr
- LT&lB*G1C*&DLa[Q'kQjYZpTa-l34QiBE(EI'K(HKR[B`[@eiAlE4G9R!F`fI!Nq
- V8m$D4U5LY+&4,qaI3GFfH$qMEL5XS`X6L1,lS2*H6a'T21dbf(8,U0lRc8k3!(D
- eFi3Xbi6D3`12l&CZ[PX4QGI6f+cbqIDAQ60N&e#fL,rH[I+,Le$4r1Tqm-eIL8c
- SMAh0MIVQLrVYk#RbEbcqjhU29#[kNkI$Y5B8(ZV@V8fXkAA504I2ip`KC`eL0ea
- VZLCreGmZ8VBmr(AjQJRaADm0NRDG3!jdpB!VBh26XRSdH'DUSC,'"N5M(QK1(*Q
- G)*Rb6PA3Y`SG`"P4(9%4`pG6k3hC1HQ'JQH3!,'*paTeN!#a![')QEH[ibEar[@
- $ZNY&)85fVqZfMF4Y!`K'k[j#A6C9e+qN(X1hd8i6V(EmGp1CZT@kKK'*D*e8lh#
- RdLd$GpNqi*rX-HG[@l(DCI0"lrR46QcZ`Fjq6&9`GPQY8@qY[,6+"GHB2aYPKE&
- `@ZbV99ASd(9B',8fICI9NBa#GB(fXqE#c4pXjXM4pJmHJrd4["qJ@&r%ZGGdRjY
- %[Z(C!+i[5kHMMr6(X2Dfj5ba`"&T2,HJFDF%r6"(iMAJI-JbkJSDBk"MmSr-T$A
- 'E@B0mA1K5mCMEi*#'3pd(K%$"1M8bQ2([fAN99YIi[5@3bAdI$T)8eQQmbbKGLB
- `Nk93PKN&MEXN@kcV@*c1N8UUCe+d"A1K*H@kabh-JMc,@F-6T'X'qQ$-E10))`f
- SaU$r1L669mlXc,2lP[4S[SP4PjL%HTCf#%8f`UUdbC-dLQH$J'AV)lJq&Sd-6j!
- !3MLPA0C0Y(G3,lZADB#A'V,+GBX3N64"J4FLLqYG#EKRLrC%j$LkNZ8#EDm"KXF
- DaE1jVSfaNR!(%#K53h#lI"e*AZIMPU+ENkD-`69&0qNL-iB8Y0r(GBY$[9Nh9dQ
- QN!!d4S0E0"G)-TBr&M&FGa!e#RJJL-MakbSAa2U5FT+bDhB&p*KajMe+jUcSk`'
- ZhqST[)*3CiCF@#dDjdXjE!,hKLN(G8DCUZd,G'j-fF3U9a,kFb@p23lF,$2*M"!
- 8GN#,&HP*3"DEC9eJ&(q@cqjd&GC$N!!ZpkR5cXJDh-TM8!93X&'p@5YD"G5VF89
- Bpl1Y&Ueq1'BDP"kU(J+0,A8mfcEj0@!kH)SV3hb#SQJr)ZS9VZ[ELX[U+UN@*(B
- -aEd`PpGL(5&%3%am3)HS(L(-TbSaEh4aF*@BRfadT!#,HGU[HE694CUE#P`+9d@
- pIZ+5&*Xpek'(#V65T-[XT+kd8-kkj%e5J`2&C8q4VVUI2GHKJF9ML39"@LSE#C5
- q(34+V,M#Y3Da5`Z8[C@M6eF4JjQ0b--l!hT0A01J3FeYkB-qf3`9pDi3eJ!1pqj
- 92$,)--A#qKmhKrZ8qV0lKGUI)'dLFNpJ&+!VDflR5Sk)aR'&4Z`1P@Qd(++QP#I
- ZMG8F0I1+cC+H9CJP8kK,ZeG4pj,+0kYM,A8eaUENY1$cH*0@-MX$E,Yji5c!5"+
- E4Z!E)'e$+a'p[55AGialBk2VC9ZXHa*brQ,LH,P#d203fNi9rCpeSMa$9+9`[MK
- Ic)21YFe%P#YSfkh@5PP,DN3MVD0GXcBAa00jVP41YKXQCAkiZi$Q9CN*TfG6rcI
- X"bkB36VfN!!VDFDDk)ifpYN3)qmjd)'e(P69fa"AhCkELMQ[+ZG$A@FY&01805[
- BDe4j@A"*@hT4!BX"5Y6)H9FD`EY5*@m4815$HhY@",[4116eND68KH+aaSi!YXE
- cX-hNmbVPJR0'P0Z5aYjFM95-baIY8imEGI&TL,42"bF!D&5K2he6+'Df(GP*KT3
- ID!%,`9mCbjKU3EBDD,48LJj"48ad1QVG-0KimlQh5C+jd1*VZ-4F[(6YKTYZ[(r
- e$BXH@*NrSZ%AejINeqkDpGRD6cpYQIq,[$rpY(I$YA-#PNXX!qH8QG-DBXhCUk6
- ,GdYe6clqa'e,,3-EeXbjeIcUR)aejT9cVM-('NSDdL3TB*iijlHET$d0$jT[rSh
- NA(A8h1Z2EdN[)[0CdQI5C9,0(hrfN!"dprX0MdK6AVjKT95e4#VF)C8er"C#VbH
- Idr$J-DRkH-1$8UldhZe25PIPErY`liHIr2@[IhcKNlFDI[l(KXFDkKSDMhcbKlD
- 'fNpHrIe,ZB2RA0C`kj`BkrBjGmaCDEjqcNf@XGCeNR1TTH4qDIj5kHkhPc`Q,@a
- iF1HL'jDK!#2c2Pk3!,Il*dI@5@ZXh5RL*2FIc(dDEVCHEpleN!#d[U(*A0S`mRM
- $%ZR1"mbh@L"`DEK'Bf+p!GULY9+EP5("SkQbqSdaq*D#1-$()KiiRij-j+aDH-Z
- BcA-9&lL@Y"l8(b,l"ebY(Z,,,,mIFG-BHq"mcY1kQEK-'q,`pUI(`"2bi[rJI(#
- +M8B1ip0MH$3ILhcJI("JLIm)q*0NA&U)3mhhT!pjB`bq8Jh%X55bh%+L6@IR1QG
- 8PDXb@8J@S)r,-B'`mHa+L,la3h!a9FUrIZe94HY6)'+i4Q`8l4QcJ9Yl&$'68h`
- HAddS%4-fU9VKlNR[3U0D0iifU`DbQD244%,U&)M,XmllbarDMC2I%"rPG-$m8Q(
- "6&hB@Q0lk!dl"UFMmfUf255FLmm3`MK$#&c2U#F"c5k1Mc%0f4d2bSU%U8`lX80
- U9BJPibKa,9X[9'MLY(U$$Y+@#8jclBj(h(`6`2UiSI#kM(ZjZ9HDTATh22G-Tr2
- pPML5F[qcVCY`J0i3$6&N8ra4MlBkpifb(PjZU-D0ldBA!+aAiJRbF1q&KH+R)*X
- ibXDp&GQGjiV2'A*iHFk3!0db0fA4+'Ph2$mCHS!Lihd[!8-!cXq$X09*E#"RjVl
- GI2#0LDKV#ShiPSTR$Zk1-armbd61ApedH#AQ%(-'TjC5[MA)Qc+9FmjhXbe$,Ap
- k'+IZ2pX+L4"%MH(Qi')#Vd%QPl(Dp*H*i5MJq288!YTq*Ci$UCe8$@5D3T8C#U8
- *m0RlGH8fr+eb%2d"IZDA*XT,TP1e%a9c,IP(a9bHrkKBeGF9'rpeaClTV&KPpHl
- B8ahfBIF&UR9XGbck,Yd(!*4X9&@U,PFflG[+PRjG9j`@F9erfBGR9VpKIm1''9N
- &pRfC1mh`UAU$#e)*a$Y+cpDm2)%I"`9-f$S!e$EKd2ZPI2Y$Eq3EjjHJePAieJr
- !*P(epkaa6$0eFhie1hQE#3FN(Vl'hc64(MSJ3CqR2A1)6NGqYR9l+mQEBe&f%(@
- 03a#rqX8dpB"d,Gi4lBpd42UlUI0pid5l&`4`mf[FK-(UhF'8EpqdHlQMS'#kF,4
- ,!Y9)V-j,0NaR@rN5hEKKZM!B+K!)(RRUE#bL3R1aLU4TV!kXhBq'Z!+*IJh(`BK
- ,4c`E,N5Q4YdJfqlP)dUBDm4d#2CGM0G10Qd%XM-mH'eLAT!!VG8KJlU1,1me6-2
- LZ)5Qle)3MT%009RF0Sej)2X[MlPJ@3*H@rMJ@bp((4*$r8JaQiK0%4l*cD9&)kb
- XKP0Zm5Dh$MfQe20UN!#%iBS,$ZlZPc5Ge6P-**VEVM4)HB`DXSHb,d+e8@q!!f"
- Tp#3M'N9%rAGa+%CfXpRf#LHNV#f9UHlZTVS5,!QiK`RUcPh(iFLl!@GF*dZme2%
- @+&JQSS,AQlIM*F*JLTQd#D"3*iP0j)dBB!cYQDK,A8i-q3m,58+qBD+pZJa(#9U
- J+@9"i$NbBB!Y5GfV"9#q+bY9'2clr@cVTZPXQNqA0BK0-da$AqrdACdm2UAkM8,
- XDfRaVjUd"$C$Y201,Z33-NPCh2[Vm-k$""E8J4MqLf,DFRP[XK@-kQ2H++5F8jl
- R[2c"MG2BeZSf"mkBUA+)KZTb"k1+SUdKK5$5S#aR6L55BL+f9-edFK'Y90%-AY&
- hUhNS"r8$28mqCFi!1')NZM,K8DVp!kUh(9AQLH)CL8L2mCU2Kb8(P3C2Y-(Z8kV
- IL0VAr(2YTeE[Y5q&IeP1"0Kfi9Z-+MjR*9(3ZUkpIY`20@Ili3P(@Sk@p`ceMSk
- Yl)M*G%8Tcj[JppGE+5Sc@(Y`IMDEG`NICk$VVb$PG%+pPab5EBHG2M3Fj)JVK5I
- b2CTXc4cQQ$fmQdP6+Ter,HM5HdbDLE+Pfi4c!Kb&ML8C6+%-NEd0G)bB`-(H@qi
- (8rJ2#iKeI%r&m'k1&"*RDHL[N!"F28d4clc3CT%jHfX0)@XhBlYbl4C6YdR5%e*
- e'q3ciK#SDG1NX8rR9d-LVA&B)DkjSTVZ)m`jl)QRZK(3R601(0GfL"Q6p)Pj+AQ
- l$N%if6K8jf3Lq!3e@BT$%r-ANe"L"QbBmIM,cL111$VmJ0Gh&#m2H8(kiT-9C(P
- +(,IbGk*qr&[a)TmT9hTV2%i#2j`TqHj-HI6X60NHY'Hb,+dk0@@Hf*0c(Nf6Amk
- 2MfGRrkbJf4QRc%k+)T26R,+pXa06!A9f4%8$p4'G9lB2*Za#6j8+hTSq656J)#D
- GQVC'5*+2E%GK8)E@ZIVCTV%D$dP2(kPZ5mR0SJeENPrC%(HZh+V#aGM!'Rfqk3S
- c,X3GBT0m+CIRA3F1f6SR%!0,L&E4N!!h)$a9lE[&MKRB+eZ0@Nij1XTR9#bIpd5
- 5"5T0m$T2HX0#f00,ZBJe$I(,J8TmRV018`jHcMkG)@G0m9SAlUKq`h*`A+3j'0J
- KQ33(B8h`93*jLdU,#Up9L+bN2TL58Tr+Q3BZTjP3YPGZieSY)2MU'bF&L,0kj6D
- SE4&b+PreIMRqcD""V4NV!fmilS!-r9&F%`0KEcJ9$H&%0J9c`5e(EHc)"9S4I+j
- p2"FKQjX!@C26108Gj'Q522@@&"+XMKH19[JpPEmZ!1reliIc!')85V6*H*'@-L5
- lZZX!MJmk9&pNe#'I+["a"U6RGjmJC3a%G%'U1mK'kP-Hb"1Rb0PP)6YSKQ'K5RE
- 0K$DTmC6N3"F%cZSS`%4ma8h&69eCH+i#T3Bdc[`qYQIhqT@RF`adj4M!qCjT"kQ
- 9Vd@@[Y@E-dklDNdQhGX&4$'VhTh+ZlXV!a$&N!!dU`I@d+lPBY8[RI+fV-qf&K4
- 6MMJbT-1%FDIL2($cre+AjDFk!83E3HDKhLl@2UGQq3dFD+@BZUe!CmHmF!j8+a+
- paBqD1Me4Pm8#XLfr[rPq[Lq'UYmBCGep#j!!TmdQl3F&`*[iB(NMRdI0cZZk%*&
- #,6')ll@HkZ3'm93effST)m+P-)@5JF*Y9RLR15G`NN9bSML4E0)k2B!"#Q8FLjd
- (I6%b-%%8`811e`3U9[Uld48IpKQ$RZSjbE&i%Qh2@$eHHAMC-dLk-cT9S-cL[@l
- 'C,HR!-ejUIdY[(+Y%'5YGbIDD&ZC')8Cfqe)iKU!D+kle0KrI*M2GAMaTB2Ea-9
- 3IS(R8Bm'SLBbb@%CTb+@pCllj'2j188i@GXTDK0*M+XF%fe6*SQ46,8qjZQ"*&S
- 59q8"q@QJZ4CRE!HK-+)jH*4NJ*+ZKlC2k2#3!#fIar`pYCPSIM+EbdQ-,9mRZ"i
- i(acK`h!5"MdL)Xkph)eCXeraGcp`I[04BT2AZK&bk+$Q$,#A3mBRr(!'@ch1@TS
- Hdp+1[UaD#j,6YNp$21pFqi8qIqL)55j&Q)lk)F,hjS$`&,db0pb"1DJhFPM@@5d
- F(4,M2+6G@c@VK"`fD2a`iah#1k486FG!h4"eG-I9"pIL5Rm&Ke#P#dGPU4+GXE8
- &F5DB#R6ipUkG4l$2jcVp5()TqS3%GKe8Eef)!Gqk5('L%6@IGCr#,2b"F"A43@*
- 0*Qm3-F`D#3TSGej1X1"h8!-8RmL*#6fE6'2EQPjV6,*LSr6%rS@M$Ze+C&5DZKC
- k(,bB`b'LK-3Ea+5d,@TDA&dELV3991ZDjN"01FKI*RAek)S1%VH06L"#EKBE2el
- Rb$,f+fL8Gbh6dKQbi"`p8Qd3U+L0DiT*ejB(DD`l6NF!$K#05"[S!lHHLI,!,@I
- L1(CcAh['Mf0Y,@al(DmR`kEdmpdZhIZj*FIk%h1rKLGHJ%23%RZNSFKmdhjTR'4
- j`&)KI@*qla2B(SI[bCC"$6Fhh2plFpTbDH[LqhkciPDTk-1(9NP6hjGHN5Cr+2e
- BUM$(52IHBm(e8qPDGTaGK+$YX+A4E*Ymm2#p9)(epV'A9cKRH0969YV"6"`J&IZ
- #dSMbbKeF)a$K!+Nb$Z!LUI4j-JC4E*@e1leb"pIZ&)QT%APAFGL2p58pMY3[$@r
- EN!"Frkr&+H&-XUl9Xi%&6(FUDP8c$[Zc6rPX53ME5@F8cm"A6fH,V3-ElK"XZ"%
- r1KF'fdbr6mST(p"0qFjkq-r%63i#Y)RjS'1#Cha`H3#Ti$'II0ErE)DTAe@4lX@
- f3VDB`RA34,*&pkZrNQlJc5p99Rpe%k*T$!Md!BTZ0Ak*,*`BIF1N`Il$%*5,3h'
- R1NabL3aZ4!BiNeHciQJ'Z&3j5,Zj[kee+-CDB96c9$kj%4FNl3[T"Zfpf#22j+h
- VhEC1VI9#6deYZC+"E1CbE@&R-He8ca"*26EXhMj+kj`DakD)p0FkRM-c-*qS@LT
- m)$VE-$6I(,,FTXCZkC!!bSX0cMKE-GRB@"Lk93[URfrXBre5@'$"hJ@"CB&PqjE
- YDJ`Xf,I!C%h9[hHM('F1'eT*-m2a)'%#IlQ2p8q-#-cGbkQ%pblHX6!`GprFe+J
- ljTl0-NKCjV2!SVf,!XX$brFYIl-aX'MI)T-e6IrH6A+FP8U@MJGfd0!VP'9#4jB
- h8CB&8AI1aC9&2(V"Qp1YH58`GpRFD-pS,E[18q99m)Qq'815&CJQ3DD8&UGJ6Jq
- SQUMcUG(0R%K9[jQ6pPTB@9C6$EM8mU*HE*!!A5)qbdrld$kdV0*hAANpKNc%Up&
- A2[dVVm99!'BMAP5p"8k2FMHLid"j0C!!'4e(*TG5`C8+BHmpMT!!fLfeDC&2fPH
- 6V+h@Vd`Q6%-&G8P1Z,B!hP1E(*lqP%G$E0K116b+D3VLBYN*RZF['re"T3Mk@6"
- ViPKHU5kJAccaYJI[P1r0&1PfkHRYKAUAK$!S)YZq,5j@5@aa)%aMC-TJKmkI(Ia
- PN!""N`U%%q,dh'8pH(LMM!AApP6X6mKfZ[@L5`L(1SKXQTM[A1K4k6STEY)BS&b
- TNk5PGh-4#9X2KXPkN!#$'eGrIkk59Ta,!MiRNErPdEmY%0'&e+"r(mAe3kil+8b
- TdGqej,X90'QkGc&jjYI9PCA,qR&)SBGd@AG@CjG"F+DjE4Y3[qCN&DLN(48Sj-D
- [kY&!P(%pAp83Qa53!20BEIL@%E59k0eqAl-M,'&qle8AAB!$IV1qGFj3I68@qD[
- Cp-Il8,[hCY-'G6E*b0-A0%VS-Q&d2EFT'*edc"f%ba%@&kdBb%iBm4e[qj[IZ$&
- Iq4f2G2DD,15pG5"A(jF0)HPp8CMfCNf)8-K[JL3#)Ge!KfK`6fd%-J%k-e&$N!$
- SXML$"Gr-rhpI(HU&qRJ3m,!#Q'JPDT@,E'ZAX,('EPRbH6FT-ZSQ`[()eNMjbCi
- $BJ*D&,Kq%T%a!Q3$ccS[XCSFfr53!%&+4`B3A1))ISDk)$I8"EPa@a2RlBPBlK9
- 9XT9PIS`dp9j4c(hp*Z1++d*q@Xcc&Gi5[`HRkfCI!IZp8KD96Hr('Yh(P)ZDf98
- 9*E1mXV60*p4l'+S!81Up0%qkmU%X$ch8a#+'Ud5HDXS#QDN(`c"0'1$AHi-(q1X
- `Id%Sj,G6Qhp"a*4YDcK#cGF3Q%JNPr&`#i4l-R*p'"2,abqC@VkU%Ac,+AEEh5#
- 013Mj)iFp28(@!E`F,q$PY3Eq*ZY"VTVT%')Fi6%1"8rJG56BcQ-F#VCc+iNj4$D
- -YZm(YFmbD*-bZ*!!8(LKBX@mBMjH-FD+dFe,H(9`0"+Y2V,Y!'i3-18QkYpE,(Z
- P%dS`-T',(ij2JY#-hSMYL"Jm'c&$MGMR'8b-@Y8i8MLE4rHrCPlf9HDGrqr-*d$
- JjLaTLe5Y-d8k),9bMS6-%NUPcH34$`pF'*DHb6@q$CJJm1bSPaGH8(%AmdVi0PD
- F(%X))-qjjC5h[D&i9eK2e@fXK+k)Ac(fV"FUhjpKAa4@T04EREiS*+`c))XQ5*c
- d9@f19d[fN!#'Pm!8X3mcF+m0EqbY,mLc$PU(RVLU+'f6jV#Bd!C2N!!92B'4[1e
- 8,JTCMIN`XKVaBC5fe`2kFC,E$86$pmZZ'J5JZP#i3c8p8k*+Bjq1pP3Z-l3H#Zl
- rERCjGL9r&6')L(ZrQefHAAqEAAQN)Ze9A#Q%Fb*`i6Y3Yh-P)R@M1(hqI0HGX!X
- BbG2`Ie)Q-d3dZT0imVYSp2)I9kZ26JUVPel!ijTm8$q'Lbc'U(Z1GqS5*,NjY)0
- J2beQ3p1c)pk-H,2jIK!k38`&hI(JeJIH@`I*)Y`EVJIh54`T,J0*UL&UDialeUV
- @mSYDcXF9DpU+DF$ZHbFAm3ZN`K0G(22-q'iDd*A1eK3Z24Q#0'XeKGHUFNB)Kfk
- Sm9dRAm`6(`[`&T(NS$N)q"j9T-[i0ef)+`B@KN0H(XXU9F(3,3$ZCq9G"RR`V8S
- Qc1Y#NRY(Nf@,,"J)E+D,`Q%LZ!Fk"(`deUe6cAaF1#N2VBY58(R)@r@)fT,'a1)
- q$c-$EL4)YMYAmjDbLSU[UP#qJ[Y#ZAc89pJ"SRNr[)UMP5%aaVk+mX`U0QEJjQK
- 0U-SVkj!!"-JP&"j`SRUF48l*Gc8-E&cP"G(Xc-DNaR$eeL-ck*!!X(Z$[,i!Vi[
- 0i`SlQ@S)(i9i)lr0$04e-NLl+DG+NdAZrZq[ic[&C$E8I$$i@0Xc3bdbJ[RpGB4
- JRZ8h)J&i2['YjhMPGVNH-SZ2SKiU0m*)dlrf#M"CV#mAFD9bHdBA!,KZ(29H!@V
- Q`ihjU)r'cC2J&B"AA+1C)Yii$FF&jLfcB-SD#j,X0!iVY4T@bIT!+Y"(%BDcA[m
- @)59mir*ZK06`aFZl%8D`h[m@)5f-DdN%%!qQN6MA2Ur8Elf'NaF`M%G09RRLNbG
- 2r25cX8CmQd(+Yej3h-Pjc6ZE&b'J!3Ara'4Ik*-e55Rf#,lmL'B$"@lQ&C!!H'b
- VC*Qqd+f+q%![fRJ(--PFrA[JiL'I5TD9E8JR[fLN)LMI!R)'6D@abX$$LB1E[Ab
- kd@#0ME-RiaT0L$EAd5&&[G-T9ieP3SFlja9G%KC0``8V,MY$6,leLdr#eVS%!Y4
- M2Z06@5+qiDa8PM4k'NX'MSLEN8h@JYBD`c[0&&((i[Zri)VFN!"RATGRi2ZBrVr
- &"!Z!eem-"J`2jR8+kKdZj$V66'Q[i"aSQH'8F6qS%KdP%Mdd,LVpT,d0FNp`V8[
- +!qYlJSTjHl[&$cR3%&C!ZPJ6A100BcXl#GZLpj3(-JH+V6+[,&`4mXj64BqN02N
- KV34dbSqHLSbZ($Nk,hMiP"GQ4$U)(`mKH`J2-F,j5-F6lSH1EqD-%CkTTlecfI#
- 93!#2afb-2H9h2RakBd(Xq%(-U&kI3i`cC-@GMJEkjP)5BK6e'Jr#I96[DPr"$1&
- Xpa6pIr46U(!&H!iUcXBXrrr-SNMl[Rb0,qpfG(hhfHkTF-H#[f'Z1ikrd[PVT'1
- 52#GULrQlde(!L4Ql(4*rGcUb6Z8"9'DF'!@PIhkHEkr[q*!!EcZk*-ceepi-KDE
- %3,CC"irq(UZ28j@h(M(JbY`)lX1&q9k)%&0HAG1iehjil8mU))RUQ#"(-&X1ar8
- VQ"pT$EEeleH`b"5*HXjh&d$k5Kji+A,`KIM`KLcB4rjBFXG"ibQ*BmQ&"YTXf)L
- l)X-a&*I2"i$q(JLflj*#YXih*!GG[L[21cXmlj*iRJZ!dkG2pAD`Z8h([`kB6ph
- T2hQ4(hR5GcTHr1@FfLNRP4rCZN1CXkHU#A[Uc"X'S))M8G8d9$8&0Y+"jmIALkU
- k(A(BJca3fJLCcch(D1+r%mRTrk(!YIZPVqBTCIEX9c092$[KH4!5`Jj9aaQm[B,
- ")pkHX"kXeKZmK[6JBCr%I9-9Ap`rpa`"NPc@#cFZ,3`6i"#2"Rq+a[i(b6q3!+l
- iahB$RVIpdr#rc04rQ[SDdlZ"6[PiJe,h`[DZcMHRI$hFY*mmN5dipcKAAq%+lZP
- @@8PZR+K3NN4Z+c2H#0p@pZ)Pk$34$MqlmhD%-"+k&i,f[XRm3Mp0[5ckrVV30Ch
- L*d2N#'9S*KHY3r[IXEYR&Cr[RY8Gm`'JIFb3!'2GZAerAHIGXm3dljkIS&K$*i9
- LjAA&bZ2jQ4I08QAV&PAkLI0BF5T'H-[%X9F@R[)C#hiQp0Y65VmCf$plX3#[,1,
- ![`rA#r%G)U04!5I58!RLdL+jN6J3h#A&[(SVCG99llY$erQK))rN&N3M3pL&H6q
- Y20TBk#C,e40E,f`E3C8D6f6Khiq$a@8kMFS!imm(IRZ!#bH#0bX3h(k8D-[0HcG
- V&YVpJGPA1E-lL5$DIV339`)pKR5L5PGA!L4##"-2l(,-(+6)5L*S'dAZJZJYb#U
- UqbV6U%GNkUC6CrChbNHp08m9YB3*TN9K1CAS2-BVB9k51TNGQd&D1Y,0P%mV`Bq
- Qb$P@FXJjhFYc-[SF#0H#F+"6L#ElB8YDm&&0'QYJdIda2bXAlFrAj$0Y2pMFH5a
- K*RAX4T*b8GN)22mP,LRKBAUjCC&&ZqJ9af8AKEcFYTD%'-9YjC&UX,fG!C%+Yj-
- eNIC6)dT(Vk4Th1E&2QGd1d`fAbjrYC&dKF"@+(Ff$%I)B`KYV8B2,QBKD13[U1L
- %F2LRk*8`R,qQmGGFlPh#AhAmG69r2F"Ice&GiRNHAJerF3@pZ3jQh00h'RJ&KZ'
- 9c2VL&@!aH!9C,&j$f6PiK9LF-4)p3"@J5YAJ@i[)EBB)F*L#Lj)RA#+IF+XXk"I
- iEM"'F(kTNkZC%A6"(#("a+"B%ZV0KZHa2SS2jKdm,S0(DRK5`Q-k2(#,caiJ[i9
- (+E)GJNiVaK[L(d+TP$hH@AKIMIG)bKkcB@1I$CL`NUNh9$IUNPRi,R#`ASGjhG*
- 2e8hA)RP(Z(,*,i4V3[NNEd49KLXq(KlY[M195ejeTR,*MGp@BFNr98&L6ZqS!XL
- 9)e8S1PZ&c,09#)#f'3M`Da,KlF1KXTMXbTE@8D%iLKEFc5X83'A+mB9LjZ$,re3
- GLIG3Z$V"GDHU%k6k4kS6E$a6RD#Ajq[$9*S!Dqdrj5V4bcYb(AmkejbcQD9#N@B
- #bI9JPNfrNHBk43ple$R&XH'0+9,,HVa,AM5ci&(2SRR8*-TYb%YbE%aa6"PM!DB
- bUB8qe9f!$UP$j@L#&Z0l'@`d&@N2+-G-$cNmQ*PqePh1U(DDA)RDUICTV*pM-Vh
- `6AIBq@Xk[@D5CcPrPH%PpQ+be!kQH'c*8VV#arY$G3S8ZYUc&46fb,5HpHJ*&*R
- ij)L"8plBK3iHN!#PV`31KbU,1HUkPhB$iefqXpc*YB-E`RKZA3r2DGK*D*-CjUB
- 0JlFFB`&r8D`3hRZjpARqfNHlLh'%Cp3"IdMFFQ((F%dkeEF"Vf+I5cdE)%@PU-p
- 2DB+V+,4a"`S8k@(E$kS9eji&A%!122I[2He*BUC)AY$f!bqImN`kJ6k3!#ZR[Ch
- 5pB(8'0ehbe[cZ$%8qHeT20l65[bcU%C*@a6V1'jp5,'HcDeE&1ZRZA@cBUhQeV9
- RmIc!0lYc5Y-h2Y+[566rUI-&3p#GEh42kCam5Ie#AAdUm3JRJIq@[FY#mj6Mq)q
- %iN`'IULRVK9P(SpLG`qX6jb0mKQjNrhhJVq`S$S'$)i*,!fB(d38!+PL0Yfc*3E
- Lq[iDF0c'8"@QF(l"6-b-!Va,()83&"I(dT6)06cr#I"aRrE*8kbIi0D-XjQ+(lV
- 1UQ2L-F8A'9Mai2F+eDe'3X9+CJU+jdcZqG4-!G1ha0@c+iq(1'0P5@KRLI9B)ML
- ,Bhk5c3UU1XZ,j'k&C5*beR8pRmHS86b6b92C3Q!-4B8U@jmj'3`U%HeG&e%c3TP
- PUCQ"3EAJ)+kZcMD(-Ta!XAamrP1'&1((5S4rbY6hf2prp1@GIH4cG8j9hk636*L
- +M5ej+Y--l8$F`i*$Q#QX%*SebCTNB3Zpm(jHHAH!6C1Z0r*YkjN0lfaFmXd`'6G
- !2LM%K*%0PrL`CS,T`Vafc#R)A-rkA`)[#,Am!e`B)XkTPd%1q58A6Q-f9TL-&rQ
- FAFcLmFhJ0K+80T+r-XN13D%H9JLZI,#,YHdLcV'f0abjj%Qb02JGkYc#IZ*#9M2
- 8V+b-SVN`K[m!+h4Y"02Fpc"M*hN(S,1J5Z$SK4"Mi)Mc(Abr#qqLEb+8Sbr14MH
- JNP4[X(NiRHKpXh0Re6Xar*i+q5hUmRX`j0I3j3HQH$fMCBl$4q-rX5RTVH3pbdL
- %fX$Rd,lM,HkU6$Q23T1@)PpmDR*lNlTLf6XqV,k1(5125m%T)h3$hj9m3ph#Apr
- LVrhdFX830ic+p+*6QFC[9[bQRIDlYkXq-djlVqfX52b-VPLAR)jPEmQ`9RA&QR8
- k&K"M1eCQ9ka2RSjPEmqiXMV8&H[58l%m1lYLI5X8kfMrHTUlBYh9CGf!+92!*e(
- "0p2)35eBA0HmXcP1PcG&MpcrB*r!cM@(TARdQ#XZPZr)Kre5PZBci[dPaFm0[`,
- BEeImRPAmiZ#A"[YZq!9aEeF!rFUGE$3fP'RqiDJ-1,GLG`EM-'fR(5`ikcIHNDR
- 8)5#M&Uq4%+NXT3BNEXc$[@BS)ZVi5[%eh0LIf)6MTY)'[64HRP@BlSLh0aNl*k3
- 4`VXLY)mL(ZIb20hca3h'r#eNSi$URFIa,Eq2%#qrkP%P3EJM,&(FaAf-Gq@%dej
- l$01#Rf1,6j@VU,CiA1iBYf+2IaYG%N-Jh3rc2#V1eR5fiVm4'963I[L$5N5[m!m
- "jcbZ(G&cFk%FHblja$+Dpbmi3[RTD!886DYb!+**3X(-RBif3(!D9)Bh`)DKTcC
- !Dq[6'ppTPc%SIl"bQ&1NHYD5EaAjSl2iJKG[[YR&@ehTrU!RDX6EB9%M[2JH9r"
- AIUZEfeIh)3V[M*JMR$NZ4M3qBIA3(,i*!CfNERqe!ppD+FLbb&bQ-$+*c[G-RGU
- a*9Ha9*D0,BqNj'S%#&-@pbXGLKAi)DclN@0FjqCQ[+(iHlP9icr&h2S%CV!Id[(
- -@Y"-VSrTR&NrV-'mbT1eak0f#Q[cC[d6VK9!&mp4m-U3!#h5cA&-UJ6kH`Em8*X
- q[r&+[$!`hL(!,ReiqbP1V0B4V-B&U@VIA`j*EV"#4Y&1j)!YXhk!h'2(ZJmalj9
- 4"+09cVJK%@rX[j!!JX@9DBM"'hY[3c6Hf*GafAT(jr4`TXVl8f22VRqI'(XfRTN
- @8JId$lM'*(Gd!GF#L2F5ePfH'RXfd)jJ[+P8KqijY1FGh20*TDi8'rR89rjc$BS
- KB)VX*kUB3[i1`[(U!TjTIUK@%"dS&DJY82T(ekb%4h,60!%15e*8X,Yi*GBJcj3
- I3%iN[EmIN!$MiC*(99Re0,UpAZeKQNSH&cYJ#JRTQMf@l[ck,Tlf,TG[JPcKf@6
- G)jVXLqBG&(E!Ilk-NK[IF9#6rTqLrN[%e%+5qAMd2ZbM,2Y[f+cZkEp+N`hhEqD
- T9fCrXimQMhRl5*5'84dNc'1lNT%DrKqPK+iJ9kQA[Gp2TGXV[RAlPXh[B1l"B8p
- c1`#U6IlPm%FRq41d*-"i(b3l-KphX8H4)jD5QmRXa"$f#UR!VXHH3&(TJUj@bE$
- )j##H$6d,@QS8CJ"eUEPplb)q"b"'lC9$XNS-LUjdSX`HLi-b#DNC%$42,dQ*HYh
- 'Bdp3f9HFqPP9qc&fSU-4G19H#M%Ac!EepF#XqZ%HH9C"APG[TqHFp6#CiNb2f&d
- Q2+!erepQ4MCR(e#m%1YaYAV&$+G-EKRK"!8(J9rKiLGQCa+DZ[fpC+9fejfpLJb
- IpVMJ6+9`#4UVjYJm9"aDr'ZNXjK-,M&((I8MUDMEfl%,D4C26)&92TmX9ZNiimK
- !&r9h@Uaqe'R%RBTXqFE'R*!!UmU*M0Y8B%(jJM()6ef5I9R+CEYqalHFlM$h+c*
- +LkGpI$a%+D@l)1hRYMrBQd5pBl"0jij2#,(kfVH46dmZ5ZK(HI`)Z2@I[1akJ95
- 4L,S*A&VDUNK3J6"9J-3`FGibrk$GiN-Z%f+Uf2%"5jeTf&F*9UhXGl(S3LRp4a%
- $L*Kl[@%r43br@h!pK*bP2XakqX9%R@BZBpV!rVRc'[ZDQH!ADa+HAF"Y%2DE&G(
- P(FHpEq!fBKlNQQ)bJm#AH&1CFcVY)@QI463[NI)XUaT@QVYpF)FdGmN@D@THNA4
- 0lS$mp$P[lrjTR28a4%UheUaFp9Qc01h`VCE+pppmhrc%qe+KY(h,2CDN6cljC2m
- aK"KYlR(hRIGXZY[5ZJaXe1A,'LC)6q(lVBD9dKqN&GBKPTA501QRdSmf2c6IQT(
- hq2@h("Zlm"CTr%ScF9-[ClZ!hN2!"Ek,1jPmCN`B2lk6b8Ha5K@"$"C8VDd+Ql&
- L&#bDiDY5iLJp+["TK8Vd9Um5,2D$S+k9Z0Ndm$)dQ@SQYb*[N!"c9eH9GfC13[@
- qri@PqUfMq"k5mb0feqUZff"-rZmT0EUi1%5Z6ClP3m,4030YGFF&2#)rIBSl@A)
- %pqA&a@(kC$-Am5BqUZU1Lq"MI-4f*%9*V+rIkI+G@)1aG33ah8+Qb'F1[R8mNA8
- `qkiKCYrR8,Fb`66NV50Ye@mG'aVah-'hML8*JAPlj`@@"*EX@l*cEQ$H[RNV,,J
- Vpr`pJj*`"R(IC6!Hqbmc#!-*TXVT'fcZ!SY%1-,MLbibGbSVPNN1(2@ck)&0[LY
- JQp$%GCldeM&B[-3r#9[lU1+hMSb#lIY(jIlK6*8Fp1M2H`Hd#5A!-!QfUdNh!Q8
- &V30AN`AIkJZ)kBQC-fqc1b'jDf(PP9bQ`U@jHIRK1Q3KB[J+F)#&(Md%h-FMMR0
- S9QkPU&q%p$!11l1ZhZ8U+20@b!SlHYiNC3!N')cf4dJHpq%qjQUa*"PmFf(Y-cH
- #BHpPS&qYBM'UiHEk#lbFiE(GreSEQ#'*5kIR-2([Yqb9l5fpm6j)I2cKNP6`SA%
- ZAY%+!@K68ST*!`!VIlQGER9)-LS*E`Hb%*lBQSY,EfJJ53'V1cMpSCM*QkiV[%9
- -5#1mXaRh)DPi,m8lB)Td4r0Eab0!dlT4MIh0%06AXkr&#2lr[FfekLd3,R*@`@p
- 2H[Cm0TqPCrq8r44e)BqfRd$d&ZF0,6SNdh!QS6&YGiTjYQB0CEC"c%ZUe%M)1-X
- 9L9HfHl$#0!HqZ,D@LE"p%Te*2QhhA)RA,-@+"Fh9h%*a'q*jA*+b6M*)VkHkZiq
- #[DH!HfZrDd0qD6`H4)Dahh@U(kVi1AbrLpVZEkje3180qJ+qmCEL)[49(Q5"[[c
- -MHPMf54Ck8"i#Q%'-pU@ARi9MBGUFkQe)+`CKASF0@,4`D53!$qFQi+TNER*m*J
- 4kR!DG-R4MRkU"JEUdV""d`LC,'"R@M0AeX13!'1rD$b,c0a5q,Rj)#Z'-#ihF6!
- QkX3TX!8ZiT-+FI,%h!ZXE)kUkZ6@VkG@6aZTJb$Kq&rq!kVqBR-G-LmVVkQY)Bb
- )92k6TK9dikldlLfVF*PeKXb)bR)V3mhh*j9`-@X(mHS-(J@MMMYiL)Zq(`IG1IZ
- J2U(XfJT44-cRqDjHC8U!D2##i%jLrA-c9bD2rLU2rMU2[SG(6dAdPa(eCFcH&m&
- l6'SKfL'+Q98he)j-XEfq(jK`eIEp,$+P#Hrp,"84Gj2il6-+@#TNIc8(phI'P[K
- Yjk##Se@p%1YS&lQLh+G)MiGq)&Ec![l8YMTLKMd21-(hfr&+HHXNAS'!"UpJ!$*
- N[pp1iJ5a5d*`iIG2+VC1bj!!!+4ilSPXAMd+eajliXqEa[)$r@#V$26(UbS`S2P
- 1`LcEEX!VXAQ*aGhFK1r0I),GJKcFJ96qbLHqeEN5TRJ([YfMT!$%TeG@SbiE6!R
- &%Za&JkS$UB&%[!S#%$5m*j(c!f2UdBDl4b3G$QfeLQiXX)aIkFrheB`&jD(@a+%
- Vh5PA'T8,)iZmPK4H[kq-U!l%XpbqeB&q,"qf$&D!9bDc)Dp105m)b9j8"[Uk5'D
- 3!#G(Q98K(f`*AQ6i*$+N$ABCI)"1'brJXX8,*NGhT"6mH%9e!-)*Vchi9M[**d5
- dCrM-ZmkH&S61KK"Hk1KRJ-k''6[VN`H@2I!-EV)VQ4JmNdl+a)S$QB8X2QlB20N
- (3XhJ"APH4[#CEl+%p4[EiB&DI&[f49h3Ap5h@lG4Ml6GlBJIJRI2#hJ9")PMme[
- 0a-2lG,2IL"TIbVHSNk@!$YhbT0SY2'YQbTZRZIF5-#'$Q(iZmdLmiUAVT&FPYhR
- dDc"kc0f2(Vd2laNX"AF$"Pi'8#"d-1PZH-",5LEibL3S6L'G4q69eZAe4f!eUSm
- dCC2Sc5))!H8p!(VeC[PmRUQqQ9!*eU+)kaBp*XbeBl)ahi+GP8,-QZ9Ae#@45'b
- 0cIDm&-qJUmT&'$+X5c6@EN(SVr"NCMIIK8V%b8UR)VAjh61eNCe65m9H6mP1R9P
- 9@kG)r!26X9c8L06kj!#AhJi@BH+VTVP#QkH@HGGJi-bAeAJ&C2l,@e'rQE1J0U-
- ThqHT8$4RS)C+ba6,M*ZBIIG$U&kf$6aa$I'dXG3M&Xe'Ff0K)A$eY29"*(h20'K
- [#90GeQ#IA9KAil&FT#VE#@DM#Kj,L@@9UJ1%+M#PZ-cVp)3Vd,f)81-#9"$br&L
- p$6E#&%M%f``G06HL9qi%epIG3h+$'cP$'66123(jH2AC@ai1VRGP)[2iG(#fGbp
- 5HbQTP65XdGj@jkhamdRe1pJDS5CNSVEP$Q)rVSfeHi2V+#0-ZK[A3A0-`i2qS)S
- +Il(%@9C6ALNA#11mSY$1CC[hR)"1(H`J,)&`HrX,Q'FG[2I+VUmVpk2f`-E3$e#
- b44F),&56FPh5%A0#1'C64mcZNkGMMZq)HGNraB68j%K-YcqSm0pF!QMYN[SDZi,
- $&'TY$lAYjP,cPU-qi16[lBdc#pVf)-DV,VdXNV&fI2U3!,Bp,DXS[`DJ9PXK&A6
- hRV89r(8'[FiXEYY0-iH`"GKI+9a"21mNm*4Mj2(AD![beXSZ0P"9DTbe2NpB0`,
- 9"I2e03G*JhE,HI6'&k6U#eE#!kh`NHLN&5i9Af!Yd!`R9B(m9-U'qf&QA8fTcea
- 43@R,,r&RRdTAIAVIM3rHrQ[&)aeh'&!6-RB6E$jmXIY`Gab%c6qT&@,GiBF[(B4
- ieKaKZTmIBHbF5i@8d9[2R35hM*iJ#Cr[*'cGYF3mhPk+pah@`Y,a6#HX)rc!d!L
- lV42X*8bVd958edh&IAaalMMiRkVCQ$Yql#6@5eHB1ljS,%Z)k*PI9*L,GA&M[Kh
- ,8(cNI4!bL3A!HkLUh$1FD502i&h#Y0e5UmUV"c*0Yk[a(SIheALAi(h[1'[K3+E
- VpN*9HHe!TY9Vm%CFhe#m%GFhYBVb6p5[ULST,'DDU1M,,@BlQU,JFVjm*Bkm2+p
- `!ZX6P9m0i6L'%*eCD#f"+'CrB@&qB5R64&p0QQ1-EY&cLZeiZk*hPb"Kq"mT+E@
- MEj)dH)pQ-GeleT9CaM0Ypb1PPaH2Kl5IV&*lbAL!C39Si@9i6lYb(08jF%ea64j
- @iF#-%QF*`)I![&+R(8FCJH8@G!6HGj96[3c$IGAdGKXHmh[UJ2J'AV-@jHDaF`a
- lFXfPU%p38c,ZDJKY$[BN4-cXpCeS@%23#51R[mRQNABq&h6ZiAFp5i)0#T6`@mX
- ZK3fjiRF$3beGJ(K`HE!h'"3KdT6pVU@FA,rJYZ[)jVjCcS0XFB[jbQU`XL5QDa"
- 'HRB*!QM3$0f,b2Xe`F"m55bL&falK84@$pZPX1dAMP,Xq,YiVMqQA10I*G[*9h'
- rlh2ETpNLN8AfiIPPNCmhJI[0icB`aX%[RGYZiRRXicDCDhG`fmqilFYN5aJBVPr
- #PGbfKYdQXQj,j4SE[i6YTpbfK6dX-Mf[ME'Hr9CN89(FpSIX*GJ%-Rk8[3hEMlR
- Y#AC)C0($Z1fEJJBflJPMUa#MBpelSpi("Dd`8'6GRq3e#`SQN8%D)pQ'#KEB`'%
- (fdR#j5,V`@[M5KGF)Z[*Fh)G&@E!pRPZHe2iUFL-D$Gdi4TKXBiC,d4qKl8I#+[
- KpfRb5ljED"CCla'm9qB+'d3@-i(E2L2m@Q4p2TElbI8(NF@5&%6dMHX[)ZYl$VI
- e#)H6@&`8FQTRY`[Sbl64FMqjqm*'ZQI3FqlN*(E1+-6Sl$YE-e*NmC!![dKpkFk
- (MAXhBEYQ3K)lldR-!r5d'lA-Z&$ZDIHe)KX`41h&-,Z!acB@F0ZRj,kK(MeeLPa
- lYRdh2'p'&iAR`HKIK[XqHj!!A$qbRACaZ1p2ZbFm$h,1$mq-($iRKT0#'11L@m0
- c*6G(VKrCmUV#-bR[(EPqC-[rDAL@&2aFV4pXAI*FF6H*,*h2*f1ZjREB9XKcaEd
- @YP[PZH*q&,BfHDkiYm$f$AQZZ,I$pT)m9pblBAY$RL[Z)b)cdA@,)@LeQ$&&[*p
- F2E@pB!1Q6,-NlRcBe#b*5i(YGRQ@a*PKqe1jRq+`U"6ar&bIDUq#V91H*A&1(FY
- )3,pkY"pSkd5@BC&R5G`#f(MQRAbeGKPX9mZc*!je(AZlh)Yapm-'FFr8Lh&2`FE
- ja3@e,bH"m"-jqGMY@XbBiQ5j&q-qJBf%2D!A24V%@)XBJEkcGA(`Hd$Z48mLE!4
- pS4Fp8*0@M+f6HY%c6Q6$X,05,hT+BCX3RL9RAFeY9ES+f0Cafd@kDYLNRkl9BBD
- 1kbI(mf"R'-Glb*L[Za%f+!DM2[EF"YYjmMlNDB'03ENeI+mDG`@[alGdN!$Y-fk
- bh1[NKfYfFckG!p'PHKkFbr[5@%Lfmq3GLq1G$e4&ajZ-I9R(QdVlY)ThSC`IalJ
- BCa%kaX@mTbA'aGM`c"MFaa*MKKb2Bmai2KcM%U#'1XBP"m)aURR['Sdkc0P2b)G
- 9eqRH!p++5bVZMjm`9M*EkBr$8)m*c&l(rL5d$1UkcTClMR1GrA)iedY"VDlMA5V
- AQq0GZMSFEdlrF,`jDm2a2S9G9FIlP$`[1GlF"m2a2LhAMq20Hb+m0hb'-!fe+ec
- 'mj-CIaR[GGN$,QX,la#mFULpiA+jMhP[Z*chTFcqbhPrb%j3+pH9pi"DZ5Hi0V9
- b(h"YDTH(De-Vcf-MSPX5Fpb"Q4GLM4(Bbf[jc$1%L!%k9Ki,[e3f,q*Lf+E"PXl
- QJpM@+2m4E"Q)MEeLiH-mR#X#GDPE+Hm%m6pQc"R$ECk)+KecPL&H@--LVY8a9`9
- Xf4TYa(8kjVE!PU[G&i'qEH$p(EFr!MY``bTj4XEIJKJ2)8BqD[-9(2!4*Q4S$e$
- p&J2MJ1fRh-ElT9X6FDH19GS3$m,UiZrAXDTGX)h6k#)HdE(TEYK+f)+)64"K[35
- f54SKiQAB##H!iP,+Jfj3m@[J0YQcHGBfmAhdY+L)(E$Gb'f"L,mb9NrU3Bd,&dG
- JpljkVcSE`Z`'MBaEa*q%MII[Z!mLY5,l'GpGi[C(pK(CHTjXh)H4r8Af11BmE0f
- 4D5,E8Lr[+piXNEAaf"k"FRTfSjb6emU%1Yklb+1+#I@mE`S#`D"1U$q+@PCdHc'
- b4"4Qm,dNBAYNP8kB-4aqdl[YM*`2[hp0IR0r(AQE+&c(pmLj@b,ALF*215BapcH
- 4$iM#(,iIc0dDZ8%8&[(pBqk1b0r!aR0PlUZ4,iV#BVjlcIe6j*p%B3Pf&YV*[1q
- *`P,)h+DGc0XZ#X[iER(bj'jaX0%aKY'YVGX38EJa8CjK#GQLX),2aH5eh8T&B5@
- Gj4TpQVT0JHdDHEBP9-%''H()pFqlc4D&9Aar6GM4l8C4Z2PH2Q-5Zpd"8@"lZ5f
- Tfi1!r(LIF"Qk23lb2-)1$D&E0eb4hi9pJASd!I@l'cJMcEq%PhA#,mj$Ie3+3VH
- rk)5lD1m%jSLqGpdYic4ZEVYBLIH'+0a04i'BH6iYE$a6%el3GdF-hJ-5AY4I$,K
- a!r+B!pYC1Z'H)l$0'rXFjI&lI(i6TJ8ElaaZRYr[mGh)*GZiPQiGfHlRHrET[I5
- MBC1pd+@rXVp`Rla,ZI9P+CTcKh0ER0kPeb3p`'dH[6G&FqXVh"D[[eD[qEQmchR
- eXr5Dhr!p`qLQEdM4I#6M8MjpNejcNZrC`#3hT@MRdQ8(i%6IV5RD'mlMYL6ph5R
- DPAfj,D"r3+rGqNGZ'k,IP+,p#mH3!)bHqLdTfJpNR#CCrdb+0TM&E5(peK4G0*p
- c4QrppK4G,-G,M"MpQbQk-E*8V@(k3)UZ4-BR8[A[TZL@br[aF2e"f'3R500rUYH
- YS'YH!,qq%bQkfq9iQ01jZTr,1bMCA!GiVS"JHS!5[mC,-0ehRAJja+becK,0(QG
- 0A8a*GCR()ei*S(H@1,@qVXlRM4d2LCQ,&*FTa1L-Hj68cMMD+D8cNJ6h@)YpYAS
- S#@ZT"-BERqZF@Zmf6R)jDm3UVqL[mEPVR,@e[8UG0G99hM+2D29jA9AZRS$6'dR
- &86L[TXCAS`I+("k(Xp032YfC6LRcPMXp[&TqlX#Q0+$iV@9e96k[Q&m'!B4eFMd
- $r$@jGMSTMaiQ5qJ0bjGeiG+U1Sqc&iiS*%d*f0F4JFYRLH1+4CcL,($@p%D"QU'
- rPp+F#G@G9pC'mkZYm(6RV0Vi3ZGe)Kd68"PeP#P&a9IeX[VU24AH1YA2Li2R9Pp
- YGaITTbNSQqUVVqXjeZPeeP59bk9BKSJi3!kA1$eb'JNPcMS4dRrpe!V5*-PNSUT
- Uqb9eP6"1Jc5+-0d[TCS,5mE"0j*(N!$+!r(9b'@qaqIZQe[[Kc"%b0%*Nbj0j4A
- +UkMLY8*@BESS'[CeBC0+bL'A!ef!9)-PD')Z0XF-mC-)1jErmM*dHh@0de8EGlV
- 9Vj4lPMUH$bMXMUG$i`ml2MA8mG,`rfqr4pTlL0c6UJmqEZf3!0cDTrrI[Bdd`a9
- +Eq2)FG#!hKi4lQhGRPc`)1rZQA5L[l#qV[Erl1d4ChTEpiV9iVh6h(FKA@Q%*jE
- f8!eK#bkBNXaqZ6j))Mihcc*KV$lA9`keeXee-D''$)GFZ+e35Ba"jC*"66,6@80
- 6Ja-2AmlebL(YPPRr4hD*e!3A1lheY3B3%B$#B*&)&bGq5J)Q1!lR,6,6lba(ZF-
- Pp91(N!$A--Tl83hi!KE9NK2jH%K#XSHD,#RF*FZk&8*#eY+Dk4&HFJpi1ebpPcP
- RqFXUp2Q3!+j&$KjU1`reZXqV0"r'2lppAL@0BELrDkleb2Z15McH5dRl3defE[H
- 3!'RXd"MCTJY)$DMb6TDIk10PC9-a4Xdk$&80TQXLc`(G[M4DeRk%2&DH+Gr`cTk
- JB[0UFG,CpHaLP"5d2-YL`J0CZb3TA8dEJ!mDdm2Pe4@eZJ+Rafm`Zea90G9)C)@
- c&PflA"kT3j5&63eB@LDZV#Ph+[EdXi-#GeFBP-[116eQY9rDUCQRhB+A9p@@TiR
- 95T9'R*jc1SarV-pA`@IeXLJ,'SXYQ&pk2ZSiS4,)lq5*TK`#P*mf$Xh0XiUAeh[
- UN!!KYFem6f5a9F`DBG*2+"(0*GCaik,(P45*@9NM,Kf5SD0lTf#K6q`B#eaFK"J
- cjR+c98`@m4Sc"[CNG4PADe%#aB%Qpe-k*QEr2%h-cR@kbP#1#@(,5HBCET&[)PH
- PBh&T*@(Dk0NkjmbSm996DmTUUTbe1K,9R%$&RqPdDmajS6PBA9C6kp52"fN%%83
- Nb"[(-PeZ6CQlHmF%596Aa%8'MKd8bLdG0m%qASI@@DDX@ljL0!eDTB%[8G,VF9$
- 3(!Gf%4qqBiMD*)&D!"GL(MVPp8fSUr*3AIlr!3!!$3d5-LihBM45C@aPBA0P)%j
- [G'9cQJ#3!i!!N!3"Ef)JPZS!N"%@!*!)rj!%9%9B9&)UBfJ"!+V,"05X&`l1!!!
- #RJ!!14i!!!%P!!!C&@"@Ap`!N!DA8K%!#!!mk3jR#,8VidLd$`Q("FiJ+@N44UY
- V3bmA%QG5-5K5Z,D[3EmkA@Nk*CN8*h0*-l((#GD5HSDk9Ne*Qk1`ASFFBqVGFAh
- X(3!0Vh4Dhai*BcqM-X)LXM)Ha#2K+NhL0*8G8epDPU`mdp1AjJcJk4pKiAj$-k@
- J*+0bd0!Q+A#fJ5Qa)%c(a6TBLKJDPCQ55)SVCe[49iaeE%HB5&,&fCeYCV`[`Gk
- HLQJ)P!$B8'8MR!@ai!A)kHH-T2#2j[bhj`#)FDMUI(KYMhNUUdI8Sjih2'eLfZD
- S($-Gp!Q0ZBfME(H3!%"-M%iQP3Si'VVLEe0Z+)R'r&KpG$rhkJ'MlC-Er154pl1
- XI`fmPA0)rT!!Se"(JeDYJPdG6I3%P,imJ,GL,l306[(Nm33C!'4Gb(,-@`Lebf[
- 5Z9hB2[TpZ[AmKDh9'9RiiK'!eA0p&iV2Dq-(G-!*mMK"2b+!VZZV5hifN5cNq%)
- @-PN)JKC'Q!Vm[J%mhYRlE1Ic4qEiF,*[cPaCZFlXE6qC2M5cZM(G`TNh0LZUVQi
- AjUdVR@fG1DilekET392hmd9RZYTFelfCAMp0$NZ--UIebRAIQieX*6rmTFTDZpd
- AIEEYmRic6Fm@$PXdITZ+fjLXVMTE9,,aV#l,qV+SjUDSF)@PlBUkHTSQ2b5(#e[
- 0-DdYUXc*V0+fREP`6BX4R($3cdeCY"er1bPcNrQ*mNfDIPL!Khk3!)irrNYr52l
- DBc&VrY%AfEQCBUYCF48e-FNDjbSc+Ejh"K[rXYIHEhZC"0FhcehE0I@e1F0bVX2
- e&bilRpCACZPXK5hUTHX@&%"9AflKCh2T6!k&'&YHfZ[@j(jqQR5k`6BZpV+iFMP
- 1eQB0"$5eMHPA1E5$09C025hGdZ"XYX-3#'e[qr(fE[i3JdfFR08Y&LmbZIIP!KG
- fH5%,m1LjQpQql%cV@UUYa9CZjKU(Lh2pSjQa2HC8@%!8Zi-[QqX9Ic+VXTmA''N
- E%6a(YjLd*BYPGB1I9h@9Bp8d#@+!R,`K`%BU1N6P-YNQ,faCcf@C['JY6T[c!Yr
- `BTek@0(LL%A*M@5&SX)KE3N&3d8dJbe6G1Db+%Y6BKa(p+eVc$N8Kp0E'!K@k1`
- j&i!!blUDhiKXkCCeFaf&G9Pd#c1DB*1e0@a[Eim`F[p@&FC@ZANa+!-cUE!JM8[
- 6fJY9+(q!f,S@1hcPVPFf0dZlN[QRGZlHVAEijr2k%M[phqb9Ya4c@6IRe#q%eC6
- AN!##%`[2E'AQZ1&UCXiGE!D,A(5lpqpMLH0q1B8mUU+#(#YqcTf'ACjZVX@40EB
- 9qiSq8X(#LLU[,rA1A[jbba@1#(2$&5pYDaC&Kd9HejGBYLb@d#LfRCBe6,LPfq)
- N+eLq-`X-Qe*TbjSh4`MC[@pQ6Eh%hrHh$,l'he`T6GU1-XH%D3%EKiA6AmfLEY8
- hpbH(4dIQV)(cPLV4MTC##q&p,6cR`[e*l-+fe6ei#bkbKm%[hZ`I6XaAKkrHbU!
- J*qLZbP[caR9f2&RCc(((2-H4$Z[P%LFI6aE&V"XIEd%E4EC3&fVU$YCXTMBl[l3
- 0jRF,b9IH)D2hTBNA%Nrh&M)5qj!!+@HZ@4B96!jUSep"3Y3CmJ@r[QaJ(XXk&l1
- H"(p3j`VDa(kY`l+jKEFYDhKQhA!%lN1CUjDjM2p@0C)QIPYmfI$D`3HL1r+lref
- blK(AD1HVP80fN984"P`MZI##ZH-I2F-'CR%G'JK2k82VF22+1C%2JU6F333+p51
- DZJB+l54X)L10rb)'&(lp@jVmR10fImq(UZLfAkeUE"5#BDfQ$RZN!r%,Yl4CLlM
- 3@AkeEFa4CHSQTeTU4Ji-+GSYA*S'['6ST"H@0Gb9idH$bBa`6pL5H"`rE5eF,#m
- D'!1M#2D9h!R[`e%4AkUfXa!ZI![k`AE`[@Xija)hq"Dl)Nr#baBd!PaLDFrKH("
- NF6Z%HAaCjAm+FBUZ3`rPP)`1AXp-#q[)a1Ce4DjGph"*+TIAP&eSDYCV(fHc8+V
- S%`G#"Z2-1+rY@`3p'!IqKh(e1+qZMiXK0@0Vf)h&r-ZJ-jm2df35-ZPTc+4rLT'
- Q"@R)1M25S52)6l8+[aPPhT+p#Bc-"Vj1NmV"&Pfc'95meLrTKakbKdZSmkj2)MT
- Ka)AfF((H!2*+%a(BSTKM+q33H0$#0K!)b)9UjeUMk9SK(r`%QqqA#+,%*FcpR11
- Y6eDZ+bB2ND4-&YFVCLT%5%H2CC%cF'mbJQ,9DDMKp!3Ramf@N!#4*S+DjrGM*'U
- -[RLZqIrC+#BMK4(UY!fFUi#lb$8PB90R)%$pDTd)'!MPG'VhYaTT%+PK2HY&e4q
- BRM95USY45r3GYjd`p+ZcV1S@!4pK!NH@!dV#3EK'T!a*8H+!)*JIXai-ZVJDpbX
- &)c$pRiBQqaU&BkEC@,18kHlQhF!"&IKjAPB3&'B`b@*D-GI3"$eqGKmaT1bA&3*
- li$'58RmD$l5$N!!)ek"H'FTiF5%S@9GH$e+Vc0(Kf`p*(*Gb9a!Qh6%QR%HIFMZ
- diA@'jAGUK0F5J[jhmV#mXCHh!P#Bp'KJ!()l5%XJJai`XfT"5(+f,1E9NJ#!KZ2
- @p%VQ-Md&@K('Je&8@GP(RR0+3R"3eqIQdF2lN!$5paB+-&J*LNS6qL9fdM5R33T
- @&F+-!+C@-TYi,S-l3KcF!)ITVL@JGVETqT8BC,X3VdU6+A-[YN4@D%9'6*d!)&3
- Q!4C$"RbXUU[aMFXLXm$&Z'QVm5p0E%kZ9PIJAfX,jc)C*+GNXd+m3eLHKEaGMe[
- #",q*@L2mNhK$ES8eClaqS&ffh+*40'VlbN&$B*)9M,f`45QS!eI6(+8*%@##pq#
- pHm5*'B&,)kK%3LmZqb&rcFYk#Z``m%#%JYT(5le[!*ERVJ&'UKRrB"mjXCJYi5q
- dq*J5%5qbXQlKSXapq&@ZNI93H!@2dkLM2),55j1[`*f&*Ni42hN3)MF+8,'M,"5
- RdcGRI58d"8G$mS)eB012%*HHpZ5Aq+mJGrpiFN6A*P#+D%+1,MN!'[FAa$hL+19
- I-El6Jac`09'ZjkSkmPU5+a3)5(1,JQ,5KArf'Q@(Mlp8)DB*Bc!mBSSB4`Y4cL4
- 38&B2c0(VPm+&(i)Zq(YjY@"rh,13!%3-$I&BAjqC!d$qmm#ZI!4YR%GkZ#pK2Lm
- 0FkX0%KdX+!F$3-)9'8$jm[QD2-Y0)V9@!'5T3@UhmNKLMEh@@5%JlM(18EUaEZ%
- M$1'RMTTe+mNd2d@@*h+&N!!6"ZiHL%MMZVj4RM-!X%$MG)ielik2[Yire%hkTS9
- +k146-#ik1#aBN!!b"T16`0)K#B-)0CqVplSVFLb6(#fC3Pbqmq*+If$eJPj*B4+
- 3!*(A`"')cT!!)I'p,&Ae-%Fr5H+G,2-46lepmHENl-AIAliqqHE[KbI(Cfp2AJF
- EhhMlmY$X2RLbYbQcAb2c%45LFT'-`ip$`-9C9f$Q$Pi+#kq4`le0qk$Nb'dVFKr
- UqYLp2pY#H+bZh"8a9m,FFZbkJmRc'1k``"[3@&Uc5-+A0Q4r&A$N"Nb4q$f[H`c
- +cG(qSH$ZIPUjHBd`SCNHU"IEHl&EH%D5h)dJCpTBqU@"jVNf$XaVD9l$a5lF&DS
- @#)H54&Q#-A0!92JHlcJ!(+J'KcU'MYH6P5q(B$I`f('i![D9[+EfVdBMLhb8,M'
- H$i*4MJF&ZFb[id$,%3*#G@-0QMCfBeTiF*qk%Gh[I[C3,aK*+Y%1`)bL(Gk4LY)
- JJXD0E(H$Vk"mhIl639l@$CRf'pZHHm[j01MeZmQVSf14NIafmZl-Nk[*YmH(mYd
- Ch@81af[1aDeZ)0JJ0+5[fec[)brZ+*'IiBNC'YFMF(ANqUNab3Ta@FkmC+N)TZq
- `PBq)3ej"2+,,5rC!fS-hjEhNl"JreKi-M5L9&aDQX3eR1''R"9EKZAjVRNZTKB3
- !44V%al,JGA#bkjA,YdMmR,Q`C5rX99+El"151SJ+f!4-lDDU%hGA2Jhrp#(6mec
- -TCeZbXlK@a'd)&-QTd#EC9[YkpaGP*ZN#5)N4pjZHBp0T3qA),-E#NF%5E%R`L`
- ['dR'#eb["2-J+RU+K$ji913P-&4#G,*F6`p3*),3Q4c&IMpX!9R0k`DE,VH6"0$
- cai@#IB#T#*b,RB8CH,H`1bSE4M''B[`3"M%rKR+&MH-,$&5a+"ReGeMlNi4F'K,
- KF#*NQ'HrG@'N,29JU5B4-"8cJ(Pm+9cQTP%6Ed&j54&+3T62U,X2pMaIP!D)Z5J
- X2FDeQ9d4"bLpN!#maILrjM"`TUj"!8-V0MkSL```Db)*I)iJk"f4S6Yi)AX0FKS
- 242eZX%`EZ-1`jb!-"`B*[iX92hc-fJfK12K+Lmi)@8dimY'TZK@qPjY+E`QN#G'
- GH39lXT3&Nd)*UQ8IDm[FqimM8X+QAk'Tf04FkMr[+H!3ppG,Ibb&$A"J3I&#%G3
- V0PMcfFm%lB[%ILB&Aqqr4qDi#jdb4b*1LLacqJkKC0"-i"HJ,VG0XiDK%EE(6EI
- `UqF&2F"!Bl$%lICk8-[eid+a'4LGPr8JLf`SK3cf6)5pi2Tkcm"lI2kHffE+hPD
- D-'l6&FKiI$#*4KQ[YlGh(q!c,V1QZU+''N'i'Xk)cDAeXS@U&q*EeTH@YDSddIY
- 1D[aH5%Ji3cBDUpq-6k8@*TbEb)6k-@BLRJQTP9*cQfQ9E+`9-[U6X#9S$Zi[f*K
- aA#J@4$MYCq5Ce"8DC$+$0MY3@9f$S`)6ND2A$8b&V'fSad9!VpafX$ZBDiXkl)e
- ZF$AkkN#*QGmLX#5JCP&1m+,NFTqImd+Z"5H89JC1P+&JkkhB!5m1U[6,D-P[Z%8
- 1PkLZeH189rRqRpE'Y)#bj9hQkc0qL#k'Q!22jcZ",-&CGX0N1k&Q$,)c-hU,,T3
- i-FC)LF3A51$8XHQ"M9J)l&Flr&0UJ6rY`GSM"["2$VKE4H+"lqDaJmIj[YCjfhU
- -C)AI$`$AA@81b3!p#*J5UAmPc8H&"D%Y*&q2riQ,5kZ-)c%-V5R4XGDXlJS)IVE
- "TQK&P43UMlN2pf!G5`T1U(JaEprEZ8GPhcZlYfdfP)#camKD8#56A%Q2c')b6dY
- dJ(#)3!G*!mZ&2U95)(qj(35`!XGRAh2)iAHe($(jJ1k&j!G(X&N'SaH1AU*m`Fd
- `GBTNhebRLB"+R'(M!$k!c(,Af#0jRcT08&91I"Hdb1+)dK*2*119p3CSpl#-cG4
- %-jF4JDL#5D,l%*YJ,&$1*FG!1bpJS10R3bHX(6p64-k&!ql(VZX*RX-32S*p%Z(
- &FUfQ%eZZ&RE+QM6U0XRB%ema+5*l4Eq#9H5+V$6K1#a%3F*M**C3B9%b-%0e$-P
- "5"SmfeHRT%NeTAQhS4k&BQa!CX&+C'PmLYT$Kk!H[ampleFPG3*$d@rp-Fd4pSV
- a44S)V*Ri%dFf3IMRK[*IE%Rc%Z+ND4)%&qS)1k&mfZkm4!"&e!-)8#A4jU"GlLR
- p[6`FKr%j-V&BH'@&d#qq)C!!6,J(fbc)5U'fY@9FPfdUUY5q+1*5%1Eh@YJ5+Cb
- )Ria$mrDEfmkYm%KLKU&QaYk*T!)29iLX"Dd&eBlmKlir18GQ3[)BhCAK$a'pb%a
- `h0E05Ck'mMI%0IEeFI&"Y@F*@$r5VA0i'`iJ63GTrd#T%Y'CA9!Z)N4!+#fkAYD
- MpfT'NdYp@jc$MJ%p3P[GpqDaN!#5HLmGH!kF'GD0h0b)CF2I!@a5HHL"G5LT&fJ
- 2iHR[KCJeYYUi+G!mfSadf"65F#$f'$[T12!RYXc#FN'GdK%[j6d)8R9IJ##QJ--
- @i"UD9PK*i+X&d3ejUi)*N!#*LQkF`@QSF8@k6-XX5`9r868LUdKRNF!)cLMR`#A
- BETClk@b2NRc6!TU5SS`q6m'c`6bBL"J3X"KLjYhj3"pm96+mE[%d6A'bqqEIc'M
- %AhEjbl5dLqqDll!X2pQ,(cm)(aXlaf,bcF2ipD2ibq2ibj2ibfIaPmre&ll!BEj
- VYVk$Me)$hpf@UjQdrdYH[j!!Jm%ff*h@'TT)9GpQS#U!L5pBhd[0i"A[hVi1L[r
- N&HNV9b,hQIf9*J(Khp)UPK+V$TIBV'8&!AB8,(MjV#!M2l5KjhS*d-,)MmMadaa
- 8ZVc[Sb!'(r"&@e)Pc9UmPCLYV`Lc!%e2X#!NZYj#,RA62P`#CaH!23KUb0MBJ+k
- VAK#H,9&Am'!fA"0bEp(Y@`+cBZM6m0XArJIc,2eLr4eq(S@I4ZQ)Ai)2KGp6d'H
- '-@QE56#3!!3Xp9L-!Me&J8Z#JK4miCYI2*2,UKq'&U!'8$54")e$%H+G*rLfZ5b
- JTa"(f*LB)IESpkm3$S%I"DIa#&ilBR83@kqX6CX`0qVM(36,EphQR!l"a&IKqHl
- 'HL8KH"X&m&+S+32Y&LXJ'L4"r!BmTj8rV8BKLJ8Q)@JR3MR60q@Q-3Hf$5$`#(h
- I*@Smapq)*r!+S#cFpLMU[%*lD)aFJKGQK)La&GTRa-9i`JDTAqZ%b!RdV#rT*!L
- #%,`kaThiKFhN4FilA9T@61#T[)iS6pi*3-CFeSM"#fGc+B'bYmH)*rh0SD+RR8&
- -N!#LU5kq3M-$AkfJ"FCRlFMl9h&d9PF`3L*(%JcakaM+Z)&-CfAQrI[h+'h-l!9
- ,%PJ9[6PB"QrN$b$1*P@!d-bI%%hS'Y`#M)CbJIHqHAIi5YV0J'iBq0Gk8D%m$mZ
- a1AD%p"KkqHADEJ8(Jj4bBe`eT!0ekh319JX9)SpEe#cd63iYJ4!rL`@UXf"l#53
- 8,@VPS)i46ZTE3VrPNMH5$Pa0GepJQKL),cr3QL30963rrh)$QK5G8*J3A'P!#!B
- J9`'$5LEbfFPI386$5(($RFE2!NVCLJmAa2)Nji1RS8`MlpJ`,Z%TJ(#6pDl#!AR
- mpA01(apb#Nm[-9$NIBN8mUXHr[XId-"k`G[qKJ)qm1UKrBUMJ9+%T5&P91aMEbN
- qiZ5rad`!G(a'%106IUM83M%-qhd9'5#M$BaY3akH`JIkp03QPN&$3@`F3BCmR5*
- iX)f(B54H+2i3P#8V(KQl4+$J5B,P#N'TQ'RQk(T!AS)PIB&F,"(F'A8Dj&AN5C`
- +"KXSYUBBY[d3UMe#e)6LQb"$AqXQ6mPJElIa'3Q-'[fKjLfm@D(&dRAL35f+Kh4
- i`))AF@crqTi!GT4piSB+BqpH'Q$55p1[S*!!bKbmqh+bGJM3!bcVDBBqp!"haM,
- q3P)#SVB%ih,A,9"1Ka)$#JK+GY'Q)!fFT95M*%YjE`*`+6h83J6`kh(YYj!!C`N
- '0+rp!iC!T#I5Y)#h@)a9Gm6PI0%F'qeA9AdY[1@(j!2dJ-G5!"k$#345dK9S##B
- HfK@cKXCEk3""k2'p-Kk&B96VQff+$UpQ1[pQ'CrSbA[!X'qH6q3"SrE2+BcF!5,
- %#3FXVi@(#&5#JI5cred$XC!!Cjla03@&MS*SKKUZjiem-kIfK@+6SEJS(F5U"AX
- R&"qffrMDATR(frGhATfqHbmNA"mr%B*fmm`Ca'"15f65eXP9S"8p5RKh!RQ*,b+
- N3,j2dhp0m#Idb#HQj%ffDkDN@DrY3qbL03(&Z)JpVCm)9Xa%a@`VN!$iD()L-r`
- $(HYh,[k-@aelD6#YbJY$&i@NA%R&[[)kXSM'Z%cIMPK"$%rNB2T*PS%#5+AQ$8V
- )Tch5%$)@CJmp,)1MB"42%dpPkMLBE6FfLcRTHeL-[NXPM!p6h`3ka1,B$X-f5N)
- YlLFGCK`3(A(QIm*'MKLZ`k-1(Ckm3GC0cejm4BH3!$i3IKYm3q[Yq#H[bG8ChXS
- *L*P#!(UP3Emm1YjrrITE*P$#+N))-6e+H#Cib),4S3L*R2pdC`GrEGqqeEF$d3,
- XdpApReKXq)@8rmXHq46iEemI2+MbIZN[-%5miCd*Aj!!%4M"#G,8BLX8Pq4VIEk
- 5F40(IhZ@iG&1r[J6A25Y&Yr-dcK$!a41YT-MCV,lKFFKEX*hk+H'eN,B3YqGJB!
- `EBaLcj2K8C3F99aS9Jrb1,`4Q0kpp5AX5ikr"U0K5!#@k#F3@2liq8deHY6J+N8
- &QBk8Y8K4MH6ci`YBfU3,lEEekf(KZM`SDNMqVDCBD8L6fe+$2&D!HP@SCZQl'q[
- 5D3j8"D%-(MkF!"%E3iU+lXcMXp$#"999cm%FAaI6@'VdqRUbrFLFRKj'LB9amT5
- D2YBP2re0&+(Y*r5MEPq'dSNqdE6b$0)QQT@Kk848",[qq8(%r&'3!0h`Z%NXYIM
- hL3#5j%d$f'd$I1KIeT0b$[bT`i&!(G*NJf6ZSN2VF9-b9(K'3alDq`"X["Y,ABM
- h&GE+"q6-k8Z#p9r-lq([Z#C0r$-3ILQY,rM&Y(!Kf@P(5pe$X`+kT*FcP)c&UJl
- N`6fqBIMMPa1HK[i0cJKpI[KB3UcSDk2B4Yc34k6NJD22YhEhYY$CfGi-SVBLpE9
- jd%!hj!8,UG,,`E9rJB,@kH&QG)m0a[$0L!@8"k`jJ'KFRT,mm#4Qk,YqI!Ac0jd
- pq-6&dS3'*V*kMJCEm'NTm$"lUrcNL3rD#DNX1rhF',GF2qERc46[Pm8$SHh%dbb
- CE)8NB+X*ZY[VMq0,((k+&!rYP(XqqQI%!4J-CD@2iJc6p(dY0V(AA4dB$aj(CIA
- (LfFM[*JUM"H[,X+Qf2698L28Zak1qMJLaBXVY(Ie64T8)+M&I`P&&riBAiL*M"E
- QMG$ji9R-RI@6Q2kad%'qE-qLVZecVclF*-B9mMP,ZPM-!`DT'2ZS1IM,X!iVGdc
- 6NU&rMPTIZSi"Lqd8pi)T#ir#-IU-&2p*"0-ZaJ$id3Rie82f!+$##jcbUX@kHqY
- lEp,N642rGJp6UAiLYrKM0-4BcqF`AR`%UX5A)NaMmb)f!Qmb6+`33!3hJl8hc38
- 2*M[2JHR@Xcf5[KhpkjPhHHErHHM8ZifSQlY"T8$2&1!IBjNc"i$J@6VL3*U`B+U
- 2V8VN`014J29S+qRc!rjY!CrhY2SVJ"Ji$,NM2KQmlL"TL*`0KGEdr`%!!-G4!!!
- "!*!$!43!N!-8!*!$-QjRC5"dD'8JBh9bFQ9ZG#"KFQ0SDACP)("KFh0hEh*N&&4
- PE'jPG#db,MGL0#df1'XZFfPd1!)!!J"6594%8dN#!&0*9%46593K!3!!GJ"3!*!
- 5V)lYD3!#(jd!!!&'C@3JG'mJFh9`F'aj)(4SC5"[FQPRD@jKE#"`BA0cGfpbC#"
- LC@C[FQ8J8h4eCQC*G#"hD@aX)'aPG#"jEh8JE@pND@Cj)'Pd,Ye%DA0`E'&jFb"
- K)'4TB@a[Cb"dEb"KE'a[Gb"jEh8JG'mJBfKKEQGP)(4SC5"MGA*bC@jd)'&bB`#
- 3!a!!+`!&!4J"pJ#3"J-!N!-"!*!$!43!N!-8!*!$-J)qMrJBR!#3!a`!-J!!8f9
- dC`#3!`S!!2rr!*!%!Ml5('CM:
--- 0 ----
Index: krb5/mac/telnet-k5-auth/telnet-k5-auth.sit.hqx
diff -c krb5/mac/telnet-k5-auth/telnet-k5-auth.sit.hqx:1.1.1.1 krb5/mac/telnet-k5-auth/telnet-k5-auth.sit.hqx:removed
*** krb5/mac/telnet-k5-auth/telnet-k5-auth.sit.hqx:1.1.1.1	Mon Jun  2 17:57:56 1997
--- krb5/mac/telnet-k5-auth/telnet-k5-auth.sit.hqx	Sun Mar 16 20:22:37 2003
***************
*** 1,255 ****
- (This file must be converted with BinHex 4.0)
- :%R4PE'jPG#eV05eKGA4S,R0TG!"6594%8dP8)3!!!!!Yq3!!!8E0rP0*9#%!!J!
- !,IPb6'&e!J%!!!!@!!!0!"K"GA4S6@&Z)&"XG@GTEL"5CA0[GA*MCA-!!!!"cQI
- JLj%!!!!!!!!!!!!!!!!!!!!!!!!!!!6M!!!!!2rrrrpbFh*M8P0&4!%!UXfipkV
- e)!%!!!ZY!!!!!!!!"&d!!!!!35S!!!!!!!!!!&*4)d31)LUrPmL0bMJ815fEj(a
- Eb9$40N128G'6#PH*R+9T"8+QbFeC-p8TU5bXC*1bbVUjS@Ae'$S@p'T$e1TBGk3
- Pk+!F(T!!1Yr@VchdDa[aqQ6a(U*T99V[a[M3*39qf2h)B@f[2Q#-FQ)UL%SQ#Tf
- DT381phNd8i51Jj03"pj#SC2mc3+(QB*QXp"aFRDM0JXGc"pcFMk5Hq10ha`5lrd
- hm#MH1NHmeM'mp4#0i$D"$blJm&ciK4FK##JjL[m5"YVjGRm8[f$jTr#&&q&(HXG
- HI0%b#!e!aeiX,Li''qNf3)J#M[+!frN8TmUd`l`kmSCAPmHD$RhYYGGqpZ56"`m
- ppH56+0#rp+,SE8mpY4qp,Gr[UhaU2pRpZYIXRZVYUhcbYGGqLYlf**lY%(T`j6-
- eGqM*[kfZRMVe)(V%S3H+lG$"JQr))#9hq-VcGrZ[mcmEH,Bjh"a"(Epprj+R(pY
- eh+9rHFA5h1'4$ejYrU02iZ%X!k0TQ+KXf2&QfE$6KASHG4RUlDL+XMf9ZE)$@ac
- PZmmREp@R$lZVER-kUQiM4pAjpcLUEK)pe%@Sc(klUJkkGaHpk$hJf&qqKfiT'kC
- TCF1j,qmD(LlI0I`Tp*Z"0dm"Mj3*leJKNHBreMGcZEGZ"4$m2e683XdrqN,[K&c
- dcS#lKrhb8VBrj0USX'r`LDY3h)@ilGamFA9*ZqX$2XTraKmmXLXrj$YfTm4h#9c
- alh!JT@GITj3[#8K,AY3r2,,0d4rP5dYCj-[ERp*P2Md#1[dj)T51!'QbT!&b4[c
- hI"VmqrRAcAFH%FlRe(F1aQ@qkmMiJ#rKM[[MIr+P[@1(k3Ljp0[TJ#,K8hrLI(C
- X#1T*%ZRH(j5&Ya%9F2%G@a(CSN!lAlbTk)0B,[2KqdaIe2c-[`2kIAiG`rA(r3l
- A1URm(3X2,-GVSS2L2Y[lj22@YEGh")I6$Dii*hj@A(G1r)birTci-A%&)UllR6i
- 9!([`%,G99JMdp5HIr*)i*jX1!JFa+#KSUb5"RkdSk1fcm$-9,b)Xd0clpcLTq0R
- h[rrp%IcA6re8q-%RmN9rG[`PBFf*Bdr[e%r`ICJGK&ZI&RRK43YA+lEl4*i12FK
- 6'JLiH%("2KplFIB'&h!kLMj6U`rPFEL)iEAql3J1Th%l(jJGqS#lrBRqZqBGRLS
- DNVJplkDq"4E%Y(DhY&U-Z[C!D,U03"d`)kcTTUbT"JYSQ5&G6UC-eVKNbB)kYXB
- ApE(QV'(+q!Y%PMQS"cpkr-9IS$QMIi&LI3fpmeJS%'PQ8DkSh)4LYi!R!2f1Ie9
- -drhAM)Z+H-RVj-j(R#[(M-ASTk124cmE23Bp,ari8MQQ#2lGk*'r0Mm5QrbKB!I
- k(IdFIl%B%RqAi'Q+(%hhI8Mm(a(%r+6Fef0MM!YBF4kV"cBVMqd&9QjMl!&J+fe
- -q5b`"3+$(`@(JG9BGbJTHaNBM#"LQMTJm1q"BZA!mXGe$DKFChVq*pY9!!!0$3j
- V08&eG'K0Ef4eE'8ZYB!!%b5k!!!!J!!!!!!"cQIJcP-!!!!!!!!!!!!!!!!!!!!
- !!"B!!!!!!!!!!2rrrrp069"568e$3`%!V$aa3kb3!,PI!!!+jJ!")dS!!!+Y!!!
- Pq6VM2PF!!!!!!!$'KL0%$L*b2dj8KXT-k8"6YhiBR!qI[QpKFpC-G@VaV-*pIaT
- hNT-k1m2GRCf"J)0bZ@1S,IHHJdH@E3U3!'2k+U,b[lB)')"b1e%a+M1HlR[e3a1
- ["XANJ,FUR5GS(*fB@FYeF&k+4,ZRScp50(h8'MI$`Y3@0X$#pP[B3)%a9pJU&0Y
- U'kCB@d'I*kHPr4`9(D!0'f490Q9*N6IcIcm%[hmhEM"-56Ir(p+5IJhAdl)UQIr
- 92VkG5242,aN[04bfaPfXT)PSrIlr9h$rr"MKA-)Q1RBlR-jcMr*pUHM[9&R"BTk
- aGS@(SIIrEepj"(LCQ'T05DHQ5M(YMd(`9%[PMLmkKdIkcNHA!fY"i@)(1Ni%@mk
- "4k'JI!r[rKZY0SD+EAPQr'UZph*G-pUi&1HkX@KahhX1UE`fle0mrZ4b@P6CT@4
- 44bk(64*C0d-9%125T8YP0DCNihaTRpklF+PRM1!$V&cZA4V6Kc+QYP3cPSiraTJ
- 6ArJH*IiG5M%hPNim4TQKaqE2@cVZ'%Q@T6N8'UU[FHQ%)j3C-5Q@iNY21-)TdA9
- 0hf"+[3T-bRP4CUR1q6(pQrJ3K"*&j!j1GHr5bL-%CmJ8Vp)-HI#BMfSl"r3aej5
- 9T4PG5mJ+YdD(%NV-T48&`F*i@S#!98ZkM*!!F2T8)b2,iZ)MRSLFcLLFq6R2r&X
- YUpm6c!4SaAkf[bGa-c!94rj[r%p,0bf8H$3NrEq1GrHMAZVb+Ah0FC@cYmJYS#e
- ELCjjp)K5ahmFjMYhY4fA!XAN'*IrM@)BqBeb*2mEjH6rl6H+GZ`h#Vf[12X+Slp
- 8Z'FYM"@Bp!Y#C@(aYN'+Q5f-Yl#T&UDdX0N@TKDBiK8,deMB13[E)c$9@aDQ%*M
- DbNP+[X'bef4Pm*,!$'&GfmKM*N2H9PP6h`F!!!liBfQ1qK"K0V'"$4adIK-["`h
- -Lh)(69HqjU#6VjFAahpGYePjl[IFAQbIAVfGhi$GIYfqjrDXXp2,kjedPT2-Xfa
- NAZFJmc,cFNb"'h3"4!mIbe3EG0SJlLhm)&pd)Er*2R+,NAh!"!+3!"@JX!#!'YK
- j)T'3!#4*-[cZ+-Pp(iAI0q"E0IafKjp6T'fN!q&E[r*3S%Ca+`'IHY!9m$ec#'r
- ((QSNURKmFiGIRZ9eBqqV'1C4TMCSN@%4pDiLVe,ReAX(ridhk#1HekGqa2-SRL+
- [P20DlRZZ5qq+B8'PC[!`YaSqU)YAaAJHMpY6jb[`0M0j`rb"N!#[jIk@ql[GpKY
- qiVc0@hQUjJe%LMbISN38PqDZ#IR8$KlAfkriI2p2lk"[+McZ!ldCVk"h1HFT0Hr
- (DaRM4G30m9h*H!d406$P3lf9MI(GFeK8#i5'05J4SR942mVcD4[dkc%Xk2E@$jY
- Eb'INr$H[Qp42NRa9m'9Zbdq(pD(I&Vpj"[PqSYc5)UfmD9REqq6CdVcc&dN9qTr
- kpT@@(MKG@MVd!ITjQcYHS2qA4Pm$Ai%#EeJkG+%%ElRhhLZ[P,V"Gh)f)9rpIUN
- lZ3dF+*A!ImRT`I0$kIcjp&ifH6+pPmqR4qV0Rledk![m[G2CHkAb&RkNTBI-KZp
- cq[,c1R[!Lhkr2`+rrJMjYc4R6rMdNV5**!qRZTD2FhY1Q,Jre',Y`E,J$QdIQG4
- bHLb8N!"V6bAXGANLBAmN'YjrAAA52'hj6`4e%kN(ZCC!CI8H69"r,+MG'E85U+b
- bD@Fhcr6I,UJPM&S1e0T3e'Hr&kM,",@(9-S9'T49k!j",@988'K39U&E"E@-88'
- K39Q&EK28FZ#5YhTU2#j28)h@*pikEIQ0JPV"U"8HeH8,DmV8a'-YDL@M9[N$iB"
- Dji+5CMdAU)X&Y5T'G8&qf%$YbDLPIKFSQiSpS2j!8(XaDMP38l&!U6F*DQrMV6j
- 26FGE6HUQ2)EmVJCS9fMT'$+TQc&U'9!c`MC2HkC+8$FhG&@K#[1QGEeC8,F`&'*
- eF%UK4B+k*FmS%15D5l($04k[@h%Um$)D!I8@3GfDjiD`V`Pb3bDM,"A8E6J9DNb
- 26e9G`569c+rEFUVL$RXMpCQhQ[Pe1dj90583VKf`JESpMl`QRcZBI#QPVK$8(5#
- E`bQ"cNj(Y6(6EdEjMUckV'+P"UQqE)AQ#qT1M&S1A5GAqVh0XqEd%p5G"69GY3&
- eEd(GK9-9Gj-,b'QU@92fJAU$8%NRULED,LV9GB9E8(GPe*k%#Sre4,cV+bQJ6KE
- 8[LE9&dj5Cmbl9P"hBp3+5UheDFNSAh'5S1l1U,dT0CM8#+LR#ZSHE94E)mJ0c`M
- URSaD5DRelQ#LUS5hZJ4eVeCU3%eN"k#H,DMpH!b4GP%QmQE0Z8K3pcDTkFLEkAp
- @82H"UK*1QFG6ieD6T6*4b#qSqc*UTFIMpIRGd9!LB)&D+kMl-@S&T8BD8P98+l8
- rIk[I!h9j+'+,"05JS1l2U&@%QRkY46fJP3U9LPfMV!J*kS&F9d+&EQPD9j0kN!"
- *9AhRTUMeJMT!+&6V#d1jCbX8&Y5"V93Yl'i[k#hU)"&jY3e3Y58Mck31&VU5bMH
- PUdNp@,behMfeaSlbQIiA"283mGC`4``e#1S34LdRe&3DLP1(LVFU2VIG1J$UZB)
- k61LUq043Bc+'&%%pY*@U+5QU*UL(L5KAr5&hE6,RQG6$KDjU-0#3!0)e+UK(Q05
- 1b'X8e#1&VUS@89+jh+31&p3QD"#PU%f#1S*6e9cGm%P"2BV(%+&feJdA#1V)9QU
- QEM#TShJ-%@TRhA#KS)ifU4f4Ce,(#)8kk`DcTMbkPCUT'dcU-5,b1ZZ''B*kV0#
- eXfi`UFH*YfEUKQNV2LZSBm9E1qX'NhSmVaX)YE0Z-+RMa&XlkiD,"A@md,@cEM#
- T*l45-hA$*B*D,D+mXfliR+#H+(6YV"Y-kJ56fK&j*R@Ld,@cEM#TN`5eXfkB*DL
- 6S@01SKbm,L3V*k2mXP)cmNjL90E"5Q'"DQE+NcQ9GSKp@VS#q*+JRX+T35rTp'6
- HDQE+8h8Ul3pPU'Ef1NfR0Jl1K)0&24hm!h#J0qrfHT-K4(5p3P$2B04+4S9qG$*
- HVa68-aN9H[2Z"NKkk6aN8XpUSkEcN!"*G6&U&9$KTD6,CQG+NhTfM"V9kVaZc9f
- NZQ24!&3`Ph4&3dhV@efH"0DLHSaSm05Pl4j![8T3[8D8Hj58P5*1p6%UFCB!090
- &I8e3rBDZK*V4eAaVE4Xe(DmQYFk)2!#kJYj8epC8+0"+eB+TH$@TjaM43(f@'k)
- KD-3VU105dMR2T)EDU1QFCe,VM4J#qd90+1)*fM&N8X-'0H4@`If5b,!@0@)Se1"
- 1jNP+rEUJ0KJa4*S0+3G''r9F)hX"09%S[dY9$&d*0C046+SDScCjACN+`+4U4NB
- Ke'5aE&'MKUkUfpr4dIq'S$BD9-eMTkjhU8e'j"&U*THEe#P'0'Le@UTfX+K6Bp5
- J4UZE)[86c0PC'Y5JTX`idPE-%G4TM&S@e"aAK%NpMe%VJjVMLM#TRf68UU$Q9p)
- H3U$1&G6c'E8LU#QqqNLMVC&&[B#rPI5K)+%SM3(lVGm5e1Q-@Ji+NFSm(HAI&Y4
- 2'G%!e9G(rp@NIMS@$GRqkhF%p61#kJYlE3H44Ee3+&4,3LqTN!"*[8LmYGB&,G&
- fB5hU$#0HrDk`EdUkZhQeS(j@4&jRap'NAL`85QF(LhT*+e@0*&U1&[9c)SC80@R
- GXUJc4633dhSU'Ui4e-m,DP1(ImLNIN(SfT4UT3,9G+4G#Uj8SL[T4)%4Zcj4BJ0
- eSD$1BY3U5SdSAPpl3@p4CjY[9492Hf&$U+Erp6*'V@"pRNLLb8kSTXIaLrbY05&
- [TPS'UZP*r4,AP9&GG[kbU&rQEi@HNNX$XfLURfFk@5pRe*iNk0bNFq"C(l"!A5+
- SAq%+35!dTS8&UZPrrDT"ECK+Qil*DX1NAQ%S4+KDR8GE(qB@p8Sp'LM9,Pm*eI6
- DAQ8UP,*L@p5[Y9+6E6D,qR96S96laD*qJqFK5XdiG&HB[Yj[QJTea+Y*R@-UT!8
- 5V5K#05F@c0AIfN$dbI316HUh1*8C-*0Y3)[kl4L9Z)LK9e'NISG6Q@dcmpEPJRT
- eM*TpUdQGakPN6SY,JIC"XMSdUGrPe&U2bkq!jcZPN!$T`liQ4Qd-Z*00dHEC9jd
- JU0IU9&qBG,h#UCaR[[8kNaUY5IV,Cm`ckk(j2+0!jCVT4m0E9`VU!Z1Y'RL98VV
- 1p,mMU-dm8e+hKdHENXU8G`VUprKEf6YGd*+bSf'9S&lI4S8'SNdejfhFd%C9Nr-
- !@UN,1C9fPF%@NFS0TUihmXJ$2`UafJGUNj&R8Vr2U1Ae`3l6!9"A#qS2H13"0G0
- QYkJhaGkDD4%$p5j"r5'MPJ%ej8DK9(-@bip-UYfCAdZpQ8FHSkEUmKRcc,N8Lf+
- kCPV%m0El"(8aSjE#M)jd5j43laI8@rKE'k$PQ+aj+I8"39h#GD@&BDVpBP'A'P5
- A&J&T%`eBS*UcFflP#LRJ+XPNP,CFIK[2+%$0CT5("2Aff&Zc'@@0S#lMZ3'SfBa
- L8THEe)k-mV#JVZ!aa+KNqN!aSkb-kGU48@E--rY$Ur3BJKC21MPBe$Xi9B9'EbI
- 9l#VG+DKJ1dMh$Km4e08m'P5PdFAQGYR4B2DLlZ,4!1k'C(ZB[I82J[TM6Sf'1c+
- X4EfE+p6N$N%0N!#TjXeT&[I!p"`5$@kSmb+Z8,Thq'G"[CG4fG5(P,*!06hkph%
- U-)Rr0C5FUp4+[Cp45dD0Rp!j,fV&R`6e*ic+HKYei-0Zlb`$p5q#qS"*KA+d,YN
- Y-kNreDR48-J9!,p5XYGV8KrNN3GGLP5rF5heS4M9e4"4dZi"NlU'4akK+KhaDP)
- IjVU5hJB0KQ39pD+JrNbReQZZqU!@5,NL61SMA#&iC$Bh[#5S2fI8RV52%S'T1qf
- Y&)[k#rj@d*6-d`[BXm6DU,r8UF66da&$IaA8Ac&UH6!+*TY)SNZjP[TV(N2JXA0
- V(9e!NrSEVK"3JbkLE&+KP`Ae8Dj3[GZMfTBq3VhSq5F&pEFm$d(R`*pfpX*EAa(
- 8acJe$"QPd`&[8KrRZK*UTh[l98(p(ApV4-ddPH,8hr0S),Pe30,+(UFq`Gp+h96
- ekSDh2QP5lElF@ZT62"TSPR6"f+eN0,`QU%rcM%+UALMddKRPG8(p!eG)$3r)'#S
- YkM0F)C,l)hk[1cRYE-8EJ[T(VP!d(-UN,k#q+DM2-QTC9%e@'TckPU!qaa@Lf53
- 9X-dcDdX%p8m`-ikm&HUKD#$YFTj99LfScc-UQAEQ!3ZK*pR"@LN*kTrj@i(UM@B
- k2G#-MP&Id+P6e9$%cN+8fNe3r`*6lH#8+U5Dcr6c9TB*kSZ-@UjiA"PV*&$0'(S
- T4L8'R3h8[c*U'9#pIYXM4UNp"29P3eHAAH0aDUQJ[X+QGCD0!lmF1$$V%Y3&Pbp
- I4LF[Xr-USjDI-(%bZ0K8'fY4Aq0[(8dDKdPSR2SkSjD1J4bCJXDTEh#&4[ND!c$
- LEi0#Eh,UQ%J)2'`EU@pakY%`!BFdAfhUNRHQ#ZVEM&Sj!6b(C2jdiVA@@prK-66
- 4S`3DNNq&YjDI+DJYr+f6B)4f1Q,EhLT,22)Q+@i`(@k)2-JY-)dE&!S1lKm!aj'
- 0EClecCr&mT!!h)hV#Z1C59UfUI2[l@fqG42feKjNYNG+)$+P3m`%NVYcAD'"(Bk
- NX2$@*H+Y*6"YPLM%+Zb8VM2Q64"[l4(6&8EKCR5pAEbee+#5QC'T+&rqj1Q#@XD
- S2@KYQ)S'H1Yb35hRd8!(BkH`c812h%&3+eJdP-!XP[465C3r*D+KNP(,JHVbeY6
- EC+!q,DK9I2+ZSVVlNjQ40RADmRX%Y5I,$H$!S(1NNp6,5Mm[U2Vm9c+I-Tfq`"8
- K1YpbEcjjPbNd++f3!($-b(cqD`QmY51'@QISbRcqDf`QDcZkEEUU[$R-9b8+JDH
- %MV0*+V6U@%(G)TDph%SU$mfrGiX5N4Zfj283M#c+B#%225+S@l(CT@8`5l6r`!'
- Tr$TYHE03D'YVaQG5ea8eJVS0Td,G3-"TUNp3YqA4%!V8"f$S3cUAhbTdh@lG20&
- ek,CjS[,fmFQJGT5ENd(P(GC0)@erUdRGFHf-cr@2EC[@+HqdIJVT@M*36a28RGG
- 1"LfqGCIeXd[IHqZCJYU(cF%UJ6PBRIPeaAQ#ZQYXHPCrU"eJpVDYd$4"lF[I#V2
- kXQm9FcIPhAMYj3G[ELKGBGq`fI8LSq`HQ`ZB9HJFmGBpH1fPGlk6Y9IC+%(GdjJ
- )NLQLV#N#mPjaMhibH`P2UYb24i0(QpU3!#jJ&m`*R5ULB@rf9TJfV@@M3IJTjAd
- qk&+)Yql,hPVZ#IRFB@K8TZS'iF'5pf1k9[(qd1KcSq["9KqP[p(4cmKUpF[PrGY
- kKkPi0AZ(mJ&@Gc1TUpQRP!pXl6LQ1JHYR96j)0kPL)B$8p+TFX%0-rmJSQ%!MeI
- HkdhTZQb0S!jN1@m,f%9JdXMUNC(kqNKi%L3AUhJ$kR0#S8'-@MTj9(Ae84PGP`N
- 2PMbB86FG`@DiR4*bDi&eQ3qS6`MU`BcDmfLI0QlUXG8%hPka,426Lq9$2ZKlL@J
- B!T2C58BK(C(1QABca9Z(-QSPT@Cm0U[1%04K*M8eeV,jNM)c+ar+U'3Z1af+RfL
- d`e[&Y'Rj-%EY4DRJ1D"apbiAU'C0HELT80*!'+FHBI94N[kK4mhmHL5MpQBlCG4
- $HR$AVRX[4)0`pX[$q9["#06TTe`e6P"(F#UIVEL"HT5C'e)9%5JNR1,bb(K'59$
- E-XSSTY#@d%ATV`BDD[U6X4C+S,DZlG@@3U-CYDIBbk-p8kiD+kKM'"9Q$fJqm!,
- D&C(eeU0C9SE*029J@%l9P,-Q9JMU-EaZJ&,M`lVK@&le"U"1cREC"I8ilYc5B!8
- ,042PTZY)(J[l%T!!D##k`R16rYH,VaSNU-Fc+NchJ3%B@XSE2@f&m0R)ipUSkBP
- a*R@m55A$rK28@C2-D$LKMCTmkkc*P`TU0D1@%DV52KHB+f6@VbIU-45#m4+3!2I
- X'*SeabZS%aLe(-Cc*!hkK$V6,hcBmN5Z%*5mYBQC5ZZSNlK#i"l)f)k!qR0"RF`
- lqK!0R4fXCFm,kNPmE`q2LlJh3lBj%YiUjSM)*c0UKFI9i@5cU+I%(*qTPmCpS[+
- TE-m51[meijZI95CQXXUR-HUf)i!icKhZ8af+eJE#I3bc$ZI-IlQ2F+6*Tc0U$r#
- rGcJ`9VmYYJU3!-rJrI+*i,4V'*&d$bbiFA9!920R-QT[8MC%S"C5Y@M01P[eJPA
- l#!HmI"CrUdkehhV$TV"MLN&e-HV@if$Udr'"QS1(M1h6Ee"Jlre",2JFSpl4'"&
- [2CY64ibIH#cPp4P*L%#hU-Ih&P3hkff3!0iKfd8L@91D[SdDf1N#cZCMI8S0@)r
- 9Bm"P#JkZJiF%fkLcjjXl&NJ2ALY[,TI"4&GCZ+AS&dHeQ-Vm`rRL2iZ@k2mk@ek
- dFRJVEp&0E0-@rC`[6CHI[RXKrrF$mY12,ebql))@H605mF(piGRdZr6'JKXII`Z
- qEm(rGc,TJm*p1rjpU`9,hMi1lY[clc+rGq0h@N(#I3,T*X1p1rqq!lrh5-4"0ZC
- M15)6"lXq*LpkLQaU*2jlmeccHlIahDVMF3!I$S2IIRSFb%rI`f0*KQmm6[3iJ2r
- #,hq[20[i[ai(m2praB'ccd`E$FiBQ!F[3kGqGH-,p*IR!fRe*f!V((&q@&N(Ndj
- @AcF)IKq3!&B2K2e`[-r"Yb(5kUY(dHf@B"j(1"BlU`HI"rmHhY)L[`K'XE2P2JX
- ZPeBh981H)hRc3(K2RrR[8$X51leZR3ikG*IZ(-"MLlbKD5(`5#pl11&*PmJp4RX
- $-'#mc%reJ2p,VdL[`Iqhi9[`'-SkGC5SZpLp(ir2lX42"rFc5"e$mKKa$F'pR$M
- ,50c"rfq(HbPaYF'p$,i[KrY"T"--pbhKqb0`Gj2-$rI0L9H*a$ITdF1p!Zj2`Ed
- 5lNr$[BENHVK[!V`,ee6,*F5C"rHHK!rhNA#I#IHM5%m,lUH6UQa008`d2`9Nfb5
- ZZe0RaHSb[G)L094-"rUZ@RL,p5kR`M4JTr%2em2F+CjAj%@,(i#*2*!!-5#@DI8
- HHjHc58mXm5ELG'0Fk[(B&BG6H"c#RFEKr10J3JhCUQLcYITP1`S'l#4F3Em*dq8
- pL%2Q#+jME3qQia(94VkdG(4k(!EXj(BGT9GCA5+p3cbpT*k$rj%k*DZ[e-,V'9h
- R`F4jm,(HJfBc[5F1P`F#rcR3KqS1GkVla1&'r0+U2DDlXj14FALmB!Ra#hHUhl`
- bTKpmVb+q8G$aITL(3rENXA4dYN3b$ZFL!$Vf)Yl5MAVUmDMV#GqTRR@EfR(Tl+p
- N(0UK`a2LFP%ITL2FUBj$hY@4kb(b5mG'6FDKhQ%m3FI&Cc-Gi8jel(D1h"Yd[1Z
- m&icmBZRSl2KN(&l5B`rj"ES19-m,CYYak@`IC4cUBXB6iK,LX&A(XZP-abp20h6
- NHF+)bq`q9-DKVQ9m)5jEhSlRI9Y(Cd-Vir!0a,!&(H2ef,`b@dGRCbcM8+F`[U$
- M!BHekGM3NY%aXm@@FDM(&er3XGH"6%HimrSB*Tcp('6B)UkMXeHAFHJH(5L!MTZ
- 513K#cmhJqq+2kaLpEr%3QGbfAPGRmbrMd+d-m!KG&el!G(fi6cTH1hB6-`lI#!k
- ,d&8*-&hrZ+P42mIVQqcfC-DKcQf830Hrjjq@C*`kHjdCKhUKm)JiKHqkVSNiG6C
- 2-`kGkB9!a'PhTZH@QEc6X41EFDK((KA3mqraqH#R$$hYINGf@cIM8-F[[P#AqRL
- r(HkXhp%VU@0fIcMM8&m``Y#hXISGX&fKh5I)EM4R(1Vea"rkJRdZ61UBhE(1105
- rKeVdRl*EhaPR@ja"ahIlQdNGXh[S'@Fl(#+[J!"fAc1l'CpaYNFRmNV-QXGm$0P
- GrBbc!aUJieCNJYCrq4Q@F6r$-UDME`e-d(f-9S'mIfrNPHcfJ-EC%4h3mD1iM1X
- *GqS$d(dcLjFCpEkPVl2RS(&f`KhdAE)TdaIZ90p$Mql3XqM4fKPRb*rMSfhjFra
- X&TrhaZU"Z*lCh4#0X`XD83rSr6rZ(c&dc'kVD"cZ)PkVilC`[r9$2EFQXr%qpY2
- !ZlF"VNrA9Hrr3A`q"A185AI&dYACTp%iZk)$ZQi(pmP`halZ*q%*1UIf8$41Ah4
- !jafi[M[#r@a83'HphV0dGRD@0-jZk)$1q%!FkljG5epRZdVMl)iHj+ZGi(iDh(G
- '"q,kHCLI6EU(#Gec'@`2Y#"rl3*hiR2q[c`@LM#pi8le[RZZRFHFc6D0XbFkS$F
- bN!#R3Gp%2HRXi'QF[G!!IC'"2!@k*[+8Xb@SF@!IBb3K2hqNprQcQGl3$rK)ld*
- GZ6G1NCGe[GI&Yckr`YL!QIZJXTZC'QFI0+#Imirj!ECqcSkSaYNAIG"2l`pDqMR
- EUKTR2qa"2hPA-SRhlVPb(lLI*qSJlJ-fiM'l4kYaqLIdh)h2#rTBepe"Ph2JhKI
- Z`Bdkkh8"k+Vl)"+k1TZq'QGrT%2Aj%kKaMN!Kp"9cdYjACeYDBe$GK9(0H,9fHI
- @1!HK&EVUrD(hmP"kFe6M$%!MmK#Gek2VUrZ0KGqJAGrNMU[''BKYj#0RHerMm"h
- lNBdmQpi6eML$dBUk+*&RR3f)MA-`$U%V[*rQ@Gf[Z#&Zdc[A'ZF3E+1HGEC*0Xi
- 3P#22TVIf-Fj3E#0HRBfFM6--jDMhdV[r'ZG3E%0ACkYTij!!5DRi4Rj0ldpXR-0
- a$Pd,GGi4+%Gq6HqJE*`M8Bjk+,eRPA(dbF2iK+kkIi22#c0dcHlrEC`4#9f4![m
- 'q)#SIR#RqX'GqMIJ6[dEjmqfpA3f%cI18FL'RRPr`dJX3dpRQh2M3-m-dp#c8-H
- 04MAb6G((-!ECd$2[@cJDbp$6f4VH1-HJ'[Qck&-i&Y@)ck)ri6K8)ck,IS5a@)D
- HcREkaMNHeBM2S[pJ(+U42iZqJr()KTjj[m%*U%BpAI3Cm%dNN!#-r&Rd&jb)DqK
- CU0I!miPSj-qLRf!LUU&Rd8F`#Ch3Fcc0k0hd1Ge'28ffiNP[Z'5Fb4c+hffrKmf
- ,+Ma)hqG#IimqAb2q(VlI8UlJ6qa9J4A%QqkR%I-VlAL!(IKJRNXq(XJf)XAiB[0
- KmZr4pc,*[DGaF&F#i(Z*V)eA2KpGI`r-YAC@q@$RG23KAK2k96,pB**Y9X)cF!A
- pG$p3AMqB9qeZk0LMQ"ppIa@d3VpFrAX@9U&I&HJ(dCIF6FSiI)mHR%)rf&3QY4k
- lI[30I0!*r8Mq"[eJ&BTX!R%M&r'Ah1,G1(`r)C3LIm-qr)A&'[MIm3RpS(l0V-N
- G1ekX3Mqbed4UchGaI)K&rL2kjI1I(l[3,eIre5)@p40)PebP1(EiZPjSKAlfb[U
- a%d!XmRGQiIEB13HaU2rSR[bjrK0If!b[d#rAI`SK&[8(,%Y33lEPlP5`(V(3,q5
- Qkj*R)c#-@132f*8pecf6T!KL8ApNPZ+1R3DX3Mqb9iX5F-akF-j&,2)Id5rI2e!
- `#rfD[+jm"Z5,Vk%8r31LApk!Tb%@q8peq`[cP+1)KAkD*pHmJG1)@0424,pmrl8
- *XFMI@Ue@k)&2`5cdJc9%mjX,6N8Mp10l11RkP3Bem*m90NAj"&DK(fb3!2cq22G
- T@)9qP8(YrARZjf%9qPA""Xp+F41d6f)9qP8%B8IIqNKM,S2`r6-4L[JMXcbJID!
- d"MS9[!"pd%rIViA[bfA8Vj!!2iJ$0TI!Tk-,qZe*GXpHjq00k!Kj(*`iKEPiRm)
- KG"4l!eNkNRcH03r[dbL'MVk`0lG*bQH`#aeTAUNP"9BfVm$XD!3M(QXl&SjQjb,
- X3NHS&rfZX'p+VQ-i!l[3NGCGaEP@Rd8amNUaJVmBbG!49S(0HNNZ36(U&9A0,r$
- c164#4hhZcRYj2US&3Nk#R)NVk!McGDL1-+HAlJN!prMH+jQkTDQ3!2"*M`1"L-Z
- 8MM420K8'[Rd"MFJ[HYq1le9Sj%Nbp38@kDehM+ZASJXkEY!2GL)(r5)+E%2G+H!
- XV%)r&RqUiR%@6Tk02ZLRjd&,2l,(0NcY@,q4IZZjl0rkl39jl@B83%HpcSV(B8h
- )fq8!r@*#arrXqi`1k&R&p(6P1N4I`LAd&21ei[%*de9F'L`Tk"51AmBGmL6SPmL
- 628Q*j5EqENpR`AJjZU#IAErEp4ECZ,kB+,q#2X4K5Vq'UA68@6D4I"@Vd!rb#0&
- 2Ur0SR3A[&9L&IT9-[rb#j9IL&[QMX%,Y9FL&I[P459r$,I*(BG$%el%+r5USIS@
- p,Vq"@q523[hh6G`LIfJ"Cdb-0!H[L,m'NMhbFm,QSKAkXCAQmS1f[S9Ck%Ff!3@
- hIDGqhdBVp'-VeZAMlcZBKAjGmAFe@U'IAr(jA!UB[E-qXARSJhk*2QC9VFIP9f"
- 2A#GrI"F0d'p[k2[IL4ASf"K`j`IQAB0$k*Mf[m$1)f4U6pMT4ef,1q364lpS6Di
- MFKe@S9mP1!bl*Sr14bcL6i-p4[*jF!&@S9qj&[(leIbDTM+bX,I)"rUa1ImHEBS
- MB$0DN6pBlR$"q*Y1"Eq(AHJ(`mmkpEXHZp"2GIE2[J'Yd)p1(BA"m8irB5&D8Ir
- "AJTN+HK!E6D"hiJqk+I[Ka@[RqU$l`rqrRj#[hfi(YhJql,rpA2Z#pp[33AU+Y#
- eDk$`$h#(Z"6lLDk,bkk"RMIp@cml$Y'"IPXCk&RBcN'5ISJ1k)N8k*LENLa*2m)
- KG%cjYUZBMRPrm-eSK)lT20Neq(04YRj")qU@dJDh8K`M+#e'(qU@4&iTEi""F(P
- hTb6GmMIp"M42@lB'9I"T8)YEB6$'%V5LV`,HIbd#UG%Ck,J8VHK,+,!,3l%[F5Z
- kdCF!AE[k%VHK&Ad*d+qV,h%l,P&[THYjd,1V,d'L'EIS5e!G#hf*jHK&Ai,T5$E
- IlY4b"AV4P`!GZrS5+p'*[S5qprhDZJ8'Pa3,qe8*2Imj6bDZkqE0deBGqf'mf[0
- 0E*e9'0CCe2N10%0RZ`iP1X2)mp`FYM[4KcV8lQqS5U0,mEJpGGN8ZaUVd+mFTXh
- RKj!!`L&9%NkKAc6mIUIbaqL$IRDGfH3133Fmlm1q'`h3lcmqCMd10lIbZ"[mAa&
- A+$Grl4lF)3j&2mc5Mqd4AmL%pk)9qS&kC)r"N!#cq0&pf)0qFLqC6,$F2UjIbDM
- a%`TZ!l+(khVpT0F@A,iFqU[5krcq*VqrY@$*1e1"XarrrJUr[mV[El1lSlr8`MN
- 5[k-(mFcQ-p6"hUVCLDXr352UX[AkJ5Qa,P[CNki9lU#IhMGEUemd&()&B*HBE)I
- mTqL#IRTrT6r8FDrUHSSq5d,2#TK[8*Jf*dN2SK0kkRAc1MeG$4%PClKr#&h3NqS
- BRhZEbM-`Yb(X8JTejaTd)LlY[%rQ10#dRih-Kp'([(m@hD#Yql[ke@ZZqU!@F!,
- bCabUkkAV`ppYjke+#)bZ1[d4Y#(HDCa)[C`iVi30PpbKr+U"XVjA)GD`Cd8[@lq
- HG0j&4-f0[##Z-0a"2cZ23)le"d+q3#5E4hk4d1qIqe4[h0Yq3lh!pMdTe$qra#V
- k(1A"+#`E%R'Qq%R5Vp!(r4*jT)VNFDd`KqhAZ%-p8XJMS'2346*L0K*rJch%SGa
- $,S2RElFfMp5l2@TZD6!iMlET*lh"qj&k(j6h0rr(EcSBI-e2#(d2KZr2IKb[S20
- !i$lhE[p$2JEqpbI3E4#l*rY8i+2h&cIBr#dkd3qap3a$2k5iAr"MD%1G4RA9kl9
- eqkl(mbc4XlKrkq2SK*kfEb@LGSh0NAk(223"N[&B6RUJ!r,VpdUr4bIbTGhATI[
- le+ZjH(`#ZkK(QBkjD9k5p#4@dGHST$e+PcILp#QI3KrddqFfa2XDa&F+KV4FAq0
- Tp+&1SIP4cbZLAV(cSaSHd,8J(R%9iaEp'Y*KMrLpEQF!q60B4AkXLSC$A3fR2f)
- 9qT9&eEc(JCaRd3Ipl2ihl8%8#XARd)JmU1pr[)89Kq#AL3B+#kH4RKQ"a[FrYYj
- 6"Bj"$bb!jR(Q"6f24Z5PH$b!IYjSB3l+Rp%(rHai9UHUS8LZHb&*,eMaV1Hj,G[
- H8kS3Ah,q1G*IX)GiN!$hEjkfXSISkeJkPLXH9pGLFLrL#MUZfp[l!0#a"2Ee6ZY
- )9Jr*kIJ5'U(MSl5c['9Fac,3dH[2EA-N5Ap0k2MaA"Jd3%q@Cd#2!q&H"[lTjfN
- QhATGhR6P[&(N[*c39qrr(-,c(A*3,mElSh#RHXIb+Y-EK0,VMUhDp+jS8#*dGGQ
- Xj2)3UqkB36I"+SqrTj+q*prHN!#(m[['r+EV2a*dKPfKj+1D,bNMXe%kG#"Q[D`
- 1`rkP!p3a9!I)*jI5$BFUiMV!($[3)6pU4$ld(hRIeL-4&lfS(P$RDi'1RBIN`l#
- $Z'$aQ4pI)Kq1$X6&9qKQ-C@3!2REkM1BP&K)Jj*mK"8AmAP*ZJlkA+64-!GT,0b
- 2jIkU-I"pR0"R&2YZkp+E$YYceF0LkqlDG+c)4rj0&hdqNkl2HPfJ,Jr6M@&lV)d
- AX2-8jrr)`beG1Yi,FH#R'bUAV(d[hbFrppi4r+lVVVmhrNkp[Yh'USI)A[e3U$[
- cD15afIT[Bpdh'AaYcm2pk1CC%bY3!Kq@T5rXQ`A,6fLjqA6bmIr)ZdL!VZ[kCPN
- pREeVjA'iKTj0qIJFMfhSQB[2%l!-2FZ)RNT6VN%NNfl,[r6mTikfMb#KC`8-f)@
- "U"'R95bIL%[%CdV2FPM%)cmd''!6d)PmSmpcM1FE-!A81V["%GM%K*l12%Gl,VA
- H*iMVqr&Fa`ejY3,m'm8'Z6`*RBKESX@cmf#lKa,B'1DijZSa)ESKXrcXGG"rUiB
- Xmq#eeFHVI1YNFNV)CMIGULIkDPXSRCiGiAmANrq3!'Mir`!!PeB!!!%!!!!"&!!
- !!"3!!!!bG6!"2+b,ZICe-!#q!-!!!!!3!"-!!!!!!!!!!!!"!!!5G'9XEQ9d,@X
- e,@&eG'JZFfPdG!)!!!"6594%8dP8)3!!8dP84&0*9#%"!2rrrrm!!!!!!!!!!!!
- !!!!!!!!!!!#XN!#RR`!!-VN!!!&'$lprr`%fUm(P@hrr!6HUc!r"Irm"P+al`c0
- rr`%[V)YQQRrr!6QXHm$dIrm"1Ual`29rr`%bV)ZjmArr!5kXMYRIIrm"9+b&dma
- e-!%dV)DP8J!!!6bXLlRfG6!!VJ#`!!!!$J!6!!!!!!!!!!!!!3!!!!!,G'PYC@p
- QC'&j,Q-!!!!!!"!!+`!&!4J"pJ!!!!!!!!-!!!!"!!!!!43!!!!8!!!!-J)qMrJ
- BR!!!!"`!-J!!8f9dC`!!!!S!!2rr!!!!!!)qdJL(!J:
--- 0 ----
Index: krb5/mac/telnet-k5-auth/tnae.h
diff -c krb5/mac/telnet-k5-auth/tnae.h:1.1.1.1 krb5/mac/telnet-k5-auth/tnae.h:removed
*** krb5/mac/telnet-k5-auth/tnae.h:1.1.1.1	Mon Jun  2 17:57:54 1997
--- krb5/mac/telnet-k5-auth/tnae.h	Sun Mar 16 20:22:37 2003
***************
*** 1,142 ****
- /* 
-  * Copyright 1994, The University of Texas at Austin
-  * All rights reserved.
-  */
- 
- #define authType 'TNae'					/* auth/encrypt module resource type */
- #define moduleType 'TNae'				/* auth/encrypt module file type */
- 
- #define NTMPAIRS	10					/* max type/modifier pairs */
- 
- #define	IAC	255
- #define	SB	250
- #define	SE	240
- 
- #define BOGUS 0x50015001
- 
- /*
-  * Kerberos, encryption
-  */
- #define OPT_AUTHENTICATION 37
- #define OPT_ENCRYPT 38
- 
- #define KRB_REJECT		1		/* Rejected (reason might follow) */
- #define KRB_AUTH		0		/* Authentication data follows */
- #define KRB_ACCEPT		2		/* Accepted */
- #define KRB_CHALLENGE	3		/* Challenge for mutual auth */
- #define KRB_RESPONSE	4		/* Response for mutual auth */
- 
- #define TNQ_IS			0		/* Option is ... */
- #define TNQ_SEND		1		/* send option */
- #define TNQ_REPLY		2		/* suboption reply */
- #define TNQ_NAME		3		/* suboption name */
- 
- /*
- * AUTHENTICATION option types
- */
- #define AUTH_NULL        0      /* no authentication */
- #define AUTH_KERBEROS_V4 1      /* Kerberos version 4 */
- #define AUTH_KERBEROS_V5 2      /* Kerberos version 5 */
- 
- /*
- * AUTHENTICATION option modifiers
- */
- #define AUTH_WHO_MASK         1
- #define AUTH_CLIENT_TO_SERVER 0
- #define AUTH_SERVER_TO_CLIENT 1
- #define AUTH_HOW_MASK         2
- #define AUTH_HOW_ONE_WAY      0
- #define AUTH_HOW_MUTUAL       2
- 
- /*
-  * suboption buffer offsets 
-  */
- #define SB_OPTION    0			/* option byte */
- #define SB_SUBOPTION 1          /* is, send, reply, name */
- #define SB_TYPE      2          /* authentication type */
- #define SB_MODIFIER  3          /* type modifier */
- #define SB_DATATYPE  4          /* type of data */
- #define SB_DATA      5          /* offset to first data byte */
- 
- /*
-  * ENCRYPTION suboptions
-  */
- #define	ENCRYPT_IS			0	/* I pick encryption type ... */
- #define	ENCRYPT_SUPPORT		1	/* I support encryption types ... */
- #define	ENCRYPT_REPLY		2	/* Initial setup response */
- #define	ENCRYPT_START		3	/* Am starting to send encrypted */
- #define	ENCRYPT_END			4	/* Am ending encrypted */
- #define	ENCRYPT_REQSTART	5	/* Request you start encrypting */
- #define	ENCRYPT_REQEND		6	/* Request you send encrypting */
- #define	ENCRYPT_ENC_KEYID	7
- #define	ENCRYPT_DEC_KEYID	8
- #define	ENCRYPT_CNT			9
- 
- #define	ENCTYPE_ANY			0
- #define	ENCTYPE_DES_CFB64	1
- #define	ENCTYPE_DES_OFB64	2
- #define	ENCTYPE_CNT			3
- 
- /* 
-  * authentication or encryption module entry point 
-  */
- typedef long (*module)(long func, void *parameters);
- 
- /*
-  * TNAE functions.
-  */
- enum {
- 	TNFUNC_INIT_SESSION_AUTH = 1,		/* init auth session data */
- 	TNFUNC_INIT_SESSION_ENCRYPT,		/* init encrypt session data */
- 	TNFUNC_QUERY_ENCRYPT,				/* query encryption capability */
- 	TNFUNC_INIT_CODE,					/* init code module */
- 	TNFUNC_AUTH_SEND,					/* process auth send sub-option */
- 	TNFUNC_AUTH_REPLY,					/* process auth reply sub-option */
- 	TNFUNC_ENCRYPT_SB,					/* process encryption sub-options */
- 	TNFUNC_DECRYPT,						/* decrypt data */
- 	TNFUNC_ENCRYPT						/* encrypt data */
- };
- 
- 
- /*
-  * TN code module return codes
-  */
- enum {
- 	TNREP_OK = 0,						/* no error */
- 	TNREP_START_DECRYPT,				/* start decrypting (not an error) */
- 	TNREP_AUTH_OK,						/* authentication ok */
- 	TNREP_AUTH_ERR,						/* authentication rejected */
- 	TNREP_ERROR,						/* generic error */
- 	TNREP_NOMEM							/* no memory */
- };
- 
- 
- /*
-  * Parameters
-  */
- typedef struct tnParams_ {
- 	void *authdata;						/* auth data */
- 	void *encryptdata;					/* encrypt data */
- 
- 	/* parameters for auth/encrypt_suboption */
- 	unsigned char *subbuffer;			/* sub options buffer */
- 	unsigned long sublength;
- 	unsigned char *sendbuffer;			/* buffer to return option data */
- 	unsigned long *sendlength;			/* length of return buffer */
- 	Boolean hisencrypt;					/* his encrypt option state */
- 	Boolean myencrypt;					/* my encrypt option state */
- 	char *cname;						/* pointer to cannonical hostname */
- 
- 	/* used by authencrypt.c */
- 	module entry;						/* auth/encrypt code module entry point */
- 
- 	/* data and flags for client */
- 	Boolean encrypting;					/* we are encrypting */
- 	Boolean startencrypting;			/* time to start encrypting */
- 	Boolean decrypting;					/* we are decrypting */
- 	long data;							/* for encrypt/decrypt */
- 	unsigned char *ebuf;				/* encrypt buf */
- } tnParams;
- 
- 
- 
--- 0 ----
Index: krb5/slave/.cvsignore
diff -c /dev/null krb5/slave/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:37 2003
--- krb5/slave/.cvsignore	Thu Jun  5 10:40:03 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/.cvsignore
diff -c /dev/null krb5/tests/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:37 2003
--- krb5/tests/.cvsignore	Thu Jun  5 10:40:04 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/asn.1/.cvsignore
diff -c /dev/null krb5/tests/asn.1/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:37 2003
--- krb5/tests/asn.1/.cvsignore	Thu Jun  5 10:40:05 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/asn.1/configure.in
diff -c krb5/tests/asn.1/configure.in:1.1.1.1 krb5/tests/asn.1/configure.in:removed
*** krb5/tests/asn.1/configure.in:1.1.1.1	Mon Jun  2 17:57:58 1997
--- krb5/tests/asn.1/configure.in	Sun Mar 16 20:22:37 2003
***************
*** 1,7 ****
- AC_INIT(krb5_encode_test.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_RUN_FLAGS
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/create/.cvsignore
diff -c /dev/null krb5/tests/create/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:37 2003
--- krb5/tests/create/.cvsignore	Thu Jun  5 10:40:06 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/create/configure.in
diff -c krb5/tests/create/configure.in:1.1.1.1 krb5/tests/create/configure.in:removed
*** krb5/tests/create/configure.in:1.1.1.1	Mon Jun  2 17:58:00 1997
--- krb5/tests/create/configure.in	Sun Mar 16 20:22:37 2003
***************
*** 1,7 ****
- AC_INIT(kdb5_mkdums.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- USE_KDB5_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/dejagnu/.cvsignore
diff -c /dev/null krb5/tests/dejagnu/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:37 2003
--- krb5/tests/dejagnu/.cvsignore	Thu Jun  5 10:40:07 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/dejagnu/configure.in
diff -c krb5/tests/dejagnu/configure.in:1.1.1.1 krb5/tests/dejagnu/configure.in:removed
*** krb5/tests/dejagnu/configure.in:1.1.1.1	Mon Jun  2 17:58:01 1997
--- krb5/tests/dejagnu/configure.in	Sun Mar 16 20:22:37 2003
***************
*** 1,10 ****
- AC_INIT(Makefile.in)
- CONFIG_RULES
- AC_PROG_INSTALL
- AC_CHECK_PROG(RUNTEST,runtest,runtest)
- AC_RETSIGTYPE
- CHECK_SIGNALS
- KRB5_RUN_FLAGS
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/gssapi/.cvsignore
diff -c /dev/null krb5/tests/gssapi/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/tests/gssapi/.cvsignore	Thu Jun  5 10:40:08 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/gssapi/configure.in
diff -c krb5/tests/gssapi/configure.in:1.1.1.1 krb5/tests/gssapi/configure.in:removed
*** krb5/tests/gssapi/configure.in:1.1.1.1	Mon Jun  2 17:58:03 1997
--- krb5/tests/gssapi/configure.in	Sun Mar 16 20:22:38 2003
***************
*** 1,10 ****
- AC_INIT(t_imp_name.c)
- CONFIG_RULES
- AC_CHECK_HEADERS(unistd.h stdlib.h)
- AC_CHECK_HEADER(string.h,AC_DEFINE(USE_STRING_H))
- AC_CONST
- AC_PROG_INSTALL
- USE_ANAME
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/hammer/.cvsignore
diff -c /dev/null krb5/tests/hammer/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/tests/hammer/.cvsignore	Thu Jun  5 10:40:09 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/hammer/configure.in
diff -c krb5/tests/hammer/configure.in:1.1.1.1 krb5/tests/hammer/configure.in:removed
*** krb5/tests/hammer/configure.in:1.1.1.1	Mon Jun  2 17:58:04 1997
--- krb5/tests/hammer/configure.in	Sun Mar 16 20:22:38 2003
***************
*** 1,6 ****
- AC_INIT(kdc5_hammer.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/resolve/.cvsignore
diff -c /dev/null krb5/tests/resolve/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/tests/resolve/.cvsignore	Thu Jun  5 10:40:09 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/resolve/configure.in
diff -c krb5/tests/resolve/configure.in:1.1.1.1 krb5/tests/resolve/configure.in:removed
*** krb5/tests/resolve/configure.in:1.1.1.1	Mon Jun  2 17:58:05 1997
--- krb5/tests/resolve/configure.in	Sun Mar 16 20:22:38 2003
***************
*** 1,9 ****
- AC_INIT(resolve.c)
- CONFIG_RULES
- AC_HEADER_STDC
- AC_CHECK_FUNCS(strchr)
- AC_CHECK_HEADERS(sys/param.h sys/socket.h)
- KRB5_RUN_FLAGS
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/tests/verify/.cvsignore
diff -c /dev/null krb5/tests/verify/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/tests/verify/.cvsignore	Thu Jun  5 10:40:10 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/tests/verify/configure.in
diff -c krb5/tests/verify/configure.in:1.1.1.1 krb5/tests/verify/configure.in:removed
*** krb5/tests/verify/configure.in:1.1.1.1	Mon Jun  2 17:58:05 1997
--- krb5/tests/verify/configure.in	Sun Mar 16 20:22:38 2003
***************
*** 1,7 ****
- AC_INIT(kdb5_verify.c)
- CONFIG_RULES
- AC_PROG_INSTALL
- USE_KDB5_LIBRARY
- KRB5_LIBRARIES
- V5_USE_SHARED_LIB
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/util/.cvsignore
diff -c /dev/null krb5/util/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/util/.cvsignore	Thu Jun  5 10:40:11 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/configure.in
diff -c krb5/util/configure.in:1.1.1.1 krb5/util/configure.in:removed
*** krb5/util/configure.in:1.1.1.1	Mon Jun  2 17:58:06 1997
--- krb5/util/configure.in	Sun Mar 16 20:22:38 2003
***************
*** 1,23 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- if test $krb5_cv_prog_gcc = yes ; then
-      HAVE_GCC=yes
-      else HAVE_GCC=
- fi
- 
- AC_SUBST(HAVE_GCC)
- HOST_TYPE=$krb5_cv_host
- AC_SUBST(HOST_TYPE)
- case $HOST_TYPE in
- *-*-aix*)
-        AppendRule(all::aix.bincmds)
-         ;;
- esac
- SHLIB_TAIL_COMP=$krb5_cv_shlibs_tail_comp
- AC_SUBST(SHLIB_TAIL_COMP)
- 
- CONFIG_DIRS(et ss profile pty dyn db2 send-pr)
- DO_SUBDIRS
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/util/makeshlib.sh
diff -c krb5/util/makeshlib.sh:1.1.1.2 krb5/util/makeshlib.sh:1.3
*** krb5/util/makeshlib.sh:1.1.1.2	Fri Feb 22 16:38:31 2002
--- krb5/util/makeshlib.sh	Fri Feb 22 19:55:07 2002
***************
*** 60,65 ****
--- 60,82 ----
  	fi
  	;;
  
+ 	# The "-expect_unresolved *" argument hides the fact that we don't
+ 	# provide the (static) db library when building the (dynamic) kadm5
+ 	# libraries.
+ 	echo ld -shared -expect_unresolved \* $ldflags -o $library -all $FILES $libdirfl $liblist -none -lc -update_registry ../../so_locations
+ 	ld -shared -expect_unresolved \* $ldflags -o $library -all $FILES $libdirfl $liblist -none -lc -update_registry ../../so_locations
+ 	stat=$?
+ 	;;
+ mips-*-irix*)
+ 	FILES=`for i 
+ 	do
+ 		sed -e "s;^;$i/;" -e "s; ; $i/;g" $i/DONE
+ 	done`
+ 
+ 	echo ld -shared -rdata_shared $ldflags -o $library $optflags $FILES $libdirfl $liblist
+ 	ld -shared -rdata_shared $ldflags -o $library $optflags $FILES $libdirfl $liblist
+ 	stat=$?
+ 	;;
  *)
  	echo "Host type $host not supported!"
  	exit 1
Index: krb5/util/autoconf/.cvsignore
diff -c /dev/null krb5/util/autoconf/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:38 2003
--- krb5/util/autoconf/.cvsignore	Thu Jun  5 10:40:12 1997
***************
*** 0 ****
--- 1,12 ----
+ config.log
+ autoconf
+ autoconf.info
+ standards.info
+ config.cache
+ config.status
+ Makefile
+ autoheader
+ autoreconf
+ autoupdate
+ ifnames
+ autoscan
Index: krb5/util/autoconf/autoconf.info
diff -c krb5/util/autoconf/autoconf.info:1.1.1.2 krb5/util/autoconf/autoconf.info:removed
*** krb5/util/autoconf/autoconf.info:1.1.1.2	Fri Feb 22 16:38:39 2002
--- krb5/util/autoconf/autoconf.info	Sun Mar 16 20:22:39 2003
***************
*** 1,5803 ****
- This is Info file autoconf.info, produced by Makeinfo version 1.68 from
- the input file ./autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998 Free Software
- Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Top,  Next: Introduction,  Prev: (dir),  Up: (dir)
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.  This is edition 2.13, for Autoconf version 2.13.
- 
- * Menu:
- 
- * Introduction::                Autoconf's purpose, strengths, and weaknesses.
- * Making configure Scripts::    How to organize and produce Autoconf scripts.
- * Setup::                       Initialization and output.
- * Existing Tests::              Macros that check for particular features.
- * Writing Tests::               How to write new feature checks.
- * Results::                     What to do with results from feature checks.
- * Writing Macros::              Adding new macros to Autoconf.
- * Manual Configuration::        Selecting features that can't be guessed.
- * Site Configuration::          Local defaults for `configure'.
- * Invoking configure::          How to use the Autoconf output.
- * Invoking config.status::      Recreating a configuration.
- * Questions::                   Questions about Autoconf, with answers.
- * Upgrading::                   Tips for upgrading from version 1.
- * History::                     History of Autoconf.
- * Old Macro Names::             Backward compatibility macros.
- * Environment Variable Index::  Index of environment variables used.
- * Output Variable Index::       Index of variables set in output files.
- * Preprocessor Symbol Index::   Index of C preprocessor symbols defined.
- * Macro Index::                 Index of Autoconf macros.
- 
-  -- The Detailed Node Listing --
- 
- Making `configure' Scripts
- 
- * Writing configure.in::        What to put in an Autoconf input file.
- * Invoking autoscan::           Semi-automatic `configure.in' writing.
- * Invoking ifnames::            Listing the conditionals in source code.
- * Invoking autoconf::           How to create configuration scripts.
- * Invoking autoreconf::         Remaking multiple `configure' scripts.
- 
- Initialization and Output Files
- 
- * Input::                       Where Autoconf should find files.
- * Output::                      Creating output files.
- * Makefile Substitutions::      Using output variables in `Makefile's.
- * Configuration Headers::       Creating a configuration header file.
- * Subdirectories::              Configuring independent packages together.
- * Default Prefix::              Changing the default installation prefix.
- * Versions::                    Version numbers in `configure'.
- 
- Substitutions in Makefiles
- 
- * Preset Output Variables::     Output variables that are always set.
- * Build Directories::           Supporting multiple concurrent compiles.
- * Automatic Remaking::          Makefile rules for configuring.
- 
- Configuration Header Files
- 
- * Header Templates::            Input for the configuration headers.
- * Invoking autoheader::         How to create configuration templates.
- 
- Existing Tests
- 
- * Alternative Programs::        Selecting between alternative programs.
- * Libraries::                   Library archives that might be missing.
- * Library Functions::           C library functions that might be missing.
- * Header Files::                Header files that might be missing.
- * Structures::                  Structures or members that might be missing.
- * Typedefs::                    `typedef's that might be missing.
- * C Compiler Characteristics::
- * Fortran 77 Compiler Characteristics::
- * System Services::             Operating system services.
- * UNIX Variants::               Special kludges for specific UNIX variants.
- 
- Alternative Programs
- 
- * Particular Programs::         Special handling to find certain programs.
- * Generic Programs::            How to find other programs.
- 
- Library Functions
- 
- * Particular Functions::        Special handling to find certain functions.
- * Generic Functions::           How to find other functions.
- 
- Header Files
- 
- * Particular Headers::          Special handling to find certain headers.
- * Generic Headers::             How to find other headers.
- 
- Typedefs
- 
- * Particular Typedefs::         Special handling to find certain types.
- * Generic Typedefs::            How to find other types.
- 
- Writing Tests
- 
- * Examining Declarations::      Detecting header files and declarations.
- * Examining Syntax::            Detecting language syntax features.
- * Examining Libraries::         Detecting functions and global variables.
- * Run Time::                    Testing for run-time features.
- * Portable Shell::              Shell script portability pitfalls.
- * Testing Values and Files::    Checking strings and files.
- * Multiple Cases::              Tests for several possible values.
- * Language Choice::             Selecting which language to use for testing.
- 
- Checking Run Time Behavior
- 
- * Test Programs::               Running test programs.
- * Guidelines::                  General rules for writing test programs.
- * Test Functions::              Avoiding pitfalls in test programs.
- 
- Results of Tests
- 
- * Defining Symbols::            Defining C preprocessor symbols.
- * Setting Output Variables::    Replacing variables in output files.
- * Caching Results::             Speeding up subsequent `configure' runs.
- * Printing Messages::           Notifying users of progress or problems.
- 
- Caching Results
- 
- * Cache Variable Names::        Shell variables used in caches.
- * Cache Files::                 Files `configure' uses for caching.
- 
- Writing Macros
- 
- * Macro Definitions::           Basic format of an Autoconf macro.
- * Macro Names::                 What to call your new macros.
- * Quoting::                     Protecting macros from unwanted expansion.
- * Dependencies Between Macros::  What to do when macros depend on other macros.
- 
- Dependencies Between Macros
- 
- * Prerequisite Macros::         Ensuring required information.
- * Suggested Ordering::          Warning about possible ordering problems.
- * Obsolete Macros::             Warning about old ways of doing things.
- 
- Manual Configuration
- 
- * Specifying Names::            Specifying the system type.
- * Canonicalizing::              Getting the canonical system type.
- * System Type Variables::       Variables containing the system type.
- * Using System Type::           What to do with the system type.
- 
- Site Configuration
- 
- * External Software::           Working with other optional software.
- * Package Options::             Selecting optional features.
- * Site Details::                Configuring site details.
- * Transforming Names::          Changing program names when installing.
- * Site Defaults::               Giving `configure' local defaults.
- 
- Transforming Program Names When Installing
- 
- * Transformation Options::      `configure' options to transform names.
- * Transformation Examples::     Sample uses of transforming names.
- * Transformation Rules::        `Makefile' uses of transforming names.
- 
- Running `configure' Scripts
- 
- * Basic Installation::          Instructions for typical cases.
- * Compilers and Options::       Selecting compilers and optimization.
- * Multiple Architectures::      Compiling for multiple architectures at once.
- * Installation Names::          Installing in different directories.
- * Optional Features::           Selecting optional features.
- * System Type::                 Specifying the system type.
- * Sharing Defaults::            Setting site-wide defaults for `configure'.
- * Operation Controls::          Changing how `configure' runs.
- 
- Questions About Autoconf
- 
- * Distributing::                Distributing `configure' scripts.
- * Why GNU m4::                  Why not use the standard `m4'?
- * Bootstrapping::               Autoconf and GNU `m4' require each other?
- * Why Not Imake::               Why GNU uses `configure' instead of Imake.
- 
- Upgrading From Version 1
- 
- * Changed File Names::          Files you might rename.
- * Changed Makefiles::           New things to put in `Makefile.in'.
- * Changed Macros::              Macro calls you might replace.
- * Invoking autoupdate::         Replacing old macro names in `configure.in'.
- * Changed Results::             Changes in how to check test results.
- * Changed Macro Writing::       Better ways to write your own macros.
- 
- History of Autoconf
- 
- * Genesis::                     Prehistory and naming of `configure'.
- * Exodus::                      The plagues of `m4' and Perl.
- * Leviticus::                   The priestly code of portability arrives.
- * Numbers::                     Growth and contributors.
- * Deuteronomy::                 Approaching the promises of easy configuration.
- 
- 
- File: autoconf.info,  Node: Introduction,  Next: Making configure Scripts,  Prev: Top,  Up: Top
- 
- Introduction
- ************
- 
-      A physicist, an engineer, and a computer scientist were
-      discussing the nature of God.  Surely a Physicist, said the
-      physicist, because early in the Creation, God made Light; and you
-      know, Maxwell's equations, the dual nature of electro-magnetic
-      waves, the relativist consequences... An Engineer!, said the
-      engineer, because before making Light, God split the Chaos into
-      Land and Water; it takes a hell of an engineer to handle that big
-      amount of mud, and orderly separation of solids from
-      liquids... The computer scientist shouted: And the Chaos,
-      where do you think it was coming from, hmm?
-      
-      ---Anonymous
- 
-    Autoconf is a tool for producing shell scripts that automatically
- configure software source code packages to adapt to many kinds of
- UNIX-like systems.  The configuration scripts produced by Autoconf are
- independent of Autoconf when they are run, so their users do not need to
- have Autoconf.
- 
-    The configuration scripts produced by Autoconf require no manual user
- intervention when run; they do not normally even need an argument
- specifying the system type.  Instead, they test for the presence of each
- feature that the software package they are for might need individually.
- (Before each check, they print a one-line message stating what they are
- checking for, so the user doesn't get too bored while waiting for the
- script to finish.)  As a result, they deal well with systems that are
- hybrids or customized from the more common UNIX variants.  There is no
- need to maintain files that list the features supported by each release
- of each variant of UNIX.
- 
-    For each software package that Autoconf is used with, it creates a
- configuration script from a template file that lists the system
- features that the package needs or can use.  After the shell code to
- recognize and respond to a system feature has been written, Autoconf
- allows it to be shared by many software packages that can use (or need)
- that feature.  If it later turns out that the shell code needs
- adjustment for some reason, it needs to be changed in only one place;
- all of the configuration scripts can be regenerated automatically to
- take advantage of the updated code.
- 
-    The Metaconfig package is similar in purpose to Autoconf, but the
- scripts it produces require manual user intervention, which is quite
- inconvenient when configuring large source trees.  Unlike Metaconfig
- scripts, Autoconf scripts can support cross-compiling, if some care is
- taken in writing them.
- 
-    There are several jobs related to making portable software packages
- that Autoconf currently does not do.  Among these are automatically
- creating `Makefile' files with all of the standard targets, and
- supplying replacements for standard library functions and header files
- on systems that lack them.  Work is in progress to add those features in
- the future.
- 
-    Autoconf imposes some restrictions on the names of macros used with
- `#ifdef' in C programs (*note Preprocessor Symbol Index::.).
- 
-    Autoconf requires GNU `m4' in order to generate the scripts.  It
- uses features that some UNIX versions of `m4' do not have.  It also
- overflows internal limits of some versions of `m4', including GNU `m4'
- 1.0.  You must use version 1.1 or later of GNU `m4'.  Using version 1.3
- or later will be much faster than 1.1 or 1.2.
- 
-    *Note Upgrading::, for information about upgrading from version 1.
- *Note History::, for the story of Autoconf's development.  *Note
- Questions::, for answers to some common questions about Autoconf.
- 
-    Mail suggestions and bug reports for Autoconf to
- `bug-gnu-utils@prep.ai.mit.edu'.  Please include the Autoconf version
- number, which you can get by running `autoconf --version'.
- 
- 
- File: autoconf.info,  Node: Making configure Scripts,  Next: Setup,  Prev: Introduction,  Up: Top
- 
- Making `configure' Scripts
- **************************
- 
-    The configuration scripts that Autoconf produces are by convention
- called `configure'.  When run, `configure' creates several files,
- replacing configuration parameters in them with appropriate values.
- The files that `configure' creates are:
- 
-    * one or more `Makefile' files, one in each subdirectory of the
-      package (*note Makefile Substitutions::.);
- 
-    * optionally, a C header file, the name of which is configurable,
-      containing `#define' directives (*note Configuration Headers::.);
- 
-    * a shell script called `config.status' that, when run, will recreate
-      the files listed above (*note Invoking config.status::.);
- 
-    * a shell script called `config.cache' that saves the results of
-      running many of the tests (*note Cache Files::.);
- 
-    * a file called `config.log' containing any messages produced by
-      compilers, to help debugging if `configure' makes a mistake.
- 
-    To create a `configure' script with Autoconf, you need to write an
- Autoconf input file `configure.in' and run `autoconf' on it.  If you
- write your own feature tests to supplement those that come with
- Autoconf, you might also write files called `aclocal.m4' and
- `acsite.m4'.  If you use a C header file to contain `#define'
- directives, you might also write `acconfig.h', and you will distribute
- the Autoconf-generated file `config.h.in' with the package.
- 
-    Here is a diagram showing how the files that can be used in
- configuration are produced.  Programs that are executed are suffixed by
- `*'.  Optional files are enclosed in square brackets (`[]').
- `autoconf' and `autoheader' also read the installed Autoconf macro
- files (by reading `autoconf.m4').
- 
- Files used in preparing a software package for distribution:
-      your source files --> [autoscan*] --> [configure.scan] --> configure.in
-      
-      configure.in --.   .------> autoconf* -----> configure
-                     +---+
-      [aclocal.m4] --+   `---.
-      [acsite.m4] ---'       |
-                             +--> [autoheader*] -> [config.h.in]
-      [acconfig.h] ----.     |
-                       +-----'
-      [config.h.top] --+
-      [config.h.bot] --'
-      
-      Makefile.in -------------------------------> Makefile.in
- 
- Files used in configuring a software package:
-                             .-------------> config.cache
-      configure* ------------+-------------> config.log
-                             |
-      [config.h.in] -.       v            .-> [config.h] -.
-                     +--> config.status* -+               +--> make*
-      Makefile.in ---'                    `-> Makefile ---'
- 
- * Menu:
- 
- * Writing configure.in::        What to put in an Autoconf input file.
- * Invoking autoscan::           Semi-automatic `configure.in' writing.
- * Invoking ifnames::            Listing the conditionals in source code.
- * Invoking autoconf::           How to create configuration scripts.
- * Invoking autoreconf::         Remaking multiple `configure' scripts.
- 
- 
- File: autoconf.info,  Node: Writing configure.in,  Next: Invoking autoscan,  Prev: Making configure Scripts,  Up: Making configure Scripts
- 
- Writing `configure.in'
- ======================
- 
-    To produce a `configure' script for a software package, create a
- file called `configure.in' that contains invocations of the Autoconf
- macros that test the system features your package needs or can use.
- Autoconf macros already exist to check for many features; see *Note
- Existing Tests::, for their descriptions.  For most other features, you
- can use Autoconf template macros to produce custom checks; see *Note
- Writing Tests::, for information about them.  For especially tricky or
- specialized features, `configure.in' might need to contain some
- hand-crafted shell commands.  The `autoscan' program can give you a
- good start in writing `configure.in' (*note Invoking autoscan::., for
- more information).
- 
-    The order in which `configure.in' calls the Autoconf macros is not
- important, with a few exceptions.  Every `configure.in' must contain a
- call to `AC_INIT' before the checks, and a call to `AC_OUTPUT' at the
- end (*note Output::.).  Additionally, some macros rely on other macros
- having been called first, because they check previously set values of
- some variables to decide what to do.  These macros are noted in the
- individual descriptions (*note Existing Tests::.), and they also warn
- you when creating `configure' if they are called out of order.
- 
-    To encourage consistency, here is a suggested order for calling the
- Autoconf macros.  Generally speaking, the things near the end of this
- list could depend on things earlier in it.  For example, library
- functions could be affected by typedefs and libraries.
- 
-      `AC_INIT(FILE)'
-      checks for programs
-      checks for libraries
-      checks for header files
-      checks for typedefs
-      checks for structures
-      checks for compiler characteristics
-      checks for library functions
-      checks for system services
-      `AC_OUTPUT([FILE...])'
- 
-    It is best to put each macro call on its own line in `configure.in'.
- Most of the macros don't add extra newlines; they rely on the newline
- after the macro call to terminate the commands.  This approach makes
- the generated `configure' script a little easier to read by not
- inserting lots of blank lines.  It is generally safe to set shell
- variables on the same line as a macro call, because the shell allows
- assignments without intervening newlines.
- 
-    When calling macros that take arguments, there must not be any blank
- space between the macro name and the open parenthesis.  Arguments can be
- more than one line long if they are enclosed within the `m4' quote
- characters `[' and `]'.  If you have a long line such as a list of file
- names, you can generally use a backslash at the end of a line to
- continue it logically on the next line (this is implemented by the
- shell, not by anything special that Autoconf does).
- 
-    Some macros handle two cases: what to do if the given condition is
- met, and what to do if the condition is not met.  In some places you
- might want to do something if a condition is true but do nothing if it's
- false, or vice versa.  To omit the true case, pass an empty value for
- the ACTION-IF-FOUND argument to the macro.  To omit the false case,
- omit the ACTION-IF-NOT-FOUND argument to the macro, including the comma
- before it.
- 
-    You can include comments in `configure.in' files by starting them
- with the `m4' builtin macro `dnl', which discards text up through the
- next newline.  These comments do not appear in the generated
- `configure' scripts.  For example, it is helpful to begin
- `configure.in' files with a line like this:
- 
-      dnl Process this file with autoconf to produce a configure script.
- 
- 
- File: autoconf.info,  Node: Invoking autoscan,  Next: Invoking ifnames,  Prev: Writing configure.in,  Up: Making configure Scripts
- 
- Using `autoscan' to Create `configure.in'
- =========================================
- 
-    The `autoscan' program can help you create a `configure.in' file for
- a software package.  `autoscan' examines source files in the directory
- tree rooted at a directory given as a command line argument, or the
- current directory if none is given.  It searches the source files for
- common portability problems and creates a file `configure.scan' which
- is a preliminary `configure.in' for that package.
- 
-    You should manually examine `configure.scan' before renaming it to
- `configure.in'; it will probably need some adjustments.  Occasionally
- `autoscan' outputs a macro in the wrong order relative to another
- macro, so that `autoconf' produces a warning; you need to move such
- macros manually.  Also, if you want the package to use a configuration
- header file, you must add a call to `AC_CONFIG_HEADER' (*note
- Configuration Headers::.).  You might also have to change or add some
- `#if' directives to your program in order to make it work with Autoconf
- (*note Invoking ifnames::., for information about a program that can
- help with that job).
- 
-    `autoscan' uses several data files, which are installed along with
- the distributed Autoconf macro files, to determine which macros to
- output when it finds particular symbols in a package's source files.
- These files all have the same format.  Each line consists of a symbol,
- whitespace, and the Autoconf macro to output if that symbol is
- encountered.  Lines starting with `#' are comments.
- 
-    `autoscan' is only installed if you already have Perl installed.
- `autoscan' accepts the following options:
- 
- `--help'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
-      Look for the data files in directory DIR instead of the default
-      installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--verbose'
-      Print the names of the files it examines and the potentially
-      interesting symbols it finds in them.  This output can be
-      voluminous.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking ifnames,  Next: Invoking autoconf,  Prev: Invoking autoscan,  Up: Making configure Scripts
- 
- Using `ifnames' to List Conditionals
- ====================================
- 
-    `ifnames' can help when writing a `configure.in' for a software
- package.  It prints the identifiers that the package already uses in C
- preprocessor conditionals.  If a package has already been set up to
- have some portability, this program can help you figure out what its
- `configure' needs to check for.  It may help fill in some gaps in a
- `configure.in' generated by `autoscan' (*note Invoking autoscan::.).
- 
-    `ifnames' scans all of the C source files named on the command line
- (or the standard input, if none are given) and writes to the standard
- output a sorted list of all the identifiers that appear in those files
- in `#if', `#elif', `#ifdef', or `#ifndef' directives.  It prints each
- identifier on a line, followed by a space-separated list of the files
- in which that identifier occurs.
- 
- `ifnames' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  Only used to get the version
-      number.  You can also set the `AC_MACRODIR' environment variable
-      to a directory; this option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking autoconf,  Next: Invoking autoreconf,  Prev: Invoking ifnames,  Up: Making configure Scripts
- 
- Using `autoconf' to Create `configure'
- ======================================
- 
-    To create `configure' from `configure.in', run the `autoconf'
- program with no arguments.  `autoconf' processes `configure.in' with
- the `m4' macro processor, using the Autoconf macros.  If you give
- `autoconf' an argument, it reads that file instead of `configure.in'
- and writes the configuration script to the standard output instead of
- to `configure'.  If you give `autoconf' the argument `-', it reads the
- standard input instead of `configure.in' and writes the configuration
- script on the standard output.
- 
-    The Autoconf macros are defined in several files.  Some of the files
- are distributed with Autoconf; `autoconf' reads them first.  Then it
- looks for the optional file `acsite.m4' in the directory that contains
- the distributed Autoconf macro files, and for the optional file
- `aclocal.m4' in the current directory.  Those files can contain your
- site's or the package's own Autoconf macro definitions (*note Writing
- Macros::., for more information).  If a macro is defined in more than
- one of the files that `autoconf' reads, the last definition it reads
- overrides the earlier ones.
- 
-    `autoconf' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--localdir=DIR'
- `-l DIR'
-      Look for the package file `aclocal.m4' in directory DIR instead of
-      in the current directory.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the installed macro files in directory DIR.  You can also
-      set the `AC_MACRODIR' environment variable to a directory; this
-      option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking autoreconf,  Prev: Invoking autoconf,  Up: Making configure Scripts
- 
- Using `autoreconf' to Update `configure' Scripts
- ================================================
- 
-    If you have a lot of Autoconf-generated `configure' scripts, the
- `autoreconf' program can save you some work.  It runs `autoconf' (and
- `autoheader', where appropriate) repeatedly to remake the Autoconf
- `configure' scripts and configuration header templates in the directory
- tree rooted at the current directory.  By default, it only remakes
- those files that are older than their `configure.in' or (if present)
- `aclocal.m4'.  Since `autoheader' does not change the timestamp of its
- output file if the file wouldn't be changing, this is not necessarily
- the minimum amount of work.  If you install a new version of Autoconf,
- you can make `autoreconf' remake *all* of the files by giving it the
- `--force' option.
- 
-    If you give `autoreconf' the `--macrodir=DIR' or `--localdir=DIR'
- options, it passes them down to `autoconf' and `autoheader' (with
- relative paths adjusted properly).
- 
-    `autoreconf' does not support having, in the same directory tree,
- both directories that are parts of a larger package (sharing
- `aclocal.m4' and `acconfig.h'), and directories that are independent
- packages (each with their own `aclocal.m4' and `acconfig.h').  It
- assumes that they are all part of the same package, if you use
- `--localdir', or that each directory is a separate package, if you
- don't use it.  This restriction may be removed in the future.
- 
-    *Note Automatic Remaking::, for `Makefile' rules to automatically
- remake `configure' scripts when their source files change.  That method
- handles the timestamps of configuration header templates properly, but
- does not pass `--macrodir=DIR' or `--localdir=DIR'.
- 
- `autoreconf' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--force'
- `-f'
-      Remake even `configure' scripts and configuration headers that are
-      newer than their input files (`configure.in' and, if present,
-      `aclocal.m4').
- 
- `--localdir=DIR'
- `-l DIR'
-      Have `autoconf' and `autoheader' look for the package files
-      `aclocal.m4' and (`autoheader' only) `acconfig.h' (but not
-      `FILE.top' and `FILE.bot') in directory DIR instead of in the
-      directory containing each `configure.in'.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--verbose'
-      Print the name of each directory where `autoreconf' runs
-      `autoconf' (and `autoheader', if appropriate).
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Setup,  Next: Existing Tests,  Prev: Making configure Scripts,  Up: Top
- 
- Initialization and Output Files
- *******************************
- 
-    Autoconf-generated `configure' scripts need some information about
- how to initialize, such as how to find the package's source files; and
- about the output files to produce.  The following sections describe
- initialization and creating output files.
- 
- * Menu:
- 
- * Input::                       Where Autoconf should find files.
- * Output::                      Creating output files.
- * Makefile Substitutions::      Using output variables in `Makefile's.
- * Configuration Headers::       Creating a configuration header file.
- * Subdirectories::              Configuring independent packages together.
- * Default Prefix::              Changing the default installation prefix.
- * Versions::                    Version numbers in `configure'.
- 
- 
- File: autoconf.info,  Node: Input,  Next: Output,  Prev: Setup,  Up: Setup
- 
- Finding `configure' Input
- =========================
- 
-    Every `configure' script must call `AC_INIT' before doing anything
- else.  The only other required macro is `AC_OUTPUT' (*note Output::.).
- 
-  - Macro: AC_INIT (UNIQUE-FILE-IN-SOURCE-DIR)
-      Process any command-line arguments and find the source code
-      directory.  UNIQUE-FILE-IN-SOURCE-DIR is some file that is in the
-      package's source directory; `configure' checks for this file's
-      existence to make sure that the directory that it is told contains
-      the source code in fact does.  Occasionally people accidentally
-      specify the wrong directory with `--srcdir'; this is a safety
-      check.  *Note Invoking configure::, for more information.
- 
-    Packages that do manual configuration or use the `install' program
- might need to tell `configure' where to find some other shell scripts
- by calling `AC_CONFIG_AUX_DIR', though the default places it looks are
- correct for most cases.
- 
-  - Macro: AC_CONFIG_AUX_DIR(DIR)
-      Use the `install-sh', `config.sub', `config.guess', and Cygnus
-      `configure' scripts that are in directory DIR.  These are
-      auxiliary files used in configuration.  DIR can be either absolute
-      or relative to `SRCDIR'.  The default is `SRCDIR' or `SRCDIR/..' or
-      `SRCDIR/../..', whichever is the first that contains `install-sh'.
-      The other files are not checked for, so that using
-      `AC_PROG_INSTALL' does not automatically require distributing the
-      other auxiliary files.  It checks for `install.sh' also, but that
-      name is obsolete because some `make' programs have a rule that
-      creates `install' from it if there is no `Makefile'.
- 
- 
- File: autoconf.info,  Node: Output,  Next: Makefile Substitutions,  Prev: Input,  Up: Setup
- 
- Creating Output Files
- =====================
- 
-    Every Autoconf-generated `configure' script must finish by calling
- `AC_OUTPUT'.  It is the macro that creates the `Makefile's and optional
- other files resulting from configuration.  The only other required
- macro is `AC_INIT' (*note Input::.).
- 
-  - Macro: AC_OUTPUT ([FILE... [, EXTRA-CMDS [, INIT-CMDS]]])
-      Create output files.  Call this macro once, at the end of
-      `configure.in'.  The FILE... argument is a whitespace-separated
-      list of output files; it may be empty.  This macro creates each
-      file `FILE' by copying an input file (by default named `FILE.in'),
-      substituting the output variable values.  *Note Makefile
-      Substitutions::, for more information on using output variables.
-      *Note Setting Output Variables::, for more information on creating
-      them.  This macro creates the directory that the file is in if it
-      doesn't exist (but not the parents of that directory).  Usually,
-      `Makefile's are created this way, but other files, such as
-      `.gdbinit', can be specified as well.
- 
-      If `AC_CONFIG_HEADER', `AC_LINK_FILES', or `AC_CONFIG_SUBDIRS' has
-      been called, this macro also creates the files named as their
-      arguments.
- 
-      A typical call to `AC_OUTPUT' looks like this:
-           AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)
- 
-      You can override an input file name by appending to FILE a
-      colon-separated list of input files.  Examples:
-           AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
-           AC_OUTPUT(Makefile:templates/vars.mk:Makefile.in:templates/rules.mk)
-      Doing this allows you to keep your file names acceptable to
-      MS-DOS, or to prepend and/or append boilerplate to the file.
- 
-      If you pass EXTRA-CMDS, those commands will be inserted into
-      `config.status' to be run after all its other processing.  If
-      INIT-CMDS are given, they are inserted just before EXTRA-CMDS,
-      with shell variable, command, and backslash substitutions
-      performed on them in `configure'.  You can use INIT-CMDS to pass
-      variables from `configure' to the EXTRA-CMDS.  If
-      `AC_OUTPUT_COMMANDS' has been called, the commands given to it are
-      run just before the commands passed to this macro.
- 
-  - Macro: AC_OUTPUT_COMMANDS (EXTRA-CMDS [, INIT-CMDS])
-      Specify additional shell commands to run at the end of
-      `config.status', and shell commands to initialize any variables
-      from `configure'.  This macro may be called multiple times.  Here
-      is an unrealistic example:
- 
-           fubar=27
-           AC_OUTPUT_COMMANDS([echo this is extra $fubar, and so on.], fubar=$fubar)
-           AC_OUTPUT_COMMANDS([echo this is another, extra, bit], [echo init bit])
- 
-    If you run `make' on subdirectories, you should run it using the
- `make' variable `MAKE'.  Most versions of `make' set `MAKE' to the name
- of the `make' program plus any options it was given.  (But many do not
- include in it the values of any variables set on the command line, so
- those are not passed on automatically.)  Some old versions of `make' do
- not set this variable.  The following macro allows you to use it even
- with those versions.
- 
-  - Macro: AC_PROG_MAKE_SET
-      If `make' predefines the variable `MAKE', define output variable
-      `SET_MAKE' to be empty.  Otherwise, define `SET_MAKE' to contain
-      `MAKE=make'.  Calls `AC_SUBST' for `SET_MAKE'.
- 
-    To use this macro, place a line like this in each `Makefile.in' that
- runs `MAKE' on other directories:
- 
-      @SET_MAKE@
- 
- 
- File: autoconf.info,  Node: Makefile Substitutions,  Next: Configuration Headers,  Prev: Output,  Up: Setup
- 
- Substitutions in Makefiles
- ==========================
- 
-    Each subdirectory in a distribution that contains something to be
- compiled or installed should come with a file `Makefile.in', from which
- `configure' will create a `Makefile' in that directory.  To create a
- `Makefile', `configure' performs a simple variable substitution,
- replacing occurrences of `@VARIABLE@' in `Makefile.in' with the value
- that `configure' has determined for that variable.  Variables that are
- substituted into output files in this way are called "output
- variables".  They are ordinary shell variables that are set in
- `configure'.  To make `configure' substitute a particular variable into
- the output files, the macro `AC_SUBST' must be called with that
- variable name as an argument.  Any occurrences of `@VARIABLE@' for
- other variables are left unchanged.  *Note Setting Output Variables::,
- for more information on creating output variables with `AC_SUBST'.
- 
-    A software package that uses a `configure' script should be
- distributed with a file `Makefile.in', but no `Makefile'; that way, the
- user has to properly configure the package for the local system before
- compiling it.
- 
-    *Note Makefile Conventions: (standards)Makefile Conventions, for
- more information on what to put in `Makefile's.
- 
- * Menu:
- 
- * Preset Output Variables::     Output variables that are always set.
- * Build Directories::           Supporting multiple concurrent compiles.
- * Automatic Remaking::          Makefile rules for configuring.
- 
- 
- File: autoconf.info,  Node: Preset Output Variables,  Next: Build Directories,  Prev: Makefile Substitutions,  Up: Makefile Substitutions
- 
- Preset Output Variables
- -----------------------
- 
-    Some output variables are preset by the Autoconf macros.  Some of the
- Autoconf macros set additional output variables, which are mentioned in
- the descriptions for those macros.  *Note Output Variable Index::, for a
- complete list of output variables.  Here is what each of the preset ones
- contains.  *Note Variables for Installation Directories:
- (standards)Directory Variables, for more information about the
- variables with names that end in `dir'.
- 
-  - Variable: bindir
-      The directory for installing executables that users run.
- 
-  - Variable: configure_input
-      A comment saying that the file was generated automatically by
-      `configure' and giving the name of the input file.  `AC_OUTPUT'
-      adds a comment line containing this variable to the top of every
-      `Makefile' it creates.  For other files, you should reference this
-      variable in a comment at the top of each input file.  For example,
-      an input shell script should begin like this:
- 
-           #! /bin/sh
-           # @configure_input@
- 
-      The presence of that line also reminds people editing the file
-      that it needs to be processed by `configure' in order to be used.
- 
-  - Variable: datadir
-      The directory for installing read-only architecture-independent
-      data.
- 
-  - Variable: exec_prefix
-      The installation prefix for architecture-dependent files.
- 
-  - Variable: includedir
-      The directory for installing C header files.
- 
-  - Variable: infodir
-      The directory for installing documentation in Info format.
- 
-  - Variable: libdir
-      The directory for installing object code libraries.
- 
-  - Variable: libexecdir
-      The directory for installing executables that other programs run.
- 
-  - Variable: localstatedir
-      The directory for installing modifiable single-machine data.
- 
-  - Variable: mandir
-      The top-level directory for installing documentation in man format.
- 
-  - Variable: oldincludedir
-      The directory for installing C header files for non-gcc compilers.
- 
-  - Variable: prefix
-      The installation prefix for architecture-independent files.
- 
-  - Variable: sbindir
-      The directory for installing executables that system
-      administrators run.
- 
-  - Variable: sharedstatedir
-      The directory for installing modifiable architecture-independent
-      data.
- 
-  - Variable: srcdir
-      The directory that contains the source code for that `Makefile'.
- 
-  - Variable: sysconfdir
-      The directory for installing read-only single-machine data.
- 
-  - Variable: top_srcdir
-      The top-level source code directory for the package.  In the
-      top-level directory, this is the same as `srcdir'.
- 
-  - Variable: CFLAGS
-      Debugging and optimization options for the C compiler.  If it is
-      not set in the environment when `configure' runs, the default
-      value is set when you call `AC_PROG_CC' (or empty if you don't).
-      `configure' uses this variable when compiling programs to test for
-      C features.
- 
-  - Variable: CPPFLAGS
-      Header file search directory (`-IDIR') and any other miscellaneous
-      options for the C preprocessor and compiler.  If it is not set in
-      the environment when `configure' runs, the default value is empty.
-      `configure' uses this variable when compiling or preprocessing
-      programs to test for C features.
- 
-  - Variable: CXXFLAGS
-      Debugging and optimization options for the C++ compiler.  If it is
-      not set in the environment when `configure' runs, the default
-      value is set when you call `AC_PROG_CXX' (or empty if you don't).
-      `configure' uses this variable when compiling programs to test for
-      C++ features.
- 
-  - Variable: FFLAGS
-      Debugging and optimization options for the Fortran 77 compiler.
-      If it is not set in the environment when `configure' runs, the
-      default value is set when you call `AC_PROG_F77' (or empty if you
-      don't).  `configure' uses this variable when compiling programs to
-      test for Fortran 77 features.
- 
-  - Variable: DEFS
-      `-D' options to pass to the C compiler.  If `AC_CONFIG_HEADER' is
-      called, `configure' replaces `@DEFS@' with `-DHAVE_CONFIG_H'
-      instead (*note Configuration Headers::.).  This variable is not
-      defined while `configure' is performing its tests, only when
-      creating the output files.  *Note Setting Output Variables::, for
-      how to check the results of previous tests.
- 
-  - Variable: LDFLAGS
-      Stripping (`-s') and any other miscellaneous options for the
-      linker.  If it is not set in the environment when `configure' runs,
-      the default value is empty.  `configure' uses this variable when
-      linking programs to test for C features.
- 
-  - Variable: LIBS
-      `-l' and `-L' options to pass to the linker.
- 
- 
- File: autoconf.info,  Node: Build Directories,  Next: Automatic Remaking,  Prev: Preset Output Variables,  Up: Makefile Substitutions
- 
- Build Directories
- -----------------
- 
-    You can support compiling a software package for several
- architectures simultaneously from the same copy of the source code.
- The object files for each architecture are kept in their own directory.
- 
-    To support doing this, `make' uses the `VPATH' variable to find the
- files that are in the source directory.  GNU `make' and most other
- recent `make' programs can do this.  Older `make' programs do not
- support `VPATH'; when using them, the source code must be in the same
- directory as the object files.
- 
-    To support `VPATH', each `Makefile.in' should contain two lines that
- look like:
- 
-      srcdir = @srcdir@
-      VPATH = @srcdir@
- 
-    Do not set `VPATH' to the value of another variable, for example
- `VPATH = $(srcdir)', because some versions of `make' do not do variable
- substitutions on the value of `VPATH'.
- 
-    `configure' substitutes in the correct value for `srcdir' when it
- produces `Makefile'.
- 
-    Do not use the `make' variable `$<', which expands to the pathname
- of the file in the source directory (found with `VPATH'), except in
- implicit rules.  (An implicit rule is one such as `.c.o', which tells
- how to create a `.o' file from a `.c' file.)  Some versions of `make'
- do not set `$<' in explicit rules; they expand it to an empty value.
- 
-    Instead, `Makefile' command lines should always refer to source
- files by prefixing them with `$(srcdir)/'.  For example:
- 
-      time.info: time.texinfo
-              $(MAKEINFO) $(srcdir)/time.texinfo
- 
- 
- File: autoconf.info,  Node: Automatic Remaking,  Prev: Build Directories,  Up: Makefile Substitutions
- 
- Automatic Remaking
- ------------------
- 
-    You can put rules like the following in the top-level `Makefile.in'
- for a package to automatically update the configuration information when
- you change the configuration files.  This example includes all of the
- optional files, such as `aclocal.m4' and those related to configuration
- header files.  Omit from the `Makefile.in' rules any of these files
- that your package does not use.
- 
-    The `${srcdir}/' prefix is included because of limitations in the
- `VPATH' mechanism.
- 
-    The `stamp-' files are necessary because the timestamps of
- `config.h.in' and `config.h' will not be changed if remaking them does
- not change their contents.  This feature avoids unnecessary
- recompilation.  You should include the file `stamp-h.in' your package's
- distribution, so `make' will consider `config.h.in' up to date.  On
- some old BSD systems, `touch' or any command that results in an empty
- file does not update the timestamps, so use a command like `echo' as a
- workaround.
- 
-      ${srcdir}/configure: configure.in aclocal.m4
-              cd ${srcdir} && autoconf
-      
-      # autoheader might not change config.h.in, so touch a stamp file.
-      ${srcdir}/config.h.in: stamp-h.in
-      ${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h \
-          config.h.top config.h.bot
-              cd ${srcdir} && autoheader
-              echo timestamp > ${srcdir}/stamp-h.in
-      
-      config.h: stamp-h
-      stamp-h: config.h.in config.status
-              ./config.status
-      
-      Makefile: Makefile.in config.status
-              ./config.status
-      
-      config.status: configure
-              ./config.status --recheck
- 
-    In addition, you should pass `echo timestamp > stamp-h' in the
- EXTRA-CMDS argument to `AC_OUTPUT', so `config.status' will ensure that
- `config.h' is considered up to date.  *Note Output::, for more
- information about `AC_OUTPUT'.
- 
-    *Note Invoking config.status::, for more examples of handling
- configuration-related dependencies.
- 
- 
- File: autoconf.info,  Node: Configuration Headers,  Next: Subdirectories,  Prev: Makefile Substitutions,  Up: Setup
- 
- Configuration Header Files
- ==========================
- 
-    When a package tests more than a few C preprocessor symbols, the
- command lines to pass `-D' options to the compiler can get quite long.
- This causes two problems.  One is that the `make' output is hard to
- visually scan for errors.  More seriously, the command lines can exceed
- the length limits of some operating systems.  As an alternative to
- passing `-D' options to the compiler, `configure' scripts can create a
- C header file containing `#define' directives.  The `AC_CONFIG_HEADER'
- macro selects this kind of output.  It should be called right after
- `AC_INIT'.
- 
-    The package should `#include' the configuration header file before
- any other header files, to prevent inconsistencies in declarations (for
- example, if it redefines `const').  Use `#include <config.h>' instead
- of `#include "config.h"', and pass the C compiler a `-I.' option (or
- `-I..'; whichever directory contains `config.h').  That way, even if
- the source directory is configured itself (perhaps to make a
- distribution), other build directories can also be configured without
- finding the `config.h' from the source directory.
- 
-  - Macro: AC_CONFIG_HEADER (HEADER-TO-CREATE ...)
-      Make `AC_OUTPUT' create the file(s) in the whitespace-separated
-      list HEADER-TO-CREATE containing C preprocessor `#define'
-      statements, and replace `@DEFS@' in generated files with
-      `-DHAVE_CONFIG_H' instead of the value of `DEFS'.  The usual name
-      for HEADER-TO-CREATE is `config.h'.
- 
-      If HEADER-TO-CREATE already exists and its contents are identical
-      to what `AC_OUTPUT' would put in it, it is left alone.  Doing this
-      allows some changes in configuration without needlessly causing
-      object files that depend on the header file to be recompiled.
- 
-      Usually the input file is named `HEADER-TO-CREATE.in'; however,
-      you can override the input file name by appending to
-      HEADER-TO-CREATE, a colon-separated list of input files.  Examples:
-           AC_CONFIG_HEADER(defines.h:defines.hin)
-           AC_CONFIG_HEADER(defines.h:defs.pre:defines.h.in:defs.post)
- 
-      Doing this allows you to keep your file names acceptable to
-      MS-DOS, or to prepend and/or append boilerplate to the file.
- 
- * Menu:
- 
- * Header Templates::            Input for the configuration headers.
- * Invoking autoheader::         How to create configuration templates.
- 
- 
- File: autoconf.info,  Node: Header Templates,  Next: Invoking autoheader,  Prev: Configuration Headers,  Up: Configuration Headers
- 
- Configuration Header Templates
- ------------------------------
- 
-    Your distribution should contain a template file that looks as you
- want the final header file to look, including comments, with default
- values in the `#define' statements.  For example, suppose your
- `configure.in' makes these calls:
- 
-      AC_CONFIG_HEADER(conf.h)
-      AC_CHECK_HEADERS(unistd.h)
- 
- Then you could have code like the following in `conf.h.in'.  On systems
- that have `unistd.h', `configure' will change the 0 to a 1.  On other
- systems, it will leave the line unchanged.
- 
-      /* Define as 1 if you have unistd.h.  */
-      #define HAVE_UNISTD_H 0
- 
-    Alternately, if your code tests for configuration options using
- `#ifdef' instead of `#if', a default value can be to `#undef' the
- variable instead of to define it to a value.  On systems that have
- `unistd.h', `configure' will change the second line to read `#define
- HAVE_UNISTD_H 1'.  On other systems, it will comment that line out (in
- case the system predefines that symbol).
- 
-      /* Define if you have unistd.h.  */
-      #undef HAVE_UNISTD_H
- 
- 
- File: autoconf.info,  Node: Invoking autoheader,  Prev: Header Templates,  Up: Configuration Headers
- 
- Using `autoheader' to Create `config.h.in'
- ------------------------------------------
- 
-    The `autoheader' program can create a template file of C `#define'
- statements for `configure' to use.  If `configure.in' invokes
- `AC_CONFIG_HEADER(FILE)', `autoheader' creates `FILE.in'; if multiple
- file arguments are given, the first one is used.  Otherwise,
- `autoheader' creates `config.h.in'.
- 
-    If you give `autoheader' an argument, it uses that file instead of
- `configure.in' and writes the header file to the standard output
- instead of to `config.h.in'.  If you give `autoheader' an argument of
- `-', it reads the standard input instead of `configure.in' and writes
- the header file to the standard output.
- 
-    `autoheader' scans `configure.in' and figures out which C
- preprocessor symbols it might define.  It copies comments and `#define'
- and `#undef' statements from a file called `acconfig.h', which comes
- with and is installed with Autoconf.  It also uses a file called
- `acconfig.h' in the current directory, if present.  If you `AC_DEFINE'
- any additional symbols, you must create that file with entries for
- them.  For symbols defined by `AC_CHECK_HEADERS', `AC_CHECK_FUNCS',
- `AC_CHECK_SIZEOF', or `AC_CHECK_LIB', `autoheader' generates comments
- and `#undef' statements itself rather than copying them from a file,
- since the possible symbols are effectively limitless.
- 
-    The file that `autoheader' creates contains mainly `#define' and
- `#undef' statements and their accompanying comments.  If `./acconfig.h'
- contains the string `@TOP@', `autoheader' copies the lines before the
- line containing `@TOP@' into the top of the file that it generates.
- Similarly, if `./acconfig.h' contains the string `@BOTTOM@',
- `autoheader' copies the lines after that line to the end of the file it
- generates.  Either or both of those strings may be omitted.
- 
-    An alternate way to produce the same effect is to create the files
- `FILE.top' (typically `config.h.top') and/or `FILE.bot' in the current
- directory.  If they exist, `autoheader' copies them to the beginning
- and end, respectively, of its output.  Their use is discouraged because
- they have file names that contain two periods, and so can not be stored
- on MS-DOS; also, they are two more files to clutter up the directory.
- But if you use the `--localdir=DIR' option to use an `acconfig.h' in
- another directory, they give you a way to put custom boilerplate in each
- individual `config.h.in'.
- 
-    `autoheader' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--localdir=DIR'
- `-l DIR'
-      Look for the package files `aclocal.m4' and `acconfig.h' (but not
-      `FILE.top' and `FILE.bot') in directory DIR instead of in the
-      current directory.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the installed macro files and `acconfig.h' in directory
-      DIR.  You can also set the `AC_MACRODIR' environment variable to a
-      directory; this option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Subdirectories,  Next: Default Prefix,  Prev: Configuration Headers,  Up: Setup
- 
- Configuring Other Packages in Subdirectories
- ============================================
- 
-    In most situations, calling `AC_OUTPUT' is sufficient to produce
- `Makefile's in subdirectories.  However, `configure' scripts that
- control more than one independent package can use `AC_CONFIG_SUBDIRS'
- to run `configure' scripts for other packages in subdirectories.
- 
-  - Macro: AC_CONFIG_SUBDIRS (DIR ...)
-      Make `AC_OUTPUT' run `configure' in each subdirectory DIR in the
-      given whitespace-separated list.  If a given DIR is not found, no
-      error is reported, so a `configure' script can configure whichever
-      parts of a large source tree are present.  If a given DIR contains
-      `configure.in' but no `configure', the Cygnus `configure' script
-      found by `AC_CONFIG_AUXDIR' is used.
- 
-      The subdirectory `configure' scripts are given the same command
-      line options that were given to this `configure' script, with
-      minor changes if needed (e.g., to adjust a relative path for the
-      cache file or source directory).  This macro also sets the output
-      variable `subdirs' to the list of directories `DIR ...'.
-      `Makefile' rules can use this variable to determine which
-      subdirectories to recurse into.  This macro may be called multiple
-      times.
- 
- 
- File: autoconf.info,  Node: Default Prefix,  Next: Versions,  Prev: Subdirectories,  Up: Setup
- 
- Default Prefix
- ==============
- 
-    By default, `configure' sets the prefix for files it installs to
- `/usr/local'.  The user of `configure' can select a different prefix
- using the `--prefix' and `--exec-prefix' options.  There are two ways
- to change the default: when creating `configure', and when running it.
- 
-    Some software packages might want to install in a directory besides
- `/usr/local' by default.  To accomplish that, use the
- `AC_PREFIX_DEFAULT' macro.
- 
-  - Macro: AC_PREFIX_DEFAULT (PREFIX)
-      Set the default installation prefix to PREFIX instead of
-      `/usr/local'.
- 
-    It may be convenient for users to have `configure' guess the
- installation prefix from the location of a related program that they
- have already installed.  If you wish to do that, you can call
- `AC_PREFIX_PROGRAM'.
- 
-  - Macro: AC_PREFIX_PROGRAM (PROGRAM)
-      If the user did not specify an installation prefix (using the
-      `--prefix' option), guess a value for it by looking for PROGRAM in
-      `PATH', the way the shell does.  If PROGRAM is found, set the
-      prefix to the parent of the directory containing PROGRAM;
-      otherwise leave the prefix specified in `Makefile.in' unchanged.
-      For example, if PROGRAM is `gcc' and the `PATH' contains
-      `/usr/local/gnu/bin/gcc', set the prefix to `/usr/local/gnu'.
- 
- 
- File: autoconf.info,  Node: Versions,  Prev: Default Prefix,  Up: Setup
- 
- Version Numbers in `configure'
- ==============================
- 
-    The following macros manage version numbers for `configure' scripts.
- Using them is optional.
- 
-  - Macro: AC_PREREQ (VERSION)
-      Ensure that a recent enough version of Autoconf is being used.  If
-      the version of Autoconf being used to create `configure' is earlier
-      than VERSION, print an error message on the standard error output
-      and do not create `configure'.  For example:
- 
-           AC_PREREQ(1.8)
- 
-      This macro is useful if your `configure.in' relies on non-obvious
-      behavior that changed between Autoconf releases.  If it merely
-      needs recently added macros, then `AC_PREREQ' is less useful,
-      because the `autoconf' program already tells the user which macros
-      are not found.  The same thing happens if `configure.in' is
-      processed by a version of Autoconf older than when `AC_PREREQ' was
-      added.
- 
-  - Macro: AC_REVISION (REVISION-INFO)
-      Copy revision stamp REVISION-INFO into the `configure' script,
-      with any dollar signs or double-quotes removed.  This macro lets
-      you put a revision stamp from `configure.in' into `configure'
-      without RCS or CVS changing it when you check in `configure'.  That
-      way, you can determine easily which revision of `configure.in' a
-      particular `configure' corresponds to.
- 
-      It is a good idea to call this macro before `AC_INIT' so that the
-      revision number is near the top of both `configure.in' and
-      `configure'.  To support doing that, the `AC_REVISION' output
-      begins with `#! /bin/sh', like the normal start of a `configure'
-      script does.
- 
-      For example, this line in `configure.in':
- 
-           AC_REVISION($Revision: 1.1.1.2 $)dnl
- 
-      produces this in `configure':
- 
-           #! /bin/sh
-           # From configure.in Revision: 1.30
- 
- 
- File: autoconf.info,  Node: Existing Tests,  Next: Writing Tests,  Prev: Setup,  Up: Top
- 
- Existing Tests
- **************
- 
-    These macros test for particular system features that packages might
- need or want to use.  If you need to test for a kind of feature that
- none of these macros check for, you can probably do it by calling
- primitive test macros with appropriate arguments (*note Writing
- Tests::.).
- 
-    These tests print messages telling the user which feature they're
- checking for, and what they find.  They cache their results for future
- `configure' runs (*note Caching Results::.).
- 
-    Some of these macros set output variables.  *Note Makefile
- Substitutions::, for how to get their values.  The phrase "define NAME"
- is used below as a shorthand to mean "define C preprocessor symbol NAME
- to the value 1".  *Note Defining Symbols::, for how to get those symbol
- definitions into your program.
- 
- * Menu:
- 
- * Alternative Programs::        Selecting between alternative programs.
- * Libraries::                   Library archives that might be missing.
- * Library Functions::           C library functions that might be missing.
- * Header Files::                Header files that might be missing.
- * Structures::                  Structures or members that might be missing.
- * Typedefs::                    `typedef's that might be missing.
- * C Compiler Characteristics::
- * Fortran 77 Compiler Characteristics::
- * System Services::             Operating system services.
- * UNIX Variants::               Special kludges for specific UNIX variants.
- 
- 
- File: autoconf.info,  Node: Alternative Programs,  Next: Libraries,  Prev: Existing Tests,  Up: Existing Tests
- 
- Alternative Programs
- ====================
- 
-    These macros check for the presence or behavior of particular
- programs.  They are used to choose between several alternative programs
- and to decide what to do once one has been chosen.  If there is no
- macro specifically defined to check for a program you need, and you
- don't need to check for any special properties of it, then you can use
- one of the general program check macros.
- 
- * Menu:
- 
- * Particular Programs::         Special handling to find certain programs.
- * Generic Programs::            How to find other programs.
- 
- 
- File: autoconf.info,  Node: Particular Programs,  Next: Generic Programs,  Prev: Alternative Programs,  Up: Alternative Programs
- 
- Particular Program Checks
- -------------------------
- 
-    These macros check for particular programs--whether they exist, and
- in some cases whether they support certain features.
- 
-  - Macro: AC_DECL_YYTEXT
-      Define `YYTEXT_POINTER' if `yytext' is a `char *' instead of a
-      `char []'.  Also set output variable `LEX_OUTPUT_ROOT' to the base
-      of the file name that the lexer generates; usually `lex.yy', but
-      sometimes something else.  These results vary according to whether
-      `lex' or `flex' is being used.
- 
-  - Macro: AC_PROG_AWK
-      Check for `mawk', `gawk', `nawk', and `awk', in that order, and
-      set output variable `AWK' to the first one that it finds.  It
-      tries `mawk' first because that is reported to be the fastest
-      implementation.
- 
-  - Macro: AC_PROG_CC
-      Determine a C compiler to use.  If `CC' is not already set in the
-      environment, check for `gcc', and use `cc' if that's not found.
-      Set output variable `CC' to the name of the compiler found.
- 
-      If using the GNU C compiler, set shell variable `GCC' to `yes',
-      empty otherwise.  If output variable `CFLAGS' was not already set,
-      set it to `-g -O2' for the GNU C compiler (`-O2' on systems where
-      GCC does not accept `-g'), or `-g' for other compilers.
- 
-      If the C compiler being used does not produce executables that can
-      run on the system where `configure' is being run, set the shell
-      variable `cross_compiling' to `yes', otherwise `no'.  In other
-      words, this tests whether the build system type is different from
-      the host system type (the target system type is irrelevant to this
-      test).  *Note Manual Configuration::, for more on support for
-      cross compiling.
- 
-  - Macro: AC_PROG_CC_C_O
-      If the C compiler does not accept the `-c' and `-o' options
-      simultaneously, define `NO_MINUS_C_MINUS_O'.
- 
-  - Macro: AC_PROG_CPP
-      Set output variable `CPP' to a command that runs the C
-      preprocessor.  If `$CC -E' doesn't work, it uses `/lib/cpp'.  It
-      is only portable to run `CPP' on files with a `.c' extension.
- 
-      If the current language is C (*note Language Choice::.), many of
-      the specific test macros use the value of `CPP' indirectly by
-      calling `AC_TRY_CPP', `AC_CHECK_HEADER', `AC_EGREP_HEADER', or
-      `AC_EGREP_CPP'.
- 
-  - Macro: AC_PROG_CXX
-      Determine a C++ compiler to use.  Check if the environment variable
-      `CXX' or `CCC' (in that order) is set; if so, set output variable
-      `CXX' to its value.  Otherwise search for a C++ compiler under
-      likely names (`c++', `g++', `gcc', `CC', `cxx', and `cc++').  If
-      none of those checks succeed, as a last resort set `CXX' to `gcc'.
- 
-      If using the GNU C++ compiler, set shell variable `GXX' to `yes',
-      empty otherwise.  If output variable `CXXFLAGS' was not already
-      set, set it to `-g -O2' for the GNU C++ compiler (`-O2' on systems
-      where G++ does not accept `-g'), or `-g' for other compilers.
- 
-      If the C++ compiler being used does not produce executables that
-      can run on the system where `configure' is being run, set the shell
-      variable `cross_compiling' to `yes', otherwise `no'.  In other
-      words, this tests whether the build system type is different from
-      the host system type (the target system type is irrelevant to this
-      test).  *Note Manual Configuration::, for more on support for
-      cross compiling.
- 
-  - Macro: AC_PROG_CXXCPP
-      Set output variable `CXXCPP' to a command that runs the C++
-      preprocessor.  If `$CXX -E' doesn't work, it uses `/lib/cpp'.  It
-      is only portable to run `CXXCPP' on files with a `.c', `.C', or
-      `.cc' extension.
- 
-      If the current language is C++ (*note Language Choice::.), many of
-      the specific test macros use the value of `CXXCPP' indirectly by
-      calling `AC_TRY_CPP', `AC_CHECK_HEADER', `AC_EGREP_HEADER', or
-      `AC_EGREP_CPP'.
- 
-  - Macro: AC_PROG_F77
-      Determine a Fortran 77 compiler to use.  If `F77' is not already
-      set in the environment, check for `g77', `f77' and `f2c', in that
-      order.  Set the output variable `F77' to the name of the compiler
-      found.
- 
-      If using `g77' (the GNU Fortran 77 compiler), then `AC_PROG_F77'
-      will set the shell variable `G77' to `yes', and empty otherwise.
-      If the output variable `FFLAGS' was not already set in the
-      environment, then set it to `-g -02' for `g77' (or `-O2' where
-      `g77' does not accept `-g').  Otherwise, set `FFLAGS' to `-g' for
-      all other Fortran 77 compilers.
- 
-  - Macro: AC_PROG_F77_C_O
-      Test if the Fortran 77 compiler accepts the options `-c' and `-o'
-      simultaneously, and define `F77_NO_MINUS_C_MINUS_O' if it does not.
- 
-  - Macro: AC_PROG_GCC_TRADITIONAL
-      Add `-traditional' to output variable `CC' if using the GNU C
-      compiler and `ioctl' does not work properly without
-      `-traditional'.  That usually happens when the fixed header files
-      have not been installed on an old system.  Since recent versions
-      of the GNU C compiler fix the header files automatically when
-      installed, this is becoming a less prevalent problem.
- 
-  - Macro: AC_PROG_INSTALL
-      Set output variable `INSTALL' to the path of a BSD compatible
-      `install' program, if one is found in the current `PATH'.
-      Otherwise, set `INSTALL' to `DIR/install-sh -c', checking the
-      directories specified to `AC_CONFIG_AUX_DIR' (or its default
-      directories) to determine DIR (*note Output::.).  Also set the
-      variables `INSTALL_PROGRAM' and `INSTALL_SCRIPT' to `${INSTALL}'
-      and `INSTALL_DATA' to `${INSTALL} -m 644'.
- 
-      This macro screens out various instances of `install' known to not
-      work.  It prefers to find a C program rather than a shell script,
-      for speed.  Instead of `install-sh', it can also use `install.sh',
-      but that name is obsolete because some `make' programs have a rule
-      that creates `install' from it if there is no `Makefile'.
- 
-      A copy of `install-sh' which you may use comes with Autoconf.  If
-      you use `AC_PROG_INSTALL', you must include either `install-sh' or
-      `install.sh' in your distribution, or `configure' will produce an
-      error message saying it can't find them--even if the system you're
-      on has a good `install' program.  This check is a safety measure
-      to prevent you from accidentally leaving that file out, which
-      would prevent your package from installing on systems that don't
-      have a BSD-compatible `install' program.
- 
-      If you need to use your own installation program because it has
-      features not found in standard `install' programs, there is no
-      reason to use `AC_PROG_INSTALL'; just put the pathname of your
-      program into your `Makefile.in' files.
- 
-  - Macro: AC_PROG_LEX
-      If `flex' is found, set output variable `LEX' to `flex' and
-      `LEXLIB' to `-lfl', if that library is in a standard place.
-      Otherwise set `LEX' to `lex' and `LEXLIB' to `-ll'.
- 
-  - Macro: AC_PROG_LN_S
-      If `ln -s' works on the current filesystem (the operating system
-      and filesystem support symbolic links), set output variable `LN_S'
-      to `ln -s', otherwise set it to `ln'.
- 
-      If the link is put in a directory other than the current
-      directory, its meaning depends on whether `ln' or `ln -s' is used.
-      To safely create links using `$(LN_S)', either find out which
-      form is used and adjust the arguments, or always invoke `ln' in
-      the directory where the link is to be created.
- 
-      In other words, it does not work to do
-           $(LN_S) foo /x/bar
- 
-      Instead, do
- 
-           (cd /x && $(LN_S) foo bar)
- 
-  - Macro: AC_PROG_RANLIB
-      Set output variable `RANLIB' to `ranlib' if `ranlib' is found,
-      otherwise to `:' (do nothing).
- 
-  - Macro: AC_PROG_YACC
-      If `bison' is found, set output variable `YACC' to `bison -y'.
-      Otherwise, if `byacc' is found, set `YACC' to `byacc'.  Otherwise
-      set `YACC' to `yacc'.
- 
- 
- File: autoconf.info,  Node: Generic Programs,  Prev: Particular Programs,  Up: Alternative Programs
- 
- Generic Program and File Checks
- -------------------------------
- 
-    These macros are used to find programs not covered by the particular
- test macros.  If you need to check the behavior of a program as well as
- find out whether it is present, you have to write your own test for it
- (*note Writing Tests::.).  By default, these macros use the environment
- variable `PATH'.  If you need to check for a program that might not be
- in the user's `PATH', you can pass a modified path to use instead, like
- this:
- 
-      AC_PATH_PROG(INETD, inetd, /usr/libexec/inetd,
-        $PATH:/usr/libexec:/usr/sbin:/usr/etc:etc)
- 
-  - Macro: AC_CHECK_FILE (FILE [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Check whether file FILE exists on the native system.  If it is
-      found, execute ACTION-IF-FOUND, otherwise do ACTION-IF-NOT-FOUND,
-      if given.
- 
-  - Macro: AC_CHECK_FILES (FILES[, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Executes `AC_CHECK_FILE' once for each file listed in FILES.
-      Additionally, defines `HAVEFILE' for each file found, set to 1.
- 
-  - Macro: AC_CHECK_PROG (VARIABLE, PROG-TO-CHECK-FOR, VALUE-IF-FOUND [,
-           VALUE-IF-NOT-FOUND [, PATH, [ REJECT ]]])
-      Check whether program PROG-TO-CHECK-FOR exists in `PATH'.  If it
-      is found, set VARIABLE to VALUE-IF-FOUND, otherwise to
-      VALUE-IF-NOT-FOUND, if given.  Always pass over REJECT (an
-      absolute file name) even if it is the first found in the search
-      path; in that case, set VARIABLE using the absolute file name of
-      the PROG-TO-CHECK-FOR found that is not REJECT.  If VARIABLE was
-      already set, do nothing.  Calls `AC_SUBST' for VARIABLE.
- 
-  - Macro: AC_CHECK_PROGS (VARIABLE, PROGS-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND [, PATH]])
-      Check for each program in the whitespace-separated list
-      PROGS-TO-CHECK-FOR exists in `PATH'.  If it is found, set VARIABLE
-      to the name of that program.  Otherwise, continue checking the
-      next program in the list.  If none of the programs in the list are
-      found, set VARIABLE to VALUE-IF-NOT-FOUND; if VALUE-IF-NOT-FOUND
-      is not specified, the value of VARIABLE is not changed.  Calls
-      `AC_SUBST' for VARIABLE.
- 
-  - Macro: AC_CHECK_TOOL (VARIABLE, PROG-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND [, PATH]])
-      Like `AC_CHECK_PROG', but first looks for PROG-TO-CHECK-FOR with a
-      prefix of the host type as determined by `AC_CANONICAL_HOST',
-      followed by a dash (*note Canonicalizing::.).  For example, if the
-      user runs `configure --host=i386-gnu', then this call:
-           AC_CHECK_TOOL(RANLIB, ranlib, :)
- 
-      sets `RANLIB' to `i386-gnu-ranlib' if that program exists in
-      `PATH', or to `ranlib' if that program exists in `PATH', or to `:'
-      if neither program exists.
- 
-  - Macro: AC_PATH_PROG (VARIABLE, PROG-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND [, PATH]])
-      Like `AC_CHECK_PROG', but set VARIABLE to the entire path of
-      PROG-TO-CHECK-FOR if found.
- 
-  - Macro: AC_PATH_PROGS (VARIABLE, PROGS-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND [, PATH]])
-      Like `AC_CHECK_PROGS', but if any of PROGS-TO-CHECK-FOR are found,
-      set VARIABLE to the entire path of the program found.
- 
- 
- File: autoconf.info,  Node: Libraries,  Next: Library Functions,  Prev: Alternative Programs,  Up: Existing Tests
- 
- Library Files
- =============
- 
-    The following macros check for the presence of certain C, C++ or
- Fortran 77 library archive files.
- 
-  - Macro: AC_CHECK_LIB (LIBRARY, FUNCTION [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-      Depending on the current language(*note Language Choice::.), try to
-      ensure that the C, C++ or Fortran 77 function FUNCTION is
-      available by checking whether a test program can be linked with the
-      library LIBRARY to get the function.  LIBRARY is the base name of
-      the library; e.g., to check for `-lmp', use `mp' as the LIBRARY
-      argument.
- 
-      ACTION-IF-FOUND is a list of shell commands to run if the link
-      with the library succeeds; ACTION-IF-NOT-FOUND is a list of shell
-      commands to run if the link fails.  If ACTION-IF-FOUND is not
-      specified, the default action will add `-lLIBRARY' to `LIBS' and
-      define `HAVE_LIBLIBRARY' (in all capitals).
- 
-      If linking with LIBRARY results in unresolved symbols, which would
-      be resolved by linking with additional libraries, give those
-      libraries as the OTHER-LIBRARIES argument, separated by spaces:
-      `-lXt -lX11'.  Otherwise this macro will fail to detect that
-      LIBRARY is present, because linking the test program will always
-      fail with unresolved symbols.
- 
-  - Macro: AC_HAVE_LIBRARY (LIBRARY, [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-      This macro is equivalent to calling `AC_CHECK_LIB' with a FUNCTION
-      argument of `main'.  In addition, LIBRARY can be written as any of
-      `foo', `-lfoo', or `libfoo.a'.  In all of those cases, the
-      compiler is passed `-lfoo'.  However, LIBRARY can not be a shell
-      variable; it must be a literal name.  This macro is considered
-      obsolete.
- 
-  - Macro: AC_SEARCH_LIBS (FUNCTION, SEARCH-LIBS [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-      Search for a library defining FUNCTION, if it's not already
-      available.  This equates to calling `AC_TRY_LINK_FUNC' first with
-      no libraries, then for each library listed in SEARCH-LIBS.
- 
-      If the function is found, run ACTION-IF-FOUND, otherwise run
-      ACTION-IF-NOT-FOUND.
- 
-      If linking with LIBRARY results in unresolved symbols, which would
-      be resolved by linking with additional libraries, give those
-      libraries as the OTHER-LIBRARIES argument, separated by spaces:
-      `-lXt -lX11'.  Otherwise this macro will fail to detect that
-      FUNCTION is present, because linking the test program will always
-      fail with unresolved symbols.
- 
-  - Macro: AC_SEARCH_LIBS (FUNCTION, SEARCH-LIBS[, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      This macro is equivalent to calling `AC_TRY_LINK_FUNC' once for
-      each library listed in SEARCH-LIBS.  Add `-lLIBRARY' to `LIBS' for
-      the first library found to contain FUNCTION, and execute
-      ACTION-IF-FOUND.  Otherwise execute ACTION-IF-NOT-FOUND.
- 
- 
- File: autoconf.info,  Node: Library Functions,  Next: Header Files,  Prev: Libraries,  Up: Existing Tests
- 
- Library Functions
- =================
- 
-    The following macros check for particular C library functions.  If
- there is no macro specifically defined to check for a function you need,
- and you don't need to check for any special properties of it, then you
- can use one of the general function check macros.
- 
- * Menu:
- 
- * Particular Functions::        Special handling to find certain functions.
- * Generic Functions::           How to find other functions.
- 
- 
- File: autoconf.info,  Node: Particular Functions,  Next: Generic Functions,  Prev: Library Functions,  Up: Library Functions
- 
- Particular Function Checks
- --------------------------
- 
-    These macros check for particular C functions--whether they exist,
- and in some cases how they respond when given certain arguments.
- 
-  - Macro: AC_FUNC_ALLOCA
-      Check how to get `alloca'.  Tries to get a builtin version by
-      checking for `alloca.h' or the predefined C preprocessor macros
-      `__GNUC__' and `_AIX'.  If this macro finds `alloca.h', it defines
-      `HAVE_ALLOCA_H'.
- 
-      If those attempts fail, it looks for the function in the standard C
-      library.  If any of those methods succeed, it defines
-      `HAVE_ALLOCA'.  Otherwise, it sets the output variable `ALLOCA' to
-      `alloca.o' and defines `C_ALLOCA' (so programs can periodically
-      call `alloca(0)' to garbage collect).  This variable is separate
-      from `LIBOBJS' so multiple programs can share the value of
-      `ALLOCA' without needing to create an actual library, in case only
-      some of them use the code in `LIBOBJS'.
- 
-      This macro does not try to get `alloca' from the System V R3
-      `libPW' or the System V R4 `libucb' because those libraries
-      contain some incompatible functions that cause trouble.  Some
-      versions do not even contain `alloca' or contain a buggy version.
-      If you still want to use their `alloca', use `ar' to extract
-      `alloca.o' from them instead of compiling `alloca.c'.
- 
-      Source files that use `alloca' should start with a piece of code
-      like the following, to declare it properly.  In some versions of
-      AIX, the declaration of `alloca' must precede everything else
-      except for comments and preprocessor directives.  The `#pragma'
-      directive is indented so that pre-ANSI C compilers will ignore it,
-      rather than choke on it.
- 
-           /* AIX requires this to be the first thing in the file.  */
-           #ifndef __GNUC__
-           # if HAVE_ALLOCA_H
-           #  include <alloca.h>
-           # else
-           #  ifdef _AIX
-            #pragma alloca
-           #  else
-           #   ifndef alloca /* predefined by HP cc +Olibcalls */
-           char *alloca ();
-           #   endif
-           #  endif
-           # endif
-           #endif
- 
-  - Macro: AC_FUNC_CLOSEDIR_VOID
-      If the `closedir' function does not return a meaningful value,
-      define `CLOSEDIR_VOID'.  Otherwise, callers ought to check its
-      return value for an error indicator.
- 
-  - Macro: AC_FUNC_FNMATCH
-      If the `fnmatch' function is available and works (unlike the one on
-      SunOS 5.4), define `HAVE_FNMATCH'.
- 
-  - Macro: AC_FUNC_GETLOADAVG
-      Check how to get the system load averages.  If the system has the
-      `getloadavg' function, this macro defines `HAVE_GETLOADAVG', and
-      adds to `LIBS' any libraries needed to get that function.
- 
-      Otherwise, it adds `getloadavg.o' to the output variable
-      `LIBOBJS', and possibly defines several other C preprocessor
-      macros and output variables:
- 
-        1. It defines `SVR4', `DGUX', `UMAX', or `UMAX4_3' if on those
-           systems.
- 
-        2. If it finds `nlist.h', it defines `NLIST_STRUCT'.
- 
-        3. If `struct nlist' has an `n_un' member, it defines
-           `NLIST_NAME_UNION'.
- 
-        4. If compiling `getloadavg.c' defines `LDAV_PRIVILEGED',
-           programs need to be installed specially on this system for
-           `getloadavg' to work, and this macro defines
-           `GETLOADAVG_PRIVILEGED'.
- 
-        5. This macro sets the output variable `NEED_SETGID'.  The value
-           is `true' if special installation is required, `false' if not.
-           If `NEED_SETGID' is `true', this macro sets `KMEM_GROUP' to
-           the name of the group that should own the installed program.
- 
-  - Macro: AC_FUNC_GETMNTENT
-      Check for `getmntent' in the `sun', `seq', and `gen' libraries,
-      for Irix 4, PTX, and Unixware, respectively.  Then, if `getmntent'
-      is available, define `HAVE_GETMNTENT'.
- 
-  - Macro: AC_FUNC_GETPGRP
-      If `getpgrp' takes no argument (the POSIX.1 version), define
-      `GETPGRP_VOID'.  Otherwise, it is the BSD version, which takes a
-      process ID as an argument.  This macro does not check whether
-      `getpgrp' exists at all; if you need to work in that situation,
-      first call `AC_CHECK_FUNC' for `getpgrp'.
- 
-  - Macro: AC_FUNC_MEMCMP
-      If the `memcmp' function is not available, or does not work on
-      8-bit data (like the one on SunOS 4.1.3), add `memcmp.o' to output
-      variable `LIBOBJS'.
- 
-  - Macro: AC_FUNC_MMAP
-      If the `mmap' function exists and works correctly, define
-      `HAVE_MMAP'.  Only checks private fixed mapping of already-mapped
-      memory.
- 
-  - Macro: AC_FUNC_SELECT_ARGTYPES
-      Determines the correct type to be passed to each of the `select'
-      function's arguments, and defines those types in
-      `SELECT_TYPE_ARG1', `SELECT_TYPE_ARG234', and `SELECT_TYPE_ARG5'
-      respectively.  `SELECT_TYPE_ARG1' defaults to `int',
-      `SELECT_TYPE_ARG234' defaults to `int *', and `SELECT_TYPE_ARG5'
-      defaults to `struct timeval *'.
- 
-  - Macro: AC_FUNC_SETPGRP
-      If `setpgrp' takes no argument (the POSIX.1 version), define
-      `SETPGRP_VOID'.  Otherwise, it is the BSD version, which takes two
-      process ID as arguments.  This macro does not check whether
-      `setpgrp' exists at all; if you need to work in that situation,
-      first call `AC_CHECK_FUNC' for `setpgrp'.
- 
-  - Macro: AC_FUNC_SETVBUF_REVERSED
-      If `setvbuf' takes the buffering type as its second argument and
-      the buffer pointer as the third, instead of the other way around,
-      define `SETVBUF_REVERSED'.  This is the case on System V before
-      release 3.
- 
-  - Macro: AC_FUNC_STRCOLL
-      If the `strcoll' function exists and works correctly, define
-      `HAVE_STRCOLL'.  This does a bit more than
-      `AC_CHECK_FUNCS(strcoll)', because some systems have incorrect
-      definitions of `strcoll', which should not be used.
- 
-  - Macro: AC_FUNC_STRFTIME
-      Check for `strftime' in the `intl' library, for SCO UNIX.  Then,
-      if `strftime' is available, define `HAVE_STRFTIME'.
- 
-  - Macro: AC_FUNC_UTIME_NULL
-      If `utime(FILE, NULL)' sets FILE's timestamp to the present,
-      define `HAVE_UTIME_NULL'.
- 
-  - Macro: AC_FUNC_VFORK
-      If `vfork.h' is found, define `HAVE_VFORK_H'.  If a working
-      `vfork' is not found, define `vfork' to be `fork'.  This macro
-      checks for several known errors in implementations of `vfork' and
-      considers the system to not have a working `vfork' if it detects
-      any of them.  It is not considered to be an implementation error
-      if a child's invocation of `signal' modifies the parent's signal
-      handler, since child processes rarely change their signal handlers.
- 
-  - Macro: AC_FUNC_VPRINTF
-      If `vprintf' is found, define `HAVE_VPRINTF'.  Otherwise, if
-      `_doprnt' is found, define `HAVE_DOPRNT'.  (If `vprintf' is
-      available, you may assume that `vfprintf' and `vsprintf' are also
-      available.)
- 
-  - Macro: AC_FUNC_WAIT3
-      If `wait3' is found and fills in the contents of its third argument
-      (a `struct rusage *'), which HP-UX does not do, define
-      `HAVE_WAIT3'.
- 
- 
- File: autoconf.info,  Node: Generic Functions,  Prev: Particular Functions,  Up: Library Functions
- 
- Generic Function Checks
- -----------------------
- 
-    These macros are used to find functions not covered by the particular
- test macros.  If the functions might be in libraries other than the
- default C library, first call `AC_CHECK_LIB' for those libraries.  If
- you need to check the behavior of a function as well as find out
- whether it is present, you have to write your own test for it (*note
- Writing Tests::.).
- 
-  - Macro: AC_CHECK_FUNC (FUNCTION, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      If C function FUNCTION is available, run shell commands
-      ACTION-IF-FOUND, otherwise ACTION-IF-NOT-FOUND.  If you just want
-      to define a symbol if the function is available, consider using
-      `AC_CHECK_FUNCS' instead.  This macro checks for functions with C
-      linkage even when `AC_LANG_CPLUSPLUS' has been called, since C++ is
-      more standardized than C is.  (*note Language Choice::., for more
-      information about selecting the language for checks.)
- 
-  - Macro: AC_CHECK_FUNCS (FUNCTION... [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      For each given FUNCTION in the whitespace-separated argument list
-      that is available, define `HAVE_FUNCTION' (in all capitals).  If
-      ACTION-IF-FOUND is given, it is additional shell code to execute
-      when one of the functions is found.  You can give it a value of
-      `break' to break out of the loop on the first match.  If
-      ACTION-IF-NOT-FOUND is given, it is executed when one of the
-      functions is not found.
- 
-  - Macro: AC_REPLACE_FUNCS (FUNCTION...)
-      Like calling `AC_CHECK_FUNCS' using an ACTION-IF-NOT-FOUND that
-      adds `FUNCTION.o' to the value of the output variable `LIBOBJS'.
-      You can declare a function for which your replacement version is
-      used by enclosing the prototype in `#ifndef HAVE_FUNCTION'.  If
-      the system has the function, it probably declares it in a header
-      file you should be including, so you shouldn't redeclare it, lest
-      your declaration conflict.
- 
- 
- File: autoconf.info,  Node: Header Files,  Next: Structures,  Prev: Library Functions,  Up: Existing Tests
- 
- Header Files
- ============
- 
-    The following macros check for the presence of certain C header
- files.  If there is no macro specifically defined to check for a header
- file you need, and you don't need to check for any special properties of
- it, then you can use one of the general header file check macros.
- 
- * Menu:
- 
- * Particular Headers::          Special handling to find certain headers.
- * Generic Headers::             How to find other headers.
- 
- 
- File: autoconf.info,  Node: Particular Headers,  Next: Generic Headers,  Prev: Header Files,  Up: Header Files
- 
- Particular Header Checks
- ------------------------
- 
-    These macros check for particular system header files--whether they
- exist, and in some cases whether they declare certain symbols.
- 
-  - Macro: AC_DECL_SYS_SIGLIST
-      Define `SYS_SIGLIST_DECLARED' if the variable `sys_siglist' is
-      declared in a system header file, either `signal.h' or `unistd.h'.
- 
-  - Macro: AC_DIR_HEADER
-      Like calling `AC_HEADER_DIRENT' and `AC_FUNC_CLOSEDIR_VOID', but
-      defines a different set of C preprocessor macros to indicate which
-      header file is found.  This macro and the names it defines are
-      considered obsolete.  The names it defines are:
- 
-     `dirent.h'
-           `DIRENT'
- 
-     `sys/ndir.h'
-           `SYSNDIR'
- 
-     `sys/dir.h'
-           `SYSDIR'
- 
-     `ndir.h'
-           `NDIR'
- 
-      In addition, if the `closedir' function does not return a
-      meaningful value, define `VOID_CLOSEDIR'.
- 
-  - Macro: AC_HEADER_DIRENT
-      Check for the following header files, and for the first one that is
-      found and defines `DIR', define the listed C preprocessor macro:
- 
-     `dirent.h'
-           `HAVE_DIRENT_H'
- 
-     `sys/ndir.h'
-           `HAVE_SYS_NDIR_H'
- 
-     `sys/dir.h'
-           `HAVE_SYS_DIR_H'
- 
-     `ndir.h'
-           `HAVE_NDIR_H'
- 
-      The directory library declarations in the source code should look
-      something like the following:
- 
-           #if HAVE_DIRENT_H
-           # include <dirent.h>
-           # define NAMLEN(dirent) strlen((dirent)->d_name)
-           #else
-           # define dirent direct
-           # define NAMLEN(dirent) (dirent)->d_namlen
-           # if HAVE_SYS_NDIR_H
-           #  include <sys/ndir.h>
-           # endif
-           # if HAVE_SYS_DIR_H
-           #  include <sys/dir.h>
-           # endif
-           # if HAVE_NDIR_H
-           #  include <ndir.h>
-           # endif
-           #endif
- 
-      Using the above declarations, the program would declare variables
-      to be type `struct dirent', not `struct direct', and would access
-      the length of a directory entry name by passing a pointer to a
-      `struct dirent' to the `NAMLEN' macro.
- 
-      This macro also checks for the SCO Xenix `dir' and `x' libraries.
- 
-  - Macro: AC_HEADER_MAJOR
-      If `sys/types.h' does not define `major', `minor', and `makedev',
-      but `sys/mkdev.h' does, define `MAJOR_IN_MKDEV'; otherwise, if
-      `sys/sysmacros.h' does, define `MAJOR_IN_SYSMACROS'.
- 
-  - Macro: AC_HEADER_STDC
-      Define `STDC_HEADERS' if the system has ANSI C header files.
-      Specifically, this macro checks for `stdlib.h', `stdarg.h',
-      `string.h', and `float.h'; if the system has those, it probably
-      has the rest of the ANSI C header files.  This macro also checks
-      whether `string.h' declares `memchr' (and thus presumably the
-      other `mem' functions), whether `stdlib.h' declare `free' (and
-      thus presumably `malloc' and other related functions), and whether
-      the `ctype.h' macros work on characters with the high bit set, as
-      ANSI C requires.
- 
-      Use `STDC_HEADERS' instead of `__STDC__' to determine whether the
-      system has ANSI-compliant header files (and probably C library
-      functions) because many systems that have GCC do not have ANSI C
-      header files.
- 
-      On systems without ANSI C headers, there is so much variation that
-      it is probably easier to declare the functions you use than to
-      figure out exactly what the system header files declare.  Some
-      systems contain a mix of functions ANSI and BSD; some are mostly
-      ANSI but lack `memmove'; some define the BSD functions as macros in
-      `string.h' or `strings.h'; some have only the BSD functions but
-      `string.h'; some declare the memory functions in `memory.h', some
-      in `string.h'; etc.  It is probably sufficient to check for one
-      string function and one memory function; if the library has the
-      ANSI versions of those then it probably has most of the others.
-      If you put the following in `configure.in':
- 
-           AC_HEADER_STDC
-           AC_CHECK_FUNCS(strchr memcpy)
- 
-      then, in your code, you can put declarations like this:
- 
-           #if STDC_HEADERS
-           # include <string.h>
-           #else
-           # ifndef HAVE_STRCHR
-           #  define strchr index
-           #  define strrchr rindex
-           # endif
-           char *strchr (), *strrchr ();
-           # ifndef HAVE_MEMCPY
-           #  define memcpy(d, s, n) bcopy ((s), (d), (n))
-           #  define memmove(d, s, n) bcopy ((s), (d), (n))
-           # endif
-           #endif
- 
-      If you use a function like `memchr', `memset', `strtok', or
-      `strspn', which have no BSD equivalent, then macros won't suffice;
-      you must provide an implementation of each function.  An easy way
-      to incorporate your implementations only when needed (since the
-      ones in system C libraries may be hand optimized) is to, taking
-      `memchr' for example, put it in `memchr.c' and use
-      `AC_REPLACE_FUNCS(memchr)'.
- 
-  - Macro: AC_HEADER_SYS_WAIT
-      If `sys/wait.h' exists and is compatible with POSIX.1, define
-      `HAVE_SYS_WAIT_H'.  Incompatibility can occur if `sys/wait.h' does
-      not exist, or if it uses the old BSD `union wait' instead of `int'
-      to store a status value.  If `sys/wait.h' is not POSIX.1
-      compatible, then instead of including it, define the POSIX.1
-      macros with their usual interpretations.  Here is an example:
- 
-           #include <sys/types.h>
-           #if HAVE_SYS_WAIT_H
-           # include <sys/wait.h>
-           #endif
-           #ifndef WEXITSTATUS
-           # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-           #endif
-           #ifndef WIFEXITED
-           # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-           #endif
- 
-  - Macro: AC_MEMORY_H
-      Define `NEED_MEMORY_H' if `memcpy', `memcmp', etc. are not
-      declared in `string.h' and `memory.h' exists.  This macro is
-      obsolete; instead, use `AC_CHECK_HEADERS(memory.h)'.  See the
-      example for `AC_HEADER_STDC'.
- 
-  - Macro: AC_UNISTD_H
-      Define `HAVE_UNISTD_H' if the system has `unistd.h'.  This macro
-      is obsolete; instead, use `AC_CHECK_HEADERS(unistd.h)'.
- 
-      The way to check if the system supports POSIX.1 is:
- 
-           #if HAVE_UNISTD_H
-           # include <sys/types.h>
-           # include <unistd.h>
-           #endif
-           
-           #ifdef _POSIX_VERSION
-           /* Code for POSIX.1 systems.  */
-           #endif
- 
-      `_POSIX_VERSION' is defined when `unistd.h' is included on POSIX.1
-      systems.  If there is no `unistd.h', it is definitely not a
-      POSIX.1 system.  However, some non-POSIX.1 systems do have
-      `unistd.h'.
- 
-  - Macro: AC_USG
-      Define `USG' if the system does not have `strings.h', `rindex',
-      `bzero', etc.  This implies that it has `string.h', `strrchr',
-      `memset', etc.
- 
-      The symbol `USG' is obsolete.  Instead of this macro, see the
-      example for `AC_HEADER_STDC'.
- 
- 
- File: autoconf.info,  Node: Generic Headers,  Prev: Particular Headers,  Up: Header Files
- 
- Generic Header Checks
- ---------------------
- 
-    These macros are used to find system header files not covered by the
- particular test macros.  If you need to check the contents of a header
- as well as find out whether it is present, you have to write your own
- test for it (*note Writing Tests::.).
- 
-  - Macro: AC_CHECK_HEADER (HEADER-FILE, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      If the system header file HEADER-FILE exists, execute shell
-      commands ACTION-IF-FOUND, otherwise execute ACTION-IF-NOT-FOUND.
-      If you just want to define a symbol if the header file is
-      available, consider using `AC_CHECK_HEADERS' instead.
- 
-  - Macro: AC_CHECK_HEADERS (HEADER-FILE... [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      For each given system header file HEADER-FILE in the
-      whitespace-separated argument list that exists, define
-      `HAVE_HEADER-FILE' (in all capitals).  If ACTION-IF-FOUND is
-      given, it is additional shell code to execute when one of the
-      header files is found.  You can give it a value of `break' to
-      break out of the loop on the first match.  If ACTION-IF-NOT-FOUND
-      is given, it is executed when one of the header files is not found.
- 
- 
- File: autoconf.info,  Node: Structures,  Next: Typedefs,  Prev: Header Files,  Up: Existing Tests
- 
- Structures
- ==========
- 
-    The following macros check for certain structures or structure
- members.  To check structures not listed here, use `AC_EGREP_CPP'
- (*note Examining Declarations::.) or `AC_TRY_COMPILE' (*note Examining
- Syntax::.).
- 
-  - Macro: AC_HEADER_STAT
-      If the macros `S_ISDIR', `S_ISREG' et al. defined in `sys/stat.h'
-      do not work properly (returning false positives), define
-      `STAT_MACROS_BROKEN'.  This is the case on Tektronix UTekV, Amdahl
-      UTS and Motorola System V/88.
- 
-  - Macro: AC_HEADER_TIME
-      If a program may include both `time.h' and `sys/time.h', define
-      `TIME_WITH_SYS_TIME'.  On some older systems, `sys/time.h'
-      includes `time.h', but `time.h' is not protected against multiple
-      inclusion, so programs should not explicitly include both files.
-      This macro is useful in programs that use, for example, `struct
-      timeval' or `struct timezone' as well as `struct tm'.  It is best
-      used in conjunction with `HAVE_SYS_TIME_H', which can be checked
-      for using `AC_CHECK_HEADERS(sys/time.h)'.
- 
-           #if TIME_WITH_SYS_TIME
-           # include <sys/time.h>
-           # include <time.h>
-           #else
-           # if HAVE_SYS_TIME_H
-           #  include <sys/time.h>
-           # else
-           #  include <time.h>
-           # endif
-           #endif
- 
-  - Macro: AC_STRUCT_ST_BLKSIZE
-      If `struct stat' contains an `st_blksize' member, define
-      `HAVE_ST_BLKSIZE'.
- 
-  - Macro: AC_STRUCT_ST_BLOCKS
-      If `struct stat' contains an `st_blocks' member, define
-      `HAVE_ST_BLOCKS'.  Otherwise, add `fileblocks.o' to the output
-      variable `LIBOBJS'.
- 
-  - Macro: AC_STRUCT_ST_RDEV
-      If `struct stat' contains an `st_rdev' member, define
-      `HAVE_ST_RDEV'.
- 
-  - Macro: AC_STRUCT_TM
-      If `time.h' does not define `struct tm', define `TM_IN_SYS_TIME',
-      which means that including `sys/time.h' had better define `struct
-      tm'.
- 
-  - Macro: AC_STRUCT_TIMEZONE
-      Figure out how to get the current timezone.  If `struct tm' has a
-      `tm_zone' member, define `HAVE_TM_ZONE'.  Otherwise, if the
-      external array `tzname' is found, define `HAVE_TZNAME'.
- 
- 
- File: autoconf.info,  Node: Typedefs,  Next: C Compiler Characteristics,  Prev: Structures,  Up: Existing Tests
- 
- Typedefs
- ========
- 
-    The following macros check for C typedefs.  If there is no macro
- specifically defined to check for a typedef you need, and you don't need
- to check for any special properties of it, then you can use a general
- typedef check macro.
- 
- * Menu:
- 
- * Particular Typedefs::         Special handling to find certain types.
- * Generic Typedefs::            How to find other types.
- 
- 
- File: autoconf.info,  Node: Particular Typedefs,  Next: Generic Typedefs,  Prev: Typedefs,  Up: Typedefs
- 
- Particular Typedef Checks
- -------------------------
- 
-    These macros check for particular C typedefs in `sys/types.h' and
- `stdlib.h' (if it exists).
- 
-  - Macro: AC_TYPE_GETGROUPS
-      Define `GETGROUPS_T' to be whichever of `gid_t' or `int' is the
-      base type of the array argument to `getgroups'.
- 
-  - Macro: AC_TYPE_MODE_T
-      If `mode_t' is not defined, define `mode_t' to be `int'.
- 
-  - Macro: AC_TYPE_OFF_T
-      If `off_t' is not defined, define `off_t' to be `long'.
- 
-  - Macro: AC_TYPE_PID_T
-      If `pid_t' is not defined, define `pid_t' to be `int'.
- 
-  - Macro: AC_TYPE_SIGNAL
-      If `signal.h' declares `signal' as returning a pointer to a
-      function returning `void', define `RETSIGTYPE' to be `void';
-      otherwise, define it to be `int'.
- 
-      Define signal handlers as returning type `RETSIGTYPE':
- 
-           RETSIGTYPE
-           hup_handler ()
-           {
-           ...
-           }
- 
-  - Macro: AC_TYPE_SIZE_T
-      If `size_t' is not defined, define `size_t' to be `unsigned'.
- 
-  - Macro: AC_TYPE_UID_T
-      If `uid_t' is not defined, define `uid_t' to be `int' and `gid_t'
-      to be `int'.
- 
- 
- File: autoconf.info,  Node: Generic Typedefs,  Prev: Particular Typedefs,  Up: Typedefs
- 
- Generic Typedef Checks
- ----------------------
- 
-    This macro is used to check for typedefs not covered by the
- particular test macros.
- 
-  - Macro: AC_CHECK_TYPE (TYPE, DEFAULT)
-      If the type TYPE is not defined in `sys/types.h', or `stdlib.h' or
-      `stddef.h' if they exist, define it to be the C (or C++) builtin
-      type DEFAULT; e.g., `short' or `unsigned'.
- 
- 
- File: autoconf.info,  Node: C Compiler Characteristics,  Next: Fortran 77 Compiler Characteristics,  Prev: Typedefs,  Up: Existing Tests
- 
- C Compiler Characteristics
- ==========================
- 
-    The following macros check for C compiler or machine architecture
- features.  To check for characteristics not listed here, use
- `AC_TRY_COMPILE' (*note Examining Syntax::.) or `AC_TRY_RUN' (*note Run
- Time::.)
- 
-  - Macro: AC_C_BIGENDIAN
-      If words are stored with the most significant byte first (like
-      Motorola and SPARC, but not Intel and VAX, CPUs), define
-      `WORDS_BIGENDIAN'.
- 
-  - Macro: AC_C_CONST
-      If the C compiler does not fully support the keyword `const',
-      define `const' to be empty.  Some C compilers that do not define
-      `__STDC__' do support `const'; some compilers that define
-      `__STDC__' do not completely support `const'.  Programs can simply
-      use `const' as if every C compiler supported it; for those that
-      don't, the `Makefile' or configuration header file will define it
-      as empty.
- 
-  - Macro: AC_C_INLINE
-      If the C compiler supports the keyword `inline', do nothing.
-      Otherwise define `inline' to `__inline__' or `__inline' if it
-      accepts one of those, otherwise define `inline' to be empty.
- 
-  - Macro: AC_C_CHAR_UNSIGNED
-      If the C type `char' is unsigned, define `__CHAR_UNSIGNED__',
-      unless the C compiler predefines it.
- 
-  - Macro: AC_C_LONG_DOUBLE
-      If the C compiler supports the `long double' type, define
-      `HAVE_LONG_DOUBLE'.  Some C compilers that do not define
-      `__STDC__' do support the `long double' type; some compilers that
-      define `__STDC__' do not support `long double'.
- 
-  - Macro: AC_C_STRINGIZE
-      If the C preprocessor supports the stringizing operator, define
-      `HAVE_STRINGIZE'.  The stringizing operator is `#' and is found in
-      macros such as this:
- 
-           #define x(y) #y
- 
-  - Macro: AC_CHECK_SIZEOF (TYPE [, CROSS-SIZE])
-      Define `SIZEOF_UCTYPE' to be the size in bytes of the C (or C++)
-      builtin type TYPE, e.g. `int' or `char *'.  If `type' is unknown
-      to the compiler, it gets a size of 0.  UCTYPE is TYPE, with
-      lowercase converted to uppercase, spaces changed to underscores,
-      and asterisks changed to `P'.  If cross-compiling, the value
-      CROSS-SIZE is used if given, otherwise `configure' exits with an
-      error message.
- 
-      For example, the call
-           AC_CHECK_SIZEOF(int *)
- 
-      defines `SIZEOF_INT_P' to be 8 on DEC Alpha AXP systems.
- 
-  - Macro: AC_INT_16_BITS
-      If the C type `int' is 16 bits wide, define `INT_16_BITS'.  This
-      macro is obsolete; it is more general to use
-      `AC_CHECK_SIZEOF(int)' instead.
- 
-  - Macro: AC_LONG_64_BITS
-      If the C type `long int' is 64 bits wide, define `LONG_64_BITS'.
-      This macro is obsolete; it is more general to use
-      `AC_CHECK_SIZEOF(long)' instead.
- 
- 
- File: autoconf.info,  Node: Fortran 77 Compiler Characteristics,  Next: System Services,  Prev: C Compiler Characteristics,  Up: Existing Tests
- 
- Fortran 77 Compiler Characteristics
- ===================================
- 
-    The following macros check for Fortran 77 compiler characteristics.
- To check for characteristics not listed here, use `AC_TRY_COMPILE'
- (*note Examining Syntax::.) or `AC_TRY_RUN' (*note Run Time::.), making
- sure to first set the current lanuage to Fortran 77 `AC_LANG_FORTRAN77'
- (*note Language Choice::.).
- 
-  - Macro: AC_F77_LIBRARY_LDFLAGS
-      Determine the linker flags (e.g. `-L' and `-l') for the "Fortran
-      77 intrinsic and run-time libraries" that are required to
-      successfully link a Fortran 77 program or shared library.  The
-      output variable `FLIBS' is set to these flags.
- 
-      This macro is intended to be used in those situations when it is
-      necessary to mix, e.g. C++ and Fortran 77 source code into a single
-      program or shared library (*note Mixing Fortran 77 With C and C++:
-      (automake)Mixing Fortran 77 With C and C++.).
- 
-      For example, if object files from a C++ and Fortran 77 compiler
-      must be linked together, then the C++ compiler/linker must be used
-      for linking (since special C++-ish things need to happen at link
-      time like calling global constructors, instantiating templates,
-      enabling exception support, etc.).
- 
-      However, the Fortran 77 intrinsic and run-time libraries must be
-      linked in as well, but the C++ compiler/linker doesn't know by
-      default how to add these Fortran 77 libraries.  Hence, the macro
-      `AC_F77_LIBRARY_LDFLAGS' was created to determine these Fortran 77
-      libraries.
- 
- 
- File: autoconf.info,  Node: System Services,  Next: UNIX Variants,  Prev: Fortran 77 Compiler Characteristics,  Up: Existing Tests
- 
- System Services
- ===============
- 
-    The following macros check for operating system services or
- capabilities.
- 
-  - Macro: AC_CYGWIN
-      Checks for the Cygwin environment.  If present, sets shell variable
-      `CYGWIN' to `yes'.  If not present, sets `CYGWIN' to the empty
-      string.
- 
-  - Macro: AC_EXEEXT
-      Defines substitute variable `EXEEXT' based on the output of the
-      compiler, after .c, .o, and .obj files have been excluded.
-      Typically set to empty string if Unix, `.exe' or `.EXE' if Win32.
- 
-  - Macro: AC_OBJEXT
-      Defines substitute variable `OBJEXT' based on the output of the
-      compiler, after .c files have been excluded.  Typically set to
-      `.o' if Unix, `.obj' if Win32.
- 
-  - Macro: AC_MINGW32
-      Checks for the MingW32 compiler environment.  If present, sets
-      shell variable `MINGW32' to `yes'.  If not present, sets `MINGW32'
-      to the empty string.
- 
-  - Macro: AC_PATH_X
-      Try to locate the X Window System include files and libraries.  If
-      the user gave the command line options `--x-includes=DIR' and
-      `--x-libraries=DIR', use those directories.  If either or both
-      were not given, get the missing values by running `xmkmf' on a
-      trivial `Imakefile' and examining the `Makefile' that it produces.
-      If that fails (such as if `xmkmf' is not present), look for them
-      in several directories where they often reside.  If either method
-      is successful, set the shell variables `x_includes' and
-      `x_libraries' to their locations, unless they are in directories
-      the compiler searches by default.
- 
-      If both methods fail, or the user gave the command line option
-      `--without-x', set the shell variable `no_x' to `yes'; otherwise
-      set it to the empty string.
- 
-  - Macro: AC_PATH_XTRA
-      An enhanced version of `AC_PATH_X'.  It adds the C compiler flags
-      that X needs to output variable `X_CFLAGS', and the X linker flags
-      to `X_LIBS'.  If X is not available, adds `-DX_DISPLAY_MISSING' to
-      `X_CFLAGS'.
- 
-      This macro also checks for special libraries that some systems
-      need in order to compile X programs.  It adds any that the system
-      needs to output variable `X_EXTRA_LIBS'.  And it checks for
-      special X11R6 libraries that need to be linked with before
-      `-lX11', and adds any found to the output variable `X_PRE_LIBS'.
- 
- 
-  - Macro: AC_SYS_INTERPRETER
-      Check whether the system supports starting scripts with a line of
-      the form `#! /bin/csh' to select the interpreter to use for the
-      script.  After running this macro, shell code in `configure.in'
-      can check the shell variable `interpval'; it will be set to `yes'
-      if the system supports `#!', `no' if not.
- 
-  - Macro: AC_SYS_LONG_FILE_NAMES
-      If the system supports file names longer than 14 characters, define
-      `HAVE_LONG_FILE_NAMES'.
- 
-  - Macro: AC_SYS_RESTARTABLE_SYSCALLS
-      If the system automatically restarts a system call that is
-      interrupted by a signal, define `HAVE_RESTARTABLE_SYSCALLS'.
- 
- 
- File: autoconf.info,  Node: UNIX Variants,  Prev: System Services,  Up: Existing Tests
- 
- UNIX Variants
- =============
- 
-    The following macros check for certain operating systems that need
- special treatment for some programs, due to exceptional oddities in
- their header files or libraries.  These macros are warts; they will be
- replaced by a more systematic approach, based on the functions they make
- available or the environments they provide.
- 
-  - Macro: AC_AIX
-      If on AIX, define `_ALL_SOURCE'.  Allows the use of some BSD
-      functions.  Should be called before any macros that run the C
-      compiler.
- 
-  - Macro: AC_DYNIX_SEQ
-      If on Dynix/PTX (Sequent UNIX), add `-lseq' to output variable
-      `LIBS'.  This macro is obsolete; instead, use `AC_FUNC_GETMNTENT'.
- 
-  - Macro: AC_IRIX_SUN
-      If on IRIX (Silicon Graphics UNIX), add `-lsun' to output variable
-      `LIBS'.  This macro is obsolete.  If you were using it to get
-      `getmntent', use `AC_FUNC_GETMNTENT' instead.  If you used it for
-      the NIS versions of the password and group functions, use
-      `AC_CHECK_LIB(sun, getpwnam)'.
- 
-  - Macro: AC_ISC_POSIX
-      If on a POSIXized ISC UNIX, define `_POSIX_SOURCE' and add
-      `-posix' (for the GNU C compiler) or `-Xp' (for other C compilers)
-      to output variable `CC'.  This allows the use of POSIX facilities.
-      Must be called after `AC_PROG_CC' and before any other macros
-      that run the C compiler.
- 
-  - Macro: AC_MINIX
-      If on Minix, define `_MINIX' and `_POSIX_SOURCE' and define
-      `_POSIX_1_SOURCE' to be 2.  This allows the use of POSIX
-      facilities.  Should be called before any macros that run the C
-      compiler.
- 
-  - Macro: AC_SCO_INTL
-      If on SCO UNIX, add `-lintl' to output variable `LIBS'.  This
-      macro is obsolete; instead, use `AC_FUNC_STRFTIME'.
- 
-  - Macro: AC_XENIX_DIR
-      If on Xenix, add `-lx' to output variable `LIBS'.  Also, if
-      `dirent.h' is being used, add `-ldir' to `LIBS'.  This macro is
-      obsolete; use `AC_HEADER_DIRENT' instead.
- 
- 
- File: autoconf.info,  Node: Writing Tests,  Next: Results,  Prev: Existing Tests,  Up: Top
- 
- Writing Tests
- *************
- 
-    If the existing feature tests don't do something you need, you have
- to write new ones.  These macros are the building blocks.  They provide
- ways for other macros to check whether various kinds of features are
- available and report the results.
- 
-    This chapter contains some suggestions and some of the reasons why
- the existing tests are written the way they are.  You can also learn a
- lot about how to write Autoconf tests by looking at the existing ones.
- If something goes wrong in one or more of the Autoconf tests, this
- information can help you understand the assumptions behind them, which
- might help you figure out how to best solve the problem.
- 
-    These macros check the output of the C compiler system.  They do not
- cache the results of their tests for future use (*note Caching
- Results::.), because they don't know enough about the information they
- are checking for to generate a cache variable name.  They also do not
- print any messages, for the same reason.  The checks for particular
- kinds of C features call these macros and do cache their results and
- print messages about what they're checking for.
- 
-    When you write a feature test that could be applicable to more than
- one software package, the best thing to do is encapsulate it in a new
- macro.  *Note Writing Macros::, for how to do that.
- 
- * Menu:
- 
- * Examining Declarations::      Detecting header files and declarations.
- * Examining Syntax::            Detecting language syntax features.
- * Examining Libraries::         Detecting functions and global variables.
- * Run Time::                    Testing for run-time features.
- * Portable Shell::              Shell script portability pitfalls.
- * Testing Values and Files::    Checking strings and files.
- * Multiple Cases::              Tests for several possible values.
- * Language Choice::             Selecting which language to use for testing.
- 
- 
- File: autoconf.info,  Node: Examining Declarations,  Next: Examining Syntax,  Prev: Writing Tests,  Up: Writing Tests
- 
- Examining Declarations
- ======================
- 
-    The macro `AC_TRY_CPP' is used to check whether particular header
- files exist.  You can check for one at a time, or more than one if you
- need several header files to all exist for some purpose.
- 
-  - Macro: AC_TRY_CPP (INCLUDES, [ACTION-IF-TRUE [, ACTION-IF-FALSE]])
-      INCLUDES is C or C++ `#include' statements and declarations, on
-      which shell variable, backquote, and backslash substitutions are
-      performed.  (Actually, it can be any C program, but other
-      statements are probably not useful.)  If the preprocessor produces
-      no error messages while processing it, run shell commands
-      ACTION-IF-TRUE.  Otherwise run shell commands ACTION-IF-FALSE.
- 
-      This macro uses `CPPFLAGS', but not `CFLAGS', because `-g', `-O',
-      etc. are not valid options to many C preprocessors.
- 
-    Here is how to find out whether a header file contains a particular
- declaration, such as a typedef, a structure, a structure member, or a
- function.  Use `AC_EGREP_HEADER' instead of running `grep' directly on
- the header file; on some systems the symbol might be defined in another
- header file that the file you are checking `#include's.
- 
-  - Macro: AC_EGREP_HEADER (PATTERN, HEADER-FILE, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      If the output of running the preprocessor on the system header file
-      HEADER-FILE matches the `egrep' regular expression PATTERN,
-      execute shell commands ACTION-IF-FOUND, otherwise execute
-      ACTION-IF-NOT-FOUND.
- 
-    To check for C preprocessor symbols, either defined by header files
- or predefined by the C preprocessor, use `AC_EGREP_CPP'.  Here is an
- example of the latter:
- 
-      AC_EGREP_CPP(yes,
-      [#ifdef _AIX
-        yes
-      #endif
-      ], is_aix=yes, is_aix=no)
- 
-  - Macro: AC_EGREP_CPP (PATTERN, PROGRAM, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      PROGRAM is the text of a C or C++ program, on which shell
-      variable, backquote, and backslash substitutions are performed.
-      If the output of running the preprocessor on PROGRAM matches the
-      `egrep' regular expression PATTERN, execute shell commands
-      ACTION-IF-FOUND, otherwise execute ACTION-IF-NOT-FOUND.
- 
-      This macro calls `AC_PROG_CPP' or `AC_PROG_CXXCPP' (depending on
-      which language is current, *note Language Choice::.), if it hasn't
-      been called already.
- 
- 
- File: autoconf.info,  Node: Examining Syntax,  Next: Examining Libraries,  Prev: Examining Declarations,  Up: Writing Tests
- 
- Examining Syntax
- ================
- 
-    To check for a syntax feature of the C, C++ or Fortran 77 compiler,
- such as whether it recognizes a certain keyword, use `AC_TRY_COMPILE' to
- try to compile a small program that uses that feature.  You can also use
- it to check for structures and structure members that are not present on
- all systems.
- 
-  - Macro: AC_TRY_COMPILE (INCLUDES, FUNCTION-BODY, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Create a C, C++ or Fortran 77 test program (depending on which
-      language is current, *note Language Choice::.), to see whether a
-      function whose body consists of FUNCTION-BODY can be compiled.
- 
-      For C and C++, INCLUDES is any `#include' statements needed by the
-      code in FUNCTION-BODY (INCLUDES will be ignored if the currently
-      selected language is Fortran 77).  This macro also uses `CFLAGS'
-      or `CXXFLAGS' if either C or C++ is the currently selected
-      language, as well as `CPPFLAGS', when compiling.  If Fortran 77 is
-      the currently selected language then `FFLAGS' will be used when
-      compiling.
- 
-      If the file compiles successfully, run shell commands
-      ACTION-IF-FOUND, otherwise run ACTION-IF-NOT-FOUND.
- 
-      This macro does not try to link; use `AC_TRY_LINK' if you need to
-      do that (*note Examining Libraries::.).
- 
- 
- File: autoconf.info,  Node: Examining Libraries,  Next: Run Time,  Prev: Examining Syntax,  Up: Writing Tests
- 
- Examining Libraries
- ===================
- 
-    To check for a library, a function, or a global variable, Autoconf
- `configure' scripts try to compile and link a small program that uses
- it.  This is unlike Metaconfig, which by default uses `nm' or `ar' on
- the C library to try to figure out which functions are available.
- Trying to link with the function is usually a more reliable approach
- because it avoids dealing with the variations in the options and output
- formats of `nm' and `ar' and in the location of the standard libraries.
- It also allows configuring for cross-compilation or checking a
- function's runtime behavior if needed.  On the other hand, it can be
- slower than scanning the libraries once.
- 
-    A few systems have linkers that do not return a failure exit status
- when there are unresolved functions in the link.  This bug makes the
- configuration scripts produced by Autoconf unusable on those systems.
- However, some of them can be given options that make the exit status
- correct.  This is a problem that Autoconf does not currently handle
- automatically.  If users encounter this problem, they might be able to
- solve it by setting `LDFLAGS' in the environment to pass whatever
- options the linker needs (for example, `-Wl,-dn' on MIPS RISC/OS).
- 
-    `AC_TRY_LINK' is used to compile test programs to test for functions
- and global variables.  It is also used by `AC_CHECK_LIB' to check for
- libraries (*note Libraries::.), by adding the library being checked for
- to `LIBS' temporarily and trying to link a small program.
- 
-  - Macro: AC_TRY_LINK (INCLUDES, FUNCTION-BODY, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Depending on the current language (*note Language Choice::.),
-      create a test program to see whether a function whose body
-      consists of FUNCTION-BODY can be compiled and linked.
- 
-      For C and C++, INCLUDES is any `#include' statements needed by the
-      code in FUNCTION-BODY (INCLUDES will be ignored if the currently
-      selected language is Fortran 77).  This macro also uses `CFLAGS'
-      or `CXXFLAGS' if either C or C++ is the currently selected
-      language, as well as `CPPFLAGS', when compiling.  If Fortran 77 is
-      the currently selected language then `FFLAGS' will be used when
-      compiling.  However, both `LDFLAGS' and `LIBS' will be used during
-      linking in all cases.
- 
-      If the file compiles and links successfully, run shell commands
-      ACTION-IF-FOUND, otherwise run ACTION-IF-NOT-FOUND.
- 
-  - Macro: AC_TRY_LINK_FUNC (FUNCTION, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Depending on the current language (*note Language Choice::.),
-      create a test program to see whether a program whose body consists
-      of a prototype of and a call to FUNCTION can be compiled and
-      linked.
- 
-      If the file compiles and links successfully, run shell commands
-      ACTION-IF-FOUND, otherwise run ACTION-IF-NOT-FOUND.
- 
-  - Macro: AC_TRY_LINK_FUNC (FUNCTION, [ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      Attempt to compile and link a small program that links with
-      FUNCTION.  If the file compiles and links successfully, run shell
-      commands ACTION-IF-FOUND, otherwise run ACTION-IF-NOT-FOUND.
- 
-  - Macro: AC_COMPILE_CHECK (ECHO-TEXT, INCLUDES, FUNCTION-BODY,
-           ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
-      This is an obsolete version of `AC_TRY_LINK', with the addition
-      that it prints `checking for ECHO-TEXT' to the standard output
-      first, if ECHO-TEXT is non-empty.  Use `AC_MSG_CHECKING' and
-      `AC_MSG_RESULT' instead to print messages (*note Printing
-      Messages::.).
- 
- 
- File: autoconf.info,  Node: Run Time,  Next: Portable Shell,  Prev: Examining Libraries,  Up: Writing Tests
- 
- Checking Run Time Behavior
- ==========================
- 
-    Sometimes you need to find out how a system performs at run time,
- such as whether a given function has a certain capability or bug.  If
- you can, make such checks when your program runs instead of when it is
- configured.  You can check for things like the machine's endianness when
- your program initializes itself.
- 
-    If you really need to test for a run-time behavior while configuring,
- you can write a test program to determine the result, and compile and
- run it using `AC_TRY_RUN'.  Avoid running test programs if possible,
- because using them prevents people from configuring your package for
- cross-compiling.
- 
- * Menu:
- 
- * Test Programs::               Running test programs.
- * Guidelines::                  General rules for writing test programs.
- * Test Functions::              Avoiding pitfalls in test programs.
- 
- 
- File: autoconf.info,  Node: Test Programs,  Next: Guidelines,  Prev: Run Time,  Up: Run Time
- 
- Running Test Programs
- ---------------------
- 
-    Use the following macro if you need to test run-time behavior of the
- system while configuring.
- 
-  - Macro: AC_TRY_RUN (PROGRAM, [ACTION-IF-TRUE [, ACTION-IF-FALSE [,
-           ACTION-IF-CROSS-COMPILING]]])
-      PROGRAM is the text of a C program, on which shell variable and
-      backquote substitutions are performed.  If it compiles and links
-      successfully and returns an exit status of 0 when executed, run
-      shell commands ACTION-IF-TRUE.  Otherwise run shell commands
-      ACTION-IF-FALSE; the exit status of the program is available in
-      the shell variable `$?'.  This macro uses `CFLAGS' or `CXXFLAGS',
-      `CPPFLAGS', `LDFLAGS', and `LIBS' when compiling.
- 
-      If the C compiler being used does not produce executables that run
-      on the system where `configure' is being run, then the test
-      program is not run.  If the optional shell commands
-      ACTION-IF-CROSS-COMPILING are given, they are run instead.
-      Otherwise, `configure' prints an error message and exits.
- 
-    Try to provide a pessimistic default value to use when
- cross-compiling makes run-time tests impossible.  You do this by
- passing the optional last argument to `AC_TRY_RUN'.  `autoconf' prints
- a warning message when creating `configure' each time it encounters a
- call to `AC_TRY_RUN' with no ACTION-IF-CROSS-COMPILING argument given.
- You may ignore the warning, though users will not be able to configure
- your package for cross-compiling.  A few of the macros distributed with
- Autoconf produce this warning message.
- 
-    To configure for cross-compiling you can also choose a value for
- those parameters based on the canonical system name (*note Manual
- Configuration::.).  Alternatively, set up a test results cache file with
- the correct values for the target system (*note Caching Results::.).
- 
-    To provide a default for calls of `AC_TRY_RUN' that are embedded in
- other macros, including a few of the ones that come with Autoconf, you
- can call `AC_PROG_CC' before running them.  Then, if the shell variable
- `cross_compiling' is set to `yes', use an alternate method to get the
- results instead of calling the macros.
- 
-  - Macro: AC_C_CROSS
-      This macro is obsolete; it does nothing.
- 
- 
- File: autoconf.info,  Node: Guidelines,  Next: Test Functions,  Prev: Test Programs,  Up: Run Time
- 
- Guidelines for Test Programs
- ----------------------------
- 
-    Test programs should not write anything to the standard output.  They
- should return 0 if the test succeeds, nonzero otherwise, so that success
- can be distinguished easily from a core dump or other failure;
- segmentation violations and other failures produce a nonzero exit
- status.  Test programs should `exit', not `return', from `main',
- because on some systems (old Suns, at least) the argument to `return'
- in `main' is ignored.
- 
-    Test programs can use `#if' or `#ifdef' to check the values of
- preprocessor macros defined by tests that have already run.  For
- example, if you call `AC_HEADER_STDC', then later on in `configure.in'
- you can have a test program that includes an ANSI C header file
- conditionally:
- 
-      #if STDC_HEADERS
-      # include <stdlib.h>
-      #endif
- 
-    If a test program needs to use or create a data file, give it a name
- that starts with `conftest', such as `conftestdata'.  The `configure'
- script cleans up by running `rm -rf conftest*' after running test
- programs and if the script is interrupted.
- 
- 
- File: autoconf.info,  Node: Test Functions,  Prev: Guidelines,  Up: Run Time
- 
- Test Functions
- --------------
- 
-    Function declarations in test programs should have a prototype
- conditionalized for C++.  In practice, though, test programs rarely need
- functions that take arguments.
- 
-      #ifdef __cplusplus
-      foo(int i)
-      #else
-      foo(i) int i;
-      #endif
- 
-    Functions that test programs declare should also be conditionalized
- for C++, which requires `extern "C"' prototypes.  Make sure to not
- include any header files containing clashing prototypes.
- 
-      #ifdef __cplusplus
-      extern "C" void *malloc(size_t);
-      #else
-      char *malloc();
-      #endif
- 
-    If a test program calls a function with invalid parameters (just to
- see whether it exists), organize the program to ensure that it never
- invokes that function.  You can do this by calling it in another
- function that is never invoked.  You can't do it by putting it after a
- call to `exit', because GCC version 2 knows that `exit' never returns
- and optimizes out any code that follows it in the same block.
- 
-    If you include any header files, make sure to call the functions
- relevant to them with the correct number of arguments, even if they are
- just 0, to avoid compilation errors due to prototypes.  GCC version 2
- has internal prototypes for several functions that it automatically
- inlines; for example, `memcpy'.  To avoid errors when checking for
- them, either pass them the correct number of arguments or redeclare them
- with a different return type (such as `char').
- 
- 
- File: autoconf.info,  Node: Portable Shell,  Next: Testing Values and Files,  Prev: Run Time,  Up: Writing Tests
- 
- Portable Shell Programming
- ==========================
- 
-    When writing your own checks, there are some shell script programming
- techniques you should avoid in order to make your code portable.  The
- Bourne shell and upward-compatible shells like Bash and the Korn shell
- have evolved over the years, but to prevent trouble, do not take
- advantage of features that were added after UNIX version 7, circa 1977.
- You should not use shell functions, aliases, negated character classes,
- or other features that are not found in all Bourne-compatible shells;
- restrict yourself to the lowest common denominator.  Even `unset' is
- not supported by all shells!  Also, include a space after the
- exclamation point in interpreter specifications, like this:
-      #! /usr/bin/perl
-    If you omit the space before the path, then 4.2BSD based systems
- (such as Sequent DYNIX) will ignore the line, because they interpret
- `#! /' as a 4-byte magic number.
- 
-    The set of external programs you should run in a `configure' script
- is fairly small.  *Note Utilities in Makefiles: (standards)Utilities in
- Makefiles, for the list.  This restriction allows users to start out
- with a fairly small set of programs and build the rest, avoiding too
- many interdependencies between packages.
- 
-    Some of these external utilities have a portable subset of features,
- as well; for example, don't rely on `ln' having a `-f' option or `cat'
- having any options.  `sed' scripts should not contain comments or use
- branch labels longer than 8 characters.  Don't use `grep -s' to
- suppress output, because `grep -s' on System V does not suppress
- output, only error messages.  Instead, redirect the standard output and
- standard error (in case the file doesn't exist) of `grep' to
- `/dev/null'.  Check the exit status of `grep' to determine whether it
- found a match.
- 
- 
- File: autoconf.info,  Node: Testing Values and Files,  Next: Multiple Cases,  Prev: Portable Shell,  Up: Writing Tests
- 
- Testing Values and Files
- ========================
- 
-    `configure' scripts need to test properties of many files and
- strings.  Here are some portability problems to watch out for when doing
- those tests.
- 
-    The `test' program is the way to perform many file and string tests.
- It is often invoked by the alternate name `[', but using that name in
- Autoconf code is asking for trouble since it is an `m4' quote character.
- 
-    If you need to make multiple checks using `test', combine them with
- the shell operators `&&' and `||' instead of using the `test' operators
- `-a' and `-o'.  On System V, the precedence of `-a' and `-o' is wrong
- relative to the unary operators; consequently, POSIX does not specify
- them, so using them is nonportable.  If you combine `&&' and `||' in
- the same statement, keep in mind that they have equal precedence.
- 
-    To enable `configure' scripts to support cross-compilation, they
- shouldn't do anything that tests features of the host system instead of
- the target system.  But occasionally you may find it necessary to check
- whether some arbitrary file exists.  To do so, use `test -f' or `test
- -r'.  Do not use `test -x', because 4.3BSD does not have it.
- 
-    Another nonportable shell programming construction is
-      VAR=${VAR:-VALUE}
- 
- The intent is to set VAR to VALUE only if it is not already set, but if
- VAR has any value, even the empty string, to leave it alone.  Old BSD
- shells, including the Ultrix `sh', don't accept the colon, and complain
- and die.  A portable equivalent is
-      : ${VAR=VALUE}
- 
- 
- File: autoconf.info,  Node: Multiple Cases,  Next: Language Choice,  Prev: Testing Values and Files,  Up: Writing Tests
- 
- Multiple Cases
- ==============
- 
-    Some operations are accomplished in several possible ways, depending
- on the UNIX variant.  Checking for them essentially requires a "case
- statement".  Autoconf does not directly provide one; however, it is
- easy to simulate by using a shell variable to keep track of whether a
- way to perform the operation has been found yet.
- 
-    Here is an example that uses the shell variable `fstype' to keep
- track of whether the remaining cases need to be checked.
- 
-      AC_MSG_CHECKING(how to get filesystem type)
-      fstype=no
-      # The order of these tests is important.
-      AC_TRY_CPP([#include <sys/statvfs.h>
-      #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
-      if test $fstype = no; then
-      AC_TRY_CPP([#include <sys/statfs.h>
-      #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
-      fi
-      if test $fstype = no; then
-      AC_TRY_CPP([#include <sys/statfs.h>
-      #include <sys/vmount.h>], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
-      fi
-      # (more cases omitted here)
-      AC_MSG_RESULT($fstype)
- 
- 
- File: autoconf.info,  Node: Language Choice,  Prev: Multiple Cases,  Up: Writing Tests
- 
- Language Choice
- ===============
- 
-    Packages that use both C and C++ need to test features of both
- compilers.  Autoconf-generated `configure' scripts check for C features
- by default.  The following macros determine which language's compiler
- is used in tests that follow in `configure.in'.
- 
-  - Macro: AC_LANG_C
-      Do compilation tests using `CC' and `CPP' and use extension `.c'
-      for test programs.  Set the shell variable `cross_compiling' to
-      the value computed by `AC_PROG_CC' if it has been run, empty
-      otherwise.
- 
-  - Macro: AC_LANG_CPLUSPLUS
-      Do compilation tests using `CXX' and `CXXCPP' and use extension
-      `.C' for test programs.  Set the shell variable `cross_compiling'
-      to the value computed by `AC_PROG_CXX' if it has been run, empty
-      otherwise.
- 
-  - Macro: AC_LANG_FORTRAN77
-      Do compilation tests using `F77' and use extension `.f' for test
-      programs.  Set the shell variable `cross_compiling' to the value
-      computed by `AC_PROG_F77' if it has been run, empty otherwise.
- 
-  - Macro: AC_LANG_SAVE
-      Remember the current language (as set by `AC_LANG_C',
-      `AC_LANG_CPLUSPLUS' or `AC_LANG_FORTRAN77') on a stack.  Does not
-      change which language is current.  Use this macro and
-      `AC_LANG_RESTORE' in macros that need to temporarily switch to a
-      particular language.
- 
-  - Macro: AC_LANG_RESTORE
-      Select the language that is saved on the top of the stack, as set
-      by `AC_LANG_SAVE', and remove it from the stack.  This macro is
-      equivalent to either `AC_LANG_C', `AC_LANG_CPLUSPLUS' or
-      `AC_LANG_FORTRAN77', whichever had been run most recently when
-      `AC_LANG_SAVE' was last called.
- 
-      Do not call this macro more times than `AC_LANG_SAVE'.
- 
-  - Macro: AC_REQUIRE_CPP
-      Ensure that whichever preprocessor would currently be used for
-      tests has been found.  Calls `AC_REQUIRE' (*note Prerequisite
-      Macros::.) with an argument of either `AC_PROG_CPP' or
-      `AC_PROG_CXXCPP', depending on which language is current.
- 
- 
- File: autoconf.info,  Node: Results,  Next: Writing Macros,  Prev: Writing Tests,  Up: Top
- 
- Results of Tests
- ****************
- 
-    Once `configure' has determined whether a feature exists, what can
- it do to record that information?  There are four sorts of things it can
- do: define a C preprocessor symbol, set a variable in the output files,
- save the result in a cache file for future `configure' runs, and print
- a message letting the user know the result of the test.
- 
- * Menu:
- 
- * Defining Symbols::            Defining C preprocessor symbols.
- * Setting Output Variables::    Replacing variables in output files.
- * Caching Results::             Speeding up subsequent `configure' runs.
- * Printing Messages::           Notifying users of progress or problems.
- 
- 
- File: autoconf.info,  Node: Defining Symbols,  Next: Setting Output Variables,  Prev: Results,  Up: Results
- 
- Defining C Preprocessor Symbols
- ===============================
- 
-    A common action to take in response to a feature test is to define a
- C preprocessor symbol indicating the results of the test.  That is done
- by calling `AC_DEFINE' or `AC_DEFINE_UNQUOTED'.
- 
-    By default, `AC_OUTPUT' places the symbols defined by these macros
- into the output variable `DEFS', which contains an option
- `-DSYMBOL=VALUE' for each symbol defined.  Unlike in Autoconf version
- 1, there is no variable `DEFS' defined while `configure' is running.
- To check whether Autoconf macros have already defined a certain C
- preprocessor symbol, test the value of the appropriate cache variable,
- as in this example:
- 
-      AC_CHECK_FUNC(vprintf, AC_DEFINE(HAVE_VPRINTF))
-      if test "$ac_cv_func_vprintf" != yes; then
-      AC_CHECK_FUNC(_doprnt, AC_DEFINE(HAVE_DOPRNT))
-      fi
- 
-    If `AC_CONFIG_HEADER' has been called, then instead of creating
- `DEFS', `AC_OUTPUT' creates a header file by substituting the correct
- values into `#define' statements in a template file.  *Note
- Configuration Headers::, for more information about this kind of output.
- 
-  - Macro: AC_DEFINE (VARIABLE [, VALUE [, DESCRIPTION]])
-      Define C preprocessor variable VARIABLE.  If VALUE is given, set
-      VARIABLE to that value (verbatim), otherwise set it to 1.  VALUE
-      should not contain literal newlines, and if you are not using
-      `AC_CONFIG_HEADER' it should not contain any `#' characters, as
-      `make' tends to eat them.  To use a shell variable (which you need
-      to do in order to define a value containing the `m4' quote
-      characters `[' or `]'), use `AC_DEFINE_UNQUOTED' instead.
-      DESCRIPTION is only useful if you are using `AC_CONFIG_HEADER'.
-      In this case, DESCRIPTION is put into the generated `config.h.in'
-      as the comment before the macro define; the macro need not be
-      mentioned in `acconfig.h'.  The following example defines the C
-      preprocessor variable `EQUATION' to be the string constant `"$a >
-      $b"':
- 
-           AC_DEFINE(EQUATION, "$a > $b")
- 
-  - Macro: AC_DEFINE_UNQUOTED (VARIABLE [, VALUE [, DESCRIPTION]])
-      Like `AC_DEFINE', but three shell expansions are
-      performed--once--on VARIABLE and VALUE: variable expansion (`$'),
-      command substitution (``'), and backslash escaping (`\').  Single
-      and double quote characters in the value have no special meaning.
-      Use this macro instead of `AC_DEFINE' when VARIABLE or VALUE is a
-      shell variable.  Examples:
- 
-           AC_DEFINE_UNQUOTED(config_machfile, "${machfile}")
-           AC_DEFINE_UNQUOTED(GETGROUPS_T, $ac_cv_type_getgroups)
-           AC_DEFINE_UNQUOTED(${ac_tr_hdr})
- 
-    Due to the syntactical bizarreness of the Bourne shell, do not use
- semicolons to separate `AC_DEFINE' or `AC_DEFINE_UNQUOTED' calls from
- other macro calls or shell code; that can cause syntax errors in the
- resulting `configure' script.  Use either spaces or newlines.  That is,
- do this:
- 
-      AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4) LIBS="$LIBS -lelf")
- 
- or this:
- 
-      AC_CHECK_HEADER(elf.h,
-        AC_DEFINE(SVR4)
-        LIBS="$LIBS -lelf")
- 
- instead of this:
- 
-      AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4); LIBS="$LIBS -lelf")
- 
- 
- File: autoconf.info,  Node: Setting Output Variables,  Next: Caching Results,  Prev: Defining Symbols,  Up: Results
- 
- Setting Output Variables
- ========================
- 
-    One way to record the results of tests is to set "output variables",
- which are shell variables whose values are substituted into files that
- `configure' outputs.  The two macros below create new output variables.
- *Note Preset Output Variables::, for a list of output variables that
- are always available.
- 
-  - Macro: AC_SUBST (VARIABLE)
-      Create an output variable from a shell variable.  Make `AC_OUTPUT'
-      substitute the variable VARIABLE into output files (typically one
-      or more `Makefile's).  This means that `AC_OUTPUT' will replace
-      instances of `@VARIABLE@' in input files with the value that the
-      shell variable VARIABLE has when `AC_OUTPUT' is called.  The value
-      of VARIABLE should not contain literal newlines.
- 
-  - Macro: AC_SUBST_FILE (VARIABLE)
-      Another way to create an output variable from a shell variable.
-      Make `AC_OUTPUT' insert (without substitutions) the contents of
-      the file named by shell variable VARIABLE into output files.  This
-      means that `AC_OUTPUT' will replace instances of `@VARIABLE@' in
-      output files (such as `Makefile.in') with the contents of the file
-      that the shell variable VARIABLE names when `AC_OUTPUT' is called.
-      Set the variable to `/dev/null' for cases that do not have a file
-      to insert.
- 
-      This macro is useful for inserting `Makefile' fragments containing
-      special dependencies or other `make' directives for particular host
-      or target types into `Makefile's.  For example, `configure.in'
-      could contain:
- 
-           AC_SUBST_FILE(host_frag)dnl
-           host_frag=$srcdir/conf/sun4.mh
- 
-      and then a `Makefile.in' could contain:
- 
-           @host_frag@
- 
- 
- File: autoconf.info,  Node: Caching Results,  Next: Printing Messages,  Prev: Setting Output Variables,  Up: Results
- 
- Caching Results
- ===============
- 
-    To avoid checking for the same features repeatedly in various
- `configure' scripts (or repeated runs of one script), `configure' saves
- the results of many of its checks in a "cache file".  If, when a
- `configure' script runs, it finds a cache file, it reads from it the
- results from previous runs and avoids rerunning those checks.  As a
- result, `configure' can run much faster than if it had to perform all
- of the checks every time.
- 
-  - Macro: AC_CACHE_VAL (CACHE-ID, COMMANDS-TO-SET-IT)
-      Ensure that the results of the check identified by CACHE-ID are
-      available.  If the results of the check were in the cache file
-      that was read, and `configure' was not given the `--quiet' or
-      `--silent' option, print a message saying that the result was
-      cached; otherwise, run the shell commands COMMANDS-TO-SET-IT.
-      Those commands should have no side effects except for setting the
-      variable CACHE-ID.  In particular, they should not call
-      `AC_DEFINE'; the code that follows the call to `AC_CACHE_VAL'
-      should do that, based on the cached value.  Also, they should not
-      print any messages, for example with `AC_MSG_CHECKING'; do that
-      before calling `AC_CACHE_VAL', so the messages are printed
-      regardless of whether the results of the check are retrieved from
-      the cache or determined by running the shell commands.  If the
-      shell commands are run to determine the value, the value will be
-      saved in the cache file just before `configure' creates its output
-      files.  *Note Cache Variable Names::, for how to choose the name
-      of the CACHE-ID variable.
- 
-  - Macro: AC_CACHE_CHECK (MESSAGE, CACHE-ID, COMMANDS)
-      A wrapper for `AC_CACHE_VAL' that takes care of printing the
-      messages.  This macro provides a convenient shorthand for the most
-      common way to use these macros.  It calls `AC_MSG_CHECKING' for
-      MESSAGE, then `AC_CACHE_VAL' with the CACHE-ID and COMMANDS
-      arguments, and `AC_MSG_RESULT' with CACHE-ID.
- 
-  - Macro: AC_CACHE_LOAD
-      Loads values from existing cache file, or creates a new cache file
-      if a cache file is not found.  Called automatically from `AC_INIT'.
- 
-  - Macro: AC_CACHE_SAVE
-      Flushes all cached values to the cache file.  Called automatically
-      from `AC_OUTPUT', but it can be quite useful to call
-      `AC_CACHE_SAVE' at key points in configure.in.  Doing so
-      checkpoints the cache in case of an early configure script abort.
- 
- * Menu:
- 
- * Cache Variable Names::        Shell variables used in caches.
- * Cache Files::                 Files `configure' uses for caching.
- 
- 
- File: autoconf.info,  Node: Cache Variable Names,  Next: Cache Files,  Prev: Caching Results,  Up: Caching Results
- 
- Cache Variable Names
- --------------------
- 
-    The names of cache variables should have the following format:
- 
-      PACKAGE-PREFIX_cv_VALUE-TYPE_SPECIFIC-VALUE[_ADDITIONAL-OPTIONS]
- 
- for example, `ac_cv_header_stat_broken' or
- `ac_cv_prog_gcc_traditional'.  The parts of the variable name are:
- 
- PACKAGE-PREFIX
-      An abbreviation for your package or organization; the same prefix
-      you begin local Autoconf macros with, except lowercase by
-      convention.  For cache values used by the distributed Autoconf
-      macros, this value is `ac'.
- 
- `_cv_'
-      Indicates that this shell variable is a cache value.
- 
- VALUE-TYPE
-      A convention for classifying cache values, to produce a rational
-      naming system.  The values used in Autoconf are listed in *Note
-      Macro Names::.
- 
- SPECIFIC-VALUE
-      Which member of the class of cache values this test applies to.
-      For example, which function (`alloca'), program (`gcc'), or output
-      variable (`INSTALL').
- 
- ADDITIONAL-OPTIONS
-      Any particular behavior of the specific member that this test
-      applies to.  For example, `broken' or `set'.  This part of the
-      name may be omitted if it does not apply.
- 
-    The values assigned to cache variables may not contain newlines.
- Usually, their values will be boolean (`yes' or `no') or the names of
- files or functions; so this is not an important restriction.
- 
- 
- File: autoconf.info,  Node: Cache Files,  Prev: Cache Variable Names,  Up: Caching Results
- 
- Cache Files
- -----------
- 
-    A cache file is a shell script that caches the results of configure
- tests run on one system so they can be shared between configure scripts
- and configure runs.  It is not useful on other systems.  If its contents
- are invalid for some reason, the user may delete or edit it.
- 
-    By default, configure uses `./config.cache' as the cache file,
- creating it if it does not exist already.  `configure' accepts the
- `--cache-file=FILE' option to use a different cache file; that is what
- `configure' does when it calls `configure' scripts in subdirectories,
- so they share the cache.  *Note Subdirectories::, for information on
- configuring subdirectories with the `AC_CONFIG_SUBDIRS' macro.
- 
-    Giving `--cache-file=/dev/null' disables caching, for debugging
- `configure'.  `config.status' only pays attention to the cache file if
- it is given the `--recheck' option, which makes it rerun `configure'.
- If you are anticipating a long debugging period, you can also disable
- cache loading and saving for a `configure' script by redefining the
- cache macros at the start of `configure.in':
- 
-      define([AC_CACHE_LOAD], )dnl
-      define([AC_CACHE_SAVE], )dnl
-      AC_INIT(whatever)
-       ... rest of configure.in ...
- 
-    It is wrong to try to distribute cache files for particular system
- types.  There is too much room for error in doing that, and too much
- administrative overhead in maintaining them.  For any features that
- can't be guessed automatically, use the standard method of the canonical
- system type and linking files (*note Manual Configuration::.).
- 
-    The cache file on a particular system will gradually accumulate
- whenever someone runs a `configure' script; it will be initially
- nonexistent.  Running `configure' merges the new cache results with the
- existing cache file.  The site initialization script can specify a
- site-wide cache file to use instead of the default, to make it work
- transparently, as long as the same C compiler is used every time (*note
- Site Defaults::.).
- 
-    If your configure script, or a macro called from configure.in,
- happens to abort the configure process, it may be useful to checkpoint
- the cache a few times at key points.  Doing so will reduce the amount
- of time it takes to re-run the configure script with (hopefully) the
- error that caused the previous abort corrected.
- 
-       ... AC_INIT, etc. ...
-      dnl checks for programs
-      AC_PROG_CC
-      AC_PROG_GCC_TRADITIONAL
-       ... more program checks ...
-      AC_CACHE_SAVE
-      
-      dnl checks for libraries
-      AC_CHECK_LIB(nsl, gethostbyname)
-      AC_CHECK_LIB(socket, connect)
-       ... more lib checks ...
-      AC_CACHE_SAVE
-      
-      dnl Might abort...
-      AM_PATH_GTK(1.0.2, , exit 1)
-      AM_PATH_GTKMM(0.9.5, , exit 1)
- 
- 
- File: autoconf.info,  Node: Printing Messages,  Prev: Caching Results,  Up: Results
- 
- Printing Messages
- =================
- 
-    `configure' scripts need to give users running them several kinds of
- information.  The following macros print messages in ways appropriate
- for each kind.  The arguments to all of them get enclosed in shell
- double quotes, so the shell performs variable and backquote substitution
- on them.  You can print a message containing a comma by quoting the
- message with the `m4' quote characters:
- 
-      AC_MSG_RESULT([never mind, I found the BASIC compiler])
- 
-    These macros are all wrappers around the `echo' shell command.
- `configure' scripts should rarely need to run `echo' directly to print
- messages for the user.  Using these macros makes it easy to change how
- and when each kind of message is printed; such changes need only be
- made to the macro definitions, and all of the callers change
- automatically.
- 
-  - Macro: AC_MSG_CHECKING (FEATURE-DESCRIPTION)
-      Notify the user that `configure' is checking for a particular
-      feature.  This macro prints a message that starts with `checking '
-      and ends with `...' and no newline.  It must be followed by a call
-      to `AC_MSG_RESULT' to print the result of the check and the
-      newline.  The FEATURE-DESCRIPTION should be something like
-      `whether the Fortran compiler accepts C++ comments' or `for c89'.
- 
-      This macro prints nothing if `configure' is run with the `--quiet'
-      or `--silent' option.
- 
-  - Macro: AC_MSG_RESULT (RESULT-DESCRIPTION)
-      Notify the user of the results of a check.  RESULT-DESCRIPTION is
-      almost always the value of the cache variable for the check,
-      typically `yes', `no', or a file name.  This macro should follow a
-      call to `AC_MSG_CHECKING', and the RESULT-DESCRIPTION should be
-      the completion of the message printed by the call to
-      `AC_MSG_CHECKING'.
- 
-      This macro prints nothing if `configure' is run with the `--quiet'
-      or `--silent' option.
- 
-  - Macro: AC_MSG_ERROR (ERROR-DESCRIPTION)
-      Notify the user of an error that prevents `configure' from
-      completing.  This macro prints an error message on the standard
-      error output and exits `configure' with a nonzero status.
-      ERROR-DESCRIPTION should be something like `invalid value $HOME
-      for \$HOME'.
- 
-  - Macro: AC_MSG_WARN (PROBLEM-DESCRIPTION)
-      Notify the `configure' user of a possible problem.  This macro
-      prints the message on the standard error output; `configure'
-      continues running afterward, so macros that call `AC_MSG_WARN'
-      should provide a default (back-up) behavior for the situations
-      they warn about.  PROBLEM-DESCRIPTION should be something like `ln
-      -s seems to make hard links'.
- 
-    The following two macros are an obsolete alternative to
- `AC_MSG_CHECKING' and `AC_MSG_RESULT'.
- 
-  - Macro: AC_CHECKING (FEATURE-DESCRIPTION)
-      This macro is similar to `AC_MSG_CHECKING', except that it prints a
-      newline after the FEATURE-DESCRIPTION.  It is useful mainly to
-      print a general description of the overall purpose of a group of
-      feature checks, e.g.,
- 
-           AC_CHECKING(if stack overflow is detectable)
- 
-  - Macro: AC_VERBOSE (RESULT-DESCRIPTION)
-      This macro is similar to `AC_MSG_RESULT', except that it is meant
-      to follow a call to `AC_CHECKING' instead of `AC_MSG_CHECKING'; it
-      starts the message it prints with a tab.  It is considered
-      obsolete.
- 
- 
- File: autoconf.info,  Node: Writing Macros,  Next: Manual Configuration,  Prev: Results,  Up: Top
- 
- Writing Macros
- **************
- 
-    When you write a feature test that could be applicable to more than
- one software package, the best thing to do is encapsulate it in a new
- macro.  Here are some instructions and guidelines for writing Autoconf
- macros.
- 
- * Menu:
- 
- * Macro Definitions::           Basic format of an Autoconf macro.
- * Macro Names::                 What to call your new macros.
- * Quoting::                     Protecting macros from unwanted expansion.
- * Dependencies Between Macros::  What to do when macros depend on other macros.
- 
- 
- File: autoconf.info,  Node: Macro Definitions,  Next: Macro Names,  Prev: Writing Macros,  Up: Writing Macros
- 
- Macro Definitions
- =================
- 
-    Autoconf macros are defined using the `AC_DEFUN' macro, which is
- similar to the `m4' builtin `define' macro.  In addition to defining a
- macro, `AC_DEFUN' adds to it some code which is used to constrain the
- order in which macros are called (*note Prerequisite Macros::.).
- 
-    An Autoconf macro definition looks like this:
- 
-      AC_DEFUN(MACRO-NAME, [MACRO-BODY])
- 
- The square brackets here do not indicate optional text: they should
- literally be present in the macro definition to avoid macro expansion
- problems (*note Quoting::.).  You can refer to any arguments passed to
- the macro as `$1', `$2', etc.
- 
-    To introduce comments in `m4', use the `m4' builtin `dnl'; it causes
- `m4' to discard the text through the next newline.  It is not needed
- between macro definitions in `acsite.m4' and `aclocal.m4', because all
- output is discarded until `AC_INIT' is called.
- 
-    *Note How to define new macros: (m4.info)Definitions, for more
- complete information on writing `m4' macros.
- 
- 
- File: autoconf.info,  Node: Macro Names,  Next: Quoting,  Prev: Macro Definitions,  Up: Writing Macros
- 
- Macro Names
- ===========
- 
-    All of the Autoconf macros have all-uppercase names starting with
- `AC_' to prevent them from accidentally conflicting with other text.
- All shell variables that they use for internal purposes have
- mostly-lowercase names starting with `ac_'.  To ensure that your macros
- don't conflict with present or future Autoconf macros, you should
- prefix your own macro names and any shell variables they use with some
- other sequence.  Possibilities include your initials, or an abbreviation
- for the name of your organization or software package.
- 
-    Most of the Autoconf macros' names follow a structured naming
- convention that indicates the kind of feature check by the name.  The
- macro names consist of several words, separated by underscores, going
- from most general to most specific.   The names of their cache
- variables use the same convention (*note Cache Variable Names::., for
- more information on them).
- 
-    The first word of the name after `AC_' usually tells the category of
- feature being tested.  Here are the categories used in Autoconf for
- specific test macros, the kind of macro that you are more likely to
- write.  They are also used for cache variables, in all-lowercase.  Use
- them where applicable; where they're not, invent your own categories.
- 
- `C'
-      C language builtin features.
- 
- `DECL'
-      Declarations of C variables in header files.
- 
- `FUNC'
-      Functions in libraries.
- 
- `GROUP'
-      UNIX group owners of files.
- 
- `HEADER'
-      Header files.
- 
- `LIB'
-      C libraries.
- 
- `PATH'
-      The full path names to files, including programs.
- 
- `PROG'
-      The base names of programs.
- 
- `STRUCT'
-      Definitions of C structures in header files.
- 
- `SYS'
-      Operating system features.
- 
- `TYPE'
-      C builtin or declared types.
- 
- `VAR'
-      C variables in libraries.
- 
-    After the category comes the name of the particular feature being
- tested.  Any further words in the macro name indicate particular aspects
- of the feature.  For example, `AC_FUNC_UTIME_NULL' checks the behavior
- of the `utime' function when called with a `NULL' pointer.
- 
-    A macro that is an internal subroutine of another macro should have a
- name that starts with the name of that other macro, followed by one or
- more words saying what the internal macro does.  For example,
- `AC_PATH_X' has internal macros `AC_PATH_X_XMKMF' and
- `AC_PATH_X_DIRECT'.
- 
- 
- File: autoconf.info,  Node: Quoting,  Next: Dependencies Between Macros,  Prev: Macro Names,  Up: Writing Macros
- 
- Quoting
- =======
- 
-    Macros that are called by other macros are evaluated by `m4' several
- times; each evaluation might require another layer of quotes to prevent
- unwanted expansions of macros or `m4' builtins, such as `define' and
- `$1'.  Quotes are also required around macro arguments that contain
- commas, since commas separate the arguments from each other.  It's a
- good idea to quote any macro arguments that contain newlines or calls
- to other macros, as well.
- 
-    Autoconf changes the `m4' quote characters from the default ``' and
- `'' to `[' and `]', because many of the macros use ``' and `'',
- mismatched.  However, in a few places the macros need to use brackets
- (usually in C program text or regular expressions).  In those places,
- they use the `m4' builtin command `changequote' to temporarily change
- the quote characters to `<<' and `>>'.  (Sometimes, if they don't need
- to quote anything, they disable quoting entirely instead by setting the
- quote characters to empty strings.)  Here is an example:
- 
-      AC_TRY_LINK(
-      changequote(<<, >>)dnl
-      <<#include <time.h>
-      #ifndef tzname /* For SGI.  */
-      extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
-      #endif>>,
-      changequote([, ])dnl
-      [atoi(*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)
- 
-    When you create a `configure' script using newly written macros,
- examine it carefully to check whether you need to add more quotes in
- your macros.  If one or more words have disappeared in the `m4' output,
- you need more quotes.  When in doubt, quote.
- 
-    However, it's also possible to put on too many layers of quotes.  If
- this happens, the resulting `configure' script will contain unexpanded
- macros.  The `autoconf' program checks for this problem by doing `grep
- AC_ configure'.
- 
- 
- File: autoconf.info,  Node: Dependencies Between Macros,  Prev: Quoting,  Up: Writing Macros
- 
- Dependencies Between Macros
- ===========================
- 
-    Some Autoconf macros depend on other macros having been called first
- in order to work correctly.  Autoconf provides a way to ensure that
- certain macros are called if needed and a way to warn the user if
- macros are called in an order that might cause incorrect operation.
- 
- * Menu:
- 
- * Prerequisite Macros::         Ensuring required information.
- * Suggested Ordering::          Warning about possible ordering problems.
- * Obsolete Macros::             Warning about old ways of doing things.
- 
- 
- File: autoconf.info,  Node: Prerequisite Macros,  Next: Suggested Ordering,  Prev: Dependencies Between Macros,  Up: Dependencies Between Macros
- 
- Prerequisite Macros
- -------------------
- 
-    A macro that you write might need to use values that have previously
- been computed by other macros.  For example, `AC_DECL_YYTEXT' examines
- the output of `flex' or `lex', so it depends on `AC_PROG_LEX' having
- been called first to set the shell variable `LEX'.
- 
-    Rather than forcing the user of the macros to keep track of the
- dependencies between them, you can use the `AC_REQUIRE' macro to do it
- automatically.  `AC_REQUIRE' can ensure that a macro is only called if
- it is needed, and only called once.
- 
-  - Macro: AC_REQUIRE (MACRO-NAME)
-      If the `m4' macro MACRO-NAME has not already been called, call it
-      (without any arguments).  Make sure to quote MACRO-NAME with
-      square brackets.  MACRO-NAME must have been defined using
-      `AC_DEFUN' or else contain a call to `AC_PROVIDE' to indicate that
-      it has been called.
- 
-    An alternative to using `AC_DEFUN' is to use `define' and call
- `AC_PROVIDE'.  Because this technique does not prevent nested messages,
- it is considered obsolete.
- 
-  - Macro: AC_PROVIDE (THIS-MACRO-NAME)
-      Record the fact that THIS-MACRO-NAME has been called.
-      THIS-MACRO-NAME should be the name of the macro that is calling
-      `AC_PROVIDE'.  An easy way to get it is from the `m4' builtin
-      variable `$0', like this:
- 
-           AC_PROVIDE([$0])
- 
- 
- File: autoconf.info,  Node: Suggested Ordering,  Next: Obsolete Macros,  Prev: Prerequisite Macros,  Up: Dependencies Between Macros
- 
- Suggested Ordering
- ------------------
- 
-    Some macros should be run before another macro if both are called,
- but neither *requires* that the other be called.  For example, a macro
- that changes the behavior of the C compiler should be called before any
- macros that run the C compiler.  Many of these dependencies are noted in
- the documentation.
- 
-    Autoconf provides the `AC_BEFORE' macro to warn users when macros
- with this kind of dependency appear out of order in a `configure.in'
- file.  The warning occurs when creating `configure' from
- `configure.in', not when running `configure'.  For example,
- `AC_PROG_CPP' checks whether the C compiler can run the C preprocessor
- when given the `-E' option.  It should therefore be called after any
- macros that change which C compiler is being used, such as
- `AC_PROG_CC'.  So `AC_PROG_CC' contains:
- 
-      AC_BEFORE([$0], [AC_PROG_CPP])dnl
- 
- This warns the user if a call to `AC_PROG_CPP' has already occurred
- when `AC_PROG_CC' is called.
- 
-  - Macro: AC_BEFORE (THIS-MACRO-NAME, CALLED-MACRO-NAME)
-      Make `m4' print a warning message on the standard error output if
-      CALLED-MACRO-NAME has already been called.  THIS-MACRO-NAME should
-      be the name of the macro that is calling `AC_BEFORE'.  The macro
-      CALLED-MACRO-NAME must have been defined using `AC_DEFUN' or else
-      contain a call to `AC_PROVIDE' to indicate that it has been called.
- 
- 
- File: autoconf.info,  Node: Obsolete Macros,  Prev: Suggested Ordering,  Up: Dependencies Between Macros
- 
- Obsolete Macros
- ---------------
- 
-    Configuration and portability technology has evolved over the years.
- Often better ways of solving a particular problem are developed, or
- ad-hoc approaches are systematized.  This process has occurred in many
- parts of Autoconf.  One result is that some of the macros are now
- considered "obsolete"; they still work, but are no longer considered
- the best thing to do.  Autoconf provides the `AC_OBSOLETE' macro to
- warn users producing `configure' scripts when they use obsolete macros,
- to encourage them to modernize.  A sample call is:
- 
-      AC_OBSOLETE([$0], [; use AC_CHECK_HEADERS(unistd.h) instead])dnl
- 
-  - Macro: AC_OBSOLETE (THIS-MACRO-NAME [, SUGGESTION])
-      Make `m4' print a message on the standard error output warning that
-      THIS-MACRO-NAME is obsolete, and giving the file and line number
-      where it was called.  THIS-MACRO-NAME should be the name of the
-      macro that is calling `AC_OBSOLETE'.  If SUGGESTION is given, it
-      is printed at the end of the warning message; for example, it can
-      be a suggestion for what to use instead of THIS-MACRO-NAME.
- 
- 
- File: autoconf.info,  Node: Manual Configuration,  Next: Site Configuration,  Prev: Writing Macros,  Up: Top
- 
- Manual Configuration
- ********************
- 
-    A few kinds of features can't be guessed automatically by running
- test programs.  For example, the details of the object file format, or
- special options that need to be passed to the compiler or linker.  You
- can check for such features using ad-hoc means, such as having
- `configure' check the output of the `uname' program, or looking for
- libraries that are unique to particular systems.  However, Autoconf
- provides a uniform method for handling unguessable features.
- 
- * Menu:
- 
- * Specifying Names::            Specifying the system type.
- * Canonicalizing::              Getting the canonical system type.
- * System Type Variables::       Variables containing the system type.
- * Using System Type::           What to do with the system type.
- 
- 
- File: autoconf.info,  Node: Specifying Names,  Next: Canonicalizing,  Prev: Manual Configuration,  Up: Manual Configuration
- 
- Specifying the System Type
- ==========================
- 
-    Like other GNU `configure' scripts, Autoconf-generated `configure'
- scripts can make decisions based on a canonical name for the system
- type, which has the form:
- 
-      CPU-COMPANY-SYSTEM
- 
-    `configure' can usually guess the canonical name for the type of
- system it's running on.  To do so it runs a script called
- `config.guess', which derives the name using the `uname' command or
- symbols predefined by the C preprocessor.
- 
-    Alternately, the user can specify the system type with command line
- arguments to `configure'.  Doing so is necessary when cross-compiling.
- In the most complex case of cross-compiling, three system types are
- involved.  The options to specify them are:
- 
- `--build=BUILD-TYPE'
-      the type of system on which the package is being configured and
-      compiled (rarely needed);
- 
- `--host=HOST-TYPE'
-      the type of system on which the package will run;
- 
- `--target=TARGET-TYPE'
-      the type of system for which any compiler tools in the package will
-      produce code.
- 
- If the user gives `configure' a non-option argument, it is used as the
- default for the host, target, and build system types if the user does
- not specify them explicitly with options.  The target and build types
- default to the host type if it is given and they are not.  If you are
- cross-compiling, you still have to specify the names of the cross-tools
- you use, in particular the C compiler, on the `configure' command line,
- e.g.,
- 
-      CC=m68k-coff-gcc configure --target=m68k-coff
- 
-    `configure' recognizes short aliases for many system types; for
- example, `decstation' can be given on the command line instead of
- `mips-dec-ultrix4.2'.  `configure' runs a script called `config.sub' to
- canonicalize system type aliases.
- 
- 
- File: autoconf.info,  Node: Canonicalizing,  Next: System Type Variables,  Prev: Specifying Names,  Up: Manual Configuration
- 
- Getting the Canonical System Type
- =================================
- 
-    The following macros make the system type available to `configure'
- scripts.  They run the shell script `config.guess' to determine any
- values for the host, target, and build types that they need and the user
- did not specify on the command line.  They run `config.sub' to
- canonicalize any aliases the user gave.  If you use these macros, you
- must distribute those two shell scripts along with your source code.
- *Note Output::, for information about the `AC_CONFIG_AUX_DIR' macro
- which you can use to control which directory `configure' looks for
- those scripts in.  If you do not use either of these macros,
- `configure' ignores any `--host', `--target', and `--build' options
- given to it.
- 
-  - Macro: AC_CANONICAL_SYSTEM
-      Determine the system type and set output variables to the names of
-      the canonical system types.  *Note System Type Variables::, for
-      details about the variables this macro sets.
- 
-  - Macro: AC_CANONICAL_HOST
-      Perform only the subset of `AC_CANONICAL_SYSTEM' relevant to the
-      host type.  This is all that is needed for programs that are not
-      part of a compiler toolchain.
- 
-  - Macro: AC_VALIDATE_CACHED_SYSTEM_TUPLE (CMD)
-      If the cache file is inconsistent with the current host, target
-      and build system types, execute CMD or print a default error
-      message.
- 
- 
- File: autoconf.info,  Node: System Type Variables,  Next: Using System Type,  Prev: Canonicalizing,  Up: Manual Configuration
- 
- System Type Variables
- =====================
- 
-    After calling `AC_CANONICAL_SYSTEM', the following output variables
- contain the system type information.  After `AC_CANONICAL_HOST', only
- the `host' variables below are set.
- 
- ``build', `host', `target''
-      the canonical system names;
- 
- ``build_alias', `host_alias', `target_alias''
-      the names the user specified, or the canonical names if
-      `config.guess' was used;
- 
- ``build_cpu', `build_vendor', `build_os''
- ``host_cpu', `host_vendor', `host_os''
- ``target_cpu', `target_vendor', `target_os''
-      the individual parts of the canonical names (for convenience).
- 
- 
- File: autoconf.info,  Node: Using System Type,  Prev: System Type Variables,  Up: Manual Configuration
- 
- Using the System Type
- =====================
- 
-    How do you use a canonical system type?  Usually, you use it in one
- or more `case' statements in `configure.in' to select system-specific C
- files.  Then link those files, which have names based on the system
- name, to generic names, such as `host.h' or `target.c'.  The `case'
- statement patterns can use shell wildcards to group several cases
- together, like in this fragment:
- 
-      case "$target" in
-      i386-*-mach* | i386-*-gnu*) obj_format=aout emulation=mach bfd_gas=yes ;;
-      i960-*-bout) obj_format=bout ;;
-      esac
- 
-  - Macro: AC_LINK_FILES (SOURCE..., DEST...)
-      Make `AC_OUTPUT' link each of the existing files SOURCE to the
-      corresponding link name DEST.  Makes a symbolic link if possible,
-      otherwise a hard link.  The DEST and SOURCE names should be
-      relative to the top level source or build directory.  This macro
-      may be called multiple times.
- 
-      For example, this call:
- 
-           AC_LINK_FILES(config/${machine}.h config/${obj_format}.h, host.h object.h)
- 
-      creates in the current directory `host.h', which is a link to
-      `SRCDIR/config/${machine}.h', and `object.h', which is a link to
-      `SRCDIR/config/${obj_format}.h'.
- 
-    You can also use the host system type to find cross-compilation
- tools.  *Note Generic Programs::, for information about the
- `AC_CHECK_TOOL' macro which does that.
- 
- 
- File: autoconf.info,  Node: Site Configuration,  Next: Invoking configure,  Prev: Manual Configuration,  Up: Top
- 
- Site Configuration
- ******************
- 
-    `configure' scripts support several kinds of local configuration
- decisions.  There are ways for users to specify where external software
- packages are, include or exclude optional features, install programs
- under modified names, and set default values for `configure' options.
- 
- * Menu:
- 
- * External Software::           Working with other optional software.
- * Package Options::             Selecting optional features.
- * Site Details::                Configuring site details.
- * Transforming Names::          Changing program names when installing.
- * Site Defaults::               Giving `configure' local defaults.
- 
- 
- File: autoconf.info,  Node: External Software,  Next: Package Options,  Prev: Site Configuration,  Up: Site Configuration
- 
- Working With External Software
- ==============================
- 
-    Some packages require, or can optionally use, other software packages
- which are already installed.  The user can give `configure' command
- line options to specify which such external software to use.  The
- options have one of these forms:
- 
-      --with-PACKAGE[=ARG]
-      --without-PACKAGE
- 
-    For example, `--with-gnu-ld' means work with the GNU linker instead
- of some other linker.  `--with-x' means work with The X Window System.
- 
-    The user can give an argument by following the package name with `='
- and the argument.  Giving an argument of `no' is for packages that are
- used by default; it says to *not* use the package.  An argument that is
- neither `yes' nor `no' could include a name or number of a version of
- the other package, to specify more precisely which other package this
- program is supposed to work with.  If no argument is given, it defaults
- to `yes'.  `--without-PACKAGE' is equivalent to `--with-PACKAGE=no'.
- 
-    `configure' scripts do not complain about `--with-PACKAGE' options
- that they do not support.  This behavior permits configuring a source
- tree containing multiple packages with a top-level `configure' script
- when the packages support different options, without spurious error
- messages about options that some of the packages support.  An
- unfortunate side effect is that option spelling errors are not
- diagnosed.  No better approach to this problem has been suggested so
- far.
- 
-    For each external software package that may be used, `configure.in'
- should call `AC_ARG_WITH' to detect whether the `configure' user asked
- to use it.  Whether each package is used or not by default, and which
- arguments are valid, is up to you.
- 
-  - Macro: AC_ARG_WITH (PACKAGE, HELP-STRING [, ACTION-IF-GIVEN [,
-           ACTION-IF-NOT-GIVEN]])
-      If the user gave `configure' the option `--with-PACKAGE' or
-      `--without-PACKAGE', run shell commands ACTION-IF-GIVEN.  If
-      neither option was given, run shell commands ACTION-IF-NOT-GIVEN.
-      The name PACKAGE indicates another software package that this
-      program should work with.  It should consist only of alphanumeric
-      characters and dashes.
- 
-      The option's argument is available to the shell commands
-      ACTION-IF-GIVEN in the shell variable `withval', which is actually
-      just the value of the shell variable `with_PACKAGE', with any `-'
-      characters changed into `_'.  You may use that variable instead,
-      if you wish.
- 
-      The argument HELP-STRING is a description of the option which
-      looks like this:
-             --with-readline         support fancy command line editing
- 
-      HELP-STRING may be more than one line long, if more detail is
-      needed.  Just make sure the columns line up in `configure --help'.
-      Avoid tabs in the help string.  You'll need to enclose it in `['
-      and `]' in order to produce the leading spaces.
- 
-  - Macro: AC_WITH (PACKAGE, ACTION-IF-GIVEN [, ACTION-IF-NOT-GIVEN])
-      This is an obsolete version of `AC_ARG_WITH' that does not support
-      providing a help string.
- 
- 
- File: autoconf.info,  Node: Package Options,  Next: Site Details,  Prev: External Software,  Up: Site Configuration
- 
- Choosing Package Options
- ========================
- 
-    If a software package has optional compile-time features, the user
- can give `configure' command line options to specify whether to compile
- them.  The options have one of these forms:
- 
-      --enable-FEATURE[=ARG]
-      --disable-FEATURE
- 
-    These options allow users to choose which optional features to build
- and install.  `--enable-FEATURE' options should never make a feature
- behave differently or cause one feature to replace another.  They
- should only cause parts of the program to be built rather than left out.
- 
-    The user can give an argument by following the feature name with `='
- and the argument.  Giving an argument of `no' requests that the feature
- *not* be made available.  A feature with an argument looks like
- `--enable-debug=stabs'.  If no argument is given, it defaults to `yes'.
- `--disable-FEATURE' is equivalent to `--enable-FEATURE=no'.
- 
-    `configure' scripts do not complain about `--enable-FEATURE' options
- that they do not support.  This behavior permits configuring a source
- tree containing multiple packages with a top-level `configure' script
- when the packages support different options, without spurious error
- messages about options that some of the packages support.  An
- unfortunate side effect is that option spelling errors are not
- diagnosed.  No better approach to this problem has been suggested so
- far.
- 
-    For each optional feature, `configure.in' should call
- `AC_ARG_ENABLE' to detect whether the `configure' user asked to include
- it.  Whether each feature is included or not by default, and which
- arguments are valid, is up to you.
- 
-  - Macro: AC_ARG_ENABLE (FEATURE, HELP-STRING [, ACTION-IF-GIVEN [,
-           ACTION-IF-NOT-GIVEN]])
-      If the user gave `configure' the option `--enable-FEATURE' or
-      `--disable-FEATURE', run shell commands ACTION-IF-GIVEN.  If
-      neither option was given, run shell commands ACTION-IF-NOT-GIVEN.
-      The name FEATURE indicates an optional user-level facility.  It
-      should consist only of alphanumeric characters and dashes.
- 
-      The option's argument is available to the shell commands
-      ACTION-IF-GIVEN in the shell variable `enableval', which is
-      actually just the value of the shell variable `enable_FEATURE',
-      with any `-' characters changed into `_'.  You may use that
-      variable instead, if you wish.  The HELP-STRING argument is like
-      that of `AC_ARG_WITH' (*note External Software::.).
- 
-  - Macro: AC_ENABLE (FEATURE, ACTION-IF-GIVEN [, ACTION-IF-NOT-GIVEN])
-      This is an obsolete version of `AC_ARG_ENABLE' that does not
-      support providing a help string.
- 
- 
- File: autoconf.info,  Node: Site Details,  Next: Transforming Names,  Prev: Package Options,  Up: Site Configuration
- 
- Configuring Site Details
- ========================
- 
-    Some software packages require complex site-specific information.
- Some examples are host names to use for certain services, company
- names, and email addresses to contact.  Since some configuration
- scripts generated by Metaconfig ask for such information interactively,
- people sometimes wonder how to get that information in
- Autoconf-generated configuration scripts, which aren't interactive.
- 
-    Such site configuration information should be put in a file that is
- edited *only by users*, not by programs.  The location of the file can
- either be based on the `prefix' variable, or be a standard location
- such as the user's home directory.  It could even be specified by an
- environment variable.  The programs should examine that file at run
- time, rather than at compile time.  Run time configuration is more
- convenient for users and makes the configuration process simpler than
- getting the information while configuring.  *Note Variables for
- Installation Directories: (standards)Directory Variables, for more
- information on where to put data files.
- 
- 
- File: autoconf.info,  Node: Transforming Names,  Next: Site Defaults,  Prev: Site Details,  Up: Site Configuration
- 
- Transforming Program Names When Installing
- ==========================================
- 
-    Autoconf supports changing the names of programs when installing
- them.  In order to use these transformations, `configure.in' must call
- the macro `AC_ARG_PROGRAM'.
- 
-  - Macro: AC_ARG_PROGRAM
-      Place in output variable `program_transform_name' a sequence of
-      `sed' commands for changing the names of installed programs.
- 
-      If any of the options described below are given to `configure',
-      program names are transformed accordingly.  Otherwise, if
-      `AC_CANONICAL_SYSTEM' has been called and a `--target' value is
-      given that differs from the host type (specified with `--host' or
-      defaulted by `config.sub'), the target type followed by a dash is
-      used as a prefix.  Otherwise, no program name transformation is
-      done.
- 
- * Menu:
- 
- * Transformation Options::      `configure' options to transform names.
- * Transformation Examples::     Sample uses of transforming names.
- * Transformation Rules::        `Makefile' uses of transforming names.
- 
- 
- File: autoconf.info,  Node: Transformation Options,  Next: Transformation Examples,  Prev: Transforming Names,  Up: Transforming Names
- 
- Transformation Options
- ----------------------
- 
-    You can specify name transformations by giving `configure' these
- command line options:
- 
- `--program-prefix=PREFIX'
-      prepend PREFIX to the names;
- 
- `--program-suffix=SUFFIX'
-      append SUFFIX to the names;
- 
- `--program-transform-name=EXPRESSION'
-      perform `sed' substitution EXPRESSION on the names.
- 
- 
- File: autoconf.info,  Node: Transformation Examples,  Next: Transformation Rules,  Prev: Transformation Options,  Up: Transforming Names
- 
- Transformation Examples
- -----------------------
- 
-    These transformations are useful with programs that can be part of a
- cross-compilation development environment.  For example, a
- cross-assembler running on a Sun 4 configured with
- `--target=i960-vxworks' is normally installed as `i960-vxworks-as',
- rather than `as', which could be confused with a native Sun 4 assembler.
- 
-    You can force a program name to begin with `g', if you don't want
- GNU programs installed on your system to shadow other programs with the
- same name.  For example, if you configure GNU `diff' with
- `--program-prefix=g', then when you run `make install' it is installed
- as `/usr/local/bin/gdiff'.
- 
-    As a more sophisticated example, you could use
-      --program-transform-name='s/^/g/; s/^gg/g/; s/^gless/less/'
- 
- to prepend `g' to most of the program names in a source tree, excepting
- those like `gdb' that already have one and those like `less' and
- `lesskey' that aren't GNU programs.  (That is assuming that you have a
- source tree containing those programs that is set up to use this
- feature.)
- 
-    One way to install multiple versions of some programs simultaneously
- is to append a version number to the name of one or both.  For example,
- if you want to keep Autoconf version 1 around for awhile, you can
- configure Autoconf version 2 using `--program-suffix=2' to install the
- programs as `/usr/local/bin/autoconf2', `/usr/local/bin/autoheader2',
- etc.
- 
- 
- File: autoconf.info,  Node: Transformation Rules,  Prev: Transformation Examples,  Up: Transforming Names
- 
- Transformation Rules
- --------------------
- 
-    Here is how to use the variable `program_transform_name' in a
- `Makefile.in':
- 
-      transform=@program_transform_name@
-      install: all
-              $(INSTALL_PROGRAM) myprog $(bindir)/`echo myprog|sed '$(transform)'`
-      
-      uninstall:
-              rm -f $(bindir)/`echo myprog|sed '$(transform)'`
- 
- If you have more than one program to install, you can do it in a loop:
- 
-      PROGRAMS=cp ls rm
-      install:
-              for p in $(PROGRAMS); do \
-                $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
-              done
-      
-      uninstall:
-              for p in $(PROGRAMS); do \
-                rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
-              done
- 
-    Whether to do the transformations on documentation files (Texinfo or
- `man') is a tricky question; there seems to be no perfect answer, due
- to the several reasons for name transforming.  Documentation is not
- usually particular to a specific architecture, and Texinfo files do not
- conflict with system documentation.  But they might conflict with
- earlier versions of the same files, and `man' pages sometimes do
- conflict with system documentation.  As a compromise, it is probably
- best to do name transformations on `man' pages but not on Texinfo
- manuals.
- 
- 
- File: autoconf.info,  Node: Site Defaults,  Prev: Transforming Names,  Up: Site Configuration
- 
- Setting Site Defaults
- =====================
- 
-    Autoconf-generated `configure' scripts allow your site to provide
- default values for some configuration values.  You do this by creating
- site- and system-wide initialization files.
- 
-    If the environment variable `CONFIG_SITE' is set, `configure' uses
- its value as the name of a shell script to read.  Otherwise, it reads
- the shell script `PREFIX/share/config.site' if it exists, then
- `PREFIX/etc/config.site' if it exists.  Thus, settings in
- machine-specific files override those in machine-independent ones in
- case of conflict.
- 
-    Site files can be arbitrary shell scripts, but only certain kinds of
- code are really appropriate to be in them.  Because `configure' reads
- any cache file after it has read any site files, a site file can define
- a default cache file to be shared between all Autoconf-generated
- `configure' scripts run on that system.  If you set a default cache
- file in a site file, it is a good idea to also set the output variable
- `CC' in that site file, because the cache file is only valid for a
- particular compiler, but many systems have several available.
- 
-    You can examine or override the value set by a command line option to
- `configure' in a site file; options set shell variables that have the
- same names as the options, with any dashes turned into underscores.
- The exceptions are that `--without-' and `--disable-' options are like
- giving the corresponding `--with-' or `--enable-' option and the value
- `no'.  Thus, `--cache-file=localcache' sets the variable `cache_file'
- to the value `localcache'; `--enable-warnings=no' or
- `--disable-warnings' sets the variable `enable_warnings' to the value
- `no'; `--prefix=/usr' sets the variable `prefix' to the value `/usr';
- etc.
- 
-    Site files are also good places to set default values for other
- output variables, such as `CFLAGS', if you need to give them non-default
- values: anything you would normally do, repetitively, on the command
- line.  If you use non-default values for PREFIX or EXEC_PREFIX
- (wherever you locate the site file), you can set them in the site file
- if you specify it with the `CONFIG_SITE' environment variable.
- 
-    You can set some cache values in the site file itself.  Doing this is
- useful if you are cross-compiling, so it is impossible to check features
- that require running a test program.  You could "prime the cache" by
- setting those values correctly for that system in
- `PREFIX/etc/config.site'.  To find out the names of the cache variables
- you need to set, look for shell variables with `_cv_' in their names in
- the affected `configure' scripts, or in the Autoconf `m4' source code
- for those macros.
- 
-    The cache file is careful to not override any variables set in the
- site files.  Similarly, you should not override command-line options in
- the site files.  Your code should check that variables such as `prefix'
- and `cache_file' have their default values (as set near the top of
- `configure') before changing them.
- 
-    Here is a sample file `/usr/share/local/gnu/share/config.site'.  The
- command `configure --prefix=/usr/share/local/gnu' would read this file
- (if `CONFIG_SITE' is not set to a different file).
- 
-      # config.site for configure
-      #
-      # Change some defaults.
-      test "$prefix" = NONE && prefix=/usr/share/local/gnu
-      test "$exec_prefix" = NONE && exec_prefix=/usr/local/gnu
-      test "$sharedstatedir" = '${prefix}/com' && sharedstatedir=/var
-      test "$localstatedir" = '${prefix}/var' && localstatedir=/var
-      #
-      # Give Autoconf 2.x generated configure scripts a shared default
-      # cache file for feature test results, architecture-specific.
-      if test "$cache_file" = ./config.cache; then
-        cache_file="$prefix/var/config.cache"
-        # A cache file is only valid for one C compiler.
-        CC=gcc
-      fi
- 
- 
- File: autoconf.info,  Node: Invoking configure,  Next: Invoking config.status,  Prev: Site Configuration,  Up: Top
- 
- Running `configure' Scripts
- ***************************
- 
-    Below are instructions on how to configure a package that uses a
- `configure' script, suitable for inclusion as an `INSTALL' file in the
- package.  A plain-text version of `INSTALL' which you may use comes
- with Autoconf.
- 
- * Menu:
- 
- * Basic Installation::          Instructions for typical cases.
- * Compilers and Options::       Selecting compilers and optimization.
- * Multiple Architectures::      Compiling for multiple architectures at once.
- * Installation Names::          Installing in different directories.
- * Optional Features::           Selecting optional features.
- * System Type::                 Specifying the system type.
- * Sharing Defaults::            Setting site-wide defaults for `configure'.
- * Operation Controls::          Changing how `configure' runs.
- 
- 
- File: autoconf.info,  Node: Basic Installation,  Next: Compilers and Options,  Up: Invoking configure
- 
- Basic Installation
- ==================
- 
-    These are generic installation instructions.
- 
-    The `configure' shell script attempts to guess correct values for
- various system-dependent variables used during compilation.  It uses
- those values to create a `Makefile' in each directory of the package.
- It may also create one or more `.h' files containing system-dependent
- definitions.  Finally, it creates a shell script `config.status' that
- you can run in the future to recreate the current configuration, a file
- `config.cache' that saves the results of its tests to speed up
- reconfiguring, and a file `config.log' containing compiler output
- (useful mainly for debugging `configure').
- 
-    If you need to do unusual things to compile the package, please try
- to figure out how `configure' could check whether to do them, and mail
- diffs or instructions to the address given in the `README' so they can
- be considered for the next release.  If at some point `config.cache'
- contains results you don't want to keep, you may remove or edit it.
- 
-    The file `configure.in' is used to create `configure' by a program
- called `autoconf'.  You only need `configure.in' if you want to change
- it or regenerate `configure' using a newer version of `autoconf'.
- 
- The simplest way to compile this package is:
- 
-   1. `cd' to the directory containing the package's source code and type
-      `./configure' to configure the package for your system.  If you're
-      using `csh' on an old version of System V, you might need to type
-      `sh ./configure' instead to prevent `csh' from trying to execute
-      `configure' itself.
- 
-      Running `configure' takes awhile.  While running, it prints some
-      messages telling which features it is checking for.
- 
-   2. Type `make' to compile the package.
- 
-   3. Optionally, type `make check' to run any self-tests that come with
-      the package.
- 
-   4. Type `make install' to install the programs and any data files and
-      documentation.
- 
-   5. You can remove the program binaries and object files from the
-      source code directory by typing `make clean'.  To also remove the
-      files that `configure' created (so you can compile the package for
-      a different kind of computer), type `make distclean'.  There is
-      also a `make maintainer-clean' target, but that is intended mainly
-      for the package's developers.  If you use it, you may have to get
-      all sorts of other programs in order to regenerate files that came
-      with the distribution.
- 
- 
- File: autoconf.info,  Node: Compilers and Options,  Next: Multiple Architectures,  Prev: Basic Installation,  Up: Invoking configure
- 
- Compilers and Options
- =====================
- 
-    Some systems require unusual options for compilation or linking that
- the `configure' script does not know about.  You can give `configure'
- initial values for variables by setting them in the environment.  Using
- a Bourne-compatible shell, you can do that on the command line like
- this:
-      CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
- 
- Or on systems that have the `env' program, you can do it like this:
-      env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
- 
- 
- File: autoconf.info,  Node: Multiple Architectures,  Next: Installation Names,  Prev: Compilers and Options,  Up: Invoking configure
- 
- Compiling For Multiple Architectures
- ====================================
- 
-    You can compile the package for more than one kind of computer at the
- same time, by placing the object files for each architecture in their
- own directory.  To do this, you must use a version of `make' that
- supports the `VPATH' variable, such as GNU `make'.  `cd' to the
- directory where you want the object files and executables to go and run
- the `configure' script.  `configure' automatically checks for the
- source code in the directory that `configure' is in and in `..'.
- 
-    If you have to use a `make' that does not supports the `VPATH'
- variable, you have to compile the package for one architecture at a time
- in the source code directory.  After you have installed the package for
- one architecture, use `make distclean' before reconfiguring for another
- architecture.
- 
- 
- File: autoconf.info,  Node: Installation Names,  Next: Optional Features,  Prev: Multiple Architectures,  Up: Invoking configure
- 
- Installation Names
- ==================
- 
-    By default, `make install' will install the package's files in
- `/usr/local/bin', `/usr/local/man', etc.  You can specify an
- installation prefix other than `/usr/local' by giving `configure' the
- option `--prefix=PATH'.
- 
-    You can specify separate installation prefixes for
- architecture-specific files and architecture-independent files.  If you
- give `configure' the option `--exec-prefix=PATH', the package will use
- PATH as the prefix for installing programs and libraries.
- Documentation and other data files will still use the regular prefix.
- 
-    In addition, if you use an unusual directory layout you can give
- options like `--bindir=PATH' to specify different values for particular
- kinds of files.  Run `configure --help' for a list of the directories
- you can set and what kinds of files go in them.
- 
-    If the package supports it, you can cause programs to be installed
- with an extra prefix or suffix on their names by giving `configure' the
- option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
- 
- 
- File: autoconf.info,  Node: Optional Features,  Next: System Type,  Prev: Installation Names,  Up: Invoking configure
- 
- Optional Features
- =================
- 
-    Some packages pay attention to `--enable-FEATURE' options to
- `configure', where FEATURE indicates an optional part of the package.
- They may also pay attention to `--with-PACKAGE' options, where PACKAGE
- is something like `gnu-as' or `x' (for the X Window System).  The
- `README' should mention any `--enable-' and `--with-' options that the
- package recognizes.
- 
-    For packages that use the X Window System, `configure' can usually
- find the X include and library files automatically, but if it doesn't,
- you can use the `configure' options `--x-includes=DIR' and
- `--x-libraries=DIR' to specify their locations.
- 
- 
- File: autoconf.info,  Node: System Type,  Next: Sharing Defaults,  Prev: Optional Features,  Up: Invoking configure
- 
- Specifying the System Type
- ==========================
- 
-    There may be some features `configure' can not figure out
- automatically, but needs to determine by the type of host the package
- will run on.  Usually `configure' can figure that out, but if it prints
- a message saying it can not guess the host type, give it the
- `--host=TYPE' option.  TYPE can either be a short name for the system
- type, such as `sun4', or a canonical name with three fields:
-      CPU-COMPANY-SYSTEM
- 
- See the file `config.sub' for the possible values of each field.  If
- `config.sub' isn't included in this package, then this package doesn't
- need to know the host type.
- 
-    If you are building compiler tools for cross-compiling, you can also
- use the `--target=TYPE' option to select the type of system they will
- produce code for and the `--build=TYPE' option to select the type of
- system on which you are compiling the package.
- 
- 
- File: autoconf.info,  Node: Sharing Defaults,  Next: Operation Controls,  Prev: System Type,  Up: Invoking configure
- 
- Sharing Defaults
- ================
- 
-    If you want to set default values for `configure' scripts to share,
- you can create a site shell script called `config.site' that gives
- default values for variables like `CC', `cache_file', and `prefix'.
- `configure' looks for `PREFIX/share/config.site' if it exists, then
- `PREFIX/etc/config.site' if it exists.  Or, you can set the
- `CONFIG_SITE' environment variable to the location of the site script.
- A warning: not all `configure' scripts look for a site script.
- 
- 
- File: autoconf.info,  Node: Operation Controls,  Prev: Sharing Defaults,  Up: Invoking configure
- 
- Operation Controls
- ==================
- 
-    `configure' recognizes the following options to control how it
- operates.
- 
- `--cache-file=FILE'
-      Use and save the results of the tests in FILE instead of
-      `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-      debugging `configure'.
- 
- `--help'
-      Print a summary of the options to `configure', and exit.
- 
- `--quiet'
- `--silent'
- `-q'
-      Do not print messages saying which checks are being made.  To
-      suppress all normal output, redirect it to `/dev/null' (any error
-      messages will still be shown).
- 
- `--srcdir=DIR'
-      Look for the package's source code in directory DIR.  Usually
-      `configure' can determine that directory automatically.
- 
- `--version'
-      Print the version of Autoconf used to generate the `configure'
-      script, and exit.
- 
- `configure' also accepts some other, not widely useful, options.
- 
- 
- File: autoconf.info,  Node: Invoking config.status,  Next: Questions,  Prev: Invoking configure,  Up: Top
- 
- Recreating a Configuration
- **************************
- 
-    The `configure' script creates a file named `config.status' which
- describes which configuration options were specified when the package
- was last configured.  This file is a shell script which, if run, will
- recreate the same configuration.
- 
-    You can give `config.status' the `--recheck' option to update
- itself.  This option is useful if you change `configure', so that the
- results of some tests might be different from the previous run.  The
- `--recheck' option re-runs `configure' with the same arguments you used
- before, plus the `--no-create' option, which prevent `configure' from
- running `config.status' and creating `Makefile' and other files, and
- the `--no-recursion' option, which prevents `configure' from running
- other `configure' scripts in subdirectories.  (This is so other
- `Makefile' rules can run `config.status' when it changes; *note
- Automatic Remaking::., for an example).
- 
-    `config.status' also accepts the options `--help', which prints a
- summary of the options to `config.status', and `--version', which
- prints the version of Autoconf used to create the `configure' script
- that generated `config.status'.
- 
-    `config.status' checks several optional environment variables that
- can alter its behavior:
- 
-  - Variable: CONFIG_SHELL
-      The shell with which to run `configure' for the `--recheck'
-      option.  It must be Bourne-compatible.  The default is `/bin/sh'.
- 
-  - Variable: CONFIG_STATUS
-      The file name to use for the shell script that records the
-      configuration.  The default is `./config.status'.  This variable is
-      useful when one package uses parts of another and the `configure'
-      scripts shouldn't be merged because they are maintained separately.
- 
-    The following variables provide one way for separately distributed
- packages to share the values computed by `configure'.  Doing so can be
- useful if some of the packages need a superset of the features that one
- of them, perhaps a common library, does.  These variables allow a
- `config.status' file to create files other than the ones that its
- `configure.in' specifies, so it can be used for a different package.
- 
-  - Variable: CONFIG_FILES
-      The files in which to perform `@VARIABLE@' substitutions.  The
-      default is the arguments given to `AC_OUTPUT' in `configure.in'.
- 
-  - Variable: CONFIG_HEADERS
-      The files in which to substitute C `#define' statements.  The
-      default is the arguments given to `AC_CONFIG_HEADER'; if that
-      macro was not called, `config.status' ignores this variable.
- 
-    These variables also allow you to write `Makefile' rules that
- regenerate only some of the files.  For example, in the dependencies
- given above (*note Automatic Remaking::.), `config.status' is run twice
- when `configure.in' has changed.  If that bothers you, you can make
- each run only regenerate the files for that rule:
- 
-      config.h: stamp-h
-      stamp-h: config.h.in config.status
-              CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
-              echo > stamp-h
-      
-      Makefile: Makefile.in config.status
-              CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
- 
- (If `configure.in' does not call `AC_CONFIG_HEADER', there is no need
- to set `CONFIG_HEADERS' in the `make' rules.)
- 
- 
- File: autoconf.info,  Node: Questions,  Next: Upgrading,  Prev: Invoking config.status,  Up: Top
- 
- Questions About Autoconf
- ************************
- 
-    Several questions about Autoconf come up occasionally.  Here some of
- them are addressed.
- 
- * Menu:
- 
- * Distributing::                Distributing `configure' scripts.
- * Why GNU m4::                  Why not use the standard `m4'?
- * Bootstrapping::               Autoconf and GNU `m4' require each other?
- * Why Not Imake::               Why GNU uses `configure' instead of Imake.
- 
- 
- File: autoconf.info,  Node: Distributing,  Next: Why GNU m4,  Prev: Questions,  Up: Questions
- 
- Distributing `configure' Scripts
- ================================
- 
-      What are the restrictions on distributing `configure'
-      scripts that Autoconf generates?  How does that affect my
-      programs that use them?
- 
-    There are no restrictions on how the configuration scripts that
- Autoconf produces may be distributed or used.  In Autoconf version 1,
- they were covered by the GNU General Public License.  We still
- encourage software authors to distribute their work under terms like
- those of the GPL, but doing so is not required to use Autoconf.
- 
-    Of the other files that might be used with `configure',
- `config.h.in' is under whatever copyright you use for your
- `configure.in', since it is derived from that file and from the public
- domain file `acconfig.h'.  `config.sub' and `config.guess' have an
- exception to the GPL when they are used with an Autoconf-generated
- `configure' script, which permits you to distribute them under the same
- terms as the rest of your package.  `install-sh' is from the X
- Consortium and is not copyrighted.
- 
- 
- File: autoconf.info,  Node: Why GNU m4,  Next: Bootstrapping,  Prev: Distributing,  Up: Questions
- 
- Why Require GNU `m4'?
- =====================
- 
-      Why does Autoconf require GNU `m4'?
- 
-    Many `m4' implementations have hard-coded limitations on the size
- and number of macros, which Autoconf exceeds.  They also lack several
- builtin macros that it would be difficult to get along without in a
- sophisticated application like Autoconf, including:
- 
-      builtin
-      indir
-      patsubst
-      __file__
-      __line__
- 
-    Since only software maintainers need to use Autoconf, and since GNU
- `m4' is simple to configure and install, it seems reasonable to require
- GNU `m4' to be installed also.  Many maintainers of GNU and other free
- software already have most of the GNU utilities installed, since they
- prefer them.
- 
- 
- File: autoconf.info,  Node: Bootstrapping,  Next: Why Not Imake,  Prev: Why GNU m4,  Up: Questions
- 
- How Can I Bootstrap?
- ====================
- 
-      If Autoconf requires GNU `m4' and GNU `m4' has an
-      Autoconf `configure' script, how do I bootstrap?  It seems
-      like a chicken and egg problem!
- 
-    This is a misunderstanding.  Although GNU `m4' does come with a
- `configure' script produced by Autoconf, Autoconf is not required in
- order to run the script and install GNU `m4'.  Autoconf is only
- required if you want to change the `m4' `configure' script, which few
- people have to do (mainly its maintainer).
- 
- 
- File: autoconf.info,  Node: Why Not Imake,  Prev: Bootstrapping,  Up: Questions
- 
- Why Not Imake?
- ==============
- 
-      Why not use Imake instead of `configure' scripts?
- 
-    Several people have written addressing this question, so I include
- adaptations of their explanations here.
- 
-    The following answer is based on one written by Richard Pixley:
- 
-    Autoconf generated scripts frequently work on machines which it has
- never been set up to handle before.  That is, it does a good job of
- inferring a configuration for a new system.  Imake cannot do this.
- 
-    Imake uses a common database of host specific data.  For X11, this
- makes sense because the distribution is made as a collection of tools,
- by one central authority who has control over the database.
- 
-    GNU tools are not released this way.  Each GNU tool has a maintainer;
- these maintainers are scattered across the world.  Using a common
- database would be a maintenance nightmare.  Autoconf may appear to be
- this kind of database, but in fact it is not.  Instead of listing host
- dependencies, it lists program requirements.
- 
-    If you view the GNU suite as a collection of native tools, then the
- problems are similar.  But the GNU development tools can be configured
- as cross tools in almost any host+target permutation.  All of these
- configurations can be installed concurrently.  They can even be
- configured to share host independent files across hosts.  Imake doesn't
- address these issues.
- 
-    Imake templates are a form of standardization.  The GNU coding
- standards address the same issues without necessarily imposing the same
- restrictions.
- 
-    Here is some further explanation, written by Per Bothner:
- 
-    One of the advantages of Imake is that it easy to generate large
- Makefiles using `cpp''s `#include' and macro mechanisms.  However,
- `cpp' is not programmable: it has limited conditional facilities, and
- no looping.  And `cpp' cannot inspect its environment.
- 
-    All of these problems are solved by using `sh' instead of `cpp'.
- The shell is fully programmable, has macro substitution, can execute
- (or source) other shell scripts, and can inspect its environment.
- 
-    Paul Eggert elaborates more:
- 
-    With Autoconf, installers need not assume that Imake itself is
- already installed and working well.  This may not seem like much of an
- advantage to people who are accustomed to Imake.  But on many hosts
- Imake is not installed or the default installation is not working well,
- and requiring Imake to install a package hinders the acceptance of that
- package on those hosts.  For example, the Imake template and
- configuration files might not be installed properly on a host, or the
- Imake build procedure might wrongly assume that all source files are in
- one big directory tree, or the Imake configuration might assume one
- compiler whereas the package or the installer needs to use another, or
- there might be a version mismatch between the Imake expected by the
- package and the Imake supported by the host.  These problems are much
- rarer with Autoconf, where each package comes with its own independent
- configuration processor.
- 
-    Also, Imake often suffers from unexpected interactions between
- `make' and the installer's C preprocessor.  The fundamental problem
- here is that the C preprocessor was designed to preprocess C programs,
- not `Makefile's.  This is much less of a problem with Autoconf, which
- uses the general-purpose preprocessor `m4', and where the package's
- author (rather than the installer) does the preprocessing in a standard
- way.
- 
-    Finally, Mark Eichin notes:
- 
-    Imake isn't all that extensible, either.  In order to add new
- features to Imake, you need to provide your own project template, and
- duplicate most of the features of the existing one.  This means that
- for a sophisticated project, using the vendor-provided Imake templates
- fails to provide any leverage--since they don't cover anything that
- your own project needs (unless it is an X11 program).
- 
-    On the other side, though:
- 
-    The one advantage that Imake has over `configure': `Imakefile's tend
- to be much shorter (likewise, less redundant) than `Makefile.in's.
- There is a fix to this, however--at least for the Kerberos V5 tree,
- we've modified things to call in common `post.in' and `pre.in'
- `Makefile' fragments for the entire tree.  This means that a lot of
- common things don't have to be duplicated, even though they normally
- are in `configure' setups.
- 
- 
- File: autoconf.info,  Node: Upgrading,  Next: History,  Prev: Questions,  Up: Top
- 
- Upgrading From Version 1
- ************************
- 
-    Autoconf version 2 is mostly backward compatible with version 1.
- However, it introduces better ways to do some things, and doesn't
- support some of the ugly things in version 1.  So, depending on how
- sophisticated your `configure.in' files are, you might have to do some
- manual work in order to upgrade to version 2.  This chapter points out
- some problems to watch for when upgrading.  Also, perhaps your
- `configure' scripts could benefit from some of the new features in
- version 2; the changes are summarized in the file `NEWS' in the
- Autoconf distribution.
- 
-    First, make sure you have GNU `m4' version 1.1 or higher installed,
- preferably 1.3 or higher.  Versions before 1.1 have bugs that prevent
- them from working with Autoconf version 2.  Versions 1.3 and later are
- much faster than earlier versions, because as of version 1.3, GNU `m4'
- has a more efficient implementation of diversions and can freeze its
- internal state in a file that it can read back quickly.
- 
- * Menu:
- 
- * Changed File Names::          Files you might rename.
- * Changed Makefiles::           New things to put in `Makefile.in'.
- * Changed Macros::              Macro calls you might replace.
- * Invoking autoupdate::         Replacing old macro names in `configure.in'.
- * Changed Results::             Changes in how to check test results.
- * Changed Macro Writing::       Better ways to write your own macros.
- 
- 
- File: autoconf.info,  Node: Changed File Names,  Next: Changed Makefiles,  Prev: Upgrading,  Up: Upgrading
- 
- Changed File Names
- ==================
- 
-    If you have an `aclocal.m4' installed with Autoconf (as opposed to
- in a particular package's source directory), you must rename it to
- `acsite.m4'.  *Note Invoking autoconf::.
- 
-    If you distribute `install.sh' with your package, rename it to
- `install-sh' so `make' builtin rules won't inadvertently create a file
- called `install' from it.  `AC_PROG_INSTALL' looks for the script under
- both names, but it is best to use the new name.
- 
-    If you were using `config.h.top' or `config.h.bot', you still can,
- but you will have less clutter if you merge them into `acconfig.h'.
- *Note Invoking autoheader::.
- 
- 
- File: autoconf.info,  Node: Changed Makefiles,  Next: Changed Macros,  Prev: Changed File Names,  Up: Upgrading
- 
- Changed Makefiles
- =================
- 
-    Add `@CFLAGS@', `@CPPFLAGS@', and `@LDFLAGS@' in your `Makefile.in'
- files, so they can take advantage of the values of those variables in
- the environment when `configure' is run.  Doing this isn't necessary,
- but it's a convenience for users.
- 
-    Also add `@configure_input@' in a comment to each non-`Makefile'
- input file for `AC_OUTPUT', so that the output files will contain a
- comment saying they were produced by `configure'.  Automatically
- selecting the right comment syntax for all the kinds of files that
- people call `AC_OUTPUT' on became too much work.
- 
-    Add `config.log' and `config.cache' to the list of files you remove
- in `distclean' targets.
- 
-    If you have the following in `Makefile.in':
- 
-      prefix = /usr/local
-      exec_prefix = ${prefix}
- 
- you must change it to:
- 
-      prefix = @prefix@
-      exec_prefix = @exec_prefix@
- 
- The old behavior of replacing those variables without `@' characters
- around them has been removed.
- 
- 
- File: autoconf.info,  Node: Changed Macros,  Next: Invoking autoupdate,  Prev: Changed Makefiles,  Up: Upgrading
- 
- Changed Macros
- ==============
- 
-    Many of the macros were renamed in Autoconf version 2.  You can still
- use the old names, but the new ones are clearer, and it's easier to find
- the documentation for them.  *Note Old Macro Names::, for a table
- showing the new names for the old macros.  Use the `autoupdate' program
- to convert your `configure.in' to using the new macro names.  *Note
- Invoking autoupdate::.
- 
-    Some macros have been superseded by similar ones that do the job
- better, but are not call-compatible.  If you get warnings about calling
- obsolete macros while running `autoconf', you may safely ignore them,
- but your `configure' script will generally work better if you follow
- the advice it prints about what to replace the obsolete macros with.  In
- particular, the mechanism for reporting the results of tests has
- changed.  If you were using `echo' or `AC_VERBOSE' (perhaps via
- `AC_COMPILE_CHECK'), your `configure' script's output will look better
- if you switch to `AC_MSG_CHECKING' and `AC_MSG_RESULT'.  *Note Printing
- Messages::.  Those macros work best in conjunction with cache
- variables.  *Note Caching Results::.
- 
- 
- File: autoconf.info,  Node: Invoking autoupdate,  Next: Changed Results,  Prev: Changed Macros,  Up: Upgrading
- 
- Using `autoupdate' to Modernize `configure'
- ===========================================
- 
-    The `autoupdate' program updates a `configure.in' file that calls
- Autoconf macros by their old names to use the current macro names.  In
- version 2 of Autoconf, most of the macros were renamed to use a more
- uniform and descriptive naming scheme.  *Note Macro Names::, for a
- description of the new scheme.  Although the old names still work
- (*note Old Macro Names::., for a list of the old macro names and the
- corresponding new names), you can make your `configure.in' files more
- readable and make it easier to use the current Autoconf documentation
- if you update them to use the new macro names.
- 
-    If given no arguments, `autoupdate' updates `configure.in', backing
- up the original version with the suffix `~' (or the value of the
- environment variable `SIMPLE_BACKUP_SUFFIX', if that is set).  If you
- give `autoupdate' an argument, it reads that file instead of
- `configure.in' and writes the updated file to the standard output.
- 
- `autoupdate' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--version'
-      Print the version number of `autoupdate' and exit.
- 
- 
- File: autoconf.info,  Node: Changed Results,  Next: Changed Macro Writing,  Prev: Invoking autoupdate,  Up: Upgrading
- 
- Changed Results
- ===============
- 
-    If you were checking the results of previous tests by examining the
- shell variable `DEFS', you need to switch to checking the values of the
- cache variables for those tests.  `DEFS' no longer exists while
- `configure' is running; it is only created when generating output
- files.  This difference from version 1 is because properly quoting the
- contents of that variable turned out to be too cumbersome and
- inefficient to do every time `AC_DEFINE' is called.  *Note Cache
- Variable Names::.
- 
-    For example, here is a `configure.in' fragment written for Autoconf
- version 1:
- 
-      AC_HAVE_FUNCS(syslog)
-      case "$DEFS" in
-      *-DHAVE_SYSLOG*) ;;
-      *) # syslog is not in the default libraries.  See if it's in some other.
-        saved_LIBS="$LIBS"
-        for lib in bsd socket inet; do
-          AC_CHECKING(for syslog in -l$lib)
-          LIBS="$saved_LIBS -l$lib"
-          AC_HAVE_FUNCS(syslog)
-          case "$DEFS" in
-          *-DHAVE_SYSLOG*) break ;;
-          *) ;;
-          esac
-          LIBS="$saved_LIBS"
-        done ;;
-      esac
- 
-    Here is a way to write it for version 2:
- 
-      AC_CHECK_FUNCS(syslog)
-      if test $ac_cv_func_syslog = no; then
-        # syslog is not in the default libraries.  See if it's in some other.
-        for lib in bsd socket inet; do
-          AC_CHECK_LIB($lib, syslog, [AC_DEFINE(HAVE_SYSLOG)
-            LIBS="$LIBS $lib"; break])
-        done
-      fi
- 
-    If you were working around bugs in `AC_DEFINE_UNQUOTED' by adding
- backslashes before quotes, you need to remove them.  It now works
- predictably, and does not treat quotes (except backquotes) specially.
- *Note Setting Output Variables::.
- 
-    All of the boolean shell variables set by Autoconf macros now use
- `yes' for the true value.  Most of them use `no' for false, though for
- backward compatibility some use the empty string instead.  If you were
- relying on a shell variable being set to something like 1 or `t' for
- true, you need to change your tests.
- 
- 
- File: autoconf.info,  Node: Changed Macro Writing,  Prev: Changed Results,  Up: Upgrading
- 
- Changed Macro Writing
- =====================
- 
-    When defining your own macros, you should now use `AC_DEFUN' instead
- of `define'.  `AC_DEFUN' automatically calls `AC_PROVIDE' and ensures
- that macros called via `AC_REQUIRE' do not interrupt other macros, to
- prevent nested `checking...'  messages on the screen.  There's no
- actual harm in continuing to use the older way, but it's less
- convenient and attractive.  *Note Macro Definitions::.
- 
-    You probably looked at the macros that came with Autoconf as a guide
- for how to do things.  It would be a good idea to take a look at the new
- versions of them, as the style is somewhat improved and they take
- advantage of some new features.
- 
-    If you were doing tricky things with undocumented Autoconf internals
- (macros, variables, diversions), check whether you need to change
- anything to account for changes that have been made.  Perhaps you can
- even use an officially supported technique in version 2 instead of
- kludging.  Or perhaps not.
- 
-    To speed up your locally written feature tests, add caching to them.
- See whether any of your tests are of general enough usefulness to
- encapsulate into macros that you can share.
- 
- 
- File: autoconf.info,  Node: History,  Next: Old Macro Names,  Prev: Upgrading,  Up: Top
- 
- History of Autoconf
- *******************
- 
-    You may be wondering, Why was Autoconf originally written?  How did
- it get into its present form?  (Why does it look like gorilla spit?)  If
- you're not wondering, then this chapter contains no information useful
- to you, and you might as well skip it.  If you *are* wondering, then
- let there be light...
- 
- * Menu:
- 
- * Genesis::                     Prehistory and naming of `configure'.
- * Exodus::                      The plagues of `m4' and Perl.
- * Leviticus::                   The priestly code of portability arrives.
- * Numbers::                     Growth and contributors.
- * Deuteronomy::                 Approaching the promises of easy configuration.
- 
- 
- File: autoconf.info,  Node: Genesis,  Next: Exodus,  Prev: History,  Up: History
- 
- Genesis
- =======
- 
-    In June 1991 I was maintaining many of the GNU utilities for the Free
- Software Foundation.  As they were ported to more platforms and more
- programs were added, the number of `-D' options that users had to
- select in the `Makefile' (around 20) became burdensome.  Especially for
- me--I had to test each new release on a bunch of different systems.  So
- I wrote a little shell script to guess some of the correct settings for
- the fileutils package, and released it as part of fileutils 2.0.  That
- `configure' script worked well enough that the next month I adapted it
- (by hand) to create similar `configure' scripts for several other GNU
- utilities packages.  Brian Berliner also adapted one of my scripts for
- his CVS revision control system.
- 
-    Later that summer, I learned that Richard Stallman and Richard Pixley
- were developing similar scripts to use in the GNU compiler tools; so I
- adapted my `configure' scripts to support their evolving interface:
- using the file name `Makefile.in' as the templates; adding `+srcdir',
- the first option (of many); and creating `config.status' files.
- 
- 
- File: autoconf.info,  Node: Exodus,  Next: Leviticus,  Prev: Genesis,  Up: History
- 
- Exodus
- ======
- 
-    As I got feedback from users, I incorporated many improvements, using
- Emacs to search and replace, cut and paste, similar changes in each of
- the scripts.  As I adapted more GNU utilities packages to use
- `configure' scripts, updating them all by hand became impractical.
- Rich Murphey, the maintainer of the GNU graphics utilities, sent me mail
- saying that the `configure' scripts were great, and asking if I had a
- tool for generating them that I could send him.  No, I thought, but I
- should!  So I started to work out how to generate them.  And the
- journey from the slavery of hand-written `configure' scripts to the
- abundance and ease of Autoconf began.
- 
-    Cygnus `configure', which was being developed at around that time,
- is table driven; it is meant to deal mainly with a discrete number of
- system types with a small number of mainly unguessable features (such as
- details of the object file format).  The automatic configuration system
- that Brian Fox had developed for Bash takes a similar approach.  For
- general use, it seems to me a hopeless cause to try to maintain an
- up-to-date database of which features each variant of each operating
- system has.  It's easier and more reliable to check for most features on
- the fly--especially on hybrid systems that people have hacked on
- locally or that have patches from vendors installed.
- 
-    I considered using an architecture similar to that of Cygnus
- `configure', where there is a single `configure' script that reads
- pieces of `configure.in' when run.  But I didn't want to have to
- distribute all of the feature tests with every package, so I settled on
- having a different `configure' made from each `configure.in' by a
- preprocessor.  That approach also offered more control and flexibility.
- 
-    I looked briefly into using the Metaconfig package, by Larry Wall,
- Harlan Stenn, and Raphael Manfredi, but I decided not to for several
- reasons.  The `Configure' scripts it produces are interactive, which I
- find quite inconvenient; I didn't like the ways it checked for some
- features (such as library functions); I didn't know that it was still
- being maintained, and the `Configure' scripts I had seen didn't work on
- many modern systems (such as System V R4 and NeXT); it wasn't very
- flexible in what it could do in response to a feature's presence or
- absence; I found it confusing to learn; and it was too big and complex
- for my needs (I didn't realize then how much Autoconf would eventually
- have to grow).
- 
-    I considered using Perl to generate my style of `configure' scripts,
- but decided that `m4' was better suited to the job of simple textual
- substitutions: it gets in the way less, because output is implicit.
- Plus, everyone already has it.  (Initially I didn't rely on the GNU
- extensions to `m4'.)  Also, some of my friends at the University of
- Maryland had recently been putting `m4' front ends on several programs,
- including `tvtwm', and I was interested in trying out a new language.
- 
- 
- File: autoconf.info,  Node: Leviticus,  Next: Numbers,  Prev: Exodus,  Up: History
- 
- Leviticus
- =========
- 
-    Since my `configure' scripts determine the system's capabilities
- automatically, with no interactive user intervention, I decided to call
- the program that generates them Autoconfig.  But with a version number
- tacked on, that name would be too long for old UNIX file systems, so I
- shortened it to Autoconf.
- 
-    In the fall of 1991 I called together a group of fellow questers
- after the Holy Grail of portability (er, that is, alpha testers) to
- give me feedback as I encapsulated pieces of my handwritten scripts in
- `m4' macros and continued to add features and improve the techniques
- used in the checks.  Prominent among the testers were Franc,ois Pinard,
- who came up with the idea of making an `autoconf' shell script to run
- `m4' and check for unresolved macro calls; Richard Pixley, who
- suggested running the compiler instead of searching the file system to
- find include files and symbols, for more accurate results; Karl Berry,
- who got Autoconf to configure TeX and added the macro index to the
- documentation; and Ian Taylor, who added support for creating a C
- header file as an alternative to putting `-D' options in a `Makefile',
- so he could use Autoconf for his UUCP package.  The alpha testers
- cheerfully adjusted their files again and again as the names and
- calling conventions of the Autoconf macros changed from release to
- release.  They all contributed many specific checks, great ideas, and
- bug fixes.
- 
- 
- File: autoconf.info,  Node: Numbers,  Next: Deuteronomy,  Prev: Leviticus,  Up: History
- 
- Numbers
- =======
- 
-    In July 1992, after months of alpha testing, I released Autoconf 1.0,
- and converted many GNU packages to use it.  I was surprised by how
- positive the reaction to it was.  More people started using it than I
- could keep track of, including people working on software that wasn't
- part of the GNU Project (such as TCL, FSP, and Kerberos V5).  Autoconf
- continued to improve rapidly, as many people using the `configure'
- scripts reported problems they encountered.
- 
-    Autoconf turned out to be a good torture test for `m4'
- implementations.  UNIX `m4' started to dump core because of the length
- of the macros that Autoconf defined, and several bugs showed up in GNU
- `m4' as well.  Eventually, we realized that we needed to use some
- features that only GNU `m4' has.  4.3BSD `m4', in particular, has an
- impoverished set of builtin macros; the System V version is better, but
- still doesn't provide everything we need.
- 
-    More development occurred as people put Autoconf under more stresses
- (and to uses I hadn't anticipated).  Karl Berry added checks for X11.
- david zuhn contributed C++ support.  Franc,ois Pinard made it diagnose
- invalid arguments.  Jim Blandy bravely coerced it into configuring GNU
- Emacs, laying the groundwork for several later improvements.  Roland
- McGrath got it to configure the GNU C Library, wrote the `autoheader'
- script to automate the creation of C header file templates, and added a
- `--verbose' option to `configure'.  Noah Friedman added the
- `--macrodir' option and `AC_MACRODIR' environment variable.  (He also
- coined the term "autoconfiscate" to mean "adapt a software package to
- use Autoconf".)  Roland and Noah improved the quoting protection in
- `AC_DEFINE' and fixed many bugs, especially when I got sick of dealing
- with portability problems from February through June, 1993.
- 
- 
- File: autoconf.info,  Node: Deuteronomy,  Prev: Numbers,  Up: History
- 
- Deuteronomy
- ===========
- 
-    A long wish list for major features had accumulated, and the effect
- of several years of patching by various people had left some residual
- cruft.  In April 1994, while working for Cygnus Support, I began a major
- revision of Autoconf.  I added most of the features of the Cygnus
- `configure' that Autoconf had lacked, largely by adapting the relevant
- parts of Cygnus `configure' with the help of david zuhn and Ken
- Raeburn.  These features include support for using `config.sub',
- `config.guess', `--host', and `--target'; making links to files; and
- running `configure' scripts in subdirectories.  Adding these features
- enabled Ken to convert GNU `as', and Rob Savoye to convert DejaGNU, to
- using Autoconf.
- 
-    I added more features in response to other peoples' requests.  Many
- people had asked for `configure' scripts to share the results of the
- checks between runs, because (particularly when configuring a large
- source tree, like Cygnus does) they were frustratingly slow.  Mike
- Haertel suggested adding site-specific initialization scripts.  People
- distributing software that had to unpack on MS-DOS asked for a way to
- override the `.in' extension on the file names, which produced file
- names like `config.h.in' containing two dots.  Jim Avera did an
- extensive examination of the problems with quoting in `AC_DEFINE' and
- `AC_SUBST'; his insights led to significant improvements.  Richard
- Stallman asked that compiler output be sent to `config.log' instead of
- `/dev/null', to help people debug the Emacs `configure' script.
- 
-    I made some other changes because of my dissatisfaction with the
- quality of the program.  I made the messages showing results of the
- checks less ambiguous, always printing a result.  I regularized the
- names of the macros and cleaned up coding style inconsistencies.  I
- added some auxiliary utilities that I had developed to help convert
- source code packages to use Autoconf.  With the help of Franc,ois
- Pinard, I made the macros not interrupt each others' messages.  (That
- feature revealed some performance bottlenecks in GNU `m4', which he
- hastily corrected!)  I reorganized the documentation around problems
- people want to solve.  And I began a testsuite, because experience had
- shown that Autoconf has a pronounced tendency to regress when we change
- it.
- 
-    Again, several alpha testers gave invaluable feedback, especially
- Franc,ois Pinard, Jim Meyering, Karl Berry, Rob Savoye, Ken Raeburn,
- and Mark Eichin.
- 
-    Finally, version 2.0 was ready.  And there was much rejoicing.  (And
- I have free time again.  I think.  Yeah, right.)
- 
- 
- File: autoconf.info,  Node: Old Macro Names,  Next: Environment Variable Index,  Prev: History,  Up: Top
- 
- Old Macro Names
- ***************
- 
-    In version 2 of Autoconf, most of the macros were renamed to use a
- more uniform and descriptive naming scheme.  Here are the old names of
- the macros that were renamed, followed by the current names of those
- macros.  Although the old names are still accepted by the `autoconf'
- program for backward compatibility, the old names are considered
- obsolete.  *Note Macro Names::, for a description of the new naming
- scheme.
- 
- `AC_ALLOCA'
-      `AC_FUNC_ALLOCA'
- 
- `AC_ARG_ARRAY'
-      removed because of limited usefulness
- 
- `AC_CHAR_UNSIGNED'
-      `AC_C_CHAR_UNSIGNED'
- 
- `AC_CONST'
-      `AC_C_CONST'
- 
- `AC_CROSS_CHECK'
-      `AC_C_CROSS'
- 
- `AC_ERROR'
-      `AC_MSG_ERROR'
- 
- `AC_FIND_X'
-      `AC_PATH_X'
- 
- `AC_FIND_XTRA'
-      `AC_PATH_XTRA'
- 
- `AC_FUNC_CHECK'
-      `AC_CHECK_FUNC'
- 
- `AC_GCC_TRADITIONAL'
-      `AC_PROG_GCC_TRADITIONAL'
- 
- `AC_GETGROUPS_T'
-      `AC_TYPE_GETGROUPS'
- 
- `AC_GETLOADAVG'
-      `AC_FUNC_GETLOADAVG'
- 
- `AC_HAVE_FUNCS'
-      `AC_CHECK_FUNCS'
- 
- `AC_HAVE_HEADERS'
-      `AC_CHECK_HEADERS'
- 
- `AC_HAVE_POUNDBANG'
-      `AC_SYS_INTERPRETER' (different calling convention)
- 
- `AC_HEADER_CHECK'
-      `AC_CHECK_HEADER'
- 
- `AC_HEADER_EGREP'
-      `AC_EGREP_HEADER'
- 
- `AC_INLINE'
-      `AC_C_INLINE'
- 
- `AC_LN_S'
-      `AC_PROG_LN_S'
- 
- `AC_LONG_DOUBLE'
-      `AC_C_LONG_DOUBLE'
- 
- `AC_LONG_FILE_NAMES'
-      `AC_SYS_LONG_FILE_NAMES'
- 
- `AC_MAJOR_HEADER'
-      `AC_HEADER_MAJOR'
- 
- `AC_MINUS_C_MINUS_O'
-      `AC_PROG_CC_C_O'
- 
- `AC_MMAP'
-      `AC_FUNC_MMAP'
- 
- `AC_MODE_T'
-      `AC_TYPE_MODE_T'
- 
- `AC_OFF_T'
-      `AC_TYPE_OFF_T'
- 
- `AC_PID_T'
-      `AC_TYPE_PID_T'
- 
- `AC_PREFIX'
-      `AC_PREFIX_PROGRAM'
- 
- `AC_PROGRAMS_CHECK'
-      `AC_CHECK_PROGS'
- 
- `AC_PROGRAMS_PATH'
-      `AC_PATH_PROGS'
- 
- `AC_PROGRAM_CHECK'
-      `AC_CHECK_PROG'
- 
- `AC_PROGRAM_EGREP'
-      `AC_EGREP_CPP'
- 
- `AC_PROGRAM_PATH'
-      `AC_PATH_PROG'
- 
- `AC_REMOTE_TAPE'
-      removed because of limited usefulness
- 
- `AC_RESTARTABLE_SYSCALLS'
-      `AC_SYS_RESTARTABLE_SYSCALLS'
- 
- `AC_RETSIGTYPE'
-      `AC_TYPE_SIGNAL'
- 
- `AC_RSH'
-      removed because of limited usefulness
- 
- `AC_SETVBUF_REVERSED'
-      `AC_FUNC_SETVBUF_REVERSED'
- 
- `AC_SET_MAKE'
-      `AC_PROG_MAKE_SET'
- 
- `AC_SIZEOF_TYPE'
-      `AC_CHECK_SIZEOF'
- 
- `AC_SIZE_T'
-      `AC_TYPE_SIZE_T'
- 
- `AC_STAT_MACROS_BROKEN'
-      `AC_HEADER_STAT'
- 
- `AC_STDC_HEADERS'
-      `AC_HEADER_STDC'
- 
- `AC_STRCOLL'
-      `AC_FUNC_STRCOLL'
- 
- `AC_ST_BLKSIZE'
-      `AC_STRUCT_ST_BLKSIZE'
- 
- `AC_ST_BLOCKS'
-      `AC_STRUCT_ST_BLOCKS'
- 
- `AC_ST_RDEV'
-      `AC_STRUCT_ST_RDEV'
- 
- `AC_SYS_SIGLIST_DECLARED'
-      `AC_DECL_SYS_SIGLIST'
- 
- `AC_TEST_CPP'
-      `AC_TRY_CPP'
- 
- `AC_TEST_PROGRAM'
-      `AC_TRY_RUN'
- 
- `AC_TIMEZONE'
-      `AC_STRUCT_TIMEZONE'
- 
- `AC_TIME_WITH_SYS_TIME'
-      `AC_HEADER_TIME'
- 
- `AC_UID_T'
-      `AC_TYPE_UID_T'
- 
- `AC_UTIME_NULL'
-      `AC_FUNC_UTIME_NULL'
- 
- `AC_VFORK'
-      `AC_FUNC_VFORK'
- 
- `AC_VPRINTF'
-      `AC_FUNC_VPRINTF'
- 
- `AC_WAIT3'
-      `AC_FUNC_WAIT3'
- 
- `AC_WARN'
-      `AC_MSG_WARN'
- 
- `AC_WORDS_BIGENDIAN'
-      `AC_C_BIGENDIAN'
- 
- `AC_YYTEXT_POINTER'
-      `AC_DECL_YYTEXT'
- 
- 
- File: autoconf.info,  Node: Environment Variable Index,  Next: Output Variable Index,  Prev: Old Macro Names,  Up: Top
- 
- Environment Variable Index
- **************************
- 
-    This is an alphabetical list of the environment variables that
- Autoconf checks.
- 
- * Menu:
- 
- * AC_MACRODIR <1>:                       Invoking autoupdate.
- * AC_MACRODIR <2>:                       Invoking autoheader.
- * AC_MACRODIR <3>:                       Invoking autoreconf.
- * AC_MACRODIR <4>:                       Invoking autoconf.
- * AC_MACRODIR <5>:                       Invoking ifnames.
- * AC_MACRODIR:                           Invoking autoscan.
- * CONFIG_FILES:                          Invoking config.status.
- * CONFIG_HEADERS:                        Invoking config.status.
- * CONFIG_SHELL:                          Invoking config.status.
- * CONFIG_SITE:                           Site Defaults.
- * CONFIG_STATUS:                         Invoking config.status.
- * SIMPLE_BACKUP_SUFFIX:                  Invoking autoupdate.
- 
- 
- File: autoconf.info,  Node: Output Variable Index,  Next: Preprocessor Symbol Index,  Prev: Environment Variable Index,  Up: Top
- 
- Output Variable Index
- *********************
- 
-    This is an alphabetical list of the variables that Autoconf can
- substitute into files that it creates, typically one or more
- `Makefile's.  *Note Setting Output Variables::, for more information on
- how this is done.
- 
- * Menu:
- 
- * ALLOCA:                                Particular Functions.
- * AWK:                                   Particular Programs.
- * bindir:                                Preset Output Variables.
- * build:                                 System Type Variables.
- * build_alias:                           System Type Variables.
- * build_cpu:                             System Type Variables.
- * build_os:                              System Type Variables.
- * build_vendor:                          System Type Variables.
- * CC <1>:                                Particular Programs.
- * CC:                                    UNIX Variants.
- * CFLAGS <1>:                            Particular Programs.
- * CFLAGS:                                Preset Output Variables.
- * configure_input:                       Preset Output Variables.
- * CPP:                                   Particular Programs.
- * CPPFLAGS:                              Preset Output Variables.
- * CXX:                                   Particular Programs.
- * CXXCPP:                                Particular Programs.
- * CXXFLAGS <1>:                          Preset Output Variables.
- * CXXFLAGS:                              Particular Programs.
- * datadir:                               Preset Output Variables.
- * DEFS:                                  Preset Output Variables.
- * exec_prefix:                           Preset Output Variables.
- * EXEEXT:                                System Services.
- * F77:                                   Particular Programs.
- * FFLAGS <1>:                            Particular Programs.
- * FFLAGS:                                Preset Output Variables.
- * FLIBS:                                 Fortran 77 Compiler Characteristics.
- * host:                                  System Type Variables.
- * host_alias:                            System Type Variables.
- * host_cpu:                              System Type Variables.
- * host_os:                               System Type Variables.
- * host_vendor:                           System Type Variables.
- * includedir:                            Preset Output Variables.
- * infodir:                               Preset Output Variables.
- * INSTALL:                               Particular Programs.
- * INSTALL_DATA:                          Particular Programs.
- * INSTALL_PROGRAM:                       Particular Programs.
- * INSTALL_SCRIPT:                        Particular Programs.
- * KMEM_GROUP:                            Particular Functions.
- * LDFLAGS:                               Preset Output Variables.
- * LEX:                                   Particular Programs.
- * LEX_OUTPUT_ROOT:                       Particular Programs.
- * LEXLIB:                                Particular Programs.
- * libdir:                                Preset Output Variables.
- * libexecdir:                            Preset Output Variables.
- * LIBOBJS <1>:                           Particular Functions.
- * LIBOBJS <2>:                           Generic Functions.
- * LIBOBJS:                               Structures.
- * LIBS <1>:                              Preset Output Variables.
- * LIBS:                                  UNIX Variants.
- * LN_S:                                  Particular Programs.
- * localstatedir:                         Preset Output Variables.
- * mandir:                                Preset Output Variables.
- * NEED_SETGID:                           Particular Functions.
- * OBJEXT:                                System Services.
- * oldincludedir:                         Preset Output Variables.
- * prefix:                                Preset Output Variables.
- * program_transform_name:                Transforming Names.
- * RANLIB:                                Particular Programs.
- * sbindir:                               Preset Output Variables.
- * SET_MAKE:                              Output.
- * sharedstatedir:                        Preset Output Variables.
- * srcdir:                                Preset Output Variables.
- * subdirs:                               Subdirectories.
- * sysconfdir:                            Preset Output Variables.
- * target:                                System Type Variables.
- * target_alias:                          System Type Variables.
- * target_cpu:                            System Type Variables.
- * target_os:                             System Type Variables.
- * target_vendor:                         System Type Variables.
- * top_srcdir:                            Preset Output Variables.
- * X_CFLAGS:                              System Services.
- * X_EXTRA_LIBS:                          System Services.
- * X_LIBS:                                System Services.
- * X_PRE_LIBS:                            System Services.
- * YACC:                                  Particular Programs.
- 
- 
- File: autoconf.info,  Node: Preprocessor Symbol Index,  Next: Macro Index,  Prev: Output Variable Index,  Up: Top
- 
- Preprocessor Symbol Index
- *************************
- 
-    This is an alphabetical list of the C preprocessor symbols that the
- Autoconf macros define.  To work with Autoconf, C source code needs to
- use these names in `#if' directives.
- 
- * Menu:
- 
- * __CHAR_UNSIGNED__:                     C Compiler Characteristics.
- * _ALL_SOURCE:                           UNIX Variants.
- * _MINIX:                                UNIX Variants.
- * _POSIX_1_SOURCE:                       UNIX Variants.
- * _POSIX_SOURCE:                         UNIX Variants.
- * _POSIX_VERSION:                        Particular Headers.
- * C_ALLOCA:                              Particular Functions.
- * CLOSEDIR_VOID:                         Particular Functions.
- * const:                                 C Compiler Characteristics.
- * DGUX:                                  Particular Functions.
- * DIRENT:                                Particular Headers.
- * F77_NO_MINUS_C_MINUS_O:                Particular Programs.
- * GETGROUPS_T:                           Particular Typedefs.
- * GETLODAVG_PRIVILEGED:                  Particular Functions.
- * GETPGRP_VOID:                          Particular Functions.
- * gid_t:                                 Particular Typedefs.
- * HAVE_ALLOCA_H:                         Particular Functions.
- * HAVE_CONFIG_H:                         Configuration Headers.
- * HAVE_DIRENT_H:                         Particular Headers.
- * HAVE_DOPRNT:                           Particular Functions.
- * HAVE_FUNCTION:                         Generic Functions.
- * HAVE_GETMNTENT:                        Particular Functions.
- * HAVE_HEADER:                           Generic Headers.
- * HAVE_LONG_DOUBLE:                      C Compiler Characteristics.
- * HAVE_LONG_FILE_NAMES:                  System Services.
- * HAVE_MMAP:                             Particular Functions.
- * HAVE_NDIR_H:                           Particular Headers.
- * HAVE_RESTARTABLE_SYSCALLS:             System Services.
- * HAVE_ST_BLKSIZE:                       Structures.
- * HAVE_ST_BLOCKS:                        Structures.
- * HAVE_ST_RDEV:                          Structures.
- * HAVE_STRCOLL:                          Particular Functions.
- * HAVE_STRFTIME:                         Particular Functions.
- * HAVE_STRINGIZE:                        C Compiler Characteristics.
- * HAVE_SYS_DIR_H:                        Particular Headers.
- * HAVE_SYS_NDIR_H:                       Particular Headers.
- * HAVE_SYS_WAIT_H:                       Particular Headers.
- * HAVE_TM_ZONE:                          Structures.
- * HAVE_TZNAME:                           Structures.
- * HAVE_UNISTD_H:                         Particular Headers.
- * HAVE_UTIME_NULL:                       Particular Functions.
- * HAVE_VFORK_H:                          Particular Functions.
- * HAVE_VPRINTF:                          Particular Functions.
- * HAVE_WAIT3:                            Particular Functions.
- * inline:                                C Compiler Characteristics.
- * INT_16_BITS:                           C Compiler Characteristics.
- * LONG_64_BITS:                          C Compiler Characteristics.
- * MAJOR_IN_MKDEV:                        Particular Headers.
- * MAJOR_IN_SYSMACROS:                    Particular Headers.
- * mode_t:                                Particular Typedefs.
- * NDIR:                                  Particular Headers.
- * NEED_MEMORY_H:                         Particular Headers.
- * NEED_SETGID:                           Particular Functions.
- * NLIST_NAME_UNION:                      Particular Functions.
- * NLIST_STRUCT:                          Particular Functions.
- * NO_MINUS_C_MINUS_O:                    Particular Programs.
- * off_t:                                 Particular Typedefs.
- * pid_t:                                 Particular Typedefs.
- * RETSIGTYPE:                            Particular Typedefs.
- * SELECT_TYPE_ARG1:                      Particular Functions.
- * SELECT_TYPE_ARG234:                    Particular Functions.
- * SELECT_TYPE_ARG5:                      Particular Functions.
- * SETPGRP_VOID:                          Particular Functions.
- * SETVBUF_REVERSED:                      Particular Functions.
- * size_t:                                Particular Typedefs.
- * STDC_HEADERS:                          Particular Headers.
- * SVR4:                                  Particular Functions.
- * SYS_SIGLIST_DECLARED:                  Particular Headers.
- * SYSDIR:                                Particular Headers.
- * SYSNDIR:                               Particular Headers.
- * TIME_WITH_SYS_TIME:                    Structures.
- * TM_IN_SYS_TIME:                        Structures.
- * uid_t:                                 Particular Typedefs.
- * UMAX:                                  Particular Functions.
- * UMAX4_3:                               Particular Functions.
- * USG:                                   Particular Headers.
- * vfork:                                 Particular Functions.
- * VOID_CLOSEDIR:                         Particular Headers.
- * WORDS_BIGENDIAN:                       C Compiler Characteristics.
- * YYTEXT_POINTER:                        Particular Programs.
- 
- 
- File: autoconf.info,  Node: Macro Index,  Prev: Preprocessor Symbol Index,  Up: Top
- 
- Macro Index
- ***********
- 
-    This is an alphabetical list of the Autoconf macros.  To make the
- list easier to use, the macros are listed without their preceding `AC_'.
- 
- * Menu:
- 
- * AIX:                                   UNIX Variants.
- * ALLOCA:                                Old Macro Names.
- * ARG_ARRAY:                             Old Macro Names.
- * ARG_ENABLE:                            Package Options.
- * ARG_PROGRAM:                           Transforming Names.
- * ARG_WITH:                              External Software.
- * BEFORE:                                Suggested Ordering.
- * C_BIGENDIAN:                           C Compiler Characteristics.
- * C_CHAR_UNSIGNED:                       C Compiler Characteristics.
- * C_CONST:                               C Compiler Characteristics.
- * C_CROSS:                               Test Programs.
- * C_INLINE:                              C Compiler Characteristics.
- * C_LONG_DOUBLE:                         C Compiler Characteristics.
- * C_STRINGIZE:                           C Compiler Characteristics.
- * CACHE_CHECK:                           Caching Results.
- * CACHE_LOAD:                            Caching Results.
- * CACHE_SAVE:                            Caching Results.
- * CACHE_VAL:                             Caching Results.
- * CANONICAL_HOST:                        Canonicalizing.
- * CANONICAL_SYSTEM:                      Canonicalizing.
- * CHAR_UNSIGNED:                         Old Macro Names.
- * CHECK_FILE:                            Generic Programs.
- * CHECK_FILES:                           Generic Programs.
- * CHECK_FUNC:                            Generic Functions.
- * CHECK_FUNCS:                           Generic Functions.
- * CHECK_HEADER:                          Generic Headers.
- * CHECK_HEADERS:                         Generic Headers.
- * CHECK_LIB:                             Libraries.
- * CHECK_PROG:                            Generic Programs.
- * CHECK_PROGS:                           Generic Programs.
- * CHECK_SIZEOF:                          C Compiler Characteristics.
- * CHECK_TOOL:                            Generic Programs.
- * CHECK_TYPE:                            Generic Typedefs.
- * CHECKING:                              Printing Messages.
- * COMPILE_CHECK:                         Examining Libraries.
- * CONFIG_AUX_DIR:                        Input.
- * CONFIG_HEADER:                         Configuration Headers.
- * CONFIG_SUBDIRS:                        Subdirectories.
- * CONST:                                 Old Macro Names.
- * CROSS_CHECK:                           Old Macro Names.
- * CYGWIN:                                System Services.
- * DECL_SYS_SIGLIST:                      Particular Headers.
- * DECL_YYTEXT:                           Particular Programs.
- * DEFINE:                                Defining Symbols.
- * DEFINE_UNQUOTED:                       Defining Symbols.
- * DEFUN:                                 Macro Definitions.
- * DIR_HEADER:                            Particular Headers.
- * DYNIX_SEQ:                             UNIX Variants.
- * EGREP_CPP:                             Examining Declarations.
- * EGREP_HEADER:                          Examining Declarations.
- * ENABLE:                                Package Options.
- * ERROR:                                 Old Macro Names.
- * EXEEXT:                                System Services.
- * F77_LIBRARY_LDFLAGS:                   Fortran 77 Compiler Characteristics.
- * FIND_X:                                Old Macro Names.
- * FIND_XTRA:                             Old Macro Names.
- * FUNC_ALLOCA:                           Particular Functions.
- * FUNC_CHECK:                            Old Macro Names.
- * FUNC_CLOSEDIR_VOID:                    Particular Functions.
- * FUNC_FNMATCH:                          Particular Functions.
- * FUNC_GETLOADAVG:                       Particular Functions.
- * FUNC_GETMNTENT:                        Particular Functions.
- * FUNC_GETPGRP:                          Particular Functions.
- * FUNC_MEMCMP:                           Particular Functions.
- * FUNC_MMAP:                             Particular Functions.
- * FUNC_SELECT_ARGTYPES:                  Particular Functions.
- * FUNC_SETPGRP:                          Particular Functions.
- * FUNC_SETVBUF_REVERSED:                 Particular Functions.
- * FUNC_STRCOLL:                          Particular Functions.
- * FUNC_STRFTIME:                         Particular Functions.
- * FUNC_UTIME_NULL:                       Particular Functions.
- * FUNC_VFORK:                            Particular Functions.
- * FUNC_VPRINTF:                          Particular Functions.
- * FUNC_WAIT3:                            Particular Functions.
- * GCC_TRADITIONAL:                       Old Macro Names.
- * GETGROUPS_T:                           Old Macro Names.
- * GETLOADAVG:                            Old Macro Names.
- * HAVE_FUNCS:                            Old Macro Names.
- * HAVE_HEADERS:                          Old Macro Names.
- * HAVE_LIBRARY:                          Libraries.
- * HAVE_POUNDBANG:                        Old Macro Names.
- * HEADER_CHECK:                          Old Macro Names.
- * HEADER_DIRENT:                         Particular Headers.
- * HEADER_EGREP:                          Old Macro Names.
- * HEADER_MAJOR:                          Particular Headers.
- * HEADER_STAT:                           Structures.
- * HEADER_STDC:                           Particular Headers.
- * HEADER_SYS_WAIT:                       Particular Headers.
- * HEADER_TIME:                           Structures.
- * INIT:                                  Input.
- * INLINE:                                Old Macro Names.
- * INT_16_BITS:                           C Compiler Characteristics.
- * IRIX_SUN:                              UNIX Variants.
- * ISC_POSIX:                             UNIX Variants.
- * LANG_C:                                Language Choice.
- * LANG_CPLUSPLUS:                        Language Choice.
- * LANG_FORTRAN77:                        Language Choice.
- * LANG_RESTORE:                          Language Choice.
- * LANG_SAVE:                             Language Choice.
- * LINK_FILES:                            Using System Type.
- * LN_S:                                  Old Macro Names.
- * LONG_64_BITS:                          C Compiler Characteristics.
- * LONG_DOUBLE:                           Old Macro Names.
- * LONG_FILE_NAMES:                       Old Macro Names.
- * MAJOR_HEADER:                          Old Macro Names.
- * MEMORY_H:                              Particular Headers.
- * MINGW32:                               System Services.
- * MINIX:                                 UNIX Variants.
- * MINUS_C_MINUS_O:                       Old Macro Names.
- * MMAP:                                  Old Macro Names.
- * MODE_T:                                Old Macro Names.
- * MSG_CHECKING:                          Printing Messages.
- * MSG_ERROR:                             Printing Messages.
- * MSG_RESULT:                            Printing Messages.
- * MSG_WARN:                              Printing Messages.
- * OBJEXT:                                System Services.
- * OBSOLETE:                              Obsolete Macros.
- * OFF_T:                                 Old Macro Names.
- * OUTPUT:                                Output.
- * PATH_PROG:                             Generic Programs.
- * PATH_PROGS:                            Generic Programs.
- * PATH_X:                                System Services.
- * PATH_XTRA:                             System Services.
- * PID_T:                                 Old Macro Names.
- * PREFIX:                                Old Macro Names.
- * PREFIX_PROGRAM:                        Default Prefix.
- * PREREQ:                                Versions.
- * PROG_AWK:                              Particular Programs.
- * PROG_CC:                               Particular Programs.
- * PROG_CC_C_O:                           Particular Programs.
- * PROG_CPP:                              Particular Programs.
- * PROG_CXX:                              Particular Programs.
- * PROG_CXXCPP:                           Particular Programs.
- * PROG_F77_C_O:                          Particular Programs.
- * PROG_FORTRAN:                          Particular Programs.
- * PROG_GCC_TRADITIONAL:                  Particular Programs.
- * PROG_INSTALL:                          Particular Programs.
- * PROG_LEX:                              Particular Programs.
- * PROG_LN_S:                             Particular Programs.
- * PROG_MAKE_SET:                         Output.
- * PROG_RANLIB:                           Particular Programs.
- * PROG_YACC:                             Particular Programs.
- * PROGRAM_CHECK:                         Old Macro Names.
- * PROGRAM_EGREP:                         Old Macro Names.
- * PROGRAM_PATH:                          Old Macro Names.
- * PROGRAMS_CHECK:                        Old Macro Names.
- * PROGRAMS_PATH:                         Old Macro Names.
- * PROVIDE:                               Prerequisite Macros.
- * REMOTE_TAPE:                           Old Macro Names.
- * REPLACE_FUNCS:                         Generic Functions.
- * REQUIRE:                               Prerequisite Macros.
- * REQUIRE_CPP:                           Language Choice.
- * RESTARTABLE_SYSCALLS:                  Old Macro Names.
- * RETSIGTYPE:                            Old Macro Names.
- * REVISION:                              Versions.
- * RSH:                                   Old Macro Names.
- * SCO_INTL:                              UNIX Variants.
- * SEARCH_LIBS:                           Libraries.
- * SET_MAKE:                              Old Macro Names.
- * SETVBUF_REVERSED:                      Old Macro Names.
- * SIZE_T:                                Old Macro Names.
- * SIZEOF_TYPE:                           Old Macro Names.
- * ST_BLKSIZE:                            Old Macro Names.
- * ST_BLOCKS:                             Old Macro Names.
- * ST_RDEV:                               Old Macro Names.
- * STAT_MACROS_BROKEN <1>:                Structures.
- * STAT_MACROS_BROKEN:                    Old Macro Names.
- * STDC_HEADERS:                          Old Macro Names.
- * STRCOLL:                               Old Macro Names.
- * STRUCT_ST_BLKSIZE:                     Structures.
- * STRUCT_ST_BLOCKS:                      Structures.
- * STRUCT_ST_RDEV:                        Structures.
- * STRUCT_TIMEZONE:                       Structures.
- * STRUCT_TM:                             Structures.
- * SUBST:                                 Setting Output Variables.
- * SUBST_FILE:                            Setting Output Variables.
- * SYS_INTERPRETER:                       System Services.
- * SYS_LONG_FILE_NAMES:                   System Services.
- * SYS_RESTARTABLE_SYSCALLS:              System Services.
- * SYS_SIGLIST_DECLARED:                  Old Macro Names.
- * TEST_CPP:                              Old Macro Names.
- * TEST_PROGRAM:                          Old Macro Names.
- * TIME_WITH_SYS_TIME:                    Old Macro Names.
- * TIMEZONE:                              Old Macro Names.
- * TRY_COMPILE:                           Examining Syntax.
- * TRY_CPP:                               Examining Declarations.
- * TRY_LINK:                              Examining Libraries.
- * TRY_LINK_FUNC:                         Examining Libraries.
- * TRY_RUN:                               Test Programs.
- * TYPE_GETGROUPS:                        Particular Typedefs.
- * TYPE_MODE_T:                           Particular Typedefs.
- * TYPE_OFF_T:                            Particular Typedefs.
- * TYPE_PID_T:                            Particular Typedefs.
- * TYPE_SIGNAL:                           Particular Typedefs.
- * TYPE_SIZE_T:                           Particular Typedefs.
- * TYPE_UID_T:                            Particular Typedefs.
- * UID_T:                                 Old Macro Names.
- * UNISTD_H:                              Particular Headers.
- * USG:                                   Particular Headers.
- * UTIME_NULL:                            Old Macro Names.
- * VALIDATE_CACHED_SYSTEM_TUPLE:          Canonicalizing.
- * VERBOSE:                               Printing Messages.
- * VFORK:                                 Old Macro Names.
- * VPRINTF:                               Old Macro Names.
- * WAIT3:                                 Old Macro Names.
- * WARN:                                  Old Macro Names.
- * WITH:                                  External Software.
- * WORDS_BIGENDIAN:                       Old Macro Names.
- * XENIX_DIR:                             UNIX Variants.
- * YYTEXT_POINTER:                        Old Macro Names.
- 
- 
- 
- Tag Table:
- Node: Top1187
- Node: Introduction9689
- Node: Making configure Scripts13529
- Node: Writing configure.in16610
- Node: Invoking autoscan20343
- Node: Invoking ifnames22648
- Node: Invoking autoconf24138
- Node: Invoking autoreconf25976
- Node: Setup28812
- Node: Input29717
- Node: Output31454
- Node: Makefile Substitutions35092
- Node: Preset Output Variables36695
- Node: Build Directories41564
- Node: Automatic Remaking43197
- Node: Configuration Headers45283
- Node: Header Templates47797
- Node: Invoking autoheader49006
- Node: Subdirectories52154
- Node: Default Prefix53549
- Node: Versions54953
- Node: Existing Tests56857
- Node: Alternative Programs58405
- Node: Particular Programs59092
- Node: Generic Programs67144
- Node: Libraries70450
- Node: Library Functions73524
- Node: Particular Functions74082
- Node: Generic Functions81276
- Node: Header Files83380
- Node: Particular Headers83939
- Node: Generic Headers90931
- Node: Structures92233
- Node: Typedefs94470
- Node: Particular Typedefs94976
- Node: Generic Typedefs96193
- Node: C Compiler Characteristics96650
- Node: Fortran 77 Compiler Characteristics99521
- Node: System Services101224
- Node: UNIX Variants104360
- Node: Writing Tests106379
- Node: Examining Declarations108372
- Node: Examining Syntax110864
- Node: Examining Libraries112309
- Node: Run Time116019
- Node: Test Programs117007
- Node: Guidelines119335
- Node: Test Functions120524
- Node: Portable Shell122067
- Node: Testing Values and Files123999
- Node: Multiple Cases125654
- Node: Language Choice126852
- Node: Results128954
- Node: Defining Symbols129716
- Node: Setting Output Variables133012
- Node: Caching Results134858
- Node: Cache Variable Names137604
- Node: Cache Files139088
- Node: Printing Messages141925
- Node: Writing Macros145373
- Node: Macro Definitions146020
- Node: Macro Names147148
- Node: Quoting149599
- Node: Dependencies Between Macros151501
- Node: Prerequisite Macros152148
- Node: Suggested Ordering153639
- Node: Obsolete Macros155169
- Node: Manual Configuration156393
- Node: Specifying Names157292
- Node: Canonicalizing159193
- Node: System Type Variables160705
- Node: Using System Type161452
- Node: Site Configuration162946
- Node: External Software163719
- Node: Package Options166922
- Node: Site Details169669
- Node: Transforming Names170892
- Node: Transformation Options172070
- Node: Transformation Examples172563
- Node: Transformation Rules174131
- Node: Site Defaults175540
- Node: Invoking configure179446
- Node: Basic Installation180395
- Node: Compilers and Options182975
- Node: Multiple Architectures183624
- Node: Installation Names184610
- Node: Optional Features185794
- Node: System Type186564
- Node: Sharing Defaults187586
- Node: Operation Controls188210
- Node: Invoking config.status189196
- Node: Questions192584
- Node: Distributing193116
- Node: Why GNU m4194260
- Node: Bootstrapping195073
- Node: Why Not Imake195689
- Node: Upgrading200098
- Node: Changed File Names201619
- Node: Changed Makefiles202373
- Node: Changed Macros203469
- Node: Invoking autoupdate204716
- Node: Changed Results206307
- Node: Changed Macro Writing208409
- Node: History209673
- Node: Genesis210465
- Node: Exodus211654
- Node: Leviticus214703
- Node: Numbers216226
- Node: Deuteronomy218142
- Node: Old Macro Names220807
- Node: Environment Variable Index223856
- Node: Output Variable Index224870
- Node: Preprocessor Symbol Index230068
- Node: Macro Index235354
- 
- End Tag Table
--- 0 ----
Index: krb5/util/autoconf/autoconf.info-1
diff -c krb5/util/autoconf/autoconf.info-1:1.1.1.1 krb5/util/autoconf/autoconf.info-1:removed
*** krb5/util/autoconf/autoconf.info-1:1.1.1.1	Mon Jun  2 17:58:28 1997
--- krb5/util/autoconf/autoconf.info-1	Sun Mar 16 20:22:40 2003
***************
*** 1,1158 ****
- This is Info file autoconf.info, produced by Makeinfo-1.55 from the
- input file autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Top,  Next: Introduction,  Up: (dir)
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.  This is edition 2.3, for Autoconf version 2.3.
- 
- * Menu:
- 
- * Introduction::                Autoconf's purpose, strengths, and weaknesses.
- * Making configure Scripts::    How to organize and produce Autoconf scripts.
- * Setup::                       Initialization and output.
- * Existing Tests::              Macros that check for particular features.
- * Writing Tests::               How to write new feature checks.
- * Results::                     What to do with results from feature checks.
- * Writing Macros::              Adding new macros to Autoconf.
- * Manual Configuration::        Selecting features that can't be guessed.
- * Site Configuration::          Local defaults for `configure'.
- * Invoking configure::          How to use the Autoconf output.
- * Invoking config.status::      Recreating a configuration.
- * Questions::                   Questions about Autoconf, with answers.
- * Upgrading::                   Tips for upgrading from version 1.
- * History::                     History of Autoconf.
- * Old Macro Names::		Backward compatibility macros.
- * Environment Variable Index::  Index of environment variables used.
- * Output Variable Index::       Index of variables set in output files.
- * Preprocessor Symbol Index::   Index of C preprocessor symbols defined.
- * Macro Index::                 Index of Autoconf macros.
- 
-  -- The Detailed Node Listing --
- 
- Making `configure' Scripts
- 
- * Writing configure.in::	What to put in an Autoconf input file.
- * Invoking autoscan::           Semi-automatic `configure.in' writing.
- * Invoking ifnames::            Listing the conditionals in source code.
- * Invoking autoconf::		How to create configuration scripts.
- * Invoking autoreconf::         Remaking multiple `configure' scripts.
- 
- Initialization and Output Files
- 
- * Input::                       Where Autoconf should find files.
- * Output::			Creating output files.
- * Makefile Substitutions::      Using output variables in `Makefile's.
- * Configuration Headers::       Creating a configuration header file.
- * Subdirectories::              Configuring independent packages together.
- * Default Prefix::              Changing the default installation prefix.
- * Versions::                    Version numbers in `configure'.
- 
- Substitutions in Makefiles
- 
- * Preset Output Variables::	Output variables that are always set.
- * Build Directories::   	Supporting multiple concurrent compiles.
- * Automatic Remaking::		Makefile rules for configuring.
- 
- Configuration Header Files
- 
- * Header Templates::            Input for the configuration headers.
- * Invoking autoheader::		How to create configuration templates.
- 
- Existing Tests
- 
- * Alternative Programs::	Selecting between alternative programs.
- * Libraries::                   Library archives that might be missing.
- * Library Functions::		C library functions that might be missing.
- * Header Files::		Header files that might be missing.
- * Structures::			Structures or members that might be missing.
- * Typedefs::			`typedef's that might be missing.
- * Compiler Characteristics::	C compiler or machine architecture features.
- * System Services::		Operating system services.
- * UNIX Variants::		Special kludges for specific UNIX variants.
- 
- Alternative Programs
- 
- * Particular Programs::         Special handling to find certain programs.
- * Generic Programs::            How to find other programs.
- 
- Library Functions
- 
- * Particular Functions::        Special handling to find certain functions.
- * Generic Functions::           How to find other functions.
- 
- Header Files
- 
- * Particular Headers::          Special handling to find certain headers.
- * Generic Headers::             How to find other headers.
- 
- Typedefs
- 
- * Particular Typedefs::         Special handling to find certain types.
- * Generic Typedefs::            How to find other types.
- 
- Writing Tests
- 
- * Examining Declarations::	Detecting header files and declarations.
- * Examining Syntax::            Detecting language syntax features.
- * Examining Libraries::         Detecting functions and global variables.
- * Run Time::		        Testing for run-time features.
- * Portable Shell::              Shell script portability pitfalls.
- * Testing Values and Files::    Checking strings and files.
- * Multiple Cases::		Tests for several possible values.
- * Language Choice::             Selecting which language to use for testing.
- 
- Checking Run Time Behavior
- 
- * Test Programs::               Running test programs.
- * Guidelines::			General rules for writing test programs.
- * Test Functions::		Avoiding pitfalls in test programs.
- 
- Results of Tests
- 
- * Defining Symbols::            Defining C preprocessor symbols.
- * Setting Output Variables::	Replacing variables in output files.
- * Caching Results::             Speeding up subsequent `configure' runs.
- * Printing Messages::           Notifying users of progress or problems.
- 
- Caching Results
- 
- * Cache Variable Names::        Shell variables used in caches.
- * Cache Files::	        	Files `configure' uses for caching.
- 
- Writing Macros
- 
- * Macro Definitions::		Basic format of an Autoconf macro.
- * Macro Names::                 What to call your new macros.
- * Quoting::			Protecting macros from unwanted expansion.
- * Dependencies Between Macros::	What to do when macros depend on other macros.
- 
- Dependencies Between Macros
- 
- * Prerequisite Macros::		Ensuring required information.
- * Suggested Ordering::		Warning about possible ordering problems.
- * Obsolete Macros::             Warning about old ways of doing things.
- 
- Manual Configuration
- 
- * Specifying Names::            Specifying the system type.
- * Canonicalizing::              Getting the canonical system type.
- * System Type Variables::       Variables containing the system type.
- * Using System Type::           What to do with the system type.
- 
- Site Configuration
- 
- * External Software::           Working with other optional software.
- * Package Options::             Selecting optional features.
- * Site Details::                Configuring site details.
- * Transforming Names::          Changing program names when installing.
- * Site Defaults::               Giving `configure' local defaults.
- 
- Transforming Program Names When Installing
- 
- * Transformation Options::      `configure' options to transform names.
- * Transformation Examples::     Sample uses of transforming names.
- * Transformation Rules::        `Makefile' uses of transforming names.
- 
- Running `configure' Scripts
- 
- * Basic Installation::          Instructions for typical cases.
- * Compilers and Options::       Selecting compilers and optimization.
- * Multiple Architectures::      Compiling for multiple architectures at once.
- * Installation Names::          Installing in different directories.
- * Optional Features::           Selecting optional features.
- * System Type::                 Specifying the system type.
- * Sharing Defaults::            Setting site-wide defaults for `configure'.
- * Operation Controls::          Changing how `configure' runs.
- 
- Questions About Autoconf
- 
- * Distributing::                Distributing `configure' scripts.
- * Why GNU m4::                  Why not use the standard `m4'?
- * Bootstrapping::               Autoconf and GNU `m4' require each other?
- * Why Not Imake::               Why GNU uses `configure' instead of Imake.
- 
- Upgrading From Version 1
- 
- * Changed File Names::          Files you might rename.
- * Changed Makefiles::           New things to put in `Makefile.in'.
- * Changed Macros::              Macro calls you might replace.
- * Invoking autoupdate::         Replacing old macro names in `configure.in'.
- * Changed Results::             Changes in how to check test results.
- * Changed Macro Writing::       Better ways to write your own macros.
- 
- History of Autoconf
- 
- * Genesis::			Prehistory and naming of `configure'.
- * Exodus::			The plagues of `m4' and Perl.
- * Leviticus::			The priestly code of portability arrives.
- * Numbers::			Growth and contributors.
- * Deuteronomy::			Approaching the promises of easy configuration.
- 
- 
- File: autoconf.info,  Node: Introduction,  Next: Making configure Scripts,  Prev: Top,  Up: Top
- 
- Introduction
- ************
- 
-      A physicist, an engineer, and a computer scientist were
-      discussing the nature of God.  Surely a Physicist, said the
-      physicist, because early in the Creation, God made Light; and you
-      know, Maxwell's equations, the dual nature of electro-magnetic
-      waves, the relativist consequences... An Engineer!, said the
-      engineer, because before making Light, God split the Chaos into
-      Land and Water; it takes a hell of an engineer to handle that big
-      amount of mud, and orderly separation of solids from
-      liquids... The computer scientist shouted: And the Chaos,
-      where do you think it was coming from, hmm?
-      
-      ---Anonymous
- 
-    Autoconf is a tool for producing shell scripts that automatically
- configure software source code packages to adapt to many kinds of
- UNIX-like systems.  The configuration scripts produced by Autoconf are
- independent of Autoconf when they are run, so their users do not need to
- have Autoconf.
- 
-    The configuration scripts produced by Autoconf require no manual user
- intervention when run; they do not normally even need an argument
- specifying the system type.  Instead, they test for the presence of each
- feature that the software package they are for might need individually.
- (Before each check, they print a one-line message stating what they are
- checking for, so the user doesn't get too bored while waiting for the
- script to finish.)  As a result, they deal well with systems that are
- hybrids or customized from the more common UNIX variants.  There is no
- need to maintain files that list the features supported by each release
- of each variant of UNIX.
- 
-    For each software package that Autoconf is used with, it creates a
- configuration script from a template file that lists the system
- features that the package needs or can use.  After the shell code to
- recognize and respond to a system feature has been written, Autoconf
- allows it to be shared by many software packages that can use (or need)
- that feature.  If it later turns out that the shell code needs
- adjustment for some reason, it needs to be changed in only one place;
- all of the configuration scripts can be regenerated automatically to
- take advantage of the updated code.
- 
-    The Metaconfig package is similar in purpose to Autoconf, but the
- scripts it produces require manual user intervention, which is quite
- inconvenient when configuring large source trees.  Unlike Metaconfig
- scripts, Autoconf scripts can support cross-compiling, if some care is
- taken in writing them.
- 
-    There are several jobs related to making portable software packages
- that Autoconf currently does not do.  Among these are automatically
- creating `Makefile' files with all of the standard targets, and
- supplying replacements for standard library functions and header files
- on systems that lack them.  Work is in progress to add those features in
- the future.
- 
-    Autoconf imposes some restrictions on the names of macros used with
- `#ifdef' in C programs (*note Preprocessor Symbol Index::.).
- 
-    Autoconf requires GNU `m4' in order to generate the scripts.  It
- uses features that some UNIX versions of `m4' do not have.  It also
- overflows internal limits of some versions of `m4', including GNU `m4'
- 1.0.  You must use version 1.1 or later of GNU `m4'.  Using version 1.3
- or later will be much faster than 1.1 or 1.2.
- 
-    *Note Upgrading::, for information about upgrading from version 1.
- *Note History::, for the story of Autoconf's development.  *Note
- Questions::, for answers to some common questions about Autoconf.
- 
-    Mail suggestions and bug reports for Autoconf to
- `bug-gnu-utils@prep.ai.mit.edu'.  Please include the Autoconf version
- number, which you can get by running `autoconf --version'.
- 
- 
- File: autoconf.info,  Node: Making configure Scripts,  Next: Setup,  Prev: Introduction,  Up: Top
- 
- Making `configure' Scripts
- **************************
- 
-    The configuration scripts that Autoconf produces are by convention
- called `configure'.  When run, `configure' creates several files,
- replacing configuration parameters in them with appropriate values.
- The files that `configure' creates are:
- 
-    * one or more `Makefile' files, one in each subdirectory of the
-      package (*note Makefile Substitutions::.);
- 
-    * optionally, a C header file, the name of which is configurable,
-      containing `#define' directives (*note Configuration Headers::.);
- 
-    * a shell script called `config.status' that, when run, will recreate
-      the files listed above (*note Invoking config.status::.);
- 
-    * a shell script called `config.cache' that saves the results of
-      running many of the tests (*note Cache Files::.);
- 
-    * a file called `config.log' containing any messages produced by
-      compilers, to help debugging if `configure' makes a mistake.
- 
-    To create a `configure' script with Autoconf, you need to write an
- Autoconf input file `configure.in' and run `autoconf' on it.  If you
- write your own feature tests to supplement those that come with
- Autoconf, you might also write files called `aclocal.m4' and
- `acsite.m4'.  If you use a C header file to contain `#define'
- directives, you might also write `acconfig.h', and you will distribute
- the Autoconf-generated file `config.h.in' with the package.
- 
-    Here is a diagram showing how the files that can be used in
- configuration are produced.  Programs that are executed are suffixed by
- `*'.  Optional files are enclosed in square brackets (`[]').
- `autoconf' and `autoheader' also read the installed Autoconf macro
- files (by reading `autoconf.m4').
- 
- Files used in preparing a software package for distribution:
-      your source files --> [autoscan*] --> [configure.scan] --> configure.in
-      
-      configure.in --.   .------> autoconf* -----> configure
-                     +---+
-      [aclocal.m4] --+   `---.
-      [acsite.m4] ---'       |
-                             +--> [autoheader*] -> [config.h.in]
-      [acconfig.h] ----.     |
-                       +-----'
-      [config.h.top] --+
-      [config.h.bot] --'
-      
-      Makefile.in -------------------------------> Makefile.in
- 
- Files used in configuring a software package:
-                             .-------------> config.cache
-      configure* ------------+-------------> config.log
-                             |
-      [config.h.in] -.       v            .-> [config.h] -.
-                     +--> config.status* -+               +--> make*
-      Makefile.in ---'                    `-> Makefile ---'
- 
- * Menu:
- 
- * Writing configure.in::	What to put in an Autoconf input file.
- * Invoking autoscan::           Semi-automatic `configure.in' writing.
- * Invoking ifnames::            Listing the conditionals in source code.
- * Invoking autoconf::		How to create configuration scripts.
- * Invoking autoreconf::         Remaking multiple `configure' scripts.
- 
- 
- File: autoconf.info,  Node: Writing configure.in,  Next: Invoking autoscan,  Up: Making configure Scripts
- 
- Writing `configure.in'
- ======================
- 
-    To produce a `configure' script for a software package, create a
- file called `configure.in' that contains invocations of the Autoconf
- macros that test the system features your package needs or can use.
- Autoconf macros already exist to check for many features; see *Note
- Existing Tests::, for their descriptions.  For most other features, you
- can use Autoconf template macros to produce custom checks; see *Note
- Writing Tests::, for information about them.  For especially tricky or
- specialized features, `configure.in' might need to contain some
- hand-crafted shell commands.  The `autoscan' program can give you a
- good start in writing `configure.in' (*note Invoking autoscan::., for
- more information).
- 
-    The order in which `configure.in' calls the Autoconf macros is not
- important, with a few exceptions.  Every `configure.in' must contain a
- call to `AC_INIT' before the checks, and a call to `AC_OUTPUT' at the
- end (*note Output::.).  Additionally, some macros rely on other macros
- having been called first, because they check previously set values of
- some variables to decide what to do.  These macros are noted in the
- individual descriptions (*note Existing Tests::.), and they also warn
- you when creating `configure' if they are called out of order.
- 
-    To encourage consistency, here is a suggested order for calling the
- Autoconf macros.  Generally speaking, the things near the end of this
- list could depend on things earlier in it.  For example, library
- functions could be affected by typedefs and libraries.
- 
-      `AC_INIT(FILE)'
-      checks for programs
-      checks for libraries
-      checks for header files
-      checks for typedefs
-      checks for structures
-      checks for compiler characteristics
-      checks for library functions
-      checks for system services
-      `AC_OUTPUT([FILE...])'
- 
-    It is best to put each macro call on its own line in `configure.in'.
- Most of the macros don't add extra newlines; they rely on the newline
- after the macro call to terminate the commands.  This approach makes
- the generated `configure' script a little easier to read by not
- inserting lots of blank lines.  It is generally safe to set shell
- variables on the same line as a macro call, because the shell allows
- assignments without intervening newlines.
- 
-    When calling macros that take arguments, there must not be any blank
- space between the macro name and the open parenthesis.  Arguments can be
- more than one line long if they are enclosed within the `m4' quote
- characters `[' and `]'.  If you have a long line such as a list of file
- names, you can generally use a backslash at the end of a line to
- continue it logically on the next line (this is implemented by the
- shell, not by anything special that Autoconf does).
- 
-    Some macros handle two cases: what to do if the given condition is
- met, and what to do if the condition is not met.  In some places you
- might want to do something if a condition is true but do nothing if it's
- false, or vice versa.  To omit the true case, pass an empty value for
- the ACTION-IF-FOUND argument to the macro.  To omit the false case,
- omit the ACTION-IF-NOT-FOUND argument to the macro, including the comma
- before it.
- 
-    You can include comments in `configure.in' files by starting them
- with the `m4' builtin macro `dnl', which discards text up through the
- next newline.  These comments do not appear in the generated
- `configure' scripts.  For example, it is helpful to begin
- `configure.in' files with a line like this:
- 
-      dnl Process this file with autoconf to produce a configure script.
- 
- 
- File: autoconf.info,  Node: Invoking autoscan,  Next: Invoking ifnames,  Prev: Writing configure.in,  Up: Making configure Scripts
- 
- Using `autoscan' to Create `configure.in'
- =========================================
- 
-    The `autoscan' program can help you create a `configure.in' file for
- a software package.  `autoscan' examines source files in the directory
- tree rooted at a directory given as a command line argument, or the
- current directory if none is given.  It searches the source files for
- common portability problems and creates a file `configure.scan' which
- is a preliminary `configure.in' for that package.
- 
-    You should manually examine `configure.scan' before renaming it to
- `configure.in'; it will probably need some adjustments.  Occasionally
- `autoscan' outputs a macro in the wrong order relative to another
- macro, so that `autoconf' produces a warning; you need to move such
- macros manually.  Also, if you want the package to use a configuration
- header file, you must add a call to `AC_CONFIG_HEADER' (*note
- Configuration Headers::.).  You might also have to change or add some
- `#if' directives to your program in order to make it work with Autoconf
- (*note Invoking ifnames::., for information about a program that can
- help with that job).
- 
-    `autoscan' uses several data files, which are installed along with
- the distributed Autoconf macro files, to determine which macros to
- output when it finds particular symbols in a package's source files.
- These files all have the same format.  Each line consists of a symbol,
- whitespace, and the Autoconf macro to output if that symbol is
- encountered.  Lines starting with `#' are comments.
- 
-    `autoscan' is only installed if you already have Perl installed.
- `autoscan' accepts the following options:
- 
- `--help'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
-      Look for the data files in directory DIR instead of the default
-      installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--verbose'
-      Print the names of the files it examines and the potentially
-      interesting symbols it finds in them.  This output can be
-      voluminous.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking ifnames,  Next: Invoking autoconf,  Prev: Invoking autoscan,  Up: Making configure Scripts
- 
- Using `ifnames' to List Conditionals
- ====================================
- 
-    `ifnames' can help when writing a `configure.in' for a software
- package.  It prints the identifiers that the package already uses in C
- preprocessor conditionals.  If a package has already been set up to
- have some portability, this program can help you figure out what its
- `configure' needs to check for.  It may help fill in some gaps in a
- `configure.in' generated by `autoscan' (*note Invoking autoscan::.).
- 
-    `ifnames' scans all of the C source files named on the command line
- (or the standard input, if none are given) and writes to the standard
- output a sorted list of all the identifiers that appear in those files
- in `#if', `#elif', `#ifdef', or `#ifndef' directives.  It prints each
- identifier on a line, followed by a space-separated list of the files
- in which that identifier occurs.
- 
- `ifnames' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  Only used to get the version
-      number.  You can also set the `AC_MACRODIR' environment variable
-      to a directory; this option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking autoconf,  Next: Invoking autoreconf,  Prev: Invoking ifnames,  Up: Making configure Scripts
- 
- Using `autoconf' to Create `configure'
- ======================================
- 
-    To create `configure' from `configure.in', run the `autoconf'
- program with no arguments.  `autoconf' processes `configure.in' with
- the `m4' macro processor, using the Autoconf macros.  If you give
- `autoconf' an argument, it reads that file instead of `configure.in'
- and writes the configuration script to the standard output instead of
- to `configure'.  If you give `autoconf' the argument `-', it reads the
- standard input instead of `configure.in' and writes the configuration
- script on the standard output.
- 
-    The Autoconf macros are defined in several files.  Some of the files
- are distributed with Autoconf; `autoconf' reads them first.  Then it
- looks for the optional file `acsite.m4' in the directory that contains
- the distributed Autoconf macro files, and for the optional file
- `aclocal.m4' in the current directory.  Those files can contain your
- site's or the package's own Autoconf macro definitions (*note Writing
- Macros::., for more information).  If a macro is defined in more than
- one of the files that `autoconf' reads, the last definition it reads
- overrides the earlier ones.
- 
-    `autoconf' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--localdir=DIR'
- `-l DIR'
-      Look for the package file `aclocal.m4' in directory DIR instead of
-      in the current directory.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the installed macro files in directory DIR.  You can also
-      set the `AC_MACRODIR' environment variable to a directory; this
-      option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Invoking autoreconf,  Prev: Invoking autoconf,  Up: Making configure Scripts
- 
- Using `autoreconf' to Update `configure' Scripts
- ================================================
- 
-    If you have a lot of Autoconf-generated `configure' scripts, the
- `autoreconf' program can save you some work.  It runs `autoconf' (and
- `autoheader', where appropriate) repeatedly to remake the Autoconf
- `configure' scripts and configuration header templates in the directory
- tree rooted at the current directory.  By default, it only remakes
- those files that are older than their `configure.in' or (if present)
- `aclocal.m4'.  Since `autoheader' does not change the timestamp of its
- output file if the file wouldn't be changing, this is not necessarily
- the minimum amount of work.  If you install a new version of Autoconf,
- you can make `autoreconf' remake *all* of the files by giving it the
- `--force' option.
- 
-    If you give `autoreconf' the `--macrodir=DIR' or `--localdir=DIR'
- options, it passes them down to `autoconf' and `autoheader' (with
- relative paths adjusted properly).
- 
-    *Note Automatic Remaking::, for `Makefile' rules to automatically
- remake `configure' scripts when their source files change.  That method
- handles the timestamps of configuration header templates properly, but
- does not pass `--macrodir=DIR' or `--localdir=DIR'.
- 
- `autoreconf' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--force'
- `-f'
-      Remake even `configure' scripts and configuration headers that are
-      newer than their input files (`configure.in' and, if present,
-      `aclocal.m4').
- 
- `--localdir=DIR'
- `-l DIR'
-      Look for the package files `aclocal.m4' and `acconfig.h' (but not
-      `FILE.top' and `FILE.bot') in directory DIR instead of in the
-      directory containing each `configure.in'.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--verbose'
-      Print the name of each directory where `autoreconf' runs
-      `autoconf' (and `autoheader', if appropriate).
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Setup,  Next: Existing Tests,  Prev: Making configure Scripts,  Up: Top
- 
- Initialization and Output Files
- *******************************
- 
-    Autoconf-generated `configure' scripts need some information about
- how to initialize, such as how to find the package's source files; and
- about the output files to produce.  The following sections describe
- initialization and creating output files.
- 
- * Menu:
- 
- * Input::                       Where Autoconf should find files.
- * Output::			Creating output files.
- * Makefile Substitutions::      Using output variables in `Makefile's.
- * Configuration Headers::       Creating a configuration header file.
- * Subdirectories::              Configuring independent packages together.
- * Default Prefix::              Changing the default installation prefix.
- * Versions::                    Version numbers in `configure'.
- 
- 
- File: autoconf.info,  Node: Input,  Next: Output,  Up: Setup
- 
- Finding `configure' Input
- =========================
- 
-    Every `configure' script must call `AC_INIT' before doing anything
- else.  The only other required macro is `AC_OUTPUT' (*note Output::.).
- 
-  - Macro: AC_INIT (UNIQUE-FILE-IN-SOURCE-DIR)
-      Process any command-line arguments and find the source code
-      directory.  UNIQUE-FILE-IN-SOURCE-DIR is some file that is in the
-      package's source directory; `configure' checks for this file's
-      existence to make sure that the directory that it is told contains
-      the source code in fact does.  Occasionally people accidentally
-      specify the wrong directory with `--srcdir'; this is a safety
-      check.  *Note Invoking configure::, for more information.
- 
-    Packages that do manual configuration or use the `install' program
- might need to tell `configure' where to find some other shell scripts
- by calling `AC_CONFIG_AUX_DIR', though the default places it looks are
- correct for most cases.
- 
-  - Macro: AC_CONFIG_AUX_DIR(DIR)
-      Use the `install-sh', `config.sub', `config.guess', and Cygnus
-      `configure' scripts that are in directory DIR.  These are
-      auxiliary files used in configuration.  DIR can be either absolute
-      or relative to `SRCDIR'.  The default is `SRCDIR' or `SRCDIR/..' or
-      `SRCDIR/../..', whichever is the first that contains `install-sh'.
-      The other files are not checked for, so that using
-      `AC_PROG_INSTALL' does not automatically require distributing the
-      other auxiliary files.  It checks for `install.sh' also, but that
-      name is obsolete because some `make' programs have a rule that
-      creates `install' from it if there is no `Makefile'.
- 
- 
- File: autoconf.info,  Node: Output,  Next: Makefile Substitutions,  Prev: Input,  Up: Setup
- 
- Creating Output Files
- =====================
- 
-    Every Autoconf-generated `configure' script must finish by calling
- `AC_OUTPUT'.  It is the macro that creates the `Makefile's and optional
- other files resulting from configuration.  The only other required
- macro is `AC_INIT' (*note Input::.).
- 
-  - Macro: AC_OUTPUT ([FILE...] [,EXTRA-CMDS] [,INIT-CMDS])
-      Create output files.  The FILE... argument is a
-      whitespace-separated list of output files; it may be empty.  This
-      macro creates each file `FILE' by copying an input file (by default
-      named `FILE.in'), substituting the output variable values.  *Note
-      Makefile Substitutions::, for more information on using output
-      variables.  *Note Setting Output Variables::, for more information
-      on creating them.  This macro creates the directory that the file
-      is in if it doesn't exist (but not the parents of that directory).
-      Usually, `Makefile's are created this way, but other files, such
-      as `.gdbinit', can be specified as well.
- 
-      If `AC_CONFIG_HEADER', `AC_LINK_FILES', or `AC_CONFIG_SUBDIRS' has
-      been called, this macro also creates the files named as their
-      arguments.
- 
-      A typical call to `AC_OUTPUT' looks like this:
-           AC_OUTPUT(Makefile src/Makefile man/Makefile X/Imakefile)
- 
-      You can override an input file name by appending it to FILE,
-      separated by a colon.  For example,
-           AC_OUTPUT(Makefile:templates/top.mk lib/Makefile:templates/lib.mk)
- 
-      If you pass EXTRA-CMDS, those commands will be inserted into
-      `config.status' to be run after all its other processing.  If
-      INIT-CMDS are given, they are inserted just before EXTRA-CMDS,
-      with shell variable, command, and backslash substitutions
-      performed on them in `configure'.  You can use INIT-CMDS to pass
-      variables from `configure' to the EXTRA-CMDS.
- 
-    If you run `make' on subdirectories, you should run it using the
- `make' variable `MAKE'.  Most versions of `make' set `MAKE' to the name
- of the `make' program plus any options it was given.  (But many do not
- include in it the values of any variables set on the command line, so
- those are not passed on automatically.) Some old versions of `make' do
- not set this variable.  The following macro allows you to use it even
- with those versions.
- 
-  - Macro: AC_PROG_MAKE_SET
-      If `make' predefines the variable `MAKE', define output variable
-      `SET_MAKE' to be empty.  Otherwise, define `SET_MAKE' to contain
-      `MAKE=make'.  Calls `AC_SUBST' for `SET_MAKE'.
- 
-    To use this macro, place a line like this in each `Makefile.in' that
- runs `MAKE' on other directories:
- 
-      @SET_MAKE@
- 
- 
- File: autoconf.info,  Node: Makefile Substitutions,  Next: Configuration Headers,  Prev: Output,  Up: Setup
- 
- Substitutions in Makefiles
- ==========================
- 
-    Each subdirectory in a distribution that contains something to be
- compiled or installed should come with a file `Makefile.in', from which
- `configure' will create a `Makefile' in that directory.  To create a
- `Makefile', `configure' performs a simple variable substitution,
- replacing occurrences of `@VARIABLE@' in `Makefile.in' with the value
- that `configure' has determined for that variable.  Variables that are
- substituted into output files in this way are called "output
- variables".  They are ordinary shell variables that are set in
- `configure'.  To make `configure' substitute a particular variable into
- the output files, the macro `AC_SUBST' must be called with that
- variable name as an argument.  Any occurrences of `@VARIABLE@' for
- other variables are left unchanged.  *Note Setting Output Variables::,
- for more information on creating output variables with `AC_SUBST'.
- 
-    A software package that uses a `configure' script should be
- distributed with a file `Makefile.in', but no `Makefile'; that way, the
- user has to properly configure the package for the local system before
- compiling it.
- 
-    *Note Makefile Conventions: (standards.info)Makefile Conventions,
- for more information on what to put in `Makefile's.
- 
- * Menu:
- 
- * Preset Output Variables::	Output variables that are always set.
- * Build Directories::   	Supporting multiple concurrent compiles.
- * Automatic Remaking::		Makefile rules for configuring.
- 
- 
- File: autoconf.info,  Node: Preset Output Variables,  Next: Build Directories,  Up: Makefile Substitutions
- 
- Preset Output Variables
- -----------------------
- 
-    Some output variables are preset by the Autoconf macros.  Some of the
- Autoconf macros set additional output variables, which are mentioned in
- the descriptions for those macros.  *Note Output Variable Index::, for a
- complete list of output variables.  Here is what each of the preset ones
- contains.
- 
-  - Variable: configure_input
-      A comment saying that the file was generated automatically by
-      `configure' and giving the name of the input file.  `AC_OUTPUT'
-      adds a comment line containing this variable to the top of every
-      `Makefile' it creates.  For other files, you should reference this
-      variable in a comment at the top of each input file.  For example,
-      an input shell script should begin like this:
- 
-           #! /bin/sh
-           # @configure_input@
- 
-      The presence of that line also reminds people editing the file
-      that it needs to be processed by `configure' in order to be used.
- 
-  - Variable: exec_prefix
-      The installation prefix for architecture-dependent files.
- 
-  - Variable: prefix
-      The installation prefix for architecture-independent files.
- 
-  - Variable: srcdir
-      The directory that contains the source code for that `Makefile'.
- 
-  - Variable: top_srcdir
-      The top-level source code directory for the package.  In the
-      top-level directory, this is the same as `srcdir'.
- 
-  - Variable: CFLAGS
-      Debugging and optimization options for the C compiler.  If it is
-      not set in the environment when `configure' runs, the default
-      value is set when you call `AC_PROG_CC' (or empty if you don't).
-      `configure' uses this variable when compiling programs to test for
-      C features.
- 
-  - Variable: CPPFLAGS
-      Header file search directory (`-IDIR') and any other miscellaneous
-      options for the C preprocessor and compiler.  If it is not set in
-      the environment when `configure' runs, the default value is empty.
-      `configure' uses this variable when compiling or preprocessing
-      programs to test for C features.
- 
-  - Variable: CXXFLAGS
-      Debugging and optimization options for the C++ compiler.  If it is
-      not set in the environment when `configure' runs, the default
-      value is set when you call `AC_PROG_CXX' (or empty if you don't).
-      `configure' uses this variable when compiling programs to test for
-      C++ features.
- 
-  - Variable: DEFS
-      `-D' options to pass to the C compiler.  If `AC_CONFIG_HEADER' is
-      called, `configure' replaces `@DEFS@' with `-DHAVE_CONFIG_H'
-      instead (*note Configuration Headers::.).  This variable is not
-      defined while `configure' is performing its tests, only when
-      creating the output files.  *Note Setting Output Variables::, for
-      how to check the results of previous tests.
- 
-  - Variable: LDFLAGS
-      Stripping (`-s') and any other miscellaneous options for the
-      linker.  If it is not set in the environment when `configure' runs,
-      the default value is empty.  `configure' uses this variable when
-      linking programs to test for C features.
- 
-  - Variable: LIBS
-      `-l' and `-L' options to pass to the linker.
- 
- 
- File: autoconf.info,  Node: Build Directories,  Next: Automatic Remaking,  Prev: Preset Output Variables,  Up: Makefile Substitutions
- 
- Build Directories
- -----------------
- 
-    You can support compiling a software package for several
- architectures simultaneously from the same copy of the source code.
- The object files for each architecture are kept in their own directory.
- 
-    To support doing this, `make' uses the `VPATH' variable to find the
- files that are in the source directory.  GNU `make' and most other
- recent `make' programs can do this.  Older `make' programs do not
- support `VPATH'; when using them, the source code must be in the same
- directory as the object files.
- 
-    To support `VPATH', each `Makefile.in' should contain two lines that
- look like:
- 
-      srcdir = @srcdir@
-      VPATH = @srcdir@
- 
-    Do not set `VPATH' to the value of another variable, for example
- `VPATH = $(srcdir)', because some versions of `make' do not do variable
- substitutions on the value of `VPATH'.
- 
-    `configure' substitutes in the correct value for `srcdir' when it
- produces `Makefile'.
- 
-    Do not use the `make' variable `$<', which expands to the pathname
- of the file in the source directory (found with `VPATH'), except in
- implicit rules.  (An implicit rule is one such as `.c.o', which tells
- how to create a `.o' file from a `.c' file.)  Some versions of `make'
- do not set `$<' in explicit rules; they expand it to an empty value.
- 
-    Instead, `Makefile' command lines should always refer to source
- files by prefixing them with `$(srcdir)/'.  For example:
- 
-      time.info: time.texinfo
-              $(MAKEINFO) $(srcdir)/time.texinfo
- 
- 
- File: autoconf.info,  Node: Automatic Remaking,  Prev: Build Directories,  Up: Makefile Substitutions
- 
- Automatic Remaking
- ------------------
- 
-    You can put rules like the following in the top-level `Makefile.in'
- for a package to automatically update the configuration information when
- you change the configuration files.  This example includes all of the
- optional files, such as `aclocal.m4' and those related to configuration
- header files.  Omit from the `Makefile.in' rules any of these files
- that your package does not use.
- 
-    The `${srcdir}/' prefix is included because of limitations in the
- `VPATH' mechanism.
- 
-    The `stamp-' files are necessary because the timestamps of
- `config.h.in' and `config.h' will not be changed if remaking them does
- not change their contents.  This feature avoids unnecessary
- recompilation.  You should include the file `stamp-h.in' your package's
- distribution, so `make' will consider `config.h.in' up to date.  On
- some old BSD systems, `touch' or any command that results in an empty
- file does not update the timestamps, so use a command like `echo' as a
- workaround.
- 
-      ${srcdir}/configure: configure.in aclocal.m4
-              cd ${srcdir} && autoconf
-      
-      # autoheader might not change config.h.in, so touch a stamp file.
-      ${srcdir}/config.h.in: stamp-h.in
-      ${srcdir}/stamp-h.in: configure.in aclocal.m4 acconfig.h \
-          config.h.top config.h.bot
-              cd ${srcdir} && autoheader
-              echo timestamp > ${srcdir}/stamp-h.in
-      
-      config.h: stamp-h
-      stamp-h: config.h.in config.status
-              ./config.status
-      
-      Makefile: Makefile.in config.status
-              ./config.status
-      
-      config.status: configure
-              ./config.status --recheck
- 
-    In addition, you should pass `echo timestamp > stamp-h' in the
- EXTRA-CMDS argument to `AC_OUTPUT', so `config.status' will ensure that
- `config.h' is considered up to date.  *Note Output::, for more
- information about `AC_OUTPUT'.
- 
-    *Note Invoking config.status::, for more examples of handling
- configuration-related dependencies.
- 
- 
- File: autoconf.info,  Node: Configuration Headers,  Next: Subdirectories,  Prev: Makefile Substitutions,  Up: Setup
- 
- Configuration Header Files
- ==========================
- 
-    When a package tests more than a few C preprocessor symbols, the
- command lines to pass `-D' options to the compiler can get quite long.
- This causes two problems.  One is that the `make' output is hard to
- visually scan for errors.  More seriously, the command lines can exceed
- the length limits of some operating systems.  As an alternative to
- passing `-D' options to the compiler, `configure' scripts can create a
- C header file containing `#define' directives.  The `AC_CONFIG_HEADER'
- macro selects this kind of output.  It should be called right after
- `AC_INIT'.
- 
-    The package should `#include' the configuration header file before
- any other header files, to prevent inconsistencies in declarations (for
- example, if it redefines `const').  Use `#include <config.h>' instead
- of `#include "config.h"', and pass the C compiler a `-I.' option (or
- `-I..'; whichever directory contains `config.h').  That way, even if
- the source directory is configured itself (perhaps to make a
- distribution), other build directories can also be configured without
- finding the `config.h' from the source directory.
- 
-  - Macro: AC_CONFIG_HEADER (HEADER-TO-CREATE ...)
-      Make `AC_OUTPUT' create the file(s) in the whitespace-separated
-      list HEADER-TO-CREATE containing C preprocessor `#define'
-      statements, and replace `@DEFS@' in generated files with
-      `-DHAVE_CONFIG_H' instead of the value of `DEFS'.  The usual name
-      for HEADER-TO-CREATE is `config.h'.
- 
-      If HEADER-TO-CREATE already exists and its contents are identical
-      to what `AC_OUTPUT' would put in it, it is left alone.  Doing this
-      allows some changes in configuration without needlessly causing
-      object files that depend on the header file to be recompiled.
- 
-      Usually the input file is named `HEADER-TO-CREATE.in'; however,
-      you can override the input file name by appending it to
-      HEADER-TO-CREATE, separated by a colon.  For example,
-           AC_CONFIG_HEADER(defines.h:defines.hin)
- 
-      Doing this allows you to keep your filenames acceptable to MS-DOS.
- 
- * Menu:
- 
- * Header Templates::            Input for the configuration headers.
- * Invoking autoheader::		How to create configuration templates.
- 
- 
- File: autoconf.info,  Node: Header Templates,  Next: Invoking autoheader,  Up: Configuration Headers
- 
- Configuration Header Templates
- ------------------------------
- 
-    Your distribution should contain a template file that looks as you
- want the final header file to look, including comments, with default
- values in the `#define' statements.  For example, suppose your
- `configure.in' makes these calls:
- 
-      AC_CONFIG_HEADER(conf.h)
-      AC_CHECK_HEADERS(unistd.h)
- 
- Then you could have code like the following in `conf.h.in'.  On systems
- that have `unistd.h', `configure' will change the 0 to a 1.  On other
- systems, it will leave the line unchanged.
- 
-      /* Define as 1 if you have unistd.h.  */
-      #define HAVE_UNISTD_H 0
- 
-    Alternately, if your code tests for configuration options using
- `#ifdef' instead of `#if', a default value can be to `#undef' the
- variable instead of to define it to a value.  On systems that have
- `unistd.h', `configure' will change the second line to read `#define
- HAVE_UNISTD_H 1'.  On other systems, it will comment that line out (in
- case the system predefines that symbol).
- 
-      /* Define if you have unistd.h.  */
-      #undef HAVE_UNISTD_H
- 
- 
- File: autoconf.info,  Node: Invoking autoheader,  Prev: Header Templates,  Up: Configuration Headers
- 
- Using `autoheader' to Create `config.h.in'
- ------------------------------------------
- 
-    The `autoheader' program can create a template file of C `#define'
- statements for `configure' to use.  If `configure.in' invokes
- `AC_CONFIG_HEADER(FILE)', `autoheader' creates `FILE.in'.  Otherwise,
- `autoheader' creates `config.h.in'.
- 
-    If you give `autoheader' an argument, it uses that file instead of
- `configure.in' and writes the header file to the standard output
- instead of to `config.h.in'.  If you give `autoheader' an argument of
- `-', it reads the standard input instead of `configure.in' and writes
- the header file to the standard output.
- 
-    `autoheader' scans `configure.in' and figures out which C
- preprocessor symbols it might define.  It copies comments and `#define'
- and `#undef' statements from a file called `acconfig.h', which comes
- with and is installed with Autoconf.  It also uses a file called
- `acconfig.h' in the current directory, if present.  If you `AC_DEFINE'
- any additional symbols, you must create that file with entries for
- them.  For symbols defined by `AC_CHECK_HEADERS', `AC_CHECK_FUNCS',
- `AC_CHECK_SIZEOF', or `AC_CHECK_LIB', `autoheader' generates comments
- and `#undef' statements itself rather than copying them from a file,
- since the possible symbols are effectively limitless.
- 
-    The file that `autoheader' creates contains mainly `#define' and
- `#undef' statements and their accompanying comments.  If `./acconfig.h'
- contains the string `@TOP@', `autoheader' copies the lines before the
- line containing `@TOP@' into the top of the file that it generates.
- Similarly, if `./acconfig.h' contains the string `@BOTTOM@',
- `autoheader' copies the lines after that line to the end of the file it
- generates.  Either or both of those strings may be omitted.
- 
-    An alternate way to produce the same effect is to create the files
- `FILE.top' (typically `config.h.top') and/or `FILE.bot' in the current
- directory.  If they exist, `autoheader' copies them to the beginning
- and end, respectively, of its output.  Their use is discouraged because
- they have file names that contain two periods, and so can not be stored
- on MS-DOS; also, they are two more files to clutter up the directory.
- But if you use the `--localdir=DIR' option to use an `acconfig.h' in
- another directory, they give you a way to put custom boilerplate in each
- individual `config.h.in'.
- 
-    `autoheader' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--localdir=DIR'
- `-l DIR'
-      Look for the package files `aclocal.m4' and `acconfig.h' (but not
-      `FILE.top' and `FILE.bot') in directory DIR instead of in the
-      current directory.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the installed macro files and `acconfig.h' in directory
-      DIR.  You can also set the `AC_MACRODIR' environment variable to a
-      directory; this option overrides the environment variable.
- 
- `--version'
-      Print the version number of Autoconf and exit.
- 
- 
- File: autoconf.info,  Node: Subdirectories,  Next: Default Prefix,  Prev: Configuration Headers,  Up: Setup
- 
- Configuring Other Packages in Subdirectories
- ============================================
- 
-    In most situations, calling `AC_OUTPUT' is sufficient to produce
- `Makefile's in subdirectories.  However, `configure' scripts that
- control more than one independent package can use `AC_CONFIG_SUBDIRS'
- to run `configure' scripts for other packages in subdirectories.
- 
-  - Macro: AC_CONFIG_SUBDIRS (DIR ...)
-      Make `AC_OUTPUT' run `configure' in each subdirectory DIR in the
-      given whitespace-separated list.  If a given DIR is not found, no
-      error is reported, so a `configure' script can configure whichever
-      parts of a large source tree are present.  If a given DIR contains
-      `configure.in' but no `configure', the Cygnus `configure' script
-      found by `AC_CONFIG_AUXDIR' is used.  The subdirectory `configure'
-      scripts are given the same command line options that were given to
-      this `configure' script, with minor changes if needed (e.g., to
-      adjust a relative path for the cache file or source directory).
-      This macro also sets the output variable `subdirs' to the list of
-      directories `DIR ...'.  `Makefile' rules can use this variable to
-      determine which subdirectories to recurse into.
- 
- 
- File: autoconf.info,  Node: Default Prefix,  Next: Versions,  Prev: Subdirectories,  Up: Setup
- 
- Default Prefix
- ==============
- 
-    By default, `configure' sets the prefix for files it installs to
- `/usr/local'.  The user of `configure' can select a different prefix
- using the `--prefix' and `--exec-prefix' options.  There are two ways
- to change the default: when creating `configure', and when running it.
- 
-    Some software packages might want to install in a directory besides
- `/usr/local' by default.  To accomplish that, use the
- `AC_PREFIX_DEFAULT' macro.
- 
-  - Macro: AC_PREFIX_DEFAULT (PREFIX)
-      Set the default installation prefix to PREFIX instead of
-      `/usr/local'.
- 
-    It may be convenient for users to have `configure' guess the
- installation prefix from the location of a related program that they
- have already installed.  If you wish to do that, you can call
- `AC_PREFIX_PROGRAM'.
- 
-  - Macro: AC_PREFIX_PROGRAM (PROGRAM)
-      If the user did not specify an installation prefix (using the
-      `--prefix' option), guess a value for it by looking for PROGRAM in
-      `PATH', the way the shell does.  If PROGRAM is found, set the
-      prefix to the parent of the directory containing PROGRAM;
-      otherwise leave the prefix specified in `Makefile.in' unchanged.
-      For example, if PROGRAM is `gcc' and the `PATH' contains
-      `/usr/local/gnu/bin/gcc', set the prefix to `/usr/local/gnu'.
- 
--- 0 ----
Index: krb5/util/autoconf/autoconf.info-2
diff -c krb5/util/autoconf/autoconf.info-2:1.1.1.1 krb5/util/autoconf/autoconf.info-2:removed
*** krb5/util/autoconf/autoconf.info-2:1.1.1.1	Mon Jun  2 17:58:30 1997
--- krb5/util/autoconf/autoconf.info-2	Sun Mar 16 20:22:40 2003
***************
*** 1,1202 ****
- This is Info file autoconf.info, produced by Makeinfo-1.55 from the
- input file autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Versions,  Prev: Default Prefix,  Up: Setup
- 
- Version Numbers in `configure'
- ==============================
- 
-    The following macros manage version numbers for `configure' scripts.
- Using them is optional.
- 
-  - Macro: AC_PREREQ (VERSION)
-      Ensure that a recent enough version of Autoconf is being used.  If
-      the version of Autoconf being used to create `configure' is earlier
-      than VERSION, print an error message on the standard error output
-      and do not create `configure'.  For example:
- 
-           AC_PREREQ(1.8)
- 
-      This macro is useful if your `configure.in' relies on non-obvious
-      behavior that changed between Autoconf releases.  If it merely
-      needs recently added macros, then `AC_PREREQ' is less useful,
-      because the `autoconf' program already tells the user which macros
-      are not found.  The same thing happens if `configure.in' is
-      processed by a version of Autoconf older than when `AC_PREREQ' was
-      added.
- 
-  - Macro: AC_REVISION (REVISION-INFO)
-      Copy revision stamp REVISION-INFO into the `configure' script,
-      with any dollar signs or double-quotes removed.  This macro lets
-      you put a revision stamp from `configure.in' into `configure'
-      without RCS or CVS changing it when you check in `configure'.  That
-      way, you can determine easily which revision of `configure.in' a
-      particular `configure' corresponds to.
- 
-      It is a good idea to call this macro before `AC_INIT' so that the
-      revision number is near the top of both `configure.in' and
-      `configure'.  To support doing that, the `AC_REVISION' output
-      begins with `#! /bin/sh', like the normal start of a `configure'
-      script does.
- 
-      For example, this line in `configure.in':
- 
-           AC_REVISION($Revision: 1.1.1.1 $)dnl
- 
-      produces this in `configure':
- 
-           #! /bin/sh
-           # From configure.in Revision: 1.30
- 
- 
- File: autoconf.info,  Node: Existing Tests,  Next: Writing Tests,  Prev: Setup,  Up: Top
- 
- Existing Tests
- **************
- 
-    These macros test for particular system features that packages might
- need or want to use.  If you need to test for a kind of feature that
- none of these macros check for, you can probably do it by calling
- primitive test macros with appropriate arguments (*note Writing
- Tests::.).
- 
-    These tests print messages telling the user which feature they're
- checking for, and what they find.  They cache their results for future
- `configure' runs (*note Caching Results::.).
- 
-    Some of these macros set output variables.  *Note Makefile
- Substitutions::, for how to get their values.  The phrase "define NAME"
- is used below as a shorthand to mean "define C preprocessor symbol NAME
- to the value 1".  *Note Defining Symbols::, for how to get those symbol
- definitions into your program.
- 
- * Menu:
- 
- * Alternative Programs::	Selecting between alternative programs.
- * Libraries::                   Library archives that might be missing.
- * Library Functions::		C library functions that might be missing.
- * Header Files::		Header files that might be missing.
- * Structures::			Structures or members that might be missing.
- * Typedefs::			`typedef's that might be missing.
- * Compiler Characteristics::	C compiler or machine architecture features.
- * System Services::		Operating system services.
- * UNIX Variants::		Special kludges for specific UNIX variants.
- 
- 
- File: autoconf.info,  Node: Alternative Programs,  Next: Libraries,  Up: Existing Tests
- 
- Alternative Programs
- ====================
- 
-    These macros check for the presence or behavior of particular
- programs.  They are used to choose between several alternative programs
- and to decide what to do once one has been chosen.  If there is no
- macro specifically defined to check for a program you need, and you
- don't need to check for any special properties of it, then you can use
- one of the general program check macros.
- 
- * Menu:
- 
- * Particular Programs::         Special handling to find certain programs.
- * Generic Programs::            How to find other programs.
- 
- 
- File: autoconf.info,  Node: Particular Programs,  Next: Generic Programs,  Up: Alternative Programs
- 
- Particular Program Checks
- -------------------------
- 
-    These macros check for particular programs--whether they exist, and
- in some cases whether they support certain features.
- 
-  - Macro: AC_DECL_YYTEXT
-      Define `YYTEXT_POINTER' if `yytext' is a `char *' instead of a
-      `char []'.  Also set output variable `LEX_OUTPUT_ROOT' to the base
-      of the file name that the lexer generates; usually `lex.yy', but
-      sometimes something else.  These results vary according to whether
-      `lex' or `flex' is being used.
- 
-  - Macro: AC_PROG_AWK
-      Check for `mawk', `gawk', `nawk', and `awk', in that order, and
-      set output variable `AWK' to the first one that it finds.  It
-      tries `mawk' first because that is reported to be the fastest
-      implementation.
- 
-  - Macro: AC_PROG_CC
-      Determine a C compiler to use.  If `CC' is not already set in the
-      environment, check for `gcc', and use `cc' if it's not found.  Set
-      output variable `CC' to the name of the compiler found.
- 
-      If using the GNU C compiler, set shell variable `GCC' to `yes',
-      empty otherwise.  If output variable `CFLAGS' was not already set,
-      set it to `-g -O' for the GNU C compiler (`-O' on systems where
-      GCC does not accept `-g'), or `-g' for other compilers.
- 
-  - Macro: AC_PROG_CC_C_O
-      If the C compiler does not accept the `-c' and `-o' options
-      simultaneously, define `NO_MINUS_C_MINUS_O'.
- 
-  - Macro: AC_PROG_CPP
-      Set output variable `CPP' to a command that runs the C
-      preprocessor.  If `$CC -E' doesn't work, it uses `/lib/cpp'.  It
-      is only portable to run `CPP' on files with a `.c' extension.
- 
-      If the current language is C (*note Language Choice::.), many of
-      the specific test macros use the value of `CPP' indirectly by
-      calling `AC_TRY_CPP', `AC_CHECK_HEADER', `AC_EGREP_HEADER', or
-      `AC_EGREP_CPP'.
- 
-  - Macro: AC_PROG_CXX
-      Determine a C++ compiler to use.  Check if the environment variable
-      `CXX' or `CCC' (in that order) is set; if so, set output variable
-      `CXX' to its value.  Otherwise search for a C++ compiler under
-      likely names (`c++', `g++', `gcc', `CC', and `cxx').  If none of
-      those checks succeed, as a last resort set `CXX' to `gcc'.
- 
-      If using the GNU C++ compiler, set shell variable `GXX' to `yes',
-      empty otherwise.  If output variable `CXXFLAGS' was not already
-      set, set it to `-g -O' for the GNU C++ compiler (`-O' on systems
-      where G++ does not accept `-g'), or `-g' for other compilers.
- 
-  - Macro: AC_PROG_CXXCPP
-      Set output variable `CXXCPP' to a command that runs the C++
-      preprocessor.  If `$CXX -E' doesn't work, it uses `/lib/cpp'.  It
-      is only portable to run `CXXCPP' on files with a `.c', `.C', or
-      `.cc' extension.
- 
-      If the current language is C++ (*note Language Choice::.), many of
-      the specific test macros use the value of `CXXCPP' indirectly by
-      calling `AC_TRY_CPP', `AC_CHECK_HEADER', `AC_EGREP_HEADER', or
-      `AC_EGREP_CPP'.
- 
-  - Macro: AC_PROG_GCC_TRADITIONAL
-      Add `-traditional' to output variable `CC' if using the GNU C
-      compiler and `ioctl' does not work properly without
-      `-traditional'.  That usually happens when the fixed header files
-      have not been installed on an old system.  Since recent versions
-      of the GNU C compiler fix the header files automatically when
-      installed, this is becoming a less prevalent problem.
- 
-  - Macro: AC_PROG_INSTALL
-      Set output variable `INSTALL' to the path of a BSD compatible
-      `install' program, if one is found in the current `PATH'.
-      Otherwise, set `INSTALL' to `DIR/install-sh -c', checking the
-      directories specified to `AC_CONFIG_AUX_DIR' (or its default
-      directories) to determine DIR (*note Output::.).  Also set the
-      variable `INSTALL_PROGRAM' to `${INSTALL}' and `INSTALL_DATA' to
-      `${INSTALL} -m 644'.
- 
-      This macro screens out various instances of `install' known to not
-      work.  It prefers to find a C program rather than a shell script,
-      for speed.  Instead of `install-sh', it can also use `install.sh',
-      but that name is obsolete because some `make' programs have a rule
-      that creates `install' from it if there is no `Makefile'.
- 
-      A copy of `install-sh' which you may use comes with Autoconf.  If
-      you use `AC_PROG_INSTALL', you must include either `install-sh' or
-      `install.sh' in your distribution, or `configure' will produce an
-      error message saying it can't find them--even if the system you're
-      on has a good `install' program.  This check is a safety measure
-      to prevent you from accidentally leaving that file out, which
-      would prevent your package from installing on systems that don't
-      have a BSD-compatible `install' program.
- 
-      If you need to use your own installation program because it has
-      features not found in standard `install' programs, there is no
-      reason to use `AC_PROG_INSTALL'; just put the pathname of your
-      program into your `Makefile.in' files.
- 
-  - Macro: AC_PROG_LEX
-      If `flex' is found, set output variable `LEX' to `flex' and
-      `LEXLIB' to `-lfl', if that library is in a standard place.
-      Otherwise set `LEX' to `lex' and `LEXLIB' to `-ll'.
- 
-  - Macro: AC_PROG_LN_S
-      If `ln -s' works on the current filesystem (the operating system
-      and filesystem support symbolic links), set output variable `LN_S'
-      to `ln -s', otherwise set it to `ln'.
- 
-  - Macro: AC_PROG_RANLIB
-      Set output variable `RANLIB' to `ranlib' if `ranlib' is found,
-      otherwise to `:' (do nothing).
- 
-  - Macro: AC_PROG_YACC
-      If `bison' is found, set output variable `YACC' to `bison -y'.
-      Otherwise, if `byacc' is found, set `YACC' to `byacc'.  Otherwise
-      set `YACC' to `yacc'.
- 
- 
- File: autoconf.info,  Node: Generic Programs,  Prev: Particular Programs,  Up: Alternative Programs
- 
- Generic Program Checks
- ----------------------
- 
-    These macros are used to find programs not covered by the particular
- test macros.  If you need to check the behavior of a program as well as
- find out whether it is present, you have to write your own test for it
- (*note Writing Tests::.).  If you need to check for a program that
- might not be in the user's `PATH', you can temporarily add to it:
- 
-      ac_save_path="$PATH"
-      PATH=/usr/libexec:/usr/sbin:/usr/etc:/etc
-      AC_PATH_PROG(INETD, inetd, /usr/libexec/inetd)
-      PATH="$ac_save_path"
- 
-  - Macro: AC_CHECK_PROG (VARIABLE, PROG-TO-CHECK-FOR, VALUE-IF-FOUND [,
-           VALUE-IF-NOT-FOUND])
-      Check whether program PROG-TO-CHECK-FOR exists in `PATH'.  If it
-      is found, set VARIABLE to VALUE-IF-FOUND, otherwise to
-      VALUE-IF-NOT-FOUND, if given.  If VARIABLE was already set, do
-      nothing.  Calls `AC_SUBST' for VARIABLE.
- 
-  - Macro: AC_CHECK_PROGS (VARIABLE, PROGS-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND])
-      Check for each program in the whitespace-separated list
-      PROGS-TO-CHECK-FOR exists in `PATH'.  If it is found, set VARIABLE
-      to the name of that program.  Otherwise, continue checking the
-      next program in the list.  If none of the programs in the list are
-      found, set VARIABLE to VALUE-IF-NOT-FOUND; if VALUE-IF-NOT-FOUND
-      is not specified, the value of VARIABLE is not changed.  Calls
-      `AC_SUBST' for VARIABLE.
- 
-  - Macro: AC_CHECK_TOOL (VARIABLE, PROG-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND])
-      Like `AC_CHECK_PROG', but first looks for PROG-TO-CHECK-FOR with a
-      prefix of the host type as determined by `AC_CANONICAL_HOST',
-      followed by a dash (*note Canonicalizing::.).  For example, if the
-      user runs `configure --host=i386-gnu', then this call:
-           AC_CHECK_TOOL(RANLIB, ranlib, :)
- 
-      sets `RANLIB' to `i386-gnu-ranlib' if that program exists in
-      `PATH', or to `ranlib' if that program exists in `PATH', or to `:'
-      if neither program exists.
- 
-  - Macro: AC_PATH_PROG (VARIABLE, PROG-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND])
-      Like `AC_CHECK_PROG', but set VARIABLE to the entire path of
-      PROG-TO-CHECK-FOR if found.
- 
-  - Macro: AC_PATH_PROGS (VARIABLE, PROGS-TO-CHECK-FOR [,
-           VALUE-IF-NOT-FOUND])
-      Like `AC_CHECK_PROGS', but if any of PROGS-TO-CHECK-FOR are found,
-      set VARIABLE to the entire path of the program found.
- 
- 
- File: autoconf.info,  Node: Libraries,  Next: Library Functions,  Prev: Alternative Programs,  Up: Existing Tests
- 
- Library Files
- =============
- 
-    The following macros check for the presence of certain C library
- archive files.
- 
-  - Macro: AC_CHECK_LIB (LIBRARY, FUNCTION [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-      Try to ensure that C function FUNCTION is available by checking
-      whether a test C program can be linked with the library LIBRARY to
-      get the function.  LIBRARY is the base name of the library; e.g.,
-      to check for `-lmp', use `mp' as the LIBRARY argument.
- 
-      ACTION-IF-FOUND is a list of shell commands to run if the link
-      with the library succeeds; ACTION-IF-NOT-FOUND is a list of shell
-      commands to run if the link fails.  If ACTION-IF-FOUND and
-      ACTION-IF-NOT-FOUND are not specified, the default action is to
-      add `-lLIBRARY' to `LIBS' and define `HAVE_LIBLIBRARY' (in all
-      capitals).
- 
-      If linking with LIBRARY results in unresolved symbols, which would
-      be resolved by linking with additional libraries, give those
-      libraries as the OTHER-LIBRARIES argument, separated by spaces:
-      `-lXt -lX11'.  Otherwise this macro will fail to detect that
-      LIBRARY is present, because linking the test program will always
-      fail with unresolved symbols.
- 
-  - Macro: AC_HAVE_LIBRARY (LIBRARY, [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
-      This macro is equivalent to calling `AC_CHECK_LIB' with a FUNCTION
-      argument of `main'.  In addition, LIBRARY can be written as any of
-      `foo', `-lfoo', or `libfoo.a'.  In all of those cases, the
-      compiler is passed `-lfoo'.  However, LIBRARY can not be a shell
-      variable; it must be a literal name.  This macro is considered
-      obsolete.
- 
- 
- File: autoconf.info,  Node: Library Functions,  Next: Header Files,  Prev: Libraries,  Up: Existing Tests
- 
- Library Functions
- =================
- 
-    The following macros check for particular C library functions.  If
- there is no macro specifically defined to check for a function you need,
- and you don't need to check for any special properties of it, then you
- can use one of the general function check macros.
- 
- * Menu:
- 
- * Particular Functions::        Special handling to find certain functions.
- * Generic Functions::           How to find other functions.
- 
- 
- File: autoconf.info,  Node: Particular Functions,  Next: Generic Functions,  Up: Library Functions
- 
- Particular Function Checks
- --------------------------
- 
-    These macros check for particular C functions--whether they exist,
- and in some cases how they respond when given certain arguments.
- 
-  - Macro: AC_FUNC_ALLOCA
-      Check how to get `alloca'.  Tries to get a builtin version by
-      checking for `alloca.h' or the predefined C preprocessor macros
-      `__GNUC__' and `_AIX'.  If this macro finds `alloca.h', it defines
-      `HAVE_ALLOCA_H'.
- 
-      If those attempts fail, it looks for the function in the standard C
-      library.  If any of those methods succeed, it defines
-      `HAVE_ALLOCA'.  Otherwise, it sets the output variable `ALLOCA' to
-      `alloca.o' and defines `C_ALLOCA' (so programs can periodically
-      call `alloca(0)' to garbage collect).  This variable is separate
-      from `LIBOBJS' so multiple programs can share the value of
-      `ALLOCA' without needing to create an actual library, in case only
-      some of them use the code in `LIBOBJS'.
- 
-      This macro does not try to get `alloca' from the System V R3
-      `libPW' or the System V R4 `libucb' because those libraries
-      contain some incompatible functions that cause trouble.  Some
-      versions do not even contain `alloca' or contain a buggy version.
-      If you still want to use their `alloca', use `ar' to extract
-      `alloca.o' from them instead of compiling `alloca.c'.
- 
-      Source files that use `alloca' should start with a piece of code
-      like the following, to declare it properly.  In some versions of
-      AIX, the declaration of `alloca' must precede everything else
-      except for comments and preprocessor directives.  The `#pragma'
-      directive is indented so that pre-ANSI C compilers will ignore it,
-      rather than choke on it.
- 
-           /* AIX requires this to be the first thing in the file.  */
-           #ifdef __GNUC__
-           # define alloca __builtin_alloca
-           #else
-           # if HAVE_ALLOCA_H
-           #  include <alloca.h>
-           # else
-           #  ifdef _AIX
-            #pragma alloca
-           #  else
-           #   ifndef alloca /* predefined by HP cc +Olibcalls */
-           char *alloca ();
-           #   endif
-           #  endif
-           # endif
-           #endif
- 
-  - Macro: AC_FUNC_CLOSEDIR_VOID
-      If the `closedir' function does not return a meaningful value,
-      define `CLOSEDIR_VOID'.  Otherwise, callers ought to check its
-      return value for an error indicator.
- 
-  - Macro: AC_FUNC_GETLOADAVG
-      Check how to get the system load averages.  If the system has the
-      `getloadavg' function, this macro defines `HAVE_GETLOADAVG', and
-      adds to `LIBS' any libraries needed to get that function.
- 
-      Otherwise, it adds `getloadavg.o' to the output variable
-      `LIBOBJS', and possibly defines several other C preprocessor
-      macros and output variables:
- 
-        1. It defines `SVR4', `DGUX', `UMAX', or `UMAX4_3' if on those
-           systems.
- 
-        2. If it finds `nlist.h', it defines `NLIST_STRUCT'.
- 
-        3. If `struct nlist' has an `n_un' member, it defines
-           `NLIST_NAME_UNION'.
- 
-        4. If compiling `getloadavg.c' defines `LDAV_PRIVILEGED',
-           programs need to be installed specially on this system for
-           `getloadavg' to work, and this macro defines
-           `GETLOADAVG_PRIVILEGED'.
- 
-        5. This macro sets the output variable `NEED_SETGID'.  The value
-           is `true' if special installation is required, `false' if not.
-           If `NEED_SETGID' is `true', this macro sets `KMEM_GROUP' to
-           the name of the group that should own the installed program.
- 
-  - Macro: AC_FUNC_GETMNTENT
-      Check for `getmntent' in the `sun' and `seq' libraries, for Irix 4
-      and PTX, respectively.  Then, if `getmntent' is available, define
-      `HAVE_GETMNTENT'.
- 
-  - Macro: AC_FUNC_GETPGRP
-      If `getpgrp' takes no argument (the POSIX.1 version), define
-      `GETPGRP_VOID'.  Otherwise, it is the BSD version, which takes a
-      process ID as an argument.  This macro does not check whether
-      `getpgrp' exists at all; if you need to work in that situation,
-      first call `AC_CHECK_FUNC' for `getpgrp'.
- 
-  - Macro: AC_FUNC_MEMCMP
-      If the `memcmp' function is not available, or does not work on
-      8-bit data (like the one on SunOS 4.1.3), add `memcmp.o' to output
-      variable `LIBOBJS'.
- 
-  - Macro: AC_FUNC_MMAP
-      If the `mmap' function exists and works correctly on memory mapped
-      files, define `HAVE_MMAP'.
- 
-  - Macro: AC_FUNC_SETVBUF_REVERSED
-      If `setvbuf' takes the buffering type as its second argument and
-      the buffer pointer as the third, instead of the other way around,
-      define `SETVBUF_REVERSED'.  This is the case on System V before
-      release 3.
- 
-  - Macro: AC_FUNC_STRCOLL
-      If the `strcoll' function exists and works correctly, define
-      `HAVE_STRCOLL'.  This does a bit more than
-      `AC_CHECK_FUNCS(strcoll)', because some systems have incorrect
-      definitions of `strcoll', which should not be used.
- 
-  - Macro: AC_FUNC_STRFTIME
-      Check for `strftime' in the `intl' library, for SCO UNIX.  Then,
-      if `strftime' is available, define `HAVE_STRFTIME'.
- 
-  - Macro: AC_FUNC_UTIME_NULL
-      If `utime(FILE, NULL)' sets FILE's timestamp to the present,
-      define `HAVE_UTIME_NULL'.
- 
-  - Macro: AC_FUNC_VFORK
-      If `vfork.h' is found, define `HAVE_VFORK_H'.  If a working
-      `vfork' is not found, define `vfork' to be `fork'.  This macro
-      checks for several known errors in implementations of `vfork' and
-      considers the system to not have a working `vfork' if it detects
-      any of them.  It is not considered to be an implementation error
-      if a child's invocation of `signal' modifies the parent's signal
-      handler, since child processes rarely change their signal handlers.
- 
-  - Macro: AC_FUNC_VPRINTF
-      If `vprintf' is found, define `HAVE_VPRINTF'.  Otherwise, if
-      `_doprnt' is found, define `HAVE_DOPRNT'.  (If `vprintf' is
-      available, you may assume that `vfprintf' and `vsprintf' are also
-      available.)
- 
-  - Macro: AC_FUNC_WAIT3
-      If `wait3' is found and fills in the contents of its third argument
-      (a `struct rusage *'), which HP-UX does not do, define
-      `HAVE_WAIT3'.
- 
- 
- File: autoconf.info,  Node: Generic Functions,  Prev: Particular Functions,  Up: Library Functions
- 
- Generic Function Checks
- -----------------------
- 
-    These macros are used to find functions not covered by the particular
- test macros.  If the functions might be in libraries other than the
- default C library, first call `AC_CHECK_LIB' for those libraries.  If
- you need to check the behavior of a function as well as find out
- whether it is present, you have to write your own test for it (*note
- Writing Tests::.).
- 
-  - Macro: AC_CHECK_FUNC (FUNCTION, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      If C function FUNCTION is available, run shell commands
-      ACTION-IF-FOUND, otherwise ACTION-IF-NOT-FOUND.  If you just want
-      to define a symbol if the function is available, consider using
-      `AC_CHECK_FUNCS' instead.  This macro checks for functions with C
-      linkage even when `AC_LANG_CPLUSPLUS' has been called, since C++ is
-      more standardized than C is.  (*note Language Choice::., for more
-      information about selecting the language for checks.)
- 
-  - Macro: AC_CHECK_FUNCS (FUNCTION... [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      For each given FUNCTION in the whitespace-separated argument list
-      that is available, define `HAVE_FUNCTION' (in all capitals).  If
-      ACTION-IF-FOUND is given, it is additional shell code to execute
-      when one of the functions is found.  You can give it a value of
-      `break' to break out of the loop on the first match.  If
-      ACTION-IF-NOT-FOUND is given, it is executed when one of the
-      functions is not found.
- 
-  - Macro: AC_REPLACE_FUNCS (FUNCTION-NAME...)
-      For each given FUNCTION-NAME in the whitespace-separated argument
-      list that is not in the C library, add `FUNCTION-NAME.o' to the
-      value of the output variable `LIBOBJS'.
- 
- 
- File: autoconf.info,  Node: Header Files,  Next: Structures,  Prev: Library Functions,  Up: Existing Tests
- 
- Header Files
- ============
- 
-    The following macros check for the presence of certain C header
- files.  If there is no macro specifically defined to check for a header
- file you need, and you don't need to check for any special properties of
- it, then you can use one of the general header file check macros.
- 
- * Menu:
- 
- * Particular Headers::          Special handling to find certain headers.
- * Generic Headers::             How to find other headers.
- 
- 
- File: autoconf.info,  Node: Particular Headers,  Next: Generic Headers,  Up: Header Files
- 
- Particular Header Checks
- ------------------------
- 
-    These macros check for particular system header files--whether they
- exist, and in some cases whether they declare certain symbols.
- 
-  - Macro: AC_DECL_SYS_SIGLIST
-      Define `SYS_SIGLIST_DECLARED' if the variable `sys_siglist' is
-      declared in a system header file, either `signal.h' or `unistd.h'.
- 
-  - Macro: AC_DIR_HEADER
-      Like calling `AC_HEADER_DIRENT' and `AC_FUNC_CLOSEDIR_VOID', but
-      defines a different set of C preprocessor macros to indicate which
-      header file is found.  This macro and the names it defines are
-      considered obsolete.  The names it defines are:
- 
-     `dirent.h'
-           `DIRENT'
- 
-     `sys/ndir.h'
-           `SYSNDIR'
- 
-     `sys/dir.h'
-           `SYSDIR'
- 
-     `ndir.h'
-           `NDIR'
- 
-      In addition, if the `closedir' function does not return a
-      meaningful value, define `VOID_CLOSEDIR'.
- 
-  - Macro: AC_HEADER_DIRENT
-      Check for the following header files, and for the first one that is
-      found and defines `DIR', define the listed C preprocessor macro:
- 
-     `dirent.h'
-           `HAVE_DIRENT_H'
- 
-     `sys/ndir.h'
-           `HAVE_SYS_NDIR_H'
- 
-     `sys/dir.h'
-           `HAVE_SYS_DIR_H'
- 
-     `ndir.h'
-           `HAVE_NDIR_H'
- 
-      The directory library declarations in the source code should look
-      something like the following:
- 
-           #if HAVE_DIRENT_H
-           # include <dirent.h>
-           # define NAMLEN(dirent) strlen((dirent)->d_name)
-           #else
-           # define dirent direct
-           # define NAMLEN(dirent) (dirent)->d_namlen
-           # if HAVE_SYS_NDIR_H
-           #  include <sys/ndir.h>
-           # endif
-           # if HAVE_SYS_DIR_H
-           #  include <sys/dir.h>
-           # endif
-           # if HAVE_NDIR_H
-           #  include <ndir.h>
-           # endif
-           #endif
- 
-      Using the above declarations, the program would declare variables
-      to be type `struct dirent', not `struct direct', and would access
-      the length of a directory entry name by passing a pointer to a
-      `struct dirent' to the `NAMLEN' macro.
- 
-      This macro also checks for the SCO Xenix `dir' and `x' libraries.
- 
-  - Macro: AC_HEADER_MAJOR
-      If `sys/types.h' does not define `major', `minor', and `makedev',
-      but `sys/mkdev.h' does, define `MAJOR_IN_MKDEV'; otherwise, if
-      `sys/sysmacros.h' does, define `MAJOR_IN_SYSMACROS'.
- 
-  - Macro: AC_HEADER_STDC
-      Define `STDC_HEADERS' if the system has ANSI C header files.
-      Specifically, this macro checks for `stdlib.h', `stdarg.h',
-      `string.h', and `float.h'; if the system has those, it probably
-      has the rest of the ANSI C header files.  This macro also checks
-      whether `string.h' declares `memchr' (and thus presumably the
-      other `mem' functions), whether `stdlib.h' declare `free' (and
-      thus presumably `malloc' and other related functions), and whether
-      the `ctype.h' macros work on characters with the high bit set, as
-      ANSI C requires.
- 
-      Use `STDC_HEADERS' instead of `__STDC__' to determine whether the
-      system has ANSI-compliant header files (and probably C library
-      functions) because many systems that have GCC do not have ANSI C
-      header files.
- 
-      On systems without ANSI C headers, there is so much variation that
-      it is probably easier to declare the functions you use than to
-      figure out exactly what the system header files declare.  Some
-      systems contain a mix of functions ANSI and BSD; some are mostly
-      ANSI but lack `memmove'; some define the BSD functions as macros in
-      `string.h' or `strings.h'; some have only the BSD functions but
-      `string.h'; some declare the memory functions in `memory.h', some
-      in `string.h'; etc.  It is probably sufficient to check for one
-      string function and one memory function; if the library has the
-      ANSI versions of those then it probably has most of the others.
-      If you put the following in `configure.in':
- 
-           AC_HEADER_STDC
-           AC_CHECK_FUNCS(strchr memcpy)
- 
-      then, in your code, you can put declarations like this:
- 
-           #if STDC_HEADERS
-           # include <string.h>
-           #else
-           # ifndef HAVE_STRCHR
-           #  define strchr index
-           #  define strrchr rindex
-           # endif
-           char *strchr (), *strrchr ();
-           # ifndef HAVE_MEMCPY
-           #  define memcpy(d, s, n) bcopy ((s), (d), (n))
-           #  define memmove(d, s, n) bcopy ((s), (d), (n))
-           # endif
-           #endif
- 
-      If you use a function like `memchr', `memset', `strtok', or
-      `strspn', which have no BSD equivalent, then macros won't suffice;
-      you must provide an implementation of each function.  An easy way
-      to incorporate your implementations only when needed (since the
-      ones in system C libraries may be hand optimized) is to, taking
-      `memchr' for example, put it in `memchr.c' and use
-      `AC_REPLACE_FUNCS(memchr)'.
- 
-  - Macro: AC_HEADER_SYS_WAIT
-      If `sys/wait.h' exists and is compatible with POSIX.1, define
-      `HAVE_SYS_WAIT_H'.  Incompatibility can occur if `sys/wait.h' does
-      not exist, or if it uses the old BSD `union wait' instead of `int'
-      to store a status value.  If `sys/wait.h' is not POSIX.1
-      compatible, then instead of including it, define the POSIX.1
-      macros with their usual interpretations.  Here is an example:
- 
-           #include <sys/types.h>
-           #if HAVE_SYS_WAIT_H
-           # include <sys/wait.h>
-           #endif
-           #ifndef WEXITSTATUS
-           # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-           #endif
-           #ifndef WIFEXITED
-           # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
-           #endif
- 
-  - Macro: AC_MEMORY_H
-      Define `NEED_MEMORY_H' if `memcpy', `memcmp', etc. are not
-      declared in `string.h' and `memory.h' exists.  This macro is
-      obsolete; instead, use `AC_CHECK_HEADERS(memory.h)'.  See the
-      example for `AC_HEADER_STDC'.
- 
-  - Macro: AC_UNISTD_H
-      Define `HAVE_UNISTD_H' if the system has `unistd.h'.  This macro
-      is obsolete; instead, use `AC_CHECK_HEADERS(unistd.h)'.
- 
-      The way to check if the system supports POSIX.1 is:
- 
-           #if HAVE_UNISTD_H
-           # include <sys/types.h>
-           # include <unistd.h>
-           #endif
-           
-           #ifdef _POSIX_VERSION
-           /* Code for POSIX.1 systems.  */
-           #endif
- 
-      `_POSIX_VERSION' is defined when `unistd.h' is included on POSIX.1
-      systems.  If there is no `unistd.h', it is definitely not a
-      POSIX.1 system.  However, some non-POSIX.1 systems do have
-      `unistd.h'.
- 
-  - Macro: AC_USG
-      Define `USG' if the system does not have `strings.h', `rindex',
-      `bzero', etc.  This implies that it has `string.h', `strrchr',
-      `memset', etc.
- 
-      The symbol `USG' is obsolete.  Instead of this macro, see the
-      example for `AC_HEADER_STDC'.
- 
- 
- File: autoconf.info,  Node: Generic Headers,  Prev: Particular Headers,  Up: Header Files
- 
- Generic Header Checks
- ---------------------
- 
-    These macros are used to find system header files not covered by the
- particular test macros.  If you need to check the contents of a header
- as well as find out whether it is present, you have to write your own
- test for it (*note Writing Tests::.).
- 
-  - Macro: AC_CHECK_HEADER (HEADER-FILE, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      If the system header file HEADER-FILE exists, execute shell
-      commands ACTION-IF-FOUND, otherwise execute ACTION-IF-NOT-FOUND.
-      If you just want to define a symbol if the header file is
-      available, consider using `AC_CHECK_HEADERS' instead.
- 
-  - Macro: AC_CHECK_HEADERS (HEADER-FILE... [, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND]])
-      For each given system header file HEADER-FILE in the
-      whitespace-separated argument list that exists, define
-      `HAVE_HEADER-FILE' (in all capitals).  If ACTION-IF-FOUND is
-      given, it is additional shell code to execute when one of the
-      header files is found.  You can give it a value of `break' to
-      break out of the loop on the first match.  If ACTION-IF-NOT-FOUND
-      is given, it is executed when one of the header files is not found.
- 
- 
- File: autoconf.info,  Node: Structures,  Next: Typedefs,  Prev: Header Files,  Up: Existing Tests
- 
- Structures
- ==========
- 
-    The following macros check for certain structures or structure
- members.  To check structures not listed here, use `AC_EGREP_CPP'
- (*note Examining Declarations::.) or `AC_TRY_COMPILE' (*note Examining
- Syntax::.).
- 
-  - Macro: AC_HEADER_STAT
-      If the macros `S_ISDIR', `S_ISREG' et al. defined in `sys/stat.h'
-      do not work properly (returning false positives), define
-      `STAT_MACROS_BROKEN'.  This is the case on Tektronix UTekV, Amdahl
-      UTS and Motorola System V/88.
- 
-  - Macro: AC_HEADER_TIME
-      If a program may include both `time.h' and `sys/time.h', define
-      `TIME_WITH_SYS_TIME'.  On some older systems, `sys/time.h'
-      includes `time.h', but `time.h' is not protected against multiple
-      inclusion, so programs should not explicitly include both files.
-      This macro is useful in programs that use, for example, `struct
-      timeval' or `struct timezone' as well as `struct tm'.  It is best
-      used in conjunction with `HAVE_SYS_TIME_H', which can be checked
-      for using `AC_CHECK_HEADERS(sys/time.h)'.
- 
-           #if TIME_WITH_SYS_TIME
-           # include <sys/time.h>
-           # include <time.h>
-           #else
-           # if HAVE_SYS_TIME_H
-           #  include <sys/time.h>
-           # else
-           #  include <time.h>
-           # endif
-           #endif
- 
-  - Macro: AC_STRUCT_ST_BLKSIZE
-      If `struct stat' contains an `st_blksize' member, define
-      `HAVE_ST_BLKSIZE'.
- 
-  - Macro: AC_STRUCT_ST_BLOCKS
-      If `struct stat' contains an `st_blocks' member, define
-      `HAVE_ST_BLOCKS'.  Otherwise, add `fileblocks.o' to the output
-      variable `LIBOBJS'.
- 
-  - Macro: AC_STRUCT_ST_RDEV
-      If `struct stat' contains an `st_rdev' member, define
-      `HAVE_ST_RDEV'.
- 
-  - Macro: AC_STRUCT_TM
-      If `time.h' does not define `struct tm', define `TM_IN_SYS_TIME',
-      which means that including `sys/time.h' had better define `struct
-      tm'.
- 
-  - Macro: AC_STRUCT_TIMEZONE
-      Figure out how to get the current timezone.  If `struct tm' has a
-      `tm_zone' member, define `HAVE_TM_ZONE'.  Otherwise, if the
-      external array `tzname' is found, define `HAVE_TZNAME'.
- 
- 
- File: autoconf.info,  Node: Typedefs,  Next: Compiler Characteristics,  Prev: Structures,  Up: Existing Tests
- 
- Typedefs
- ========
- 
-    The following macros check for C typedefs.  If there is no macro
- specifically defined to check for a typedef you need, and you don't need
- to check for any special properties of it, then you can use a general
- typedef check macro.
- 
- * Menu:
- 
- * Particular Typedefs::         Special handling to find certain types.
- * Generic Typedefs::            How to find other types.
- 
- 
- File: autoconf.info,  Node: Particular Typedefs,  Next: Generic Typedefs,  Up: Typedefs
- 
- Particular Typedef Checks
- -------------------------
- 
-    These macros check for particular C typedefs in `sys/types.h' and
- `stdlib.h' (if it exists).
- 
-  - Macro: AC_TYPE_GETGROUPS
-      Define `GETGROUPS_T' to be whichever of `gid_t' or `int' is the
-      base type of the array argument to `getgroups'.
- 
-  - Macro: AC_TYPE_MODE_T
-      If `mode_t' is not defined, define `mode_t' to be `int'.
- 
-  - Macro: AC_TYPE_OFF_T
-      If `off_t' is not defined, define `off_t' to be `long'.
- 
-  - Macro: AC_TYPE_PID_T
-      If `pid_t' is not defined, define `pid_t' to be `int'.
- 
-  - Macro: AC_TYPE_SIGNAL
-      If `signal.h' declares `signal' as returning a pointer to a
-      function returning `void', define `RETSIGTYPE' to be `void';
-      otherwise, define it to be `int'.
- 
-      Define signal handlers as returning type `RETSIGTYPE':
- 
-           RETSIGTYPE
-           hup_handler ()
-           {
-           ...
-           }
- 
-  - Macro: AC_TYPE_SIZE_T
-      If `size_t' is not defined, define `size_t' to be `unsigned'.
- 
-  - Macro: AC_TYPE_UID_T
-      If `uid_t' is not defined, define `uid_t' to be `int' and `gid_t'
-      to be `int'.
- 
- 
- File: autoconf.info,  Node: Generic Typedefs,  Prev: Particular Typedefs,  Up: Typedefs
- 
- Generic Typedef Checks
- ----------------------
- 
-    This macro is used to check for typedefs not covered by the
- particular test macros.
- 
-  - Macro: AC_CHECK_TYPE (TYPE, DEFAULT)
-      If the type TYPE is not defined in `sys/types.h' or `stdlib.h' (if
-      it exists), define it to be the C (or C++) builtin type DEFAULT;
-      e.g., `short' or `unsigned'.
- 
- 
- File: autoconf.info,  Node: Compiler Characteristics,  Next: System Services,  Prev: Typedefs,  Up: Existing Tests
- 
- Compiler Characteristics
- ========================
- 
-    The following macros check for C compiler or machine architecture
- features.  To check for characteristics not listed here, use
- `AC_TRY_COMPILE' (*note Examining Syntax::.) or `AC_TRY_RUN' (*note Run
- Time::.)
- 
-  - Macro: AC_C_BIGENDIAN
-      If words are stored with the most significant byte first (like
-      Motorola and SPARC, but not Intel and VAX, CPUs), define
-      `WORDS_BIGENDIAN'.
- 
-  - Macro: AC_C_CONST
-      If the C compiler does not fully support the keyword `const',
-      define `const' to be empty.  Some C compilers that do not define
-      `__STDC__' do support `const'; some compilers that define
-      `__STDC__' do not completely support `const'.  Programs can simply
-      use `const' as if every C compiler supported it; for those that
-      don't, the `Makefile' or configuration header file will define it
-      as empty.
- 
-  - Macro: AC_C_INLINE
-      If the C compiler supports the keyword `inline', do nothing.
-      Otherwise define `inline' to `__inline__' or `__inline' if it
-      accepts one of those, otherwise define `inline' to be empty.
- 
-  - Macro: AC_C_CHAR_UNSIGNED
-      If the C type `char' is unsigned, define `__CHAR_UNSIGNED__',
-      unless the C compiler predefines it.
- 
-  - Macro: AC_C_LONG_DOUBLE
-      If the C compiler supports the `long double' type, define
-      `HAVE_LONG_DOUBLE'.  Some C compilers that do not define
-      `__STDC__' do support the `long double' type; some compilers that
-      define `__STDC__' do not support `long double'.
- 
-  - Macro: AC_CHECK_SIZEOF (TYPE)
-      Define `SIZEOF_UCTYPE' to be the size in bytes of the C (or C++)
-      builtin type TYPE, e.g. `int' or `char *'.  If `type' is unknown
-      to the compiler, it gets a size of 0.  UCTYPE is TYPE, with
-      lowercase converted to uppercase, spaces changed to underscores,
-      and asterisks changed to `P'.  For example, the call
-           AC_CHECK_SIZEOF(int *)
- 
-      defines `SIZEOF_INT_P' to be 8 on DEC Alpha AXP systems.
- 
-  - Macro: AC_INT_16_BITS
-      If the C type `int' is 16 bits wide, define `INT_16_BITS'.  This
-      macro is obsolete; it is more general to use
-      `AC_CHECK_SIZEOF(int)' instead.
- 
-  - Macro: AC_LONG_64_BITS
-      If the C type `long int' is 64 bits wide, define `LONG_64_BITS'.
-      This macro is obsolete; it is more general to use
-      `AC_CHECK_SIZEOF(long)' instead.
- 
- 
- File: autoconf.info,  Node: System Services,  Next: UNIX Variants,  Prev: Compiler Characteristics,  Up: Existing Tests
- 
- System Services
- ===============
- 
-    The following macros check for operating system services or
- capabilities.
- 
-  - Macro: AC_SYS_INTERPRETER
-      Check whether the system supports starting scripts with a line of
-      the form `#! /bin/csh' to select the interpreter to use for the
-      script.  After running this macro, shell code in `configure.in'
-      can check the variable `ac_cv_sys_interpreter'; it will be set to
-      `yes' if the system supports `#!', `no' if not.
- 
-  - Macro: AC_PATH_X
-      Try to locate the X Window System include files and libraries.  If
-      the user gave the command line options `--x-includes=DIR' and
-      `--x-libraries=DIR', use those directories.  If either or both
-      were not given, get the missing values by running `xmkmf' on a
-      trivial `Imakefile' and examining the `Makefile' that it produces.
-      If that fails (such as if `xmkmf' is not present), look for them
-      in several directories where they often reside.  If either method
-      is successful, set the shell variables `x_includes' and
-      `x_libraries' to their locations, unless they are in directories
-      the compiler searches by default.
- 
-      If both methods fail, or the user gave the command line option
-      `--without-x', set the shell variable `no_x' to `yes'; otherwise
-      set it to the empty string.
- 
-  - Macro: AC_PATH_XTRA
-      An enhanced version of `AC_PATH_X'.  It adds the C compiler flags
-      that X needs to output variable `X_CFLAGS', and the X linker flags
-      to `X_LIBS'.  If X is not available, adds `-DX_DISPLAY_MISSING' to
-      `X_CFLAGS'.
- 
-      This macro also checks for special libraries that some systems
-      need in order to compile X programs.  It adds any that the system
-      needs to output variable `X_EXTRA_LIBS'.  And it checks for
-      special X11R6 libraries that need to be linked with before
-      `-lX11', and adds any found to the output variable `X_PRE_LIBS'.
- 
- 
-  - Macro: AC_SYS_LONG_FILE_NAMES
-      If the system supports file names longer than 14 characters, define
-      `HAVE_LONG_FILE_NAMES'.
- 
-  - Macro: AC_SYS_RESTARTABLE_SYSCALLS
-      If the system automatically restarts a system call that is
-      interrupted by a signal, define `HAVE_RESTARTABLE_SYSCALLS'.
- 
- 
- File: autoconf.info,  Node: UNIX Variants,  Prev: System Services,  Up: Existing Tests
- 
- UNIX Variants
- =============
- 
-    The following macros check for certain operating systems that need
- special treatment for some programs, due to exceptional oddities in
- their header files or libraries.  These macros are warts; they will be
- replaced by a more systematic approach, based on the functions they make
- available or the environments they provide.
- 
-  - Macro: AC_AIX
-      If on AIX, define `_ALL_SOURCE'.  Allows the use of some BSD
-      functions.  Should be called before any macros that run the C
-      compiler.
- 
-  - Macro: AC_DYNIX_SEQ
-      If on Dynix/PTX (Sequent UNIX), add `-lseq' to output variable
-      `LIBS'.  This macro is obsolete; instead, use `AC_FUNC_GETMNTENT'.
- 
-  - Macro: AC_IRIX_SUN
-      If on IRIX (Silicon Graphics UNIX), add `-lsun' to output variable
-      `LIBS'.  This macro is obsolete.  If you were using it to get
-      `getmntent', use `AC_FUNC_GETMNTENT' instead.  If you used it for
-      the NIS versions of the password and group functions, use
-      `AC_CHECK_LIB(sun, getpwnam)'.
- 
-  - Macro: AC_ISC_POSIX
-      If on a POSIXized ISC UNIX, define `_POSIX_SOURCE' and add
-      `-posix' (for the GNU C compiler) or `-Xp' (for other C compilers)
-      to output variable `CC'.  This allows the use of POSIX facilities.
-      Must be called after `AC_PROG_CC' and before any other macros
-      that run the C compiler.
- 
-  - Macro: AC_MINIX
-      If on Minix, define `_MINIX' and `_POSIX_SOURCE' and define
-      `_POSIX_1_SOURCE' to be 2.  This allows the use of POSIX
-      facilities.  Should be called before any macros that run the C
-      compiler.
- 
-  - Macro: AC_SCO_INTL
-      If on SCO UNIX, add `-lintl' to output variable `LIBS'.  This
-      macro is obsolete; instead, use `AC_FUNC_STRFTIME'.
- 
-  - Macro: AC_XENIX_DIR
-      If on Xenix, add `-lx' to output variable `LIBS'.  Also, if
-      `dirent.h' is being used, add `-ldir' to `LIBS'.  This macro is
-      obsolete; use `AC_HEADER_DIRENT' instead.
- 
- 
- File: autoconf.info,  Node: Writing Tests,  Next: Results,  Prev: Existing Tests,  Up: Top
- 
- Writing Tests
- *************
- 
-    If the existing feature tests don't do something you need, you have
- to write new ones.  These macros are the building blocks.  They provide
- ways for other macros to check whether various kinds of features are
- available and report the results.
- 
-    This chapter contains some suggestions and some of the reasons why
- the existing tests are written the way they are.  You can also learn a
- lot about how to write Autoconf tests by looking at the existing ones.
- If something goes wrong in one or more of the Autoconf tests, this
- information can help you understand the assumptions behind them, which
- might help you figure out how to best solve the problem.
- 
-    These macros check the output of the C compiler system.  They do not
- cache the results of their tests for future use (*note Caching
- Results::.), because they don't know enough about the information they
- are checking for to generate a cache variable name.  They also do not
- print any messages, for the same reason.  The checks for particular
- kinds of C features call these macros and do cache their results and
- print messages about what they're checking for.
- 
-    When you write a feature test that could be applicable to more than
- one software package, the best thing to do is encapsulate it in a new
- macro.  *Note Writing Macros::, for how to do that.
- 
- * Menu:
- 
- * Examining Declarations::	Detecting header files and declarations.
- * Examining Syntax::            Detecting language syntax features.
- * Examining Libraries::         Detecting functions and global variables.
- * Run Time::		        Testing for run-time features.
- * Portable Shell::              Shell script portability pitfalls.
- * Testing Values and Files::    Checking strings and files.
- * Multiple Cases::		Tests for several possible values.
- * Language Choice::             Selecting which language to use for testing.
- 
- 
- File: autoconf.info,  Node: Examining Declarations,  Next: Examining Syntax,  Up: Writing Tests
- 
- Examining Declarations
- ======================
- 
-    The macro `AC_TRY_CPP' is used to check whether particular header
- files exist.  You can check for one at a time, or more than one if you
- need several header files to all exist for some purpose.
- 
-  - Macro: AC_TRY_CPP (INCLUDES, ACTION-IF-TRUE [, ACTION-IF-FALSE])
-      INCLUDES is C or C++ `#include' statements and declarations, on
-      which shell variable, backquote, and backslash substitutions are
-      performed.  (Actually, it can be any C program, but other
-      statements are probably not useful.)  If the preprocessor produces
-      no error messages while processing it, run shell commands
-      ACTION-IF-TRUE.  Otherwise run shell commands ACTION-IF-FALSE.
- 
-      This macro uses `CPPFLAGS', but not `CFLAGS', because `-g', `-O',
-      etc. are not valid options to many C preprocessors.
- 
-    Here is now to find out whether a header file contains a particular
- declaration, such as a typedef, a structure, a structure member, or a
- function.  Use `AC_EGREP_HEADER' instead of running `grep' directly on
- the header file; on some systems the symbol might be defined in another
- header file that the file you are checking `#include's.
- 
-  - Macro: AC_EGREP_HEADER (PATTERN, HEADER-FILE, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      If the output of running the preprocessor on the system header file
-      HEADER-FILE matches the `egrep' regular expression PATTERN,
-      execute shell commands ACTION-IF-FOUND, otherwise execute
-      ACTION-IF-NOT-FOUND.
- 
-    To check for C preprocessor symbols, either defined by header files
- or predefined by the C preprocessor, use `AC_EGREP_CPP'.  Here is an
- example of the latter:
- 
-      AC_EGREP_CPP(yes,
-      [#ifdef _AIX
-        yes
-      #endif
-      ], is_aix=yes, is_aix=no)
- 
-  - Macro: AC_EGREP_CPP (PATTERN, PROGRAM, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      PROGRAM is the text of a C or C++ program, on which shell
-      variable, backquote, and backslash substitutions are performed.
-      If the output of running the preprocessor on PROGRAM matches the
-      `egrep' regular expression PATTERN, execute shell commands
-      ACTION-IF-FOUND, otherwise execute ACTION-IF-NOT-FOUND.
- 
-      This macro calls `AC_PROG_CPP' or `AC_PROG_CXXCPP' (depending on
-      which language is current, *note Language Choice::.), if it hasn't
-      been called already.
- 
- 
- File: autoconf.info,  Node: Examining Syntax,  Next: Examining Libraries,  Prev: Examining Declarations,  Up: Writing Tests
- 
- Examining Syntax
- ================
- 
-    To check for a syntax feature of the C or C++ compiler, such as
- whether it recognizes a certain keyword, use `AC_TRY_COMPILE' to try to
- compile a small program that uses that feature.  You can also use it to
- check for structures and structure members that are not present on all
- systems.
- 
-  - Macro: AC_TRY_COMPILE (INCLUDES, FUNCTION-BODY, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      Create a test C program to see whether a function whose body
-      consists of FUNCTION-BODY can be compiled; INCLUDES is any
-      `#include' statements needed by the code in FUNCTION-BODY.  If the
-      file compiles successfully, run shell commands ACTION-IF-FOUND,
-      otherwise run ACTION-IF-NOT-FOUND.  This macro uses `CFLAGS' or
-      `CXXFLAGS', and `CPPFLAGS', when compiling.  It does not try to
-      link; use `AC_TRY_LINK' if you need to do that (*note Examining
-      Libraries::.).
- 
--- 0 ----
Index: krb5/util/autoconf/autoconf.info-3
diff -c krb5/util/autoconf/autoconf.info-3:1.1.1.1 krb5/util/autoconf/autoconf.info-3:removed
*** krb5/util/autoconf/autoconf.info-3:1.1.1.1	Mon Jun  2 17:58:30 1997
--- krb5/util/autoconf/autoconf.info-3	Sun Mar 16 20:22:40 2003
***************
*** 1,1192 ****
- This is Info file autoconf.info, produced by Makeinfo-1.55 from the
- input file autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Examining Libraries,  Next: Run Time,  Prev: Examining Syntax,  Up: Writing Tests
- 
- Examining Libraries
- ===================
- 
-    To check for a library, a function, or a global variable, Autoconf
- `configure' scripts try to compile and link a small program that uses
- it.  This is unlike Metaconfig, which by default uses `nm' or `ar' on
- the C library to try to figure out which functions are available.
- Trying to link with the function is usually a more reliable approach
- because it avoids dealing with the variations in the options and output
- formats of `nm' and `ar' and in the location of the standard libraries.
- It also allows configuring for cross-compilation or checking a
- function's runtime behavior if needed.  On the other hand, it can be
- slower than scanning the libraries once.
- 
-    A few systems have linkers that do not return a failure exit status
- when there are unresolved functions in the link.  This bug makes the
- configuration scripts produced by Autoconf unusable on those systems.
- However, some of them can be given options that make the exit status
- correct.  This is a problem that Autoconf does not currently handle
- automatically.  If users encounter this problem, they might be able to
- solve it by setting `LDFLAGS' in the environment to pass whatever
- options the linker needs (for example, `-Wl,-dn' on MIPS RISC/OS).
- 
-    `AC_TRY_LINK' is used to compile test programs to test for functions
- and global variables.  It is also used (by `AC_CHECK_LIB') to check for
- libraries, by adding the library being checked for to `LIBS'
- temporarily and trying to link a small program.
- 
-  - Macro: AC_TRY_LINK (INCLUDES, FUNCTION-BODY, ACTION-IF-FOUND [,
-           ACTION-IF-NOT-FOUND])
-      Create a test C program to see whether a function whose body
-      consists of FUNCTION-BODY can be compiled and linked; INCLUDES is
-      any `#include' statements needed by the code in FUNCTION-BODY.  If
-      the file compiles and links successfully, run shell commands
-      ACTION-IF-FOUND, otherwise run ACTION-IF-NOT-FOUND.  This macro
-      uses `CFLAGS' or `CXXFLAGS', `CPPFLAGS', `LDFLAGS', and `LIBS'
-      when compiling.
- 
-  - Macro: AC_COMPILE_CHECK (ECHO-TEXT, INCLUDES, FUNCTION-BODY,
-           ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
-      This is an obsolete version of `AC_TRY_LINK', with the addition
-      that it prints `checking for ECHO-TEXT' to the standard output
-      first, if ECHO-TEXT is non-empty.  Use `AC_MSG_CHECKING' and
-      `AC_MSG_RESULT' instead to print messages (*note Printing
-      Messages::.).
- 
- 
- File: autoconf.info,  Node: Run Time,  Next: Portable Shell,  Prev: Examining Libraries,  Up: Writing Tests
- 
- Checking Run Time Behavior
- ==========================
- 
-    Sometimes you need to find out how a system performs at run time,
- such as whether a given function has a certain capability or bug.  If
- you can, make such checks when your program runs instead of when it is
- configured.  You can check for things like the machine's endianness when
- your program initializes itself.
- 
-    If you really need to test for a run-time behavior while configuring,
- you can write a test program to determine the result, and compile and
- run it using `AC_TRY_RUN'.  Avoid running test programs if possible,
- because using them prevents people from configuring your package for
- cross-compiling.
- 
- * Menu:
- 
- * Test Programs::               Running test programs.
- * Guidelines::			General rules for writing test programs.
- * Test Functions::		Avoiding pitfalls in test programs.
- 
- 
- File: autoconf.info,  Node: Test Programs,  Next: Guidelines,  Up: Run Time
- 
- Running Test Programs
- ---------------------
- 
-    Use the following macro if you need to test run-time behavior of the
- system while configuring.
- 
-  - Macro: AC_TRY_RUN (PROGRAM, ACTION-IF-TRUE [, ACTION-IF-FALSE [,
-           ACTION-IF-CROSS-COMPILING]])
-      PROGRAM is the text of a C program, on which shell variable and
-      backquote substitutions are performed.  If it compiles and links
-      successfully and returns an exit status of 0 when executed, run
-      shell commands ACTION-IF-TRUE.  Otherwise run shell commands
-      ACTION-IF-FALSE; the exit status of the program is available in
-      the shell variable `$?'.  This macro uses `CFLAGS' or `CXXFLAGS',
-      `CPPFLAGS', `LDFLAGS', and `LIBS' when compiling.
- 
-      If the C compiler being used does not produce executables that run
-      on the system where `configure' is being run, then the test
-      program is not run.  If the optional shell commands
-      ACTION-IF-CROSS-COMPILING are given, they are run instead and this
-      macro calls `AC_C_CROSS' if it has not already been called.
-      Otherwise, `configure' prints an error message and exits.
- 
-    Try to provide a pessimistic default value to use when
- cross-compiling makes run-time tests impossible.  You do this by
- passing the optional last argument to `AC_TRY_RUN'.  `autoconf' prints
- a warning message when creating `configure' each time it encounters a
- call to `AC_TRY_RUN' with no ACTION-IF-CROSS-COMPILING argument given.
- You may ignore the warning, though users will not be able to configure
- your package for cross-compiling.  A few of the macros distributed with
- Autoconf produce this warning message.
- 
-    To configure for cross-compiling you can also choose a value for
- those parameters based on the canonical system name (*note Manual
- Configuration::.).  Alternatively, set up a test results cache file with
- the correct values for the target system (*note Caching Results::.).
- 
-    To provide a default for calls of `AC_TRY_RUN' that are embedded in
- other macros, including a few of the ones that come with Autoconf, you
- can call `AC_C_CROSS' before running them.  Then, if the shell variable
- `cross_compiling' is set to `yes', use an alternate method to get the
- results instead of calling the macros.
- 
-  - Macro: AC_C_CROSS
-      If the C compiler being used does not produce executables that can
-      run on the system where `configure' is being run, set the shell
-      variable `cross_compiling' to `yes', otherwise `no'.
- 
- 
- File: autoconf.info,  Node: Guidelines,  Next: Test Functions,  Prev: Test Programs,  Up: Run Time
- 
- Guidelines for Test Programs
- ----------------------------
- 
-    Test programs should not write anything to the standard output.  They
- should return 0 if the test succeeds, nonzero otherwise, so that success
- can be distinguished easily from a core dump or other failure;
- segmentation violations and other failures produce a nonzero exit
- status.  Test programs should `exit', not `return', from `main',
- because on some systems (old Suns, at least) the argument to `return'
- in `main' is ignored.
- 
-    Test programs can use `#if' or `#ifdef' to check the values of
- preprocessor macros defined by tests that have already run.  For
- example, if you call `AC_HEADER_STDC', then later on in `configure.in'
- you can have a test program that includes an ANSI C header file
- conditionally:
- 
-      #if STDC_HEADERS
-      # include <stdlib.h>
-      #endif
- 
-    If a test program needs to use or create a data file, give it a name
- that starts with `conftest', such as `conftestdata'.  The `configure'
- script cleans up by running `rm -rf conftest*' after running test
- programs and if the script is interrupted.
- 
- 
- File: autoconf.info,  Node: Test Functions,  Prev: Guidelines,  Up: Run Time
- 
- Test Functions
- --------------
- 
-    Function declarations in test programs should have a prototype
- conditionalized for C++.  In practice, though, test programs rarely need
- functions that take arguments.
- 
-      #ifdef __cplusplus
-      foo(int i)
-      #else
-      foo(i) int i;
-      #endif
- 
-    Functions that test programs declare should also be conditionalized
- for C++, which requires `extern "C"' prototypes.  Make sure to not
- include any header files containing clashing prototypes.
- 
-      #ifdef __cplusplus
-      extern "C" void *malloc(size_t);
-      #else
-      char *malloc();
-      #endif
- 
-    If a test program calls a function with invalid parameters (just to
- see whether it exists), organize the program to ensure that it never
- invokes that function.  You can do this by calling it in another
- function that is never invoked.  You can't do it by putting it after a
- call to `exit', because GCC version 2 knows that `exit' never returns
- and optimizes out any code that follows it in the same block.
- 
-    If you include any header files, make sure to call the functions
- relevant to them with the correct number of arguments, even if they are
- just 0, to avoid compilation errors due to prototypes.  GCC version 2
- has internal prototypes for several functions that it automatically
- inlines; for example, `memcpy'.  To avoid errors when checking for
- them, either pass them the correct number of arguments or redeclare them
- with a different return type (such as `char').
- 
- 
- File: autoconf.info,  Node: Portable Shell,  Next: Testing Values and Files,  Prev: Run Time,  Up: Writing Tests
- 
- Portable Shell Programming
- ==========================
- 
-    When writing your own checks, there are some shell script programming
- techniques you should avoid in order to make your code portable.  The
- Bourne shell and upward-compatible shells like Bash and the Korn shell
- have evolved over the years, but to prevent trouble, do not take
- advantage of features that were added after UNIX version 7, circa 1977.
- You should not use shell functions, aliases, negated character classes,
- or other features that are not found in all Bourne-compatible shells;
- restrict yourself to the lowest common denominator.  Even `unset' is
- not supported by all shells!  Also, include a space after the
- exclamation point in interpreter specifications, like this:
-      #! /usr/bin/perl
-    If you omit the space before the path, then 4.2BSD based systems
- (such as Sequent DYNIX) will ignore the line, because they interpret
- `#! /' as a 4-byte magic number.
- 
-    The set of external programs you should run in a `configure' script
- is fairly small.  *Note Utilities in Makefiles:
- (standards.info)Utilities in Makefiles, for the list.  This restriction
- allows users to start out with a fairly small set of programs and build
- the rest, avoiding too many interdependencies between packages.
- 
-    Some of these external utilities have a portable subset of features,
- as well; for example, don't rely on `ln' having a `-f' option or `cat'
- having any options.  `sed' scripts should not contain comments or use
- branch labels longer than 8 characters.  Don't use `grep -s' to
- suppress output, because `grep -s' on System V does not suppress
- output, only error messages.  Instead, redirect the standard output and
- standard error (in case the file doesn't exist) of `grep' to
- `/dev/null'.  Check the exit status of `grep' to determine whether it
- found a match.
- 
- 
- File: autoconf.info,  Node: Testing Values and Files,  Next: Multiple Cases,  Prev: Portable Shell,  Up: Writing Tests
- 
- Testing Values and Files
- ========================
- 
-    `configure' scripts need to test properties of many files and
- strings.  Here are some portability problems to watch out for when doing
- those tests.
- 
-    The `test' program is the way to perform many file and string tests.
- It is often invoked by the alternate name `[', but using that name in
- Autoconf code is asking for trouble since it is an `m4' quote character.
- 
-    If you need to make multiple checks using `test', combine them with
- the shell operators `&&' and `||' instead of using the `test' operators
- `-a' and `-o'.  On System V, the precedence of `-a' and `-o' is wrong
- relative to the unary operators; consequently, POSIX does not specify
- them, so using them is nonportable.  If you combine `&&' and `||' in
- the same statement, keep in mind that they have equal precedence.
- 
-    To enable `configure' scripts to support cross-compilation, they
- shouldn't do anything that tests features of the host system instead of
- the target system.  But occasionally you may find it necessary to check
- whether some arbitrary file exists.  To do so, use `test -f' or `test
- -r'.  Do not use `test -x', because 4.3BSD does not have it.
- 
-    Another nonportable shell programming construction is
-      VAR=${VAR:-VALUE}
- 
- The intent is to set VAR to VALUE only if it is not already set, but if
- VAR has any value, even the empty string, to leave it alone.  Old BSD
- shells, including the Ultrix `sh', don't accept the colon, and complain
- and die.  A portable equivalent is
-      : ${VAR=VALUE}
- 
- 
- File: autoconf.info,  Node: Multiple Cases,  Next: Language Choice,  Prev: Testing Values and Files,  Up: Writing Tests
- 
- Multiple Cases
- ==============
- 
-    Some operations are accomplished in several possible ways, depending
- on the UNIX variant.  Checking for them essentially requires a "case
- statement".  Autoconf does not directly provide one; however, it is
- easy to simulate by using a shell variable to keep track of whether a
- way to perform the operation has been found yet.
- 
-    Here is an example that uses the shell variable `fstype' to keep
- track of whether the remaining cases need to be checked.
- 
-      AC_MSG_CHECKING(how to get filesystem type)
-      fstype=no
-      # The order of these tests is important.
-      AC_TRY_CPP([#include <sys/statvfs.h>
-      #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
-      if test $fstype = no; then
-      AC_TRY_CPP([#include <sys/statfs.h>
-      #include <sys/fstyp.h>], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
-      fi
-      if test $fstype = no; then
-      AC_TRY_CPP([#include <sys/statfs.h>
-      #include <sys/vmount.h>], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
-      fi
-      # (more cases omitted here)
-      AC_MSG_RESULT($fstype)
- 
- 
- File: autoconf.info,  Node: Language Choice,  Prev: Multiple Cases,  Up: Writing Tests
- 
- Language Choice
- ===============
- 
-    Packages that use both C and C++ need to test features of both
- compilers.  Autoconf-generated `configure' scripts check for C features
- by default.  The following macros determine which language's compiler
- is used in tests that follow in `configure.in'.
- 
-  - Macro: AC_LANG_C
-      Do compilation tests using `CC' and `CPP' and use extension `.c'
-      for test programs.
- 
-  - Macro: AC_LANG_CPLUSPLUS
-      Do compilation tests using `CXX' and `CXXCPP' and use extension
-      `.C' for test programs.
- 
-  - Macro: AC_LANG_SAVE
-      Remember the current language (as set by `AC_LANG_C' or
-      `AC_LANG_CPLUSPLUS') on a stack.  Does not change which language is
-      current.  Use this macro and `AC_LANG_RESTORE' in macros that need
-      to temporarily switch to a particular language.
- 
-  - Macro: AC_LANG_RESTORE
-      Select the language that is saved on the top of the stack, as set
-      by `AC_LANG_SAVE', and remove it from the stack.  This macro is
-      equivalent to either `AC_LANG_C' or `AC_LANG_CPLUSPLUS', whichever
-      had been run most recently when `AC_LANG_SAVE' was last called.
- 
-      Do not call this macro more times than `AC_LANG_SAVE'.
- 
-  - Macro: AC_REQUIRE_CPP
-      Ensure that whichever preprocessor would currently be used for
-      tests has been found.  Calls `AC_REQUIRE' (*note Prerequisite
-      Macros::.) with an argument of either `AC_PROG_CPP' or
-      `AC_PROG_CXXCPP', depending on which language is current.
- 
- 
- File: autoconf.info,  Node: Results,  Next: Writing Macros,  Prev: Writing Tests,  Up: Top
- 
- Results of Tests
- ****************
- 
-    Once `configure' has determined whether a feature exists, what can
- it do to record that information?  There are four sorts of things it can
- do: define a C preprocessor symbol, set a variable in the output files,
- save the result in a cache file for future `configure' runs, and print
- a message letting the user know the result of the test.
- 
- * Menu:
- 
- * Defining Symbols::            Defining C preprocessor symbols.
- * Setting Output Variables::	Replacing variables in output files.
- * Caching Results::             Speeding up subsequent `configure' runs.
- * Printing Messages::           Notifying users of progress or problems.
- 
- 
- File: autoconf.info,  Node: Defining Symbols,  Next: Setting Output Variables,  Up: Results
- 
- Defining C Preprocessor Symbols
- ===============================
- 
-    A common action to take in response to a feature test is to define a
- C preprocessor symbol indicating the results of the test.  That is done
- by calling `AC_DEFINE' or `AC_DEFINE_UNQUOTED'.
- 
-    By default, `AC_OUTPUT' places the symbols defined by these macros
- into the output variable `DEFS', which contains an option
- `-DSYMBOL=VALUE' for each symbol defined.  Unlike in Autoconf version
- 1, there is no variable `DEFS' defined while `configure' is running.
- To check whether Autoconf macros have already defined a certain C
- preprocessor symbol, test the value of the appropriate cache variable,
- as in this example:
- 
-      AC_CHECK_FUNC(vprintf, AC_DEFINE(HAVE_VPRINTF))
-      if test "$ac_cv_func_vprintf" != yes; then
-      AC_CHECK_FUNC(_doprnt, AC_DEFINE(HAVE_DOPRNT))
-      fi
- 
-    If `AC_CONFIG_HEADER' has been called, then instead of creating
- `DEFS', `AC_OUTPUT' creates a header file by substituting the correct
- values into `#define' statements in a template file.  *Note
- Configuration Headers::, for more information about this kind of output.
- 
-  - Macro: AC_DEFINE (VARIABLE [, VALUE])
-      Define C preprocessor variable VARIABLE.  If VALUE is given, set
-      VARIABLE to that value (verbatim), otherwise set it to 1.  VALUE
-      should not contain literal newlines, and if you are not using
-      `AC_CONFIG_HEADER' it should not contain any `#' characters, as
-      `make' tends to eat them.  To use a shell variable (which you need
-      to do in order to define a value containing the `m4' quote
-      characters `[' or `]'), use `AC_DEFINE_UNQUOTED' instead.  The
-      following example defines the C preprocessor variable `EQUATION'
-      to be the string constant `"$a > $b"':
- 
-           AC_DEFINE(EQUATION, "$a > $b")
- 
-  - Macro: AC_DEFINE_UNQUOTED (VARIABLE [, VALUE])
-      Like `AC_DEFINE', but three shell expansions are
-      performed--once--on VARIABLE and VALUE: variable expansion (`$'),
-      command substitution (``'), and backslash escaping (`\').  Single
-      and double quote characters in the value have no special meaning.
-      Use this macro instead of `AC_DEFINE' when VARIABLE or VALUE is a
-      shell variable.  Examples:
- 
-           AC_DEFINE_UNQUOTED(config_machfile, "${machfile}")
-           AC_DEFINE_UNQUOTED(GETGROUPS_T, $ac_cv_type_getgroups)
-           AC_DEFINE_UNQUOTED(${ac_tr_hdr})
- 
-    Due to the syntactical bizarreness of the Bourne shell, do not use
- semicolons to separate `AC_DEFINE' or `AC_DEFINE_UNQUOTED' calls from
- other macro calls or shell code; that can cause syntax errors in the
- resulting `configure' script.  Use either spaces or newlines.  That is,
- do this:
- 
-      AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4) LIBS="$LIBS -lelf")
- 
- or this:
- 
-      AC_CHECK_HEADER(elf.h,
-        AC_DEFINE(SVR4)
-        LIBS="$LIBS -lelf")
- 
- instead of this:
- 
-      AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4); LIBS="$LIBS -lelf")
- 
- 
- File: autoconf.info,  Node: Setting Output Variables,  Next: Caching Results,  Prev: Defining Symbols,  Up: Results
- 
- Setting Output Variables
- ========================
- 
-    One way to record the results of tests is to set "output variables",
- which are shell variables whose values are substituted into files that
- `configure' outputs.  The two macros below create new output variables.
- *Note Preset Output Variables::, for a list of output variables that
- are always available.
- 
-  - Macro: AC_SUBST (VARIABLE)
-      Create an output variable from a shell variable.  Make `AC_OUTPUT'
-      substitute the variable VARIABLE into output files (typically one
-      or more `Makefile's).  This means that `AC_OUTPUT' will replace
-      instances of `@VARIABLE@' in input files with the value that the
-      shell variable VARIABLE has when `AC_OUTPUT' is called.  The value
-      of VARIABLE should not contain literal newlines.
- 
-  - Macro: AC_SUBST_FILE (VARIABLE)
-      Another way to create an output variable from a shell variable.
-      Make `AC_OUTPUT' insert (without substitutions) the contents of
-      the file named by shell variable VARIABLE into output files.  This
-      means that `AC_OUTPUT' will replace instances of `@VARIABLE@' in
-      output files (such as `Makefile.in') with the contents of the file
-      that the shell variable VARIABLE names when `AC_OUTPUT' is called.
-      Set the variable to `/dev/null' for cases that do not have a file
-      to insert.
- 
-      This macro is useful for inserting `Makefile' fragments containing
-      special dependencies or other `make' directives for particular host
-      or target types into `Makefile's.  For example, `configure.in'
-      could contain:
- 
-           AC_SUBST_FILE(host_frag)dnl
-           host_frag=$srcdir/conf/sun4.mh
- 
-      and then a `Makefile.in' could contain:
- 
-           @host_frag@
- 
- 
- File: autoconf.info,  Node: Caching Results,  Next: Printing Messages,  Prev: Setting Output Variables,  Up: Results
- 
- Caching Results
- ===============
- 
-    To avoid checking for the same features repeatedly in various
- `configure' scripts (or repeated runs of one script), `configure' saves
- the results of many of its checks in a "cache file".  If, when a
- `configure' script runs, it finds a cache file, it reads from it the
- results from previous runs and avoids rerunning those checks.  As a
- result, `configure' can run much faster than if it had to perform all
- of the checks every time.
- 
-  - Macro: AC_CACHE_VAL (CACHE-ID, COMMANDS-TO-SET-IT)
-      Ensure that the results of the check identified by CACHE-ID are
-      available.  If the results of the check were in the cache file
-      that was read, and `configure' was not given the `--quiet' or
-      `--silent' option, print a message saying that the result was
-      cached; otherwise, run the shell commands COMMANDS-TO-SET-IT.
-      Those commands should have no side effects except for setting the
-      variable CACHE-ID.  In particular, they should not call
-      `AC_DEFINE'; the code that follows the call to `AC_CACHE_VAL'
-      should do that, based on the cached value.  Also, they should not
-      print any messages, for example with `AC_MSG_CHECKING'; do that
-      before calling `AC_CACHE_VAL', so the messages are printed
-      regardless of whether the results of the check are retrieved from
-      the cache or determined by running the shell commands.  If the
-      shell commands are run to determine the value, the value will be
-      saved in the cache file just before `configure' creates its output
-      files.  *Note Cache Variable Names::, for how to choose the name
-      of the CACHE-ID variable.
- 
- * Menu:
- 
- * Cache Variable Names::        Shell variables used in caches.
- * Cache Files::	        	Files `configure' uses for caching.
- 
- 
- File: autoconf.info,  Node: Cache Variable Names,  Next: Cache Files,  Up: Caching Results
- 
- Cache Variable Names
- --------------------
- 
-    The names of cache variables should have the following format:
- 
-      PACKAGE-PREFIX_cv_VALUE-TYPE_SPECIFIC-VALUE[_ADDITIONAL-OPTIONS]
- 
- for example, `ac_cv_header_stat_broken' or
- `ac_cv_prog_gcc_traditional'.  The parts of the variable name are:
- 
- PACKAGE-PREFIX
-      An abbreviation for your package or organization; the same prefix
-      you begin local Autoconf macros with, except lowercase by
-      convention.  For cache values used by the distributed Autoconf
-      macros, this value is `ac'.
- 
- `_cv_'
-      Indicates that this shell variable is a cache value.
- 
- VALUE-TYPE
-      A convention for classifying cache values, to produce a rational
-      naming system.  The values used in Autoconf are listed in *Note
-      Macro Names::.
- 
- SPECIFIC-VALUE
-      Which member of the class of cache values this test applies to.
-      For example, which function (`alloca'), program (`gcc'), or output
-      variable (`INSTALL').
- 
- ADDITIONAL-OPTIONS
-      Any particular behavior of the specific member that this test
-      applies to.  For example, `broken' or `set'.  This part of the
-      name may be omitted if it does not apply.
- 
-    Like their names, the values that may be assigned to cache variables
- have a few restrictions.  The values may not contain single quotes or
- curly braces.  Usually, their values will be boolean (`yes' or `no') or
- the names of files or functions; so this is not an important
- restriction.
- 
- 
- File: autoconf.info,  Node: Cache Files,  Prev: Cache Variable Names,  Up: Caching Results
- 
- Cache Files
- -----------
- 
-    A cache file is a shell script that caches the results of configure
- tests run on one system so they can be shared between configure scripts
- and configure runs.  It is not useful on other systems.  If its contents
- are invalid for some reason, the user may delete or edit it.
- 
-    By default, configure uses `./config.cache' as the cache file,
- creating it if it does not exist already.  `configure' accepts the
- `--cache-file=FILE' option to use a different cache file; that is what
- `configure' does when it calls `configure' scripts in subdirectories,
- so they share the cache.  Giving `--cache-file=/dev/null' disables
- caching, for debugging `configure'.  *Note Subdirectories::, for
- information on configuring subdirectories with the `AC_CONFIG_SUBDIRS'
- macro.  `config.status' only pays attention to the cache file if it is
- given the `--recheck' option, which makes it rerun `configure'.
- 
-    It is wrong to try to distribute cache files for particular system
- types.  There is too much room for error in doing that, and too much
- administrative overhead in maintaining them.  For any features that
- can't be guessed automatically, use the standard method of the canonical
- system type and linking files (*note Manual Configuration::.).
- 
-    The cache file on a particular system will gradually accumulate
- whenever someone runs a `configure' script; it will be initially
- nonexistent.  Running `configure' merges the new cache results with the
- existing cache file.  The site initialization script can specify a
- site-wide cache file to use instead of the default, to make it work
- transparently, as long as the same C compiler is used every time (*note
- Site Defaults::.).
- 
- 
- File: autoconf.info,  Node: Printing Messages,  Prev: Caching Results,  Up: Results
- 
- Printing Messages
- =================
- 
-    `configure' scripts need to give users running them several kinds of
- information.  The following macros print messages in ways appropriate
- for each kind.  The arguments to all of them get enclosed in shell
- double quotes, so the shell performs variable and backquote substitution
- on them.
- 
-    These macros are all wrappers around the `echo' shell command.
- `configure' scripts should rarely need to run `echo' directly to print
- messages for the user.  Using these macros makes it easy to change how
- and when each kind of message is printed; such changes need only be
- made to the macro definitions, and all of the callers change
- automatically.
- 
-  - Macro: AC_MSG_CHECKING (FEATURE-DESCRIPTION)
-      Notify the user that `configure' is checking for a particular
-      feature.  This macro prints a message that starts with `checking '
-      and ends with `...' and no newline.  It must be followed by a call
-      to `AC_MSG_RESULT' to print the result of the check and the
-      newline.  The FEATURE-DESCRIPTION should be something like
-      `whether the Fortran compiler accepts C++ comments' or `for c89'.
- 
-      This macro prints nothing if `configure' is run with the `--quiet'
-      or `--silent' option.
- 
-  - Macro: AC_MSG_RESULT (RESULT-DESCRIPTION)
-      Notify the user of the results of a check.  RESULT-DESCRIPTION is
-      almost always the value of the cache variable for the check,
-      typically `yes', `no', or a file name.  This macro should follow a
-      call to `AC_MSG_CHECKING', and the RESULT-DESCRIPTION should be
-      the completion of the message printed by the call to
-      `AC_MSG_CHECKING'.
- 
-      This macro prints nothing if `configure' is run with the `--quiet'
-      or `--silent' option.
- 
-  - Macro: AC_MSG_ERROR (ERROR-DESCRIPTION)
-      Notify the user of an error that prevents `configure' from
-      completing.  This macro prints an error message on the standard
-      error output and exits `configure' with a nonzero status.
-      eRROR-DESCRIPTION should be something like `invalid value $HOME
-      for \$HOME'.
- 
-  - Macro: AC_MSG_WARN (PROBLEM-DESCRIPTION)
-      Notify the `configure' user of a possible problem.  This macro
-      prints the message on the standard error output; `configure'
-      continues running afterward, so macros that call `AC_MSG_WARN'
-      should provide a default (back-up) behavior for the situations
-      they warn about.  PROBLEM-DESCRIPTION should be something like `ln
-      -s seems to make hard links'.
- 
-    The following two macros are an obsolete alternative to
- `AC_MSG_CHECKING' and `AC_MSG_RESULT'.
- 
-  - Macro: AC_CHECKING (FEATURE-DESCRIPTION)
-      This macro is similar to `AC_MSG_CHECKING', except that it prints a
-      newline after the FEATURE-DESCRIPTION.  It is useful mainly to
-      print a general description of the overall purpose of a group of
-      feature checks, e.g.,
- 
-           AC_CHECKING(if stack overflow is detectable)
- 
-  - Macro: AC_VERBOSE (RESULT-DESCRIPTION)
-      This macro is similar to `AC_MSG_RESULT', except that it is meant
-      to follow a call to `AC_CHECKING' instead of `AC_MSG_CHECKING'; it
-      starts the message it prints with a tab.  It is considered
-      obsolete.
- 
- 
- File: autoconf.info,  Node: Writing Macros,  Next: Manual Configuration,  Prev: Results,  Up: Top
- 
- Writing Macros
- **************
- 
-    When you write a feature test that could be applicable to more than
- one software package, the best thing to do is encapsulate it in a new
- macro.  Here are some instructions and guidelines for writing Autoconf
- macros.
- 
- * Menu:
- 
- * Macro Definitions::		Basic format of an Autoconf macro.
- * Macro Names::                 What to call your new macros.
- * Quoting::			Protecting macros from unwanted expansion.
- * Dependencies Between Macros::	What to do when macros depend on other macros.
- 
- 
- File: autoconf.info,  Node: Macro Definitions,  Next: Macro Names,  Up: Writing Macros
- 
- Macro Definitions
- =================
- 
-    Autoconf macros are defined using the `AC_DEFUN' macro, which is
- similar to the `m4' builtin `define' macro.  In addition to defining a
- macro, `AC_DEFUN' adds to it some code which is used to constrain the
- order in which macros are called (*note Prerequisite Macros::.).
- 
-    An Autoconf macro definition looks like this:
- 
-      AC_DEFUN(MACRO-NAME, [MACRO-BODY])
- 
- The square brackets here do not indicate optional text: they should
- literally be present in the macro definition to avoid macro expansion
- problems (*note Quoting::.).  You can refer to any arguments passed to
- the macro as `$1', `$2', etc.
- 
-    To introduce comments in `m4', use the `m4' builtin `dnl'; it causes
- `m4' to discard the text through the next newline.  It is not needed
- between macro definitions in `acsite.m4' and `aclocal.m4', because all
- output is discarded until `AC_INIT' is called.
- 
-    *Note How to define new macros: (m4.info)Definitions, for more
- complete information on writing `m4' macros.
- 
- 
- File: autoconf.info,  Node: Macro Names,  Next: Quoting,  Prev: Macro Definitions,  Up: Writing Macros
- 
- Macro Names
- ===========
- 
-    All of the Autoconf macros have all-uppercase names starting with
- `AC_' to prevent them from accidentally conflicting with other text.
- All shell variables that they use for internal purposes have
- mostly-lowercase names starting with `ac_'.  To ensure that your macros
- don't conflict with present or future Autoconf macros, you should
- prefix your own macro names and any shell variables they use with some
- other sequence.  Possibilities include your initials, or an abbreviation
- for the name of your organization or software package.
- 
-    Most of the Autoconf macros' names follow a structured naming
- convention that indicates the kind of feature check by the name.  The
- macro names consist of several words, separated by underscores, going
- from most general to most specific.   The names of their cache
- variables use the same convention (*note Cache Variable Names::., for
- more information on them).
- 
-    The first word of the name after `AC_' usually tells the category of
- feature being tested.  Here are the categories used in Autoconf for
- specific test macros, the kind of macro that you are more likely to
- write.  They are also used for cache variables, in all-lowercase.  Use
- them where applicable; where they're not, invent your own categories.
- 
- `C'
-      C language builtin features.
- 
- `DECL'
-      Declarations of C variables in header files.
- 
- `FUNC'
-      Functions in libraries.
- 
- `GROUP'
-      UNIX group owners of files.
- 
- `HEADER'
-      Header files.
- 
- `LIB'
-      C libraries.
- 
- `PATH'
-      The full path names to files, including programs.
- 
- `PROG'
-      The base names of programs.
- 
- `STRUCT'
-      Definitions of C structures in header files.
- 
- `SYS'
-      Operating system features.
- 
- `TYPE'
-      C builtin or declared types.
- 
- `VAR'
-      C variables in libraries.
- 
-    After the category comes the name of the particular feature being
- tested.  Any further words in the macro name indicate particular aspects
- of the feature.  For example, `AC_FUNC_UTIME_NULL' checks the behavior
- of the `utime' function when called with a `NULL' pointer.
- 
-    A macro that is an internal subroutine of another macro should have a
- name that starts with the name of that other macro, followed by one or
- more words saying what the internal macro does.  For example,
- `AC_PATH_X' has internal macros `AC_PATH_X_XMKMF' and
- `AC_PATH_X_DIRECT'.
- 
- 
- File: autoconf.info,  Node: Quoting,  Next: Dependencies Between Macros,  Prev: Macro Names,  Up: Writing Macros
- 
- Quoting
- =======
- 
-    Macros that are called by other macros are evaluated by `m4' several
- times; each evaluation might require another layer of quotes to prevent
- unwanted expansions of macros or `m4' builtins, such as `define' and
- `$1'.  Quotes are also required around macro arguments that contain
- commas, since commas separate the arguments from each other.  It's a
- good idea to quote any macro arguments that contain newlines or calls
- to other macros, as well.
- 
-    Autoconf changes the `m4' quote characters from the default ``' and
- `'' to `[' and `]', because many of the macros use ``' and `'',
- mismatched.  However, in a few places the macros need to use brackets
- (usually in C program text or regular expressions).  In those places,
- they use the `m4' builtin command `changequote' to temporarily change
- the quote characters to `<<' and `>>'.  (Sometimes, if they don't need
- to quote anything, they disable quoting entirely instead by setting the
- quote characters to empty strings.)  Here is an example:
- 
-      AC_TRY_LINK(
-      changequote(<<, >>)dnl
-      <<#include <time.h>
-      #ifndef tzname /* For SGI.  */
-      extern char *tzname[]; /* RS6000 and others reject char **tzname.  */
-      #endif>>,
-      changequote([, ])dnl
-      [atoi(*tzname);], ac_cv_var_tzname=yes, ac_cv_var_tzname=no)
- 
-    When you create a `configure' script using newly written macros,
- examine it carefully to check whether you need to add more quotes in
- your macros.  If one or more words have disappeared in the `m4' output,
- you need more quotes.  When in doubt, quote.
- 
-    However, it's also possible to put on too many layers of quotes.  If
- this happens, the resulting `configure' script will contain unexpanded
- macros.  The `autoconf' program checks for this problem by doing `grep
- AC_ configure'.
- 
- 
- File: autoconf.info,  Node: Dependencies Between Macros,  Prev: Quoting,  Up: Writing Macros
- 
- Dependencies Between Macros
- ===========================
- 
-    Some Autoconf macros depend on other macros having been called first
- in order to work correctly.  Autoconf provides a way to ensure that
- certain macros are called if needed and a way to warn the user if
- macros are called in an order that might cause incorrect operation.
- 
- * Menu:
- 
- * Prerequisite Macros::		Ensuring required information.
- * Suggested Ordering::		Warning about possible ordering problems.
- * Obsolete Macros::             Warning about old ways of doing things.
- 
- 
- File: autoconf.info,  Node: Prerequisite Macros,  Next: Suggested Ordering,  Up: Dependencies Between Macros
- 
- Prerequisite Macros
- -------------------
- 
-    A macro that you write might need to use values that have previously
- been computed by other macros.  For example, `AC_DECL_YYTEXT' examines
- the output of `flex' or `lex', so it depends on `AC_PROG_LEX' having
- been called first to set the shell variable `LEX'.
- 
-    Rather than forcing the user of the macros to keep track of the
- dependencies between them, you can use the `AC_REQUIRE' macro to do it
- automatically.  `AC_REQUIRE' can ensure that a macro is only called if
- it is needed, and only called once.
- 
-  - Macro: AC_REQUIRE (MACRO-NAME)
-      If the `m4' macro MACRO-NAME has not already been called, call it
-      (without any arguments).  Make sure to quote MACRO-NAME with
-      square brackets.  MACRO-NAME must have been defined using
-      `AC_DEFUN' or else contain a call to `AC_PROVIDE' to indicate that
-      it has been called.
- 
-    An alternative to using `AC_DEFUN' is to use `define' and call
- `AC_PROVIDE'.  Because this technique does not prevent nested messages,
- it is considered obsolete.
- 
-  - Macro: AC_PROVIDE (THIS-MACRO-NAME)
-      Record the fact that THIS-MACRO-NAME has been called.
-      tHIS-MACRO-NAME should be the name of the macro that is calling
-      `AC_PROVIDE'.  An easy way to get it is from the `m4' builtin
-      variable `$0', like this:
- 
-           AC_PROVIDE([$0])
- 
- 
- File: autoconf.info,  Node: Suggested Ordering,  Next: Obsolete Macros,  Prev: Prerequisite Macros,  Up: Dependencies Between Macros
- 
- Suggested Ordering
- ------------------
- 
-    Some macros should be run before another macro if both are called,
- but neither *requires* that the other be called.  For example, a macro
- that changes the behavior of the C compiler should be called before any
- macros that run the C compiler.  Many of these dependencies are noted in
- the documentation.
- 
-    Autoconf provides the `AC_BEFORE' macro to warn users when macros
- with this kind of dependency appear out of order in a `configure.in'
- file.  The warning occurs when creating `configure' from
- `configure.in', not when running `configure'.  For example,
- `AC_PROG_CPP' checks whether the C compiler can run the C preprocessor
- when given the `-E' option.  It should therefore be called after any
- macros that change which C compiler is being used, such as
- `AC_PROG_CC'.  So `AC_PROG_CC' contains:
- 
-      AC_BEFORE([$0], [AC_PROG_CPP])dnl
- 
- This warns the user if a call to `AC_PROG_CPP' has already occurred
- when `AC_PROG_CC' is called.
- 
-  - Macro: AC_BEFORE (THIS-MACRO-NAME, CALLED-MACRO-NAME)
-      Make `m4' print a warning message on the standard error output if
-      CALLED-MACRO-NAME has already been called.  THIS-MACRO-NAME should
-      be the name of the macro that is calling `AC_BEFORE'.  The macro
-      CALLED-MACRO-NAME must have been defined using `AC_DEFUN' or else
-      contain a call to `AC_PROVIDE' to indicate that it has been called.
- 
- 
- File: autoconf.info,  Node: Obsolete Macros,  Prev: Suggested Ordering,  Up: Dependencies Between Macros
- 
- Obsolete Macros
- ---------------
- 
-    Configuration and portability technology has evolved over the years.
- Often better ways of solving a particular problem are developed, or
- ad-hoc approaches are systematized.  This process has occurred in many
- parts of Autoconf.  One result is that some of the macros are now
- considered "obsolete"; they still work, but are no longer considered
- the best thing to do.  Autoconf provides the `AC_OBSOLETE' macro to
- warn users producing `configure' scripts when they use obsolete macros,
- to encourage them to modernize.  A sample call is:
- 
-      AC_OBSOLETE([$0], [; use AC_CHECK_HEADERS(unistd.h) instead])dnl
- 
-  - Macro: AC_OBSOLETE (THIS-MACRO-NAME [, SUGGESTION])
-      Make `m4' print a message on the standard error output warning that
-      THIS-MACRO-NAME is obsolete, and giving the file and line number
-      where it was called.  THIS-MACRO-NAME should be the name of the
-      macro that is calling `AC_OBSOLETE'.  If SUGGESTION is given, it
-      is printed at the end of the warning message; for example, it can
-      be a suggestion for what to use instead of THIS-MACRO-NAME.
- 
- 
- File: autoconf.info,  Node: Manual Configuration,  Next: Site Configuration,  Prev: Writing Macros,  Up: Top
- 
- Manual Configuration
- ********************
- 
-    A few kinds of features can't be guessed automatically by running
- test programs.  For example, the details of the object file format, or
- special options that need to be passed to the compiler or linker.  You
- can check for such features using ad-hoc means, such as having
- `configure' check the output of the `uname' program, or looking for
- libraries that are unique to particular systems.  However, Autoconf
- provides a uniform method for handling unguessable features.
- 
- * Menu:
- 
- * Specifying Names::            Specifying the system type.
- * Canonicalizing::              Getting the canonical system type.
- * System Type Variables::       Variables containing the system type.
- * Using System Type::           What to do with the system type.
- 
- 
- File: autoconf.info,  Node: Specifying Names,  Next: Canonicalizing,  Up: Manual Configuration
- 
- Specifying the System Type
- ==========================
- 
-    Like other GNU `configure' scripts, Autoconf-generated `configure'
- scripts can make decisions based on a canonical name for the system
- type, which has the form:
- 
-      CPU-COMPANY-SYSTEM
- 
-    `configure' can usually guess the canonical name for the type of
- system it's running on.  To do so it runs a script called
- `config.guess', which derives the name using the `uname' command or
- symbols predefined by the C preprocessor.
- 
-    Alternately, the user can specify the system type with command line
- arguments to `configure'.  Doing so is necessary when cross-compiling.
- In the most complex case of cross-compiling, three system types are
- involved.  The options to specify them are:
- 
- `--build=BUILD-TYPE'
-      the type of system on which the package is being configured and
-      compiled (rarely needed);
- 
- `--host=HOST-TYPE'
-      the type of system on which the package will run;
- 
- `--target=TARGET-TYPE'
-      the type of system for which any compiler tools in the package will
-      produce code.
- 
- If the user gives `configure' a non-option argument, it is used as the
- default for the host, target, and build system types if the user does
- not specify them explicitly with options.  The target and build types
- default to the host type if it is given and they are not.  If you are
- cross-compiling, you still have to specify the names of the cross-tools
- you use, in particular the C compiler, on the `configure' command line,
- e.g.,
- 
-      CC=m68k-coff-gcc configure --target=m68k-coff
- 
-    `configure' recognizes short aliases for many system types; for
- example, `decstation' can be given on the command line instead of
- `mips-dec-ultrix4.2'.  `configure' runs a script called `config.sub' to
- canonicalize system type aliases.
- 
- 
- File: autoconf.info,  Node: Canonicalizing,  Next: System Type Variables,  Prev: Specifying Names,  Up: Manual Configuration
- 
- Getting the Canonical System Type
- =================================
- 
-    The following macros make the system type available to `configure'
- scripts.  They run the shell script `config.guess' to determine any
- values for the host, target, and build types that they need and the user
- did not specify on the command line.  They run `config.sub' to
- canonicalize any aliases the user gave.  If you use these macros, you
- must distribute those two shell scripts along with your source code.
- *Note Output::, for information about the `AC_CONFIG_AUX_DIR' macro
- which you can use to control which directory `configure' looks for
- those scripts in.  If you do not use either of these macros,
- `configure' ignores any `--host', `--target', and `--build' options
- given to it.
- 
-  - Macro: AC_CANONICAL_SYSTEM
-      Determine the system type and set output variables to the names of
-      the canonical system types.  *Note System Type Variables::, for
-      details about the variables this macro sets.
- 
-  - Macro: AC_CANONICAL_HOST
-      Perform only the subset of `AC_CANONICAL_SYSTEM' relevant to the
-      host type.  This is all that is needed for programs that are not
-      part of a compiler toolchain.
- 
- 
- File: autoconf.info,  Node: System Type Variables,  Next: Using System Type,  Prev: Canonicalizing,  Up: Manual Configuration
- 
- System Type Variables
- =====================
- 
-    After calling `AC_CANONICAL_SYSTEM', the following output variables
- contain the system type information.  After `AC_CANONICAL_HOST', only
- the `host' variables below are set.
- 
- ``build', `host', `target''
-      the canonical system names;
- 
- ``build_alias', `host_alias', `target_alias''
-      the names the user specified, or the canonical names if
-      `config.guess' was used;
- 
- ``build_cpu', `build_vendor', `build_os''
- ``host_cpu', `host_vendor', `host_os''
- ``target_cpu', `target_vendor', `target_os''
-      the individual parts of the canonical names (for convenience).
- 
- 
- File: autoconf.info,  Node: Using System Type,  Prev: System Type Variables,  Up: Manual Configuration
- 
- Using the System Type
- =====================
- 
-    How do you use a canonical system type?  Usually, you use it in one
- or more `case' statements in `configure.in' to select system-specific C
- files.  Then link those files, which have names based on the system
- name, to generic names, such as `host.h' or `target.c'.  The `case'
- statement patterns can use shell wildcards to group several cases
- together, like in this fragment:
- 
-      case "$target" in
-      i386-*-mach* | i386-*-gnu*) obj_format=aout emulation=mach bfd_gas=yes ;;
-      i960-*-bout) obj_format=bout ;;
-      esac
- 
-  - Macro: AC_LINK_FILES (SOURCE..., DEST...)
-      Make `AC_OUTPUT' link each of the existing files SOURCE to the
-      corresponding link name DEST.  Makes a symbolic link if possible,
-      otherwise a hard link.  The DEST and SOURCE names should be
-      relative to the top level source or build directory.
- 
-      For example, this call:
- 
-           AC_LINK_FILES(config/${machine}.h config/${obj_format}.h, host.h object.h)
- 
-      creates in the current directory `host.h', which is a link to
-      `SRCDIR/config/${machine}.h', and `object.h', which is a link to
-      `SRCDIR/config/${obj_format}.h'.
- 
-    You can also use the host system type to find cross-compilation
- tools.  *Note Generic Programs::, for information about the
- `AC_CHECK_TOOL' macro which does that.
- 
- 
- File: autoconf.info,  Node: Site Configuration,  Next: Invoking configure,  Prev: Manual Configuration,  Up: Top
- 
- Site Configuration
- ******************
- 
-    `configure' scripts support several kinds of local configuration
- decisions.  There are ways for users to specify where external software
- packages are, include or exclude optional features, install programs
- under modified names, and set default values for `configure' options.
- 
- * Menu:
- 
- * External Software::           Working with other optional software.
- * Package Options::             Selecting optional features.
- * Site Details::                Configuring site details.
- * Transforming Names::          Changing program names when installing.
- * Site Defaults::               Giving `configure' local defaults.
- 
- 
- File: autoconf.info,  Node: External Software,  Next: Package Options,  Up: Site Configuration
- 
- Working With External Software
- ==============================
- 
-    Some packages require, or can optionally use, other software packages
- which are already installed.  The user can give `configure' command
- line options to specify which such external software to use.  The
- options have one of these forms:
- 
-      --with-PACKAGE[=ARG]
-      --without-PACKAGE
- 
-    For example, `--with-gnu-ld' means work with the GNU linker instead
- of some other linker.  `--with-x11' means work with X11.
- 
-    The user can give an argument by following the package name with `='
- and the argument.  Giving an argument of `no' is for packages that are
- used by default; it says to *not* use the package.  An argument that is
- neither `yes' nor `no' could include a name or number of a version of
- the other package, to specify more precisely which other package this
- program is supposed to work with.  If no argument is given, it defaults
- to `yes'.  `--without-PACKAGE' is equivalent to `--with-PACKAGE=no'.
- 
-    For each external software package that may be used, `configure.in'
- should call `AC_ARG_WITH' to detect whether the `configure' user asked
- to use it.  Whether each package is used or not by default, and which
- arguments are valid, is up to you.
- 
-  - Macro: AC_ARG_WITH (PACKAGE, HELP-STRING [, ACTION-IF-GIVEN [,
-           ACTION-IF-NOT-GIVEN]])
-      If the user gave `configure' the option `--with-PACKAGE' or
-      `--without-PACKAGE', run shell commands ACTION-IF-GIVEN.  If
-      neither option was given, run shell commands ACTION-IF-NOT-GIVEN.
-      The name PACKAGE indicates another software package that this
-      program should work with.  It should consist only of alphanumeric
-      characters and dashes.
- 
-      The option's argument is available to the shell commands
-      ACTION-IF-GIVEN in the shell variable `withval', which is actually
-      just the value of the shell variable `with_PACKAGE'; you may use
-      that variable instead, if you wish.
- 
-      The argument HELP-STRING is a description of the option which
-      looks like this:
-             --with-readline         support fancy command line editing
- 
-      HELP-STRING may be more than one line long, if more detail is
-      needed.  Just make sure the columns line up in `configure --help'.
-      Avoid tabs in the help string.  You'll need to enclose it in `['
-      and `]' in order to produce the leading spaces.
- 
-  - Macro: AC_WITH (PACKAGE, ACTION-IF-GIVEN [, ACTION-IF-NOT-GIVEN])
-      This is an obsolete version of `AC_ARG_WITH' that does not support
-      providing a help string.
- 
--- 0 ----
Index: krb5/util/autoconf/autoconf.info-4
diff -c krb5/util/autoconf/autoconf.info-4:1.1.1.1 krb5/util/autoconf/autoconf.info-4:removed
*** krb5/util/autoconf/autoconf.info-4:1.1.1.1	Mon Jun  2 17:58:31 1997
--- krb5/util/autoconf/autoconf.info-4	Sun Mar 16 20:22:40 2003
***************
*** 1,1129 ****
- This is Info file autoconf.info, produced by Makeinfo-1.55 from the
- input file autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Package Options,  Next: Site Details,  Prev: External Software,  Up: Site Configuration
- 
- Choosing Package Options
- ========================
- 
-    If a software package has optional compile-time features, the user
- can give `configure' command line options to specify whether to compile
- them.  The options have one of these forms:
- 
-      --enable-FEATURE[=ARG]
-      --disable-FEATURE
- 
-    These options allow users to choose which optional features to build
- and install.  `--enable-FEATURE' options should never make a feature
- behave differently or cause one feature to replace another.  They
- should only cause parts of the program to be built rather than left out.
- 
-    The user can give an argument by following the feature name with `='
- and the argument.  Giving an argument of `no' requests that the feature
- *not* be made available.  A feature with an argument looks like
- `--enable-debug=stabs'.  If no argument is given, it defaults to `yes'.
- `--disable-FEATURE' is equivalent to `--enable-FEATURE=no'.
- 
-    For each optional feature, `configure.in' should call
- `AC_ARG_ENABLE' to detect whether the `configure' user asked to include
- it.  Whether each feature is included or not by default, and which
- arguments are valid, is up to you.
- 
-  - Macro: AC_ARG_ENABLE (FEATURE, HELP-STRING [, ACTION-IF-GIVEN [,
-           ACTION-IF-NOT-GIVEN]])
-      If the user gave `configure' the option `--enable-FEATURE' or
-      `--disable-FEATURE', run shell commands ACTION-IF-GIVEN.  If
-      neither option was given, run shell commands ACTION-IF-NOT-GIVEN.
-      The name FEATURE indicates an optional user-level facility.  It
-      should consist only of alphanumeric characters and dashes.
- 
-      The option's argument is available to the shell commands
-      ACTION-IF-GIVEN in the shell variable `enableval', which is
-      actually just the value of the shell variable `enable_PACKAGE';
-      you may use that variable instead, if you wish.  The HELP-STRING
-      argument is like that of `AC_ARG_WITH' (*note External
-      Software::.).
- 
-  - Macro: AC_ENABLE (FEATURE, ACTION-IF-GIVEN [, ACTION-IF-NOT-GIVEN])
-      This is an obsolete version of `AC_ARG_ENABLE' that does not
-      support providing a help string.
- 
- 
- File: autoconf.info,  Node: Site Details,  Next: Transforming Names,  Prev: Package Options,  Up: Site Configuration
- 
- Configuring Site Details
- ========================
- 
-    Some software packages require complex site-specific information.
- Some examples are host names to use for certain services, company
- names, and email addresses to contact.  Since some configuration
- scripts generated by Metaconfig ask for such information interactively,
- people sometimes wonder how to get that information in
- Autoconf-generated configuration scripts, which aren't interactive.
- 
-    Such site configuration information should be put in a file that is
- edited *only by users*, not by programs.  The location of the file can
- either be based on the `prefix' variable, or be a standard location
- such as the user's home directory.  It could even be specified by an
- environment variable.  The programs should examine that file at run
- time, rather than at compile time.  Run time configuration is more
- convenient for users and makes the configuration process simpler than
- getting the information while configuring.  *Note Variables for
- Installation Directories: (standards)Directory Variables, for more
- information on where to put data files.
- 
- 
- File: autoconf.info,  Node: Transforming Names,  Next: Site Defaults,  Prev: Site Details,  Up: Site Configuration
- 
- Transforming Program Names When Installing
- ==========================================
- 
-    Autoconf supports changing the names of programs when installing
- them.  In order to use these transformations, `configure.in' must call
- the macro `AC_ARG_PROGRAM'.
- 
-  - Macro: AC_ARG_PROGRAM
-      Place in output variable `program_transform_name' a sequence of
-      `sed' commands for changing the names of installed programs.
- 
-      If any of the options described below are given to `configure',
-      program names are transformed accordingly.  Otherwise, if
-      `AC_CANONICAL_SYSTEM' has been called and a `--target' value is
-      given that differs from the host type (specified with `--host' or
-      defaulted by `config.sub'), the target type followed by a dash is
-      used as a prefix.  Otherwise, no program name transformation is
-      done.
- 
- * Menu:
- 
- * Transformation Options::      `configure' options to transform names.
- * Transformation Examples::     Sample uses of transforming names.
- * Transformation Rules::        `Makefile' uses of transforming names.
- 
- 
- File: autoconf.info,  Node: Transformation Options,  Next: Transformation Examples,  Up: Transforming Names
- 
- Transformation Options
- ----------------------
- 
-    You can specify name transformations by giving `configure' these
- command line options:
- 
- `--program-prefix=PREFIX'
-      prepend PREFIX to the names;
- 
- `--program-suffix=SUFFIX'
-      append SUFFIX to the names;
- 
- `--program-transform-name=EXPRESSION'
-      perform `sed' substitution EXPRESSION on the names.
- 
- 
- File: autoconf.info,  Node: Transformation Examples,  Next: Transformation Rules,  Prev: Transformation Options,  Up: Transforming Names
- 
- Transformation Examples
- -----------------------
- 
-    These transformations are useful with programs that can be part of a
- cross-compilation development environment.  For example, a
- cross-assembler running on a Sun 4 configured with
- `--target=i960-vxworks' is normally installed as `i960-vxworks-as',
- rather than `as', which could be confused with a native Sun 4 assembler.
- 
-    You can force a program name to begin with `g', if you don't want
- GNU programs installed on your system to shadow other programs with the
- same name.  For example, if you configure GNU `diff' with
- `--program-prefix=g', then when you run `make install' it is installed
- as `/usr/local/bin/gdiff'.
- 
-    As a more sophisticated example, you could use
-      --program-transform-name='s/^/g/; s/^gg/g/; s/^gless/less/'
- 
- to prepend `g' to most of the program names in a source tree, excepting
- those like `gdb' that already have one and those like `less' and
- `lesskey' that aren't GNU programs.  (That is assuming that you have a
- source tree containing those programs that is set up to use this
- feature.)
- 
-    One way to install multiple versions of some programs simultaneously
- is to append a version number to the name of one or both.  For example,
- if you want to keep Autoconf version 1 around for awhile, you can
- configure Autoconf version 2 using `--program-suffix=2' to install the
- programs as `/usr/local/bin/autoconf2', `/usr/local/bin/autoheader2',
- etc.
- 
- 
- File: autoconf.info,  Node: Transformation Rules,  Prev: Transformation Examples,  Up: Transforming Names
- 
- Transformation Rules
- --------------------
- 
-    Here is how to use the variable `program_transform_name' in a
- `Makefile.in':
- 
-      transform=@program_transform_name@
-      install: all
-              $(INSTALL_PROGRAM) myprog $(bindir)/`echo myprog|sed '$(transform)'`
-      
-      uninstall:
-              rm -f $(bindir)/`echo myprog|sed '$(transform)'`
- 
- If you have more than one program to install, you can do it in a loop:
- 
-      PROGRAMS=cp ls rm
-      install:
-              for p in $(PROGRAMS); do \
-                $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
-              done
-      
-      uninstall:
-              for p in $(PROGRAMS); do \
-                rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
-              done
- 
-    Whether to do the transformations on documentation files (Texinfo or
- `man') is a tricky question; there seems to be no perfect answer, due
- to the several reasons for name transforming.  Documentation is not
- usually particular to a specific architecture, and Texinfo files do not
- conflict with system documentation.  But they might conflict with
- earlier versions of the same files, and `man' pages sometimes do
- conflict with system documentation.  As a compromise, it is probably
- best to do name transformations on `man' pages but not on Texinfo
- manuals.
- 
- 
- File: autoconf.info,  Node: Site Defaults,  Prev: Transforming Names,  Up: Site Configuration
- 
- Setting Site Defaults
- =====================
- 
-    Autoconf-generated `configure' scripts allow your site to provide
- default values for some configuration values.  You do this by creating
- site- and system-wide initialization files.
- 
-    If the environment variable `CONFIG_SITE' is set, `configure' uses
- its value as the name of a shell script to read.  Otherwise, it reads
- the shell script `PREFIX/share/config.site' if it exists, then
- `PREFIX/etc/config.site' if it exists.  Thus, settings in
- machine-specific files override those in machine-independent ones in
- case of conflict.
- 
-    Site files can be arbitrary shell scripts, but only certain kinds of
- code are really appropriate to be in them.  Because `configure' reads
- any cache file after it has read any site files, a site file can define
- a default cache file to be shared between all Autoconf-generated
- `configure' scripts run on that system.  If you set a default cache
- file in a site file, it is a good idea to also set the output variable
- `CC' in that site file, because the cache file is only valid for a
- particular compiler, but many systems have several available.
- 
-    You can examine or override the value set by a command line option to
- `configure' in a site file; options set shell variables that have the
- same names as the options, with any dashes turned into underscores.
- The exceptions are that `--without-' and `--disable-' options are like
- giving the corresponding `--with-' or `--enable-' option and the value
- `no'.  Thus, `--cache-file=localcache' sets the variable `cache_file'
- to the value `localcache'; `--enable-warnings=no' or
- `--disable-warnings' sets the variable `enable_warnings' to the value
- `no'; `--prefix=/usr' sets the variable `prefix' to the value `/usr';
- etc.
- 
-    Site files are also good places to set default values for other
- output variables, such as `CFLAGS', if you need to give them non-default
- values: anything you would normally do, repetitively, on the command
- line.  If you use non-default values for PREFIX or EXEC_PREFIX
- (wherever you locate the site file), you can set them in the site file
- if you specify it with the `CONFIG_SITE' environment variable.
- 
-    You can set some cache values in the site file itself.  Doing this is
- useful if you are cross-compiling, so it is impossible to check features
- that require running a test program.  You could "prime the cache" by
- setting those values correctly for that system in
- `PREFIX/etc/config.site'.  To find out the names of the cache variables
- you need to set, look for shell variables with `_cv_' in their names in
- the affected `configure' scripts, or in the Autoconf `m4' source code
- for those macros.
- 
-    The cache file is careful to not override any variables set in the
- site files.  Similarly, you should not override command-line options in
- the site files.  Your code should check that variables such as `prefix'
- and `cache_file' have their default values (as set near the top of
- `configure') before changing them.
- 
-    Here is a sample file `/usr/share/local/gnu/share/config.site'.  The
- command `configure --prefix=/usr/share/local/gnu' would read this file
- (if `CONFIG_SITE' is not set to a different file).
- 
-      # config.site for configure
-      #
-      # Default --prefix and --exec-prefix.
-      test "$prefix" = NONE && prefix=/usr/share/local/gnu
-      test "$exec_prefix" = NONE && exec_prefix=/usr/local/gnu
-      #
-      # Give Autoconf 2.x generated configure scripts a shared default
-      # cache file for feature test results, architecture-specific.
-      if test "$cache_file" = ./config.cache; then
-        cache_file="$prefix/var/config.cache"
-        # A cache file is only valid for one C compiler.
-        CC=gcc
-      fi
- 
- 
- File: autoconf.info,  Node: Invoking configure,  Next: Invoking config.status,  Prev: Site Configuration,  Up: Top
- 
- Running `configure' Scripts
- ***************************
- 
-    Below are instructions on how to configure a package that uses a
- `configure' script, suitable for inclusion as an `INSTALL' file in the
- package.  A plain-text version of `INSTALL' which you may use comes
- with Autoconf.
- 
- * Menu:
- 
- * Basic Installation::          Instructions for typical cases.
- * Compilers and Options::       Selecting compilers and optimization.
- * Multiple Architectures::      Compiling for multiple architectures at once.
- * Installation Names::          Installing in different directories.
- * Optional Features::           Selecting optional features.
- * System Type::                 Specifying the system type.
- * Sharing Defaults::            Setting site-wide defaults for `configure'.
- * Operation Controls::          Changing how `configure' runs.
- 
- 
- File: autoconf.info,  Node: Basic Installation,  Next: Compilers and Options,  Up: Invoking configure
- 
- Basic Installation
- ==================
- 
-    These are generic installation instructions.
- 
-    The `configure' shell script attempts to guess correct values for
- various system-dependent variables used during compilation.  It uses
- those values to create a `Makefile' in each directory of the package.
- It may also create one or more `.h' files containing system-dependent
- definitions.  Finally, it creates a shell script `config.status' that
- you can run in the future to recreate the current configuration, a file
- `config.cache' that saves the results of its tests to speed up
- reconfiguring, and a file `config.log' containing compiler output
- (useful mainly for debugging `configure').
- 
-    If you need to do unusual things to compile the package, please try
- to figure out how `configure' could check whether to do them, and mail
- diffs or instructions to the address given in the `README' so they can
- be considered for the next release.  If at some point `config.cache'
- contains results you don't want to keep, you may remove or edit it.
- 
-    The file `configure.in' is used to create `configure' by a program
- called `autoconf'.  You only need `configure.in' if you want to change
- it or regenerate `configure' using a newer version of `autoconf'.
- 
- The simplest way to compile this package is:
- 
-   1. `cd' to the directory containing the package's source code and type
-      `./configure' to configure the package for your system.  If you're
-      using `csh' on an old version of System V, you might need to type
-      `sh ./configure' instead to prevent `csh' from trying to execute
-      `configure' itself.
- 
-      Running `configure' takes awhile.  While running, it prints some
-      messages telling which features it is checking for.
- 
-   2. Type `make' to compile the package.
- 
-   3. Optionally, type `make check' to run any self-tests that come with
-      the package.
- 
-   4. Type `make install' to install the programs and any data files and
-      documentation.
- 
-   5. You can remove the program binaries and object files from the
-      source code directory by typing `make clean'.  To also remove the
-      files that `configure' created (so you can compile the package for
-      a different kind of computer), type `make distclean'.  There is
-      also a `make maintainer-clean' target, but that is intended mainly
-      for the package's developers.  If you use it, you may have to get
-      all sorts of other programs in order to regenerate files that came
-      with the distribution.
- 
- 
- File: autoconf.info,  Node: Compilers and Options,  Next: Multiple Architectures,  Prev: Basic Installation,  Up: Invoking configure
- 
- Compilers and Options
- =====================
- 
-    Some systems require unusual options for compilation or linking that
- the `configure' script does not know about.  You can give `configure'
- initial values for variables by setting them in the environment.  Using
- a Bourne-compatible shell, you can do that on the command line like
- this:
-      CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
- 
- Or on systems that have the `env' program, you can do it like this:
-      env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
- 
- 
- File: autoconf.info,  Node: Multiple Architectures,  Next: Installation Names,  Prev: Compilers and Options,  Up: Invoking configure
- 
- Compiling For Multiple Architectures
- ====================================
- 
-    You can compile the package for more than one kind of computer at the
- same time, by placing the object files for each architecture in their
- own directory.  To do this, you must use a version of `make' that
- supports the `VPATH' variable, such as GNU `make'.  `cd' to the
- directory where you want the object files and executables to go and run
- the `configure' script.  `configure' automatically checks for the
- source code in the directory that `configure' is in and in `..'.
- 
-    If you have to use a `make' that does not supports the `VPATH'
- variable, you have to compile the package for one architecture at a time
- in the source code directory.  After you have installed the package for
- one architecture, use `make distclean' before reconfiguring for another
- architecture.
- 
- 
- File: autoconf.info,  Node: Installation Names,  Next: Optional Features,  Prev: Multiple Architectures,  Up: Invoking configure
- 
- Installation Names
- ==================
- 
-    By default, `make install' will install the package's files in
- `/usr/local/bin', `/usr/local/man', etc.  You can specify an
- installation prefix other than `/usr/local' by giving `configure' the
- option `--prefix=PATH'.
- 
-    You can specify separate installation prefixes for
- architecture-specific files and architecture-independent files.  If you
- give `configure' the option `--exec-prefix=PATH', the package will use
- PATH as the prefix for installing programs and libraries.
- Documentation and other data files will still use the regular prefix.
- 
-    If the package supports it, you can cause programs to be installed
- with an extra prefix or suffix on their names by giving `configure' the
- option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
- 
- 
- File: autoconf.info,  Node: Optional Features,  Next: System Type,  Prev: Installation Names,  Up: Invoking configure
- 
- Optional Features
- =================
- 
-    Some packages pay attention to `--enable-FEATURE' options to
- `configure', where FEATURE indicates an optional part of the package.
- They may also pay attention to `--with-PACKAGE' options, where PACKAGE
- is something like `gnu-as' or `x' (for the X Window System).  The
- `README' should mention any `--enable-' and `--with-' options that the
- package recognizes.
- 
-    For packages that use the X Window System, `configure' can usually
- find the X include and library files automatically, but if it doesn't,
- you can use the `configure' options `--x-includes=DIR' and
- `--x-libraries=DIR' to specify their locations.
- 
- 
- File: autoconf.info,  Node: System Type,  Next: Sharing Defaults,  Prev: Optional Features,  Up: Invoking configure
- 
- Specifying the System Type
- ==========================
- 
-    There may be some features `configure' can not figure out
- automatically, but needs to determine by the type of host the package
- will run on.  Usually `configure' can figure that out, but if it prints
- a message saying it can not guess the host type, give it the
- `--host=TYPE' option.  TYPE can either be a short name for the system
- type, such as `sun4', or a canonical name with three fields:
-      CPU-COMPANY-SYSTEM
- 
- See the file `config.sub' for the possible values of each field.  If
- `config.sub' isn't included in this package, then this package doesn't
- need to know the host type.
- 
-    If you are building compiler tools for cross-compiling, you can also
- use the `--target=TYPE' option to select the type of system they will
- produce code for and the `--build=TYPE' option to select the type of
- system on which you are compiling the package.
- 
- 
- File: autoconf.info,  Node: Sharing Defaults,  Next: Operation Controls,  Prev: System Type,  Up: Invoking configure
- 
- Sharing Defaults
- ================
- 
-    If you want to set default values for `configure' scripts to share,
- you can create a site shell script called `config.site' that gives
- default values for variables like `CC', `cache_file', and `prefix'.
- `configure' looks for `PREFIX/share/config.site' if it exists, then
- `PREFIX/etc/config.site' if it exists.  Or, you can set the
- `CONFIG_SITE' environment variable to the location of the site script.
- A warning: not all `configure' scripts look for a site script.
- 
- 
- File: autoconf.info,  Node: Operation Controls,  Prev: Sharing Defaults,  Up: Invoking configure
- 
- Operation Controls
- ==================
- 
-    `configure' recognizes the following options to control how it
- operates.
- 
- `--cache-file=FILE'
-      Use and save the results of the tests in FILE instead of
-      `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-      debugging `configure'.
- 
- `--help'
-      Print a summary of the options to `configure', and exit.
- 
- `--quiet'
- `--silent'
- `-q'
-      Do not print messages saying which checks are being made.
- 
- `--srcdir=DIR'
-      Look for the package's source code in directory DIR.  Usually
-      `configure' can determine that directory automatically.
- 
- `--version'
-      Print the version of Autoconf used to generate the `configure'
-      script, and exit.
- 
- `configure' also accepts some other, not widely useful, options.
- 
- 
- File: autoconf.info,  Node: Invoking config.status,  Next: Questions,  Prev: Invoking configure,  Up: Top
- 
- Recreating a Configuration
- **************************
- 
-    The `configure' script creates a file named `config.status' which
- describes which configuration options were specified when the package
- was last configured.  This file is a shell script which, if run, will
- recreate the same configuration.
- 
-    You can give `config.status' the `--recheck' option to update
- itself.  This option is useful if you change `configure', so that the
- results of some tests might be different from the previous run.  The
- `--recheck' option re-runs `configure' with the same arguments you used
- before, plus the `--no-create' option, which prevent `configure' from
- running `config.status' and creating `Makefile' and other files, and
- the `--no-recursion' option, which prevents `configure' from running
- other `configure' scripts in subdirectories.  (This is so other
- `Makefile' rules can run `config.status' when it changes; *note
- Automatic Remaking::., for an example).
- 
-    `config.status' also accepts the options `--help', which prints a
- summary of the options to `config.status', and `--version', which
- prints the version of Autoconf used to create the `configure' script
- that generated `config.status'.
- 
-    `config.status' checks several optional environment variables that
- can alter its behavior:
- 
-  - Variable: CONFIG_SHELL
-      The shell with which to run `configure' for the `--recheck'
-      option.  It must be Bourne-compatible.  The default is `/bin/sh'.
- 
-  - Variable: CONFIG_STATUS
-      The file name to use for the shell script that records the
-      configuration.  The default is `./config.status'.  This variable is
-      useful when one package uses parts of another and the `configure'
-      scripts shouldn't be merged because they are maintained separately.
- 
-    The following variables provide one way for separately distributed
- packages to share the values computed by `configure'.  Doing so can be
- useful if some of the packages need a superset of the features that one
- of them, perhaps a common library, does.  These variables allow a
- `config.status' file to create files other than the ones that its
- `configure.in' specifies, so it can be used for a different package.
- 
-  - Variable: CONFIG_FILES
-      The files in which to perform `@VARIABLE@' substitutions.  The
-      default is the arguments given to `AC_OUTPUT' in `configure.in'.
- 
-  - Variable: CONFIG_HEADERS
-      The files in which to substitute C `#define' statements.  The
-      default is the arguments given to `AC_CONFIG_HEADER'; if that
-      macro was not called, `config.status' ignores this variable.
- 
-    These variables also allow you to write `Makefile' rules that
- regenerate only some of the files.  For example, in the dependencies
- given above (*note Automatic Remaking::.), `config.status' is run twice
- when `configure.in' has changed.  If that bothers you, you can make
- each run only regenerate the files for that rule:
- 
-      config.h: stamp-h
-      stamp-h: config.h.in config.status
-              CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
-              echo > stamp-h
-      
-      Makefile: Makefile.in config.status
-              CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
- 
- (If `configure.in' does not call `AC_CONFIG_HEADER', there is no need
- to set `CONFIG_HEADERS' in the `make' rules.)
- 
- 
- File: autoconf.info,  Node: Questions,  Next: Upgrading,  Prev: Invoking config.status,  Up: Top
- 
- Questions About Autoconf
- ************************
- 
-    Several questions about Autoconf come up occasionally.  Here some of
- them are addressed.
- 
- * Menu:
- 
- * Distributing::                Distributing `configure' scripts.
- * Why GNU m4::                  Why not use the standard `m4'?
- * Bootstrapping::               Autoconf and GNU `m4' require each other?
- * Why Not Imake::               Why GNU uses `configure' instead of Imake.
- 
- 
- File: autoconf.info,  Node: Distributing,  Next: Why GNU m4,  Up: Questions
- 
- Distributing `configure' Scripts
- ================================
- 
-      What are the restrictions on distributing `configure'
-      scripts that Autoconf generates?  How does that affect my
-      programs that use them?
- 
-    There are no restrictions on how the configuration scripts that
- Autoconf produces may be distributed or used.  In Autoconf version 1,
- they were covered by the GNU General Public License.  We still
- encourage software authors to distribute their work under terms like
- those of the GPL, but doing so is not required to use Autoconf.
- 
-    Of the other files that might be used with `configure',
- `config.h.in' is under whatever copyright you use for your
- `configure.in', since it is derived from that file and from the public
- domain file `acconfig.h'.  `config.sub' and `config.guess' have an
- exception to the GPL when they are used with an Autoconf-generated
- `configure' script, which permits you to distribute them under the same
- terms as the rest of your package.  `install-sh' is from the X
- Consortium and is not copyrighted.
- 
- 
- File: autoconf.info,  Node: Why GNU m4,  Next: Bootstrapping,  Prev: Distributing,  Up: Questions
- 
- Why Require GNU `m4'?
- =====================
- 
-      Why does Autoconf require GNU `m4'?
- 
-    Many `m4' implementations have hard-coded limitations on the size
- and number of macros, which Autoconf exceeds.  They also lack several
- builtin macros that it would be difficult to get along without in a
- sophisticated application like Autoconf, including:
- 
-      builtin
-      indir
-      patsubst
-      __file__
-      __line__
- 
-    Since only software maintainers need to use Autoconf, and since GNU
- `m4' is simple to configure and install, it seems reasonable to require
- GNU `m4' to be installed also.  Many maintainers of GNU and other free
- software already have most of the GNU utilities installed, since they
- prefer them.
- 
- 
- File: autoconf.info,  Node: Bootstrapping,  Next: Why Not Imake,  Prev: Why GNU m4,  Up: Questions
- 
- How Can I Bootstrap?
- ====================
- 
-      If Autoconf requires GNU `m4' and GNU `m4' has an
-      Autoconf `configure' script, how do I bootstrap?  It seems
-      like a chicken and egg problem!
- 
-    This is a misunderstanding.  Although GNU `m4' does come with a
- `configure' script produced by Autoconf, Autoconf is not required in
- order to run the script and install GNU `m4'.  Autoconf is only
- required if you want to change the `m4' `configure' script, which few
- people have to do (mainly its maintainer).
- 
- 
- File: autoconf.info,  Node: Why Not Imake,  Prev: Bootstrapping,  Up: Questions
- 
- Why Not Imake?
- ==============
- 
-      Why not use Imake instead of `configure' scripts?
- 
-    Several people have written addressing this question, so I include
- adaptations of their explanations here.
- 
-    The following answer is based on one written by Richard Pixley:
- 
-    Autoconf generated scripts frequently work on machines which it has
- never been set up to handle before.  That is, it does a good job of
- inferring a configuration for a new system.  Imake cannot do this.
- 
-    Imake uses a common database of host specific data.  For X11, this
- makes sense because the distribution is made as a collection of tools,
- by one central authority who has control over the database.
- 
-    GNU tools are not released this way.  Each GNU tool has a maintainer;
- these maintainers are scattered across the world.  Using a common
- database would be a maintenance nightmare.  Autoconf may appear to be
- this kind of database, but in fact it is not.  Instead of listing host
- dependencies, it lists program requirements.
- 
-    If you view the GNU suite as a collection of native tools, then the
- problems are similar.  But the GNU development tools can be configured
- as cross tools in almost any host+target permutation.  All of these
- configurations can be installed concurrently.  They can even be
- configured to share host independent files across hosts.  Imake doesn't
- address these issues.
- 
-    Imake templates are a form of standardization.  The GNU coding
- standards address the same issues without necessarily imposing the same
- restrictions.
- 
-    Here is some further explanation, written by Per Bothner:
- 
-    One of the advantages of Imake is that it easy to generate large
- Makefiles using `cpp''s `#include' and macro mechanisms.  However,
- `cpp' is not programmable: it has limited conditional facilities, and
- no looping.  And `cpp' cannot inspect its environment.
- 
-    All of these problems are solved by using `sh' instead of `cpp'.
- The shell is fully programmable, has macro substitution, can execute
- (or source) other shell scripts, and can inspect its environment.
- 
-    Paul Eggert elaborates more:
- 
-    With Autoconf, installers need not assume that Imake itself is
- already installed and working well.  This may not seem like much of an
- advantage to people who are accustomed to Imake.  But on many hosts
- Imake is not installed or the default installation is not working well,
- and requiring Imake to install a package hinders the acceptance of that
- package on those hosts.  For example, the Imake template and
- configuration files might not be installed properly on a host, or the
- Imake build procedure might wrongly assume that all source files are in
- one big directory tree, or the Imake configuration might assume one
- compiler whereas the package or the installer needs to use another, or
- there might be a version mismatch between the Imake expected by the
- package and the Imake supported by the host.  These problems are much
- rarer with Autoconf, where each package comes with its own independent
- configuration processor.
- 
-    Also, Imake often suffers from unexpected interactions between
- `make' and the installer's C preprocessor.  The fundamental problem
- here is that the C preprocessor was designed to preprocess C programs,
- not `Makefile's.  This is much less of a problem with Autoconf, which
- uses the general-purpose preprocessor `m4', and where the package's
- author (rather than the installer) does the preprocessing in a standard
- way.
- 
-    Finally, Mark Eichin notes:
- 
-    Imake isn't all that extensible, either.  In order to add new
- features to Imake, you need to provide your own project template, and
- duplicate most of the features of the existing one.  This means that
- for a sophisticated project, using the vendor-provided Imake templates
- fails to provide any leverage--since they don't cover anything that
- your own project needs (unless it is an X11 program).
- 
-    On the other side, though:
- 
-    The one advantage that Imake has over `configure': `Imakefile's tend
- to be much shorter (likewise, less redundant) than `Makefile.in's.
- There is a fix to this, however--at least for the Kerberos V5 tree,
- we've modified things to call in common `post.in' and `pre.in'
- `Makefile' fragments for the entire tree.  This means that a lot of
- common things don't have to be duplicated, even though they normally
- are in `configure' setups.
- 
- 
- File: autoconf.info,  Node: Upgrading,  Next: History,  Prev: Questions,  Up: Top
- 
- Upgrading From Version 1
- ************************
- 
-    Autoconf version 2 is mostly backward compatible with version 1.
- However, it introduces better ways to do some things, and doesn't
- support some of the ugly things in version 1.  So, depending on how
- sophisticated your `configure.in' files are, you might have to do some
- manual work in order to upgrade to version 2.  This chapter points out
- some problems to watch for when upgrading.  Also, perhaps your
- `configure' scripts could benefit from some of the new features in
- version 2; the changes are summarized in the file `NEWS' in the
- Autoconf distribution.
- 
-    First, make sure you have GNU `m4' version 1.1 or higher installed,
- preferably 1.3 or higher.  Versions before 1.1 have bugs that prevent
- them from working with Autoconf version 2.  Versions 1.3 and later are
- much faster than earlier versions, because as of version 1.3, GNU `m4'
- has a more efficient implementation of diversions and can freeze its
- internal state in a file that it can read back quickly.
- 
- * Menu:
- 
- * Changed File Names::          Files you might rename.
- * Changed Makefiles::           New things to put in `Makefile.in'.
- * Changed Macros::              Macro calls you might replace.
- * Invoking autoupdate::         Replacing old macro names in `configure.in'.
- * Changed Results::             Changes in how to check test results.
- * Changed Macro Writing::       Better ways to write your own macros.
- 
- 
- File: autoconf.info,  Node: Changed File Names,  Next: Changed Makefiles,  Up: Upgrading
- 
- Changed File Names
- ==================
- 
-    If you have an `aclocal.m4' installed with Autoconf (as opposed to
- in a particular package's source directory), you must rename it to
- `acsite.m4'.  *Note Invoking autoconf::.
- 
-    If you distribute `install.sh' with your package, rename it to
- `install-sh' so `make' builtin rules won't inadvertently create a file
- called `install' from it.  `AC_PROG_INSTALL' looks for the script under
- both names, but it is best to use the new name.
- 
-    If you were using `config.h.top' or `config.h.bot', you still can,
- but you will have less clutter if you merge them into `acconfig.h'.
- *Note Invoking autoheader::.
- 
- 
- File: autoconf.info,  Node: Changed Makefiles,  Next: Changed Macros,  Prev: Changed File Names,  Up: Upgrading
- 
- Changed Makefiles
- =================
- 
-    Add `@CFLAGS@', `@CPPFLAGS@', and `@LDFLAGS@' in your `Makefile.in'
- files, so they can take advantage of the values of those variables in
- the environment when `configure' is run.  Doing this isn't necessary,
- but it's a convenience for users.
- 
-    Also add `@configure_input@' in a comment to each non-`Makefile'
- input file for `AC_OUTPUT', so that the output files will contain a
- comment saying they were produced by `configure'.  Automatically
- selecting the right comment syntax for all the kinds of files that
- people call `AC_OUTPUT' on became too much work.
- 
-    Add `config.log' and `config.cache' to the list of files you remove
- in `distclean' targets.
- 
-    If you have the following in `Makefile.in':
- 
-      prefix = /usr/local
-      exec_prefix = ${prefix}
- 
- you must change it to:
- 
-      prefix = @prefix@
-      exec_prefix = @exec_prefix@
- 
- The old behavior of replacing those variables without `@' characters
- around them has been removed.
- 
- 
- File: autoconf.info,  Node: Changed Macros,  Next: Invoking autoupdate,  Prev: Changed Makefiles,  Up: Upgrading
- 
- Changed Macros
- ==============
- 
-    Many of the macros were renamed in Autoconf version 2.  You can still
- use the old names, but the new ones are clearer, and it's easier to find
- the documentation for them.  *Note Old Macro Names::, for a table
- showing the new names for the old macros.  Use the `autoupdate' program
- to convert your `configure.in' to using the new macro names.  *Note
- Invoking autoupdate::.
- 
-    Some macros have been superseded by similar ones that do the job
- better, but are not call-compatible.  If you get warnings about calling
- obsolete macros while running `autoconf', you may safely ignore them,
- but your `configure' script will generally work better if you follow
- the advice it prints about what to replace the obsolete macros with.  In
- particular, the mechanism for reporting the results of tests has
- changed.  If you were using `echo' or `AC_VERBOSE' (perhaps via
- `AC_COMPILE_CHECK'), your `configure' script's output will look better
- if you switch to `AC_MSG_CHECKING' and `AC_MSG_RESULT'.  *Note Printing
- Messages::.  Those macros work best in conjunction with cache
- variables.  *Note Caching Results::.
- 
- 
- File: autoconf.info,  Node: Invoking autoupdate,  Next: Changed Results,  Prev: Changed Macros,  Up: Upgrading
- 
- Using `autoupdate' to Modernize `configure'
- ===========================================
- 
-    The `autoupdate' program updates a `configure.in' file that calls
- Autoconf macros by their old names to use the current macro names.  In
- version 2 of Autoconf, most of the macros were renamed to use a more
- uniform and descriptive naming scheme.  *Note Macro Names::, for a
- description of the new scheme.  Although the old names still work
- (*note Old Macro Names::., for a list of the old macro names and the
- corresponding new names), you can make your `configure.in' files more
- readable and make it easier to use the current Autoconf documentation
- if you update them to use the new macro names.
- 
-    If given no arguments, `autoupdate' updates `configure.in', backing
- up the original version with the suffix `~' (or the value of the
- environment variable `SIMPLE_BACKUP_SUFFIX', if that is set).  If you
- give `autoupdate' an argument, it reads that file instead of
- `configure.in' and writes the updated file to the standard output.
- 
- `autoupdate' accepts the following options:
- 
- `--help'
- `-h'
-      Print a summary of the command line options and exit.
- 
- `--macrodir=DIR'
- `-m DIR'
-      Look for the Autoconf macro files in directory DIR instead of the
-      default installation directory.  You can also set the `AC_MACRODIR'
-      environment variable to a directory; this option overrides the
-      environment variable.
- 
- `--version'
-      Print the version number of `autoupdate' and exit.
- 
- 
- File: autoconf.info,  Node: Changed Results,  Next: Changed Macro Writing,  Prev: Invoking autoupdate,  Up: Upgrading
- 
- Changed Results
- ===============
- 
-    If you were checking the results of previous tests by examining the
- shell variable `DEFS', you need to switch to checking the values of the
- cache variables for those tests.  `DEFS' no longer exists while
- `configure' is running; it is only created when generating output
- files.  This difference from version 1 is because properly quoting the
- contents of that variable turned out to be too cumbersome and
- inefficient to do every time `AC_DEFINE' is called.  *Note Cache
- Variable Names::.
- 
-    For example, here is a `configure.in' fragment written for Autoconf
- version 1:
- 
-      AC_HAVE_FUNCS(syslog)
-      case "$DEFS" in
-      *-DHAVE_SYSLOG*) ;;
-      *) # syslog is not in the default libraries.  See if it's in some other.
-        saved_LIBS="$LIBS"
-        for lib in bsd socket inet; do
-          AC_CHECKING(for syslog in -l$lib)
-          LIBS="$saved_LIBS -l$lib"
-          AC_HAVE_FUNCS(syslog)
-          case "$DEFS" in
-          *-DHAVE_SYSLOG*) break ;;
-          *) ;;
-          esac
-          LIBS="$saved_LIBS"
-        done ;;
-      esac
- 
-    Here is a way to write it for version 2:
- 
-      AC_CHECK_FUNCS(syslog)
-      if test $ac_cv_func_syslog = no; then
-        # syslog is not in the default libraries.  See if it's in some other.
-        for lib in bsd socket inet; do
-          AC_CHECK_LIB($lib, syslog, [AC_DEFINE(HAVE_SYSLOG)
-            LIBS="$LIBS $lib"; break])
-        done
-      fi
- 
-    If you were working around bugs in `AC_DEFINE_UNQUOTED' by adding
- backslashes before quotes, you need to remove them.  It now works
- predictably, and does not treat quotes (except backquotes) specially.
- *Note Setting Output Variables::.
- 
-    All of the boolean shell variables set by Autoconf macros now use
- `yes' for the true value.  Most of them use `no' for false, though for
- backward compatibility some use the empty string instead.  If you were
- relying on a shell variable being set to something like 1 or `t' for
- true, you need to change your tests.
- 
- 
- File: autoconf.info,  Node: Changed Macro Writing,  Prev: Changed Results,  Up: Upgrading
- 
- Changed Macro Writing
- =====================
- 
-    When defining your own macros, you should now use `AC_DEFUN' instead
- of `define'.  `AC_DEFUN' automatically calls `AC_PROVIDE' and ensures
- that macros called via `AC_REQUIRE' do not interrupt other macros, to
- prevent nested `checking...' messages on the screen.  There's no actual
- harm in continuing to use the older way, but it's less convenient and
- attractive.  *Note Macro Definitions::.
- 
-    You probably looked at the macros that came with Autoconf as a guide
- for how to do things.  It would be a good idea to take a look at the new
- versions of them, as the style is somewhat improved and they take
- advantage of some new features.
- 
-    If you were doing tricky things with undocumented Autoconf internals
- (macros, variables, diversions), check whether you need to change
- anything to account for changes that have been made.  Perhaps you can
- even use an officially supported technique in version 2 instead of
- kludging.  Or perhaps not.
- 
-    To speed up your locally written feature tests, add caching to them.
- See whether any of your tests are of general enough usefulness to
- encapsulate into macros that you can share.
- 
- 
- File: autoconf.info,  Node: History,  Next: Old Macro Names,  Prev: Upgrading,  Up: Top
- 
- History of Autoconf
- *******************
- 
-    You may be wondering, Why was Autoconf originally written?  How did
- it get into its present form?  (Why does it look like gorilla spit?)  If
- you're not wondering, then this chapter contains no information useful
- to you, and you might as well skip it.  If you *are* wondering, then
- let there be light...
- 
- * Menu:
- 
- * Genesis::			Prehistory and naming of `configure'.
- * Exodus::			The plagues of `m4' and Perl.
- * Leviticus::			The priestly code of portability arrives.
- * Numbers::			Growth and contributors.
- * Deuteronomy::			Approaching the promises of easy configuration.
- 
- 
- File: autoconf.info,  Node: Genesis,  Next: Exodus,  Up: History
- 
- Genesis
- =======
- 
-    In June 1991 I was maintaining many of the GNU utilities for the Free
- Software Foundation.  As they were ported to more platforms and more
- programs were added, the number of `-D' options that users had to
- select in the `Makefile' (around 20) became burdensome.  Especially for
- me--I had to test each new release on a bunch of different systems.  So
- I wrote a little shell script to guess some of the correct settings for
- the fileutils package, and released it as part of fileutils 2.0.  That
- `configure' script worked well enough that the next month I adapted it
- (by hand) to create similar `configure' scripts for several other GNU
- utilities packages.  Brian Berliner also adapted one of my scripts for
- his CVS revision control system.
- 
-    Later that summer, I learned that Richard Stallman and Richard Pixley
- were developing similar scripts to use in the GNU compiler tools; so I
- adapted my `configure' scripts to support their evolving interface:
- using the file name `Makefile.in' as the templates; adding `+srcdir',
- the first option (of many); and creating `config.status' files.
- 
- 
- File: autoconf.info,  Node: Exodus,  Next: Leviticus,  Prev: Genesis,  Up: History
- 
- Exodus
- ======
- 
-    As I got feedback from users, I incorporated many improvements, using
- Emacs to search and replace, cut and paste, similar changes in each of
- the scripts.  As I adapted more GNU utilities packages to use
- `configure' scripts, updating them all by hand became impractical.
- Rich Murphey, the maintainer of the GNU graphics utilities, sent me mail
- saying that the `configure' scripts were great, and asking if I had a
- tool for generating them that I could send him.  No, I thought, but I
- should!  So I started to work out how to generate them.  And the
- journey from the slavery of hand-written `configure' scripts to the
- abundance and ease of Autoconf began.
- 
-    Cygnus `configure', which was being developed at around that time,
- is table driven; it is meant to deal mainly with a discrete number of
- system types with a small number of mainly unguessable features (such as
- details of the object file format).  The automatic configuration system
- that Brian Fox had developed for Bash takes a similar approach.  For
- general use, it seems to me a hopeless cause to try to maintain an
- up-to-date database of which features each variant of each operating
- system has.  It's easier and more reliable to check for most features on
- the fly--especially on hybrid systems that people have hacked on
- locally or that have patches from vendors installed.
- 
-    I considered using an architecture similar to that of Cygnus
- `configure', where there is a single `configure' script that reads
- pieces of `configure.in' when run.  But I didn't want to have to
- distribute all of the feature tests with every package, so I settled on
- having a different `configure' made from each `configure.in' by a
- preprocessor.  That approach also offered more control and flexibility.
- 
-    I looked briefly into using the Metaconfig package, by Larry Wall,
- Harlan Stenn, and Raphael Manfredi, but I decided not to for several
- reasons.  The `Configure' scripts it produces are interactive, which I
- find quite inconvenient; I didn't like the ways it checked for some
- features (such as library functions); I didn't know that it was still
- being maintained, and the `Configure' scripts I had seen didn't work on
- many modern systems (such as System V R4 and NeXT); it wasn't very
- flexible in what it could do in response to a feature's presence or
- absence; I found it confusing to learn; and it was too big and complex
- for my needs (I didn't realize then how much Autoconf would eventually
- have to grow).
- 
-    I considered using Perl to generate my style of `configure' scripts,
- but decided that `m4' was better suited to the job of simple textual
- substitutions: it gets in the way less, because output is implicit.
- Plus, everyone already has it.  (Initially I didn't rely on the GNU
- extensions to `m4'.)  Also, some of my friends at the University of
- Maryland had recently been putting `m4' front ends on several programs,
- including `tvtwm', and I was interested in trying out a new language.
- 
- 
- File: autoconf.info,  Node: Leviticus,  Next: Numbers,  Prev: Exodus,  Up: History
- 
- Leviticus
- =========
- 
-    Since my `configure' scripts determine the system's capabilities
- automatically, with no interactive user intervention, I decided to call
- the program that generates them Autoconfig.  But with a version number
- tacked on, that name would be too long for old UNIX file systems, so I
- shortened it to Autoconf.
- 
-    In the fall of 1991 I called together a group of fellow questers
- after the Holy Grail of portability (er, that is, alpha testers) to
- give me feedback as I encapsulated pieces of my handwritten scripts in
- `m4' macros and continued to add features and improve the techniques
- used in the checks.  Prominent among the testers were Franc,ois Pinard,
- who came up with the idea of making an `autoconf' shell script to run
- `m4' and check for unresolved macro calls; Richard Pixley, who
- suggested running the compiler instead of searching the file system to
- find include files and symbols, for more accurate results; Karl Berry,
- who got Autoconf to configure TeX and added the macro index to the
- documentation; and Ian Taylor, who added support for creating a C
- header file as an alternative to putting `-D' options in a `Makefile',
- so he could use Autoconf for his UUCP package.  The alpha testers
- cheerfully adjusted their files again and again as the names and
- calling conventions of the Autoconf macros changed from release to
- release.  They all contributed many specific checks, great ideas, and
- bug fixes.
- 
--- 0 ----
Index: krb5/util/autoconf/autoconf.info-5
diff -c krb5/util/autoconf/autoconf.info-5:1.1.1.1 krb5/util/autoconf/autoconf.info-5:removed
*** krb5/util/autoconf/autoconf.info-5:1.1.1.1	Mon Jun  2 17:58:31 1997
--- krb5/util/autoconf/autoconf.info-5	Sun Mar 16 20:22:40 2003
***************
*** 1,700 ****
- This is Info file autoconf.info, produced by Makeinfo-1.55 from the
- input file autoconf.texi.
- 
- START-INFO-DIR-ENTRY
- * Autoconf: (autoconf).         Create source code configuration scripts.
- END-INFO-DIR-ENTRY
- 
-    Autoconf: Creating Automatic Configuration Scripts, by David
- MacKenzie.
- 
-    This file documents the GNU Autoconf package for creating scripts to
- configure source code packages using templates and an `m4' macro
- package.
- 
-    Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Foundation.
- 
- 
- File: autoconf.info,  Node: Numbers,  Next: Deuteronomy,  Prev: Leviticus,  Up: History
- 
- Numbers
- =======
- 
-    In July 1992, after months of alpha testing, I released Autoconf 1.0,
- and converted many GNU packages to use it.  I was surprised by how
- positive the reaction to it was.  More people started using it than I
- could keep track of, including people working on software that wasn't
- part of the GNU Project (such as TCL, FSP, and Kerberos V5).  Autoconf
- continued to improve rapidly, as many people using the `configure'
- scripts reported problems they encountered.
- 
-    Autoconf turned out to be a good torture test for `m4'
- implementations.  UNIX `m4' started to dump core because of the length
- of the macros that Autoconf defined, and several bugs showed up in GNU
- `m4' as well.  Eventually, we realized that we needed to use some
- features that only GNU `m4' has.  4.3BSD `m4', in particular, has an
- impoverished set of builtin macros; the System V version is better, but
- still doesn't provide everything we need.
- 
-    More development occurred as people put Autoconf under more stresses
- (and to uses I hadn't anticipated).  Karl Berry added checks for X11.
- david zuhn contributed C++ support.  Franc,ois Pinard made it diagnose
- invalid arguments.  Jim Blandy bravely coerced it into configuring GNU
- Emacs, laying the groundwork for several later improvements.  Roland
- McGrath got it to configure the GNU C Library, wrote the `autoheader'
- script to automate the creation of C header file templates, and added a
- `--verbose' option to `configure'.  Noah Friedman added the
- `--macrodir' option and `AC_MACRODIR' environment variable.  (He also
- coined the term "autoconfiscate" to mean "adapt a software package to
- use Autoconf".)  Roland and Noah improved the quoting protection in
- `AC_DEFINE' and fixed many bugs, especially when I got sick of dealing
- with portability problems from February through June, 1993.
- 
- 
- File: autoconf.info,  Node: Deuteronomy,  Prev: Numbers,  Up: History
- 
- Deuteronomy
- ===========
- 
-    A long wish list for major features had accumulated, and the effect
- of several years of patching by various people had left some residual
- cruft.  In April 1994, while working for Cygnus Support, I began a major
- revision of Autoconf.  I added most of the features of the Cygnus
- `configure' that Autoconf had lacked, largely by adapting the relevant
- parts of Cygnus `configure' with the help of david zuhn and Ken
- Raeburn.  These features include support for using `config.sub',
- `config.guess', `--host', and `--target'; making links to files; and
- running `configure' scripts in subdirectories.  Adding these features
- enabled Ken to convert GNU `as', and Rob Savoye to convert DejaGNU, to
- using Autoconf.
- 
-    I added more features in response to other peoples' requests.  Many
- people had asked for `configure' scripts to share the results of the
- checks between runs, because (particularly when configuring a large
- source tree, like Cygnus does) they were frustratingly slow.  Mike
- Haertel suggested adding site-specific initialization scripts.  People
- distributing software that had to unpack on MS-DOS asked for a way to
- override the `.in' extension on the file names, which produced file
- names like `config.h.in' containing two dots.  Jim Avera did an
- extensive examination of the problems with quoting in `AC_DEFINE' and
- `AC_SUBST'; his insights led to significant improvements.  Richard
- Stallman asked that compiler output be sent to `config.log' instead of
- `/dev/null', to help people debug the Emacs `configure' script.
- 
-    I made some other changes because of my dissatisfaction with the
- quality of the program.  I made the messages showing results of the
- checks less ambiguous, always printing a result.  I regularized the
- names of the macros and cleaned up coding style inconsistencies.  I
- added some auxiliary utilities that I had developed to help convert
- source code packages to use Autoconf.  With the help of Franc,ois
- Pinard, I made the macros not interrupt each others' messages.  (That
- feature revealed some performance bottlenecks in GNU `m4', which he
- hastily corrected!) I reorganized the documentation around problems
- people want to solve.  And I began a testsuite, because experience had
- shown that Autoconf has a pronounced tendency to regress when we change
- it.
- 
-    Again, several alpha testers gave invaluable feedback, especially
- Franc,ois Pinard, Jim Meyering, Karl Berry, Rob Savoye, Ken Raeburn,
- and Mark Eichin.
- 
-    Finally, version 2.0 was ready.  And there was much rejoicing.  (And
- I have free time again.  I think.  Yeah, right.)
- 
- 
- File: autoconf.info,  Node: Old Macro Names,  Next: Environment Variable Index,  Prev: History,  Up: Top
- 
- Old Macro Names
- ***************
- 
-    In version 2 of Autoconf, most of the macros were renamed to use a
- more uniform and descriptive naming scheme.  Here are the old names of
- the macros that were renamed, followed by the current names of those
- macros.  Although the old names are still accepted by the `autoconf'
- program for backward compatibility, the old names are considered
- obsolete.  *Note Macro Names::, for a description of the new naming
- scheme.
- 
- `AC_ALLOCA'
-      `AC_FUNC_ALLOCA'
- 
- `AC_ARG_ARRAY'
-      removed because of limited usefulness
- 
- `AC_CHAR_UNSIGNED'
-      `AC_C_CHAR_UNSIGNED'
- 
- `AC_CONST'
-      `AC_C_CONST'
- 
- `AC_CROSS_CHECK'
-      `AC_C_CROSS'
- 
- `AC_ERROR'
-      `AC_MSG_ERROR'
- 
- `AC_FIND_X'
-      `AC_PATH_X'
- 
- `AC_FIND_XTRA'
-      `AC_PATH_XTRA'
- 
- `AC_FUNC_CHECK'
-      `AC_CHECK_FUNC'
- 
- `AC_GCC_TRADITIONAL'
-      `AC_PROG_GCC_TRADITIONAL'
- 
- `AC_GETGROUPS_T'
-      `AC_TYPE_GETGROUPS'
- 
- `AC_GETLOADAVG'
-      `AC_FUNC_GETLOADAVG'
- 
- `AC_HAVE_FUNCS'
-      `AC_CHECK_FUNCS'
- 
- `AC_HAVE_HEADERS'
-      `AC_CHECK_HEADERS'
- 
- `AC_HAVE_POUNDBANG'
-      `AC_SYS_INTERPRETER' (different calling convention)
- 
- `AC_HEADER_CHECK'
-      `AC_CHECK_HEADER'
- 
- `AC_HEADER_EGREP'
-      `AC_EGREP_HEADER'
- 
- `AC_INLINE'
-      `AC_C_INLINE'
- 
- `AC_LN_S'
-      `AC_PROG_LN_S'
- 
- `AC_LONG_DOUBLE'
-      `AC_C_LONG_DOUBLE'
- 
- `AC_LONG_FILE_NAMES'
-      `AC_SYS_LONG_FILE_NAMES'
- 
- `AC_MAJOR_HEADER'
-      `AC_HEADER_MAJOR'
- 
- `AC_MINUS_C_MINUS_O'
-      `AC_PROG_CC_C_O'
- 
- `AC_MMAP'
-      `AC_FUNC_MMAP'
- 
- `AC_MODE_T'
-      `AC_TYPE_MODE_T'
- 
- `AC_OFF_T'
-      `AC_TYPE_OFF_T'
- 
- `AC_PID_T'
-      `AC_TYPE_PID_T'
- 
- `AC_PREFIX'
-      `AC_PREFIX_PROGRAM'
- 
- `AC_PROGRAMS_CHECK'
-      `AC_CHECK_PROGS'
- 
- `AC_PROGRAMS_PATH'
-      `AC_PATH_PROGS'
- 
- `AC_PROGRAM_CHECK'
-      `AC_CHECK_PROG'
- 
- `AC_PROGRAM_EGREP'
-      `AC_EGREP_CPP'
- 
- `AC_PROGRAM_PATH'
-      `AC_PATH_PROG'
- 
- `AC_REMOTE_TAPE'
-      removed because of limited usefulness
- 
- `AC_RESTARTABLE_SYSCALLS'
-      `AC_SYS_RESTARTABLE_SYSCALLS'
- 
- `AC_RETSIGTYPE'
-      `AC_TYPE_SIGNAL'
- 
- `AC_RSH'
-      removed because of limited usefulness
- 
- `AC_SETVBUF_REVERSED'
-      `AC_FUNC_SETVBUF_REVERSED'
- 
- `AC_SET_MAKE'
-      `AC_PROG_MAKE_SET'
- 
- `AC_SIZEOF_TYPE'
-      `AC_CHECK_SIZEOF'
- 
- `AC_SIZE_T'
-      `AC_TYPE_SIZE_T'
- 
- `AC_STAT_MACROS_BROKEN'
-      `AC_HEADER_STAT'
- 
- `AC_STDC_HEADERS'
-      `AC_HEADER_STDC'
- 
- `AC_STRCOLL'
-      `AC_FUNC_STRCOLL'
- 
- `AC_ST_BLKSIZE'
-      `AC_STRUCT_ST_BLKSIZE'
- 
- `AC_ST_BLOCKS'
-      `AC_STRUCT_ST_BLOCKS'
- 
- `AC_ST_RDEV'
-      `AC_STRUCT_ST_RDEV'
- 
- `AC_SYS_SIGLIST_DECLARED'
-      `AC_DECL_SYS_SIGLIST'
- 
- `AC_TEST_CPP'
-      `AC_TRY_CPP'
- 
- `AC_TEST_PROGRAM'
-      `AC_TRY_RUN'
- 
- `AC_TIMEZONE'
-      `AC_STRUCT_TIMEZONE'
- 
- `AC_TIME_WITH_SYS_TIME'
-      `AC_HEADER_TIME'
- 
- `AC_UID_T'
-      `AC_TYPE_UID_T'
- 
- `AC_UTIME_NULL'
-      `AC_FUNC_UTIME_NULL'
- 
- `AC_VFORK'
-      `AC_FUNC_VFORK'
- 
- `AC_VPRINTF'
-      `AC_FUNC_VPRINTF'
- 
- `AC_WAIT3'
-      `AC_FUNC_WAIT3'
- 
- `AC_WARN'
-      `AC_MSG_WARN'
- 
- `AC_WORDS_BIGENDIAN'
-      `AC_C_BIGENDIAN'
- 
- `AC_YYTEXT_POINTER'
-      `AC_DECL_YYTEXT'
- 
- 
- File: autoconf.info,  Node: Environment Variable Index,  Next: Output Variable Index,  Prev: Old Macro Names,  Up: Top
- 
- Environment Variable Index
- **************************
- 
-    This is an alphabetical list of the environment variables that
- Autoconf checks.
- 
- * Menu:
- 
- * AC_MACRODIR:                          Invoking autoupdate.
- * AC_MACRODIR:                          Invoking autoheader.
- * AC_MACRODIR:                          Invoking autoreconf.
- * AC_MACRODIR:                          Invoking autoconf.
- * AC_MACRODIR:                          Invoking ifnames.
- * AC_MACRODIR:                          Invoking autoscan.
- * CONFIG_FILES:                         Invoking config.status.
- * CONFIG_HEADERS:                       Invoking config.status.
- * CONFIG_SHELL:                         Invoking config.status.
- * CONFIG_SITE:                          Site Defaults.
- * CONFIG_STATUS:                        Invoking config.status.
- * SIMPLE_BACKUP_SUFFIX:                 Invoking autoupdate.
- 
- 
- File: autoconf.info,  Node: Output Variable Index,  Next: Preprocessor Symbol Index,  Prev: Environment Variable Index,  Up: Top
- 
- Output Variable Index
- *********************
- 
-    This is an alphabetical list of the variables that Autoconf can
- substitute into files that it creates, typically one or more
- `Makefile's.  *Note Setting Output Variables::, for more information on
- how this is done.
- 
- * Menu:
- 
- * ALLOCA:                               Particular Functions.
- * AWK:                                  Particular Programs.
- * build:                                System Type Variables.
- * build_alias:                          System Type Variables.
- * build_cpu:                            System Type Variables.
- * build_os:                             System Type Variables.
- * build_vendor:                         System Type Variables.
- * CC:                                   UNIX Variants.
- * CC:                                   Particular Programs.
- * CC:                                   Particular Programs.
- * CFLAGS:                               Particular Programs.
- * CFLAGS:                               Preset Output Variables.
- * configure_input:                      Preset Output Variables.
- * CPP:                                  Particular Programs.
- * CPPFLAGS:                             Preset Output Variables.
- * CXX:                                  Particular Programs.
- * CXXCPP:                               Particular Programs.
- * CXXFLAGS:                             Particular Programs.
- * CXXFLAGS:                             Preset Output Variables.
- * DEFS:                                 Preset Output Variables.
- * exec_prefix:                          Preset Output Variables.
- * host:                                 System Type Variables.
- * host_alias:                           System Type Variables.
- * host_cpu:                             System Type Variables.
- * host_os:                              System Type Variables.
- * host_vendor:                          System Type Variables.
- * INSTALL:                              Particular Programs.
- * INSTALL_DATA:                         Particular Programs.
- * INSTALL_PROGRAM:                      Particular Programs.
- * KMEM_GROUP:                           Particular Functions.
- * LDFLAGS:                              Preset Output Variables.
- * LEX:                                  Particular Programs.
- * LEXLIB:                               Particular Programs.
- * LEX_OUTPUT_ROOT:                      Particular Programs.
- * LIBOBJS:                              Structures.
- * LIBOBJS:                              Generic Functions.
- * LIBOBJS:                              Particular Functions.
- * LIBOBJS:                              Particular Functions.
- * LIBS:                                 UNIX Variants.
- * LIBS:                                 UNIX Variants.
- * LIBS:                                 Preset Output Variables.
- * LN_S:                                 Particular Programs.
- * NEED_SETGID:                          Particular Functions.
- * prefix:                               Preset Output Variables.
- * program_transform_name:               Transforming Names.
- * RANLIB:                               Particular Programs.
- * SET_MAKE:                             Output.
- * srcdir:                               Preset Output Variables.
- * subdirs:                              Subdirectories.
- * target:                               System Type Variables.
- * target_alias:                         System Type Variables.
- * target_cpu:                           System Type Variables.
- * target_os:                            System Type Variables.
- * target_vendor:                        System Type Variables.
- * top_srcdir:                           Preset Output Variables.
- * X_CFLAGS:                             System Services.
- * X_EXTRA_LIBS:                         System Services.
- * X_LIBS:                               System Services.
- * X_PRE_LIBS:                           System Services.
- * YACC:                                 Particular Programs.
- 
- 
- File: autoconf.info,  Node: Preprocessor Symbol Index,  Next: Macro Index,  Prev: Output Variable Index,  Up: Top
- 
- Preprocessor Symbol Index
- *************************
- 
-    This is an alphabetical list of the C preprocessor symbols that the
- Autoconf macros define.  To work with Autoconf, C source code needs to
- use these names in `#if' directives.
- 
- * Menu:
- 
- * CLOSEDIR_VOID:                        Particular Functions.
- * const:                                Compiler Characteristics.
- * C_ALLOCA:                             Particular Functions.
- * DGUX:                                 Particular Functions.
- * DIRENT:                               Particular Headers.
- * GETGROUPS_T:                          Particular Typedefs.
- * GETLODAVG_PRIVILEGED:                 Particular Functions.
- * GETPGRP_VOID:                         Particular Functions.
- * gid_t:                                Particular Typedefs.
- * HAVE_FUNCTION:                        Generic Functions.
- * HAVE_HEADER:                          Generic Headers.
- * HAVE_ALLOCA_H:                        Particular Functions.
- * HAVE_CONFIG_H:                        Configuration Headers.
- * HAVE_DIRENT_H:                        Particular Headers.
- * HAVE_DOPRNT:                          Particular Functions.
- * HAVE_GETMNTENT:                       Particular Functions.
- * HAVE_LONG_DOUBLE:                     Compiler Characteristics.
- * HAVE_LONG_FILE_NAMES:                 System Services.
- * HAVE_MMAP:                            Particular Functions.
- * HAVE_NDIR_H:                          Particular Headers.
- * HAVE_RESTARTABLE_SYSCALLS:            System Services.
- * HAVE_STRCOLL:                         Particular Functions.
- * HAVE_STRFTIME:                        Particular Functions.
- * HAVE_ST_BLKSIZE:                      Structures.
- * HAVE_ST_BLOCKS:                       Structures.
- * HAVE_ST_RDEV:                         Structures.
- * HAVE_SYS_DIR_H:                       Particular Headers.
- * HAVE_SYS_NDIR_H:                      Particular Headers.
- * HAVE_SYS_WAIT_H:                      Particular Headers.
- * HAVE_TM_ZONE:                         Structures.
- * HAVE_TZNAME:                          Structures.
- * HAVE_UNISTD_H:                        Particular Headers.
- * HAVE_UTIME_NULL:                      Particular Functions.
- * HAVE_VFORK_H:                         Particular Functions.
- * HAVE_VPRINTF:                         Particular Functions.
- * HAVE_WAIT3:                           Particular Functions.
- * inline:                               Compiler Characteristics.
- * INT_16_BITS:                          Compiler Characteristics.
- * LONG_64_BITS:                         Compiler Characteristics.
- * MAJOR_IN_MKDEV:                       Particular Headers.
- * MAJOR_IN_SYSMACROS:                   Particular Headers.
- * mode_t:                               Particular Typedefs.
- * NDIR:                                 Particular Headers.
- * NEED_MEMORY_H:                        Particular Headers.
- * NEED_SETGID:                          Particular Functions.
- * NLIST_NAME_UNION:                     Particular Functions.
- * NLIST_STRUCT:                         Particular Functions.
- * NO_MINUS_C_MINUS_O:                   Particular Programs.
- * off_t:                                Particular Typedefs.
- * pid_t:                                Particular Typedefs.
- * RETSIGTYPE:                           Particular Typedefs.
- * SETVBUF_REVERSED:                     Particular Functions.
- * size_t:                               Particular Typedefs.
- * STDC_HEADERS:                         Particular Headers.
- * SVR4:                                 Particular Functions.
- * SYSDIR:                               Particular Headers.
- * SYSNDIR:                              Particular Headers.
- * SYS_SIGLIST_DECLARED:                 Particular Headers.
- * TIME_WITH_SYS_TIME:                   Structures.
- * TM_IN_SYS_TIME:                       Structures.
- * uid_t:                                Particular Typedefs.
- * UMAX:                                 Particular Functions.
- * UMAX4_3:                              Particular Functions.
- * USG:                                  Particular Headers.
- * vfork:                                Particular Functions.
- * VOID_CLOSEDIR:                        Particular Headers.
- * WORDS_BIGENDIAN:                      Compiler Characteristics.
- * YYTEXT_POINTER:                       Particular Programs.
- * _ALL_SOURCE:                          UNIX Variants.
- * _MINIX:                               UNIX Variants.
- * _POSIX_1_SOURCE:                      UNIX Variants.
- * _POSIX_SOURCE:                        UNIX Variants.
- * _POSIX_SOURCE:                        UNIX Variants.
- * _POSIX_VERSION:                       Particular Headers.
- * __CHAR_UNSIGNED__:                    Compiler Characteristics.
- 
- 
- File: autoconf.info,  Node: Macro Index,  Prev: Preprocessor Symbol Index,  Up: Top
- 
- Macro Index
- ***********
- 
-    This is an alphabetical list of the Autoconf macros.  To make the
- list easier to use, the macros are listed without their preceding `AC_'.
- 
- * Menu:
- 
- * AIX:                                  UNIX Variants.
- * ALLOCA:                               Old Macro Names.
- * ARG_ARRAY:                            Old Macro Names.
- * ARG_ENABLE:                           Package Options.
- * ARG_PROGRAM:                          Transforming Names.
- * ARG_WITH:                             External Software.
- * BEFORE:                               Suggested Ordering.
- * CACHE_VAL:                            Caching Results.
- * CANONICAL_HOST:                       Canonicalizing.
- * CANONICAL_SYSTEM:                     Canonicalizing.
- * CHAR_UNSIGNED:                        Old Macro Names.
- * CHECKING:                             Printing Messages.
- * CHECK_FUNC:                           Generic Functions.
- * CHECK_FUNCS:                          Generic Functions.
- * CHECK_HEADER:                         Generic Headers.
- * CHECK_HEADERS:                        Generic Headers.
- * CHECK_LIB:                            Libraries.
- * CHECK_PROG:                           Generic Programs.
- * CHECK_PROGS:                          Generic Programs.
- * CHECK_SIZEOF:                         Compiler Characteristics.
- * CHECK_TOOL:                           Generic Programs.
- * CHECK_TYPE:                           Generic Typedefs.
- * COMPILE_CHECK:                        Examining Libraries.
- * CONFIG_AUX_DIR:                       Input.
- * CONFIG_HEADER:                        Configuration Headers.
- * CONFIG_SUBDIRS:                       Subdirectories.
- * CONST:                                Old Macro Names.
- * CROSS_CHECK:                          Old Macro Names.
- * C_BIGENDIAN:                          Compiler Characteristics.
- * C_CHAR_UNSIGNED:                      Compiler Characteristics.
- * C_CONST:                              Compiler Characteristics.
- * C_CROSS:                              Test Programs.
- * C_INLINE:                             Compiler Characteristics.
- * C_LONG_DOUBLE:                        Compiler Characteristics.
- * DECL_SYS_SIGLIST:                     Particular Headers.
- * DECL_YYTEXT:                          Particular Programs.
- * DEFINE:                               Defining Symbols.
- * DEFINE_UNQUOTED:                      Defining Symbols.
- * DEFUN:                                Macro Definitions.
- * DIR_HEADER:                           Particular Headers.
- * DYNIX_SEQ:                            UNIX Variants.
- * EGREP_CPP:                            Examining Declarations.
- * EGREP_HEADER:                         Examining Declarations.
- * ENABLE:                               Package Options.
- * ERROR:                                Old Macro Names.
- * FIND_X:                               Old Macro Names.
- * FIND_XTRA:                            Old Macro Names.
- * FUNC_ALLOCA:                          Particular Functions.
- * FUNC_CHECK:                           Old Macro Names.
- * FUNC_CLOSEDIR_VOID:                   Particular Functions.
- * FUNC_GETLOADAVG:                      Particular Functions.
- * FUNC_GETMNTENT:                       Particular Functions.
- * FUNC_GETPGRP:                         Particular Functions.
- * FUNC_MEMCMP:                          Particular Functions.
- * FUNC_MMAP:                            Particular Functions.
- * FUNC_SETVBUF_REVERSED:                Particular Functions.
- * FUNC_STRCOLL:                         Particular Functions.
- * FUNC_STRFTIME:                        Particular Functions.
- * FUNC_UTIME_NULL:                      Particular Functions.
- * FUNC_VFORK:                           Particular Functions.
- * FUNC_VPRINTF:                         Particular Functions.
- * FUNC_WAIT3:                           Particular Functions.
- * GCC_TRADITIONAL:                      Old Macro Names.
- * GETGROUPS_T:                          Old Macro Names.
- * GETLOADAVG:                           Old Macro Names.
- * HAVE_FUNCS:                           Old Macro Names.
- * HAVE_HEADERS:                         Old Macro Names.
- * HAVE_LIBRARY:                         Libraries.
- * HAVE_POUNDBANG:                       Old Macro Names.
- * HEADER_CHECK:                         Old Macro Names.
- * HEADER_DIRENT:                        Particular Headers.
- * HEADER_EGREP:                         Old Macro Names.
- * HEADER_MAJOR:                         Particular Headers.
- * HEADER_STAT:                          Structures.
- * HEADER_STDC:                          Particular Headers.
- * HEADER_SYS_WAIT:                      Particular Headers.
- * HEADER_TIME:                          Structures.
- * INIT:                                 Input.
- * INLINE:                               Old Macro Names.
- * INT_16_BITS:                          Compiler Characteristics.
- * IRIX_SUN:                             UNIX Variants.
- * ISC_POSIX:                            UNIX Variants.
- * LANG_C:                               Language Choice.
- * LANG_CPLUSPLUS:                       Language Choice.
- * LANG_RESTORE:                         Language Choice.
- * LANG_SAVE:                            Language Choice.
- * LINK_FILES:                           Using System Type.
- * LN_S:                                 Old Macro Names.
- * LONG_64_BITS:                         Compiler Characteristics.
- * LONG_DOUBLE:                          Old Macro Names.
- * LONG_FILE_NAMES:                      Old Macro Names.
- * MAJOR_HEADER:                         Old Macro Names.
- * MEMORY_H:                             Particular Headers.
- * MINIX:                                UNIX Variants.
- * MINUS_C_MINUS_O:                      Old Macro Names.
- * MMAP:                                 Old Macro Names.
- * MODE_T:                               Old Macro Names.
- * MSG_CHECKING:                         Printing Messages.
- * MSG_ERROR:                            Printing Messages.
- * MSG_RESULT:                           Printing Messages.
- * MSG_WARN:                             Printing Messages.
- * OBSOLETE:                             Obsolete Macros.
- * OFF_T:                                Old Macro Names.
- * OUTPUT:                               Output.
- * PATH_PROG:                            Generic Programs.
- * PATH_PROGS:                           Generic Programs.
- * PATH_X:                               System Services.
- * PATH_XTRA:                            System Services.
- * PID_T:                                Old Macro Names.
- * PREFIX:                               Old Macro Names.
- * PREFIX_PROGRAM:                       Default Prefix.
- * PREREQ:                               Versions.
- * PROGRAMS_CHECK:                       Old Macro Names.
- * PROGRAMS_PATH:                        Old Macro Names.
- * PROGRAM_CHECK:                        Old Macro Names.
- * PROGRAM_EGREP:                        Old Macro Names.
- * PROGRAM_PATH:                         Old Macro Names.
- * PROG_AWK:                             Particular Programs.
- * PROG_CC:                              Particular Programs.
- * PROG_CC_C_O:                          Particular Programs.
- * PROG_CPP:                             Particular Programs.
- * PROG_CXX:                             Particular Programs.
- * PROG_CXXCPP:                          Particular Programs.
- * PROG_GCC_TRADITIONAL:                 Particular Programs.
- * PROG_INSTALL:                         Particular Programs.
- * PROG_LEX:                             Particular Programs.
- * PROG_LN_S:                            Particular Programs.
- * PROG_MAKE_SET:                        Output.
- * PROG_RANLIB:                          Particular Programs.
- * PROG_YACC:                            Particular Programs.
- * PROVIDE:                              Prerequisite Macros.
- * REMOTE_TAPE:                          Old Macro Names.
- * REPLACE_FUNCS:                        Generic Functions.
- * REQUIRE:                              Prerequisite Macros.
- * REQUIRE_CPP:                          Language Choice.
- * RESTARTABLE_SYSCALLS:                 Old Macro Names.
- * RETSIGTYPE:                           Old Macro Names.
- * REVISION:                             Versions.
- * RSH:                                  Old Macro Names.
- * SCO_INTL:                             UNIX Variants.
- * SETVBUF_REVERSED:                     Old Macro Names.
- * SET_MAKE:                             Old Macro Names.
- * SIZEOF_TYPE:                          Old Macro Names.
- * SIZE_T:                               Old Macro Names.
- * STAT_MACROS_BROKEN:                   Old Macro Names.
- * STAT_MACROS_BROKEN:                   Structures.
- * STDC_HEADERS:                         Old Macro Names.
- * STRCOLL:                              Old Macro Names.
- * STRUCT_ST_BLKSIZE:                    Structures.
- * STRUCT_ST_BLOCKS:                     Structures.
- * STRUCT_ST_RDEV:                       Structures.
- * STRUCT_TIMEZONE:                      Structures.
- * STRUCT_TM:                            Structures.
- * ST_BLKSIZE:                           Old Macro Names.
- * ST_BLOCKS:                            Old Macro Names.
- * ST_RDEV:                              Old Macro Names.
- * SUBST:                                Setting Output Variables.
- * SUBST_FILE:                           Setting Output Variables.
- * SYS_INTERPRETER:                      System Services.
- * SYS_LONG_FILE_NAMES:                  System Services.
- * SYS_RESTARTABLE_SYSCALLS:             System Services.
- * SYS_SIGLIST_DECLARED:                 Old Macro Names.
- * TEST_CPP:                             Old Macro Names.
- * TEST_PROGRAM:                         Old Macro Names.
- * TIMEZONE:                             Old Macro Names.
- * TIME_WITH_SYS_TIME:                   Old Macro Names.
- * TRY_COMPILE:                          Examining Syntax.
- * TRY_CPP:                              Examining Declarations.
- * TRY_LINK:                             Examining Libraries.
- * TRY_RUN:                              Test Programs.
- * TYPE_GETGROUPS:                       Particular Typedefs.
- * TYPE_MODE_T:                          Particular Typedefs.
- * TYPE_OFF_T:                           Particular Typedefs.
- * TYPE_PID_T:                           Particular Typedefs.
- * TYPE_SIGNAL:                          Particular Typedefs.
- * TYPE_SIZE_T:                          Particular Typedefs.
- * TYPE_UID_T:                           Particular Typedefs.
- * UID_T:                                Old Macro Names.
- * UNISTD_H:                             Particular Headers.
- * USG:                                  Particular Headers.
- * UTIME_NULL:                           Old Macro Names.
- * VERBOSE:                              Printing Messages.
- * VFORK:                                Old Macro Names.
- * VPRINTF:                              Old Macro Names.
- * WAIT3:                                Old Macro Names.
- * WARN:                                 Old Macro Names.
- * WITH:                                 External Software.
- * WORDS_BIGENDIAN:                      Old Macro Names.
- * XENIX_DIR:                            UNIX Variants.
- * YYTEXT_POINTER:                       Old Macro Names.
- 
- 
--- 0 ----
Index: krb5/util/autoconf/configure
diff -c krb5/util/autoconf/configure:1.1.1.1 krb5/util/autoconf/configure:1.2
*** krb5/util/autoconf/configure:1.1.1.1	Mon Jun  2 17:58:33 1997
--- krb5/util/autoconf/configure	Mon Feb 25 03:04:48 2002
***************
*** 1,7 ****
  #! /bin/sh
  
  # Guess values for system-dependent variables and create Makefiles.
! # Generated automatically using autoconf version 2.10 
  # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
  #
  # This configure script is free software; the Free Software Foundation
--- 1,7 ----
  #! /bin/sh
  
  # Guess values for system-dependent variables and create Makefiles.
! # Generated automatically using autoconf version 2.13 
  # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
  #
  # This configure script is free software; the Free Software Foundation
***************
*** 49,54 ****
--- 49,57 ----
  # Initialize some other variables.
  subdirs=
  MFLAGS= MAKEFLAGS=
+ SHELL=${CONFIG_SHELL-/bin/sh}
+ # Maximum number of lines to put in a shell here document.
+ ac_max_here_lines=12
  
  ac_prev=
  for ac_option
***************
*** 330,336 ****
      verbose=yes ;;
  
    -version | --version | --versio | --versi | --vers)
!     echo "configure generated by autoconf version 2.10"
      exit 0 ;;
  
    -with-* | --with-*)
--- 333,339 ----
      verbose=yes ;;
  
    -version | --version | --versio | --versi | --vers)
!     echo "configure generated by autoconf version 2.13"
      exit 0 ;;
  
    -with-* | --with-*)
***************
*** 432,442 ****
  done
  
  # NLS nuisances.
! # Only set LANG and LC_ALL to C if already set.
! # These must not be set unconditionally because not all systems understand
! # e.g. LANG=C (notably SCO).
! if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
  if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
  
  # confdefs.h avoids OS command line length limits that DEFS can exceed.
  rm -rf conftest* confdefs.h
--- 435,448 ----
  done
  
  # NLS nuisances.
! # Only set these to C if already set.  These must not be set unconditionally
! # because not all systems understand e.g. LANG=C (notably SCO).
! # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
! # Non-C LC_CTYPE values break the ctype check.
  if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+ if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+ if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+ if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
  
  # confdefs.h avoids OS command line length limits that DEFS can exceed.
  rm -rf conftest* confdefs.h
***************
*** 497,504 ****
  # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
  ac_cpp='$CPP $CPPFLAGS'
  ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
! ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
  
  if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
    # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
    if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
--- 503,513 ----
  # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
  ac_cpp='$CPP $CPPFLAGS'
  ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
! ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
! cross_compiling=$ac_cv_prog_cc_cross
  
+ ac_exeext=
+ ac_objext=o
  if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
    # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
    if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
***************
*** 538,543 ****
--- 547,553 ----
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+ echo "configure:551: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_path_M4'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 545,553 ****
    /*)
    ac_cv_path_M4="$M4" # Let the user override the test with a path.
    ;;
    *)
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
!   for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_path_M4="$ac_dir/$ac_word"
--- 555,567 ----
    /*)
    ac_cv_path_M4="$M4" # Let the user override the test with a path.
    ;;
+   ?:/*)			 
+   ac_cv_path_M4="$M4" # Let the user override the test with a dos path.
+   ;;
    *)
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
!   ac_dummy="$PATH"
!   for ac_dir in $ac_dummy; do 
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_path_M4="$ac_dir/$ac_word"
***************
*** 574,587 ****
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
  if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    if test -n "$AWK"; then
    ac_cv_prog_AWK="$AWK" # Let the user override the test.
  else
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
!   for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_prog_AWK="$ac_prog"
--- 588,603 ----
  # Extract the first word of "$ac_prog", so it can be a program name with args.
  set dummy $ac_prog; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+ echo "configure:592: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
    if test -n "$AWK"; then
    ac_cv_prog_AWK="$AWK" # Let the user override the test.
  else
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
!   ac_dummy="$PATH"
!   for ac_dir in $ac_dummy; do
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_prog_AWK="$ac_prog"
***************
*** 605,610 ****
--- 621,627 ----
  # Extract the first word of "perl", so it can be a program name with args.
  set dummy perl; ac_word=$2
  echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+ echo "configure:625: checking for $ac_word" >&5
  if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
***************
*** 612,620 ****
    /*)
    ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
    ;;
    *)
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
!   for ac_dir in $PATH; do
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_path_PERL="$ac_dir/$ac_word"
--- 629,641 ----
    /*)
    ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
    ;;
+   ?:/*)			 
+   ac_cv_path_PERL="$PERL" # Let the user override the test with a dos path.
+   ;;
    *)
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
!   ac_dummy="$PATH"
!   for ac_dir in $ac_dummy; do 
      test -z "$ac_dir" && ac_dir=.
      if test -f $ac_dir/$ac_word; then
        ac_cv_path_PERL="$ac_dir/$ac_word"
***************
*** 665,691 ****
  # SunOS /usr/etc/install
  # IRIX /sbin/install
  # AIX /bin/install
  # AFS /usr/afsws/bin/install, which mishandles nonexistent args
  # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
  # ./install, which can be erroneously created by make from ./install.sh.
  echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
  if test -z "$INSTALL"; then
  if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
!     IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
    for ac_dir in $PATH; do
      # Account for people who put trailing slashes in PATH elements.
      case "$ac_dir/" in
      /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
      *)
        # OSF1 and SCO ODT 3.0 have their own names for install.
!       for ac_prog in ginstall installbsd scoinst install; do
          if test -f $ac_dir/$ac_prog; then
  	  if test $ac_prog = install &&
              grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
  	    # AIX install.  It has an incompatible calling convention.
- 	    # OSF/1 installbsd also uses dspmsg, but is usable.
  	    :
  	  else
  	    ac_cv_path_install="$ac_dir/$ac_prog -c"
--- 686,715 ----
  # SunOS /usr/etc/install
  # IRIX /sbin/install
  # AIX /bin/install
+ # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
  # AFS /usr/afsws/bin/install, which mishandles nonexistent args
  # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
  # ./install, which can be erroneously created by make from ./install.sh.
  echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+ echo "configure:695: checking for a BSD compatible install" >&5
  if test -z "$INSTALL"; then
  if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
    echo $ac_n "(cached) $ac_c" 1>&6
  else
!     IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
    for ac_dir in $PATH; do
      # Account for people who put trailing slashes in PATH elements.
      case "$ac_dir/" in
      /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
      *)
        # OSF1 and SCO ODT 3.0 have their own names for install.
!       # Don't use installbsd from OSF since it installs stuff as root
!       # by default.
!       for ac_prog in ginstall scoinst install; do
          if test -f $ac_dir/$ac_prog; then
  	  if test $ac_prog = install &&
              grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
  	    # AIX install.  It has an incompatible calling convention.
  	    :
  	  else
  	    ac_cv_path_install="$ac_dir/$ac_prog -c"
***************
*** 696,702 ****
        ;;
      esac
    done
!   IFS="$ac_save_ifs"
  
  fi
    if test "${ac_cv_path_install+set}" = set; then
--- 720,726 ----
        ;;
      esac
    done
!   IFS="$ac_save_IFS"
  
  fi
    if test "${ac_cv_path_install+set}" = set; then
***************
*** 715,720 ****
--- 739,746 ----
  # It thinks the first close brace ends the variable substitution.
  test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
  
+ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+ 
  test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
  
  
***************
*** 740,750 ****
  # --recheck option to rerun configure.
  #
  EOF
  # Ultrix sh set writes to stderr and can't be redirected directly,
  # and sets the high bit in the cache file unless we assign to the vars.
  (set) 2>&1 |
!   sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \
!   >> confcache
  if cmp -s $cache_file confcache; then
    :
  else
--- 766,790 ----
  # --recheck option to rerun configure.
  #
  EOF
+ # The following way of writing the cache mishandles newlines in values,
+ # but we know of no workaround that is simple, portable, and efficient.
+ # So, don't put newlines in cache variables' values.
  # Ultrix sh set writes to stderr and can't be redirected directly,
  # and sets the high bit in the cache file unless we assign to the vars.
  (set) 2>&1 |
!   case `(ac_space=' '; set | grep ac_space) 2>&1` in
!   *ac_space=\ *)
!     # `set' does not quote correctly, so add quotes (double-quote substitution
!     # turns \\\\ into \\, and sed turns \\ into \).
!     sed -n \
!       -e "s/'/'\\\\''/g" \
!       -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
!     ;;
!   *)
!     # `set' quotes correctly as required by POSIX, so do not add quotes.
!     sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
!     ;;
!   esac >> confcache
  if cmp -s $cache_file confcache; then
    :
  else
***************
*** 811,817 ****
      echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
      exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
    -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
!     echo "$CONFIG_STATUS generated by autoconf version 2.10"
      exit 0 ;;
    -help | --help | --hel | --he | --h)
      echo "\$ac_cs_usage"; exit 0 ;;
--- 851,857 ----
      echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
      exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
    -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
!     echo "$CONFIG_STATUS generated by autoconf version 2.13"
      exit 0 ;;
    -help | --help | --hel | --he | --h)
      echo "\$ac_cs_usage"; exit 0 ;;
***************
*** 831,839 ****
--- 871,881 ----
   s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
  $ac_vpsub
  $extrasub
+ s%@SHELL@%$SHELL%g
  s%@CFLAGS@%$CFLAGS%g
  s%@CPPFLAGS@%$CPPFLAGS%g
  s%@CXXFLAGS@%$CXXFLAGS%g
+ s%@FFLAGS@%$FFLAGS%g
  s%@DEFS@%$DEFS%g
  s%@LDFLAGS@%$LDFLAGS%g
  s%@LIBS@%$LIBS%g
***************
*** 857,882 ****
  s%@PERL@%$PERL%g
  s%@SCRIPTS@%$SCRIPTS%g
  s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
  s%@INSTALL_DATA@%$INSTALL_DATA%g
  s%@standards_info@%$standards_info%g
  s%@standards_dvi@%$standards_dvi%g
  
  CEOF
  EOF
  cat >> $CONFIG_STATUS <<EOF
  
  CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile"}
  EOF
  cat >> $CONFIG_STATUS <<\EOF
  for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
!   # Support "outfile[:infile]", defaulting infile="outfile.in".
    case "$ac_file" in
!   *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
         ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
    *) ac_file_in="${ac_file}.in" ;;
    esac
  
!   # Adjust relative srcdir, etc. for subdirectories.
  
    # Remove last slash and all that follows it.  Not all systems have dirname.
    ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
--- 899,961 ----
  s%@PERL@%$PERL%g
  s%@SCRIPTS@%$SCRIPTS%g
  s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+ s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
  s%@INSTALL_DATA@%$INSTALL_DATA%g
  s%@standards_info@%$standards_info%g
  s%@standards_dvi@%$standards_dvi%g
  
  CEOF
  EOF
+ 
+ cat >> $CONFIG_STATUS <<\EOF
+ 
+ # Split the substitutions into bite-sized pieces for seds with
+ # small command number limits, like on Digital OSF/1 and HP-UX.
+ ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ ac_file=1 # Number of current file.
+ ac_beg=1 # First line for current file.
+ ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ ac_more_lines=:
+ ac_sed_cmds=""
+ while $ac_more_lines; do
+   if test $ac_beg -gt 1; then
+     sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+   else
+     sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+   fi
+   if test ! -s conftest.s$ac_file; then
+     ac_more_lines=false
+     rm -f conftest.s$ac_file
+   else
+     if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f conftest.s$ac_file"
+     else
+       ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+     fi
+     ac_file=`expr $ac_file + 1`
+     ac_beg=$ac_end
+     ac_end=`expr $ac_end + $ac_max_sed_cmds`
+   fi
+ done
+ if test -z "$ac_sed_cmds"; then
+   ac_sed_cmds=cat
+ fi
+ EOF
+ 
  cat >> $CONFIG_STATUS <<EOF
  
  CONFIG_FILES=\${CONFIG_FILES-"Makefile testsuite/Makefile"}
  EOF
  cat >> $CONFIG_STATUS <<\EOF
  for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
!   # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
    case "$ac_file" in
!   *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
         ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
    *) ac_file_in="${ac_file}.in" ;;
    esac
  
!   # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
  
    # Remove last slash and all that follows it.  Not all systems have dirname.
    ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
***************
*** 904,939 ****
    [/$]*) INSTALL="$ac_given_INSTALL" ;;
    *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
    esac
    echo creating "$ac_file"
    rm -f "$ac_file"
!   # allow for outfile[:infile1[+infile2[+infile3...]]] syntax
!   IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}+"
!   ac_files_in=
!   for ac_file_name in $ac_file_in
!   do
!     ac_files_in="$ac_files_in $ac_given_srcdir/$ac_file_name"
!   done
!   IFS="$ac_save_ifs"
!   configure_input=`echo $ac_files_in | sed 's%/./%/%g
! s%  *./%%g
! s%  *%+%g
! s%^%Generated automatically from %
! s%$% by configure.%'`
    case "$ac_file" in
    *Makefile*) ac_comsub="1i\\
  # $configure_input" ;;
    *) ac_comsub= ;;
    esac
    sed -e "$ac_comsub
  s%@configure_input@%$configure_input%g
  s%@srcdir@%$srcdir%g
  s%@top_srcdir@%$top_srcdir%g
  s%@INSTALL@%$INSTALL%g
! " -f conftest.subs $ac_files_in > $ac_file
  fi; done
! rm -f conftest.subs
  
  
  
  exit 0
  EOF
--- 983,1013 ----
    [/$]*) INSTALL="$ac_given_INSTALL" ;;
    *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
    esac
+ 
    echo creating "$ac_file"
    rm -f "$ac_file"
!   configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
    case "$ac_file" in
    *Makefile*) ac_comsub="1i\\
  # $configure_input" ;;
    *) ac_comsub= ;;
    esac
+ 
+   ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
    sed -e "$ac_comsub
  s%@configure_input@%$configure_input%g
  s%@srcdir@%$srcdir%g
  s%@top_srcdir@%$top_srcdir%g
  s%@INSTALL@%$INSTALL%g
! " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
  fi; done
! rm -f conftest.s*
  
+ EOF
+ cat >> $CONFIG_STATUS <<EOF
  
+ EOF
+ cat >> $CONFIG_STATUS <<\EOF
  
  exit 0
  EOF
Index: krb5/util/autoconf/standards.info
diff -c krb5/util/autoconf/standards.info:1.1.1.2 krb5/util/autoconf/standards.info:removed
*** krb5/util/autoconf/standards.info:1.1.1.2	Fri Feb 22 16:38:48 2002
--- krb5/util/autoconf/standards.info	Sun Mar 16 20:22:41 2003
***************
*** 1,3837 ****
- This is Info file standards.info, produced by Makeinfo version 1.68
- from the input file ./standards.texi.
- 
- START-INFO-DIR-ENTRY
- * Standards: (standards).        GNU coding standards.
- END-INFO-DIR-ENTRY
- 
-    GNU Coding Standards Copyright (C) 1992, 1993, 1994, 1995, 1996,
- 1997, 1998 Free Software Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Free Software Foundation.
- 
- 
- File: standards.info,  Node: Top,  Next: Preface,  Prev: (dir),  Up: (dir)
- 
- Version
- *******
- 
-    Last updated August 26, 1998.
- 
- * Menu:
- 
- * Preface::                     About the GNU Coding Standards
- * Intellectual Property::       Keeping Free Software Free
- * Design Advice::               General Program Design
- * Program Behavior::            Program Behavior for All Programs
- * Writing C::                   Making The Best Use of C
- * Documentation::               Documenting Programs
- * Managing Releases::           The Release Process
- 
- 
- File: standards.info,  Node: Preface,  Next: Intellectual Property,  Prev: Top,  Up: Top
- 
- About the GNU Coding Standards
- ******************************
- 
-    The GNU Coding Standards were written by Richard Stallman and other
- GNU Project volunteers.  Their purpose is to make the GNU system clean,
- consistent, and easy to install.  This document can also be read as a
- guide to writing portable, robust and reliable programs.  It focuses on
- programs written in C, but many of the rules and principles are useful
- even if you write in another programming language.  The rules often
- state reasons for writing in a certain way.
- 
-    Corrections or suggestions for this document should be sent to
- <gnu@gnu.org>.  If you make a suggestion, please include a suggested
- new wording for it; our time is limited.  We prefer a context diff to
- the `standards.texi' or `make-stds.texi' files, but if you don't have
- those files, please mail your suggestion anyway.
- 
-    This release of the GNU Coding Standards was last updated August 26,
- 1998.
- 
- 
- File: standards.info,  Node: Intellectual Property,  Next: Design Advice,  Prev: Preface,  Up: Top
- 
- Keeping Free Software Free
- **************************
- 
-    This node discusses how you can make sure that GNU software remains
- unencumbered.
- 
- * Menu:
- 
- * Reading Non-Free Code::       Referring to Proprietary Programs
- * Contributions::               Accepting Contributions
- 
- 
- File: standards.info,  Node: Reading Non-Free Code,  Next: Contributions,  Up: Intellectual Property
- 
- Referring to Proprietary Programs
- =================================
- 
-    Don't in any circumstances refer to Unix source code for or during
- your work on GNU!  (Or to any other proprietary programs.)
- 
-    If you have a vague recollection of the internals of a Unix program,
- this does not absolutely mean you can't write an imitation of it, but
- do try to organize the imitation internally along different lines,
- because this is likely to make the details of the Unix version
- irrelevant and dissimilar to your results.
- 
-    For example, Unix utilities were generally optimized to minimize
- memory use; if you go for speed instead, your program will be very
- different.  You could keep the entire input file in core and scan it
- there instead of using stdio.  Use a smarter algorithm discovered more
- recently than the Unix program.  Eliminate use of temporary files.  Do
- it in one pass instead of two (we did this in the assembler).
- 
-    Or, on the contrary, emphasize simplicity instead of speed.  For some
- applications, the speed of today's computers makes simpler algorithms
- adequate.
- 
-    Or go for generality.  For example, Unix programs often have static
- tables or fixed-size strings, which make for arbitrary limits; use
- dynamic allocation instead.  Make sure your program handles NULs and
- other funny characters in the input files.  Add a programming language
- for extensibility and write part of the program in that language.
- 
-    Or turn some parts of the program into independently usable
- libraries.  Or use a simple garbage collector instead of tracking
- precisely when to free memory, or use a new GNU facility such as
- obstacks.
- 
- 
- File: standards.info,  Node: Contributions,  Prev: Reading Non-Free Code,  Up: Intellectual Property
- 
- Accepting Contributions
- =======================
- 
-    If someone else sends you a piece of code to add to the program you
- are working on, we need legal papers to use it--the same sort of legal
- papers we will need to get from you.  *Each* significant contributor to
- a program must sign some sort of legal papers in order for us to have
- clear title to the program.  The main author alone is not enough.
- 
-    So, before adding in any contributions from other people, please tell
- us, so we can arrange to get the papers.  Then wait until we tell you
- that we have received the signed papers, before you actually use the
- contribution.
- 
-    This applies both before you release the program and afterward.  If
- you receive diffs to fix a bug, and they make significant changes, we
- need legal papers for that change.
- 
-    This also applies to comments and documentation files.  For copyright
- law, comments and code are just text.  Copyright applies to all kinds of
- text, so we need legal papers for all kinds.
- 
-    You don't need papers for changes of a few lines here or there, since
- they are not significant for copyright purposes.  Also, you don't need
- papers if all you get from the suggestion is some ideas, not actual code
- which you use.  For example, if you write a different solution to the
- problem, you don't need to get papers.
- 
-    We know this is frustrating; it's frustrating for us as well.  But if
- you don't wait, you are going out on a limb--for example, what if the
- contributor's employer won't sign a disclaimer?  You might have to take
- that code out again!
- 
-    The very worst thing is if you forget to tell us about the other
- contributor.  We could be very embarrassed in court some day as a
- result.
- 
-    We have more detailed advice for maintainers of programs; if you have
- reached the stage of actually maintaining a program for GNU (whether
- released or not), please ask us for a copy.
- 
- 
- File: standards.info,  Node: Design Advice,  Next: Program Behavior,  Prev: Intellectual Property,  Up: Top
- 
- General Program Design
- **********************
- 
-    This node discusses some of the issues you should take into account
- when designing your program.
- 
- * Menu:
- 
- * Compatibility::               Compatibility with other implementations
- * Using Extensions::            Using non-standard features
- * ANSI C::                      Using ANSI C features
- * Source Language::             Using languages other than C
- 
- 
- File: standards.info,  Node: Compatibility,  Next: Using Extensions,  Up: Design Advice
- 
- Compatibility with Other Implementations
- ========================================
- 
-    With occasional exceptions, utility programs and libraries for GNU
- should be upward compatible with those in Berkeley Unix, and upward
- compatible with ANSI C if ANSI C specifies their behavior, and upward
- compatible with POSIX if POSIX specifies their behavior.
- 
-    When these standards conflict, it is useful to offer compatibility
- modes for each of them.
- 
-    ANSI C and POSIX prohibit many kinds of extensions.  Feel free to
- make the extensions anyway, and include a `--ansi', `--posix', or
- `--compatible' option to turn them off.  However, if the extension has
- a significant chance of breaking any real programs or scripts, then it
- is not really upward compatible.  Try to redesign its interface.
- 
-    Many GNU programs suppress extensions that conflict with POSIX if the
- environment variable `POSIXLY_CORRECT' is defined (even if it is
- defined with a null value).  Please make your program recognize this
- variable if appropriate.
- 
-    When a feature is used only by users (not by programs or command
- files), and it is done poorly in Unix, feel free to replace it
- completely with something totally different and better.  (For example,
- `vi' is replaced with Emacs.)  But it is nice to offer a compatible
- feature as well.  (There is a free `vi' clone, so we offer it.)
- 
-    Additional useful features not in Berkeley Unix are welcome.
- 
- 
- File: standards.info,  Node: Using Extensions,  Next: ANSI C,  Prev: Compatibility,  Up: Design Advice
- 
- Using Non-standard Features
- ===========================
- 
-    Many GNU facilities that already exist support a number of convenient
- extensions over the comparable Unix facilities.  Whether to use these
- extensions in implementing your program is a difficult question.
- 
-    On the one hand, using the extensions can make a cleaner program.
- On the other hand, people will not be able to build the program unless
- the other GNU tools are available.  This might cause the program to
- work on fewer kinds of machines.
- 
-    With some extensions, it might be easy to provide both alternatives.
- For example, you can define functions with a "keyword" `INLINE' and
- define that as a macro to expand into either `inline' or nothing,
- depending on the compiler.
- 
-    In general, perhaps it is best not to use the extensions if you can
- straightforwardly do without them, but to use the extensions if they
- are a big improvement.
- 
-    An exception to this rule are the large, established programs (such
- as Emacs) which run on a great variety of systems.  Such programs would
- be broken by use of GNU extensions.
- 
-    Another exception is for programs that are used as part of
- compilation: anything that must be compiled with other compilers in
- order to bootstrap the GNU compilation facilities.  If these require
- the GNU compiler, then no one can compile them without having them
- installed already.  That would be no good.
- 
- 
- File: standards.info,  Node: ANSI C,  Next: Source Language,  Prev: Using Extensions,  Up: Design Advice
- 
- ANSI C and pre-ANSI C
- =====================
- 
-    Do not ever use the "trigraph" feature of ANSI C.
- 
-    ANSI C is widespread enough now that it is ok to write new programs
- that use ANSI C features (and therefore will not work in non-ANSI
- compilers).  And if a program is already written in ANSI C, there's no
- need to convert it to support non-ANSI compilers.
- 
-    However, it is easy to support non-ANSI compilers in most programs,
- so you might still consider doing so when you write a program.  Instead
- of writing function definitions in ANSI prototype form,
- 
-      int
-      foo (int x, int y)
-      ...
- 
- write the definition in pre-ANSI style like this,
- 
-      int
-      foo (x, y)
-           int x, y;
-      ...
- 
- and use a separate declaration to specify the argument prototype:
- 
-      int foo (int, int);
- 
-    You need such a declaration anyway, in a header file, to get the
- benefit of ANSI C prototypes in all the files where the function is
- called.  And once you have it, you lose nothing by writing the function
- definition in the pre-ANSI style.
- 
-    If you don't know non-ANSI C, there's no need to learn it; just
- write in ANSI C.
- 
- 
- File: standards.info,  Node: Source Language,  Prev: ANSI C,  Up: Design Advice
- 
- Using Languages Other Than C
- ============================
- 
-    Using a language other than C is like using a non-standard feature:
- it will cause trouble for users.  Even if GCC supports the other
- language, users may find it inconvenient to have to install the
- compiler for that other language in order to build your program.  For
- example, if you write your program in C++, people will have to install
- the C++ compiler in order to compile your program.  Thus, it is better
- if you write in C.
- 
-    But there are three situations when there is no disadvantage in using
- some other language:
- 
-    * It is okay to use another language if your program contains an
-      interpreter for that language.
- 
-      For example, if your program links with GUILE, it is ok to write
-      part of the program in Scheme or another language supported by
-      GUILE.
- 
-    * It is okay to use another language in a tool specifically intended
-      for use with that language.
- 
-      This is okay because the only people who want to build the tool
-      will be those who have installed the other language anyway.
- 
-    * If an application is of interest to a narrow community, then
-      perhaps it's not important if the application is inconvenient to
-      install.
- 
-    C has one other advantage over C++ and other compiled languages: more
- people know C, so more people will find it easy to read and modify the
- program if it is written in C.
- 
- 
- File: standards.info,  Node: Program Behavior,  Next: Writing C,  Prev: Design Advice,  Up: Top
- 
- Program Behavior for All Programs
- *********************************
- 
-    This node describes how to write robust software. It also describes
- general standards for error messages, the command line interface, and
- how libraries should behave.
- 
- * Menu:
- 
- * Semantics::                   Writing robust programs
- * Libraries::                   Library behavior
- * Errors::                      Formatting error messages
- * User Interfaces::             Standards for command line interfaces
- * Option Table::                Table of long options.
- * Memory Usage::                When and how to care about memory needs
- 
- 
- File: standards.info,  Node: Semantics,  Next: Libraries,  Up: Program Behavior
- 
- Writing Robust Programs
- =======================
- 
-    Avoid arbitrary limits on the length or number of *any* data
- structure, including file names, lines, files, and symbols, by
- allocating all data structures dynamically.  In most Unix utilities,
- "long lines are silently truncated".  This is not acceptable in a GNU
- utility.
- 
-    Utilities reading files should not drop NUL characters, or any other
- nonprinting characters *including those with codes above 0177*.  The
- only sensible exceptions would be utilities specifically intended for
- interface to certain types of printers that can't handle those
- characters.
- 
-    Check every system call for an error return, unless you know you
- wish to ignore errors.  Include the system error text (from `perror' or
- equivalent) in *every* error message resulting from a failing system
- call, as well as the name of the file if any and the name of the
- utility.  Just "cannot open foo.c" or "stat failed" is not sufficient.
- 
-    Check every call to `malloc' or `realloc' to see if it returned
- zero.  Check `realloc' even if you are making the block smaller; in a
- system that rounds block sizes to a power of 2, `realloc' may get a
- different block if you ask for less space.
- 
-    In Unix, `realloc' can destroy the storage block if it returns zero.
- GNU `realloc' does not have this bug: if it fails, the original block
- is unchanged.  Feel free to assume the bug is fixed.  If you wish to
- run your program on Unix, and wish to avoid lossage in this case, you
- can use the GNU `malloc'.
- 
-    You must expect `free' to alter the contents of the block that was
- freed.  Anything you want to fetch from the block, you must fetch before
- calling `free'.
- 
-    If `malloc' fails in a noninteractive program, make that a fatal
- error.  In an interactive program (one that reads commands from the
- user), it is better to abort the command and return to the command
- reader loop.  This allows the user to kill other processes to free up
- virtual memory, and then try the command again.
- 
-    Use `getopt_long' to decode arguments, unless the argument syntax
- makes this unreasonable.
- 
-    When static storage is to be written in during program execution, use
- explicit C code to initialize it.  Reserve C initialized declarations
- for data that will not be changed.
- 
-    Try to avoid low-level interfaces to obscure Unix data structures
- (such as file directories, utmp, or the layout of kernel memory), since
- these are less likely to work compatibly.  If you need to find all the
- files in a directory, use `readdir' or some other high-level interface.
- These will be supported compatibly by GNU.
- 
-    The preferred signal handling facilities are the BSD variant of
- `signal', and the POSIX `sigaction' function; the alternative USG
- `signal' interface is an inferior design.
- 
-    Nowadays, using the POSIX signal functions may be the easiest way to
- make a program portable.  If you use `signal', then on GNU/Linux
- systems running GNU libc version 1, you should include `bsd/signal.h'
- instead of `signal.h', so as to get BSD behavior.  It is up to you
- whether to support systems where `signal' has only the USG behavior, or
- give up on them.
- 
-    In error checks that detect "impossible" conditions, just abort.
- There is usually no point in printing any message.  These checks
- indicate the existence of bugs.  Whoever wants to fix the bugs will have
- to read the source code and run a debugger.  So explain the problem with
- comments in the source.  The relevant data will be in variables, which
- are easy to examine with the debugger, so there is no point moving them
- elsewhere.
- 
-    Do not use a count of errors as the exit status for a program.
- *That does not work*, because exit status values are limited to 8 bits
- (0 through 255).  A single run of the program might have 256 errors; if
- you try to return 256 as the exit status, the parent process will see 0
- as the status, and it will appear that the program succeeded.
- 
-    If you make temporary files, check the `TMPDIR' environment
- variable; if that variable is defined, use the specified directory
- instead of `/tmp'.
- 
- 
- File: standards.info,  Node: Libraries,  Next: Errors,  Prev: Semantics,  Up: Program Behavior
- 
- Library Behavior
- ================
- 
-    Try to make library functions reentrant.  If they need to do dynamic
- storage allocation, at least try to avoid any nonreentrancy aside from
- that of `malloc' itself.
- 
-    Here are certain name conventions for libraries, to avoid name
- conflicts.
- 
-    Choose a name prefix for the library, more than two characters long.
- All external function and variable names should start with this prefix.
- In addition, there should only be one of these in any given library
- member.  This usually means putting each one in a separate source file.
- 
-    An exception can be made when two external symbols are always used
- together, so that no reasonable program could use one without the
- other; then they can both go in the same file.
- 
-    External symbols that are not documented entry points for the user
- should have names beginning with `_'.  They should also contain the
- chosen name prefix for the library, to prevent collisions with other
- libraries.  These can go in the same files with user entry points if
- you like.
- 
-    Static functions and variables can be used as you like and need not
- fit any naming convention.
- 
- 
- File: standards.info,  Node: Errors,  Next: User Interfaces,  Prev: Libraries,  Up: Program Behavior
- 
- Formatting Error Messages
- =========================
- 
-    Error messages from compilers should look like this:
- 
-      SOURCE-FILE-NAME:LINENO: MESSAGE
- 
-    Error messages from other noninteractive programs should look like
- this:
- 
-      PROGRAM:SOURCE-FILE-NAME:LINENO: MESSAGE
- 
- when there is an appropriate source file, or like this:
- 
-      PROGRAM: MESSAGE
- 
- when there is no relevant source file.
- 
-    In an interactive program (one that is reading commands from a
- terminal), it is better not to include the program name in an error
- message.  The place to indicate which program is running is in the
- prompt or with the screen layout.  (When the same program runs with
- input from a source other than a terminal, it is not interactive and
- would do best to print error messages using the noninteractive style.)
- 
-    The string MESSAGE should not begin with a capital letter when it
- follows a program name and/or file name.  Also, it should not end with
- a period.
- 
-    Error messages from interactive programs, and other messages such as
- usage messages, should start with a capital letter.  But they should not
- end with a period.
- 
- 
- File: standards.info,  Node: User Interfaces,  Next: Option Table,  Prev: Errors,  Up: Program Behavior
- 
- Standards for Command Line Interfaces
- =====================================
- 
-    Please don't make the behavior of a utility depend on the name used
- to invoke it.  It is useful sometimes to make a link to a utility with
- a different name, and that should not change what it does.
- 
-    Instead, use a run time option or a compilation switch or both to
- select among the alternate behaviors.
- 
-    Likewise, please don't make the behavior of the program depend on the
- type of output device it is used with.  Device independence is an
- important principle of the system's design; do not compromise it merely
- to save someone from typing an option now and then.  (Variation in error
- message syntax when using a terminal is ok, because that is a side issue
- that people do not depend on.)
- 
-    If you think one behavior is most useful when the output is to a
- terminal, and another is most useful when the output is a file or a
- pipe, then it is usually best to make the default behavior the one that
- is useful with output to a terminal, and have an option for the other
- behavior.
- 
-    Compatibility requires certain programs to depend on the type of
- output device.  It would be disastrous if `ls' or `sh' did not do so in
- the way all users expect.  In some of these cases, we supplement the
- program with a preferred alternate version that does not depend on the
- output device type.  For example, we provide a `dir' program much like
- `ls' except that its default output format is always multi-column
- format.
- 
-    It is a good idea to follow the POSIX guidelines for the
- command-line options of a program.  The easiest way to do this is to use
- `getopt' to parse them.  Note that the GNU version of `getopt' will
- normally permit options anywhere among the arguments unless the special
- argument `--' is used.  This is not what POSIX specifies; it is a GNU
- extension.
- 
-    Please define long-named options that are equivalent to the
- single-letter Unix-style options.  We hope to make GNU more user
- friendly this way.  This is easy to do with the GNU function
- `getopt_long'.
- 
-    One of the advantages of long-named options is that they can be
- consistent from program to program.  For example, users should be able
- to expect the "verbose" option of any GNU program which has one, to be
- spelled precisely `--verbose'.  To achieve this uniformity, look at the
- table of common long-option names when you choose the option names for
- your program (*note Option Table::.).
- 
-    It is usually a good idea for file names given as ordinary arguments
- to be input files only; any output files would be specified using
- options (preferably `-o' or `--output').  Even if you allow an output
- file name as an ordinary argument for compatibility, try to provide an
- option as another way to specify it.  This will lead to more consistency
- among GNU utilities, and fewer idiosyncracies for users to remember.
- 
-    All programs should support two standard options: `--version' and
- `--help'.
- 
- `--version'
-      This option should direct the program to information about its
-      name, version, origin and legal status, all on standard output,
-      and then exit successfully.  Other options and arguments should be
-      ignored once this is seen, and the program should not perform its
-      normal function.
- 
-      The first line is meant to be easy for a program to parse; the
-      version number proper starts after the last space.  In addition,
-      it contains the canonical name for this program, in this format:
- 
-           GNU Emacs 19.30
- 
-      The program's name should be a constant string; *don't* compute it
-      from `argv[0]'.  The idea is to state the standard or canonical
-      name for the program, not its file name.  There are other ways to
-      find out the precise file name where a command is found in `PATH'.
- 
-      If the program is a subsidiary part of a larger package, mention
-      the package name in parentheses, like this:
- 
-           emacsserver (GNU Emacs) 19.30
- 
-      If the package has a version number which is different from this
-      program's version number, you can mention the package version
-      number just before the close-parenthesis.
- 
-      If you *need* to mention the version numbers of libraries which
-      are distributed separately from the package which contains this
-      program, you can do so by printing an additional line of version
-      info for each library you want to mention.  Use the same format
-      for these lines as for the first line.
- 
-      Please do not mention all of the libraries that the program uses
-      "just for completeness"--that would produce a lot of unhelpful
-      clutter.  Please mention library version numbers only if you find
-      in practice that they are very important to you in debugging.
- 
-      The following line, after the version number line or lines, should
-      be a copyright notice.  If more than one copyright notice is
-      called for, put each on a separate line.
- 
-      Next should follow a brief statement that the program is free
-      software, and that users are free to copy and change it on certain
-      conditions.  If the program is covered by the GNU GPL, say so
-      here.  Also mention that there is no warranty, to the extent
-      permitted by law.
- 
-      It is ok to finish the output with a list of the major authors of
-      the program, as a way of giving credit.
- 
-      Here's an example of output that follows these rules:
- 
-           GNU Emacs 19.34.5
-           Copyright (C) 1996 Free Software Foundation, Inc.
-           GNU Emacs comes with NO WARRANTY,
-           to the extent permitted by law.
-           You may redistribute copies of GNU Emacs
-           under the terms of the GNU General Public License.
-           For more information about these matters,
-           see the files named COPYING.
- 
-      You should adapt this to your program, of course, filling in the
-      proper year, copyright holder, name of program, and the references
-      to distribution terms, and changing the rest of the wording as
-      necessary.
- 
-      This copyright notice only needs to mention the most recent year in
-      which changes were made--there's no need to list the years for
-      previous versions' changes.  You don't have to mention the name of
-      the program in these notices, if that is inconvenient, since it
-      appeared in the first line.
- 
- `--help'
-      This option should output brief documentation for how to invoke the
-      program, on standard output, then exit successfully.  Other
-      options and arguments should be ignored once this is seen, and the
-      program should not perform its normal function.
- 
-      Near the end of the `--help' option's output there should be a line
-      that says where to mail bug reports.  It should have this format:
- 
-           Report bugs to MAILING-ADDRESS.
- 
- 
- File: standards.info,  Node: Option Table,  Next: Memory Usage,  Prev: User Interfaces,  Up: Program Behavior
- 
- Table of Long Options
- =====================
- 
-    Here is a table of long options used by GNU programs.  It is surely
- incomplete, but we aim to list all the options that a new program might
- want to be compatible with.  If you use names not already in the table,
- please send <gnu@gnu.org> a list of them, with their meanings, so we
- can update the table.
- 
- `after-date'
-      `-N' in `tar'.
- 
- `all'
-      `-a' in `du', `ls', `nm', `stty', `uname', and `unexpand'.
- 
- `all-text'
-      `-a' in `diff'.
- 
- `almost-all'
-      `-A' in `ls'.
- 
- `append'
-      `-a' in `etags', `tee', `time'; `-r' in `tar'.
- 
- `archive'
-      `-a' in `cp'.
- 
- `archive-name'
-      `-n' in `shar'.
- 
- `arglength'
-      `-l' in `m4'.
- 
- `ascii'
-      `-a' in `diff'.
- 
- `assign'
-      `-v' in `gawk'.
- 
- `assume-new'
-      `-W' in Make.
- 
- `assume-old'
-      `-o' in Make.
- 
- `auto-check'
-      `-a' in `recode'.
- 
- `auto-pager'
-      `-a' in `wdiff'.
- 
- `auto-reference'
-      `-A' in `ptx'.
- 
- `avoid-wraps'
-      `-n' in `wdiff'.
- 
- `background'
-      For server programs, run in the background.
- 
- `backward-search'
-      `-B' in `ctags'.
- 
- `basename'
-      `-f' in `shar'.
- 
- `batch'
-      Used in GDB.
- 
- `baud'
-      Used in GDB.
- 
- `before'
-      `-b' in `tac'.
- 
- `binary'
-      `-b' in `cpio' and `diff'.
- 
- `bits-per-code'
-      `-b' in `shar'.
- 
- `block-size'
-      Used in `cpio' and `tar'.
- 
- `blocks'
-      `-b' in `head' and `tail'.
- 
- `break-file'
-      `-b' in `ptx'.
- 
- `brief'
-      Used in various programs to make output shorter.
- 
- `bytes'
-      `-c' in `head', `split', and `tail'.
- 
- `c++'
-      `-C' in `etags'.
- 
- `catenate'
-      `-A' in `tar'.
- 
- `cd'
-      Used in various programs to specify the directory to use.
- 
- `changes'
-      `-c' in `chgrp' and `chown'.
- 
- `classify'
-      `-F' in `ls'.
- 
- `colons'
-      `-c' in `recode'.
- 
- `command'
-      `-c' in `su'; `-x' in GDB.
- 
- `compare'
-      `-d' in `tar'.
- 
- `compat'
-      Used in `gawk'.
- 
- `compress'
-      `-Z' in `tar' and `shar'.
- 
- `concatenate'
-      `-A' in `tar'.
- 
- `confirmation'
-      `-w' in `tar'.
- 
- `context'
-      Used in `diff'.
- 
- `copyleft'
-      `-W copyleft' in `gawk'.
- 
- `copyright'
-      `-C' in `ptx', `recode', and `wdiff'; `-W copyright' in `gawk'.
- 
- `core'
-      Used in GDB.
- 
- `count'
-      `-q' in `who'.
- 
- `count-links'
-      `-l' in `du'.
- 
- `create'
-      Used in `tar' and `cpio'.
- 
- `cut-mark'
-      `-c' in `shar'.
- 
- `cxref'
-      `-x' in `ctags'.
- 
- `date'
-      `-d' in `touch'.
- 
- `debug'
-      `-d' in Make and `m4'; `-t' in Bison.
- 
- `define'
-      `-D' in `m4'.
- 
- `defines'
-      `-d' in Bison and `ctags'.
- 
- `delete'
-      `-D' in `tar'.
- 
- `dereference'
-      `-L' in `chgrp', `chown', `cpio', `du', `ls', and `tar'.
- 
- `dereference-args'
-      `-D' in `du'.
- 
- `diacritics'
-      `-d' in `recode'.
- 
- `dictionary-order'
-      `-d' in `look'.
- 
- `diff'
-      `-d' in `tar'.
- 
- `digits'
-      `-n' in `csplit'.
- 
- `directory'
-      Specify the directory to use, in various programs.  In `ls', it
-      means to show directories themselves rather than their contents.
-      In `rm' and `ln', it means to not treat links to directories
-      specially.
- 
- `discard-all'
-      `-x' in `strip'.
- 
- `discard-locals'
-      `-X' in `strip'.
- 
- `dry-run'
-      `-n' in Make.
- 
- `ed'
-      `-e' in `diff'.
- 
- `elide-empty-files'
-      `-z' in `csplit'.
- 
- `end-delete'
-      `-x' in `wdiff'.
- 
- `end-insert'
-      `-z' in `wdiff'.
- 
- `entire-new-file'
-      `-N' in `diff'.
- 
- `environment-overrides'
-      `-e' in Make.
- 
- `eof'
-      `-e' in `xargs'.
- 
- `epoch'
-      Used in GDB.
- 
- `error-limit'
-      Used in `makeinfo'.
- 
- `error-output'
-      `-o' in `m4'.
- 
- `escape'
-      `-b' in `ls'.
- 
- `exclude-from'
-      `-X' in `tar'.
- 
- `exec'
-      Used in GDB.
- 
- `exit'
-      `-x' in `xargs'.
- 
- `exit-0'
-      `-e' in `unshar'.
- 
- `expand-tabs'
-      `-t' in `diff'.
- 
- `expression'
-      `-e' in `sed'.
- 
- `extern-only'
-      `-g' in `nm'.
- 
- `extract'
-      `-i' in `cpio'; `-x' in `tar'.
- 
- `faces'
-      `-f' in `finger'.
- 
- `fast'
-      `-f' in `su'.
- 
- `fatal-warnings'
-      `-E' in `m4'.
- 
- `file'
-      `-f' in `info', `gawk', Make, `mt', and `tar'; `-n' in `sed'; `-r'
-      in `touch'.
- 
- `field-separator'
-      `-F' in `gawk'.
- 
- `file-prefix'
-      `-b' in Bison.
- 
- `file-type'
-      `-F' in `ls'.
- 
- `files-from'
-      `-T' in `tar'.
- 
- `fill-column'
-      Used in `makeinfo'.
- 
- `flag-truncation'
-      `-F' in `ptx'.
- 
- `fixed-output-files'
-      `-y' in Bison.
- 
- `follow'
-      `-f' in `tail'.
- 
- `footnote-style'
-      Used in `makeinfo'.
- 
- `force'
-      `-f' in `cp', `ln', `mv', and `rm'.
- 
- `force-prefix'
-      `-F' in `shar'.
- 
- `foreground'
-      For server programs, run in the foreground; in other words, don't
-      do anything special to run the server in the background.
- 
- `format'
-      Used in `ls', `time', and `ptx'.
- 
- `freeze-state'
-      `-F' in `m4'.
- 
- `fullname'
-      Used in GDB.
- 
- `gap-size'
-      `-g' in `ptx'.
- 
- `get'
-      `-x' in `tar'.
- 
- `graphic'
-      `-i' in `ul'.
- 
- `graphics'
-      `-g' in `recode'.
- 
- `group'
-      `-g' in `install'.
- 
- `gzip'
-      `-z' in `tar' and `shar'.
- 
- `hashsize'
-      `-H' in `m4'.
- 
- `header'
-      `-h' in `objdump' and `recode'
- 
- `heading'
-      `-H' in `who'.
- 
- `help'
-      Used to ask for brief usage information.
- 
- `here-delimiter'
-      `-d' in `shar'.
- 
- `hide-control-chars'
-      `-q' in `ls'.
- 
- `idle'
-      `-u' in `who'.
- 
- `ifdef'
-      `-D' in `diff'.
- 
- `ignore'
-      `-I' in `ls'; `-x' in `recode'.
- 
- `ignore-all-space'
-      `-w' in `diff'.
- 
- `ignore-backups'
-      `-B' in `ls'.
- 
- `ignore-blank-lines'
-      `-B' in `diff'.
- 
- `ignore-case'
-      `-f' in `look' and `ptx'; `-i' in `diff' and `wdiff'.
- 
- `ignore-errors'
-      `-i' in Make.
- 
- `ignore-file'
-      `-i' in `ptx'.
- 
- `ignore-indentation'
-      `-I' in `etags'.
- 
- `ignore-init-file'
-      `-f' in Oleo.
- 
- `ignore-interrupts'
-      `-i' in `tee'.
- 
- `ignore-matching-lines'
-      `-I' in `diff'.
- 
- `ignore-space-change'
-      `-b' in `diff'.
- 
- `ignore-zeros'
-      `-i' in `tar'.
- 
- `include'
-      `-i' in `etags'; `-I' in `m4'.
- 
- `include-dir'
-      `-I' in Make.
- 
- `incremental'
-      `-G' in `tar'.
- 
- `info'
-      `-i', `-l', and `-m' in Finger.
- 
- `initial'
-      `-i' in `expand'.
- 
- `initial-tab'
-      `-T' in `diff'.
- 
- `inode'
-      `-i' in `ls'.
- 
- `interactive'
-      `-i' in `cp', `ln', `mv', `rm'; `-e' in `m4'; `-p' in `xargs';
-      `-w' in `tar'.
- 
- `intermix-type'
-      `-p' in `shar'.
- 
- `jobs'
-      `-j' in Make.
- 
- `just-print'
-      `-n' in Make.
- 
- `keep-going'
-      `-k' in Make.
- 
- `keep-files'
-      `-k' in `csplit'.
- 
- `kilobytes'
-      `-k' in `du' and `ls'.
- 
- `language'
-      `-l' in `etags'.
- 
- `less-mode'
-      `-l' in `wdiff'.
- 
- `level-for-gzip'
-      `-g' in `shar'.
- 
- `line-bytes'
-      `-C' in `split'.
- 
- `lines'
-      Used in `split', `head', and `tail'.
- 
- `link'
-      `-l' in `cpio'.
- 
- `lint'
- `lint-old'
-      Used in `gawk'.
- 
- `list'
-      `-t' in `cpio'; `-l' in `recode'.
- 
- `list'
-      `-t' in `tar'.
- 
- `literal'
-      `-N' in `ls'.
- 
- `load-average'
-      `-l' in Make.
- 
- `login'
-      Used in `su'.
- 
- `machine'
-      No listing of which programs already use this; someone should
-      check to see if any actually do, and tell <gnu@gnu.org>.
- 
- `macro-name'
-      `-M' in `ptx'.
- 
- `mail'
-      `-m' in `hello' and `uname'.
- 
- `make-directories'
-      `-d' in `cpio'.
- 
- `makefile'
-      `-f' in Make.
- 
- `mapped'
-      Used in GDB.
- 
- `max-args'
-      `-n' in `xargs'.
- 
- `max-chars'
-      `-n' in `xargs'.
- 
- `max-lines'
-      `-l' in `xargs'.
- 
- `max-load'
-      `-l' in Make.
- 
- `max-procs'
-      `-P' in `xargs'.
- 
- `mesg'
-      `-T' in `who'.
- 
- `message'
-      `-T' in `who'.
- 
- `minimal'
-      `-d' in `diff'.
- 
- `mixed-uuencode'
-      `-M' in `shar'.
- 
- `mode'
-      `-m' in `install', `mkdir', and `mkfifo'.
- 
- `modification-time'
-      `-m' in `tar'.
- 
- `multi-volume'
-      `-M' in `tar'.
- 
- `name-prefix'
-      `-a' in Bison.
- 
- `nesting-limit'
-      `-L' in `m4'.
- 
- `net-headers'
-      `-a' in `shar'.
- 
- `new-file'
-      `-W' in Make.
- 
- `no-builtin-rules'
-      `-r' in Make.
- 
- `no-character-count'
-      `-w' in `shar'.
- 
- `no-check-existing'
-      `-x' in `shar'.
- 
- `no-common'
-      `-3' in `wdiff'.
- 
- `no-create'
-      `-c' in `touch'.
- 
- `no-defines'
-      `-D' in `etags'.
- 
- `no-deleted'
-      `-1' in `wdiff'.
- 
- `no-dereference'
-      `-d' in `cp'.
- 
- `no-inserted'
-      `-2' in `wdiff'.
- 
- `no-keep-going'
-      `-S' in Make.
- 
- `no-lines'
-      `-l' in Bison.
- 
- `no-piping'
-      `-P' in `shar'.
- 
- `no-prof'
-      `-e' in `gprof'.
- 
- `no-regex'
-      `-R' in `etags'.
- 
- `no-sort'
-      `-p' in `nm'.
- 
- `no-split'
-      Used in `makeinfo'.
- 
- `no-static'
-      `-a' in `gprof'.
- 
- `no-time'
-      `-E' in `gprof'.
- 
- `no-timestamp'
-      `-m' in `shar'.
- 
- `no-validate'
-      Used in `makeinfo'.
- 
- `no-wait'
-      Used in `emacsclient'.
- 
- `no-warn'
-      Used in various programs to inhibit warnings.
- 
- `node'
-      `-n' in `info'.
- 
- `nodename'
-      `-n' in `uname'.
- 
- `nonmatching'
-      `-f' in `cpio'.
- 
- `nstuff'
-      `-n' in `objdump'.
- 
- `null'
-      `-0' in `xargs'.
- 
- `number'
-      `-n' in `cat'.
- 
- `number-nonblank'
-      `-b' in `cat'.
- 
- `numeric-sort'
-      `-n' in `nm'.
- 
- `numeric-uid-gid'
-      `-n' in `cpio' and `ls'.
- 
- `nx'
-      Used in GDB.
- 
- `old-archive'
-      `-o' in `tar'.
- 
- `old-file'
-      `-o' in Make.
- 
- `one-file-system'
-      `-l' in `tar', `cp', and `du'.
- 
- `only-file'
-      `-o' in `ptx'.
- 
- `only-prof'
-      `-f' in `gprof'.
- 
- `only-time'
-      `-F' in `gprof'.
- 
- `output'
-      In various programs, specify the output file name.
- 
- `output-prefix'
-      `-o' in `shar'.
- 
- `override'
-      `-o' in `rm'.
- 
- `overwrite'
-      `-c' in `unshar'.
- 
- `owner'
-      `-o' in `install'.
- 
- `paginate'
-      `-l' in `diff'.
- 
- `paragraph-indent'
-      Used in `makeinfo'.
- 
- `parents'
-      `-p' in `mkdir' and `rmdir'.
- 
- `pass-all'
-      `-p' in `ul'.
- 
- `pass-through'
-      `-p' in `cpio'.
- 
- `port'
-      `-P' in `finger'.
- 
- `portability'
-      `-c' in `cpio' and `tar'.
- 
- `posix'
-      Used in `gawk'.
- 
- `prefix-builtins'
-      `-P' in `m4'.
- 
- `prefix'
-      `-f' in `csplit'.
- 
- `preserve'
-      Used in `tar' and `cp'.
- 
- `preserve-environment'
-      `-p' in `su'.
- 
- `preserve-modification-time'
-      `-m' in `cpio'.
- 
- `preserve-order'
-      `-s' in `tar'.
- 
- `preserve-permissions'
-      `-p' in `tar'.
- 
- `print'
-      `-l' in `diff'.
- 
- `print-chars'
-      `-L' in `cmp'.
- 
- `print-data-base'
-      `-p' in Make.
- 
- `print-directory'
-      `-w' in Make.
- 
- `print-file-name'
-      `-o' in `nm'.
- 
- `print-symdefs'
-      `-s' in `nm'.
- 
- `printer'
-      `-p' in `wdiff'.
- 
- `prompt'
-      `-p' in `ed'.
- 
- `query-user'
-      `-X' in `shar'.
- 
- `question'
-      `-q' in Make.
- 
- `quiet'
-      Used in many programs to inhibit the usual output.  *Note:* every
-      program accepting `--quiet' should accept `--silent' as a synonym.
- 
- `quiet-unshar'
-      `-Q' in `shar'
- 
- `quote-name'
-      `-Q' in `ls'.
- 
- `rcs'
-      `-n' in `diff'.
- 
- `re-interval'
-      Used in `gawk'.
- 
- `read-full-blocks'
-      `-B' in `tar'.
- 
- `readnow'
-      Used in GDB.
- 
- `recon'
-      `-n' in Make.
- 
- `record-number'
-      `-R' in `tar'.
- 
- `recursive'
-      Used in `chgrp', `chown', `cp', `ls', `diff', and `rm'.
- 
- `reference-limit'
-      Used in `makeinfo'.
- 
- `references'
-      `-r' in `ptx'.
- 
- `regex'
-      `-r' in `tac' and `etags'.
- 
- `release'
-      `-r' in `uname'.
- 
- `reload-state'
-      `-R' in `m4'.
- 
- `relocation'
-      `-r' in `objdump'.
- 
- `rename'
-      `-r' in `cpio'.
- 
- `replace'
-      `-i' in `xargs'.
- 
- `report-identical-files'
-      `-s' in `diff'.
- 
- `reset-access-time'
-      `-a' in `cpio'.
- 
- `reverse'
-      `-r' in `ls' and `nm'.
- 
- `reversed-ed'
-      `-f' in `diff'.
- 
- `right-side-defs'
-      `-R' in `ptx'.
- 
- `same-order'
-      `-s' in `tar'.
- 
- `same-permissions'
-      `-p' in `tar'.
- 
- `save'
-      `-g' in `stty'.
- 
- `se'
-      Used in GDB.
- 
- `sentence-regexp'
-      `-S' in `ptx'.
- 
- `separate-dirs'
-      `-S' in `du'.
- 
- `separator'
-      `-s' in `tac'.
- 
- `sequence'
-      Used by `recode' to chose files or pipes for sequencing passes.
- 
- `shell'
-      `-s' in `su'.
- 
- `show-all'
-      `-A' in `cat'.
- 
- `show-c-function'
-      `-p' in `diff'.
- 
- `show-ends'
-      `-E' in `cat'.
- 
- `show-function-line'
-      `-F' in `diff'.
- 
- `show-tabs'
-      `-T' in `cat'.
- 
- `silent'
-      Used in many programs to inhibit the usual output.  *Note:* every
-      program accepting `--silent' should accept `--quiet' as a synonym.
- 
- `size'
-      `-s' in `ls'.
- 
- `socket'
-      Specify a file descriptor for a network server to use for its
-      socket, instead of opening and binding a new socket.  This
-      provides a way to run, in a nonpriveledged process, a server that
-      normally needs a reserved port number.
- 
- `sort'
-      Used in `ls'.
- 
- `source'
-      `-W source' in `gawk'.
- 
- `sparse'
-      `-S' in `tar'.
- 
- `speed-large-files'
-      `-H' in `diff'.
- 
- `split-at'
-      `-E' in `unshar'.
- 
- `split-size-limit'
-      `-L' in `shar'.
- 
- `squeeze-blank'
-      `-s' in `cat'.
- 
- `start-delete'
-      `-w' in `wdiff'.
- 
- `start-insert'
-      `-y' in `wdiff'.
- 
- `starting-file'
-      Used in `tar' and `diff' to specify which file within a directory
-      to start processing with.
- 
- `statistics'
-      `-s' in `wdiff'.
- 
- `stdin-file-list'
-      `-S' in `shar'.
- 
- `stop'
-      `-S' in Make.
- 
- `strict'
-      `-s' in `recode'.
- 
- `strip'
-      `-s' in `install'.
- 
- `strip-all'
-      `-s' in `strip'.
- 
- `strip-debug'
-      `-S' in `strip'.
- 
- `submitter'
-      `-s' in `shar'.
- 
- `suffix'
-      `-S' in `cp', `ln', `mv'.
- 
- `suffix-format'
-      `-b' in `csplit'.
- 
- `sum'
-      `-s' in `gprof'.
- 
- `summarize'
-      `-s' in `du'.
- 
- `symbolic'
-      `-s' in `ln'.
- 
- `symbols'
-      Used in GDB and `objdump'.
- 
- `synclines'
-      `-s' in `m4'.
- 
- `sysname'
-      `-s' in `uname'.
- 
- `tabs'
-      `-t' in `expand' and `unexpand'.
- 
- `tabsize'
-      `-T' in `ls'.
- 
- `terminal'
-      `-T' in `tput' and `ul'.  `-t' in `wdiff'.
- 
- `text'
-      `-a' in `diff'.
- 
- `text-files'
-      `-T' in `shar'.
- 
- `time'
-      Used in `ls' and `touch'.
- 
- `to-stdout'
-      `-O' in `tar'.
- 
- `total'
-      `-c' in `du'.
- 
- `touch'
-      `-t' in Make, `ranlib', and `recode'.
- 
- `trace'
-      `-t' in `m4'.
- 
- `traditional'
-      `-t' in `hello'; `-W traditional' in `gawk'; `-G' in `ed', `m4',
-      and `ptx'.
- 
- `tty'
-      Used in GDB.
- 
- `typedefs'
-      `-t' in `ctags'.
- 
- `typedefs-and-c++'
-      `-T' in `ctags'.
- 
- `typeset-mode'
-      `-t' in `ptx'.
- 
- `uncompress'
-      `-z' in `tar'.
- 
- `unconditional'
-      `-u' in `cpio'.
- 
- `undefine'
-      `-U' in `m4'.
- 
- `undefined-only'
-      `-u' in `nm'.
- 
- `update'
-      `-u' in `cp', `ctags', `mv', `tar'.
- 
- `usage'
-      Used in `gawk'; same as `--help'.
- 
- `uuencode'
-      `-B' in `shar'.
- 
- `vanilla-operation'
-      `-V' in `shar'.
- 
- `verbose'
-      Print more information about progress.  Many programs support this.
- 
- `verify'
-      `-W' in `tar'.
- 
- `version'
-      Print the version number.
- 
- `version-control'
-      `-V' in `cp', `ln', `mv'.
- 
- `vgrind'
-      `-v' in `ctags'.
- 
- `volume'
-      `-V' in `tar'.
- 
- `what-if'
-      `-W' in Make.
- 
- `whole-size-limit'
-      `-l' in `shar'.
- 
- `width'
-      `-w' in `ls' and `ptx'.
- 
- `word-regexp'
-      `-W' in `ptx'.
- 
- `writable'
-      `-T' in `who'.
- 
- `zeros'
-      `-z' in `gprof'.
- 
- 
- File: standards.info,  Node: Memory Usage,  Prev: Option Table,  Up: Program Behavior
- 
- Memory Usage
- ============
- 
-    If it typically uses just a few meg of memory, don't bother making
- any effort to reduce memory usage.  For example, if it is impractical
- for other reasons to operate on files more than a few meg long, it is
- reasonable to read entire input files into core to operate on them.
- 
-    However, for programs such as `cat' or `tail', that can usefully
- operate on very large files, it is important to avoid using a technique
- that would artificially limit the size of files it can handle.  If a
- program works by lines and could be applied to arbitrary user-supplied
- input files, it should keep only a line in memory, because this is not
- very hard and users will want to be able to operate on input files that
- are bigger than will fit in core all at once.
- 
-    If your program creates complicated data structures, just make them
- in core and give a fatal error if `malloc' returns zero.
- 
- 
- File: standards.info,  Node: Writing C,  Next: Documentation,  Prev: Program Behavior,  Up: Top
- 
- Making The Best Use of C
- ************************
- 
-    This node provides advice on how best to use the C language when
- writing GNU software.
- 
- * Menu:
- 
- * Formatting::                  Formatting Your Source Code
- * Comments::                    Commenting Your Work
- * Syntactic Conventions::       Clean Use of C Constructs
- * Names::                       Naming Variables and Functions
- * System Portability::          Portability between different operating systems
- * CPU Portability::             Supporting the range of CPU types
- * System Functions::            Portability and "standard" library functions
- * Internationalization::        Techniques for internationalization
- * Mmap::                        How you can safely use `mmap'.
- 
- 
- File: standards.info,  Node: Formatting,  Next: Comments,  Up: Writing C
- 
- Formatting Your Source Code
- ===========================
- 
-    It is important to put the open-brace that starts the body of a C
- function in column zero, and avoid putting any other open-brace or
- open-parenthesis or open-bracket in column zero.  Several tools look
- for open-braces in column zero to find the beginnings of C functions.
- These tools will not work on code not formatted that way.
- 
-    It is also important for function definitions to start the name of
- the function in column zero.  This helps people to search for function
- definitions, and may also help certain tools recognize them.  Thus, the
- proper format is this:
- 
-      static char *
-      concat (s1, s2)        /* Name starts in column zero here */
-           char *s1, *s2;
-      {                     /* Open brace in column zero here */
-        ...
-      }
- 
- or, if you want to use ANSI C, format the definition like this:
- 
-      static char *
-      concat (char *s1, char *s2)
-      {
-        ...
-      }
- 
-    In ANSI C, if the arguments don't fit nicely on one line, split it
- like this:
- 
-      int
-      lots_of_args (int an_integer, long a_long, short a_short,
-                    double a_double, float a_float)
-      ...
- 
-    For the body of the function, we prefer code formatted like this:
- 
-      if (x < foo (y, z))
-        haha = bar[4] + 5;
-      else
-        {
-          while (z)
-            {
-              haha += foo (z, z);
-              z--;
-            }
-          return ++x + bar ();
-        }
- 
-    We find it easier to read a program when it has spaces before the
- open-parentheses and after the commas.  Especially after the commas.
- 
-    When you split an expression into multiple lines, split it before an
- operator, not after one.  Here is the right way:
- 
-      if (foo_this_is_long && bar > win (x, y, z)
-          && remaining_condition)
- 
-    Try to avoid having two operators of different precedence at the same
- level of indentation.  For example, don't write this:
- 
-      mode = (inmode[j] == VOIDmode
-              || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])
-              ? outmode[j] : inmode[j]);
- 
-    Instead, use extra parentheses so that the indentation shows the
- nesting:
- 
-      mode = ((inmode[j] == VOIDmode
-               || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])))
-              ? outmode[j] : inmode[j]);
- 
-    Insert extra parentheses so that Emacs will indent the code properly.
- For example, the following indentation looks nice if you do it by hand,
- but Emacs would mess it up:
- 
-      v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
-          + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000;
- 
-    But adding a set of parentheses solves the problem:
- 
-      v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
-           + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);
- 
-    Format do-while statements like this:
- 
-      do
-        {
-          a = foo (a);
-        }
-      while (a > 0);
- 
-    Please use formfeed characters (control-L) to divide the program into
- pages at logical places (but not within a function).  It does not matter
- just how long the pages are, since they do not have to fit on a printed
- page.  The formfeeds should appear alone on lines by themselves.
- 
- 
- File: standards.info,  Node: Comments,  Next: Syntactic Conventions,  Prev: Formatting,  Up: Writing C
- 
- Commenting Your Work
- ====================
- 
-    Every program should start with a comment saying briefly what it is
- for.  Example: `fmt - filter for simple filling of text'.
- 
-    Please write the comments in a GNU program in English, because
- English is the one language that nearly all programmers in all
- countries can read.  If you do not write English well, please write
- comments in English as well as you can, then ask other people to help
- rewrite them.  If you can't write comments in English, please find
- someone to work with you and translate your comments into English.
- 
-    Please put a comment on each function saying what the function does,
- what sorts of arguments it gets, and what the possible values of
- arguments mean and are used for.  It is not necessary to duplicate in
- words the meaning of the C argument declarations, if a C type is being
- used in its customary fashion.  If there is anything nonstandard about
- its use (such as an argument of type `char *' which is really the
- address of the second character of a string, not the first), or any
- possible values that would not work the way one would expect (such as,
- that strings containing newlines are not guaranteed to work), be sure
- to say so.
- 
-    Also explain the significance of the return value, if there is one.
- 
-    Please put two spaces after the end of a sentence in your comments,
- so that the Emacs sentence commands will work.  Also, please write
- complete sentences and capitalize the first word.  If a lower-case
- identifier comes at the beginning of a sentence, don't capitalize it!
- Changing the spelling makes it a different identifier.  If you don't
- like starting a sentence with a lower case letter, write the sentence
- differently (e.g., "The identifier lower-case is ...").
- 
-    The comment on a function is much clearer if you use the argument
- names to speak about the argument values.  The variable name itself
- should be lower case, but write it in upper case when you are speaking
- about the value rather than the variable itself.  Thus, "the inode
- number NODE_NUM" rather than "an inode".
- 
-    There is usually no purpose in restating the name of the function in
- the comment before it, because the reader can see that for himself.
- There might be an exception when the comment is so long that the
- function itself would be off the bottom of the screen.
- 
-    There should be a comment on each static variable as well, like this:
- 
-      /* Nonzero means truncate lines in the display;
-         zero means continue them.  */
-      int truncate_lines;
- 
-    Every `#endif' should have a comment, except in the case of short
- conditionals (just a few lines) that are not nested.  The comment should
- state the condition of the conditional that is ending, *including its
- sense*.  `#else' should have a comment describing the condition *and
- sense* of the code that follows.  For example:
- 
-      #ifdef foo
-        ...
-      #else /* not foo */
-        ...
-      #endif /* not foo */
-      #ifdef foo
-        ...
-      #endif /* foo */
- 
- but, by contrast, write the comments this way for a `#ifndef':
- 
-      #ifndef foo
-        ...
-      #else /* foo */
-        ...
-      #endif /* foo */
-      #ifndef foo
-        ...
-      #endif /* not foo */
- 
- 
- File: standards.info,  Node: Syntactic Conventions,  Next: Names,  Prev: Comments,  Up: Writing C
- 
- Clean Use of C Constructs
- =========================
- 
-    Please explicitly declare all arguments to functions.  Don't omit
- them just because they are `int's.
- 
-    Declarations of external functions and functions to appear later in
- the source file should all go in one place near the beginning of the
- file (somewhere before the first function definition in the file), or
- else should go in a header file.  Don't put `extern' declarations inside
- functions.
- 
-    It used to be common practice to use the same local variables (with
- names like `tem') over and over for different values within one
- function.  Instead of doing this, it is better declare a separate local
- variable for each distinct purpose, and give it a name which is
- meaningful.  This not only makes programs easier to understand, it also
- facilitates optimization by good compilers.  You can also move the
- declaration of each local variable into the smallest scope that includes
- all its uses.  This makes the program even cleaner.
- 
-    Don't use local variables or parameters that shadow global
- identifiers.
- 
-    Don't declare multiple variables in one declaration that spans lines.
- Start a new declaration on each line, instead.  For example, instead of
- this:
- 
-      int    foo,
-             bar;
- 
- write either this:
- 
-      int foo, bar;
- 
- or this:
- 
-      int foo;
-      int bar;
- 
- (If they are global variables, each should have a comment preceding it
- anyway.)
- 
-    When you have an `if'-`else' statement nested in another `if'
- statement, always put braces around the `if'-`else'.  Thus, never write
- like this:
- 
-      if (foo)
-        if (bar)
-          win ();
-        else
-          lose ();
- 
- always like this:
- 
-      if (foo)
-        {
-          if (bar)
-            win ();
-          else
-            lose ();
-        }
- 
-    If you have an `if' statement nested inside of an `else' statement,
- either write `else if' on one line, like this,
- 
-      if (foo)
-        ...
-      else if (bar)
-        ...
- 
- with its `then'-part indented like the preceding `then'-part, or write
- the nested `if' within braces like this:
- 
-      if (foo)
-        ...
-      else
-        {
-          if (bar)
-            ...
-        }
- 
-    Don't declare both a structure tag and variables or typedefs in the
- same declaration.  Instead, declare the structure tag separately and
- then use it to declare the variables or typedefs.
- 
-    Try to avoid assignments inside `if'-conditions.  For example, don't
- write this:
- 
-      if ((foo = (char *) malloc (sizeof *foo)) == 0)
-        fatal ("virtual memory exhausted");
- 
- instead, write this:
- 
-      foo = (char *) malloc (sizeof *foo);
-      if (foo == 0)
-        fatal ("virtual memory exhausted");
- 
-    Don't make the program ugly to placate `lint'.  Please don't insert
- any casts to `void'.  Zero without a cast is perfectly fine as a null
- pointer constant, except when calling a varargs function.
- 
- 
- File: standards.info,  Node: Names,  Next: System Portability,  Prev: Syntactic Conventions,  Up: Writing C
- 
- Naming Variables and Functions
- ==============================
- 
-    The names of global variables and functions in a program serve as
- comments of a sort.  So don't choose terse names--instead, look for
- names that give useful information about the meaning of the variable or
- function.  In a GNU program, names should be English, like other
- comments.
- 
-    Local variable names can be shorter, because they are used only
- within one context, where (presumably) comments explain their purpose.
- 
-    Please use underscores to separate words in a name, so that the Emacs
- word commands can be useful within them.  Stick to lower case; reserve
- upper case for macros and `enum' constants, and for name-prefixes that
- follow a uniform convention.
- 
-    For example, you should use names like `ignore_space_change_flag';
- don't use names like `iCantReadThis'.
- 
-    Variables that indicate whether command-line options have been
- specified should be named after the meaning of the option, not after
- the option-letter.  A comment should state both the exact meaning of
- the option and its letter.  For example,
- 
-      /* Ignore changes in horizontal whitespace (-b).  */
-      int ignore_space_change_flag;
- 
-    When you want to define names with constant integer values, use
- `enum' rather than `#define'.  GDB knows about enumeration constants.
- 
-    Use file names of 14 characters or less, to avoid creating gratuitous
- problems on older System V systems.  You can use the program `doschk'
- to test for this.  `doschk' also tests for potential name conflicts if
- the files were loaded onto an MS-DOS file system--something you may or
- may not care about.
- 
- 
- File: standards.info,  Node: System Portability,  Next: CPU Portability,  Prev: Names,  Up: Writing C
- 
- Portability between System Types
- ================================
- 
-    In the Unix world, "portability" refers to porting to different Unix
- versions.  For a GNU program, this kind of portability is desirable, but
- not paramount.
- 
-    The primary purpose of GNU software is to run on top of the GNU
- kernel, compiled with the GNU C compiler, on various types of CPU.  The
- amount and kinds of variation among GNU systems on different CPUs will
- be comparable to the variation among Linux-based GNU systems or among
- BSD systems today.  So the kinds of portability that are absolutely
- necessary are quite limited.
- 
-    But many users do run GNU software on non-GNU Unix or Unix-like
- systems.  So supporting a variety of Unix-like systems is desirable,
- although not paramount.
- 
-    The easiest way to achieve portability to most Unix-like systems is
- to use Autoconf.  It's unlikely that your program needs to know more
- information about the host platform than Autoconf can provide, simply
- because most of the programs that need such knowledge have already been
- written.
- 
-    Avoid using the format of semi-internal data bases (e.g.,
- directories) when there is a higher-level alternative (`readdir').
- 
-    As for systems that are not like Unix, such as MSDOS, Windows, the
- Macintosh, VMS, and MVS, supporting them is usually so much work that it
- is better if you don't.
- 
-    The planned GNU kernel is not finished yet, but you can tell which
- facilities it will provide by looking at the GNU C Library Manual.  The
- GNU kernel is based on Mach, so the features of Mach will also be
- available.  However, if you use Mach features, you'll probably have
- trouble debugging your program today.
- 
- 
- File: standards.info,  Node: CPU Portability,  Next: System Functions,  Prev: System Portability,  Up: Writing C
- 
- Portability between CPUs
- ========================
- 
-    Even GNU systems will differ because of differences among CPU
- types--for example, difference in byte ordering and alignment
- requirements.  It is absolutely essential to handle these differences.
- However, don't make any effort to cater to the possibility that an
- `int' will be less than 32 bits.  We don't support 16-bit machines in
- GNU.
- 
-    Don't assume that the address of an `int' object is also the address
- of its least-significant byte.  This is false on big-endian machines.
- Thus, don't make the following mistake:
- 
-      int c;
-      ...
-      while ((c = getchar()) != EOF)
-        write(file_descriptor, &c, 1);
- 
-    When calling functions, you need not worry about the difference
- between pointers of various types, or between pointers and integers.
- On most machines, there's no difference anyway.  As for the few
- machines where there is a difference, all of them support ANSI C, so
- you can use prototypes (conditionalized to be active only in ANSI C) to
- make the code work on those systems.
- 
-    In certain cases, it is ok to pass integer and pointer arguments
- indiscriminately to the same function, and use no prototype on any
- system.  For example, many GNU programs have error-reporting functions
- that pass their arguments along to `printf' and friends:
- 
-      error (s, a1, a2, a3)
-           char *s;
-           int a1, a2, a3;
-      {
-        fprintf (stderr, "error: ");
-        fprintf (stderr, s, a1, a2, a3);
-      }
- 
- In practice, this works on all machines, and it is much simpler than any
- "correct" alternative.  Be sure *not* to use a prototype for such
- functions.
- 
-    However, avoid casting pointers to integers unless you really need
- to.  These assumptions really reduce portability, and in most programs
- they are easy to avoid.  In the cases where casting pointers to
- integers is essential--such as, a Lisp interpreter which stores type
- information as well as an address in one word--it is ok to do so, but
- you'll have to make explicit provisions to handle different word sizes.
- 
- 
- File: standards.info,  Node: System Functions,  Next: Internationalization,  Prev: CPU Portability,  Up: Writing C
- 
- Calling System Functions
- ========================
- 
-    C implementations differ substantially.  ANSI C reduces but does not
- eliminate the incompatibilities; meanwhile, many users wish to compile
- GNU software with pre-ANSI compilers.  This chapter gives
- recommendations for how to use the more or less standard C library
- functions to avoid unnecessary loss of portability.
- 
-    * Don't use the value of `sprintf'.  It returns the number of
-      characters written on some systems, but not on all systems.
- 
-    * `main' should be declared to return type `int'.  It should
-      terminate either by calling `exit' or by returning the integer
-      status code; make sure it cannot ever return an undefined value.
- 
-    * Don't declare system functions explicitly.
- 
-      Almost any declaration for a system function is wrong on some
-      system.  To minimize conflicts, leave it to the system header
-      files to declare system functions.  If the headers don't declare a
-      function, let it remain undeclared.
- 
-      While it may seem unclean to use a function without declaring it,
-      in practice this works fine for most system library functions on
-      the systems where this really happens; thus, the disadvantage is
-      only theoretical.  By contrast, actual declarations have
-      frequently caused actual conflicts.
- 
-    * If you must declare a system function, don't specify the argument
-      types.  Use an old-style declaration, not an ANSI prototype.  The
-      more you specify about the function, the more likely a conflict.
- 
-    * In particular, don't unconditionally declare `malloc' or `realloc'.
- 
-      Most GNU programs use those functions just once, in functions
-      conventionally named `xmalloc' and `xrealloc'.  These functions
-      call `malloc' and `realloc', respectively, and check the results.
- 
-      Because `xmalloc' and `xrealloc' are defined in your program, you
-      can declare them in other files without any risk of type conflict.
- 
-      On most systems, `int' is the same length as a pointer; thus, the
-      calls to `malloc' and `realloc' work fine.  For the few
-      exceptional systems (mostly 64-bit machines), you can use
-      *conditionalized* declarations of `malloc' and `realloc'--or put
-      these declarations in configuration files specific to those
-      systems.
- 
-    * The string functions require special treatment.  Some Unix systems
-      have a header file `string.h'; others have `strings.h'.  Neither
-      file name is portable.  There are two things you can do: use
-      Autoconf to figure out which file to include, or don't include
-      either file.
- 
-    * If you don't include either strings file, you can't get
-      declarations for the string functions from the header file in the
-      usual way.
- 
-      That causes less of a problem than you might think.  The newer ANSI
-      string functions should be avoided anyway because many systems
-      still don't support them.  The string functions you can use are
-      these:
- 
-           strcpy   strncpy   strcat   strncat
-           strlen   strcmp    strncmp
-           strchr   strrchr
- 
-      The copy and concatenate functions work fine without a declaration
-      as long as you don't use their values.  Using their values without
-      a declaration fails on systems where the width of a pointer
-      differs from the width of `int', and perhaps in other cases.  It
-      is trivial to avoid using their values, so do that.
- 
-      The compare functions and `strlen' work fine without a declaration
-      on most systems, possibly all the ones that GNU software runs on.
-      You may find it necessary to declare them *conditionally* on a few
-      systems.
- 
-      The search functions must be declared to return `char *'.  Luckily,
-      there is no variation in the data type they return.  But there is
-      variation in their names.  Some systems give these functions the
-      names `index' and `rindex'; other systems use the names `strchr'
-      and `strrchr'.  Some systems support both pairs of names, but
-      neither pair works on all systems.
- 
-      You should pick a single pair of names and use it throughout your
-      program.  (Nowadays, it is better to choose `strchr' and `strrchr'
-      for new programs, since those are the standard ANSI names.)
-      Declare both of those names as functions returning `char *'.  On
-      systems which don't support those names, define them as macros in
-      terms of the other pair.  For example, here is what to put at the
-      beginning of your file (or in a header) if you want to use the
-      names `strchr' and `strrchr' throughout:
- 
-           #ifndef HAVE_STRCHR
-           #define strchr index
-           #endif
-           #ifndef HAVE_STRRCHR
-           #define strrchr rindex
-           #endif
-           
-           char *strchr ();
-           char *strrchr ();
- 
-    Here we assume that `HAVE_STRCHR' and `HAVE_STRRCHR' are macros
- defined in systems where the corresponding functions exist.  One way to
- get them properly defined is to use Autoconf.
- 
- 
- File: standards.info,  Node: Internationalization,  Next: Mmap,  Prev: System Functions,  Up: Writing C
- 
- Internationalization
- ====================
- 
-    GNU has a library called GNU gettext that makes it easy to translate
- the messages in a program into various languages.  You should use this
- library in every program.  Use English for the messages as they appear
- in the program, and let gettext provide the way to translate them into
- other languages.
- 
-    Using GNU gettext involves putting a call to the `gettext' macro
- around each string that might need translation--like this:
- 
-      printf (gettext ("Processing file `%s'..."));
- 
- This permits GNU gettext to replace the string `"Processing file
- `%s'..."' with a translated version.
- 
-    Once a program uses gettext, please make a point of writing calls to
- `gettext' when you add new strings that call for translation.
- 
-    Using GNU gettext in a package involves specifying a "text domain
- name" for the package.  The text domain name is used to separate the
- translations for this package from the translations for other packages.
- Normally, the text domain name should be the same as the name of the
- package--for example, `fileutils' for the GNU file utilities.
- 
-    To enable gettext to work well, avoid writing code that makes
- assumptions about the structure of words or sentences.  When you want
- the precise text of a sentence to vary depending on the data, use two or
- more alternative string constants each containing a complete sentences,
- rather than inserting conditionalized words or phrases into a single
- sentence framework.
- 
-    Here is an example of what not to do:
- 
-      printf ("%d file%s processed", nfiles,
-              nfiles != 1 ? "s" : "");
- 
- The problem with that example is that it assumes that plurals are made
- by adding `s'.  If you apply gettext to the format string, like this,
- 
-      printf (gettext ("%d file%s processed"), nfiles,
-              nfiles != 1 ? "s" : "");
- 
- the message can use different words, but it will still be forced to use
- `s' for the plural.  Here is a better way:
- 
-      printf ((nfiles != 1 ? "%d files processed"
-               : "%d file processed"),
-              nfiles);
- 
- This way, you can apply gettext to each of the two strings
- independently:
- 
-      printf ((nfiles != 1 ? gettext ("%d files processed")
-               : gettext ("%d file processed")),
-              nfiles);
- 
- This can be any method of forming the plural of the word for "file", and
- also handles languages that require agreement in the word for
- "processed".
- 
-    A similar problem appears at the level of sentence structure with
- this code:
- 
-      printf ("#  Implicit rule search has%s been done.\n",
-              f->tried_implicit ? "" : " not");
- 
- Adding `gettext' calls to this code cannot give correct results for all
- languages, because negation in some languages requires adding words at
- more than one place in the sentence.  By contrast, adding `gettext'
- calls does the job straightfowardly if the code starts out like this:
- 
-      printf (f->tried_implicit
-              ? "#  Implicit rule search has been done.\n",
-              : "#  Implicit rule search has not been done.\n");
- 
- 
- File: standards.info,  Node: Mmap,  Prev: Internationalization,  Up: Writing C
- 
- Mmap
- ====
- 
-    Don't assume that `mmap' either works on all files or fails for all
- files.  It may work on some files and fail on others.
- 
-    The proper way to use `mmap' is to try it on the specific file for
- which you want to use it--and if `mmap' doesn't work, fall back on
- doing the job in another way using `read' and `write'.
- 
-    The reason this precaution is needed is that the GNU kernel (the
- HURD) provides a user-extensible file system, in which there can be many
- different kinds of "ordinary files."  Many of them support `mmap', but
- some do not.  It is important to make programs handle all these kinds
- of files.
- 
- 
- File: standards.info,  Node: Documentation,  Next: Managing Releases,  Prev: Writing C,  Up: Top
- 
- Documenting Programs
- ********************
- 
- * Menu:
- 
- * GNU Manuals::                 Writing proper manuals.
- * Manual Structure Details::    Specific structure conventions.
- * NEWS File::                   NEWS files supplement manuals.
- * Change Logs::                 Recording Changes
- * Man Pages::                   Man pages are secondary.
- * Reading other Manuals::       How far you can go in learning
-                                 from other manuals.
- 
- 
- File: standards.info,  Node: GNU Manuals,  Next: Manual Structure Details,  Up: Documentation
- 
- GNU Manuals
- ===========
- 
-    The preferred way to document part of the GNU system is to write a
- manual in the Texinfo formatting language.  See the Texinfo manual,
- either the hardcopy, or the on-line version available through `info' or
- the Emacs Info subsystem (`C-h i').
- 
-    Programmers often find it most natural to structure the documentation
- following the structure of the implementation, which they know.  But
- this structure is not necessarily good for explaining how to use the
- program; it may be irrelevant and confusing for a user.
- 
-    At every level, from the sentences in a paragraph to the grouping of
- topics into separate manuals, the right way to structure documentation
- is according to the concepts and questions that a user will have in mind
- when reading it.  Sometimes this structure of ideas matches the
- structure of the implementation of the software being documented--but
- often they are different.  Often the most important part of learning to
- write good documentation is learning to notice when you are structuring
- the documentation like the implementation, and think about better
- alternatives.
- 
-    For example, each program in the GNU system probably ought to be
- documented in one manual; but this does not mean each program should
- have its own manual.  That would be following the structure of the
- implementation, rather than the structure that helps the user
- understand.
- 
-    Instead, each manual should cover a coherent *topic*.  For example,
- instead of a manual for `diff' and a manual for `diff3', we have one
- manual for "comparison of files" which covers both of those programs,
- as well as `cmp'.  By documenting these programs together, we can make
- the whole subject clearer.
- 
-    The manual which discusses a program should document all of the
- program's command-line options and all of its commands.  It should give
- examples of their use.  But don't organize the manual as a list of
- features.  Instead, organize it logically, by subtopics.  Address the
- questions that a user will ask when thinking about the job that the
- program does.
- 
-    In general, a GNU manual should serve both as tutorial and reference.
- It should be set up for convenient access to each topic through Info,
- and for reading straight through (appendixes aside).  A GNU manual
- should give a good introduction to a beginner reading through from the
- start, and should also provide all the details that hackers want.
- 
-    That is not as hard as it first sounds.  Arrange each chapter as a
- logical breakdown of its topic, but order the sections, and write their
- text, so that reading the chapter straight through makes sense.  Do
- likewise when structuring the book into chapters, and when structuring a
- section into paragraphs.  The watchword is, *at each point, address the
- most fundamental and important issue raised by the preceding text.*
- 
-    If necessary, add extra chapters at the beginning of the manual which
- are purely tutorial and cover the basics of the subject.  These provide
- the framework for a beginner to understand the rest of the manual.  The
- Bison manual provides a good example of how to do this.
- 
-    Don't use Unix man pages as a model for how to write GNU
- documentation; most of them are terse, badly structured, and give
- inadequate explanation of the underlying concepts.  (There are, of
- course exceptions.)  Also Unix man pages use a particular format which
- is different from what we use in GNU manuals.
- 
-    Please do not use the term "pathname" that is used in Unix
- documentation; use "file name" (two words) instead.  We use the term
- "path" only for search paths, which are lists of file names.
- 
-    Please do not use the term "illegal" to refer to erroneous input to a
- computer program.  Please use "invalid" for this, and reserve the term
- "illegal" for violations of law.
- 
- 
- File: standards.info,  Node: Manual Structure Details,  Next: NEWS File,  Prev: GNU Manuals,  Up: Documentation
- 
- Manual Structure Details
- ========================
- 
-    The title page of the manual should state the version of the
- programs or packages documented in the manual.  The Top node of the
- manual should also contain this information.  If the manual is changing
- more frequently than or independent of the program, also state a version
- number for the manual in both of these places.
- 
-    Each program documented in the manual should should have a node named
- `PROGRAM Invocation' or `Invoking PROGRAM'.  This node (together with
- its subnodes, if any) should describe the program's command line
- arguments and how to run it (the sort of information people would look
- in a man page for).  Start with an `@example' containing a template for
- all the options and arguments that the program uses.
- 
-    Alternatively, put a menu item in some menu whose item name fits one
- of the above patterns.  This identifies the node which that item points
- to as the node for this purpose, regardless of the node's actual name.
- 
-    There will be automatic features for specifying a program name and
- quickly reading just this part of its manual.
- 
-    If one manual describes several programs, it should have such a node
- for each program described.
- 
- 
- File: standards.info,  Node: NEWS File,  Next: Change Logs,  Prev: Manual Structure Details,  Up: Documentation
- 
- The NEWS File
- =============
- 
-    In addition to its manual, the package should have a file named
- `NEWS' which contains a list of user-visible changes worth mentioning.
- In each new release, add items to the front of the file and identify
- the version they pertain to.  Don't discard old items; leave them in
- the file after the newer items.  This way, a user upgrading from any
- previous version can see what is new.
- 
-    If the `NEWS' file gets very long, move some of the older items into
- a file named `ONEWS' and put a note at the end referring the user to
- that file.
- 
- 
- File: standards.info,  Node: Change Logs,  Next: Man Pages,  Prev: NEWS File,  Up: Documentation
- 
- Change Logs
- ===========
- 
-    Keep a change log to describe all the changes made to program source
- files.  The purpose of this is so that people investigating bugs in the
- future will know about the changes that might have introduced the bug.
- Often a new bug can be found by looking at what was recently changed.
- More importantly, change logs can help you eliminate conceptual
- inconsistencies between different parts of a program, by giving you a
- history of how the conflicting concepts arose and who they came from.
- 
- * Menu:
- 
- * Change Log Concepts::
- * Style of Change Logs::
- * Simple Changes::
- * Conditional Changes::
- 
- 
- File: standards.info,  Node: Change Log Concepts,  Next: Style of Change Logs,  Up: Change Logs
- 
- Change Log Concepts
- -------------------
- 
-    You can think of the change log as a conceptual "undo list" which
- explains how earlier versions were different from the current version.
- People can see the current version; they don't need the change log to
- tell them what is in it.  What they want from a change log is a clear
- explanation of how the earlier version differed.
- 
-    The change log file is normally called `ChangeLog' and covers an
- entire directory.  Each directory can have its own change log, or a
- directory can use the change log of its parent directory-it's up to you.
- 
-    Another alternative is to record change log information with a
- version control system such as RCS or CVS.  This can be converted
- automatically to a `ChangeLog' file.
- 
-    There's no need to describe the full purpose of the changes or how
- they work together.  If you think that a change calls for explanation,
- you're probably right.  Please do explain it--but please put the
- explanation in comments in the code, where people will see it whenever
- they see the code.  For example, "New function" is enough for the
- change log when you add a function, because there should be a comment
- before the function definition to explain what it does.
- 
-    However, sometimes it is useful to write one line to describe the
- overall purpose of a batch of changes.
- 
-    The easiest way to add an entry to `ChangeLog' is with the Emacs
- command `M-x add-change-log-entry'.  An entry should have an asterisk,
- the name of the changed file, and then in parentheses the name of the
- changed functions, variables or whatever, followed by a colon.  Then
- describe the changes you made to that function or variable.
- 
- 
- File: standards.info,  Node: Style of Change Logs,  Next: Simple Changes,  Prev: Change Log Concepts,  Up: Change Logs
- 
- Style of Change Logs
- --------------------
- 
-    Here are some examples of change log entries:
- 
-      * register.el (insert-register): Return nil.
-      (jump-to-register): Likewise.
-      
-      * sort.el (sort-subr): Return nil.
-      
-      * tex-mode.el (tex-bibtex-file, tex-file, tex-region):
-      Restart the tex shell if process is gone or stopped.
-      (tex-shell-running): New function.
-      
-      * expr.c (store_one_arg): Round size up for move_block_to_reg.
-      (expand_call): Round up when emitting USE insns.
-      * stmt.c (assign_parms): Round size up for move_block_from_reg.
- 
-    It's important to name the changed function or variable in full.
- Don't abbreviate function or variable names, and don't combine them.
- Subsequent maintainers will often search for a function name to find all
- the change log entries that pertain to it; if you abbreviate the name,
- they won't find it when they search.
- 
-    For example, some people are tempted to abbreviate groups of function
- names by writing `* register.el ({insert,jump-to}-register)'; this is
- not a good idea, since searching for `jump-to-register' or
- `insert-register' would not find that entry.
- 
-    Separate unrelated change log entries with blank lines.  When two
- entries represent parts of the same change, so that they work together,
- then don't put blank lines between them.  Then you can omit the file
- name and the asterisk when successive entries are in the same file.
- 
- 
- File: standards.info,  Node: Simple Changes,  Next: Conditional Changes,  Prev: Style of Change Logs,  Up: Change Logs
- 
- Simple Changes
- --------------
- 
-    Certain simple kinds of changes don't need much detail in the change
- log.
- 
-    When you change the calling sequence of a function in a simple
- fashion, and you change all the callers of the function, there is no
- need to make individual entries for all the callers that you changed.
- Just write in the entry for the function being called, "All callers
- changed."
- 
-      * keyboard.c (Fcommand_execute): New arg SPECIAL.
-      All callers changed.
- 
-    When you change just comments or doc strings, it is enough to write
- an entry for the file, without mentioning the functions.  Just "Doc
- fixes" is enough for the change log.
- 
-    There's no need to make change log entries for documentation files.
- This is because documentation is not susceptible to bugs that are hard
- to fix.  Documentation does not consist of parts that must interact in a
- precisely engineered fashion.  To correct an error, you need not know
- the history of the erroneous passage; it is enough to compare what the
- documentation says with the way the program actually works.
- 
- 
- File: standards.info,  Node: Conditional Changes,  Prev: Simple Changes,  Up: Change Logs
- 
- Conditional Changes
- -------------------
- 
-    C programs often contain compile-time `#if' conditionals.  Many
- changes are conditional; sometimes you add a new definition which is
- entirely contained in a conditional.  It is very useful to indicate in
- the change log the conditions for which the change applies.
- 
-    Our convention for indicating conditional changes is to use square
- brackets around the name of the condition.
- 
-    Here is a simple example, describing a change which is conditional
- but does not have a function or entity name associated with it:
- 
-      * xterm.c [SOLARIS2]: Include string.h.
- 
-    Here is an entry describing a new definition which is entirely
- conditional.  This new definition for the macro `FRAME_WINDOW_P' is
- used only when `HAVE_X_WINDOWS' is defined:
- 
-      * frame.h [HAVE_X_WINDOWS] (FRAME_WINDOW_P): Macro defined.
- 
-    Here is an entry for a change within the function `init_display',
- whose definition as a whole is unconditional, but the changes themselves
- are contained in a `#ifdef HAVE_LIBNCURSES' conditional:
- 
-      * dispnew.c (init_display) [HAVE_LIBNCURSES]: If X, call tgetent.
- 
-    Here is an entry for a change that takes affect only when a certain
- macro is *not* defined:
- 
-      (gethostname) [!HAVE_SOCKETS]: Replace with winsock version.
- 
- 
- File: standards.info,  Node: Man Pages,  Next: Reading other Manuals,  Prev: Change Logs,  Up: Documentation
- 
- Man Pages
- =========
- 
-    In the GNU project, man pages are secondary.  It is not necessary or
- expected for every GNU program to have a man page, but some of them do.
- It's your choice whether to include a man page in your program.
- 
-    When you make this decision, consider that supporting a man page
- requires continual effort each time the program is changed.  The time
- you spend on the man page is time taken away from more useful work.
- 
-    For a simple program which changes little, updating the man page may
- be a small job.  Then there is little reason not to include a man page,
- if you have one.
- 
-    For a large program that changes a great deal, updating a man page
- may be a substantial burden.  If a user offers to donate a man page,
- you may find this gift costly to accept.  It may be better to refuse
- the man page unless the same person agrees to take full responsibility
- for maintaining it--so that you can wash your hands of it entirely.  If
- this volunteer later ceases to do the job, then don't feel obliged to
- pick it up yourself; it may be better to withdraw the man page from the
- distribution until someone else agrees to update it.
- 
-    When a program changes only a little, you may feel that the
- discrepancies are small enough that the man page remains useful without
- updating.  If so, put a prominent note near the beginning of the man
- page explaining that you don't maintain it and that the Texinfo manual
- is more authoritative.  The note should say how to access the Texinfo
- documentation.
- 
- 
- File: standards.info,  Node: Reading other Manuals,  Prev: Man Pages,  Up: Documentation
- 
- Reading other Manuals
- =====================
- 
-    There may be non-free books or documentation files that describe the
- program you are documenting.
- 
-    It is ok to use these documents for reference, just as the author of
- a new algebra textbook can read other books on algebra.  A large portion
- of any non-fiction book consists of facts, in this case facts about how
- a certain program works, and these facts are necessarily the same for
- everyone who writes about the subject.  But be careful not to copy your
- outline structure, wording, tables or examples from preexisting non-free
- documentation.  Copying from free documentation may be ok; please check
- with the FSF about the individual case.
- 
- 
- File: standards.info,  Node: Managing Releases,  Prev: Documentation,  Up: Top
- 
- The Release Process
- *******************
- 
-    Making a release is more than just bundling up your source files in a
- tar file and putting it up for FTP.  You should set up your software so
- that it can be configured to run on a variety of systems.  Your Makefile
- should conform to the GNU standards described below, and your directory
- layout should also conform to the standards discussed below.  Doing so
- makes it easy to include your package into the larger framework of all
- GNU software.
- 
- * Menu:
- 
- * Configuration::               How Configuration Should Work
- * Makefile Conventions::	Makefile Conventions
- * Releases::                    Making Releases
- 
- 
- File: standards.info,  Node: Configuration,  Next: Makefile Conventions,  Up: Managing Releases
- 
- How Configuration Should Work
- =============================
- 
-    Each GNU distribution should come with a shell script named
- `configure'.  This script is given arguments which describe the kind of
- machine and system you want to compile the program for.
- 
-    The `configure' script must record the configuration options so that
- they affect compilation.
- 
-    One way to do this is to make a link from a standard name such as
- `config.h' to the proper configuration file for the chosen system.  If
- you use this technique, the distribution should *not* contain a file
- named `config.h'.  This is so that people won't be able to build the
- program without configuring it first.
- 
-    Another thing that `configure' can do is to edit the Makefile.  If
- you do this, the distribution should *not* contain a file named
- `Makefile'.  Instead, it should include a file `Makefile.in' which
- contains the input used for editing.  Once again, this is so that people
- won't be able to build the program without configuring it first.
- 
-    If `configure' does write the `Makefile', then `Makefile' should
- have a target named `Makefile' which causes `configure' to be rerun,
- setting up the same configuration that was set up last time.  The files
- that `configure' reads should be listed as dependencies of `Makefile'.
- 
-    All the files which are output from the `configure' script should
- have comments at the beginning explaining that they were generated
- automatically using `configure'.  This is so that users won't think of
- trying to edit them by hand.
- 
-    The `configure' script should write a file named `config.status'
- which describes which configuration options were specified when the
- program was last configured.  This file should be a shell script which,
- if run, will recreate the same configuration.
- 
-    The `configure' script should accept an option of the form
- `--srcdir=DIRNAME' to specify the directory where sources are found (if
- it is not the current directory).  This makes it possible to build the
- program in a separate directory, so that the actual source directory is
- not modified.
- 
-    If the user does not specify `--srcdir', then `configure' should
- check both `.' and `..' to see if it can find the sources.  If it finds
- the sources in one of these places, it should use them from there.
- Otherwise, it should report that it cannot find the sources, and should
- exit with nonzero status.
- 
-    Usually the easy way to support `--srcdir' is by editing a
- definition of `VPATH' into the Makefile.  Some rules may need to refer
- explicitly to the specified source directory.  To make this possible,
- `configure' can add to the Makefile a variable named `srcdir' whose
- value is precisely the specified directory.
- 
-    The `configure' script should also take an argument which specifies
- the type of system to build the program for.  This argument should look
- like this:
- 
-      CPU-COMPANY-SYSTEM
- 
-    For example, a Sun 3 might be `m68k-sun-sunos4.1'.
- 
-    The `configure' script needs to be able to decode all plausible
- alternatives for how to describe a machine.  Thus, `sun3-sunos4.1'
- would be a valid alias.  For many programs, `vax-dec-ultrix' would be
- an alias for `vax-dec-bsd', simply because the differences between
- Ultrix and BSD are rarely noticeable, but a few programs might need to
- distinguish them.
- 
-    There is a shell script called `config.sub' that you can use as a
- subroutine to validate system types and canonicalize aliases.
- 
-    Other options are permitted to specify in more detail the software
- or hardware present on the machine, and include or exclude optional
- parts of the package:
- 
- `--enable-FEATURE[=PARAMETER]'
-      Configure the package to build and install an optional user-level
-      facility called FEATURE.  This allows users to choose which
-      optional features to include.  Giving an optional PARAMETER of
-      `no' should omit FEATURE, if it is built by default.
- 
-      No `--enable' option should *ever* cause one feature to replace
-      another.  No `--enable' option should ever substitute one useful
-      behavior for another useful behavior.  The only proper use for
-      `--enable' is for questions of whether to build part of the program
-      or exclude it.
- 
- `--with-PACKAGE'
-      The package PACKAGE will be installed, so configure this package
-      to work with PACKAGE.
- 
-      Possible values of PACKAGE include `gnu-as' (or `gas'), `gnu-ld',
-      `gnu-libc', `gdb', `x', and `x-toolkit'.
- 
-      Do not use a `--with' option to specify the file name to use to
-      find certain files.  That is outside the scope of what `--with'
-      options are for.
- 
- `--nfp'
-      The target machine has no floating point processor.
- 
- `--gas'
-      The target machine assembler is GAS, the GNU assembler.  This is
-      obsolete; users should use `--with-gnu-as' instead.
- 
- `--x'
-      The target machine has the X Window System installed.  This is
-      obsolete; users should use `--with-x' instead.
- 
-    All `configure' scripts should accept all of these "detail" options,
- whether or not they make any difference to the particular package at
- hand.  In particular, they should accept any option that starts with
- `--with-' or `--enable-'.  This is so users will be able to configure
- an entire GNU source tree at once with a single set of options.
- 
-    You will note that the categories `--with-' and `--enable-' are
- narrow: they *do not* provide a place for any sort of option you might
- think of.  That is deliberate.  We want to limit the possible
- configuration options in GNU software.  We do not want GNU programs to
- have idiosyncratic configuration options.
- 
-    Packages that perform part of the compilation process may support
- cross-compilation.  In such a case, the host and target machines for
- the program may be different.  The `configure' script should normally
- treat the specified type of system as both the host and the target,
- thus producing a program which works for the same type of machine that
- it runs on.
- 
-    The way to build a cross-compiler, cross-assembler, or what have
- you, is to specify the option `--host=HOSTTYPE' when running
- `configure'.  This specifies the host system without changing the type
- of target system.  The syntax for HOSTTYPE is the same as described
- above.
- 
-    Bootstrapping a cross-compiler requires compiling it on a machine
- other than the host it will run on.  Compilation packages accept a
- configuration option `--build=HOSTTYPE' for specifying the
- configuration on which you will compile them, in case that is different
- from the host.
- 
-    Programs for which cross-operation is not meaningful need not accept
- the `--host' option, because configuring an entire operating system for
- cross-operation is not a meaningful thing.
- 
-    Some programs have ways of configuring themselves automatically.  If
- your program is set up to do this, your `configure' script can simply
- ignore most of its arguments.
- 
- 
- File: standards.info,  Node: Makefile Conventions,  Next: Releases,  Prev: Configuration,  Up: Managing Releases
- 
- Makefile Conventions
- ====================
- 
-    This node describes conventions for writing the Makefiles for GNU
- programs.
- 
- * Menu:
- 
- * Makefile Basics::		General Conventions for Makefiles
- * Utilities in Makefiles::	Utilities in Makefiles
- * Command Variables::		Variables for Specifying Commands
- * Directory Variables::		Variables for Installation Directories
- * Standard Targets::		Standard Targets for Users
- * Install Command Categories::  Three categories of commands in the `install'
-                                   rule: normal, pre-install and post-install.
- 
- 
- File: standards.info,  Node: Makefile Basics,  Next: Utilities in Makefiles,  Up: Makefile Conventions
- 
- General Conventions for Makefiles
- ---------------------------------
- 
-    Every Makefile should contain this line:
- 
-      SHELL = /bin/sh
- 
- to avoid trouble on systems where the `SHELL' variable might be
- inherited from the environment.  (This is never a problem with GNU
- `make'.)
- 
-    Different `make' programs have incompatible suffix lists and
- implicit rules, and this sometimes creates confusion or misbehavior.  So
- it is a good idea to set the suffix list explicitly using only the
- suffixes you need in the particular Makefile, like this:
- 
-      .SUFFIXES:
-      .SUFFIXES: .c .o
- 
- The first line clears out the suffix list, the second introduces all
- suffixes which may be subject to implicit rules in this Makefile.
- 
-    Don't assume that `.' is in the path for command execution.  When
- you need to run programs that are a part of your package during the
- make, please make sure that it uses `./' if the program is built as
- part of the make or `$(srcdir)/' if the file is an unchanging part of
- the source code.  Without one of these prefixes, the current search
- path is used.
- 
-    The distinction between `./' (the "build directory") and
- `$(srcdir)/' (the "source directory") is important because users can
- build in a separate directory using the `--srcdir' option to
- `configure'.  A rule of the form:
- 
-      foo.1 : foo.man sedscript
-              sed -e sedscript foo.man > foo.1
- 
- will fail when the build directory is not the source directory, because
- `foo.man' and `sedscript' are in the the source directory.
- 
-    When using GNU `make', relying on `VPATH' to find the source file
- will work in the case where there is a single dependency file, since
- the `make' automatic variable `$<' will represent the source file
- wherever it is.  (Many versions of `make' set `$<' only in implicit
- rules.)  A Makefile target like
- 
-      foo.o : bar.c
-              $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
- 
- should instead be written as
- 
-      foo.o : bar.c
-              $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
- 
- in order to allow `VPATH' to work correctly.  When the target has
- multiple dependencies, using an explicit `$(srcdir)' is the easiest way
- to make the rule work well.  For example, the target above for `foo.1'
- is best written as:
- 
-      foo.1 : foo.man sedscript
-              sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@
- 
-    GNU distributions usually contain some files which are not source
- files--for example, Info files, and the output from Autoconf, Automake,
- Bison or Flex.  Since these files normally appear in the source
- directory, they should always appear in the source directory, not in the
- build directory.  So Makefile rules to update them should put the
- updated files in the source directory.
- 
-    However, if a file does not appear in the distribution, then the
- Makefile should not put it in the source directory, because building a
- program in ordinary circumstances should not modify the source directory
- in any way.
- 
-    Try to make the build and installation targets, at least (and all
- their subtargets) work correctly with a parallel `make'.
- 
- 
- File: standards.info,  Node: Utilities in Makefiles,  Next: Command Variables,  Prev: Makefile Basics,  Up: Makefile Conventions
- 
- Utilities in Makefiles
- ----------------------
- 
-    Write the Makefile commands (and any shell scripts, such as
- `configure') to run in `sh', not in `csh'.  Don't use any special
- features of `ksh' or `bash'.
- 
-    The `configure' script and the Makefile rules for building and
- installation should not use any utilities directly except these:
- 
-      cat cmp cp diff echo egrep expr false grep install-info
-      ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
- 
-    The compression program `gzip' can be used in the `dist' rule.
- 
-    Stick to the generally supported options for these programs.  For
- example, don't use `mkdir -p', convenient as it may be, because most
- systems don't support it.
- 
-    It is a good idea to avoid creating symbolic links in makefiles,
- since a few systems don't support them.
- 
-    The Makefile rules for building and installation can also use
- compilers and related programs, but should do so via `make' variables
- so that the user can substitute alternatives.  Here are some of the
- programs we mean:
- 
-      ar bison cc flex install ld ldconfig lex
-      make makeinfo ranlib texi2dvi yacc
- 
-    Use the following `make' variables to run those programs:
- 
-      $(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
-      $(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
- 
-    When you use `ranlib' or `ldconfig', you should make sure nothing
- bad happens if the system does not have the program in question.
- Arrange to ignore an error from that command, and print a message before
- the command to tell the user that failure of this command does not mean
- a problem.  (The Autoconf `AC_PROG_RANLIB' macro can help with this.)
- 
-    If you use symbolic links, you should implement a fallback for
- systems that don't have symbolic links.
- 
-    Additional utilities that can be used via Make variables are:
- 
-      chgrp chmod chown mknod
- 
-    It is ok to use other utilities in Makefile portions (or scripts)
- intended only for particular systems where you know those utilities
- exist.
- 
- 
- File: standards.info,  Node: Command Variables,  Next: Directory Variables,  Prev: Utilities in Makefiles,  Up: Makefile Conventions
- 
- Variables for Specifying Commands
- ---------------------------------
- 
-    Makefiles should provide variables for overriding certain commands,
- options, and so on.
- 
-    In particular, you should run most utility programs via variables.
- Thus, if you use Bison, have a variable named `BISON' whose default
- value is set with `BISON = bison', and refer to it with `$(BISON)'
- whenever you need to use Bison.
- 
-    File management utilities such as `ln', `rm', `mv', and so on, need
- not be referred to through variables in this way, since users don't
- need to replace them with other programs.
- 
-    Each program-name variable should come with an options variable that
- is used to supply options to the program.  Append `FLAGS' to the
- program-name variable name to get the options variable name--for
- example, `BISONFLAGS'.  (The names `CFLAGS' for the C compiler,
- `YFLAGS' for yacc, and `LFLAGS' for lex, are exceptions to this rule,
- but we keep them because they are standard.)  Use `CPPFLAGS' in any
- compilation command that runs the preprocessor, and use `LDFLAGS' in
- any compilation command that does linking as well as in any direct use
- of `ld'.
- 
-    If there are C compiler options that *must* be used for proper
- compilation of certain files, do not include them in `CFLAGS'.  Users
- expect to be able to specify `CFLAGS' freely themselves.  Instead,
- arrange to pass the necessary options to the C compiler independently
- of `CFLAGS', by writing them explicitly in the compilation commands or
- by defining an implicit rule, like this:
- 
-      CFLAGS = -g
-      ALL_CFLAGS = -I. $(CFLAGS)
-      .c.o:
-              $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
- 
-    Do include the `-g' option in `CFLAGS', because that is not
- *required* for proper compilation.  You can consider it a default that
- is only recommended.  If the package is set up so that it is compiled
- with GCC by default, then you might as well include `-O' in the default
- value of `CFLAGS' as well.
- 
-    Put `CFLAGS' last in the compilation command, after other variables
- containing compiler options, so the user can use `CFLAGS' to override
- the others.
- 
-    `CFLAGS' should be used in every invocation of the C compiler, both
- those which do compilation and those which do linking.
- 
-    Every Makefile should define the variable `INSTALL', which is the
- basic command for installing a file into the system.
- 
-    Every Makefile should also define the variables `INSTALL_PROGRAM'
- and `INSTALL_DATA'.  (The default for each of these should be
- `$(INSTALL)'.)  Then it should use those variables as the commands for
- actual installation, for executables and nonexecutables respectively.
- Use these variables as follows:
- 
-      $(INSTALL_PROGRAM) foo $(bindir)/foo
-      $(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
- 
- Always use a file name, not a directory name, as the second argument of
- the installation commands.  Use a separate command for each file to be
- installed.
- 
- 
- File: standards.info,  Node: Directory Variables,  Next: Standard Targets,  Prev: Command Variables,  Up: Makefile Conventions
- 
- Variables for Installation Directories
- --------------------------------------
- 
-    Installation directories should always be named by variables, so it
- is easy to install in a nonstandard place.  The standard names for these
- variables are described below.  They are based on a standard filesystem
- layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
- other modern operating systems.
- 
-    These two variables set the root for the installation.  All the other
- installation directories should be subdirectories of one of these two,
- and nothing should be directly installed into these two directories.
- 
- `prefix'
-      A prefix used in constructing the default values of the variables
-      listed below.  The default value of `prefix' should be
-      `/usr/local'.  When building the complete GNU system, the prefix
-      will be empty and `/usr' will be a symbolic link to `/'.  (If you
-      are using Autoconf, write it as `@prefix@'.)
- 
- `exec_prefix'
-      A prefix used in constructing the default values of some of the
-      variables listed below.  The default value of `exec_prefix' should
-      be `$(prefix)'.  (If you are using Autoconf, write it as
-      `@exec_prefix@'.)
- 
-      Generally, `$(exec_prefix)' is used for directories that contain
-      machine-specific files (such as executables and subroutine
-      libraries), while `$(prefix)' is used directly for other
-      directories.
- 
-    Executable programs are installed in one of the following
- directories.
- 
- `bindir'
-      The directory for installing executable programs that users can
-      run.  This should normally be `/usr/local/bin', but write it as
-      `$(exec_prefix)/bin'.  (If you are using Autoconf, write it as
-      `@bindir@'.)
- 
- `sbindir'
-      The directory for installing executable programs that can be run
-      from the shell, but are only generally useful to system
-      administrators.  This should normally be `/usr/local/sbin', but
-      write it as `$(exec_prefix)/sbin'.  (If you are using Autoconf,
-      write it as `@sbindir@'.)
- 
- `libexecdir'
-      The directory for installing executable programs to be run by other
-      programs rather than by users.  This directory should normally be
-      `/usr/local/libexec', but write it as `$(exec_prefix)/libexec'.
-      (If you are using Autoconf, write it as `@libexecdir@'.)
- 
-    Data files used by the program during its execution are divided into
- categories in two ways.
- 
-    * Some files are normally modified by programs; others are never
-      normally modified (though users may edit some of these).
- 
-    * Some files are architecture-independent and can be shared by all
-      machines at a site; some are architecture-dependent and can be
-      shared only by machines of the same kind and operating system;
-      others may never be shared between two machines.
- 
-    This makes for six different possibilities.  However, we want to
- discourage the use of architecture-dependent files, aside from object
- files and libraries.  It is much cleaner to make other data files
- architecture-independent, and it is generally not hard.
- 
-    Therefore, here are the variables Makefiles should use to specify
- directories:
- 
- `datadir'
-      The directory for installing read-only architecture independent
-      data files.  This should normally be `/usr/local/share', but write
-      it as `$(prefix)/share'.  (If you are using Autoconf, write it as
-      `@datadir@'.)  As a special exception, see `$(infodir)' and
-      `$(includedir)' below.
- 
- `sysconfdir'
-      The directory for installing read-only data files that pertain to a
-      single machine-that is to say, files for configuring a host.
-      Mailer and network configuration files, `/etc/passwd', and so
-      forth belong here.  All the files in this directory should be
-      ordinary ASCII text files.  This directory should normally be
-      `/usr/local/etc', but write it as `$(prefix)/etc'.  (If you are
-      using Autoconf, write it as `@sysconfdir@'.)
- 
-      Do not install executables here in this directory (they probably
-      belong in `$(libexecdir)' or `$(sbindir)').  Also do not install
-      files that are modified in the normal course of their use (programs
-      whose purpose is to change the configuration of the system
-      excluded).  Those probably belong in `$(localstatedir)'.
- 
- `sharedstatedir'
-      The directory for installing architecture-independent data files
-      which the programs modify while they run.  This should normally be
-      `/usr/local/com', but write it as `$(prefix)/com'.  (If you are
-      using Autoconf, write it as `@sharedstatedir@'.)
- 
- `localstatedir'
-      The directory for installing data files which the programs modify
-      while they run, and that pertain to one specific machine.  Users
-      should never need to modify files in this directory to configure
-      the package's operation; put such configuration information in
-      separate files that go in `$(datadir)' or `$(sysconfdir)'.
-      `$(localstatedir)' should normally be `/usr/local/var', but write
-      it as `$(prefix)/var'.  (If you are using Autoconf, write it as
-      `@localstatedir@'.)
- 
- `libdir'
-      The directory for object files and libraries of object code.  Do
-      not install executables here, they probably ought to go in
-      `$(libexecdir)' instead.  The value of `libdir' should normally be
-      `/usr/local/lib', but write it as `$(exec_prefix)/lib'.  (If you
-      are using Autoconf, write it as `@libdir@'.)
- 
- `infodir'
-      The directory for installing the Info files for this package.  By
-      default, it should be `/usr/local/info', but it should be written
-      as `$(prefix)/info'.  (If you are using Autoconf, write it as
-      `@infodir@'.)
- 
- `lispdir'
-      The directory for installing any Emacs Lisp files in this package.
-      By default, it should be `/usr/local/share/emacs/site-lisp', but
-      it should be written as `$(prefix)/share/emacs/site-lisp'.
- 
-      If you are using Autoconf, write the default as `@lispdir@'.  In
-      order to make `@lispdir@' work, you need the following lines in
-      your `configure.in' file:
- 
-           lispdir='${datadir}/emacs/site-lisp'
-           AC_SUBST(lispdir)
- 
- `includedir'
-      The directory for installing header files to be included by user
-      programs with the C `#include' preprocessor directive.  This
-      should normally be `/usr/local/include', but write it as
-      `$(prefix)/include'.  (If you are using Autoconf, write it as
-      `@includedir@'.)
- 
-      Most compilers other than GCC do not look for header files in
-      directory `/usr/local/include'.  So installing the header files
-      this way is only useful with GCC.  Sometimes this is not a problem
-      because some libraries are only really intended to work with GCC.
-      But some libraries are intended to work with other compilers.
-      They should install their header files in two places, one
-      specified by `includedir' and one specified by `oldincludedir'.
- 
- `oldincludedir'
-      The directory for installing `#include' header files for use with
-      compilers other than GCC.  This should normally be `/usr/include'.
-      (If you are using Autoconf, you can write it as `@oldincludedir@'.)
- 
-      The Makefile commands should check whether the value of
-      `oldincludedir' is empty.  If it is, they should not try to use
-      it; they should cancel the second installation of the header files.
- 
-      A package should not replace an existing header in this directory
-      unless the header came from the same package.  Thus, if your Foo
-      package provides a header file `foo.h', then it should install the
-      header file in the `oldincludedir' directory if either (1) there
-      is no `foo.h' there or (2) the `foo.h' that exists came from the
-      Foo package.
- 
-      To tell whether `foo.h' came from the Foo package, put a magic
-      string in the file--part of a comment--and `grep' for that string.
- 
-    Unix-style man pages are installed in one of the following:
- 
- `mandir'
-      The top-level directory for installing the man pages (if any) for
-      this package.  It will normally be `/usr/local/man', but you should
-      write it as `$(prefix)/man'.  (If you are using Autoconf, write it
-      as `@mandir@'.)
- 
- `man1dir'
-      The directory for installing section 1 man pages.  Write it as
-      `$(mandir)/man1'.
- 
- `man2dir'
-      The directory for installing section 2 man pages.  Write it as
-      `$(mandir)/man2'
- 
- `...'
-      *Don't make the primary documentation for any GNU software be a
-      man page.  Write a manual in Texinfo instead.  Man pages are just
-      for the sake of people running GNU software on Unix, which is a
-      secondary application only.*
- 
- `manext'
-      The file name extension for the installed man page.  This should
-      contain a period followed by the appropriate digit; it should
-      normally be `.1'.
- 
- `man1ext'
-      The file name extension for installed section 1 man pages.
- 
- `man2ext'
-      The file name extension for installed section 2 man pages.
- 
- `...'
-      Use these names instead of `manext' if the package needs to
-      install man pages in more than one section of the manual.
- 
-    And finally, you should set the following variable:
- 
- `srcdir'
-      The directory for the sources being compiled.  The value of this
-      variable is normally inserted by the `configure' shell script.
-      (If you are using Autconf, use `srcdir = @srcdir@'.)
- 
-    For example:
- 
-      # Common prefix for installation directories.
-      # NOTE: This directory must exist when you start the install.
-      prefix = /usr/local
-      exec_prefix = $(prefix)
-      # Where to put the executable for the command `gcc'.
-      bindir = $(exec_prefix)/bin
-      # Where to put the directories used by the compiler.
-      libexecdir = $(exec_prefix)/libexec
-      # Where to put the Info files.
-      infodir = $(prefix)/info
- 
-    If your program installs a large number of files into one of the
- standard user-specified directories, it might be useful to group them
- into a subdirectory particular to that program.  If you do this, you
- should write the `install' rule to create these subdirectories.
- 
-    Do not expect the user to include the subdirectory name in the value
- of any of the variables listed above.  The idea of having a uniform set
- of variable names for installation directories is to enable the user to
- specify the exact same values for several different GNU packages.  In
- order for this to be useful, all the packages must be designed so that
- they will work sensibly when the user does so.
- 
- 
- File: standards.info,  Node: Standard Targets,  Next: Install Command Categories,  Prev: Directory Variables,  Up: Makefile Conventions
- 
- Standard Targets for Users
- --------------------------
- 
-    All GNU programs should have the following targets in their
- Makefiles:
- 
- `all'
-      Compile the entire program.  This should be the default target.
-      This target need not rebuild any documentation files; Info files
-      should normally be included in the distribution, and DVI files
-      should be made only when explicitly asked for.
- 
-      By default, the Make rules should compile and link with `-g', so
-      that executable programs have debugging symbols.  Users who don't
-      mind being helpless can strip the executables later if they wish.
- 
- `install'
-      Compile the program and copy the executables, libraries, and so on
-      to the file names where they should reside for actual use.  If
-      there is a simple test to verify that a program is properly
-      installed, this target should run that test.
- 
-      Do not strip executables when installing them.  Devil-may-care
-      users can use the `install-strip' target to do that.
- 
-      If possible, write the `install' target rule so that it does not
-      modify anything in the directory where the program was built,
-      provided `make all' has just been done.  This is convenient for
-      building the program under one user name and installing it under
-      another.
- 
-      The commands should create all the directories in which files are
-      to be installed, if they don't already exist.  This includes the
-      directories specified as the values of the variables `prefix' and
-      `exec_prefix', as well as all subdirectories that are needed.  One
-      way to do this is by means of an `installdirs' target as described
-      below.
- 
-      Use `-' before any command for installing a man page, so that
-      `make' will ignore any errors.  This is in case there are systems
-      that don't have the Unix man page documentation system installed.
- 
-      The way to install Info files is to copy them into `$(infodir)'
-      with `$(INSTALL_DATA)' (*note Command Variables::.), and then run
-      the `install-info' program if it is present.  `install-info' is a
-      program that edits the Info `dir' file to add or update the menu
-      entry for the given Info file; it is part of the Texinfo package.
-      Here is a sample rule to install an Info file:
- 
-           $(infodir)/foo.info: foo.info
-                   $(POST_INSTALL)
-           # There may be a newer info file in . than in srcdir.
-                   -if test -f foo.info; then d=.; \
-                    else d=$(srcdir); fi; \
-                   $(INSTALL_DATA) $$d/foo.info $@; \
-           # Run install-info only if it exists.
-           # Use `if' instead of just prepending `-' to the
-           # line so we notice real errors from install-info.
-           # We use `$(SHELL) -c' because some shells do not
-           # fail gracefully when there is an unknown command.
-                   if $(SHELL) -c 'install-info --version' \
-                      >/dev/null 2>&1; then \
-                     install-info --dir-file=$(infodir)/dir \
-                                  $(infodir)/foo.info; \
-                   else true; fi
- 
-      When writing the `install' target, you must classify all the
-      commands into three categories: normal ones, "pre-installation"
-      commands and "post-installation" commands.  *Note Install Command
-      Categories::.
- 
- `uninstall'
-      Delete all the installed files--the copies that the `install'
-      target creates.
- 
-      This rule should not modify the directories where compilation is
-      done, only the directories where files are installed.
- 
-      The uninstallation commands are divided into three categories,
-      just like the installation commands.  *Note Install Command
-      Categories::.
- 
- `install-strip'
-      Like `install', but strip the executable files while installing
-      them.  In many cases, the definition of this target can be very
-      simple:
- 
-           install-strip:
-                   $(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' \
-                           install
- 
-      Normally we do not recommend stripping an executable unless you
-      are sure the program has no bugs.  However, it can be reasonable
-      to install a stripped executable for actual execution while saving
-      the unstripped executable elsewhere in case there is a bug.
- 
- `clean'
-      Delete all files from the current directory that are normally
-      created by building the program.  Don't delete the files that
-      record the configuration.  Also preserve files that could be made
-      by building, but normally aren't because the distribution comes
-      with them.
- 
-      Delete `.dvi' files here if they are not part of the distribution.
- 
- `distclean'
-      Delete all files from the current directory that are created by
-      configuring or building the program.  If you have unpacked the
-      source and built the program without creating any other files,
-      `make distclean' should leave only the files that were in the
-      distribution.
- 
- `mostlyclean'
-      Like `clean', but may refrain from deleting a few files that people
-      normally don't want to recompile.  For example, the `mostlyclean'
-      target for GCC does not delete `libgcc.a', because recompiling it
-      is rarely necessary and takes a lot of time.
- 
- `maintainer-clean'
-      Delete almost everything from the current directory that can be
-      reconstructed with this Makefile.  This typically includes
-      everything deleted by `distclean', plus more: C source files
-      produced by Bison, tags tables, Info files, and so on.
- 
-      The reason we say "almost everything" is that running the command
-      `make maintainer-clean' should not delete `configure' even if
-      `configure' can be remade using a rule in the Makefile.  More
-      generally, `make maintainer-clean' should not delete anything that
-      needs to exist in order to run `configure' and then begin to build
-      the program.  This is the only exception; `maintainer-clean' should
-      delete everything else that can be rebuilt.
- 
-      The `maintainer-clean' target is intended to be used by a
-      maintainer of the package, not by ordinary users.  You may need
-      special tools to reconstruct some of the files that `make
-      maintainer-clean' deletes.  Since these files are normally
-      included in the distribution, we don't take care to make them easy
-      to reconstruct.  If you find you need to unpack the full
-      distribution again, don't blame us.
- 
-      To help make users aware of this, the commands for the special
-      `maintainer-clean' target should start with these two:
- 
-           @echo 'This command is intended for maintainers to use; it'
-           @echo 'deletes files that may need special tools to rebuild.'
- 
- `TAGS'
-      Update a tags table for this program.
- 
- `info'
-      Generate any Info files needed.  The best way to write the rules
-      is as follows:
- 
-           info: foo.info
-           
-           foo.info: foo.texi chap1.texi chap2.texi
-                   $(MAKEINFO) $(srcdir)/foo.texi
- 
-      You must define the variable `MAKEINFO' in the Makefile.  It should
-      run the `makeinfo' program, which is part of the Texinfo
-      distribution.
- 
-      Normally a GNU distribution comes with Info files, and that means
-      the Info files are present in the source directory.  Therefore,
-      the Make rule for an info file should update it in the source
-      directory.  When users build the package, ordinarily Make will not
-      update the Info files because they will already be up to date.
- 
- `dvi'
-      Generate DVI files for all Texinfo documentation.  For example:
- 
-           dvi: foo.dvi
-           
-           foo.dvi: foo.texi chap1.texi chap2.texi
-                   $(TEXI2DVI) $(srcdir)/foo.texi
- 
-      You must define the variable `TEXI2DVI' in the Makefile.  It should
-      run the program `texi2dvi', which is part of the Texinfo
-      distribution.(1)  Alternatively, write just the dependencies, and
-      allow GNU `make' to provide the command.
- 
- `dist'
-      Create a distribution tar file for this program.  The tar file
-      should be set up so that the file names in the tar file start with
-      a subdirectory name which is the name of the package it is a
-      distribution for.  This name can include the version number.
- 
-      For example, the distribution tar file of GCC version 1.40 unpacks
-      into a subdirectory named `gcc-1.40'.
- 
-      The easiest way to do this is to create a subdirectory
-      appropriately named, use `ln' or `cp' to install the proper files
-      in it, and then `tar' that subdirectory.
- 
-      Compress the tar file file with `gzip'.  For example, the actual
-      distribution file for GCC version 1.40 is called `gcc-1.40.tar.gz'.
- 
-      The `dist' target should explicitly depend on all non-source files
-      that are in the distribution, to make sure they are up to date in
-      the distribution.  *Note Making Releases: Releases.
- 
- `check'
-      Perform self-tests (if any).  The user must build the program
-      before running the tests, but need not install the program; you
-      should write the self-tests so that they work when the program is
-      built but not installed.
- 
-    The following targets are suggested as conventional names, for
- programs in which they are useful.
- 
- `installcheck'
-      Perform installation tests (if any).  The user must build and
-      install the program before running the tests.  You should not
-      assume that `$(bindir)' is in the search path.
- 
- `installdirs'
-      It's useful to add a target named `installdirs' to create the
-      directories where files are installed, and their parent
-      directories.  There is a script called `mkinstalldirs' which is
-      convenient for this; you can find it in the Texinfo package.  You
-      can use a rule like this:
- 
-           # Make sure all installation directories (e.g. $(bindir))
-           # actually exist by making them if necessary.
-           installdirs: mkinstalldirs
-                   $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
-                                           $(libdir) $(infodir) \
-                                           $(mandir)
- 
-      This rule should not modify the directories where compilation is
-      done.  It should do nothing but create installation directories.
- 
-    ---------- Footnotes ----------
- 
-    (1) `texi2dvi' uses TeX to do the real work of formatting. TeX is
- not distributed with Texinfo.
- 
- 
- File: standards.info,  Node: Install Command Categories,  Prev: Standard Targets,  Up: Makefile Conventions
- 
- Install Command Categories
- --------------------------
- 
-    When writing the `install' target, you must classify all the
- commands into three categories: normal ones, "pre-installation"
- commands and "post-installation" commands.
- 
-    Normal commands move files into their proper places, and set their
- modes.  They may not alter any files except the ones that come entirely
- from the package they belong to.
- 
-    Pre-installation and post-installation commands may alter other
- files; in particular, they can edit global configuration files or data
- bases.
- 
-    Pre-installation commands are typically executed before the normal
- commands, and post-installation commands are typically run after the
- normal commands.
- 
-    The most common use for a post-installation command is to run
- `install-info'.  This cannot be done with a normal command, since it
- alters a file (the Info directory) which does not come entirely and
- solely from the package being installed.  It is a post-installation
- command because it needs to be done after the normal command which
- installs the package's Info files.
- 
-    Most programs don't need any pre-installation commands, but we have
- the feature just in case it is needed.
- 
-    To classify the commands in the `install' rule into these three
- categories, insert "category lines" among them.  A category line
- specifies the category for the commands that follow.
- 
-    A category line consists of a tab and a reference to a special Make
- variable, plus an optional comment at the end.  There are three
- variables you can use, one for each category; the variable name
- specifies the category.  Category lines are no-ops in ordinary execution
- because these three Make variables are normally undefined (and you
- *should not* define them in the makefile).
- 
-    Here are the three possible category lines, each with a comment that
- explains what it means:
- 
-              $(PRE_INSTALL)     # Pre-install commands follow.
-              $(POST_INSTALL)    # Post-install commands follow.
-              $(NORMAL_INSTALL)  # Normal commands follow.
- 
-    If you don't use a category line at the beginning of the `install'
- rule, all the commands are classified as normal until the first category
- line.  If you don't use any category lines, all the commands are
- classified as normal.
- 
-    These are the category lines for `uninstall':
- 
-              $(PRE_UNINSTALL)     # Pre-uninstall commands follow.
-              $(POST_UNINSTALL)    # Post-uninstall commands follow.
-              $(NORMAL_UNINSTALL)  # Normal commands follow.
- 
-    Typically, a pre-uninstall command would be used for deleting entries
- from the Info directory.
- 
-    If the `install' or `uninstall' target has any dependencies which
- act as subroutines of installation, then you should start *each*
- dependency's commands with a category line, and start the main target's
- commands with a category line also.  This way, you can ensure that each
- command is placed in the right category regardless of which of the
- dependencies actually run.
- 
-    Pre-installation and post-installation commands should not run any
- programs except for these:
- 
-      [ basename bash cat chgrp chmod chown cmp cp dd diff echo
-      egrep expand expr false fgrep find getopt grep gunzip gzip
-      hostname install install-info kill ldconfig ln ls md5sum
-      mkdir mkfifo mknod mv printenv pwd rm rmdir sed sort tee
-      test touch true uname xargs yes
- 
-    The reason for distinguishing the commands in this way is for the
- sake of making binary packages.  Typically a binary package contains
- all the executables and other files that need to be installed, and has
- its own method of installing them--so it does not need to run the normal
- installation commands.  But installing the binary package does need to
- execute the pre-installation and post-installation commands.
- 
-    Programs to build binary packages work by extracting the
- pre-installation and post-installation commands.  Here is one way of
- extracting the pre-installation commands:
- 
-      make -n install -o all \
-            PRE_INSTALL=pre-install \
-            POST_INSTALL=post-install \
-            NORMAL_INSTALL=normal-install \
-        | gawk -f pre-install.awk
- 
- where the file `pre-install.awk' could contain this:
- 
-      $0 ~ /^\t[ \t]*(normal_install|post_install)[ \t]*$/ {on = 0}
-      on {print $0}
-      $0 ~ /^\t[ \t]*pre_install[ \t]*$/ {on = 1}
- 
-    The resulting file of pre-installation commands is executed as a
- shell script as part of installing the binary package.
- 
- 
- File: standards.info,  Node: Releases,  Prev: Makefile Conventions,  Up: Managing Releases
- 
- Making Releases
- ===============
- 
-    Package the distribution of `Foo version 69.96' up in a gzipped tar
- file with the name `foo-69.96.tar.gz'.  It should unpack into a
- subdirectory named `foo-69.96'.
- 
-    Building and installing the program should never modify any of the
- files contained in the distribution.  This means that all the files
- that form part of the program in any way must be classified into "source
- files" and "non-source files".  Source files are written by humans and
- never changed automatically; non-source files are produced from source
- files by programs under the control of the Makefile.
- 
-    Naturally, all the source files must be in the distribution.  It is
- okay to include non-source files in the distribution, provided they are
- up-to-date and machine-independent, so that building the distribution
- normally will never modify them.  We commonly include non-source files
- produced by Bison, `lex', TeX, and `makeinfo'; this helps avoid
- unnecessary dependencies between our distributions, so that users can
- install whichever packages they want to install.
- 
-    Non-source files that might actually be modified by building and
- installing the program should *never* be included in the distribution.
- So if you do distribute non-source files, always make sure they are up
- to date when you make a new distribution.
- 
-    Make sure that the directory into which the distribution unpacks (as
- well as any subdirectories) are all world-writable (octal mode 777).
- This is so that old versions of `tar' which preserve the ownership and
- permissions of the files from the tar archive will be able to extract
- all the files even if the user is unprivileged.
- 
-    Make sure that all the files in the distribution are world-readable.
- 
-    Make sure that no file name in the distribution is more than 14
- characters long.  Likewise, no file created by building the program
- should have a name longer than 14 characters.  The reason for this is
- that some systems adhere to a foolish interpretation of the POSIX
- standard, and refuse to open a longer name, rather than truncating as
- they did in the past.
- 
-    Don't include any symbolic links in the distribution itself.  If the
- tar file contains symbolic links, then people cannot even unpack it on
- systems that don't support symbolic links.  Also, don't use multiple
- names for one file in different directories, because certain file
- systems cannot handle this and that prevents unpacking the distribution.
- 
-    Try to make sure that all the file names will be unique on MS-DOS.  A
- name on MS-DOS consists of up to 8 characters, optionally followed by a
- period and up to three characters.  MS-DOS will truncate extra
- characters both before and after the period.  Thus, `foobarhacker.c'
- and `foobarhacker.o' are not ambiguous; they are truncated to
- `foobarha.c' and `foobarha.o', which are distinct.
- 
-    Include in your distribution a copy of the `texinfo.tex' you used to
- test print any `*.texinfo' or `*.texi' files.
- 
-    Likewise, if your program uses small GNU software packages like
- regex, getopt, obstack, or termcap, include them in the distribution
- file.  Leaving them out would make the distribution file a little
- smaller at the expense of possible inconvenience to a user who doesn't
- know what other files to get.
- 
- 
- 
- Tag Table:
- Node: Top988
- Node: Preface1532
- Node: Intellectual Property2560
- Node: Reading Non-Free Code2935
- Node: Contributions4667
- Node: Design Advice6661
- Node: Compatibility7178
- Node: Using Extensions8689
- Node: ANSI C10191
- Node: Source Language11427
- Node: Program Behavior12920
- Node: Semantics13629
- Node: Libraries17779
- Node: Errors19014
- Node: User Interfaces20237
- Node: Option Table27109
- Node: Memory Usage41664
- Node: Writing C42658
- Node: Formatting43497
- Node: Comments46769
- Node: Syntactic Conventions50067
- Node: Names53005
- Node: System Portability54741
- Node: CPU Portability56517
- Node: System Functions58678
- Node: Internationalization63782
- Node: Mmap66930
- Node: Documentation67635
- Node: GNU Manuals68193
- Node: Manual Structure Details72080
- Node: NEWS File73410
- Node: Change Logs74091
- Node: Change Log Concepts74808
- Node: Style of Change Logs76576
- Node: Simple Changes78130
- Node: Conditional Changes79321
- Node: Man Pages80698
- Node: Reading other Manuals82317
- Node: Managing Releases83101
- Node: Configuration83837
- Node: Makefile Conventions90777
- Node: Makefile Basics91457
- Node: Utilities in Makefiles94626
- Node: Command Variables96762
- Node: Directory Variables99791
- Node: Standard Targets110374
- Node: Install Command Categories120874
- Node: Releases125447
- 
- End Tag Table
--- 0 ----
Index: krb5/util/autoconf/standards.info-1
diff -c krb5/util/autoconf/standards.info-1:1.1.1.1 krb5/util/autoconf/standards.info-1:removed
*** krb5/util/autoconf/standards.info-1:1.1.1.1	Mon Jun  2 17:58:35 1997
--- krb5/util/autoconf/standards.info-1	Sun Mar 16 20:22:41 2003
***************
*** 1,1150 ****
- This is Info file standards.info, produced by Makeinfo-1.55 from the
- input file standards.texi.
- 
- START-INFO-DIR-ENTRY
- * Standards: (standards).        GNU coding standards.
- END-INFO-DIR-ENTRY
- 
-    GNU Coding Standards Copyright (C) 1992, 1993, 1994 Free Software
- Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Free Software Foundation.
- 
- 
- File: standards.info,  Node: Top,  Next: Preface,  Prev: (dir),  Up: (dir)
- 
- Version
- *******
- 
-    Last updated 16 May 1995.
- 
- * Menu:
- 
- * Preface::			About the GNU Coding Standards
- * Reading Non-Free Code::	Referring to Proprietary Programs
- * Contributions::		Accepting Contributions
- * Change Logs::			Recording Changes
- * Compatibility::		Compatibility with Other Implementations
- * Makefile Conventions::	Makefile Conventions
- * Configuration::		How Configuration Should Work
- * Source Language::		Using Languages Other Than C
- * Formatting::			Formatting Your Source Code
- * Comments::			Commenting Your Work
- * Syntactic Conventions::	Clean Use of C Constructs
- * Names::			Naming Variables, Functions and Files
- * Using Extensions::		Using Non-standard Features
- * System Functions::            Portability and "standard" library functions
- * Semantics::			Program Behavior for All Programs
- * Errors::			Formatting Error Messages
- * Libraries::			Library Behavior
- * Portability::			Portability As It Applies to GNU
- * User Interfaces::		Standards for Command Line Interfaces
- * Documentation::		Documenting Programs
- * Releases::			Making Releases
- 
- 
- File: standards.info,  Node: Preface,  Next: Reading Non-Free Code,  Prev: Top,  Up: Top
- 
- About the GNU Coding Standards
- ******************************
- 
-    The GNU Coding Standards were written by Richard Stallman and other
- GNU Project volunteers.  Their purpose is to make the GNU system clean,
- consistent, and easy to install.  This document can also be read as a
- guide to write portable, robust and reliable programs.  It focuses on
- programs written in C, but many of the rules and principles are useful
- even if you write in another programming language.  The rules often
- state reasons for writing in a certain way.
- 
-    Corrections or suggestions regarding this document should be sent to
- `gnu@prep.ai.mit.edu'.  If you make a suggestion, please include a
- suggested new wording for it; our time is limited.  We prefer a context
- diff to the `standards.texi' or `make-stds.texi' files, but if you
- don't have those files, please mail your suggestion anyway.
- 
-    This release of the GNU Coding Standards was last updated 16 May
- 1995.
- 
- 
- File: standards.info,  Node: Reading Non-Free Code,  Next: Contributions,  Prev: Preface,  Up: Top
- 
- Referring to Proprietary Programs
- *********************************
- 
-    Don't in any circumstances refer to Unix source code for or during
- your work on GNU!  (Or to any other proprietary programs.)
- 
-    If you have a vague recollection of the internals of a Unix program,
- this does not absolutely mean you can't write an imitation of it, but
- do try to organize the imitation internally along different lines,
- because this is likely to make the details of the Unix version
- irrelevant and dissimilar to your results.
- 
-    For example, Unix utilities were generally optimized to minimize
- memory use; if you go for speed instead, your program will be very
- different.  You could keep the entire input file in core and scan it
- there instead of using stdio.  Use a smarter algorithm discovered more
- recently than the Unix program.  Eliminate use of temporary files.  Do
- it in one pass instead of two (we did this in the assembler).
- 
-    Or, on the contrary, emphasize simplicity instead of speed.  For some
- applications, the speed of today's computers makes simpler algorithms
- adequate.
- 
-    Or go for generality.  For example, Unix programs often have static
- tables or fixed-size strings, which make for arbitrary limits; use
- dynamic allocation instead.  Make sure your program handles NULs and
- other funny characters in the input files.  Add a programming language
- for extensibility and write part of the program in that language.
- 
-    Or turn some parts of the program into independently usable
- libraries.  Or use a simple garbage collector instead of tracking
- precisely when to free memory, or use a new GNU facility such as
- obstacks.
- 
- 
- File: standards.info,  Node: Contributions,  Next: Change Logs,  Prev: Reading Non-Free Code,  Up: Top
- 
- Accepting Contributions
- ***********************
- 
-    If someone else sends you a piece of code to add to the program you
- are working on, we need legal papers to use it--the same sort of legal
- papers we will need to get from you.  *Each* significant contributor to
- a program must sign some sort of legal papers in order for us to have
- clear title to the program.  The main author alone is not enough.
- 
-    So, before adding in any contributions from other people, tell us so
- we can arrange to get the papers.  Then wait until we tell you that we
- have received the signed papers, before you actually use the
- contribution.
- 
-    This applies both before you release the program and afterward.  If
- you receive diffs to fix a bug, and they make significant change, we
- need legal papers for it.
- 
-    You don't need papers for changes of a few lines here or there, since
- they are not significant for copyright purposes.  Also, you don't need
- papers if all you get from the suggestion is some ideas, not actual code
- which you use.  For example, if you write a different solution to the
- problem, you don't need to get papers.
- 
-    I know this is frustrating; it's frustrating for us as well.  But if
- you don't wait, you are going out on a limb--for example, what if the
- contributor's employer won't sign a disclaimer?  You might have to take
- that code out again!
- 
-    The very worst thing is if you forget to tell us about the other
- contributor.  We could be very embarrassed in court some day as a
- result.
- 
- 
- File: standards.info,  Node: Change Logs,  Next: Compatibility,  Prev: Contributions,  Up: Top
- 
- Change Logs
- ***********
- 
-    Keep a change log for each directory, describing the changes made to
- source files in that directory.  The purpose of this is so that people
- investigating bugs in the future will know about the changes that might
- have introduced the bug.  Often a new bug can be found by looking at
- what was recently changed.  More importantly, change logs can help
- eliminate conceptual inconsistencies between different parts of a
- program; they can give you a history of how the conflicting concepts
- arose.
- 
-    Use the Emacs command `M-x add-change-log-entry' to start a new
- entry in the change log.  An entry should have an asterisk, the name of
- the changed file, and then in parentheses the name of the changed
- functions, variables or whatever, followed by a colon.  Then describe
- the changes you made to that function or variable.
- 
-    Separate unrelated entries with blank lines.  When two entries
- represent parts of the same change, so that they work together, then
- don't put blank lines between them.  Then you can omit the file name
- and the asterisk when successive entries are in the same file.
- 
-    Here are some examples:
- 
-      * register.el (insert-register): Return nil.
-      (jump-to-register): Likewise.
-      
-      * sort.el (sort-subr): Return nil.
-      
-      * tex-mode.el (tex-bibtex-file, tex-file, tex-region):
-      Restart the tex shell if process is gone or stopped.
-      (tex-shell-running): New function.
-      
-      * expr.c (store_one_arg): Round size up for move_block_to_reg.
-      (expand_call): Round up when emitting USE insns.
-      * stmt.c (assign_parms): Round size up for move_block_from_reg.
- 
-    It's important to name the changed function or variable in full.
- Don't abbreviate them; don't combine them.  Subsequent maintainers will
- often search for a function name to find all the change log entries that
- pertain to it; if you abbreviate the name, they won't find it when they
- search.  For example, some people are tempted to abbreviate groups of
- function names by writing `* register.el ({insert,jump-to}-register)';
- this is not a good idea, since searching for `jump-to-register' or
- `insert-register' would not find the entry.
- 
-    There's no need to describe the full purpose of the changes or how
- they work together.  It is better to put such explanations in comments
- in the code.  That's why just "New function" is enough; there is a
- comment with the function in the source to explain what it does.
- 
-    However, sometimes it is useful to write one line to describe the
- overall purpose of a large batch of changes.
- 
-    You can think of the change log as a conceptual "undo list" which
- explains how earlier versions were different from the current version.
- People can see the current version; they don't need the change log to
- tell them what is in it.  What they want from a change log is a clear
- explanation of how the earlier version differed.
- 
-    When you change the calling sequence of a function in a simple
- fashion, and you change all the callers of the function, there is no
- need to make individual entries for all the callers.  Just write in the
- entry for the function being called, "All callers changed."
- 
-    When you change just comments or doc strings, it is enough to write
- an entry for the file, without mentioning the functions.  Write just,
- "Doc fix."  There's no need to keep a change log for documentation
- files.  This is because documentation is not susceptible to bugs that
- are hard to fix.  Documentation does not consist of parts that must
- interact in a precisely engineered fashion; to correct an error, you
- need not know the history of the erroneous passage.
- 
- 
- File: standards.info,  Node: Compatibility,  Next: Makefile Conventions,  Prev: Change Logs,  Up: Top
- 
- Compatibility with Other Implementations
- ****************************************
- 
-    With certain exceptions, utility programs and libraries for GNU
- should be upward compatible with those in Berkeley Unix, and upward
- compatible with ANSI C if ANSI C specifies their behavior, and upward
- compatible with POSIX if POSIX specifies their behavior.
- 
-    When these standards conflict, it is useful to offer compatibility
- modes for each of them.
- 
-    ANSI C and POSIX prohibit many kinds of extensions.  Feel free to
- make the extensions anyway, and include a `--ansi' or `--compatible'
- option to turn them off.  However, if the extension has a significant
- chance of breaking any real programs or scripts, then it is not really
- upward compatible.  Try to redesign its interface.
- 
-    Many GNU programs suppress extensions that conflict with POSIX if the
- environment variable `POSIXLY_CORRECT' is defined (even if it is
- defined with a null value).  Please make your program recognize this
- variable if appropriate.
- 
-    When a feature is used only by users (not by programs or command
- files), and it is done poorly in Unix, feel free to replace it
- completely with something totally different and better.  (For example,
- vi is replaced with Emacs.)  But it is nice to offer a compatible
- feature as well.  (There is a free vi clone, so we offer it.)
- 
-    Additional useful features not in Berkeley Unix are welcome.
- Additional programs with no counterpart in Unix may be useful, but our
- first priority is usually to duplicate what Unix already has.
- 
- 
- File: standards.info,  Node: Makefile Conventions,  Next: Configuration,  Prev: Compatibility,  Up: Top
- 
- Makefile Conventions
- ********************
- 
-    This chapter describes conventions for writing the Makefiles for GNU
- programs.
- 
- * Menu:
- 
- * Makefile Basics::
- * Utilities in Makefiles::
- * Standard Targets::
- * Command Variables::
- * Directory Variables::
- 
- 
- File: standards.info,  Node: Makefile Basics,  Next: Utilities in Makefiles,  Up: Makefile Conventions
- 
- General Conventions for Makefiles
- =================================
- 
-    Every Makefile should contain this line:
- 
-      SHELL = /bin/sh
- 
- to avoid trouble on systems where the `SHELL' variable might be
- inherited from the environment.  (This is never a problem with GNU
- `make'.)
- 
-    Different `make' programs have incompatible suffix lists and
- implicit rules, and this sometimes creates confusion or misbehavior.  So
- it is a good idea to set the suffix list explicitly using only the
- suffixes you need in the particular Makefile, like this:
- 
-      .SUFFIXES:
-      .SUFFIXES: .c .o
- 
- The first line clears out the suffix list, the second introduces all
- suffixes which may be subject to implicit rules in this Makefile.
- 
-    Don't assume that `.' is in the path for command execution.  When
- you need to run programs that are a part of your package during the
- make, please make sure that it uses `./' if the program is built as
- part of the make or `$(srcdir)/' if the file is an unchanging part of
- the source code.  Without one of these prefixes, the current search
- path is used.
- 
-    The distinction between `./' and `$(srcdir)/' is important when
- using the `--srcdir' option to `configure'.  A rule of the form:
- 
-      foo.1 : foo.man sedscript
-              sed -e sedscript foo.man > foo.1
- 
- will fail when the current directory is not the source directory,
- because `foo.man' and `sedscript' are not in the current directory.
- 
-    When using GNU `make', relying on `VPATH' to find the source file
- will work in the case where there is a single dependency file, since
- the `make' automatic variable `$<' will represent the source file
- wherever it is.  (Many versions of `make' set `$<' only in implicit
- rules.)  A makefile target like
- 
-      foo.o : bar.c
-              $(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
- 
- should instead be written as
- 
-      foo.o : bar.c
-              $(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
- 
- in order to allow `VPATH' to work correctly.  When the target has
- multiple dependencies, using an explicit `$(srcdir)' is the easiest way
- to make the rule work well.  For example, the target above for `foo.1'
- is best written as:
- 
-      foo.1 : foo.man sedscript
-              sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@
- 
- 
- File: standards.info,  Node: Utilities in Makefiles,  Next: Standard Targets,  Prev: Makefile Basics,  Up: Makefile Conventions
- 
- Utilities in Makefiles
- ======================
- 
-    Write the Makefile commands (and any shell scripts, such as
- `configure') to run in `sh', not in `csh'.  Don't use any special
- features of `ksh' or `bash'.
- 
-    The `configure' script and the Makefile rules for building and
- installation should not use any utilities directly except these:
- 
-      cat cmp cp echo egrep expr grep
-      ln mkdir mv pwd rm rmdir sed test touch
- 
-    Stick to the generally supported options for these programs.  For
- example, don't use `mkdir -p', convenient as it may be, because most
- systems don't support it.
- 
-    The Makefile rules for building and installation can also use
- compilers and related programs, but should do so via `make' variables
- so that the user can substitute alternatives.  Here are some of the
- programs we mean:
- 
-      ar bison cc flex install ld lex
-      make makeinfo ranlib texi2dvi yacc
- 
-    Use the following `make' variables:
- 
-      $(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LEX)
-      $(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
- 
-    When you use `ranlib', you should make sure nothing bad happens if
- the system does not have `ranlib'.  Arrange to ignore an error from
- that command, and print a message before the command to tell the user
- that failure of the `ranlib' command does not mean a problem.
- 
-    If you use symbolic links, you should implement a fallback for
- systems that don't have symbolic links.
- 
-    It is ok to use other utilities in Makefile portions (or scripts)
- intended only for particular systems where you know those utilities to
- exist.
- 
- 
- File: standards.info,  Node: Standard Targets,  Next: Command Variables,  Prev: Utilities in Makefiles,  Up: Makefile Conventions
- 
- Standard Targets for Users
- ==========================
- 
-    All GNU programs should have the following targets in their
- Makefiles:
- 
- `all'
-      Compile the entire program.  This should be the default target.
-      This target need not rebuild any documentation files; Info files
-      should normally be included in the distribution, and DVI files
-      should be made only when explicitly asked for.
- 
- `install'
-      Compile the program and copy the executables, libraries, and so on
-      to the file names where they should reside for actual use.  If
-      there is a simple test to verify that a program is properly
-      installed, this target should run that test.
- 
-      If possible, write the `install' target rule so that it does not
-      modify anything in the directory where the program was built,
-      provided `make all' has just been done.  This is convenient for
-      building the program under one user name and installing it under
-      another.
- 
-      The commands should create all the directories in which files are
-      to be installed, if they don't already exist.  This includes the
-      directories specified as the values of the variables `prefix' and
-      `exec_prefix', as well as all subdirectories that are needed.  One
-      way to do this is by means of an `installdirs' target as described
-      below.
- 
-      Use `-' before any command for installing a man page, so that
-      `make' will ignore any errors.  This is in case there are systems
-      that don't have the Unix man page documentation system installed.
- 
-      The way to install Info files is to copy them into `$(infodir)'
-      with `$(INSTALL_DATA)' (*note Command Variables::.), and then run
-      the `install-info' program if it is present.  `install-info' is a
-      script that edits the Info `dir' file to add or update the menu
-      entry for the given Info file; it will be part of the Texinfo
-      package.  Here is a sample rule to install an Info file:
- 
-           $(infodir)/foo.info: foo.info
-           # There may be a newer info file in . than in srcdir.
-                   -if test -f foo.info; then d=.; \
-                    else d=$(srcdir); fi; \
-                   $(INSTALL_DATA) $$d/foo.info $@; \
-           # Run install-info only if it exists.
-           # Use `if' instead of just prepending `-' to the
-           # line so we notice real errors from install-info.
-           # We use `$(SHELL) -c' because some shells do not
-           # fail gracefully when there is an unknown command.
-                   if $(SHELL) -c 'install-info --version' \
-                      >/dev/null 2>&1; then \
-                     install-info --infodir=$(infodir) $$d/foo.info; \
-                   else true; fi
- 
- `uninstall'
-      Delete all the installed files that the `install' target would
-      create (but not the noninstalled files such as `make all' would
-      create).
- 
-      This rule should not modify the directories where compilation is
-      done, only the directories where files are installed.
- 
- `clean'
-      Delete all files from the current directory that are normally
-      created by building the program.  Don't delete the files that
-      record the configuration.  Also preserve files that could be made
-      by building, but normally aren't because the distribution comes
-      with them.
- 
-      Delete `.dvi' files here if they are not part of the distribution.
- 
- `distclean'
-      Delete all files from the current directory that are created by
-      configuring or building the program.  If you have unpacked the
-      source and built the program without creating any other files,
-      `make distclean' should leave only the files that were in the
-      distribution.
- 
- `mostlyclean'
-      Like `clean', but may refrain from deleting a few files that people
-      normally don't want to recompile.  For example, the `mostlyclean'
-      target for GCC does not delete `libgcc.a', because recompiling it
-      is rarely necessary and takes a lot of time.
- 
- `maintainer-clean'
-      Delete almost everything from the current directory that can be
-      reconstructed with this Makefile.  This typically includes
-      everything deleted by `distclean', plus more: C source files
-      produced by Bison, tags tables, Info files, and so on.
- 
-      The reason we say "almost everything" is that `make
-      maintainer-clean' should not delete `configure' even if
-      `configure' can be remade using a rule in the Makefile.  More
-      generally, `make maintainer-clean' should not delete anything that
-      needs to exist in order to run `configure' and then begin to build
-      the program.  This is the only exception; `maintainer-clean' should
-      delete everything else that can be rebuilt.
- 
-      The `maintainer-clean' is intended to be used by a maintainer of
-      the package, not by ordinary users.  You may need special tools to
-      reconstruct some of the files that `make maintainer-clean' deletes.
-      Since these files are normally included in the distribution, we
-      don't take care to make them easy to reconstruct.  If you find you
-      need to unpack the full distribution again, don't blame us.
- 
-      To help make users aware of this, the commands for
-      `maintainer-clean' should start with these two:
- 
-           @echo "This command is intended for maintainers to use;"
-           @echo "it deletes files that may require special tools to rebuild."
- 
- `TAGS'
-      Update a tags table for this program.
- 
- `info'
-      Generate any Info files needed.  The best way to write the rules
-      is as follows:
- 
-           info: foo.info
-           
-           foo.info: foo.texi chap1.texi chap2.texi
-                   $(MAKEINFO) $(srcdir)/foo.texi
- 
-      You must define the variable `MAKEINFO' in the Makefile.  It should
-      run the `makeinfo' program, which is part of the Texinfo
-      distribution.
- 
- `dvi'
-      Generate DVI files for all TeXinfo documentation.  For example:
- 
-           dvi: foo.dvi
-           
-           foo.dvi: foo.texi chap1.texi chap2.texi
-                   $(TEXI2DVI) $(srcdir)/foo.texi
- 
-      You must define the variable `TEXI2DVI' in the Makefile.  It should
-      run the program `texi2dvi', which is part of the Texinfo
-      distribution.  Alternatively, write just the dependencies, and
-      allow GNU Make to provide the command.
- 
- `dist'
-      Create a distribution tar file for this program.  The tar file
-      should be set up so that the file names in the tar file start with
-      a subdirectory name which is the name of the package it is a
-      distribution for.  This name can include the version number.
- 
-      For example, the distribution tar file of GCC version 1.40 unpacks
-      into a subdirectory named `gcc-1.40'.
- 
-      The easiest way to do this is to create a subdirectory
-      appropriately named, use `ln' or `cp' to install the proper files
-      in it, and then `tar' that subdirectory.
- 
-      The `dist' target should explicitly depend on all non-source files
-      that are in the distribution, to make sure they are up to date in
-      the distribution.  *Note Making Releases: (standards)Releases.
- 
- `check'
-      Perform self-tests (if any).  The user must build the program
-      before running the tests, but need not install the program; you
-      should write the self-tests so that they work when the program is
-      built but not installed.
- 
-    The following targets are suggested as conventional names, for
- programs in which they are useful.
- 
- `installcheck'
-      Perform installation tests (if any).  The user must build and
-      install the program before running the tests.  You should not
-      assume that `$(bindir)' is in the search path.
- 
- `installdirs'
-      It's useful to add a target named `installdirs' to create the
-      directories where files are installed, and their parent
-      directories.  There is a script called `mkinstalldirs' which is
-      convenient for this; find it in the Texinfo package.You can use a
-      rule like this:
- 
-           # Make sure all installation directories (e.g. $(bindir))
-           # actually exist by making them if necessary.
-           installdirs: mkinstalldirs
-                   $(srcdir)/mkinstalldirs $(bindir) $(datadir) \
-                                           $(libdir) $(infodir) \
-                                           $(mandir)
- 
-      This rule should not modify the directories where compilation is
-      done.  It should do nothing but create installation directories.
- 
- 
- File: standards.info,  Node: Command Variables,  Next: Directory Variables,  Prev: Standard Targets,  Up: Makefile Conventions
- 
- Variables for Specifying Commands
- =================================
- 
-    Makefiles should provide variables for overriding certain commands,
- options, and so on.
- 
-    In particular, you should run most utility programs via variables.
- Thus, if you use Bison, have a variable named `BISON' whose default
- value is set with `BISON = bison', and refer to it with `$(BISON)'
- whenever you need to use Bison.
- 
-    File management utilities such as `ln', `rm', `mv', and so on, need
- not be referred to through variables in this way, since users don't
- need to replace them with other programs.
- 
-    Each program-name variable should come with an options variable that
- is used to supply options to the program.  Append `FLAGS' to the
- program-name variable name to get the options variable name--for
- example, `BISONFLAGS'.  (The name `CFLAGS' is an exception to this
- rule, but we keep it because it is standard.)  Use `CPPFLAGS' in any
- compilation command that runs the preprocessor, and use `LDFLAGS' in
- any compilation command that does linking as well as in any direct use
- of `ld'.
- 
-    If there are C compiler options that *must* be used for proper
- compilation of certain files, do not include them in `CFLAGS'.  Users
- expect to be able to specify `CFLAGS' freely themselves.  Instead,
- arrange to pass the necessary options to the C compiler independently
- of `CFLAGS', by writing them explicitly in the compilation commands or
- by defining an implicit rule, like this:
- 
-      CFLAGS = -g
-      ALL_CFLAGS = -I. $(CFLAGS)
-      .c.o:
-              $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
- 
-    Do include the `-g' option in `CFLAGS', because that is not
- *required* for proper compilation.  You can consider it a default that
- is only recommended.  If the package is set up so that it is compiled
- with GCC by default, then you might as well include `-O' in the default
- value of `CFLAGS' as well.
- 
-    Put `CFLAGS' last in the compilation command, after other variables
- containing compiler options, so the user can use `CFLAGS' to override
- the others.
- 
-    Every Makefile should define the variable `INSTALL', which is the
- basic command for installing a file into the system.
- 
-    Every Makefile should also define the variables `INSTALL_PROGRAM'
- and `INSTALL_DATA'.  (The default for each of these should be
- `$(INSTALL)'.)  Then it should use those variables as the commands for
- actual installation, for executables and nonexecutables respectively.
- Use these variables as follows:
- 
-      $(INSTALL_PROGRAM) foo $(bindir)/foo
-      $(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
- 
- Always use a file name, not a directory name, as the second argument of
- the installation commands.  Use a separate command for each file to be
- installed.
- 
- 
- File: standards.info,  Node: Directory Variables,  Prev: Command Variables,  Up: Makefile Conventions
- 
- Variables for Installation Directories
- ======================================
- 
-    Installation directories should always be named by variables, so it
- is easy to install in a nonstandard place.  The standard names for these
- variables are described below.  They are based on a standard filesystem
- layout; variants of it are used in SVR4, 4.4BSD, Linux, Ultrix v4, and
- other modern operating systems.
- 
-    These two variables set the root for the installation.  All the other
- installation directories should be subdirectories of one of these two,
- and nothing should be directly installed into these two directories.
- 
- `prefix'
-      A prefix used in constructing the default values of the variables
-      listed below.  The default value of `prefix' should be `/usr/local'
-      When building the complete GNU system, the prefix will be empty and
-      `/usr' will be a symbolic link to `/'.
- 
- `exec_prefix'
-      A prefix used in constructing the default values of some of the
-      variables listed below.  The default value of `exec_prefix' should
-      be `$(prefix)'.
- 
-      Generally, `$(exec_prefix)' is used for directories that contain
-      machine-specific files (such as executables and subroutine
-      libraries), while `$(prefix)' is used directly for other
-      directories.
- 
-    Executable programs are installed in one of the following
- directories.
- 
- `bindir'
-      The directory for installing executable programs that users can
-      run.  This should normally be `/usr/local/bin', but write it as
-      `$(exec_prefix)/bin'.
- 
- `sbindir'
-      The directory for installing executable programs that can be run
-      from the shell, but are only generally useful to system
-      administrators.  This should normally be `/usr/local/sbin', but
-      write it as `$(exec_prefix)/sbin'.
- 
- `libexecdir'
-      The directory for installing executable programs to be run by other
-      programs rather than by users.  This directory should normally be
-      `/usr/local/libexec', but write it as `$(exec_prefix)/libexec'.
- 
-    Data files used by the program during its execution are divided into
- categories in two ways.
- 
-    * Some files are normally modified by programs; others are never
-      normally modified (though users may edit some of these).
- 
-    * Some files are architecture-independent and can be shared by all
-      machines at a site; some are architecture-dependent and can be
-      shared only by machines of the same kind and operating system;
-      others may never be shared between two machines.
- 
-    This makes for six different possibilities.  However, we want to
- discourage the use of architecture-dependent files, aside from of object
- files and libraries.  It is much cleaner to make other data files
- architecture-independent, and it is generally not hard.
- 
-    Therefore, here are the variables makefiles should use to specify
- directories:
- 
- `datadir'
-      The directory for installing read-only architecture independent
-      data files.  This should normally be `/usr/local/share', but write
-      it as `$(prefix)/share'.  As a special exception, see `$(infodir)'
-      and `$(includedir)' below.
- 
- `sysconfdir'
-      The directory for installing read-only data files that pertain to a
-      single machine-that is to say, files for configuring a host.
-      Mailer and network configuration files, `/etc/passwd', and so
-      forth belong here.  All the files in this directory should be
-      ordinary ASCII text files.  This directory should normally be
-      `/usr/local/etc', but write it as `$(prefix)/etc'.
- 
-      Do not install executables in this directory (they probably belong
-      in `$(libexecdir)' or `$(sbindir))'.  Also do not install files
-      that are modified in the normal course of their use (programs
-      whose purpose is to change the configuration of the system
-      excluded).  Those probably belong in `$(localstatedir)'.
- 
- `sharedstatedir'
-      The directory for installing architecture-independent data files
-      which the programs modify while they run.  This should normally be
-      `/usr/local/com', but write it as `$(prefix)/com'.
- 
- `localstatedir'
-      The directory for installing data files which the programs modify
-      while they run, and that pertain to one specific machine.  Users
-      should never need to modify files in this directory to configure
-      the package's operation; put such configuration information in
-      separate files that go in `datadir' or `$(sysconfdir)'.
-      `$(localstatedir)' should normally be `/usr/local/var', but write
-      it as `$(prefix)/var'.
- 
- `libdir'
-      The directory for object files and libraries of object code.  Do
-      not install executables here, they probably belong in
-      `$(libexecdir)' instead.  The value of `libdir' should normally be
-      `/usr/local/lib', but write it as `$(exec_prefix)/lib'.
- 
- `infodir'
-      The directory for installing the Info files for this package.  By
-      default, it should be `/usr/local/info', but it should be written
-      as `$(prefix)/info'.
- 
- `includedir'
-      The directory for installing header files to be included by user
-      programs with the C `#include' preprocessor directive.  This
-      should normally be `/usr/local/include', but write it as
-      `$(prefix)/include'.
- 
-      Most compilers other than GCC do not look for header files in
-      `/usr/local/include'.  So installing the header files this way is
-      only useful with GCC.  Sometimes this is not a problem because some
-      libraries are only really intended to work with GCC.  But some
-      libraries are intended to work with other compilers.  They should
-      install their header files in two places, one specified by
-      `includedir' and one specified by `oldincludedir'.
- 
- `oldincludedir'
-      The directory for installing `#include' header files for use with
-      compilers other than GCC.  This should normally be `/usr/include'.
- 
-      The Makefile commands should check whether the value of
-      `oldincludedir' is empty.  If it is, they should not try to use
-      it; they should cancel the second installation of the header files.
- 
-      A package should not replace an existing header in this directory
-      unless the header came from the same package.  Thus, if your Foo
-      package provides a header file `foo.h', then it should install the
-      header file in the `oldincludedir' directory if either (1) there
-      is no `foo.h' there or (2) the `foo.h' that exists came from the
-      Foo package.
- 
-      To tell whether `foo.h' came from the Foo package, put a magic
-      string in the file--part of a comment--and grep for that string.
- 
-    Unix-style man pages are installed in one of the following:
- 
- `mandir'
-      The directory for installing the man pages (if any) for this
-      package.  It should include the suffix for the proper section of
-      the manual--usually `1' for a utility.  It will normally be
-      `/usr/local/man/man1', but you should write it as
-      `$(prefix)/man/man1'.
- 
- `man1dir'
-      The directory for installing section 1 man pages.
- 
- `man2dir'
-      The directory for installing section 2 man pages.
- 
- `...'
-      Use these names instead of `mandir' if the package needs to
-      install man pages in more than one section of the manual.
- 
-      *Don't make the primary documentation for any GNU software be a
-      man page.  Write a manual in Texinfo instead.  Man pages are just
-      for the sake of people running GNU software on Unix, which is a
-      secondary application only.*
- 
- `manext'
-      The file name extension for the installed man page.  This should
-      contain a period followed by the appropriate digit; it should
-      normally be `.1'.
- 
- `man1ext'
-      The file name extension for installed section 1 man pages.
- 
- `man2ext'
-      The file name extension for installed section 2 man pages.
- 
- `...'
-      Use these names instead of `manext' if the package needs to
-      install man pages in more than one section of the manual.
- 
-    And finally, you should set the following variable:
- 
- `srcdir'
-      The directory for the sources being compiled.  The value of this
-      variable is normally inserted by the `configure' shell script.
- 
-    For example:
- 
-      # Common prefix for installation directories.
-      # NOTE: This directory must exist when you start the install.
-      prefix = /usr/local
-      exec_prefix = $(prefix)
-      # Where to put the executable for the command `gcc'.
-      bindir = $(exec_prefix)/bin
-      # Where to put the directories used by the compiler.
-      libexecdir = $(exec_prefix)/libexec
-      # Where to put the Info files.
-      infodir = $(prefix)/info
- 
-    If your program installs a large number of files into one of the
- standard user-specified directories, it might be useful to group them
- into a subdirectory particular to that program.  If you do this, you
- should write the `install' rule to create these subdirectories.
- 
-    Do not expect the user to include the subdirectory name in the value
- of any of the variables listed above.  The idea of having a uniform set
- of variable names for installation directories is to enable the user to
- specify the exact same values for several different GNU packages.  In
- order for this to be useful, all the packages must be designed so that
- they will work sensibly when the user does so.
- 
- 
- File: standards.info,  Node: Configuration,  Next: Source Language,  Prev: Makefile Conventions,  Up: Top
- 
- How Configuration Should Work
- *****************************
- 
-    Each GNU distribution should come with a shell script named
- `configure'.  This script is given arguments which describe the kind of
- machine and system you want to compile the program for.
- 
-    The `configure' script must record the configuration options so that
- they affect compilation.
- 
-    One way to do this is to make a link from a standard name such as
- `config.h' to the proper configuration file for the chosen system.  If
- you use this technique, the distribution should *not* contain a file
- named `config.h'.  This is so that people won't be able to build the
- program without configuring it first.
- 
-    Another thing that `configure' can do is to edit the Makefile.  If
- you do this, the distribution should *not* contain a file named
- `Makefile'.  Instead, include a file `Makefile.in' which contains the
- input used for editing.  Once again, this is so that people won't be
- able to build the program without configuring it first.
- 
-    If `configure' does write the `Makefile', then `Makefile' should
- have a target named `Makefile' which causes `configure' to be rerun,
- setting up the same configuration that was set up last time.  The files
- that `configure' reads should be listed as dependencies of `Makefile'.
- 
-    All the files which are output from the `configure' script should
- have comments at the beginning explaining that they were generated
- automatically using `configure'.  This is so that users won't think of
- trying to edit them by hand.
- 
-    The `configure' script should write a file named `config.status'
- which describes which configuration options were specified when the
- program was last configured.  This file should be a shell script which,
- if run, will recreate the same configuration.
- 
-    The `configure' script should accept an option of the form
- `--srcdir=DIRNAME' to specify the directory where sources are found (if
- it is not the current directory).  This makes it possible to build the
- program in a separate directory, so that the actual source directory is
- not modified.
- 
-    If the user does not specify `--srcdir', then `configure' should
- check both `.' and `..' to see if it can find the sources.  If it finds
- the sources in one of these places, it should use them from there.
- Otherwise, it should report that it cannot find the sources, and should
- exit with nonzero status.
- 
-    Usually the easy way to support `--srcdir' is by editing a
- definition of `VPATH' into the Makefile.  Some rules may need to refer
- explicitly to the specified source directory.  To make this possible,
- `configure' can add to the Makefile a variable named `srcdir' whose
- value is precisely the specified directory.
- 
-    The `configure' script should also take an argument which specifies
- the type of system to build the program for.  This argument should look
- like this:
- 
-      CPU-COMPANY-SYSTEM
- 
-    For example, a Sun 3 might be `m68k-sun-sunos4.1'.
- 
-    The `configure' script needs to be able to decode all plausible
- alternatives for how to describe a machine.  Thus, `sun3-sunos4.1'
- would be a valid alias.  For many programs, `vax-dec-ultrix' would be
- an alias for `vax-dec-bsd', simply because the differences between
- Ultrix and BSD are rarely noticeable, but a few programs might need to
- distinguish them.
- 
-    There is a shell script called `config.sub' that you can use as a
- subroutine to validate system types and canonicalize aliases.
- 
-    Other options are permitted to specify in more detail the software
- or hardware present on the machine, and include or exclude optional
- parts of the package:
- 
- `--enable-FEATURE[=PARAMETER]'
-      Configure the package to build and install an optional user-level
-      facility called FEATURE.  This allows users to choose which
-      optional features to include.  Giving an optional PARAMETER of
-      `no' should omit FEATURE, if it is built by default.
- 
-      No `--enable' option should *ever* cause one feature to replace
-      another.  No `--enable' option should ever substitute one useful
-      behavior for another useful behavior.  The only proper use for
-      `--enable' is for questions of whether to build part of the program
-      or exclude it.
- 
- `--with-PACKAGE'
-      The package PACKAGE will be installed, so configure this package
-      to work with PACKAGE.
- 
-      Possible values of PACKAGE include `x', `x-toolkit', `gnu-as' (or
-      `gas'), `gnu-ld', `gnu-libc', and `gdb'.
- 
-      Do not use a `--with' option to specify the file name to use to
-      find certain files.  That is outside the scope of what `--with'
-      options are for.
- 
- `--nfp'
-      The target machine has no floating point processor.
- 
- `--gas'
-      The target machine assembler is GAS, the GNU assembler.  This is
-      obsolete; users should use `--with-gnu-as' instead.
- 
- `--x'
-      The target machine has the X Window System installed.  This is
-      obsolete; users should use `--with-x' instead.
- 
-    All `configure' scripts should accept all of these "detail" options,
- whether or not they make any difference to the particular package at
- hand.  In particular, they should accept any option that starts with
- `--with-' or `--enable-'.  This is so users will be able to configure
- an entire GNU source tree at once with a single set of options.
- 
-    You will note that the categories `--with-' and `--enable-' are
- narrow: they *do not* provide a place for any sort of option you might
- think of.  That is deliberate.  We want to limit the possible
- configuration options in GNU software.  We do not want GNU programs to
- have idiosyncratic configuration options.
- 
-    Packages that perform part of compilation may support
- cross-compilation.  In such a case, the host and target machines for
- the program may be different.  The `configure' script should normally
- treat the specified type of system as both the host and the target,
- thus producing a program which works for the same type of machine that
- it runs on.
- 
-    The way to build a cross-compiler, cross-assembler, or what have
- you, is to specify the option `--host=HOSTTYPE' when running
- `configure'.  This specifies the host system without changing the type
- of target system.  The syntax for HOSTTYPE is the same as described
- above.
- 
-    Bootstrapping a cross-compiler requires compiling it on a machine
- other than the host it will run on.  Compilation packages accept a
- configuration option `--build=HOSTTYPE' for specifying the
- configuration on which you will compile them, in case that is different
- from the host.
- 
-    Programs for which cross-operation is not meaningful need not accept
- the `--host' option, because configuring an entire operating system for
- cross-operation is not a meaningful thing.
- 
-    Some programs have ways of configuring themselves automatically.  If
- your program is set up to do this, your `configure' script can simply
- ignore most of its arguments.
- 
- 
- File: standards.info,  Node: Source Language,  Next: Formatting,  Prev: Configuration,  Up: Top
- 
- Using Languages Other Than C
- ****************************
- 
-    Using a language other than C is like using a non-standard feature:
- it will cause trouble for users.  Even if GCC supports the other
- language, users may find it inconvenient to have to install the
- compiler for that other language in order to build your program.  So
- please write in C.
- 
-    There are three exceptions for this rule:
- 
-    * It is okay to use a special language if the same program contains
-      an interpreter for that language.
- 
-      Thus, it is not a problem that GNU Emacs contains code written in
-      Emacs Lisp, because it comes with a Lisp interpreter.
- 
-    * It is okay to use another language in a tool specifically intended
-      for use with that language.
- 
-      This is okay because the only people who want to build the tool
-      will be those who have installed the other language anyway.
- 
-    * If an application is not of extremely widespread interest, then
-      perhaps it's not important if the application is inconvenient to
-      install.
- 
- 
- File: standards.info,  Node: Formatting,  Next: Comments,  Prev: Source Language,  Up: Top
- 
- Formatting Your Source Code
- ***************************
- 
-    It is important to put the open-brace that starts the body of a C
- function in column zero, and avoid putting any other open-brace or
- open-parenthesis or open-bracket in column zero.  Several tools look
- for open-braces in column zero to find the beginnings of C functions.
- These tools will not work on code not formatted that way.
- 
-    It is also important for function definitions to start the name of
- the function in column zero.  This helps people to search for function
- definitions, and may also help certain tools recognize them.  Thus, the
- proper format is this:
- 
-      static char *
-      concat (s1, s2)        /* Name starts in column zero here */
-           char *s1, *s2;
-      {                     /* Open brace in column zero here */
-        ...
-      }
- 
- or, if you want to use ANSI C, format the definition like this:
- 
-      static char *
-      concat (char *s1, char *s2)
-      {
-        ...
-      }
- 
-    In ANSI C, if the arguments don't fit nicely on one line, split it
- like this:
- 
-      int
-      lots_of_args (int an_integer, long a_long, short a_short,
-                    double a_double, float a_float)
-      ...
- 
-    For the body of the function, we prefer code formatted like this:
- 
-      if (x < foo (y, z))
-        haha = bar[4] + 5;
-      else
-        {
-          while (z)
-            {
-              haha += foo (z, z);
-              z--;
-            }
-          return ++x + bar ();
-        }
- 
-    We find it easier to read a program when it has spaces before the
- open-parentheses and after the commas.  Especially after the commas.
- 
-    When you split an expression into multiple lines, split it before an
- operator, not after one.  Here is the right way:
- 
-      if (foo_this_is_long && bar > win (x, y, z)
-          && remaining_condition)
- 
-    Try to avoid having two operators of different precedence at the same
- level of indentation.  For example, don't write this:
- 
-      mode = (inmode[j] == VOIDmode
-              || GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])
-              ? outmode[j] : inmode[j]);
- 
-    Instead, use extra parentheses so that the indentation shows the
- nesting:
- 
-      mode = ((inmode[j] == VOIDmode
-               || (GET_MODE_SIZE (outmode[j]) > GET_MODE_SIZE (inmode[j])))
-              ? outmode[j] : inmode[j]);
- 
-    Insert extra parentheses so that Emacs will indent the code properly.
- For example, the following indentation looks nice if you do it by hand,
- but Emacs would mess it up:
- 
-      v = rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
-          + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000;
- 
-    But adding a set of parentheses solves the problem:
- 
-      v = (rup->ru_utime.tv_sec*1000 + rup->ru_utime.tv_usec/1000
-           + rup->ru_stime.tv_sec*1000 + rup->ru_stime.tv_usec/1000);
- 
-    Format do-while statements like this:
- 
-      do
-        {
-          a = foo (a);
-        }
-      while (a > 0);
- 
-    Please use formfeed characters (control-L) to divide the program into
- pages at logical places (but not within a function).  It does not matter
- just how long the pages are, since they do not have to fit on a printed
- page.  The formfeeds should appear alone on lines by themselves.
- 
--- 0 ----
Index: krb5/util/autoconf/standards.info-2
diff -c krb5/util/autoconf/standards.info-2:1.1.1.1 krb5/util/autoconf/standards.info-2:removed
*** krb5/util/autoconf/standards.info-2:1.1.1.1	Mon Jun  2 17:58:35 1997
--- krb5/util/autoconf/standards.info-2	Sun Mar 16 20:22:41 2003
***************
*** 1,1845 ****
- This is Info file standards.info, produced by Makeinfo-1.55 from the
- input file standards.texi.
- 
- START-INFO-DIR-ENTRY
- * Standards: (standards).        GNU coding standards.
- END-INFO-DIR-ENTRY
- 
-    GNU Coding Standards Copyright (C) 1992, 1993, 1994 Free Software
- Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Free Software Foundation.
- 
- 
- File: standards.info,  Node: Comments,  Next: Syntactic Conventions,  Prev: Formatting,  Up: Top
- 
- Commenting Your Work
- ********************
- 
-    Every program should start with a comment saying briefly what it is
- for.  Example: `fmt - filter for simple filling of text'.
- 
-    Please put a comment on each function saying what the function does,
- what sorts of arguments it gets, and what the possible values of
- arguments mean and are used for.  It is not necessary to duplicate in
- words the meaning of the C argument declarations, if a C type is being
- used in its customary fashion.  If there is anything nonstandard about
- its use (such as an argument of type `char *' which is really the
- address of the second character of a string, not the first), or any
- possible values that would not work the way one would expect (such as,
- that strings containing newlines are not guaranteed to work), be sure
- to say so.
- 
-    Also explain the significance of the return value, if there is one.
- 
-    Please put two spaces after the end of a sentence in your comments,
- so that the Emacs sentence commands will work.  Also, please write
- complete sentences and capitalize the first word.  If a lower-case
- identifier comes at the beginning of a sentence, don't capitalize it!
- Changing the spelling makes it a different identifier.  If you don't
- like starting a sentence with a lower case letter, write the sentence
- differently (e.g., "The identifier lower-case is ...").
- 
-    The comment on a function is much clearer if you use the argument
- names to speak about the argument values.  The variable name itself
- should be lower case, but write it in upper case when you are speaking
- about the value rather than the variable itself.  Thus, "the inode
- number NODE_NUM" rather than "an inode".
- 
-    There is usually no purpose in restating the name of the function in
- the comment before it, because the reader can see that for himself.
- There might be an exception when the comment is so long that the
- function itself would be off the bottom of the screen.
- 
-    There should be a comment on each static variable as well, like this:
- 
-      /* Nonzero means truncate lines in the display;
-         zero means continue them.  */
-      int truncate_lines;
- 
-    Every `#endif' should have a comment, except in the case of short
- conditionals (just a few lines) that are not nested.  The comment should
- state the condition of the conditional that is ending, *including its
- sense*.  `#else' should have a comment describing the condition *and
- sense* of the code that follows.  For example:
- 
-      #ifdef foo
-        ...
-      #else /* not foo */
-        ...
-      #endif /* not foo */
- 
- but, by contrast, write the comments this way for a `#ifndef':
- 
-      #ifndef foo
-        ...
-      #else /* foo */
-        ...
-      #endif /* foo */
- 
- 
- File: standards.info,  Node: Syntactic Conventions,  Next: Names,  Prev: Comments,  Up: Top
- 
- Clean Use of C Constructs
- *************************
- 
-    Please explicitly declare all arguments to functions.  Don't omit
- them just because they are `int's.
- 
-    Declarations of external functions and functions to appear later in
- the source file should all go in one place near the beginning of the
- file (somewhere before the first function definition in the file), or
- else should go in a header file.  Don't put `extern' declarations inside
- functions.
- 
-    It used to be common practice to use the same local variables (with
- names like `tem') over and over for different values within one
- function.  Instead of doing this, it is better declare a separate local
- variable for each distinct purpose, and give it a name which is
- meaningful.  This not only makes programs easier to understand, it also
- facilitates optimization by good compilers.  You can also move the
- declaration of each local variable into the smallest scope that includes
- all its uses.  This makes the program even cleaner.
- 
-    Don't use local variables or parameters that shadow global
- identifiers.
- 
-    Don't declare multiple variables in one declaration that spans lines.
- Start a new declaration on each line, instead.  For example, instead of
- this:
- 
-      int    foo,
-             bar;
- 
- write either this:
- 
-      int foo, bar;
- 
- or this:
- 
-      int foo;
-      int bar;
- 
- (If they are global variables, each should have a comment preceding it
- anyway.)
- 
-    When you have an `if'-`else' statement nested in another `if'
- statement, always put braces around the `if'-`else'.  Thus, never write
- like this:
- 
-      if (foo)
-        if (bar)
-          win ();
-        else
-          lose ();
- 
- always like this:
- 
-      if (foo)
-        {
-          if (bar)
-            win ();
-          else
-            lose ();
-        }
- 
-    If you have an `if' statement nested inside of an `else' statement,
- either write `else if' on one line, like this,
- 
-      if (foo)
-        ...
-      else if (bar)
-        ...
- 
- with its `then'-part indented like the preceding `then'-part, or write
- the nested `if' within braces like this:
- 
-      if (foo)
-        ...
-      else
-        {
-          if (bar)
-            ...
-        }
- 
-    Don't declare both a structure tag and variables or typedefs in the
- same declaration.  Instead, declare the structure tag separately and
- then use it to declare the variables or typedefs.
- 
-    Try to avoid assignments inside `if'-conditions.  For example, don't
- write this:
- 
-      if ((foo = (char *) malloc (sizeof *foo)) == 0)
-        fatal ("virtual memory exhausted");
- 
- instead, write this:
- 
-      foo = (char *) malloc (sizeof *foo);
-      if (foo == 0)
-        fatal ("virtual memory exhausted");
- 
-    Don't make the program ugly to placate `lint'.  Please don't insert
- any casts to `void'.  Zero without a cast is perfectly fine as a null
- pointer constant.
- 
- 
- File: standards.info,  Node: Names,  Next: Using Extensions,  Prev: Syntactic Conventions,  Up: Top
- 
- Naming Variables, Functions, and Files
- **************************************
- 
-    Please use underscores to separate words in a name, so that the Emacs
- word commands can be useful within them.  Stick to lower case; reserve
- upper case for macros and `enum' constants, and for name-prefixes that
- follow a uniform convention.
- 
-    For example, you should use names like `ignore_space_change_flag';
- don't use names like `iCantReadThis'.
- 
-    Variables that indicate whether command-line options have been
- specified should be named after the meaning of the option, not after
- the option-letter.  A comment should state both the exact meaning of
- the option and its letter.  For example,
- 
-      /* Ignore changes in horizontal whitespace (-b).  */
-      int ignore_space_change_flag;
- 
-    When you want to define names with constant integer values, use
- `enum' rather than `#define'.  GDB knows about enumeration constants.
- 
-    Use file names of 14 characters or less, to avoid creating gratuitous
- problems on System V.  You can use the program `doschk' to test for
- this.  `doschk' also tests for potential name conflicts if the files
- were loaded onto an MS-DOS file system--something you may or may not
- care about.
- 
-    In general, use `-' to separate words in file names, not `_'.  Make
- all letters in file names be lower case, except when following specific
- conventions that call for upper case in certain kinds of names.
- Conventional occasions for using upper case letters in file names
- include `Makefile', `ChangeLog', `COPYING' and `README'.  It is common
- to name other `README'-like documentation files in all upper case just
- like `README'.
- 
- 
- File: standards.info,  Node: Using Extensions,  Next: System Functions,  Prev: Names,  Up: Top
- 
- Using Non-standard Features
- ***************************
- 
-    Many GNU facilities that already exist support a number of convenient
- extensions over the comparable Unix facilities.  Whether to use these
- extensions in implementing your program is a difficult question.
- 
-    On the one hand, using the extensions can make a cleaner program.
- On the other hand, people will not be able to build the program unless
- the other GNU tools are available.  This might cause the program to
- work on fewer kinds of machines.
- 
-    With some extensions, it might be easy to provide both alternatives.
- For example, you can define functions with a "keyword" `INLINE' and
- define that as a macro to expand into either `inline' or nothing,
- depending on the compiler.
- 
-    In general, perhaps it is best not to use the extensions if you can
- straightforwardly do without them, but to use the extensions if they
- are a big improvement.
- 
-    An exception to this rule are the large, established programs (such
- as Emacs) which run on a great variety of systems.  Such programs would
- be broken by use of GNU extensions.
- 
-    Another exception is for programs that are used as part of
- compilation: anything that must be compiled with other compilers in
- order to bootstrap the GNU compilation facilities.  If these require
- the GNU compiler, then no one can compile them without having them
- installed already.  That would be no good.
- 
-    Since most computer systems do not yet implement ANSI C, using the
- ANSI C features is effectively using a GNU extension, so the same
- considerations apply.  (Except for ANSI features that we discourage,
- such as trigraphs--don't ever use them.)
- 
- 
- File: standards.info,  Node: System Functions,  Next: Semantics,  Prev: Using Extensions,  Up: Top
- 
- Calling System Functions
- ************************
- 
-    C implementations differ substantially.  ANSI C reduces but does not
- eliminate the incompatibilities; meanwhile, many users wish to compile
- GNU software with pre-ANSI compilers.  This chapter gives
- recommendations for how to use the more or less standard C library
- functions to avoid unnecessary loss of portability.
- 
-    * Don't use the value of `sprintf'.  It returns the number of
-      characters written on some systems, but not on all systems.
- 
-    * Don't declare system functions explicitly.
- 
-      Almost any declaration for a system function is wrong on some
-      system.  To minimize conflicts, leave it to the system header
-      files to declare system functions.  If the headers don't declare a
-      function, let it remain undeclared.
- 
-      While it may seem unclean to use a function without declaring it,
-      in practice this works fine for most system library functions on
-      the systems where this really happens.  The problem is only
-      theoretical.  By contrast, actual declarations have frequently
-      caused actual conflicts.
- 
-    * If you must declare a system function, don't specify the argument
-      types.  Use an old-style declaration, not an ANSI prototype.  The
-      more you specify about the function, the more likely a conflict.
- 
-    * In particular, don't unconditionally declare `malloc' or `realloc'.
- 
-      Most GNU programs use those functions just once, in functions
-      conventionally named `xmalloc' and `xrealloc'.  These functions
-      call `malloc' and `realloc', respectively, and check the results.
- 
-      Because `xmalloc' and `xrealloc' are defined in your program, you
-      can declare them in other files without any risk of type conflict.
- 
-      On most systems, `int' is the same length as a pointer; thus, the
-      calls to `malloc' and `realloc' work fine.  For the few
-      exceptional systems (mostly 64-bit machines), you can use
-      *conditionalized* declarations of `malloc' and `realloc'--or put
-      these declarations in configuration files specific to those
-      systems.
- 
-    * The string functions require special treatment.  Some Unix systems
-      have a header file `string.h'; other have `strings.h'.  Neither
-      file name is portable.  There are two things you can do: use
-      Autoconf to figure out which file to include, or don't include
-      either file.
- 
-    * If you don't include either strings file, you can't get
-      declarations for the string functions from the header file in the
-      usual way.
- 
-      That causes less of a problem than you might think.  The newer ANSI
-      string functions are off-limits anyway because many systems still
-      don't support them.  The string functions you can use are these:
- 
-           strcpy   strncpy   strcat   strncat
-           strlen   strcmp   strncmp
-           strchr   strrchr
- 
-      The copy and concatenate functions work fine without a declaration
-      as long as you don't use their values.  Using their values without
-      a declaration fails on systems where the width of a pointer
-      differs from the width of `int', and perhaps in other cases.  It
-      is trivial to avoid using their values, so do that.
- 
-      The compare functions and `strlen' work fine without a declaration
-      on most systems, possibly all the ones that GNU software runs on.
-      You may find it necessary to declare them *conditionally* on a few
-      systems.
- 
-      The search functions must be declared to return `char *'.  Luckily,
-      there is no variation in the data type they return.  But there is
-      variation in their names.  Some systems give these functions the
-      names `index' and `rindex'; other systems use the names `strchr'
-      and `strrchr'.  Some systems support both pairs of names, but
-      neither pair works on all systems.
- 
-      You should pick a single pair of names and use it throughout your
-      program.  (Nowadays, it is better to choose `strchr' and
-      `strrchr'.)  Declare both of those names as functions returning
-      `char *'.  On systems which don't support those names, define them
-      as macros in terms of the other pair.  For example, here is what
-      to put at the beginning of your file (or in a header) if you want
-      to use the names `strchr' and `strrchr' throughout:
- 
-           #ifndef HAVE_STRCHR
-           #define strchr index
-           #endif
-           #ifndef HAVE_STRRCHR
-           #define strrchr rindex
-           #endif
-           
-           char *strchr ();
-           char *strrchr ();
- 
-    Here we assume that `HAVE_STRCHR' and `HAVE_STRRCHR' are macros
- defined in systems where the corresponding functions exist.  One way to
- get them properly defined is to use Autoconf.
- 
- 
- File: standards.info,  Node: Semantics,  Next: Errors,  Prev: System Functions,  Up: Top
- 
- Program Behavior for All Programs
- *********************************
- 
-    Avoid arbitrary limits on the length or number of *any* data
- structure, including file names, lines, files, and symbols, by
- allocating all data structures dynamically.  In most Unix utilities,
- "long lines are silently truncated".  This is not acceptable in a GNU
- utility.
- 
-    Utilities reading files should not drop NUL characters, or any other
- nonprinting characters *including those with codes above 0177*.  The
- only sensible exceptions would be utilities specifically intended for
- interface to certain types of printers that can't handle those
- characters.
- 
-    Check every system call for an error return, unless you know you
- wish to ignore errors.  Include the system error text (from `perror' or
- equivalent) in *every* error message resulting from a failing system
- call, as well as the name of the file if any and the name of the
- utility.  Just "cannot open foo.c" or "stat failed" is not sufficient.
- 
-    Check every call to `malloc' or `realloc' to see if it returned
- zero.  Check `realloc' even if you are making the block smaller; in a
- system that rounds block sizes to a power of 2, `realloc' may get a
- different block if you ask for less space.
- 
-    In Unix, `realloc' can destroy the storage block if it returns zero.
- GNU `realloc' does not have this bug: if it fails, the original block
- is unchanged.  Feel free to assume the bug is fixed.  If you wish to
- run your program on Unix, and wish to avoid lossage in this case, you
- can use the GNU `malloc'.
- 
-    You must expect `free' to alter the contents of the block that was
- freed.  Anything you want to fetch from the block, you must fetch before
- calling `free'.
- 
-    If `malloc' fails in a noninteractive program, make that a fatal
- error.  In an interactive program (one that reads commands from the
- user), it is better to abort the command and return to the command
- reader loop.  This allows the user to kill other processes to free up
- virtual memory, and then try the command again.
- 
-    Use `getopt_long' to decode arguments, unless the argument syntax
- makes this unreasonable.
- 
-    When static storage is to be written in during program execution, use
- explicit C code to initialize it.  Reserve C initialized declarations
- for data that will not be changed.
- 
-    Try to avoid low-level interfaces to obscure Unix data structures
- (such as file directories, utmp, or the layout of kernel memory), since
- these are less likely to work compatibly.  If you need to find all the
- files in a directory, use `readdir' or some other high-level interface.
- These will be supported compatibly by GNU.
- 
-    By default, the GNU system will provide the signal handling
- functions of BSD and of POSIX.  So GNU software should be written to use
- these.
- 
-    In error checks that detect "impossible" conditions, just abort.
- There is usually no point in printing any message.  These checks
- indicate the existence of bugs.  Whoever wants to fix the bugs will have
- to read the source code and run a debugger.  So explain the problem with
- comments in the source.  The relevant data will be in variables, which
- are easy to examine with the debugger, so there is no point moving them
- elsewhere.
- 
-    Do not use a count of errors as the exit status for a program.
- *That does not work*, because exit status values are limited to 8 bits
- (0 through 255).  A single run of the program might have 256 errors; if
- you try to return 256 as the exit status, the parent process will see 0
- as the status, and it will appear that the program succeeded.
- 
- 
- File: standards.info,  Node: Errors,  Next: Libraries,  Prev: Semantics,  Up: Top
- 
- Formatting Error Messages
- *************************
- 
-    Error messages from compilers should look like this:
- 
-      SOURCE-FILE-NAME:LINENO: MESSAGE
- 
-    Error messages from other noninteractive programs should look like
- this:
- 
-      PROGRAM:SOURCE-FILE-NAME:LINENO: MESSAGE
- 
- when there is an appropriate source file, or like this:
- 
-      PROGRAM: MESSAGE
- 
- when there is no relevant source file.
- 
-    In an interactive program (one that is reading commands from a
- terminal), it is better not to include the program name in an error
- message.  The place to indicate which program is running is in the
- prompt or with the screen layout.  (When the same program runs with
- input from a source other than a terminal, it is not interactive and
- would do best to print error messages using the noninteractive style.)
- 
-    The string MESSAGE should not begin with a capital letter when it
- follows a program name and/or file name.  Also, it should not end with
- a period.
- 
-    Error messages from interactive programs, and other messages such as
- usage messages, should start with a capital letter.  But they should not
- end with a period.
- 
- 
- File: standards.info,  Node: Libraries,  Next: Portability,  Prev: Errors,  Up: Top
- 
- Library Behavior
- ****************
- 
-    Try to make library functions reentrant.  If they need to do dynamic
- storage allocation, at least try to avoid any nonreentrancy aside from
- that of `malloc' itself.
- 
-    Here are certain name conventions for libraries, to avoid name
- conflicts.
- 
-    Choose a name prefix for the library, more than two characters long.
- All external function and variable names should start with this prefix.
- In addition, there should only be one of these in any given library
- member.  This usually means putting each one in a separate source file.
- 
-    An exception can be made when two external symbols are always used
- together, so that no reasonable program could use one without the
- other; then they can both go in the same file.
- 
-    External symbols that are not documented entry points for the user
- should have names beginning with `_'.  They should also contain the
- chosen name prefix for the library, to prevent collisions with other
- libraries.  These can go in the same files with user entry points if
- you like.
- 
-    Static functions and variables can be used as you like and need not
- fit any naming convention.
- 
- 
- File: standards.info,  Node: Portability,  Next: User Interfaces,  Prev: Libraries,  Up: Top
- 
- Portability As It Applies to GNU
- ********************************
- 
-    Much of what is called "portability" in the Unix world refers to
- porting to different Unix versions.  This is a secondary consideration
- for GNU software, because its primary purpose is to run on top of one
- and only one kernel, the GNU kernel, compiled with one and only one C
- compiler, the GNU C compiler.  The amount and kinds of variation among
- GNU systems on different cpu's will be like the variation among Berkeley
- 4.3 systems on different cpu's.
- 
-    All users today run GNU software on non-GNU systems.  So supporting a
- variety of non-GNU systems is desirable; simply not paramount.  The
- easiest way to achieve portability to a reasonable range of systems is
- to use Autoconf.  It's unlikely that your program needs to know more
- information about the host machine than Autoconf can provide, simply
- because most of the programs that need such knowledge have already been
- written.
- 
-    It is difficult to be sure exactly what facilities the GNU kernel
- will provide, since it isn't finished yet.  Therefore, assume you can
- use anything in 4.3; just avoid using the format of semi-internal data
- bases (e.g., directories) when there is a higher-level alternative
- (`readdir').
- 
-    You can freely assume any reasonably standard facilities in the C
- language, libraries or kernel, because we will find it necessary to
- support these facilities in the full GNU system, whether or not we have
- already done so.  The fact that there may exist kernels or C compilers
- that lack these facilities is irrelevant as long as the GNU kernel and
- C compiler support them.
- 
-    It remains necessary to worry about differences among cpu types, such
- as the difference in byte ordering and alignment restrictions.  It's
- unlikely that 16-bit machines will ever be supported by GNU, so there
- is no point in spending any time to consider the possibility that an
- int will be less than 32 bits.
- 
-    You can assume that all pointers have the same format, regardless of
- the type they point to, and that this is really an integer.  There are
- some weird machines where this isn't true, but they aren't important;
- don't waste time catering to them.  Besides, eventually we will put
- function prototypes into all GNU programs, and that will probably make
- your program work even on weird machines.
- 
-    Since some important machines (including the 68000) are big-endian,
- it is important not to assume that the address of an `int' object is
- also the address of its least-significant byte.  Thus, don't make the
- following mistake:
- 
-      int c;
-      ...
-      while ((c = getchar()) != EOF)
-              write(file_descriptor, &c, 1);
- 
-    You can assume that it is reasonable to use a meg of memory.  Don't
- strain to reduce memory usage unless it can get to that level.  If your
- program creates complicated data structures, just make them in core and
- give a fatal error if malloc returns zero.
- 
-    If a program works by lines and could be applied to arbitrary
- user-supplied input files, it should keep only a line in memory, because
- this is not very hard and users will want to be able to operate on input
- files that are bigger than will fit in core all at once.
- 
- 
- File: standards.info,  Node: User Interfaces,  Next: Documentation,  Prev: Portability,  Up: Top
- 
- Standards for Command Line Interfaces
- *************************************
- 
-    Please don't make the behavior of a utility depend on the name used
- to invoke it.  It is useful sometimes to make a link to a utility with
- a different name, and that should not change what it does.
- 
-    Instead, use a run time option or a compilation switch or both to
- select among the alternate behaviors.
- 
-    Likewise, please don't make the behavior of the program depend on the
- type of output device it is used with.  Device independence is an
- important principle of the system's design; do not compromise it merely
- to save someone from typing an option now and then.
- 
-    If you think one behavior is most useful when the output is to a
- terminal, and another is most useful when the output is a file or a
- pipe, then it is usually best to make the default behavior the one that
- is useful with output to a terminal, and have an option for the other
- behavior.
- 
-    Compatibility requires certain programs to depend on the type of
- output device.  It would be disastrous if `ls' or `sh' did not do so in
- the way all users expect.  In some of these cases, we supplement the
- program with a preferred alternate version that does not depend on the
- output device type.  For example, we provide a `dir' program much like
- `ls' except that its default output format is always multi-column
- format.
- 
-    It is a good idea to follow the POSIX guidelines for the
- command-line options of a program.  The easiest way to do this is to use
- `getopt' to parse them.  Note that the GNU version of `getopt' will
- normally permit options anywhere among the arguments unless the special
- argument `--' is used.  This is not what POSIX specifies; it is a GNU
- extension.
- 
-    Please define long-named options that are equivalent to the
- single-letter Unix-style options.  We hope to make GNU more user
- friendly this way.  This is easy to do with the GNU function
- `getopt_long'.
- 
-    One of the advantages of long-named options is that they can be
- consistent from program to program.  For example, users should be able
- to expect the "verbose" option of any GNU program which has one, to be
- spelled precisely `--verbose'.  To achieve this uniformity, look at the
- table of common long-option names when you choose the option names for
- your program.  The table appears below.
- 
-    If you use names not already in the table, please send
- `gnu@prep.ai.mit.edu' a list of them, with their meanings, so we can
- update the table.
- 
-    It is usually a good idea for file names given as ordinary arguments
- to be input files only; any output files would be specified using
- options (preferably `-o').  Even if you allow an output file name as an
- ordinary argument for compatibility, try to provide a suitable option
- as well.  This will lead to more consistency among GNU utilities, so
- that there are fewer idiosyncracies for users to remember.
- 
-    Programs should support an option `--version' which prints the
- program's version number on standard output and exits successfully, and
- an option `--help' which prints option usage information on standard
- output and exits successfully.  These options should inhibit the normal
- function of the command; they should do nothing except print the
- requested information.
- 
- `after-date'
-      `-N' in `tar'.
- 
- `all'
-      `-a' in `du', `ls', `nm', `stty', `uname', and `unexpand'.
- 
- `all-text'
-      `-a' in `diff'.
- 
- `almost-all'
-      `-A' in `ls'.
- 
- `append'
-      `-a' in `etags', `tee', `time'; `-r' in `tar'.
- 
- `archive'
-      `-a' in `cp'.
- 
- `archive-name'
-      `-n' in `shar'.
- 
- `arglength'
-      `-l' in `m4'.
- 
- `ascii'
-      `-a' in `diff'.
- 
- `assign'
-      `-v' in Gawk.
- 
- `assume-new'
-      `-W' in Make.
- 
- `assume-old'
-      `-o' in Make.
- 
- `auto-check'
-      `-a' in `recode'.
- 
- `auto-pager'
-      `-a' in `wdiff'.
- 
- `auto-reference'
-      `-A' in `ptx'.
- 
- `avoid-wraps'
-      `-n' in `wdiff'.
- 
- `backward-search'
-      `-B' in `ctags'.
- 
- `basename'
-      `-f' in `shar'.
- 
- `batch'
-      Used in GDB.
- 
- `baud'
-      Used in GDB.
- 
- `before'
-      `-b' in `tac'.
- 
- `binary'
-      `-b' in `cpio' and `diff'.
- 
- `bits-per-code'
-      `-b' in `shar'.
- 
- `block-size'
-      Used in `cpio' and `tar'.
- 
- `blocks'
-      `-b' in `head' and `tail'.
- 
- `break-file'
-      `-b' in `ptx'.
- 
- `brief'
-      Used in various programs to make output shorter.
- 
- `bytes'
-      `-c' in `head', `split', and `tail'.
- 
- `c++'
-      `-C' in `etags'.
- 
- `catenate'
-      `-A' in `tar'.
- 
- `cd'
-      Used in various programs to specify the directory to use.
- 
- `changes'
-      `-c' in `chgrp' and `chown'.
- 
- `classify'
-      `-F' in `ls'.
- 
- `colons'
-      `-c' in `recode'.
- 
- `command'
-      `-c' in `su'; `-x' in GDB.
- 
- `compare'
-      `-d' in `tar'.
- 
- `compat'
-      Used in gawk (no corresponding single-letter option).
- 
- `compress'
-      `-Z' in `tar' and `shar'.
- 
- `concatenate'
-      `-A' in `tar'.
- 
- `confirmation'
-      `-w' in `tar'.
- 
- `context'
-      Used in `diff'.
- 
- `copyleft'
-      Used in gawk (no corresponding single-letter option).
- 
- `copyright'
-      `-C' in `ptx', `recode', and `wdiff'.  Also used in gawk (no
-      corresponding single-letter option).
- 
- `core'
-      Used in GDB.
- 
- `count'
-      `-q' in `who'.
- 
- `count-links'
-      `-l' in `du'.
- 
- `create'
-      Used in `tar' and `cpio'.
- 
- `cut-mark'
-      `-c' in `shar'.
- 
- `cxref'
-      `-x' in `ctags'.
- 
- `date'
-      `-d' in `touch'.
- 
- `debug'
-      `-d' in Make and `m4'; `-t' in Bison.
- 
- `define'
-      `-D' in `m4'.
- 
- `defines'
-      `-d' in Bison and `ctags'.
- 
- `delete'
-      `-D' in `tar'.
- 
- `dereference'
-      `-L' in `chgrp', `chown', `cpio', `du', `ls', and `tar'.
- 
- `dereference-args'
-      `-D' in `du'.
- 
- `diacritics'
-      `-d' in `recode'.
- 
- `dictionary-order'
-      `-d' in `look'.
- 
- `diff'
-      `-d' in `tar'.
- 
- `digits'
-      `-n' in `csplit'.
- 
- `directory'
-      Specify the directory to use, in various programs.  In `ls', it
-      means to show directories themselves rather than their contents.
-      In `rm' and `ln', it means to not treat links to directories
-      specially.
- 
- `discard-all'
-      `-x' in `strip'.
- 
- `discard-locals'
-      `-X' in `strip'.
- 
- `dry-run'
-      `-n' in Make.
- 
- `ed'
-      `-e' in `diff'.
- 
- `elide-empty-files'
-      `-z' in `csplit'.
- 
- `end-delete'
-      `-x' in `wdiff'.
- 
- `end-insert'
-      `-z' in `wdiff'.
- 
- `entire-new-file'
-      `-N' in `diff'.
- 
- `environment-overrides'
-      `-e' in Make.
- 
- `eof'
-      `-e' in `xargs'.
- 
- `epoch'
-      Used in GDB.
- 
- `error-limit'
-      Used in Makeinfo.
- 
- `error-output'
-      `-o' in `m4'.
- 
- `escape'
-      `-b' in `ls'.
- 
- `exclude-from'
-      `-X' in `tar'.
- 
- `exec'
-      Used in GDB.
- 
- `exit'
-      `-x' in `xargs'.
- 
- `exit-0'
-      `-e' in `unshar'.
- 
- `expand-tabs'
-      `-t' in `diff'.
- 
- `expression'
-      `-e' in `sed'.
- 
- `extern-only'
-      `-g' in `nm'.
- 
- `extract'
-      `-i' in `cpio'; `-x' in `tar'.
- 
- `faces'
-      `-f' in `finger'.
- 
- `fast'
-      `-f' in `su'.
- 
- `fatal-warnings'
-      `-E' in `m4'.
- 
- `field-separator'
-      p`-F' in Gawk.
- 
- `file'
-      `-f' in Gawk, `info', Make, `mt', and `tar'; `-n' in `sed'; `-r'
-      in `touch'.
- 
- `file-prefix'
-      `-b' in Bison.
- 
- `file-type'
-      `-F' in `ls'.
- 
- `files-from'
-      `-T' in `tar'.
- 
- `fill-column'
-      Used in Makeinfo.
- 
- `flag-truncation'
-      `-F' in `ptx'.
- 
- `fixed-output-files'
-      `-y' in Bison.
- 
- `follow'
-      `-f' in `tail'.
- 
- `footnote-style'
-      Used in Makeinfo.
- 
- `force'
-      `-f' in `cp', `ln', `mv', and `rm'.
- 
- `force-prefix'
-      `-F' in `shar'.
- 
- `format'
-      Used in `ls', `time', and `ptx'.
- 
- `freeze-state'
-      `-F' in `m4'.
- 
- `fullname'
-      Used in GDB.
- 
- `gap-size'
-      `-g' in `ptx'.
- 
- `get'
-      `-x' in `tar'.
- 
- `graphic'
-      `-i' in `ul'.
- 
- `graphics'
-      `-g' in `recode'.
- 
- `group'
-      `-g' in `install'.
- 
- `gzip'
-      `-z' in `tar' and `shar'.
- 
- `hashsize'
-      `-H' in `m4'.
- 
- `header'
-      `-h' in `objdump' and `recode'
- 
- `heading'
-      `-H' in `who'.
- 
- `help'
-      Used to ask for brief usage information.
- 
- `here-delimiter'
-      `-d' in `shar'.
- 
- `hide-control-chars'
-      `-q' in `ls'.
- 
- `idle'
-      `-u' in `who'.
- 
- `ifdef'
-      `-D' in `diff'.
- 
- `ignore'
-      `-I' in `ls'; `-x' in `recode'.
- 
- `ignore-all-space'
-      `-w' in `diff'.
- 
- `ignore-backups'
-      `-B' in `ls'.
- 
- `ignore-blank-lines'
-      `-B' in `diff'.
- 
- `ignore-case'
-      `-f' in `look' and `ptx'; `-i' in `diff' and `wdiff'.
- 
- `ignore-errors'
-      `-i' in Make.
- 
- `ignore-file'
-      `-i' in `ptx'.
- 
- `ignore-indentation'
-      `-I' in `etags'.
- 
- `ignore-init-file'
-      `-f' in Oleo.
- 
- `ignore-interrupts'
-      `-i' in `tee'.
- 
- `ignore-matching-lines'
-      `-I' in `diff'.
- 
- `ignore-space-change'
-      `-b' in `diff'.
- 
- `ignore-zeros'
-      `-i' in `tar'.
- 
- `include'
-      `-i' in `etags'; `-I' in `m4'.
- 
- `include-dir'
-      `-I' in Make.
- 
- `incremental'
-      `-G' in `tar'.
- 
- `info'
-      `-i', `-l', and `-m' in Finger.
- 
- `initial'
-      `-i' in `expand'.
- 
- `initial-tab'
-      `-T' in `diff'.
- 
- `inode'
-      `-i' in `ls'.
- 
- `interactive'
-      `-i' in `cp', `ln', `mv', `rm'; `-e' in `m4'; `-p' in `xargs';
-      `-w' in `tar'.
- 
- `intermix-type'
-      `-p' in `shar'.
- 
- `jobs'
-      `-j' in Make.
- 
- `just-print'
-      `-n' in Make.
- 
- `keep-going'
-      `-k' in Make.
- 
- `keep-files'
-      `-k' in `csplit'.
- 
- `kilobytes'
-      `-k' in `du' and `ls'.
- 
- `language'
-      `-l' in `etags'.
- 
- `less-mode'
-      `-l' in `wdiff'.
- 
- `level-for-gzip'
-      `-g' in `shar'.
- 
- `line-bytes'
-      `-C' in `split'.
- 
- `lines'
-      Used in `split', `head', and `tail'.
- 
- `link'
-      `-l' in `cpio'.
- 
- `lint'
-      Used in gawk (no corresponding single-letter option).
- 
- `list'
-      `-t' in `cpio'; `-l' in `recode'.
- 
- `list'
-      `-t' in `tar'.
- 
- `literal'
-      `-N' in `ls'.
- 
- `load-average'
-      `-l' in Make.
- 
- `login'
-      Used in `su'.
- 
- `machine'
-      No listing of which programs already use this; someone should
-      check to see if any actually do and tell `gnu@prep.ai.mit.edu'.
- 
- `macro-name'
-      `-M' in `ptx'.
- 
- `mail'
-      `-m' in `hello' and `uname'.
- 
- `make-directories'
-      `-d' in `cpio'.
- 
- `makefile'
-      `-f' in Make.
- 
- `mapped'
-      Used in GDB.
- 
- `max-args'
-      `-n' in `xargs'.
- 
- `max-chars'
-      `-n' in `xargs'.
- 
- `max-lines'
-      `-l' in `xargs'.
- 
- `max-load'
-      `-l' in Make.
- 
- `max-procs'
-      `-P' in `xargs'.
- 
- `mesg'
-      `-T' in `who'.
- 
- `message'
-      `-T' in `who'.
- 
- `minimal'
-      `-d' in `diff'.
- 
- `mixed-uuencode'
-      `-M' in `shar'.
- 
- `mode'
-      `-m' in `install', `mkdir', and `mkfifo'.
- 
- `modification-time'
-      `-m' in `tar'.
- 
- `multi-volume'
-      `-M' in `tar'.
- 
- `name-prefix'
-      `-a' in Bison.
- 
- `nesting-limit'
-      `-L' in `m4'.
- 
- `net-headers'
-      `-a' in `shar'.
- 
- `new-file'
-      `-W' in Make.
- 
- `no-builtin-rules'
-      `-r' in Make.
- 
- `no-character-count'
-      `-w' in `shar'.
- 
- `no-check-existing'
-      `-x' in `shar'.
- 
- `no-common'
-      `-3' in `wdiff'.
- 
- `no-create'
-      `-c' in `touch'.
- 
- `no-defines'
-      `-D' in `etags'.
- 
- `no-deleted'
-      `-1' in `wdiff'.
- 
- `no-dereference'
-      `-d' in `cp'.
- 
- `no-inserted'
-      `-2' in `wdiff'.
- 
- `no-keep-going'
-      `-S' in Make.
- 
- `no-lines'
-      `-l' in Bison.
- 
- `no-piping'
-      `-P' in `shar'.
- 
- `no-prof'
-      `-e' in `gprof'.
- 
- `no-regex'
-      `-R' in `etags'.
- 
- `no-sort'
-      `-p' in `nm'.
- 
- `no-split'
-      Used in Makeinfo.
- 
- `no-static'
-      `-a' in `gprof'.
- 
- `no-time'
-      `-E' in `gprof'.
- 
- `no-timestamp'
-      `-m' in `shar'.
- 
- `no-validate'
-      Used in Makeinfo.
- 
- `no-warn'
-      Used in various programs to inhibit warnings.
- 
- `node'
-      `-n' in `info'.
- 
- `nodename'
-      `-n' in `uname'.
- 
- `nonmatching'
-      `-f' in `cpio'.
- 
- `nstuff'
-      `-n' in `objdump'.
- 
- `null'
-      `-0' in `xargs'.
- 
- `number'
-      `-n' in `cat'.
- 
- `number-nonblank'
-      `-b' in `cat'.
- 
- `numeric-sort'
-      `-n' in `nm'.
- 
- `numeric-uid-gid'
-      `-n' in `cpio' and `ls'.
- 
- `nx'
-      Used in GDB.
- 
- `old-archive'
-      `-o' in `tar'.
- 
- `old-file'
-      `-o' in Make.
- 
- `one-file-system'
-      `-l' in `tar', `cp', and `du'.
- 
- `only-file'
-      `-o' in `ptx'.
- 
- `only-prof'
-      `-f' in `gprof'.
- 
- `only-time'
-      `-F' in `gprof'.
- 
- `output'
-      In various programs, specify the output file name.
- 
- `output-prefix'
-      `-o' in `shar'.
- 
- `override'
-      `-o' in `rm'.
- 
- `overwrite'
-      `-c' in `unshar'.
- 
- `owner'
-      `-o' in `install'.
- 
- `paginate'
-      `-l' in `diff'.
- 
- `paragraph-indent'
-      Used in Makeinfo.
- 
- `parents'
-      `-p' in `mkdir' and `rmdir'.
- 
- `pass-all'
-      `-p' in `ul'.
- 
- `pass-through'
-      `-p' in `cpio'.
- 
- `port'
-      `-P' in `finger'.
- 
- `portability'
-      `-c' in `cpio' and `tar'.
- 
- `posix'
-      Used in gawk (no corresponding single-letter option).
- 
- `prefix-builtins'
-      `-P' in `m4'.
- 
- `prefix'
-      `-f' in `csplit'.
- 
- `preserve'
-      Used in `tar' and `cp'.
- 
- `preserve-environment'
-      `-p' in `su'.
- 
- `preserve-modification-time'
-      `-m' in `cpio'.
- 
- `preserve-order'
-      `-s' in `tar'.
- 
- `preserve-permissions'
-      `-p' in `tar'.
- 
- `print'
-      `-l' in `diff'.
- 
- `print-chars'
-      `-L' in `cmp'.
- 
- `print-data-base'
-      `-p' in Make.
- 
- `print-directory'
-      `-w' in Make.
- 
- `print-file-name'
-      `-o' in `nm'.
- 
- `print-symdefs'
-      `-s' in `nm'.
- 
- `printer'
-      `-p' in `wdiff'.
- 
- `prompt'
-      `-p' in `ed'.
- 
- `query-user'
-      `-X' in `shar'.
- 
- `question'
-      `-q' in Make.
- 
- `quiet'
-      Used in many programs to inhibit the usual output.  *Note:* every
-      program accepting `--quiet' should accept `--silent' as a synonym.
- 
- `quiet-unshar'
-      `-Q' in `shar'
- 
- `quote-name'
-      `-Q' in `ls'.
- 
- `rcs'
-      `-n' in `diff'.
- 
- `read-full-blocks'
-      `-B' in `tar'.
- 
- `readnow'
-      Used in GDB.
- 
- `recon'
-      `-n' in Make.
- 
- `record-number'
-      `-R' in `tar'.
- 
- `recursive'
-      Used in `chgrp', `chown', `cp', `ls', `diff', and `rm'.
- 
- `reference-limit'
-      Used in Makeinfo.
- 
- `references'
-      `-r' in `ptx'.
- 
- `regex'
-      `-r' in `tac' and `etags'.
- 
- `release'
-      `-r' in `uname'.
- 
- `reload-state'
-      `-R' in `m4'.
- 
- `relocation'
-      `-r' in `objdump'.
- 
- `rename'
-      `-r' in `cpio'.
- 
- `replace'
-      `-i' in `xargs'.
- 
- `report-identical-files'
-      `-s' in `diff'.
- 
- `reset-access-time'
-      `-a' in `cpio'.
- 
- `reverse'
-      `-r' in `ls' and `nm'.
- 
- `reversed-ed'
-      `-f' in `diff'.
- 
- `right-side-defs'
-      `-R' in `ptx'.
- 
- `same-order'
-      `-s' in `tar'.
- 
- `same-permissions'
-      `-p' in `tar'.
- 
- `save'
-      `-g' in `stty'.
- 
- `se'
-      Used in GDB.
- 
- `sentence-regexp'
-      `-S' in `ptx'.
- 
- `separate-dirs'
-      `-S' in `du'.
- 
- `separator'
-      `-s' in `tac'.
- 
- `sequence'
-      Used by `recode' to chose files or pipes for sequencing passes.
- 
- `shell'
-      `-s' in `su'.
- 
- `show-all'
-      `-A' in `cat'.
- 
- `show-c-function'
-      `-p' in `diff'.
- 
- `show-ends'
-      `-E' in `cat'.
- 
- `show-function-line'
-      `-F' in `diff'.
- 
- `show-tabs'
-      `-T' in `cat'.
- 
- `silent'
-      Used in many programs to inhibit the usual output.  *Note:* every
-      program accepting `--silent' should accept `--quiet' as a synonym.
- 
- `size'
-      `-s' in `ls'.
- 
- `sort'
-      Used in `ls'.
- 
- `source'
-      Used in gawk (no corresponding single-letter option).
- 
- `sparse'
-      `-S' in `tar'.
- 
- `speed-large-files'
-      `-H' in `diff'.
- 
- `split-at'
-      `-E' in `unshar'.
- 
- `split-size-limit'
-      `-L' in `shar'.
- 
- `squeeze-blank'
-      `-s' in `cat'.
- 
- `start-delete'
-      `-w' in `wdiff'.
- 
- `start-insert'
-      `-y' in `wdiff'.
- 
- `starting-file'
-      Used in `tar' and `diff' to specify which file within a directory
-      to start processing with.
- 
- `statistics'
-      `-s' in `wdiff'.
- 
- `stdin-file-list'
-      `-S' in `shar'.
- 
- `stop'
-      `-S' in Make.
- 
- `strict'
-      `-s' in `recode'.
- 
- `strip'
-      `-s' in `install'.
- 
- `strip-all'
-      `-s' in `strip'.
- 
- `strip-debug'
-      `-S' in `strip'.
- 
- `submitter'
-      `-s' in `shar'.
- 
- `suffix'
-      `-S' in `cp', `ln', `mv'.
- 
- `suffix-format'
-      `-b' in `csplit'.
- 
- `sum'
-      `-s' in `gprof'.
- 
- `summarize'
-      `-s' in `du'.
- 
- `symbolic'
-      `-s' in `ln'.
- 
- `symbols'
-      Used in GDB and `objdump'.
- 
- `synclines'
-      `-s' in `m4'.
- 
- `sysname'
-      `-s' in `uname'.
- 
- `tabs'
-      `-t' in `expand' and `unexpand'.
- 
- `tabsize'
-      `-T' in `ls'.
- 
- `terminal'
-      `-T' in `tput' and `ul'.  `-t' in `wdiff'.
- 
- `text'
-      `-a' in `diff'.
- 
- `text-files'
-      `-T' in `shar'.
- 
- `time'
-      Used in `ls' and `touch'.
- 
- `to-stdout'
-      `-O' in `tar'.
- 
- `total'
-      `-c' in `du'.
- 
- `touch'
-      `-t' in Make, `ranlib', and `recode'.
- 
- `trace'
-      `-t' in `m4'.
- 
- `traditional'
-      `-t' in `hello'; `-G' in `ed', `m4', and `ptx'.
- 
- `tty'
-      Used in GDB.
- 
- `typedefs'
-      `-t' in `ctags'.
- 
- `typedefs-and-c++'
-      `-T' in `ctags'.
- 
- `typeset-mode'
-      `-t' in `ptx'.
- 
- `uncompress'
-      `-z' in `tar'.
- 
- `unconditional'
-      `-u' in `cpio'.
- 
- `undefine'
-      `-U' in `m4'.
- 
- `undefined-only'
-      `-u' in `nm'.
- 
- `update'
-      `-u' in `cp', `ctags', `mv', `tar'.
- 
- `usage'
-      Used in gawk (no corresponding single-letter option).
- 
- `uuencode'
-      `-B' in `shar'.
- 
- `vanilla-operation'
-      `-V' in `shar'.
- 
- `verbose'
-      Print more information about progress.  Many programs support this.
- 
- `verify'
-      `-W' in `tar'.
- 
- `version'
-      Print the version number.
- 
- `version-control'
-      `-V' in `cp', `ln', `mv'.
- 
- `vgrind'
-      `-v' in `ctags'.
- 
- `volume'
-      `-V' in `tar'.
- 
- `what-if'
-      `-W' in Make.
- 
- `whole-size-limit'
-      `-l' in `shar'.
- 
- `width'
-      `-w' in `ls' and `ptx'.
- 
- `word-regexp'
-      `-W' in `ptx'.
- 
- `writable'
-      `-T' in `who'.
- 
- `zeros'
-      `-z' in `gprof'.
- 
- 
- File: standards.info,  Node: Documentation,  Next: Releases,  Prev: User Interfaces,  Up: Top
- 
- Documenting Programs
- ********************
- 
- * Menu:
- 
- * GNU Manuals::                 Writing proper manuals.
- * Manual Structure Details::    Specific structure conventions.
- * NEWS File::                   NEWS files supplement manuals.
- * Man Pages::                   Man pages are secondary.
- * Reading other Manuals::       How far you can go in learning
-                                   from other manuals.
- 
- 
- File: standards.info,  Node: GNU Manuals,  Next: Manual Structure Details,  Up: Documentation
- 
- GNU Manuals
- ===========
- 
-    The preferred way to document part of the GNU system is to write a
- manual in the Texinfo formatting language.  See the Texinfo manual,
- either the hardcopy or the version in the Emacs Info subsystem (`C-h
- i').
- 
-    The manual should document all of the program's command-line options
- and all of its commands.  It should give examples of their use.  But
- don't organize the manual as a list of features.  Instead, organize it
- logically, by subtopics.  Address the goals that a user will have in
- mind, and explain how to accomplish them.
- 
-    In general, a GNU manual should serve both as tutorial and reference.
- It should be set up for convenient access to each topic through Info,
- and for reading straight through (appendixes aside).  A GNU manual
- should give a good introduction to a beginner reading through from the
- start, and should also provide all the details that hackers want.
- 
-    That is not as hard as it sounds at first.  Arrange each chapter as a
- logical breakdown of its topic, but order the sections, and write their
- text, so that reading the chapter straight through makes sense.  Do
- likewise when structuring the book into chapters, and when structuring a
- section into paragraphs.  The watchword is, *at each point, address the
- most fundamental and important issue raised by the preceding text.*
- 
-    If necessary, add extra chapters at the beginning of the manual which
- are purely tutorial and cover the basics of the subject.  These provide
- the framework for a beginner to understand the rest of the manual.  The
- Bison manual provides a good example of how to do this.
- 
-    Don't use Unix man pages as a model for how to write GNU
- documentation; they are a bad example to follow.
- 
-    Please do not use the term "pathname" that is used in Unix
- documentation; use "file name" (two words) instead.  We use the term
- "path" only for search paths, which are lists of file names.
- 
- 
- File: standards.info,  Node: Manual Structure Details,  Next: NEWS File,  Prev: GNU Manuals,  Up: Documentation
- 
- Manual Structure Details
- ========================
- 
-    The title page of the manual should state the version of the program
- which the manual applies to.  The Top node of the manual should also
- contain this information.  If the manual is changing more frequently
- than or independent of the program, also state a version number for the
- manual in both of these places.
- 
-    The manual should have a node named `PROGRAM Invocation' or
- `Invoking PROGRAM', where PROGRAM stands for the name of the program
- being described, as you would type it in the shell to run the program.
- This node (together with its subnodes, if any) should describe the
- program's command line arguments and how to run it (the sort of
- information people would look in a man page for).  Start with an
- `@example' containing a template for all the options and arguments that
- the program uses.
- 
-    Alternatively, put a menu item in some menu whose item name fits one
- of the above patterns.  This identifies the node which that item points
- to as the node for this purpose, regardless of the node's actual name.
- 
-    There will be automatic features for specifying a program name and
- quickly reading just this part of its manual.
- 
-    If one manual describes several programs, it should have such a node
- for each program described.
- 
- 
- File: standards.info,  Node: NEWS File,  Next: Man Pages,  Prev: Manual Structure Details,  Up: Documentation
- 
- The NEWS File
- =============
- 
-    In addition to its manual, the package should have a file named
- `NEWS' which contains a list of user-visible changes worth mentioning.
- In each new release, add items to the front of the file and identify
- the version they pertain to.  Don't discard old items; leave them in
- the file after the newer items.  This way, a user upgrading from any
- previous version can see what is new.
- 
-    If the `NEWS' file gets very long, move some of the older items into
- a file named `ONEWS' and put a note at the end referring the user to
- that file.
- 
- 
- File: standards.info,  Node: Man Pages,  Next: Reading other Manuals,  Prev: NEWS File,  Up: Documentation
- 
- Man Pages
- =========
- 
-    It is ok to supply a man page for the program as well as a Texinfo
- manual if you wish to.  But keep in mind that supporting a man page
- requires continual effort, each time the program is changed.  Any time
- you spend on the man page is time taken away from more useful things you
- could contribute.
- 
-    Thus, even if a user volunteers to donate a man page, you may find
- this gift costly to accept.  Unless you have time on your hands, it may
- be better to refuse the man page unless the same volunteer agrees to
- take full responsibility for maintaining it--so that you can wash your
- hands of it entirely.  If the volunteer ceases to do the job, then
- don't feel obliged to pick it up yourself; it may be better to withdraw
- the man page until another volunteer offers to carry on with it.
- 
-    Alternatively, if you expect the discrepancies to be small enough
- that the man page remains useful, put a prominent note near the
- beginning of the man page explaining that you don't maintain it and
- that the Texinfo manual is more authoritative, and describing how to
- access the Texinfo documentation.
- 
- 
- File: standards.info,  Node: Reading other Manuals,  Prev: Man Pages,  Up: Documentation
- 
- Reading other Manuals
- =====================
- 
-    There may be non-free books or documentation files that describe the
- program you are documenting.
- 
-    It is ok to use these documents for reference, just as the author of
- a new algebra textbook can read other books on algebra.  A large portion
- of any non-fiction book consists of facts, in this case facts about how
- a certain program works, and these facts are necessarily the same for
- everyone who writes about the subject.  But be careful not to copy your
- outline structure, wording, tables or examples from preexisting non-free
- documentation.  Copying from free documentation may be ok; please check
- with the FSF about the individual case.
- 
--- 0 ----
Index: krb5/util/autoconf/standards.info-3
diff -c krb5/util/autoconf/standards.info-3:1.1.1.1 krb5/util/autoconf/standards.info-3:removed
*** krb5/util/autoconf/standards.info-3:1.1.1.1	Mon Jun  2 17:58:35 1997
--- krb5/util/autoconf/standards.info-3	Sun Mar 16 20:22:41 2003
***************
*** 1,92 ****
- This is Info file standards.info, produced by Makeinfo-1.55 from the
- input file standards.texi.
- 
- START-INFO-DIR-ENTRY
- * Standards: (standards).        GNU coding standards.
- END-INFO-DIR-ENTRY
- 
-    GNU Coding Standards Copyright (C) 1992, 1993, 1994 Free Software
- Foundation, Inc.
- 
-    Permission is granted to make and distribute verbatim copies of this
- manual provided the copyright notice and this permission notice are
- preserved on all copies.
- 
-    Permission is granted to copy and distribute modified versions of
- this manual under the conditions for verbatim copying, provided that
- the entire resulting derived work is distributed under the terms of a
- permission notice identical to this one.
- 
-    Permission is granted to copy and distribute translations of this
- manual into another language, under the above conditions for modified
- versions, except that this permission notice may be stated in a
- translation approved by the Free Software Foundation.
- 
- 
- File: standards.info,  Node: Releases,  Prev: Documentation,  Up: Top
- 
- Making Releases
- ***************
- 
-    Package the distribution of Foo version 69.96 in a gzipped tar file
- named `foo-69.96.tar.gz'.  It should unpack into a subdirectory named
- `foo-69.96'.
- 
-    Building and installing the program should never modify any of the
- files contained in the distribution.  This means that all the files
- that form part of the program in any way must be classified into "source
- files" and "non-source files".  Source files are written by humans and
- never changed automatically; non-source files are produced from source
- files by programs under the control of the Makefile.
- 
-    Naturally, all the source files must be in the distribution.  It is
- okay to include non-source files in the distribution, provided they are
- up-to-date and machine-independent, so that building the distribution
- normally will never modify them.  We commonly include non-source files
- produced by Bison, Lex, TeX, and Makeinfo; this helps avoid unnecessary
- dependencies between our distributions, so that users can install
- whichever packages they want to install.
- 
-    Non-source files that might actually be modified by building and
- installing the program should *never* be included in the distribution.
- So if you do distribute non-source files, always make sure they are up
- to date when you make a new distribution.
- 
-    Make sure that the directory into which the distribution unpacks (as
- well as any subdirectories) are all world-writable (octal mode 777).
- This is so that old versions of `tar' which preserve the ownership and
- permissions of the files from the tar archive will be able to extract
- all the files even if the user is unprivileged.
- 
-    Make sure that all the files in the distribution are world-readable.
- 
-    Make sure that no file name in the distribution is more than 14
- characters long.  Likewise, no file created by building the program
- should have a name longer than 14 characters.  The reason for this is
- that some systems adhere to a foolish interpretation of the POSIX
- standard, and refuse to open a longer name, rather than truncating as
- they did in the past.
- 
-    Don't include any symbolic links in the distribution itself.  If the
- tar file contains symbolic links, then people cannot even unpack it on
- systems that don't support symbolic links.  Also, don't use multiple
- names for one file in different directories, because certain file
- systems cannot handle this and that prevents unpacking the distribution.
- 
-    Try to make sure that all the file names will be unique on MS-DOG.  A
- name on MS-DOG consists of up to 8 characters, optionally followed by a
- period and up to three characters.  MS-DOG will truncate extra
- characters both before and after the period.  Thus, `foobarhacker.c'
- and `foobarhacker.o' are not ambiguous; they are truncated to
- `foobarha.c' and `foobarha.o', which are distinct.
- 
-    Include in your distribution a copy of the `texinfo.tex' you used to
- test print any `*.texinfo' files.
- 
-    Likewise, if your program uses small GNU software packages like
- regex, getopt, obstack, or termcap, include them in the distribution
- file.  Leaving them out would make the distribution file a little
- smaller at the expense of possible inconvenience to a user who doesn't
- know what other files to get.
- 
- 
--- 0 ----
Index: krb5/util/autoconf/testsuite/.cvsignore
diff -c /dev/null krb5/util/autoconf/testsuite/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:41 2003
--- krb5/util/autoconf/testsuite/.cvsignore	Thu Jun  5 10:40:14 1997
***************
*** 0 ****
--- 1 ----
+ Makefile
Index: krb5/util/db2/.cvsignore
diff -c /dev/null krb5/util/db2/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:42 2003
--- krb5/util/db2/.cvsignore	Thu Jun  5 10:40:15 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/db2/CHANGELOG
diff -c krb5/util/db2/CHANGELOG:1.1.1.1 krb5/util/db2/CHANGELOG:removed
*** krb5/util/db2/CHANGELOG:1.1.1.1	Mon Jun  2 17:58:07 1997
--- krb5/util/db2/CHANGELOG	Sun Mar 16 20:22:42 2003
***************
*** 1,123 ****
- db2-alpha.0 -> db2-alpha.1
- 		This fixes a number of bugs in the alpha release.
- 		1. 64-bit functionality.  The test suite now runs on alphas.
- 		Memory leak fixed.
- 		Pairs no longer disappear when pages are exactly full.
- 		Flush meta-data correctly on sync.
- 1.86 -> db2-alpha.0
- 		This is an interim release.  We are in the process of
- 		adding logging, locking, and transaction support to all
- 		the db access methods.  This will necessitate database
- 		format changes, interface changes, and major upheaval.
- 		In the meantime, this PRELIMINARY release is to correct
- 		some known bugs in the hash pacakge.  This release uses
- 		a different page format from 1.86, so you will need to
- 		dump and reload any existing databases if you upgrade
- 		to this (and may have to do it again when 2.0 becomes
- 		available.
- 1.85 -> 1.86
- 	btree:	Fix to split code for single large record at the end of a
- 		page.
- 1.84 -> 1.85
- 	recno:	#ifdef out use of mmap, it's not portable enough.
- 
- 1.83 -> 1.84	Thu Aug 18 15:46:07 EDT 1994
- 	recno:	Rework fixed-length records so that closing and reopening
- 		the file now works.  Pad short records on input.  Never do
- 		signed comparison in recno input reading functions.
- 
- 1.82 -> 1.83	Tue Jul 26 15:33:44 EDT 1994
- 	btree:	Rework cursor deletion code yet again; bugs with
- 		deleting empty pages that only contained the cursor
- 		record.
- 
- 1.81 -> 1.82	Sat Jul 16 11:01:50 EDT 1994
- 	btree:	Fix bugs introduced by new cursor/deletion code.
- 		Replace return kbuf/dbuf with real DBT's.
- 
- 1.80 -> 1.81
- 	btree:	Fix bugs introduced by new cursor/deletion code.
- 	all:	Add #defines for Purify.
- 
- 1.79 -> 1.80	Wed Jul 13 22:41:54 EDT 1994
- 	btree	Change deletion to coalesce empty pages.  This is a major
- 		change, cursors and duplicate pages all had to be reworked.
- 		Return to a fixed stack.
- 	recno:	Affected by cursor changes.  New cursor structures should
- 		permit multiple cursors in the future.
- 
- 1.78 -> 1.79	Mon Jun 20 17:36:47 EDT 1994
- 	all:	Minor cleanups of 1.78 for porting reasons; only
- 		major change was inlining check of NULL pointer
- 		so that __fix_realloc goes away.
- 
- 1.77 -> 1.78	Thu Jun 16 19:06:43 EDT 1994
- 	all:	Move "standard" size typedef's into db.h.
- 
- 1.76 -> 1.77	Thu Jun 16 16:48:38 EDT 1994
- 	hash:	Delete __init_ routine, has special meaning to OSF 2.0.
- 
- 1.74 -> 1.76
- 	all:	Finish up the port to the Alpha.
- 
- 1.73 -> 1.74
- 	recno:	Don't put the record if rec_search fails, in rec_rdelete.
- 		Create fixed-length intermediate records past "end" of DB
- 		correctly.
- 		Realloc bug when reading in fixed records.
- 	all:	First cut at port to Alpha (64-bit architecture) using
- 		4.4BSD basic integral types typedef's.
- 		Cast allocation pointers to shut up old compilers.
- 		Rework PORT directory into OS/machine directories.
- 
- 1.72 -> 1.73
- 	btree:	If enough duplicate records were inserted and then deleted
- 		that internal pages had references to empty pages of the
- 		duplicate keys, the search function ended up on the wrong
- 		page.
- 
- 1.7  -> 1.72	12 Oct 1993
- 	hash:	Support NET/2 hash formats.
- 
- 1.7  -> 1.71	16 Sep 1993
- 	btree/recno:
- 		Fix bug in internal search routines that caused
- 		return of invalid pointers.
- 
- 1.6  -> 1.7	07 Sep 1993
- 	hash:	Fixed big key overflow bugs.
- 	test:	Portability hacks, rewrite test script, Makefile.
- 	btree/recno:
- 		Stop copying non-overflow key/data pairs.
- 	PORT:	Break PORT directory up into per architecture/OS
- 		subdirectories.
- 
- 1.5  -> 1.6	06 Jun 1993
- 	hash:	In PAIRFITS, the first comparison should look at (P)[2].
- 		The hash_realloc function was walking off the end of memory.
- 		The overflow page number was wrong when bumping splitpoint.
- 
- 1.4  -> 1.5	23 May 1993
- 	hash:	Set hash default fill factor dynamically.
- 	recno:	Fixed bug in sorted page splits.
- 		Add page size parameter support.
- 		Allow recno to specify the name of the underlying btree;
- 			used for vi recovery.
- 	btree/recno:
- 		Support 64K pages.
- 	btree/hash/recno:
- 		Provide access to an underlying file descriptor.
- 		Change sync routines to take a flag argument, recno
- 			uses this to sync out the underlying btree.
- 
- 1.3  -> 1.4	10 May 1993
- 	recno:	Delete the R_CURSORLOG flag from the recno interface.
- 		Zero-length record fix for non-mmap reads.
- 		Try and make SIZE_T_MAX test in open portable.
- 
- 1.2  -> 1.3	01 May 1993
- 	btree:	Ignore user byte-order setting when reading already
- 		existing database.  Fixes to byte-order conversions.
- 
- 1.1  -> 1.2	15 Apr 1993
- 		No bug fixes, only compatibility hacks.
--- 0 ----
Index: krb5/util/db2/obj/.cvsignore
diff -c /dev/null krb5/util/db2/obj/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:43 2003
--- krb5/util/db2/obj/.cvsignore	Tue Jul  8 15:31:38 1997
***************
*** 0 ****
--- 1 ----
+ db-config.h.in
Index: krb5/util/db2/obj/Makefile.in
diff -c krb5/util/db2/obj/Makefile.in:1.1.1.2 krb5/util/db2/obj/Makefile.in:1.3
*** krb5/util/db2/obj/Makefile.in:1.1.1.2	Fri Feb 22 16:39:10 2002
--- krb5/util/db2/obj/Makefile.in	Fri Feb 22 19:55:17 2002
***************
*** 48,53 ****
--- 48,54 ----
  	$(RANLIB) $@
  
  db.h: $(top_srcdir)/include/db.h
+ 	rm -f db.h
  	ln -s $(top_srcdir)/include/db.h .
  
  dbtest: dbtest.o $(STRERROR_OBJ) $(LIBDB)
Index: krb5/util/db2/obj/db-config.h.in
diff -c krb5/util/db2/obj/db-config.h.in:1.1.1.2 krb5/util/db2/obj/db-config.h.in:removed
*** krb5/util/db2/obj/db-config.h.in:1.1.1.2	Fri Feb 22 16:39:11 2002
--- krb5/util/db2/obj/db-config.h.in	Sun Mar 16 20:22:43 2003
***************
*** 1,43 ****
- /* obj/db-config.h.in.  Generated automatically from configure.in by autoheader.  */
- 
- /* Define to empty if the keyword does not work.  */
- #undef const
- 
- /* Define to `unsigned' if <sys/types.h> doesn't define.  */
- #undef size_t
- 
- /* Define if you have the ANSI C header files.  */
- #undef STDC_HEADERS
- 
- /* Define if your processor stores words with the most significant
-    byte first (like Motorola and SPARC, unlike Intel and VAX).  */
- #undef WORDS_BIGENDIAN
- 
- #undef ssize_t
- 
- #undef u_char
- #undef u_short
- #undef u_int
- #undef u_long
- 
- #undef int8_t
- #undef u_int8_t
- #undef int16_t
- #undef u_int16_t
- #undef int32_t
- #undef u_int32_t
- 
- /* The number of bytes in a int.  */
- #undef SIZEOF_INT
- 
- /* Define if you have the memmove function.  */
- #undef HAVE_MEMMOVE
- 
- /* Define if you have the mkstemp function.  */
- #undef HAVE_MKSTEMP
- 
- /* Define if you have the strerror function.  */
- #undef HAVE_STRERROR
- 
- /* Define if you have the <unistd.h> header file.  */
- #undef HAVE_UNISTD_H
--- 0 ----
Index: krb5/util/dyn/.cvsignore
diff -c /dev/null krb5/util/dyn/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:43 2003
--- krb5/util/dyn/.cvsignore	Thu Jun  5 10:40:17 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/dyn/configure.in
diff -c krb5/util/dyn/configure.in:1.1.1.1 krb5/util/dyn/configure.in:removed
*** krb5/util/dyn/configure.in:1.1.1.1	Mon Jun  2 17:58:47 1997
--- krb5/util/dyn/configure.in	Sun Mar 16 20:22:44 2003
***************
*** 1,14 ****
- AC_INIT(dyn.h)
- CONFIG_RULES
- AC_PROG_ARCHIVE
- AC_PROG_ARCHIVE_ADD
- AC_PROG_RANLIB
- AC_PROG_INSTALL
- AC_CHECK_FUNCS(memmove)
- V5_SHARED_LIB_OBJS
- V5_MAKE_SHARED_LIB(libdyn,1.0,../../lib, ../util/dyn)
- dnl DEPLIBS is normally set by KRB5_LIBRARIES, but that makes assumptions
- dnl which fail for libdyn.
- AC_SUBST(DEPLIBS)
- CopySrcHeader(dyn.h,[$](BUILDTOP)/include)
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/util/et/.cvsignore
diff -c /dev/null krb5/util/et/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:44 2003
--- krb5/util/et/.cvsignore	Thu Jun  5 10:40:18 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/profile/.cvsignore
diff -c /dev/null krb5/util/profile/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:44 2003
--- krb5/util/profile/.cvsignore	Thu Jun  5 10:40:20 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/profile/prof_section.c
diff -c krb5/util/profile/prof_section.c:1.1.1.1 krb5/util/profile/prof_section.c:removed
*** krb5/util/profile/prof_section.c:1.1.1.1	Mon Jun  2 17:58:55 1997
--- krb5/util/profile/prof_section.c	Sun Mar 16 20:22:44 2003
***************
*** 1,170 ****
- /*
-  * prof_section.c --- routines that manipulate the profile_section_t
-  * 	object
-  *
-  * XXX this file is still under construction.
-  */
- 
- #include <stdio.h>
- #include <string.h>
- #ifdef HAVE_STDLIB_H
- #include <stdlib.h>
- #endif
- #include <errno.h>
- 
- #include "prof_int.h"
- 
- /*
-  * This routine frees a profile_section
-  */
- void profile_free_section(sect)
- 	profile_section_t	sect;
- {
- 	if (sect->name)
- 		free(sect->name);
- 	sect->magic = 0;
- 	free(sect);
- }
- 
- /*
-  * This routine creates a profile_section from its parent.  If the
-  * parent is NULL, then a top-level profile section is created.
-  *
-  * Top-level profile sections are different from normal
-  * profile_sections in that top-level sections are agregated across
-  * multiple files, where as subsections are not.
-  */
- errcode_t profile_get_subsection(profile, parent, name, ret_name,
- 				 ret_section)
- 	profile_t		profile;
- 	profile_section_t	parent;
- 	const char *		name;
- 	char **			ret_name;
- 	profile_section_t	*ret_section;
- {
- 	profile_section_t	section;
- 	prf_file_t		file;
- 	errcode_t		retval;
- 
- 	section = malloc(sizeof(struct _profile_section_t));
- 	if (section == 0)
- 		return ENOMEM;
- 	memset(section, 0, sizeof(struct _profile_section_t));
- 	section->magic = PROF_MAGIC_SECTION;
- 	section->name = malloc(strlen(name)+1);
- 	if (section->name == 0) {
- 		free(section);
- 		return ENOMEM;
- 	}
- 	strcpy(section->name, name);
- 	section->file_ptr = file = profile->first_file;
- 	section->profile = profile;
- 
- 	if (parent == 0) {
- 		/*
- 		 * If parent is NULL, then we are creating a
- 		 * top-level section which hangs off the root.
- 		 * 
- 		 * We make sure that the section exists in least one
- 		 * file.
- 		 */
- 		section->top_lvl = 1;
- 		if (name == 0)
- 			return PROF_TOPSECTION_ITER_NOSUPP;
- 		while (file) {
- 			retval = profile_find_node_subsection(file->root,
- 				name, &section->state,
- 			        ret_name, &section->sect);
- 			file = file->next;
- 			if (retval == 0)
- 				break;
- 			if (retval == PROF_NO_SECTION)
- 				continue;
- 			profile_free_section(section);
- 			return retval;
- 		}
- 		if (section->sect == 0 && file == 0) {
- 			profile_free_section(section);
- 			return PROF_NO_SECTION;
- 		}
- 		*ret_section = section;
- 		return 0;
- 	}
- 		
- 	
- 	section->top_lvl = 0;
- 	if (parent->top_lvl) {
- 		section->top_lvl_search = 1;
- 		
- 	} else {
- 		section->top_lvl_search = 0;
- 		if (parent->sect == 0) {
- 			profile_free_section(section);
- 			return PROF_INVALID_SECTION;
- 		}
- 		section->parent = parent->sect;
- 		retval = profile_find_node_subsection(parent->sect,
- 		      name, &section->state, ret_name, &section->sect);
- 		if (retval) {
- 			profile_free_section(section);
- 			return retval;
- 		}
- 	}
- 	*ret_section = section;
- 	return 0;
- }
- 
- errcode_t profile_next_section(section, ret_name)
- 	profile_section_t	section;
- 	char			**ret_name;
- {
- 	prf_file_t	file;
- 	errcode_t	retval;
- 	
- 	if (section->top_lvl)
- 		return PROF_END_OF_SECTIONS;
- 	else {
- 		if (section->sect == 0)
- 			return PROF_INVALID_SECTION;
- 		retval = profile_find_node_subsection(section->parent,
- 		    section->name, &section->state, ret_name, &section->sect);
- 		if (retval == PROF_NO_SECTION)
- 			retval = PROF_END_OF_SECTIONS;
- 		return retval;
- 	}
- }
- 
- errcode_t profile_get_relation(section, name, ret_values)
- 	profile_section_t	section;
- 	const char 		*name;
- 	char 			***ret_values;
- {
- 	prf_file_t	file;
- 	char		**values;
- 	int		num_values;
- 	int		max_values;
- 	char		*value;
- 	errcode_t	retval;
- 	
- 
- 	max_values = 10;
- 	values = malloc(sizeof(char *) * max_values);
- 	
- 	if (section->top_lvl) {
- 		for (file = section->profile->first_file; file;
- 		     file = file->next) {
- 			retval = profile_find_node_relation(file->root,
- 			    section->name, &section->state, 0, &value);
- 			if (retval)
- 				continue;
- 			
- 		}
- 	} else {
- 		if (section->sect == 0)
- 			return PROF_INVALID_SECTION;
- 	}
- 	return 0;
- }
- 
- 	
- 	
--- 0 ----
Index: krb5/util/pty/.cvsignore
diff -c /dev/null krb5/util/pty/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:44 2003
--- krb5/util/pty/.cvsignore	Thu Jun  5 10:40:23 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/pty/configure.in
diff -c krb5/util/pty/configure.in:1.1.1.2 krb5/util/pty/configure.in:1.4
*** krb5/util/pty/configure.in:1.1.1.2	Fri Feb 22 16:39:41 2002
--- krb5/util/pty/configure.in	Mon Mar 10 15:26:27 2003
***************
*** 215,221 ****
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
--- 215,222 ----
  AC_MSG_CHECKING([setenv])
  AC_CACHE_VAL(krb5_cv_setenv,
  [AC_TRY_LINK(
! [],[setenv("PATH","/bin",0);
!     unsetenv("PATH");],
  krb5_cv_setenv=yes,krb5_cv_setenv=no)])
  AC_MSG_RESULT($krb5_cv_setenv)
  if test $krb5_cv_setenv = no; then
Index: krb5/util/send-pr/.cvsignore
diff -c /dev/null krb5/util/send-pr/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:45 2003
--- krb5/util/send-pr/.cvsignore	Thu Jun  5 10:40:23 1997
***************
*** 0 ****
--- 1 ----
+ configure
Index: krb5/util/send-pr/configure.in
diff -c krb5/util/send-pr/configure.in:1.1.1.1 krb5/util/send-pr/configure.in:removed
*** krb5/util/send-pr/configure.in:1.1.1.1	Mon Jun  2 17:58:59 1997
--- krb5/util/send-pr/configure.in	Sun Mar 16 20:22:45 2003
***************
*** 1,6 ****
- AC_INIT(configure.in)
- CONFIG_RULES
- 
- 
- 
- V5_AC_OUTPUT_MAKEFILE
--- 0 ----
Index: krb5/util/ss/.cvsignore
diff -c /dev/null krb5/util/ss/.cvsignore:1.1
*** /dev/null	Sun Mar 16 20:22:45 2003
--- krb5/util/ss/.cvsignore	Thu Jun  5 10:40:24 1997
***************
*** 0 ****
--- 1 ----
+ configure
