#pragma module NNTP_EXPIRE "NNTP_EXPIRE-1-A" /* **++ ** FACILITY: NNTP server for OpenVMS ** ** MODULE DESCRIPTION: ** ** This module contains all routines to performs a puring of articles in the NNTP database. ** ** AUTHORS: ** ** Copyright (c) 1996-2002 Ruslan R. Laishev (@RRL) ** ** CREATION DATE: ??-???-1996 ** ** ** MODIFICATION HISTORY: ** ** 4-FEB-2006 RRL Some cosmetic changes. ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include "nntp.h" extern int exit_flag; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Purging articles in a given group with given date/time range. ** ** FORMAL PARAMETERS: ** ** Wctxp: A worker's context buffer ** mt: A low limit of a date range ** ct: A high limit of a time range ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int nntp_expire_group ( WCTX *Wctxp, time_t mt, time_t ct ) { long status; ulong Purged = 0,Skiped = 0; ushort sz,sz0,sz1; char buf0[32],buf1[32]; /* ** Debug stuff */ cvt_vms_to_nntp(Wctxp->wctx$r_grec.grp$l_datecr,buf0,&sz0); cvt_vms_to_nntp(Wctxp->wctx$r_grec.grp$l_dateup,buf1,&sz1); NNTP_LOGT(Wctxp,LOG$K_WAR,"%.*s|%.*s%11lu|%11lu|%c|%c|%.*s", sz0,buf0,sz1,buf1, Wctxp->wctx$r_grec.grp$l_first,Wctxp->wctx$r_grec.grp$l_last, Wctxp->wctx$r_grec.grp$b_post?'y':' ', Wctxp->wctx$r_grec.grp$b_suck?'y':' ', Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname); /* ** Run over all articles in a given group check an old of an article ** and skip or delete it */ for (;!exit_flag && (Wctxp->wctx$r_grec.grp$l_first < Wctxp->wctx$r_grec.grp$l_last); Wctxp->wctx$r_grec.grp$l_first++) { /* ** Get next article in the given group */ status = MsgDBget_byNum (&Wctxp->wctx$r_mrab,&Wctxp->wctx$r_grec, Wctxp->wctx$r_grec.grp$l_first, &Wctxp->wctx$r_mrec,&sz); /* ** If article is not found just go to next article # */ if ( status == RMS$_RNF ) { Skiped++; continue; } if ( !$VMS_STATUS_SUCCESS(status) ) { NNTP_LOGT(Wctxp,LOG$K_ERR,"'%.*s', ARTICLE #%u-Can't be retrived,(status = %u)", Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname,Wctxp->wctx$r_grec.grp$l_first,status); Skiped++; continue; } /* ** Is this article is not too old or a date is not in a future ? */ if ( (Wctxp->wctx$r_mrec.msg$l__date > mt) && (Wctxp->wctx$r_mrec.msg$l__date < ct) ) break; /* ** Delete an expired article */ if ( !(1 & (status = MsgDBdel_byNum (&Wctxp->wctx$r_mrab,&Wctxp->wctx$r_grec, Wctxp->wctx$r_grec.grp$l_first, &Wctxp->wctx$r_mrec))) ) { NNTP_LOGT(Wctxp,LOG$K_FAT,"Can't delete '%.*s', ARTICLE #%u %.*s,(status = %u)", Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname, Wctxp->wctx$r_grec.grp$l_first, Wctxp->wctx$r_mrec.msg$w_midlen,Wctxp->wctx$r_mrec.msg$t_mid,status); break; } Purged++; } /* ** Debug stuff */ cvt_vms_to_nntp(Wctxp->wctx$r_grec.grp$l_datecr,buf0,&sz0); cvt_vms_to_nntp(Wctxp->wctx$r_grec.grp$l_dateup,buf1,&sz1); NNTP_LOGT(Wctxp,LOG$K_WAR,"%.*s|%.*s%11lu|%11lu|%c|%c|%.*s", sz0,buf0,sz1,buf1, Wctxp->wctx$r_grec.grp$l_first,Wctxp->wctx$r_grec.grp$l_last, Wctxp->wctx$r_grec.grp$b_post?'y':' ', Wctxp->wctx$r_grec.grp$b_suck?'y':' ', Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname); /* ** Return a total processed articles count */ return (Purged + Skiped); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** A main entry of the purging/expiration procedure to performs ** a purging, group switching from active to passive. ** ** FORMAL PARAMETERS: ** ** Wctxp: A worker's context buffer ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int nntp_expire ( WCTX *Wctxp ) { int status,rewindf = 0,updflag; time_t gt,mt,ct; NNTP_LOGT(Wctxp,LOG$K_WAR, "DateCr |DateUp |First msg#| Last msg#|P|S|Group Name...."); /* ** Compute a time range to matching with an article date */ time(&ct); gt = ct - (nntp_conf._w_grpday*24*60*60); mt = ct - (nntp_conf._w_msgpurgeday*24*60*60); /* ** Run over group database check and performs a purging... */ while ( !exit_flag && (1 & (status = GrpDBget(&Wctxp->wctx$r_grab,&Wctxp->wctx$r_grec,0,rewindf++,1))) ) { updflag = 0; /* ** Check that group is not epmty */ if ( Wctxp->wctx$r_grec.grp$l_first || Wctxp->wctx$r_grec.grp$l_last ) { /* ** Lock group record for changes */ if ( !(1 & (status = GrpDBget(&Wctxp->wctx$r_grab,&Wctxp->wctx$r_grec,1,0,0))) ) { NNTP_LOGT(Wctxp,LOG$K_ERR,"GrpDBget('%.*s'),(status = %u)", Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname); continue; } /* ** Purging message database for in a selected group */ updflag = nntp_expire_group (Wctxp,mt,ct); } /* ** If group is expiried - clear suck flag */ if ( Wctxp->wctx$r_grec.grp$b_suck && (gt > (max(Wctxp->wctx$r_grec.grp$l_dateup,Wctxp->wctx$r_grec.grp$l_datecr))) ) { NNTP_LOGT(Wctxp,LOG$K_INF,"%.*s is switched to passive", Wctxp->wctx$r_grec.grp$b_grplen,Wctxp->wctx$r_grec.grp$t_grpname); Wctxp->wctx$r_grec.grp$b_suck = 0; updflag = 1; } /* ** It need to update a group record ? */ if ( updflag && !(1 & (status = GrpDBput(&Wctxp->wctx$r_grab,&Wctxp->wctx$r_grec))) ) NNTP_LOGT(Wctxp,LOG$K_FAT,"Update GrpDB,(status = %u).",status); else GrpDBfree(&Wctxp->wctx$r_grab); } /* ** If we reach an end of group database file - return Ok status */ return status==RMS$_EOF?SS$_NORMAL:status; }