Imported Upstream version 2.3.1
This commit is contained in:
commit
4013fe89db
|
@ -0,0 +1,6 @@
|
||||||
|
Note in regards to PBBS forwarding:
|
||||||
|
If you do compressed forwarding with other PBBS systems, insure you flag
|
||||||
|
your connection so that you do NOT have ANSI turned on for that interface
|
||||||
|
AND that you disable the escape character. See: man uronode.perms
|
||||||
|
for the proper flags. This insures that compression will stay enabled
|
||||||
|
and that a compressed ctrl+t is not sent via compressed ascii codes.
|
|
@ -0,0 +1,929 @@
|
||||||
|
URONode bug fix and change notes:
|
||||||
|
|
||||||
|
30/4/1998 v0.3a:
|
||||||
|
Users with no permissions on AX25, NETROM, ROSE, TELNET outgoing connections,
|
||||||
|
can use alias commands that connect a remote node by AX25, NETROM, ROSE and
|
||||||
|
TELNET outgoing connections.
|
||||||
|
|
||||||
|
30/4/1998 v0.3b:
|
||||||
|
"!" command crashed on systems with no swap: CORRECTED!
|
||||||
|
Reconnected on Telnet sended two prompt-line: CORRECTED!
|
||||||
|
|
||||||
|
8/1/2000 v0.4-pre1:
|
||||||
|
Now compile and run under kernel 2.2.x, glibc6 and new ax25 and ax25io libs!
|
||||||
|
Added Gateway special tranfer mode.
|
||||||
|
|
||||||
|
18/2/2000 v0.4-pre2:
|
||||||
|
"Ports" command crashed on systems without listening sockets: CORRECTED!
|
||||||
|
Bad Pre-compiler directive order for systems without ROSE support: CORRECTED!
|
||||||
|
Now AWZNode have a better I/O flushing.
|
||||||
|
Other little code bugs resolved.
|
||||||
|
|
||||||
|
*Rewrites by Brian N1URO
|
||||||
|
**Note: this is being done on a debian linux server running kernel 2.4.20.
|
||||||
|
your milage may vary depending on the flavor of linux you're using. It
|
||||||
|
may be possible that with the exception of screen pushes, the AWZNode
|
||||||
|
could infact be working 100% fine, this I don't know.
|
||||||
|
|
||||||
|
5/4/2003 v0.5.2:
|
||||||
|
Renamed the project to AWZ-URONode.
|
||||||
|
Stripped out the recursing prompt to the end users.
|
||||||
|
Redesigned the output of the node to be similar to that of TheNet X1J type
|
||||||
|
nodes.
|
||||||
|
Added NodeId variable header of several command output lines, this is
|
||||||
|
totally configurable in /etc/ax25/node.conf under the "NodeId" option. I
|
||||||
|
suggest in keeping with the design of TheNet X1J to use a format similar
|
||||||
|
to: UROHUB:N1URO-2} (that's my personal preference hi!)
|
||||||
|
In flexd.c (line 310), changed i++ from (2) to (16) to ignore additional ctext.
|
||||||
|
If by chance you only get one packet burst worth of ctext or login.fpr
|
||||||
|
information, you may reduce (16) below to 8, or if yo uget 3 packets worth
|
||||||
|
of information you may go higher. In my case, I receive two packets of connect
|
||||||
|
texts from my FlexNet gateway node so I use 16 for myself. You will have to
|
||||||
|
experiment with this. You have been notified. Failure to adjust the parsing
|
||||||
|
code properly -will- result in any connect text strings as being falsely
|
||||||
|
parsed as bogus flexnet destinations and will maintain a sloppy list.
|
||||||
|
|
||||||
|
5/4/2003 v0.5.3:
|
||||||
|
With the amount of rewrites, I decided to rename the node to URONode.
|
||||||
|
Did more cosmetic cleanups and changed the node to look more like TheNet
|
||||||
|
type node. This also included some code cleanup and rewrites of some
|
||||||
|
minor routines.
|
||||||
|
Readded a node prompt as an option, however unlike the previous way
|
||||||
|
the prompt was programmed, if there was no prompt defined, a generic
|
||||||
|
AWZNode -> prompt displayed. If in /etc/ax25/node.conf the prompt
|
||||||
|
was left blank (aka: "") then a null line feed occurred. Now in
|
||||||
|
regards to the prompt, if no Prompt is defined in /etc/ax25/node.conf
|
||||||
|
a flexnet type prompt "=>" will display, or if you set the prompt in
|
||||||
|
/etc/ax25/node.conf to Prompt "", then the prompt will be defeated
|
||||||
|
and no additional lines of text (null or not) will be displayed.
|
||||||
|
*I found it VERY frustrating that when a sysop or a user with
|
||||||
|
shell permissions accessed the shell, upon return, there was
|
||||||
|
no notification that you were back into the node! Added a routine
|
||||||
|
that welcomed the user back to the node upon shell logout.
|
||||||
|
Repeated the above for the PMS gateway. I guess AWZ hardcoded in
|
||||||
|
a prompt for such notifications so I assume I am the one who
|
||||||
|
broke this hi!
|
||||||
|
|
||||||
|
6/4/2003 v0.5.4
|
||||||
|
Cleaned out some coded carriage returns which to me only adds junk to the
|
||||||
|
code (unless the intent was for this to ensure a local echo wasn't working
|
||||||
|
or something of that nature... ) at any rate, commented it out for now.
|
||||||
|
Tightned some more of the displays which also cleans up some code as well.
|
||||||
|
By now you may be wondering the madness behind my logic:
|
||||||
|
As I stated when I first started this project, my goal was to use the
|
||||||
|
existing AWZNode code and make it behave (oh austin powers behave!) as
|
||||||
|
much like a TheNet X1J node as I could, with enhancing upon the existing
|
||||||
|
tcp/ip and flexnet features this node has. Of course, code cleanup is part
|
||||||
|
of the process. One thing I noticed on both AWZ and Tomi's node programs
|
||||||
|
were the added strings both push such as the "Trying" messages when a
|
||||||
|
user requests a connect to another node, etc. Personally, and especially
|
||||||
|
on busy 1k2 baud links, i find it a bit irritating (as I'm sure end users
|
||||||
|
do also) that additional lag due to a null line-feed or the node telling
|
||||||
|
me what I asked it to is in process. In essance, this *should* make the
|
||||||
|
node appear to connect faster for the end user... I hope *grin*
|
||||||
|
Cleaned up the Sessions display... the net/rom sessions screen had an
|
||||||
|
allocation for Rtt when it's not in use. This also caused the Sendq
|
||||||
|
colum to appear grunged/misplaced.
|
||||||
|
There's still some line-feeds here n there I'm cleaning as I go to which
|
||||||
|
the subversion will increase hi!
|
||||||
|
|
||||||
|
6/4/2003 v0.5.5
|
||||||
|
Changed mailbox.c and system.c from looking at the users's environment
|
||||||
|
mail variable to point to /usr/bin/mail and /var/spool/mail/ respectively.
|
||||||
|
I noticed (on debian anyway) that the hardcoded paths failed mail to no
|
||||||
|
end. Doing more work on mail as I go along. Note: this only affects internet
|
||||||
|
based email! A seperate PBBS such as F6FBB is recommended for AX.25 mail.
|
||||||
|
Changed MSession command back to Sessions. I have no idea why this was done.
|
||||||
|
Deleted the Send command. It refuses to send no matter what I do anyway, so
|
||||||
|
to me it's useless. Also changed ! (STats) to STats to match Tomi's node.
|
||||||
|
Personally, I found this confusing between the two nodes. Added a Quit
|
||||||
|
hardcoded command to match both TheNet X1J and FlexNet style nodes.
|
||||||
|
Tweeked the way the Stats displayed. Memory shows not just 'memory' but
|
||||||
|
the definitions between swap and physical ram are displayed. Also AX.25
|
||||||
|
daemon socket stats are also a bit more defined.
|
||||||
|
Mail checking sometimes worked, other times didn't. Fixed the mailpoll
|
||||||
|
routines so that polling would keep displaying to the user that he/she
|
||||||
|
has new mail. This may irritate the user, but considering it's your
|
||||||
|
hard disk space that's storing their internet email, for them to be
|
||||||
|
on the node and simply choose *not* to read and/or delete mail from
|
||||||
|
your resources is just as rude to you (my train of thought anyway).
|
||||||
|
**NOTE: I can't stress enough on how dangerous (in regards to spam)
|
||||||
|
the mail feature can be! I **highly** suggest that you *only* give
|
||||||
|
access to those you know are hams! Needless to say, I would *not*
|
||||||
|
turn access for this feature on for global access!!! Not only would
|
||||||
|
you upset many people who are against receiving junk emails, but you
|
||||||
|
could risk losing any and all internet connectivity from your ISP as
|
||||||
|
some are *very* picky about spam mail that's relayed! Working for ISPs
|
||||||
|
in the past, I can verify this :-)
|
||||||
|
|
||||||
|
8/4/2003 v0.5.6
|
||||||
|
Still cleaning up some displays...this will be a task as I go along.
|
||||||
|
One thing I'm not positive about is whether or not on multiple port
|
||||||
|
usage how some diplays will read since I only have a single ax0 port
|
||||||
|
I'm using.
|
||||||
|
Fixed some routines in the do_finger command and added user usage
|
||||||
|
messages. In some cases, routines were forced so that if certain
|
||||||
|
strings (even null) weren't set after the finger command, it
|
||||||
|
was programmed to force the user to finger the localhost whether
|
||||||
|
or not that was their intentions. Personally, I found it better
|
||||||
|
to push a usage message of one line to the user than to go ahead
|
||||||
|
and process an errant finger request to the localhost. I did
|
||||||
|
force finger to require an @ within the command... since you're
|
||||||
|
fingering something"@"somewhere. This is displayed in the usage
|
||||||
|
message to the end user whether or not the input string after
|
||||||
|
the command is null.
|
||||||
|
Mail checking still seems buggy, and the bug seems somehow (so far)
|
||||||
|
to be linked with the mailbox.c routines. This is also where the
|
||||||
|
do_sendmessage command is. Fixed some routines in the send command
|
||||||
|
where if the To: or Subject fields comtained an UPPERCASE
|
||||||
|
character, it could cause the node to segfault out and leave
|
||||||
|
the ipcs open. This is bad! More on this in the Known Bugs section.
|
||||||
|
|
||||||
|
10/4/2003 v0.5.7
|
||||||
|
Whew! After much hassle...FIXED the former (and I mean former hi!)
|
||||||
|
SEnd command. While I was at it I also renamed it from Send to
|
||||||
|
MEssage. I thought Mail and MEssage were similar in function so
|
||||||
|
I decided to keep them together on the prompt as well.
|
||||||
|
|
||||||
|
11/4/2003 v0.5.8
|
||||||
|
Found a bug in the MEssage command *sigh* more on this below.
|
||||||
|
Moved the location of the help files from /usr/lib/ax25/node/help/
|
||||||
|
to /var/ax25/node/help/ so that all created node files are together.
|
||||||
|
Changed/fixed some of the help files to reflect changed commands, etc.
|
||||||
|
Cleaned up more diplay text. (since I'm more a code hacker than a true
|
||||||
|
coder, this is what I do best hi!.. but I learn as I go.)
|
||||||
|
Edited the man pages and changed them from a text to a compressed format.
|
||||||
|
Changed the configure script to grab the server's hostname. If your
|
||||||
|
server's hostname is already an *.ampr.org host, then you should be
|
||||||
|
fine with everything. If your server's hostname is a commercial domain
|
||||||
|
based name, then you will have to edit config.h and insert the proper
|
||||||
|
your.ampr.org hostname inside, or if you wish replied mail to be auto
|
||||||
|
redirected to a NOS based node, enter in your NOS' ampr.org hostname.
|
||||||
|
Added a warning message in the ./configure script to alert the sysop
|
||||||
|
to check their config.h file for proper paths, etc. I was going to force
|
||||||
|
a load of vi, but now-a-day most people don't use vi from my discussions
|
||||||
|
but another editor such as ae, joe, pico, etc. Since the sysop will be
|
||||||
|
editing their config files anyway, I feel the sysop can take a minute to
|
||||||
|
verify paths and variables. Please pay close attention to any and all
|
||||||
|
comments within this file!
|
||||||
|
Added Makefile.in which is a 'generic' Makefile. Makefile is now created
|
||||||
|
when you run the configure script. Also added some other environment
|
||||||
|
grabber functions to the configure script which adds to the proper files
|
||||||
|
that requires them for you.
|
||||||
|
Added removal of Makefile in the command 'make distclean'.
|
||||||
|
Removed local echo of "To:" field when using the MEssage command. That was
|
||||||
|
for debugging purposes anyway.
|
||||||
|
|
||||||
|
12/4/2003 v0.5.9
|
||||||
|
Fixed the bug that drove me nuts with the mail command. Now the mail
|
||||||
|
command will reject/refuse a parameter. One more down off of the
|
||||||
|
hitlist of bugs :-) It was suggested by N1UAN to make a configure
|
||||||
|
script toggle for the MEssage command too. I may do that in the future.
|
||||||
|
Fixed a bug in the POrts output. Since I only have one port, this was
|
||||||
|
hard for me to test. N1UAN has multiple ports and using his node I was
|
||||||
|
able to see and fix this bug before it made it to the buglist.
|
||||||
|
|
||||||
|
12/4/2003 v0.5.10
|
||||||
|
Woops, fixed a bug in the Info command where there wasn't a line
|
||||||
|
feed after the compile date. Reported by N1UAN. I also found a bug
|
||||||
|
in the display of: Node Call|Alias where lines were grunging. I
|
||||||
|
*think* I fixed this. Unfortunately this is the result of me only
|
||||||
|
having one port to work with hi! I happened to find this myself
|
||||||
|
using the copy N1UAN is running. Hopefully I fixed this bug.
|
||||||
|
More of a maintenance release than anything else. Fixed a few tweeks
|
||||||
|
here and there, nothing worthwhile to mention. The key thing in this
|
||||||
|
version was to make it more customizable for the hard-set commands.
|
||||||
|
This was suggested by N1UAN to which I kind of agree. It is possible that
|
||||||
|
one could have a linux box on an amateur radio packet network but not wish
|
||||||
|
to have it connected to the ampr.org or any other TCP/IP network. Coding in
|
||||||
|
these commands would then become a bit of a tease to the end user who may
|
||||||
|
wish to use URONode as a 'NOS' substitute for outbound telnet links, etc.
|
||||||
|
Now hardcoded commands will be toggled on/off depending on how you answer
|
||||||
|
the configure script. Answering NO to ALL questions will enable ONLY the
|
||||||
|
following hardcoded commands:
|
||||||
|
?, Bye, Escape, Help, Info, Quit, Status.
|
||||||
|
Answering YES to AX.25 enables:
|
||||||
|
Connect, Desti, Ports, Links, SEssions, Users.
|
||||||
|
Answering YES to Email enables:
|
||||||
|
MEssage.
|
||||||
|
Answering NO to FlexNet:
|
||||||
|
Disables the Desti command and will NOT compile or install the flexd
|
||||||
|
daemon...however if you have a destinations file that is valid that
|
||||||
|
will allow users to connect to digipeated paths without having to
|
||||||
|
manually type a 'via' statement in.
|
||||||
|
Answering YES to FlexNet enables:
|
||||||
|
Desti.
|
||||||
|
Answering YES to MHEARD enables:
|
||||||
|
MHeard.
|
||||||
|
Answering YES to NETROM enables:
|
||||||
|
Nodes, Routes.
|
||||||
|
Answering YES to ROSE enables:
|
||||||
|
Rose based protocol strings within ax.25
|
||||||
|
Answering YES to TCP/IP enables:
|
||||||
|
Finger, HOst, Ping, Telnet
|
||||||
|
Answering YES to TALK enables:
|
||||||
|
TAlk.
|
||||||
|
I may move the users to the default hardcoded commands..but for now my
|
||||||
|
thinking at 5:00am on a saturday morning is, if you're not going to run
|
||||||
|
ax.25, then you probably aren't as concerned who's in the node :-) Also
|
||||||
|
the use of the linux netstat command will show you who's on. The commands
|
||||||
|
I'm considering moving to the default are the ax.25 related commands...
|
||||||
|
since after all, if you're on RF, you'll -need- ax.25 right?
|
||||||
|
The Mail and SYsop commands are flagged on|off by the node.user file.
|
||||||
|
|
||||||
|
14/4/2003 v.0.5.11
|
||||||
|
Another change to the configure script. This time it checks your local
|
||||||
|
hostname and requests that you verify it. If you see it's correct,
|
||||||
|
just hit enter. If not, change it. Now... and this is tricky...
|
||||||
|
*if* you do NOT wish to have users RECEIVE mail on the node but have another
|
||||||
|
smtp based server such as a NOS node in which you wish your users to receive
|
||||||
|
smtp mail, then what I suggest you do is set hostname to the hostname of
|
||||||
|
THAT server. What this will do is send mail from the user with a 'return'
|
||||||
|
path of your NOS server. For example;
|
||||||
|
On my system I have an MFNOS node which users may send and receive SMTP
|
||||||
|
based mail. It has a hostname of "n1uro.ampr.org". While users may have
|
||||||
|
permission to SEND mail from URONode "dx.n1uro.ampr.org", I wish them to
|
||||||
|
only receive their mail at n1uro.ampr.org, so in this case I would tell
|
||||||
|
the configure script my hostname is: n1uro.ampr.org. It's sort of a way
|
||||||
|
you can allow mail with some sort of anti-third-party protection. Its not
|
||||||
|
perfect, but it helps. The configure script *will* prompt you for this
|
||||||
|
whether or not you enable the Email feature.
|
||||||
|
I added two neat commands. One is the new Version command. This is set
|
||||||
|
as part of the default hardcoded commands. All it does is shows the
|
||||||
|
version information of the node. This same data is also shown in the
|
||||||
|
Users command to keep the node in line with the display parameters of
|
||||||
|
TheNet/X1J style nodes (as I like). The other is what I call a Whowas
|
||||||
|
command. I got the idea from being on IRC, and borrowed code from
|
||||||
|
PE1RJA's node. With the W command, this will show you when a callsign
|
||||||
|
was last on the node, and how that user connected... ie: which port,
|
||||||
|
ip address, etc. If the user connected multiple times within the scope
|
||||||
|
of the log rotation then a columnized listing of that user's information
|
||||||
|
will be displayed. My happy news is that the SSID stripper from the
|
||||||
|
user's connection in sending email is fixed. One bug down!
|
||||||
|
|
||||||
|
15/4/2003 v0.5-R1
|
||||||
|
WooHOO! MHeard table read/write of digipeated MHeard routing is FIXED!
|
||||||
|
What I had to do was get argv to parse up to two digipeaters and then
|
||||||
|
print to the device each in reverse order. Now since my RF digipeater
|
||||||
|
gateway is a direct flexnet neighbor on axip, this was all I had to
|
||||||
|
test with, your milage may vary. If the digipeated path is not yet in
|
||||||
|
the mheard table, then it will fail. Another bug off of the list!
|
||||||
|
*whew* I knew I was close <G>. Also found some more screen writes
|
||||||
|
to tighten up. As far as I know, I'm going to (for now) close this
|
||||||
|
chapter of my life's efforts and make a release. I"m happy with how
|
||||||
|
URONode is performing and my alpha tester N1UAN appears to be just
|
||||||
|
as pleased :)
|
||||||
|
Found a bug in the output of the Who command when *
|
||||||
|
was entered. While this didn't seem to affect me on a debian system,
|
||||||
|
it did seem to act funky on a SuSe system. Flexd needs NOT be edited
|
||||||
|
now. Cleaned up some time variables in the MHeard routine and added
|
||||||
|
a column for the port heard, and the frame (pid) type. Since the
|
||||||
|
users can now see the pid types, they'll have a hint as to how their
|
||||||
|
connect request will be handled.
|
||||||
|
Found two bugs in the finger routine, both which appear to be in ALL
|
||||||
|
flavors of "*node". The first one I fixed, and that was quite simple.
|
||||||
|
When fingering information, the [address] or [hostname] was omitted.
|
||||||
|
I don't know if this was intentional, but I fixed it anyway to match
|
||||||
|
that of standard 'finger' displays. The second appears to be that
|
||||||
|
on a long RF hop, or a socket that's become broke due to routing
|
||||||
|
being cut, etc... there's *no* escape. For now, I've omitted the
|
||||||
|
Escape: CTRL-* display in all routines. It will still work for
|
||||||
|
telnet, netrom, and other types of connects. Since the Escape
|
||||||
|
command is a seperate command at the moment, I think it's fine
|
||||||
|
for users to check|set their Escape sequence. Hopefully I'll be
|
||||||
|
able to figure out a routine to escape from a 'stuck finger' :-)
|
||||||
|
Also tweeked the output of the HOst command.
|
||||||
|
*Welp, further research shows that there is no "escape" in the
|
||||||
|
native linux finger command... as there is none with the ftp command.
|
||||||
|
Needless to say, the better 'fix' was to simply disable all 'trying' state
|
||||||
|
messages. Personally I find them to be excess traffic that's not needed as
|
||||||
|
either the node will tell you that it's connected or it will tell you that
|
||||||
|
it failed. I know flexnet will tell you that it's trying a link setup and
|
||||||
|
xnet will take that a step further and show you which port the link is being
|
||||||
|
setup on. I may add the set escape sequence in the login screen as default
|
||||||
|
prior to users attempting connections so that it'll be easier on them to
|
||||||
|
know that there is a way to break a connect if needed.
|
||||||
|
|
||||||
|
16/4/2003 v0.5-R2
|
||||||
|
Ok, well I did decide to add the CTRL-* message as part of the
|
||||||
|
initial user login screen. Also made some minor tweeks to the
|
||||||
|
telnet login where now it shows more of a 'linux' style login.
|
||||||
|
Did some more screens cleanups and stripped out a lot of the debugs
|
||||||
|
I had commented out of the code. Ok..enough for now...I'm considering
|
||||||
|
this version 'done' unless bugs are reported. :)
|
||||||
|
|
||||||
|
22/08/2003 - Bug/security report
|
||||||
|
Morgan sm6tky publically posed a security report with some PoC listed but
|
||||||
|
not all. While I was able to duplicate what he did submit for PoC, I
|
||||||
|
wasn't able to find others. I'm very greatful to Morgan for bringing such
|
||||||
|
information to my attention, I'm surprised that his first step was to post
|
||||||
|
it in a public email list and list that I didn't reply when I wasn't even
|
||||||
|
given the chance to... however with that being said, I still took his
|
||||||
|
notations to heart and put the project a bit on the back-burner until I
|
||||||
|
had time to do the fixes. I also offered Morgan a chance to submit code
|
||||||
|
fixes to which he failed to do such. I don't claim to be a coder but just
|
||||||
|
a hobbiest in regards to C and always welcome patches as I have with htppu
|
||||||
|
with patches submitted by Thomas dl9sau who's also released his own flavor
|
||||||
|
entitled SAUPP. Version 0.6.x will be in process as I have the time to do
|
||||||
|
such.
|
||||||
|
|
||||||
|
v0.6.0 - never happened. Just made the directory structure and took an
|
||||||
|
initial peek at Morgan's reports.
|
||||||
|
|
||||||
|
12/7/2005 v0.6.1
|
||||||
|
Security issues fixed/removed. Rather than fix the talk command I decided
|
||||||
|
to just eliminate it in favor of an external conversd command. I figure
|
||||||
|
there's plenty of channels and lord knows there's actually more convers
|
||||||
|
servers now than users to use them... why not just use that?
|
||||||
|
|
||||||
|
Another security issue was mail. Instead of having mail routines built
|
||||||
|
into the node itself, I figure a node sysop can grab my updated axmail
|
||||||
|
node plugin and use that. I've done some basic security tests and it
|
||||||
|
seems to be a better way to go.
|
||||||
|
|
||||||
|
12/7/2005 v0.6.2
|
||||||
|
Just a beta version, never released while working on more security
|
||||||
|
fixes... I think I'm getting close now!
|
||||||
|
|
||||||
|
Changed some code in the do_help routine in command.c where Morgan
|
||||||
|
reported the possibility of a buffer overflow.
|
||||||
|
|
||||||
|
Changed some code in the syslog routine in util.c hopefully fixing the
|
||||||
|
formatstring vulnerability in that routine.
|
||||||
|
|
||||||
|
Changed some code in gateway.c in hopes of fixing the reported buffer
|
||||||
|
overflow.
|
||||||
|
|
||||||
|
Found what I thought to be an open hole in ipc.c, should be fixed and
|
||||||
|
with any luck the ipcs build-up issues will vanish with it. Only time
|
||||||
|
and your debug reports will tell.
|
||||||
|
|
||||||
|
Fixed a bug in Makefile where the man pages weren't installed due to the
|
||||||
|
fact I gzipped them and didn't change this in Makefile.
|
||||||
|
|
||||||
|
Changed the ftp url path, listed below.
|
||||||
|
|
||||||
|
v0.6.3 - some cosmetic tweeks I can't recall what they were.
|
||||||
|
|
||||||
|
04/07/2006 v0.6.4
|
||||||
|
|
||||||
|
Found a bug where if a user's permissions were flagged for "no escape"
|
||||||
|
such as a xNOS, F6FBB BBS, etc, that the node tried to display an Esc-?
|
||||||
|
as part of the prompt/screens. Removed the Esc-? from displaying. That
|
||||||
|
simply annoyed me and I'm surprised it wasn't reported... after all if
|
||||||
|
there's no escape why show "?" as one since "?" can be used as an escape
|
||||||
|
character with CTRL.
|
||||||
|
|
||||||
|
Added an Email flag in node.conf. Simply add:
|
||||||
|
Email <your@node.ampr.org>
|
||||||
|
on a blank line within node.conf for it to get pulled into the node. If you
|
||||||
|
don't "(null)" will display. It won't prevent the node from functioning but
|
||||||
|
will show users how lazy you are hi! This allows a sysop to deny all users
|
||||||
|
connection access _unless_ they have a password, while at the same time
|
||||||
|
allowing the node sysop a means of displaying a point of contact so that
|
||||||
|
users wishing to use their node and it requires a password can send a
|
||||||
|
communication to gain access. I strongly suggest for any account that has
|
||||||
|
sysop privs on the node that you force a password on _all_ connects and
|
||||||
|
that you only grant access via internet/amprnet to those who request a
|
||||||
|
password for security reasons if anything at all. Because I feel this is
|
||||||
|
security related, I'm making this a release.
|
||||||
|
|
||||||
|
Fixed a bug in the install routine for the man pages. The default
|
||||||
|
install for man pages was /usr/man, now it's /usr/share/man. I also
|
||||||
|
updated the manpage for node.conf.5 and re-gzipped it.
|
||||||
|
|
||||||
|
24/10/2006 v0.6.5
|
||||||
|
After a nudge from Stefano in Italy, I reintroduced a method in which one
|
||||||
|
user on the node can send a brief "msg" to another. The command once was
|
||||||
|
"talk" and still is on node (or if you prefer linuxnode that Tomi has
|
||||||
|
set the standard for!). For the sender, they get a full status report
|
||||||
|
as to what happened to their "msg" once the "enter" key is hit. For
|
||||||
|
the receiver, if they're truely idle on the node, the message will pop up
|
||||||
|
on them and the prompt will not return until they acknowledge receipt
|
||||||
|
of the msg by hitting the "enter" key. Also note that a system bell
|
||||||
|
will return on both sides, or just the sender's side *if* the msg
|
||||||
|
wasn't delivered. Since this acts sort of similar to today's Instant
|
||||||
|
Messaging world... I figure "what the hay they play noises too". I still
|
||||||
|
stand on the theory that if one wishes to engage in keyboard chat, they
|
||||||
|
should make direct TNC<>TNC connects or use convers but Stefano
|
||||||
|
made me rethink this and I can see how it could be used for one user
|
||||||
|
to "ping" another user with a msg saying "hey meet me on conv channel
|
||||||
|
32767 and see if we can wake the sleeping sysops!" :-) Originally this
|
||||||
|
was part of Morgan's security report filed back in 2003 (what? me
|
||||||
|
procrastinate? LOL) so with convers so easily available to URONode as
|
||||||
|
a plugin I felt it just as simple and quicker a fix just to remove
|
||||||
|
"talk". I renamed the command to "msg" since you're really just sending
|
||||||
|
a message and not really "talking" to the remote end.
|
||||||
|
|
||||||
|
Fixed the help files a bit to move talk.hlp to msg.hlp, and edited the
|
||||||
|
content of such to fit the re-introduced command.
|
||||||
|
|
||||||
|
26/10/2006 v1.0.0
|
||||||
|
First off, many thanks to Stefano and Alessio for their interest and
|
||||||
|
contributions to URONode. They've inspired me to help improve this
|
||||||
|
spinoff of AWZNode (which is a spinoff of FlexNode which is a
|
||||||
|
spinoff of node which is a spinoff of.... :-} ) Stefano asked me a while
|
||||||
|
back about putting in compression for Telnet and Connect commands.
|
||||||
|
Considering so many have broadband now on their wired links, I somewhat felt
|
||||||
|
this to be unnecessary, and here in the U.S. ax25 based transmissions are
|
||||||
|
supposed to be in plain text... so between those two major reasons I had
|
||||||
|
thought it best to just eliminate this feature a while back... not to
|
||||||
|
mention security issues with zlib that were going on. Since those have
|
||||||
|
been cleared and in respect to the motivation Stefano and Alessio have
|
||||||
|
given me with their interest in this project I thought it only nice that
|
||||||
|
I try and fullfill their desires as best as I can. Recieving compressed
|
||||||
|
requests into URONode was always there but not an outgoing client... so
|
||||||
|
I spent a few moments and coded one back into the front end. Needless
|
||||||
|
to say, ZTelnet and ZConnect (as with node) are in URONode now as
|
||||||
|
client gateway commands.
|
||||||
|
You need to set up another inetd/xinetd instance on an unused port
|
||||||
|
that calls "node -c" to enable receiving compressed connections via
|
||||||
|
telnet. Make a new alias/ssid for ax25/netrom if you wish to support
|
||||||
|
ZConnect client requests. Failure to do such will result in the remote
|
||||||
|
end getting an error message.
|
||||||
|
|
||||||
|
27/12/2007 v1.0.1
|
||||||
|
After a heated discussion with w0rli (as if that has never happened
|
||||||
|
on packet before, and him accusing me of knowing nothing about packet
|
||||||
|
or it's protocols) I decided to keep him happy while working on a system
|
||||||
|
that's linked to one of his. Hank feels that by having a login screen this
|
||||||
|
makes a node an application. While I can understand how he determines this
|
||||||
|
in his one-sided point of view, I still disagree with it but can appreciate
|
||||||
|
his concerns. Apparently he has never logged into a backbone router at an
|
||||||
|
ISP and seen a cisco MOTD file... or is a backbone core or border router
|
||||||
|
not a node on a network? :) In any event, I decided that I'd make the whole
|
||||||
|
login sequence of displaying the node version and /etc/ax25/node.motd file
|
||||||
|
an option to the node sysop upon running the ./configure script. Along
|
||||||
|
with not displaying a MOTD file, the default FlexNet style prompt of
|
||||||
|
"=>" will also not display. This will make URONode act more like
|
||||||
|
Hank's snos and like TheNet X1J-4 (with the "welcome" message flagged
|
||||||
|
off upon connect). Thanks are given to w0rli for this idea.
|
||||||
|
|
||||||
|
I also added a flag for the "NODE} Goodbye." string so that if you
|
||||||
|
do not have a MOTD displayed, it will also halt the display of the
|
||||||
|
node front-end saying bye to the user.
|
||||||
|
|
||||||
|
01/01/2008 v1.0.1a
|
||||||
|
I decided that I'd go through the code and search for more cases that
|
||||||
|
if MOTD is *not* defined, to ignore any and all reconnect flags, whether or not
|
||||||
|
they're defined for external plugins (ie: axMail) or alias commands in the
|
||||||
|
/etc/ax25/node.conf file. If during configure you decided to add MOTD during
|
||||||
|
the option questions, then the node will infact act more like a user
|
||||||
|
application including allowing reconnects etc.
|
||||||
|
|
||||||
|
I had thought I fixed the man pages install, appearantly I never saved it.
|
||||||
|
This should now be fixed. My apologies.
|
||||||
|
|
||||||
|
* Author's Note: If you're linking the node to systems such as SNOS, or
|
||||||
|
you're on a very busy network, or if you forward with other BBS systems
|
||||||
|
who for whatever reason feel the need to connect to your node first
|
||||||
|
before connecting to the BBS (which I feel is unneccessary but happens), I
|
||||||
|
strongly suggest that you do NOT enable the MOTD which is the default option
|
||||||
|
now in the configure script.
|
||||||
|
|
||||||
|
*** Important: I just don't have the time to clean up all the gcc-3.x
|
||||||
|
compiler warnings however URONode compiles just fine under gcc-2.95
|
||||||
|
so I made a decision to force gcc-2.95 for compiling URONode under.
|
||||||
|
Configure was rewritten to check for this, and if it doesn't it will
|
||||||
|
instruct you on where you can get a copy. This will not interfere with
|
||||||
|
your installed copy of gcc-3.x if you so have it. I have verified that
|
||||||
|
URONode compiles quite cleanly under gcc-2.95 and I do have both
|
||||||
|
versions on my box:
|
||||||
|
root@schlitz:/usr/bin# ls -al gcc
|
||||||
|
lrwxrwxrwx 1 root root 7 Jun 25 00:00 gcc -> gcc-3.3
|
||||||
|
root@schlitz:/usr/bin# ls -al gcc-*
|
||||||
|
-rwxr-x--- 1 root root 69960 Mar 10 2004 gcc-2.95
|
||||||
|
-rwxr-x--- 1 root root 85196 May 24 2005 gcc-3.3
|
||||||
|
As you see above, gcc by itself is just a symlink to the latest
|
||||||
|
version of gcc-*. Ensure that gcc-2.95 is in your executable
|
||||||
|
path.
|
||||||
|
|
||||||
|
23-24/01/2008 v1.0.2
|
||||||
|
Huge news! I finally got off my duff and cleaned up compile warnings.
|
||||||
|
URONode will now compile fine on gcc-4.1 and under! This was just something
|
||||||
|
that was under my craw for a very long time, but not that critical enough
|
||||||
|
so you can really ignore the above notes in regards to GCC.
|
||||||
|
|
||||||
|
I ended up also making some modifications to the configure script, Makefile
|
||||||
|
and config.h. Part of cleaning up some of the compile errors was a dupe
|
||||||
|
conflict between library "log" routines and the internal node "log" routine.
|
||||||
|
URONode now has it's own node_log() routine as to keep it seperate from
|
||||||
|
library log routines. There's no change in it writing to syslog for you,
|
||||||
|
just the function was renamed to avoid compiler warnings. Many files were
|
||||||
|
updated due to this.
|
||||||
|
|
||||||
|
**Man file for uronode is now called "uronode", not "node". The binary made now
|
||||||
|
is also "uronode".** This is *very* important because when you run
|
||||||
|
"make install" or "make installbin", your inetd.conf/xinetd files will need
|
||||||
|
to be changed to spawn the new binary, and your config within
|
||||||
|
/etc/ax25/ax25d.conf will also need to be changed from calling "node" to
|
||||||
|
call "uronode" now!! If you do NOT do this, you will be stuck running either
|
||||||
|
an older compile or it won't launch at all. Please see the examples in the
|
||||||
|
INSTALL file for help on how to configure this properly. In the future
|
||||||
|
I may change the config files from node.* to uronode.* too. The advantage
|
||||||
|
of doing this would be tri fold:
|
||||||
|
1) it'd allow sysops to compare and test URONode side by side with another
|
||||||
|
package such as Tomi's LinuxNode
|
||||||
|
2) sysops could offer both flavors of a "node" to users if they so desired
|
||||||
|
to do such.
|
||||||
|
3) a sysop might prefer to have 2 compiles of URONode... one with full
|
||||||
|
MOTD compiled in, one without.
|
||||||
|
Those who know me, know I believe in allowing a sysop to have the freedom
|
||||||
|
to pick and choose just how they run their nodes... and this just adds
|
||||||
|
to their options. I do however discourage doing this unless it's for
|
||||||
|
testing reasons but c'est la vie.
|
||||||
|
|
||||||
|
**** Actually, I figured why wait to change files around, so I changed
|
||||||
|
all the config files from "node.*" to "uronode.*". Now if you're doing
|
||||||
|
an UPGRADE, you'll need to rename your config files in /etc/ax25/node.*
|
||||||
|
to /etc/ax25/uronode.* or else you'll have issues with some routines.
|
||||||
|
I also deleted the *.ex files and changed installconf so that the proper
|
||||||
|
files get copied into /etc/ax25 for new installs. I also changed all the
|
||||||
|
man page files that were node.* to uronode.*
|
||||||
|
|
||||||
|
As much as it sorta kinda but not really pained me to do this, I decided
|
||||||
|
that it may be cool to have *something* to let the user know that their
|
||||||
|
outbound ax25-type connect is via flexnet, so I added a routine in
|
||||||
|
gateway.c which checks the connect type and if the request is via FlexNet,
|
||||||
|
the user will see the standard "link setup..." message like they would on
|
||||||
|
a flexnet node, followed by "*** connected to <desti>". This MAY have an
|
||||||
|
adverse affect on FBB forwarding since FBB looks for "Connected..." instead
|
||||||
|
of "*** connected...", but there's ways around that in your FBB forward
|
||||||
|
file.
|
||||||
|
|
||||||
|
25/01/2008 v1.0.3
|
||||||
|
|
||||||
|
*Big News*
|
||||||
|
For Debian and (K)ubuntu users, I've decided to make a release of
|
||||||
|
uronode as a .deb package. This is my first time doing this and I'm really
|
||||||
|
not that comfortable with rolling it out officially since it's my first
|
||||||
|
pre-packaged binary so here's what I suggest you do if you decide to use it:
|
||||||
|
cd /etc and tar cvf ax25/* ax25files.tar
|
||||||
|
dpkg -i /path/to/uronode*.deb
|
||||||
|
tar xvf ax25files.tar
|
||||||
|
For now this will preserve your current config as the .deb package *will*
|
||||||
|
overwrite your current files in full including configs!
|
||||||
|
YOU HAVE BEEN WARNED!
|
||||||
|
|
||||||
|
Found a bug in the WHO command when MOTD was disabled. Currently if you
|
||||||
|
don't define that, then the WHO command is deactivated and not compiled
|
||||||
|
in. MH works fine and should be enough to be used to track recent connects
|
||||||
|
to your node.
|
||||||
|
|
||||||
|
Discovered a bug in the newly introduced FlexNet style cosmetics where
|
||||||
|
after "link setup..." if the connect request times out, error isn't printed
|
||||||
|
on a new line. I wrote a new string to push to the user so that if their
|
||||||
|
request does time out, it matches that of FlexNet's timeout string while
|
||||||
|
leaving vanilla ax25 and netrom timeout errors the same. Again, these
|
||||||
|
strings will inform end users the type of outgoing request was made
|
||||||
|
whether it was FlexNet or vanilla ax25.
|
||||||
|
|
||||||
|
While I was add it, I decided it would be helpful to end users who are
|
||||||
|
making FlexNet links to show which ax25 interface is being used for
|
||||||
|
connects similar to that of how Xnet shows connect requests. The interface
|
||||||
|
will be displayed in parentheses () such as: Link setup (ax0)...
|
||||||
|
so if the link fails, the user can see which interface to try a direct ax25
|
||||||
|
connect request out from.
|
||||||
|
|
||||||
|
I think I fixed a slight bug in flexd.c where if the LO.FPR and C.FPR
|
||||||
|
weren't formatted just right, it'd exit prematurely and issue a false
|
||||||
|
error. Apparantly the buffer was set a bit too high and captured too much
|
||||||
|
to parse, so I lowered "buffer" from 1024 to 512 and it now appears to be
|
||||||
|
fine.
|
||||||
|
|
||||||
|
A "bug" was reported about the config of the backend of URONode when infact
|
||||||
|
the bug was with ax25d.conf and nrports. Remember, when you configure your
|
||||||
|
node, ALL your SSIDs for ax25, netrom ports, and axports *MUST BE UNIQUE* if
|
||||||
|
you have RF links to native netrom nodes. Failure to do such will result in
|
||||||
|
some flooding issues because if an ssid in axports, ax25d.conf and nrports
|
||||||
|
is shared, an X1J node connecting into URONode will result in the ax25 link
|
||||||
|
layer being seen as a user and not a network socket. You'll ping-pong
|
||||||
|
the node with X1J in almost an endless loop. *You have been warned!*
|
||||||
|
|
||||||
|
22/02/2008 v1.0.4
|
||||||
|
|
||||||
|
I decided to make the node text more "technically correct" in it's display
|
||||||
|
of things... mainly in regards to "ports". We don't have "ports" per say
|
||||||
|
but we do have "interfaces". Needless to say, any reference to "port(s)"
|
||||||
|
has been changed to "interface(s)" including the former Ports command. This
|
||||||
|
has been replaced with the new INTerfaces command.
|
||||||
|
|
||||||
|
Users now will show the "interface" a user may be coming in on if it's ax25
|
||||||
|
or if inbound from FlexNet.
|
||||||
|
|
||||||
|
The PIng command has been shortened to Ping now with the refactor of the
|
||||||
|
"Ports" command. Ping now only requires "P" to ping another node.
|
||||||
|
|
||||||
|
*Note: this will be the last release for a while as I'm moving and won't
|
||||||
|
have a server or test bed to test with.
|
||||||
|
|
||||||
|
10/05/2008 v1.0.5r1
|
||||||
|
|
||||||
|
The move has completed and of course in my own sick and twisted mind, I have
|
||||||
|
decided to do a release that I call version 1.0.5 release candidate 1. This
|
||||||
|
is a minor release but it's something I despirately wanted to do for a while
|
||||||
|
and was just sitting like an itch under my skin to do, and sometimes you have
|
||||||
|
to just take a break from it <all> to clear the noggin and get the code the
|
||||||
|
way you want it. What was bothering me was the fact that not one flavor of
|
||||||
|
a linux-node complies with that of the Software 2000, inc specifications of
|
||||||
|
Net/Rom... and I desired to be the first to do such... yay me?
|
||||||
|
|
||||||
|
In any event I went through the code and made changes to the following files:
|
||||||
|
command.c, config.c, extcmd.c, gateway.c, node.c, node.h, and system.c.
|
||||||
|
What this does for you is makes your URONode behave more to the specifications
|
||||||
|
of Net/Rom regardless of how you define the MOTD flag. If you define the MOTD
|
||||||
|
flag, the node will continue to behave as it has <all> along, however it forces
|
||||||
|
it in "off" mode when the incoming connection is Net/Rom based. This is
|
||||||
|
extremely useful if a robot script (such as FBB forwarding) is used to
|
||||||
|
go through your node.
|
||||||
|
|
||||||
|
The decision of making this a release candidate was because I'm sure I may
|
||||||
|
have missed testing some of it's behavior and will have to do some cosmetic
|
||||||
|
and/or bug fixes.. so if you find any, please report them to me and I'll do
|
||||||
|
what I can to fix it.
|
||||||
|
|
||||||
|
Source, .deb, and .rpm packages are available at the typical location of
|
||||||
|
ftp://ftp.uroweb.net/pub/ax25/ ...enjoy for now!
|
||||||
|
|
||||||
|
12/05/2008 v1.0.5r2
|
||||||
|
|
||||||
|
I had this really irritating bug that appearantly I just never noticed
|
||||||
|
all this time when HAVEMOTD was undefined. Thanks to some assistance from
|
||||||
|
K2MF, I was able to identify and fix this bug. Inside the main loop statement
|
||||||
|
for the node, when a user disconnected, it was adding an extra frame to
|
||||||
|
the stream that contained only a line feed. Looking back at this, I did this
|
||||||
|
due to the fact that X1J handles it's output to the terminal differently than
|
||||||
|
does any other node that I'm aware of.
|
||||||
|
|
||||||
|
In any event, taking out this line feed somewhat caused other outputs of
|
||||||
|
text to lack a line feed when it needed it... so this meant changes in
|
||||||
|
command.c, extcmd.c, gateway.c, ipc.c, node.c, system.c, user.c and maybe
|
||||||
|
more that I can't quite recall as of this writing.
|
||||||
|
|
||||||
|
The good news is that I did fix 2 minor bugs that were under my skin!
|
||||||
|
One minor bug was that when a nodes or destis list ended with a row of
|
||||||
|
4, an extra line-feed was displayed. While this bug still exists under
|
||||||
|
certain conditions, it's no longer present during netrom connects.
|
||||||
|
|
||||||
|
Also during a netrom disconnect, an extra line-feed no longer sends to
|
||||||
|
the remote node thus making it more Software 2000, inc. compliant. I'll fix
|
||||||
|
the previous mentioned bug for release 1.0.6 sometime.
|
||||||
|
|
||||||
|
21/05/08 v1.0.5r3
|
||||||
|
|
||||||
|
Fixed some screen cosmetics that I introduced while making the node more
|
||||||
|
Software2000 compliant... I'm sure I missed a few more.
|
||||||
|
|
||||||
|
***Big News***
|
||||||
|
I've finally tracked down and fixed the remote escape bug (I think)!
|
||||||
|
What I saw was happening was that the SIGPIPE handler wasn't being
|
||||||
|
executed properly and it appeared to be waiting for more data which
|
||||||
|
it never received. I added a quit_handler routine in the main loop
|
||||||
|
which now will execute a node_logout(), flush out the IPCs,
|
||||||
|
log the event to syslog, and close out the application properly.
|
||||||
|
Due to this bug lingering in all flavors of *node for linux, and not
|
||||||
|
having the resources to fully stress-test this, I'm going to leave this
|
||||||
|
as release candidate 3 for now until (hopefully not!) someone reports
|
||||||
|
that this routine is causing ill-behavior.
|
||||||
|
|
||||||
|
26/05/08 v1.0.5r4
|
||||||
|
|
||||||
|
There was a LOT of cosmetic changes in this one which caused me to add
|
||||||
|
a LOT of conditional calls into the code, many of which I'm unsure whether
|
||||||
|
or not it'll fly properly under every condition so your milage will definately
|
||||||
|
vary depending on your specific setup! Since URONode has become very popular
|
||||||
|
within the EastNet packet system I decided to make the node appear for both
|
||||||
|
the ax25/FlexNet side or its NetRom side, dependant on how the user logs into
|
||||||
|
the node. Because of the massive changes in structures, rather than listing
|
||||||
|
them <all>, the above description should do.
|
||||||
|
**Note: you MUST add a new line in uronode.conf that defines
|
||||||
|
FlexId XX#XX-##
|
||||||
|
Either take yourcall-ssid from ax25d.conf OR if you're linked to a
|
||||||
|
node that does flexnet, use yourcall-ssid as it is on the remote flexnet
|
||||||
|
system. If you don't, and a user connects in via telnet or ax25/flex you'll
|
||||||
|
display (null) to them. Also: if you added a } after your NodeId
|
||||||
|
callsign-ssid, remove it. It's been hardcoded into URONode now.
|
||||||
|
|
||||||
|
I decided to mute the banner section of the login sequence however
|
||||||
|
it will still display your MOTD if it's defined during ./configure.
|
||||||
|
If there's a demand for it, I may add it as a configurable option.
|
||||||
|
|
||||||
|
Even though I put r4 out for download, I did find a couple minor bugs
|
||||||
|
which have since been fixed.
|
||||||
|
|
||||||
|
29/05/08 v1.0.5r5
|
||||||
|
|
||||||
|
In a nutshell, if the user connects to your URONode via NetRom, then
|
||||||
|
they will get standard NetRom prompts with "ALIAS:CALL-#} " as a result
|
||||||
|
header to all of your commands with the exception of FlexNet gateway
|
||||||
|
connects.
|
||||||
|
|
||||||
|
Now in uronode.conf, a *new* line _must_ be added for FlexId. The parameter
|
||||||
|
is:
|
||||||
|
FlexId <call-flexssid>
|
||||||
|
An example since my URONode is on FlexNet as ssid 3:
|
||||||
|
FlexId N1URO-3
|
||||||
|
|
||||||
|
Also note that the need to have a closed bracket "}" after your NodeId
|
||||||
|
now is not required and should be deleted. I finally got off my butt and
|
||||||
|
hard-coded it into the software.
|
||||||
|
|
||||||
|
The Version routine was also changed depending on how the user is connected
|
||||||
|
in. If the incoming connect is made using NetRom, then the standard prompt
|
||||||
|
is displayed. If the incoming connect is via any other type of link, then
|
||||||
|
a columnized display is made showing Software version, NodeId, and FlexId
|
||||||
|
in hopes of eliminating confusion to the end user.
|
||||||
|
|
||||||
|
While in the midst of all the above, I did find some cosmetics to fix.
|
||||||
|
|
||||||
|
Before I make this release candidate an official, I'm curious as to
|
||||||
|
whether or not anyone would object to me eliminating some of the
|
||||||
|
standards of the login banner of the node (non-NetRom displayed).
|
||||||
|
Please let me know and I'll make the necessary changes if need be.
|
||||||
|
-- actually I already decided to do this.
|
||||||
|
|
||||||
|
I added a new routine in util.c which now will give the end user
|
||||||
|
the type of prompt based upon the type of connection. The default
|
||||||
|
for ax25/FlexNet is: "=> " (note the space after > unlike Flex)
|
||||||
|
for NetRom is: "ALIAS:CALL-ID} "
|
||||||
|
for tcp/ip is: "usercall@hostname:/uronode$ "
|
||||||
|
|
||||||
|
With the new routine, I changed the main loop in node.c from defaulting to
|
||||||
|
Prompt simply to using node_prompt().
|
||||||
|
|
||||||
|
01/06/08 v 1.0.5
|
||||||
|
URONode version 1.0.5 is now considered to be "final". With the new month
|
||||||
|
is a new final release, and in this release it has more face-lifts than
|
||||||
|
Joan Rivers hihi!
|
||||||
|
|
||||||
|
I added a new routine in the configure script which will prompt you for
|
||||||
|
telnet colored routines... yes we have ANSI! Now, a couple things about
|
||||||
|
pushing ANSI code:
|
||||||
|
1 - consider network bandwidth if you have IP users via RF
|
||||||
|
2 - many windows apps such as WinPack do NOT support ansi. This is NOT
|
||||||
|
a fault of URONode, but that of the Windows application. If you
|
||||||
|
find you have trouble decoding ansi, try PuTTY or use HyperTerminal
|
||||||
|
in telnet mode. Ansi is hard disabled for ax25/Flex and NetRom connects.
|
||||||
|
I also added ansi codes for "Nodes" and for "Desti" lists commands if the
|
||||||
|
inbound connect is made via IP.
|
||||||
|
|
||||||
|
Added an "EXit" command for users in IP mode since you now feel like you're
|
||||||
|
in a bash shell... just a 'force of habit' thing. Bye still works.
|
||||||
|
|
||||||
|
Fixed a bug introduced with the new node_prompt changes to node.c. If
|
||||||
|
the user was required to enter a password outside of being on the localhost
|
||||||
|
or amprnet, the prompt displayed twice... this is now fixed. I also found
|
||||||
|
and fixed soem more cosmetics that I considered to be wrong. This bug was
|
||||||
|
driving me insane as to why it was doing this, but I finally tracked it
|
||||||
|
down.
|
||||||
|
|
||||||
|
Found and fixed another bug where if the user's permissions were set
|
||||||
|
to a perm "escape off", prompts didn't properly function.
|
||||||
|
|
||||||
|
Made a change to nodeusers where now if no one is on the node, it'll
|
||||||
|
say such instead of simply being blank.
|
||||||
|
|
||||||
|
A note about ansi:
|
||||||
|
linux shells will decode ansi pretty good as will old DOS based terminal
|
||||||
|
programs such as Qmodem, Telix, etc. If you use a raw terminal such as
|
||||||
|
xNOS, you'll need to insure you load ANSI.SYS in your C:\CONFIG.SYS file
|
||||||
|
and reboot so the terminal will decode ansi.
|
||||||
|
Windows telnet *will* decode ansi as well however since XP, local echoing
|
||||||
|
by default is set to OFF. You can CTRL-] and type: set localecho, then hit
|
||||||
|
enter twice and you can get echoing back on.
|
||||||
|
If you use something such as WinPack which doesn't decode ANSI, please do
|
||||||
|
NOT contact me! Contact the authors of WinPack and report the lack of
|
||||||
|
ansi as a bug.
|
||||||
|
|
||||||
|
I also am including a copy of axdigi from the original FlexNode package.
|
||||||
|
This is compiled as a static binary and a copy of axdigi.conf IS
|
||||||
|
also included in the source package, but I won't package it with the .deb
|
||||||
|
or .rpm packages... however I do reserve the right to change my mind :)
|
||||||
|
|
||||||
|
Static binary packages are compiled with the following options OFF:
|
||||||
|
Rose support
|
||||||
|
All other options are compiled in.
|
||||||
|
|
||||||
|
04/07/2008 v1.0.6
|
||||||
|
Found and fixed a bug in the Who routine where a netrom prompt was merging
|
||||||
|
with the last entry of a list even if the connect was not netrom. This change
|
||||||
|
was made in system.c.
|
||||||
|
|
||||||
|
Added some more ansi routines if #defined COLOR. Here's the schema:
|
||||||
|
Connects display in green as in "gateway go"
|
||||||
|
Reconnects display in red as in "gateway stop"
|
||||||
|
Commands display in bright white
|
||||||
|
Netrom Nodes (full list) in bold cyan
|
||||||
|
FlexNet destis (full list) in yellow
|
||||||
|
Current users in magenta
|
||||||
|
Aborts and timeouts blink bright red
|
||||||
|
Logouts in low cyan
|
||||||
|
I'm making the color schema a bit more consistant through out the application.
|
||||||
|
While doing such, I'm cleaning things up so that just the headers are in
|
||||||
|
color, not the actual results so that if one is NOT decoding in ansi (and
|
||||||
|
again if not that's a fault of the client NOT of the node) the node won't
|
||||||
|
appear as offensive.
|
||||||
|
|
||||||
|
Found a bug in the auto router where it wasn't parsing the digi path
|
||||||
|
from the mheard table, HUGE credit goes to Barry K2MF (of MFNOS fame) for
|
||||||
|
supplying the code that properly handles this. Fixed.
|
||||||
|
|
||||||
|
Did a lot of clean-up for how the node/shell responds dependant on how the
|
||||||
|
user connects in. Many changes done in gateway.c, extcmd.c and node.c.
|
||||||
|
|
||||||
|
Now made ANSI a flag in uronode.perm... I may change this later however
|
||||||
|
because of such, it forced me to have to make a new nuser_list routine
|
||||||
|
in command.c as well as move node_prompt from util.c elsewhere so
|
||||||
|
command.c seemed like the best choice. Setting the user bit +512 will
|
||||||
|
now grant them telnet ANSI color. Not giving them this will turn
|
||||||
|
it off. I'd like to make it an end-user toggle so that depending on
|
||||||
|
which client the user is coming in with they can choose online to get
|
||||||
|
color or not. The user perm flag replaces defining Color during the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
Defining MOTD now serves multiple functions:
|
||||||
|
1) Display of the MOTD screen/file
|
||||||
|
2) Display of prompts for all interfaces
|
||||||
|
3) Reconnect back to the node upon a gateway link out
|
||||||
|
I suggest compiling with MOTD on, which configured by default in the
|
||||||
|
.deb and .rpm packages.
|
||||||
|
|
||||||
|
Changed some of the technical correctness of the node in regards to IP
|
||||||
|
functions. Ping now returns ICMP Echo request/reply messages and IP based
|
||||||
|
connects out now show the service/port that the connection request is being
|
||||||
|
opened to.
|
||||||
|
|
||||||
|
Added color schemas to the NetRom and ax25/Flex interfaces if the user
|
||||||
|
requests it to be on. The same color schema is used on all 3 interfaces.
|
||||||
|
|
||||||
|
Fixed a very irritating bug that some folks have reported on which
|
||||||
|
when do_ports() was called, and the axport description was over 42
|
||||||
|
characters in length, do_ports() was *not* properly truncating the
|
||||||
|
additional characters, and making things looks a bit sloppy. A similar
|
||||||
|
bug exists in LinuxNode =< 0.3.2. Note: In your axports file, you *MUST*
|
||||||
|
have a tab after the window digit before writing your interface
|
||||||
|
description or else the parser will consider the spaces as just that...
|
||||||
|
empty spaces! You have been WARNED!
|
||||||
|
|
||||||
|
Updated uronode.conf and uronode.perms files to show examples of recently
|
||||||
|
added features.
|
||||||
|
|
||||||
|
Long overdue: Updated the MAN pages!! I'm so sorry for letting these slide!
|
||||||
|
It really is hard enough trying to keep track of things in this file, never
|
||||||
|
mind actually documenting it in a manual page or two hihi!
|
||||||
|
|
||||||
|
Found and fixed a bug in the logout routine where a false error was being
|
||||||
|
reported that the shared memory segment (IPC) couldn't close. Somehow this
|
||||||
|
was introduced by me duping the lines in the routines so that it was actually
|
||||||
|
trying to close the shared memory segment twice! I guess in reality, the
|
||||||
|
log error was indeed correct since there was no second segment to close hi!
|
||||||
|
|
||||||
|
Added a "make update" option to the Makefile. This option *must* be used
|
||||||
|
in version release sequential order or else it may fail!
|
||||||
|
|
||||||
|
Fixed a cosmetic bug in the way NetRom nodes introduced by me when I created
|
||||||
|
multiple interfaces. The word "NetRom" appeared twice in the header when
|
||||||
|
a user would request a Nodes list.
|
||||||
|
|
||||||
|
15/11/2008 v1.0.7
|
||||||
|
|
||||||
|
Made some cosmetic changes to text and ansi color displays, still a few
|
||||||
|
more to do but not critical so it gives me an excuse to do a maintenance
|
||||||
|
release one of these days hihi!
|
||||||
|
|
||||||
|
With the assistance of the great and mighty <all>, the <all> of c coding
|
||||||
|
knowledge, I was able to incorporate a loop detection system when making
|
||||||
|
FlexNet or ax25 connects... now if there's a loop in the outbound connect
|
||||||
|
request, the user will be informed of such which includes a system bell
|
||||||
|
(beep). I thought about adding a loop connect block such as with FlexNet
|
||||||
|
however in the case of axip/axudp links many links may share the same
|
||||||
|
interface which really would be unfair to the user trying to gateway out
|
||||||
|
that's also coming in from the same axip interface.
|
||||||
|
|
||||||
|
Now for the big news of this release: By request of Bob Anderson K2BJG,
|
||||||
|
I wrote a kluge for flexd.c which now requires 2 additional fields in
|
||||||
|
/etc/ax25/flexd.conf - MyGate and MyRange. Inside flexd.conf, MyGate
|
||||||
|
is your neighbor FlexNet gateway without ssid, and MyRange would be
|
||||||
|
the full ssid range of the FlexNet gateway you poll. This will add your
|
||||||
|
FlexNet gateway into your local desti table complete with SSID range and
|
||||||
|
give it a ttl of 0 since there's no true ttl polling going on... but there
|
||||||
|
is a catch to this: you MUST add each ssid of the remote FlexNet system
|
||||||
|
into uronode.routes as a direct link or else connect requests will fail
|
||||||
|
because the connect will try to digi off of the remote FlexNet system
|
||||||
|
to itself. I don't know if I agree with this yet or not as a local
|
||||||
|
FlexNet system never shows itself in it's desti table, and that's what
|
||||||
|
K2BJG has asked me to do with URONode. As I said, for now this is all
|
||||||
|
a kluge but it does appear to work if instructions are followed
|
||||||
|
verbatim.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
MyGate N1URO
|
||||||
|
MyRange 1-11
|
||||||
|
|
||||||
|
Made a change in the Makefile so that the axdigi module does NOT copy over
|
||||||
|
by default. Now you MUST do this manually and add it to your scripts. Not
|
||||||
|
everyone would wish to use this so why force more junk in a directory? :)
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
See CHANGES.2 for more notes in regards to changes.
|
|
@ -0,0 +1,637 @@
|
||||||
|
|
||||||
|
28/11/2008 v1.0.8
|
||||||
|
*notes lost, sorry.
|
||||||
|
|
||||||
|
27/05/2009 v1.0.9
|
||||||
|
**production copy stolen. See LICENSE for who did this and my response.
|
||||||
|
|
||||||
|
11/05/2013 v2.0
|
||||||
|
Clean up of some code... I had a copy of 1.0.8 from 2008 I recovered. I
|
||||||
|
did
|
||||||
|
have a version 1.0.9 in production but can't seem to locate it for some
|
||||||
|
reason so starting from memory using 1.0.8. Thanks to Brett WA7V for
|
||||||
|
supplying me with some teaser code :-)
|
||||||
|
|
||||||
|
Updated version! We're on 2.0... finally! (yea, big news right? Maybe
|
||||||
|
not!)
|
||||||
|
|
||||||
|
Moved the "Who" commmand to the list of basic internal node commands.
|
||||||
|
I can't recall why on earth I had it defined with MOTD. Perhaps it may
|
||||||
|
come to me later but for now I can't recall. I may have to move it
|
||||||
|
somewhere else, but I believe it has to do something with logging
|
||||||
|
features or something along those lines. For now, you need to define
|
||||||
|
MOTD as a compile selective to have the <Who (call)> defined.
|
||||||
|
|
||||||
|
Fixed the sysop shell warning, this needed to be a tad more specific
|
||||||
|
in my point of view... then again who am I? Also cleaned up the return
|
||||||
|
prompt as it could be confusing if the incoming connection was done via
|
||||||
|
NetRom. I removed the default FlexNet Identifier out. Now it just says:
|
||||||
|
"Welcome back.".
|
||||||
|
|
||||||
|
In regards to the "Who" command; I see what was going on here and where
|
||||||
|
I left off with it! Logging and the "Who" command pretty much go hand in
|
||||||
|
hand - so they're combined. The initial design of FlexNode was to have a
|
||||||
|
MOTD based off of the logging of when the user last was on, otherwise if
|
||||||
|
they did not exist, push the "new user" screen to them. The down and
|
||||||
|
dirty quick fix is to simply remove it from netrom connections into the
|
||||||
|
system! Who cares if you get a MOTD on a flex/ax25 or a telnet connect
|
||||||
|
into the system!
|
||||||
|
|
||||||
|
With the above said, I changed the sequence of "configure" to ask if the
|
||||||
|
sysop/admin wishes to log user connects into the system. In the future I
|
||||||
|
will either move this to be included with protocols or I may simply hard
|
||||||
|
code it in as a defaulted option, and move the "Who" command as being
|
||||||
|
defined into TCP/IP functions. For now, it's hard coded in as a selected
|
||||||
|
option but will NOT display for NetRom connects.
|
||||||
|
|
||||||
|
While I was at it, I changed some of the routines in the configure script.
|
||||||
|
Nothing major but did improve upon a few things. While doing this, and
|
||||||
|
running "make upgrade" I noticed that flexd.conf was being overwritten!
|
||||||
|
OUCH! I'm surprised this went on for as long as it did. I *think* I did
|
||||||
|
this to force people to add the new lines in flexd.conf that K2BJG/SK had
|
||||||
|
asked me to do.
|
||||||
|
|
||||||
|
Created a man page for flexd.conf(5)! I'm surprised no one asked me why this
|
||||||
|
was missing! It explains further how to create the file. Keep in mind, this
|
||||||
|
also works on Xnet as well as Flexnet. If this doesn't help you figure out
|
||||||
|
how to create this file or edit the sample one... I don't honestly know what
|
||||||
|
to tell you. In doing such, it also forced me to change the generated
|
||||||
|
Makefile so that "install upgrade" and "install man" installs it.
|
||||||
|
|
||||||
|
Changed the licensing! This is (I'll admit) very personal and _must_
|
||||||
|
remain as is! I could fill a TB hard disk with reasons and debates
|
||||||
|
as to why it's no longer GPL code. Please insure you are in an area
|
||||||
|
where you can use this code. Thank you.
|
||||||
|
|
||||||
|
Fixed an ANSI bug I had in the "Users" command which was driving me nuts!
|
||||||
|
On NetRom, it would change the prompt to magenta which it shouldn't. What
|
||||||
|
I did as a fix was to force a removal of ANSI on the prompt for NetRom
|
||||||
|
based connects... simple enough. There may be other ANSIs for me to fix
|
||||||
|
and I'll cross those bridges when I get to them. Found another in gateway.c
|
||||||
|
and fixed the netrom ANSI to properly reflect that once a connection was
|
||||||
|
made, it was "systems GO" (green) without changing the Node's ID string.
|
||||||
|
|
||||||
|
Created a COLORS file which somewhat explains the hows/whys of not only
|
||||||
|
how I came up with a schema, but when it should and should NOT be used.
|
||||||
|
It may also be used as a quick reference guide for the local sysop. It's
|
||||||
|
a nice little cheat sheet one may print and keep near their keyboard if
|
||||||
|
they want.
|
||||||
|
|
||||||
|
Added text to both the colors.hlp and help.hlp file for a users better
|
||||||
|
understanding of the color schema and how to gain colors to their terminal
|
||||||
|
if they so choose to have it. See my wishlist below for more information on
|
||||||
|
where I wish to go with this.
|
||||||
|
|
||||||
|
Added an item to the Wish List located further below in this file. With so
|
||||||
|
many spend-thrifty hams, do I really need to go through the code and match
|
||||||
|
it with the most up-to-date version(s) of GCC for compiling? I originally
|
||||||
|
developed the code using GCC version 2.95, now I'm compiling it on version
|
||||||
|
4.2.4 and it's not showing any errors during compile. If you have a specific
|
||||||
|
version of GCC you're using, please submit that and proper hardware for me
|
||||||
|
to run it on and I'll be more than happy to march forward :-)
|
||||||
|
|
||||||
|
Changed the inactivity timeout message so that it does NOT show
|
||||||
|
the FlexNet node call and gives a more specific message as to why the user
|
||||||
|
was disconnected. This was a call I originally edited and have now cleaned
|
||||||
|
up in node.c. There may be more of such messages. I can only test so much
|
||||||
|
and for so long :)
|
||||||
|
|
||||||
|
Made some more ANSI cleanups - in regards to Status and Users commands. I
|
||||||
|
had them as magenta and they should only be bright white as they don't
|
||||||
|
fit into any real category except for local system informations. For these
|
||||||
|
I had to make routine changes as well as ANSI changes in user.c and in
|
||||||
|
command.c. Also fixed the ANSI for version in NetRom. It currently had none.
|
||||||
|
This was done in command.c. Also cleaned up Links and Routes ANSI in command.c
|
||||||
|
and other places where needed. Originally I had the Routes as yellow which
|
||||||
|
even though it points the ax25-interface that NetRom is encapsulated under,
|
||||||
|
it's really more for NetRom "route"-ing... so changed it to cyan to keep with
|
||||||
|
the schema.
|
||||||
|
|
||||||
|
Found a disaster in ANSI routines for the Links command and the variant
|
||||||
|
switches along with it! The ANSI ran to the table which I did not want
|
||||||
|
to have happen and I believe I was very diligent in cleaning this up
|
||||||
|
in ver 1.0.8 or 1.0.9. In any event, I recall doing this and now I have
|
||||||
|
repeated my work... thus taken time away from more important tasks
|
||||||
|
*sigh*.
|
||||||
|
|
||||||
|
These were worked in router.c. I also cleaned up other places where ANSI
|
||||||
|
ran over other strings that it shouldn't, and where it may have engaged
|
||||||
|
prior to where it should. Such instances are when it would highlight over
|
||||||
|
the Node-ID string (ex: MYNODE:mycall-5}). This really made my skin crawl
|
||||||
|
and I *know* I fixed this before... who knows perhaps I made a cleaner
|
||||||
|
routine than I had.
|
||||||
|
|
||||||
|
I recall doing a LOT of code clean-up, and it appears I need to revisit this
|
||||||
|
again. When I'm done, hopefully I can get rid of a few hundred lines of code
|
||||||
|
that's simply commented out for testing purposes only. The sizes of your
|
||||||
|
binaries should not be affected by this and I believe I've been diligent
|
||||||
|
to clean up the configure script to somewhat automate this process for you.
|
||||||
|
This task will be excessively time consuming! If anything it'd be an excuse
|
||||||
|
for a maintenance release!
|
||||||
|
|
||||||
|
Fixed a minor routine in ipc.c in regards to the Msg command. I deliberately
|
||||||
|
did NOT add ANSI to this because in a way the Msg command I feel is a tad
|
||||||
|
intrusive such as with an instant message, however I did clean up how an
|
||||||
|
incoming message was handled to the recipient. It now (in my opinion)
|
||||||
|
shows a cleaner screen.
|
||||||
|
|
||||||
|
I found Craig Small's old axdigi code and made an elf compile. In layman's
|
||||||
|
terms, it's a static binary and should run as-is for you. This binary
|
||||||
|
claims to be fully automagic in regards to crossport digipeating unless you
|
||||||
|
make changes to your interfaces in which you should restart it. This binary
|
||||||
|
also should NOT require /etc/ax25/axdigi.conf anymore. I have the other
|
||||||
|
binary so if you think you need it, let me know.
|
||||||
|
|
||||||
|
Added an install for axdigi in Makefile.in under "install bin". Previously
|
||||||
|
this file was not included, now it is. I may write a shell script to launch
|
||||||
|
the daemons for you... keep an eye on this file for further info!
|
||||||
|
|
||||||
|
26/05/2013 v2.1
|
||||||
|
|
||||||
|
Fixed a bug in gateway.c where the finger "stop" ansi was white instead
|
||||||
|
of red (for stop). This was one I missed not having proper routing yet
|
||||||
|
to fully test. Thanks Brett WA7V for the link!!
|
||||||
|
|
||||||
|
Made another change in gateway.c in regards to the handling of the
|
||||||
|
flexnet destinations listing when using Flex/AX25 ONLY. There is a
|
||||||
|
reason for this (believe it or not) and that's in the shell and netrom
|
||||||
|
interfaces they both begin the destinations list with the string
|
||||||
|
"Flexnet Destinations:". This may cause neighbor URONode/AWZNode/etc
|
||||||
|
systems using flexd to improperly parse flexnet destinations from each
|
||||||
|
other. At the moment, I don't have the facilities to properly test this
|
||||||
|
but am hoping to work something out.
|
||||||
|
|
||||||
|
Thanks to Bob K2JJT, I added an include for socket.h in ipc.c. While I
|
||||||
|
never saw any errors here, I don't believe I've ever tested or compiled
|
||||||
|
on a Slackware system... Bob uses Slack. K2JJT reported adding this to
|
||||||
|
ipc.c helped him fix issues with his compile as it was griping about
|
||||||
|
AF_NETROM. Adding it here made no difference so since it helps Slackware
|
||||||
|
I'm all for being multi-distro compatable as much as humanly possible.
|
||||||
|
|
||||||
|
In reviewing 2.0 changes, it had me look more into the shell function
|
||||||
|
for sysops. I made a change that more defines which shell you may be
|
||||||
|
in when you do a 'w' or a 'who' in a linux shell via the node. This
|
||||||
|
was changed in system.c
|
||||||
|
|
||||||
|
Made a patch to node.c where if called from a shell, it would coredump.
|
||||||
|
Now, if it's called from a shell it simply exits back to the shell
|
||||||
|
prompt. I believe the same is in other "node" variants to which
|
||||||
|
the documentation directs the local sysop not to call the node from
|
||||||
|
a prompt, however KI6ZHD felt this was an issue. Being harmless in
|
||||||
|
nature to the function of my design I felt it wasn't harmful to add
|
||||||
|
it in. This patch was provided by David Ranch KI6ZHD. Thanks to him
|
||||||
|
for providing this, and eliminating any accidental core files on your
|
||||||
|
hard drives, and to Steven, K6SPI for coding the patch.
|
||||||
|
|
||||||
|
Thanks to David KI6ZHD for motivating me to do something I wanted to do
|
||||||
|
but put it way on the back burner, and to Barry K2MF for his elite C
|
||||||
|
skills. MHeard now will only print up to the 20 most recent heards. With
|
||||||
|
the initial routine, it would just dump either the global list heard
|
||||||
|
or if the user selected a specific interface the entire list for that
|
||||||
|
interface. At first, it worked fine for telnet and/or ax25/flex
|
||||||
|
connections but in NetRom it was double spacing. This was fixed by me. I
|
||||||
|
chose 20 to leave room for system headers and prompt returns. In a
|
||||||
|
standard 80x25 terminal screen, with a full listing, this should fill
|
||||||
|
the entire screen without a need for the end user to scroll up and
|
||||||
|
should help keep some traffic down on a busy network.
|
||||||
|
|
||||||
|
Made a change in gateway.c to eliminate the "trying state" message only
|
||||||
|
in NetRom when trying to connect to a remote NetRom node. This should
|
||||||
|
keep the node more in compliance with Software2000 specifications.
|
||||||
|
|
||||||
|
There was chatter within the BPQ32 user group on Yahoo that URONode was
|
||||||
|
not releasing any keep-alive timers. Please, this is NOT the duty of
|
||||||
|
a node Front End to control what the native protocol stack is designed
|
||||||
|
to do. This is totally sysop configurable. To flag this I strongly
|
||||||
|
suggest the following be added to your scripts:
|
||||||
|
echo "600000" > /proc/sys/net/ax25/ax0/idle_timeout
|
||||||
|
echo "600000" > /proc/sys/net/ax25/ax1/idle_timeout
|
||||||
|
echo "600000" > /proc/sys/net/ax25/ax2/idle_timeout
|
||||||
|
and so on... one line for each ax25 interface. This will break the
|
||||||
|
keep-alive virtual circuit Netrom AND IP will use for transport, and
|
||||||
|
thus break your IP as well. If you're running IP through an ax25
|
||||||
|
interface I suggest you leave this defaulted to 0 (disabled).
|
||||||
|
|
||||||
|
Rewrote the auto-find routine in gateway.c in do_connect so that first
|
||||||
|
order of preference for connects searches the destis table from flexd
|
||||||
|
BEFORE checking the netrom nodes and mheard tables, THEN it will search
|
||||||
|
for the destination in the netrom nodes if not found in the destis
|
||||||
|
table and prior to searching the mheard list. If you don't use flexnet,
|
||||||
|
then this shouldn't be an issue for you. As of this time, I'm unsure
|
||||||
|
if this would create any bugs if you don't define FlexNet during
|
||||||
|
the configure procedure. If it does, please file a report on the
|
||||||
|
online forum at https://www.n1uro.net/forum for me!
|
||||||
|
|
||||||
|
Made some changes in util.c and gateway.c in regards to duplicate ax25
|
||||||
|
route connection attempts. If you attempt to connect twice through the
|
||||||
|
same path, same call, etc, to clarify the error handling. This was
|
||||||
|
something I worked with K2MF on in regards to MFNOS. This does not mean
|
||||||
|
you can't make a connect on the same interface you came in on, you will
|
||||||
|
get a loop warning but the connect will attempt. If you connect from
|
||||||
|
the node, and try to connect to <callsign>, loop back into the node,
|
||||||
|
and try to connect to the same <callsign> again, you will NOT be allowed
|
||||||
|
to connect. URONode will tell you that a duplicate connection is not
|
||||||
|
allowed.
|
||||||
|
|
||||||
|
Cleaned up the do_routes routine in command.c. Shortened "Quality" to
|
||||||
|
"Qual" and renamed "Destinations" to "Nodes". After all, netrom doesn't
|
||||||
|
really use "Destinations", that's more a flexnet thing. Still more
|
||||||
|
cleanup to do in there *sigh*.
|
||||||
|
|
||||||
|
While I was at the do_routes, I noticed missing ansi in do_routes and
|
||||||
|
do_nodes. This has been fixed (and was previously in 1.0.10). I also
|
||||||
|
cleaned up the ansi routine in do_destinations in router.c to match
|
||||||
|
that of the netrom counterpart routines in command.c. Again, this was
|
||||||
|
done in 1.0.10 *double sigh*.
|
||||||
|
|
||||||
|
Rather than include an i686 elf of Craig Small's axdigi cross-port
|
||||||
|
digipeater which probably would NOT work on a Raspberry PI, I added
|
||||||
|
it into the Makefile by default. I also added an additional routine
|
||||||
|
in the configure script to check to insure that this file is made.
|
||||||
|
|
||||||
|
I also had to update axdigi.c so that it wouldn't error on the newer
|
||||||
|
(as if I run newer ha!) gcc. This was done for strcpy so that it
|
||||||
|
wouldn't produce errors as it does. I suspect in the "OLD" days of
|
||||||
|
linux/gcc it may have been OK as I consider Craig to be one of the
|
||||||
|
"village elders" of the packet system on linux.
|
||||||
|
|
||||||
|
Added a man page for axdigi. READ THIS VERY CAREFULLY!! To digi through
|
||||||
|
linux you *must* know some specific information and you might have to
|
||||||
|
educate your users on how exactly to cross-port digi through you if
|
||||||
|
they intend to do such. It's not something normally visible to them!
|
||||||
|
I may add a node-help file on digi...but for now please study the man
|
||||||
|
page on how. It works and works very slick as I've been testing it for
|
||||||
|
a couple of months. Mheard also will learn digi paths and use them to
|
||||||
|
connect to digipeated nodes if need be.
|
||||||
|
|
||||||
|
Cleaned up do_nodes in command.c. Shortened Quality to Qual, and the
|
||||||
|
equivilant of Obs. This will use less chars per line when doing a
|
||||||
|
node <node> or node * . I've been wanting to do this but saved
|
||||||
|
it for one of those rainy day things. Guess today was that rainy day?
|
||||||
|
|
||||||
|
Cleaned up more code and hope to have it finished before 2.1's final
|
||||||
|
release. So far I'm doing flexd.c at this point. FYI; code cleanup will
|
||||||
|
be a 2-fold process. First; I'll be formatting each file so it's at a
|
||||||
|
level of consistency. Second, things I have commented out for testing
|
||||||
|
that aren't needed may be permanently removed. I may leave a few things
|
||||||
|
in in case someone desires to say add a 'Welcome." message to netrom
|
||||||
|
(which is NOT Software2000 compliant!).
|
||||||
|
|
||||||
|
Speaking of which, I see I introduced a bug when ANSI is defined for
|
||||||
|
a specific user which violates Software2000 specs. I believe I did this
|
||||||
|
as a fail-safe in the prompt routine however now I see it's not needed
|
||||||
|
with all the other ANSI cleanups I've done. This change (deletion)
|
||||||
|
was done in node.c where I forced a shutoff of ANSI upon NetRom connects
|
||||||
|
only, as NetRom does not display the MOTD.
|
||||||
|
|
||||||
|
I rewrote a bit of the reconnect string. The "reconnect" in uronode.conf
|
||||||
|
should be set to OFF. All connections with the exception of NetRom WILL
|
||||||
|
reconnect. NetRom defaults to off, however with the {S|D} flags you may
|
||||||
|
manually request you stay connected. Eventually I will remove this flag
|
||||||
|
in the file so it will become moot. Please change it now to OFF! This
|
||||||
|
was done in gateway.c. Previously, these flags were moot in NetRom
|
||||||
|
connects. With the default to OFF, this keeps the NetRom in URONode
|
||||||
|
Software2000 compliant. A NetRom disconnect should *never* send any
|
||||||
|
text back whether it's a user or robot/script. Now a user can request
|
||||||
|
staying connected to URONode from a incoming NetRom connection. For
|
||||||
|
clarity sake, this only affects the user IF they connect INTO URONode
|
||||||
|
via NetRom. The "S" flag works for ax25/Flex/NetRom outbound connects.
|
||||||
|
A user connecting INTO URONode via ax25/Flex/IP will still automatically
|
||||||
|
be reconnected after an outbound connect.
|
||||||
|
|
||||||
|
N1UAN reports make install fails to install the config files. He's
|
||||||
|
correct. Changed Makefile.in so that "make install" also includes
|
||||||
|
make installconf which run by itself will install just the config
|
||||||
|
files for /etc/ax25.
|
||||||
|
|
||||||
|
I'm also working on changing the configure script to have some
|
||||||
|
"eye candy". This will be a continuing work in progress. You'll see it
|
||||||
|
as it comes. You will need the package "whiptail" in order to see this
|
||||||
|
new configuration routine. I don't know if this is standard amongst
|
||||||
|
ALL distributions, however I do know it comes default in debian and
|
||||||
|
debian based systems. If this *is* too much of an issue, I'll revert
|
||||||
|
back to the old method.
|
||||||
|
|
||||||
|
Almost forgot about an ANSI bug in extcmd.c where if you created an
|
||||||
|
external command in the node and the user was in via NetRom, when the
|
||||||
|
node issued "Welcome back." the ansi did NOT clear the color. I found
|
||||||
|
this in ver 2.0 and thought I fixed it, apparently not (age catching
|
||||||
|
up to me?) In any event, this is now fixed and working properly again.
|
||||||
|
Since most people don't use the +512 Color flags I'm sure it was missed.
|
||||||
|
|
||||||
|
Found a non-critical bug in cmdparse.s in regards to running external
|
||||||
|
commands - where it would automatically input a line feed before it
|
||||||
|
executed the command. This was the only routine which did this. A
|
||||||
|
routine like this really got under my skin and I was determined to find
|
||||||
|
and fix this finally... this was a routine I never changed, and that
|
||||||
|
was halted today (28 July 2013). Instead of totally removing this line
|
||||||
|
of code, I changed it to now display "Executing command... " and where
|
||||||
|
ANSI is defined, it is, naturally, green.
|
||||||
|
|
||||||
|
Found a non-critical bug in the Info command where it would show as
|
||||||
|
the first string to the user: "Help command for help" then it would push
|
||||||
|
the uronode.info file. This is very wrong. While the Info command does
|
||||||
|
use the routine of do_help in command.c, Info is an independent internal
|
||||||
|
command and this should not have occurred. This is now fixed with ANSI
|
||||||
|
if permissions display ANSI.
|
||||||
|
|
||||||
|
Updated the outdated INSTALL text document. It had some now misleading
|
||||||
|
pieces of information in it as some paths and make options have been
|
||||||
|
changed. Since no one has said anything to this, I'll assume no one
|
||||||
|
RTFM? (not surprised! email me and say in the subject line: surprise!
|
||||||
|
if you do!)
|
||||||
|
|
||||||
|
Went through the example config files and heavily commented them so for
|
||||||
|
new installs, it explains each line more specifically in hopes less
|
||||||
|
misconfigured systems will be created. I also found some typos as to
|
||||||
|
man page references - fixed. Also updated some of the help files in
|
||||||
|
regards to the new changes in relation to the "stay" sub command when
|
||||||
|
connecting out from URONode.
|
||||||
|
|
||||||
|
Note: in node.c I modified the pre-provided segfault patch to now
|
||||||
|
push text to the local console instructing the local sysop or user
|
||||||
|
what/how to properly execute the node. This will (I hope) force
|
||||||
|
some RTFM to occur. Syslog logging was also added in the event this
|
||||||
|
occurs. Actually, after thinking about this, I figured I'd dummy it up
|
||||||
|
a bit and have it launch a login anyway. This depends that the local
|
||||||
|
administrator/sysop -properly configures their box- and does the
|
||||||
|
following:
|
||||||
|
1 - add a line in /etc/services to point tcp/3694 to uronode
|
||||||
|
2 - add uronode as a service in inetd or xinetd
|
||||||
|
3 - insure you have a local telnet client on the box
|
||||||
|
4 - enjoy!
|
||||||
|
You will be reminded about this during the login, and syslog will
|
||||||
|
reflect a local console login as well.I strongly urge you not to open
|
||||||
|
2 shells and tail your syslog in one while you try to run URONode from
|
||||||
|
the console. Wink
|
||||||
|
|
||||||
|
Cleaned up a minor routine in do_nodes which lays in command.c where
|
||||||
|
under an incoming NetRom connect, a user who did "Nodes" received
|
||||||
|
an extra line feed if the columns were all equal at 4 per row. This
|
||||||
|
was a bit under my skin... fixed/changed. While I was at it, I changed
|
||||||
|
the output string when doing "Nodes *" from 'Nodes:' to "Detailed
|
||||||
|
nodes listing:' which actually makes more sense since it is a detailed
|
||||||
|
list.
|
||||||
|
|
||||||
|
Fixed a minor bug in the way the prompts were handled under certain
|
||||||
|
telnet clients. This was reported also by Marius Petrescu yo2loj. Under
|
||||||
|
telnet, I added a carriage return (/r) along with the line feed (/n).
|
||||||
|
Thank you Marius for the report.
|
||||||
|
|
||||||
|
Slightly rewrote the way meminfo() was being handled. While I may have
|
||||||
|
created a bug in 2.4 and lower kernels, this now should work in 2.6 and
|
||||||
|
higher kernels. I guess the phrase "if it's not broke don't fix it"
|
||||||
|
doesn't apply anymore?
|
||||||
|
|
||||||
|
FINALLY - split the CHANGES file into a new page!! This makes it easier
|
||||||
|
for me to input the change notes instead of having to scroll down for 30
|
||||||
|
seconds Smile Call me lazy but don't call me late for supper! <G>
|
||||||
|
|
||||||
|
04/09/2013 v2.2
|
||||||
|
|
||||||
|
Made multiple .c file edits to reflect the new libax25-devel .h files.
|
||||||
|
Currently these were pointing to the older kernel_*.h files and on newer
|
||||||
|
linux systems was preventing compile. Now URONode should work fine.
|
||||||
|
|
||||||
|
Added Marius Petrescu to the URONode team! With his c version of ripv2d,
|
||||||
|
Marius will (and already has) make a huge impact on the future of
|
||||||
|
URONode! Welcome Marius to the team! Made a reflection of this in the
|
||||||
|
configure script.
|
||||||
|
|
||||||
|
Marius brought to my attention the issue in the log timer routine where
|
||||||
|
it was forcing 32-bit. He supplied code to fix this in both system.c and
|
||||||
|
flexd.c.
|
||||||
|
|
||||||
|
While in discussions, Marius brought it to my attention that Ubuntu (and
|
||||||
|
this includes Mint and any other Ubuntu backed distributions) where they
|
||||||
|
run as he calls it a "fortified libc6" which segfaults on every (what it
|
||||||
|
thinks is suspicious) buffer accesseD to prevent overflows however this
|
||||||
|
libc6 itself causes buffer overflowing. Why on earth did the Ubuntu team
|
||||||
|
ever do this?? Anyway, we're investigating how we're going to handle
|
||||||
|
this issue. I personally have verified URONode to compile and work on
|
||||||
|
the new kernel 3.x series on Debian and Fedora.
|
||||||
|
|
||||||
|
In "fixing" the prompt bug earlier reported by Marius, I made an error in
|
||||||
|
the non-ANSI telnet prompt where the (/r) was also chopping off the first
|
||||||
|
letter of a callsign! OOPS! This was reported by Ted K1YON. Fixed.
|
||||||
|
|
||||||
|
** Key news of this release: ROSE is a LOT more user friendly, AND it also
|
||||||
|
has the ability to display color screens to the end user. This now means
|
||||||
|
that URONode is an 8-prompt system! 4 main prompts, and 4 color prompts.
|
||||||
|
The prompt system is designed to show the end user what protocol/method
|
||||||
|
they used to connect into URONode with. Also proper SSIDs are displayed
|
||||||
|
to match that of how the end user connected. I did this because seeing
|
||||||
|
other nodes, they don't and when (as a user) connect into, for example,
|
||||||
|
a NetRom node who's ssid is -12 and the node displays something
|
||||||
|
-=totally=- different, I often wonder if I connected to the proper node.
|
||||||
|
|
||||||
|
The new prompt schema is:
|
||||||
|
telnet : user@<sysop>.ampr.org:/uronode$
|
||||||
|
netrom : <none> - this keeps in spec with Software2000
|
||||||
|
flex/ax25: =>
|
||||||
|
rose : -=>
|
||||||
|
|
||||||
|
Each matches with its own colors as well if you run the ansi flag. The
|
||||||
|
goodbye message for rose is also different than it is for flex/ax25 and
|
||||||
|
telnet links. The new RoseID flag is used as a personalized message to
|
||||||
|
the remote user to say a nice goodbye, and to remind them of your Rose
|
||||||
|
information. The (V)ersion command also has a rose column added to show
|
||||||
|
the remote user your rose information. An example of this is included
|
||||||
|
in the uronode.conf.5 man page.
|
||||||
|
|
||||||
|
With such, a new uronode.conf file string called RoseID has been created.
|
||||||
|
Details are in the file. You must keep the single quotes ' ' around the
|
||||||
|
string for it to display properly. You have been warned. Also, I've added
|
||||||
|
a default ExtCmd called ROSe so those who connect remotely can get rose
|
||||||
|
addresses for now. I'm sure I'll be changing this in the future.
|
||||||
|
|
||||||
|
Also, I decided to eliminate the permissions flag for use of hidden interfaces.
|
||||||
|
Reason being is if a sysop flags an interface to be hidden, they did so for a
|
||||||
|
specific reason. With that, I moved the ANSI flag from 512 in it's place to
|
||||||
|
64. This was also changed in the man page uronode.perms.5.
|
||||||
|
|
||||||
|
In regards to PBBS forwarding, I -=URGE=- you to read BBS.txt. Since
|
||||||
|
there's no need for me to rewrite it, please heed my warning here. This
|
||||||
|
is not something critical, just informational to help you improve your
|
||||||
|
link with URONode systems.
|
||||||
|
|
||||||
|
Fixed a cosmetic bug in regards to windows->linux emulation where when
|
||||||
|
logging in, sentences were not getting properly wrapped. This was done
|
||||||
|
in node.c. Other emulations such as PuTTY do not give you in windows
|
||||||
|
full linux-type emulation. Higher profile programs such as SecureCRT
|
||||||
|
will. For a free/shareware program I suggest MobiXterm. This also
|
||||||
|
gives you a raw Xserver emulated screen. Of course, there are no issues
|
||||||
|
if you use a standard linux console.
|
||||||
|
|
||||||
|
Added a .pid file to flexd, code supplied by Jaroslav, OK2JRQ and other
|
||||||
|
patches such as installer edits, etc. The only patches he supplied that I
|
||||||
|
have yet to add is the install location patch, and one he feels is good
|
||||||
|
for non-interactive. Source installs need to be interactive, if not you
|
||||||
|
would not be compliling - just my honest opinion. I can see in the case
|
||||||
|
of a possible distro package this may not be desired. The distros for now
|
||||||
|
can hash that out on their own.
|
||||||
|
|
||||||
|
Many more cosmetic bugs fixed/changed. Moreso in ROSE but I did find a
|
||||||
|
few others in there which needed my attention. I have noticed windows terminal
|
||||||
|
based programs such as PuTTY have an issue determining \n based line feeds
|
||||||
|
vs \r carriage returns in C code. This mainly seems to affect the various
|
||||||
|
8 prompts. It seems if I put both in the code, Windows is happy but *nx
|
||||||
|
may issue an added line-feed. I had thought I cleaned these all up but
|
||||||
|
I introduced a couple old ones and some new ones with the ROSE work.
|
||||||
|
|
||||||
|
01/10/2014 -2.2 released!
|
||||||
|
|
||||||
|
02/10/2014 - 2.2.1
|
||||||
|
|
||||||
|
Improperly packaged an old flexd.c! This one should compile. This is NOT
|
||||||
|
the one I want, I've been fighting with flexd for a while now.
|
||||||
|
|
||||||
|
uronode.conf may not update. If it does, you will need to redo yours from
|
||||||
|
scratch. Look at the one in the etc/ directory in the source and add the
|
||||||
|
line for RoseId. This is required. Thanks for the above reports from
|
||||||
|
VE1JOT and SP2LOB.
|
||||||
|
|
||||||
|
Removed the need to have quotes around the RoseId string in URONode.conf. I
|
||||||
|
found it unneccessary to have to do this. Keep the string togther ex:
|
||||||
|
callsign-ssid@1000,200000 now is fine. I also find this cleaner.
|
||||||
|
|
||||||
|
12/10/2014 - v5.1
|
||||||
|
URONode release ver 51 is out!.. um.. I mean its main developer *sigh*
|
||||||
|
|
||||||
|
21/12/2014 - v2.3
|
||||||
|
|
||||||
|
Added Bob Tenty ve3tok to the development team and created a subversion
|
||||||
|
server. Please welcome Bob to the team!
|
||||||
|
|
||||||
|
Bob Tenty ve3tok reports when NOT using the official ax25 packages and
|
||||||
|
on Ubuntu, the node when compiled natively may buffer overflow. He made
|
||||||
|
changes to buffers in gateway.c, router.c, and flexd.c which prevent this.
|
||||||
|
I have incorporated these changes and there's no ill effect on non Ubuntu
|
||||||
|
distros.
|
||||||
|
|
||||||
|
Fixed a bug I introduced into the ROSE ansi prompt where it wasn't
|
||||||
|
executing a proper \n because I inadvertantly removed it. Restored.
|
||||||
|
|
||||||
|
Fixed a warning in the axdigi code. Now that I'm on a more modern system
|
||||||
|
I can fix these things as now I can see them better. This was also brought
|
||||||
|
to my attention by Tomasz SP2L... thanks Tomasz!
|
||||||
|
|
||||||
|
Figured out a way to compile and have it NOT segfault under Ubuntu. While
|
||||||
|
I'll admit for the time being it's somewhat of a hack, but it *does* work
|
||||||
|
for Ubuntu. There are warnings on Ubuntu compiles that don't exist on other
|
||||||
|
platforms - interesting to say the least - but I think I see a relation
|
||||||
|
between the warnings and the pervious Makefile. The prior statement is being
|
||||||
|
left in as a comment deliberately as I hope to try and revert back to
|
||||||
|
the previous method.
|
||||||
|
|
||||||
|
**IMPORTANT: Per distro downstreams, I've been asked to change the paths
|
||||||
|
of the URONode installs. Now your uronode and binaries will be placed in
|
||||||
|
/usr/local/sbin instead of /usr/sbin. Config files will be in
|
||||||
|
/usr/local/etc/ax25 instead of /usr/ax25/. Node files will now be in
|
||||||
|
/usr/local/var/ax25/node or flexd instead of /var/ax25/node or flexd.
|
||||||
|
If you're a thrifty ham such as myself, you'll already have symlinks created
|
||||||
|
for easier management, so that /etc/ax25 is symlinked into /usr/local/etc/ax25
|
||||||
|
and so forth. Local files I can think of that would need editing if you use
|
||||||
|
my standard config:
|
||||||
|
/usr/local/bin/ax25
|
||||||
|
/etc/xinetd.d/uronode
|
||||||
|
/etc/xinetd.d/telnet (?)
|
||||||
|
/etc/ax25/ax25d.conf
|
||||||
|
|
||||||
|
Added a compile flag to keep Ubuntu happy. This and other routines were at the
|
||||||
|
suggestions of YO2LOJ and VE3TOK.
|
||||||
|
|
||||||
|
SYSop command does NOT spawn a shell anymore. This is due to the changes
|
||||||
|
with the UNIX98 file system. I'm debating on whether or not I wish to
|
||||||
|
continue to keep this or possibly eliminate this (for possible security
|
||||||
|
reasons). I see both PROs and CONs with it. Note: this ONLY affects those
|
||||||
|
systems which force the use of /dev/ptmx in which one needs to use SOCAT
|
||||||
|
to create static /dev/tty*# and /dev/pty*# pipes. This only affects the
|
||||||
|
Kernel 3-series in which the older /dev/pty# system is no longer used and
|
||||||
|
a master ptyx is used.
|
||||||
|
|
||||||
|
I did notice UBUNTU made changes to their libraries last year (2013) in
|
||||||
|
which URONode compiled but failed to execute any direct disk read/write
|
||||||
|
routines. In any event, they fixed this bug late fall 2014 (at least in
|
||||||
|
12.0.4LTS). One of the nice things about Ubuntu doing this is that you
|
||||||
|
can add a line in your grub configuration to have the kernel create a
|
||||||
|
number of satic pseudo terminals upon boot. Debian, however, breaks this
|
||||||
|
ruleset. I contacted my downstream and he hasn't responded. This would
|
||||||
|
help a sysop gain a shell... however also creates a possible backdoor.
|
||||||
|
|
||||||
|
Edited gateway.c so that the callsign-ssid is force altered on outbound
|
||||||
|
ax25 connect requests regardless of how the inbound connect was initiated.
|
||||||
|
VE1JOT reports that when a user telnets in, and gateway ax25 connects out,
|
||||||
|
the callsign-0 is kept. This should be altered to a -15. This was always
|
||||||
|
true when inbound connects were ax25 and also outbound connects the same.
|
||||||
|
VE1JOT reports this is troublesome, and in some cases causing DM frames
|
||||||
|
to occur. While I tested this and found this not to be true on my own
|
||||||
|
system, I did make a code adjustment to handle this.
|
||||||
|
|
||||||
|
Fixed a bug in config.h which may cause flexd not to find the proper
|
||||||
|
config lines. When I changed file paths I missed a couple. Now the system as
|
||||||
|
a whole should be consistant in regards to config files.
|
||||||
|
|
||||||
|
Removed the need for MyGate and MyRange in flexd.conf! This was added by
|
||||||
|
the request of K2BJG/SK so that the flexgate itself would be listed. Actually
|
||||||
|
it is in the LINKS file. Unfortunately when trying to connect to a listed
|
||||||
|
flexgate, it would try to digi via itself! Not good. While I was at it, I
|
||||||
|
also increased the buffer from 512 to 1024. This may help with those gates
|
||||||
|
that insist on making L A R G E MOTDs.
|
||||||
|
|
||||||
|
|
||||||
|
14/02/2015 - v2.3.1
|
||||||
|
Happy Valentine's day to the one we all love: Our Compilers!
|
||||||
|
This is a critical security patch! I URGE you *all* to recompile.
|
||||||
|
If anything, hopefully you've all patched your systems against GHOST.
|
||||||
|
For those who wish to test their system I have a tool on my ftp site
|
||||||
|
which can do this for you.
|
||||||
|
|
||||||
|
Through Paul G4APL, Andy G0HXT reported a condition on Ubuntu-based
|
||||||
|
systems in which a user may enter a malformed NetRom connect string
|
||||||
|
into URONode and the node will buffer overflow. I fixed this in
|
||||||
|
gateway.c limiting the string for searching connects on the first parameter.
|
||||||
|
Also changed the error output to the user so that they may know the error
|
||||||
|
may be their own.
|
||||||
|
|
||||||
|
Made edits to all the man pages and the INSTALL file as suggested by Tomasz
|
||||||
|
SP2L. I also grepped for certain strings in other files and made a change
|
||||||
|
to the README file as well.
|
||||||
|
|
||||||
|
Changed the version in node.h to reflect this security patch.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Known NON-Critical Bugs:
|
||||||
|
Status memory/swap reporting fix
|
||||||
|
|
||||||
|
Wish-list:
|
||||||
|
Who file sorter
|
||||||
|
pactor - requested by sv1uy
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Original Development Information (aka Disclaimer):
|
||||||
|
URONode was developed on an IBM eSeries 330 eServer with dual 1.2GHz CPUs
|
||||||
|
The OS is Debian Linux 4 using kernel 2.4.27, libax25 v0.0.11,
|
||||||
|
ax25-tools v0.0.8 and ax25-apps v0.0.6. This software comes with
|
||||||
|
absolutely NO guarantees so crash n burn at your own risk. We all may
|
||||||
|
be surprised and find out that it actually DOES something useful!
|
||||||
|
URONode may not run 100% depending on environmental conditions specific
|
||||||
|
to your system.
|
||||||
|
|
||||||
|
URONode is GLPv2 code, and tested by it's main author on the following
|
||||||
|
platforms: Raspberry Pi ver. B, Debian 7.7 on a Core-i3, Ubuntu 12.0.4LTS
|
||||||
|
on a Core-i3, Fedora ver. 19
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
Comments/suggestions? email: n1uro@n1uro.ampr.org
|
||||||
|
Gripes??? cat gripes > /dev/null Smile just kidding!
|
||||||
|
|
||||||
|
This version will get you going for now. I'll post any changes to:
|
||||||
|
ftp://ftp.n1uro.net/packet
|
||||||
|
|
||||||
|
Join our support mail list graciously donated by TAPR!
|
||||||
|
http://www.tapr.org/mailman/listinfo/uronode
|
||||||
|
|
||||||
|
73 de Brian N1URO
|
|
@ -0,0 +1,25 @@
|
||||||
|
Incase you're wondering about the method behind the madness in my color
|
||||||
|
schema it's very simple. Picture yourself with 3 vehicles to drive on
|
||||||
|
different roads with; a scooter, a compact car, and an SUV. Each vehicle
|
||||||
|
(or protocol) has it's own color. Each vehicle follows the same rules
|
||||||
|
of the road (green for go, red for stop, blinking red for alarms). When
|
||||||
|
you command URONode to go somewhere, you get green. When you return and
|
||||||
|
the process has completed it's red. Ax25/Flex is Yellow, NetRom is Cyan,
|
||||||
|
and IP/System messages are Magenta.
|
||||||
|
|
||||||
|
It's VERY IMPORTANT that you program any automated scripts that connect
|
||||||
|
to URONode that they do NOT use colors! Simply remove 512 from their
|
||||||
|
permissions. If you do NOT do this, the robot script may attempt to
|
||||||
|
decipher ANSI code and it may cause it to hang. YOU HAVE BEEN WARNED!
|
||||||
|
|
||||||
|
|
||||||
|
Here's the schema:
|
||||||
|
Connects display in green as in "gateway go"
|
||||||
|
Reconnects display in red as in "gateway stop"
|
||||||
|
IP based information is in magenta
|
||||||
|
Netrom Nodes (full list) in bold cyan
|
||||||
|
FlexNet destis (full list) in yellow
|
||||||
|
System info in bright white
|
||||||
|
Aborts and timeouts blink bright red
|
||||||
|
Logouts in low cyan
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
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.
|
|
@ -0,0 +1,35 @@
|
||||||
|
Welcome to the official FAQ file for URONode.
|
||||||
|
|
||||||
|
The purpose of this file is to help explain better about URONode and what
|
||||||
|
the various features were designed for. Since this file will be maintained
|
||||||
|
via URONode Sysop reports, I'll consider this file a constant 'work in
|
||||||
|
progress' type file.
|
||||||
|
|
||||||
|
When using URONode or really any other linux node flavor, keep in mind
|
||||||
|
that the actual node program itself is only a front-end for the users
|
||||||
|
to do various functions your linux server may have to provide. Node really
|
||||||
|
doesn't do any sort of control features whatsoever, it merely acts as a
|
||||||
|
sort of proxy to your linux daemons. Those features are toggled on/off at
|
||||||
|
compile time by the operator of the node. I've taken time to rework the
|
||||||
|
configure script to give the node ops more flexibility in what they wish
|
||||||
|
to service their end users with. Nothing about URONode was ever designed
|
||||||
|
as a 'replacement' for any existing services such as email and convers.
|
||||||
|
I'm not even going to suggest one chooses to run URONode as a replacement
|
||||||
|
for LinuxNode by Tomi, AWZNode, or even FlexNode. The goals I set when
|
||||||
|
starting this project were moreso to custom fit my unique setup and its
|
||||||
|
something I can share with the amateur community at the same time.
|
||||||
|
|
||||||
|
URONode is NOT:
|
||||||
|
A replacement for *NOS
|
||||||
|
A replacement for Email
|
||||||
|
A replacement for PBBS
|
||||||
|
A replacement for convers
|
||||||
|
A FlexNet router
|
||||||
|
|
||||||
|
URONode IS:
|
||||||
|
A user front-end with some additional features to help compliment those
|
||||||
|
existing features an end user may need but for whatever reason doesn't
|
||||||
|
have access to at the moment, while allowing links to various entities
|
||||||
|
such as AX.25 links, Net/Rom routing, FlexNet destinations, general and
|
||||||
|
amprnet TCP/IP services.
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
1. COMPILING and INSTALLING
|
||||||
|
|
||||||
|
To compile and run URONode you will need to have libax25-0.0.4 or newer
|
||||||
|
installed on your system. It should work on any platform where libax25 can
|
||||||
|
be compiled and installed.
|
||||||
|
Note however that it will NOT work with 2.0.x kernels.
|
||||||
|
|
||||||
|
To install you should first run:
|
||||||
|
|
||||||
|
./configure
|
||||||
|
|
||||||
|
and answer to the questions it makes.
|
||||||
|
|
||||||
|
** IF ** this is an ** UPGRADE **:
|
||||||
|
and if you said no to configure running a "make", just type:
|
||||||
|
make; make upgrade
|
||||||
|
This will *not* overwrite your config files, and will freshen up
|
||||||
|
your binaries only. If you told the configure script to make, then
|
||||||
|
all you need to type to upgrade is: make upgrade.
|
||||||
|
|
||||||
|
** IF ** this is a new install:
|
||||||
|
|
||||||
|
If all files needed are present everything should work. Next:
|
||||||
|
|
||||||
|
make (if you said "no" to the configure script launching it for you)
|
||||||
|
make install
|
||||||
|
make installhelp
|
||||||
|
|
||||||
|
Optionally you may want to run also:
|
||||||
|
|
||||||
|
make installconf
|
||||||
|
|
||||||
|
to install the default configuration files.
|
||||||
|
Note however this copy example files in /usr/local/etc/ax25 but with ".ex".
|
||||||
|
You should rename it by removing ".ex" at the end of filenames.
|
||||||
|
|
||||||
|
After that you need to edit the configuration files to suit your system.
|
||||||
|
The manual pages for uronode.conf(5) and uronode.perms(5) should give
|
||||||
|
an idea of what to put into these files. The AX25-HOWTO is a must read also.
|
||||||
|
|
||||||
|
2. RUNNING
|
||||||
|
|
||||||
|
URONode is intended to be called from ax25d or inetd. It doesn't need
|
||||||
|
any command line arguments. See the uronode(8) manual page.
|
||||||
|
|
||||||
|
To run URONode from ax25d, /usr/local/etc/ax25/ax25d.conf should have something
|
||||||
|
like this in it:
|
||||||
|
|
||||||
|
# AX25 Port ax0
|
||||||
|
# Belows SSID can not be the same as your netrom node SSID!
|
||||||
|
[N1URO-2 VIA ax0]
|
||||||
|
default * * * * * * - root /usr/local/sbin/uronode uronode
|
||||||
|
|
||||||
|
# NETROM Port
|
||||||
|
<nr0>
|
||||||
|
default * * * * * * - root /usr/local/sbin/uronode uronode
|
||||||
|
|
||||||
|
add uronode as a service in /etc/services:
|
||||||
|
uronode 3694/tcp # Node/URONode packet
|
||||||
|
|
||||||
|
if you use inetd -
|
||||||
|
/etc/inetd.conf could have something like this in it:
|
||||||
|
|
||||||
|
# Listen at telnet port -> URONode
|
||||||
|
uronode stream tcp nowait nobody /usr/local/sbin/uronode uronode
|
||||||
|
|
||||||
|
if you use xinetd -
|
||||||
|
/etc/xinetd.d/uronode should look like this:
|
||||||
|
|
||||||
|
service uronode
|
||||||
|
{
|
||||||
|
disable = no
|
||||||
|
socket_type = stream
|
||||||
|
protocol = tcp
|
||||||
|
user = nobody
|
||||||
|
server = /usr/local/sbin/uronode
|
||||||
|
wait = no
|
||||||
|
instances = 20
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
all: nodeusers uronode axdigi @FLEXNET@
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
LD = gcc
|
||||||
|
# CFLAGS = -O2 -g -s -Wstrict-prototypes
|
||||||
|
CFLAGS = -O2 -g -Wno-unused-result -Wstrict-prototypes
|
||||||
|
LDFLAGS =
|
||||||
|
LIBS = -lax25 -lax25io
|
||||||
|
|
||||||
|
include Makefile.include
|
||||||
|
|
||||||
|
COMMON_SRC = user.c util.c
|
||||||
|
NODE_SRC = node.c cmdparse.c config.c command.c mheard.c axcalluser.c \
|
||||||
|
gateway.c extcmd.c procinfo.c router.c system.c sysinfo.c ipc.c
|
||||||
|
NODEUSERS_SRC = nodeusers.c
|
||||||
|
FLEXD_SRC = flexd.c procinfo.c
|
||||||
|
DIGI_SRC = axdigi.c
|
||||||
|
|
||||||
|
COMMON_OBJS = $(COMMON_SRC:.c=.o)
|
||||||
|
NODE_OBJS = $(NODE_SRC:.c=.o)
|
||||||
|
NODEUSERS_OBJS = $(NODEUSERS_SRC:.c=.o)
|
||||||
|
FLEXD_OBJS = $(FLEXD_SRC:.c=.o)
|
||||||
|
DIGI_OBJS = $(DIGI_SRC:.c=.o)
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) -c $<
|
||||||
|
|
||||||
|
install: installbin installman installhelp installconf
|
||||||
|
install -m 755 -D -d $(VAR_DIR)
|
||||||
|
install -m 755 -D -d $(VAR_DIR)/node
|
||||||
|
install -m 644 -p etc/loggedin $(VAR_DIR)/node
|
||||||
|
install -m 644 -p etc/lastlog $(VAR_DIR)/node
|
||||||
|
install -m 755 -D -d $(VAR_DIR)/flex
|
||||||
|
install -m 644 -p etc/gateways $(VAR_DIR)/flex
|
||||||
|
|
||||||
|
installbin: all
|
||||||
|
install -m 755 -s -p uronode $(SBIN_DIR)
|
||||||
|
install -m 755 -s -p nodeusers $(SBIN_DIR)
|
||||||
|
install -m 755 -s -p axdigi $(SBIN_DIR)
|
||||||
|
@IN@ install -m 755 -s -p flexd $(SBIN_DIR)
|
||||||
|
|
||||||
|
installhelp:
|
||||||
|
install -m 755 -D -d $(VAR_DIR)
|
||||||
|
install -m 755 -D -d $(VAR_DIR)/node/help
|
||||||
|
install -m 644 -p etc/help/*.hlp $(VAR_DIR)/node/help
|
||||||
|
|
||||||
|
installconf: installhelp
|
||||||
|
install -m 755 -D -d $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.conf $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.perms $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.info $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.motd $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.users $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/uronode.routes $(ETC_DIR)
|
||||||
|
install -m 600 -p etc/flexd.conf $(ETC_DIR)
|
||||||
|
|
||||||
|
installman:
|
||||||
|
install -m 755 -D -d $(MAN_DIR)/man1 $(MAN_DIR)/man5 $(MAN_DIR)/man8
|
||||||
|
install -m 644 -p man/nodeusers.1.gz $(MAN_DIR)/man1
|
||||||
|
install -m 644 -p man/uronode.conf.5.gz $(MAN_DIR)/man5
|
||||||
|
install -m 644 -p man/uronode.perms.5.gz $(MAN_DIR)/man5
|
||||||
|
install -m 644 -p man/flexd.conf.5.gz $(MAN_DIR)/man5
|
||||||
|
install -m 644 -p man/uronode.8.gz $(MAN_DIR)/man8
|
||||||
|
install -m 644 -p man/axdigi.8.gz $(MAN_DIR)/man8
|
||||||
|
|
||||||
|
upgrade: installman
|
||||||
|
install -m 755 -p uronode $(SBIN_DIR)
|
||||||
|
install -m 755 -p nodeusers $(SBIN_DIR)
|
||||||
|
install -m 755 -p flexd $(SBIN_DIR)
|
||||||
|
install -m 755 -p axdigi $(SBIN_DIR)
|
||||||
|
install -m 644 -p uronode.conf $(ETC_DIR)
|
||||||
|
install -m 644 -p uronode.perms $(ETC_DIR)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f *.o *~ *.bak *.orig make.debug nodeusers uronode flexd axdigi
|
||||||
|
rm -f etc/*~ etc/*.bak etc/*.orig
|
||||||
|
rm -f etc/help/*~ etc/help/*.bak etc/help/*.orig
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f .depend Makefile.include config.h
|
||||||
|
rm -f uronode nodeusers axdigi @FLEXNET@
|
||||||
|
rm -f Makefile make.debug
|
||||||
|
|
||||||
|
depend:
|
||||||
|
$(CC) $(CFLAGS) -M $(COMMON_SRC) $(NODE_SRC) $(NODEUSERS_SRC) $(FLEXD_SRC) > .depend
|
||||||
|
|
||||||
|
uronode: $(COMMON_OBJS) $(NODE_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o uronode $(COMMON_OBJS) $(NODE_OBJS) $(LIBS) $(ZLIB)
|
||||||
|
|
||||||
|
nodeusers: $(COMMON_OBJS) $(NODEUSERS_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o nodeusers $(COMMON_OBJS) $(NODEUSERS_OBJS) $(LIBS) $(ZLIB)
|
||||||
|
|
||||||
|
flexd: $(FLEXD_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o flexd $(FLEXD_OBJS) $(LIBS) $(ZLIB)
|
||||||
|
|
||||||
|
axdigi: $(DIGI_OBJS)
|
||||||
|
$(LD) $(LDFLAGS) -o axdigi $(DIGI_OBJS)
|
||||||
|
|
||||||
|
ifeq (.depend,$(wildcard .depend))
|
||||||
|
include .depend
|
||||||
|
endif
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Processor architecture
|
||||||
|
ARCH = @ARCH@
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
ETC_DIR = @ETC_DIR@
|
||||||
|
SBIN_DIR = @SBIN_DIR@
|
||||||
|
BIN_DIR = @BIN_DIR@
|
||||||
|
LIB_DIR = @LIB_DIR@
|
||||||
|
MAN_DIR = @MAN_DIR@
|
||||||
|
VAR_DIR = @VAR_DIR@
|
||||||
|
|
||||||
|
# Is Zlib available?
|
||||||
|
ZLIB = @ZLIB@
|
|
@ -0,0 +1,95 @@
|
||||||
|
Please check out the file INSTALL to compile and install URONode.
|
||||||
|
Also please read the CHANGES.* file for all version history changes.URONode README file September 09, 2013
|
||||||
|
|
||||||
|
Note: Please read the CHANGES file for detailed information
|
||||||
|
about the changes from AWZNode to URONode and what I've
|
||||||
|
done with it... along with current version info! - Brian N1URO
|
||||||
|
|
||||||
|
Hi linuxers!
|
||||||
|
|
||||||
|
First all, I thanks PE1RJA and OH2BNS for their very great job!
|
||||||
|
|
||||||
|
*****************************************************************************
|
||||||
|
The v0.5.x release is a temporary version of URONode running and compiling
|
||||||
|
under linux 2.4.x, with glibc 6 and new ax25 and ax25io libraries. v0.0.11
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
UROnode is based on AWZ|LinuxNode by Tomi Manninen OH2BNS and FlexNode
|
||||||
|
by Roy PE1RJA. It was born initially for the aripisa.ampr.org system
|
||||||
|
by Stefano Noferi IZ5AWZ of ARI Ham Radio Association of Pisa (ITALY).
|
||||||
|
Users in URONode can connect all ham packet world: all AX25, NETROM, ROSE,
|
||||||
|
FLEXNET, ITANET, TCP/IP nodes in the world are now near.
|
||||||
|
|
||||||
|
Comment from Stefano:
|
||||||
|
I have a "packet" dream: all the packet networks can interchange connections.
|
||||||
|
My version of node software for Linux is an attempt to realize this idea
|
||||||
|
and I hope it can help the ham radio digital world to come back one. ;)
|
||||||
|
|
||||||
|
I thanks ARI association of Pisa and Alex Del Chicca IK5PWJ,
|
||||||
|
for their trust and supports.
|
||||||
|
|
||||||
|
This README file, the documentation etc. are very incomplete!
|
||||||
|
Sorry, but my free time is very very very... very little.. :)
|
||||||
|
|
||||||
|
If you decide to use URONode, send me a mail.
|
||||||
|
|
||||||
|
Routing features include: (in order preferance)
|
||||||
|
- netrom routing
|
||||||
|
- fixed routes
|
||||||
|
Create and/or modify /usr/local/etc/ax25/uronode.routes, the format of
|
||||||
|
this file is in the example file uronode.route.ex.
|
||||||
|
Now fixed link nodes in this file have an alias and 3 connection
|
||||||
|
modes, can be queried using the Links command and can be
|
||||||
|
connected directly using: Connect <call>|<alias> (ie. without
|
||||||
|
specifying the downlink port)
|
||||||
|
- flexnet destination lists
|
||||||
|
A separate daemon (flexd) queries a neighbouring flexnet node for its
|
||||||
|
reachable destinations, these destinations are stored on the local
|
||||||
|
disk and can be queried using the Dest command and can be connected
|
||||||
|
directly using: Connect <destination>
|
||||||
|
Config file: flexd.conf:
|
||||||
|
MyCall <call> # the callsign used during the connection
|
||||||
|
PollInterval <interval> # how often the destinations are downloaded
|
||||||
|
FlexGate <call> # the neighbouring flexnet node
|
||||||
|
The pollinterval is specified in seconds and the callsign after
|
||||||
|
flexgate must be defined in uronode.routes !!
|
||||||
|
- mheard based routing
|
||||||
|
When users are using your node the mheard tables are filled with
|
||||||
|
callsigns, callsigns heard on ports can be connected directly with
|
||||||
|
the Connect <call> command, without specifying the downlink port.
|
||||||
|
|
||||||
|
Other features:
|
||||||
|
- local users of the linux machine can be granted access to the mailreader
|
||||||
|
and optionally to the shell. Config file: /etc/ax25/node.users
|
||||||
|
<call>:<password>:<username>:[mail][,shell]
|
||||||
|
call : the callsign of the user that is allowed to access special features
|
||||||
|
password : a string pasword
|
||||||
|
username : the (real)-username on the linux side
|
||||||
|
options : mail - the user has permission to access his or her mailbox
|
||||||
|
shell - the user has permission to access the shell
|
||||||
|
Users with the mail option enabled will receive messages like "New mail
|
||||||
|
has arrived", mostly when the stated condition is met ;-)
|
||||||
|
- all users can send messages to a callsign associated in the kernel table
|
||||||
|
with a linux username ("send" command).
|
||||||
|
- now the sysop can modified the node prompt and password prompt
|
||||||
|
- "!" command show system statistics
|
||||||
|
- old "SEssions" command is now "MSessions"
|
||||||
|
- now "MHeard" command can be used without port specification
|
||||||
|
- changed the output of several query programs (like ports/routes etc.) also
|
||||||
|
included more netrom specific output in these commands
|
||||||
|
- included a lastlog, which shows the time, date and port of your previous
|
||||||
|
session, if this is your first connect, you are requested to read the
|
||||||
|
info text
|
||||||
|
|
||||||
|
The official FTP Site of URONode is:
|
||||||
|
https://sourceforge.net/projects/uronode/?source=directory
|
||||||
|
ftp://ftp.n1uro.net/packet/
|
||||||
|
|
||||||
|
The official Forums site is:
|
||||||
|
http://www.tapr.org/mailman/listinfo/uronode
|
||||||
|
|
||||||
|
URONode is also a part of Fedora 20 and higher.
|
||||||
|
"yum install uronode" to install the .rpm package.
|
||||||
|
|
||||||
|
Please check out the file INSTALL to compile and install URONode.
|
||||||
|
Also please read the CHANGES.* file for all version history changes.
|
|
@ -0,0 +1,49 @@
|
||||||
|
** Note: this file is depreciated, refer to CHANGES.*
|
||||||
|
|
||||||
|
URONode was spawned off of the original linuxnode by Tomi Manninen OH2BNS
|
||||||
|
Before URONode was FlexNode by Roy PE1RJA, and then by Stefano Noferi IZ5AWZ
|
||||||
|
who called it AWZNode. I took over the code willingly and on my own mainly
|
||||||
|
as a project I could do under C program coding in April 2003 after it
|
||||||
|
appeared that AWZNode was no longer being developed.
|
||||||
|
|
||||||
|
My first goal was to make it appear and act more like TheNet X1J and spent
|
||||||
|
most of my time configuring the node to behave as such which I felt I did
|
||||||
|
quite successfully. While doing that I thought I'd try to add in email
|
||||||
|
features by using the old PMS system written by Alan Cox, who has a lot
|
||||||
|
of code in the main linux kernel for it's IP stack (most of which is taken
|
||||||
|
directly out of KA9Q nos). While I was successful in doing that, Morgan
|
||||||
|
SM6TKY reported that the code was old and exploitable... unfortunately I had
|
||||||
|
a period where I couldn't devote the time into getting it repaired quickly
|
||||||
|
and URONode sat and suffered with a note explaining that certain features
|
||||||
|
should not be used or enabled. As a quick fix, I simply commented out the
|
||||||
|
found exploits and did some more cosmetics to the code and released a patch.
|
||||||
|
|
||||||
|
Still with users wanting EMAIL as a feature to the software, this inspired me
|
||||||
|
to pick up with the dropped axMail code and bring that more up to date. axMail
|
||||||
|
was originally started by Heikki Hannikainen, and then mailbox routines were
|
||||||
|
added by Marius Petrescu, however system configs were lacking. I took the
|
||||||
|
code and added in the routines which are in there now so that new users
|
||||||
|
are properly created within the basic linux filesystem schema, and passwords
|
||||||
|
can be created (optional) so that a web front-end such as NeoMail can be
|
||||||
|
used in conjunction with axMail giving users the choice of the web or RF
|
||||||
|
packet to do their SMTP based EMAIL with. It was and always will be an optional
|
||||||
|
add-on module for URONode, and other flavors of *node for linux.
|
||||||
|
|
||||||
|
These two packages together, along with F6FBB make for one heck of a feature
|
||||||
|
packed system a sysop can piece together on one server. Because of such,
|
||||||
|
URONode has become very popular in the NorthEast USA and in Central East
|
||||||
|
Florida within the EastNet FlexNet network and with the Florida MARS
|
||||||
|
networks. With this, I've taken the look and feel of URONode to try and
|
||||||
|
match that of a FlexNet interface.
|
||||||
|
|
||||||
|
The latest version of URONode under-went many face lifts! The node not only
|
||||||
|
auto-senses the incoming connection but delivers an interface which clones
|
||||||
|
that of the type of system they're connecting in from. A user connecting
|
||||||
|
in via IP will actually get a prompt that looks and acts similar to a
|
||||||
|
Unix bash prompt with custom aliased commands!.. and to top that all off
|
||||||
|
I've added an ansi schema to the IP interface!!
|
||||||
|
|
||||||
|
URONode is used world-wide in Europe, Africa, Asia, and in North America.
|
||||||
|
A web bbs is available at https://www.n1uro.net/forum where release notes
|
||||||
|
for URONode are posted. If the functionality of URONode isn't enough to
|
||||||
|
get interest in packet growing, the stability of URONode should!
|
|
@ -0,0 +1,77 @@
|
||||||
|
/* axcalluser.c - determine username corresponding to callsign */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include "config.h"
|
||||||
|
#include "axcalluser.h"
|
||||||
|
|
||||||
|
int axcalluserid(char *call)
|
||||||
|
{
|
||||||
|
char callsign[10];
|
||||||
|
char username[80];
|
||||||
|
int id;
|
||||||
|
int userid = -1;
|
||||||
|
FILE *f = fopen(PROC_AX25_CALLS_FILE,"r");
|
||||||
|
if (f) { /* VE3TOK, 18Nov2014, return value usage */
|
||||||
|
if (fgets(username,79,f) == NULL) {
|
||||||
|
syslog(LOG_DEBUG, "Can't get username: %s", strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
while (fscanf(f," %d %9s",&id,callsign) != EOF) {
|
||||||
|
char *a,*b;
|
||||||
|
for (a=call,b=callsign;
|
||||||
|
*a && *b && toupper(*a)==toupper(*b) && *b!='-';
|
||||||
|
a++,b++) ;
|
||||||
|
if (!isalnum(*a) && !isalnum(*b)) {
|
||||||
|
userid = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
return userid;
|
||||||
|
}
|
||||||
|
char *getusername(int userid)
|
||||||
|
{
|
||||||
|
int colons;
|
||||||
|
int c,i;
|
||||||
|
char token[80];
|
||||||
|
static char name[80];
|
||||||
|
char *retval = NULL;
|
||||||
|
FILE *f;
|
||||||
|
f = fopen("/etc/passwd","r");
|
||||||
|
if (f) {
|
||||||
|
i = 0;
|
||||||
|
colons = 0;
|
||||||
|
while ((c = getc(f)) != EOF) {
|
||||||
|
switch (c) {
|
||||||
|
case ':':
|
||||||
|
token[i] = '\0';
|
||||||
|
colons++;
|
||||||
|
if (colons == 3) {
|
||||||
|
if (userid == atoi(token)) {
|
||||||
|
retval = name;
|
||||||
|
goto endloop;
|
||||||
|
}
|
||||||
|
} else if (colons == 1) {
|
||||||
|
strcpy(name,token);
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
colons = 0;
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
token[i++] = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
endloop:
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef AXCALLUSER_H
|
||||||
|
#define AXCALLUSER_H
|
||||||
|
|
||||||
|
/* Simple functions to return userid of a callsign, and */
|
||||||
|
/* username of a userid, by reading appropriate files. */
|
||||||
|
/* Surely there's a better way to do 'getusername', but */
|
||||||
|
/* this works. */
|
||||||
|
/* Dave Brown N2RJT 5/5/96 */
|
||||||
|
|
||||||
|
/* return userid of given callsign, or -1 if not found */
|
||||||
|
int axcalluserid(char *callsign);
|
||||||
|
|
||||||
|
/* return username of given userid, or NULL if not found */
|
||||||
|
char *getusername(int userid);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* axdigi: Cross and straight port digipeater program
|
||||||
|
* Copyright (C) 1995 Craig Small VK2XLZ
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* JSN - Small tweaks to ensure compilation and execution under Linux 2.1.x.
|
||||||
|
* 12th June 1997.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include </usr/include/net/if.h>
|
||||||
|
#include <linux/if_ether.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strings.h>
|
||||||
|
/* below added by N1URO */
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/ax25.h>
|
||||||
|
|
||||||
|
int recv_packet(unsigned char *buf, int size, unsigned char *port);
|
||||||
|
void print_call(unsigned char *buf);
|
||||||
|
unsigned char *find_call(char *port);
|
||||||
|
void add_port(char *call, char *port);
|
||||||
|
void get_interfaces(int skt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The defines we use
|
||||||
|
*/
|
||||||
|
#define AXALEN 7
|
||||||
|
#define E_BIT 0x01 /* Address extension bit */
|
||||||
|
#define REPEATED 0x80 /* Has-been-repeated bit */
|
||||||
|
#define MAX_PORTS 16
|
||||||
|
#define VERSION "0.2"
|
||||||
|
|
||||||
|
int port_count = 0;
|
||||||
|
unsigned char portname[MAX_PORTS][20];
|
||||||
|
unsigned char portcall[MAX_PORTS][8];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int skt;
|
||||||
|
int size, rt;
|
||||||
|
unsigned char buf[4096];
|
||||||
|
struct sockaddr sa;
|
||||||
|
int asize;
|
||||||
|
|
||||||
|
/* Check our huge range of flags */
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "-h") ==0)
|
||||||
|
{
|
||||||
|
printf("axdigi version %s. Copyright (C) 1995 Craig Small VK2XLZ\n\n", VERSION);
|
||||||
|
printf("axdigi comes with ABSOLUTELY NO WARRANTY.\n");
|
||||||
|
printf("This is free software, and you are welcome to redistribute it\n");
|
||||||
|
printf("under the terms of GNU General Public Licence as published\n");
|
||||||
|
printf("by Free Software Foundation; either version 2 of the License, or\n");
|
||||||
|
printf("(at your option) any later version.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Change to keep code more modern - N1URO */
|
||||||
|
if ((skt = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_AX25))) == -1)
|
||||||
|
{
|
||||||
|
perror("socket");
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
get_interfaces(skt);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
asize = sizeof(sa);
|
||||||
|
|
||||||
|
if ((size = recvfrom(skt, buf, sizeof(buf), 0, &sa, &asize)) == -1)
|
||||||
|
{
|
||||||
|
perror("recv");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((rt = recv_packet(buf, size, sa.sa_data)) >= 0)
|
||||||
|
{
|
||||||
|
if (rt < port_count)
|
||||||
|
{
|
||||||
|
asize = sizeof(sa);
|
||||||
|
strcpy(sa.sa_data, portname[rt]);
|
||||||
|
if (sendto(skt, buf, size, 0, &sa, asize) == -1)
|
||||||
|
perror("sendto");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* printf("Unknown port %s\n", sa.sa_data);*/
|
||||||
|
} /* recv_packet true */
|
||||||
|
} /* while(1) */
|
||||||
|
close(skt);
|
||||||
|
}
|
||||||
|
|
||||||
|
int recv_packet(unsigned char *buf, int size, unsigned char *port)
|
||||||
|
{
|
||||||
|
unsigned char *bptr;
|
||||||
|
int count, i;
|
||||||
|
unsigned char *call;
|
||||||
|
|
||||||
|
/* printf("Got packet size %d\n", size);*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Decode the AX.25 Packet
|
||||||
|
*/
|
||||||
|
/* Find packet, skip over flag */
|
||||||
|
bptr = buf+1;
|
||||||
|
/* Now at destination address */
|
||||||
|
/* print_call(bptr);
|
||||||
|
printf("<-");*/
|
||||||
|
bptr += AXALEN;
|
||||||
|
|
||||||
|
/* Now at source address */
|
||||||
|
/* print_call(bptr);*/
|
||||||
|
if (bptr[6] & E_BIT)
|
||||||
|
{
|
||||||
|
/* printf("\n");*/
|
||||||
|
return -1; /* No digis, we're not interested */
|
||||||
|
}
|
||||||
|
/* printf(" ");*/
|
||||||
|
bptr += AXALEN;
|
||||||
|
/* Now at digipeaters */
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
while( count < AX25_MAX_DIGIS && ( (bptr - buf) < size))
|
||||||
|
{
|
||||||
|
/* print_call(bptr);
|
||||||
|
printf(", ");*/
|
||||||
|
if (bptr[6] & REPEATED)
|
||||||
|
{
|
||||||
|
/* This one has been repeated, move to next one */
|
||||||
|
bptr += AXALEN;
|
||||||
|
count++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* Check to see if callsign is one of ours */
|
||||||
|
for (i = 0; i < port_count; i++)
|
||||||
|
{
|
||||||
|
/* printf("compare ");
|
||||||
|
print_call(bptr);
|
||||||
|
printf(" ");
|
||||||
|
print_call(portcall[i]);
|
||||||
|
printf("\n");*/
|
||||||
|
if ( (bcmp(bptr, portcall[i], AXALEN-1) == 0) && ((bptr[6] & 0x1e) == portcall[i][6]))
|
||||||
|
{
|
||||||
|
/* Copy new address over and turn on repeated bit*/
|
||||||
|
call = find_call(port);
|
||||||
|
if (call == NULL)
|
||||||
|
return -1;
|
||||||
|
bcopy(call, bptr, AXALEN-1);
|
||||||
|
bptr[6] = (bptr[6] & ~0x1e) | call[6];
|
||||||
|
bptr[6] |= REPEATED;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} /* for */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_call(unsigned char *bptr)
|
||||||
|
{
|
||||||
|
printf("%c%c%c%c%c%c-%d", bptr[0] >> 1, bptr[1] >> 1,
|
||||||
|
bptr[2] >> 1, bptr[3] >> 1, bptr[4] >> 1, bptr[5] >> 1,
|
||||||
|
(bptr[6] >> 1) & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_port(char *call, char *port)
|
||||||
|
{
|
||||||
|
unsigned char *s;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (port_count == MAX_PORTS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s = portcall[port_count];
|
||||||
|
|
||||||
|
while( (*call != '-') && ( (int)(s - portcall[port_count])< 6))
|
||||||
|
*s++ = (*call++) << 1;
|
||||||
|
call++; /* skip over dash */
|
||||||
|
n = atoi(call);
|
||||||
|
*s = n << 1;
|
||||||
|
|
||||||
|
strcpy(portname[port_count], port);
|
||||||
|
port_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char *find_call(char *port)
|
||||||
|
{
|
||||||
|
static unsigned char callsign[8];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < port_count; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(port, portname[i]) == 0)
|
||||||
|
{
|
||||||
|
bcopy(portcall[i], callsign, 7);
|
||||||
|
return callsign;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (char*)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_interfaces(int skt)
|
||||||
|
{
|
||||||
|
char buf[1024];
|
||||||
|
struct ifconf ifc;
|
||||||
|
struct ifreq *ifr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ifc.ifc_len = sizeof(buf);
|
||||||
|
ifc.ifc_buf = buf;
|
||||||
|
if (ioctl(skt, SIOCGIFCONF, &ifc) < 0)
|
||||||
|
{
|
||||||
|
perror("ioctl");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ifr = ifc.ifc_req;
|
||||||
|
for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++)
|
||||||
|
{
|
||||||
|
if (ioctl(skt, SIOCGIFHWADDR, ifr) < 0)
|
||||||
|
continue;
|
||||||
|
if (ifr->ifr_hwaddr.sa_family == AF_AX25)
|
||||||
|
{
|
||||||
|
/* AX25 port, add to list */
|
||||||
|
if (port_count < MAX_PORTS)
|
||||||
|
{
|
||||||
|
bcopy(ifr->ifr_hwaddr.sa_data, portcall[port_count], 7);
|
||||||
|
strcpy(portname[port_count], ifr->ifr_name);
|
||||||
|
port_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* for */
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,300 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
static void expand_string(char *dest, char *src, int argc, char **argv)
|
||||||
|
{
|
||||||
|
char tmpbuf[64], def[64];
|
||||||
|
char *p1, *p2, *cp;
|
||||||
|
int n, skip, nocopy;
|
||||||
|
|
||||||
|
if (strchr(src, '%') == NULL) {
|
||||||
|
strcpy(dest, src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p1 = src;
|
||||||
|
p2 = dest;
|
||||||
|
while (*p1) {
|
||||||
|
if (*p1 == '%') {
|
||||||
|
nocopy=1;
|
||||||
|
p1++;
|
||||||
|
skip = 1;
|
||||||
|
def[0] = 0;
|
||||||
|
if (*p1 == '{') {
|
||||||
|
p1++;
|
||||||
|
if ((cp = strchr(p1, '}')) != NULL) {
|
||||||
|
skip = cp - p1 + 1;
|
||||||
|
cp = p1;
|
||||||
|
if (*++cp == ':') {
|
||||||
|
cp++;
|
||||||
|
n = min(skip - 3, 63);
|
||||||
|
strncpy(def, cp, n);
|
||||||
|
def[n] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (*p1) {
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
strcpy(tmpbuf, User.call);
|
||||||
|
if ((cp = strrchr(tmpbuf, '-'))) *cp = 0;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
strcpy(tmpbuf, User.call);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
strcpy(tmpbuf, User.ul_name);
|
||||||
|
if ((cp = strrchr(tmpbuf, '-'))) *cp = 0;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
strcpy(tmpbuf, User.ul_name);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
switch (User.ul_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
strcpy(tmpbuf, "flexnet");
|
||||||
|
break;
|
||||||
|
case AF_AX25:
|
||||||
|
strcpy(tmpbuf, "ax25");
|
||||||
|
break;
|
||||||
|
case AF_NETROM:
|
||||||
|
strcpy(tmpbuf, "netrom");
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
strcpy(tmpbuf, "rose");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
strcpy(tmpbuf, "inet");
|
||||||
|
break;
|
||||||
|
case AF_UNSPEC:
|
||||||
|
strcpy(tmpbuf, "host");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
n = *p1 - '0';
|
||||||
|
if (n < argc) strcpy(tmpbuf, argv[n]);
|
||||||
|
else strcpy(tmpbuf, def);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
nocopy=0;
|
||||||
|
for(n=2;n<argc;n++) {
|
||||||
|
if (argv[n]==NULL) break;
|
||||||
|
strcpy(tmpbuf, argv[n]);
|
||||||
|
if (isalpha(*p1)) {
|
||||||
|
if (isupper(*p1)) strupr(tmpbuf);
|
||||||
|
else strlwr(tmpbuf);
|
||||||
|
}
|
||||||
|
strcpy(p2, tmpbuf);
|
||||||
|
p2 += strlen(tmpbuf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy(tmpbuf, "%");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nocopy==1) {
|
||||||
|
if (isalpha(*p1)) {
|
||||||
|
if (isupper(*p1)) strupr(tmpbuf);
|
||||||
|
else strlwr(tmpbuf);
|
||||||
|
}
|
||||||
|
strcpy(p2, tmpbuf);
|
||||||
|
p2 += strlen(tmpbuf);
|
||||||
|
}
|
||||||
|
p1 += skip;
|
||||||
|
} else
|
||||||
|
*p2++ = *p1++;
|
||||||
|
}
|
||||||
|
*p2 = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is straight from *NOS */
|
||||||
|
|
||||||
|
static char *parse_string(char *str)
|
||||||
|
{
|
||||||
|
char *cp = str;
|
||||||
|
unsigned long num;
|
||||||
|
|
||||||
|
while (*str != '\0' && *str != '\"') {
|
||||||
|
if (*str == '\\') {
|
||||||
|
str++;
|
||||||
|
switch (*str++) {
|
||||||
|
case 'n': *cp++ = '\n'; break;
|
||||||
|
case 't': *cp++ = '\t'; break;
|
||||||
|
case 'v': *cp++ = '\v'; break;
|
||||||
|
case 'b': *cp++ = '\b'; break;
|
||||||
|
case 'r': *cp++ = '\r'; break;
|
||||||
|
case 'f': *cp++ = '\f'; break;
|
||||||
|
case 'a': *cp++ = '\007'; break;
|
||||||
|
case '\\': *cp++ = '\\'; break;
|
||||||
|
case '\"': *cp++ = '\"'; break;
|
||||||
|
case 'x':
|
||||||
|
num = strtoul(--str, &str, 16);
|
||||||
|
*cp++ = (char) num;
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
num = strtoul(--str, &str, 8);
|
||||||
|
*cp++ = (char) num;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
return NULL;
|
||||||
|
default:
|
||||||
|
*cp++ = *(str - 1);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
*cp++ = *str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*str == '\"') str++; /* skip final quote */
|
||||||
|
*cp = '\0'; /* terminate string */
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_args(char **argv, char *cmd)
|
||||||
|
{
|
||||||
|
int ct = 0;
|
||||||
|
int quoted;
|
||||||
|
|
||||||
|
while (ct < 31) {
|
||||||
|
quoted = 0;
|
||||||
|
while (*cmd && isspace(*cmd)) cmd++;
|
||||||
|
if (*cmd == 0) break;
|
||||||
|
if (*cmd == '"') {
|
||||||
|
quoted++;
|
||||||
|
cmd++;
|
||||||
|
}
|
||||||
|
argv[ct++] = cmd;
|
||||||
|
if (quoted) {
|
||||||
|
if ((cmd = parse_string(cmd)) == NULL)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
while (*cmd && !isspace(*cmd)) cmd++;
|
||||||
|
}
|
||||||
|
if (*cmd) *cmd++ = 0;
|
||||||
|
}
|
||||||
|
argv[ct] = NULL;
|
||||||
|
return ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cmdparse(struct cmd *list, char *cmdline)
|
||||||
|
{
|
||||||
|
struct cmd *cmdp;
|
||||||
|
int argc;
|
||||||
|
char *argv[32];
|
||||||
|
static char cmdbuf[1024];
|
||||||
|
|
||||||
|
/* convert cmdline to argc,argv[] if '#' or empty: return */
|
||||||
|
if ((argc = parse_args(argv, cmdline)) == 0 || *argv[0] == '#') return 2;
|
||||||
|
/* check if the command in argv[0] is in the list */
|
||||||
|
for (cmdp = list; cmdp != NULL; cmdp = cmdp->next) {
|
||||||
|
if (strlen(argv[0]) < cmdp->len || strlen(argv[0]) > strlen(cmdp->name)) continue;
|
||||||
|
if (strncasecmp(cmdp->name, argv[0], strlen(argv[0])) == 0) break;
|
||||||
|
}
|
||||||
|
if (cmdp == NULL) return -1;
|
||||||
|
strlwr(argv[0]);
|
||||||
|
switch (cmdp->type) {
|
||||||
|
case CMD_INTERNAL: /* execute internal command */
|
||||||
|
return (*cmdp->function)(argc, argv);
|
||||||
|
case CMD_ALIAS:
|
||||||
|
/* evaluate arguments */
|
||||||
|
expand_string(cmdbuf, cmdp->command, argc, argv);
|
||||||
|
aliascmd=1;
|
||||||
|
/* re-execute the command */
|
||||||
|
return cmdparse(list, cmdbuf);
|
||||||
|
case CMD_EXTERNAL:
|
||||||
|
/* evaluate arguments */
|
||||||
|
expand_string(cmdbuf, cmdp->command, argc, argv);
|
||||||
|
/* convert the cmdline to argc,argv[] */
|
||||||
|
argc = parse_args(argv, cmdbuf);
|
||||||
|
/* execute an external command */
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;32mExecuting command...\e[0m\n");
|
||||||
|
} else {
|
||||||
|
axio_puts("Executing command... \n", NodeIo);
|
||||||
|
}
|
||||||
|
return extcmd(cmdp, argv);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert_cmd(struct cmd **list, struct cmd *new)
|
||||||
|
{
|
||||||
|
struct cmd *tmp, *p;
|
||||||
|
|
||||||
|
if (*list == NULL || strcasecmp(new->name, (*list)->name) < 0) {
|
||||||
|
tmp = *list;
|
||||||
|
*list = new;
|
||||||
|
new->next = tmp;
|
||||||
|
} else {
|
||||||
|
for (p = *list; p->next != NULL; p = p->next)
|
||||||
|
if (strcasecmp(new->name, p->next->name) < 0) break;
|
||||||
|
tmp = p->next;
|
||||||
|
p->next = new;
|
||||||
|
new->next = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int add_internal_cmd(struct cmd **list, char *name, int len, int (*function) (int argc, char **argv))
|
||||||
|
{
|
||||||
|
struct cmd *new;
|
||||||
|
|
||||||
|
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
|
||||||
|
node_perror("add_internal_cmd: calloc", errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
new->name = strdup(name);
|
||||||
|
new->len = len;
|
||||||
|
new->type = CMD_INTERNAL;
|
||||||
|
new->function = function;
|
||||||
|
insert_cmd(list, new);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_cmdlist(struct cmd *list)
|
||||||
|
{
|
||||||
|
struct cmd *tmp;
|
||||||
|
|
||||||
|
while (list != NULL) {
|
||||||
|
free(list->name);
|
||||||
|
free(list->command);
|
||||||
|
free(list->path);
|
||||||
|
tmp = list;
|
||||||
|
list = list->next;
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,485 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <netax25/ax25.h> /* axutils.h needs this... */
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
long IdleTimeout = 360L; /* default to 6 mins */
|
||||||
|
long ConnTimeout = 300L; /* default to 5 mins */
|
||||||
|
int ReConnectTo = 0;
|
||||||
|
int LogLevel = LOGLVL_ERROR;
|
||||||
|
int EscChar = 20; /* CTRL-T */
|
||||||
|
|
||||||
|
char *Email = NULL;
|
||||||
|
char *HostName = NULL;
|
||||||
|
char *NodeId = NULL;
|
||||||
|
char *NrPort = NULL; /* first netrom port */
|
||||||
|
char *FlexId = NULL;
|
||||||
|
char *RoseId = NULL;
|
||||||
|
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
char *Prompt = "\n=> "; /* Prompt by IZ5AWZ */
|
||||||
|
#else
|
||||||
|
char *Prompt = "\n";
|
||||||
|
#endif
|
||||||
|
char *PassPrompt = "\nPassword >"; /* Prompt Password by IZ5AWZ */
|
||||||
|
|
||||||
|
static unsigned long Permissions = 0L;
|
||||||
|
static unsigned long LocalNet = 0L;
|
||||||
|
static unsigned long LocalMask = ~0L;
|
||||||
|
static char *HiddenPorts[32] = {0};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if `port' is a hidden port.
|
||||||
|
*/
|
||||||
|
int is_hidden(const char *port)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; HiddenPorts[i] != NULL && i < 31; i++)
|
||||||
|
if (!strcmp(port, HiddenPorts[i]))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if peer is on "local" or loopback network.
|
||||||
|
*/
|
||||||
|
static int is_local(unsigned long peer)
|
||||||
|
{
|
||||||
|
return ((peer & LocalMask) == LocalNet) || ((peer & 0xff) == 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return non-zero if peer is on amprnet.
|
||||||
|
*/
|
||||||
|
static int is_ampr(unsigned long peer)
|
||||||
|
{
|
||||||
|
return ((peer & 0xff) == 44);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert NOS style width to a netmask in network byte order.
|
||||||
|
*/
|
||||||
|
static unsigned long bits_to_mask(int bits)
|
||||||
|
{
|
||||||
|
return htonl(~0L << (32 - bits));
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_perms(int what, unsigned long peer)
|
||||||
|
{
|
||||||
|
if (what == PERM_TELNET) {
|
||||||
|
if (is_local(peer)) {
|
||||||
|
if (Permissions & PERM_TELNET_LOCAL)
|
||||||
|
return 0;
|
||||||
|
} else if (is_ampr(peer)) {
|
||||||
|
if (Permissions & PERM_TELNET_AMPR)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (Permissions & PERM_TELNET_INET)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((Permissions & what) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read permissions file and return a password if needed or "*" if not.
|
||||||
|
* If user access is denied return NULL.
|
||||||
|
*/
|
||||||
|
char *read_perms(struct user *up, unsigned long peer)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char line[256], *argv[32], *cp;
|
||||||
|
int argc, n = 0;
|
||||||
|
|
||||||
|
if ((fp = fopen(CONF_NODE_PERMS_FILE, "r")) == NULL) {
|
||||||
|
node_perror(CONF_NODE_PERMS_FILE, errno);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((cp = strchr(up->call, '-')) != NULL)
|
||||||
|
*cp = 0;
|
||||||
|
while (fgets(line, 256, fp) != NULL) {
|
||||||
|
n++;
|
||||||
|
argc = parse_args(argv, line);
|
||||||
|
if (argc == 0 || *argv[0] == '#')
|
||||||
|
continue;
|
||||||
|
if (argc != 5) {
|
||||||
|
node_msg("Configuration error");
|
||||||
|
node_log(LOGLVL_ERROR, "Syntax error in permission file at line %d", n);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp(argv[0], "*") && strcasecmp(argv[0], up->call))
|
||||||
|
continue;
|
||||||
|
switch (up->ul_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "flexnet"))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
case AF_AX25:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "ax25"))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
case AF_NETROM:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "netrom"))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "rose"))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "local") && is_local(peer))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "ampr") && is_ampr(peer))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "inet") && !is_local(peer) && !is_ampr(peer))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
case AF_UNSPEC:
|
||||||
|
if (!strcmp(argv[1], "*"))
|
||||||
|
break;
|
||||||
|
if (!strcasecmp(argv[1], "host"))
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (up->ul_type == AF_AX25) {
|
||||||
|
if (strcmp(argv[2], "*") && strcmp(argv[2], up->ul_name))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (cp != NULL)
|
||||||
|
*cp = '-';
|
||||||
|
if ((Permissions = strtoul(argv[4], NULL, 10)) == 0)
|
||||||
|
return NULL;
|
||||||
|
else
|
||||||
|
return strdup(argv[3]);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_alias(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct cmd *new;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
return -1;
|
||||||
|
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
|
||||||
|
node_perror("do_alias: malloc", errno);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
new->name = strdup(argv[1]);
|
||||||
|
while (isupper(new->name[len]))
|
||||||
|
len++;
|
||||||
|
/* Ok. So they can't read... */
|
||||||
|
if (len == 0) {
|
||||||
|
strupr(new->name);
|
||||||
|
len = strlen(new->name);
|
||||||
|
}
|
||||||
|
new->len = len;
|
||||||
|
new->command = strdup(argv[2]);
|
||||||
|
new->type = CMD_ALIAS;
|
||||||
|
insert_cmd(&Nodecmds, new);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_loglevel(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
LogLevel = atoi(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_escape(char *s)
|
||||||
|
{
|
||||||
|
int escape;
|
||||||
|
char *endptr[1];
|
||||||
|
|
||||||
|
if (isdigit(*s)) {
|
||||||
|
escape = strtol(s, endptr, 0);
|
||||||
|
if (**endptr)
|
||||||
|
return -2;
|
||||||
|
else
|
||||||
|
return escape;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(s) == 1)
|
||||||
|
return *s;
|
||||||
|
|
||||||
|
if (strlen(s) == 2 && *s == '^')
|
||||||
|
return (toupper(*++s) - 'A' + 1);
|
||||||
|
|
||||||
|
if (strcasecmp(s, "off") == 0 || strcmp(s, "-1") == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int do_escapechar(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
EscChar = get_escape(argv[1]);
|
||||||
|
|
||||||
|
if (EscChar < -1 || EscChar > 255) {
|
||||||
|
node_msg("Configuration error");
|
||||||
|
node_log(LOGLVL_ERROR, "do_escapechar: Invalid escape character %s",
|
||||||
|
argv[1]);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_idletimeout(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
IdleTimeout = atol(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_conntimeout(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
ConnTimeout = atol(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_hostname(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
HostName = strdup(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_localnet(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
if ((cp = strchr(argv[1], '/')) != NULL) {
|
||||||
|
*cp = 0;
|
||||||
|
LocalMask = bits_to_mask(atoi(++cp));
|
||||||
|
}
|
||||||
|
LocalNet = inet_addr(argv[1]);
|
||||||
|
LocalNet &= LocalMask;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_reconnect(int argc, char **argv)
|
||||||
|
{
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
if (!strcasecmp(argv[1], "on"))
|
||||||
|
ReConnectTo = 1;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
ReConnectTo = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_hiddenports(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
for (i = 1; i < argc && i < 31; i++) {
|
||||||
|
if (ax25_config_get_dev(argv[i]) == NULL) {
|
||||||
|
node_msg("Configuration error");
|
||||||
|
node_log(LOGLVL_ERROR, "do_hiddenports: invalid port %s", argv[i]);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
HiddenPorts[i - 1] = strdup(argv[i]);
|
||||||
|
}
|
||||||
|
HiddenPorts[i - 1] = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_extcmd(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct cmd *new;
|
||||||
|
struct passwd *pw;
|
||||||
|
char buf[1024];
|
||||||
|
int i, len;
|
||||||
|
|
||||||
|
if (argc < 6)
|
||||||
|
return -1;
|
||||||
|
if ((new = calloc(1, sizeof(struct cmd))) == NULL) {
|
||||||
|
node_perror("do_extcmd: malloc", errno);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
new->name = strdup(argv[1]);
|
||||||
|
len = 0;
|
||||||
|
while (isupper(new->name[len]))
|
||||||
|
len++;
|
||||||
|
/* Ok. So they can't read... */
|
||||||
|
if (len == 0) {
|
||||||
|
strupr(new->name);
|
||||||
|
len = strlen(new->name);
|
||||||
|
}
|
||||||
|
new->len = len;
|
||||||
|
new->flags = atoi(argv[2]);
|
||||||
|
if ((pw = getpwnam(argv[3])) == NULL) {
|
||||||
|
node_msg("Configuration error");
|
||||||
|
node_log(LOGLVL_ERROR, "do_extcmd: Unknown user %s", argv[3]);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
new->uid = pw->pw_uid;
|
||||||
|
new->gid = pw->pw_gid;
|
||||||
|
new->path = strdup(argv[4]);
|
||||||
|
len = 0;
|
||||||
|
for (i = 0; argv[i + 5] != NULL; i++) {
|
||||||
|
sprintf(&buf[len], "\"%s\" ", argv[i + 5]);
|
||||||
|
len = strlen(buf);
|
||||||
|
}
|
||||||
|
new->command = strdup(buf);
|
||||||
|
new->type = CMD_EXTERNAL;
|
||||||
|
insert_cmd(&Nodecmds, new);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_nodeid(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
NodeId = strdup(argv[1]);
|
||||||
|
} else if (User.ul_type != AF_NETROM) {
|
||||||
|
NodeId = strdup(argv[1]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_flexid(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2 )
|
||||||
|
return -1;
|
||||||
|
FlexId = ("%s ;" , strdup(argv[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_roseid(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2 )
|
||||||
|
return -1;
|
||||||
|
RoseId = ("%s ;" , strdup(argv[1]));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_prompt(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if ((User.ul_type != AF_NETROM) || (User.ul_type != AF_INET)) {
|
||||||
|
if (argc < 2) {
|
||||||
|
return -1;
|
||||||
|
Prompt = strdup(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_passprompt(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (User.ul_type != AF_NETROM) {
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
PassPrompt = strdup(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_nrport(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
NrPort = strdup(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int do_email(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
Email = strdup(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_config(void)
|
||||||
|
{
|
||||||
|
struct cmd *cfg_cmds = NULL;
|
||||||
|
FILE *fp;
|
||||||
|
char line[256];
|
||||||
|
int ret, n = 0;
|
||||||
|
|
||||||
|
add_internal_cmd(&cfg_cmds, "alias", 5, do_alias);
|
||||||
|
add_internal_cmd(&cfg_cmds, "conntimeout", 11, do_conntimeout);
|
||||||
|
add_internal_cmd(&cfg_cmds, "email", 5, do_email);
|
||||||
|
add_internal_cmd(&cfg_cmds, "escapechar", 10, do_escapechar);
|
||||||
|
add_internal_cmd(&cfg_cmds, "extcmd", 6, do_extcmd);
|
||||||
|
add_internal_cmd(&cfg_cmds, "hiddenports", 11, do_hiddenports);
|
||||||
|
add_internal_cmd(&cfg_cmds, "hostname", 8, do_hostname);
|
||||||
|
add_internal_cmd(&cfg_cmds, "idletimeout", 11, do_idletimeout);
|
||||||
|
add_internal_cmd(&cfg_cmds, "localnet", 8, do_localnet);
|
||||||
|
add_internal_cmd(&cfg_cmds, "loglevel", 8, do_loglevel);
|
||||||
|
add_internal_cmd(&cfg_cmds, "nodeid", 6, do_nodeid);
|
||||||
|
add_internal_cmd(&cfg_cmds, "flexid", 6, do_flexid);
|
||||||
|
add_internal_cmd(&cfg_cmds, "roseid", 6, do_roseid);
|
||||||
|
add_internal_cmd(&cfg_cmds, "prompt", 6, do_prompt);
|
||||||
|
add_internal_cmd(&cfg_cmds, "nrport", 6, do_nrport);
|
||||||
|
add_internal_cmd(&cfg_cmds, "reconnect", 8, do_reconnect);
|
||||||
|
add_internal_cmd(&cfg_cmds, "passprompt", 6, do_passprompt);
|
||||||
|
|
||||||
|
if ((fp = fopen(CONF_NODE_FILE, "r")) == NULL) {
|
||||||
|
node_perror(CONF_NODE_FILE, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while (fgets(line, 256, fp) != NULL) {
|
||||||
|
n++;
|
||||||
|
ret = cmdparse(cfg_cmds, line);
|
||||||
|
if (ret == -1) {
|
||||||
|
node_msg("Configuration error");
|
||||||
|
node_log(LOGLVL_ERROR, "Syntax error in config file at line %d: %s", n, line);
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
fclose(fp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
free_cmdlist(cfg_cmds);
|
||||||
|
cfg_cmds = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some global #defines for programmers to use for conditional compilation
|
||||||
|
*/
|
||||||
|
@HAVEAX25@
|
||||||
|
@HAVEFLEX@
|
||||||
|
@HAVEROSE@
|
||||||
|
@HAVENETROM@
|
||||||
|
@HAVEZLIB@
|
||||||
|
@HAVEMHEARD@
|
||||||
|
@HAVETCPIP@
|
||||||
|
#define PROC_AX25_CALLS_FILE "/proc/net/ax25_calls"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* node specific
|
||||||
|
*/
|
||||||
|
#define CONF_NODE_FILE "@ETC_DIR@/uronode.conf"
|
||||||
|
#define CONF_NODE_PERMS_FILE "@ETC_DIR@/uronode.perms"
|
||||||
|
@HAVEMOTD@ @MOTDPATH@
|
||||||
|
#define CONF_NODE_INFO_FILE "@ETC_DIR@/uronode.info"
|
||||||
|
#define AX_ROUTES_FILE "@ETC_DIR@/uronode.routes"
|
||||||
|
#define CONF_USERS_FILE "@ETC_DIR@/uronode.users"
|
||||||
|
#define FLEXD_CONF_FILE "@ETC_DIR@/flexd.conf"
|
||||||
|
#define FLEXD_TEMP_PATH "@VAR_DIR@/flex/"
|
||||||
|
#define FLEXD_PID_FILE "/var/run/flexd.pid"
|
||||||
|
#define FLEX_GT_FILE "@VAR_DIR@/flex/gateways"
|
||||||
|
#define FLEX_DST_FILE "@VAR_DIR@/flex/destinations"
|
||||||
|
#define DATA_MHEARD_FILE "@VAR_DIR@/mheard/mheard.dat"
|
||||||
|
#define DATA_NODE_LOGIN_FILE "@VAR_DIR@/node/loggedin"
|
||||||
|
#define DATA_NODE_HELP_DIR "@VAR_DIR@/node/help/"
|
||||||
|
#define DATA_NODE_LAST_FILE "@VAR_DIR@/node/lastlog"
|
||||||
|
#define DATA_NODE_IP_FILE "@VAR_DIR@/node/iplog"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,303 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
_sleep()
|
||||||
|
{
|
||||||
|
[ "$NON_INTERACTIVE" = 1 ] || sleep "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
_whiptail()
|
||||||
|
{
|
||||||
|
[ "$NON_INTERACTIVE" = 1 ] || whiptail "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Cleaning the directory for a fresh configuration..."
|
||||||
|
_sleep 2
|
||||||
|
make distclean > make.debug
|
||||||
|
|
||||||
|
ETC_DIR=/usr/local/etc/ax25
|
||||||
|
SBIN_DIR=/usr/local/sbin
|
||||||
|
BIN_DIR=/usr/local/bin
|
||||||
|
LIB_DIR=/usr/local/lib
|
||||||
|
MAN_DIR=/usr/local/share/man
|
||||||
|
VAR_DIR=/usr/local/var/ax25
|
||||||
|
|
||||||
|
echo "Welcome to the configuration utility for URONode. This configure script"
|
||||||
|
echo "will very simply and easily guide you into installling URONode with as"
|
||||||
|
echo "very little trouble as possible. All you need to really do is simply"
|
||||||
|
echo "answer the following questions below properly. If you make a mistake"
|
||||||
|
echo "just break out of it (ctrl+c) and rerun ./configure. Let's get started!"
|
||||||
|
_sleep 1
|
||||||
|
echo " "
|
||||||
|
_sleep 1
|
||||||
|
echo -n "you need gcc to build URONode: "
|
||||||
|
GCC=`which gcc`
|
||||||
|
_sleep 2
|
||||||
|
if [ -e "$GCC" ]
|
||||||
|
then
|
||||||
|
echo -n "saw $GCC... "
|
||||||
|
_sleep 1
|
||||||
|
echo "GCC found! Congratulations!!"
|
||||||
|
else
|
||||||
|
echo "gcc not found!"
|
||||||
|
echo " "
|
||||||
|
echo "You need this compiler to build URONode."
|
||||||
|
echo "Please install gcc, and rerun this ./configure script."
|
||||||
|
echo "If you have a copy of gcc installed, please insure you have a"
|
||||||
|
echo "symlink by typing as root: ln -s /usr/bin/gcc-#.## /usr/bin/gcc"
|
||||||
|
echo "and rerun ./configure to continue."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo -n "Your machine architecture is: "
|
||||||
|
_sleep 1
|
||||||
|
ARCH=`uname -m`
|
||||||
|
echo $ARCH
|
||||||
|
_sleep 1
|
||||||
|
echo -n "Checking for the existence of the Zlib headers... "
|
||||||
|
ZLIB=""
|
||||||
|
HAVEZLIB="#undef HAVE_ZLIB"
|
||||||
|
for zlibdir in /usr/include /usr/local/include
|
||||||
|
do
|
||||||
|
if [ -f $zlibdir/zlib.h ]
|
||||||
|
then
|
||||||
|
echo $zlibdir/zlib.h
|
||||||
|
ZLIB="-lz"
|
||||||
|
HAVEZLIB="#define HAVE_ZLIB 1"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if [ -z "$ZLIB" ]
|
||||||
|
then
|
||||||
|
echo "not found."
|
||||||
|
echo " Without Zlib Node will lack compression support"
|
||||||
|
echo " See INSTALL for more information."
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Global protocol definition symbols for programmers that want to conditionally
|
||||||
|
# compile
|
||||||
|
HAVEAX25="#undef HAVE_AX25"
|
||||||
|
HAVEFLEX="#undef HAVE_FLEX"
|
||||||
|
FLEXNET=" "
|
||||||
|
IN="#"
|
||||||
|
HAVENETROM="#undef HAVE_NETROM"
|
||||||
|
HAVEROSE="#undef HAVE_ROSE"
|
||||||
|
HAVEMHEARD="#undef HAVE_MHEARD"
|
||||||
|
HAVETCPIP="#undef HAVE_TCPIP"
|
||||||
|
HAVEMOTD="#undef HAVE_MOTD"
|
||||||
|
MOTDPATH=
|
||||||
|
# echo -n "Include support for the AX.25 protocol ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-ax25"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support AX25?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVEAX25="#define HAVE_AX25 1"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# echo -n "Include support for the FlexNet protocol ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-flexnet"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support FlexNet?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVEAX25="#define HAVE_AX25 1"
|
||||||
|
HAVEFLEX="#define HAVE_FLEX 1"
|
||||||
|
FLEXNET="flexd"
|
||||||
|
IN=""
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# echo -n "Include support for the NetRom protocol ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-netrom"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support NetRom?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVEAX25="#define HAVE_AX25 1"
|
||||||
|
HAVENETROM="#define HAVE_NETROM 1"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# echo -n "Include support for the Rose protocol ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-rose"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support ROSE?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVEAX25="#define HAVE_AX25 1"
|
||||||
|
HAVEROSE="#define HAVE_ROSE 1"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# echo -n "Include support for MHeard ports listen ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-mheard"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support MHeard?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVEAX25="#define HAVE_AX25 1"
|
||||||
|
HAVEMHEARD="#define HAVE_MHEARD 1"
|
||||||
|
fi
|
||||||
|
#
|
||||||
|
# echo -n "Include support for TCP/IP functions ? [Y/n]: "; read answer
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" = 1 ]
|
||||||
|
then
|
||||||
|
echo "$@" | grep -vqe "--without-tcpip"
|
||||||
|
else
|
||||||
|
whiptail --title "URONode Options:" --yesno "Support TCP/IP?" 7 22
|
||||||
|
fi
|
||||||
|
if [ $? -ne 1 ]
|
||||||
|
then
|
||||||
|
HAVETCPIP="#define HAVE_TCPIP 1"
|
||||||
|
HAVEMOTD="#define HAVEMOTD"
|
||||||
|
MOTDPATH='"/etc/ax25/uronode.motd"'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating Makefile"
|
||||||
|
|
||||||
|
sed -e "s~@FLEXNET@~$FLEXNET~g; \
|
||||||
|
s~@IN@~$IN~g" <Makefile.in > Makefile
|
||||||
|
|
||||||
|
echo "Creating Makefile.include"
|
||||||
|
|
||||||
|
sed -e "s~@ARCH@~$ARCH~g; \
|
||||||
|
s~@ETC_DIR@~$ETC_DIR~g; \
|
||||||
|
s~@LIB_DIR@~$LIB_DIR~g; \
|
||||||
|
s~@SBIN_DIR@~$SBIN_DIR~g; \
|
||||||
|
s~@BIN_DIR@~$BIN_DIR~g; \
|
||||||
|
s~@VAR_DIR@~$VAR_DIR~g; \
|
||||||
|
s~@MAN_DIR@~$MAN_DIR~g; \
|
||||||
|
s~@ZLIB@~$ZLIB~g" <Makefile.include.in >Makefile.include
|
||||||
|
|
||||||
|
echo "Creating config.h"
|
||||||
|
|
||||||
|
sed -e "s~@ETC_DIR@~$ETC_DIR~g; \
|
||||||
|
s~@LIB_DIR@~$LIB_DIR~g; \
|
||||||
|
s~@SBIN_DIR@~$SBIN_DIR~g; \
|
||||||
|
s~@BIN_DIR@~$BIN_DIR~g; \
|
||||||
|
s~@VAR_DIR@~$VAR_DIR~g; \
|
||||||
|
s~@MAN_DIR@~$MAN_DIR~g; \
|
||||||
|
s~@HAVEAX25@~$HAVEAX25~g; \
|
||||||
|
s~@HAVEFLEX@~$HAVEFLEX~g; \
|
||||||
|
s~@HAVENETROM@~$HAVENETROM~g; \
|
||||||
|
s~@HAVEROSE@~$HAVEROSE~g; \
|
||||||
|
s~@HAVEMHEARD@~$HAVEMHEARD~g; \
|
||||||
|
s~@HAVETCPIP@~$HAVETCPIP~g; \
|
||||||
|
s~@HAVEMOTD@~$HAVEMOTD~g; \
|
||||||
|
s~@MOTDPATH@~$MOTDPATH~g; \
|
||||||
|
s~@HAVEZLIB@~$HAVEZLIB~g" <config.h.in >config.h
|
||||||
|
|
||||||
|
echo "Creating dependancy files..."
|
||||||
|
make depend > /dev/null 2>&1
|
||||||
|
echo "Configuration successful!!"
|
||||||
|
_sleep 1
|
||||||
|
echo "about the authors..."
|
||||||
|
_sleep 3
|
||||||
|
echo "URONode is a combined effort of years worth of work. Those who's code"
|
||||||
|
echo "is included in this flavor of a linux based node are:"
|
||||||
|
_sleep 1
|
||||||
|
echo "Brian Rogers N1URO (current maintainer), "
|
||||||
|
_sleep 1
|
||||||
|
echo "Marius Petrescu YO2LOJ (current team member),"
|
||||||
|
_sleep 1
|
||||||
|
echo "Bob Tenty VE3TOK (current team member),"
|
||||||
|
_sleep 1
|
||||||
|
echo "Stefano Noferi IZ5AWZ (AWZNode)"
|
||||||
|
_sleep 1
|
||||||
|
echo -n "Tomi Manninen OH2BNS, "
|
||||||
|
_sleep 1
|
||||||
|
echo -n "Alan Cox GW4PTS, "
|
||||||
|
_sleep 1
|
||||||
|
echo "and Roy Van Zundert PE1RJA"
|
||||||
|
echo ""
|
||||||
|
_sleep 1
|
||||||
|
echo "Special thanks to: Morgan, sm6tky for his security report"
|
||||||
|
echo "and Barry K2MF for his input on some of my routines and supplying"
|
||||||
|
echo "some source code."
|
||||||
|
_sleep 1
|
||||||
|
echo ""
|
||||||
|
#echo -n "Shall I run the make command for you ? [Y/n]: "
|
||||||
|
_whiptail --title "Shall I make URONode?" --yesno "Yes to make or No to exit" 7 30
|
||||||
|
# if [ "$answer" = "Y" -o "$answer" = "y" -o "$answer" = "" ]
|
||||||
|
if [ "$NON_INTERACTIVE" != 1 -a $? -ne 1 ]
|
||||||
|
then
|
||||||
|
# echo "Making URONode! Please be patient."
|
||||||
|
# _sleep 1
|
||||||
|
# echo "compile errors will be in make.debug."
|
||||||
|
# echo ""
|
||||||
|
# _sleep 1
|
||||||
|
# echo "You may not see anything until the process is complete..."
|
||||||
|
_whiptail --title "Making URONODE..." --msgbox "Making. Check make.debug for errors. Hit OK to continue. You may not see anything for a minute..." 10 45
|
||||||
|
make >> make.debug
|
||||||
|
echo "let's check for binary errors..."
|
||||||
|
_sleep 1
|
||||||
|
echo -n "nodeusers: "
|
||||||
|
_sleep 1
|
||||||
|
if [ -x ./nodeusers ]; then
|
||||||
|
echo "SUCCESS!"
|
||||||
|
else
|
||||||
|
echo "FAILED!"
|
||||||
|
fi
|
||||||
|
_sleep 1
|
||||||
|
echo -n "uronode: "
|
||||||
|
_sleep 1
|
||||||
|
if [ -x ./uronode ]; then
|
||||||
|
echo "SUCCESS!"
|
||||||
|
else
|
||||||
|
echo "FAILED!"
|
||||||
|
fi
|
||||||
|
_sleep 1
|
||||||
|
echo -n "axdigi: "
|
||||||
|
_sleep 1
|
||||||
|
if [ -x ./axdigi ]; then
|
||||||
|
echo "SUCCESS!"
|
||||||
|
fi
|
||||||
|
_sleep 1
|
||||||
|
echo -n "flexd: "
|
||||||
|
_sleep 1
|
||||||
|
if [ -x ./flexd ]; then
|
||||||
|
echo "SUCCESS!"
|
||||||
|
_sleep 1
|
||||||
|
else
|
||||||
|
echo "FAILED! - perhaps you didn't want flexnet?"
|
||||||
|
echo "This is not an error if you chose NO to flexnet."
|
||||||
|
echo "This only means the flexnet daemon binary was not found."
|
||||||
|
echo ""
|
||||||
|
echo "Process complete!"
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
_sleep 1
|
||||||
|
_whiptail --title "URONode" --msgbox "Check the file make.debug if you had errors. If no errors, type: make install (new install) or make upgrade (existing install) and edit your files in /usr/local/etc/ax25/\n\n**WARNING: if you haven't already, add the following to your startup scripts:\n/usr/local/sbin/axdigi & \nto insure cross-port digipeating.\n\nFor help and release news join the forum at\nhttps://www.n1uro.net/forum\n\nEnjoy URONode - 73 de Brian N1URO" 20 50
|
||||||
|
|
||||||
|
# echo "Check the file make.debug if you had errors."
|
||||||
|
# echo "If no errors, type: make install or make upgrade"
|
||||||
|
# echo "and edit your files in /etc/ax25/"
|
||||||
|
# echo "**WARNING: if you haven't already, add the following to your"
|
||||||
|
# echo "startup scripts:"
|
||||||
|
# echo "/usr/sbin/axdigi &"
|
||||||
|
# echo "to insure cross-port digipeating."
|
||||||
|
# echo ""
|
||||||
|
# echo "For support and release news join the forum"
|
||||||
|
# echo "at https://www.n1uro.net/forum"
|
||||||
|
# echo ""
|
||||||
|
# echo "Enjoy URONode! 73 de N1URO."
|
||||||
|
fi
|
||||||
|
exit 0
|
|
@ -0,0 +1,20 @@
|
||||||
|
# URONode axdigi module
|
||||||
|
# load using /usr/sbin/axdigi &
|
||||||
|
#
|
||||||
|
#print debuginfo on/off
|
||||||
|
Debug off
|
||||||
|
#
|
||||||
|
#The digi call
|
||||||
|
MyCall xx0xx
|
||||||
|
#
|
||||||
|
# on use ssid 0-15 for digicall ,off use only ssid of mycall
|
||||||
|
IgnoreSSID on
|
||||||
|
#
|
||||||
|
#number of entrys for autorouting
|
||||||
|
lookupsize 100
|
||||||
|
#
|
||||||
|
#timeout auto routing data in sec.
|
||||||
|
TIMEOUT 3600
|
||||||
|
#
|
||||||
|
DefaultPort ln.tue
|
||||||
|
#
|
|
@ -0,0 +1,14 @@
|
||||||
|
# /etc/ax25/flexd.conf URONode example configuration file
|
||||||
|
# see man flexd.conf
|
||||||
|
|
||||||
|
# The callsign-ssid you wish to poll your flex neighbor with:
|
||||||
|
|
||||||
|
MyCall xx0xx
|
||||||
|
|
||||||
|
# How often do we poll our flex neighbor (in seconds):
|
||||||
|
|
||||||
|
PollInterval 300
|
||||||
|
|
||||||
|
# The FlexNet node we're to poll:
|
||||||
|
|
||||||
|
FlexGate xx0xx-#
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Bye
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Disconnects you from this node.
|
|
@ -0,0 +1,18 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
<none>
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Adds ANSI color to the system for you. Send a message to
|
||||||
|
the sysop and request that they add 512 to your permissions
|
||||||
|
flag for the interface(s) you connect in from to get the
|
||||||
|
color schema. You *must* use an ANSI compliant terminal such
|
||||||
|
as Qmodem, Telix, telnet, etc.
|
||||||
|
Interfaces available: Schema:
|
||||||
|
ax25 ax25 - yellow
|
||||||
|
netrom netrom - cyan
|
||||||
|
internet internet- magenta
|
||||||
|
amprnet system - white
|
||||||
|
localhost starts - green
|
||||||
|
stops - red
|
||||||
|
alarms - flashing red
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Connect <call | alias> [s|d] For NET/ROM or Links
|
||||||
|
Connect <intf> <call> [via <digi1> ...] [s|d] For AX25
|
||||||
|
Connect <call> <address> [<digi>] [d|s] For ROSE
|
||||||
|
Connect <destination> [s|d] For FlexNet
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Initiates an AX25, NET/ROM, ROSE or Flexnet connection to a
|
||||||
|
remote host. If more than two parameters are entered and the
|
||||||
|
second parameter is ten charachers in length then it is
|
||||||
|
interpreted as a ROSE connection, otherwise the first
|
||||||
|
parameter is interpreted as a port name and AX25 is used
|
||||||
|
to make the connection via that port. If only one parameter
|
||||||
|
is given the connection is made searching for the callsign
|
||||||
|
in NET/ROM nodes, in AX25 Fixed links, in FlexNet destinations
|
||||||
|
and last in Mheard database in this order.
|
||||||
|
|
||||||
|
If a single `s' is entered as the last parameter, then when
|
||||||
|
the remote host disconnects you will be returned to this node.
|
||||||
|
If a single `d' is entered as the last parameter, you will
|
||||||
|
be disconnected from this node too. Default behaviour depends
|
||||||
|
on how the user connects in:
|
||||||
|
NetRom - defaults to disconnect
|
||||||
|
all others - defaults to reconnect
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Dest [*|<nodecall>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows the FlexNet destination table of the local node. The
|
||||||
|
destinations on this list can be reached using the Connect
|
||||||
|
command without knowing the actual network path used
|
||||||
|
(assuming the network is OK).
|
||||||
|
|
||||||
|
The optional parameter * toggles verbose mode, showing the
|
||||||
|
ssid mask, the round-trip-time and the path used to reach each
|
||||||
|
node. You can also specify a node callsign to get the verbose
|
||||||
|
information for a single node.
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Escape <escape char>
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Sets the character will be treated as the signal to close down any
|
||||||
|
open connection made from the node.
|
||||||
|
|
||||||
|
You can specify the escape character in a number of ways. They are:
|
||||||
|
|
||||||
|
<char> the actual binary character
|
||||||
|
^T to set it to Control-T (or any other control character)
|
||||||
|
0xNN to set it to hexadecimal value NN
|
||||||
|
0NNN to set it to Octal value NNN
|
||||||
|
NNN to set it to decimal value NNN (no leading zero!)
|
||||||
|
-1 to disable this feature
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Finger [<username>][@<hostname>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Retrieves information about users of a system. If the user
|
||||||
|
name is omitted, shows the users currently logged on the
|
||||||
|
host. If the hostname is omitted, defaults to the local host.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
finger @aripisa.ampr.org
|
||||||
|
finger iz5awz@aripisa.ampr.org
|
||||||
|
finger iz5awz
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Help [<command>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Gives help for the specified command or this text if no
|
||||||
|
command is specified. Commands can not be abbreviated.
|
||||||
|
Use the "?" command to retrieve a list of available commands,
|
||||||
|
except for the COLOR command which you need to contact your
|
||||||
|
sysop to add. "Help color" to see about the color schema.
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Host <hostname>|<ip address>
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Tells information about an Internet host. The host can be identified
|
||||||
|
using a host name (for example, aripisa.ampr.org) or an IP
|
||||||
|
address (for example, 44.134.208.29).
|
||||||
|
|
||||||
|
Returns the host name, IP addresses and known aliases for the host.
|
||||||
|
The information is gathered from the DNS (domain name service).
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Info
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Displays the version information and the contents of the
|
||||||
|
/etc/ax25/uronode.info file, which describes those aspects of
|
||||||
|
the system that the sysop likes to brag about.
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Links [ d | n | v | <call>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows the AX25 link table of the local node. The destinations
|
||||||
|
on this list can be reached using the Connect command without
|
||||||
|
knowing the actual network path used (assuming the network is OK).
|
||||||
|
|
||||||
|
The optional parameter d show the AX25 nodes directly linked.
|
||||||
|
The optional parameter n show the AX25 nodes linked connecting
|
||||||
|
another node and passing a string type "C XX0XX".
|
||||||
|
The optional parameter v show the AX25 links via digipeaters.
|
||||||
|
|
||||||
|
You can also specify a destination callsign to get the verbose
|
||||||
|
information for a single destination.
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Mail
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Access your mailbox and send mail to other users
|
||||||
|
if you have mail waiting.
|
||||||
|
(only available for sysops and some users).
|
||||||
|
|
||||||
|
Note: this feature is initially disabled, contact the sysop
|
||||||
|
if you like to have it enabled.
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
MEssage <callsign or user@domain>
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
|
||||||
|
Send email to users (now only available for messages to sysop).
|
||||||
|
Note: sysop has to enable your mail flag for you to be able to
|
||||||
|
receive mail, otherwise you may only send from here.
|
||||||
|
|
||||||
|
*Sysop Note: use your adduser or userconf program and create
|
||||||
|
the users account as well as adding the mail flag to the
|
||||||
|
configuration file. Select: /bin/false for a shell.
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Mheard [<port>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Gives a list of heard AX25 stations on all ports and, if
|
||||||
|
specified, on the specified port.
|
||||||
|
Use the "Ports" command to get a list of available ports.
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
MSg <call> <message>
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Sends a one-line message to another user of the node. The user
|
||||||
|
in question must be in idle state (ie. not connected/connecting
|
||||||
|
anywhere or running a program).
|
||||||
|
|
||||||
|
If the user has an SSID other than zero, the SSID must be
|
||||||
|
specified. If multiple users are logged in with the same
|
||||||
|
callsign/SSID pair, those who are in idle state, get the message.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
msg k2mf Hello, Bawee!
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
NEtstat
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Gives a list of active TCP/IP connections to and from the local
|
||||||
|
host.
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Nodes [*|<nodecall>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows the NET/ROM node table of the local host. The nodes on this
|
||||||
|
list can be reached using the Connect command without knowing the
|
||||||
|
actual network path used (assuming the network is OK).
|
||||||
|
|
||||||
|
The optional parameter * toggles verbose mode, showing the
|
||||||
|
Obsolescence counter, relative path quality and the port and
|
||||||
|
neighbour node used to reach each node. You can also specify
|
||||||
|
a node callsign to get the verbose information for a single node.
|
||||||
|
In that case a "which" field that tells what route the kernel
|
||||||
|
will use to reach the node is shown.
|
|
@ -0,0 +1,15 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
PIng <hostname> [<length>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Checks if a host can be reached trough the network by sending
|
||||||
|
an ICMP Echo Request packet to the host and waiting for it to
|
||||||
|
reply. If a reply is received the round-trip-time (RTT)
|
||||||
|
between the local and remote hosts is shown.
|
||||||
|
|
||||||
|
If an optional length is specified the data portion of the
|
||||||
|
packet is filled with length number of bytes.
|
||||||
|
|
||||||
|
EXAMPLE
|
||||||
|
ping aripisa.ampr.org
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Ports
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows the available AX25 ports. Shown are the port name, a short
|
||||||
|
description for the port, the number of sessions via the port (qso)
|
||||||
|
and the number received and transmitted packets via the port.
|
||||||
|
The port name is used when using the Connect command to connect
|
||||||
|
to an user or service not running NET/ROM or FlexNet (eg. not visible
|
||||||
|
in the Nodes and Destinations lists). The port name is also visible
|
||||||
|
in the Route, MHeard and MSession lists.
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Quit
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Disconnects you from this node.
|
|
@ -0,0 +1,2 @@
|
||||||
|
<enter your rose routes here. Ex:>
|
||||||
|
c n1uro-8 3100860906
|
|
@ -0,0 +1,16 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Routes
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows the NET/ROM route table of the local host (eg. the nodes
|
||||||
|
which the local node directly talks with). These nodes are used
|
||||||
|
to reach the other nodes on the node table. Fields shown are:
|
||||||
|
|
||||||
|
Link - Is there an AX25 connection active to this node
|
||||||
|
Port - Which port is this route on
|
||||||
|
Callsign - The callsign of the neighbour node
|
||||||
|
Quality - A relative quality for the path (0-255)
|
||||||
|
Destinations - Number of other nodes reached via this route
|
||||||
|
Lock - Is the quality of this route locked by the operator
|
||||||
|
QSO - Number of NET/ROM session enties
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
SEssions [* | <call>]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Gives a list of active AX25 and NET/ROM connections to and
|
||||||
|
from the local host. With an asterisk (*) as an argument
|
||||||
|
shows also AX25 and NET/ROM sockets in listening state. With
|
||||||
|
a callsign as an argument gives a list of all connections with
|
||||||
|
either source or destination callsign <call>.
|
|
@ -0,0 +1,14 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
STatus
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Returns information about the status of the Linux system which this
|
||||||
|
URONode runs on. All information is taken directly from the
|
||||||
|
operating system.
|
||||||
|
|
||||||
|
The "load average" values indicate the average amount of processes
|
||||||
|
waiting for processor time during the last 1, 5 and 15 minutes.
|
||||||
|
Load average of 1.0 would mean that the all of the processor time is
|
||||||
|
used by the processes, and all processes still get all of the time
|
||||||
|
they can use.
|
|
@ -0,0 +1,26 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Telnet <host> [<port>] [s|d]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Initiates a telnet session to a remote host using TCP/IP.
|
||||||
|
You might not be able to connect to a given host due to the
|
||||||
|
local operator's policy of using this node, or simply because
|
||||||
|
the host is unreachable due to a network failure. You can use
|
||||||
|
the ping command to check if a host is reachable.
|
||||||
|
|
||||||
|
By default, the telnet command connects to the TCP port 23
|
||||||
|
(allocated for telnet). You can specify another TCP port or
|
||||||
|
a TCP port name.
|
||||||
|
|
||||||
|
If a single `s' is entered as the last parameter, then when
|
||||||
|
the remote host disconnects you will be returned to this node.
|
||||||
|
This is only valid if the user connects into your node via
|
||||||
|
NetRom, otherwise the user is automatically reconnected to
|
||||||
|
the node.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
telnet aripisa.ampr.org
|
||||||
|
telnet aripisa.ampr.org 1024
|
||||||
|
telnet 44.134.208.29 s
|
||||||
|
telnet 44.88.0.9 23 s
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Users
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows a list of users currently connected to the local node,
|
||||||
|
where the users are coming from, and what are they doing at the
|
||||||
|
moment.
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Version
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Displays the software version information,
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
Who (<call> | *)
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Shows a list when the user with the callsign <call> last
|
||||||
|
connected to this node. Use the asterisk to print out
|
||||||
|
the entire log table.
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
ZConnect <call | alias> [s|d] For NET/ROM or Links
|
||||||
|
ZConnect <port> <call> [via <digi1> ...] [s|d] For AX25
|
||||||
|
ZConnect <call> <address> [<digi>] [d|s] For ROSE
|
||||||
|
ZConnect <destination> [s|d] For FlexNet
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Compresses an AX25, NET/ROM, ROSE or Flexnet connection to a
|
||||||
|
remote host. If more than two parameters are entered and the
|
||||||
|
second parameter is ten charachers in length then it is
|
||||||
|
interpreted as a ROSE connection, otherwise the first
|
||||||
|
parameter is interpreted as a port name and AX25 is used
|
||||||
|
to make the connection via that port. If only one parameter
|
||||||
|
is given the connection is made searching for the callsign
|
||||||
|
in NET/ROM nodes, in AX25 Fixed links, in FlexNet destinations
|
||||||
|
and last in Mheard database in this order.
|
||||||
|
|
||||||
|
If a single `s' is entered as the last parameter, then when
|
||||||
|
the remote host disconnects you will be returned to this node.
|
||||||
|
If a single `d' is entered as the last parameter, you will
|
||||||
|
be disconnected from this node too. Default behaviour (neither
|
||||||
|
`s' nor `d' entered) depends on sysop configuration.
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
ZTelnet <host> [<port>] [s|d]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Compresses a telnet session to a remote host using TCP/IP.
|
||||||
|
You might not be able to connect to a given host due to the
|
||||||
|
local operator's policy of using this node, or simply because
|
||||||
|
the host is unreachable due to a network failure. You can use
|
||||||
|
the ping command to check if a host is reachable.
|
||||||
|
|
||||||
|
By default, the telnet command connects to the TCP port 23
|
||||||
|
(allocated for telnet). You can specify another TCP port or
|
||||||
|
a TCP port name.
|
||||||
|
|
||||||
|
If a single `s' is entered as the last parameter, then when
|
||||||
|
the remote host disconnects you will be returned to this node.
|
||||||
|
If a single `d' is entered as the last parameter, you will
|
||||||
|
be disconnected from this node too. Default behaviour (neither
|
||||||
|
`s' nor `d' entered) depends on sysop configuration.
|
||||||
|
|
||||||
|
EXAMPLES
|
||||||
|
ztelnet aripisa.ampr.org
|
||||||
|
ztelnet aripisa.ampr.org 1024
|
||||||
|
ztelnet 44.134.208.29
|
|
@ -0,0 +1,89 @@
|
||||||
|
# /etc/ax25/uronode.conf - URONode example configuration file
|
||||||
|
#
|
||||||
|
# see uronode.conf(5)
|
||||||
|
|
||||||
|
# Idle timeout (seconds).
|
||||||
|
# This is how long we hold onto a dead link. 0 disables (this is NOT
|
||||||
|
# recommended! Time is in seconds.
|
||||||
|
|
||||||
|
IdleTimeout 900
|
||||||
|
|
||||||
|
# Timeout when gatewaying (seconds).
|
||||||
|
# This (in seconds) is a keep-alive for dead connects out of the node.
|
||||||
|
|
||||||
|
ConnTimeout 600
|
||||||
|
|
||||||
|
# Visible hostname. Will be shown at telnet login.
|
||||||
|
# set this to your ampr.org hostname.
|
||||||
|
|
||||||
|
HostName xx#xx.ampr.org
|
||||||
|
|
||||||
|
# SysOp email address
|
||||||
|
# Set this to your email address - preferred to use an ampr.org email.
|
||||||
|
|
||||||
|
Email <your@email.ampr.org>
|
||||||
|
|
||||||
|
# "Local" network.
|
||||||
|
# This is your local amprnet subnet in full. Do NOT use 44.0.0.0/8!
|
||||||
|
|
||||||
|
LocalNet 44.0.0.0/32
|
||||||
|
|
||||||
|
# Command aliases. See uronode.conf(5) for the meaning of the uppercase
|
||||||
|
# letters in the name of the alias. Examples below:
|
||||||
|
|
||||||
|
Alias CAllbook "telnet %{3:144.167.99.66} 2000 %1 s"
|
||||||
|
Alias CONVers "telnet %{2:44.88.0.9} 3600 \"/n %u %{1:1}\""
|
||||||
|
Alias DXCluster "connect dxnet"
|
||||||
|
Alias Quit "bye"
|
||||||
|
Alias WX "telnet %{3:38.102.137.140} %1 s"
|
||||||
|
|
||||||
|
# Hidden ports.
|
||||||
|
# List interfaces you wish not to display. Not suggested.
|
||||||
|
|
||||||
|
#HiddenPorts inet
|
||||||
|
|
||||||
|
# External commands. See uronode.conf(5) for the meaning of the uppercase
|
||||||
|
# letters in the name of the extcmd.
|
||||||
|
#
|
||||||
|
# Flags: 1 Run command through pipe
|
||||||
|
# 2 Reconnected flag
|
||||||
|
# 3 Run through pipe and reconnect
|
||||||
|
#
|
||||||
|
ExtCmd NEstat 1 nobody /bin/netstat netstat --inet
|
||||||
|
#ExtCmd PMS 1 root /usr/sbin/pms pms -u %U -o XX0XX
|
||||||
|
|
||||||
|
# Node ID.
|
||||||
|
# This displays before all output texts when the user connects into
|
||||||
|
# your node via NetRom. Set to "" to leave blank.
|
||||||
|
# Note: This -must- be defined or will display as "(null)". A space
|
||||||
|
# is hardcoded in. Example: UROHUB:N1URO-2 do NOT add the bracket
|
||||||
|
# afterwards "}" this is predefined in URONode.
|
||||||
|
#
|
||||||
|
NodeId XXXXXX:XX#XX-#
|
||||||
|
|
||||||
|
# Ax25/Flex ID.
|
||||||
|
# This displays before some strings and at logout to the end user when
|
||||||
|
# they connect in via ax25 as defined in your ax25d.conf file. If
|
||||||
|
# you don't define this "(null)" will be presented to the end user. Its
|
||||||
|
# suggested you take this from your ax25d config which either faces a
|
||||||
|
# flexnet system OR your 2-meter user interface. Note: do NOT make this
|
||||||
|
# ssid the same as your NetRom SSID here or in ax25d.conf.
|
||||||
|
|
||||||
|
FlexId XX#XX-#
|
||||||
|
|
||||||
|
# ROSE ssid@network - if none, enter in: none.
|
||||||
|
|
||||||
|
RoseId XX#XX-#@####,######
|
||||||
|
|
||||||
|
# Netrom port name. This port is used for outgoing netrom connects.
|
||||||
|
|
||||||
|
NrPort nr0
|
||||||
|
|
||||||
|
# Syslog Logging level - suggest leaving this at 3 for debugging. 0
|
||||||
|
# halts logging.
|
||||||
|
|
||||||
|
LogLevel 3
|
||||||
|
|
||||||
|
# The default escape character (CTRL-T)
|
||||||
|
#
|
||||||
|
EscapeChar ^T
|
|
@ -0,0 +1,3 @@
|
||||||
|
This is a new system running URONode.
|
||||||
|
*** please edit /etc/ax25/uronode.info to change this text to display
|
||||||
|
information about your system.
|
|
@ -0,0 +1,4 @@
|
||||||
|
This is copy of URONode is located in <town>,
|
||||||
|
<county>, <state/province> [XX##xx] (grid)
|
||||||
|
Type "?" for commands or H <command> for more detailed help on a command.
|
||||||
|
*** please edit /etc/ax25/uronode.motd to change this text
|
|
@ -0,0 +1,26 @@
|
||||||
|
# /etc/ax25/uronode.perms - URONode example permissions file
|
||||||
|
#
|
||||||
|
# see uronode.perms(5)
|
||||||
|
#
|
||||||
|
# Note: The flags have been changed as of 2014/08/23
|
||||||
|
#
|
||||||
|
# user type port passwd perms
|
||||||
|
|
||||||
|
# User oh2bns can login without password from anywhere else but 'inet'.
|
||||||
|
#
|
||||||
|
#xx0xx inet * qwerty 95
|
||||||
|
#xx0xx * * * 95
|
||||||
|
n1uro * * * 255
|
||||||
|
|
||||||
|
# OH2RBI is a bbs so it needs escape disabled.
|
||||||
|
#
|
||||||
|
#xx0xx * * * 287
|
||||||
|
|
||||||
|
# Default permissions per connection type.
|
||||||
|
#
|
||||||
|
* ax25 * * 31
|
||||||
|
* netrom * * 31
|
||||||
|
* local * * 31
|
||||||
|
* ampr * * 31
|
||||||
|
* inet * * 0
|
||||||
|
* host * * 31
|
|
@ -0,0 +1,21 @@
|
||||||
|
# /etc/ax25/uronode.routes URONode example configuration file
|
||||||
|
# This is used for quick ax25 connects so users need not add an interface
|
||||||
|
# when making a connect. You also need a statement in here for flexd to
|
||||||
|
# poll your flexnet neighbor.
|
||||||
|
|
||||||
|
# URONode shows links with this order. Examples below:
|
||||||
|
|
||||||
|
# Direct Routing
|
||||||
|
# route <call> <alias> <port> d 'description'
|
||||||
|
#
|
||||||
|
#route n1uro-1 fxuro ax0 d 'N1URO FlexNet Hub'
|
||||||
|
|
||||||
|
# Routing across another node with sending a string "C <call>"
|
||||||
|
# route <call> <alias> <port> n 'description' <node>
|
||||||
|
#
|
||||||
|
#route n1uro-14 WMASS ax0 n 'N1URO-NOS' n1uro-1
|
||||||
|
|
||||||
|
# Routing via digipeaters
|
||||||
|
# route <call> <alias> <port> v 'description' <digipeaters>
|
||||||
|
#
|
||||||
|
#route n1uro-9 MACTFX ax0 v 'N1URO Xnet' n1uro-1
|
|
@ -0,0 +1,6 @@
|
||||||
|
# /etc/ax25/uronode.users URONode example configuration file
|
||||||
|
# Shell access for Sysop users
|
||||||
|
|
||||||
|
# callsign:password:local linux username:shell
|
||||||
|
# xx#xx:password:xx#xx:shell
|
||||||
|
# yy#yy:password:thomas:shell
|
|
@ -0,0 +1,203 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
#define ECMD_PIPE 1 /* Run through pipe */
|
||||||
|
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
#define ECMD_RECONN 2 /* */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int norm_extcmd(struct cmd *cmdp, char **argv)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
alarm(0L);
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
/* fork error */
|
||||||
|
node_perror("norm_extcmd: fork", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pid == 0) {
|
||||||
|
/* child */
|
||||||
|
setgroups(0, NULL);
|
||||||
|
setgid(cmdp->gid);
|
||||||
|
setuid(cmdp->uid);
|
||||||
|
execve(cmdp->path, argv, NULL);
|
||||||
|
node_perror("norm_extcmd: execve", errno);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* parent */
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pipe_extcmd(struct cmd *cmdp, char **argv)
|
||||||
|
{
|
||||||
|
ax25io *iop;
|
||||||
|
int pipe_in[2], pipe_out[2];
|
||||||
|
int pid, c;
|
||||||
|
fd_set fdset;
|
||||||
|
|
||||||
|
if (pipe(pipe_in) == -1) {
|
||||||
|
node_perror("pipe_extcmd: pipe_in", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pipe(pipe_out) == -1) {
|
||||||
|
node_perror("pipe_extcmd: pipe_out", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
signal(SIGCHLD, SIG_IGN);
|
||||||
|
pid = fork();
|
||||||
|
if (pid == -1) {
|
||||||
|
/* fork error */
|
||||||
|
node_perror("pipe_extcmd: fork", errno);
|
||||||
|
signal(SIGCHLD, SIG_DFL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pid == 0) {
|
||||||
|
/* child */
|
||||||
|
/*
|
||||||
|
* Redirect childs output to the pipes closing
|
||||||
|
* stdin/out/err as we go.
|
||||||
|
*/
|
||||||
|
dup2(pipe_in[0], STDIN_FILENO);
|
||||||
|
dup2(pipe_out[1], STDOUT_FILENO);
|
||||||
|
dup2(pipe_out[1], STDERR_FILENO);
|
||||||
|
/* Close the other ends */
|
||||||
|
close(pipe_in[1]);
|
||||||
|
close(pipe_out[0]);
|
||||||
|
setgroups(0, NULL);
|
||||||
|
setgid(cmdp->gid);
|
||||||
|
setuid(cmdp->uid);
|
||||||
|
execve(cmdp->path, argv, NULL);
|
||||||
|
perror("pipe_extcmd: execve");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/* parent */
|
||||||
|
close(pipe_in[0]);
|
||||||
|
close(pipe_out[1]);
|
||||||
|
if (fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK) == -1 ||
|
||||||
|
fcntl(pipe_out[0], F_SETFL, O_NONBLOCK) == -1) {
|
||||||
|
node_perror("pipe_extcmd: fcntl - pipe_out", errno);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
iop = axio_init(pipe_out[0], pipe_in[1], 1024, UNSPEC_EOL);
|
||||||
|
if (iop == NULL) {
|
||||||
|
node_perror("pipe_extcmd: Error initializing I/O", -1);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
while (1) {
|
||||||
|
FD_ZERO(&fdset);
|
||||||
|
FD_SET(STDIN_FILENO, &fdset);
|
||||||
|
FD_SET(pipe_out[0], &fdset);
|
||||||
|
if (select(32, &fdset, 0, 0, 0) == -1) {
|
||||||
|
node_perror("pipe_extcmd: select", errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(STDIN_FILENO, &fdset)) {
|
||||||
|
alarm(ConnTimeout);
|
||||||
|
while((c = axio_getc(NodeIo)) != -1)
|
||||||
|
axio_putc(c, iop);
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(pipe_out[0], &fdset)) {
|
||||||
|
alarm(ConnTimeout);
|
||||||
|
while((c = axio_getc(iop)) != -1)
|
||||||
|
axio_putc(c, NodeIo);
|
||||||
|
if (errno != EAGAIN) {
|
||||||
|
if (errno)
|
||||||
|
node_msg("%s", strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
axio_flush(iop);
|
||||||
|
}
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} ", NodeId);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;31mWelcome back.\e[0m");
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo, "Welcome back.");
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (User.ul_type == AF_INET) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[01;31m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo, "Returning you to the shell... ");
|
||||||
|
} else if (User.ul_type == AF_AX25) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;31m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Welcome back to %s.", FlexId);
|
||||||
|
} else if (User.ul_type == AF_ROSE) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;31m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Back to %s", RoseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
axio_end(iop);
|
||||||
|
end:
|
||||||
|
signal(SIGCHLD, SIG_DFL);
|
||||||
|
kill(pid, SIGKILL);
|
||||||
|
close(pipe_in[1]);
|
||||||
|
close(pipe_out[0]);
|
||||||
|
if (fcntl(STDIN_FILENO, F_SETFL, 0) == -1)
|
||||||
|
node_perror("pipe_extcmd: fcntl - stdin", errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int extcmd(struct cmd *cmdp, char **argv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
User.state = STATE_EXTCMD;
|
||||||
|
User.dl_type = AF_UNSPEC;
|
||||||
|
strcpy(User.dl_name, cmdp->name);
|
||||||
|
strupr(User.dl_name);
|
||||||
|
update_user();
|
||||||
|
if (cmdp->flags & ECMD_PIPE)
|
||||||
|
ret = pipe_extcmd(cmdp, argv);
|
||||||
|
else
|
||||||
|
ret = norm_extcmd(cmdp, argv);
|
||||||
|
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
if (cmdp->flags & ECMD_RECONN) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} Welcome back.", NodeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (User.ul_type == AF_AX25) {
|
||||||
|
/* axio_printf(NodeIo, "Welcome back to %s.", FlexId); */
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (cmdp->flags)
|
||||||
|
node_logout("");
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,431 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netinet/ip_icmp.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include <netax25/nrconfig.h>
|
||||||
|
#include <netax25/rsconfig.h>
|
||||||
|
#include <netax25/procutils.h>
|
||||||
|
#include <netax25/daemon.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "procinfo.h"
|
||||||
|
|
||||||
|
#define DEFAULT_POLL_TIME 600
|
||||||
|
#define MINIMUM_POLL_TIME 300
|
||||||
|
|
||||||
|
int poll_time=DEFAULT_POLL_TIME;
|
||||||
|
char flexgate[10]="\0";
|
||||||
|
char mycall[10]="\0";
|
||||||
|
struct ax_routes *gw;
|
||||||
|
int s;
|
||||||
|
void (*sigterm_defhnd)(int);
|
||||||
|
|
||||||
|
void read_conf(void)
|
||||||
|
{
|
||||||
|
FILE *fp, *fgt;
|
||||||
|
char buf[1024], line[1024], *cp;
|
||||||
|
int i=0,k;
|
||||||
|
char digipath[AX25_MAX_DIGIS*10];
|
||||||
|
|
||||||
|
if ((fp=fopen(FLEXD_CONF_FILE, "r")) == NULL) {
|
||||||
|
fprintf(stderr, "flexd config: Cannot open config file: %s\n", FLEXD_CONF_FILE);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if ((fgt=fopen(FLEX_GT_FILE, "w")) == NULL) {
|
||||||
|
fprintf(stderr, "flexd config: Cannot open flexnet gateways file: %s\n", FLEX_GT_FILE);
|
||||||
|
fclose(fp);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("addr callsign dev digipeaters\n", fgt);
|
||||||
|
|
||||||
|
while(fgets(buf, sizeof(buf), fp)) {
|
||||||
|
if(*buf=='#' || *buf==' ') continue; /* comment line/empty line */
|
||||||
|
cp=strchr(buf, '#');
|
||||||
|
if (cp) *cp='\0';
|
||||||
|
cp=strtok(buf, " \t\n\r");
|
||||||
|
if(cp==NULL) continue; /* empty line */
|
||||||
|
|
||||||
|
if(strcasecmp(cp,"pollinterval")==0) { /* set poll interval */
|
||||||
|
cp=strtok(NULL, " \t\n\r");
|
||||||
|
if(cp==NULL) {
|
||||||
|
fprintf(stderr, "flexd config: PollInterval needs an argument\n");
|
||||||
|
fclose(fp);
|
||||||
|
fclose(fgt);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
poll_time=safe_atoi(cp);
|
||||||
|
if (poll_time<MINIMUM_POLL_TIME) poll_time=MINIMUM_POLL_TIME;
|
||||||
|
}
|
||||||
|
if(strcasecmp(cp,"mycall")==0) { /* set connect call for download */
|
||||||
|
cp=strtok(NULL, " \t\n\r");
|
||||||
|
if(cp==NULL) {
|
||||||
|
fprintf(stderr, "flexd config: MyCall needs an argument\n");
|
||||||
|
fclose(fp);
|
||||||
|
fclose(fgt);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
safe_strncpy(mycall, cp, 9);
|
||||||
|
}
|
||||||
|
if(strcasecmp(cp,"flexgate")==0) { /* set flexnet gateway */
|
||||||
|
cp=strtok(NULL, " \t\n\r");
|
||||||
|
if(cp==NULL) {
|
||||||
|
fprintf(stderr, "flexd config: FlexGate needs an argument\n");
|
||||||
|
fclose(fp);
|
||||||
|
fclose(fgt);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
safe_strncpy(flexgate, cp, 9);
|
||||||
|
gw=find_route(flexgate, NULL);
|
||||||
|
if (gw==NULL) {
|
||||||
|
fprintf(stderr, "flexd config: FlexGate %s not found in route file: %s\n", flexgate, AX_ROUTES_FILE);
|
||||||
|
fclose(fp);
|
||||||
|
fclose(fgt);
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
*digipath='\0';
|
||||||
|
for(k=0;k<AX25_MAX_DIGIS;k++) {
|
||||||
|
if (gw->digis[k]==NULL) break;
|
||||||
|
strcat(digipath," ");
|
||||||
|
strcat(digipath, gw->digis[k]);
|
||||||
|
}
|
||||||
|
sprintf(line, "%05d %-8s %4s %s\n", i++, gw->dest_call, ax25_config_get_dev(gw->dev), digipath);
|
||||||
|
fputs(line, fgt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fgt);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int download_dest(char *gateway, char *fname)
|
||||||
|
{
|
||||||
|
FILE *tmp;
|
||||||
|
char buffer[1024], port[14], path[AX25_MAX_DIGIS*10];
|
||||||
|
char *addr, *commands[10], *dlist[9]; /* Destination + 8 digipeaters */
|
||||||
|
fd_set read_fd;
|
||||||
|
int n, addrlen, cmd_send=0, cmd_ack=0, c, k;
|
||||||
|
struct full_sockaddr_ax25 axbind, axconnect;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gw=find_route(gateway, NULL);
|
||||||
|
if (gw==NULL) {
|
||||||
|
fprintf(stderr, "flexd connect: FlexGate %s not found in route file: %s\n", gateway, AX_ROUTES_FILE);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
*path='\0';
|
||||||
|
for(k=0;k<AX25_MAX_DIGIS;k++) {
|
||||||
|
if (gw->digis[k][0]=='\0') dlist[k+1]=NULL;
|
||||||
|
else dlist[k+1]=gw->digis[k];
|
||||||
|
}
|
||||||
|
dlist[0]=gw->dest_call;
|
||||||
|
strcpy(port,gw->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((addr = ax25_config_get_addr(port)) == NULL) {
|
||||||
|
sprintf(buffer, "flexd connect: invalid AX.25 port name - %s\r\n", port);
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Open the socket into the kernel.
|
||||||
|
*/
|
||||||
|
if ((s = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) {
|
||||||
|
sprintf(buffer, "flexd connect: cannot open AX.25 socket, %s\r\n", strerror(errno));
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set our AX.25 callsign and AX.25 port callsign accordingly.
|
||||||
|
*/
|
||||||
|
if (*mycall=='\0') sprintf(buffer, "%s %s", addr, addr);
|
||||||
|
else sprintf(buffer, "%s %s", mycall, addr);
|
||||||
|
ax25_aton(buffer, &axbind);
|
||||||
|
axbind.fsa_ax25.sax25_family = AF_AX25;
|
||||||
|
addrlen=sizeof(struct full_sockaddr_ax25);
|
||||||
|
|
||||||
|
if (bind(s, (struct sockaddr *)&axbind, addrlen) != 0) {
|
||||||
|
sprintf(buffer, "flexd connect: cannot bind AX.25 socket, %s\r\n", strerror(errno));
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lets try and connect to the far end.
|
||||||
|
*/
|
||||||
|
addrlen=sizeof(struct full_sockaddr_ax25);
|
||||||
|
axconnect.fsa_ax25.sax25_family = AF_AX25;
|
||||||
|
|
||||||
|
if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
|
||||||
|
sprintf(buffer, "flexd connect: fcntl on socket: %s\r\n", strerror(errno));
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ax25_aton_arglist((const char **)dlist, &axconnect) == -1) {
|
||||||
|
sprintf(buffer, "flexd connect: invalid destination callsign or digipeater\r\n");
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connect(s, (struct sockaddr *)&axconnect, addrlen) == -1 && errno != EINPROGRESS) {
|
||||||
|
switch (errno) {
|
||||||
|
case ECONNREFUSED:
|
||||||
|
strcpy(buffer, "*** Connection refused - aborting\r\n");
|
||||||
|
break;
|
||||||
|
case ENETUNREACH:
|
||||||
|
strcpy(buffer, "*** No known route - aborting\r\n");
|
||||||
|
break;
|
||||||
|
case EINTR:
|
||||||
|
strcpy(buffer, "*** Connection timed out - aborting\r\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(buffer, "*** Cannot connect, %s\r\n", strerror(errno));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
FD_ZERO(&read_fd);
|
||||||
|
FD_SET(s, &read_fd);
|
||||||
|
|
||||||
|
tv.tv_sec=180;
|
||||||
|
tv.tv_usec=0;
|
||||||
|
|
||||||
|
k=select(s + 3, &read_fd, NULL, 0, &tv);
|
||||||
|
|
||||||
|
if (k<1) { /* error or timeout */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FD_ISSET(s, &read_fd)) {
|
||||||
|
int ret, retlen;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/* See if we got connected or if this was an error */
|
||||||
|
getsockopt(s, SOL_SOCKET, SO_ERROR, &ret, &retlen);
|
||||||
|
if (ret != 0) {
|
||||||
|
cp = strdup(strerror(ret));
|
||||||
|
strlwr(cp);
|
||||||
|
sprintf(buffer, "flexd connect: Failure with %s: %sr\r\n", gateway, cp);
|
||||||
|
write(STDOUT_FILENO, buffer, strlen(buffer));
|
||||||
|
free(cp);
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commands[0]="d\r\n";
|
||||||
|
commands[1]="q\r\n";
|
||||||
|
commands[2]=NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop until one end of the connection goes away.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((tmp=fopen(fname, "w")) == NULL) {
|
||||||
|
fprintf(stderr, "flexd connect: Cannot open temporary file: %s\n", fname);
|
||||||
|
close(s);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
FD_ZERO(&read_fd);
|
||||||
|
FD_SET(s, &read_fd);
|
||||||
|
|
||||||
|
tv.tv_sec=180;
|
||||||
|
tv.tv_usec=0;
|
||||||
|
|
||||||
|
k=select(s + 1, &read_fd, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (k<1) { /* error or timeout */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(s, &read_fd)) {
|
||||||
|
if ((n = read(s, buffer, 512)) == -1) break;
|
||||||
|
for(c=0;c<n;c++) {
|
||||||
|
if (buffer[c]=='\r') buffer[c]='\n';
|
||||||
|
if (buffer[c]=='=' && c<n-1 && buffer[c+1]=='>') {
|
||||||
|
/* fprintf(stderr, "flex interact: ack[%d]\n", cmd_ack); */
|
||||||
|
cmd_ack++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fwrite(buffer, sizeof(char), n, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd_ack!=0) {
|
||||||
|
if (commands[cmd_send]!=NULL) {
|
||||||
|
write(s, commands[cmd_send], 2);
|
||||||
|
/* fprintf(stderr, "flexd interact: send[%d]: %s\n", cmd_send, commands[cmd_send]); */
|
||||||
|
cmd_send++;
|
||||||
|
}
|
||||||
|
cmd_ack=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(s);
|
||||||
|
|
||||||
|
fputs("\n",tmp);
|
||||||
|
|
||||||
|
fclose(tmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_dest(char *gateway, char *fname)
|
||||||
|
{
|
||||||
|
FILE *fdst, *tmp;
|
||||||
|
char *call, *ssid, *rtt, *cp, buf[1024], line[1024], ax[10];
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
if ((tmp=fopen(fname, "r")) == NULL) {
|
||||||
|
fprintf(stderr, "flexd update: Cannot open temporary file: %s\n", fname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fdst=fopen(FLEX_DST_FILE, "w")) == NULL) {
|
||||||
|
fprintf(stderr, "flexd update: Cannot open flexnet destinations file: %s\n", FLEX_DST_FILE);
|
||||||
|
fclose(tmp);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("callsign ssid rtt gateway\n", fdst);
|
||||||
|
/* fprintf(fdst, "%s %s 0 00000\n", mygate, myrange); */
|
||||||
|
while(fgets(buf, sizeof(buf), tmp)) {
|
||||||
|
cp=strtok(buf, " \t\n\r");
|
||||||
|
if(cp==NULL) continue; /* empty line */
|
||||||
|
if(strstr(cp,"=>")) i++; /* system prompt */
|
||||||
|
if(i==0) continue; /* skip connect text */
|
||||||
|
if(*cp=='#' || *cp=='=' || *cp==' ' || *cp=='*' || *cp=='-' || *cp==':') continue; /* comment line/system prompt */
|
||||||
|
if(strncmp(cp,"73!",3)==0) continue; /* End greeting */
|
||||||
|
|
||||||
|
/* CALL SSID-ESID RTT */
|
||||||
|
do {
|
||||||
|
call=cp;
|
||||||
|
if (call==NULL) break;
|
||||||
|
if (strlen(call)>6) break;
|
||||||
|
if (strchr(call,'-')) break;
|
||||||
|
if (ax25_aton_entry(call,ax)!=0) break;
|
||||||
|
if (!ax25_validate(ax)) break;
|
||||||
|
ssid=strtok(NULL, " \t\n\r");
|
||||||
|
if (ssid==NULL) break;
|
||||||
|
if (!strchr(ssid,'-')) break;
|
||||||
|
rtt=strtok(NULL, " \t\n\r");
|
||||||
|
if (rtt==NULL) break;
|
||||||
|
if (atoi(rtt)==0) break;
|
||||||
|
sprintf(line, "%-8s %-5s %6d %05d\n", call, ssid, safe_atoi(rtt), 0);
|
||||||
|
fputs(line, fdst);
|
||||||
|
cp=strtok(NULL, " \t\n\r");
|
||||||
|
} while(cp!=NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fdst);
|
||||||
|
fclose(tmp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int update_flex(void)
|
||||||
|
{
|
||||||
|
char fname[80];
|
||||||
|
|
||||||
|
sprintf(fname, "%s/.session.%s", FLEXD_TEMP_PATH, flexgate);
|
||||||
|
|
||||||
|
if (download_dest(flexgate, fname)==0) parse_dest(flexgate, fname);
|
||||||
|
remove(fname);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void hup_handler(int sig)
|
||||||
|
{
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
|
||||||
|
read_conf();
|
||||||
|
|
||||||
|
signal(SIGHUP, hup_handler); /* Restore hangup handler */
|
||||||
|
}
|
||||||
|
|
||||||
|
void alarm_handler(int sig)
|
||||||
|
{
|
||||||
|
signal(SIGALRM, SIG_IGN);
|
||||||
|
|
||||||
|
update_flex();
|
||||||
|
|
||||||
|
signal(SIGALRM, alarm_handler); /* Restore alarm handler */
|
||||||
|
alarm(poll_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void quit_handler(int sig)
|
||||||
|
{
|
||||||
|
signal(SIGTERM, SIG_IGN);
|
||||||
|
|
||||||
|
unlink(FLEXD_PID_FILE);
|
||||||
|
|
||||||
|
signal(SIGTERM, sigterm_defhnd);
|
||||||
|
raise(SIGTERM);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
FILE *pidfile;
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
if (ax25_config_load_ports() == 0) {
|
||||||
|
fprintf(stderr, "flexd error: No AX25 port data configured\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_conf();
|
||||||
|
|
||||||
|
if (!daemon_start(TRUE)) {
|
||||||
|
fprintf(stderr, "flexd: cannot become a daemon\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGTERM, quit_handler);
|
||||||
|
pidfile = fopen(FLEXD_PID_FILE, "w");
|
||||||
|
fprintf(pidfile, "%d\n", (int)getpid());
|
||||||
|
fclose(pidfile);
|
||||||
|
|
||||||
|
update_flex();
|
||||||
|
|
||||||
|
signal(SIGHUP, hup_handler);
|
||||||
|
signal(SIGALRM, alarm_handler);
|
||||||
|
sigterm_defhnd = signal(SIGTERM, quit_handler);
|
||||||
|
if (sigterm_defhnd == SIG_ERR)
|
||||||
|
sigterm_defhnd = SIG_DFL;
|
||||||
|
alarm(poll_time);
|
||||||
|
|
||||||
|
for(;;) pause();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
/* oringinal by Heikki Hannikainen, modified by Brian Rogers */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h>
|
||||||
|
#include <sys/msg.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include <netax25/nrconfig.h>
|
||||||
|
#include <netax25/rsconfig.h>
|
||||||
|
#include <netax25/procutils.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
#define FIRST_KEY (3694 - 1) /* Where to start looking for a key */
|
||||||
|
#define LAST_KEY (FIRST_KEY + 200) /* How far to search */
|
||||||
|
#define M_LEN 1024 /* Largest message transferred */
|
||||||
|
|
||||||
|
struct nmsgbuf {
|
||||||
|
long mtype; /* message type, must be > 0 */
|
||||||
|
char mtext[M_LEN]; /* message data */
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ipc_id = -1;
|
||||||
|
|
||||||
|
static void usr2_handler(int sig)
|
||||||
|
{
|
||||||
|
struct nmsgbuf buf;
|
||||||
|
|
||||||
|
if (msgrcv(ipc_id, (struct msgbuf *)&buf, M_LEN, 0, IPC_NOWAIT|MSG_NOERROR) != -1) {
|
||||||
|
node_msg("%s", buf.mtext);
|
||||||
|
if (User.ul_type != AF_NETROM) {
|
||||||
|
node_prompt();
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
} else
|
||||||
|
node_log(LOGLVL_ERROR, "usr2_handler: Caught SIGUSR2, but couldn't receive a message");
|
||||||
|
|
||||||
|
signal(SIGUSR2, usr2_handler); /* Restore handler */
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_send(key_t key, long mtype, char *mtext)
|
||||||
|
{
|
||||||
|
struct nmsgbuf buf;
|
||||||
|
int id;
|
||||||
|
|
||||||
|
if ((id = msgget(key, S_IRWXU)) == -1) {
|
||||||
|
node_perror("ipc_send: Could not get transmit channel", errno);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.mtype = mtype;
|
||||||
|
strncpy(buf.mtext, mtext, M_LEN);
|
||||||
|
|
||||||
|
if (msgsnd(id, (struct msgbuf *)&buf, M_LEN, 0) == -1) {
|
||||||
|
node_perror("ipc_send: Could not send message", errno);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_open(void)
|
||||||
|
{
|
||||||
|
key_t key = FIRST_KEY;
|
||||||
|
|
||||||
|
do {
|
||||||
|
key++;
|
||||||
|
ipc_id = msgget(key, S_IRWXU | IPC_CREAT | IPC_EXCL);
|
||||||
|
} while ((ipc_id == -1) && (key != LAST_KEY));
|
||||||
|
|
||||||
|
if (ipc_id == -1)
|
||||||
|
node_perror("ipc_open: Could not get an IPC channel", errno);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
node_msg("debug: ipc_id=%d key=%d", ipc_id, key);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
User.ipc_key = key;
|
||||||
|
|
||||||
|
if (key != -1)
|
||||||
|
signal(SIGUSR2, usr2_handler);
|
||||||
|
else
|
||||||
|
signal(SIGUSR2, SIG_IGN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipc_close(void)
|
||||||
|
{
|
||||||
|
struct msqid_ds buf;
|
||||||
|
|
||||||
|
if (ipc_id != -1) /* Remove the IPC channel */
|
||||||
|
if (msgctl(ipc_id, IPC_RMID, &buf) == -1) {
|
||||||
|
node_log(LOGLVL_ERROR, "ipc_close: Could not remove IPC channel: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
node_log(LOGLVL_ERROR, "ipc_close: Removing IPC channel for %s", User.call);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_msg(int argc, char **argv)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
struct user u;
|
||||||
|
char call[10];
|
||||||
|
char mtext[M_LEN];
|
||||||
|
int i, hits = 0, sent = 0;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
node_msg("Usage: msg <call> <your text msg>");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sprintf(mtext, "\n*** Msg from %s:\n\a", User.call);
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
strncat(mtext, argv[i], M_LEN - strlen(mtext));
|
||||||
|
strncat(mtext, " ", M_LEN - strlen(mtext));
|
||||||
|
}
|
||||||
|
strncat(mtext, "\n*** End of msg.", M_LEN - strlen(mtext));
|
||||||
|
mtext[M_LEN - 1] = 0;
|
||||||
|
|
||||||
|
strncpy(call, argv[1], 9);
|
||||||
|
call[9] = 0;
|
||||||
|
|
||||||
|
while (fread(&u, sizeof(u), 1, f) == 1) {
|
||||||
|
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH))
|
||||||
|
continue;
|
||||||
|
if (!strcasecmp(u.call, call)) {
|
||||||
|
hits++;
|
||||||
|
if (u.ipc_key != -1 && u.state == STATE_IDLE) {
|
||||||
|
ipc_send(u.ipc_key, 1, mtext);
|
||||||
|
kill(u.pid, SIGUSR2);
|
||||||
|
sent++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
if (hits == 0) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo, "%s is not on the node now.\a", call);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
} else if (sent == 0) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo, "%s is busy and not accepting msgs now.\a", call);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
} else if (sent != 0) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo, "Msg sent to %s.\a", call);
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,151 @@
|
||||||
|
/* Routine rewritten mainly by Barry K2MF (Mr. MFNOS) and Brian N1URO */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include <netax25/mheard.h>
|
||||||
|
|
||||||
|
#include "config.h" /* Bob VE3TOK 30Nov2014 */
|
||||||
|
#include "procinfo.h"
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
struct mheard_list {
|
||||||
|
struct mheard_struct data;
|
||||||
|
struct mheard_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
int do_mheard (int argc,char **argv) {
|
||||||
|
FILE *fp;
|
||||||
|
struct mheard_struct mh;
|
||||||
|
struct mheard_list *list = NULL, *new, *tmp, *p;
|
||||||
|
char *s, *t, *u;
|
||||||
|
int mhcount = 0;
|
||||||
|
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
|
||||||
|
if(User.ul_type == AF_NETROM)
|
||||||
|
axio_printf(NodeIo,"%s} ",NodeId);
|
||||||
|
|
||||||
|
if(argc > 1) {
|
||||||
|
if(ax25_config_get_dev(argv[1]) == NULL
|
||||||
|
|| (check_perms(PERM_HIDDEN, 0) == -1
|
||||||
|
&& is_hidden(argv[1]))) {
|
||||||
|
axio_printf(NodeIo,"Invalid port: %s",argv[1]);
|
||||||
|
|
||||||
|
if(User.ul_type == AF_NETROM)
|
||||||
|
node_msg("");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if((fp = fopen(DATA_MHEARD_FILE,"r")) == NULL) {
|
||||||
|
node_perror(DATA_MHEARD_FILE,errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while(mhcount < 20 && fread(&mh,sizeof(struct mheard_struct),1,fp)
|
||||||
|
== 1) {
|
||||||
|
if(argc > 1) {
|
||||||
|
if(strcmp(argv[1],mh.portname))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(check_perms(PERM_HIDDEN,0) == -1 && is_hidden(mh.portname))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if((new = calloc(1,sizeof(struct mheard_list))) == NULL) {
|
||||||
|
node_perror("do_mheard: calloc",errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
new->data = mh;
|
||||||
|
|
||||||
|
if(list == NULL || mh.last_heard > list->data.last_heard) {
|
||||||
|
tmp = list;
|
||||||
|
list = new;
|
||||||
|
} else {
|
||||||
|
for(p = list; p->next != NULL; p = p->next) {
|
||||||
|
if(mh.last_heard > p->next->data.last_heard)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp = p->next;
|
||||||
|
p->next = new;
|
||||||
|
}
|
||||||
|
new->next = tmp;
|
||||||
|
mhcount++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if(check_perms(PERM_ANSI,0L) != -1)
|
||||||
|
axio_printf(NodeIo,"\e[01;33m");
|
||||||
|
|
||||||
|
node_msg("MHeard list:");
|
||||||
|
|
||||||
|
if(check_perms(PERM_ANSI,0L) != -1)
|
||||||
|
axio_printf(NodeIo,"\e[0;m");
|
||||||
|
|
||||||
|
axio_printf(NodeIo,"Callsign Device Packets Date & Time Frame Type(s)\n");
|
||||||
|
axio_printf(NodeIo,"--------- ------ -------- --------------- -------------");
|
||||||
|
|
||||||
|
while(list != NULL) {
|
||||||
|
s = ctime(&list->data.last_heard);
|
||||||
|
s[19] = 0;
|
||||||
|
s += 4;
|
||||||
|
t = ax25_ntoa(&list->data.from_call);
|
||||||
|
|
||||||
|
if((u = strstr(t,"-0")) != NULL)
|
||||||
|
*u = '\0';
|
||||||
|
|
||||||
|
axio_printf(NodeIo,"\n%-9s %-6s %-8d %s",t,list->data.portname,list->data.count,s);
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_ARP)
|
||||||
|
axio_printf(NodeIo," ARP");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_FLEXNET)
|
||||||
|
axio_printf(NodeIo," FlexNet");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_IP_DG)
|
||||||
|
axio_printf(NodeIo," IP-DG");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_IP_VC)
|
||||||
|
axio_printf(NodeIo," IP-VC");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_NETROM)
|
||||||
|
axio_printf(NodeIo," NetRom");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_ROSE)
|
||||||
|
axio_printf(NodeIo," Rose");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_SEGMENT)
|
||||||
|
axio_printf(NodeIo," Segment");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_TEXNET)
|
||||||
|
axio_printf(NodeIo," TexNet");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_TEXT)
|
||||||
|
axio_printf(NodeIo," Text");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_PSATFT)
|
||||||
|
axio_printf(NodeIo," PacsatFT");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_PSATPB)
|
||||||
|
axio_printf(NodeIo," PacsatPB");
|
||||||
|
|
||||||
|
if(list->data.mode & MHEARD_MODE_UNKNOWN)
|
||||||
|
axio_printf(NodeIo," Unknown");
|
||||||
|
|
||||||
|
tmp = list;
|
||||||
|
list = list->next;
|
||||||
|
free(tmp);
|
||||||
|
|
||||||
|
}
|
||||||
|
if(User.ul_type == AF_NETROM)
|
||||||
|
node_msg("");
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,419 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include <netax25/nrconfig.h>
|
||||||
|
#include <netax25/rsconfig.h>
|
||||||
|
#include <netax25/procutils.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
ax25io *NodeIo = NULL;
|
||||||
|
|
||||||
|
int aliascmd = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do some validity checking for callsign pointed to by `s'.
|
||||||
|
*/
|
||||||
|
static int check_call(const char *s)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int nums = 0;
|
||||||
|
int ssid = 0;
|
||||||
|
char *p[1];
|
||||||
|
|
||||||
|
if (s == NULL)
|
||||||
|
return -1;
|
||||||
|
while (*s && *s != '-') {
|
||||||
|
if (!isalnum(*s))
|
||||||
|
return -1;
|
||||||
|
if (isdigit(*s))
|
||||||
|
nums++;
|
||||||
|
len++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
if (*s == '-') {
|
||||||
|
if (!isdigit(*++s))
|
||||||
|
return -1;
|
||||||
|
ssid = strtol(s, p, 10);
|
||||||
|
if (**p)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (len < 4 || len > 6 || !nums || nums > 2 || ssid < 0 || ssid > 15)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alarm_handler(int sig)
|
||||||
|
{
|
||||||
|
axio_eolmode(NodeIo, EOLMODE_TEXT);
|
||||||
|
axio_puts("\n",NodeIo);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[05;31m");
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("%s} Inactivity timeout! Closing circuit... ", NodeId);
|
||||||
|
}
|
||||||
|
if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) {
|
||||||
|
node_msg("Inactivity timeout! Disconnecting you... ");
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
node_msg("Inactivity timeout! Disconnecting you...");
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[0;m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node_logout("User timed out");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void term_handler(int sig)
|
||||||
|
{
|
||||||
|
axio_eolmode(NodeIo, EOLMODE_TEXT);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("%s} Termination received!", NodeId);
|
||||||
|
} else {
|
||||||
|
node_msg("%s - System going down! Disconnecting...", FlexId);
|
||||||
|
}
|
||||||
|
node_logout("SIGTERM");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void quit_handler(int sig)
|
||||||
|
{
|
||||||
|
axio_eolmode(NodeIo, EOLMODE_TEXT);
|
||||||
|
node_logout("User terminated at remote");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct full_sockaddr_ax25 sax;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
struct sockaddr_rose srose;
|
||||||
|
#endif
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
} saddr;
|
||||||
|
int i, slen = sizeof(saddr);
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
char *p, buf[256], *pw;
|
||||||
|
#else
|
||||||
|
char *p, *pw;
|
||||||
|
#endif
|
||||||
|
int paclen;
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
FILE *fp;
|
||||||
|
#endif
|
||||||
|
int invalid_cmds = 0;
|
||||||
|
int no_password = 2;
|
||||||
|
int first_time = 1;
|
||||||
|
|
||||||
|
signal(SIGALRM, alarm_handler);
|
||||||
|
signal(SIGTERM, term_handler);
|
||||||
|
signal(SIGPIPE, quit_handler);
|
||||||
|
signal(SIGQUIT, quit_handler);
|
||||||
|
|
||||||
|
#ifdef HAVE_AX25
|
||||||
|
if (ax25_config_load_ports() == 0) {
|
||||||
|
node_log(LOGLVL_ERROR, "No AX.25 port data configured");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_NETROM
|
||||||
|
nr_config_load_ports();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
rs_config_load_ports();
|
||||||
|
#endif
|
||||||
|
if (getpeername(STDOUT_FILENO, (struct sockaddr *)&saddr, &slen) == -1) {
|
||||||
|
if (errno != ENOTSOCK) {
|
||||||
|
node_log(LOGLVL_ERROR, "getpeername: %s", strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
User.ul_type = AF_UNSPEC;
|
||||||
|
} else
|
||||||
|
User.ul_type = saddr.sax.fsa_ax25.sax25_family;
|
||||||
|
switch (User.ul_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
case AF_AX25:
|
||||||
|
strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call));
|
||||||
|
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) {
|
||||||
|
node_log(LOGLVL_ERROR, "getsockname: %s", strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(User.ul_name, ax25_config_get_port(&saddr.sax.fsa_digipeater[0]));
|
||||||
|
paclen = ax25_config_get_paclen(User.ul_name);
|
||||||
|
p = AX25_EOL;
|
||||||
|
break;
|
||||||
|
case AF_NETROM:
|
||||||
|
strcpy(User.call, ax25_ntoa(&saddr.sax.fsa_ax25.sax25_call));
|
||||||
|
strcpy(User.ul_name, ax25_ntoa(&saddr.sax.fsa_digipeater[0]));
|
||||||
|
if (getsockname(STDOUT_FILENO, (struct sockaddr *)&saddr.sax, &slen) == -1) {
|
||||||
|
node_log(LOGLVL_ERROR, "getsockname: %s", strerror(errno));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
strcpy(User.ul_port, nr_config_get_port(&saddr.sax.fsa_ax25.sax25_call));
|
||||||
|
paclen = nr_config_get_paclen(User.ul_port);
|
||||||
|
p = NETROM_EOL;
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
strcpy(User.call, ax25_ntoa(&saddr.srose.srose_call));
|
||||||
|
strcpy(User.ul_name, rose_ntoa(&saddr.srose.srose_addr));
|
||||||
|
paclen = rs_config_get_paclen(NULL);
|
||||||
|
p = ROSE_EOL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
case AF_INET6:
|
||||||
|
strcpy(User.ul_name, inet_ntoa(saddr.sin.sin_addr));
|
||||||
|
paclen = 1024;
|
||||||
|
p = INET_EOL;
|
||||||
|
break;
|
||||||
|
case AF_UNSPEC:
|
||||||
|
strcpy(User.ul_name, "local");
|
||||||
|
if ((p = get_call(getuid())) == NULL) {
|
||||||
|
node_log(LOGLVL_ERROR, "No uid->callsign association found", -1);
|
||||||
|
printf("Launching: telnet localhost 3694 ...\n");
|
||||||
|
printf("if this fails please RTFM to see how to properly configure it.\n - 73 de N1URO\a\n");
|
||||||
|
node_log(LOGLVL_ERROR, "Tool ran me from the console so I'm forcing", -1);
|
||||||
|
node_log(LOGLVL_ERROR, "a telnet session to port 3694/tcp on them.", -1);
|
||||||
|
/* axio_flush(NodeIo); */
|
||||||
|
if(NodeIo!=NULL)
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
if (system("telnet 127.0.0.1 3694") < 0 ) { /* VE3TOK - 18Nov2014, return value */
|
||||||
|
syslog(LOG_DEBUG, "Can't \"execute telnet 127.0.0.1 3694\"");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
node_log(LOGLVL_ERROR,"Closing console telnet session.", -1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strcpy(User.call, p);
|
||||||
|
paclen = 1024;
|
||||||
|
p = UNSPEC_EOL;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
node_log(LOGLVL_ERROR, "Unsupported address family %d", User.ul_type);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, paclen, p);
|
||||||
|
if (NodeIo == NULL) {
|
||||||
|
node_log(LOGLVL_ERROR, "Error initializing I/O");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_ZLIB_H
|
||||||
|
if (argc > 1 && strcmp(argv[1], "-c") == 0) {
|
||||||
|
axio_compr(NodeIo, 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
axio_tnmode(NodeIo, 1);
|
||||||
|
axio_tn_do_linemode(NodeIo);
|
||||||
|
}
|
||||||
|
init_nodecmds();
|
||||||
|
if (read_config() == -1) {
|
||||||
|
axio_end(NodeIo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
for(i=1;i<argc;i++) {
|
||||||
|
if (strcmp(argv[i],"--delay")==0) {
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
p = axio_getline(NodeIo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
User.state = STATE_LOGIN;
|
||||||
|
login_user();
|
||||||
|
if (User.call[0] == 0) {
|
||||||
|
axio_printf(NodeIo,"(%s:uronode) login: ", HostName);
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
alarm(60L); /* 1 min timeout */
|
||||||
|
if ((p = axio_getline(NodeIo)) == NULL)
|
||||||
|
node_logout("User disconnected");
|
||||||
|
alarm(0L);
|
||||||
|
strncpy(User.call, p, 9);
|
||||||
|
User.call[9] = 0;
|
||||||
|
strlwr(User.call);
|
||||||
|
}
|
||||||
|
if ((p = strstr(User.call, "-0")) != NULL)
|
||||||
|
*p = 0;
|
||||||
|
if (check_call(User.call) == -1) {
|
||||||
|
node_msg("%s - Invalid callsign", FlexId);
|
||||||
|
node_log(LOGLVL_LOGIN, "Invalid callsign %s @ %s", User.call, User.ul_name);
|
||||||
|
node_logout("Invalid callsign");
|
||||||
|
}
|
||||||
|
if ((pw = read_perms(&User, saddr.sin.sin_addr.s_addr)) == NULL) {
|
||||||
|
node_msg("Sorry, I'm not allowed to talk to you.");
|
||||||
|
node_log(LOGLVL_LOGIN, "Login denied for %s @ %s", User.call, User.ul_name);
|
||||||
|
node_logout("Login denied");
|
||||||
|
} else if (strcmp(pw, "*") != 0) {
|
||||||
|
node_msg("*** Password required! If you don't have a password please email\r\n%s for a password you wish to use.", Email);
|
||||||
|
axio_printf(NodeIo,"\rPassword: ");
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
axio_tn_will_echo(NodeIo);
|
||||||
|
axio_eolmode(NodeIo, EOLMODE_BINARY);
|
||||||
|
}
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
p = axio_getline(NodeIo);
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
axio_tn_wont_echo(NodeIo);
|
||||||
|
axio_eolmode(NodeIo, EOLMODE_TEXT);
|
||||||
|
/* axio_puts("\n",NodeIo); */
|
||||||
|
}
|
||||||
|
if (p == NULL || strcmp(p, pw) != 0) {
|
||||||
|
axio_printf(NodeIo, "\n");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("%s} Invalid or incorrect password...", NodeId);
|
||||||
|
} else {
|
||||||
|
node_msg("%s Invalid or incorrect password...", FlexId);
|
||||||
|
}
|
||||||
|
node_log(LOGLVL_LOGIN, "Login failed for %s @ %s", User.call, User.ul_name);
|
||||||
|
node_logout("Login failed");
|
||||||
|
}
|
||||||
|
no_password = 0;
|
||||||
|
};
|
||||||
|
free(pw);
|
||||||
|
examine_user();
|
||||||
|
ipc_open();
|
||||||
|
node_log(LOGLVL_LOGIN, "%s @ %s logged in", User.call, User.ul_name);
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
/* axio_printf(NodeIo, "%s} Welcome.\n", NodeId); */
|
||||||
|
} else
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
node_msg("\n\e[01;34m[\e[01;37m%s\e[01;34m]\e[0m\nWelcome %s to the %s packet shell.", VERSION, User.call, HostName);
|
||||||
|
} else if (check_perms(PERM_ANSI, 0L) == -1) {
|
||||||
|
node_msg("\n[%s]\nWelcome %s to the %s packet shell.", VERSION, User.call, HostName);
|
||||||
|
}
|
||||||
|
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
|
||||||
|
while (fgets(buf,256, fp) != NULL) axio_puts(buf,NodeIo);
|
||||||
|
axio_printf (NodeIo, "\n");
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
}
|
||||||
|
} else if (User.ul_type == AF_AX25) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
node_msg("\e[01;34m[\e[01;37m%s\e[01;34m]\e[0m - Welcome to %s", VERSION, FlexId);
|
||||||
|
} else
|
||||||
|
node_msg("%s - Welcome to %s", VERSION, FlexId);
|
||||||
|
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
|
||||||
|
while (fgets(buf, 256, fp) != NULL) axio_puts(buf,NodeIo);
|
||||||
|
axio_puts ("\n",NodeIo);
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
}
|
||||||
|
} else if (User.ul_type == AF_ROSE) {
|
||||||
|
node_msg("%s - Welcome to %s", VERSION, RoseId);
|
||||||
|
if ((fp = fopen(HAVEMOTD, "r")) != NULL) {
|
||||||
|
while (fgets(buf, 256, fp) != NULL) axio_puts(buf,NodeIo);
|
||||||
|
axio_puts ("\n",NodeIo);
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastlog();
|
||||||
|
#endif
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
while (1) { if (User.ul_type != AF_NETROM) {
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;34");
|
||||||
|
}
|
||||||
|
if (no_password == 2) {
|
||||||
|
node_prompt();
|
||||||
|
}
|
||||||
|
if (no_password == 1) {
|
||||||
|
node_prompt();
|
||||||
|
no_password = 2;
|
||||||
|
}
|
||||||
|
if (no_password == 0)
|
||||||
|
{
|
||||||
|
if (first_time == 1)
|
||||||
|
{
|
||||||
|
first_time = 0;
|
||||||
|
if (User.ul_type != AF_NETROM) {
|
||||||
|
/* node_prompt("3"); */
|
||||||
|
if ((User.ul_type == AF_AX25) || (User.ul_type == AF_ROSE)) {
|
||||||
|
node_prompt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((User.ul_type != AF_NETROM) && (User.ul_type != AF_ROSE)) {
|
||||||
|
node_prompt();
|
||||||
|
} else if ((User.ul_type == AF_NETROM) || (User.ul_type == AF_ROSE)) {
|
||||||
|
axio_printf(NodeIo,"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
/* Not needed from what I see so far. */
|
||||||
|
if (User.ul_type == AF_AX25) {
|
||||||
|
axio_printf(NodeIo,"\e[0m");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
User.state = STATE_IDLE;
|
||||||
|
time(&User.cmdtime);
|
||||||
|
update_user();
|
||||||
|
alarm(IdleTimeout);
|
||||||
|
errno = 0;
|
||||||
|
if ((p = axio_getline(NodeIo)) == NULL) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
|
node_logout("User disconnected");
|
||||||
|
};
|
||||||
|
alarm(IdleTimeout);
|
||||||
|
errno = 0;
|
||||||
|
time(&User.cmdtime);
|
||||||
|
update_user();
|
||||||
|
aliascmd = 0;
|
||||||
|
switch (cmdparse(Nodecmds, p))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
if (++invalid_cmds < 3) {
|
||||||
|
/* node_msg("%s Unknown command. Type ? for a list", NodeId); */
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("What?\007");
|
||||||
|
} else if (User.ul_type == AF_ROSE) {
|
||||||
|
axio_printf(NodeIo,"Que?\007");
|
||||||
|
} else if (User.ul_type == AF_INET) {
|
||||||
|
axio_printf(NodeIo, "Huh?\007");
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo,"Eh?\007");
|
||||||
|
}
|
||||||
|
node_log(LOGLVL_ERROR,"%s Tool tried bogus command", NodeId);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("%s Too many invalid commands. Disconnecting...", NodeId);
|
||||||
|
node_logout("Too many invalid commands");
|
||||||
|
} else {
|
||||||
|
node_msg("Too many invalid commands, disconnecting you...");
|
||||||
|
node_logout("Too many invalid commands");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
invalid_cmds = 0;
|
||||||
|
/* axio_puts ("\n",NodeIo); */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
invalid_cmds = 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
invalid_cmds = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node_logout("Out of main loop !?!?!?");
|
||||||
|
}
|
|
@ -0,0 +1,172 @@
|
||||||
|
#define VERSION "URONode v2.3.1"
|
||||||
|
#define COMPILING "February 14, 2015"
|
||||||
|
|
||||||
|
#define STATE_IDLE 0
|
||||||
|
#define STATE_TRYING 1
|
||||||
|
#define STATE_CONNECTED 2
|
||||||
|
#define STATE_PINGING 3
|
||||||
|
#define STATE_EXTCMD 4
|
||||||
|
#define STATE_LOGIN 5
|
||||||
|
#define STATE_QUIT 6
|
||||||
|
|
||||||
|
#define LOGLVL_NONE 0
|
||||||
|
#define LOGLVL_ERROR 1
|
||||||
|
#define LOGLVL_LOGIN 2
|
||||||
|
#define LOGLVL_GW 3
|
||||||
|
|
||||||
|
#define PERM_LOGIN 1 /* Permit login */
|
||||||
|
#define PERM_AX25 2 /* AX.25 gatewaying */
|
||||||
|
#define PERM_NETROM 4 /* NETROM gatewaying */
|
||||||
|
#define PERM_TELNET_LOCAL 8 /* Telnet to "local" hosts */
|
||||||
|
#define PERM_TELNET_AMPR 16 /* Telnet to 44.xx.xx.xx hosts */
|
||||||
|
#define PERM_TELNET_INET 32 /* Telnet to other hosts */
|
||||||
|
#define PERM_ANSI 64 /* Ansi Color graphics */
|
||||||
|
#define PERM_ROSE 128 /* ROSE gatewaying */
|
||||||
|
#define PERM_NOESC 256 /* No escape character */
|
||||||
|
#define PERM_HIDDEN 512 /* Use hidden ports - to be removed */
|
||||||
|
|
||||||
|
#define PERM_TELNET (PERM_TELNET_LOCAL & PERM_TELNET_AMPR & PERM_TELNET_INET)
|
||||||
|
|
||||||
|
/* Fake id for Flexnet */
|
||||||
|
#define AF_FLEXNET 128
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ipc.h> /* for key_t */
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25io.h>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
struct user
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
key_t ipc_key;
|
||||||
|
time_t logintime;
|
||||||
|
time_t cmdtime;
|
||||||
|
unsigned char state;
|
||||||
|
char call[10];
|
||||||
|
unsigned short ul_type;
|
||||||
|
unsigned short dl_type;
|
||||||
|
char ul_name[32];
|
||||||
|
char dl_name[32];
|
||||||
|
char ul_port[32];
|
||||||
|
char dl_port[32];
|
||||||
|
|
||||||
|
char unused[92];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct user User;
|
||||||
|
|
||||||
|
extern ax25io *NodeIo;
|
||||||
|
|
||||||
|
extern long IdleTimeout;
|
||||||
|
extern long ConnTimeout;
|
||||||
|
extern int ReConnectTo;
|
||||||
|
extern int LogLevel;
|
||||||
|
extern int EscChar;
|
||||||
|
extern int aliascmd;
|
||||||
|
|
||||||
|
extern char *Email;
|
||||||
|
extern char *HostName;
|
||||||
|
extern char *NodeId;
|
||||||
|
extern char *FlexId;
|
||||||
|
extern char *RoseId;
|
||||||
|
extern char *NrPort;
|
||||||
|
extern char *Prompt;
|
||||||
|
extern char *PassPrompt;
|
||||||
|
|
||||||
|
#define CMD_INTERNAL 1
|
||||||
|
#define CMD_ALIAS 2
|
||||||
|
#define CMD_EXTERNAL 3
|
||||||
|
|
||||||
|
struct cmd {
|
||||||
|
char *name;
|
||||||
|
int len;
|
||||||
|
int type;
|
||||||
|
int (*function) (int argc, char **argv);
|
||||||
|
char *command;
|
||||||
|
int flags;
|
||||||
|
int uid;
|
||||||
|
int gid;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
struct cmd *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct cmd *Nodecmds;
|
||||||
|
|
||||||
|
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
/* in cmdparse.c */
|
||||||
|
void free_cmdlist(struct cmd *list);
|
||||||
|
extern void insert_cmd(struct cmd **list, struct cmd *new);
|
||||||
|
extern int add_internal_cmd(struct cmd **list, char *name, int len, int (*function) (int argc, char **argv));
|
||||||
|
/* extern char *expand_string(char *str, int argc, char **argv); */
|
||||||
|
extern int parse_args(char **argv, char *cmd);
|
||||||
|
extern int cmdparse(struct cmd *cmdp, char *cmdline);
|
||||||
|
|
||||||
|
/* in util.c */
|
||||||
|
extern void node_msg(const char *fmt, ...);
|
||||||
|
extern void node_perror(char *str, int err);
|
||||||
|
extern char *print_node(const char *alias, const char *call);
|
||||||
|
extern void node_log(int, const char *, ...);
|
||||||
|
|
||||||
|
/* in user.c */
|
||||||
|
extern void login_user(void);
|
||||||
|
extern void logout_user(void);
|
||||||
|
extern void update_user(void);
|
||||||
|
extern int user_list(int argc, char **argv);
|
||||||
|
extern int user_count(void);
|
||||||
|
extern int system_user_count(void);
|
||||||
|
|
||||||
|
/* in config.c */
|
||||||
|
extern int is_hidden(const char *port);
|
||||||
|
extern int check_perms(int what, unsigned long peer);
|
||||||
|
extern char *read_perms(struct user *up, unsigned long peer);
|
||||||
|
extern int read_config(void);
|
||||||
|
extern int get_escape(char *s);
|
||||||
|
|
||||||
|
/* in command.c */
|
||||||
|
void init_nodecmds(void);
|
||||||
|
extern void node_logout(char *reason);
|
||||||
|
extern int nuser_list(int argc, char **argv);
|
||||||
|
extern int do_bye(int argc, char **argv);
|
||||||
|
extern int do_escape(int argc, char **argv);
|
||||||
|
extern int do_help(int argc, char **argv);
|
||||||
|
extern int do_host(int argc, char **argv);
|
||||||
|
extern int do_ports(int argc, char **argv);
|
||||||
|
extern int do_sessions(int argc, char **argv);
|
||||||
|
extern int do_routes(int argc, char **argv);
|
||||||
|
extern int do_nodes(int argc, char **argv);
|
||||||
|
extern int do_status(int argc, char **argv);
|
||||||
|
extern int do_version(int argc, char **argv);
|
||||||
|
extern int do_last(int argc, char **last);
|
||||||
|
|
||||||
|
/* in gateway.c */
|
||||||
|
extern int do_connect(int argc, char **argv);
|
||||||
|
extern int do_finger(int argc, char **argv);
|
||||||
|
extern int do_ping(int argc, char **argv);
|
||||||
|
|
||||||
|
/* in router.c */
|
||||||
|
extern int do_links(int argc, char **argv);
|
||||||
|
extern int do_dest(int argc, char **argv);
|
||||||
|
|
||||||
|
/* in ipc.c */
|
||||||
|
extern int ipc_open(void);
|
||||||
|
extern int ipc_close(void);
|
||||||
|
extern int do_msg(int argc, char **argv);
|
||||||
|
|
||||||
|
/* in extcmd.c */
|
||||||
|
extern int extcmd(struct cmd *cmdp, char **argv);
|
||||||
|
|
||||||
|
/* in system.c */
|
||||||
|
extern int do_system(int argc, char **argv);
|
||||||
|
extern int examine_user(void);
|
||||||
|
extern void newmail(void);
|
||||||
|
extern void mailcheck(void);
|
||||||
|
extern void lastlog(void);
|
||||||
|
|
||||||
|
/* in mheard.c */
|
||||||
|
extern int do_mheard(int argc, char **argv);
|
|
@ -0,0 +1,82 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/procutils.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
char *NodeId = "Nodeusers:";
|
||||||
|
int LogLevel = LOGLVL_NONE;
|
||||||
|
ax25io *NodeIo = NULL;
|
||||||
|
static void pipe_handler(int sig)
|
||||||
|
{
|
||||||
|
syslog(LOG_ERR, "received SIGPIPE");
|
||||||
|
axio_end(NodeIo);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int n, len = 1024;
|
||||||
|
char *cp = UNSPEC_EOL;
|
||||||
|
int inet = 0;
|
||||||
|
int logging = 0;
|
||||||
|
|
||||||
|
while ((n = getopt(argc, argv, "ail")) != -1) {
|
||||||
|
switch (n) {
|
||||||
|
case 'a':
|
||||||
|
cp = AX25_EOL;
|
||||||
|
len = 128;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
cp = INET_EOL;
|
||||||
|
inet = 1;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
logging = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "usage: nodeusers [-a] [-i] [-l]\r\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logging)
|
||||||
|
openlog("nodeusers", LOG_PID, LOG_DAEMON);
|
||||||
|
signal(SIGPIPE, pipe_handler);
|
||||||
|
NodeIo = axio_init(STDIN_FILENO, STDOUT_FILENO, len, cp);
|
||||||
|
if (NodeIo == NULL) {
|
||||||
|
fprintf(stderr, "nodeusers: axio_init failes\r\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (inet && axio_getline(NodeIo) == NULL) {
|
||||||
|
if (logging)
|
||||||
|
syslog(LOG_ERR, "axio_getline: %m");
|
||||||
|
axio_printf(NodeIo,"\n");
|
||||||
|
axio_end(NodeIo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
n = user_count();
|
||||||
|
axio_printf(NodeIo,"\n%s (%s), %d user%s.\n",
|
||||||
|
VERSION, COMPILING, n, n == 1 ? "" : "s");
|
||||||
|
user_list(0, NULL);
|
||||||
|
if (n > 0)
|
||||||
|
axio_printf(NodeIo,"\n");
|
||||||
|
if (axio_flush(NodeIo) == -1 && logging)
|
||||||
|
syslog(LOG_ERR, "axio_flush: %m");
|
||||||
|
axio_end(NodeIo);
|
||||||
|
usleep(500000L);
|
||||||
|
closelog();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,358 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include <netax25/mheard.h>
|
||||||
|
|
||||||
|
#include "procinfo.h"
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version of atoi() that returns zero if s == NULL.
|
||||||
|
*/
|
||||||
|
int safe_atoi(const char *s)
|
||||||
|
{
|
||||||
|
return (s == NULL) ? 0 : atoi(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Version of strncpy() that returns NULL if either src or dest is NULL
|
||||||
|
* and also makes sure destination string is always terminated.
|
||||||
|
*/
|
||||||
|
char *safe_strncpy(char *dest, char *src, int n)
|
||||||
|
{
|
||||||
|
if (dest == NULL || src == NULL) return NULL;
|
||||||
|
dest[n] = 0;
|
||||||
|
return strncpy(dest, src, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct proc_dev *read_proc_dev(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[256];
|
||||||
|
struct proc_dev *p;
|
||||||
|
struct proc_dev *list = NULL;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if ((fp = fopen(PROC_DEV_FILE, "r")) == NULL) return NULL;
|
||||||
|
while (fgets(buffer, 256, fp) != NULL) {
|
||||||
|
if (i++<2) continue;
|
||||||
|
if ((p = calloc(1, sizeof(struct proc_dev))) == NULL) break;
|
||||||
|
|
||||||
|
safe_strncpy(p->interface, strtok(buffer, ":\n\r"), 6);
|
||||||
|
while (*p->interface==' ') strcpy(p->interface, p->interface+1);
|
||||||
|
p->rx_bytes = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_packets = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_errs = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_drop = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_fifo = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_frame = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_compressed = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->rx_multicast = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_bytes = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_packets = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_errs = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_drop = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_fifo = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_colls = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_carrier = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->tx_compressed = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
p->next = list;
|
||||||
|
list = p;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_proc_dev(struct proc_dev *ap)
|
||||||
|
{
|
||||||
|
struct proc_dev *p;
|
||||||
|
|
||||||
|
while (ap != NULL) {
|
||||||
|
p = ap->next;
|
||||||
|
free(ap);
|
||||||
|
ap = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct flex_gt *read_flex_gt(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[256], *cp;
|
||||||
|
struct flex_gt *p=NULL, *list = NULL, *new_el;
|
||||||
|
int i = 0, k;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if ((fp = fopen(FLEX_GT_FILE, "r")) == NULL) return NULL;
|
||||||
|
while (fgets(buffer, 256, fp) != NULL) {
|
||||||
|
if (i++<1) continue;
|
||||||
|
if ((new_el = calloc(1, sizeof(struct flex_gt))) == NULL) break;
|
||||||
|
|
||||||
|
new_el->addr = safe_atoi(strtok(buffer, " \t\n\r"));
|
||||||
|
safe_strncpy(new_el->call, strtok(NULL, " \t\n\r"), 9);
|
||||||
|
safe_strncpy(new_el->dev, strtok(NULL, " \t\n\r"), 4);
|
||||||
|
|
||||||
|
k=0;
|
||||||
|
while((cp=strtok(NULL, " \t\n\r"))!=NULL&&k<AX25_MAX_DIGIS) safe_strncpy(new_el->digis[k++],cp,9);
|
||||||
|
while(k<AX25_MAX_DIGIS) strcpy(new_el->digis[k++],"\0");
|
||||||
|
|
||||||
|
if(list==NULL) {
|
||||||
|
list=new_el;
|
||||||
|
p=list;
|
||||||
|
} else {
|
||||||
|
p->next = new_el;
|
||||||
|
p=p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_flex_gt(struct flex_gt *fp)
|
||||||
|
{
|
||||||
|
struct flex_gt *p;
|
||||||
|
|
||||||
|
while (fp != NULL) {
|
||||||
|
p = fp->next;
|
||||||
|
free(fp);
|
||||||
|
fp = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct flex_dst *read_flex_dst(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[256];
|
||||||
|
struct flex_dst *p=NULL, *list = NULL, *new_el;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if ((fp = fopen(FLEX_DST_FILE, "r")) == NULL) return NULL;
|
||||||
|
while (fgets(buffer, 256, fp) != NULL) {
|
||||||
|
if (i++<1) continue;
|
||||||
|
if ((new_el = calloc(1, sizeof(struct flex_dst))) == NULL) break;
|
||||||
|
|
||||||
|
safe_strncpy(new_el->dest_call, strtok(buffer, " \t\n\r"), 9);
|
||||||
|
new_el->ssida = safe_atoi(strtok(NULL, " -\t\n\r"));
|
||||||
|
new_el->sside = safe_atoi(strtok(NULL, " -\t\n\r"));
|
||||||
|
new_el->rtt = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
new_el->addr = safe_atoi(strtok(NULL, " \t\n\r"));
|
||||||
|
|
||||||
|
if(list==NULL) {
|
||||||
|
list=new_el;
|
||||||
|
p=list;
|
||||||
|
} else {
|
||||||
|
p->next = new_el;
|
||||||
|
p=p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_flex_dst(struct flex_dst *fp)
|
||||||
|
{
|
||||||
|
struct flex_dst *p;
|
||||||
|
|
||||||
|
while (fp != NULL) {
|
||||||
|
p = fp->next;
|
||||||
|
free(fp);
|
||||||
|
fp = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ax_routes *read_ax_routes(void)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char buffer[256], *cp, *cmd;
|
||||||
|
struct ax_routes *p=NULL, *list = NULL, *new_el;
|
||||||
|
int i = 0, k;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
if ((fp = fopen(AX_ROUTES_FILE, "r")) == NULL) return NULL;
|
||||||
|
while (fgets(buffer, 256, fp) != NULL) {
|
||||||
|
if (i++<1) continue;
|
||||||
|
|
||||||
|
if(*buffer=='#' || *buffer==' ' ) continue; /* commented line */
|
||||||
|
cp=strchr(buffer, '#'); /* ignore comments */
|
||||||
|
if (cp) *cp='\0';
|
||||||
|
|
||||||
|
cmd=strtok(buffer, " \t\n\r");
|
||||||
|
if(cmd==NULL) continue; /* empty line */
|
||||||
|
|
||||||
|
if (strcasecmp(cmd,"route")==0) { /* add route */
|
||||||
|
if ((new_el = calloc(1, sizeof(struct ax_routes))) == NULL) break;
|
||||||
|
safe_strncpy(new_el->dest_call, strupr(strtok(NULL, " \t\n\r")), 9);
|
||||||
|
safe_strncpy(new_el->alias, strupr(strtok(NULL, " \t\n\r")), 9);
|
||||||
|
safe_strncpy(new_el->dev, strtok(NULL, " \t\n\r"), 13);
|
||||||
|
safe_strncpy(new_el->conn_type, strupr(strtok(NULL, " \t\n\r")), 1);
|
||||||
|
safe_strncpy(new_el->description, strtok(NULL, "'\t\n\r"), 50);
|
||||||
|
if (new_el->description==NULL) strcpy(new_el->description," ");
|
||||||
|
|
||||||
|
switch(*new_el->conn_type) {
|
||||||
|
case CONN_TYPE_DIRECT:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONN_TYPE_NODE:
|
||||||
|
{
|
||||||
|
safe_strncpy(new_el->digis[0], strupr(strtok(NULL, " \t\n\r")), 9);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONN_TYPE_DIGI:
|
||||||
|
{
|
||||||
|
k=0;
|
||||||
|
while((cp=strtok(NULL, " \t\n\r"))!=NULL&&k<AX25_MAX_DIGIS)
|
||||||
|
safe_strncpy(new_el->digis[k++],strupr(cp),9);
|
||||||
|
while(k<AX25_MAX_DIGIS) strcpy(new_el->digis[k++],"\0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(list==NULL) {
|
||||||
|
list=new_el;
|
||||||
|
p=list;
|
||||||
|
} else {
|
||||||
|
p->next = new_el;
|
||||||
|
p=p->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_ax_routes(struct ax_routes *ap)
|
||||||
|
{
|
||||||
|
struct ax_routes *p;
|
||||||
|
|
||||||
|
while (ap != NULL) {
|
||||||
|
p = ap->next;
|
||||||
|
free(ap);
|
||||||
|
ap = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ax_routes *find_route(char *dest_call, struct ax_routes *list)
|
||||||
|
{
|
||||||
|
static struct ax_routes a;
|
||||||
|
struct ax_routes *axrt=NULL, *p;
|
||||||
|
char *cp, call[10];
|
||||||
|
|
||||||
|
safe_strncpy(call,dest_call,9);
|
||||||
|
|
||||||
|
if ((cp = strchr(call, '-')) != NULL && *(cp + 1) == '0') *cp = 0;
|
||||||
|
axrt=list?list:read_ax_routes();
|
||||||
|
for (p=axrt;p!=NULL;p=p->next) {
|
||||||
|
if (!strcasecmp(call, p->dest_call)) {
|
||||||
|
a = *p;
|
||||||
|
a.next = NULL;
|
||||||
|
p = &a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!strcasecmp(call, p->alias)) {
|
||||||
|
a = *p;
|
||||||
|
a.next = NULL;
|
||||||
|
p = &a;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if (list==NULL) free_ax_routes(axrt);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct flex_dst *find_dest(char *dest_call, struct flex_dst *list)
|
||||||
|
{
|
||||||
|
static struct flex_dst f;
|
||||||
|
struct flex_dst *fdst=NULL, *p;
|
||||||
|
char *cp, call[10];
|
||||||
|
int ssid;
|
||||||
|
|
||||||
|
safe_strncpy(call, dest_call, 9);
|
||||||
|
cp=strchr(call,'-');
|
||||||
|
if (cp==NULL) ssid=0;
|
||||||
|
else {
|
||||||
|
ssid=safe_atoi(cp+1);
|
||||||
|
*cp='\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
fdst=list?list:read_flex_dst();
|
||||||
|
for (p=fdst;p!=NULL;p=p->next) {
|
||||||
|
if (!strcasecmp(call, p->dest_call) && (ssid>=p->ssida && ssid<=p->sside)) {
|
||||||
|
f = *p;
|
||||||
|
f.next = NULL;
|
||||||
|
p = &f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list==NULL) free_flex_dst(fdst);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct flex_gt *find_gateway(int addr, struct flex_gt *list)
|
||||||
|
{
|
||||||
|
static struct flex_gt f;
|
||||||
|
struct flex_gt *flgt=NULL, *p;
|
||||||
|
|
||||||
|
flgt=list?list:read_flex_gt();
|
||||||
|
for (p=flgt;p!=NULL;p=p->next) {
|
||||||
|
if (addr==p->addr) {
|
||||||
|
f = *p;
|
||||||
|
f.next = NULL;
|
||||||
|
p = &f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (list==NULL) free_flex_gt(flgt);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ax_routes *find_mheard(char *dest_call)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
static struct ax_routes a;
|
||||||
|
struct mheard_struct mh;
|
||||||
|
char call[12];
|
||||||
|
char *cp;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
if ((fp = fopen(DATA_MHEARD_FILE, "r")) == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_strncpy(call,dest_call,9);
|
||||||
|
cp=strchr(call, '-');
|
||||||
|
if (cp==NULL) strcat(call,"-0");
|
||||||
|
|
||||||
|
while (fread(&mh, sizeof(struct mheard_struct), 1, fp) == 1) {
|
||||||
|
if (strcasecmp(call, ax25_ntoa(&mh.from_call))==0) {
|
||||||
|
fclose(fp);
|
||||||
|
safe_strncpy(a.dest_call, ax25_ntoa(&mh.from_call), 9);
|
||||||
|
safe_strncpy(a.dev, mh.portname, 13);
|
||||||
|
for(k=0;k<AX25_MAX_DIGIS;k++) {
|
||||||
|
if (k<=mh.ndigis) safe_strncpy(a.digis[k],ax25_ntoa(&mh.digis[k]),9);
|
||||||
|
else strcpy(a.digis[k],"\0");
|
||||||
|
}
|
||||||
|
return &a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
#ifndef _PROCINFO_H
|
||||||
|
#define _PROCINFO_H
|
||||||
|
|
||||||
|
#define PROC_NR_FILE "/proc/net/nr"
|
||||||
|
#define PROC_DEV_FILE "/proc/net/dev"
|
||||||
|
|
||||||
|
/* VE3TOK 30Nov2014 - A number of defines moved to config.h */
|
||||||
|
|
||||||
|
#define CONN_TYPE_DIRECT 'D'
|
||||||
|
#define CONN_TYPE_NODE 'N'
|
||||||
|
#define CONN_TYPE_DIGI 'V'
|
||||||
|
|
||||||
|
struct proc_dev {
|
||||||
|
char interface[6];
|
||||||
|
int rx_bytes;
|
||||||
|
int rx_packets;
|
||||||
|
int rx_errs;
|
||||||
|
int rx_drop;
|
||||||
|
int rx_fifo;
|
||||||
|
int rx_frame;
|
||||||
|
int rx_compressed;
|
||||||
|
int rx_multicast;
|
||||||
|
int tx_bytes;
|
||||||
|
int tx_packets;
|
||||||
|
int tx_errs;
|
||||||
|
int tx_drop;
|
||||||
|
int tx_fifo;
|
||||||
|
int tx_colls;
|
||||||
|
int tx_carrier;
|
||||||
|
int tx_compressed;
|
||||||
|
|
||||||
|
struct proc_dev *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* /var/ax25/flex/gateways: (example)
|
||||||
|
* addr callsign dev dest digipeaters
|
||||||
|
* 00001 PI4TUE ax1 935
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct flex_gt {
|
||||||
|
int addr;
|
||||||
|
char call[10];
|
||||||
|
char dev[14];
|
||||||
|
char digis[AX25_MAX_DIGIS][10];
|
||||||
|
|
||||||
|
struct flex_gt *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* /usr/local/var/ax25/flex/destinations: (example)
|
||||||
|
* callsign ssid rtt gateway
|
||||||
|
* 9A0XZG 0-15 2575 00001
|
||||||
|
* DB0AAA 0-0 63 00001
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct flex_dst {
|
||||||
|
char dest_call[10];
|
||||||
|
unsigned short ssida;
|
||||||
|
unsigned short sside;
|
||||||
|
unsigned long rtt;
|
||||||
|
int addr;
|
||||||
|
|
||||||
|
struct flex_dst *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ax_routes {
|
||||||
|
char dest_call[10];
|
||||||
|
char alias[10];
|
||||||
|
char dev[14];
|
||||||
|
char conn_type[1];
|
||||||
|
char description[50];
|
||||||
|
char digis[AX25_MAX_DIGIS][10];
|
||||||
|
|
||||||
|
struct ax_routes *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int safe_atoi(const char *s);
|
||||||
|
extern char *safe_strncpy(char *dest, char *src, int n);
|
||||||
|
|
||||||
|
extern struct proc_dev *read_proc_dev(void);
|
||||||
|
extern void free_proc_dev(struct proc_dev *ap);
|
||||||
|
|
||||||
|
extern struct flex_gt *read_flex_gt(void);
|
||||||
|
extern void free_flex_gt(struct flex_gt *fp);
|
||||||
|
|
||||||
|
extern struct flex_dst *read_flex_dst(void);
|
||||||
|
extern void free_flex_dst(struct flex_dst *fp);
|
||||||
|
|
||||||
|
extern struct ax_routes *read_ax_routes(void);
|
||||||
|
extern void free_ax_routes(struct ax_routes *ap);
|
||||||
|
|
||||||
|
extern struct ax_routes *find_route(char *dest_call, struct ax_routes *list);
|
||||||
|
extern struct flex_dst *find_dest(char *dest_call, struct flex_dst *list);
|
||||||
|
extern struct flex_gt *find_gateway(int addr, struct flex_gt *list);
|
||||||
|
extern struct ax_routes *find_mheard(char *dest_call);
|
||||||
|
|
||||||
|
#endif /* _PROCINFO_H */
|
|
@ -0,0 +1,261 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
#include "procinfo.h"
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
|
||||||
|
int do_links(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct ax_routes *axrt, *p;
|
||||||
|
char digipath[AX25_MAX_DIGIS*10];
|
||||||
|
char tipoconn[9];
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if ((axrt=read_ax_routes()) == NULL) {
|
||||||
|
if (errno) node_perror("do_links: read_ax_routes", errno);
|
||||||
|
else axio_printf(NodeIo,"No known links");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "links" */
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[01;33m");
|
||||||
|
}
|
||||||
|
if (argc == 1) {
|
||||||
|
node_msg("AX25 Links:");
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Call Alias Description\n");
|
||||||
|
axio_printf(NodeIo,"--------- --------- -----------");
|
||||||
|
for(p=axrt;p!=NULL;p=p->next)
|
||||||
|
axio_printf(NodeIo,"\n%-9s %-9s %s", p->dest_call, p->alias, p->description);
|
||||||
|
free_ax_routes(axrt);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* "links d" */
|
||||||
|
if ((*argv[1]=='d') && (strlen(argv[1])==1)) {
|
||||||
|
node_msg("AX25 Direct Links:");
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Call Alias Interf Description\n");
|
||||||
|
axio_printf(NodeIo,"--------- --------- ------- -----------");
|
||||||
|
for(p=axrt;p!=NULL;p=p->next)
|
||||||
|
{ if (*p->conn_type==CONN_TYPE_DIRECT) axio_printf(NodeIo,"\n%-9s %-9s %-7s %s", p->dest_call, p->alias, p->dev, p->description); }
|
||||||
|
free_ax_routes(axrt);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* "links n" */
|
||||||
|
if ((*argv[1]=='n') && (strlen(argv[1])==1)) {
|
||||||
|
node_msg("AX25 Links via other nodes:");
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Call Alias Interf Routing Description\n");
|
||||||
|
axio_printf(NodeIo,"--------- --------- ------- --------- -----------");
|
||||||
|
for(p=axrt;p!=NULL;p=p->next)
|
||||||
|
{ if (*p->conn_type==CONN_TYPE_NODE) axio_printf(NodeIo,"\n%-9s %-9s %-7s %-9s %s", p->dest_call, p->alias, p->dev, p->digis[0], p->description); }
|
||||||
|
free_ax_routes(axrt);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* "links v" */
|
||||||
|
if ((*argv[1]=='v') && (strlen(argv[1])==1)) {
|
||||||
|
node_msg("AX25 Links via digipeaters:");
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Call Alias Interf Digipeaters\n");
|
||||||
|
axio_printf(NodeIo,"--------- --------- ------- -----------");
|
||||||
|
for(p=axrt;p!=NULL;p=p->next) {
|
||||||
|
*digipath='\0';
|
||||||
|
for(i=0;i<AX25_MAX_DIGIS;i++) {
|
||||||
|
if (p->digis[i]==NULL) break;
|
||||||
|
if (i!=0) strcat(digipath," ");
|
||||||
|
strcat(digipath, p->digis[i]);
|
||||||
|
}
|
||||||
|
if (*p->conn_type==CONN_TYPE_DIGI) axio_printf(NodeIo,"\n%-9s %-9s %-7s %s", p->dest_call, p->alias, p->dev, digipath);
|
||||||
|
}
|
||||||
|
free_ax_routes(axrt);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "links <call>" */
|
||||||
|
p=find_route(argv[1], axrt);
|
||||||
|
if(p!=NULL) {
|
||||||
|
node_msg("AX25 Link to %s:", p->dest_call);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Call Alias Interf Type Description\n");
|
||||||
|
axio_printf(NodeIo,"--------- --------- ------- -------- -----------");
|
||||||
|
switch(*p->conn_type) {
|
||||||
|
case CONN_TYPE_DIRECT:
|
||||||
|
{ strcpy(tipoconn,"Direct"); break; }
|
||||||
|
case CONN_TYPE_NODE:
|
||||||
|
{ strcpy(tipoconn,"Via Node"); break; }
|
||||||
|
case CONN_TYPE_DIGI:
|
||||||
|
{ strcpy(tipoconn,"Via Digi"); break; }
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"\n%-9s %-9s %-7s %-10s %s", p->dest_call, p->alias, p->dev, tipoconn, p->description);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo,"No such link");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_ax_routes(axrt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ssid buffer increased by 1 by VE3TOK */
|
||||||
|
int do_dest(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct flex_dst *fdst, *p;
|
||||||
|
struct flex_gt *flgt, *q;
|
||||||
|
char ssid[6];
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if ((fdst=read_flex_dst()) == NULL) {
|
||||||
|
axio_printf(NodeIo,"No known destinations");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "dest" */
|
||||||
|
if (argc == 1) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;33m");
|
||||||
|
}
|
||||||
|
if (User.ul_type != AF_AX25) {
|
||||||
|
axio_printf(NodeIo,"FlexNet Destinations:\n");
|
||||||
|
}
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
for (p=fdst;p!=NULL;p=p->next) {
|
||||||
|
sprintf(ssid, "%d-%d", p->ssida, p->sside);
|
||||||
|
axio_printf(NodeIo,"%-7s %-5s %4ld%s",p->dest_call,ssid,p->rtt,(++i % 4) ? " " : "\n");
|
||||||
|
}
|
||||||
|
if ((i % 4) != 0) axio_printf(NodeIo,"");
|
||||||
|
free_flex_dst(fdst);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((flgt=read_flex_gt()) == NULL) {
|
||||||
|
node_perror("do_dest: read_flex_gt", errno);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* "dest *" */
|
||||||
|
if (*argv[1]=='*') {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;33m");
|
||||||
|
}
|
||||||
|
node_msg("FlexNet Destinations:");
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Dest SSID RTT Gateway\n");
|
||||||
|
axio_printf(NodeIo,"-------- ----- ----- --------");
|
||||||
|
for(p=fdst;p!=NULL;p=p->next) {
|
||||||
|
sprintf(ssid, "%d-%d", p->ssida, p->sside);
|
||||||
|
q=find_gateway(p->addr,flgt);
|
||||||
|
axio_printf(NodeIo,"\n%-8s %-5s %5ld %-8s", p->dest_call, ssid,
|
||||||
|
p->rtt, q!=NULL?q->call:"?");
|
||||||
|
}
|
||||||
|
free_flex_dst(fdst);
|
||||||
|
free_flex_gt(flgt);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* "dest <call>" */
|
||||||
|
p=find_dest(argv[1], fdst);
|
||||||
|
if(p!=NULL) {
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo,"\e[01;33m");
|
||||||
|
}
|
||||||
|
node_msg("FlexNet Destination %s:", p->dest_call);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0;m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Dest SSID RTT Gateway\n");
|
||||||
|
axio_printf(NodeIo,"-------- ----- ----- -------");
|
||||||
|
sprintf(ssid, "%d-%d", p->ssida, p->sside);
|
||||||
|
q=find_gateway(p->addr,flgt);
|
||||||
|
axio_printf(NodeIo,"\n%-8s %-5s %5ld %-8s", p->dest_call, ssid, p->rtt, q!=NULL?q->call:"?");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo,"No such destination");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free_flex_dst(fdst);
|
||||||
|
free_flex_gt(flgt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
* This code is slightly modified from the procps package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
#include "sysinfo.h"
|
||||||
|
|
||||||
|
char *xmalloc(size_t);
|
||||||
|
char *fixup_null_alloc(size_t);
|
||||||
|
int read_utmp(char *);
|
||||||
|
int list_entries(int);
|
||||||
|
int who(void);
|
||||||
|
|
||||||
|
#define UPTIME_FILE "/proc/uptime"
|
||||||
|
#define LOADAVG_FILE "/proc/loadavg"
|
||||||
|
#define MEMINFO_FILE "/proc/meminfo"
|
||||||
|
|
||||||
|
#define STRUCT_UTMP struct utmp
|
||||||
|
static STRUCT_UTMP *utmp_contents;
|
||||||
|
|
||||||
|
#ifndef UTMP_FILE
|
||||||
|
#define UTMP_FILE "/var/run/utmp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef EMAILLEN
|
||||||
|
#define EMAILLEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef S_IWGRP
|
||||||
|
#define S_IWGRP 020
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char buf[300];
|
||||||
|
|
||||||
|
/* This macro opens FILE only if necessary and seeks to 0 so that successive
|
||||||
|
calls to the functions are more efficient. It also reads the current
|
||||||
|
contents of the file into the global buf.
|
||||||
|
*/
|
||||||
|
#define FILE_TO_BUF(FILE) { \
|
||||||
|
static int n, fd = -1; \
|
||||||
|
if (fd == -1 && (fd = open(FILE, O_RDONLY)) == -1) { \
|
||||||
|
close(fd); \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
lseek(fd, 0L, SEEK_SET); \
|
||||||
|
if ((n = read(fd, buf, sizeof buf - 1)) < 0) { \
|
||||||
|
close(fd); \
|
||||||
|
fd = -1; \
|
||||||
|
return 0; \
|
||||||
|
} \
|
||||||
|
buf[n] = '\0'; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SET_IF_DESIRED(x,y) if (x) *(x) = (y) /* evals 'x' twice */
|
||||||
|
|
||||||
|
int uptime(double *uptime_secs, double *idle_secs) {
|
||||||
|
double up=0, idle=0;
|
||||||
|
|
||||||
|
FILE_TO_BUF(UPTIME_FILE)
|
||||||
|
if (sscanf(buf, "%lf %lf", &up, &idle) < 2) {
|
||||||
|
printf("Bad data in %s\n", UPTIME_FILE );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SET_IF_DESIRED(uptime_secs, up);
|
||||||
|
SET_IF_DESIRED(idle_secs, idle);
|
||||||
|
return up; /* assume never be zero seconds in practice */
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadavg(double *av1, double *av5, double *av15) {
|
||||||
|
double avg_1=0, avg_5=0, avg_15=0;
|
||||||
|
|
||||||
|
FILE_TO_BUF(LOADAVG_FILE)
|
||||||
|
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
|
||||||
|
printf("Bad data in %s\n", LOADAVG_FILE );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SET_IF_DESIRED(av1, avg_1);
|
||||||
|
SET_IF_DESIRED(av5, avg_5);
|
||||||
|
SET_IF_DESIRED(av15, avg_15);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following /proc/meminfo parsing routine assumes the following format:
|
||||||
|
[ <label> ... ] # header lines
|
||||||
|
[ <label> ] <num> [ <num> ... ] # table rows
|
||||||
|
[ repeats of above line ]
|
||||||
|
|
||||||
|
Any lines with fewer <num>s than <label>s get trailing <num>s set to zero.
|
||||||
|
The return value is a NULL terminated unsigned** which is the table of
|
||||||
|
numbers without labels. Convenient enumeration constants for the major and
|
||||||
|
minor dimensions are available in the header file. Note that this version
|
||||||
|
requires that labels do not contain digits. It is readily extensible to
|
||||||
|
labels which do not *begin* with digits, though.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAX_ROW 27 /* these are a little liberal for flexibility */
|
||||||
|
#define MAX_COL 2
|
||||||
|
|
||||||
|
unsigned** meminfo(void) {
|
||||||
|
static unsigned *row[MAX_ROW + 1]; /* row pointers */
|
||||||
|
static unsigned num[MAX_ROW * MAX_COL]; /* number storage */
|
||||||
|
char *p;
|
||||||
|
int i, j, k, l;
|
||||||
|
|
||||||
|
FILE_TO_BUF(MEMINFO_FILE)
|
||||||
|
if (!row[0]) /* init ptrs 1st time through */
|
||||||
|
for (i=0; i < MAX_ROW; i++) /* std column major order: */
|
||||||
|
row[i] = num + MAX_COL*i; /* A[i][j] = A + COLS*i + j */
|
||||||
|
p = buf;
|
||||||
|
for (i=0; i < MAX_ROW; i++) /* zero unassigned fields */
|
||||||
|
for (j=0; j < MAX_COL; j++)
|
||||||
|
row[i][j] = 0;
|
||||||
|
for (i=0; i < MAX_ROW && *p; i++) { /* loop over rows */
|
||||||
|
while(*p && !isdigit(*p)) p++; /* skip chars until a digit */
|
||||||
|
for (j=0; j < MAX_COL && *p; j++) { /* scanf column-by-column */
|
||||||
|
l = sscanf(p, "%u%n", row[i] + j, &k);
|
||||||
|
p += k; /* step over used buffer */
|
||||||
|
if (*p == '\n' || l < 1) /* end of line/buffer */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* row[i+1] = NULL; terminate the row list, currently unnecessary */
|
||||||
|
return row; /* NULL return ==> error */
|
||||||
|
}
|
||||||
|
|
||||||
|
int system_user_count(void)
|
||||||
|
{
|
||||||
|
int users;
|
||||||
|
|
||||||
|
users=who();
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
|
int who(void)
|
||||||
|
{
|
||||||
|
int users;
|
||||||
|
|
||||||
|
users=read_utmp(UTMP_FILE);
|
||||||
|
return list_entries(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_utmp (filename)
|
||||||
|
char *filename;
|
||||||
|
{
|
||||||
|
FILE *utmp;
|
||||||
|
struct stat file_stats;
|
||||||
|
int n_read;
|
||||||
|
size_t size;
|
||||||
|
|
||||||
|
utmp = fopen (filename, "r");
|
||||||
|
if (utmp == NULL) return 0;
|
||||||
|
|
||||||
|
fstat (fileno (utmp), &file_stats);
|
||||||
|
size = file_stats.st_size;
|
||||||
|
if (size > 0)
|
||||||
|
utmp_contents = (STRUCT_UTMP *) xmalloc (size);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fclose (utmp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use < instead of != in case the utmp just grew. */
|
||||||
|
n_read = fread (utmp_contents, 1, size, utmp);
|
||||||
|
if (ferror (utmp) || fclose (utmp) == EOF || n_read < size) return 0;
|
||||||
|
|
||||||
|
return size / sizeof (STRUCT_UTMP);
|
||||||
|
}
|
||||||
|
int list_entries (n)
|
||||||
|
int n;
|
||||||
|
{
|
||||||
|
register STRUCT_UTMP *this = utmp_contents;
|
||||||
|
register int entries = 0;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
if (this->ut_name[0]
|
||||||
|
#ifdef USER_PROCESS
|
||||||
|
&& this->ut_type == USER_PROCESS
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
char trimmed_name[sizeof (this->ut_name) + 1];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
strncpy (trimmed_name, this->ut_name, sizeof (this->ut_name));
|
||||||
|
trimmed_name[sizeof (this->ut_name)] = ' ';
|
||||||
|
for (i = 0; i <= sizeof (this->ut_name); i++)
|
||||||
|
{
|
||||||
|
if (trimmed_name[i] == ' ')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
trimmed_name[i] = '\0';
|
||||||
|
|
||||||
|
/* tprintf("%s ", trimmed_name); */
|
||||||
|
entries++;
|
||||||
|
}
|
||||||
|
this++;
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *fixup_null_alloc (n)
|
||||||
|
size_t n;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
if (n == 0)
|
||||||
|
p = malloc ((size_t) 1);
|
||||||
|
if (p == 0) return NULL;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||||
|
|
||||||
|
char *xmalloc (n)
|
||||||
|
size_t n;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
p = malloc (n);
|
||||||
|
if (p == 0)
|
||||||
|
p = fixup_null_alloc (n);
|
||||||
|
return p;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef SYSINFO_H
|
||||||
|
#define SYSINFO_H
|
||||||
|
|
||||||
|
int loadavg(double *av1, double *av5, double *av15);
|
||||||
|
int uptime (double *uptime_secs, double *idle_secs);
|
||||||
|
|
||||||
|
unsigned** meminfo(void);
|
||||||
|
|
||||||
|
enum meminfo_row { meminfo_main = 0, meminfo_free, meminfo_buffers,
|
||||||
|
meminfo_cached, meminfo_scached, meminfo_active,
|
||||||
|
meminfo_inactive, meminfo_htotal, meminfo_hfree,
|
||||||
|
meminfo_ltotal, meminfo_lfree, meminfo_stotal,
|
||||||
|
meminfo_sfree, meminfo_dirty, meminfo_writeback,
|
||||||
|
meminfo_anonpages, meminfo_mapped, meminfo_slab,
|
||||||
|
meminfo_sreclaim, meminfo_sunreclaim, meminfo_pagetables,
|
||||||
|
meminfo_nfs_unstab, meminfo_bounce, meminfo_climit,
|
||||||
|
meminfo_cas, meminfo_vmtotal, meminfo_vmused,
|
||||||
|
meminfo_vmchunk
|
||||||
|
};
|
||||||
|
|
||||||
|
enum meminfo_col { meminfo_total = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned read_total_main(void);
|
||||||
|
|
||||||
|
#endif /* SYSINFO_H */
|
|
@ -0,0 +1,632 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <paths.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
#include <netax25/axconfig.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
#include "procinfo.h"
|
||||||
|
#include "config.h" /* VE3TOK - Dec20, 2014 */
|
||||||
|
|
||||||
|
#define USER_NOBODY "nobody"
|
||||||
|
|
||||||
|
#define NUMPTY 176
|
||||||
|
#define SYSTEM_TIMEOUT 7200
|
||||||
|
#define LAST_DATA_SIZE 120
|
||||||
|
|
||||||
|
int shell=0;
|
||||||
|
char *envp[16], *argp[16], mbox[40];
|
||||||
|
char other_id[20];
|
||||||
|
int in_queue=0;
|
||||||
|
int pid=-1;
|
||||||
|
char ptyname[80], Password[256];
|
||||||
|
int ptyfd;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int cusgets(char *buf, int buflen, ax25io *iop)
|
||||||
|
{
|
||||||
|
int c, len = 0;
|
||||||
|
|
||||||
|
while (len < (buflen - 1)) {
|
||||||
|
c = axio_getc(iop);
|
||||||
|
if (c == -1) {
|
||||||
|
if (len > 0) {
|
||||||
|
buf[len] = 0;
|
||||||
|
return (len);
|
||||||
|
} else return -1;
|
||||||
|
}
|
||||||
|
/* NULL also interpreted as EOL */
|
||||||
|
if (c == '\n' || c == '\r' || c == 0) {
|
||||||
|
buf[len++] = c;
|
||||||
|
buf[len] = 0;
|
||||||
|
return (len);
|
||||||
|
}
|
||||||
|
buf[len++] = c;
|
||||||
|
}
|
||||||
|
buf[buflen - 1] = 0;
|
||||||
|
return (buflen-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int find_pty(char *ptyname)
|
||||||
|
{
|
||||||
|
char master[80];
|
||||||
|
int fd;
|
||||||
|
int num;
|
||||||
|
static int lastnum = -1;
|
||||||
|
|
||||||
|
for(num = lastnum + 1; ; num++) {
|
||||||
|
if (num >= NUMPTY) num = 0;
|
||||||
|
sprintf(master, "/dev/pty%c%x", 'p' + (num >> 4), num & 0xf);
|
||||||
|
/* sprintf(master, "/dev/pts/%x", num & 0xf); */
|
||||||
|
if ((fd = open(master, O_RDWR | O_NONBLOCK, 0600)) >= 0) {
|
||||||
|
sprintf(ptyname, "/dev/tty%c%x", 'p' + (num >> 4), num & 0xf);
|
||||||
|
/* sprintf(ptyname, "/dev/pts/%x", num & 0xf); */
|
||||||
|
lastnum = num;
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
if (num == lastnum) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void login_close(void)
|
||||||
|
{
|
||||||
|
struct utmp utmpbuf, *ut;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (ptyfd > 0) {
|
||||||
|
chown(ptyname, 0, 0);
|
||||||
|
chmod(ptyname, 0666);
|
||||||
|
ioctl(ptyfd, TCFLSH, 2);
|
||||||
|
close(ptyfd);
|
||||||
|
}
|
||||||
|
if (pid>0) {
|
||||||
|
kill(pid, SIGHUP);
|
||||||
|
pid=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&utmpbuf, 0, sizeof(utmpbuf));
|
||||||
|
setutent();
|
||||||
|
utmpbuf.ut_type=LOGIN_PROCESS;
|
||||||
|
strcpy(utmpbuf.ut_line, ptyname+5);
|
||||||
|
strcpy(utmpbuf.ut_id, ptyname+strlen(ptyname)-2);
|
||||||
|
ut=getutid(&utmpbuf);
|
||||||
|
ut->ut_type=DEAD_PROCESS;
|
||||||
|
memset(ut->ut_host,0,UT_HOSTSIZE);
|
||||||
|
memset(ut->ut_user,0,UT_NAMESIZE);
|
||||||
|
time(&ut->ut_time);
|
||||||
|
/* ut->ut_xtime = (unsigned int)time(NULL); */
|
||||||
|
pututline(ut);
|
||||||
|
endutent();
|
||||||
|
if ((fp = fopen(_PATH_WTMP, "r+")) != NULL) {
|
||||||
|
fseek(fp, 0L, SEEK_END);
|
||||||
|
fwrite(ut, sizeof(utmpbuf), 1, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} Welcome back.\n", NodeId);
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo,"Welcome back.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int login_open(struct passwd *pw, char *command)
|
||||||
|
{
|
||||||
|
if ((ptyfd=find_pty(ptyname)) < 0) {
|
||||||
|
syslog(LOG_ERR, "Error opening pseudo terminal for %s", pw->pw_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog(LOG_INFO, "Opened pseudo terminal (%s) for %s", ptyname, pw->pw_name);
|
||||||
|
|
||||||
|
pid=fork();
|
||||||
|
|
||||||
|
if (pid==-1) {
|
||||||
|
syslog(LOG_ERR, "Cannot fork for %s", pw->pw_name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid==0) { /* child */
|
||||||
|
struct termios termios;
|
||||||
|
struct utmp utmpbuf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i=0;i<FD_SETSIZE;i++) close(i);
|
||||||
|
setsid();
|
||||||
|
open(ptyname, O_RDWR, 0666);
|
||||||
|
dup(0);
|
||||||
|
dup(0);
|
||||||
|
chmod(ptyname, 0622);
|
||||||
|
ioctl(0, TIOCSCTTY, 0);
|
||||||
|
|
||||||
|
memset(&termios, 0 , sizeof(termios));
|
||||||
|
termios.c_iflag = ICRNL | IXOFF;
|
||||||
|
termios.c_oflag = OPOST | ONLCR | TAB3;
|
||||||
|
termios.c_cflag = CS8 | CREAD | CLOCAL;
|
||||||
|
termios.c_lflag = ISIG | ICANON;
|
||||||
|
|
||||||
|
termios.c_cc[VINTR] = 127;
|
||||||
|
termios.c_cc[VQUIT] = 28;
|
||||||
|
termios.c_cc[VERASE] = 8;
|
||||||
|
termios.c_cc[VKILL] = 24;
|
||||||
|
termios.c_cc[VEOF] = 4;
|
||||||
|
|
||||||
|
cfsetispeed(&termios, B38400);
|
||||||
|
cfsetospeed(&termios, B38400);
|
||||||
|
tcsetattr(0, TCSANOW, &termios);
|
||||||
|
|
||||||
|
memset(&utmpbuf, 0, sizeof(utmpbuf));
|
||||||
|
utmpbuf.ut_type=USER_PROCESS; /* Type of login */
|
||||||
|
utmpbuf.ut_pid=getpid(); /* Pid of login process */
|
||||||
|
strcpy(utmpbuf.ut_line, ptyname+5); /* Devicename of tty */
|
||||||
|
strcpy(utmpbuf.ut_id, ptyname+strlen(ptyname)-2); /* Inittab id */
|
||||||
|
strcpy(utmpbuf.ut_user, pw->pw_name); /* Username */
|
||||||
|
strcpy(utmpbuf.ut_host, "local:uronode");
|
||||||
|
utmpbuf.ut_addr=0x7f000000;
|
||||||
|
time(&utmpbuf.ut_time); /* Time entry was made */
|
||||||
|
/* utmpbuf.ut_xtime = (unsigned int)time(NULL); */
|
||||||
|
|
||||||
|
setutent();
|
||||||
|
pututline(&utmpbuf);
|
||||||
|
endutent();
|
||||||
|
|
||||||
|
setgid(pw->pw_gid);
|
||||||
|
setuid(pw->pw_uid);
|
||||||
|
|
||||||
|
execve(command, argp, envp);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pid!=0) {
|
||||||
|
int k, cnt;
|
||||||
|
fd_set fds_read, fds_err;
|
||||||
|
struct timeval tv;
|
||||||
|
char buf[1500];
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
FD_ZERO(&fds_read);
|
||||||
|
FD_ZERO(&fds_err);
|
||||||
|
FD_SET(STDIN_FILENO, &fds_read);
|
||||||
|
/* FD_SET(User.fd, &fds_err); */
|
||||||
|
FD_SET(ptyfd, &fds_read);
|
||||||
|
/* FD_SET(ptyfd, &fds_err); */
|
||||||
|
|
||||||
|
if (User.ul_type==AF_INET) {
|
||||||
|
tv.tv_usec=25;
|
||||||
|
tv.tv_sec=0;
|
||||||
|
} else {
|
||||||
|
tv.tv_usec=750;
|
||||||
|
tv.tv_sec=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_queue>0) k=select(ptyfd+1, &fds_read, NULL, &fds_err, &tv);
|
||||||
|
else k=select(ptyfd+1, &fds_read, NULL, &fds_err, NULL);
|
||||||
|
|
||||||
|
if (k == -1) {
|
||||||
|
if (errno!=EINTR) {
|
||||||
|
syslog(LOG_DEBUG,"I/O select");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k == 0) {
|
||||||
|
if (in_queue>0) {
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
in_queue=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (FD_ISSET(User.fd, &fds_err)) {
|
||||||
|
syslog(LOG_DEBUG,"I/O end: error channel, user");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(ptyfd, &fds_err)) {
|
||||||
|
syslog(LOG_DEBUG,"I/O end: error channel, application");
|
||||||
|
break;
|
||||||
|
} */
|
||||||
|
|
||||||
|
if (FD_ISSET(STDIN_FILENO, &fds_read)) {
|
||||||
|
alarm(SYSTEM_TIMEOUT);
|
||||||
|
cnt=cusgets(buf, sizeof(buf), NodeIo);
|
||||||
|
if (cnt < 0)
|
||||||
|
{
|
||||||
|
syslog(LOG_DEBUG,"I/O end: stdio channel, user");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
write(ptyfd, buf, cnt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FD_ISSET(ptyfd, &fds_read)) {
|
||||||
|
alarm(SYSTEM_TIMEOUT);
|
||||||
|
cnt = read(ptyfd, buf, sizeof(buf));
|
||||||
|
if (cnt < 0) {
|
||||||
|
syslog(LOG_DEBUG,"I/O end: stdio channel, application");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for(k = 0 ; k < cnt ; k++) {
|
||||||
|
if (buf[k]=='\n' && (User.ul_type==AF_AX25 || User.ul_type==AF_FLEXNET || User.ul_type==AF_NETROM)) continue;
|
||||||
|
axio_putc(buf[k], NodeIo);
|
||||||
|
}
|
||||||
|
in_queue+=cnt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
login_close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int check_passwd(void)
|
||||||
|
{
|
||||||
|
char buffer[400]="",
|
||||||
|
tmp[100]="";
|
||||||
|
int pass[5],
|
||||||
|
level,i;
|
||||||
|
long timet;
|
||||||
|
|
||||||
|
char answer[81]="";
|
||||||
|
char buf[2048];
|
||||||
|
|
||||||
|
level=strlen(Password);
|
||||||
|
timet=time(NULL);
|
||||||
|
srandom((int) timet);
|
||||||
|
for(i=0;i<5;i++) pass[i]=(int) (level * (random()/(RAND_MAX+1.0)));
|
||||||
|
|
||||||
|
sprintf(buffer,"%10.10ld%s",timet,Password);
|
||||||
|
axio_printf(NodeIo,"%s %d %d %d %d %d [%010.10ld]\n",
|
||||||
|
PassPrompt,pass[0]+1,pass[1]+1,pass[2]+1,pass[3]+1,pass[4]+1,timet);
|
||||||
|
|
||||||
|
sprintf(answer,"%c%c%c%c%c",Password[pass[0]],Password[pass[1]],Password[pass[2]],Password[pass[3]],Password[pass[4]]);
|
||||||
|
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
axio_gets(buf, sizeof(buf), NodeIo);
|
||||||
|
|
||||||
|
|
||||||
|
if(strlen(buf)==32) i=strcmp(buf,tmp);
|
||||||
|
else i=strcmp(buf,answer);
|
||||||
|
|
||||||
|
if(i) {
|
||||||
|
axio_printf(NodeIo,"Password incorrect!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"URONode Shell engaged - use EXTREME caution! \n\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
int do_system(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct passwd *pw=NULL;
|
||||||
|
argp[0]=argv[0];
|
||||||
|
for(i=1;i<(argc);i++) argp[i]=argv[i];
|
||||||
|
argp[argc]=NULL;
|
||||||
|
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
if (other_id!=NULL && strcmp(other_id, USER_NOBODY)!=0) pw=getpwnam(other_id);
|
||||||
|
|
||||||
|
if (pw==NULL) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
node_msg("Permission denied\n");
|
||||||
|
syslog(LOG_INFO, "system: %s attempted command %s", User.call, argv[0]);
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (strncmp(argv[0],"sysop",strlen(argv[0]))==0)
|
||||||
|
{
|
||||||
|
if (shell==1) {
|
||||||
|
User.state = STATE_EXTCMD;
|
||||||
|
User.dl_type = AF_UNSPEC;
|
||||||
|
strcpy(User.dl_name, "sysop");
|
||||||
|
strupr(User.dl_name);
|
||||||
|
update_user();
|
||||||
|
if (check_passwd()==0) return 0;
|
||||||
|
login_open(pw, "/bin/bash");
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
node_msg("permission denied");
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
node_msg("unknown command");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int examine_user(void)
|
||||||
|
{
|
||||||
|
FILE *users;
|
||||||
|
char call[10], buf[1024], *cp, *ep;
|
||||||
|
char flags[40];
|
||||||
|
|
||||||
|
strcpy(other_id, USER_NOBODY);
|
||||||
|
|
||||||
|
if ((users=fopen(CONF_USERS_FILE, "r"))==NULL) {
|
||||||
|
node_msg("system: cannot open authority file: %s", CONF_USERS_FILE);
|
||||||
|
syslog(LOG_ERR, "system: cannot open authority file: %s", CONF_USERS_FILE);
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(call, User.call);
|
||||||
|
cp=strchr(call, '-');
|
||||||
|
if (cp) *cp='\0';
|
||||||
|
|
||||||
|
while(fgets(buf, 1024, users)) {
|
||||||
|
ep=strchr(buf, '#');
|
||||||
|
if (ep) *ep='\0';
|
||||||
|
if (*buf==0) continue;
|
||||||
|
cp=strtok(buf, ":\t\n\r");
|
||||||
|
if (cp==NULL) continue;
|
||||||
|
if (strcasecmp(cp, call)==0) {
|
||||||
|
cp=strtok(NULL, ":\t\n\r");
|
||||||
|
if (cp==NULL) continue;
|
||||||
|
strcpy(Password, cp);
|
||||||
|
cp=strtok(NULL, ":\t\n\r");
|
||||||
|
if (cp==NULL) continue;
|
||||||
|
strcpy(other_id, cp);
|
||||||
|
cp=strtok(NULL, ":\t\n\r");
|
||||||
|
if (cp==NULL) continue;
|
||||||
|
strcpy(flags, cp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(other_id, USER_NOBODY)==0) return 0;
|
||||||
|
|
||||||
|
cp=strtok(flags, " ,;-/\t\n\r");
|
||||||
|
if (cp==NULL) return 0;
|
||||||
|
do {
|
||||||
|
if (strcmp(cp, "shell")==0) {
|
||||||
|
shell=1;
|
||||||
|
add_internal_cmd(&Nodecmds, "SYSop", 1, do_system);
|
||||||
|
}
|
||||||
|
cp=strtok(NULL, " ,;-/\t\n\r");
|
||||||
|
} while(cp!=NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct nodelastlog {
|
||||||
|
char ll_user[8];
|
||||||
|
long ll_time;
|
||||||
|
char ll_line[LAST_DATA_SIZE];
|
||||||
|
char ll_host[LAST_DATA_SIZE];
|
||||||
|
int ll_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ipheardlastlog {
|
||||||
|
char ii_host[LAST_DATA_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
void lastlog(void)
|
||||||
|
{
|
||||||
|
struct nodelastlog ll;
|
||||||
|
int last;
|
||||||
|
int count=0;
|
||||||
|
int hit=0;
|
||||||
|
int UserId=0;
|
||||||
|
char tty[LAST_DATA_SIZE];
|
||||||
|
char hostname[LAST_DATA_SIZE];
|
||||||
|
char usercall[10];
|
||||||
|
char *cp;
|
||||||
|
int escape;
|
||||||
|
strcpy(usercall, User.call);
|
||||||
|
cp=strchr(usercall, '-');
|
||||||
|
if (cp) *cp='\0';
|
||||||
|
strcpy(tty, "");
|
||||||
|
switch (User.ul_type) {
|
||||||
|
case AF_FLEXNET: strcpy(hostname, "FlexNet");
|
||||||
|
break;
|
||||||
|
case AF_AX25: strcpy(hostname, "[");
|
||||||
|
strcat(hostname, "AX25");
|
||||||
|
strcat(hostname, "] ");
|
||||||
|
strcat(hostname, User.call);
|
||||||
|
if (strlen(User.ul_name)>0) {
|
||||||
|
strcat(hostname, " via ");
|
||||||
|
strcat(hostname, User.ul_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case AF_NETROM: strcpy(hostname, "<");
|
||||||
|
strcat(hostname, User.ul_port);
|
||||||
|
strcat(hostname, "> ");
|
||||||
|
strcat(hostname, User.call);
|
||||||
|
if (strlen(User.ul_name)>0) {
|
||||||
|
strcat(hostname, "@");
|
||||||
|
strcat(hostname, User.ul_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE: strcpy(hostname, User.call);
|
||||||
|
if (strlen(User.ul_name)>0) {
|
||||||
|
strcat(hostname, " at ");
|
||||||
|
strcat(hostname, User.ul_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET: strcpy(hostname, User.ul_name);
|
||||||
|
break;
|
||||||
|
case AF_UNSPEC: strcpy(hostname, User.call);
|
||||||
|
strcat(hostname, " on local");
|
||||||
|
break;
|
||||||
|
default: strcpy(hostname, "");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((last = open(DATA_NODE_LAST_FILE, O_RDWR, 0)) >= 0) {
|
||||||
|
lseek(last, (off_t)UserId * sizeof(ll), L_SET);
|
||||||
|
while (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0) {
|
||||||
|
if (strcmp(ll.ll_user,usercall)==0) {
|
||||||
|
escape = (check_perms(PERM_NOESC, 0L) == 0) ? -1 : EscChar;
|
||||||
|
#ifdef HAVEMOTD
|
||||||
|
/*
|
||||||
|
if (User.ul_type != AF_NETROM) {
|
||||||
|
axio_printf(NodeIo," Escape is: %s%c\n", escape < 32 ? "CTRL-" : "", escape < 32 ? (escape + 'A' - 1) : escape);
|
||||||
|
axio_printf(NodeIo,"Last login: %.*s ",24-5,(char *)ctime(&ll.ll_time));
|
||||||
|
if (*ll.ll_host != '\0') axio_printf(NodeIo,"\n From: %.*s\n",(int)sizeof(ll.ll_host), ll.ll_host);
|
||||||
|
else axio_printf(NodeIo," on %.*s\n",(int)sizeof(ll.ll_line), ll.ll_line);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
count=ll.ll_count;
|
||||||
|
hit++;
|
||||||
|
break;
|
||||||
|
} else UserId++;
|
||||||
|
}
|
||||||
|
lseek(last, (off_t)UserId * sizeof(ll), L_SET);
|
||||||
|
}
|
||||||
|
memset((char *)&ll, 0, sizeof(ll));
|
||||||
|
if ((hit==0) && (User.ul_type != AF_NETROM)) {
|
||||||
|
axio_printf(NodeIo,"Welcome, new user! Please use the Info and ? commands.\n\n");
|
||||||
|
count=0;
|
||||||
|
}
|
||||||
|
ll.ll_count=count+1;
|
||||||
|
(void)time(&ll.ll_time);
|
||||||
|
strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
|
||||||
|
strncpy(ll.ll_user, usercall, sizeof(ll.ll_user));
|
||||||
|
if (hostname) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
|
||||||
|
write(last, (char *)&ll, sizeof(ll));
|
||||||
|
close(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_last(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int last;
|
||||||
|
struct nodelastlog ll;
|
||||||
|
int Entries=0;
|
||||||
|
char call[10], *cp;
|
||||||
|
|
||||||
|
if ((last = open(DATA_NODE_LAST_FILE, O_RDONLY, 0)) <= 0) {
|
||||||
|
node_perror(DATA_NODE_LAST_FILE, errno);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Usage: Who <callsign or *>");
|
||||||
|
close(last);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(argv[1],"*")==0) {
|
||||||
|
cp=NULL;
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[01;37m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Logins for ALL:\n", call);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0m");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!ax25_aton_entry(argv[1], call)) {
|
||||||
|
strcpy(call,strupr(argv[1]));
|
||||||
|
cp=strchr(call,'-');
|
||||||
|
if (cp) *cp='\0';
|
||||||
|
cp=call;
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[01;37m");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Last online information for %s:\n", call);
|
||||||
|
if (check_perms(PERM_ANSI, 0L) != -1) {
|
||||||
|
axio_printf(NodeIo, "\e[0m");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"Usage: Who <callsign or *>\n");
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
close(last);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lseek(last, (off_t)Entries * sizeof(ll), L_SET);
|
||||||
|
/* while (Entries < 20 && (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time != 0)) { */
|
||||||
|
while (read(last, (char *)&ll, sizeof(ll)) == sizeof(ll) && ll.ll_time !=0) {
|
||||||
|
if (cp && strcasecmp(cp,ll.ll_user)!=0) continue;
|
||||||
|
if (Entries==0) {
|
||||||
|
axio_printf(NodeIo,"User Last Online Count From\n");
|
||||||
|
axio_printf(NodeIo,"------ -------------------- ----- -----------------------------");
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"\n%-10s ", ll.ll_user);
|
||||||
|
axio_printf(NodeIo,"%.*s ",24-5,(char *)ctime(&ll.ll_time));
|
||||||
|
axio_printf(NodeIo,"%-5d ",ll.ll_count);
|
||||||
|
if (*ll.ll_host != '\0') axio_printf(NodeIo," %.*s",(int)sizeof(ll.ll_host), ll.ll_host);
|
||||||
|
else axio_printf(NodeIo," on %.*s",(int)sizeof(ll.ll_line), ll.ll_line);
|
||||||
|
Entries++;
|
||||||
|
}
|
||||||
|
lseek(last, (off_t)Entries * sizeof(ll), L_SET);
|
||||||
|
|
||||||
|
close(last);
|
||||||
|
if (!cp && Entries==0) axio_printf(NodeIo,"No users in the lastlog database.");
|
||||||
|
if (cp && Entries==0) axio_printf(NodeIo,"%s Never logged in.", call);
|
||||||
|
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,289 @@
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <netax25/procutils.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
#include "sysinfo.h"
|
||||||
|
|
||||||
|
struct user User = {0};
|
||||||
|
static long CallerPos = -1L;
|
||||||
|
|
||||||
|
void login_user(void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
struct user u;
|
||||||
|
long pos = 0L;
|
||||||
|
long free = -1L;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
if (stat(DATA_NODE_LOGIN_FILE, &statbuf) == -1) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (statbuf.st_size % sizeof(struct user) != 0) {
|
||||||
|
node_msg("%s: Incorrect size", DATA_NODE_LOGIN_FILE);
|
||||||
|
node_log(LOGLVL_ERROR, "%s: Incorrect size", DATA_NODE_LOGIN_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
time(&User.logintime);
|
||||||
|
User.cmdtime = User.logintime;
|
||||||
|
User.pid = getpid();
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (flock(fileno(f), LOCK_EX) == -1) {
|
||||||
|
node_perror("login_user: flock", errno);
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (fread(&u, sizeof(u), 1, f) == 1) {
|
||||||
|
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH)) {
|
||||||
|
free = pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += sizeof(u);
|
||||||
|
}
|
||||||
|
if (free != -1L && fseek(f, free, 0L) == -1) {
|
||||||
|
node_perror("login_user: fseek", errno);
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fflush(f);
|
||||||
|
CallerPos = ftell(f);
|
||||||
|
fwrite(&User, sizeof(User), 1, f);
|
||||||
|
fflush(f);
|
||||||
|
flock(fileno(f), LOCK_UN);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void logout_user(void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (CallerPos == -1L)
|
||||||
|
return;
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fseek(f, CallerPos, 0) == -1) {
|
||||||
|
node_perror("logout_user: fseek", errno);
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
User.pid = -1;
|
||||||
|
fwrite(&User, sizeof(User), 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_user(void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
if (CallerPos == -1L)
|
||||||
|
return;
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r+")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (fseek(f, CallerPos, 0) == -1) {
|
||||||
|
node_perror("update_user: fseek", errno);
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fwrite(&User, sizeof(User), 1, f);
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
int user_count(void)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
struct user u;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
while (fread(&u, sizeof(u), 1, f) == 1)
|
||||||
|
if (u.pid != -1 && (kill(u.pid, 0) != -1 || errno != ESRCH))
|
||||||
|
cnt++;
|
||||||
|
fclose(f);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int user_list(int argc, char **argv)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
struct user u;
|
||||||
|
struct tm *tp;
|
||||||
|
struct proc_nr_nodes *np;
|
||||||
|
char buf[80];
|
||||||
|
long l;
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) {
|
||||||
|
node_perror(DATA_NODE_LOGIN_FILE, errno);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo, "%s} %s", NodeId, VERSION);
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
axio_printf(NodeIo, "\e[01;35m");
|
||||||
|
} else {
|
||||||
|
axio_printf(NodeIo, "Current users:");
|
||||||
|
}
|
||||||
|
if (user_count() == 0) {
|
||||||
|
axio_printf(NodeIo, " No users online.\n");
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_INET) {
|
||||||
|
axio_printf(NodeIo,"\e[0;m");
|
||||||
|
}
|
||||||
|
if (user_count() != 0) /* axio_printf(NodeIo,"") */ ;
|
||||||
|
while (fread(&u, sizeof(u), 1, f) == 1) {
|
||||||
|
if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH))
|
||||||
|
continue;
|
||||||
|
switch (u.ul_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
sprintf(buf, "\nFlexNet (%.9s)",
|
||||||
|
u.call);
|
||||||
|
break;
|
||||||
|
case AF_AX25:
|
||||||
|
sprintf(buf, "\nUplink (%.9s on interface %.10s)",
|
||||||
|
u.call, u.ul_name);
|
||||||
|
break;
|
||||||
|
case AF_NETROM:
|
||||||
|
if ((np = find_node(u.ul_name, NULL)) != NULL) {
|
||||||
|
sprintf(buf, "\nCircuit (%.9s %.18s)",
|
||||||
|
u.call,
|
||||||
|
print_node(np->alias, np->call));
|
||||||
|
} else {
|
||||||
|
sprintf(buf, "\nCircuit (%.9s %.18s)",
|
||||||
|
u.call, u.ul_name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
sprintf(buf, "\nROSE (%.9s %.18s)",
|
||||||
|
u.call, u.ul_name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
sprintf(buf, "\nTelnet (%.9s @ %.16s)",
|
||||||
|
u.call, u.ul_name);
|
||||||
|
break;
|
||||||
|
case AF_UNSPEC:
|
||||||
|
sprintf(buf, "\nHost (%.9s on local)",
|
||||||
|
u.call);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(buf, "\n?????? (%.9s %.18s)",
|
||||||
|
u.call, u.ul_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
axio_printf(NodeIo,"%-37.37s ", buf);
|
||||||
|
switch (u.state) {
|
||||||
|
case STATE_QUIT:
|
||||||
|
logout_user();
|
||||||
|
break;
|
||||||
|
case STATE_LOGIN:
|
||||||
|
axio_puts(" -> Logging in",NodeIo);
|
||||||
|
break;
|
||||||
|
case STATE_IDLE:
|
||||||
|
time(&l);
|
||||||
|
l -= u.cmdtime;
|
||||||
|
tp = gmtime(&l);
|
||||||
|
axio_printf(NodeIo," -> Idle (%d:%02d:%02d:%02d)",
|
||||||
|
tp->tm_yday, tp->tm_hour,
|
||||||
|
tp->tm_min, tp->tm_sec);
|
||||||
|
break;
|
||||||
|
case STATE_TRYING:
|
||||||
|
switch (u.dl_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
axio_printf(NodeIo," -> Trying (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
case AF_AX25:
|
||||||
|
axio_printf(NodeIo," -> Trying (%s on interface %s)",
|
||||||
|
u.dl_name, u.dl_port);
|
||||||
|
break;
|
||||||
|
case AF_NETROM:
|
||||||
|
axio_printf(NodeIo," -> Trying (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
axio_printf(NodeIo," -> Trying (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
axio_printf(NodeIo," -> Trying (%s:%s)",
|
||||||
|
u.dl_name, u.dl_port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
axio_puts(" -> ???",NodeIo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_CONNECTED:
|
||||||
|
switch (u.dl_type) {
|
||||||
|
case AF_FLEXNET:
|
||||||
|
axio_printf(NodeIo,"<--> FlexNet (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
case AF_AX25:
|
||||||
|
axio_printf(NodeIo,"<--> Downlink (%s on interface %s)",
|
||||||
|
u.dl_name, u.dl_port);
|
||||||
|
break;
|
||||||
|
case AF_NETROM:
|
||||||
|
axio_printf(NodeIo,"<--> Circuit (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
#ifdef HAVE_ROSE
|
||||||
|
case AF_ROSE:
|
||||||
|
axio_printf(NodeIo,"<--> ROSE (%s)",
|
||||||
|
u.dl_name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case AF_INET:
|
||||||
|
axio_printf(NodeIo,"<--> Telnet (%s:%s)",
|
||||||
|
u.dl_name, u.dl_port);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
axio_printf(NodeIo,"<--> ???");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_PINGING:
|
||||||
|
axio_printf(NodeIo,"<--> Pinging (%s)", u.dl_name);
|
||||||
|
break;
|
||||||
|
case STATE_EXTCMD:
|
||||||
|
axio_printf(NodeIo,"<--> Extcmd (%s)", u.dl_name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
axio_puts(" -> ??????",NodeIo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
axio_puts("",NodeIo);
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
node_msg("");
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netax25/ax25.h>
|
||||||
|
#include <netrose/rose.h>
|
||||||
|
#include <netax25/axlib.h>
|
||||||
|
|
||||||
|
#include "node.h"
|
||||||
|
#include "sysinfo.h"
|
||||||
|
#include "procinfo.h"
|
||||||
|
|
||||||
|
static char buf[256];
|
||||||
|
char *HostName;
|
||||||
|
char *Prompt;
|
||||||
|
|
||||||
|
void node_msg(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsprintf(buf, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
axio_printf(NodeIo,"%s\n", buf);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void node_prompt(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsprintf(buf, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
if (User.ul_type == AF_NETROM) {
|
||||||
|
axio_printf(NodeIo,"%s} ", NodeId);
|
||||||
|
}
|
||||||
|
if ((User.ul_type == AF_INET) && (check_perms(PERM_ANSI, 0L) != -1)) {
|
||||||
|
axio_printf(NodeIo,"\n\e[01;31m%s\e[0m@\e[01;34m%s\e[0m:/uronode$ ",User.call, HostName);
|
||||||
|
}
|
||||||
|
if ((User.ul_type == AF_INET) && (check_perms(PERM_ANSI, 0L) == -1)) {
|
||||||
|
axio_printf(NodeIo,"\n%s@%s:/uronode$ ", User.call, HostName);
|
||||||
|
}
|
||||||
|
if (User.ul_type == AF_AX25) {
|
||||||
|
axio_printf(NodeIo,"%s",Prompt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void node_perror(char *str, int err)
|
||||||
|
{
|
||||||
|
int oldmode;
|
||||||
|
|
||||||
|
oldmode = axio_eolmode(NodeIo, EOLMODE_TEXT);
|
||||||
|
buf[0] = 0;
|
||||||
|
if (str)
|
||||||
|
strcpy(buf, str);
|
||||||
|
if (str && err != -1)
|
||||||
|
strcat(buf, ": ");
|
||||||
|
if (err != -1)
|
||||||
|
strcat(buf, strerror(err));
|
||||||
|
axio_printf(NodeIo,"\nERROR; %s\n", buf);
|
||||||
|
axio_eolmode(NodeIo, oldmode);
|
||||||
|
axio_flush(NodeIo);
|
||||||
|
node_log(LOGLVL_ERROR, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *print_node(const char *alias, const char *call)
|
||||||
|
{
|
||||||
|
static char node[17];
|
||||||
|
|
||||||
|
sprintf(node, "%s%s%s",
|
||||||
|
!strcmp(alias, "*") ? "" : alias,
|
||||||
|
!strcmp(call, "*") ? "" : ":", call);
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void node_log(int loglevel, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
static int opened = 0;
|
||||||
|
va_list args;
|
||||||
|
int pri;
|
||||||
|
|
||||||
|
if (LogLevel < loglevel)
|
||||||
|
return;
|
||||||
|
if (!opened) {
|
||||||
|
openlog("uronode", LOG_PID, LOG_LOCAL7);
|
||||||
|
opened = 1;
|
||||||
|
}
|
||||||
|
switch (loglevel) {
|
||||||
|
case LOGLVL_ERROR:
|
||||||
|
pri = LOG_ERR;
|
||||||
|
break;
|
||||||
|
case LOGLVL_LOGIN:
|
||||||
|
pri = LOG_NOTICE;
|
||||||
|
break;
|
||||||
|
case LOGLVL_GW:
|
||||||
|
pri = LOG_INFO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pri = LOG_INFO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
va_start(args, fmt);
|
||||||
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||||
|
buf[sizeof(buf) - 1] = 0;
|
||||||
|
va_end(args);
|
||||||
|
syslog(pri, "%s", buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue