add the Java Client from M0AZM

This commit is contained in:
minima 2001-04-18 16:11:46 +00:00
parent 5e14535873
commit 1540d1ee26
35 changed files with 2804 additions and 0 deletions

View File

@ -1,3 +1,7 @@
18Apr01=======================================================================
1. added Ian M0AZM's Java Client (SpiderConsole)
17Apr01=======================================================================
1. made a slight speedup on write in Msg.pm (about doubled it)
16Apr01=======================================================================
1. make the correct error messages come out on reject/accept when people
leave out keywords like 'on'.

367
SpiderConsole/docs/COPYING Executable file
View File

@ -0,0 +1,367 @@
*******************************************************************************
NO WARRANTY
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
*******************************************************************************
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -0,0 +1,79 @@
RadioConsole (Possibly referred to as SpiderConsole)
by (C) 2001 Ian Norton, i.norton@lancaster.ac.uk
First Release v1.0, 20010418 (18th April 2001).
1. Introduction
This document assumes that you have the JDK or JRE already installed and
working on your machine. I have no intention of providing a HOWTO on this,
there are plenty out there already. <http://www.blackdown.org> has a list of
JDK/JRE mirror sites for Linux if you don't have it.
If you install the JRE (Java Runtime Environment) you will not be able to
compile the source code, you will only be able to interpret the code that
has already been compiled (Java works by compiling source into byte code,
and then using an interpreter to run the byte code, this is why you must
install some Java stuff, but this is also how it is platform independent).
If you don't intend to modify or recompile the source code, skip the
programming section, it won't be of any interest to you.
This version of JCAdmin has been tested with the Blackdown port for linux
of the Java Development Kit version 1.3.0 <http://www.blackdown.org/>.
1.1. Acknowledgements
Some time ago I created JCAdmin for my good friends Ian (G0VGS) and Linda
(G0YLM) Maude. JCAdmin was designed to be an admin interface to the CLX
cluster software (http://www.clx.muc.de/). It was written with the expressed
purpose of performing certain tasks on Ian's cluster and never really intended
to be anything marvelous. After about a year of using this, Ian decided that
CLX was no longer the software he wanted to use and switched to Dx Spider
(http://www.dxcluster.org). After much wailing and gnashing of teeth he
persuaded me that perhaps I might like to write a new console for Spider.
After experiencing a brief sense of flashback and "I've been here before" I
decided that it would be a good challenge to write not only a new console but
a framework on which to build future consoles.
This is the approach I have taken with this console.
1.2. So how do I get this console to talk to something then?
The console works on the principle that whatever specific task you want to
perform can be done with a plugin. The console provides a framework for adding
and removing plugins that provide menu items, toolbar buttons and so on.
(Some of these features are planned but havn't yet been implemented fully).
To take the previously mentioned example, the SpiderCluster plugin can talk
directly to the DX Spider internal protocol engine, thus allowing the user
administrative rights on the cluster whilst they are using the console.
All sections SPECIFIC to spider are written into the SpiderCluster plugin.
Generic communication modules are then used to get everything to talk.
The next logical addition to the SpiderCluster plugin is a standard Cluster
plugin that allows a user to connect to a spider cluster via IP (Although this
requires some more work before it's actually useful).
So using the generic framework should make just about anything possible.
Want a graph of WWV/WCY? Just write a new plugin for it then!
1.3. Getting it to run.
Compile all the java files in the src directory simply with javac *.java.
You should now be able to start the console with java Console.
By default the SpiderCluster plugin is used and a connect made to
127.0.0.1:27754.
1.4. New versions / updates.
New versions of RadioConsole and it's documentation will be made available
through the DX Spider homepage <http://www.dxcluster.org/>.
1.5. Feedback
Please mail me your comments, observations and suggestions for features or
improvements and in the unlikely event (!) of bugs. I will do my best to give
you a prompt reply and request number!
Ian Norton
i.norton@lancaster.ac.uk

View File

@ -0,0 +1,13 @@
Bug #1 20010403 - reporter Ian, G0VGS.
Error on typing in a long command.
java.lang.IndexOutOfBoundsException
at java.io.PipedInputStream.read(PipedInputStream.java:271)
at PipedInputMUX.run(PipedInputMUX.java:79)
at java.lang.Thread.run(Thread.java:484)
ConnectionOutput: IOException reading data.
IDN 20010403 - Fixed
PipedInputMUX was trying to read all the input into a 16 byte array.
Put an if > 16 line in that tells it to only read 16 bytes.

View File

@ -0,0 +1,256 @@
<ea1dav> supose two ports in tnc3
<Stephan> never tried the 2nd port Jesus
<ea1dav> oh,ok
<Stephan> but it is mentioned in the ax25-howto (not tnc3, but multiport tnc´s)
<ea1dav> yes i have an kpc4 in my node and use mkis
<ea1dav> but go to change by an tnc3 1k2/9k6
<Stephan> should be easy anyway
<ea1dav> how many RAM you have in tnc3 ?
<Stephan> at db0sue-4(db0sue-7) 256Kb
<ea1dav> it seem the standard when attached to an PC, then a buy with 256K also
<Stephan> It isd tnc3/xnet and just have 2 links (one local to db0sue-7 wire and one to db0sue on 2.4GHz 80m distance)
<ea1dav> ah, Xnet inside tnc..No i have xnet run in pc.
<ea1dav> a radio link off 80 m the shortest I know :-)
<Stephan> a kiss link, with Siemens GIGA SET M101DATA (virtuell rs232)
<ea1dav> how much power (mW).. it is very interesant
<Stephan> 100mW, but not sure - have to search for the manual
<ea1dav> are usual (easy to find ) that equipment..?
<Stephan> look for M101DATA
<Stephan> 115k2 (real 57k6)
<ea1dav> very good,only need an external antena to increase distance.
<Stephan> max 6.5Km we have tested
<ea1dav> with external...or with built in antena.?
<Stephan> external
<ea1dav> ah, very good solution,I like it.
<Stephan> since 1 1/2 year we have that link up without any error
<ea1dav> and is an rs-232 transparent or need some software.?
<ea1dav> all info that fint is in german :-(
<ea1dav> find
<Stephan> yep, needs windows to setup the master and slave - just for initial
<ea1dav> and then store the info and act like a cable.?
<Stephan> it is stored in the memory of the master/slave rx/tx
<-- pa3ezl has quit (EOF From client)
<-- Dirk-home has quit ([x]chat)
<ea1dav> go home....by
<ea7wa> bye
<-- ea1dav (ea1dav@212.51.60.18) has left #9000 (ea1dav)
<-- oz1lqh (~nospam@cpe.atm0-0-0-130143.arcnxx2.customer.tele.dk) has left #9000 (oz1lqh)
<ea7wa> check your mail Stephan
<g0vgs> is it fixed Angel?
<ea7wa> which thing Ian ?
<Stephan> ok
<g0vgs> the mail
<g0vgs> and ge all
<ea7wa> no, I'm talking with Ben, but maybe I'm loosing my english and I'm not able
<ea7wa> to explain myself in this language
<g0vgs> I was reading your comments and it seems ok to me
<g0vgs> although to my knowledge, Spider and AK1A treat mail in the same way. I cannot be sure about DXNet
<ea7wa> I think Olivier will be also using that style for dxnet
<g0vgs> The diff with Spider is that it treats mail as simply as possible
<g0vgs> that is.. it can only ever deal with one message at a time
<g0vgs> and if it receives a message for another node/user it simply says...
<g0vgs> is that node/user on the network? Ok, send the message. There is no delay at all
<ea7wa> yes, that's understood bye Ben, it will be fixed it seems in next release
<ea7wa> so, send the message as soon as it arrives.
<g0vgs> good, it would be nice to see it finally fixed
<ea7wa> <dl6rai-1>: b) trigger it whenever an outgoing message is created
<g0vgs> only send it if the user is seen on the network
<Stephan> got it - finally :)
<g0vgs> if the user cannot be seen on the network then hold the message until they are
<g0vgs> pointless sending mail when we do not know where the user will appear
<g0vgs> the time is a day out on that example Angel!
<g0vgs> sorry, I thought it was the same message, it is not
<g0vgs> well I am going to bed folks, I have work in the morning :-(
<g0vgs> at least I will be working at home!
<Stephan> nite Ian
<g0vgs> g'night all
* g0vgs is away: Zzzzzzzzzz
<ea7wa> Bye Ian, all stuff on clx is being sent with that PC28 synyax
<ea7wa> synyax = syntax
<Stephan> Im off for to bed, goodnight
--- Stephan is now known as dk8lv-Zzz
<ea7wa> did you get the mail ?
<dk8lv-Zzz> yes, I told you
<ea7wa> ah, sorry
<dk8lv-Zzz> will try that one tomorrow
<ea7wa> ok, sleep well
<dk8lv-Zzz> goodnight Angel
<dk8lv-Zzz> btw
<dk8lv-Zzz> need someone looking for sue-7 the next weeks
--> pa4ab (~pa4ab@212.163.193.2) has joined #9000
<Amanda> [pa4ab] [pa4ab] Arnold, qth: Ede joins channel #9000 Hello to all!
--- Amanda gives channel operator status to pa4ab
<dk8lv-Zzz> Hello Arnold, merry christmas for the rest
--- dk8lv-Zzz is now known as Stephan
<pa4ab> Hello Stephan also a Merry Christmas for next year :-0
<Stephan> still sun, beach and girls ?
<Stephan> :))
<pa4ab> Nope rain and rain and rain
<Stephan> too bad - but here it is/was cold - not too much snow yet
<pa4ab> no snow here still ten degrees at night
--> pa3ezl (^aurelio@pa3goj.ampr.org) has joined #9000
<pa3ezl> GA!
<pa4ab> Hello Aurelio
<Stephan> thought that channel ops are able to give op to other
<pa3ezl> nice to see you ARnold!
<Stephan> but Amanda do not like that
<Stephan> hi Aurelio
<pa3ezl> how have you been?
<pa3ezl> GA Stephan
<pa4ab> Who needs to be operator here?
<pa4ab> I am doing well Aurelio although very busy :-)
<pa4ab> how are things in PA country?
<Stephan> Ian (0AZM), Jesus, Rene
<pa4ab> Do we all need to be operator?
<Stephan> don´t know :)
<pa3ezl> snow..
<pa4ab> I better can ask Amanda to put auto-operator on!
<pa3ezl> but slowly melting
<pa4ab> SNOW????????????????????????????????????
<pa3ezl> yes!
<pa3ezl> 2cm
<pa3ezl> I was just outside putting some 'karton' in from of the 'radiateur'
<pa3ezl> it feels cold
<pa4ab> Mhh we are better of here it seems
<pa3ezl> other than that, all is fine. Another 'attach' by that Molukse actiegroep
<pa3ezl> attach=attack
<Stephan> Arnold, is there a command to put lilo into MBR (not with yast)?
<pa3ezl> so, how is your work progressing?
<pa4ab> another? I have not heard about that do we have ETA now in Holland too?
<pa4ab> Well work is not progressing too well, waiting for the lines (for internet)
<pa4ab> Telefonica is not that fast
<pa3ezl> well, they claimed the action of putting a sack of rocks on a rail track
<pa4ab> oh dear
<pa3ezl> all and all it was nice, white Xmas
<pa3ezl> can you operate HF?
<pa4ab> No not right away I have stuff with me but at 'home'
<pa4ab> not at work
<pa4ab> I think it must be defined in /etc/lilo.conf Stephan
<pa3ezl> I will be in EHV this friday, would be nice working you
<pa4ab> Well I can try but friday is a transport day here I will go back to our house in Asturias
<pa4ab> for the celebration of the end of the year
<Stephan> looked there, but it foes not tell how to install lilo into mbr
<pa3ezl> -rr- next time then
<pa4ab> and what's wrong with yast?
<Stephan> if, for some reason, I have to fdisk /mbr (overwrite lilo), I have to re-install the whole linux
<Stephan> coz yast just can install lilo to hda and yast2 to hde (only once)
<pa4ab> lilo has an uninstall
<Stephan> and I don´t have hda as my first HD
<pa4ab> lilo -u
<pa3ezl> Bem-vindo ao PY5UFP-11 Cluster CLX (r) v4.06 - Voce se logou de 200.17.209.10
<Stephan> that is un-install?!
<pa3ezl> is that version still with user links?
<pa4ab> yes Stephan
<pa4ab> yes Aurelio
<pa4ab> sorry have to run
<pa4ab> cu l8ter
<pa3ezl> bye
<Stephan> I want the other way - install to mbr on /dev/hde
<Stephan> cul Arnold
<-- pa4ab has quit (Connection reset by peer)
<ea7wa> Hola
<Stephan> Hola Angel
<-- pa3ezl has quit (Leaving)
--> dk8lv-Zzz (~dk8lv@pD903B746.dip.t-dialin.net) has joined #9000
<Amanda> [dk8lv-Zzz] Stephan - Groß Rheide
--- Amanda gives channel operator status to dk8lv-Zzz
<-- Stephan has quit (Ping timeout)
<-- ea7wa has quit (Leaving)
--> pa4ab (~pa4ab@212.163.193.2) has joined #9000
<Amanda> [pa4ab] [pa4ab] Arnold, qth: Ede joins channel #9000 Hello to all!
--- Amanda gives channel operator status to pa4ab
<-- pa4ab has quit (Connection reset by peer)
--> Dirk-home (~djk@gate.tobit.co.uk) has joined #9000
--- Amanda gives channel operator status to Dirk-home
<Dirk-home> Greetings to this IRC channel
<m0azm> Evening
<Dirk-home> LO
<Dirk-home> ?
<m0azm> Been looking at a java based telnet interface today Dirk. It supports an applet front end and plug in modules.
<m0azm> Built in support for IO stream plug in filters too...
<m0azm> Looks like an ideal start for a front end.
<Dirk-home> I am just in the process of thinking about making some small changes to the 'internal' protocol so that it is possible to distinguish talks from announces from dx from logging info from the rest
<Dirk-home> But I really need to get the latest 'version' out the door so IAN are you there?
<Dirk-home> IAN
<m0azm> Havn't had chance to look at that yet. How does that work in terms of actually connecting to the cluster? Does it connect as a normal user and then do some kind of negotiaton?
<Dirk-home> The internal protocol is very simple:-
<Dirk-home> <letter><callsign>|<data>\n
<Dirk-home> when you connect you send:
<Dirk-home> AG1TLH|telnet
<Dirk-home> (if you are telnetting in)
<Dirk-home> to send a 'normal' line to the node:
<Dirk-home> IG1TLH|t m0azm hello sailor
<Dirk-home> it replies to you (for normal data)
<Dirk-home> DM0AZM|M0AZM de G1TLH: Hello sailor
--> ea1dav (jesus@180-CORU-X5.libre.retevision.es) has joined #9000
<Dirk-home> there are a few control letters like:-
<Dirk-home> BG1TLH|0
<Dirk-home> EG1TLH|0
<Dirk-home> which means don't buffer and don't echo respectively and are sent to the client by the node
<Dirk-home> and
<Dirk-home> ZG1TLH|Bye
<Dirk-home> should be self evident
--> pa3ezl (pa3ezl@c71057.upc-c.chello.nl) has joined #9000
--- Amanda gives channel operator status to pa3ezl
<Dirk-home> no binary (all such are encoded over the link as %07, %FF etc)
<pa3ezl> GE all
<Dirk-home> GE
<m0azm> Ge.
<ea1dav> Ge all
<Dirk-home> as default the node only listens to localhost port 27754
<m0azm> Where abouts do the new protocol bits live?
<Dirk-home> what I will do is make talk output 'TG1TLH|', DX broadcasts 'XG1TLH|' and announce broadcasts 'NG1TLH|' so you can stick them into different colours/windows easily also have 'LG1TLH|' for logging info which currently comes out on the stdout of the node program
<Dirk-home> new protocol is inter cluster protocol and that has not been designed in detail yet, I thought you wanted to do a sysop interface in java?
<m0azm> Yes, I thought this was the internode protocol though? Or do you have a separate proto for the console?
<Dirk-home> separate protocol for console and clients.
--> aurelio (pa3ezl@c71057.upc-c.chello.nl) has joined #9000
<Dirk-home> It is a client/server architecture.
--- Amanda gives channel operator status to aurelio
<Dirk-home> this is the simple internal protocol that you have to interpret.
<m0azm> Ok, I think I'm confused now. Will this be a connect to localhost port 27754 or a connect to the standard port?
<Dirk-home> Of course there in nothing to stop me sending you either full or bastardised PC protocol but that may a bit too much for starters.
<-- aurelio has quit (EOF From client)
<Dirk-home> OK
<m0azm> :)
<Dirk-home> What happens is this:
<Dirk-home> There is a node (cluster.pl) which is a server which sits there listening on localhost port 27754
<m0azm> Ok.
<Dirk-home> then either it or some other process starts a 'client' who's sole job in life is to normalise 'input' and 'output' to and from this server
<m0azm> Right, ok I'm with you now.
<m0azm> So I could manually telnet to the port and issue these commands?
<m0azm> Same idea as sendmail etc..
<Dirk-home> for a 'normal' user this amounts to dealing with line ending conventions and coping with 'binary characters'
<Dirk-home> yes.
<m0azm> Sorry, I seem to be a little slow on the uptake today :-)
<Dirk-home> The callsign that you use determines whether you see 'user' or 'node' data - but the data is always framed in the way I described earlier.
<m0azm> Ok. That seems fairly straight forward.
<Dirk-home> It isn't wonderfully secure, which is why the node only listens to localhost.
<Dirk-home> If you look at console.pl it should show you the sort of thing that happens. It is very simple.
<Dirk-home> what it doesn't currently do is distinguish the various broadcast things from 'interactive' traffic which is what I want to do next. If I also allow log info onto that 'channel' then you can split out a window with that on.
<m0azm> Ok, I've just given it an initial glance today. Trying to work out how the Java Telnet application works.
<m0azm> It seems to do everything that we need, it just needs tweeking.
<Dirk-home> My personal view is that you might be better to start again. A lot of these 'applets' have been written by erm... less experienced people.
<Dirk-home> send us a copy and let me look at (just out of curiosity).
<m0azm> It looks to be written how I had initially thought about writing it.
<m0azm> Hang on, I'll grab the URL.
<m0azm> http://www.mud.de/se/jta/html/download.html
<m0azm> It'll need a bit of a re-work to get the GUI to look a bit nicer, but other than that it seems a good way to start.
<m0azm> Or, as you say I might steal some of the better ideas and start afresh.
<Dirk-home> It's erm.. big isn't it? it's bigger than a normal telnet session!
<m0azm> Yes, it's a bit bloated. But then there's no telnet implementation for Java, you have to write your own from scratch.
<m0azm> It has lots of extra rubbish we don't need such as ssh support.
<Dirk-home> I was sort of thinking that this might be a stand alone thingie rather than a 'use a browser' thingie.
<Dirk-home> You shouldn't need any of the telent protocol stuff (%ff%xx) pairs. I assume a 'noecho' connection
<m0azm> Yes, that's what it does. There's an applet there too, but it's just a front end plug in.
<m0azm> So you think I should be able to open a raw connection to it?
<Dirk-home> basically you don't need anything other than a basic socket connection plus the 'internal' protocol engine together with a really funky 'swing' interface (:-)
<Dirk-home> That's what I do.
<m0azm> I'm just looking at funky swing stuff atm
<m0azm> !
<m0azm> Ok, I'll have a re-think.
<Dirk-home> have a look at the perl/C clients you will see they are very simple.
<m0azm> I thought I had to deal with the telnet stuff from the RFC.
<Dirk-home> Of course once you have done that then we can look at the 'remote' user version that implements the multicast protocol (that I haven't defined properly yet) and start to make this all really good...
<m0azm> <Throws a thick book out of the window>
<Dirk-home> and with that thought I shall leave for a moment or five and search for a nice glass of wine...
<m0azm> Ok, thanks for the pointers :-)

