summaryrefslogtreecommitdiffstats
path: root/term-utils/write.c
diff options
context:
space:
mode:
authorSami Kerola2016-05-07 13:02:12 +0200
committerSami Kerola2016-07-01 22:08:53 +0200
commitb5a6937961ec9146883ad107b588ff41f6f3a278 (patch)
treea553fff1c245182a637c8b61bff9f7de4ebc24dd /term-utils/write.c
parentwrite: run atexit() checks at the end of execution (diff)
downloadkernel-qcow2-util-linux-b5a6937961ec9146883ad107b588ff41f6f3a278.tar.gz
kernel-qcow2-util-linux-b5a6937961ec9146883ad107b588ff41f6f3a278.tar.xz
kernel-qcow2-util-linux-b5a6937961ec9146883ad107b588ff41f6f3a278.zip
write: add control structure to clarify what is going on
This is done purely an improve readability of the source code. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'term-utils/write.c')
-rw-r--r--term-utils/write.c96
1 files changed, 54 insertions, 42 deletions
diff --git a/term-utils/write.c b/term-utils/write.c
index 568892d79..2557f3361 100644
--- a/term-utils/write.c
+++ b/term-utils/write.c
@@ -68,6 +68,14 @@
static sig_atomic_t signal_received = 0;
+struct write_control {
+ uid_t src_uid;
+ const char *src_login;
+ char *src_tty;
+ const char *dst_login;
+ char dst_tty[PATH_MAX];
+};
+
static void __attribute__ ((__noreturn__)) usage(FILE * out)
{
fputs(USAGE_HEADER, out);
@@ -116,7 +124,7 @@ static int term_chk(char *tty, int *msgsokP, time_t * atimeP, int showerror)
* utmp_chk - checks that the given user is actually logged in on
* the given tty
*/
-static int utmp_chk(char *user, char *tty)
+static int utmp_chk(const struct write_control *ctl)
{
struct utmp u;
struct utmp *uptr;
@@ -127,8 +135,8 @@ static int utmp_chk(char *user, char *tty)
while ((uptr = getutent())) {
memcpy(&u, uptr, sizeof(u));
- if (strncmp(user, u.ut_user, sizeof(u.ut_user)) == 0 &&
- strncmp(tty, u.ut_line, sizeof(u.ut_line)) == 0) {
+ if (strncmp(ctl->dst_login, u.ut_user, sizeof(u.ut_user)) == 0 &&
+ strncmp(ctl->dst_tty, u.ut_line, sizeof(u.ut_line)) == 0) {
res = 0;
break;
}
@@ -149,7 +157,7 @@ static int utmp_chk(char *user, char *tty)
* Special case for writing to yourself - ignore the terminal you're
* writing from, unless that's the only terminal with messages enabled.
*/
-static void search_utmp(char *user, char *tty, char *mytty, uid_t myuid)
+static void search_utmp(struct write_control *ctl)
{
struct utmp u;
struct utmp *uptr;
@@ -165,16 +173,16 @@ static void search_utmp(char *user, char *tty, char *mytty, uid_t myuid)
user_is_me = 0;
while ((uptr = getutent())) {
memcpy(&u, uptr, sizeof(u));
- if (strncmp(user, u.ut_user, sizeof(u.ut_user)) == 0) {
+ if (strncmp(ctl->dst_login, u.ut_user, sizeof(u.ut_user)) == 0) {
++nloggedttys;
xstrncpy(atty, u.ut_line, sizeof(atty));
if (term_chk(atty, &msgsok, &atime, 0))
/* bad term? skip */
continue;
- if (myuid && !msgsok)
+ if (ctl->src_uid && !msgsok)
/* skip ttys with msgs off */
continue;
- if (strcmp(atty, mytty) == 0) {
+ if (strcmp(atty, ctl->src_tty) == 0) {
user_is_me = 1;
/* don't write to yourself */
continue;
@@ -185,25 +193,26 @@ static void search_utmp(char *user, char *tty, char *mytty, uid_t myuid)
++nttys;
if (atime > bestatime) {
bestatime = atime;
- strcpy(tty, atty);
+ xstrncpy(ctl->dst_tty, atty, sizeof(ctl->dst_tty));
}
}
}
endutent();
if (nloggedttys == 0)
- errx(EXIT_FAILURE, _("%s is not logged in"), user);
+ errx(EXIT_FAILURE, _("%s is not logged in"), ctl->dst_login);
if (nttys == 0) {
if (user_is_me) {
/* ok, so write to yourself! */
- strcpy(tty, mytty);
+ xstrncpy(ctl->dst_tty, ctl->src_tty, sizeof(ctl->dst_tty));
return;
}
- errx(EXIT_FAILURE, _("%s has messages disabled"), user);
+ errx(EXIT_FAILURE, _("%s has messages disabled"), ctl->dst_login);
} else if (nttys > 1) {
warnx(_("%s is logged in more than once; writing to %s"),
- user, tty);
+ ctl->dst_login, ctl->dst_tty);
}
+
}
/*
@@ -237,7 +246,7 @@ static void wr_fputs(char *s)
/*
* do_write - actually make the connection
*/
-static void do_write(char *tty, char *mytty, uid_t myuid)
+static void do_write(const struct write_control *ctl)
{
char *login, *pwuid, *nows;
struct passwd *pwd;
@@ -246,16 +255,16 @@ static void do_write(char *tty, char *mytty, uid_t myuid)
struct sigaction sigact;
/* Determine our login name(s) before the we reopen() stdout */
- if ((pwd = getpwuid(myuid)) != NULL)
+ if ((pwd = getpwuid(ctl->src_uid)) != NULL)
pwuid = pwd->pw_name;
else
pwuid = "???";
if ((login = getlogin()) == NULL)
login = pwuid;
- if (strlen(tty) + 6 > sizeof(path))
- errx(EXIT_FAILURE, _("tty path %s too long"), tty);
- snprintf(path, sizeof(path), "/dev/%s", tty);
+ if (strlen(ctl->dst_tty) + 6 > sizeof(path))
+ errx(EXIT_FAILURE, _("tty path %s too long"), ctl->dst_tty);
+ snprintf(path, sizeof(path), "/dev/%s", ctl->dst_tty);
if ((freopen(path, "w", stdout)) == NULL)
err(EXIT_FAILURE, "%s", path);
@@ -276,10 +285,10 @@ static void do_write(char *tty, char *mytty, uid_t myuid)
printf("\r\n\007\007\007");
if (strcmp(login, pwuid))
printf(_("Message from %s@%s (as %s) on %s at %s ..."),
- login, host, pwuid, mytty, nows + 11);
+ login, host, pwuid, ctl->src_tty, nows + 11);
else
printf(_("Message from %s@%s on %s at %s ..."),
- login, host, mytty, nows + 11);
+ login, host, ctl->src_tty, nows + 11);
free(host);
printf("\r\n");
@@ -293,9 +302,8 @@ static void do_write(char *tty, char *mytty, uid_t myuid)
int main(int argc, char **argv)
{
- uid_t myuid;
- int msgsok = 0, myttyfd, c;
- char tty[PATH_MAX], *mytty;
+ int msgsok = 0, src_fd, c;
+ struct write_control ctl = { 0 };
static const struct option longopts[] = {
{"version", no_argument, NULL, 'V'},
@@ -321,16 +329,16 @@ int main(int argc, char **argv)
/* check that sender has write enabled */
if (isatty(STDIN_FILENO))
- myttyfd = STDIN_FILENO;
+ src_fd = STDIN_FILENO;
else if (isatty(STDOUT_FILENO))
- myttyfd = STDOUT_FILENO;
+ src_fd = STDOUT_FILENO;
else if (isatty(STDERR_FILENO))
- myttyfd = STDERR_FILENO;
+ src_fd = STDERR_FILENO;
else
- myttyfd = -1;
+ src_fd = -1;
- if (myttyfd != -1) {
- if (!(mytty = ttyname(myttyfd)))
+ if (src_fd != -1) {
+ if (!(ctl.src_tty = ttyname(src_fd)))
errx(EXIT_FAILURE,
_("can't find your tty's name"));
@@ -339,39 +347,43 @@ int main(int argc, char **argv)
* term_chk() will put "/dev/" in front, so remove that
* part.
*/
- if (!strncmp(mytty, "/dev/", 5))
- mytty += 5;
- if (term_chk(mytty, &msgsok, NULL, 1))
+ if (!strncmp(ctl.src_tty, "/dev/", 5))
+ ctl.src_tty += 5;
+ if (term_chk(ctl.src_tty, &msgsok, NULL, 1))
exit(EXIT_FAILURE);
if (!msgsok)
errx(EXIT_FAILURE,
_("you have write permission turned off"));
msgsok = 0;
} else
- mytty = "<no tty>";
+ ctl.src_tty = "<no tty>";
- myuid = getuid();
+ ctl.src_uid = getuid();
/* check args */
switch (argc) {
case 2:
- search_utmp(argv[1], tty, mytty, myuid);
- do_write(tty, mytty, myuid);
+ ctl.dst_login = argv[1];
+ search_utmp(&ctl);
+ do_write(&ctl);
break;
case 3:
+ ctl.dst_login = argv[1];
if (!strncmp(argv[2], "/dev/", 5))
- argv[2] += 5;
- if (utmp_chk(argv[1], argv[2]))
+ xstrncpy(ctl.dst_tty, argv[2] + 5, sizeof(ctl.dst_tty));
+ else
+ xstrncpy(ctl.dst_tty, argv[2], sizeof(ctl.dst_tty));
+ if (utmp_chk(&ctl))
errx(EXIT_FAILURE,
_("%s is not logged in on %s"),
- argv[1], argv[2]);
- if (term_chk(argv[2], &msgsok, NULL, 1))
+ ctl.dst_login, ctl.dst_tty);
+ if (term_chk(ctl.dst_tty, &msgsok, NULL, 1))
exit(EXIT_FAILURE);
- if (myuid && !msgsok)
+ if (ctl.src_uid && !msgsok)
errx(EXIT_FAILURE,
_("%s has messages disabled on %s"),
- argv[1], argv[2]);
- do_write(argv[2], mytty, myuid);
+ ctl.dst_login, ctl.dst_tty);
+ do_write(&ctl);
break;
default:
usage(stderr);