summaryrefslogtreecommitdiffstats
path: root/hunt/huntd/faketalk.c
diff options
context:
space:
mode:
Diffstat (limited to 'hunt/huntd/faketalk.c')
-rw-r--r--hunt/huntd/faketalk.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/hunt/huntd/faketalk.c b/hunt/huntd/faketalk.c
new file mode 100644
index 00000000..2a50c3dd
--- /dev/null
+++ b/hunt/huntd/faketalk.c
@@ -0,0 +1,217 @@
+/*
+ * Hunt
+ * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
+ * San Francisco, California
+ *
+ * Copyright (c) 1985 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#include "bsd.h"
+
+#if defined(TALK_43) || defined(TALK_42)
+
+# include <stdio.h>
+# include <string.h>
+# include <netdb.h>
+# include "talk_ctl.h"
+# include <ctype.h>
+# include <signal.h>
+# include <sys/time.h>
+extern int errno;
+
+# 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;
+
+/*
+ * exorcise - disspell zombies
+ */
+
+SIGNAL_TYPE
+exorcise()
+{
+ (void) wait(0);
+}
+
+/*
+ * query the local SMTP daemon to expand the RENDEZVOUS mailing list
+ * and fake a talk request to each address thus found.
+ */
+
+faketalk()
+{
+ struct servent *sp;
+ char buf[BUFSIZ];
+ FILE *f;
+ int service; /* socket of service */
+ struct sockaddr_in des; /* address of destination */
+ char *a, *b;
+ extern char **environ;
+
+ (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
+ fprintf(stderr, "faketalk: stmp protocol not supported\n");
+# 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
+ perror("falktalk: socket");
+# endif
+ _exit(-1);
+ }
+
+ if (connect(service, (struct sockaddr *) &des, sizeof(des)) != 0) {
+# ifdef LOG
+ syslog(LOG_ERR, "faketalk: connect");
+# else
+ perror("faketalk: connect");
+# endif
+ _exit(-1);
+ }
+ if ((f = fdopen(service, "r")) == NULL) {
+# ifdef LOG
+ syslog(LOG_ERR, "fdopen failed\n");
+# else
+ fprintf(stderr, "fdopen failed\n");
+# 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.
+ */
+
+do_announce(s)
+ char *s;
+{
+ CTL_RESPONSE response;
+ extern struct sockaddr_in ctl_addr;
+
+ 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_long) -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
+faketalk()
+{
+ return;
+}
+#endif