View File

@ -0,0 +1,358 @@
/**
* Cluster - Cluster console plugin.
* @author Ian Norton
* @verison 0.1 - 28/12/00.
* @see JPanel
*
* RadioConsole.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.Hashtable ;
import java.util.Enumeration ;
// public class Cluster extends Plugin implements Runnable
class Cluster extends Plugin implements Runnable
{
// Name and tip used when creating the tabbed pane.
public static final String NAME = "Cluster" ;
public static final String TIP = "DX Cluster Console" ;
// Number of commands to buffer.
public static final int CMDBUFFERLINES = 30 ;
// Number of lines of scrollback to buffer.
public static final int SCROLLBUFFERLINES = 100 ;
public static final boolean DEBUG = false ;
// Input and output streams for the plugin.
// private PipedInputStream pin ;
private BufferedReader bir ;
private PipedOutputStream pos ;
// User input field.
private JTextField tf ;
private JTextPane jtp ;
private Thread t ;
private SimpleAttributeSet attr ;
private LimitedStyledDocument doc ;
// Input line scrollback buffer.
private CommandBuffer cbuf ;
private static final String encoding = "latin1"; // "ISO8859_1";
/**
* Class initialiser.
**/
public Cluster()
{
super() ;
}
/**
* Plugin initialiser.
* @param PipedInputStream i - Stream to read data from
* @param PipedOutputStream o - Stream to write data to
**/
public void init(PipedInputStream i, PipedOutputStream o)
{
// Initialise the plugin IO.
bir = new BufferedReader(new InputStreamReader(i)) ;
pos = o ;
// Initialise the ScrollingTextArea.
// ScrollingTextArea sta = new ScrollingTextArea(pin, SCROLLBUFFERLINES, doc) ;
// sta.setFont(new Font("Courier", Font.PLAIN, 10)) ;
// sta.setFont(new Font("Monospaced", Font.PLAIN, 10)) ;
// System.out.println(sta.getFont()) ;
doc = new LimitedStyledDocument(SCROLLBUFFERLINES) ;
jtp = new JTextPane(doc) ;
jtp.setEditable(false) ;
attr = new SimpleAttributeSet() ;
StyleConstants.setFontFamily(attr, "Monospaced") ;
StyleConstants.setFontSize(attr, 10) ;
jtp.setBackground(Color.black) ;
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
jtp.setCaretPosition(doc.getLength()) ;
// tf.requestFocus() ;
}
public void removeUpdate(DocumentEvent e) {
}
public void changedUpdate(DocumentEvent e) {
}
});
// Initialise the TextField for user input.
tf = new JTextField() ;
tf.setFont(new Font("Courier", Font.PLAIN, 10)) ;
Insets inset = tf.getMargin() ;
inset.top = inset.top + 1 ;
inset.bottom = inset.bottom + 1 ;
tf.setMargin(inset) ;
tf.setForeground(Color.white) ;
tf.setBackground(Color.black) ;
// Set the layout manager.
this.setLayout(new BorderLayout()) ;
// Scrollbars for scrolling text area.
// JScrollPane scrollpane = new JScrollPane(sta);
JScrollPane scrollpane = new JScrollPane(jtp);
// Add the bits to the panel.
this.add(scrollpane, BorderLayout.CENTER);
this.add(tf, BorderLayout.SOUTH);
// Initialise the command buffer.
cbuf = new CommandBuffer(CMDBUFFERLINES) ;
// Action listener stuff.
tf.addKeyListener(new KeyAdapter()
{
public void keyTyped(KeyEvent e)
{
// Enter key
if((e.getID() == KeyEvent.KEY_TYPED) && (e.getKeyChar() == KeyEvent.VK_ENTER))
{
// System.out.println("Enter Event") ;
send(tf.getText() + '\n') ;
cbuf.addCommand(tf.getText()) ;
tf.setText("") ;
}
}
public void keyPressed(KeyEvent e)
{
// UP Arrow
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_UP))
{
// System.out.println("UP Event") ;
tf.setText(cbuf.getPreviousCommand()) ;
tf.setCaretPosition(tf.getText().length()) ;
}
// DOWN Arrow
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_DOWN))
{
// System.out.println("DOWN Event") ;
tf.setText(cbuf.getNextCommand()) ;
tf.setCaretPosition(tf.getText().length()) ;
}
// Escape key
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_ESCAPE))
{
// System.out.println("ESCAPE Event") ;
tf.setText("") ; }
}
}) ;
// Add component listener to focus text field.
this.addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
tf.setVisible(true) ;
tf.requestFocus() ;
}
});
// Init the scrolling thread.
t = new Thread(this, "Scrolling thread") ;
t.start() ;
} // End of init
/**
* getTabName - Get the name that this component should show on it's tab
* @returns String s - Tab name
**/
public String getTabName()
{ return NAME ;
}
/**
* getTabTip - Get the tip that this component should show on it's tab
* @returns String s - Tab tip
**/
public String getTabTip()
{
return TIP ;
}
/**
* getMenu - get the menu to add to the main menu bar.
* @returns JMenu
**/
public JMenu getMenu()
{
return null ;
}
/**
* send - Helper function to send data out to the PipedOutputMUX
* @param String s - data to send.
**/
private void send(String s)
{
// System.out.println("Cluster: send got : " + s) ;
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
pos.write(s.charAt(i)) ;
}
}
catch(IOException ex)
{
System.out.println("Cluster: IOException on destination stream.") ;
System.out.println(ex) ;
}
}
/**
* Loop continually checking to see if anything has been written to the
* file that is being monitored.
*/
public void run()
{
String output = new String() ;
// Loop continually reading from the input stream
while(true)
{
try
{
//while(n >= 0)
// {
// n = pin.read(b);
// if(n > 0)
// {
// output = new String(b, 0, n, encoding) ;
// display(output) ;
// // System.out.println("Read : " + output) ;
// }
// }
output = bir.readLine() ;
if(output != null) display(output) ;
if(DEBUG) System.out.println("After reading a line.") ;
}
catch(IOException ex)
{
System.out.println("ScrollingTextArea: IOException trying to read.") ;
}
} // End of infinate loop.
} // End of run.
private void display(String s)
{
// System.out.println(s) ;
// Ignore Ctrl-G.
// s = s.replace('\r', ' ') ;
s = s.replace('', ' ') ;
attr = getAttributes(s) ;
doc.append(s + "\n", attr) ;
}
private SimpleAttributeSet getAttributes(String s)
{
SimpleAttributeSet sas = attr ;
/**
# 0 - $foreground, $background
# 1 - RED, $background
# 2 - BROWN, $background
# 3 - GREEN, $background
# 4 - CYAN, $background
# 5 - BLUE, $background
# 6 - MAGENTA, $background
VHF DX SPOT
[ '^DX de [\-A-Z0-9]+:\s+([57][01]\d\d\d\.|\d\d\d\d\d\d+.)', COLOR_PAIR(1) ],
PROMPT
[ '^G0VGS de GB7MBC', COLOR_PAIR(6) ],
DUNNO!
[ '^G0VGS de', A_BOLD|COLOR_PAIR(2) ],
HF DX SPOT
[ '^DX', COLOR_PAIR(5) ],
ANNOUNCE
[ '^To', COLOR_PAIR(3) ],
WWV SPOT
[ '^WWV', COLOR_PAIR(4) ],
DUNNO!
[ '^[-A-Z0-9]+ de [-A-Z0-9]+ \d\d-\w\w\w-\d\d\d\d \d\d\d\dZ', COLOR_PAIR(0) ],
DUNNO! - PROBABLY A TALK
[ '^[-A-Z0-9]+ de [-A-Z0-9]+ ', COLOR_PAIR(6) ],
WX SPOT
[ '^WX', COLOR_PAIR(3) ],
NEW MAIL
[ '^New mail', A_BOLD|COLOR_PAIR(4) ],
USER LOGIN?
[ '^User', COLOR_PAIR(2) ],
NODE LOGIN?
[ '^Node', COLOR_PAIR(2) ],
**/
Hashtable h = new Hashtable() ;
h.put("DX de", Color.red) ;
h.put("M0AZM de GB7MBC", Color.magenta) ;
h.put("G0VGS de GB7MBC", Color.magenta) ;
h.put("G0VGS2 de GB7MBC", Color.magenta) ;
// h.put("DX", Color.blue) ;
h.put("To", Color.green) ;
h.put("WWV", Color.cyan) ;
h.put("WCY", Color.cyan) ;
// h.put("", Color.) ;
// h.put("", Color.) ;
h.put("WX", Color.green) ;
h.put("New mail", Color.cyan) ;
//h.put("User", Color.brown) ;
//h.put("Node", Color.brown) ;
h.put("User", Color.yellow) ;
h.put("Node", Color.orange) ;
Enumeration e = h.keys() ;
while(e.hasMoreElements())
{
String prefix = (String)e.nextElement() ;
if(s.startsWith(prefix))
{
StyleConstants.setForeground(sas, (Color)h.get(prefix)) ;
return sas ;
}
}
StyleConstants.setForeground(sas, Color.white) ;
return sas ;
}
}

