netkit-ntalk-0.17/ 40700 144 144 0 7141142004 13234 5ustar dhollandpeoplenetkit-ntalk-0.17/talk/ 40700 144 144 0 7141142004 14167 5ustar dhollandpeoplenetkit-ntalk-0.17/talk/.cvsignore100644 144 144 5 6774160722 16233 0ustar dhollandpeopletalk netkit-ntalk-0.17/talk/Makefile100644 144 144 723 6750736414 15743 0ustar dhollandpeopleall: talk include ../MCONFIG include ../MRULES CFLAGS += -I../include OBJS = ctl.o ctl_transact.o display.o get_addrs.o get_names.o \ init_disp.o invite.o io.o look_up.o msgs.o talk.o LIBS += $(LIBCURSES) talk: $(OBJS) $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ $(OBJS): talk.h ../include/prot_talkd.h ../version.h install: talk install -s -m$(BINMODE) talk $(INSTALLROOT)$(BINDIR) install -m$(MANMODE) talk.1 $(INSTALLROOT)$(MANDIR)/man1/ clean: rm -f *.o talk netkit-ntalk-0.17/talk/ctl.c100644 144 144 5346 6627502476 15261 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)ctl.c 5.7 (Berkeley) 3/1/91 */ char ctl_rcsid[] = "$Id: ctl.c,v 1.11 1998/11/27 10:55:58 dholland Exp $"; /* * This file handles haggling with the various talk daemons to * get a socket to talk to. sockt is opened and connected in * the progress */ #include #include #include #include "talk.h" /* inet address of the remote machine */ struct in_addr his_machine_addr; u_short daemon_port; /* port number of the talk daemon */ int sockt; int invitation_waiting = 0; CTL_MSG msg; void open_sockt(void) { sockt = socket(AF_INET, SOCK_STREAM, 0); if (sockt <= 0) p_error("Bad socket"); } #if 0 /* print_addr is a debug print routine */ void print_addr(struct sockaddr_in addr) { int i; printf("addr = %x, port = %o, family = %o zero = ", addr.sin_addr.s_addr, addr.sin_port, addr.sin_family); for (i = 0; i<8;i++) printf("%o ", (int)addr.sin_zero[i]); putchar('\n'); } #endif /* 0 */ netkit-ntalk-0.17/talk/ctl_transact.c100644 144 144 15532 6774235536 17201 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)ctl_transact.c 5.8 (Berkeley) 3/1/91 */ char ctlt_rcsid[] = "$Id: ctl_transact.c,v 1.12 1999/09/28 22:04:14 netbug Exp $"; #include #include #include #include #include /* #include looks like this is not needed (no functions used) */ #include #include #include "talk.h" #define CTL_WAIT 2 /* time to wait for a response, in seconds */ /* We now make two UDP sockets, one for the local talkd, one for the remote. */ static int to_local_talkd; static int to_remote_talkd; static u_int32_t local_addr_for_remote; /* open the ctl sockets */ void open_ctl(void) { struct sockaddr_in loc, rem; socklen_t length; int on=1; to_local_talkd = socket(AF_INET, SOCK_DGRAM, 0); to_remote_talkd = socket(AF_INET, SOCK_DGRAM, 0); if (to_local_talkd < 0 || to_remote_talkd < 0) { p_error("Bad socket"); } #ifdef SO_BSDCOMPAT /* * Linux does some async error return stuff that * really disagrees with us. So we disable it. */ setsockopt(to_local_talkd, SOL_SOCKET, SO_BSDCOMPAT, &on, sizeof(on)); setsockopt(to_remote_talkd, SOL_SOCKET, SO_BSDCOMPAT, &on, sizeof(on)); #endif /* * Explicitly talk to the local daemon over loopback. */ memset(&loc, 0, sizeof(loc)); loc.sin_family = AF_INET; loc.sin_port = htons(0); loc.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (bind(to_local_talkd, (struct sockaddr *)&loc, sizeof(loc))<0) { p_error("Couldn't bind local control socket"); } memset(&loc, 0, sizeof(loc)); loc.sin_family = AF_INET; loc.sin_port = daemon_port; loc.sin_addr.s_addr = htonl(INADDR_LOOPBACK); if (connect(to_local_talkd, (struct sockaddr *)&loc, sizeof(loc))<0) { p_error("Couldn't connect local control socket"); } /* * Now the trick - don't bind the remote socket. Instead * just do a UDP connect on it to force it to talk to the * remote talkd. The neat side effect of this is that * we can then get the correct local IP back from it * with getsockname. */ memset(&rem, 0, sizeof(rem)); rem.sin_family = AF_INET; rem.sin_port = daemon_port; rem.sin_addr = his_machine_addr; if (connect(to_remote_talkd, (struct sockaddr *)&rem, sizeof(rem))<0) { p_error("Couldn't connect remote control socket"); } length = sizeof(rem); if (getsockname(to_remote_talkd, (struct sockaddr *)&rem, &length)<0) { p_error("getsockname"); } local_addr_for_remote = rem.sin_addr.s_addr; } static void send_packet(CTL_MSG *msg, int sock) { int cc; cc = send(sock, msg, sizeof(*msg), 0); if (cc<0 && errno == EINTR) { return; } else if (cc<0) { p_error("Error on write to talk daemon"); } else if (cc != sizeof(*msg)) { p_error("Short write to talk daemon"); } } static void clean_up_packet(int sock, CTL_MSG *msg, int type) { struct sockaddr_in here; socklen_t len = sizeof(here); msg->vers = TALK_VERSION; msg->type = type; msg->answer = 0; msg->pad = 0; if (getsockname(sock, (struct sockaddr *)&here, &len)<0) { p_error("getsockname"); } msg->ctl_addr.ta_family = htons(AF_INET); msg->ctl_addr.ta_port = here.sin_port; msg->ctl_addr.ta_addr = here.sin_addr.s_addr; msg->addr.ta_family = htons(AF_INET); msg->addr.ta_addr = local_addr_for_remote; } void send_one_delete(int ismydaemon, int id) { CTL_MSG tmp = msg; int sock = ismydaemon ? to_local_talkd : to_remote_talkd; tmp.id_num = htonl(id); clean_up_packet(sock, &tmp, DELETE); send_packet(&tmp, sock); } /* * SOCKDGRAM is unreliable, so we must repeat messages if we have * not received an acknowledgement within a reasonable amount * of time */ static void do_transact(int sock, CTL_MSG *mesg, CTL_RESPONSE *rp) { fd_set read_mask, ctl_mask; int nready=0, cc; struct timeval wait; FD_ZERO(&ctl_mask); FD_SET(sock, &ctl_mask); /* * Keep sending the message until a response of * the proper type is obtained. */ do { /* resend message until a response is obtained */ do { send_packet(mesg, sock); read_mask = ctl_mask; wait.tv_sec = CTL_WAIT; wait.tv_usec = 0; nready = select(sock+1, &read_mask, 0, 0, &wait); if (nready < 0) { if (errno == EINTR) continue; p_error("Error waiting for daemon response"); } } while (nready == 0); /* * Keep reading while there are queued messages * (this is not necessary, it just saves extra * request/acknowledgements being sent) */ do { cc = recv(sock, (char *)rp, sizeof (*rp), 0); if (cc < 0) { if (errno == EINTR) continue; p_error("Error on read from talk daemon"); } read_mask = ctl_mask; /* an immediate poll */ timerclear(&wait); nready = select(sock+1, &read_mask, 0, 0, &wait); } while (nready > 0 && (rp->vers != TALK_VERSION || rp->type != mesg->type)); } while (rp->vers != TALK_VERSION || rp->type != mesg->type); } void ctl_transact(int ismydaemon, CTL_MSG mesg, int type, CTL_RESPONSE *rp) { int sock; sock = ismydaemon ? to_local_talkd : to_remote_talkd; clean_up_packet(sock, &mesg, type); do_transact(sock, &mesg, rp); rp->id_num = ntohl(rp->id_num); rp->addr.ta_family = ntohs(rp->addr.ta_family); } netkit-ntalk-0.17/talk/display.c100644 144 144 31760 7140623563 16153 0ustar dhollandpeople/* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. * * Copyright 1999 David A. Holland. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notices, this list of conditions, and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notices, this list of conditions, and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgements: * This product includes software developed by the University of * California, Berkeley and its contributors. * This product includes software developed by David A. Holland. * 4. Neither the name of the University nor the names of its contributors * nor the names of other copyright holders may be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS, CONTRIBUTORS, AND OTHER AUTHORS * ``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 REGENTS, CONTRIBUTORS, OR * OTHER AUTHORS 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. */ /* * From: @(#)display.c 5.4 (Berkeley) 6/1/90 * * Heavily modified 11/99 by dholland to add scrollback support. */ char display_rcsid[] = "$Id: display.c,v 1.15 2000/07/29 18:50:27 dholland Exp $"; /* * The window 'manager', initializes curses and handles the actual * displaying of text */ #include #include #include #include #include #include #include "talk.h" #define MAX_MAXLINES 16384 typedef struct { char *l_text; } line; typedef struct { line *s_lines; /* Text in scroll buffer */ int s_nlines; /* Number of valid lines in s_lines[] */ int s_maxlines; /* Max already-allocated number of lines */ int s_scrollup; /* Number of lines scrolled back */ char *s_typebuf; /* Current input line */ int s_typebufpos; /* Current position in input line */ int s_typebufmax; /* Max length of input line */ char cerase; /* Erase-character key */ char werase; /* Erase-word key */ char lerase; /* Erase-line key */ } window; static const char *topmessage; /* Message at top of screen, if any */ static window my_win; /* Scrolling data for top window */ static window his_win; /* Scrolling data for bottom window */ static int sepline; /* Line where separator is */ static int last_was_bot; /* if 1, last win with activity was bottom */ static void do_sigwinch(int ignore) { (void)ignore; /* Get curses to notice the size change */ endwin(); refresh(); /* and now repaint. */ dorefresh(); } static void init_window(window *win) { win->s_maxlines = 32; win->s_nlines = 0; win->s_lines = malloc(win->s_maxlines * sizeof(line)); if (!win->s_lines) p_error("Out of memory"); win->s_scrollup = 0; win->s_typebufmax = COLS+1; win->s_typebufpos = 0; win->s_typebuf = malloc(win->s_typebufmax); if (!win->s_typebuf) p_error("Out of memory"); win->cerase = 2; /* ^B */ win->werase = 23; /* ^W */ win->lerase = 21; /* ^U */ } void real_init_display(void) { struct sigaction sigac; /* Open curses. */ LINES = COLS = 0; if (initscr() == NULL) { printf("initscr failed: TERM is not set or set to an " "unknown terminal type.\n"); exit(1); } /* Block SIGALRM while handling SIGTSTP (curses catches SIGTSTP). */ sigaction(SIGTSTP, NULL, &sigac); sigaddset(&sigac.sa_mask, SIGALRM); sigaction(SIGTSTP, &sigac, NULL); /* Grab SIGWINCH (curses cannot do this correctly on its own) */ sigaction(SIGWINCH, NULL, &sigac); sigaddset(&sigac.sa_mask, SIGALRM); sigac.sa_handler = do_sigwinch; sigaction(SIGWINCH, &sigac, NULL); /* Set curses modes. */ cbreak(); noecho(); nl(); /* force cr->lf */ init_window(&my_win); init_window(&his_win); topmessage = NULL; sepline = LINES/2; /* Forcibly clear the screen. */ clear(); dorefresh(); } void set_my_edit_chars(int cerase, int lerase, int werase) { my_win.cerase = cerase; my_win.lerase = lerase; my_win.werase = werase; } void set_his_edit_chars(int cerase, int lerase, int werase) { his_win.cerase = cerase; his_win.lerase = lerase; his_win.werase = werase; } /**************************************************************/ void dobeep(void) { beep(); } static void refresh_window(window *win, int nlines, int typeline) { int i, line, topline = typeline-nlines+1; for (i=nlines-1; i>=0; i--) { move(topline+i, 0); line = win->s_nlines - (nlines - 1) + i - win->s_scrollup; if (line >=0 && line < win->s_nlines) { addstr(win->s_lines[line].l_text); } else if (line==win->s_nlines) { addstr(win->s_typebuf); } clrtoeol(); } } void dorefresh(void) { int i; erase(); sepline = LINES/2; /* Separator */ move(sepline, 0); for (i=0; is_scrollup + delta; if (nsc<0) nsc = 0; if (nsc>win->s_nlines) nsc = win->s_nlines; win->s_scrollup = nsc; dorefresh(); } static int do_one_getch(void) { static int gotesc = 0; int ich; unsigned char ch; ich = getch(); if (ich==ERR) { return -1; } ch = (unsigned char)ich; if (!gotesc && ch==27) { gotesc = 1; return -1; } if (gotesc) { gotesc = 0; return ((int)ch)|256; } #if 0 /* blah - someone please fix this */ if (ch & 128) { /* * It would be nice to be able to tell if this is meant to * be a meta-modifier, in which case we should flip it to * the next bit over, or an actual 8-bit character, in * which case it should be passed through. * * The following kludge probably won't work right. When will * we get *working* international charset support in unix? * XXX. */ const char *foo = getenv("LC_CTYPE"); if (!foo) { return = ((int)(ch&127))|256; } } #endif return ch; } /* * Note: at this level we trap scrolling keys and other local phenomena. * Erase/word erase/line erase, newlines, and so forth get passed through, * sent to the other guy, and ultimately come out in display(). */ int dogetch(void) { int k = do_one_getch(); int scrl = sepline-2; /* number of lines to scroll by */ if (k==('p'|256)) { /* M-p: scroll our window up */ doscroll(&my_win, scrl); } else if (k==('n'|256)) { /* M-n: scroll our window down */ doscroll(&my_win, -scrl); } else if (k==('p'&31)) { /* C-p: scroll other window up */ doscroll(&his_win, scrl); } else if (k==('n'&31)) { /* C-n: scroll other window down */ doscroll(&his_win, -scrl); } else if (k == '\f') { /* C-l: reprint */ clear(); dorefresh(); } else if (k>=0) { return k; } return -1; } /**************************************************************/ static void display_lerase(window *win) { win->s_typebuf[0] = 0; win->s_typebufpos = 0; } static void discard_top_line(window *win) { int i; assert(win->s_nlines>0); free(win->s_lines[0].l_text); for (i=0; is_nlines-1; i++) { win->s_lines[i] = win->s_lines[i+1]; } win->s_nlines--; } static void display_eol(window *win) { line *tmpl; char *tmps; if (win->s_nlines == win->s_maxlines) { if (win->s_maxlines < MAX_MAXLINES) { win->s_maxlines *= 2; tmpl = realloc(win->s_lines, win->s_maxlines*sizeof(line)); } else { /* Reached size limit - pretend realloc failed */ tmpl = NULL; } if (!tmpl) { discard_top_line(win); } else { win->s_lines = tmpl; } } assert(win->s_nlines < win->s_maxlines); while ((tmps = strdup(win->s_typebuf))==NULL && win->s_nlines>0) { discard_top_line(win); } if (!tmps) { p_error("Out of memory"); } win->s_lines[win->s_nlines++].l_text = tmps; display_lerase(win); if (win==&my_win) topmessage = NULL; } static void display_addch(window *win, int ch) { /* * Leave one extra byte of space in the type buffer. This is so that * the last column of the screen doesn't get used, because the refresh * code does clreol after it, and that clears the next line of the * screen, which makes a mess. */ if (win->s_typebufpos+2 == win->s_typebufmax) { display_eol(win); } win->s_typebuf[win->s_typebufpos++] = ch; win->s_typebuf[win->s_typebufpos] = 0; } static void display_tab(window *win) { while (win->s_typebufpos%8 != 0) { display_addch(win, ' '); } } static void display_cerase(window *win) { if (win->s_typebufpos > 0) { win->s_typebuf[--win->s_typebufpos] = 0; } } static void display_werase(window *win) { /* * Search backwards until we find the beginning of a word or * the beginning of the line. */ int lastpos=win->s_typebufpos; int pos = lastpos; while (pos>=0) { int onword = poss_typebuf[pos]!=' '; int prevspace = pos==0 || win->s_typebuf[pos-1]==' '; if (onword && prevspace) break; pos--; } if (pos<0) pos = 0; win->s_typebuf[pos] = 0; win->s_typebufpos = pos; } /* * Display some text on somebody's window, processing some control * characters while we are at it. */ void display(int hiswin, unsigned char *text, int size) { int j; window *win = hiswin ? &his_win : &my_win; last_was_bot = hiswin; for (j = 0; j < size; j++) { if (text[j] == '\n' || text[j]=='\r') { display_eol(win); } else if (text[j]=='\b' || text[j]==127 || text[j]==win->cerase) { /* someday erase characters will work right in unix */ display_cerase(win); } else if (text[j] == win->werase) { display_werase(win); } else if (text[j] == win->lerase) { /* line kill */ display_lerase(win); } else if (text[j] == '\a') { beep(); } else if (text[j] == '\f') { /* nothing */ } else if (text[j] == '\t') { display_tab(win); } else if ((text[j] & 0x7F) < ' ') { display_addch(win, '^'); display_addch(win, (text[j] & 63) + 64); } else { display_addch(win, text[j]); } } dorefresh(); } /**************************************************************/ /* * Display string in the standard location */ void message(const char *string) { topmessage = string; dorefresh(); } static int check_alt_screen(void) { const char *rmcup, *smcup; rmcup = tigetstr("rmcup"); smcup = tigetstr("smcup"); return rmcup || smcup; } static void middle_message(const char *string, const char *string2) { int line = sepline; int width, start; dorefresh(); width = 2 + strlen(string) + strlen(string2) + 2; start = (COLS - width)/2; if (start<0) start = 0; move(line, start); addstr("[ "); addstr(string); addstr(string2); addstr(" ]"); refresh(); } static void do_quit(void) { move(LINES-1, 0); clrtoeol(); refresh(); endwin(); if (invitation_waiting) { send_delete(); } exit(0); } /* * p_error prints the system error message on the standard location * on the screen and then exits. (i.e. a curses version of perror) */ void p_error(const char *string) { char msgbuf[256]; int hold = check_alt_screen(); snprintf(msgbuf, sizeof(msgbuf), "%s: %s", string, strerror(errno)); middle_message(msgbuf, hold ? ". Press any key..." : ""); if (hold) { /* alternative screen, wait before exiting */ getch(); } do_quit(); } /* * All done talking...hang up the phone and reset terminal thingy */ void quit(int direct) { int hold = check_alt_screen(); if (direct != 1 && hold) { /* alternative screen, prompt before exit */ middle_message("Press any key to exit", ""); getch(); } else { /* Make sure any message appears */ dorefresh(); } do_quit(); } netkit-ntalk-0.17/talk/get_addrs.c100644 144 144 5360 6774235536 16432 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)get_addrs.c 5.7 (Berkeley) 3/1/91 */ char ga_rcsid[] = "$Id: get_addrs.c,v 1.11 1999/09/28 22:04:14 netbug Exp $"; #include #include #include #include #include #include #include #include #include #include "talk.h" void get_addrs(const char *his_machine_name) { struct hostent *hp; struct servent *sp; msg.pid = htonl(getpid()); hp = gethostbyname(his_machine_name); if (hp == NULL) { fprintf(stderr, "talk: %s: ", his_machine_name); herror((char *)NULL); exit(-1); } if (hp->h_length > (int)sizeof(his_machine_addr)) { hp->h_length = sizeof(his_machine_addr); } memcpy(&his_machine_addr, hp->h_addr, hp->h_length); /* find the server's port */ sp = getservbyname("ntalk", "udp"); if (sp == 0) { fprintf(stderr, "talk: %s/%s: service is not registered.\n", "ntalk", "udp"); exit(-1); } daemon_port = sp->s_port; } netkit-ntalk-0.17/talk/get_names.c100644 144 144 7216 7017141601 16416 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)get_names.c 5.9 (Berkeley) 3/1/91 */ char gn_rcsid[] = "$Id: get_names.c,v 1.11 1999/11/25 05:05:05 netbug Exp $"; #include #include #include #include #include #include #include #include "talk.h" /* * Determine the local and remote user, tty, and machines */ void get_names(int argc, char *argv[]) { char hostname[MAXHOSTNAMELEN]; char *his_name, *my_name; char *my_machine_name, *his_machine_name; const char *his_tty; register char *cp; char *names; if (argc < 2) { printf("Usage: talk user [ttyname]\n"); exit(1); } if (!isatty(0)) { printf("Standard input must be a tty, not a pipe or a file\n"); exit(1); } if ((my_name = getlogin()) == NULL || my_name[0] == 0) { struct passwd *pw; if ((pw = getpwuid(getuid())) == NULL) { printf("You don't exist. Go away.\n"); exit(1); } my_name = pw->pw_name; } gethostname(hostname, sizeof (hostname)); my_machine_name = hostname; /* check for, and strip out, the machine name of the target */ names = strdup(argv[1]); for (cp = names; *cp && !index("@:!.", *cp); cp++) ; if (*cp == '\0') { /* this is a local to local talk */ his_name = names; his_machine_name = my_machine_name; } else { if (*cp++ == '@') { /* user@host */ his_name = names; his_machine_name = cp; } else { /* host.user or host!user or host:user */ his_name = cp; his_machine_name = names; } *--cp = '\0'; } if (argc > 2) his_tty = argv[2]; /* tty name is arg 2 */ else his_tty = ""; get_addrs(his_machine_name); /* * Initialize the message template. */ msg.id_num = htonl(0); strncpy(msg.l_name, my_name, NAME_SIZE); msg.l_name[NAME_SIZE - 1] = 0; strncpy(msg.r_name, his_name, NAME_SIZE); msg.r_name[NAME_SIZE - 1] = 0; strncpy(msg.r_tty, his_tty, TTY_SIZE); msg.r_tty[TTY_SIZE - 1] = 0; } netkit-ntalk-0.17/talk/init_disp.c100644 144 144 6556 7017134712 16451 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)init_disp.c 5.4 (Berkeley) 6/1/90 */ char id_rcsid[] = "$Id: init_disp.c,v 1.12 1999/11/25 04:23:38 dholland Exp $"; /* * Initialization code for the display package, * as well as the signal handling routines. */ #include #include #include #include #include #include "talk.h" static void sig_sent(int); /* * Set up curses, catch the appropriate signals, * and build the various windows. */ void init_display(void) { real_init_display(); signal(SIGINT, sig_sent); signal(SIGPIPE, sig_sent); /* let them know we are working on it */ current_state = "No connection yet"; } /* * Trade edit characters with the other talk. By agreement * the first three characters each talk transmits after * connection are the three edit characters. */ void set_edit_chars(void) { char buf[3]; int cc; struct termios tios; int cerase, lerase, werase; tcgetattr(0, &tios); cerase = tios.c_cc[VERASE]; lerase = tios.c_cc[VKILL]; werase = tios.c_cc[VWERASE]; if ((unsigned char)werase == 0xff) { werase = '\027'; /* control W */ } set_my_edit_chars(cerase, lerase, werase); buf[0] = cerase; buf[1] = lerase; buf[2] = werase; cc = write(sockt, buf, sizeof(buf)); if (cc != sizeof(buf) ) p_error("Lost the connection"); cc = read(sockt, buf, sizeof(buf)); if (cc != sizeof(buf) ) p_error("Lost the connection"); cerase = buf[0]; lerase = buf[1]; werase = buf[2]; set_his_edit_chars(cerase, lerase, werase); } void sig_sent(int signum) { (void)signum; message("Connection closing. Exiting"); quit(1); } netkit-ntalk-0.17/talk/invite.c100644 144 144 13272 6774235537 16016 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)invite.c 5.8 (Berkeley) 3/1/91 */ char inv_rcsid[] = "$Id: invite.c,v 1.12 1999/09/28 22:04:15 netbug Exp $"; #include #include #include #include #include #include #include #include #include "talk.h" static void announce_invite(void); /* * There wasn't an invitation waiting, so send a request containing * our sockt address to the remote talk daemon so it can invite * him */ /* * The msg.id's for the invitations * on the local and remote machines. * These are used to delete the * invitations. */ int local_id, remote_id; void re_invite(int); sigjmp_buf invitebuf; void invite_remote(void) { /*volatile int nfd, read_mask, template;*/ volatile int new_sockt; struct itimerval itimer; CTL_RESPONSE response; struct sockaddr_in sn; socklen_t size = sizeof(sn); unsigned long int endvalue=-1; itimer.it_value.tv_sec = RING_WAIT; itimer.it_value.tv_usec = 0; itimer.it_interval = itimer.it_value; if (listen(sockt, 5) != 0) { p_error("Error on attempt to listen for caller"); } getsockname(sockt, (struct sockaddr *)&sn, &size); /* copy new style sockaddr to old */ msg.addr.ta_family = htons(AF_INET); msg.addr.ta_port = sn.sin_port; msg.addr.ta_addr = 0; /* will be patched up in ctl_transact */ msg.id_num = htonl(endvalue); /* an impossible id_num */ invitation_waiting = 1; announce_invite(); /* * Shut off the automatic messages for a while, * so we can use the interupt timer to resend the invitation */ end_msgs(); setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); message("Waiting for your party to respond"); signal(SIGALRM, re_invite); (void) sigsetjmp(invitebuf, 1); while ((new_sockt = accept(sockt, 0, 0)) < 0) { if (errno == EINTR) continue; p_error("Unable to connect with your party"); } close(sockt); sockt = new_sockt; /* * Have the daemons delete the invitations now that we * have connected. */ current_state = "Waiting for your party to respond"; start_msgs(); msg.id_num = htonl(local_id); ctl_transact(MY_DAEMON, msg, DELETE, &response); msg.id_num = htonl(remote_id); ctl_transact(HIS_DAEMON, msg, DELETE, &response); invitation_waiting = 0; } /* * Routine called on interupt to re-invite the callee */ void re_invite(int ignore) { (void)ignore; signal(SIGALRM, re_invite); message("Ringing your party again"); current_line++; /* force a re-announce */ msg.id_num = htonl(remote_id + 1); announce_invite(); siglongjmp(invitebuf, 1); } static const char *answers[] = { "answer #0", /* SUCCESS */ "Your party is not logged on", /* NOT_HERE */ "Target machine is too confused to talk to us", /* FAILED */ "Target machine does not recognize us", /* MACHINE_UNKNOWN */ "Your party is refusing messages", /* PERMISSION_REFUSED */ "Target machine can not handle remote talk", /* UNKNOWN_REQUEST */ "Target machine indicates protocol mismatch", /* BADVERSION */ "Target machine indicates protocol botch (addr)",/* BADADDR */ "Target machine indicates protocol botch (ctl_addr)",/* BADCTLADDR */ }; #define NANSWERS (sizeof (answers) / sizeof (answers[0])) /* * Transmit the invitation and process the response */ static void announce_invite(void) { CTL_RESPONSE response; current_state = "Trying to connect to your party's talk daemon"; ctl_transact(HIS_DAEMON, msg, ANNOUNCE, &response); remote_id = response.id_num; if (response.answer != SUCCESS) { if (response.answer < NANSWERS) message(answers[response.answer]); quit(0); } /* leave the actual invitation on my talk daemon */ ctl_transact(MY_DAEMON, msg, LEAVE_INVITE, &response); local_id = response.id_num; } /* * Tell the daemon to remove your invitation */ void send_delete(void) { /* * This is just a extra clean up, so just send it * and don't wait for an answer */ send_one_delete(HIS_DAEMON, remote_id); send_one_delete(MY_DAEMON, local_id); } netkit-ntalk-0.17/talk/io.c100644 144 144 6350 7136436375 15102 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)io.c 5.6 (Berkeley) 3/1/91 */ char io_rcsid[] = "$Id: io.c,v 1.13 2000/07/23 00:31:57 dholland Exp $"; /* * This file contains the I/O handling and the exchange of * edit characters. This connection itself is established in * ctl.c */ #include #include #include #include #include #include #include "talk.h" /* * The routine to do the actual talking */ void talk(void) { fd_set read_set; int nb, k; unsigned char buf[BUFSIZ]; message("Connection established"); dobeep(); dorefresh(); current_line = 0; /* * Wait on both the other process and standard input */ for (;;) { FD_ZERO(&read_set); FD_SET(0, &read_set); if (sockt>=0) FD_SET(sockt, &read_set); nb = select(sockt+2, &read_set, NULL, NULL, NULL); if (nb <= 0) { if (nb<0 && errno==EINTR) { continue; } /* panic, we don't know what happened */ p_error("Unexpected error from select"); quit(0); } if (sockt>=0 && FD_ISSET(sockt, &read_set)) { /* There is data on sockt */ nb = read(sockt, buf, sizeof(buf)); if (nb <= 0) { message("Connection closed. ^C to exit"); close(sockt); sockt = -1; } else { display(1, buf, nb); } } if (FD_ISSET(0, &read_set)) { k = dogetch(); if (k>=0 && sockt>=0) { nb = 1; buf[0] = k; display(0, buf, nb); while (write(sockt, buf, nb)==-1 && errno==EAGAIN) ; } } } } netkit-ntalk-0.17/talk/look_up.c100644 144 144 7036 6627502476 16145 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)look_up.c 5.7 (Berkeley) 3/1/91 */ char lu_rcsid[] = "$Id: look_up.c,v 1.6 1998/11/27 10:55:58 dholland Exp $"; #include #include #include #include #include #include "talk.h" static int look_for_invite(CTL_RESPONSE *rp); /* * See if the local daemon has an invitation for us. */ int check_local(void) { CTL_RESPONSE response; register CTL_RESPONSE *rp = &response; /* must be initiating a talk */ if (!look_for_invite(rp)) return 0; /* * There was an invitation waiting for us, * so connect with the other (hopefully waiting) party */ current_state = "Waiting to connect with caller"; do { if (rp->addr.ta_family != AF_INET) p_error("Response uses invalid network address"); errno = 0; if (connect(sockt, (struct sockaddr *)&rp->addr, sizeof (rp->addr)) != -1) return 1; } while (errno == EINTR); if (errno == ECONNREFUSED) { /* * The caller gave up, but his invitation somehow * was not cleared. Clear it and initiate an * invitation. (We know there are no newer invitations, * the talkd works LIFO.) */ ctl_transact(HIS_DAEMON, msg, DELETE, rp); close(sockt); open_sockt(); return 0; } p_error("Unable to connect with initiator"); /*NOTREACHED*/ return 0; } /* * Look for an invitation on 'machine' */ static int look_for_invite(CTL_RESPONSE *rp) { /* struct in_addr machine_addr; */ current_state = "Checking for invitation on caller's machine"; ctl_transact(HIS_DAEMON, msg, LOOK_UP, rp); /* the switch is for later options, such as multiple invitations */ switch (rp->answer) { case SUCCESS: msg.id_num = htonl(rp->id_num); return (1); default: /* there wasn't an invitation waiting for us */ return (0); } } netkit-ntalk-0.17/talk/msgs.c100644 144 144 6006 6627502476 15442 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)msgs.c 5.6 (Berkeley) 3/1/91 */ char msgs_rcsid[] = "$Id: msgs.c,v 1.6 1998/11/27 10:55:58 dholland Exp $"; /* * A package to display what is happening every MSG_INTERVAL seconds * if we are slow connecting. */ #include #include #include #include "talk.h" #define MSG_INTERVAL 4 const char *current_state; int current_line = 0; static void disp_msg(int ignore) { (void)ignore; message(current_state); } void start_msgs(void) { struct itimerval itimer; struct sigaction act; message(current_state); act.sa_handler = disp_msg; act.sa_flags = SA_RESTART; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGALRM); sigaction(SIGALRM, &act, NULL); itimer.it_value.tv_sec = itimer.it_interval.tv_sec = MSG_INTERVAL; itimer.it_value.tv_usec = itimer.it_interval.tv_usec = 0; setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); } void end_msgs(void) { struct itimerval itimer; struct sigaction act; timerclear(&itimer.it_value); timerclear(&itimer.it_interval); setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); act.sa_handler = SIG_DFL; act.sa_flags = SA_RESTART; sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask, SIGALRM); sigaction(SIGALRM, &act, NULL); } netkit-ntalk-0.17/talk/talk.1100644 144 144 12205 7141140316 15337 0ustar dhollandpeople.\" Copyright (c) 1983, 1990 The 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: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. .\" .\" from: @(#)talk.1 6.6 (Berkeley) 4/22/91 .\" $Id: talk.1,v 1.15 2000/07/30 23:57:02 dholland Exp $ .\" .Dd November 24, 1999 .Dt TALK 1 .Os "Linux NetKit (0.17)" .Sh NAME .Nm talk .Nd talk to another user .Sh SYNOPSIS .Nm talk .Ar person .Op Ar ttyname .Sh DESCRIPTION .Nm Talk is a visual communication program which copies lines from your terminal to that of another user. .Pp Options available: .Bl -tag -width ttyname .It Ar person If you wish to talk to someone on your own machine, then .Ar person is just the person's login name. If you wish to talk to a user on another host, then .Ar person is of the form .Ql user@host . .It Ar ttyname If you wish to talk to a user who is logged in more than once, the .Ar ttyname argument may be used to indicate the appropriate terminal name, where .Ar ttyname is of the form .Ql ttyXX or .Ql pts/X . .El .Pp When first called, .Nm talk contacts the talk daemon on the other user's machine, which sends the message .Bd -literal -offset indent -compact Message from TalkDaemon@his_machine... talk: connection requested by your_name@your_machine. talk: respond with: talk your_name@your_machine .Ed .Pp to that user. At this point, he then replies by typing .Pp .Dl talk \ your_name@your_machine .Pp It doesn't matter from which machine the recipient replies, as long as his login name is the same. Once communication is established, the two parties may type simultaneously; their output will appear in separate windows. Typing control-L (^L) .\".Ql ^L will cause the screen to be reprinted. The erase, kill line, and word erase characters (normally ^H, ^U, and ^W respectively) will behave normally. To exit, just type the interrupt character (normally ^C); .Nm talk then moves the cursor to the bottom of the screen and restores the terminal to its previous state. .Pp As of netkit-ntalk 0.15 .Nm talk supports scrollback; use esc-p and esc-n to scroll your window, and ctrl-p and ctrl-n to scroll the other window. These keys are now opposite from the way they were in 0.16; while this will probably be confusing at first, the rationale is that the key combinations with escape are harder to type and should therefore be used to scroll one's own screen, since one needs to do that much less often. .Pp If you do not want to receive talk requests, you may block them using the .Xr mesg 1 command. By default, talk requests are normally not blocked. Certain commands, in particular .Xr nroff 1 , .Xr pine 1 , and .Xr pr 1 , may block messages temporarily in order to prevent messy output. .Pp .Sh FILES .Bl -tag -width /var/run/utmp -compact .It Pa /etc/hosts to find the recipient's machine .It Pa /var/run/utmp to find the recipient's tty .El .Sh SEE ALSO .Xr mail 1 , .Xr mesg 1 , .Xr who 1 , .Xr write 1 , .Xr talkd 8 .Sh BUGS The protocol used to communicate with the talk daemon is braindead. .Pp Also, the version of .Xr talk 1 released with .Bx 4.2 uses a different and even more braindead protocol that is completely incompatible. Some vendor Unixes (particularly those from Sun) have been found to use this old protocol. .Pp Old versions of .Nm talk may have trouble running on machines with more than one IP address, such as machines with dynamic SLIP or PPP connections. This problem is fixed as of netkit-ntalk 0.11, but may affect people you are trying to communicate with. .Sh HISTORY The .Nm command appeared in .Bx 4.2 . netkit-ntalk-0.17/talk/talk.c100644 144 144 5365 6750736414 15431 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ char copyright[] = "@(#) Copyright (c) 1983 Regents of the University of California.\n" "All rights reserved.\n"; /* * From: @(#)talk.c 5.5 (Berkeley) 6/1/90 */ char talk_rcsid[] = "$Id: talk.c,v 1.3 1999/08/01 03:20:44 dholland Exp $"; #include "../version.h" #include "talk.h" /* * talk: A visual form of write. Using sockets, a two way * connection is set up between the two people talking. * With the aid of curses, the screen is split into two * windows, and each users text is added to the window, * one character at a time... * * Written by Kipp Hickman * * Modified to run under 4.1a by Clem Cole and Peter Moore * Modified to run between hosts by Peter Moore, 8/19/82 * Modified to run under 4.1c by Peter Moore 3/17/83 */ int main(int argc, char *argv[]) { get_names(argc, argv); init_display(); open_ctl(); open_sockt(); start_msgs(); if (!check_local()) invite_remote(); end_msgs(); set_edit_chars(); talk(); return 0; } netkit-ntalk-0.17/talk/talk.h100644 144 144 5756 7017164544 15436 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * from: @(#)talk.h 5.7 (Berkeley) 3/1/91 * $Id: talk.h,v 1.15 1999/11/25 07:46:44 dholland Exp $ */ /*#include */ #include #include #include "prot_talkd.h" extern int sockt; extern int invitation_waiting; extern const char *current_state; extern int current_line; void p_error(const char *string); void quit(int); void message(const char *mesg); void get_names(int argc, char *argv[]); void get_addrs(const char *); void init_display(void); void real_init_display(void); void open_ctl(void); void open_sockt(void); void start_msgs(void); int check_local(void); void invite_remote(void); void end_msgs(void); void set_edit_chars(void); void talk(void); void send_delete(void); void display(int hiswin, unsigned char *, int); void set_my_edit_chars(int ctrlh, int ctrlu, int ctrlw); void set_his_edit_chars(int ctrlh, int ctrlu, int ctrlw); void dobeep(void); void dorefresh(void); int dogetch(void); /* returns 0-255 or -1 meaning no character */ #define HIS_DAEMON 0 #define MY_DAEMON 1 void send_one_delete(int ismydaemon, int); void ctl_transact(int ismydaemon, CTL_MSG, int, CTL_RESPONSE *); extern struct in_addr his_machine_addr; extern u_short daemon_port; extern CTL_MSG msg; netkit-ntalk-0.17/.cvsignore100644 144 144 10 6775463647 15331 0ustar dhollandpeopleMCONFIG netkit-ntalk-0.17/BUGS100644 144 144 1141 7136434744 14046 0ustar dhollandpeopletalk: - support word-wrap. maybe. It's not clear what this means or how it should work if each end has a different width of screen. - handle backspacing intelligently. - there are reports that it sometimes goes into a one-line-only mode where it only prints to the top line of the screen. I can't reproduce this, I'm afraid... insight welcome. - someone should figure out some way to determine whether 8-bit input is meant to be carrying a meta-modifier bit or be text. talkd: - talk request messages should check for 8 bit tty and not clear to 7 bits. - doesn't log flash attempts. netkit-ntalk-0.17/ChangeLog100644 144 144 12065 7140623561 15154 0ustar dhollandpeople29-Jul-2000: Have talk scroll by screenfuls instead of single lines. Flip the escape-p/n and ctrl-p/n keys, so the other person's window scrolls using ctrl. The rationale is that one scrolls one's own screen much less often and ctrl-combinations are easier to type (and can be held down for repeat) - many keyboards do not have a shifting key that sends an escape prefix. 22-Jul-2000: Fix minor nonexploitable overflow. (Found by "teso".) Fix input handling to not do silly things with 8-bit text input. (noted by several people) Hopefully fix a problem where talk spews trash on tty hangup. Also fix things so that talk doesn't exit until you say so - if the connection breaks, it won't let you type any more, but you can still scroll and read everything the other guy wrote. 21-May-2000: Fix bug in otalk emulation. (Herbert Xu, herbert@gondor.apana.org.au) 21-Dec-1999: Make talk handle window resize better. 14-Dec-1999: netkit-ntalk-0.16 is released. 24-Nov-1999: Total rewrite of curses handling in talk to add support for scrollback. (David A. Holland, dholland@hcs.harvard.edu) 14-Sep-1999: Always ask curses to map input CRs to LFs. (Olaf Kirch, okir@caldera.de) 1-Aug-1999: Complete y2k and y2038 audit. 31-Jul-1999: Redid makefiles/config stuff for new confgen version. 19-Jun-1999: Fix small glitch in talkd man page. Preliminary version of code in repairs.c to handle otalk packets (at least of the kind ytalk emits). It seems current ytalk versions will hork without this. 7-Apr-1999: netkit-ntalk-0.11 released. 9-Dec-1998: We don't need to check for BSD signal semantics now; updated MCONFIG and regenerated configure script. 26-Nov-1998: Fixed bug: the talkd announce message is passed as the format string to fprintf, so if it has %'s in it, we probably crash. Copied into include directory, because we need to fiddle with it. Rearrange/clean up talkd source. Removed mytalkd.h. Added lots of checking and paranoia to packet handling. Don't reply to the ctl_addr in the packet; reply to where the packet came from. Created framework for working with bogus packets. Beefed up talkd's debug logging. Cleanup in talk. Removed talk_ctl.h. Fixed the problem where talk goes and blindly binds things to the wrong local addresses. We don't need talk.FvK.patch any more, either. Filter high-ascii control characters in talk as well as regular ones. (Olaf Kirch, okir@caldera.de) Don't zoom off the end of the string fields of the input packet in talkd. (Olaf Kirch, okir@caldera.de) 22-Sep-1997: Fix talkd to use WIFEXITED et al. rather than assume things about the bits returned by wait. 12-Jun-1997: netkit-ntalk-0.10 released. 08-Jun-1997: Pause before clearing the screen on exit. (Peter Tobias, tobias@et-inf.fho-emden.de) 19-May-1997: glibc fixes from Red Hat. 05-Apr-1997: Added configure script to generate MCONFIG. Fix problem in talkd that issued PERMISSION_DENIED instead of NOT_HERE. (Joerg Kleuver, kleuver@shadowgate.rhein.de, via Debian) Talk accepts ^H and ^? as erase characters regardless of stty settings. Better utmp handling in talkd. 08-Mar-1997: Split from full NetKit package. Generated this change log from NetKit's. 29-Dec-1996 NetKit-0.09 released. Assorted alpha/glibc patches. (Erik Troan, ewt@redhat.com) Assorted bug fixes from Debian. (Peter Tobias, tobias@et-inf.fho-emden.de) Hardened programs against DNS h_length spoofing attacks. Use inet_aton() everywhere instead of inet_addr(). 8-bit fixes to talk. (Christer Weinigel, wingel@dumburk.signum.se) Assorted fixes to talk. (Florian La Roche) Talk handles ^Z correctly now. 22-Aug-1996 NetKit-B-0.08 released. (almost) everything now compiles with lots of warnings turned on. talk now beeps correctly with ncurses (fix from Marek Rouchal .) 25-Jul-1996 NetKit-B-0.07A released. 23-Jul-1996 NetKit-B-0.07 released. Integrated a collection of patches that had been lurking on the net, including the 256-ptys support for telnetd and passive mode ftp. Major security fixes, including to fingerd, lpr, rlogin, rsh, talkd, and telnetd. Do *not* use the sliplogin from earlier versions of this package, either. talkd is flashproof. Much of the code builds without libbsd.a or bsd includes. Massive code cleanup. Almost everything compiles clean with gcc -Wall now. rusers and rusersd do not; patches to rpcgen to fix this would be appreciated if anyone feels like it. New maintainer: David A. Holland, dholland@hcs.harvard.edu date not known NetKit-B-0.06 released. Have talk be interruptable by Ctrl-Z from John Tombs (haven't tested this) date not known NetKit-B-0.05 released. Fixed talk connection problem for multihomed hosts (Pauline Middelink) This patch must be activated by editing the Makefile of "talk" as this is not the correct way to set up a linux host/solve this problem... date not known NetKit-B-0.04 released. Changes to talk and talkd from newer NetBSD versions. date not known NetKit-B-0.03 released. netkit-ntalk-0.17/MCONFIG.in100644 144 144 260 6774770341 14761 0ustar dhollandpeople# Dirs INSTALLROOT BINDIR SBINDIR MANDIR # Modes BINMODE DAEMONMODE MANMODE # Compiling ALLWARNINGS CC CFLAGS LDFLAGS LIBS # Features LIBCURSES FN(snprintf) TYPE(socklen_t) netkit-ntalk-0.17/MRULES100644 144 144 173 6310314570 14264 0ustar dhollandpeople# Standard compilation rules (don't use make builtins) %.o: %.c $(CC) $(CFLAGS) $< -c %.o: %.cc $(CC) $(CFLAGS) $< -c netkit-ntalk-0.17/Makefile100644 144 144 745 7024720305 14777 0ustar dhollandpeople# You can do "make SUB=blah" to make only a few, or edit here, or both # You can also run make directly in the subdirs you want. SUB = talk talkd %.build: (cd $(patsubst %.build, %, $@) && $(MAKE)) %.install: (cd $(patsubst %.install, %, $@) && $(MAKE) install) %.clean: (cd $(patsubst %.clean, %, $@) && $(MAKE) clean) all: $(patsubst %, %.build, $(SUB)) install: $(patsubst %, %.install, $(SUB)) clean: $(patsubst %, %.clean, $(SUB)) distclean: clean rm -f MCONFIG netkit-ntalk-0.17/README100644 144 144 10075 7141137761 14264 0ustar dhollandpeopleThis is netkit-ntalk-0.17 for Linux. This package updates netkit-ntalk-0.16. If you're reading this off a CD, go right away and check the net archives for later versions and security fixes. As of this writing the home site for NetKit is ftp://ftp.uk.linux.org/pub/linux/Networking/netkit Contents: talk Program for chatting with another user elsewhere. talkd Daemon to help set up talk sessions. Requires: Working compiler, libc, and kernel, and a recent ncurses. Security: This release contains a fix for an almost certainly unexploitable issue in netkit-ntalk-0.16 Just to be safe, we recommend not running netkit-ntalk-0.16 or earlier. Versions prior to NetKit-0.09 should not be used under any circumstances. Features: talk should now works correctly on multihomed machines (those with multiple IP addresses). talkd now contains code to hopefully detect and handle certain kinds of mangled talk packets that you may encounter. It also now has an option to log talk packets it doesn't understand; see the man page. Hopefully this will be useful if you run into interoperability problems. Other notes: Use of the "wordwrap.patch" patch is neither recommended nor discouraged. Apply it at your discretion. Installation: Do "./configure --help" and decide what options you want. The defaults should be suitable for most Linux systems. Then run the configure script. Do "make" to compile. Then (as root) do "make install". Save a backup copy of any mission-critical program in case the new one doesn't work, and so forth. We warned you. If you get gcc warnings from files in /usr/include, they are due to problems in your libc, not netkit. (You may only see them when compiling netkit because netkit turns on a lot of compiler warnings.) DEC CC: The DEC compiler for the Alpha is now freely available. This is a much better compiler with gcc, that is, it generates much better code. If you have the DEC compiler, you can explicitly use the DEC compiler instead of gcc by configuring like this: ./configure --with-c-compiler=ccc It is known to generate spurious warnings on some files. Also, some headers from some versions of glibc confuse it; that may prevent netkit from working. Other problems should be reported as bugs. Bugs: Please make sure the header files in /usr/include match the libc version installed in /lib and /usr/lib. If you have weird problems this is the most likely culprit. Also, before reporting a bug, be sure you're working with the latest version. If something doesn't compile for you, fix it and send diffs. If you can't, send the compiler's error output. If it compiles but doesn't work, send as complete a bug report as you can. Patches and fixes are welcome, as long as you describe adequately what they're supposed to fix. Please, one patch per distinct fix. Please do NOT send the whole archive back or reindent the source. Be sure to send all correspondence in e-mail to the netkit address. Postings to netnews or mailing lists will not be seen due to the enormous volume. Also, anything that doesn't get filed in the bug database is quite likely to end up forgotten. Please don't report known bugs (see the BUGS file(s)) unless you are including fixes. :-) Mail should be sent to: netbug@ftp.uk.linux.org Early in April 2000, a hacker broke into the machine that was hosting the netkit bug database for me and trashed it. Unfortunately, it seems backups hadn't gotten done for a while, so three months of mail (since mid-January) was lost. So, if you sent something and didn't hear back, or you sent something, heard back, but the changes failed to appear in this release (unlikely but possible) - please resend. Please see http://www.hcs.harvard.edu/~dholland/computers/netkit.html if you are curious why it was so long between the 0.10 and 0.16 releases. Future plans for netkit maintenance are still up in the air, but in the meantime new releases will still appear from time to time. I don't have a whole lot of cycles to spare to work on netkit, so things are likely to continue to be fairly slow. David A. Holland 23 July 2000 netkit-ntalk-0.17/configure100755 144 144 21306 7140615674 15315 0ustar dhollandpeople#!/bin/sh # # This file was generated by confgen version 2. # Do not edit. # PREFIX='/usr' #EXECPREFIX='$PREFIX' INSTALLROOT='' BINMODE='755' #DAEMONMODE='$BINMODE' MANMODE='644' while [ x$1 != x ]; do case $1 in --help) cat < __conftest.c int main() { int class=0; return class; } EOF if [ x"$CC" = x ]; then echo -n 'Looking for a C compiler... ' for TRY in egcs gcc g++ CC c++ cc; do ( $TRY __conftest.c -o __conftest || exit 1; ./__conftest || exit 1; ) >/dev/null 2>&1 || continue; CC=$TRY break; done if [ x"$CC" = x ]; then echo 'failed.' echo 'Cannot find a C compiler. Run configure with --with-c-compiler.' rm -f __conftest* exit fi echo "$CC" else echo -n 'Checking if C compiler works... ' if ( $CC __conftest.c -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo 'yes' else echo 'no' echo 'Compiler '"$CC"' does not exist or cannot compile C; try another.' rm -f __conftest* exit fi fi echo -n "Checking if $CC accepts gcc warnings... " if ( $CC $WARNINGS __conftest.c -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'yes' CC_WARNINGS=1 else echo 'no' fi if [ x$DEBUG = x ]; then echo -n "Checking if $CC accepts -O2... " if ( $CC -O2 __conftest.c -o __conftest ) >/dev/null 2>&1; then echo 'yes' CFLAGS="$CFLAGS -O2" else echo 'no' echo -n "Checking if $CC accepts -O... " if ( $CC -O __conftest.c -o __conftest ) >/dev/null 2>&1; then echo 'yes' CFLAGS="$CFLAGS -O" else echo 'no' fi fi else echo -n "Checking if $CC accepts -g... " if ( $CC -g __conftest.c -o __conftest ) >/dev/null 2>&1; then echo 'yes' CFLAGS="$CFLAGS -g" else echo 'no' fi fi LDFLAGS= LIBS= rm -f __conftest* ################################################## echo -n 'Checking for ncurses... ' cat <__conftest.c #include #include #ifndef KEY_DOWN syntax error. /* not ncurses */ #endif int main() { endwin(); return 0; } EOF if ( $CC $CFLAGS __conftest.c -lncurses -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'yes' NCURSES=1 else if ( $CC $CFLAGS -I/usr/include/ncurses __conftest.c -lncurses -o __conftest || exit 1 ) >/dev/null 2>&1; then echo '-I/usr/include/ncurses' CFLAGS="$CFLAGS -I/usr/include/ncurses" NCURSES=1 else echo 'no' fi fi if [ x$NCURSES != x ]; then LIBCURSES=-lncurses else echo -n 'Checking for traditional curses... ' cat <__conftest.c #include #include #include int main() { tgetent(NULL, NULL); endwin(); return 0; } EOF if ( $CC $CFLAGS __conftest.c -lcurses -o __conftest || exit 1 ) >/dev/null 2>&1; then echo '-lcurses' LIBCURSES=-lcurses else if ( $CC $CFLAGS __conftest.c -lcurses -ltermcap -o __conftest || exit 1 ) >/dev/null 2>&1; then echo '-lcurses -ltermcap' LIBCURSES='-lcurses -ltermcap' else echo 'not found' echo 'This package needs curses to run.' rm -f __conftest* exit fi fi fi rm -f __conftest* ################################################## echo -n 'Checking for socklen_t... ' cat <__conftest.c #include #include #include int main() { struct sockaddr_in sn; socklen_t len = sizeof(sn); getpeername(0, (struct sockaddr *)&sn, &len); return 0; } EOF if ( $CC $CFLAGS __conftest.c -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'yes' else if ( $CC $CFLAGS -Dsocklen_t=int __conftest.c -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'int' CFLAGS="$CFLAGS -Dsocklen_t=int" else if ( $CC $CFLAGS -Dsocklen_t=size_t __conftest.c -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'size_t' CFLAGS="$CFLAGS -Dsocklen_t=size_t" else echo 'no' echo 'Cannot work out what to use for socklen_t. Help...' rm -f __conftest* exit fi fi fi rm -f __conftest* ################################################## echo -n 'Checking for snprintf declaration... ' cat <__conftest.c #include int main() { void *x = (void *)snprintf; printf("%lx", (long)x); return 0; } EOF if ( $CC $CFLAGS __conftest.c -o __conftest || exit 1 ) >/dev/null 2>&1; then echo 'ok' else if ( $CC $CFLAGS -D_GNU_SOURCE __conftest.c -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo '-D_GNU_SOURCE' CFLAGS="$CFLAGS -D_GNU_SOURCE" else echo 'manual' CFLAGS="$CFLAGS -DDECLARE_SNPRINTF" fi fi rm -f __conftest* echo -n 'Checking for snprintf implementation... ' cat <__conftest.c #include #include #ifdef DECLARE_SNPRINTF #ifdef __cplusplus extern "C" #endif /*__cplusplus*/ int snprintf(char *, int, const char *, ...); #endif /*DECLARE_SNPRINTF*/ int main() { char buf[32]; snprintf(buf, 8, "%s", "1234567890"); if (strlen(buf)!=7) return 1; return 0; } EOF if ( $CC $CFLAGS __conftest.c $LIBBSD -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo 'ok' else if ( $CC $CFLAGS __conftest.c -lsnprintf $LIBBSD -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo '-lsnprintf' LIBS="$LIBS -lsnprintf" else if ( $CC $CFLAGS __conftest.c -ldb $LIBBSD -o __conftest || exit 1 ./__conftest || exit 1 ) >/dev/null 2>&1; then echo '-ldb' LIBS="$LIBS -ldb" else echo 'missing' echo 'This package requires snprintf.' rm -f __conftest* exit fi fi fi rm -f __conftest* ################################################## ## libbsd should go last in case it's broken if [ "x$LIBBSD" != x ]; then LIBS="$LIBS $LIBBSD" fi echo 'Generating MCONFIG...' ( echo -n '# Generated by configure (confgen version 2) on ' date echo '#' echo echo "BINDIR=$BINDIR" echo "SBINDIR=$SBINDIR" echo "MANDIR=$MANDIR" echo "BINMODE=$BINMODE" echo "DAEMONMODE=$DAEMONMODE" echo "MANMODE=$MANMODE" echo "PREFIX=$PREFIX" echo "EXECPREFIX=$EXECPREFIX" echo "INSTALLROOT=$INSTALLROOT" echo "CC=$CC" if [ x$CC_WARNINGS != x ]; then CFLAGS="$CFLAGS $WARNINGS" fi echo "CFLAGS=$CFLAGS" | sed 's/= */=/' echo "LDFLAGS=$LDFLAGS" | sed 's/= */=/' echo "LIBS=$LIBS" | sed 's/= */=/' echo "LIBCURSES=$LIBCURSES" ) > MCONFIG netkit-ntalk-0.17/version.h100644 144 144 146 7141140316 15166 0ustar dhollandpeople/* * String to embed in binaries to identify package */ char pkg[]="$NetKit: netkit-ntalk-0.17 $"; netkit-ntalk-0.17/wordwrap.patch100644 144 144 5772 6627513202 16256 0ustar dhollandpeopleThis patch is not applied because it implements wordwrap in a way that makes the local screen (where both your text and the other guy's text get wordwrapped) differ from the remote screen (where they don't). I'm not convinced this is a good idea. However, because the patch might be useful, it is included here. (The diffs were modified by dholland to fix some minor bugs.) Date: Fri, 17 Apr 1998 18:21:17 -0500 From: Dale Osowski Subject: talk program I have added a word wrap feature to "talk" today. I have attached the diffs to this email. I hope there isn't a problem with how I did it. I added to members to the xwin_t struct in order to keep track of where a word starts. -- Dale Osowski dosowski0474@vax2.winona.msus.edu http://web.winona.msus.edu/~dosowski --- display.c 1998/11/27 11:30:43 1.7 +++ display.c 1998/11/27 12:03:08 @@ -40,8 +40,9 @@ /* * The window 'manager', initializes curses and handles the actual * displaying of text */ +#include #include "talk.h" static void xscroll(xwin_t *win, int flag); static int readwin(WINDOW *win, int line, int col); @@ -62,8 +63,37 @@ return (a > b ? a : b); } + +/* + * Wordwrap added by Dale Osowski (dosowski0474@vax2.winona.msus.edu) + * on 4/17/98 + */ +static void +wordwrap(xwin_t *win) +{ + int oldline = win->x_lspaceline; + int oldcol = win->x_lspacecol; + int i, n = COLS-1-oldcol-1; + char *tomovedown = malloc(n); + + wmove(win->x_win, oldline, oldcol+1); + for (i=0; ix_win, oldline, i+oldcol+1); + } + + wmove(win->x_win, oldline, oldcol+1); + wclrtoeol(win->x_win); + wmove(win->x_win, oldline, oldcol+1); + xscroll(win, 0); + for (i=0; ix_win, tomovedown[i]); + } + free(tomovedown); +} + + /* * Display some text on somebody's window, processing some control * characters while we are at it. */ @@ -79,8 +109,14 @@ text++; continue; } + /* Mark position of last space. For wordwrap */ + if (*text == ' ') + { + getyx(win->x_win, win->x_lspaceline, win->x_lspacecol); + } + /* someday erase characters will work properly in unix */ if (*text == '\b' || *text == 127) *text = win->cerase; /* erase character */ @@ -142,10 +178,16 @@ text++; continue; } if (win->x_col == COLS-1) { - /* check for wraparound */ - xscroll(win, 0); + /* check for wraparound -- wordwrap */ + if (win->x_lspaceline == win->x_line && + win->x_lspacecol > 1) { + wordwrap(win); + } + else { + xscroll(win, 0); + } } if ((*text & 0x7F) < ' ' && *text != '\t') { waddch(win->x_win, '^'); getyx(win->x_win, win->x_line, win->x_col); --- talk.h 1998/11/27 10:55:58 1.13 +++ talk.h 1998/11/27 11:55:52 @@ -55,8 +55,10 @@ int x_col; char kill; char cerase; char werase; + int x_lspacecol; /* column of last space character */ + int x_lspaceline; /* line of last space character */ } xwin_t; extern xwin_t my_win; extern xwin_t his_win; netkit-ntalk-0.17/include/ 40700 144 144 0 7141142004 14657 5ustar dhollandpeoplenetkit-ntalk-0.17/include/prot_talkd.h100644 144 144 12057 6627425005 17344 0ustar dhollandpeople/* * Copyright (c) 1983, 1993 * The 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. * * @(#)talkd.h 8.1 (Berkeley) 6/2/93 */ #ifndef _PROTOCOLS_TALKD_H #define _PROTOCOLS_TALKD_H /* * This describes the protocol used by the talk server and clients. * * The talk server acts a repository of invitations, responding to * requests by clients wishing to rendezvous for the purpose of * holding a conversation. In normal operation, a client, the caller, * initiates a rendezvous by sending a CTL_MSG to the server of * type LOOK_UP. This causes the server to search its invitation * tables to check if an invitation currently exists for the caller * (to speak to the callee specified in the message). If the lookup * fails, the caller then sends an ANNOUNCE message causing the server * to broadcast an announcement on the callee's login ports requesting * contact. When the callee responds, the local server uses the * recorded invitation to respond with the appropriate rendezvous * address and the caller and callee client programs establish a * stream connection through which the conversation takes place. */ #include /* * This is a copy of 4.3BSD struct sockaddr. */ struct talk_addr { u_int16_t ta_family; u_int16_t ta_port; u_int32_t ta_addr; u_int32_t ta_junk1; u_int32_t ta_junk2; }; /* * Client->server request message format. */ #define NAME_SIZE 12 #define TTY_SIZE 16 typedef struct { u_int8_t vers; /* protocol version */ u_int8_t type; /* request type, see below */ u_int8_t answer; /* not used */ u_int8_t pad; u_int32_t id_num; /* message id */ struct talk_addr addr; /* address of client tcp port */ struct talk_addr ctl_addr; /* address of client udp port */ u_int32_t pid; /* caller's process id */ char l_name[NAME_SIZE];/* caller's name */ char r_name[NAME_SIZE];/* callee's name */ char r_tty[TTY_SIZE];/* callee's tty name */ } CTL_MSG; /* * Server->client response message format. */ typedef struct { u_int8_t vers; /* protocol version */ u_int8_t type; /* type of request message, see below */ u_int8_t answer; /* respose to request message, see below */ u_int8_t pad; u_int32_t id_num; /* message id */ struct talk_addr addr; /* address for establishing conversation */ } CTL_RESPONSE; #define TALK_VERSION 1 /* protocol version */ /* message type values */ #define LEAVE_INVITE 0 /* leave invitation with server */ #define LOOK_UP 1 /* check for invitation by callee */ #define DELETE 2 /* delete invitation by caller */ #define ANNOUNCE 3 /* announce invitation by caller */ /* answer values */ #define SUCCESS 0 /* operation completed properly */ #define NOT_HERE 1 /* callee not logged in */ #define FAILED 2 /* operation failed for unexplained reason */ #define MACHINE_UNKNOWN 3 /* caller's machine name unknown */ #define PERMISSION_DENIED 4 /* callee's tty doesn't permit announce */ #define UNKNOWN_REQUEST 5 /* request has invalid type value */ #define BADVERSION 6 /* request has invalid protocol version */ #define BADADDR 7 /* request has invalid addr value */ #define BADCTLADDR 8 /* request has invalid ctl_addr value */ /* * Operational parameters. * RING_WAIT should be 10's of seconds less than MAX_LIFE */ #define MAX_LIFE 60 /* max time daemon saves invitations */ #define RING_WAIT 30 /* time to wait before resending invitation */ #endif /* !_PROTOCOLS_TALKD_H */ netkit-ntalk-0.17/talkd/ 40700 144 144 0 7141142004 14333 5ustar dhollandpeoplenetkit-ntalk-0.17/talkd/.cvsignore100644 144 144 6 6774160722 16400 0ustar dhollandpeopletalkd netkit-ntalk-0.17/talkd/Makefile100644 144 144 1213 6750736414 16122 0ustar dhollandpeopleall: talkd include ../MCONFIG include ../MRULES CFLAGS += -I../include OBJS = talkd.o announce.o process.o table.o print.o repairs.o talkd: $(OBJS) $(CC) $(LDFLAGS) $^ $(LIBS) -o $@ $(OBJS): proto.h ../include/prot_talkd.h ../version.h install: talkd install -s -m$(DAEMONMODE) talkd $(INSTALLROOT)$(SBINDIR)/in.ntalkd ln -sf in.ntalkd $(INSTALLROOT)$(SBINDIR)/in.talkd install -m$(MANMODE) talkd.8 $(INSTALLROOT)$(MANDIR)/man8/in.ntalkd.8 ln -sf in.ntalkd.8 $(INSTALLROOT)$(MANDIR)/man8/in.talkd.8 ln -sf in.ntalkd.8 $(INSTALLROOT)$(MANDIR)/man8/ntalkd.8 ln -sf in.talkd.8 $(INSTALLROOT)$(MANDIR)/man8/talkd.8 clean: rm -f *.o talkd netkit-ntalk-0.17/talkd/announce.c100644 144 144 14257 7136336553 16467 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)announce.c 5.9 (Berkeley) 2/26/91 */ char ann_rcsid[] = "$Id: announce.c,v 1.8 2000/07/22 15:27:39 dholland Exp $"; #include #include #include #include #include #include #include #include #include #include #include #include #include "prot_talkd.h" #include "proto.h" /* * Announce an invitation to talk. * * Because the tty driver insists on attaching a terminal-less * process to any terminal that it writes on, we must fork a child * to protect ourselves. * * That hasn't been true since, hrm, 4.2BSD maybe? Even in System V, * we can use O_NOCTTY. On the other hand, forking is a good idea in * case the tty hangs. But at present we don't take advantage of that; * we'd wait() forever. */ /* * Reject control codes and other crap. * FUTURE: don't clear high ascii if the tty is in 8-bit mode * Note that we don't need to let through tabs or newlines here. */ static int safechar(int ch) { if (ch>127 || ch<32) ch = '?'; return ch; } #define max(a,b) ( (a) > (b) ? (a) : (b) ) #define N_LINES 5 #define N_CHARS 120 /* * Build a block of characters containing the message. * It is sent blank filled and in a single block to * try to keep the message in one piece if the recipient * is in, say, vi at the time. */ static void print_mesg(int fd, CTL_MSG *request, const char *remote_machine) { struct timeval clocc; struct timezone zone; struct tm *localclock; char line_buf[N_LINES][N_CHARS]; int sizes[N_LINES]; char big_buf[N_LINES*(N_CHARS+2)+16]; char *bptr, *lptr; int i, j, max_size; time_t footime; i = 0; max_size = 0; gettimeofday(&clocc, &zone); footime = clocc.tv_sec; localclock = localtime(&footime); snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; snprintf(line_buf[i], N_CHARS, "Message from Talk_Daemon@%s at %d:%02d ...", ourhostname, localclock->tm_hour, localclock->tm_min); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; snprintf(line_buf[i], N_CHARS, "talk: connection requested by %s@%s.", request->l_name, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s", request->l_name, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; bptr = big_buf; *bptr++ = ''; /* send something to wake them up */ *bptr++ = '\r'; /* add a \r in case of raw mode */ *bptr++ = '\n'; for (i = 0; i < N_LINES; i++) { /* copy the line into the big buffer */ lptr = line_buf[i]; while (*lptr != '\0') *(bptr++) = safechar(*(lptr++)); /* pad out the rest of the lines with blanks */ for (j = sizes[i]; j < max_size + 2; j++) *(bptr++) = ' '; *(bptr++) = '\r'; /* add a \r in case of raw mode */ *(bptr++) = '\n'; } *bptr = 0; write(fd, big_buf, strlen(big_buf)); } /* * See if the user is accepting messages. If so, announce that * a talk is requested. */ static int announce_proc(CTL_MSG *request, const char *remote_machine) { char full_tty[32]; int fd; struct stat stbuf; snprintf(full_tty, sizeof(full_tty), "%s/%s", _PATH_DEV, request->r_tty); if (access(full_tty, F_OK) != 0) return FAILED; fd = open(full_tty, O_WRONLY|O_NOCTTY); if (fd<0) { return (PERMISSION_DENIED); } if (fstat(fd, &stbuf) < 0) { return (PERMISSION_DENIED); } if ((stbuf.st_mode&020) == 0) { return (PERMISSION_DENIED); } print_mesg(fd, request, remote_machine); close(fd); return SUCCESS; } int announce(CTL_MSG *request, const char *remote_machine) { int pid, val, status; pid = fork(); if (pid==-1) { /* fork failed */ return FAILED; } if (pid==0) { /* child */ status = announce_proc(request, remote_machine); _exit(status); } /* we are the parent, so wait for the child */ do { val = wait(&status); if (val == -1) { if (errno == EINTR || errno == EAGAIN) continue; /* shouldn't happen */ syslog(LOG_WARNING, "announce: wait: %m"); return (FAILED); } } while (val != pid); if (WIFSIGNALED(status)) { /* we were killed by some signal */ return FAILED; } /* Send back the exit/return code */ return (WEXITSTATUS(status)); } netkit-ntalk-0.17/talkd/print.c100644 144 144 12017 6775455502 16011 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)print.c 5.8 (Berkeley) 2/26/91 */ char print_rcsid[] = "$Id: print.c,v 1.11 1999/10/02 19:21:38 dholland Exp $"; /* debug print routines */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "prot_talkd.h" #include "proto.h" #ifndef _PATH_VAR_LOG #define _PATH_VAR_LOG "/var/log/" #endif #define NTYPES 4 static const char *types[NTYPES] = { "LEAVE_INVITE", "LOOK_UP", "DELETE", "ANNOUNCE" }; #define NANSWERS 9 static const char *answers[NANSWERS] = { "SUCCESS", "NOT_HERE", "FAILED", "MACHINE_UNKNOWN", "PERMISSION_DENIED", "UNKNOWN_REQUEST", "BADVERSION", "BADADDR", "BADCTLADDR" }; static int logging, badpackets; static int logfd, packfd; void set_debug(int l, int b) { const char *file; logging = l; badpackets = b; if (logging) { file = _PATH_VAR_LOG "talkd.log"; logfd = open(file, O_WRONLY|O_APPEND); if (logfd<0) { syslog(LOG_WARNING, "%s: %s", file, strerror(errno)); logging = 0; } } if (badpackets) { file = _PATH_VAR_LOG "talkd.packets"; packfd = open(file, O_WRONLY|O_APPEND); if (packfd<0) { syslog(LOG_WARNING, "%s: %s", file, strerror(errno)); badpackets = 0; } } } static const char * print_type(int type) { static char rv[80]; if (type > NTYPES) { snprintf(rv, sizeof(rv), "type %d", type); return rv; } return types[type]; } static const char * print_answer(int answer) { static char rv[80]; if (answer > NANSWERS) { snprintf(rv, sizeof(rv), "answer %d", answer); return rv; } return answers[answer]; } void print_request(const char *cp, const CTL_MSG *mp) { char lu[NAME_SIZE+1], ru[NAME_SIZE+1], tt[TTY_SIZE+1]; char buf[1024]; const char *tp; if (!logging) return; tp = print_type(mp->type); strncpy(lu, mp->l_name, sizeof(lu)); strncpy(ru, mp->r_name, sizeof(ru)); strncpy(tt, mp->r_tty, sizeof(tt)); lu[sizeof(lu)-1]=0; ru[sizeof(ru)-1]=0; tt[sizeof(tt)-1]=0; snprintf(buf, sizeof(buf), "%s: %s: id %u, l_user %s, r_user %s, r_tty %s\n", cp, tp, mp->id_num, lu, ru, tt); write(logfd, buf, strlen(buf)); } void print_response(const char *cp, const CTL_RESPONSE *rp) { char buf[1024]; const char *tp, *ap; if (!logging) return; tp = print_type(rp->type); ap = print_answer(rp->answer); snprintf(buf, sizeof(buf), "%s: %s <-- %s, id %d\n", cp, tp, ap, ntohl(rp->id_num)); write(logfd, buf, strlen(buf)); } void debug(const char *format, ...) { char buf[1024]; va_list ap; if (!logging) return; va_start(ap, format); vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); write(logfd, buf, strlen(buf)); } void print_broken_packet(const char *pack, size_t len, struct sockaddr_in *from) { size_t i; char tmp[4], buf[128]; if (!badpackets) return; snprintf(buf, sizeof(buf), "From: %s [%u]", inet_ntoa(from->sin_addr), from->sin_addr.s_addr); write(packfd, buf, strlen(buf)); for (i=0; i #include #include #include /* #include <--- unused? */ #include #include #include #include /* #include <---- unused? */ #include #include "prot_talkd.h" #include "proto.h" static int check_one_utmp(const struct utmp *ut, const char *name) { /* * We've got uptr->ut_name, and name, neither of which is * necessarily null-terminated. Worse, either might be larger, * depending on libc version. name came from a talkd * structure, so it's at most NAME_SIZE. ut->ut_name is at * most UT_NAMESIZE. So the sum is guaranteed to hold * either... * Worse, strncmp isn't good enough. Suppose UT_NAMESIZE is 6 and * NAME_SIZE is 4, and ut_name is "abcdef" and name is "abcd". * We don't really want those to match. Now, NAME_SIZE is 12, but * UT_NAMESIZE is 256 on some platforms. I suppose maybe you *want* * to be able to have name be a prefix of ut_name in this case, or * you can't talk request people with huge names at all, but suppose * there are several such people? Argh. *punt* */ char nametmp1[UT_NAMESIZE+NAME_SIZE+1]; char nametmp2[UT_NAMESIZE+NAME_SIZE+1]; strncpy(nametmp1, name, NAME_SIZE); strncpy(nametmp2, ut->ut_name, UT_NAMESIZE); nametmp1[NAME_SIZE] = 0; nametmp2[UT_NAMESIZE] = 0; if (strcmp(nametmp1, nametmp2)!=0) { debug("utmp: %s!=%s\n", nametmp1, nametmp2); return NOT_HERE; } debug("utmp: %s==%s\n", nametmp1, nametmp2); return SUCCESS; } static int check_tty_perms(const char *tty, time_t *atime) { struct stat statb; /* our current dir is /dev, no need to prepend it */ if (stat(tty, &statb) != 0) { return FAILED; } if (!(statb.st_mode & 020)) { return PERMISSION_DENIED; } *atime = statb.st_atime; return SUCCESS; } /* * Search utmp for the local user */ static int find_user(const char *name, char *tty) { struct utmp *uptr; int found=0, ok=0, ret; time_t best_time = 0, this_time; char besttty[PATH_MAX]; *besttty = 0; setutent(); while ((uptr = getutent())!=NULL) { #ifdef USER_PROCESS if (uptr->ut_type!=USER_PROCESS) continue; #endif ret = check_one_utmp(uptr, name); if (ret!=SUCCESS) { /* wrong user */ continue; } if (*tty && !strcmp(tty, uptr->ut_line)) { /* asked for a tty, found it */ endutent(); return SUCCESS; } ret = check_tty_perms(uptr->ut_line, &this_time); if (ret != SUCCESS) { found = 1; /* but don't set ok */ continue; } found = ok = 1; if (this_time > best_time) { best_time = this_time; strcpy(besttty, uptr->ut_line); } } endutent(); strcpy(tty, besttty); return !found ? NOT_HERE : (!ok ? PERMISSION_DENIED : SUCCESS); } static void do_announce(CTL_MSG *mp, CTL_RESPONSE *rp, const char *fromhost) { CTL_MSG *ptr; int result; u_int32_t temp; /* * See if the user is logged in. * Clobbers mp->r_tty, replacing it with the tty to page them on. * (If mp->r_tty is not empty, should only return that tty, or fail.) */ result = find_user(mp->r_name, mp->r_tty); if (result != SUCCESS) { rp->answer = result; return; } ptr = find_request(mp); if (ptr == NULL) { insert_table(mp, rp); rp->answer = announce(mp, fromhost); return; } /* * Voodoo #1: if the client is opposite-endian and old/broken, * it will have added one to the id while it was byte-swapped. * Try undoing this. If it matches the id we have on file, it * was a broken attempt to re-announce. * We don't use ntohl because if we're big-endian ntohl is a nop. */ temp = byte_swap32(byte_swap32(mp->id_num)-1); if (mp->id_num > ptr->id_num || temp==ptr->id_num) { /* * This is an explicit re-announce, so update the id_num * field to avoid duplicates and re-announce the talk. */ ptr->id_num = new_id(); rp->id_num = htonl(ptr->id_num); rp->answer = announce(mp, fromhost); } else { /* duplicated or garbage request, so ignore it */ rp->id_num = htonl(ptr->id_num); rp->answer = SUCCESS; } } void process_request(CTL_MSG *mp, CTL_RESPONSE *rp, const char *fromhost) { CTL_MSG *ptr; /* Ensure null-termination */ mp->l_name[sizeof(mp->l_name)-1] = 0; mp->r_name[sizeof(mp->r_name)-1] = 0; mp->r_tty[sizeof(mp->r_tty)-1] = 0; rp->vers = TALK_VERSION; rp->type = mp->type; rp->id_num = htonl(0); if (mp->vers != TALK_VERSION) { syslog(LOG_WARNING, "Bad protocol version %d", mp->vers); rp->answer = BADVERSION; return; } mp->id_num = ntohl(mp->id_num); mp->pid = ntohl(mp->pid); print_request("process_request", mp); switch (mp->type) { case ANNOUNCE: do_announce(mp, rp, fromhost); break; case LEAVE_INVITE: ptr = find_request(mp); if (ptr != NULL) { rp->id_num = htonl(ptr->id_num); rp->answer = SUCCESS; } else insert_table(mp, rp); break; case LOOK_UP: ptr = find_match(mp); if (ptr != NULL) { rp->id_num = htonl(ptr->id_num); rp->addr = ptr->addr; rp->addr.ta_family = htons(ptr->addr.ta_family); rp->answer = SUCCESS; } else rp->answer = NOT_HERE; break; case DELETE: rp->answer = delete_invite(mp->id_num); break; default: rp->answer = UNKNOWN_REQUEST; break; } print_response("process_request", rp); } netkit-ntalk-0.17/talkd/proto.h100644 144 144 1724 6733027224 15776 0ustar dhollandpeople/* quirks for repairs.c */ #define QUIRK_NONE 0 #define QUIRK_OTALK 1 struct sockaddr_in; extern char ourhostname[]; /* print.c */ void print_request(const char *cp, const CTL_MSG *mp); void print_response(const char *cp, const CTL_RESPONSE *rp); void print_broken_packet(const char *pack, size_t len, struct sockaddr_in *); void debug(const char *fmt, ...); void set_debug(int logging, int badpackets); /* table.c */ void insert_table(CTL_MSG *request, CTL_RESPONSE *response); CTL_MSG *find_request(CTL_MSG *request); CTL_MSG *find_match(CTL_MSG *request); /* repairs.c */ u_int32_t byte_swap32(u_int32_t); int rationalize_packet(char *buf, size_t len, size_t maxlen, struct sockaddr_in *); size_t irrationalize_reply(char *buf, size_t maxbuf, int quirk); /* other */ int announce(CTL_MSG *request, const char *remote_machine); void process_request(CTL_MSG *mp, CTL_RESPONSE *rp, const char *fromhost); int new_id(void); int delete_invite(unsigned id_num); netkit-ntalk-0.17/talkd/repairs.c100644 144 144 17137 7112053001 16300 0ustar dhollandpeople/* * Copyright 1998 David A. Holland. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of the copyright holder(s) nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ char repairs_rcsid[] = "$Id: repairs.c,v 1.6 2000/05/21 21:32:49 dholland Exp $"; /* * Most, but not quite all, of the voodoo for detecting and handling * malformed packets goes here. * * Basically anything which we can detect by examining the packet we * try to do in rationalize_packet(). We return a quirk code for what * we did so we can send back replies that will make sense to the other * end. That's irrationalize_reply(). */ #include #include #include #include #include "prot_talkd.h" #include "proto.h" u_int32_t byte_swap32(u_int32_t k) { return (k<<24) | ((k&0xff00) << 8) | ((k>>8) & 0xff00) | (k>>24); } static u_int16_t byte_swap16(u_int16_t k) { return (k<<8) | (k>>8); } /***************************************************/ /* * probe for strings that are meaningful in talkd packets. * rejects all control characters and delete. newlines and tabs have * no business in tty names or usernames. */ static int probe_string(const char *buf, size_t len) { size_t i; int ch; for (i=0; isin_family; u_int16_t xfamily = byte_swap16(family); u_int16_t port = sn->sin_port; u_int16_t xport = byte_swap16(port); u_int32_t addr = sn->sin_addr.s_addr; u_int32_t xaddr = byte_swap32(addr); if (ta->ta_family != family && ta->ta_family != xfamily) return -1; if (ta->ta_port != port && ta->ta_port != xport) return -1; if (ta->ta_addr != addr && ta->ta_addr != xaddr) return -1; return 0; } /***************************************************/ /* * warning warning: in some cases this packet may need compiler * pragmas to force the compiler to not pad it. shouldn't with * gcc though. */ #define OTALK_PACKET_SIZE 76 #define OLD_NAME_SIZE 9 struct otalk_packet { char type; char l_name[OLD_NAME_SIZE]; char r_name[OLD_NAME_SIZE]; char filler; u_int32_t id_num; u_int32_t pid; char r_tty[TTY_SIZE]; struct talk_addr addr; struct talk_addr ctl_addr; }; struct otalk_reply { char type; char answer; u_int16_t filler; u_int32_t id_num; struct talk_addr addr; }; /* additional types */ #define OLD_DELETE_INVITE 4 #define OLD_AUTO_LOOK_UP 5 #define OLD_AUTO_DELETE 6 static int probe_otalk_packet(char *buf, size_t len, size_t maxlen, struct sockaddr_in *sn) { struct otalk_packet otp; CTL_MSG m; debug("Probing for QUIRK_OTALK\n"); if (sizeof(otp)!=OTALK_PACKET_SIZE) { syslog(LOG_ERR, "QUIRK_OTALK: struct otalk_packet padding " "is wrong\n"); return -1; } if (len!=sizeof(otp)) { debug("QUIRK_OTALK: wrong size\n"); return -1; } memcpy(&otp, buf, len); if (probe_string(otp.l_name, sizeof(otp.l_name))) { debug("QUIRK_OTALK: l_name not a string\n"); return -1; } if (probe_string(otp.r_name, sizeof(otp.r_name))) { debug("QUIRK_OTALK: r_name not a string\n"); return -1; } if (probe_string(otp.r_tty, sizeof(otp.r_tty))) { debug("QUIRK_OTALK: r_tty not a string\n"); return -1; } if (probe_addr(&otp.ctl_addr, sn)) { debug("QUIRK_OTALK: addresses do not match\n"); return -1; } switch (otp.type) { case LEAVE_INVITE: case LOOK_UP: case DELETE: case ANNOUNCE: break; /* I'm not sure these will work. */ case OLD_DELETE_INVITE: otp.type = DELETE; break; case OLD_AUTO_LOOK_UP: otp.type = LOOK_UP; break; case OLD_AUTO_DELETE: otp.type = DELETE; break; default: debug("QUIRK_OTALK: invalid type field\n"); return -1; } if (OLD_NAME_SIZE >= NAME_SIZE) { syslog(LOG_ERR, "QUIRK_OTALK: OLD_NAME_SIZE >= NAME_SIZE\n"); syslog(LOG_ERR, "QUIRK_OTALK: fix repairs.c and recompile\n"); return -1; } if (maxlen < sizeof(CTL_MSG)) { syslog(LOG_ERR, "QUIRK_OTALK: maxlen too small; enlarge " "inbuf[] in talkd.c and recompile\n"); return -1; } m.vers = TALK_VERSION; m.type = otp.type; m.answer = 0; m.pad = 0; m.id_num = otp.id_num; m.addr = otp.addr; m.ctl_addr = otp.ctl_addr; m.pid = otp.pid; memcpy(m.l_name, otp.l_name, OLD_NAME_SIZE); m.l_name[OLD_NAME_SIZE-1] = 0; memcpy(m.r_name, otp.r_name, OLD_NAME_SIZE); m.r_name[OLD_NAME_SIZE-1] = 0; memcpy(m.r_tty, otp.r_tty, TTY_SIZE); m.r_tty[TTY_SIZE-1] = 0; memcpy(buf, &m, sizeof(m)); return 0; } static size_t do_otalk_reply(char *buf, size_t maxlen) { struct otalk_reply or; CTL_RESPONSE *r = (CTL_RESPONSE *)buf; if (sizeof(or) > maxlen) { syslog(LOG_ERR, "QUIRK_OTALK: reply: maxlen too small; " "enlarge buf[] in send_packet and recompile\n"); return sizeof(CTL_RESPONSE); } /* * If we changed the type above, this might break. Should we encode * it in the quirk code? */ or.type = r->type; or.answer = r->answer; or.filler = 0; or.id_num = r->id_num; or.addr = r->addr; memcpy(buf, &or, sizeof(or)); return sizeof(or); } /***************************************************/ /* * Return 0 if the packet's normal, -1 if we can't figure it out, * otherwise a quirk code from the quirk list. * * For now, we don't support any quirks. Need more data. */ int rationalize_packet(char *buf, size_t len, size_t mlen, struct sockaddr_in *sn) { if (len == sizeof(CTL_MSG)) { return 0; } debug("Malformed packet (length %u)\n", len); if (probe_otalk_packet(buf, len, mlen, sn)==0) { debug("Using QUIRK_OTALK\n"); return QUIRK_OTALK; } return -1; } size_t irrationalize_reply(char *buf, size_t maxlen, int quirk) { switch (quirk) { case QUIRK_NONE: return sizeof(CTL_RESPONSE); case QUIRK_OTALK: return do_otalk_reply(buf, maxlen); } /* ? */ return 0; } netkit-ntalk-0.17/talkd/table.c100644 144 144 13132 6627455667 15753 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ /* * From: @(#)table.c 5.7 (Berkeley) 2/26/91 */ char table_rcsid[] = "$Id: table.c,v 1.9 1998/11/27 07:58:47 dholland Exp $"; /* * Routines to handle insertion, deletion, etc on the table * of requests kept by the daemon. Nothing fancy here, linear * search on a double-linked list. A time is kept with each * entry so that overly old invitations can be eliminated. * * Consider this a mis-guided attempt at modularity */ #include #include #include #include #include #include #include #include #include #include "prot_talkd.h" #include "proto.h" #define MAX_ID 16000 /* << 2^15 so I don't have sign troubles */ typedef struct table_entry { struct table_entry *next; struct table_entry *last; CTL_MSG request; time_t time; } TABLE_ENTRY; static TABLE_ENTRY *table = NULL; /* * Generate a unique non-zero sequence number */ int new_id(void) { static int current_id = 0; current_id = (current_id + 1) % MAX_ID; /* 0 is reserved, helps to pick up bugs */ if (current_id == 0) current_id = 1; return current_id; } /* * Classic delete from a double-linked list */ static void deleteit(TABLE_ENTRY *ptr) { print_request("deleteit", &ptr->request); if (table == ptr) { table = ptr->next; } else if (ptr->last != NULL) { ptr->last->next = ptr->next; } if (ptr->next != NULL) { ptr->next->last = ptr->last; } free(ptr); } /* * Go through the table and chuck out anything out of date */ static void expire(void) { time_t current_time = time(NULL); TABLE_ENTRY *ptr; for (ptr = table; ptr != NULL; ptr = ptr->next) { if ((current_time - ptr->time) > MAX_LIFE) { /* the entry is too old */ print_request("deleting expired entry", &ptr->request); deleteit(ptr); } } } /* * Look in the table for an invitation that matches the current * request looking for an invitation */ CTL_MSG * find_match(CTL_MSG *request) { TABLE_ENTRY *ptr; expire(); print_request("find_match", request); for (ptr = table; ptr != NULL; ptr = ptr->next) { print_request("", &ptr->request); if (strcmp(request->l_name, ptr->request.r_name) == 0 && strcmp(request->r_name, ptr->request.l_name) == 0 && ptr->request.type == LEAVE_INVITE) return (&ptr->request); } return NULL; } /* * Look for an identical request, as opposed to a complementary * one as find_match does */ CTL_MSG * find_request(CTL_MSG *request) { TABLE_ENTRY *ptr; expire(); /* * See if this is a repeated message. */ print_request("find_request", request); for (ptr = table; ptr != NULL; ptr = ptr->next) { print_request("", &ptr->request); if (strcmp(request->r_name, ptr->request.r_name) == 0 && strcmp(request->l_name, ptr->request.l_name) == 0 && request->type == ptr->request.type && request->pid == ptr->request.pid) { /* update the time if we 'touch' it */ ptr->time = time(NULL); return (&ptr->request); } } return NULL; } void insert_table(CTL_MSG *request, CTL_RESPONSE *response) { TABLE_ENTRY *ptr; request->id_num = new_id(); response->id_num = htonl(request->id_num); /* insert a new entry into the top of the list */ ptr = malloc(sizeof(TABLE_ENTRY)); if (ptr == NULL) { syslog(LOG_ERR, "insert_table: Out of memory"); _exit(1); } ptr->time = time(NULL); ptr->request = *request; ptr->next = table; if (ptr->next != NULL) { ptr->next->last = ptr; } ptr->last = NULL; table = ptr; } /* * Delete the invitation with id 'id_num' */ int delete_invite(unsigned id_num) { TABLE_ENTRY *ptr; ptr = table; debug("delete_invite(%d)\n", id_num); for (ptr = table; ptr != NULL; ptr = ptr->next) { if (ptr->request.id_num == id_num) break; print_request("", &ptr->request); } if (ptr != NULL) { deleteit(ptr); return SUCCESS; } return NOT_HERE; } netkit-ntalk-0.17/talkd/talkd.8100644 144 144 6542 7141140316 15645 0ustar dhollandpeople.\" Copyright (c) 1983, 1991 The 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: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. .\" .\" from: @(#)talkd.8 6.5 (Berkeley) 3/16/91 .\" $Id: talkd.8,v 1.14 2000/07/30 23:57:02 dholland Exp $ .\" .Dd March 16, 1991 .Dt TALKD 8 .Os "Linux NetKit (0.17)" .Sh NAME .Nm talkd .Nd remote user communication server .Sh SYNOPSIS .Nm talkd .Op Fl dp .Sh DESCRIPTION .Nm Talkd is the server that notifies a user that someone else wants to initiate a conversation. It acts a repository of invitations, responding to requests by clients wishing to rendezvous to hold a conversation. In normal operation, a client, the caller, initiates a rendezvous by sending a .Tn CTL_MSG to the server of type .Tn LOOK_UP (see .Aq Pa protocols/talkd.h ) . This causes the server to search its invitation tables to check if an invitation currently exists for the caller (to speak to the callee specified in the message). If the lookup fails, the caller then sends an .Tn ANNOUNCE message causing the server to broadcast an announcement on the callee's login ports requesting contact. When the callee responds, the local server uses the recorded invitation to respond with the appropriate rendezvous address and the caller and callee client programs establish a stream connection through which the conversation takes place. .Sh OPTIONS .Op Fl d Debug mode; writes copious logging and debugging information to .Pa /var/log/talkd.log . .Pp .Op Fl p Packet logging mode; writes copies of malformed packets to .Pa /var/log/talkd.packets . This is useful for debugging interoperability problems. .Sh SEE ALSO .Xr talk 1 , .Xr write 1 .Sh HISTORY The .Nm command appeared in .Bx 4.3 . netkit-ntalk-0.17/talkd/talkd.c100644 144 144 22616 6774235537 15765 0ustar dhollandpeople/* * Copyright (c) 1983 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. */ char copyright[] = "@(#) Copyright (c) 1983 Regents of the University of California.\n" "All rights reserved.\n"; /* * From: @(#)talkd.c 5.8 (Berkeley) 2/26/91 */ char talkd_rcsid[] = "$Id: talkd.c,v 1.12 1999/09/28 22:04:15 netbug Exp $"; #include "../version.h" /* * talkd - internet talk daemon * loops waiting for and processing requests until idle for a while, * then exits. */ #include #include #include #include #include #include #include #include #include /*#include */ #include #include #include #include #include "prot_talkd.h" #include "proto.h" #define TIMEOUT 30 #define MAXIDLE 120 #if !defined(MAXHOSTNAMELEN) #define MAXHOSTNAMELEN 64 #endif char ourhostname[MAXHOSTNAMELEN]; static time_t lastmsgtime; static void timeout(int ignore) { (void)ignore; if (time(NULL) - lastmsgtime >= MAXIDLE) _exit(0); signal(SIGALRM, timeout); alarm(TIMEOUT); } /* * Returns true if the address belongs to the local host. If it's * not a loopback address, try binding to it. */ static int is_local_address(u_int32_t addr) { struct sockaddr_in sn; int sock, ret; if (addr == htonl(INADDR_LOOPBACK)) { return 1; } sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock<0) { syslog(LOG_WARNING, "socket: %s", strerror(errno)); return 0; } memset(&sn, 0, sizeof(sn)); sn.sin_family = AF_INET; sn.sin_port = htons(0); sn.sin_addr.s_addr = addr; ret = bind(sock, (struct sockaddr *)&sn, sizeof(sn)); close(sock); return ret==0; } static void send_packet(CTL_RESPONSE *response, struct sockaddr_in *sn, int quirk) { char buf[2*sizeof(CTL_RESPONSE)]; size_t sz = sizeof(CTL_RESPONSE); int cc, err=0; memcpy(buf, response, sz); if (quirk) { sz = irrationalize_reply(buf, sizeof(buf), quirk); } while (sz > 0) { cc = sendto(1, buf, sz, 0, (struct sockaddr *)sn, sizeof(*sn)); if (cc<0) { syslog(LOG_WARNING, "sendto: %s", strerror(errno)); if (err) return; err = 1; } else sz -= cc; } } /* * Issue an error packet. Should not assume anything other than the * header part (the u_int8_t's) of mp is valid, and assume as little * as possible about that, since it might have been a packet we * couldn't dequirk. */ static void send_reject_packet(CTL_MSG *mp, struct sockaddr_in *sn, int code, int quirk) { CTL_RESPONSE rsp; memset(&rsp, 0, sizeof(rsp)); rsp.vers = TALK_VERSION; rsp.type = mp->type; rsp.answer = code; send_packet(&rsp, sn, quirk); } static void do_one_packet(void) { char inbuf[2*sizeof(CTL_MSG)]; int quirk = 0; CTL_RESPONSE response; CTL_MSG *mp; char theirhost[MAXHOSTNAMELEN]; const char *theirip; struct hostent *hp; struct sockaddr_in sn; int cc, i, ok; socklen_t addrlen; addrlen = sizeof(sn); cc = recvfrom(0, inbuf, sizeof(inbuf), 0, (struct sockaddr *)&sn, &addrlen); if (cc<0) { if (errno==EINTR || errno==EAGAIN) { return; } syslog(LOG_WARNING, "recvfrom: %s", strerror(errno)); return; } /* * This should be set on any input, even trash, because even * trash input will cause us to be restarted if we exit. */ lastmsgtime = time(NULL); if (addrlen!=sizeof(sn)) { syslog(LOG_WARNING, "recvfrom: bogus address length"); return; } if (sn.sin_family!=AF_INET) { syslog(LOG_WARNING, "recvfrom: bogus address family"); return; } /* * If we get here we have an address we can reply to, although * it may not be good for much. If possible, reply to it, because * if we just drop the packet the remote talk client will keep * throwing junk at us. */ theirip = inet_ntoa(sn.sin_addr); mp = (CTL_MSG *)inbuf; /* * Check they're not being weenies. * We should look into using libwrap here so hosts.deny works. * Wrapping talkd with tcpd isn't very useful. */ hp = gethostbyaddr((char *)&sn.sin_addr, sizeof(struct in_addr), AF_INET); if (hp == NULL) { syslog(LOG_WARNING, "%s: bad dns", theirip); send_reject_packet(mp, &sn, MACHINE_UNKNOWN, 0); return; } strncpy(theirhost, hp->h_name, sizeof(theirhost)); theirhost[sizeof(theirhost)-1] = 0; hp = gethostbyname(theirhost); if (hp == NULL) { syslog(LOG_WARNING, "%s: bad dns", theirip); send_reject_packet(mp, &sn, MACHINE_UNKNOWN, 0); return; } for (i=ok=0; hp->h_addr_list[i] && !ok; i++) { if (!memcmp(hp->h_addr_list[i], &sn.sin_addr, sizeof(sn.sin_addr))) ok = 1; } if (!ok) { syslog(LOG_WARNING, "%s: bad dns", theirip); send_reject_packet(mp, &sn, MACHINE_UNKNOWN, 0); return; } /* * Try to straighten out bad packets. */ quirk = rationalize_packet(inbuf, cc, sizeof(inbuf), &sn); if (quirk<0) { print_broken_packet(inbuf, cc, &sn); syslog(LOG_WARNING, "%s (%s): unintelligible packet", theirhost, theirip); send_reject_packet(mp, &sn, UNKNOWN_REQUEST, 0); return; } /* * Make sure we know what we're getting into. */ if (mp->vers!=TALK_VERSION) { syslog(LOG_WARNING, "%s (%s): bad protocol version %d", theirhost, theirip, mp->vers); send_reject_packet(mp, &sn, BADVERSION, 0); return; } /* * LEAVE_INVITE messages should only come from localhost. * Of course, old talk clients send from our hostname's IP * rather than localhost, complicating the issue... */ if (mp->type==LEAVE_INVITE && !is_local_address(sn.sin_addr.s_addr)) { syslog(LOG_WARNING, "%s (%s) sent invite packet", theirhost, theirip); send_reject_packet(mp, &sn, MACHINE_UNKNOWN, quirk); return; } /* * Junk the reply address they reported for themselves. Write * the real one over it because announce.c gets it from there. */ mp->ctl_addr.ta_family = AF_INET; mp->ctl_addr.ta_port = sn.sin_port; mp->ctl_addr.ta_addr = sn.sin_addr.s_addr; /* * Since invite messages only come from localhost, and nothing * but invite messages use the TCP address, force it to be our * address. * * Actually, if it's a local address, leave it alone. talk has * to play games to figure out the right interface address to * use, and we don't want to get into that - they can work it * out, but we can't since we don't know who they're trying to * talk to. * * If it's not a local address, someone's trying to play games * with us. Rather than trying to pick a local address to use, * reject the packet. */ if (mp->type==LEAVE_INVITE) { mp->addr.ta_family = AF_INET; if (!is_local_address(mp->addr.ta_addr)) { syslog(LOG_WARNING, "invite packet had bad return address"); send_reject_packet(mp, &sn, BADADDR, quirk); return; } } else { /* non-invite packets don't use this field */ memset(&mp->addr, 0, sizeof(mp->addr)); } process_request(mp, &response, theirhost); /* can block here, is this what I want? */ send_packet(&response, &sn, quirk); } int main(int argc, char *argv[]) { struct sockaddr_in sn; socklen_t sz = sizeof(sn); int do_debug=0, do_badpackets=0, ch; /* make sure we're a daemon */ if (getsockname(0, (struct sockaddr *)&sn, &sz)) { const char *msg = strerror(errno); write(2, msg, strlen(msg)); exit(1); } openlog("talkd", LOG_PID, LOG_DAEMON); if (gethostname(ourhostname, sizeof(ourhostname) - 1) < 0) { syslog(LOG_ERR, "gethostname: %s", strerror(errno)); exit(1); } if (chdir(_PATH_DEV) < 0) { syslog(LOG_ERR, "chdir: %s: %s", _PATH_DEV, strerror(errno)); exit(1); } while ((ch = getopt(argc, argv, "dp"))!=-1) { switch (ch) { case 'd': do_debug=1; break; case 'p': do_badpackets=1; break; } } set_debug(do_debug, do_badpackets); signal(SIGALRM, timeout); alarm(TIMEOUT); for (;;) { do_one_packet(); } /* return 0; <--- unreachable because of the above loop */ }