home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 2 BBS
/
02-BBS.zip
/
muprg110.zip
/
MUPURGE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-09
|
17KB
|
608 lines
#define RDS_TITLE "MUPURGE" /* Program Name */
#ifdef __OS2__
#undef RDS_TITLE
#define RDS_TITLE "MUPURGEP" /* Program Name */
#endif
#define RDS_DATES "1995" /* Copyright Date */
#define RDS_VERSION "1.10" /* Version Number */
#define NUM_RULES 20 /* Maximum Purge Rules */
/*
MUPURGE / MUPURGEP
Copyright (c) Bob Swift, 1995. All Rights Reserved.
This program is used to read the Max 3.00 USER.BBS file in the
current directory and purge users based on a combination of access,
number of calls, and days since the last call. Purge criteria are
determined by the Sysop in a control file. The first record in
USER.BBS (usually the sysop) is ignored, as are any records marked as
"Permanent". Records marked as "Deleted" are purged.
The format for using this program is as follows:
MUPURGE [ctlfile] (for DOS)
MUPURGEP [ctlfile] (for OS/2)
Where [ctlfile] is the path and name of the control file (default is
MUPURGE.CTL in the current directory).
Examples: MUPURGE c:\max\misc\usrpurge.cfg
MUPURGEP ctlfiles\mupurge.ctl
MUPURGEP
The program will display a VERY brief set of instructions if it encounters
an error. The following is a list of the error codes returned by the
program:
0 - No errors. Normal termination.
1 - Bad / Extra command line argument.
2 - Unable to open the control file.
3 - No purge criteria specified.
4 - Unable to create the backup files.
5 - Unable to read the input files.
6 - Unable to write the output files.
7 - Unable to write the log file.
When an error is encountered, the program will exit immediately and will
attempt to properly close all files.
Although I have chosen to retain all rights to this program, you are free
to use it under the following conditions:
- You realize that there is NO Warrantee of any sort.
It was tested pretty thoroughly here before release
but who knows what bugs may be lurking within.
- You will not modify the code and release a new version
of the program. I welcome suggestions for improvement
(especially when accompanied by code) but I make no
guarantee of future releases.
- You drop me a note to let me know that you use the
program. That way, I know who to inform if there are
any future releases. Please either send netmail to:
Bob Swift
1:342/5 @ fidonet
or a postcard to:
Bob Swift
5708 - 47th Street
Stony Plain, Alberta
T7Z 1C6, Canada
- If you find the program useful, I ask that you do
something to brighten somebody else's day. Just
exactly what, I will leave up to you.
You may freely distribute this program provided that you distribute only
the complete archive which includes the files:
MUPURGE.EXE - Program File for DOS
MUPURGEP.EXE - Program File for OS/2
MUPURGE.CTL - Sample Control File
MUPURGE.C - 'C' Source Code
MAX_U.H - Maximus User Structures
STAMP.H - Maximus Stamp Structures
TYPEDEFS.H - Maximus Type Definitions
MUPURGE.DOC - Program Documentation
FILE_ID.DIZ - Program Description File
If you run across any bugs with this program, please report them to the
address listed above. Thanks for giving MUPURGE(P) a try.
Bob Swift (1:342/5)
Revision History
----------------
1.00 95/09/06 First release version.
1.10 95/09/09 Added log style option. Removed the code to
read / write the USER.IDX file because it seems
that Maximus rebuilds this file whenever it starts
up, so I don't have to worry about keeping it in
sync. Besides, the code would potentially cause
other problems if the .IDX file was not synchronized
with the .BBS file.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef __OS2__
#include <os2.h>
#endif
#include "max_u.h"
#define BASE 1936
void helpscrn(int ernum);
word julian (word month, word day, word year);
void gregorian (word jdate, word *month, word *day, word *year);
/*******************************************************************/
void main(int argc, char *argv[])
{
static struct _usr usr_data;
struct tm *tm_now;
time_t secs_now;
FILE *bbs_in,*bbs_out,*log_out;
char temp[256];
char temp1[256];
char temp2[256];
char temp3[256];
char *p,*p1,*p2,*p3;
word i,j,k;
sword tp,tc,td;
word today;
word t_priv[NUM_RULES];
word t_call[NUM_RULES];
word t_days[NUM_RULES];
word num_rules;
word f_first;
word f_purge;
word f_log;
word f_logmax;
secs_now = time(NULL);
tm_now = localtime(&secs_now);
i = tm_now->tm_mon+1;
j = tm_now->tm_mday;
k = tm_now->tm_year+1900;
today = julian(i,j,k);
printf("\n\n%s (v%s)\n",RDS_TITLE,RDS_VERSION);
printf("Copyright (c) Bob Swift, %s. All Rights Reserved.\n\n",RDS_DATES);
if (argc > 2) helpscrn(1);
strcpy(temp1,"MUPURGE.CTL"); /* Control File */
if (argc == 2) strcpy(temp1,strupr(argv[1])); /* Control File */
if ((bbs_in=fopen(temp1,"rt")) == NULL) helpscrn(2);
num_rules = 0;
f_first = 0;
f_purge = 0;
f_log = 0;
f_logmax = 0;
temp1[0] = '\0';
temp2[0] = '\0';
while (fgets(temp3,256,bbs_in) != NULL)
{
strcpy(temp,temp3);
/*********************************************************
* *
* The following routine is used to pull the tokens out *
* of the input string from the control file. This is *
* being used rather than the strtok() function because *
* of all the problems I had with the strtok() function *
* in the OS/2 version compiled with the Watcom C/C++ *
* compiler. *
* *
*********************************************************/
tp = 0;
p = temp;
p1 = p;
p2 = p;
p3 = p;
k = 0;
i = 0;
j = strlen(temp);
while (i < j)
{
if ((temp[i] == ' ') || (temp[i] == '\t') || (temp[i] == '\n'))
{
if (k != 0)
{
k = 0;
temp[i] = '\0';
if (tp == 1) i = j;
}
if (p == p3) p++;
if (p1 == p3) p1++;
if (p2 == p3) p2++;
if (tp == 0) p3++;
}
else
{
if (k == 0)
{
k = 1;
if (p == p3)
{p1++; p2++; p3++;}
else
{
if (p1 == p3)
{p2++; p3++;}
else
{
if (p2 == p3)
p3++;
else
tp = 1;
}
}
}
else
{
if (p == p3) p++;
if (p1 == p3) p1++;
if (p2 == p3) p2++;
if (tp == 0) p3++;
}
}
i++;
}
/************************************
* *
* End of special parsing routine. *
* *
************************************/
// p = strtok(temp," \n");
if (strcmpi(p,"CHKFIRST") == 0) f_first = 1;
if (strcmpi(p,"PURGE") == 0) f_purge = 1;
if (strcmpi(p,"LOGMAX") == 0) f_logmax = 1;
if (strcmpi(p,"LOGFILE") == 0)
{
// p1 = strtok(NULL," \n");
// if (p1 != NULL)
if ((p1[0] != '\0') && (p1[0] != ';'))
{
strcpy(temp1,p1);
f_log = 1;
}
else
{
temp1[0] = '\0';
f_log = 0;
}
}
if (strcmpi(p,"USERPATH") == 0)
{
// p1 = strtok(NULL," \n");
// if (p1 != NULL)
if ((p1[0] != '\0') && (p1[0] != ';'))
{
strcpy(temp2,p1);
}
else
{
temp2[0] = '\0';
}
}
if (strcmpi(p,"DELETE") == 0)
{
// p1 = strtok(NULL," \n");
// p2 = strtok(NULL," \n");
// p3 = strtok(NULL," \n");
if (num_rules < NUM_RULES)
{
tp = -1;
tc = -1;
td = -1;
if (p1[0] == 'a' || p1[0] == 'A') tp = atoi(p1+2);
if (p2[0] == 'a' || p2[0] == 'A') tp = atoi(p2+2);
if (p3[0] == 'a' || p3[0] == 'A') tp = atoi(p3+2);
if (p1[0] == 'c' || p1[0] == 'C') tc = atoi(p1+2);
if (p2[0] == 'c' || p2[0] == 'C') tc = atoi(p2+2);
if (p3[0] == 'c' || p3[0] == 'C') tc = atoi(p3+2);
if (p1[0] == 'd' || p1[0] == 'D') td = atoi(p1+2);
if (p2[0] == 'd' || p2[0] == 'D') td = atoi(p2+2);
if (p3[0] == 'd' || p3[0] == 'D') td = atoi(p3+2);
if ((tp > 0) && (tc >= 0) && (td > 0))
{
t_priv[num_rules] = tp;
t_call[num_rules] = tc;
t_days[num_rules] = td;
num_rules++;
}
}
}
}
fclose(bbs_in);
if (num_rules < 1) helpscrn(3);
if (f_log == 1)
{
if ((log_out=fopen(temp1,"at")) == NULL) helpscrn(7);
}
if (temp2[0] != '\0')
{
if (temp2[strlen(temp2)-1] != ':' && temp2[strlen(temp2)-1] != '\\')
strcat(temp2,"\\");
}
strcpy(temp,temp2);
strcpy(temp1,temp2);
strcat(temp,"USER.BBS");
strcat(temp1,"USER.BB$");
if ((bbs_in=fopen(temp,"rb")) == NULL) helpscrn(5);
fclose(bbs_in);
unlink(temp1);
rename(temp,temp1);
if ((bbs_in=fopen(temp1,"rb")) == NULL) helpscrn(5);
if ((bbs_out=fopen(temp,"wb")) == NULL) helpscrn(4);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp,80,"+ %d %b %H:%M:%S MUP ",tm_now);
}
else
temp[0] = '\0';
fprintf(log_out,"\n%s%s (v%s)\n",temp,RDS_TITLE,RDS_VERSION);
fprintf(log_out,"%sCopyright (c) Bob Swift, %s. All Rights Reserved.\n",temp,RDS_DATES,temp);
if (f_logmax != 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp1,80,"%Y %b %d %H:%M:%S",tm_now);
fprintf(log_out,"(Program started: %s)\n",temp1);
}
fprintf(log_out,"%s\n",temp);
}
sprintf(temp,"Purge Rules:");
puts(temp);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
}
fputs(temp,log_out);
fputs("\n",log_out);
}
sprintf(temp,"Access (<=) Calls (<=) Days (>=)");
puts(temp);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
}
fputs(temp,log_out);
fputs("\n",log_out);
}
i = 0;
while (i < num_rules)
{
if (t_call[i] == 0)
sprintf(temp,"%6u%17s%16u",t_priv[i],"n/a",t_days[i]);
else
sprintf(temp,"%6u%17u%16u",t_priv[i],t_call[i],t_days[i]);
puts(temp);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
}
fputs(temp,log_out);
fputs("\n",log_out);
}
i++;
}
puts("");
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
}
fputs("\n",log_out);
}
i = 0;
while (fread(&usr_data,sizeof(struct _usr),1,bbs_in) == 1)
{
i++;
fprintf(stderr,"Processing: %-36s\r",usr_data.name);
tp = 0;
if ((i > 1 || f_first == 1) && ((usr_data.delflag & UFLAG_PERM) != UFLAG_PERM))
{
k = today - julian(usr_data.ludate.msg_st.date.mo,usr_data.ludate.msg_st.date.da,usr_data.ludate.msg_st.date.yr+1980);
j = 0;
while (j < num_rules)
{
if (k >= t_days[j] && usr_data.priv <= t_priv[j] && (usr_data.times <= t_call[j] || t_call[j] == 0))
{
j = num_rules;
usr_data.delflag = UFLAG_DEL;
sprintf(temp,"Marking: %-25sA=%-6uC=%-6uD=%u",usr_data.name,usr_data.priv,usr_data.times,k);
if (f_purge == 1)
{
temp[0] = 'P';
temp[1] = 'u';
temp[3] = 'g';
}
puts(temp);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
}
fputs(temp,log_out);
fputs("\n",log_out);
}
}
j++;
}
}
if (((usr_data.delflag & UFLAG_DEL) != UFLAG_DEL) || ((usr_data.delflag & UFLAG_PERM) == UFLAG_PERM) || f_purge == 0)
{
if (fwrite(&usr_data,sizeof(struct _usr),1,bbs_out) != 1) helpscrn(6);
}
}
fclose(bbs_in);
fclose(bbs_out);
/* Thank the user and exit gracefully */
printf("%60s\r"," ");
sprintf(temp,"Operation complete. Thank-you for using %s.\n",RDS_TITLE);
puts("\n");
puts(temp);
if (f_log == 1)
{
if (f_logmax == 1)
{
secs_now = time(NULL);
tm_now = localtime(&secs_now);
strftime(temp3,80,"+ %d %b %H:%M:%S MUP ",tm_now);
fputs(temp3,log_out);
fputs("\n",log_out);
fputs(temp3,log_out);
}
else
fputs("\n",log_out);
fputs(temp,log_out);
fputs("\n",log_out);
}
fclose(log_out);
exit(0);
}
/*******************************************************************/
/* julian -- calculate julian date from gregorian date */
word julian (word month, word day, word year)
{
if (month > 2)
{
month -= 3;
year -= BASE;
}
else
{
month += 9;
year -= BASE + 1;
}
year = ((long) year * 1461) / 4;
month = (month * 153 + 2) / 5;
day += year + month -1;
return day;
}
/* gregorian -- calculate gregorian date from julian */
void gregorian (word jdate, word *month, word *day, word *year)
{
dword temp;
temp = (long) jdate * 4 + 3;
*year = temp / 1461;
*day = (unsigned) (temp % 1461) / 4;
*month = (*day * 5 + 2);
*day = (*month % 153) / 5 + 1;
*month /= 153;
if (*month > 9)
{
*year += BASE + 1;
*month -= 9;
}
else
{
*year += BASE;
*month += 3;
}
}
/*******************************************************************/
void helpscrn(int ernum)
/* Here are the error messages and VERY brief instructions */
{
printf("\n\n");
switch (ernum) {
case 1 : printf("Bad / Extra command line argument.\n\n");
break;
case 2 : printf("Unable to open the control file.\n\n");
break;
case 3 : printf("No purge criteria specified.\n\n");
break;
case 4 : printf("Unable to create the backup files.\n\n");
break;
case 5 : printf("Unable to read the input files.\n\n");
break;
case 6 : printf("Unable to write the output files.\n\n");
break;
case 7 : printf("Unable to write the log file.\n\n");
break;
}
printf("This program is used to read the Max 3.00 USER.BBS file in the\n");
printf("current directory and purge users based on a combination of access,\n");
printf("number of calls, and days since the last call. Purge criteria are\n");
printf("determined by the Sysop in a control file. The first record in\n");
printf("USER.BBS (usually the sysop) is ignored, as are any records marked as\n");
printf("'Permanent'. Records marked as 'Deleted' are purged.\n\n");
printf("The format for using this program is as follows:\n\n");
printf(" %s [ctlfile]\n\n",RDS_TITLE);
printf("Where [ctlfile] is the path and name of the control file (default is\n");
printf(" MUPURGE.CTL in the current directory).\n\n");
printf("Examples: %s c:\\max\\misc\\usrpurge.cfg\n",RDS_TITLE);
printf(" %s ctlfiles\\mupurge.ctl\n",RDS_TITLE);
printf(" %s\n\n",RDS_TITLE);
exit(ernum);
}
/*******************************************************************/