home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1498 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  8.5 KB

  1. From: jcb@frisbee.Eng.Sun.COM (Jim Becker)
  2. Newsgroups: alt.sources
  3. Subject: Baff -- But Another Folder Flasher (Sun only)
  4. Message-ID: <137509@sun.Eng.Sun.COM>
  5. Date: 19 Jun 90 17:27:00 GMT
  6.  
  7.  
  8.  
  9. `Baff' is a utility which can be run in the background  to  watch  for
  10. incoming mail. When it detects unread mail in the spool file it parses
  11. it  and  outputs  the sender and subject lines to the FRAME BUFFER. It
  12. then leaves the lines for a brief period before erasing them.
  13.  
  14. Baff is the cousin of Biff, but it tells you a bit more directly  what
  15. is awaiting your eyes in the mail input basket. It's possible that the
  16. screen  will  get  a  little  messed  up  if there are changes for the
  17. message duration, but this is infrequent (for me) and harmless.
  18.  
  19. Baff currently runs only on Suns, although the principle could be used
  20. elsewhere.  Although it compiles with the Sun pixrect lib, I use it on
  21. OpenWindows (aka X11/NeWS). This amazes people when they try to figure
  22. out how I'm doing this in X.. (It's possible, but would be slower).
  23.  
  24. Most of the varients have been made user-specifiable, there is a usage
  25. message to give all the details. Just one file, so no Makefile logic.
  26.  
  27.  
  28. -Jim Becker
  29.  
  30. --    
  31.      Jim Becker / jcb%frisbee@sun.com  / Sun Microsystems
  32.  
  33. ---cut here---
  34.  
  35. /*
  36.  *
  37.  *    baff.c        -- But Another Folder Flasher
  38.  *
  39.  *    This program runs in the background looking at the user's 
  40.  *    mail spool file. When it detects that there has been a change
  41.  *    to the file, or at periodical intervals when there is outstanding
  42.  *    mail for the user, it blits the author/subject onto the frame
  43.  *    buffer directly. these lines are left up for a period then erased,
  44.  *    via the magic of Xor. 
  45.  *
  46.  *    This depends on using the pixrect library, and there is a hardcoded
  47.  *    default font/fontpath within also. Suns only at this point.
  48.  *
  49.  *    Since the application writes to the frame buffer directly it can be 
  50.  *    used under either SunView or X11/News servers, as well as at the console
  51.  *    level. This will baff*le people that don't know how it's done!
  52.  *
  53.  *    To build:    cc -o baff baff.c -lpixrect
  54.  *
  55.  *    Jim Becker    jcb%frisbee@sun.com    -- released Spring 1990
  56.  *
  57.  */
  58.  
  59. #include    <ctype.h>
  60. #include    <strings.h>
  61. #include    <stdio.h>
  62. #include    <sys/types.h>
  63. #include    <sys/stat.h>
  64. #include     <signal.h>
  65. #include     <pixrect/pixrect_hs.h>
  66.  
  67.  
  68. #define    DELAY_TIME    10        /* time between checks    */
  69. #define    THRESHHOLD    6        /* #times before show it*/
  70. #define    WAIT_TIME    3        /* how long on screen    */
  71.  
  72. #define    FONT_DIR    "/usr/lib/fonts/fixedwidthfonts";
  73. #define    FONT_NAME    "cour.r.16";
  74.  
  75. #define    STR_MAX        128
  76. #define    MAX_LETTERS    50
  77.  
  78. #define    TRUE        1
  79. #define    FALSE        0
  80.  
  81. #define    EQUALN(a,b)    (strncmp((char*)a,(char*)b,strlen(a))==0)
  82.  
  83. typedef    struct {
  84.     char        user[80];
  85.     char        subject[80];
  86. }    letter;
  87.  
  88. /*    the following can be changed by the user    */
  89. static    int        delay_time        = DELAY_TIME;
  90. static    int        threshhold        = THRESHHOLD;
  91. static    int        wait_time        = WAIT_TIME;
  92.  
  93. static    char        font_dir[STR_MAX]    = FONT_DIR;
  94. static    char        font_name[STR_MAX]    = FONT_NAME;
  95. static    char        font_path[STR_MAX];
  96.  
  97. static    letter        letter_stack[MAX_LETTERS];
  98. static    int        letter_count;
  99.  
  100. static    char        file_name[STR_MAX];
  101. static    int        last_file_time, current_file_time;
  102. static    short        user_active;
  103. static    short        subject_active;
  104.  
  105. static    struct pixrect    *screen;
  106. struct  pixfont        *font_info;
  107. struct  pr_prpos    location;
  108. static    char        message[STR_MAX];
  109.  
  110. static     int        ypos = 30, xpos = 30;
  111. static    int        ysize;
  112.  
  113. static    char        *usage_msg[]    = {
  114.     "\n\t\tBaff    - \"But Another Folder Flasher\"\n\n",
  115.  
  116.     "This  program  runs in the background looking at the user's mail spool\n",
  117.     "file. When it detects that there has been a change to the file, or  at\n",
  118.     "periodical  intervals  when there is outstanding mail for the user, it\n",
  119.     "blits  the  author/subject onto the frame buffer directly. These lines\n",
  120.     "are left up for a period then erased, Minor visual damage is possible,\n",
  121.     "but harmless. This can also `baff'le those that think it's done in X..\n\n",
  122.  
  123.     "There are tweakable things, of course, with command line options:\n\n",
  124.  
  125.     "    -d <nn>    (delay_time)    delay for <nn> seconds between mail checks\n",
  126.     "    -t <nn>    (threshhold)    every <nn> times checked display old info\n",
  127.     "    -w <nn>    (wait_for)    wait for <nn> seconds before erasing info\n\n",
  128.  
  129.     "The font can be changed with:\n\n",
  130.  
  131.     "    -font <fontname>        name of a valid SunView style font\n",
  132.     "    -fdir <fontdir>        where the fonts live in system\n\n",
  133.     NULL};
  134.  
  135. mail_file_time()
  136. {
  137. struct    stat        file_stat;
  138.  
  139.     if( stat( file_name, &file_stat) != 0 )
  140.         return -1;
  141.     else
  142.         return (int)file_stat.st_mtime;
  143. }
  144.  
  145. add_current_record()
  146. {
  147.     letter_count++;
  148.  
  149.     user_active    = FALSE;
  150.     subject_active    = FALSE;    
  151. }        
  152.  
  153. clear_current_record()
  154. {
  155.     user_active    = FALSE;
  156.     subject_active    = FALSE;    
  157.  
  158.     if( letter_count > 0 )
  159.         letter_count--;
  160. }        
  161.  
  162. set_current_user( user )
  163. char        *user;
  164. {
  165.     strcpy( letter_stack[letter_count].user, user );
  166.  
  167.     user_active    = TRUE;
  168. }
  169.  
  170. set_current_subject( subject )
  171. char        *subject;
  172. {
  173.     strcpy( letter_stack[letter_count].subject, subject );
  174.  
  175.     subject_active    = TRUE;
  176. }
  177.  
  178. open_parse_file()
  179. {
  180.     FILE        *mail;
  181.     char        line[STR_MAX];
  182.  
  183.     mail    = fopen( file_name, "r" );
  184.  
  185.     letter_count    = 0;
  186.     clear_current_record();
  187.  
  188.     if( mail == NULL )
  189.         return letter_count;
  190.  
  191.     while( fgets( line, sizeof(line), mail ) != NULL ) {
  192.  
  193.         line[strlen(line)-1] = '\0';
  194.  
  195.         if( user_active && subject_active ) 
  196.             add_current_record();
  197.  
  198.         if( EQUALN( "From:",     line ) )
  199.             set_current_user( &line[6] );
  200.         else
  201.         if( EQUALN( "Subject:", line ) )
  202.             set_current_subject( &line[9] );
  203.         else
  204.         if( EQUALN( "Status:",     line ) )
  205.             clear_current_record();
  206.     }                        
  207.  
  208.     if( user_active && subject_active ) 
  209.           add_current_record();
  210.  
  211.     fclose(mail);
  212.  
  213.     return letter_count;
  214. }
  215.  
  216. /*
  217.  *    write a single line to the display
  218.  */
  219. update_line( lineno )
  220. int    lineno;
  221. {
  222.     sprintf(message, "%-36s \"%s\"\n",
  223.         letter_stack[lineno].user, letter_stack[lineno].subject );
  224.         
  225.     location.pos.x    = xpos;
  226.     location.pos.y    = lineno * ysize + ypos;
  227.         
  228.     pf_ttext( location, PIX_NOT(PIX_DST) | PIX_COLOR( 1 ), 
  229.          font_info, message );
  230.  
  231. }
  232.  
  233. /*
  234.  *    update entire display, first on with the lines then off
  235.  */
  236. update_display()
  237. {
  238.     int        i;
  239.  
  240.     location.pr = screen;
  241.  
  242.     /* two loops, cause it looks better to take 'em off in reverse */
  243.     for( i = 0; i < letter_count; i++ ) 
  244.         update_line( i );
  245.  
  246.     /* let the user see the messages */
  247.     sleep(wait_time);
  248.  
  249.     for( i = letter_count-1; i >= 0; i-- ) 
  250.         update_line( i );
  251. }
  252.  
  253. /*
  254.  *    this spits out the message on how to use the demo program.
  255.  */
  256. static    void
  257. usage()
  258. {
  259.     char        **string     = usage_msg;
  260.  
  261.     while( *string != NULL )
  262.         printf( *string++ );
  263. }
  264.  
  265. parse_args( argc, argv )
  266. int        argc;
  267. char        **argv;
  268. {
  269.     char        *arg;
  270.     int        i, j;
  271.     short        error        = FALSE;
  272.  
  273.     for( i = 1; i < argc; i++ ) {
  274.  
  275.         arg    = argv[i];
  276.  
  277.         if( arg[0] == '-' ) {
  278.             switch( arg[1] ) {
  279.             case     't':
  280.                 if( i < (argc-1) ) {
  281.                     arg        = argv[++i];
  282.                     threshhold    = atoi(arg);
  283.                 }
  284.                 break;
  285.             case     'w':
  286.                 if( i < (argc-1) ) {
  287.                     arg        = argv[++i];
  288.                     wait_time    = atoi(arg);
  289.                 }
  290.                 break;
  291.             case    'd':
  292.                 if( i < (argc-1) ) {
  293.                     arg        = argv[++i];
  294.                     delay_time    = atoi(arg);
  295.                 }
  296.                 break;
  297.             case    'f':
  298.                 if( i < (argc-1) ) {
  299.                     if( arg[2] == 'o' ) {
  300.                         arg    = argv[++i];
  301.                         strcpy( font_name, arg );
  302.                     } 
  303.                     else if( arg[2] == 'd' ) {
  304.                         arg    = argv[++i];
  305.                         strcpy( font_dir, arg );
  306.                         
  307.                         /* trim trailing / if there */
  308.                         j    = strlen(font_dir)-1;
  309.                         if( font_dir[j] == '/' )
  310.                             font_dir[j]    = '\0';
  311.                     }
  312.                 }
  313.                 break;
  314.             default:
  315.                 printf("don't understand argument `%s'\n", arg);
  316.             case     '-':
  317.             case    'h':
  318.                 usage();
  319.                 error     = TRUE;
  320.             }
  321.         }
  322.     }
  323.  
  324.     return !error;
  325. }
  326.     
  327.  
  328. main( argc, argv )
  329. int        argc;
  330. char        **argv;
  331. {
  332.     int    refresh_count    = 0;
  333.  
  334.     /* a little hardcoding for the hacker in me.. */
  335.     sprintf( file_name, "/usr/spool/mail/%s", getenv("USER") );
  336.  
  337.     screen = pr_open( "/dev/fb" );
  338.  
  339.     if( screen == NULL ) {
  340.         printf("No frame buffer access to /dev/fb..\n");
  341.         exit(1);
  342.     }
  343.  
  344.     if( argc > 1 ) {
  345.         if( !parse_args( argc, argv ) )
  346.             exit(1);
  347.     }
  348.  
  349.     /* construct the default fontname */
  350.     sprintf( font_path, "%s/%s", font_dir, font_name );
  351.  
  352.     font_info = pf_open( font_path );
  353.  
  354.     if( font_info == NULL ){
  355.         printf("Font `%s' not available..\n", font_path );
  356.         exit(1);
  357.     }
  358.  
  359.     /* this is the space between lines */
  360.     ysize    = font_info->pf_defaultsize.y;
  361.     ysize  += ysize / 3;    /* spacing */
  362.  
  363.     while(TRUE) {
  364.  
  365.         current_file_time    = mail_file_time();
  366.  
  367.         if( current_file_time > last_file_time || 
  368.             ++refresh_count   > threshhold ) {
  369.  
  370.             /* get new letter stack */
  371.             if( open_parse_file() ) 
  372.                 update_display();
  373.               
  374.             last_file_time    = current_file_time;
  375.             refresh_count    = 0;
  376.         }
  377.  
  378.         sleep(delay_time);
  379.     }
  380. }
  381. --
  382. --    
  383.      Jim Becker / jcb%frisbee@sun.com  / Sun Microsystems
  384.