/* (c) @RRL,1996-1998! */ #include "nntp.h" char MsgDBname[] = "nntp$msg"; char GrpDBname[] = "nntp$grp"; char FeedSuckDBname[]= "nntp$feedsuck"; $DESCRIPTOR(msggrp_fao,"!AC !11ZL"); /* */ struct FAB Msgfab; struct XABKEY MsgGrp; struct XABKEY MsgId; char MsgGrp$_knm[] = "News Groups ID + # Article "; char MsgId$_knm[] = "Message ID "; /* */ struct FAB Grpfab; struct XABKEY GrpName; char GrpName$_knm[] = "News Groups ID "; /* */ struct FAB FeedSuckfab; struct RAB FeedSuckrab; struct XABKEY FeedSuckxab; char FeedSuck$_knm[] = " Host_IP ',' News Groups ID "; char DEFEXT [] = ".DB"; /* *-------------------------------------------------------------------------------- */ int MsgDBopen (void) { long status; /* * FAB$ */ Msgfab = cc$rms_fab; Msgfab.fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_UPD | FAB$M_DEL; Msgfab.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT | FAB$M_SHRUPD | FAB$M_SHRDEL; Msgfab.fab$l_fna = MsgDBname; Msgfab.fab$v_mse = 1; Msgfab.fab$b_fns = sizeof(MsgDBname)-1; Msgfab.fab$w_mrs = MSG$_MRS; Msgfab.fab$b_org = FAB$C_IDX; Msgfab.fab$b_rat = FAB$M_CR; Msgfab.fab$l_fop = FAB$M_CIF | FAB$M_CBT; Msgfab.fab$b_rfm = FAB$C_VAR; Msgfab.fab$l_dna = DEFEXT; Msgfab.fab$b_dns = sizeof(DEFEXT)-1; /* * XABKEY$MsgGrp: comp.os.vms,vmsnet.test... + Article number */ MsgGrp = cc$rms_xabkey; MsgGrp.xab$b_ref = MSGGRP$_REF; MsgGrp.xab$b_dtp = XAB$C_STG; MsgGrp.xab$b_flg = XAB$M_DUP; MsgGrp.xab$w_pos0= MSGGRP$_POS; MsgGrp.xab$b_siz0= MSGGRP$_LEN; Msgfab.fab$l_xab = (char* ) &MsgGrp; /* * XABKEY$MsgId: <4358asdfd@petrobank.spb.su>... */ MsgId = cc$rms_xabkey; MsgId.xab$b_ref = MSGID$_REF; MsgId.xab$b_dtp = XAB$C_STG; MsgId.xab$b_flg = XAB$M_DUP; MsgId.xab$w_pos0= MSGID$_POS; MsgId.xab$b_siz0= MSGID$_LEN; MsgGrp.xab$l_nxt = (char *) &MsgId; /* * Open or Create file (if need) */ status = sys$open (&Msgfab); if (! (status & 1)) { MsgGrp.xab$l_knm = MsgGrp$_knm; MsgId.xab$l_knm = MsgId$_knm; status = sys$create (&Msgfab); } return status; } int GrpDBopen (void) { long status; /* * FAB$ */ Grpfab = cc$rms_fab; Grpfab.fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_UPD | FAB$M_DEL; Grpfab.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT | FAB$M_SHRUPD | FAB$M_SHRDEL; Grpfab.fab$l_fna = GrpDBname; Grpfab.fab$v_mse = 1; Grpfab.fab$b_fns = sizeof(GrpDBname)-1; Grpfab.fab$w_mrs = GRPNAME$_MRS; Grpfab.fab$b_org = FAB$C_IDX; Grpfab.fab$b_rat = FAB$M_CR; Grpfab.fab$l_fop = FAB$M_CIF | FAB$M_CBT; Grpfab.fab$b_rfm = FAB$C_VAR; Grpfab.fab$l_dna = DEFEXT; Grpfab.fab$b_dns = sizeof(DEFEXT)-1; /* * XABKEY$GrpName: comp.os.vms,vmsnet.test... */ GrpName = cc$rms_xabkey; GrpName.xab$b_ref = GRPNAME$_REF; GrpName.xab$b_dtp = XAB$C_STG; GrpName.xab$b_flg = 0; GrpName.xab$w_pos0= GRPNAME$_POS; GrpName.xab$b_siz0= GRPNAME$_LEN; Grpfab.fab$l_xab = (char* ) &GrpName; /* * Open or Create file (if need) */ status = sys$open (&Grpfab); if ( !(status & 1)) { GrpName.xab$l_knm = GrpName$_knm; status = sys$create (&Grpfab); } return status; } int FeedSuckDBopen (void) { long status; /* * FAB$ */ FeedSuckfab= cc$rms_fab; FeedSuckfab.fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_UPD | FAB$M_DEL; FeedSuckfab.fab$b_shr = FAB$M_SHRGET | FAB$M_SHRPUT | FAB$M_SHRUPD | FAB$M_SHRDEL; FeedSuckfab.fab$v_mse = 1; FeedSuckfab.fab$l_fna = FeedSuckDBname; FeedSuckfab.fab$b_fns = sizeof(FeedSuckDBname) - 1; FeedSuckfab.fab$w_mrs = FEEDSUCK$_MRS; FeedSuckfab.fab$b_org = FAB$C_IDX; FeedSuckfab.fab$b_rat = FAB$M_CR; FeedSuckfab.fab$l_fop = FAB$M_CIF | FAB$M_CBT; FeedSuckfab.fab$l_dna = DEFEXT; FeedSuckfab.fab$b_dns = sizeof(DEFEXT)-1; /* * XABKEY$SuckName: "194.220.60.71,comp.os.vms" */ FeedSuckxab = cc$rms_xabkey; FeedSuckxab.xab$b_ref = FEEDSUCK$_REF; FeedSuckxab.xab$b_dtp = XAB$C_STG; FeedSuckxab.xab$b_flg = 0; FeedSuckxab.xab$w_pos0= FEEDSUCK$_POS; FeedSuckxab.xab$b_siz0= FEEDSUCK$_LEN; FeedSuckfab.fab$l_xab = (char *) &FeedSuckxab; /* * Open or Create file (if need) */ status = sys$open (&FeedSuckfab); if (! (status & 1)) { FeedSuckxab.xab$l_knm = FeedSuck$_knm; status = sys$create (&FeedSuckfab); } return status; } /* *-------------------------------------------------------------------------------- * Allocate RAB & buffers, open stream's */ int MsgDBopen_stream (struct RAB *rabp) { long status; *rabp = cc$rms_rab; rabp->rab$l_fab = &Msgfab; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$v_wat = 1; /* Wait if record is current locked, */ rabp->rab$b_tmo = 250; /* 250 second before return */ status = sys$connect (rabp); rabp->rab$v_nlk = 1; return status; } /* *-------------------------------------------------------------------------------- */ int GrpDBopen_stream (struct RAB *rabp) { long status; *rabp = cc$rms_rab; rabp->rab$l_fab = &Grpfab; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$v_wat = 1; /* Wait if record is currently locked */ rabp->rab$b_tmo = 250; /* 250 second before return */ rabp->rab$v_uif = 1; /* Update if record (primary key) exist */ return sys$connect (rabp); } /* *-------------------------------------------------------------------------------- */ int FeedSuckDBopen_stream (struct RAB *rabp) { long status; *rabp = cc$rms_rab; rabp->rab$l_fab = &FeedSuckfab; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$v_uif = 1; status = sys$connect (rabp); rabp->rab$v_nlk = 1; return status; } /* *-------------------------------------------------------------------------------- * Close stream's */ int DBclose_stream (struct RAB *rabp) { long status; status = sys$flush(rabp); status = sys$free (rabp); return sys$disconnect(rabp); } /* *-------------------------------------------------------------------------------- * Open databases */ int DBopen (void) { long status; status = MsgDBopen(); if (! (status & 1)) lib$signal(status); status = GrpDBopen(); if (! (status & 1)) lib$signal(status); status = FeedSuckDBopen(); if (! (status & 1)) lib$signal(status); return status; } /* *-------------------------------------------------------------------------------- * Close databases */ int DBclose (void) { long status; status = sys$close (&Msgfab); if (! (status & 1)) lib$signal(status); status = sys$close (&Grpfab); if (! (status & 1)) lib$signal(status); status = sys$close (&FeedSuckfab); if (! (status & 1)) lib$signal(status); return SS$_NORMAL; } /* *-------------------------------------------------------------------------------- */ int MsgDBfind_byId ( struct RAB *mrabp, char *MsgId, ushort MsgIdL ) { long status; mrabp->rab$b_krf = MSGID$_REF; mrabp->rab$b_rac = RAB$C_KEY; mrabp->rab$l_kbf = MsgId; mrabp->rab$b_ksz = MsgIdL; mrabp->rab$v_nlk = 1; return sys$find (mrabp); } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byId ( struct RAB *mrabp, char *msgid, ushort msgidlen, msgrec_t *mrec, ushort *mreclen ) { long status; mrabp->rab$b_krf = MSGID$_REF; mrabp->rab$b_rac = RAB$C_KEY; mrabp->rab$l_kbf = msgid; mrabp->rab$b_ksz = msgidlen; mrabp->rab$l_ubf = (char *) mrec; mrabp->rab$w_usz = sizeof(msgrec_t); mrabp->rab$v_nlk = 1; status = sys$get (mrabp); *mreclen= mrabp->rab$w_rsz - MSGBODY$_POS; return status; } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byNum ( struct RAB *mrabp, grprec_t *grec, ulong MsgIdx, msgrec_t *mrec, ushort *mreclen ) { long status; struct dsc$descriptor_s key_dsc; /* ** Perfom GroupName + Number article's key generation */ INIT_SDESC(key_dsc,MSGGRP$_LEN,mrec->_t_gid); status = sys$fao(&msggrp_fao,&key_dsc.dsc$w_length,&key_dsc, &grec->_ac_grp,MsgIdx); if ( !(status & 1) ) return status; mrabp->rab$b_krf = MSGGRP$_REF; mrabp->rab$b_rac = RAB$C_KEY; mrabp->rab$l_kbf = key_dsc.dsc$a_pointer; mrabp->rab$b_ksz = key_dsc.dsc$w_length; mrabp->rab$l_ubf = (char *) mrec; mrabp->rab$w_usz = sizeof(msgrec_t); mrabp->rab$v_nlk = 1; status = sys$get (mrabp); if (! (status & 1)) return status; /* ** Check for reference and get message body by Mess-ID */ if ( mrec->_t_mid[0] == '>' ) { mrec->_t_mid[0] = '<'; return MsgDBget_byId(mrabp,mrec->_t_mid,mrec->_w_midlen, mrec,mreclen); } *mreclen= mrabp->rab$w_rsz - MSGBODY$_POS; return status; } /* *-------------------------------------------------------------------------------- */ int MsgDBdel (struct RAB *mrabp) { long status; mrabp->rab$v_nlk = 0; while (1 & (status = sys$find (mrabp)) ) { status = sys$delete (mrabp); if (! (status & 1)) break; } return status; } /* *-------------------------------------------------------------------------------- */ int GrpDBget ( struct RAB *grabp, grprec_t *grec, int lockf, int rewindf, int racf ) { long status; grabp->rab$b_krf = GRPNAME$_REF; grabp->rab$b_rac = (racf?RAB$C_SEQ:RAB$C_KEY); grabp->rab$l_kbf = grec->_t_name; grabp->rab$b_ksz = grec->_b_len; grabp->rab$l_ubf = (char *) grec; grabp->rab$w_usz = sizeof(grprec_t); grabp->rab$v_nlk = (lockf?0:1); if (!rewindf) { status = sys$rewind (grabp); if (! (status & 1)) return status; } return sys$get (grabp); } /* *-------------------------------------------------------------------------------- */ int GrpDBfree (struct RAB *grabp) { return sys$free (grabp); } /* *-------------------------------------------------------------------------------- */ int GrpDBput ( struct RAB *grabp, grprec_t *grec ) { long status; grabp->rab$b_rac = RAB$C_KEY; grabp->rab$b_krf = GRPNAME$_REF; grabp->rab$l_kbf = grec->_t_name; grabp->rab$b_ksz = grec->_b_len; grabp->rab$l_rbf = (char *) grec; grabp->rab$w_rsz = sizeof(grprec_t); status = sys$put (grabp); sys$free (grabp); if ( !(1&status) ) lib$signal(status,grabp->rab$l_stv); return status; } /* *-------------------------------------------------------------------------------- */ int DBins ( struct RAB *grabp, struct RAB *mrabp, grprec_t *grec, time_t Date, msgrec_t *mrec, ushort mreclen ) { long status,faostatus; struct dsc$descriptor_s out_dsc; /* ** Get group's information with LOCK */ grabp->rab$b_krf = GRPNAME$_REF; grabp->rab$b_rac = RAB$C_KEY; grabp->rab$l_kbf = grec->_t_name; grabp->rab$b_ksz = grec->_b_len; grabp->rab$l_ubf = (char *) grec; grabp->rab$w_usz = sizeof(grprec_t); grabp->rab$v_nlk = 0; status = sys$get (grabp); if (! (status & 1)) { sys$free(grabp); return status; } /* ** Check allowing of a post operation */ if ( 'n' == grec->_c_postflag ) { sys$free(grabp); return SS$_ABORT; } /* ** Perform neccesary modification in the group record */ grec->_l_datecr = (grec->_l_datecr == 0?Date:grec->_l_datecr); grec->_l_first = (grec->_l_first == 0?1:grec->_l_first); grec->_l_last++; /* ** Check for presence of the article in the database */ mrabp->rab$b_krf = MSGID$_REF; mrabp->rab$b_rac = RAB$C_KEY; mrabp->rab$l_kbf = mrec->_t_mid; mrabp->rab$b_ksz = mrec->_w_midlen; status = sys$find (mrabp); memset(mrec->_t_gid,0,sizeof(mrec->_t_gid)); INIT_SDESC(out_dsc,MSGGRP$_LEN,mrec->_t_gid); faostatus = sys$fao(&msggrp_fao,&mrec->_w_gidlen,&out_dsc, &grec->_ac_grp,grec->_l_last); if ( !(faostatus & 1) ) return faostatus; mrabp->rab$l_rbf = (char *) mrec; mrabp->rab$w_rsz = mreclen + MSGBODY$_POS; mrec->_l_date = Date; grec->_l_dateup = Date; if ( status != RMS$_RNF ) { mrec->_t_mid[0] = '>'; mrabp->rab$w_rsz = mreclen; } status = sys$put (mrabp); if (status & 1) { grabp->rab$l_rbf = (char *) grec; grabp->rab$w_rsz = sizeof(grprec_t); status = sys$put (grabp); } sys$free(grabp); return status;; } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byRange ( struct RAB *mrabp, grprec_t *grec, ulong from, ulong to, msgrec_t *mrec, ushort *msgreclen, char *LimKey, ushort *LimKeysz ) { long status; struct dsc$descriptor_s out_dsc; mrabp->rab$b_krf = MSGGRP$_REF; mrabp->rab$l_ubf = (char *) mrec; mrabp->rab$w_usz = sizeof(msgrec_t); mrabp->rab$v_nlk = 1; if ( !(*LimKeysz) ) { INIT_SDESC(out_dsc,MSGGRP$_LEN,LimKey); status = sys$fao(&msggrp_fao,LimKeysz,&out_dsc, &grec->_ac_grp,to); if ( !(status & 1) ) return status; INIT_SDESC(out_dsc,MSGGRP$_LEN,mrec->_t_gid); status = sys$fao(&msggrp_fao,LimKeysz,&out_dsc, &grec->_ac_grp,from); if ( !(status & 1) ) return status; mrabp->rab$b_rac = RAB$C_KEY; mrabp->rab$b_krf = MSGGRP$_REF; mrabp->rab$l_kbf = mrec->_t_gid; mrabp->rab$b_ksz = *LimKeysz; status = sys$get (mrabp); *msgreclen = mrabp->rab$w_rsz - MSGBODY$_POS; return status; } mrabp->rab$b_rac = RAB$C_SEQ; mrabp->rab$v_lim = 1; mrabp->rab$l_kbf = LimKey; mrabp->rab$b_ksz = *LimKeysz; status = sys$get (mrabp); *msgreclen = mrabp->rab$w_rsz - MSGBODY$_POS; return status; } /* *-------------------------------------------------------------------------------- */ int FeedSuckDBget ( struct RAB *rabp, fsrec_t *fsrec ) { long status; rabp->rab$b_krf = FEEDSUCK$_REF; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = fsrec->_t_hash; rabp->rab$b_ksz = sizeof(fsrec->_t_hash); rabp->rab$l_ubf = (char *) fsrec; rabp->rab$w_usz = sizeof(fsrec_t); return sys$get (rabp); } /* *-------------------------------------------------------------------------------- */ int FeedSuckDBput ( struct RAB *rabp, fsrec_t *fsrec ) { rabp->rab$b_krf = FEEDSUCK$_REF; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = fsrec->_t_hash; rabp->rab$b_ksz = sizeof(fsrec->_t_hash); rabp->rab$l_rbf = (char *) fsrec; rabp->rab$w_rsz = sizeof(fsrec_t); return sys$put (rabp); }