Binary file not shown.

View File

@ -0,0 +1,110 @@
/**
* Command Buffer for the cluster window of the spider GUI.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/ **/
import java.util.Vector ;
class CommandBuffer
{
private int top, bottom, pointer, size ;
private Vector buffer ;
private boolean rolled ;
/**
* main - testing purposes only.
**/
public static void main(String[] args)
{
CommandBuffer c = new CommandBuffer(5) ;
c.addCommand("1") ;
System.out.println(c.getPreviousCommand()) ;
System.out.println(c.getNextCommand()) ;
}
/**
* CommandBuffer
* @param int - Number of lines of buffer.
**/
public CommandBuffer(int i)
{
// Size of the buffer.
size = i ;
// "Pointers"
bottom = 0 ;
pointer = 0 ;
top = size - 1 ;
// Vector that does that actual storage.
buffer = new Vector(size) ;
}
/**
* addCommand
* @param String - command to add to the buffer
**/
public void addCommand(String s)
{
// Is it an empty string
if(s.length() == 0) return ;
// Add the command to the buffer
buffer.addElement(s) ;
// Check the buffer remains the correct size.
while(buffer.size() > size) buffer.removeElementAt(0) ;
// Pointer to the last command
pointer = buffer.indexOf(s) ;
}
/**
* getPreviousCommand - get the previous command (recursive)
* @returns String - previous command
**/
public String getPreviousCommand()
{
String output = (String)buffer.elementAt(pointer) ;
if(pointer != 0) pointer-- ;
return output ;
}
/**
* getNextCommand - get the next command (recursive)
* @returns String - next command
**/
public String getNextCommand()
{
pointer++ ;
if(pointer == buffer.size())
{
pointer-- ;
return "" ;
}
String output = (String)buffer.elementAt(pointer) ;
return output ;
}
} // End of class.

Binary file not shown.

View File

@ -0,0 +1,193 @@
/**
* Ian's attempt at writing a socket module for the Spider GUI.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.io.* ;
import java.net.* ;
public class Connection
{
// Host information.
private String host ;
private int port ;
// Socket.
private Socket socket ;
// Socket input and output streams.
private InputStream is ;
private OutputStream os ;
// Piped IO back up the chain.
private PipedInputStream pin ;
private PipedOutputStream pos ;
// IO readers.
private ConnectionInput conin ;
private ConnectionOutput conout ;
// Encoding String.
public static final String encoding = "latin1"; // "ISO8859_1";
// Connection status.
private boolean disconnected ;
// Default port to use if one isn't specified.
// private static final int DEFAULTPORT = 8000 ; // Use this for user client
private static final int DEFAULTPORT = 27754 ;
/**
* Connection
* @param PipedInputStream - Stream to read from
* @param PipedOutputStream - Stream to send data to
* @param Console - Where to send status alerts to.
**/
public Connection(PipedInputStream i, PipedOutputStream o, Console c)
{
// Initialise the IO pipes.
pin = i ;
pos = o ;
// Yep, we're definately disconnected.
disconnected = false ;
// Initialise the Input and Output readers.
conin = new ConnectionInput(pos, this) ;
conout = new ConnectionOutput(pin, this) ;
}
/**
* connect
* @param String - host to connect to. Port after a ':'.
**/
public void connect(String s)
{
// Has the socket been initialised?
if(socket != null)
disconnect() ;
// Work out the hostname and port.
if(s.indexOf(":") > - 1)
{
try
{
port = Integer.valueOf(s.substring(s.indexOf(":") + 1, s.length())).intValue() ;
}
catch(NumberFormatException ex)
{
System.out.println("Number format exception - bad int in String.") ;
}
s = s.substring(0, s.indexOf(":")) ;
}
else
{
port = DEFAULTPORT ;
}
host = s ;
// Try and make the connection.
try
{
socket = new Socket(host, port) ;
}
catch(UnknownHostException ex)
{
System.out.println("Connection: UnknownHostException") ;
System.out.println(ex) ;
}
catch(IOException ex)
{
System.out.println("Connection: IOException") ;
System.out.println(ex) ;
}
// Get the streams from the connection.
try
{
is = socket.getInputStream() ;
os = socket.getOutputStream() ;
}
catch(IOException ex)
{
System.out.println("Connection: IOException getting the connection streams") ;
System.out.println(ex) ;
}
// Start the readers.
conin.start(is) ;
conout.start(os) ;
// Write a "Connected to " message to the multiplexor.
try
{
// Write disconnected to the PipedOutputStream.
String output = "\nConnected to " + host + ":" + port + "\n" ;
for(int i=0;i<output.length();i++)
{
pos.write(output.charAt(i)) ;
}
}
catch(IOException ex)
{
}
disconnected = false ;
}
/**
* disconnect - disconnect the current connection.
**/
public void disconnect()
{
try
{
if(!disconnected)
{
disconnected = true ;
conin.disconnect() ;
conout.disconnect() ;
// Write disconnected to the PipedOutputStream.
String output = "\nDisconnected from " + host + ":" + port + "\n" ;
for(int i=0;i<output.length();i++)
{
pos.write(output.charAt(i)) ;
}
}
if(socket != null) socket.close() ;
}
catch(IOException ex)
{
System.out.println("Connection: IOException closing socket") ;
System.out.println(ex) ;
}
}
} // End of class

Binary file not shown.

View File

@ -0,0 +1,157 @@
/**
* ConnectionInput - reads from the socket and writes data to the pipe.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.io.* ;
import java.net.* ;
class ConnectionInput implements Runnable
{
// Debug me bugs
public static final boolean DEBUG = false ;
// Data streams.
private InputStream is ;
private PipedOutputStream pos ;
// Connection object that created us.
private Connection connection ;
// Connection status.
private boolean disconnected ;
// Thread to run the read code in.
private Thread t ;
// Encoding string.
public static final String encoding = "latin1"; // "ISO8859_1";
/**
* ConnectionInput
* @param InputStream - InputStream from the socket to read from
* @param PipedOutputStream - Write the data out to here
* @param Connection - the object that created us
**/
public ConnectionInput(PipedOutputStream p, Connection c)
{
// Initialise the streams & connection
pos = p ;
connection = c ;
disconnected = true ;
}
/**
* disconnect - disconnect the current connection.
**/
public void disconnect()
{
if(!disconnected)
{
if(DEBUG) System.out.println("ConnectionInput: disconnect()") ;
try { pos.flush() ; }
catch(IOException ex) { }
disconnected = true ;
connection.disconnect() ;
}
}
/**
* start - begin reading. Called when a connect has been achieved.
**/
public void start(InputStream i)
{
is = i ;
disconnected = false ;
// Initialise the thread to read data & start it.
t = new Thread(this, "ConnectionInput") ;
t.start() ;
}
/**
* Thread run method.
**/
public void run()
{
byte[] b = new byte[16];
// Loop reading data.
while(!disconnected)
{
try
{
// Read from InputStream and write to PipedOutputStream
int n = 0;
n = is.read(b) ;
if(n > 0)
{
String output = new String(b, 0, n, encoding) ;
send(output) ;
}
else if(n == -1)
{
this.disconnect() ;
}
}
catch(IOException ex)
{
if(disconnected)
return ;
System.out.println("ConnectionInput: IOException reading data.") ;
this.disconnect() ;
}
} // End while(true)
} // End run()
/**
* send
* @param String s - string to send to destination stream.
**/
private void send(String s)
{
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
pos.write(s.charAt(i)) ;
pos.flush() ;
}
}
catch(IOException ex)
{
System.out.println("ConnectionInput: IOException writing to multiplexor.") ;
System.exit(1) ;
}
} // End of send(String s)
} // End class

Binary file not shown.

View File

@ -0,0 +1,157 @@
/**
* ConnectionOutput - reads from the pipe and writes data to the socket.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.io.* ;
import java.net.* ;
class ConnectionOutput implements Runnable
{
// Debug me bugs
public static final boolean DEBUG = false ;
// Data streams.
private OutputStream os ;
private PipedInputStream pin ;
// Connection object that created us.
private Connection connection ;
// Connection status.
private boolean disconnected ;
// Thread to run the read code in.
private Thread t ;
// Encoding string.
public static final String encoding = "latin1"; // "ISO8859_1";
/**
* ConnectionOutput
* @param OutputStream - OutputStream to the socket to write to
* @param PipedInputStream - Read data from here
* @param Connection - the object that created us
**/
public ConnectionOutput(PipedInputStream p, Connection c)
{
// Initialise the streams & connection
pin = p ;
connection = c ;
disconnected = true ;
}
/**
* disconnect - disconnect the current connection.
**/
public void disconnect()
{
if(!disconnected)
{
if(DEBUG) System.out.println("ConnectionOutput: disconnect()") ;
disconnected = true ;
connection.disconnect() ;
}
}
/**
* start - begin reading. Called when a connect has been achieved.
**/
public void start(OutputStream o)
{
os = o ;
disconnected = false ;
// Test to see if the thread has been inititialised.
if(t == null) ;
{
if(DEBUG) System.out.println("ConnectionOutput: Creating thread.") ;
// Initialise the thread to read data & start it.
t = new Thread(this, "Connection") ;
t.start() ;
}
}
/**
* Thread run method.
**/
public void run()
{
byte[] b = new byte[16];
// Loop reading data.
while(true)
{
try
{
// Read from PipedInputStream and write to OutputStream
int n = 0;
// Read that many bytes and return.
n = pin.read(b);
// If disconnected read and disguard data or the MUX dies.
if(n > 0 && !disconnected)
{
String output = new String(b, 0, n, encoding) ;
send(output) ;
}
}
catch(IOException ex)
{
System.out.println("ConnectionOutput: IOException reading data from multiplexor.") ;
System.exit(1) ;
}
} // End while(true)
} // End run()
/**
* send
* @param String s - string to send to destination stream.
**/
private void send(String s)
{
if(DEBUG) System.out.println("ConnectionOutput: Send called : " + s) ;
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
os.write(s.charAt(i)) ;
os.flush() ;
}
}
catch(IOException ex)
{
System.out.println("ConnectionOutput: IOException writing to socket.") ;
System.exit(1) ;
}
}
} // End class

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

303
SpiderConsole/src/Console.java Executable file
View File

@ -0,0 +1,303 @@
/**
* Console - modular Amateur Radio console for clusters and converse.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
public class Console
{
private JFrame frame ;
private JPanel buttonpanel ;
private JTabbedPane tabbedpane ;
// Static variables.
public static final int WIDTH = 620 ;
public static final int HEIGHT = 350 ;
public static final String VERSION = "1.0" ;
public static final String INFO = "RadioConsole Version " + VERSION +
"\nWritten By Ian Norton (M0AZM)\n" +
"i.norton@lancaster.ac.uk" ;
// IO Multiplexors
private PipedInputMUX inmux ;
private PipedOutputMUX outmux ;
// Vector to store plugins
private Vector plugins ;
private int plugnumber ;
// Connection object.
private Connection connection ;
// Host that we connected to (May include port number).
private String host ;
/**
* main
**/
public static void main(String[] args)
{
// Start the console.
Console c = new Console("DX Cluster Console " + VERSION) ;
}
/**
* Console init method.
* @param String title
**/
public Console(String s)
{
// Default host and port to connect to.
host = "127.0.0.1:27754" ;
// Initialise the frame for the whole thing.
frame = new JFrame(s) ;
// Build connection here.
PipedInputStream pincon = new PipedInputStream() ;
PipedOutputStream poscon = new PipedOutputStream() ;
connection = new Connection(pincon, poscon, this) ;
// Build protocol here.
/**
PipedInputStream pinprot ;
PipedOutputStream posprot ;
try
{
pinprot = new PipedInputStream(poscon) ;
posprot = new PipedOutputStream(pincon) ;
Protocol protocol = new Protocol(pinprot, posprot, this) ;
}
catch(IOException ex)
{
System.out.println("Console: IOException creating protocol.") ;
System.exit(1) ;
}
**/
// Build input/output MUX's here.
PipedInputStream pinmux ;
PipedOutputStream posmux ;
try
{
// Initialise pipes.
pinmux = new PipedInputStream(poscon) ;
posmux = new PipedOutputStream(pincon) ;
// Initialise the MUX's
inmux = new PipedInputMUX(posmux) ;
outmux = new PipedOutputMUX(pinmux) ;
}
catch(IOException ex)
{
System.out.println("Console: IOException creating MUXes.") ;
System.out.println(ex) ;
System.exit(1) ;
}
// Initialise the plugin stuff.
plugins = new Vector() ;
plugnumber = 0 ;
// Build tabbed panes from the plugins.
buildTabs() ;
// Build menu bars.
buildMenus() ;
// Build the button bar.
// buildToolbar() ;
// Add action listener to close the window.
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0) ; }
});
// Set initial size.
frame.setSize(WIDTH, HEIGHT) ;
frame.getContentPane().add(tabbedpane, BorderLayout.CENTER);
frame.show();
// Pop a connection dialog or use saved hostname or something here.
connection.connect(host) ;
}
/**
* buildTabs - build the tabbed panes with the plugins.
**/
public void buildTabs()
{
tabbedpane = new JTabbedPane() ;
tabbedpane.setTabPlacement(JTabbedPane.BOTTOM);
// The first plugin should always be the cluster plugin.
// addPlugin("Cluster") ;
addPlugin("SpiderCluster") ;
// Call insert plugins method here. **AZM**
}
/**
* buildMenus - build the Menus with the plugins.
**/
public void buildMenus()
{
// Create a menu bar and add it to the frame.
JMenuBar mbar = new JMenuBar() ;
frame.setJMenuBar(mbar) ;
// Create the file menu stuff.
JMenu filemenu = new JMenu("File") ;
JMenuItem item ;
filemenu.add(item = new JMenuItem("Connect")) ;
item.setMnemonic(KeyEvent.VK_C) ;
item.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_C, ActionEvent.ALT_MASK));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
connection.connect(host);
}});
filemenu.add(item = new JMenuItem("Connect To")) ;
// item.setMnemonic(KeyEvent.VK_C) ;
// item.setAccelerator(KeyStroke.getKeyStroke(
// KeyEvent.VK_C, ActionEvent.ALT_MASK));
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Connection dialog.
String ho = JOptionPane.showInputDialog("Enter the host to connect to") ;
if(ho == null || ho.indexOf(" ") > -1)
return ;
if(ho != null && ho.length() > 0)
{
// connection.disconnect() ;
connection.connect(ho);
}
}});
filemenu.add(item = new JMenuItem("Disconnect")) ;
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{ connection.disconnect() ; }});
filemenu.add(item = new JMenuItem("About")) ;
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{ JOptionPane.showMessageDialog(frame, INFO) ; }});
filemenu.addSeparator() ;
filemenu.add(item = new JMenuItem("Quit")) ;
item.addActionListener(new ActionListener() { // Quit.
public void actionPerformed(ActionEvent e) { System.exit(0) ; }});
// Add the menus onto the menu bar.
mbar.add(filemenu) ;
}
/**
* buildToolbar - build the Toolbar with the plugins.
**/
public void buildToolbar()
{
}
/**
* addPlugin
* @param String - name of the plugin to insert.
**/
private void addPlugin(String p)
{
Plugin pl = null ;
try
{
Class c = Class.forName(p) ;
pl = (Plugin)c.newInstance();
}
catch(ClassNotFoundException ex)
{
System.out.println("Exceptional!\n"+ex) ;
}
catch(InstantiationException ex)
{
System.out.println("Exceptional!\n"+ex) ;
}
catch(IllegalAccessException ex)
{
System.out.println("Exceptional!\n"+ex) ;
}
PipedOutputStream plugoutstr = new PipedOutputStream() ;
PipedInputStream pluginstr = new PipedInputStream() ;
// Insert the object into the vector.
plugins.addElement(pl) ;
// Add the plug in to the tabbedpane.
tabbedpane.addTab(pl.getTabName(), null, pl, pl.getTabTip()) ;
PipedInputStream pinmux = null ;
PipedOutputStream posmux = null ;
try
{
pinmux = new PipedInputStream(plugoutstr) ;
posmux = new PipedOutputStream(pluginstr) ;
}
catch(IOException ex)
{
System.out.println("Console: IOException creating plugin pipes.") ;
System.out.println(ex) ;
}
// Add the streams to the multiplexors.
inmux.addInputStream(pinmux) ;
outmux.addOutputStream(posmux) ;
// Initialise the plugin.
pl.init(pluginstr, plugoutstr) ;
plugnumber++ ;
// Menus?
// Toolbars?
}
}

Binary file not shown.

View File

@ -0,0 +1,100 @@
/**
* LimitedStyledDocument
* @author Ian Norton
* @version 1.0 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.awt.* ;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.Toolkit;
import java.util.* ;
public class LimitedStyledDocument extends DefaultStyledDocument
{
int scrollbufferlines ;
SimpleAttributeSet attr ;
int num ;
public LimitedStyledDocument(int i)
{
scrollbufferlines = i ;
attr = new SimpleAttributeSet() ;
num = 0 ;
}
/**
* append - append a string to the end of the document keeping the
* number of lines in the document at or below maxscrollbuffer.
* @param String s - String to append.
* @param AttributeSet a - Attributes of the string to append.
**/
public void append(String s, AttributeSet a)
{
// Try and append the string to the document.
try
{
super.insertString(super.getLength(), s, a) ;
}
catch(BadLocationException ex)
{
}
StringTokenizer st = null ;
// Split the document into tokens delimited by '\n'.
try
{
// Need to do clever stuff here to chop the top off the buffer.
st = new StringTokenizer(super.getText(0, super.getLength()), "\n") ;
}
catch(BadLocationException ex)
{
}
int i = 0;
// Are there more lines than there should be?
if(st.countTokens() > scrollbufferlines)
{
// How many lines too many?
i = st.countTokens() - scrollbufferlines ;
}
// For each line too many
for(;i>0;i--)
{
String tmp = st.nextToken() ;
try
{
// Remove the line.
super.remove(0, super.getText(0, super.getLength()).indexOf(tmp) + tmp.length()) ;
}
catch(BadLocationException ex)
{
}
} // End of for(;i>0;i--)
} // End of append
} // End of class.

Binary file not shown.

View File

