home *** CD-ROM | disk | FTP | other *** search
- /*
- ** libsaywha.c - common routines for say(1) and wha(1)
- **
- ** Copyright (C) 1990 by Jef Poskanzer.
- **
- ** Permission to use, copy, modify, and distribute this software and its
- ** documentation for any purpose and without fee is hereby granted, provided
- ** that the above copyright notice appear in all copies and that both that
- ** copyright notice and this permission notice appear in supporting
- ** documentation. This software is provided "as is" without express or
- ** implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "@(#) $Header: libsaywha.c,v 1.6 90/07/24 16:39:42 jef Exp $";
- #endif
-
- #include <stdio.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include "libsaywha.h"
-
- /* External routines. */
- extern int fprintf(), strcmp(), strlen(), strncmp();
- extern char *getenv(), *index(), *mktemp(), *sprintf();
- extern time_t time();
-
- /* Public globals. */
- char *sw_argv0;
- int sw_keepdays = 3;
- int sw_terse = 0;
- #ifdef MAIL_EDITOR
- int sw_mail_editor = 0;
- #endif
- int sw_savemine = 0;
-
- /* Private globals. */
- static char *tmpfilename = "/tmp/sw.XXXXXX";
- static int unlinktmpfile = 0;
-
- int
- sw_check_sayrc( )
- {
- char *home, buf[1000], *cp, *name, *value;
- FILE *fp;
-
- if ( ( home = getenv( "HOME" ) ) == NULL )
- {
- (void) fprintf( stderr, "%s: can't find home directory\n", sw_argv0 );
- return -1;
- }
- (void) sprintf( buf, "%s/.sayrc", home );
- if ( ( fp = fopen( buf, "r" ) ) != NULL )
- {
- while ( fgets( buf, sizeof(buf), fp ) != NULL )
- {
- /* Trim comments. */
- if ( ( cp = index( buf, '#' ) ) != NULL )
- *cp = '\0';
- /* Trim trailing whitespace. */
- for ( cp = &buf[strlen(buf) - 1];
- *cp == ' ' || *cp == '\t' || *cp == '\n';
- --cp )
- *cp = '\0';
- /* Skip leading whitespace. */
- for ( cp = buf;
- *cp == ' ' || *cp == '\t' || *cp == '\n';
- ++cp )
- ;
-
- /* Now, see what we've got. */
- if ( *cp == '\0' )
- {
- /* Null command. */
- }
- else if ( strncmp( cp, "set", 3 ) == 0 )
- {
- /* A set command. */
- cp += 3;
- while ( *cp != ' ' && *cp != '\t' && *cp != '\0' )
- ++cp;
- while ( *cp != '\0' )
- {
- while ( *cp == ' ' || *cp == '\t' )
- ++cp;
- name = cp;
- while ( *cp != '=' && *cp != ' ' && *cp != '\t' &&
- *cp != '\0' )
- ++cp;
- if ( *cp == '=' )
- {
- /* set name=value */
- *cp++ = '\0';
- value = cp;
- while ( *cp != ' ' && *cp != '\t' && *cp != '\0' )
- ++cp;
- *cp++ = '\0';
- }
- else
- {
- /* set name */
- *cp++ = '\0';
- value = NULL;
- }
- /* Ok, we have name and value. Now take a look. */
- if ( strcmp( name, "keepdays" ) == 0 )
- {
- if ( value == NULL )
- (void) fprintf( stderr,
- "%s: missing value in .sayrc set keepdays command\n",
- sw_argv0 );
- else if ( sscanf( value, "%d", &sw_keepdays ) != 1 )
- (void) fprintf( stderr,
- "%s: non-numeric value in .sayrc set keepdays command: \"%s\"\n",
- sw_argv0, value );
- }
- #ifdef MAIL_EDITOR
- else if ( strcmp( name, "mail_editor" ) == 0 )
- {
- if ( value != NULL )
- (void) fprintf( stderr,
- "%s: extraneous value in .sayrc set mail_editor command: \"%s\"\n",
- sw_argv0, value );
- else
- sw_mail_editor = 1;
- }
- #endif
- else if ( strcmp( name, "terse" ) == 0 )
- {
- if ( value != NULL )
- (void) fprintf( stderr,
- "%s: extraneous value in .sayrc set terse command: \"%s\"\n",
- sw_argv0, value );
- else
- sw_terse = 1;
- }
- else if ( strcmp( name, "savemine" ) == 0 )
- {
- if ( value != NULL )
- (void) fprintf( stderr,
- "%s: extraneous value in .sayrc set savemine command: \"%s\"\n",
- sw_argv0, value );
- else
- sw_savemine = 1;
- }
- else
- (void) fprintf( stderr,
- "%s: unrecognized variable in .sayrc set command: \"%s\"\n",
- sw_argv0, name );
- }
- }
- else
- (void) fprintf( stderr,
- "%s: unrecognized command in .sayrc: \"%s\"\n",
- sw_argv0, cp );
- }
- (void) fclose( fp );
- #ifdef MAIL_EDITOR
- if ( sw_mail_editor && sw_terse )
- (void) fprintf( stderr,
- "%s: set mail_editor and set terse don't make sense together\n",
- sw_argv0 );
- #endif
- }
- return 0;
- }
-
- int
- sw_check_my_sayfile( )
- {
- char *home, filename[200], buf[1000];
- FILE *fp1, *fp2;
- int fd;
-
- if ( ( home = getenv( "HOME" ) ) == NULL )
- {
- (void) fprintf( stderr, "%s: can't find home directory\n", sw_argv0 );
- return -1;
- }
- (void) sprintf( filename, "%s/.sayfile", home );
- if ( ( fp1 = fopen( filename, "r+" ) ) == NULL )
- {
- /* No .sayfile found - create one, with the proper protection. */
- if ( ( fd = open( filename, O_CREAT | O_EXCL, 0 ) ) < 0 )
- {
- (void) sprintf( buf, "%s: error creating .sayfile", sw_argv0 );
- perror( buf );
- return -1;
- }
- (void) close( fd );
- #ifdef WORLD_READABLE
- (void) chmod( filename, 0666 );
- #else /*WORLD_READABLE*/
- (void) chmod( filename, 0622 );
- #endif /*WORLD_READABLE*/
- }
- else
- {
- /* Expire old messages. */
- int expired, saving, newsize;
- time_t now;
- int then;
- char tuser[100];
-
- (void) mktemp( tmpfilename );
- if ( ( fp2 = fopen( tmpfilename, "w+" ) ) == NULL )
- {
- (void) sprintf( buf, "%s: couldn't open temp file", sw_argv0 );
- perror( buf );
- return -1;
- }
- unlinktmpfile = 1;
- (void) fchmod( fileno( fp2 ), 0600 );
- expired = 0;
- saving = 1;
- now = time( (time_t *) NULL );
- while ( fgets( buf, sizeof(buf), fp1 ) != NULL )
- {
- if ( buf[0] == MSGSEP )
- {
- if ( sscanf( buf + 1, "%d,%s\n", &then, tuser ) == 2 )
- {
- if ( then / 86400 + sw_keepdays > now / 86400 )
- {
- if ( ! expired )
- break; /* don't bother reading further */
- saving = 1;
- }
- else
- {
- saving = 0;
- expired = 1;
- }
- }
- else
- {
- saving = 0;
- }
- }
- if ( saving )
- (void) fputs( buf, fp2 );
- }
- /* If any messages were expired, copy back the temp file. */
- if ( expired )
- {
- rewind( fp1 );
- rewind( fp2 );
- while ( fgets( buf, sizeof(buf), fp2 ) != NULL )
- (void) fputs( buf, fp1 );
- newsize = ftell( fp1 );
- }
- if ( fclose( fp1 ) == EOF )
- {
- (void) fprintf( stderr, "%s: error closing ", sw_argv0 );
- perror( filename );
- return -1;
- }
- if ( fclose( fp2 ) == EOF )
- {
- (void) fprintf( stderr, "%s: error closing temp file ", sw_argv0 );
- perror( tmpfilename );
- return -1;
- }
- (void) unlink( tmpfilename );
- if ( expired )
- if ( truncate( filename, newsize ) < 0 )
- {
- (void) fprintf( stderr, "%s: error truncating ", sw_argv0 );
- perror( filename );
- return -1;
- }
- }
- return 0;
- }
-
- void
- sw_cleanup( )
- {
- if ( unlinktmpfile )
- (void) unlink( tmpfilename );
- unlinktmpfile = 0;
- }
-