cleaned up some code, removed/improved few comments, better logging
[rxpd.git] / src / main.c
blob27aabf3ea724ea7bee684da641dfa576bce9a3f1
1 /*
2 main.c - regex policy daemon
4 Copyright (C)
5 2007, Christian Thaeter <ct@pipapo.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "rxpd.h"
24 #include <string.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <locale.h>
30 #include <langinfo.h>
32 void
33 version (void)
35 printf (
36 " Regex Policy Daemon ("PACKAGE_STRING")\n\n"
37 " Copyright (C)\n"
38 " 2007, Christian Thaeter <ct@pipapo.org>\n\n"
39 " This is free software. You may redistribute copies of it under the terms of\n"
40 " the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
41 " There is NO WARRANTY, to the extent permitted by law.\n\n"
42 " http://www.pipapo.org/pipawiki/RegexPolicyDaemon\n"
46 void
47 usage (void)
49 printf (
50 "rxpd [OPTIONS] RULES..\n"
51 " -v increase verbosity level\n"
52 " -V show version\n"
53 " -d daemonize into background\n"
54 " -D debug mode\n"
55 " -b dir basedir for rules\n"
56 " -q be quiet\n"
57 " -t port listen on tcp port\n"
58 //" -u name unix\n"
59 " -p policy define a list for access policies\n"
60 //" -i case insensitive\n"
61 //" -4 ipv4\n"
62 //" -6 ipv6\n"
63 //" -r resolve names\n"
64 //" -l log log hits to logfile\n"
65 " -L locale set locale, must be a utf-8 locale, only LC_CTYPE is used\n"
66 " -h this usage information\n"
67 //" -U user switch to user\n"
72 int
73 main (int argc, char** argv)
75 if (pth_init() == FALSE)
76 rxpd_fail (NULL, "pth initialization failed\n");
78 struct rxpd_base* rxpd;
80 openlog (PACKAGE_NAME, LOG_PID, LOG_DAEMON);
82 rxpd = rxpd_init ();
84 opterr = 0;
85 int opt;
87 while ((opt = getopt (argc, argv, "vVdDb:qt:u:p:i46rl:L:h")) != -1)
88 switch (opt)
90 case 'v':
91 if (rxpd->verbosity < LOG_DEBUG)
92 ++rxpd->verbosity;
93 break;
94 case 'V':
95 version ();
96 exit (EXIT_SUCCESS);
97 case 'd':
98 rxpd->daemonize = 1;
99 break;
100 case 'D':
101 if (rxpd->verbosity < LOG_INFO)
102 rxpd->verbosity = LOG_INFO;
103 rxpd->daemonize = 0;
104 break;
105 case 'b':
106 if (!rxpd->basedir)
107 rxpd_set_basedir (rxpd, optarg);
108 else
109 rxpd_fail (rxpd, "basedir already set\n");
110 break;
111 case 'q':
112 rxpd->verbosity = LOG_ALERT;
113 break;
114 case 't':
116 int port = atoi (optarg);
117 if (port > 0 && port < 65536)
119 if (!rxpd_socket_new_tcp4 (rxpd, NULL, port))
120 rxpd_fail (rxpd, "Could not open listening socket on port %d\n", port);
122 else
123 rxpd_fail (rxpd, "Illegal port number\n");
125 // TODO rxpd_socket_new_tcp6 (rxpd, NULL, 2374)
126 break;
127 #if 0 /*not yet implemented*/
128 case 'u':
129 //rxpd_socket_new_unix (rxpd, NULL, 2374);
130 break;
131 #endif
132 case 'p':
133 if (!rxpd->policy)
134 rxpd->policy = rxpd_file_new (rxpd, optarg);
135 else
136 rxpd_fail (rxpd, "policy already set\n");
137 break;
138 case 'i':
139 rxpd->regflags |= REG_ICASE;
140 break;
141 case 'L':
142 if (!rxpd->locale)
143 rxpd->locale = optarg;
144 else
145 rxpd_fail (rxpd, "locale already set\n");
146 break;
147 #if 0 /*not yet implemented*/
148 case '4':
149 break;
150 case '6':
151 break;
152 case 'r':
153 break;
154 case 'l:':
155 break;
156 #endif
157 case 'h':
158 usage ();
159 exit (0);
160 break;
161 default:
162 rxpd_fail (rxpd, "Unknown option '-%c'\n", opt);
165 if (!rxpd->basedir)
166 rxpd_fail (rxpd, "Basedir not set (use -b BASEDIR)\n");
168 if (llist_is_empty (&rxpd->sockets))
169 rxpd_fail (rxpd, "No listening sockets given (use -t TCP or -u UNIX)\n");
171 rxpd->locale = setlocale(LC_CTYPE, rxpd->locale ? rxpd->locale : "");
172 if (!rxpd->locale)
173 rxpd_fail (rxpd, "Failed setting locale\n");
175 rxpd_log (rxpd, LOG_INFO, "Using locale '%s'\n", rxpd->locale);
176 if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
177 rxpd_fail (rxpd, "Not a utf-8 locale '%s'\n", rxpd->locale);
179 if (rxpd->policy)
181 if (rxpd_file_load (rxpd->policy))
182 rxpd_log (rxpd, LOG_INFO, "Loaded policy '%s'\n", rxpd->policy->filename);
183 else
184 rxpd_fail (rxpd, "Failed loading policy '%s'\n", rxpd->policy->filename);
187 for (int i = optind; i < argc; ++i)
189 if (!rxpd_file_load (rxpd_file_new (rxpd, argv[i])))
190 rxpd_fail (rxpd, "Failed loading file '%s'\n", argv[i]);
193 if (rxpd->daemonize)
195 rxpd_log (rxpd, LOG_NOTICE, "Daemonizing ...\n");
196 if (daemon(1, 0))
197 rxpd_fail (rxpd, "Couldn't daemonize\n");
200 rxpd_log (rxpd, LOG_NOTICE, PACKAGE_STRING" starting up\n");
202 LLIST_FOREACH (&rxpd->sockets, n)
204 struct rxpd_socket* socket = (struct rxpd_socket*)n;
205 rxpd_socket_spawn (socket);
208 rxpd_log (rxpd, LOG_NOTICE, PACKAGE_STRING" running\n");
210 LLIST_WHILE_HEAD (&rxpd->sockets, n)
212 struct rxpd_socket* socket = (struct rxpd_socket*)n;
213 rxpd_socket_delete (rxpd_socket_join (socket));
216 rxpd_log (rxpd, LOG_NOTICE, PACKAGE_STRING" exited\n");
217 rxpd_destroy ();
219 return EXIT_SUCCESS;