/* Copyright (c) 1996, Ruslan R. Laishev (@RRL) */ #include "nntp.h" #include "nntp_rms.h" #include "nntp_log.h" #include "nntp_lib.h" char *MsgDBname = "nntp$msg.db"; char *GrpDBname = "nntp$grp.db"; char *MsgBuff; /* */ struct FAB Msgfab; struct XABKEY MsgGrp; struct XABKEY MsgId; struct XABKEY MsgDate; char *MsgGrp$_knm = "News Groups ID + Date/Time "; char *MsgId$_knm = "Message ID "; char *MsgDate$_knm = "Message Date/Time "; /* */ struct FAB Grpfab; struct XABKEY GrpName; char *GrpName$_knm = "News Groups ID "; /* *-------------------------------------------------------------------------------- */ /* Open all files of DataSet:Msg,Grp -*.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; /* read/write sharing */ Msgfab.fab$l_fna = MsgDBname; Msgfab.fab$v_mse = 1; /* multistream */ Msgfab.fab$b_fns = strlen(MsgDBname); Msgfab.fab$w_mrs = Msg_MaxRec; /* record size */ Msgfab.fab$b_org = FAB$C_IDX; Msgfab.fab$b_rat = FAB$M_CR; /* implied carriage return */ Msgfab.fab$l_fop = FAB$M_CIF | FAB$M_CBT; Msgfab.fab$b_rfm = FAB$C_VAR; /* * XABKEY$MsgGrp: comp.os.vms,vmsnet.test... + Date/Time in ASCII format */ 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; /* * XABKEY$MsgDate: Message Date/Time in time_t format */ MsgDate = cc$rms_xabkey; MsgDate.xab$b_ref = MsgDate$_ref; MsgDate.xab$b_dtp = XAB$C_BN4; MsgDate.xab$b_flg = XAB$M_DUP; MsgDate.xab$w_pos0= MsgDate$_pos; MsgDate.xab$b_siz0= MsgDate$_len; MsgId.xab$l_nxt = (char *) &MsgDate; /* * 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; MsgDate.xab$l_knm = MsgDate$_knm; status = sys$create (&Msgfab); } return (nntp_log_err(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; /* read/write sharing */ Grpfab.fab$l_fna = GrpDBname; Grpfab.fab$v_mse = 1; /* multistream */ Grpfab.fab$b_fns = strlen(GrpDBname); Grpfab.fab$w_mrs = Grp_MaxRec; /* record size */ Grpfab.fab$b_org = FAB$C_IDX; Grpfab.fab$b_rat = FAB$M_CR; /* implied carriage return */ Grpfab.fab$l_fop = FAB$M_CIF | FAB$M_CBT; Grpfab.fab$b_rfm = FAB$C_VAR; /* * 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 (nntp_log_err(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_wbh = 1; rabp->rab$v_rah = 1; rabp->rab$v_wat = 1; /* Wait if record is current locked, */ rabp->rab$b_tmo = 20; /* 120 second before return */ rabp->rab$b_mbf = 8; /* Number of buffers for the one stream */ rabp->rab$v_nlk = 1; status = sys$connect (rabp); return (nntp_log_err (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_wbh = 1; rabp->rab$v_rah = 1; rabp->rab$v_wat = 1; /* Wait if record is currently locked */ rabp->rab$b_tmo = 20; /* 120 second before return */ rabp->rab$v_uif = 1; /* Update if record (primary key) exist */ rabp->rab$b_mbf = 4; /* Number of buffers for the one stream */ rabp->rab$v_nlk = 1; status = sys$connect (rabp); return (nntp_log_err (status)); } /* *-------------------------------------------------------------------------------- * Close stream's */ int MsgDBclose_stream (struct RAB *rabp) { long status; status = sys$flush(rabp); status = sys$disconnect(rabp); return (nntp_log_err (status)); } int GrpDBclose_stream (struct RAB *rabp) { long status; status = sys$flush(rabp); status = sys$disconnect(rabp); return (nntp_log_err (status)); } /* *-------------------------------------------------------------------------------- * Close databases */ int MsgDBclose (void) { long status; status = sys$close (&Msgfab); return (nntp_log_err (status)); } int GrpDBclose (void) { long status; status = sys$close (&Grpfab); return (nntp_log_err (status)); } /* *-------------------------------------------------------------------------------- */ int MsgDBput (struct RAB *rabp,char *bufp, char *Grp,int n,time_t Date,int MsgL) { long status; MsgKey *Keyp = (MsgKey *) bufp; rabp->rab$b_krf = MsgId$_ref; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = (char *)&Keyp->MsgId; rabp->rab$b_ksz = strnlen(Keyp->MsgId,MsgId$_len); status = sys$find (rabp); memset(Keyp->Grp,0,sizeof(Keyp->Grp)); sprintf(Keyp->Grp,"%.*s %011lu",GrpName$_len,Grp,n); rabp->rab$l_rbf = bufp; rabp->rab$w_rsz = sizeof(MsgKey)+MsgL; rabp->rab$l_ubf = bufp; rabp->rab$w_usz = sizeof(MsgKey)+MsgL; Keyp->Date = Date; if ( status != RMS$_RNF ) { nntp_log(logw, (stdout,"MessageID already exist-Change MsgId key")); Keyp->MsgId[0] = '>'; rabp->rab$w_rsz = sizeof(MsgKey); } status = sys$put (rabp); if (! (status & 1)) return (nntp_log_err (status)); return 0; } /* *-------------------------------------------------------------------------------- */ int MsgDBfind_byId (struct RAB *rabp,char *Id,int Idl) { long status; rabp->rab$b_krf = MsgId$_ref; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = Id; rabp->rab$b_ksz = Idl; status = sys$find (rabp); if (! (status & 1)) return -1; return 0; } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byId (struct RAB *rabp, char *Id,char *Msg,int MsgL) { long status; rabp->rab$b_krf = MsgId$_ref; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = Id; rabp->rab$b_ksz = strnlen(Id,MsgId$_len); rabp->rab$l_rbf = Msg; rabp->rab$w_rsz = MsgL; rabp->rab$l_ubf = Msg; rabp->rab$w_usz = MsgL; status = sys$get (rabp); if (! (status & 1)) { nntp_log_err (status); return 0; } return (rabp->rab$w_rsz - sizeof(MsgKey)); } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byNum (struct RAB *rabp, char *Grp,int n,char *Msg,int MsgL) { long status; MsgKey *Keyp; Keyp = (MsgKey *) Msg; sprintf(Keyp->Grp,"%.*s %011lu",GrpName$_len,Grp,n); rabp->rab$b_krf = MsgGrp$_ref; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = (char *)Keyp->Grp; rabp->rab$b_ksz = strnlen(Keyp->Grp,MsgGrp$_len); rabp->rab$l_rbf = Msg; rabp->rab$w_rsz = MsgL; rabp->rab$l_ubf = Msg; rabp->rab$w_usz = MsgL; status = sys$get (rabp); if (! (status & 1)) { nntp_log_err (status); return 0; } if ( Keyp->MsgId[0] == '>' ) { Keyp->MsgId[0] = '<'; return ( MsgDBget_byId(rabp,&Keyp->MsgId[0],Msg,MsgL) ); } return (rabp->rab$w_rsz - sizeof(MsgKey)); } /* *-------------------------------------------------------------------------------- */ int GrpDBput (struct RAB *rabp,char *bufp) { long status; rabp->rab$l_rbf = bufp; rabp->rab$w_rsz = sizeof(GrpKey); status = sys$put (rabp); if (! (status & 1)) return (nntp_log_err (status)); return 0; } /* *-------------------------------------------------------------------------------- */ int GrpDBget (struct RAB *rabp,char *Grp,char *bufp) { long status; rabp->rab$b_krf = GrpName$_ref; rabp->rab$b_rac = RAB$C_KEY; rabp->rab$l_kbf = Grp; rabp->rab$b_ksz = strnlen(Grp,GrpName$_len); rabp->rab$l_rbf = bufp; rabp->rab$w_rsz = sizeof(GrpKey); rabp->rab$l_ubf = bufp; rabp->rab$w_usz = sizeof(GrpKey); status = sys$get (rabp); if (! (status & 1)) return ( nntp_log_err (status)); return rabp->rab$w_rsz; } /* *-------------------------------------------------------------------------------- */ int GrpDBget_seq (struct RAB *rabp,char *bufp,int flag) { long status; void lib$signal(); rabp->rab$b_krf = GrpName$_ref; rabp->rab$b_rac = RAB$C_SEQ; rabp->rab$l_rbf = bufp; rabp->rab$w_rsz = sizeof(GrpKey); rabp->rab$l_ubf = bufp; rabp->rab$w_usz = sizeof(GrpKey); if (!flag) { status = sys$rewind (rabp); if (! (status & 1)) return (nntp_log_err (status)); } status = sys$get (rabp); if (! (status & 1)) { nntp_log_err (status); return 0; } return rabp->rab$w_rsz; } /* *-------------------------------------------------------------------------------- */ int MsgDBget_byRange (struct RAB *rabp, char *Grp,int n,char *Msg,int MsgL,int flag) { long status; char Limkey[MsgGrp$_len]; if (!flag) sprintf(Limkey,"%.*s %011lu",GrpName$_len,Grp,n); rabp->rab$b_rac = RAB$C_SEQ; rabp->rab$b_krf = MsgGrp$_ref; rabp->rab$v_lim = 1; rabp->rab$l_kbf = Limkey; rabp->rab$b_ksz = strnlen(Limkey,MsgGrp$_len); rabp->rab$l_rbf = Msg; rabp->rab$w_rsz = MsgL; rabp->rab$l_ubf = Msg; rabp->rab$w_usz = MsgL; status = sys$get (rabp); if (! (status & 1)) { nntp_log_err (status); return 0; } return (rabp->rab$w_rsz - sizeof(MsgKey)); }