linpac-0.28/0000775000076400007640000000000014006074455007731 500000000000000linpac-0.28/Makefile.am0000664000076400007640000000251614006074433011705 00000000000000## Process this file with automake to produce Makefile.in ## Automake options should match the init call in configure.ac AUTOMAKE_OPTIONS = gnu -Wall -Werror ## See https://bugzilla.redhat.com/show_bug.cgi?id=901333 for more ## information about ACLOCAL_AMFLAGS ## The work-around for this bug is to commit the m4/ directory. ACLOCAL_AMFLAGS = -I m4 SUBDIRS = contrib ctt data doc macro mail src inst plugins dist_pkgdata_DATA = README NEWS EXTRA_DIST = linpac.lsm COPYING generate-ChangeLog.sh dist-hook: sh $(top_srcdir)/generate-ChangeLog.sh $(top_srcdir) $(distdir) .PHONY: noinstall noinstall: @if [ -x ./src/linpac ]; then \ (cd src && @LN_S@ applications bin >/dev/null 2>/dev/null); \ (cd src && @LN_S@ ../macro macro >/dev/null 2>/dev/null); \ (cd src && @LN_S@ ../mail mail >/dev/null 2>/dev/null); \ (cd src && mkdir save >/dev/null 2>/dev/null); \ (cd src && mkdir user >/dev/null 2>/dev/null); \ (cd src && mkdir log >/dev/null 2>/dev/null); \ (cd src/applications && @LN_S@ autobin autotx); \ (cd src/applications && @LN_S@ rawio rawtx); \ (cd src/applications && @LN_S@ yapp yapptx); \ (cd src/applications && @LN_S@ mailer/mail mail); \ cp ctt/*.ctt src; \ (cd src/applications/liblinpac && make install); \ echo LinPac is now prepared for running from ./src; \ else echo Please execute the 'make' command first; \ fi linpac-0.28/COPYING0000664000076400007640000004307614006074433010712 00000000000000 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. Copyright (C) 19yy 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. , 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. linpac-0.28/README0000664000076400007640000002251414006074433010531 00000000000000 LinPac version 0.28 (stable release) Copyright (c) 2021 by David Ranch (KI6ZHD) and Martin Cooper (KD6YAM) Linpac is a modular, Ncurses console-oriented AX.25 packet radio terminal with a built-in messaging client. Using Linux's native AX.25 network stack, it can support eight concurrent connected sessions (QSOs) as well as send UNPROTO packets (UI) to any preconfigured ax25 digi path. Local messaging support is currently fairly simple yet Linpac is designed to relay all messages to remote BBSes for full messaging if configured. Linpac "stable" currently supports an Ncurses-based CLI client but there is also an unstable Java-based client/server version with a GUI client that's partially operational but needs work. If you encounter any problems when compiling or using LinPac please go to http://linpac.sourceforge.net for support. Current contributors: - David Ranch (KI6ZHD) Packet radio mail: KI6ZHD@N0ARY.#NCA.CA.USA.NOAM - Martin Cooper (KD6YAM) - Polling load reduction; mail bug fixes; many warning cleanups - Jerry Dunmire (KA6HLD) - Auto-tools - Steven Loomis (K6SPI) - Misc patches Many thanks to the original author of Linpac for creating this flexible and valuable package for Linux: Radek Burget OK2JBG ( radkovo@centrum.cz ) QUICK INSTALATION FROM A RELEASE PACKAGE ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Release packages can be identified by the presence of the ./configure in this directory. If the ./configure script is not present, then see the 'Hacking' instructions below. Optional: --------- If you plan to use Linpac for recieving and sending your packet mail via a remote BBS system (not required), you must install the ax25mail-utils package first BEFORE first running Linpac. This package can be found at http://ax25mail.sf.net Before compilation of Linpac, you must have these other packages installed: NOTE: Though some distributions offer the AX25 libraries natively in their own repositories, they are usually very old and lack several important fixes. You can read more about these improvements here: https://github.com/ve7fet/linuxax25 Required dependencies: ~~~~~~~~~~~~~~~~~~~~~~ Debian / Ubunutu package names: libax25 ax25-apps libncurses5-dev perl Optional install: ax25-tools ax25-xtools ax25mail-utils Centos / Fedora package names: libax25 ax25apps ncurses-libs perl Optional install: ax25tools ax25mail-utils I recommend all users install or build the AX.25 stack from this alternative provider for now: https://github.com/ve7fet/linuxax25 Once you have installed the above dependencies, please run: ./configure NOTE: If the "configure" prompt isn't present, you probably got your source code from Git. If so, run the following: autoreconf --install ./configure If autoreconf doesn't run, it probably means you need to install Autotools: deb-based: sudo apt-get install automake autoconf rpm-based yum install automake autoconf If "autoreconf --install" fails with: src/applications/liblinpac/Makefile.am:4: error: Libtool library used but 'LIBTOOL' is undefined src/applications/liblinpac/Makefile.am:4: The usual way to define 'LIBTOOL' is to add 'LT_INIT' src/applications/liblinpac/Makefile.am:4: to 'configure.ac' and run 'aclocal' and 'autoconf' again. src/applications/liblinpac/Makefile.am:4: If 'LT_INIT' is in 'configure.ac', make sure src/applications/liblinpac/Makefile.am:4: its definition is in aclocal's search path. Do the following: deb-based: sudo apt-get install libtool libtoolize autoreconf --install rpm-based: sudo yum install libtool libtoolize autoreconf --install The default installation destination directory prefix is /usr/local/*. If you want to change this, add the following configuure --prefix switch: ./configure --prefix=DIR where DIR is the new destination directory prefix. (LinPac installs into PREFIX/bin and PREFIX/share/linpac) After this just type make to compile the package. At that point, you can install the application a few ways: For Debian/Ubuntu folks: -- Consider using the "checkinstall" tool instead of "make install". This tool must be installed seperately but it will run the equivelent of "make install" but instead, wrap everything into an unofficial .deb file with proper packaging or For rpm based folks: -- Consider using the included contrib/packaging/rpm/linpac.spec file with the rpmbuild tool. This tool must be installed seperately but takes care of creating a clean RPM package to install or # The old classic way make install ldconfig or make install-strip ldconfig One of these options will install Linpac onto your system. The "install-strip" command will also strip the debugging information from the program (the installation is then MUCH SMALLER) but harder to report issues to the developer. ONCE INSTALLED ~~~~~~~~~~~~~~ Once Linpac is installed, you MUST configure the Linux AX.25 system first. Linpac is only an application that uses a fully functional AX.25 stack. Please review the various resources on the Internet on how to do this such as: - Official AX25 HOWTO (old, dated but still useful) http://tldp.org/HOWTO/AX25-HOWTO/ - John Ackermann's pages: http://www.febo.com/packet/linux-ax25/ax25-config.html - David Ranch's pages: http://www.trinityos.com/HAM/CentosDigitalModes/hampacketizing-centos.html#7.ax25initsetup KNOWN PROBLEMS ~~~~~~~~~~~~~~ - There are reported issues with Ncurses 6.1 (not 6.0) and Linpac where this buggy 6.1 version is present in Raspbian Buster (10.1), Ubuntu 18.04, etc. Examples include: * in the monitor window, the first character is sometimes being cut off, but many times it's not cut off and looks fine. * in the mail window, weird things are going on with the "background window" A workaround for now is to run the following command before you run Linpac: export TERM="simpleterm" - Signifincant issue with AX.25 and Raspbian Stretch I have confirmed that with Raspian Stretch, there is some sort of conflict with it's newly enabled predictable network interface names. What are those? If you run the command "ifconfig" or "ip addr", you will no longer see Ethernet interfaces with names like "eth0" but instead, you'll see something like "enxb827eb5f05". How's that for catchy? For known reasons to the AX.25 kernel maintainers, in the sa_data kernel data structure, both the stock Raspbian AX.25 .debs and the 3rd party VE7FET ax.25 debs will give errors like the following when ANY network interface name is longer than 13 characters: SIOCGIFHWADDR: No such device Programs like beacon will fail to start. Linpac will also crash upon start with /usr/bin/linpac: line 181: 9811 Segmentation fault $PKG_BINDIR/linpac $* Fortunately, if you disable predictable network interface names, things work fine. To do this, do the following steps: sudo vi /boot/cmdline.txt #append the following to the end of the one line in this file net.ifnames=0 biosdevname=0 Reboot your Raspberry Pi and things will work from there on out. Btw, if Linpac crashed on you, your terminal might be screwed up and not working properly. To fix that, run the commands: stty sane rm -f rm /var/lock/LinPac.0 - The --enable-LINKSTATIC configuration option does not work. Please see the linpac-todo.txt file in this source package as well as see http://linpac.sf.net for other possible problems and their solutions. NOTES FOR HACKING with the Source code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's always recommended to start with the "develop" Git branch as it will always have the newest code. From there, a clean checkout from the source repository is not ready to configure and compile. You will need the GNU autotools (https://en.wikipedia.org/wiki/GNU_build_system) to create the ./configure script and Makfile templates. Once the autotools are installed the full build procedure is: autoreconf --install ./configure make make install You can make a release package for distribution using: make dist For debugging Linpac, it is useful to run Linpac in the place of compile without installing it. For this the command 'make noinstall' can be used. This will create the directory structure in the ./src directory. This is only available with the staticaly linked applications. CONFIGURATION OPTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Most of the configuration options are described in the INSTALL file. [broken at the moment] There is one custom option for linpac; --enable-LINKSTATIC. The applicatons are linked using the shared library by default (the library liblinpac.so is installed in /usr/local/lib). You can link all the applications staticaly by running configure --enable-LINKSTATIC linpac-0.28/doc/0000775000076400007640000000000014006074455010476 500000000000000linpac-0.28/doc/manual.html0000664000076400007640000020031214006074433012553 00000000000000 LinPac User Manual

LinPac - Packet Radio Terminal for Linux

Version 0.28

(c) 2020 - 1998 by David Ranch KI6ZHD


User manual

Index

1 What is LinPac

2 First configuration

3 LinPac controls
3.1 Keyboard
3.2 Entering commands
3.3 Initiating a connection
3.4 Receiving and sending files
3.5 Remote commands
3.6 Character encoding
3.7 Huffman compression

4 Variables
4.1 Special variables

5 Station database
5.1 The station.data file format
5.2 The 'Name' command
5.3 Using the database

6 About macros
6.1 Creating macros
6.2 Commands used in macros
6.3 Special system macros

7 Creating new commands

8 Standard applications
8.1 File transfer protocols
8.2 Automatic password generation
8.2.1 Login passwords
8.2.2 Sysop and general use passwords
8.3 Utilities for mail exchange
8.4 Mail client
8.5 Logbook

9 Command line options

10 Copying

Appendix A: List of LinPac commands

Appendix B: Linpac FAQ / Questions and Answers / Getting more help

Appendix C: Errata


1 What is LinPac

LinPac is a packet radio terminal for Linux that allows wide configurability and easy addition of new functions and special functions needed by the user. The aim is to minimize the amount of 'hard coded' functions and create a complete set of applications that can be easy expanded and/or completely reconfigured.

All functions described in this manual match the standard configuration that comes with the distribution package.

2 First configuration

When linpac is started for the first time on your computer, it automaticaly creates the directory called LinPac in the running user's home directory. This directory will contain the user's personal LinPac configuration settings. After creating this directory, LinPac asks for basic callsign, port and other information and prepares a useable configuration for you. An example setup dialog is as shown, where we are using the bogus call "n0call" logging into the local home BBS "n0ary-1":
    $ linpac
    
    Hello dear user. You seem to run LinPac for the first time.
    LinPac has to create a directory in your home directory for storing
    your personal configuration.
    
    For creating your personal configuration please answer following questions:
    
    Your callsign:
    n0call
    
    Enter your home BBS callsign with SSID :
    n0ary-1
    
    Enter the name of port to connect N0ARY-1
    d710
    
    Enter the digipeaters used to connect N0ARY-1 or press enter
    when no digipeaters are used:
    
    
    Enter the full hierarchical address of N0ARY-1
    (e.g. #MOR.CZE.EU)
    #NCA.CA.USA.NOAM
    
    Thank you, N0CALL
    Please wait a moment for creating your personal configuration
    Installation done.
    Press ENTER to run LinPac
    

The above information is then stored in the $HOME/LinPac/macro/init.mac file as various 'functions'. These functions are based on the very simple interpreted language (actually it's not a language but something like the batch files in DOS). In the LinPac/macro directory are all the scripts written in this language. The init.mac macro is loaded at start of loading Linpac and contains the commands to setup the callsigns and other settings. You can modify this file to change the initial configuration of LinPac. Other macros can be run in LinPac as desired or required. The simplest case of a macro is a normal text file that is just printed to the screen (or sent to the remote peer) when executed. The language is described in chapter 6.

You may also want to review or change following macro files:

  • info.mac - contains information about your system
  • ctext.mac - executed when the peer connects and should contain the greeting text
  • quit.mac - called when user enters the Quit command (end of connection) and should print some farewell text and disconnect

After this you should be able to make your first connection.

3 LinPac controls

After automatically running the LinPac setup routine, the main screen should appear. If you see a segmentation fault, please see Linux AX.25 issues with long predictable network interface names for a work around. Moving on, in Linpac's main interface in the standard configuraion, the screen is divided into five parts (described from the top of the screen to the bottom):

  • QSO window: this window contains the text that came from the peer and also the sent text and some special messages (different text colours).
  • Status line: displays your callsign, current time and some information about the current connection.
  • Editor: allows you to enter the text you want to send to the peer or the commands you want to execute
  • Channel list: displays the list of channels with the callsign of connected users. The currently selected channel is highlighted.
  • Monitor : displays the traffic on your radio ports

LinPac is mostly driven by commands. The commands are entered using the editor and must start with a colon (':') in the first column. Lines that don't begin with a colon are sent to the peer, if connected.

LinPac allows up to eight connections to be made simultaneously. For each connection one channel is used. You can switch between channels by pressing the F1 - F8 keys. Each has its own QSO window, status line and editor. The channel list and the monitor are common across all the channels.

There is a special channel invoked by pressing F10. This channel has no QSO window and doesn't allow making a connection. The text written is sent out immediately using UI frames (beacon).

3.1 Keyboard

The following list contains the important shortcuts:

    Global
    F1 - F8 : switch to channel 1 - 8
    F10 : switch to monitor
    Alt-X : end of LinPac

    QSO Window
    PgUp, PgDn, ctrl-R, ctrl-V : scroll one page up / down
    ctrl-E, ctrl-X : scroll one line up / down
    ctrl-B : skip to end of buffer

    Editor
    Cursor keys, Home, End, Backspace, Del : text editing
    ctrl-Y : delete current line
    Enter : send current line

Some applications (e.g. mailer) can use the whole screen. Each channel can run only one such application at a time. It's possible to switch to this application using Alt-<channel_number> (e.g. Alt-5) and switch back to terminal using F1 - F10.

3.2 Entering commands

Each command is invoked using its name. Some commands can be abbreviated. In this manual the mandatory part is always written in upper case. The remainder of the command name is optional. Some commands require some extra arguments. The arguments are written after the command and are separated by one or more spaces. If you want to enter an argument containing more than one word, that argument must be entered in quotation marks.

Examples:

    :color red blue - calls the 'color' command with two arguments - 'red' and 'blue'
    :color 'light red' or
    :color "light red" - calls the 'color' command with one argument 'light red'

Most of the commands work on the currently selected channel. If you want to execute the command on some other channel, you can enter the number of the channel this way. For example, to make an OUTGOING connection to destination OK0PAB on Linpac channel 5:

    :connect@5 OK0PAB

In this case the 'connect' command is executed on channel 5.

The complete list of commands with descriptions is available in Appendix A.

3.3 Initiating a connection

To initiate a connection the :Connect command is used. Just switch to the channel you want to use by pressing F1 - F8 and enter the following command:

:connect CALLSIGN

Replace the CALLSIGN with the real callsign of the station you want to connect. The command can be abbreviated to the first letter only. Example:

:c OK0PAB

This command will initiate the connecting sequence to OK0PAB. To close the connection, you can use the :Disconnect command by entering

:d

When your system has multiple radio ports, you can specify its name before the callsign like this:

:c 2:OK0PAB

This command will try to connect OK0PAB via port 2. When no port name is specified, the default one is used. Initially the default port is the first port in /etc/axports (your system AX.25 port configuration file). If you want to change the default port, just use the command :port.

:port 2

This will change the default port name to '2'. In some cases it is useful to set another default port for some selected channels. For this the variable CHN_PORT can be used (see chapter 4). When set, the content of this variable overrides the default port selection for the particular channel. For example, when you set the variable for channel 4 using

:set CHN_PORT@4 1

the port '1' will be used as the default one for the channel 4. For other channels, the previously set default port will be used.

3.4 Receiving and sending files

The standard distribution can receive files using plain text or binary transfer and using file transfer protocols YAPP and Autobin. LinPac will automaticaly start to receive the file when the peer begins to send using the YAPP or Autobin protocols. The 7+ files are automaticaly saved too. When you want to save the incoming text you have to use the command

:Write <filename>

The incoming text will be saved until you stop the saving using

:Write off

For receiving a plain binary file, the corresponding command :WBin can be used. This way of transferring binary files is not recommended; use the autobin or yapp protocol instead.

The following commands are available for sending files:

    :rprg <filename> - sends the file using the Autobin protocol
    :yput <filename> - sends the file using the YAPP protocol
    :rbin <filename> - sends the binary file (no protocol - not recommended)
    :read <filename> - semds the text file

3.5 Remote commands

LinPac allows the remote user to enter commands. For remote control, all LinPac commands are available but there can be (and should be) some restrictions for each user.

The remote command must start with the // sequence. For example if some connected user sends you the text '//info' your terminal will send back the station information.

The remote commands can be disabled using the command :remote off and enabled by :remote on. You can also specify that only some commands be available for remote users. The default list of available remote commands is defined in the init.mac file (the DEF_RCMD line). It is also possible to enable various commands for each user. This is described in chapter 5.

3.6 Character encoding

Some countries use different national character encodings for some historical reasons. A user who has his Linux console configured for example for some of the standard ISO encodings may be incompatible with another one using a traditional encoding. To solve this LinPac allows the translation of the input and output of each channel using a translation table. The translation tables are stored in files *.ctt in the LinPac home directory.

All known encodings must be defined in the file called encodings in the LinPac home directory. This file contains a single line for each encoding that specifies its alias (name which will identify the encoding in LinPac), encoding name (an official name such as iso-8859-1) and optionally the name of the translation table file to be used (without the extension .ctt).

Note that LinPac does not support multi-byte encodings such as UTF-8 or other Unicode encodings.

The current encoding can be switched using the :TRanslate command separately for each channel. To specify the default encoding for each user you can add the line

ENC=<alias>

to the appropriate record in the station database. (The station database is described in chapter 5.) When no encoding is specified for the user, the default one is used. The default encoding alias is stored in the DEF_ENC@0 variable which is set in the macro init.mac.

When the conversion table is not specified in the encodings file LinPac only changes the name of currently used encoding but doesn't provide any conversion. However some applications (such as QLinPac which works in unicode) are able to do their own conversions.

3.7 Huffman compression

Some packet radio terminals and BBS software allows the compression of transferred text. When switched on, the sender does the compression of all data before sending them to the other station and the recipient has to decompress the data after receiving them. This makes the communication more reliable and reduces the load of the radio link.

The line compression in LinPac is activated using the :comp command. The compression is switched on using :comp on and switched off using :comp off. To ensure that the compression is activated or deactivated on both ends of the link simultaneously LinPac sends the remote command :comp 1 or :comp 0 to the other station automatically. The arguments 1 and 0 have the same effect as on and off, but they don't cause sending any command to the other station.

In the case in which the remote system doesn't support the :comp command it's necessary to switch on the compression on the remote system manually and then use the:comp 1 command in LinPac.

4 Variables

Each channel has its own set of variables. Some of the variables are used to store the configuration data. The user can create and remove variables and change the values of existing variables using following commands:

    :set <variable> <value> - sets the value of the variable. If the variable doesn't exist, a new one is created.
    :get <variable> - prints the value of the variable
    :unset <variable> - removes the variable

Some examples:

    :set NAME John
    :set WHOLE_NAME 'John Big'
    :get NAME
    :unset NAME

The name of the variable can contain the specification of the channel. For example the variable NAME@5 is the variable 'NAME' defined on channel 5.

When LinPac finds the character '%' followed by the name of variable, it automatically replaces this text with the value of the variable. Considering the previous example, the text %NAME will be replaced with John.

4.1 Special variables

There are some special internal variables that don't allow changing their value. Their value is set and changed directly by LinPac and these variables can be used to add some actual information to the text. The list follows:

    %V - LinPac version (e.g. 0.26)
    %C - The callsign of connected station
    %N - The name of connected station (when known), else replaced by the contents of %U macro
    %Y- Channel callsign (mycall)
    %K- Current channel number
    %T - Current time
    %D - Current date
    %B - Audible bell
    %Z - Current time zone
    %U - The text used when the name is unknown. This can contain other macros (typicaly %C).
    %P- The port number
    %M- The number of connected users
    %A- The time since the last operator activity
    %_- End of line (CR)
    %<- Contents of the last line received, this is cleared by reading
    %#number - Replaced by a character with an ASCII value <number> (e.g. %#27 means ESC)
    %(command) - Replaced by the command result.
    %[expression] - Replaced by the result of mathematical expression

Variables for use in macros only:

    %R - the number of macro arguments (up to 9)
    %0 - the name of the macro
    %1 - %9 - macro arguments

For example try to write following text in the editor and press enter:

The time is %T and the date is %D.

5 Station database

The station database holds various information about known stations. All the information is stored in the 'station.data' file and can be changed using the normal text editor or using the LinPac :Name command.

5.1 The station.data file format

The information about each station is written in a paragraph starting with the station callsign in square brackets. Each line in the paragraph contains one definition like:

<item_name>=<value>

A typical station information paragraph might look like this:

    [OK0NMA]
    NAME=PC/FlexNet Brno
    TYPE=FLEXNET
    LOC=JN89HE
    QRG=144.8125 MHz
    SYSNUM=85946

There are no mandatory items; the user can add various items depending on what information he wants to store. The current LinPac distribution uses following item names for standard information:

    NAME - Text information about the station, or the operator's name. LinPac shows this information when connected to that station. LOC - QRA locator of the station. Shown after connect too.

    TYPE - The type of the station. For standard stations the types FLEXNET, THENET, FBB, BAYBOX, DIEBOX, TNOS, JNOS, DXC and TERM for user terminals are recomended, but you can add any other type.

    LANG - The language to communicate with the station. This is currently supported by macros only. When this item is set, LinPac will try to find the macro in the directory macro/<LANG>/.

    NICKNAME - The nickname of the operator.

The standard LinPac configuration also uses these item names:

    TERM - What type of terminal is used. If 'ansi' is set, LinPac switches to the ansi-color mode after connecting this station.
    ENC - The character encoding. Used to automaticaly switch to the i/o character conversion.
    RCMD - The list of enabled remote commands for this station.
    QRG - The user frequency. Used by the logbook.
    SYSNUM and PWD - Sysop password for the station. See chapter 8.2 for more information.

5.2 The 'Name' command

The :Name command is used to modify the station database. Running the command without arguments results printing the name of currently connected station. Arguments can be used to modify the data:

    <name> - modify the NAME item
    -l <locator> - modify the LOC item
    -t <type> - TYPE
    -L <language> - LANG
    -n <nickname> - NICKNAME
    -s <item>=<value> - modify other item

The command 'Name -i' prints all information about the station. When you need to change the information about a station other than the connected station, add the argument -c <callsign>.

Examples:

    :Name David
    :Name -c KI6ZHD -l CM97ai David
    :Name -i

5.3 Using the database

After any connection is established, LinPac reads the information about the connected station from the database and creates the set of variables with names STN_<database_item_name> containing the values of the items. These variables can be used in macros as described below.

6 About macros

6.1 Creating macros

A macro is a LinPac command that is created using the macro language, and uses other LinPac commands to perform some action. A macro can be defined by creating the file macro/<command_name>.mac. It's possible to define an abbreviated form of the command; this is described in chapter 7. There are two ways to define a macro:

a) Text macros
This way is suitable for commands which are intended to produce a larger text output (for example station information). When executing this macro, each line that doesn't start with ':' is printed (sent out). All commands must start with the colon. This is suitable for modifying the text output using the IF ~ ELSE ~ ENDIF commands or for including some other commands.

b) Command macros
A command macro must start with the line
:MACRO <name>
Each line of a command macro is interpreted as a command (doesn't start with the colon and doesn't need to start at the begining of line). Text output is provided by the 'echo' command. This way is more synoptical and allows including comments that must start with the sequence ';;' and end at the end of the line.

A macro is called with its name. When the first arguments starts with the '@' symbol the macro is executed from the specified label. For example the command :convers @SEND will execute the macro 'convers.mac' from the label 'SEND' (see next chapter to see how to define the label).

6.2 Commands used in macros

A macro can contain all LinPac and user defined commands. There are also some special commands that can be used in macros only:

MACRO [name]
Start of the command script definition (see previous section).

LABEL <label_name>
Creates a label with specified name. In the command scripts the notation :<label_name> can be used.

GOTO <label_name>
Jump to specified label.

IF ~ ELSE ~ ENDIF
Conditional commands. There are two ways to specify a condition:

  • normal notation (for more than one command)
  •  

    IF <condition>
    .
    .
    (commands to be executed when the condition is true)
    .
    .
    ELSE
    .
    .
    (commands to be executed when the condition is false)
    .
    .
    ENDIF

    The ELSE part is not necessary - the IF ~ ENDIF notation is possible.
     

  • abbreviated notation (for one conditional command)
  • IF (<condition>) command

    The parentheses are necessary in this case.

The following example shows how to use conditions and how to use the data from the station database. We want to create a macro that will greet the operator of the connected station with his nickname or with his name, if the nickname is not defined.

a) The solution using a text macro (the comments are actually not allowed in the text macros, they are here for explanation only)

    :if %(exist STN_NICKNAME) == 1 ;; when NICKNAME is defined
    Hello %STN_NICKNAME            ;; greet with the nickname
    :else                          ;; else (not defined)
    Hello %N !                     ;; greet with the name
    :endif                         ;;(following commands are always executed)
    You have connected to %Y at %T. ;; Say your callsign and current time

b) The solution using a command macro

    :macro GREETING ;; start the command macro
    if %(exist STN_NICKNAME) == 1 ;; when NICKNAME is defined
    echo Hello %STN_NICKNAME     ;; greet with the nickname
    else                         ;; else (not defined)
    echo Hello %N !              ;; greet with the name
    endif                        ;; (following commands are always executed)
    echo You have connected to %Y at %T. ;; Say your callsign and current time

6.3 Special system macros

There are some special macros that are executed automaticaly by LinPac in some cases:

    init.mac - This is executed when LinPac is started and its function is to set the callsigns, screen options, and some other parameters.

    cinit.mac - This is always executed when a connection is established. The distribution version of this macro sets the channel parameters in order to configure station settings from the station database (allowed remote commands, i/o encoding, terminal type) and executes the logbook command to sign the start of a connection. LinPac always passes two arguments to this macro. The first (%1) argument is the callsign of the connected station and the second (%2) argument is the callsign of the previously connected station that provides the connection, or empty in case of direct connection.

    ctext.mac - This macro is executed when some station connects to the terminal. It should print some greeting text. No arguments are passed.

    cexit.mac - This is always executed when a connection closes. The distribution version of this macro just executes the logbook command to sign the end of the connection and clears the list of allowed remote commands. There is always one argument passed by LinPac (%1), containing the callsign of the disconnected station.

7 Creating new commands

A new command can be represented by a macro or by an external program (standard linux program or special LinPac application). Macros are placed in the $LINPACDIR/macro directory and external programs are placed in the $LINPACDIR/bin directory. In both of these directories is the file 'commands' that contains the list of commands in that directory. You should specify here the name of the file, the name of the command in LinPac (use upper case to specify the mandatory part of the command). It's not necessary to include the macros here if you don't want to define the abbreviation.

In case of external programs, it is also possibile to specify program flags. Currently the following flags are supported:

    A - Ascii mode program. LinPac provides CR <-> LF conversion when communicating with this program. This is the default setting.
    B - Binary mode. Disables the text conversions.
    C - Leaves the stdout stream of the program on the console and reads its stderr stream instead.
    D - DOS conversion - ignore LF characters.
    S - Reads both stdin and stderr streams of the program (shell mode).
    L - Local. This program is never available as a remote command.
    R - This program is always run as a remote command (its messages are always sent out).
    P - LinPac removes the paths from filenames that are passed as the argument of this command when the FIXPATH command is on. This is a security option.

8 Standard applications

8.1 File transfer protocols

At present LinPac supports two protocols for transferring files:

  • Autobin - a simple protocol suitable for short files
  • YAPP - a very sophisticated transfer protocol that provides better error detection and is able to resume a previously interrupted transfer

Usage of these protocols is described in chapter 3.4.

LinPac can also automatically save incomming 7+ files. After saving all parts of a file LinPac tries to call the '7plus' program to decode the file. Received 7+ files are not removed automatically.

8.2 Automatic password generation

8.2.1 Login passwords

LinPac provides automatic replies to the login authorization requests for the following systems: F6FBB BBS (VE2BLY C_FILTER), BAYBOX, TNOS (numeric MD5). Each station which requests a login password must have an entry in the station database containing at least following fields:

A

    TYPE=<station_type> (FBB, BAYBOX or TNOS)
    LOGINPW=<login_password>
    PWPROMPT=<BBS_prompt>

BBS_prompt is the text which the BBS sends when requesting the authorization. Usually it looks like 'Password>' or 'OK0XYZ>'.

8.2.2 Sysop and general use passwords

LinPac provides automatic authorization to the following systems: F6FBB BBS (MD2 password), FLEXNET (older versions, the 'magic' numbers system and newer TheNet-like system), THENET and BAYBOX. Each station you want to authenticate with must have an entry in the station database. For password generation, the following fields must be set:

    TYPE=<station_type>
    PWD=<your_password> or
    SYSNUM=<magic_number>

Known station types are:

  • FBB - An F6FBB BBS. The PWD field must contain your password.
  • THENET - A TheNet node. Again the PWD must contain the password.
  • BAYBOX - The same system as TheNet.
  • FPAC - A FPAC node. Password must be stored in the PWD field.
  • FLEXNET - FlexNet node. If the magic number algorithm is used (older versions of flexdigi) the SYSNUM field must contain your magic number and the PWD field must not be set. When the TheNet algorithm is used (newer versions of flexdigi), the PWD field must contain the password and the SYSNUM field must not be used.

In case of FBB the authorization algorithm can be chosen by setting the MD field in the station database:

    MD=5 - this value will select the MD5 algorithm
    MD=2 - this value will select the MD2 algorithm

When no value is set, MD2 algorithm is used.

After connecting to the station you want to authenticate with, the authorization sequence begins with the :PW command. LinPac will send the authorization command to the station and tries to answer the authorization request using your password. If the password is correct, authorization should finish successfully.

The PW command accepts the following parameters:

    :PW [<command> [<system> [<password>]]]

where

  • <command> is the command to be sent to the remote station to start the authorization sequence (sys by default)
  • <system> is one of the above-mentioned supported systems; this system is used instead of the one specified in station database
  • <password> is the password that will be used instead of the one specified in the station database

It's recommended that you create simple macros for frequently used authorizations that require special arguments to the PW command.

8.3 Utilities for mail exchange

LinPac contains support for exchanging messages with remote Kantronics PBBSs as well as F6FBB BBS systems. This support utilizies some tools from the ax25mail-utils so please install that package first. THe next step would be to configure Linpac and ax25mail-utils's configuration settings with the following variables either in Linpac's channel 0 or in Linpac's init.mac file:

Example #1: Kantronics KPC3:

  • HOME_TYPE - This sets the type of remote system you're connecting to. Supported options are either "PBBS" for Kantronics KPC3 type TNCs or "FBB" for F6FBB BBSes. Only "PBBS" is well understood though the FBB support has been there for some time.
  • HOME_BBS - The AX.25 path to the home PBBS including the port name. For example d710:AA6WK-1 means use the d710 AX.25 port as defined in the /etc/ax25/axports configuration file and connect to the PBBS AA6WK-1. It's important to note that the callsigns in Linpac are CaSe-SeNsItIvE so make sure these two variables use the SAME case.
  • HOME_ADDR - The full hierarchical address of the BBS (which technically isn't required for PBBSes). For example AA6WK.#NCA.CA.USA.NOAM.

To set the variable while in Linpac, the :SET command can be used. You can also put this same line (but without the colon) in Linpac's init.mac file:

    :set HOME_TYPE "PBBS"
    :set HOME_BBS@0 "d710:AA6WK-1"
    :set HOME_ADDR "AA6WK.#NCA.CA.USA.NOAM"

The recommended place to set this variables is in the startup macro init.mac. The default version of this macro contains an example of setting these variables. After setting these variables, the following commands are available:

Example #2:

  • HOME_TYPE - This sets the type of remote system you're connecting to. Supported options are either "PBBS" for Kantronics KPC3 type TNCs or "FBB" for F6FBB BBSes. Only "PBBS" is well understood though the FBB support has been there for some time.
  • HOME_BBS - The AX.25 path to the home BBS including the port name. For example kiss:OK0PAB OK0NMA means use the kiss AX.25 port as defined in the /etc/ax25/axports configuration file and connec to the BBS OK0PAB via the digipeater OK0NMA. It's important to note that the callsigns are CaSe-SeNsItIvE in Linpac so make sure these two variables use the SAME case.
  • HOME_ADDR - The full hierarchical address of the BBS. For example OK0PAB.#MOR.CZE.EU.

To set the variable while in Linpac, the :SET command can be used. You can also put this same line (but without the colon) in Linpac's init.mac file:

    :set HOME_TYPE "FBB"
    :set HOME_BBS@0 "kiss:OK0PAB OK0NMA"
    :set HOME_ADDR "OK0PAB.#MOR.CZE.EU"

The recommended place to set this variables is in the startup macro init.mac. The default version of this macro contains an example of setting these variables. After setting these variables, the following commands are available:

Now you need to configure the ax25mail-utils program by editing the /etc/ax25/axgetlist.conf file. The following example is to support connecting to PBBSes in example #1 above:

       [AA6WK-1]
       MYCALL N0CALL
       BBSCALL AA6WK-1
       BBSPORT d710
       CMD_LIST LO +;L
       CMD_LIST_FROM LO +;L $
       CMD_DISC B
       HEADER_LINES 1
       FORMAT <NUM> <FLAGS> <SIZE> <TO> <FROM> <DATE> <TIME> <SUBJ>
       DATEFMT mm/dd/yyyy
       BPFPOS 1--
       

Each remote BBS gets it's own section, unique callsign, and any other specific settings to support the sending and receiving of messages.

NOTE: the associated ax25mail-utils /etc/ax25/axgetmail.conf configuration file NOT currently mentioned in this documentation is only used for remote "FBB" setups. That support is currently not documented yet.

Urgent: Linpac's packet messaging support is still a work in progress so some quirks exist for now:

  • All remote BBS systems that use SSID numbers will have their message index files "flattened" aka written to the same base callsign name without the SSID in /var/ax25/ulistd/. In the future, this filename should include the -SSID#
  • All non-private messages will be stored in /var/ax25/mail/<callsign-SSID>
  • All private messages will be stored in /var/ax25/mail/<callsign-SSID>
  • There is a known bug in Linpac's message system due to the index "flattening" issue where messages cannot be written to disk or found in the :mail interface. To work around this issue, do the following in the directory of the Linux user who is running Linpac:
    • mkdir LinPac/mail/<callsign-SSID>
      ln -s LinPac/mail/<callsign-SSID> LinPac/mail/<callsign>

Now that the basics (and workarounds) are setup, let's fetch any pending messages for you on your configured remote BBS system. Enter in the following command on the Linux prompt (this example is following example #1 above):

    axgetlist -b AA6WK-1

NOTE: The above Linux command must be run as the same Unix user that is running the Linpac program.

The axgetlist utility will now fetch an index of all messages on the remote BBS system and store this list in /var/ax25/ulistd/<bbs-name> (all SSIDs are currently stripped). While this Linux command line-based index capture occurs, the packet traffic will NOT show up in Linpac's main send/receive UI as this command is running outside of Linpac. You will see the AX.25 traffic if you have Linpac's AX.25 traffic monitor working. The resulting downloaded index file will then be used to manually download any messages with the getmsg command or interact with those remote messages them via Linpac's :mail interface

    :GETMSG <message_number> [<message_number> ...]
    From the main Linpac interface, this command reads specified messages from the remote BBS and stores them into /var/ax25/mail/<BBS_callsign>/<message_number>. The file system directory for the remote BBS must be created before using this command (use upper case for the BBS callsign). When the message number starts with the letter 'p', the message is considered a PERSONAL one and it's killed automatically after download. You can specify the kill command by setting the KILLPERS variable in channel 0 using the # character for the number of the message (e.g. :set KILLPERS@0 "kill #"). When this variable is not set, the default command K # is used. This can also be set in the init.mac file.

    :SP <address> or :SB <address>
    These commands can be used for creating new private messages or bulletins. The usage is the same as for the FBB BBS.

    :FORWARD
    Transfers all new messages to the BBS.

    :DELMSG <message_number>
    Marks the message for delete.

    :PACK
    Deletes all marked messages.

8.4 Mail client

This application allows full screen message editing and browsing. It provides a graphical (Ncurses) frontend to mail exchange utilities. The mail client is started by the :MAIL command from Linpac's Channel 0 (aka.. the F1-key view). If you run this command from any other Linpac channel, it won't display any messages!

After the mail interface opens, the H key shows the operating instructions.

In the INCOMING mail folder, you should see a list of messages available to download. Toggle the messages you want to fetch with the SPACEBAR and then use the "d" key to download those messages.

8.5 Logbook

Logbook is a simple application that is started from the cinit.mac and cexit.mac scripts (at the begining and at the end of each connection). It creates the file in the 'log' directory for each callsign and writes there the time when the connections were started and finished and the QRG. The QRG is taken from the QRG field of the station entry in station database. If the station has no QRG defined, the value from the QRG@0 variable is taken.

9 Command line options

LinPac accepts following command line options:

    -m : disable monitor. When this option is used, LinPac doesn't create it's internal monitor objects and saves memory.

    -s : disable ax25spyd. Linpac normally tries to connect ax25spyd to get monitor data and when the connection fails, the listen utility is used instead. When -s swicth is used, LinPac doesn't try to connect ax25spyd at all.

    -d : daemon mode. LinPac doesn't initialize the screen and runs in the background.

    -p <string> : specify the arguments for the listen program. Default value is ar8.

10 Copying

LinPac is Copyright (c) 2002-2020 by David Ranch KI6ZHD and Copyright (c) 1998-2002 by Radek Burget, OK2JBG

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;

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 (contained in file 'license').

You should have received a copy of the GNU General Public License along with this program; if not, see <https://www.gnu.org/licenses/>.


Appendix A - LinPac commands

Built-in commands

a) action commands

      ABort [address]
      Cancels an action. Some commands are cancelled without specifying any address (e.g. autobin). Addresses for some commands:

        Action Address for abort
        autobin RX/TX autobin (or none)
        yapp RX/TX yapp (or none)
        7plus autosave 7plus (or none)
        read / RBin read (or none)
        write / WBin write (or none)
        forward forward (mandatory)

    Most of the other commands don't need any address.

      COMPress [on | off | 1 | 0]
      Switch the link compression on or off. The arguments 1 and 0 have the same meaning as on or off but the remote station is not synchronized.

      Connect [port:]call [digi [digi...]]
      Initiate a connection to the specified station.

      Disconnect
      Disconnect the channel.

      Echo <text>
      Print (send) the specified text.

      FLUSH
      Flush an output buffer (for example in scripts before disconnect or before requesting input).

      SYstem
      End of LinPac, cancel all connections.

      UNproto <text>
      Send specified text in a UI frame.

      VERsion
      Print version information.

    b) Commands for variable handling

      SET <variable> <value>
      Assign a value to the variable. If the variable doesn't exist, it is created.

      UNSET <variable>
      Remove the variable.

      GET <variable>
      Return the value of the variable. Usually is better to use macro %variable (see file macros.txt)

      EXISTs <variable>
      Return 1 when variable exists, 0 when it doesn't exist.

    c) information commands

      ENVINFO
      Display information about the variable environment.

      ISCONnected
      Return "1" when the channel is connected, "0" otherwise.

      MAXCHannels
      Return the number of LinPac channels (typically 8).

      PCALL
      Return the physical callsign of the connected station (first station connected)

      UTCTime
      Return current UTC time (operating system value).

    d) setup commands

      CBell [on|off]
      When on, LinPac gives an audio signal when any station connects or disconnects.

      FIXPath [on|off]
      When FIXPath=ON then the paths to files mentioned in the parameters are ignored for external commands marked with a P flag. That means only the default paths are usable.

      INFOLEvel [0 | 1 | 2]
      Set the mode of information line:
      0 - off (no connection info)
      1 - show importatnt informations
      2 - show all available informations

      KNax [on|off]
      Enable/disable sound signal when data is received.

      Language [language]
      Sets the language used. Currently supported in scripts only.

      LIsten [on|off]
      When listen is off, all connect requests are ignored by LinPac. Default value is on.

      MBIN [on|off]
      When switched on, the monitor shows binary data. When switched off, the binary data is hidden and replaced with the <Binary data> information.

      MONitor [on|off]
      Enable/disable monitor function. This command is usually followed by STATLINE and CHNLINE commands to adjust the screen layout.

      MONPort <port_specification>
      Monitor the specified port(s) only. Port specification is either a port name (as defined in /etc/ax25/axports) or * for monitoring all the ports.

      MYcall <call>
      Change the channel callsign.

      Port <port_name>
      Set the default port for the Connect command. This is usually the first port defined in the /etc/ax25/axports file but can be overriden here. This can be overriden for particular channels by setting the CHN_PORT variable for the channel (see chapter 3.3).

      PRIVate [on|off]
      Mark the channel as private. No stations are allowed to connect on this channel.

      RCMD [<command list>]
      Specify the list of available external commands. Only commands from this list are available to a remote user. It's possible to include abbreviated commands. The remote commands can be executed only on a channel which provides a connection. Adding the @ character just after the command name in the list (e.g. GET@) means that the remote user is allowed to specify the channel on which the command should be executed (e.g. //GET@5 NAME).

      REMote [on|off]
      Enable or disable remote commands.

      RXFlow [on|off]
      Enable or disable data RX. The data is received only when RXFlow is enabled on all channels.

      TIMEZone [zone]
      Set the time zone. Used for information only, doesn't affect time.

      UNDest [call]
      The destination address for UI / unconnected frames. You can use up to a maximum of seven digipeaters by by including the remote digis in a space delinated list. Here is an example where you MUST include the double quotes to complete the proper syntax:
      undest "DAVID KLPRC3 KBETH KBANN KBULN"

      UNPort <port_name>
      Set the default port for the UI frames / unproto traffic command or F10 unproto traffic area. This is usually the first port defined in the /etc/ax25/axports file but can be overriden here. This can be overriden for particular channels by setting the unport variable for the channel.

      UNSrc [call]
      The source callsign for UI frames.

      WAtch <port | 0> <pattern> <command/text>
      Start to watch the specified port (0 for all ports). When the specified pattern is received then the specified command is executed or text is sent. (Commands must start with a colon.)

    e) Screen control commands

      STATLINE <n>
      Place the status line at the n-th line of the screen.

      CHNLINE <n>
      Place the channel line at the n-th line of the screen.

      SWAPEDit
      Replace the editor window with the QSO window and vice versa.

      INFOLine <nm> <text>
      Change the specified info line text. If the info line doesn't exist, it's created.

      REMOVEINFO <nm>
      Remove the specified info line.

      TRanslate <alias>
      Switch I/O character translation (see chapter 3.6). Running this command on channel 0 (unproto channel) switches the translation table in all channels including the unproto channel and the monitor window.

      TErm <type>
      Set the terminal type. If 'ansi' is entered then ANSI-color control sequences are interpreted.

      SCRLimit <low-limit> <high-limit>
      When the size of the window buffer exceeds the high limit, then the size of the buffer is truncated to low-limit. The values are in bytes; default is 356352 and 524288 (384 and 512 kB).

      DEFColor <color_name> <foreground_color> <background_color>
      Change the color of some part of screen. The color_name parameter specifies which part of screen to change. The following values can be used:
      QSO_RX - received text in QSO window
      QSO_TX - sent text in QSO window
      QSO_INFO - local information in QSO window
      QSO_CTRL - control characters in QSO window
      ED_TEXT - normal text in editor
      ED_INFO - command results in editor
      ED_CTRL - control characters in editor
      CI_NORM - channel info line - channel numbers
      CI_SLCT - selected channel
      CI_NCHN - normal channel
      CI_PRVT - private channel
      IL_TEXT - status lines

      For specifying foreground and background colors, these values can be used:
      BLACK, RED, GREEN, BROWN, BLUE, MAGENTA, CYAN, LIGHTGRAY
      These additional colors can be used for foreground only:
      DARKGRAY, LIGHTRED, LIGHTGREEN, YELLOW, LIGHTBLUE, LIGHTMAGENTA, LIGHTCYAN, WHITE

    f) system commands

      RESULT <text>
      Return the text as the result of a script.

    g) string commands

      STRMid <start> <length> <string>
      Return the substring starting at <start> position and <length> characters long.

      STRLeft <length> <string>
      Return the left substring of specified length.

      STRRight <length> <string>
      Return the right substring of specified length.

      STRLen <string>
      Return the length of the string.

      STRPos <substring> <string>
      Return the position of the substring in the string or -1 when the string doesn't contain the substring.

      UPCASE <string>
      Return the string converted into upper case.

External commands

    Bell
    Call the operator using an acoustic signal.

    Compose [p|b] <address> [<subject>] [<filename>] Create either a Private message or a Bulletin packet message for the specified callsign or fully formatted packet BBS address. When no subject is specified, the user is prompted for the subject. When filename is specified, the message is created from the file, otherwise the text is read from the LinPac console.

    CATCH -iol <pattern> <command/text>
    Catch is the extended version of WAtch command. It scans one or more data streams (-i = input stream, -o = output stream, -l = local info stream) for the configured pattern. The pattern can contain * and ? wildcards. The command can contain string $1 .. $n which are replaced with the string corresponding to the n-th wildcard in the pattern. The $0 string is replaced with the whole string that matches the pattern. See catch -h for extended parameters.

    DELMSG <message_number>
    Mark the packet message for deletion

    FORWARD
    Transmit all new packet messages to a BBS

    GETMsg <numers>
    Fetch packet messages from the configured BBS

    JOIN <channel_number>
    This is a form of a group chat feature where you can join the specified Linpac channel to current Linpac channel. All data received on any of these channels is automatically redirected to the other channel. Stop with :ABort join.

    MAIL
    Simple full-screen packet message client

    MHeard
    List of heard stations.

    Name
    Store station name or change a station database entry. (see Name -h)

    PACK
    Delete all packet messages marked for deletion

    Read <filename>
    Send the specified text file (see Wbin / Rbin commands for BINARY files)

    RPRg <filename>
    Transmit the specified file using Autobin protocol

    RTt
    Measure the round trip time to the other connected Linpac station. Think of this as a "ping" time but results can be highly variable due to on-frequency packet collisions, poor packet decodes, RF propogation, etc.

    SENDFile [p|b] <file> <address> [<num_messages>]
    This command takes a binary file, splits the file into num_messages parts using 7plus and creates a separate packet message for each part. When num_messages is not specified, the command tries to use
    the variable BLOCK7P@0 which should contain the maximum size of one block. If this variable is not set, blocks of 5 KB are created.

    WBin / RBin
    The same as Read / Write file transfers but to be used with BINARY files. (See Read / Write commands for TEXT files)

    Write <filename>
    Start to write received TEXT to the file. (see Wbin / Rbin commands for BINARY files)

    YPUT <filename>
    Transmit the file using the YAPP protocol.

Macros

    Activity
    Show the time since the last operator activity. This is also posted when users first log into the Linpac system

    Conv
    Enter the conference.

    Info
    Print local station information.

    Help
    Print brief help information.

    PW [<command> [<system> [<password>] ] ]
    Start the authorization to the BBS or the node. See chapter 8.2.2 .

    Quit
    Send the quit text and disconnect.

    Users / CStatus
    Print list of connected users.

Commands for creating scripts

    MACRO [name]
    Start of the command script definition (see below).

    LABEL <label_name>
    Create a label with specified name. In the command scripts the notation :<label_name> can be used.

    GOTO <label_name>
    Jump to specified label.

    IF ~ ELSE ~ ENDIF
    Conditional commands. There are two ways to specify a condition:

    • normal notation (for more than one command)
    • IF <condition>
      .
      .
      (commands to be done when the condition is true)
      .
      .
      ELSE
      .
      .
      (commands to be done when the condition is false)
      .
      .
      ENDIF

      The ELSE part is not necessary - the IF ~ ENDIF notation is possible.

      abbreviated notation (for one conditional command)

      IF (<condition>) command

      The parentheses are necessary in this case.

    RETURN [<data>]
    Abort the macro execution and return the data as a result.

    SLEEP <seconds>
    Pause the macro for specified time in seconds.

    WAITFOR <condition>
    Pause the macro until the condition is true.


Appendix B - Linpac FAQ / Questions and Answers / Getting more help

  1. Q: X doesn't work right in Linpact. Why?
    A: Have you looked in the errors.txt file found in the main LinPac directory? It can provide a lot of clues.
  2. Q: When I start Linpac, I get "Segmentation fault". What is the fix?
    A: You are probably running an old version of Linpac. Please try the newest release version available at https://sourceforge.net/projects/linpac/ or possibly the newest DEVELOP branch. This will most likely require you to compile Linpac to get it running
  3. Q: When I start Linpac, all of the text in the AX.25 monitor is indented to the right. How do I fix this?
    A: Exit Linpac, go into the directory where Linpac is installed, and delete the file:

      monitor.screen

    Now restart Linpac. Did that solve your issue? No? Also try deleting the files window*.screen and restart Linpac
  4. Q: My question isn't addressed in this document, where else can I get help?
    A: Consider reviewing these other URLS:


Appendix c - Errata

03/30/2020 - dranch

  • Expanded packet mail section on how to configure message system for PBBS and FBB remote systems
  • Added a FAQ section and added this errata section
  • Improved formatting and added this errata section

04/01/2019 - dranch

  • Minor improvements


Last update: March 30 2020
Please report any errors to linpac@trinnet.net

