/* $NetBSD: faketalk.c,v 1.8 2003/06/11 12:00:22 wiz Exp $ */ /* * Copyright (c) 1983-2003, Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * + Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * + Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * + Neither the name of the University of California, San Francisco nor * the names of its contributors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #ifndef lint __RCSID("$NetBSD: faketalk.c,v 1.8 2003/06/11 12:00:22 wiz Exp $"); #endif /* not lint */ #include "bsd.h" #include "hunt.h" #if defined(TALK_43) || defined(TALK_42) # include # include # include # include # include # include # include # include # include "talk_ctl.h" # define TRUE 1 # define FALSE 0 /* defines for fake talk message to announce start of game */ # ifdef TALK_43 # define MASQUERADE "\"Hunt Game\"" # else # define MASQUERADE "HuntGame" # endif # define RENDEZVOUS "hunt-players" # define ARGV0 "HUNT-ANNOUNCE" extern char *my_machine_name; extern char *First_arg, *Last_arg; extern char **environ; static void do_announce __P((char *)); SIGNAL_TYPE exorcise __P((int)); /* * exorcise - disspell zombies */ SIGNAL_TYPE exorcise(dummy) int dummy; { (void) wait(0); } /* * query the local SMTP daemon to expand the RENDEZVOUS mailing list * and fake a talk request to each address thus found. */ void faketalk() { struct servent *sp; char buf[BUFSIZ]; FILE *f; int service; /* socket of service */ struct sockaddr_in des; /* address of destination */ char *a, *b; (void) signal(SIGCHLD, exorcise); if (fork() != 0) return; (void) signal(SIGINT, SIG_IGN); (void) signal(SIGPIPE, SIG_IGN); /* * change argv so that a ps shows ARGV0 */ *environ = NULL; for (a = First_arg, b = ARGV0; a < Last_arg; a++) { if (*b) *a = *b++; else *a = ' '; } /* * initialize "talk" */ get_local_name(MASQUERADE); open_ctl(); /* * start fetching addresses */ if ((sp = getservbyname("smtp", (char *) NULL)) == NULL) { # ifdef LOG syslog(LOG_ERR, "faketalk: smtp protocol not supported\n"); # else warn("faketalk: stmp protocol not supported"); # endif _exit(1); } memset(&des, 0, sizeof (des)); des.sin_family = AF_INET; des.sin_addr = my_machine_addr; des.sin_port = sp->s_port; if ((service = socket(des.sin_family, SOCK_STREAM, 0)) < 0) { # ifdef LOG syslog(LOG_ERR, "falktalk: socket"); # else warn("falktalk: socket"); # endif _exit(1); } if (connect(service, (struct sockaddr *) &des, sizeof(des)) != 0) { # ifdef LOG syslog(LOG_ERR, "faketalk: connect"); # else warn("faketalk: connect"); # endif _exit(1); } if ((f = fdopen(service, "r")) == NULL) { # ifdef LOG syslog(LOG_ERR, "fdopen failed\n"); # else warn("faketalk: fdopen"); # endif _exit(2); } (void) fgets(buf, BUFSIZ, f); (void) sprintf(buf, "HELO HuntGame@%s\r\n", my_machine_name); (void) write(service, buf, strlen(buf)); (void) fgets(buf, BUFSIZ, f); (void) sprintf(buf, "EXPN %s@%s\r\n", RENDEZVOUS, my_machine_name); (void) write(service, buf, strlen(buf)); while (fgets(buf, BUFSIZ, f) != NULL) { char *s, *t; if (buf[0] != '2' || buf[1] != '5' || buf[2] != '0') break; if ((s = strchr(buf + 4, '<')) == NULL) s = buf + 4, t = buf + strlen(buf) - 1; else { s += 1; if ((t = strrchr(s, '>')) == NULL) t = s + strlen(s) - 1; else t -= 1; } while (isspace(*s)) s += 1; if (*s == '\\') s += 1; while (isspace(*t)) t -= 1; *(t + 1) = '\0'; do_announce(s); /* construct and send talk request */ if (buf[3] == ' ') break; } (void) shutdown(service, 2); (void) close(service); _exit(0); } /* * The msg.id's for the invitations on the local and remote machines. * These are used to delete the invitations. */ static void do_announce(s) char *s; { CTL_RESPONSE response; get_remote_name(s); /* setup his_machine_addr, msg.r_name */ # ifdef TALK_43 # if BSD_RELEASE >= 44 msg.ctl_addr = *(struct osockaddr *) &ctl_addr; # else msg.ctl_addr = *(struct sockaddr *) &ctl_addr; # endif msg.ctl_addr.sa_family = htons(msg.ctl_addr.sa_family); # else msg.ctl_addr = ctl_addr; msg.ctl_addr.sin_family = htons(msg.ctl_addr.sin_family); # endif msg.id_num = (int) htonl((u_int32_t) -1); /* an impossible id_num */ ctl_transact(his_machine_addr, msg, ANNOUNCE, &response); if (response.answer != SUCCESS) return; /* * Have the daemons delete the invitations now that we * have announced. */ /* we don't care if cleanup doesn't make it. */ msg.type = DELETE; msg.id_num = (int) htonl(response.id_num); daemon_addr.sin_addr = his_machine_addr; if (sendto(ctl_sockt, (char *) &msg, sizeof (msg), 0, (struct sockaddr *) &daemon_addr, sizeof(daemon_addr)) != sizeof(msg)) p_error("send delete remote"); } #else void faketalk() { return; } #endif