home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-05 | 40.0 KB | 1,455 lines |
- /* #define OS2 1 */
- /**************************************************************************
- I hate to do this, but here goes:
-
- The source code for O_RENUM is provided for your use and examination.
-
- Because of a recent malicious "hack" of the source code, you are ASKED NOT
- to make the source available for DownLoad or FileRequest without my
- permission. This is to protect the FIDOnet community more than it is
- to protect the source code itself.
-
- If you make any changes to the program that you would like to see
- incorporated into MY next release, please SEND CODE <tm, Wynn Wagner III>
- or enough information to understand what needs to be done. My FIDOnet
- node number is 1:133/302. My EGGnet address is 99:9000/6.
-
- Steve Antonoff
- Atlanta, GA
- August 8, 1990
-
- ***********************************************************************
-
- O_RENUM.C Does message renumbering for Opus 1.1x+ in "straight" C.
- No fancy low-level calls, will probably be slower than Bob Hartman's
- but will work on anything.
-
- Fully released to the Opus community. Have fun, make it faster/better
- just keep it free!
- Doug Boone 119/5
- P.O. Box 5108
- Chico, CA 959528
-
- Thanks to Bob Hartman for providing code. Although I didn't use any of
- his code, being able to understand the logic and procedures he used
- were extremely important.
-
- ---------------------------------------------------------------------
- Pre-1.10 1/12/90 Steve Antonoff
- Compiled with COMPACT model of TurboC
- Added ECHO.CTL searching and command line
- argument for SYSTEM directory
-
- 1.10.ix.A 1/22/90 Steve Antonoff
- Applied Bob Davis' fix for 1.MSG 1/22/90 Steve Antonoff
- added "adopted" and "thanks" lines
- Added OPUS version number and COMPDATE
-
- 1.10.ix.C 1/31/90 Steve Antonoff:
- Added additional checks to prevent killing of 1.msg in echo areas
- Added -T (threshhold) option
- Changed fgetc/fputc to fread/fwrite for LASTREAD file
-
- 1.10.ix.D 02/24/90 Steve Antonoff
- Fixed error that occured if last message read was being deleted
- Changed program name from RENUM to O_RENUM
-
- 1.10.ix.E 02/25/90 Steve Antonoff
- Fixed renumbering to include last message (bug introduced in .ix.D)
-
- 1.10.ix.F 02/26/90 Steve Antonoff
- Fixed processing for -N option to not require -R at the same time
-
- 1.10.ix.G 03/06/90 Steve Antonoff
- Fixed processing for 1.MSG to update high water mark properly
-
- 1.10 3/13/90 Steve Antonoff
- Reversed order for test on high water mark
- Official release version for OPUS 1.10
-
- 1.10A 3/17/90 Steve Antonoff
- Fixed update of LASTREAD to reflect correct value (was off by 1)
-
- 1.10B 3/19/90 Steve Antonoff
- Added -W (write) and -A (automatic) options to write and read
- renum parameters from RENUM.DAT in the OPUS SYSTEM path.
-
- 1.10C 3/19/90 Steve Antonoff
- Fixed -N to count 1.MSG in the count of messages kept below #
-
-
- 1.10D 3/25/90 Steve Antonoff
- Suppressed RENUMBER and RELINK if -R is not specified
-
- 1.10E 4/01/90 Steve Antonoff
- -W only writes the parameters - doesn't do any renumbering
- set exit() errorlevels to indicate error condition to DOS:
-
- 0 Successful or no renumber based on threshhold
- 1 Neither area number nor name given
- 2 Insufficient memory for message data
- 3 Error getting system info from SYSTEM.DAT
- 4 Write of RENUM parameters requested - no other processing performed
- 5 Can't find message path
- 6 Insufficient memory for user file data
- 7 Message number exceeds requeste max
- 8 Help (no arguments given)
-
- 1.10F 6/23/90 Steve Antonoff
- "Neatened" up the status displays while running.
- Added a display of the number of messages found.
- Improved intelligence of command line parser to accept directory and
- file names with or without an intervening space.
-
- 1.13 6/30/90 Steve Antonoff
- Converted to "sparse" array manipulation, using qsort() to sort
- message array. Thus, if an area has messages 1, 1000-1010, only 13
- message slots will be used rather than 1011. Slot 0 is not used
- ever.
- Changed message number displays from %4d to %5d, allowing a full
- 32K-1 to be displayed properly.
-
- 1.13A 7/8/90 Steve Antonoff
- Fixed bug in -M argument processing: 'M' was not listed in the switch
- statement as a single parameter argument
-
- 1.13B 7/28/90 Steve Antonoff
- Added -V (verbose) option and changed display of message numbers and
- user names to default to off (quiet mode)
- Added -Q (quiet) option to surpress normal status messages
- Added -C (change directory) for future version
-
- 1.13C 7/31/90 Steve Antonoff
- Changed test to allow -N option to allow -N=0,x
- Fixed logic to use msg_count rather than max_msg in various places;
- Use in_number and out_number rather than the index in various places
- to accommodate sparse matrix
-
- 1.13D 8/9/90 Steve Antonoff
- Changed calls to fix_lastread and fix_user back to use new_max_msg,
- which is correctly returned from relink. 1.13C incorrectly used
- msg_count for these two routines, resulting in message counts for
- lastread and user renumber. The lastread/user lastread counters
- are only adjusted if new_max_msg is not equal to max_msg, indicating
- that some adjustment might be necessary.
-
- 1.13E 8/31/90 Steve Antonoff
- Added check for 4 byte LASTREAD file as used by MSGED. Both pointers
- are adjusted if a 4 byte file is found.
-
- 1.13F 9/8/90 Steve Antonoff
- 1) Extended 1.13E changes to include variable length LASTREAD files
- to accommodate other message handlers. The LASTREAD file is treated
- as a list of int, each int adjusted independently.
- 2) Corrected error in handling of QUIET mode: if QUIET was engaged,
- message renumbering might have been disabled in certain circumstances.
-
- 1.71 8/5/91 Doug Boone.
-
- Update for Opus 1.7x
-
- ***************************************************************************/
- #include <stdio.h>
- #include <dos.h>
- #include <string.h>
- #include <ctype.h>
- #include <io.h>
- #include <stdlib.h>
- #ifdef __TURBOC__
- #include <alloc.h>
- #include <dir.h>
- #else
- #include <malloc.h>
- #endif
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #ifdef OS2
- #define INCL_GPI
- #define INCL_BASE
- #define INCL_DOS
- #include <os2.h>
- #endif
- /*#include "otoolkit.h"*/
- /*#include "compdate.h" */
- #include "newuser.h"
- #include "system.h"
-
- #define VERSION "1.71"
-
- #define MAX_USERS 24 /* Maximum # of users to update at once */
- #define MAX_PATH 80 /* Maximum file path */
- #define MAX_NAME 33 /* Maximum echo name */
-
- #ifndef FALSE
- #define FALSE 0
- #define TRUE !FALSE
- #endif
-
- /*------------------------------------------------------------------------*/
- /* Set of values to use with "flags" to tell renum what to do */
- /*------------------------------------------------------------------------*/
- #define KILL_DAYS 0x0001
- #define KILL_NUMBER 0x0002
- #define KILL_RCVD 0x0004
- #define KILL_SENT 0x0008
- #define RENUMBER 0x0010
- #define RELINK_MSG 0x0020
- #define IS_ECHO 0x1000
- /*------------------------------------------------------------------------*/
- /* Message status flags */
- /*------------------------------------------------------------------------*/
- #define ZAP 0x0001
- #define EXISTS 0x0002
- #define NOT_HERE 0x0000
- /*------------------------------------------------------------------------*/
- /* Return values */
- /*------------------------------------------------------------------------*/
- /*#define ERROR -1 */
- #define SUCCESS 1
-
- /*------------------------------------------------------------------------*/
- /* Used to generate dates */
- /*------------------------------------------------------------------------*/
-
- #define YEAR_SHIFT 9
- #define MONTH_SHIFT 5
- #define DOS_EPOCH 80
-
- #ifndef ERROR
- #define ERROR (-1)
- #endif
- /*------------------------------------------------------------------------*/
- /* The basic internal structure to keep track of messages */
- /*------------------------------------------------------------------------*/
- struct a_msg
- {
- int status; /* internal renum status for this message */
- int in_number; /* what was the original message number */
- int out_number; /* what is the output number going to be */
- int how_old; /* date_received date stamp */
- int uplink; /* "there is a reply....." */
- int downlink; /* "this is a reply to ......" */
- int attr; /* the message's attribute */
- };
-
- /*------------------------------------------------------------------------*/
- /* Global Data */
- /*------------------------------------------------------------------------*/
- struct a_msg *msg;
- int MAX_MSGS = 1024; /* default max message area size */
- char msg_path[MAX_PATH]; /* the message area path */
- char echo_name[MAX_NAME]; /* the echo area name */
- /*int flags = RELINK_MSG;*/ /* RENUM flags so we know what to do */
- char *msg_file_format = "%s%i.MSG"; /* Format for message file name */
- int months[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
- int area = -1; /* What area number is being used */
- char echo_ctl_name[MAX_PATH],opus_sys_path[MAX_PATH];
- int verbose = FALSE;
- int quiet = FALSE;
- int change_dir = FALSE;
- int Opus_120 = FALSE;
-
- struct flag_struct /* RENUM flags so we know what to do */
- {
- unsigned threshhold:1;
- unsigned kill_days:1;
- unsigned kill_number:1;
- unsigned kill_rcvd:1;
- unsigned kill_sent:1;
- unsigned renumber:1;
- unsigned relink:1;
- unsigned is_echo:1;
- unsigned spare:8;
- };
-
- struct renum_param /* RENUM parameter structure */
- {
- struct flag_struct flags;
- int days;
- int keep_lo,keep_hi;
- int min_delete;
- }renum,renum_from_file;
-
- /*------------------------------------------------------------------------*/
- /* Procedure definitions */
- /*------------------------------------------------------------------------*/
-
- void fix_lastread(int);
- void fix_users(int,int);
- int relink(int);
- void delete_msgs(int);
- int kill_count(int);
- int message_count(int);
- int get_sys_info(int,char *);
- int get_msg_info(int *);
- int msg_age_as_of(int);
- void no_parms(int,int);
- int scan_echo_ctl(char *, char *, char *);
- int proc_args(int, char **);
- void show_params(int);
- int read_param_data(int,char *);
- int write_param_data(int,char *);
- #ifdef __TURBOC__
- int msg_cmp(const void *,const void *);
- #else
- int msg_cmp(struct a_msg *,struct a_msg *);
- #endif
- void xprintf(const char *);
- /*--------------------------------------------------------------------------*/
- extern long get_msgpos(int,char *);
- extern char * pascal getstring(byte,int);
- void fix_lread_dat(int);
- /*--------------------------------------------------------------------------*/
- void xprintf(const char *s)
- {
- if (!quiet)
- printf("%s",s);
- }
-
- #ifdef __TURBOC__
- int msg_cmp(const void *msg1,const void *msg2)
- {
- struct a_msg *m1,*m2;
- m1 = (struct a_msg *)msg1;
- m2 = (struct a_msg *)msg2;
- return (m1->in_number - m2->in_number);
- }
- #else
- int msg_cmp(struct a_msg *msg1,struct a_msg *msg2)
- {
- return (msg1->in_number - msg2->in_number);
- }
- #endif
-
- int add_slash(char *path)
- {
- char last_char;
-
- last_char = path[strlen(path)-1];
- if (last_char != '\\' && last_char != ':')
- strcat(path,"\\");
- return last_char;
- }
-
- int main(int argc,char *argv[])
- {
- int i = 1;
- int j;
- int k;
- #ifdef OLDVERSION
- int days; /* Number of days for deleting */
- int keep_lo;
- int keep_hi;
- int min_delete=-1;
- #endif
- int killed_count=0;
- int write_data=0; /* 0 = no action, 1 = write data, 2 = read data*/
- int older; /* Date stamp for older messages */
- int max_msg; /* Highest message number found */
- int new_max_msg; /* Highest message after renumbering */
- int msg_count; /* Number of messages found */
-
- no_parms(argc-1,0); /* give instructions or credit */
-
- msg_path[0] = 0; /* blast out msg_path */
- echo_name[0] = 0;
- echo_ctl_name[0] = 0;
- opus_sys_path[0] = 0;
- renum.min_delete = 0;
-
- renum.flags.threshhold = FALSE;
- renum.flags.kill_days = FALSE;
- renum.flags.kill_number = FALSE;
- renum.flags.kill_rcvd = FALSE;
- renum.flags.kill_sent = FALSE;
- renum.flags.renumber = FALSE;
- renum.flags.relink = TRUE;
- renum.flags.is_echo = FALSE;
-
- write_data = proc_args(argc,argv);
- if (!(msg_path[0]) && (area==-1))
- {
- printf("Neither message area directory nor area number given\n");
- exit(1);
- }
- if ( NULL ==
- (msg = (struct a_msg *) calloc(sizeof(struct a_msg),MAX_MSGS) ) )
- {
- printf("Unable to allocate space for %d messages\n",MAX_MSGS);
- exit(2);
- }
-
- if (echo_ctl_name[0])
- {
- add_slash(echo_ctl_name);
- strcat(echo_ctl_name,"ECHO.CTL");
- }
- if (opus_sys_path[0])
- add_slash(opus_sys_path);
- else
- write_data = 0; /* can't read or write without OPUS system path */
-
- if (msg_path[0])
- {
- strcpy(echo_name,msg_path);
- add_slash(msg_path);
- area = scan_echo_ctl(msg_path,echo_name,echo_ctl_name);
- }
- if (!(msg_path[0])) /* If the message path is no good..... */
- {
- if (ERROR == get_sys_info(area,opus_sys_path) )
- exit(3);
- }
- if ((write_data & 2) && area > -1)
- {
- read_param_data(area,opus_sys_path);
- proc_args(argc,argv);
- }
- show_params(write_data);
- if ((write_data & 1) && area > -1)
- {
- write_param_data(area,opus_sys_path);
- printf("Data written - O_RENUM terminating\n");
- exit(4);
- }
- if (renum.flags.is_echo)
- xprintf("Treating area as ECHOMAIL....\n");
- i = strlen(msg_path) - 1;
- if (msg_path[i] == '\\')
- msg_path[i] = '\0';
- if (access(msg_path,0))
- {
- printf("Can't find path %s\n\n",msg_path);
- exit(5);
- }
- strcat(msg_path,"\\");
- printf("Checking messages in %s\n",msg_path);
-
- max_msg = get_msg_info(&msg_count);
-
- if (!quiet)
- {
- printf("Max message number found: %d\n",max_msg);
- printf("Number of messages found: %d\n",msg_count-1);
- printf("Sorting message array...\n");
- }
- qsort(msg,(size_t)msg_count,sizeof (struct a_msg),msg_cmp);
-
- if (renum.flags.kill_sent)
- {
- xprintf("Marking messages that have been sent........\n");
- for (i = 0; i<= msg_count; i++)
- if (msg[i].attr & MSGSENT)
- msg[i].status = ZAP;
- }
-
- if (renum.flags.kill_rcvd)
- {
- xprintf("Marking messages that have been received....\n");
- for (i = 0; i<= msg_count; i++)
- if (msg[i].attr & MSGREAD)
- msg[i].status = ZAP;
- }
-
- if (renum.flags.kill_days)
- {
- xprintf("Marking old messages....\n");
- older = msg_age_as_of(renum.days);
- for (i = 1; i<= msg_count; i++)
- if (msg[i].how_old < older)
- msg[i].status = ZAP;
- }
-
- if (renum.flags.kill_number)
- {
- if (!quiet)
- printf(
- "Marking messages after #%i and before the highest %i messages.....\n",
- renum.keep_lo,renum.keep_hi);
- }
- else
- {
- renum.keep_hi = msg_count;
- renum.keep_lo = 1;
- }
-
- if (renum.flags.kill_number)
- {
- j = renum.keep_hi;
- i = msg_count;
- while (j > 0 && i > renum.keep_lo)
- {
- if (EXISTS == msg[i].status)
- j--;
- i--;
- }
- if (renum.flags.is_echo) /* don't kill 1.msg for echos */
- {
- k = 2;
- j = 1; /* but remember that we haven't! */
- }
- else
- {
- k = 1;
- j = 0;
- }
- while (j < renum.keep_lo && k <= i)
- {
- if (EXISTS == msg[k].status)
- j++;
- k++;
- }
- for (j = k;j <= i;j++)
- msg[j].status = ZAP;
- }
- killed_count = kill_count(msg_count);
- if (renum.flags.threshhold && (killed_count < renum.min_delete) )
- {
- printf("Fewer than %i messages to delete (%i) - terminating\n",
- renum.min_delete,killed_count);
- exit(0);
- }
- if (!quiet)
- printf("Killing %i messages....\n",killed_count);
- delete_msgs(msg_count);
- if (renum.flags.renumber)
- {
- new_max_msg = relink(msg_count);
- if (new_max_msg != max_msg)
- {
- fix_lastread(new_max_msg);
- if (area != -1) {
- if (Opus_120) {
- fix_lread_dat(new_max_msg);
- }
- /* else Uncomment this line for newer version*/
- /* if (area < 256)
- fix_users(new_max_msg,area); */
- }
- }
- }
- exit(0);
- return 0;
- }
-
- /*------------------------------------------------------------------------*/
- /* Fix up LASTREAD in this area */
- /*------------------------------------------------------------------------*/
- void fix_lastread(int max)
- {
- char full[MAX_PATH];
- FILE *infp;
- int last_msg;
- int i;
- int hit;
- long last_leng,last_cnt;
-
- sprintf(full,"%sLASTREAD",msg_path);
- if ((infp = fopen(full,"r+b")) == NULL)
- return;
- fseek(infp,0L,SEEK_END);
- last_leng = ftell(infp);
- fseek(infp,0L,SEEK_SET);
- if (verbose || !quiet)
- printf("Updating %s:\n",full);
- for (last_cnt = 0 ; last_cnt < last_leng ; last_cnt += 2)
- {
- hit = FALSE;
- fseek(infp,last_cnt,SEEK_SET);
- fread(&last_msg,2,1,infp);
- if (last_msg > 0)
- {
- if (verbose || !quiet)
- printf(" %d ->",full,last_msg);
- for (i = max; i >= 1 && !hit ; i--)
- {
- if (msg[i].in_number <= last_msg)
- {
- last_msg = msg[i].out_number;
- hit = TRUE;
- }
- }
- if (!hit)
- last_msg = 0;
- fseek(infp,last_cnt,SEEK_SET);
- fwrite(&last_msg,2,1,infp);
- if (verbose || !quiet)
- {
- printf("%d\n",last_msg);
- }
- }
- }
- fclose(infp);
- return;
- }
- /*------------------------------------------------------------------------*/
- /* Fix up user records, resetting message areas as needed */
- /*------------------------------------------------------------------------*/
- void fix_users(int high,int area)
- {
- struct _usr *auser;
- int i;
- int j;
- int k;
- int hit=FALSE;
- int user_no = 0;
- FILE *infp;
-
-
- if ( (auser =
- (struct _usr *)calloc(MAX_USERS, sizeof (struct _usr) ) ) ==
- NULL)
- {
- printf("Unable to allocate memory for user file buffer\n");
- exit(6);
- }
- if ((infp = fopen("USER.DAT","r+b")) == NULL)
- {
- printf("\nCouldn't find USER.DAT!!\n");
- return;
- }
- xprintf("Updating USER records..........\n");
- while ((k = fread(auser,sizeof(struct _usr),MAX_USERS,infp)) > 0)
- {
- for (i = 0; i < k; i++)
- {
- user_no++;
- if (auser[i].lastmsg[area] > 0)
- {
- hit = FALSE;
- for (j = high; j >= 1 && !hit; j--)
- {
- if (msg[j].in_number <= auser[i].lastmsg[area])
- {
- if (verbose && !quiet)
- printf("\r%5d -> %5d: (%d) %-40.40s",
- auser[i].lastmsg[area],msg[j].out_number,
- user_no,auser[i].name);
- auser[i].lastmsg[area] = msg[j].out_number;
- hit = TRUE;
- }
- }
- if (!hit)
- auser[i].lastmsg[area] = 1;
- }
- }
- fseek(infp,-((long) (k * sizeof(struct _usr))),SEEK_CUR);
- fwrite(auser,sizeof(struct _usr),k,infp);
- };
- fclose(infp);
- free(auser);
- printf("\n");
- return;
- }
-
- /*------------------------------------------------------------------------*/
- /* Relink the replies in the message headers */
- /*------------------------------------------------------------------------*/
- int relink(int high)
- {
- int i,hit;
- int j = 1;
- int low = 1;
- char new[MAX_PATH];
- char old[MAX_PATH];
- FILE *infp;
- struct _msg amsg;
-
- if (!quiet)
- printf("Renumbering %sMessages........\n",
- (renum.flags.relink) ?"& Relinking ":"");
-
- if (renum.flags.is_echo)
- {
- low = 2;
- j = 2;
- }
- /*------------------------------------------------------------------------*/
- /* This is where renumbering really takes place, finding the messages */
- /* that are still marked as EXISTS and crunching them down. */
- /*------------------------------------------------------------------------*/
- for (i = low; i <= high; i++)
- {
- if (EXISTS == msg[i].status)
- {
- msg[j].status = msg[i].status;
- msg[j].in_number = msg[i].in_number;
- msg[j].out_number = j;
- msg[j].how_old = msg[i].how_old;
- msg[j].uplink = msg[i].uplink;
- msg[j].downlink = msg[i].downlink;
- msg[j].attr = msg[i].attr;
- j++;
- }
- }
- /*------------------------------------------------------------------------*/
- /* Now we've packed down the msg array and found the new highest message */
- /* so begin the process of re-linking the replies */
- /*------------------------------------------------------------------------*/
- high = j;
- if (high)
- high--;
- if (renum.flags.is_echo)
- {
- if (msg[1].status > 0)
- msg[1].status = EXISTS;
- if (msg[1].downlink > 0) /* Handle 1.MSG for echoes */
- {
- hit = FALSE;
- for (j = high; j > 0 && !hit ;j--) /* High Water Mark */
- {
- if (msg[j].in_number <= msg[1].downlink)
- {
- msg[1].downlink = msg[j].out_number;
- j = high;
- hit = TRUE;
- }
- }
- }
- if (msg[1].uplink > 0)
- {
- hit = FALSE;
- for (j = high; j > 0 && !hit; j--)
- {
- if (msg[j].in_number == msg[1].uplink)
- {
- msg[1].uplink = msg[j].out_number;
- j = high;
- hit = TRUE;
- }
- }
- }
- sprintf(new,"%s1.MSG",msg_path);
- infp = fopen(new,"r+b");
- fread(&amsg,sizeof(struct _msg),1,infp);
- amsg.reply = msg[1].downlink;
- amsg.up = msg[1].uplink;
- fseek(infp,0L,SEEK_SET);
- fwrite(&amsg,sizeof(struct _msg),1,infp);
- fclose(infp);
-
- } /* End of special handling for message #1 */
-
- for (i = low; i <= high; i++)
- {
- if (msg[i].downlink > 0)
- {
- hit = FALSE;
- for (j = low; j < i && !hit; j++)
- {
- if (msg[j].in_number == msg[i].downlink)
- {
- msg[i].downlink = j;
- hit = TRUE;
- }
- }
- }
- if (msg[i].uplink > 0)
- {
- hit = FALSE;
- for (j = i; j <= high && !hit; j++)
- {
- if (msg[j].in_number == msg[i].uplink)
- {
- msg[i].uplink = j;
- hit = TRUE;
- }
- }
- }
- }
- /*------------------------------------------------------------------------*/
- /* Rename the messages */
- /*------------------------------------------------------------------------*/
- for (i = low; i <= high; i++)
- {
- if (msg[i].in_number != i)
- {
- sprintf(new,msg_file_format,msg_path,msg[i].out_number);
- sprintf(old,msg_file_format,msg_path,msg[i].in_number);
- if (verbose && !quiet)
- printf("\r%5d -> %5d",msg[i].in_number,msg[i].out_number);
- if (rename(old,new) != 0)
- {
- unlink(new);
- rename(old,new);
- }
- if ( (msg[i].uplink || msg[i].downlink) && (renum.flags.relink) )
- {
- infp = fopen(new,"r+b");
- fread(&amsg,sizeof(struct _msg),1,infp);
- amsg.reply = msg[i].downlink;
- amsg.up = msg[i].uplink;
- fseek(infp,0L,SEEK_SET);
- fwrite(&amsg,sizeof(struct _msg),1,infp);
- fclose(infp);
- }
- }
- }
- if (verbose && !quiet)
- printf("\n");
- return(high); /* Return the new max_msg */
- }
-
- /*------------------------------------------------------------------------*/
- /* Delete all the messages who have a status of ZAP */
- /*------------------------------------------------------------------------*/
- void delete_msgs(int high)
- {
- char full[MAX_PATH];
- int i;
- int j = 1;
-
- if (renum.flags.is_echo)
- j = 2;
- for (i = j;i <= high;i++)
- {
- if (ZAP == msg[i].status)
- {
- if (verbose && !quiet)
- printf("Kill %5d\r",msg[i].in_number);
- sprintf(full,msg_file_format,msg_path,msg[i].in_number);
- unlink(full);
- }
- }
- if (verbose && !quiet)
- printf("\n");
- return;
- }
- /*------------------------------------------------------------------------*/
- /* Read the SYSTEM*.DAT path, only works with Opus 1.10! */
- /*------------------------------------------------------------------------*/
- int get_sys_info(int area,char *opus_sys_path)
- {
- struct _sys one_sys;
- FILE *handle;
- char sys_path[MAX_PATH];
- struct _msgsys asys;
- long f_pos;
- int fh;
- char *junk;
-
- if (Opus_120) {
- if ((f_pos = get_msgpos(area,opus_sys_path)) < 0L)
- return(ERROR);
- sprintf(sys_path,"%sSYSMSG.DAT",opus_sys_path);
- if ((fh = open(sys_path,O_RDONLY|O_BINARY)) < 0) {
- printf("\nFailed to open %s\n",sys_path);
- return(ERROR);
- }
- lseek(fh,f_pos,SEEK_SET);
- read(fh,(char*)&asys,sizeof(struct _msgsys));
- junk = getstring(asys.Path_Len,fh);
- strcpy(msg_path,junk);
- free(junk);
- close(fh);
- if (asys.Attrib & ECHOMAIL)
- renum.flags.is_echo = TRUE;
- return(SUCCESS);
- }
- /*--------------------------------------------------------------------------*/
- sprintf(sys_path,"%sSYSTEM%02X.DAT",opus_sys_path,area);
-
- if ((handle = fopen(sys_path,"rb")) == NULL)
- {
- printf("Couldn't open %s!!\n",sys_path);
- return(ERROR);
- }
- if ((fread(&one_sys,sizeof(struct _sys),1,handle)) < 0)
- {
- printf("Error reading %s!!\n",sys_path);
- fclose(handle);
- return(ERROR);
- }
-
- strcpy(msg_path,(char *)one_sys.msgpath);
- fclose(handle);
- if (one_sys.attrib & ECHOMAIL)
- renum.flags.is_echo = TRUE;
- return(SUCCESS);
- }
- /*------------------------------------------------------------------------*/
- /* Read the message headers and load up the msg[] array */
- /*------------------------------------------------------------------------*/
- int get_msg_info(int *count)
- {
- struct _msg amsg;
- char fullpath[MAX_PATH];
- FILE *handle;
- #ifdef __TURBOC__
- struct ffblk ffblk;
- #elif OS2
- HDIR hdir;
- USHORT usSearch;
- FILEFINDBUF findbuf;
- #else
- struct find_t ffblk;
- #endif
- int done;
- int i;
- int high_msg = 0;
-
- *count = 1;
- sprintf(fullpath,"%s*.MSG",msg_path);
- #ifdef __TURBOC__
- done = findfirst(fullpath,&ffblk,0);
- #elif OS2
- DosFindFirst(fullpath,&hdir,0x0017,&findbuf,sizeof(findbuf),&usSearch,0L);
- if (usSearch)
- done = 0;
- else
- done = 1;
- printf("\nPath: %s Result: %s %x %x",fullpath,findbuf.achName,usSearch,done);
- #else
- done = _dos_findfirst(fullpath,_A_NORMAL,&ffblk);
- #endif
-
- printf("Checking:\n");
- while (!done) {
- #ifdef __TURBOC__
- i = atoi(ffblk.ff_name);
- #elif OS2
- i = atoi(findbuf.achName);
- printf("\nFile: %s Done = %x %x",
- findbuf.achName,done,usSearch);
- #else
- i = atoi(ffblk.name);
- #endif
- if (i > MAX_MSGS)
- {
- printf("Message number %d exceeds max limit\n",i);
- exit(7);
- }
- sprintf(fullpath,msg_file_format,msg_path,i);
- if ((handle = fopen(fullpath,"rb")) == NULL)
- msg[i].status = NOT_HERE;
- else
- {
- if ((fread(&amsg,sizeof(struct _msg),1,handle)) < 0)
- msg[i].status = ZAP; /* this must be a bogus message, no header */
- else
- {
- if (verbose && !quiet)
- printf("%5d\r",i);
- msg[*count].status = EXISTS;
- msg[*count].in_number = i;
- msg[*count].uplink = amsg.up;
- msg[*count].downlink = amsg.reply;
- msg[*count].attr = amsg.attr;
- msg[*count].how_old = amsg.date_arrived.date;
- }
- if (high_msg < i)
- high_msg = i;
- fclose(handle);
- }
- (*count)++;
- #ifdef __TURBOC__
- done = findnext(&ffblk);
- #elif OS2
- done = DosFindNext(hdir,&findbuf,sizeof(findbuf),&usSearch);
- if (usSearch)
- done = 0;
- else
- done = 1;
- #else
- done = _dos_findnext(&ffblk);
- #endif
- };
- if (verbose && !quiet)
- printf("\n");
- return(high_msg);
- }
-
- /*------------------------------------------------------------------------*/
- /* Work out what the date stamp would have been on the date (how_old) ago */
- /*------------------------------------------------------------------------*/
- int msg_age_as_of(int kill_date)
- {
- int day;
- int month;
- int year;
- int check;
- #ifdef OS2
- struct _DATETIME date;
-
-
- DosGetDateTime(&date);
-
- month = date.month;
- day = date.day;
- year = date.year;
- #else
- union REGS inregs,outregs;
-
- inregs.h.ah = 0x2a;
- intdos(&inregs,&outregs);
- year = outregs.x.cx;
- month = outregs.h.dh;
- day = outregs.h.dl;
- #endif
-
- while (kill_date > 0)
- {
- if (day > kill_date)
- {
- day -= kill_date;
- kill_date = 0;
- }
- else
- {
- months[1] = (year % 4 ? 28 : 29); /* Leap years through 2099 */
- if (month == 1) /* move back to previous year */
- {
- if (kill_date >= 31)
- kill_date -= 31;
- else
- {
- day = 31 + day - kill_date;
- kill_date = 0;
- }
- year--;
- month = 12;
- }
- else
- {
- if (kill_date >= months[month-2])
- kill_date -= months[month-2];
- else
- {
- day = months[month-2] + day - kill_date;
- kill_date = 0;
- }
- month--;
- }
- }
- }
- /*------------------------------------------------------------------------*/
- if (!quiet)
- printf("Kill older than: %02d-%02d-%4d\n",month,day,year);
- /*------------------------------------------------------------------------*/
- year = (year % 100);
- year -= DOS_EPOCH;
- check = year << YEAR_SHIFT;
- check += month << MONTH_SHIFT;
- check += day;
- return(check);
- }
-
- /*------------------------------------------------------------------------*/
- /* Your basic help and exit messages */
- /*------------------------------------------------------------------------*/
- void no_parms(int argc,int arg_char)
- {
- printf("\n\n"
- "O_RENUM %s %s - adopted by Steve Antonoff, 133/302\n"
- "Thanks to Bob Hartman, Doug Boone and Bob Davis.\n",
- VERSION,__DATE__);
- if (argc > 0)
- return;
- if (argc < 0)
- printf("\nError detected in command option: %c\n",arg_char);
- printf(
- "\n"
- "Use as O_RENUM [-K] [-N #1 #2] [-D ##] [-S] [-M #] [-F] [-E path]\n"
- " [-O path] [-T #] [-Q] [-V] [-R] [#|path|conf]\n"
- "\n"
- "-2 .............. Opus 1.7x!\n"
- "-K .............. Kill received messages\n"
- "-S .............. Delete messages that have already been sent\n"
- "-N #1 #2 ........ Keep the first #1 messages and the last #2 messages\n"
- "-D ## ........... Kill message more than ## days old\n"
- "-M # ............ Maximum number of messages to handle (100-4500)\n"
- "-F .............. Fast renum (don't relink message chains)\n"
- "-E path ......... Path (disk:\\dir) to ECHO.CTL\n"
- "-O path ......... Path (disk:\\dir) to OPUS SYSTEM??.DAT files\n"
- "-T # ............ Threshhold (kill only if more than # msgs to kill)\n"
- "-Q .............. Quiet mode (few displays)\n"
- "-V .............. Verbose mode (message count & user names displayed)\n"
- "-R .............. Renumber the messages\n"
- "-W .............. Write parameters to RENUM.DAT and terminate\n"
- "-A .............. Automatic renum (use data in RENUM.DAT\n"
- "#/path/conf ..... Area number, path or conference name (tag) for messages\n"
- "-W and -A require an area number, either from the command line or from\n"
- "ECHO.CTL; both require an OPUS SYSTEM PATH (-o)\n"
- "\n"
- "Commands and parameters may be separated by spaces or they can be run\n"
- "together, or they can be separated by \"=\" and the -N option can use a\n"
- "comma to separte the two numbers.\n");
- exit(8);
- }
-
- int scan_echo_ctl(char *msg_path,char *area_name,char *echo_ctl_path)
- {
- FILE *ctl;
- int areanum;
- char echo_path[MAX_PATH];
- char echo_name[MAX_NAME];
- char buffer[256];
-
- if (!quiet)
- printf("Scanning %s for echo area directory %s...\n",
- echo_ctl_path,msg_path);
- if ( ( ctl = fopen(echo_ctl_path,"rt") ) == NULL )
- {
- printf("%s not found.....\n",echo_ctl_path);
- return -1;
- }
- while (!feof(ctl))
- {
- if (fgets(buffer,255,ctl))
- {
- sscanf(buffer,"%d %s %s",&areanum,echo_path,echo_name);
- if ( !stricmp(echo_path,msg_path ) ||
- !stricmp(echo_name,area_name) )
- {
- if (!quiet)
- printf("Found: area #%d.....\n",areanum);
- fclose(ctl);
- msg_path[0] = 0;
- return areanum;
- }
- }
- }
- printf("%s (%s) not found.....\n",msg_path,area_name);
- return -1;
- }
-
- int kill_count(int msg_count)
- {
- int i,kill=0;
-
- xprintf("Counting messages to be killed....\n");
- if ( (renum.flags.is_echo) && msg[1].status == ZAP)
- msg[1].status = EXISTS;
- for (i=1 ; i <= msg_count ; i++)
- if (msg[i].status == ZAP)
- kill++;
- return kill;
- }
-
- /**************************************************************************/
-
- int proc_args(int argc, char *argv[])
- {
- int arg=1,write_data=0;
- char *arg_s,*arg_data1,*arg_data2;
- static int first=TRUE;
-
- if (first)
- {
- printf("Processing command line arguments....\n");
- }
- while (arg<argc)
- {
- strupr(argv[arg]);
- arg_s = argv[arg];
- if (*arg_s == '-' || *arg_s == '/')
- {
- ++arg_s;
- arg_data1 = arg_s + 1;
- if (*arg_data1 == '=')
- arg_data1++;
- arg_data2 = arg_data1;
- while (*arg_data2 && *arg_data2 != ',')
- arg_data2++;
- if (*arg_data2 == ',' || *arg_data2 == '=')
- arg_data2++;
- switch (*arg_s) /* group options:
- no parameters,
- one parameter,
- two parameters */
- {
- case 'K': /* no parameters */
- case 'S':
- case 'F':
- case 'R':
- case 'W':
- case 'A':
- case 'V':
- case 'Q':
- case 'C':
- break;
- case 'D': /* one parameter */
- case 'T':
- case 'E':
- case 'O':
- case 'M':
- case 'N': /* two parameters */
- if (!(*arg_data1) ) /* no parameters within arg */
- {
- arg++;
- arg_data1 = argv[arg];
- arg_data2 = arg_data1;
- while (*arg_data2 && *arg_data2 != ',')
- arg_data2++;
- if (*arg_data2 == ',' || *arg_data2 == '=')
- arg_data2++;
- }
-
- if (*arg_s == 'N') /* only two parameter option */
- {
- if (!(*arg_data2) ) /* no second parameter */
- {
- arg++;
- arg_data2 = argv[arg];
- }
- }
- break;
- }
- switch(*arg_s)
- {
- case '2':
- Opus_120 = TRUE;
- break;
- case 'V':
- verbose = TRUE;
- break;
- case 'Q':
- quiet = TRUE;
- break;
- case 'C':
- change_dir = TRUE;
- break;
- case 'N':
- renum.keep_lo = atoi(arg_data1);
- renum.keep_hi = atoi(arg_data2);
- renum.flags.kill_number = TRUE;
- if (renum.keep_hi <= 0 || renum.keep_lo < 0)
- no_parms(-1,*arg_s);
- break;
-
- case 'R':
- renum.flags.renumber = TRUE;
- break;
-
- case 'D':
- renum.days = atoi(arg_data1);
- renum.flags.kill_days = TRUE;
- if (renum.days <= 0)
- no_parms(-1,*arg_s);
- break;
-
- case 'K':
- renum.flags.kill_rcvd = TRUE;
- break;
-
- case 'S':
- renum.flags.kill_sent = TRUE;
- break;
-
- case 'E':
- if (first)
- {
- if (!(*arg_data1))
- no_parms(-1,*arg_s);
- strcpy(echo_ctl_name,arg_data1);
- }
- break;
-
- case 'O':
- if (first)
- {
- if (!(*arg_data1))
- no_parms(-1,*arg_s);
- strcpy(opus_sys_path,arg_data1);
- }
- break;
-
- case 'M':
- MAX_MSGS = atoi(arg_data1);
- if (MAX_MSGS == 0)
- no_parms(-1,*arg_s);
- if (MAX_MSGS < 100)
- MAX_MSGS = 100;
- if (MAX_MSGS > 4500)
- MAX_MSGS = 4500;
- break;
-
- case 'T':
- renum.min_delete = atoi(arg_data1);
- if (renum.min_delete <= 0)
- no_parms(-1,*arg_s);
- renum.flags.threshhold = TRUE;
- break;
-
- case 'F':
- renum.flags.relink = FALSE;
- break;
-
- case 'W':
- write_data += 1;
- break;
-
- case 'A':
- write_data += 2;
- break;
- }
- }
- else
- {
- if (first)
- {
- if (isdigit(*argv[arg]) > 0) /* is this an area number? */
- area = atoi(argv[arg]);
- else
- strcpy(msg_path,argv[arg]); /* must be just a path */
- }
- }
- arg++;
- }
- first = FALSE;
- return (write_data);
- }
-
- /**************************************************************************/
-
- void show_params(int write_data)
- {
- char *on="ON",*off="OFF";
- if (quiet)
- return;
- printf("\nWriting parameters: %s",write_data==1?on:off);
- printf("\nReading parameters: %s",write_data==2?on:off);
- printf("\nThreshhold: %s",renum.flags.threshhold?on:off);
- if (renum.flags.threshhold)
- printf(" %d messages minimum",renum.min_delete);
- printf("\nDelete by days: %s",renum.flags.kill_days?on:off);
- if (renum.flags.kill_days)
- printf(" %d days old or older",renum.days);
- printf("\nKill by Msg Number: %s",renum.flags.kill_number?on:off);
- if (renum.flags.kill_number)
- printf(" Leave first %d and last %d messages",
- renum.keep_lo,renum.keep_hi);
- printf("\nRelinking: %s",renum.flags.relink?on:off);
- printf("\nRenumbering: %s",renum.flags.renumber?on:off);
- printf("\nKill Sent: %s",renum.flags.kill_sent?on:off);
- printf("\nKill Rcvd: %s",renum.flags.kill_rcvd?on:off);
- if (*opus_sys_path)
- printf("\nOPUS System Path: %s",opus_sys_path);
- if (*echo_ctl_name)
- printf("\nECHO.CTL Name: %s",echo_ctl_name);
- printf("\nMessage path: %s",msg_path);
- printf("\n");
- }
-
- int read_param_data(int area,char *opus_sys_path)
- {
- FILE *handle;
- char sys_path[MAX_PATH];
-
- sprintf(sys_path,"%sRENUM.DAT",opus_sys_path);
-
- if ((handle = fopen(sys_path,"rb")) == NULL)
- {
- printf("Couldn't open %s!!\n",sys_path);
- return(ERROR);
- }
- fseek(handle,(long)area * sizeof(struct renum_param),SEEK_SET);
- if ((fread(&renum_from_file,sizeof(struct renum_param),1,handle)) < 0)
- {
- printf("Error reading %s!!\n",sys_path);
- fclose(handle);
- return(ERROR);
- }
-
- memcpy(&renum,&renum_from_file,sizeof(struct renum_param));
- fclose(handle);
- return(SUCCESS);
- }
-
- int write_param_data(int area,char *opus_sys_path)
- {
- FILE *handle;
- char sys_path[MAX_PATH];
- int area_no;
-
-
- sprintf(sys_path,"%sRENUM.DAT",opus_sys_path);
-
- if (access(sys_path,0))
- {
- if ( (handle = fopen(sys_path,"w+b") ) == NULL)
- {
- printf("Couldn't create %s!!\n",sys_path);
- return (ERROR);
- }
- for (area_no = 0 ; area_no < 256 ; area_no++)
- {
- if ((fwrite(&renum,sizeof(struct renum_param),1,handle)) < 0)
- {
- printf("Error initializing %s!!\n",sys_path);
- return(ERROR);
- }
- }
- fclose(handle);
- }
-
- if ( ( handle = fopen(sys_path,"r+b") ) == NULL)
- {
- printf("Couldn't open %s!!\n",sys_path);
- return(ERROR);
- }
- fseek(handle,(long)area * sizeof(struct renum_param),SEEK_SET);
- if ((fwrite(&renum,sizeof(struct renum_param),1,handle)) < 0)
- {
- printf("Error writing %s!!\n",sys_path);
- fclose(handle);
- return(ERROR);
- }
-
- fclose(handle);
- return(SUCCESS);
- }
-
- void fix_lread_dat(int high)
- {
- int infh;
- int outfh;
- int hit;
- int j;
- struct _lmr lreads;
- char old_name[80];
- char new_name[80];
-
- strcpy(old_name,msg_path);
- strcpy(new_name,msg_path);
- strcat(old_name,"LREAD.OLD");
- strcat(new_name,"LREAD.DAT");
-
- if (!quiet)
- printf("\nUpdating %s",old_name);
- unlink(old_name);
- rename(new_name,old_name);
-
- infh = open(old_name,O_BINARY|O_RDONLY);
- outfh = open(new_name,O_BINARY|O_WRONLY|O_CREAT,S_IWRITE|S_IREAD);
-
- while ((read(infh,(char *)&lreads,sizeof(struct _lmr))) == sizeof(struct _lmr)) {
- hit = 0;
- for (j = high; j > 1 && hit != 3; j--) {
- if (msg[j].in_number <= lreads.last_msg) {
- lreads.last_msg = j;
- hit |= 0x01;
- } /* End of success handling */
- if (msg[j].in_number <= lreads.high_msg) {
- lreads.high_msg = j;
- hit |= 0x02;
- }
- } /* End of for() loop */
- if (!hit)
- continue;
- if (!(hit & 0x02))
- lreads.high_msg = lreads.last_msg;
- if (!(hit & 0x01))
- lreads.last_msg = lreads.high_msg;
- write(outfh,(char *)&lreads,sizeof(struct _lmr));
- } /* End of while loop */
- close(infh);
- close(outfh);
- unlink(old_name);
- return;
- }
-
-
-