Incremental commit.
authorfredrik@DOLDA2000.COM <fredrik@DOLDA2000.COM@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 4 Mar 2005 02:27:32 +0000 (02:27 +0000)
committerfredrik@DOLDA2000.COM <fredrik@DOLDA2000.COM@959494ce-11ee-0310-bf91-de5d638817bd>
Fri, 4 Mar 2005 02:27:32 +0000 (02:27 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/utils@168 959494ce-11ee-0310-bf91-de5d638817bd

krb5-agent.c

index 6cbb783..7edd369 100644 (file)
@@ -2,8 +2,150 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <krb5.h>
+#include <time.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#define STD_INTERVAL (3600 * 8)
+
+volatile int died = 0;
+pid_t child;
+int execmode = 0, failsafe = 0;
+int verbose = 0, quiet = 0;
+krb5_context context = NULL;
+krb5_ccache ccache = NULL;
+
+void cleanup_krb5(void)
+{
+    if(ccache != NULL)
+       krb5_cc_close(context, ccache);
+    if(context != NULL)
+       krb5_free_context(context);
+}
+
+void sighandler(int sig)
+{
+    switch(sig) {
+    case SIGCHLD:
+       died = 1;
+       break;
+    }
+}
+
+void renew(void)
+{
+    int ret;
+    
+    if(ccache == NULL)
+       return;
+}
 
 int main(int argc, char **argv)
 {
-    return(0);
+    char *p;
+    int c;
+    time_t interval, last, now;
+    pid_t wpid;
+    int ret, status;
+    
+    interval = STD_INTERVAL;
+    while((c = getopt(argc, argv, "+hi:vqf")) != -1) {
+       switch(c) {
+       case 'v':
+           verbose++;
+           break;
+       case 'q':
+           quiet = 1;
+           break;
+       case 'f':
+           failsafe = 1;
+           break;
+       case 'i':
+           p = optarg + strlen(optarg) - 1;
+           if((*p >= 'a') || (*p <= 'z')) {
+               if(*p == 'm')
+                   interval = 60;
+               else if(*p == 'h')
+                   interval = 3600;
+               else if(*p == 'd')
+                   interval = 86400;
+               else
+                   interval = 1;
+               *p = 0;
+           } else {
+               interval = 1;
+           }
+           interval *= atoi(optarg);
+           break;
+       case 'h':
+       case '?':
+       case ':':
+       default:
+           fprintf(stderr, "usage: krb5-agent [-hvqf] [-i interval] [program args...]\n");
+           exit((c == 'h')?0:1);
+       }
+    }
+    
+    atexit(cleanup_krb5);
+    if((ret = krb5_init_context(&context)) != 0) {
+       if(!quiet)
+           fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret));
+       if(!failsafe)
+           exit(1);
+    }
+    if(context != NULL) {
+       if((ret = krb5_cc_default(context, &ccache)) != 0) {
+           if(!quiet)
+               fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret));
+           if(!failsafe)
+               exit(1);
+       }
+    }
+    
+    if(optind < argc) {
+       execmode = 1;
+       signal(SIGCHLD, sighandler);
+       if((child = fork()) < 0) {
+           perror("fork");
+           exit(1);
+       }
+       if(child == 0) {
+           char buf[80];
+           snprintf(buf, 80, "KRB5_AGENT_PID=%i", getpid());
+           putenv(buf);
+           execvp(argv[optind], argv + optind);
+           perror(argv[optind]);
+           exit(255);
+       }
+    }
+    now = last = time(NULL);
+    while(1) {
+       if(died) {
+           wpid = waitpid(-1, &status, WNOHANG);
+           if(wpid < 0) {
+               perror("waitpid");
+           } else if(execmode && (wpid == child)) {
+               /* Try to preserve exit status as best as we can... */
+               if(WIFEXITED(status)) {
+                   exit(WEXITSTATUS(status));
+               } else {
+                   signal(WTERMSIG(status), SIG_DFL);
+                   kill(getpid(), WTERMSIG(status));
+                   exit(255);
+               }
+           }
+           died = 0;
+       }
+       sleep((last + interval) - now);
+       now = time(NULL);
+       if(now >= last + interval)
+           renew();
+    }
 }
+
+/*
+ * Local Variables:
+ * compile-command: "gcc -Wall -g -o krb5-agent krb5-agent.c -lkrb5"
+ * End:
+ */