You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
8.4 KiB
C
339 lines
8.4 KiB
C
/*
|
|
* binkleyforce -- unix FTN mailer project
|
|
*
|
|
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
#include "includes.h"
|
|
#include "confread.h"
|
|
#include "version.h"
|
|
#include "logger.h"
|
|
#include "util.h"
|
|
#include "outbound.h"
|
|
#include "session.h"
|
|
|
|
/*
|
|
* Command line options storage structure
|
|
*/
|
|
typedef struct {
|
|
bool calls_stat;
|
|
bool sort_bysize;
|
|
bool sort_byaddr;
|
|
bool sort_reverse;
|
|
bool disable_total_sizes;
|
|
bool humansizes;
|
|
int nodeslimit;
|
|
} s_opts;
|
|
|
|
|
|
/*
|
|
* Our fake expressions checker. Allways return FALSE (?)
|
|
*/
|
|
bool eventexpr(s_expr *expr)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
static void usage(void)
|
|
{
|
|
printf_usage("outbound viewer",
|
|
"usage: bfstat [-afhprst] [-n<number>]\n"
|
|
"\n"
|
|
"options:\n"
|
|
" -a sort by FTN address (default)\n"
|
|
" -c print incoming/outgoing calls statistic\n"
|
|
" -f disable queue sorting\n"
|
|
" -h print this help message\n"
|
|
" -n <number> don't print more than <number> systems\n"
|
|
" -p print sizes in human readable format\n"
|
|
" -r reverse order while sorting\n"
|
|
" -s sort by total files size\n"
|
|
" -t disable total sizes printing\n"
|
|
"\n"
|
|
);
|
|
}
|
|
|
|
static void bfstat_opts_default(s_opts *opts)
|
|
{
|
|
memset(opts, '\0', sizeof(s_opts));
|
|
|
|
opts->sort_bysize = FALSE;
|
|
opts->sort_byaddr = TRUE;
|
|
opts->sort_reverse = FALSE;
|
|
opts->disable_total_sizes = FALSE;
|
|
opts->humansizes = FALSE;
|
|
opts->nodeslimit = 0;
|
|
}
|
|
|
|
static void bfstat_print_outbound(s_sysqueue *queue, s_opts *opts)
|
|
{
|
|
int i;
|
|
char sbuf[4][10];
|
|
char age_buffer[20];
|
|
char abuf[BF_MAXADDRSTR+1];
|
|
size_t size_netmail = 0;
|
|
size_t size_arcmail = 0;
|
|
size_t size_other = 0;
|
|
time_t now = time(0);
|
|
int printnum = opts->nodeslimit ? MIN(opts->nodeslimit, queue->sysnum)
|
|
: queue->sysnum;
|
|
|
|
printf("Address Netmail Arcmail Other Flavors Age\n");
|
|
printf("=========================================================================\n");
|
|
|
|
for( i = 0; i < printnum; i++ )
|
|
{
|
|
/* Update total size counters */
|
|
if( !opts->disable_total_sizes )
|
|
{
|
|
size_netmail += queue->systab[i].netmail_size;
|
|
size_arcmail += queue->systab[i].arcmail_size;
|
|
size_other += queue->systab[i].request_size
|
|
+ queue->systab[i].files_size;
|
|
}
|
|
|
|
/* Get mail age string */
|
|
if( queue->systab[i].mailage > 0 )
|
|
time_string_approx_interval(age_buffer,
|
|
(now - queue->systab[i].mailage));
|
|
else
|
|
*age_buffer = '\0';
|
|
|
|
if( opts->humansizes )
|
|
{
|
|
printf("%-25s %-9s %-9s %-9s %c%c%c%c%c %s\n",
|
|
ftn_addrstr(abuf, queue->systab[i].node.addr),
|
|
string_humansize(sbuf[0], queue->systab[i].netmail_size),
|
|
string_humansize(sbuf[1], queue->systab[i].arcmail_size),
|
|
string_humansize(sbuf[2], queue->systab[i].request_size + queue->systab[i].files_size),
|
|
(queue->systab[i].flavors & FLAVOR_HOLD ) ? 'H' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_NORMAL) ? 'N' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_DIRECT) ? 'D' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_CRASH ) ? 'C' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_IMMED ) ? 'I' : '.',
|
|
age_buffer);
|
|
}
|
|
else
|
|
{
|
|
printf("%-25s %-9ld %-9ld %-9ld %c%c%c%c%c %s\n",
|
|
ftn_addrstr(abuf, queue->systab[i].node.addr),
|
|
(long)(queue->systab[i].netmail_size),
|
|
(long)(queue->systab[i].arcmail_size),
|
|
(long)(queue->systab[i].request_size + queue->systab[i].files_size),
|
|
(queue->systab[i].flavors & FLAVOR_HOLD ) ? 'H' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_NORMAL) ? 'N' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_DIRECT) ? 'D' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_CRASH ) ? 'C' : '.',
|
|
(queue->systab[i].flavors & FLAVOR_IMMED ) ? 'I' : '.',
|
|
age_buffer);
|
|
}
|
|
}
|
|
|
|
if( !opts->disable_total_sizes )
|
|
{
|
|
printf("=========================================================================\n");
|
|
|
|
if( opts->humansizes )
|
|
{
|
|
printf("TOTAL %3d systems %-9s %-9s %-9s %-9s\n",
|
|
printnum,
|
|
string_humansize(sbuf[0], size_netmail),
|
|
string_humansize(sbuf[1], size_arcmail),
|
|
string_humansize(sbuf[2], size_other),
|
|
string_humansize(sbuf[3], size_netmail+size_arcmail+size_other));
|
|
}
|
|
else
|
|
{
|
|
printf("TOTAL %3d systems %-9ld %-9ld %-9ld %-9ld\n",
|
|
printnum,
|
|
(long)size_netmail, (long)size_arcmail, (long)size_other,
|
|
(long)(size_netmail + size_arcmail + size_other));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void bfstat_print_stat(s_sysqueue *queue, s_opts *opts)
|
|
{
|
|
int i;
|
|
s_sess_stat stat;
|
|
char abuf[BF_MAXADDRSTR+1];
|
|
time_t now = time(0);
|
|
int printnum = opts->nodeslimit ? MIN(opts->nodeslimit, queue->sysnum)
|
|
: queue->sysnum;
|
|
|
|
printf("Address Last incoming Last outgoing Status\n");
|
|
printf("=========================================================================\n");
|
|
|
|
for( i = 0; i < printnum; i++ )
|
|
{
|
|
if( session_stat_get(&stat, &queue->systab[i].node.addr) )
|
|
{
|
|
printf("%-25s No statistic available\n",
|
|
ftn_addrstr(abuf, queue->systab[i].node.addr));
|
|
}
|
|
else
|
|
{
|
|
char last_in[30];
|
|
char last_out[30];
|
|
char status[60];
|
|
char buffer[30];
|
|
|
|
/*
|
|
* Format date of the last successful incoming session
|
|
*/
|
|
if( stat.last_success_in > 0 )
|
|
{
|
|
time_string_format(last_in, sizeof(last_in),
|
|
"%H:%M %d/%m/%y", stat.last_success_in);
|
|
}
|
|
else
|
|
strcpy(last_in, "--------------");
|
|
|
|
/*
|
|
* Format date of the last successful outgoing session
|
|
*/
|
|
if( stat.last_success_out > 0 )
|
|
{
|
|
time_string_format(last_out, sizeof(last_out),
|
|
"%H:%M %d/%m/%y", stat.last_success_out);
|
|
}
|
|
else
|
|
strcpy(last_out, "--------------");
|
|
|
|
/*
|
|
* Generate calls status message
|
|
*/
|
|
if( stat.undialable )
|
|
{
|
|
strcpy(status, "Undialable");
|
|
}
|
|
else if( stat.hold_until > now )
|
|
{
|
|
sprintf(status, "Holded for %s",
|
|
time_string_approx_interval(buffer, stat.hold_until - now));
|
|
}
|
|
else if( stat.hold_freqs > now )
|
|
{
|
|
sprintf(status, "Holded for %s",
|
|
time_string_approx_interval(buffer, stat.hold_freqs - now));
|
|
}
|
|
else
|
|
strcpy(status, "Normal");
|
|
|
|
if( *status )
|
|
{
|
|
printf("%-25s %-15s %-15s %s\n",
|
|
ftn_addrstr(abuf, queue->systab[i].node.addr),
|
|
last_in, last_out, status);
|
|
}
|
|
else
|
|
{
|
|
printf("%-25s %-15s %-15s\n",
|
|
ftn_addrstr(abuf, queue->systab[i].node.addr),
|
|
last_in, last_out);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
s_opts opts;
|
|
s_sysqueue queue;
|
|
s_outbound_callback_data ocb;
|
|
char c;
|
|
int i;
|
|
|
|
bfstat_opts_default(&opts);
|
|
|
|
while( (c = getopt(argc, argv, "acfhn:prst")) != (char)-1 )
|
|
{
|
|
switch( c ) {
|
|
case 'h':
|
|
usage();
|
|
exit(0);
|
|
case 'c':
|
|
opts.calls_stat = TRUE;
|
|
break;
|
|
case 'f':
|
|
opts.sort_bysize = FALSE;
|
|
opts.sort_byaddr = FALSE;
|
|
opts.sort_reverse = FALSE;
|
|
break;
|
|
case 'p':
|
|
opts.humansizes = TRUE;
|
|
break;
|
|
case 't':
|
|
opts.disable_total_sizes = TRUE;
|
|
break;
|
|
case 'r':
|
|
opts.sort_reverse = TRUE;
|
|
break;
|
|
case 's':
|
|
opts.sort_byaddr = FALSE;
|
|
opts.sort_bysize = TRUE;
|
|
break;
|
|
case 'a':
|
|
opts.sort_byaddr = TRUE;
|
|
opts.sort_bysize = FALSE;
|
|
break;
|
|
case 'n':
|
|
if( ISDEC(optarg) )
|
|
opts.nodeslimit = atoi(optarg);
|
|
break;
|
|
default:
|
|
usage();
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
memset(&queue, '\0', sizeof(s_sysqueue));
|
|
|
|
/* Initialise random number generation */
|
|
(void)srand((unsigned)time(0));
|
|
/* Initialise current locale */
|
|
(void)setlocale(LC_ALL, "");
|
|
|
|
if( conf_readconf(conf_getconfname(), 0, false) )
|
|
exit(1);
|
|
|
|
memset(&ocb, '\0', sizeof(s_outbound_callback_data));
|
|
ocb.callback = out_handle_sysqueue;
|
|
ocb.dest = (void *)&queue;
|
|
out_scan(&ocb, NULL);
|
|
|
|
if( queue.sysnum > 1 && (opts.sort_byaddr || opts.sort_bysize) )
|
|
{
|
|
int sort_opts = opts.sort_byaddr ? QUEUE_SORT_ADDRESS
|
|
: opts.sort_bysize ? QUEUE_SORT_SIZE : 0;
|
|
if( opts.sort_reverse )
|
|
sort_opts |= QUEUE_SORT_REVERSE;
|
|
out_sysqueue_sort(&queue, sort_opts);
|
|
}
|
|
|
|
if( queue.sysnum > 0 )
|
|
{
|
|
if( opts.calls_stat )
|
|
bfstat_print_stat(&queue, &opts);
|
|
else
|
|
bfstat_print_outbound(&queue, &opts);
|
|
}
|
|
else
|
|
printf("Outbound queue is empty\n");
|
|
|
|
fflush(stdout);
|
|
|
|
deinit_sysqueue(&queue);
|
|
deinit_conf();
|
|
|
|
exit(0);
|
|
}
|
|
|