--- /dev/null
+diff -ru ../kstart-3.10/krenew.c ./krenew.c
+--- ../kstart-3.10/krenew.c 2007-03-03 20:42:26.000000000 -0800
++++ ./krenew.c 2007-11-11 18:20:25.000000000 -0800
+@@ -33,6 +33,7 @@
+ Usage: krenew [options] [command]\n\
+ -b Fork and run in the background\n\
+ -h Display this usage message and exit\n\
++ -H <min> Only renew tickets if we don't have a happy ticket\n\
+ -K <interval> Run as daemon, renew ticket every <interval> minutes\n\
+ (implies -q unless -v is given)\n\
+ -k <file> Use <file> as the ticket cache\n\
+@@ -53,7 +54,7 @@
+ {
+ va_list args;
+
+- fprintf(stderr, "k5start: ");
++ fprintf(stderr, "krenew: ");
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+@@ -165,7 +166,8 @@
+ ** Renew the user's tickets, exiting with an error if this isn't possible.
+ */
+ static void
+-renew(krb5_context ctx, krb5_ccache cache, int verbose)
++renew(krb5_context ctx, krb5_ccache cache, int verbose, int do_aklog,
++ const char *aklog, int happy_interval)
+ {
+ int status;
+ krb5_principal user;
+@@ -175,6 +177,37 @@
+ krb5_creds in, *old = NULL;
+ #endif
+
++ if( happy_interval > 0 )
++ {
++ krb5_cc_cursor cursor;
++
++ status = krb5_cc_start_seq_get( ctx, cache, &cursor );
++ if( status != 0 )
++ krb5_err( ctx, 1, status, "krenew: error reading cache" );
++ status = krb5_cc_next_cred( ctx, cache, &cursor, &creds);
++ if( status != 0 )
++ krb5_err( ctx, 1, status, "krenew: error reading cache" );
++ status = krb5_cc_end_seq_get( ctx, cache, &cursor );
++ if( status != 0 )
++ krb5_err( ctx, 1, status, "krenew: error reading cache" );
++
++ if( time(NULL) + happy_interval * 60 < creds.times.endtime )
++ {
++ if( verbose )
++ fputs( "krenew: Happy ticket. Not renewing credentials\n",
++ stderr );
++ return;
++ }
++
++ if( time(NULL) + happy_interval * 60 >= creds.times.renew_till )
++ {
++ if( verbose )
++ fputs( "krenew: Renewing ticket will not make it happy\n",
++ stderr );
++ exit(1);
++ }
++ }
++
+ memset(&creds, 0, sizeof(creds));
+ status = krb5_cc_get_principal(ctx, cache, &user);
+ if (status != 0)
+@@ -186,10 +219,12 @@
+ if (status != 0)
+ krb5_warn(ctx, status, "krenew: error unparsing name");
+ else {
+- printf("kstart: renewing credentials for %s\n", name);
++ printf("krenew: renewing credentials for %s\n", name);
+ free(name);
+ }
+ }
++
++
+ #ifdef HAVE_KRB5_GET_RENEWED_CREDS
+ status = krb5_get_renewed_creds(ctx, &creds, user, cache, NULL);
+ out = &creds;
+@@ -228,6 +263,10 @@
+ if (out != NULL)
+ krb5_free_creds(ctx, out);
+ #endif
++
++ /* If requested, run the aklog program. */
++ if (do_aklog)
++ run_aklog(aklog, verbose);
+ }
+
+
+@@ -241,6 +280,7 @@
+ int background = 0;
+ int keep_ticket = 0;
+ int do_aklog = 0;
++ int happy_interval = 0;
+ int verbose = 0;
+ const char *aklog = NULL;
+ krb5_context ctx;
+@@ -249,7 +289,7 @@
+ pid_t child = 0;
+
+ /* Parse command-line options. */
+- while ((option = getopt(argc, argv, "bhK:k:p:qtv")) != EOF)
++ while ((option = getopt(argc, argv, "bhH:K:k:p:qtv")) != EOF)
+ switch (option) {
+ case 'b': background = 1; break;
+ case 'h': usage(0); break;
+@@ -257,6 +297,12 @@
+ case 't': do_aklog = 1; break;
+ case 'v': verbose = 1; break;
+
++ case 'H':
++ happy_interval = atoi(optarg);
++ if( happy_interval <= 0 )
++ die("Happy interval must be a positive integer");
++ break;
++
+ case 'K':
+ keep_ticket = atoi(optarg);
+ if (keep_ticket <= 0)
+@@ -283,6 +329,8 @@
+ /* Check the arguments for consistency. */
+ if (background && keep_ticket == 0 && command == NULL)
+ die("-b only makes sense with -K or a command to run");
++ if (happy_interval > 0 && (background || keep_ticket || command))
++ die("-H should only be used for one time renuals");
+
+ /* Set aklog from KINIT_PROG or the compiled-in default. */
+ aklog = getenv("KINIT_PROG");
+@@ -321,13 +369,11 @@
+ }
+ }
+
+- /* Now, do the initial ticket renewal even if it's not necessary so that
+- we can catch any problems. */
+- renew(ctx, cache, verbose);
++ /* Now, do the initial ticket renewal, if we don't have a happy ticket. If
++ the happy interval was not specified, then do it anyway, if it's not
++ necessary so that we can catch any problems. */
++ renew(ctx, cache, verbose, do_aklog, aklog, happy_interval);
+
+- /* If requested, run the aklog program. */
+- if (do_aklog)
+- run_aklog(aklog, verbose);
+
+ /* If told to background, background ourselves. We do this late so that
+ we can report initial errors. We have to do this before spawning the
+@@ -373,11 +419,8 @@
+ timeout.tv_sec = keep_ticket * 60;
+ timeout.tv_usec = 0;
+ select(0, NULL, NULL, NULL, &timeout);
+- if (ticket_expired(ctx, cache, keep_ticket)) {
+- renew(ctx, cache, verbose);
+- if (do_aklog)
+- run_aklog(aklog, verbose);
+- }
++ if (ticket_expired(ctx, cache, keep_ticket))
++ renew(ctx, cache, verbose, do_aklog, aklog, 0);
+ }
+ }
+
+diff -ru ../kstart-3.10/krenew.pod ./krenew.pod
+--- ../kstart-3.10/krenew.pod 2006-06-23 19:39:40.000000000 -0700
++++ ./krenew.pod 2007-11-11 18:15:31.000000000 -0800
+@@ -71,6 +71,12 @@
+
+ Display a usage message and exit.
+
++=item B<-H> I<minutes>
++
++Only renew the ticket if it can be renewed, and and has fewer than I<minutes>
++to expiry. Exits with status 0 if ticket is happy, or was successfully renewed
++to a happy ticket. Exits with status 1 otherwise.
++
+ =item B<-K> I<minutes>
+
+ Run in daemon mode to keep a ticket alive indefinitely. The program