Incremental commit.
[utils.git] / krb5-agent.c
CommitLineData
d5996a1f
DC
1#include <stdlib.h>
2#include <stdio.h>
3#include <unistd.h>
4#include <krb5.h>
e73ae134
DC
5#include <time.h>
6#include <string.h>
7#include <signal.h>
8#include <sys/wait.h>
9
10#define STD_INTERVAL (3600 * 8)
11
12volatile int died = 0;
13pid_t child;
14int execmode = 0, failsafe = 0;
15int verbose = 0, quiet = 0;
16krb5_context context = NULL;
17krb5_ccache ccache = NULL;
18
19void cleanup_krb5(void)
20{
21 if(ccache != NULL)
22 krb5_cc_close(context, ccache);
23 if(context != NULL)
24 krb5_free_context(context);
25}
26
27void sighandler(int sig)
28{
29 switch(sig) {
30 case SIGCHLD:
31 died = 1;
32 break;
33 }
34}
35
36void renew(void)
37{
38 int ret;
39
40 if(ccache == NULL)
41 return;
42}
d5996a1f
DC
43
44int main(int argc, char **argv)
45{
e73ae134
DC
46 char *p;
47 int c;
48 time_t interval, last, now;
49 pid_t wpid;
50 int ret, status;
51
52 interval = STD_INTERVAL;
53 while((c = getopt(argc, argv, "+hi:vqf")) != -1) {
54 switch(c) {
55 case 'v':
56 verbose++;
57 break;
58 case 'q':
59 quiet = 1;
60 break;
61 case 'f':
62 failsafe = 1;
63 break;
64 case 'i':
65 p = optarg + strlen(optarg) - 1;
66 if((*p >= 'a') || (*p <= 'z')) {
67 if(*p == 'm')
68 interval = 60;
69 else if(*p == 'h')
70 interval = 3600;
71 else if(*p == 'd')
72 interval = 86400;
73 else
74 interval = 1;
75 *p = 0;
76 } else {
77 interval = 1;
78 }
79 interval *= atoi(optarg);
80 break;
81 case 'h':
82 case '?':
83 case ':':
84 default:
85 fprintf(stderr, "usage: krb5-agent [-hvqf] [-i interval] [program args...]\n");
86 exit((c == 'h')?0:1);
87 }
88 }
89
90 atexit(cleanup_krb5);
91 if((ret = krb5_init_context(&context)) != 0) {
92 if(!quiet)
93 fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret));
94 if(!failsafe)
95 exit(1);
96 }
97 if(context != NULL) {
98 if((ret = krb5_cc_default(context, &ccache)) != 0) {
99 if(!quiet)
100 fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret));
101 if(!failsafe)
102 exit(1);
103 }
104 }
105
106 if(optind < argc) {
107 execmode = 1;
108 signal(SIGCHLD, sighandler);
109 if((child = fork()) < 0) {
110 perror("fork");
111 exit(1);
112 }
113 if(child == 0) {
114 char buf[80];
115 snprintf(buf, 80, "KRB5_AGENT_PID=%i", getpid());
116 putenv(buf);
117 execvp(argv[optind], argv + optind);
118 perror(argv[optind]);
119 exit(255);
120 }
121 }
122 now = last = time(NULL);
123 while(1) {
124 if(died) {
125 wpid = waitpid(-1, &status, WNOHANG);
126 if(wpid < 0) {
127 perror("waitpid");
128 } else if(execmode && (wpid == child)) {
129 /* Try to preserve exit status as best as we can... */
130 if(WIFEXITED(status)) {
131 exit(WEXITSTATUS(status));
132 } else {
133 signal(WTERMSIG(status), SIG_DFL);
134 kill(getpid(), WTERMSIG(status));
135 exit(255);
136 }
137 }
138 died = 0;
139 }
140 sleep((last + interval) - now);
141 now = time(NULL);
142 if(now >= last + interval)
143 renew();
144 }
d5996a1f 145}
e73ae134
DC
146
147/*
148 * Local Variables:
149 * compile-command: "gcc -Wall -g -o krb5-agent krb5-agent.c -lkrb5"
150 * End:
151 */