- Added hint on GIF char array generation to jcc.c
[privoxy.git] / killpopup.c
1 const char killpopup_rcs[] = "$Id: killpopup.c,v 1.1 2001/05/13 21:57:06 administrator Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /home/administrator/cvs/ijb/killpopup.c,v $
5  *
6  * Purpose     :  Handles the filtering of popups.
7  *
8  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
9  *                IJBSWA team.  http://ijbswa.sourceforge.net
10  *
11  *                Based on the Internet Junkbuster originally written
12  *                by and Copyright (C) 1997 Anonymous Coders and 
13  *                Junkbusters Corporation.  http://www.junkbusters.com
14  *
15  *                This program is free software; you can redistribute it 
16  *                and/or modify it under the terms of the GNU General
17  *                Public License as published by the Free Software
18  *                Foundation; either version 2 of the License, or (at
19  *                your option) any later version.
20  *
21  *                This program is distributed in the hope that it will
22  *                be useful, but WITHOUT ANY WARRANTY; without even the
23  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
24  *                PARTICULAR PURPOSE.  See the GNU General Public
25  *                License for more details.
26  *
27  *                The GNU General Public License should be included with
28  *                this file.  If not, you can view it at
29  *                http://www.gnu.org/copyleft/gpl.html
30  *                or write to the Free Software Foundation, Inc., 59
31  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
32  *
33  * Revisions   :
34  *    $Log: killpopup.c,v $
35  *
36  *********************************************************************/
37 \f
38
39 #include "config.h"
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <sys/types.h>
44 #include <string.h>
45 #include <malloc.h>
46 #include <errno.h>
47 #include <sys/stat.h>
48 #include <ctype.h>
49
50 #ifndef _WIN32
51 #include <unistd.h>
52 #endif
53
54 #include "project.h"
55 #include "killpopup.h"
56 #include "jcc.h"
57
58 const char killpopup_h_rcs[] = KILLPOPUP_H_VERSION;
59
60 #ifdef KILLPOPUPS
61
62 /* Change these for debug output.  *lots*. */
63 /*#define POPUP_VERBOSE 1*/
64 /* CHANGED - added the below and shifted the more spammy stuff into it ;-) */
65 #undef POPUP_VERY_VERBOSE
66 #undef POPUP_VERBOSE
67
68
69 /*********************************************************************
70  *
71  * Function    :  filter_popups
72  *
73  * Description :  Filter the block of data that's been read from the server.
74  *                IF NECESSARY.
75  *
76  * Parameters  :
77  *          1  :  csp = Client state
78  *          2  :  host_name = hostname of originating web page to
79  *                look up on blocklist
80  *          3  :  buff = Buffer to scan and modify.  Null terminated.
81  *          4  :  size = Buffer size, excluding null terminator.
82  *
83  * Returns     :  void
84  *
85  *********************************************************************/
86 void filter_popups(struct client_state *csp, char *host_name, char *buff, int size)
87 {
88    struct popup_settings * data;
89    struct popup_blocklist * cur;
90    int i;
91    int found = 0;
92    char *popup = NULL;
93    char *close = NULL;
94    char *p     = NULL;
95    char *q     = NULL; /* by BREITENB NEW! */
96
97    if ( (!csp->plist) || ((data = csp->plist->f) == NULL) )
98    {
99       /* Disabled. */
100       return;
101    }
102
103    /* If the hostname is on our list for blocking then mark it
104     * as a host to   block from.  (This may be later changed if the
105     * host is also on the list-to-allow list).
106     */
107
108    for (i=0; (i < 50) && (i < size); i++)   /* avoid scanning binary data! */
109    {
110       if ((unsigned int)(buff[i])>127)
111       {
112 #ifdef  POPUP_VERBOSE
113          fprintf(logfp, "I'm not scanning binary stuff! (%i)\n",buff[i]);
114 #endif
115          return;
116       }
117    }
118
119
120    for (cur = data->blocked ; cur ; cur = cur->next)
121    {
122       if ( host_name != 0 )
123       {
124          if ( strcmp( cur->host_name, host_name ) == 0 )
125          {
126 #ifdef  POPUP_VERBOSE
127             fprintf(logfp, "Blocking %s\n", host_name );
128 #endif
129             found = 1;
130          }
131       }
132    }
133
134    /* Force match if we're supposed to nuke _all_ popups, globally. */
135    if ( kill_all_popups != 0 )
136    {
137 #ifdef POPUP_VERBOSE
138       fprintf(logfp, "Indescriminatly nuking popups..\n" );
139 #endif
140       found = 1;
141    }
142    /* an exception-from blocking should still be an exception! by BREITENB NEW! */
143
144
145    /*    Now, if its allowed adjust the filtering, so it _doesn't_ happen. */
146    for (cur = data->allowed ; cur ; cur = cur->next)
147    {
148       if ( host_name != 0 )
149       {
150          if ( strcmp( cur->host_name, host_name ) == 0 )
151          {
152 #ifdef POPUP_VERBOSE
153             fprintf(logfp, "Reversing block decision for %s\n", host_name );
154 #endif
155             found = 0;
156          }
157       }
158    }
159
160    if ( found == 0)
161    {
162 #ifdef POPUP_VERBOSE
163       fprintf(logfp, "Allowing %s\n", host_name );
164 #endif
165       return;
166    }
167
168    while ((popup = strstr( buff, "window.open(" )) != NULL)
169       /* if ( popup  )  by BREITENB filter ALL popups! NEW! */
170    {
171 #ifdef POPUP_VERBOSE
172       fprintf(logfp, "Found start of window open" );
173 #endif
174       close = strstr( popup+1, ");" );
175       if ( close )
176       {
177 #ifdef POPUP_VERBOSE
178          fprintf(logfp, "Found end of window open" );
179 #endif
180          for ( p = popup; p != (close+1); p++ )
181          {
182             *p = ' ';
183          }
184 #ifdef POPUP_VERBOSE
185          fprintf(logfp, "Blocked %s\n", host_name );
186 #endif
187       }
188       else
189       {
190 #ifdef POPUP_VERBOSE
191          fprintf(logfp, "Couldn't find end, turned into comment.  Read boundary?\n" );
192 #endif
193          *popup = '/';
194          popup++;
195          *popup = '/';
196       }
197
198
199       q=popup; /* by BREITENB NEW! */
200       while (q>=buff)
201       {
202          if (*q==' ' || *q=='\t')
203             q--;
204          else break;
205       }
206       if (q>=buff)
207       {
208          if (*q=='=') *++q='1';
209          /* result of popup is assigned to a variable! ensure success. hehehe. */
210       }
211    }
212
213    /* Filter all other crap like onUnload onExit etc.  (by BREITENB) NEW!*/
214    popup=strstr( buff, "<body");
215    if (!popup) popup=strstr( buff, "<BODY");
216    if (!popup) popup=strstr( buff, "<Body");
217    if (!popup) popup=strstr( buff, "<BOdy");
218    if (popup)
219    {
220       q=strchr(popup,'>');
221       if (q)
222       {
223          /* we are now between <body and the ending > */
224          p=strstr(popup, "onUnload");
225          if (p)
226          {
227             strncpy(p,"_nU_",4);
228          }
229          p=strstr(popup, "onExit");
230          if (p)
231          {
232             strncpy(p,"_nE_",4);
233          }
234       }
235    }
236
237 }
238
239 #endif /* def KILLPOPUPS */
240
241 /*
242   Local Variables:
243   tab-width: 3
244   end:
245 */