home *** CD-ROM | disk | FTP | other *** search
- /*
- Message Base Reply Chain Linker
-
- This module was originally written by Bob Hartman
- Sysop of FidoNet node 1:132/101
-
- Spark Software, 427-3 Amherst St, CS 2032, Suite 232, Nashua, NH 03061
-
- This program source code is being released with the following provisions:
-
- 1. You are free to make changes to this source code for use on your own
- machine, however, altered source files may not be distributed without the
- consent of Spark Software.
-
- 2. You may distribute "patches" or "diff" files for any changes that you
- have made, provided that the "patch" or "diff" files are also sent to Spark
- Software for inclusion in future releases of the entire package. A "diff"
- file for the source archives may also contain a compiled version, provided
- it is clearly marked as not being created from the original source code.
- No other executable versions may be distributed without the consent of
- Spark Software.
-
- 3. You are free to include portions of this source code in any program you
- develop, providing: a) Credit is given to Spark Software for any code that
- may is used, and b) The resulting program is free to anyone wanting to use
- it, including commercial and government users.
-
- 4. There is NO technical support available for dealing with this source
- code, or the accompanying executable files. This source code is provided
- as is, with no warranty expressed or implied (I hate legalease). In other
- words, if you don't know what to do with it, don't use it, and if you are
- brave enough to use it, you're on your own.
-
- Spark Software may be contacted by modem at (603) 888-8179 (node 1:132/101)
- on the public FidoNet network, or at the address given above.
-
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
- #include <dos.h>
- #include <direct.h>
-
- #ifdef OS_2
- #define DOS_INCL_DOSFILEMGR
- #include <os2.h>
- #endif
-
- #include "bbsdev.h"
- #ifndef OS_2
- #include "diskio.h"
- #endif
-
- char *REV = "$Revision: 1.0c $"; /* Used in my code for
- * my RCS program */
-
- #define MSG_EXISTS 1
- #define MSG_LINK_CHANGED 4
-
- #ifdef OS_2
- #define MAX_FN_LEN 260
- #else
- #define MAX_FN_LEN 80
- #endif
-
- char dir_drive2[MAX_FN_LEN];
- char dir_drive1[MAX_FN_LEN];
-
- typedef struct msgtyp
- {
- int msg_num;
- unsigned int msg_subj;
- int msg_up;
- int msg_down;
- int msg_flags;
- } MSG_TYP;
-
- #define MAX_MSGS 2048
-
- MSG_TYP msgs[MAX_MSGS];
- SYS curr_system;
- _sys opus_sys;
- MSG msg_tmp;
-
- int n_msgs, quiet, opus;
-
- int total_reserved;
- char dta[128];
- char *junk;
- extern char tmpjunk[], tmpjunk1[], tmpjunk2[];
- AREAS_PTR areas[MAXAREAS];
- int tot_areas;
-
- void main (argc, argv)
- int argc;
- char *argv[];
- {
- register int i;
- int j;
- char buff1[20], buff2[20]; /* Junk buffers */
- FILE *f1;
- int from_file;
- char *p1;
-
- /* Process command line */
- if (((argv[1][0] == '-')||(argv[1][0] == '/')) && (toupper (argv[1][1]) == 'F'))
- {
- --argc;
- ++argv;
- if ((f1 = fopen (argv[1], "rt")) == NULL)
- {
- printf ("Cannot open '%s'- exiting\n", argv[1]);
- exit (2);
- }
- from_file = 1;
- --argc;
- ++argv;
- }
- else
- from_file = 0;
-
- if (((argv[1][0] == '-')||(argv[1][0] == '/')) && (toupper (argv[1][1]) == 'O'))
- {
- --argc;
- ++argv;
- opus = 1;
- }
- else
- opus = 0;
-
- if (((argv[1][0] == '-')||(argv[1][0] == '/')) && (toupper (argv[1][1]) == 'Q'))
- {
- --argc;
- ++argv;
- quiet = 1;
- }
- else
- quiet = 0;
-
- if (argv[1][0] == '+')
- {
- strcpy (tmpjunk, &argv[1][1]);
- --argc;
- ++argv;
- }
- else
- strcpy (tmpjunk, "AREAS.BBS");
-
- if (!quiet)
- {
- /* Say hello to the world */
- sscanf (REV, "$%s %s", buff1, buff2);
- #ifdef OS_2
- printf ("MsgLinkOS2 - %s %s by Bill Andrus, SysOp of FidoNet Node 1:109/301.1\n", buff1, buff2);
- #else
- printf ("MsgLink - %s %s by Bill Andrus, SysOp of FidoNet Node 1:109/301.1\n", buff1, buff2);
- #endif
- printf ("This executable program is based on released sources of Bob Hartman.\n");
- printf ("This executable program is in the Public Domain as part of the BBS project.\n");
- printf ("For information on BBS (Bit Bucket Software), contact 132/101 or 141/491.\n");
- printf ("CRC routine copyright Renex Corporation. Used with permission of Ray Gwinn.\n\n");
- }
-
- if (compile_areas (tmpjunk) != 0)
- {
- printf ("Could not process AREAS file\n");
- }
-
- if ((argc < 2) && !from_file)
- {
- msglink_usage ();
- }
-
- while ((--argc > 0) || from_file)
- {
- /* Save where we are */
- getcwd (dir_drive2, MAX_FN_LEN);
- getcwd (dir_drive1, MAX_FN_LEN);
-
- if ((argc <= 0) && from_file)
- {
- if (fgets (tmpjunk1, 128, f1) == NULL)
- {
- from_file = 0;
- fclose (f1);
- continue;
- }
- else
- {
- /* Null terminate the string */
- p1 = tmpjunk1;
- while (*p1)
- {
- if ((isspace (*p1)) || (*p1 == 26))
- {
- *p1 = '\0';
- break;
- }
- ++p1;
- }
-
- /* If we didn't get anything */
- if (p1 == tmpjunk1)
- continue;
- }
- }
- else
- {
- strcpy (tmpjunk1, argv[1]);
- ++argv;
- }
-
- j = 500;
- strcpy (tmpjunk2, tmpjunk1);
- if (!get_fido_sys (tmpjunk2, 0))
- {
- strcpy (tmpjunk1, tmpjunk2);
- }
- else
- {
- /* Now find it in our list of areas */
- for (j = 0; j < tot_areas; j++)
- {
- if (stricmp (areas[j]->area_name, tmpjunk2) == 0)
- {
- /* Found it */
- strcpy (tmpjunk1, areas[j]->msg_path);
- break;
- }
- }
- if (j == tot_areas)
- {
- if (!(filedir (tmpjunk2, 0, tmpjunk2, ST_DIRECT) & ST_DIRECT))
- {
- printf ("Unknown Area Name '%s'\n", tmpjunk1);
- continue;
- }
- }
- }
-
- if (opus)
- {
- if (get_opus (tmpjunk1,(_sys *)&opus_sys) < 0)
- {
- printf ("Cannot make sense of '%s'\n", tmpjunk1);
- continue;
- }
- }
- else
- {
- if (get_system (tmpjunk1,(SYS *)&curr_system) < 0)
- {
- printf ("Cannot make sense of '%s'\n", tmpjunk1);
- continue;
- }
- }
-
-
- n_msgs = 0;
-
- /* Read in all message data */
- if (!quiet)
- printf ("Reading in message data...\n");
- read_msg_data ();
-
- /* Process message data */
- if (n_msgs > 0)
- {
- if ((msgs[0].msg_num != 1) && (msgs[0].msg_down != 0))
- {
- msgs[0].msg_down = 0;
- msgs[0].msg_flags = MSG_LINK_CHANGED;
- }
- if ((n_msgs == 1) && (msgs[0].msg_up != 0))
- {
- msgs[0].msg_up = 0;
- msgs[0].msg_flags = MSG_LINK_CHANGED;
- }
- }
-
- for (i = 1; i < n_msgs; i++)
- {
- /* If they have the same subject, try to link them */
- if (msgs[i].msg_subj == msgs[i - 1].msg_subj)
- {
- /* Is the back one linked? */
- if (msgs[i - 1].msg_up != msgs[i].msg_num)
- {
- /* Link it up and mark it for later */
- msgs[i - 1].msg_up = msgs[i].msg_num;
- msgs[i - 1].msg_flags = MSG_LINK_CHANGED;
- }
- /* Is this one linked? */
- if (msgs[i].msg_down != msgs[i - 1].msg_num)
- {
- /* Link it up and mark it for later */
- msgs[i].msg_down = msgs[i - 1].msg_num;
- msgs[i].msg_flags = MSG_LINK_CHANGED;
- }
- }
- else
- {
- /* Unlink it if necessary */
- if (msgs[i].msg_down != 0)
- {
- msgs[i].msg_down = 0;
- msgs[i].msg_flags = MSG_LINK_CHANGED;
- }
- if (msgs[i - 1].msg_up != 0)
- {
- msgs[i - 1].msg_up = 0;
- msgs[i - 1].msg_flags = MSG_LINK_CHANGED;
- }
- }
- }
-
- /* Re-link the reply chains */
- relink ();
-
- if (go_directory (dir_drive2, NULL))
- {
- printf ("Cannot seem to change directories back to %s\n", dir_drive2);
- }
- if (go_directory (dir_drive1, NULL))
- {
- printf ("Cannot seem to change directories back to %s\n", dir_drive1);
- exit (1);
- }
- if (!quiet)
- printf ("\n");
- }
-
- if (!quiet)
- printf ("Done!\n");
- exit (0);
- }
-
- unsigned int calcrc(ptr)
- char *ptr;
- {
- unsigned int crc;
- int j;
- unsigned char r;
-
- crc = 0;
- j = 0;
- while (j++ <= 40)
- {
- if (*ptr)
- {
- r = toupper (*ptr);
- ++ptr;
- }
- else
- r = 0;
-
- crc = xcrc (crc, r);
- }
- return (crc);
- }
-
- int compare (arg1, arg2)
- MSG_TYP *arg1, *arg2;
- {
- if (arg1->msg_subj != arg2->msg_subj)
- return (arg1->msg_subj - arg2->msg_subj);
- else
- return (arg1->msg_num - arg2->msg_num);
- }
-
- void update ()
- {
- int f, st;
- char junk[64];
-
- sprintf (junk, "%d.MSG", msgs[n_msgs].msg_num);
-
- if ((f = fast_open (junk, O_RDONLY|O_BINARY)) == -1)
- {
- printf ("Error opening '%s'\n", junk);
- msgs[n_msgs].msg_num = 0;
- return;
- }
-
- if (fast_read (f, (char *) &msg_tmp, sizeof (MSG)) != sizeof (MSG))
- {
- printf ("Error reading '%s'\n", junk);
- msgs[n_msgs].msg_num = 0;
- (void) fast_close (f);
- return;
- }
- (void) fast_close (f);
- /* Get CRC of Subj: field */
- if ((toupper(msg_tmp.subj[0]) == 'R') &&
- (toupper(msg_tmp.subj[1]) == 'E') &&
- (msg_tmp.subj[2] == ':') &&
- (msg_tmp.subj[3] == ' '))
- {
- st = 4;
- }
- else
- st = 0;
- msgs[n_msgs].msg_subj = calcrc (&(msg_tmp.subj[st]));
- msgs[n_msgs].msg_up = msg_tmp.up;
- msgs[n_msgs].msg_down = msg_tmp.reply;
- }
-
- void read_msg_data ()
- {
- int i;
- char junk[64];
- char name[20];
-
- sprintf (junk, "*.MSG");
- (void) filedir (junk, 0, name, 0);
- while (name[0] != '\0')
- {
- i = 0;
- sscanf (name, "%d.", &i);
- if (i > 1)
- {
- msgs[n_msgs].msg_num = i;
- msgs[n_msgs].msg_flags = MSG_EXISTS;
- update ();
- ++n_msgs;
- if (n_msgs >= MAX_MSGS)
- {
- break;
- }
- }
- (void) filedir (junk, 1, name, 0);
- }
- (void) qsort ((char *) msgs, n_msgs, sizeof (MSG_TYP), compare);
- }
-
- void fancy_str (value)
- char *value;
- {
- register char *sptr;
- char lower = 0;
-
- sptr = value;
-
- if (sptr)
- { /* don't touch any NULL pointers */
- while (*sptr)
- {
- if (lower)
- {
- *sptr = tolower (*sptr);
- }
- else
- {
- *sptr = toupper (*sptr);
- }
-
- lower = (isalnum (*sptr++));
- }
- }
- }
-
- int get_system (where, ret_system)
- char *where;
- SYS *ret_system;
- {
- char sys_file[64];
- int sys_input;
- int num;
- int ret;
- char *p;
-
- ret = ALL_OK;
- sys_file[0] = '\0';
- num = atoi (where);
- if (!isdigit (where[0]))
- {
- strupr (where);
- strcpy (ret_system->msgpath, where);
- }
- else
- if (num == 0)
- {
- sprintf (sys_file, "%s%s", SYSNAME, DEF_EXT);
- }
- else
- {
- sprintf (sys_file, "%s%d%s", SYSNAME, num, DEF_EXT);
- }
-
- if (sys_file[0] != '\0')
- {
- if ((sys_input = fast_open (sys_file, O_RDONLY|O_BINARY)) == -1)
- {
- printf ("\nError %d openning '%s', aborting.\n", sys_input, sys_file);
- return (NO_SYSTEM);
- }
- else
- {
- if ((fast_read (sys_input, (char *) ret_system, sizeof (SYS))) == -1)
- {
- printf ("\nError -1 reading '%s', aborting.\n", sys_file);
- fast_close (sys_input);
- return (NO_SYSTEM);
- }
- strupr (ret_system->msgpath);
- fast_close (sys_input);
- }
- }
- p = &(ret_system->msgpath[strlen (ret_system->msgpath) - 1]);
- if ((*p == '\\') || (*p == '/'))
- {
- if ((p > ret_system->msgpath) && (*(p - 1) != ':'))
- *p = '\0';
- }
- fancy_str (ret_system->msgpath);
- num = go_directory (ret_system->msgpath, dir_drive2);
- if (num == 0)
- {
- if (!quiet)
- printf ("MsgLink using directory '%s'\n", ret_system->msgpath);
- return (ret);
- }
- else
- return (NO_GO);
- }
-
- int get_opus (where, ret_system)
- char *where;
- _sys *ret_system;
- {
- char sys_file[64];
- int sys_input;
- int num;
- int ret;
- char *p;
-
- ret = ALL_OK;
- sys_file[0] = '\0';
- num = atoi (where);
- if (!isdigit (where[0]))
- {
- strupr (where);
- strcpy (ret_system->msgpath, where);
- }
- else
- sprintf (sys_file, "SYSTEM%02X.DAT", num);
-
- if (sys_file[0] != '\0')
- {
- if ((sys_input = fast_open (sys_file, O_RDONLY|O_BINARY)) == -1)
- {
- printf ("\nError %d openning '%s', aborting.\n", sys_input, sys_file);
- return (NO_SYSTEM);
- }
- else
- {
- if ((fast_read (sys_input, (char *) ret_system, sizeof (_sys))) == -1)
- {
- printf ("\nError -1 reading '%s', aborting.\n", sys_file);
- fast_close (sys_input);
- return (NO_SYSTEM);
- }
- strupr (ret_system->msgpath);
- fast_close (sys_input);
- }
- }
- p = &(ret_system->msgpath[strlen (ret_system->msgpath) - 1]);
- if ((*p == '\\') || (*p == '/'))
- {
- if ((p > ret_system->msgpath) && (*(p-1) != ':'))
- *p = '\0';
- }
- fancy_str (ret_system->msgpath);
- num = go_directory (ret_system->msgpath, dir_drive2);
- if (num == 0)
- {
- if (!quiet)
- printf ("MsgLink using directory '%s'\n", ret_system->msgpath);
- return (ret);
- }
- else
- return (NO_GO);
- }
-
- void relink ()
- {
- int i, f;
- MSG_TYP *mptr;
-
- if (!quiet)
- printf ("Relinking reply chains...\n");
- for (mptr = &msgs[1],i = 1; i < n_msgs; mptr++, i++)
- {
- if (mptr->msg_flags & MSG_LINK_CHANGED)
- {
- /* Create the name of this message */
- sprintf (tmpjunk2, "%d.msg", mptr->msg_num);
-
- f = fast_open (tmpjunk2, O_RDWR|O_BINARY);
- (void) fast_read (f, (char *) &msg_tmp, sizeof (MSG));
- (void) fast_lseek (f, 0L, SEEK_SET);
- msg_tmp.up = mptr->msg_up;
- msg_tmp.reply = mptr->msg_down;
- (void) fast_write (f, (char *) &msg_tmp, sizeof(MSG));
- (void) fast_close (f);
- }
- }
- }
-
- int go_directory (dir, save)
- char *dir;
- char *save;
- {
- #ifndef OS_2
- unsigned num_drives;
- #endif
- if (dir[1] == ':')
- {
- #ifdef OS_2
- (void)DosSelectDisk(toupper (dir[0]) - 'A' + 1);
- #else
- _dos_setdrive(toupper (dir[0]) - 'A' + 1, &num_drives);
- #endif
- if (save != NULL)
- {
- getcwd (save, 80);
- }
- }
- return (chdir (dir));
- }
-
- void msglink_usage ()
- {
- printf ("/nUsage: MsgLink [-o] [-q] dir [dir] [dir] ...\n");
- printf (" MsgLink -f areas.lst [-o] [-q] [+areas.bbs]\n\n");
- printf (" Switches must be given in the order shown\n");
- printf (" Switches f, o and q can follow '/' or '-'\n");
- printf (" f = process echomail areas named in the areas.lst specified\n");
- printf (" o = Opus 1.1 operation\n");
- printf (" q = quiet operation\n");
- printf (" dir is a directory path, a SYSTEMxx.BBS/DAT number, or msg area name\n");
- printf (" areas.lst is a list of echomail areas to process\n");
- printf (" areas.bbs is the areas.bbs file to read to find the echomail areas\n");
- exit (1);
- }