home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume2 / baff next >
Text File  |  1990-08-24  |  9KB  |  394 lines

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