/* This version adds the distribution list and cleans up the program's handling of messages (especially outgoing ones) by using the fidonet.h file for some fidonet-specific functions. */ /* This program scans the message files in the netmail directory looking for messages addressed to it (BBSLIST as the 1st 7 chars.). Any messages which are null or of unrecognized format will engender a "help" message which is sent to the originator of the message. Messages which are requests are processed immediately. Messages which would update the bbs listing are first checked for a valid password. ----- Make sure you compile this program from the command line (bcc)! ----- */ #define MAX_MSGS_TO_SCAN 200 /* We scan messages from 1 to this */ /* number for the name BBSLIST. */ #include #include #include #include #include /* Dos-specific functions are used to get date/time. */ #include "fidonet.h" #include "i_f_eng.c" #define ERRORLEVEL_SUCCESS 0 #define ERRORLEVEL_LIST_CHANGED 1 #define ERRORLEVEL_BAD_PARAMETER 2 #define ERRORLEVEL_CONFIGURATION 3 #define ERRORLEVEL_ENGINE 4 #define ERRORLEVEL_FATAL 5 char DEBUG_FLAG=0, /* These two fields are gotten from the "debug_string" */ delete_received_messages_flag=0; /* line of the configuration file. */ struct data_record_type { char unique_number_highorder; char unique_number_loworder; char name[30]; char sysop[20]; char sysopreal[20]; char number[10]; char addr1[20]; char addr2[20]; char addr3[20]; char baud[20]; char location[20]; char hours[10]; char software[10]; } data_record; struct distribution_record_type { unsigned char net_highorder; unsigned char net_loworder; unsigned char node_highorder; unsigned char node_loworder; } distribution_record; struct print_record_1_type { char name[30], filler_1[2], number[10], filler_2[2], baud[20], filler_3[2], hours[10]; } print_record_1; struct print_record_2_type { char sysop[20], filler_1[2], sysopreal[20], filler_2[2], location[20], filler_3[2], software[10]; } print_record_2; struct print_record_3_type { char addr1[20], filler_1[2], addr2[20], filler_2[2], addr3[20], filler_3[2], unique_number[10]; } print_record_3; char create_bbslist_flag=0; /* Set non-zero if new bbslist.txt should be written.*/ FILE *config_file,*incoming_file,*outgoing_file,*bbslist_file,*temp_file; int message_number = 0; /* The message number to open; we search */ /* the first MAX_MSGS_TO_SCAN messages. */ int temp_int, data_file_handle, /* Holds the file handle for the file engine. */ distribution_file_handle, errcode, /* Used for holding results of indexed file engine calls. */ result; /* This is used to hold the result of memcmp() calls. */ char from_bbslist_program[]="BBSLIST -- the bbslist maintainer", temp_string[128],temp_string_2[128], CR_string[2], /* This gets initialized to be a CR we can append to lines. */ CRLF_string[3],debug_string[10], parsed_message_line[128],parsed_keyword[128],parsed_value[128], /* These are used for parsing message lines. */ message_file_suffix[]=".msg", config_file_name[64],help_file_name[64],info_file_name[64], data_file_name[64],distribution_file_name[64], bbslist_file_name[64], bbslist_header_spec[64],bbslist_trailer_spec[64],update_password[16], incoming_file_name[64],outgoing_file_name[64],netmail_directory_spec[64]; div_t results; /* Used for splitting integers into separate bytes. */ /*----------------------- Program functions ------------------------*/ void send_attached_bbslist() { printf("Sending attached bbslist now.\n"); if ( fidonet_send_message(from_bbslist_program, incoming_header.fromUserName, "", bbslist_file_name, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, incoming_header.origNode_loworder, incoming_header.origNode_highorder, incoming_header.origNet_loworder, incoming_header.origNet_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); add_to_message_body_file(" The BBS listing you requested has been attached as BBSLIST.TXT."); create_bbslist_flag = 1; } void process_bbslist_change(unique_number) { printf("Processing bbslist change for number %d.\n",unique_number); if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */ { add_to_message_body_file(" Invalid update password; please send update password as subject of message."); add_to_message_body_file(" Skipping keywords up to blank (separator) line or end of message."); while (parsed_keyword[0]) parse_message_line(); return; } errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0); if (errcode) { printf("?Error opening data file to change record; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } results = div(unique_number,256); /* Try to read key. */ data_record.unique_number_highorder = results.quot; data_record.unique_number_loworder = results.rem; errcode = indexed_file(&data_file_handle,I_F_READ,&data_record,0); if (errcode == I_F_ERROR_KEYNOTFOUND) { strcpy(temp_string," ?Can't read unique number to change: "); itoa(unique_number,temp_string_2,10); strcat(temp_string,temp_string_2); add_to_message_body_file(temp_string); indexed_file(&data_file_handle,I_F_CLOSE,"",0); while (parsed_keyword[0]) /* Skip through the change field names */ parse_message_line(); /* until we get to a blank or end. */ return; } /* We have read the record. Modify the fields listed in the message. */ while (!parse_message_line()) /* Quit if EOF reached. */ { /* printf("Parsed keyword: %s Parsed value: %s\n",parsed_keyword,parsed_value); */ if (!parsed_keyword[0]) /* Blank line in message? */ break; /* End of this particular function. */ if (!strcmp(parsed_keyword,"name")) strncpy(data_record.name,parsed_value,sizeof(data_record.name)); else if (!strcmp(parsed_keyword,"sysop")) strncpy(data_record.sysop,parsed_value,sizeof(data_record.sysop)); else if (!strcmp(parsed_keyword,"sysopreal")) strncpy(data_record.sysopreal,parsed_value,sizeof(data_record.sysopreal)); else if (!strcmp(parsed_keyword,"number")) strncpy(data_record.number,parsed_value,sizeof(data_record.number)); else if (!strcmp(parsed_keyword,"addr1")) strncpy(data_record.addr1,parsed_value,sizeof(data_record.addr1)); else if (!strcmp(parsed_keyword,"addr2")) strncpy(data_record.addr2,parsed_value,sizeof(data_record.addr2)); else if (!strcmp(parsed_keyword,"addr3")) strncpy(data_record.addr3,parsed_value,sizeof(data_record.addr3)); else if (!strcmp(parsed_keyword,"baud")) strncpy(data_record.baud,parsed_value,sizeof(data_record.baud)); else if (!strcmp(parsed_keyword,"location")) strncpy(data_record.location,parsed_value,sizeof(data_record.location)); else if (!strcmp(parsed_keyword,"hours")) strncpy(data_record.hours,parsed_value,sizeof(data_record.hours)); else if (!strcmp(parsed_keyword,"software")) strncpy(data_record.software,parsed_value,sizeof(data_record.software)); else { strcpy(temp_string," ?Unknown keyword skipped: "); strcat(temp_string,parsed_keyword); add_to_message_body_file(temp_string); } } /* We have modified the data in the record. */ errcode = indexed_file(&data_file_handle,I_F_REWRITE,&data_record,0); if (errcode) { /* The record was successfully added? */ printf("?Unexpected error rewriting record; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } indexed_file(&data_file_handle,I_F_CLOSE,data_file_name,0); strcpy(temp_string," Changes made to listing for BBS with unique number "); itoa(unique_number,temp_string_2,10); strcat(temp_string,temp_string_2); add_to_message_body_file(temp_string); create_bbslist_flag = 1; } void process_bbslist_addition() { short unique_number=0; /* Holds the unique number of the created message. */ printf("Processing bbslist addition.\n"); if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */ { add_to_message_body_file(" Invalid update password; please send update password as subject of message."); add_to_message_body_file(" Skipping keywords up to blank (separator) line or end of message."); while (parsed_keyword[0]) parse_message_line(); return; } memset(&data_record,0,sizeof(struct data_record_type)); while (!parse_message_line()) /* Quit if EOF reached. */ { if (!parsed_keyword[0]) /* Blank line in message? */ { printf("Blank keyword encountered; end of ADD function.\n"); break; /* End of this particular function. */ } if (!strcmp(parsed_keyword,"name")) strncpy(data_record.name,parsed_value,sizeof(data_record.name)); else if (!strcmp(parsed_keyword,"sysop")) strncpy(data_record.sysop,parsed_value,sizeof(data_record.sysop)); else if (!strcmp(parsed_keyword,"sysopreal")) strncpy(data_record.sysopreal,parsed_value,sizeof(data_record.sysopreal)); else if (!strcmp(parsed_keyword,"number")) strncpy(data_record.number,parsed_value,sizeof(data_record.number)); else if (!strcmp(parsed_keyword,"addr1")) strncpy(data_record.addr1,parsed_value,sizeof(data_record.addr1)); else if (!strcmp(parsed_keyword,"addr2")) strncpy(data_record.addr2,parsed_value,sizeof(data_record.addr2)); else if (!strcmp(parsed_keyword,"addr3")) strncpy(data_record.addr3,parsed_value,sizeof(data_record.addr3)); else if (!strcmp(parsed_keyword,"baud")) strncpy(data_record.baud,parsed_value,sizeof(data_record.baud)); else if (!strcmp(parsed_keyword,"location")) strncpy(data_record.location,parsed_value,sizeof(data_record.location)); else if (!strcmp(parsed_keyword,"hours")) strncpy(data_record.hours,parsed_value,sizeof(data_record.hours)); else if (!strcmp(parsed_keyword,"software")) strncpy(data_record.software,parsed_value,sizeof(data_record.software)); else { strcpy(temp_string," ?Unknown keyword skipped: "); strcat(temp_string,parsed_keyword); add_to_message_body_file(temp_string); } } if (DEBUG_FLAG) printf("Opening indexed file for I/O now.\n"); errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0); if (errcode) { printf("?Error opening data file to add record; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } while (1) { results = div(unique_number,256); /* Try to write with key; might exist already! */ data_record.unique_number_highorder = results.quot; data_record.unique_number_loworder = results.rem; printf("Trying to write record with loworder %d and highorder %d now.\n",data_record.unique_number_loworder,data_record.unique_number_highorder); errcode = indexed_file(&data_file_handle,I_F_WRITE,&data_record,0); if (errcode == I_F_ERROR_KEYEXISTS) /* Go try the next unique number. */ { if (DEBUG_FLAG) printf("Unique number %d already in file; trying next number.\n",unique_number); unique_number++; continue; } if (!errcode) /* The record was successfully added? */ break; printf("?Unexpected error adding record; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } if (DEBUG_FLAG) printf("Record was added ok.\n"); indexed_file(&data_file_handle,I_F_CLOSE,data_file_name,0); strcpy(temp_string," BBS added to list and given unique number "); itoa(unique_number,temp_string_2,10); strcat(temp_string,temp_string_2); add_to_message_body_file(temp_string); create_bbslist_flag = 1; } void process_bbslist_deletion(short unique_number) { printf("Processing bbslist deletion of number %d.\n",unique_number); if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */ { add_to_message_body_file(" Invalid update password; please send update password as subject of message."); add_to_message_body_file(" Skipping keywords up to blank (separator) line or end of message."); while (parsed_keyword[0]) parse_message_line(); return; } /* Try to delete the BBS list entry with that unique number from the data file.*/ errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0); if (errcode) { printf("?Error opening data file; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } results = div(unique_number,256); /* Figure out the key. */ data_record.unique_number_highorder = results.quot; data_record.unique_number_loworder = results.rem; errcode = indexed_file(&data_file_handle,I_F_READ,&data_record,0); if (!errcode) errcode = indexed_file(&data_file_handle,I_F_DELETE,&data_record,0); if (errcode == I_F_ERROR_KEYNOTFOUND) { strcpy(temp_string," ?Unable to delete BBS with unique number "); itoa(unique_number,temp_string_2,10); strcat(temp_string,temp_string_2); strcat(temp_string,"; doesn't exist!"); add_to_message_body_file(temp_string); } else if (errcode) { printf("?Error deleting unique number %d; error code: %d\n",unique_number,errcode); exit(ERRORLEVEL_ENGINE); } else { strcpy(temp_string," BBS with unique number "); itoa(unique_number,temp_string_2,10); strcat(temp_string,temp_string_2); strcat(temp_string," deleted!"); add_to_message_body_file(temp_string); } indexed_file(&data_file_handle,I_F_CLOSE,"",0); /* Close the data file. */ create_bbslist_flag = 1; } void send_info_message() { printf("Sending info. message.\n"); if ( fidonet_send_message(from_bbslist_program, incoming_header.fromUserName, "", info_file_name, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, incoming_header.origNode_loworder, incoming_header.origNode_highorder, incoming_header.origNet_loworder, incoming_header.origNet_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); add_to_message_body_file(" The info file BBSLIST.INF has been attached to you."); } void process_distribution_list_update(char update_mode,char net_and_node[]) /* Update mode is 'a'dd or 'd'elete; net_and_node is "xxx/xxx". */ { char the_net[8]="",the_node[8]="",*temp_char_ptr; unsigned short net_number,node_number; printf("Processing distribution list update; mode %c, net/node %s.\n",update_mode,net_and_node); if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */ { add_to_message_body_file(" Invalid update password; please send update password as subject of message."); add_to_message_body_file(" Skipping keywords up to blank (separator) line or end of message."); while (parsed_keyword[0]) parse_message_line(); return; } errcode = indexed_file(&distribution_file_handle,I_F_OPEN_READ,distribution_file_name,0); if (errcode) { printf("!Couldn't open distribution file; attempting to create new one\n"); strcpy(I_F_FILE_ATTRIBUTES,"4 1 0 4 0"); errcode = indexed_file(&distribution_file_handle,I_F_OPEN_WRITE,distribution_file_name,0); } if (errcode) { printf("?Error checking/creating distribution file; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } indexed_file(&distribution_file_handle,I_F_CLOSE,"",0); if (strstr(net_and_node,"/")==NULL) /* Bad format (slash missing)? */ { add_to_message_body_file(" ?Bad format; slash missing from net/node. Specify as xxx/xxx."); return; } temp_char_ptr = strtok(net_and_node,"/"); /* Now parse the net/node supplied. */ if (temp_char_ptr) strcpy(the_net,temp_char_ptr); temp_char_ptr = strtok(NULL,"/"); if (temp_char_ptr) strcpy(the_node,temp_char_ptr); net_number = (unsigned short)atol(the_net); node_number = (unsigned short)atol(the_node); if (!net_number) { add_to_message_body_file(" ?Net number invalid or zero -or- net/node format wrong (use xxx/xxx)."); return; } distribution_record.net_highorder = (net_number >> 8) & 255; distribution_record.net_loworder = net_number & 255; distribution_record.node_highorder = (node_number >> 8) & 255; distribution_record.node_loworder = node_number & 255; if (DEBUG_FLAG) printf("\n%d %d %d %d ----- TEST\n",distribution_record.net_highorder, distribution_record.net_loworder,distribution_record.node_highorder, distribution_record.node_loworder); errcode = indexed_file(&distribution_file_handle,I_F_OPEN_IO,distribution_file_name,0); if (errcode) { printf("!Couldn't reopen distribution file; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } errcode = indexed_file(&distribution_file_handle,I_F_READ,&distribution_record,0); if (errcode) { if (update_mode == 'a') goto add_to_list; add_to_message_body_file(" ?Couldn't find net/node in the distribution list."); goto update_done; } if (update_mode == 'a') { add_to_message_body_file(" ?Net/node already in the distribution list."); goto update_done; } errcode = indexed_file(&distribution_file_handle,I_F_DELETE,&distribution_record,0); if (errcode) { printf("?Invalid delete after good read in process_distribution_list_update()\n"); printf(" Engine error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } goto send_verification; add_to_list: errcode = indexed_file(&distribution_file_handle,I_F_WRITE,&distribution_record,0); if (errcode) { printf("?Invalid write in process_distribution_list_update(); error: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } if ( fidonet_send_message(from_bbslist_program, "Sysop", ";Your system has been added to the BBSLIST distribution list.", bbslist_file_name, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, distribution_record.node_loworder, distribution_record.node_highorder, distribution_record.net_loworder, distribution_record.net_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); if ( fidonet_send_message(from_bbslist_program, "Sysop", ";Attached is the help file for the BBSLIST message processor.", help_file_name, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, distribution_record.node_loworder, distribution_record.node_highorder, distribution_record.net_loworder, distribution_record.net_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); add_to_message_body_file(" New node notified and sent latest list and help file."); /* Now send the distribution list along in the response message. */ send_verification: memset(&distribution_record,0,sizeof(struct distribution_record_type)); errcode = indexed_file(&distribution_file_handle,I_F_START,&distribution_record,0); add_to_message_body_file(" This is a list of the nodes currently on the distribution list:"); while (!indexed_file(&distribution_file_handle,I_F_READNEXT,&distribution_record,0)) { net_number = (distribution_record.net_highorder << 8) + distribution_record.net_loworder; ltoa((long)net_number,the_net,10); node_number = (distribution_record.node_highorder << 8) + distribution_record.node_loworder; ltoa((long)node_number,the_node,10); strcpy(temp_string," "); strcat(temp_string,the_net); strcat(temp_string,"/"); strcat(temp_string,the_node); add_to_message_body_file(temp_string); } add_to_message_body_file(" (end of distribution list)"); update_done: indexed_file(&distribution_file_handle,I_F_CLOSE,"",0); } /*--------------- Message character/line subroutines ---------------*/ int read_character_from_message() /* Returns character or -1 for EOF. */ { /* Also return EOF if NULL found. */ char input_char; int result; read_character: result = fread(&input_char,1,1,incoming_file); if (!result) /* End of file? Return EOF. */ return(-1); if (input_char == 00) /* End of message found; return EOF. */ return(-1); if (input_char == 10) /* Skip linefeeds in the message body. */ goto read_character; return(input_char); } int parse_message_line() /* Sets global variables parsed_keyword and */ { /* and parsed_value. Returns non-zero if EOF. */ int parsed_keyword_pointer=0,parsed_value_pointer=0,char_from_file, parsed_message_line_pointer=0; if (DEBUG_FLAG) printf("\nThis is parse_message_line().\n"); parsed_keyword[0] = 0; /* Initialize to null strings. */ parsed_value[0] = 0; parsed_message_line[0] = 0; char_from_file = read_character_from_message(); /* Read 1st char from message.*/ if (char_from_file == -1) /* EOF? */ { if (DEBUG_FLAG) printf("The first character read was EOF.\n"); return(1); } while (1) /* Process/read characters until we break out. */ { printf("Keyword character read; value: %d; character: %c\n",char_from_file,char_from_file); if (char_from_file == 13) { if (DEBUG_FLAG) printf("CR found while parsing keyword.\n"); parsed_keyword[parsed_keyword_pointer] = 0; parsed_message_line[parsed_message_line_pointer] = 0; return(0); } parsed_keyword[parsed_keyword_pointer++] = char_from_file; parsed_message_line[parsed_message_line_pointer++] = char_from_file; if (parsed_keyword_pointer == sizeof(parsed_keyword)) return(0); /* Before it overflows! */ if (parsed_message_line_pointer == sizeof(parsed_message_line)) return(0); char_from_file = read_character_from_message(); if (char_from_file == -1) { parsed_keyword[parsed_keyword_pointer] = 0; /* Terminate string. */ parsed_message_line[parsed_message_line_pointer] = 0; if (DEBUG_FLAG) printf("EOF char found while parsing keyword.\n"); return(0); } if (char_from_file == '=') { parsed_keyword[parsed_keyword_pointer] = 0; parsed_message_line[parsed_message_line_pointer++] = '='; break; } /* Go and read characters after '=' sign. */ /* Go and read next character of keyword. */ } char_from_file = read_character_from_message(); if (char_from_file == -1) { parsed_message_line[parsed_message_line_pointer] = 0; if (DEBUG_FLAG) printf("EOF char found while reading char after =.\n"); return(0); } while (1) { printf("Value character read; value: %d; character: %c\n",char_from_file,char_from_file); if (char_from_file == 13) { parsed_value[parsed_value_pointer] = 0; parsed_message_line[parsed_message_line_pointer] = 0; if (DEBUG_FLAG) printf("CR found while reading value.\n"); break; } parsed_value[parsed_value_pointer++] = char_from_file; parsed_message_line[parsed_message_line_pointer++] = char_from_file; if (parsed_value_pointer == sizeof(parsed_value)) break; /* Prevent overflow! */ if (parsed_message_line_pointer == sizeof(parsed_message_line)) break; char_from_file = read_character_from_message(); if (char_from_file == -1) { parsed_value[parsed_value_pointer] = 0; parsed_message_line[parsed_message_line_pointer] = 0; if (DEBUG_FLAG) printf("EOF char found while reading value.\n"); break; } } return(0); } void process_this_message() { char temp_string[80],file_to_attach[80]=""; printf("Processing message %d....\n",message_number); decode_attribute_word((incoming_header.AttributeWord_highorder*256)+incoming_header.AttributeWord_loworder); if (flag_recd) /* This message already received? */ return; if (init_message_body_file()) /* Where we echo incoming and write reply lines to.*/ { printf("?Error initializing message body file\n"); exit(ERRORLEVEL_FATAL); } while (!parse_message_line()) /* Read lines of incoming message until EOF. */ { if (!parsed_message_line[0]) /* Blank line? */ continue; /* Ignore blanks at this point. */ if (parsed_message_line[0] != 1) /* Don't echo kludge lines to requester. */ { if (add_to_message_body_file(parsed_message_line)) { printf("?Error adding to message body file.\n"); exit(ERRORLEVEL_FATAL); } } if (DEBUG_FLAG) { printf("Just wrote parsed_message_line to message_body_file.\n"); printf("Keyword: %s Value: %s\n",parsed_keyword,parsed_value); } if (!strcmp(parsed_keyword,"DELETE")) process_bbslist_deletion(atoi(parsed_value)); else if (!strcmp(parsed_keyword,"ADD") ) process_bbslist_addition(); else if (!strcmp(parsed_keyword,"CHANGE")) process_bbslist_change(atoi(parsed_value)); else if (!strcmp(parsed_keyword,"LIST") ) send_attached_bbslist(); else if (!strcmp(parsed_keyword,"HELP") ) { strcpy(file_to_attach,help_file_name); add_to_message_body_file(" The help file is attached, per your request."); } else if (!strcmp(parsed_keyword,"INFO") ) send_info_message(); else if (!strcmp(parsed_keyword,"DIST-A")) process_distribution_list_update('a',parsed_value); else if (!strcmp(parsed_keyword,"DIST-D")) process_distribution_list_update('d',parsed_value); else if (parsed_keyword[0] == 1 ) { /* printf("Skipping kludge line.\n"); */ continue; } else { strcpy(file_to_attach,help_file_name); add_to_message_body_file(" ?Keyword unrecognized at this point; see attached help file."); } } if (DEBUG_FLAG) printf("Getting ready to send back message body file %s\n",message_body_filename); if ( fidonet_send_message(from_bbslist_program, incoming_header.fromUserName, message_body_filename, file_to_attach, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, incoming_header.origNode_loworder, incoming_header.origNode_highorder, incoming_header.origNet_loworder, incoming_header.origNet_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); incoming_header.AttributeWord_loworder |= 4; /* Mark this message received. */ fseek(incoming_file,0,SEEK_SET); result = fwrite(&incoming_header,sizeof(struct message_header_type),1,incoming_file); if (!result) { printf("?Error rewriting message header of incoming file\n"); exit(ERRORLEVEL_FATAL); } } void init_print_records() { memset(&print_record_1,32,sizeof(struct print_record_1_type)); memset(&print_record_2,32,sizeof(struct print_record_2_type)); memset(&print_record_3,32,sizeof(struct print_record_3_type)); } void move_to_print_field(char output_field[],char input_field[],char field_size) { char offset_counter=0; while (offset_counter < field_size) { if (!input_field[offset_counter]) break; output_field[offset_counter] = input_field[offset_counter]; offset_counter++; } } /*--------------------------- The Code -------------------------------------*/ int main(int argc, char *argv[]) { struct date current_date; struct time current_time; printf("----Begin program execution\n"); if (argc != 2) { printf("?Illegal number of arguments; command line syntax: \n"); printf(" BBSLIST BBSLIST.CFG \n"); printf(" where BBSLIST.CFG is the path to the config file.\n"); return(ERRORLEVEL_BAD_PARAMETER); } strcpy(config_file_name,argv[1]); config_file = fopen(config_file_name,"rt"); if (config_file == NULL) { printf("?Can't open config file %s\n",config_file_name); return(ERRORLEVEL_BAD_PARAMETER); } fgets(help_file_name,sizeof(help_file_name),config_file); help_file_name[strlen(help_file_name)-1] = 0; /* Cut off LF. */ fgets(info_file_name,sizeof(info_file_name),config_file); info_file_name[strlen(info_file_name)-1] = 0; /* Cut off LF. */ fgets(data_file_name,sizeof(data_file_name),config_file); data_file_name[strlen(data_file_name)-1] = 0; fgets(distribution_file_name,sizeof(distribution_file_name),config_file); distribution_file_name[strlen(distribution_file_name)-1] = 0; fgets(bbslist_file_name,sizeof(bbslist_file_name),config_file); bbslist_file_name[strlen(bbslist_file_name)-1] = 0; fgets(netmail_directory_spec,sizeof(netmail_directory_spec),config_file); netmail_directory_spec[strlen(netmail_directory_spec)-1] = 0; if (netmail_directory_spec[strlen(netmail_directory_spec)-1] != '\\') { netmail_directory_spec[strlen(netmail_directory_spec)+1] = 0; netmail_directory_spec[strlen(netmail_directory_spec)] = '\\'; } fgets(bbslist_header_spec,sizeof(bbslist_header_spec),config_file); bbslist_header_spec[strlen(bbslist_header_spec)-1] = 0; fgets(bbslist_trailer_spec,sizeof(bbslist_trailer_spec),config_file); bbslist_trailer_spec[strlen(bbslist_trailer_spec)-1] = 0; fgets(update_password,sizeof(update_password),config_file); update_password[strlen(update_password)-1] = 0; fgets(debug_string,sizeof(debug_string),config_file); debug_string[strlen(debug_string)-1] = 0; fclose(config_file); if (debug_string[0] == 'Y') /* Turn debug mode on? */ DEBUG_FLAG = 1; if (debug_string[1] == 'Y') delete_received_messages_flag = 1; if (DEBUG_FLAG) { printf("Help file spec: %s\n",help_file_name); printf("Info file spec: %s\n",info_file_name); printf("Data file spec: %s\n",data_file_name); printf("Distribution file name: %s\n",distribution_file_name); printf("BBSLIST (text) file spec: %s\n",bbslist_file_name); printf("Netmail directory spec: %s\n",netmail_directory_spec); printf("BBSLIST header file spec: %s\n",bbslist_header_spec); printf("BBSLIST trailer file spec: %s\n",bbslist_trailer_spec); printf("Update password: %s\n",update_password); } errcode = indexed_file(&data_file_handle,I_F_OPEN_READ,data_file_name,0); if (errcode) { printf("!Couldn't open data file; attempting to create new one\n"); strcpy(I_F_FILE_ATTRIBUTES,"202 2 0 2 0 2 30 0"); errcode = indexed_file(&data_file_handle,I_F_OPEN_WRITE,data_file_name,0); } if (errcode) { printf("?Error checking/creating data file; error code: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } indexed_file(&data_file_handle,I_F_CLOSE,"",0); CR_string[0] = 13; /* We'll use this for stuff. */ CR_string[1] = 0; CRLF_string[0] = 13; CRLF_string[1] = 10; CRLF_string[2] = 0; message_number = 0; /* Start looking for messages addressed to us. */ while (1) /* Do this until we break out. */ { if (message_number++ > MAX_MSGS_TO_SCAN) /* Check, then increment. */ break; strcpy(incoming_file_name,netmail_directory_spec); itoa(message_number,temp_string,10); strcat(incoming_file_name,temp_string); strcat(incoming_file_name,message_file_suffix); incoming_file = fopen(incoming_file_name,"rb+"); if (incoming_file != NULL) /* Found a message file? */ { fread(&incoming_header,sizeof(struct message_header_type),1,incoming_file); temp_string[0] = 0; strncat(temp_string,incoming_header.toUserName,sizeof(incoming_header.toUserName)); strupr(temp_string); result = memcmp(temp_string,"BBSLIST",8); if (!result) { process_this_message(); /* We found a message addressed to BBSLIST. */ if (delete_received_messages_flag) { if (unlink(incoming_file_name)) { printf("?Error deleting the incoming message we just processed.\n"); printf(" The filename was %s.\n",incoming_file_name); exit(ERRORLEVEL_FATAL); } } } fclose(incoming_file); } } if (!create_bbslist_flag) /* Anything else to do? */ exit(ERRORLEVEL_SUCCESS); /* Guess not! */ /* First, write out the new bbslist text file from the data file. */ bbslist_file = fopen(bbslist_file_name,"wb"); if (bbslist_file == NULL) { printf("?Error opening bbslist file for output\n"); exit(ERRORLEVEL_CONFIGURATION); } temp_file = fopen(bbslist_header_spec,"rt"); if (temp_file == NULL) { printf("?Error opening header file for bbs list\n"); exit(ERRORLEVEL_CONFIGURATION); } while (!feof(temp_file)) { fgets(temp_string,sizeof(temp_string),temp_file); if (strlen(temp_string)) temp_string[strlen(temp_string)-1] = 0; /* Strip off CR. */ fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); } fclose(temp_file); /* Now print out each record in the indexed file. */ errcode = indexed_file(&data_file_handle,I_F_OPEN_READ,data_file_name,0); if (errcode) { printf("?Error opening indexed file to write out new bbs list: %d\n",errcode); exit(ERRORLEVEL_ENGINE); } memset(&data_record,0,sizeof(struct data_record_type)); errcode = indexed_file(&data_file_handle,I_F_START,&data_record,1); /* Start by name. */ if (!errcode) errcode = indexed_file(&data_file_handle,I_F_READNEXT,&data_record,0); while (!errcode) { /* Copy the data fields to the print fields and print. */ init_print_records(); move_to_print_field(print_record_1.name, data_record.name, sizeof(print_record_1.name)); move_to_print_field(print_record_1.number, data_record.number, sizeof(print_record_1.number)); move_to_print_field(print_record_1.baud, data_record.baud, sizeof(print_record_1.baud)); move_to_print_field(print_record_1.hours, data_record.hours, sizeof(print_record_1.hours)); move_to_print_field(print_record_2.sysop, data_record.sysop, sizeof(print_record_2.sysop)); move_to_print_field(print_record_2.sysopreal,data_record.sysopreal,sizeof(print_record_2.sysopreal)); move_to_print_field(print_record_2.location, data_record.location, sizeof(print_record_2.location)); move_to_print_field(print_record_2.software, data_record.software, sizeof(print_record_2.software)); move_to_print_field(print_record_3.addr1, data_record.addr1, sizeof(print_record_3.addr1)); move_to_print_field(print_record_3.addr2, data_record.addr2, sizeof(print_record_3.addr2)); move_to_print_field(print_record_3.addr3, data_record.addr3, sizeof(print_record_3.addr3)); itoa((data_record.unique_number_highorder*256)+data_record.unique_number_loworder,temp_string,10); move_to_print_field(print_record_3.unique_number,temp_string,sizeof(print_record_3.unique_number)); fwrite(&print_record_1,sizeof(struct print_record_1_type),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); fwrite(&print_record_2,sizeof(struct print_record_2_type),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); fwrite(&print_record_3,sizeof(struct print_record_3_type),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); errcode = indexed_file(&data_file_handle,I_F_READNEXT,&data_record,0); } indexed_file(&data_file_handle,I_F_CLOSE,"",0); temp_file = fopen(bbslist_trailer_spec,"rt"); if (temp_file == NULL) { printf("?Error opening trailer file for bbs list\n"); exit(ERRORLEVEL_CONFIGURATION); } while (!feof(temp_file)) { fgets(temp_string,sizeof(temp_string),temp_file); if (strlen(temp_string)) temp_string[strlen(temp_string)-1] = 0; fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); } fclose(temp_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); strcpy(temp_string,"This listing was last updated "); fwrite(temp_string,strlen(temp_string),1,bbslist_file); getdate(¤t_date); itoa(current_date.da_mon,temp_string,10); fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite("/",1,1,bbslist_file); itoa(current_date.da_day,temp_string,10); fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite("/",1,1,bbslist_file); itoa(current_date.da_year,temp_string,10); fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite(" at ",4,1,bbslist_file); gettime(¤t_time); itoa(current_time.ti_hour,temp_string,10); fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite(":",1,1,bbslist_file); itoa(current_time.ti_min,temp_string,10); fwrite(temp_string,strlen(temp_string),1,bbslist_file); fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file); fclose(bbslist_file); /* Now send to the distribution list, if any. */ if (!indexed_file(&distribution_file_handle,I_F_OPEN_READ,distribution_file_name,0)) /* Does file exist at all? */ { memset(&distribution_record,0,sizeof(struct distribution_record_type)); indexed_file(&distribution_file_handle,I_F_START,&distribution_record,0); while (!indexed_file(&distribution_file_handle,I_F_READNEXT,&distribution_record,0)) { if ( fidonet_send_message(from_bbslist_program, "Sysop", "", bbslist_file_name, netmail_directory_spec, incoming_header.destNode_loworder, incoming_header.destNode_highorder, distribution_record.node_loworder, distribution_record.node_highorder, distribution_record.net_loworder, distribution_record.net_highorder, incoming_header.destNet_loworder, incoming_header.destNet_highorder, DEBUG_FLAG) ) exit(ERRORLEVEL_FATAL); } indexed_file(&distribution_file_handle,I_F_CLOSE,"",0); } return(ERRORLEVEL_LIST_CHANGED); }