home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
msglink
/
msglink.c
< prev
next >
Wrap
Text File
|
1990-09-16
|
15KB
|
652 lines
/*
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);
}