Hourly stamp
[mirror/userdir-ldap.git] / ud-fingerserv2.c
1 /* $Id# */
2 /* compile: gcc -Wall -o ud-fingerserv2 ud-fingerserv2.c */
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <stdarg.h>
6 #include <signal.h>
7 #include <unistd.h>
8 #include <string.h>
9 #include <netinet/in.h>
10 #include <sys/time.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13
14 #define PROGNAME         "ud-fingerserv"
15 #define VERSION          "0.90"
16 #define PROGDATE         "1999/12/10"
17
18 #define FINGERPORT       79
19 #define TIMEOUT          600 /* seconds */
20 #define PERROR(ctx)      do { perror(ctx); exit(1); } while (0);
21 #define DEFAULTLOGFILE   "/var/log/ud-fingerserv.log"
22
23 #define OPT_INETD     1
24 #define OPT_LOGSCR    (1 << 1)
25
26 static FILE *g_logfs = NULL;
27 static char *g_logfn = NULL;
28 static int g_options = 0;
29
30 int processcxn(int, struct sockaddr_in *);
31 void logf(char *fmt, ...);
32 void cleanup(void);
33 void timeout(void);
34 void usage(void);
35 void sendhelp(void);
36
37 /* ********************************************************************** */
38
39 int processcxn(int s, struct sockaddr_in *rmtaddr)
40 {
41     printf("connected\n");
42     return 0;
43 }
44
45 void sendhelp(void)
46 {
47 }
48
49 void logf(char *fmt, ...)
50 {
51     va_list ap;
52     time_t t;
53     char logline[1024];
54     char *ts;
55    
56     t = time(NULL);
57     ts = ctime(&t);
58     ts[strlen(ts)-1] = 0; /* remove stupid newline */
59     
60     if (g_logfs == NULL) {
61         if (g_logfn == NULL) g_logfn = DEFAULTLOGFILE;
62         if ((g_logfs = fopen(g_logfn, "a")) == NULL && !(g_options & OPT_LOGSCR)) PERROR("logf");        
63     }   
64    
65     vsnprintf(logline, sizeof(logline), fmt, ap);
66     if (g_logfs) {
67         fprintf(g_logfs, "[%s] " PROGNAME ": %s\n", ts, logline);
68         fflush(g_logfs);
69     }
70         
71     if (g_options & OPT_LOGSCR) printf("[%s] " PROGNAME ": %s\n", ts, logline);
72 }
73
74 void cleanup(void)
75 {
76     if (g_logfs) fclose(g_logfs);
77 }
78
79 void usage(void)
80 {
81     fprintf(stderr, "ud-fingerserv " VERSION " " PROGDATE "\n");
82     fprintf(stderr, "\t(c) 1999 Randolph Chung <tausq@debian.org>. Released under the GPL\n");
83     fprintf(stderr, "\tThe following options are recognized:\n");
84     fprintf(stderr, "\t\t-h : this help text\n");
85     fprintf(stderr, "\t\t-i : run in inetd mode; otherwise runs in standalone mode\n");
86     fprintf(stderr, "\t\t-v : logs messages to stdout in addition to log file\n");
87     fprintf(stderr, "\t\t-l <file> : use <file> as the log file, instead of " DEFAULTLOGFILE "\n"); 
88     exit(0);
89 }
90
91 int main(int argc, char *argv[])
92 {
93     int ls, as;
94     int r;
95     struct sockaddr_in myaddr, rmtaddr;
96     socklen_t addrlen = sizeof(struct sockaddr_in);  
97    
98     atexit(cleanup);
99    
100     while ((r = getopt(argc, argv, "hivl:")) > 0) {
101         switch (r) {
102          case 'i': g_options |= OPT_INETD; break;
103          case 'v': g_options |= OPT_LOGSCR; break;
104          case 'l': g_logfn = strdup(optarg); break;
105          default: usage();
106         }
107     }
108
109     if (g_options & OPT_INETD) {
110         getsockname(fileno(stdin), &rmtaddr, &addrlen);
111         processcxn(fileno(stdin), &rmtaddr);
112     } else {
113         if ((ls = socket(AF_INET, SOCK_STREAM, 0)) < 0) PERROR("socket");
114         memset(&myaddr, 0, sizeof(myaddr));
115         myaddr.sin_family = AF_INET;
116         myaddr.sin_addr.s_addr = htonl(INADDR_ANY);
117         myaddr.sin_port = htons(FINGERPORT);
118         if (bind(ls, &myaddr, sizeof(myaddr)) < 0) PERROR("bind");
119         if (listen(ls, SOMAXCONN) < 0) PERROR("listen");
120         logf("Waiting for connection");
121         while ((as = accept(ls, &rmtaddr, &addrlen))) {
122             if ((r = fork()) == 0) {
123                 processcxn(as, &rmtaddr);
124                 exit(0);
125             } else {
126                 if (r < 0) PERROR("fork");
127             }
128         }
129     }
130    
131     return 0;
132 }
133