Use err(3). Add usage() and prototypes.

This commit is contained in:
Philippe Charnier 1997-08-26 11:23:37 +00:00
parent 552f27d60f
commit 29909ffecc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=28794
2 changed files with 60 additions and 67 deletions

View File

@ -33,7 +33,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)write.1 8.1 (Berkeley) 6/6/93
.\" $Id: write.1,v 1.4 1997/02/22 19:57:53 peter Exp $
.\" $Id: write.1,v 1.5 1997/03/22 17:19:32 mpp Exp $
.\"
.Dd June 6, 1993
.Dt WRITE 1
@ -51,7 +51,7 @@ allows you to communicate with other users, by copying lines from
your terminal to theirs.
.Pp
When you run the
.Nm write
.Nm
command, the user you are writing to gets a message of the form:
.Pp
.Dl Message from yourname@yourhost on yourtty at hh:mm ...
@ -59,7 +59,7 @@ command, the user you are writing to gets a message of the form:
Any further lines you enter will be copied to the specified user's
terminal.
If the other user wants to reply, they must run
.Nm write
.Nm
as well.
.Pp
When you are done, type an end-of-file or interrupt character.
@ -76,10 +76,10 @@ command.
If the user you want to write to is logged in on more than one terminal,
you can specify which terminal to write to by specifying the terminal
name as the second operand to the
.Nm write
.Nm
command.
Alternatively, you can let
.Nm write
.Nm
select one of the terminals \- it will pick the one with the shortest
idle time.
This is so that if the user is logged in at work and also dialed up from

View File

