Initial revision

This commit is contained in:
Evgeniy Kozhuhovskiy 2004-12-30 16:00:36 +00:00
commit 69f117bf78
169 changed files with 50779 additions and 0 deletions

60
CHANGES Normal file
View File

@ -0,0 +1,60 @@
* New: now "bforce" can start outgoing sessions simply on stdin/stdout.
(command line option "-o")
* New: file boxes support. New config keywords "filebox" and
"filebox_directory"
* Bugfix: now "bforce" will remove .bsy locks immediately after
disconnection
* New: implemented CRAM-MD5 authentication in the BinkP protocol
* New: new command line option "-c" in the "bfstat" utility
* New: BinkP seems to be working fine now
* Bugfix: some file names could be spoiled on the Hydra protocol while
receiving (it is a bug with receiving files with the name "d" instead
of the real one)
* New: implementation of the YooHoo handshake protocol
* New: now will create .csy locks while dialing and convert it to
the .bsy only at handshake
* Bugfix: now daemon will not call to the nodes marked as Hold/Down
in a nodelist
* New: added sessions history loging. New config keyword "sessions_history"
For the history file format look sources.
* Bugfix: Hydra didn't send "short" file name, as a result some mailers
with strict checks could not receive files with long names :))
* New: removed check for "short" file name length in the Hydra
0.22 (31-07-2000)
* Bugfix: at incoming sessions used speed limit for outgoing sessions
* Bugfix: RH1 mode didn't work correctly
* Bugfix: outgoing BinkP password protected sessions allways fail
with invalid password error
* Bugfix: files from the AmigaDos Outbound send in incorrect order
* New: passwords are case insensitive now (again)
* New: improved EMSI handshake, now it should work better with systems
using Cisco or something like that with login prompt
* New: added writing of the remote intro to log (like *ico). To control
this feature added new option "[No]Intro"
* New: protocol selection options now works at incoming sessions too
* New: added support for modem chat commands, e.g "ATz| ATm0|", mailer
will wait for modem response ("OK" or "ERROR") after sending each
substring and only then send the next one
* Bugfix: file masks checker didn't work correctly than '!' (not)
prefix was used. Now "DelayFiles", "SkipFiles" should work normaly
* New: Added new expression elements: Exist <file name>, Mailer <mailer
name substring>, Port <port name substring>
* New: Added autoconfiguration of UUCP lock files directory
* Bugfix: daemon could call even to "-Unpublished-" phone if it was
specified in override.
* Bugfix: could not parse received EMSI data packet if character ']' was
escaped as '\5d' by remote mailer (e.g. DVMMail do such escaping)
* New: added support for Tx/Rx windows and ASC/UUE packets in the Hydra
* Bugfix: files skipped by remote mailer was not really skipped :)
* New: extended algorithm of renaming received file if file with such name
allready exist in the inbound directory:
- For netmail packets and '.tic' files: generate new random name
- For arcmail packets: rotate extension characters, as most other mailers do
- For file requests: allways overwrite existing file
- For all other files: add numeric extension as in previous versions
* New: added ability to recode file names and intro text to another charset
then sending/receiving. Recode tables are compartible with HPT. New
config keywords: "Recode_file_in", "Recode_file_out", "Recode_intro_in"

67
CHANGES.kst Normal file
View File

@ -0,0 +1,67 @@
0.22.7.kst1
===========
* Attempt to fix warnings, when compiling with -Wall.
+ make update -- install only binaries.
* Better EMSI handling, when calling to cisco.
+ Correct ZMH support in daemon.
* Some fixes in contributed perl scripts.
0.22.7.kst2
===========
+ Added option --with-uucp-lockdir=... to configure.
* Using strncpy(3) instead of strcpy(3) if possible.
Added patches by Maxi Rovnich @ 2:5030/872:
+ Support for maximum 'no dialtone' count.
+ Support for download resyncing, while checking for free space.
+ Ignore all files, but *.pnt, *.req, *.?lo and *.?ut in BSO.
0.22.7.kst3
===========
* Compilation failed with --disable-hangup-watch-cd. Fixed.
+ Ability to write daemon pid in file.
* -f option had reverse meaning. Thanks to Eugene Korovin @ 2:5080/196.72
+ -q option terminates daemon process (only if pidfile is used).
0.22.7.kst4
===========
* Hydra was broken in kst2. Fixed.
+ Bidirectional session drops only if rxcps and txcps are less than
mincps at the same time.
0.22.7.kst5
===========
+ port tcpip patch by Serge N. Pokhodyaev @ 2:5020/1838
* lock fix, when outbound on not lockable filesystem.
Patch by Andrew Dolgov @ 2:5030/394.41
0.22.7.kst6
===========
* traffic wasn't shown if no files in boxes.
Patch by Alexander Shiyan @ 2:5030/39.2
* bfstat now correctly shows age of files.
Patch by Alexander Shiyan @ 2:5030/39.2
* logging 'undefined cmd' fixed.
Thanks to Pavel I.Osipov @ 2:5020/770.50
0.22.8.kst7
===========
Some changes taken from 0.22.8 by Alexander Belkin:
* some bugfixes
+ new environment variable $RC (session return code)
+ sending of EMSI_ACK every time after recving of EMSI_DAT
+ support for nodelist IBN flag
0.22.8.kst8
===========
* fixed bug with flags CM in override
* fixed bug with sending HUP to daemon

26
CHANGES.ugenk Normal file
View File

@ -0,0 +1,26 @@
0.22.8.ugenk1
=============
+ initial release, based on bforce 0.22.8.kst8
* fixed problem with worktime detecting
+ makefiles fixed (removed make update, now make install installs config files with extension .sample)
+ added --with-user and --with-group options to ``configure'' script.
+ installation directories by default are compliance with default fidogate installation
0.22.8.ugenk2
=============
* pathes by Andrey Slusar @ 2:467/126
(total 12: patch-bforce.c, patch-bfstat.c, patch-daemon.c, patch-expression.y,
patch-nlookup.c, patch-prot_binkp.c, patch-prot_emsi.c, patch-prot_yoohoo.c, patch-prot_zmrecv.c,
patch-prot_zmsend.c, patch-sess_call.c, patch-sess_stat.c)
+ added syslog support (see SYSLOG)
+ fixed nlookup (broken in ugenk1)
+ spec file now goes with bforce
0.22.8.ugenk3
=============
+ fixed working with syslog (not tested yet, any volonteers?)
* some bugfixes
0.22.8.ugenk4
=============
+ fixed problems with license (thnx to Jonathan Gonzales V. from gnu.org)

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

175
INSTALL Normal file
View File

@ -0,0 +1,175 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Type `make install' to install the programs and any data files and
documentation.
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

131
INSTALL.ru Normal file
View File

@ -0,0 +1,131 @@
В этом файле описывается процесс установки и настройки
фидонет-совместимого мейлера bforce 0.22.8.ugenk1.
В данном документе приняты следующие обозначения:
<SRCDIR> - путь, куда вы распаковали тарболл с исходными
текстами bforce 0.22.8.ugenk1 (далее bforce)
Тарболл - файл с расширением tar.gz, или tar.bz2
Требования к системе
====================
Для компиляции bforce вам потребуется компилятор (для
gnu/bsd-систем gcc), так же GNU make (make для линукс,
gmake для bsd).
Обратитесь к документации по вашей системе того, что бы
узнать как установить вышеперечисленное программное обеспечение.
Процесс компиляции
==================
Распакуйте тарболл следующими командами:
gzip -d bforce-0.22.8.ugenk1.tar.gz
или
bzip2 -d bforce-0.22.8.ugenk1.tar.bz2
tar -xvf bforce-0.22.8.ugenk1.tar
Перейдите в директорию bforce-0.22.8.ugenk1/source:
cd <SRCDIR>/bforce-0.22.8.ugenk1/source
Для создания Makefile, который наиболее подходит к вашей
системе, наберите:
./configure --help
и внимательно прочитайте предлагаемую справку.
Если вам не понятна предлагаемая справка, то просто запустите:
./configure
При необходимости исправьте Makefile для ваших нужд.
Запустите команду make (для bsd - gmake):
make
В случае ошибок при выполнении команды make пишите bugreport на
e.kozhuhovskiy@gmail.com
Возможно, прийдется пересоздать configure с помощью autoconf
Поздравляем, компиляция завершилась успешно.
Для установки bforce наберите:
make install
Для bsd:
gmake install
Настройка
=========
Для нормальной работы вам нужно отредактировать конфигурационные файлы
bforce. По умолчанию они находятся в /usr/local/fido/etc и называются
bforce.conf - основной конфигурационный файл bforce
bforce.passwd - файл определения паролей на сессии
bforce.subst - файл переопределения данных из nodelist
freq.dirs - файл задания списка директорий для freq-запросов
freq.aliases - файл задания magic freqests
Так же вам необходимо подправить файл outman. По умолчанию он лежит в
/usr/local/fido/bin. outman - это скрипт, вызываемый вами для создания
прозвонок, файловых запросов и файл-аттачей на узлы ftn.
Использование
=============
bforce - основной файл bforce, служит для запуска
демона, исходящих звонков и запуска из-под mgetty\portslave для приема
входящих звонков.
Попробуйте bforce --help
bfindex - служит для обновления индексных файлов (перекомпиляции)
нодлистов. Испрользование: bfindex
bfstat - служит для показа почтовой очереди. Использование: bfstat
nlookup - служит для поиска информации в нодлисте. Использование:
nlookup <ftn_address>
outman - см. "Настройка". Попробуйте outman --help
Дополнительные утилиты
======================
Дополнительные утилиты для bforce находятся в <SRCDIR>/contrib:
bflan - bforce log analyzer
callout.sh - скрипт для отзвонки на аплинков
outman - скрипт outman
timesync.tcl - скрипт для синхорнизации времени
init.d/bforce - init-скрипт для RedHat
init.d/bforce.debian - init-скрипт для non-RedHat
bfha - bforce history analyzer (bfha)
bfha/README - bfha README
bfha/bfha.pl - собственно, bfha
u-srif - продвинутый freq-процессор
u-srif/u-srif-index.py \ с поддержой отчетов,
u-srif/u-srif-lookup.py \ ограничений,
u-srif/u-srif.py \ индексации файловой базы,
u-srif/conf \ что значительно ускоряет
u-srif/conf/report.footer \ работу.
u-srif/conf/report.header \ Написан на python.
u-srif/conf/u-srif.aliases \ --------------------
u-srif/conf/u-srif.conf \ -------------------
u-srif/conf/u-srif.dirs \ ------------------
u-srif/lib / ------------------
u-srif/lib/uconfig.py / -------------------
u-srif/lib/udbase.py / --------------------
u-srif/lib/ufido.py / ---------------------
u-srif/lib/unodestat.py / ----------------------
u-srif/lib/utmpl.py / -----------------------
u-srif/lib/uutil.py / ------------------------

32
README Normal file
View File

@ -0,0 +1,32 @@
$Id$:
BinkleyForce FTN mailer
-----------------------
BinkleyForce is a simple ifcico like FTN mailer. It can works via
TCP/IP as well as on modem links. Look sample configs for more
information.
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, or (at your option)
any later version. See the COPYING file for further information.
Known Bugs
----------
- BinkD use and expect local file time at BinkP sessions, but
BinkleyForce allways use UTC time (?)
Bug Reports
-----------
E-Mail : adb@newmail.ru
FidoNet : Alexander Belkin, 2:5020/1398.11
New Versions
------------
http://adb.newmail.ru
Copyright (c) 1998-2000 Alexander Belkin, Moscow, Russia.

14
README.kst Normal file
View File

@ -0,0 +1,14 @@
BinkleyForce FTN mailer (Branch KST)
------------------------------------
Bug Reports
-----------
E-Mail : kst@moecho.org
FidoNet : Konstantin Stepanenkov, 2:5030/1251
New Versions
------------
http://kst.spb.ru/bforce/

14
README.ugenk Normal file
View File

@ -0,0 +1,14 @@
BinkleyForce FTN mailer (Branch ugenk)
------------------------------------
Bug Reports
-----------
E-Mail : e.kozhuhovskiy@gmail.com
FidoNet : Evgeniy Kozhuhovskiy, 2:450/256, 2:450/267
New Versions
------------
http://ugenk.bas-net.by/

10
SYSLOG Normal file
View File

@ -0,0 +1,10 @@
Now binkleyforce supports logging to syslog (see syslogd(8) for
details)
It uses LOG_UUCP facility, LOG_PID option. LOG_ERR and LOG_NOTICE
levels are used.
To enable it, uncomment line 19 in source/include/logger.h
( /* #define USE_SYSLOG */ )
TODO: add option to ``configure'' script

11
TODO Normal file
View File

@ -0,0 +1,11 @@
"-" - bugfix
"+" - feature
- sed detection in makefile
+ [io_modem.c] add random and smart algorythms selecting of tty.
smart means (1) write time stat for every line and (2) evenly
select a line to make a call
+ HOLDALL emsi option, if specified flag exists
+ add bind_ip option
- fix Exec feature

0
build-stamp Normal file
View File

0
configure-stamp Normal file
View File

19
contrib/bfha/README Normal file
View File

@ -0,0 +1,19 @@
Данный скрипт предназначен для генерации статистики о работе мейлера
binkleyforce путём анализа создаваемого им файла истории сессий (параметр
`history_file' в bforce.conf). Статистика генерится за предыдущие сутки от
момента запуска скрипта и постится в заданную ньюсгруппу. Доступны два типа
статистики.
Перед первым запуском рекомендуется изменить значение конфигурационных
переменных -- они находятся в начале скрипта.
Известные баги:
1. Hе учитывается случай, когда файл истории сессий повёрнут
logrotate'ом (может потеряться часть статистики)
2. Hеправильно считает cps (завышает), если трафик в обе стороны
Автор скрипта: Serge N. Pokhodyaev, 2:5020/1838, <snp@ru.ru>
Распространяется под GNU GPL.

575
contrib/bfha/bfha.pl Normal file
View File

