+-+-+-+ Beginning of part 9 +-+-+-+ X while (rou_getjni(&jinf.context, &jinf.mask, &node_name, &jinf.node_type, X`009 &link_name, &jinf.link_pid, &jinf.link_status, &jinf.link_qcnt, X`009 &link_daemon, &line_name, &jinf.line_status, &jinf.line_tot, X`009 &jinf.line_err, &jinf.line_tmo) & 1) `123 X X`009/* What is the link doing? */ X X`009if (jinf.link_status == 0) `123`009/* Already inactive, don't bother */ X`009 continue; X`009`125 X X`009/* Terminate and fondle the name */ X X`009jinf.l_name[8] = '\0'; X`009strip(strupr(jinf.l_name)); X X`009/* Does it have to be down before we can continue? */ X X`009if (mandatory_link(jinf.l_name)) `123 X`009 return (jinf.l_name); X`009`125 X `125 X return (NULL); X`125 X X/* So what version of Jnet is this, anyway? */ X Xstatic char * jver[32]; Xstatic struct dsc$descriptor_s X jni_vers_dsc; X Xchar * get_jnet_wrk(struct dsc$descriptor * jni_vers_dsc) X`123 X strncpy(jver, jni_vers_dsc->dsc$a_pointer, jni_vers_dsc->dsc$w_length); X jver[jni_vers_dsc->dsc$w_length] = '\0'; X`125 X `032 Xchar * get_jnet_ver(void) X`123 X rou_version_dsp(get_jnet_wrk);`009/* Undocumented, but works */ X X return(jver); X`125 $ GOSUB UNPACK_FILE $ FILE_IS = "JANINFO.C" $ CHECKSUM_IS = 221984847 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#include X#include X Xstatic struct `123 `009`009`009/* Used in all of the GETJNI() calls */ X char n_name[9]; X char l_name[9]; X char l_daemon[33]; X char ln_name[9]; X int node_type; X int link_pid; X int link_status; X int link_qcnt; X int line_status; X int line_tot; X int line_err; X int line_tmo; X int context; X int mask; X`125 jinf; X Xstatic int init = 0;`009`009`009/* Flag for use of rou_init_route() */ Xstatic int status = 0; X X/* Descriptors for buffers */ X Xstatic struct dsc$descriptor_s X node_name`009= `123 8, DSC$K_DTYPE_T, DSC$K_CLASS_S, &jinf.n_name`125, X link_daemon = `12332, DSC$K_DTYPE_T, DSC$K_CLASS_S, &jinf.l_daemon`125, X line_name`009= `123 8, DSC$K_DTYPE_T, DSC$K_CLASS_S, &jinf.ln_name`125; X X X/* Check if the hook already in use? */ X Xmain() X`123 X static struct dsc$descriptor_s X`009link_name = `123 8, DSC$K_DTYPE_T, DSC$K_CLASS_S, &jinf.l_name`125; X X jinf.context = -1;`009`009`009/* Unknown */ X jinf.mask = 0x0a;`009`009`009/* Want LINKs and HOOKs */ X X if (init++ == 0) `123`009`009`009/* First time through */ X`009status = rou_init_route(); X`009printf("rou_init_route() = %08X\n", status); X `125 X X /* Do it to it */ X X`009printf("nodename t linkname linkpid s linkdaem linename\n"); X`009printf("-------- - -------- -------- - -------- --------\n"); X X while (rou_getjni(&jinf.context, &jinf.mask, &node_name, &jinf.node_type, X`009 &link_name, &jinf.link_pid, &jinf.link_status, &jinf.link_qcnt, X`009 &link_daemon, &line_name, &jinf.line_status, &jinf.line_tot, X`009 &jinf.line_err, &jinf.line_tmo) & 1) `123 X X`009jinf.n_name[8]='\0'; X`009jinf.l_name[8]='\0'; X`009jinf.l_daemon[8]='\0'; X`009jinf.ln_name[8]='\0'; X X`009printf("%8s %1d %8s %08X %1d %8s %8s\n", jinf.n_name, jinf.node_type, X`009 jinf.l_name, jinf.link_pid, jinf.link_status, jinf.l_daemon, X`009 jinf.ln_name); X `125 X`125 $ GOSUB UNPACK_FILE $ FILE_IS = "JANINFO.COM" $ CHECKSUM_IS = 421739283 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$ cc janinfo X$ link/map janinfo, sys$input/opt Xjan_common:[lib]janshr/share`032 Xsys$share:vaxcrtl/sha`032 $ GOSUB UNPACK_FILE $ FILE_IS = "JANTIDY_ADDITION.COM" $ CHECKSUM_IS = 641337297 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X$ set default jan_sys X$ jcp :== $jan_sys:jcp X$ say := write sys$output X$ ! ** BBOARD ** X$ bbcontext="" X$ say "" X$bbnext: X$ bbpid=f$pid(bbcontext) X$ if bbpid .eqs. "" then goto bbnotfound X$ if f$getjpi(bbpid,"PRCNAM") .nes. "BBoard_Daemon" then goto bbnext X$ if f$getjpi(bbpid,"USERNAME") .nes. "BBOARD " then goto bbnext X$ say "BBoard running as PID ''bbpid'" X$ say "" X$ say "Stopping link JCSVAX1." X$ jcp stop jcsvax1 X$ wait 00:00:15 X$ say "" X$ say "Sending shutdown request to BBOARD." X$ send bboard@spcvxa shutdown X$ bbcount=0 X$ set message/nofacility/noseverity/noidentification/notext X$bbwait: X$ wait 00:00:05 X$ on warning then goto bbexit X$ bbdummy=f$getjpi(bbpid,"PRCNAM") X$ bbcount=bbcount+1 X$ if bbcount .lt. 24 then goto bbwait X$ say "" X$ say "BBoard shutdown taking to long, aborting BBoard." X$ goto bbexit X$bbnotfound: X$ say "BBoard not running." X$bbexit: X$ set on X$ set message/facility/severity/identification/text X$ ! ** BBOARD ** $ GOSUB UNPACK_FILE $ FILE_IS = "MAKEFILE." $ CHECKSUM_IS = 1904132874 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X! For debugging, use CCOPT = /define=("DEBUG=1") XCCOPT = X Xall:`009bboard.exe X Xbboard.exe:`009bboard.obj bbsupp.obj hooks.obj supp.obj rules.obj \ X`009`009comsupp.obj usefile.obj digest.obj usemsg.obj notelog.obj X`009link/map bboard, bbsupp, hooks, supp, rules, comsupp, usefile, - X`009`009digest, usemsg, notelog, sys$input/opt X`009jan_common:[lib]janshr/share $ X`009sys$share:vaxcrtl/sha $ X`009ident="V1.44-FINAL" $ X`009copy bboard.exe [-] X Xbboard.obj:`009bboard.c bboard.h X`009cc $(CCOPT) bboard X Xbbsupp.obj:`009bbsupp.c bboard.h X`009cc $(CCOPT) bbsupp X Xhooks.obj:`009hooks.c bboard.h X`009cc $(CCOPT) hooks X Xsupp.obj:`009supp.c bboard.h X`009cc $(CCOPT) supp X Xrules.obj:`009rules.c bboard.h X`009cc $(CCOPT) rules X Xcomsupp.obj:`009comsupp.c bboard.h X`009cc $(CCOPT) comsupp X Xusefile.obj:`009usefile.c bboard.h X`009cc $(CCOPT) usefile X Xdigest.obj:`009digest.c bboard.h X`009cc $(CCOPT) digest X Xusemsg.obj:`009usemsg.c bboard.h X`009cc $(CCOPT) usemsg X Xnotelog.obj:`009notelog.c bboard.h X`009cc $(CCOPT) notelog $ GOSUB UNPACK_FILE $ FILE_IS = "NOTELOG.C" $ CHECKSUM_IS = 842032981 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#include X#include X#include X#include X#include X#include X#include X#include "bboard.h" X Xstruct note_log `123 X char conf_name[40]; `009`009/* Name of the conference (not list) */ X long close_date;`009`009`009/* Last possible date of posting */ X SYSTIM last_post;`009`009`009/* Last time list was posted to */ X`125; X Xstatic int search_log_file(FILE * i, struct note_log * ent, char * conf, X int case_sense); Xstatic sort_log_file(void); Xstatic int log_compare(struct note_log * x, struct note_log * y); X X/* Figure out if we need a new topic since we're at the beginning of an X interval */ X Xvoid fondle_note_log_file(FILE * out, char interval, char * conf, char * hdr) X`123 X struct note_log file_entry; `009/* Need one of our own */ X X SYSTIM cur_time;`009`009`009/* Now - begin of period */ X struct $NUMTIM start_time;`009`009/* Now - begin of period */ X SYSTIM end_time;`009`009`009/* Later - end of period */ X struct $NUMTIM time;`009`009/* Later - end of period */ X FILE * note_log_file;`009`009/* Where our info gets stuffed */ X long cur_date;`009`009`009/* Temporary date value */ X V static char * month_list[] = `123 "January", "February", "March", "April" X, X`009"May", "June", "July", "August", "September", "October", "November", X`009"December" `125; X X /* Setup */ X X get_time(cur_time); `009`009/* When are we now? */ X get_numtim(&start_time, cur_time);`009/* Full format, please */ X X /* Open the file in append mode */ X X note_log_file = fopen(log_file.dsc$a_pointer, "a+"); X X /* See if it already exists */ X X if (!search_log_file(note_log_file, &file_entry, conf, TRUE)) `123 X`009memset(&file_entry, 0, sizeof(struct note_log)); /* Zap it */ X`009strcpy(file_entry.conf_name, conf);`009/* Save the conf name */ X`009goto fondle_note_log_file_new_topic;`009/* We know that it's new */ X `125 X X#ifdef DEBUG V printf("fondle_note_log_file: Processing for %s\n", file_entry.conf_name) X; X#endif X X /* What's today's date? */ X X cur_date = (long) (start_time.year * 10000L) + X`009 (long) (start_time.month * 100L) + (long) (start_time.day); X X /* How does that compare to the last posting date? */ X X if (cur_date <= file_entry.close_date) `123 X#ifdef DEBUG X`009printf("fondle_note_log_file: Updating last posting date\n"); X#endif X`009memcpy(file_entry.last_post, cur_time, sizeof (SYSTIM)); X`009fwrite(&file_entry, sizeof(struct note_log), 1, note_log_file); X`009fclose(note_log_file);`009`009 /* Just close the info file */ X`009return; `009`009`009 /* And run away */ X `125 X X /* We need a new topic */ X Xfondle_note_log_file_new_topic: X X /* Get the first and last dates of the interval */ X X start_end_time(interval, cur_time, end_time); X X /* Convert close date to NUMTIM for use */ X X get_numtim(&time, end_time); X X /* Save the info */ X X file_entry.close_date = (long) (time.year * 10000L) + X`009 (long) (time.month * 100L) + (long) (time.day); X X /* Write it back to the log file */ X X fwrite(&file_entry, sizeof(struct note_log), 1, note_log_file); X fclose(note_log_file); X X /* Before doing anything else, make sure the log file is sorted... */ X X sort_log_file(); X X /* Now let's fondle inside NOTES */ X X#ifdef DEBUG X printf("fondle_note_log_file: Building new topic commands\n"); X#endif X X if (setuname_used) `123 X`009fputs("$ setuname 'oldname'\n", out); X `125 X X fprintf(out, "$ notes/nonotebook 0::%s\n", conf); X fputs("set moderator\n", out); X X /* The topic is written by BBOARD itself */ X X fputs("set prof/temp/pers=\"Notes Poster Daemon\"\n", out); X fputs("write/noedit nl:\n", out); X X /* Now let's set up the subject of the new topic */ X X fprintf(out, "%s Postings", hdr); X X if (interval == 'w' `124`124 interval == 'W') `123 X X`009/* Weekly get start and end dates */ X X`009get_numtim(&start_time, cur_time); X`009fprintf(out, " for %02d/%02d/%02d - %02d/%02d/%02d", X`009`009start_time.month, start_time.day, start_time.year % 100, X`009`009time.month, time.day, time.year % 100); X X `125 else if (interval == 'm' `124`124 interval == 'M') `123 X X`009/* Monthly just get month and year */ X X`009fprintf(out, " for %s, %04d", month_list[time.month-1], time.year); X `125 X X /* Yes, we want the note entered */ X X fputs("\nyes\n", out); X X /* And it's time to get out of NOTES again */ X X fputs("exit\n", out); X X return; X`125 X X/* Reset a particular entry in the log file */ X Xvoid reset_log_file_entry(char * conf, char * node, char * user) X`123 X struct note_log cur;`009`009/* current entry */ X FILE * logf;`009`009`009/* log file itself */ X X /* Play with the conference name */ X X scrunch(conf); X X /* Did they want a wild card mayhap? */ X X if (strchr(conf, '*')) `123 X`009send_msg(node, user, "Not allowed to RESET wildcarded names."); X`009return; X `125 X X /* Need to open the file */ X X logf = fopen(log_file.dsc$a_pointer, "a+"); X X /* Now let's see if we can find what they're talking about */ X X#ifdef DEBUG X printf("reset_log_file_entry: About to search for %s\n", conf); X#endif X X if (!search_log_file(logf, &cur, conf, FALSE)) `123 X X`009/* Not found. Tell them that it didn't work */ X X`009sprintf(temp, "Unable to find conference '%s'.", conf); X`009send_msg(node, user, temp); X X`009/* Close the file */ X X`009fclose(logf); X X`009/* And just go away */ X X`009return; X `125 X X /* Ok. So let's just zap the close date back to zero. That'll do it */ X X#ifdef DEBUG X printf("reset_log_file_entry: Okay to zap %s\n", conf); X#endif X X cur.close_date = 0L; X fwrite(&cur, sizeof(struct note_log), 1, logf); X fclose(logf); X X /* Tell them about it */ X X sprintf(temp, "I '%s' reset.", conf); X send_msg(node, user, temp+2); X X /* Also log the event */ X X send_log_file(temp); X`125 X X/* Display info on a conference to a user */ X Xvoid display_log_file_entry(char * conf, char * node, char * user) X`123 X struct note_log cur;`009`009/* Current entry */ X struct dsc$descriptor_s pat;`009/* Pattern (passed to us) */ X char temp_conf[40]; `009`009/* For uppercasing name */ X struct dsc$descriptor_s cand;`009/* Candidate (from entry) */ X FILE * logf; X int found_any; X static char time_str[24];`009`009/* For when we started */ X static struct dsc$descriptor_s time_buf = X`009`123 23, DSC$K_DTYPE_T, DSC$K_CLASS_S, &time_str `125; X int time_len;`009`009`009/* How long is returned string? */ X X static char * mon_list[] = `123 X`009"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", X`009"OCT", "NOV", "DEC" X `125; X X /* Setup */ X X found_any = FALSE; X X /* Play with the conference name */ X X scrunch(conf); X X /* And shove it into a descriptor */ X X str_desc(&pat, conf); X X /* Need to open the file */ X X logf = fopen(log_file.dsc$a_pointer, "a+"); X X /* And jump to the beginning */ X X rewind(logf); X X /* Now let's start searching through */ X X#ifdef DEBUG X printf("display_log_file_entry: About to search for >%s<\n", conf); X#endif X X while (TRUE) `123 X X`009/* Read the next record */ X X`009if (!fread(&cur, sizeof(struct note_log), 1, logf)) `123 X`009 break;`009`009`009/* EOF */ X`009`125 X X`009/* Let's fondle the conference name */ X X`009strcpy(temp_conf, cur.conf_name); X`009strupr(temp_conf); X X#ifdef DEBUG X`009printf("display_log_file_entry: current conf: >%s<\n", temp_conf); X#endif X X`009/* Now build a descriptor of it */ X X`009str_desc(&cand, temp_conf); X X`009/* Try for a match */ X X`009if (str$match_wild(&cand, &pat) == STR$_NOMATCH) `123 X`009 continue; X`009`125 X X`009/* Got a match. Say something about it */ X X`009found_any = TRUE; X X`009/* Format the outgoing message */ X X`009if (cur.close_date) `123 X`009 sprintf(temp, " close: %02d-%s-%4d", X`009`009 (int) (cur.close_date % 100), X`009`009 mon_list[(int) ((cur.close_date / 100) % 100) - 1], X`009`009 (int) (cur.close_date / 10000L)); X`009`125 else `123 X`009 sprintf(temp, " close: conference RESET", cur.conf_name); X`009`125 X X`009strcpy(temp+256, " last posted: "); X X`009if (cur.last_post[0] `124`124 cur.last_post[1]) `123 X X`009 /* Format the time that we started */ X X`009 sys$asctim(&time_len, &time_buf, cur.last_post, 0); X X`009 /* Chop off the trailing hundredths of a second (silly) */ X X`009 time_str[20] = '\0'; X X`009 /* Now tack on the rest of the message */ X X`009 strcat(temp+256, time_str); X`009`125 else `123 X`009 strcat(temp+256, "N/A"); X`009`125 X X`009/* Finally we get to tell them */ X X`009send_msg(node, user, cur.conf_name); X`009send_msg(node, user, temp); -+-+-+-+-+ End of part 9 +-+-+-+-+-