From d2a8c2ee9dadb6dc0c70698ed1f8a4dd726c4d274dbb76cf2bd8412a56e2f93f Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Wed, 10 Jan 2007 17:37:33 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/talk?expand=0&rev=1 --- talk.changes | 77 +++ talk.spec | 130 +++++ .gitattributes | 23 + .gitignore | 1 + netkit-ntalk-0.17-alt-talkd.patch | 31 ++ netkit-ntalk-0.17-dont-resolve.patch | 37 ++ netkit-ntalk-0.17-strip.diff | 22 + netkit-ntalk-0.17.dif | 43 ++ netkit-ntalk-0.17.tar.bz2 | 3 + netkit-ntalk-multibyte.diff | 699 +++++++++++++++++++++++++++ ntalk.xinetd | 14 + ready | 0 talk.xinetd | 14 + 13 files changed, 1094 insertions(+) create mode 100644 talk.changes create mode 100644 talk.spec create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 netkit-ntalk-0.17-alt-talkd.patch create mode 100644 netkit-ntalk-0.17-dont-resolve.patch create mode 100644 netkit-ntalk-0.17-strip.diff create mode 100644 netkit-ntalk-0.17.dif create mode 100644 netkit-ntalk-0.17.tar.bz2 create mode 100644 netkit-ntalk-multibyte.diff create mode 100644 ntalk.xinetd create mode 100644 ready create mode 100644 talk.xinetd diff --git a/talk.changes b/talk.changes new file mode 100644 index 0000000..c5ddea4 --- /dev/null +++ b/talk.changes @@ -0,0 +1,77 @@ +------------------------------------------------------------------- +Wed Jan 10 15:18:49 CET 2007 - anosek@suse.cz + +- fixed: talkd does not allow connection from hosts without DNS + record [#227396] (dont-resolve.patch) + +------------------------------------------------------------------- +Tue Sep 19 16:28:59 CEST 2006 - anosek@suse.cz + +- talk server runs as nobody.tty (originally was root.root) + +------------------------------------------------------------------- +Wed Jan 25 21:42:00 CET 2006 - mls@suse.de + +- converted neededforbuild to BuildRequires + +------------------------------------------------------------------- +Sun Jan 15 19:02:48 CET 2006 - schwab@suse.de + +- Don't strip binaries. + +------------------------------------------------------------------- +Tue Jun 21 01:04:51 CEST 2005 - ro@suse.de + +- build with fPIE/pie + +------------------------------------------------------------------- +Mon Sep 20 15:47:02 CEST 2004 - postadal@suse.cz + +- fixed DoS [#44756] (alt-talkd.patch) + +------------------------------------------------------------------- +Thu Feb 26 12:18:15 CET 2004 - hmacht@suse.de + +- building as non-root + +------------------------------------------------------------------- +Tue Mar 4 11:08:39 CET 2003 - kraxel@suse.de + +- yet another multibyte patch fix (line erase not working correctly). + +------------------------------------------------------------------- +Mon Feb 24 17:24:24 CET 2003 - vbobek@suse.cz + +- created config file for xinetd + +------------------------------------------------------------------- +Tue Jan 14 15:43:12 CET 2003 - kraxel@suse.de + +- more multibyte patch fixes. + +------------------------------------------------------------------- +Tue Dec 17 18:37:53 CET 2002 - kraxel@suse.de + +- various minor fixes in the multibyte patch. + +------------------------------------------------------------------- +Wed Dec 11 19:48:58 CET 2002 - kraxel@suse.de + +- added locale and multibyte support. + +------------------------------------------------------------------- +Thu Mar 22 18:51:02 CET 2001 - ro@suse.de + +- added split-aliases as provides + +------------------------------------------------------------------- +Fri Mar 16 13:47:44 CET 2001 - cihlar@suse.cz + +- added Url +- claen up spec file + +------------------------------------------------------------------- +Fri Mar 2 15:54:23 CET 2001 - kukuk@suse.de + +- Initial package, split from nkitb + diff --git a/talk.spec b/talk.spec new file mode 100644 index 0000000..e4d919b --- /dev/null +++ b/talk.spec @@ -0,0 +1,130 @@ +# +# spec file for package talk (Version 0.17) +# +# Copyright (c) 2007 SUSE LINUX Products GmbH, Nuernberg, Germany. +# This file and all modifications and additions to the pristine +# package are under the same license as the package itself. +# +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +# norootforbuild + +Name: talk +License: BSD License and BSD-like +Group: Productivity/Networking/Talk/Clients +Provides: nkitb:/usr/bin/talk +Autoreqprov: on +Version: 0.17 +Release: 592 +Summary: Talk Client for Chatting with Another User +BuildRoot: %{_tmppath}/%{name}-%{version}-build +URL: ftp://ftp.uk.linux.org/pub/linux/Networking/netkit/ +Source: netkit-ntalk-%{version}.tar.bz2 +Source1: talk.xinetd +Source2: ntalk.xinetd +Patch: netkit-ntalk-%{version}.dif +Patch1: netkit-ntalk-multibyte.diff +Patch2: netkit-ntalk-%{version}-alt-talkd.patch +Patch3: netkit-ntalk-%{version}-strip.diff +Patch4: netkit-ntalk-%{version}-dont-resolve.patch + +%description +This package contains the talk client, which allows you to chat with +another user on a different system. Talk is a communication program +which copies lines from one terminal to that of another user. + + + +%package server +Version: 0.17 +Release: 592 +Summary: Talk Daemon to Chat with Another User +Group: Productivity/Networking/Talk/Servers +Requires: net-tools netcfg +Provides: nkitserv:/usr/sbin/in.talkd +Autoreqprov: on + +%description server +This package contains the talk daemon, which allows you to chat with +another user on a different system. Talk is a communication program +which copies lines from one terminal to the terminal of another user. + + + +%prep +%setup -n netkit-ntalk-%{version} +%patch +%patch1 -p1 -b .mb +%patch2 -p1 +%patch3 +%patch4 + +%build +CFLAGS="$RPM_OPT_FLAGS" ./configure +cat <<-EOF >> MCONFIG + LIBCURSES=-lncursesw + CFLAGS += -D_GNU_SOURCE -fPIE + LDFLAGS += -pie +EOF +make + +%install +install -d -m 755 $RPM_BUILD_ROOT/etc/xinetd.d +install -d -m 755 $RPM_BUILD_ROOT/usr/{bin,sbin} +install -d -m 755 $RPM_BUILD_ROOT%{_mandir}/man{1,8} +make install INSTALLROOT=$RPM_BUILD_ROOT +install -m 644 %{S:1} $RPM_BUILD_ROOT/etc/xinetd.d/talk +install -m 644 %{S:2} $RPM_BUILD_ROOT/etc/xinetd.d/ntalk + +%clean +[ -d %{buildroot} -a "%{buildroot}" != "" ] && rm -rf %{buildroot} + +%files +%defattr(-,root,root) +%doc BUGS ChangeLog +/usr/bin/talk +%doc %{_mandir}/man1/* + +%files server +%defattr(-,root,root) +%doc BUGS ChangeLog +%doc %{_mandir}/man8/* +/usr/sbin/in.ntalkd +/usr/sbin/in.talkd +%config(noreplace) /etc/xinetd.d/talk +%config(noreplace) /etc/xinetd.d/ntalk + +%changelog -n talk +* Wed Jan 10 2007 - anosek@suse.cz +- fixed: talkd does not allow connection from hosts without DNS + record [#227396] (dont-resolve.patch) +* Tue Sep 19 2006 - anosek@suse.cz +- talk server runs as nobody.tty (originally was root.root) +* Wed Jan 25 2006 - mls@suse.de +- converted neededforbuild to BuildRequires +* Sun Jan 15 2006 - schwab@suse.de +- Don't strip binaries. +* Tue Jun 21 2005 - ro@suse.de +- build with fPIE/pie +* Mon Sep 20 2004 - postadal@suse.cz +- fixed DoS [#44756] (alt-talkd.patch) +* Thu Feb 26 2004 - hmacht@suse.de +- building as non-root +* Tue Mar 04 2003 - kraxel@suse.de +- yet another multibyte patch fix (line erase not working correctly). +* Mon Feb 24 2003 - vbobek@suse.cz +- created config file for xinetd +* Tue Jan 14 2003 - kraxel@suse.de +- more multibyte patch fixes. +* Tue Dec 17 2002 - kraxel@suse.de +- various minor fixes in the multibyte patch. +* Wed Dec 11 2002 - kraxel@suse.de +- added locale and multibyte support. +* Thu Mar 22 2001 - ro@suse.de +- added split-aliases as provides +* Fri Mar 16 2001 - cihlar@suse.cz +- added Url +- claen up spec file +* Fri Mar 02 2001 - kukuk@suse.de +- Initial package, split from nkitb diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/netkit-ntalk-0.17-alt-talkd.patch b/netkit-ntalk-0.17-alt-talkd.patch new file mode 100644 index 0000000..64324f7 --- /dev/null +++ b/netkit-ntalk-0.17-alt-talkd.patch @@ -0,0 +1,31 @@ +--- netkit-ntalk-0.17/talkd/talkd.c.orig 1999-09-29 02:04:15 +0400 ++++ netkit-ntalk-0.17/talkd/talkd.c 2004-09-05 19:20:50 +0400 +@@ -68,6 +68,7 @@ char talkd_rcsid[] = + + #define TIMEOUT 30 + #define MAXIDLE 120 ++#define MINUDPSRCPORT 1024 + + #if !defined(MAXHOSTNAMELEN) + #define MAXHOSTNAMELEN 64 +@@ -167,6 +168,7 @@ do_one_packet(void) + struct sockaddr_in sn; + int cc, i, ok; + socklen_t addrlen; ++ int theirport; + + addrlen = sizeof(sn); + cc = recvfrom(0, inbuf, sizeof(inbuf), 0, +@@ -194,6 +196,12 @@ do_one_packet(void) + return; + } + ++ theirport = ntohs(sn.sin_port); ++ if (theirport < MINUDPSRCPORT) { ++ syslog(LOG_WARNING, "%d: bad port", theirport); ++ 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 diff --git a/netkit-ntalk-0.17-dont-resolve.patch b/netkit-ntalk-0.17-dont-resolve.patch new file mode 100644 index 0000000..4cca17c --- /dev/null +++ b/netkit-ntalk-0.17-dont-resolve.patch @@ -0,0 +1,37 @@ +--- talkd/talkd.c ++++ talkd/talkd.c +@@ -220,28 +220,13 @@ + 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; ++ strncpy(theirhost, theirip, sizeof(theirhost)); ++ theirhost[sizeof(theirhost)-1] = 0; + } ++ else { ++ strncpy(theirhost, hp->h_name, sizeof(theirhost)); ++ theirhost[sizeof(theirhost)-1] = 0; ++ } + + /* + * Try to straighten out bad packets. diff --git a/netkit-ntalk-0.17-strip.diff b/netkit-ntalk-0.17-strip.diff new file mode 100644 index 0000000..b071b14 --- /dev/null +++ b/netkit-ntalk-0.17-strip.diff @@ -0,0 +1,22 @@ +--- talk/Makefile ++++ talk/Makefile +@@ -16,7 +16,7 @@ + $(OBJS): talk.h ../include/prot_talkd.h ../version.h + + install: talk +- install -s -m$(BINMODE) talk $(INSTALLROOT)$(BINDIR) ++ install -m$(BINMODE) talk $(INSTALLROOT)$(BINDIR) + install -m$(MANMODE) talk.1 $(INSTALLROOT)$(MANDIR)/man1/ + + clean: +--- talkd/Makefile ++++ talkd/Makefile +@@ -13,7 +13,7 @@ + $(OBJS): proto.h ../include/prot_talkd.h ../version.h + + install: talkd +- install -s -m$(DAEMONMODE) talkd $(INSTALLROOT)$(SBINDIR)/in.ntalkd ++ install -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 diff --git a/netkit-ntalk-0.17.dif b/netkit-ntalk-0.17.dif new file mode 100644 index 0000000..0aebd67 --- /dev/null +++ b/netkit-ntalk-0.17.dif @@ -0,0 +1,43 @@ +--- configure ++++ configure 2001/02/23 11:22:13 +@@ -55,7 +55,7 @@ + + BINDIR="$EXECPREFIX/bin" + SBINDIR="$EXECPREFIX/sbin" +-MANDIR="$PREFIX/man" ++MANDIR="$PREFIX/share/man" + + echo "Directories: $BINDIR $SBINDIR $MANDIR " + +--- talk/ctl_transact.c ++++ talk/ctl_transact.c 2001/02/23 11:22:13 +@@ -37,6 +37,8 @@ + char ctlt_rcsid[] = + "$Id: ctl_transact.c,v 1.12 1999/09/28 22:04:14 netbug Exp $"; + ++#define _GNU_SOURCE ++ + #include + #include + #include +--- talk/msgs.c ++++ talk/msgs.c 2001/02/23 11:22:13 +@@ -42,6 +42,8 @@ + * if we are slow connecting. + */ + ++#define _GNU_SOURCE ++ + #include + #include + #include +--- talkd/announce.c ++++ talkd/announce.c 2001/02/23 11:22:13 +@@ -49,6 +49,7 @@ + #include + #include + #include ++#include + #include "prot_talkd.h" + #include "proto.h" + diff --git a/netkit-ntalk-0.17.tar.bz2 b/netkit-ntalk-0.17.tar.bz2 new file mode 100644 index 0000000..500028c --- /dev/null +++ b/netkit-ntalk-0.17.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d6c3637773139b423773369325d6bcffdb4d2ea707c7daf8b935a220702a7b2 +size 32111 diff --git a/netkit-ntalk-multibyte.diff b/netkit-ntalk-multibyte.diff new file mode 100644 index 0000000..d231e99 --- /dev/null +++ b/netkit-ntalk-multibyte.diff @@ -0,0 +1,699 @@ +--- netkit-ntalk-0.17/talk/display.c.mb 2000-07-29 20:50:27.000000000 +0200 ++++ netkit-ntalk-0.17/talk/display.c 2003-03-04 11:04:36.000000000 +0100 +@@ -39,6 +39,11 @@ + * From: @(#)display.c 5.4 (Berkeley) 6/1/90 + * + * Heavily modified 11/99 by dholland to add scrollback support. ++ * ++ * multibyte support 2002 by Gerd Knorr ++ * also got window resize without crashing for free because ++ * I had to replace some fixed-length arrays by dynamically ++ * allocated ones :-) + */ + char display_rcsid[] = + "$Id: display.c,v 1.15 2000/07/29 18:50:27 dholland Exp $"; +@@ -49,16 +54,21 @@ + */ + #include + #include ++#include + #include + #include + #include ++#include ++#include + #include ++#include ++#include + #include "talk.h" + + #define MAX_MAXLINES 16384 + + typedef struct { +- char *l_text; ++ wchar_t *l_text; + } line; + + typedef struct { +@@ -66,9 +76,11 @@ + 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 */ ++ char *s_typebuf_raw; /* Current input line */ ++ int s_typebuf_len; /* Current position in input line */ ++ wchar_t *s_typebuf_w; ++ int s_typebuf_wlen; + 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 */ +@@ -79,6 +91,18 @@ + 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 */ ++char *peer_encoding = NULL; ++ ++static void ++wait_for_data(int fd) ++{ ++ fd_set se; ++ ++ FD_ZERO(&se); ++ FD_SET(fd,&se); ++ select(fd+1,&se,NULL,NULL,NULL); ++} ++ + + static + void +@@ -105,10 +129,12 @@ + + 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->s_typebufpos = 0; ++ win->s_typebuf_len = 0; ++ win->s_typebuf_raw = NULL; ++ win->s_typebuf_wlen = 64; ++ win->s_typebuf_w = malloc((win->s_typebuf_wlen+1) * ++ sizeof(wchar_t)); + + win->cerase = 2; /* ^B */ + win->werase = 23; /* ^W */ +@@ -142,6 +168,7 @@ + /* Set curses modes. */ + cbreak(); + noecho(); ++ nodelay(stdscr,1); /* otherwise get_wch() may block */ + nl(); /* force cr->lf */ + + init_window(&my_win); +@@ -188,10 +215,10 @@ + 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); ++ addwstr(win->s_lines[line].l_text); + } + else if (line==win->s_nlines) { +- addstr(win->s_typebuf); ++ addwstr(win->s_typebuf_w); + } + clrtoeol(); + } +@@ -266,81 +293,65 @@ + 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 ++char* + dogetch(void) + { +- int k = do_one_getch(); ++ static int gotesc = 0; + int scrl = sepline-2; /* number of lines to scroll by */ ++ wint_t k; ++ wchar_t wc[2]; ++ static char mbs[16]; ++ ++#if 1 ++ /* not implemented in older libncursesw versions */ ++ if (OK != get_wch(&k)) ++ k = L'?'; ++#else ++ /* buggy due to stdio buffering (cut+paste shows this nicely) */ ++ k = getwchar(); ++#endif ++ if (WEOF == k) ++ return NULL; + +- if (k==('p'|256)) { /* M-p: scroll our window up */ ++ if (!gotesc && k == 27) { ++ gotesc = 1; ++ return NULL; ++ } ++ ++ if (gotesc && k==L'p') { /* M-p: scroll our window up */ + doscroll(&my_win, scrl); ++ gotesc = 0; ++ return NULL; + } +- else if (k==('n'|256)) { /* M-n: scroll our window down */ ++ else if (gotesc && k==L'n') { /* M-n: scroll our window down */ + doscroll(&my_win, -scrl); ++ gotesc = 0; ++ return NULL; + } +- else if (k==('p'&31)) { /* C-p: scroll other window up */ ++ else if (k==(L'p'&31)) { /* C-p: scroll other window up */ + doscroll(&his_win, scrl); ++ return NULL; + } +- else if (k==('n'&31)) { /* C-n: scroll other window down */ ++ else if (k==(L'n'&31)) { /* C-n: scroll other window down */ + doscroll(&his_win, -scrl); ++ return NULL; + } + else if (k == '\f') { /* C-l: reprint */ + clear(); + dorefresh(); ++ return NULL; + } +- else if (k>=0) { +- return k; +- } +- return -1; ++ ++ gotesc = 0; ++ wc[0] = k; ++ wc[1] = L'\0'; ++ wcstombs(mbs,wc,sizeof(mbs)); ++ return mbs; + } + + /**************************************************************/ +@@ -349,8 +360,11 @@ + void + display_lerase(window *win) + { +- win->s_typebuf[0] = 0; +- win->s_typebufpos = 0; ++ free(win->s_typebuf_raw); ++ win->s_typebuf_raw = NULL; ++ win->s_typebuf_len = 0; ++ win->s_typebuf_w[0] = L'\0'; ++ win->s_typebufpos = 0; + } + + static +@@ -371,7 +385,7 @@ + display_eol(window *win) + { + line *tmpl; +- char *tmps; ++ wchar_t *tmps; + + if (win->s_nlines == win->s_maxlines) { + if (win->s_maxlines < MAX_MAXLINES) { +@@ -393,7 +407,7 @@ + } + assert(win->s_nlines < win->s_maxlines); + +- while ((tmps = strdup(win->s_typebuf))==NULL && win->s_nlines>0) { ++ while ((tmps = wcsdup(win->s_typebuf_w))==NULL && win->s_nlines>0) { + discard_top_line(win); + } + if (!tmps) { +@@ -407,61 +421,84 @@ + if (win==&my_win) topmessage = NULL; + } + +-static +-void +-display_addch(window *win, int ch) ++static wchar_t *try_convert(char *charset, char *src, size_t ilen) + { +- /* +- * 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, ' '); +- } +-} ++ size_t olen; ++ wchar_t *dest; ++ char *d; ++ iconv_t ic; ++ int rc; ++ ++ ic = iconv_open("WCHAR_T", charset); ++ if (NULL == ic) ++ return NULL; ++ ++ dest = malloc((ilen+1) * sizeof(wchar_t)); ++ d = (char*)dest; ++ if (NULL == dest) ++ p_error("Out of memory"); ++ olen = ilen * sizeof(wchar_t); ++ rc = iconv(ic,&src,&ilen,&d,&olen); ++ iconv_close(ic); ++ if (-1 == rc) { ++ free(dest); ++ return NULL; ++ } ++ *((wchar_t*)d) = L'\0'; ++ return dest; ++} ++ ++static int convert_back(char *charset, ++ char *dest, int dlen, ++ wchar_t *src, int slen) ++{ ++ size_t ilen,olen; ++ char *ibuf,*obuf; ++ iconv_t ic; ++ ++ ic = iconv_open(charset, "WCHAR_T"); ++ if (NULL == ic) ++ return -1; + +-static +-void +-display_cerase(window *win) +-{ +- if (win->s_typebufpos > 0) { +- win->s_typebuf[--win->s_typebufpos] = 0; ++ ilen = slen * sizeof(wchar_t); ++ olen = dlen; ++ ibuf = (char*)src; ++ obuf = dest; ++ iconv(ic,&ibuf,&ilen,&obuf,&olen); ++ iconv_close(ic); ++ return obuf - dest; ++} ++ ++static int display_addchar(window *win, int *out, int *pos, wchar_t ch) ++{ ++ int width; ++ ++ width = wcwidth(ch); ++ if (-1 == width) ++ /* non-printable by the current locale */ ++ ch = L'?'; ++ width = wcwidth(ch); ++ ++ if (*out >= win->s_typebuf_wlen) { ++ win->s_typebuf_wlen += 16; ++ win->s_typebuf_w = realloc(win->s_typebuf_w, ++ (win->s_typebuf_wlen+1) * ++ sizeof(wchar_t)); ++ if (NULL == win->s_typebuf_w) ++ p_error("Out of memory"); + } ++ if (*pos + width > COLS-1) ++ return -1; ++ win->s_typebuf_w[*out] = ch; ++ *out += 1; ++ *pos += width; ++ return 0; + } + +-static +-void +-display_werase(window *win) ++static void display_delchar(window *win, int *out, int *pos) + { +- /* +- * 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; ++ *out -= 1; ++ *pos -= wcwidth(win->s_typebuf_w[*out]); + } + + /* +@@ -471,46 +508,141 @@ + void + display(int hiswin, unsigned char *text, int size) + { +- int j; ++ static char msg[80]; ++ int in,out,pos; ++ wchar_t *tmp; ++ int tmplen; ++ char *lcharset,*charset = NULL; + 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) { ++ /* append new data to current line */ ++ win->s_typebuf_raw = realloc(win->s_typebuf_raw, ++ win->s_typebuf_len + size); ++ if (NULL == win->s_typebuf_raw) ++ p_error("Out of memory"); ++ memcpy(win->s_typebuf_raw+win->s_typebuf_len,text,size); ++ win->s_typebuf_len += size; + +- /* someday erase characters will work right in unix */ +- display_cerase(win); +- } +- else if (text[j] == win->werase) { +- display_werase(win); ++ /* convert the line to wchar_t */ ++ lcharset = nl_langinfo(CODESET); ++ if (hiswin) { ++ /* ++ * Because as talk doesn't say what charset the other ++ * end uses, we have to do some guesswork here ... ++ * ++ * Very first try is encoding specified on the command ++ * line option (if present). ++ * ++ * First try is utf-8 which is easy to identify ++ * because iconv very likely failes if the guess is ++ * wrong (or it doesn't matter if the guess is wrong ++ * because the received text is plain us-ascii which ++ * in turn is a subset utf-8 ...). ++ * ++ * Next try is the charset used by the current ++ * locale, taking in account that the people talking ++ * to each other likely use the same language and ++ * thus the same locale. ++ * ++ * If nothing else works, we use iso-8859-1 as ++ * fallback. ++ */ ++ char *try[] = { ++ peer_encoding, ++ "UTF-8", ++ lcharset, ++ "ISO-8859-1", ++ }; ++ size_t i; ++ ++ for (i = 0, tmp = NULL; i < sizeof(try)/sizeof(char*); i++) { ++ if (NULL == try[i]) ++ continue; ++ charset = try[i]; ++ tmp = try_convert(charset,win->s_typebuf_raw, ++ win->s_typebuf_len); ++ if (tmp) ++ break; ++ } ++#if 1 ++ /* nice for trouble shooting ... */ ++ sprintf(msg,"guessed peer charset: %s",charset); ++ message(msg); ++#endif ++ } else { ++ charset = lcharset; ++ tmp = try_convert(charset,win->s_typebuf_raw, ++ win->s_typebuf_len); ++ } ++ if (NULL == tmp) ++ p_error("iconv"); ++ ++ /* (re-)build wchar_t line buffer */ ++ tmplen = wcslen(tmp); ++ ++ for (in = 0, out = 0, pos = 0; in < tmplen; in++) { ++ if (tmp[in] == L'\n' || tmp[in]==L'\r') { ++ break; ++ } ++ else if (tmp[in]==L'\b' || ++ tmp[in]==127 || ++ tmp[in]==win->cerase) { ++ if (out > 0) ++ display_delchar(win,&out,&pos); ++ } ++ else if (tmp[in] == win->werase) { ++ while (out > 0 && win->s_typebuf_w[out-1] != L' ') ++ display_delchar(win,&out,&pos); + } +- else if (text[j] == win->lerase) { ++ else if (tmp[in] == win->lerase) { + /* line kill */ +- display_lerase(win); ++ out = 0; ++ pos = 0; + } +- else if (text[j] == '\a') { +- beep(); ++ else if (tmp[in] == L'\a') { ++ if (in+1 == tmplen) ++ beep(); + } +- else if (text[j] == '\f') { ++ else if (tmp[in] == '\f') { + /* nothing */ + } +- else if (text[j] == '\t') { +- display_tab(win); ++ else if (tmp[in] == L'\t') { ++ while ((out % 8) != 0) { ++ if (-1 == display_addchar(win,&out,&pos,L' ')) ++ break; ++ } ++ if ((out % 8) != 0) ++ break; ++ } ++ else if ((tmp[in]) < L' ') { ++ if (-1 == display_addchar(win,&out,&pos,L'^')) ++ break; ++ if (-1 == display_addchar(win,&out,&pos,tmp[in] + 64)) ++ break; + } +- else if ((text[j] & 0x7F) < ' ') { +- display_addch(win, '^'); +- display_addch(win, (text[j] & 63) + 64); +- } + else { +- display_addch(win, text[j]); ++ if (-1 == display_addchar(win,&out,&pos,tmp[in])) ++ break; + } + } +- dorefresh(); ++ win->s_typebuf_w[out] = L'\0'; ++ win->s_typebufpos = pos; ++ ++ if (in != tmplen) { ++ /* line break */ ++ display_eol(win); ++ if (tmp[in] == L'\n' || tmp[in]==L'\r') ++ in++; ++ } ++ if (in != tmplen) { ++ /* more data for the next line ... */ ++ size = convert_back(charset,text,size,tmp+in,tmplen-in); ++ display(hiswin,text,size); ++ } else { ++ dorefresh(); ++ } ++ free(tmp); + } + + /**************************************************************/ +@@ -586,6 +718,7 @@ + + if (hold) { + /* alternative screen, wait before exiting */ ++ wait_for_data(0); + getch(); + } + +@@ -603,6 +736,7 @@ + if (direct != 1 && hold) { + /* alternative screen, prompt before exit */ + middle_message("Press any key to exit", ""); ++ wait_for_data(0); + getch(); + } + else { +--- netkit-ntalk-0.17/talk/io.c.mb 2000-07-23 02:31:57.000000000 +0200 ++++ netkit-ntalk-0.17/talk/io.c 2003-03-03 16:40:08.000000000 +0100 +@@ -58,7 +58,8 @@ + talk(void) + { + fd_set read_set; +- int nb, k; ++ int nb; ++ char *k; + unsigned char buf[BUFSIZ]; + + message("Connection established"); +@@ -97,11 +98,10 @@ + } + 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 && ++ if (NULL != k && sockt>=0) { ++ nb = strlen(k); ++ display(0, k, nb); ++ while (write(sockt, k, nb)==-1 && + errno==EAGAIN) + ; + } +--- netkit-ntalk-0.17/talk/talk.c.mb 1999-08-01 05:20:44.000000000 +0200 ++++ netkit-ntalk-0.17/talk/talk.c 2003-03-03 16:40:08.000000000 +0100 +@@ -41,6 +41,11 @@ + char talk_rcsid[] = + "$Id: talk.c,v 1.3 1999/08/01 03:20:44 dholland Exp $"; + ++#include ++#include ++#include ++#include ++#include + #include "../version.h" + + #include "talk.h" +@@ -62,7 +67,28 @@ + int + main(int argc, char *argv[]) + { +- get_names(argc, argv); ++ int c; ++ ++ if (NULL == setlocale(LC_ALL,"")) { ++ fprintf(stderr,"warning: locale not supported by libc\n"); ++ /* give the user the chance to read the error message ++ * before init_display() clears the screen ... */ ++ sleep(3); ++ } ++ ++ for (;;) { ++ if (-1 == (c = getopt(argc, argv, "p:"))) ++ break; ++ switch (c) { ++ case 'p': ++ peer_encoding = optarg; ++ break; ++ default: ++ exit(1); ++ } ++ } ++ get_names(argc - optind+1, argv + optind-1); ++ + init_display(); + open_ctl(); + open_sockt(); +--- netkit-ntalk-0.17/talk/talk.h.mb 1999-11-25 08:46:44.000000000 +0100 ++++ netkit-ntalk-0.17/talk/talk.h 2003-03-03 16:40:08.000000000 +0100 +@@ -68,7 +68,7 @@ + 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 */ ++char* dogetch(void); /* returns mbs or NULL meaning no character */ + + #define HIS_DAEMON 0 + #define MY_DAEMON 1 +@@ -78,3 +78,4 @@ + extern struct in_addr his_machine_addr; + extern u_short daemon_port; + extern CTL_MSG msg; ++extern char *peer_encoding; +--- netkit-ntalk-0.17/talk/talk.1.mb 2000-07-31 01:57:02.000000000 +0200 ++++ netkit-ntalk-0.17/talk/talk.1 2003-03-03 16:40:08.000000000 +0100 +@@ -40,6 +40,7 @@ + .Nd talk to another user + .Sh SYNOPSIS + .Nm talk ++[-p encoding] + .Ar person + .Op Ar ttyname + .Sh DESCRIPTION +@@ -48,7 +49,11 @@ + terminal to that of another user. + .Pp + Options available: +-.Bl -tag -width ttyname ++.Bl -tag -width encoding ++.It Ar encoding ++The charset encoding sent by your peer (i.e. UTF-8, ISO-8859-1, ++EUC-JP, whatever). Default is some guesswork based on the incoming ++data and your current locate. + .It Ar person + If you wish to talk to someone on your own machine, then + .Ar person +--- netkit-ntalk-0.17/talkd/announce.c.mb 2003-03-03 16:40:08.000000000 +0100 ++++ netkit-ntalk-0.17/talkd/announce.c 2003-03-03 16:40:08.000000000 +0100 +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/ntalk.xinetd b/ntalk.xinetd new file mode 100644 index 0000000..e9a6c60 --- /dev/null +++ b/ntalk.xinetd @@ -0,0 +1,14 @@ +# default: off +# description: The talk server accepts talk requests for chatting with users \ +# on other systems. +service ntalk +{ + flags = IPv4 + socket_type = dgram + protocol = udp + wait = yes + user = nobody + group = tty + server = /usr/sbin/in.talkd + disable = yes +} diff --git a/ready b/ready new file mode 100644 index 0000000..473a0f4 diff --git a/talk.xinetd b/talk.xinetd new file mode 100644 index 0000000..d58c968 --- /dev/null +++ b/talk.xinetd @@ -0,0 +1,14 @@ +# default: off +# description: The talk server accepts talk requests for chatting with users \ +# on other systems. +service talk +{ + flags = IPv4 + socket_type = dgram + protocol = udp + wait = yes + user = nobody + group = tty + server = /usr/sbin/in.talkd + disable = yes +}