@ -0,0 +1,575 @@
#!/usr/bin/perl
#
# bfha -- binkleyforce history analyzer
#
# Copyright (C) 2000 Serge N. Pokhodyaev
#
# E-mail: snp@ru.ru
# Fido: 2:5020/1838
#
#
# 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.
#
#
# $Id$
#
#
# çÅÎÅÒÉÔ ÓÔÁÔÉÓÔÉËÕ ÚÁ ÐÒÅÄÙÄÕÝÉÊ ÄÅÎØ
#
#
# TODO:
#
# 1. õÞÅÓÔØ ÓÌÕÞÁÊ, ËÏÇÄÁ ÌÏÇ ÐÏ×£ÒÎÕÔ logrotate'ÏÍ
#
# Known bugs:
#
# 1. HÅÐÒÁ×ÉÌØÎÏ ÓÞÉÔÁÅÔ cps (ÚÁ×ÙÛÁÅÔ) ÅÓÌÉ ÔÒÁÆÉË × ÏÂÅ ÓÔÏÒÏÎÙ
#
use strict;
use Time::Local;
use POSIX qw(strftime);
my $PROGNAME = 'bfha';
my $VERSION = '$Revision$ ';
######## Configurable part ###################################################
my $inews = "/usr/bin/inews -h -O -S";
my $log = "/var/spool/fido/history";
my $rep_newsgroups = "ftn.1838.stat";
my $rep_from = "\"Statistics generator\" <snp\@gloom.intra.eu.org>";
my $rep1_subj = "Sessions history";
my $rep2_subj = "Sessions history";
my $rep3_subj = "Links statistics";
my $count_failed = 1;
#my %line_names = (
# "ttyS1" => "Modem",
# "tcpip" => "IP"
#);
##############################################################################
my $devel = 0;
my (%st, %lines, %nodes, @nodes_sorted);
my @tm;
my $time;
die "Usage: $PROGNAME [-d]\n" if (!((0 == $#ARGV) && ($ARGV[0] eq '-d')) && !(-1 == $#ARGV));
$devel = 1 if ((0 == $#ARGV) && ($ARGV[0] eq '-d'));
$log = "./history" if ($devel);
# Make version string
#
$VERSION =~ s/(\$Rev)ision:\s([\d.]+).*/$PROGNAME\/$2/;
# Get time of 0:00:00 of yesterday
#
@tm = localtime(time - 86400);
$tm[0] = 0; # sec
$tm[1] = 0; # min
$tm[2] = 0; # hours
$time = timelocal(@tm);
# At first read logs
#
undef %st;
undef %lines;
undef %nodes;
die "Log reading error\n" if (0 != log_read($time));
@nodes_sorted = sort(node_cmp keys(%nodes));
# Now generate statistics
#
out_close();
#rep1();
rep2();
rep3();
sub log_read
{
my $i;
my $t;
my @l;
die if (0 != $#_);
$t = $_[0];
open(LOG, "< $log") || die("Can't open $log: $!\n");
while (<LOG>)
{
chomp;
@l = split(/,/);
return 1 if ($#l != 11);
return 1 if (! ($l[4] =~ /[IO]/));
# Check date
#
next if ($l[2] < $t);
last if ($l[2] >= ($t + 86400));
# Entries without address
#
if ($l[1] eq '')
{
next if (0 == $count_failed);
$l[1] = 'failed' if (0 != $count_failed);
}
# Remove domain
#
$l[1] =~ s/@.*$//;
# Add statistics
#
$i = $#{$st{beg}} + 1;
$lines{$l[0]}[$#{$lines{$l[0]}} + 1] = $i;
$nodes{$l[1]}[$#{$nodes{$l[1]}} + 1] = $i;
$st{beg}[$i] = $l[2];
$st{len}[$i] = $l[3];
$st{addr}[$i] = $l[1];
$st{line}[$i] = $l[0];
$st{rc}[$i] = $l[5];
$st{snt_nm}[$i] = $l[6];
$st{snt_am}[$i] = $l[7];
$st{snt_f}[$i] = $l[8];
$st{rcv_nm}[$i] = $l[9];
$st{rcv_am}[$i] = $l[10];
$st{rcv_f}[$i] = $l[11];
$st{islst}[$i] = 0;
$st{islst}[$i] = 1 if ($l[4] =~ /L/);
$st{isprot}[$i] = 0;
$st{isprot}[$i] = 1 if ($l[4] =~ /P/);
$st{type}[$i] = 'I' if ($l[4] =~ /I/);
$st{type}[$i] = 'O' if ($l[4] =~ /O/);
}
}
######## rep1 ################################################################
sub rep1
{
my ($i, $j);
my (%se, %se_t);
my $node;
out_open($rep1_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep1_header";
write;
$~ = "rep1_body";
$se_t{num_in} = 0;
$se_t{num_out} = 0;
$se_t{snt} = 0;
$se_t{rcv} = 0;
$se_t{len} = 0;
foreach $node (@nodes_sorted)
{
$se{num_in} = 0;
$se{num_out} = 0;
$se{snt} = 0;
$se{rcv} = 0;
$se{len} = 0;
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
++$se{num_in} if ($st{type}[$j] eq 'I');
++$se{num_out} if ($st{type}[$j] eq 'O');
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{len} += $st{len}[$j];
}
$se{time} = time_int2str($se{len});
# FIXME (cps)
$se{cps} = div_int(($se{snt} + $se{rcv}), $se{len});
write;
$se_t{num_in} += $se{num_in};
$se_t{num_out} += $se{num_out};
$se_t{snt} += $se{snt};
$se_t{rcv} += $se{rcv};
$se_t{len} += $se{len};
}
$~ = "rep1_footer";
$se_t{time} = time_int2str($se_t{len});
# FIXME (cps)
$se_t{cps} = div_int(($se_t{snt} + $se_t{rcv}), $se_t{len});
write;
print "\n";
out_close();
format rep1_header =
¥                                                                    ¨
¡ System <EFBFBD> Sessions <EFBFBD> Sent <EFBFBD> Received <EFBFBD> Time <EFBFBD> CPS ¡
¡ address <EFBFBD> in out <EFBFBD> bytes <EFBFBD> bytes <EFBFBD> online <EFBFBD> ¡
±                 ¼          ¼           ¼            ¼           ¼       µ
.
format rep1_body =
¡ @<<<<<<<<<<<<<< <EFBFBD> @>> @>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>>>>>>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>> ¡
$node, $se{num_in}, $se{num_out}, $se{snt}, $se{rcv}, $se{time}, $se{cps}
.
format rep1_footer =
°ŠŠŠŠŠ´
¡ TOTAL <EFBFBD> @>> @>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>>>>>>> <EFBFBD> @>>>>>>>> <EFBFBD> @>>>> ¡
$se_t{num_in}, $se_t{num_out}, $se_t{snt}, $se_t{rcv}, $se_t{time}, $se_t{cps}
«                 ¹          ¹           ¹            ¹           ¹       ®
.
}
######## rep2 ################################################################
sub rep2
{
my ($i, $j);
my @t;
my ($t1, $t2, $str, $lv);
my $node;
my %se;
out_open($rep2_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep2_header";
write;
$~ = "rep2_body";
foreach $node (@nodes_sorted)
{
$se{snt} = 0;
$se{rcv} = 0;
$se{len} = 0;
for ($i = 0; $i <= 95; ++$i)
{
$t[$i] = 0;
}
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
# Fill array
#
$t1 = $st{beg}[$j] - $time;
$t2 = $t1 + $st{len}[$j];
$t2 = 86399 if ($t2 > 86399);
$t1 = div_int($t1, 900);
$t2 = div_int($t2, 900);
while ($t1 <= $t2)
{
$t[$t1++] = 1;
}
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{len} += $st{len}[$j];
}
$se{time} = time_int2str($se{len});
# FIXME (cps)
$se{cps} = div_int(($se{snt} + $se{rcv}), $se{len});
# Visualize
#
$i = 0;
$str = "";
if ($t[$i++])
{
$str = $str . "<22>";
}
else
{
$str = $str . "<22>";
}
while ($i < $#t)
{
$lv = 0;
$lv += 1 if ($t[$i++]);
$lv += 2 if ($t[$i++]);
if (0 == $lv)
{
if (div_rest(($i - 1), 8) == 0)
{
$str = $str . "<22>";
}
else
{
$str = $str . " ";
}
}
elsif (1 == $lv)
{
$str = $str . "Ž";
}
elsif (2 == $lv)
{
$str = $str . "<22>";
}
elsif (3 == $lv)
{
$str = $str . "<22>";
}
}
if ($t[$i])
{
$str = $str . "Ž";
}
else
{
$str = $str . "<22>";
}
write;
}
$~ = "rep2_footer";
write;
out_close();
format rep2_header =
0 2 4 6 8 10 12 14 16 18 20 22 24
ŠŠŠŠŠŠŠŠŠŠŠ
.
format rep2_body =
@<<<<<<<<<<<<<<@||||||||||||||||||||||||||||||||||||||||||||||||
$node, $str
.
format rep2_footer =
ˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆŠˆ
0 2 4 6 8 10 12 14 16 18 20 22 24
.
}
######## rep3 ################################################################
sub rep3
{
my $node;
my (%se, %se_t);
my ($i, $j);
out_open($rep3_subj);
printf "Date: %s\n\n", strftime("%a, %e %b %Y", localtime($time));
$~ = "rep3_header";
write;
$~ = "rep3_body";
$se_t{num_in} = 0;
$se_t{num_out} = 0;
$se_t{time_in} = 0;
$se_t{time_out} = 0;
$se_t{snt} = 0;
$se_t{rcv} = 0;
$se_t{time} = 0;
foreach $node (@nodes_sorted)
{
$se{num_in} = 0;
$se{num_out} = 0;
$se{time_in} = 0;
$se{time_out} = 0;
$se{snt} = 0;
$se{rcv} = 0;
$se{time} = 0;
for ($i = 0; $i <= $#{$nodes{$node}}; ++$i)
{
$j = $nodes{$node}[$i];
++$se{num_in} if ($st{type}[$j] eq 'I');
++$se{num_out} if ($st{type}[$j] eq 'O');
$se{time_in} += $st{len}[$j] if ($st{type}[$j] eq 'I');
$se{time_out} += $st{len}[$j] if ($st{type}[$j] eq 'O');
$se{snt} += $st{snt_am}[$j] + $st{snt_nm}[$j] + $st{snt_f}[$j];
$se{rcv} += $st{rcv_am}[$j] + $st{rcv_nm}[$j] + $st{rcv_f}[$j];
$se{time} += $st{len}[$j];
}
# Total counters
#
$se_t{num_in} += $se{num_in};
$se_t{num_out} += $se{num_out};
$se_t{snt} += $se{snt};
$se_t{rcv} += $se{rcv};
$se_t{time} += $se{time};
$se_t{time_out} += $se{time_out};
$se_t{time_in} += $se{time_in};
# Output string
#
# FIXME (cps)
$se{cps} = dash_if_zero(div_int(($se{snt} + $se{rcv}), $se{time}));
$se{time} = time_int2str($se{time});
$se{time_in} = time_int2str($se{time_in});
$se{time_out} = time_int2str($se{time_out});
$se{num_in} = dash_if_zero($se{num_in});
$se{num_out} = dash_if_zero($se{num_out});
$se{rcv} = shrink_size(dash_if_zero($se{rcv}));
$se{snt} = shrink_size(dash_if_zero($se{snt}));
write;
}
$~ = "rep3_footer";
# FIXME (cps)
$se_t{cps} = dash_if_zero(div_int(($se_t{snt} + $se_t{rcv}), $se_t{time}));
$se_t{time} = time_int2str($se_t{time});
$se_t{time_in} = time_int2str($se_t{time_in});
$se_t{time_out} = time_int2str($se_t{time_out});
$se_t{num_in} = dash_if_zero($se_t{num_in});
$se_t{num_out} = dash_if_zero($se_t{num_out});
$se_t{rcv} = shrink_size(dash_if_zero($se_t{rcv}));
$se_t{snt} = shrink_size(dash_if_zero($se_t{snt}));
$~ = "rep3_footer";
write;
print "\n";
out_close();
format rep3_header =
¥                ¸                           ¸          ¸             ¸       ¨
¡ ¡ Sessions/Online ¡ Time ¡ Traffic ¡ ¡
¡ Address ±             ¸             µ online ±      ¸      µ CPS ¡
¡ ¡ Incoming ¡ Outgoing ¡ ¡ Rcvd ¡ Sent ¡ ¡
±                ¾            ¾            ¾          ¾      ¾      ¾       µ
.
format rep3_body =
¡ @<<<<<<<<<<<<<<¡@>><EFBFBD>@>>>>>>> ¡@>><EFBFBD>@>>>>>>> ¡@>>>>>>>> ¡@>>>>>¡@>>>>>¡@>>>>> ¡
$node, $se{num_in}, $se{time_in}, $se{num_out}, $se{time_out}, $se{time}, $se{rcv}, $se{snt}, $se{cps}
.
format rep3_footer =
°½Š½Š½½½½´
¡ TOTAL ¡@>><EFBFBD>@>>>>>>> ¡@>><EFBFBD>@>>>>>>> ¡@>>>>>>>> ¡@>>>>>¡@>>>>>¡@>>>>> ¡
$se_t{num_in}, $se_t{time_in}, $se_t{num_out}, $se_t{time_out}, $se_t{time}, $se_t{rcv}, $se_t{snt}, $se_t{cps}
«                »   ¹         »   ¹         »          »      »      »       ®
.
}
##############################################################################
sub shrink_size
{
die if (0 != $#_);
return $_[0] if ($_[0] < 1024);
return sprintf("%.1fk", $_[0] / 1024) if ($_[0] < 1048576);
return sprintf("%.1fM", $_[0] / 1048576);
}
sub dash_if_zero
{
die if (0 != $#_);
return "-" if (0 == $_[0]);
return $_[0];
}
sub time_int2str
{
my $time;
my $h;
my $m;
my $s;
die if (0 != $#_);
die if (86399 < $time);
return "-:--:--" if (0 == $_[0]);
$time = $_[0];
$h = div_int($time, 3600);
$time = div_rest($time, 3600);
$m = div_int($time, 60);
$s = div_rest($time, 60);
return sprintf("%d:%2.2d:%2.2d", $h, $m, $s);
}
# ãÅÌÏÞÉÓÌÅÎÎÏÅ ÄÅÌÅÎÉÅ
sub div_int
{
use integer;
die if (1 != $#_);
return 0 if ($_[1] == 0);
return $_[0] / $_[1];
}
# ïÓÔÁÔÏË ÏÔ ÃÅÌÏÞÉÓÌÅÎÎÏÇÏ ÄÅÌÅÎÉÑ
sub div_rest
{
die if (1 != $#_);
return 0 if ($_[1] == 0);
return $_[0] - (div_int($_[0], $_[1]) * $_[1]);
}
sub out_open
{
die if (0 != $#_);
open(STDOUT, "| $inews") || die("Can't pipe to inews: $!\n") if (! $devel);
printf "Newsgroups: %s\n", $rep_newsgroups;
printf "From: %s\n", $rep_from;
printf "Subject: %s\n", $_[0];
printf "X-FTN-Tearline: %s\n\n", $VERSION;
}
sub out_close
{
close(STDOUT) if (! $devel);
}
sub node_cmp
{
my (@na, @nb);
@na = split('[:/.]', $::a);
@nb = split('[:/.]', $::b);
# zone
return -1 if ($na[0] < $nb[0]);
return 1 if ($na[0] > $nb[0]);
# net
return -1 if ($na[1] < $nb[1]);
return 1 if ($na[1] > $nb[1]);
# node
return -1 if ($na[2] < $nb[2]);
return 1 if ($na[2] > $nb[2]);
#point
return -1 if ($na[3] < $nb[3]);
return 1 if ($na[3] > $nb[3]);
return 0;
}

384
contrib/bflan Normal file
View File

@ -0,0 +1,384 @@
#!/usr/bin/perl
#
# It is a log file analyser for 'binkleyforce' mailer.
#
# Copyright (c) 1998-99 by Alexander Belkin
#
# $Id$:
#
# If you have any questions, suggestions or wishes, feel free to contact
# with me. My address: 2:5020/1398.11@fidonet
#
# To post into news, use bflan |inews -h -O -S
$program_name = "bforce-lan v1.0/Perl/Linux";
$station_name = "My Station";
$log_file = "/var/log/bforce/bf-log.ttyS0";
$news_header = "From: Statistic Robot <postmaster\@fido.xxx.local>\n".
"Newsgroups: junk\n".
"Subject: Sessions statistic.\n";
#main
#{
if( &ReadLog($log_file) == 0 )
{
print $news_header;
print "\n";
print "\"$system_name\" statistic from <$TimeFirst> to <$TimeLast>\n";
print "\n";
&TotalStatistic();
print "\n";
&SessionsStatistic();
}
exit(0);
#}
sub ReadLog
{
my($start);
if( open( FLOG, $_[0] ) == 0 )
{
print "Can't open log \"$_[0]\": $!\n";
return 1;
}
$start = 0;
$cnt = 0;
$TimeFirst = "";
$TimeLast = "";
# Read in information from logfile
while( <FLOG> )
{
chomp;
( $Mon, $Day, $Time, $Pid, $Text ) = split( /[ \t]+/, $_, 5 );
if( $TimeFirst eq "" )
{
$TimeFirst = "$Mon $Day $Time";
}
if( $start == 0 )
{
if( !defined($Connect[$cnt]) )
{
$Address[$cnt] = "";
$Connect[$cnt] = "?????";
$InFiles[$cnt] = 0;
$OutFiles[$cnt] = 0;
$InBytes[$cnt] = 0;
$OutBytes[$cnt] = 0;
$Status[$cnt] = "U";
$Success[$cnt] = " ";
}
if( $Text =~ /^calling/ )
{
$Text =~ /^calling ([\d:\/.]+)/;
$PidsCall{$Pid} = $1;
$Calls{$1} = 0 if (!defined( $Calls{$1} ));
$Calls{$1}++;
}
elsif( $Text =~ /^connect/ )
{
$Text =~ /^connect "\D*(\d+).*$/;
$Connect[$cnt] = $1;
}
elsif( $Text =~ /^TCP\/IP connect/ )
{
$Connect[$cnt] = "TCPIP";
}
elsif( $Text =~ /^outbound (\S+) session/ )
{
$start = 1;
$Time =~ /^(..):(..):(..)$/;
$Start[$cnt] = ( $1 * 60 + $2 ) * 60 + $3;
$Direction[$cnt] = "O";
$Address[$cnt] = $PidsCall{$Pid};
$MySexyPid = $Pid;
next;
}
elsif( $Text =~ /^inbound (\S+) session/ )
{
$start = 1;
$Time =~ /^(..):(..):(..)$/;
$Start[$cnt] = ( $1 * 60 + $2 ) * 60 + $3;
$Direction[$cnt] = "I";
# $kAddress[$cnt] = $PidsCall{$Pid} if( defined($PidsCall{$Pid}) );
$MySexyPid = $Pid;
next;
}
next;
}
if( ($start == 1) && ($Pid eq $MySexyPid) )
{
if( $Text =~ /^remote is password protected system/ )
{
$Status[$cnt] = "P";
}
elsif( $Text =~ /^remote is listed system/ )
{
$Status[$cnt] = "L";
}
elsif( $Text =~ /^remote is unlisted system/ )
{
$Status[$cnt] = "U";
}
elsif( $Text =~ /^[ \t]*Address :/ )
{
next if( $Address[$cnt] ne "" );
$Text =~ /^.+:[ \t]+([\d:.\/]+).*$/;
$Address[$cnt] = $1;
}
elsif( $Text =~ /^rcvd: \".+\" \d+/ )
{
$Text =~ /^rcvd: \".+\" (\d+)/;
$InBytes[$cnt] += $1;
$InFiles[$cnt] ++;
}
elsif( $Text =~ /^sent: \".+\" \d+/ )
{
$Text =~ /^sent: \".+\" (\d+)/;
$OutBytes[$cnt] += $1;
$OutFiles[$cnt] ++;
}
elsif( $Text =~ /^session rc = \d+/ )
{
$Text =~ /^session rc = (\d+)/;
if( $1 != 0 )
{
$Success[$cnt] = "A";
}
$Time =~ /^(..):(..):(..)$/;
$Finish[$cnt] = ( $1 * 60 + $2 ) * 60 + $3;
$OnLine[$cnt] = $Finish[$cnt] - $Start[$cnt];
$OnLine[$cnt] += 86400 if(( $Finish[$cnt] - $Start[$cnt] ) < 0 );
$start = 0;
$cnt++;
}
}
# got another PID!
elsif( $Text =~ /^connect \".+\"/
|| $Text =~ /^inbound (\S+) session/
|| $Text =~ /^outbound (\S+) session/ )
{
# Possible there was incorrectly terminated session
# due to mailer crash or killing, so getting this string
# can mean that we need to break reading session statistic?
# But we can also get it if log file used not only by one
# mailer at the same time, so.. ignore :)
}
} # end of while( <FLOG> )
close(FLOG);
$TimeLast = "$Mon $Day $Time" if( $Mon && $Day && $Time );
}
sub SessionsStatistic
{
local ($addr, $start, $finish, $online, $ibyte, $obyte, $cps, $speed);
my ($i);
$~ = HEADER;
write;
$~ = EACH;
for ($i = 0; $i < $cnt; $i++)
{
$addr = $Address[$i];
$stat = "$Direction[$i]$Status[$i]$Success[$i]";
$start = sec2str($Start[$i], "short");
$finish = sec2str($Finish[$i], "short");
$online = sec2str($OnLine[$i], "long");
$ibyte = $InBytes[$i];
$in = $InFiles[$i];
$obyte = $OutBytes[$i];
$on = $OutFiles[$i];
$cps = int( ($ibyte + $obyte) / $OnLine[$i] ) if ($OnLine[$i] > 0);
$speed = $Connect[$i];
$ibyte = num2siz( $ibyte );
$obyte = num2siz( $obyte );
write;
}
$~ = FOOTER;
write;
}
sub TotalStatistic
{
undef( %hSystems );
undef( %hCalls );
undef( %hTimes );
undef( %hSessions );
undef( %hInBytes );
undef( %hOutBytes );
undef( %hInFiles );
undef( %hOutFiles );
local($cal, $ses, $time, $ibyte, $obyte, $inum, $onum, $icps, $ocps);
local($acal, $ases, $atime, $aibyte, $aobyte, $ainum, $aonum, $aicps, $aocps);
local($sys);
my($i);
$acal = 0;
$ases = 0;
$atime = 0;
$aibyte = 0;
$aobyte = 0;
$ainum = 0;
$aonum = 0;
$aicps = 0;
$aocps = 0;
for( $i = 0; $i < $cnt; $i++ )
{
$sys = $Address[$i];
if( !defined($hSystems{$sys}) )
{
$hSystems{$sys} = 1;
$hCalls{$sys} = $Calls{$sys}; $Calls{$sys} = 0;
$hTimes{$sys} = 0;
$hSessions{$sys} = 0;
$hInBytes{$sys} = 0;
$hOutBytes{$sys} = 0;
$hInFiles{$sys} = 0;
$hOutFiles{$sys} = 0;
}
$hTimes{$sys} += $OnLine[$i];
$hSessions{$sys} += 1;
$hInBytes{$sys} += $InBytes[$i];
$hOutBytes{$sys} += $OutBytes[$i];
$hInFiles{$sys} += $InFiles[$i];
$hOutFiles{$sys} += $OutFiles[$i];
}
@Syst = sort( keys( %hSystems ));
$~ = hHEADER;
write;
$~ = hEACH;
for( $i = 0; $i <= $#Syst; $i++ )
{
$sys = $Syst[$i];
$cal = ( $hCalls{$sys} || 0 ); $acal += $cal;
$ses = $hSessions{$sys}; $ases += $ses;
$time = sec2str($hTimes{$sys}, "long"); $atime += $hTimes{$sys};
$ibyte = $hInBytes{$sys}; $aibyte += $ibyte;
$obyte = $hOutBytes{$sys}; $aobyte += $obyte;
$inum = $hInFiles{$sys}; $ainum += $inum;
$onum = $hOutFiles{$sys}; $aonum += $onum;
if( $hInFiles{$sys} > 0 || $hOutFiles{$sys} > 0 )
{
$cps = int( ($hInBytes{$sys} + $hOutBytes{$sys}) / $hTimes{$sys} );
$acps += $cps;
$sess++;
}
else
{
$cps = 0;
}
write;
}
# Now, draw systems without sessions ..
@Syst = sort( keys( %Calls ));
$ses = "-";
$time = "-";
$ibyte = "-";
$obyte = "-";
$inum = "-";
$onum = "-";
$cps = "-";
for( $i = 0; $i <= $#Syst; $i++ )
{
$sys = $Syst[$i];
if( $Calls{$sys} )
{
$sys = $Syst[$i];
$cal = $Calls{$sys}; $acal += $cal;
write;
}
}
$atime = sec2str($atime, "long");
if( $sess > 0 )
{
$acps = int( $acps / $sess );
}
else
{
$acps = 0;
}
$~ = hFOOTER;
write;
}
sub num2siz
{
my($num) = $_[0];
my($siz);
if($num < 1000) {
$siz = $num.' ';
} elsif($num < 10000000) {
$siz = int($num/1024).'k';
} else {
$siz = int($num/(1024*1024)).'M';
}
return $siz;
}
sub sec2str
{
my($sec) = $_[0];
my($tip) = $_[1];
my ($h, $m, $s);
$h = int( $sec / 3600 );
$m = int( ($sec - $h*3600) / 60);
$s = int( $sec % 60 );
if( $tip =~ /short/ ) {
return sprintf("%02d:%02d", $h, $m);
} elsif( $tip =~ /long/ ) {
return sprintf("%03d:%02d:%02d", $h, $m, $s);
}
}
format HEADER =
ª”” Call : 'I' - Incoming, 'O' - Outgoing
ƒª” Status : 'U' - Unlisted, 'L' - Listed, 'P' - Protected
ƒƒª Session : ' ' - Success, 'A' - Aborted
¥<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˆ
ƒ Time ƒStaƒ FTN ƒ On-Line ƒ Incoming ƒ Outgoing ƒ Avg.ƒSpeedƒ
ƒhh:mm-hh:mmƒtusƒ Address ƒhhh:mm:ssƒ Bytesƒ N ƒ Bytesƒ N ƒ CPS ƒ ƒ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.
format EACH =
ƒ@<<<<-@<<<<ƒ@<<ƒ@<<<<<<<<<<<<<<ƒ@>>>>>>>>ƒ@>>>>>ƒ@>>ƒ@>>>>>ƒ@>>ƒ@>>>>ƒ@>>>>ƒ
$start,$finish,$stat,$addr, $online, $ibyte, $in,$obyte, $on,$cps, $speed
.
format FOOTER =
¤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ž
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$Version
.
format hHEADER =
¥<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˆ
ƒ FTN ƒ Total ƒ Time ƒ Incoming ƒ Outgoing ƒ CPS ƒ
ƒ Address ƒCal.ƒSes.ƒ On-Line ƒ Bytes ƒ NN ƒ Bytes ƒ NN ƒ ƒ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
.
format hEACH =
ƒ@<<<<<<<<<<<<<<ƒ@>>>ƒ@>>>ƒ@||||||||ƒ@>>>>>>>>ƒ@>>>ƒ@>>>>>>>>ƒ@>>>ƒ@>>>>ƒ
$sys, $cal,$ses,$time, $ibyte, $inum,$obyte, $onum,$cps
.
format hFOOTER =
“”””””””””””””””•””””•””””•”””””””””•”””””””””•””””•”””””””””•””””•”””””„
ƒ TOTAL ƒ@>>>ƒ@>>>ƒ@||||||||ƒ@>>>>>>>>ƒ@>>>ƒ@>>>>>>>>ƒ@>>>ƒ@>>>>ƒ
$acal,$ases,$atime, $aibyte, $ainum,$aobyte,$aonum,$acps
¤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ž
@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
$Version
.

229
contrib/callout.sh Normal file
View File

@ -0,0 +1,229 @@
#!/bin/sh
Ver=1.1h
# óËÒÉÐÔ ÄÌÑ ÐÒÏÚ×ÏÎËÉ ÎÁ ÁÐÌÉÎËÏ×
# ðÒÏ ×ÒÅÍÑ ÉÈ ÒÁÂÏÔÙ (É ÔÅÌÅÆÏÎÙ ÈÉÄÄÅÎÏ×) ÄÏÌÖÅÎ ÚÎÁÔØ ÍÅÊÌÅÒ
#
# úÁÔÏÞÅÎ ÄÌÑ ÍÅÊÌÅÒÁ BinkleyForce
# äÌÑ ÄÒÕÇÉÈ ÐÒÁ×ÉÔØ ÆÕÎËÃÉÀ docallout
#
# Copyright (c) 2000 by Georgi Fofanov, 2:5050/29@fidonet
#
# 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.
#
# ðÕÔØ Ë outbound'Õ ÎÕÖÎÏÊ ÚÏÎÙ (ÐÏËÁ ÚÎÁÅÍ ÔÏÌØËÏ ÐÒÏ ÏÄÎÕ ÚÏÎÕ)
outb=/var/spool/ifmail/outb/
# ðÕÔØ Ë ËÁÔÁÌÏÇÕ Ó lock-ÆÁÊÌÁÍÉ (ÐÏÓÌÅÄÎÉÊ ÓÌÜÛ ÎÕÖÅÎ!)
lock=/var/lock/
# ðÁÕÚÁ ÍÅÖÄÕ Ú×ÏÎËÁÍÉ
# ÷ ÓÅËÕÎÄÁÈ
dialdelay=120
# ðÅÒÉÏÄ ÓËÁÎÉÒÏ×ÁÎÉÑ outbound'Á
# ðÏËÁ ÐÏÓÌÅ ÚÁ×ÅÒÛÅÎÉÑ ËÒÕÇÁ ÐÒÏÚ×ÏÎËÉ ÂÕÄÅÔ 2 ÐÁÕÚÙ - dialdelay É scan
# ÷ ÓÅËÕÎÄÁÈ
scan=60
# ðÁÕÚÁ ÍÅÖÄÕ ÐÒÏ×ÅÒËÁÍÉ lock-ÆÁÊÌÁ
# ÷ ÓÅËÕÎÄÁÈ
lockdelay=10
# òÁÓÐÏÌÏÖÅÎÉÅ ÍÅÊÌÅÒÁ
mailer=/usr/local/bin/bforce
# ëÏÍÁÎÄÁ, ×ÙÐÏÌÎÑÅÍÁÑ ÐÏÓÌÅ ÕÓÐÅÛÎÏÊ ÓÅÓÓÉÉ
after=/usr/local/bin/after_session
# õÓÔÒÏÊÓÔ×Ï, ÎÁ ËÏÔÏÒÏÍ ÓÉÄÉÔ ÍÏÄÅÍ
TTY="ttyS1"
# úÄÅÓØ ÐÅÒÅÞÉÓÌÅÎÙ ÓÉÓÔÅÍÙ, ÎÁ ËÏÔÏÒÙÅ ÍÏÖÎÏ Ú×ÏÎÉÔØ É (ÞÅÒÅÚ ÐÒÏÂÅÌ) ÞÉÓÌÏ
# ÉÈ ÍÏÄÅÍÎÙÈ ÌÉÎÉÊ
# îÁÐÒÉÍÅÒ:
# 2:5050/13 3
# 2:5050/9 2
# 2:5050/33 1
sys_poll=/etc/fido/poll.list
# ðÏÌØÚÏ×ÁÔÅÌØ, ÏÔ ÉÍÅÎÉ ËÏÔÏÒÏÇÏ ÎÁÄÏ ÚÁÐÕÓËÁÔØ
mailer_owner=fido
# ÷ÒÅÍÅÎÎÙÊ ÆÁÊÌ, ËÕÄÁ ÚÁÐÉÓÙ×ÁÅÔÓÑ ÓÐÉÓÏË ?lo É ?ut
list_file=/var/spool/ifmail/list.lst
# ÷ÒÅÍÅÎÎÙÊ ÆÁÊÌ
tmp_file=/var/spool/ifmail/list.tmp
# ÷ÒÅÍÅÎÎÙÊ ÆÁÊÌ, × ËÏÔÏÒÏÍ ÐÅÒÅÞÉÓÌÅÎÙ ÓÉÓÔÅÍÙ, ÎÁ ËÏÔÏÒÙÅ ÂÕÄÅÍ Ú×ÏÎÉÔØ
poll_file=/var/spool/ifmail/polling.list
# íÁËÓÉÍÁÌØÎÏÅ ÞÉÓÌÏ ÐÏÐÙÔÏË ÄÏÚ×ÏÎÉÔØÓÑ ÎÁ ÓÉÓÔÅÍÕ
MAXTRY=25
# óËÏÌØËÏ ×ÒÅÍÅÎÉ ÎÅ Ú×ÏÎÉÔØ ÎÁ ÓÉÓÔÅÍÕ, ÅÓÌÉ ÉÓÞÅÒÐÁÎÏ ÞÉÓÌÏ ÐÏÐÙÔÏË ÄÏÚ×ÏÎÁ
# ÷ ÍÉÎÕÔÁÈ
MAXTIME=60
# ðÒÏÉÚ×ÏÄÉÍ Ú×ÏÎÏË
function docallout ()
{
local zone=$1 net=$2 node=$3 point=$4 curtry=$5 numline=$6 line
let line=${curtry}%${numline}
if [ $point = 0 ] ; then
echo -n `date +%b\ %m\ %T` callout[$$] ú×ÏÎÉÍ ÎÁ ${zone}:${net}/${node} \(try \#${curtry}\)
$mailer ${zone}:${net}/${node} -l $line
let result=$?
else
echo -n `date +%b\ %m.%Y\ %T` callout[$$] ú×ÏÎÉÍ ÎÁ ${zone}:${net}/${node}.${point} \(try \#${curtry}\)
$mailer ${zone}:${net}/${node}.${point} -l $line
let result=$?
fi
case $result in
0 ) echo " ÕÓÐÅÛÎÏ" ;;
* ) echo " ÏÛÉÂËÁ" \#$result ;;
esac
if [ $result = 0 ] ; then
echo `date +%s` 0 0 >$sts
`$after`
else
echo `date +%s` $curtry $result >$sts
fi
}
# ðÒÏ×ÅÒÑÅÍ, ÍÏÖÎÏ ÌÉ Ú×ÏÎÉÔØ ÎÁ ÜÔÕ ÓÉÓÔÅÍÕ
function checkcallout ()
{
local curtry=$1 zone=$2 net=$3 node=$4 point=$5 numline=0
if [ $point = 0 ] ; then
`fgrep "${zone}:${net}/${node}" $sys_poll | awk '{ print "let numline=" $2 }'`
else
`fgrep "${zone}:${net}/${node}.${point}" $sys_poll | awk '{ print "let numline=" $2 }'`
fi
if [ $numline == 0 ] ; then return ; fi
docallout $zone $net $node $point $curtry $numline
}
# óËÁÎÉÒÕÅÍ outbound
function scandir ()
{
find -type f -and \( -name "*.?lo" -o -name "*.?ut" \) > $list_file
for file in `cat $list_file` ; do
eval `echo $file | awk '{ sub(/\.\//, "")
if (substr($0, 9, 4) == ".pnt") {
point = substr($0, 18, 4)
} else {
point = 0
}
printf "zonehex=%s nethex=%s nodehex=%s pointhex=%s let zone=0x%s net=0x%s node=0x%s point=0x%s",
"2", substr($0, 1, 4), substr($0, 5, 4), point,
"2", substr($0, 1, 4), substr($0, 5, 4), point
}'`
ext=${file:${#file}-3}
sts=${file%%?ut}
sts=${sts%%?lo}
bsy=${sts}bsy
sts=${sts}sts
if [ $ext != hlo -a $ext != hut ] ; then
echo ${zone} ${net} ${node} ${point} $sts $bsy >> $tmp_file
fi
done
rm $list_file
if [ -f $tmp_file ] ; then
`cat $tmp_file | sort | uniq > $poll_file`
rm $tmp_file
n=0
for sys in `cat $poll_file` ; do
let n=${n}+1
let tmp=${n}%6
case $tmp in
1 ) let zone=$sys ;;
2 ) let net=$sys ;;
3 ) let node=$sys ;;
4 ) let point=$sys ;;
5 ) sts=$sys ;;
0 ) bsy=$sys ;;
esac
if [ $tmp == 0 ] ; then
while [ -e ${lock}LCK..$TTY ]
do
sleep $lockdelay
done
if [ ! -f $bsy ] ; then
if [ ! -f $sts ] ; then
let lasttime=0 retries=0 errcode=0
else
`cat $sts|awk '{ print "let lasttime=" $1 " retries=" $2 " errcode=" $3 }'`
fi
let curtime=`date +%s`
let timediff=${curtime}-${lasttime}
let curtry=${retries}+1
if [ $curtry -gt $MAXTRY ] ; then
if [ $timediff -gt $MAXTIME ] ; then
let curtry=1
checkcallout $curtry $zone $net $node $point
sleep $dialdelay
fi
else
checkcallout $curtry $zone $net $node $point
sleep $dialdelay
fi
fi
fi
done
rm $poll_file
fi
}
function main ()
{
cd $outb
while [ ! -f /tmp/callout.exit ] ; do
if [ ! -e ${lock}LCK..$TTY ]; then
scandir
sleep $scan
else
sleep $lockdelay
fi
done
rm /tmp/callout.exit
}
if [ `whoami` != "$mailer_owner" ]; then
echo "wrong uid, run as user $mailer_owner (rc=2)"
exit 2
fi
. /etc/profile > /dev/null 2>&1
let MAXTIME=${MAXTIME}*60
main >> /var/log/ifmail/callout.log 2>&1
## éÚÍÅÎÅÎÉÑ
# Ver 1.1, 09 Jul 2000:
#
# ïÂÎÕÌÅÎÉÅ ÞÉÓÌÁ ÐÏÐÙÔÏË ÐÏÓÌÅ ÕÓÐÅÛÎÏÊ ÓÅÓÓÉÉ
#
# îÅ ÒÁÂÏÔÁÌ MAXTIME
# Ver 1.0, 08 Jul 2000:
#
# ðÅÒ×ÁÑ ÓÔÁÂÉÌØÎÁÑ ×ÅÒÓÉÑ

51
contrib/init.d/bforce Normal file
View File

@ -0,0 +1,51 @@
#!/bin/sh
#
# bforce FTN mailer
#
# chkconfig: 345 94 14
# description: Starts and stops the binkleyforce mailer daemon
#
# 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.
OWNER=uucp
BFORCE=/usr/local/fido/bin/bforce
# Source function library.
. /etc/init.d/functions
[ -f $BFORCE ] || exit 0
# See how we were called.
case "$1" in
start)
# Start daemon.
echo -n "Starting bforce: "
su $OWNER -c ". /etc/rc.d/init.d/functions; daemon $BFORCE -d"
echo
touch /var/lock/subsys/bforce
;;
stop)
# Stop daemon.
echo -n "Shutting down bforce: "
killproc bforce
rm -f /var/lock/subsys/bforce
echo
;;
status)
status bforce
exit $?
;;
restart)
$0 stop
$0 start
exit $?
;;
*)
echo "Usage: bforce {start|stop|status|restart}"
exit 1
esac
exit 0

View File

@ -0,0 +1,44 @@
#!/bin/sh
#
# bforce FTN mailer
#
# chkconfig: 345 94 14
# description: Starts and stops the binkleyforce mailer daemon
#
# 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.
OWNER=uucp
BFORCE=/usr/local/fido/bin/bforce
[ -f $BFORCE ] || exit 0
# See how we were called.
case "$1" in
start)
# Start daemon.
echo -n "Starting bforce. "
su $OWNER -c "daemon $BFORCE -d"
echo
touch /var/lock/subsys/bforce
;;
stop)
# Stop daemon.
echo -n "Shutting down bforce. "
$BFORCE -q
rm -f /var/lock/subsys/bforce
echo
;;
restart)
$0 stop
$0 start
exit $?
;;
*)
echo "Usage: bforce {start|stop|restart}"
exit 1
esac
exit 0

366
contrib/outman Normal file
View File

@ -0,0 +1,366 @@
#!/usr/bin/tclsh
#
# Copyright (c) 2000 by Alexander Belkin <adb@newmail.ru>
#
# $Id$
#
# Tcl script for creating polls, file requests and file attaches
#
# 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.
##################
# Program settings
# Defaults for address completion
set def_zone 2
set def_net 5020
set def_node 1398
# Path to your main BSO directory (not implemented)
#set bso_dir "/var/spool/ftn/out"
# Path to your ASO directory
set aso_dir "/var/spool/fido/amiga.out"
# Log file name
set logfile "/var/log/bforce/outman.log"
# Uncomment this if you not need logging
#set logfile {}
################################
# The program's body starts here
set LOG {}
proc stupid_user {} {
puts "Usage: outman <\[poll|freq|send]> \[options] <address> \[files]\n"
puts "options:"
puts " -hold set hold flavor"
puts " -normal set normal flavor (default)"
puts " -crash set crash flavor"
puts " -kill kill files after send"
puts " -truncate truncate files after send"
puts ""
puts "Mail bug reports to <adb@newmail.ru>"
exit 1
}
proc log {str} {
global LOG
global logfile
if { $logfile != {} } {
if { $LOG == {} } {
set LOG [open $logfile "a"]
}
set seconds [clock seconds]
puts $LOG "[clock format $seconds -format "%d/%m %H:%M:%S"] $str"
}
}
proc parse_addr {str} {
global def_zone
global def_net
global def_node
set zone $def_zone
set net $def_net
set node $def_node
set point 0
if { [regexp "^\[0-9]+:\[0-9]+/\[0-9]+\\.?\[0-9]*$" $str] } {
regexp "(\[0-9]+):(\[0-9]+)/(\[0-9]+)\\.?(\[0-9]*)$" $str \
{} zone net node point
} elseif { [regexp "^\[0-9]+/\[0-9]+\\.?\[0-9]*$" $str] } {
regexp "(\[0-9]+)/(\[0-9]+)\\.?(\[0-9]*)$" $str \
{} net node point
} elseif { [regexp "^\[0-9]+\\.?\[0-9]*$" $str] } {
regexp "^(\[0-9]*)\\.?(\[0-9]*)$" $str \
{} node point
} elseif { [regexp "^\.\[0-9]+$" $str] } {
regexp "^\.(\[0-9]+)$" $str \
{} point
} else {
puts "invalid address $str"
return {}
}
if { $zone == {} } { set zone [$def_zone] }
if { $net == {} } { set net [$def_net] }
if { $node == {} } { set node [$def_node] }
if { $point == {} } { set point 0 }
# puts "debug: address parse '$str' -> '$zone,$net,$node,$point'"
return "$zone $net $node $point"
}
proc addrstr {addr} {
return [lindex $addr 0]:[lindex $addr 1]/[lindex $addr 2].[lindex $addr 3]
}
#
# TODO: support for outbounds not in the default zone
#
proc filename_bso {addr flavor} {
global bso_dir
set zone [lindex $addr 0]
set net [lindex $addr 1]
set node [lindex $addr 2]
set point [lindex $addr 3]
if { $point } {
set name [format "%04x%04x.pnt/%08x" $net $node $point]
} else {
set name [format "%04x%04x" $net $node]
}
switch $flavor {
"bsy" {
return "$bso_dir/$name.bsy"
}
"freq" {
return "$bso_dir/$name.req"
}
"hold" {
return "$bso_dir/$name.hlo"
}
"crash" {
return "$bso_dir/$name.clo"
}
default {
return "$bso_dir/$name.flo"
}
}
}
proc filename_aso {addr flavor} {
global aso_dir
set name [lindex $addr 0].[lindex $addr 1].[lindex $addr 2].[lindex $addr 3]
switch $flavor {
"bsy" {
return "$aso_dir/$name.bsy"
}
"freq" {
return "$aso_dir/$name.req"
}
"hold" {
return "$aso_dir/$name.hlo"
}
"crash" {
return "$aso_dir/$name.clo"
}
default {
return "$aso_dir/$name.flo"
}
}
}
proc bsy_exist {addr} {
set bsyname [filename_aso $addr "bsy"]
if { [file exists $bsyname] } {
return 1
}
return 0
}
proc command_freq {addr files} {
set reqname [filename_aso $addr "freq"]
set name {}
# puts "debug: file request name is '$reqname'"
set REQ [open $reqname "a"]
foreach name $files {
puts $REQ $name
log "request \"$name\" from [addrstr $addr]"
}
close $REQ
}
proc command_poll {addr flavor} {
set floname [filename_aso $addr $flavor]
if { ![file exists $floname] } {
set FLO [open $floname "a"]
close $FLO
log "poll [addrstr $addr] ($flavor)"
} else {
log "cannot create poll for [addrstr $addr]: allready polled"
}
}
proc command_send {addr files flavor action} {
set floname [filename_aso $addr $flavor]
set name {}
set curdir [exec pwd]
set FLO [open $floname "a"]
foreach name $files {
if { [file exists $name] } {
if { [file pathtype $name] == "relative" } {
if { [string match "./*" $name] } {
set name [string range $name 2 end]
}
set name "$curdir/$name"
}
log "send file \"$name\" ([file size $name] bytes) to [addrstr $addr] ($flavor)"
switch $action {
"kill" {
puts $FLO "^$name"
}
"truncate" {
puts $FLO "#$name"
}
default {
puts $FLO "@$name"
}
}
} else {
puts "skip file \"$name\" to [addrstr $addr]: file not exist"
}
}
close $FLO
}
##############################
# The main program starts here
if { $argc < 2 } {
stupid_user
}
set command {}
set address {}
set addr {}
set files {}
set flavor "normal"
set action "nothing"
for {set i 0} {$i < $argc} {incr i} {
set arg [lindex $argv $i]
if { [string index $arg 0] == "-" } {
switch [string range $arg 1 end] {
"hold" {
set flavor "hold"
}
"normal" {
set flavor "normal"
}
"crash" {
set flavor "crash"
}
"kill" {
set action "kill"
}
"truncate" {
set action "truncate"
}
default {
puts "unknown command line option '$arg'"
stupid_user
}
}
} elseif { $command == {} } {
set command $arg
} elseif { $address == {} } {
set address $arg
set addr [parse_addr $address]
if { $addr == {} } {
stupid_user
}
} else {
lappend files $arg
}
}
if { $command == {} || $address == {} } {
stupid_user
}
if { [bsy_exist $addr] } {
puts "bsy file exist for address [addrstr $addr]"
exit 2
}
switch $command {
"poll" {
command_poll $addr $flavor
}
"freq" {
command_freq $addr $files
}
"send" {
command_send $addr $files $flavor $action
}
default {
puts "unknown command $command"
stupid_user
}
}
if { $LOG != {} } {
close $LOG
}
exit 0

116
contrib/timesync.tcl Normal file
View File

@ -0,0 +1,116 @@
#!/usr/bin/tclsh
#
# Copyright (c) 2000 by Alexander Belkin <adb@newmail.ru>
#
# $Id$
#
# Time syncronization utility
#
# 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.
##################
# Program settings
set bforce_log_file "/var/log/bforce/bf-log.ttyS0"
set sync_with_addr "2:450/102"
set max_time_diff 1800
set min_time_diff 20
set news_groups "local.robots"
set from_user "Time Robot <root@fido.xxx.local>"
set inews_cmd "/usr/bin/inews"
################################
# The program's body starts here
set sess_pid ""
set remote_times ""
set local_times ""
set TEXT ""
set INP [open $bforce_log_file "r"]
foreach line [split [read $INP] "\n"] {
set fields [split $line " "]
set pid [lindex $fields 3]
set time [join [lrange $fields 0 2]]
set data [join [lrange $fields 4 end]]
if { [string match "*Address : $sync_with_addr" $data] } {
set sess_pid $pid
set sess_time ""
} elseif { [string match "*Time :*" $data] } {
if { $sess_pid == $pid } {
regexp "Time : (.+)" $data {} timestr
if { $timestr != "" } {
set sess_time $timestr
}
}
} elseif { [string match "remote is*,protected" $data] } {
if { $sess_pid == $pid } {
if { $sess_time != "" && $time != "" } {
lappend remote_times $sess_time
lappend local_times $time
}
set sess_pid ""
set sess_time ""
}
} elseif { [string match "remote is*" $data] } {
if { $sess_pid == $pid } {
set sess_pid ""
set sess_time ""
}
}
}
close $INP
set last_rem_time [lindex $remote_times end]
set last_loc_time [lindex $local_times end]
if { $last_rem_time != "" && $last_loc_time != "" } {
regexp "(\[0-9]+):(\[0-9]+):(\[0-9]+)" $last_rem_time {} rh rm rs
regexp "(\[0-9]+):(\[0-9]+):(\[0-9]+)" $last_loc_time {} lh lm ls
set rem [expr "$rh*3600 + $rm*60 + $rs"]
set loc [expr "$lh*3600 + $lm*60 + $ls"]
set diff [expr "$rem - $loc"]
if { [expr abs($diff)] < $min_time_diff } {
# Do nothing
} elseif { [expr abs($diff)] <= $max_time_diff } {
set old_sec [clock seconds]
set new_sec [expr $old_sec + $diff]
exec /bin/date -s [clock format $new_sec -format "%d-%b-%Y %H:%M:%S"]
exec /sbin/clock -wu
append TEXT "The System time was synchronized with the node $sync_with_addr\n\n"
append TEXT "Old time : [clock format $old_sec]\n"
append TEXT "New time : [clock format $new_sec]\n"
append TEXT "Time difference : $diff second(s)\n"
} else {
set old_sec [clock seconds]
set new_sec [expr $old_sec + $diff]
append TEXT "The System time WAS NOT synchronized with the node $sync_with_addr\n\n"
append TEXT "Current time : [clock format $old_sec]\n"
append TEXT "Want set time : [clock format $new_sec]\n"
append TEXT "Time difference : $diff second(s) (must be lower $max_time_diff seconds)\n"
}
}
if { $TEXT != "" } {
set MSG "From: $from_user\n"
append MSG "Subject: Time synchronization\n"
append MSG "Newsgroups: $news_groups\n\n"
append MSG $TEXT
exec $inews_cmd -h << $MSG
}
exit 0

6
contrib/u-srif/INFO Normal file
View File

@ -0,0 +1,6 @@
License notice for u-srif-py
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.

View File

@ -0,0 +1,27 @@
+-----------+----------------------+----------------------+
| | Statistic | Limits |
| Period +-------------+--------+-------------+--------+
| | Size | Number | Size | Number |
+-----------+-------------+--------+-------------+--------+
| Day | @%-11d,sent_day_size@ | @%-6d,sent_day_num@ | @%-11s,limit_size_day@ | @%-6s,limit_num_day@ |
+-----------+-------------+--------+-------------+--------+
| Week | @%-11d,sent_week_size@ | @%-6d,sent_week_num@ | @%-11s,limit_size_week@ | @%-6s,limit_num_week@ |
+-----------+-------------+--------+-------------+--------+
| Month | @%-11d,sent_month_size@ | @%-6d,sent_month_num@ | @%-11s,limit_size_month@ | @%-6s,limit_num_month@ |
+-----------+-------------+--------+-------------+--------+
| Total | @%-11d,sent_total_size@ | @%-6d,sent_total_num@ |
+-----------+-------------+--------+
******************************************************************************
File requests policy
******************************************************************************
File requests supported at 00:00-05:30 and at least 9600 speed
There are aliases for file requests:
FILES - Happy Station files list
BFORCE - The latest version of the binkleyforce mailer
Bye, call again!

View File

@ -0,0 +1,2 @@
Hello, @%s,remote_sysop@!

View File

@ -0,0 +1,6 @@
files /home/ftp/pub/info/happy.zip
filelist /home/ftp/pub/info/happy.lst
test /home/ftp/pub/fileecho/PNT5020/pnt5020.zip
bforce /home/ftp/pub/bforce/bforce-last.tar.gz

View File

@ -0,0 +1,21 @@
##############################################################################
### u-srif FREQ processor configuration file #################################
##############################################################################
# Spool directory for files index, links statistic, etc.
spool-dir /var/spool/u-srif
# Log file name
log-file /var/log/ftn/u-srif.log
# File with list of freqable directories
dir-list-file /usr/local/etc/u-srif/u-srif.dirs
# File with list of freqable directories
alias-list-file /usr/local/etc/u-srif/u-srif.aliases
freq-policy /usr/local/etc/u-srif/policy.text
freq-magic bforce-cvs /usr/local/etc/u-srif/magic/bforce-cvs
freq-alias = files /home/ftp/pub password

View File

@ -0,0 +1,42 @@
/home/ftp/pub/bforce/
/home/ftp/pub/fileecho/ADV_FTNSOFT/
/home/ftp/pub/fileecho/AFTNMISC/
/home/ftp/pub/fileecho/AVP/
/home/ftp/pub/fileecho/BOOK/
/home/ftp/pub/fileecho/CRACKER/
/home/ftp/pub/fileecho/CRACKS/
/home/ftp/pub/fileecho/FAR/
/home/ftp/pub/fileecho/FR_CO.FILES/
/home/ftp/pub/fileecho/FWUTILS/
/home/ftp/pub/fileecho/GSS_BETA/
/home/ftp/pub/fileecho/GSS_SOFT/
/home/ftp/pub/fileecho/G_CHEAT/
/home/ftp/pub/fileecho/IT.FILES/
/home/ftp/pub/fileecho/IT.MP3/
/home/ftp/pub/fileecho/IT.MUSIC/
/home/ftp/pub/fileecho/IT.NDL/
/home/ftp/pub/fileecho/LARRY.FILES/
/home/ftp/pub/fileecho/HAPPY.XCK/
/home/ftp/pub/fileecho/MOBIL/
/home/ftp/pub/fileecho/NET5020/
/home/ftp/pub/fileecho/PNT5020/
/home/ftp/pub/fileecho/RUFO/
/home/ftp/pub/fileecho/STICK.FILES/
/home/ftp/pub/fileecho/T-MAIL/
/home/ftp/pub/fileecho/UNKNOWN/
/home/ftp/pub/fileecho/XDOCREF/
/home/ftp/pub/fileecho/XGAMSOL/
/home/ftp/pub/fileecho/XHAMRADIO/
/home/ftp/pub/fileecho/XHRDASUS/
/home/ftp/pub/fileecho/XHRDDOCS/
/home/ftp/pub/fileecho/XHRDIDC/
/home/ftp/pub/fileecho/XHRDUSR/
/home/ftp/pub/fileecho/XPICART/
/home/ftp/pub/fileecho/XPICHUMOR/
/home/ftp/pub/fileecho/XPICMUSIC/
/home/ftp/pub/fileecho/XPICSHIP/
/home/ftp/pub/fileecho/XPICSYSOP/
/home/ftp/pub/fileecho/XPICWEAPON/
/home/ftp/pub/files/uue_files/
/home/ftp/pub/redhat-5.2/RedHat/RPMS/
/home/ftp/pub/redhat-6.1/RedHat/RPMS/

View File

@ -0,0 +1,163 @@
import gdbm
import string
import os
import ufido
ALIAS_TYPE_NORMAL = 1 # Traditional aliase
ALIAS_TYPE_MAGIC = 2 # "Magic" alias
# TODO: These functions must generate an exception in case of errors
def get_bool(str):
str = string.lower(str)
if str == 'yes' or str == 'true':
return 1
elif str == 'no' or str == 'false':
return 0
return None
def get_size(str):
# TODO: support nice size formats like 64M, 10G
return str
def get_alias(str, type):
args = string.split(str)
if len(args) < 2 or len(args) > 3:
return None
if len(args) == 3:
passwd = args[2]
else:
passwd = None
return Alias(args[0], args[1], passwd, type)
class Alias:
""" Aliases implementation
"""
def __init__(self, name, filename, passwd, type):
""" Alias initialisation
"""
self.name = name
self.filename = filename
self.type = type
def get(self, passwd):
""" Get the list of files to send for this alias
"""
yield = []
if self.type == ALIAS_TYPE_NORMAL:
yield.append(self.filename)
return yield
elif self.type == ALIAS_TYPE_MAGIC:
# Prepare the environment (TODO)
putenv('PASSWORD', passwd)
putenv('ADDRESS', None)
putenv('PROTECTED', 'FALSE')
putenv('LISTED', 'FALSE')
# Execute magic program and process its output
try:
magic = popen(self.filename)
line = magic.readline()
while line:
line = magic.readline()
yield.append(string.strip(line))
if magic.close():
print "Magic return code is non-zero: ", self.filename
return None
return yield
except IOError:
print "Failed to run magic: ", self.filename
return None
class Config:
def read_dir_list(self):
yield = []
fp = open(self.dir_list_file, 'r')
line = fp.readline()
while line:
line = string.strip(line)
if line != '':
yield.append(line)
line = fp.readline()
fp.close()
return yield
def read_alias_list(self):
yield = []
fp = open(self.alias_list_file, 'r')
line = fp.readline()
while line:
line = string.strip(line)
if line != '':
[name, filename] = string.split(line, None, 1)
yield.append(alias(name, filename))
line = fp.readline()
fp.close()
return yield
def read(self, name):
fp = open(name, 'r')
line = fp.readline()
while line:
line = string.strip(line)
args = string.split(line, None, 1)
if line[0:1] == '#' or len(line) == 0:
pass
elif len(args) != 2:
print "Invalid string in config: ", line
else:
key = string.lower(args[0])
val = args[1]
if key == 'dir-list-file':
self.dir_list_file = val
elif key == 'send-report':
self.send_report = get_bool(val)
elif key == 'limit-size-day':
self.limit_size_day = get_size(val)
elif key == 'limit-size-week':
self.limit_size_week = get_size(val)
elif key == 'limit-size-month':
self.limit_size_month = get_size(val)
elif key == 'spool-dir':
self.spool_dir = val
elif key == 'freq-alias':
self.freq_alias.append(get_alias(val, ALIAS_TYPE_NORMAL))
elif key == 'freq-magic':
self.freq_magic.append(get_alias(val, ALIAS_TYPE_MAGIC))
elif key == 'log-file':
self.log_file = val
elif key == 'local-address':
self.local_address.parse(var)
elif key == 'report-header':
self.report_header = val
elif key == 'report-footer':
self.report_footer = val
elif key == 'report-from':
self.report_from = val
elif key == 'report-subj':
self.report_subj = val
elif key == 'stat-dbase':
self.stat_dbase = val
else:
print "unknown config keyword:", key
line = fp.readline()
fp.close()
def __init__(self, name):
self.dir_list_file = ''
self.send_report = 0
self.limit_size_day = 0
self.limit_size_week = 0
self.limit_size_month = 0
self.spool_dir = ''
self.freq_policy = ''
self.freq_alias = []
self.freq_magic = []
self.log_file = ''
self.local_address = ufido.address()
self.report_header = ''
self.report_footer = ''
self.report_from = 'FREQ manager'
self.report_subj = 'FREQ report'
self.stat_dbase = None
self.read(name)

View File

@ -0,0 +1,151 @@
import os
import gdbm
import string
def get_file_desc(filename):
path, name = os.path.split(filename)
descname = os.path.join(path, '.desc', name + '.desc')
if not os.path.isfile(descname):
return None
try:
fp = open(descname, 'r')
except IOError:
print 'Cannot open', descname
return None
line = fp.readline()
yield = ''
while line:
yield = yield + line
line = fp.readline()
fp.close()
return string.strip(yield)
def get_area_desc(areapath):
descname = os.path.join(areapath, '.desc', '.desc')
if not os.path.isfile(descname):
return None
try:
fp = open(descname, 'r')
except IOError:
print 'Cannot open', descname
return None
line = fp.readline()
yield = ''
while line:
yield = yield + line
line = fp.readline()
fp.close()
return string.strip(yield)
class file:
def stat(self):
if self.fake:
return
try:
statinfo = os.stat(self.fullname)
self.size = statinfo[6]
self.time = statinfo[8]
except OSError:
self.size = -1
self.time = -1
self.desc = 'File is not accessable'
def set(self, fullname, name = None, area = '', dlcnt = 0,\
mode = '', desc = '', fake = 0):
if name == None:
self.name = os.path.split(fullname)[1]
else:
self.name = name
self.fullname = fullname
self.dlcnt = dlcnt
self.size = -1
self.time = -1
self.area = area
self.mode = mode
self.desc = desc
self.fake = fake
def reset(self):
self.name = ''
self.fullname = ''
self.area = ''
self.dlcnt = 0
self.mode = ''
self.desc = ''
self.size = -1
self.time = -1
self.fake = 0
def __init__(self):
self.reset()
class filebase:
""" Index entry format: [fullname, area, dlcnt, accessmode, desc]
"""
def open(self, mode):
self.db = gdbm.open(self.dbfile, mode)
def close(self):
self.db.close()
def sync(self):
self.db.sync()
def clean(self):
for filename in self.db.keys():
file = self.get(filename)
if not os.path.isfile(file.fullname):
print 'Remove file "%s" from index' % file.fullname
del self.db[filename]
def get_all(self, filenames):
""" Lookup files in the database and return list
of file objects
"""
yield = []
for name in filenames:
files = self.get(name)
if files and len(files) > 0:
yield.extend(files)
return yield
def get(self, filename):
""" Lookup file by its name in the database and
return list of file objects for this name
"""
yield = []
if not self.db.has_key(filename):
return None
files_info = eval(self.db[filename])
if files_info == None:
newfile = file()
newfile.set(filename, desc='File not found', fake=1)
yield.append(newfile)
else:
for finfo in files_info:
newfile = file()
finfo = eval(finfo)
newfile.set(finfo[0], area = finfo[1],\
dlcnt = finfo[2], mode = finfo[3],\
desc = finfo[4])
yield.append(newfile)
return yield
def put(self, file):
finfo = []
finfo.append(file.fullname)
finfo.append(file.area)
finfo.append(file.dlcnt)
finfo.append(file.mode)
finfo.append(file.desc)
if self.db.has_key(file.name):
files_info = eval(self.db[file.name])
else:
files_info = []
files_info.append(repr(finfo))
self.db[file.name] = repr(files_info)
def __init__(self, spooldir):
self.dbfile = os.path.join(spooldir, 'filebase.db')

181
contrib/u-srif/lib/ufido.py Normal file
View File

@ -0,0 +1,181 @@
import string
import re
import struct
import time
#address_1 = re.compile('^\([0-9]+\):\([0-9]+\)/\([0-9]+\)\.?\([0-9]+\)?$')
address_1 = re.compile('^(\d+):(\d+)/(\d+)\.?(\d+)?$')
months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',\
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Jan')
class address:
def is_set(self):
if self.zone > 0 and self.net > 0:
return 1
return 0
def string(self):
if self.invalid:
yield = 'Invalid address'
elif self.point > 0:
yield = '%d:%d/%d.%d' % (self.zone, self.net, self.node, self.point)
else:
yield = '%d:%d/%d' % (self.zone, self.net, self.node)
return yield
def parse(self, str):
match = address_1.match(str)
if match:
try:
self.zone = string.atoi(match.group(1))
self.net = string.atoi(match.group(2))
self.node = string.atoi(match.group(3))
tmp = match.group(4)
if tmp and tmp != '-1':
self.point = string.atoi(tmp)
else:
self.point = 0
self.invalid = 0
except IndexError:
self.__init__()
return -1
else:
print "Regexp doesnt match!"
return -1
return 0
def __init__(self):
self.zone = 0
self.net = 0
self.node = 0
self.point = 0
self.invalid = 1
class message:
def newmsg(self, addr_from, user_from, addr_to, user_to, subject):
self.unix_time = time.time()
self.addr_orig = addr_from
self.addr_dest = addr_to
self.user_orig = user_from
self.user_dest = user_to
self.subject = subject
self.msgbody = ''
self.append_line('\001FMPT %d' % self.addr_orig.point)
self.append_line('\001TOPT %d' % self.addr_dest.point)
def append_line(self, string):
self.msgbody = self.msgbody + string + '\r'
def append_text(self, text):
for line in string.split(text, '\n'):
self.append_line(line)
def append_file(self, filename):
try:
fp = open(filename, 'r')
except IOError:
print 'Cannot append file', filename
return
line = fp.readline()
while line:
self.append_line(string.rstrip(line))
line = fp.readline()
fp.close()
def __init__(self):
self.unix_time = 0
self.addr_orig = address()
self.addr_dest = address()
self.user_orig = ''
self.user_dest = ''
self.subject = ''
self.msgbody = ''
self.origin = ''
class packet:
def reset(self):
self.addr_orig = address()
self.addr_dest = address()
self.password = ''
self.messages = []
# TODO
def read(self, filename):
self.reset()
fp = open(filename, "w")
fp.close()
def get_time_string(self, unix_time):
msgtime = time.localtime(unix_time)
return '%02d %s %02d %02d:%02d:%02d' % \
(msgtime[2], months[msgtime[1]], msgtime[0] % 100, \
msgtime[3], msgtime[4], msgtime[5])
def get_message_header(self, message):
return struct.pack('7H20s',\
2,\
message.addr_orig.node,\
message.addr_dest.node,\
message.addr_orig.net,\
message.addr_dest.net,\
0,\
0,\
self.get_time_string(message.unix_time)) + \
message.user_dest[0:36] + '\0' + \
message.user_orig[0:36] + '\0' + \
message.subject[0:72] + '\0'
def get_packet_header(self):
now = time.localtime(time.time())
return struct.pack('13H8s12H',\
self.addr_orig.node,\
self.addr_dest.node,\
now[0], # Year\
now[1], # Month\
now[2], # Day\
now[3], # Hour\
now[4], # Minute\
now[5], # Second\
9600, # Baud\
2, # PKT type\
self.addr_orig.net,\
self.addr_dest.net,\
254, # Prod. code + Rev. number\
self.password,\
self.addr_orig.zone,\
self.addr_dest.zone,\
0, # AuxNet\
0, # CWvalidationCopy\
0, # ProductCode + Revision \
0, # CapabilWord\
self.addr_orig.zone,\
self.addr_dest.zone,\
self.addr_orig.point,\
self.addr_dest.point,\
0,
0)
def write(self, filename):
fp = open(filename, "w")
fp.write(self.get_packet_header())
for msg in self.messages:
fp.write(self.get_message_header(msg))
fp.write(msg.msgbody)
fp.write('\0')
fp.write('\0\0')
fp.close()
def add_message(self, message):
self.messages.append(message)
def __init__(self):
self.reset()
if __name__ == "__main__":
tmp = address()
tmp.parse('2:5020/2120')
print tmp.string()

View File

@ -0,0 +1,102 @@
import time
import gdbm
import ufido
class nodestat:
""" [[month_id, month_size, month_num, month_time],
[week_id, seek_size, week_num, week_time],
[day_id, day_size, day_num, day_time],
[total_size, total_num, total_time]]
"""
def __init__(self, dbpath, address):
self.addr = address
self.key = address.string()
self.stat_session_size = 0
self.stat_session_num = 0
self.stat_session_time = 0
self.stat_day_size = 0
self.stat_day_num = 0
self.stat_day_time = 0
self.stat_week_size = 0
self.stat_week_num = 0
self.stat_week_time = 0
self.stat_month_size = 0
self.stat_month_num = 0
self.stat_month_time = 0
self.stat_total_size = 0
self.stat_total_num = 0
self.stat_total_time = 0
self.dbpath = dbpath
tt = time.localtime()
self.month_id = time.strftime('%Y%m', tt)
self.week_id = time.strftime('%Y%W', tt)
self.day_id = time.strftime('%Y%j', tt)
self.notexist = 0 # Entry for this node doesn't exist yet?
def upd_stat(self, num, size):
self.stat_session_size = self.stat_session_size + size
self.stat_session_num = self.stat_session_num + num
self.stat_month_size = self.stat_month_size + size
self.stat_month_num = self.stat_month_num + num
self.stat_week_size = self.stat_week_size + size
self.stat_week_num = self.stat_week_num + num
self.stat_day_size = self.stat_day_size + size
self.stat_day_num = self.stat_day_num + num
self.stat_total_size = self.stat_total_size + size
self.stat_total_num = self.stat_total_num + num
def get_stat(self):
try:
db = gdbm.open(self.dbpath, 'r')
except gdbm.error:
return 0
if not db.has_key(self.key):
self.notexist = 1
db.close()
return 0
entry = eval(db[self.key])
# Check month statistic
if entry[0][0] == self.month_id:
self.stat_month_size = entry[0][1]
self.stat_month_num = entry[0][2]
self.stat_month_time = entry[0][3]
# Check week statistic
if entry[1][0] == self.week_id:
self.stat_week_size = entry[1][1]
self.stat_week_num = entry[1][2]
self.stat_week_time = entry[1][3]
# Check day statistic
if entry[2][0] == self.day_id:
self.stat_day_size = entry[2][1]
self.stat_day_num = entry[2][2]
self.stat_day_time = entry[2][3]
# Get total statistic
self.stat_total_size = entry[3][0]
self.stat_total_num = entry[3][1]
self.stat_total_time = entry[3][2]
db.close()
return 0
def put_stat(self):
db = gdbm.open(self.dbpath, 'cf')
# Don't handle exceptions
entry = [[self.month_id, self.stat_month_size, self.stat_month_num, self.stat_month_time],
[self.week_id, self.stat_week_size, self.stat_week_num, self.stat_week_time],
[self.day_id, self.stat_day_size, self.stat_day_num, self.stat_day_time],
[self.stat_total_size, self.stat_total_num, self.stat_total_time]]
db[self.key] = repr(entry)
db.close()
return 0
if __name__ == '__main__':
addr = ufido.address()
addr.parse('2:5020/2120')
ns = nodestat('./tmp.db', addr)
ns.upd_stat(2, 32768)
ns.put_stat()
addr2 = ufido.address()
addr2.parse('2:5020/2120')
ns2 = nodestat('./tmp.db', addr2)
ns2.get_stat()
print ns2.stat_total_num, ns2.stat_total_size

View File

@ -0,0 +1,97 @@
import string
class template:
def __init__(self):
self.local_address = ''
self.local_sysop = ''
self.local_location = ''
self.local_phone = ''
self.remote_address = ''
self.remote_sysop = ''
self.remote_location = ''
self.remote_phone = ''
self.remote_cid = ''
self.limit_size_day = -1
self.limit_size_week = -1
self.limit_size_month = -1
self.sent_size_day = -1
self.sent_size_week = -1
self.sent_size_month = -1
self.sent_size = -1
self.conn_speed = -1
self.text = None
def set(self, srif=None, conf=None, nodestat=None):
if srif:
self.remote_address = srif.aka.string()
self.remote_sysop = srif.sysop
self.remote_location = srif.site
self.remote_cid = srif.callerid
self.conn_speed = srif.baud
if conf:
self.local_address = conf.local_address.string()
self.limit_size_day = conf.limit_size_day
self.limit_size_week = conf.limit_size_week
self.limit_size_month = conf.limit_size_month
if nodestat:
self.sent_session_size = nodestat.stat_session_size
self.sent_session_num = nodestat.stat_session_num
self.sent_day_size = nodestat.stat_day_size
self.sent_day_num = nodestat.stat_day_num
self.sent_week_size = nodestat.stat_week_size
self.sent_week_num = nodestat.stat_week_num
self.sent_month_size = nodestat.stat_month_size
self.sent_month_num = nodestat.stat_month_num
self.sent_total_size = nodestat.stat_total_size
self.sent_total_num = nodestat.stat_total_num
def __cmd__(self, str):
try:
[fmt, arg] = string.split(str, ',', 1)
return eval('"' + fmt + '" % self.' + arg)
except ValueError:
return '@ValueError@'
except AttributeError:
return '@AttributeError@'
def process(self, text=None):
if text == None:
text = self.text
if text == None:
return None
pos = 0
while 1:
pos = string.find(text, '@', pos)
if pos < 0:
break
end_pos = string.find(text, '@', pos+1)
if end_pos < 0:
break
if end_pos - pos > 1:
# Process escaped command
replace = self.__cmd__(text[pos+1:end_pos])
if replace:
text = text[:pos]+replace+text[end_pos+1:]
# Fix the current position
pos = end_pos + len(replace)-(end_pos-pos+1)
else:
# Leave text untouched
pos = end_pos + 1
else:
# Replace '@@' by the single '@'
text = text[:pos+1]+text[pos+2:]
pos = end_pos
return text
def readfile(self, path):
try:
fp = open(path, 'r')
self.text = fp.read()
fp.close()
except IOError:
pass
if __name__ == "__main__":
test = template()
print test.process("'@@'\n'@@'\n'@%d,conn_speed@'\n'@@@'")

View File

@ -0,0 +1,54 @@
import string
# Header for the files information
file_info_header = 'File Size Description\n'\
+ '-' * 78
class ULog:
def __init__(self, path):
self.path = path
self.fp = open(path, 'a')
def puts(self, string):
fp.puts(strftime('%b %d %H:%M:%S ', gmtime())+string)
def close(self):
fp.close()
def format_desc(desc, offset, width=78):
""" Format file's description
"""
yield = ''
desc = string.expandtabs(desc, 1)
for line in string.split(desc, '\n'):
line = string.rstrip(line)
if line == '':
continue
pos = 0
endpos = width
while line[pos:endpos]:
if yield:
yield = yield + '\n'
yield = yield + offset * ' '
yield = yield + line[pos:endpos]
pos = endpos
endpos = endpos + width
return yield
def format_file_info(name, size, desc, line_length=78):
""" Format file information to meet human requirements
"""
if size < 0:
yield = '%-20s ' % name + 11 * ' '
else:
yield = '%-20s %-11d' % (name, size)
if desc:
offset = len(yield) + 1
width = line_length - offset
desc = format_desc(desc, offset, width)
yield = yield + ' ' + string.lstrip(desc)
else:
yield = yield + ' Description not available'
return yield

View File

@ -0,0 +1,50 @@
#!/usr/bin/python
import sys
import posix
import os
import libconf
import libfbase
USRIF_CONFIG = '/usr/local/etc/u-srif/u-srif.conf'
##############################
# The main program starts here
# Read configuration
Conf = libconf.config(USRIF_CONFIG)
# Open files index for writing
FBase = libfbase.filebase(Conf.spool_dir)
FBase.open('cwf')
file = libfbase.file()
# Process aliases from 'alias-list-file'
for alias in Conf.read_alias_list():
print 'Processing alias "%s": %s' % (alias.name, alias.filename)
file_desc = libfbase.get_file_desc(alias.filename)
file.set(alias.filename, name = alias.name, desc = file_desc)
file.stat()
FBase.put(file)
# Process dirs from 'dir-list-file'
for dir in Conf.read_dir_list():
area_desc = libfbase.get_area_desc(dir)
print 'Processing: %s (%s)' % (dir, area_desc)
files_list = posix.listdir(dir)
for file_name in files_list:
full_name = os.path.join(dir, file_name)
if os.path.isfile(full_name):
file_desc = libfbase.get_file_desc(full_name)
file.set(full_name, area = area_desc, desc = file_desc)
file.stat()
FBase.put(file)
# Purge files index
#print 'Purging removed files from files index'
#FBase.clean()
FBase.close()
sys.exit(0)

View File

@ -0,0 +1,35 @@
#!/usr/local/bin/python
import sys
# Our own libraries
sys.path.append('./lib')
import uconfig
import udbase
from uutil import *
USRIF_CONFIG = '/usr/local/etc/u-srif/u-srif.conf'
##############################
# The main program starts here
if len(sys.argv) < 2:
print 'usage:', sys.argv[0], '<[file] [file] ..>'
sys.exit(1)
# Read configuration
Conf = uconfig.Config(USRIF_CONFIG)
# Lookup files in the database
FBase = udbase.filebase(Conf.spool_dir)
FBase.open('r')
yield = FBase.get_all(sys.argv[1:])
FBase.close()
# Pretty printing
print file_info_header
for file in yield:
file.stat()
print format_file_info(file.name, file.size, file.desc)
sys.exit(0)

182
contrib/u-srif/u-srif.py Normal file
View File

@ -0,0 +1,182 @@
#!/usr/local/bin/python
import string
import sys
import os
# Our own libraries
sys.path.append('./lib')
import uconfig
import udbase
import ufido
import utmpl
import unodestat
from uutil import *
USRIF_CONFIG = '/usr/local/etc/u-srif/u-srif.conf'
class freq_report(ufido.message):
def write_packet(self, pktname):
self.packet.addr_orig = self.addr_orig
self.packet.addr_dest = self.addr_dest
self.packet.write(pktname)
def add_file(self, name, size, desc):
text = format_file_info(name, size, desc)
self.append_text(text)
def __init__(self):
ufido.message.__init__(self)
self.packet = ufido.packet()
self.packet.add_message(self)
class srif_file:
def read_req_list(self):
yield = []
fp = open(self.requestlist, 'r')
line = fp.readline()
while line:
line = string.strip(line)
yield.append(line)
line = fp.readline()
fp.close()
return yield
def write_resp_list(self, list):
fp = open(self.responselist, 'w')
for file in list:
fp.write('+' + file + '\n')
fp.close()
def read(self, name):
fp = open(name, 'r')
line = fp.readline()
while line:
line = string.strip(line)
args = string.split(line, None, 1)
if len(args) == 2:
if string.lower(args[0]) == 'sysop':
self.sysop = args[1]
if string.lower(args[0]) == 'aka':
self.aka.parse(args[1])
elif string.lower(args[0]) == 'baud':
self.baud = args[1]
elif string.lower(args[0]) == 'requestlist':
self.requestlist = args[1]
elif string.lower(args[0]) == 'responselist':
self.responselist = args[1]
elif string.lower(args[0]) == 'remotestatus':
self.remotestatus = args[1]
elif string.lower(args[0]) == 'systemstatus':
self.systemstatus = args[1]
elif string.lower(args[0]) == 'site':
self.site = args[1]
elif string.lower(args[0]) == 'callerid':
self.callerid = args[1]
elif string.lower(args[0]) == 'password':
self.password = args[1]
else:
print "skipping keyword", args[0], "in SRIF"
line = fp.readline()
fp.close()
def __init__(self, name):
self.sysop = ''
self.aka = ufido.address()
self.baud = 0
self.requestlist = ''
self.responselist = ''
self.remotestatus = ''
self.systemstatus = ''
self.site = ''
self.callerid = ''
self.password = ''
self.read(name)
def remote_addr(self):
return self.aka
def isprotected(self):
if string.lower(self.remotestatus) == 'protected':
return 1
return 0
def islisted(self):
if string.lower(self.systemstatus) == 'listed':
return 1
return 0
def append_new_file(fileslist, file):
TotalFiles = TotalFiles + 1
TotalSize = TotalSize + file.size
fileslist.append(file.fullname)
##############################
# The main program starts here
# Global variables
yield_list = []
if len(sys.argv) <> 2:
print 'usage: u-srif <srif file name>'
sys.exit(1)
# Read configuration
conf = uconfig.Config(USRIF_CONFIG)
# Read SRIF files
srif = srif_file(sys.argv[1])
# Read node's statistic
nodestat = unodestat.nodestat(conf.stat_dbase, srif.aka)
nodestat.get_stat()
# Lookup requested files in the our database
FBase = udbase.filebase(conf.spool_dir)
FBase.open('r')
yield = FBase.get_all(srif.read_req_list())
FBase.close()
# Prepare found files for sending
for file in yield:
if not file.fake:
file.stat()
nodestat.upd_stat(1, file.size)
yield_list.append(file.fullname)
# Store node's statistic
nodestat.put_stat()
# Send FREQ report?
if conf.send_report:
# Prepare templates object
tmpl = utmpl.template()
tmpl.set(srif=srif, conf=conf, nodestat=nodestat)
# Setup report object
report = freq_report()
report.newmsg(conf.local_address, conf.report_from, \
srif.aka, srif.sysop, conf.report_subj)
report.append_line('')
# Append header
tmpl.readfile(conf.report_header)
text = tmpl.process()
if text:
report.append_text(text)
# Append per files statistic
for file in yield:
report.add_file(file.name, file.size, file.desc)
# Append footer
tmpl.readfile(conf.report_footer)
text = tmpl.process()
if text:
report.append_text(text)
# Add empty line to the report
report.append_line('')
# Create netmail packet with the FREQ report
pktname = '/var/tmp/12345678.pkt' # XXX
report.write_packet(pktname)
# Add packet file to the response files list
yield_list.append(pktname)
# Dump reponse list
srif.write_resp_list(yield_list)
sys.exit(0)

242
debian/Makefile vendored Normal file
View File

@ -0,0 +1,242 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# ../debian/Makefile. Generated from Makefile.in by configure.
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = .
top_srcdir = ../..
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = /usr/bin/install -c
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 = i686-pc-linux-gnu
host_triplet = i686-pc-linux-gnu
target_triplet = i686-pc-linux-gnu
CC = gcc
CFLAGS = -g -O2
CPP = gcc -E
CPPFLAGS =
DEFS = -DHAVE_CONFIG_H
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = grep -E
EXEEXT =
GROUP = news
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
LDFLAGS =
LIBOBJS =
LIBS =
LTLIBOBJS =
OBJEXT = o
OWNER = uucp
PACKAGE_BUGREPORT = ugenk@tut.by
PACKAGE_NAME = bforce
PACKAGE_STRING = bforce 0.22.8.ugenk2
PACKAGE_TARNAME = bforce
PACKAGE_VERSION = 0.22.8.ugenk2
PATH_SEPARATOR = :
SHELL = /bin/sh
YACC = bison -y
ac_ct_CC = gcc
bindir = ${exec_prefix}/bin
build = i686-pc-linux-gnu
build_alias =
build_cpu = i686
build_os = linux-gnu
build_vendor = pc
datadir = ${prefix}/share
exec_prefix = ${prefix}
host = i686-pc-linux-gnu
host_alias =
host_cpu = i686
host_os = linux-gnu
host_vendor = pc
includedir = ${prefix}/include
infodir = ${prefix}/info
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localstatedir = ${prefix}/var
mandir = ${prefix}/man
oldincludedir = /usr/include
prefix = /usr/local
program_transform_name = s,x,x,
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
sysconfdir = ${prefix}/etc
target = i686-pc-linux-gnu
target_alias =
target_cpu = i686
target_os = linux-gnu
target_vendor = pc
# $Id$
EXTRA_DIST = copyright changelog rules conffiles \
control dirs init.d
subdir = ../debian
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu ../debian/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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
installdirs:
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:
-rm -f $(CONFIG_CLEAN_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 mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
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
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# 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:

3
debian/Makefile.am vendored Normal file
View File

@ -0,0 +1,3 @@
# $Id$
EXTRA_DIST = copyright changelog rules conffiles \
control dirs init.d

242
debian/Makefile.in vendored Normal file
View File

@ -0,0 +1,242 @@
# Makefile.in generated by automake 1.7.9 from Makefile.am.
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
target_triplet = @target@
CC = @CC@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
DEFS = @DEFS@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GROUP = @GROUP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
OBJEXT = @OBJEXT@
OWNER = @OWNER@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
SHELL = @SHELL@
YACC = @YACC@
ac_ct_CC = @ac_ct_CC@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
# $Id$
EXTRA_DIST = copyright changelog rules conffiles \
control dirs init.d
subdir = ../debian
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/include/config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu ../debian/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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
installdirs:
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:
-rm -f $(CONFIG_CLEAN_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 mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
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
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am info info-am install \
install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am
# 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:

6
debian/README.Debian vendored Normal file
View File

@ -0,0 +1,6 @@
bforce for Debian
-----------------
See CHANGES.ugenk
-- Evgeniy Kozhuhovskiy <e.kozhuhovskiy>, Sun, 4 Oct 2004 11:14:15 +0200

25
debian/bfindex.1 vendored Normal file
View File

@ -0,0 +1,25 @@
.TH BFINDEX "1" "April 2003"
.SH NAME
bfindex \- nodelist compiler for bforce
.SH SYNOPSYS
\fBbfindex [-fh]\fR
.SH DESCRIPTION
\fBbfindex\fP is a nodelist compiler for BinkleyForce FTN mailer.
.SH OPTIONS
\fB\-f\fR
force nodelist compiling
.P
\fB-h\fR
show help message
.SH SEE ALSO
bforce(1),bfstat(1),nlookup(1)
.SH AUTHOR
Bforce was written by Alexander Belkin <adb@newmail.ru>, 2:5020/2120
.P
This manual page was written by Zhenja Kaluta <trinfo@mail.ru>
This is free documentation; 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.

68
debian/bforce.1 vendored Normal file
View File

@ -0,0 +1,68 @@
.TH BFORCE "1" "April 2003"
.SH NAME
Bforce \- FTN mailer
.SH SYNOPSYS
\fBbforce [-fmh] [-I\fIinclude\fB] [-n\fIphone\fB]\
[-l\fIline_number\fB] [-a\fIip_address\fB] \
[-S\fIconnect\fB] [-p\fIdevice\fB] \fP<\fInode\fP>
.P
\fBbforce [-ih] [-I\fIinclude\fB] [-S\fIconnect\fB] \
\fI<tsync|yoohoo|emsi|binkp|auto>
.P
\fBbforce [-dh] [-C\fIconfig\fB] [-I\fIinclude\fB]
.SH DESCRIPTION
\fBbforce\fP BinkleyForce is a simple ifcico like FTN mailer. It can
works via TCP/IP as well as on modem links.
.SH OPTIONS
\fB\-d\fR
run as daemon
.P
\fB\-q\fR
terminate daemon
.P
\fB\-i\fR
run from inetd (for slave mode only)
.P
\fB\-f\fR
ignore system's work time
.P
\fB\-o\fR
starts outgoing session on stdin/stdout
.P
\fB-C \fIconfig\fR
main config file name. Default is ("/etc/bforce/bforce.conf")
.P
\fB-I \fIconfig\fR
additional config file name
.P
\fB-n \fIphone\fR
override phone number
.P
\fB-l \fIline_number\fR
call on this hidden line (default is 0)
.P
\fB-a \fIip_address\fR
override internet address
.P
\fB-S \fIconnect_str\fR
connect string (for slave mode only)
.P
\fB-p \fIport\fR
override modem port (must be defined in config)
.P
\fB-h\fR
show help message
.SH SEE ALSO
bfindex(1),bfstat(1),nlookup(1)
.SH AUTHOR
Bforce was written by Alexander Belkin <adb@newmail.ru>, 2:5020/2120
.P
This manual page was written by Zhenja Kaluta <trinfo@mail.ru>
.P
Revision 2 by Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com>
This is free documentation; 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.

10
debian/bforce.postinst.debhelper vendored Normal file
View File

@ -0,0 +1,10 @@
# Automatically added by dh_installinit
if [ -x "/etc/init.d/bforce" ]; then
update-rc.d bforce defaults >/dev/null
if [ -x /usr/sbin/invoke-rc.d ]; then
invoke-rc.d bforce start || exit 0
else
/etc/init.d/bforce start || exit 0
fi
fi
# End automatically added section

5
debian/bforce.postrm.debhelper vendored Normal file
View File

@ -0,0 +1,5 @@
# Automatically added by dh_installinit
if [ "$1" = "purge" ] ; then
update-rc.d bforce remove >/dev/null || exit 0
fi
# End automatically added section

9
debian/bforce.prerm.debhelper vendored Normal file
View File

@ -0,0 +1,9 @@
# Automatically added by dh_installinit
if [ -x "/etc/init.d/bforce" ]; then
if [ -x /usr/sbin/invoke-rc.d ] ; then
invoke-rc.d bforce stop || exit 0
else
/etc/init.d/bforce stop || exit 0
fi
fi
# End automatically added section

1
debian/bforce.substvars vendored Normal file
View File

@ -0,0 +1 @@
shlibs:Depends=libc6 (>= 2.3.2.ds1-4)

47
debian/bfstat.1 vendored Normal file
View File

@ -0,0 +1,47 @@
.TH BINDEX "1" "April 2003"
.SH NAME
bfstat \- binkley style outbound statistic
.SH SYNOPSYS
\fBbfstat [-afhprst] [-n \fInumber\fB]\fR
.SH DESCRIPTION
\fBbfstat\fP help you to see your outbound statistic in human readable
form.
.SH OPTIONS
\fB\-a\fR
sort by FTN address (default)
.P
\fB\-c\fR
print incoming/outgoing calls statistic
.P
\fB\-f\fR
disable queue sorting
.P
\fB\-n \fInumber\fR
don't print more than <number> systems
.P
\fB\-p\fR
print sizes in human readable format
.P
\fB\-r\fR
reverse order while sorting
.P
\fB\-s\fR
sort by total files size
.P
\fB\-t\fR
disable total sizes printing
.P
\fB-h\fR
show help message
.SH SEE ALSO
bforce(1),bindex(1),nlookup(1)
.SH AUTHOR
Bforce was written by Alexander Belkin <adb@newmail.ru>, 2:5020/2120
.P
This manual page was written by Zhenja Kaluta <trinfo@mail.ru>
.P
Revision 2 by Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com>
This is free documentation; 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.

27
debian/changelog vendored Normal file
View File

@ -0,0 +1,27 @@
bforce (0.22.8.ugenk3-1) unstable; urgency=low
* New upstream release
* revision of manual pages
-- Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com> Tue, 16 Nov 2004 08:42:04 +0200
bforce (0.22.8.ugenk2-2) unstable; urgency=low
* fixed some bugs in configfiles
* sorry, bforce compiled without syslog support (maybe in the next version?)
-- Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com> Tue, 2 Nov 2004 10:44:03 +0200
bforce (0.22.8.ugenk2-1) unstable; urgency=low
* Initial Release.
* Really working rules ;)
-- Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com> Sun, 31 Oct 2004 12:04:10 +0200
bforce (0.22.8.ugenk1-1) unstable; urgency=low
* Initial Release.
-- Evgeniy Kozhuhovskiy <ugenk@tut.by> Sun, 4 Jul 2004 11:14:15 +0200

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
4

6
debian/conffiles vendored Normal file
View File

@ -0,0 +1,6 @@
/etc/bforce/bforce.conf
/etc/bforce/bforce.subst
/etc/bforce/bforce.passwd
/etc/bforce/freq.dirs
/etc/bforce/freq.aliases

18
debian/control vendored Normal file
View File

@ -0,0 +1,18 @@
Source: bforce
Section: net
Priority: optional
Maintainer: Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com>
Build-Depends: debhelper (>> 3.0.0), dpatch (>= 1.11)
Standards-Version: 3.5.10
Package: bforce
Architecture: any
Depends: ${shlibs:Depends}
Description: Binkey Force FTN mailer
FTN mailer is a program that transmit files (netmail and echomail)
between your FTN node and other.
.
Bforce can be used to communicate over tcp/ip with binkp protocol or
with classic FTN way -- modem links. Bforce is easy to configure and
have good support of FTN standards.

14
debian/copyright vendored Normal file
View File

@ -0,0 +1,14 @@
This package was debianized by Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com> on
Sun, 4 Jul 2004 11:14:15 +0200.
It was downloaded from http://ugenk.bas-net.by
Upstream Author(s): Alexander Belkin, 2:5020/1398.11
Konstantin Stepanenkov, 2:5030/1251
Evgeniy Kozhuhovskiy, 2:450/256
Copyright:
All programs are either under the GPL or LGPL. On Debian systems,
the complete text of the GPL and LGPL licenses can be found in the
/usr/share/common-licenses/GPL and /usr/share/common-licenses/LGPL files.

2
debian/default vendored Normal file
View File

@ -0,0 +1,2 @@
#
RUN="no"

13
debian/dirs vendored Normal file
View File

@ -0,0 +1,13 @@
usr/bin
etc/bforce
etc/default
etc/default/bforce
var/spool/fido/out
var/spool/fido/in
var/spool/fido/pin
var/spool/fido/ndl
var/spool/fido/fbox
var/spool/bforce
var/log/bforce
var/run/bforce

9
debian/docs vendored Normal file
View File

@ -0,0 +1,9 @@
README
README.kst
README.ugenk
TODO
CHANGES
CHANGES.kst
CHANGES.ugenk
INSTALL
INSTALL.ru

61
debian/init.d vendored Normal file
View File

@ -0,0 +1,61 @@
#! /bin/sh
#
# skeleton example file to build /etc/init.d/ scripts.
# This file should be used to construct scripts for /etc/init.d.
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian
# by Ian Murdock <imurdock@gnu.ai.mit.edu>.
#
# Version: @(#)skeleton 1.9 26-Feb-2001 miquels@cistron.nl
#
# 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.
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/bforce
NAME=bforce
DESC=bforce
test -x $DAEMON || exit 0
# Include bforce defaults if available
if [ -f /etc/default/bforce ] ; then
. /etc/default/bforce
fi
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
--exec $DAEMON
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile \
/var/run/$NAME.pid --exec $DAEMON
sleep 1
start-stop-daemon --start --quiet --pidfile \
/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

30
debian/nlookup.1 vendored Normal file
View File

@ -0,0 +1,30 @@
.TH NLOOKUP "1" "April 2003"
.SH NAME
Bnlookup \- Nodelist search tool for bforce
.SH SYNOPSYS
\fBnlookup [-rh]\fR
.SH DESCRIPTION
\fBnlookup\fP is a nodelist search tool for BinkleyForce FTN mailer.
.SH OPTIONS
\fB\-r\fR
show nodelist string
.P
\fB\-m\fR
show sysops e-mail (see FSP-1004.001 - p2)
.P
\fB-h\fR
show help message
.SH SEE ALSO
bforce(1),bfstat(1),nlookup(1)
.SH AUTHOR
Bforce was written by Alexander Belkin <adb@newmail.ru>, 2:5020/2120
.P
This manual page was written by Zhenja Kaluta <trinfo@mail.ru>
.P
Revision 2 by Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com>
This is free documentation; 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.

36
debian/outman.1 vendored Normal file
View File

@ -0,0 +1,36 @@
.TH OUTMAN "1" "November 2004"
.SH NAME
outman \- creates polls, file requests and attach files in aso and bso
.SH SYNOPSIS
.B outman
\fI<\fR[\fIpoll|freq|send\fR]\fI> \fR[\fIoptions\fR] \fI<address> \fR[\fIfiles\fR]
.SH DESCRIPTION
.SS "options:"
.TP
\fB\-hold\fR
set hold flavor
.TP
\fB\-normal\fR
set normal flavor (default)
.TP
\fB\-crash\fR
set crash flavor
.TP
\fB\-kill\fR
kill files after send
.HP
\fB\-truncate\fR truncate files after send
.PP
Mail bug reports to <e.kozhuhovskiy@gmail.com>
.SH "SEE ALSO"
bfindex(1), bfstat(1), nlookup(1), bforce(1)
.SH AUTHOR
Bforce was written by Alexander Belkin <adb@newmail.ru>, 2:5020/2120
.P
This manual page was written by Evgeniy Kozhuhovskiy <e.kozhuhovskiy@gmail.com>
This is free documentation; 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.

57
debian/postinst vendored Normal file
View File

@ -0,0 +1,57 @@
#! /bin/sh
# postinst script for bforce
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
#
# quoting from the policy:
# Any necessary prompting should almost always be confined to the
# post-installation script, and should be protected with a conditional
# so that unnecessary prompting doesn't happen if a package's
# installation fails and the `postinst' is called with `abort-upgrade',
# `abort-remove' or `abort-deconfigure'.
case "$1" in
configure)
if ! grep -s news /etc/group >/dev/null 2>&1; then
addgroup --system news
fi
if ! id uucp >/dev/null 2>&1; then
adduser --system --disabled-password uucp
chsh -s /bin/sh uucp
adduser uucp dialout
fi
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

38
debian/postrm vendored Normal file
View File

@ -0,0 +1,38 @@
#! /bin/sh
# postrm script for bforce
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postrm> `remove'
# * <postrm> `purge'
# * <old-postrm> `upgrade' <new-version>
# * <new-postrm> `failed-upgrade' <old-version>
# * <new-postrm> `abort-install'
# * <new-postrm> `abort-install' <old-version>
# * <new-postrm> `abort-upgrade' <old-version>
# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
;;
*)
echo "postrm called with unknown argument \`$1'" >&2
exit 1
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

44
debian/preinst vendored Normal file
View File

@ -0,0 +1,44 @@
#! /bin/sh
# preinst script for bforce
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <new-preinst> `install'
# * <new-preinst> `install' <old-version>
# * <new-preinst> `upgrade' <old-version>
# * <old-preinst> `abort-upgrade' <new-version>
#
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
install|upgrade)
# if [ "$1" = "upgrade" ]
# then
# start-stop-daemon --stop --quiet --oknodo \
# --pidfile /var/run/bforce.pid \
# --exec /usr/sbin/bforce 2>/dev/null || true
# fi
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

39
debian/prerm vendored Normal file
View File

@ -0,0 +1,39 @@
#! /bin/sh
# prerm script for bforce
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <prerm> `remove'
# * <old-prerm> `upgrade' <new-version>
# * <new-prerm> `failed-upgrade' <old-version>
# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
# * <deconfigured's-prerm> `deconfigure' `in-favour'
# <package-being-installed> <version> `removing'
# <conflicting-package> <version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
remove|upgrade|deconfigure)
# install-info --quiet --remove /usr/info/bforce.info.gz
;;
failed-upgrade)
;;
*)
echo "prerm called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

111
debian/rules vendored Executable file
View File

@ -0,0 +1,111 @@
#!/usr/bin/make -f
# Sample debian/rules that uses debhelper.
# GNU copyright 1997 to 1999 by Joey Hess.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
# This is the debhelper compatibility version to use.
export DH_COMPAT=3
PACKAGE = bforce
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
configure: configure-stamp
configure-stamp:
dh_testdir
# Add here commands to configure the package.
# cat $(CURDIR)/source/Makefile.in | sed 's/\(^INSTALL_.*\)-o \$${OWNER} -g \$${GROUP}/\1/' > \
# $(CURDIR)/source/Makefile.in.new
# mv $(CURDIR)/source/Makefile.in.new $(CURDIR)/source/Makefile.in
cd source; ./configure --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --sysconfdir=/etc/bforce -with-user=uucp --with-group=news
touch configure-stamp
build: build-stamp
build-stamp: configure-stamp
dh_testdir
# Add here commands to compile the package.
$(MAKE) -C source 2>/dev/null
# /usr/bin/docbook-to-man debian/bforce.sgml > bforce.1
touch build-stamp
clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
# Add here commands to clean up after the build process.
-$(MAKE) -C source clean
dh_clean
rm -f source/config.cache source/include/config.h source/config.log\
source/config.status source/Makefile
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/bforce.
# $(MAKE) -C source install DESTDIR=$(CURDIR)/debian/bforce/
# install $(CURDIR)/debian/default $(CURDIR)/debian/bforce/etc/default/bforce/
/usr/bin/install -c -o uucp -g news source/bin/bforce $(CURDIR)/debian/bforce/usr/bin/bforce
/usr/bin/install -c -o uucp -g news source/bin/bfindex $(CURDIR)/debian/bforce/usr/bin/bfindex
/usr/bin/install -c -o uucp -g news source/bin/bfstat $(CURDIR)/debian/bforce/usr/bin/bfstat
/usr/bin/install -c -o uucp -g news source/bin/nlookup $(CURDIR)/debian/bforce/usr/bin/nlookup
/usr/bin/install -c -o uucp -g news contrib/outman $(CURDIR)/debian/bforce/usr/bin/outman
/usr/bin/install -c -m 644 -o uucp -g news examples/bforce.conf $(CURDIR)/debian/bforce/etc/bforce/bforce.conf
/usr/bin/install -c -m 644 -o uucp -g news examples/bforce.subst $(CURDIR)/debian/bforce/etc/bforce/bforce.subst
/usr/bin/install -c -m 644 -o uucp -g news examples/bforce.passwd $(CURDIR)/debian/bforce/etc/bforce/bforce.passwd
/usr/bin/install -c -m 644 -o uucp -g news examples/freq.aliases $(CURDIR)/debian/bforce/etc/bforce/freq.aliases
/usr/bin/install -c -m 644 -o uucp -g news examples/freq.dirs $(CURDIR)/debian/bforce/etc/bforce/freq.dirs
# Build architecture-independent files here.
binary-indep: build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
# dh_installdebconf
dh_installdocs -X.cvsignore
dh_installexamples examples/*
# dh_installlogrotate
dh_installinit
# dh_installcron
dh_installman $(CURDIR)/debian/bfindex.1 $(CURDIR)/debian/bforce.1 \
$(CURDIR)/debian/bfstat.1 $(CURDIR)/debian/nlookup.1
# dh_installinfo
dh_installchangelogs CHANGES
dh_link
dh_strip
dh_compress
dh_fixperms
chown -R uucp:news $(CURDIR)/debian/bforce/etc/bforce
chown -R uucp:news $(CURDIR)/debian/bforce/var/spool/fido $(CURDIR)/debian/bforce/var/spool/bforce
chown -R uucp:news $(CURDIR)/debian/bforce/var/log/bforce $(CURDIR)/debian/bforce/var/run/bforce
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

96
debian/rules-1 vendored Executable file
View File

@ -0,0 +1,96 @@
#!/usr/bin/make -f
# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
# This is the debhelper compatibility version to use.
export DH_COMPAT=3
PACKAGE = bforce
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
endif
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
INSTALL_PROGRAM += -s
endif
configure: #configure-stamp
#configure-stamp:
dh_testdir
# Add here commands to configure the package.
# cat $(CURDIR)/source/Makefile.in | sed 's/\(^INSTALL_.*\)-o \$${OWNER} -g \$${GROUP}/\1/' > \
# $(CURDIR)/source/Makefile.in.new
# mv $(CURDIR)/source/Makefile.in.new $(CURDIR)/source/Makefile.in
cd source; ./configure --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --sysconfdir=/etc/bforce --with-owner=uucp --with-group=news
touch configure-stamp
build: build-stamp
build-stamp: configure-stamp
dh_testdir
# Add here commands to compile the package.
$(MAKE) -C source
# /usr/bin/docbook-to-man debian/bforce.sgml > bforce.1
touch build-stamp
#clean: unpatch
# dh_testdir
# dh_testroot
# rm -f build-stamp configure-stamp
#
# # Add here commands to clean up after the build process.
# -$(MAKE) -C source clean
# dh_clean
# rm -f source/config.cache source/include/config.h source/config.log\
# source/config.status source/Makefile
install: build
dh_testdir
# dh_testroot
dh_clean -k
dh_installdirs
# Add here commands to install the package into debian/bforce.
$(MAKE) -C source install DESTDIR=$(CURDIR)/debian/bforce
# install $(CURDIR)/debian/default $(CURDIR)/debian/bforce/etc/default/bforce
# Build architecture-independent files here.
binary-indep: configure build install
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: configure build install
dh_testdir
dh_testroot
# dh_installdebconf
dh_installdocs -X.cvsignore
dh_installexamples examples/*
# dh_installlogrotate
dh_installinit
# dh_installcron
dh_installman $(CURDIR)/debian/bfindex.1 $(CURDIR)/debian/bforce.1 \
$(CURDIR)/debian/bfstat.1 $(CURDIR)/debian/nlookup.1
# dh_installinfo
dh_installchangelogs CHANGES CHANGES.kst CHANGES.ugenk
dh_link
dh_strip
dh_compress
dh_fixperms
chown -R uucp:news $(CURDIR)/debian/bforce/etc/bforce
chown -R uucp:news $(CURDIR)/debian/bforce/var/spool/fido $(CURDIR)/debian/bforce/var/spool/bforce
chown -R uucp:news $(CURDIR)/debian/bforce/var/log/bforce $(CURDIR)/debian/bforce/var/run/bforce
# dh_makeshlibs
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

567
examples/bforce.conf Normal file
View File

@ -0,0 +1,567 @@
##
## This is an example binkleyforce configuration file
##
## Configuration line format:
## <Keyword> [(<expression>)] <Value>
##
## For all addresses masks ``2:5020/*'' is equal to the ``2:5020/*.0''
##
## Expression elements:
## <Address or address mask>
## Time <interval>[,<interval>,..]
## Speed <logic_operator> <number>
## ConnSpeed <logic_operator> <number>
## Flag <nodelist_flag>
## Exec <command_name>
## Inbound, Outbound, Listed, Protected
##
## You can split long strings by adding '\' character to the end of previous
## line. Total length of string is unlimited. For example:
##
## Options NoZmodem \
## NoZedZap
##
## Config reader directives:
##
## $INCLUDE <filename> Include this file
## $LOGFILE <filename> Log to this file
## $DEBUGFILE <filename> Write debug information to this file
## $DEBUGLEVEL <debug_levels> Change debug level
##
## $IFEXP <expression> All data between ``$IFEXP'' and ``$ENDIF''
## <config_keyword> <value> directives will be used with the specified
## .... expression, empty lines are unallowed
## $ENDIF
##
## Examples:
##
## $DEBUGLEVEL Outbound hShake
##
## $IFEXP ((2:*/*.* | !protected) & Time 23:00-01:00)
## options NoFreqs
## min_speed_in 14400
## session_limit_in 600
## $ENDIF
##
$INCLUDE /usr/local/fido/etc/bforce.subst
$INCLUDE /usr/local/fido/etc/bforce.passwd
address 2:450/256.0@fidonet
address 2:450/247.128@fidonet
address 20:26/100.0@easynet
#
# Hide addresses from remote, where <address> must be one of your AKAs
#
# hide_our_aka <address>
#
#
# Allowed options:
# [No]Zmodem, [No]ZedZap, [No]DirZap, [No]Janus, [No]Hydra
# [No]Chat, [No]FTS1, [No]YooHoo, [No]EMSI, [No]EMSI-II
# [No]Freqs, [No]MailOnly, [No]HoldXT, [No]HoldReq, [No]HoldHold
# [No]HoldAll, [No]PickUp, [No]RH1
#
# Now it is highly recommended to set at least "NoDirZap NoJanus"
#
options NoDirZap NoJanus NoChat
#
# Domain outbounds
# Domain <domain_name> <outbound_dir> <zone>
#
#domain lasernet /var/spool/ftn/lasernet/ 161
#domain medianet /var/spool/ftn/medianet/ 776
#domain schoolnet /var/spool/ftn/schoolnet/ 461
#
# Log/debug file names (if not defined, used builtins)
#
#log_file_daemon /var/log/bforce/bf-daemon
#log_file /var/log/bforce/bf-log
#debug_file /var/log/bforce/bf-debug
#
# Existing of this file forbid any outgoing modem calls. Existing of
# file with name <nodialflag>.ttyS1 forbid outgoing calls only via
# modem on device /dev/ttyS1, and so on.
#
nodial_flag /etc/nodial
#
# Debugging information completness level. Debugging is disabled by
# default. Allowed debug levels: config, nodelist, outbound, info, hshake,
# ttyio, modem, prot, freq, daemon, full
#
# It seems to be broken now, use "$DEBUGLEVEL" instead
#
#debug_level info hshake prot
#
#
# Inbound directories
#
inbound_directory (Protected) /var/spool/fido/bt/pin
inbound_directory /var/spool/fido/bt/in
#
# Path to your 4D outbound (use zone as extension)
#
#outbound_directory /var/spool/fido/bt/out
#
# Path to your AmigaDos style 4D outbound.
# (You can use all outbound styles at the same time)
#
amiga_outbound_directory /var/spool/fido/bt/out
#
# Directory with your nodelists (for nodelist without full path)
#
nodelist_directory /var/spool/fido/ndl
#
# Directory for status files
#
status_directory /var/spool/fido/bforce
#
# Sessions history
#
history_file /var/log/bforce/history
#
# Minimal connect speeds for incoming/outgoing sessions
#
#min_speed_in 1200
#min_speed_out 1200
#
# Time limit for incoming/outgoing session [seconds]
#
#session_limit_in 1800
#session_limit_out 1800
#
# Abort transfer if minimal CPS stays longer this time (in seconds)
# Default value is 60 seconds.
#
#min_cps_time 120
#
# Force usage of this value as minimal CPS (most priority)
# min_cps_recv <Minimal_CPS>
# min_cps_send <Minimal_CPS>
#
# For example:
# min_cps_recv (2:5020/1398) 2100
# min_cps_recv (2:5020/1682) 3000
# min_cps_recv (2:5020/1811) 1400
#
# Minimal CPS values for Zmodem ,ZedZap, DirZap protocols (Receive/Send)
#
# <Speed> <CPS>
#
zmodem_mincps_recv 300 15
zmodem_mincps_recv 1200 90
zmodem_mincps_recv 2400 120
zmodem_mincps_recv 4800 240
zmodem_mincps_recv 7200 360
zmodem_mincps_recv 9600 480
zmodem_mincps_recv 12000 600
zmodem_mincps_recv 14400 720
zmodem_mincps_recv 16800 840
zmodem_mincps_recv 19200 960
zmodem_mincps_recv 21600 1080
zmodem_mincps_recv 23600 1180
zmodem_mincps_recv 24000 1200
zmodem_mincps_recv 26400 1320
zmodem_mincps_recv 28800 1440
zmodem_mincps_recv 31200 1600
zmodem_mincps_recv 33600 1700
zmodem_mincps_send 300 15
zmodem_mincps_send 1200 90
zmodem_mincps_send 2400 120
zmodem_mincps_send 4800 240
zmodem_mincps_send 7200 360
zmodem_mincps_send 9600 480
zmodem_mincps_send 12000 600
zmodem_mincps_send 14400 720
zmodem_mincps_send 16800 840
zmodem_mincps_send 19200 960
zmodem_mincps_send 21600 1080
zmodem_mincps_send 23600 1180
zmodem_mincps_send 24000 1200
zmodem_mincps_send 26400 1320
zmodem_mincps_send 28800 1440
zmodem_mincps_send 31200 1600
zmodem_mincps_send 33600 1700
hydra_mincps_recv 300 15
hydra_mincps_recv 1200 90
hydra_mincps_recv 2400 120
hydra_mincps_recv 4800 240
hydra_mincps_recv 7200 360
hydra_mincps_recv 9600 480
hydra_mincps_recv 12000 600
hydra_mincps_recv 14400 720
hydra_mincps_recv 16800 840
hydra_mincps_recv 19200 960
hydra_mincps_recv 21600 1080
hydra_mincps_recv 23600 1180
hydra_mincps_recv 24000 1200
hydra_mincps_recv 26400 1320
hydra_mincps_recv 28800 1440
hydra_mincps_recv 31200 1600
hydra_mincps_recv 33600 1700
hydra_mincps_send 300 15
hydra_mincps_send 1200 90
hydra_mincps_send 2400 120
hydra_mincps_send 4800 240
hydra_mincps_send 7200 360
hydra_mincps_send 9600 480
hydra_mincps_send 12000 600
hydra_mincps_send 14400 720
hydra_mincps_send 16800 840
hydra_mincps_send 19200 960
hydra_mincps_send 21600 1080
hydra_mincps_send 23600 1180
hydra_mincps_send 24000 1200
hydra_mincps_send 26400 1320
hydra_mincps_send 28800 1440
hydra_mincps_send 31200 1600
hydra_mincps_send 33600 1700
#
# Automatically set this permissions on the received files
#
mode_default 100660
mode_arcmail 100660
mode_netmail 100660
mode_request 100660
#
# In modem commands you can use:
# '|' cartidge return
# '^' high DTR
# 'v' low DTR
# '~' 1 second delay
# '`' 1/4 second delay
#
# Yor modem devices names (will use first not locked one)
# ModemDev <device>[<:lock_speed>]
#
modem_port /dev/ttyS0:57600
#
# Send this string to modem before calling
#
modem_reset_command AT|
#
# Dial string
#
modem_dial_prefix ATDP
#
# Dial string
#
modem_dial_suffix |
#
# Hangup string
#
modem_hangup_command v~^~ATH0|
#
# Command for getting modem statistic (after outgoing sessions)
#
#
#modem_stat_command AT%S|
# if your modem do not send statistic, use this:
modem_stat_command AT|
#
# List of modem responses on modem dial command
#
# First field is substring of modem response string, first match used!
#
# Second field value Default return code
# connect --
# busy 11
# nocarrier 12
# nodialtone 13
# noanswer 14
# error 15
#
# You are free to use something like: ModemDialResp "LINE IN USE" Error 200
#
# <Modem said> <Mailer think> [Return code]
#
modem_dial_response "CONNECT" connect
modem_dial_response "BUSY" busy
modem_dial_response "NO CARRIER" nocarrier
modem_dial_response "NO DIAL" nodialTone
modem_dial_response "NO ANSWER" noanswer
modem_dial_response "VOICE" noanswer
modem_dial_response "ERROR" error
#
# Your nodelists. Will try all nodelists with matching address mask.
#
nodelist nodelist.ndl *:*/*.0
nodelist 450_256.pnt 2:450/256.*
nodelist easynet.ndl 20:26/*.0
nodelist *:*/*.*
#
# Nodelist phone numbers translation
# phone_translate <what_translate> [to_what_translate]
phone_translate 375-17-
phone_translate 375- 8W
#
# Your system information (for EMSI only)
#
system_name XXX Station
location Minsk, Belarus
sysop_name Evgeniy Kozhuhovskiy
phone 375-17-2250238, voice: 375-29-5586164
max_speed 57600
flags XW,V34B,IDC,LMD
emsi_OH_time 22:00-07:30
emsi_FR_time 22:30-05:30
#
# Our receiver buffer size [bytes]
#
recv_buffer_size 65536
#
# Wait for modem response this time at calling [seconds]
#
wait_carrier_out 120
# Command to run external SRIF processor
#
#freq_srif_command /usr/local/lib/u-srif/u-srif
#
# Files with list of aliases and dirs for FREQs
#
freq_alias_list /usr/local/fido/etc/freq.aliases
freq_dir_list /usr/local/fido/etc/freq.dirs
#
# Maximal number of files to send on FREQs
#
freq_limit_number 10
#
# Size limit for file requests [bytes]
#
freq_limit_size 6000000
#
# _SEND_ requested files not longer this time [seconds]
#
freq_limit_time 1200
#
# Ignore this masks in file requests
#
freq_ignore_masks \\* \\*.\\* \\*.zip \\*.rar \\*.tgz \\*.mp3
#
# Skip files with ZRPOS on zmodem protocol (else use ZSKIP)
#
#zmodem_skip_by_pos yes
#
# Binkleyforce will send empty netmail packet on Zmodem/ZedZap/DirZap
# protocols if there is nothing to send (default - No)
#
zmodem_send_dummy_pkt no
#
# Initial block size [bytes] for Zmodem/ZedZap/DirZap protocols
#
#zmodem_start_block_size 512
#
# Tx window size [bytes] for Zmodem/ZedZap/DirZap protocols
#
#zmodem_tx_window 32768
#
# Automaticaly skip files with such names at receiving
#
skip_files_recv *.pif *.swp
#
# Delay files with such names at receiving/sending
#
#delay_files_recv !%arcmail !%netmail # We will refuse all except mail
#delay_files_send !%netmail # We will send only netmail
# # packets
#
# Our netmail-only uplink
#delay_files_recv (2:450/102) !%netmail
#
# Binkleyforce will delay all receiving files if free space space
# in the inbound directory is lower this value [Kbytes]
#
#min_free_space 20000
#
# Tables for recoding to another charset. Tables format is compartible
# with HPT, FTrack and possible with something else.
#
# File names recoding
#recode_file_out /usr/local/fido/etc/koi82alt.tbl
#recode_file_in /usr/local/fido/etc/alt2koi8.tbl
# Intro recoding (Buggy Sidoroff)
#recode_intro_in (2:450/236) /usr/local/fido/etc/alt2koi8.tbl
#
# External programs support. Possible execution options:
#
# nowait - don't wait for the process termination
# logout - write stdout/stderr to the log
# setsid - run command in a new session
# useshell - run command by calling a shell (/bin/sh)
#
#run_after_handshake [logout]/bin/echo "Hello, world!"
#run_after_session [nowait,setsid]/usr/local/lib/ftp/run-in
#
# To see a nodelist node information in the log file, write:
#
#run_after_handshake [useshell,logout]/usr/local/lib/ftn/nlookup $REM_ADDR_FTN
#
# Path to the directory with "long" fileboxes. Such fileboxes names
# has the format "<zone>.<net>.<node>.<point>" (e.g. "2.5020.2120.0").
# The files from such fileboxes are allways queued with a "hold" flavor
#
#filebox_directory /var/spool/fido/bt/fbox
#
# Personal fileboxes
# filebox <path> <address> [flavor]
#
#filebox /var/spool/ftn/fbox/adb 2:5020/2120.1 hold
#filebox /var/spool/ftn/fbox/pvc 2:5020/2091 normal
#
# ?LO files content translation rules
# flo_translate <find string> <replace string>
#
#flo_translate C:\\fido\\spool\\outbound /var/spool/ftn/out
#flo_translate \\ /
#######################
# DAEMON configuration
#
# Try counters short description:
#
# <Keyword> <Tries number> <Action> [<Action argument>]
#
# Allowed 'Keywords':
# 'Maxtries'
# Increase : every time when we call system
# Reset : successful session
# 'Maxtries_noansw'
# Increase : modem return "noanswer"
# Reset : connect
# 'Maxtries_noconn'
# Increase : cannot connect
# Reset : connect
# 'Maxtries_hshake'
# Increase : handshake failure
# Reset : successful handshake
# 'Maxtries_sessions'
# Increase : any failures after connect (including connect speed too low)
# Reset : successful session
# 'Maxtries_nodial'
# Increase : modem return "nodialtone"
# Reset : connect
#
# Allowed 'Actions':
# 'Undialable' - set undialable flag to the system, so we will never try
# to call it more
# 'Hold' - don't call system during next <Action argument> seconds
# 'HoldAll' - don't make outgoing calls to ANY system during next
# <Action argument> seconds
#
maxtries 200 Undialable # Be carefull.. =)
maxtries_noansw 5 Hold 7200 # Call two hours later
maxtries_noconn 40 Hold 10800 # Don't call 3 hours
maxtries_hshake 10 Hold 86400 # 1 day delay
maxtries_sessions 10 Hold 3600 # Don't annoy uplinks
maxtries_nodial 1 Hold 1200 # Call 20 min later
#
# Minimum delay between reusings of the same modem [seconds]
#
daemon_circle_modem 40
#
# Outbound queue rescan interval [seconds]
#
daemon_circle_rescan 60
#
# Minimum delay between two outgoing calls to the same system,
# depending on the mail/files flavor [seconds]
#
daemon_circle_normal 80
daemon_circle_direct 40
daemon_circle_crash 20
daemon_circle_immed 10
#
# Maximum number of the simultaneously running TCP/IP clients. Zero value
# will forbid any outgoing calls via TCP/IP
#
daemon_maxclients_tcpip 3
#
# Maximum number of the simultaneously running modem clients. Zero value
# will forbid any outgoing calls via modems
#
daemon_maxclients_modem 1
#
# Daemon PID file name
#
daemon_pid_file /var/run/bforce.pid
#
# Syslog facility (see man 3 openlog and /usr/include/sys/syslog.h for list of facilities)
# 64 == 8<3 ==
# See SYSLOG for details
#
syslog_facility 64
#
# Where to listen (0.0.0.0 for all available)
#
bind_ip 127.0.0.1
#
# Holdall flag (if exists, no mail will sent)
#
nomail_flag /etc/nomail
# That's all!