linpac-0.28/doc/Makefile.am0000664000076400007640000000031014006074433012440 00000000000000## Process this file with automake to produce Makefile.in SUBDIRS = czech charsets dist_doc_DATA = manual.txt manual.html applguide.txt applguide.html events.txt \ objects.txt ioctl.txt linpac-0.28/doc/charsets/0000775000076400007640000000000014006074455012312 500000000000000linpac-0.28/doc/charsets/Makefile.am0000664000076400007640000000020314006074433014255 00000000000000## Process this file with automake to produce Makefile.in csdocdir = $(docdir)/charsets dist_csdoc_DATA = table.tab ctt_files.txt linpac-0.28/doc/charsets/ctt_files.txt0000664000076400007640000000144314006074433014745 00000000000000Creating the CTT (Charset conversion table) files ================================================= SRC = source encoding (remote system encoding) DEST = destination encoding (local Linux console encoding) There is a file "table.tab" located in the same directory as this document. You will need any conversion software that can convert between SRC and DEST charsets in both directions (e.g. Trans http://www.kostis.net/freeware/). 1. Convert the file "table.tab" from SRC to DEST and store to tab1.tab 2. Convert the file "table.tab" from DEST to SRC and store to tab2.tab 3. cat tab1.tab tab2.tab >result.ctt The resulting file should be 512 bytes long. For installing the encoding table to LinPac just copy the file *.ctt to $HOME/LinPac/ You may need to update the file $HOME/LinPac/encodings. linpac-0.28/doc/charsets/Makefile.in0000664000076400007640000002664014006074450014302 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/charsets DIST_COMMON = $(dist_csdoc_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(csdocdir)" DATA = $(dist_csdoc_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LINPACLINK = @LINPACLINK@ LIPO = @LIPO@ LISTEN = @LISTEN@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ csdocdir = $(docdir)/charsets dist_csdoc_DATA = table.tab ctt_files.txt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/charsets/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/charsets/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_csdocDATA: $(dist_csdoc_DATA) @$(NORMAL_INSTALL) test -z "$(csdocdir)" || $(MKDIR_P) "$(DESTDIR)$(csdocdir)" @list='$(dist_csdoc_DATA)'; test -n "$(csdocdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(csdocdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(csdocdir)" || exit $$?; \ done uninstall-dist_csdocDATA: @$(NORMAL_UNINSTALL) @list='$(dist_csdoc_DATA)'; test -n "$(csdocdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(csdocdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(csdocdir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(csdocdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_csdocDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_csdocDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dist_csdocDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am uninstall-dist_csdocDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: linpac-0.28/doc/charsets/table.tab0000664000076400007640000000040014006074433013777 00000000000000  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿlinpac-0.28/doc/czech/0000775000076400007640000000000014006074455011572 500000000000000linpac-0.28/doc/czech/Makefile.am0000664000076400007640000000024314006074433013541 00000000000000## Process this file with automake to produce Makefile.in czdocdir = $(docdir)/czech dist_czdoc_DATA = cti.me klavesnice.txt makra.txt prikazy.txt stanice.txt linpac-0.28/doc/czech/makra.txt0000664000076400007640000000373614006074433013353 00000000000000[Document encoding ISO-8859-2] LinPac - textová makra ====================== Textová makra slou¾í ke vkládání zvlá¹tních údajù do vypisovaného textu. Ka¾dé makro (uvozené znakem '%') je pøi vypisování textu nahrazeno pøíslu¹nou aktuální informací. Pøíklad: v textu "Dnes je %D a va¹e znaèka je %C" se makro %D nahradí aktuálním datem a %C se nahradí volací znaèkou u¾ivatele. Obsah nìkterých maker závisí na aktuálním kanálu. Pøi pou¾ití makra ve skriptu se za aktuální pova¾uje kanál, na kterém skript probíhá, pøi zadání pøímo v editoru pøíkazù se za aktuální pova¾uje právì zobrazený kanál. Èíslo kanálu lze explicitnì zadat pomocí zápisu %x@nn (napø. %C@2 se nahradí znaèkou protistanice pøipojené na kanál 2). Seznam pou¾itelných maker ========================= %V - Verze programu (napø. 0.01) %C - Znaèka spojené protistanice %N - Jméno spojené protistanice pokud je zadáno, jinak se nahradí obsahem makra %U %Y - Znaèka kanálu (u¾ivatele terminálu) %K - Èíslo aktuálního kanálu %T - Aktuální èas %D - Aktuální datum %B - Znak pro zvukový signál (BEL) %Z - Aktuální èasová zóna %U - Èím se nahrazuje jméno kdy¾ není zadáno (mù¾e obsahovat dal¹í makra, typicky %C) %P - Èíslo portu na kterém probíhá spojení %M - Celkový poèet pøipojených u¾ivatelù %A - Èas v sekundách od posledí akce operátora %_ - Konec øádku (CR) %< - Obsah posledního pøijatého øádku, pøeètením se vyma¾e %#èíslo - Nahradí se znakem s hodnotou èíslo (napø. %#27 se nahradí znakem ESC) %(pøíkaz) - Pøíkaz se provede a makro se nahradí jeho výsledkem %[výraz] - Nahradí se výsledkem matematického výrazu který se mù¾e skládat z celých èísel, závorek a operátorù +, -, *, \ s obvyklými prioritami %promìnná - Nahradí se obsahem dané promìnné Makra pro pou¾ití pouze ve skriptech: %R - poèet parametrù pøedaných skriptu %0 - jméno provádìného skriptu %1 a¾ %9 - parametry pøedané skriptu linpac-0.28/doc/czech/klavesnice.txt0000664000076400007640000000146514006074433014401 00000000000000[Document encoding ISO-8859-2] LinPac - horké klávesy ====================== Globální: F1 - F8 : pøepínání mezi kanály F10 : pøepnutí do monitoru Alt-X : ukonèení LinPacu Vstupní okno: PgUp, PgDn, ctrl-R, ctrl-V : listování po stránkách ctrl-E, ctrl-X : listování po øádcích ctrl-B : skok na konec bufferu Editor: Kurzorové klávesy, Home, End, Backspace, Del : editace ctrl-Y : vymazání aktuálního øádku Enter : odeslání aktuálního øádku Na ka¾dém kanálu mù¾e bì¾et jedna aplikace vyu¾ívající celou obrazovku (napø. program mail). Do této aplikace se lze pøepnout stiskem Alt+èíslo_kanálu (napø. Alt-5). Zpìt do terminálu se lze pøepnout stiskem F1 - F10. linpac-0.28/doc/czech/cti.me0000664000076400007640000000023514006074433012610 00000000000000Ceska verze dokumentace je neuplna a zastarala, protoze o ni zatim nikdo neprojevil zajem. Zajemci o vytvoreni ceske dokumentace podle anglicke jsou vitani. linpac-0.28/doc/czech/Makefile.in0000664000076400007640000002666714006074450013573 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc/czech DIST_COMMON = $(dist_czdoc_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(czdocdir)" DATA = $(dist_czdoc_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LINPACLINK = @LINPACLINK@ LIPO = @LIPO@ LISTEN = @LISTEN@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ czdocdir = $(docdir)/czech dist_czdoc_DATA = cti.me klavesnice.txt makra.txt prikazy.txt stanice.txt all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/czech/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/czech/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_czdocDATA: $(dist_czdoc_DATA) @$(NORMAL_INSTALL) test -z "$(czdocdir)" || $(MKDIR_P) "$(DESTDIR)$(czdocdir)" @list='$(dist_czdoc_DATA)'; test -n "$(czdocdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(czdocdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(czdocdir)" || exit $$?; \ done uninstall-dist_czdocDATA: @$(NORMAL_UNINSTALL) @list='$(dist_czdoc_DATA)'; test -n "$(czdocdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(czdocdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(czdocdir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(czdocdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dist_czdocDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_czdocDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dist_czdocDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am uninstall-dist_czdocDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: linpac-0.28/doc/czech/prikazy.txt0000664000076400007640000002067414006074433013751 00000000000000[Document encoding ISO-8859-2] Linpac - seznam pøíkazù ======================= U pøíkazù jsou povinná pouze velká písmena. Ka¾dý pøíkaz lze provést i na jiném ne¾ aktuálním kanálu zadáním pøíkaz@kanál (napø. "connect@2 cz6jbg"). V¹echny pøíkazy musí zaèínat dvojteèkou, jinak jde o text k odeslání. 1) Vestavìné pøíkazy a) 'akèní' pøíkazy ABort [adresa] Zru¹ení akce. Nìkteré programy reagují i bez udání parametru (autobin). Adresy jednotlivých pøíkazù: èinnost parametr_pro_abort ------------------------------------- autobin RX/TX autobin (nebo nic) yapp RX/TX yapp (nebo nic) 7plus autosave 7plus (nebo nic) read/RBin read (nebo nic) write/WBin write (nebo nic) forward forward ostatní bez parametru. Connect [port:]znaèka [digi [digi...]] Zaène navazovat spojení s danou stanicí na aktuálním kanále. Disconnect Rozpojení. Echo Vypí¹e (vy¹le) daný text. FLUSH Zpùsobí výslání dosud nevyslaných rámcù (uplatní se spí¹e ve skriptech napø. tìsnì pøed pøíkazem Disconnect nebo pøed èekáním na vstup) SYstem Ukonèení programu LinPacu, zru¹í v¹echna spojení. UNproto Vyslání neèíslovaného rámce s daným textem. VERsion Výpis verze programu. b) pøíkazy pro práci s promìnnými SET Pøíøadí hodnotu dané promìnné. Pokud promìnná neexistuje, tak ji vytvoøí. UNSET Zru¹í danou promìnnou. GET Vrací hodnotu promìnné, obvykle lze úèinìji nahradit pomocí %promìnná. (viz soubor macros.txt) EXISTs Vrací 1 kdy¾ promìnná existuje, 0 kdy¾ neexistuje. c) informaèní pøíkazy ENVINFO Vypí¹e aktuální stav prostoru pro promìnné. PCALL Vrací volací znak první pøipojené protistanice na aktuálním kanálu pøi právì probíhajícím spojení. UTCTime Vrací aktuální èas UTC (hodnota z os). d) pøíkazy pro zmìnu nastavení CBell [on|off] Zapne/vypne zvukový signál pøi navázání nebo ukonèení spojení. FIXPath [on|off] Pøi FIXPath=ON se ignorují zadané cesty k souborùm u externích pøíkazù oznaèených pøíznakem P. Je tedy mo¾né pou¾ívat pouze cestu USER_PATH pro ètení souborù a SAVE_PATH pro zápis souborù. INFOLEvel [0|1|2] Nastaví zobrazování informaèního øádku: 0 - vypnuto (¾ádné informace o stavu spojení) 1 - zobrazení dùle¾itých informací 2 - zobrazení v¹ech informací Language [jazyk] Nastaví aktuální jazyk. Zatím podporováno pouze pro skripty (skript se hledá nejdøíve v adresáøi s pøíslu¹ným jménem) MYcall Zmìna volací znaèky pro daný kanál. REMote [on|off] Zapnutí/vypnutí dálkového ovládání. Port Nastaví port, který se pou¾ije pøi pøíkazu Connect, pokud není explicitnì zadán. TIMEZone [zóna] Nastavení èasové zóny. Pouze se ukládá, nemá vliv na èas. UNSrc [znaèka] Nastaví znaèku odesilatele pro neèíslované rámce. UNDest [znaèka] Nastaví cílovou adresu pro neèíslované rámce. WAtch <øetìzec> Zapne sledování daného portu (0 - v¹echny porty). Pokud od protistanice pøijde zadaný øetìzec, vykoná se pøíkaz (pøíkaz musí zaèínat dvojteèkou, jinak jde o text k vypsání) e) pøíkazy pro ovládání obrazovky STATLINE Umístí hlavní stavový øádek na n-tý øádek obrazovky. CHNLINE Umístí øádek pro pøepínání kanálù na n-tý øádek obrazovky. SWAPEDit Zamìní okno editoru s oknem spojení. INFOLine <èíslo> Zmìní stavový øádek oznaèený èíslem na zadaný text. Pokud takový øádek neexistuje, je vytvoøen. REMOVEINFO <èíslo> Odstraní stavový øádek oznaèený daným èíslem. TRanslate Zapne pøekódování vstupu a výstupu podle zadané tabulky. Tabulky jsou ulo¾eny v souborech *.ctt TErm Nastavý typ terminálu. Pokud se zadá typ 'ansi', pøepne se terminál do re¾imu ansi barev. SCRLimit Kdy¾ velikost bufferu s pøijímanými daty pøesáhne hodnotu high-limit, potom je buffer zkrácen na low-limit. Hodnoty se udávájí v bajtech. Implicitní hodnoty jsou 384 kB a 512 kB. f) systémové pøíkazy RESULT Vrátí zadaný text jako výsledek skriptu. g) pøíkazy pro práci s øetìzci STRMid <øetìzec> Vrací podøetìzec zadaného øetìzce zaèínající na pozici délky maximálnì znakù STRLeft <øetìzec> Vrací prvních znakù øetìzce STRRight <øetìzec> Vrací posledních znakù øetìzce STRLen <øetìzec> Vrací délku øetìzce STRPos <øetìzec> Hledá v øetìzci podøetìzec, vrací pozici zaèátku nebo -1 kdy¾ nebyl nalezen UPCASE <øetìzec> Pøevede øetezec na velká písmena 2) Externí pøíkazy RPrg Vy¹le soubor protokolem autobin. Bell Zvukový signál pro pøivolání operátora. Compose Vytvoøení privátní zprávy/bulettinu pro danou znaèku. FORWARD Odeslání dosud neodeslaných zpráv do domácí BBS. MHeard Vypsání sly¹ených stanic. MAIL Vyvolá nástroj pro ètení a psaní po¹ty Name Ulo¾ení jména a editace databáze stanic (viz. Name -h) RTt Mìøení èasu pøenosu mezi stanicemi. YPUT Vyslání souboru protokolem YAPP. Write Zaèátek ukládání pøíchozího textu do souboru. Ukonèí se :Write off. Read Vyslání zadaného textového souboru. WBin / RBin Jako Write / Read, ale pro binární soubory. GETMsg <èíslo> Získání zprávy z domácí BBS. 3) Makra Activity Výpis èasu od poslední akce operátora. Conv Vstup do konference Info Informace o stanici. Help Struèná nápovìda k pøíkazùm Quit Vyslání ukonèovacího textu a ukonèení spojení. Users / CStatus Seznam pøipojených u¾ivatelù Pøíkazy pro vytváøení skriptù ============================= MACRO [název] Uvozuje definici pøíkazového skriptu (viz ní¾e) LABEL Definuje návì¹tí daného jména. U pøíkazových skriptù lze nahradit zápisem :. GOTO Skok na dané návì¹tí. IF ~ ELSE ~ ENDIF Podmínkové pøíkazy. Existují dva zpùsoby zápisu podmínky: - normální zápis (pro více pøíkazù): IF . . (pøíkazy, které se mají vykonat pøi splnìní podmínky) . . ELSE . . (pøíkazy, které se mají vykonat pøi nesplnìní podmínky) . . ENDIF Èást ELSE lze vynechat a pou¾ít pouze IF ~ ENDIF. - zkrácený zápis (pro jeden pøíkaz) IF () pøíkaz (podmínka je uvedena v závorkách, pøíkaz se provede pøi jejím splnìní) Pro zápis podmínek lze vyu¾ít operátory = (nebo ==), <, >, <= (nebo =<), >= (nebo =>), != (nebo <>). Pokud oba operátory jsou èísla, porovnají se jako èísla, jinak se porovnají jako øetìzce. Vytváøení skriptù ================= Skript lze definovat vytvoøením souboru macro/.mac. Pokud mù¾e být pøíkaz zkrácen, je tøeba jej uvést v souboru "commands" ve stejném adresáøi. Existují dva zpùsoby zápisu skriptu: a) Textové skripty Tento zpùsob definice je vhodný pro pøíkazy, jejich¾ hlavním úkolem je vypsat nìjaký text (napøíklad informace o stanici). Po spu¹tìní takto definovaného pøíkazu je ka¾dý øádek souboru, který nezaèíná dvojteèkou zobrazen na obrazovku (odeslán protistanici). Pøíkazy musí zaèínat dvojteèkou, je mo¾no pou¾ít v¹echny pøíkazy LinPacu i ostatní u¾ivatelem definované pøíkazy a navíc speciální pøíkazy pro skripty. Tímto zpùsobem lze do textu vlo¾it napøíklad informaci o probíhajících spojeních (pøíkazem :Users) nebo modifikovat text pomocí pøíkazu :IF,:ELSE a :ENDIF. b) Pøíkazové skripty Pøedchozí zpùsob definice umo¾òuje snadné vypisování textu, av¹ak pøi pou¾ití vìt¹ího mno¾ství pøíkazù se definice stává velmi nepøehlednou. Definice ve formì pøíkazù je oproti tomu vhodná k zápisu vìt¹ího mno¾ství pøíkazù s men¹ím mno¾stvím vypisovaného textu. První øádek takové definice musí tvoøit pøíkaz :MACRO (na zaèátku øádku) za kterým mù¾e následovat jakýkoliv text (napø. jméno makra atd.). Za tímto øádkem lze psát pøíkazy, pøed které se u¾ nepí¹e dvojteèka. Tyto pøíkazy nemusí zaèínat na zaèátku øádku (mohou být libovolnì odsazeny), prázdné øádky se pøeskakují. Text se vypisuje pomocí pøíkazu Echo. linpac-0.28/doc/czech/stanice.txt0000664000076400007640000001060514006074433013677 00000000000000[Document encoding ISO-8859-2] LinPac - Databáze stanic ------------------------ Databáze je urèena pro ukládání v¹ech informací o protistanicích. Ve¹keré tyto informace jsou ulo¾eny v souboru "station.data" a lze je mìnit buï pøímo editací tohoto souboru, nebo prostøednictvím pøíkazu Name (popsáno dále). 1. Formát souboru station.data ------------------------------ Informace o ka¾dé stanici jsou uvedeny v odstavci, který zaèíná znaèkou stanice v hranatých závorkách a konèí buï hlavièkou popisu jiné stanice nebo koncem souboru. Ka¾dý øádek obsahuje jednu definici ve tvaru =. Typický záznam o stanici mù¾e tedy vypadat napøíklad takto: [OK0NMA] NAME=PC/Flexnet Brno TYPE=FLEXNET LOC=JN89HE QRG=144.8125 MHz SYSNUM=85964 ®ádná polo¾ka není povinná a u¾ivatel mù¾e do databáze pøidávat libovolné dal¹í polo¾ky podle toho, jaké informace potøebuje uchovávat. Nicménì pro zachování urèitého standardu se pro standardní informace doporuèuje pou¾ívat tìchto jmen: NAME - textové informace o stanici nebo jméno operátora. Pokud je tato polo¾ka uvedena v databázi, LinPac zobrazí její obsah pøi spojení s danou stanicí. LOC - QRA lokátor stanice. LinPac se opìt pokusí zobrazit tuto informaci pøi návázání spojení s protistanicí. TYPE - Typ protistanice. Pro obvykle pou¾ívané typy se doporuèuje: FLEXNET, THENET, FBB, BAYBOX, DIEBOX, TNOS, JNOS, DXC a pro u¾ivatelské terminály TERM. Takto udaný typ je ov¹em vyu¾íván pouze u¾ivatelem, lze proto pou¾ít libovolné oznaèení typu stanice. LANG - Jazyk kterým se má komunikovat s protistanicí. Pokud je definován, LinPac se pøi spu¹tìní makra hledat soubor s definicí makra nejprve v podadresáøi s tímto jménem (macro/). NICKNAME - pøezdívka operátora, v èe¹tinì lze vyu¾ít pro ulo¾ení pátého pádu jména. Standardní konfigurace LinPacu vyu¾ívá navíc je¹tì tyto polo¾ky: TERM - jaký druh terminálu se má pou¾ít. Pokud je nastaveno 'ansi', LinPac se po spojení s touto stanicí pøepne do re¾imu zobrazování barev, co¾ lze vyu¾ít napøíklad u TNOS BBS. Stejný efekt má i pøíkaz TErm (viz prikazy.txt) ENC - pou¾ité pøekódování vstupu a výstupu. Pøi spojení se pøepne na kódovací tabulku s tímto jménem. To umo¾òuje komunikovat s ka¾dou protistanicí v jiném kódování èe¹tiny. Stejný efekt má pøíkaz TRanslate. RCMD - seznam povolených vzdálených pøíkazù. QRG - frekvence u¾ivatelského vstupu dané stanice, pou¾ije se v záznamech do stanièního deníku. 2. Pou¾ití pøíkazu Name ----------------------- Pøíkaz name lze pou¾ít ke zmìnám v databázi stanic bez nutnosti pøímé editace souboru. Samotný pøíkaz bez parametrù zpùsobí vypsání zadaného jména právì pøipojené protistanice. Zadáním dal¹ích parametrù se provede zmìna údajù o právì pøipojené stanici. Pou¾itelné parametry: - zmìna polo¾ky NAME -l - zmìna polo¾ky LOC -t - TYPE -L - LANG -n - NICKNAME -s = - zmìna jiné polo¾ky. Pøíkaz Name -i vypí¹e v¹echny zadané informace o stanici. Pokud chceme mìnit informace o jiné ne¾ právì pøipojené stanici, pøidáme parametr -c . Pøíklad: :NAME -c OK2JBG -n Radku -l JN89HF Radek 3. Vyu¾ití údajù v databázi --------------------------- Jak ji¾ bylo popsáno, LinPac pro vnitøní potøebu vyu¾ívá pouze polo¾ky se jmény NAME, LOC a LANG. Vyu¾ití ostatních polo¾ek závisí na u¾ivateli. Pøi ka¾dém spojení se stanicí, která má záznam v databázi stanice se vytvoøí promìnné se jmény STN_, které lze vyhodnotit v makrech. Pøíklad pou¾ití: chci aby se ka¾dá pøipojená stanice oslovila pøezdívkou operátora a pokud pøezdívka není zadána, aby se oslovila jménem operátora. Pøi ka¾dém pøipojení protistanice se spou¹tí makro 'ctext.mac' ulo¾ené v adresáøi macro. Obsah tohoto souboru v na¹em pøípadì mù¾e vypadat napøíklad takto: :if %(exist STN_NICKNAME) == 1 ;;pokud existuje STN_NICKNAME Ahoj %STN_NICKNAME ! ;;pozdrav pøezdívkou :else ;;jinak (pokud neexistuje) Ahoj %N ! ;;pozdrav jménem :endif ;;(dal¹í pøíkazy se provedou v¾dy) Pøipojil ses k %Y v %T. ;;Sdìl svoji znaèku a èas. Teï ji¾ staèí jen pøidat øádek NICKNAME=pøezdívka k záznamu ka¾dé stanice, kterou chci oslovovat pøezdívkou. linpac-0.28/doc/events.txt0000664000076400007640000004461714006074433012473 00000000000000LinPac internal events ---------------------- This list contains the description of almost all events that can occur in LinPac. Each application can generate any of these events and it can also handle any of them. The names of the source objects are written in parenthesis. The list of internal LinPac objects can be found in the file objects.txt. a) User interaction EV_KEY_PRESS (key pressed) Generated by: The user interface (Keyscan) when a keyboard key is pressed Handled by : User interface Data : x - key code (ncurses-compatibile) y - 0 when Alt wasn't pressed EV_KEY_PRESS_MULTI (multiple keys pressed) Generated by: The user interface (Keyscan) when multiple printable keyboard keys are pressed in rapid succession Handled by : User interface Data : data - pointer to c-string EV_TEXT_RAW (raw output text) Generated by: Text editor (Editor*) when the text line is confirmed Macro processor (Macro*) (line from a macro) Remote command source (Command) Handled by : Text cooker (Cooker) - replacing the text macros Data : chn - channel number data - pointer to c-string x - contains source description: FLAG_REMOTE - remote command FLAG_MACRO - command from macro, wasn't processed with macro command interpreter (can contain some macro command such as IF ot GOTO) FLAG_FM_MACRO - command from macro that is not a special macro command (already processed with macro command interpreter) FLAG_EDIT - from text editor (local user) EV_TEXT_ARGS (cooking arguments for EV_TEXT_RAW, must be sent just before each EV_TEXT_RAW when needed). Generated by: Macro processor (Macro*) before sending EV_TEXT_RAW line to tell the Cooker object the arguments of the Macro (for cooking %1 - %9). Handled by : Text cooker (Cooker) Data : chn - channel number data - strings arguments separated by \0 x - data length EV_TEXT_COOKED (cooked output text) Generated by: Text variables processor (Cooker) after receiving the EV_TEXT_RAW event and replacing the variables with their values. Any application that wants to send out some text or command. Handled by : Command processor (Command) (when the text starts with ':') I/O interface (Ax25io) (when the text doesn't start with ':') - the output is cached (text is not transmitted immediately) Data : chn - channel number data - pointer to c-string x - source description copied from the received EV_TEXT_RAW event EV_TEXT_FLUSH (flush output) Generated by: any source Handled by : I/O interface (Ax25io) - transmits the cache contents and clears the cache Data : chn - channel number x = FLAG_FLUSH_IMMEDIATE - flush the output buffer now = 0 - flush after cooking last EV_TEXT_RAW (usual value) EV_EDIT_INFO (insert info into editor) Generated by: Command processor (Command) Handled by : Text editor (Editor*) - inserts the information behind current line and moves after this text Data : chn - channel number data - pointer to c-string EV_CALL_CHANGE (change the callsign) Generated by: Command processor (Command) (:mycall command, :connect command) Handled by : AX.25 I/O interface (Ax25io) - changes the callsign of the channel Data : chn - channel number data - new callsign (c-string) EV_UNPROTO_SRC (change unproto source) Generated by: Command processor (Command) (:unsrc) Handled by : AX.25 I/O interface (Ax25io) - changes the unproto source callsign Data : chn - channel number data - new callsign (c-string) EV_UNPROTO_DEST (change unproto destination) Generated by: Command processor (Command) (:undest) Handled by : AX.25 I/O interface - (Ac25io) changes the unproto destination callsign Data : chn - channel number data - new callsign (c-string) EV_UNPROTO_PORT (change unproto port) Generated by: Command processor (Command) (:unport) Handled by : AX.25 I/O interface (Ax25io) - changes the unproto port Data : chn - channel number data - new port name (c-string) EV_WANT_RESULT (execute the command and generate a result event) Generated by: Variable processor (Cooker) when replacing %(command) Handled by : Command processor - executes the command and generates the EV_CMD_RESULT event containing the result Data : chn - channel number data - command string (without the initial ':') (c-string) x - result ID. The EV_CMD_RESULT generated by command processor will have the same ID (for recognizing the right result) EV_CMD_RESULT (the command result) Generated by: Command processor as the answer to EV_WANT_RESULT event or after executing a command that returns some result (:strlen ...) The application using the appl_result() function. Handled by : Command processor - when ID == FLAG_NO_HANDLE then generates the EV_EDIT_INFO event to display the result in editor The creator if EV_WANT_RESULT with the same result ID. Data : chn - channel number data - result text (c-string) x - result ID - can contain the ID of the EV_WANT_RESULT event that caused this event or it can contain FLAG_NO_HANDLE (value -1) when this is not the answer to any EV_WANT_RESULT EV_DO_COMMAND (execute the command) Generated by: any source Handled by : Command processor - executes this command Data : chn - channel number data - command without the initial ':' (c-string) EV_SELECT_CHN (current channel change) Generated by: User interface (Keyscan) (user pressed F1 - F10) Applications that want to switch the channel Handled by : Many objects (object activation/deactivation etc...) Data : chn - new channel number: 1 to 8 - normal channels (F1 - F8) 0 - unproto channel (F10) -1 to -8 - channels for fullscreen applications (Alt-1 - Alt-8) -10 - channel for fullscreen application (Alt-0) EV_USER_ACT (user is active) Geterated by: User interface (Keyscan) (user has done some action) Handled by : User activity counter (clears) Data : none b) Macros EV_MACRO_STARTED (macro processing has been started) Generated by: Macro processor (Macro*) Handled by : Macro processor - pauses processing other macros on the channel Data : chn - channel nuber data - pointer to new macro processor (for identification) EV_MACRO_FINISHED (macro processing has been finished) Generated by: Macro processor Handled by : Macro processor - resumes processing other macros on the channel Data : chn - channel nuber data - pointer to finishing macro processor (for identification) c) Character input/output EV_DATA_INPUT (data block received) Generated by: I/O interface (Ax25io) after receiving some data Handled by : User interface (QSOWin*) - display incomming text Incomming text watcher (Watch) - scan for pattrens Data : chn - channel number data - pointer to char buffer (char[]) x - block length (characters) EV_DATA_OUTPUT (data block transmitted) Generated by: I/O interface (Ax25io) after transmitting some data Handled by : User interface (QSOWin*) - display outgoing text Data : chn - channel number data - pointer to char buffer (char[]) x - block length (characters) EV_LOCAL_MSG (local info text) Generated by: I/O interface Handled by : User interface - display local info Data : chn - channel number data - pointer to char buffer (char[]) x - block length (characters) EV_LINE_RECV (text line received) Generated by: I/O interface (Ax25io) after receiving end of line in incomming data Handled by : Command processor - check for "//" - external commands Incomming text watcher - check for "connected to" ... Data : chn - channel number data - pointer to char buffer (char[]) x - block length (characters) EV_RX_CTL (rx data flow control) Generated by: Command processor (Command) - :rxflow on/off I/O interface when new incomming connection establishes (for synchronization reasons) Handled by : I/O interface (Ax25io) Data : x - 0 = rxflow is off, 1 = rxflow is on d) Connection EV_CONN_LOC (begin connection) Generated by: Command processor (:connect) Application that wants to initiate the connection Handled by : I/O interface - begins the connection Data : chn - channel number data - c-string with destination address in format port:CALL DIGI1 DIGI2 ... EV_DISC_LOC (close connection) Generated by: Command processor (:disconnect) Application that wants to close the connection Handled by : I/O interface - closes the connection Data : chn - channel number EV_CONN_TO (connection established) Generated by: I/O interface when connection establishes Handled by : User interface (QSOWin*) (display the message...) Data : chn - channel number data - connected callsign (c-string) x - 0 when we initiated the connection (else other party has initiated the connection) EV_DISC_FM (connection closed) Generated by: I/O interface when station disconnects Handled by : User interface (QSOWin*) (display the message...) Data : chn - channel number data - disconnected callsign (c-string) EV_DISC_TIME (disconnected for timeout) Generated by: I/O interface when station disconnects for timeout Handled by : User interface (QSOWin*) (display the message...) Data : chn - channel number data - disconnected callsign (c-string) EV_CONN_REQ (unsuccesful connect request) Generated by: I/O interface when some station requests the connection and there is no free channel Handled by : User interface (QSOWin*) (display the message...) Data : chn - channel number data - callsign (c-string) EV_FAILURE (connection failure) Generated by: I/O interface when connection breaks Handled by : User interface (QSOWin*) (display the message...) Data : chn - channel number data - callsign (c-string) EV_RECONN_TO (reconnected to) Generated by: Incomming text watcher (Watch) when the message is detected Handled by : User interface (InfoLine...) Data : chn - channel number data - new callsign (c-string) x - 1 when connected forward ("connected to" message) else connected back ("reconnected to" message) EV_STATUS_CHANGE (connection status changed) Generated by: I/O interface when connection status changes Handled by : User interface (display new status) Data : chn - channel number x - new status: ST_DISC - disconnected ST_DISP - disconnecting ST_TIME - disconnecting for timeout ST_CONN - connected ST_CONP - connecting in progress EV_DISABLE_CHN (disable connections to the channel) Generated by: Command processor (:priv) Applications that want to reserve the channel Handled by : I/O interface (marks the channel) User interface (shows the ++++++ instead of ------) Data : chn - channel number EV_ENABLE_CHN (enable connections to the channel) Generated by: Command processor (:priv) Application Handled by : I/O interface User interface Data : chn - channel number EV_LISTEN_ON (enable incomming connections) Generated by: Command processor (:list) Handled by : I/O interface (creates listening sockets) Data : none EV_LISTEN_OFF (disable (=ignore) incomming connections) Generated by: Command processor (:list) Handled by : I/O interface (closes listening sockets) Data : none e) Screen EV_DISABLE_SCREEN (disable output to QSO window) Generated by: Applications (in case of binary transfer...) Handled by : User interface (stops displaying the data in QSO window) Data : chn - channel number EV_ENABLE_SCREEN (enable output to QSO window) Generated by: Applications (end of binary transfer...) Handled by : User interface (enables output to window) Data : chn - channel number EV_CHANGE_STLINE (change or create additional status line) Generated by: Command processor (:infoline) Applications using the statline() function Handled by : User interface (add or change the status line) Data : chn - channel number data - status text (c-string) x - line ID. If the line with this ID doesn't exist, it's created. If it exists, the content is changed. EV_REMOVE_STLINE (remove aditional statusline) Generated by: Command processor (:removeinfo) Applications using the remove_statline() function Handled by : User interface Data : chn - channel number x - line ID EV_CONV_IN (install input conversion table) EV_CONV_OUT (install output conversion table) Generated by: Command processor (:trans) Handled by : User interface Data : chn - channel number, 0 means all channels and monitor window x - table length, max 256 data - x bytes, each byte represents the output character when the character with ASCII value equal to index of that byte is received. When the value of received character is greater than x no conversion is done. EV_CONV_NAME (use specified i/o character encoding) Generated by: Command processor (:trans) Handled by : User interface Data : chn - channel number, 0 means all channels and monitor window data - c-string containing encoding name EV_SET_TERM (set terminal type - none, ansi, ...) Generated by: Command processor (:term) Handled by : User interface Data : chn - channel number data - terminal name (c-string) EV_REDRAW_SCREEN (redraw the screen) Generated by: Command processor (:redraw) Handled by : User interface Data : none EV_MONITOR_CTL (control the monitor) Generated by: Command processor (:monitor) Handled by : User interface (monitor window) Data : x = 0 : disable monitor function (stop displaying anything into the monitor window) x = 1 : enable monitor function f) Application communication EV_APP_MESSAGE (message from application to other application) Generated by: application Handled by : application Data : data - message text (c-string) EV_APP_RESULT (an application result) Generated by: application Handled by : Event manager - after the application finishes the EV_CMD_RESULT with the same data is generated. Data : data - the result message (c-string) EV_REG_COMMAND (register a command for an application) Genereted by: application (wants to provide an user command) Handled by : Command processor (Command) - considers the command as the known one, when execution of this commands is requested, generates EV_APP_COMMAND. Data : data - command name (c-string) EV_UNREG_COMMAND (cancel command registration) Generated by: application Handled by : Command processor (Command) - command registration is caneclled. Data : data - command name (c-string) EV_APP_COMMAND (a command to be executed by an application) Generated by: Command processor (Command) - registered command requested Handled by : application that provides such command Data : chn - execution channel data - command name and arguments (c-string) g) Other events EV_STAT_REQ (application requests the AX.25 connection status) Generated by: application Handled by : LinPac status server (Status) - generates EV_STATUS Data : chn - channel number EV_STATUS (connection status info) Generated by: LinPac status server (the answer to EV_STAT_REQ event) Handled by : application Data : chn - channel number data - points to the ax25_status structure EV_DISABLE_OBJ (temporarily disable an internal object) Generated by: anybody Handled by : Event manager (stops sending the events to this object) Data : data - object name (e.g. QSOWindow1) (c-string) EV_ENABLE_OBJ (enable an internal object) Generated by: anybody Handled by : Event manager (resumes sending the events to this object) Data : data - object name (c-string) EV_ADD_WATCH (watch for pattern in input data) Generated by: Command processor (Command) - :watch Handled by : Input text watcher (Watch) Data : chn - channel (0 = all the channels) data - text pattern EV_ABORT (abort application) Generated by: Command processor (:abort) Handled by : application (compares the address with its own one and aborts) Data : chn - channel number data - abort address (command parameter) (c-string) EV_VOID (void event - synchronization reasons) Generated by: anybody Handled by : nobody Data : none EV_SYSREQ (request special actions - debugging...) Generated by: normally nobody Handled by : Event manager Data : x - request number. Currently implemented: 0: check if debugging is supported 1: dump a list of active internal modules to errorlog 2: toggle macro debugging (this dumps the internal macro notation to errorlog each time a macro is executed) EV_QUIT (quit LinPac) Generated by: Command processor (:system) Handled by : Event manager (stops working) Data : none linpac-0.28/doc/objects.txt0000664000076400007640000000364114006074433012610 00000000000000LinPac internal objects ----------------------- This is a list of LinPac internal objects. Each object is identified by its name (up to 10 characters). Object name | Description ----------------+----------------------------------------------------------- SCREEN | Screen manager. | Keyscan | Reads the keyboard, generates appropriate events when one or | more keys are pressed (EV_KEY_PRESS, EV_KEY_PRESS_MULTI) | Command | Interpret commands represented by EV_DO_COMMANDS, | EV_TEXT_COOKED (starting with :) or EV_LINE_RECV | (remote commands) | Ax25io | Ax25 i/o interface. Sends/receives packets, generates | EV_DATA_INPUT, EV_DATA_OUTPUT, EV_LOCAL_MSG, creates | packets from EV_TEXT_COOKED and sends them. | Cooker | Converts EV_TEXT_RAW to EV_TEXT_COOKED (macro | replacement). | ChnInfo | Channel information line (shows callsigns depending on the | connection/reconnection events) | InfoLine | Connection status line. | MonWin | Monitor window. | QSOWin1 - | QSO windows for each channel. Displays the data contained QSOWin8 | in EV_DATA_INPUT, EV_DATA_OUTPUT and EV_LOCAL_MSG events. | Editor0 - | Editor windows each channel (0 = unproto mode). Reads the Editor8 | EV_KEY_PRESSED and EV_KEY_PRESS_MULTI events and produces | EV_TEXT_RAW events. | Statln1 - | Managers of additional status lines (one for each Statln8 | channel). | StnDB | Station database. Reacts to (re)connection events and | produces information messages, sets the variables, etc. | Watch | Input data watcher. Looks for patterns in input data, | produces command events when some pattern is found. | Sound | Produces various sounds when some particular event occurs. | Status | Registers connection status, generates status events. | ----------------+------------------------------------------------------------ linpac-0.28/doc/applguide.html0000664000076400007640000011044314006074433013255 00000000000000 LinPac External Application Programming Guide

LinPac - Packet Radio Terminal for Linux


Version 0.28

(c) Martin Cooper KD6YAM 2020
(c) David Ranch KI6ZHD (linpac@trinnet.net) 2002 - 2020
(c) 1998 - 2001 by Radek Burget OK2JBG

External Application Programming Guide

Contents

1 Introduction

2 What is an external program?

3 Basic concepts of the API

4 How applications communicate with LinPac

5 Using the application library
5.1 The simplest application

6 Application programming
6.1 Events
6.2 Sending and receiving events
6.3 Synchronization
6.4 Shared variables and configuration
6.5 Connection status
6.6 Event usage examples
6.6.1 Connecting to a remote station
6.6.2 Using LinPac commands in programs

7 The application library interface
7.1 Constants
7.2 Data structures
7.3 Functions
7.3.1 Uninterruptable versions of some system calls
7.3.2 Basic communication functions
7.3.3 Automatic event handling functions
7.3.4 Environment functions
7.3.5 User functions
7.3.6 Tool functions
7.3.7 Application information functions

8 The shell interface
8.1 Writing the script
8.1.1 Ensuring that LinPac is running
8.1.2 Accessing configuration and state
8.1.3 Executing commands
8.1.4 Simple shell example
8.2 Creating the command

1 Introduction

This guide is written for programmers who want to add some new functions to LinPac. In the following text, basic knowledge of Linux programming is assumed. Reading the LinPac User Manual before proceeding is also recommended.

2 What is an external program?

An external program is a standard Linux application which uses LinPac to communicate with remote stations. There are basically two types of LinPac external programs:
  • Standard Linux applications that use standard input and output streams. These programs can be used without LinPac too. LinPac allows redirection of the input stream (stdin) of the application and any of the output streams (stdout, stderr) or both of them. LinPac can also provide CR/LF conversions in these streams. These parameters are set when adding the external program to LinPac - see Section 7, "Creating new commands", in the User Manual.
  • Applications written using LinPac's application interface. These applications can share some information with LinPac, and they can control almost all functions of LinPac.
No special knowledge of LinPac is needed for creating the first type of programs, because no LinPac functions are used. The remainder of this guide is dedicated to the second type of applications.

3 Basic concepts of the API

The LinPac application interface is based on events. Every action in LinPac, such as pressing a key, receiving data, executing a command, etc., is represented by a data structure called an event, which describes exactly what happened. LinPac's internal structure consists of separate objects which communicate with each other using these events. Each object provides its own functionality, and often generates events. For example, the object Keyscan produces an event each time any key is pressed.

All the events generated by any object are put into the common event queue. The LinPac kernel simply takes the events from the queue one by one and sends them to all the objects (including the one that generated the event). Thus each event generated by any part of LinPac is forwarded to all of the objects. The reaction of each object fully depends on its functionality, but of course it can include generation of other events.

The list of LinPac internal objects and their names can be found in the file objects.txt.

An additional feature of the API is a shared variable environment. This is a set of variables that is shared with LinPac; the values are automatically synchronized with all the external programs. These variables are accessed using special functions of the API as described below.

4 How applications communicate with LinPac

LinPac uses TCP/IP sockets for communication with external programs (applications). The connection is always initiated by the application after it starts. There are basically two ways that an application may be started:
  • The application is started by LinPac, through being associated with a LinPac command. In this case LinPac registers the channel on which the application was started and expects the connection attempt from the application. After the application initializes and contacts LinPac, it is provided with the working channel and whether it was started by a remote or local user. LinPac may also redirect the input and output streams of the application (depending upon LinPac settings).
  • The application is started without using LinPac. In this case LinPac assumes that the application runs on channel 0 and was started by the local user. The input and output streams of the application are not redirected.
In both cases, the start of an application causes the creation of a new object in LinPac called an event gate. This object represents the application within LinPac. Bearing in mind the previous chapter, this means that the application is forwarded all of the events generated by any LinPac object, and all of the events generated by the application are forwarded to all LinPac objects.

NOTE: All of the communication via TCP/IP sockets is provided by the LinPac application library. The user application should not attempt to access the sockets directly.

5 Using the application library

During LinPac installation, the application library liblinpac is created and installed by default to /usr/local/lib. The interface to this library is contained in the file lpapp.h, which is installed by default to /usr/local/include/linpac. The next chapter illustrates how to use the library within a user application.

5.1 The simplest application

The following application example just tries to contact LinPac, and prints the result.

#include <stdio.h> #include <unistd.h> #include <linpac/lpapp.h> int main() { if (lp_start_appl()) { printf("Application started\n"); sleep(10); printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; }

The function lp_start_appl() tries to contact LinPac and returns 1 in case of success or 0 when a connection to LinPac cannot be made (probably because it's not running). This function should precede the usage of any other application library functions.

The function lp_end_appl() closes the connection to LinPac.

To compile this example, use:

$ gcc -o test1 test1.c -llinpac

This example just detects if LinPac is running, and it can be executed directly from the shell. When running from the shell, no streams are redirected to LinPac, and the application appears to run on channel 0 of LinPac. This is useful for some applications that are used to control LinPac from outside. However this is not a typical use case.

For most applications, it is better to copy the executable to the $LINPACDIR/bin directory and then add it to the file $LINPACDIR/bin/commands as described in the User Manual. After this, the application can be executed as a LinPac command. In this scenario, the streams are properly redirected and the application output is visible in the LinPac QSO window. It is also possible to select the channel on which to run the application.

NOTE: The LinPac application library (liblinpac) can be linked without problems with both C and C++ code.

6 Application programming

6.1 Events

LinPac is completely driven by events. Each part of LinPac, including applications, can generate events to inform other parts (internal modules or applications) that something has happened. Each event is sent to all LinPac components and applications. For example when some station connects to some LinPac channel, the internal AX.25 interface generates an event reporting that the station has connected and includes its callsign. All components and applications now know who has connected, and they can take some actions. For example, the output window prints information about the connection, the macro processor executes the cinit.mac macro, and so on. Each application can handle all of the events too, and can generate events which are handled by other components.

An event is represented by the following structure:


struct Event
{
    int type;
    int chn;
    int x,y;
    char ch;
    void *data;
};

The meaning of each field is as follows:

type
Specifies the type of the event. Actually it determines what happened. There is a symbolic constant defined for each known event type.
chn
Specifies the channel to which the event applies. For example, if the type of the event specifies that some data was received, the chn field contains the number of the channel which has received that data. There are many events that apply for all the channels. For those events, this field is not significant.
x, y
The meaning of these fields depends on the event type. The y field is usually not used, other than by some internal events.
ch
This field is used only by some internal events.
data
Depends on the type of the event. It usually points to some string data or a char buffer.

All of the event types are described in the event list.

6.2 Sending and receiving events

For sending events the following function is used:

int lp_emit_event(int chn, int type, int x, void *data);

This generates a new event using the specified values. Each argument corresponds to one of the fields in the Event structure.

There are two modes for handling incoming events:

a) Reading each event on demand

This mode is started by the lp_event_handling_off() call. In this mode, events are read explicitly using the function:

int get_event(Event *ev);

This function returns 0 when no event is available. When an event is available, it returns 1 and fills the Event structure with the received event data.

WARNING #1: The data field in your Event structure must point to a dynamically allocated buffer. The size of the buffer is reallocated automatically after receiving an event. When the data field is set to NULL, a new buffer is allocated. This field must be initialized.

WARNING #2: In this mode, the application must read all events. It is not a good idea to stop reading events, because the event queue may overflow. LinPac will automatically kill the application when the event queue exceeds some reasonable number of events.

b) Automatic event processing

This mode is started by the lp_event_handling_on() call. All events are read automatically. Programmers can define their own function that will be called automatically when an event occurs. When no such function is defined, all events are discarded.

The event handling function must have following prototype:

void my_event_handler(Event *ev);

(The function name may be different.) After initializing the application, the event handling function must be registered using the function:

lp_set_event_handler()

from the application library.

The following example is an application that prints the types of all events received and stops when an EV_ABORT event is received. This event can be generated using the :ABort command in LinPac.


#include <stdio.h> #include <linpac/lpapp.h> int aborted = 0; //User event handling function. This function is called each time //an event occurs void my_event_handler(Event *ev) { printf("The event of type %i has been received\n", ev->type); if (ev->type == EV_ABORT) aborted = 1; } int main() { if (lp_start_appl()) { lp_event_handling_on(); //turn on automatic event handling lp_set_event_handler(my_event_handler); //define own event handler printf("Application started\n"); printf("Stop with the ':Abort' command\n"); do ; while(!aborted); //wait until application is aborted printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; }

This example contains "active waiting" (the do ; while(...) construction). This is very ugly and inefficient. For this reason, the LinPac API offers an alternative for waiting for events, namely the lp_wait_event() function. Let's change the example to use this function:


#include <stdio.h> #include <linpac/lpapp.h> int main() { if (lp_start_appl()) { lp_event_handling_on(); //turn on automatic event handling printf("Application started\n"); printf("Stop with the ':Abort' command\n"); lp_wait_event(lp_channel(), EV_ABORT); //wait for the abort event printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; }

WARNING: Note that some system calls may be interrupted when an event is received. An interrupted system call returns an error result (for example the read() call returns -1), sets errno to EAGAIN, and must be called again. To avoid this, use the interrupt-safe versions of the system calls contained in this application library. (See Chapter 7.3.1.)

6.3 Synchronization

An event generated by an application is sent to all modules and applications, including the application that generated the event. When there is a need to wait until the event is accepted by LinPac, the simplest way is to wait until the event we have sent is received back.

For testing that all events were processed, there is an EV_VOID event. It is not handled by any module. After sending all events, just generate an EV_VOID event and wait until it returns. After that, you can be assured that all previous events have been processed.

