home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8708 / 10 < prev    next >
Encoding:
Internet Message Format  |  1990-07-13  |  26.4 KB

  1. From: forys@boulder.Colorado.EDU (Jeff Forys)
  2. Newsgroups: comp.sources.misc
  3. Subject: talk(1) enhancements (2 of 2)
  4. Message-ID: <4115@ncoast.UUCP>
  5. Date: 11 Aug 87 00:16:31 GMT
  6. Sender: allbery@ncoast.UUCP
  7. Organization: University of Colorado, Boulder
  8. Lines: 932
  9. Approved: allbery@ncoast.UUCP
  10. X-Archive: comp.sources.misc/8708/10
  11.  
  12. What follows is a set of patches that will enhance `talk' as
  13. distributed with 4.3BSD.  No functionality is lost if these patches
  14. are applied (i.e. it is still compatible with other machines who
  15. run stock 4.3BSD talk).  Here is a summary of what the patches do:
  16.  
  17.     1) Fix a bug in 4.3BSD talk which results in bogus error
  18.        messages being displayed under various circumstances.
  19.        I posted this fix back in November, everyone should
  20.        apply it, hence it is separate from the `enhancements'.
  21.  
  22.     2) Makes the 4.3BSD version of talk portable to the following
  23.        flavours of Unix: Pyramid (OSx2.5,OSx3.1,OSx4.0), Ultrix (1.2),
  24.        Sun (3.0,3.1,3.2).  This is nice, since few of these speak the
  25.        4.3BSD talk protocol; it'll probably port to 4.2BSD with OSx2.5.
  26.  
  27.     3) Allow for special control codes to be expanded locally.
  28.        (e.g. ^A maps into "<go ahead>", ^N displays a menu, etc)
  29.        While it is possible to send the *mappings* out to people
  30.        not running these enhancements, doing it `right' requires
  31.        awful code (e.g. some control chars are only meaningful
  32.        locally and shouldnt be sent).  Instead, because of #2
  33.        above (easy portability), we simply run it everywhere here.
  34.  
  35.     4) Resolve internet addresses (e.g. 128.138.240.1) so that
  36.        things like `talk user@128.138.240.1' will work, and
  37.        talkd may display "respond with: talk user@128.138.240.1".
  38.        (this is good for internet hosts that dont yet run a
  39.        nameserver, and dont have up-to-date /etc/hosts files)
  40.  
  41.     5) If a person you are trying to contact has messages off,
  42.        and they have a file called ".busy" in their home directory,
  43.        it will be sent to you and displayed in their half of the
  44.        screen.  The file generally contains the `reason' your
  45.        messages are off.
  46.  
  47.     6) A "dumb terminal" interface called `chat'.  This is good
  48.        for consoles and terminals without termcaps.  `chat' is
  49.        hard-linked to `talk' and each does the right thing.
  50.  
  51.     7) A revised manual page explaining these enhancements.
  52.  
  53. One thing that would be easy to add to the talk daemon, and probably will
  54. be added in the future (if you or I ever get the time) is a ".talkrc" file
  55. that would contain options to:
  56.  
  57.     1) list people you will talk to (when your messages are off).
  58.     2) list people who you wont talk to even though your messages are on.
  59.  
  60. I have tested these `enhancements' under many circumstances for
  61. compatibility with 4.3BSD.  Most of these mods have been running for
  62. a couple years and I've fixed any little bugs that have since appeared.
  63. Finally, this is available via anonymous ftp from boulder.Colorado.EDU.
  64.  
  65. What follows, is a shar archive containing the files:
  66.  
  67.     4.3talk_fix   - a fix that should be applied to every 4.3BSD talk.
  68.     talk.1_diffs  - patch to /usr/man/man1/talk.1 (move the patched
  69.             file to /usr/src/ucb/talk/talk.1 for `make install')
  70.     talk_diffs    - patches for talk; cd /usr/src/ucb/talk & patch...
  71.     talkd_diffs   - patches for talkd; cd /usr/src/etc/talkd & patch...
  72.     talkd.h_diffs - patch to /usr/include/protocols/talkd.h
  73.  
  74. [I split talkd_diffs into a separate file because of the 64K message limit
  75. on some machines.  ++bsa]
  76.  
  77. If you make any changes or fix a bug, please let me know... thanks!
  78. ---
  79. Jeff Forys @ UC/Boulder Engineering Research Comp Cntr (303-492-4991)
  80. forys@boulder.Colorado.Edu  -or-  ..!{hao|nbires}!boulder!forys
  81.  
  82. #--------------------------------CUT HERE-------------------------------------
  83. #! /bin/sh
  84. #
  85. # This is a shell archive.  Save this into a file, edit it
  86. # and delete all lines above this comment.  Then give this
  87. # file to sh by executing the command "sh file".  The files
  88. # will be extracted into the current directory owned by
  89. # you with default permissions.
  90. #
  91. # The files contained herein are:
  92. #
  93. # -rw-r--r--   1 allbery  System     21740 Aug 10 20:03 talkd_diffs
  94. #
  95. echo 'x - talkd_diffs'
  96. if test -f talkd_diffs; then echo 'shar: not overwriting talkd_diffs'; else
  97. sed 's/^X//' << '________This_Is_The_END________' > talkd_diffs
  98. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:15 1987
  99. X--- Makefile    Fri Aug  7 17:40:42 1987
  100. X***************
  101. X*** 3,14 ****
  102. X  # All rights reserved.  The Berkeley software License Agreement
  103. X  # specifies the terms and conditions for redistribution.
  104. X  #
  105. X! #    @(#)Makefile    5.4 (Berkeley) 3/13/86
  106. X  #
  107. X! DESTDIR=
  108. X  OBJS=    talkd.o announce.o process.o table.o print.o
  109. X  SRCS=    talkd.c announce.c process.c table.c print.c
  110. X- CFLAGS= -O
  111. X  
  112. X  all:    talkd
  113. X  
  114. X--- 3,56 ----
  115. X  # All rights reserved.  The Berkeley software License Agreement
  116. X  # specifies the terms and conditions for redistribution.
  117. X  #
  118. X! #    @(#)Makefile    5.4.1 (Berkeley) 3/13/86
  119. X  #
  120. X! 
  121. X! #    Sun Jan 11 20:08:22 MST 1987    JEF    forys@Boulder.Colorado.Edu
  122. X! #    Conditional compilations for different machines...
  123. X! #
  124. X! #    4.3 BSD
  125. X! CFLAGS=-O
  126. X! DESTDIR=/etc/ntalkd
  127. X! #
  128. X! #    Pyramid OSx2.5
  129. X! #CFLAGS=-O -DPYRAMID -DNO_INETD
  130. X! #DESTDIR=/etc/ntalkd
  131. X! #
  132. X! #    Pyramid OSx3.1
  133. X! #CFLAGS=-O -DPYRAMID
  134. X! #DESTDIR=/usr/etc/in.ntalkd
  135. X! #
  136. X! #    Pyramid OSx4.0
  137. X! #CFLAGS=-O -DPYRAMID -DBSD4_3
  138. X! #DESTDIR=/etc/ntalkd
  139. X! #
  140. X! #    Sun 3.1, 3.0
  141. X! #CFLAGS=-O -DSUN3_1
  142. X! #DESTDIR=/usr/etc/in.ntalkd
  143. X! #
  144. X! #    Sun 3.2
  145. X! #CFLAGS=-O -DSUN3_2
  146. X! #DESTDIR=/usr/etc/in.ntalkd
  147. X! #
  148. X! #    Ultrix 1.2
  149. X! #CFLAGS=-O -DULTRIX1_2
  150. X! #DESTDIR=/etc/ntalkd
  151. X! #
  152. X! #    If you are trying to get this to run under a different
  153. X! #    system, the following should help:
  154. X! #        NO_INETD - compile in code to listen for connections
  155. X! #        PYRAMID - defines for byte order stuff, old syslog, 
  156. X! #        SUN3_1 - old 4.2 syslog
  157. X! #        SUN3_2 - old 4.2 syslog
  158. X! #        ULTRIX1_2 - old 4.2 syslog
  159. X! #    We no longer have 4.2BSD machines around, but I'm sure they'll
  160. X! #    need NO_INETD and the old syslog stuff...
  161. X! 
  162. X! MANDIR=/usr/man/man1
  163. X! 
  164. X  OBJS=    talkd.o announce.o process.o table.o print.o
  165. X  SRCS=    talkd.c announce.c process.c table.c print.c
  166. X  
  167. X  all:    talkd
  168. X  
  169. X***************
  170. X*** 16,22 ****
  171. X      cc ${CFLAGS} -o talkd ${OBJS}
  172. X  
  173. X  install: talkd
  174. X!     install -s talkd ${DESTDIR}/etc/ntalkd
  175. X  
  176. X  clean:
  177. X      rm -f ${OBJS} errs core a.out talkd
  178. X--- 58,64 ----
  179. X      cc ${CFLAGS} -o talkd ${OBJS}
  180. X  
  181. X  install: talkd
  182. X!     install -s talkd ${DESTDIR}
  183. X  
  184. X  clean:
  185. X      rm -f ${OBJS} errs core a.out talkd
  186. X***************
  187. X*** 26,32 ****
  188. X  
  189. X  depend: ${SRCS}
  190. X      for i in ${SRCS}; do \
  191. X!         cc -M $$i | sed 's/\.o//' | \
  192. X          awk ' { if ($$1 != prev) \
  193. X          { if (rec != "") print rec; rec = $$0; prev = $$1; } \
  194. X          else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  195. X--- 68,74 ----
  196. X  
  197. X  depend: ${SRCS}
  198. X      for i in ${SRCS}; do \
  199. X!         cc -M ${CFLAGS} $$i | sed 's/\.o//' | \
  200. X          awk ' { if ($$1 != prev) \
  201. X          { if (rec != "") print rec; rec = $$0; prev = $$1; } \
  202. X          else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  203. X***************
  204. X*** 52,63 ****
  205. X  announce: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h
  206. X  announce: /usr/include/sys/ioctl.h /usr/include/sys/time.h /usr/include/time.h
  207. X  announce: /usr/include/stdio.h /usr/include/sys/wait.h /usr/include/errno.h
  208. X! announce: /usr/include/syslog.h /usr/include/protocols/talkd.h
  209. X! announce: /usr/include/sys/types.h /usr/include/sys/socket.h
  210. X  process: process.c /usr/include/sys/types.h /usr/include/sys/stat.h
  211. X  process: /usr/include/stdio.h /usr/include/syslog.h /usr/include/netdb.h
  212. X! process: /usr/include/netinet/in.h /usr/include/protocols/talkd.h
  213. X! process: /usr/include/sys/types.h /usr/include/sys/socket.h /usr/include/utmp.h
  214. X  table: table.c /usr/include/stdio.h /usr/include/sys/time.h /usr/include/time.h
  215. X  table: /usr/include/syslog.h /usr/include/protocols/talkd.h
  216. X  table: /usr/include/sys/types.h /usr/include/sys/socket.h
  217. X--- 94,109 ----
  218. X  announce: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h
  219. X  announce: /usr/include/sys/ioctl.h /usr/include/sys/time.h /usr/include/time.h
  220. X  announce: /usr/include/stdio.h /usr/include/sys/wait.h /usr/include/errno.h
  221. X! announce: /usr/include/syslog.h /usr/include/strings.h /usr/include/pwd.h
  222. X! announce: /usr/include/protocols/talkd.h /usr/include/sys/types.h
  223. X! announce: /usr/include/sys/socket.h
  224. X  process: process.c /usr/include/sys/types.h /usr/include/sys/stat.h
  225. X  process: /usr/include/stdio.h /usr/include/syslog.h /usr/include/netdb.h
  226. X! process: /usr/include/netinet/in.h /usr/include/sys/param.h
  227. X! process: /usr/include/machine/machparam.h /usr/include/signal.h
  228. X! process: /usr/include/sys/types.h /usr/include/protocols/talkd.h
  229. X! process: /usr/include/sys/types.h /usr/include/sys/socket.h
  230. X! process: /usr/include/arpa/inet.h /usr/include/utmp.h
  231. X  table: table.c /usr/include/stdio.h /usr/include/sys/time.h /usr/include/time.h
  232. X  table: /usr/include/syslog.h /usr/include/protocols/talkd.h
  233. X  table: /usr/include/sys/types.h /usr/include/sys/socket.h
  234. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:18 1987
  235. X--- announce.c    Fri Aug  7 17:40:46 1987
  236. X***************
  237. X*** 17,25 ****
  238. X--- 17,34 ----
  239. X  #include <sys/wait.h>
  240. X  #include <errno.h>
  241. X  #include <syslog.h>
  242. X+ #include <strings.h>
  243. X+ #include <pwd.h>
  244. X  
  245. X  #include <protocols/talkd.h>
  246. X  
  247. X+ #if PYRAMID
  248. X+ #define    ntohl(x)    (x)
  249. X+ #define    ntohs(x)    (x)
  250. X+ #define    htonl(x)    (x)
  251. X+ #define    htons(x)    (x)
  252. X+ #endif
  253. X+ 
  254. X  extern    int errno;
  255. X  extern    char hostname[];
  256. X  
  257. X***************
  258. X*** 30,45 ****
  259. X   * process to any terminal that it writes on, we must fork a child
  260. X   * to protect ourselves
  261. X   */
  262. X! announce(request, remote_machine)
  263. X      CTL_MSG *request;
  264. X      char *remote_machine;
  265. X  {
  266. X      int pid, val, status;
  267. X  
  268. X      if (pid = fork()) {
  269. X          /* we are the parent, so wait for the child */
  270. X!         if (pid == -1)        /* the fork failed */
  271. X              return (FAILED);
  272. X          do {
  273. X              val = wait(&status);
  274. X              if (val == -1) {
  275. X--- 39,63 ----
  276. X   * process to any terminal that it writes on, we must fork a child
  277. X   * to protect ourselves
  278. X   */
  279. X! announce(request, remote_machine, busy)
  280. X      CTL_MSG *request;
  281. X      char *remote_machine;
  282. X+     CTL_BUSY *busy;
  283. X  {
  284. X      int pid, val, status;
  285. X+     int fd[2];
  286. X  
  287. X+     if (pipe(fd) < 0)    /* need a pipe to return .busy from child */
  288. X+         return(FAILED);
  289. X+ 
  290. X      if (pid = fork()) {
  291. X          /* we are the parent, so wait for the child */
  292. X!         if (pid == -1) {    /* the fork failed */
  293. X!             close(fd[0]);
  294. X!             close(fd[1]);
  295. X              return (FAILED);
  296. X+         }
  297. X+ 
  298. X          do {
  299. X              val = wait(&status);
  300. X              if (val == -1) {
  301. X***************
  302. X*** 46,71 ****
  303. X                  if (errno == EINTR)
  304. X                      continue;
  305. X                  /* shouldn't happen */
  306. X                  syslog(LOG_WARNING, "announce: wait: %m");
  307. X                  return (FAILED);
  308. X              }
  309. X          } while (val != pid);
  310. X!         if (status&0377 > 0)    /* we were killed by some signal */
  311. X              return (FAILED);
  312. X          /* Get the second byte, this is the exit/return code */
  313. X!         return ((status >> 8) & 0377);
  314. X      }
  315. X      /* we are the child, go and do it */
  316. X!     _exit(announce_proc(request, remote_machine));
  317. X  }
  318. X!     
  319. X  /*
  320. X   * See if the user is accepting messages. If so, announce that 
  321. X   * a talk is requested.
  322. X   */
  323. X! announce_proc(request, remote_machine)
  324. X      CTL_MSG *request;
  325. X      char *remote_machine;
  326. X  {
  327. X      int pid, status;
  328. X      char full_tty[32];
  329. X--- 64,101 ----
  330. X                  if (errno == EINTR)
  331. X                      continue;
  332. X                  /* shouldn't happen */
  333. X+                 close(fd[0]);
  334. X+                 close(fd[1]);
  335. X                  syslog(LOG_WARNING, "announce: wait: %m");
  336. X                  return (FAILED);
  337. X              }
  338. X          } while (val != pid);
  339. X!         if (status&0377 > 0) {    /* we were killed by some signal */
  340. X!             close(fd[0]);
  341. X!             close(fd[1]);
  342. X              return (FAILED);
  343. X+         }
  344. X          /* Get the second byte, this is the exit/return code */
  345. X!         status = (status >> 8) & 0377;
  346. X! 
  347. X!         if (status == PERMISSION_DENIED)    /* get .busy file */
  348. X!             get_busy(fd[0], busy);
  349. X!         close(fd[0]);
  350. X!         close(fd[1]);
  351. X!         return(status);
  352. X      }
  353. X      /* we are the child, go and do it */
  354. X!     _exit(announce_proc(request, remote_machine, fd[1]));
  355. X  }
  356. X! 
  357. X  /*
  358. X   * See if the user is accepting messages. If so, announce that 
  359. X   * a talk is requested.
  360. X   */
  361. X! announce_proc(request, remote_machine, fd_write)
  362. X      CTL_MSG *request;
  363. X      char *remote_machine;
  364. X+     int fd_write;
  365. X  {
  366. X      int pid, status;
  367. X      char full_tty[32];
  368. X***************
  369. X*** 75,82 ****
  370. X      sprintf(full_tty, "/dev/%s", request->r_tty);
  371. X      if (access(full_tty, 0) != 0)
  372. X          return (FAILED);
  373. X!     if ((tf = fopen(full_tty, "w")) == NULL)
  374. X          return (PERMISSION_DENIED);
  375. X      /*
  376. X       * On first tty open, the server will have
  377. X       * it's pgrp set, so disconnect us from the
  378. X--- 105,114 ----
  379. X      sprintf(full_tty, "/dev/%s", request->r_tty);
  380. X      if (access(full_tty, 0) != 0)
  381. X          return (FAILED);
  382. X!     if ((tf = fopen(full_tty, "w")) == NULL) {
  383. X!         refuse(request->r_name, fd_write);
  384. X          return (PERMISSION_DENIED);
  385. X+     }
  386. X      /*
  387. X       * On first tty open, the server will have
  388. X       * it's pgrp set, so disconnect us from the
  389. X***************
  390. X*** 83,92 ****
  391. X       * tty before we catch a signal.
  392. X       */
  393. X      ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
  394. X!     if (fstat(fileno(tf), &stbuf) < 0)
  395. X          return (PERMISSION_DENIED);
  396. X!     if ((stbuf.st_mode&020) == 0)
  397. X          return (PERMISSION_DENIED);
  398. X      print_mesg(tf, request, remote_machine);
  399. X      fclose(tf);
  400. X      return (SUCCESS);
  401. X--- 115,128 ----
  402. X       * tty before we catch a signal.
  403. X       */
  404. X      ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
  405. X!     if (fstat(fileno(tf), &stbuf) < 0) {
  406. X!         refuse(request->r_name, fd_write);
  407. X          return (PERMISSION_DENIED);
  408. X!     }
  409. X!     if ((stbuf.st_mode&020) == 0) {
  410. X!         refuse(request->r_name, fd_write);
  411. X          return (PERMISSION_DENIED);
  412. X+     }
  413. X      print_mesg(tf, request, remote_machine);
  414. X      fclose(tf);
  415. X      return (SUCCESS);
  416. X***************
  417. X*** 154,161 ****
  418. X          while (*lptr != '\0')
  419. X              *(bptr++) = *(lptr++);
  420. X          /* pad out the rest of the lines with blanks */
  421. X!         for (j = sizes[i]; j < max_size + 2; j++)
  422. X              *(bptr++) = ' ';
  423. X          *(bptr++) = '\r';    /* add a \r in case of raw mode */
  424. X          *(bptr++) = '\n';
  425. X      }
  426. X--- 190,198 ----
  427. X          while (*lptr != '\0')
  428. X              *(bptr++) = *(lptr++);
  429. X          /* pad out the rest of the lines with blanks */
  430. X!         for (j = sizes[i]; j < max_size + 2; j++) {
  431. X              *(bptr++) = ' ';
  432. X+         }
  433. X          *(bptr++) = '\r';    /* add a \r in case of raw mode */
  434. X          *(bptr++) = '\n';
  435. X      }
  436. X***************
  437. X*** 163,166 ****
  438. X--- 200,272 ----
  439. X      fprintf(tf, big_buf);
  440. X      fflush(tf);
  441. X      ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0);
  442. X+ }
  443. X+ 
  444. X+ refuse(r_name, fd_write)    /* try to find out why user is unsociable */
  445. X+ char *r_name;
  446. X+ int fd_write;
  447. X+ {
  448. X+     register FILE *fpr;
  449. X+     char bpth[100];            /* homedirectory/BUSYFLNM */
  450. X+     char bufr[BUSYSIZE];        /* contents of BUSYFLNM */
  451. X+     register int c, i=0;
  452. X+     struct passwd *my_getpwnam();
  453. X+ 
  454. X+     *bufr = '\0';
  455. X+     (void) strcat(strcat(strcpy(bpth, my_getpwnam(r_name)->pw_dir), "/"),
  456. X+               BUSYFLNM);
  457. X+     if ((fpr=fopen(bpth, "r")) != NULL) {    /* file exists */
  458. X+         while ((c=getc(fpr)) != EOF && i<BUSYSIZE-1)
  459. X+             bufr[i++] = c;        /* read file to buffer */
  460. X+         bufr[i] = '\0';
  461. X+         (void) fclose(fpr);
  462. X+     }
  463. X+     (void) write(fd_write, bufr, BUSYSIZE);    /* write to pipe */
  464. X+ }
  465. X+ 
  466. X+ get_busy(fd_read, busy)        /* read from pipe into CTL_BUSY */
  467. X+ int fd_read;
  468. X+ CTL_BUSY *busy;
  469. X+ {
  470. X+     register int i;
  471. X+ 
  472. X+     busy->chksum = (long) 0;    /* We also want a check sum */
  473. X+ 
  474. X+     (void) read(fd_read, busy->busy, BUSYSIZE);    /* Read from pipe */
  475. X+ 
  476. X+     for (i=0; i<BUSYSIZE && busy->busy[i]; i++)    /* Compute checksum */
  477. X+         busy->chksum += (long) busy->busy[i];
  478. X+     busy->chksum = htonl(busy->chksum);
  479. X+ }
  480. X+ 
  481. X+ /*
  482. X+  *    I had to write my own 'getpwnam' because the one that is
  483. X+  *    provided seems to have an obscure bug in it.  The problem
  484. X+  *    was tracked down to 'endpwent' which calls 'dbm_close'
  485. X+  *    which makes a call to 'free' (and promptly dies).  My
  486. X+  *    solution was to simply eliminate the call to 'endpwent'
  487. X+  *    because if this code was executed, the user must have had
  488. X+  *    his messages off and the daemon will die (thus closing the
  489. X+  *    database files).  Even if the daemon doesn't die quickly
  490. X+  *    and this procedure is called again, 'setpwent' knows that
  491. X+  *    the database is still open and just rewinds it.
  492. X+  *
  493. X+  *    Incidentally, when I used 'endpwent', talk responded:
  494. X+  *
  495. X+  *        [No connection yet]
  496. X+  *        [Target machine is too confused to talk to us]
  497. X+  *        <exit>
  498. X+  */
  499. X+ 
  500. X+ struct passwd *my_getpwnam(usrnam)    /* getpwnam without call to endpwent */
  501. X+ char *usrnam;
  502. X+ {
  503. X+     struct passwd *pw;
  504. X+ 
  505. X+     (void) setpwent();        /* Open password file */
  506. X+ 
  507. X+     while ((pw = getpwent()) && strcmp(usrnam, pw->pw_name))
  508. X+         ;    /* Find the right entry */
  509. X+ 
  510. X+     return(pw);    /* It MUST exist (user is logged in), just return it */
  511. X  }
  512. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:21 1987
  513. X--- print.c    Fri Aug  7 17:40:50 1987
  514. X***************
  515. X*** 15,20 ****
  516. X--- 15,27 ----
  517. X  
  518. X  #include <protocols/talkd.h>
  519. X  
  520. X+ #if PYRAMID
  521. X+ #define    ntohl(x)    (x)
  522. X+ #define    ntohs(x)    (x)
  523. X+ #define    htonl(x)    (x)
  524. X+ #define    htons(x)    (x)
  525. X+ #endif
  526. X+ 
  527. X  static    char *types[] =
  528. X      { "leave_invite", "look_up", "delete", "announce" };
  529. X  #define    NTYPES    (sizeof (types) / sizeof (types[0]))
  530. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:24 1987
  531. X--- process.c    Fri Aug  7 17:40:55 1987
  532. X***************
  533. X*** 22,37 ****
  534. X  #include <syslog.h>
  535. X  #include <netdb.h>
  536. X  #include <netinet/in.h>
  537. X  
  538. X  #include <protocols/talkd.h>
  539. X  
  540. X  char    *strcpy();
  541. X  CTL_MSG *find_request();
  542. X  CTL_MSG *find_match();
  543. X  
  544. X! process_request(mp, rp)
  545. X      register CTL_MSG *mp;
  546. X      register CTL_RESPONSE *rp;
  547. X  {
  548. X      register CTL_MSG *ptr;
  549. X      extern int debug;
  550. X--- 22,48 ----
  551. X  #include <syslog.h>
  552. X  #include <netdb.h>
  553. X  #include <netinet/in.h>
  554. X+ #include <sys/param.h>
  555. X  
  556. X  #include <protocols/talkd.h>
  557. X  
  558. X+ #if PYRAMID
  559. X+ #define    ntohl(x)    (x)
  560. X+ #define    ntohs(x)    (x)
  561. X+ #define    htonl(x)    (x)
  562. X+ #define    htons(x)    (x)
  563. X+ #else /* I wont explain this one; simply believe me -- pyramids hate it */
  564. X+ #include <arpa/inet.h>
  565. X+ #endif
  566. X+ 
  567. X  char    *strcpy();
  568. X  CTL_MSG *find_request();
  569. X  CTL_MSG *find_match();
  570. X  
  571. X! process_request(mp, rp, busy)
  572. X      register CTL_MSG *mp;
  573. X      register CTL_RESPONSE *rp;
  574. X+     CTL_BUSY *busy;
  575. X  {
  576. X      register CTL_MSG *ptr;
  577. X      extern int debug;
  578. X***************
  579. X*** 38,44 ****
  580. X  
  581. X      rp->vers = TALK_VERSION;
  582. X      rp->type = mp->type;
  583. X!     rp->id_num = htonl(0);
  584. X      if (mp->vers != TALK_VERSION) {
  585. X          syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  586. X          rp->answer = BADVERSION;
  587. X--- 49,55 ----
  588. X  
  589. X      rp->vers = TALK_VERSION;
  590. X      rp->type = mp->type;
  591. X!     rp->id_num = htonl((long)0);
  592. X      if (mp->vers != TALK_VERSION) {
  593. X          syslog(LOG_WARNING, "Bad protocol version %d", mp->vers);
  594. X          rp->answer = BADVERSION;
  595. X***************
  596. X*** 65,71 ****
  597. X      switch (mp->type) {
  598. X  
  599. X      case ANNOUNCE:
  600. X!         do_announce(mp, rp);
  601. X          break;
  602. X  
  603. X      case LEAVE_INVITE:
  604. X--- 76,82 ----
  605. X      switch (mp->type) {
  606. X  
  607. X      case ANNOUNCE:
  608. X!         do_announce(mp, rp, busy);
  609. X          break;
  610. X  
  611. X      case LEAVE_INVITE:
  612. X***************
  613. X*** 100,108 ****
  614. X          print_response("process_request", rp);
  615. X  }
  616. X  
  617. X! do_announce(mp, rp)
  618. X      register CTL_MSG *mp;
  619. X      CTL_RESPONSE *rp;
  620. X  {
  621. X      struct hostent *hp;
  622. X      CTL_MSG *ptr;
  623. X--- 111,120 ----
  624. X          print_response("process_request", rp);
  625. X  }
  626. X  
  627. X! do_announce(mp, rp, busy)
  628. X      register CTL_MSG *mp;
  629. X      CTL_RESPONSE *rp;
  630. X+     CTL_BUSY *busy;
  631. X  {
  632. X      struct hostent *hp;
  633. X      CTL_MSG *ptr;
  634. X***************
  635. X*** 110,130 ****
  636. X  
  637. X      /* see if the user is logged */
  638. X      result = find_user(mp->r_name, mp->r_tty);
  639. X!     if (result != SUCCESS) {
  640. X          rp->answer = result;
  641. X          return;
  642. X      }
  643. X  #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  644. X!     hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr,
  645. X          sizeof (struct in_addr), AF_INET);
  646. X!     if (hp == (struct hostent *)0) {
  647. X!         rp->answer = MACHINE_UNKNOWN;
  648. X!         return;
  649. X      }
  650. X      ptr = find_request(mp);
  651. X      if (ptr == (CTL_MSG *) 0) {
  652. X          insert_table(mp, rp);
  653. X!         rp->answer = announce(mp, hp->h_name);
  654. X          return;
  655. X      }
  656. X      if (mp->id_num > ptr->id_num) {
  657. X--- 122,164 ----
  658. X  
  659. X      /* see if the user is logged */
  660. X      result = find_user(mp->r_name, mp->r_tty);
  661. X!     if (result != SUCCESS && result != PERMISSION_DENIED) {
  662. X          rp->answer = result;
  663. X          return;
  664. X      }
  665. X  #define    satosin(sa)    ((struct sockaddr_in *)(sa))
  666. X!     hp = gethostbyaddr((char *) &satosin(&mp->ctl_addr)->sin_addr,
  667. X          sizeof (struct in_addr), AF_INET);
  668. X!     if (hp == (struct hostent *) 0) {
  669. X!         static struct hostent def;
  670. X!         static struct in_addr defaddr;
  671. X!         static char *iaddr_str;
  672. X! #ifdef BSD4_3
  673. X!         static char *alist[1];
  674. X! #endif
  675. X!         static char namebuf[128];
  676. X! 
  677. X!         iaddr_str = (char *)inet_ntoa(satosin(&mp->ctl_addr)->sin_addr);
  678. X!         defaddr.s_addr = inet_addr(iaddr_str);
  679. X!         if (defaddr.s_addr == -1) {
  680. X!             rp->answer = MACHINE_UNKNOWN;
  681. X!             return;
  682. X!         }
  683. X!         strcpy(namebuf, iaddr_str);
  684. X!         def.h_name = namebuf;
  685. X! #ifdef BSD4_3
  686. X!         def.h_addr_list = alist,
  687. X! #endif
  688. X!         def.h_addr = (char *)&defaddr;
  689. X!         def.h_length = sizeof (struct in_addr);
  690. X!         def.h_addrtype = AF_INET;
  691. X!         def.h_aliases = 0;
  692. X!         hp = &def;
  693. X      }
  694. X      ptr = find_request(mp);
  695. X      if (ptr == (CTL_MSG *) 0) {
  696. X          insert_table(mp, rp);
  697. X!         rp->answer = announce(mp, hp->h_name, busy);
  698. X          return;
  699. X      }
  700. X      if (mp->id_num > ptr->id_num) {
  701. X***************
  702. X*** 134,140 ****
  703. X           */
  704. X          ptr->id_num = new_id();
  705. X          rp->id_num = htonl(ptr->id_num);
  706. X!         rp->answer = announce(mp, hp->h_name);
  707. X      } else {
  708. X          /* a duplicated request, so ignore it */
  709. X          rp->id_num = htonl(ptr->id_num);
  710. X--- 168,174 ----
  711. X           */
  712. X          ptr->id_num = new_id();
  713. X          rp->id_num = htonl(ptr->id_num);
  714. X!         rp->answer = announce(mp, hp->h_name, busy);
  715. X      } else {
  716. X          /* a duplicated request, so ignore it */
  717. X          rp->id_num = htonl(ptr->id_num);
  718. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:28 1987
  719. X--- table.c    Fri Aug  7 17:40:59 1987
  720. X***************
  721. X*** 22,27 ****
  722. X--- 22,34 ----
  723. X  
  724. X  #include <protocols/talkd.h>
  725. X  
  726. X+ #if PYRAMID
  727. X+ #define    ntohl(x)    (x)
  728. X+ #define    ntohs(x)    (x)
  729. X+ #define    htonl(x)    (x)
  730. X+ #define    htons(x)    (x)
  731. X+ #endif
  732. X+ 
  733. X  #define MAX_ID 16000    /* << 2^15 so I don't have sign troubles */
  734. X  
  735. X  #define NIL ((TABLE_ENTRY *)0)
  736. X*** /tmp/,RCSt1019995    Fri Aug  7 17:43:31 1987
  737. X--- talkd.c    Fri Aug  7 17:41:04 1987
  738. X***************
  739. X*** 27,36 ****
  740. X  
  741. X  #include <protocols/talkd.h>
  742. X  
  743. X  CTL_MSG        request;
  744. X  CTL_RESPONSE    response;
  745. X  
  746. X! int    sockt;
  747. X  int    debug = 0;
  748. X  int    timeout();
  749. X  long    lastmsgtime;
  750. X--- 27,43 ----
  751. X  
  752. X  #include <protocols/talkd.h>
  753. X  
  754. X+ #ifdef NO_INETD
  755. X+ #include <netinet/in.h>
  756. X+ #include <sys/ioctl.h>
  757. X+ #include <netdb.h>
  758. X+ #endif
  759. X+ 
  760. X  CTL_MSG        request;
  761. X  CTL_RESPONSE    response;
  762. X+ CTL_BUSY    busy;
  763. X  
  764. X! int    sockt = 0;
  765. X  int    debug = 0;
  766. X  int    timeout();
  767. X  long    lastmsgtime;
  768. X***************
  769. X*** 37,42 ****
  770. X--- 44,54 ----
  771. X  
  772. X  char    hostname[32];
  773. X  
  774. X+ #ifdef NO_INETD
  775. X+ struct    sockaddr_in sin = { AF_INET };
  776. X+ u_short    port = 0;
  777. X+ #endif
  778. X+ 
  779. X  #define TIMEOUT 30
  780. X  #define MAXIDLE 120
  781. X  
  782. X***************
  783. X*** 44,49 ****
  784. X--- 56,66 ----
  785. X      int argc;
  786. X      char *argv[];
  787. X  {
  788. X+ #ifdef NO_INETD
  789. X+     struct servent *sp, *getservbyname();
  790. X+     struct sockaddr_in from;
  791. X+     int fromlen;
  792. X+ #endif
  793. X      register CTL_MSG *mp = &request;
  794. X      int cc;
  795. X  
  796. X***************
  797. X*** 51,57 ****
  798. X--- 68,79 ----
  799. X          fprintf(stderr, "%s: getuid: not super-user", argv[0]);
  800. X          exit(1);
  801. X      }
  802. X+ #if (SUN3_1 | SUN3_2 | PYRAMID | ULTRIX1_2)
  803. X+     openlog("talkd", LOG_PID);
  804. X+ #else
  805. X      openlog("talkd", LOG_PID, LOG_DAEMON);
  806. X+ #endif
  807. X+ 
  808. X      if (gethostname(hostname, sizeof (hostname) - 1) < 0) {
  809. X          syslog(LOG_ERR, "gethostname: %m");
  810. X          _exit(1);
  811. X***************
  812. X*** 62,73 ****
  813. X      }
  814. X      if (argc > 1 && strcmp(argv[1], "-d") == 0)
  815. X          debug = 1;
  816. X      signal(SIGALRM, timeout);
  817. X      alarm(TIMEOUT);
  818. X      for (;;) {
  819. X          extern int errno;
  820. X  
  821. X!         cc = recv(0, (char *)mp, sizeof (*mp), 0);
  822. X          if (cc != sizeof (*mp)) {
  823. X              if (cc < 0 && errno != EINTR)
  824. X                  syslog(LOG_WARNING, "recv: %m");
  825. X--- 84,130 ----
  826. X      }
  827. X      if (argc > 1 && strcmp(argv[1], "-d") == 0)
  828. X          debug = 1;
  829. X+ 
  830. X+ #ifdef NO_INETD
  831. X+     if ((sp=getservbyname("ntalk", "udp")) == (struct servent *) 0) {
  832. X+         syslog(LOG_ERR, "gethostbyname: %m");
  833. X+         _exit(1);
  834. X+     }
  835. X+     port = sp->s_port;
  836. X+ 
  837. X+     if ((sockt=socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  838. X+         syslog(LOG_ERR, "socket: %m");
  839. X+         _exit(1);
  840. X+     }
  841. X+ 
  842. X+     bzero((char *)&sin, sizeof(sin));
  843. X+     sin.sin_addr.s_addr = INADDR_ANY;
  844. X+     sin.sin_port = port;
  845. X+     sin.sin_family = AF_INET;
  846. X+ 
  847. X+     if (bind(sockt, (caddr_t)&sin, sizeof(sin)) < 0) {
  848. X+         syslog(LOG_ERR, "bind: %m");
  849. X+         _exit(1);
  850. X+     }
  851. X+ 
  852. X+     if (fork())
  853. X+         _exit(0);
  854. X+     setup_descriptors(sockt);
  855. X+ 
  856. X+ #else
  857. X      signal(SIGALRM, timeout);
  858. X      alarm(TIMEOUT);
  859. X+ #endif
  860. X      for (;;) {
  861. X          extern int errno;
  862. X  
  863. X! #ifdef NO_INETD
  864. X!         fromlen = sizeof(from);
  865. X!         cc = recvfrom(sockt, (char *)mp,
  866. X!             sizeof (*mp), 0, &from, &fromlen);
  867. X! #else
  868. X!         cc = recv(sockt, (char *)mp, sizeof (*mp), 0);
  869. X! #endif
  870. X          if (cc != sizeof (*mp)) {
  871. X              if (cc < 0 && errno != EINTR)
  872. X                  syslog(LOG_WARNING, "recv: %m");
  873. X***************
  874. X*** 74,85 ****
  875. X              continue;
  876. X          }
  877. X          lastmsgtime = time(0);
  878. X!         process_request(mp, &response);
  879. X          /* can block here, is this what I want? */
  880. X          cc = sendto(sockt, (char *)&response,
  881. X              sizeof (response), 0, &mp->ctl_addr, sizeof (mp->ctl_addr));
  882. X          if (cc != sizeof (response))
  883. X              syslog(LOG_WARNING, "sendto: %m");
  884. X      }
  885. X  }
  886. X  
  887. X--- 131,151 ----
  888. X              continue;
  889. X          }
  890. X          lastmsgtime = time(0);
  891. X!         process_request(mp, &response, &busy);
  892. X          /* can block here, is this what I want? */
  893. X          cc = sendto(sockt, (char *)&response,
  894. X              sizeof (response), 0, &mp->ctl_addr, sizeof (mp->ctl_addr));
  895. X          if (cc != sizeof (response))
  896. X              syslog(LOG_WARNING, "sendto: %m");
  897. X+ 
  898. X+         if (response.answer == PERMISSION_DENIED) {
  899. X+             /* send reason why this party is refusing messages */
  900. X+ 
  901. X+             cc = sendto(sockt, (char *) &busy, sizeof(busy), 0,
  902. X+                 &request.ctl_addr, sizeof(request.ctl_addr));
  903. X+             if (cc != sizeof(busy))
  904. X+                 syslog(LOG_WARNING, "sendto: %m");
  905. X+         }
  906. X      }
  907. X  }
  908. X  
  909. X***************
  910. X*** 90,92 ****
  911. X--- 156,181 ----
  912. X          _exit(0);
  913. X      alarm(TIMEOUT);
  914. X  }
  915. X+ 
  916. X+ #ifdef NO_INETD
  917. X+ setup_descriptors(sockt)
  918. X+ int sockt;
  919. X+ {
  920. X+     int i, tty;
  921. X+ 
  922. X+     if (sockt != 0)
  923. X+         (void) close(0);
  924. X+ 
  925. X+     i = open("/dev/null", 0);
  926. X+     if (sockt != 1)
  927. X+         (void) dup2(i, 1);
  928. X+     if (sockt != 2)
  929. X+         (void) dup2(i, 2);
  930. X+ 
  931. X+     if ((tty=open("/dev/tty", 0)) != -1) {
  932. X+         ioctl(tty, TIOCNOTTY, (struct sgttyb *) 0);
  933. X+         (void) close(tty);
  934. X+     } else
  935. X+         setpgrp(0, getpid());
  936. X+ }
  937. X+ #endif
  938. ________This_Is_The_END________
  939. if test `wc -l < talkd_diffs` -ne 840; then
  940.     echo 'shar: talkd_diffs was damaged during transit (should have been 840 bytes)'
  941. fi
  942. fi        ; : end of overwriting check
  943. exit 0
  944.