home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1625 / libsaywha.c next >
C/C++ Source or Header  |  1990-12-28  |  7KB  |  283 lines

  1. /*
  2. ** libsaywha.c - common routines for say(1) and wha(1)
  3. **
  4. ** Copyright (C) 1990 by Jef Poskanzer.
  5. **
  6. ** Permission to use, copy, modify, and distribute this software and its
  7. ** documentation for any purpose and without fee is hereby granted, provided
  8. ** that the above copyright notice appear in all copies and that both that
  9. ** copyright notice and this permission notice appear in supporting
  10. ** documentation.  This software is provided "as is" without express or
  11. ** implied warranty.
  12. */
  13.  
  14. #ifndef lint
  15. static char rcsid[] = "@(#) $Header: libsaywha.c,v 1.6 90/07/24 16:39:42 jef Exp $";
  16. #endif
  17.  
  18. #include <stdio.h>
  19. #include <sys/file.h>
  20. #include <sys/types.h>
  21. #include "libsaywha.h"
  22.  
  23. /* External routines. */
  24. extern int fprintf(), strcmp(), strlen(), strncmp();
  25. extern char *getenv(), *index(), *mktemp(), *sprintf();
  26. extern time_t time();
  27.  
  28. /* Public globals. */
  29. char *sw_argv0;
  30. int sw_keepdays = 3;
  31. int sw_terse = 0;
  32. #ifdef MAIL_EDITOR
  33. int sw_mail_editor = 0;
  34. #endif
  35. int sw_savemine = 0;
  36.  
  37. /* Private globals. */
  38. static char *tmpfilename = "/tmp/sw.XXXXXX";
  39. static int unlinktmpfile = 0;
  40.  
  41. int
  42. sw_check_sayrc( )
  43.     {
  44.     char *home, buf[1000], *cp, *name, *value;
  45.     FILE *fp;
  46.  
  47.     if ( ( home = getenv( "HOME" ) ) == NULL )
  48.     {
  49.     (void) fprintf( stderr, "%s: can't find home directory\n", sw_argv0 );
  50.     return -1;
  51.     }
  52.     (void) sprintf( buf, "%s/.sayrc", home );
  53.     if ( ( fp = fopen( buf, "r" ) ) != NULL )
  54.     {
  55.     while ( fgets( buf, sizeof(buf), fp ) != NULL )
  56.         {
  57.         /* Trim comments. */
  58.         if ( ( cp = index( buf, '#' ) ) != NULL )
  59.         *cp = '\0';
  60.         /* Trim trailing whitespace. */
  61.         for ( cp = &buf[strlen(buf) - 1];
  62.           *cp == ' ' || *cp == '\t' || *cp == '\n';
  63.           --cp )
  64.         *cp = '\0';
  65.         /* Skip leading whitespace. */
  66.         for ( cp = buf;
  67.           *cp == ' ' || *cp == '\t' || *cp == '\n';
  68.           ++cp )
  69.         ;
  70.  
  71.         /* Now, see what we've got. */
  72.         if ( *cp == '\0' )
  73.         {
  74.         /* Null command. */
  75.         }
  76.         else if ( strncmp( cp, "set", 3 ) == 0 )
  77.         {
  78.         /* A set command. */
  79.         cp += 3;
  80.         while ( *cp != ' ' && *cp != '\t' && *cp != '\0' )
  81.             ++cp;
  82.         while ( *cp != '\0' )
  83.             {
  84.             while ( *cp == ' ' || *cp == '\t' )
  85.             ++cp;
  86.             name = cp;
  87.             while ( *cp != '=' && *cp != ' ' && *cp != '\t' &&
  88.                 *cp != '\0' )
  89.             ++cp;
  90.             if ( *cp == '=' )
  91.             {
  92.             /* set name=value */
  93.             *cp++ = '\0';
  94.             value = cp;
  95.             while ( *cp != ' ' && *cp != '\t' && *cp != '\0' )
  96.                 ++cp;
  97.             *cp++ = '\0';
  98.             }
  99.             else
  100.             {
  101.             /* set name */
  102.             *cp++ = '\0';
  103.             value = NULL;
  104.             }
  105.             /* Ok, we have name and value.  Now take a look. */
  106.             if ( strcmp( name, "keepdays" ) == 0 )
  107.             {
  108.             if ( value == NULL )
  109.                 (void) fprintf( stderr,
  110.                "%s: missing value in .sayrc set keepdays command\n",
  111.                 sw_argv0 );
  112.             else if ( sscanf( value, "%d", &sw_keepdays ) != 1 )
  113.                 (void) fprintf( stderr,
  114.            "%s: non-numeric value in .sayrc set keepdays command: \"%s\"\n",
  115.                 sw_argv0, value );
  116.             }
  117. #ifdef MAIL_EDITOR
  118.             else if ( strcmp( name, "mail_editor" ) == 0 )
  119.             {
  120.             if ( value != NULL )
  121.                 (void) fprintf( stderr,
  122.          "%s: extraneous value in .sayrc set mail_editor command: \"%s\"\n",
  123.                 sw_argv0, value );
  124.             else
  125.                 sw_mail_editor = 1;
  126.             }
  127. #endif
  128.             else if ( strcmp( name, "terse" ) == 0 )
  129.             {
  130.             if ( value != NULL )
  131.                 (void) fprintf( stderr,
  132.            "%s: extraneous value in .sayrc set terse command: \"%s\"\n",
  133.                 sw_argv0, value );
  134.             else
  135.                 sw_terse = 1;
  136.             }
  137.             else if ( strcmp( name, "savemine" ) == 0 )
  138.             {
  139.             if ( value != NULL )
  140.                 (void) fprintf( stderr,
  141.         "%s: extraneous value in .sayrc set savemine command: \"%s\"\n",
  142.                 sw_argv0, value );
  143.             else
  144.                 sw_savemine = 1;
  145.             }
  146.             else
  147.             (void) fprintf( stderr,
  148.             "%s: unrecognized variable in .sayrc set command: \"%s\"\n",
  149.                 sw_argv0, name );
  150.             }
  151.         }
  152.         else
  153.         (void) fprintf( stderr,
  154.             "%s: unrecognized command in .sayrc: \"%s\"\n",
  155.             sw_argv0, cp );
  156.         }
  157.     (void) fclose( fp );
  158. #ifdef MAIL_EDITOR
  159.     if ( sw_mail_editor && sw_terse )
  160.         (void) fprintf( stderr,
  161.         "%s: set mail_editor and set terse don't make sense together\n",
  162.         sw_argv0 );
  163. #endif
  164.     }
  165.     return 0;
  166.     }
  167.  
  168. int
  169. sw_check_my_sayfile( )
  170.     {
  171.     char *home, filename[200], buf[1000];
  172.     FILE *fp1, *fp2;
  173.     int fd;
  174.  
  175.     if ( ( home = getenv( "HOME" ) ) == NULL )
  176.     {
  177.     (void) fprintf( stderr, "%s: can't find home directory\n", sw_argv0 );
  178.     return -1;
  179.     }
  180.     (void) sprintf( filename, "%s/.sayfile", home );
  181.     if ( ( fp1 = fopen( filename, "r+" ) ) == NULL )
  182.     {
  183.     /* No .sayfile found - create one, with the proper protection. */
  184.     if ( ( fd = open( filename, O_CREAT | O_EXCL, 0 ) ) < 0 )
  185.         {
  186.         (void) sprintf( buf, "%s: error creating .sayfile", sw_argv0 );
  187.         perror( buf );
  188.         return -1;
  189.         }
  190.     (void) close( fd );
  191. #ifdef WORLD_READABLE
  192.     (void) chmod( filename, 0666 );
  193. #else /*WORLD_READABLE*/
  194.     (void) chmod( filename, 0622 );
  195. #endif /*WORLD_READABLE*/
  196.     }
  197.     else
  198.     {
  199.     /* Expire old messages. */
  200.     int expired, saving, newsize;
  201.     time_t now;
  202.     int then;
  203.     char tuser[100];
  204.  
  205.     (void) mktemp( tmpfilename );
  206.     if ( ( fp2 = fopen( tmpfilename, "w+" ) ) == NULL )
  207.         {
  208.         (void) sprintf( buf, "%s: couldn't open temp file", sw_argv0 );
  209.         perror( buf );
  210.         return -1;
  211.         }
  212.     unlinktmpfile = 1;
  213.     (void) fchmod( fileno( fp2 ), 0600 );
  214.     expired = 0;
  215.     saving = 1;
  216.     now = time( (time_t *) NULL );
  217.     while ( fgets( buf, sizeof(buf), fp1 ) != NULL )
  218.         {
  219.         if ( buf[0] == MSGSEP )
  220.         {
  221.         if ( sscanf( buf + 1, "%d,%s\n", &then, tuser ) == 2 )
  222.             {
  223.             if ( then / 86400 + sw_keepdays > now / 86400 )
  224.             {
  225.             if ( ! expired )
  226.                 break;    /* don't bother reading further */
  227.             saving = 1;
  228.             }
  229.             else
  230.             {
  231.             saving = 0;
  232.             expired = 1;
  233.             }
  234.             }
  235.         else
  236.             {
  237.             saving = 0;
  238.             }
  239.         }
  240.         if ( saving )
  241.         (void) fputs( buf, fp2 );
  242.         }
  243.     /* If any messages were expired, copy back the temp file. */
  244.     if ( expired )
  245.         {
  246.         rewind( fp1 );
  247.         rewind( fp2 );
  248.         while ( fgets( buf, sizeof(buf), fp2 ) != NULL )
  249.         (void) fputs( buf, fp1 );
  250.         newsize = ftell( fp1 );
  251.         }
  252.     if ( fclose( fp1 ) == EOF )
  253.         {
  254.         (void) fprintf( stderr, "%s: error closing ", sw_argv0 );
  255.         perror( filename );
  256.         return -1;
  257.         }
  258.     if ( fclose( fp2 ) == EOF )
  259.         {
  260.         (void) fprintf( stderr, "%s: error closing temp file ", sw_argv0 );
  261.         perror( tmpfilename );
  262.         return -1;
  263.         }
  264.     (void) unlink( tmpfilename );
  265.     if ( expired )
  266.         if ( truncate( filename, newsize ) < 0 )
  267.         {
  268.         (void) fprintf( stderr, "%s: error truncating ", sw_argv0 );
  269.         perror( filename );
  270.         return -1;
  271.         }
  272.     }
  273.     return 0;
  274.     }
  275.  
  276. void
  277. sw_cleanup( )
  278.     {
  279.     if ( unlinktmpfile )
  280.     (void) unlink( tmpfilename );
  281.     unlinktmpfile = 0;
  282.     }
  283.