C 9
Bbslist.c Guest on 21st November 2020 10:05:16 AM
  1.  
  2. /* This version adds the distribution list and cleans up the program's
  3.     handling of messages (especially outgoing ones) by using the
  4.     fidonet.h file for some fidonet-specific functions.            */
  5.  
  6. /*
  7. This program scans the message files in the netmail directory looking
  8. for messages addressed to it (BBSLIST as the 1st 7 chars.).  Any messages
  9. which are null or of unrecognized format will engender a "help" message
  10. which is sent to the originator of the message.  Messages which are requests
  11. are processed immediately.  Messages which would update the bbs listing are
  12. first checked for a valid password.
  13.  
  14. ----- Make sure you compile this program from the command line (bcc)! -----
  15. */
  16.  
  17. #define MAX_MSGS_TO_SCAN 200  /* We scan messages from 1 to this */
  18.                               /*  number for the name BBSLIST.   */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <process.h>
  23. #include <dos.h>       /* Dos-specific functions are used to get date/time. */
  24.  
  25. #include "fidonet.h"
  26. #include "i_f_eng.c"
  27.  
  28. #define ERRORLEVEL_SUCCESS       0
  29. #define ERRORLEVEL_LIST_CHANGED  1
  30. #define ERRORLEVEL_BAD_PARAMETER 2
  31. #define ERRORLEVEL_CONFIGURATION 3
  32. #define ERRORLEVEL_ENGINE        4
  33. #define ERRORLEVEL_FATAL         5
  34.  
  35. char DEBUG_FLAG=0,                      /* These two fields are gotten from the "debug_string" */
  36.      delete_received_messages_flag=0;   /*  line of the configuration file.                    */
  37.  
  38. struct data_record_type  {
  39.   char unique_number_highorder;
  40.   char unique_number_loworder;
  41.   char name[30];
  42.   char sysop[20];
  43.   char sysopreal[20];
  44.   char number[10];
  45.   char addr1[20];
  46.   char addr2[20];
  47.   char addr3[20];
  48.   char baud[20];
  49.   char location[20];
  50.   char hours[10];
  51.   char software[10];
  52.   }  data_record;
  53.  
  54. struct distribution_record_type  {
  55.   unsigned char net_highorder;
  56.   unsigned char net_loworder;
  57.   unsigned char node_highorder;
  58.   unsigned char node_loworder;
  59.   }  distribution_record;
  60.  
  61. struct print_record_1_type  {
  62.   char name[30],
  63.        filler_1[2],
  64.        number[10],
  65.        filler_2[2],
  66.        baud[20],
  67.        filler_3[2],
  68.        hours[10];
  69.   }  print_record_1;
  70.  
  71. struct print_record_2_type  {
  72.   char sysop[20],
  73.            filler_1[2],
  74.            sysopreal[20],
  75.            filler_2[2],
  76.            location[20],
  77.            filler_3[2],
  78.        software[10];
  79.   }  print_record_2;
  80.  
  81. struct print_record_3_type  {
  82.   char addr1[20],
  83.            filler_1[2],
  84.            addr2[20],
  85.            filler_2[2],
  86.            addr3[20],
  87.            filler_3[2],
  88.        unique_number[10];
  89.   }  print_record_3;
  90.  
  91. char create_bbslist_flag=0; /* Set non-zero if new bbslist.txt should be written.*/
  92.  
  93. FILE *config_file,*incoming_file,*outgoing_file,*bbslist_file,*temp_file;
  94. int message_number = 0;    /* The message number to open; we search  */
  95.                                                    /*  the first MAX_MSGS_TO_SCAN messages.  */
  96. int temp_int,
  97.   data_file_handle, /* Holds the file handle for the file engine. */
  98.   distribution_file_handle,
  99.   errcode,          /* Used for holding results of indexed file engine calls. */
  100.   result;           /* This is used to hold the result of memcmp() calls. */
  101. char from_bbslist_program[]="BBSLIST -- the bbslist maintainer",
  102.   temp_string[128],temp_string_2[128],
  103.   CR_string[2],   /* This gets initialized to be a CR we can append to lines. */
  104.   CRLF_string[3],debug_string[10],
  105.   parsed_message_line[128],parsed_keyword[128],parsed_value[128],  /* These are used for parsing message lines. */
  106.   message_file_suffix[]=".msg",
  107.   config_file_name[64],help_file_name[64],info_file_name[64],
  108.   data_file_name[64],distribution_file_name[64],
  109.   bbslist_file_name[64],
  110.   bbslist_header_spec[64],bbslist_trailer_spec[64],update_password[16],
  111.   incoming_file_name[64],outgoing_file_name[64],netmail_directory_spec[64];
  112. div_t results;  /* Used for splitting integers into separate bytes. */
  113.  
  114.  
  115. /*----------------------- Program functions ------------------------*/
  116. void send_attached_bbslist()
  117. {
  118. printf("Sending attached bbslist now.\n");
  119. if ( fidonet_send_message(from_bbslist_program,
  120.                           incoming_header.fromUserName,
  121.                           "",
  122.                           bbslist_file_name,
  123.                           netmail_directory_spec,
  124.                           incoming_header.destNode_loworder,
  125.                           incoming_header.destNode_highorder,
  126.                           incoming_header.origNode_loworder,
  127.                           incoming_header.origNode_highorder,
  128.                           incoming_header.origNet_loworder,
  129.                           incoming_header.origNet_highorder,
  130.                           incoming_header.destNet_loworder,
  131.                           incoming_header.destNet_highorder,
  132.                           DEBUG_FLAG) )
  133.   exit(ERRORLEVEL_FATAL);
  134. add_to_message_body_file("  The BBS listing you requested has been attached as BBSLIST.TXT.");
  135. create_bbslist_flag = 1;
  136. }
  137.  
  138. void process_bbslist_change(unique_number)
  139. {
  140. printf("Processing bbslist change for number %d.\n",unique_number);
  141. if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */
  142.   {
  143.   add_to_message_body_file("  Invalid update password; please send update password as subject of message.");
  144.   add_to_message_body_file("  Skipping keywords up to blank (separator) line or end of message.");
  145.   while (parsed_keyword[0])
  146.     parse_message_line();
  147.   return;
  148.   }
  149. errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0);
  150. if (errcode)  {
  151.   printf("?Error opening data file to change record; error code: %d\n",errcode);
  152.   exit(ERRORLEVEL_ENGINE);    }
  153. results = div(unique_number,256);    /* Try to read key. */
  154. data_record.unique_number_highorder = results.quot;
  155. data_record.unique_number_loworder  = results.rem;
  156. errcode = indexed_file(&data_file_handle,I_F_READ,&data_record,0);
  157. if (errcode == I_F_ERROR_KEYNOTFOUND)
  158.   {
  159.   strcpy(temp_string,"  ?Can't read unique number to change: ");
  160.   itoa(unique_number,temp_string_2,10);
  161.   strcat(temp_string,temp_string_2);
  162.   add_to_message_body_file(temp_string);
  163.   indexed_file(&data_file_handle,I_F_CLOSE,"",0);
  164.   while (parsed_keyword[0])  /* Skip through the change field names */
  165.         parse_message_line();    /*  until we get to a blank or end.    */
  166.   return;
  167.   }
  168. /* We have read the record.  Modify the fields listed in the message. */
  169. while (!parse_message_line())  /* Quit if EOF reached. */
  170.   {
  171.   /* printf("Parsed keyword: %s   Parsed value: %s\n",parsed_keyword,parsed_value); */
  172.   if (!parsed_keyword[0])   /* Blank line in message? */
  173.         break;                  /*  End of this particular function. */
  174.   if       (!strcmp(parsed_keyword,"name"))      strncpy(data_record.name,parsed_value,sizeof(data_record.name));
  175.    else if (!strcmp(parsed_keyword,"sysop"))     strncpy(data_record.sysop,parsed_value,sizeof(data_record.sysop));
  176.    else if (!strcmp(parsed_keyword,"sysopreal")) strncpy(data_record.sysopreal,parsed_value,sizeof(data_record.sysopreal));
  177.    else if (!strcmp(parsed_keyword,"number"))    strncpy(data_record.number,parsed_value,sizeof(data_record.number));
  178.    else if (!strcmp(parsed_keyword,"addr1"))     strncpy(data_record.addr1,parsed_value,sizeof(data_record.addr1));
  179.    else if (!strcmp(parsed_keyword,"addr2"))     strncpy(data_record.addr2,parsed_value,sizeof(data_record.addr2));
  180.    else if (!strcmp(parsed_keyword,"addr3"))     strncpy(data_record.addr3,parsed_value,sizeof(data_record.addr3));
  181.    else if (!strcmp(parsed_keyword,"baud"))      strncpy(data_record.baud,parsed_value,sizeof(data_record.baud));
  182.    else if (!strcmp(parsed_keyword,"location"))  strncpy(data_record.location,parsed_value,sizeof(data_record.location));
  183.    else if (!strcmp(parsed_keyword,"hours"))     strncpy(data_record.hours,parsed_value,sizeof(data_record.hours));
  184.    else if (!strcmp(parsed_keyword,"software"))  strncpy(data_record.software,parsed_value,sizeof(data_record.software));
  185.    else                                          {
  186.                                                  strcpy(temp_string,"  ?Unknown keyword skipped: ");
  187.                                                                                                  strcat(temp_string,parsed_keyword);
  188.                                                  add_to_message_body_file(temp_string);
  189.                                                  }
  190.   }
  191. /* We have modified the data in the record. */
  192. errcode = indexed_file(&data_file_handle,I_F_REWRITE,&data_record,0);
  193. if (errcode) { /* The record was successfully added? */
  194.   printf("?Unexpected error rewriting record; error code: %d\n",errcode);
  195.   exit(ERRORLEVEL_ENGINE);   }
  196. indexed_file(&data_file_handle,I_F_CLOSE,data_file_name,0);
  197. strcpy(temp_string,"  Changes made to listing for BBS with unique number ");
  198. itoa(unique_number,temp_string_2,10);
  199. strcat(temp_string,temp_string_2);
  200. add_to_message_body_file(temp_string);
  201. create_bbslist_flag = 1;
  202. }
  203.  
  204. void process_bbslist_addition()
  205. {
  206. short unique_number=0;  /* Holds the unique number of the created message. */
  207. printf("Processing bbslist addition.\n");
  208. if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */
  209.   {
  210.   add_to_message_body_file("  Invalid update password; please send update password as subject of message.");
  211.   add_to_message_body_file("  Skipping keywords up to blank (separator) line or end of message.");
  212.   while (parsed_keyword[0])
  213.     parse_message_line();
  214.   return;
  215.   }
  216. memset(&data_record,0,sizeof(struct data_record_type));
  217. while (!parse_message_line())  /* Quit if EOF reached. */
  218.   {
  219.   if (!parsed_keyword[0])   /* Blank line in message? */
  220.     {
  221.     printf("Blank keyword encountered; end of ADD function.\n");
  222.         break;                  /*  End of this particular function. */
  223.     }
  224.   if       (!strcmp(parsed_keyword,"name"))      strncpy(data_record.name,parsed_value,sizeof(data_record.name));
  225.    else if (!strcmp(parsed_keyword,"sysop"))     strncpy(data_record.sysop,parsed_value,sizeof(data_record.sysop));
  226.    else if (!strcmp(parsed_keyword,"sysopreal")) strncpy(data_record.sysopreal,parsed_value,sizeof(data_record.sysopreal));
  227.    else if (!strcmp(parsed_keyword,"number"))    strncpy(data_record.number,parsed_value,sizeof(data_record.number));
  228.    else if (!strcmp(parsed_keyword,"addr1"))     strncpy(data_record.addr1,parsed_value,sizeof(data_record.addr1));
  229.    else if (!strcmp(parsed_keyword,"addr2"))     strncpy(data_record.addr2,parsed_value,sizeof(data_record.addr2));
  230.    else if (!strcmp(parsed_keyword,"addr3"))     strncpy(data_record.addr3,parsed_value,sizeof(data_record.addr3));
  231.    else if (!strcmp(parsed_keyword,"baud"))      strncpy(data_record.baud,parsed_value,sizeof(data_record.baud));
  232.    else if (!strcmp(parsed_keyword,"location"))  strncpy(data_record.location,parsed_value,sizeof(data_record.location));
  233.    else if (!strcmp(parsed_keyword,"hours"))     strncpy(data_record.hours,parsed_value,sizeof(data_record.hours));
  234.    else if (!strcmp(parsed_keyword,"software"))  strncpy(data_record.software,parsed_value,sizeof(data_record.software));
  235.    else                                          {
  236.                                                  strcpy(temp_string,"  ?Unknown keyword skipped: ");
  237.                                                                                                  strcat(temp_string,parsed_keyword);
  238.                                                  add_to_message_body_file(temp_string);
  239.                                                  }
  240.   }
  241. if (DEBUG_FLAG)
  242.   printf("Opening indexed file for I/O now.\n");
  243. errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0);
  244. if (errcode)
  245.   {
  246.   printf("?Error opening data file to add record; error code: %d\n",errcode);
  247.   exit(ERRORLEVEL_ENGINE);
  248.   }
  249. while (1)
  250.   {
  251.   results = div(unique_number,256);    /* Try to write with key; might exist already! */
  252.   data_record.unique_number_highorder = results.quot;
  253.   data_record.unique_number_loworder  = results.rem;
  254.   printf("Trying to write record with loworder %d and highorder %d now.\n",data_record.unique_number_loworder,data_record.unique_number_highorder);
  255.   errcode = indexed_file(&data_file_handle,I_F_WRITE,&data_record,0);
  256.   if (errcode == I_F_ERROR_KEYEXISTS)  /* Go try the next unique number. */
  257.     {
  258.     if (DEBUG_FLAG)
  259.       printf("Unique number %d already in file; trying next number.\n",unique_number);
  260.     unique_number++;
  261.     continue;
  262.     }
  263.   if (!errcode)  /* The record was successfully added? */
  264.         break;
  265.   printf("?Unexpected error adding record; error code: %d\n",errcode);
  266.   exit(ERRORLEVEL_ENGINE);
  267.   }
  268. if (DEBUG_FLAG)
  269.   printf("Record was added ok.\n");
  270. indexed_file(&data_file_handle,I_F_CLOSE,data_file_name,0);
  271. strcpy(temp_string,"  BBS added to list and given unique number ");
  272. itoa(unique_number,temp_string_2,10);
  273. strcat(temp_string,temp_string_2);
  274. add_to_message_body_file(temp_string);
  275. create_bbslist_flag = 1;
  276. }
  277.  
  278. void process_bbslist_deletion(short unique_number)
  279. {
  280. printf("Processing bbslist deletion of number %d.\n",unique_number);
  281. if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */
  282.   {
  283.   add_to_message_body_file("  Invalid update password; please send update password as subject of message.");
  284.   add_to_message_body_file("  Skipping keywords up to blank (separator) line or end of message.");
  285.   while (parsed_keyword[0])
  286.     parse_message_line();
  287.   return;
  288.   }
  289. /* Try to delete the BBS list entry with that unique number from the data file.*/
  290. errcode = indexed_file(&data_file_handle,I_F_OPEN_IO,data_file_name,0);
  291. if (errcode)  {
  292.   printf("?Error opening data file; error code: %d\n",errcode);
  293.   exit(ERRORLEVEL_ENGINE);    }
  294. results = div(unique_number,256);    /* Figure out the key. */
  295. data_record.unique_number_highorder = results.quot;
  296. data_record.unique_number_loworder  = results.rem;
  297. errcode = indexed_file(&data_file_handle,I_F_READ,&data_record,0);
  298. if (!errcode)
  299.   errcode = indexed_file(&data_file_handle,I_F_DELETE,&data_record,0);
  300. if (errcode == I_F_ERROR_KEYNOTFOUND)
  301.   {
  302.   strcpy(temp_string,"  ?Unable to delete BBS with unique number ");
  303.   itoa(unique_number,temp_string_2,10);
  304.   strcat(temp_string,temp_string_2);
  305.   strcat(temp_string,"; doesn't exist!");
  306.   add_to_message_body_file(temp_string);
  307.   }
  308. else
  309. if (errcode)
  310.   {
  311.   printf("?Error deleting unique number %d; error code: %d\n",unique_number,errcode);
  312.   exit(ERRORLEVEL_ENGINE);
  313.   }
  314. else
  315.   {
  316.   strcpy(temp_string,"  BBS with unique number ");
  317.   itoa(unique_number,temp_string_2,10);
  318.   strcat(temp_string,temp_string_2);
  319.   strcat(temp_string," deleted!");
  320.   add_to_message_body_file(temp_string);
  321.   }
  322. indexed_file(&data_file_handle,I_F_CLOSE,"",0);  /* Close the data file. */
  323. create_bbslist_flag = 1;
  324. }
  325.  
  326. void send_info_message()
  327. {
  328. printf("Sending info. message.\n");
  329. if ( fidonet_send_message(from_bbslist_program,
  330.                           incoming_header.fromUserName,
  331.                           "",
  332.                           info_file_name,
  333.                           netmail_directory_spec,
  334.                           incoming_header.destNode_loworder,
  335.                           incoming_header.destNode_highorder,
  336.                           incoming_header.origNode_loworder,
  337.                           incoming_header.origNode_highorder,
  338.                           incoming_header.origNet_loworder,
  339.                           incoming_header.origNet_highorder,
  340.                           incoming_header.destNet_loworder,
  341.                           incoming_header.destNet_highorder,
  342.                           DEBUG_FLAG) )
  343.   exit(ERRORLEVEL_FATAL);
  344. add_to_message_body_file("  The info file BBSLIST.INF has been attached to you.");
  345. }
  346.  
  347. 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". */
  348. {
  349. char the_net[8]="",the_node[8]="",*temp_char_ptr;
  350. unsigned short net_number,node_number;
  351. printf("Processing distribution list update; mode %c, net/node %s.\n",update_mode,net_and_node);
  352. if (strcmp(incoming_header.subject,update_password)) /* Password not correct? */
  353.   {
  354.   add_to_message_body_file("  Invalid update password; please send update password as subject of message.");
  355.   add_to_message_body_file("  Skipping keywords up to blank (separator) line or end of message.");
  356.   while (parsed_keyword[0])
  357.     parse_message_line();
  358.   return;
  359.   }
  360. errcode = indexed_file(&distribution_file_handle,I_F_OPEN_READ,distribution_file_name,0);
  361. if (errcode)  {
  362.   printf("!Couldn't open distribution file; attempting to create new one\n");
  363.   strcpy(I_F_FILE_ATTRIBUTES,"4 1 0 4 0");
  364.   errcode = indexed_file(&distribution_file_handle,I_F_OPEN_WRITE,distribution_file_name,0);  }
  365. if (errcode)  {
  366.   printf("?Error checking/creating distribution file; error code: %d\n",errcode);
  367.   exit(ERRORLEVEL_ENGINE);    }
  368. indexed_file(&distribution_file_handle,I_F_CLOSE,"",0);
  369. if (strstr(net_and_node,"/")==NULL)       /* Bad format (slash missing)?      */
  370.   {
  371.   add_to_message_body_file("  ?Bad format; slash missing from net/node.  Specify as xxx/xxx.");
  372.   return;
  373.   }
  374. temp_char_ptr = strtok(net_and_node,"/"); /* Now parse the net/node supplied. */
  375. if (temp_char_ptr)
  376.         strcpy(the_net,temp_char_ptr);
  377. temp_char_ptr = strtok(NULL,"/");
  378. if (temp_char_ptr)
  379. strcpy(the_node,temp_char_ptr);
  380. net_number  = (unsigned short)atol(the_net);
  381. node_number = (unsigned short)atol(the_node);
  382. if (!net_number)
  383.   {
  384.   add_to_message_body_file("  ?Net number invalid or zero -or- net/node format wrong (use xxx/xxx).");
  385.   return;
  386.   }
  387. distribution_record.net_highorder  = (net_number >> 8)  & 255;
  388. distribution_record.net_loworder   =  net_number        & 255;
  389. distribution_record.node_highorder = (node_number >> 8) & 255;
  390. distribution_record.node_loworder  =  node_number       & 255;
  391. if (DEBUG_FLAG)
  392.   printf("\n%d  %d  %d  %d  ----- TEST\n",distribution_record.net_highorder,
  393.    distribution_record.net_loworder,distribution_record.node_highorder,
  394.    distribution_record.node_loworder);
  395. errcode = indexed_file(&distribution_file_handle,I_F_OPEN_IO,distribution_file_name,0);
  396. if (errcode)                {
  397.   printf("!Couldn't reopen distribution file; error code: %d\n",errcode);
  398.   exit(ERRORLEVEL_ENGINE);  }
  399. errcode = indexed_file(&distribution_file_handle,I_F_READ,&distribution_record,0);
  400. if (errcode)
  401.   {
  402.   if (update_mode == 'a')
  403.     goto add_to_list;
  404.   add_to_message_body_file("  ?Couldn't find net/node in the distribution list.");
  405.   goto update_done;
  406.   }
  407. if (update_mode == 'a')
  408.   {
  409.   add_to_message_body_file("  ?Net/node already in the distribution list.");
  410.   goto update_done;
  411.   }
  412. errcode = indexed_file(&distribution_file_handle,I_F_DELETE,&distribution_record,0);
  413. if (errcode)
  414.   {
  415.   printf("?Invalid delete after good read in process_distribution_list_update()\n");
  416.   printf(" Engine error code: %d\n",errcode);
  417.   exit(ERRORLEVEL_ENGINE);
  418.   }
  419. goto send_verification;
  420. add_to_list:
  421. errcode = indexed_file(&distribution_file_handle,I_F_WRITE,&distribution_record,0);
  422. if (errcode)
  423.   {
  424.   printf("?Invalid write in process_distribution_list_update(); error: %d\n",errcode);
  425.   exit(ERRORLEVEL_ENGINE);
  426.   }
  427. if ( fidonet_send_message(from_bbslist_program,
  428.                           "Sysop",
  429.                           ";Your system has been added to the BBSLIST distribution list.",
  430.                           bbslist_file_name,
  431.                           netmail_directory_spec,
  432.                           incoming_header.destNode_loworder,
  433.                           incoming_header.destNode_highorder,
  434.                           distribution_record.node_loworder,
  435.                           distribution_record.node_highorder,
  436.                           distribution_record.net_loworder,
  437.                           distribution_record.net_highorder,
  438.                           incoming_header.destNet_loworder,
  439.                           incoming_header.destNet_highorder,
  440.                           DEBUG_FLAG) )
  441.   exit(ERRORLEVEL_FATAL);
  442. if ( fidonet_send_message(from_bbslist_program,
  443.                           "Sysop",
  444.                           ";Attached is the help file for the BBSLIST message processor.",
  445.                           help_file_name,
  446.                           netmail_directory_spec,
  447.                           incoming_header.destNode_loworder,
  448.                           incoming_header.destNode_highorder,
  449.                           distribution_record.node_loworder,
  450.                           distribution_record.node_highorder,
  451.                           distribution_record.net_loworder,
  452.                           distribution_record.net_highorder,
  453.                           incoming_header.destNet_loworder,
  454.                           incoming_header.destNet_highorder,
  455.                           DEBUG_FLAG) )
  456.   exit(ERRORLEVEL_FATAL);
  457. add_to_message_body_file("  New node notified and sent latest list and help file.");
  458. /* Now send the distribution list along in the response message. */
  459. send_verification:
  460. memset(&distribution_record,0,sizeof(struct distribution_record_type));
  461. errcode = indexed_file(&distribution_file_handle,I_F_START,&distribution_record,0);
  462. add_to_message_body_file("  This is a list of the nodes currently on the distribution list:");
  463. while (!indexed_file(&distribution_file_handle,I_F_READNEXT,&distribution_record,0))
  464.   {
  465.   net_number  = (distribution_record.net_highorder  << 8) + distribution_record.net_loworder;
  466.   ltoa((long)net_number,the_net,10);
  467.   node_number = (distribution_record.node_highorder << 8) + distribution_record.node_loworder;
  468.   ltoa((long)node_number,the_node,10);
  469.   strcpy(temp_string,"    ");
  470.   strcat(temp_string,the_net);
  471.   strcat(temp_string,"/");
  472.   strcat(temp_string,the_node);
  473.   add_to_message_body_file(temp_string);
  474.   }
  475. add_to_message_body_file("    (end of distribution list)");
  476. update_done:
  477. indexed_file(&distribution_file_handle,I_F_CLOSE,"",0);
  478. }
  479.  
  480. /*--------------- Message character/line subroutines ---------------*/
  481.  
  482. int read_character_from_message()  /* Returns character or -1 for EOF. */
  483. {                                  /*  Also return EOF if NULL found.  */
  484. char input_char;
  485. int result;
  486. read_character:
  487. result = fread(&input_char,1,1,incoming_file);
  488. if (!result)            /* End of file?  Return EOF.           */
  489.   return(-1);
  490. if (input_char == 00)   /* End of message found; return EOF.   */
  491.   return(-1);
  492. if (input_char == 10)   /* Skip linefeeds in the message body. */
  493.   goto read_character;
  494. return(input_char);
  495. }
  496.  
  497. int parse_message_line()  /* Sets global variables parsed_keyword and    */
  498. {                         /* and parsed_value.  Returns non-zero if EOF. */
  499. int parsed_keyword_pointer=0,parsed_value_pointer=0,char_from_file,
  500.     parsed_message_line_pointer=0;
  501.  
  502. if (DEBUG_FLAG)
  503.   printf("\nThis is parse_message_line().\n");
  504. parsed_keyword[0] = 0;  /* Initialize to null strings. */
  505. parsed_value[0]   = 0;
  506. parsed_message_line[0] = 0;
  507. char_from_file = read_character_from_message(); /* Read 1st char from message.*/
  508. if (char_from_file == -1)   /* EOF? */
  509.   {
  510.   if (DEBUG_FLAG)
  511.     printf("The first character read was EOF.\n");
  512.   return(1);
  513.   }
  514. while (1)     /* Process/read characters until we break out. */
  515.   {
  516.   printf("Keyword character read; value: %d; character: %c\n",char_from_file,char_from_file);
  517.   if (char_from_file == 13)
  518.     {
  519.     if (DEBUG_FLAG)
  520.       printf("CR found while parsing keyword.\n");
  521.     parsed_keyword[parsed_keyword_pointer] = 0;
  522.     parsed_message_line[parsed_message_line_pointer] = 0;
  523.     return(0);
  524.     }
  525.   parsed_keyword[parsed_keyword_pointer++] = char_from_file;
  526.   parsed_message_line[parsed_message_line_pointer++] = char_from_file;
  527.   if (parsed_keyword_pointer == sizeof(parsed_keyword))
  528.     return(0);   /* Before it overflows! */
  529.   if (parsed_message_line_pointer == sizeof(parsed_message_line))
  530.     return(0);
  531.   char_from_file = read_character_from_message();
  532.   if (char_from_file == -1)
  533.     {
  534.     parsed_keyword[parsed_keyword_pointer] = 0;  /* Terminate string. */
  535.     parsed_message_line[parsed_message_line_pointer] = 0;
  536.     if (DEBUG_FLAG)
  537.       printf("EOF char found while parsing keyword.\n");
  538.     return(0);
  539.     }
  540.   if (char_from_file == '=')
  541.     {
  542.     parsed_keyword[parsed_keyword_pointer] = 0;
  543.     parsed_message_line[parsed_message_line_pointer++] = '=';
  544.     break;
  545.     }              /* Go and read characters after '=' sign. */
  546.   /* Go and read next character of keyword. */
  547.   }
  548. char_from_file = read_character_from_message();
  549. if (char_from_file == -1)
  550.   {
  551.   parsed_message_line[parsed_message_line_pointer] = 0;
  552.   if (DEBUG_FLAG)
  553.     printf("EOF char found while reading char after =.\n");
  554.   return(0);
  555.   }
  556. while (1)
  557.   {
  558.   printf("Value character read; value: %d; character: %c\n",char_from_file,char_from_file);
  559.   if (char_from_file == 13)
  560.     {
  561.     parsed_value[parsed_value_pointer] = 0;
  562.     parsed_message_line[parsed_message_line_pointer] = 0;
  563.     if (DEBUG_FLAG)
  564.       printf("CR found while reading value.\n");
  565.     break;
  566.     }
  567.   parsed_value[parsed_value_pointer++] = char_from_file;
  568.   parsed_message_line[parsed_message_line_pointer++] = char_from_file;
  569.   if (parsed_value_pointer == sizeof(parsed_value))
  570.     break;  /* Prevent overflow! */
  571.   if (parsed_message_line_pointer == sizeof(parsed_message_line))
  572.     break;
  573.   char_from_file = read_character_from_message();
  574.   if (char_from_file == -1)
  575.     {
  576.     parsed_value[parsed_value_pointer] = 0;
  577.     parsed_message_line[parsed_message_line_pointer] = 0;
  578.     if (DEBUG_FLAG)
  579.       printf("EOF char found while reading value.\n");
  580.     break;
  581.     }
  582.   }
  583. return(0);
  584. }
  585.  
  586. void process_this_message()
  587. {
  588. char temp_string[80],file_to_attach[80]="";
  589. printf("Processing message %d....\n",message_number);
  590. decode_attribute_word((incoming_header.AttributeWord_highorder*256)+incoming_header.AttributeWord_loworder);
  591. if (flag_recd)  /* This message already received? */
  592.   return;
  593. if (init_message_body_file())  /* Where we echo incoming and write reply lines to.*/
  594.   {
  595.   printf("?Error initializing message body file\n");
  596.   exit(ERRORLEVEL_FATAL);
  597.   }
  598. while (!parse_message_line())    /* Read lines of incoming message until EOF. */
  599.   {
  600.   if (!parsed_message_line[0])   /* Blank line? */
  601.     continue;                    /*   Ignore blanks at this point. */
  602.   if (parsed_message_line[0] != 1)  /* Don't echo kludge lines to requester. */
  603.     {
  604.     if (add_to_message_body_file(parsed_message_line))
  605.       {
  606.       printf("?Error adding to message body file.\n");
  607.       exit(ERRORLEVEL_FATAL);
  608.       }
  609.     }
  610.     if (DEBUG_FLAG)
  611.       {
  612.       printf("Just wrote parsed_message_line to message_body_file.\n");
  613.       printf("Keyword: %s    Value: %s\n",parsed_keyword,parsed_value);
  614.       }
  615.   if       (!strcmp(parsed_keyword,"DELETE"))  process_bbslist_deletion(atoi(parsed_value));
  616.    else if (!strcmp(parsed_keyword,"ADD")   )  process_bbslist_addition();
  617.    else if (!strcmp(parsed_keyword,"CHANGE"))  process_bbslist_change(atoi(parsed_value));
  618.    else if (!strcmp(parsed_keyword,"LIST")  )  send_attached_bbslist();
  619.    else if (!strcmp(parsed_keyword,"HELP")  )  {
  620.                                                strcpy(file_to_attach,help_file_name);
  621.                                                add_to_message_body_file("  The help file is attached, per your request.");
  622.                                                }
  623.    else if (!strcmp(parsed_keyword,"INFO")  )  send_info_message();
  624.    else if (!strcmp(parsed_keyword,"DIST-A"))  process_distribution_list_update('a',parsed_value);
  625.    else if (!strcmp(parsed_keyword,"DIST-D"))  process_distribution_list_update('d',parsed_value);
  626.    else if (parsed_keyword[0] == 1          )  {
  627.                                                /* printf("Skipping kludge line.\n"); */
  628.                                                continue;
  629.                                                }
  630.    else                                        {
  631.                                                strcpy(file_to_attach,help_file_name);
  632.                                                add_to_message_body_file("  ?Keyword unrecognized at this point; see attached help file.");
  633.                                                }
  634.   }
  635. if (DEBUG_FLAG)
  636.   printf("Getting ready to send back message body file %s\n",message_body_filename);
  637. if ( fidonet_send_message(from_bbslist_program,
  638.                           incoming_header.fromUserName,
  639.                           message_body_filename,
  640.                           file_to_attach,
  641.                           netmail_directory_spec,
  642.                           incoming_header.destNode_loworder,
  643.                           incoming_header.destNode_highorder,
  644.                           incoming_header.origNode_loworder,
  645.                           incoming_header.origNode_highorder,
  646.                           incoming_header.origNet_loworder,
  647.                           incoming_header.origNet_highorder,
  648.                           incoming_header.destNet_loworder,
  649.                           incoming_header.destNet_highorder,
  650.                           DEBUG_FLAG) )
  651.   exit(ERRORLEVEL_FATAL);
  652. incoming_header.AttributeWord_loworder |= 4;  /* Mark this message received. */
  653. fseek(incoming_file,0,SEEK_SET);
  654. result = fwrite(&incoming_header,sizeof(struct message_header_type),1,incoming_file);
  655. if (!result)               {
  656.   printf("?Error rewriting message header of incoming file\n");
  657.   exit(ERRORLEVEL_FATAL);  }
  658. }
  659.  
  660. void init_print_records()
  661. {
  662. memset(&print_record_1,32,sizeof(struct print_record_1_type));
  663. memset(&print_record_2,32,sizeof(struct print_record_2_type));
  664. memset(&print_record_3,32,sizeof(struct print_record_3_type));
  665. }
  666.  
  667. void move_to_print_field(char output_field[],char input_field[],char field_size)
  668. {
  669. char offset_counter=0;
  670. while (offset_counter < field_size)
  671.   {
  672.   if (!input_field[offset_counter])
  673.         break;
  674.   output_field[offset_counter] = input_field[offset_counter];
  675.   offset_counter++;
  676.   }
  677. }
  678.  
  679. /*--------------------------- The Code -------------------------------------*/
  680. int main(int argc, char *argv[])
  681. {
  682. struct date current_date;
  683. struct time current_time;
  684.  
  685. printf("----Begin program execution\n");
  686. if (argc != 2)
  687.   {
  688.   printf("?Illegal number of arguments; command line syntax: \n");
  689.   printf("    BBSLIST BBSLIST.CFG                            \n");
  690.   printf("  where BBSLIST.CFG is the path to the config file.\n");
  691.   return(ERRORLEVEL_BAD_PARAMETER);
  692.   }
  693. strcpy(config_file_name,argv[1]);
  694. config_file = fopen(config_file_name,"rt");
  695. if (config_file == NULL)
  696.   {
  697.   printf("?Can't open config file %s\n",config_file_name);
  698.   return(ERRORLEVEL_BAD_PARAMETER);
  699.   }
  700. fgets(help_file_name,sizeof(help_file_name),config_file);
  701. help_file_name[strlen(help_file_name)-1] = 0;  /* Cut off LF. */
  702. fgets(info_file_name,sizeof(info_file_name),config_file);
  703. info_file_name[strlen(info_file_name)-1] = 0;  /* Cut off LF. */
  704. fgets(data_file_name,sizeof(data_file_name),config_file);
  705. data_file_name[strlen(data_file_name)-1] = 0;
  706. fgets(distribution_file_name,sizeof(distribution_file_name),config_file);
  707. distribution_file_name[strlen(distribution_file_name)-1] = 0;
  708. fgets(bbslist_file_name,sizeof(bbslist_file_name),config_file);
  709. bbslist_file_name[strlen(bbslist_file_name)-1] = 0;
  710. fgets(netmail_directory_spec,sizeof(netmail_directory_spec),config_file);
  711. netmail_directory_spec[strlen(netmail_directory_spec)-1] = 0;
  712. if (netmail_directory_spec[strlen(netmail_directory_spec)-1] != '\\')  {
  713.   netmail_directory_spec[strlen(netmail_directory_spec)+1] = 0;
  714.   netmail_directory_spec[strlen(netmail_directory_spec)]   = '\\';     }
  715. fgets(bbslist_header_spec,sizeof(bbslist_header_spec),config_file);
  716. bbslist_header_spec[strlen(bbslist_header_spec)-1] = 0;
  717. fgets(bbslist_trailer_spec,sizeof(bbslist_trailer_spec),config_file);
  718. bbslist_trailer_spec[strlen(bbslist_trailer_spec)-1] = 0;
  719. fgets(update_password,sizeof(update_password),config_file);
  720. update_password[strlen(update_password)-1] = 0;
  721. fgets(debug_string,sizeof(debug_string),config_file);
  722. debug_string[strlen(debug_string)-1] = 0;
  723. fclose(config_file);
  724.  
  725. if (debug_string[0] == 'Y')   /* Turn debug mode on? */
  726.   DEBUG_FLAG = 1;
  727. if (debug_string[1] == 'Y')
  728.   delete_received_messages_flag = 1;
  729.  
  730. if (DEBUG_FLAG)
  731.   {
  732.   printf("Help file spec:            %s\n",help_file_name);
  733.   printf("Info file spec:            %s\n",info_file_name);
  734.   printf("Data file spec:            %s\n",data_file_name);
  735.   printf("Distribution file name:    %s\n",distribution_file_name);
  736.   printf("BBSLIST (text) file spec:  %s\n",bbslist_file_name);
  737.   printf("Netmail directory spec:    %s\n",netmail_directory_spec);
  738.   printf("BBSLIST header file spec:  %s\n",bbslist_header_spec);
  739.   printf("BBSLIST trailer file spec: %s\n",bbslist_trailer_spec);
  740.   printf("Update password:           %s\n",update_password);
  741.   }
  742. errcode = indexed_file(&data_file_handle,I_F_OPEN_READ,data_file_name,0);
  743. if (errcode)  {
  744.   printf("!Couldn't open data file; attempting to create new one\n");
  745.   strcpy(I_F_FILE_ATTRIBUTES,"202 2 0 2 0 2 30 0");
  746.   errcode = indexed_file(&data_file_handle,I_F_OPEN_WRITE,data_file_name,0);  }
  747. if (errcode)  {
  748.   printf("?Error checking/creating data file; error code: %d\n",errcode);
  749.   exit(ERRORLEVEL_ENGINE);    }
  750. indexed_file(&data_file_handle,I_F_CLOSE,"",0);
  751.  
  752. CR_string[0] = 13;  /* We'll use this for stuff. */
  753. CR_string[1] = 0;
  754. CRLF_string[0] = 13;
  755. CRLF_string[1] = 10;
  756. CRLF_string[2] = 0;
  757.  
  758. message_number = 0;        /* Start looking for messages addressed to us. */
  759. while (1)   /* Do this until we break out. */
  760.   {
  761.   if (message_number++ > MAX_MSGS_TO_SCAN)    /* Check, then increment. */
  762.         break;
  763.   strcpy(incoming_file_name,netmail_directory_spec);
  764.   itoa(message_number,temp_string,10);
  765.   strcat(incoming_file_name,temp_string);
  766.   strcat(incoming_file_name,message_file_suffix);
  767.   incoming_file = fopen(incoming_file_name,"rb+");
  768.   if (incoming_file != NULL)   /* Found a message file?     */
  769.         {
  770.     fread(&incoming_header,sizeof(struct message_header_type),1,incoming_file);
  771.     temp_string[0] = 0;
  772.     strncat(temp_string,incoming_header.toUserName,sizeof(incoming_header.toUserName));
  773.     strupr(temp_string);
  774.     result = memcmp(temp_string,"BBSLIST",8);
  775.     if (!result)
  776.       {
  777.       process_this_message(); /* We found a message addressed to BBSLIST. */
  778.       if (delete_received_messages_flag)
  779.         {
  780.         if (unlink(incoming_file_name))
  781.           {
  782.           printf("?Error deleting the incoming message we just processed.\n");
  783.           printf(" The filename was %s.\n",incoming_file_name);
  784.           exit(ERRORLEVEL_FATAL);
  785.           }
  786.         }
  787.       }
  788.     fclose(incoming_file);
  789.     }
  790.   }
  791.  
  792. if (!create_bbslist_flag)   /* Anything else to do? */
  793.   exit(ERRORLEVEL_SUCCESS);  /*  Guess not!          */
  794.  
  795. /* First, write out the new bbslist text file from the data file. */
  796. bbslist_file = fopen(bbslist_file_name,"wb");
  797. if (bbslist_file == NULL)          {
  798.   printf("?Error opening bbslist file for output\n");
  799.   exit(ERRORLEVEL_CONFIGURATION);  }
  800. temp_file = fopen(bbslist_header_spec,"rt");
  801. if (temp_file == NULL)             {
  802.   printf("?Error opening header file for bbs list\n");
  803.   exit(ERRORLEVEL_CONFIGURATION);  }
  804. while (!feof(temp_file))                                   {
  805.   fgets(temp_string,sizeof(temp_string),temp_file);
  806.   if (strlen(temp_string))
  807.     temp_string[strlen(temp_string)-1] = 0;  /* Strip off CR. */
  808.   fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  809.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);  }
  810. fclose(temp_file);
  811. /* Now print out each record in the indexed file. */
  812. errcode = indexed_file(&data_file_handle,I_F_OPEN_READ,data_file_name,0);
  813. if (errcode)
  814.   {
  815.   printf("?Error opening indexed file to write out new bbs list: %d\n",errcode);
  816.   exit(ERRORLEVEL_ENGINE);
  817.   }
  818. memset(&data_record,0,sizeof(struct data_record_type));
  819. errcode = indexed_file(&data_file_handle,I_F_START,&data_record,1);  /* Start by name. */
  820. if (!errcode)
  821.   errcode = indexed_file(&data_file_handle,I_F_READNEXT,&data_record,0);
  822. while (!errcode)
  823.   {               /* Copy the data fields to the print fields and print. */
  824.   init_print_records();
  825.   move_to_print_field(print_record_1.name,     data_record.name,     sizeof(print_record_1.name));
  826.   move_to_print_field(print_record_1.number,   data_record.number,   sizeof(print_record_1.number));
  827.   move_to_print_field(print_record_1.baud,     data_record.baud,     sizeof(print_record_1.baud));
  828.   move_to_print_field(print_record_1.hours,    data_record.hours,    sizeof(print_record_1.hours));
  829.   move_to_print_field(print_record_2.sysop,    data_record.sysop,    sizeof(print_record_2.sysop));
  830.   move_to_print_field(print_record_2.sysopreal,data_record.sysopreal,sizeof(print_record_2.sysopreal));
  831.   move_to_print_field(print_record_2.location, data_record.location, sizeof(print_record_2.location));
  832.   move_to_print_field(print_record_2.software, data_record.software, sizeof(print_record_2.software));
  833.   move_to_print_field(print_record_3.addr1,    data_record.addr1,    sizeof(print_record_3.addr1));
  834.   move_to_print_field(print_record_3.addr2,    data_record.addr2,    sizeof(print_record_3.addr2));
  835.   move_to_print_field(print_record_3.addr3,    data_record.addr3,    sizeof(print_record_3.addr3));
  836.   itoa((data_record.unique_number_highorder*256)+data_record.unique_number_loworder,temp_string,10);
  837.   move_to_print_field(print_record_3.unique_number,temp_string,sizeof(print_record_3.unique_number));
  838.   fwrite(&print_record_1,sizeof(struct print_record_1_type),1,bbslist_file);
  839.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  840.   fwrite(&print_record_2,sizeof(struct print_record_2_type),1,bbslist_file);
  841.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  842.   fwrite(&print_record_3,sizeof(struct print_record_3_type),1,bbslist_file);
  843.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  844.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  845.   errcode = indexed_file(&data_file_handle,I_F_READNEXT,&data_record,0);
  846.   }
  847. indexed_file(&data_file_handle,I_F_CLOSE,"",0);
  848. temp_file = fopen(bbslist_trailer_spec,"rt");
  849. if (temp_file == NULL)  {
  850.   printf("?Error opening trailer file for bbs list\n");
  851.   exit(ERRORLEVEL_CONFIGURATION);              }
  852. while (!feof(temp_file))                     {
  853.   fgets(temp_string,sizeof(temp_string),temp_file);
  854.   if (strlen(temp_string))
  855.     temp_string[strlen(temp_string)-1] = 0;
  856.   fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  857.   fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);  }
  858. fclose(temp_file);
  859. fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  860. strcpy(temp_string,"This listing was last updated ");
  861. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  862. getdate(&current_date);
  863. itoa(current_date.da_mon,temp_string,10);
  864. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  865. fwrite("/",1,1,bbslist_file);
  866. itoa(current_date.da_day,temp_string,10);
  867. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  868. fwrite("/",1,1,bbslist_file);
  869. itoa(current_date.da_year,temp_string,10);
  870. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  871. fwrite(" at ",4,1,bbslist_file);
  872. gettime(&current_time);
  873. itoa(current_time.ti_hour,temp_string,10);
  874. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  875. fwrite(":",1,1,bbslist_file);
  876. itoa(current_time.ti_min,temp_string,10);
  877. fwrite(temp_string,strlen(temp_string),1,bbslist_file);
  878. fwrite(CRLF_string,strlen(CRLF_string),1,bbslist_file);
  879. fclose(bbslist_file);
  880.  
  881. /* Now send to the distribution list, if any. */
  882. if (!indexed_file(&distribution_file_handle,I_F_OPEN_READ,distribution_file_name,0))  /* Does file exist at all? */
  883.   {
  884.   memset(&distribution_record,0,sizeof(struct distribution_record_type));
  885.   indexed_file(&distribution_file_handle,I_F_START,&distribution_record,0);
  886.   while (!indexed_file(&distribution_file_handle,I_F_READNEXT,&distribution_record,0))
  887.     {
  888.     if ( fidonet_send_message(from_bbslist_program,
  889.                               "Sysop",
  890.                               "",
  891.                               bbslist_file_name,
  892.                               netmail_directory_spec,
  893.                               incoming_header.destNode_loworder,
  894.                               incoming_header.destNode_highorder,
  895.                               distribution_record.node_loworder,
  896.                               distribution_record.node_highorder,
  897.                               distribution_record.net_loworder,
  898.                               distribution_record.net_highorder,
  899.                               incoming_header.destNet_loworder,
  900.                               incoming_header.destNet_highorder,
  901.                               DEBUG_FLAG) )
  902.       exit(ERRORLEVEL_FATAL);
  903.     }
  904.   indexed_file(&distribution_file_handle,I_F_CLOSE,"",0);
  905.   }
  906.  
  907. return(ERRORLEVEL_LIST_CHANGED);
  908. }

Paste is for source code and general debugging text.

Login or Register to edit, delete and keep track of your pastes and more.

Raw Paste

Login or Register to edit or fork this paste. It's free.