X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=loaders.c;h=c62a399841fb8d75696e8198b0d0bc0e0fe05ec4;hp=d68b40dbc4fc6e50de616bf11655c3597b58a06a;hb=7600ab8fcf587195f51d2faf6e92d1d1a2e24fd0;hpb=994e35d0510a22346d510eee39829f91a2f13387 diff --git a/loaders.c b/loaders.c index d68b40db..c62a3998 100644 --- a/loaders.c +++ b/loaders.c @@ -1,4 +1,4 @@ -const char loaders_rcs[] = "$Id: loaders.c,v 1.74 2009/09/26 13:29:57 fabiankeil Exp $"; +const char loaders_rcs[] = "$Id: loaders.c,v 1.81 2011/03/03 14:38:36 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/loaders.c,v $ @@ -8,7 +8,7 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.74 2009/09/26 13:29:57 fabiankeil * the list of active loaders, and to automatically * unload files that are no longer in use. * - * Copyright : Written by and Copyright (C) 2001-2009 the + * Copyright : Written by and Copyright (C) 2001-2010 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -114,7 +114,8 @@ static struct file_list *current_re_filterfile[MAX_AF_FILES] = { unsigned int sweep(void) { struct file_list *fl, *nfl; - struct client_state *csp, *last_active; + struct client_state *csp; + struct client_states *last_active, *client_list; int i; unsigned int active_threads = 0; @@ -125,10 +126,11 @@ unsigned int sweep(void) } last_active = clients; - csp = clients->next; + client_list = clients->next; - while (NULL != csp) + while (NULL != client_list) { + csp = &client_list->csp; if (csp->flags & CSP_FLAG_ACTIVE) { /* Mark this client's files as active */ @@ -174,15 +176,15 @@ unsigned int sweep(void) active_threads++; - last_active = csp; - csp = csp->next; + last_active = client_list; + client_list = client_list->next; } else /* * This client is not active. Free its resources. */ { - last_active->next = csp->next; + last_active->next = client_list->next; freez(csp->ip_addr_str); freez(csp->iob->buf); @@ -208,9 +210,9 @@ unsigned int sweep(void) } #endif /* def FEATURE_STATISTICS */ - freez(csp); + freez(client_list); - csp = last_active->next; + client_list = last_active->next; } } @@ -357,7 +359,7 @@ jb_err simple_read_line(FILE *fp, char **dest, int *newline) p = buf; /* - * Character codes. If you have a wierd compiler and the following are + * Character codes. If you have a weird compiler and the following are * incorrect, you also need to fix NEWLINE() in loaders.h */ #define CHAR_CR '\r' /* ASCII 13 */ @@ -735,41 +737,27 @@ jb_err edit_read_line(FILE *fp, * and respects escaping of newline and comment char. * * Parameters : - * 1 : buf = Buffer to use. - * 2 : buflen = Size of buffer in bytes. - * 3 : fp = File to read from - * 4 : linenum = linenumber in file + * 1 : fp = File to read from + * 2 : linenum = linenumber in file + * 3 : buf = Pointer to a pointer to set to the data buffer. * * Returns : NULL on EOF or error * Otherwise, returns buf. * *********************************************************************/ -char *read_config_line(char *buf, size_t buflen, FILE *fp, unsigned long *linenum) +char *read_config_line(FILE *fp, unsigned long *linenum, char **buf) { jb_err err; - char *buf2 = NULL; - err = edit_read_line(fp, NULL, NULL, &buf2, NULL, linenum); + err = edit_read_line(fp, NULL, NULL, buf, NULL, linenum); if (err) { if (err == JB_ERR_MEMORY) { log_error(LOG_LEVEL_FATAL, "Out of memory loading a config file"); } - return NULL; - } - else - { - assert(buf2); - if (strlen(buf2) + 1U > buflen) - { - log_error(LOG_LEVEL_FATAL, - "Max line limit reached. Linenumber: %u. Lenght: %u. Max lenght: %u.", - *linenum, strlen(buf2), buflen-1); - } - strlcpy(buf, buf2, buflen); - free(buf2); - return buf; + *buf = NULL; } + return *buf; } @@ -847,7 +835,7 @@ int load_trustfile(struct client_state *csp) struct block_spec *b, *bl; struct url_spec **tl; - char buf[BUFFER_SIZE], *p, *q; + char *buf = NULL; int reject, trusted; struct file_list *fs; unsigned long linenum = 0; @@ -856,10 +844,7 @@ int load_trustfile(struct client_state *csp) if (!check_file_changed(current_trustfile, csp->config->trustfile, &fs)) { /* No need to load */ - if (csp) - { - csp->tlist = current_trustfile; - } + csp->tlist = current_trustfile; return(0); } if (!fs) @@ -881,7 +866,7 @@ int load_trustfile(struct client_state *csp) tl = csp->config->trust_list; - while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL) + while (read_config_line(fp, &linenum, &buf) != NULL) { trusted = 0; reject = 1; @@ -894,6 +879,9 @@ int load_trustfile(struct client_state *csp) if (*buf == '~') { + char *p; + char *q; + reject = 0; p = buf; q = p+1; @@ -906,6 +894,7 @@ int load_trustfile(struct client_state *csp) /* skip blank lines */ if (*buf == '\0') { + freez(buf); continue; } @@ -939,6 +928,7 @@ int load_trustfile(struct client_state *csp) *tl++ = b->url; } } + freez(buf); } if(trusted_referrers >= MAX_TRUSTED_REFERRERS) @@ -970,12 +960,12 @@ int load_trustfile(struct client_state *csp) { csp->tlist = fs; } - return(0); load_trustfile_error: log_error(LOG_LEVEL_FATAL, "can't load trustfile '%s': %E", - csp->config->trustfile); + csp->config->trustfile); + freez(buf); return(-1); } @@ -1132,7 +1122,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) struct re_filterfile_spec *new_bl, *bl = NULL; struct file_list *fs; - char buf[BUFFER_SIZE]; + char *buf = NULL; int error; unsigned long linenum = 0; pcrs_job *dummy, *lastjob = NULL; @@ -1166,7 +1156,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) /* * Read line by line */ - while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL) + while (read_config_line(fp, &linenum, &buf) != NULL) { int new_filter = NO_NEW_FILTER; @@ -1250,6 +1240,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) log_error(LOG_LEVEL_RE_FILTER, "Reading in filter \"%s\" (\"%s\")", bl->name, bl->description); + freez(buf); continue; } @@ -1281,6 +1272,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) bl->dynamic = 1; log_error(LOG_LEVEL_RE_FILTER, "Adding dynamic re_filter job \'%s\' to filter %s succeeded.", buf, bl->name); + freez(buf); continue; } else if (bl->dynamic) @@ -1292,6 +1284,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) */ log_error(LOG_LEVEL_RE_FILTER, "Adding static re_filter job \'%s\' to dynamic filter %s succeeded.", buf, bl->name); + freez(buf); continue; } @@ -1299,6 +1292,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) { log_error(LOG_LEVEL_ERROR, "Adding re_filter job \'%s\' to filter %s failed with error %d.", buf, bl->name, error); + freez(buf); continue; } else @@ -1320,6 +1314,7 @@ int load_one_re_filterfile(struct client_state *csp, int fileid) log_error(LOG_LEVEL_ERROR, "Ignoring job %s outside filter block in %s, line %d", buf, csp->config->re_filterfile[fileid], linenum); } + freez(buf); } fclose(fp); @@ -1420,6 +1415,68 @@ int run_loader(struct client_state *csp) } +/********************************************************************* + * + * Function : file_has_been_modified + * + * Description : Helper function to check if a file has been changed + * + * Parameters : + * 1 : filename = The name of the file to check + * 2 : last_known_modification = The time of the last known + * modification + * + * Returns : TRUE if the file has been changed, + * FALSE otherwise. + * + *********************************************************************/ +static int file_has_been_modified(const char *filename, time_t last_know_modification) +{ + struct stat statbuf[1]; + + if (stat(filename, statbuf) < 0) + { + /* Error, probably file not found which counts as change. */ + return 1; + } + + return (last_know_modification != statbuf->st_mtime); +} + + +/********************************************************************* + * + * Function : any_loaded_file_changed + * + * Description : Helper function to check if any loaded file has been + * changed since the time it has been loaded. + * + * XXX: Should we cache the return value for x seconds? + * + * Parameters : + * 1 : files_to_check = List of files to check + * + * Returns : TRUE if any file has been changed, + * FALSE otherwise. + * + *********************************************************************/ +int any_loaded_file_changed(const struct file_list *files_to_check) +{ + const struct file_list *file_to_check = files_to_check; + + while (file_to_check != NULL) + { + if (file_has_been_modified(file_to_check->filename, file_to_check->lastmodified)) + { + log_error(LOG_LEVEL_INFO, + "File modification detected: %s", file_to_check->filename); + return TRUE; + } + file_to_check = file_to_check->next; + } + return FALSE; +} + /* Local Variables: