home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
MNUM416D.SZH
/
MSGNUM.C
< prev
next >
Wrap
Text File
|
1991-04-16
|
41KB
|
1,429 lines
/*
Message Base Renumberer
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: 4.16d $"; /* Used in my code for my RCS program */
#define MSG_EXISTS 1
#define MSG_DELETED 2
#define MSG_LINK_CHANGED 4
#define YEAR(x) ((((x)->date>>9)&0x7f))
#define MONTH(x) (((x)->date>>5)&0x0f)
#define DAY(x) ((x)->date&0x1f)
long days_to_month[12] = {
0L, 31L, 59L, 90L, 120L, 151L, 181L, 212L, 243L, 273L, 304L, 334L
};
static char *_days[7] = {
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
};
static char *_months[12] = {
"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
"JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
};
#ifndef OS_2
#define MAX_PATH 80
#else
#define MAX_PATH 260
#endif
char dir_drive1[MAX_PATH];
char dir_drive2[MAX_PATH];
char dir_drive3[MAX_PATH];
typedef struct msgtyp {
int msg_num;
int msg_out_num;
long msg_time;
int msg_up;
int msg_down;
int msg_attr;
int msg_flags;
} MSG_TYP;
#define MAXLASTREADS 16
#define MAX_MSGS 2048
#define MAX_USERS 32
#define MAX_NAME 33
char areaname[MAX_PATH];
char opus_sys_path[MAX_PATH];
MSG msg_tmp;
MSG_TYP msgs[MAX_MSGS+1];
SYS curr_system;
USR users[MAX_USERS];
_usr opus_user;
_sys opus_sys;
int help;
int max;
int qmail;
int n_msgs;
int kills[10];
int n_kills;
int opus;
int opus_120;
int quiet;
int renum;
int kill_n1, kill_n2;
int kill_date;
int kill_sent;
int areanum = -1;
#define KILL_N 1
#define KILL_DATE 2
#define KILL_RCVD 4
#define KILL_SENT 8
char tmpjunk2[MAX_PATH];
int total_reserved;
char dta[128];
void main (int argc, char *argv[])
{
register int i;
register MSG_TYP *mptr;
MSG_TYP *m;
int j;
char buff1[20], buff2[20]; /* Junk buffers */
/* Process command line */
if (argc == 1)
help++;
while (--argc)
{
++argv;
if (argv[0][0] == '?')
help++;
if ((argv[0][0] == '-') || (argv[0][0] == '/'))
{
switch (tolower (argv[0][1]))
{
case 'a':
qmail++;
break;
case 'd':
kill_date = atoi (argv[1]);
++argv;
--argc;
kills[n_kills++] = KILL_DATE;
break;
case 'k':
kills[n_kills++] = KILL_RCVD;
break;
case 'm':
max++;
break;
case 'n':
kill_n1 = atoi (argv[1]);
kill_n2 = atoi (argv[2]);
argv += 2;
argc -= 2;
kills[n_kills++] = KILL_N;
break;
case 'o':
opus++;
if (argv[0][2] == '1')
opus_120++;
break;
case 'q':
quiet++;
break;
case 'r':
renum++;
break;
case 's':
kill_sent++;
kills[n_kills++] = KILL_SENT;
break;
case '?':
help++;
break;
default:
printf ("Unknown option '%s'\n", argv[0]);
help++;
}
}
}
if (!quiet || help)
{
/* Say hello to the world */
sscanf (REV, "$%s %s", buff1, buff2);
#ifdef OS_2
printf ("\nMsgNumOS2 - %s %s by Bill Andrus, FidoNet Node 1:109/301.0\n", buff1, buff2);
#else
printf ("\nMsgNum - %s %s by Bill Andrus, FidoNet Node 1:109/301.0\n", buff1, buff2);
#endif
printf ("Includes OPUS 1.20 mods from Graham Stair, FidoNet Node 3:711/409.\n");
printf ("Based on copyrighted source files from Bob Hartman.\n");
printf ("Copyright 1985-88 Spark Software, Inc. All rights reserved.\n\n");
}
if (help)
msgnum_usage();
/* Get to proper directory, saving where we are */
getcwd (dir_drive1, MAX_PATH);
getcwd (dir_drive2, MAX_PATH);
if (opus)
{
if (get_opus (argv[0], &opus_sys) < 0)
{
printf ("Cannot make sense of '%s'\n", argv[0]);
(void) go_directory (dir_drive2, NULL);
(void) go_directory (dir_drive1, NULL);
exit (1);
}
}
else
{
if (get_system (argv[0], &curr_system) < 0)
{
printf ("Cannot make sense of '%s'\n", argv[0]);
(void) go_directory (dir_drive2, NULL);
(void) go_directory (dir_drive1, NULL);
exit (1);
}
}
getcwd (dir_drive3, MAX_PATH);
if (!quiet)
{
if (areanum >= 0) {
if (opus) {
if (opus_120) {
printf ("Using Opus 1.2+ SYSTEM%02X.DAT file in '%s' ...\n", areanum, dir_drive1);
} else {
printf ("Using Opus 1.1+ SYSTEM%02X.DAT file in '%s' ...\n", areanum, dir_drive1);
}
} else {
printf ("Using Opus 1.0x SYSTEM%2d.BBS file in '%s' ...\n", areanum, dir_drive1);
}
} else {
printf ("Using Directory '%s' ...\n", dir_drive3);
}
}
/* Read in all message data */
if (!quiet)
printf ("Reading in message data ...\n");
read_msg_data ();
/* Process each kill function in order */
if (n_msgs)
{
if (!quiet)
printf ("Processing message data ...\n");
for (i = 0; i < n_kills; i++)
{
switch (kills[i])
{
case KILL_N:
kill_number ();
break;
case KILL_DATE:
kill_by_date ();
break;
case KILL_RCVD:
kill_attr (MSGREAD);
break;
case KILL_SENT:
kill_attr (MSGSENT);
break;
default:
break;
}
}
}
/* Do any necessary renumbering */
if (renum && n_msgs)
{
if (!quiet)
printf ("Renumbering remaining message(s) ...\n");
for (mptr = &msgs[1], i = j = 1; i <= n_msgs; mptr++, i++)
{
if (mptr->msg_flags & MSG_EXISTS)
mptr->msg_out_num = j++;
}
}
if (n_msgs)
{
/* Update 1.MSG HWM */
if (!quiet)
printf ("Updating 1.MSG High Water Mark ...\n");
m = &msgs[1];
if (((i = m->msg_down) > 1) && (m->msg_down <= n_msgs))
{
mptr = &msgs[i];
if (mptr->msg_flags & MSG_EXISTS)
{
if (m->msg_flags & MSG_EXISTS)
{
m->msg_down = mptr->msg_out_num;
if (i != mptr->msg_out_num)
m->msg_flags |= MSG_LINK_CHANGED;
}
else
{
for (m = &msgs[2], j = 2; j <= n_msgs; j++, m++)
{
if ((m->msg_flags & MSG_EXISTS) && (m->msg_out_num == 1))
{
m->msg_down = mptr->msg_out_num;
m->msg_flags |= MSG_LINK_CHANGED;
break;
}
}
}
}
else /* zap (new) 1.msg */
{
if (!(m->msg_flags & MSG_EXISTS))
{
for (m = &msgs[2], j = 2; j <= n_msgs; j++, m++)
{
if ((m->msg_flags & MSG_EXISTS) && (m->msg_out_num == 1))
break;
}
}
m->msg_down = 0;
m->msg_flags |= MSG_LINK_CHANGED;
}
}
else /* summats wrong */
{
if (!(m->msg_flags & MSG_EXISTS))
{
for (m = &msgs[2], j = 2; j <= n_msgs; j++, m++)
{
if ((m->msg_flags & MSG_EXISTS) && (m->msg_out_num == 1))
break;
}
}
m->msg_down = 0;
m->msg_flags |= MSG_LINK_CHANGED;
}
}
/* Process message links */
if (n_msgs)
{
if (!quiet)
printf ("Relinking remaining message(s) ...\n");
for (mptr = &msgs[1], i = 1; i <= n_msgs; mptr++, i++)
{
if (mptr->msg_flags & MSG_DELETED)
continue;
if ((mptr->msg_up <= n_msgs) && ((j = mptr->msg_up) != 0))
{
/* Follow the chain up to one that is good */
while ((j <= n_msgs) && (j > 0) && (msgs[j].msg_flags & MSG_DELETED))
{
/* If we somehow go backwards, bag out because we won't recover */
if ((j > n_msgs) || (j <= 0) || (msgs[j].msg_up <= j))
break;
j = msgs[j].msg_up;
}
if ((j <= n_msgs) && (j > 0) && (msgs[j].msg_flags & MSG_EXISTS))
{
if (msgs[j].msg_out_num != mptr->msg_up)
mptr->msg_flags |= MSG_LINK_CHANGED;
mptr->msg_up = msgs[j].msg_out_num;
}
else
{
mptr->msg_flags |= MSG_LINK_CHANGED;
mptr->msg_up = 0;
}
}
if (((j = mptr->msg_down) != 0) && (mptr->msg_out_num > 1))
{
/* Follow the chain up to one that is good */
while ((j <= n_msgs) && (msgs[j].msg_flags & MSG_DELETED))
{
/* If we somehow go forwards, bag out because we won't recover */
if ((msgs[j].msg_down >= j) || (msgs[j].msg_down > n_msgs))
break;
j = msgs[j].msg_down;
}
if ((j <= n_msgs) && (msgs[j].msg_flags & MSG_EXISTS))
{
if (msgs[j].msg_out_num != mptr->msg_down)
mptr->msg_flags |= MSG_LINK_CHANGED;
mptr->msg_down = msgs[j].msg_out_num;
}
else
{
mptr->msg_flags |= MSG_LINK_CHANGED;
mptr->msg_down = 0;
}
}
}
}
if (n_msgs)
{
/* Update lastread pointer */
fix_lastread ();
if (max)
renum_max_lastread ();
if (opus_120)
renum_opus120_lastread ();
}
/* Update user.bbs */
if ((areanum >= 0) && n_msgs)
{
if (!quiet)
printf ("Updating Opus %s user lastread pointers ...\n",(opus)?("1.1+"):("1.0x"));
if (go_directory (dir_drive1, NULL))
{
printf ("Cannot seem to change directories back to %s\n", dir_drive1);
}
if (opus)
renum_opus (areanum);
else
renum_users (areanum);
if (go_directory (dir_drive3, NULL))
{
printf ("Cannot seem to change directories back to %s\n", dir_drive3);
}
}
/* Delete messages marked for deletion and perform any necessary renames */
if ((renum || n_kills) && (n_msgs))
{
if (!quiet)
printf ("Renaming %smessage(s) ...\n", n_kills ? "and deleting " : "");
write_msg_data ();
}
if (n_msgs)
/* Re-link the reply chains */
if (!quiet)
printf ("Writing new message header links ...\n");
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);
}
if (!quiet)
printf ("Done!\n");
}
int compare (MSG_TYP *arg1,MSG_TYP *arg2)
{
return (arg1->msg_num - arg2->msg_num);
}
void get_date (char *fmt,char *d)
{
#ifndef OS_2
union REGS inregs;
#endif
union REGS outregs;
char temp[5]; /* To hold date so it can be processed again */
#ifndef OS_2
inregs.h.ah = 0x2a;
(void) intdos (&inregs, &outregs);
#else
dosdate ((int *)&outregs.h.dh, (int *)&outregs.h.dl, (int *)&outregs.x.cx, (int *)&outregs.h.al);
#endif
/* Now go through the format string */
while (*fmt != '\0')
{
if (*fmt != ESCAPE_CHAR)
*d++ = *fmt;
else
{
switch (*(++fmt))
{
case 'n':
sprintf (d, "%.3s",
_months[outregs.h.dh - 1]);
d += 3;
break;
case 'N':
sprintf (d, "%s",
_months[outregs.h.dh - 1]);
d += strlen (d);
break;
case 'm':
sprintf (d, "%02d", outregs.h.dh);
d += 2;
break;
case 'd':
sprintf (d, "%02d", outregs.h.dl);
d += 2;
break;
case 'w':
sprintf (d, "%.3s",
_days[outregs.h.ah]);
d += 3;
break;
case 'W':
sprintf (d, "%s",
_days[outregs.h.ah]);
d += strlen (d);
break;
case 'y':
sprintf (temp, "%04d", outregs.x.cx);
sprintf (d, "%.2s", temp+2);
d += 2;
break;
case 'Y':
sprintf (d, "%04d", outregs.x.cx);
d += 4;
break;
default:
*d++ = *fmt;
}
}
++fmt;
}
*d = '\0'; /* Just to be sure that it is null terminated */
}
long days_from_1980 (MSG_PTR str)
{
long ret_val, y, d;
int i;
char m[60], junk[60];
if (((str->date[19])&0xff) != 0xff)
{
if (sscanf (str->date, "%ld %s %ld", &d, m, &y) != 3)
if (sscanf (str->date, "%s %ld %s %ld", junk, &d, m, &y) != 4)
return (600000L);
for (i = 0; i < 12; ++i)
{
if (strnicmp (_months[i], m, 3) == 0)
break;
}
if ((i == 12) && (strnicmp("MEI", m, 3) == 0))
i=4;
y -= 80;
}
else
{
y = (long) (YEAR (&(str->_date_arrived)));
d = (long) (DAY (&(str->_date_arrived)));
i = MONTH (&(str->_date_arrived)) - 1;
}
ret_val = y;
ret_val *= 365;
ret_val += d;
if (i < 12)
ret_val += days_to_month[i];
return (ret_val);
}
void read_msg_data ()
{
int i, f;
MSG *m;
register MSG_TYP *mptr;
char junk[64], junk2[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 > 0) && (i <= MAX_MSGS))
{
mptr = &msgs[i];
mptr->msg_out_num = mptr->msg_num = i;
mptr->msg_flags = MSG_EXISTS;
/* Extract current message header fields */
m = &msg_tmp;
sprintf (junk2, "%d.MSG", mptr->msg_out_num);
if ((f = fast_open (junk2, O_RDONLY|O_BINARY)) == -1)
{
printf ("Error opening '%s'\n", junk2);
mptr->msg_out_num = 0;
mptr->msg_flags = MSG_DELETED;
}
else
{
if (fast_read (f, (char *) m, sizeof (MSG)) != sizeof (MSG))
{
printf ("Error reading '%s'\n", junk2);
mptr->msg_out_num = 0;
mptr->msg_flags = MSG_DELETED;
(void) fast_close (f);
}
else
{
(void) fast_close (f);
mptr->msg_up = m->up;
mptr->msg_down = m->reply;
mptr->msg_attr = m->attr;
mptr->msg_time = days_from_1980 (m);
n_msgs = max(n_msgs, i);
}
}
}
(void) filedir (junk, 1, name, 0);
}
}
void write_msg_data ()
{
register int i;
register MSG_TYP *mptr;
int err;
char oldname[16], newname[16];
(void) qsort ((char *) &msgs[1], n_msgs, sizeof (MSG_TYP), compare);
for (mptr = &msgs[1], i = 1; i <= n_msgs; mptr++, i++)
{
if (mptr->msg_flags & MSG_DELETED)
{
sprintf (oldname, "%d.MSG", mptr->msg_num);
unlink(oldname);
continue;
}
if ((mptr->msg_out_num != mptr->msg_num) && (mptr->msg_flags & MSG_EXISTS))
{
sprintf (oldname, "%d.MSG", mptr->msg_num);
sprintf (newname, "%d.MSG", mptr->msg_out_num);
err = rename (oldname, newname);
if (err)
{
unlink (newname);
err = rename (oldname, newname);
if (err)
printf ("Error %d renaming '%s' to '%s', continuing\n", err, oldname, newname);
}
}
}
}
void kill_number ()
{
register int i;
register MSG_TYP *mptr;
int j;
int nkill = 0;
int start, stop;
start = 1;
for (mptr = &msgs[1], j = 0, i = 1; (j < kill_n1) && (i <= n_msgs) ; mptr++, i++)
{
if (mptr->msg_flags & MSG_EXISTS)
{
++j;
start = i + 1;
}
}
j = 0;
stop = n_msgs;
for (mptr = &msgs[n_msgs], i = n_msgs; (j < kill_n2) && (i >= start); mptr--, i--)
{
if (mptr->msg_flags & MSG_EXISTS)
{
++j;
stop = i - 1;
}
}
for (mptr = &msgs[start], i = start; i <= stop; mptr++, i++)
{
mptr->msg_flags = MSG_DELETED;
nkill++;
}
if (!quiet && nkill)
printf("Killing %d message%s after skipping %s%d message%s, keeping %d message%s ...\n",
nkill,
(nkill == 1) ? ("") : ("s"),
(kill_n1 > 1) ? ("first ") : (""),
kill_n1,
(kill_n1 == 1) ? ("") : ("s"),
kill_n2,
(kill_n2 > 1) ? ("s") : (""));
}
void kill_attr (unsigned int attr)
{
register int i;
register MSG_TYP *mptr;
int nkill = 0;
for (mptr = &msgs[1], i = 1; i <= n_msgs; mptr++, i++)
{
if (mptr->msg_flags & MSG_EXISTS)
{
if (mptr->msg_attr & attr)
{
mptr->msg_flags = MSG_DELETED;
nkill++;
}
}
}
if (!quiet && nkill)
printf("Killing %d %s message%s ...\n",
nkill,
(attr == MSGREAD) ? ("RECEIVED") : ("SENT"),
(nkill == 1) ? ("") : ("s"));
}
void kill_by_date ()
{
register int i;
register MSG_TYP *mptr;
int nkill = 0;
long today;
MSG m;
if (kill_date <= 0)
return;
get_date ("%d %n %y ", m.date);
m.date[19] = 0;
today = days_from_1980 (&m);
for (mptr = &msgs[1], i = 1; i <= n_msgs; mptr++, i++)
{
if (mptr->msg_flags & MSG_EXISTS)
{
if ((today > mptr->msg_time)
&& (today - mptr->msg_time > kill_date))
mptr->msg_flags = MSG_DELETED;
}
}
if (!quiet && nkill)
{
printf("Killing %d message%s over %d day%s old ...\n",
nkill, (nkill == 1) ? ("") : ("s"),
kill_date, (kill_date == 1) ? ("") : ("s") );
}
}
void fancy_str (char *value)
{
register char *sptr;
int lower = 0;
sptr = value;
if (sptr) /* don't touch any NULL pointers */
{
while (*sptr)
{
if (lower)
{
*sptr = (char) tolower (*sptr);
}
else
{
*sptr = (char) toupper (*sptr);
}
lower = isalnum(*sptr++);
}
}
}
int get_system (char *where,SYS_PTR 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)
{
return (NO_SYSTEM);
}
else
{
fast_read (sys_input, (char *) ret_system, sizeof (SYS));
strupr (ret_system->msgpath);
fast_close (sys_input);
areanum = num;
}
}
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)
return (ret);
return (NO_GO);
}
int get_opus (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);
areanum = num;
}
}
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)
return (ret);
return (NO_GO);
}
void fix_lastread ()
{
register int j;
register MSG_TYP *mptr;
int i, k, lr, new, upd;
char buf[20], junk[64];
int lr_array[MAXLASTREADS];
int lrbytes, lrcount;
/* Set up the filename for LASTREA? */
sprintf(junk, "LASTREA?");
(void) filedir (junk, 0, buf, 0);
while (buf[0] != '\0')
{
/* Can we open it? */
if ((lr = fast_open (buf, O_RDWR|O_BINARY)) != -1)
{
/* read in up to MAXLASTREADS elements */
if ((lrbytes = fast_read (lr, (char *) lr_array, sizeof(int)*MAXLASTREADS)) > 0)
{
/* Rewind the file */
(void) fast_lseek (lr, 0L, SEEK_SET);
lrcount = lrbytes / sizeof(int);
if (!quiet)
{
printf("Checking ");
if (lrcount > 1)
{
printf("%d ", lrcount);
}
printf("Sysop LASTREAD pointer%s in %s ...\n",
(lrcount > 1) ? ("s") : (""), buf);
}
/* Check and update lastreads */
for (new = -1, upd = i = 0; i < lrcount; i++)
{
/* validity check this entry */
if ((j = lr_array[i]) < 2)
/* if not zero, zip it and schedule rewrite */
{
if (j)
{
upd++;
new = 0;
}
}
else
/* run back up the entries with it */
{
for (mptr = &msgs[k = min(n_msgs, j)]; k > 1; k--, mptr--)
{
/* does this one persist? */
if (!(mptr->msg_flags & MSG_EXISTS))
{
continue;
}
/* will it require a rewrite? */
if ((mptr->msg_out_num == j) && (k == j))
{
new = -2;
break;
}
else
{
new = mptr->msg_out_num;
upd++;
break;
}
}
if ((new > -2) && ((new < 2) || (k < 2)))
{
new = 0;
upd++;
}
}
if (new > -1)
{
if (!quiet)
{
printf("Changed %s lastread #%d from %d to %d ...\n",
buf, i+1, j, new);
}
lr_array[i] = new;
}
new = -1;
}
/* Write out lastreads */
if (upd)
{
(void) fast_write (lr, (char *) lr_array, lrbytes);
}
/* Now close up */
(void) fast_close (lr);
}
else
{
printf ("It seems that the LASTREAD file '%s' is empty!\n", buf);
(void) fast_close (lr);
}
}
else
{
printf ("Unable to open the LASTREAD file '%s'!\n", buf);
}
(void) filedir (junk, 1, buf, 0);
}
}
int renum_users (int area)
{
char username[13];
int user_bbs;
int i, j, k, l;
int read_size;
sprintf (username, "%s%s", USERNAME, DEF_EXT);
if ((user_bbs = fast_open (username, O_RDWR|O_BINARY)) == -1)
{
printf ("Cannot find Opus 1.0x user list\n");
return (ALL_OK);
}
while ((read_size = fast_read (user_bbs, (char *) users, MAX_USERS * sizeof (USR))) > 0)
{
(void) fast_lseek (user_bbs, (long) (-read_size), SEEK_CUR);
l = read_size / sizeof (USR);
for (k = 0; k < l; k++)
{
for (i = 0; i < 10; i++)
{
if (users[k].msgs_read[i].area == area)
break;
}
if (i != 10)
{
for (j = users[k].msgs_read[i].last_read; j > 0; j--)
{
if (msgs[j].msg_flags & MSG_EXISTS)
break;
}
if (j == 0)
users[k].msgs_read[i].last_read = 0;
else
users[k].msgs_read[i].last_read = msgs[j].msg_out_num;
}
}
(void) fast_write (user_bbs, (char *) users, read_size);
}
(void) fast_close (user_bbs);
return (ALL_OK);
}
int renum_opus (int area)
{
int user_bbs;
int i;
int read_size;
if ((user_bbs = fast_open ("USER.DAT", O_RDONLY|O_BINARY)) == -1)
{
printf ("Cannot find Opus 1.1+ user list\n");
return (ALL_OK);
}
(void) fast_close (user_bbs);
user_bbs = fast_open ("USER.DAT", O_RDWR|O_BINARY);
while ((read_size = fast_read (user_bbs, (char *) &opus_user, sizeof (_usr))) > 0)
{
if ((i = opus_user.lastmsg[area]) <= 0)
continue;
(void) fast_lseek (user_bbs, (long) (-read_size), SEEK_CUR);
opus_user.lastmsg[area] = 0;
if ((i <= n_msgs) && (i > 0))
{
if (!(msgs[i].msg_flags & MSG_EXISTS))
{
while(--i)
{
if (msgs[i].msg_flags & MSG_EXISTS)
{
opus_user.lastmsg[area] = msgs[i].msg_out_num;
break;
}
}
}
else
{
opus_user.lastmsg[area] = msgs[i].msg_out_num;
}
}
(void) fast_write (user_bbs, (char *) &opus_user, read_size);
}
(void) fast_close (user_bbs);
return (ALL_OK);
}
void renum_opus120_lastread ()
{
register int j;
register MSG_TYP *mptr;
int i, k, lrb, new, upd;
LMR lr_array[MAXLASTREADS];
int lrbytes, lrcount;
/* Can we open it? */
if ((lrb = fast_open("LREAD.DAT", O_RDWR|O_BINARY)) != -1)
{
/* read in up to MAXLASTREADS elements */
while ((lrbytes = fast_read (lrb, (char *)lr_array, sizeof(lr_array))) > 0)
{
lrcount = lrbytes / sizeof(struct _lmr);
if (!quiet)
{
printf("Checking Opus 1.2x LREAD.DAT entries ...\n");
}
/* Check and update lastreads */
for (new = -1, upd = i = 0; i < lrcount; i++)
{
/*
** Do the high_read pointer
*/
/* validity check this entry */
if ((j = lr_array[i].high_msg) < 2)
/* if not zero, zip it and schedule rewrite */
{
if (j)
{
upd++;
new = 0;
}
}
else
/* run back up the entries with it */
{
for (mptr = &msgs[k = min(n_msgs, j)]; k > 1; k--, mptr--)
{
/* does this one persist? */
if (!(mptr->msg_flags & MSG_EXISTS))
{
continue;
}
/* will it require a rewrite? */
if ((mptr->msg_out_num == j) && (k == j))
{
new = -2;
break;
}
else
{
new = mptr->msg_out_num;
upd++;
break;
}
}
if ((new > -2) && ((new < 2) || (k < 2)))
{
new = 0;
upd++;
}
}
if (new > -1)
lr_array[i].high_msg = new;
new = -1;
/*
** Do the last_read pointer
*/
/* validity check this entry */
if ((j = lr_array[i].last_msg) < 2)
/* if not zero, zip it and schedule rewrite */
{
if (j)
{
upd++;
new = 0;
}
}
else
/* run back up the entries with it */
{
for (mptr = &msgs[k = min(n_msgs, j)]; k > 1; k--, mptr--)
{
/* does this one persist? */
if (!(mptr->msg_flags & MSG_EXISTS))
{
continue;
}
/* will it require a rewrite? */
if ((mptr->msg_out_num == j) && (k == j))
{
new = -2;
break;
}
else
{
new = mptr->msg_out_num;
upd++;
break;
}
}
if ((new > -2) && ((new < 2) || (k < 2)))
{
new = 0;
upd++;
}
}
if (new > -1)
lr_array[i].last_msg = new;
new = -1;
}
/* Write out lastreads */
if (upd)
{
/* Rewind the file */
(void) fast_lseek (lrb, (long) (-lrbytes), SEEK_CUR);
(void) fast_write (lrb, (char *) lr_array, lrbytes);
}
}
(void) fast_close (lrb);
}
else
{
printf ("Unable to open the LREAD.DAT file!\n");
}
}
void renum_max_lastread ()
{
register int j;
register MSG_TYP *mptr;
int i, k, lrb, new, upd;
int lr_array[MAXLASTREADS];
int lrbytes, lrcount;
/* Can we open it? */
if ((lrb = fast_open("LASTREAD.BBS", O_RDWR|O_BINARY)) != -1)
{
if (!quiet)
{
printf("Checking Maximus LASTREAD.BBS entries ...\n");
}
/* read in up to MAXLASTREADS elements */
while ((lrbytes = fast_read (lrb, (char *) lr_array, sizeof(int)*MAXLASTREADS)) > 0)
{
lrcount = lrbytes / sizeof(int);
/* Check and update lastreads */
for (new = -1, upd = i = 0; i < lrcount; i++)
{
/* validity check this entry */
if ((j = lr_array[i]) < 2)
/* if not zero, zip it and schedule rewrite */
{
if (j)
{
upd++;
new = 0;
}
}
else
/* run back up the entries with it */
{
for (mptr = &msgs[k = min(n_msgs, j)]; k > 1; k--, mptr--)
{
/* does this one persist? */
if (!(mptr->msg_flags & MSG_EXISTS))
{
continue;
}
/* will it require a rewrite? */
if ((mptr->msg_out_num == j) && (k == j))
{
new = -2;
break;
}
else
{
new = mptr->msg_out_num;
upd++;
break;
}
}
if ((new > -2) && ((new < 2) || (k < 2)))
{
new = 0;
upd++;
}
}
if (new > -1)
lr_array[i] = new;
new = -1;
}
/* Write out lastreads */
if (upd)
{
/* Rewind the file */
(void) fast_lseek (lrb, (long) (-lrbytes), SEEK_CUR);
(void) fast_write (lrb, (char *) lr_array, lrbytes);
}
}
(void) fast_close (lrb);
}
else
{
printf ("Unable to open the LASTREAD.BBS file!\n");
}
}
void relink ()
{
int i, f;
MSG_TYP *mptr;
MSG *m1;
m1 = &msg_tmp;
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_out_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);
m1->up = mptr->msg_up;
m1->attr = mptr->msg_attr;
m1->reply = mptr->msg_down;
(void) fast_write (f, (char *) &msg_tmp, sizeof(MSG));
(void) fast_close (f);
}
}
}
int go_directory (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((unsigned)(toupper(dir[0]) - 'A' + 1), &num_drives);
#endif
if (save != NULL)
{
getcwd (save, MAX_PATH);
}
}
return (chdir (dir));
}
void msgnum_usage ()
{
printf ("\n\n");
#ifndef OS_2
printf ("Usage: MSGNUM [-D days] [-N save1 save2]\n [-Q] [-K] [-S] [-M] [-O|O120] [-R] dir\n");
#else
printf ("Usage: MSGNUMP [-D days] [-N save1 save2]\n [-Q] [-K] [-S] [-M] [-O|O120] [-R] dir\n");
#endif
printf ("Where: -Q = Quiet, -K = Kill received msgs, -S = Kill sent msgs,\n");
printf (" -M = Max 1.0x, -O = Opus 1.1x, -O120 = Opus 1.2x file structures,\n");
printf (" dir is the SYSTEMxx.BBS/DAT number or the message area path.\n\n");
exit (1);
}