Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!necntc!ncoast!allbery From: forys@boulder.Colorado.EDU (Jeff Forys) Newsgroups: comp.sources.misc Subject: talk(1) enhancements (2 of 2) Message-ID: <4115@ncoast.UUCP> Date: Mon, 10-Aug-87 20:16:31 EDT Article-I.D.: ncoast.4115 Posted: Mon Aug 10 20:16:31 1987 Date-Received: Thu, 13-Aug-87 00:35:49 EDT Sender: allbery@ncoast.UUCP Organization: University of Colorado, Boulder Lines: 932 Keywords: 4.3BSD, patches, compatible, portable Approved: allbery@ncoast.UUCP X-Archive: comp.sources.misc/8708/10 What follows is a set of patches that will enhance `talk' as distributed with 4.3BSD. No functionality is lost if these patches are applied (i.e. it is still compatible with other machines who run stock 4.3BSD talk). Here is a summary of what the patches do: 1) Fix a bug in 4.3BSD talk which results in bogus error messages being displayed under various circumstances. I posted this fix back in November, everyone should apply it, hence it is separate from the `enhancements'. 2) Makes the 4.3BSD version of talk portable to the following flavours of Unix: Pyramid (OSx2.5,OSx3.1,OSx4.0), Ultrix (1.2), Sun (3.0,3.1,3.2). This is nice, since few of these speak the 4.3BSD talk protocol; it'll probably port to 4.2BSD with OSx2.5. 3) Allow for special control codes to be expanded locally. (e.g. ^A maps into "", ^N displays a menu, etc) While it is possible to send the *mappings* out to people not running these enhancements, doing it `right' requires awful code (e.g. some control chars are only meaningful locally and shouldnt be sent). Instead, because of #2 above (easy portability), we simply run it everywhere here. 4) Resolve internet addresses (e.g. 128.138.240.1) so that things like `talk user@128.138.240.1' will work, and talkd may display "respond with: talk user@128.138.240.1". (this is good for internet hosts that dont yet run a nameserver, and dont have up-to-date /etc/hosts files) 5) If a person you are trying to contact has messages off, and they have a file called ".busy" in their home directory, it will be sent to you and displayed in their half of the screen. The file generally contains the `reason' your messages are off. 6) A "dumb terminal" interface called `chat'. This is good for consoles and terminals without termcaps. `chat' is hard-linked to `talk' and each does the right thing. 7) A revised manual page explaining these enhancements. One thing that would be easy to add to the talk daemon, and probably will be added in the future (if you or I ever get the time) is a ".talkrc" file that would contain options to: 1) list people you will talk to (when your messages are off). 2) list people who you wont talk to even though your messages are on. I have tested these `enhancements' under many circumstances for compatibility with 4.3BSD. Most of these mods have been running for a couple years and I've fixed any little bugs that have since appeared. Finally, this is available via anonymous ftp from boulder.Colorado.EDU. What follows, is a shar archive containing the files: 4.3talk_fix - a fix that should be applied to every 4.3BSD talk. talk.1_diffs - patch to /usr/man/man1/talk.1 (move the patched file to /usr/src/ucb/talk/talk.1 for `make install') talk_diffs - patches for talk; cd /usr/src/ucb/talk & patch... talkd_diffs - patches for talkd; cd /usr/src/etc/talkd & patch... talkd.h_diffs - patch to /usr/include/protocols/talkd.h [I split talkd_diffs into a separate file because of the 64K message limit on some machines. ++bsa] If you make any changes or fix a bug, please let me know... thanks! --- Jeff Forys @ UC/Boulder Engineering Research Comp Cntr (303-492-4991) forys@boulder.Colorado.Edu -or- ..!{hao|nbires}!boulder!forys #--------------------------------CUT HERE------------------------------------- #! /bin/sh # # This is a shell archive. Save this into a file, edit it # and delete all lines above this comment. Then give this # file to sh by executing the command "sh file". The files # will be extracted into the current directory owned by # you with default permissions. # # The files contained herein are: # # -rw-r--r-- 1 allbery System 21740 Aug 10 20:03 talkd_diffs # echo 'x - talkd_diffs' if test -f talkd_diffs; then echo 'shar: not overwriting talkd_diffs'; else sed 's/^X//' << '________This_Is_The_END________' > talkd_diffs X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:15 1987 X--- Makefile Fri Aug 7 17:40:42 1987 X*************** X*** 3,14 **** X # All rights reserved. The Berkeley software License Agreement X # specifies the terms and conditions for redistribution. X # X! # @(#)Makefile 5.4 (Berkeley) 3/13/86 X # X! DESTDIR= X OBJS= talkd.o announce.o process.o table.o print.o X SRCS= talkd.c announce.c process.c table.c print.c X- CFLAGS= -O X X all: talkd X X--- 3,56 ---- X # All rights reserved. The Berkeley software License Agreement X # specifies the terms and conditions for redistribution. X # X! # @(#)Makefile 5.4.1 (Berkeley) 3/13/86 X # X! X! # Sun Jan 11 20:08:22 MST 1987 JEF forys@Boulder.Colorado.Edu X! # Conditional compilations for different machines... X! # X! # 4.3 BSD X! CFLAGS=-O X! DESTDIR=/etc/ntalkd X! # X! # Pyramid OSx2.5 X! #CFLAGS=-O -DPYRAMID -DNO_INETD X! #DESTDIR=/etc/ntalkd X! # X! # Pyramid OSx3.1 X! #CFLAGS=-O -DPYRAMID X! #DESTDIR=/usr/etc/in.ntalkd X! # X! # Pyramid OSx4.0 X! #CFLAGS=-O -DPYRAMID -DBSD4_3 X! #DESTDIR=/etc/ntalkd X! # X! # Sun 3.1, 3.0 X! #CFLAGS=-O -DSUN3_1 X! #DESTDIR=/usr/etc/in.ntalkd X! # X! # Sun 3.2 X! #CFLAGS=-O -DSUN3_2 X! #DESTDIR=/usr/etc/in.ntalkd X! # X! # Ultrix 1.2 X! #CFLAGS=-O -DULTRIX1_2 X! #DESTDIR=/etc/ntalkd X! # X! # If you are trying to get this to run under a different X! # system, the following should help: X! # NO_INETD - compile in code to listen for connections X! # PYRAMID - defines for byte order stuff, old syslog, X! # SUN3_1 - old 4.2 syslog X! # SUN3_2 - old 4.2 syslog X! # ULTRIX1_2 - old 4.2 syslog X! # We no longer have 4.2BSD machines around, but I'm sure they'll X! # need NO_INETD and the old syslog stuff... X! X! MANDIR=/usr/man/man1 X! X OBJS= talkd.o announce.o process.o table.o print.o X SRCS= talkd.c announce.c process.c table.c print.c X X all: talkd X X*************** X*** 16,22 **** X cc ${CFLAGS} -o talkd ${OBJS} X X install: talkd X! install -s talkd ${DESTDIR}/etc/ntalkd X X clean: X rm -f ${OBJS} errs core a.out talkd X--- 58,64 ---- X cc ${CFLAGS} -o talkd ${OBJS} X X install: talkd X! install -s talkd ${DESTDIR} X X clean: X rm -f ${OBJS} errs core a.out talkd X*************** X*** 26,32 **** X X depend: ${SRCS} X for i in ${SRCS}; do \ X! cc -M $$i | sed 's/\.o//' | \ X awk ' { if ($$1 != prev) \ X { if (rec != "") print rec; rec = $$0; prev = $$1; } \ X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X--- 68,74 ---- X X depend: ${SRCS} X for i in ${SRCS}; do \ X! cc -M ${CFLAGS} $$i | sed 's/\.o//' | \ X awk ' { if ($$1 != prev) \ X { if (rec != "") print rec; rec = $$0; prev = $$1; } \ X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X*************** X*** 52,63 **** X announce: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h X announce: /usr/include/sys/ioctl.h /usr/include/sys/time.h /usr/include/time.h X announce: /usr/include/stdio.h /usr/include/sys/wait.h /usr/include/errno.h X! announce: /usr/include/syslog.h /usr/include/protocols/talkd.h X! announce: /usr/include/sys/types.h /usr/include/sys/socket.h X process: process.c /usr/include/sys/types.h /usr/include/sys/stat.h X process: /usr/include/stdio.h /usr/include/syslog.h /usr/include/netdb.h X! process: /usr/include/netinet/in.h /usr/include/protocols/talkd.h X! process: /usr/include/sys/types.h /usr/include/sys/socket.h /usr/include/utmp.h X table: table.c /usr/include/stdio.h /usr/include/sys/time.h /usr/include/time.h X table: /usr/include/syslog.h /usr/include/protocols/talkd.h X table: /usr/include/sys/types.h /usr/include/sys/socket.h X--- 94,109 ---- X announce: /usr/include/sys/ttychars.h /usr/include/sys/ttydev.h X announce: /usr/include/sys/ioctl.h /usr/include/sys/time.h /usr/include/time.h X announce: /usr/include/stdio.h /usr/include/sys/wait.h /usr/include/errno.h X! announce: /usr/include/syslog.h /usr/include/strings.h /usr/include/pwd.h X! announce: /usr/include/protocols/talkd.h /usr/include/sys/types.h X! announce: /usr/include/sys/socket.h X process: process.c /usr/include/sys/types.h /usr/include/sys/stat.h X process: /usr/include/stdio.h /usr/include/syslog.h /usr/include/netdb.h X! process: /usr/include/netinet/in.h /usr/include/sys/param.h X! process: /usr/include/machine/machparam.h /usr/include/signal.h X! process: /usr/include/sys/types.h /usr/include/protocols/talkd.h X! process: /usr/include/sys/types.h /usr/include/sys/socket.h X! process: /usr/include/arpa/inet.h /usr/include/utmp.h X table: table.c /usr/include/stdio.h /usr/include/sys/time.h /usr/include/time.h X table: /usr/include/syslog.h /usr/include/protocols/talkd.h X table: /usr/include/sys/types.h /usr/include/sys/socket.h X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:18 1987 X--- announce.c Fri Aug 7 17:40:46 1987 X*************** X*** 17,25 **** X--- 17,34 ---- X #include X #include X #include X+ #include X+ #include X X #include X X+ #if PYRAMID X+ #define ntohl(x) (x) X+ #define ntohs(x) (x) X+ #define htonl(x) (x) X+ #define htons(x) (x) X+ #endif X+ X extern int errno; X extern char hostname[]; X X*************** X*** 30,45 **** X * process to any terminal that it writes on, we must fork a child X * to protect ourselves X */ X! announce(request, remote_machine) X CTL_MSG *request; X char *remote_machine; X { X int pid, val, status; X X if (pid = fork()) { X /* we are the parent, so wait for the child */ X! if (pid == -1) /* the fork failed */ X return (FAILED); X do { X val = wait(&status); X if (val == -1) { X--- 39,63 ---- X * process to any terminal that it writes on, we must fork a child X * to protect ourselves X */ X! announce(request, remote_machine, busy) X CTL_MSG *request; X char *remote_machine; X+ CTL_BUSY *busy; X { X int pid, val, status; X+ int fd[2]; X X+ if (pipe(fd) < 0) /* need a pipe to return .busy from child */ X+ return(FAILED); X+ X if (pid = fork()) { X /* we are the parent, so wait for the child */ X! if (pid == -1) { /* the fork failed */ X! close(fd[0]); X! close(fd[1]); X return (FAILED); X+ } X+ X do { X val = wait(&status); X if (val == -1) { X*************** X*** 46,71 **** X if (errno == EINTR) X continue; X /* shouldn't happen */ X syslog(LOG_WARNING, "announce: wait: %m"); X return (FAILED); X } X } while (val != pid); X! if (status&0377 > 0) /* we were killed by some signal */ X return (FAILED); X /* Get the second byte, this is the exit/return code */ X! return ((status >> 8) & 0377); X } X /* we are the child, go and do it */ X! _exit(announce_proc(request, remote_machine)); X } X! X /* X * See if the user is accepting messages. If so, announce that X * a talk is requested. X */ X! announce_proc(request, remote_machine) X CTL_MSG *request; X char *remote_machine; X { X int pid, status; X char full_tty[32]; X--- 64,101 ---- X if (errno == EINTR) X continue; X /* shouldn't happen */ X+ close(fd[0]); X+ close(fd[1]); X syslog(LOG_WARNING, "announce: wait: %m"); X return (FAILED); X } X } while (val != pid); X! if (status&0377 > 0) { /* we were killed by some signal */ X! close(fd[0]); X! close(fd[1]); X return (FAILED); X+ } X /* Get the second byte, this is the exit/return code */ X! status = (status >> 8) & 0377; X! X! if (status == PERMISSION_DENIED) /* get .busy file */ X! get_busy(fd[0], busy); X! close(fd[0]); X! close(fd[1]); X! return(status); X } X /* we are the child, go and do it */ X! _exit(announce_proc(request, remote_machine, fd[1])); X } X! X /* X * See if the user is accepting messages. If so, announce that X * a talk is requested. X */ X! announce_proc(request, remote_machine, fd_write) X CTL_MSG *request; X char *remote_machine; X+ int fd_write; X { X int pid, status; X char full_tty[32]; X*************** X*** 75,82 **** X sprintf(full_tty, "/dev/%s", request->r_tty); X if (access(full_tty, 0) != 0) X return (FAILED); X! if ((tf = fopen(full_tty, "w")) == NULL) X return (PERMISSION_DENIED); X /* X * On first tty open, the server will have X * it's pgrp set, so disconnect us from the X--- 105,114 ---- X sprintf(full_tty, "/dev/%s", request->r_tty); X if (access(full_tty, 0) != 0) X return (FAILED); X! if ((tf = fopen(full_tty, "w")) == NULL) { X! refuse(request->r_name, fd_write); X return (PERMISSION_DENIED); X+ } X /* X * On first tty open, the server will have X * it's pgrp set, so disconnect us from the X*************** X*** 83,92 **** X * tty before we catch a signal. X */ X ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); X! if (fstat(fileno(tf), &stbuf) < 0) X return (PERMISSION_DENIED); X! if ((stbuf.st_mode&020) == 0) X return (PERMISSION_DENIED); X print_mesg(tf, request, remote_machine); X fclose(tf); X return (SUCCESS); X--- 115,128 ---- X * tty before we catch a signal. X */ X ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); X! if (fstat(fileno(tf), &stbuf) < 0) { X! refuse(request->r_name, fd_write); X return (PERMISSION_DENIED); X! } X! if ((stbuf.st_mode&020) == 0) { X! refuse(request->r_name, fd_write); X return (PERMISSION_DENIED); X+ } X print_mesg(tf, request, remote_machine); X fclose(tf); X return (SUCCESS); X*************** X*** 154,161 **** X while (*lptr != '\0') X *(bptr++) = *(lptr++); X /* pad out the rest of the lines with blanks */ X! for (j = sizes[i]; j < max_size + 2; j++) X *(bptr++) = ' '; X *(bptr++) = '\r'; /* add a \r in case of raw mode */ X *(bptr++) = '\n'; X } X--- 190,198 ---- X while (*lptr != '\0') X *(bptr++) = *(lptr++); X /* pad out the rest of the lines with blanks */ X! for (j = sizes[i]; j < max_size + 2; j++) { X *(bptr++) = ' '; X+ } X *(bptr++) = '\r'; /* add a \r in case of raw mode */ X *(bptr++) = '\n'; X } X*************** X*** 163,166 **** X--- 200,272 ---- X fprintf(tf, big_buf); X fflush(tf); X ioctl(fileno(tf), TIOCNOTTY, (struct sgttyb *) 0); X+ } X+ X+ refuse(r_name, fd_write) /* try to find out why user is unsociable */ X+ char *r_name; X+ int fd_write; X+ { X+ register FILE *fpr; X+ char bpth[100]; /* homedirectory/BUSYFLNM */ X+ char bufr[BUSYSIZE]; /* contents of BUSYFLNM */ X+ register int c, i=0; X+ struct passwd *my_getpwnam(); X+ X+ *bufr = '\0'; X+ (void) strcat(strcat(strcpy(bpth, my_getpwnam(r_name)->pw_dir), "/"), X+ BUSYFLNM); X+ if ((fpr=fopen(bpth, "r")) != NULL) { /* file exists */ X+ while ((c=getc(fpr)) != EOF && ichksum = (long) 0; /* We also want a check sum */ X+ X+ (void) read(fd_read, busy->busy, BUSYSIZE); /* Read from pipe */ X+ X+ for (i=0; ibusy[i]; i++) /* Compute checksum */ X+ busy->chksum += (long) busy->busy[i]; X+ busy->chksum = htonl(busy->chksum); X+ } X+ X+ /* X+ * I had to write my own 'getpwnam' because the one that is X+ * provided seems to have an obscure bug in it. The problem X+ * was tracked down to 'endpwent' which calls 'dbm_close' X+ * which makes a call to 'free' (and promptly dies). My X+ * solution was to simply eliminate the call to 'endpwent' X+ * because if this code was executed, the user must have had X+ * his messages off and the daemon will die (thus closing the X+ * database files). Even if the daemon doesn't die quickly X+ * and this procedure is called again, 'setpwent' knows that X+ * the database is still open and just rewinds it. X+ * X+ * Incidentally, when I used 'endpwent', talk responded: X+ * X+ * [No connection yet] X+ * [Target machine is too confused to talk to us] X+ * X+ */ X+ X+ struct passwd *my_getpwnam(usrnam) /* getpwnam without call to endpwent */ X+ char *usrnam; X+ { X+ struct passwd *pw; X+ X+ (void) setpwent(); /* Open password file */ X+ X+ while ((pw = getpwent()) && strcmp(usrnam, pw->pw_name)) X+ ; /* Find the right entry */ X+ X+ return(pw); /* It MUST exist (user is logged in), just return it */ X } X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:21 1987 X--- print.c Fri Aug 7 17:40:50 1987 X*************** X*** 15,20 **** X--- 15,27 ---- X X #include X X+ #if PYRAMID X+ #define ntohl(x) (x) X+ #define ntohs(x) (x) X+ #define htonl(x) (x) X+ #define htons(x) (x) X+ #endif X+ X static char *types[] = X { "leave_invite", "look_up", "delete", "announce" }; X #define NTYPES (sizeof (types) / sizeof (types[0])) X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:24 1987 X--- process.c Fri Aug 7 17:40:55 1987 X*************** X*** 22,37 **** X #include X #include X #include X X #include X X char *strcpy(); X CTL_MSG *find_request(); X CTL_MSG *find_match(); X X! process_request(mp, rp) X register CTL_MSG *mp; X register CTL_RESPONSE *rp; X { X register CTL_MSG *ptr; X extern int debug; X--- 22,48 ---- X #include X #include X #include X+ #include X X #include X X+ #if PYRAMID X+ #define ntohl(x) (x) X+ #define ntohs(x) (x) X+ #define htonl(x) (x) X+ #define htons(x) (x) X+ #else /* I wont explain this one; simply believe me -- pyramids hate it */ X+ #include X+ #endif X+ X char *strcpy(); X CTL_MSG *find_request(); X CTL_MSG *find_match(); X X! process_request(mp, rp, busy) X register CTL_MSG *mp; X register CTL_RESPONSE *rp; X+ CTL_BUSY *busy; X { X register CTL_MSG *ptr; X extern int debug; X*************** X*** 38,44 **** X X rp->vers = TALK_VERSION; X rp->type = mp->type; X! rp->id_num = htonl(0); X if (mp->vers != TALK_VERSION) { X syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); X rp->answer = BADVERSION; X--- 49,55 ---- X X rp->vers = TALK_VERSION; X rp->type = mp->type; X! rp->id_num = htonl((long)0); X if (mp->vers != TALK_VERSION) { X syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); X rp->answer = BADVERSION; X*************** X*** 65,71 **** X switch (mp->type) { X X case ANNOUNCE: X! do_announce(mp, rp); X break; X X case LEAVE_INVITE: X--- 76,82 ---- X switch (mp->type) { X X case ANNOUNCE: X! do_announce(mp, rp, busy); X break; X X case LEAVE_INVITE: X*************** X*** 100,108 **** X print_response("process_request", rp); X } X X! do_announce(mp, rp) X register CTL_MSG *mp; X CTL_RESPONSE *rp; X { X struct hostent *hp; X CTL_MSG *ptr; X--- 111,120 ---- X print_response("process_request", rp); X } X X! do_announce(mp, rp, busy) X register CTL_MSG *mp; X CTL_RESPONSE *rp; X+ CTL_BUSY *busy; X { X struct hostent *hp; X CTL_MSG *ptr; X*************** X*** 110,130 **** X X /* see if the user is logged */ X result = find_user(mp->r_name, mp->r_tty); X! if (result != SUCCESS) { X rp->answer = result; X return; X } X #define satosin(sa) ((struct sockaddr_in *)(sa)) X! hp = gethostbyaddr(&satosin(&mp->ctl_addr)->sin_addr, X sizeof (struct in_addr), AF_INET); X! if (hp == (struct hostent *)0) { X! rp->answer = MACHINE_UNKNOWN; X! return; X } X ptr = find_request(mp); X if (ptr == (CTL_MSG *) 0) { X insert_table(mp, rp); X! rp->answer = announce(mp, hp->h_name); X return; X } X if (mp->id_num > ptr->id_num) { X--- 122,164 ---- X X /* see if the user is logged */ X result = find_user(mp->r_name, mp->r_tty); X! if (result != SUCCESS && result != PERMISSION_DENIED) { X rp->answer = result; X return; X } X #define satosin(sa) ((struct sockaddr_in *)(sa)) X! hp = gethostbyaddr((char *) &satosin(&mp->ctl_addr)->sin_addr, X sizeof (struct in_addr), AF_INET); X! if (hp == (struct hostent *) 0) { X! static struct hostent def; X! static struct in_addr defaddr; X! static char *iaddr_str; X! #ifdef BSD4_3 X! static char *alist[1]; X! #endif X! static char namebuf[128]; X! X! iaddr_str = (char *)inet_ntoa(satosin(&mp->ctl_addr)->sin_addr); X! defaddr.s_addr = inet_addr(iaddr_str); X! if (defaddr.s_addr == -1) { X! rp->answer = MACHINE_UNKNOWN; X! return; X! } X! strcpy(namebuf, iaddr_str); X! def.h_name = namebuf; X! #ifdef BSD4_3 X! def.h_addr_list = alist, X! #endif X! def.h_addr = (char *)&defaddr; X! def.h_length = sizeof (struct in_addr); X! def.h_addrtype = AF_INET; X! def.h_aliases = 0; X! hp = &def; X } X ptr = find_request(mp); X if (ptr == (CTL_MSG *) 0) { X insert_table(mp, rp); X! rp->answer = announce(mp, hp->h_name, busy); X return; X } X if (mp->id_num > ptr->id_num) { X*************** X*** 134,140 **** X */ X ptr->id_num = new_id(); X rp->id_num = htonl(ptr->id_num); X! rp->answer = announce(mp, hp->h_name); X } else { X /* a duplicated request, so ignore it */ X rp->id_num = htonl(ptr->id_num); X--- 168,174 ---- X */ X ptr->id_num = new_id(); X rp->id_num = htonl(ptr->id_num); X! rp->answer = announce(mp, hp->h_name, busy); X } else { X /* a duplicated request, so ignore it */ X rp->id_num = htonl(ptr->id_num); X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:28 1987 X--- table.c Fri Aug 7 17:40:59 1987 X*************** X*** 22,27 **** X--- 22,34 ---- X X #include X X+ #if PYRAMID X+ #define ntohl(x) (x) X+ #define ntohs(x) (x) X+ #define htonl(x) (x) X+ #define htons(x) (x) X+ #endif X+ X #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ X X #define NIL ((TABLE_ENTRY *)0) X*** /tmp/,RCSt1019995 Fri Aug 7 17:43:31 1987 X--- talkd.c Fri Aug 7 17:41:04 1987 X*************** X*** 27,36 **** X X #include X X CTL_MSG request; X CTL_RESPONSE response; X X! int sockt; X int debug = 0; X int timeout(); X long lastmsgtime; X--- 27,43 ---- X X #include X X+ #ifdef NO_INETD X+ #include X+ #include X+ #include X+ #endif X+ X CTL_MSG request; X CTL_RESPONSE response; X+ CTL_BUSY busy; X X! int sockt = 0; X int debug = 0; X int timeout(); X long lastmsgtime; X*************** X*** 37,42 **** X--- 44,54 ---- X X char hostname[32]; X X+ #ifdef NO_INETD X+ struct sockaddr_in sin = { AF_INET }; X+ u_short port = 0; X+ #endif X+ X #define TIMEOUT 30 X #define MAXIDLE 120 X X*************** X*** 44,49 **** X--- 56,66 ---- X int argc; X char *argv[]; X { X+ #ifdef NO_INETD X+ struct servent *sp, *getservbyname(); X+ struct sockaddr_in from; X+ int fromlen; X+ #endif X register CTL_MSG *mp = &request; X int cc; X X*************** X*** 51,57 **** X--- 68,79 ---- X fprintf(stderr, "%s: getuid: not super-user", argv[0]); X exit(1); X } X+ #if (SUN3_1 | SUN3_2 | PYRAMID | ULTRIX1_2) X+ openlog("talkd", LOG_PID); X+ #else X openlog("talkd", LOG_PID, LOG_DAEMON); X+ #endif X+ X if (gethostname(hostname, sizeof (hostname) - 1) < 0) { X syslog(LOG_ERR, "gethostname: %m"); X _exit(1); X*************** X*** 62,73 **** X } X if (argc > 1 && strcmp(argv[1], "-d") == 0) X debug = 1; X signal(SIGALRM, timeout); X alarm(TIMEOUT); X for (;;) { X extern int errno; X X! cc = recv(0, (char *)mp, sizeof (*mp), 0); X if (cc != sizeof (*mp)) { X if (cc < 0 && errno != EINTR) X syslog(LOG_WARNING, "recv: %m"); X--- 84,130 ---- X } X if (argc > 1 && strcmp(argv[1], "-d") == 0) X debug = 1; X+ X+ #ifdef NO_INETD X+ if ((sp=getservbyname("ntalk", "udp")) == (struct servent *) 0) { X+ syslog(LOG_ERR, "gethostbyname: %m"); X+ _exit(1); X+ } X+ port = sp->s_port; X+ X+ if ((sockt=socket(AF_INET, SOCK_DGRAM, 0)) < 0) { X+ syslog(LOG_ERR, "socket: %m"); X+ _exit(1); X+ } X+ X+ bzero((char *)&sin, sizeof(sin)); X+ sin.sin_addr.s_addr = INADDR_ANY; X+ sin.sin_port = port; X+ sin.sin_family = AF_INET; X+ X+ if (bind(sockt, (caddr_t)&sin, sizeof(sin)) < 0) { X+ syslog(LOG_ERR, "bind: %m"); X+ _exit(1); X+ } X+ X+ if (fork()) X+ _exit(0); X+ setup_descriptors(sockt); X+ X+ #else X signal(SIGALRM, timeout); X alarm(TIMEOUT); X+ #endif X for (;;) { X extern int errno; X X! #ifdef NO_INETD X! fromlen = sizeof(from); X! cc = recvfrom(sockt, (char *)mp, X! sizeof (*mp), 0, &from, &fromlen); X! #else X! cc = recv(sockt, (char *)mp, sizeof (*mp), 0); X! #endif X if (cc != sizeof (*mp)) { X if (cc < 0 && errno != EINTR) X syslog(LOG_WARNING, "recv: %m"); X*************** X*** 74,85 **** X continue; X } X lastmsgtime = time(0); X! process_request(mp, &response); X /* can block here, is this what I want? */ X cc = sendto(sockt, (char *)&response, X sizeof (response), 0, &mp->ctl_addr, sizeof (mp->ctl_addr)); X if (cc != sizeof (response)) X syslog(LOG_WARNING, "sendto: %m"); X } X } X X--- 131,151 ---- X continue; X } X lastmsgtime = time(0); X! process_request(mp, &response, &busy); X /* can block here, is this what I want? */ X cc = sendto(sockt, (char *)&response, X sizeof (response), 0, &mp->ctl_addr, sizeof (mp->ctl_addr)); X if (cc != sizeof (response)) X syslog(LOG_WARNING, "sendto: %m"); X+ X+ if (response.answer == PERMISSION_DENIED) { X+ /* send reason why this party is refusing messages */ X+ X+ cc = sendto(sockt, (char *) &busy, sizeof(busy), 0, X+ &request.ctl_addr, sizeof(request.ctl_addr)); X+ if (cc != sizeof(busy)) X+ syslog(LOG_WARNING, "sendto: %m"); X+ } X } X } X X*************** X*** 90,92 **** X--- 156,181 ---- X _exit(0); X alarm(TIMEOUT); X } X+ X+ #ifdef NO_INETD X+ setup_descriptors(sockt) X+ int sockt; X+ { X+ int i, tty; X+ X+ if (sockt != 0) X+ (void) close(0); X+ X+ i = open("/dev/null", 0); X+ if (sockt != 1) X+ (void) dup2(i, 1); X+ if (sockt != 2) X+ (void) dup2(i, 2); X+ X+ if ((tty=open("/dev/tty", 0)) != -1) { X+ ioctl(tty, TIOCNOTTY, (struct sgttyb *) 0); X+ (void) close(tty); X+ } else X+ setpgrp(0, getpid()); X+ } X+ #endif ________This_Is_The_END________ if test `wc -l < talkd_diffs` -ne 840; then echo 'shar: talkd_diffs was damaged during transit (should have been 840 bytes)' fi fi ; : end of overwriting check exit 0