@ -0,0 +1,145 @@
/**
* InputStreamMultiplexor
* This takes multiple input streams and sends them to one input stream.
* @author Ian Norton
* @version 1.00 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.io.* ;
import java.util.Vector ;
import java.util.Enumeration ;
import java.util.Calendar ;
class PipedInputMUX implements Runnable
{
public static final boolean DEBUG = false ;
public static final String encoding = "latin1"; // "ISO8859_1";
private PipedOutputStream pos ;
private Vector streams ;
private Thread t ;
/**
* PipedInputMUX initialiser.
* @param PipedOutputStream - target stream.
**/
public PipedInputMUX(PipedOutputStream o)
{
pos = o ;
// Streams Vector holds all the InputStreams we know about.
streams = new Vector() ;
// Initialise and start the thread.
t = new Thread(this, "InputMultiplexor") ;
t.start() ;
}
/**
* addInputStream
* @param PipedInputStream pi - add a stream get input from.
**/
public void addInputStream(PipedInputStream pi)
{
// Add the supplied stream to the vector of streams.
streams.addElement(pi) ;
}
/**
* run - Thread run method.
**/
public void run()
{
// Loop continually reading from the input streams
while(true)
{
// Enumeration thing here.
Enumeration e = streams.elements() ;
byte[] b = new byte[16];
while(e.hasMoreElements())
{
PipedInputStream is = (PipedInputStream)e.nextElement() ;
try
{
// Read a line and see if it has any data in it.
int n = 0;
// While there is non-blocking data available to read
while(is.available() > 0)
{
// find out how many bytes we can read without blocking
int rdb = is.available() ;
if(rdb > 16) rdb = 16 ;
// Read that many bytes and return.
n = is.read(b, 0, rdb);
if(n > 0)
{
String output = new String(b, 0, n, encoding) ;
send(output) ;
}
}
if(DEBUG) System.out.println("After reading a line.") ;
}
catch(IOException ex)
{
// If we get an IO exception, then the other end of the pipe
// has been closed. We need to remove this stream.
streams.removeElement(is) ;
System.out.println("IOException - stream removed.") ;
}
} // End of while(e.hasMoreElements())
} // End of while(true)
} // End of run()
/**
* send
* @param String s - string to send to destination stream.
**/
private void send(String s)
{
// Calendar cal = Calendar.getInstance() ;
// if(DEBUG) System.out.println("PipedInputMUX: " + cal.getTime() + " Send called with : " + s) ;
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
pos.write(s.charAt(i)) ;
pos.flush() ;
}
}
catch(IOException ex)
{
System.out.println("PipedInputMUX: IOException on destination stream.") ;
}
}
} // End of class.

Binary file not shown.

View File

@ -0,0 +1,148 @@
/**
* OutputStreamMultiplexor
* Takes one output stream and sends it to multiple output streams.
* @author Ian Norton
* @version 1.0 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import java.io.* ;
import java.util.Vector ;
import java.util.Enumeration ;
import java.util.Calendar ;
class PipedOutputMUX implements Runnable
{
public static final boolean DEBUG = false ;
public static final String encoding = "latin1"; // "ISO8859_1";
private PipedInputStream pin ;
private Vector streams ;
private Thread t ;
/**
* PipedOutputMUX initialiser
* @param PipedOutputStream i - Source stream
**/
public PipedOutputMUX(PipedInputStream i)
{
pin = i ;
// Streams Vector holds all the OutputStreams we know about.
streams = new Vector() ;
// Initialise and start the thread.
t = new Thread(this, "OutputMultiplexor") ;
t.start() ;
}
/**
* addOutputStream
* @param PipedOutputStream po - add a stream to send output to.
**/
public void addOutputStream(PipedOutputStream po)
{
// Add the supplied stream to the vector of streams.
streams.addElement(po) ;
}
/**
* run - Thread run method.
**/
public void run()
{
// Loop continually reading the input stream.
while(true)
{
try
{
byte[] b = new byte[16];
// Read a line and see if it has any data in it.
int n = 0;
// Trying to read
while(pin.available() > 0)
{
int rdb = pin.available() ;
if(rdb > 16) rdb = 16 ;
n = pin.read(b, 0, rdb);
if(n > 0)
{
// Convert the output to a string and send it.
String output = new String(b, 0, n, encoding) ;
if(DEBUG) System.out.println(output) ;
send(output) ;
}
}
}
catch(IOException ex)
{
System.out.println("PipedOutputMUX: IOException trying to read.") ;
System.exit(1) ;
}
} // End of loop
} // End of run()
/**
* send
* @param String s - string to send to all streams.
**/
private void send(String s)
{
// Calendar cal = Calendar.getInstance() ;
// if(DEBUG) System.out.println("PipedOutputMUX: " + cal.getTime() + " Send called with :" + s) ;
// If we have no streams, then we can't do anything.
if(streams.size() == 0) return ;
// Create Enumeration object to enumerate with :-)
Enumeration e = streams.elements() ;
// Go through the enumeration and send the string to each stream.
while(e.hasMoreElements())
{
PipedOutputStream os = (PipedOutputStream)e.nextElement() ;
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
os.write(s.charAt(i)) ;
os.flush() ;
}
}
catch(IOException ex)
{
// If we get an IO exception, then the other end of the pipe
// has been closed. We need to remove this stream.
streams.removeElement(os) ;
System.out.println("IOException - stream removed.") ;
}
}
}
} // End of class.

Binary file not shown.

View File

