home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / msgd / mesg / mesg.c < prev   
Encoding:
C/C++ Source or Header  |  1992-03-09  |  4.4 KB  |  175 lines

  1. /*
  2.  * Copyright (c) 1987 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1987 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. static char *sccsid = "@(#)mesg.c    4.2 (Berkeley) 10/18/80";
  25. /*
  26.  * mesg -- set current tty to accept or
  27.  *    forbid write permission.
  28.  *
  29.  *    mesg [yn] "answerback message"
  30.  *        y allow messages
  31.  *        n forbid messages
  32.  *        answerback is what the other guy gets told (Waterloo)
  33.  *        needs to be setuid root to get rid of other people's
  34.  *        old answerback message files
  35.  *
  36.  */
  37.  
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <utmp.h>
  42. #include <pwd.h>
  43.  
  44. #define ANSWERBACK_FMT    "/usr/tmp/mesg.%s"
  45.  
  46. main(argc, argv)
  47.     char **argv;
  48. {
  49.     int uid, mode, r=0;
  50.     char *tty, *p, *rindex(), *ttyname();
  51.     FILE *fp;
  52.     int i_own_answerback = 0;
  53.     struct stat sbuf;
  54.     struct passwd *pw;
  55.     char answerback[200];
  56.  
  57.     (void) umask(022);    /* so we can read answerback file */
  58.     tty = ttyname(2);
  59.     if (tty == 0)
  60.         error("Cannot determine name of current terminal", (char *)0);
  61.     if ( (p=rindex(tty,'/')) != NULL )
  62.         p++;
  63.     else
  64.         p = tty;
  65.     /*
  66.      * If this isn't a login session, use of mesg is meaningless.
  67.      */
  68.     uid = getuid();
  69.     pw = getpwuid(uid);
  70.     if (pw == NULL) {
  71.         fprintf(stderr, "mesg: Can't find your uid (%d) in the password file\n", uid);
  72.         exit(2);
  73.     }
  74.     if (!in_utmp(pw->pw_name, p)) {
  75.         fprintf(stderr, "mesg: Current terminal session on %s is not a login session\n", tty);
  76.         exit(2);
  77.     }
  78.     /* find name of answerback file */
  79.     (void) sprintf( answerback, ANSWERBACK_FMT, p );
  80.     /* Now make sure that if the answerback file exists, it belongs to
  81.        the current user */
  82.     if ( lstat( answerback, &sbuf ) == 0 ) {
  83.         if (sbuf.st_uid == uid)
  84.             i_own_answerback = 1;
  85.         else
  86.             (void) unlink(answerback);
  87.     }
  88.     if(stat(tty, &sbuf) < 0) error("cannot stat", tty);
  89.     /*
  90.      * must be root before here so we can get rid of other persons
  91.      * answerback file since sticky bit is on tmp directory.
  92.      * must be real user after here so he cant read/write *any* file
  93.      * by creating a link in the tmp directory.
  94.      */
  95.     setuid(uid);
  96.     if(argc < 2) {
  97.         if(sbuf.st_mode & 020)
  98.             printf( "is y\n" );
  99.         else {    r=1;
  100.             printf( "is n\n" );
  101.         }
  102.         if (i_own_answerback) {
  103.             if ( (fp=fopen(answerback,"r")) != NULL ) {
  104.                 int c;
  105.                 while ( (c=getc(fp)) != EOF )
  106.                     putc( c, stdout );
  107.                 (void) fclose( fp );
  108.             } else
  109.                 error("Can't read answerback file", answerback);
  110.         }
  111.     } else {
  112.         if (i_own_answerback)
  113.             (void) unlink(answerback);
  114.         if ( argv[1][0] == 'y' ) {
  115.             mode = sbuf.st_mode | 020;
  116.         } else if ( argv[1][0] == 'n' ) {
  117.             mode = sbuf.st_mode & ~022;
  118.             r = 1;
  119.         } else
  120.             error("usage: mesg [yn] [answerback message]", (char *)0);
  121.         if (chmod(tty, mode) < 0)
  122.             error("cannot change modes", tty);
  123.         if ( argc > 2 ) {    /* write answerback message */
  124.             int i;
  125.             if ( (fp=fopen(answerback,"w")) == (FILE *)NULL )
  126.                 error("Couldn't write answerback file", answerback);
  127.             for ( i=2; i<argc; i++ ) {
  128.                 if ( i>2 )
  129.                     putc( ' ', fp );
  130.                 fputs( argv[i], fp );
  131.             }
  132.             putc( '\n', fp );
  133.             (void) fclose( fp );
  134.         }
  135.     }
  136.     exit(r);
  137. }
  138.  
  139. error(s, arg)
  140. char *s, *arg;
  141. {
  142.     fprintf(stderr,"mesg: %s", s);
  143.     if (arg)
  144.         perror(arg);
  145.     else
  146.         putc('\n', stderr);
  147.     exit(2);
  148. }
  149.  
  150. /*
  151.  * Does the given (user,tty) pair appear in the utmp file?
  152.  */
  153. in_utmp(user, tty)
  154.     char *user, *tty;
  155. {
  156.     FILE *fp;
  157.     struct utmp utmp;
  158.  
  159.     if ((fp = fopen("/etc/utmp", "r")) == NULL)
  160.         return 0;
  161.     while (fread((char *)&utmp, sizeof utmp, 1, fp) == 1) {
  162.         if (strncmp(user, utmp.ut_name, sizeof utmp.ut_name) == 0 &&
  163.             strncmp(tty, utmp.ut_line, sizeof utmp.ut_line) == 0) {
  164. #ifdef USER_PROCESS
  165.             if ( utmp.ut_type != USER_PROCESS )
  166.                 continue;
  167. #endif
  168.             fclose(fp);
  169.             return 1;
  170.         }
  171.     }
  172.     fclose(fp);
  173.     return 0;
  174. }
  175.