v02i018: baff - but another folder flasher
Charles Mcgrew
mcgrew at aramis.rutgers.edu
Sat Aug 25 06:17:19 AEST 1990
Submitted-by: jcb at frisbee.eng.sun.com (Jim Becker)
Posting-number: Volume 2, Issue 18
Archive-name: baff
Since sometimes one want's to preview mail headers without getting
involved in obscured console windows or loading up your favorite mail
reader, this program was developed.
Baff is a folder flasher, flat out. It watches your spool file and
displays the user and subject of non-read mail messages onto your
frame buffer. I know that frame buffers are naughty to write to, but
how this works makes me happy. So it reads the spool file, then rolls
down the current messages, pauses, then rolls 'em back up.
There are a number of settable things in it. I'm sure there are plenty
more things that can be hung off baff also. See the usage message for
details. Since I use gnuemacs to suck in my spool file, there may need
to be tweaking for mail readers that don't do this.
Yes, you too can be a flasher - Enjoy!
-Jim Becker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
*
* baff.c -- But Another Folder Flasher
*
* This program runs in the background looking at the user's
* mail spool file. When it detects that there has been a change
* to the file, or at periodical intervals when there is outstanding
* mail for the user, it blits the author/subject onto the frame
* buffer directly. these lines are left up for a period then erased,
* via the magic of Xor.
*
* This depends on using the pixrect library, and there is a hardcoded
* default font/fontpath within also. Suns only at this point.
*
* Since the application writes to the frame buffer directly it can be
* used under either SunView or X11/News servers, as well as at the console
* level. This will baff*le people that don't know how it's done!
*
* Most things are now flexible for paths and names. See usage message.
*
* To build: cc -o baff baff.c -lpixrect
*
* Jim Becker jcb%frisbee at sun.com -- released Spring 1990
*
*/
#include <ctype.h>
#include <strings.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <pixrect/pixrect_hs.h>
#define DELAY_TIME 10 /* time between checks */
#define THRESHHOLD 6 /* #times before show it*/
#define WAIT_TIME 3 /* how long on screen */
#define FONT_DIR "/usr/lib/fonts/fixedwidthfonts";
#define FONT_NAME "cour.r.16";
#define STR_MAX 128
#define MAX_LETTERS 50
#define TRUE 1
#define FALSE 0
#define EQUALN(a,b) (strncmp((char*)a,(char*)b,strlen(a))==0)
typedef struct {
char user[80];
char subject[80];
} letter;
/* the following can be changed by the user */
static int delay_time = DELAY_TIME;
static int threshhold = THRESHHOLD;
static int wait_time = WAIT_TIME;
static char font_dir[STR_MAX] = FONT_DIR;
static char font_name[STR_MAX] = FONT_NAME;
static char font_path[STR_MAX];
static letter letter_stack[MAX_LETTERS];
static int letter_count;
static char file_name[STR_MAX];
static int last_file_time, current_file_time;
static short user_active;
static short subject_active;
static struct pixrect *screen;
struct pixfont *font_info;
struct pr_prpos location;
static char message[STR_MAX];
static int ypos = 30, xpos = 30;
static int ysize;
static char *usage_msg[] = {
"\n\t\tBaff - \"But Another Folder Flasher\"\n\n",
"This program runs in the background looking at the user's mail spool\n",
"file. When it detects that there has been a change to the file, or at\n",
"periodical intervals when there is outstanding mail for the user, it\n",
"blits the author/subject onto the frame buffer directly. These lines\n",
"are left up for a period then erased, Minor visual damage is possible,\n",
"but harmless. This can also `baff'le those that think it's done in X..\n\n",
"There are tweakable things, of course, with command line options:\n\n",
" -d <nn> (delay_time) delay for <nn> seconds between mail checks\n",
" -t <nn> (threshhold) every <nn> times checked display old info\n",
" -w <nn> (wait_for) wait for <nn> seconds before erasing info\n\n",
"The font can be changed with:\n\n",
" -font <fontname> name of a valid SunView style font\n",
" -fdir <fontdir> where the fonts live in system\n\n",
NULL};
mail_file_time()
{
struct stat file_stat;
if( stat( file_name, &file_stat) != 0 )
return -1;
else
return (int)file_stat.st_mtime;
}
add_current_record()
{
letter_count++;
user_active = FALSE;
subject_active = FALSE;
}
clear_current_record()
{
user_active = FALSE;
subject_active = FALSE;
if( letter_count > 0 )
letter_count--;
}
set_current_user( user )
char *user;
{
strcpy( letter_stack[letter_count].user, user );
user_active = TRUE;
}
set_current_subject( subject )
char *subject;
{
strcpy( letter_stack[letter_count].subject, subject );
subject_active = TRUE;
}
open_parse_file()
{
FILE *mail;
char line[STR_MAX];
mail = fopen( file_name, "r" );
letter_count = 0;
clear_current_record();
if( mail == NULL )
return letter_count;
while( fgets( line, sizeof(line), mail ) != NULL ) {
line[strlen(line)-1] = '\0';
if( user_active && subject_active )
add_current_record();
if( EQUALN( "From:", line ) )
set_current_user( &line[6] );
else
if( EQUALN( "Subject:", line ) )
set_current_subject( &line[9] );
else
if( EQUALN( "Status:", line ) )
clear_current_record();
}
if( user_active && subject_active )
add_current_record();
fclose(mail);
return letter_count;
}
/*
* write a single line to the display
*/
update_line( lineno )
int lineno;
{
sprintf(message, "%-36s \"%s\"\n",
letter_stack[lineno].user, letter_stack[lineno].subject );
location.pos.x = xpos;
location.pos.y = lineno * ysize + ypos;
pf_ttext( location, PIX_NOT(PIX_DST) | PIX_COLOR( 1 ),
font_info, message );
}
/*
* update entire display, first on with the lines then off
*/
update_display()
{
int i;
location.pr = screen;
/* two loops, cause it looks better to take 'em off in reverse */
for( i = 0; i < letter_count; i++ )
update_line( i );
/* let the user see the messages */
sleep(wait_time);
for( i = letter_count-1; i >= 0; i-- )
update_line( i );
}
/*
* this spits out the message on how to use the demo program.
*/
static void
usage()
{
char **string = usage_msg;
while( *string != NULL )
printf( *string++ );
}
parse_args( argc, argv )
int argc;
char **argv;
{
char *arg;
int i, j;
short error = FALSE;
for( i = 1; i < argc; i++ ) {
arg = argv[i];
if( arg[0] == '-' ) {
switch( arg[1] ) {
case 't':
if( i < (argc-1) ) {
arg = argv[++i];
threshhold = atoi(arg);
}
break;
case 'w':
if( i < (argc-1) ) {
arg = argv[++i];
wait_time = atoi(arg);
}
break;
case 'd':
if( i < (argc-1) ) {
arg = argv[++i];
delay_time = atoi(arg);
}
break;
case 'f':
if( i < (argc-1) ) {
if( arg[2] == 'o' ) {
arg = argv[++i];
strcpy( font_name, arg );
}
else if( arg[2] == 'd' ) {
arg = argv[++i];
strcpy( font_dir, arg );
/* trim trailing / if there */
j = strlen(font_dir)-1;
if( font_dir[j] == '/' )
font_dir[j] = '\0';
}
}
break;
default:
printf("don't understand argument `%s'\n", arg);
case '-':
case 'h':
usage();
error = TRUE;
}
}
}
return !error;
}
main( argc, argv )
int argc;
char **argv;
{
int refresh_count = 0;
/* a little hardcoding for the hacker in me.. */
sprintf( file_name, "/usr/spool/mail/%s", getenv("USER") );
screen = pr_open( "/dev/fb" );
if( screen == NULL ) {
printf("No frame buffer access to /dev/fb..\n");
exit(1);
}
if( argc > 1 ) {
if( !parse_args( argc, argv ) )
exit(1);
}
/* construct the default fontname */
sprintf( font_path, "%s/%s", font_dir, font_name );
font_info = pf_open( font_path );
if( font_info == NULL ){
printf("Font `%s' not available..\n", font_path );
exit(1);
}
/* this is the space between lines */
ysize = font_info->pf_defaultsize.y;
ysize += ysize / 3; /* spacing */
while(TRUE) {
current_file_time = mail_file_time();
if( current_file_time > last_file_time ||
++refresh_count > threshhold ) {
/* get new letter stack */
if( open_parse_file() )
update_display();
last_file_time = current_file_time;
refresh_count = 0;
}
sleep(delay_time);
}
}
-- EOF --
--
--
Jim Becker / jcb%frisbee at sun.com / Sun Microsystems
More information about the Comp.sources.sun
mailing list