6.4 Shared variables and configuration

Each shared variable is denoted by its name (string) and channel number. Each variable has a value represented by a string (char[]). Access to these variables is provided by following functions:
void lp_set_var(int chn, const char *name, const char *value)
Changes the value of the variable. If the variable doesn't exist, it is created.
char *lp_get_var(int chn, const char *name)
Reads the value of the variable. Returns NULL if the variable doesn't exist.
void lp_del_var(int chn, const char *name)
Deletes the variable.
void lp_clear_var_names(int chn, const char *prefix)
Deletes all variables with the specified name.

The value of each variable is automatically synchronized with LinPac and all running applications. The variables whose names start with "_" are reserved for system use. These variables can be used for obtaining system configuration and status but it may be potentialy dangerous to change some of these variables.

NOTE: Many of the variables contain boolean values. Their value is 1 when true, 0 otherwise.

Currently the following system variables are defined (in channel 0):

_remote
1 when remote commands are enabled
_cbell
1 when connect sound is enabled
_knax
1 when sound signal for each frame is enabled
_def_port
default port name
_unportname
port name for unproto frames
_unport
port number for unproto frames
_info_level
status-line level (0 to 2)
_no_name
default station name
_timezone
local timezone name
_swap_edit
1 when swapedit is on
_fixpath
1 when fixpath is on
_daemon
1 when linpac works as a daemon
_monitor
1 when monitor is enabled
_no_monitor
1 when monitor is disabled from command line
_listen
1 when accepting connections is enabled
_disable_spyd
1 when ax25spyd support is disabled from command line
_mon_bin
1 when monitor filters binary characters
_monparms
command line arguments for 'listen' program
_maxchn
maximal number of channels
_last_act
time of last user activity (same format as the time() system call).

These variables may be read using the lp_get_var() function defined above. Furthermore there are two special functions defined for reading these variables. These functions expect the name of the system variable without the leading underscore.

char *lp_sconfig(const char *name)
Returns the value of the configuration variable as a string.
int lp_iconfig(const char *name)
Returns the value of the configuration variable as an integer.

The following system variables are defined for each channel:

_call
callsign for each channel
_cwit
connected with callsign
_cphy
physical connection to
_port
connected on which port
_state
connection status

There are also special functions for reading values of these variables:

int lp_chn_status(int chn)
Returns the status of a channel. The following status constants are defined:
ST_DISC
channel disconnected
ST_DISP
disconnect in progress
ST_TIME
disconnecting for timeout
ST_CONN
channel connected
ST_CONP
connecting in progress
char *lp_chn_call(int chn)
Returns channel callsign.
char *lp_chn_cwit(int chn)
Returns the callsign of connected station.
char *lp_chn_cphy(int chn)
Returns the callsign of physicaly connected station (the first connected station).
int lp_chn_port(int chn)
Returns the number of the port used for connection.

The last two functions enable changing the time of last users's response:

time_t lp_last_activity()
Returns the time of last activity of the user.
void lp_set_last_activity(time_t timeval)
Sets the last activity time.

6.5 Connection status

There are two special events reserved for obtaining the AX.25 connection status. When an application wants to get the status of the connection on a certain LinPac channel, it generates the EV_STAT_REQ event on this channel. In response, LinPac generates the EV_STATUS event. The data field of this event points to the ax25_status structure (see Chapter 7.2). When there is no active connection on the channel, no EV_STATUS event is generated.

6.6 Event usage examples

The following examples show how to use events for controlling LinPac. The complete list of events can be found in the file events.txt.

6.6.1 Connecting to a remote station

When initiating the connection, the first step is to check that the channel is free (i.e. it is not in use for another connection). The status of a channel can be checked using the lp_chn_status() function (see Chapter 6.4).

The second step is emiting the EV_CONN_LOC event on the appropriate channel. The data field of the event contains a C string with the destination address in the form port:callsign [digi [digi ...]].

The last step is to wait until the connection is established. For this the function lp_wait_connect() can be used. An example piece of code follows:


int chn = lp_channel(); if (lp_chn_status(chn) == ST_DISC) { char addr[30]; strcpy(addr, "kiss:OK0PAB OK0NMA"); lp_emit_event(chn, EV_CONN_LOC, 0, addr); lp_wait_connect(chn, "OK0PAB"); /* ... connection established ... */ }

6.6.2 Using LinPac commands in programs

Any application may run LinPac commands by emitting the EV_DO_COMMAND event. For example, to download a message from a BBS using the getmsg command following code can be used:

char cmd[30]; sprintf(cmd, "getmsg %i", message_number); lp_emit_event(lp_channel(), EV_DO_COMMAND, 0, cmd);

Another option is to use the EV_WANT_RESULT event. The usage is similar to the previous example, but the x field of the event has special meaning: as a response to this event, LinPac will generate an EV_CMD_RESULT event with the same x field and with the data field containing the result of the command.

An example follows:


char cmd[30]; int id = 0; Event *ev; sprintf(cmd, "getmsg %i", message_number); lp_emit_event(lp_channel(), EV_WANT_RESULT, 1234, cmd); while (id != 1234) /* wait for the command result */ { lp_wait_event(lp_channel(), EV_CMD_RESULT); ev = lp_awaited_event(); id = ev->x; } printf("The result is: %s\n", (char *)ev.data);

7 The application library interface

7.1 Constants

LPAPP_VERSION
the version of LinPac that the library came with
ST_xxxx
connection status constants (see Chapter 6.4)

7.2 Data structures

struct ax25_status
contains the AX.25 connection status:

typedef struct
{
    char devname[8];
    int state;
    int vs, vr, va;
    int t1, t2, t3, t1max, t2max, t3max;
    int idle, idlemax;
    int n2, n2max;
    int rtt;
    int window;
    int paclen;
    bool dama;
    int sendq, recvq;
} ax25_status;

7.3 Functions

7.3.1 Uninterruptable versions of some system calls

The following functions work the same way as the original system calls, but they are interrupt-safe. That is, they don't fail with errno == EAGAIN.

size_t safe_read(int fd, void *buf, size_t count);
size_t safe_write(int fd, const void *buf, size_t count);
char *safe_fgets(char *s, int size, FILE *stream);
int safe_fgetc(FILE *stream);

7.3.2 Basic communication functions

