/* @RRL (c),Jun-1997-2006 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "nntp.h" extern void *NNTPCP_CLD; $DESCRIPTOR(res_dsc,"NNTP_SRV$SHUT"); int getYesNo (void); void out_info (char *,uchar); #define $DESC(string) { sizeof( string ) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, string } static struct dsc$descriptor cmd[] = { $DESC("SET"), $DESC("SHOW"), $DESC("HELP"), $DESC("ADD"), $DESC("DELETE") }; static struct dsc$descriptor par_dsc = $DESC("GROUP"); $DESCRIPTOR(q_suck, "SUCK"); $DESCRIPTOR(q_post, "POST"); $DESCRIPTOR(q_conf, "CONFIRM"); $DESCRIPTOR(q_log, "LOGGING"); $DESCRIPTOR(q_reset, "RESET"); $DESCRIPTOR(wild,"*%"); $DESCRIPTOR(welcome,"\n\t\tNNTP Server Control Program,(c)@RRL\n"); $DESCRIPTOR(prompt,"NNTP-CP>"); char grp_buf [ 1024 ]; char tmp_buf [ 1024 ]; struct dsc$descriptor grp_dsc = $DESC(grp_buf), junk = $DESC(tmp_buf); struct RAB mrab,grab,fsrab; GRPREC grec; ushort len; int suck,post,suck_f,post_f,conf,log_sw,rewindf,reset; int changes; int n; time_t t; /* *-------------------------------------------------------------------------------- */ void NNTPCP_CMD_SHUT (void) { int status; lksb lksb_; /* ** Queue a lock request, to send a SHUTDOWN Request */ if ( !(1 & (status = sys$enqw (EFN$C_ENF, LCK$K_EXMODE, &lksb_, LCK$M_SYSTEM,&res_dsc,0,0,0,0,0,0))) || !(1 & (lksb_.lksb$w_status)) ) return lksb_.lksb$w_status; return sys$deq(lksb_.lksb$l_lkid,0,0,0); } /* *-------------------------------------------------------------------------------- */ void NNTPCP_CMD_EXIT (void) { DBclose(); sys$exit(SS$_NORMAL); } /* *-------------------------------------------------------------------------------- */ int NNTPCP_CMD_SET (void) { int status; conf = (CLI$_PRESENT == cli$present (&q_conf)); log_sw = (CLI$_PRESENT == cli$present (&q_log)); reset = (CLI$_PRESENT == cli$present (&q_reset)); /* ** */ if ( CLI$_PRESENT == cli$present (&q_suck) ) { status = cli$get_value(&q_suck,&junk,&len); if (! (status & 1)) return status; suck = 1; suck_f = (tmp_buf[0] == 'Y'?1:0); } if ( CLI$_PRESENT == cli$present (&q_post) ) { status = cli$get_value(&q_post,&junk,&len); if (! (status & 1)) return status; post = 1; post_f = tolower (tmp_buf[0]); } status = cli$get_value(&par_dsc,&grp_dsc,&grp_dsc.dsc$w_length); if ( !(1 & status) ) return status; /* ** */ printf("\nSet for '%.*s'",grp_dsc.dsc$w_length,grp_dsc.dsc$a_pointer); printf("\nDateCr |DateUp |First msg#| Last msg#|P|S|Group Name...."); /* ** Check for wildcard and if not, make up for one group only */ if ( !str$find_first_in_set (&grp_dsc,&wild) ) { if ( conf && (0 >= getYesNo ())) return SS$_ABORT; memcpy (grec.grp$t_grpname,grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length); grec.grp$b_grplen = grp_dsc.dsc$w_length; status = GrpDBget(&grab,&grec,0,1,0); if ( status == RMS$_RNF ) return SS$_NORMAL; if ( !(1 & status) ) return status; if ( suck && (grec.grp$b_suck != suck_f) ) {grec.grp$b_suck = suck_f; changes = 1;} if ( post && (grec.grp$b_post != post_f) ) {grec.grp$b_post = post_f; changes = 1;} if ( suck ) {time(&grec.grp$l_dateup); grec.grp$b_suck = suck_f;} if ( post ) grec.grp$b_post = post_f; if ( reset ) grec.grp$l_first = grec.grp$l_last = 0; status = GrpDBput(&grab,&grec); if ( log_sw ) out_info(grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length); if ( log_sw ) printf("\nchanges completed"); return status; } while ( 1 & (status = GrpDBget(&grab,&grec,0,rewindf++,1)) ) { if ( !strmatch (grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length, grec.grp$t_grpname,grec.grp$b_grplen) ) continue; if ( suck ) {time(&grec.grp$l_dateup); grec.grp$b_suck = suck_f;} if ( post ) grec.grp$b_post = post_f; if ( reset ) grec.grp$l_first = grec.grp$l_last = 0; if ( conf ) { status = getYesNo (); if ( status < 0 ) break; if ( !status) continue; } if ( !(1 & (status = GrpDBput(&grab,&grec))) ) break; if ( log_sw ) out_info(grec.grp$t_grpname,grec.grp$b_grplen); n++; } if ( status == RMS$_EOF ) status = SS$_NORMAL; if (log_sw) printf("\n%d changes is completed",n); return status; } /* *-------------------------------------------------------------------------------- */ int NNTPCP_CMD_SHOW (void) { int status; status = cli$get_value(&par_dsc,&grp_dsc,&grp_dsc.dsc$w_length); if (! (status & 1)) return status; if ( CLI$_PRESENT == cli$present (&q_suck) ) suck = 1; printf("\nShow information for '%.*s'",grp_dsc.dsc$w_length,grp_dsc.dsc$a_pointer); printf("\nDateCr |DateUp |First msg#| Last msg#|P|S|Group Name...."); if ( !str$find_first_in_set (&grp_dsc,&wild) ) { memcpy (grec.grp$t_grpname,grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length); grec.grp$b_grplen = grp_dsc.dsc$w_length; status = GrpDBget(&grab,&grec,0,1,0); if ( !(1 & status) ) return SS$_NORMAL; out_info(grec.grp$t_grpname,grec.grp$b_grplen); return SS$_NORMAL; } while ( 1 & (status = GrpDBget(&grab,&grec,0,rewindf++,1)) ) { if ( strmatch (grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length, grec.grp$t_grpname,grec.grp$b_grplen) ) { if ( suck && (!grec.grp$b_suck) ) continue; out_info(grec.grp$t_grpname,grec.grp$b_grplen); } } if ( status == RMS$_EOF ) status = SS$_NORMAL; return status; } /* *-------------------------------------------------------------------------------- */ int NNTPCP_CMD_HELP (void) { $DESCRIPTOR(hlp_lib_dsc,"nntpcp.hlb"); int hlp_flg = HLP$M_PROMPT | HLP$M_HELP; return ( lbr$output_help(lib$put_output, 0,0,&hlp_lib_dsc,&hlp_flg, lib$get_input)); } /* *-------------------------------------------------------------------------------- */ int NNTPCP_CMD_DELETE (void) { return SS$_NORMAL; } int getYesNo (void) { int status; $DESCRIPTOR(dsc_buf,"\r\nConfirm by press [Y/N]:"); $DESCRIPTOR(dsc_yn, " "); int len; status = lib$get_input(&dsc_buf,&dsc_yn,&len); if (! (status & 1)) lib$signal(status); return ( ((*dsc_buf.dsc$a_pointer == 'y') || (*dsc_buf.dsc$a_pointer == 'Y'))?1:0); } /* *-------------------------------------------------------------------------------- */ int NNTPCP_CMD_ADD (void) { int status; if ( CLI$_PRESENT != cli$present (&q_conf) ) conf = 0; else conf = 1; if ( CLI$_PRESENT != cli$present (&q_log) ) log_sw = 0; else log_sw = 1; /* ** */ if ( CLI$_PRESENT == cli$present (&q_suck) ) { status = cli$get_value(&q_suck,&junk,&len); if (! (status & 1)) return status; suck = 1; suck_f = (tmp_buf[0] == 'N'?0:1); } /* ** */ if ( CLI$_PRESENT == cli$present (&q_post) ) { status = cli$get_value(&q_post,&junk,&len); if (! (status & 1)) return status; post = 1; post_f = tolower (tmp_buf[0]); } status = cli$get_value(&par_dsc,&grp_dsc,&grp_dsc.dsc$w_length); if ( !(1 & status) ) return status; /* ** */ memcpy (grec.grp$t_grpname,grp_dsc.dsc$a_pointer,grp_dsc.dsc$w_length); grec.grp$b_grplen = grp_dsc.dsc$w_length; status = GrpDBget(&grab,&grec,0,1,0); if ( 1 & status ) return SS$_NORMAL; time(&grec.grp$l_dateup); time(&grec.grp$l_datecr); grec.grp$b_suck = suck_f; grec.grp$b_post = post_f; grec.grp$l_first = grec.grp$l_last = 0; if ( log_sw ) { printf("\nDateCr |DateUp |First msg#| Last msg#|P|S|Group Name...."); out_info(grec.grp$t_grpname,grec.grp$b_grplen); } if ( conf && (0 >= getYesNo ())) return SS$_ABORT; return GrpDBput(&grab,&grec); } /* *-------------------------------------------------------------------------------- */ void out_info (char *grp,uchar len) { char buf [32]; ushort sz; cvt_vms_to_nntp(grec.grp$l_datecr,buf,&sz); printf("\n%.*s",sz,buf); cvt_vms_to_nntp(grec.grp$l_dateup,buf,&sz); printf(" %.*s",sz,buf); printf("%11lu|%11lu|%c|%c|%.*s",grec.grp$l_first,grec.grp$l_last, grec.grp$b_post?'y':' ', grec.grp$b_suck?'y':' ',len,grp); } /* *-------------------------------------------------------------------------------- */ void main (void) { int status,flag = 0; char buf[255] = {"NNTPCP "}; struct dsc$descriptor cmd_dsc; /* ** Printout a banner */ if ( !(1 & (status = lib$put_output (&welcome))) ) lib$signal(status); /* ** Openning database files */ if (!(1 & (status = MsgDBopen())) ) lib$signal(status); if (!(1 & (status = GrpDBopen())) ) lib$signal(status); if (!(1 & (status = FeedSuckDBopen())) ) lib$signal(status); if (!(1 & (status = MsgDBopen_stream (&mrab))) ) lib$signal(status); if (!(1 & (status = GrpDBopen_stream (&grab))) ) lib$signal(status); /* ** Check the presence of the comand line agruments */ INIT_SDESC(cmd_dsc,sizeof(buf),buf); if ( !(1 & (status = lib$get_foreign(&cmd_dsc,0,&cmd_dsc.dsc$w_length,&flag))) ) return status; if ( cmd_dsc.dsc$w_length ) { if ( CLI$_NORMAL == (status = cli$dcl_parse (&cmd_dsc,&NNTPCP_CLD,0,0,0)) ) return cli$dispatch(); else return status; } /* ** Start reading commands in loop */ while ( RMS$_EOF != ( status=cli$dcl_parse (0,&NNTPCP_CLD,lib$get_input,lib$get_input,&prompt)) ) { INIT_SDESC(grp_dsc,sizeof(grp_buf),grp_buf); changes = len =rewindf = suck = post = suck_f = post_f = n = 0; conf = log_sw = 1; if ( status != CLI$_NORMAL ) continue; if (!(1 & (status = cli$dispatch())) ) lib$signal(status); printf("\n"); } NNTPCP_CMD_EXIT (); }