home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / sun / volume02 / baff next >
Encoding:
Internet Message Format  |  1991-08-27  |  9.0 KB

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