int lp_start_appl()
Starts communication with LinPac. A non-zero return value means success; a zero value means that LinPac cannot be contacted (probably because it's not running).
int lp_get_event(Event *ev)
Read an event from the queue. A non-zero return value means a successful read; a zero value means that the event queue is empty. The data field of the event structure must be initialized before using this function (to NULL or to some buffer). This function should not be used when automatic event processing is used.
int lp_emit_event(int chn, int type, int x, void *data)
Generate a new event. The arguments correspond to the fields in the event structure. The return value is always 0.
void lp_wait_event(int chn, int type)
Wait until an event with the same chn and type values are received.
void lp_wait_init(int chn, int type)
The same as lp_wait_event() but returns immediately. Waiting is provided by following function lp_wait_realize().
void lp_wait_realize()
Realizes waiting initialized by lp_wait_init(). All the events that arrived since the last lp_wait_init() call are ignored. lp_wait_realize() may exit immediately if the event has already arrived.
Event *lp_awaited_event()
After return from a call to lp_wait_event() or lp_wait_realize(), this function returns the event that stopped the waiting.
Event *lp_copy_event(Event *dest, const Event *src)
Copy the event structure (using a deep copy).
void lp_discard_event(Event *ev)
Free the memory used by the data field of Event structure received using lp_get_event().
void lp_clear_event_queue()
Remove all events from the event queue. This has no purpose when automatic event processing is enabled.
void lp_end_appl()
Closes the connection to LinPac.

7.3.3 Automatic event handling functions

void lp_event_handling_on()
Enables automatic event handling. From this point onwards, each event is automatically read from the queue, treated with an event handler function (if defined) and then discarded.
void lp_event_handling_off()
Disables automatic event handling. Events must be read from the queue using the lp_get_event() function.
void lp_set_event_handler(handler_type handler)
Defines the event handler function, a function with signature void my_event_handler(Event *ev). The event handler is called automatically each time an event is received, when automatic event handling is enabled.

7.3.4 Environment functions

LinPac has its own environment for storing variables. Each application can share and modify this environment using environment-related functions. Each channel has its own environment. See Chapter 6.4 for a detailed description and list of functions.

7.3.5 User functions

void lp_appl_result(const char *fmt, ...)
Set the final result of the application. This function generates an EV_APP_RESULT event with the specified message string. The argument format is the same as for printf().
void lp_statline(const char *fmt, ...)
Displays or changes the additional status line in the LinPac user interface. Only one additional status line is displayed. This function generates a EV_CHANGE_STLINE event with the x field (line ID) containing the PID of the application. To display more than one status line for the application, additional EV_CHANGE_STLINE events must be generated manually.
void lp_remove_statline()
Removes the additional status line.
void lp_disable_screen()
Disables displaying data in the QSO window on application's channel. The EV_DISABLE_SCREEN event is used to accomplish this.
void lp_enable_screen()
Enables displaying data in the QSO window. The EV_ENABLE_SCREEN event is used to accomplish this.
void lp_wait_connect(int chn, const char *call)
Waits for a connection with the specified callsign on the specified channel.

7.3.6 Tool functions

char *time_stamp(int utc)
Returns a pointer to a C string that contains the actual time. If utc is 0, then local time is used; otherwise UTC time is used.
char *date_stamp(int utc)
Returns the date-string.
void replace_macros(int chn, char *s)
Replaces macro variables in the string (i.e. %xxx) with their values. The %(command) macro is not replaced.
void get_port_name(int n)
Returns the name of the nth port in axports (starting from 0).

7.3.7 Application information functions

char *lp_version()
Returns the current LinPac version.
int lp_channel()
Returns the channel number on which the application was started. Returns 0 when the application was not started using LinPac.
int lp_app_remote()
Returns a non-zero value if the application was started using a remote command in LinPac (i.e. the application is communicating with a remote user).

8 The shell interface

In addition to the C API described in the above chapters, LinPac also provides a set of functions that allow programmers to create new LinPac commands using bash shell scripts. While this set of functions is limited, it is sufficient to enable quite sophisticated and complex commands to be added to LinPac without requiring programming in C or C++.

8.1 Writing the script

The shell functions are all accessed through the lpapi command, which has the following form:

lpapi <channel> [command] [arguments]

The specifics of the available commands are described in the following sections.

The channel on which the script application is running is made available to the script as the $LPCHN shell environment variable. The use of this variable is demonstrated below.

8.1.1 Ensuring that LinPac is running

The first step in any LinPac shell command should be to ensure that LinPac is running, such that subsequent use of the shell interface can proceed. This is accomplished by calling the API as follows:

lpapi 0

This command will exit with a 0 result code if LinPac is running. Any other result code indicates that LinPac is not running, in which case the script should most likely echo an error message to the user and exit. As usual, the result code can be determined by examining the special $? value.

8.1.2 Accessing configuration and state

It is important that a shell script be able to determine the current status of LinPac and retrieve configuration values. The API provides several functions to enable this.

All of these functions return values that can be assigned to a shell variable, and are used in the following manner (using "call" as an example here):

MYVAR=`lpapi $LPCHN call`

The available functions are as follows:

call
Return the callsign for the specified channel.
cwit
Return the callsign of the station connected on the specified channel.
port
Return the port of the station connected on the specified channel.
state
Return current status of the specified channel (as a number).
pname <number>
Return the name of port with the specified number.
get <variable>
Return the value of specified variable on the specified channel.

8.1.3 Executing commands

Accomplishing real work with the shell interface will usually require calling into LinPac to execute other LinPac commands. This is achieved using the do command, which is functionally equivalent to generating the EV_DO_COMMAND event from the C API.

The do command has the following form:

lpapi <channel> do <command> [arguments]

However, since do is a reserved word in Bash shell scripts, it is necessary to use Bash's eval command to invoke it as a LinPac function, as follows:

eval lpapi <channel> do "<command> [arguments]"

IMPORTANT: The do command is asynchronous. That is, the shell command may return before the command issued to LinPac has completed. A script will need to account for this in considering subsequent actions.

8.1.4 Simple shell example

TBD

8.2 Creating the command

The steps to add the script to LinPac as a new command are essentially the same as for an application written in C, described in Chapter 5.1 above. That is:
  1. Copy the script to the $LINPACDIR/bin directory, making sure that the permissions allow execution.
  2. Add the new command to the file $LINPACDIR/bin/commands as described in the User Manual.

Last update: 16 Feb 2020

linpac-0.28/doc/Makefile.in0000664000076400007640000004475614006074450012476 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = doc DIST_COMMON = $(dist_doc_DATA) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(docdir)" DATA = $(dist_doc_DATA) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LINPACLINK = @LINPACLINK@ LIPO = @LIPO@ LISTEN = @LISTEN@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = czech charsets dist_doc_DATA = manual.txt manual.html applguide.txt applguide.html events.txt \ objects.txt ioctl.txt all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu doc/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-dist_docDATA: $(dist_doc_DATA) @$(NORMAL_INSTALL) test -z "$(docdir)" || $(MKDIR_P) "$(DESTDIR)$(docdir)" @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(docdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(docdir)" || exit $$?; \ done uninstall-dist_docDATA: @$(NORMAL_UNINSTALL) @list='$(dist_doc_DATA)'; test -n "$(docdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(docdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(docdir)" && rm -f $$files # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(docdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dist_docDATA install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-dist_docDATA .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dist_docDATA install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-dist_docDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: linpac-0.28/doc/applguide.txt0000664000076400007640000010726614006074433013141 00000000000000 LinPac - Packet Radio Terminal for Linux -------------------------------------------------------------------------- Version 0.28 (c) Martin Cooper KD6YAM 2020 (c) David Ranch KI6ZHD (linpac@trinnet.net) 2002 - 2020 (c) 1998 - 2001 by Radek Burget OK2JBG External Application Programming Guide Contents 1 Introduction 2 What is an external program? 3 Basic concepts of the API 4 How applications communicate with LinPac 5 Using the application library 5.1 The simplest application 6 Application programming 6.1 Events 6.2 Sending and receiving events 6.3 Synchronization 6.4 Shared variables and configuration 6.5 Connection status 6.6 Event usage examples 6.6.1 Connecting to a remote station 6.6.2 Using LinPac commands in programs 7 The application library interface 7.1 Constants 7.2 Data structures 7.3 Functions 7.3.1 Uninterruptable versions of some system calls 7.3.2 Basic communication functions 7.3.3 Automatic event handling functions 7.3.4 Environment functions 7.3.5 User functions 7.3.6 Tool functions 7.3.7 Application information functions 8 The shell interface 8.1 Writing the script 8.1.1 Ensuring that LinPac is running 8.1.2 Accessing configuration and state 8.1.3 Executing commands 8.1.4 Simple shell example 8.2 Creating the command 1 Introduction This guide is written for programmers who want to add some new functions to LinPac. In the following text, basic knowledge of Linux programming is assumed. Reading the LinPac User Manual before proceeding is also recommended. 2 What is an external program? An external program is a standard Linux application which uses LinPac to communicate with remote stations. There are basically two types of LinPac external programs: * Standard Linux applications that use standard input and output streams. These programs can be used without LinPac too. LinPac allows redirection of the input stream (stdin) of the application and any of the output streams (stdout, stderr) or both of them. LinPac can also provide CR/LF conversions in these streams. These parameters are set when adding the external program to LinPac - see Section 7, "Creating new commands", in the User Manual. * Applications written using LinPac's application interface. These applications can share some information with LinPac, and they can control almost all functions of LinPac. No special knowledge of LinPac is needed for creating the first type of programs, because no LinPac functions are used. The remainder of this guide is dedicated to the second type of applications. 3 Basic concepts of the API The LinPac application interface is based on events. Every action in LinPac, such as pressing a key, receiving data, executing a command, etc., is represented by a data structure called an event, which describes exactly what happened. LinPac's internal structure consists of separate objects which communicate with each other using these events. Each object provides its own functionality, and often generates events. For example, the object Keyscan produces an event each time any key is pressed. All the events generated by any object are put into the common event queue. The LinPac kernel simply takes the events from the queue one by one and sends them to all the objects (including the one that generated the event). Thus each event generated by any part of LinPac is forwarded to all of the objects. The reaction of each object fully depends on its functionality, but of course it can include generation of other events. The list of LinPac internal objects and their names can be found in the file objects.txt. An additional feature of the API is a shared variable environment. This is a set of variables that is shared with LinPac; the values are automatically synchronized with all the external programs. These variables are accessed using special functions of the API as described below. 4 How applications communicate with LinPac LinPac uses TCP/IP sockets for communication with external programs (applications). The connection is always initiated by the application after it starts. There are basically two ways that an application may be started: * The application is started by LinPac, through being associated with a LinPac command. In this case LinPac registers the channel on which the application was started and expects the connection attempt from the application. After the application initializes and contacts LinPac, it is provided with the working channel and whether it was started by a remote or local user. LinPac may also redirect the input and output streams of the application (depending upon LinPac settings). * The application is started without using LinPac. In this case LinPac assumes that the application runs on channel 0 and was started by the local user. The input and output streams of the application are not redirected. In both cases, the start of an application causes the creation of a new object in LinPac called an event gate. This object represents the application within LinPac. Bearing in mind the previous chapter, this means that the application is forwarded all of the events generated by any LinPac object, and all of the events generated by the application are forwarded to all LinPac objects. NOTE: All of the communication via TCP/IP sockets is provided by the LinPac application library. The user application should not attempt to access the sockets directly. 5 Using the application library During LinPac installation, the application library liblinpac is created and installed by default to /usr/local/lib. The interface to this library is contained in the file lpapp.h, which is installed by default to /usr/local/include/linpac. The next chapter illustrates how to use the library within a user application. 5.1 The simplest application The following application example just tries to contact LinPac, and prints the result. -------------------------------------------------------------------------- #include #include #include int main() { if (lp_start_appl()) { printf("Application started\n"); sleep(10); printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; } -------------------------------------------------------------------------- The function lp_start_appl() tries to contact LinPac and returns 1 in case of success or 0 when a connection to LinPac cannot be made (probably because it's not running). This function should precede the usage of any other application library functions. The function lp_end_appl() closes the connection to LinPac. To compile this example, use: $ gcc -o test1 test1.c -llinpac This example just detects if LinPac is running, and it can be executed directly from the shell. When running from the shell, no streams are redirected to LinPac, and the application appears to run on channel 0 of LinPac. This is useful for some applications that are used to control LinPac from outside. However this is not a typical use case. For most applications, it is better to copy the executable to the $LINPACDIR/bin directory and then add it to the file $LINPACDIR/bin/commands as described in the User Manual. After this, the application can be executed as a LinPac command. In this scenario, the streams are properly redirected and the application output is visible in the LinPac QSO window. It is also possible to select the channel on which to run the application. NOTE: The LinPac application library (liblinpac) can be linked without problems with both C and C++ code. 6 Application programming 6.1 Events LinPac is completely driven by events. Each part of LinPac, including applications, can generate events to inform other parts (internal modules or applications) that something has happened. Each event is sent to all LinPac components and applications. For example when some station connects to some LinPac channel, the internal AX.25 interface generates an event reporting that the station has connected and includes its callsign. All components and applications now know who has connected, and they can take some actions. For example, the output window prints information about the connection, the macro processor executes the cinit.mac macro, and so on. Each application can handle all of the events too, and can generate events which are handled by other components. An event is represented by the following structure: struct Event { int type; int chn; int x,y; char ch; void *data; }; The meaning of each field is as follows: type Specifies the type of the event. Actually it determines what happened. There is a symbolic constant defined for each known event type. chn Specifies the channel to which the event applies. For example, if the type of the event specifies that some data was received, the chn field contains the number of the channel which has received that data. There are many events that apply for all the channels. For those events, this field is not significant. x, y The meaning of these fields depends on the event type. The y field is usually not used, other than by some internal events. ch This field is used only by some internal events. data Depends on the type of the event. It usually points to some string data or a char buffer. All of the event types are described in the event list. 6.2 Sending and receiving events For sending events the following function is used: int lp_emit_event(int chn, int type, int x, void *data); This generates a new event using the specified values. Each argument corresponds to one of the fields in the Event structure. There are two modes for handling incoming events: a) Reading each event on demand This mode is started by the lp_event_handling_off() call. In this mode, events are read explicitly using the function: int get_event(Event *ev); This function returns 0 when no event is available. When an event is available, it returns 1 and fills the Event structure with the received event data. WARNING #1: The data field in your Event structure must point to a dynamically allocated buffer. The size of the buffer is reallocated automatically after receiving an event. When the data field is set to NULL, a new buffer is allocated. This field must be initialized. WARNING #2: In this mode, the application must read all events. It is not a good idea to stop reading events, because the event queue may overflow. LinPac will automatically kill the application when the event queue exceeds some reasonable number of events. b) Automatic event processing This mode is started by the lp_event_handling_on() call. All events are read automatically. Programmers can define their own function that will be called automatically when an event occurs. When no such function is defined, all events are discarded. The event handling function must have following prototype: void my_event_handler(Event *ev); (The function name may be different.) After initializing the application, the event handling function must be registered using the function: lp_set_event_handler() from the application library. The following example is an application that prints the types of all events received and stops when an EV_ABORT event is received. This event can be generated using the :ABort command in LinPac. -------------------------------------------------------------------------- #include #include int aborted = 0; //User event handling function. This function is called each time //an event occurs void my_event_handler(Event *ev) { printf("The event of type %i has been received\n", ev->type); if (ev->type == EV_ABORT) aborted = 1; } int main() { if (lp_start_appl()) { lp_event_handling_on(); //turn on automatic event handling lp_set_event_handler(my_event_handler); //define own event handler printf("Application started\n"); printf("Stop with the ':Abort' command\n"); do ; while(!aborted); //wait until application is aborted printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; } -------------------------------------------------------------------------- This example contains "active waiting" (the do ; while(...) construction). This is very ugly and inefficient. For this reason, the LinPac API offers an alternative for waiting for events, namely the lp_wait_event() function. Let's change the example to use this function: -------------------------------------------------------------------------- #include #include int main() { if (lp_start_appl()) { lp_event_handling_on(); //turn on automatic event handling printf("Application started\n"); printf("Stop with the ':Abort' command\n"); lp_wait_event(lp_channel(), EV_ABORT); //wait for the abort event printf("Application finished\n"); lp_end_appl(); } else { printf("LinPac is not running\n"); return 1; } return 0; } -------------------------------------------------------------------------- WARNING: Note that some system calls may be interrupted when an event is received. An interrupted system call returns an error result (for example the read() call returns -1), sets errno to EAGAIN, and must be called again. To avoid this, use the interrupt-safe versions of the system calls contained in this application library. (See Chapter 7.3.1.) 6.3 Synchronization An event generated by an application is sent to all modules and applications, including the application that generated the event. When there is a need to wait until the event is accepted by LinPac, the simplest way is to wait until the event we have sent is received back. For testing that all events were processed, there is an EV_VOID event. It is not handled by any module. After sending all events, just generate an EV_VOID event and wait until it returns. After that, you can be assured that all previous events have been processed. 6.4 Shared variables and configuration Each shared variable is denoted by its name (string) and channel number. Each variable has a value represented by a string (char[]). Access to these variables is provided by following functions: void lp_set_var(int chn, const char *name, const char *value) Changes the value of the variable. If the variable doesn't exist, it is created. char *lp_get_var(int chn, const char *name) Reads the value of the variable. Returns NULL if the variable doesn't exist. void lp_del_var(int chn, const char *name) Deletes the variable. void lp_clear_var_names(int chn, const char *prefix) Deletes all variables with the specified name. The value of each variable is automatically synchronized with LinPac and all running applications. The variables whose names start with "_" are reserved for system use. These variables can be used for obtaining system configuration and status but it may be potentialy dangerous to change some of these variables. NOTE: Many of the variables contain boolean values. Their value is 1 when true, 0 otherwise. Currently the following system variables are defined (in channel 0): _remote 1 when remote commands are enabled _cbell 1 when connect sound is enabled _knax 1 when sound signal for each frame is enabled _def_port default port name _unportname port name for unproto frames _unport port number for unproto frames _info_level status-line level (0 to 2) _no_name default station name _timezone local timezone name _swap_edit 1 when swapedit is on _fixpath 1 when fixpath is on _daemon 1 when linpac works as a daemon _monitor 1 when monitor is enabled _no_monitor 1 when monitor is disabled from command line _listen 1 when accepting connections is enabled _disable_spyd 1 when ax25spyd support is disabled from command line _mon_bin 1 when monitor filters binary characters _monparms command line arguments for 'listen' program _maxchn maximal number of channels _last_act time of last user activity (same format as the time() system call). These variables may be read using the lp_get_var() function defined above. Furthermore there are two special functions defined for reading these variables. These functions expect the name of the system variable without the leading underscore. char *lp_sconfig(const char *name) Returns the value of the configuration variable as a string. int lp_iconfig(const char *name) Returns the value of the configuration variable as an integer. The following system variables are defined for each channel: _call callsign for each channel _cwit connected with callsign _cphy physical connection to _port connected on which port _state connection status There are also special functions for reading values of these variables: int lp_chn_status(int chn) Returns the status of a channel. The following status constants are defined: ST_DISC channel disconnected ST_DISP disconnect in progress ST_TIME disconnecting for timeout ST_CONN channel connected ST_CONP connecting in progress char *lp_chn_call(int chn) Returns channel callsign. char *lp_chn_cwit(int chn) Returns the callsign of connected station. char *lp_chn_cphy(int chn) Returns the callsign of physicaly connected station (the first connected station). int lp_chn_port(int chn) Returns the number of the port used for connection. The last two functions enable changing the time of last users's response: time_t lp_last_activity() Returns the time of last activity of the user. void lp_set_last_activity(time_t timeval) Sets the last activity time. 6.5 Connection status There are two special events reserved for obtaining the AX.25 connection status. When an application wants to get the status of the connection on a certain LinPac channel, it generates the EV_STAT_REQ event on this channel. In response, LinPac generates the EV_STATUS event. The data field of this event points to the ax25_status structure (see Chapter 7.2). When there is no active connection on the channel, no EV_STATUS event is generated. 6.6 Event usage examples The following examples show how to use events for controlling LinPac. The complete list of events can be found in the file events.txt. 6.6.1 Connecting to a remote station When initiating the connection, the first step is to check that the channel is free (i.e. it is not in use for another connection). The status of a channel can be checked using the lp_chn_status() function (see Chapter 6.4). The second step is emiting the EV_CONN_LOC event on the appropriate channel. The data field of the event contains a C string with the destination address in the form port:callsign [digi [digi ...]]. The last step is to wait until the connection is established. For this the function lp_wait_connect() can be used. An example piece of code follows: -------------------------------------------------------------------------- int chn = lp_channel(); if (lp_chn_status(chn) == ST_DISC) { char addr[30]; strcpy(addr, "kiss:OK0PAB OK0NMA"); lp_emit_event(chn, EV_CONN_LOC, 0, addr); lp_wait_connect(chn, "OK0PAB"); /* ... connection established ... */ } -------------------------------------------------------------------------- 6.6.2 Using LinPac commands in programs Any application may run LinPac commands by emitting the EV_DO_COMMAND event. For example, to download a message from a BBS using the getmsg command following code can be used: -------------------------------------------------------------------------- char cmd[30]; sprintf(cmd, "getmsg %i", message_number); lp_emit_event(lp_channel(), EV_DO_COMMAND, 0, cmd); -------------------------------------------------------------------------- Another option is to use the EV_WANT_RESULT event. The usage is similar to the previous example, but the x field of the event has special meaning: as a response to this event, LinPac will generate an EV_CMD_RESULT event with the same x field and with the data field containing the result of the command. An example follows: -------------------------------------------------------------------------- char cmd[30]; int id = 0; Event *ev; sprintf(cmd, "getmsg %i", message_number); lp_emit_event(lp_channel(), EV_WANT_RESULT, 1234, cmd); while (id != 1234) /* wait for the command result */ { lp_wait_event(lp_channel(), EV_CMD_RESULT); ev = lp_awaited_event(); id = ev->x; } printf("The result is: %s\n", (char *)ev.data); -------------------------------------------------------------------------- 7 The application library interface 7.1 Constants LPAPP_VERSION the version of LinPac that the library came with ST_xxxx connection status constants (see Chapter 6.4) 7.2 Data structures struct ax25_status contains the AX.25 connection status: typedef struct { char devname[8]; int state; int vs, vr, va; int t1, t2, t3, t1max, t2max, t3max; int idle, idlemax; int n2, n2max; int rtt; int window; int paclen; bool dama; int sendq, recvq; } ax25_status; 7.3 Functions 7.3.1 Uninterruptable versions of some system calls The following functions work the same way as the original system calls, but they are interrupt-safe. That is, they don't fail with errno == EAGAIN. size_t safe_read(int fd, void *buf, size_t count); size_t safe_write(int fd, const void *buf, size_t count); char *safe_fgets(char *s, int size, FILE *stream); int safe_fgetc(FILE *stream); 7.3.2 Basic communication functions int lp_start_appl() Starts communication with LinPac. A non-zero return value means success; a zero value means that LinPac cannot be contacted (probably because it's not running). int lp_get_event(Event *ev) Read an event from the queue. A non-zero return value means a successful read; a zero value means that the event queue is empty. The data field of the event structure must be initialized before using this function (to NULL or to some buffer). This function should not be used when automatic event processing is used. int lp_emit_event(int chn, int type, int x, void *data) Generate a new event. The arguments correspond to the fields in the event structure. The return value is always 0. void lp_wait_event(int chn, int type) Wait until an event with the same chn and type values are received. void lp_wait_init(int chn, int type) The same as lp_wait_event() but returns immediately. Waiting is provided by following function lp_wait_realize(). void lp_wait_realize() Realizes waiting initialized by lp_wait_init(). All the events that arrived since the last lp_wait_init() call are ignored. lp_wait_realize() may exit immediately if the event has already arrived. Event *lp_awaited_event() After return from a call to lp_wait_event() or lp_wait_realize(), this function returns the event that stopped the waiting. Event *lp_copy_event(Event *dest, const Event *src) Copy the event structure (using a deep copy). void lp_discard_event(Event *ev) Free the memory used by the data field of Event structure received using lp_get_event(). void lp_clear_event_queue() Remove all events from the event queue. This has no purpose when automatic event processing is enabled. void lp_end_appl() Closes the connection to LinPac. 7.3.3 Automatic event handling functions void lp_event_handling_on() Enables automatic event handling. From this point onwards, each event is automatically read from the queue, treated with an event handler function (if defined) and then discarded. void lp_event_handling_off() Disables automatic event handling. Events must be read from the queue using the lp_get_event() function. void lp_set_event_handler(handler_type handler) Defines the event handler function, a function with signature void my_event_handler(Event *ev). The event handler is called automatically each time an event is received, when automatic event handling is enabled. 7.3.4 Environment functions LinPac has its own environment for storing variables. Each application can share and modify this environment using environment-related functions. Each channel has its own environment. See Chapter 6.4 for a detailed description and list of functions. 7.3.5 User functions void lp_appl_result(const char *fmt, ...) Set the final result of the application. This function generates an EV_APP_RESULT event with the specified message string. The argument format is the same as for printf(). void lp_statline(const char *fmt, ...) Displays or changes the additional status line in the LinPac user interface. Only one additional status line is displayed. This function generates a EV_CHANGE_STLINE event with the x field (line ID) containing the PID of the application. To display more than one status line for the application, additional EV_CHANGE_STLINE events must be generated manually. void lp_remove_statline() Removes the additional status line. void lp_disable_screen() Disables displaying data in the QSO window on application's channel. The EV_DISABLE_SCREEN event is used to accomplish this. void lp_enable_screen() Enables displaying data in the QSO window. The EV_ENABLE_SCREEN event is used to accomplish this. void lp_wait_connect(int chn, const char *call) Waits for a connection with the specified callsign on the specified channel. 7.3.6 Tool functions char *time_stamp(int utc) Returns a pointer to a C string that contains the actual time. If utc is 0, then local time is used; otherwise UTC time is used. char *date_stamp(int utc) Returns the date-string. void replace_macros(int chn, char *s) Replaces macro variables in the string (i.e. %xxx) with their values. The %(command) macro is not replaced. void get_port_name(int n) Returns the name of the nth port in axports (starting from 0). 7.3.7 Application information functions char *lp_version() Returns the current LinPac version. int lp_channel() Returns the channel number on which the application was started. Returns 0 when the application was not started using LinPac. int lp_app_remote() Returns a non-zero value if the application was started using a remote command in LinPac (i.e. the application is communicating with a remote user). 8 The shell interface In addition to the C API described in the above chapters, LinPac also provides a set of functions that allow programmers to create new LinPac commands using bash shell scripts. While this set of functions is limited, it is sufficient to enable quite sophisticated and complex commands to be added to LinPac without requiring programming in C or C++. 8.1 Writing the script The shell functions are all accessed through the lpapi command, which has the following form: lpapi [command] [arguments] The specifics of the available commands are described in the following sections. The channel on which the script application is running is made available to the script as the $LPCHN shell environment variable. The use of this variable is demonstrated below. 8.1.1 Ensuring that LinPac is running The first step in any LinPac shell command should be to ensure that LinPac is running, such that subsequent use of the shell interface can proceed. This is accomplished by calling the API as follows: lpapi 0 This command will exit with a 0 result code if LinPac is running. Any other result code indicates that LinPac is not running, in which case the script should most likely echo an error message to the user and exit. As usual, the result code can be determined by examining the special $? value. 8.1.2 Accessing configuration and state It is important that a shell script be able to determine the current status of LinPac and retrieve configuration values. The API provides several functions to enable this. All of these functions return values that can be assigned to a shell variable, and are used in the following manner (using "call" as an example here): MYVAR=`lpapi $LPCHN call` The available functions are as follows: call Return the callsign for the specified channel. cwit Return the callsign of the station connected on the specified channel. port Return the port of the station connected on the specified channel. state Return current status of the specified channel (as a number). pname Return the name of port with the specified number. get Return the value of specified variable on the specified channel. 8.1.3 Executing commands Accomplishing real work with the shell interface will usually require calling into LinPac to execute other LinPac commands. This is achieved using the do command, which is functionally equivalent to generating the EV_DO_COMMAND event from the C API. The do command has the following form: lpapi do [arguments] However, since do is a reserved word in Bash shell scripts, it is necessary to use Bash's eval command to invoke it as a LinPac function, as follows: eval lpapi do " [arguments]" IMPORTANT: The do command is asynchronous. That is, the shell command may return before the command issued to LinPac has completed. A script will need to account for this in considering subsequent actions. 8.1.4 Simple shell example TBD 8.2 Creating the command The steps to add the script to LinPac as a new command are essentially the same as for an application written in C, described in Chapter 5.1 above. That is:  1. Copy the script to the $LINPACDIR/bin directory, making sure that the permissions allow execution.  2. Add the new command to the file $LINPACDIR/bin/commands as described in the User Manual. -------------------------------------------------------------------------- Last update: 16 Feb 2020 References Visible links . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS3 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS5 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS5_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_3 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_5 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_6 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_6_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_6_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_3 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_5 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_6 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_7 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_1_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_1_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_1_3 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_1_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS8_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/manual.html#POS7 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/objects.txt . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/manual.html . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/events.txt . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_3_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS7_2 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/events.txt . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS6_4 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/applguide.html#POS5_1 . file:///home/archive/Linpac/BitBucket-Git/linpac/doc/manual.html linpac-0.28/doc/manual.txt0000664000076400007640000016432714006074433012445 00000000000000 LinPac - Packet Radio Terminal for Linux -------------------------------------------------------------------------- Version 0.28 (c) 2020 - 1998 by David Ranch KI6ZHD User manual Index 1 [1]What is LinPac 2 [2]First configuration 3 [3]LinPac controls 3.1 [4]Keyboard 3.2 [5]Entering commands 3.3 [6]Initiating a connection 3.4 [7]Receiving and sending files 3.5 [8]Remote commands 3.6 [9]Character encoding 3.7 [10]Huffman compression 4 [11]Variables 4.1 [12]Special variables 5 [13]Station database 5.1 [14]The station.data file format 5.2 [15]The 'Name' command 5.3 [16]Using the database 6 [17]About macros 6.1 [18]Creating macros 6.2 [19]Commands used in macros 6.3 [20]Special system macros 7 [21]Creating new commands 8 [22]Standard applications 8.1 [23]File transfer protocols 8.2 [24]Automatic password generation 8.2.1 [25]Login passwords 8.2.2 [26]Sysop and general use passwords 8.3 [27]Utilities for mail exchange 8.4 [28]Mail client 8.5 [29]Logbook 9 [30]Command line options 10 [31]Copying Appendix A: [32]List of LinPac commands Appendix B: [33]Linpac FAQ / Questions and Answers / Getting more help Appendix C: [34]Errata -------------------------------------------------------------------------- 1 What is LinPac LinPac is a packet radio terminal for Linux that allows wide configurability and easy addition of new functions and special functions needed by the user. The aim is to minimize the amount of 'hard coded' functions and create a complete set of applications that can be easy expanded and/or completely reconfigured. All functions described in this manual match the standard configuration that comes with the distribution package. 2 First configuration When linpac is started for the first time on your computer, it automaticaly creates the directory called LinPac in the running user's home directory. This directory will contain the user's personal LinPac configuration settings. After creating this directory, LinPac asks for basic callsign, port and other information and prepares a useable configuration for you. An example setup dialog is as shown, where we are using the bogus call "n0call" logging into the local home BBS "n0ary-1": $ linpac Hello dear user. You seem to run LinPac for the first time. LinPac has to create a directory in your home directory for storing your personal configuration. For creating your personal configuration please answer following questions: Your callsign: n0call Enter your home BBS callsign with SSID : n0ary-1 Enter the name of port to connect N0ARY-1 d710 Enter the digipeaters used to connect N0ARY-1 or press enter when no digipeaters are used: Enter the full hierarchical address of N0ARY-1 (e.g. #MOR.CZE.EU) #NCA.CA.USA.NOAM Thank you, N0CALL Please wait a moment for creating your personal configuration Installation done. Press ENTER to run LinPac The above information is then stored in the $HOME/LinPac/macro/init.mac file as various 'functions'. These functions are based on the very simple interpreted language (actually it's not a language but something like the batch files in DOS). In the LinPac/macro directory are all the scripts written in this language. The init.mac macro is loaded at start of loading Linpac and contains the commands to setup the callsigns and other settings. You can modify this file to change the initial configuration of LinPac. Other macros can be run in LinPac as desired or required. The simplest case of a macro is a normal text file that is just printed to the screen (or sent to the remote peer) when executed. The language is described in [35]chapter 6. You may also want to review or change following macro files: * info.mac - contains information about your system * ctext.mac - executed when the peer connects and should contain the greeting text * quit.mac - called when user enters the Quit command (end of connection) and should print some farewell text and disconnect After this you should be able to make your first connection. 3 LinPac controls After automatically running the LinPac setup routine, the main screen should appear. If you see a segmentation fault, please see [36]Linux AX.25 issues with long predictable network interface names for a work around. Moving on, in Linpac's main interface in the standard configuraion, the screen is divided into five parts (described from the top of the screen to the bottom): * QSO window: this window contains the text that came from the peer and also the sent text and some special messages (different text colours). * Status line: displays your callsign, current time and some information about the current connection. * Editor: allows you to enter the text you want to send to the peer or the commands you want to execute * Channel list: displays the list of channels with the callsign of connected users. The currently selected channel is highlighted. * Monitor : displays the traffic on your radio ports LinPac is mostly driven by commands. The commands are entered using the editor and must start with a colon (':') in the first column. Lines that don't begin with a colon are sent to the peer, if connected. LinPac allows up to eight connections to be made simultaneously. For each connection one channel is used. You can switch between channels by pressing the F1 - F8 keys. Each has its own QSO window, status line and editor. The channel list and the monitor are common across all the channels. There is a special channel invoked by pressing F10. This channel has no QSO window and doesn't allow making a connection. The text written is sent out immediately using UI frames (beacon). 3.1 Keyboard The following list contains the important shortcuts: Global F1 - F8 : switch to channel 1 - 8 F10 : switch to monitor Alt-X : end of LinPac QSO Window PgUp, PgDn, ctrl-R, ctrl-V : scroll one page up / down ctrl-E, ctrl-X : scroll one line up / down ctrl-B : skip to end of buffer Editor Cursor keys, Home, End, Backspace, Del : text editing ctrl-Y : delete current line Enter : send current line Some applications (e.g. mailer) can use the whole screen. Each channel can run only one such application at a time. It's possible to switch to this application using Alt- (e.g. Alt-5) and switch back to terminal using F1 - F10. 3.2 Entering commands Each command is invoked using its name. Some commands can be abbreviated. In this manual the mandatory part is always written in upper case. The remainder of the command name is optional. Some commands require some extra arguments. The arguments are written after the command and are separated by one or more spaces. If you want to enter an argument containing more than one word, that argument must be entered in quotation marks. Examples: :color red blue - calls the 'color' command with two arguments - 'red' and 'blue' :color 'light red' or :color "light red" - calls the 'color' command with one argument 'light red' Most of the commands work on the currently selected channel. If you want to execute the command on some other channel, you can enter the number of the channel this way. For example, to make an OUTGOING connection to destination OK0PAB on Linpac channel 5: :connect@5 OK0PAB In this case the 'connect' command is executed on channel 5. The complete list of commands with descriptions is available in Appendix A. 3.3 Initiating a connection To initiate a connection the :Connect command is used. Just switch to the channel you want to use by pressing F1 - F8 and enter the following command: :connect CALLSIGN Replace the CALLSIGN with the real callsign of the station you want to connect. The command can be abbreviated to the first letter only. Example: :c OK0PAB This command will initiate the connecting sequence to OK0PAB. To close the connection, you can use the :Disconnect command by entering :d When your system has multiple radio ports, you can specify its name before the callsign like this: :c 2:OK0PAB This command will try to connect OK0PAB via port 2. When no port name is specified, the default one is used. Initially the default port is the first port in /etc/axports (your system AX.25 port configuration file). If you want to change the default port, just use the command :port. :port 2 This will change the default port name to '2'. In some cases it is useful to set another default port for some selected channels. For this the variable CHN_PORT can be used (see [37]chapter 4). When set, the content of this variable overrides the default port selection for the particular channel. For example, when you set the variable for channel 4 using :set CHN_PORT@4 1 the port '1' will be used as the default one for the channel 4. For other channels, the previously set default port will be used. 3.4 Receiving and sending files The standard distribution can receive files using plain text or binary transfer and using file transfer protocols YAPP and Autobin. LinPac will automaticaly start to receive the file when the peer begins to send using the YAPP or Autobin protocols. The 7+ files are automaticaly saved too. When you want to save the incoming text you have to use the command :Write The incoming text will be saved until you stop the saving using :Write off For receiving a plain binary file, the corresponding command :WBin can be used. This way of transferring binary files is not recommended; use the autobin or yapp protocol instead. The following commands are available for sending files: :rprg - sends the file using the Autobin protocol :yput - sends the file using the YAPP protocol :rbin - sends the binary file (no protocol - not recommended) :read - semds the text file 3.5 Remote commands LinPac allows the remote user to enter commands. For remote control, all LinPac commands are available but there can be (and should be) some restrictions for each user. The remote command must start with the // sequence. For example if some connected user sends you the text '//info' your terminal will send back the station information. The remote commands can be disabled using the command :remote off and enabled by :remote on. You can also specify that only some commands be available for remote users. The default list of available remote commands is defined in the init.mac file (the DEF_RCMD line). It is also possible to enable various commands for each user. This is described in [38]chapter 5. 3.6 Character encoding Some countries use different national character encodings for some historical reasons. A user who has his Linux console configured for example for some of the standard ISO encodings may be incompatible with another one using a traditional encoding. To solve this LinPac allows the translation of the input and output of each channel using a translation table. The translation tables are stored in files *.ctt in the LinPac home directory. All known encodings must be defined in the file called encodings in the LinPac home directory. This file contains a single line for each encoding that specifies its alias (name which will identify the encoding in LinPac), encoding name (an official name such as iso-8859-1) and optionally the name of the translation table file to be used (without the extension .ctt). Note that LinPac does not support multi-byte encodings such as UTF-8 or other Unicode encodings. The current encoding can be switched using the :TRanslate command separately for each channel. To specify the default encoding for each user you can add the line ENC= to the appropriate record in the station database. (The station database is described in [39]chapter 5.) When no encoding is specified for the user, the default one is used. The default encoding alias is stored in the DEF_ENC@0 variable which is set in the macro init.mac. When the conversion table is not specified in the encodings file LinPac only changes the name of currently used encoding but doesn't provide any conversion. However some applications (such as QLinPac which works in unicode) are able to do their own conversions. 3.7 Huffman compression Some packet radio terminals and BBS software allows the compression of transferred text. When switched on, the sender does the compression of all data before sending them to the other station and the recipient has to decompress the data after receiving them. This makes the communication more reliable and reduces the load of the radio link. The line compression in LinPac is activated using the :comp command. The compression is switched on using :comp on and switched off using :comp off. To ensure that the compression is activated or deactivated on both ends of the link simultaneously LinPac sends the remote command :comp 1 or :comp 0 to the other station automatically. The arguments 1 and 0 have the same effect as on and off, but they don't cause sending any command to the other station. In the case in which the remote system doesn't support the :comp command it's necessary to switch on the compression on the remote system manually and then use the:comp 1 command in LinPac. 4 Variables Each channel has its own set of variables. Some of the variables are used to store the configuration data. The user can create and remove variables and change the values of existing variables using following commands: :set - sets the value of the variable. If the variable doesn't exist, a new one is created. :get - prints the value of the variable :unset - removes the variable Some examples: :set NAME John :set WHOLE_NAME 'John Big' :get NAME :unset NAME The name of the variable can contain the specification of the channel. For example the variable NAME@5 is the variable 'NAME' defined on channel 5. When LinPac finds the character '%' followed by the name of variable, it automatically replaces this text with the value of the variable. Considering the previous example, the text %NAME will be replaced with John. 4.1 Special variables There are some special internal variables that don't allow changing their value. Their value is set and changed directly by LinPac and these variables can be used to add some actual information to the text. The list follows: %V - LinPac version (e.g. 0.26) %C - The callsign of connected station %N - The name of connected station (when known), else replaced by the contents of %U macro %Y- Channel callsign (mycall) %K- Current channel number %T - Current time %D - Current date %B - Audible bell %Z - Current time zone %U - The text used when the name is unknown. This can contain other macros (typicaly %C). %P- The port number %M- The number of connected users %A- The time since the last operator activity %_- End of line (CR) %<- Contents of the last line received, this is cleared by reading %#number - Replaced by a character with an ASCII value (e.g. %#27 means ESC) %(command) - Replaced by the command result. %[expression] - Replaced by the result of mathematical expression Variables for use in macros only: %R - the number of macro arguments (up to 9) %0 - the name of the macro %1 - %9 - macro arguments For example try to write following text in the editor and press enter: The time is %T and the date is %D. 5 Station database The station database holds various information about known stations. All the information is stored in the 'station.data' file and can be changed using the normal text editor or using the LinPac :Name command. 5.1 The station.data file format The information about each station is written in a paragraph starting with the station callsign in square brackets. Each line in the paragraph contains one definition like: = A typical station information paragraph might look like this: [OK0NMA] NAME=PC/FlexNet Brno TYPE=FLEXNET LOC=JN89HE QRG=144.8125 MHz SYSNUM=85946 There are no mandatory items; the user can add various items depending on what information he wants to store. The current LinPac distribution uses following item names for standard information: NAME - Text information about the station, or the operator's name. LinPac shows this information when connected to that station. LOC - QRA locator of the station. Shown after connect too. TYPE - The type of the station. For standard stations the types FLEXNET, THENET, FBB, BAYBOX, DIEBOX, TNOS, JNOS, DXC and TERM for user terminals are recomended, but you can add any other type. LANG - The language to communicate with the station. This is currently supported by macros only. When this item is set, LinPac will try to find the macro in the directory macro//. NICKNAME - The nickname of the operator. The standard LinPac configuration also uses these item names: TERM - What type of terminal is used. If 'ansi' is set, LinPac switches to the ansi-color mode after connecting this station. ENC - The character encoding. Used to automaticaly switch to the i/o character conversion. RCMD - The list of enabled remote commands for this station. QRG - The user frequency. Used by the logbook. SYSNUM and PWD - Sysop password for the station. See chapter [40]8.2 for more information. 5.2 The 'Name' command The :Name command is used to modify the station database. Running the command without arguments results printing the name of currently connected station. Arguments can be used to modify the data: - modify the NAME item -l - modify the LOC item -t - TYPE -L - LANG -n - NICKNAME -s = - modify other item The command 'Name -i' prints all information about the station. When you need to change the information about a station other than the connected station, add the argument -c . Examples: :Name David :Name -c KI6ZHD -l CM97ai David :Name -i 5.3 Using the database After any connection is established, LinPac reads the information about the connected station from the database and creates the set of variables with names STN_ containing the values of the items. These variables can be used in macros as described below. 6 About macros 6.1 Creating macros A macro is a LinPac command that is created using the macro language, and uses other LinPac commands to perform some action. A macro can be defined by creating the file macro/.mac. It's possible to define an abbreviated form of the command; this is described in [41]chapter 7. There are two ways to define a macro: a) Text macros This way is suitable for commands which are intended to produce a larger text output (for example station information). When executing this macro, each line that doesn't start with ':' is printed (sent out). All commands must start with the colon. This is suitable for modifying the text output using the IF ~ ELSE ~ ENDIF commands or for including some other commands. b) Command macros A command macro must start with the line :MACRO Each line of a command macro is interpreted as a command (doesn't start with the colon and doesn't need to start at the begining of line). Text output is provided by the 'echo' command. This way is more synoptical and allows including comments that must start with the sequence ';;' and end at the end of the line. A macro is called with its name. When the first arguments starts with the '@' symbol the macro is executed from the specified label. For example the command :convers @SEND will execute the macro 'convers.mac' from the label 'SEND' (see next chapter to see how to define the label). 6.2 Commands used in macros A macro can contain all LinPac and user defined commands. There are also some special commands that can be used in macros only: MACRO [name] Start of the command script definition (see previous section). LABEL Creates a label with specified name. In the command scripts the notation : can be used. GOTO Jump to specified label. IF ~ ELSE ~ ENDIF Conditional commands. There are two ways to specify a condition: * normal notation (for more than one command)   IF . . (commands to be executed when the condition is true) . . ELSE . . (commands to be executed when the condition is false) . . ENDIF The ELSE part is not necessary - the IF ~ ENDIF notation is possible.   * abbreviated notation (for one conditional command) IF () command The parentheses are necessary in this case. The following example shows how to use conditions and how to use the data from the station database. We want to create a macro that will greet the operator of the connected station with his nickname or with his name, if the nickname is not defined. a) The solution using a text macro (the comments are actually not allowed in the text macros, they are here for explanation only) :if %(exist STN_NICKNAME) == 1 ;; when NICKNAME is defined Hello %STN_NICKNAME            ;; greet with the nickname :else                          ;; else (not defined) Hello %N !                     ;; greet with the name :endif                         ;;(following commands are always executed) You have connected to %Y at %T. ;; Say your callsign and current time b) The solution using a command macro :macro GREETING ;; start the command macro if %(exist STN_NICKNAME) == 1 ;; when NICKNAME is defined echo Hello %STN_NICKNAME     ;; greet with the nickname else                         ;; else (not defined) echo Hello %N !              ;; greet with the name endif                        ;; (following commands are always executed) echo You have connected to %Y at %T. ;; Say your callsign and current time 6.3 Special system macros There are some special macros that are executed automaticaly by LinPac in some cases: init.mac - This is executed when LinPac is started and its function is to set the callsigns, screen options, and some other parameters. cinit.mac - This is always executed when a connection is established. The distribution version of this macro sets the channel parameters in order to configure station settings from the station database (allowed remote commands, i/o encoding, terminal type) and executes the logbook command to sign the start of a connection. LinPac always passes two arguments to this macro. The first (%1) argument is the callsign of the connected station and the second (%2) argument is the callsign of the previously connected station that provides the connection, or empty in case of direct connection. ctext.mac - This macro is executed when some station connects to the terminal. It should print some greeting text. No arguments are passed. cexit.mac - This is always executed when a connection closes. The distribution version of this macro just executes the logbook command to sign the end of the connection and clears the list of allowed remote commands. There is always one argument passed by LinPac (%1), containing the callsign of the disconnected station. 7 Creating new commands A new command can be represented by a macro or by an external program (standard linux program or special LinPac application). Macros are placed in the $LINPACDIR/macro directory and external programs are placed in the $LINPACDIR/bin directory. In both of these directories is the file 'commands' that contains the list of commands in that directory. You should specify here the name of the file, the name of the command in LinPac (use upper case to specify the mandatory part of the command). It's not necessary to include the macros here if you don't want to define the abbreviation. In case of external programs, it is also possibile to specify program flags. Currently the following flags are supported: A - Ascii mode program. LinPac provides CR <-> LF conversion when communicating with this program. This is the default setting. B - Binary mode. Disables the text conversions. C - Leaves the stdout stream of the program on the console and reads its stderr stream instead. D - DOS conversion - ignore LF characters. S - Reads both stdin and stderr streams of the program (shell mode). L - Local. This program is never available as a remote command. R - This program is always run as a remote command (its messages are always sent out). P - LinPac removes the paths from filenames that are passed as the argument of this command when the FIXPATH command is on. This is a security option. 8 Standard applications 8.1 File transfer protocols At present LinPac supports two protocols for transferring files: * Autobin - a simple protocol suitable for short files * YAPP - a very sophisticated transfer protocol that provides better error detection and is able to resume a previously interrupted transfer Usage of these protocols is described in chapter [42]3.4. LinPac can also automatically save incomming 7+ files. After saving all parts of a file LinPac tries to call the '7plus' program to decode the file. Received 7+ files are not removed automatically. 8.2 Automatic password generation 8.2.1 Login passwords LinPac provides automatic replies to the login authorization requests for the following systems: F6FBB BBS (VE2BLY C_FILTER), BAYBOX, TNOS (numeric MD5). Each station which requests a login password must have an entry in the station database containing at least following fields: A TYPE= (FBB, BAYBOX or TNOS) LOGINPW= PWPROMPT= BBS_prompt is the text which the BBS sends when requesting the authorization. Usually it looks like 'Password>' or 'OK0XYZ>'. 8.2.2 Sysop and general use passwords LinPac provides automatic authorization to the following systems: F6FBB BBS (MD2 password), FLEXNET (older versions, the 'magic' numbers system and newer TheNet-like system), THENET and BAYBOX. Each station you want to authenticate with must have an entry in the station database. For password generation, the following fields must be set: TYPE= PWD= or SYSNUM= Known station types are: * FBB - An F6FBB BBS. The PWD field must contain your password. * THENET - A TheNet node. Again the PWD must contain the password. * BAYBOX - The same system as TheNet. * FPAC - A FPAC node. Password must be stored in the PWD field. * FLEXNET - FlexNet node. If the magic number algorithm is used (older versions of flexdigi) the SYSNUM field must contain your magic number and the PWD field must not be set. When the TheNet algorithm is used (newer versions of flexdigi), the PWD field must contain the password and the SYSNUM field must not be used. In case of FBB the authorization algorithm can be chosen by setting the MD field in the station database: MD=5 - this value will select the MD5 algorithm MD=2 - this value will select the MD2 algorithm When no value is set, MD2 algorithm is used. After connecting to the station you want to authenticate with, the authorization sequence begins with the :PW command. LinPac will send the authorization command to the station and tries to answer the authorization request using your password. If the password is correct, authorization should finish successfully. The PW command accepts the following parameters: :PW [ [ []]] where *  is the command to be sent to the remote station to start the authorization sequence (sys by default) *  is one of the above-mentioned supported systems; this system is used instead of the one specified in station database *  is the password that will be used instead of the one specified in the station database It's recommended that you create simple macros for frequently used authorizations that require special arguments to the PW command. 8.3 Utilities for mail exchange LinPac contains support for exchanging messages with remote Kantronics PBBSs as well as F6FBB BBS systems. This support utilizies some tools from the ax25mail-utils so please install that package first. THe next step would be to configure Linpac and ax25mail-utils's configuration settings with the following variables either in Linpac's channel 0 or in Linpac's init.mac file: Example #1: Kantronics KPC3: * HOME_TYPE - This sets the type of remote system you're connecting to. Supported options are either "PBBS" for Kantronics KPC3 type TNCs or "FBB" for F6FBB BBSes. Only "PBBS" is well understood though the FBB support has been there for some time. * HOME_BBS - The AX.25 path to the home PBBS including the port name. For example d710:AA6WK-1 means use the d710 AX.25 port as defined in the /etc/ax25/axports configuration file and connect to the PBBS AA6WK-1. It's important to note that the callsigns in Linpac are CaSe-SeNsItIvE so make sure these two variables use the SAME case. * HOME_ADDR - The full hierarchical address of the BBS (which technically isn't required for PBBSes). For example AA6WK.#NCA.CA.USA.NOAM. To set the variable while in Linpac, the :SET command can be used. You can also put this same line (but without the colon) in Linpac's init.mac file: :set HOME_TYPE "PBBS" :set HOME_BBS@0 "d710:AA6WK-1" :set HOME_ADDR "AA6WK.#NCA.CA.USA.NOAM" The recommended place to set this variables is in the startup macro init.mac. The default version of this macro contains an example of setting these variables. After setting these variables, the following commands are available: Example #2: * HOME_TYPE - This sets the type of remote system you're connecting to. Supported options are either "PBBS" for Kantronics KPC3 type TNCs or "FBB" for F6FBB BBSes. Only "PBBS" is well understood though the FBB support has been there for some time. * HOME_BBS - The AX.25 path to the home BBS including the port name. For example kiss:OK0PAB OK0NMA means use the kiss AX.25 port as defined in the /etc/ax25/axports configuration file and connec to the BBS OK0PAB via the digipeater OK0NMA. It's important to note that the callsigns are CaSe-SeNsItIvE in Linpac so make sure these two variables use the SAME case. * HOME_ADDR - The full hierarchical address of the BBS. For example OK0PAB.#MOR.CZE.EU. To set the variable while in Linpac, the :SET command can be used. You can also put this same line (but without the colon) in Linpac's init.mac file: :set HOME_TYPE "FBB" :set HOME_BBS@0 "kiss:OK0PAB OK0NMA" :set HOME_ADDR "OK0PAB.#MOR.CZE.EU" The recommended place to set this variables is in the startup macro init.mac. The default version of this macro contains an example of setting these variables. After setting these variables, the following commands are available: Now you need to configure the ax25mail-utils program by editing the /etc/ax25/axgetlist.conf file. The following example is to support connecting to PBBSes in example #1 above: [AA6WK-1] MYCALL N0CALL BBSCALL AA6WK-1 BBSPORT d710 CMD_LIST LO +;L CMD_LIST_FROM LO +;L $ CMD_DISC B HEADER_LINES 1 FORMAT