@ -0,0 +1,39 @@
/**
* Plugin - abstract plugin class.
* We need this so that when we compile Console, it knows what methods to
* expect in plugin modules. If we don't use this it will complain.
* Any methods added to plugins need to be added to ALL plugins and here.
* @author Ian Norton
* @version 1.0 - 20010418.
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import javax.swing.*;
import java.io.PipedInputStream ;
import java.io.PipedOutputStream ;
public abstract class Plugin extends JPanel{
public abstract void init(PipedInputStream i, PipedOutputStream o) ;
public abstract String getTabName() ;
public abstract String getTabTip() ;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,375 @@
/**
* SpiderCluster - SpiderCluster console plugin.
* @author Ian Norton
* @verison 1.0 - 20010418.
* @see JPanel
*
* Copyright (C) 2001 Ian Norton.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public Licence as published by
* the Free Software Foundation; either version 2 of the Licence, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public Licence for more details.
*
* You should have received a copy of the GNU General Public Licence
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Contacting the author :
* Ian Norton
* i.norton@lancaster.ac.uk
* http://www.lancs.ac.uk/~norton/
**/
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.Hashtable ;
import java.util.Enumeration ;
// public class Cluster extends Plugin implements Runnable
class SpiderCluster extends Plugin implements Runnable
{
// Name and tip used when creating the tabbed pane.
public static final String NAME = "SpiderCluster" ;
public static final String TIP = "Spider DX Cluster Console" ;
// Number of commands to buffer.
public static final int CMDBUFFERLINES = 30 ;
// Number of lines of scrollback to buffer.
public static final int SCROLLBUFFERLINES = 100 ;
public static final boolean DEBUG = false ;
// Input and output streams for the plugin.
private BufferedReader bir ;
private PipedOutputStream pos ;
// User input field.
private JTextField tf ;
private JTextPane jtp ;
private Thread t ;
private SimpleAttributeSet attr ;
private LimitedStyledDocument doc ;
// Input line scrollback buffer.
private CommandBuffer cbuf ;
// Callsign of the connecting user.
private String call ;
private static final String encoding = "latin1"; // "ISO8859_1";
/**
* Class initialiser.
**/
public SpiderCluster()
{
super() ;
}
/**
* Plugin initialiser.
* @param PipedInputStream i - Stream to read data from
* @param PipedOutputStream o - Stream to write data to
**/
public void init(PipedInputStream i, PipedOutputStream o)
{
// Initialise the plugin IO.
bir = new BufferedReader(new InputStreamReader(i)) ;
pos = o ;
// Initialise the Scrolling output area.
doc = new LimitedStyledDocument(SCROLLBUFFERLINES) ;
jtp = new JTextPane(doc) ;
jtp.setEditable(false) ;
attr = new SimpleAttributeSet() ;
StyleConstants.setFontFamily(attr, "Monospaced") ;
StyleConstants.setFontSize(attr, 10) ;
jtp.setBackground(Color.black) ;
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
jtp.setCaretPosition(doc.getLength()) ;
}
public void removeUpdate(DocumentEvent e) { }
public void changedUpdate(DocumentEvent e) { }
});
// Initialise the TextField for user input.
tf = new JTextField() ;
tf.setFont(new Font("Courier", Font.PLAIN, 10)) ;
Insets inset = tf.getMargin() ;
inset.top = inset.top + 1 ;
inset.bottom = inset.bottom + 1 ;
tf.setMargin(inset) ;
tf.setForeground(Color.white) ;
tf.setBackground(Color.black) ;
tf.setCaretColor(Color.white) ;
// Set the layout manager.
this.setLayout(new BorderLayout()) ;
// Scrollbars for scrolling text area.
JScrollPane scrollpane = new JScrollPane(jtp);
// Add the bits to the panel.
this.add(scrollpane, BorderLayout.CENTER);
this.add(tf, BorderLayout.SOUTH);
// Initialise the command buffer.
cbuf = new CommandBuffer(CMDBUFFERLINES) ;
// Action listener stuff.
tf.addKeyListener(new KeyAdapter()
{
public void keyTyped(KeyEvent e)
{
// Enter key
if((e.getID() == KeyEvent.KEY_TYPED) && (e.getKeyChar() == KeyEvent.VK_ENTER))
{
if(DEBUG) System.out.println("Enter Event") ;
send(tf.getText() + '\n') ;
cbuf.addCommand(tf.getText()) ;
tf.setText("") ;
}
}
public void keyPressed(KeyEvent e)
{
// UP Arrow
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_UP))
{
if(DEBUG) System.out.println("UP Event") ;
tf.setText(cbuf.getPreviousCommand()) ;
tf.setCaretPosition(tf.getText().length()) ;
}
// DOWN Arrow
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_DOWN))
{
if(DEBUG) System.out.println("DOWN Event") ;
tf.setText(cbuf.getNextCommand()) ;
tf.setCaretPosition(tf.getText().length()) ;
}
// Escape key
if((e.getID() == KeyEvent.KEY_PRESSED) && (e.getKeyCode() == KeyEvent.VK_ESCAPE))
{
if(DEBUG) System.out.println("ESCAPE Event") ;
tf.setText("") ; }
}
}) ;
// Add component listener to focus text field.
this.addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
tf.setVisible(true) ;
tf.requestFocus() ;
}
});
// Init the scrolling thread.
t = new Thread(this, "Scrolling thread") ;
t.start() ;
// Prompt for callsign to connect with.
while(call == null || call.indexOf(" ") > -1)
{
call = JOptionPane.showInputDialog("Enter your callsign") ;
}
call = call.toUpperCase() ;
} // End of init
/**
* getTabName - Get the name that this component should show on it's tab
* @returns String s - Tab name
**/
public String getTabName()
{ return NAME ;
}
/**
* getTabTip - Get the tip that this component should show on it's tab
* @returns String s - Tab tip
**/
public String getTabTip()
{
return TIP ;
}
/**
* getMenu - get the menu to add to the main menu bar.
* @returns JMenu
**/
public JMenu getMenu()
{
return null ;
}
/**
* send - Helper function to send data out to the PipedOutputMUX
* @param String s - data to send.
**/
private void send(String s)
{
if(DEBUG) System.out.println("Cluster: send got : " + s) ;
// If the input has no | in it, prefix I<CALLSIGN>| and send it.
if(s.indexOf("|") == -1)
{
s = "I" + call + "|" + s ;
}
try
{
// Write the data to the stream.
for(int i=0;i<s.length();i++)
{
pos.write(s.charAt(i)) ;
}
}
catch(IOException ex)
{
System.out.println("Cluster: IOException on destination stream.") ;
System.out.println(ex) ;
}
}
/**
* Loop continually checking to see if anything has been written to the
* file that is being monitored.
*/
public void run()
{
String output = new String() ;
// Loop continually reading from the input stream
while(true)
{
try
{
// Read in a line of data (This screws up prompts with no /n)
output = bir.readLine() ;
if(output != null) display(output) ;
if(DEBUG) System.out.println("After reading a line.") ;
}
catch(IOException ex)
{
System.out.println("SpiderCluster: IOException trying to read.") ;
}
} // End of infinate loop.
} // End of run.
private void display(String s)
{
// Automatic login - when we see "Conneted to" send the login string.
if(s.startsWith("Connected to")) { send("A" + call + "|local\n") ; }
// s = s.replace('', ' ') ;
// Get rid of Ctrl-G's in UNICODE.
while(s.indexOf("%07") > -1)
{
StringBuffer sb = new StringBuffer(s) ;
sb.delete(s.indexOf("%07"), s.indexOf("%07") + 3) ;
s = sb.toString() ;
}
// If the line has a | and starts with D, strip off upto and inc the |.
if(s.indexOf("|") != -1 && s.charAt(0) == 'D')
{
s = s.substring(s.indexOf("|") + 1, s.length()) ;
}
// Find out what colour this needs to be.
attr = getAttributes(s) ;
// Display it in the doc.
doc.append(s + "\n", attr) ;
}
/**
* getAttributes(String s) - get attributes (i.e. colour) given a string.
* @param String s
**/
private SimpleAttributeSet getAttributes(String s)
{
SimpleAttributeSet sas = attr ;
/**
# 0 - $foreground, $background
# 1 - RED, $background
# 2 - BROWN, $background
# 3 - GREEN, $background
# 4 - CYAN, $background
# 5 - BLUE, $background
# 6 - MAGENTA, $background
VHF DX SPOT
[ '^DX de [\-A-Z0-9]+:\s+([57][01]\d\d\d\.|\d\d\d\d\d\d+.)', COLOR_PAIR(1) ],
PROMPT
[ '^G0VGS de GB7MBC', COLOR_PAIR(6) ],
DUNNO!
[ '^G0VGS de', A_BOLD|COLOR_PAIR(2) ],
HF DX SPOT
[ '^DX', COLOR_PAIR(5) ],
ANNOUNCE
[ '^To', COLOR_PAIR(3) ],
WWV SPOT
[ '^WWV', COLOR_PAIR(4) ],
DUNNO!
[ '^[-A-Z0-9]+ de [-A-Z0-9]+ \d\d-\w\w\w-\d\d\d\d \d\d\d\dZ', COLOR_PAIR(0) ],
DUNNO! - PROBABLY A TALK
[ '^[-A-Z0-9]+ de [-A-Z0-9]+ ', COLOR_PAIR(6) ],
WX SPOT
[ '^WX', COLOR_PAIR(3) ],
NEW MAIL
[ '^New mail', A_BOLD|COLOR_PAIR(4) ],
USER LOGIN?
[ '^User', COLOR_PAIR(2) ],
NODE LOGIN?
[ '^Node', COLOR_PAIR(2) ],
**/
Hashtable h = new Hashtable() ;
h.put("DX de", Color.red) ; // HF DX
h.put(call + " de ", Color.magenta) ;
// h.put("DX", Color.blue) ; // VHF/UHF DX
h.put("To", Color.green) ;
h.put("WWV", Color.cyan) ;
h.put("WCY", Color.cyan) ;
// h.put("", Color.) ;
// h.put("", Color.) ;
h.put("WX", Color.green) ;
h.put("New mail", Color.cyan) ;
//h.put("User", Color.brown) ;
//h.put("Node", Color.brown) ;
h.put("User", Color.yellow) ;
h.put("Node", Color.orange) ;
Enumeration e = h.keys() ;
while(e.hasMoreElements())
{
String prefix = (String)e.nextElement() ;
if(s.startsWith(prefix))
{
StyleConstants.setForeground(sas, (Color)h.get(prefix)) ;
return sas ;
}
}
StyleConstants.setForeground(sas, Color.white) ;
return sas ;
}
} // End of class.