#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include "fe_ncurses.h"
#include "ncgui.h"
#include "config.h"
#include "pfqhelp.h"
#include "pfqmessage.h"
#include "pfregex.h"
#include "pfqconfig.h"
#include "pfqlib.h"
#define CAT_BUF_SIZE 20*1024
#define BUF_SIZE 250
char *a_names[]={
"hold",
"delete",
"release",
"requeue"
};
char *s_names[]={
"unsorted",
"sorted by from",
"sorted by to",
"sorted by subject"
};
int page_step;
int MSGMARK;
char* cat_buf;
char* regexps;
struct pfql_context_t *pfql_ctx;
struct msg_list_t *msg_list; /* Array of CURRENTLY SHOWN msg ids */
int msg_num; /* Number of messages in the queue */
time_t last_repaint;
int half_delay_time;
int show_body_win;
int show_body_always;
int show_body_fromline;
int wnd_confirm ( const char *action ) {
int c, ret;
WINDOW *w = newwin ( 5, 50, (LINES-5)/2, (COLS-50)/2 );
wnd_border ( w );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wbkgd ( w, COLOR_PAIR(CP_DIALOG) );
nocbreak();
cbreak();
if ( pfql_getstatus(pfql_ctx)->wrk_tagged || (pfql_getstatus(pfql_ctx)->auto_wrk_tagged && pfql_num_tag(pfql_ctx)) )
mvwprintw ( w, 2, 2, "Do you really want to %s tagged messages?", action );
else
mvwprintw ( w, 2, 2, "Do you really want to %s this message?", action );
wrefresh ( w );
c = wgetch ( w );
ret = ( c=='y' || c=='Y' ? 1 : 0 );
delwin ( w );
halfdelay ( half_delay_time*10 );
return ret;
}
int wnd_change_sort_field () {
int c, ret;
WINDOW *w = newwin ( 8, 50, (LINES-8)/2, (COLS-50)/2 );
wnd_border ( w );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wbkgd ( w, COLOR_PAIR(CP_DIALOG) );
nocbreak();
cbreak();
mvwprintw ( w, 1, 2, "Choose sort field:" );
mvwprintw ( w, 3, 2, "0: unsorted" );
mvwprintw ( w, 4, 2, "1: from (4 descendent)" );
mvwprintw ( w, 5, 2, "2: to (5 descendent)" );
mvwprintw ( w, 6, 2, "3: subject (6 descendent)" );
wrefresh ( w );
c = wgetch ( w );
if ( c>='0' && c<='6' )
ret = c-'0';
else
ret = -1;
delwin ( w );
halfdelay ( half_delay_time*10 );
return ret;
}
void wnd_getregexp () {
char *tmp;
WINDOW *w = newwin ( 5, 60, (LINES-5)/2, (COLS-60)/2 );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wbkgd ( w, COLOR_PAIR(CP_DIALOG) );
wnd_border ( w );
echo();
nocbreak();
cbreak();
mvwaddstr ( w, 1, 2, "Insert POSIX regular expression to search for:" );
wrefresh ( w );
wnd_prompt ( w, 3, 2, regexps, REGEXP_LEN );
delwin ( w );
halfdelay ( half_delay_time*10 );
noecho();
pfql_ctx->search_mode = SM_ALL;
if ( !strncmp( regexps, "f:", 2 ) )
pfql_ctx->search_mode = SM_FROM;
if ( !strncmp( regexps, "t:", 2 ) )
pfql_ctx->search_mode = SM_TO;
if ( !strncmp( regexps, "e:", 2 ) )
pfql_ctx->search_mode = SM_TO | SM_FROM;
if ( !strncmp( regexps, "s:", 2 ) )
pfql_ctx->search_mode = SM_SUBJ;
if ( pfql_ctx->search_mode != ( SM_ALL ) ) {
tmp = (char*) malloc ( REGEXP_LEN );
strncpy ( tmp, regexps+2, REGEXP_LEN );
strncpy ( regexps, tmp, REGEXP_LEN );
free ( tmp );
}
return;
}
void version() {
printf ( "pfqueue - Version %s - (C) 2004-2007 Stefano Rivoir\n",
VERSION );
}
void usage() {
version();
printf ( "Usage: pfqueue [-ehvn] [-b postfix1|postfix2|exim] [-q queue_num] [-m max_msg]\n"
" [-s autorefresh_seconds] [-l limit_seconds] -[B backends_path]\n"
" [-p executables_path] [-c config_path]\n" );
}
void help() {
WINDOW *w;
char *ht;
int c;
char *help_be;
help_be = (char*)(malloc ( 1024 ) );
sprintf ( help_be,
" pfqueue lib version: %s\n"
" Backend API version: %d\n\n"
" Backend ID: %s\n"
" Backend version: %s",
pfql_version(), pfql_backend_apiversion(pfql_ctx), pfql_backend_id(pfql_ctx), pfql_backend_version(pfql_ctx) );
w = newwin ( 25, 60, (LINES-26)/2,(COLS-60)/2 );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wbkgd ( w, COLOR_PAIR(CP_DIALOG) );
nocbreak();
cbreak();
ht = help_text1;
c = 0;
while ( c!='q' && c!='Q' ) {
wclear ( w );
mvwprintw ( w, 1, 0, ht );
wnd_border ( w );
wattron ( w, A_BOLD );
mvwaddstr ( w, 0, 28, "Help" );
mvwaddstr ( w, 0, 2, "pfqueue ver. " );
mvwaddstr ( w, 0, 15, VERSION );
mvwaddstr ( w, 23, 2, "Press q to exit help, any key for next page" );
wattroff ( w, A_BOLD );
wrefresh ( w );
c = wgetch ( w );
if ( ht==help_text1 )
ht = help_text2;
else if ( ht == help_text2 )
ht = help_be;
else
ht = help_text1;
}
delwin ( w );
free ( help_be );
halfdelay ( half_delay_time*10 );
}
int goto_msg(int i) {
int j;
if ( i<0 || i>=msg_num )
return 0;
PREVROW = CURROW;
PREVMSG = CURMSG;
CURMSG = i;
CURROW = (i-FIRSTMSG)+FIRSTROW;
show_body_fromline = 0;
if ( CURROW<FIRSTROW ) {
CURROW = FIRSTROW;
FIRSTMSG = CURMSG;
return 1;
}
if ( CURROW>MAXROW ) {
j = CURROW-MAXROW;
FIRSTMSG += j;
CURROW = MAXROW;
return 1;
}
return 0;
}
int goto_next() {
return goto_msg( CURMSG+1 );
}
int goto_prev() {
return goto_msg( CURMSG-1 );
}
int goto_first() {
return goto_msg(0);
}
int goto_last() {
if ( msg_num )
return goto_msg( msg_num-1 );
return 0;
}
int goto_nextpage() {
if ( CURMSG+page_step < msg_num-1 )
return goto_msg ( CURMSG+page_step );
else
return goto_msg ( msg_num-1 );
}
int goto_prevpage() {
if ( CURMSG > page_step )
return goto_msg ( CURMSG-page_step );
else
return goto_msg ( 0 );
}
void win_header() {
wattron ( hwnd, A_BOLD );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wattron ( hwnd, COLOR_PAIR(CP_HEAD) );
mvwprintw ( hwnd, 0, 1, "Queue: '%s', %d message%s, %d tagged, %s",
pfql_queue_name(pfql_ctx,pfql_getstatus(pfql_ctx)->cur_queue), msg_num,
( msg_num != 1 ? "s" : "" ),
pfql_num_tag(pfql_ctx),
s_names[pfql_getstatus(pfql_ctx)->sort_field]);
wclrtoeol ( hwnd );
wattroff ( hwnd, A_REVERSE );
if ( pfql_getstatus(pfql_ctx)->auto_wrk_tagged )
wattron ( hwnd, A_REVERSE );
mvwaddstr ( hwnd, 0, COLS-7, "A" );
wattroff ( hwnd, A_REVERSE );
if ( pfql_getstatus(pfql_ctx)->wrk_tagged )
wattron ( hwnd, A_REVERSE );
mvwaddstr ( hwnd, 0, COLS-6, "T" );
wattroff ( hwnd, A_REVERSE );
if ( pfql_getstatus(pfql_ctx)->ask_confirm )
wattron ( hwnd, A_REVERSE );
mvwaddstr ( hwnd, 0, COLS-5, "C" );
wattroff ( hwnd, A_REVERSE );
if ( pfql_getstatus(pfql_ctx)->do_scan )
wattron ( hwnd, A_REVERSE );
mvwaddstr ( hwnd, 0, COLS-4, "S" );
wattroff ( hwnd, A_REVERSE );
if ( show_body_always )
wattron ( hwnd, A_REVERSE );
mvwaddstr ( hwnd, 0, COLS-3, "B" );
wattroff ( hwnd, A_REVERSE );
wattron ( hwnd, A_BOLD );
mvwaddstr ( hwnd, 1, 1, "ID" );
mvwaddstr ( hwnd, 1, COL1, "From" );
mvwaddstr ( hwnd, 1, COL2, "To" );
wattroff ( hwnd, A_BOLD );
wattroff ( hwnd, COLOR_PAIR(CP_HEAD) );
wnoutrefresh ( hwnd );
}
// Sizes the window according to the (new) screen size
void win_resize () {
int mwnd_tot;
int bwnd_tot;
int lwnd_tot;
bwnd_tot = bwnd_height + 2;
if ( mwnd )
delwin ( mwnd );
if ( mwndb )
delwin ( mwndb );
if ( bwnd )
delwin ( bwnd );
if ( bwndb )
delwin ( bwndb );
if ( lwnd )
delwin ( lwnd );
if ( hwnd )
delwin ( hwnd );
if ( bline )
free ( bline );
if ( msg_list )
free ( msg_list );
last_repaint = 0;
mainwnd = initscr();
FIRSTROW = 0;
if ( !has_colors() || start_color()==ERR )
pfql_getstatus(pfql_ctx)->use_colors = 0;
bline = (char*)malloc(sizeof(char)*COLS+1);
memset ( bline, ' ', sizeof(char)*COLS+1 );
*(bline+COLS) = 0;
msg_list = (struct msg_list_t*)malloc(sizeof(struct msg_list_t)*(LINES));
mwnd_tot = 7;
lwnd_tot = LINES-mwnd_tot-2;
if ( show_body_win )
lwnd_tot -= bwnd_height;
MAXROW = LINES-(mwnd_tot)-1-2;
if ( show_body_win )
MAXROW -= bwnd_height;
hwnd = newwin ( 2, COLS, 0, 0 );
lwnd = newwin ( lwnd_tot, COLS, 2, 0 );
mwndb = newwin ( mwnd_tot, COLS, lwnd_tot+2, 0 );
mwnd = newwin ( mwnd_tot-2, COLS-2, lwnd_tot+3, 1 );
if ( show_body_win ) {
bwndb = newwin ( bwnd_height, COLS, lwnd_tot+2+mwnd_tot, 0 );
bwnd = newwin ( bwnd_height-2, COLS-2, lwnd_tot+2+mwnd_tot+1, 1 );
}
if ( pfql_getstatus(pfql_ctx)->use_colors ) {
init_pair ( CP_MSG, COLOR_WHITE, COLOR_MAGENTA );
init_pair ( CP_HEAD,COLOR_WHITE, COLOR_BLUE );
init_pair ( CP_TAG, COLOR_YELLOW, COLOR_BLACK );
init_pair ( CP_DIALOG, COLOR_WHITE, COLOR_RED );
init_pair ( CP_OPTDIS, COLOR_RED, COLOR_BLUE );
wbkgd ( mwndb, COLOR_PAIR(CP_HEAD) );
if ( show_body_win )
wbkgd ( bwndb, COLOR_PAIR(CP_HEAD) );
wbkgd ( hwnd, COLOR_PAIR(CP_HEAD) );
}
if ( pfql_getstatus(pfql_ctx)->use_envelope )
wnd_clear ( mwndb, "Message (from envelope)" );
else
wnd_clear ( mwndb, "Message (from headers)" );
if ( show_body_win )
wnd_clear ( bwndb, "Message body" );
COL1 = 20;
COL2 = COL1+( COLS - COL1 ) / 2-2;
noecho();
halfdelay(half_delay_time*10);
wnoutrefresh ( mwndb );
if ( show_body_win )
wnoutrefresh ( bwndb );
page_step = MAXROW ;
doupdate();
}
// Displays the bottom window
void msg_show_headers () {
struct msg_t *msg;
if ( !msg_num ) {
wclear ( mwnd );
mvwaddstr ( mwnd, 0, 0, "Queue is empty" );
return;
}
msg = pfql_msg( pfql_ctx, msg_list[CURROW].id );
if ( !msg )
return;
pfql_retr_status ( pfql_ctx, msg->id );
pfql_retr_headers( pfql_ctx, msg->id );
mvwaddstr ( mwnd, 0, 0, "Message:" );
wclrtobot ( mwnd );
mvwaddstr ( mwnd, 0, 9, msg->id );
mvwaddstr ( mwnd, 1, 0, "From..:" );
mvwaddstr ( mwnd, 1, 8, msg->from );
mvwaddstr ( mwnd, 2, 0, "To....:" );
mvwaddstr ( mwnd, 2, 8, msg->to );
mvwaddstr ( mwnd, 3, 0, "Subj..:" );
mvwaddstr ( mwnd, 3, 8, msg->subj );
mvwaddstr ( mwnd, 4, 0, "Status:" );
mvwaddstr ( mwnd, 5, 0, " " );
mvwaddstr ( mwnd, 4, 8, msg->stat );
if ( show_body_always && show_body_win )
msg_show_body(0);
}
// Returns the message displayed at row r
int msg_at(int r) {
return (FIRSTMSG+r-FIRSTROW);
}
// Clears the cursor in the previous position and displays the current one
void show_cursor() {
char *buf;
int i;
struct msg_t *msg;
buf = (char*)malloc(BUF_SIZE);
// Current row
i = msg_at(CURROW);
mvwinnstr ( lwnd, CURROW, 0, buf, COLS );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wattron ( lwnd, COLOR_PAIR(CP_MSG) );
else
wattron ( lwnd, A_REVERSE );
msg = pfql_msg_at(pfql_ctx,i);
if ( msg && msg->tagged )
wattron ( lwnd, A_BOLD );
mvwaddstr ( lwnd, CURROW, 0, buf );
wattroff ( lwnd, COLOR_PAIR(CP_MSG) );
wattroff ( lwnd, A_BOLD );
wattroff ( lwnd, A_REVERSE );
// Previous row
if ( PREVROW!=CURROW ) {
i = msg_at(PREVROW);
mvwinnstr ( lwnd, PREVROW, 0, buf, COLS );
msg = pfql_msg_at(pfql_ctx,i);
if ( msg ) {
if ( msg->tagged )
wattron ( lwnd, A_BOLD );
if ( msg->tagged && pfql_getstatus(pfql_ctx)->use_colors )
wattron ( lwnd, COLOR_PAIR(CP_TAG) );
}
mvwaddstr ( lwnd, PREVROW, 0, buf );
}
free ( buf );
wattroff ( lwnd, COLOR_PAIR(CP_MSG) );
wattroff ( lwnd, COLOR_PAIR(CP_TAG) );
wattroff ( lwnd, A_BOLD );
wattroff ( lwnd, A_REVERSE );
wrefresh ( hwnd );
wmove ( lwnd, CURROW, 0 );
PREVROW = CURROW;
msg_show_headers();
wrefresh ( mwnd );
}
void msg_cat_body( WINDOW *pw, WINDOW* bw, int wl, int wc, int ctrls ) {
char lines[MSG_MAX_ROWS][MSG_MAX_COLS];
int j, i;
int c;
int fline;
int pgstep;
int msglines;
int ptr;
int buflen;
int maxcol;
maxcol = wc-2;
memset ( lines, 0, sizeof(lines) );
buflen = pfql_retr_body ( pfql_ctx, msg_list[CURROW].id, cat_buf, CAT_BUF_SIZE );
if ( buflen == PFQL_MSGNOTEX )
return;
msglines = 0;
ptr = 0;
// Copy cat_buf into splitted lines
while ( ptr<buflen && msglines < MSG_MAX_ROWS ) {
c = 0;
while ( c < maxcol && *(cat_buf+ptr)!='\n' ) {
lines[msglines][c] = *(cat_buf+ptr);
ptr++;
c++;
}
while ( *(cat_buf+ptr)!='\n' )
ptr++;
ptr++;
msglines++;
}
keypad ( pw, TRUE );
pgstep = wl;
if ( bw ) {
wattron ( bw, A_BOLD );
mvwaddstr ( bw, 0, 2, "Body of" );
mvwaddstr ( bw, 0, 10, pfql_msg_at(pfql_ctx,CURMSG)->path );
wattroff ( bw, A_BOLD );
wrefresh ( bw );
}
c = 0;
if ( ctrls )
fline = 0;
else
fline = show_body_fromline;
while ( c!='q' && c!='Q' ) {
j = fline;
i = 0;
while ( j<MSG_MAX_ROWS && i < wl ) {
mvwaddnstr ( pw, i++, 2, lines[j++], maxcol );
wclrtoeol ( pw );
}
wrefresh ( pw );
no_fill:
if ( ctrls )
c = wgetch (pw);
else
c = 'q';
switch (c) {
case 'g':
case KEY_HOME:
fline = 0;
break;
case 'G':
case KEY_END:
fline = msglines-pgstep;
break;
case KEY_PPAGE:
if ( fline > pgstep )
fline -= pgstep;
else
fline = 0;
break;
case KEY_NPAGE:
if ( fline < (msglines-pgstep) )
fline += pgstep;
break;
case KEY_UP:
if ( fline )
fline--;
break;
case ' ':
case KEY_DOWN:
if ( fline<msglines-pgstep )
fline++;
break;
case 'q':
case 'Q':
break;
default:
goto no_fill;
break;
}
}
halfdelay ( half_delay_time*10 );
}
void msg_show_body(int force_own) {
WINDOW *w1, *w2;
if ( show_body_win && !force_own )
msg_cat_body ( bwnd, bwndb, bwnd_height-2, COLS-2, 0 );
else {
w1 = newwin ( LINES-4, COLS-4, 2, 2 );
w2 = newwin ( LINES-6, COLS-6, 3, 3 );
wnd_border ( w1 );
wrefresh ( w1 );
msg_cat_body ( w2, w1, LINES-6, COLS-6, 1 );
delwin ( w2 );
delwin ( w1 );
}
}
// Returns 1 if queue needs repaint
int queue_needs_repaint () {
return ( pfql_queue_last_changed(pfql_ctx) >= last_repaint );
}
// Set repaint flag
void queue_force_repaint(int f) {
if ( f )
last_repaint = 0;
else
last_repaint = pfql_queue_last_changed(pfql_ctx);
}
// Displays the list of messages
void queue_show() {
int i, j;
//time_t show_start;
struct msg_t *msg;
j = FIRSTROW;
i = FIRSTMSG;
msg_num = pfql_num_msg(pfql_ctx);
last_repaint = time(NULL);
if ( pfql_getstatus(pfql_ctx)->sort_field!=PFQL_SORT_UNSORTED )
while ( pfql_ctx->pfql_status.queue_status!=PFQL_Q_IDLE ) { usleep(5000); }
while ( j <= MAXROW ) {
if ( i<msg_num ) {
msg = pfql_msg_at(pfql_ctx,i);
if ( !msg )
return;
strcpy ( msg_list[j].id, msg->id );
pfql_retr_headers ( pfql_ctx,msg->id );
if ( msg->tagged ) {
wattron ( lwnd, A_BOLD );
if ( pfql_getstatus(pfql_ctx)->use_colors )
wattron ( lwnd, COLOR_PAIR(CP_TAG) );
}
mvwaddnstr ( lwnd, j, 0, bline, COLS );
mvwaddnstr ( lwnd, j, 1, msg->id, sizeof(msg->id) );
mvwaddnstr ( lwnd, j, COL1, msg->from, COL2-2-COL1 );
mvwaddstr ( lwnd, j, COL2-2, " " );
mvwaddnstr ( lwnd, j, COL2, msg->to, COLS-2-COL2 );
wattroff ( lwnd, A_BOLD );
wattroff ( lwnd, COLOR_PAIR(CP_TAG) );
} else {
mvwaddstr ( lwnd, j, 1, " " );
wclrtobot ( lwnd );
j = MAXROW+1; // Force loop exit
}
j++;
i++;
}
if ( msg_num && CURMSG > (msg_num-1) )
goto_last();
keypad ( lwnd, 1 );
win_header();
show_cursor();
wnoutrefresh ( mwnd );
wnoutrefresh ( lwnd );
doupdate();
wrefresh ( lwnd );
}
// Init frontend
int fe_init() {
cat_buf = 0;
bwnd_height = 10;
cat_buf = (char*)malloc(CAT_BUF_SIZE);
if ( !cat_buf )
return 0;
regexps = 0;
regexps = (char*)malloc(REGEXP_LEN);
if ( !regexps )
return 0;
mainwnd = mwndb = lwnd = mwnd = hwnd = bwnd = bwndb = NULL;
bline = 0;
msg_list = 0;
return 1;
}
void fe_close() {
if ( cat_buf )
free ( cat_buf );
if ( msg_list )
free ( msg_list );
if ( bline )
free ( bline );
if ( regexps )
free ( regexps );
}
void queue_change(int q) {
int r;
r = pfql_set_queue(pfql_ctx,q);
if ( r==PFQL_OK ) {
CURMSG = 0;
goto_first();
win_header();
}
}
void msg_action(const char* id, int act) {
if ( !msg_num )
return;
if ( (pfql_getstatus(pfql_ctx)->ask_confirm && wnd_confirm(a_names[act])) ||
(!pfql_getstatus(pfql_ctx)->ask_confirm) )
pfql_msg_action(pfql_ctx, id, act);
queue_force_repaint(1);
}
void main_loop() {
int c, r;
int i;
c = 0;
CURMSG = 0;
MSGMARK = -1;
FIRSTMSG = 0;
while ( c != 'q' && c != 'Q' ) {
if ( queue_needs_repaint() )
queue_show();
else
show_cursor();
c = wgetch ( lwnd );
switch ( c ) {
case 'G':
case KEY_END:
queue_force_repaint ( goto_last() );
break;
case 'g':
case KEY_HOME:
queue_force_repaint ( goto_first() );
break;
case KEY_UP:
queue_force_repaint ( goto_prev() );
break;
case KEY_DOWN:
queue_force_repaint ( goto_next() );
break;
case KEY_PPAGE:
queue_force_repaint ( goto_prevpage() );
break;
case KEY_NPAGE:
queue_force_repaint ( goto_nextpage() );
break;
case KEY_RESIZE:
win_resize();
break;
case 'e':
pfql_toggle_envelope(pfql_ctx);
queue_force_repaint ( 1 );
break;
case 'd':
case KEY_DC:
msg_action( msg_list[CURROW].id, MSG_DELETE );
break;
case 'h':
msg_action( msg_list[CURROW].id, MSG_HOLD );
break;
case 'l':
msg_action ( msg_list[CURROW].id, MSG_RELEASE );
break;
case 'r':
msg_action ( msg_list[CURROW].id, MSG_REQUEUE );
break;
case '1':
queue_change ( Q_DEFERRED );
break;
case '4':
queue_change ( Q_HOLD );
break;
case '3':
queue_change ( Q_INCOMING );
break;
case '2':
queue_change ( Q_ACTIVE );
break;
case '5':
queue_change ( Q_CORRUPT );
break;
case 'a':
pfql_tag_all(pfql_ctx);
queue_force_repaint ( 1 );
win_header();
break;
case 'm':
MSGMARK = CURMSG;
pfql_msg_tag( pfql_ctx, msg_list[CURROW].id);
break;
case 'b':
show_body_win = !show_body_win;
win_resize();
if ( show_body_win )
msg_show_body(0);
break;
case 'B':
show_body_always = !show_body_always;
win_header();
break;
case 32:
case 't':
if ( !msg_num )
break;
if ( MSGMARK==-1 ) {
pfql_msg_toggletag( pfql_ctx,msg_list[CURROW].id );
} else {
if ( CURMSG>=MSGMARK ) {
for ( i=MSGMARK; i<=CURMSG; i++ )
pfql_msg_tag(pfql_ctx,pfql_msg_at(pfql_ctx,i)->id);
} else {
for ( i=CURMSG; i<=MSGMARK; i++ )
pfql_msg_tag(pfql_ctx,pfql_msg_at(pfql_ctx,i)->id);
}
}
MSGMARK = -1;
goto_next();
queue_force_repaint ( 1 );
show_cursor();
win_header();
break;
case 'T':
wnd_getregexp();
pfql_msg_searchandtag(pfql_ctx,regexps);
queue_force_repaint ( 1 );
win_header();
break;
case 'u':
pfql_tag_none(pfql_ctx);
win_header();
queue_force_repaint ( 1 );
break;
case ':':
pfql_getstatus(pfql_ctx)->auto_wrk_tagged = !pfql_getstatus(pfql_ctx)->auto_wrk_tagged;
win_header();
break;
case ';':
pfql_getstatus(pfql_ctx)->wrk_tagged = !pfql_getstatus(pfql_ctx)->wrk_tagged;
win_header();
break;
case '/':
wnd_getregexp();
i = pfql_msg_search(pfql_ctx,regexps);
goto_msg ( i );
queue_force_repaint ( 1 );
break;
case 'n':
i = pfql_msg_searchnext(pfql_ctx,regexps);
goto_msg ( i );
break;
case 'p':
pfql_msg_searchprev(pfql_ctx,regexps);
break;
case '?':
help();
queue_force_repaint ( 1 );
break;
case 'c':
pfql_getstatus(pfql_ctx)->ask_confirm = !pfql_getstatus(pfql_ctx)->ask_confirm;
win_header();
break;
case '-':
pfql_getstatus(pfql_ctx)->do_scan = !pfql_getstatus(pfql_ctx)->do_scan;
win_header();
break;
case '+':
pfql_getstatus(pfql_ctx)->use_colors = !pfql_getstatus(pfql_ctx)->use_colors;
queue_force_repaint ( 1 );
win_resize();
win_header();
break;
case '>':
if ( bwnd_height<LINES-10 )
bwnd_height++;
win_resize();
win_header();
break;
case '<':
if ( bwnd_height>5 )
bwnd_height--;
win_resize();
win_header();
break;
case ',':
if ( show_body_fromline && show_body_win )
show_body_fromline--;
msg_show_body(0);
break;
case '.':
if ( show_body_win ) {
show_body_fromline++;
msg_show_body(0);
}
break;
case 13:
case 10:
msg_show_body(0);
if ( !show_body_win ) {
win_resize();
queue_force_repaint ( 1 );
msg_show_headers();
}
break;
case 's':
if ( msg_num ) {
msg_show_body(1);
win_resize();
queue_force_repaint ( 1 );
msg_show_headers();
}
break;
case 'S':
r = wnd_change_sort_field();
if ( r != -1 ) {
if ( r<=3 ) {
pfql_getstatus(pfql_ctx)->sort_field = r;
pfql_getstatus(pfql_ctx)->sort_sense = PFQL_SORT_ASC;
} else {
pfql_getstatus(pfql_ctx)->sort_field = r-3;
pfql_getstatus(pfql_ctx)->sort_sense = PFQL_SORT_DESC;
}
}
queue_force_repaint ( 1 );
}
}
}
int main ( int argc, char** argv ) {
int opt;
int mm;
if ( getuid()!=0 ) {
fprintf ( stderr, "You need to be root to use pfqueue, sorry\n" );
exit (-3);
}
pfql_ctx = 0;
if ( pfql_context_create (&pfql_ctx)!=PFQL_OK ) {
fprintf ( stderr, "pfqueue: cannot pfql_create_context!\n" );
exit (-1);
}
if ( pfql_init(pfql_ctx)!=PFQL_OK ) {
fprintf ( stderr, "pfqueue: cannot pfql_init!\n" );
exit (-1);
}
if ( !fe_init() ) {
pfql_context_destroy(pfql_ctx);
fe_close();
fprintf ( stderr, "pfqueue: cannot fe_init!\n" );
exit (-2);
}
/* Ignore pipes error */
signal ( SIGPIPE, SIG_IGN );
/*
* Parse parameters
*/
// Some defaults
pfql_ctx->regexp = 0;
half_delay_time = 1;
show_body_win = 0;
show_body_always = 1;
pfq_read_config ( pfql_ctx );
opt = 0;
while ( opt!=-1 ) {
opt = getopt ( argc, argv, "p:c:r:B:b:q:s:m:l:ehvn" );
switch (opt) {
case 'p':
snprintf ( pfql_getconf(pfql_ctx)->backend_progs, pfql_getconf(pfql_ctx)->max_char, "%s", optarg );
break;
case 'c':
snprintf ( pfql_getconf(pfql_ctx)->backend_config, pfql_getconf(pfql_ctx)->max_char, "%s", optarg );
break;
case 'r':
snprintf ( pfql_getconf(pfql_ctx)->remote_host, pfql_getconf(pfql_ctx)->max_char, "%s", optarg );
break;
case 'B':
snprintf ( pfql_getconf(pfql_ctx)->backends_path, pfql_getconf(pfql_ctx)->max_char, "%s", optarg );
break;
case 'b':
snprintf ( pfql_getconf(pfql_ctx)->backend_name, pfql_getconf(pfql_ctx)->max_char, "%s", optarg );
break;
case 'q':
mm = atoi ( optarg );
switch ( mm ) {
case 1:
mm = 0;
break;
case 2:
mm = 3;
break;
case 3:
mm = 2;
break;
case 4:
mm = 1;
break;
default:
mm = 0;
}
pfql_getconf(pfql_ctx)->initial_queue = mm;
break;
case 'h':
usage();
exit(0);
break;
case 'v':
version();
exit(0);
break;
case 'm':
mm = atoi (optarg);
if ( mm < 5 )
mm = 5;
pfql_getconf(pfql_ctx)->msg_max = mm;
break;
case 's':
half_delay_time = atoi ( optarg );
if ( half_delay_time > 300 )
half_delay_time = 300;
if ( half_delay_time < 1 )
half_delay_time = 1;
break;
case 'l':
mm = atoi ( optarg );
if ( mm > 300 )
mm = 300;
if ( mm < 1 )
mm = 1;
pfql_getconf(pfql_ctx)->scan_limit = mm;
break;
case 'e':
pfql_getstatus(pfql_ctx)->use_envelope = TRUE;
break;
case 'n':
pfql_getstatus(pfql_ctx)->use_colors = 0;
break;
case 'd':
pfql_getconf(pfql_ctx)->scan_delay = atoi(optarg);
break;
case '?':
goto do_exit;
}
}
if ( pfql_start(pfql_ctx) != PFQL_OK ) {
fprintf ( stderr, "pfqueue: cannot start pfqlib. See syslog for details\n" );
pfql_context_destroy(pfql_ctx);
exit (-4);
}
win_resize();
queue_show();
main_loop();
do_exit:
if ( pfql_ctx )
pfql_context_destroy ( pfql_ctx );
fe_close();
endwin();
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1