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