9
examples/bforce.passwd Normal file
View File

@ -0,0 +1,9 @@
#
# Format: password <address> <password>
#
password 2:5020/1398 passwd1
password 2:5020/1682 passwd2
password 2:5020/1811 passwd3
password 776:308/8 passwd4

33
examples/bforce.subst Normal file
View File

@ -0,0 +1,33 @@
#
# Example of overriding node with hidden lines:
# Override 1:2/3 Phone 123-1313 Worktime 21:00-07:00 \
# Hidden Phone 123-1314 Worktime 09:00-13:00 \
# Hidden Phone 123-1315 Worktime 09:00-21:00 \
# Hidden Phone 123-1316 Flags CM
#
# You may specify different time for different days of week:
# Override 1:2/3 Phone 123-1313 Worktime Wk20:00-07:30,We00:00-24:00
#
# Allowed day prefixes: Sun, Mon, Tue, Wed, Thu, Fri, Sat, Any, Wk, We
#
# To use BinkP protocol, write:
# Override 1:2/3 Ipaddr f3.n2.z1.fidonet.net Flags CM,BINKP
#
# If you want never call to certain node, write:
# Override 1:2/3 Phone Unpublished
#
# Happy
override 776:308/1 Ipaddr 192.168.1.1 Flags CM,IFC
override 776:308/1.1 Ipaddr 192.168.1.2 Flags CM,BINKP
# Estar
override 2:5020/758 Phone 961-2243
# Hard Core
override 2:5020/1398 Phone 700-0245 Worktime 00:00-07:00
# Stick's
override 2:5020/1682 Phone 308-5537 Worktime 23:30-07:00
override 2:5020/2120 Ipaddr 192.168.1.1 flags BINKP,CM

