/* * $Id: text-garb.c,v 0.23 1998/07/08 13:42:05 ceder Exp $ * Copyright (C) 1991, 1992, 1993, 1994, 1995 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please mail bug reports to bug-lyskom@lysator.liu.se. */ /* * This file contains the functions that deletes old texts. * * Author: Per Cederqvist. */ static const char * rcsid = "$Id: text-garb.c,v 0.23 1998/07/08 13:42:05 ceder Exp $"; #include "rcs.h" USE(rcsid); #include #include #include #ifdef HAVE_STDARG_H # include #endif #include "ldifftime.h" #include "s-string.h" #include "kom-types.h" #include "text-garb.h" #include "misc-types.h" #include "debug.h" #include "cache.h" #include "lyskomd.h" #include "log.h" #include "internal-services.h" #include "param.h" /* * This comment is a description of how this _could_ be done in a more * efficient way. It is not yet implemented. Design by Inge Wallin * and Per Cederqvist 1992-10-07. +++FIXME. * * Today, all text statuses are read into the core during the garbage * collection phase. Due to step 3 below we think that we can reduce * the number of text-status-fetches by 95 %. * * 1) Allocate a bitmap with one bit for each text. Clear all bits. * This bit is set as soon as it is certain that this text should * not be deleted during this garbage collection pass. * 2) Loop over all persons: * + Set the bit for all his/her marked texts. * (This step may, or may not, be efficient. Profile your code!) * 3) Loop over all conferences: * + Loop over all texts in the conference: * + If the bit is already set, skip the text. * + Retrieve the text status from the data base. * + If it is old enough (in all the recipient conferences) * delete it. * else * set the bit. * + If it is too young to be deleted (only * considering this conferene) * + Set the bit for this text and all subsequent * texts in this conference. * 4) Loop over all remaining texts: * + If the bit is not set, * + delete the text. (It has no recipients). * 5) Deallocate the bitmap and wait 24 hours. */ /* * Delete old texts. * * Return value is TRUE if there is nothing more to do right now, * FALSE if this function should be called again as soon as the * server has some time over. */ Bool garb_text(void) { static Text_no last_checked = 0; static time_t last_start = NO_TIME; static long deleted_texts = 0; BUGDECL; Text_stat *text_s; Misc_info *misc; u_short nmisc, naux; double age; /* How many seconds is this text? */ double limit = 24 * 3600; if (param.garb_enable == FALSE) return TRUE; if ( last_checked == 0 ) { if ( last_start != NO_TIME && ldifftime(time(NULL), last_start) < param.garb_interval * 60 ) { return TRUE; } log("MSG: garb started.\n"); time( &last_start ); } tell_cache_garb_text(1); last_checked = traverse_text( last_checked ); if ( last_checked == 0 ) { log("MSG: garb ready. %lu texts deleted.\n", (u_long)deleted_texts); deleted_texts = 0; tell_cache_garb_text(0); return FALSE; } if ( (text_s = cached_get_text_stat( last_checked )) == NULL ) { log("ERROR: garb_text(): Can't get text-stat.\n"); tell_cache_garb_text(0); return FALSE; } age = ldifftime( time(NULL), text_s->creation_time ); if ( text_s->no_of_marks > 0 || age < 24 * 3600 ) { tell_cache_garb_text(0); return FALSE; } for (naux = 0; naux < text_s->aux_item_list.length; --naux) { if (text_s->aux_item_list.items[naux].flags.dont_garb) { tell_cache_garb_text(0); return FALSE; } } for (nmisc = text_s->no_of_misc, misc = text_s->misc_items; nmisc > 0; --nmisc, ++misc ) { switch ( misc->type ) { case recpt: if ( cached_conf_exists( misc->datum.recipient ) ) { limit = (24 * 3600 * cached_get_garb_nice( misc->datum.recipient )); if ( age < limit ) { tell_cache_garb_text(0); return FALSE; } } break; case cc_recpt: if ( cached_conf_exists( misc->datum.cc_recipient )) { limit = ( 24 * 3600 * cached_get_garb_nice( misc->datum.cc_recipient )); if ( age < limit ) { tell_cache_garb_text(0); return FALSE; } } break; case bcc_recpt: if ( cached_conf_exists( misc->datum.bcc_recipient )) { limit = ( 24 * 3600 * cached_get_garb_nice( misc->datum.bcc_recipient )); if ( age < limit ) { tell_cache_garb_text(0); return FALSE; } } break; case comm_to: case comm_in: case footn_to: case footn_in: limit = 24 * 3600; break; case loc_no: case rec_time: case sent_by: break; case sent_at: if ( ldifftime ( time(NULL), misc->datum.sent_at ) < limit ) { tell_cache_garb_text(0); return FALSE; } break; #ifndef COMPILE_CHECKS default: restart_kom("garb_text(): Illegal misc-item.\n"); #endif } } VBUG(("garb_text: deleting %lu\n", last_checked)); do_delete_text ( last_checked, text_s ); deleted_texts++; tell_cache_garb_text(0); return FALSE; }