mesg.c (1837B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include <errno.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/stat.h> // stat, chmod
- #include <unistd.h> // ttyname
- int
- main(int argc, char *argv[])
- {
- argc -= 1;
- argv += 1;
- if(argc > 1)
- {
- fprintf(stderr, "mesg: error: Expected either 0 or 1 argument, got %d\n", argc);
- return 2;
- }
- if(argc == 1)
- {
- if(argv[0][0] == '\0')
- {
- fputs("mesg: error: argument is empty, expected 'y' or 'n'\n", stderr);
- return 2;
- }
- if(argv[0][1] != '\0')
- {
- fputs("mesg: error: argument is too long, expected 'y' or 'n'\n", stderr);
- return 2;
- }
- if(argv[0][0] != 'y' && argv[0][0] != 'n')
- {
- fprintf(stderr, "mesg: error: unknown argument '%s', expected 'y' or 'n'\n", argv[0]);
- return 2;
- }
- }
- char *tty = ttyname(STDIN_FILENO);
- if(!tty) ttyname(STDOUT_FILENO);
- if(!tty) ttyname(STDERR_FILENO);
- if(!tty)
- {
- fputs("mesg: error: Could not determine TTY from stdin/stdout/stderr\n", stderr);
- return 2;
- }
- struct stat tty_st;
- if(stat(tty, &tty_st) < 0)
- {
- fprintf(
- stderr, "mesg: error: Failed getting file status from '%s': %s\n", tty, strerror(errno));
- return 2;
- }
- if(argc == 0)
- {
- if((tty_st.st_mode & 0022) == 0022)
- {
- fputs("messages allowed\n", stdout);
- return 0;
- }
- fputs("messages denied\n", stdout);
- return 1;
- }
- mode_t new_mode = tty_st.st_mode;
- if(argv[0][0] == 'y')
- new_mode |= 0022;
- else
- new_mode &= ~0022;
- if(chmod(tty, new_mode) < 0)
- {
- fprintf(stderr,
- "mesg: error: Failed setting new mode (0%03o) on terminal '%s': %s\n",
- new_mode,
- tty,
- strerror(errno));
- return 2;
- }
- return 0;
- }