Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v23i006: ttywatch - shell window popup daemon, Part01/01

7 views
Skip to first unread message

Alastair Rae

unread,
Mar 14, 1995, 6:16:10 PM3/14/95
to
Submitted-by: a...@zeus.uk.mdis.com (Alastair Rae)
Posting-number: Volume 23, Issue 6
Archive-name: ttywatch/part01
Environment: X11, xterm

ttywatch is a simple X11 utility to de-iconify or raise a shell window
when it receives output. This version has new code from Adam Stein
(ad...@iset.scan.mc.xerox.com) to make it work with Sun command tools
and other tty orientated X tools.

#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: ttywatch ttywatch/ChangeLog ttywatch/Imakefile
# ttywatch/Makefile ttywatch/README ttywatch/ttywatch.c
# ttywatch/ttywatch.man ttywatch/ttywatch.txt
# Wrapped by chris@ftp on Tue Mar 14 17:12:01 1995
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin:$PATH ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 1)."'
if test ! -d 'ttywatch' ; then
echo shar: Creating directory \"'ttywatch'\"
mkdir 'ttywatch'
fi
if test -f 'ttywatch/ChangeLog' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/ChangeLog'\"
else
echo shar: Extracting \"'ttywatch/ChangeLog'\" \(484 characters\)
sed "s/^X//" >'ttywatch/ChangeLog' <<'END_OF_FILE'
XMon Sep 12 09:38:13 1994 Adam Stein (ad...@iset.scan.mc.xerox.com)
X
X * Added ability to use with shell windows other than xterm by
X automatically getting the window ID
X
XThu Mar 24 11:57:47 1994 Alastair Rae (ar...@mdis.com)
X
X * Incorporated changes from Jonathan Harris <jh...@dcs.ed.ac.uk>
Xto
X allow for window managers that don't raises on mapping.
X
XMon Mar 21 13:40:54 1994 Alastair Rae (ar...@mdis.com)
X
X * Made sensitive to visibilty events.
X
X
X
END_OF_FILE
if test 484 -ne `wc -c <'ttywatch/ChangeLog'`; then
echo shar: \"'ttywatch/ChangeLog'\" unpacked with wrong size!
fi
# end of 'ttywatch/ChangeLog'
fi
if test -f 'ttywatch/Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/Imakefile'\"
else
echo shar: Extracting \"'ttywatch/Imakefile'\" \(158 characters\)
sed "s/^X//" >'ttywatch/Imakefile' <<'END_OF_FILE'
X
X
X PROGRAMS = ttywatch
X
X OBJS1 = $(PROGRAMS).o
X
XComplexProgramTarget_1($(PROGRAMS),$(XLIB),/**/)
X
Xclean::
X $(RM) Makefile
X
END_OF_FILE
if test 158 -ne `wc -c <'ttywatch/Imakefile'`; then
echo shar: \"'ttywatch/Imakefile'\" unpacked with wrong size!
fi
# end of 'ttywatch/Imakefile'
fi
if test -f 'ttywatch/Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/Makefile'\"
else
echo shar: Extracting \"'ttywatch/Makefile'\" \(8844 characters\)
sed "s/^X//" >'ttywatch/Makefile' <<'END_OF_FILE'
X# Makefile generated by imake - do not edit!
X# $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
X#
X# The cpp used on this machine replaces all newlines and multiple tabs and
X# spaces in a macro expansion with a single space. Imake tries to compensate
X# for this, but is not always successful.
X#
X
X###########################################################################
X# Makefile generated from "Imake.tmpl" and <Imakefile>
X# $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
X#
X# Platform-specific parameters may be set in the appropriate .cf
X# configuration files. Site-wide parameters may be set in the file
X# site.def. Full rebuilds are recommended if any parameters are changed.
X#
X# If your C preprocessor doesn't define any unique symbols, you'll need
X# to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
X# "make Makefile", "make Makefiles", or "make World").
X#
X# If you absolutely can't get imake to work, you'll need to set the
X# variables at the top of each Makefile as well as the dependencies at the
X# bottom (makedepend will do this automatically).
X#
X
X###########################################################################
X# platform-specific configuration parameters - edit sun.cf to change
X
X# platform: $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
X# operating system: SunOS 4.0.3
X
X###########################################################################
X# site-specific configuration parameters - edit site.def to change
X
X SHELL = /bin/sh
X
X TOP = .
X CURRENT_DIR = .
X
X AR = ar clq
X BOOTSTRAPCFLAGS =
X CC = cc
X
X COMPRESS = compress
X CPP = /lib/cpp $(STD_CPP_DEFINES)
X PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
X INSTALL = install
X LD = ld
X LINT = lint
X LINTLIBFLAG = -C
X LINTOPTS = -axz
X LN = ln -s
X MAKE = make
X MV = mv
X CP = cp
X RANLIB = ranlib
X RANLIBINSTFLAGS =
X RM = rm -f
X STD_INCLUDES =
X STD_CPP_DEFINES =
X STD_DEFINES =
X EXTRA_LOAD_FLAGS =
X EXTRA_LIBRARIES =
X TAGS = ctags
X
X SHAREDCODEDEF = -DSHAREDCODE
X SHLIBDEF = -DSUNSHLIB
X
X PROTO_DEFINES =
X
X INSTPGMFLAGS =
X
X INSTBINFLAGS = -m 0755
X INSTUIDFLAGS = -m 4755
X INSTLIBFLAGS = -m 0664
X INSTINCFLAGS = -m 0444
X INSTMANFLAGS = -m 0444
X INSTDATFLAGS = -m 0444
X INSTKMEMFLAGS = -m 4755
X
X DESTDIR =
X
X TOP_INCLUDES = -I$(INCROOT)
X
X CDEBUGFLAGS = -O
X CCOPTIONS =
X COMPATFLAGS =
X
X ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
X ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
X CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
X LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
X LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
X LDCOMBINEFLAGS = -X -r
X
X MACROFILE = sun.cf
X RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
X
X IMAKE_DEFINES =
X
X IRULESRC = $(CONFIGDIR)
X IMAKE_CMD = $(IMAKE) -DUseInstalled -I$(IRULESRC) $(IMAKE_DEFINES)
X
X ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
X $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
X $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
X
X###########################################################################
X# X Window System Build Parameters
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X###########################################################################
X# X Window System make variables; this need to be coordinated with rules
X# $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
X
X PATHSEP = /
X USRLIBDIR = $(DESTDIR)/usr/lib
X BINDIR = $(DESTDIR)/usr/bin/X11
X INCROOT = $(DESTDIR)/usr/include
X BUILDINCROOT = $(TOP)
X BUILDINCDIR = $(BUILDINCROOT)/X11
X BUILDINCTOP = ..
X INCDIR = $(INCROOT)/X11
X ADMDIR = $(DESTDIR)/usr/adm
X LIBDIR = $(USRLIBDIR)/X11
X CONFIGDIR = $(LIBDIR)/config
X LINTLIBDIR = $(USRLIBDIR)/lint
X
X FONTDIR = $(LIBDIR)/fonts
X XINITDIR = $(LIBDIR)/xinit
X XDMDIR = $(LIBDIR)/xdm
X AWMDIR = $(LIBDIR)/awm
X TWMDIR = $(LIBDIR)/twm
X GWMDIR = $(LIBDIR)/gwm
X MANPATH = $(DESTDIR)/usr/man
X MANSOURCEPATH = $(MANPATH)/man
X MANDIR = $(MANSOURCEPATH)n
X LIBMANDIR = $(MANSOURCEPATH)3
X XAPPLOADDIR = $(LIBDIR)/app-defaults
X
X SOXLIBREV = 4.2
X SOXTREV = 4.0
X SOXAWREV = 4.0
X SOOLDXREV = 4.0
X SOXMUREV = 4.0
X SOXEXTREV = 4.0
X
X FONTCFLAGS = -t
X
X INSTAPPFLAGS = $(INSTDATFLAGS)
X
X IMAKE = imake
X DEPEND = makedepend
X RGB = rgb
X FONTC = bdftosnf
X MKFONTDIR = mkfontdir
X MKDIRHIER = /bin/sh $(BINDIR)/mkdirhier.sh
X
X CONFIGSRC = $(TOP)/config
X CLIENTSRC = $(TOP)/clients
X DEMOSRC = $(TOP)/demos
X LIBSRC = $(TOP)/lib
X FONTSRC = $(TOP)/fonts
X INCLUDESRC = $(TOP)/X11
X SERVERSRC = $(TOP)/server
X UTILSRC = $(TOP)/util
X SCRIPTSRC = $(UTILSRC)/scripts
X EXAMPLESRC = $(TOP)/examples
X CONTRIBSRC = $(TOP)/../contrib
X DOCSRC = $(TOP)/doc
X RGBSRC = $(TOP)/rgb
X DEPENDSRC = $(UTILSRC)/makedepend
X IMAKESRC = $(CONFIGSRC)
X XAUTHSRC = $(LIBSRC)/Xau
X XLIBSRC = $(LIBSRC)/X
X XMUSRC = $(LIBSRC)/Xmu
X TOOLKITSRC = $(LIBSRC)/Xt
X AWIDGETSRC = $(LIBSRC)/Xaw
X OLDXLIBSRC = $(LIBSRC)/oldX
X XDMCPLIBSRC = $(LIBSRC)/Xdmcp
X BDFTOSNFSRC = $(FONTSRC)/bdftosnf
X MKFONTDIRSRC = $(FONTSRC)/mkfontdir
X EXTENSIONSRC = $(TOP)/extensions
X
X DEPEXTENSIONLIB =
X EXTENSIONLIB = -lXext
X
X DEPXLIB = $(DEPEXTENSIONLIB)
X XLIB = $(EXTENSIONLIB) -lX11
X
X DEPXAUTHLIB = $(USRLIBDIR)/libXau.a
X XAUTHLIB = -lXau
X
X DEPXMULIB =
X XMULIB = -lXmu
X
X DEPOLDXLIB =
X OLDXLIB = -loldX
X
X DEPXTOOLLIB =
X XTOOLLIB = -lXt
X
X DEPXAWLIB =
X XAWLIB = -lXaw
X
X LINTEXTENSIONLIB = $(USRLIBDIR)/llib-lXext.ln
X LINTXLIB = $(USRLIBDIR)/llib-lX11.ln
X LINTXMU = $(USRLIBDIR)/llib-lXmu.ln
X LINTXTOOL = $(USRLIBDIR)/llib-lXt.ln
X LINTXAW = $(USRLIBDIR)/llib-lXaw.ln
X
X DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
X
X DEPLIBS1 = $(DEPLIBS)
X DEPLIBS2 = $(DEPLIBS)
X DEPLIBS3 = $(DEPLIBS)
X
X###########################################################################
X# Imake rules for building libraries, programs, scripts, and data files
X# rules: $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
X
X###########################################################################
X# start of Imakefile
X
X PROGRAMS = ttywatch
X
X OBJS1 = $(PROGRAMS).o
X
X OBJS = $(OBJS1) $(OBJS2) $(OBJS3)
X SRCS = $(SRCS1) $(SRCS2) $(SRCS3)
X
Xall:: $(PROGRAMS)
X
X$(PROGRAMS): $(OBJS1) $(DEPLIBS1)
X $(RM) $@
X $(CC) -o $@ $(LDOPTIONS) $(OBJS1) $(XLIB) $(LDLIBS) $(EXTRA_LOAD_FLAGS)
X
Xinstall:: $(PROGRAMS)
X $(INSTALL) -c $(INSTPGMFLAGS) $(PROGRAMS) $(BINDIR)
X
Xinstall.man:: $(PROGRAMS).man
X $(INSTALL) -c $(INSTMANFLAGS) $(PROGRAMS).man $(MANDIR)/$(PROGRAMS).n
X
Xsaber_$(PROGRAMS):
X #load $(ALLDEFINES) $(SRCS1) $(XLIB) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
Xosaber_$(PROGRAMS):
X #load $(ALLDEFINES) $(OBJS1) $(XLIB) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
X
Xdepend::
X $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
X
Xlint:
X $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
Xlint1:
X $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
X
Xclean::
X $(RM) $(PROGRAMS)
X
Xclean::
X $(RM) Makefile
X
X###########################################################################
X# common rules for all Makefiles - do not edit
X
Xemptyrule::
X
Xclean::
X $(RM_CMD) \#*
X
XMakefile::
X -@if [ -f Makefile ]; then \
X echo " $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
X $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
X else exit 0; fi
X $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
X
Xtags::
X $(TAGS) -w *.[ch]
X $(TAGS) -xw *.[ch] > TAGS
X
Xsaber:
X #load $(ALLDEFINES) $(SRCS)
X
Xosaber:
X #load $(ALLDEFINES) $(OBJS)
X
X###########################################################################
X# empty rules for directories that do not have SUBDIRS - do not edit
X
Xinstall::
X @echo "install in $(CURRENT_DIR) done"
X
Xinstall.man::
X @echo "install.man in $(CURRENT_DIR) done"
X
XMakefiles::
X
Xincludes::
X
X###########################################################################
X# dependencies generated by makedepend
X
END_OF_FILE
if test 8844 -ne `wc -c <'ttywatch/Makefile'`; then
echo shar: \"'ttywatch/Makefile'\" unpacked with wrong size!
fi
# end of 'ttywatch/Makefile'
fi
if test -f 'ttywatch/README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/README'\"
else
echo shar: Extracting \"'ttywatch/README'\" \(155 characters\)
sed "s/^X//" >'ttywatch/README' <<'END_OF_FILE'
X
Xttywatch v1.3 by Alastair Rae <ar...@mdis.com>
X
XA simple X11 utility to de-iconify an shell window when it receives
Xoutput. See the man page for details.
X
END_OF_FILE
if test 155 -ne `wc -c <'ttywatch/README'`; then
echo shar: \"'ttywatch/README'\" unpacked with wrong size!
fi
# end of 'ttywatch/README'
fi
if test -f 'ttywatch/ttywatch.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/ttywatch.c'\"
else
echo shar: Extracting \"'ttywatch/ttywatch.c'\" \(2662 characters\)
sed "s/^X//" >'ttywatch/ttywatch.c' <<'END_OF_FILE'
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X
Xvoid main()
X{
X int fd = 0;
X Display *display;
X struct stat s;
X time_t t;
X char *winid;
X
X if (!isatty(fd))
X puts("not a tty");
X
X else if (!(display = XOpenDisplay(0)))
X puts("Cannot open display");
X
X else
X {
X struct stat s;
X time_t t;
X XEvent event;
X Bool hidden = False; /* Sure about this? */
X Window window,getwindow();
X
X /*If WINDOWID doesn't exist, assume the window with the focus
X is the one starting the ttywatch command*/
X if (!(winid = (char *)getenv("WINDOWID"))) {
X int dummy;
X
X /*The window returned from XGetInputFocus may not be the
Xtop-level
X window. Using getwindow(), we recursivley go up the window
X list until we find a parent with a name. We assume the
Xfirst
X window with a name is the top-level window.*/
X XGetInputFocus(display,&window,&dummy);
X window = getwindow(display,window);
X } else window = strtol(winid,0,0);
X
X XSelectInput(display, window, VisibilityChangeMask);
X
X for (t = 0; ; t = s.st_mtime)
X {
X sleep(2);
X
X while (XCheckWindowEvent(display, window,
X VisibilityChangeMask, &event))
X hidden = (event.xvisibility.state ==
XVisibilityFullyObscured);
X
X if (fstat(fd, &s))
X perror("fstat"), exit(1);
X
X if (t && (s.st_mtime > t))
X {
X XWindowAttributes attributes;
X XGetWindowAttributes(display, window, &attributes);
X
X if (attributes.map_state == IsUnmapped)
X {
X XMapWindow(display, window);
X XRaiseWindow(display, window);
X }
X
X /*Always raise window, can't hurt and it will always
X bring this window to the top*/
X XRaiseWindow(display, window);
X
X XFlush(display);
X }
X }
X }
X exit(1);
X}
X
XWindow getwindow(display,window)
XDisplay *display;
XWindow window;
X{
X unsigned int dummy;
X Window root,*child,parent;
X XTextProperty text_prop;
X
X /*Find the parent of "window"*/
X XQueryTree(display,window,&root,&parent,&child,&dummy);
X XFree((caddr_t) child);
X
X /*If parent has a name, assume it's the top-level, otherwise
X find its parent and do this again*/
X if(XGetWMName(display,parent,&text_prop)) return(parent);
X else return(getwindow(display,parent));
X}
X
END_OF_FILE
if test 2662 -ne `wc -c <'ttywatch/ttywatch.c'`; then
echo shar: \"'ttywatch/ttywatch.c'\" unpacked with wrong size!
fi
# end of 'ttywatch/ttywatch.c'
fi
if test -f 'ttywatch/ttywatch.man' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/ttywatch.man'\"
else
echo shar: Extracting \"'ttywatch/ttywatch.man'\" \(1108 characters\)
sed "s/^X//" >'ttywatch/ttywatch.man' <<'END_OF_FILE'
X.TH ttywatch 1 "12 Sep 94" "" ""
X.ad l
X.UC 4
X.SH NAME
Xttywatch - shell window popup daemon
X.SH SYNOPSIS
X.B ttywatch
X.SH DESCRIPTION
X.I ttywatch
Xwatchs the terminal associated with a shell window such as xterm or
XSun's
Xshelltool. When there is any output it de-iconifies and/or raises the
Xwindow.
X
XThe device monitored is actually stdin. If you have a problem with
Xthat then you could try
X.ti 8
Xttywatch < /dev/tty
X.br
Xor whatever.
X
XFor xterm, the window id is obtained from the environment variable
X.I $WINDOWID
Xwhich is normally set up by the xterm. By changing this, and stdin,
Xyou can monitor any X tty-orientated window.
X
XIf
X.I $WINDOWID
Xisn't set, the window ID containing the focus is watched.
X.SH AUTHOR
XAlastair Rae (ar...@mdis.com)
X.br
XAdditional input from Jonathan Harris (jh...@dcs.ed.ac.uk).
Xand from Adam Stein (ad...@iset.scan.mc.xerox.com).
X
XThere is no copyright on this software. Neither the author nor his
Xemployers can accept any responsibility for the use of this software.
X.SH ENVIRONMENT
X.IP WINDOWID
Xwindow ID for an xterm window
X.SH SEE ALSO
Xcmdtool(1), env(1), shelltool(1), xterm(1)
X
END_OF_FILE
if test 1108 -ne `wc -c <'ttywatch/ttywatch.man'`; then
echo shar: \"'ttywatch/ttywatch.man'\" unpacked with wrong size!
fi
# end of 'ttywatch/ttywatch.man'
fi
if test -f 'ttywatch/ttywatch.txt' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ttywatch/ttywatch.txt'\"
else
echo shar: Extracting \"'ttywatch/ttywatch.txt'\" \(1259 characters\)
sed "s/^X//" >'ttywatch/ttywatch.txt' <<'END_OF_FILE'
X
X
X
Xttywatch(1) ttywatch(1)
X
X
XNAME
X ttywatch - shell window popup daemon
X
XSYNOPSIS
X ttywatch
X
XDESCRIPTION
X ttywatch watchs the terminal associated with a shell win-
X dow such as xterm or Sun's shelltool. When there is any
X output it de-iconifies and/or raises the window.
X
X The device monitored is actually stdin. If you have a
X problem with that then you could try
X ttywatch < /dev/tty
X or whatever.
X
X For xterm, the window id is obtained from the environment
X variable $WINDOWID which is normally set up by the xterm.
X By changing this, and stdin, you can monitor any X tty-
X orientated window.
X
X If $WINDOWID isn't set, the window ID containing the focus
X is watched.
X
XAUTHOR
X Alastair Rae (ar...@mdis.com)
X Additional input from Jonathan Harris (jh...@dcs.ed.ac.uk).
X and from Adam Stein (ad...@iset.scan.mc.xerox.com).
X
X There is no copyright on this software. Neither the author
X nor his employers can accept any responsibility for the
X use of this software.
X
XENVIRONMENT
X WINDOWID
X window ID for an xterm window
X
XSEE ALSO
X cmdtool(1), env(1), shelltool(1), xterm(1)
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X 12 Sep 94 1
X
X
END_OF_FILE
if test 1259 -ne `wc -c <'ttywatch/ttywatch.txt'`; then
echo shar: \"'ttywatch/ttywatch.txt'\" unpacked with wrong size!
fi
# end of 'ttywatch/ttywatch.txt'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have the archive.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...
--
// ch...@Sterling.COM | Send comp.sources.x submissions to:
\X/ Amiga: The only way to fly! | sour...@sterling.com
GCS d++(--) h++ s++:+ g+++(?) p? au(*)(0) a w+ v-(*) C++ US+++ P+ L+ 3 N++ K
!W M V-- -po+ Y+ t+ 5++ j- r+ G+ v b+++ D- b-- e+ u+ h- f+ r+++ !n y+++

0 new messages