@ -35,13 +35,17 @@
*/
#ifndef lint
static char copyright[] =
static const char copyright[] =
"@(#) Copyright (c) 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)write.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id$";
#endif /* not lint */
#include <sys/param.h>
@ -49,15 +53,24 @@ static char sccsid[] = "@(#)write.c 8.1 (Berkeley) 6/6/93";
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/time.h>
#include <utmp.h>
#include <ctype.h>
#include <err.h>
#include <paths.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <utmp.h>
extern int errno;
void done __P((void));
void do_write __P((char *, char *, uid_t));
static void usage __P((void));
int term_chk __P((char *, int *, time_t *, int));
void wr_fputs __P((unsigned char *s));
void search_utmp __P((char *, char *, char *, uid_t));
int utmp_chk __P((char *, char *));
int
main(argc, argv)
int argc;
char **argv;
@ -66,8 +79,7 @@ main(argc, argv)
time_t atime;
uid_t myuid;
int msgsok, myttyfd;
char tty[MAXPATHLEN], *mytty, *ttyname();
void done();
char tty[MAXPATHLEN], *mytty;
/* check that sender has write enabled */
if (isatty(fileno(stdin)))
@ -76,23 +88,16 @@ main(argc, argv)
myttyfd = fileno(stdout);
else if (isatty(fileno(stderr)))
myttyfd = fileno(stderr);
else {
(void)fprintf(stderr, "write: can't find your tty\n");
exit(1);
}
if (!(mytty = ttyname(myttyfd))) {
(void)fprintf(stderr, "write: can't find your tty's name\n");
exit(1);
}
if (cp = rindex(mytty, '/'))
else
errx(1, "can't find your tty");
if (!(mytty = ttyname(myttyfd)))
errx(1, "can't find your tty's name");
if ((cp = rindex(mytty, '/')))
mytty = cp + 1;
if (term_chk(mytty, &msgsok, &atime, 1))
exit(1);
if (!msgsok) {
(void)fprintf(stderr,
"write: you have write permission turned off.\n");
exit(1);
}
if (!msgsok)
errx(1, "you have write permission turned off");
myuid = getuid();
@ -105,34 +110,33 @@ main(argc, argv)
case 3:
if (!strncmp(argv[2], _PATH_DEV, strlen(_PATH_DEV)))
argv[2] += strlen(_PATH_DEV);
if (utmp_chk(argv[1], argv[2])) {
(void)fprintf(stderr,
"write: %s is not logged in on %s.\n",
argv[1], argv[2]);
exit(1);
}
if (utmp_chk(argv[1], argv[2]))
errx(1, "%s is not logged in on %s", argv[1], argv[2]);
if (term_chk(argv[2], &msgsok, &atime, 1))
exit(1);
if (myuid && !msgsok) {
(void)fprintf(stderr,
"write: %s has messages disabled on %s\n",
argv[1], argv[2]);
exit(1);
}
if (myuid && !msgsok)
errx(1, "%s has messages disabled on %s", argv[1], argv[2]);
do_write(argv[2], mytty, myuid);
break;
default:
(void)fprintf(stderr, "usage: write user [tty]\n");
exit(1);
usage();
}
done();
/* NOTREACHED */
return (0);
}
static void
usage()
{
(void)fprintf(stderr, "usage: write user [tty]\n");
exit(1);
}
/*
* utmp_chk - checks that the given user is actually logged in on
* the given tty
*/
int
utmp_chk(user, tty)
char *user, *tty;
{
@ -164,6 +168,7 @@ utmp_chk(user, tty)
* Special case for writing to yourself - ignore the terminal you're
* writing from, unless that's the only terminal with messages enabled.
*/
void
search_utmp(user, tty, mytty, myuid)
char *user, *tty, *mytty;
uid_t myuid;
@ -173,10 +178,8 @@ search_utmp(user, tty, mytty, myuid)
int ufd, nloggedttys, nttys, msgsok, user_is_me;
char atty[UT_LINESIZE + 1];
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) {
perror("utmp");
exit(1);
}
if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0)
err(1, "utmp");
nloggedttys = nttys = 0;
bestatime = 0;
@ -202,22 +205,16 @@ search_utmp(user, tty, mytty, myuid)
}
(void)close(ufd);
if (nloggedttys == 0) {
(void)fprintf(stderr, "write: %s is not logged in\n", user);
exit(1);
}
if (nloggedttys == 0)
errx(1, "%s is not logged in", user);
if (nttys == 0) {
if (user_is_me) { /* ok, so write to yourself! */
(void)strcpy(tty, mytty);
return;
}
(void)fprintf(stderr,
"write: %s has messages disabled\n", user);
exit(1);
errx(1, "%s has messages disabled", user);
} else if (nttys > 1) {
(void)fprintf(stderr,
"write: %s is logged in more than once; writing to %s\n",
user, tty);
warnx("%s is logged in more than once; writing to %s", user, tty);
}
}
@ -225,6 +222,7 @@ search_utmp(user, tty, mytty, myuid)
* term_chk - check that a terminal exists, and get the message bit
* and the access time
*/
int
term_chk(tty, msgsokP, atimeP, showerror)
char *tty;
int *msgsokP, showerror;
@ -236,8 +234,7 @@ term_chk(tty, msgsokP, atimeP, showerror)
(void)snprintf(path, sizeof(path), "%s%s", _PATH_DEV, tty);
if (stat(path, &s) < 0) {
if (showerror)
(void)fprintf(stderr,
"write: %s: %s\n", path, strerror(errno));
warn("%s", path);
return(1);
}
*msgsokP = (s.st_mode & (S_IWRITE >> 3)) != 0; /* group write bit */
@ -248,28 +245,26 @@ term_chk(tty, msgsokP, atimeP, showerror)
/*
* do_write - actually make the connection
*/
void
do_write(tty, mytty, myuid)
char *tty, *mytty;
uid_t myuid;
{
register char *login, *nows;
register struct passwd *pwd;
time_t now, time();
char *getlogin(), path[MAXPATHLEN], host[MAXHOSTNAMELEN], line[512];
void done();
time_t now;
char path[MAXPATHLEN], host[MAXHOSTNAMELEN], line[512];
/* Determine our login name before the we reopen() stdout */
if ((login = getlogin()) == NULL)
if (pwd = getpwuid(myuid))
if ((pwd = getpwuid(myuid)))
login = pwd->pw_name;
else
login = "???";
(void)snprintf(path, sizeof(path), "%s%s", _PATH_DEV, tty);
if ((freopen(path, "w", stdout)) == NULL) {
(void)fprintf(stderr, "write: %s: %s\n", path, strerror(errno));
exit(1);
}
if ((freopen(path, "w", stdout)) == NULL)
err(1, "%s", path);
(void)signal(SIGINT, done);
(void)signal(SIGHUP, done);
@ -301,11 +296,12 @@ done()
* wr_fputs - like fputs(), but makes control characters visible and
* turns \n into \r\n
*/
void
wr_fputs(s)
register unsigned char *s;
{
#define PUTC(c) if (putchar(c) == EOF) goto err;
#define PUTC(c) if (putchar(c) == EOF) err(1, NULL);
for (; *s != '\0'; ++s) {
if (*s == '\n') {
@ -324,8 +320,5 @@ wr_fputs(s)
PUTC(*s);
}
return;
err: (void)fprintf(stderr, "write: %s\n", strerror(errno));
exit(1);
#undef PUTC
}