home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
C
/
TOPUSE4S
/
TOPUSERS.C
next >
Wrap
Text File
|
1992-01-13
|
21KB
|
781 lines
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "user.h"
#include "topusers.h"
void qsort2(void *base, unsigned nel, unsigned width,
int (*comp)(const void *, const void *));
int s_len, userfile, num_users, calls = 0;
unsigned long length, uploads = 0L, downloads = 0L, syscalls = 0L;
char configfile[80] = "topusers.cfg";
FILE *out, *cnf;
int tencalls[100], tenups[100], tendowns[100], node[99];
main(int argc, char *argv[])
{
struct _usr users[1];
int x, y, z;
if(argc == 2) strcpy(configfile, argv[1]);
printf("\n\nTOPUSER4 By Erik VanRiper (1:107/230@fidonet.org)\n\n" \
"This program is free for non-commercial use.\n");
if((cnf = fopen(configfile,"rb")) == NULL)
{
puts("Usage:");
puts(" TOPUSERS [config_file]");
puts("Example: ");
puts(" TOPUSERS");
puts(" Or: ");
puts(" TOPUSERS topusers.cfg");
exit(255);
}
defaults();
for(x = 0; x < 99; x++) node[x] = 0;
ParseConfig();
if ((userfile=open(config.userfile,O_RDONLY | O_BINARY))==-1)
{
printf("Error opening %s",config.userfile);
exit(255);
}
read(userfile,&users[0],sizeof(struct _usr));
s_len=users[0].struct_len ? users[0].struct_len*20 : 180;
length = filelength(userfile);
num_users = length / s_len;
if((out = fopen(config.outfile,"w+b")) == NULL)
{
printf("Error opening %s",config.outfile);
exit(0);
}
printf("\nTop %d of %d Users on %s\nWriting output to: %s\n",
config.topnumber,
num_users,
config.bbsname,
config.outfile);
for(x = 0; x < num_users - config.sysop; x++)
{
if((ind[x] = malloc(sizeof(IND))) == NULL)
{
printf("\nOut of memory!\n");
exit(255);
}
}
for(x = 0; x < (config.topnumber * 3); x++)
{
if((info[x] = malloc(sizeof(INFO))) == NULL)
{
printf("\nOut of memory!\n");
exit(255);
}
}
printf("Reading . . .");
z = read_user(num_users);
printf("\rSorting . . .");
qsort2(ind, z, sizeof(IND *), compare_times);
for(x = 0; x < config.topnumber; x++)
{
info[x]->user_num = ind[x]->index;
info[x]->upk = ind[x]->upk;
info[x]->downk = ind[x]->downk;
info[x]->times = ind[x]->times;
}
qsort2(ind, z, sizeof(IND *), compare_ups);
for(x = config.topnumber; x < (config.topnumber * 2); x++)
{
info[x]->user_num = ind[x - config.topnumber]->index;
info[x]->upk = ind[x - config.topnumber]->upk;
info[x]->downk = ind[x - config.topnumber]->downk;
info[x]->times = ind[x - config.topnumber]->times;
}
qsort2(ind, z, sizeof(IND *), compare_downs);
for(x = (config.topnumber * 2); x < (config.topnumber * 3); x++)
{
info[x]->user_num = ind[x - (config.topnumber * 2)]->index;
info[x]->upk = ind[x - (config.topnumber * 2)]->upk;
info[x]->downk = ind[x - (config.topnumber * 2)]->downk;
info[x]->times = ind[x - (config.topnumber * 2)]->times;
}
printf("\rReading . . .");
read_user2(config.topnumber);
close(userfile);
x = strlen(config.bbsname);
if(config.topnumber < 10) x += 16;
else if(config.topnumber < 99) x += 17;
else x += 18;
y = (80 - x) / 2;
printf("\rWriting . . .");
if(!(config.more)) fprintf(out,"");
for(z = 0; z < y; z++) fprintf(out," ");
fprintf(out,"%sTop %d Users for %s\n%s",
config.banner,
config.topnumber,
config.bbsname,
config.line);
for(z = 0; z < y; z++) fprintf(out," ");
for(y = 0;y < x;y++)
{
fprintf(out,"%c",config.shoriz ? 196 : 205);
}
if(config.shoriz)
{
if(config.svert) fprintf(out,"\n\n%s┌─┬─┬─┐\n",config.topsides);
else fprintf(out,"\n\n%s╓─╥─╥─╖\n",config.topsides);
}
else
{
if(config.svert) fprintf(out,"\n\n%s╒═╤═╤═╕\n",config.topsides);
else fprintf(out,"\n\n%s╔═╦═╦═╗\n",config.topsides);
}
fprintf(out,"%c%s TOP CALLERS CALLS %s%c%s TOP UPLOADERS KB %s%c%s TOP DOWNLOADERS KB %s%c\n",
config.svert ? 179 : 186,
config.callheader, config.topsides,
config.svert ? 179 : 186,
config.upldheader, config.topsides,
config.svert ? 179 : 186,
config.dnldheader, config.topsides,
config.svert ? 179 : 186);
if(config.shoriz)
{
if(config.svert) fprintf(out,"├─┼─┼─┤\n");
else fprintf(out,"╟─╫─╫─╢\n");
}
else
{
if(config.svert) fprintf(out,"╞═╪═╪═╡\n");
else fprintf(out,"╠═╬═╬═╣\n");
}
printf("\rSorting . . .");
printf("\rWriting . . .");
for(x = 0; x < config.topnumber; x++)
{
top_ten(0,x,x);
top_ten(1,x + config.topnumber, x);
top_ten(2,x + (config.topnumber * 2), x);
}
if((config.totals) || (config.avg) || (config.sys))
if(config.shoriz)
{
if(config.svert) fprintf(out,"%s├─┼─┼─┤\n",config.topsides);
else fprintf(out,"%s╟─╫─╫─╢\n",config.topsides);
}
else
{
if(config.svert) fprintf(out,"%s╞═╪═╪═╡\n",config.topsides);
else fprintf(out,"%s╠═╬═╬═╣\n",config.topsides);
}
if(config.totals)
fprintf(out,"%c%sTotal User Calls: %6d%s%c%sTotal Upld KB: %9ld%s%c%sTotal Dnld KB: %9ld%s%c\n",
config.svert ? 179 : 186,
config.totalcalls, calls,
config.topsides,
config.svert ? 179 : 186,
config.totaluplds, (unsigned long) uploads,
config.topsides,
config.svert ? 179 : 186,
config.totaldnlds, (unsigned long) downloads,
config.topsides,
config.svert ? 179 : 186);
if(config.avg)
{
fprintf(out,"%c%sAverage / User: %6d%s%c%sAverage / User: %9d%s%c%sAverage / User: %9d%s%c\n",
config.svert ? 179 : 186,
config.avgcalls, calls / (num_users - config.sysop),
config.topsides,
config.svert ? 179 : 186,
config.avguplds, (unsigned int) ((unsigned long) uploads / (num_users - config.sysop)),
config.topsides,
config.svert ? 179 : 186,
config.avgdnlds, (unsigned int) ((unsigned long) downloads / (num_users - config.sysop)),
config.topsides,
config.svert ? 179 : 186);
}
if(config.sys)
{
uploads = 0L;
downloads = 0L;
z = 0;
for(x = 0; x < 99; x++)
{
if(node[x])
{
z = 1;
ProcessStats(x);
}
}
if(!z) ProcessStats(0);
fprintf(out,"%c%sCalls to System: %6ld%s%c%sSystem Uploads: %9lu%s%c%sSystem Dnloads: %9lu%s%c\n",
config.svert ? 179 : 186,
config.syscalls, syscalls,
config.topsides,
config.svert ? 179 : 186,
config.sysuplds, (unsigned long) uploads,
config.topsides,
config.svert ? 179 : 186,
config.sysdnlds, (unsigned long) downloads,
config.topsides,
config.svert ? 179 : 186);
}
else printf("\nSystem stats not processed!\n");
if(config.shoriz)
{
if(config.svert) fprintf(out,"└─┴─┴─┘\n");
else fprintf(out,"╙─╨─╨─╜\n");
}
else
{
if(config.svert) fprintf(out,"╘═╧═╧═╛\n");
else fprintf(out,"╚═╩═╩═╝\n");
}
fprintf(out,"\n%c",config.more ? 32 : 5);
fclose(out);
for(x = 0; x < num_users - config.sysop; x++)
free(ind[x]);
for(x = 0; x < config.topnumber * 3; x++)
free(info[x]);
printf("\rDone! \n");
return(1);
}
top_ten(int e, int x, int y)
{
if(x == -1) return(-1);
if(e == 0)
{
fprintf(out,"%s%c%s",
config.topsides,
config.svert ? 179 : 186,
((y == 0) ||
(y == config.topnumber) ||
(y == config.topnumber * 2)) ?
config.topcall : config.rest);
if(info[x]->times == 0)
fprintf(out,"%s ----- Vacant! ----- ",config.vacant);
else
fprintf(out,"%-19.19s %5d",info[x]->name,info[x]->times);
}
if(e == 1)
{
fprintf(out,"%s%c%s",
config.topsides,
config.svert ? 179 : 186,
((y == 0) ||
(y == config.topnumber) ||
(y == config.topnumber * 2)) ?
config.topupld : config.rest);
if(info[x]->upk == 0)
fprintf(out,"%s ----- Vacant! ----- ",config.vacant);
else
fprintf(out,"%-18.18s %6lu",info[x]->name,info[x]->upk);
}
if(e == 2)
{
fprintf(out,"%s%c%s",
config.topsides,
config.svert ? 179 : 186,
((y == 0) ||
(y == config.topnumber) ||
(y == config.topnumber * 2)) ?
config.topdnld : config.rest);
if(info[x]->downk == 0)
fprintf(out,"%s ----- Vacant! ----- ",config.vacant);
else
fprintf(out,"%-18.18s %6lu",info[x]->name,info[x]->downk);
fprintf(out,"%s%c\n",config.topsides,config.svert ? 179 : 186);
if(y == 0)
if(config.shoriz)
{
if(config.svert) fprintf(out,"├─┼─┼─┤\n");
else fprintf(out,"╟─╫─╫─╢\n");
}
else
{
if(config.svert) fprintf(out,"╞═╪═╪═╡\n");
else fprintf(out,"╠═╬═╬═╣\n");
}
}
return(1);
}
read_user(int p)
{
struct _usr users[1];
int x, y = 0;
for (x = (0 + config.sysop);x < p;x++)
{
lseek(userfile,(long)x*(long)s_len,SEEK_SET);
read(userfile,&users[0],sizeof(struct _usr));
uploads += (unsigned long) users[0].up;
downloads += (unsigned long) users[0].down;
calls += (unsigned long) users[0].times;
if(!(users[0].bits & BITS_NOULIST)) /* If "paranoia" flag not set */
{
ind[y]->times = users[0].times;
ind[y]->downk = users[0].down;
ind[y]->upk = users[0].up;
ind[y]->index = x;
y++;
}
}
return(y);
}
read_user2(int p)
{
struct _usr users[1];
int x, y;
for (x = 0; x < p; x++)
{
lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
read(userfile,&users[0],sizeof(struct _usr));
strncpy(info[x]->name,users[0].name,19);
y = strlen(users[0].name);
if(y > 19) info[x]->name[20] = '\0';
else info[x]->name[y] = '\0';
}
for (x = p; x < (p * 2); x++)
{
lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
read(userfile,&users[0],sizeof(struct _usr));
strncpy(info[x]->name,users[0].name,19);
y = strlen(users[0].name);
if(y > 19) info[x]->name[20] = '\0';
else info[x]->name[y] = '\0';
}
for (x = (p * 2); x < (p * 3); x++)
{
lseek(userfile,(long)info[x]->user_num*(long)s_len,SEEK_SET);
read(userfile,&users[0],sizeof(struct _usr));
strncpy(info[x]->name,users[0].name,19);
y = strlen(users[0].name);
if(y > 19) info[x]->name[20] = '\0';
else info[x]->name[y] = '\0';
}
return(1);
}
int compare_times(const void *a, const void *b)
{
IND *ai = *((IND **)a);
IND *bi = *((IND **)b);
if(ai->times == bi->times) return(0);
return((ai->times < bi->times) ? 1 : -1);
}
int compare_downs(const void *a, const void *b)
{
IND *ai = *((IND **)a);
IND *bi = *((IND **)b);
if(ai->downk == bi->downk) return(0);
return((ai->downk < bi->downk) ? 1 : -1);
}
int compare_ups(const void *a, const void *b)
{
IND *ai = *((IND **)a);
IND *bi = *((IND **)b);
if(ai->upk == bi->upk) return(0);
return((ai->upk < bi->upk) ? 1 : -1);
}
ParseConfigLine(char *line)
{
char *delim = " \t\n\r";
char *s;
int x, t;
/*
** Strip off any comments
*/
if((s = strchr(line, ';')) != NULL) *s='\0';
/*
** Grab a word from the config
*/
s=strtok(line, delim);
if(s==NULL) return(2);
t = strlen(s);
if((t == 1) || (t == 2))
{
node[atoi(s)] = 1;
return(1);
}
for(x = 0; x < (sizeof((char *)parse) / 2); x++)
{
if(eqstri(s, parse[x]))
{
switch(x)
{
case 0:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.bbsname,s);
break;
case 1:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.userfile,s);
break;
case 2:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.outfile,s);
break;
case 3:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
config.topnumber = atoi(s);
if(atoi(s) > 100) config.topnumber = 10;
if(atoi(s) < 2) config.topnumber = 10;
break;
case 4:
config.sysop = 0; /* 0 == TRUE! */
break;
case 5:
config.dhoriz = 1;
config.shoriz = 0;
break;
case 6:
config.dvert = 1;
config.svert = 0;
break;
case 7:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.topsides,s);
break;
case 8:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.callheader,s);
break;
case 9:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.upldheader,s);
break;
case 10:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.dnldheader,s);
break;
case 11:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.topcall,s);
break;
case 12:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.topupld,s);
break;
case 13:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.topdnld,s);
break;
case 14:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.rest,s);
break;
case 15:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.totalcalls,s);
break;
case 16:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.totaluplds,s);
break;
case 17:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.totaldnlds,s);
break;
case 18:
config.cls = 1;
break;
case 19:
config.more = 0;
break;
case 20:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.vacant,s);
break;
case 21:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.banner,s);
break;
case 22:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.line,s);
break;
case 23:
config.avg = 0;
break;
case 24:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.avgcalls,s);
break;
case 25:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.avguplds,s);
break;
case 26:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.avgdnlds,s);
break;
case 27:
config.sys = 0;
break;
case 28:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.syscalls,s);
break;
case 29:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.sysdnlds,s);
break;
case 30:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.sysuplds,s);
break;
case 31:
s = strtok(NULL,"\r\n");
if(s==NULL) return(0);
strcpy(config.maxdir,s);
if(config.maxdir[(strlen(config.maxdir) - 1)] != 92)
{
config.maxdir[strlen(config.maxdir)] = 92;
config.maxdir[strlen(config.maxdir)] = '\0';
}
break;
case 32:
config.totals = 0;
break;
default: break;
}
}
}
if(x > (sizeof((char *)parse) / 2)) return(0);
return(1);
}
int ParseConfig()
{
static char line[81];
char temp[81];
char *delim = " \t\n\r";
char *s;
int t = 0, j = 0;
while(fgets(line, 80, cnf))
{
j++;
strcpy(temp,line);
if((s = strchr(temp, ';')) != NULL) *s='\0';
s=strtok(temp, delim);
if(s==NULL) continue;
t = ParseConfigLine(line);
if(!t)
{
printf("\nError in Config file. You most likely have more than one space between" \
"\narguments. Or, you have an option specified with no argument following." \
"\nPlease re-edit line %d in %s.\n",j,configfile);
fclose(cnf);
exit(254);
}
}
fclose(cnf);
return(1);
}
/* From: Ray Gardner */
/* qsort2() -- Shell sort Raymond Gardner public domain 11/91
**
** A version of qsort that uses Shell's sort algorithm.
*/
void qsort2(void *base, unsigned nel, unsigned width,
int (*comp)(const void *, const void *))
{
unsigned int wnel, gap, wgap, i, j, k;
char *a, *b, tmp;
wnel = width * nel;
for(gap = 0; ++gap < nel;)
gap *= 3;
while ( gap /= 3 )
{
wgap = width * gap;
for ( i = wgap; i < wnel; i += width )
{
for ( j = i - wgap; ;j -= wgap )
{
a = j + (char *)base;
b = a + wgap;
if((*comp)(a, b) <= 0)
break;
k = width;
do
{
tmp = *a;
*a++ = *b;
*b++ = tmp;
} while ( --k );
if(j < wgap)
break;
}
}
}
}
ProcessStats(int y)
{
char file[13];
sprintf(file,"BBSTAT%-2.2d.BBS",y);
PrintStats(file);
return(1);
}
PrintStats(char *filename)
{
int file;
STATS *stats;
char maxpath[80];
sprintf(maxpath,"%s%s",config.maxdir,filename);
if((file=open(maxpath,O_RDONLY | O_BINARY))==-1)
{
return(0);
}
if((stats = malloc(sizeof(STATS))) == NULL)
{
exit(255);
}
read(file,stats,sizeof(STATS));
syscalls += (dword) stats->num_callers;
uploads += (dword) stats->total_ul;
downloads += (dword) stats->total_dl;
close(file);
free(stats);
return(1);
}