home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- #ifndef lint
- char copyright[] =
- "@(#) Copyright (c) 1987 Regents of the University of California.\n\
- All rights reserved.\n";
- #endif /* not lint */
-
- static char *sccsid = "@(#)mesg.c 4.2 (Berkeley) 10/18/80";
- /*
- * mesg -- set current tty to accept or
- * forbid write permission.
- *
- * mesg [yn] "answerback message"
- * y allow messages
- * n forbid messages
- * answerback is what the other guy gets told (Waterloo)
- * needs to be setuid root to get rid of other people's
- * old answerback message files
- *
- */
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <utmp.h>
- #include <pwd.h>
-
- #define ANSWERBACK_FMT "/usr/tmp/mesg.%s"
-
- main(argc, argv)
- char **argv;
- {
- int uid, mode, r=0;
- char *tty, *p, *rindex(), *ttyname();
- FILE *fp;
- int i_own_answerback = 0;
- struct stat sbuf;
- struct passwd *pw;
- char answerback[200];
-
- (void) umask(022); /* so we can read answerback file */
- tty = ttyname(2);
- if (tty == 0)
- error("Cannot determine name of current terminal", (char *)0);
- if ( (p=rindex(tty,'/')) != NULL )
- p++;
- else
- p = tty;
- /*
- * If this isn't a login session, use of mesg is meaningless.
- */
- uid = getuid();
- pw = getpwuid(uid);
- if (pw == NULL) {
- fprintf(stderr, "mesg: Can't find your uid (%d) in the password file\n", uid);
- exit(2);
- }
- if (!in_utmp(pw->pw_name, p)) {
- fprintf(stderr, "mesg: Current terminal session on %s is not a login session\n", tty);
- exit(2);
- }
- /* find name of answerback file */
- (void) sprintf( answerback, ANSWERBACK_FMT, p );
- /* Now make sure that if the answerback file exists, it belongs to
- the current user */
- if ( lstat( answerback, &sbuf ) == 0 ) {
- if (sbuf.st_uid == uid)
- i_own_answerback = 1;
- else
- (void) unlink(answerback);
- }
- if(stat(tty, &sbuf) < 0) error("cannot stat", tty);
- /*
- * must be root before here so we can get rid of other persons
- * answerback file since sticky bit is on tmp directory.
- * must be real user after here so he cant read/write *any* file
- * by creating a link in the tmp directory.
- */
- setuid(uid);
- if(argc < 2) {
- if(sbuf.st_mode & 020)
- printf( "is y\n" );
- else { r=1;
- printf( "is n\n" );
- }
- if (i_own_answerback) {
- if ( (fp=fopen(answerback,"r")) != NULL ) {
- int c;
- while ( (c=getc(fp)) != EOF )
- putc( c, stdout );
- (void) fclose( fp );
- } else
- error("Can't read answerback file", answerback);
- }
- } else {
- if (i_own_answerback)
- (void) unlink(answerback);
- if ( argv[1][0] == 'y' ) {
- mode = sbuf.st_mode | 020;
- } else if ( argv[1][0] == 'n' ) {
- mode = sbuf.st_mode & ~022;
- r = 1;
- } else
- error("usage: mesg [yn] [answerback message]", (char *)0);
- if (chmod(tty, mode) < 0)
- error("cannot change modes", tty);
- if ( argc > 2 ) { /* write answerback message */
- int i;
- if ( (fp=fopen(answerback,"w")) == (FILE *)NULL )
- error("Couldn't write answerback file", answerback);
- for ( i=2; i<argc; i++ ) {
- if ( i>2 )
- putc( ' ', fp );
- fputs( argv[i], fp );
- }
- putc( '\n', fp );
- (void) fclose( fp );
- }
- }
- exit(r);
- }
-
- error(s, arg)
- char *s, *arg;
- {
- fprintf(stderr,"mesg: %s", s);
- if (arg)
- perror(arg);
- else
- putc('\n', stderr);
- exit(2);
- }
-
- /*
- * Does the given (user,tty) pair appear in the utmp file?
- */
- in_utmp(user, tty)
- char *user, *tty;
- {
- FILE *fp;
- struct utmp utmp;
-
- if ((fp = fopen("/etc/utmp", "r")) == NULL)
- return 0;
- while (fread((char *)&utmp, sizeof utmp, 1, fp) == 1) {
- if (strncmp(user, utmp.ut_name, sizeof utmp.ut_name) == 0 &&
- strncmp(tty, utmp.ut_line, sizeof utmp.ut_line) == 0) {
- #ifdef USER_PROCESS
- if ( utmp.ut_type != USER_PROCESS )
- continue;
- #endif
- fclose(fp);
- return 1;
- }
- }
- fclose(fp);
- return 0;
- }
-