#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: ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include "nntp.h" /* **++ ** 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_t *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->grec._l_datecr,buf0,&sz0); cvt_vms_to_nntp(Wctxp->grec._l_dateup,buf1,&sz1); NNTP_LOGT(Wctxp,LOGW,"%.*s|%.*s%11lu|%11lu|%c|%c|%.*s", sz0,buf0,sz1,buf1, Wctxp->grec._l_first,Wctxp->grec._l_last, Wctxp->grec._c_postflag?'y':' ', Wctxp->grec._c_suckflag?'y':' ', Wctxp->grec._b_len,Wctxp->grec._t_name); /* ** Run over all articles in a given group check an old of an article ** and skip or delete it */ for (;Wctxp->grec._l_first < Wctxp->grec._l_last;Wctxp->grec._l_first++) { /* ** Get next article in the given group */ status = MsgDBget_byNum (&Wctxp->_s_msgrab,&Wctxp->grec, Wctxp->grec._l_first, &Wctxp->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,LOGE,"'%.*s', ARTICLE #%u-Can't be retrived,(status = %u)", Wctxp->grec._b_len,Wctxp->grec._t_name,Wctxp->grec._l_first,status); Skiped++; continue; } /* ** Is this article is not too old or a date is not in a future ? */ if ( (Wctxp->mrec._l_date > mt) && (Wctxp->mrec._l_date < ct) ) break; /* ** Delete an expired article */ if ( !(1 & (status = MsgDBdel_byNum (&Wctxp->_s_msgrab,&Wctxp->grec, Wctxp->grec._l_first, &Wctxp->mrec))) ) { NNTP_LOGT(Wctxp,LOGF,"Can't delete '%.*s', ARTICLE #%u %.*s,(status = %u)", Wctxp->grec._b_len,Wctxp->grec._t_name, Wctxp->grec._l_first, Wctxp->mrec._w_midlen,Wctxp->mrec._t_mid,status); break; } Purged++; } /* ** Debug stuff */ cvt_vms_to_nntp(Wctxp->grec._l_datecr,buf0,&sz0); cvt_vms_to_nntp(Wctxp->grec._l_dateup,buf1,&sz1); NNTP_LOGT(Wctxp,LOGW,"%.*s|%.*s%11lu|%11lu|%c|%c|%.*s", sz0,buf0,sz1,buf1, Wctxp->grec._l_first,Wctxp->grec._l_last, Wctxp->grec._c_postflag?'y':' ', Wctxp->grec._c_suckflag?'y':' ', Wctxp->grec._b_len,Wctxp->grec._t_name); /* ** 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_t *Wctxp ) { int status,rewindf = 0,updflag; time_t gt,mt,ct; NNTP_LOGT(Wctxp,LOGW, "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 ( 1 & (status = GrpDBget(&Wctxp->_s_grprab,&Wctxp->grec,0,rewindf++,1)) ) { updflag = 0; /* ** Check that group is not epmty */ if ( Wctxp->grec._l_first || Wctxp->grec._l_last ) { /* ** Lock group record for changes */ if ( !(1 & (status = GrpDBget(&Wctxp->_s_grprab,&Wctxp->grec,1,0,0))) ) { NNTP_LOGT(Wctxp,LOGE,"GrpDBget('%.*s'),(status = %u)", Wctxp->grec._b_len,Wctxp->grec._t_name); 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->grec._c_suckflag && (gt > (max(Wctxp->grec._l_dateup,Wctxp->grec._l_datecr))) ) { NNTP_LOGT(Wctxp,LOGI,"%.*s is switched to passive", Wctxp->grec._b_len,Wctxp->grec._t_name); Wctxp->grec._c_suckflag = 0; updflag = 1; } /* ** It need to update a group record ? */ if ( updflag && !(1 & (status = GrpDBput(&Wctxp->_s_grprab,&Wctxp->grec))) ) NNTP_LOGT(Wctxp,LOGF,"Update GrpDB,(status = %u).",status); else GrpDBfree(&Wctxp->_s_grprab); } /* ** If we reach an end of group database file - return Ok status */ return status==RMS$_EOF?SS$_NORMAL:status; }