billw@oberon.lcs.mit.edu (Bill Wisner) (12/30/87)
Due to a problem with the format of /etc/utmp, dots can't handle 2-player
games against someone with an eight-letter username. The following replacement
for findem.c alleviates the problem.
-- (cut here)
/* findem.c find the login of the person we wanna play */
#include "dots.h"
#include <sys/stat.h>
#include <sgtty.h>
#include <utmp.h>
#define UTMP "/etc/utmp"
struct utmp utmp_buf;
struct stat stat_buf;
struct sgttyb sgtty_buf;
int fd;
findem(argc, argv)
char **argv;
{
char *ttyname(), to_tty[13], *tmp_name;
register char *login = argv[2], *where = "", *ourtty = ttyname(0) + 5;
register FILE *recipient;
if (argc > 3)
where = argv[3];
if (!strcmp(where, ourtty)) {
fprintf(stderr, "You can't play yourself.\n");
return 0;
}
if ((fd = open(UTMP, 0)) == -1) {
perror(UTMP);
return 0;
}
while (read(fd, (char *) &utmp_buf, sizeof(utmp_buf)))
if (!strncmp(utmp_buf.ut_name, login, 8) &&
(*where && !strcmp(utmp_buf.ut_line, where) ||
(!*where && strcmp(where, ourtty))))
break;
(void) close(fd);
if (strncmp(login, utmp_buf.ut_name, 8)) {
fprintf(stderr, "%s is not logged in.", login);
return 0;
}
if (*where && strcmp(where, utmp_buf.ut_line)) {
fprintf(stderr, "%s is not logged in on %s.\n", login, where);
return 0;
}
(void) sprintf(to_tty, "/dev/%s", utmp_buf.ut_line);
if (!(recipient = fopen(to_tty, "w"))) {
perror(to_tty);
fprintf(stderr, "%s: Can't ask %s to play.\n", argv[0], argv[2]);
return 0;
}
setuid(getuid()); /* turns off set-uid attribute once tty is opened */
setgid(getgid()); /* probably isn't necessary most of the time */
return invite(recipient);
}chris@mimsy.UUCP (Chris Torek) (12/31/87)
In article <7765@eddie.MIT.EDU>, billw@oberon.lcs.mit.edu (Bill Wisner) writes: >Due to a problem with the format of /etc/utmp, dots can't handle 2-player >games against someone with an eight-letter username. The following replacement >for findem.c alleviates the problem. As it says in <utmp.h>, `Assuming the number 8 is unwise.' There are several other potential bugs in this routine (I spotted three offhand). I would change it to something more like this: /* findem.c find the login of the person we wanna play */ #include "dots.h" #include <sys/stat.h> #include <sgtty.h> #include <utmp.h> #define UTMP "/etc/utmp" struct utmp utmp_buf; struct stat stat_buf; struct sgttyb sgtty_buf; int fd; #define NMAX sizeof(utmp_buf.ut_name) #define LMAX sizeof(utmp_buf.ut_line) #define DEVPART "/dev/" #define DEVLEN 5 /* strlen(DEVPART) */ char *ttyname(); findem(argc, argv) int argc; char **argv; { register char *login = argv[2], *where = 0, *ourtty = ttyname(0); register FILE *recipient; int found; char *to_tty[DEVLEN + LMAX + 1]; if (ourtty == 0) { fprintf(stderr, "%s: can't find your tty\n"); return 0; } ourtty += DEVLEN; if (argc > 3) { where = argv[3]; if (strcmp(where, ourtty) == 0) { fprintf(stderr, "You can't play yourself.\n"); return 0; } } if ((fd = open(UTMP, 0)) == -1) { perror(UTMP); return 0; } found = 0; while (read(fd, (char *)&utmp_buf, sizeof(utmp_buf)) > 0) { if (strncmp(utmp_buf.ut_name, login, NMAX) != 0) continue; found = -1; if (where == 0 || strncmp(utmp_buf.ut_line, where, LMAX) == 0)) { found = 1; break; } } (void) close(fd); if (found < 1) { fprintf(stderr, "%s is not logged in%s%s.\n", login, found ? " on " : "", found ? where : ""); return 0; } /* N.B.: %.*s may be dubious under dpANS */ (void) sprintf(to_tty, "%s%.*s", DEVPART, LMAX, utmp_buf.ut_line); if ((recipient = fopen(to_tty, "w")) == 0) { perror(to_tty); fprintf(stderr, "%s: Can't ask %s to play.\n", argv[0], argv[2]); return 0; } setgid(getgid());/* probably isn't necessary most of the time */ setuid(getuid());/* turns off set-uid attribute once tty is opened */ return invite(recipient); } -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris