+-+-+-+ Beginning of part 15 +-+-+-+ $ FILE_IS = "USEFILE.C" $ CHECKSUM_IS = 474055494 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#include X#include X#include X#include X#include X#include X#include "bboard.h" X Vstatic void build_note_file(char * o_fl, char * conf, FILE * in, int err_note X); X Xstatic struct jnet_file_header * f_save; X V/* Now that we've received the file, we're supposed to do something with it * X/ X Xvoid use_file(struct jnet_file_header * f) X`123 X FILE * note; X X f_save = f; `009`009`009/* Save this for local gloabl usage */ X X note = fopen(f->local_file, "r"); /* Open it */ X X scan_header(note, NULL);`009`009/* Fill up the header IDs */ X do_rules(note);`009`009`009/* And make them make sense */ X X fclose(note);`009`009`009/* Close the mail file */ X remove(f->local_file);`009`009/* And toss it out the window */ X X delete(f->jnet_file);`009`009/* Kill Jnet's version of the file */ X rou_got_file();`009`009`009/* And tell Jnet that we're finished */ X X mail_received++;`009`009`009/* And another one rides the bus */ X`125 X X/* Set up for, and then run, a .COM file to write the message to NOTES */ X Xvoid put_note(FILE * note, struct rule_info * rule, struct list_info * list, X int error_note) X`123 X char * from;`009`009`009/* Name of author */ X char * subj;`009`009`009/* Subject from header */ X char * conf_to_use; `009`009/* Just figure this out once */ X char note_fn[200];`009`009`009/* Where the text goes */ X FILE * com_file;`009`009`009/* Ditto */ X X /* Figure out which NOTES conference it gets put into */ X X conf_to_use = (error_note ? error_conf.dsc$a_pointer : list->conf_name); X X /* And save the name */ X X strcpy(f_save->conf_name, conf_to_use); X X /* Is this a digest to be processed? */ X X if (!error_note && list->flag_digest) `123 X`009digest_run(note, rule, list); X`009return; X `125 X X /* Build the text file and let us know where it is */ X X#ifdef DEBUG X printf("put_note: about to build note text\n"); X#endif X X build_note_file(note_fn, conf_to_use, note, error_note); X X /* Now let's get the pieces of the header that we need */ X /* This is only possible if we got here through a rule */ X X if (!error_note) `123 X`009from = find_source(rule->id_from); X`009if (!from) `123`009`009`009/* If no one home, use a blank to */ X`009 from = ""; /* prevent ACCVIO */ X`009`125 X X`009from_text_fondle(from); `009/* Do all the right things with this */ X X`009/* Now onto the Subject */ X X`009subj = find_source(rule->id_subj); X`009if (!subj) `123 X`009 subj = ""; X`009`125 X X`009subj_text_fondle(subj);`009`009/* Do all the right things with this */ X `125 X X /* Open up the .COM file */ X X com_file = com_open(); X X#ifdef DEBUG X printf("put_note: starting to construct .COM file\n"); X#endif X X /* Let's see if we need a new topic written */ X X if (!error_note) `123 X`009fondle_note_log_file(com_file, list->new_topic_interval, X`009`009list->conf_name, list->conf_hdr); X `125 X X /* Are we being told to become someone else? This only works if you've */ X /*`009got SETUNAME. Otherwise, don't fill in this field in the control */ X /*`009file. */ X X if (!error_note && list->conf_user[0]) `123 X`009fprintf(com_file, "$ setuname %s\n", list->conf_user); X`009setuname_used = TRUE; X `125 X V /* Were we someone else but we're not posting as anyone else? If so, we * X/ X /*`009need to change back to our hook name. */ X X if ((error_note `124`124 !list->conf_user[0]) && setuname_used) `123 X`009fprintf(com_file, "$ setuname %s\n", hook_name.dsc$a_pointer); X `125 X X /* Enter NOTES */ X X fprintf(com_file, "$ notes/nonotebook 0::%s\n", conf_to_use); X X /* Need moderator privs since the confs are /NOWRITE */ X X fputs("set moderator\n", com_file); X V /* If we're not in an error situation, we want to set the personal name * X/ X /*`009to the original From: of the message */ X X if (error_note) `123 X`009fputs("set prof/temp/pers=\"Notes Poster Daemon\"\n", com_file); X `125 else `123 X`009fprintf(com_file, "set prof/temp/pers=\"%s\"\n", from); X `125 X X /* Go to the last note of the last topic */ X X fputs("l.l\n", com_file); X X /* Reply with the text file */ X X fprintf(com_file, "reply/noedit %s\n", note_fn); X X /* Write out the subject */ X X if (!error_note) `123 X`009fprintf(com_file, "%s\n", subj); X `125 else `123 X`009fprintf(com_file, "Unknown subject\n"); X `125 X X /* Yes, we want to enter the reply */ X X fputs("yes\n", com_file); X X /* Do we want to add a keyword? */ X X if (!error_note && list->flag_keyword && !list->conf_user[0]) `123 X`009fprintf(com_file, "add keyword %s\n", list->scan_data); X `125 X X /* And jump out of NOTES */ X X fputs("exit\n", com_file); X X /* Make sure that we delete the note file */ X X fprintf(com_file, "$ delete %s;*\n", note_fn); X X /* Wrap it up ready to go */ X X com_close(1); X`125 X X/* Build a text file name and copy the message text to it */ X Vstatic void build_note_file(char * o_fl, char * conf, FILE * in, int err_note X) X`123 X SYSTIM cur_time;`009`009`009/* When is now? */ X struct $NUMTIM t;`009`009`009/* Need this to break it out */ X FILE * out; `009`009`009/* Where do we write it? */ X X if (err_note) `123`009`009`009/* If error, want the header also */ X`009rewind(in); X `125 X X /* Get time and date for the text file name */ X X get_time(cur_time); X get_numtim(&t, cur_time); X X /* Build the name into our caller's buffer so they know what it is */ X X sprintf(o_fl, "%s%s.%04d-%04d%04d", scratch_dir.dsc$a_pointer, conf, X`009 t.month * 100 + t.day, t.hour * 100 + t.minute, X`009 t.second * 100 + t.h_second); X X /* Open the file in a way that makes sense for EDT, etc. */ X X out = fopen(o_fl, "w", "ctx=rec", "rat=cr", "rfm=var"); X X /* Copy it over while there's more text there */ X X while (TRUE) `123 X`009if (!fgets(temp, 255, in)) `123 X`009 break; X`009`125 X`009fputs(temp, out); X `125 X X /* Close the text file */ X X fclose(out); X X /* And let's run away */ X X return; X`125 $ GOSUB UNPACK_FILE $ FILE_IS = "USEMSG.C" $ CHECKSUM_IS = 2015229471 $ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY X#include X#include X#include X#include "bboard.h" X X/* #define some command counters */ X X#define SHUT 1 X#define RELO 2 X#define RESE 3 X#define WRIT 4 X#define SUSP 5 X#define RESU 6 X#define STAT 7 X#define DISP 8 X#define HELP 9 X X/* Structure of the commands that we can execute */ X Xstatic struct command cmds[] = `123 X `123 "SHUTDOWN", 4, TRUE, SHUT `125, X `123 "RELOAD", 3, TRUE, RELO `125, X `123 "RESET", 5, TRUE, RESE `125, X `123 "WRITE", 3, TRUE, WRIT `125, X `123 "SUSPEND", 4, TRUE, SUSP `125, X `123 "RESUME", 4, TRUE, RESU `125, X `123 "STATUS", 1, FALSE, STAT `125, X `123 "DISPLAY", 1, FALSE, DISP `125, X `123 "HELP", 4, FALSE, HELP `125, X `123 "?", 1, FALSE, HELP `125, X `123 NULL,`009 0, FALSE, 0 `125 X`125; X Xstatic void do_command(char * node, char * user, int cmd, char * parm); X X/* We've received a message, so let's do something with it */ X Xvoid use_msg(char * node, char * user, char * msg) X`123 X struct command * cur;`009`009/* Which command is it? */ X char t_cmd[21];`009`009`009/* Buffer for the command */ X int len;`009`009`009`009/* Length of the command that we got? */ X X /* Ignore commands that start with '*' - it's from a process */ X X if (msg[0] == '*') `123 /* Ignore commands with '*' */ X`009return; X `125 X X /* Let's copy the first word over, unless we get ridiculous */ X X for (len = 0; msg[len] != ' ' && msg[len] && len < 20; len++) `123 X`009t_cmd[len] = msg[len]; X `125 X X /* Terminate the string */ X X t_cmd[len] = '\0'; X X /* Now let's see if we got a match anywhere */ X X for (cur = cmds; cur->name; cur++) `123 X`009if (strncmp(t_cmd, cur->name, len)) `123 X`009 continue; X`009`125 X X`009/* Do we have a minimum length match? */ X X`009if (len < cur->min_len) `123 X`009 continue; X`009`125 X X`009/* We have a winner! */ X X#ifdef DEBUG X`009printf("use_msg: Found command %s\n", cur->name); X#endif X X`009break; X `125 X X /* If we ran off the end of the command list, it's invalid */ X X if (!cur->name) `123 X`009sprintf(temp, "Invalid command: '%s'.", t_cmd); X`009send_msg(node, user, temp); X`009send_msg(node, user, "Send 'HELP' for further information."); X`009return; X `125 X V /* If it's a privileged command and you're not, it's not going to happen X */ X X if (cur->privileged && !valid_manager(node, user)) `123 X`009sprintf(temp, "Restricted command: '%s'.", cur->name); X`009send_msg(node, user, temp); X`009return; X `125 X X /* So, do something useful with this */ X X do_command(node, user, cur->cmd_value, msg+len); X`125 X X/* We've received a valid command from someone who's allowed to tell us */ X Xstatic void do_command(char * node, char * user, int cmd, char * parm) X`123 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 char * bad_link;`009`009`009/* Which link isn't inactive yet */ X X switch (cmd) `123`009`009`009/* Use the command number */ X X /* Shutdown request */ X`009case SHUT: X X`009 /* Check if we're allowed to (do we have anything to post, and */ X`009 /*`009we're not allowed to). */ X X`009 if (postings_suspended && new_count) `123 X`009`009strcpy(temp, "I Posting suspended with outstanding entries"); X`009`009send_msg(node, user, "SHUTDOWN command not accepted"); X`009`009send_msg(node, user, temp+2); X`009`009send_log_file(temp); X`009 `125 X X`009 /* Now see if everything is down that should be */ X X#ifdef DEBUG X`009 printf("do_command: shutdown: checking links\n"); X#endif X X`009 bad_link = check_links_down(); X X`009 /* Did it work? */ X X`009 if (bad_link) `123 X`009`009sprintf(temp, "Link '%s' is not inactive.", bad_link); X`009`009send_msg(node, user, "SHUTDOWN command not accepted"); X`009`009send_msg(node, user, temp); X`009`009break; X`009 `125 X X`009 /* We're ready to run away. Tell them that it worked */ X X`009 send_msg(node, user, "SHUTDOWN command accepted."); X X`009 /* And set the flag */ X X`009 shutdown_state = TRUE; X`009 break; X X /* Reload rules file */ X`009case RELO: X X`009 /* We heard you... */ X X`009 send_msg(node, user, "RELOAD command accepted."); X X`009 /* We'll do it and let you know if it worked */ X X`009 if (read_control_file(TRUE, node, user)) `123 X`009`009send_msg(node, user, "Rules reload complete."); X`009`009send_log_file("I Rules reloaded."); X`009 `125 X X`009 break; X X /* Reset the closing date on a conference */ X`009case RESE: X X`009 /* Just call someone else to do it all */ X X`009 reset_log_file_entry(parm, node, user); X X`009 break; X X /* Write all unprocessed messages to Notes */ X`009case WRIT: X X`009 /* If we're SUSPENDed, don't even think about it. We're */ X`009 /*`009SUSPENDed for a reason, let's keep it that way. */ X X`009 if (postings_suspended) `123 X`009`009send_msg(node, user,`032 X`009`009`009"Postings SUSPENDed. WRITE command rejected."); X`009`009break; X`009 `125 X X`009 /* This will force it through normal channels */ X X`009 if (new_count) `123 X`009`009new_count = -1; X`009`009send_msg(node, user, "WRITE command accepted."); X`009`009send_log_file("I WRITE forced for unposted entries."); X`009 `125 else `123 X`009`009send_msg(node, user, X`009`009`009"WRITE command ignored. No unposted entries"); X`009 `125 X X`009 break; X X /* Suspend BBoard's ability to post to Notes */ X`009case SUSP: X X`009 /* Send the message first */ X X`009 sprintf(temp, "Postings are %ssuspended", (postings_suspended ? X`009`009 "already " : "")); X`009 send_msg(node, user, temp); X X`009 /* Now log it, if needed */ X X`009 if (!postings_suspended) `123 X`009`009send_log_file("I Posting SUSPENDed"); X`009 `125 X X`009 /* Just set the flag */ X X`009 postings_suspended = TRUE; X`009 break; X X /* Resume posting after a suspension */ X`009case RESU: X X`009 /* Send message first */ X X`009 sprintf(temp, "Postings are %senabled", (postings_suspended ? X`009`009 "" : "already ")); X`009 send_msg(node, user, temp); X X`009 /* Now log the event */ X X`009 if (postings_suspended) `123 X`009`009send_log_file("I Posting RESUMEd"); X`009 `125 X X`009 /* Now just set the flag */ X X`009 postings_suspended = FALSE; X X`009 /* If something was waiting, make sure it goes out immediately */ X X`009 if (new_count) `123 X`009`009new_count = -1; X`009 `125 X`009 break; X X /* Status message */ X`009case STAT: X X`009 /* Format the time that we started */ X X`009 sys$asctim(&time_len, &time_buf, bboard_start, 0); X X`009 /* Chop off the trailing hundredths of a second (silly) */ X X`009 time_str[20] = '\0'; X X`009 /* Format it for outgoing */ X X`009 sprintf(temp, "BBOARD %s, %s, VMS %s", version, X`009`009get_jnet_ver(), get_vms_ver()); X`009 sprintf(temp+128, "Started at %s, Entries since restart: %d", X`009`009time_str, mail_received); X`009 sprintf(temp+256, "Unposted entries: %d, Posting state: %s",`032 X`009`009(new_count >= 0 ? new_count : 0), (postings_suspended ? X`009`009"SUSPENDED" : "NORMAL")); X X#ifdef`009DEBUG X#if (DEBUG & 1) X`009 sprintf(temp+384,"Debugging: FULL"); X#else X`009 sprintf(temp+384,"Debugging: ON"); X#endif`009/* (DEBUG & 1) */ X#else X`009 sprintf(temp+384,"Debugging: OFF"); X#endif`009/* DEBUG */ X X`009 /* And bop it out there */ X X`009 send_msg(node, user, temp); X`009 send_msg(node, user, temp+128); X`009 send_msg(node, user, temp+256); X`009 send_msg(node, user, temp+384); X X`009 break; X X /* Display the status of a conference */ X`009case DISP: X X`009 /* Just call someone else to take care of it */ X X`009 display_log_file_entry(parm, node, user); X X`009 break; X X /* Send something useful if someone asks */ X`009case HELP: X X`009 /* Ok. Now start spitting... */ X X`009 send_msg(node, user, X`009`009"You have reached the BBoard VAX Notes Posting Facility."); X`009 send_msg(node, user, X`009`009"This facility is for local VAX Notes users to read BITNET-"); -+-+-+-+-+ End of part 15 +-+-+-+-+-