6
examples/freq.aliases Normal file
View File

@ -0,0 +1,6 @@
#
# <Alias> <File> [!<Password>]
#
#files /home/ftp/pub/info/happy.zip
#filelist /home/ftp/pub/info/happy.lst
#test /home/ftp/pub/fileecho/PNT5020/pnt5020.zip

10
examples/freq.dirs Normal file
View File

@ -0,0 +1,10 @@
#
# <Path> [!<Password>]
#
#/home/ftp/secure/doc/xxx.zip !fdsn02vz
#/home/ftp/pub/fileecho/AFTNMISC/
#/home/ftp/pub/fileecho/AVP/
#/home/ftp/pub/fileecho/LARRY.FILES/
#/home/ftp/pub/fileecho/MOBIL/
#/home/ftp/pub/fileecho/NET5020/

2
patch-stamp Normal file
View File

@ -0,0 +1,2 @@
Patches applied in the Debian version of :

70
rpm/bforce.spec Normal file
View File

@ -0,0 +1,70 @@
Summary: Bforce, Fidonet mailer
Name: bforce
Version: 0.22.8
Release: ugenk2
Copyright: GPL
Group: Fidonet/mailer
Source0: bforce-%{version}.%{release}.tar.gz
BuildRoot: %{_tmppath}/%{name}-root
%description
BFORCE is a FTN mailer. Supports PSTN and binkp sessions.
%prep
%setup -q -n %{name}-%{version}.%{release}
cd source
./configure --prefix=/usr --disable-log-passwd --sysconfdir=/etc/bforce --bindir=/usr/bin --with-owner=uucp --with-group=news
%build
cd source
make
%install
rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/etc/bforce
mkdir -p $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/usr/sbin
mkdir -p $RPM_BUILD_ROOT/var/log/bforce
mkdir -p $RPM_BUILD_ROOT/var/spool/fido/bt/pin
mkdir -p $RPM_BUILD_ROOT/var/spool/fido/bt/in
mkdir -p $RPM_BUILD_ROOT/var/spool/fido/ndl
mkdir -p $RPM_BUILD_ROOT/var/spool/fido/bforce
install -o uucp -g news source/bin/bforce $RPM_BUILD_ROOT/usr/bin/bforce
install -o uucp -g news source/bin/bfindex $RPM_BUILD_ROOT/usr/bin/bfindex
install -o uucp -g news source/bin/bfstat $RPM_BUILD_ROOT/usr/bin/bfstat
install -o uucp -g news source/bin/nlookup $RPM_BUILD_ROOT/usr/bin/nlookup
install -o uucp -g news examples/bforce.conf $RPM_BUILD_ROOT/etc/bforce/bforce.conf.sample
install -o uucp -g news examples/bforce.passwd $RPM_BUILD_ROOT/etc/bforce/bforce.passwd.sample
install -o uucp -g news examples/bforce.subst $RPM_BUILD_ROOT/etc/bforce/bforce.subst.sample
install -o uucp -g news examples/freq.aliases $RPM_BUILD_ROOT/etc/bforce/freq.aliases.sample
install -o uucp -g news examples/freq.dirs $RPM_BUILD_ROOT/etc/bforce/freq.dirs.sample
install -m755 -o uucp -g news contrib/outman $RPM_BUILD_ROOT/usr/bin/outman
%clean
rm -rf $RPM_BUILD_ROOT
%files
%doc README README.kst CHANGES CHANGES.kst COPYING INSTALL.ru README.ugenk
%attr(550,uucp,news) /usr/bin/bforce
%attr(550,uucp,news) /usr/bin/bfindex
%attr(550,uucp,news) /usr/bin/bfstat
%attr(550,uucp,news) /usr/bin/nlookup
%attr(550,uucp,news) /usr/bin/outman
%attr(644,root,root) /usr/share/doc/bforce-0.22.8/*
%dir %attr(770,uucp,news) /var/log/bforce
%dir %attr(770,uucp,news) /var/spool/fido/ndl
%attr(775,uucp,news) /var/spool/fido/bt
%config %attr(600,uucp,news) /etc/bforce/bforce.conf.sample
%config %attr(600,uucp,news) /etc/bforce/bforce.subst.sample
%config %attr(600,uucp,news) /etc/bforce/bforce.passwd.sample
%config %attr(600,uucp,news) /etc/bforce/freq.aliases.sample
%config %attr(600,uucp,news) /etc/bforce/freq.dirs.sample

31
rpm/buildrpm.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/sh
# 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.
RPMROOT='/home/ugenk/rpm'
if [ `whoami` != "root" ]; then
echo "$0: your must be root run this script."
exit 1
fi
cd ../source
make distclean
cd -
rm -f *.gz
tar -cvf bforce-`cat ../source/.version`.tar ../../bforce-`cat ../source/.version`/source/ ../../bforce-`cat ../source/.version`/CHANGES* ../../bforce-`cat ../source/.version`/COPYING ../../bforce-`cat ../source/.version`/INSTALL* ../../bforce-`cat ../source/.version`/README* ../../bforce-`cat ../source/.version`/SYSLOG ../../bforce-`cat ../source/.version`/TODO ../../bforce-`cat ../source/.version`/contrib ../../bforce-`cat ../source/.version`/examples ../../bforce-`cat ../source/.version`/debian
gzip bforce-`cat ../source/.version`.tar
cp -f bforce-`cat ../source/.version`.tar.gz $RPMROOT/SOURCES/
rpm -ba bforce.spec

1
source/.version Normal file
View File

@ -0,0 +1 @@
0.22.8.ugenk4

185
source/Makefile Normal file
View File

@ -0,0 +1,185 @@
#
# Copyright (c) 1999-2000, Alexander Belkin <adb@newmail.ru>
#
# $Id$
#
CC = gcc
INCLUDES = -I./include
CFLAGS = -g -O2
LIBS =
YACC = bison -y
INSTALL = /usr/bin/install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
SRCDIR = .
SRCDIRCONF = $(SRCDIR)/../examples
CONTRIBDIR = $(SRCDIR)/../contrib
OWNER = uucp
GROUP = news
CONFDIR = /usr/local/etc
BINDIR = /usr/local/bin
LOGDIR = /var/log/bforce
SPOOLDIR = /var/spool/bforce
DAEMON_LOGFILE = $(LOGDIR)/bf-daemon
BFORCE_LOGFILE = $(LOGDIR)/bf-log
BFORCE_DEBFILE = $(LOGDIR)/bf-debug
BFORCE_CFGFILE = $(CONFDIR)/bforce.conf
DEFINES = -DDAEMON_LOGFILE=\"$(DAEMON_LOGFILE)\" \
-DBFORCE_LOGFILE=\"$(BFORCE_LOGFILE)\" \
-DBFORCE_DEBFILE=\"$(BFORCE_DEBFILE)\" \
-DBFORCE_CFGFILE=\"$(BFORCE_CFGFILE)\" \
-DBF_OS=\"linux-gnu\" -DHAVE_CONFIG_H
SUBDIRS = bforce bfutil
BFINDEX_OBJS = bfutil/bfindex.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/logger.o bforce/nodelist.o \
bforce/u_file.o bforce/u_ftn.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o
NLOOKUP_OBJS = bfutil/nlookup.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/logger.o bforce/nodelist.o \
bforce/u_file.o bforce/u_ftn.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o
BFSTAT_OBJS = bfutil/bfstat.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/outb_flo.o bforce/outb_fsqueue.o \
bforce/sess_stat.o \
bforce/outb_getname.o bforce/outb_sysqueue.o \
bforce/outb_scan.o bforce/logger.o \
bforce/u_file.o \
bforce/u_ftn.o bforce/u_misc.o \
bforce/u_string.o bforce/u_time.o \
bforce/u_plock.o
BFORCE_OBJS = bforce/bforce.o \
bforce/daemon.o bforce/daemon_branch.o \
bforce/daemon_call.o bforce/daemon_lines.o \
bforce/conf_deinit.o \
bforce/conf_proc.o bforce/conf_read.o \
bforce/conf_get.o bforce/expression.o \
bforce/freq_bark.o bforce/freq_proc.o \
bforce/freq_srif.o bforce/freq_wazoo.o \
bforce/io_modem.o bforce/io_tcpip.o \
bforce/io_unix_lock.o bforce/io_unix_modem.o \
bforce/io_unix_tio.o bforce/io_unix_tty.o \
bforce/logger.o bforce/nodelist.o \
bforce/os_unix.o bforce/outb_bsy.o \
bforce/outb_flo.o bforce/outb_fsqueue.o \
bforce/outb_getname.o bforce/outb_sysqueue.o \
bforce/outb_scan.o bforce/prot_common.o \
bforce/prot_binkp.o bforce/prot_binkp_api.o \
bforce/prot_binkp_misc.o bforce/prot_hydra.o \
bforce/prot_xmrecv.o bforce/prot_xmsend.o \
bforce/prot_zmmisc.o bforce/prot_zmrecv.o \
bforce/prot_zmsend.o \
bforce/prot_yoohoo.o bforce/prot_yoohoo_api.o \
bforce/prot_emsi.o bforce/prot_emsi_misc.o \
bforce/prot_emsi_api.o \
bforce/sess_common.o bforce/sess_stat.o \
bforce/sess_call.o bforce/sess_answ.o \
bforce/sess_init.o bforce/sess_main.o \
bforce/u_crc.o bforce/u_ftn.o \
bforce/u_md5.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o bforce/u_file.o \
bforce/u_pkt.o bforce/u_recode.o \
bforce/u_plock.o
.c.o:
@echo Compiling $*.c
@$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@
all: bin/bforce bin/bfindex bin/bfstat bin/nlookup
expression.c: bforce/expression.y
$(YACC) bforce/expression.y
mv y.tab.c bforce/expression.c
bin/bforce: $(BFLIB_OBJS) $(BFORCE_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFORCE_OBJS) $(LIBS) -o $@
bin/bfindex: $(BFLIB_OBJS) $(BFINDEX_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFINDEX_OBJS) $(LIBS) -o $@
bin/nlookup: $(BFLIB_OBJS) $(NLOOKUP_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(NLOOKUP_OBJS) $(LIBS) -o $@
bin/bfstat: $(BFLIB_OBJS) $(BFSTAT_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFSTAT_OBJS) $(LIBS) -o $@
clean:
@for i in $(SUBDIRS); do (rm -f $$i/*.o || exit 1); done
rm -f ./bforce/expression.c
rm -f ./bin/bforce
rm -f ./bin/bfindex
rm -f ./bin/bfstat
rm -f ./bin/nlookup
rm -f ./bin/core
clean-am:
rm -f ./Makefile
rm -f ./include/config.h
rm -f ./config.log
rm -f ./config.status
clean-ac:
rm -f ./configure
distclean: clean clean-am
distclean-m: distclean clean-ac
ifnames:
@for i in $(SUBDIRS); do (ifnames $$i/*.c || exit 1); done
bforce/expression.y.o: bforce/expression.y.c bforce/expression.l.c
bforce/expression.l.o: bforce/expression.y.c bforce/expression.l.c
installdirs:
if [ ! -d $(CONFDIR) ]; then mkdir -p $(CONFDIR); fi
if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi
if [ ! -d $(LOGDIR) ]; then mkdir -p $(LOGDIR); fi
if [ ! -d $(SPOOLDIR) ]; then mkdir -p $(SPOOLDIR); fi
if [ ! -d $(SPOOLDIR)/bt/in ]; then mkdir -p $(SPOOLDIR)/bt/in; fi
if [ ! -d $(SPOOLDIR)/bt/pin ]; then mkdir -p $(SPOOLDIR)/bt/pin; fi
if [ ! -d $(SPOOLDIR)/bt/out ]; then mkdir -p $(SPOOLDIR)/bt/out; fi
if [ ! -d $(SPOOLDIR)/ndl ]; then mkdir -p $(SPOOLDIR)/ndl; fi
if [ ! -d $(SPOOLDIR)/bforce ]; then mkdir -p $(SPOOLDIR); fi
chown $(OWNER).$(GROUP) $(CONFDIR)
chown $(OWNER).$(GROUP) $(LOGDIR)
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/in
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/pin
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/out
chown $(OWNER).$(GROUP) $(SPOOLDIR)/ndl
chown $(OWNER).$(GROUP) $(SPOOLDIR)
install:
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bforce $(BINDIR)/bforce
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bfindex $(BINDIR)/bfindex
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bfstat $(BINDIR)/bfstat
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/nlookup $(BINDIR)/nlookup
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(CONTRIBDIR)/outman $(BINDIR)/outman
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.conf $(CONFDIR)/bforce.conf.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.subst $(CONFDIR)/bforce.subst.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.passwd $(CONFDIR)/bforce.passwd.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/freq.aliases $(CONFDIR)/freq.aliases.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/freq.dirs $(CONFDIR)/freq.dirs.sample
@echo "Please, edit $(BINDIR)/outman"

185
source/Makefile.in Normal file
View File

@ -0,0 +1,185 @@
#
# Copyright (c) 1999-2000, Alexander Belkin <adb@newmail.ru>
#
# $Id$
#
CC = @CC@
INCLUDES = -I./include
CFLAGS = @CFLAGS@
LIBS = @LIBS@
YACC = @YACC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
SRCDIR = @srcdir@
SRCDIRCONF = $(SRCDIR)/../examples
CONTRIBDIR = $(SRCDIR)/../contrib
OWNER = @OWNER@
GROUP = @GROUP@
CONFDIR = @prefix@/etc
BINDIR = @prefix@/bin
LOGDIR = /var/log/bforce
SPOOLDIR = /var/spool/bforce
DAEMON_LOGFILE = $(LOGDIR)/bf-daemon
BFORCE_LOGFILE = $(LOGDIR)/bf-log
BFORCE_DEBFILE = $(LOGDIR)/bf-debug
BFORCE_CFGFILE = $(CONFDIR)/bforce.conf
DEFINES = -DDAEMON_LOGFILE=\"$(DAEMON_LOGFILE)\" \
-DBFORCE_LOGFILE=\"$(BFORCE_LOGFILE)\" \
-DBFORCE_DEBFILE=\"$(BFORCE_DEBFILE)\" \
-DBFORCE_CFGFILE=\"$(BFORCE_CFGFILE)\" \
-DBF_OS=\"@build_os@\" @DEFS@
SUBDIRS = bforce bfutil
BFINDEX_OBJS = bfutil/bfindex.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/logger.o bforce/nodelist.o \
bforce/u_file.o bforce/u_ftn.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o
NLOOKUP_OBJS = bfutil/nlookup.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/logger.o bforce/nodelist.o \
bforce/u_file.o bforce/u_ftn.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o
BFSTAT_OBJS = bfutil/bfstat.o \
bforce/conf_deinit.o bforce/conf_proc.o \
bforce/conf_read.o bforce/conf_get.o \
bforce/outb_flo.o bforce/outb_fsqueue.o \
bforce/sess_stat.o \
bforce/outb_getname.o bforce/outb_sysqueue.o \
bforce/outb_scan.o bforce/logger.o \
bforce/u_file.o \
bforce/u_ftn.o bforce/u_misc.o \
bforce/u_string.o bforce/u_time.o \
bforce/u_plock.o
BFORCE_OBJS = bforce/bforce.o \
bforce/daemon.o bforce/daemon_branch.o \
bforce/daemon_call.o bforce/daemon_lines.o \
bforce/conf_deinit.o \
bforce/conf_proc.o bforce/conf_read.o \
bforce/conf_get.o bforce/expression.o \
bforce/freq_bark.o bforce/freq_proc.o \
bforce/freq_srif.o bforce/freq_wazoo.o \
bforce/io_modem.o bforce/io_tcpip.o \
bforce/io_unix_lock.o bforce/io_unix_modem.o \
bforce/io_unix_tio.o bforce/io_unix_tty.o \
bforce/logger.o bforce/nodelist.o \
bforce/os_unix.o bforce/outb_bsy.o \
bforce/outb_flo.o bforce/outb_fsqueue.o \
bforce/outb_getname.o bforce/outb_sysqueue.o \
bforce/outb_scan.o bforce/prot_common.o \
bforce/prot_binkp.o bforce/prot_binkp_api.o \
bforce/prot_binkp_misc.o bforce/prot_hydra.o \
bforce/prot_xmrecv.o bforce/prot_xmsend.o \
bforce/prot_zmmisc.o bforce/prot_zmrecv.o \
bforce/prot_zmsend.o \
bforce/prot_yoohoo.o bforce/prot_yoohoo_api.o \
bforce/prot_emsi.o bforce/prot_emsi_misc.o \
bforce/prot_emsi_api.o \
bforce/sess_common.o bforce/sess_stat.o \
bforce/sess_call.o bforce/sess_answ.o \
bforce/sess_init.o bforce/sess_main.o \
bforce/u_crc.o bforce/u_ftn.o \
bforce/u_md5.o \
bforce/u_misc.o bforce/u_string.o \
bforce/u_time.o bforce/u_file.o \
bforce/u_pkt.o bforce/u_recode.o \
bforce/u_plock.o
.c.o:
@echo Compiling $*.c
@$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c $< -o $@
all: bin/bforce bin/bfindex bin/bfstat bin/nlookup
expression.c: bforce/expression.y
$(YACC) bforce/expression.y
mv y.tab.c bforce/expression.c
bin/bforce: $(BFLIB_OBJS) $(BFORCE_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFORCE_OBJS) $(LIBS) -o $@
bin/bfindex: $(BFLIB_OBJS) $(BFINDEX_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFINDEX_OBJS) $(LIBS) -o $@
bin/nlookup: $(BFLIB_OBJS) $(NLOOKUP_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(NLOOKUP_OBJS) $(LIBS) -o $@
bin/bfstat: $(BFLIB_OBJS) $(BFSTAT_OBJS)
@echo "Linking $@"
@$(CC) $(BFLIB_OBJS) $(BFSTAT_OBJS) $(LIBS) -o $@
clean:
@for i in $(SUBDIRS); do (rm -f $$i/*.o || exit 1); done
rm -f ./bforce/expression.c
rm -f ./bin/bforce
rm -f ./bin/bfindex
rm -f ./bin/bfstat
rm -f ./bin/nlookup
rm -f ./bin/core
clean-am:
rm -f ./Makefile
rm -f ./include/config.h
rm -f ./config.log
rm -f ./config.status
clean-ac:
rm -f ./configure
distclean: clean clean-am
distclean-m: distclean clean-ac
ifnames:
@for i in $(SUBDIRS); do (ifnames $$i/*.c || exit 1); done
bforce/expression.y.o: bforce/expression.y.c bforce/expression.l.c
bforce/expression.l.o: bforce/expression.y.c bforce/expression.l.c
installdirs:
if [ ! -d $(CONFDIR) ]; then mkdir -p $(CONFDIR); fi
if [ ! -d $(BINDIR) ]; then mkdir -p $(BINDIR); fi
if [ ! -d $(LOGDIR) ]; then mkdir -p $(LOGDIR); fi
if [ ! -d $(SPOOLDIR) ]; then mkdir -p $(SPOOLDIR); fi
if [ ! -d $(SPOOLDIR)/bt/in ]; then mkdir -p $(SPOOLDIR)/bt/in; fi
if [ ! -d $(SPOOLDIR)/bt/pin ]; then mkdir -p $(SPOOLDIR)/bt/pin; fi
if [ ! -d $(SPOOLDIR)/bt/out ]; then mkdir -p $(SPOOLDIR)/bt/out; fi
if [ ! -d $(SPOOLDIR)/ndl ]; then mkdir -p $(SPOOLDIR)/ndl; fi
if [ ! -d $(SPOOLDIR)/bforce ]; then mkdir -p $(SPOOLDIR); fi
chown $(OWNER).$(GROUP) $(CONFDIR)
chown $(OWNER).$(GROUP) $(LOGDIR)
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/in
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/pin
chown $(OWNER).$(GROUP) $(SPOOLDIR)/bt/out
chown $(OWNER).$(GROUP) $(SPOOLDIR)/ndl
chown $(OWNER).$(GROUP) $(SPOOLDIR)
install:
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bforce $(BINDIR)/bforce
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bfindex $(BINDIR)/bfindex
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/bfstat $(BINDIR)/bfstat
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(SRCDIR)/bin/nlookup $(BINDIR)/nlookup
$(INSTALL_PROGRAM) -o $(OWNER) -g $(GROUP) $(CONTRIBDIR)/outman $(BINDIR)/outman
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.conf $(CONFDIR)/bforce.conf.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.subst $(CONFDIR)/bforce.subst.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/bforce.passwd $(CONFDIR)/bforce.passwd.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/freq.aliases $(CONFDIR)/freq.aliases.sample
$(INSTALL_DATA) -o $(OWNER) -g $(GROUP) $(SRCDIRCONF)/freq.dirs $(CONFDIR)/freq.dirs.sample
@echo "Please, edit $(BINDIR)/outman"

485
source/bforce/bforce.c Normal file
View File

@ -0,0 +1,485 @@
/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* 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.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "version.h"
#include "logger.h"
#include "util.h"
#include "bforce.h"
#include "nodelist.h"
#include "session.h"
/* PID of our child process (if use fork) */
pid_t child_pid = 0;
const char *BFERR[] = {
/* 00 */ "Successfull",
/* 01 */ "Fatal error occured",
/* 02 */ "Unknown phone number(or ip address)",
/* 03 */ "Modem port busy (or open error)",
/* 04 */ "System locked now",
/* 05 */ "Try later",
/* 06 */ "Modem not response",
/* 07 */ "Not working now",
/* 08 */ "Unused entry",
/* 09 */ "Unused entry",
/* 10 */ "Can't connect to remote",
/* 11 */ "Can't connect to remote: busy",
/* 12 */ "Can't connect to remote: nocarrier",
/* 13 */ "Can't connect to remote: nodialtone",
/* 14 */ "Can't connect to remote: noanswer",
/* 15 */ "Can't connect to remote: error",
/* 16 */ "Can't connect to remote: user defined 16",
/* 17 */ "Can't connect to remote: user defined 17",
/* 18 */ "Can't connect to remote: user defined 18",
/* 19 */ "Can't connect to remote: user defined 19",
/* 20 */ "Connect speed too low",
/* 21 */ "Cannot handshake with remote",
/* 22 */ "Xmiting error",
/* 23 */ "CPS too low",
/* 24 */ "Reached stop time",
/* 25 */ "Unused entry",
/* 26 */ "Unused entry",
/* 27 */ "Unused entry"
};
static void deinit_opts(s_bforce_opts *opts);
/*
static void print_compiled_configuration(void)
{
printf("BFORCE_LOGFILE = "BFORCE_LOGFILE"\n");
printf("BFORCE_DEBFILE = "BFORCE_DEBFILE"\n");
printf("DAEMON_LOGFILE = "DAEMON_LOGFILE"\n");
printf("BFORCE_CFGFILE = "BFORCE_CFGFILE"\n");
printf("BF_OS = "BF_OS"\n");
}
*/
static void usage(void)
{
printf_usage(NULL,
"usage: bforce [-fmh] [-I<include>] [-n<phone>] [-l<line_number>]\n"
" [-a<ip_address>] [-S<connect>] [-p<device>] <node>\n"
" bforce [-ih] [-I<include>] [-S<connect>]\n"
" <tsync|yoohoo|emsi|binkp|auto> (this implies slave mode)\n"
" bforce [-dh] [-C<config>] [-I<include>]\n"
"\n"
"options:\n"
" -d run as daemon\n"
" -q terminate daemon\n"
" -i run from inetd (for slave mode only)\n"
" -f ignore system's work time\n"
" -o starts outgoing session on stdin/stdout\n"
" -C <config> main config file name (\"%s\")\n"
" -I <config> additional config file name\n"
" -n <phone> override phone number\n"
" -l <line_number> call on this hidden line (default is 0) \n"
" -a <ip_address> override internet address\n"
" -S <connect_str> connect string (for slave mode only)\n"
" -p <port> override modem port (must be defined in config)\n"
" -h show this help message\n"
"\n",
conf_getconfname()
);
}
int bforce_create_dirs(void)
{
const char *p_dirname = conf_string(cf_status_directory);
if( p_dirname )
{
if( access(p_dirname, F_OK) == -1 || !is_directory(p_dirname) )
{
if( directory_create(p_dirname, 0700) == -1 )
{
logerr("cannot create spool directory \"%s\"", p_dirname);
return -1;
}
}
}
return 0;
}
/*
* Universal signal handler for parent processes :) Will resend
* signals to child process
*/
static RETSIGTYPE parent_sighandler(int sig)
{
/* Send this signal to our child */
if( child_pid ) kill(child_pid, sig);
}
/*
* Return non-zero value to indicate error, on success - return zero
* to child process and NEVER return to parent process
*/
static int usefork(void)
{
pid_t cpid; /* child PID */
pid_t wpid; /* waitpid() returned value */
int status = 0;
cpid = fork();
if( cpid == 0 )
{ return 0; }
if( cpid < 0 )
{ logerr("failed fork() call"); return 1; }
/*
* Now we are parent process
*/
/* Put PID into global variable */
child_pid = cpid;
/* Setup signals handling */
signal(SIGHUP, parent_sighandler);
signal(SIGINT, parent_sighandler);
signal(SIGTERM, parent_sighandler);
signal(SIGUSR1, parent_sighandler);
signal(SIGUSR2, parent_sighandler);
/* Wait until child die */
while( (wpid = waitpid(cpid, &status, 0)) < 0 && errno == EINTR )
{
/* EMPTY LOOP */
}
if( wpid == cpid && WIFEXITED(status) )
{
/* Child was terminated with _exit() */
exit(WEXITSTATUS(status));
}
else if( wpid < 0 && WIFSIGNALED(status) )
{
/* Child was terminated by signal */
kill(getpid(), WTERMSIG(status));
}
exit(BFERR_FATALERROR);
}
static int bforce_master(const s_bforce_opts *opts)
{
s_falist *tmpl;
int rc, maxrc = BFERR_NOERROR;
#ifdef GETPGRP_VOID
if( getpgrp() == getpid() )
#else
if( getpgrp(0) == getpid() )
#endif
{
/* We are process group leader -> fork() */
if( usefork() ) return BFERR_FATALERROR;
}
for( tmpl = opts->addrlist; tmpl; tmpl = tmpl->next )
{
int callopt = 0;
if( opts->iaddr ) callopt |= CALLOPT_INET;
if( opts->force ) callopt |= CALLOPT_FORCE;
rc = call_system(tmpl->addr, opts);
if( rc > maxrc ) maxrc = rc;
}
return maxrc;
}
static int bforce_slave(const s_bforce_opts *opts)
{
return answ_system(opts->stype, opts->connect, opts->inetd);
}
static int bforce_daemon(const s_bforce_opts *opts)
{
int forkrc = fork();
if( forkrc == -1 )
{
logerr("cannot run daemon: failed fork() call");
return BFERR_FATALERROR;
}
else if( forkrc > 0 )
{
return BFERR_NOERROR;
}
/*
* We are inside a child process.
* Create new session and run daemon
*/
setsid();
return daemon_run(opts->confname, opts->incname, opts->quit);
}
int main(int argc, char *argv[], char *envp[])
{
s_bforce_opts opts;
int rc = 0;
int ch = 0;
int role = 0;
memset(&opts, '\0', sizeof(s_bforce_opts));
while( (ch=getopt(argc, argv, "hodqr:ifC:I:n:l:a:S:p:")) != EOF )
{
switch( ch ) {
case 'h':
usage();
exit(BFERR_NOERROR);
case 'd':
if( opts.inetd || opts.force || opts.phone
|| opts.hiddline || opts.iaddr || opts.connect
|| opts.device || opts.quit )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.daemon = 1; }
break;
case 'q':
if( opts.inetd || opts.force || opts.phone
|| opts.hiddline || opts.iaddr || opts.connect
|| opts.device || opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.daemon = 1; opts.quit = 1; }
break;
case 'i':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.inetd = 1; }
break;
case 'f':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.force = 1; }
break;
case 'o':
if( opts.dontcall )
{ usage(); exit(BFERR_FATALERROR); }
else
{ opts.dontcall = TRUE; }
break;
case 'C':
if( opts.confname ) free(opts.confname);
if( optarg ) opts.confname = (char *)xstrcpy(optarg);
break;
case 'I':
if( opts.incname ) free(opts.incname);
if( optarg ) opts.incname = (char *)xstrcpy(optarg);
break;
case 'n':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{
if( opts.phone ) free(opts.phone);
if( optarg ) opts.phone = (char *)xstrcpy(optarg);
}
break;
case 'l':
if( ISDEC(optarg) && opts.daemon == 0 )
opts.hiddline = atoi(optarg);
else
{ usage(); exit(BFERR_FATALERROR); }
break;
case 'a':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{
if( opts.iaddr ) free(opts.iaddr);
if( optarg ) opts.iaddr = (char *)xstrcpy(optarg);
}
break;
case 'S':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{
if( opts.connect ) free(opts.connect);
if( optarg ) opts.connect = (char *)xstrcpy(optarg);
}
break;
case 'p':
if( opts.daemon )
{ usage(); exit(BFERR_FATALERROR); }
else
{
if( opts.device ) free(opts.device);
if( optarg ) opts.device = (char *)xstrcpy(optarg);
}
break;
default :
usage();
exit(BFERR_FATALERROR);
}
}
/* Expression checker use it, so init first */
init_state(&state);
/* Set space available for process title */
#ifndef HAVE_SETPROCTITLE
setargspace(argv, envp);
#endif
/* Initialise random number generation */
(void)srand((unsigned)time(NULL));
/* Initialise current locale */
(void)setlocale(LC_ALL, "");
/* Set secure process umask */
(void)umask(~(S_IRUSR|S_IWUSR));
/* Now process non-option arguments */
if( opts.daemon == FALSE )
{
const char *p;
s_faddr addr;
s_falist **alist = &opts.addrlist;
while( (optind < argc) && (p = argv[optind++]) )
{
for( ; *p == '*'; p++ );
if( strcasecmp(p, "tsync") == 0 )
{
role = 0;
opts.stype = SESSION_FTSC;
}
else if( strcasecmp(p, "yoohoo") == 0 )
{
role = 0;
opts.stype = SESSION_YOOHOO;
}
else if( strcasecmp(p, "**EMSI_INQC816") == 0 )
{
role = 0;
opts.stype = SESSION_EMSI;
}
else if( strncasecmp(p, "emsi", 4) == 0 )
{
role = 0;
opts.stype = SESSION_EMSI;
}
else if( strcasecmp(p, "binkp") == 0 )
{
role = 0;
opts.stype = SESSION_BINKP;
}
else if( strcasecmp(p, "auto") == 0 )
{
role = 0;
opts.stype = SESSION_UNKNOWN;
}
else if( ftn_addrparse(&addr, p, FALSE) == 0 )
{
role = 1;
(*alist) = (s_falist*)xmalloc(sizeof(s_falist));
memset(*alist, '\0', sizeof(s_falist));
(*alist)->addr = addr;
alist = &(*alist)->next;
}
else
{
printf("invalid address \"%s\"", p);
usage();
exit(BFERR_FATALERROR);
}
}
if( opts.dontcall && role == 0 )
{
usage();
exit(BFERR_FATALERROR);
}
}
/* if( (rc = log_open(log_getfilename(LOG_FILE_SESSION), NULL, NULL)) )
{
log("can't continue without logging");
gotoexit(BFERR_FATALERROR);
}
*/
/* Process primary config file */
if( opts.confname && *opts.confname )
rc = conf_readconf(opts.confname, 0);
else
rc = conf_readconf(conf_getconfname(), 0);
if( rc ) gotoexit(BFERR_FATALERROR);
/* Process additional config file, ignore errors */
if( opts.incname && *opts.incname )
(void)conf_readconf(opts.incname, 1);
/* Reopen log file if it was defined in config */
if( log_open(log_getfilename(LOG_FILE_SESSION), NULL, NULL) )
{
log("can't continue without logging");
gotoexit(BFERR_FATALERROR);
}
#ifdef DEBUG
/* Same for the debug file */
(void)debug_setfilename(log_getfilename(LOG_FILE_DEBUG));
#endif
if( opts.daemon )
rc = bforce_daemon(&opts);
else if( role )
rc = bforce_master(&opts);
else
rc = bforce_slave(&opts);
exit:
deinit_conf();
deinit_opts(&opts);
/* Shutdown logging services */
if( log_isopened() ) log_close();
#ifdef DEBUG
if( debug_isopened() ) debug_close();
#endif
exit(rc);
}
static void deinit_opts(s_bforce_opts *opts)
{
if( opts->confname ) free(opts->confname);
if( opts->incname ) free(opts->incname);
if( opts->phone ) free(opts->phone);
if( opts->iaddr ) free(opts->iaddr);
if( opts->connect ) free(opts->connect);
if( opts->device ) free(opts->device);
if( opts->addrlist ) deinit_falist(opts->addrlist);
memset(opts, '\0', sizeof(s_bforce_opts));
}

