sqcwa-0.3/0040755000175000017500000000000007636206455011557 5ustar cprovcprovsqcwa-0.3/Makefile0100644000175000017500000000114407631451331013202 0ustar cprovcprovCFLAGS=-Wall -O2 all: sqcwa distclean: clean rm -fv *~ clean: rm -fv *.o sqcwa sqcwa: url.o sqclient.o htmlchk.o sqcwa.o watchlog.o daemon.o install: sqcwa mkdir -p $(DESTDIR)/usr/sbin/ install -m 0755 sqcwa $(DESTDIR)/usr/sbin/sqcwa mkdir -p $(DESTDIR)/etc/init.d/ install -m 0755 sqcwa.init.d $(DESTDIR)/etc/init.d/sqcwa uninstall: rm -fv $(DESTDIR)/usr/sbin/sqcwa $(DESTDIR)/etc/init.d/sqcwa # squid in Debian starts at sequence 30. lets start sqcwa # before squid is running (sequence 31) and stop it before # squid dies (sequence 29). # update-rc.d sqcwa start 31 2 3 4 5 . stop 29 0 1 6 . sqcwa-0.3/README0100644000175000017500000000423107631447777012445 0ustar cprovcprovsqcwa -- workaround for squid not caching pages with or others Copyright (C) 2003 Pedro Zorzenon Neto José Roberto Monteiro This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- This program reads squid/access.log, analyses it and searches inside all text/html objects for some tags, and if found, tells squidclient to purge the page. This program is in TESTING stage. To use it, install squid and squidclient in the computer, and execute the following command: sqcwa /var/log/squid/access.log It will expect that you have installed the program client from squid in /usr/bin/squidclient. If you do not have it there, then use a symbolic link or change SQCLIENT.H in the sources. It will expect to find squid running in localhost tcp port 3128. Note: this program will only run if executed in the same computer where squid is installed. I'd apreciate your comments about this program. This is a TESTING version and we need to know how it is working. Write to with subject sqcwa. We tried to make this program without any security hole, but we are not sure about it. Known side effects of using it: - increases CPU load (not too much. in out tests, less than 1% in a pentium 2 300MHz, with 5 browsers using proxy) - does not work if someone navigates from localhost - increase access.log lines with accesses from localhost (check and purge access) SQCWA means SQuid Cache Work-Around sqcwa-0.3/sqcwa.c0100644000175000017500000001124407631441763013036 0ustar cprovcprov/* sqcwa -- workaround for squid not caching pages with or others Copyright (C) 2003 Pedro Zorzenon Neto José Roberto Monteiro This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* memory debug */ //#define MEMDEBUG /* verbose mode, usefull for debug */ //#define SQCWA_VERBOSE /* undefine to run in the command line for debugging */ #define SQCWA_DAEMON_MODE #define PIDBASEFILENAME "sqcwa" /* run with privileges of user 'proxy' * Debian systems, its uid and gid are 13 * if you do not want the program to drop * privileges, use UID -1 and GID -1. * drop privileges is only enabled in daemon_mode */ #define SQCWA_PROXY_UID 13 #define SQCWA_PROXY_GID 13 /* PID file */ #define SQCWA_VERSION "0.3" #include "common.h" #include "htmlchk.h" #include "sqclient.h" #include "watchlog.h" #include "daemon.h" #include #include #include #include #include #include #include int main(int argc, char * argv[]) { char * ss, * sn, * si, * sdata[4]; int i, error; int http_code; htmlchk_t * ht; watchlog_t * wl; #ifdef SQCWA_DAEMON_MODE run_daemon_run (PIDBASEFILENAME, SQCWA_PROXY_UID, SQCWA_PROXY_GID); #endif /* IMPROVE compare argv to --version, -v, --help, -h */ fprintf(stderr,"sqcwa - SQuid Cache WorkAround\n" "Version: " SQCWA_VERSION "\n" "Website: http://www.autsens.com/sqcwa/\n" "Usage: sqcwa [logfilename]\n" "\n" "sqcwa is running now...\n"); ht = htmlchk_init (); if (argc>1) { /* user defined logfile */ wl = watchlog_init (argv[1]); } else { /* default logfile */ fprintf(stderr,"WARNING: you did not specify a logfilename\n" " will use '/var/log/squid/access.log'\n"); wl = watchlog_init ("/var/log/squid/access.log"); } // while ((ss = fgets(s, LOGLINEMAXSIZE, stdin))) { while (1) { int idata = 0; // fprintf(stderr,"will getline\n"); watchlog_getline(wl); // fprintf(stderr," gotline %s\n", wl->data); ss = wl->data; #ifdef MEMDEBUG fprintf(stderr,"memory allocated: %d\n",mallinfo().arena); #endif #ifdef SQCWA_VERBOSE fprintf(stderr,"\nfound log line: %s",ss); #endif error = 0; // s[LOGLINEMAXSIZE-1] = '\0'; // end line safety //if (strlen(s) >= LOGLINEMAXSIZE) // verify line size // continue; // skips if it has the maximum size //sn = ss = strdup(s); // copies line sn = ss; for (i = 0; i < 4; i++) sdata[i] = NULL; i = 0; while ((si = strsep(& sn, " \t\n\r"))) { if (i > 10) { error = 1; break; } if (si && strlen(si)) { switch (i) { case 2: case 3: case 6: case 9: sdata[idata++] = strdup(si); break; } i++; } } if (i < 10) { error |= 2; } if (! error) { http_code = -1; for (i = 0; i < strlen(sdata[1]) - 1; i++) { if (sdata[1][i] == '/') { sdata[1][i+2] = '\0'; http_code = atoi(sdata[1]+i+1); } } if (strcmp(sdata[0], "127.0.0.1") != 0 && strcmp(sdata[3], "text/html") == 0 && (http_code == 2 || http_code == 3)) { #ifdef SQCWA_VERBOSE fprintf(stderr," will open and check this html file. decision = "); #endif if (htmlchk_pagestate(ht,sdata[2]) == 2) { #ifdef SQCWA_VERBOSE fprintf(stderr,"need to PURGE\n"); #endif sqclient_purge_from_cache(sdata[2]); } else { #ifdef SQCWA_VERBOSE fprintf(stderr,"nothing to do\n"); #endif } } else { #ifdef SQCWA_VERBOSE fprintf(stderr," no need to check this logline\n"); /* "IP = %s HTTP Code = %d " " Mime = %s\nURL = %s\n", sdata[0], http_code, sdata[3], sdata[2]); */ #endif } } else { fprintf(stderr," Error parsing logfile line. error code: %d\n", error); } for (i = 0; i < 4; i++) if (sdata[i]) free(sdata[i]); //free(ss); } htmlchk_destroy(ht); watchlog_destroy(wl); return 0; } sqcwa-0.3/sqclient.c0100644000175000017500000000446307631415275013546 0ustar cprovcprov/* sqclient -- gets a page from squid cache or purge it Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "htmlchk.h" #include "sqclient.h" #include "url.h" #include #include #include #include #include #include #include /* debug purposes */ //#define SQCLIENT_VERBOSE int sqclient_retrieve_if_in_cache (char * url, char * outfile) { int i; char * s; char * urlf; urlf = malloc ((strlen(url)*3)+1); assert (urlf != NULL); url_filter (url, urlf); s = malloc (strlen(urlf)+200); assert (s != NULL); sprintf(s, SQUIDCLIENT " " SQUIDCLIENTARGS " " " -m GET " "-H \"Cache-control: Only-if-cached\\n\" " "'%s' " "> %s 2>/dev/null", urlf, outfile); #ifdef SQCLIENT_VERBOSE fprintf(stderr,"sqclient: checking cache: %s\n",urlf); #endif i=system(s); if (i!=0) { fprintf(stderr,"sqclient: system call failed. ERR:%d CMD:%s\n",i,s); } free(urlf); free(s); if (i == 0) { return 1; } return 0; } void sqclient_purge_from_cache(char * url) { int i; char * s; char * urlf; #ifdef SQCLIENT_VERBOSE fprintf(stderr,"sqclient: PURGING from cache: %s\n",url); #endif urlf = malloc ((strlen(url)*3)+1); assert (urlf != NULL); url_filter (url, urlf); s = malloc (strlen(urlf)+200); assert (s != NULL); sprintf(s, SQUIDCLIENT " " SQUIDCLIENTARGS " " "-m PURGE " "'%s' " "> /dev/null 2>&1", urlf); i=system(s); if (i!=0) { fprintf(stderr,"sqclient: system call failed. ERR:%d CMD:%s\n",i,s); } free(urlf); free(s); } sqcwa-0.3/Changelog0100644000175000017500000000053307631451707013364 0ustar cprovcprovsqcwa (0.3) * Added daemon feature. * Added logfile watch feature. * Changed from three numbers (0.0.2) to two numbers (0.3) version. -- Pedro Zorzenon Neto Wed, 5 Mar 2003 16:44:51 -0300 sqcwa (0.0.2) * Memory leak bugfix in htmlchk.c -- Pedro Zorzenon Neto Thu, 30 Jan 2003 11:38:10 -0200 sqcwa-0.3/watchlog.h0100644000175000017500000000302607631442164013530 0ustar cprovcprov/* watchlog -- reads lines from logfile. checks if name has changed and if file has new data. Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _WATCHLOG_H #define _WATCHLOG_H #include /* for FILE type */ struct watchlog { char * fn; /* logfile name */ struct stat * fs; /* logfile status */ int is_at_eof; /* indicates that fileposition is at eof */ char * data; /* last line read from logfile */ FILE * fh; /* logfile handle */ }; #define watchlog_t struct watchlog /* this function does not fail. it retries if failed and returns * only when it succeeds */ watchlog_t * watchlog_init (char * logfilename); /* this function blocks the program until there is data available */ void watchlog_getline (watchlog_t * self); void watchlog_destroy (watchlog_t * self); #endif sqcwa-0.3/common.h0100644000175000017500000000016007631350613013201 0ustar cprovcprov#ifndef _COMMON_H #define _COMMON_H /* maximun size of a squid log line */ #define LOGLINEMAXSIZE 8200 #endif sqcwa-0.3/htmlchk.c0100644000175000017500000001365107616224216013351 0ustar cprovcprov/* htmlchk -- checks if page has directives to explicit disable caching Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "htmlchk.h" #include "sqclient.h" #include #include #include #include #include #include #include #include #define TMPFILE_TIMEOUT 50 #define BUFSIZE 32768 /* testing and debug purposes #define HTMLCHKTEST #define VERBOSE */ htmlchk_t * htmlchk_init (void) { htmlchk_t * self; char * fn = NULL; int maxtry = TMPFILE_TIMEOUT; while ( (fn==NULL) && (maxtry>0) ) { int fd; /* I want "tmpnam", not "mkstemp", ignore warning when compiling */ fn = tmpnam(NULL); fd = open(fn, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { /* open error */ maxtry--; fn=NULL; } else { close(fd); } } if (fn==NULL) { fprintf(stderr, "Could not create a unique temporary file.\n"); abort(); } self = malloc (sizeof(htmlchk_t)); assert(self != NULL); self->tmpfile = malloc (strlen(fn)+1); assert(self->tmpfile != NULL); strcpy(self->tmpfile, fn); return self; } int htmlchk_pagestate (htmlchk_t * self, char * url) { int comment = 0; int state=-1; char *buf; ssize_t size; int i, fd; i = sqclient_retrieve_if_in_cache (url, self->tmpfile); if (i != 1) { /* did not find page in cache */ return 0; } /* page is in cache, lets scan it */ fd = open (self->tmpfile, O_RDONLY); if ( fd == -1 ) { fprintf(stderr, "could not open html tmpfile for scanning.\n"); return -1; } buf = calloc ( BUFSIZE, 1); size = read (fd, buf, BUFSIZE-7); /* 7 is the lucky number :-) */ for (i=0; i", buf+i, 3) == 0) { comment=0; i+=3; } if (comment==0) { if (*(buf+i)=='<') { int tagbegin=i; int tagend=i; while ( (tagend<(BUFSIZE-1)) && ( *(buf+tagend) != '>') ) { tagend++; if (*(buf+tagend)=='<') { /* found '<' inside a tag... */ tagend=BUFSIZE; } } if ( (tagend!=BUFSIZE) && ( (tagend-tagbegin) > 2 ) ) { /* tag has begin and end */ int j; int k=0; char *meta; meta = malloc (tagend-tagbegin-1); for (j=(tagbegin+1); j0x2F) && (c<0x3A) ) || ( (c>0x40) && (c<0x5B) ) || ( (c>0x60) && (c<0x7B) ) ) { *(meta+k)=c; k++; } } *(meta+k)=0; /* end of string */ if ( (strcasecmp("/head",meta)==0) || (strcasecmp("body",meta)==0) ) { /* or found... * will not find outside or inside */ #ifdef VERBOSE fprintf(stderr, "end of element or begin of " " element found\n"); #endif state=1; } if ( strcasecmp("metahttp-equiv=pragmacontent=no-cache", meta)==0) { /* found the right tag */ #ifdef VERBOSE fprintf(stderr, " found\n"); #endif state=2; } if ( strcasecmp("metahttp-equiv=cache-controlcontent=no-cache", meta)==0) { /* found the right tag */ #ifdef VERBOSE fprintf(stderr, " found\n"); #endif state=2; } if ( strcasecmp("metahttp-equiv=expirescontent=0", meta)==0) { /* found the right tag */ #ifdef VERBOSE fprintf(stderr, " found\n"); #endif state=2; } if ( strcasecmp("metahttp-equiv=expirescontent=-1", meta)==0) { /* found the right tag */ #ifdef VERBOSE fprintf(stderr, " found\n"); #endif state=2; } free(meta); i=tagend+1; } } } if (state != -1) { break; } } /* end of for (i=0; itmpfile != NULL) { remove(self->tmpfile); free(self->tmpfile); } free(self); } } #ifdef HTMLCHKTEST int main() { struct htmlchk *ht; char url[1024]; int i; ht=htmlchk_init(); printf("htmlchk tmpfilename: '%s'\n", ht->tmpfile); strcpy (url, "http://www.autsens.com/teste-0.htm"); i = htmlchk_pagestate (ht, url); printf ("htmlchk %s pagestate=%d\n", url, i); if (i == 2) { printf("state is 2, purging from cache\n"); sqclient_purge_from_cache(url); } printf("\n"); strcpy (url, "http://www.autsens.com/teste-3.htm"); i = htmlchk_pagestate (ht, url); printf ("htmlchk %s pagestate=%d\n", url, i); if (i == 2) { printf("state is 2, purging from cache\n"); sqclient_purge_from_cache(url); } htmlchk_destroy(ht); return 0; } #endif sqcwa-0.3/watchlog.c0100644000175000017500000001672707631417723013542 0ustar cprovcprov/* watchlog -- reads lines from logfile. checks if name has changed and if file has new data. Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* NOTA: I tried to use "Interrupt I/O" described in libc info page * with SIGIO and O_ASYNC, but my try was not successful. * then I used a pool mode with file attributes, checking if file * size has changed or if file has changed by a logrotate * (device/inode) */ //#define WATCHLOG_DEBUG //#define WATCHLOG_TEST #include "watchlog.h" #include "common.h" #include #include #include #include #include #include #include #include #define AT_BOF 1 /* begin-of-file */ #define AT_EOF 2 /* end-of-file */ #define WATCHLOG_INIT_CAN_ABORT /* watchlog_init will abort program * if could not find the logfile. * if not defined, watchlog_init will * retry to open file every 10 senconds */ /* private functions */ int stat_withretry (char * fn, struct stat * fs); FILE * logfile_open (watchlog_t * self, int where); /* end of private functions */ watchlog_t * watchlog_init (char * logfilename) { watchlog_t * self; self = malloc (sizeof (watchlog_t)); assert (self != NULL); self->fn = malloc (sizeof(char) * (strlen (logfilename) + 1)); assert (self->fn != NULL); strcpy (self->fn, logfilename); self->fs = malloc (sizeof (struct stat)); assert (self->fs != NULL); self->data = malloc (sizeof(char) * LOGLINEMAXSIZE); assert(self->data != NULL); strcpy(self->data,""); self->fh = NULL; #ifdef WATCHLOG_INIT_CAN_ABORT if (stat(self->fn, self->fs) != 0) { fprintf(stderr,"logfile name: %s\n", self->fn); perror("logfile open: stat"); abort(); } #endif while (self->fh == NULL) { stat_withretry (self->fn, self->fs); self->fh = logfile_open (self, AT_EOF); if (self->fh == NULL) { /* open failed */ sleep (1); } } self->is_at_eof = 1; #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_init\n"); #endif return self; } void watchlog_destroy (watchlog_t * self) { if (self != NULL) { if (self->fh != NULL) { fclose (self->fh); } if (self->fn != NULL) { free (self->fn); } if (self->data != NULL) { free (self->data); } free(self); } #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_destroy\n"); #endif } int stat_withretry (char * fn, struct stat * fs) { int firsttime = 1; int retval = -1; int no_need_to_retry = 1; #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_stat_withretry begin\n"); #endif while (retval != 0) { retval=stat(fn, fs); if (retval != 0) { /* something failed. wait sometime before retry */ #ifdef WATCHLOG_DEBUG perror("stat"); fprintf(stderr,"filename %s\n",fn); fprintf(stderr,"watchlog_stat_withretry retry\n"); #endif no_need_to_retry = 0; if (firsttime) { sleep(1); } else { sleep(10); } } firsttime = 0; } #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_stat_withretry end '%d'\n", no_need_to_retry); #endif return no_need_to_retry; } FILE * logfile_open (watchlog_t * self, int where) { FILE * fh; #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_logfile_open begin\n"); #endif /* open log file */ fh = fopen(self->fn, "r"); if (fh == NULL) { /* open failed */ #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_logfile_open failed\n"); #endif return NULL; } switch (where) { case AT_BOF: /* nothing to do, fopen already opens at begin-of-file */ break; case AT_EOF: /* go to end-of-file */ if ( fseek (fh, 0, SEEK_END) != 0 ) { /* end-of-file failed */ #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_logfile_fseek failed\n"); #endif fclose (fh); fh = NULL; } break; default: assert(0); } return fh; } void watchlog_getline (watchlog_t * self) { #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_getline begin\n"); #endif if (self->is_at_eof == 0) { /* there is data available */ if (feof (self->fh)) { /* just a protection. should never enter here */ assert(0); self->is_at_eof = 1; clearerr (self->fh); /* clear eof flag */ watchlog_getline(self); return; } if (fgets(self->data, LOGLINEMAXSIZE, self->fh) != NULL) { self->is_at_eof = 0; #ifdef WATCHLOG_DEBUG printf("getline: %s",self->data); #endif return; } else { /* could not read... then should be at eof */ self->is_at_eof = 1; if (feof(self->fh)) { clearerr (self->fh); /* clear eof flag */ } watchlog_getline(self); return; } return; } else { /* need to check if there is data available */ struct stat * fsn; fsn = malloc(sizeof(struct stat)); assert (fsn != NULL); while (1) { int need_reopen = 0; int has_newdata = 0; if (stat_withretry(self->fn, fsn) == 0) { need_reopen = 1; } else if (memcmp(fsn, self->fs, sizeof(struct stat)) != 0) { /* something has changed */ if ( (fsn->st_dev != self->fs->st_dev) || (fsn->st_ino != self->fs->st_ino) || (fsn->st_size < self->fs->st_size) ) /* file is shorter */ { /* file device or inode has changed */ need_reopen=1; } else if (fsn->st_size != self->fs->st_size) { /* file size has changed */ has_newdata = 1; } } memcpy(self->fs, fsn, sizeof(struct stat)); if (need_reopen == 1) { /* we need to reopen the file */ fclose (self->fh); self->fh = NULL; while (self->fh == NULL) { stat_withretry (self->fn, fsn); self->fh = logfile_open (self, AT_BOF); if (self->fh == NULL) { /* open failed */ sleep (1); } } fprintf(stderr,"WARNING: lost logfile handler. will reopen " "logfile now -- this occours when file is truncated " "or when file inode changes (maybe it was just " "'logrotate' doing its job).\n"); /* file is reopened now and fileposition is at BOF */ /* lets assume that the file is new, then we need to parse * data from its begin */ has_newdata = 1; } if (has_newdata == 1) { if (fgets(self->data, LOGLINEMAXSIZE, self->fh) != NULL) { self->is_at_eof = 0; #ifdef WATCHLOG_DEBUG fprintf(stderr,"watchlog_getline: %s",self->data); #endif free(fsn); return; } else { /* could not read... then should be at eof */ if (feof(self->fh)) { clearerr (self->fh); /* clear eof flag */ } } } sleep (2); /* prevents too much resource usage */ } } } #ifdef WATCHLOG_TEST int main() { watchlog_t * wl; wl = watchlog_init("/tmp/mylog"); while (1) { watchlog_getline(wl); printf("gotdata: %s",wl->data); } return 0; } #endif sqcwa-0.3/htmlchk.h0100644000175000017500000000267507616003273013360 0ustar cprovcprov/* htmlchk -- checks if page has directives to explicit disable caching Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _HTMLCHK_H #define _HTMLCHK_H struct htmlchk { char * tmpfile; }; typedef struct htmlchk htmlchk_t; /* returns a pointer to htmlchk_t */ htmlchk_t * htmlchk_init (void); /* destroy htmlchk struct */ void htmlchk_destroy (htmlchk_t * self); /* retrieves page from cache and checks if it contains patterns * asking not to be cached * * returns: * -1 = error occoured * 0 = page is not in cache, or could not be retrieved * 1 = page is in cache and does not need to be removed * 2 = page is in cache and asks to be removed */ int htmlchk_pagestate (htmlchk_t * self, char * url); #endif /* _HTMLCHK_H */ sqcwa-0.3/sqcwa.init.d0100755000175000017500000000220407631436213013772 0ustar cprovcprov#! /bin/sh # # this init.d script was build from an example found at # /etc/init.d/skeleton in a Debian GNU system. # the skeleton file was: # Written by Miquel van Smoorenburg . # Modified for Debian GNU/Linux # by Ian Murdock . PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON=/usr/sbin/sqcwa NAME=sqcwa DESC="Squid Cache Workaround" SQUIDLOG=/var/log/squid/access.log test -x $DAEMON || exit 0 set -e case "$1" in start) echo -n "Starting $DESC: $NAME" start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \ --exec $DAEMON -- $SQUIDLOG echo "." ;; stop) echo -n "Stopping $DESC: $NAME " start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \ --exec $DAEMON echo "." ;; restart|force-reload) echo -n "Restarting $DESC: $NAME" start-stop-daemon --stop --quiet --pidfile \ /var/run/$NAME.pid --exec $DAEMON sleep 1 start-stop-daemon --start --quiet --pidfile \ /var/run/$NAME.pid --exec $DAEMON -- $SQUIDLOG echo "." ;; *) N=/etc/init.d/$NAME echo "Usage: $N {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0 sqcwa-0.3/url.h0100644000175000017500000000201507616003335012513 0ustar cprovcprov/* url -- filters url for characters that would confuse shell Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _URL_H #define _URL_H /* WARNING: urlfil size must be at least 3 times urlunf size */ /* filters url for characters that would confuse shell */ void url_filter (char * urlunf, char * urlfil); #endif sqcwa-0.3/sqclient.h0100644000175000017500000000233207616005173013537 0ustar cprovcprov/* sqclient -- gets a page from squid cache or purge it Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _SQCLIENT_H #define _SQCLIENT_H #define SQUIDCLIENT "/usr/bin/squidclient" /* IMPORTANT: just use it from localhost, never change to other host */ #define SQUIDCLIENTARGS "-h localhost -p 3128" /* returns 1 if successfully retrieved page * returns 0 if could not retrieve */ int sqclient_retrieve_if_in_cache (char * url, char * outfile); void sqclient_purge_from_cache(char * url); #endif /* _SQCLIENT_H */ sqcwa-0.3/daemon.c0100644000175000017500000000477207631441422013163 0ustar cprovcprov/* daemon -- functions for running as daemon Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "daemon.h" #include #include #include #include #include void run_daemon_run (char * name, int uid, int gid) { daemon_fork(); daemon_pid (name); daemon_drop (uid, gid); daemon_tty (); daemon_null (); } void daemon_fork (void) { pid_t pid; pid = fork (); if (pid<0) { perror("fork error"); abort(); } if (pid != 0) { /* parent will terminate */ exit(0); } /* this is the child */ } void daemon_pid (char * name) { FILE * fh; char * s; s = malloc( sizeof(char)* ( strlen(DAEMON_PIDPREFIX) + strlen(name) + strlen(DAEMON_PIDSUFFIX) + 1 )); assert(s != NULL); sprintf(s, "%s%s%s", DAEMON_PIDPREFIX, name, DAEMON_PIDSUFFIX); /* write to PID file */ fh=fopen(s, "w"); /* we will continue without errors if PID file failed */ if (fh != NULL) { fprintf(fh, "%d\n", getpid()); fclose(fh); } free(s); } void daemon_drop (int uid, int gid) { if (gid != -1) { setgid (gid); } if (uid != -1) { setuid (uid); } } void daemon_tty (void) { /* lets remove the controlling tty */ if (setsid() == -1) { /* failed */ perror("setsid error"); abort(); } } void daemon_null (void) { FILE * fh; /* redirect stdin, stdout, stderr to /dev/null */ fh=freopen("/dev/null", "r", stdin); if (fh == NULL) { perror("could not redirect stdin:"); abort(); } fh=freopen("/dev/null", "w", stdout); if (fh == NULL) { perror("could not redirect stdout:"); abort(); } fh=freopen("/dev/null", "w", stderr); if (fh == NULL) { perror("could not redirect stderr:"); abort(); } } sqcwa-0.3/daemon.h0100644000175000017500000000275407631441156013172 0ustar cprovcprov/* daemon -- functions for running as daemon Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _DAEMON_H #define _DAEMON_H #define DAEMON_PIDPREFIX "/var/run/" #define DAEMON_PIDSUFFIX ".pid" void daemon_fork (void); /* forks, terminate parent, child continues */ void daemon_pid (char * name); /* creates /var/run/NAME.pid file */ void daemon_drop (int uid, int gid); /* drop root privileges */ void daemon_tty (void); /* detaches from controlling tty */ void daemon_null (void); /* redirect stdin, stdout, stderr to /dev/null */ /* inspired by the movie Forest Gump */ void run_daemon_run (char * name, int uid, int gid); /* executes _fork, _pid, _drop, _tty and _null */ /* if you do not want run_daemon_run to drop privileges, call it * with uid=-1 and gid=-1 */ #endif sqcwa-0.3/url.c0100644000175000017500000000232507616003403012506 0ustar cprovcprov/* url -- filters url for characters that would confuse shell Copyright (C) 2003 Pedro Zorzenon Neto This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "url.h" #include void url_filter (char * urlunf, char * urlfil) { int i; int j=0; unsigned char c; for (i=0; i