9f0604e69fda95c122d636f568e3092ba48abbdc
[oweals/cde.git] / cde / programs / dtterm / util / logger.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: logger.c /main/3 1995/10/31 12:04:16 rswiston $ */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <signal.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 #include <netdb.h>
35 #include <fcntl.h>
36
37 /*                                                                      *
38  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
39  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
40  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
41  * (c) Copyright 1993, 1994 Novell, Inc.                                *
42  */
43
44 static void serve(char *progName, int s, int logfd);
45
46 int
47 main(int argc, char **argv)
48 {
49     int s;
50     int i1;
51     int noFork = 0;
52     int pid;
53     int logfd = 1;
54     struct sockaddr_in myaddr_in;
55     extern char *optarg;
56     extern int optind, optopt;
57
58     while(EOF != (i1 = getopt(argc, argv, "fl:"))) {
59         switch(i1) {
60         case 'f' :
61             noFork = 1;
62             break;
63
64         case 'l' :
65             if ((logfd =
66                     open(optarg, O_WRONLY | O_APPEND | O_CREAT, 0644)) < 0) {
67                 (void) perror(optarg);
68                 (void) exit(1);
69             }
70             break;
71         }
72     }
73
74     /* init data... */
75 #if defined(USL) || defined(linux) || defined(sun) || defined(CSRG_BASED)
76     (void) memset((void *) &myaddr_in, (int) '\0', sizeof(myaddr_in));
77 #else
78     (void) memset(myaddr_in, '\0', sizeof(myaddr_in));
79 #endif
80
81     /* set up my address for socket... */
82     myaddr_in.sin_family = AF_INET;
83     /* listen to the wildcard address... */
84     myaddr_in.sin_addr.s_addr = INADDR_ANY;
85     /* use port 4444... */
86     myaddr_in.sin_port = 4444;
87
88     /* create a socket... */
89     s = socket(AF_INET, SOCK_DGRAM, 0);
90     if (s < 0) {
91         (void) perror("socket");
92         (void) exit(1);
93     }
94
95     /* bind the servers addr to the socket... */
96     if (bind(s, (struct sockaddr *)&myaddr_in, sizeof(myaddr_in)) == -1) {
97         (void) perror("bind");
98         (void) exit(1);
99     }
100
101     /* daemonize ourself... */
102     (void) setsid();
103
104     if (noFork) {
105         pid = 0 ;
106     } else {
107         pid = fork();
108     }
109
110     switch(pid) {
111     case -1:
112         /* unable to fork... */
113         (void) perror("fork");
114         (void) _exit(1);
115         break;
116
117     case 0:
118         /* child... */
119         (void) serve(argv[0], s, logfd);
120         break;
121
122     default:
123         /* parent... */
124         (void) exit(0);
125     }
126
127     (void) exit(0);
128 }
129
130 static void
131 logStartStop(char *progName, int logfd, int start)
132 {
133     static char *savedProgName = (char *) 0;
134     static int savedLogfd = -1;
135     time_t now;
136     char buffer[BUFSIZ];
137     char *tstring;
138
139     if (progName && *progName)
140         savedProgName = progName;
141     if (logfd >= 0)
142         savedLogfd = logfd;
143
144     (void) time(&now);
145     tstring = ctime(&now);
146     /* remove the trailing '\n'... */
147     tstring[strlen(tstring) - 1] = '\0';
148
149     (void) snprintf(buffer, sizeof buffer, "%s: %s %s\n",
150             (savedProgName && *savedProgName) ? savedProgName : "logger",
151             start ? "starting" : "terminating",
152             tstring);
153
154     if (savedLogfd >= 0)
155         (void) write(savedLogfd, buffer, strlen(buffer));
156 }
157     
158 void
159 shutDown(int sig)
160 {
161     (void) logStartStop(NULL, -1, 0);
162 }
163
164 static void
165 serve(char *progName, int s, int logfd)
166 {
167     int i;
168     int cc;
169     socklen_t addrlen;
170     char *c1;
171     char buffer[BUFSIZ];
172     struct sockaddr_in clientaddr_in;
173     struct hostent *hp;
174     
175     for (i = 0; i < 2; i++) {
176         if ((i != s) && (i != logfd)) {
177             (void) close(i);
178         }
179     }
180
181     (void) logStartStop(progName, logfd, 1);
182     (void) signal(SIGINT, shutDown);
183     (void) signal(SIGQUIT, shutDown);
184     (void) signal(SIGTERM, shutDown);
185     (void) signal(SIGUSR1, shutDown);
186     (void) signal(SIGUSR2, shutDown);
187
188     addrlen = sizeof(clientaddr_in);
189     while (1) {
190         (void) memset((char *) &clientaddr_in, 0, sizeof(clientaddr_in));
191         cc = recvfrom(s, buffer, sizeof(buffer) - 1, 0, 
192                       (struct sockaddr *)&clientaddr_in, &addrlen);
193
194         if (cc < 0) {
195             (void) exit(1);
196         }
197
198         /* null term the buffer... */
199         buffer[cc] = '\0';
200
201         hp = gethostbyaddr((char *) &clientaddr_in.sin_addr,
202                 sizeof(clientaddr_in.sin_addr), clientaddr_in.sin_family);
203         if (hp) {
204             c1 = hp->h_name;
205         } else {
206             c1 = inet_ntoa(clientaddr_in.sin_addr);
207         }
208         (void) write(logfd, c1, strlen(c1));
209         (void) write(logfd, ": ", 2);
210
211         (void) write(logfd, buffer, strlen(buffer));
212         (void) write(logfd, "\n", 1);
213
214         /* find the first space after the id... */
215         for (c1 = buffer; *c1 && (*c1 != ' ') && (*c1 != '\t'); c1++) {
216             ;
217         }
218         (void) strcpy(c1, " ACK");
219         (void) sendto(s, buffer, strlen(buffer), 0, (struct sockaddr *)&clientaddr_in, addrlen);
220     }
221 }