135
source/bforce/conf_deinit.c Normal file
View File

@ -0,0 +1,135 @@
/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* 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.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "logger.h"
#include "util.h"
void deinit_conf(void)
{
s_cval_entry *ptrl;
s_cval_entry *next;
int i;
for( i = 0; bforce_config[i].name; i++ )
{
for( ptrl = bforce_config[i].data; ptrl; ptrl = next )
{
next = ptrl->next;
deinit_cval_entry(ptrl, bforce_config[i].type);
free(ptrl);
}
bforce_config[i].data = NULL;
}
}
void deinit_cval_entry(s_cval_entry *dest, bforce_config_keyword type)
{
/*
* Other config variables doesn't use allocated memory
*/
switch(type) {
case CT_ADDRESS:
case CT_NODELIST:
case CT_PASSWORD:
if( dest->d.falist.what )
free(dest->d.falist.what);
break;
case CT_DOMAIN:
deinit_domain(&dest->d.domain);
break;
case CT_DIALRESP:
deinit_dialresp(&dest->d.dialresp);
break;
case CT_MODEMPORT:
deinit_modemport(&dest->d.modemport);
break;
case CT_OVERRIDE:
deinit_override(&dest->d.override);
break;
case CT_PATH:
case CT_STRING:
deinit_string(&dest->d.string);
break;
case CT_TRANSLATE:
deinit_translate(&dest->d.translate);
break;
default:
DEB((D_CONFIG, "deinit_cval_entry: type %d doesn't use dynamic memory",
type));
}
}
void deinit_dialresp(s_dialresp *dest)
{
if( dest->mstr ) free(dest->mstr);
}
void deinit_domain(s_domain *dest)
{
if( dest->domain ) free(dest->domain);
if( dest->path ) free(dest->path);
}
void deinit_expr(s_expr *dest)
{
if( dest->expr ) free(dest->expr);
}
void deinit_falist(s_falist *dest)
{
s_falist *ptrl, *next;
for( ptrl = dest; ptrl; ptrl = next )
{
next = ptrl->next;
if( ptrl->what ) free(ptrl->what);
free(ptrl);
}
}
void deinit_modemport(s_modemport *dest)
{
if( dest->name ) free(dest->name);
}
void deinit_override(s_override *dest)
{
s_override *ptrl, *next;
if( dest->sIpaddr ) free(dest->sIpaddr);
if( dest->sPhone ) free(dest->sPhone);
if( dest->sFlags ) free(dest->sFlags);
for( ptrl = dest->hidden; ptrl; ptrl = next )
{
next = ptrl->hidden;
if( ptrl->sIpaddr ) free(ptrl->sIpaddr);
if( ptrl->sPhone ) free(ptrl->sPhone);
if( ptrl->sFlags ) free(ptrl->sFlags);
free(ptrl);
}
}
void deinit_string(s_string *dest)
{
if( dest->str ) free(dest->str);
}
void deinit_translate(s_translate *dest)
{
if( dest->find ) free(dest->find);
if( dest->repl ) free(dest->repl);
}

