1 /*
2 * $Id: main.c,v 1.3 1998/08/15 00:00:50 elkner Exp $
3 *
4 * Author: Squirm derived http://www.senet.com.au/squirm/
5 * Project: Jesred http://ivs.cs.uni-magdeburg.de/~elkner/webtools/jesred/
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
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.
16 *
17 * http://www.gnu.org/copyleft/gpl.html or ./gpl.html
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24 #include<stdio.h>
25 #include<stdlib.h>
26 #include<string.h>
27 #include<sys/signal.h>
28 #include<sys/types.h>
29 #include<netinet/in.h>
30 #include<arpa/inet.h>
31
32 #ifdef LOCAL_REGEX
33 #include "regex.h"
34 #else
35 #include<regex.h>
36 #endif
37
38 #include "main.h"
39 #include "ip_list.h"
40 #include "pattern_list.h"
41 #include "config.h"
42 #include "util.h"
43 #include "log.h"
44 #include "version.h"
45 #include "rewrite.h"
46
47 static void Usage (void);
48 static void GetOptions(int argc, char *argv[]);
49
50 int echo_mode = 0;
51 int sig_hup = 0;
52 int interactive = 0;
53 int allow_siblings = 0;
54 #ifdef DEBUG
55 int debug_mode = 0;
56 #endif
57 FILE *fd_redirect = NULL;
58 FILE *fd_rewrite = NULL;
59
60
main(int argc,char ** argv)61 int main(int argc, char **argv)
62 {
63 char *f_allow = NULL;
64 char *f_rules = NULL;
65 char *f_rewrite = NULL;
66 char *f_redirect = NULL;
67
68
69 int first_run = 1;
70 char buff[BUFSIZE];
71 char redirect_url[BUFSIZE];
72 char *url, *src_addr, *ident, *method;
73 int finished = 0;
74 int buff_status = 0;
75 ip_acl *ip_list = NULL;
76 pattern_item *pattern_list = NULL;
77
78 /* go into interactive mode if we're run as root */
79 if((int)getuid() == 0) {
80 interactive = 1;
81 fprintf(stderr, "%s running as UID 0: writing logs to stderr\n",APPNAME);
82 }
83 signal(SIGHUP, HUPhandler);
84 signal(SIGKILL, KILLhandler);
85 GetOptions(argc, argv);
86
87 /* main program loop, executed forever more unless terminated
88 by a kill signal or EOF on stdin */
89 while(! finished) {
90 int val;
91
92 sig_hup = 0;
93 log(INFO, "Freeing up old linked lists\n");
94 ip_acl_destroy(&ip_list);
95 plist_destroy(&pattern_list);
96 closeLogs();
97 read_config(&f_allow, &f_rules, &f_redirect, &f_rewrite);
98 if (! interactive)
99 openLogs(&f_redirect, &f_rewrite);
100 read_allow(&f_allow, &ip_list);
101 read_rules(&f_rules, &pattern_list);
102
103 if(echo_mode)
104 log(ERROR, "Invalid condition - continuing in ECHO mode\n");
105 log(INFO, "%s (PID %d) started\n", APPNAME, (int)getpid());
106
107 while((!sig_hup) && (fgets(buff, BUFSIZE, stdin) != NULL)){
108 if(echo_mode) {
109 puts("");
110 fflush(stdout);
111 continue;
112 }
113 /* separate the four fields from the single input line of stdin */
114 buff_status = parse_buff(buff, &url, &src_addr, &ident, &method,
115 ip_list, pattern_list);
116 /* error during parsing the passed line from squid - no rewrite */
117 if(buff_status) {
118 puts("");
119 fflush(stdout);
120 continue;
121 }
122 /* check echo_mode again (sighup)*/
123 if(echo_mode) {
124 puts("");
125 fflush(stdout);
126 log(ERROR, "Invalid condition - continuing in ECHO mode\n");
127 continue;
128 }
129 /* find a rule for rewriting the URL */
130 val = pattern_compare(url, redirect_url, pattern_list);
131 if( val < 1 ) {
132 /* no rule found = 0, or ABORT rule -N */
133 puts("");
134 fflush(stdout);
135 continue;
136 }
137 else {
138 /* redirect_url contains the replacement URL */
139 if ( redirect_url[0] == '\0' ) {
140 /* regex[i] abort, i.e. empty replacement URL */
141 puts("");
142 fflush(stdout);
143 }
144 else {
145 printf("%s %s %s %s\n",
146 redirect_url, src_addr, ident, method);
147 fflush(stdout);
148 log(MATCH, "%s %s %s %d\n", src_addr, url, redirect_url,
149 val);
150 }
151 }
152 }
153 if(! sig_hup)
154 finished = 1;
155 } /* end while(1) */
156 ip_acl_destroy(&ip_list);
157 plist_destroy(&pattern_list);
158 closeLogs();
159 safe_free(f_rewrite);
160 safe_free(f_redirect);
161 return 0;
162 }
163
164 static void
GetOptions(int argc,char * argv[])165 GetOptions(int argc, char *argv[])
166 {
167 extern char *optarg;
168 extern int optind;
169 int c;
170
171 while ((c = getopt(argc, argv, "hv")) != -1) {
172 switch (c) {
173 case 'h' :
174 Usage();
175 break;
176 case 'v' :
177 printf("%s %s (C) by %s (%s)\n%s\n",
178 APPNAME, VERSION, AUTHOR, AUTHOR_EMAIL, APPURL);
179 exit(0);
180 default:
181 Usage();
182 break;
183 }
184 }
185 }
186
187 static void
Usage(void)188 Usage(void)
189 {
190
191 fprintf(stderr,
192 "Usage: %s [-h] [-v]\n\n"
193 " -h print this and exit\n"
194 " -v show version and exit\n",
195 APPNAME);
196 exit(1);
197 }
198