(root)/
util-linux-2.39/
term-utils/
mesg.c
       1  /*
       2   * Copyright (c) 1987, 1993
       3   *	The Regents of the University of California.  All rights reserved.
       4   * (c) UNIX System Laboratories, Inc.
       5   * All or some portions of this file are derived from material licensed
       6   * to the University of California by American Telephone and Telegraph
       7   * Co. or Unix System Laboratories, Inc. and are reproduced herein with
       8   * the permission of UNIX System Laboratories, Inc.
       9   *
      10   * Redistribution and use in source and binary forms, with or without
      11   * modification, are permitted provided that the following conditions
      12   * are met:
      13   * 1. Redistributions of source code must retain the above copyright
      14   *    notice, this list of conditions and the following disclaimer.
      15   * 2. Redistributions in binary form must reproduce the above copyright
      16   *    notice, this list of conditions and the following disclaimer in the
      17   *    documentation and/or other materials provided with the distribution.
      18   * 3. All advertising materials mentioning features or use of this software
      19   *    must display the following acknowledgement:
      20   *	This product includes software developed by the University of
      21   *	California, Berkeley and its contributors.
      22   * 4. Neither the name of the University nor the names of its contributors
      23   *    may be used to endorse or promote products derived from this software
      24   *    without specific prior written permission.
      25   *
      26   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      27   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      28   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      29   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      30   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      31   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      32   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      33   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      34   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      35   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      36   * SUCH DAMAGE.
      37   *
      38   * Modified Fri Mar 10 20:27:19 1995, faith@cs.unc.edu, for Linux
      39   * Modified Mon Jul  1 18:14:10 1996, janl@ifi.uio.no, writing to stdout
      40   *	as suggested by Michael Meskes <meskes@Informatik.RWTH-Aachen.DE>
      41   *
      42   * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
      43   * - added Native Language Support
      44   *
      45   * 2010-12-01 Marek Polacek <mmpolacek@gmail.com>
      46   * - cleanups
      47   */
      48  
      49  #include <errno.h>
      50  #include <stdio.h>
      51  #include <stdlib.h>
      52  #include <string.h>
      53  #include <unistd.h>
      54  #include <sys/types.h>
      55  #include <sys/stat.h>
      56  #include <getopt.h>
      57  
      58  #include "closestream.h"
      59  #include "nls.h"
      60  #include "c.h"
      61  #include "rpmatch.h"
      62  #include "ttyutils.h"
      63  #include "pathnames.h"
      64  
      65  /* exit codes */
      66  
      67  #define IS_ALLOWED        0  /* Receiving messages is allowed.  */
      68  #define IS_NOT_ALLOWED    1  /* Receiving messages is not allowed.  */
      69  #define MESG_EXIT_FAILURE 2  /* An error occurred.  */
      70  
      71  static void __attribute__((__noreturn__)) usage(void)
      72  {
      73  	FILE *out = stdout;
      74  	fputs(USAGE_HEADER, out);
      75  	/* TRANSLATORS: this program uses for y and n rpmatch(3),
      76  	 * which means they can be translated.  */
      77  	fprintf(out,
      78  	      _(" %s [options] [y | n]\n"), program_invocation_short_name);
      79  
      80  	fputs(USAGE_SEPARATOR, out);
      81  	fputs(_("Control write access of other users to your terminal.\n"), out);
      82  
      83  	fputs(USAGE_OPTIONS, out);
      84  	fputs(_(" -v, --verbose  explain what is being done\n"), out);
      85  	printf(USAGE_HELP_OPTIONS(16));
      86  	printf(USAGE_MAN_TAIL("mesg(1)"));
      87  
      88  	exit(EXIT_SUCCESS);
      89  }
      90  
      91  int main(int argc, char *argv[])
      92  {
      93  	struct stat sb;
      94  	char *tty;
      95  	char ttybuf[sizeof(_PATH_PROC_FDDIR) + sizeof(stringify_value(INT_MAX))];
      96  	int ch, fd, verbose = FALSE, ret;
      97  
      98  	static const struct option longopts[] = {
      99  		{ "verbose",    no_argument,       NULL, 'v' },
     100  		{ "version",    no_argument,       NULL, 'V' },
     101  		{ "help",       no_argument,       NULL, 'h' },
     102  		{ NULL,         0, NULL, 0 }
     103  	};
     104  
     105  	setlocale(LC_ALL, "");
     106  	bindtextdomain(PACKAGE, LOCALEDIR);
     107  	textdomain(PACKAGE);
     108  	close_stdout_atexit();
     109  
     110  	while ((ch = getopt_long(argc, argv, "vVh", longopts, NULL)) != -1)
     111  		switch (ch) {
     112  		case 'v':
     113  			verbose = TRUE;
     114  			break;
     115  
     116  		case 'V':
     117  			print_version(EXIT_SUCCESS);
     118  		case 'h':
     119  			usage();
     120  		default:
     121  			errtryhelp(EXIT_FAILURE);
     122  		}
     123  
     124  	argc -= optind;
     125  	argv += optind;
     126  
     127  	fd = get_terminal_stdfd();
     128  	if (fd < 0) {
     129  		if (verbose)
     130  			warnx(_("no tty"));
     131  		exit(MESG_EXIT_FAILURE);
     132  	}
     133  
     134  	tty = ttyname(fd);
     135  	if (!tty) {
     136  		snprintf(ttybuf, sizeof(ttybuf), "%s/%d", _PATH_PROC_FDDIR, fd);
     137  		tty = ttybuf;
     138  		if (verbose)
     139  			warnx(_("ttyname() failed, attempting to go around using: %s"), tty);
     140  	}
     141  
     142  	if (!*argv) {
     143  		if (stat(tty, &sb))
     144  			err(MESG_EXIT_FAILURE, _("stat of %s failed"), tty);
     145  		if (sb.st_mode & (S_IWGRP | S_IWOTH)) {
     146  			puts(_("is y"));
     147  			return IS_ALLOWED;
     148  		}
     149  		puts(_("is n"));
     150  		return IS_NOT_ALLOWED;
     151  	}
     152  
     153  	if ((fd = open(tty, O_RDONLY)) < 0)
     154  		err(MESG_EXIT_FAILURE, _("cannot open %s"), tty);
     155  	if (fstat(fd, &sb))
     156  		err(MESG_EXIT_FAILURE, _("stat of %s failed"), tty);
     157  
     158  	switch (rpmatch(argv[0])) {
     159  	case RPMATCH_YES:
     160  #ifdef USE_TTY_GROUP
     161  		if (fchmod(fd, sb.st_mode | S_IWGRP) < 0)
     162  #else
     163  		if (fchmod(fd, sb.st_mode | S_IWGRP | S_IWOTH) < 0)
     164  #endif
     165  			err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
     166  		if (verbose)
     167  			puts(_("write access to your terminal is allowed"));
     168  		ret = IS_ALLOWED;
     169  		break;
     170  	case RPMATCH_NO:
     171  		if (fchmod(fd, sb.st_mode & ~(S_IWGRP|S_IWOTH)) < 0)
     172  			 err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
     173  		if (verbose)
     174  			puts(_("write access to your terminal is denied"));
     175  		ret = IS_NOT_ALLOWED;
     176  		break;
     177  	case RPMATCH_INVALID:
     178  		warnx(_("invalid argument: %s"), argv[0]);
     179  		errtryhelp(EXIT_FAILURE);
     180          default:
     181                  abort();
     182  	}
     183  	close(fd);
     184  	return ret;
     185  }