108
source/bforce/conf_get.c Normal file
View File

@ -0,0 +1,108 @@
/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* 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.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "logger.h"
#include "util.h"
s_cval_entry *conf_first(bforce_config_keyword keyword)
{
s_cval_entry *ptrl;
for( ptrl = bforce_config[keyword].data; ptrl; ptrl = ptrl->next )
if( !ptrl->expr.expr || eventexpr(&ptrl->expr) )
return ptrl;
return NULL;
}
s_cval_entry *conf_next(s_cval_entry *ptrl)
{
ASSERT(ptrl);
for( ptrl = ptrl->next; ptrl; ptrl = ptrl->next )
if( !ptrl->expr.expr || eventexpr(&ptrl->expr) )
return ptrl;
return NULL;
}
bool conf_boolean(bforce_config_keyword keyword)
{
s_cval_entry *ptrl = conf_first(keyword);
return ptrl ? ptrl->d.boolean.istrue : FALSE;
}
mode_t conf_filemode(bforce_config_keyword keyword)
{
s_cval_entry *ptrl = conf_first(keyword);
return ptrl ? ptrl->d.filemode.mode : (mode_t)0;
}
long conf_options(bforce_config_keyword keyword)
{
long result = 0L;
s_cval_entry *ptrl;
for( ptrl = conf_first(keyword); ptrl; ptrl = conf_next(ptrl) )
result = ((~ptrl->d.options.mask) & result) | ptrl->d.options.value;
return result;
}
long conf_connlist(bforce_config_keyword keyword, long speed)
{
s_cval_entry *ptrl;
for( ptrl = conf_first(keyword); ptrl; ptrl = conf_next(ptrl) )
if( ptrl->d.connlist.speed == speed )
return ptrl->d.connlist.value;
return 0;
}
char *conf_string(bforce_config_keyword keyword)
{
s_cval_entry *ptrl = conf_first(keyword);
return ptrl ? ptrl->d.string.str : (char*)NULL;
}
long conf_number(bforce_config_keyword keyword)
{
s_cval_entry *ptrl = conf_first(keyword);
return ptrl ? ptrl->d.number.num : (long)0L;
}
s_override *conf_override(bforce_config_keyword keyword, s_faddr addr)
{
s_cval_entry *ptrl;
for( ptrl = conf_first(keyword); ptrl; ptrl = conf_next(ptrl) )
if( !ftn_addrcomp(ptrl->d.override.addr, addr) )
return &ptrl->d.override;
return NULL;
}
s_tries *conf_tries(bforce_config_keyword keyword)
{
s_cval_entry *ptrl = conf_first(keyword);
return ptrl ? &ptrl->d.tries : NULL;
}

