(linenum→info "unix/slp.c:2238")

bsd-games/2.17/hunt/huntd/faketalk.c

    1: /*      $NetBSD: faketalk.c,v 1.10 2004/02/08 22:23:50 jsm Exp $     */
    2: /*
    3:  * Copyright (c) 1983-2003, Regents of the University of California.
    4:  * All rights reserved.
    5:  * 
    6:  * Redistribution and use in source and binary forms, with or without 
    7:  * modification, are permitted provided that the following conditions are 
    8:  * met:
    9:  * 
   10:  * + Redistributions of source code must retain the above copyright 
   11:  *   notice, this list of conditions and the following disclaimer.
   12:  * + Redistributions in binary form must reproduce the above copyright 
   13:  *   notice, this list of conditions and the following disclaimer in the 
   14:  *   documentation and/or other materials provided with the distribution.
   15:  * + Neither the name of the University of California, San Francisco nor 
   16:  *   the names of its contributors may be used to endorse or promote 
   17:  *   products derived from this software without specific prior written 
   18:  *   permission.
   19:  * 
   20:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
   21:  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
   22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
   23:  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
   24:  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
   25:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
   26:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
   27:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
   28:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
   29:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
   30:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31:  */
   32: 
   33: #include <sys/cdefs.h>
   34: #ifndef lint
   35: __RCSID("$NetBSD: faketalk.c,v 1.10 2004/02/08 22:23:50 jsm Exp $");
   36: #endif /* not lint */
   37: 
   38: #include "bsd.h"
   39: #include "hunt.h"
   40: 
   41: #if     defined(TALK_43) || defined(TALK_42)
   42: 
   43: # include       <sys/time.h>
   44: # include       <sys/wait.h>
   45: # include       <ctype.h>
   46: # include       <netdb.h>
   47: # include       <signal.h>
   48: # include       <stdio.h>
   49: # include       <string.h>
   50: # include       <unistd.h>
   51: # include       "talk_ctl.h"
   52: 
   53: # define        TRUE           1
   54: # define        FALSE          0
   55: 
   56: /* defines for fake talk message to announce start of game */
   57: # ifdef TALK_43
   58: # define        MASQUERADE     "\"Hunt Game\""
   59: # else
   60: # define        MASQUERADE     "HuntGame"
   61: # endif
   62: # define        RENDEZVOUS     "hunt-players"
   63: # define        ARGV0          "HUNT-ANNOUNCE"
   64: 
   65: extern  char             *my_machine_name;
   66: extern  char             *First_arg, *Last_arg;
   67: extern  char             **environ;
   68: 
   69: static  void     do_announce(char *);
   70: SIGNAL_TYPE     exorcise(int);
   71: /*
   72:  *      exorcise - disspell zombies
   73:  */
   74: 
   75: SIGNAL_TYPE
   76: exorcise(dummy)
   77:         int dummy __attribute__((__unused__));
   78: {
   79:         (void) wait(0);
   80: }
   81: 
   82: /*
   83:  *      query the local SMTP daemon to expand the RENDEZVOUS mailing list
   84:  *      and fake a talk request to each address thus found.
   85:  */
   86: 
   87: void
   88: faketalk()
   89: {
   90:         struct servent         *sp;
   91:         char                   buf[BUFSIZ];
   92:         FILE                   *f;
   93:         int                    service; /* socket of service */
   94:         struct sockaddr_in     des;                /* address of destination */
   95:         char                   *a;
   96:         const char             *b;
   97: 
   98:         (void) signal(SIGCHLD, exorcise);
   99: 
  100:         if (fork() != 0)
  101:                 return;
  102: 
  103:         (void) signal(SIGINT, SIG_IGN);
  104:         (void) signal(SIGPIPE, SIG_IGN);
  105: 
  106:         /*
  107:          *     change argv so that a ps shows ARGV0
  108:          */
  109:         *environ = NULL;
  110:         for (a = First_arg, b = ARGV0; a < Last_arg; a++) {
  111:                 if (*b)
  112:                         *a = *b++;
  113:                 else
  114:                         *a = ' ';
  115:         }
  116: 
  117:         /*
  118:          *     initialize "talk"
  119:          */
  120:         get_local_name(MASQUERADE);
  121:         open_ctl();
  122: 
  123:         /*
  124:          *     start fetching addresses
  125:          */
  126: 
  127:         if ((sp = getservbyname("smtp", (char *) NULL)) == NULL) {
  128: # ifdef LOG
  129:                 syslog(LOG_ERR, "faketalk: smtp protocol not supported\n");
  130: # else
  131:                 warn("faketalk: smtp protocol not supported");
  132: # endif
  133:                 _exit(1);
  134:         }
  135: 
  136:         memset(&des, 0, sizeof (des));
  137:         des.sin_family = AF_INET;
  138:         des.sin_addr = my_machine_addr;
  139:         des.sin_port = sp->s_port;
  140: 
  141:         if ((service = socket(des.sin_family, SOCK_STREAM, 0)) < 0) {
  142: # ifdef LOG
  143:                 syslog(LOG_ERR, "falktalk:  socket");
  144: # else
  145:                 warn("falktalk:  socket");
  146: # endif
  147:                 _exit(1);
  148:         }
  149: 
  150:         if (connect(service, (struct sockaddr *) &des, sizeof(des)) != 0) {
  151: # ifdef LOG
  152:                 syslog(LOG_ERR, "faketalk:  connect");
  153: # else
  154:                 warn("faketalk:  connect");
  155: # endif
  156:                 _exit(1);
  157:         }
  158:         if ((f = fdopen(service, "r")) == NULL) {
  159: # ifdef LOG
  160:                 syslog(LOG_ERR, "fdopen failed\n");
  161: # else
  162:                 warn("faketalk:  fdopen");
  163: # endif
  164:                 _exit(2);
  165:         }
  166: 
  167:         (void) fgets(buf, BUFSIZ, f);
  168:         (void) sprintf(buf, "HELO HuntGame@%s\r\n", my_machine_name);
  169:         (void) write(service, buf, strlen(buf));
  170:         (void) fgets(buf, BUFSIZ, f);
  171:         (void) sprintf(buf, "EXPN %s@%s\r\n", RENDEZVOUS, my_machine_name);
  172:         (void) write(service, buf, strlen(buf));
  173:         while (fgets(buf, BUFSIZ, f) != NULL) {
  174:                 char  *s, *t;
  175: 
  176:                 if (buf[0] != '2' || buf[1] != '5' || buf[2] != '0')
  177:                         break;
  178:                 if ((s = strchr(buf + 4, '<')) == NULL)
  179:                         s = buf + 4, t = buf + strlen(buf) - 1;
  180:                 else {
  181:                         s += 1;
  182:                         if ((t = strrchr(s, '>')) == NULL)
  183:                                 t = s + strlen(s) - 1;
  184:                         else
  185:                                 t -= 1;
  186:                 }
  187:                 while (isspace(*s))
  188:                         s += 1;
  189:                 if (*s == '\\')
  190:                         s += 1;
  191:                 while (isspace(*t))
  192:                         t -= 1;
  193:                 *(t + 1) = '\0';
  194:                 do_announce(s);               /* construct and send talk request */
  195:                 if (buf[3] == ' ')
  196:                         break;
  197:         }
  198:         (void) shutdown(service, 2);
  199:         (void) close(service);
  200:         _exit(0);
  201: }
  202: 
  203: /*
  204:  * The msg.id's for the invitations on the local and remote machines.
  205:  * These are used to delete the invitations.
  206:  */
  207: 
  208: static void
  209: do_announce(s)
  210:         char   *s;
  211: {
  212:         CTL_RESPONSE                   response;
  213: 
  214:         get_remote_name(s);    /* setup his_machine_addr, msg.r_name */
  215: 
  216: # ifdef TALK_43
  217: # if BSD_RELEASE >= 44
  218:         msg.ctl_addr = *(struct osockaddr *) &ctl_addr;
  219: # else
  220:         msg.ctl_addr = *(struct sockaddr *) &ctl_addr;
  221: # endif
  222:         msg.ctl_addr.sa_family = htons(msg.ctl_addr.sa_family);
  223: # else
  224:         msg.ctl_addr = ctl_addr;
  225:         msg.ctl_addr.sin_family = htons(msg.ctl_addr.sin_family);
  226: # endif
  227:         msg.id_num = (int) htonl((u_int32_t) -1);      /* an impossible id_num */
  228:         ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
  229:         if (response.answer != SUCCESS)
  230:                 return;
  231: 
  232:         /*
  233:          * Have the daemons delete the invitations now that we
  234:          * have announced.
  235:          */
  236: 
  237:         /* we don't care if cleanup doesn't make it. */
  238:         msg.type = DELETE;
  239:         msg.id_num = (int) htonl(response.id_num);
  240:         daemon_addr.sin_addr = his_machine_addr;
  241:         if (sendto(ctl_sockt, (char *) &msg, sizeof (msg), 0,
  242:                         (struct sockaddr *) &daemon_addr, sizeof(daemon_addr))
  243:                         != sizeof(msg))
  244:                 p_error("send delete remote");
  245: }
  246: #else
  247: void
  248: faketalk()
  249: {
  250:         return;
  251: }
  252: #endif
Syntax (Markdown)