Update to upstream util-linux 2.20.1
[framework/base/util-linux-ng.git] / 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 #include "nls.h"
58 #include "c.h"
59
60 /* exit codes */
61
62 #define IS_ALLOWED        0  /* Receiving messages is allowed.  */
63 #define IS_NOT_ALLOWED    1  /* Receiving messages is not allowed.  */
64 #define MESG_EXIT_FAILURE 2  /* An error occurred.  */
65
66 static void __attribute__ ((__noreturn__)) usage(FILE * out)
67 {
68         fputs(_("\nUsage:\n"), out);
69         fprintf(out,
70               _(" %s [options] [y | n]\n"), program_invocation_short_name);
71
72         fputs(_("\nOptions:\n"), out);
73         fputs(_(" -v, --verbose      explain what is being done\n"
74                 " -V, --version      output version information and exit\n"
75                 " -h, --help         output help screen and exit\n\n"), out);
76
77         exit(out == stderr ? MESG_EXIT_FAILURE : EXIT_SUCCESS);
78 }
79
80 int main(int argc, char *argv[])
81 {
82         struct stat sb;
83         char *tty;
84         int ch, verbose = FALSE;
85
86         setlocale(LC_ALL, "");
87         bindtextdomain(PACKAGE, LOCALEDIR);
88         textdomain(PACKAGE);
89
90         static const struct option longopts[] = {
91                 { "verbose",    no_argument,       0, 'v' },
92                 { "version",    no_argument,       0, 'V' },
93                 { "help",       no_argument,       0, 'h' },
94                 { NULL,         0, 0, 0 }
95         };
96
97         while ((ch = getopt_long(argc, argv, "vVh", longopts, NULL)) != -1)
98                 switch (ch) {
99                 case 'v':
100                         verbose = TRUE;
101                         break;
102                 case 'V':
103                         printf(_("%s from %s\n"), program_invocation_short_name,
104                         PACKAGE_STRING);
105                         exit(EXIT_SUCCESS);
106                 case 'h':
107                         usage(stdout);
108                 default:
109                         usage(stderr);
110                 }
111
112         argc -= optind;
113         argv += optind;
114
115         if ((tty = ttyname(STDERR_FILENO)) == NULL)
116                 err(MESG_EXIT_FAILURE, _("ttyname failed"));
117
118         if (stat(tty, &sb) < 0)
119                 err(MESG_EXIT_FAILURE, _("stat %s failed"), tty);
120
121         if (!*argv) {
122                 if (sb.st_mode & (S_IWGRP | S_IWOTH)) {
123                         puts(_("is y"));
124                         return IS_ALLOWED;
125                 }
126                 puts(_("is n"));
127                 return IS_NOT_ALLOWED;
128         }
129
130         switch (*argv[0]) {
131         case 'y':
132 #ifdef USE_TTY_GROUP
133                 if (chmod(tty, sb.st_mode | S_IWGRP) < 0)
134 #else
135                 if (chmod(tty, sb.st_mode | S_IWGRP | S_IWOTH) < 0)
136 #endif
137                         err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
138                 if (verbose)
139                         puts(_("write access to your terminal is allowed"));
140                 return IS_ALLOWED;
141         case 'n':
142                 if (chmod(tty, sb.st_mode & ~(S_IWGRP|S_IWOTH)) < 0)
143                          err(MESG_EXIT_FAILURE, _("change %s mode failed"), tty);
144                 if (verbose)
145                         puts(_("write access to your terminal is denied"));
146                 return IS_NOT_ALLOWED;
147         default:
148                 warnx(_("invalid argument: %c"), *argv[0]);
149                 usage(stderr);
150         }
151 }