997
source/bforce/conf_proc.c Normal file
View File

@ -0,0 +1,997 @@
/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* 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.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "logger.h"
#include "util.h"
#include "outbound.h" /* Required only for ``proc_filebox()'' */
struct tab_options {
const char *keystr;
unsigned long value_no;
unsigned long value_yes;
} options[] = {
{ "Zmodem", OPTIONS_NO_ZMODEM, 0 },
{ "ZedZap", OPTIONS_NO_ZEDZAP, 0 },
{ "DirZap", OPTIONS_NO_DIRZAP, 0 },
{ "Janus", OPTIONS_NO_JANUS, 0 },
{ "Hydra", OPTIONS_NO_HYDRA, 0 },
{ "BinkP", OPTIONS_NO_BINKP, 0 },
{ "TCP", OPTIONS_NO_TCP, 0 },
{ "Chat", OPTIONS_NO_CHAT, 0 },
{ "FTS1", OPTIONS_NO_FTS1, 0 },
{ "YooHoo", OPTIONS_NO_YOOHOO, 0 },
{ "EMSI", OPTIONS_NO_EMSI, 0 },
{ "EMSI-II", OPTIONS_NO_EMSI_II, 0 },
{ "Freqs", OPTIONS_NO_FREQS, 0 },
{ "MailOnly", 0, OPTIONS_MAILONLY },
{ "HoldXT" , 0, OPTIONS_HOLDXT },
{ "HoldReq", 0, OPTIONS_HOLDREQ },
{ "HoldAll", 0, OPTIONS_HOLDALL },
{ "HoldHold", 0, OPTIONS_HOLDHOLD },
{ "PickUp", OPTIONS_NO_PICKUP, 0 },
{ "RH1", OPTIONS_NO_RH1, 0 },
{ "Intro", OPTIONS_NO_INTRO, 0 },
{ NULL, 0, 0 }
};
struct tab_resptypes {
const char *str;
int value;
int retv;
} resptypes[] = {
{ "Connect", RESPTYPE_CONNECT, 0 },
{ "Busy", RESPTYPE_BUSY, 11 },
{ "Nocarrier", RESPTYPE_NOCARRIER, 12 },
{ "Nodialtone", RESPTYPE_NODIALTONE, 13 },
{ "Noanswer", RESPTYPE_NOANSWER, 14 },
{ "Error", RESPTYPE_ERROR, 15 },
{ NULL, 0, 0 }
};
#define CONF_KEY(name, type) { #name, type, NULL, cf_##name }
#define CONF_END() { NULL, 0, NULL, 0 }
s_conf_entry bforce_config[BFORCE_NUMBER_OF_KEYWORDS+1] = {
CONF_KEY(address, CT_ADDRESS),
CONF_KEY(amiga_outbound_directory, CT_PATH),
CONF_KEY(binkp_timeout, CT_NUMBER),
CONF_KEY(daemon_circle, CT_NUMBER),
CONF_KEY(daemon_circle_crash, CT_NUMBER),
CONF_KEY(daemon_circle_direct, CT_NUMBER),
CONF_KEY(daemon_circle_immed, CT_NUMBER),
CONF_KEY(daemon_circle_modem, CT_NUMBER),
CONF_KEY(daemon_circle_normal, CT_NUMBER),
CONF_KEY(daemon_circle_rescan, CT_NUMBER),
CONF_KEY(daemon_maxclients_modem, CT_NUMBER),
CONF_KEY(daemon_maxclients_tcpip, CT_NUMBER),
CONF_KEY(daemon_pid_file, CT_STRING),
CONF_KEY(delay_files_recv, CT_STRING),
CONF_KEY(delay_files_send, CT_STRING),
CONF_KEY(disable_aka_matching, CT_BOOLEAN),
CONF_KEY(domain, CT_DOMAIN),
CONF_KEY(emsi_FR_time, CT_STRING),
CONF_KEY(emsi_OH_time, CT_STRING),
CONF_KEY(emsi_slave_sends_nak, CT_BOOLEAN),
CONF_KEY(filebox, CT_FILEBOX),
CONF_KEY(filebox_directory, CT_PATH),
CONF_KEY(flags, CT_STRING),
CONF_KEY(flo_translate, CT_TRANSLATE),
CONF_KEY(freq_alias_list, CT_STRING),
CONF_KEY(freq_dir_list, CT_STRING),
CONF_KEY(freq_ignore_masks, CT_STRING),
CONF_KEY(freq_limit_number, CT_NUMBER),
CONF_KEY(freq_limit_size, CT_NUMBER),
CONF_KEY(freq_limit_time, CT_NUMBER),
CONF_KEY(freq_min_speed, CT_NUMBER),
CONF_KEY(freq_srif_command, CT_STRING),
CONF_KEY(hide_our_aka, CT_ADDRESS),
CONF_KEY(history_file, CT_STRING),
CONF_KEY(hydra_options, CT_OPTIONS),
CONF_KEY(hydra_mincps_recv, CT_CONNLIST),
CONF_KEY(hydra_mincps_send, CT_CONNLIST),
CONF_KEY(hydra_tx_window, CT_NUMBER),
CONF_KEY(hydra_rx_window, CT_NUMBER),
CONF_KEY(inbound_directory, CT_PATH),
CONF_KEY(location, CT_STRING),
CONF_KEY(log_file, CT_STRING),
CONF_KEY(log_file_daemon, CT_STRING),
CONF_KEY(max_speed, CT_NUMBER),
CONF_KEY(maxtries, CT_TRIES),
CONF_KEY(maxtries_nodial, CT_TRIES),
CONF_KEY(maxtries_noansw, CT_TRIES),
CONF_KEY(maxtries_noconn, CT_TRIES),
CONF_KEY(maxtries_hshake, CT_TRIES),
CONF_KEY(maxtries_sessions, CT_TRIES),
CONF_KEY(min_cps_recv, CT_NUMBER),
CONF_KEY(min_cps_send, CT_NUMBER),
CONF_KEY(min_cps_time, CT_NUMBER),
CONF_KEY(min_free_space, CT_NUMBER),
CONF_KEY(min_speed_in, CT_NUMBER),
CONF_KEY(min_speed_out, CT_NUMBER),
CONF_KEY(mode_netmail, CT_FILEMODE),
CONF_KEY(mode_arcmail, CT_FILEMODE),
CONF_KEY(mode_request, CT_FILEMODE),
CONF_KEY(mode_ticfile, CT_FILEMODE),
CONF_KEY(mode_default, CT_FILEMODE),
CONF_KEY(modem_can_send_break, CT_BOOLEAN),
CONF_KEY(modem_dial_prefix, CT_STRING),
CONF_KEY(modem_dial_suffix, CT_STRING),
CONF_KEY(modem_dial_response, CT_DIALRESP),
CONF_KEY(modem_hangup_command, CT_STRING),
CONF_KEY(modem_port, CT_MODEMPORT),
CONF_KEY(modem_reset_command, CT_STRING),
CONF_KEY(modem_stat_command, CT_STRING),
CONF_KEY(nodelist, CT_NODELIST),
CONF_KEY(nodelist_directory, CT_PATH),
CONF_KEY(nodial_flag, CT_STRING),
CONF_KEY(override, CT_OVERRIDE),
CONF_KEY(options, CT_OPTIONS),
CONF_KEY(outbound_directory, CT_PATH),
CONF_KEY(password, CT_PASSWORD),
CONF_KEY(phone, CT_STRING),
CONF_KEY(phone_translate, CT_TRANSLATE),
CONF_KEY(recode_file_in, CT_STRING),
CONF_KEY(recode_file_out, CT_STRING),
CONF_KEY(recode_intro_in, CT_STRING),
CONF_KEY(recv_buffer_size, CT_NUMBER),
CONF_KEY(rescan_delay, CT_NUMBER),
CONF_KEY(run_after_handshake, CT_STRING),
CONF_KEY(run_after_session, CT_STRING),
CONF_KEY(session_limit_in, CT_NUMBER),
CONF_KEY(session_limit_out, CT_NUMBER),
CONF_KEY(skip_files_recv, CT_STRING),
CONF_KEY(status_directory, CT_PATH),
CONF_KEY(system_name, CT_STRING),
CONF_KEY(sysop_name, CT_STRING),
CONF_KEY(uucp_lock_directory, CT_PATH),
CONF_KEY(wait_carrier_in, CT_NUMBER),
CONF_KEY(wait_carrier_out, CT_NUMBER),
CONF_KEY(zmodem_mincps_recv, CT_CONNLIST),
CONF_KEY(zmodem_mincps_send, CT_CONNLIST),
CONF_KEY(zmodem_send_dummy_pkt, CT_BOOLEAN),
CONF_KEY(zmodem_skip_by_pos, CT_BOOLEAN),
CONF_KEY(zmodem_start_block_size, CT_NUMBER),
CONF_KEY(zmodem_tx_window, CT_NUMBER),
CONF_KEY(nomail_flag, CT_STRING),
CONF_KEY(bind_ip, CT_STRING),
#ifdef USE_SYSLOG
CONF_KEY(syslog_facility, CT_NUMBER),
#endif
#ifdef DEBUG
CONF_KEY(debug_file, CT_STRING),
CONF_KEY(debug_level, CT_DEBLEVEL),
#endif
CONF_END()
};
static int proc_override(s_override *dest, char *value);
static int proc_options(s_options *options, char *value);
static int proc_string(s_string *dest, char *value);
static int proc_number(s_number *dest, char *value);
static int proc_filemode(s_filemode *dest, char *value);
static int proc_boolean(s_boolean *dest, char *value);
static int proc_address(s_falist *dest, char *value);
static int proc_nodelist(s_falist *dest, char *value);
static int proc_modemport(s_modemport *dest, char *value);
static int proc_domain(s_domain *dest, char *value);
static int proc_password(s_falist *dest, char *value);
static int proc_path(s_string *dest, char *value);
static int proc_dialresp(s_dialresp *dest, char *value);
static int proc_translate(s_translate *dest, char *value);
static int proc_speeddep(s_connlist *dest, char *value);
static int proc_tries(s_tries *dest, char *value);
#ifdef DEBUG
static int proc_debuglevel(s_number *dest, char *value);
#endif
static int proc_filebox(s_filebox *dest, char *value);
static int append_config_entry(s_conf_entry *conf_ent, s_cval_entry *cval_entry)
{
s_cval_entry **ptrl;
for( ptrl = &conf_ent->data; *ptrl; ptrl = &(*ptrl)->next );
*ptrl = (s_cval_entry *)xmalloc(sizeof(s_cval_entry));
memcpy(*ptrl, cval_entry, sizeof(s_cval_entry));
return 0;
}
int proc_configline(const char *k, const char *e, const char *v)
{
s_cval_entry temp_value;
int rc = PROC_RC_ABORT;
int i;
char *copy;
ASSERT(k != NULL && v != NULL );
DEB((D_CONFIG, "conf_proc: key \"%s\" expr \"%s\" value \"%s\"",
k, e, v));
copy = xstrcpy(v);
for( i = 0; bforce_config[i].name; i++ )
if( !strcmp(bforce_config[i].name, k) )
break;
if( bforce_config[i].name )
{
/*
* Make all changes in temp_value structure
*/
memset(&temp_value, '\0', sizeof(s_cval_entry));
switch(bforce_config[i].type) {
case CT_ADDRESS:
rc = proc_address(&temp_value.d.falist, copy);
break;
case CT_BOOLEAN:
rc = proc_boolean(&temp_value.d.boolean, copy);
break;
case CT_CONNLIST:
rc = proc_speeddep(&temp_value.d.connlist, copy);
break;
case CT_DIALRESP:
rc = proc_dialresp(&temp_value.d.dialresp, copy);
break;
case CT_DOMAIN:
rc = proc_domain(&temp_value.d.domain, copy);
break;
case CT_FILEMODE:
rc = proc_filemode(&temp_value.d.filemode, copy);
break;
case CT_MODEMPORT:
rc = proc_modemport(&temp_value.d.modemport, copy);
break;
case CT_NODELIST:
rc = proc_nodelist(&temp_value.d.falist, copy);
break;
case CT_NUMBER:
rc = proc_number(&temp_value.d.number, copy);
break;
case CT_OPTIONS:
rc = proc_options(&temp_value.d.options, copy);
break;
case CT_OVERRIDE:
rc = proc_override(&temp_value.d.override, copy);
break;
case CT_PATH:
rc = proc_path(&temp_value.d.string, copy);
break;
case CT_PASSWORD:
rc = proc_password(&temp_value.d.falist, copy);
break;
case CT_STRING:
rc = proc_string(&temp_value.d.string, copy);
break;
case CT_TRANSLATE:
rc = proc_translate(&temp_value.d.translate, copy);
break;
case CT_TRIES:
rc = proc_tries(&temp_value.d.tries, copy);
break;
#ifdef DEBUG
case CT_DEBLEVEL:
rc = proc_debuglevel(&temp_value.d.number, copy);
break;
#endif
case CT_FILEBOX:
rc = proc_filebox(&temp_value.d.filebox, copy);
break;
default:
log("internal error, unknown keyword type = %d",
bforce_config[i].type);
ASSERT(0);
}
if( rc == PROC_RC_OK || rc == PROC_RC_WARN )
{
if( e && *e )
{
temp_value.expr.expr = xstrcpy(e);
temp_value.expr.error = 0;
}
append_config_entry(&bforce_config[i], &temp_value);
}
}
else
{
log("unknown keyword \"%s\"", k);
rc = PROC_RC_IGNORE;
}
free(copy);
return rc;
}
/*
* Line format: Override <Address> <Overrides..> [Hidden <Overrides>]
*/
static int proc_override(s_override *dest, char *value)
{
s_override **p = &dest;
s_faddr addr;
int rc = PROC_RC_OK;
char *key = NULL;
char *arg = NULL;
char *n = NULL;
char *p_addr = NULL;
bool neednew = FALSE;
ASSERT(dest != NULL && value != NULL);
p_addr = string_token(value, &n, NULL, 0);
if( p_addr == NULL || *p_addr == '\0' || ftn_addrparse(&addr, p_addr, FALSE) )
return(PROC_RC_IGNORE);
memset(dest, '\0', sizeof(s_override));
dest->addr = addr;
while( key || (key = string_token(NULL, &n, NULL, 1)) )
{
if( (arg = string_token(NULL, &n, NULL, 1)) == NULL || *arg == '\0' )
{
log("no argument(s) for override \"%s\"", key);
if( rc < PROC_RC_WARN )
rc = PROC_RC_WARN;
break;
}
if( neednew )
{
(*p) = (s_override*)xmalloc(sizeof(s_override));
memset(*p, '\0', sizeof(s_override));
(*p)->addr = addr;
neednew = FALSE;
}
if( strcasecmp(key, "phone") == 0 )
{
if( (*p)->sPhone )
free((*p)->sPhone);
(*p)->sPhone = xstrcpy(arg);
key = NULL;
}
else if( strcasecmp(key, "ipaddr") == 0 )
{
if( (*p)->sIpaddr )
free((*p)->sIpaddr);
(*p)->sIpaddr = xstrcpy(arg);
key = NULL;
}
else if( strcasecmp(key, "worktime") == 0 )
{
if( timevec_parse_list(&((*p)->worktime), arg) == -1 )
{
log("invalid work time \"%s\"", arg);
if( rc < PROC_RC_WARN )
rc = PROC_RC_WARN;
}
key = NULL;
}
else if( strcasecmp(key, "freqtime") == 0 )
{
if( timevec_parse_list(&((*p)->freqtime), arg) == -1 )
{
log("invalid freq time \"%s\"", arg);
if( rc < PROC_RC_WARN )
rc = PROC_RC_WARN;
}
key = NULL;
}
else if( strcasecmp(key, "flags") == 0 )
{
if( (*p)->sFlags )
free((*p)->sFlags);
(*p)->sFlags = xstrcpy(arg);
key = NULL;
}
else if( strcasecmp(key, "hidden") == 0 )
{
neednew = TRUE;
p = &((*p)->hidden);
key = arg;
}
else
{
log("unknown keyword \"%s\" in override", key);
if( rc < PROC_RC_WARN )
rc = PROC_RC_WARN;
key = arg;
}
}
return(rc);
}
/*
* Line format: Options <options..>
*/
static int proc_options(s_options *dest, char *value)
{
int i, rc = PROC_RC_OK;
char *key = NULL, *n = NULL;
ASSERT(dest != NULL && value != NULL);
for( key = string_token(value, &n, NULL, 0); key;
key = string_token(NULL, &n, NULL, 0) )
{
for( i = 0; options[i].keystr; i++ )
{
if( strcasecmp(key, options[i].keystr) == 0 )
{
if( options[i].value_no )
{
dest->value &= ~options[i].value_no;
dest->mask |= options[i].value_no;
}
if( options[i].value_yes )
{
dest->value |= options[i].value_yes;
dest->mask |= options[i].value_yes;
}
#ifdef DEBUG
if( options[i].value_no == 0 && options[i].value_yes == 0 )
ASSERT_MSG();
#endif
break;
}
else if( (strncasecmp(key, "no", 2) == 0
&& strcasecmp(key+2, options[i].keystr) == 0)
|| (*key == '!'
&& strcasecmp(key+1, options[i].keystr) == 0) )
{
if( options[i].value_no )
{
dest->value |= options[i].value_no;
dest->mask |= options[i].value_no;
}
if( options[i].value_yes )
{
dest->value &= ~options[i].value_yes;
dest->mask |= options[i].value_yes;
}
#ifdef DEBUG
if( !options[i].value_no && !options[i].value_yes )
ASSERT_MSG();
#endif
break;
}
}
if( !options[i].keystr )
{
log("unknown option \"%s\"", key);
if( rc < PROC_RC_WARN )
rc = PROC_RC_WARN;
}
}
return(rc);
}
/*
* Line format: <Keyword> <Any value>
*/
static int proc_string(s_string *dest, char *value)
{
ASSERT(dest != NULL && value != NULL);
dest->str = xstrcpy(value);
return PROC_RC_OK;
}
/*
* Line format: <Keyword> <Number>
*/
static int proc_number(s_number *dest, char *value)
{
ASSERT(dest != NULL && value != NULL);
if( !ISDEC(value) )
{
log("value \"%s\" isn't numeric", value);
return(PROC_RC_IGNORE);
}
dest->num = atol(value);
return(PROC_RC_OK);
}
/*
* Line format: <Keyword> <Octal permissions>
*/
static int proc_filemode(s_filemode *dest, char *value)
{
int rc = PROC_RC_OK;
ASSERT(dest != NULL && value != NULL);
if( !ISOCT(value) )
{
log("value \"%s\" isn't octal number", value);
return(PROC_RC_IGNORE);
}
sscanf(value, "%o", (unsigned int *)&dest->mode);
return(rc);
}
/*
* Line format: <Keyword> <Yes|No|True|False>
*/
static int proc_boolean(s_boolean *dest, char *value)
{
ASSERT(dest != NULL && value != NULL);
if( !strcasecmp(value, "yes")
|| !strcasecmp(value, "true") )
{
dest->istrue = 1;
return(PROC_RC_OK);
}
else if( !strcasecmp(value, "no")
|| !strcasecmp(value, "false") )
{
dest->istrue = 0;
return(PROC_RC_OK);
}
log("unexpected argument \"%s\", must be \"Yes\" or \"No\"", value);
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <FTN address|Inet address>
*/
static int proc_address(s_falist *dest, char *value)
{
s_faddr addr;
ASSERT(dest != NULL && value != NULL);
if( ftn_addrparse(&addr, value, FALSE) )
{
log("can't parse address \"%s\"", value);
return(PROC_RC_IGNORE);
}
dest->addr = addr;
return(PROC_RC_OK);
}
/*
* Line format: <Keyword> <File name> <Address>
*/
static int proc_nodelist(s_falist *dest, char *value)
{
s_faddr addr;
char *n = NULL;
char *p_name = NULL;
char *p_addr = NULL;
ASSERT(dest != NULL && value != NULL);
p_name = string_token(value, &n, NULL, 1);
p_addr = string_token(NULL, &n, NULL, 1);
if( p_name && *p_name && p_addr && *p_addr )
{
if( ftn_addrparse(&addr, p_addr, TRUE) == 0 )
{
dest->addr = addr;
dest->what = xstrcpy(p_name);
return(PROC_RC_OK);
}
else
{
log("can't parse address \"%s\"", p_addr);
return(PROC_RC_IGNORE);
}
}
log("incorrect nodelist specification");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <domain> <path> <zone>
*/
static int proc_domain(s_domain *dest, char *value)
{
char *n = NULL;
char *p_domn = NULL;
char *p_path = NULL;
char *p_zone = NULL;
ASSERT(dest != NULL && value != NULL);
p_domn = string_token(value, &n, NULL, 1);
p_path = string_token(NULL, &n, NULL, 1);
p_zone = string_token(NULL, &n, NULL, 1);
if( p_domn && *p_domn && p_path && *p_path && p_zone && *p_zone )
{
if( ISDEC(p_zone) )
{
dest->domain = xstrcpy(p_domn);
dest->zone = atoi(p_zone);
if( p_path[strlen(p_path)-1] == DIRSEPCHR )
dest->path = xstrcpy(p_path);
else
dest->path = string_concat(p_path, DIRSEPSTR, NULL);
return(PROC_RC_OK);
}
else
{
log("zone isn't numeric value in domain specification");
return(PROC_RC_IGNORE);
}
}
log("incorrect domain specification");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <port>[:<lockspeed>]
*/
static int proc_modemport(s_modemport *dest, char *value)
{
char *p_speed = NULL;
long speed = 0;
ASSERT(dest != NULL && value != NULL);
p_speed = strrchr(value, ':');
if( p_speed ) {
if( ISDEC(p_speed+1) )
{
p_speed[0] = '\0';
speed = atol(p_speed+1);
}
else
{
log("incorrect modem port \"%s\": bad lock speed", value);
return(PROC_RC_IGNORE);
}
}
dest->name = xstrcpy(value);
dest->speed = speed;
return(PROC_RC_OK);
}
/*
* Line format: <Keyword> <Address> <Password>
*/
static int proc_password(s_falist *dest, char *value)
{
s_faddr addr;
char *n = NULL;
char *p_addr = NULL;
char *p_passwd = NULL;
ASSERT(dest != NULL && value != NULL);
p_addr = string_token(value, &n, NULL, 1);
p_passwd = string_token(NULL, &n, NULL, 1);
if( p_addr && *p_addr && p_passwd && *p_passwd )
{
if( ftn_addrparse(&addr, p_addr, FALSE) == 0 )
{
dest->addr = addr;
dest->what = xstrcpy(p_passwd);
return(PROC_RC_OK);
}
else
{
log("can't parse address \"%s\"", value);
return(PROC_RC_IGNORE);
}
}
log("incorrect password specification");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <Path>
*/
static int proc_path(s_string *dest, char *value)
{
ASSERT(dest != NULL && value != NULL);
if( value[strlen(value)-1] == DIRSEPCHR )
dest->str = xstrcpy(value);
else
dest->str = string_concat(value, DIRSEPSTR, NULL);
return(PROC_RC_OK);
}
/*
* Line format: <Keyword> <<String1[:RC]> [String2[:RC]] ..>
*/
static int proc_dialresp(s_dialresp *dest, char *value)
{
int i;
char *n = NULL;
char *p_mstr = NULL;
char *p_type = NULL;
char *p_retv = NULL;
ASSERT(dest != NULL && value != NULL);
p_mstr = string_token(value, &n, NULL, 1);
p_type = string_token(NULL, &n, NULL, 1);
p_retv = string_token(NULL, &n, NULL, 1);
if( p_mstr && *p_mstr && p_type && *p_type )
{
if( p_retv && !ISDEC(p_retv) )
{
log("return code isn't numeric in modem response specification");
return(PROC_RC_IGNORE);
}
for( i = 0; resptypes[i].str; i++ )
if( strcasecmp(p_type, resptypes[i].str) == 0 )
break;
if( resptypes[i].str )
{
dest->mstr = xstrcpy(p_mstr);
dest->type = resptypes[i].value;
dest->retv = p_retv ? atoi(p_retv) : resptypes[i].retv;
return(PROC_RC_OK);
}
log("unknown response type \"%s\"", p_type);
return(PROC_RC_IGNORE);
}
log("incorrect modem response specification");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <Search value> <Replace value>
*/
static int proc_translate(s_translate *dest, char *value)
{
char *n = NULL;
char *p_find = NULL;
char *p_repl = NULL;
ASSERT(dest != NULL && value != NULL);
p_find = string_token(value, &n, NULL, 1);
p_repl = string_token(NULL, &n, NULL, 1);
if( p_find && *p_find )
{
dest->find = xstrcpy(p_find);
if( p_repl )
dest->repl = xstrcpy(p_repl);
return(PROC_RC_OK);
}
log("incorrect translation rule specification");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <Connect speed> <Number>
*/
static int proc_speeddep(s_connlist *dest, char *value)
{
char *n = NULL;
char *p_speed = NULL;
char *p_value = NULL;
ASSERT(dest != NULL && value != NULL);
p_speed = string_token(value, &n, NULL, 1);
p_value = string_token(NULL, &n, NULL, 1);
if( p_speed && *p_speed && p_value && *p_value )
{
if( ISDEC(p_speed) && ISDEC(p_value) )
{
dest->speed = atoi(p_speed);
dest->value = atoi(p_value);
return(PROC_RC_OK);
}
log("non-numeric value \"%s\" or \"%s\"", p_speed, p_value);
return(PROC_RC_IGNORE);
}
log("incorrect speed dependent config string");
return(PROC_RC_IGNORE);
}
/*
* Line format: <Keyword> <Tries number> [<Action> <Action argument(s)>]
*/
static int proc_tries(s_tries *dest, char *value)
{
int rc = PROC_RC_OK;
char *n = NULL;
char *p_tries = NULL;
char *p_action = NULL;
char *p_arg = NULL;
int action = TRIES_ACTION_UNDIALABLE;
int arg = 0;
ASSERT(dest != NULL && value != NULL);
p_tries = string_token(value, &n, NULL, 0);
p_action = string_token(NULL, &n, NULL, 0);
p_arg = string_token(NULL, &n, NULL, 0);
if( p_tries && *p_tries && ISDEC(p_tries) )
{
if( p_action && *p_action )
{
if( strcasecmp(p_action, "undialable") == 0 )
{
if( p_arg && *p_arg )
{
log("no argument needed for action 'undialable'");
rc = PROC_RC_WARN;
}
action = TRIES_ACTION_UNDIALABLE;
arg = 0;
}
else if( strcasecmp(p_action, "hold") == 0 )
{
if( p_arg && *p_arg && !ISDEC(p_arg) )
{
log("non-numeric argument for action 'hold'");
return PROC_RC_IGNORE;
}
else if( p_arg == NULL )
{
log("no argument for action 'hold'");
return PROC_RC_IGNORE;
}
action = TRIES_ACTION_HOLDSYSTEM;
arg = atoi(p_arg);
}
else if( strcasecmp(p_action, "holdall") == 0 )
{
if( p_arg && *p_arg && !ISDEC(p_arg) )
{
log("non-numeric argument for action 'holdall'");
return PROC_RC_IGNORE;
}
else if( p_arg == NULL )
{
log("no argument for action 'holdall'");
return PROC_RC_IGNORE;
}
action = TRIES_ACTION_HOLDALL;
arg = atoi(p_arg);
}
else
{
log("unknown action '%s'", p_action);
return PROC_RC_IGNORE;
}
}
dest->tries = atoi(p_tries);
dest->action = action;
dest->arg = arg;
return(rc);
}