Initial revision
This commit is contained in:
parent
e5a74c85d6
commit
fa6be5da46
|
@ -0,0 +1,25 @@
|
|||
As this software is in the Alpha state, there are still some bugs or
|
||||
problems. If you encountered one please include following informations when
|
||||
reporting it:
|
||||
- The version you are using.
|
||||
- Your `Config', `config.h' and `yaps.rc' file.
|
||||
- Call `yaps -V' and redirect the output into a file. Include this file.
|
||||
- A command to reproduce the bug.
|
||||
- The output with the highest verbosity. This can be
|
||||
done by starting yaps with several -v's (at least 4) and
|
||||
redirecting stdout and stderr into a file, e.g.:
|
||||
yaps -vvvv [your options] &> bug [bash]
|
||||
- or -
|
||||
yaps -vvvv [your options] >bug 2>&1 [sh]
|
||||
- or -
|
||||
see your shell manual.
|
||||
- If the program terminates recompile it with debug information
|
||||
(if not already done). Reproduce the problem. Start the program
|
||||
under the control of the debugger. Save the location and the stack
|
||||
frame into a file. Send the file. If a core file is generated,
|
||||
start the debugger on the program/core pair, print the location
|
||||
and the stack frame into a file. Send the file.
|
||||
- DO NOT SEND CORE FILES!!!
|
||||
|
||||
Send these information either to <yaps@nitmar.tnet.de> (preferred) or
|
||||
<ud@cube.net>.
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,17 @@
|
|||
Copyright (c) 1997 Ulrich Dessauer
|
||||
All rights reserved.
|
||||
|
||||
You may distribute under the terms of the GNU General Public
|
||||
License.
|
||||
|
||||
IN NO EVENT SHALL ULRICH DESSAUER BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
|
||||
THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ULRICH DESSAUER
|
||||
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ULRICH DESSAUER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
|
||||
BASIS, AND ULRICH DESSAUER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
|
||||
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# -*- sh -*-
|
||||
# SECTION A.) Global configuration
|
||||
# Select compiler command
|
||||
CC = gcc
|
||||
#
|
||||
CFLAGS = -Wall -Wno-parentheses -Wshadow -Wstrict-prototypes -Wmissing-prototypes
|
||||
LDFLAGS =
|
||||
EXLIBS =
|
||||
#
|
||||
# Select scripting language(s)
|
||||
# SLang (ftp://space.mit.edu/pub/davis/slang/)
|
||||
#SLANG = True
|
||||
# LUA (ftp://ftp.icad.puc-rio.br/pub/lua/)
|
||||
#LUA = True
|
||||
#
|
||||
# Define this to disable debugging
|
||||
#NDEBUG = True
|
||||
#
|
||||
#
|
||||
#
|
||||
# SECTION B.) yaps configuration
|
||||
# Name and location of global configuration file
|
||||
YAPS_CFGFILE = /etc/yaps.rc
|
||||
# Name of local configuration file (location is $HOME.)
|
||||
YAPS_LCFGFILE = .yapsrc
|
||||
# Directory for installing the binary
|
||||
YAPS_BINDIR = /usr/local/bin
|
||||
# Directory for optional support files
|
||||
YAPS_LIBDIR = /usr/local/lib/yaps
|
||||
# User/Group/Mode for yaps
|
||||
YAPS_USER = bin
|
||||
YAPS_GROUP = uucp
|
||||
YAPS_MODE = 2711
|
||||
# User/Group/Mode for global configuration file
|
||||
YAPS_RCUSER = bin
|
||||
YAPS_RCGROUP = bin
|
||||
YAPS_RCMODE = 644
|
||||
#
|
||||
# End of Configuration, the rest is for automatic
|
||||
# configuration depending on settings above
|
||||
LDEFS =
|
||||
LLIBS =
|
||||
ifdef SLANG
|
||||
LDEFS += -DSCRIPT_SLANG
|
||||
LLIBS += -lslang
|
||||
MATH = True
|
||||
endif
|
||||
ifdef LUA
|
||||
LDEFS += -DSCRIPT_LUA
|
||||
LLIBS += -llualib -llua
|
||||
MATH = True
|
||||
endif
|
||||
ifdef MATH
|
||||
LLIBS += -lm
|
||||
endif
|
||||
#
|
||||
ifdef NDEBUG
|
||||
DDEFS = -DNDEBUG
|
||||
G = -O
|
||||
else
|
||||
G = -g
|
||||
endif
|
||||
#
|
||||
CFLAGS := $G $(CFLAGS) $(LDEFS) $(DDEFS)
|
||||
LDFLAGS := $G $(LDFLAGS)
|
|
@ -0,0 +1,65 @@
|
|||
# -*- sh -*-
|
||||
#
|
||||
include Config
|
||||
#
|
||||
#CFLAGS := -include mem.h $(CFLAGS)
|
||||
CFLAGS := $(CFLAGS)
|
||||
#
|
||||
DEFS = -DCFGFILE=\"$(YAPS_CFGFILE)\" -DLCFGFILE=\"$(YAPS_LCFGFILE)\" \
|
||||
-DLIBDIR=\"$(YAPS_LIBDIR)\"
|
||||
LIBS = -L. -lpager $(LLIBS)
|
||||
OBJS = data.o util.o cfg.o tty.o cv.o asc.o scr.o tap.o ucp.o \
|
||||
slang.o lua.o #mem.o
|
||||
YOBJS = yaps.o valid.o
|
||||
DSTFLE = $(YAPS_BINDIR)/yaps
|
||||
|
||||
all: yaps yaps.doc
|
||||
@if [ -f contrib/Makefile ]; then \
|
||||
$(MAKE) -C contrib all ; \
|
||||
fi
|
||||
|
||||
yaps: libpager.a $(YOBJS)
|
||||
$(CC) $(LDFLAGS) $(YOBJS) -o $@ $(LIBS)
|
||||
|
||||
libpager.a: $(OBJS)
|
||||
rm -f $@
|
||||
ar rc $@ $(OBJS)
|
||||
ranlib $@
|
||||
|
||||
yaps.o: yaps.c pager.h
|
||||
$(CC) $(CFLAGS) $(DEFS) $< -c -o $@
|
||||
|
||||
yaps.doc: yaps.html
|
||||
lynx -cfg=/dev/null -nolist -dump $< > $@
|
||||
|
||||
install: $(DSTFLE) $(CFGFILE)
|
||||
if [ ! -d $(YAPS_LIBDIR) ]; then \
|
||||
install -d -m 755 -o $(YAPS_USER) -g $(YAPS_GROUP) $(YAPS_LIBDIR) ; \
|
||||
fi
|
||||
@if [ -f contrib/Makefile ]; then \
|
||||
$(MAKE) -C contrib install ; \
|
||||
fi
|
||||
|
||||
$(DSTFLE): yaps
|
||||
install -o $(YAPS_USER) -g $(YAPS_GROUP) -m $(YAPS_MODE) -s yaps $@
|
||||
|
||||
$(CFGFILE): yaps.rc
|
||||
@if [ ! -f $@ ]; then \
|
||||
install -o $(YAPS_RCUSER) -g $(YAPS_RCGROUP) -m $(YAPS_RCMODE) -s yaps.rc $@ ; \
|
||||
fi
|
||||
|
||||
clean:
|
||||
rm -f *.[oa] *~ .*~ yaps core .depend
|
||||
@if [ -f contrib/Makefile ]; then \
|
||||
$(MAKE) -C contrib clean ; \
|
||||
fi
|
||||
|
||||
depend:
|
||||
$(CPP) $(CFLAGS) -MM *.c > .depend
|
||||
@if [ -f contrib/Makefile ]; then \
|
||||
$(MAKE) -C contrib depend ; \
|
||||
fi
|
||||
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
|
@ -0,0 +1,113 @@
|
|||
yaps -or- Yet Another Pager Software
|
||||
=====================================
|
||||
|
||||
This software is primary designed to send message to so called pager devices
|
||||
including cellular phones which are able to receive textual messages
|
||||
(sometimes called SMS, short message system/service.)
|
||||
|
||||
This is a simple command line driven program with a global and a personal
|
||||
configuration file, but the protocol implementation is kept as a seperate
|
||||
library, with which one may somedays write a client/server system.
|
||||
|
||||
Copyright:
|
||||
~~~~~~~~~~
|
||||
Copyright (c) 1997 Ulrich Dessauer
|
||||
All rights reserved.
|
||||
|
||||
You may distribute under the terms of the GNU General Public
|
||||
License.
|
||||
|
||||
IN NO EVENT SHALL ULRICH DESSAUER BE LIABLE TO ANY PARTY FOR DIRECT,
|
||||
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
|
||||
THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ULRICH DESSAUER
|
||||
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ULRICH DESSAUER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
|
||||
BASIS, AND ULRICH DESSAUER HAS NO OBLIGATION TO PROVIDE MAINTENANCE,
|
||||
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
|
||||
Installation:
|
||||
~~~~~~~~~~~~~
|
||||
You need a system supporting the Posix system calls and library functions
|
||||
(every modern Unix like OS should have this support) and you need an install
|
||||
program, otherwise you have to install the result by hand. Gnumake and GCC
|
||||
are a plus, otherwise you may have to tweak the Makefile and some source
|
||||
files a bit.
|
||||
|
||||
1.) Edit Config (which will be included by make) & edit config.h
|
||||
1a.) If you do not have the SLang library installed, comment out
|
||||
the line `SLANG = True' in Config or install it somewhere
|
||||
the compiler can find it (/usr/local/{lib,include} seems to
|
||||
be a not-to-bad place). READ THE ATTACHED COPYRIGHT NOTICE!
|
||||
1b.) Dito for lua.
|
||||
2.) Edit config.h. Comments should explain enough.
|
||||
3.) `make depend'
|
||||
4.) `make'
|
||||
|
||||
If the program compiles fine:
|
||||
5.) `make install' as root (if you have permissons). If you do not have
|
||||
an install program, install it by hand:
|
||||
a.) Copy the executable `yaps' to somewhere in your path
|
||||
b.) Install yaps.rc as /etc/yaps.rc or as ~/.yapsrc
|
||||
6.) edit `/etc/yaps.rc' for global settings
|
||||
7.) Optional edit ~/.yapsrc for your private settings
|
||||
|
||||
An example `yaps.rc' file is included and can be used directly for some
|
||||
services available in Germany. Others may be added. See the `yaps.doc' file
|
||||
for a complete description of the configuration files.
|
||||
|
||||
Implementation:
|
||||
~~~~~~~~~~~~~~~
|
||||
The current implementation allows sending messages to pager, where the
|
||||
service company offers a modem gateway. Paging via Internet or other online
|
||||
services is currently not supported, as they are mostly quite simple to
|
||||
realize (sending an e-mail to a specific address, calling an URL, etc.)
|
||||
|
||||
Following protocols are implemented:
|
||||
- ASCII based. This could also be handled by programs like `chat', but is
|
||||
included for completness. You can use simple send/expect strings to define
|
||||
the communication.
|
||||
|
||||
- SCRIPT based. This could be considered as an enhanced ASCII mode and
|
||||
depends on the available scripting languages, that are integrated.
|
||||
Currently SLang and Lua are supported, others may follow.
|
||||
|
||||
- TAP (Telocator Alphanumeric Protocol). This is the result of the earlier
|
||||
used IXO and PET protocols. The documentation for this protocol is
|
||||
available via the Web:
|
||||
http://www.mot.com/MIMS/MSPG/pcia_protocols/tap_v1p8/table_of_contents.html
|
||||
(Thanks a lot to Motorola!)
|
||||
|
||||
- UCP (Universal Computer Protocol). D2privat has kindly made the
|
||||
description available to me, thanks a lot to Mannesmann Mobilfunk! Lots of
|
||||
the protocol is NOT implemented, as this makes not much sense on dialup
|
||||
lines.
|
||||
|
||||
ATTENTION: If someone has the complete documentation for any other used
|
||||
protocol for pager like devices, I would be glad if she/he could make them
|
||||
available for me. If I had a testing possibility I'll try to implement that
|
||||
protocol.
|
||||
|
||||
Bugs, Problems, Comments:
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Please send any bug report, any encountered problem (with a detailed
|
||||
description as possible) and any comments to <yaps@nitmar.tnet.de> or
|
||||
<ud@cube.net>.
|
||||
|
||||
Files:
|
||||
~~~~~~
|
||||
README: This file
|
||||
COPYING.GPL, COPYRIGHT: About distributing the software
|
||||
INSTALL: A pointer into the README file
|
||||
BUGREPORT: How to report a bug
|
||||
Makefile, Config: Make rules
|
||||
yaps.rc: Sample configuration file
|
||||
yaps.c: The driver program
|
||||
valid.c, valid.h: Support routines for the driver program
|
||||
remaining *.c, *.h: The paging library
|
||||
yaps.html, yaps.doc: Documentation in HTML and plain text
|
||||
yaps.1: A minimal manual page
|
||||
yaps.lsm: The Linux Software Map entry
|
||||
contrib/: Files not supported by the author
|
|
@ -0,0 +1,372 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
# include <string.h>
|
||||
# include "pager.h"
|
||||
|
||||
/*{{{ typedefs */
|
||||
typedef struct {
|
||||
# ifndef NDEBUG
|
||||
# define MAGIC MKMAGIC('a', 's', 'c', '\0')
|
||||
long magic;
|
||||
# endif /* NDEBUG */
|
||||
void *sp;
|
||||
void *ctab;
|
||||
void (*logger) (char, char *, ...);
|
||||
char *callid;
|
||||
int deftout;
|
||||
char *alogin;
|
||||
char *alogout;
|
||||
char *apid;
|
||||
char *amsg;
|
||||
char *anext;
|
||||
char *async;
|
||||
|
||||
date_t delay;
|
||||
date_t expire;
|
||||
Bool rds;
|
||||
} asc;
|
||||
/*}}}*/
|
||||
/*{{{ convert */
|
||||
static char *
|
||||
escape_string (asc *a, char *str)
|
||||
{
|
||||
int c;
|
||||
char ch, prev;
|
||||
char *ret;
|
||||
int n;
|
||||
|
||||
if (ret = malloc (strlen (str) * 2 + 16)) {
|
||||
prev = '\0';
|
||||
ch = '\0';
|
||||
for (n = 0; *str; prev = ch) {
|
||||
c = cv_conv (a -> ctab, (char_t) *str++);
|
||||
if (c < 0)
|
||||
continue;
|
||||
ch = (char) c;
|
||||
if ((ch == '<') && isspace (prev)) {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = '<';
|
||||
} else if (ch == ' ') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 's';
|
||||
} else if (ch == '\a') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 'a';
|
||||
} else if (ch == '\b') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 'b';
|
||||
} else if (ch == '\f') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 'f';
|
||||
} else if (ch == '\n') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 'n';
|
||||
} else if (ch == '\r') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 'r';
|
||||
} else if (ch == '\t') {
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = 't';
|
||||
} else if (ch) {
|
||||
if ((ch == '\\') || (ch == '^') || (ch == '%'))
|
||||
ret[n++] = '\\';
|
||||
ret[n++] = ch;
|
||||
}
|
||||
}
|
||||
ret[n] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *
|
||||
convert_asc (asc *a, char *pat, char *pid, char *msg)
|
||||
{
|
||||
char *str;
|
||||
int siz, len;
|
||||
char *ptr;
|
||||
int plen;
|
||||
char scr[32];
|
||||
|
||||
str = NULL;
|
||||
siz = 0;
|
||||
len = 0;
|
||||
while (*pat) {
|
||||
if (len + 2 >= siz) {
|
||||
siz += 32;
|
||||
if (! (str = Realloc (str, siz + 2)))
|
||||
break;
|
||||
}
|
||||
if (*pat == '\\') {
|
||||
++pat;
|
||||
if (*pat) {
|
||||
ptr = NULL;
|
||||
switch (*pat) {
|
||||
case 'C': ptr = a -> callid; break;
|
||||
case 'P': ptr = pid; break;
|
||||
case 'M': ptr = msg; break;
|
||||
case 'R':
|
||||
strcpy (scr, (a -> rds ? "1" : "0"));
|
||||
ptr = scr;
|
||||
break;
|
||||
default:
|
||||
str[len++] = '\\';
|
||||
str[len++] = *pat;
|
||||
break;
|
||||
}
|
||||
if (ptr && (ptr = escape_string (a, ptr))) {
|
||||
if (plen = strlen (ptr)) {
|
||||
if (len + plen + 2 >= siz) {
|
||||
siz = len + plen + 32;
|
||||
if (! (str = Realloc (str, siz)))
|
||||
break;
|
||||
}
|
||||
strcpy (str + len, ptr);
|
||||
len += plen;
|
||||
}
|
||||
free (ptr);
|
||||
}
|
||||
++pat;
|
||||
}
|
||||
} else if (! iscntrl (*pat))
|
||||
str[len++] = *pat++;
|
||||
else {
|
||||
str[len++] = ' ';
|
||||
++pat;
|
||||
}
|
||||
}
|
||||
if (str)
|
||||
str[len] = '\0';
|
||||
return str;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ general sending routine */
|
||||
static int
|
||||
do_send (asc *a, char *what, char *pat, char *pid, char *msg)
|
||||
{
|
||||
int ret;
|
||||
char *str;
|
||||
|
||||
ret = ERR_FAIL;
|
||||
if (a && a -> sp)
|
||||
if (pat && *pat) {
|
||||
if (str = convert_asc (a, pat, pid, msg)) {
|
||||
if (tty_send_expect (a -> sp, a -> deftout, str, NULL) != -1) {
|
||||
V (1, ("Ascii %s sent\n", what));
|
||||
ret = NO_ERR;
|
||||
} else
|
||||
V (1, ("Unable to send %s\n", what));
|
||||
free (str);
|
||||
}
|
||||
} else
|
||||
ret = NO_ERR;
|
||||
return ret;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ login/logout/transmit/next/sync */
|
||||
int
|
||||
asc_login (void *ap, string_t *cid)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
if (a) {
|
||||
if (a -> callid)
|
||||
free (a -> callid);
|
||||
a -> callid = sextract (cid);
|
||||
}
|
||||
return a ? do_send (a, "login", a -> alogin, NULL, NULL) : ERR_ABORT;
|
||||
}
|
||||
|
||||
int
|
||||
asc_logout (void *ap)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
return a ? do_send (a, "logout", a -> alogout, NULL, NULL) : ERR_FATAL;
|
||||
}
|
||||
|
||||
int
|
||||
asc_transmit (void *ap, char *pid, char *msg)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
int n;
|
||||
|
||||
MCHK (a);
|
||||
if (! a)
|
||||
return ERR_FATAL;
|
||||
if ((n = do_send (a, "pagerid", a -> apid, pid, NULL)) != NO_ERR)
|
||||
return n;
|
||||
return do_send (a, "message", a -> amsg, NULL, msg);
|
||||
}
|
||||
|
||||
int
|
||||
asc_next (void *ap)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
return a ? do_send (a, "next", a -> anext, NULL, NULL) : ERR_FATAL;
|
||||
}
|
||||
|
||||
int
|
||||
asc_sync (void *ap)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
return a ? do_send (a, "sync", a -> async, NULL, NULL) : ERR_FATAL;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ config */
|
||||
void
|
||||
asc_config (void *ap, void (*logger) (char, char *, ...),
|
||||
int deftout, char *alogin, char *alogout, char *apid, char *amsg, char *anext, char *async,
|
||||
date_t *delay, date_t *expire, Bool rds)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
if (a) {
|
||||
a -> logger = logger;
|
||||
if (deftout != -1)
|
||||
a -> deftout = deftout;
|
||||
if (alogin) {
|
||||
if (a -> alogin)
|
||||
free (a -> alogin);
|
||||
a -> alogin = strdup (alogin);
|
||||
}
|
||||
if (alogout) {
|
||||
if (a -> alogout)
|
||||
free (a -> alogout);
|
||||
a -> alogout = strdup (alogout);
|
||||
}
|
||||
if (apid) {
|
||||
if (a -> apid)
|
||||
free (a -> apid);
|
||||
a -> apid = strdup (apid);
|
||||
}
|
||||
if (amsg) {
|
||||
if (a -> amsg)
|
||||
free (a -> amsg);
|
||||
a -> amsg = strdup (amsg);
|
||||
}
|
||||
if (anext) {
|
||||
if (a -> anext)
|
||||
free (a -> anext);
|
||||
a -> anext = strdup (anext);
|
||||
}
|
||||
if (async) {
|
||||
if (a -> async)
|
||||
free (a -> async);
|
||||
a -> async = strdup (async);
|
||||
}
|
||||
if (delay)
|
||||
a -> delay = *delay;
|
||||
else
|
||||
dat_clear (& a -> delay);
|
||||
if (expire)
|
||||
a -> expire = *expire;
|
||||
else
|
||||
dat_clear (& a -> expire);
|
||||
a -> rds = rds;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
asc_set_convtable (void *ap, void *ctab)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
if (a) {
|
||||
if (a -> ctab)
|
||||
cv_free (a -> ctab);
|
||||
a -> ctab = ctab;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
asc_add_convtable (void *ap, void *ctab)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
if (a) {
|
||||
if (! a -> ctab)
|
||||
a -> ctab = cv_new ();
|
||||
if (a -> ctab)
|
||||
cv_merge (a -> ctab, ctab, True);
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ new/free/etc */
|
||||
void *
|
||||
asc_new (void *sp)
|
||||
{
|
||||
asc *a;
|
||||
|
||||
if (a = (asc *) malloc (sizeof (asc))) {
|
||||
# ifndef NDEBUG
|
||||
a -> magic = MAGIC;
|
||||
# endif /* NDEBUG */
|
||||
a -> sp = sp;
|
||||
a -> ctab = NULL;
|
||||
a -> logger = NULL;
|
||||
a -> callid = NULL;
|
||||
a -> deftout = 10;
|
||||
a -> alogin = NULL;
|
||||
a -> alogout = NULL;
|
||||
a -> apid = NULL;
|
||||
a -> amsg = NULL;
|
||||
a -> anext = NULL;
|
||||
a -> async = NULL;
|
||||
dat_clear (& a -> delay);
|
||||
dat_clear (& a -> expire);
|
||||
a -> rds = False;
|
||||
}
|
||||
return (void *) a;
|
||||
}
|
||||
|
||||
void *
|
||||
asc_free (void *ap)
|
||||
{
|
||||
asc *a = (asc *) ap;
|
||||
|
||||
MCHK (a);
|
||||
if (a) {
|
||||
if (a -> ctab)
|
||||
cv_free (a -> ctab);
|
||||
if (a -> callid)
|
||||
free (a -> callid);
|
||||
if (a -> alogin)
|
||||
free (a -> alogin);
|
||||
if (a -> alogout)
|
||||
free (a -> alogout);
|
||||
if (a -> apid)
|
||||
free (a -> apid);
|
||||
if (a -> amsg)
|
||||
free (a -> amsg);
|
||||
if (a -> anext)
|
||||
free (a -> anext);
|
||||
if (a -> async)
|
||||
free (a -> async);
|
||||
free (a);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
asc_preinit (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
asc_postdeinit (void)
|
||||
{
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,553 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
# include <string.h>
|
||||
# include "pager.h"
|
||||
|
||||
/*{{{ typedefs */
|
||||
typedef unsigned long hash_t;
|
||||
|
||||
typedef struct _entry {
|
||||
hash_t hval;
|
||||
char *var;
|
||||
char *val;
|
||||
struct _entry
|
||||
*next;
|
||||
} entry;
|
||||
|
||||
typedef struct _charc {
|
||||
hash_t hval;
|
||||
char *name;
|
||||
struct _charc
|
||||
*next;
|
||||
} charc;
|
||||
|
||||
typedef struct _block {
|
||||
# ifndef NDEBUG
|
||||
# define MAGIC MKMAGIC ('c', 'f', 'g', '\0')
|
||||
long magic;
|
||||
# endif /* NDEBUG */
|
||||
hash_t hval;
|
||||
char *name;
|
||||
charc *use;
|
||||
Bool done;
|
||||
entry *e;
|
||||
char *sep;
|
||||
int seplen;
|
||||
struct _block
|
||||
*next;
|
||||
} block;
|
||||
|
||||
typedef struct _fifo {
|
||||
void *dat;
|
||||
struct _fifo
|
||||
*next;
|
||||
} fifo;
|
||||
|
||||
typedef struct _fpstack {
|
||||
FILE *fp;
|
||||
struct _fpstack
|
||||
*up;
|
||||
} fpstack;
|
||||
/*}}}*/
|
||||
/*{{{ support routines */
|
||||
static hash_t
|
||||
calc_hash (char *str)
|
||||
{
|
||||
hash_t hval;
|
||||
|
||||
for (hval = 0; *str; ) {
|
||||
hval <<= 2;
|
||||
hval += *str++ & 0xff;
|
||||
hval >>= 1;
|
||||
}
|
||||
return hval;
|
||||
}
|
||||
|
||||
static Bool
|
||||
issame (hash_t h1, char *s1, hash_t h2, char *s2)
|
||||
{
|
||||
if (h1 == h2)
|
||||
if ((! s1) && (! s2))
|
||||
return True;
|
||||
else if (s1 && s2 && (s1[0] == s2[0]) && (! strcmp (s1, s2)))
|
||||
return True;
|
||||
return False;
|
||||
}
|
||||
|
||||
static block *
|
||||
new_block (char *bname, hash_t hval, char *sep)
|
||||
{
|
||||
block *b;
|
||||
|
||||
if (b = (block *) malloc (sizeof (block))) {
|
||||
b -> name = NULL;
|
||||
if ((! bname) || (b -> name = strdup (bname))) {
|
||||
b -> sep = NULL;
|
||||
b -> seplen = 0;
|
||||
if ((! sep) || (b -> sep = strdup (sep))) {
|
||||
# ifndef NDEBUG
|
||||
b -> magic = MAGIC;
|
||||
# endif /* NDEBUG */
|
||||
b -> hval = hval;
|
||||
b -> use = NULL;
|
||||
b -> done = False;
|
||||
b -> e = NULL;
|
||||
b -> next = NULL;
|
||||
} else {
|
||||
if (b -> name)
|
||||
free (b -> name);
|
||||
free (b);
|
||||
b = NULL;
|
||||
}
|
||||
} else {
|
||||
free (b);
|
||||
b = NULL;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
add_entry (block *base, block *b, char *var, char *val)
|
||||
{
|
||||
hash_t hval;
|
||||
entry *e, *etmp;
|
||||
Bool add;
|
||||
char *sav;
|
||||
|
||||
if (b && var) {
|
||||
if (*var == '+') {
|
||||
++var;
|
||||
add = True;
|
||||
} else
|
||||
add = False;
|
||||
hval = calc_hash (var);
|
||||
for (e = b -> e; e; e = e -> next)
|
||||
if (issame (hval, var, e -> hval, e -> var))
|
||||
break;
|
||||
if (e) {
|
||||
if (e -> val)
|
||||
if (add) {
|
||||
if (val && *val) {
|
||||
sav = e -> val;
|
||||
if (e -> val = malloc (strlen (sav) + strlen (val) + base -> seplen + 2)) {
|
||||
sprintf (e -> val, "%s%s%s", sav, (base -> sep ? base -> sep : ""), val);
|
||||
free (sav);
|
||||
val = NULL;
|
||||
} else
|
||||
e -> val = sav;
|
||||
}
|
||||
} else {
|
||||
free (e -> val);
|
||||
e -> val = NULL;
|
||||
}
|
||||
} else if (e = (entry *) malloc (sizeof (entry)))
|
||||
if (e -> var = strdup (var)) {
|
||||
e -> hval = hval;
|
||||
e -> val = NULL;
|
||||
e -> next = b -> e;
|
||||
b -> e = e;
|
||||
} else {
|
||||
free (e);
|
||||
e = NULL;
|
||||
}
|
||||
if (e && (! e -> val) && val && *val) {
|
||||
if (add && (base != b)) {
|
||||
for (etmp = base -> e; etmp; etmp = etmp -> next)
|
||||
if (issame (hval, var, etmp -> hval, etmp -> var))
|
||||
break;
|
||||
if (etmp && etmp -> val)
|
||||
if (e -> val = malloc (strlen (etmp -> val) + strlen (val) + base -> seplen + 2))
|
||||
sprintf (e -> val, "%s%s%s", etmp -> val, (base -> sep ? base -> sep : ""), val);
|
||||
}
|
||||
if (! e -> val)
|
||||
e -> val = strdup (val);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ read configuration */
|
||||
void *
|
||||
cfg_new (char *sep)
|
||||
{
|
||||
return (void *) new_block (NULL, 0, sep);
|
||||
}
|
||||
|
||||
void *
|
||||
cfg_read (char *fname, void *bp, char *sep)
|
||||
{
|
||||
FILE *fp;
|
||||
fpstack *fcur, *ftmp;
|
||||
char *gline, *line;
|
||||
char *ptr, *use;
|
||||
charc *prv, *tmp;
|
||||
block *base, *prev, *cur;
|
||||
hash_t hval;
|
||||
char *var, *val;
|
||||
int plen;
|
||||
Bool done;
|
||||
int siz, len;
|
||||
char *temp;
|
||||
|
||||
if (bp)
|
||||
base = (block *) bp;
|
||||
else
|
||||
if (! (base = new_block (NULL, 0, sep)))
|
||||
return NULL;
|
||||
cur = base;
|
||||
if (fp = fopen (fname, "r"))
|
||||
if (fcur = (fpstack *) malloc (sizeof (fpstack))) {
|
||||
fcur -> fp = fp;
|
||||
fcur -> up = NULL;
|
||||
while (fcur) {
|
||||
while (gline = getline (fcur -> fp, True)) {
|
||||
for (line = gline; isspace (*line); ++line)
|
||||
;
|
||||
if ((! *line) || (*line == '#')) {
|
||||
free (gline);
|
||||
continue;
|
||||
}
|
||||
if (*line == '[') {
|
||||
use = NULL;
|
||||
if (ptr = strchr (line, ']')) {
|
||||
*ptr++ = '\0';
|
||||
while (isspace (*ptr))
|
||||
++ptr;
|
||||
if (*ptr)
|
||||
use = ptr;
|
||||
}
|
||||
ptr = line + 1;
|
||||
if (! *ptr)
|
||||
cur = base;
|
||||
else {
|
||||
hval = calc_hash (ptr);
|
||||
for (cur = base, prev = NULL; cur; cur = cur -> next)
|
||||
if (issame (hval, ptr, cur -> hval, cur -> name))
|
||||
break;
|
||||
else
|
||||
prev = cur;
|
||||
if ((! cur) && (cur = new_block (ptr, hval, NULL)))
|
||||
if (prev)
|
||||
prev -> next = cur;
|
||||
if (cur && use) {
|
||||
if (cur -> use)
|
||||
for (prv = cur -> use; prv -> next; prv = prv -> next)
|
||||
;
|
||||
else
|
||||
prv = NULL;
|
||||
while (*use) {
|
||||
ptr = use;
|
||||
use = skipch (ptr, ',');
|
||||
if (tmp = (charc *) malloc (sizeof (charc)))
|
||||
if (tmp -> name = strdup (ptr)) {
|
||||
tmp -> hval = 0;
|
||||
tmp -> next = NULL;
|
||||
if (prv)
|
||||
prv -> next = tmp;
|
||||
else
|
||||
cur -> use = tmp;
|
||||
prv = tmp;
|
||||
} else
|
||||
free (tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (! cur) {
|
||||
free (gline);
|
||||
break;
|
||||
}
|
||||
} else if (*line == '|') {
|
||||
++line;
|
||||
while (isspace (*line))
|
||||
++line;
|
||||
if (fp = fopen (line, "r"))
|
||||
if (ftmp = (fpstack *) malloc (sizeof (fpstack))) {
|
||||
ftmp -> fp = fp;
|
||||
ftmp -> up = fcur;
|
||||
fcur = ftmp;
|
||||
} else
|
||||
fclose (fp);
|
||||
} else {
|
||||
var = line;
|
||||
val = skip (var);
|
||||
if (var = strdup (var)) {
|
||||
temp = NULL;
|
||||
if ((*val == '{') && (! *(val + 1))) {
|
||||
done = False;
|
||||
siz = 0;
|
||||
len = 0;
|
||||
while (ptr = getline (fcur -> fp, False)) {
|
||||
if ((*ptr != '}') || *(ptr + 1)) {
|
||||
plen = strlen (ptr);
|
||||
if (len + plen + 2 >= siz) {
|
||||
siz = len + plen + 256;
|
||||
if (! (temp = Realloc (temp, siz + 2))) {
|
||||
siz = 0;
|
||||
done = True;
|
||||
}
|
||||
}
|
||||
if (len + plen < siz) {
|
||||
if (len)
|
||||
temp[len++] = '\n';
|
||||
strcpy (temp + len, ptr);
|
||||
len += plen;
|
||||
}
|
||||
} else
|
||||
done = True;
|
||||
free (ptr);
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
if (temp) {
|
||||
temp[len] = '\0';
|
||||
val = temp;
|
||||
} else
|
||||
val = NULL;
|
||||
} else if (*val == '\\')
|
||||
++val;
|
||||
add_entry (base, cur, var, val);
|
||||
if (temp)
|
||||
free (temp);
|
||||
free (var);
|
||||
}
|
||||
}
|
||||
free (gline);
|
||||
}
|
||||
ftmp = fcur;
|
||||
fcur = fcur -> up;
|
||||
fclose (ftmp -> fp);
|
||||
free (ftmp);
|
||||
}
|
||||
} else
|
||||
fclose (fp);
|
||||
return (void *) base;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ add/change configuration */
|
||||
void
|
||||
cfg_modify (void *bp, char *bname, char *var, char *val)
|
||||
{
|
||||
block *base = (block *) bp;
|
||||
block *use, *prv;
|
||||
hash_t hval;
|
||||
|
||||
MCHK (base);
|
||||
if (base) {
|
||||
if (! bname)
|
||||
use = base;
|
||||
else {
|
||||
hval = calc_hash (bname);
|
||||
for (use = base -> next, prv = base; use; use = use -> next)
|
||||
if (issame (hval, bname, use -> hval, use -> name))
|
||||
break;
|
||||
else
|
||||
prv = use;
|
||||
if (! use)
|
||||
use = new_block (bname, hval, NULL);
|
||||
}
|
||||
if (use)
|
||||
add_entry (base, use, var, val);
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ end (free up) configuration */
|
||||
void *
|
||||
cfg_end (void *bp)
|
||||
{
|
||||
block *b = (block *) bp;
|
||||
block *tmp;
|
||||
charc *run;
|
||||
entry *e;
|
||||
|
||||
MCHK (b);
|
||||
while (b) {
|
||||
if (b -> name)
|
||||
free (b -> name);
|
||||
while (b -> use) {
|
||||
run = b -> use;
|
||||
b -> use = b -> use -> next;
|
||||
if (run -> name)
|
||||
free (run -> name);
|
||||
free (run);
|
||||
}
|
||||
while (b -> e) {
|
||||
e = b -> e;
|
||||
b -> e = b -> e -> next;
|
||||
if (e -> var)
|
||||
free (e -> var);
|
||||
if (e -> val)
|
||||
free (e -> val);
|
||||
free (e);
|
||||
}
|
||||
if (b -> sep)
|
||||
free (b -> sep);
|
||||
tmp = b;
|
||||
b = b -> next;
|
||||
free (tmp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ retrieving */
|
||||
static char *
|
||||
do_get (void *bp, char *bname, char *var, Bool glob, char *dflt)
|
||||
{
|
||||
block *b = (block *) bp;
|
||||
block *run, *tmp;
|
||||
entry *e;
|
||||
fifo *f, *l, *ft;
|
||||
charc *use;
|
||||
char *ptr, *sav;
|
||||
charc *vars, *vprv, *vtmp, *vrun;
|
||||
Bool first;
|
||||
hash_t hval;
|
||||
|
||||
MCHK (b);
|
||||
if (! (var = strdup (var)))
|
||||
return NULL;
|
||||
vars = NULL;
|
||||
vprv = NULL;
|
||||
for (ptr = var; *ptr; ) {
|
||||
sav = ptr;
|
||||
ptr = skipch (ptr, ',');
|
||||
if (vtmp = (charc *) malloc (sizeof (charc)))
|
||||
if (vtmp -> name = strdup (sav)) {
|
||||
vtmp -> hval = calc_hash (vtmp -> name);
|
||||
vtmp -> next = NULL;
|
||||
if (vprv)
|
||||
vprv -> next = vtmp;
|
||||
else
|
||||
vars = vtmp;
|
||||
vprv = vtmp;
|
||||
} else
|
||||
free (vtmp);
|
||||
}
|
||||
free (var);
|
||||
if (! vars)
|
||||
return NULL;
|
||||
e = NULL;
|
||||
f = NULL;
|
||||
l = NULL;
|
||||
first = True;
|
||||
while ((! e) && bname) {
|
||||
hval = calc_hash (bname);
|
||||
for (run = b -> next; run; run = run -> next)
|
||||
if (issame (hval, bname, run -> hval, run -> name))
|
||||
break;
|
||||
bname = NULL;
|
||||
if (run && (first || (! run -> done))) {
|
||||
for (vrun = vars; vrun; vrun = vrun -> next) {
|
||||
for (e = run -> e; e; e = e -> next)
|
||||
if (issame (vrun -> hval, vrun -> name, e -> hval, e -> var))
|
||||
break;
|
||||
if (e)
|
||||
break;
|
||||
}
|
||||
if (! e) {
|
||||
if (use = run -> use) {
|
||||
if (first) {
|
||||
for (tmp = b -> next; tmp; tmp = tmp -> next)
|
||||
tmp -> done = False;
|
||||
first = False;
|
||||
}
|
||||
for (; use; use = use -> next)
|
||||
if (ft = (fifo *) malloc (sizeof (fifo))) {
|
||||
ft -> dat = (void *) use;
|
||||
ft -> next = NULL;
|
||||
if (l)
|
||||
l -> next = ft;
|
||||
else {
|
||||
f = ft;
|
||||
l = ft;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (f) {
|
||||
ft = f;
|
||||
f = f -> next;
|
||||
if (! f)
|
||||
l = NULL;
|
||||
use = (charc *) ft -> dat;
|
||||
bname = use -> name;
|
||||
free (ft);
|
||||
} else
|
||||
bname = NULL;
|
||||
run -> done = True;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((! e) && glob)
|
||||
for (vrun = vars; vrun; vrun = vrun -> next) {
|
||||
for (e = b -> e; e; e = e -> next)
|
||||
if (issame (vrun -> hval, vrun -> name, e -> hval, e -> var))
|
||||
break;
|
||||
if (e)
|
||||
break;
|
||||
}
|
||||
while (vars) {
|
||||
vtmp = vars;
|
||||
vars = vars -> next;
|
||||
free (vtmp -> name);
|
||||
free (vtmp);
|
||||
}
|
||||
return e ? e -> val : dflt;
|
||||
}
|
||||
|
||||
static int
|
||||
do_iget (void *bp, char *bname, char *var, Bool glob, int dflt)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = do_get (bp, bname, var, glob, NULL);
|
||||
return ret ? atoi (ret) : dflt;
|
||||
}
|
||||
|
||||
static Bool
|
||||
do_bget (void *bp, char *bname, char *var, Bool glob, int dflt)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = do_get (bp, bname, var, glob, NULL);
|
||||
return ret ? ((*ret && strchr ("TtYy1+", *ret)) ? True : False) : dflt;
|
||||
}
|
||||
|
||||
char *
|
||||
cfg_get (void *bp, char *bname, char *var, char *dflt)
|
||||
{
|
||||
return do_get (bp, bname, var, True, dflt);
|
||||
}
|
||||
|
||||
int
|
||||
cfg_iget (void *bp, char *bname, char *var, int dflt)
|
||||
{
|
||||
return do_iget (bp, bname, var, True, dflt);
|
||||
}
|
||||
|
||||
Bool
|
||||
cfg_bget (void *bp, char *bname, char *var, Bool dflt)
|
||||
{
|
||||
return do_bget (bp, bname, var, True, dflt);
|
||||
}
|
||||
|
||||
char *
|
||||
cfg_block_get (void *bp, char *bname, char *var, char *dflt)
|
||||
{
|
||||
return do_get (bp, bname, var, False, dflt);
|
||||
}
|
||||
|
||||
int
|
||||
cfg_block_iget (void *bp, char *bname, char *var, int dflt)
|
||||
{
|
||||
return do_iget (bp, bname, var, False, dflt);
|
||||
}
|
||||
|
||||
Bool
|
||||
cfg_block_bget (void *bp, char *bname, char *var, Bool dflt)
|
||||
{
|
||||
return do_bget (bp, bname, var, False, dflt);
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,134 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# ifndef __CONFIG_H
|
||||
# define __CONFIG_H 1
|
||||
|
||||
/*{{{ changeable configuration */
|
||||
/*
|
||||
* Define signal handling:
|
||||
* POSIX_SIGNAL if you have the Posix sigaction() family
|
||||
* BSD_SIGNAL if you have BSD like signal() handling
|
||||
* SYSV_SIGNAL if you have SysV like signal() handling
|
||||
* SIG_VOID_RETURN if your signal handler returns void
|
||||
* SIG_INT_RETURN if your signal handler returns int
|
||||
*/
|
||||
# define POSIX_SIGNAL 1
|
||||
# define BSD_SIGNAL 0
|
||||
# define SYSV_SIGNAL 0
|
||||
# define SIG_VOID_RETURN 1
|
||||
# define SIG_INT_RETURN 0
|
||||
|
||||
/*
|
||||
* Set each define to 1, if you have the matching header file, otherwise
|
||||
* set it to 0. Remember, that some features may not available, if the
|
||||
* header file is not available.
|
||||
*/
|
||||
/*
|
||||
* Needed only by some systems, which do not define FD_SET etc.
|
||||
* in sys/time.h
|
||||
*/
|
||||
# define HAVE_SYS_SELECT_H 0
|
||||
|
||||
/*
|
||||
* If you have locales set this. This is useful to for character
|
||||
* conversion/classification
|
||||
*/
|
||||
# define HAVE_LOCALE_H 0
|
||||
|
||||
/*
|
||||
* If you have Posix regular expressions, set this. Otherwise a
|
||||
* very weak replacement is used to find matching services
|
||||
*/
|
||||
# define HAVE_REGEX_H 0
|
||||
|
||||
/*
|
||||
* one of these is required for SysV like lockfiles
|
||||
*/
|
||||
# define HAVE_SYS_SYSMACROS_H 1
|
||||
# define HAVE_SYS_MKDEV_H 0
|
||||
|
||||
/*
|
||||
* Some system do not define the getopt stuff in unistd.h, but in
|
||||
* a own include file getopt.h. Or (like the GNU libc) defines there
|
||||
* the extended getopt_long version.
|
||||
*/
|
||||
# define HAVE_GETOPT_H 0
|
||||
|
||||
/*
|
||||
* Set each define to 1, if your library supports the function, otherwise
|
||||
* set it to 0. See above for note.
|
||||
*/
|
||||
/*
|
||||
* If the library contains this function, a call to it is required
|
||||
* to get valid return values from localtime
|
||||
*/
|
||||
# define HAVE_TZSET 0
|
||||
|
||||
/*
|
||||
* If these are not set, chmod()/chown() are used
|
||||
*/
|
||||
# define HAVE_FCHMOD 0
|
||||
# define HAVE_FCHOWN 0
|
||||
|
||||
/*
|
||||
* If you have sigsetjmp() you definitly want to set this, otherwise
|
||||
* longjmp() from the signal handler leads into chaos
|
||||
*/
|
||||
# define HAVE_SIGSETJMP 0
|
||||
|
||||
/*
|
||||
* Memory access functions. Nearly everybody has memcpy()/memset(), so
|
||||
* choose the bcopy()/bzero() part only if you are missing the other two
|
||||
*/
|
||||
# define HAVE_MEMCPY 1
|
||||
# define HAVE_BCOPY 0
|
||||
# define HAVE_MEMSET 1
|
||||
# define HAVE_BZERO 0
|
||||
|
||||
/*
|
||||
* If your library supports getopt at all
|
||||
*/
|
||||
# define HAVE_GETOPT 1
|
||||
|
||||
/*
|
||||
* If your library supports long options (getopt_long(3)), then set this
|
||||
* to one
|
||||
*/
|
||||
# define HAVE_GETOPT_LONG 0
|
||||
|
||||
/*
|
||||
* If you have getopt(3), but your headerfile(s) does not declare
|
||||
* optind/optarg set this to 1, otherwise to 0
|
||||
*/
|
||||
# define NEED_OPTIND_OPTARG 0
|
||||
|
||||
/*
|
||||
* If your realloc(3) function cannot handle realloc (NULL, size), then
|
||||
* set this to 1, otherwise to 0
|
||||
*/
|
||||
# define BROKEN_REALLOC 1
|
||||
|
||||
/* -------------- END OF CHANGEABLE PART ------------------ */
|
||||
/*}}}*/
|
||||
/*{{{ auto configuration part */
|
||||
/*
|
||||
* Autoconfiguration
|
||||
*/
|
||||
# if ! HAVE_MEMCPY
|
||||
# if HAVE_BCOPY
|
||||
# define memcpy(aa,bb,cc) bcopy((bb),(aa),(cc))
|
||||
# else /* HAVE_BCOPY */
|
||||
# error "Neither memcopy() nor bcopy() available, aborted"
|
||||
# endif /* HAVE_BCOPY */
|
||||
# endif /* BSD */
|
||||
|
||||
# if BROKEN_REALLOC
|
||||
# define Realloc(ppp,sss) ((ppp) ? realloc ((ppp), (sss)) : malloc ((sss)))
|
||||
# else /* BROKEN_REALLOC */
|
||||
# define Realloc realloc
|
||||
# endif /* BROKEN_REALLOC */
|
||||
|
||||
# ifndef __GCC__
|
||||
# define inline
|
||||
# endif /* __GCC__ */
|
||||
/*}}}*/
|
||||
# endif /* __CONFIG_H */
|
|
@ -0,0 +1,12 @@
|
|||
# -*- sh -*-
|
||||
all:
|
||||
@echo -n
|
||||
|
||||
clean:
|
||||
rm -f *~ core
|
||||
|
||||
install:
|
||||
@echo -n
|
||||
|
||||
depend:
|
||||
@echo -n
|
|
@ -0,0 +1,10 @@
|
|||
Here all available contributed files, a short description and
|
||||
the author:
|
||||
|
||||
m2y.pl: Simple perl script to use yaps in a mail to pager
|
||||
enviroment. Just an example, for real use you have
|
||||
to enhance it significant. (Ulrich Dessauer)
|
||||
|
||||
tap.sl: Example for usage of scripting as a protocol
|
||||
replacement. This implements a minimal subset
|
||||
of TAP.
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/perl
|
||||
# -*- perl -*-
|
||||
# Untested mail -> yaps gateway (just an example)
|
||||
# (C) by Ulrich Dessauer
|
||||
# Create some receiver address, e.g. <nr>@yaps.<yourdomain> and
|
||||
# instruct your mailer to forward each mail to this address to
|
||||
# this script. Ensure that there is only one receiver per mail.
|
||||
#
|
||||
# To be really useful, the script must be expanded to check for
|
||||
# illegal characters in receiver/message (in this case the >'<
|
||||
# as this is used as quoting in the system() call) and handling
|
||||
# of multiple receivers in one call, etc. Happy Hacking!
|
||||
#
|
||||
# Markus <markus@mail.yezz.de> made some comments and improvments
|
||||
# to make this script slowly useful.
|
||||
#
|
||||
$yaps = "/usr/local/bin/yaps";
|
||||
$mailer = "/usr/lib/sendmail -t";
|
||||
$send_response = 1;
|
||||
#
|
||||
$recv = $ARGV[0];
|
||||
$recv = (split ('@', $recv))[0];
|
||||
die "No receiver given\n"
|
||||
unless $recv;
|
||||
undef $msg;
|
||||
undef $from;
|
||||
while (<STDIN>) {
|
||||
chomp;
|
||||
if ($_ =~ /^Subject: /i) {
|
||||
$msg = $_;
|
||||
$msg =~ s/^Subject: //i;
|
||||
undef $msg
|
||||
if $msg eq "";
|
||||
} elsif ($_ =~ /^From: /i) {
|
||||
$from = $_;
|
||||
$from =~ s/^From: //i;
|
||||
}
|
||||
}
|
||||
die "No message found\n"
|
||||
unless $msg;
|
||||
die "No sender found\n"
|
||||
unless $from;
|
||||
#
|
||||
# Avoid apostroph in command line (otherwise the shell will stumble)
|
||||
$recv =~ s/\'/\`/g;
|
||||
$msg =~ s/\'/\`/g;
|
||||
$from =~ s/\'/\`/g;
|
||||
$n = system ("$yaps '$recv' '(EMail from $from) $msg'");
|
||||
die "Unable to send message to $recv\n"
|
||||
if $n;
|
||||
if ($send_response) {
|
||||
die "Unable to invoke mailer for response\n"
|
||||
unless open (OUT, "|$mailer");
|
||||
print OUT "From: yaps-mail\n";
|
||||
print OUT "To: $from\n";
|
||||
print OUT "Subject: Message sent to $recv\n";
|
||||
print OUT "\n";
|
||||
print OUT "Your message $msg\nto $recv has been sent\n";
|
||||
close (OUT);
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
% -*- slang -*-
|
||||
%
|
||||
% (C) by Ulrich Dessauer
|
||||
%
|
||||
% This is an example for scripting by re-implementing TAP
|
||||
% using SLang. This is a minimal implementation and has not
|
||||
% all the fancy features the internal version has, but it
|
||||
% should only be an example for the usage of scripting.
|
||||
%
|
||||
%
|
||||
% Add these lines if you want to use it in your yaps.rc
|
||||
% protocol script
|
||||
% use-call-id False
|
||||
% script-type SLang
|
||||
% script-name /path/to/this/file/tap.sl
|
||||
% scr-login tap_login
|
||||
% scr-logout tap_logout
|
||||
% scr-pagerid tap_pagerid
|
||||
% scr-message tap_message
|
||||
% scr-next tap_next
|
||||
% scr-sync tap_sync
|
||||
%
|
||||
variable tap_pid = Null_String;
|
||||
variable tap_t1 = 2;
|
||||
variable tap_t3 = 10;
|
||||
|
||||
define
|
||||
tap_login (callid)
|
||||
{
|
||||
variable n, ep;
|
||||
|
||||
for (n = 0; n < 3; ++n) {
|
||||
!if (send ("\r"))
|
||||
return (ERR_FATAL);
|
||||
if (expect (tap_t1, "ID=", 1) == 1)
|
||||
break;
|
||||
}
|
||||
if (n == 3)
|
||||
return (ERR_FATAL);
|
||||
for (n = 0; n < 3; ++n) {
|
||||
!if (send ("\033PG1\r"))
|
||||
return (ERR_FATAL);
|
||||
ep = expect (tap_t3, "\x06\r", "\x15\r", "\x1b\x04\r", 3);
|
||||
if (ep == 1)
|
||||
break;
|
||||
else if ((ep == 2) or (ep == 3))
|
||||
return (ERR_ABORT);
|
||||
}
|
||||
if (n == 3)
|
||||
return (ERR_FATAL);
|
||||
if (expect (tap_t3, "\x1b[p\r", 1) != 1)
|
||||
return (ERR_ABORT);
|
||||
return (NO_ERR);
|
||||
}
|
||||
|
||||
define
|
||||
tap_logout (dummy)
|
||||
{
|
||||
variable n, ep;
|
||||
|
||||
for (n = 0; n < 3; ++n) {
|
||||
!if (send ("\x04\r"))
|
||||
return (ERR_FATAL);
|
||||
ep = expect (tap_t3, "\x1b\x04\r", "\x1e\r", 2);
|
||||
if (ep == 1)
|
||||
break;
|
||||
else if (ep != 2)
|
||||
return (ERR_FATAL);
|
||||
}
|
||||
if (n == 3)
|
||||
return (ERR_FATAL);
|
||||
return (NO_ERR);
|
||||
}
|
||||
|
||||
define
|
||||
tap_pagerid (pid)
|
||||
{
|
||||
tap_pid = conv (pid);
|
||||
return (NO_ERR);
|
||||
}
|
||||
|
||||
define
|
||||
tap_message (msg)
|
||||
{
|
||||
variable str;
|
||||
variable chk;
|
||||
variable n, ep, len;
|
||||
|
||||
str = "\x02" + tap_pid + "\r" + conv (msg) + "\r" + "\x03";
|
||||
len = strlen (str);
|
||||
chk = 0;
|
||||
for (n = 0; n < len; ++n)
|
||||
chk = chk + (str[n] & 0xff);
|
||||
str = str + Sprintf ("%c%c%c\r", ((chk shr 8) & 0xf) + 0x30, ((chk shr 4) & 0xf) + 0x30, (chk & 0xf) + 0x30, 3);
|
||||
for (n = 0; n < 3; ++n) {
|
||||
!if (send (str))
|
||||
return (ERR_FATAL);
|
||||
ep = expect (tap_t3, "\x06\r", "\x15\r", "\x1e\r", "\x1b\x04\r", 4);
|
||||
if (ep == 1)
|
||||
break;
|
||||
else if ((ep == 2) or (ep == 3))
|
||||
return (ERR_FATAL);
|
||||
else if (ep == 4)
|
||||
return (ERR_ABORT);
|
||||
}
|
||||
if (n == 3)
|
||||
return (ERR_FATAL);
|
||||
return (NO_ERR);
|
||||
}
|
||||
|
||||
define
|
||||
tap_next (dummy)
|
||||
{
|
||||
return (NO_ERR);
|
||||
}
|
||||
|
||||
define
|
||||
tap_sync (dummy)
|
||||
{
|
||||
return (ERR_FATAL);
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
# include "pager.h"
|
||||
|
||||
/*{{{ typedefs */
|
||||
typedef struct {
|
||||
# ifndef NDEBUG
|
||||
# define MAGIC MKMAGIC ('c', 'o', 'n', 'v')
|
||||
long magic;
|
||||
# endif /* NDEBUG */
|
||||
int c[256]; /* the conversion table */
|
||||
} conv;
|
||||
/*}}}*/
|
||||
/*{{{ new/free */
|
||||
void *
|
||||
cv_new (void)
|
||||
{
|
||||
conv *c;
|
||||
int n;
|
||||
|
||||
if (c = (conv *) malloc (sizeof (conv))) {
|
||||
# ifndef NDEBUG
|
||||
c -> magic = MAGIC;
|
||||
# endif /* NDEBUG */
|
||||
for (n = 0; n < 256; ++n)
|
||||
c -> c[n] = n;
|
||||
}
|
||||
return (void *) c;
|
||||
}
|
||||
|
||||
void *
|
||||
cv_free (void *cv)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
|
||||
MCHK (c);
|
||||
if (c)
|
||||
free (c);
|
||||
return NULL;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ reverse */
|
||||
void *
|
||||
cv_reverse (void *src)
|
||||
{
|
||||
conv *s = (conv *) src;
|
||||
conv *c;
|
||||
int n;
|
||||
|
||||
MCHK (s);
|
||||
if (c = (conv *) cv_new ())
|
||||
for (n = 0; n < 256; ++n)
|
||||
if (s -> c[n] != -1)
|
||||
c -> c[s -> c[n]] = n;
|
||||
return (void *) c;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ define/undefine */
|
||||
static char_t
|
||||
getval (char *str)
|
||||
{
|
||||
char_t ret;
|
||||
|
||||
if (isdigit (*str))
|
||||
ret = (char_t) strtol (str, NULL, 0);
|
||||
else if (! *(str + 1))
|
||||
ret = (char_t) *str;
|
||||
else if (*str == '^') {
|
||||
++str;
|
||||
ret = (char_t) (*str == '?' ? 0x7f : (*str & 0x1f));
|
||||
} else if (*str == '\\') {
|
||||
++str;
|
||||
switch (*str) {
|
||||
case 'a': ret = (char_t) '\a'; break;
|
||||
case 'b': ret = (char_t) '\b'; break;
|
||||
case 'e': ret = (char_t) '\x1b'; break;
|
||||
case 'f': ret = (char_t) '\f'; break;
|
||||
case 'l': ret = (char_t) '\012'; break;
|
||||
case 'n': ret = (char_t) '\n'; break;
|
||||
case 'r': ret = (char_t) '\r'; break;
|
||||
case 's': ret = (char_t) ' '; break;
|
||||
case 't': ret = (char_t) '\t'; break;
|
||||
case 'v': ret = (char_t) '\v'; break;
|
||||
default: ret = (char_t) *str; break;
|
||||
}
|
||||
} else
|
||||
ret = (char_t) *str;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
cv_define (void *cv, char_t src, char_t dst)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
|
||||
MCHK (c);
|
||||
if (c)
|
||||
c -> c[src] = dst;
|
||||
}
|
||||
|
||||
void
|
||||
cv_sdefine (void *cv, char *src, char *dst)
|
||||
{
|
||||
cv_define (cv, getval (src), getval (dst));
|
||||
}
|
||||
|
||||
void
|
||||
cv_undefine (void *cv, char_t ch)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
|
||||
MCHK (c);
|
||||
if (c)
|
||||
c -> c[ch] = ch;
|
||||
}
|
||||
|
||||
void
|
||||
cv_sundefine (void *cv, char *ch)
|
||||
{
|
||||
cv_undefine (cv, getval (ch));
|
||||
}
|
||||
|
||||
void
|
||||
cv_invalid (void *cv, char_t ch)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
|
||||
MCHK (c);
|
||||
if (c)
|
||||
c -> c[ch] = -1;
|
||||
}
|
||||
|
||||
void
|
||||
cv_sinvalid (void *cv, char *ch)
|
||||
{
|
||||
cv_invalid (cv, getval (ch));
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ read/write table */
|
||||
int
|
||||
cv_read_table (void *cv, char *fname)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
FILE *fp;
|
||||
char *line;
|
||||
char *sp, *dp;
|
||||
|
||||
MCHK (c);
|
||||
if ((! c) || (! (fp = fopen (fname, "r"))))
|
||||
return -1;
|
||||
while (line = getline (fp, True)) {
|
||||
for (sp = line; isspace (*sp); ++sp)
|
||||
;
|
||||
if (*sp && (*sp != '#')) {
|
||||
dp = skip (sp);
|
||||
skip (dp);
|
||||
if (*sp)
|
||||
if (*dp)
|
||||
c -> c[getval (sp)] = getval (dp);
|
||||
else
|
||||
c -> c[getval (sp)] = -1;
|
||||
|
||||
}
|
||||
free (line);
|
||||
}
|
||||
fclose (fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cv_write_table (void *cv, char *fname)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
FILE *fp;
|
||||
int n;
|
||||
|
||||
MCHK (c);
|
||||
if ((! c) || (! (fp = fopen (fname, "w"))))
|
||||
return -1;
|
||||
fprintf (fp, "#\tThis file is generated automatically\n");
|
||||
for (n = 0; n < 256; ++n) {
|
||||
if ((! (n & 0x80)) && isprint (n))
|
||||
fprintf (fp, "#\t%c\n", (char) n);
|
||||
if (c -> c[n] != -1)
|
||||
fprintf (fp, "0x%02x\t0x%02x\n", n, c -> c[n]);
|
||||
else
|
||||
fprintf (fp, "0x%02x\n", n);
|
||||
}
|
||||
fclose (fp);
|
||||
return 0;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ merging */
|
||||
void
|
||||
cv_merge (void *cv, void *in, Bool second)
|
||||
{
|
||||
conv *c = (conv *) cv,
|
||||
*i = (conv *) in;
|
||||
int n;
|
||||
|
||||
MCHK (c);
|
||||
MCHK (i);
|
||||
if (c && i)
|
||||
for (n = 0; n < 256; ++n)
|
||||
if (second || (c -> c[n] == n))
|
||||
c -> c[n] = i -> c[n];
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ converting */
|
||||
int
|
||||
cv_conv (void *cv, char_t ch)
|
||||
{
|
||||
conv *c = (conv *) cv;
|
||||
|
||||
MCHK (c);
|
||||
return c ? c -> c[ch] : (int) ch;
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,6 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include "pager.h"
|
||||
|
||||
int verbose = 0;
|
||||
int (*verbout) (char *, ...) = verbose_out;
|
|
@ -0,0 +1,442 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# ifdef SCRIPT_LUA
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
# include <lua.h>
|
||||
# include <lualib.h>
|
||||
# include "pager.h"
|
||||
# include "script.h"
|
||||
|
||||
# define STARTUP "Startup.lua"
|
||||
|
||||
/*{{{ statics & callable functions */
|
||||
static Bool isinit = False;
|
||||
static double lua_no_err = (double) NO_ERR,
|
||||
lua_err_fail = (double) ERR_FAIL,
|
||||
lua_err_fatal = (double) ERR_FATAL,
|
||||
lua_err_abort = (double) ERR_ABORT;
|
||||
static script *ls = NULL;
|
||||
static char *lline = NULL;
|
||||
static int lsiz = 0;
|
||||
static char *lcb = NULL;
|
||||
|
||||
static void
|
||||
lua_logger (void)
|
||||
{
|
||||
lua_Object obj;
|
||||
char *sav, *str;
|
||||
char typ;
|
||||
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) &&
|
||||
(str = lua_getstring (obj)) &&
|
||||
(sav = strdup (str))) {
|
||||
typ = *sav;
|
||||
if (((obj = lua_getparam (2)) == LUA_NOOBJECT) ||
|
||||
(! (str = lua_getstring (obj)))) {
|
||||
str = sav;
|
||||
typ = LG_INF;
|
||||
}
|
||||
if (ls && ls -> logger)
|
||||
(*ls -> logger) (typ, "%s\n", str);
|
||||
free (sav);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lua_callback (void *sp, string_t *s, char_t sep, void *data)
|
||||
{
|
||||
int len;
|
||||
char *str;
|
||||
lua_Object obj;
|
||||
|
||||
if (str = sextract (s)) {
|
||||
len = strlen (str);
|
||||
if (len + 2 >= lsiz) {
|
||||
lsiz = len + 64;
|
||||
if (! (lline = Realloc (lline, lsiz + 4)))
|
||||
lsiz = 0;
|
||||
}
|
||||
if (lline) {
|
||||
sprintf (lline, "%s%c", str, (char) sep);
|
||||
if (lcb && (obj = lua_getglobal (lcb)) && lua_isfunction (obj)) {
|
||||
lua_pushstring (lline);
|
||||
lua_callfunction (obj);
|
||||
}
|
||||
}
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lua_setcb (void)
|
||||
{
|
||||
lua_Object obj1, obj2;
|
||||
char *sep, *func;
|
||||
|
||||
if ((obj1 = lua_getparam (1)) != LUA_NOOBJECT)
|
||||
obj2 = lua_getparam (2);
|
||||
else
|
||||
obj2 = LUA_NOOBJECT;
|
||||
if (lcb) {
|
||||
free (lcb);
|
||||
lcb = NULL;
|
||||
}
|
||||
if ((obj1 == LUA_NOOBJECT) || (! lua_isstring (obj1)) || (! (sep = lua_getstring (obj1)))) {
|
||||
if (ls && ls -> sp)
|
||||
tty_set_line_callback (ls -> sp, NULL, NULL, NULL);
|
||||
} else {
|
||||
if (ls && ls -> sp)
|
||||
tty_set_line_callback (ls -> sp, lua_callback, sep, NULL);
|
||||
if ((obj2 != LUA_NOOBJECT) && lua_isstring (obj2) && (func = lua_getstring (obj2)))
|
||||
lcb = strdup (func);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lua_get_line (void)
|
||||
{
|
||||
if (lline)
|
||||
lua_pushstring (lline);
|
||||
else
|
||||
lua_pushnil ();
|
||||
}
|
||||
|
||||
static void
|
||||
lua_hangup (void)
|
||||
{
|
||||
lua_Object obj;
|
||||
double sec;
|
||||
int msec;
|
||||
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) &&
|
||||
lua_isnumber (obj)) {
|
||||
sec = lua_getnumber (obj);
|
||||
msec = (int) (sec * 1000.0);
|
||||
} else
|
||||
msec = 500;
|
||||
if (ls && ls -> sp)
|
||||
tty_hangup (ls -> sp, msec);
|
||||
}
|
||||
|
||||
static void
|
||||
do_send (Bool dcv)
|
||||
{
|
||||
int ret;
|
||||
lua_Object obj;
|
||||
char *str;
|
||||
|
||||
ret = 0;
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) &&
|
||||
lua_isstring (obj) && (str = lua_getstring (obj)))
|
||||
if (ls && ls -> sp) {
|
||||
if (dcv)
|
||||
str = scr_convert (ls, str);
|
||||
if (str) {
|
||||
if (tty_send_string (ls -> sp, str) != -1)
|
||||
ret = 1;
|
||||
if (dcv)
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
if (ret)
|
||||
lua_pushnumber (1.0);
|
||||
else
|
||||
lua_pushnil ();
|
||||
}
|
||||
|
||||
static void
|
||||
lua_send (void)
|
||||
{
|
||||
do_send (False);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_csend (void)
|
||||
{
|
||||
do_send (True);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_expect (void)
|
||||
{
|
||||
int ret;
|
||||
lua_Object obj;
|
||||
int tout;
|
||||
char *str;
|
||||
int cnt, siz;
|
||||
char **ex;
|
||||
int *len;
|
||||
int start;
|
||||
int n;
|
||||
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) && lua_isnumber (obj)) {
|
||||
tout = (int) lua_getnumber (obj);
|
||||
start = 2;
|
||||
} else {
|
||||
tout = 5;
|
||||
start = 1;
|
||||
}
|
||||
ex = NULL;
|
||||
cnt = 0;
|
||||
siz = 0;
|
||||
while (((obj = lua_getparam (start)) != LUA_NOOBJECT) &&
|
||||
lua_isstring (obj) && (str = lua_getstring (obj))) {
|
||||
if (cnt >= siz) {
|
||||
siz += 4;
|
||||
if (! (ex = (char **) Realloc (ex, (siz + 2) * sizeof (char *))))
|
||||
break;
|
||||
}
|
||||
if (ex[cnt] = strdup (str))
|
||||
++cnt;
|
||||
}
|
||||
ret = -1;
|
||||
if (ex) {
|
||||
ex[cnt] = NULL;
|
||||
if ((cnt > 0) && (len = (int *) malloc ((cnt + 1) * sizeof (int)))) {
|
||||
for (n = 0; n < cnt; ++n)
|
||||
len[n] = strlen (ex[n]);
|
||||
len[cnt] = 0;
|
||||
if (ls && ls -> sp)
|
||||
ret = tty_expect_list (ls -> sp, tout, ex, len);
|
||||
free (len);
|
||||
for (n = 0; n < cnt; ++n)
|
||||
free (ex[n]);
|
||||
}
|
||||
free (ex);
|
||||
}
|
||||
lua_pushnumber ((double) ret);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_send_expect (void)
|
||||
{
|
||||
int ret;
|
||||
lua_Object obj;
|
||||
int tout;
|
||||
char *str;
|
||||
|
||||
ret = 0;
|
||||
if ((obj = lua_getparam (1)) != LUA_NOOBJECT) {
|
||||
if (lua_isnumber (obj)) {
|
||||
tout = (int) lua_getnumber (obj);
|
||||
obj = lua_getparam (2);
|
||||
}
|
||||
if ((obj != LUA_NOOBJECT) && lua_isstring (obj) && (str = lua_getstring (obj)))
|
||||
if (ls && ls -> sp && (tty_send_expect (ls -> sp, tout, str, NULL) != -1))
|
||||
ret = 1;
|
||||
}
|
||||
if (ret)
|
||||
lua_pushnumber (1.0);
|
||||
else
|
||||
lua_pushnil ();
|
||||
}
|
||||
|
||||
static void
|
||||
lua_drain (void)
|
||||
{
|
||||
lua_Object obj;
|
||||
int sec;
|
||||
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) && lua_isnumber (obj))
|
||||
sec = (int) lua_getnumber (obj);
|
||||
else
|
||||
sec = 1;
|
||||
if (ls && ls -> sp)
|
||||
tty_drain (ls -> sp, sec);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_cvdef (void)
|
||||
{
|
||||
lua_Object obj1, obj2;
|
||||
char *src, *dst;
|
||||
int n;
|
||||
|
||||
if (ls) {
|
||||
if (! ls -> ctab)
|
||||
ls -> ctab = cv_new ();
|
||||
if (ls -> ctab)
|
||||
if (((obj1 = lua_getparam (1)) != LUA_NOOBJECT) && lua_isstring (obj1) && (src = lua_getstring (obj1))) {
|
||||
if ((obj2 = lua_getparam (2)) == LUA_NOOBJECT)
|
||||
cv_undefine (ls -> ctab, (char_t) *src);
|
||||
else if (lua_isstring (obj2) && (dst = lua_getstring (obj2)))
|
||||
cv_define (ls -> ctab, (char_t) *src, (char_t) *dst);
|
||||
else if (lua_isnumber (obj2)) {
|
||||
n = (int) lua_getnumber (obj2);
|
||||
if (n < 0)
|
||||
cv_invalid (ls -> ctab, (char_t) *src);
|
||||
else
|
||||
cv_define (ls -> ctab, (char_t) *src, (char_t) n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
lua_conv (void)
|
||||
{
|
||||
char *ret;
|
||||
lua_Object obj;
|
||||
char *str;
|
||||
|
||||
ret = NULL;
|
||||
if (((obj = lua_getparam (1)) != LUA_NOOBJECT) && lua_isstring (obj) && (str = lua_getstring (obj)))
|
||||
if (ls)
|
||||
ret = scr_convert (ls, str);
|
||||
if (ret) {
|
||||
lua_pushstring (ret);
|
||||
free (ret);
|
||||
} else
|
||||
lua_pushnil ();
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ init/deinit */
|
||||
static int
|
||||
lua_init (script *s, char *libdir)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
if (! isinit) {
|
||||
iolib_open ();
|
||||
strlib_open ();
|
||||
mathlib_open ();
|
||||
lua_pushnumber (lua_no_err); lua_storeglobal ("NO_ERR");
|
||||
lua_pushnumber (lua_err_fail); lua_storeglobal ("ERR_FAIL");
|
||||
lua_pushnumber (lua_err_fatal); lua_storeglobal ("ERR_FATAL");
|
||||
lua_pushnumber (lua_err_abort); lua_storeglobal ("ERR_ABORT");
|
||||
/* void logger (string str); */
|
||||
lua_register ("logger", lua_logger);
|
||||
/* void setcb ([string sep[, string|function func]]); */
|
||||
lua_register ("setcb", lua_setcb);
|
||||
/* string|nil get_line (void); */
|
||||
lua_register ("get_line", lua_get_line);
|
||||
/* void hangup ([num sec]); */
|
||||
lua_register ("hangup", lua_hangup);
|
||||
/* num|nil send (string line); */
|
||||
lua_register ("send", lua_send);
|
||||
/* num|nil csend (string line); */
|
||||
lua_register ("csend", lua_csend);
|
||||
/* num expect (num tout, string, s1, ..., string sn); */
|
||||
lua_register ("expect", lua_expect);
|
||||
/* num|nil send_expect (num tout, string str); */
|
||||
lua_register ("send_expect", lua_send_expect);
|
||||
/* void drain ([num sec]); */
|
||||
lua_register ("drain", lua_drain);
|
||||
/* void cvdef (string src[, string|num dst]); */
|
||||
lua_register ("cvdef", lua_cvdef);
|
||||
/* string|nil conv (string str); */
|
||||
lua_register ("conv", lua_conv);
|
||||
if (libdir && (fname = malloc (strlen (libdir) + sizeof (STARTUP) + 4))) {
|
||||
sprintf (fname, "%s/%s", libdir, STARTUP);
|
||||
if (access (fname, R_OK) != -1)
|
||||
lua_dofile (fname);
|
||||
free (fname);
|
||||
}
|
||||
lline = NULL;
|
||||
lsiz = 0;
|
||||
isinit = True;
|
||||
}
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
static void
|
||||
lua_deinit (script *s)
|
||||
{
|
||||
if (lline) {
|
||||
free (lline);
|
||||
lline = NULL;
|
||||
lsiz = 0;
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ execution */
|
||||
static int
|
||||
lua_execute (script *s, char *func, char *parm)
|
||||
{
|
||||
int err;
|
||||
lua_Object obj;
|
||||
double ret;
|
||||
|
||||
err = NO_ERR;
|
||||
if ((obj = lua_getglobal (func)) && lua_isfunction (obj)) {
|
||||
ls = s;
|
||||
lua_beginblock ();
|
||||
lua_pushnumber ((double) s -> delay.day); lua_storeglobal ("delay_day");
|
||||
lua_pushnumber ((double) s -> delay.mon); lua_storeglobal ("delay_mon");
|
||||
lua_pushnumber ((double) s -> delay.year); lua_storeglobal ("delay_year");
|
||||
lua_pushnumber ((double) s -> delay.hour); lua_storeglobal ("delay_hour");
|
||||
lua_pushnumber ((double) s -> delay.min); lua_storeglobal ("delay_min");
|
||||
lua_pushnumber ((double) s -> delay.sec); lua_storeglobal ("delay_sec");
|
||||
lua_pushnumber ((double) s -> expire.day); lua_storeglobal ("expire_day");
|
||||
lua_pushnumber ((double) s -> expire.mon); lua_storeglobal ("expire_mon");
|
||||
lua_pushnumber ((double) s -> expire.year); lua_storeglobal ("expire_year");
|
||||
lua_pushnumber ((double) s -> expire.hour); lua_storeglobal ("expire_hour");
|
||||
lua_pushnumber ((double) s -> expire.min); lua_storeglobal ("expire_min");
|
||||
lua_pushnumber ((double) s -> expire.sec); lua_storeglobal ("expire_sec");
|
||||
lua_pushnumber ((double) s -> rds); lua_storeglobal ("rds");
|
||||
if (parm)
|
||||
lua_pushstring (parm);
|
||||
else
|
||||
lua_pushnil ();
|
||||
if (lua_callfunction (obj))
|
||||
err = ERR_FATAL;
|
||||
else if ((obj = lua_getresult (1)) && (obj != LUA_NOOBJECT)) {
|
||||
ret = lua_getnumber (obj);
|
||||
if (ret == lua_no_err)
|
||||
err = NO_ERR;
|
||||
else if (ret == lua_err_fail)
|
||||
err = ERR_FAIL;
|
||||
else if (ret == lua_err_fatal)
|
||||
err = ERR_FATAL;
|
||||
else if (ret == lua_err_abort)
|
||||
err = ERR_ABORT;
|
||||
}
|
||||
lua_endblock ();
|
||||
if (ls -> sp)
|
||||
tty_set_line_callback (ls -> sp, NULL, NULL, NULL);
|
||||
ls = NULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ loading */
|
||||
static int
|
||||
lua_load_string (script *s, char *scr)
|
||||
{
|
||||
return lua_dostring (scr) ? ERR_FATAL : NO_ERR;
|
||||
}
|
||||
|
||||
static int
|
||||
lua_load_file (script *s, char *fname)
|
||||
{
|
||||
return lua_dofile (fname) ? ERR_FATAL : NO_ERR;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ preinit/postdeinit/scriptentry */
|
||||
static int
|
||||
lua_preinit (char *libdir)
|
||||
{
|
||||
return lua_init (NULL, libdir);
|
||||
}
|
||||
|
||||
static void
|
||||
lua_postdeinit (void)
|
||||
{
|
||||
lua_deinit (NULL);
|
||||
}
|
||||
|
||||
funcs flua = {
|
||||
"Lua",
|
||||
lua_init,
|
||||
lua_deinit,
|
||||
lua_execute,
|
||||
lua_load_string,
|
||||
lua_load_file,
|
||||
lua_preinit,
|
||||
lua_postdeinit
|
||||
};
|
||||
/*}}}*/
|
||||
# endif /* SCRIPT_LUA */
|
|
@ -0,0 +1,207 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# ifndef __PAGER_H
|
||||
# define __PAGER_H 1
|
||||
# include <stdio.h>
|
||||
|
||||
/*{{{ definitions, macros */
|
||||
# ifndef NDEBUG
|
||||
# define V(lvl,msg) ((void) (((lvl) <= verbose) && verbout ? (*verbout) msg, fflush (stdout) : 0))
|
||||
# define MCHK(xxx) ((void) ((xxx) && ((xxx) -> magic != MAGIC) ? fprintf (stderr, "Invalid magic: expect %ld got %ld in %s:%d\n", MAGIC, (xxx) -> magic, __FILE__, __LINE__) : 0))
|
||||
# define MKMAGIC(ch1,ch2,ch3,ch4) \
|
||||
((long) ((((unsigned char) (ch1)) << 24) | \
|
||||
(((unsigned char) (ch2)) << 16) | \
|
||||
(((unsigned char) (ch3)) << 8) | \
|
||||
((unsigned char) (ch4))))
|
||||
# else /* NDEBUG */
|
||||
# define V(lvl,msg)
|
||||
# define MCHK(xxx)
|
||||
# endif /* NDEBUG */
|
||||
|
||||
# define NO_ERR 0
|
||||
# define ERR_FAIL (-1)
|
||||
# define ERR_FATAL (-2)
|
||||
# define ERR_ABORT (-3)
|
||||
|
||||
# define ECONT(xxx) (((xxx) == NO_ERR) || ((xxx) == ERR_FAIL))
|
||||
# define ESTOP(xxx) (((xxx) == ERR_FATAL) || ((xxx) == ERR_ABORT))
|
||||
|
||||
# define LGS_SENT '+'
|
||||
# define LGF_SENT '-'
|
||||
# define LGS_INF '*'
|
||||
# define LGF_INF '/'
|
||||
|
||||
# define LG_INF 'i'
|
||||
# define LG_COST 'c'
|
||||
# define LG_SSESSION 's'
|
||||
# define LG_ESESSION 'e'
|
||||
# define LG_PROTO 'p'
|
||||
/*}}}*/
|
||||
/*{{{ typedefs */
|
||||
typedef enum {
|
||||
False = 0,
|
||||
True = ! False
|
||||
} Bool;
|
||||
|
||||
typedef enum {
|
||||
Unknown,
|
||||
Ascii,
|
||||
Script,
|
||||
Tap,
|
||||
Ucp
|
||||
} Protocol;
|
||||
|
||||
typedef unsigned char char_t;
|
||||
|
||||
typedef struct {
|
||||
char_t *str; /* the string itself */
|
||||
int len; /* the current length */
|
||||
int size; /* the allocated size */
|
||||
} string_t;
|
||||
|
||||
typedef struct {
|
||||
int day, mon, year;
|
||||
int hour, min, sec;
|
||||
} date_t;
|
||||
/*}}}*/
|
||||
/*{{{ prototypes */
|
||||
/*{{{ utility */
|
||||
extern char *skip (char *str);
|
||||
extern char *skipch (char *str, char ch);
|
||||
extern char *getline (FILE *fp, Bool cont);
|
||||
extern int verbose_out (char *, ...);
|
||||
/*}}}*/
|
||||
/*{{{ string handling */
|
||||
extern string_t *snewc (char *str);
|
||||
extern string_t *snew (char_t *str, int len);
|
||||
extern Bool sexpand (string_t *s, int nsize);
|
||||
extern Bool scopy (string_t *dst, string_t *src);
|
||||
extern Bool scat (string_t *dst, string_t *src);
|
||||
extern Bool scopyc (string_t *dst, char *src);
|
||||
extern Bool scatc (string_t *dst, char *src);
|
||||
extern string_t *scut (string_t *str, int start, int len);
|
||||
extern void sdel (string_t *str, int start, int len);
|
||||
extern Bool sput (string_t *str, string_t *ins, int pos, int len);
|
||||
extern Bool sputc (string_t *str, char *ins, int pos, int len);
|
||||
extern char *sextract (string_t *s);
|
||||
extern char *schar (string_t *s);
|
||||
extern void *sfree (string_t *s);
|
||||
extern void srelease (string_t *s);
|
||||
extern Bool siscntrl (string_t *s, int pos);
|
||||
extern Bool sisspace (string_t *s, int pos);
|
||||
extern Bool sisdigit (string_t *s, int pos);
|
||||
extern int stoi (string_t *s);
|
||||
/*}}}*/
|
||||
/*{{{ date handling */
|
||||
extern date_t *dat_free (date_t *d);
|
||||
extern date_t *dat_parse (char *str);
|
||||
extern int dat_diff (date_t *d1, date_t *d2);
|
||||
extern void dat_clear (date_t *d);
|
||||
extern void dat_localtime (date_t *d);
|
||||
/*}}}*/
|
||||
/*{{{ tty handling */
|
||||
extern void *tty_open (char *dev, char *lckprefix, char *lckmethod);
|
||||
extern void *tty_close (void *sp);
|
||||
extern Bool tty_reopen (void *s, int msec);
|
||||
extern void tty_hangup (void *sp, int msec);
|
||||
extern int tty_fd (void *sp);
|
||||
extern int tty_setup (void *sp, Bool raw, Bool modem, int speed, int bpb, int sb, char parity);
|
||||
extern void tty_set_line_callback (void *sp, void (*func) (void *, string_t *, char_t, void *), char *sep, void *data);
|
||||
extern void tty_suspend_callback (void *sp, Bool susp);
|
||||
extern int tty_send (void *sp, char *str, int len);
|
||||
extern int tty_send_string (void *sp, char *str);
|
||||
extern int tty_expect (void *sp, int tout, ...);
|
||||
extern int tty_expect_list (void *sp, int tout, char **strs, int *lens);
|
||||
extern int tty_expect_string (void *sp, int tout, char *str);
|
||||
extern int tty_send_expect (void *sp, int deftout, char *str, char **opts);
|
||||
extern void tty_mdrain (void *sp, int msecs);
|
||||
extern void tty_drain (void *sp, int secs);
|
||||
/*}}}*/
|
||||
/*{{{ configuration */
|
||||
extern void *cfg_new (char *sep);
|
||||
extern void *cfg_read (char *fname, void *bp, char *sep);
|
||||
extern void *cfg_end (void *bp);
|
||||
extern void cfg_modify (void *bp, char *bname, char *var, char *val);
|
||||
extern char *cfg_get (void *bp, char *bname, char *var, char *dflt);
|
||||
extern int cfg_iget (void *bp, char *bname, char *var, int dflt);
|
||||
extern Bool cfg_bget (void *bp, char *bname, char *var, Bool dflt);
|
||||
extern char *cfg_block_get (void *bp, char *bname, char *var, char *dflt);
|
||||
extern int cfg_block_iget (void *bp, char *bname, char *var, int dflt);
|
||||
extern Bool cfg_block_bget (void *bp, char *bname, char *var, Bool dflt);
|
||||
/*}}}*/
|
||||
/*{{{ converting */
|
||||
extern void *cv_new (void);
|
||||
extern void *cv_free (void *cv);
|
||||
extern void *cv_reverse (void *src);
|
||||
extern void cv_define (void *cv, char_t src, char_t dst);
|
||||
extern void cv_sdefine (void *cv, char *src, char *dst);
|
||||
extern void cv_undefine (void *cv, char_t ch);
|
||||
extern void cv_sundefine (void *cv, char *ch);
|
||||
extern void cv_invalid (void *cv, char_t ch);
|
||||
extern void cv_sinvalid (void *cv, char *ch);
|
||||
extern int cv_read_table (void *cv, char *fname);
|
||||
extern int cv_write_table (void *cv, char *fname);
|
||||
extern void cv_merge (void *cv, void *in, Bool second);
|
||||
extern int cv_conv (void *cv, char_t ch);
|
||||
/*}}}*/
|
||||
/*{{{ ASCII protocol */
|
||||
extern int asc_login (void *ap, string_t *callid);
|
||||
extern int asc_logout (void *ap);
|
||||
extern int asc_transmit (void *ap, char *pid, char *msg);
|
||||
extern int asc_next (void *ap);
|
||||
extern int asc_sync (void *ap);
|
||||
extern void asc_config (void *ap, void (*logger) (char, char *, ...),
|
||||
int deftout, char *alogin, char *alogout, char *apid, char *amsg, char *anext, char *async,
|
||||
date_t *delay, date_t *expire, Bool rds);
|
||||
extern void asc_set_convtable (void *ap, void *ctab);
|
||||
extern void asc_add_convtable (void *ap, void *ctab);
|
||||
extern void *asc_new (void *sp);
|
||||
extern void *asc_free (void *ap);
|
||||
extern int asc_preinit (void);
|
||||
extern void asc_postdeinit (void);
|
||||
/*}}}*/
|
||||
/*{{{ scripting protocol */
|
||||
extern int scr_execute (void *sp, char *label, char *parm);
|
||||
extern int scr_load_string (void *sp, char *scr);
|
||||
extern int scr_load_file (void *sp, char *fname);
|
||||
extern void scr_config (void *sp, void (*logger) (char, char *, ...), date_t *delay, date_t *expire, Bool rds);
|
||||
extern void scr_set_convtable (void *sp, void *ctab);
|
||||
extern void scr_add_convtable (void *sp, void *ctab);
|
||||
extern void *scr_new (void *sp, char *typ, char *libdir);
|
||||
extern void *scr_free (void *sp);
|
||||
extern int scr_preinit (char *libdir);
|
||||
extern void scr_postdeinit (void);
|
||||
/*}}}*/
|
||||
/*{{{ Telocator Alphanumeric Protocol */
|
||||
extern int tap_login (void *tp, char *stype, char ttype, char *passwd, string_t *callid);
|
||||
extern int tap_logout (void *tp);
|
||||
extern int tap_transmit (void *tp, string_t **field, Bool last);
|
||||
extern void tap_config (void *tp, void (*logger) (char, char *, ...), Bool pre16);
|
||||
extern void tap_timeouts (void *tp, int t1, int t2, int t3, int t4, int t5);
|
||||
extern void tap_retries (void *tp, int n1, int n2, int n3, int licnt, int locnt);
|
||||
extern void tap_set_convtable (void *tp, void *ctab);
|
||||
extern void tap_add_convtable (void *tp, void *ctab);
|
||||
extern void *tap_new (void *sp);
|
||||
extern void *tap_free (void *tp);
|
||||
extern int tap_preinit (void);
|
||||
extern void tap_postdeinit (void);
|
||||
/*}}}*/
|
||||
/*{{{ Universal Computer Protocol */
|
||||
extern int ucp_login (void *up, string_t *callid);
|
||||
extern int ucp_logout (void *up);
|
||||
extern int ucp_transmit (void *up, string_t *pagerid, string_t *msg, Bool last);
|
||||
extern void ucp_config (void *up, void (*logger) (char, char *, ...),
|
||||
Bool xtend, int stout, int retry, int rtout,
|
||||
date_t *delay, date_t *expire, Bool rds);
|
||||
extern void ucp_set_convtable (void *up, void *ctab);
|
||||
extern void ucp_add_convtable (void *up, void *ctab);
|
||||
extern void *ucp_new (void *sp);
|
||||
extern void *ucp_free (void *up);
|
||||
extern int ucp_preinit (void);
|
||||
extern void ucp_postdeinit (void);
|
||||
/*}}}*/
|
||||
/*}}}*/
|
||||
/*{{{ global variables */
|
||||
extern int verbose;
|
||||
extern int (*verbout) (char *, ...);
|
||||
/*}}}*/
|
||||
# endif /* __PAGER_H */
|
|
@ -0,0 +1,189 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include "pager.h"
|
||||
# include "script.h"
|
||||
|
||||
/*{{{ available scripts */
|
||||
static funcs *flist[] = {
|
||||
# ifdef SCRIPT_SLANG
|
||||
& fslang,
|
||||
# endif /* SCRIPT_SLANG */
|
||||
# ifdef SCRIPT_LUA
|
||||
& flua,
|
||||
# endif /* SCRIPT_LUA */
|
||||
NULL
|
||||
};
|
||||
/*}}}*/
|
||||
/*{{{ convert */
|
||||
char *
|
||||
scr_convert (script *s, char *str)
|
||||
{
|
||||
char *ret;
|
||||
int n, m;
|
||||
int c;
|
||||
|
||||
if (ret = malloc (strlen (str) + 1)) {
|
||||
for (n = 0, m = 0; str[n]; ++n)
|
||||
if ((c = cv_conv (s -> ctab, (char_t) str[n])) > 0)
|
||||
ret[m++] = (char) c;
|
||||
ret[m] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ execute */
|
||||
int
|
||||
scr_execute (void *sp, char *label, char *parm)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if ((! s) || (! s -> f) || (! s -> f -> fexec))
|
||||
return ERR_FATAL;
|
||||
return (*s -> f -> fexec) (s, label, parm);
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ script loading */
|
||||
int
|
||||
scr_load_string (void *sp, char *scr)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if ((! s) || (! s -> f) || (! s -> f -> fsload))
|
||||
return ERR_FATAL;
|
||||
return (*s -> f -> fsload) (s, scr);
|
||||
}
|
||||
|
||||
int
|
||||
scr_load_file (void *sp, char *fname)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if ((! s) || (! s -> f) || (! s -> f -> ffload))
|
||||
return ERR_FATAL;
|
||||
return (*s -> f -> ffload) (s, fname);
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ configuration */
|
||||
void
|
||||
scr_config (void *sp, void (*logger) (char, char *, ...), date_t *delay, date_t *expire, Bool rds)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if (s) {
|
||||
s -> logger = logger;
|
||||
if (delay)
|
||||
s -> delay = *delay;
|
||||
else
|
||||
dat_clear (& s -> delay);
|
||||
if (expire)
|
||||
s -> expire = *expire;
|
||||
else
|
||||
dat_clear (& s -> expire);
|
||||
s -> rds = False;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scr_set_convtable (void *sp, void *ctab)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if (s) {
|
||||
if (s -> ctab)
|
||||
cv_free (s -> ctab);
|
||||
s -> ctab = ctab;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
scr_add_convtable (void *sp, void *ctab)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if (s) {
|
||||
if (! s -> ctab)
|
||||
s -> ctab = cv_new ();
|
||||
if (s -> ctab)
|
||||
cv_merge (s -> ctab, ctab, True);
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ new/free/etc */
|
||||
void *
|
||||
scr_new (void *sp, char *typ, char *libdir)
|
||||
{
|
||||
script *s;
|
||||
int n;
|
||||
|
||||
if (s = (script *) malloc (sizeof (script))) {
|
||||
# ifndef NDEBUG
|
||||
s -> magic = MAGIC;
|
||||
# endif /* NDEBUG */
|
||||
s -> sp = sp;
|
||||
s -> ctab = NULL;
|
||||
s -> logger = NULL;
|
||||
dat_clear (& s -> delay);
|
||||
dat_clear (& s -> expire);
|
||||
s -> rds = False;
|
||||
s -> priv = NULL;
|
||||
for (n = 0; flist[n]; ++n)
|
||||
if (flist[n] -> typ && (! strcmp (flist[n] -> typ, typ)))
|
||||
break;
|
||||
if (flist[n]) {
|
||||
s -> f = flist[n];
|
||||
if (s -> f -> finit)
|
||||
if ((*s -> f -> finit) (s, libdir) < 0)
|
||||
s = scr_free (s);
|
||||
} else
|
||||
s = scr_free (s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void *
|
||||
scr_free (void *sp)
|
||||
{
|
||||
script *s = (script *) sp;
|
||||
|
||||
MCHK (s);
|
||||
if (s) {
|
||||
if (s -> f && s -> f -> fdeinit)
|
||||
(*s -> f -> fdeinit) (s);
|
||||
if (s -> ctab)
|
||||
cv_free (s -> ctab);
|
||||
free (s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
scr_preinit (char *libdir)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; flist[n]; ++n)
|
||||
if (flist[n] -> fpreinit)
|
||||
if ((*flist[n] -> fpreinit) (libdir) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
scr_postdeinit (void)
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; flist[n]; ++n)
|
||||
if (flist[n] -> fpostdeinit)
|
||||
(*flist[n] -> fpostdeinit) ();
|
||||
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# ifndef __SCRIPT_H
|
||||
# define __SCRIPT_H 1
|
||||
/*{{{ typedefs */
|
||||
typedef struct script script;
|
||||
|
||||
typedef struct {
|
||||
char *typ;
|
||||
int (*finit) (script *, char *);
|
||||
void (*fdeinit) (script *);
|
||||
int (*fexec) (script *, char *, char *);
|
||||
int (*fsload) (script *, char *);
|
||||
int (*ffload) (script *, char *);
|
||||
int (*fpreinit) (char *);
|
||||
void (*fpostdeinit) (void);
|
||||
} funcs;
|
||||
|
||||
struct script {
|
||||
# ifndef NDEBUG
|
||||
# define MAGIC MKMAGIC ('s', 'c', 'r', '\0')
|
||||
long magic;
|
||||
# endif /* NDEBUG */
|
||||
void *sp;
|
||||
void *ctab;
|
||||
void (*logger) (char, char *, ...);
|
||||
date_t delay;
|
||||
date_t expire;
|
||||
Bool rds;
|
||||
void *priv;
|
||||
funcs *f;
|
||||
};
|
||||
/*}}}*/
|
||||
|
||||
extern char *scr_convert (script *s, char *str);
|
||||
# ifdef SCRIPT_SLANG
|
||||
extern funcs fslang;
|
||||
# endif /* SCRIPT_SLANG */
|
||||
# ifdef SCRIPT_LUA
|
||||
extern funcs flua;
|
||||
# endif /* SCRIPT_LUA */
|
||||
# endif /* __SCRIPT_H */
|
|
@ -0,0 +1,692 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# ifdef SCRIPT_SLANG
|
||||
# ifndef FLOAT_TYPE
|
||||
# define FLOAT_TYPE
|
||||
# endif /* FLOAT_TYPE */
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
# include <slang.h>
|
||||
# include "pager.h"
|
||||
# include "script.h"
|
||||
|
||||
# define STARTUP "Startup.sl"
|
||||
|
||||
/*{{{ string class */
|
||||
static char *ifmt = NULL;
|
||||
static char *ffmt = NULL;
|
||||
|
||||
static inline char *
|
||||
make_scratch (unsigned char typ, VOID_STAR p)
|
||||
{
|
||||
char buf[128];
|
||||
|
||||
buf[0] = '\0';
|
||||
switch (typ) {
|
||||
case INT_TYPE:
|
||||
sprintf (buf, (ifmt ? ifmt : "%d"), *(int *) p);
|
||||
break;
|
||||
case FLOAT_TYPE:
|
||||
sprintf (buf, (ffmt ? ffmt : "%f"), (double) (*(float64 *) p));
|
||||
break;
|
||||
}
|
||||
return strdup (buf);
|
||||
}
|
||||
|
||||
static int
|
||||
binop_string (int op, unsigned char atyp, unsigned char btyp,
|
||||
VOID_STAR ap, VOID_STAR bp)
|
||||
{
|
||||
char *scratch;
|
||||
char *a, *b;
|
||||
int la, lb;
|
||||
int len;
|
||||
int n;
|
||||
char *ptr;
|
||||
char *res;
|
||||
|
||||
scratch = NULL;
|
||||
if ((atyp == STRING_TYPE) && (btyp == STRING_TYPE)) {
|
||||
a = (char *) ap;
|
||||
b = (char *) bp;
|
||||
} else if (atyp == STRING_TYPE) {
|
||||
a = (char *) ap;
|
||||
scratch = make_scratch (btyp, bp);
|
||||
b = scratch;
|
||||
} else {
|
||||
b = (char *) ap;
|
||||
scratch = make_scratch (atyp, ap);
|
||||
a = scratch;
|
||||
}
|
||||
if (! (a && b))
|
||||
return 0;
|
||||
res = NULL;
|
||||
switch (op) {
|
||||
case SLANG_PLUS:
|
||||
la = strlen (a);
|
||||
lb = strlen (b);
|
||||
if (res = SLMALLOC (la + lb + 1)) {
|
||||
strcpy (res, a);
|
||||
strcat (res, b);
|
||||
}
|
||||
break;
|
||||
case SLANG_MINUS:
|
||||
la = strlen (a);
|
||||
lb = strlen (b);
|
||||
if (ptr = strstr (a, b)) {
|
||||
if (res = SLMALLOC (la - lb + 1)) {
|
||||
len = (int) ((unsigned long) ptr - (unsigned long) a);
|
||||
strncpy (res, a, len);
|
||||
res[len] = '\0';
|
||||
strcat (res, a + len + lb);
|
||||
}
|
||||
} else if (res = SLMALLOC (la + 1))
|
||||
strcpy (res, a);
|
||||
break;
|
||||
case SLANG_TIMES:
|
||||
la = strlen (a);
|
||||
if ((n = atoi (b)) > 0) {
|
||||
if (res = SLMALLOC (la * n + 1)) {
|
||||
ptr = res;
|
||||
while (n-- > 0) {
|
||||
strcpy (ptr, a);
|
||||
while (*ptr)
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
} else if (res = SLMALLOC (2))
|
||||
res[0] = '\0';
|
||||
break;
|
||||
case SLANG_DIVIDE:
|
||||
for (ptr = a; *ptr; ++ptr)
|
||||
if (! strchr (b, *ptr))
|
||||
break;
|
||||
if (res = SLMALLOC (strlen (ptr) + 1)) {
|
||||
strcpy (res, ptr);
|
||||
if (res[0]) {
|
||||
for (ptr = res; *ptr; ++ptr)
|
||||
;
|
||||
--ptr;
|
||||
while (ptr != res)
|
||||
if (strchr (b, *ptr))
|
||||
*ptr-- = '\0';
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SLANG_EQ:
|
||||
SLang_push_integer (strcmp (a, b) == 0 ? 1 : 0);
|
||||
break;
|
||||
case SLANG_NE:
|
||||
SLang_push_integer (strcmp (a, b) ? 1 : 0);
|
||||
break;
|
||||
case SLANG_GT:
|
||||
SLang_push_integer (strcmp (a, b) > 0 ? 1 : 0);
|
||||
break;
|
||||
case SLANG_GE:
|
||||
SLang_push_integer (strcmp (a, b) >= 0 ? 1 : 0);
|
||||
break;
|
||||
case SLANG_LT:
|
||||
SLang_push_integer (strcmp (a, b) < 0 ? 1 : 0);
|
||||
break;
|
||||
case SLANG_LE:
|
||||
SLang_push_integer (strcmp (a, b) <= 0 ? 1 : 0);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (scratch)
|
||||
free (scratch);
|
||||
if (res)
|
||||
SLang_push_malloced_string (res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
unop_string (int op, unsigned char typ, VOID_STAR p)
|
||||
{
|
||||
char *s;
|
||||
char *r;
|
||||
int len;
|
||||
|
||||
s = (char *) p;
|
||||
switch (op) {
|
||||
case SLANG_ABS:
|
||||
SLang_push_integer (strlen (s));
|
||||
break;
|
||||
case SLANG_SIGN:
|
||||
SLang_push_integer (*s ? 1 : 0);
|
||||
break;
|
||||
case SLANG_SQR:
|
||||
break;
|
||||
case SLANG_MUL2:
|
||||
len = strlen (s);
|
||||
if (r = SLMALLOC (len * 2 + 1)) {
|
||||
strcpy (r, s);
|
||||
strcat (r, s);
|
||||
SLang_push_malloced_string (r);
|
||||
}
|
||||
break;
|
||||
case SLANG_CHS:
|
||||
SLang_push_string (s);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
get_format (char **var)
|
||||
{
|
||||
char *fmt;
|
||||
int fre;
|
||||
|
||||
if (*var) {
|
||||
free (*var);
|
||||
*var = NULL;
|
||||
}
|
||||
if (SLang_pop_string (& fmt, & fre))
|
||||
return;
|
||||
*var = strdup (fmt);
|
||||
if (fre)
|
||||
SLFREE (fmt);
|
||||
}
|
||||
|
||||
static void
|
||||
str_iformat (void)
|
||||
{
|
||||
get_format (& ifmt);
|
||||
}
|
||||
|
||||
static void
|
||||
str_fformat (void)
|
||||
{
|
||||
get_format (& ffmt);
|
||||
}
|
||||
|
||||
static SLang_Name_Type avail_string[] = {
|
||||
/* void str_iformat (string format); */
|
||||
MAKE_INTRINSIC (".str_iformat", str_iformat, VOID_TYPE, 0),
|
||||
/* void str_fformat (string format); */
|
||||
MAKE_INTRINSIC (".str_fformat", str_fformat, VOID_TYPE, 0),
|
||||
/*
|
||||
MAKE_INTRINSIC (".", , _TYPE, 0),
|
||||
MAKE_INTRINSIC (".function_name", c_function, TYPE, 0),
|
||||
MAKE_VARIABLE (".", & , TYPE, ),
|
||||
MAKE_VARIABLE (".var", &c_variable, TYPE, flag),
|
||||
*/
|
||||
SLANG_END_TABLE
|
||||
};
|
||||
|
||||
static int
|
||||
string_class (void)
|
||||
{
|
||||
if ((! SLang_register_class (STRING_TYPE, NULL, NULL)) ||
|
||||
(! SLang_add_binary_op (STRING_TYPE, STRING_TYPE,
|
||||
(VOID_STAR) binop_string)) ||
|
||||
(! SLang_add_binary_op (STRING_TYPE, INT_TYPE,
|
||||
(VOID_STAR) binop_string)) ||
|
||||
(! SLang_add_binary_op (STRING_TYPE, FLOAT_TYPE,
|
||||
(VOID_STAR) binop_string)) ||
|
||||
(! SLang_add_unary_op (STRING_TYPE,
|
||||
(VOID_STAR) unop_string)) ||
|
||||
(! SLang_add_table (avail_string, "string")))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ statics */
|
||||
static Bool isinit = False;
|
||||
static script *sls = NULL;
|
||||
static char *slline = NULL;
|
||||
static int slsiz = 0;
|
||||
static SLang_Name_Type *slcb = NULL;
|
||||
/*}}}*/
|
||||
/*{{{ callable functions and variables */
|
||||
static void
|
||||
sllogger (void)
|
||||
{
|
||||
char *str;
|
||||
int fre;
|
||||
int typ;
|
||||
|
||||
if (SLang_pop_string (& str, & fre) ||
|
||||
SLang_pop_integer (& typ))
|
||||
return;
|
||||
if (sls && sls -> logger) {
|
||||
if (! typ)
|
||||
typ = LG_INF;
|
||||
(*sls -> logger) ((char) typ, "%s\n", str);
|
||||
}
|
||||
if (fre)
|
||||
SLFREE (str);
|
||||
}
|
||||
|
||||
static void
|
||||
slcallback (void *sp, string_t *s, char_t sep, void *data)
|
||||
{
|
||||
int len;
|
||||
char *str;
|
||||
|
||||
if (str = sextract (s)) {
|
||||
len = strlen (str);
|
||||
if (len + 2 >= slsiz) {
|
||||
slsiz = len + 64;
|
||||
if (! (slline = Realloc (slline, slsiz + 4)))
|
||||
slsiz = 0;
|
||||
}
|
||||
if (slline) {
|
||||
sprintf (slline, "%s%c", str, (char) sep);
|
||||
if (slcb) {
|
||||
SLang_push_string (slline);
|
||||
SLexecute_function (slcb);
|
||||
}
|
||||
}
|
||||
free (str);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
slsetcb (void)
|
||||
{
|
||||
char *func, *sep;
|
||||
int fr1, fr2;
|
||||
|
||||
if (SLang_pop_string (& sep, & fr2) ||
|
||||
SLang_pop_string (& func, & fr1))
|
||||
return;
|
||||
if (func && *func)
|
||||
slcb = SLang_get_function (func);
|
||||
else
|
||||
slcb = NULL;
|
||||
if (sls && sls -> sp)
|
||||
tty_set_line_callback (sls -> sp, slcallback, sep, NULL);
|
||||
if (fr1)
|
||||
SLFREE (func);
|
||||
if (fr2)
|
||||
SLFREE (sep);
|
||||
}
|
||||
|
||||
static void
|
||||
slclrcb (void)
|
||||
{
|
||||
slcb = NULL;
|
||||
if (sls && sls -> sp)
|
||||
tty_set_line_callback (sls -> sp, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
slget_line (void)
|
||||
{
|
||||
SLang_push_string (slline ? slline : "");
|
||||
}
|
||||
|
||||
static void
|
||||
slhangup (void)
|
||||
{
|
||||
int msec;
|
||||
|
||||
if (SLang_pop_integer (& msec))
|
||||
return;
|
||||
if (sls && sls -> sp)
|
||||
tty_hangup (sls -> sp, msec);
|
||||
}
|
||||
|
||||
static int
|
||||
slsend (void)
|
||||
{
|
||||
int ret;
|
||||
char *str;
|
||||
int fre;
|
||||
|
||||
if (SLang_pop_string (& str, & fre))
|
||||
return 0;
|
||||
ret = 0;
|
||||
if (sls && sls -> sp)
|
||||
if (tty_send_string (sls -> sp, str) != -1)
|
||||
ret = 1;
|
||||
if (fre)
|
||||
SLFREE (str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
slcsend (void)
|
||||
{
|
||||
int ret;
|
||||
char *str;
|
||||
int fre;
|
||||
char *rstr;
|
||||
|
||||
if (SLang_pop_string (& str, & fre))
|
||||
return 0;
|
||||
ret = 0;
|
||||
if (sls && sls -> sp)
|
||||
if (rstr = scr_convert (sls, str)) {
|
||||
if (tty_send_string (sls -> sp, rstr) != -1)
|
||||
ret = 1;
|
||||
free (rstr);
|
||||
}
|
||||
if (fre)
|
||||
SLFREE (str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
slexpect (void)
|
||||
{
|
||||
int ret;
|
||||
int cnt;
|
||||
char **str;
|
||||
int *fre;
|
||||
int *len;
|
||||
int tout;
|
||||
int n;
|
||||
|
||||
if (SLang_pop_integer (& cnt))
|
||||
return -1;
|
||||
ret = -1;
|
||||
if ((str = (char **) malloc ((cnt + 2) * sizeof (char *))) &&
|
||||
(fre = (int *) malloc ((cnt + 2) * sizeof (int))) &&
|
||||
(len = (int *) malloc ((cnt + 2) * sizeof (int)))) {
|
||||
for (n = cnt - 1; n >= 0; --n)
|
||||
if (SLang_pop_string (& str[n], & fre[n]))
|
||||
return -1;
|
||||
else
|
||||
len[n] = strlen (str[n]);
|
||||
str[cnt] = NULL;
|
||||
len[cnt] = 0;
|
||||
if (SLang_pop_integer (& tout))
|
||||
return -1;
|
||||
if (sls && sls -> sp)
|
||||
ret = tty_expect_list (sls -> sp, tout, str, len);
|
||||
for (n = 0; n < cnt; ++n)
|
||||
if (fre[n])
|
||||
SLFREE (str[n]);
|
||||
free (str);
|
||||
free (fre);
|
||||
free (len);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
slsend_expect (void)
|
||||
{
|
||||
int tout;
|
||||
char *str;
|
||||
int fre;
|
||||
int ret;
|
||||
|
||||
if (SLang_pop_string (& str, & fre) ||
|
||||
SLang_pop_integer (& tout))
|
||||
return 0;
|
||||
ret = 0;
|
||||
if (sls && sls -> sp)
|
||||
if (tty_send_expect (sls -> sp, tout, str, NULL) != -1)
|
||||
ret = 1;
|
||||
if (fre)
|
||||
SLFREE (str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
sldrain (void)
|
||||
{
|
||||
int secs;
|
||||
|
||||
if (SLang_pop_integer (& secs))
|
||||
return;
|
||||
if (sls && sls -> sp)
|
||||
tty_drain (sls -> sp, secs);
|
||||
}
|
||||
|
||||
static void
|
||||
slcvdef (void)
|
||||
{
|
||||
int src, dst;
|
||||
|
||||
if (SLang_pop_integer (& dst) ||
|
||||
SLang_pop_integer (& src))
|
||||
return;
|
||||
if (sls) {
|
||||
if (! sls -> ctab)
|
||||
sls -> ctab = cv_new ();
|
||||
if (sls -> ctab)
|
||||
cv_define (sls -> ctab, (char_t) src, (char_t) dst);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
slcvundef (void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (SLang_pop_integer (& ch))
|
||||
return;
|
||||
if (sls && sls -> ctab)
|
||||
cv_undefine (sls -> ctab, (char_t) ch);
|
||||
}
|
||||
|
||||
static void
|
||||
slcvinval (void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (SLang_pop_integer (& ch))
|
||||
return;
|
||||
if (sls) {
|
||||
if (! sls -> ctab)
|
||||
sls -> ctab = cv_new ();
|
||||
if (sls -> ctab)
|
||||
cv_invalid (sls -> ctab, (char_t) ch);
|
||||
}
|
||||
}
|
||||
static void
|
||||
slconv (void)
|
||||
{
|
||||
char *str;
|
||||
int fre;
|
||||
char *rstr;
|
||||
|
||||
if (SLang_pop_string (& str, & fre))
|
||||
return;
|
||||
if (sls)
|
||||
rstr = scr_convert (sls, str);
|
||||
else
|
||||
rstr = NULL;
|
||||
SLang_push_string (rstr ? rstr : str);
|
||||
if (rstr)
|
||||
free (rstr);
|
||||
if (fre)
|
||||
SLFREE (str);
|
||||
}
|
||||
|
||||
static int no_err = NO_ERR,
|
||||
err_fail = ERR_FAIL,
|
||||
err_fatal = ERR_FATAL,
|
||||
err_abort = ERR_ABORT;
|
||||
static date_t sldelay, slexpire;
|
||||
static int slrds = 0;
|
||||
static int xFalse = (int) False,
|
||||
xTrue = (int) True;
|
||||
static char xNull_String[2] = "";
|
||||
/*}}}*/
|
||||
/*{{{ function/variable table */
|
||||
static SLang_Name_Type avail[] = {
|
||||
/* void logger (string str); */
|
||||
MAKE_INTRINSIC (".logger", sllogger, VOID_TYPE, 0),
|
||||
/* void setcb (string func, string sep); */
|
||||
MAKE_INTRINSIC (".setcb", slsetcb, VOID_TYPE, 0),
|
||||
/* void clrcb (void); */
|
||||
MAKE_INTRINSIC (".clrcb", slclrcb, VOID_TYPE, 0),
|
||||
/* string line (void); */
|
||||
MAKE_INTRINSIC (".line", slget_line, VOID_TYPE, 0),
|
||||
/* void hangup (int msec); */
|
||||
MAKE_INTRINSIC (".hangup", slhangup, VOID_TYPE, 0),
|
||||
/* int send (string str); */
|
||||
MAKE_INTRINSIC (".send", slsend, INT_TYPE, 0),
|
||||
/* int csend (string str); */
|
||||
MAKE_INTRINSIC (".csend", slcsend, INT_TYPE, 0),
|
||||
/* int expect (int tout, string e1, ..., string en,
|
||||
int cnt); */
|
||||
MAKE_INTRINSIC (".expect", slexpect, INT_TYPE, 0),
|
||||
/* int send_expect (int tout, string str); */
|
||||
MAKE_INTRINSIC (".send_expect", slsend_expect, INT_TYPE, 0),
|
||||
/* void drain (int secs); */
|
||||
MAKE_INTRINSIC (".drain", sldrain, INT_TYPE, 0),
|
||||
/* void cvdef (int src, int dst); */
|
||||
MAKE_INTRINSIC (".cvdef", slcvdef, VOID_TYPE, 0),
|
||||
/* void cvundef (int ch); */
|
||||
MAKE_INTRINSIC (".cvundef", slcvundef, VOID_TYPE, 0),
|
||||
/* void cvinval (int ch); */
|
||||
MAKE_INTRINSIC (".cvinval", slcvinval, VOID_TYPE, 0),
|
||||
/* string conv (string str); */
|
||||
MAKE_INTRINSIC (".conv", slconv, VOID_TYPE, 0),
|
||||
|
||||
MAKE_VARIABLE (".NO_ERR", & no_err, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".ERR_FAIL", & err_fail, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".ERR_FATAL", & err_fatal, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".ERR_ABORT", & err_abort, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_day", & sldelay.day, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_mon", & sldelay.mon, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_year", & sldelay.year, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_hour", & sldelay.hour, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_min", & sldelay.min, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".delay_sec", & sldelay.sec, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_day", & slexpire.day, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_mon", & slexpire.mon, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_year", & slexpire.year, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_hour", & slexpire.hour, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_min", & slexpire.min, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".expire_sec", & slexpire.sec, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".rds", & slrds, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".False", & xFalse, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".True", & xTrue, INT_TYPE, 1),
|
||||
MAKE_VARIABLE (".Null_String", & xNull_String, STRING_TYPE, 1),
|
||||
/*
|
||||
MAKE_INTRINSIC (".", , _TYPE, 0),
|
||||
MAKE_INTRINSIC (".function_name", c_function, TYPE, 0),
|
||||
MAKE_VARIABLE (".", & , TYPE, ),
|
||||
MAKE_VARIABLE (".var", &c_variable, TYPE, flag),
|
||||
*/
|
||||
SLANG_END_TABLE
|
||||
};
|
||||
/*}}}*/
|
||||
/*{{{ init/deinit */
|
||||
static int
|
||||
slang_init (script *s, char *libdir)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
if (! isinit) {
|
||||
if ((! init_SLang ()) || (! init_SLmath ()) ||
|
||||
(! init_SLunix ()) || (! init_SLfiles ()) ||
|
||||
(! string_class ()) || (! SLang_add_table (avail, "yaps")))
|
||||
return -1;
|
||||
if (libdir && (fname = malloc (strlen (libdir) + sizeof (STARTUP) + 4))) {
|
||||
sprintf (fname, "%s/%s", libdir, STARTUP);
|
||||
if (access (fname, R_OK) != -1)
|
||||
if ((! SLang_load_file (fname)) || SLang_Error)
|
||||
SLang_restart (1);
|
||||
free (fname);
|
||||
}
|
||||
isinit = True;
|
||||
}
|
||||
if (slline)
|
||||
slline[0] = '\0';
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
static void
|
||||
slang_deinit (script *s)
|
||||
{
|
||||
if (slline) {
|
||||
free (slline);
|
||||
slline = NULL;
|
||||
}
|
||||
slsiz = 0;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ execute */
|
||||
static int
|
||||
slang_execute (script *s, char *label, char *parm)
|
||||
{
|
||||
SLang_Name_Type *func;
|
||||
int ret;
|
||||
|
||||
ret = NO_ERR;
|
||||
if (func = SLang_get_function (label)) {
|
||||
SLang_push_string (parm ? parm : "");
|
||||
sldelay = s -> delay;
|
||||
slexpire = s -> expire;
|
||||
slrds = s -> rds;
|
||||
sls = s;
|
||||
SLexecute_function (func);
|
||||
if (sls -> sp)
|
||||
tty_set_line_callback (sls -> sp, NULL, NULL, NULL);
|
||||
sls = NULL;
|
||||
if (SLang_Error || SLang_pop_integer (& ret)) {
|
||||
ret = ERR_FATAL;
|
||||
SLang_restart (1);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ loading */
|
||||
static int
|
||||
slang_load_string (script *s, char *scr)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ERR_FATAL;
|
||||
if (SLang_load_string (scr) && (! SLang_Error))
|
||||
err = NO_ERR;
|
||||
else
|
||||
SLang_restart (1);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
slang_load_file (script *s, char *fname)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = ERR_FATAL;
|
||||
if (SLang_load_file (fname) && (! SLang_Error))
|
||||
err = NO_ERR;
|
||||
else
|
||||
SLang_restart (1);
|
||||
return err;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ preinit/postdeinit/scriptentry */
|
||||
static int
|
||||
slang_preinit (char *libdir)
|
||||
{
|
||||
return slang_init (NULL, libdir);
|
||||
}
|
||||
|
||||
static void
|
||||
slang_postdeinit (void)
|
||||
{
|
||||
slang_deinit (NULL);
|
||||
}
|
||||
|
||||
funcs fslang = {
|
||||
"SLang",
|
||||
slang_init,
|
||||
slang_deinit,
|
||||
slang_execute,
|
||||
slang_load_string,
|
||||
slang_load_file,
|
||||
slang_preinit,
|
||||
slang_postdeinit
|
||||
};
|
||||
/*}}}*/
|
||||
# endif /* SCRIPT_SLANG */
|
|
@ -0,0 +1,725 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <ctype.h>
|
||||
# include <string.h>
|
||||
# include "pager.h"
|
||||
|
||||
/*{{{ definitions & typedefs */
|
||||
# define DEF_SERVICE_TYPE "PG"
|
||||
# define DEF_TERMINAL_TYPE '1'
|
||||
|
||||
# define CHKTYPE(sss,ccc) ((((sss)[0] & 0xff) << 16) | (((sss)[1] & 0xff) << 8) | ((ccc) & 0xff))
|
||||
# define CHKSTYPE(cc1,cc2,cc3) ((((cc1) & 0xff) << 16) | (((cc2) & 0xff) << 8) | ((cc3) & 0xff))
|
||||
|
||||
typedef enum {
|
||||
None,
|
||||
PG1
|
||||
} Type;
|
||||
|
||||
typedef struct _rmsg {
|
||||
string_t *str;
|
||||
int rnr;
|
||||
struct _rmsg *next;
|
||||
} rmsg;
|
||||
|
||||
typedef struct {
|
||||
# ifndef NDEBUG
|
||||
# define MAGIC MKMAGIC ('t', 'a', 'p', '\0')
|
||||
long magic;
|
||||
# endif /* NDEBUG */
|
||||
void *sp; /* the serial connection */
|
||||
void *ctab; /* the conversion table */
|
||||
void (*logger) (char, char *, ...);
|
||||
string_t
|
||||
*callid; /* caller id */
|
||||
Type typ; /* the connection type */
|
||||
Bool pre16; /* if p.version before 1.6 is used */
|
||||
/* timing and retry values */
|
||||
int t1, t2, t3, t4, t5;
|
||||
int n1, n2, n3;
|
||||
int licnt, locnt;
|
||||
|
||||
rmsg *r, *prv; /* response message(s) on callback */
|
||||
} tap;
|
||||
/*}}}*/
|
||||
/*{{{ convert */
|
||||
static int
|
||||
field_convert (tap *t, string_t *ptr, string_t *cf)
|
||||
{
|
||||
int n;
|
||||
int ch;
|
||||
|
||||
cf -> str = NULL;
|
||||
cf -> size = ptr -> len + 32;
|
||||
if (! (cf -> str = malloc (cf -> size + 2)))
|
||||
return ERR_FATAL;
|
||||
for (n = 0, cf -> len = 0; n < ptr -> len; ++n) {
|
||||
if (cf -> len + 2 >= cf -> size)
|
||||
if (! sexpand (cf, cf -> size + 32))
|
||||
return ERR_FATAL;
|
||||
ch = cv_conv (t -> ctab, ptr -> str[n]);
|
||||
if (ch != -1)
|
||||
switch ((char_t) ch) {
|
||||
case '\x0d': case '\x0a': case '\x1b':
|
||||
case '\x02': case '\x03': case '\x1f':
|
||||
case '\x17': case '\x04': case '\x1a':
|
||||
if (! t -> pre16) {
|
||||
cf -> str[cf -> len++] = '\x1a';
|
||||
cf -> str[cf -> len++] = (char_t) (ch + 0x40);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
cf -> str[cf -> len++] = (char_t) ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cf -> str) {
|
||||
cf -> str[cf -> len] = '\0';
|
||||
return NO_ERR;
|
||||
}
|
||||
return ERR_FATAL;
|
||||
}
|
||||
|
||||
static char chkstr[] = "0123456789:;<=>?";
|
||||
static string_t **
|
||||
convert_tap (tap *t, string_t **field)
|
||||
{
|
||||
string_t **ret;
|
||||
int fcnt;
|
||||
string_t *cf;
|
||||
char_t *ptr;
|
||||
int cnt, siz;
|
||||
char_t tmp[260];
|
||||
Bool needchk;
|
||||
unsigned long chk;
|
||||
int fld, off, len;
|
||||
int n, m;
|
||||
|
||||
ret = NULL;
|
||||
for (fcnt = 0; field[fcnt]; ++fcnt)
|
||||
;
|
||||
if (cf = (string_t *) malloc ((fcnt + 1) * sizeof (string_t))) {
|
||||
for (fld = 0; fld < fcnt; ++fld)
|
||||
if (field_convert (t, field[fld], & cf[fld]) != NO_ERR) {
|
||||
while (--fld >= 0)
|
||||
free (cf[fld].str);
|
||||
free (cf);
|
||||
break;
|
||||
}
|
||||
if (fld < fcnt)
|
||||
return NULL;
|
||||
cnt = 0;
|
||||
siz = 0;
|
||||
n = 0;
|
||||
needchk = False;
|
||||
for (fld = 0, off = 0; fld < fcnt; ) {
|
||||
ptr = cf[fld].str + off;
|
||||
len = cf[fld].len - off;
|
||||
do {
|
||||
if (! n)
|
||||
tmp[n++] = '\x02';
|
||||
if (len) {
|
||||
tmp[n++] = *ptr++;
|
||||
--len;
|
||||
++off;
|
||||
}
|
||||
if (! len) {
|
||||
off = 0;
|
||||
++fld;
|
||||
tmp[n++] = '\r';
|
||||
if (fld == fcnt) {
|
||||
tmp[n++] = '\x03';
|
||||
needchk = True;
|
||||
} else if (n >= 230) {
|
||||
tmp[n++] = '\x17';
|
||||
needchk = True;
|
||||
}
|
||||
} else if (n >= 250) {
|
||||
tmp[n++] = '\x1f';
|
||||
needchk = True;
|
||||
}
|
||||
if (needchk) {
|
||||
needchk = False;
|
||||
for (m = 0, chk = 0; m < n; ++m)
|
||||
chk += tmp[m] & 0xff;
|
||||
tmp[n++] = chkstr[(chk >> 8) & 0xf];
|
||||
tmp[n++] = chkstr[(chk >> 4) & 0xf];
|
||||
tmp[n++] = chkstr[chk & 0xf];
|
||||
tmp[n++] = '\r';
|
||||
tmp[n] = '\0';
|
||||
if (cnt >= siz) {
|
||||
siz += 4;
|
||||
if (! (ret = (string_t **) Realloc (ret, (siz + 1) * sizeof (string_t *))))
|
||||
return NULL;
|
||||
}
|
||||
if (! (ret[cnt] = snew (tmp, n))) {
|
||||
while (--cnt >= 0)
|
||||
sfree (ret[cnt]);
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
++cnt;
|
||||
ret[cnt] = NULL;
|
||||
n = 0;
|
||||
}
|
||||
} while (len);
|
||||
}
|
||||
for (fld = 0; fld < fcnt; ++fld)
|
||||
free (cf[fld].str);
|
||||
free (cf);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ callback interface for receiving response numbers */
|
||||
static void
|
||||
getresponse (void *sp, string_t *s, char_t ch, void *data)
|
||||
{
|
||||
tap *t = (tap *) data;
|
||||
rmsg *r;
|
||||
|
||||
if (t && (! t -> pre16) && s && (s -> len > 0))
|
||||
if (sisdigit (s, 0)) {
|
||||
if (r = (rmsg *) malloc (sizeof (rmsg)))
|
||||
if (r -> str = snew (s -> str, s -> len + 2)) {
|
||||
r -> rnr = stoi (r -> str);
|
||||
r -> next = NULL;
|
||||
if (t -> prv)
|
||||
t -> prv -> next = r;
|
||||
else
|
||||
t -> r = r;
|
||||
t -> prv = r;
|
||||
} else
|
||||
free (r);
|
||||
} else if ((! siscntrl (s, 0)) && (r = t -> prv) && scatc (r -> str, "\n")) {
|
||||
if (sisspace (s, 0))
|
||||
sdel (s, 0, 1);
|
||||
scat (r -> str, s);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_resp (tap *t)
|
||||
{
|
||||
rmsg *tmp;
|
||||
|
||||
if (t) {
|
||||
while (t -> r) {
|
||||
tmp = t -> r;
|
||||
t -> r = t -> r -> next;
|
||||
sfree (tmp -> str);
|
||||
free (tmp);
|
||||
}
|
||||
t -> prv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
setcb (tap *t)
|
||||
{
|
||||
if (! t -> pre16) {
|
||||
free_resp (t);
|
||||
tty_suspend_callback (t -> sp, False);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clrcb (tap *t)
|
||||
{
|
||||
if (! t -> pre16) {
|
||||
tty_suspend_callback (t -> sp, True);
|
||||
free_resp (t);
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ response handling */
|
||||
static int
|
||||
show_response (tap *t)
|
||||
{
|
||||
rmsg *r;
|
||||
int nr, typ;
|
||||
char *line, *ptr;
|
||||
|
||||
for (r = t -> r, nr = -1; r; r = r -> next) {
|
||||
nr = r -> rnr;
|
||||
if (line = sextract (r -> str)) {
|
||||
for (ptr = line; isdigit (*ptr); ++ptr)
|
||||
;
|
||||
while (isspace (*ptr))
|
||||
++ptr;
|
||||
} else
|
||||
ptr = "(none)";
|
||||
switch (nr) {
|
||||
case 110:
|
||||
V (1, ("TAP Version: %s\n", ptr));
|
||||
break;
|
||||
case 111:
|
||||
V (1, ("processing input\n"));
|
||||
break;
|
||||
case 112:
|
||||
V (1, ("maximum pages entered\n"));
|
||||
break;
|
||||
case 113:
|
||||
V (1, ("maximum time reached\n"));
|
||||
break;
|
||||
case 114:
|
||||
V (1, ("Welcome: %s\n", ptr));
|
||||
break;
|
||||
case 115:
|
||||
V (1, ("Byebye: %s\n", ptr));
|
||||
break;
|
||||
case 211:
|
||||
V (1, ("Page(s) sent successful\n"));
|
||||
break;
|
||||
case 212:
|
||||
V (1, ("Long message truncated and sent\n"));
|
||||
break;
|
||||
case 213:
|
||||
V (1, ("Message accepted - held for deferred delivery\n"));
|
||||
break;
|
||||
case 214:
|
||||
V (1, ("%d character maximum, message has been truncated and sent\n", atoi (ptr)));
|
||||
break;
|
||||
case 501:
|
||||
V (1, ("Timeout during input\n"));
|
||||
break;
|
||||
case 502:
|
||||
V (1, ("Unexpected character received before transaction\n"));
|
||||
break;
|
||||
case 503:
|
||||
V (1, ("Excessive attempts to send/re-send a transaction with checksum errors\n"));
|
||||
break;
|
||||
case 504:
|
||||
V (1, ("Message have to be empty for tone-only pager\n"));
|
||||
break;
|
||||
case 505:
|
||||
V (1, ("Message must not contain characters for a numeric pager\n"));
|
||||
break;
|
||||
case 506:
|
||||
V (1, ("Excessive invalid pages received\n"));
|
||||
break;
|
||||
case 507:
|
||||
V (1, ("Invalid logon attempt: Incorrectly formed logon sequence\n"));
|
||||
break;
|
||||
case 508:
|
||||
V (1, ("Invalid Logon attempt: Service type and category given is not supported\n"));
|
||||
break;
|
||||
case 509:
|
||||
V (1, ("Invalid Logon attempt: Invalid password supplied\n"));
|
||||
break;
|
||||
case 510:
|
||||
V (1, ("Illegal Pager ID\n"));
|
||||
break;
|
||||
case 511:
|
||||
V (1, ("Invalid Pager ID\n"));
|
||||
break;
|
||||
case 512:
|
||||
V (1, ("Temporarily cannot deliver to Pager ID\n"));
|
||||
break;
|
||||
case 513:
|
||||
V (1, ("Long message rejected for exceeding maximum character length\n"));
|
||||
break;
|
||||
case 514:
|
||||
V (1, ("Checksum error\n"));
|
||||
break;
|
||||
case 515:
|
||||
V (1, ("Message format error\n"));
|
||||
break;
|
||||
case 516:
|
||||
V (1, ("Message quota temporarily exceeded\n"));
|
||||
break;
|
||||
case 517:
|
||||
V (1, ("%d character maximum, message rejected\n", atoi (ptr)));
|
||||
break;
|
||||
default:
|
||||
typ = nr / 100;
|
||||
switch (typ) {
|
||||
default:
|
||||
V (1, ("Response"));
|
||||
break;
|
||||
case 1:
|
||||
V (1, ("Informal"));
|
||||
break;
|
||||
case 2:
|
||||
V (1, ("Success"));
|
||||
break;
|
||||
case 5:
|
||||
V (1, ("Fail"));
|
||||
break;
|
||||
}
|
||||
V (1, (" %03d: %s\n", r -> rnr, ptr));
|
||||
break;
|
||||
}
|
||||
if (line)
|
||||
free (line);
|
||||
}
|
||||
return nr;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ login/logout */
|
||||
int
|
||||
tap_login (void *tp, char *stype, char ttype, char *passwd, string_t *callid)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
int n, ep;
|
||||
char *cbuf;
|
||||
int clen;
|
||||
int err;
|
||||
|
||||
MCHK (t);
|
||||
if ((! t) || (! t -> sp))
|
||||
return ERR_ABORT;
|
||||
if (! stype)
|
||||
stype = DEF_SERVICE_TYPE;
|
||||
else if (strlen (stype) != 2) {
|
||||
V (1, ("Invalid service type %s\n", stype));
|
||||
return ERR_ABORT;
|
||||
}
|
||||
if (! ttype)
|
||||
ttype = DEF_TERMINAL_TYPE;
|
||||
switch (CHKTYPE (stype, ttype)) {
|
||||
case CHKSTYPE ('P', 'G', '1'):
|
||||
t -> typ = PG1;
|
||||
break;
|
||||
}
|
||||
if (t -> typ == None) {
|
||||
V (1, ("Invalid service/terminal type combination\n"));
|
||||
return ERR_ABORT;
|
||||
}
|
||||
t -> callid = sfree (t -> callid);
|
||||
if (callid && (! (t -> callid = snew (callid -> str, callid -> len))))
|
||||
return ERR_ABORT;
|
||||
for (n = 0; n < t -> n1; ++n)
|
||||
if (tty_send (t -> sp, "\r", 1) != 1)
|
||||
V (1, ("Unable to send initial CR\n"));
|
||||
else if (tty_expect (t -> sp, t -> t1, "ID=", 3, NULL) == 1) {
|
||||
V (1, ("Send initial CR\n"));
|
||||
break;
|
||||
}
|
||||
if (n == t -> n1) {
|
||||
V (1, ("Didn't got initial response\n"));
|
||||
return ERR_ABORT;
|
||||
}
|
||||
if (cbuf = malloc ((passwd ? strlen (passwd) : 0) + strlen (stype) + 16)) {
|
||||
if (passwd)
|
||||
sprintf (cbuf, "\x1b%s%c%s\r", stype, ttype, passwd);
|
||||
else
|
||||
sprintf (cbuf, "\x1b%s%c\r", stype, ttype);
|
||||
clen = strlen (cbuf);
|
||||
} else {
|
||||
V (1, ("Out of memory!\n"));
|
||||
return ERR_ABORT;
|
||||
}
|
||||
err = NO_ERR;
|
||||
for (n = 0; n < t -> licnt; ++n)
|
||||
if (tty_send (t -> sp, cbuf, clen) != clen)
|
||||
V (1, ("Unable to send Logon request\n"));
|
||||
else {
|
||||
setcb (t);
|
||||
ep = tty_expect (t -> sp, t -> t3, "\x06\r", 2, "ID=", 3, "\x15\r", 2, "\x1b\x04\r", 3, NULL);
|
||||
if ((! t -> pre16) && t -> r)
|
||||
show_response (t);
|
||||
if (ep == 1) {
|
||||
V (1, ("Login request accepted\n"));
|
||||
break;
|
||||
} else if (ep == 2)
|
||||
V (1, ("Oops, got ID= again\n"));
|
||||
else if (ep == 3)
|
||||
V (1, ("Login request not accepted\n"));
|
||||
else if (ep == 4) {
|
||||
V (1, ("Logout forced\n"));
|
||||
n = t -> licnt;
|
||||
err = ERR_ABORT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
free (cbuf);
|
||||
clrcb (t);
|
||||
if (n == t -> licnt) {
|
||||
V (1, ("Could not login\n"));
|
||||
return (err == NO_ERR) ? ERR_FATAL : err;
|
||||
}
|
||||
if (tty_expect (t -> sp, t -> t3, "\x1b[p\r", 4, NULL) != 1) {
|
||||
V (1, ("Didn't got Go Ahead message\n"));
|
||||
return ERR_FATAL;
|
||||
} else
|
||||
V (1, ("Successful login\n"));
|
||||
return NO_ERR;
|
||||
}
|
||||
|
||||
int
|
||||
tap_logout (void *tp)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
int err;
|
||||
int n, ep;
|
||||
|
||||
MCHK (t);
|
||||
if ((! t) || (! t -> sp))
|
||||
return ERR_FATAL;
|
||||
err = NO_ERR;
|
||||
for (n = 0; n < t -> locnt; ++n)
|
||||
if (tty_send (t -> sp, "\x04\r", 2) != 2)
|
||||
V (1, ("Unable to send logout request\n"));
|
||||
else {
|
||||
setcb (t);
|
||||
ep = tty_expect (t -> sp, t -> t3, "\x1b\x04\r", 3, "\x1e\r", 2, NULL);
|
||||
if ((! t -> pre16) && t -> r)
|
||||
show_response (t);
|
||||
if (ep == 1) {
|
||||
V (1, ("Message sending completed\n"));
|
||||
break;
|
||||
} else if (ep == 2) {
|
||||
V (1, ("Message sending failed (%d)\n", ep));
|
||||
err = ERR_FATAL;
|
||||
n = t -> locnt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
clrcb (t);
|
||||
if (n == t -> locnt) {
|
||||
if (err == NO_ERR)
|
||||
err = ERR_FAIL;
|
||||
V (1, ("Unable to logout\n"));
|
||||
return err;
|
||||
} else
|
||||
V (1, ("Logout successful\n"));
|
||||
return NO_ERR;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ transmit */
|
||||
int
|
||||
tap_transmit (void *tp, string_t **field, Bool last)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
int err;
|
||||
string_t **snd;
|
||||
char *ptr;
|
||||
int len;
|
||||
int n, m, ep;
|
||||
|
||||
MCHK (t);
|
||||
if ((! t) || (! t -> sp))
|
||||
return ERR_FATAL;
|
||||
switch (t -> typ) {
|
||||
default:
|
||||
case None:
|
||||
V (1, ("Invalid service/terminal type\n"));
|
||||
return ERR_FAIL;
|
||||
case PG1:
|
||||
for (n = 0; field[n]; ++n)
|
||||
;
|
||||
if (n != 2) {
|
||||
V (1, ("PG1 service/terminal type needs exactly two fields\n"));
|
||||
return ERR_FAIL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
err = ERR_FATAL;
|
||||
if (snd = convert_tap (t, field)) {
|
||||
err = NO_ERR;
|
||||
for (m = 0; snd[m]; ++m) {
|
||||
ptr = (char *) snd[m] -> str;
|
||||
len = snd[m] -> len;
|
||||
for (n = 0; n < t -> n2; ++n)
|
||||
if (tty_send (t -> sp, ptr, len) != len)
|
||||
V (1, ("Unable to transmit part\n"));
|
||||
else {
|
||||
setcb (t);
|
||||
ep = tty_expect (t -> sp, t -> t3, "\x06\r", 2, "\x15\r", 2, "\x1e\r", 2, "\x1b\x04\r", 3, NULL);
|
||||
if ((! t -> pre16) && t -> r)
|
||||
show_response (t);
|
||||
if (ep == 1) {
|
||||
V (1, ("Transmited part\n"));
|
||||
break;
|
||||
} else if (ep == 2)
|
||||
V (1, ("Can't transmit part\n"));
|
||||
else if (ep == 3) {
|
||||
V (1, ("Can't transmit this message\n"));
|
||||
err = ERR_FAIL;
|
||||
n = t -> n2;
|
||||
break;
|
||||
} else if (ep == 4) {
|
||||
V (1, ("Logout forced\n"));
|
||||
err = ERR_ABORT;
|
||||
n = t -> n2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sfree (snd[m]);
|
||||
clrcb (t);
|
||||
if (n == t -> n2) {
|
||||
V (1, ("Unable to send part %d\n", m));
|
||||
for (n = m + 1; snd[n]; ++n)
|
||||
sfree (snd[n]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! snd[m])
|
||||
V (1, ("Sent message\n"));
|
||||
else if (err == NO_ERR)
|
||||
err = ERR_FAIL;
|
||||
free (snd);
|
||||
} else
|
||||
V (1, ("Unable to convert message\n"));
|
||||
return err;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ configuration */
|
||||
void
|
||||
tap_config (void *tp, void (*logger) (char, char *, ...), Bool pre16)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
t -> logger = logger;
|
||||
if (t -> pre16 = pre16)
|
||||
tty_suspend_callback (t -> sp, True);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tap_timeouts (void *tp, int t1, int t2, int t3, int t4, int t5)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
if (t1 != -1)
|
||||
t -> t1 = t1;
|
||||
if (t2 != -1)
|
||||
t -> t2 = t2;
|
||||
if (t3 != -1)
|
||||
t -> t3 = t3;
|
||||
if (t4 != -1)
|
||||
t -> t4 = t4;
|
||||
if (t5 != -1)
|
||||
t -> t5 = t5;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tap_retries (void *tp, int n1, int n2, int n3, int licnt, int locnt)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
if (n1 != -1)
|
||||
t -> n1 = n1;
|
||||
if (n2 != -1)
|
||||
t -> n2 = n2;
|
||||
if (n3 != -1)
|
||||
t -> n3 = n3;
|
||||
if (licnt != -1)
|
||||
t -> licnt = licnt;
|
||||
if (locnt != -1)
|
||||
t -> locnt = locnt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
tap_set_convtable (void *tp, void *ctab)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
if (t -> ctab)
|
||||
cv_free (t -> ctab);
|
||||
t -> ctab = ctab;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
new_convtab (tap *t)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (t -> ctab = cv_new ())
|
||||
for (n = 128; n < 256; ++n)
|
||||
cv_invalid (t -> ctab, (char_t) n);
|
||||
}
|
||||
|
||||
void
|
||||
tap_add_convtable (void *tp, void *ctab)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
if (! t -> ctab)
|
||||
new_convtab (t);
|
||||
if (t -> ctab)
|
||||
cv_merge (t -> ctab, ctab, True);
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ new/free/etc */
|
||||
void *
|
||||
tap_new (void *sp)
|
||||
{
|
||||
tap *t;
|
||||
|
||||
if (t = (tap *) malloc (sizeof (tap))) {
|
||||
# ifndef NDEBUG
|
||||
t -> magic = MAGIC;
|
||||
# endif /* NDEBUG */
|
||||
t -> sp = sp;
|
||||
new_convtab (t);
|
||||
t -> logger = NULL;
|
||||
t -> callid = NULL;
|
||||
t -> typ = None;
|
||||
t -> pre16 = False;
|
||||
t -> t1 = 2;
|
||||
t -> t2 = 1;
|
||||
t -> t3 = 10;
|
||||
t -> t4 = 4;
|
||||
t -> t5 = 8;
|
||||
t -> n1 = 3;
|
||||
t -> n2 = 3;
|
||||
t -> n3 = 3;
|
||||
t -> licnt = 3;
|
||||
t -> locnt = 3;
|
||||
t -> r = NULL;
|
||||
t -> prv = NULL;
|
||||
tty_set_line_callback (t -> sp, getresponse, "\r", (void *) t);
|
||||
tty_suspend_callback (t -> sp, True);
|
||||
}
|
||||
return (void *) t;
|
||||
}
|
||||
|
||||
void *
|
||||
tap_free (void *tp)
|
||||
{
|
||||
tap *t = (tap *) tp;
|
||||
|
||||
MCHK (t);
|
||||
if (t) {
|
||||
if (t -> ctab)
|
||||
cv_free (t -> ctab);
|
||||
if (t -> sp)
|
||||
tty_set_line_callback (t -> sp, NULL, NULL, NULL);
|
||||
if (t -> callid)
|
||||
sfree (t -> callid);
|
||||
if (t -> r)
|
||||
free_resp (t);
|
||||
free (t);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
tap_preinit (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
tap_postdeinit (void)
|
||||
{
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,596 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <stdarg.h>
|
||||
# include <ctype.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# include "pager.h"
|
||||
|
||||
/*{{{ utility functions */
|
||||
char *
|
||||
skip (char *str)
|
||||
{
|
||||
while (*str && (! isspace (*str)))
|
||||
++str;
|
||||
if (*str) {
|
||||
*str++ = '\0';
|
||||
while (isspace (*str))
|
||||
++str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *
|
||||
skipch (char *str, char ch)
|
||||
{
|
||||
while (*str && (*str != ch))
|
||||
++str;
|
||||
if (*str) {
|
||||
*str++ = '\0';
|
||||
while (isspace (*str))
|
||||
++str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *
|
||||
getline (FILE *fp, Bool cont)
|
||||
{
|
||||
char *buf;
|
||||
int size;
|
||||
char *ret;
|
||||
int len;
|
||||
char *ptr;
|
||||
|
||||
size = 256;
|
||||
if (! (buf = malloc (size + 2)))
|
||||
return NULL;
|
||||
len = 0;
|
||||
while (ret = fgets (buf + len, size - len - 2, fp)) {
|
||||
if (ptr = strchr (buf + len, '\n')) {
|
||||
*ptr = '\0';
|
||||
len += strlen (buf + len);
|
||||
if (! cont)
|
||||
break;
|
||||
if (len && (buf[len - 1] == '\\')) {
|
||||
--len;
|
||||
buf[len] = '\0';
|
||||
} else
|
||||
break;
|
||||
} else
|
||||
len += strlen (buf + len);
|
||||
if (len + 64 >= size) {
|
||||
size += size;
|
||||
if (! (buf = Realloc (buf, size + 2)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((! ret) && buf) {
|
||||
free (buf);
|
||||
buf = NULL;
|
||||
}
|
||||
return len || ret ? buf : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
verbose_out (char *fmt, ...)
|
||||
{
|
||||
va_list par;
|
||||
|
||||
va_start (par, fmt);
|
||||
vfprintf (stdout, fmt, par);
|
||||
va_end (par);
|
||||
return 0;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ string_t handling */
|
||||
string_t *
|
||||
snewc (char *str)
|
||||
{
|
||||
string_t *s;
|
||||
|
||||
if (s = (string_t *) malloc (sizeof (string_t))) {
|
||||
s -> str = NULL;
|
||||
if (str) {
|
||||
s -> len = strlen (str);
|
||||
s -> size = s -> len + 1;
|
||||
if (s -> str = (char_t *) malloc (sizeof (char_t) * s -> size))
|
||||
memcpy (s -> str, str, s -> len);
|
||||
else {
|
||||
free (s);
|
||||
s = NULL;
|
||||
}
|
||||
} else {
|
||||
s -> len = 0;
|
||||
s -> size = 0;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
string_t *
|
||||
snew (char_t *str, int len)
|
||||
{
|
||||
string_t *s;
|
||||
|
||||
if (s = (string_t *) malloc (sizeof (string_t))) {
|
||||
s -> str = NULL;
|
||||
s -> len = 0;
|
||||
s -> size = 0;
|
||||
if (len > 0)
|
||||
if (s -> str = (char_t *) malloc (sizeof (char_t) * (len + 1))) {
|
||||
s -> size = len + 1;
|
||||
if (str) {
|
||||
s -> len = len;
|
||||
memcpy (s -> str, str, len);
|
||||
} else
|
||||
s -> len = 0;
|
||||
} else {
|
||||
free (s);
|
||||
s = NULL;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Bool
|
||||
sexpand (string_t *s, int nsize)
|
||||
{
|
||||
if (s && (nsize + 2 > s -> size)) {
|
||||
s -> size = nsize + 2;
|
||||
if (! (s -> str = (char_t *) Realloc (s -> str, sizeof (char_t) * s -> size))) {
|
||||
s -> size = 0;
|
||||
s -> len = 0;
|
||||
return False;
|
||||
}
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
scopy (string_t *dst, string_t *src)
|
||||
{
|
||||
if (dst && src && sexpand (dst, src -> len + 1)) {
|
||||
if (src -> str) {
|
||||
memcpy (dst -> str, src -> str, src -> len);
|
||||
dst -> len = src -> len;
|
||||
} else
|
||||
dst -> len = 0;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
Bool
|
||||
scat (string_t *dst, string_t *src)
|
||||
{
|
||||
if (dst && src && sexpand (dst, dst -> len + src -> len + 1)) {
|
||||
if (src -> str) {
|
||||
memcpy (dst -> str + dst -> len, src -> str, src -> len);
|
||||
dst -> len += src -> len;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
static Bool
|
||||
dostr (string_t *dst, char *src, Bool (*func) (string_t *, string_t *))
|
||||
{
|
||||
Bool ret;
|
||||
string_t *rsrc;
|
||||
|
||||
ret = False;
|
||||
if (dst)
|
||||
if (src) {
|
||||
if (rsrc = snewc (src)) {
|
||||
ret = (*func) (dst, rsrc);
|
||||
sfree (rsrc);
|
||||
}
|
||||
} else
|
||||
ret = True;
|
||||
return ret;
|
||||
}
|
||||
|
||||
Bool
|
||||
scopyc (string_t *dst, char *src)
|
||||
{
|
||||
return dostr (dst, src, scopy);
|
||||
}
|
||||
|
||||
Bool
|
||||
scatc (string_t *dst, char *src)
|
||||
{
|
||||
return dostr (dst, src, scat);
|
||||
}
|
||||
|
||||
string_t *
|
||||
scut (string_t *str, int start, int len)
|
||||
{
|
||||
string_t *res;
|
||||
|
||||
if (len < 0)
|
||||
len = str ? str -> len - start : 0;
|
||||
if (res = snew (NULL, len + 1)) {
|
||||
if (str -> len > start) {
|
||||
if (str -> len - start < len)
|
||||
len = str -> len - start;
|
||||
} else
|
||||
len = 0;
|
||||
if (len > 0)
|
||||
memcpy (res -> str, str -> str + start, len);
|
||||
res -> len = len;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
sdel (string_t *str, int start, int len)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (str -> len > start) {
|
||||
if (str -> len - start < len)
|
||||
len = str -> len - start;
|
||||
} else
|
||||
len = 0;
|
||||
if (len > 0) {
|
||||
size = str -> len - (start + len);
|
||||
if (size > 0)
|
||||
memcpy (str -> str + start, str -> str + start + len, str -> len - (start + len));
|
||||
str -> len -= len;
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
sput (string_t *str, string_t *ins, int pos, int len)
|
||||
{
|
||||
if ((len < 0) || (len > ins -> len))
|
||||
len = ins -> len;
|
||||
if (len + pos >= str -> size)
|
||||
if (! sexpand (str, len + pos + 1))
|
||||
return False;
|
||||
memcpy (str -> str + pos, ins -> str, len);
|
||||
if (str -> len < len + pos)
|
||||
str -> len = len + pos;
|
||||
return True;
|
||||
}
|
||||
|
||||
Bool
|
||||
sputc (string_t *str, char *ins, int pos, int len)
|
||||
{
|
||||
Bool ret;
|
||||
string_t *rins;
|
||||
|
||||
ret = False;
|
||||
if (str && ins && (rins = snewc (ins))) {
|
||||
ret = sput (str, rins, pos, len);
|
||||
sfree (rins);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
sextract (string_t *s)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = NULL;
|
||||
if (s)
|
||||
if (ret = malloc (s -> len + 1))
|
||||
if (s -> str) {
|
||||
memcpy (ret, s -> str, s -> len);
|
||||
ret[s -> len] = '\0';
|
||||
} else
|
||||
ret[0] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
schar (string_t *s)
|
||||
{
|
||||
if (s) {
|
||||
if (s -> len + 1>= s -> size)
|
||||
sexpand (s, s -> len + 2);
|
||||
if (s -> len + 1 < s -> size) {
|
||||
s -> str[s -> len] = '\0';
|
||||
return (char *) s -> str;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
sfree (string_t *s)
|
||||
{
|
||||
if (s) {
|
||||
if (s -> str)
|
||||
free (s -> str);
|
||||
free (s);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
srelease (string_t *s)
|
||||
{
|
||||
if (s -> size + 1 > s -> len) {
|
||||
s -> size = s -> len + 1;
|
||||
if (! (s -> str = (char_t *) Realloc (s -> str, sizeof (char_t) * (s -> size + 2)))) {
|
||||
s -> size = 0;
|
||||
s -> len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool
|
||||
siscntrl (string_t *s, int pos)
|
||||
{
|
||||
return (s && (pos >= 0) && (pos < s -> len) && iscntrl (s -> str[pos])) ? True : False;
|
||||
}
|
||||
|
||||
Bool
|
||||
sisspace (string_t *s, int pos)
|
||||
{
|
||||
return (s && (pos >= 0) && (pos < s -> len) && isspace (s -> str[pos])) ? True : False;
|
||||
}
|
||||
|
||||
Bool
|
||||
sisdigit (string_t *s, int pos)
|
||||
{
|
||||
return (s && (pos >= 0) && (pos < s -> len) && isdigit (s -> str[pos])) ? True : False;
|
||||
}
|
||||
|
||||
int
|
||||
stoi (string_t *s)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
if (s && s -> str) {
|
||||
s -> str[s -> len] = '\0';
|
||||
ret = atoi ((char *) s -> str);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
/*}}}*/
|
||||
/*{{{ date_t handling */
|
||||
# if ! HAVE_MEMSET && ! HAVE_BZERO
|
||||
static void
|
||||
dozero (void *p, int len)
|
||||
{
|
||||
unsigned char *ptr = (char *) p;
|
||||
|
||||
while (len-- > 0)
|
||||
*ptr++ = 0;
|
||||
}
|
||||
# endif /* ! HAVE_MEMSET && ! HAVE_BZERO */
|
||||
|
||||
date_t *
|
||||
dat_free (date_t *d)
|
||||
{
|
||||
if (d)
|
||||
free (d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
date_t *
|
||||
dat_parse (char *str)
|
||||
{
|
||||
date_t *d;
|
||||
time_t tim;
|
||||
struct tm *tt;
|
||||
struct tm tm;
|
||||
Bool add;
|
||||
char *ptr, *sav;
|
||||
char *p1, *p2;
|
||||
int mode;
|
||||
int n, val;
|
||||
char sep;
|
||||
date_t tmp;
|
||||
|
||||
d = NULL;
|
||||
if ((! str) || (str = strdup (str))) {
|
||||
if (d = (date_t *) malloc (sizeof (date_t))) {
|
||||
time (& tim);
|
||||
if (tt = localtime (& tim)) {
|
||||
d -> day = tt -> tm_mday;
|
||||
d -> mon = tt -> tm_mon + 1;
|
||||
d -> year = tt -> tm_year + 1900;
|
||||
d -> hour = tt -> tm_hour;
|
||||
d -> min = tt -> tm_min;
|
||||
d -> sec = tt -> tm_sec;
|
||||
} else {
|
||||
d -> day = 1;
|
||||
d -> mon = 1;
|
||||
d -> year = 1970;
|
||||
d -> hour = 0;
|
||||
d -> min = 0;
|
||||
d -> sec = 0;
|
||||
}
|
||||
if (str && strcmp (str, "now")) {
|
||||
if (*str == '+') {
|
||||
add = True;
|
||||
ptr = str + 1;
|
||||
} else {
|
||||
add = False;
|
||||
ptr = str;
|
||||
}
|
||||
tmp.day = -1;
|
||||
tmp.mon = -1;
|
||||
tmp.year = -1;
|
||||
tmp.hour = -1;
|
||||
tmp.min = -1;
|
||||
tmp.sec = -1;
|
||||
while (*ptr) {
|
||||
sav = ptr;
|
||||
ptr = skip (ptr);
|
||||
if (strchr (sav, '.')) {
|
||||
sep = '.';
|
||||
mode = 1;
|
||||
} else if (strchr (sav, '/')) {
|
||||
sep = '/';
|
||||
mode = 2;
|
||||
} else if (strchr (sav, ':')) {
|
||||
sep = ':';
|
||||
mode = 3;
|
||||
} else {
|
||||
sep = '\0';
|
||||
mode = 0;
|
||||
}
|
||||
for (p1 = sav, n = 0; *p1; ++n) {
|
||||
p2 = p1;
|
||||
p1 = skipch (p1, sep);
|
||||
val = atoi (p2);
|
||||
switch (mode) {
|
||||
case 0:
|
||||
tmp.sec = 0;
|
||||
if (val < 30) {
|
||||
tmp.hour = val;
|
||||
tmp.min = 0;
|
||||
} else {
|
||||
tmp.hour = val / 60;
|
||||
tmp.min = val % 60;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if (n == 0)
|
||||
tmp.day = val;
|
||||
else if (n == 1)
|
||||
tmp.mon = val;
|
||||
else if (n == 2) {
|
||||
if ((! add) && (val < 1900))
|
||||
val += 1900;
|
||||
tmp.year = val;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (n == 0)
|
||||
tmp.mon = val;
|
||||
else if (n == 1)
|
||||
tmp.day = val;
|
||||
else if (n == 2) {
|
||||
if ((! add) && (val < 1900))
|
||||
val += 1900;
|
||||
tmp.year = val;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (n == 0) {
|
||||
tmp.hour = val;
|
||||
tmp.min = 0;
|
||||
tmp.sec = 0;
|
||||
} else if (n == 1)
|
||||
tmp.min = val;
|
||||
else if (n == 2)
|
||||
tmp.sec = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (add) {
|
||||
if (tmp.day != -1)
|
||||
d -> day += tmp.day;
|
||||
if (tmp.mon != -1)
|
||||
d -> mon += tmp.mon;
|
||||
if (tmp.year != -1)
|
||||
d -> year += tmp.year;
|
||||
if (tmp.hour != -1)
|
||||
d -> hour += tmp.hour;
|
||||
if (tmp.min != -1)
|
||||
d -> min += tmp.min;
|
||||
if (tmp.sec != -1)
|
||||
d -> sec += tmp.sec;
|
||||
} else {
|
||||
if (tmp.day != -1)
|
||||
d -> day = tmp.day;
|
||||
if (tmp.mon != -1)
|
||||
d -> mon = tmp.mon;
|
||||
if (tmp.year != -1)
|
||||
d -> year = tmp.year;
|
||||
if (tmp.hour != -1)
|
||||
d -> hour = tmp.hour;
|
||||
if (tmp.min != -1)
|
||||
d -> min = tmp.min;
|
||||
if (tmp.sec != -1)
|
||||
d -> sec = tmp.sec;
|
||||
}
|
||||
# if HAVE_MEMSET
|
||||
memset (& tm, 0, sizeof (tm));
|
||||
# elif HAVE_BZERO
|
||||
bzero (& tm, sizeof (tm));
|
||||
# else
|
||||
dozero (& tm, sizeof (tm));
|
||||
# endif /* ! HAVE_MEMSET && ! HAVE_BZERO */
|
||||
tm.tm_mday = d -> day;
|
||||
tm.tm_mon = d -> mon - 1;
|
||||
tm.tm_year = d -> year - 1900;
|
||||
tm.tm_hour = d -> hour;
|
||||
tm.tm_min = d -> min;
|
||||
tm.tm_sec = d -> sec;
|
||||
tm.tm_isdst = tt -> tm_isdst;
|
||||
if (mktime (& tm) == (time_t) -1)
|
||||
d = dat_free (d);
|
||||
else {
|
||||
d -> day = tm.tm_mday;
|
||||
d -> mon = tm.tm_mon + 1;
|
||||
d -> year = tm.tm_year + 1900;
|
||||
d -> hour = tm.tm_hour;
|
||||
d -> min = tm.tm_min;
|
||||
d -> sec = tm.tm_sec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (str)
|
||||
free (str);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int
|
||||
dat_diff (date_t *d1, date_t *d2)
|
||||
{
|
||||
int v1, v2;
|
||||
|
||||
if (d1)
|
||||
v1 = (((((d1 -> year * 12 + d1 -> mon) * 31 + d1 -> day) * 24 + d1 -> hour) * 60 + d1 -> min) * 60 + d1 -> sec);
|
||||
else
|
||||
v1 = 0;
|
||||
if (d2)
|
||||
v2 = (((((d2 -> year * 12 + d2 -> mon) * 31 + d2 -> day) * 24 + d2 -> hour) * 60 + d2 -> min) * 60 + d2 -> sec);
|
||||
else
|
||||
v2 = 0;
|
||||
return v2 - v1;
|
||||
}
|
||||
|
||||
void
|
||||
dat_clear (date_t *d)
|
||||
{
|
||||
d -> day = 0;
|
||||
d -> mon = 0;
|
||||
d -> year = 0;
|
||||
d -> hour = 0;
|
||||
d -> min = 0;
|
||||
d -> sec = 0;
|
||||
}
|
||||
|
||||
void
|
||||
dat_localtime (date_t *d)
|
||||
{
|
||||
time_t tim;
|
||||
struct tm *tt;
|
||||
|
||||
time (& tim);
|
||||
if (tt = localtime (& tim)) {
|
||||
d -> day = tt -> tm_mday;
|
||||
d -> mon = tt -> tm_mon + 1;
|
||||
d -> year = tt -> tm_year + 1900;
|
||||
d -> hour = tt -> tm_hour;
|
||||
d -> min = tt -> tm_min;
|
||||
d -> sec = tt -> tm_sec;
|
||||
} else
|
||||
dat_clear (d);
|
||||
}
|
||||
/*}}}*/
|
|
@ -0,0 +1,126 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# include "config.h"
|
||||
/*# undef HAVE_REGEX_H*/
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include "pager.h"
|
||||
# include "valid.h"
|
||||
|
||||
valid_t *
|
||||
v_new (char *pattern)
|
||||
{
|
||||
valid_t *v;
|
||||
# if ! HAVE_REGEX_H
|
||||
int cnt, siz;
|
||||
char *ptr, *sav;
|
||||
int n;
|
||||
# endif /* ! HAVE_REGEX_H */
|
||||
|
||||
if (v = (valid_t *) malloc (sizeof (valid_t))) {
|
||||
# if HAVE_REGEX_H
|
||||
if (regcomp (& v -> r, pattern, REG_EXTENDED)) {
|
||||
free (v);
|
||||
v = NULL;
|
||||
}
|
||||
# else /* HAVE_REGEX_H */
|
||||
v -> pats = NULL;
|
||||
v -> lens = NULL;
|
||||
v -> malways = 0;
|
||||
if (! strcmp (pattern, "-"))
|
||||
v -> malways = 1;
|
||||
else if (pattern = strdup (pattern)) {
|
||||
cnt = 0;
|
||||
siz = 0;
|
||||
for (ptr = pattern; ptr; ) {
|
||||
sav = ptr;
|
||||
if (ptr = strchr (ptr, '|'))
|
||||
*ptr++ = '\0';
|
||||
if (cnt >= siz) {
|
||||
siz += 4;
|
||||
if (! (v -> pats = Realloc (v -> pats, (siz + 1) * sizeof (char *))))
|
||||
break;
|
||||
}
|
||||
if (! (v -> pats[cnt] = strdup (sav))) {
|
||||
while (--cnt >= 0)
|
||||
free (v -> pats[cnt]);
|
||||
free (v -> pats);
|
||||
v -> pats = NULL;
|
||||
break;
|
||||
}
|
||||
++cnt;
|
||||
}
|
||||
free (pattern);
|
||||
if (v -> pats) {
|
||||
v -> pats[cnt] = NULL;
|
||||
if (! (v -> lens = (int *) malloc ((cnt + 1) * sizeof (int)))) {
|
||||
for (n = 0; n < cnt; ++n)
|
||||
free (v -> pats[n]);
|
||||
free (v -> pats);
|
||||
v -> pats = NULL;
|
||||
} else
|
||||
for (n = 0; n < cnt; ++n)
|
||||
v -> lens[n] = strlen (v -> pats[n]);
|
||||
}
|
||||
if (! v -> pats) {
|
||||
free (v);
|
||||
v = NULL;
|
||||
}
|
||||
}
|
||||
# endif /* HAVE_REGEX_H */
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
Bool
|
||||
v_alidate (valid_t *v, char *str, int *start, int *end)
|
||||
{
|
||||
Bool ret = False;
|
||||
# if HAVE_REGEX_H
|
||||
regmatch_t mt;
|
||||
|
||||
if (! regexec (& v -> r, str, 1, & mt, 0)) {
|
||||
*start = mt.rm_so;
|
||||
*end = mt.rm_eo;
|
||||
ret = True;
|
||||
}
|
||||
# else /* HAVE_REGEX_H */
|
||||
int n;
|
||||
|
||||
if (v -> pats) {
|
||||
for (n = 0; v -> pats[n]; ++n)
|
||||
if (! strncmp (v -> pats[n], str, v -> lens[n]))
|
||||
break;
|
||||
if (v -> pats[n]) {
|
||||
*start = 0;
|
||||
*end = v -> lens[n];
|
||||
ret = True;
|
||||
}
|
||||
} else if (v -> malways) {
|
||||
*start = 0;
|
||||
*end = 0;
|
||||
ret = True;
|
||||
}
|
||||
# endif /* HAVE_REGEX_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
v_free (valid_t *v)
|
||||
{
|
||||
# if HAVE_REGEX_H
|
||||
regfree (& v -> r);
|
||||
# else /* HAVE_REGEX_H */
|
||||
int n;
|
||||
|
||||
if (v -> pats) {
|
||||
for (n = 0; v -> pats[n]; ++n)
|
||||
free (v -> pats[n]);
|
||||
free (v -> pats);
|
||||
}
|
||||
if (v -> lens) {
|
||||
free (v -> lens);
|
||||
v -> lens = NULL;
|
||||
}
|
||||
# endif /* HAVE_REGEX_H */
|
||||
free (v);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/* -*- mode: c; mode: fold -*- */
|
||||
# ifndef __VALID_H
|
||||
# define __VALID_H 1
|
||||
# if HAVE_REGEX_H
|
||||
# include <regex.h>
|
||||
# endif /* HAVE_REGEX_H */
|
||||
|
||||
typedef struct {
|
||||
# if HAVE_REGEX_H
|
||||
regex_t r;
|
||||
# else /* HAVE_REGEX_H */
|
||||
char **pats;
|
||||
int *lens;
|
||||
int malways;
|
||||
# endif /* HAVE_REGEX_H */
|
||||
} valid_t;
|
||||
|
||||
extern valid_t *v_new (char *pattern);
|
||||
extern Bool v_alidate (valid_t *v, char *str, int *start, int *end);
|
||||
extern void v_free (valid_t *v);
|
||||
# endif /* __VALID_H */
|
|
@ -0,0 +1,19 @@
|
|||
.TH YAPS 1 "V 0.92 21. May 1997"
|
||||
.SH NAME
|
||||
yaps \- Yet Another Pager Software
|
||||
.SH SYNOPSIS
|
||||
yaps [opts] [parameter]
|
||||
.SH DESCRIPTION
|
||||
Sorry, this manual page is currently more or less empty. See the user
|
||||
documentation
|
||||
.B yaps.html
|
||||
or
|
||||
.BR yaps.doc .
|
||||
.SH AUTHOR
|
||||
Written and copyrighted by Ulrich Dessauer, Germering, Germany. See file
|
||||
.B COPYRIGHT
|
||||
and
|
||||
.B COPYING.GPL
|
||||
for details on usage and warrenty.
|
||||
.SH BUGS
|
||||
Perhaps a lot as this is considered as alpha software.
|
|
@ -0,0 +1,910 @@
|
|||
|
||||
Table of Contents
|
||||
|
||||
1. Introduction
|
||||
2. Installation
|
||||
3. Configuration
|
||||
4. Command Line
|
||||
5. Sending/Expecting Syntax
|
||||
6. Scripting
|
||||
7. Examples
|
||||
8. Changelog
|
||||
|
||||
Introduction
|
||||
|
||||
Welcome to Yaps, Yet Another Paging Package. The program is used to
|
||||
send textual messages to a remote paging device using a modem gateway.
|
||||
Many pager companies offer such modem gateways and are using specific
|
||||
protocols. The most often used one, TAP is implemented beside others
|
||||
(more or less complete.) This command line program uses a global and a
|
||||
private configuration file to get information about each paging
|
||||
service, installed modems and possibly other.
|
||||
|
||||
As the main part is implemented as a library it is not very
|
||||
complicated to write a client/server solution. For the legal status
|
||||
see the File Copying.
|
||||
|
||||
Installation
|
||||
|
||||
The software is written, tested and designed on and for Unix(tm) like
|
||||
operating systems and requires the so called Posix system calls and
|
||||
function library. Gnumake and GCC are required, too (or some changes
|
||||
to the Makefile and the code may be neccessary.) It is known to run at
|
||||
least on following operating systems:
|
||||
* Linux (native system)
|
||||
* Solaris 2.5.1 (Frank Käfer)
|
||||
* SunOS 4.1.3 aka Solaris 1.1 (Frank Käfer)
|
||||
|
||||
(more may follow.)
|
||||
|
||||
Typically these steps should be enough to install the package:
|
||||
|
||||
Edit Config
|
||||
For GCC the settings of CC and CFLAGS should be okay. Define
|
||||
SLANG=True, if you like to use the SLang scripting language,
|
||||
which can be found on space.mit.edu. Install it somewhere the
|
||||
compiler can find it. Define LUA=True for using the lua
|
||||
scripting language, which is located on ftp.icad.puc-rio.br.
|
||||
READ THE COPYRIGHT RELATED FILES OF EACH PACKAGE BEFORE
|
||||
INSTALLING IT!
|
||||
|
||||
Edit config.h
|
||||
This is used to adapt the software to various variants of
|
||||
Unix(tm). If you do not have a regex.h file, either set
|
||||
HAVE_REGEX_T to zero or install the GNU regular expression
|
||||
library. Be sure the library and includefile can be found by
|
||||
the compiler and the name of the header file is regex.h,
|
||||
otherwise make a (symbolic) link to this file. Add the libary
|
||||
to EXLIB = in Config.
|
||||
|
||||
make depend
|
||||
This create the dependency file which will be included during
|
||||
make.
|
||||
|
||||
make (or make all)
|
||||
This compiles the library, the program driver and links the
|
||||
program. The documentation is created using lynx. As lynx is
|
||||
not on every system the already formated result is included as
|
||||
well.
|
||||
|
||||
make install
|
||||
This copies the program and the global configuration file to
|
||||
the final location. This step requires a working install
|
||||
program. If this is missing, you have to install it by hand
|
||||
(well, two files should not be too much.)
|
||||
|
||||
Edit the global configuration file
|
||||
With your favorite editor you should edit the global
|
||||
configuration file (which will be installed as /etc/yaps.rc on
|
||||
default) and change everything as required. See the
|
||||
Configuration section for a detailed description of the
|
||||
contents of the file.
|
||||
|
||||
Done!
|
||||
You may play around with your configuration until you are
|
||||
satisfied, but this fine tuning is up to you.
|
||||
|
||||
If you have problems during compilation, feel free to send me a mail.
|
||||
|
||||
Configuration
|
||||
|
||||
The program reads first the global configuration file /etc/yaps.rc
|
||||
(when not overwritten by command line switch), then the local one in
|
||||
~/.yapsrc to get its configuration. Command line options may overwrite
|
||||
some settings in these files. Both configuration files have the same
|
||||
layout where the local one can overwrite settings of the global one.
|
||||
Each file is seperated in sections, where a section is started with
|
||||
[<name>] or [] for the global section. When a file is opened all
|
||||
entries are stored in the global section until a section name appears.
|
||||
If a section expression [..] is followed by a comma seperate list of
|
||||
names, then these are the fallback sections, i.e. variables not found
|
||||
int his section are taken from the fallback sections before trying the
|
||||
global one.
|
||||
|
||||
If the first character is a bar (|) then the rest is taken as a
|
||||
filename to be included at this point. The current section is NOT
|
||||
affected by this call. Each line may have exactly one entry (or a
|
||||
comment starting with a hash sign in the first column) where the
|
||||
variable name is seperated by whitespaces from its value. If the first
|
||||
character of the value is a backslash (\), then this is removed. This
|
||||
allowes creating values starting with whitespaces. But if a value
|
||||
should start with a backslash itself, be sure to escape it with
|
||||
another backslash. A line can split over several physical line, if
|
||||
each line (expect the last one) ends with a backslash. If the value
|
||||
starts with an opening curly bracket ({) then all lines up to the
|
||||
closing curly bracket (}) in the first column are taken as the value
|
||||
for that variable. The brackets (and the lines where they appear) are
|
||||
not part of the value.
|
||||
|
||||
The value may either be textual, numeric, boolean or a check
|
||||
expression. Textual values are starting with the first non whitespace
|
||||
character and continue to the end of the line. Numeric values are a
|
||||
sequence of digits which are parsed by the C-function atoi(3). Boolean
|
||||
may either be T, Y, 1 or + for true and F, N, 0 or - for false (or in
|
||||
greater detail, everything that is not true is false.) Case is here
|
||||
not significant. The check is a sequence of special characters which
|
||||
must match the given string. If a > is found, then the rest is
|
||||
optional, but must still match, if a < is found and the string is not
|
||||
at its end, it is considered as too long. These characters are
|
||||
supported:
|
||||
* 1 numeric
|
||||
* h hexadecimal
|
||||
* l lowercase
|
||||
* u uppercase
|
||||
* a alpha
|
||||
* n alphanumeric
|
||||
* p printable
|
||||
* x ascii
|
||||
* every other character matches every character
|
||||
|
||||
Some simple examples:
|
||||
* >1 A string with unlimited length, but made only out of numeric
|
||||
values.
|
||||
* aaa A string of exact three alpha characters.
|
||||
* >xxxx< A string of length zero up to four made of ASCII
|
||||
characters.
|
||||
* ....>1111< A string starting with exact four characters, followed
|
||||
by zero to four numeric characters.
|
||||
|
||||
Alternative one can specify the check by a description, if the
|
||||
checkstring is prefixed by a plus sign. This is then a comma seperated
|
||||
list of checks, which are seperated by an equal sign into variable and
|
||||
value. These variables are supported:
|
||||
* type=<type> Each character in the string must match the type,
|
||||
which may be one of the following:
|
||||
+ numeric only digits are allowed.
|
||||
+ sedecimal only hexdigits are allowed.
|
||||
+ lower only lowercase characters are allowed.
|
||||
+ upper only uppercase characters are allowed.
|
||||
+ alpha only alpha characters are allowed.
|
||||
+ alphanumeric only digits and alpha characters are allowed.
|
||||
+ print only printable characters are allowed.
|
||||
+ ascii only ASCII characters are allowed.
|
||||
* length=<length> The string must have exact this length.
|
||||
* minimum=<length> The string must at least this length.
|
||||
* maximum=<length> The string must not be longer than this length.
|
||||
|
||||
The global section defines global values or default values for other
|
||||
sections. Some section may not inherit these values, but currently
|
||||
there is only one and is marked as such.
|
||||
|
||||
Global section
|
||||
|
||||
These are typical found in the global section and can be overwritten
|
||||
in other sections, if required.
|
||||
|
||||
services <text>
|
||||
This is the comma seperated list of available services.
|
||||
|
||||
call-id <text>
|
||||
If the pager allows to send the source caller id this id is
|
||||
used, if not overwritten by a command line argument.
|
||||
|
||||
signature <text>
|
||||
If this is present, then the text is appended to each message
|
||||
sent to the pager (and if use-signature is True).
|
||||
|
||||
verbose <num>
|
||||
Sets the debugging/verbosity level. The bigger the number, the
|
||||
more output is generated.
|
||||
|
||||
logfile <text>
|
||||
If the given text is a valid filename the status of a sending
|
||||
request is loged there.
|
||||
|
||||
logstring <text>
|
||||
If this is present, then only these parts are logged, which
|
||||
match the given string. Currently these elements are supported:
|
||||
|
||||
+ message had been trasmitted successfully
|
||||
- message had not been transmitted
|
||||
* part had been transmitted successfully
|
||||
/ part had not been transmitted
|
||||
i informal logfile entry
|
||||
c cost relevant informations
|
||||
s session start
|
||||
e session end
|
||||
p protocol specific
|
||||
|
||||
modems <text>
|
||||
This is a list of modem entries, seperated by commas.
|
||||
|
||||
final-report <text>
|
||||
If this is set, a final report is written to the given
|
||||
filename. If filename is -, then it is written to stdout. This
|
||||
feature is intended for use in shell scripts, so the script
|
||||
could proof which message has actual send and which one has
|
||||
been rejected instead of simple rely on the return code of
|
||||
yaps.
|
||||
|
||||
Service section
|
||||
|
||||
The names of these section are free to the user, but their contents
|
||||
describe a paging service (or a paging company.) Following variables
|
||||
are allowed for service sections:
|
||||
|
||||
speed <num>
|
||||
The speed of the serial device.
|
||||
|
||||
bits-per-byte <num>
|
||||
The number of bits per byte, supported are 5 to 8.
|
||||
|
||||
parity <text>
|
||||
The used parity, this may either be none, even or odd.
|
||||
|
||||
stopbits <num>
|
||||
The number of stopbits, supported are 1 or 2.
|
||||
|
||||
phone <text>
|
||||
The phone number of the modem gateway for this service. If the
|
||||
number contains %P and insert-pager-id is set, then the pagerid
|
||||
is inserted into the phonenumber.
|
||||
|
||||
protocol <text>
|
||||
This is the communication protocol, that this service requires.
|
||||
Currently are ascii, script, tap and ucp allowed.
|
||||
|
||||
max-size <num>
|
||||
The maximal length of a message for this service.
|
||||
|
||||
may-split <bool>
|
||||
If this is true, then a message, which is too long will be
|
||||
split into several messages.
|
||||
|
||||
max-messages <num>
|
||||
The maximum number of messages per message, that can be send.
|
||||
If this is zero, then an unlimited number of messages can be
|
||||
send.
|
||||
|
||||
truncate <bool>
|
||||
If this is set a message is not split, but truncated to the
|
||||
length allowed by the provider.
|
||||
|
||||
use-call-id <bool>
|
||||
If this is true, then the caller-id is inserted. Where it is
|
||||
insert is protocol specific.
|
||||
|
||||
use-signature <bool>
|
||||
If this is true and a signature is given, this is appended to
|
||||
each message.
|
||||
|
||||
insert-pager-id <bool>
|
||||
If this is true, then the pagerid is inserted as part of the
|
||||
phone number. This implies, that only messages to the same
|
||||
receipiant can be send at one call.
|
||||
|
||||
rm-invalids-cid <text>
|
||||
Remove every character in text, that appears in the caller id.
|
||||
This is designed to make a caller id more readable, but still
|
||||
useable by the desired service.
|
||||
|
||||
rm-invalids-pid <text>
|
||||
Dito for pager ids.
|
||||
|
||||
valid-pid <text>
|
||||
This is a regular expression to check wether a pager-id is
|
||||
valid for this service. If your system does not support Posix
|
||||
regular expression, you can use a simple replacement. This is
|
||||
just a list of strings, seperated by a bar which must match the
|
||||
beginning of the pager-id.
|
||||
|
||||
change-pid <text>
|
||||
If the pager-id matches the regular expression of valid-pid,
|
||||
then this matching part is replaced with this string. If the
|
||||
string is just a minus (-), then the match is removed from the
|
||||
resulting pager-id.
|
||||
|
||||
valid-cid <text>
|
||||
The same like valid-pid for the caller id.
|
||||
|
||||
change-cid <text>
|
||||
The same like change-pid for the caller id.
|
||||
|
||||
conv-table <text>
|
||||
The value is a filename to a character conversion table. This
|
||||
affects only the message (and depending on the protocol the
|
||||
pagerid) and allows transforming illegal characters to valid
|
||||
ones.
|
||||
|
||||
convert <text>
|
||||
This is comma seperated list of direct change entries of the
|
||||
convertion table. If you want to include more than one pair,
|
||||
the block construct using curly brackets ({..}) must be used.
|
||||
Each line contains a source and a destination character, i.e.
|
||||
if the source character is encountered in a message, the
|
||||
destination character is used for it. There are also some
|
||||
predefined convertion rules, which all starts with an asterisk:
|
||||
|
||||
+ *no-control control characters are suppressed
|
||||
+ *control control characters are inserted literal
|
||||
+ *no-8bit no characters with 8'th bit set are included
|
||||
+ *8bit use also characters with 8'th bit set.
|
||||
+ *numeric only numeric characters are allowed.
|
||||
|
||||
cost <text>
|
||||
This string is used to calculate the costs for each call. The
|
||||
description is a comma seperated list of variables with equal
|
||||
sign seperated optional value. These variables are currently
|
||||
implemented:
|
||||
|
||||
fixed
|
||||
This tells the software, that the cost are fixed per call,
|
||||
i.e. no real calculation takes place according to the used
|
||||
entities.
|
||||
entity-length=<entity>
|
||||
This is the length of one entity. This is interpreted as a
|
||||
floating point number.
|
||||
max-entities=<count>
|
||||
Some providers only charge until a maximum of entites had
|
||||
been used and stop then charging.
|
||||
dial-overhead=<seconds>
|
||||
The counter starts before dialing. Typically it takes some
|
||||
time from dialing to the first billed entity. This time
|
||||
can be specified using this variable.
|
||||
cost=<cost>
|
||||
This is the cost per entity (or the whole cost on fixed
|
||||
charging services). This is a floating point number.
|
||||
unit=<string>
|
||||
This string is appended in the logfile for the currency.
|
||||
This is only of cosmetic value.
|
||||
remainder=<digits>
|
||||
This is the number of digits after the point in the cost
|
||||
display. This value is typical two.
|
||||
timetable=<description>
|
||||
If a timetable entry is given, then the cost are
|
||||
calculated depending on weekday and time. On fixed
|
||||
charging services the value describes the complete costs
|
||||
for the call, in the other case the value is the
|
||||
entity-length for this day/time. The description is a
|
||||
semi-colon seperated list of single entries of the form:
|
||||
<Weekday(s)><from>-<to>=<value>
|
||||
Each weekday is a two letter sequence (So, Mo, Tu, We, Th,
|
||||
Fr, Sa) and there are three special "weekdays": Wk for
|
||||
working days (monday to friday), Ss for weekend (saturday
|
||||
and sunday) and al for all days. A typical example may
|
||||
look like: Wk0800-1800=12;Wk1800-0800=24;Ss=24, but this
|
||||
could be written shorter as: =24;Wk0800-1800=12 because
|
||||
the first entry is taken as the default, if no match is
|
||||
found. And the construct =24 does not contain any weekday,
|
||||
so it is invalid for any regular check.
|
||||
|
||||
force <bool>
|
||||
If a feature is requested, but this service do not support it,
|
||||
the message will still be delivered, if this variable is set to
|
||||
True.
|
||||
|
||||
can-delay <bool>
|
||||
Set this to True, if the service provider accepts a delay for
|
||||
sending the message.
|
||||
|
||||
can-expire <bool>
|
||||
Set this to True, if the service provider allowes the setting
|
||||
of an expiration timestamp.
|
||||
|
||||
can-rds <bool>
|
||||
Set this to True, if the service provider allowes the request
|
||||
for a delivery status.
|
||||
|
||||
rds <bool>
|
||||
Set this to True, if can-rds is True and you always want to get
|
||||
a delivery status.
|
||||
|
||||
check-call-id <check>
|
||||
The caller id must match the check expression.
|
||||
|
||||
check-pager-id <check>
|
||||
Each pager id must match the check expression.
|
||||
|
||||
Modem section
|
||||
|
||||
Each modem should have its own section. Following entries are
|
||||
currently supported:
|
||||
|
||||
device <text>
|
||||
The filename for the device where the modem is attached to.
|
||||
|
||||
lock-prefix <text>
|
||||
This is the pathname to prefix the basename of the modemdevice
|
||||
to create lockfiles. This can be used to enable more than one
|
||||
application to use the modem.
|
||||
|
||||
lock-method <text>
|
||||
This is a comma seperated list of locking mechanism. Currently
|
||||
these flags are supported:
|
||||
|
||||
+ ascii PID is stored as ASCII text in lockfile.
|
||||
+ binary PID is stored in machine representation in lockfile.
|
||||
+ lower converts device part of lockfile to lower case.
|
||||
+ upper converts device part of lockfile to upper case.
|
||||
+ sysv4 append SysV4 style infos to lockfile instead of the
|
||||
basename of the device.
|
||||
+ timeout=<secs> tries to lock the device secs seconds.
|
||||
|
||||
init <text>
|
||||
This is the init sequence to initialize the modem.
|
||||
|
||||
dial <text>
|
||||
This is the dial sequence to dial a phone number with the
|
||||
modem. An \L in the string will be replaced by the phone
|
||||
number.
|
||||
|
||||
timeout <num>
|
||||
This is the default timeout to wait for responses of the modem.
|
||||
|
||||
reset <text>
|
||||
This is the sequence to reset the modem.
|
||||
|
||||
local-init <text>
|
||||
This is used to customize an existing modem entry for different
|
||||
purpose (e.g. force a specific connect rate, etc.)
|
||||
|
||||
Beside this the section may contain protocol specific entries to adapt
|
||||
the protocol for this service.
|
||||
|
||||
ASCII based protocol
|
||||
|
||||
A \C is replaced with the caller id, if available. If request a
|
||||
delivery report is switched on, a \R is replaced with 1, else with 0.
|
||||
|
||||
asc-timeout <num>
|
||||
This is the default timeout for sequences when communicating
|
||||
with the remote side.
|
||||
|
||||
asc-login <text>
|
||||
This is the sequence to login to the remote service.
|
||||
|
||||
asc-logout <text>
|
||||
This is the sequence to logout from the remote service.
|
||||
|
||||
asc-pagerid <text>
|
||||
This is the sequence to embedded the pager id to be sent. \P is
|
||||
replaced with the pager id.
|
||||
|
||||
asc-message <text>
|
||||
Dito for the message, \M is replaced with the message.
|
||||
|
||||
asc-next <text>
|
||||
This is the sequence to start the next transmission.
|
||||
|
||||
asc-sync <text>
|
||||
If we get out of sync, then this sequence should bring us back
|
||||
to a stage as if we had just loged in.
|
||||
|
||||
Script specific
|
||||
|
||||
script-type <text>
|
||||
This is the scripting language to choose. Currently these are
|
||||
supported: SLang, Lua.
|
||||
|
||||
script-name <text>
|
||||
This is the name (e.g. the name of the variable containing) the
|
||||
script. If the name starts with a slash or a plus sign, then
|
||||
the value is treated as a filename from where the script should
|
||||
be read. The plus sign is stripped off before opening the file.
|
||||
|
||||
scr-login <text>
|
||||
This is the function/label where to start at login. If the
|
||||
caller id is available (and the language supports it) the
|
||||
caller id is passed as an argument.
|
||||
|
||||
scr-logout <text>
|
||||
Dito for logout.
|
||||
|
||||
scr-pagerid <text>
|
||||
Dito for sending the pagerid. The pagerid is passed as an
|
||||
argument.
|
||||
|
||||
scr-message <text>
|
||||
Dito for sending the message. The message is passed as an
|
||||
argument.
|
||||
|
||||
scr-next <text>
|
||||
Dito to go to the next message.
|
||||
|
||||
scr-sync <text>
|
||||
Dito to sync to a definite state (i.e. as if we had just loged
|
||||
in.)
|
||||
|
||||
TAP specific
|
||||
|
||||
tap-t1, tap-t2, tap-t3, tap-t4, tap-t5 <num>
|
||||
This is the timeout for each stage defined in the TAP
|
||||
specification. See there for details.
|
||||
|
||||
tap-n1, tap-n2, tap-n3 <num>
|
||||
This is the retry count for each stage defined int the TAP
|
||||
specification. See there for details.
|
||||
|
||||
tap-login-count <num>
|
||||
This is the number of tries to login to the remote service.
|
||||
|
||||
tap-logout-count <num>
|
||||
This is the number of tries to logout from the remote service.
|
||||
|
||||
UCP specific
|
||||
|
||||
ucp-timeout <num>
|
||||
This is the time to wait for an answer from the remote system.
|
||||
The documentation says that this could be about 40 to 60
|
||||
seconds. This depends on the provider.
|
||||
|
||||
ucp-retry <num>
|
||||
This specifies how often a message should be sent, until the
|
||||
program gives up.
|
||||
|
||||
ucp-extend <bool>
|
||||
If this is True then the extend UCP implementation is used,
|
||||
i.e. the more complex, but more flexibel protocol (currently
|
||||
only possible on german cellular phone provider Mannesmann D2.)
|
||||
|
||||
ucp-ds-timeout <num>
|
||||
Wait a maximum of this value seconds for receiving of the
|
||||
delivery status.
|
||||
|
||||
Alias section
|
||||
|
||||
The entries in this section are not able to access the global entries.
|
||||
Each entry contains an alias name with its real number.
|
||||
|
||||
Command Line
|
||||
|
||||
Yaps support several command line parameter which can overwrite the
|
||||
possibly used default values in the configuration files. Following
|
||||
options are understood by this program (on some systems, there are is
|
||||
also support for long options):
|
||||
|
||||
-C <configfile>, --config=<configfile>
|
||||
Use cfgfile instead of the default global configuration file
|
||||
/etc/yaps.rc.
|
||||
|
||||
-s <service>, --service=<service>
|
||||
Use paging service service instead of the default of the
|
||||
configuration file.
|
||||
|
||||
-t, --truncate
|
||||
If this is set, then a message is truncated, if it is longer
|
||||
than the allowed limit of the choosen service.
|
||||
|
||||
-c <callid>, --call-id=<callid>
|
||||
Use callid as the caller id.
|
||||
|
||||
-S <signature>, --signature=<signature>
|
||||
If signature appending is enabled by the service, use this
|
||||
string as the signature.
|
||||
|
||||
-l <logfile>, --logfile=<logfile>
|
||||
Write status of transmission to logfile.
|
||||
|
||||
-L <logstr>, --logstring=<logstr>
|
||||
This is used to select the messages written to the logfile. See
|
||||
above unter the configuration entry logstring for a detailed
|
||||
description.
|
||||
|
||||
-f, --force
|
||||
Force sending of messages, even if -d/-e/-r is not supported by
|
||||
the service.
|
||||
|
||||
-d <date>, --delay=<date>
|
||||
If the service supports it, the message is delayed and sent at
|
||||
date.
|
||||
|
||||
-e <date>, --expire=<date>
|
||||
If the service supports it, the message is deleted, if this
|
||||
date is reached and the message had not been transmitted until
|
||||
then.
|
||||
|
||||
-r, --request-delivery-status
|
||||
If the service supports it, a delivery status is requested.
|
||||
|
||||
-R <fname>, --final-report=<fname>
|
||||
A final report is written to fname (or stdout, if fname is -.)
|
||||
This feature is useful to check which message had been
|
||||
delivered successfully or not.
|
||||
|
||||
-z <fname>, --message-file=<fname>
|
||||
Reads pager-ids and messages form fname. Each line contains one
|
||||
pair, seperated by whitespace(s).
|
||||
|
||||
-v, --verbose
|
||||
Increase the verbosity of yaps, more -v's give more debug
|
||||
output.
|
||||
|
||||
-p, --print-config
|
||||
This is used to printout configuration values for testing
|
||||
purpose. The remaining paramters are variables to print out
|
||||
with their value.
|
||||
|
||||
Following the options the user has to give receiver/message pairs, all
|
||||
using the same service. A receiver is either the pager id itself or an
|
||||
alias. If the first character is a colon, then the colon is cut off
|
||||
and the remaining part is taken as an alias, if the first character is
|
||||
a slash, it is cut off as well and the remaining is taken as the pager
|
||||
id. If the first character is a digit, it is taken as a pager id,
|
||||
otherwise as an alias. It is possible to specify multiple receiver, if
|
||||
the receiver is a comma seperate list of individual receivers. If the
|
||||
first character of the message is a plus sign, then the remaining
|
||||
message is treated as a filename and the real message is read from
|
||||
this file. If the message is just a minus (-), then the message is
|
||||
read from stdin, if it is just a dot (.), then the message is empty.
|
||||
|
||||
The options -d and -e accept a date representation which must be
|
||||
(according to option parsing) one argument, e.g. if it contains spaces
|
||||
it must be quoted. If the first character of date is a plus (+) sign,
|
||||
then the date is taken as an offset to the current time. All further
|
||||
definitions are seperated by spaces:
|
||||
* <hour>:<min>:<sec>
|
||||
* <day>.<month>.<year>
|
||||
* <month>/<day>/<year>
|
||||
* <numeric> if less than 30 is taken as the hour
|
||||
* <numeric> if greater or equal than 30 is taken as minutes
|
||||
|
||||
Sending/Expecting Syntax
|
||||
|
||||
Whenever communication over the serial line takes place the
|
||||
send/expect functions are comming into play. There are three important
|
||||
functions, which are called from several parts: sending of data,
|
||||
expecting data and a send/expect function. Each is explained in detail
|
||||
here (including the supported syntax):
|
||||
|
||||
Sending
|
||||
|
||||
Sending itself is nothing fancy, just all data will be written to the
|
||||
serial line.
|
||||
|
||||
Expecting
|
||||
|
||||
Expecting means to wait for some pattern to arrive. It is possible to
|
||||
expect more than one sequence and the function returns the matching
|
||||
entry, a timeout or an error condition.
|
||||
|
||||
Send/Expect
|
||||
|
||||
Most communication parts call this function (which then calls the
|
||||
functions above.) This function requires a string with tokens
|
||||
seperated by whitespaces. A token may contain whitespaces, if the
|
||||
token is enclosed in single or double quotes. These quotes (as any
|
||||
other quotes) are removed during the preparse. The first character of
|
||||
the token is relevant for the method to be executed. Each token is
|
||||
preparsed to remove/interpret special characters. Following special
|
||||
characters are interpreted:
|
||||
* Backslash \
|
||||
The backslash is used to escape any other special character
|
||||
(inclusive quotes and the backslash itself) or to insert typical
|
||||
control characters. These are supported:
|
||||
+ \a -> Bel
|
||||
+ \b -> Bs
|
||||
+ \f -> Ff
|
||||
+ \l -> Lf
|
||||
+ \n -> Nl (system depended)
|
||||
+ \r -> CR
|
||||
+ \s -> Space
|
||||
+ \t -> Tab
|
||||
* Up arrow ^
|
||||
This is used to insert control characters, e.g. ^M means CR.
|
||||
* Percent %<nr>
|
||||
This inserts optional paramter nr, if supplied.
|
||||
|
||||
These character initiate the behaviour of the token:
|
||||
|
||||
< Expect
|
||||
The rest of the token is for expecting. If the token contains -
|
||||
then the token is split again and each subtoken is treated as
|
||||
expect/send, if the expect failed. The expect token may be
|
||||
seperated by | to indicate alternatives. The expect is failed,
|
||||
if an error occurs, a timeout arised or not the first
|
||||
alternatives matches. The < may be appended by a numeric value,
|
||||
which is used as the timeout in seconds.
|
||||
|
||||
! Command
|
||||
To insert dynamic commands into the sequence use this
|
||||
construct. Following is an optional numeric value n and a
|
||||
command character. If n is not set, its default value is one.
|
||||
Following characters are supported:
|
||||
|
||||
+ d - sleep n seconds
|
||||
+ D - sleep n miliseconds
|
||||
+ b - send break (length depends on n and the implementation)
|
||||
+ h - hangup the line (lowering DTR by n * 0,5 seconds.)
|
||||
+ o - waits for output to drain
|
||||
+ < - flushes the input queue
|
||||
+ > - flushes the output queue
|
||||
+ f - forces the sequence to fail
|
||||
+ s - forces the sequence to succeed
|
||||
|
||||
Any other character
|
||||
This string is just send to the remote side.
|
||||
|
||||
Scripting
|
||||
|
||||
Scripting has the advantage (compared to the ASCII protocol) that one
|
||||
is more flexible. As there are a lot of scripting languages around,
|
||||
there will be no specific one for this package. As long as such a
|
||||
language is embeddable into C programs, it should not be too
|
||||
complicate to integrate it into this package.
|
||||
|
||||
This section explains the additional function (or simular) for the
|
||||
available scripting languages. The syntax itself is explained in the
|
||||
distribution of each scripting package.
|
||||
|
||||
SLang
|
||||
|
||||
Beside the new functions there is an extension to the string class, so
|
||||
you can use (beside others) the plus sign to concaternate strings. One
|
||||
time this part should make its way into the main SLang distribution.
|
||||
|
||||
Variable index
|
||||
|
||||
int NO_ERR;
|
||||
This is the return value for a function, that ended successful.
|
||||
|
||||
int ERR_FAIL;
|
||||
This is the return value for a function, that encountered an
|
||||
error, but which allowes the script to continue.
|
||||
|
||||
int ERR_FATAL;
|
||||
Dito, but the script should not continue any more.
|
||||
|
||||
int ERR_ABORT;
|
||||
Dito, but no further action should take place.
|
||||
|
||||
int rds;
|
||||
Is set to True, if a delivery status should be requested.
|
||||
|
||||
int delay_day, delay_mon, delay_year, delay_hour, delay_min,
|
||||
delay_sec;
|
||||
This is the time/date to delay the delivery of the message.
|
||||
|
||||
int expire_day, expire_mon, expire_year, expire_hour, expire_min,
|
||||
expire_sec;
|
||||
This is the time/date to expire a buffered message.
|
||||
|
||||
int False;
|
||||
The numeric value for False.
|
||||
|
||||
int True;
|
||||
Dito for True.
|
||||
|
||||
Function index
|
||||
|
||||
void setcb (string func, string sep);
|
||||
This enable the line callback facility and stores each line
|
||||
into a local variable, which will be overwritten after each new
|
||||
encountered line. A line is considered as complete, if one
|
||||
character in sep is received. If func is the name of a defined
|
||||
function, then this function is called on every completed new
|
||||
line. The line is passed as the paramter to this function.
|
||||
|
||||
void clrcb (void);
|
||||
Clears the line callback facility.
|
||||
|
||||
string line (void);
|
||||
Returns the last complete read in line, if the line callback
|
||||
facility is enabled.
|
||||
|
||||
void hangup (void);
|
||||
Tries to hangup, if the modem is currently off-hook. This is
|
||||
done by lowering the DTR line.
|
||||
|
||||
int send (string str);
|
||||
Sends the string to the remote side. Returns True on success,
|
||||
False otherwise.
|
||||
|
||||
int csend (string str);
|
||||
Dito, but the string is converted before it is sended to the
|
||||
remote side.
|
||||
|
||||
int expect (int tout, string str1, ..., string strn, int cnt);
|
||||
The function waits tout seconds until one of the strings is
|
||||
received. If no string is received, 0 is returned, -1 on error.
|
||||
Otherwise the number of the string is returned (1 for str1, 2
|
||||
for str2, etc). cnt is the number of strings to wait for.
|
||||
|
||||
int send_expect (int tout, string expr);
|
||||
This function executes the expr with its internal send/expect
|
||||
evaluater and returns True, when the sequence had been executed
|
||||
completely, otherwies False.
|
||||
|
||||
void drain (int secs);
|
||||
This function reads and discards any character for secs
|
||||
seconds.
|
||||
|
||||
void cvdef (int src, int dst);
|
||||
Defines a converion rule. Every character src will be replaced
|
||||
by dst. The conversion is used in csend().
|
||||
|
||||
void cvundef (int ch);
|
||||
Undefines the conversion rule for ch.
|
||||
|
||||
void cvinval (int ch);
|
||||
Marks the character ch as invalid.
|
||||
|
||||
string conv (string str);
|
||||
Converts the string str using the defined conversion rules and
|
||||
returns the converted string.
|
||||
|
||||
Lua
|
||||
|
||||
Examples
|
||||
|
||||
Here are some examples that may help you to understand the software a
|
||||
bit better. First you should read the example configuration file
|
||||
yaps.rc. This could be used as a base for your own global
|
||||
configuration file.
|
||||
|
||||
Calling
|
||||
|
||||
Typically the program is called yaps <pagerid> <message>. pagerid is
|
||||
either the exact pagerid of the receiver or an alias found in the
|
||||
alias section. message is the message to send by itself. If a pager-id
|
||||
leads to more than one provider, then the first is used. To force a
|
||||
special service use the -s <service> switch.
|
||||
|
||||
Script protocol
|
||||
|
||||
In the contrib directory, you can find tap.sl, an example on how to
|
||||
use the scripting facility to emulate a protocol. This is a minimal,
|
||||
but working reimplemetation of TAP.
|
||||
|
||||
Changelog
|
||||
|
||||
This is a list of changes:
|
||||
9. May 1997: V 0.90 released
|
||||
+ Minor cleanup on calling sending routines
|
||||
+ Added optional multiple receiver per message
|
||||
+ Changing UCP to prepare the real implementation
|
||||
+ Preparing the creation of a client/server solution
|
||||
+ Compile configuration moved to seperate file
|
||||
13. May 1997: V 0.91 released
|
||||
+ Converted `char *' to `string_t *' in several places
|
||||
+ Added max-messages configuration option
|
||||
+ Moved some configuration stuff to config.h
|
||||
+ Got UCP docu! Implemented it partial (as much as it makes
|
||||
sense)
|
||||
+ Added option -d/-e as UCP (in extended mode) can support it
|
||||
+ Added special date handling functions for this purpose
|
||||
+ Changed copyright to the GPL
|
||||
+ Use transparent data in extended UCP, if characters with set
|
||||
8th bit are found
|
||||
+ Better message splitting
|
||||
+ Added some sanity checks
|
||||
22. May 1997: V 0.92 released
|
||||
+ Added handling of configuration variants
|
||||
+ Added include option in configuration files
|
||||
+ First bugs encountered by tester fixed
|
||||
+ Message can now be read from stdin, if message == '-' (idea
|
||||
by <markus@mail.yezz.de>)
|
||||
+ Message can now be empty, if message == '.'
|
||||
+ Minor bugfixing/Makefilehandling (reported by Frank Käfer)
|
||||
+ Enhanced lockfile handling, including SysV4 lockfiles
|
||||
(inspirated by Frank Käfer)
|
||||
+ Total rewrite of UCP sending
|
||||
26. May 1997: V 0.93 released
|
||||
+ UCP works again including delivery report
|
||||
+ Added checking of pager id for a service
|
||||
+ Added signature in configuration file
|
||||
+ Added value start escaping with backslash
|
||||
+ Changed checking of pager id for service
|
||||
+ Automatic assign of a pager id to a service
|
||||
+ Could now handle more than one service at one call
|
||||
30. May 1997: V 0.94 released
|
||||
+ Workaround for serial bug in sunos/solaris (by Frank Käfer)
|
||||
+ If the system does not support Posix regular expression, a
|
||||
simple replacement is added
|
||||
+ More comments in yaps.rc (as wished by Frank Käfer ;-)
|
||||
+ Change handling of control chars in TAP/pre V1.6 (hint by
|
||||
<markus@mail.yezz.de>)
|
||||
+ Added default conversion rules
|
||||
+ Added force/-f
|
||||
+ Added long options support
|
||||
+ Added getopt() for systems without this function
|
||||
+ Added valid-cid/change-cid/rm-invalids-cid/rm-invalids-pid
|
||||
3. June 1997: V 0.95 released
|
||||
+ Added final status report
|
||||
+ Added a 2nd checking scheme
|
||||
+ Added support for lua (another scripting language)
|
||||
+ Removed porting approach, should be done by someone who has
|
||||
access to such an OS.
|
||||
+ Added reading of pager-id/message pairs from file
|
||||
+ Added cost calculation
|
||||
+ Enhanced logfile handling
|
||||
14. June 1997: V 0.96 released
|
|
@ -0,0 +1,883 @@
|
|||
<HTML><Head><Title>
|
||||
yaps
|
||||
</Title></Head><Body>
|
||||
|
||||
|
||||
<H1>Table of Contents</H1>
|
||||
|
||||
<Ol Compact>
|
||||
<Li> <a href="#intro">Introduction</a>
|
||||
<Li> <a href="#install">Installation</a>
|
||||
<Li> <a href="#config">Configuration</a>
|
||||
<Li> <a href="#cmdline">Command Line</a>
|
||||
<Li> <a href="#syntax">Sending/Expecting Syntax</a>
|
||||
<Li> <a href="#script">Scripting</a>
|
||||
<Li> <a href="#sample">Examples</a>
|
||||
<Li> <a href="#chlog">Changelog</a>
|
||||
</Ol>
|
||||
|
||||
|
||||
<H1 ID="intro">Introduction</H1>
|
||||
|
||||
Welcome to <em>Yaps</em>, Yet Another Paging Package. The program is used
|
||||
to send textual messages to a remote paging device using a modem gateway.
|
||||
Many pager companies offer such modem gateways and are using specific
|
||||
protocols. The most often used one, TAP is implemented beside others (more
|
||||
or less complete.) This command line program uses a global and a private
|
||||
configuration file to get information about each paging service, installed
|
||||
modems and possibly other.<P>
|
||||
|
||||
As the main part is implemented as a library it is not very complicated to
|
||||
write a client/server solution. For the legal status see the File
|
||||
<a href="COPYING.GPL">Copying</a>.
|
||||
|
||||
|
||||
<H1 ID="install">Installation</H1>
|
||||
|
||||
The software is written, tested and designed on and for Unix(tm) like
|
||||
operating systems and requires the so called Posix system calls and function
|
||||
library. Gnumake and GCC are required, too (or some changes to the Makefile
|
||||
and the code may be neccessary.) It is known to run at least on following
|
||||
operating systems:
|
||||
<Ul Compact>
|
||||
<Li> <a href="http://www.linux.org/">Linux</a> (native system)
|
||||
<Li> <a href="http://www.sun.com/">Solaris 2.5.1</a> (Frank Käfer)
|
||||
<Li> <a href="http://www.sun.com/">SunOS 4.1.3 aka Solaris 1.1</a> (Frank
|
||||
Käfer)
|
||||
</Ul>
|
||||
(more may follow.)<P>
|
||||
|
||||
Typically these steps should be enough to install the package:
|
||||
<Dl>
|
||||
<Dt> Edit Config
|
||||
<Dd> For GCC the settings of CC and CFLAGS should be okay. Define
|
||||
<strong>SLANG=True</strong>, if you like to use the SLang scripting
|
||||
language, which can be found on
|
||||
<a href="ftp://space.mit.edu/pub/davis/slang/">space.mit.edu</a>. Install it
|
||||
somewhere the compiler can find it. Define <strong>LUA=True</strong> for
|
||||
using the lua scripting language, which is located on
|
||||
<a href="ftp://ftp.icad.puc-rio.br/pub/lua">ftp.icad.puc-rio.br</a>. READ
|
||||
THE COPYRIGHT RELATED FILES OF EACH PACKAGE BEFORE INSTALLING IT!
|
||||
<Dt> Edit config.h
|
||||
<Dd> This is used to adapt the software to various variants of Unix(tm). If
|
||||
you do not have a regex.h file, either set HAVE_REGEX_T to zero or install
|
||||
the GNU regular expression library. Be sure the library and includefile can
|
||||
be found by the compiler and the name of the header file is
|
||||
<em>regex.h</em>, otherwise make a (symbolic) link to this file. Add the
|
||||
libary to <em>EXLIB =</em> in Config.
|
||||
<Dt> make depend
|
||||
<Dd> This create the dependency file which will be included during make.
|
||||
<Dt> make (or make all)
|
||||
<Dd> This compiles the library, the program driver and links the program.
|
||||
The documentation is created using lynx. As lynx is not on every system the
|
||||
already formated result is included as well.
|
||||
<Dt> make install
|
||||
<Dd> This copies the program and the global configuration file to the final
|
||||
location. This step requires a working <em>install</em> program. If this is
|
||||
missing, you have to install it by hand (well, two files should not be too
|
||||
much.)
|
||||
<Dt> Edit the global configuration file
|
||||
<Dd> With your favorite editor you should edit the global configuration file
|
||||
(which will be installed as <em>/etc/yaps.rc</em> on default) and change
|
||||
everything as required. See the <a href="#config">Configuration</a> section
|
||||
for a detailed description of the contents of the file.
|
||||
<Dt> Done!
|
||||
<Dd> You may play around with your configuration until you are satisfied,
|
||||
but this fine tuning is up to you.
|
||||
</Dl><P>
|
||||
|
||||
If you have problems during compilation, feel free to send me a
|
||||
<a href="mailto:yaps@nitmar.tnet.de">mail</a>.
|
||||
|
||||
|
||||
<H1 ID="config">Configuration</H1>
|
||||
|
||||
The program reads first the global configuration file <em>/etc/yaps.rc</em>
|
||||
(when not overwritten by command line switch), then the local one in
|
||||
<em>~/.yapsrc</em> to get its configuration. Command line options may
|
||||
overwrite some settings in these files. Both configuration files have the
|
||||
same layout where the local one can overwrite settings of the global one.
|
||||
Each file is seperated in sections, where a section is started with
|
||||
<strong>[<name>]</strong> or <strong>[]</strong> for the global
|
||||
section. When a file is opened all entries are stored in the global section
|
||||
until a section name appears. If a section expression [..] is followed by a
|
||||
comma seperate list of names, then these are the fallback sections, i.e.
|
||||
variables not found int his section are taken from the fallback sections
|
||||
before trying the global one.<P>
|
||||
|
||||
If the first character is a bar (<strong>|</strong>) then the rest is taken
|
||||
as a filename to be included at this point. The current section is
|
||||
<strong>NOT</strong> affected by this call.
|
||||
|
||||
Each line may have exactly one entry (or a comment starting with a hash sign
|
||||
in the first column) where the variable name is seperated by whitespaces
|
||||
from its value. If the first character of the value is a backslash
|
||||
(<strong>\</strong>), then this is removed. This allowes creating values
|
||||
starting with whitespaces. But if a value should start with a backslash
|
||||
itself, be sure to escape it with another backslash. A line can split over
|
||||
several physical line, if each line (expect the last one) ends with a
|
||||
backslash. If the value starts with an opening curly bracket (<em>{</em>)
|
||||
then all lines up to the closing curly bracket (<em>}</em>) in the first
|
||||
column are taken as the value for that variable. The brackets (and the lines
|
||||
where they appear) are not part of the value.<P>
|
||||
|
||||
The value may either be textual, numeric, boolean or a check expression.
|
||||
Textual values are starting with the first non whitespace character and
|
||||
continue to the end of the line. Numeric values are a sequence of digits
|
||||
which are parsed by the C-function <em>atoi(3)</em>. Boolean may either be
|
||||
<em>T</em>, <em>Y</em>, <em>1</em> or <em>+</em> for true and <em>F</em>,
|
||||
<em>N</em>, <em>0</em> or <em>-</em> for false (or in greater detail,
|
||||
everything that is not true is false.) Case is here not significant. The
|
||||
check is a sequence of special characters which must match the given string.
|
||||
If a <em>></em> is found, then the rest is optional, but must still
|
||||
match, if a <em><</em> is found and the string is not at its end, it is
|
||||
considered as too long. These characters are supported:
|
||||
<Ul Compact>
|
||||
<Li> <em>1</em> numeric
|
||||
<Li> <em>h</em> hexadecimal
|
||||
<Li> <em>l</em> lowercase
|
||||
<Li> <em>u</em> uppercase
|
||||
<Li> <em>a</em> alpha
|
||||
<Li> <em>n</em> alphanumeric
|
||||
<Li> <em>p</em> printable
|
||||
<Li> <em>x</em> ascii
|
||||
<Li> every other character matches every character
|
||||
</Ul>
|
||||
Some simple examples:
|
||||
<Ul Compact>
|
||||
<Li> <strong>>1</strong> A string with unlimited length, but made only
|
||||
out of numeric values.
|
||||
<Li> <strong>aaa</strong> A string of exact three alpha characters.
|
||||
<Li> <strong>>xxxx<</strong> A string of length zero up to four made
|
||||
of ASCII characters.
|
||||
<Li> <strong>....>1111<</strong> A string starting with exact four
|
||||
characters, followed by zero to four numeric characters.
|
||||
</Ul>
|
||||
|
||||
Alternative one can specify the check by a description, if the checkstring
|
||||
is prefixed by a plus sign. This is then a comma seperated list of checks,
|
||||
which are seperated by an equal sign into variable and value. These
|
||||
variables are supported:
|
||||
<Ul>
|
||||
<Li> <strong>type=<type></strong> Each character in the string must
|
||||
match the type, which may be one of the following:
|
||||
<Ul Compact>
|
||||
<Li> <strong>numeric</strong> only digits are allowed.
|
||||
<Li> <strong>sedecimal</strong> only hexdigits are allowed.
|
||||
<Li> <strong>lower</strong> only lowercase characters are allowed.
|
||||
<Li> <strong>upper</strong> only uppercase characters are allowed.
|
||||
<Li> <strong>alpha</strong> only alpha characters are allowed.
|
||||
<Li> <strong>alphanumeric</strong> only digits and alpha characters are
|
||||
allowed.
|
||||
<Li> <strong>print</strong> only printable characters are allowed.
|
||||
<Li> <strong>ascii</strong> only ASCII characters are allowed.
|
||||
</Ul>
|
||||
<Li> <strong>length=<length></strong> The string must have exact this
|
||||
length.
|
||||
<Li> <strong>minimum=<length></strong> The string must at least this
|
||||
length.
|
||||
<Li> <strong>maximum=<length></strong> The string must not be longer
|
||||
than this length.
|
||||
</Ul>
|
||||
<P>
|
||||
|
||||
The global section defines global values or default values for other
|
||||
sections. Some section may not inherit these values, but currently there is
|
||||
only one and is marked as such.<P>
|
||||
|
||||
<H2>Global section</H2>
|
||||
|
||||
These are typical found in the global section and can be overwritten in
|
||||
other sections, if required.
|
||||
|
||||
<Dl>
|
||||
<Dt> services <text>
|
||||
<Dd> This is the comma seperated list of available services.
|
||||
<Dt> call-id <text>
|
||||
<Dd> If the pager allows to send the source caller id this id is used, if
|
||||
not overwritten by a command line argument.
|
||||
<Dt> signature <text>
|
||||
<Dd> If this is present, then the text is appended to each message sent to
|
||||
the pager (and if use-signature is True).
|
||||
<Dt> verbose <num>
|
||||
<Dd> Sets the debugging/verbosity level. The bigger the number, the more
|
||||
output is generated.
|
||||
<Dt> logfile <text>
|
||||
<Dd> If the given text is a valid filename the status of a sending request
|
||||
is loged there.
|
||||
<Dt> <a ID="logstr"></a>logstring <text>
|
||||
<Dd> If this is present, then only these parts are logged, which match the
|
||||
given string. Currently these elements are supported:
|
||||
<Ul Plain Compact>
|
||||
<Li> <strong>+</strong> message had been trasmitted successfully
|
||||
<Li> <strong>-</strong> message had not been transmitted
|
||||
<Li> <strong>*</strong> part had been transmitted successfully
|
||||
<Li> <strong>/</strong> part had not been transmitted
|
||||
<Li> <strong>i</strong> informal logfile entry
|
||||
<Li> <strong>c</strong> cost relevant informations
|
||||
<Li> <strong>s</strong> session start
|
||||
<Li> <strong>e</strong> session end
|
||||
<Li> <strong>p</strong> protocol specific
|
||||
</Ul>
|
||||
<Dt> modems <text>
|
||||
<Dd> This is a list of modem entries, seperated by commas.
|
||||
<Dt> final-report <text>
|
||||
<Dd> If this is set, a final report is written to the given filename. If
|
||||
filename is <strong>-</strong>, then it is written to stdout. This feature
|
||||
is intended for use in shell scripts, so the script could proof which
|
||||
message has actual send and which one has been rejected instead of simple
|
||||
rely on the return code of yaps.
|
||||
</Dl>
|
||||
|
||||
<H2>Service section</H2>
|
||||
|
||||
The names of these section are free to the user, but their contents describe
|
||||
a paging service (or a paging company.) Following variables are allowed for
|
||||
service sections:
|
||||
|
||||
<Dl>
|
||||
<Dt> speed <num>
|
||||
<Dd> The speed of the serial device.
|
||||
<Dt> bits-per-byte <num>
|
||||
<Dd> The number of bits per byte, supported are 5 to 8.
|
||||
<Dt> parity <text>
|
||||
<Dd> The used parity, this may either be <em>n</em>one, <em>e</em>ven or
|
||||
<em>o</em>dd.
|
||||
<Dt> stopbits <num>
|
||||
<Dd> The number of stopbits, supported are 1 or 2.
|
||||
<Dt> phone <text>
|
||||
<Dd> The phone number of the modem gateway for this service. If the number
|
||||
contains <strong>%P</strong> and <em>insert-pager-id</em> is set, then the
|
||||
pagerid is inserted into the phonenumber.
|
||||
<Dt> protocol <text>
|
||||
<Dd> This is the communication protocol, that this service requires.
|
||||
Currently are <em>ascii</em>, <em>script</em>, <em>tap</em> and <em>ucp</em>
|
||||
allowed.
|
||||
<Dt> max-size <num>
|
||||
<Dd> The maximal length of a message for this service.
|
||||
<Dt> may-split <bool>
|
||||
<Dd> If this is true, then a message, which is too long will be split into
|
||||
several messages.
|
||||
<Dt> max-messages <num>
|
||||
<Dd> The maximum number of messages per message, that can be send. If this
|
||||
is zero, then an unlimited number of messages can be send.
|
||||
<Dt> truncate <bool>
|
||||
<Dd> If this is set a message is not split, but truncated to the length
|
||||
allowed by the provider.
|
||||
<Dt> use-call-id <bool>
|
||||
<Dd> If this is true, then the caller-id is inserted. Where it is insert is
|
||||
protocol specific.
|
||||
<Dt> use-signature <bool>
|
||||
<Dd> If this is true and a signature is given, this is appended to each
|
||||
message.
|
||||
<Dt> insert-pager-id <bool>
|
||||
<Dd> If this is true, then the pagerid is inserted as part of the phone
|
||||
number. This implies, that only messages to the same receipiant can be send
|
||||
at one call.
|
||||
<Dt> rm-invalids-cid <text>
|
||||
<Dd> Remove every character in <em>text</em>, that appears in the caller id.
|
||||
This is designed to make a caller id more readable, but still useable by the
|
||||
desired service.
|
||||
<Dt> rm-invalids-pid <text>
|
||||
<Dd> Dito for pager ids.
|
||||
<Dt> valid-pid <text>
|
||||
<Dd> This is a regular expression to check wether a pager-id is valid for
|
||||
this service. If your system does not support Posix regular expression, you
|
||||
can use a simple replacement. This is just a list of strings, seperated by a
|
||||
bar which must match the beginning of the pager-id.
|
||||
<Dt> change-pid <text>
|
||||
<Dd> If the pager-id matches the regular expression of <em>valid-pid</em>,
|
||||
then this matching part is replaced with this string. If the string is just
|
||||
a minus (<em>-</em>), then the match is removed from the resulting pager-id.
|
||||
<Dt> valid-cid <text>
|
||||
<Dd> The same like <em>valid-pid</em> for the caller id.
|
||||
<Dt> change-cid <text>
|
||||
<Dd> The same like <em>change-pid</em> for the caller id.
|
||||
<Dt> conv-table <text>
|
||||
<Dd> The value is a filename to a character conversion table. This affects
|
||||
only the message (and depending on the protocol the pagerid) and allows
|
||||
transforming illegal characters to valid ones.
|
||||
<Dt> convert <text>
|
||||
<Dd> This is comma seperated list of direct change entries of the convertion
|
||||
table. If you want to include more than one pair, the block construct using
|
||||
curly brackets (<em>{..}</em>) must be used. Each line contains a source and
|
||||
a destination character, i.e. if the source character is encountered in a
|
||||
message, the destination character is used for it. There are also some
|
||||
predefined convertion rules, which all starts with an asterisk:
|
||||
<Ul Compact>
|
||||
<Li> <strong>*no-control</strong> control characters are suppressed
|
||||
<Li> <strong>*control</strong> control characters are inserted literal
|
||||
<Li> <strong>*no-8bit</strong> no characters with 8'th bit set are
|
||||
included
|
||||
<Li> <strong>*8bit</strong> use also characters with 8'th bit set.
|
||||
<Li> <strong>*numeric</strong> only numeric characters are allowed.
|
||||
</Ul>
|
||||
<Dt> cost <text>
|
||||
<Dd> This string is used to calculate the costs for each call. The
|
||||
description is a comma seperated list of variables with equal sign seperated
|
||||
optional value. These variables are currently implemented:
|
||||
<Dl Compact>
|
||||
<Dt> fixed
|
||||
<Dd> This tells the software, that the cost are fixed per call, i.e.
|
||||
no real calculation takes place according to the used entities.
|
||||
<Dt> entity-length=<entity>
|
||||
<Dd> This is the length of one entity. This is interpreted as a
|
||||
floating point number.
|
||||
<Dt> max-entities=<count>
|
||||
<Dd> Some providers only charge until a maximum of entites had
|
||||
been used and stop then charging.
|
||||
<Dt> dial-overhead=<seconds>
|
||||
<Dd> The counter starts before dialing. Typically it takes some
|
||||
time from dialing to the first billed entity. This time can
|
||||
be specified using this variable.
|
||||
<Dt> cost=<cost>
|
||||
<Dd> This is the cost per entity (or the whole cost on fixed charging
|
||||
services). This is a floating point number.
|
||||
<Dt> unit=<string>
|
||||
<Dd> This string is appended in the logfile for the currency. This is
|
||||
only of cosmetic value.
|
||||
<Dt> remainder=<digits>
|
||||
<Dd> This is the number of digits after the point in the cost display.
|
||||
This value is typical two.
|
||||
<Dt> timetable=<description>
|
||||
<Dd> If a timetable entry is given, then the cost are calculated
|
||||
depending on weekday and time. On fixed charging services the
|
||||
value describes the complete costs for the call, in the other
|
||||
case the value is the entity-length for this day/time. The
|
||||
description is a semi-colon seperated list of single entries of
|
||||
the form:<BR>
|
||||
<strong><Weekday(s)><from>-<to>=<value></strong><BR>
|
||||
Each weekday is a two letter sequence (So, Mo, Tu, We, Th, Fr, Sa)
|
||||
and there are three special "weekdays": <em>Wk</em> for
|
||||
working days (monday to friday), <em>Ss</em> for weekend
|
||||
(saturday and sunday) and <em>al</em> for all days. A typical
|
||||
example may look like:
|
||||
<strong>Wk0800-1800=12;Wk1800-0800=24;Ss=24</strong>, but this
|
||||
could be written shorter as:
|
||||
<strong>=24;Wk0800-1800=12</strong> because the first entry is
|
||||
taken as the default, if no match is found. And the construct
|
||||
<em>=24</em> does not contain any weekday, so it is invalid for
|
||||
any regular check.
|
||||
</Dl>
|
||||
<Dt> force <bool>
|
||||
<Dd> If a feature is requested, but this service do not support it, the
|
||||
message will still be delivered, if this variable is set to True.
|
||||
<Dt> can-delay <bool>
|
||||
<Dd> Set this to True, if the service provider accepts a delay for sending
|
||||
the message.
|
||||
<Dt> can-expire <bool>
|
||||
<Dd> Set this to True, if the service provider allowes the setting of an
|
||||
expiration timestamp.
|
||||
<Dt> can-rds <bool>
|
||||
<Dd> Set this to True, if the service provider allowes the request for a
|
||||
delivery status.
|
||||
<Dt> rds <bool>
|
||||
<Dd> Set this to True, if <em>can-rds</em> is True and you always want to
|
||||
get a delivery status.
|
||||
<Dt> check-call-id <check>
|
||||
<Dd> The caller id must match the <strong>check</strong> expression.
|
||||
<Dt> check-pager-id <check>
|
||||
<Dd> Each pager id must match the <strong>check</strong> expression.
|
||||
</Dl>
|
||||
|
||||
<H2>Modem section</H2>
|
||||
|
||||
Each modem should have its own section. Following entries are currently
|
||||
supported:
|
||||
|
||||
<Dl>
|
||||
<Dt> device <text>
|
||||
<Dd> The filename for the device where the modem is attached to.
|
||||
<Dt> lock-prefix <text>
|
||||
<Dd> This is the pathname to prefix the basename of the modemdevice to
|
||||
create lockfiles. This can be used to enable more than one application to
|
||||
use the modem.
|
||||
<Dt> lock-method <text>
|
||||
<Dd> This is a comma seperated list of locking mechanism. Currently these
|
||||
flags are supported:
|
||||
<Ul Compact>
|
||||
<Li> <em>ascii</em> PID is stored as ASCII text in lockfile.
|
||||
<Li> <em>binary</em> PID is stored in machine representation in
|
||||
lockfile.
|
||||
<Li> <em>lower</em> converts device part of lockfile to lower case.
|
||||
<Li> <em>upper</em> converts device part of lockfile to upper case.
|
||||
<Li> <em>sysv4</em> append SysV4 style infos to lockfile instead of the
|
||||
basename of the device.
|
||||
<Li> <em>timeout=<secs></em> tries to lock the device
|
||||
<strong>secs</strong> seconds.
|
||||
</Ul>
|
||||
<Dt> init <text>
|
||||
<Dd> This is the init sequence to initialize the modem.
|
||||
<Dt> dial <text>
|
||||
<Dd> This is the dial sequence to dial a phone number with the modem. An
|
||||
<strong>\L</strong> in the string will be replaced by the phone number.
|
||||
<Dt> timeout <num>
|
||||
<Dd> This is the default timeout to wait for responses of the modem.
|
||||
<Dt> reset <text>
|
||||
<Dd> This is the sequence to reset the modem.
|
||||
<Dt> local-init <text>
|
||||
<Dd> This is used to customize an existing modem entry for different purpose
|
||||
(e.g. force a specific connect rate, etc.)
|
||||
</Dl>
|
||||
|
||||
Beside this the section may contain protocol specific entries to adapt the
|
||||
protocol for this service.
|
||||
|
||||
<H2>ASCII based protocol</H2>
|
||||
|
||||
A <strong>\C</strong> is replaced with the caller id, if available. If
|
||||
request a delivery report is switched on, a <strong>\R</strong> is replaced
|
||||
with <em>1</em>, else with <em>0</em>.
|
||||
|
||||
<Dl>
|
||||
<Dt> asc-timeout <num>
|
||||
<Dd> This is the default timeout for sequences when communicating with the
|
||||
remote side.
|
||||
<Dt> asc-login <text>
|
||||
<Dd> This is the sequence to login to the remote service.
|
||||
<Dt> asc-logout <text>
|
||||
<Dd> This is the sequence to logout from the remote service.
|
||||
<Dt> asc-pagerid <text>
|
||||
<Dd> This is the sequence to embedded the pager id to be sent.
|
||||
<strong>\P</strong> is replaced with the pager id.
|
||||
<Dt> asc-message <text>
|
||||
<Dd> Dito for the message, <strong>\M</strong> is replaced with the message.
|
||||
<Dt> asc-next <text>
|
||||
<Dd> This is the sequence to start the next transmission.
|
||||
<Dt> asc-sync <text>
|
||||
<Dd> If we get out of sync, then this sequence should bring us back to a
|
||||
stage as if we had just loged in.
|
||||
</Dl>
|
||||
|
||||
<H2>Script specific</H2>
|
||||
|
||||
<Dl>
|
||||
<Dt> script-type <text>
|
||||
<Dd> This is the scripting language to choose. Currently these are
|
||||
supported: <strong>SLang</strong>, <strong>Lua</strong>.
|
||||
<Dt> script-name <text>
|
||||
<Dd> This is the name (e.g. the name of the variable containing) the script.
|
||||
If the name starts with a slash or a plus sign, then the value is treated as
|
||||
a filename from where the script should be read. The plus sign is stripped
|
||||
off before opening the file.
|
||||
<Dt> scr-login <text>
|
||||
<Dd> This is the function/label where to start at login. If the caller id is
|
||||
available (and the language supports it) the caller id is passed as an
|
||||
argument.
|
||||
<Dt> scr-logout <text>
|
||||
<Dd> Dito for logout.
|
||||
<Dt> scr-pagerid <text>
|
||||
<Dd> Dito for sending the pagerid. The pagerid is passed as an argument.
|
||||
<Dt> scr-message <text>
|
||||
<Dd> Dito for sending the message. The message is passed as an argument.
|
||||
<Dt> scr-next <text>
|
||||
<Dd> Dito to go to the next message.
|
||||
<Dt> scr-sync <text>
|
||||
<Dd> Dito to sync to a definite state (i.e. as if we had just loged in.)
|
||||
</Dl>
|
||||
|
||||
<H2>TAP specific</H2>
|
||||
|
||||
<Dl>
|
||||
<Dt> tap-t1, tap-t2, tap-t3, tap-t4, tap-t5 <num>
|
||||
<Dd> This is the timeout for each stage defined in the TAP specification.
|
||||
See
|
||||
<a href="http://www.mot.com/MIMS/MSPG/pcia_protocols/tap_v1p8/timing_retry_parameters.html#params">
|
||||
there</a>
|
||||
for details.
|
||||
<Dt> tap-n1, tap-n2, tap-n3 <num>
|
||||
<Dd> This is the retry count for each stage defined int the TAP
|
||||
specification. See
|
||||
<a href="http://www.mot.com/MIMS/MSPG/pcia_protocols/tap_v1p8/timing_retry_parameters.html#params">
|
||||
there</a>
|
||||
for details.
|
||||
<Dt> tap-login-count <num>
|
||||
<Dd> This is the number of tries to login to the remote service.
|
||||
<Dt> tap-logout-count <num>
|
||||
<Dd> This is the number of tries to logout from the remote service.
|
||||
</Dl>
|
||||
|
||||
<H2>UCP specific</H2>
|
||||
|
||||
<Dl>
|
||||
<Dt> ucp-timeout <num>
|
||||
<Dd> This is the time to wait for an answer from the remote system. The
|
||||
documentation says that this could be about 40 to 60 seconds. This depends
|
||||
on the provider.
|
||||
<Dt> ucp-retry <num>
|
||||
<Dd> This specifies how often a message should be sent, until the program
|
||||
gives up.
|
||||
<Dt> ucp-extend <bool>
|
||||
<Dd> If this is True then the extend UCP implementation is used, i.e. the
|
||||
more complex, but more flexibel protocol (currently only possible on german
|
||||
cellular phone provider Mannesmann D2.)
|
||||
<Dt> ucp-ds-timeout <num>
|
||||
<Dd> Wait a maximum of this value seconds for receiving of the delivery
|
||||
status.
|
||||
</Dl>
|
||||
|
||||
<H2>Alias section</H2>
|
||||
|
||||
The entries in this section are not able to access the global entries. Each
|
||||
entry contains an alias name with its real number.
|
||||
|
||||
|
||||
<H1 ID="cmdline">Command Line</H1>
|
||||
|
||||
Yaps support several command line parameter which can overwrite the possibly
|
||||
used default values in the configuration files. Following options are
|
||||
understood by this program (on some systems, there are is also support for
|
||||
long options):
|
||||
|
||||
<Dl>
|
||||
<Dt> -C <configfile>, --config=<configfile>
|
||||
<Dd> Use <strong>cfgfile</strong> instead of the default global
|
||||
configuration file <em>/etc/yaps.rc</em>.
|
||||
<Dt> -s <service>, --service=<service>
|
||||
<Dd> Use paging service <strong>service</strong> instead of the default of
|
||||
the configuration file.
|
||||
<Dt> -t, --truncate
|
||||
<Dd> If this is set, then a message is truncated, if it is longer than the
|
||||
allowed limit of the choosen service.
|
||||
<Dt> -c <callid>, --call-id=<callid>
|
||||
<Dd> Use <strong>callid</strong> as the caller id.
|
||||
<Dt> -S <signature>, --signature=<signature>
|
||||
<Dd> If signature appending is enabled by the service, use this string as
|
||||
the signature.
|
||||
<Dt> -l <logfile>, --logfile=<logfile>
|
||||
<Dd> Write status of transmission to <strong>logfile</strong>.
|
||||
<Dt> -L <logstr>, --logstring=<logstr>
|
||||
<Dd> This is used to select the messages written to the logfile. See
|
||||
<a href="#logstr">above</a> unter the configuration entry
|
||||
<em>logstring</em> for a detailed description.
|
||||
<Dt> -f, --force
|
||||
<Dd> Force sending of messages, even if -d/-e/-r is not supported by the
|
||||
service.
|
||||
<Dt> -d <date>, --delay=<date>
|
||||
<Dd> If the service supports it, the message is delayed and sent at
|
||||
<strong>date</strong>.
|
||||
<Dt> -e <date>, --expire=<date>
|
||||
<Dd> If the service supports it, the message is deleted, if this date is
|
||||
reached and the message had not been transmitted until then.
|
||||
<Dt> -r, --request-delivery-status
|
||||
<Dd> If the service supports it, a delivery status is requested.
|
||||
<Dt> -R <fname>, --final-report=<fname>
|
||||
<Dd> A final report is written to <em>fname</em> (or stdout, if fname is
|
||||
<strong>-</strong>.) This feature is useful to check which message had been
|
||||
delivered successfully or not.
|
||||
<Dt> -z <fname>, --message-file=<fname>
|
||||
<Dd> Reads pager-ids and messages form <em>fname</em>. Each line contains
|
||||
one pair, seperated by whitespace(s).
|
||||
<Dt> -v, --verbose
|
||||
<Dd> Increase the verbosity of yaps, more -v's give more debug output.
|
||||
<Dt> -p, --print-config
|
||||
<Dd> This is used to printout configuration values for testing purpose. The
|
||||
remaining paramters are variables to print out with their value.
|
||||
</Dl>
|
||||
|
||||
Following the options the user has to give receiver/message pairs, all using
|
||||
the same service. A receiver is either the pager id itself or an alias. If
|
||||
the first character is a colon, then the colon is cut off and the remaining
|
||||
part is taken as an alias, if the first character is a slash, it is cut off
|
||||
as well and the remaining is taken as the pager id. If the first character
|
||||
is a digit, it is taken as a pager id, otherwise as an alias. It is possible
|
||||
to specify multiple receiver, if the receiver is a comma seperate list of
|
||||
individual receivers. If the first character of the message is a plus sign,
|
||||
then the remaining message is treated as a filename and the real message is
|
||||
read from this file. If the message is just a minus (<strong>-</strong>),
|
||||
then the message is read from stdin, if it is just a dot
|
||||
(<strong>.</strong>), then the message is empty.<P>
|
||||
|
||||
The options <em>-d</em> and <em>-e</em> accept a date representation which
|
||||
must be (according to option parsing) one argument, e.g. if it contains
|
||||
spaces it must be quoted. If the first character of date is a plus
|
||||
(<strong>+</strong>) sign, then the date is taken as an offset to the
|
||||
current time. All further definitions are seperated by spaces:
|
||||
<Ul>
|
||||
<Li> <hour><strong>:</strong><min><strong>:</strong><sec>
|
||||
<Li> <day><strong>.</strong><month><strong>.</strong><year>
|
||||
<Li> <month><strong>/</strong><day><strong>/</strong><year>
|
||||
<Li> <numeric> if less than 30 is taken as the hour
|
||||
<Li> <numeric> if greater or equal than 30 is taken as minutes
|
||||
</Ul>
|
||||
|
||||
|
||||
<H1 ID="syntax">Sending/Expecting Syntax</H1>
|
||||
|
||||
Whenever communication over the serial line takes place the send/expect
|
||||
functions are comming into play. There are three important functions, which
|
||||
are called from several parts: sending of data, expecting data and a
|
||||
send/expect function. Each is explained in detail here (including the
|
||||
supported syntax):
|
||||
|
||||
<H2>Sending</H2>
|
||||
|
||||
Sending itself is nothing fancy, just all data will be written to the serial
|
||||
line.
|
||||
|
||||
<H2>Expecting</H2>
|
||||
|
||||
Expecting means to wait for some pattern to arrive. It is possible to expect
|
||||
more than one sequence and the function returns the matching entry, a
|
||||
timeout or an error condition.
|
||||
|
||||
<H2>Send/Expect</H2>
|
||||
|
||||
Most communication parts call this function (which then calls the functions
|
||||
above.) This function requires a string with tokens seperated by
|
||||
whitespaces. A token may contain whitespaces, if the token is enclosed in
|
||||
single or double quotes. These quotes (as any other quotes) are removed
|
||||
during the preparse. The first character of the token is relevant for the
|
||||
method to be executed. Each token is preparsed to remove/interpret special
|
||||
characters. Following special characters are interpreted:
|
||||
|
||||
<Ul Compact>
|
||||
<Li> Backslash <strong>\</strong><BR>
|
||||
The backslash is used to escape any other special character (inclusive
|
||||
quotes and the backslash itself) or to insert typical control characters.
|
||||
These are supported:
|
||||
<Ul>
|
||||
<Li> \a -> Bel
|
||||
<Li> \b -> Bs
|
||||
<Li> \f -> Ff
|
||||
<Li> \l -> Lf
|
||||
<Li> \n -> Nl (system depended)
|
||||
<Li> \r -> CR
|
||||
<Li> \s -> Space
|
||||
<Li> \t -> Tab
|
||||
</Ul>
|
||||
<Li> Up arrow <strong>^</strong><BR>
|
||||
This is used to insert control characters, e.g. ^M means CR.
|
||||
<Li> Percent <strong>%<nr></strong><BR>
|
||||
This inserts optional paramter <strong>nr</strong>, if supplied.
|
||||
</Ul><P>
|
||||
|
||||
These character initiate the behaviour of the token:
|
||||
<Dl>
|
||||
<Dt> <strong><</strong> Expect
|
||||
<Dd> The rest of the token is for expecting. If the token contains
|
||||
<strong>-</strong> then the token is split again and each subtoken is
|
||||
treated as expect/send, if the expect failed. The expect token may be
|
||||
seperated by <strong>|</strong> to indicate alternatives. The expect is
|
||||
failed, if an error occurs, a timeout arised or not the first alternatives
|
||||
matches. The <strong><</strong> may be appended by a numeric value, which
|
||||
is used as the timeout in seconds.
|
||||
<Dt> <strong>!</strong> Command
|
||||
<Dd> To insert dynamic commands into the sequence use this construct.
|
||||
Following is an optional numeric value <strong>n</strong> and a command
|
||||
character. If <strong>n</strong> is not set, its default value is one.
|
||||
Following characters are supported:
|
||||
<Ul>
|
||||
<Li> d - sleep <strong>n</strong> seconds
|
||||
<Li> D - sleep <strong>n</strong> miliseconds
|
||||
<Li> b - send break (length depends on <strong>n</strong> and the
|
||||
implementation)
|
||||
<Li> h - hangup the line (lowering DTR by <strong>n</strong> * 0,5
|
||||
seconds.)
|
||||
<Li> o - waits for output to drain
|
||||
<Li> < - flushes the input queue
|
||||
<Li> > - flushes the output queue
|
||||
<Li> f - forces the sequence to fail
|
||||
<Li> s - forces the sequence to succeed
|
||||
</Ul>
|
||||
<Dt> Any other character
|
||||
<Dd> This string is just send to the remote side.
|
||||
</Dl>
|
||||
|
||||
|
||||
<H1 ID="script">Scripting</H1>
|
||||
|
||||
Scripting has the advantage (compared to the ASCII protocol) that one is
|
||||
more flexible. As there are a lot of scripting languages around, there will
|
||||
be no specific one for this package. As long as such a language is
|
||||
embeddable into C programs, it should not be too complicate to integrate it
|
||||
into this package.<P>
|
||||
|
||||
This section explains the additional function (or simular) for the available
|
||||
scripting languages. The syntax itself is explained in the distribution of
|
||||
each scripting package.
|
||||
|
||||
<H2>SLang</H2>
|
||||
|
||||
Beside the new functions there is an extension to the string class, so you
|
||||
can use (beside others) the plus sign to concaternate strings. One time this
|
||||
part should make its way into the main SLang distribution.
|
||||
|
||||
<H3>Variable index</H3>
|
||||
|
||||
<Dl>
|
||||
<Dt> int NO_ERR;
|
||||
<Dd> This is the return value for a function, that ended successful.
|
||||
<Dt> int ERR_FAIL;
|
||||
<Dd> This is the return value for a function, that encountered an error, but
|
||||
which allowes the script to continue.
|
||||
<Dt> int ERR_FATAL;
|
||||
<Dd> Dito, but the script should not continue any more.
|
||||
<Dt> int ERR_ABORT;
|
||||
<Dd> Dito, but no further action should take place.
|
||||
<Dt> int rds;
|
||||
<Dd> Is set to <em>True</em>, if a delivery status should be requested.
|
||||
<Dt> int delay_day, delay_mon, delay_year, delay_hour, delay_min, delay_sec;
|
||||
<Dd> This is the time/date to delay the delivery of the message.
|
||||
<Dt> int expire_day, expire_mon, expire_year, expire_hour, expire_min, expire_sec;
|
||||
<Dd> This is the time/date to expire a buffered message.
|
||||
<Dt> int False;
|
||||
<Dd> The numeric value for False.
|
||||
<Dt> int True;
|
||||
<Dd> Dito for True.
|
||||
</Dl>
|
||||
|
||||
<H3>Function index</H3>
|
||||
|
||||
<Dl>
|
||||
<Dt> void setcb (string func, string sep);
|
||||
<Dd> This enable the line callback facility and stores each line into a
|
||||
local variable, which will be overwritten after each new encountered line. A
|
||||
line is considered as complete, if one character in <strong>sep</strong> is
|
||||
received. If <strong>func</strong> is the name of a defined function, then
|
||||
this function is called on every completed new line. The line is passed as
|
||||
the paramter to this function.
|
||||
<Dt> void clrcb (void);
|
||||
<Dd> Clears the line callback facility.
|
||||
<Dt> string line (void);
|
||||
<Dd> Returns the last complete read in line, if the line callback facility
|
||||
is enabled.
|
||||
<Dt> void hangup (void);
|
||||
<Dd> Tries to hangup, if the modem is currently off-hook. This is done by
|
||||
lowering the DTR line.
|
||||
<Dt> int send (string str);
|
||||
<Dd> Sends the string to the remote side. Returns <strong>True</strong> on
|
||||
success, <strong>False</strong> otherwise.
|
||||
<Dt> int csend (string str);
|
||||
<Dd> Dito, but the string is converted before it is sended to the remote
|
||||
side.
|
||||
<Dt> int expect (int tout, string str1, ..., string strn, int cnt);
|
||||
<Dd> The function waits <strong>tout</strong> seconds until one of the
|
||||
strings is received. If no string is received, <strong>0</strong> is
|
||||
returned, <strong>-1</strong> on error. Otherwise the number of the string
|
||||
is returned (<strong>1</strong> for <strong>str1</strong>,
|
||||
<strong>2</strong> for <strong>str2</strong>, etc). <strong>cnt</strong> is
|
||||
the number of strings to wait for.
|
||||
<Dt> int send_expect (int tout, string expr);
|
||||
<Dd> This function executes the <strong>expr</strong> with its internal
|
||||
send/expect evaluater and returns <strong>True</strong>, when the sequence
|
||||
had been executed completely, otherwies <strong>False</strong>.
|
||||
<Dt> void drain (int secs);
|
||||
<Dd> This function reads and discards any character for
|
||||
<strong>secs</strong> seconds.
|
||||
<Dt> void cvdef (int src, int dst);
|
||||
<Dd> Defines a converion rule. Every character <strong>src</strong> will be
|
||||
replaced by <strong>dst</strong>. The conversion is used in <em>csend()</em>.
|
||||
<Dt> void cvundef (int ch);
|
||||
<Dd> Undefines the conversion rule for <strong>ch</strong>.
|
||||
<Dt> void cvinval (int ch);
|
||||
<Dd> Marks the character <strong>ch</strong> as invalid.
|
||||
<Dt> string conv (string str);
|
||||
<Dd> Converts the string <strong>str</strong> using the defined conversion
|
||||
rules and returns the converted string.
|
||||
</Dl>
|
||||
|
||||
<H2>Lua</H2>
|
||||
<!-- TODO! -->
|
||||
|
||||
|
||||
<H1 ID="sample">Examples</H1>
|
||||
|
||||
Here are some examples that may help you to understand the software a bit
|
||||
better. First you should read the example configuration file
|
||||
<a href="yaps.rc">yaps.rc</a>. This could be used as a base for your own
|
||||
global configuration file.
|
||||
|
||||
<H2>Calling</H2>
|
||||
|
||||
Typically the program is called <strong>yaps <pagerid>
|
||||
<message></strong>. <em>pagerid</em> is either the exact pagerid of
|
||||
the receiver or an alias found in the alias section. <em>message</em> is the
|
||||
message to send by itself. If a pager-id leads to more than one provider,
|
||||
then the first is used. To force a special service use the <strong>-s
|
||||
<service></strong> switch.
|
||||
|
||||
<H2>Script protocol</H2>
|
||||
|
||||
In the contrib directory, you can find <a href="contrib/tap.sl">tap.sl</a>,
|
||||
an example on how to use the scripting facility to emulate a protocol. This
|
||||
is a minimal, but working reimplemetation of TAP.
|
||||
|
||||
<H1 ID="chlog">Changelog</H1>
|
||||
|
||||
This is a list of changes:
|
||||
<Ul Plain>
|
||||
<Li> 9. May 1997: V 0.90 released
|
||||
<Ul Compact>
|
||||
<Li> Minor cleanup on calling sending routines
|
||||
<Li> Added optional multiple receiver per message
|
||||
<Li> Changing UCP to prepare the real implementation
|
||||
<Li> Preparing the creation of a client/server solution
|
||||
<Li> Compile configuration moved to seperate file
|
||||
</Ul>
|
||||
<Li> 13. May 1997: V 0.91 released
|
||||
<Ul Compact>
|
||||
<Li> Converted `char *' to `string_t *' in several places
|
||||
<Li> Added max-messages configuration option
|
||||
<Li> Moved some configuration stuff to config.h
|
||||
<Li> Got UCP docu! Implemented it partial (as much as it makes sense)
|
||||
<Li> Added option -d/-e as UCP (in extended mode) can support it
|
||||
<Li> Added special date handling functions for this purpose
|
||||
<Li> Changed copyright to the GPL
|
||||
<Li> Use transparent data in extended UCP, if characters with
|
||||
set 8th bit are found
|
||||
<Li> Better message splitting
|
||||
<Li> Added some sanity checks
|
||||
</Ul>
|
||||
<Li> 22. May 1997: V 0.92 released
|
||||
<Ul Compact>
|
||||
<Li> Added handling of configuration variants
|
||||
<Li> Added include option in configuration files
|
||||
<Li> First bugs encountered by tester fixed
|
||||
<Li> Message can now be read from stdin, if message == '-'
|
||||
(idea by <markus@mail.yezz.de>)
|
||||
<Li> Message can now be empty, if message == '.'
|
||||
<Li> Minor bugfixing/Makefilehandling (reported by Frank Käfer)
|
||||
<Li> Enhanced lockfile handling, including SysV4 lockfiles (inspirated
|
||||
by Frank Käfer)
|
||||
<Li> Total rewrite of UCP sending
|
||||
</Ul>
|
||||
<Li> 26. May 1997: V 0.93 released
|
||||
<Ul Compact>
|
||||
<Li> UCP works again including delivery report
|
||||
<Li> Added checking of pager id for a service
|
||||
<Li> Added signature in configuration file
|
||||
<Li> Added value start escaping with backslash
|
||||
<Li> Changed checking of pager id for service
|
||||
<Li> Automatic assign of a pager id to a service
|
||||
<Li> Could now handle more than one service at one call
|
||||
</Ul>
|
||||
<Li> 30. May 1997: V 0.94 released
|
||||
<Ul Compact>
|
||||
<Li> Workaround for serial bug in sunos/solaris (by Frank Käfer)
|
||||
<Li> If the system does not support Posix regular expression, a simple
|
||||
replacement is added
|
||||
<Li> More comments in yaps.rc (as wished by Frank Käfer ;-)
|
||||
<Li> Change handling of control chars in TAP/pre V1.6 (hint by
|
||||
<markus@mail.yezz.de>)
|
||||
<Li> Added default conversion rules
|
||||
<Li> Added force/-f
|
||||
<Li> Added long options support
|
||||
<Li> Added getopt() for systems without this function
|
||||
<Li> Added valid-cid/change-cid/rm-invalids-cid/rm-invalids-pid
|
||||
</Ul>
|
||||
<Li> 3. June 1997: V 0.95 released
|
||||
<Ul Compact>
|
||||
<Li> Added final status report
|
||||
<Li> Added a 2nd checking scheme
|
||||
<Li> Added support for lua (another scripting language)
|
||||
<Li> Removed porting approach, should be done by someone who
|
||||
has access to such an OS.
|
||||
<Li> Added reading of pager-id/message pairs from file
|
||||
<Li> Added cost calculation
|
||||
<Li> Enhanced logfile handling
|
||||
</Ul>
|
||||
<Li> 14. June 1997: V 0.96 released
|
||||
</Ul>
|
||||
|
||||
</Body></HTML>
|
|
@ -0,0 +1,19 @@
|
|||
Begin3
|
||||
Title: yaps
|
||||
Version: 0.96
|
||||
Entered-date: 14JUN97
|
||||
Description: This is a standalone program to send messages to paging
|
||||
devices over a modem gateway using well defined protocols.
|
||||
Keywords: pager sms tap ucp
|
||||
Author: ud@nitmar.tnet.de (Ulrich Dessauer)
|
||||
Maintained-by: ud@nitmar.tnet.de (Ulrich Dessauer)
|
||||
Primary-site: ftp.sta.com /pub/fk/yaps
|
||||
91k yaps-0.96.tar.gz
|
||||
725 yaps.lsm
|
||||
Alternate-site: sunsite.unc.edu /pub/Linux/apps/serialcomm/machines/
|
||||
91k yaps-0.96.tar.gz
|
||||
725 yaps.lsm
|
||||
Platforms: Linux, Solaris, SunOS and modem (or modem like device,
|
||||
e.g. ISDN) optional SLang V99.38, Lua-2.5
|
||||
Copying-policy: GPL
|
||||
End
|
|
@ -0,0 +1,370 @@
|
|||
# -*- sh -*-
|
||||
#
|
||||
# General yaps example configuration file
|
||||
#
|
||||
#########################################
|
||||
# global section #
|
||||
#########################################
|
||||
#
|
||||
# This is a comma seperated list of available services. This
|
||||
# is required for autodetect the matching service for a
|
||||
# pager-id
|
||||
services D1,D2,E+
|
||||
+services Telmi,Telmi-Fun,Telmi-Family,Telmi-Top,Telmi-Pro
|
||||
+services Skyper,Quix
|
||||
#
|
||||
# This is the default caller-id. If the protocol/service allowes
|
||||
# it, this is inserted in the message (and the receiver gets this
|
||||
# as the sender's number)
|
||||
call-id +1-(555)-1234
|
||||
#
|
||||
# If you forget to sign your message, you can automatically append
|
||||
# this string to each message.
|
||||
signature (It's me!)
|
||||
#
|
||||
# You can either switch the use of the signature here on for all
|
||||
# services or in each service section for that particular service.
|
||||
use-signature True
|
||||
#
|
||||
# To get more verbose output when running yaps increase this value.
|
||||
# Currently 4 is the highest supported value.
|
||||
verbose 0
|
||||
#
|
||||
# If you'd like to log every sending session define this. It should
|
||||
# point to a writeable file. If you install the software setgid, then
|
||||
# change the group of this file to the same yaps uses and make it
|
||||
# group writeable.
|
||||
logfile /var/log/yaps.log
|
||||
#
|
||||
# A comma seperated list of modem sections. You can also define this
|
||||
# in each service section.
|
||||
modems standard
|
||||
#
|
||||
# some global defaults for the serial interface (even if the most
|
||||
# protocols are assuming 7e1, these settings seem to work well)
|
||||
speed 38400
|
||||
bits-per-byte 8
|
||||
parity none
|
||||
stopbits 1
|
||||
|
||||
#
|
||||
# To calculate the cost for each call, you can define some globales
|
||||
# here and do the fine tuning in each protocol
|
||||
cost cost=0.12,unit=DM,remainder=2,dial-overhead=13
|
||||
|
||||
#
|
||||
# These are two example of internal conversion tables. The can be
|
||||
# used using the `convert' entry (see below).
|
||||
cv-default {
|
||||
Ä [
|
||||
Ö \
|
||||
Ü ]
|
||||
ä {
|
||||
ö |
|
||||
ü }
|
||||
ß ~
|
||||
}
|
||||
cv-extend {
|
||||
\l \s
|
||||
\n \s
|
||||
\r \s
|
||||
\f \s
|
||||
\t \s
|
||||
}
|
||||
|
||||
#
|
||||
# These values are normally only found in each service section,
|
||||
# but are listen here with an explaination for completeness.
|
||||
#
|
||||
# This is the phone number of the modem gateway for this service
|
||||
#phone 0015559876
|
||||
|
||||
#
|
||||
# This is the protocol the service uses. Currently this can be
|
||||
# either ascii, script, ucp or tap. Each protocol has a set of
|
||||
# special configuration parameters, see below.
|
||||
#protocol tap
|
||||
|
||||
#
|
||||
# Most services limit the length of a message to a specific length.
|
||||
# Enter the value here to check valid messages
|
||||
#max-size 160
|
||||
|
||||
#
|
||||
# If a message is longer than max-size, you can set this to split
|
||||
# it off into several single messages of allowed length
|
||||
#may-split True
|
||||
|
||||
#
|
||||
# If a message is longer than max-size, you can set this to truncate
|
||||
# the message to the allowed length. The remaining part is discarded.
|
||||
#truncate True
|
||||
|
||||
#
|
||||
# Some services allow to send more than one message per session. If
|
||||
# it is limited, set it using this parameter
|
||||
#max-messages 1
|
||||
|
||||
#
|
||||
# If the service allows using your caller-id set this to True.
|
||||
#use-call-id True
|
||||
|
||||
#
|
||||
# If the service is reachable over a phonenumber where the pager-id
|
||||
# is part of the phone number, define this and add a `%P' anywehere
|
||||
# in the `phone' number.
|
||||
#insert-pager-id True
|
||||
|
||||
#
|
||||
# Remove these characters from the pager-id, as they are not valid
|
||||
rm-invalids-pid + (-)
|
||||
|
||||
#
|
||||
# Dito for caller id
|
||||
rm-invalids-cid + (-)
|
||||
|
||||
#
|
||||
# Check for valid call id (see below for more details) While
|
||||
# valid-pid is required, this is optional
|
||||
#valid-cid ^(001|1)
|
||||
#change-cid 001
|
||||
|
||||
#
|
||||
# Depending on your system the value for this parameter is either a
|
||||
# regular expression or a simple list of strings (seperated by bars)
|
||||
# which must match the prefix of the pager-id.
|
||||
#valid-pid ^(0171|0049171)
|
||||
#valid-pid 0171|0049171
|
||||
# Use these paramters in the global section if you want do not want
|
||||
# to check pager-ids (and do not set change-pid):
|
||||
#valid-pid .
|
||||
#valid-pid -
|
||||
|
||||
#
|
||||
# If a pagerid has matched the expression above, then the matching part
|
||||
# may be replaced by this string
|
||||
#change-pid 0171
|
||||
|
||||
#
|
||||
# As the services do not use (in general) the ISO 8859/1 character set,
|
||||
# one can define convertion tables. you can either specify a file which
|
||||
# contains the convertion rules:
|
||||
#conv-table /usr/local/lib/yaps/iso2din.tab
|
||||
|
||||
# or use predefined convertion rules
|
||||
#convert *no-control,*no-8bit,cv-default,cv-extended
|
||||
|
||||
#
|
||||
# If this is set, send a message even if a requested feature is
|
||||
# not available
|
||||
#force True
|
||||
|
||||
#
|
||||
# If the provider supportes to set a delay for sending the message,
|
||||
# set this
|
||||
#can-delay True
|
||||
|
||||
#
|
||||
# If the provider can delete a buffered message after a period of time,
|
||||
# set this
|
||||
#can-expire True
|
||||
|
||||
#
|
||||
# If the provider can report a delivery status, set this.
|
||||
#can-rds True
|
||||
|
||||
#
|
||||
# To check wether a call-id/pager-id is valid use these paramters.
|
||||
# For the exact syntax see the documentation
|
||||
#check-call-id >1111111111111111<
|
||||
#check-pager-id >1111111111111111<
|
||||
#check-call-id +minimum=0,maximum=16,type=numeric
|
||||
|
||||
#
|
||||
# These values are typically found in a modem section, but can also
|
||||
# appear in the global section to set some defaults
|
||||
|
||||
#
|
||||
# Set this to the modem device you wish to use
|
||||
#device /dev/modem
|
||||
#device /dev/cua1
|
||||
#device /dev/cua/a
|
||||
|
||||
#
|
||||
# Set this to the prefix of the lockfile use for the device. There
|
||||
# are several places, and two common formats:
|
||||
#lock-prefix /usr/spool/uucp/LCK..
|
||||
#lock-prefix /var/spool/lock/LCK..
|
||||
#lock-prefix /var/spool/locks/LK.
|
||||
|
||||
#
|
||||
# The different format of the part which is appended to the lockfile
|
||||
# and the contents can be specified here. See documentation for a
|
||||
# full list inclusive explaination
|
||||
#lock-method sysv4
|
||||
#lock-method binary
|
||||
#lock-method timeout=10
|
||||
|
||||
#
|
||||
# These are send/expect sequences to talk to the modem. For an exact
|
||||
# definition see (again) the documentation. Following entries are
|
||||
# supported:
|
||||
# init: to initialize the modem
|
||||
# local-init: a second initialization string, used to customize
|
||||
# already defined modems for different handling
|
||||
# dial: to dial a phone number %L is replaced with the
|
||||
# phone number itself
|
||||
# timeout: the default timeout in seconds to wait for answers
|
||||
# reset: to reset the modem
|
||||
|
||||
#########################################
|
||||
# service section #
|
||||
#########################################
|
||||
#
|
||||
# D1 (by Deutsche Telekom)
|
||||
#
|
||||
[D1]
|
||||
protocol tap
|
||||
valid-pid 0171|0049171|49171
|
||||
change-pid 0171
|
||||
convert *no-8bit,cv-d1
|
||||
cv-d1 {
|
||||
Ä [
|
||||
Ö \
|
||||
Ü ~
|
||||
ä {
|
||||
ö |
|
||||
ü ~
|
||||
ß ^]
|
||||
}
|
||||
+cost timetable=Wk0800-1800=5.7;Wk1800-0800=11.4;Ss=11.4
|
||||
phone 01712092522
|
||||
max-size 160
|
||||
may-split True
|
||||
use-call-id False
|
||||
tap-old True
|
||||
#
|
||||
# D2 (by Mannesmann Mobilfunk)
|
||||
#
|
||||
[D2]
|
||||
modem standard-d2
|
||||
protocol ucp
|
||||
valid-pid 0172|0049172|49172
|
||||
change-pid 0172
|
||||
convert *no-8bit,cv-default
|
||||
+cost timetable=Wk0800-1800=5.7;Wk1800-0800=11.4;Ss=11.4
|
||||
phone 01722278020
|
||||
max-size 160
|
||||
may-split True
|
||||
use-call-id True
|
||||
can-delay True
|
||||
can-expire True
|
||||
can-rds True
|
||||
check-call-id >1111111111111111<
|
||||
check-pager-id >1111111111111111<
|
||||
ucp-extend True
|
||||
#
|
||||
# E+ (by ???)
|
||||
# !! UNTESTED !!
|
||||
#
|
||||
[E+]
|
||||
protocol tap
|
||||
valid-pid 0177|0049177|49177
|
||||
change-pid 0177
|
||||
convert *no-8bit,cv-default
|
||||
+cost timetable=Wk0800-1800=5.7;Wk1800-0800=11.4;Ss=11.4
|
||||
phone 01771167
|
||||
max-size 160
|
||||
may-split True
|
||||
use-call-id False
|
||||
#
|
||||
# Telmi, Telmi-* (by Deutsche Funkruf)
|
||||
# !! ONLY TESTED FOR TELMI-FUN !!
|
||||
#
|
||||
[Telmi]
|
||||
protocol tap
|
||||
valid-pid 01661|01665|00491661|00491665|491661|491665
|
||||
change-pid -
|
||||
convert *no-control,*no-8bit,cv-default,cv-extend
|
||||
+cost entity-length=5.2
|
||||
phone 016601010101
|
||||
max-size 114
|
||||
may-split True
|
||||
max-messages 1
|
||||
use-call-id False
|
||||
check-pager-id 1111111
|
||||
tap-old True
|
||||
[Telmi-Fun] Telmi
|
||||
[Telmi-Family] Telmi
|
||||
[Telmi-Top] Telmi
|
||||
max-size 240
|
||||
[Telmi-Pro] Telmi-Top
|
||||
#
|
||||
# Skyper (by Deutsche Telekom)
|
||||
# !! UNTESTED !!
|
||||
#
|
||||
[Skyper]
|
||||
protocol tap
|
||||
valid-pid 01692|00491692|491692
|
||||
change-pid -
|
||||
convert *no-8bit,cv-default,cv-extend
|
||||
+cost fixed,cost=0.96
|
||||
phone 01692%P
|
||||
max-size 80
|
||||
use-call-id False
|
||||
insert-pager-id True
|
||||
#
|
||||
# Quix (by Miniruf)
|
||||
# !! UNTESTED !!
|
||||
#
|
||||
[Quix]
|
||||
protocol ucp
|
||||
valid-pid 01653|00491653|491653
|
||||
change-pid -
|
||||
+cost fixed,timetable=Wk0800-1800=1.20;Al=0.96
|
||||
convert *no-8bit,cv-default,cv-extend
|
||||
phone 016593
|
||||
max-size 80
|
||||
use-call-id True
|
||||
|
||||
#########################################
|
||||
# modem section #
|
||||
#########################################
|
||||
[standard]
|
||||
#
|
||||
# Locking
|
||||
#
|
||||
# Older Unix versions
|
||||
lock-prefix /usr/spool/uucp/LCK..
|
||||
# Newer Unix versions
|
||||
#lock-prefix /var/spool/uucp/LCK..
|
||||
#lock-prefix /var/lock/LCK..
|
||||
# SysV4
|
||||
#lock-prefix /var/spool/locks/LK.
|
||||
#lock-method sysv4
|
||||
#
|
||||
# Device
|
||||
#
|
||||
# Typical a symbolic link to the real device
|
||||
device /dev/modem
|
||||
# "normal" call-out device
|
||||
#device /dev/cua1
|
||||
# Solaris convention
|
||||
#device /dev/cua/a
|
||||
|
||||
#
|
||||
# Modem talk
|
||||
#
|
||||
init \\r !200D ATZ\r <OK ATE0Q0V1\r <OK
|
||||
dial ATD%L\r <60CONNECT|OK|BUSY|NO\sDIALTONE|NO\sCARRIER
|
||||
reset ATZ\r <OK
|
||||
timeout 10
|
||||
# Customizing an existing modem entry
|
||||
[standard-d2] standard
|
||||
local-init AT\%C2\r <OK
|
||||
#
|
||||
# alias section
|
||||
#
|
||||
[alias]
|
||||
#foo 001 555 1221
|
||||
#bar +1-(555)-2112
|
Loading…
Reference in New Issue