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