Taylor UUCP 1.04
This commit is contained in:
parent
4ff3cd9d3d
commit
a5ebd84e62
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242
339
gnu/libexec/uucp/COPYING
Normal file
339
gnu/libexec/uucp/COPYING
Normal file
@ -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
|
||||||
|
|
||||||
|
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.
|
3152
gnu/libexec/uucp/ChangeLog
Normal file
3152
gnu/libexec/uucp/ChangeLog
Normal file
File diff suppressed because it is too large
Load Diff
8
gnu/libexec/uucp/Makefile
Normal file
8
gnu/libexec/uucp/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# This is the Makefile for Taylor UUCP
|
||||||
|
# $Id: Makefile,v 1.4 1993/08/05 17:56:17 jtc Exp $
|
||||||
|
|
||||||
|
SUBDIR= libunix libuucp libuuconf \
|
||||||
|
cu uuchk uucico uuconv uucp uulog uuname uupick uusched \
|
||||||
|
uustat uuto uux uuxqt
|
||||||
|
|
||||||
|
.include <bsd.subdir.mk>
|
30
gnu/libexec/uucp/Makefile.inc
Normal file
30
gnu/libexec/uucp/Makefile.inc
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
.if exists(${.CURDIR}/../libunix/obj)
|
||||||
|
LIBUNIX= $(.CURDIR)/../libunix/obj/libunix.a
|
||||||
|
.else
|
||||||
|
LIBUNIX= $(.CURDIR)/../libunix/libunix.a
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.if exists(${.CURDIR}/../libuuconf/obj)
|
||||||
|
LIBUUCONF= $(.CURDIR)/../libuuconf/obj/libuuconf.a
|
||||||
|
.else
|
||||||
|
LIBUUCONF= $(.CURDIR)/../libuuconf/libuuconf.a
|
||||||
|
.endif
|
||||||
|
|
||||||
|
.if exists(${.CURDIR}/../libuucp/obj)
|
||||||
|
LIBUUCP= $(.CURDIR)/../libuucp/obj/libuucp.a
|
||||||
|
.else
|
||||||
|
LIBUUCP= $(.CURDIR)/../libuucp/libuucp.a
|
||||||
|
.endif
|
||||||
|
|
||||||
|
VERSION= 1.04
|
||||||
|
owner= uucp
|
||||||
|
bindir= /usr/bin
|
||||||
|
sbindir= /usr/libexec/uucp
|
||||||
|
|
||||||
|
# The directory to look in for new style configuration files (when
|
||||||
|
# using HAVE_TAYLOR_CONFIG).
|
||||||
|
newconfigdir= /etc/uucp
|
||||||
|
|
||||||
|
# The directory to look in for BNU (when using HAVE_BNU_CONFIG) or
|
||||||
|
# V2 (when using HAVE_V2_CONFIG) style configuration files.
|
||||||
|
oldconfigdir= /etc/uucp
|
207
gnu/libexec/uucp/README
Normal file
207
gnu/libexec/uucp/README
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
This is the README file for version 1.04 of the Taylor UUCP package.
|
||||||
|
|
||||||
|
It was written by Ian Lance Taylor. I can be reached at ian@airs.com,
|
||||||
|
or, equivalently, uunet!cygint!airs!ian, or c/o Cygnus Support, 4th
|
||||||
|
Floor, Building 200, 1 Kendall Square, Cambridge MA, 02139, USA.
|
||||||
|
|
||||||
|
There is a mailing list for discussion of the package. To join (or
|
||||||
|
get off) the list, send mail to taylor-uucp-request@gnu.ai.mit.edu.
|
||||||
|
Mail to this address is answered by a person, not a program. When
|
||||||
|
joining the list, make sure you include the address at which you want
|
||||||
|
to receive mail in the body of your message. To send a message to the
|
||||||
|
list, send it to taylor-uucp@gnu.ai.mit.edu.
|
||||||
|
|
||||||
|
This package is covered by the Gnu Public License. See the file
|
||||||
|
COPYING for details. If you would like to do something with this
|
||||||
|
package that you feel is reasonable but you feel is prohibited by the
|
||||||
|
license, contact me to see if we can work it out.
|
||||||
|
|
||||||
|
WHAT IT IS
|
||||||
|
|
||||||
|
This is the complete source code for a Unix UUCP package. It provides
|
||||||
|
everything you need to make a UUCP connection. It includes versions
|
||||||
|
of uucico, uusched, uuxqt, uux, uucp, uustat, uulog, uuname, uuto,
|
||||||
|
uupick, and cu, as well as uuchk (a program to check configuration
|
||||||
|
files), uuconv (a program to convert from one type of configuration
|
||||||
|
file to another) and tstuu (a test harness for the package).
|
||||||
|
|
||||||
|
The Free Software Foundation plans to make this their standard UUCP
|
||||||
|
package.
|
||||||
|
|
||||||
|
The package currently supports the 'f', 'g' (in all window and packet
|
||||||
|
sizes), 'G', 't' and 'e' protocols, as well a Zmodem protocol and two
|
||||||
|
new bidirectional protocols. If you have a Berkeley sockets library,
|
||||||
|
it can make TCP connections. If you have TLI libraries, it can make
|
||||||
|
TLI connections. It supports a new configuration file mechanism which
|
||||||
|
I like (but other people dislike).
|
||||||
|
|
||||||
|
The package has a few advantages over regular UUCP:
|
||||||
|
|
||||||
|
You get the source code.
|
||||||
|
|
||||||
|
It uses significantly less CPU time than many UUCP packages.
|
||||||
|
|
||||||
|
You can specify a chat script to run when a system calls in,
|
||||||
|
allowing adjustment of modem parameters on a per system basis.
|
||||||
|
|
||||||
|
You can specify failure strings for chat scripts, allowing the
|
||||||
|
chat script to fail immediately if the modem returns ``BUSY''.
|
||||||
|
|
||||||
|
If you are talking to another instance of the package, you can use
|
||||||
|
the new bidirectional protocol for rapid data transfer in both
|
||||||
|
directions at once. You can also restrict file transfers by size
|
||||||
|
based on the time of day and who placed the call.
|
||||||
|
|
||||||
|
On the other hand:
|
||||||
|
|
||||||
|
It only runs on Unix. The code is carefully divided into system
|
||||||
|
dependent and system independent portions, so it should be
|
||||||
|
possible to port it to other systems. It would not be trivial.
|
||||||
|
|
||||||
|
You don't get uuclean, uusend, uuq, uusnap, uumonitor, uutry,
|
||||||
|
uupoll, etc. If you have current copies of these programs, you
|
||||||
|
may be able to use them. Shell scripts versions of uuclean and
|
||||||
|
uutry are provided, with most, if not all, of the functionality of
|
||||||
|
the usual programs. I believe the supplied uustat program allows
|
||||||
|
you to do everything that uuq, uusnap and uumonitor do. uupoll
|
||||||
|
could be written as a shell script.
|
||||||
|
|
||||||
|
The package does not read modemcap or acucap files, although you
|
||||||
|
can use V2 configuration files with a BNU Dialers file or a dialer
|
||||||
|
file written in my new configuration file format.
|
||||||
|
|
||||||
|
The package cannot use SCO dialer programs directly, although it
|
||||||
|
can with a simple shell script interface.
|
||||||
|
|
||||||
|
If you start using this package, I suggest that you join the mailing
|
||||||
|
list (see above) to keep up to date on patches and new versions. I am
|
||||||
|
also open to suggestions for improvements and modifications.
|
||||||
|
|
||||||
|
CHANGES SINCE 1.03
|
||||||
|
|
||||||
|
For a complete list, see ChangeLog.
|
||||||
|
|
||||||
|
IMPORTANT: the default when talking to another version of 1.04 is to
|
||||||
|
use the new bidirectional 'i' protocol. If you are using a
|
||||||
|
half-duplex modem, such as a Telebit T2500, you will want to either
|
||||||
|
mark the port as half-duplex with the ``half-duplex'' command, or
|
||||||
|
force use of the 'g' protocol by using the ``protocol'' command in the
|
||||||
|
sys or port file or by adding ``,g'' after the port name in the
|
||||||
|
Systems or L.sys or Devices file.
|
||||||
|
|
||||||
|
As usual, many bugs were fixed.
|
||||||
|
|
||||||
|
Bidirectional transfers are supported with the new 'i' protocol;
|
||||||
|
it requires an eight-bit clear datapath.
|
||||||
|
|
||||||
|
New programs: uusched, cu, uuto and uupick.
|
||||||
|
|
||||||
|
The 'G' protocol and a new Zmodem protocol were added.
|
||||||
|
|
||||||
|
A number of uustat options were added to support uuclean, and a
|
||||||
|
sample uuclean shell script was added to the contrib directory.
|
||||||
|
The uustat output formats were changed slightly.
|
||||||
|
|
||||||
|
A protocol extension eliminates transfer of the command file for
|
||||||
|
simple commands, such as rmail or rnews, when talking to another
|
||||||
|
version of 1.04.
|
||||||
|
|
||||||
|
Some TLI support was added.
|
||||||
|
|
||||||
|
UUCP forwarding was added, along with the ``forward-to'',
|
||||||
|
``forward-from'' and ``forward'' commands.
|
||||||
|
|
||||||
|
If a file transfer fails in the middle, the retry will now start
|
||||||
|
from where it left off. The implementation is compatible with
|
||||||
|
SVR4.
|
||||||
|
|
||||||
|
The work queue is checked every 10 minutes during a conversation;
|
||||||
|
if there is new work and a bidirectional protocol is not in use,
|
||||||
|
the receiving uucico requests the sender to transfer control.
|
||||||
|
|
||||||
|
The amount of free disk space is checked periodically as a file is
|
||||||
|
received, and if it drops too low the call is aborted.
|
||||||
|
|
||||||
|
The UUCP configuration file reading routines were moved into a
|
||||||
|
standalone library, uuconf. All known bugs in V2 and HDB
|
||||||
|
configuration file reading were fixed.
|
||||||
|
|
||||||
|
The ``half-duplex'' command was added for the port and dialer
|
||||||
|
files.
|
||||||
|
|
||||||
|
The ``max-retries'', ``success-wait'', ``send-request'' and
|
||||||
|
``receive-request'' commands were added for the sys file. The
|
||||||
|
``call-request'' and ``called-request'' commands were eliminated
|
||||||
|
(they did not work correctly anyhow).
|
||||||
|
|
||||||
|
\d in chat scripts now calls sleep (2) rather than sleep (1), so
|
||||||
|
it will sleep longer (on some systems sleep(1) may delay much less
|
||||||
|
than one second).
|
||||||
|
|
||||||
|
SPOOLDIR_SVR4 was added for SVR4 style spool directories.
|
||||||
|
|
||||||
|
Defaults are now permitted in the port and dialer files.
|
||||||
|
|
||||||
|
The ALIAS field is supported in the HDB Permissions file.
|
||||||
|
|
||||||
|
DOCUMENTATION
|
||||||
|
|
||||||
|
The documentation is in the file uucp.texi, which is a Texinfo file.
|
||||||
|
Texinfo is a format used by the Free Software Foundation. You can
|
||||||
|
print the documentation using TeX in combination with the file
|
||||||
|
texinfo.tex. DVI, PostScript and info versions of the documentation
|
||||||
|
are available in a separate package, uucp-doc-1.04.tar.Z.
|
||||||
|
|
||||||
|
See the TODO file for things which should be done. Please feel free
|
||||||
|
to do them, although you may want to check with me first. Send me
|
||||||
|
suggestions for new things to do.
|
||||||
|
|
||||||
|
The compilation instructions are in uucp.texi. Here is a summary.
|
||||||
|
|
||||||
|
Edit Makefile.in to set installation directories.
|
||||||
|
|
||||||
|
Type ``sh configure''. You can pass a number of arguments in the
|
||||||
|
environment (using bash or sh, enter something like ``CC=gcc
|
||||||
|
configure''; using csh, enter something like ``setenv CC gcc; sh
|
||||||
|
configure''):
|
||||||
|
CC: C compiler to use; default is gcc if it exists, else cc
|
||||||
|
CFLAGS: Flags to pass to $CC when compiling; default -g
|
||||||
|
LDFLAGS: Flags to pass to $CC when only linking; default none
|
||||||
|
LIBS: Library arguments to pass to $CC; default none
|
||||||
|
INSTALL: Install program; default install -c or cp
|
||||||
|
INSTALLDATA: Install data; default install -c -m 0644 or cp
|
||||||
|
The configure script will compile a number of test programs to see
|
||||||
|
what is available on your system, so if your system is at all
|
||||||
|
unusual you will need to pass in $CC and $LIBS correctly.
|
||||||
|
|
||||||
|
The configure script will create conf.h from conf.h.in and
|
||||||
|
Makefile from Makefile.in. It will also create config.status,
|
||||||
|
which is a shell script which actually creates the files. Please
|
||||||
|
report any configuration problems, so that they can be fixed in
|
||||||
|
later versions.
|
||||||
|
|
||||||
|
Igor V. Semenyuk provided this (lightly edited) note about ISC
|
||||||
|
Unix 3.0. The configure script will default to passing -posix to
|
||||||
|
gcc. However, using -posix changes the environment to POSIX, and
|
||||||
|
on ISC 3.0, at least, the default for POSIX_NO_TRUNC is 1. This
|
||||||
|
means nothing for uucp, but can lead to a problem when uuxqt
|
||||||
|
executes rmail. IDA sendmail has dbm configuration files named
|
||||||
|
mailertable.{dir,pag}. Notice these names are 15 characters long.
|
||||||
|
When uuxqt compiled with -posix executes rmail, which in turn
|
||||||
|
executes sendmail, the later is run under POSIX environment too!
|
||||||
|
This leads to sendmail bombing out with 'error opening 'M'
|
||||||
|
database: name too long' (mailertable.dir). It's rather obscure
|
||||||
|
behaviour, and it took me a day to find out the cause. I don't
|
||||||
|
use -posix, instead I run gcc with -D_POSIX_SOURCE, and add
|
||||||
|
-lcposix to LIBS.
|
||||||
|
|
||||||
|
Examine conf.h and Makefile to make sure they're right.
|
||||||
|
|
||||||
|
Edit policy.h for your local system.
|
||||||
|
|
||||||
|
Type ``make''.
|
||||||
|
|
||||||
|
Use ``uuchk'' to check configuration files. You can use
|
||||||
|
``uuconv'' to convert between configuration file formats.
|
||||||
|
|
||||||
|
Type ``make install'' to install.
|
573
gnu/libexec/uucp/TODO
Normal file
573
gnu/libexec/uucp/TODO
Normal file
@ -0,0 +1,573 @@
|
|||||||
|
This is a list of things to do for the Taylor UUCP package. Please
|
||||||
|
feel free to work on any of them. You may want to check with me first
|
||||||
|
to make sure that nobody else is working on them as well.
|
||||||
|
|
||||||
|
Some of these are my thoughts, but most are suggestions from other
|
||||||
|
people; I have tried to give credit. They are in the order I received
|
||||||
|
them; the missing numbers have already been implemented.
|
||||||
|
|
||||||
|
Just because something is on the list doesn't mean that I necessarily
|
||||||
|
think it is a good idea. It does mean that I think it's worth
|
||||||
|
thinking about.
|
||||||
|
|
||||||
|
2.
|
||||||
|
|
||||||
|
John Cowan <cowan@snark.thyrsus.com> says:
|
||||||
|
|
||||||
|
>I think you should accept a broader range of time specifications.
|
||||||
|
>Consider using getdate() (from your handy Usenet news source code)
|
||||||
|
>with its high-powered yacc parser.
|
||||||
|
|
||||||
|
Of course, getdate() accepts a single date, but we want a range. A
|
||||||
|
better syntax would be certainly be nice.
|
||||||
|
|
||||||
|
9.
|
||||||
|
|
||||||
|
Gordon Burditt <gordon@sneaky.lonestar.org> warns about modifications
|
||||||
|
to the TZ environment variable, to fool uucico into dialing out at an
|
||||||
|
inappropriate time.
|
||||||
|
|
||||||
|
10.
|
||||||
|
|
||||||
|
Gordon Burditt <gordon@sneaky.lonestar.org> says:
|
||||||
|
|
||||||
|
>(4) Less important, because few people will have this problem, is a
|
||||||
|
>port-specific dialcodes file. Why? Well, one system I had was connected
|
||||||
|
>to 2 inside lines "dial 9 for outside line", and one outside line (which
|
||||||
|
>doesn't want the 9). A number of the systems called were "inside", so
|
||||||
|
>you didn't add the 9 on those lines dialing from inside, but you did add
|
||||||
|
>"390" to the 4-digit number if you dialed it via "outside". Also not
|
||||||
|
>unheard of are systems with 2 outside lines that are local to different
|
||||||
|
>area codes, or one local outside line and one WATS line (which MUST
|
||||||
|
>have an area code).
|
||||||
|
>Example:
|
||||||
|
> inside-line Dialcodes outside-line Dialcodes
|
||||||
|
> pbx "" pbx "390"
|
||||||
|
> local "9" local ""
|
||||||
|
> nyc "9-1212" nyc "1212"
|
||||||
|
|
||||||
|
12.
|
||||||
|
|
||||||
|
Ralf E. Stranzenbach <ralf@reswi.ruhr.de> says:
|
||||||
|
|
||||||
|
>It would be nice to also have the option of running a shell script each time
|
||||||
|
>uucico connects/disconnects a systen. I do not mean shell scripts for dial/in.
|
||||||
|
>I would like to do some accounting and batching when the connection
|
||||||
|
>establishes.
|
||||||
|
|
||||||
|
13.
|
||||||
|
|
||||||
|
les@chinet.chi.il.us (Leslie Mikesell) writes:
|
||||||
|
|
||||||
|
>>local-send /usr/spool/uucppublic !/usr/spool/uucpublic/private
|
||||||
|
>>
|
||||||
|
>>The directories are searched from left to right, and the last one to
|
||||||
|
>>match determines whether the file may be sent or not. This is
|
||||||
|
>>slightly more general than NOWRITE, since it permits a public
|
||||||
|
>>directory within a private directory within a public directory,
|
||||||
|
>>although probably nobody will ever want that.
|
||||||
|
>
|
||||||
|
>Interesting... The obvious enhancement is to generalize to shell-like
|
||||||
|
>wild cards for the READ/WRITE/COMMANDS entries.
|
||||||
|
|
||||||
|
14.
|
||||||
|
|
||||||
|
Should there be a way for chat scripts to specify the parity to
|
||||||
|
generate? I don't think there's much point to specifying what parity
|
||||||
|
to accept.
|
||||||
|
|
||||||
|
17.
|
||||||
|
|
||||||
|
The -b and -s switches to uux are not implemented by uuxqt.
|
||||||
|
|
||||||
|
18.
|
||||||
|
|
||||||
|
If we are supposed to call a system back, we should do it immediately
|
||||||
|
rather than merely queuing up an empty command file.
|
||||||
|
|
||||||
|
22.
|
||||||
|
|
||||||
|
Add an ftp port type which uses anonymous ftp rather than any of the
|
||||||
|
UUCP protocols to do file transfers. This would allow ftp work to be
|
||||||
|
done late at night, and allow neighbors of cooperative Internet sites
|
||||||
|
to use UUCP forwarding for anonymous FTP.
|
||||||
|
|
||||||
|
31.
|
||||||
|
|
||||||
|
David Nugent: add a -C option to uucico to only call the system if
|
||||||
|
there is work to do.
|
||||||
|
|
||||||
|
32.
|
||||||
|
|
||||||
|
It would be nice if uucico could sleep until a line was available.
|
||||||
|
This is complicated by the possibility of wanting to wait for any of
|
||||||
|
several different lines, and one would really want some sort of
|
||||||
|
semaphore function to do it right. If the available lines could be
|
||||||
|
sorted, then each could be assigned to a byte in a line lock file.
|
||||||
|
Looking for a line could be done by sleeping on a read lock on all
|
||||||
|
possible lines. Once it came through, write locks would be attempted.
|
||||||
|
If they all failed, somebody else snuck in, so you would sleep on a
|
||||||
|
read lock again. This isn't great because a process could be starved,
|
||||||
|
but it might be better than nothing.
|
||||||
|
|
||||||
|
This could be tied in to uucp and uux, such that they wouldn't
|
||||||
|
actually fire up uucico unless a line was known to be available; an
|
||||||
|
additional switch would be used to fire up uucico anyhow (or one could
|
||||||
|
switch the default behaviour and the switch).
|
||||||
|
|
||||||
|
So how do you sort the lines? You could just use the index in the
|
||||||
|
port (or Devices) file, but what if multiple ports used the same
|
||||||
|
physical device? Hmmm.
|
||||||
|
|
||||||
|
43.
|
||||||
|
|
||||||
|
David Nugent: it would be nice to be able to set debugging, log, and
|
||||||
|
statistics files on a site by site basis.
|
||||||
|
Brian Murrell: heck, set those files on a port by port basis as well.
|
||||||
|
|
||||||
|
74.
|
||||||
|
|
||||||
|
Yanek Martinson: allow each system to independently choose whether to
|
||||||
|
permit shell execution.
|
||||||
|
|
||||||
|
81.
|
||||||
|
|
||||||
|
Marty Shannon: log reason for dial failure (chat-fail string) in
|
||||||
|
.Status file.
|
||||||
|
|
||||||
|
83.
|
||||||
|
|
||||||
|
Switch between 'M' and 'S' correctly in the BNU log file output.
|
||||||
|
|
||||||
|
86.
|
||||||
|
|
||||||
|
Les Mikesell: allow a separate program to be specified to handle the
|
||||||
|
communications with a particular system.
|
||||||
|
|
||||||
|
105.
|
||||||
|
|
||||||
|
T. William Wells: close and open the Debug file after each file
|
||||||
|
transfer. Alternatively, cycle through a series of Debug file names
|
||||||
|
every 1000 lines or so.
|
||||||
|
|
||||||
|
106.
|
||||||
|
|
||||||
|
Marty Shannon: add a time command for ports, to specify when they may
|
||||||
|
be used.
|
||||||
|
|
||||||
|
115.
|
||||||
|
|
||||||
|
T. William Wells: new options for uustat:
|
||||||
|
-i display job ids only
|
||||||
|
Also, there should perhaps be a configuration option to request uustat
|
||||||
|
to only display jobs submitted by the user running uustat, except for
|
||||||
|
root and uucp.
|
||||||
|
|
||||||
|
117.
|
||||||
|
|
||||||
|
Marc Unangst: provide some way to change the debugging level of a
|
||||||
|
running uucico. T. William Wells suggests having it read a file to
|
||||||
|
change arbitrary configuration information, although obviously one has
|
||||||
|
to be careful of what gets changed while a connection is active.
|
||||||
|
|
||||||
|
120.
|
||||||
|
|
||||||
|
Jarmo Raiha: new chat-fail commands: one to not update the status file
|
||||||
|
and require a retry wait, and one to permit the string to occur a few
|
||||||
|
times before reporting an error.
|
||||||
|
|
||||||
|
124.
|
||||||
|
|
||||||
|
Peter da Silva: perhaps there should be a ``chat-end-program'' command
|
||||||
|
to let a program be run after the initial handshake has been completed
|
||||||
|
and the protocol has been selected and turned on. This would let
|
||||||
|
people run stty to change their terminal parameters.
|
||||||
|
|
||||||
|
128.
|
||||||
|
|
||||||
|
Richard Stallman: have an interactive program to set up a chat script.
|
||||||
|
It would let you type directly to the port, recording what you type as
|
||||||
|
send strings and recording what comes back from the other side as
|
||||||
|
expect strings.
|
||||||
|
|
||||||
|
129.
|
||||||
|
|
||||||
|
Use POSIX fcntl locks when possible instead of creating a lock file.
|
||||||
|
|
||||||
|
130.
|
||||||
|
|
||||||
|
Chip Salzenberg: BSD lets you override the timeout for a particular
|
||||||
|
expect string by using a trailing ~.
|
||||||
|
|
||||||
|
138.
|
||||||
|
|
||||||
|
T. William Wells: BNU apparently uses a file named A.whatever to hold
|
||||||
|
the line number reached in current C. file processing. This is a
|
||||||
|
hack, and won't work right with size control anyhow, but
|
||||||
|
fsysdep_did_work could, for example, clobber the first byte in the
|
||||||
|
line to a # or something to mark that it had been finished. Still a
|
||||||
|
hack, but a better one.
|
||||||
|
|
||||||
|
139.
|
||||||
|
|
||||||
|
Patrick Smith: incorporate patches to generate full debugging traces
|
||||||
|
with less debugging file overhead. The debugging file repeats too
|
||||||
|
much information at great length right now--not good.
|
||||||
|
|
||||||
|
141.
|
||||||
|
|
||||||
|
Franc,ois Pinard: batch up pauses and delays in chat scripts and do
|
||||||
|
them all at once in a single system call. This is particularly useful
|
||||||
|
for pauses on systems which don't support subsecond sleeps. For
|
||||||
|
everything else it's a fairly minor optimization.
|
||||||
|
|
||||||
|
142.
|
||||||
|
|
||||||
|
Franc,ois Pinard: give uustat an option to requeue jobs to another
|
||||||
|
system. This only makes a lot of sense for rmail executions, but it's
|
||||||
|
fairly easy to do for any type of command. I think uucico does all
|
||||||
|
the file checking needed to ensure that this doesn't break security,
|
||||||
|
but that should be double-checked.
|
||||||
|
|
||||||
|
144.
|
||||||
|
|
||||||
|
T. William Wells: add a -g option to uucico to permit specifying the
|
||||||
|
maximum grade to be transferred at that time. This could restrict the
|
||||||
|
timegrade command further, but should not be permitted to override it.
|
||||||
|
|
||||||
|
145.
|
||||||
|
|
||||||
|
T. William Wells: if uucico or uuxqt get started with bad arguments,
|
||||||
|
put an indication in the log file since stderr may be /dev/null.
|
||||||
|
|
||||||
|
146.
|
||||||
|
|
||||||
|
Richard Todd: it would be nice to sometimes be able to request the
|
||||||
|
other side to turn on debugging.
|
||||||
|
|
||||||
|
147.
|
||||||
|
|
||||||
|
Bart Schaefer: some more possible options for uucico:
|
||||||
|
-R reverse roles (hangup immediately). Not too exciting.
|
||||||
|
some method to restrict calling to particular systems.
|
||||||
|
|
||||||
|
148.
|
||||||
|
|
||||||
|
Jarmo Raiha: some method to control the work queue at the remote end.
|
||||||
|
This could get awfully general, though.
|
||||||
|
|
||||||
|
149.
|
||||||
|
|
||||||
|
The interaction of the time command and defaults can be confusing,
|
||||||
|
since any time command in the actual system entry, even a fairly
|
||||||
|
specific one, will wipe out the default entry. Not sure what can be
|
||||||
|
done about this.
|
||||||
|
|
||||||
|
150.
|
||||||
|
|
||||||
|
Jarmo Raiha: should there be some way to specify modem initialization
|
||||||
|
strings when uucico is hanging on a port with -l or -e? This would
|
||||||
|
presumably require a new type of chat script associated with a dialer.
|
||||||
|
|
||||||
|
151.
|
||||||
|
|
||||||
|
Petri Helenius: log complete CONNECT string reported by modem, so that
|
||||||
|
the baud rate is recorded in the log file.
|
||||||
|
|
||||||
|
152.
|
||||||
|
|
||||||
|
Marc Evans: let the protocol selection be based on the CONNECT string,
|
||||||
|
so that different protocols could be selected based on what type of
|
||||||
|
connection was made.
|
||||||
|
|
||||||
|
153.
|
||||||
|
|
||||||
|
Chris Lewis: provide a signal to get a core dump even on systems which
|
||||||
|
won't do core dumps if the uid is not the euid. One could catch a
|
||||||
|
signal, call setuid (getuid ()), and then raise the signal again.
|
||||||
|
Unfortunately the core dump has to wind up in a directory which is
|
||||||
|
world writable, so that the process is able to create the core file,
|
||||||
|
but is not world readable, since that would permit anybody to read the
|
||||||
|
core dump file and extract private information from it.
|
||||||
|
|
||||||
|
154.
|
||||||
|
|
||||||
|
Les Mikesell: write a new version of dial.o, with provisions for
|
||||||
|
running a chat script.
|
||||||
|
|
||||||
|
155.
|
||||||
|
|
||||||
|
Scott Blachowicz: perhaps there should be some way to telling uucico
|
||||||
|
to not log certain errors. This could get fairly complex, though.
|
||||||
|
|
||||||
|
156.
|
||||||
|
|
||||||
|
Franc,ois Pinard: have uustat -m report the time of the last
|
||||||
|
successful conversation when reporting a failure.
|
||||||
|
|
||||||
|
158.
|
||||||
|
|
||||||
|
Thomas Fischer: should there be a way to completely disable an entry
|
||||||
|
in the sys, port or dial file? Such as a ``disable'' command?
|
||||||
|
|
||||||
|
159.
|
||||||
|
|
||||||
|
Petri Helenius: when uuxqt -s is invoked, lock uuxqt for the system so
|
||||||
|
that only one uuxqt is invoked per system. If the -c option is used,
|
||||||
|
don't lock on a per system basis, and ignore any per system locks
|
||||||
|
(regardless of -s). If neither option is used, respect existing
|
||||||
|
system and command locks, and do any other type of file.
|
||||||
|
|
||||||
|
161.
|
||||||
|
|
||||||
|
Scott Blachowicz: provide some sort of include mechanism for the
|
||||||
|
configuration files.
|
||||||
|
|
||||||
|
162.
|
||||||
|
|
||||||
|
Chris Lewis: add uuxqtpolicy command, probably in config, supporting
|
||||||
|
the following values which determine when uuxqt should be run:
|
||||||
|
- never (let cron or something else worry about it)
|
||||||
|
- perinvocation (when uucico exits for good - current behaviour)
|
||||||
|
- persite (when uucico terminates a conversation - HDBish)
|
||||||
|
- periodic (per 5 or 10 incoming X. files - BSDish)
|
||||||
|
- perturnaround?
|
||||||
|
|
||||||
|
163.
|
||||||
|
|
||||||
|
Sort jobs in the send queue by size. Pretty easy.
|
||||||
|
|
||||||
|
164.
|
||||||
|
|
||||||
|
Ed Carp: preserve files if uuxqt execution fails.
|
||||||
|
|
||||||
|
165.
|
||||||
|
|
||||||
|
Marc Sheldon: use exit codes from <sysexits.h> in uux and uucp.
|
||||||
|
|
||||||
|
166.
|
||||||
|
|
||||||
|
Chip Salzenberg: allow chat failure strings to specify a retry time.
|
||||||
|
|
||||||
|
167.
|
||||||
|
|
||||||
|
Gregory Bond: allow a dialer sequence for a TCP port, so you can make
|
||||||
|
a TCP connection to a modem and then dial out.
|
||||||
|
|
||||||
|
168.
|
||||||
|
|
||||||
|
Jose A. Manas: allow a maximum connect time, after which we try to
|
||||||
|
hang up the connection. This requires a protocol extension, since
|
||||||
|
there's no way to force the other side to hang up. The best we can do
|
||||||
|
without an extension is refuse to send any new jobs ourselves. Of
|
||||||
|
course, we could just drop the connection.
|
||||||
|
|
||||||
|
169.
|
||||||
|
|
||||||
|
Franc,ois Pinard: when given uustat -k00FC, check each possible job ID
|
||||||
|
and use it if there is an unambiguous one.
|
||||||
|
|
||||||
|
170.
|
||||||
|
|
||||||
|
T. William Wells: if ! HAVE_SETREUID && ! HAVE_SAVED_SETUID, fork a
|
||||||
|
subprocesses to revoke setuid and read the file over a pipe.
|
||||||
|
|
||||||
|
171.
|
||||||
|
|
||||||
|
Provide some option to have the internal uuconf functions not start
|
||||||
|
with an underscore.
|
||||||
|
|
||||||
|
172.
|
||||||
|
|
||||||
|
T. William Wells: have some way to configure the parity for cu.
|
||||||
|
|
||||||
|
173.
|
||||||
|
|
||||||
|
Gert Doering: uuchk should display unknown system information.
|
||||||
|
|
||||||
|
175.
|
||||||
|
|
||||||
|
T. William Wells:
|
||||||
|
Cu will not let itself be interrupted before the connection is
|
||||||
|
established. If the chat script doesn't write something, cu does
|
||||||
|
something odd, I've forgotten exactly what. Cu takes an
|
||||||
|
inordinate amount of time after the line drops to exit. Somebody,
|
||||||
|
cu, I think, but maybe uucico, drops dtr twice sometimes. Again,
|
||||||
|
somebody will attempt to write after a hangup signal has been
|
||||||
|
received. Once a hangup has been received, I/O should not be
|
||||||
|
attempted. Among other things this will save the bacon of those
|
||||||
|
who have brain damaged serial drivers (FAS, sigh, is among them)
|
||||||
|
that don't handle output properly on a dropped line.
|
||||||
|
|
||||||
|
Me:
|
||||||
|
Note that sometimes you do want to write to a line after receiving a
|
||||||
|
hangup signal. For example, you might want to use ATZ to reset a
|
||||||
|
modem.
|
||||||
|
|
||||||
|
176.
|
||||||
|
|
||||||
|
Hans-Dieter Doll: provide some way (another escape sequence) to pass
|
||||||
|
the protocol to a chat-program. Or, allow the protocol as an argument
|
||||||
|
to the chat script command, which is more general, but maybe a bit too
|
||||||
|
fancy.
|
||||||
|
|
||||||
|
177.
|
||||||
|
|
||||||
|
Nickolay Saukh: use a default port for cu, you can just do ``cu
|
||||||
|
number''.
|
||||||
|
|
||||||
|
178.
|
||||||
|
|
||||||
|
Don Phillips: should there be some way to restrict of grade of
|
||||||
|
transfers even when the other system places the call?
|
||||||
|
|
||||||
|
179.
|
||||||
|
|
||||||
|
Nickolay Saukh: add something to chat scripts to specify the timeout
|
||||||
|
for an expect string, e.g. AT\c OK\W3 to wait for 3 seconds. Except
|
||||||
|
that perhaps the unit should not be seconds. Berkeley apparently uses
|
||||||
|
~number, not \W number, but I don't see any reason to prevent use of
|
||||||
|
the ~ character in an expect string.
|
||||||
|
|
||||||
|
180.
|
||||||
|
|
||||||
|
Nickolay Saukh: if we have received a partial file, request the remote
|
||||||
|
system to start sending from that point. We currently accept SVR4
|
||||||
|
style remote file positioning requests, but we do not generate them.
|
||||||
|
|
||||||
|
181.
|
||||||
|
|
||||||
|
Mark Powell: provide some way to restrict file transfer by size as
|
||||||
|
well as grade? One way would be to let uux select the grade based on
|
||||||
|
the file size.
|
||||||
|
|
||||||
|
182.
|
||||||
|
|
||||||
|
Mark Powell: permit using multiple timetables in a single time
|
||||||
|
statement.
|
||||||
|
|
||||||
|
183.
|
||||||
|
|
||||||
|
Optionally check for interrupts in fcopy_file, since it can take a
|
||||||
|
long time to copy a file named in a uucp request.
|
||||||
|
|
||||||
|
184.
|
||||||
|
|
||||||
|
Ian Moran: if an attempt is made to a copy a file to a directory which
|
||||||
|
denies write permission, perhaps the file should be saved somewhere.
|
||||||
|
It must be saved in a private location, though.
|
||||||
|
|
||||||
|
185.
|
||||||
|
|
||||||
|
A syntax error in a command received from the remote system should not
|
||||||
|
hold up the queue. Unfortunately, I don't know what can be done
|
||||||
|
except deny the command and report it. Reporting a garbled command
|
||||||
|
error should report the command correctly, rather than just the first
|
||||||
|
character.
|
||||||
|
|
||||||
|
186.
|
||||||
|
|
||||||
|
Franc,ois Pinard: have an option to control nostop vs. stop on the cu
|
||||||
|
command line.
|
||||||
|
|
||||||
|
187.
|
||||||
|
|
||||||
|
Fix the notion of %nostop to be SVID compatible.
|
||||||
|
|
||||||
|
188.
|
||||||
|
|
||||||
|
Frank Conrad: provide a means to set the strip mode for a port, to
|
||||||
|
make it easy to use it from cu.
|
||||||
|
|
||||||
|
189.
|
||||||
|
|
||||||
|
Marc Unangst: there should be a way to specify that a system should
|
||||||
|
only be called if there are jobs of a certain grade, but if the system
|
||||||
|
is called then jobs of any grade should be transferred. This
|
||||||
|
basically means splitting the ``timegrade'' command into two commands:
|
||||||
|
``place-call-timegrade'' and ``transfer-timegrade''. Or maybe another
|
||||||
|
optional argument to ``timegrade'':
|
||||||
|
timegrade grade time-string [retry] [transfer-any]
|
||||||
|
not to mention
|
||||||
|
time time-string [retry] [transfer-any]
|
||||||
|
Or maybe a separate command for a system or port like
|
||||||
|
transfer-any BOOL
|
||||||
|
|
||||||
|
190.
|
||||||
|
|
||||||
|
Chip Salzenberg: it would be really nice if uucico could automatically
|
||||||
|
figure out when it could use an E command, so that uux didn't have to
|
||||||
|
generate it and so that uucico could use with other versions of uux.
|
||||||
|
Unfortunately, it would require uucico to read the execution file to
|
||||||
|
see if it were suitable; this would be complex, but it would probably
|
||||||
|
be worth it since normally the execution file would wind up not being
|
||||||
|
sent. Of course, the current method works too; it's just harder to
|
||||||
|
combine with other versions of UUCP.
|
||||||
|
|
||||||
|
191.
|
||||||
|
|
||||||
|
Brian J. Murrell: should there be a way to cu a specific alternate?
|
||||||
|
|
||||||
|
192.
|
||||||
|
|
||||||
|
Andrew A. Chernov: Perhaps cu -pport system should be able to try
|
||||||
|
different alternates for the system, because there might be different
|
||||||
|
phone numbers to try.
|
||||||
|
|
||||||
|
193.
|
||||||
|
|
||||||
|
Brian J. Murrell: it would be nice to be able to ^C a cu chat script
|
||||||
|
if you know it's going to fail. Right now you have to use ^\.
|
||||||
|
|
||||||
|
194.
|
||||||
|
|
||||||
|
Steven S. Dick: have some way to force uucico off the phone at a
|
||||||
|
certain time. If that is done, it might be cool to have some way to
|
||||||
|
predict how long a file transfer will take, and not do it if it will
|
||||||
|
take too long. But, if doing file restart, you can just quit and then
|
||||||
|
pick it up later.
|
||||||
|
|
||||||
|
195.
|
||||||
|
|
||||||
|
Franc,ois Pinard: if the disk fills up, or some other error occurs,
|
||||||
|
while receiving a file, perhaps it would make sense to turn the
|
||||||
|
connection around immediately and see if the other side had anything
|
||||||
|
to do, and then try again later. This would require a protocol
|
||||||
|
extension. I don't know if it's worth it. The code should be checked
|
||||||
|
to see how well it handles a disk full situation.
|
||||||
|
|
||||||
|
196.
|
||||||
|
|
||||||
|
For real adjustability, provide some mechanism for picking the lead
|
||||||
|
characters to use for the shell scripts, between : and #!.
|
||||||
|
|
||||||
|
197.
|
||||||
|
|
||||||
|
Try alternate IP addresses if there are any.
|
||||||
|
|
||||||
|
198.
|
||||||
|
|
||||||
|
Lele Gaifax: mention the device in Stats, and provide some way to
|
||||||
|
associate the entry in Log with the entry in Stats.
|
||||||
|
|
||||||
|
199.
|
||||||
|
|
||||||
|
Michael Richardson: provide some way to turn on parity for the login
|
||||||
|
chat, since some systems apparently require it. Provide some way for
|
||||||
|
cu to control parity after connecting.
|
||||||
|
|
||||||
|
200.
|
||||||
|
|
||||||
|
Chip Salzenberg: add max-remote-debug to config.
|
||||||
|
|
||||||
|
201.
|
||||||
|
|
||||||
|
Gert Doering: change the timeout message in chat scripts to reflect
|
||||||
|
which chat script timed out (dialer or login).
|
||||||
|
|
||||||
|
202.
|
||||||
|
|
||||||
|
Bill Foote: have uuchk check whether a system is defined more than
|
||||||
|
once.
|
||||||
|
|
||||||
|
203.
|
4
gnu/libexec/uucp/VERSION
Normal file
4
gnu/libexec/uucp/VERSION
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
Version 1.04
|
||||||
|
|
||||||
|
a complete, unmodified version of this program is available from
|
||||||
|
prep.ai.mit.edu.
|
1429
gnu/libexec/uucp/common_sources/chat.c
Normal file
1429
gnu/libexec/uucp/common_sources/chat.c
Normal file
File diff suppressed because it is too large
Load Diff
444
gnu/libexec/uucp/common_sources/conf.h
Normal file
444
gnu/libexec/uucp/common_sources/conf.h
Normal file
@ -0,0 +1,444 @@
|
|||||||
|
/* conf.h. Generated automatically by configure. */
|
||||||
|
/* Configuration header file for Taylor UUCP. -*- C -*- */
|
||||||
|
|
||||||
|
/* Set MAIL_PROGRAM to a program which takes a mail address as an
|
||||||
|
argument and accepts a mail message to send to that address on
|
||||||
|
stdin (e.g. "/bin/mail"). */
|
||||||
|
#define MAIL_PROGRAM "/usr/bin/mail"
|
||||||
|
|
||||||
|
/* Set ECHO_PROGRAM to a program which echoes its arguments; if echo
|
||||||
|
is a shell builtin you can just use "echo". */
|
||||||
|
#define ECHO_PROGRAM "echo"
|
||||||
|
|
||||||
|
/* The following macros indicate what header files you have. Set the
|
||||||
|
macro to 1 if you have the corresponding header file, or 0 if you
|
||||||
|
do not. */
|
||||||
|
#define HAVE_STDDEF_H 1 /* <stddef.h> */
|
||||||
|
#define HAVE_STRING_H 1 /* <string.h> */
|
||||||
|
#define HAVE_STRINGS_H 1 /* <strings.h> */
|
||||||
|
#define HAVE_UNISTD_H 1 /* <unistd.h> */
|
||||||
|
#define HAVE_STDLIB_H 1 /* <stdlib.h> */
|
||||||
|
#define HAVE_LIMITS_H 1 /* <limits.h> */
|
||||||
|
#define HAVE_TIME_H 1 /* <time.h> */
|
||||||
|
#define HAVE_SYS_WAIT_H 1 /* <sys/wait.h> */
|
||||||
|
#define HAVE_SYS_IOCTL_H 1 /* <sys/ioctl.h> */
|
||||||
|
#define HAVE_DIRENT_H 1 /* <dirent.h> */
|
||||||
|
#define HAVE_MEMORY_H 1 /* <memory.h> */
|
||||||
|
#define HAVE_SYS_PARAM_H 1 /* <sys/param.h> */
|
||||||
|
#define HAVE_UTIME_H 1 /* <utime.h> */
|
||||||
|
#define HAVE_FCNTL_H 1 /* <fcntl.h> */
|
||||||
|
#define HAVE_SYS_FILE_H 1 /* <sys/file.h> */
|
||||||
|
#define HAVE_SYS_TIMES_H 1 /* <sys/times.h> */
|
||||||
|
#define HAVE_LIBC_H 0 /* <libc.h> */
|
||||||
|
#define HAVE_SYSEXITS_H 1 /* <sysexits.h> */
|
||||||
|
#define HAVE_POLL_H 0 /* <poll.h> */
|
||||||
|
#define HAVE_TIUSER_H 0 /* <tiuser.h> */
|
||||||
|
#define HAVE_XTI_H 0 /* <xti.h> */
|
||||||
|
#define HAVE_SYS_TLI_H 0 /* <sys/tli.h> */
|
||||||
|
#define HAVE_STROPTS_H 0 /* <stropts.h> */
|
||||||
|
#define HAVE_FTW_H 0 /* <ftw.h> */
|
||||||
|
#define HAVE_GLOB_H 1 /* <glob.h> */
|
||||||
|
#define HAVE_SYS_SELECT_H 0 /* <sys/select.h> */
|
||||||
|
#define HAVE_SYS_TYPES_TCP_H 0 /* <sys/types.tcp.h> */
|
||||||
|
|
||||||
|
/* If major and minor are not defined in <sys/types.h>, but are in
|
||||||
|
<sys/mkdev.h>, set MAJOR_IN_MKDEV to 1. If they are in
|
||||||
|
<sys/sysmacros.h>, set MAJOR_IN_SYSMACROS to 1. */
|
||||||
|
#define MAJOR_IN_MKDEV 0
|
||||||
|
#define MAJOR_IN_SYSMACROS 0
|
||||||
|
|
||||||
|
/* If the macro offsetof is not defined in <stddef.h>, you may give it
|
||||||
|
a definition here. If you do not, the code will use a definition
|
||||||
|
(in uucp.h) that should be fairly portable. */
|
||||||
|
/* #define offsetof */
|
||||||
|
|
||||||
|
/* Set RETSIGTYPE to the return type of a signal handler. On newer
|
||||||
|
systems this will be void; some older systems use int. */
|
||||||
|
#define RETSIGTYPE void
|
||||||
|
|
||||||
|
/* Set HAVE_SYS_TIME_AND_TIME_H to 1 if <time.h> and <sys/time.h> can both
|
||||||
|
be included in a single source file; if you don't have either or both of
|
||||||
|
them, it doesn't matter what you set this to. */
|
||||||
|
#define HAVE_SYS_TIME_AND_TIME_H 1
|
||||||
|
|
||||||
|
/* Set HAVE_TERMIOS_AND_SYS_IOCTL_H to 1 if <termios.h> and <sys/ioctl.h>
|
||||||
|
can both be included in a single source file; if you don't have either
|
||||||
|
or both of them, it doesn't matter what you set this to. */
|
||||||
|
#define HAVE_TERMIOS_AND_SYS_IOCTL_H 1
|
||||||
|
|
||||||
|
/* If you are configuring by hand, you should set one of the terminal
|
||||||
|
driver options in policy.h. If you are autoconfiguring, the script
|
||||||
|
will check whether your system defines CBREAK, which is a terminal
|
||||||
|
setting; if your system supports CBREAK, and you don't set a terminal
|
||||||
|
driver in policy.h, the code will assume that you have a BSD style
|
||||||
|
terminal driver. */
|
||||||
|
#define HAVE_CBREAK 1
|
||||||
|
|
||||||
|
/* The package needs several standard types. If you are using the
|
||||||
|
configure script, it will look in standard places for these types,
|
||||||
|
and give default definitions for them here if it doesn't find them.
|
||||||
|
The default definitions should work on most systems, but you may
|
||||||
|
want to check them. If you are configuring by hand, you will have
|
||||||
|
to figure out whether the types are defined on your system, and
|
||||||
|
what they should be defined to.
|
||||||
|
|
||||||
|
Any type that is not defined on your system should get a macro
|
||||||
|
definition. The definition should be of the name of the type in
|
||||||
|
all capital letters. For example, #define PID_T int. If the type
|
||||||
|
is defined in a standard header file, the macro name should not be
|
||||||
|
defined. */
|
||||||
|
|
||||||
|
/* The type pid_t is used to hold a process ID number. It is normally
|
||||||
|
defined in <sys/types.h>. This is the type returned by the
|
||||||
|
functions fork or getpid. Usually int will work fine. */
|
||||||
|
#undef PID_T
|
||||||
|
|
||||||
|
/* The type uid_t is used to hold a user ID number. It is normally
|
||||||
|
defined in <sys/types.h>. This is the type returned by the getuid
|
||||||
|
function. Usually int will work fine. */
|
||||||
|
#undef UID_T
|
||||||
|
|
||||||
|
/* The type gid_t is used to hold a group ID number. It is sometimes
|
||||||
|
defined in <sys/types.h>. This is the type returned by the getgid
|
||||||
|
function. Usually int will work fine. */
|
||||||
|
#undef GID_T
|
||||||
|
|
||||||
|
/* The type off_t is used to hold an offset in a file. It is sometimes
|
||||||
|
defined in <sys/types.h>. This is the type of the second argument to
|
||||||
|
the lseek function. Usually long will work fine. */
|
||||||
|
#undef OFF_T
|
||||||
|
|
||||||
|
/* Set HAVE_SIG_ATOMIC_T_IN_SIGNAL_H if the type sig_atomic_t is defined
|
||||||
|
in <signal.h> as required by ANSI C. */
|
||||||
|
#define HAVE_SIG_ATOMIC_T_IN_SIGNAL_H 1
|
||||||
|
|
||||||
|
/* Set HAVE_SIG_ATOMIC_T_IN_TYPES_H if the type sig_atomic_t is defined
|
||||||
|
in <sys/types.h>. This is ignored if HAVE_SIG_ATOMIC_T_IN_SIGNAL_H is
|
||||||
|
set to 1. */
|
||||||
|
#define HAVE_SIG_ATOMIC_T_IN_TYPES_H 0
|
||||||
|
|
||||||
|
/* The type sig_atomic_t is used to hold a value which may be
|
||||||
|
referenced in a single atomic operation. If it is not defined in
|
||||||
|
either <signal.h> or <sys/types.h>, you may want to give it a
|
||||||
|
definition here. If you don't, the code will use char. If your
|
||||||
|
compiler does not support sig_atomic_t, there is no type which is
|
||||||
|
really correct; fortunately, for this package it does not really
|
||||||
|
matter very much. */
|
||||||
|
#undef SIG_ATOMIC_T
|
||||||
|
|
||||||
|
/* Set HAVE_SIZE_T_IN_STDDEF_H to 1 if the type size_t is defined in
|
||||||
|
<stddef.h> as required by ANSI C. */
|
||||||
|
#define HAVE_SIZE_T_IN_STDDEF_H 1
|
||||||
|
|
||||||
|
/* Set HAVE_SIZE_T_IN_TYPES_H to 1 if the type size_t is defined in
|
||||||
|
<sys/types.h>. This is ignored if HAVE_SIZE_T_IN_STDDEF_H is set
|
||||||
|
to 1. */
|
||||||
|
#define HAVE_SIZE_T_IN_TYPES_H 1
|
||||||
|
|
||||||
|
/* The type size_t is used to hold the size of an object. In
|
||||||
|
particular, an argument of this type is passed as the size argument
|
||||||
|
to the malloc and realloc functions. If size_t is not defined in
|
||||||
|
either <stddef.h> or <sys/types.h>, you may want to give it a
|
||||||
|
definition here. If you don't, the code will use unsigned. */
|
||||||
|
#undef SIZE_T
|
||||||
|
|
||||||
|
/* Set HAVE_TIME_T_IN_TIME_H to 1 if the type time_t is defined in
|
||||||
|
<time.h>, as required by the ANSI C standard. */
|
||||||
|
#define HAVE_TIME_T_IN_TIME_H 1
|
||||||
|
|
||||||
|
/* Set HAVE_TIME_T_IN_TYPES_H to 1 if the type time_t is defined in
|
||||||
|
<sys/types.h>. This is ignored if HAVE_TIME_T_IN_TIME_H is set to
|
||||||
|
1. */
|
||||||
|
#define HAVE_TIME_T_IN_TYPES_H 1
|
||||||
|
|
||||||
|
/* When Taylor UUCP is talking to another instance of itself, it will
|
||||||
|
tell the other side the size of a file before it is transferred.
|
||||||
|
If the package can determine how much disk space is available, it
|
||||||
|
will use this information to avoid filling up the disk. Define one
|
||||||
|
of the following macros to tell the code how to determine the
|
||||||
|
amount of available disk space. It is possible that none of these
|
||||||
|
are appropriate; it will do no harm to use none of them, but, of
|
||||||
|
course, nothing will then prevent the package from filling up the
|
||||||
|
disk. Note that this space check is only useful when talking to
|
||||||
|
another instance of Taylor UUCP.
|
||||||
|
|
||||||
|
STAT_STATVFS statvfs function
|
||||||
|
STAT_STATFS2_BSIZE two argument statfs function with f_bsize field
|
||||||
|
STAT_STATFS2_FSIZE two argument statfs function with f_fsize field
|
||||||
|
STAT_STATFS2_FS_DATA two argument statfs function with fd_req field
|
||||||
|
STAT_STATFS4 four argument statfs function
|
||||||
|
STAT_USTAT the ustat function with 512 byte blocks. */
|
||||||
|
#define STAT_STATVFS 0
|
||||||
|
#define STAT_STATFS2_BSIZE 0
|
||||||
|
#define STAT_STATFS2_FSIZE 1
|
||||||
|
#define STAT_STATFS2_FS_DATA 0
|
||||||
|
#define STAT_STATFS4 0
|
||||||
|
#define STAT_USTAT 0
|
||||||
|
|
||||||
|
/* Set HAVE_VOID to 1 if the compiler supports declaring functions with
|
||||||
|
a return type of void and casting values to void. */
|
||||||
|
#define HAVE_VOID 1
|
||||||
|
|
||||||
|
/* Set HAVE_UNSIGNED_CHAR to 1 if the compiler supports the type unsigned
|
||||||
|
char. */
|
||||||
|
#define HAVE_UNSIGNED_CHAR 1
|
||||||
|
|
||||||
|
/* Set HAVE_ERRNO_DECLARATION to 1 if errno is declared in <errno.h>. */
|
||||||
|
#define HAVE_ERRNO_DECLARATION 1
|
||||||
|
|
||||||
|
/* There are now a number of functions to check for. For each of
|
||||||
|
these, the macro HAVE_FUNC should be set to 1 if your system has
|
||||||
|
FUNC. For example, HAVE_VFPRINTF should be set to 1 if your system
|
||||||
|
has vfprintf, 0 otherwise. */
|
||||||
|
|
||||||
|
/* Taylor UUCP will take advantage of the following functions if they
|
||||||
|
are available, but knows how to deal with their absence. */
|
||||||
|
#define HAVE_VFPRINTF 1
|
||||||
|
#define HAVE_FTRUNCATE 1
|
||||||
|
#define HAVE_LTRUNC 0
|
||||||
|
#define HAVE_WAITPID 1
|
||||||
|
#define HAVE_WAIT4 1
|
||||||
|
#define HAVE_GLOB 1
|
||||||
|
#define HAVE_SETREUID 1
|
||||||
|
|
||||||
|
/* There are several functions which are replaced in the subdirectory
|
||||||
|
lib. If they are missing, the configure script will automatically
|
||||||
|
add them to lib/Makefile to force them to be recompiled. If you
|
||||||
|
are configuring by hand, you will have to do this yourself. The
|
||||||
|
string @LIBOBJS@ in lib/Makefile.in should be replaced by a list of
|
||||||
|
object files in lib/Makefile. The following comments tell you
|
||||||
|
which object file names to add (they are generally fairly obvious,
|
||||||
|
given that the file names have no more than six characters before
|
||||||
|
the period). */
|
||||||
|
|
||||||
|
/* For each of these functions, if it does not exist, the indicated
|
||||||
|
object file should be added to lib/Makefile. */
|
||||||
|
#define HAVE_BSEARCH 1 /* bsrch.o */
|
||||||
|
#define HAVE_GETLINE 0 /* getlin.o */
|
||||||
|
#define HAVE_MEMCHR 1 /* memchr.o */
|
||||||
|
#define HAVE_STRDUP 1 /* strdup.o */
|
||||||
|
#define HAVE_STRSTR 1 /* strstr.o */
|
||||||
|
#define HAVE_STRTOL 1 /* strtol.o */
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add bzero.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_BZERO 1
|
||||||
|
#define HAVE_MEMSET 1
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add memcmp.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_MEMCMP 1
|
||||||
|
#define HAVE_BCMP 1
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add memcpy.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_MEMCPY 1
|
||||||
|
#define HAVE_BCOPY 1
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add strcas.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_STRCASECMP 1
|
||||||
|
#define HAVE_STRICMP 0
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add strncs.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_STRNCASECMP 1
|
||||||
|
#define HAVE_STRNICMP 0
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add strchr.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_STRCHR 1
|
||||||
|
#define HAVE_INDEX 1
|
||||||
|
|
||||||
|
/* If neither of these functions exists, you should add strrch.o to
|
||||||
|
lib/Makefile. */
|
||||||
|
#define HAVE_STRRCHR 1
|
||||||
|
#define HAVE_RINDEX 1
|
||||||
|
|
||||||
|
/* There are also Unix specific functions which are replaced in the
|
||||||
|
subdirectory unix. If they are missing, the configure script will
|
||||||
|
automatically add them to unix/Makefile to force them to be
|
||||||
|
recompiled. If you are configuring by hand, you will have to do
|
||||||
|
this yourself. The string @UNIXOBJS@ in unix/Makefile.in should be
|
||||||
|
replaced by a list of object files in unix/Makefile. The following
|
||||||
|
comments tell you which object file names to add. */
|
||||||
|
|
||||||
|
/* For each of these functions, if it does not exist, the indicated
|
||||||
|
object file should be added to unix/Makefile. */
|
||||||
|
#define HAVE_OPENDIR 1 /* dirent.o */
|
||||||
|
#define HAVE_DUP2 1 /* dup2.o */
|
||||||
|
#define HAVE_FTW 0 /* ftw.o */
|
||||||
|
#define HAVE_REMOVE 1 /* remove.o */
|
||||||
|
#define HAVE_RENAME 1 /* rename.o */
|
||||||
|
#define HAVE_STRERROR 1 /* strerr.o */
|
||||||
|
|
||||||
|
/* The code needs to know how to create directories. If you have the
|
||||||
|
mkdir function, set HAVE_MKDIR to 1 and replace @UUDIR@ in
|
||||||
|
Makefile.in with '# ' (the configure script will set @UUDIR@
|
||||||
|
according to the variable UUDIR). Otherwise, set HAVE_MKDIR to 0,
|
||||||
|
remove @UUDIR@ from Makefile.in, set MKDIR_PROGRAM to the name of
|
||||||
|
the program which will create a directory named on the command line
|
||||||
|
(e.g., "/bin/mkdir"), and add mkdir.o to the @UNIXOBJS@ string in
|
||||||
|
unix/Makefile.in. */
|
||||||
|
#define HAVE_MKDIR 1
|
||||||
|
#define MKDIR_PROGRAM unused
|
||||||
|
|
||||||
|
/* The code also needs to know how to remove directories. If you have
|
||||||
|
the rmdir function, set HAVE_RMDIR to 1. Otherwise, set
|
||||||
|
RMDIR_PROGRAM to the name of the program which will remove a
|
||||||
|
directory named on the command line (e.g., "/bin/rmdir") and add
|
||||||
|
rmdir.o to the @UNIXOBJS@ string in unix/Makefile.in. */
|
||||||
|
#define HAVE_RMDIR 1
|
||||||
|
#define RMDIR_PROGRAM unused
|
||||||
|
|
||||||
|
/* The code needs to know to how to get the name of the current
|
||||||
|
directory. If getcwd is available it will be used, otherwise if
|
||||||
|
getwd is available it will be used. Otherwise, set PWD_PROGRAM to
|
||||||
|
the name of the program which will print the name of the current
|
||||||
|
working directory (e.g., "/bin/pwd") and add getcwd.o to the
|
||||||
|
@UNIXOBJS@ string in unix/Makefile.in. */
|
||||||
|
#define HAVE_GETCWD 1
|
||||||
|
#define HAVE_GETWD 1
|
||||||
|
#define PWD_PROGRAM unused
|
||||||
|
|
||||||
|
/* If you have either sigsetjmp or setret, it will be used instead of
|
||||||
|
setjmp. These functions will only be used if your system restarts
|
||||||
|
system calls after interrupts (see HAVE_RESTARTABLE_SYSCALLS,
|
||||||
|
below). */
|
||||||
|
#define HAVE_SIGSETJMP 0
|
||||||
|
#define HAVE_SETRET 0
|
||||||
|
|
||||||
|
/* The code needs to know what function to use to set a signal
|
||||||
|
handler. If will try to use each of the following functions in
|
||||||
|
turn. If none are available, it will use signal, which is assumed
|
||||||
|
to always exist. */
|
||||||
|
#define HAVE_SIGACTION 1
|
||||||
|
#define HAVE_SIGVEC 1
|
||||||
|
#define HAVE_SIGSET 0
|
||||||
|
|
||||||
|
/* If the code is going to use sigvec (HAVE_SIGACTION is 0 and
|
||||||
|
HAVE_SIGVEC is 1), then HAVE_SIGVEC_SV_FLAGS must be set to 1 if
|
||||||
|
the sigvec structure contains the sv_flags field, or 0 if the
|
||||||
|
sigvec structure contains the sv_onstack field. If the code is not
|
||||||
|
going to use sigvec, it doesn't matter what this is set to. */
|
||||||
|
#define HAVE_SIGVEC_SV_FLAGS 1
|
||||||
|
|
||||||
|
/* The code will try to use each of the following functions in turn
|
||||||
|
when blocking signals from delivery. If none are available, a
|
||||||
|
relatively unimportant race condition will exist. */
|
||||||
|
#define HAVE_SIGPROCMASK 1
|
||||||
|
#define HAVE_SIGBLOCK 1
|
||||||
|
#define HAVE_SIGHOLD 0
|
||||||
|
|
||||||
|
/* If you have either of the following functions, it will be used to
|
||||||
|
determine the number of file descriptors which may be open.
|
||||||
|
Otherwise, the code will use OPEN_MAX if defined, then NOFILE if
|
||||||
|
defined, then 20. */
|
||||||
|
#define HAVE_GETDTABLESIZE 1
|
||||||
|
#define HAVE_SYSCONF 0
|
||||||
|
|
||||||
|
/* The code will use one of the following functions when detaching
|
||||||
|
from a terminal. One of these must exist. */
|
||||||
|
#define HAVE_SETPGRP 1
|
||||||
|
#define HAVE_SETSID 1
|
||||||
|
|
||||||
|
/* If you do not specify the local node name in the main configuration
|
||||||
|
file, Taylor UUCP will try to use each of the following functions
|
||||||
|
in turn. If neither is available, you must specify the local node
|
||||||
|
name in the configuration file. */
|
||||||
|
#define HAVE_GETHOSTNAME 1
|
||||||
|
#define HAVE_UNAME 0
|
||||||
|
|
||||||
|
/* The code will try to use each of the following functions in turn to
|
||||||
|
determine the current time. If none are available, it will use
|
||||||
|
time, which is assumed to always exist. */
|
||||||
|
#define HAVE_GETTIMEOFDAY 1
|
||||||
|
#define HAVE_FTIME 0
|
||||||
|
|
||||||
|
/* If neither gettimeofday nor ftime is available, the code will use
|
||||||
|
times (if available) to measure a span of time. See also the
|
||||||
|
discussion of TIMES_TICK in policy.h. */
|
||||||
|
#define HAVE_TIMES 1
|
||||||
|
|
||||||
|
/* When a chat script requests a pause of less than a second with \p,
|
||||||
|
Taylor UUCP will try to use each of the following functions in
|
||||||
|
turn. If none are available, it will sleep for a full second.
|
||||||
|
Also, the (non-portable) tstuu program requires either select or
|
||||||
|
poll. */
|
||||||
|
#define HAVE_NAPMS 0
|
||||||
|
#define HAVE_NAP 0
|
||||||
|
#define HAVE_USLEEP 1
|
||||||
|
#define HAVE_POLL 0
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* If the getgrent function is available, it will be used to determine
|
||||||
|
all the groups a user belongs to when checking file access
|
||||||
|
permissions. */
|
||||||
|
#define HAVE_GETGRENT 1
|
||||||
|
|
||||||
|
/* If the socket function is available, TCP support code will be
|
||||||
|
compiled in. */
|
||||||
|
#define HAVE_SOCKET 1
|
||||||
|
|
||||||
|
/* If the t_open function is available, TLI support code will be
|
||||||
|
compiled in. This may require adding a library, such as -lnsl or
|
||||||
|
-lxti, to the Makefile variables LIBS. */
|
||||||
|
#define HAVE_T_OPEN 0
|
||||||
|
|
||||||
|
/* That's the end of the list of the functions. Now there are a few
|
||||||
|
last miscellaneous items. */
|
||||||
|
|
||||||
|
/* On some systems the following functions are declared in such a way
|
||||||
|
that the code cannot make a simple extern. On other systems, these
|
||||||
|
functions are not declared at all, and the extern is required. If
|
||||||
|
a declaration of the function, as shown, compiles on your system,
|
||||||
|
set the value to 1. Not all functions declared externally are
|
||||||
|
listed here, only the ones with which I have had trouble. */
|
||||||
|
/* extern long times (); */
|
||||||
|
#define TIMES_DECLARATION_OK 0
|
||||||
|
/* extern struct passwd *getpwnam (); */
|
||||||
|
#define GETPWNAM_DECLARATION_OK 1
|
||||||
|
/* extern struct passwd *getpwuid (); */
|
||||||
|
#define GETPWUID_DECLARATION_OK 0
|
||||||
|
/* extern struct group *getgrent (); */
|
||||||
|
#define GETGRENT_DECLARATION_OK 1
|
||||||
|
|
||||||
|
/* Set HAVE_BSD_PGRP to 1 if your getpgrp call takes 1 argument and
|
||||||
|
your setpgrp calls takes 2 arguments (on System V they generally
|
||||||
|
take no arguments). You can safely set this to 1 on System V,
|
||||||
|
provided the call will compile without any errors. */
|
||||||
|
#define HAVE_BSD_PGRP 0
|
||||||
|
|
||||||
|
/* Set HAVE_UNION_WAIT to 1 if union wait is defined in the header
|
||||||
|
file <sys/wait.h>. */
|
||||||
|
#define HAVE_UNION_WAIT 1
|
||||||
|
|
||||||
|
/* Set HAVE_LONG_FILE_NAMES to 1 if the system supports file names
|
||||||
|
longer than 14 characters. */
|
||||||
|
#define HAVE_LONG_FILE_NAMES 1
|
||||||
|
|
||||||
|
/* If slow system calls are restarted after interrupts, set
|
||||||
|
HAVE_RESTARTABLE_SYSCALLS to 1. This is ignored if HAVE_SIGACTION
|
||||||
|
is 1 or if HAVE_SIGVEC is 1 and HAVE_SIGVEC_SV_FLAGS is 1 and
|
||||||
|
SV_INTERRUPT is defined in <signal.h>. In both of these cases
|
||||||
|
system calls can be prevented from restarting. */
|
||||||
|
#define HAVE_RESTARTABLE_SYSCALLS 1
|
||||||
|
|
||||||
|
/* Some systems supposedly need the following macros to be defined.
|
||||||
|
These are handled by the configure script (it will turn #undef into
|
||||||
|
#define when appropriate, which is why the peculiar #ifndef #undef
|
||||||
|
construction is used). If you are configuring by hand, you may add
|
||||||
|
appropriate definitions here, or just add them to CFLAGS when
|
||||||
|
running make. */
|
||||||
|
#ifndef _ALL_SOURCE
|
||||||
|
#undef _ALL_SOURCE
|
||||||
|
#endif
|
||||||
|
#ifndef _POSIX_SOURCE
|
||||||
|
#undef _POSIX_SOURCE
|
||||||
|
#endif
|
||||||
|
#ifndef _MINIX
|
||||||
|
#undef _MINIX
|
||||||
|
#endif
|
||||||
|
#ifndef _POSIX_1_SOURCE
|
||||||
|
#undef _POSIX_1_SOURCE
|
||||||
|
#endif
|
552
gnu/libexec/uucp/common_sources/conn.c
Normal file
552
gnu/libexec/uucp/common_sources/conn.c
Normal file
@ -0,0 +1,552 @@
|
|||||||
|
/* conn.c
|
||||||
|
Connection routines for the Taylor UUCP package.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char conn_rcsid[] = "$Id: conn.c,v 1.1 1993/08/04 19:30:39 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "conn.h"
|
||||||
|
|
||||||
|
static boolean fcdo_dial P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
const char *zphone, boolean ftranslate));
|
||||||
|
|
||||||
|
/* Create a new connection. This relies on system dependent functions
|
||||||
|
to set the qcmds and psysdep fields. If qport is NULL, it opens a
|
||||||
|
standard input port. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_init (qport, qconn)
|
||||||
|
struct uuconf_port *qport;
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
qconn->qport = qport;
|
||||||
|
switch (qport == NULL ? UUCONF_PORTTYPE_STDIN : qport->uuconf_ttype)
|
||||||
|
{
|
||||||
|
case UUCONF_PORTTYPE_STDIN:
|
||||||
|
return fsysdep_stdin_init (qconn);
|
||||||
|
case UUCONF_PORTTYPE_MODEM:
|
||||||
|
return fsysdep_modem_init (qconn);
|
||||||
|
case UUCONF_PORTTYPE_DIRECT:
|
||||||
|
return fsysdep_direct_init (qconn);
|
||||||
|
#if HAVE_TCP
|
||||||
|
case UUCONF_PORTTYPE_TCP:
|
||||||
|
return fsysdep_tcp_init (qconn);
|
||||||
|
#endif
|
||||||
|
#if HAVE_TLI
|
||||||
|
case UUCONF_PORTTYPE_TLI:
|
||||||
|
return fsysdep_tli_init (qconn);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
ulog (LOG_ERROR, "Unknown port type");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connection dispatch routines. */
|
||||||
|
|
||||||
|
/* Free a connection. */
|
||||||
|
|
||||||
|
void
|
||||||
|
uconn_free (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
(*qconn->qcmds->pufree) (qconn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lock a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_lock (qconn, fin)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
boolean fin;
|
||||||
|
{
|
||||||
|
boolean (*pflock) P((struct sconnection *, boolean));
|
||||||
|
|
||||||
|
pflock = qconn->qcmds->pflock;
|
||||||
|
if (pflock == NULL)
|
||||||
|
return TRUE;
|
||||||
|
return (*pflock) (qconn, fin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_unlock (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
boolean (*pfunlock) P((struct sconnection *));
|
||||||
|
|
||||||
|
pfunlock = qconn->qcmds->pfunlock;
|
||||||
|
if (pfunlock == NULL)
|
||||||
|
return TRUE;
|
||||||
|
return (*pfunlock) (qconn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_open (qconn, ibaud, ihighbaud, fwait)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
long ibaud;
|
||||||
|
long ihighbaud;
|
||||||
|
boolean fwait;
|
||||||
|
{
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (FDEBUGGING (DEBUG_PORT))
|
||||||
|
{
|
||||||
|
char abspeed[20];
|
||||||
|
|
||||||
|
if (ibaud == (long) 0)
|
||||||
|
strcpy (abspeed, "default speed");
|
||||||
|
else
|
||||||
|
sprintf (abspeed, "speed %ld", ibaud);
|
||||||
|
|
||||||
|
if (qconn->qport == NULL)
|
||||||
|
ulog (LOG_DEBUG, "fconn_open: Opening stdin port (%s)",
|
||||||
|
abspeed);
|
||||||
|
else if (qconn->qport->uuconf_zname == NULL)
|
||||||
|
ulog (LOG_DEBUG, "fconn_open: Opening unnamed port (%s)",
|
||||||
|
abspeed);
|
||||||
|
else
|
||||||
|
ulog (LOG_DEBUG, "fconn_open: Opening port %s (%s)",
|
||||||
|
qconn->qport->uuconf_zname, abspeed);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the system provides a range of baud rates, we select the
|
||||||
|
highest baud rate supported by the port. */
|
||||||
|
if (ihighbaud != 0 && qconn->qport != NULL)
|
||||||
|
{
|
||||||
|
struct uuconf_port *qport;
|
||||||
|
|
||||||
|
qport = qconn->qport;
|
||||||
|
ibaud = ihighbaud;
|
||||||
|
if (qport->uuconf_ttype == UUCONF_PORTTYPE_MODEM)
|
||||||
|
{
|
||||||
|
if (qport->uuconf_u.uuconf_smodem.uuconf_ilowbaud != 0)
|
||||||
|
{
|
||||||
|
if (qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud < ibaud)
|
||||||
|
ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ihighbaud;
|
||||||
|
}
|
||||||
|
else if (qport->uuconf_u.uuconf_smodem.uuconf_ibaud != 0)
|
||||||
|
ibaud = qport->uuconf_u.uuconf_smodem.uuconf_ibaud;
|
||||||
|
}
|
||||||
|
else if (qport->uuconf_ttype == UUCONF_PORTTYPE_DIRECT)
|
||||||
|
{
|
||||||
|
if (qport->uuconf_u.uuconf_sdirect.uuconf_ibaud != 0)
|
||||||
|
ibaud = qport->uuconf_u.uuconf_sdirect.uuconf_ibaud;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This will normally be overridden by the port specific open
|
||||||
|
routine. */
|
||||||
|
if (qconn->qport == NULL)
|
||||||
|
ulog_device ("stdin");
|
||||||
|
else
|
||||||
|
ulog_device (qconn->qport->uuconf_zname);
|
||||||
|
|
||||||
|
fret = (*qconn->qcmds->pfopen) (qconn, ibaud, fwait);
|
||||||
|
|
||||||
|
if (! fret)
|
||||||
|
ulog_device ((const char *) NULL);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_close (qconn, puuconf, qdialer, fsuccess)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
boolean fsuccess;
|
||||||
|
{
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_close: Closing connection");
|
||||||
|
|
||||||
|
/* Don't report hangup signals while we're closing. */
|
||||||
|
fLog_sighup = FALSE;
|
||||||
|
|
||||||
|
fret = (*qconn->qcmds->pfclose) (qconn, puuconf, qdialer, fsuccess);
|
||||||
|
|
||||||
|
/* Make sure any signal reporting has been done before we set
|
||||||
|
fLog_sighup back to TRUE. */
|
||||||
|
ulog (LOG_ERROR, (const char *) NULL);
|
||||||
|
fLog_sighup = TRUE;
|
||||||
|
|
||||||
|
ulog_device ((const char *) NULL);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_reset (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_reset: Resetting connection");
|
||||||
|
|
||||||
|
return (*qconn->qcmds->pfreset) (qconn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dial out on the connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zphone;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
enum tdialerfound *ptdialerfound;
|
||||||
|
{
|
||||||
|
struct uuconf_dialer sdialer;
|
||||||
|
enum tdialerfound tfound;
|
||||||
|
boolean (*pfdial) P((struct sconnection *, pointer,
|
||||||
|
const struct uuconf_system *, const char *,
|
||||||
|
struct uuconf_dialer *, enum tdialerfound *));
|
||||||
|
|
||||||
|
if (qdialer == NULL)
|
||||||
|
qdialer = &sdialer;
|
||||||
|
if (ptdialerfound == NULL)
|
||||||
|
ptdialerfound = &tfound;
|
||||||
|
|
||||||
|
qdialer->uuconf_zname = NULL;
|
||||||
|
*ptdialerfound = DIALERFOUND_FALSE;
|
||||||
|
|
||||||
|
pfdial = qconn->qcmds->pfdial;
|
||||||
|
if (pfdial == NULL)
|
||||||
|
return TRUE;
|
||||||
|
return (*pfdial) (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read data from the connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_read (qconn, zbuf, pclen, cmin, ctimeout, freport)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
char *zbuf;
|
||||||
|
size_t *pclen;
|
||||||
|
size_t cmin;
|
||||||
|
int ctimeout;
|
||||||
|
boolean freport;
|
||||||
|
{
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
fret = (*qconn->qcmds->pfread) (qconn, zbuf, pclen, cmin, ctimeout,
|
||||||
|
freport);
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (FDEBUGGING (DEBUG_INCOMING))
|
||||||
|
udebug_buffer ("fconn_read: Read", zbuf, *pclen);
|
||||||
|
else if (FDEBUGGING (DEBUG_PORT))
|
||||||
|
ulog (LOG_DEBUG, "fconn_read: Read %lu", (unsigned long) *pclen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write data to the connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_write (qconn, zbuf, clen)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
const char *zbuf;
|
||||||
|
size_t clen;
|
||||||
|
{
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (FDEBUGGING (DEBUG_OUTGOING))
|
||||||
|
udebug_buffer ("fconn_write: Writing", zbuf, clen);
|
||||||
|
else if (FDEBUGGING (DEBUG_PORT))
|
||||||
|
ulog (LOG_DEBUG, "fconn_write: Writing %lu", (unsigned long) clen);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (*qconn->qcmds->pfwrite) (qconn, zbuf, clen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read and write data. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_io (qconn, zwrite, pcwrite, zread, pcread)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
const char *zwrite;
|
||||||
|
size_t *pcwrite;
|
||||||
|
char *zread;
|
||||||
|
size_t *pcread;
|
||||||
|
{
|
||||||
|
boolean fret;
|
||||||
|
#if DEBUG > 1
|
||||||
|
size_t cwrite = *pcwrite;
|
||||||
|
size_t cread = *pcread;
|
||||||
|
|
||||||
|
if (cread == 0 || cwrite == 0)
|
||||||
|
ulog (LOG_FATAL, "fconn_io: cread %lu; cwrite %lu",
|
||||||
|
(unsigned long) cread, (unsigned long) cwrite);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (FDEBUGGING (DEBUG_OUTGOING))
|
||||||
|
udebug_buffer ("fconn_io: Writing", zwrite, cwrite);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fret = (*qconn->qcmds->pfio) (qconn, zwrite, pcwrite, zread, pcread);
|
||||||
|
|
||||||
|
DEBUG_MESSAGE4 (DEBUG_PORT,
|
||||||
|
"fconn_io: Wrote %lu of %lu, read %lu of %lu",
|
||||||
|
(unsigned long) *pcwrite, (unsigned long) cwrite,
|
||||||
|
(unsigned long) *pcread, (unsigned long) cread);
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (*pcread > 0 && FDEBUGGING (DEBUG_INCOMING))
|
||||||
|
udebug_buffer ("fconn_io: Read", zread, *pcread);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a break character to a connection. Some port types may not
|
||||||
|
support break characters, in which case we just return TRUE. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_break (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
boolean (*pfbreak) P((struct sconnection *));
|
||||||
|
|
||||||
|
pfbreak = *qconn->qcmds->pfbreak;
|
||||||
|
if (pfbreak == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT, "fconn_break: Sending break character");
|
||||||
|
|
||||||
|
return (*pfbreak) (qconn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change the setting of a connection. Some port types may not
|
||||||
|
support this, in which case we just return TRUE. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_set (qconn, tparity, tstrip, txonxoff)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
enum tparitysetting tparity;
|
||||||
|
enum tstripsetting tstrip;
|
||||||
|
enum txonxoffsetting txonxoff;
|
||||||
|
{
|
||||||
|
boolean (*pfset) P((struct sconnection *, enum tparitysetting,
|
||||||
|
enum tstripsetting, enum txonxoffsetting));
|
||||||
|
|
||||||
|
pfset = qconn->qcmds->pfset;
|
||||||
|
if (pfset == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE3 (DEBUG_PORT,
|
||||||
|
"fconn_set: Changing setting to %d, %d, %d",
|
||||||
|
(int) tparity, (int) tstrip, (int) txonxoff);
|
||||||
|
|
||||||
|
return (*pfset) (qconn, tparity, tstrip, txonxoff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Require or ignore carrier on a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_carrier (qconn, fcarrier)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
boolean fcarrier;
|
||||||
|
{
|
||||||
|
boolean (*pfcarrier) P((struct sconnection *, boolean));
|
||||||
|
|
||||||
|
pfcarrier = qconn->qcmds->pfcarrier;
|
||||||
|
if (pfcarrier == NULL)
|
||||||
|
return TRUE;
|
||||||
|
return (*pfcarrier) (qconn, fcarrier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run a chat program on a connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fconn_run_chat (qconn, pzprog)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
char **pzprog;
|
||||||
|
{
|
||||||
|
return (*qconn->qcmds->pfchat) (qconn, pzprog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the baud rate of a connection. */
|
||||||
|
|
||||||
|
long
|
||||||
|
iconn_baud (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
long (*pibaud) P((struct sconnection *));
|
||||||
|
|
||||||
|
pibaud = qconn->qcmds->pibaud;
|
||||||
|
if (pibaud == NULL)
|
||||||
|
return 0;
|
||||||
|
return (*pibaud) (qconn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modem dialing routines. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fmodem_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zphone;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
enum tdialerfound *ptdialerfound;
|
||||||
|
{
|
||||||
|
*ptdialerfound = DIALERFOUND_FALSE;
|
||||||
|
|
||||||
|
if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer != NULL)
|
||||||
|
{
|
||||||
|
char **pz;
|
||||||
|
boolean ffirst;
|
||||||
|
|
||||||
|
/* The pzdialer field is a sequence of dialer/token pairs. The
|
||||||
|
dialer portion names a dialer to use. The token portion is
|
||||||
|
what \D and \T in the chat script expand to. If there is no
|
||||||
|
token for the last dialer, the phone number for the system is
|
||||||
|
used. */
|
||||||
|
ffirst = TRUE;
|
||||||
|
pz = qconn->qport->uuconf_u.uuconf_smodem.uuconf_pzdialer;
|
||||||
|
while (*pz != NULL)
|
||||||
|
{
|
||||||
|
int iuuconf;
|
||||||
|
struct uuconf_dialer *q;
|
||||||
|
struct uuconf_dialer s;
|
||||||
|
const char *ztoken;
|
||||||
|
boolean ftranslate;
|
||||||
|
|
||||||
|
if (! ffirst)
|
||||||
|
q = &s;
|
||||||
|
else
|
||||||
|
q = qdialer;
|
||||||
|
|
||||||
|
iuuconf = uuconf_dialer_info (puuconf, *pz, q);
|
||||||
|
if (iuuconf == UUCONF_NOT_FOUND)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: Dialer not found", *pz);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
{
|
||||||
|
ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
++pz;
|
||||||
|
ztoken = *pz;
|
||||||
|
|
||||||
|
ftranslate = FALSE;
|
||||||
|
if (ztoken == NULL
|
||||||
|
|| strcmp (ztoken, "\\D") == 0)
|
||||||
|
ztoken = zphone;
|
||||||
|
else if (strcmp (ztoken, "\\T") == 0)
|
||||||
|
{
|
||||||
|
ztoken = zphone;
|
||||||
|
ftranslate = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! fcdo_dial (qconn, puuconf, q, ztoken, ftranslate))
|
||||||
|
{
|
||||||
|
(void) uuconf_dialer_free (puuconf, q);
|
||||||
|
if (! ffirst)
|
||||||
|
(void) uuconf_dialer_free (puuconf, qdialer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffirst)
|
||||||
|
{
|
||||||
|
*ptdialerfound = DIALERFOUND_FREE;
|
||||||
|
ffirst = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(void) uuconf_dialer_free (puuconf, q);
|
||||||
|
|
||||||
|
if (*pz != NULL)
|
||||||
|
++pz;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer != NULL)
|
||||||
|
{
|
||||||
|
struct uuconf_dialer *q;
|
||||||
|
|
||||||
|
q = qconn->qport->uuconf_u.uuconf_smodem.uuconf_qdialer;
|
||||||
|
*qdialer = *q;
|
||||||
|
*ptdialerfound = DIALERFOUND_TRUE;
|
||||||
|
return fcdo_dial (qconn, puuconf, q, zphone, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "No dialer information");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Actually use a dialer. We set up the modem (which may include
|
||||||
|
opening the dialer device), run the chat script, and finish dealing
|
||||||
|
with the modem. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
fcdo_dial (qconn, puuconf, qdial, zphone, ftranslate)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
struct uuconf_dialer *qdial;
|
||||||
|
const char *zphone;
|
||||||
|
boolean ftranslate;
|
||||||
|
{
|
||||||
|
const char *zname;
|
||||||
|
|
||||||
|
if (! fsysdep_modem_begin_dial (qconn, qdial))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (qconn->qport == NULL)
|
||||||
|
zname = NULL;
|
||||||
|
else
|
||||||
|
zname = qconn->qport->uuconf_zname;
|
||||||
|
|
||||||
|
if (! fchat (qconn, puuconf, &qdial->uuconf_schat,
|
||||||
|
(const struct uuconf_system *) NULL, qdial,
|
||||||
|
zphone, ftranslate, zname, iconn_baud (qconn)))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return fsysdep_modem_end_dial (qconn, qdial);
|
||||||
|
}
|
312
gnu/libexec/uucp/common_sources/conn.h
Normal file
312
gnu/libexec/uucp/common_sources/conn.h
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
/* conn.h
|
||||||
|
Header file for routines which manipulate connections.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONN_H
|
||||||
|
|
||||||
|
#define CONN_H
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
/* These structures are used in prototypes but are not defined in this
|
||||||
|
header file. */
|
||||||
|
struct uuconf_system;
|
||||||
|
struct uuconf_dialer;
|
||||||
|
struct uuconf_chat;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This structure represents a connection. */
|
||||||
|
|
||||||
|
struct sconnection
|
||||||
|
{
|
||||||
|
/* Pointer to command table for this type of connection. */
|
||||||
|
const struct sconncmds *qcmds;
|
||||||
|
/* Pointer to system dependent information. */
|
||||||
|
pointer psysdep;
|
||||||
|
/* Pointer to system independent information. */
|
||||||
|
struct uuconf_port *qport;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Whether fconn_dial got a dialer. */
|
||||||
|
|
||||||
|
enum tdialerfound
|
||||||
|
{
|
||||||
|
/* Did not find a dialer. */
|
||||||
|
DIALERFOUND_FALSE,
|
||||||
|
/* Found a dialer which does not need to be freed. */
|
||||||
|
DIALERFOUND_TRUE,
|
||||||
|
/* Found a dialer which does need to be freed. */
|
||||||
|
DIALERFOUND_FREE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Parity settings to pass to fconn_set. */
|
||||||
|
|
||||||
|
enum tparitysetting
|
||||||
|
{
|
||||||
|
/* Do not change output parity generation. */
|
||||||
|
PARITYSETTING_DEFAULT,
|
||||||
|
/* No parity (all eight output bits used). */
|
||||||
|
PARITYSETTING_NONE,
|
||||||
|
/* Even parity. */
|
||||||
|
PARITYSETTING_EVEN,
|
||||||
|
/* Odd parity. */
|
||||||
|
PARITYSETTING_ODD,
|
||||||
|
/* Mark parity. */
|
||||||
|
PARITYSETTING_MARK,
|
||||||
|
/* Space parity. */
|
||||||
|
PARITYSETTING_SPACE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type of strip control argument to fconn_set. */
|
||||||
|
|
||||||
|
enum tstripsetting
|
||||||
|
{
|
||||||
|
/* Do not change the stripping of input characters. */
|
||||||
|
STRIPSETTING_DEFAULT,
|
||||||
|
/* Do not strip input characters to seven bits. */
|
||||||
|
STRIPSETTING_EIGHTBITS,
|
||||||
|
/* Strip input characters to seven bits. */
|
||||||
|
STRIPSETTING_SEVENBITS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type of XON/XOFF control argument to fconn_set. */
|
||||||
|
|
||||||
|
enum txonxoffsetting
|
||||||
|
{
|
||||||
|
/* Do not change XON/XOFF handshake setting. */
|
||||||
|
XONXOFF_DEFAULT,
|
||||||
|
/* Do not do XON/XOFF handshaking. */
|
||||||
|
XONXOFF_OFF,
|
||||||
|
/* Do XON/XOFF handshaking. */
|
||||||
|
XONXOFF_ON
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A command table holds the functions which implement actions for
|
||||||
|
each different kind of connection. */
|
||||||
|
|
||||||
|
struct sconncmds
|
||||||
|
{
|
||||||
|
/* Free up a connection. */
|
||||||
|
void (*pufree) P((struct sconnection *qconn));
|
||||||
|
/* Lock the connection. The fin argument is TRUE if the connection
|
||||||
|
is to be used for an incoming call. May be NULL. */
|
||||||
|
boolean (*pflock) P((struct sconnection *qconn, boolean fin));
|
||||||
|
/* Unlock the connection. May be NULL. */
|
||||||
|
boolean (*pfunlock) P((struct sconnection *qconn));
|
||||||
|
/* Open the connection. */
|
||||||
|
boolean (*pfopen) P((struct sconnection *qconn, long ibaud,
|
||||||
|
boolean fwait));
|
||||||
|
/* Close the connection. */
|
||||||
|
boolean (*pfclose) P((struct sconnection *qconn,
|
||||||
|
pointer puuconf,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
boolean fsuccess));
|
||||||
|
/* Reset the connection so that another call may be accepted. */
|
||||||
|
boolean (*pfreset) P((struct sconnection *qconn));
|
||||||
|
/* Dial a number on a connection. This set *qdialer to the dialer
|
||||||
|
used, if any, and sets *ptdialerfound appropriately. The qsys
|
||||||
|
and zphone arguments are for the chat script. This field may be
|
||||||
|
NULL. */
|
||||||
|
boolean (*pfdial) P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const char *zphone,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
enum tdialerfound *ptdialerfound));
|
||||||
|
/* Read data from a connection, with a timeout in seconds. When
|
||||||
|
called *pclen is the length of the buffer; on successful return
|
||||||
|
*pclen is the number of bytes read into the buffer. The cmin
|
||||||
|
argument is the minimum number of bytes to read before returning
|
||||||
|
ahead of a timeout. */
|
||||||
|
boolean (*pfread) P((struct sconnection *qconn, char *zbuf, size_t *pclen,
|
||||||
|
size_t cmin, int ctimeout, boolean freport));
|
||||||
|
/* Write data to the connection. */
|
||||||
|
boolean (*pfwrite) P((struct sconnection *qconn, const char *zbuf,
|
||||||
|
size_t clen));
|
||||||
|
/* Read and write data to the connection. This reads and writes
|
||||||
|
data until either all passed in data has been written or the read
|
||||||
|
buffer has been filled. When called *pcread is the size of the
|
||||||
|
read buffer and *pcwrite is the number of bytes to write; on
|
||||||
|
successful return *pcread is the number of bytes read and
|
||||||
|
*pcwrite is the number of bytes written. */
|
||||||
|
boolean (*pfio) P((struct sconnection *qconn, const char *zwrite,
|
||||||
|
size_t *pcwrite, char *zread, size_t *pcread));
|
||||||
|
/* Send a break character. This field may be NULL. */
|
||||||
|
boolean (*pfbreak) P((struct sconnection *qconn));
|
||||||
|
/* Change the connection setting. This field may be NULL. */
|
||||||
|
boolean (*pfset) P((struct sconnection *qconn,
|
||||||
|
enum tparitysetting tparity,
|
||||||
|
enum tstripsetting tstrip,
|
||||||
|
enum txonxoffsetting txonxoff));
|
||||||
|
/* Require or ignore carrer. This field may be NULL. */
|
||||||
|
boolean (*pfcarrier) P((struct sconnection *qconn,
|
||||||
|
boolean fcarrier));
|
||||||
|
/* Run a chat program on a connection. */
|
||||||
|
boolean (*pfchat) P((struct sconnection *qconn, char **pzprog));
|
||||||
|
/* Get the baud rate of a connection. This field may be NULL. */
|
||||||
|
long (*pibaud) P((struct sconnection *qconn));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Connection functions. */
|
||||||
|
|
||||||
|
/* Initialize a connection. This must be called before any of the
|
||||||
|
other connection functions are called. It initializes the fields
|
||||||
|
of qconn. It returns FALSE on error. */
|
||||||
|
extern boolean fconn_init P((struct uuconf_port *qport,
|
||||||
|
struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Free up connection data. */
|
||||||
|
extern void uconn_free P((struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Lock a connection. The fin argument is TRUE if the port is to be
|
||||||
|
used for an incoming call; certains type of Unix locking need this
|
||||||
|
information because they need to open the port. */
|
||||||
|
extern boolean fconn_lock P((struct sconnection *qconn, boolean fin));
|
||||||
|
|
||||||
|
/* Unlock a connection. */
|
||||||
|
extern boolean fconn_unlock P((struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Open a connection. If ibaud is 0, the natural baud rate of the
|
||||||
|
port is used. If ihighbaud is not 0, fconn_open chooses the
|
||||||
|
highest supported baud rate between ibaud and ihighbaud. If fwait
|
||||||
|
is TRUE, this should wait for an incoming call. */
|
||||||
|
extern boolean fconn_open P((struct sconnection *qconn, long ibaud,
|
||||||
|
long ihighbaud, boolean fwait));
|
||||||
|
|
||||||
|
/* Close a connection. The fsuccess argument is TRUE if the
|
||||||
|
conversation completed normally, FALSE if it is being aborted. */
|
||||||
|
extern boolean fconn_close P((struct sconnection *qconn,
|
||||||
|
pointer puuconf,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
boolean fsuccess));
|
||||||
|
|
||||||
|
/* Reset a connection such that another call may be accepted. */
|
||||||
|
extern boolean fconn_reset P((struct sconnection *q));
|
||||||
|
|
||||||
|
/* Dial out on a connection. The qsys and zphone arguments are for
|
||||||
|
the chat scripts; zphone is the phone number to dial. If qdialer
|
||||||
|
is not NULL, *qdialer will be set to the dialer information used if
|
||||||
|
any; *ptdialerfound will be set appropriately. */
|
||||||
|
extern boolean fconn_dial P((struct sconnection *q, pointer puuconf,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const char *zphone,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
enum tdialerfound *ptdialerfound));
|
||||||
|
|
||||||
|
/* Read from a connection.
|
||||||
|
zbuf -- buffer to read bytes into
|
||||||
|
*pclen on call -- length of zbuf
|
||||||
|
*pclen on successful return -- number of bytes read
|
||||||
|
cmin -- minimum number of bytes to read before returning ahead of timeout
|
||||||
|
ctimeout -- timeout in seconds, 0 if none
|
||||||
|
freport -- whether to report errors. */
|
||||||
|
extern boolean fconn_read P((struct sconnection *qconn, char *zbuf,
|
||||||
|
size_t *pclen, size_t cmin,
|
||||||
|
int ctimeout, boolean freport));
|
||||||
|
|
||||||
|
/* Write to a connection. */
|
||||||
|
extern boolean fconn_write P((struct sconnection *qconn, const char *zbuf,
|
||||||
|
size_t cbytes));
|
||||||
|
|
||||||
|
/* Read and write to a connection. This reads and writes data until
|
||||||
|
either all passed-in data has been written or the read buffer is
|
||||||
|
full.
|
||||||
|
zwrite -- buffer to write bytes from
|
||||||
|
*pcwrite on call -- number of bytes to write
|
||||||
|
*pcwrite on successful return -- number of bytes written
|
||||||
|
zread -- buffer to read bytes into
|
||||||
|
*pcread on call -- size of read buffer
|
||||||
|
*pcread on successful return -- number of bytes read. */
|
||||||
|
extern boolean fconn_io P((struct sconnection *qconn, const char *zwrite,
|
||||||
|
size_t *pcwrite, char *zread, size_t *pcread));
|
||||||
|
|
||||||
|
/* Send a break character to a connection. */
|
||||||
|
extern boolean fconn_break P((struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Change the settings of a connection. This allows independent
|
||||||
|
control over the parity of output characters, whether to strip
|
||||||
|
input characters, and whether to do XON/XOFF handshaking. There is
|
||||||
|
no explicit control over parity checking of input characters. This
|
||||||
|
function returns FALSE on error. Attempts to set values not
|
||||||
|
supported by the hardware are silently ignored. */
|
||||||
|
extern boolean fconn_set P((struct sconnection *qconn,
|
||||||
|
enum tparitysetting tparity,
|
||||||
|
enum tstripsetting tstrip,
|
||||||
|
enum txonxoffsetting txonxoff));
|
||||||
|
|
||||||
|
/* Get the baud rate of a connection. */
|
||||||
|
extern long iconn_baud P((struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Do a chat script with a system. */
|
||||||
|
extern boolean fchat P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
const struct uuconf_chat *qchat,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const struct uuconf_dialer *qdialer,
|
||||||
|
const char *zphone, boolean ftranslate,
|
||||||
|
const char *zport, long ibaud));
|
||||||
|
|
||||||
|
/* Tell the connection to either require or ignore carrier as fcarrier
|
||||||
|
is TRUE or FALSE respectively. This is called with fcarrier TRUE
|
||||||
|
when \m is encountered in a chat script, and with fcarrier FALSE
|
||||||
|
when \M is encountered. */
|
||||||
|
extern boolean fconn_carrier P((struct sconnection *qconn,
|
||||||
|
boolean fcarrier));
|
||||||
|
|
||||||
|
/* Run a chat program on a connection. */
|
||||||
|
extern boolean fconn_run_chat P((struct sconnection *qconn,
|
||||||
|
char **pzprog));
|
||||||
|
|
||||||
|
/* Dialing out on a modem is partially system independent. This is
|
||||||
|
the modem dialing routine. */
|
||||||
|
extern boolean fmodem_dial P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const char *zphone,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
enum tdialerfound *ptdialerfound));
|
||||||
|
|
||||||
|
/* Begin dialing out. This should open the dialer device if there is
|
||||||
|
one, toggle DTR if requested and possible, and tell the port to
|
||||||
|
ignore carrier. It should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_modem_begin_dial P((struct sconnection *qconn,
|
||||||
|
struct uuconf_dialer *qdial));
|
||||||
|
|
||||||
|
/* Finish dialing out on a modem. This should close the dialer device
|
||||||
|
if there is one. If the dialer and the port both support carrier,
|
||||||
|
the connection should be told to pay attention to carrier. If it
|
||||||
|
is possible to wait for carrier to come on, and the dialer and the
|
||||||
|
port both the port support carrier, it should wait until carrier
|
||||||
|
comes on. */
|
||||||
|
extern boolean fsysdep_modem_end_dial P((struct sconnection *qconn,
|
||||||
|
struct uuconf_dialer *qdial));
|
||||||
|
|
||||||
|
/* System dependent initialization routines. */
|
||||||
|
extern boolean fsysdep_stdin_init P((struct sconnection *qconn));
|
||||||
|
extern boolean fsysdep_modem_init P((struct sconnection *qconn));
|
||||||
|
extern boolean fsysdep_direct_init P((struct sconnection *qconn));
|
||||||
|
#if HAVE_TCP
|
||||||
|
extern boolean fsysdep_tcp_init P((struct sconnection *qconn));
|
||||||
|
#endif
|
||||||
|
#if HAVE_TLI
|
||||||
|
extern boolean fsysdep_tli_init P((struct sconnection *qconn));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! defined (CONN_H) */
|
202
gnu/libexec/uucp/common_sources/copy.c
Normal file
202
gnu/libexec/uucp/common_sources/copy.c
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
/* copy.c
|
||||||
|
Copy one file to another for the UUCP package.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char copy_rcsid[] = "$Id: copy.c,v 1.1 1993/08/04 19:30:44 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Copy one file to another. */
|
||||||
|
|
||||||
|
#if USE_STDIO
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fcopy_file (zfrom, zto, fpublic, fmkdirs)
|
||||||
|
const char *zfrom;
|
||||||
|
const char *zto;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fmkdirs;
|
||||||
|
{
|
||||||
|
FILE *efrom;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
efrom = fopen (zfrom, BINREAD);
|
||||||
|
if (efrom == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fopen (%s): %s", zfrom, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fret = fcopy_open_file (efrom, zto, fpublic, fmkdirs);
|
||||||
|
(void) fclose (efrom);
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fcopy_open_file (efrom, zto, fpublic, fmkdirs)
|
||||||
|
FILE *efrom;
|
||||||
|
const char *zto;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fmkdirs;
|
||||||
|
{
|
||||||
|
FILE *eto;
|
||||||
|
char ab[8192];
|
||||||
|
int c;
|
||||||
|
|
||||||
|
eto = esysdep_fopen (zto, fpublic, FALSE, fmkdirs);
|
||||||
|
if (eto == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
while ((c = fread (ab, sizeof (char), sizeof ab, efrom)) != 0)
|
||||||
|
{
|
||||||
|
if (fwrite (ab, sizeof (char), (size_t) c, eto) != c)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fwrite: %s", strerror (errno));
|
||||||
|
(void) fclose (eto);
|
||||||
|
(void) remove (zto);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fclose (eto) != 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fclose: %s", strerror (errno));
|
||||||
|
(void) remove (zto);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! USE_STDIO */
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fcopy_file (zfrom, zto, fpublic, fmkdirs)
|
||||||
|
const char *zfrom;
|
||||||
|
const char *zto;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fmkdirs;
|
||||||
|
{
|
||||||
|
int ofrom;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
ofrom = open (zfrom, O_RDONLY | O_NOCTTY, 0);
|
||||||
|
if (ofrom < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "open (%s): %s", zfrom, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fret = fcopy_open_file (ofrom, zto, fpublic, fmkdirs);
|
||||||
|
(void) close (ofrom);
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fcopy_open_file (ofrom, zto, fpublic, fmkdirs)
|
||||||
|
int ofrom;
|
||||||
|
const char *zto;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fmkdirs;
|
||||||
|
{
|
||||||
|
int oto;
|
||||||
|
char ab[8192];
|
||||||
|
int c;
|
||||||
|
|
||||||
|
/* These file mode arguments are from the UNIX version of sysdep.h;
|
||||||
|
each system dependent header file will need their own
|
||||||
|
definitions. */
|
||||||
|
oto = creat (zto, fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE);
|
||||||
|
if (oto < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT && fmkdirs)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zto, fpublic))
|
||||||
|
return FALSE;
|
||||||
|
oto = creat (zto,
|
||||||
|
fpublic ? IPUBLIC_FILE_MODE : IPRIVATE_FILE_MODE);
|
||||||
|
}
|
||||||
|
if (oto < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "open (%s): %s", zto, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((c = read (ofrom, ab, sizeof ab)) > 0)
|
||||||
|
{
|
||||||
|
if (write (oto, ab, (size_t) c) != c)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "write: %s", strerror (errno));
|
||||||
|
(void) close (oto);
|
||||||
|
(void) remove (zto);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close (oto) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "close: %s", strerror (errno));
|
||||||
|
(void) remove (zto);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "read: %s", strerror (errno));
|
||||||
|
(void) remove (zto);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! USE_STDIO */
|
80
gnu/libexec/uucp/common_sources/cu.h
Normal file
80
gnu/libexec/uucp/common_sources/cu.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* cu.h
|
||||||
|
Header file for cu.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The user settable variables supported by cu. */
|
||||||
|
|
||||||
|
/* The escape character used to introduce a special command. The
|
||||||
|
escape character is the first character of this string. */
|
||||||
|
extern const char *zCuvar_escape;
|
||||||
|
|
||||||
|
/* Whether to delay for a second before printing the host name after
|
||||||
|
seeing an escape character. */
|
||||||
|
extern boolean fCuvar_delay;
|
||||||
|
|
||||||
|
/* The input characters which finish a line. The escape character is
|
||||||
|
only recognized following one of these characters. */
|
||||||
|
extern const char *zCuvar_eol;
|
||||||
|
|
||||||
|
/* Whether to transfer binary data (nonprintable characters other than
|
||||||
|
newline and tab) when sending a file. If this is FALSE, then
|
||||||
|
newline is changed to carriage return. */
|
||||||
|
extern boolean fCuvar_binary;
|
||||||
|
|
||||||
|
/* A prefix string to use before sending a binary character from a
|
||||||
|
file; this is only used if fCuvar_binary is TRUE. */
|
||||||
|
extern const char *zCuvar_binary_prefix;
|
||||||
|
|
||||||
|
/* Whether to check for echoes of characters sent when sending a file.
|
||||||
|
This is ignored if fCuvar_binary is TRUE. */
|
||||||
|
extern boolean fCuvar_echocheck;
|
||||||
|
|
||||||
|
/* A character to look for after each newline is sent when sending a
|
||||||
|
file. The character is the first character in this string, except
|
||||||
|
that a '\0' means that no echo check is done. */
|
||||||
|
extern const char *zCuvar_echonl;
|
||||||
|
|
||||||
|
/* The timeout to use when looking for an character. */
|
||||||
|
extern int cCuvar_timeout;
|
||||||
|
|
||||||
|
/* The character to use to kill a line if an echo check fails. The
|
||||||
|
first character in this string is sent. */
|
||||||
|
extern const char *zCuvar_kill;
|
||||||
|
|
||||||
|
/* The number of times to try resending a line if the echo check keeps
|
||||||
|
failing. */
|
||||||
|
extern int cCuvar_resend;
|
||||||
|
|
||||||
|
/* The string to send at the end of a file sent with ~>. */
|
||||||
|
extern const char *zCuvar_eofwrite;
|
||||||
|
|
||||||
|
/* The string to look for to finish a file received with ~<. For tip
|
||||||
|
this is a collection of single characters, but I don't want to do
|
||||||
|
that because it means that there are characters which cannot be
|
||||||
|
received. */
|
||||||
|
extern const char *zCuvar_eofread;
|
||||||
|
|
||||||
|
/* Whether to provide verbose information when sending or receiving a
|
||||||
|
file. */
|
||||||
|
extern boolean fCuvar_verbose;
|
120
gnu/libexec/uucp/common_sources/getopt.h
Normal file
120
gnu/libexec/uucp/common_sources/getopt.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* Declarations for getopt.
|
||||||
|
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
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, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
This file was modified slightly by Ian Lance Taylor, November 1992,
|
||||||
|
for Taylor UUCP. */
|
||||||
|
|
||||||
|
#ifndef _GETOPT_H
|
||||||
|
#define _GETOPT_H 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ian Lance Taylor <ian@airs.com> added the following defines for
|
||||||
|
Taylor UUCP. This avoids reported conflicts with system getopt
|
||||||
|
definitions. */
|
||||||
|
#define getopt gnu_getopt
|
||||||
|
#define optarg gnu_optarg
|
||||||
|
#define optind gnu_optind
|
||||||
|
#define opterr gnu_opterr
|
||||||
|
|
||||||
|
/* For communication from `getopt' to the caller.
|
||||||
|
When `getopt' finds an option that takes an argument,
|
||||||
|
the argument value is returned here.
|
||||||
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
|
||||||
|
/* Index in ARGV of the next element to be scanned.
|
||||||
|
This is used for communication to and from the caller
|
||||||
|
and for communication between successive calls to `getopt'.
|
||||||
|
|
||||||
|
On entry to `getopt', zero means this is the first call; initialize.
|
||||||
|
|
||||||
|
When `getopt' returns EOF, this is the index of the first of the
|
||||||
|
non-option elements that the caller should itself scan.
|
||||||
|
|
||||||
|
Otherwise, `optind' communicates from one call to the next
|
||||||
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
extern int optind;
|
||||||
|
|
||||||
|
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||||
|
for unrecognized options. */
|
||||||
|
|
||||||
|
extern int opterr;
|
||||||
|
|
||||||
|
/* Describe the long-named options requested by the application.
|
||||||
|
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||||
|
of `struct option' terminated by an element containing a name which is
|
||||||
|
zero.
|
||||||
|
|
||||||
|
The field `has_arg' is:
|
||||||
|
no_argument (or 0) if the option does not take an argument,
|
||||||
|
required_argument (or 1) if the option requires an argument,
|
||||||
|
optional_argument (or 2) if the option takes an optional argument.
|
||||||
|
|
||||||
|
If the field `flag' is not NULL, it points to a variable that is set
|
||||||
|
to the value given in the field `val' when the option is found, but
|
||||||
|
left unchanged if the option is not found.
|
||||||
|
|
||||||
|
To have a long-named option do something other than set an `int' to
|
||||||
|
a compiled-in constant, such as set a value from `optarg', set the
|
||||||
|
option's `flag' field to zero and its `val' field to a nonzero
|
||||||
|
value (the equivalent single-letter option character, if there is
|
||||||
|
one). For long options that have a zero `flag' field, `getopt'
|
||||||
|
returns the contents of the `val' field. */
|
||||||
|
|
||||||
|
struct option
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
/* has_arg can't be an enum because some compilers complain about
|
||||||
|
type mismatches in all the code that assumes it is an int. */
|
||||||
|
int has_arg;
|
||||||
|
int *flag;
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||||
|
|
||||||
|
enum _argtype
|
||||||
|
{
|
||||||
|
no_argument,
|
||||||
|
required_argument,
|
||||||
|
optional_argument
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int getopt P((int argc, char *const *argv, const char *shortopts));
|
||||||
|
extern int getopt_long P((int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind));
|
||||||
|
extern int getopt_long_only P((int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind));
|
||||||
|
|
||||||
|
/* Internal only. Users should not call this directly. */
|
||||||
|
extern int _getopt_internal P((int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind,
|
||||||
|
int long_only));
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _GETOPT_H */
|
699
gnu/libexec/uucp/common_sources/log.c
Normal file
699
gnu/libexec/uucp/common_sources/log.c
Normal file
@ -0,0 +1,699 @@
|
|||||||
|
/* log.c
|
||||||
|
Routines to add entries to the log files.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char log_rcsid[] = "$Id: log.c,v 1.1 1993/08/04 19:30:50 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Local functions. */
|
||||||
|
|
||||||
|
static const char *zldate_and_time P((void));
|
||||||
|
|
||||||
|
/* Log file name. */
|
||||||
|
static const char *zLogfile;
|
||||||
|
|
||||||
|
/* The function to call when a LOG_FATAL error occurs. */
|
||||||
|
static void (*pfLfatal) P((void));
|
||||||
|
|
||||||
|
/* Whether to go to a file. */
|
||||||
|
static boolean fLfile;
|
||||||
|
|
||||||
|
/* ID number. */
|
||||||
|
static int iLid;
|
||||||
|
|
||||||
|
/* The current user name. */
|
||||||
|
static char *zLuser;
|
||||||
|
|
||||||
|
/* The current system name. */
|
||||||
|
static char *zLsystem;
|
||||||
|
|
||||||
|
/* The current device name. */
|
||||||
|
char *zLdevice;
|
||||||
|
|
||||||
|
/* The open log file. */
|
||||||
|
static FILE *eLlog;
|
||||||
|
|
||||||
|
/* Whether we have tried to open the log file. We need this because
|
||||||
|
we don't want to keep trying to open the log file if we failed the
|
||||||
|
first time. It can't be static because under HAVE_HDB_LOGGING we
|
||||||
|
may have to write to various different log files. */
|
||||||
|
static boolean fLlog_tried;
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
/* Debugging file name. */
|
||||||
|
static const char *zLdebugfile;
|
||||||
|
|
||||||
|
/* The open debugging file. */
|
||||||
|
static FILE *eLdebug;
|
||||||
|
|
||||||
|
/* Whether we've tried to open the debugging file. */
|
||||||
|
static boolean fLdebug_tried;
|
||||||
|
|
||||||
|
/* Whether we've written out any debugging information. */
|
||||||
|
static boolean fLdebugging;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Statistics file name. */
|
||||||
|
static const char *zLstatsfile;
|
||||||
|
|
||||||
|
/* The open statistics file. */
|
||||||
|
static FILE *eLstats;
|
||||||
|
|
||||||
|
/* Whether we've tried to open the statistics file. */
|
||||||
|
static boolean fLstats_tried;
|
||||||
|
|
||||||
|
/* The array of signals. The elements are only set to TRUE by the
|
||||||
|
default signal handler. They are only set to FALSE if we don't
|
||||||
|
care whether we got the signal or not. */
|
||||||
|
volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
|
||||||
|
|
||||||
|
/* The array of signals to log. The elements are only set to TRUE by
|
||||||
|
the default signal handler. They are set to FALSE when the signal
|
||||||
|
is logged in ulog. This means that if a signal comes in at just
|
||||||
|
the right time we won't log it (or, rather, we'll log it once
|
||||||
|
instead of twice), but that is not a catatrophe. */
|
||||||
|
volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
|
||||||
|
|
||||||
|
/* Flag that indicates SIGHUP is worth logging. */
|
||||||
|
boolean fLog_sighup = TRUE;
|
||||||
|
|
||||||
|
/* Signal names to use when logging signals. */
|
||||||
|
static const char * const azSignal_names[INDEXSIG_COUNT] = INDEXSIG_NAMES;
|
||||||
|
|
||||||
|
/* If not NULL, ulog calls this function before outputting anything.
|
||||||
|
This is used to support cu. */
|
||||||
|
void (*pfLstart) P((void));
|
||||||
|
|
||||||
|
/* If not NULL, ulog calls this function after outputting everything.
|
||||||
|
This is used to support cu. */
|
||||||
|
void (*pfLend) P((void));
|
||||||
|
|
||||||
|
/* Set the function to call on a LOG_FATAL error. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_fatal_fn (pfn)
|
||||||
|
void (*pfn) P((void));
|
||||||
|
{
|
||||||
|
pfLfatal = pfn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decide whether to send log message to the file or not. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_to_file (puuconf, ffile)
|
||||||
|
pointer puuconf;
|
||||||
|
boolean ffile;
|
||||||
|
{
|
||||||
|
int iuuconf;
|
||||||
|
|
||||||
|
iuuconf = uuconf_logfile (puuconf, &zLogfile);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
iuuconf = uuconf_debugfile (puuconf, &zLdebugfile);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
iuuconf = uuconf_statsfile (puuconf, &zLstatsfile);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
fLfile = ffile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the ID number. This will be called by the usysdep_initialize
|
||||||
|
if there is something sensible to set it to. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_id (i)
|
||||||
|
int i;
|
||||||
|
{
|
||||||
|
iLid = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the user we are making log entries for. The arguments will be
|
||||||
|
copied into memory. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_user (zuser)
|
||||||
|
const char *zuser;
|
||||||
|
{
|
||||||
|
ubuffree (zLuser);
|
||||||
|
zLuser = zbufcpy (zuser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the system name we are making log entries for. The name is copied
|
||||||
|
into memory. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_system (zsystem)
|
||||||
|
const char *zsystem;
|
||||||
|
{
|
||||||
|
if (zsystem == NULL
|
||||||
|
|| zLsystem == NULL
|
||||||
|
|| strcmp (zsystem, zLsystem) != 0)
|
||||||
|
{
|
||||||
|
ubuffree (zLsystem);
|
||||||
|
zLsystem = zbufcpy (zsystem);
|
||||||
|
#if HAVE_HDB_LOGGING
|
||||||
|
/* Under HDB logging we now must write to a different log file. */
|
||||||
|
ulog_close ();
|
||||||
|
#endif /* HAVE_HDB_LOGGING */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the device name. This is copied into memory. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_device (zdevice)
|
||||||
|
const char *zdevice;
|
||||||
|
{
|
||||||
|
ubuffree (zLdevice);
|
||||||
|
zLdevice = zbufcpy (zdevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make a log entry. We make a token concession to non ANSI_C systems,
|
||||||
|
but it clearly won't always work. */
|
||||||
|
|
||||||
|
#if ! ANSI_C
|
||||||
|
#undef HAVE_VFPRINTF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*VARARGS2*/
|
||||||
|
#if HAVE_VFPRINTF
|
||||||
|
void
|
||||||
|
ulog (enum tlog ttype, const char *zmsg, ...)
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
ulog (ttype, zmsg, a, b, c, d, f, g, h, i, j)
|
||||||
|
enum tlog ttype;
|
||||||
|
const char *zmsg;
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if HAVE_VFPRINTF
|
||||||
|
va_list parg;
|
||||||
|
#endif
|
||||||
|
FILE *e, *edebug;
|
||||||
|
boolean fstart, fend;
|
||||||
|
const char *zhdr, *zstr;
|
||||||
|
|
||||||
|
/* Log any received signal. We do it this way to avoid calling ulog
|
||||||
|
from the signal handler. A few routines call ulog to get this
|
||||||
|
message out with zmsg == NULL. */
|
||||||
|
{
|
||||||
|
static boolean fdoing_sigs;
|
||||||
|
|
||||||
|
if (! fdoing_sigs)
|
||||||
|
{
|
||||||
|
int isig;
|
||||||
|
|
||||||
|
fdoing_sigs = TRUE;
|
||||||
|
for (isig = 0; isig < INDEXSIG_COUNT; isig++)
|
||||||
|
{
|
||||||
|
if (afLog_signal[isig])
|
||||||
|
{
|
||||||
|
afLog_signal[isig] = FALSE;
|
||||||
|
|
||||||
|
/* Apparently SunOS sends SIGINT rather than SIGHUP
|
||||||
|
when hanging up, so we don't log either signal if
|
||||||
|
fLog_sighup is FALSE. */
|
||||||
|
if ((isig != INDEXSIG_SIGHUP && isig != INDEXSIG_SIGINT)
|
||||||
|
|| fLog_sighup)
|
||||||
|
ulog (LOG_ERROR, "Got %s signal", azSignal_names[isig]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fdoing_sigs = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zmsg == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
/* If we've had a debugging file open in the past, then we want to
|
||||||
|
write all log file entries to the debugging file even if it's
|
||||||
|
currently closed. */
|
||||||
|
if (fLfile
|
||||||
|
&& eLdebug == NULL
|
||||||
|
&& ! fLdebug_tried
|
||||||
|
&& (fLdebugging || (int) ttype >= (int) LOG_DEBUG))
|
||||||
|
{
|
||||||
|
fLdebug_tried = TRUE;
|
||||||
|
eLdebug = esysdep_fopen (zLdebugfile, FALSE, TRUE, TRUE);
|
||||||
|
fLdebugging = TRUE;
|
||||||
|
}
|
||||||
|
#endif /* DEBUG > 1 */
|
||||||
|
|
||||||
|
if (! fLfile)
|
||||||
|
e = stderr;
|
||||||
|
#if DEBUG > 1
|
||||||
|
else if ((int) ttype >= (int) LOG_DEBUG)
|
||||||
|
{
|
||||||
|
e = eLdebug;
|
||||||
|
|
||||||
|
/* If we can't open the debugging file, don't output any
|
||||||
|
debugging messages. */
|
||||||
|
if (e == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* DEBUG > 1 */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (eLlog == NULL && ! fLlog_tried)
|
||||||
|
{
|
||||||
|
fLlog_tried = TRUE;
|
||||||
|
#if ! HAVE_HDB_LOGGING
|
||||||
|
eLlog = esysdep_fopen (zLogfile, TRUE, TRUE, TRUE);
|
||||||
|
#else /* HAVE_HDB_LOGGING */
|
||||||
|
{
|
||||||
|
const char *zsys;
|
||||||
|
char *zfile;
|
||||||
|
|
||||||
|
/* We want to write to .Log/program/system, e.g.
|
||||||
|
.Log/uucico/uunet. The system name may not be set. */
|
||||||
|
if (zLsystem == NULL)
|
||||||
|
zsys = "ANY";
|
||||||
|
else
|
||||||
|
zsys = zLsystem;
|
||||||
|
|
||||||
|
zfile = zbufalc (strlen (zLogfile)
|
||||||
|
+ strlen (abProgram)
|
||||||
|
+ strlen (zsys)
|
||||||
|
+ 1);
|
||||||
|
sprintf (zfile, zLogfile, abProgram, zsys);
|
||||||
|
eLlog = esysdep_fopen (zfile, TRUE, TRUE, TRUE);
|
||||||
|
ubuffree (zfile);
|
||||||
|
}
|
||||||
|
#endif /* HAVE_HDB_LOGGING */
|
||||||
|
|
||||||
|
if (eLlog == NULL)
|
||||||
|
{
|
||||||
|
/* We can't open the log file. We don't even have a
|
||||||
|
safe way to report this problem, since we may not be
|
||||||
|
able to write to stderr (it may, for example, be
|
||||||
|
attached to the incoming call). */
|
||||||
|
if (pfLfatal != NULL)
|
||||||
|
(*pfLfatal) ();
|
||||||
|
usysdep_exit (FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e = eLlog;
|
||||||
|
|
||||||
|
/* eLlog might be NULL here because we might try to open the log
|
||||||
|
file recursively via esysdep_fopen. */
|
||||||
|
if (e == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pfLstart != NULL)
|
||||||
|
(*pfLstart) ();
|
||||||
|
|
||||||
|
edebug = NULL;
|
||||||
|
#if DEBUG > 1
|
||||||
|
if ((int) ttype < (int) LOG_DEBUG)
|
||||||
|
edebug = eLdebug;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fstart = TRUE;
|
||||||
|
fend = TRUE;
|
||||||
|
|
||||||
|
switch (ttype)
|
||||||
|
{
|
||||||
|
case LOG_NORMAL:
|
||||||
|
zhdr = "";
|
||||||
|
break;
|
||||||
|
case LOG_ERROR:
|
||||||
|
zhdr = "ERROR: ";
|
||||||
|
break;
|
||||||
|
case LOG_FATAL:
|
||||||
|
zhdr = "FATAL: ";
|
||||||
|
break;
|
||||||
|
#if DEBUG > 1
|
||||||
|
case LOG_DEBUG:
|
||||||
|
zhdr = "DEBUG: ";
|
||||||
|
break;
|
||||||
|
case LOG_DEBUG_START:
|
||||||
|
zhdr = "DEBUG: ";
|
||||||
|
fend = FALSE;
|
||||||
|
break;
|
||||||
|
case LOG_DEBUG_CONTINUE:
|
||||||
|
zhdr = NULL;
|
||||||
|
fstart = FALSE;
|
||||||
|
fend = FALSE;
|
||||||
|
break;
|
||||||
|
case LOG_DEBUG_END:
|
||||||
|
zhdr = NULL;
|
||||||
|
fstart = FALSE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
zhdr = "???: ";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fstart)
|
||||||
|
{
|
||||||
|
if (! fLfile)
|
||||||
|
{
|
||||||
|
fprintf (e, "%s: ", abProgram);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s: ", abProgram);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
fprintf (e, "%s ", abProgram);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s ", abProgram);
|
||||||
|
#else /* ! HAVE_TAYLOR_LOGGING */
|
||||||
|
fprintf (e, "%s ", zLuser == NULL ? "uucp" : zLuser);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s ", zLuser == NULL ? "uucp" : zLuser);
|
||||||
|
#endif /* HAVE_TAYLOR_LOGGING */
|
||||||
|
|
||||||
|
fprintf (e, "%s ", zLsystem == NULL ? "-" : zLsystem);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s ", zLsystem == NULL ? "-" : zLsystem);
|
||||||
|
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
fprintf (e, "%s ", zLuser == NULL ? "-" : zLuser);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s ", zLuser == NULL ? "-" : zLuser);
|
||||||
|
#endif /* HAVE_TAYLOR_LOGGING */
|
||||||
|
|
||||||
|
zstr = zldate_and_time ();
|
||||||
|
fprintf (e, "(%s", zstr);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "(%s", zstr);
|
||||||
|
|
||||||
|
if (iLid != 0)
|
||||||
|
{
|
||||||
|
#if ! HAVE_HDB_LOGGING
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
fprintf (e, " %d", iLid);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, " %d", iLid);
|
||||||
|
#else /* ! HAVE_TAYLOR_LOGGING */
|
||||||
|
fprintf (e, "-%d", iLid);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "-%d", iLid);
|
||||||
|
#endif /* ! HAVE_TAYLOR_LOGGING */
|
||||||
|
#else /* HAVE_HDB_LOGGING */
|
||||||
|
|
||||||
|
/* I assume that the second number here is meant to be
|
||||||
|
some sort of file sequence number, and that it should
|
||||||
|
correspond to the sequence number in the statistics
|
||||||
|
file. I don't have any really convenient way to do
|
||||||
|
this, so I won't unless somebody thinks it's very
|
||||||
|
important. */
|
||||||
|
fprintf (e, ",%d,%d", iLid, 0);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, ",%d,%d", iLid, 0);
|
||||||
|
#endif /* HAVE_HDB_LOGGING */
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (e, ") ");
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, ") ");
|
||||||
|
|
||||||
|
fprintf (e, "%s", zhdr);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "%s", zhdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_VFPRINTF
|
||||||
|
va_start (parg, zmsg);
|
||||||
|
vfprintf (e, zmsg, parg);
|
||||||
|
va_end (parg);
|
||||||
|
if (edebug != NULL)
|
||||||
|
{
|
||||||
|
va_start (parg, zmsg);
|
||||||
|
vfprintf (edebug, zmsg, parg);
|
||||||
|
va_end (parg);
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_VFPRINTF */
|
||||||
|
fprintf (e, zmsg, a, b, c, d, f, g, h, i, j);
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, zmsg, a, b, c, d, f, g, h, i, j);
|
||||||
|
#endif /* ! HAVE_VFPRINTF */
|
||||||
|
|
||||||
|
if (fend)
|
||||||
|
{
|
||||||
|
fprintf (e, "\n");
|
||||||
|
if (edebug != NULL)
|
||||||
|
fprintf (edebug, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) fflush (e);
|
||||||
|
if (edebug != NULL)
|
||||||
|
(void) fflush (edebug);
|
||||||
|
|
||||||
|
if (pfLend != NULL)
|
||||||
|
(*pfLend) ();
|
||||||
|
|
||||||
|
if (ttype == LOG_FATAL)
|
||||||
|
{
|
||||||
|
if (pfLfatal != NULL)
|
||||||
|
(*pfLfatal) ();
|
||||||
|
usysdep_exit (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CLOSE_LOGFILES
|
||||||
|
ulog_close ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Log a uuconf error. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_uuconf (ttype, puuconf, iuuconf)
|
||||||
|
enum tlog ttype;
|
||||||
|
pointer puuconf;
|
||||||
|
int iuuconf;
|
||||||
|
{
|
||||||
|
char ab[512];
|
||||||
|
|
||||||
|
(void) uuconf_error_string (puuconf, iuuconf, ab, sizeof ab);
|
||||||
|
ulog (ttype, "%s", ab);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the log file. There's nothing useful we can do with errors,
|
||||||
|
so we don't check for them. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ulog_close ()
|
||||||
|
{
|
||||||
|
/* Make sure we logged any signal we received. */
|
||||||
|
ulog (LOG_ERROR, (const char *) NULL);
|
||||||
|
|
||||||
|
if (eLlog != NULL)
|
||||||
|
{
|
||||||
|
(void) fclose (eLlog);
|
||||||
|
eLlog = NULL;
|
||||||
|
fLlog_tried = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
if (eLdebug != NULL)
|
||||||
|
{
|
||||||
|
(void) fclose (eLdebug);
|
||||||
|
eLdebug = NULL;
|
||||||
|
fLdebug_tried = FALSE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add an entry to the statistics file. We may eventually want to put
|
||||||
|
failed file transfers in here, but we currently do not. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
void
|
||||||
|
ustats (fsucceeded, zuser, zsystem, fsent, cbytes, csecs, cmicros, fmaster)
|
||||||
|
boolean fsucceeded;
|
||||||
|
const char *zuser;
|
||||||
|
const char *zsystem;
|
||||||
|
boolean fsent;
|
||||||
|
long cbytes;
|
||||||
|
long csecs;
|
||||||
|
long cmicros;
|
||||||
|
boolean fmaster;
|
||||||
|
{
|
||||||
|
long cbps;
|
||||||
|
|
||||||
|
/* The seconds and microseconds are now counted independently, so
|
||||||
|
they may be out of synch. */
|
||||||
|
if (cmicros < 0)
|
||||||
|
{
|
||||||
|
csecs -= ((- cmicros) / 1000000L) + 1;
|
||||||
|
cmicros = 1000000L - ((- cmicros) % 1000000L);
|
||||||
|
}
|
||||||
|
if (cmicros >= 1000000L)
|
||||||
|
{
|
||||||
|
csecs += cmicros / 10000000L;
|
||||||
|
cmicros = cmicros % 1000000L;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* On a system which can determine microseconds we might very well
|
||||||
|
have both csecs == 0 and cmicros == 0. */
|
||||||
|
if (csecs == 0 && cmicros < 1000)
|
||||||
|
cbps = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
long cmillis;
|
||||||
|
|
||||||
|
/* This computation will not overflow provided csecs < 2147483
|
||||||
|
and cbytes and cbps both fit in a long. */
|
||||||
|
cmillis = csecs * 1000 + cmicros / 1000;
|
||||||
|
cbps = ((cbytes / cmillis) * 1000
|
||||||
|
+ ((cbytes % cmillis) * 1000) / cmillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eLstats == NULL)
|
||||||
|
{
|
||||||
|
if (fLstats_tried)
|
||||||
|
return;
|
||||||
|
fLstats_tried = TRUE;
|
||||||
|
eLstats = esysdep_fopen (zLstatsfile, TRUE, TRUE, TRUE);
|
||||||
|
if (eLstats == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
fprintf (eLstats,
|
||||||
|
"%s %s (%s) %s%s %ld bytes in %ld.%03ld seconds (%ld bytes/sec)\n",
|
||||||
|
zuser, zsystem, zldate_and_time (),
|
||||||
|
fsucceeded ? "" : "failed after ",
|
||||||
|
fsent ? "sent" : "received",
|
||||||
|
cbytes, csecs, cmicros / 1000, cbps);
|
||||||
|
#endif /* HAVE_TAYLOR_LOGGING */
|
||||||
|
#if HAVE_V2_LOGGING
|
||||||
|
fprintf (eLstats,
|
||||||
|
"%s %s (%s) (%ld) %s %s %ld bytes %ld seconds\n",
|
||||||
|
zuser, zsystem, zldate_and_time (),
|
||||||
|
(long) time ((time_t *) NULL),
|
||||||
|
fsent ? "sent" : "received",
|
||||||
|
fsucceeded ? "data" : "failed after",
|
||||||
|
cbytes, csecs + cmicros / 500000);
|
||||||
|
#endif /* HAVE_V2_LOGGING */
|
||||||
|
#if HAVE_HDB_LOGGING
|
||||||
|
{
|
||||||
|
static int iseq;
|
||||||
|
|
||||||
|
/* I don't know what the 'C' means. The sequence number should
|
||||||
|
probably correspond to the sequence number in the log file, but
|
||||||
|
that is currently always 0; using this fake sequence number
|
||||||
|
will still at least reveal which transfers are from different
|
||||||
|
calls. We don't report a failed data transfer with this
|
||||||
|
format. */
|
||||||
|
if (! fsucceeded)
|
||||||
|
return;
|
||||||
|
++iseq;
|
||||||
|
fprintf (eLstats,
|
||||||
|
"%s!%s %c (%s) (C,%d,%d) [%s] %s %ld / %ld.%03ld secs, %ld %s\n",
|
||||||
|
zsystem, zuser, fmaster ? 'M' : 'S', zldate_and_time (),
|
||||||
|
iLid, iseq, zLdevice == NULL ? "unknown" : zLdevice,
|
||||||
|
fsent ? "->" : "<-",
|
||||||
|
cbytes, csecs, cmicros / 1000, cbps,
|
||||||
|
"bytes/sec");
|
||||||
|
}
|
||||||
|
#endif /* HAVE_HDB_LOGGING */
|
||||||
|
|
||||||
|
(void) fflush (eLstats);
|
||||||
|
|
||||||
|
#if CLOSE_LOGFILES
|
||||||
|
ustats_close ();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the statistics file. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ustats_close ()
|
||||||
|
{
|
||||||
|
if (eLstats != NULL)
|
||||||
|
{
|
||||||
|
if (fclose (eLstats) != 0)
|
||||||
|
ulog (LOG_ERROR, "fclose: %s", strerror (errno));
|
||||||
|
eLstats = NULL;
|
||||||
|
fLstats_tried = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the date and time in a form used for a log entry. */
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
zldate_and_time ()
|
||||||
|
{
|
||||||
|
long isecs, imicros;
|
||||||
|
struct tm s;
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
static char ab[sizeof "1991-12-31 12:00:00.00"];
|
||||||
|
#endif
|
||||||
|
#if HAVE_V2_LOGGING
|
||||||
|
static char ab[sizeof "12/31-12:00"];
|
||||||
|
#endif
|
||||||
|
#if HAVE_HDB_LOGGING
|
||||||
|
static char ab[sizeof "12/31-12:00:00"];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isecs = ixsysdep_time (&imicros);
|
||||||
|
usysdep_localtime (isecs, &s);
|
||||||
|
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
sprintf (ab, "%04d-%02d-%02d %02d:%02d:%02d.%02d",
|
||||||
|
s.tm_year + 1900, s.tm_mon + 1, s.tm_mday, s.tm_hour,
|
||||||
|
s.tm_min, s.tm_sec, (int) (imicros / 10000));
|
||||||
|
#endif
|
||||||
|
#if HAVE_V2_LOGGING
|
||||||
|
sprintf (ab, "%d/%d-%02d:%02d", s.tm_mon + 1, s.tm_mday,
|
||||||
|
s.tm_hour, s.tm_min);
|
||||||
|
#endif
|
||||||
|
#if HAVE_HDB_LOGGING
|
||||||
|
sprintf (ab, "%d/%d-%02d:%02d:%02d", s.tm_mon + 1, s.tm_mday,
|
||||||
|
s.tm_hour, s.tm_min, s.tm_sec);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ab;
|
||||||
|
}
|
521
gnu/libexec/uucp/common_sources/policy.h
Normal file
521
gnu/libexec/uucp/common_sources/policy.h
Normal file
@ -0,0 +1,521 @@
|
|||||||
|
/* policy.h
|
||||||
|
Configuration file for policy decisions. To be edited on site.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This header file contains macro definitions which must be set by
|
||||||
|
each site before compilation. The first few are system
|
||||||
|
characteristics that can not be easily discovered by the
|
||||||
|
configuration script. Most are configuration decisions that must
|
||||||
|
be made by the local administrator. */
|
||||||
|
|
||||||
|
/* System characteristics. */
|
||||||
|
|
||||||
|
/* This code tries to use several ANSI C features, including
|
||||||
|
prototypes, stdarg.h, the const qualifier and the types void
|
||||||
|
(including void * pointers) and unsigned char. By default it will
|
||||||
|
use these features if the compiler defines __STDC__. If your
|
||||||
|
compiler supports these features but does not define __STDC__, you
|
||||||
|
should set ANSI_C to 1. If your compiler does not support these
|
||||||
|
features but defines __STDC__ (no compiler should do this, in my
|
||||||
|
opinion), you should set ANSI_C to 0. In most cases (or if you're
|
||||||
|
not sure) just leave the line below commented out. */
|
||||||
|
/* #define ANSI_C 1 */
|
||||||
|
|
||||||
|
/* Set USE_STDIO to 1 if data files should be read using the stdio
|
||||||
|
routines (fopen, fread, etc.) rather than the UNIX unbuffered I/O
|
||||||
|
calls (open, read, etc.). Unless you know your stdio is really
|
||||||
|
rotten, you should leave this as 1. */
|
||||||
|
#define USE_STDIO 1
|
||||||
|
|
||||||
|
/* Exactly one of the following macros must be set to 1. Many modern
|
||||||
|
systems support more than one of these choices through some form of
|
||||||
|
compilation environment, in which case the setting will depend on
|
||||||
|
the compilation environment you use. If you have a reasonable
|
||||||
|
choice between options, I suspect that TERMIO or TERMIOS will be
|
||||||
|
more efficient than TTY, but I have not done any head to head
|
||||||
|
comparisons.
|
||||||
|
|
||||||
|
If you don't set any of these macros, the code below will guess.
|
||||||
|
It will doubtless be wrong on some systems.
|
||||||
|
|
||||||
|
HAVE_BSD_TTY -- Use the 4.2BSD tty routines
|
||||||
|
HAVE_SYSV_TERMIO -- Use the System V termio routines
|
||||||
|
HAVE_POSIX_TERMIOS -- Use the POSIX termios routines
|
||||||
|
*/
|
||||||
|
#define HAVE_BSD_TTY 0
|
||||||
|
#define HAVE_SYSV_TERMIO 0
|
||||||
|
#define HAVE_POSIX_TERMIOS 1
|
||||||
|
|
||||||
|
/* This code tries to guess which terminal driver to use if you did
|
||||||
|
not make a choice above. It is in this file to make it easy to
|
||||||
|
figure out what's happening if something goes wrong. */
|
||||||
|
|
||||||
|
#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS == 0
|
||||||
|
#if HAVE_CBREAK
|
||||||
|
#undef HAVE_BSD_TTY
|
||||||
|
#define HAVE_BSD_TTY 1
|
||||||
|
#else
|
||||||
|
#undef HAVE_SYSV_TERMIO
|
||||||
|
#define HAVE_SYSV_TERMIO 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* On some systems a write to a serial port will block even if the
|
||||||
|
file descriptor has been set to not block. File transfer can be
|
||||||
|
more efficient if the package knows that a write to the serial port
|
||||||
|
will not block; however, if the write does block unexpectedly then
|
||||||
|
data loss is possible at high speeds.
|
||||||
|
|
||||||
|
If writes to a serial port always block even when requested not to,
|
||||||
|
you should set HAVE_UNBLOCKED_WRITES to 0; otherwise you should set
|
||||||
|
it to 1. In general on System V releases without STREAMS-based
|
||||||
|
ttys (e.g., before SVR4) HAVE_UNBLOCKED_WRITES should be 0 and on
|
||||||
|
BSD or SVR4 it should be 1.
|
||||||
|
|
||||||
|
If HAVE_UNBLOCKED_WRITES is set to 1 when it should be 0 you may
|
||||||
|
see an unexpectedly large number of transmission errors, or, if you
|
||||||
|
have hardware handshaking, transfer times may be lower than
|
||||||
|
expected (but then, they always are). If HAVE_UNBLOCKED_WRITES is
|
||||||
|
set to 0 when it should be 1, file transfer will use more CPU time
|
||||||
|
than necessary. If you are unsure, setting HAVE_UNBLOCKED_WRITES
|
||||||
|
to 0 should always be safe. */
|
||||||
|
#define HAVE_UNBLOCKED_WRITES 1
|
||||||
|
|
||||||
|
/* When the code does do a blocking write, it wants to write the
|
||||||
|
largest amount of data which the kernel will accept as a single
|
||||||
|
unit. On BSD this is typically the value of OBUFSIZ in
|
||||||
|
<sys/tty.h>, usually 100. On System V before SVR4 this is
|
||||||
|
typically the size of a clist, CLSIZE in <sys/tty.h>, which is
|
||||||
|
usually 64. On SVR4, which uses STREAMS-based ttys, 2048 is
|
||||||
|
reasonable. Define SINGLE_WRITE to the correct value for your
|
||||||
|
system. If SINGLE_WRITE is too large, data loss may occur. If
|
||||||
|
SINGLE_WRITE is too small, file transfer will use more CPU time
|
||||||
|
than necessary. If you have no idea, 64 should work on most modern
|
||||||
|
systems. */
|
||||||
|
#define SINGLE_WRITE 100
|
||||||
|
|
||||||
|
/* Some tty drivers, such as those from SCO and AT&T's Unix PC, have a
|
||||||
|
bug in the implementation of ioctl() that causes CLOCAL to be
|
||||||
|
ineffective until the port is opened a second time. If
|
||||||
|
HAVE_CLOCAL_BUG is set to 1, code will be added to do this second
|
||||||
|
open on the port. Set this if you are getting messages that say
|
||||||
|
"Line disconnected" while in the dial chat script after only
|
||||||
|
writing the first few characters to the port. This bug causes the
|
||||||
|
resetting of CLOCAL to have no effect, so the "\m" (require
|
||||||
|
carrier) escape sequence won't function properly in dialer chat
|
||||||
|
scripts. */
|
||||||
|
#define HAVE_CLOCAL_BUG 0
|
||||||
|
|
||||||
|
/* On some systems, such as SCO Xenix, resetting DTR on a port
|
||||||
|
apparently prevents getty from working on the port, and thus
|
||||||
|
prevents anybody from dialing in. If HAVE_RESET_BUG is set to 1,
|
||||||
|
DTR will not be reset when a serial port is closed. */
|
||||||
|
#define HAVE_RESET_BUG 0
|
||||||
|
|
||||||
|
/* The Sony NEWS reportedly handles no parity by clearing both the odd
|
||||||
|
and even parity bits in the sgtty structure, unlike most BSD based
|
||||||
|
systems in which no parity is indicated by setting both the odd and
|
||||||
|
even parity bits. Setting HAVE_PARITY_BUG to 1 will handle this
|
||||||
|
correctly. */
|
||||||
|
#define HAVE_PARITY_BUG 0
|
||||||
|
|
||||||
|
#if HAVE_BSD_TTY
|
||||||
|
#ifdef sony
|
||||||
|
#undef HAVE_PARITY_BUG
|
||||||
|
#define HAVE_PARITY_BUG 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* On Ultrix 4.0, at least, setting CBREAK causes input characters to
|
||||||
|
be stripped, regardless of the setting of LPASS8 and LLITOUT. This
|
||||||
|
can be worked around by using the termio call to reset ISTRIP.
|
||||||
|
This probably does not apply to any other operating system.
|
||||||
|
Setting HAVE_STRIP_BUG to 1 will use this workaround. */
|
||||||
|
#define HAVE_STRIP_BUG 0
|
||||||
|
|
||||||
|
#if HAVE_BSD_TTY
|
||||||
|
#ifdef ultrix
|
||||||
|
#undef HAVE_STRIP_BUG
|
||||||
|
#define HAVE_STRIP_BUG 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TIMES_TICK is the fraction of a second which times(2) returns (for
|
||||||
|
example, if times returns 100ths of a second TIMES_TICK should be
|
||||||
|
set to 100). On a true POSIX system (one which has the sysconf
|
||||||
|
function and also has _SC_CLK_TCK defined in <unistd.h>) TIMES_TICK
|
||||||
|
may simply be left as 0. On some systems the environment variable
|
||||||
|
HZ is what you want for TIMES_TICK, but on some other systems HZ
|
||||||
|
has the wrong value; check the man page. If you leave this set to
|
||||||
|
0, the code will try to guess; it will doubtless be wrong on some
|
||||||
|
non-POSIX systems. If TIMES_TICK is wrong the code may report
|
||||||
|
incorrect file transfer times in the statistics file, but on many
|
||||||
|
systems times(2) will actually not be used and this value will not
|
||||||
|
matter at all. */
|
||||||
|
#define TIMES_TICK 0
|
||||||
|
|
||||||
|
/* If your system does not support saved set user ID, set
|
||||||
|
HAVE_SAVED_SETUID to 0. However, this is ignored if your system
|
||||||
|
has the setreuid function. Most modern Unixes have one or the
|
||||||
|
other. If your system has the setreuid function, don't worry about
|
||||||
|
this define, or about the following discussion.
|
||||||
|
|
||||||
|
If you set HAVE_SAVED_SETUID to 0, you will not be able to use uucp
|
||||||
|
to transfer files that the uucp user can not read. Basically, you
|
||||||
|
will only be able to use uucp on world-readable files. If you set
|
||||||
|
HAVE_SAVED_SETUID to 1, but your system does not have saved set
|
||||||
|
user ID, uucp will fail with an error message whenever anybody
|
||||||
|
other than the uucp user uses it. */
|
||||||
|
#define HAVE_SAVED_SETUID 1
|
||||||
|
|
||||||
|
/* On some systems, such as the DG Aviion and, possibly, the RS/6000,
|
||||||
|
the setreuid function is broken. It should be possible to use
|
||||||
|
setreuid to swap the real and effective user ID's, but on some
|
||||||
|
systems it will not change the real user ID (I believe this is due
|
||||||
|
to a misreading of the POSIX standard). On such a system you must
|
||||||
|
set HAVE_BROKEN_SETREUID to 1; if you do not, you will get error
|
||||||
|
messages from setreuid. Systems on which setreuid exists but is
|
||||||
|
broken pretty much always have saved setuid. */
|
||||||
|
#define HAVE_BROKEN_SETREUID 0
|
||||||
|
|
||||||
|
/* On the 3B2, and possibly other systems, nap takes an argument in
|
||||||
|
hundredths of a second rather than milliseconds. I don't know of
|
||||||
|
any way to test for this. Set HAVE_HUNDREDTHS_NAP to 1 if this is
|
||||||
|
true on your system. This does not matter if your system does not
|
||||||
|
have the nap function. */
|
||||||
|
#define HAVE_HUNDREDTHS_NAP 0
|
||||||
|
|
||||||
|
/* Set PS_PROGRAM to the program to run to get a process status,
|
||||||
|
including the arguments to pass it. This is used by ``uustat -p''.
|
||||||
|
Set HAVE_PS_MULTIPLE to 1 if a comma separated list of process
|
||||||
|
numbers may be appended (e.g. ``ps -flp1,10,100''). Otherwise ps
|
||||||
|
will be invoked several times, with a single process number append
|
||||||
|
each time. The default definitions should work on most systems,
|
||||||
|
although some (such as the NeXT) will complain about the 'p'
|
||||||
|
option; for those, use the second set of definitions. The third
|
||||||
|
set of definitions are appropriate for System V. To use the second
|
||||||
|
or third set of definitions, change the ``#if 1'' to ``#if 0'' and
|
||||||
|
change the appropriate ``#if 0'' to ``#if 1''. */
|
||||||
|
#if 1
|
||||||
|
#define PS_PROGRAM "/bin/ps -lp"
|
||||||
|
#define HAVE_PS_MULTIPLE 0
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
#define PS_PROGRAM "/bin/ps -l"
|
||||||
|
#define HAVE_PS_MULTIPLE 0
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
#define PS_PROGRAM "/bin/ps -flp"
|
||||||
|
#define HAVE_PS_MULTIPLE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If you use other programs that also lock devices, such as cu or
|
||||||
|
uugetty, the other programs and UUCP must agree on whether a device
|
||||||
|
is locked. This is typically done by creating a lock file in a
|
||||||
|
specific directory; the lock files are generally named
|
||||||
|
LCK..something or LK.something. If the LOCKDIR macro is defined,
|
||||||
|
these lock files will be placed in the named directory; otherwise
|
||||||
|
they will be placed in the default spool directory. On some HDB
|
||||||
|
systems the lock files are placed in /etc/locks. On some they are
|
||||||
|
placed in /usr/spool/locks. On the NeXT they are placed in
|
||||||
|
/usr/spool/uucp/LCK. */
|
||||||
|
/* #define LOCKDIR "/usr/spool/uucp" */
|
||||||
|
/* #define LOCKDIR "/etc/locks" */
|
||||||
|
/* #define LOCKDIR "/usr/spool/locks" */
|
||||||
|
/* #define LOCKDIR "/usr/spool/uucp/LCK" */
|
||||||
|
#define LOCKDIR "/var/spool/lock"
|
||||||
|
|
||||||
|
/* You must also specify the format of the lock files by setting
|
||||||
|
exactly one of the following macros to 1. Check an existing lock
|
||||||
|
file to decide which of these choices is more appropriate.
|
||||||
|
|
||||||
|
The HDB style is to write the locking process ID in ASCII, passed
|
||||||
|
to ten characters, followed by a newline.
|
||||||
|
|
||||||
|
The V2 style is to write the locking process ID as four binary
|
||||||
|
bytes in the host byte order. Many BSD derived systems use this
|
||||||
|
type of lock file, including the NeXT.
|
||||||
|
|
||||||
|
SCO lock files are similar to HDB lock files, but always lock the
|
||||||
|
lowercase version of the tty (i.e., LCK..tty2a is created if you
|
||||||
|
are locking tty2A). They are appropriate if you are using Taylor
|
||||||
|
UUCP on an SCO Unix, SCO Xenix, or SCO Open Desktop system.
|
||||||
|
|
||||||
|
SVR4 lock files are also similar to HDB lock files, but they use a
|
||||||
|
different naming convention. The filenames are LK.xxx.yyy.zzz,
|
||||||
|
where xxx is the major device number of the device holding the
|
||||||
|
special device file, yyy is the major device number of the port
|
||||||
|
device itself, and zzz is the minor device number of the port
|
||||||
|
device.
|
||||||
|
|
||||||
|
Coherent use a completely different method of terminal locking.
|
||||||
|
See unix/cohtty for details. For locks other than for terminals,
|
||||||
|
HDB type lock files are used. */
|
||||||
|
#define HAVE_V2_LOCKFILES 0
|
||||||
|
#define HAVE_HDB_LOCKFILES 1
|
||||||
|
#define HAVE_SCO_LOCKFILES 0
|
||||||
|
#define HAVE_SVR4_LOCKFILES 0
|
||||||
|
#define HAVE_COHERENT_LOCKFILES 0
|
||||||
|
|
||||||
|
/* If your system supports Internet mail addresses (which look like
|
||||||
|
user@host.domain rather than system!user), HAVE_INTERNET_MAIL
|
||||||
|
should be set to 1. This is checked by uuxqt when sending error
|
||||||
|
(or success, if requested) notifications to the person who
|
||||||
|
submitted the job. */
|
||||||
|
#define HAVE_INTERNET_MAIL 1
|
||||||
|
|
||||||
|
/* Adminstrative decisions. */
|
||||||
|
|
||||||
|
/* Set USE_RCS_ID to 1 if you want the RCS ID strings compiled into
|
||||||
|
the executable. Leaving them out will decrease the executable
|
||||||
|
size. Leaving them in will make it easier to determine which
|
||||||
|
version you are running. */
|
||||||
|
#define USE_RCS_ID 1
|
||||||
|
|
||||||
|
/* DEBUG controls how much debugging information is compiled into the
|
||||||
|
code. If DEBUG is defined as 0, no sanity checks will be done and
|
||||||
|
no debugging messages will be compiled in. If DEBUG is defined as
|
||||||
|
1 sanity checks will be done but there will still be no debugging
|
||||||
|
messages. If DEBUG is 2 than debugging messages will be compiled
|
||||||
|
in. When initially testing, DEBUG should be 2, and you should
|
||||||
|
probably leave it at 2 unless a small reduction in the executable
|
||||||
|
file size will be very helpful. */
|
||||||
|
#define DEBUG 2
|
||||||
|
|
||||||
|
/* Set the default grade to use for a uucp command if the -g option is
|
||||||
|
not used. The grades, from highest to lowest, are 0 to 9, A to Z,
|
||||||
|
a to z. */
|
||||||
|
#define BDEFAULT_UUCP_GRADE ('N')
|
||||||
|
|
||||||
|
/* Set the default grade to use for a uux command if the -g option is
|
||||||
|
not used. */
|
||||||
|
#define BDEFAULT_UUX_GRADE ('N')
|
||||||
|
|
||||||
|
/* To compile in use of the new style of configuration files described
|
||||||
|
in the documentation, set HAVE_TAYLOR_CONFIG to 1. */
|
||||||
|
#define HAVE_TAYLOR_CONFIG 1
|
||||||
|
|
||||||
|
/* To compile in use of V2 style configuration files (L.sys, L-devices
|
||||||
|
and so on), set HAVE_V2_CONFIG to 1. To compile in use of HDB
|
||||||
|
style configuration files (Systems, Devices and so on) set
|
||||||
|
HAVE_HDB_CONFIG to 1. The files will be looked up in the
|
||||||
|
oldconfigdir directory as defined in the Makefile.
|
||||||
|
|
||||||
|
You may set any or all of HAVE_TAYLOR_CONFIG, HAVE_V2_CONFIG and
|
||||||
|
HAVE_HDB_CONFIG to 1 (you must set at least one of the macros).
|
||||||
|
When looking something up (a system, a port, etc.) the new style
|
||||||
|
configuration files will be read first, followed by the V2
|
||||||
|
configuration files, followed by the HDB configuration files. */
|
||||||
|
#define HAVE_V2_CONFIG 1
|
||||||
|
#define HAVE_HDB_CONFIG 1
|
||||||
|
|
||||||
|
/* Exactly one of the following macros must be set to 1. The exact
|
||||||
|
format of the spool directories is explained in unix/spool.c.
|
||||||
|
|
||||||
|
SPOOLDIR_V2 -- Use a Version 2 (original UUCP) style spool directory
|
||||||
|
SPOOLDIR_BSD42 -- Use a BSD 4.2 style spool directory
|
||||||
|
SPOOLDIR_BSD43 -- Use a BSD 4.3 style spool directory
|
||||||
|
SPOOLDIR_HDB -- Use a HDB (BNU) style spool directory
|
||||||
|
SPOOLDIR_ULTRIX -- Use an Ultrix style spool directory
|
||||||
|
SPOOLDIR_SVR4 -- Use a System V Release 4 spool directory
|
||||||
|
SPOOLDIR_TAYLOR -- Use a new style spool directory
|
||||||
|
|
||||||
|
If you are not worried about compatibility with a currently running
|
||||||
|
UUCP, use SPOOLDIR_TAYLOR. */
|
||||||
|
#define SPOOLDIR_V2 0
|
||||||
|
#define SPOOLDIR_BSD42 0
|
||||||
|
#define SPOOLDIR_BSD43 0
|
||||||
|
#define SPOOLDIR_HDB 0
|
||||||
|
#define SPOOLDIR_ULTRIX 0
|
||||||
|
#define SPOOLDIR_SVR4 0
|
||||||
|
#define SPOOLDIR_TAYLOR 1
|
||||||
|
|
||||||
|
/* You must select which type of logging you want by setting exactly
|
||||||
|
one of the following to 1. These control output to the log file
|
||||||
|
and to the statistics file.
|
||||||
|
|
||||||
|
If you define HAVE_TAYLOR_LOGGING, each line in the log file will
|
||||||
|
look something like this:
|
||||||
|
|
||||||
|
uucico uunet uucp (1991-12-10 09:04:34.45 16390) Receiving uunet/D./D.uunetSwJ72
|
||||||
|
|
||||||
|
and each line in the statistics file will look something like this:
|
||||||
|
|
||||||
|
uucp uunet (1991-12-10 09:04:40.20) received 2371 bytes in 5 seconds (474 bytes/sec)
|
||||||
|
|
||||||
|
If you define HAVE_V2_LOGGING, each line in the log file will look
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
uucico uunet uucp (12/10-09:04 16390) Receiving uunet/D./D.uunetSwJ72
|
||||||
|
|
||||||
|
and each line in the statistics file will look something like this:
|
||||||
|
|
||||||
|
uucp uunet (12/10-09:04 16390) (692373862) received data 2371 bytes 5 seconds
|
||||||
|
|
||||||
|
If you define HAVE_HDB_LOGGING, each program will by default use a
|
||||||
|
separate log file. For uucico talking to uunet, for example, it
|
||||||
|
will be /usr/spool/uucp/.Log/uucico/uunet. Each line will look
|
||||||
|
something like this:
|
||||||
|
|
||||||
|
uucp uunet (12/10-09:04:22,16390,1) Receiving uunet/D./D.uunetSwJ72
|
||||||
|
|
||||||
|
and each line in the statistics file will look something like this:
|
||||||
|
|
||||||
|
uunet!uucp M (12/10-09:04:22) (C,16390,1) [ttyXX] <- 2371 / 5.000 secs, 474 bytes/sec
|
||||||
|
|
||||||
|
The main reason to prefer one format over another is that you may
|
||||||
|
have shell scripts which expect the files to have a particular
|
||||||
|
format. If you have none, choose whichever format you find more
|
||||||
|
appealing. */
|
||||||
|
#define HAVE_TAYLOR_LOGGING 1
|
||||||
|
#define HAVE_V2_LOGGING 0
|
||||||
|
#define HAVE_HDB_LOGGING 0
|
||||||
|
|
||||||
|
/* If you would like the log, debugging and statistics files to be
|
||||||
|
closed after each message, set CLOSE_LOGFILES to 1. This will
|
||||||
|
permit the log files to be easily moved. If a log file does not
|
||||||
|
exist when a new message is written out, it will be created.
|
||||||
|
Setting CLOSE_LOGFILES to 1 will obviously require slightly more
|
||||||
|
processing time. */
|
||||||
|
#define CLOSE_LOGFILES 0
|
||||||
|
|
||||||
|
/* The name of the default spool directory. If HAVE_TAYLOR_CONFIG is
|
||||||
|
set to 1, this may be overridden by the ``spool'' command in the
|
||||||
|
configuration file. */
|
||||||
|
#define SPOOLDIR "/var/spool/uucp"
|
||||||
|
|
||||||
|
/* The name of the default public directory. If HAVE_TAYLOR_CONFIG is
|
||||||
|
set to 1, this may be overridden by the ``pubdir'' command in the
|
||||||
|
configuration file. Also, a particular system may be given a
|
||||||
|
specific public directory by using the ``pubdir'' command in the
|
||||||
|
system file. */
|
||||||
|
#define PUBDIR "/var/spool/uucppublic"
|
||||||
|
|
||||||
|
/* The default command path. This is a space separated list of
|
||||||
|
directories. Remote command executions requested by uux are looked
|
||||||
|
up using this path. If you are using HAVE_TAYLOR_CONFIG, the
|
||||||
|
command path may be overridden for a particular system. For most
|
||||||
|
systems, you should just make sure that the programs rmail and
|
||||||
|
rnews can be found using this path. */
|
||||||
|
#define CMDPATH "/bin /usr/bin /usr/local/bin"
|
||||||
|
|
||||||
|
/* The default amount of free space to require for systems that do not
|
||||||
|
specify an amount with the ``free-space'' command. This is only
|
||||||
|
used when talking to another instance of Taylor UUCP; if accepting
|
||||||
|
a file would not leave at least this many bytes free on the disk,
|
||||||
|
it will be refused. */
|
||||||
|
#define DEFAULT_FREE_SPACE (50000)
|
||||||
|
|
||||||
|
/* While a file is being received, Taylor UUCP will periodically check
|
||||||
|
to see if there is enough free space remaining on the disk. If
|
||||||
|
there is not enough space available on the disk (as determined by
|
||||||
|
DEFAULT_FREE_SPACE, above, or the ``free-space'' command for the
|
||||||
|
system) the communication will be aborted. The disk will be
|
||||||
|
checked each time FREE_SPACE_DELTA bytes are received. Lower
|
||||||
|
values of FREE_SPACE_DELTA are less likely to fill up the disk, but
|
||||||
|
will also waste more time checking the amount of free space. To
|
||||||
|
avoid checking the disk while the file is being received, set
|
||||||
|
FREE_SPACE_DELTA to 0. */
|
||||||
|
#define FREE_SPACE_DELTA (10240)
|
||||||
|
|
||||||
|
/* It is possible for an execute job to request to be executed using
|
||||||
|
sh(1), rather than execve(2). This is such a security risk, it is
|
||||||
|
being disabled by default; to allow such jobs, set the following
|
||||||
|
macro to 1. */
|
||||||
|
#define ALLOW_SH_EXECUTION 0
|
||||||
|
|
||||||
|
/* If a command executed on behalf of a remote system takes a filename
|
||||||
|
as an argument, a security breach may be possible (note that on my
|
||||||
|
system neither of the default commands, rmail and rnews, take
|
||||||
|
filename arguments). If you set ALLOW_FILENAME_ARGUMENTS to 0, all
|
||||||
|
arguments to a command will be checked; if any argument
|
||||||
|
1) starts with ../
|
||||||
|
2) contains the string /../
|
||||||
|
3) begins with a / but does not name a file that may be sent or
|
||||||
|
received (according to the specified ``remote-send'' and
|
||||||
|
``remote-receive'')
|
||||||
|
the command will be rejected. By default, any argument is
|
||||||
|
permitted. */
|
||||||
|
#define ALLOW_FILENAME_ARGUMENTS 1
|
||||||
|
|
||||||
|
#if HAVE_TAYLOR_LOGGING
|
||||||
|
|
||||||
|
/* The default log file when using HAVE_TAYLOR_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define LOGFILE "/var/spool/uucp/Log"
|
||||||
|
|
||||||
|
/* The default statistics file when using HAVE_TAYLOR_LOGGING. When
|
||||||
|
using HAVE_TAYLOR_CONFIG, this may be overridden by the
|
||||||
|
``statfile'' command in the configuration file. */
|
||||||
|
#define STATFILE "/var/spool/uucp/Stats"
|
||||||
|
|
||||||
|
/* The default debugging file when using HAVE_TAYLOR_LOGGING. When
|
||||||
|
using HAVE_TAYLOR_CONFIG, this may be overridden by the
|
||||||
|
``debugfile'' command in the configuration file. */
|
||||||
|
#define DEBUGFILE "/var/spool/uucp/Debug"
|
||||||
|
|
||||||
|
#endif /* HAVE_TAYLOR_LOGGING */
|
||||||
|
|
||||||
|
#if HAVE_V2_LOGGING
|
||||||
|
|
||||||
|
/* The default log file when using HAVE_V2_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define LOGFILE "/var/spool/uucp/LOGFILE"
|
||||||
|
|
||||||
|
/* The default statistics file when using HAVE_V2_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define STATFILE "/var/spool/uucp/SYSLOG"
|
||||||
|
|
||||||
|
/* The default debugging file when using HAVE_V2_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define DEBUGFILE "/var/spool/uucp/DEBUG"
|
||||||
|
|
||||||
|
#endif /* HAVE_V2_LOGGING */
|
||||||
|
|
||||||
|
#if HAVE_HDB_LOGGING
|
||||||
|
|
||||||
|
/* The default log file when using HAVE_HDB_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``logfile''
|
||||||
|
command in the configuration file. The first %s in the string will
|
||||||
|
be replaced by the program name (e.g. uucico); the second %s will
|
||||||
|
be replaced by the system name (if there is no appropriate system,
|
||||||
|
"ANY" will be used). No other '%' character may appear in the
|
||||||
|
string. */
|
||||||
|
#define LOGFILE "/var/spool/uucp/.Log/%s/%s"
|
||||||
|
|
||||||
|
/* The default statistics file when using HAVE_HDB_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``statfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define STATFILE "/var/spool/uucp/.Admin/xferstats"
|
||||||
|
|
||||||
|
/* The default debugging file when using HAVE_HDB_LOGGING. When using
|
||||||
|
HAVE_TAYLOR_CONFIG, this may be overridden by the ``debugfile''
|
||||||
|
command in the configuration file. */
|
||||||
|
#define DEBUGFILE "/var/spool/uucp/.Admin/audit.local"
|
||||||
|
|
||||||
|
#endif /* HAVE_HDB_LOGGING */
|
237
gnu/libexec/uucp/common_sources/prot.c
Normal file
237
gnu/libexec/uucp/common_sources/prot.c
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/* prot.c
|
||||||
|
Protocol support routines to move commands and data around.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char prot_rcsid[] = "$Id: prot.c,v 1.1 1993/08/04 19:30:55 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "conn.h"
|
||||||
|
#include "prot.h"
|
||||||
|
|
||||||
|
/* Variables visible to the protocol-specific routines. */
|
||||||
|
|
||||||
|
/* Buffer to hold received data. */
|
||||||
|
char abPrecbuf[CRECBUFLEN];
|
||||||
|
|
||||||
|
/* Index of start of data in abPrecbuf. */
|
||||||
|
int iPrecstart;
|
||||||
|
|
||||||
|
/* Index of end of data (first byte not included in data) in abPrecbuf. */
|
||||||
|
int iPrecend;
|
||||||
|
|
||||||
|
/* We want to output and input at the same time, if supported on this
|
||||||
|
machine. If we have something to send, we send it all while
|
||||||
|
accepting a large amount of data. Once we have sent everything we
|
||||||
|
look at whatever we have received. If data comes in faster than we
|
||||||
|
can send it, we may run out of buffer space. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsend_data (qconn, zsend, csend, fdoread)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
const char *zsend;
|
||||||
|
size_t csend;
|
||||||
|
boolean fdoread;
|
||||||
|
{
|
||||||
|
if (! fdoread)
|
||||||
|
return fconn_write (qconn, zsend, csend);
|
||||||
|
|
||||||
|
while (csend > 0)
|
||||||
|
{
|
||||||
|
size_t crec, csent;
|
||||||
|
|
||||||
|
if (iPrecend < iPrecstart)
|
||||||
|
crec = iPrecstart - iPrecend - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
crec = CRECBUFLEN - iPrecend;
|
||||||
|
if (iPrecstart == 0)
|
||||||
|
--crec;
|
||||||
|
}
|
||||||
|
|
||||||
|
csent = csend;
|
||||||
|
|
||||||
|
if (! fconn_io (qconn, zsend, &csent, abPrecbuf + iPrecend, &crec))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
csend -= csent;
|
||||||
|
zsend += csent;
|
||||||
|
|
||||||
|
iPrecend = (iPrecend + crec) % CRECBUFLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read data from the other system when we have nothing to send. The
|
||||||
|
argument cneed is the amount of data the caller wants, and ctimeout
|
||||||
|
is the timeout in seconds. The function sets *pcrec to the amount
|
||||||
|
of data which was actually received, which may be less than cneed
|
||||||
|
if there isn't enough room in the receive buffer. If no data is
|
||||||
|
received before the timeout expires, *pcrec will be returned as 0.
|
||||||
|
If an error occurs, the function returns FALSE. If the freport
|
||||||
|
argument is FALSE, no error should be reported. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
freceive_data (qconn, cneed, pcrec, ctimeout, freport)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
size_t cneed;
|
||||||
|
size_t *pcrec;
|
||||||
|
int ctimeout;
|
||||||
|
boolean freport;
|
||||||
|
{
|
||||||
|
/* Set *pcrec to the maximum amount of data we can read. fconn_read
|
||||||
|
expects *pcrec to be the buffer size, and sets it to the amount
|
||||||
|
actually received. */
|
||||||
|
if (iPrecend < iPrecstart)
|
||||||
|
*pcrec = iPrecstart - iPrecend - 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pcrec = CRECBUFLEN - iPrecend;
|
||||||
|
if (iPrecstart == 0)
|
||||||
|
--(*pcrec);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG > 0
|
||||||
|
/* If we have no room in the buffer, we're in trouble. The
|
||||||
|
protocols must be written to ensure that this can't happen. */
|
||||||
|
if (*pcrec == 0)
|
||||||
|
ulog (LOG_FATAL, "freceive_data: No room in buffer");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we don't have room for all the data the caller wants, we
|
||||||
|
simply have to expect less. We'll get the rest later. */
|
||||||
|
if (*pcrec < cneed)
|
||||||
|
cneed = *pcrec;
|
||||||
|
|
||||||
|
if (! fconn_read (qconn, abPrecbuf + iPrecend, pcrec, cneed, ctimeout,
|
||||||
|
freport))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
iPrecend = (iPrecend + *pcrec) % CRECBUFLEN;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a single character. Get it out of the receive buffer if it's
|
||||||
|
there, otherwise ask freceive_data for at least one character.
|
||||||
|
This is used because as a protocol is shutting down freceive_data
|
||||||
|
may read ahead and eat characters that should be read outside the
|
||||||
|
protocol routines. We call freceive_data rather than fconn_read
|
||||||
|
with an argument of 1 so that we can get all the available data in
|
||||||
|
a single system call. The ctimeout argument is the timeout in
|
||||||
|
seconds; the freport argument is FALSE if no error should be
|
||||||
|
reported. This returns a character, or -1 on timeout or -2 on
|
||||||
|
error. */
|
||||||
|
|
||||||
|
int
|
||||||
|
breceive_char (qconn, ctimeout, freport)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
int ctimeout;
|
||||||
|
boolean freport;
|
||||||
|
{
|
||||||
|
char b;
|
||||||
|
|
||||||
|
if (iPrecstart == iPrecend)
|
||||||
|
{
|
||||||
|
size_t crec;
|
||||||
|
|
||||||
|
if (! freceive_data (qconn, sizeof (char), &crec, ctimeout, freport))
|
||||||
|
return -2;
|
||||||
|
if (crec == 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = abPrecbuf[iPrecstart];
|
||||||
|
iPrecstart = (iPrecstart + 1) % CRECBUFLEN;
|
||||||
|
return BUCHAR (b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send mail about a file transfer. We send to the given mailing
|
||||||
|
address if there is one, otherwise to the user. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fmail_transfer (fsuccess, zuser, zmail, zwhy, zfromfile, zfromsys,
|
||||||
|
ztofile, ztosys, zsaved)
|
||||||
|
boolean fsuccess;
|
||||||
|
const char *zuser;
|
||||||
|
const char *zmail;
|
||||||
|
const char *zwhy;
|
||||||
|
const char *zfromfile;
|
||||||
|
const char *zfromsys;
|
||||||
|
const char *ztofile;
|
||||||
|
const char *ztosys;
|
||||||
|
const char *zsaved;
|
||||||
|
{
|
||||||
|
const char *zsendto;
|
||||||
|
const char *az[20];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (zmail != NULL && *zmail != '\0')
|
||||||
|
zsendto = zmail;
|
||||||
|
else
|
||||||
|
zsendto = zuser;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
az[i++] = "The file\n\t";
|
||||||
|
if (zfromsys != NULL)
|
||||||
|
{
|
||||||
|
az[i++] = zfromsys;
|
||||||
|
az[i++] = "!";
|
||||||
|
}
|
||||||
|
az[i++] = zfromfile;
|
||||||
|
if (fsuccess)
|
||||||
|
az[i++] = "\nwas successfully transferred to\n\t";
|
||||||
|
else
|
||||||
|
az[i++] = "\ncould not be transferred to\n\t";
|
||||||
|
if (ztosys != NULL)
|
||||||
|
{
|
||||||
|
az[i++] = ztosys;
|
||||||
|
az[i++] = "!";
|
||||||
|
}
|
||||||
|
az[i++] = ztofile;
|
||||||
|
az[i++] = "\nas requested by\n\t";
|
||||||
|
az[i++] = zuser;
|
||||||
|
if (! fsuccess)
|
||||||
|
{
|
||||||
|
az[i++] = "\nfor the following reason:\n\t";
|
||||||
|
az[i++] = zwhy;
|
||||||
|
az[i++] = "\n";
|
||||||
|
}
|
||||||
|
if (zsaved != NULL)
|
||||||
|
{
|
||||||
|
az[i++] = zsaved;
|
||||||
|
az[i++] = "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsysdep_mail (zsendto,
|
||||||
|
fsuccess ? "UUCP succeeded" : "UUCP failed",
|
||||||
|
i, az);
|
||||||
|
}
|
250
gnu/libexec/uucp/common_sources/prot.h
Normal file
250
gnu/libexec/uucp/common_sources/prot.h
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/* prot.h
|
||||||
|
Protocol header file.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* We need the definition of uuconf_cmdtab to declare the protocol
|
||||||
|
parameter arrays. */
|
||||||
|
#ifndef UUCONF_H
|
||||||
|
#include "uuconf.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
/* These structures are used in prototypes but are not defined in this
|
||||||
|
header file. */
|
||||||
|
struct sdaemon;
|
||||||
|
struct sconnection;
|
||||||
|
struct stransfer;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The sprotocol structure holds information and functions for a specific
|
||||||
|
protocol (e.g. the 'g' protocol). */
|
||||||
|
|
||||||
|
struct sprotocol
|
||||||
|
{
|
||||||
|
/* The name of the protocol (e.g. 'g'). */
|
||||||
|
char bname;
|
||||||
|
/* Reliability requirements, an or of UUCONF_RELIABLE_xxx defines
|
||||||
|
from uuconf.h. */
|
||||||
|
int ireliable;
|
||||||
|
/* The maximum number of channels this protocol can support. */
|
||||||
|
int cchans;
|
||||||
|
/* Protocol parameter commands. */
|
||||||
|
struct uuconf_cmdtab *qcmds;
|
||||||
|
/* A routine to start the protocol. If *pzlog is set to be
|
||||||
|
non-NULL, it is an informative message to be logged; it should
|
||||||
|
then be passed to ubuffree. */
|
||||||
|
boolean (*pfstart) P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
/* Shutdown the protocol. */
|
||||||
|
boolean (*pfshutdown) P((struct sdaemon *qdaemon));
|
||||||
|
/* Send a command to the other side. */
|
||||||
|
boolean (*pfsendcmd) P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
/* Get buffer to space to fill with data. This should set *pcdata
|
||||||
|
to the amount of data desired. */
|
||||||
|
char *(*pzgetspace) P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
/* Send data to the other side. The argument z must be a return
|
||||||
|
value of pzgetspace. The ipos argument is the file position, and
|
||||||
|
is ignored by most protocols. */
|
||||||
|
boolean (*pfsenddata) P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
/* Wait for data to come in and call fgot_data with it until
|
||||||
|
fgot_data sets *pfexit. */
|
||||||
|
boolean (*pfwait) P((struct sdaemon *qdaemon));
|
||||||
|
/* Handle any file level actions that need to be taken. If a file
|
||||||
|
transfer is starting rather than ending, fstart is TRUE. If the
|
||||||
|
file is being sent rather than received, fsend is TRUE. If
|
||||||
|
fstart and fsend are both TRUE, cbytes holds the size of the
|
||||||
|
file. If *pfhandled is set to TRUE, then the protocol routine
|
||||||
|
has taken care of queueing up qtrans for the next action. */
|
||||||
|
boolean (*pffile) P((struct sdaemon *qdaemon, struct stransfer *qtrans,
|
||||||
|
boolean fstart, boolean fsend, long cbytes,
|
||||||
|
boolean *pfhandled));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Send data to the other system. If the fread argument is TRUE, this
|
||||||
|
will also receive data into the receive buffer abPrecbuf; fread is
|
||||||
|
passed as TRUE if the protocol expects data to be coming back, to
|
||||||
|
make sure the input buffer does not fill up. Returns FALSE on
|
||||||
|
error. */
|
||||||
|
extern boolean fsend_data P((struct sconnection *qconn,
|
||||||
|
const char *zsend, size_t csend,
|
||||||
|
boolean fdoread));
|
||||||
|
|
||||||
|
/* Receive data from the other system when there is no data to send.
|
||||||
|
The cneed argument is the amount of data desired and the ctimeout
|
||||||
|
argument is the timeout in seconds. This will set *pcrec to the
|
||||||
|
amount of data received. It will return FALSE on error. If a
|
||||||
|
timeout occurs, it will return TRUE with *pcrec set to zero. */
|
||||||
|
extern boolean freceive_data P((struct sconnection *qconn, size_t cneed,
|
||||||
|
size_t *pcrec, int ctimeout,
|
||||||
|
boolean freport));
|
||||||
|
|
||||||
|
/* Get one character from the remote system, going through the
|
||||||
|
procotol buffering. The ctimeout argument is the timeout in
|
||||||
|
seconds, and the freport argument is TRUE if errors should be
|
||||||
|
reported (when closing a connection it is pointless to report
|
||||||
|
errors). This returns a character or -1 on a timeout or -2 on an
|
||||||
|
error. */
|
||||||
|
extern int breceive_char P((struct sconnection *qconn,
|
||||||
|
int ctimeout, boolean freport));
|
||||||
|
|
||||||
|
/* Compute a 32 bit CRC of a data buffer, given an initial CRC. */
|
||||||
|
extern unsigned long icrc P((const char *z, size_t c, unsigned long ick));
|
||||||
|
|
||||||
|
/* The initial CRC value to use for a new buffer. */
|
||||||
|
#if ANSI_C
|
||||||
|
#define ICRCINIT (0xffffffffUL)
|
||||||
|
#else
|
||||||
|
#define ICRCINIT ((unsigned long) 0xffffffffL)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The size of the receive buffer. */
|
||||||
|
#define CRECBUFLEN (16384)
|
||||||
|
|
||||||
|
/* Buffer to hold received data. */
|
||||||
|
extern char abPrecbuf[CRECBUFLEN];
|
||||||
|
|
||||||
|
/* Index of start of data in abPrecbuf. */
|
||||||
|
extern int iPrecstart;
|
||||||
|
|
||||||
|
/* Index of end of data (first byte not included in data) in abPrecbuf. */
|
||||||
|
extern int iPrecend;
|
||||||
|
|
||||||
|
/* There are a couple of variables and functions that are shared by
|
||||||
|
the 'i' and 'j' protocols (the 'j' protocol is just a wrapper
|
||||||
|
around the 'i' protocol). These belong in a separate header file,
|
||||||
|
protij.h, but I don't want to create one for just a couple of
|
||||||
|
things. */
|
||||||
|
|
||||||
|
/* An escape sequence of characters for the 'j' protocol to avoid
|
||||||
|
(protocol parameter ``avoid''). */
|
||||||
|
extern const char *zJavoid_parameter;
|
||||||
|
|
||||||
|
/* Timeout to use when sending the 'i' protocol SYNC packet (protocol
|
||||||
|
parameter ``sync-timeout''). */
|
||||||
|
extern int cIsync_timeout;
|
||||||
|
|
||||||
|
/* Shared startup routine for the 'i' and 'j' protocols. */
|
||||||
|
extern boolean fijstart P((struct sdaemon *qdaemon, char **pzlog,
|
||||||
|
int imaxpacksize,
|
||||||
|
boolean (*pfsend) P((struct sconnection *qconn,
|
||||||
|
const char *zsend,
|
||||||
|
size_t csend,
|
||||||
|
boolean fdoread)),
|
||||||
|
boolean (*pfreceive) P((struct sconnection *qconn,
|
||||||
|
size_t cneed,
|
||||||
|
size_t *pcrec,
|
||||||
|
int ctimeout,
|
||||||
|
boolean freport))));
|
||||||
|
|
||||||
|
/* Prototypes for 'g' protocol functions. */
|
||||||
|
|
||||||
|
extern struct uuconf_cmdtab asGproto_params[];
|
||||||
|
extern boolean fgstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean fbiggstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean fgshutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fgsendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *zggetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean fgsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean fgwait P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Prototypes for 'f' protocol functions. */
|
||||||
|
|
||||||
|
extern struct uuconf_cmdtab asFproto_params[];
|
||||||
|
extern boolean ffstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean ffshutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean ffsendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *zfgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean ffsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean ffwait P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fffile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
|
||||||
|
boolean fstart, boolean fsend, long cbytes,
|
||||||
|
boolean *pfhandled));
|
||||||
|
|
||||||
|
/* Prototypes for 't' protocol functions. */
|
||||||
|
|
||||||
|
extern struct uuconf_cmdtab asTproto_params[];
|
||||||
|
extern boolean ftstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean ftshutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean ftsendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *ztgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean ftsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean ftwait P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean ftfile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
|
||||||
|
boolean fstart, boolean fsend, long cbytes,
|
||||||
|
boolean *pfhandled));
|
||||||
|
|
||||||
|
/* Prototypes for 'e' protocol functions. */
|
||||||
|
|
||||||
|
extern struct uuconf_cmdtab asEproto_params[];
|
||||||
|
extern boolean festart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean feshutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fesendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *zegetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean fesenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean fewait P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fefile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
|
||||||
|
boolean fstart, boolean fsend, long cbytes,
|
||||||
|
boolean *pfhandled));
|
||||||
|
|
||||||
|
/* Prototypes for 'i' protocol functions. */
|
||||||
|
|
||||||
|
extern struct uuconf_cmdtab asIproto_params[];
|
||||||
|
extern boolean fistart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean fishutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fisendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *zigetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean fisenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean fiwait P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Prototypes for 'j' protocol functions. The 'j' protocol mostly
|
||||||
|
uses the 'i' protocol functions, but it has a couple of functions
|
||||||
|
of its own. */
|
||||||
|
extern boolean fjstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean fjshutdown P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Prototypes for 'a' protocol functions (these use 'z' as the second
|
||||||
|
character because 'a' is a modified Zmodem protocol). */
|
||||||
|
extern struct uuconf_cmdtab asZproto_params[];
|
||||||
|
extern boolean fzstart P((struct sdaemon *qdaemon, char **pzlog));
|
||||||
|
extern boolean fzshutdown P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fzsendcmd P((struct sdaemon *qdaemon, const char *z,
|
||||||
|
int ilocal, int iremote));
|
||||||
|
extern char *zzgetspace P((struct sdaemon *qdaemon, size_t *pcdata));
|
||||||
|
extern boolean fzsenddata P((struct sdaemon *qdaemon, char *z, size_t c,
|
||||||
|
int ilocal, int iremote, long ipos));
|
||||||
|
extern boolean fzwait P((struct sdaemon *qdaemon));
|
||||||
|
extern boolean fzfile P((struct sdaemon *qdaemon, struct stransfer *qtrans,
|
||||||
|
boolean fstart, boolean fsend, long cbytes,
|
||||||
|
boolean *pfhandled));
|
530
gnu/libexec/uucp/common_sources/sysdep.h
Normal file
530
gnu/libexec/uucp/common_sources/sysdep.h
Normal file
@ -0,0 +1,530 @@
|
|||||||
|
/* sysh.unx -*- C -*-
|
||||||
|
The header file for the UNIX system dependent routines.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYSH_UNX_H
|
||||||
|
|
||||||
|
#define SYSH_UNX_H
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
/* These structures are used in prototypes but are not defined in this
|
||||||
|
header file. */
|
||||||
|
struct uuconf_system;
|
||||||
|
struct sconnection;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make sure the defines do not conflict. These are in this file
|
||||||
|
because they are Unix dependent. */
|
||||||
|
#if HAVE_V2_LOCKFILES + HAVE_HDB_LOCKFILES + HAVE_SCO_LOCKFILES + HAVE_SVR4_LOCKFILES + HAVE_COHERENT_LOCKFILES != 1
|
||||||
|
#error LOCKFILES define not set or duplicated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* SCO and SVR4 lockfiles are basically just like HDB lockfiles. */
|
||||||
|
#if HAVE_SCO_LOCKFILES || HAVE_SVR4_LOCKFILES
|
||||||
|
#undef HAVE_HDB_LOCKFILES
|
||||||
|
#define HAVE_HDB_LOCKFILES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS != 1
|
||||||
|
#error Terminal driver define not set or duplicated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SPOOLDIR_V2 + SPOOLDIR_BSD42 + SPOOLDIR_BSD43 + SPOOLDIR_HDB + SPOOLDIR_ULTRIX + SPOOLDIR_SVR4 + SPOOLDIR_TAYLOR != 1
|
||||||
|
#error Spool directory define not set or duplicated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If setreuid is broken, don't use it. */
|
||||||
|
#if HAVE_BROKEN_SETREUID
|
||||||
|
#undef HAVE_SETREUID
|
||||||
|
#define HAVE_SETREUID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get some standard types from the configuration header file. */
|
||||||
|
#ifdef PID_T
|
||||||
|
typedef PID_T pid_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UID_T
|
||||||
|
typedef UID_T uid_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GID_T
|
||||||
|
typedef GID_T gid_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OFF_T
|
||||||
|
typedef OFF_T off_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* On Unix, binary files are the same as text files. */
|
||||||
|
#define BINREAD "r"
|
||||||
|
#define BINWRITE "w"
|
||||||
|
|
||||||
|
/* If we have sigaction, we can force system calls to not be
|
||||||
|
restarted. */
|
||||||
|
#if HAVE_SIGACTION
|
||||||
|
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we have sigvec, and we have HAVE_SIGVEC_SV_FLAGS, and
|
||||||
|
SV_INTERRUPT is defined, we can force system calls to not be
|
||||||
|
restarted (signal.h is included by uucp.h before this point, so
|
||||||
|
SV_INTERRUPT will be defined by now if it it ever is). */
|
||||||
|
#if HAVE_SIGVEC && HAVE_SIGVEC_SV_FLAGS
|
||||||
|
#ifdef SV_INTERRUPT
|
||||||
|
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we were cross-configured, we will have a value of -1 for
|
||||||
|
HAVE_RESTARTABLE_SYSCALLS. In this case, we try to guess what the
|
||||||
|
correct value should be. Yuck. If we have sigvec, but neither of
|
||||||
|
the above cases applied (which we know because they would have
|
||||||
|
changed HAVE_RESTARTABLE_SYSCALLS) then we are probably on 4.2BSD
|
||||||
|
and system calls are automatically restarted. Otherwise, assume
|
||||||
|
that they are not. */
|
||||||
|
#if HAVE_RESTARTABLE_SYSCALLS == -1
|
||||||
|
#undef HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
#if HAVE_SIGVEC
|
||||||
|
#define HAVE_RESTARTABLE_SYSCALLS 1
|
||||||
|
#else
|
||||||
|
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||||||
|
#endif
|
||||||
|
#endif /* HAVE_RESTARTABLE_SYSCALLS == -1 */
|
||||||
|
|
||||||
|
/* We don't handle sigset in combination with restartable system
|
||||||
|
calls, so we check for it although this combination will never
|
||||||
|
happen. */
|
||||||
|
#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && HAVE_SIGSET
|
||||||
|
#if HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
#undef HAVE_SIGSET
|
||||||
|
#define HAVE_SIGSET 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we don't have restartable system calls, we can ignore
|
||||||
|
fsysdep_catch, usysdep_start_catch and usysdep_end_catch.
|
||||||
|
Otherwise fsysdep_catch has to do a setjmp. */
|
||||||
|
|
||||||
|
#if ! HAVE_RESTARTABLE_SYSCALLS
|
||||||
|
|
||||||
|
#define fsysdep_catch() (TRUE)
|
||||||
|
#define usysdep_start_catch()
|
||||||
|
#define usysdep_end_catch()
|
||||||
|
#define CATCH_PROTECT
|
||||||
|
|
||||||
|
#else /* HAVE_RESTARTABLE_SYSCALLS */
|
||||||
|
|
||||||
|
#if HAVE_SETRET && ! HAVE_SIGSETJMP
|
||||||
|
#include <setret.h>
|
||||||
|
#define setjmp setret
|
||||||
|
#define longjmp longret
|
||||||
|
#define jmp_buf ret_buf
|
||||||
|
#else /* ! HAVE_SETRET || HAVE_SIGSETJMP */
|
||||||
|
#include <setjmp.h>
|
||||||
|
#if HAVE_SIGSETJMP
|
||||||
|
#undef setjmp
|
||||||
|
#undef longjmp
|
||||||
|
#undef jmp_buf
|
||||||
|
#define setjmp(s) sigsetjmp ((s), TRUE)
|
||||||
|
#define longjmp siglongjmp
|
||||||
|
#define jmp_buf sigjmp_buf
|
||||||
|
#endif /* HAVE_SIGSETJMP */
|
||||||
|
#endif /* ! HAVE_SETRET || HAVE_SIGSETJMP */
|
||||||
|
|
||||||
|
extern volatile sig_atomic_t fSjmp;
|
||||||
|
extern volatile jmp_buf sSjmp_buf;
|
||||||
|
|
||||||
|
#define fsysdep_catch() (setjmp (sSjmp_buf) == 0)
|
||||||
|
|
||||||
|
#define usysdep_start_catch() (fSjmp = TRUE)
|
||||||
|
|
||||||
|
#define usysdep_end_catch() (fSjmp = FALSE)
|
||||||
|
|
||||||
|
#define CATCH_PROTECT volatile
|
||||||
|
|
||||||
|
#endif /* HAVE_RESTARTABLE_SYSCALLS */
|
||||||
|
|
||||||
|
/* Get definitions for the terminal driver. */
|
||||||
|
|
||||||
|
#if HAVE_BSD_TTY
|
||||||
|
#include <sgtty.h>
|
||||||
|
struct sbsd_terminal
|
||||||
|
{
|
||||||
|
struct sgttyb stty;
|
||||||
|
struct tchars stchars;
|
||||||
|
struct ltchars sltchars;
|
||||||
|
};
|
||||||
|
typedef struct sbsd_terminal sterminal;
|
||||||
|
#define fgetterminfo(o, q) \
|
||||||
|
(ioctl ((o), TIOCGETP, &(q)->stty) == 0 \
|
||||||
|
&& ioctl ((o), TIOCGETC, &(q)->stchars) == 0 \
|
||||||
|
&& ioctl ((o), TIOCGLTC, &(q)->sltchars) == 0)
|
||||||
|
#define fsetterminfo(o, q) \
|
||||||
|
(ioctl ((o), TIOCSETN, &(q)->stty) == 0 \
|
||||||
|
&& ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
|
||||||
|
&& ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
|
||||||
|
#define fsetterminfodrain(o, q) \
|
||||||
|
(ioctl ((o), TIOCSETP, &(q)->stty) == 0 \
|
||||||
|
&& ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
|
||||||
|
&& ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
|
||||||
|
#endif /* HAVE_BSD_TTY */
|
||||||
|
|
||||||
|
#if HAVE_SYSV_TERMIO
|
||||||
|
#include <termio.h>
|
||||||
|
typedef struct termio sterminal;
|
||||||
|
#define fgetterminfo(o, q) (ioctl ((o), TCGETA, (q)) == 0)
|
||||||
|
#define fsetterminfo(o, q) (ioctl ((o), TCSETA, (q)) == 0)
|
||||||
|
#define fsetterminfodrain(o, q) (ioctl ((o), TCSETAW, (q)) == 0)
|
||||||
|
#endif /* HAVE_SYSV_TERMIO */
|
||||||
|
|
||||||
|
#if HAVE_POSIX_TERMIOS
|
||||||
|
#include <termios.h>
|
||||||
|
typedef struct termios sterminal;
|
||||||
|
#define fgetterminfo(o, q) (tcgetattr ((o), (q)) == 0)
|
||||||
|
#define fsetterminfo(o, q) (tcsetattr ((o), TCSANOW, (q)) == 0)
|
||||||
|
#define fsetterminfodrain(o, q) (tcsetattr ((o), TCSADRAIN, (q)) == 0)
|
||||||
|
|
||||||
|
/* On some systems it is not possible to include both <sys/ioctl.h>
|
||||||
|
and <termios.h> in the same source files; I don't really know why.
|
||||||
|
On such systems, we pretend that we don't have <sys/ioctl.h>. */
|
||||||
|
#if ! HAVE_TERMIOS_AND_SYS_IOCTL_H
|
||||||
|
#undef HAVE_SYS_IOCTL_H
|
||||||
|
#define HAVE_SYS_IOCTL_H 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_POSIX_TERMIOS */
|
||||||
|
|
||||||
|
/* The root directory (this is needed by the system independent stuff
|
||||||
|
as the default for local-send). */
|
||||||
|
#define ZROOTDIR "/"
|
||||||
|
|
||||||
|
/* The name of the execution directory within the spool directory
|
||||||
|
(this is need by the system independent uuxqt.c). */
|
||||||
|
#define XQTDIR ".Xqtdir"
|
||||||
|
|
||||||
|
/* The name of the directory in which we preserve file transfers that
|
||||||
|
failed. */
|
||||||
|
#define PRESERVEDIR ".Preserve"
|
||||||
|
|
||||||
|
/* The length of the sequence number used in a file name. */
|
||||||
|
#define CSEQLEN (4)
|
||||||
|
|
||||||
|
/* Get some standard definitions. Avoid including the files more than
|
||||||
|
once--some might have been included by uucp.h. */
|
||||||
|
#if USE_STDIO && HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
#if ! USE_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
/* Get definitions for the file permission bits. */
|
||||||
|
|
||||||
|
#ifndef S_IRWXU
|
||||||
|
#define S_IRWXU 0700
|
||||||
|
#endif
|
||||||
|
#ifndef S_IRUSR
|
||||||
|
#define S_IRUSR 0400
|
||||||
|
#endif
|
||||||
|
#ifndef S_IWUSR
|
||||||
|
#define S_IWUSR 0200
|
||||||
|
#endif
|
||||||
|
#ifndef S_IXUSR
|
||||||
|
#define S_IXUSR 0100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef S_IRWXG
|
||||||
|
#define S_IRWXG 0070
|
||||||
|
#endif
|
||||||
|
#ifndef S_IRGRP
|
||||||
|
#define S_IRGRP 0040
|
||||||
|
#endif
|
||||||
|
#ifndef S_IWGRP
|
||||||
|
#define S_IWGRP 0020
|
||||||
|
#endif
|
||||||
|
#ifndef S_IXGRP
|
||||||
|
#define S_IXGRP 0010
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef S_IRWXO
|
||||||
|
#define S_IRWXO 0007
|
||||||
|
#endif
|
||||||
|
#ifndef S_IROTH
|
||||||
|
#define S_IROTH 0004
|
||||||
|
#endif
|
||||||
|
#ifndef S_IWOTH
|
||||||
|
#define S_IWOTH 0002
|
||||||
|
#endif
|
||||||
|
#ifndef S_IXOTH
|
||||||
|
#define S_IXOTH 0001
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
#ifdef S_IFDIR
|
||||||
|
#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
|
||||||
|
#else /* ! defined (S_IFDIR) */
|
||||||
|
#define S_ISDIR(i) (((i) & 0170000) == 040000)
|
||||||
|
#endif /* ! defined (S_IFDIR) */
|
||||||
|
#endif /* ! defined (S_ISDIR) */
|
||||||
|
|
||||||
|
/* We need the access macros. */
|
||||||
|
#ifndef R_OK
|
||||||
|
#define R_OK 4
|
||||||
|
#define W_OK 2
|
||||||
|
#define X_OK 1
|
||||||
|
#define F_OK 0
|
||||||
|
#endif /* ! defined (R_OK) */
|
||||||
|
|
||||||
|
/* We create files with these modes (should this be configurable?). */
|
||||||
|
#define IPRIVATE_FILE_MODE (S_IRUSR | S_IWUSR)
|
||||||
|
#define IPUBLIC_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
|
||||||
|
|
||||||
|
/* We create directories with this mode (should this be configurable?). */
|
||||||
|
#define IDIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
|
||||||
|
#define IPUBLIC_DIRECTORY_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
|
||||||
|
|
||||||
|
#if ! HAVE_OPENDIR
|
||||||
|
|
||||||
|
/* Define some structures to use if we don't have opendir, etc. These
|
||||||
|
will only work if we have the old Unix filesystem, with a 2 byte
|
||||||
|
inode and a 14 byte filename. */
|
||||||
|
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
struct dirent
|
||||||
|
{
|
||||||
|
char d_name[DIRSIZ + 1];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int o;
|
||||||
|
struct dirent s;
|
||||||
|
} DIR;
|
||||||
|
|
||||||
|
extern DIR *opendir P((const char *zdir));
|
||||||
|
extern struct dirent *readdir P((DIR *));
|
||||||
|
extern int closedir P((DIR *));
|
||||||
|
|
||||||
|
#endif /* ! HAVE_OPENDIR */
|
||||||
|
|
||||||
|
#if ! HAVE_FTW_H
|
||||||
|
|
||||||
|
/* If there is no <ftw.h>, define the ftw constants. */
|
||||||
|
|
||||||
|
#define FTW_F (0)
|
||||||
|
#define FTW_D (1)
|
||||||
|
#define FTW_DNR (2)
|
||||||
|
#define FTW_NS (3)
|
||||||
|
|
||||||
|
#endif /* ! HAVE_FTW_H */
|
||||||
|
|
||||||
|
/* This structure holds the system dependent information we keep for a
|
||||||
|
connection. This is used by the TCP and TLI code. */
|
||||||
|
|
||||||
|
struct ssysdep_conn
|
||||||
|
{
|
||||||
|
/* File descriptor. */
|
||||||
|
int o;
|
||||||
|
/* Device name. */
|
||||||
|
char *zdevice;
|
||||||
|
/* File status flags. */
|
||||||
|
int iflags;
|
||||||
|
/* File status flags for descriptor 1 (-1 if not standard input). */
|
||||||
|
int istdout_flags;
|
||||||
|
/* Hold the real descriptor when using a dialer device. */
|
||||||
|
int ohold;
|
||||||
|
/* TRUE if this is a terminal and the remaining fields are valid. */
|
||||||
|
boolean fterminal;
|
||||||
|
/* TRUE if this is a TLI descriptor. */
|
||||||
|
boolean ftli;
|
||||||
|
/* Baud rate. */
|
||||||
|
long ibaud;
|
||||||
|
/* Original terminal settings. */
|
||||||
|
sterminal sorig;
|
||||||
|
/* Current terminal settings. */
|
||||||
|
sterminal snew;
|
||||||
|
#if HAVE_COHERENT_LOCKFILES
|
||||||
|
/* On Coherent we need to hold on to the real port name which will
|
||||||
|
be used to enable the port. Ick. */
|
||||||
|
char *zenable;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* These functions do I/O and chat scripts to a port. They are called
|
||||||
|
by the TCP and TLI routines. */
|
||||||
|
extern boolean fsysdep_conn_read P((struct sconnection *qconn,
|
||||||
|
char *zbuf, size_t *pclen,
|
||||||
|
size_t cmin, int ctimeout,
|
||||||
|
boolean freport));
|
||||||
|
extern boolean fsysdep_conn_write P((struct sconnection *qconn,
|
||||||
|
const char *zbuf, size_t clen));
|
||||||
|
extern boolean fsysdep_conn_io P((struct sconnection *qconn,
|
||||||
|
const char *zwrite, size_t *pcwrite,
|
||||||
|
char *zread, size_t *pcread));
|
||||||
|
extern boolean fsysdep_conn_chat P((struct sconnection *qconn,
|
||||||
|
char **pzprog));
|
||||||
|
|
||||||
|
/* Set a signal handler. */
|
||||||
|
extern void usset_signal P((int isig, RETSIGTYPE (*pfn) P((int)),
|
||||||
|
boolean fforce, boolean *pfignored));
|
||||||
|
|
||||||
|
/* Default signal handler. This sets the appropriate element of the
|
||||||
|
afSignal array. If system calls are automatically restarted, it
|
||||||
|
may do a longjmp to an fsysdep_catch. */
|
||||||
|
extern RETSIGTYPE ussignal P((int isig));
|
||||||
|
|
||||||
|
/* Try to fork, repeating several times. */
|
||||||
|
extern pid_t ixsfork P((void));
|
||||||
|
|
||||||
|
/* Spawn a job. Returns the process ID of the spawned job or -1 on
|
||||||
|
error. The following macros may be passed in aidescs. */
|
||||||
|
|
||||||
|
/* Set descriptor to /dev/null. */
|
||||||
|
#define SPAWN_NULL (-1)
|
||||||
|
/* Set element of aidescs to a pipe for caller to read from. */
|
||||||
|
#define SPAWN_READ_PIPE (-2)
|
||||||
|
/* Set element of aidescs to a pipe for caller to write to. */
|
||||||
|
#define SPAWN_WRITE_PIPE (-3)
|
||||||
|
|
||||||
|
extern pid_t ixsspawn P((const char **pazargs, int *aidescs,
|
||||||
|
boolean fkeepuid, boolean fkeepenv,
|
||||||
|
const char *zchdir, boolean fnosigs,
|
||||||
|
boolean fshell, const char *zpath,
|
||||||
|
const char *zuu_machine,
|
||||||
|
const char *zuu_user));
|
||||||
|
|
||||||
|
/* Do a form of popen using ixsspawn. */
|
||||||
|
extern FILE *espopen P((const char **pazargs, boolean frd,
|
||||||
|
pid_t *pipid));
|
||||||
|
|
||||||
|
/* Wait for a particular process to finish, returning the exit status.
|
||||||
|
The process ID should be pid_t, but we can't put that in a
|
||||||
|
prototype. */
|
||||||
|
extern int ixswait P((unsigned long ipid, const char *zreport));
|
||||||
|
|
||||||
|
/* Find a spool file in the spool directory. For a local file, the
|
||||||
|
bgrade argument is the grade of the file. This is needed for
|
||||||
|
SPOOLDIR_SVR4. */
|
||||||
|
extern char *zsfind_file P((const char *zsimple, const char *zsystem,
|
||||||
|
int bgrade));
|
||||||
|
|
||||||
|
/* Return the grade given a sequence number. */
|
||||||
|
extern char bsgrade P((pointer pseq));
|
||||||
|
|
||||||
|
/* Lock a string. */
|
||||||
|
extern boolean fsdo_lock P((const char *, boolean fspooldir,
|
||||||
|
boolean *pferr));
|
||||||
|
|
||||||
|
/* Unlock a string. */
|
||||||
|
extern boolean fsdo_unlock P((const char *, boolean fspooldir));
|
||||||
|
|
||||||
|
/* Check access for a particular user name, or NULL to check access
|
||||||
|
for any user. */
|
||||||
|
extern boolean fsuser_access P((const struct stat *, int imode,
|
||||||
|
const char *zuser));
|
||||||
|
|
||||||
|
/* Stick two directories and a file name together. */
|
||||||
|
extern char *zsappend3 P((const char *zdir1, const char *zdir2,
|
||||||
|
const char *zfile));
|
||||||
|
|
||||||
|
/* Stick three directories and a file name together. */
|
||||||
|
extern char *zsappend4 P((const char *zdir1, const char *zdir2,
|
||||||
|
const char *zdir3, const char *zfile));
|
||||||
|
|
||||||
|
/* Get a temporary file name. */
|
||||||
|
extern char *zstemp_file P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Get a command file name. */
|
||||||
|
extern char *zscmd_file P((const struct uuconf_system *qsys, int bgrade));
|
||||||
|
|
||||||
|
/* Get a jobid from a system, a file name, and a grade. */
|
||||||
|
extern char *zsfile_to_jobid P((const struct uuconf_system *qsys,
|
||||||
|
const char *zfile,
|
||||||
|
int bgrade));
|
||||||
|
|
||||||
|
/* Get a file name from a jobid. This also returns the associated system
|
||||||
|
in *pzsystem and the grade in *pbgrade. */
|
||||||
|
extern char *zsjobid_to_file P((const char *zid, char **pzsystem,
|
||||||
|
char *pbgrade));
|
||||||
|
|
||||||
|
/* See whether there is a spool directory for a system when using
|
||||||
|
SPOOLDIR_ULTRIX. */
|
||||||
|
extern boolean fsultrix_has_spool P((const char *zsystem));
|
||||||
|
|
||||||
|
#if HAVE_COHERENT_LOCKFILES
|
||||||
|
/* Lock a coherent tty. */
|
||||||
|
extern boolean lockttyexist P((const char *z));
|
||||||
|
extern boolean fscoherent_disable_tty P((const char *zdevice,
|
||||||
|
char **pzenable));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Some replacements for standard Unix functions. */
|
||||||
|
|
||||||
|
#if ! HAVE_DUP2
|
||||||
|
extern int dup2 P((int oold, int onew));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_FTW
|
||||||
|
extern int ftw P((const char *zdir,
|
||||||
|
int (*pfn) P((const char *zfile,
|
||||||
|
const struct stat *qstat,
|
||||||
|
int iflag)),
|
||||||
|
int cdescriptors));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_GETCWD && ! HAVE_GETWD
|
||||||
|
extern char *getcwd P((char *zbuf, size_t cbuf));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_MKDIR
|
||||||
|
extern int mkdir P((const char *zdir, int imode));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_RENAME
|
||||||
|
extern int rename P((const char *zold, const char *znew));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_RMDIR
|
||||||
|
extern int rmdir P((const char *zdir));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The working directory from which the program was run (this is set
|
||||||
|
by usysdep_initialize if called with INIT_GETCWD). */
|
||||||
|
extern char *zScwd;
|
||||||
|
|
||||||
|
/* The spool directory name. */
|
||||||
|
extern const char *zSspooldir;
|
||||||
|
|
||||||
|
/* The lock directory name. */
|
||||||
|
extern const char *zSlockdir;
|
||||||
|
|
||||||
|
/* The local UUCP name (needed for some spool directory stuff). */
|
||||||
|
extern const char *zSlocalname;
|
||||||
|
|
||||||
|
#endif /* ! defined (SYSH_UNX_H) */
|
950
gnu/libexec/uucp/common_sources/system.h
Normal file
950
gnu/libexec/uucp/common_sources/system.h
Normal file
@ -0,0 +1,950 @@
|
|||||||
|
/* system.h
|
||||||
|
Header file for system dependent stuff in the Taylor UUCP package.
|
||||||
|
This file is not itself system dependent.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYSTEM_H
|
||||||
|
|
||||||
|
#define SYSTEM_H
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
/* These structures are used in prototypes but are not defined in this
|
||||||
|
header file. */
|
||||||
|
struct tm;
|
||||||
|
struct uuconf_system;
|
||||||
|
struct uuconf_port;
|
||||||
|
struct sconnection;
|
||||||
|
struct sstatus;
|
||||||
|
struct scmd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Any function which returns an error should also report an error
|
||||||
|
message, unless otherwise indicated.
|
||||||
|
|
||||||
|
Any function that returns a char *, rather than a const char *, is
|
||||||
|
returning a pointer to a buffer allocated by zbufalc which must be
|
||||||
|
freed using ubuffree, unless otherwise indicated. */
|
||||||
|
|
||||||
|
/* The maximum length of a remote system name. */
|
||||||
|
extern size_t cSysdep_max_name_len;
|
||||||
|
|
||||||
|
/* Initialize. If something goes wrong, this routine should just
|
||||||
|
exit. The flag argument is 0, or a combination of any of the
|
||||||
|
following flags. */
|
||||||
|
|
||||||
|
/* This program needs to know the current working directory. This is
|
||||||
|
used because on Unix it can be expensive to determine the current
|
||||||
|
working directory (some versions of getcwd fork a process), but in
|
||||||
|
most cases we don't need to know it. However, we are going to
|
||||||
|
chdir to the spool directory (unless INIT_CHDIR is set), so we have
|
||||||
|
to get the cwd now if we are ever going to get it. Both uucp and
|
||||||
|
uux use the function fsysdep_needs_cwd to determine whether they
|
||||||
|
will need the current working directory, and pass the argument to
|
||||||
|
usysdep_initialize appropriately. There's probably a cleaner way
|
||||||
|
to handle this, but this will suffice for now. */
|
||||||
|
#define INIT_GETCWD (01)
|
||||||
|
|
||||||
|
/* This program should not chdir to the spool directory. This may
|
||||||
|
only make sense on Unix. It is set by cu. */
|
||||||
|
#define INIT_NOCHDIR (02)
|
||||||
|
|
||||||
|
/* This program needs special access to the spool directories. That
|
||||||
|
means, on Unix, this program is normally installed setuid. */
|
||||||
|
#define INIT_SUID (04)
|
||||||
|
|
||||||
|
extern void usysdep_initialize P((pointer puuconf, int iflags));
|
||||||
|
|
||||||
|
/* Exit the program. The fsuccess argument indicates whether to
|
||||||
|
return an indication of success or failure to the outer
|
||||||
|
environment. This routine should not return. */
|
||||||
|
extern void usysdep_exit P((boolean fsuccess));
|
||||||
|
|
||||||
|
/* Called when a non-standard configuration file is being used, to
|
||||||
|
avoid handing out privileged access. If it returns FALSE, default
|
||||||
|
configuration file will be used. This is called before the
|
||||||
|
usysdep_initialize function is called. */
|
||||||
|
extern boolean fsysdep_other_config P((const char *));
|
||||||
|
|
||||||
|
/* Detach from the controlling terminal. This probably only makes
|
||||||
|
sense on Unix. It is called by uucico to try to get the modem port
|
||||||
|
as a controlling terminal. It is also called by uucico before it
|
||||||
|
starts up uuxqt, so that uuxqt will be a complete daemon. */
|
||||||
|
extern void usysdep_detach P((void));
|
||||||
|
|
||||||
|
/* Get the local node name if it is not specified in the configuration
|
||||||
|
files. Returns NULL on error; otherwise the return value should
|
||||||
|
point to a static buffer. */
|
||||||
|
extern const char *zsysdep_localname P((void));
|
||||||
|
|
||||||
|
/* Get the login name. This is used when uucico is started up with no
|
||||||
|
arguments in slave mode, which causes it to assume that somebody
|
||||||
|
has logged in. It also used by uucp and uux for recording the user
|
||||||
|
name. This may not return NULL. The return value should point to
|
||||||
|
a static buffer. */
|
||||||
|
extern const char *zsysdep_login_name P((void));
|
||||||
|
|
||||||
|
/* Set a signal handler for a signal. If the signal occurs, the
|
||||||
|
appropriate element of afSignal should be set to the signal number
|
||||||
|
(see the declaration of afSignal in uucp.h). This routine might be
|
||||||
|
able to just use signal, but Unix requires more complex handling.
|
||||||
|
This is called before usysdep_initialize. */
|
||||||
|
extern void usysdep_signal P((int isig));
|
||||||
|
|
||||||
|
/* Catch a signal. This is actually defined as a macro in the system
|
||||||
|
dependent header file, and the prototype here just indicates how it
|
||||||
|
should be called. It is called before a routine which must exit if
|
||||||
|
a signal occurs, and is expected to set do a setjmp (which is why
|
||||||
|
it must be a macro). It is actually only called in one place in
|
||||||
|
the system independent code, before the call to read stdin in uux.
|
||||||
|
This is needed to handle 4.2 BSD restartable system calls, which
|
||||||
|
require a longjmp. On systems which don't need to do
|
||||||
|
setjmp/longjmp around system calls, this can be redefined in
|
||||||
|
sysdep.h to TRUE. It should return TRUE if the routine should
|
||||||
|
proceed, or FALSE if a signal occurred. After having this return
|
||||||
|
TRUE, usysdep_start_catch should be used to start catching the
|
||||||
|
signal; this basically tells the signal handler that it's OK to do
|
||||||
|
the longjmp, if fsysdep_catch did not already do so. */
|
||||||
|
#ifndef fsysdep_catch
|
||||||
|
extern boolean fsysdep_catch P((void));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Start catching a signal. This is called after fsysdep_catch to
|
||||||
|
tell the signal handler to go ahead and do the longjmp. This may
|
||||||
|
be implemented as a macro in sysdep.h. */
|
||||||
|
#ifndef usysdep_start_catch
|
||||||
|
extern void usysdep_start_catch P((void));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Stop catching a signal. This is called when it is no longer
|
||||||
|
necessary for fsysdep_catch to handle signals. This may be
|
||||||
|
implemented as a macro in sysdep.h. */
|
||||||
|
#ifndef usysdep_end_catch
|
||||||
|
extern void usysdep_end_catch P((void));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Link two files. On Unix this should attempt the link. If it
|
||||||
|
succeeds it should return TRUE with *pfworked set to TRUE. If the
|
||||||
|
link fails because it must go across a device, it should return
|
||||||
|
TRUE with *pfworked set to FALSE. If the link fails for some other
|
||||||
|
reason, it should log an error message and return FALSE. On a
|
||||||
|
system which does not support links to files, this should just
|
||||||
|
return TRUE with *pfworked set to FALSE. */
|
||||||
|
extern boolean fsysdep_link P((const char *zfrom, const char *zto,
|
||||||
|
boolean *pfworked));
|
||||||
|
|
||||||
|
/* Get the port name. This is used when uucico is started up in slave
|
||||||
|
mode to figure out which port was used to call in so that it can
|
||||||
|
determine any appropriate protocol parameters. This may return
|
||||||
|
NULL if the port cannot be determined, which will just mean that no
|
||||||
|
protocol parameters are applied. The name returned should be the
|
||||||
|
sort of name that would appear in the port file. This should set
|
||||||
|
*pftcp_port to TRUE if it can determine that the port is a TCP
|
||||||
|
connection rather than a normal serial port. The return value (if
|
||||||
|
not NULL) should point to a static buffer. */
|
||||||
|
extern const char *zsysdep_port_name P((boolean *pftcp_port));
|
||||||
|
|
||||||
|
/* Expand a file name on the local system. On Unix, if the zfile
|
||||||
|
argument begins with ~user/ it goes in that users home directory,
|
||||||
|
and if it begins with ~/ it goes in the public directory (the
|
||||||
|
public directory is passed to this routine, since each system may
|
||||||
|
have its own public directory). Similar conventions may be
|
||||||
|
desirable on other systems. This should always return an absolute
|
||||||
|
path name, probably in the public directory. It should return NULL
|
||||||
|
on error; otherwise the return value should be allocated using
|
||||||
|
zbufcpy or zbufalc. */
|
||||||
|
extern char *zsysdep_local_file P((const char *zname,
|
||||||
|
const char *zpubdir));
|
||||||
|
|
||||||
|
/* Return whether a file name is in a directory, and check for read or
|
||||||
|
write access. This should check whether zfile is within zdir (or
|
||||||
|
is zdir itself). If it is not, it should return FALSE. If zfile
|
||||||
|
is in zdir, then fcheck indicates whether further checking should
|
||||||
|
be done. If fcheck is FALSE, no further checking is done.
|
||||||
|
Otherwise, if freadable is TRUE the user zuser should have search
|
||||||
|
access to all directories from zdir down to zfile and should have
|
||||||
|
read access on zfile itself (if zfile does not exist, or is not a
|
||||||
|
regular file, this function may return FALSE but does not have to).
|
||||||
|
If freadable is FALSE, the user zuser should have search access to
|
||||||
|
all directories from zdir down to zfile and should have write
|
||||||
|
access on zfile (which may be a directory, or may not actually
|
||||||
|
exist, which is acceptable). The zuser argument may be NULL, in
|
||||||
|
which case the check should be made for any user, not just zuser.
|
||||||
|
There is no way for this function to return error. */
|
||||||
|
extern boolean fsysdep_in_directory P((const char *zfile,
|
||||||
|
const char *zdir,
|
||||||
|
boolean fcheck,
|
||||||
|
boolean freadable,
|
||||||
|
const char *zuser));
|
||||||
|
|
||||||
|
/* Return TRUE if a file exists, FALSE otherwise. There is no way to
|
||||||
|
return error. */
|
||||||
|
extern boolean fsysdep_file_exists P((const char *zfile));
|
||||||
|
|
||||||
|
/* Start up a program. The code expects fsysdep_run to return after
|
||||||
|
doing a fork, but at least for now everything will work fine if it
|
||||||
|
does not (on a system which does not support forking). The three
|
||||||
|
string arguments may be catenated together to form the program to
|
||||||
|
execute; I did it this way to make it easy to call execl(2), and
|
||||||
|
because I never needed more than two arguments. The program will
|
||||||
|
always be "uucico" or "uuxqt". The return value will be passed
|
||||||
|
directly to usysdep_exit, and should be TRUE on success, FALSE on
|
||||||
|
error. */
|
||||||
|
extern boolean fsysdep_run P((const char *zprogram, const char *zarg1,
|
||||||
|
const char *zarg2));
|
||||||
|
|
||||||
|
/* Send a mail message. This function will be passed an array of
|
||||||
|
strings. All necessary newlines are already included; the strings
|
||||||
|
should simply be concatenated together to form the mail message.
|
||||||
|
It should return FALSE on error, although the return value is often
|
||||||
|
ignored. */
|
||||||
|
extern boolean fsysdep_mail P((const char *zto, const char *zsubject,
|
||||||
|
int cstrs, const char **paz));
|
||||||
|
|
||||||
|
/* Get the time in seconds since some epoch. The actual epoch is
|
||||||
|
unimportant, so long as the time values are consistent across
|
||||||
|
program executions and the value is never negative. If the
|
||||||
|
pimicros argument is not NULL, it should be set to the number of
|
||||||
|
microseconds (if this is not available, *pimicros should be set to
|
||||||
|
zero). */
|
||||||
|
extern long ixsysdep_time P((long *pimicros));
|
||||||
|
|
||||||
|
/* Get the time in seconds and microseconds (millionths of a second)
|
||||||
|
since some epoch. The actual epoch is not important, and it may
|
||||||
|
change in between program invocations; this is provided because on
|
||||||
|
Unix the times function may be used. If microseconds can not be
|
||||||
|
determined, *pimicros can just be set to zero. */
|
||||||
|
extern long ixsysdep_process_time P((long *pimicros));
|
||||||
|
|
||||||
|
/* Parse the value returned by ixsysdep_time into a struct tm. I
|
||||||
|
assume that this structure is defined in <time.h>. This is
|
||||||
|
basically just localtime, except that the ANSI function takes a
|
||||||
|
time_t which may not be what is returned by ixsysdep_time. */
|
||||||
|
extern void usysdep_localtime P((long itime, struct tm *q));
|
||||||
|
|
||||||
|
/* Sleep for a number of seconds. */
|
||||||
|
extern void usysdep_sleep P((int cseconds));
|
||||||
|
|
||||||
|
/* Pause for half a second, or 1 second if subsecond sleeps are not
|
||||||
|
possible. */
|
||||||
|
extern void usysdep_pause P((void));
|
||||||
|
|
||||||
|
/* Lock a remote system. This should return FALSE if the system is
|
||||||
|
already locked (no error should be reported). */
|
||||||
|
extern boolean fsysdep_lock_system P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Unlock a remote system. This should return FALSE on error
|
||||||
|
(although the return value is generally ignored). */
|
||||||
|
extern boolean fsysdep_unlock_system P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Get the conversation sequence number for a remote system, and
|
||||||
|
increment it for next time. This should return -1 on error. */
|
||||||
|
extern long ixsysdep_get_sequence P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Get the status of a remote system. This should return FALSE on
|
||||||
|
error. Otherwise it should set *qret to the status. If no status
|
||||||
|
information is available, this should set *qret to sensible values
|
||||||
|
and return TRUE. If pfnone is not NULL, then it should be set to
|
||||||
|
TRUE if no status information was available or FALSE otherwise. */
|
||||||
|
extern boolean fsysdep_get_status P((const struct uuconf_system *qsys,
|
||||||
|
struct sstatus *qret,
|
||||||
|
boolean *pfnone));
|
||||||
|
|
||||||
|
/* Set the status of a remote system. This should return FALSE on
|
||||||
|
error. The system will be locked before this call is made. */
|
||||||
|
extern boolean fsysdep_set_status P((const struct uuconf_system *qsys,
|
||||||
|
const struct sstatus *qset));
|
||||||
|
|
||||||
|
/* See whether a remote system is permitted to log in. This is just
|
||||||
|
to support the remote.unknown shell script for HDB. The zscript
|
||||||
|
argument is the script name, as return by uuconf_remote_unknown.
|
||||||
|
The zsystem argument is the name given by the remote system. If
|
||||||
|
the system is not permitted to log in, this function should log an
|
||||||
|
error and return FALSE. */
|
||||||
|
extern boolean fsysdep_unknown_caller P((const char *zscript,
|
||||||
|
const char *zsystem));
|
||||||
|
|
||||||
|
/* Check whether there is work for a remote system. It should return
|
||||||
|
TRUE if there is work, FALSE otherwise; there is no way to indicate
|
||||||
|
an error. */
|
||||||
|
extern boolean fsysdep_has_work P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Initialize the work scan. This will be called before
|
||||||
|
fsysdep_get_work. The bgrade argument is the minimum grade of
|
||||||
|
execution files that should be considered (e.g. a bgrade of 'd'
|
||||||
|
will allow all grades from 'A' to 'Z' and 'a' to 'd'). This
|
||||||
|
function should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_get_work_init P((const struct uuconf_system *qsys,
|
||||||
|
int bgrade));
|
||||||
|
|
||||||
|
/* Get the next command to be executed for a remote system. The
|
||||||
|
bgrade argument will be the same as for fsysdep_get_work_init;
|
||||||
|
probably only one of these functions will use it, namely the
|
||||||
|
function for which it is more convenient. This should return FALSE
|
||||||
|
on error. The structure pointed to by qcmd should be filled in.
|
||||||
|
The strings may point into a static buffer; they will be copied out
|
||||||
|
if necessary. If there is no more work, this should set qcmd->bcmd
|
||||||
|
to 'H' and return TRUE. This should set qcmd->pseq to something
|
||||||
|
which can be passed to fsysdep_did_work to remove the job from the
|
||||||
|
queue when it has been completed. This may set qcmd->bcmd to 'P'
|
||||||
|
to represent a poll file; the main code will just pass the pseq
|
||||||
|
element of such a structure to fsysdep_did_work if the system is
|
||||||
|
called. */
|
||||||
|
extern boolean fsysdep_get_work P((const struct uuconf_system *qsys,
|
||||||
|
int bgrade, struct scmd *qcmd));
|
||||||
|
|
||||||
|
/* Remove a job from the work queue. This must also remove the
|
||||||
|
temporary file used for a send command, if there is one. It should
|
||||||
|
return FALSE on error. */
|
||||||
|
extern boolean fsysdep_did_work P((pointer pseq));
|
||||||
|
|
||||||
|
/* Save the temporary file for a send command. This function should
|
||||||
|
return a string that will be put into a mail message. On success
|
||||||
|
this string should say something like ``The file has been saved as
|
||||||
|
...''. On failure it could say something like ``The file could not
|
||||||
|
be saved because ...''. If there is no temporary file, or for some
|
||||||
|
reason it's not appropriate to include a message, this function
|
||||||
|
should just return NULL. This function is used when a file send
|
||||||
|
fails for some reason, to make sure that we don't completely lost
|
||||||
|
the file. */
|
||||||
|
extern const char *zsysdep_save_temp_file P((pointer pseq));
|
||||||
|
|
||||||
|
/* Cleanup anything left over by fsysdep_get_work_init and
|
||||||
|
fsysdep_get_work. This may be called even though
|
||||||
|
fsysdep_get_work_init has not been. */
|
||||||
|
extern void usysdep_get_work_free P((const struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* Add a base name to a file if it is a directory. If zfile names a
|
||||||
|
directory, then return a string naming a file within the directory
|
||||||
|
with the base file name of zname. This should return NULL on
|
||||||
|
error. */
|
||||||
|
extern char *zsysdep_add_base P((const char *zfile,
|
||||||
|
const char *zname));
|
||||||
|
|
||||||
|
/* Get a file name from the spool directory. This should return NULL
|
||||||
|
on error. The pseq argument is TRUE if the file was found from
|
||||||
|
searching the work directory; this is, unfortunately, needed to
|
||||||
|
support SVR4 spool directories. */
|
||||||
|
extern char *zsysdep_spool_file_name P((const struct uuconf_system *qsys,
|
||||||
|
const char *zfile,
|
||||||
|
pointer pseq));
|
||||||
|
|
||||||
|
/* Make necessary directories. This should create all non-existent
|
||||||
|
directories for a file. If the fpublic argument is TRUE, anybody
|
||||||
|
should be permitted to create and remove files in the directory;
|
||||||
|
otherwise anybody can list the directory, but only the UUCP system
|
||||||
|
can create and remove files. It should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_make_dirs P((const char *zfile, boolean fpublic));
|
||||||
|
|
||||||
|
/* Create a stdio file, setting appropriate protection. If the
|
||||||
|
fpublic argument is TRUE, the file is made publically accessible;
|
||||||
|
otherwise it is treated as a private data file. If the fappend
|
||||||
|
argument is TRUE, the file is opened in append mode; otherwise any
|
||||||
|
previously existing file of the same name is removed. If the
|
||||||
|
fmkdirs argument is TRUE, then any necessary directories should
|
||||||
|
also be created. On a system in which file protections are
|
||||||
|
unimportant and the necessary directories exist, this may be
|
||||||
|
implemented as
|
||||||
|
|
||||||
|
fopen (zfile, fappend ? "a" : "w");
|
||||||
|
|
||||||
|
*/
|
||||||
|
extern FILE *esysdep_fopen P((const char *zfile, boolean fpublic,
|
||||||
|
boolean fappend, boolean fmkdirs));
|
||||||
|
|
||||||
|
/* Open a file, using the access permission of the user who invoked
|
||||||
|
the program. The frd argument is TRUE if the file should be opened
|
||||||
|
for reading, and the fbinary argument is TRUE if the file should be
|
||||||
|
opened as a binary file (this is ignored on Unix, since there all
|
||||||
|
files are binary files). This returns an openfile_t, not a FILE *.
|
||||||
|
This is supposed to be able to open a file even if it can not be
|
||||||
|
read by the uucp user. This is not possible on some older Unix
|
||||||
|
systems. */
|
||||||
|
extern openfile_t esysdep_user_fopen P((const char *zfile,
|
||||||
|
boolean frd, boolean fbinary));
|
||||||
|
|
||||||
|
/* Open a file to send to another system; the qsys argument is the
|
||||||
|
system the file is being sent to. If fcheck is TRUE, it should
|
||||||
|
make sure that the file is readable by zuser (if zuser is NULL the
|
||||||
|
file must be readable by anybody). This is to eliminate a window
|
||||||
|
between fsysdep_in_directory and esysdep_open_send. If an error
|
||||||
|
occurs, it should return EFILECLOSED. */
|
||||||
|
extern openfile_t esysdep_open_send P((const struct uuconf_system *qsys,
|
||||||
|
const char *zname,
|
||||||
|
boolean fcheck,
|
||||||
|
const char *zuser));
|
||||||
|
|
||||||
|
/* Return a temporary file name to receive into. This file will be
|
||||||
|
opened by esysdep_open_receive. The qsys argument is the system
|
||||||
|
the file is coming from, the zto argument is the name the file will
|
||||||
|
have after it has been fully received, and the ztemp argument, if
|
||||||
|
it is not NULL, is from the command sent by the remote system. The
|
||||||
|
return value must be freed using ubuffree. The function should
|
||||||
|
return NULL on error. */
|
||||||
|
extern char *zsysdep_receive_temp P((const struct uuconf_system *qsys,
|
||||||
|
const char *zfile,
|
||||||
|
const char *ztemp));
|
||||||
|
|
||||||
|
/* Open a file to receive from another system. The zreceive argument
|
||||||
|
is the return value of zsysdep_receive_temp with the same qsys,
|
||||||
|
zfile and ztemp arguments. If the function can determine that this
|
||||||
|
file has already been partially received, it should set *pcrestart
|
||||||
|
to the number of bytes that have been received. If the file has
|
||||||
|
not been partially received, *pcrestart should be set to -1. The
|
||||||
|
function should return EFILECLOSED on error. After the file is
|
||||||
|
written, fsysdep_move_file will be called to move the file to its
|
||||||
|
final destination, and to set the correct file mode. */
|
||||||
|
extern openfile_t esysdep_open_receive P((const struct uuconf_system *qsys,
|
||||||
|
const char *zto,
|
||||||
|
const char *ztemp,
|
||||||
|
const char *zreceive,
|
||||||
|
long *pcrestart));
|
||||||
|
|
||||||
|
/* Move a file. This is used to move a received file to its final
|
||||||
|
location. The zto argument is the file to create. The zorig
|
||||||
|
argument is the name of the file to move. If fmkdirs is TRUE, then
|
||||||
|
any necessary directories are created; fpublic indicates whether
|
||||||
|
they should be publically writeable or not. If fcheck is TRUE,
|
||||||
|
this should make sure the directory is writeable by the user zuser
|
||||||
|
(if zuser is NULL, then it must be writeable by any user); this is
|
||||||
|
to avoid a window of vulnerability between fsysdep_in_directory and
|
||||||
|
fsysdep_move_file. This function should return FALSE on error; the
|
||||||
|
zorig file should be removed even if an error occurs. */
|
||||||
|
extern boolean fsysdep_move_file P((const char *zorig, const char *zto,
|
||||||
|
boolean fmkdirs, boolean fpublic,
|
||||||
|
boolean fcheck, const char *zuser));
|
||||||
|
|
||||||
|
/* Change the mode of a file. The imode argument is a Unix mode.
|
||||||
|
This should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_change_mode P((const char *zfile,
|
||||||
|
unsigned int imode));
|
||||||
|
|
||||||
|
/* Truncate a file which we are receiving into. This may be done by
|
||||||
|
closing the original file, removing it and reopening it. This
|
||||||
|
should return FALSE on error. */
|
||||||
|
extern openfile_t esysdep_truncate P((openfile_t e, const char *zname));
|
||||||
|
|
||||||
|
/* It is possible for the acknowledgement of a received file to be
|
||||||
|
lost. The sending system will then now know that the file was
|
||||||
|
correctly received, and will send it again. This can be a problem
|
||||||
|
particularly with protocols which support channels, since they may
|
||||||
|
send several small files in a single window, all of which may be
|
||||||
|
received correctly although the sending system never sees the
|
||||||
|
acknowledgement. If these files involve an execution, the
|
||||||
|
execution will happen twice, which will be bad.
|
||||||
|
|
||||||
|
This function is called when a file is completely received. It is
|
||||||
|
supposed to try and remember the reception, in case the connection
|
||||||
|
is lost. It is passed the system, the file name to receive to, and
|
||||||
|
the temporary file name from the sending system. It should return
|
||||||
|
FALSE on error. */
|
||||||
|
extern boolean fsysdep_remember_reception P((const struct uuconf_system *qsys,
|
||||||
|
const char *zto,
|
||||||
|
const char *ztemp));
|
||||||
|
|
||||||
|
/* This function is called to see if a file has already been received
|
||||||
|
successfully. It gets the same arguments as
|
||||||
|
fsysdep_remember_reception. It should return TRUE if the file was
|
||||||
|
already received, FALSE otherwise. There is no way to report
|
||||||
|
error. */
|
||||||
|
extern boolean fsysdep_already_received P((const struct uuconf_system *qsys,
|
||||||
|
const char *zto,
|
||||||
|
const char *ztemp));
|
||||||
|
|
||||||
|
/* This function is called when it is no longer necessary to remember
|
||||||
|
that a file has been received. This will be called when the
|
||||||
|
protocol knows that the receive message has been acknowledged. It
|
||||||
|
gets the same arguments as fsysdep_remember_reception. it should
|
||||||
|
return FALSE on error. */
|
||||||
|
extern boolean fsysdep_forget_reception P((const struct uuconf_system *qsys,
|
||||||
|
const char *zto,
|
||||||
|
const char *ztemp));
|
||||||
|
|
||||||
|
/* Start expanding a wildcarded file name. This should return FALSE
|
||||||
|
on error; otherwise subsequent calls to zsysdep_wildcard should
|
||||||
|
return file names. */
|
||||||
|
extern boolean fsysdep_wildcard_start P((const char *zfile));
|
||||||
|
|
||||||
|
/* Get the next wildcard name. This should return NULL when there are
|
||||||
|
no more names to return. The return value should be freed using
|
||||||
|
ubuffree. The argument should be the same as that to
|
||||||
|
fsysdep_wildcard_start. There is no way to return error. */
|
||||||
|
extern char *zsysdep_wildcard P((const char *zfile));
|
||||||
|
|
||||||
|
/* Finish getting wildcard names. This may be called before or after
|
||||||
|
zsysdep_wildcard has returned NULL. It should return FALSE on
|
||||||
|
error. */
|
||||||
|
extern boolean fsysdep_wildcard_end P((void));
|
||||||
|
|
||||||
|
/* Prepare to execute a bunch of file transfer requests. This should
|
||||||
|
make an entry in the spool directory so that the next time uucico
|
||||||
|
is started up it will transfer these files. The bgrade argument
|
||||||
|
specifies the grade of the commands. The commands themselves are
|
||||||
|
in the pascmds array, which has ccmds entries. The function should
|
||||||
|
return NULL on error, or the jobid on success. The jobid is a
|
||||||
|
string that may be printed or passed to fsysdep_kill_job and
|
||||||
|
related functions, but is otherwise uninterpreted. */
|
||||||
|
extern char *zsysdep_spool_commands P((const struct uuconf_system *qsys,
|
||||||
|
int bgrade, int ccmds,
|
||||||
|
const struct scmd *pascmds));
|
||||||
|
|
||||||
|
/* Get a file name to use for a data file to be copied to another
|
||||||
|
system. The ztname, zdname and zxname arguments will all either be
|
||||||
|
NULL or point to an array of CFILE_NAME_LEN characters in length.
|
||||||
|
The ztname array should be set to a temporary file name that could
|
||||||
|
be passed to zsysdep_spool_file_name to retrieve the return value
|
||||||
|
of this function; this will be appropriate for the temporary name
|
||||||
|
in a send request. The zdname array should be set to a data file
|
||||||
|
name that is appropriate for the spool directory of the other
|
||||||
|
system; this will be appropriate for the name of the destination
|
||||||
|
file in a send request of a data file for an execution of some
|
||||||
|
sort. The zxname array should be set to an execute file name that
|
||||||
|
is appropriate for the other system. The zlocalname argument is
|
||||||
|
the name of the local system as seen by the remote system, the
|
||||||
|
bgrade argument is the grade, and fxqt is TRUE if this file is
|
||||||
|
going to become an execution file. This should return NULL on
|
||||||
|
error. */
|
||||||
|
#define CFILE_NAME_LEN (15)
|
||||||
|
|
||||||
|
extern char *zsysdep_data_file_name P((const struct uuconf_system *qsys,
|
||||||
|
const char *zlocalname,
|
||||||
|
int bgrade, boolean fxqt,
|
||||||
|
char *ztname, char *zdname,
|
||||||
|
char *zxname));
|
||||||
|
|
||||||
|
/* Get a name for a local execute file. This is used by uux for a
|
||||||
|
local command with remote files. Returns NULL on error. */
|
||||||
|
extern char *zsysdep_xqt_file_name P((void));
|
||||||
|
|
||||||
|
/* Beginning getting execute files. To get a list of execute files,
|
||||||
|
first fsysdep_get_xqt_init is called, then zsysdep_get_xqt is
|
||||||
|
called several times until it returns NULL, then finally
|
||||||
|
usysdep_get_xqt_free is called. */
|
||||||
|
extern boolean fsysdep_get_xqt_init P((void));
|
||||||
|
|
||||||
|
/* Get the next execute file. This should return NULL when finished
|
||||||
|
(with *pferr set to FALSE). On an error this should return NULL
|
||||||
|
with *pferr set to TRUE. This should set *pzsystem to the name of
|
||||||
|
the system for which the execute file was created. Both the return
|
||||||
|
value and *pzsystem should be freed using ubuffree. */
|
||||||
|
extern char *zsysdep_get_xqt P((char **pzsystem,
|
||||||
|
boolean *pferr));
|
||||||
|
|
||||||
|
/* Clean up after getting execute files. */
|
||||||
|
extern void usysdep_get_xqt_free P((void));
|
||||||
|
|
||||||
|
/* Get the absolute pathname of a command to execute. This is given
|
||||||
|
the legal list of commands (which may be the special case "ALL")
|
||||||
|
and the path. It must return an absolute pathname to the command.
|
||||||
|
If it gets an error it should set *pferr to TRUE and return NULL;
|
||||||
|
if the command is not found it should set *pferr to FALSE and
|
||||||
|
return NULL. */
|
||||||
|
extern char *zsysdep_find_command P((const char *zcmd, char **pzcmds,
|
||||||
|
char **pzpath, boolean *pferr));
|
||||||
|
|
||||||
|
/* Expand file names for uuxqt. This exists because uuxqt on Unix has
|
||||||
|
to expand file names which begin with a ~. It does not want to
|
||||||
|
expand any other type of file name, and it turns a double ~ into a
|
||||||
|
single one without expanding. If this returns NULL, the file does
|
||||||
|
not need to be changed; otherwise it returns a zbufalc'ed string.
|
||||||
|
There is no way to report error. */
|
||||||
|
extern char *zsysdep_xqt_local_file P((const struct uuconf_system *qsys,
|
||||||
|
const char *zfile));
|
||||||
|
|
||||||
|
#if ! ALLOW_FILENAME_ARGUMENTS
|
||||||
|
/* Check an argument to an execution command to make sure that it
|
||||||
|
doesn't refer to a file name that may not be accessed. This should
|
||||||
|
check the argument to see if it is a filename. If it is, it should
|
||||||
|
either reject it out of hand or it should call fin_directory_list
|
||||||
|
on the file with both qsys->zremote_receive and qsys->zremote_send.
|
||||||
|
If the file is rejected, it should log an error and return FALSE.
|
||||||
|
Otherwise it should return TRUE. */
|
||||||
|
extern boolean fsysdep_xqt_check_file P((const struct uuconf_system *qsys,
|
||||||
|
const char *zfile));
|
||||||
|
#endif /* ! ALLOW_FILENAME_ARGUMENTS */
|
||||||
|
|
||||||
|
/* Run an execute file. The arguments are:
|
||||||
|
|
||||||
|
qsys -- system for which execute file was created
|
||||||
|
zuser -- user who requested execution
|
||||||
|
pazargs -- list of arguments to command (element 0 is command)
|
||||||
|
zfullcmd -- command and arguments stuck together in one string
|
||||||
|
zinput -- file name for standard input (may be NULL)
|
||||||
|
zoutput -- file name for standard output (may be NULL)
|
||||||
|
fshell -- if TRUE, use /bin/sh to execute file
|
||||||
|
ilock -- return value of ixsysdep_lock_uuxqt
|
||||||
|
pzerror -- set to name of standard error file
|
||||||
|
pftemp -- set to TRUE if error is temporary, FALSE otherwise
|
||||||
|
|
||||||
|
If fshell is TRUE, the command should be executed with /bin/sh
|
||||||
|
(obviously, this can only really be done on Unix systems). If an
|
||||||
|
error occurs this should return FALSE and set *pftemp
|
||||||
|
appropriately. *pzerror should be freed using ubuffree. */
|
||||||
|
extern boolean fsysdep_execute P((const struct uuconf_system *qsys,
|
||||||
|
const char *zuser,
|
||||||
|
const char **pazargs,
|
||||||
|
const char *zfullcmd,
|
||||||
|
const char *zinput,
|
||||||
|
const char *zoutput,
|
||||||
|
boolean fshell,
|
||||||
|
int ilock,
|
||||||
|
char **pzerror,
|
||||||
|
boolean *pftemp));
|
||||||
|
|
||||||
|
/* Lock for uuxqt execution. If the cmaxuuxqts argument is not zero,
|
||||||
|
this should make sure that no more than cmaxuuxqts uuxqt processes
|
||||||
|
are running at once. Also, only one uuxqt may execute a particular
|
||||||
|
command (specified by the -c option) at a time. If zcmd is not
|
||||||
|
NULL, it is a command that must be locked. This should return a
|
||||||
|
nonnegative number which will be passed to other routines,
|
||||||
|
including fsysdep_unlock_uuxqt, or -1 on error. */
|
||||||
|
extern int ixsysdep_lock_uuxqt P((const char *zcmd,
|
||||||
|
int cmaxuuxqts));
|
||||||
|
|
||||||
|
/* Unlock a uuxqt process. This is passed the return value of
|
||||||
|
ixsysdep_lock_uuxqt, as well as the arguments passed to
|
||||||
|
ixsysdep_lock_uuxqt. It may return FALSE on error, but at present
|
||||||
|
the return value is ignored. */
|
||||||
|
extern boolean fsysdep_unlock_uuxqt P((int iseq, const char *zcmd,
|
||||||
|
int cmaxuuxqts));
|
||||||
|
|
||||||
|
/* See whether a particular uuxqt command is locked. This should
|
||||||
|
return TRUE if the command is locked (because ixsysdep_lock_uuxqt
|
||||||
|
was called with it as an argument), FALSE otherwise. There is no
|
||||||
|
way to return error. */
|
||||||
|
extern boolean fsysdep_uuxqt_locked P((const char *zcmd));
|
||||||
|
|
||||||
|
/* Lock an execute file in order to execute it. This should return
|
||||||
|
FALSE if the execute file is already locked. There is no way to
|
||||||
|
return error. */
|
||||||
|
extern boolean fsysdep_lock_uuxqt_file P((const char *zfile));
|
||||||
|
|
||||||
|
/* Unlock an execute file. This should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_unlock_uuxqt_file P((const char *zfile));
|
||||||
|
|
||||||
|
/* Lock the execution directory. The ilock argument is the return
|
||||||
|
value of ixsysdep_lock_uuxqt. This should return FALSE if the
|
||||||
|
directory is already locked. There is no way to return error. */
|
||||||
|
extern boolean fsysdep_lock_uuxqt_dir P((int ilock));
|
||||||
|
|
||||||
|
/* Remove all files in the execution directory, and unlock it. This
|
||||||
|
should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_unlock_uuxqt_dir P((int ilock));
|
||||||
|
|
||||||
|
/* Move files into or out of the execution directory. The code will
|
||||||
|
already have checked that all the files exist. The elements in the
|
||||||
|
pzfrom array will be complete filenames, and the elements in the
|
||||||
|
pzto array will be either NULL (in which case the file should not
|
||||||
|
be moved) or simple base names. If fto is TRUE, the files in
|
||||||
|
pzfrom should be moved to pzto; otherwise, the files in pzto should
|
||||||
|
be moved to pzfrom (this is used if a temporary failure occurs, in
|
||||||
|
which case the execution will be retried later). If pzinput and
|
||||||
|
*pzinput are not NULL, then it is the name of the standard input
|
||||||
|
file; if it is the same as any element of pzfrom, then *pzinput
|
||||||
|
should be set to the zbufcpy of the corresponding pzto value, if
|
||||||
|
any. */
|
||||||
|
extern boolean fsysdep_move_uuxqt_files P((int cfiles,
|
||||||
|
const char *const *pzfrom,
|
||||||
|
const char *const *pzto,
|
||||||
|
boolean fto, int ilock,
|
||||||
|
char **pzinput));
|
||||||
|
|
||||||
|
/* Expand a file name on the local system, defaulting to the current
|
||||||
|
directory. This is just like zsysdep_local_file, except that
|
||||||
|
relative files are placed in the working directory the program
|
||||||
|
started in rather than in the public directory. This should return
|
||||||
|
NULL on error. */
|
||||||
|
extern char *zsysdep_local_file_cwd P((const char *zname,
|
||||||
|
const char *zpubdir));
|
||||||
|
|
||||||
|
/* Add the working directory to a file name. The named file is
|
||||||
|
actually on a remote system. If the file already has a directory,
|
||||||
|
it should not be changed. This should return NULL on error. */
|
||||||
|
extern char *zsysdep_add_cwd P((const char *zfile));
|
||||||
|
|
||||||
|
/* See whether a file name will need the current working directory
|
||||||
|
when zsysdep_local_file_cwd or zsysdep_add_cwd is called on it.
|
||||||
|
This will be called before usysdep_initialize. It should just
|
||||||
|
check whether the argument is an absolute path. See the comment
|
||||||
|
above usysdep_initialize in this file for an explanation of why
|
||||||
|
things are done this way. */
|
||||||
|
extern boolean fsysdep_needs_cwd P((const char *zfile));
|
||||||
|
|
||||||
|
/* Get the base name of a file. The file will be a local file name,
|
||||||
|
and this function should return the base file name, ideally in a
|
||||||
|
form which will make sense on most systems; it will be used if the
|
||||||
|
destination of a uucp is a directory. */
|
||||||
|
extern char *zsysdep_base_name P((const char *zfile));
|
||||||
|
|
||||||
|
/* Return a filename within a directory. */
|
||||||
|
extern char *zsysdep_in_dir P((const char *zdir, const char *zfile));
|
||||||
|
|
||||||
|
/* Get the mode of a file. This should return a Unix style file mode.
|
||||||
|
It should return 0 on error. */
|
||||||
|
extern unsigned int ixsysdep_file_mode P((const char *zfile));
|
||||||
|
|
||||||
|
/* See whether the user has access to a file. This is called by uucp
|
||||||
|
and uux to prevent copying of a file which uucp can read but the
|
||||||
|
user cannot. If access is denied, this should log an error message
|
||||||
|
and return FALSE. */
|
||||||
|
extern boolean fsysdep_access P((const char *zfile));
|
||||||
|
|
||||||
|
/* See whether the daemon has access to a file. This is called by
|
||||||
|
uucp and uux when a file is queued up for transfer without being
|
||||||
|
copied into the spool directory. It is merely an early error
|
||||||
|
check, as the daemon would of course discover the error itself when
|
||||||
|
it tried the transfer. If access would be denied, this should log
|
||||||
|
an error message and return FALSE. */
|
||||||
|
extern boolean fsysdep_daemon_access P((const char *zfile));
|
||||||
|
|
||||||
|
/* Translate a destination from system!user to a place in the public
|
||||||
|
directory where uupick will get the file. On Unix this produces
|
||||||
|
system!~/receive/user/localname, and that's probably what it has to
|
||||||
|
produce on any other system as well. Returns NULL on a usage
|
||||||
|
error, or otherwise returns string allocated by zbufcpy. */
|
||||||
|
extern char *zsysdep_uuto P((const char *zdest,
|
||||||
|
const char *zlocalname));
|
||||||
|
|
||||||
|
/* Return TRUE if a pathname exists and is a directory. */
|
||||||
|
extern boolean fsysdep_directory P((const char *zpath));
|
||||||
|
|
||||||
|
/* Walk a directory tree. The zdir argument is the directory to walk.
|
||||||
|
The pufn argument is a function to call on each regular file in the
|
||||||
|
tree. The first argument to pufn should be the full filename; the
|
||||||
|
second argument to pufn should be the filename relative to zdir;
|
||||||
|
the third argument to pufn should be the pinfo argument to
|
||||||
|
usysdep_walk_tree. The usysdep_walk_tree function should return
|
||||||
|
FALSE on error. */
|
||||||
|
extern boolean usysdep_walk_tree P((const char *zdir,
|
||||||
|
void (*pufn) P((const char *zfull,
|
||||||
|
const char *zrelative,
|
||||||
|
pointer pinfo)),
|
||||||
|
pointer pinfo));
|
||||||
|
|
||||||
|
/* Return the jobid of a work file, given the sequence value. On
|
||||||
|
error this should log an error and return NULL. The jobid is a
|
||||||
|
string which may be printed out and read in and passed to
|
||||||
|
fsysdep_kill_job, etc., but is not otherwise interpreted. */
|
||||||
|
extern char *zsysdep_jobid P((const struct uuconf_system *qsys,
|
||||||
|
pointer pseq));
|
||||||
|
|
||||||
|
/* See whether the current user is permitted to kill jobs submitted by
|
||||||
|
another user. This should return TRUE if permission is granted,
|
||||||
|
FALSE otherwise. */
|
||||||
|
extern boolean fsysdep_privileged P((void));
|
||||||
|
|
||||||
|
/* Kill a job, given the jobid. This should remove all associated
|
||||||
|
files and in general eliminate the job completely. On error it
|
||||||
|
should log an error message and return FALSE. */
|
||||||
|
extern boolean fsysdep_kill_job P((pointer puuconf,
|
||||||
|
const char *zjobid));
|
||||||
|
|
||||||
|
/* Rejuvenate a job, given the jobid. If possible, this should update
|
||||||
|
the time associated with the job such that it will not be
|
||||||
|
eliminated by uustat -K or similar programs that check the creation
|
||||||
|
time. This should affect the return value of ixsysdep_work_time.
|
||||||
|
On error it should log an error message and return FALSE. */
|
||||||
|
extern boolean fsysdep_rejuvenate_job P((pointer puuconf,
|
||||||
|
const char *zjobid));
|
||||||
|
|
||||||
|
/* Get the time a job was queued, given the sequence number. There is
|
||||||
|
no way to indicate error. The return value must use the same epoch
|
||||||
|
as ixsysdep_time. */
|
||||||
|
extern long ixsysdep_work_time P((const struct uuconf_system *qsys,
|
||||||
|
pointer pseq));
|
||||||
|
|
||||||
|
/* Get the time a file was created. This is called by uustat on
|
||||||
|
execution files. There is no way to indicate error. The return
|
||||||
|
value must use the same epoch as ixsysdep_time. */
|
||||||
|
extern long ixsysdep_file_time P((const char *zfile));
|
||||||
|
|
||||||
|
/* Get the size in bytes of a file. If this file does not exist, this
|
||||||
|
should not give an error message, but should return -1. If some
|
||||||
|
other error occurs, this should return -2. */
|
||||||
|
extern long csysdep_size P((const char *zfile));
|
||||||
|
|
||||||
|
/* Return the amount of free space on the containing the given file
|
||||||
|
name (the file may or may not exist). If the amount of free space
|
||||||
|
cannot be determined, the function should return -1. */
|
||||||
|
extern long csysdep_bytes_free P((const char *zfile));
|
||||||
|
|
||||||
|
/* Start getting status information for all systems with available
|
||||||
|
status information. There may be status information for unknown
|
||||||
|
systems, which is why this series of functions is used. The phold
|
||||||
|
argument is used to pass information around, to possibly avoid the
|
||||||
|
use of static variables. On error this should log an error and
|
||||||
|
return FALSE. */
|
||||||
|
extern boolean fsysdep_all_status_init P((pointer *phold));
|
||||||
|
|
||||||
|
/* Get status information for the next system. This should return the
|
||||||
|
system name and fill in the qstat argument. The phold argument
|
||||||
|
will be that set by fsysdep_all_status_init. On error this should
|
||||||
|
log an error, set *pferr to TRUE, and return NULL. */
|
||||||
|
extern char *zsysdep_all_status P((pointer phold, boolean *pferr,
|
||||||
|
struct sstatus *qstat));
|
||||||
|
|
||||||
|
/* Free up anything allocated by fsysdep_all_status_init and
|
||||||
|
zsysdep_all_status. The phold argument is that set by
|
||||||
|
fsysdep_all_status_init. */
|
||||||
|
extern void usysdep_all_status_free P((pointer phold));
|
||||||
|
|
||||||
|
/* Display the process status of all processes holding lock files.
|
||||||
|
This is uustat -p. The return value is passed to usysdep_exit. */
|
||||||
|
extern boolean fsysdep_lock_status P((void));
|
||||||
|
|
||||||
|
/* Return TRUE if the user has legitimate access to the port. This is
|
||||||
|
used by cu to control whether the user can open a port directly,
|
||||||
|
rather than merely being able to dial out on it. Opening a port
|
||||||
|
directly allows the modem to be reprogrammed. */
|
||||||
|
extern boolean fsysdep_port_access P((struct uuconf_port *qport));
|
||||||
|
|
||||||
|
/* Return whether the given port could be named by the given line. On
|
||||||
|
Unix, the line argument would be something like "ttyd0", and this
|
||||||
|
function should return TRUE if the named port is "/dev/ttyd0". */
|
||||||
|
extern boolean fsysdep_port_is_line P((struct uuconf_port *qport,
|
||||||
|
const char *zline));
|
||||||
|
|
||||||
|
/* Set the terminal into raw mode. In this mode no input characters
|
||||||
|
should be treated specially, and characters should be made
|
||||||
|
available as they are typed. The original terminal mode should be
|
||||||
|
saved, so that it can be restored by fsysdep_terminal_restore. If
|
||||||
|
flocalecho is TRUE, then local echoing should still be done;
|
||||||
|
otherwise echoing should be disabled. This function returns FALSE
|
||||||
|
on error. */
|
||||||
|
extern boolean fsysdep_terminal_raw P((boolean flocalecho));
|
||||||
|
|
||||||
|
/* Restore the terminal back to the original setting, before
|
||||||
|
fsysdep_terminal_raw was called. Returns FALSE on error. */
|
||||||
|
extern boolean fsysdep_terminal_restore P((void));
|
||||||
|
|
||||||
|
/* Read a line from the terminal. The fsysdep_terminal_raw function
|
||||||
|
will have been called. This should print the zprompt argument
|
||||||
|
(unless it is NULL) and return the line, allocated by zbufcpy, or
|
||||||
|
NULL on error. */
|
||||||
|
extern char *zsysdep_terminal_line P((const char *zprompt));
|
||||||
|
|
||||||
|
/* Write a line to the terminal, ending with a newline. This is
|
||||||
|
basically just puts (zline, stdout), except that the terminal will
|
||||||
|
be in raw mode, so on ASCII Unix systems the line needs to end with
|
||||||
|
\r\n. */
|
||||||
|
extern boolean fsysdep_terminal_puts P((const char *zline));
|
||||||
|
|
||||||
|
/* If faccept is TRUE, permit the user to generate signals from the
|
||||||
|
terminal. If faccept is FALSE, turn signals off again. After
|
||||||
|
fsysdep_terminal_raw is called, signals should be off. Return
|
||||||
|
FALSE on error. */
|
||||||
|
extern boolean fsysdep_terminal_signals P((boolean faccept));
|
||||||
|
|
||||||
|
/* The cu program expects the system dependent code to handle the
|
||||||
|
details of copying data from the communications port to the
|
||||||
|
terminal. This should be set up by fsysdep_cu_init, and done while
|
||||||
|
fsysdep_cu is called. It is permissible to do it on a continual
|
||||||
|
basis (on Unix a subprocess handles it) so long as the copying can
|
||||||
|
be stopped by the fsysdep_cu_copy function.
|
||||||
|
|
||||||
|
The fsysdep_cu_init function does any system dependent
|
||||||
|
initialization needed for this. */
|
||||||
|
extern boolean fsysdep_cu_init P((struct sconnection *qconn));
|
||||||
|
|
||||||
|
/* Copy all data from the communications port to the terminal, and all
|
||||||
|
data from the terminal to the communications port. Keep this up
|
||||||
|
until the escape character *zCuvar_escape is seen. Set *pbcmd to
|
||||||
|
the character following the escape character; after the escape
|
||||||
|
character, zlocalname should be printed, possibly after a delay.
|
||||||
|
If two escape characters are entered in sequence, this function
|
||||||
|
should send a single escape character to the port, and not return.
|
||||||
|
Returns FALSE on error. */
|
||||||
|
extern boolean fsysdep_cu P((struct sconnection *qconn,
|
||||||
|
char *pbcmd,
|
||||||
|
const char *zlocalname));
|
||||||
|
|
||||||
|
/* If fcopy is TRUE, start copying data from the communications port
|
||||||
|
to the terminal. If fcopy is FALSE, stop copying data. This
|
||||||
|
function may be called several times during a cu session. It
|
||||||
|
should return FALSE on error. */
|
||||||
|
extern boolean fsysdep_cu_copy P((boolean fcopy));
|
||||||
|
|
||||||
|
/* Stop copying data from the communications port to the terminal, and
|
||||||
|
generally clean up after fsysdep_cu_init and fsysdep_cu. Returns
|
||||||
|
FALSE on error. */
|
||||||
|
extern boolean fsysdep_cu_finish P((void));
|
||||||
|
|
||||||
|
/* Run a shell command. If zcmd is NULL, or *zcmd == '\0', just
|
||||||
|
start up a shell. The second argument is one of the following
|
||||||
|
values. This should return FALSE on error. */
|
||||||
|
enum tshell_cmd
|
||||||
|
{
|
||||||
|
/* Attach stdin and stdout to the terminal. */
|
||||||
|
SHELL_NORMAL,
|
||||||
|
/* Attach stdout to the communications port, stdin to the terminal. */
|
||||||
|
SHELL_STDOUT_TO_PORT,
|
||||||
|
/* Attach stdin to the communications port, stdout to the terminal. */
|
||||||
|
SHELL_STDIN_FROM_PORT,
|
||||||
|
/* Attach both stdin and stdout to the communications port. */
|
||||||
|
SHELL_STDIO_ON_PORT
|
||||||
|
};
|
||||||
|
|
||||||
|
extern boolean fsysdep_shell P((struct sconnection *qconn,
|
||||||
|
const char *zcmd,
|
||||||
|
enum tshell_cmd tcmd));
|
||||||
|
|
||||||
|
/* Change directory. If zdir is NULL, or *zdir == '\0', change to the
|
||||||
|
user's home directory. Return FALSE on error. */
|
||||||
|
extern boolean fsysdep_chdir P((const char *zdir));
|
||||||
|
|
||||||
|
/* Suspend the current process. This is only expected to work on Unix
|
||||||
|
versions that support SIGTSTP. In general, people can just shell
|
||||||
|
out. */
|
||||||
|
extern boolean fsysdep_suspend P((void));
|
||||||
|
|
||||||
|
/* Start getting files for uupick. The zsystem argument may be NULL
|
||||||
|
to get files from all systems, or it may specify a particular
|
||||||
|
system. The zpubdir argument is the public directory to use. This
|
||||||
|
returns FALSE on error. */
|
||||||
|
extern boolean fsysdep_uupick_init P((const char *zsystem,
|
||||||
|
const char *zpubdir));
|
||||||
|
|
||||||
|
/* Get the next file for uupick. This returns the basic file name.
|
||||||
|
It sets *pzfull to the full name, and *pzfrom to the name of the
|
||||||
|
system which sent this file over; both should be freed using
|
||||||
|
ubuffree. *pzfull should be passed to ubuffree after it is no
|
||||||
|
longer needed. The zsystem and zpubdir arguments should be the
|
||||||
|
same as the arguments to fsysdep_uupick_init. This returns NULL
|
||||||
|
when all files been returned. */
|
||||||
|
extern char *zsysdep_uupick P((const char *zsystem, const char *zpubdir,
|
||||||
|
char **pzfrom, char **pzfull));
|
||||||
|
|
||||||
|
/* Clean up after getting files for uupick. */
|
||||||
|
extern boolean fsysdep_uupick_free P((const char *zsystem,
|
||||||
|
const char *zpubdir));
|
||||||
|
|
||||||
|
/* Translate a local file name for uupick. On Unix this is just like
|
||||||
|
zsysdep_local_file_cwd except that a file beginning with ~/ is
|
||||||
|
placed in the user's home directory rather than in the public
|
||||||
|
directory. */
|
||||||
|
extern char *zsysdep_uupick_local_file P((const char *zfile));
|
||||||
|
|
||||||
|
/* Remove a directory and all the files in it. */
|
||||||
|
extern boolean fsysdep_rmdir P((const char *zdir));
|
||||||
|
|
||||||
|
#endif /* ! defined (SYSTEM_H) */
|
470
gnu/libexec/uucp/common_sources/tcp.c
Normal file
470
gnu/libexec/uucp/common_sources/tcp.c
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
/* tcp.c
|
||||||
|
Code to handle TCP connections.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char tcp_rcsid[] = "$Id: tcp.c,v 1.1 1993/08/04 19:31:06 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TCP
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "conn.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_SYS_TYPES_TCP_H
|
||||||
|
#include <sys/types.tcp.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This code handles TCP connections. It assumes a Berkeley socket
|
||||||
|
interface. */
|
||||||
|
|
||||||
|
/* The normal "uucp" port number. */
|
||||||
|
#define IUUCP_PORT (540)
|
||||||
|
|
||||||
|
/* Local functions. */
|
||||||
|
static void utcp_free P((struct sconnection *qconn));
|
||||||
|
static boolean ftcp_open P((struct sconnection *qconn, long ibaud,
|
||||||
|
boolean fwait));
|
||||||
|
static boolean ftcp_close P((struct sconnection *qconn,
|
||||||
|
pointer puuconf,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
boolean fsuccess));
|
||||||
|
static boolean ftcp_reset P((struct sconnection *qconn));
|
||||||
|
static boolean ftcp_dial P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const char *zphone,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
enum tdialerfound *ptdialer));
|
||||||
|
static int itcp_port_number P((const char *zport));
|
||||||
|
|
||||||
|
/* The command table for a TCP connection. */
|
||||||
|
static const struct sconncmds stcpcmds =
|
||||||
|
{
|
||||||
|
utcp_free,
|
||||||
|
NULL, /* pflock */
|
||||||
|
NULL, /* pfunlock */
|
||||||
|
ftcp_open,
|
||||||
|
ftcp_close,
|
||||||
|
ftcp_reset,
|
||||||
|
ftcp_dial,
|
||||||
|
fsysdep_conn_read,
|
||||||
|
fsysdep_conn_write,
|
||||||
|
fsysdep_conn_io,
|
||||||
|
NULL, /* pfbreak */
|
||||||
|
NULL, /* pfset */
|
||||||
|
NULL, /* pfcarrier */
|
||||||
|
fsysdep_conn_chat,
|
||||||
|
NULL /* pibaud */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initialize a TCP connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_tcp_init (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *q;
|
||||||
|
|
||||||
|
q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn));
|
||||||
|
q->o = -1;
|
||||||
|
q->zdevice = NULL;
|
||||||
|
q->iflags = -1;
|
||||||
|
q->istdout_flags = -1;
|
||||||
|
q->fterminal = FALSE;
|
||||||
|
q->ftli = FALSE;
|
||||||
|
q->ibaud = 0;
|
||||||
|
|
||||||
|
qconn->psysdep = (pointer) q;
|
||||||
|
qconn->qcmds = &stcpcmds;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a TCP connection. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
utcp_free (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
xfree (qconn->psysdep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a TCP connection. If the fwait argument is TRUE, we are
|
||||||
|
running as a server. Otherwise we are just trying to reach another
|
||||||
|
system. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
ftcp_open (qconn, ibaud, fwait)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
long ibaud;
|
||||||
|
boolean fwait;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
struct sockaddr_in s;
|
||||||
|
const char *zport;
|
||||||
|
uid_t iuid, ieuid;
|
||||||
|
|
||||||
|
ulog_device ("TCP");
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
qsysdep->o = socket (AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (qsysdep->o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "socket: %s", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl (qsysdep->o, F_SETFD,
|
||||||
|
fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0);
|
||||||
|
if (qsysdep->iflags < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we aren't waiting for a connection, we're done. */
|
||||||
|
if (! fwait)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* Run as a server and wait for a new connection. The code in
|
||||||
|
uucico.c has already detached us from our controlling terminal.
|
||||||
|
From this point on if the server gets an error we exit; we only
|
||||||
|
return if we have received a connection. It would be more robust
|
||||||
|
to respawn the server if it fails; someday. */
|
||||||
|
bzero ((pointer) &s, sizeof s);
|
||||||
|
s.sin_family = AF_INET;
|
||||||
|
zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
|
||||||
|
s.sin_port = itcp_port_number (zport);
|
||||||
|
s.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||||
|
|
||||||
|
/* Swap to our real user ID when doing the bind call. This will
|
||||||
|
permit the server to use privileged TCP ports when invoked by
|
||||||
|
root. We only swap if our effective user ID is not root, so that
|
||||||
|
the program can also be made suid root in order to get privileged
|
||||||
|
ports when invoked by anybody. */
|
||||||
|
iuid = getuid ();
|
||||||
|
ieuid = geteuid ();
|
||||||
|
if (ieuid != 0)
|
||||||
|
{
|
||||||
|
#if HAVE_SETREUID
|
||||||
|
/* Swap the effective user id and the real user id. We can then
|
||||||
|
swap them back again when we want to return to the uucp
|
||||||
|
user's permissions. */
|
||||||
|
if (setreuid (ieuid, iuid) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
|
||||||
|
(long) ieuid, (long) iuid, strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_SETREUID */
|
||||||
|
#if HAVE_SAVED_SETUID
|
||||||
|
/* Set the effective user id to the real user id. Since the
|
||||||
|
effective user id is the saved setuid we will able to set
|
||||||
|
back to it later. If the real user id is root we will not be
|
||||||
|
able to switch back and forth, but that doesn't matter since
|
||||||
|
we only want to switch once. */
|
||||||
|
if (setuid (iuid) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid,
|
||||||
|
strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_SAVED_SETUID */
|
||||||
|
/* There's no way to switch between real permissions and
|
||||||
|
effective permissions. Just try the bind with the uucp
|
||||||
|
permissions. */
|
||||||
|
#endif /* ! HAVE_SAVED_SETUID */
|
||||||
|
#endif /* ! HAVE_SETREUID */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
|
||||||
|
ulog (LOG_FATAL, "bind: %s", strerror (errno));
|
||||||
|
|
||||||
|
/* Now swap back to the uucp user ID. */
|
||||||
|
if (ieuid != 0)
|
||||||
|
{
|
||||||
|
#if HAVE_SETREUID
|
||||||
|
if (setreuid (iuid, ieuid) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
|
||||||
|
(long) iuid, (long) ieuid, strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_SETREUID */
|
||||||
|
#if HAVE_SAVED_SETUID
|
||||||
|
/* Set ourselves back to our original effective user id. */
|
||||||
|
if (setuid ((uid_t) ieuid) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid,
|
||||||
|
strerror (errno));
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_SAVED_SETUID */
|
||||||
|
/* We didn't switch, no need to switch back. */
|
||||||
|
#endif /* ! HAVE_SAVED_SETUID */
|
||||||
|
#endif /* ! HAVE_SETREUID */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen (qsysdep->o, 5) < 0)
|
||||||
|
ulog (LOG_FATAL, "listen: %s", strerror (errno));
|
||||||
|
|
||||||
|
while (! FGOT_SIGNAL ())
|
||||||
|
{
|
||||||
|
size_t clen;
|
||||||
|
int onew;
|
||||||
|
pid_t ipid;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT,
|
||||||
|
"ftcp_open: Waiting for connections");
|
||||||
|
|
||||||
|
clen = sizeof s;
|
||||||
|
onew = accept (qsysdep->o, (struct sockaddr *) &s, &clen);
|
||||||
|
if (onew < 0)
|
||||||
|
ulog (LOG_FATAL, "accept: %s", strerror (errno));
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT,
|
||||||
|
"ftcp_open: Got connection; forking");
|
||||||
|
|
||||||
|
ipid = ixsfork ();
|
||||||
|
if (ipid < 0)
|
||||||
|
ulog (LOG_FATAL, "fork: %s", strerror (errno));
|
||||||
|
if (ipid == 0)
|
||||||
|
{
|
||||||
|
(void) close (qsysdep->o);
|
||||||
|
qsysdep->o = onew;
|
||||||
|
|
||||||
|
/* Now we fork and let our parent die, so that we become
|
||||||
|
a child of init. This lets the main server code wait
|
||||||
|
for its child and then continue without accumulating
|
||||||
|
zombie children. */
|
||||||
|
ipid = ixsfork ();
|
||||||
|
if (ipid < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fork: %s", strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipid != 0)
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
|
ulog_id (getpid ());
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) close (onew);
|
||||||
|
|
||||||
|
/* Now wait for the child. */
|
||||||
|
(void) ixswait ((unsigned long) ipid, (const char *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We got a signal. */
|
||||||
|
usysdep_exit (FALSE);
|
||||||
|
|
||||||
|
/* Avoid compiler warnings. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the port. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftcp_close (qconn, puuconf, qdialer, fsuccess)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
boolean fsuccess;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
fret = TRUE;
|
||||||
|
if (qsysdep->o >= 0 && close (qsysdep->o) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "close: %s", strerror (errno));
|
||||||
|
fret = FALSE;
|
||||||
|
}
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the port. This will be called by a child which was forked
|
||||||
|
off in ftcp_open, above. We don't want uucico to continue looping
|
||||||
|
and giving login prompts, so we pretend that we received a SIGINT
|
||||||
|
signal. This should probably be handled more cleanly. The signal
|
||||||
|
will not be recorded in the log file because we don't set
|
||||||
|
afLog_signal[INDEXSIG_SIGINT]. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftcp_reset (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
afSignal[INDEXSIG_SIGINT] = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dial out on a TCP port, so to speak: connect to a remote computer. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zphone;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
enum tdialerfound *ptdialer;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
const char *zhost;
|
||||||
|
struct hostent *q;
|
||||||
|
struct sockaddr_in s;
|
||||||
|
const char *zport;
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
*ptdialer = DIALERFOUND_FALSE;
|
||||||
|
|
||||||
|
zhost = zphone;
|
||||||
|
if (zhost == NULL)
|
||||||
|
{
|
||||||
|
if (qsys == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "No address for TCP connection");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
zhost = qsys->uuconf_zname;
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
q = gethostbyname ((char *) zhost);
|
||||||
|
if (q == NULL)
|
||||||
|
{
|
||||||
|
if (errno == 0)
|
||||||
|
ulog (LOG_ERROR, "%s: unknown host name", zhost);
|
||||||
|
else
|
||||||
|
ulog (LOG_ERROR, "gethostbyname (%s): %s", zhost, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.sin_family = q->h_addrtype;
|
||||||
|
zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
|
||||||
|
s.sin_port = itcp_port_number (zport);
|
||||||
|
memcpy (&s.sin_addr.s_addr, q->h_addr, (size_t) q->h_length);
|
||||||
|
|
||||||
|
if (connect (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "connect: %s", strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the port number given a name. The argument will almost always
|
||||||
|
be "uucp" so we cache that value. The return value is always in
|
||||||
|
network byte order. This returns -1 on error. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
itcp_port_number (zname)
|
||||||
|
const char *zname;
|
||||||
|
{
|
||||||
|
boolean fuucp;
|
||||||
|
static int iuucp;
|
||||||
|
int i;
|
||||||
|
char *zend;
|
||||||
|
struct servent *q;
|
||||||
|
|
||||||
|
fuucp = strcmp (zname, "uucp") == 0;
|
||||||
|
if (fuucp && iuucp != 0)
|
||||||
|
return iuucp;
|
||||||
|
|
||||||
|
/* Try it as a number first. */
|
||||||
|
i = strtol ((char *) zname, &zend, 10);
|
||||||
|
if (i != 0 && *zend == '\0')
|
||||||
|
return htons (i);
|
||||||
|
|
||||||
|
q = getservbyname ((char *) zname, (char *) "tcp");
|
||||||
|
if (q == NULL)
|
||||||
|
{
|
||||||
|
/* We know that the "uucp" service should be 540, even if isn't
|
||||||
|
in /etc/services. */
|
||||||
|
if (fuucp)
|
||||||
|
{
|
||||||
|
iuucp = htons (IUUCP_PORT);
|
||||||
|
return iuucp;
|
||||||
|
}
|
||||||
|
ulog (LOG_ERROR, "getservbyname (%s): %s", zname, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fuucp)
|
||||||
|
iuucp = q->s_port;
|
||||||
|
|
||||||
|
return q->s_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_TCP */
|
644
gnu/libexec/uucp/common_sources/tli.c
Normal file
644
gnu/libexec/uucp/common_sources/tli.c
Normal file
@ -0,0 +1,644 @@
|
|||||||
|
/* tli.c
|
||||||
|
Code to handle TLI connections.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char tli_rcsid[] = "$Id: tli.c,v 1.1 1993/08/04 19:31:09 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TLI
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "conn.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_SYS_IOCTL_H
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TIUSER_H
|
||||||
|
#include <tiuser.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_XTI_H
|
||||||
|
#include <xti.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_TLI_H
|
||||||
|
#include <sys/tli.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_STROPTS_H
|
||||||
|
#include <stropts.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The arguments to t_alloca have two different names. I want the
|
||||||
|
SVID ones, not the XPG3 ones. */
|
||||||
|
#ifndef T_BIND
|
||||||
|
#define T_BIND T_BIND_STR
|
||||||
|
#endif
|
||||||
|
#ifndef T_CALL
|
||||||
|
#define T_CALL T_CALL_STR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Hopefully these externs will not cause any trouble. This is how
|
||||||
|
they are shown in the SVID. */
|
||||||
|
extern int t_errno;
|
||||||
|
extern char *t_errlist[];
|
||||||
|
extern int t_nerr;
|
||||||
|
|
||||||
|
#ifndef t_alloc
|
||||||
|
extern pointer t_alloc ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This code handles TLI connections. It's Unix specific. It's
|
||||||
|
largely based on code from Unix Network Programming, by W. Richard
|
||||||
|
Stevens. */
|
||||||
|
|
||||||
|
/* Local functions. */
|
||||||
|
static const char *ztlierror P((void));
|
||||||
|
static void utli_free P((struct sconnection *qconn));
|
||||||
|
static boolean ftli_push P((struct sconnection *qconn));
|
||||||
|
static boolean ftli_open P((struct sconnection *qconn, long ibaud,
|
||||||
|
boolean fwait));
|
||||||
|
static boolean ftli_close P((struct sconnection *qconn,
|
||||||
|
pointer puuconf,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
boolean fsuccess));
|
||||||
|
static boolean ftli_reset P((struct sconnection *qconn));
|
||||||
|
static boolean ftli_dial P((struct sconnection *qconn, pointer puuconf,
|
||||||
|
const struct uuconf_system *qsys,
|
||||||
|
const char *zphone,
|
||||||
|
struct uuconf_dialer *qdialer,
|
||||||
|
enum tdialerfound *ptdialer));
|
||||||
|
|
||||||
|
/* The command table for a TLI connection. */
|
||||||
|
static const struct sconncmds stlicmds =
|
||||||
|
{
|
||||||
|
utli_free,
|
||||||
|
NULL, /* pflock */
|
||||||
|
NULL, /* pfunlock */
|
||||||
|
ftli_open,
|
||||||
|
ftli_close,
|
||||||
|
ftli_reset,
|
||||||
|
ftli_dial,
|
||||||
|
fsysdep_conn_read,
|
||||||
|
fsysdep_conn_write,
|
||||||
|
fsysdep_conn_io,
|
||||||
|
NULL, /* pfbreak */
|
||||||
|
NULL, /* pfset */
|
||||||
|
NULL, /* pfcarrier */
|
||||||
|
fsysdep_conn_chat,
|
||||||
|
NULL /* pibaud */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Get a TLI error string. */
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
ztlierror ()
|
||||||
|
{
|
||||||
|
if (t_errno == TSYSERR)
|
||||||
|
return strerror (errno);
|
||||||
|
if (t_errno < 0 || t_errno >= t_nerr)
|
||||||
|
return "Unknown TLI error";
|
||||||
|
return t_errlist[t_errno];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize a TLI connection. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_tli_init (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *q;
|
||||||
|
|
||||||
|
q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn));
|
||||||
|
q->o = -1;
|
||||||
|
q->zdevice = NULL;
|
||||||
|
q->iflags = -1;
|
||||||
|
q->istdout_flags = -1;
|
||||||
|
q->fterminal = FALSE;
|
||||||
|
q->ftli = TRUE;
|
||||||
|
q->ibaud = 0;
|
||||||
|
|
||||||
|
qconn->psysdep = (pointer) q;
|
||||||
|
qconn->qcmds = &stlicmds;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free a TLI connection. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
utli_free (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
xfree (qconn->psysdep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push all desired modules onto a TLI stream. If the user requests a
|
||||||
|
STREAMS connection without giving a list of modules, we just push
|
||||||
|
tirdwr. If the I_PUSH ioctl is not defined on this system, we just
|
||||||
|
ignore any list of modules. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
ftli_push (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
#ifdef I_PUSH
|
||||||
|
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
if (qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush != NULL)
|
||||||
|
{
|
||||||
|
char **pz;
|
||||||
|
|
||||||
|
for (pz = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush;
|
||||||
|
*pz != NULL;
|
||||||
|
pz++)
|
||||||
|
{
|
||||||
|
if (ioctl (qsysdep->o, I_PUSH, *pz) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "ioctl (I_PUSH, %s): %s", *pz,
|
||||||
|
strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream)
|
||||||
|
{
|
||||||
|
if (ioctl (qsysdep->o, I_PUSH, "tirdwr") < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "ioctl (I_PUSH, tirdwr): %s",
|
||||||
|
strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have just put the connection into stream mode, we must turn
|
||||||
|
off the TLI flag to avoid using TLI calls on it. */
|
||||||
|
if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream)
|
||||||
|
qsysdep->ftli = FALSE;
|
||||||
|
|
||||||
|
#endif /* defined (I_PUSH) */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a TLI connection. If the fwait argument is TRUE, we are
|
||||||
|
running as a server. Otherwise we are just trying to reach another
|
||||||
|
system. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
ftli_open (qconn, ibaud, fwait)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
long ibaud;
|
||||||
|
boolean fwait;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
const char *zdevice;
|
||||||
|
char *zfreedev;
|
||||||
|
const char *zservaddr;
|
||||||
|
char *zfreeaddr;
|
||||||
|
struct t_bind *qtbind;
|
||||||
|
struct t_call *qtcall;
|
||||||
|
|
||||||
|
/* Unlike most other device types, we don't bother to call
|
||||||
|
ulog_device here, because fconn_open calls it with the name of
|
||||||
|
the port anyhow. */
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
zdevice = qconn->qport->uuconf_u.uuconf_stli.uuconf_zdevice;
|
||||||
|
if (zdevice == NULL)
|
||||||
|
zdevice = qconn->qport->uuconf_zname;
|
||||||
|
|
||||||
|
zfreedev = NULL;
|
||||||
|
if (*zdevice != '/')
|
||||||
|
{
|
||||||
|
zfreedev = zbufalc (sizeof "/dev/" + strlen (zdevice));
|
||||||
|
sprintf (zfreedev, "/dev/%s", zdevice);
|
||||||
|
zdevice = zfreedev;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsysdep->o = t_open (zdevice, O_RDWR, (struct t_info *) NULL);
|
||||||
|
if (qsysdep->o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "t_open (%s): %s", zdevice, ztlierror ());
|
||||||
|
ubuffree (zfreedev);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl (qsysdep->o, F_SETFD,
|
||||||
|
fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
|
||||||
|
ubuffree (zfreedev);
|
||||||
|
(void) t_close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0);
|
||||||
|
if (qsysdep->iflags < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl: %s", strerror (errno));
|
||||||
|
ubuffree (zfreedev);
|
||||||
|
(void) t_close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we aren't waiting for a connection, we can bind to any local
|
||||||
|
address, and then we're finished. */
|
||||||
|
if (! fwait)
|
||||||
|
{
|
||||||
|
ubuffree (zfreedev);
|
||||||
|
if (t_bind (qsysdep->o, (struct t_bind *) NULL,
|
||||||
|
(struct t_bind *) NULL) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "t_bind: %s", ztlierror ());
|
||||||
|
(void) t_close (qsysdep->o);
|
||||||
|
qsysdep->o = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Run as a server and wait for a new connection. The code in
|
||||||
|
uucico.c has already detached us from our controlling terminal.
|
||||||
|
From this point on if the server gets an error we exit; we only
|
||||||
|
return if we have received a connection. It would be more robust
|
||||||
|
to respawn the server if it fails; someday. */
|
||||||
|
qtbind = (struct t_bind *) t_alloc (qsysdep->o, T_BIND, T_ALL);
|
||||||
|
if (qtbind == NULL)
|
||||||
|
ulog (LOG_FATAL, "t_alloc (T_BIND): %s", ztlierror ());
|
||||||
|
|
||||||
|
zservaddr = qconn->qport->uuconf_u.uuconf_stli.uuconf_zservaddr;
|
||||||
|
if (zservaddr == NULL)
|
||||||
|
ulog (LOG_FATAL, "Can't run as TLI server; no server address");
|
||||||
|
|
||||||
|
zfreeaddr = zbufcpy (zservaddr);
|
||||||
|
qtbind->addr.len = cescape (zfreeaddr);
|
||||||
|
if (qtbind->addr.len > qtbind->addr.maxlen)
|
||||||
|
ulog (LOG_FATAL, "%s: TLI server address too long (max %d)",
|
||||||
|
zservaddr, qtbind->addr.maxlen);
|
||||||
|
memcpy (qtbind->addr.buf, zfreeaddr, qtbind->addr.len);
|
||||||
|
ubuffree (zfreeaddr);
|
||||||
|
|
||||||
|
qtbind->qlen = 5;
|
||||||
|
|
||||||
|
if (t_bind (qsysdep->o, qtbind, (struct t_bind *) NULL) < 0)
|
||||||
|
ulog (LOG_FATAL, "t_bind (%s): %s", zservaddr, ztlierror ());
|
||||||
|
|
||||||
|
(void) t_free ((pointer) qtbind, T_BIND);
|
||||||
|
|
||||||
|
qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ALL);
|
||||||
|
if (qtcall == NULL)
|
||||||
|
ulog (LOG_FATAL, "t_alloc (T_CALL): %s", ztlierror ());
|
||||||
|
|
||||||
|
while (! FGOT_SIGNAL ())
|
||||||
|
{
|
||||||
|
int onew;
|
||||||
|
pid_t ipid;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT,
|
||||||
|
"ftli_open: Waiting for connections");
|
||||||
|
|
||||||
|
if (t_listen (qsysdep->o, qtcall) < 0)
|
||||||
|
ulog (LOG_FATAL, "t_listen: %s", ztlierror ());
|
||||||
|
|
||||||
|
onew = t_open (zdevice, O_RDWR, (struct t_info *) NULL);
|
||||||
|
if (onew < 0)
|
||||||
|
ulog (LOG_FATAL, "t_open (%s): %s", zdevice, ztlierror ());
|
||||||
|
|
||||||
|
if (fcntl (onew, F_SETFD,
|
||||||
|
fcntl (onew, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
ulog (LOG_FATAL, "fcntl (FD_CLOEXEC): %s", strerror (errno));
|
||||||
|
|
||||||
|
if (t_bind (onew, (struct t_bind *) NULL, (struct t_bind *) NULL) < 0)
|
||||||
|
ulog (LOG_FATAL, "t_bind: %s", ztlierror ());
|
||||||
|
|
||||||
|
if (t_accept (qsysdep->o, onew, qtcall) < 0)
|
||||||
|
{
|
||||||
|
/* We may have received a disconnect. */
|
||||||
|
if (t_errno != TLOOK)
|
||||||
|
ulog (LOG_FATAL, "t_accept: %s", ztlierror ());
|
||||||
|
if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0)
|
||||||
|
ulog (LOG_FATAL, "t_rcvdis: %s", ztlierror ());
|
||||||
|
(void) t_close (onew);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_MESSAGE0 (DEBUG_PORT,
|
||||||
|
"ftli_open: Got connection; forking");
|
||||||
|
|
||||||
|
ipid = ixsfork ();
|
||||||
|
if (ipid < 0)
|
||||||
|
ulog (LOG_FATAL, "fork: %s", strerror (errno));
|
||||||
|
if (ipid == 0)
|
||||||
|
{
|
||||||
|
ulog_close ();
|
||||||
|
|
||||||
|
(void) t_close (qsysdep->o);
|
||||||
|
qsysdep->o = onew;
|
||||||
|
|
||||||
|
/* Push any desired modules. */
|
||||||
|
if (! ftli_push (qconn))
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
|
||||||
|
/* Now we fork and let our parent die, so that we become
|
||||||
|
a child of init. This lets the main server code wait
|
||||||
|
for its child and then continue without accumulating
|
||||||
|
zombie children. */
|
||||||
|
ipid = ixsfork ();
|
||||||
|
if (ipid < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fork: %s", strerror (errno));
|
||||||
|
_exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipid != 0)
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
|
ulog_id (getpid ());
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) t_close (onew);
|
||||||
|
|
||||||
|
/* Now wait for the child. */
|
||||||
|
(void) ixswait ((unsigned long) ipid, (const char *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We got a signal. */
|
||||||
|
usysdep_exit (FALSE);
|
||||||
|
|
||||||
|
/* Avoid compiler warnings. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the port. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftli_close (qconn, puuconf, qdialer, fsuccess)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
boolean fsuccess;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
fret = TRUE;
|
||||||
|
if (qsysdep->o >= 0)
|
||||||
|
{
|
||||||
|
if (qsysdep->ftli)
|
||||||
|
{
|
||||||
|
if (t_close (qsysdep->o) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "t_close: %s", ztlierror ());
|
||||||
|
fret = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (close (qsysdep->o) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "close: %s", strerror (errno));
|
||||||
|
fret = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qsysdep->o = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reset the port. This will be called by a child which was forked
|
||||||
|
off in ftli_open, above. We don't want uucico to continue looping
|
||||||
|
and giving login prompts, so we pretend that we received a SIGINT
|
||||||
|
signal. This should probably be handled more cleanly. The signal
|
||||||
|
will not be recorded in the log file because we don't set
|
||||||
|
afLog_signal[INDEXSIG_SIGINT]. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftli_reset (qconn)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
{
|
||||||
|
afSignal[INDEXSIG_SIGINT] = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dial out on a TLI port, so to speak: connect to a remote computer. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static boolean
|
||||||
|
ftli_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound)
|
||||||
|
struct sconnection *qconn;
|
||||||
|
pointer puuconf;
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zphone;
|
||||||
|
struct uuconf_dialer *qdialer;
|
||||||
|
enum tdialerfound *ptdialerfound;
|
||||||
|
{
|
||||||
|
struct ssysdep_conn *qsysdep;
|
||||||
|
char **pzdialer;
|
||||||
|
const char *zaddr;
|
||||||
|
struct t_call *qtcall;
|
||||||
|
char *zescape;
|
||||||
|
|
||||||
|
qsysdep = (struct ssysdep_conn *) qconn->psysdep;
|
||||||
|
|
||||||
|
*ptdialerfound = DIALERFOUND_FALSE;
|
||||||
|
|
||||||
|
pzdialer = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzdialer;
|
||||||
|
if (*pzdialer == NULL)
|
||||||
|
pzdialer = NULL;
|
||||||
|
|
||||||
|
/* If the first dialer is "TLI" or "TLIS", we use the first token
|
||||||
|
(pzdialer[1]) as the address to connect to. */
|
||||||
|
zaddr = zphone;
|
||||||
|
if (pzdialer != NULL
|
||||||
|
&& (strcmp (pzdialer[0], "TLI") == 0
|
||||||
|
|| strcmp (pzdialer[0], "TLIS") == 0))
|
||||||
|
{
|
||||||
|
if (pzdialer[1] == NULL)
|
||||||
|
++pzdialer;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (strcmp (pzdialer[1], "\\D") != 0
|
||||||
|
&& strcmp (pzdialer[1], "\\T") != 0)
|
||||||
|
zaddr = pzdialer[1];
|
||||||
|
pzdialer += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zaddr == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "No address for TLI connection");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ADDR);
|
||||||
|
if (qtcall == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "t_alloc (T_CALL): %s", ztlierror ());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
zescape = zbufcpy (zaddr);
|
||||||
|
qtcall->addr.len = cescape (zescape);
|
||||||
|
if (qtcall->addr.len > qtcall->addr.maxlen)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: TLI address too long (max %d)", zaddr,
|
||||||
|
qtcall->addr.maxlen);
|
||||||
|
ubuffree (zescape);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memcpy (qtcall->addr.buf, zescape, qtcall->addr.len);
|
||||||
|
ubuffree (zescape);
|
||||||
|
|
||||||
|
if (t_connect (qsysdep->o, qtcall, (struct t_call *) NULL) < 0)
|
||||||
|
{
|
||||||
|
if (t_errno != TLOOK)
|
||||||
|
ulog (LOG_ERROR, "t_connect: %s", ztlierror ());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0)
|
||||||
|
ulog (LOG_ERROR, "t_rcvdis: %s", ztlierror ());
|
||||||
|
else
|
||||||
|
ulog (LOG_ERROR, "Connection refused");
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We've connected to the remote. Push any desired modules. */
|
||||||
|
if (! ftli_push (qconn))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Handle the rest of the dialer sequence. This is similar to
|
||||||
|
fmodem_dial, and they should, perhaps, be combined somehow. */
|
||||||
|
if (pzdialer != NULL)
|
||||||
|
{
|
||||||
|
boolean ffirst;
|
||||||
|
|
||||||
|
ffirst = TRUE;
|
||||||
|
while (*pzdialer != NULL)
|
||||||
|
{
|
||||||
|
int iuuconf;
|
||||||
|
struct uuconf_dialer *q;
|
||||||
|
struct uuconf_dialer s;
|
||||||
|
const char *ztoken;
|
||||||
|
boolean ftranslate;
|
||||||
|
|
||||||
|
if (! ffirst)
|
||||||
|
q = &s;
|
||||||
|
else
|
||||||
|
q = qdialer;
|
||||||
|
|
||||||
|
iuuconf = uuconf_dialer_info (puuconf, *pzdialer, q);
|
||||||
|
if (iuuconf == UUCONF_NOT_FOUND)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: Dialer not found", *pzdialer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
{
|
||||||
|
ulog_uuconf (LOG_ERROR, puuconf, iuuconf);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
++pzdialer;
|
||||||
|
ztoken = *pzdialer;
|
||||||
|
|
||||||
|
ftranslate = FALSE;
|
||||||
|
if (ztoken == NULL
|
||||||
|
|| strcmp (ztoken, "\\D") == 0)
|
||||||
|
ztoken = zphone;
|
||||||
|
else if (strcmp (ztoken, "\\T") == 0)
|
||||||
|
{
|
||||||
|
ztoken = zphone;
|
||||||
|
ftranslate = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! fchat (qconn, puuconf, &q->uuconf_schat,
|
||||||
|
(const struct uuconf_system *) NULL, q,
|
||||||
|
zphone, ftranslate, qconn->qport->uuconf_zname,
|
||||||
|
(long) 0))
|
||||||
|
{
|
||||||
|
(void) uuconf_dialer_free (puuconf, q);
|
||||||
|
if (! ffirst)
|
||||||
|
(void) uuconf_dialer_free (puuconf, qdialer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ffirst)
|
||||||
|
{
|
||||||
|
*ptdialerfound = DIALERFOUND_FREE;
|
||||||
|
ffirst = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(void) uuconf_dialer_free (puuconf, q);
|
||||||
|
|
||||||
|
if (*pzdialer != NULL)
|
||||||
|
++pzdialer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_TLI */
|
268
gnu/libexec/uucp/common_sources/trans.h
Normal file
268
gnu/libexec/uucp/common_sources/trans.h
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/* trans.h
|
||||||
|
Header file for file and command transfer routines.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The maximum possible number of channels. */
|
||||||
|
#define IMAX_CHAN (16)
|
||||||
|
|
||||||
|
/* The ifeatures field of the sdaemon structure is an or of the
|
||||||
|
following values. These values are sent during the uucico
|
||||||
|
handshake, and MUST NOT CHANGE. */
|
||||||
|
|
||||||
|
/* File size negotiation. */
|
||||||
|
#define FEATURE_SIZES (01)
|
||||||
|
|
||||||
|
/* File transfer restart. */
|
||||||
|
#define FEATURE_RESTART (02)
|
||||||
|
|
||||||
|
/* The E (execute) command. */
|
||||||
|
#define FEATURE_EXEC (04)
|
||||||
|
|
||||||
|
/* Version 1.03: requires decimal size in S and R command. Needless
|
||||||
|
to say, this should not be used by any new programs. */
|
||||||
|
#define FEATURE_V103 (010)
|
||||||
|
|
||||||
|
/* SVR4 UUCP: expects dummy string between notify field and size field
|
||||||
|
in send command. There is probably some meaning to this string,
|
||||||
|
but I don't know what it is. If I ever find out, this flag will
|
||||||
|
still be used to indicate it. */
|
||||||
|
#define FEATURE_SVR4 (020)
|
||||||
|
|
||||||
|
/* This structure is used to hold information concerning the
|
||||||
|
communication link established with the remote system. */
|
||||||
|
|
||||||
|
struct sdaemon
|
||||||
|
{
|
||||||
|
/* Global uuconf pointer. */
|
||||||
|
pointer puuconf;
|
||||||
|
/* Remote system information. */
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
/* Local name being used. */
|
||||||
|
const char *zlocalname;
|
||||||
|
/* Connection structure. */
|
||||||
|
struct sconnection *qconn;
|
||||||
|
/* Protocol being used. */
|
||||||
|
const struct sprotocol *qproto;
|
||||||
|
/* The largest file size permitted for a local request. */
|
||||||
|
long clocal_size;
|
||||||
|
/* The largest file size permitted for a remote request. */
|
||||||
|
long cremote_size;
|
||||||
|
/* The largest file size that may ever be transferred. */
|
||||||
|
long cmax_ever;
|
||||||
|
/* The remote system ulimit. */
|
||||||
|
long cmax_receive;
|
||||||
|
/* Features supported by the remote side. */
|
||||||
|
int ifeatures;
|
||||||
|
/* TRUE if we should request the remote side to hang up. */
|
||||||
|
boolean frequest_hangup;
|
||||||
|
/* TRUE if the remote side requested a hangup. */
|
||||||
|
boolean fhangup_requested;
|
||||||
|
/* TRUE if we are hanging up. */
|
||||||
|
boolean fhangup;
|
||||||
|
/* TRUE if the local system is currently the master. */
|
||||||
|
boolean fmaster;
|
||||||
|
/* TRUE if the local system placed the call. */
|
||||||
|
boolean fcaller;
|
||||||
|
/* UUCONF_RELIABLE_* flags for the connection. */
|
||||||
|
int ireliable;
|
||||||
|
/* If fcaller is FALSE, the lowest grade which may be transferred
|
||||||
|
during this call. */
|
||||||
|
char bgrade;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This structure is used to hold a file or command transfer which is
|
||||||
|
in progress. */
|
||||||
|
|
||||||
|
struct stransfer
|
||||||
|
{
|
||||||
|
/* Next file transfer in queue. */
|
||||||
|
struct stransfer *qnext;
|
||||||
|
/* Previous file transfer in queue. */
|
||||||
|
struct stransfer *qprev;
|
||||||
|
/* Points to the queue this structure is on. */
|
||||||
|
struct stransfer **pqqueue;
|
||||||
|
/* The function to call to send some data. */
|
||||||
|
boolean (*psendfn) P((struct stransfer *qtrans, struct sdaemon *qdaemon));
|
||||||
|
/* The function to call when data is received. */
|
||||||
|
boolean (*precfn) P((struct stransfer *qtrans, struct sdaemon *qdaemon,
|
||||||
|
const char *zdata, size_t cdata));
|
||||||
|
/* Type specific information. */
|
||||||
|
pointer pinfo;
|
||||||
|
/* TRUE if we are sending the file e (this is used to avoid a call
|
||||||
|
to psendfn). */
|
||||||
|
boolean fsendfile;
|
||||||
|
/* TRUE if we are receiving the file e (this is used to avoid a call
|
||||||
|
to precfn). */
|
||||||
|
boolean frecfile;
|
||||||
|
/* The file to read or write. */
|
||||||
|
openfile_t e;
|
||||||
|
/* The position we are at in the file. */
|
||||||
|
long ipos;
|
||||||
|
/* TRUE if we are waiting for a command string. */
|
||||||
|
boolean fcmd;
|
||||||
|
/* The command string we have so far. */
|
||||||
|
char *zcmd;
|
||||||
|
/* The length of the command string we have so far. */
|
||||||
|
size_t ccmd;
|
||||||
|
/* Local destination number. */
|
||||||
|
int ilocal;
|
||||||
|
/* Remote destination number. */
|
||||||
|
int iremote;
|
||||||
|
/* The command. */
|
||||||
|
struct scmd s;
|
||||||
|
/* A message to log when work starts. */
|
||||||
|
char *zlog;
|
||||||
|
/* The process time; imicros can be negative. */
|
||||||
|
long isecs;
|
||||||
|
long imicros;
|
||||||
|
/* Number of bytes sent or received. */
|
||||||
|
long cbytes;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reasons that a file transfer might fail. */
|
||||||
|
|
||||||
|
enum tfailure
|
||||||
|
{
|
||||||
|
/* No failure. */
|
||||||
|
FAILURE_NONE,
|
||||||
|
/* No permission for operation. */
|
||||||
|
FAILURE_PERM,
|
||||||
|
/* Can't open necessary file. */
|
||||||
|
FAILURE_OPEN,
|
||||||
|
/* Not enough space to receive file. */
|
||||||
|
FAILURE_SIZE,
|
||||||
|
/* File was received in a previous conversation. */
|
||||||
|
FAILURE_RECEIVED
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The main loop which talks to the remote system, passing transfer
|
||||||
|
requests and file back and forth. */
|
||||||
|
extern boolean floop P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Allocate a new transfer structure. */
|
||||||
|
extern struct stransfer *qtransalc P((struct scmd *qcmd));
|
||||||
|
|
||||||
|
/* Free a transfer structure. */
|
||||||
|
extern void utransfree P((struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Queue up local requests. If pfany is not NULL, this sets *pfany to
|
||||||
|
TRUE if there are, in fact, any local requests which can be done at
|
||||||
|
this point. */
|
||||||
|
extern boolean fqueue P((struct sdaemon *qdaemon, boolean *pfany));
|
||||||
|
|
||||||
|
/* Clear away any queued requests. This may be called more than once
|
||||||
|
at the end of a call. */
|
||||||
|
extern void uclear_queue P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Queue a new transfer request made by the local system. */
|
||||||
|
extern boolean fqueue_local P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Queue a new transfer request made by the remote system. */
|
||||||
|
extern boolean fqueue_remote P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Queue a transfer request which wants to send something. */
|
||||||
|
extern boolean fqueue_send P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Queue a transfer request which wants to receiving something. */
|
||||||
|
extern boolean fqueue_receive P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Prepare to send a file by local or remote request. */
|
||||||
|
extern boolean flocal_send_file_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd));
|
||||||
|
extern boolean fremote_send_file_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd,
|
||||||
|
int iremote));
|
||||||
|
|
||||||
|
/* Prepare to receive a file by local or remote request. */
|
||||||
|
extern boolean flocal_rec_file_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd));
|
||||||
|
extern boolean fremote_rec_file_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd,
|
||||||
|
int iremote));
|
||||||
|
|
||||||
|
/* Prepare to request work by local or remote request. */
|
||||||
|
extern boolean flocal_xcmd_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd));
|
||||||
|
extern boolean fremote_xcmd_init P((struct sdaemon *qdaemon,
|
||||||
|
struct scmd *qcmd,
|
||||||
|
int iremote));
|
||||||
|
|
||||||
|
/* We have lost the connection; record any in progress file transfers
|
||||||
|
in the statistics file and discard any temporary files. */
|
||||||
|
extern void ufailed P((struct sdaemon *qdaemon));
|
||||||
|
|
||||||
|
/* Check that there is enough disk space for a file receive. Return
|
||||||
|
FALSE if there is not. */
|
||||||
|
extern boolean frec_check_free P((struct stransfer *qtrans,
|
||||||
|
long cfree_space));
|
||||||
|
|
||||||
|
/* Discard the temporary file being used to receive a file, if
|
||||||
|
appropriate. */
|
||||||
|
extern boolean frec_discard_temp P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* Handle data received by a protocol. This is called by the protocol
|
||||||
|
specific routines as data comes in. The data is passed as two
|
||||||
|
buffers because that is convenient for packet based protocols, but
|
||||||
|
normally csecond will be 0. The ilocal argument is the local
|
||||||
|
channel number, and the iremote argument is the remote channel
|
||||||
|
number. Either may be -1, if the protocol does not have channels.
|
||||||
|
The ipos argument is the position in the file, if the protocol
|
||||||
|
knows it; for most protocols, this will be -1. The fallacked
|
||||||
|
argument should be set to TRUE if the remote has acknowledged all
|
||||||
|
outstanding data; see uwindow_acked, below, for details. This will
|
||||||
|
set *pfexit to TRUE if there is something for the main loop to do.
|
||||||
|
A file is complete is when a zero length buffer is passed (cfirst
|
||||||
|
== 0). A command is complete when data containing a null byte is
|
||||||
|
passed. This will return FALSE on error. If the protocol pfwait
|
||||||
|
entry point should exit and let the top level loop continue,
|
||||||
|
*pfexit will be set to TRUE (if pfexit is not NULL). This will not
|
||||||
|
set *pfexit to FALSE, so the caller must do that. */
|
||||||
|
extern boolean fgot_data P((struct sdaemon *qdaemon,
|
||||||
|
const char *zfirst, size_t cfirst,
|
||||||
|
const char *zsecond, size_t csecond,
|
||||||
|
int ilocal, int iremote,
|
||||||
|
long ipos, boolean fallacked,
|
||||||
|
boolean *pfexit));
|
||||||
|
|
||||||
|
/* This routine is called when an ack is sent for a file receive. */
|
||||||
|
extern void usent_receive_ack P((struct sdaemon *qdaemon,
|
||||||
|
struct stransfer *qtrans));
|
||||||
|
|
||||||
|
/* A protocol may call this routine to indicate the packets have been
|
||||||
|
acknowledged by the remote system. If the fallacked argument is
|
||||||
|
TRUE, then all outstanding packets have been acknowledged; for
|
||||||
|
convenience, this may also be indicated by passing fallacked as
|
||||||
|
TRUE to fgot_data, above. Otherwise this routine should be called
|
||||||
|
each time a complete window is acked by the remote system. The
|
||||||
|
transfer code uses this information to keep track of when an
|
||||||
|
acknowledgement of a file receive has been seen by the other side,
|
||||||
|
so that file receives may be handled cleanly if the connection is
|
||||||
|
lost. */
|
||||||
|
extern void uwindow_acked P((struct sdaemon *qdaemon,
|
||||||
|
boolean fallacked));
|
144
gnu/libexec/uucp/common_sources/util.c
Normal file
144
gnu/libexec/uucp/common_sources/util.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/* util.c
|
||||||
|
A couple of UUCP utility functions.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char util_rcsid[] = "$Id: util.c,v 1.1 1993/08/04 19:31:13 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Get information for an unknown system. This will leave the name
|
||||||
|
allocated on the heap. We could fix this by breaking the
|
||||||
|
abstraction and adding the name to qsys->palloc. It makes sure the
|
||||||
|
name is not too long, but takes no other useful action. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
funknown_system (puuconf, zsystem, qsys)
|
||||||
|
pointer puuconf;
|
||||||
|
const char *zsystem;
|
||||||
|
struct uuconf_system *qsys;
|
||||||
|
{
|
||||||
|
char *z;
|
||||||
|
int iuuconf;
|
||||||
|
|
||||||
|
if (strlen (zsystem) <= cSysdep_max_name_len)
|
||||||
|
z = zbufcpy (zsystem);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char **pznames, **pz;
|
||||||
|
boolean ffound;
|
||||||
|
|
||||||
|
z = zbufalc (cSysdep_max_name_len + 1);
|
||||||
|
memcpy (z, zsystem, cSysdep_max_name_len);
|
||||||
|
z[cSysdep_max_name_len] = '\0';
|
||||||
|
|
||||||
|
iuuconf = uuconf_system_names (puuconf, &pznames, TRUE);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
ffound = FALSE;
|
||||||
|
for (pz = pznames; *pz != NULL; pz++)
|
||||||
|
{
|
||||||
|
if (strcmp (*pz, z) == 0)
|
||||||
|
ffound = TRUE;
|
||||||
|
xfree ((pointer) *pz);
|
||||||
|
}
|
||||||
|
xfree ((pointer) pznames);
|
||||||
|
|
||||||
|
if (ffound)
|
||||||
|
{
|
||||||
|
ubuffree (z);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iuuconf = uuconf_system_unknown (puuconf, qsys);
|
||||||
|
if (iuuconf == UUCONF_NOT_FOUND)
|
||||||
|
{
|
||||||
|
ubuffree (z);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
for (; qsys != NULL; qsys = qsys->uuconf_qalternate)
|
||||||
|
qsys->uuconf_zname = z;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See whether a file is in a directory list, and make sure the user
|
||||||
|
has appropriate access. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fin_directory_list (zfile, pzdirs, zpubdir, fcheck, freadable, zuser)
|
||||||
|
const char *zfile;
|
||||||
|
char **pzdirs;
|
||||||
|
const char *zpubdir;
|
||||||
|
boolean fcheck;
|
||||||
|
boolean freadable;
|
||||||
|
const char *zuser;
|
||||||
|
{
|
||||||
|
boolean fmatch;
|
||||||
|
char **pz;
|
||||||
|
|
||||||
|
fmatch = FALSE;
|
||||||
|
|
||||||
|
for (pz = pzdirs; *pz != NULL; pz++)
|
||||||
|
{
|
||||||
|
char *zuse;
|
||||||
|
|
||||||
|
if (pz[0][0] == '!')
|
||||||
|
{
|
||||||
|
zuse = zsysdep_local_file (*pz + 1, zpubdir);
|
||||||
|
if (zuse == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (fsysdep_in_directory (zfile, zuse, FALSE,
|
||||||
|
FALSE, (const char *) NULL))
|
||||||
|
fmatch = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zuse = zsysdep_local_file (*pz, zpubdir);
|
||||||
|
if (zuse == NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (fsysdep_in_directory (zfile, zuse, fcheck,
|
||||||
|
freadable, zuser))
|
||||||
|
fmatch = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuffree (zuse);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmatch;
|
||||||
|
}
|
1496
gnu/libexec/uucp/common_sources/uuconf.h
Normal file
1496
gnu/libexec/uucp/common_sources/uuconf.h
Normal file
File diff suppressed because it is too large
Load Diff
367
gnu/libexec/uucp/common_sources/uucp.h
Normal file
367
gnu/libexec/uucp/common_sources/uucp.h
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
/* uucp.h
|
||||||
|
Header file for the UUCP package.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Get the system configuration parameters. */
|
||||||
|
#include "conf.h"
|
||||||
|
#include "policy.h"
|
||||||
|
|
||||||
|
/* Get a definition for ANSI_C if we weren't given one. */
|
||||||
|
#ifndef ANSI_C
|
||||||
|
#ifdef __STDC__
|
||||||
|
#define ANSI_C 1
|
||||||
|
#else /* ! defined (__STDC__) */
|
||||||
|
#define ANSI_C 0
|
||||||
|
#endif /* ! defined (__STDC__) */
|
||||||
|
#endif /* ! defined (ANSI_C) */
|
||||||
|
|
||||||
|
/* Pass this definition into uuconf.h. */
|
||||||
|
#define UUCONF_ANSI_C ANSI_C
|
||||||
|
|
||||||
|
/* We always include some standard header files. We need <signal.h>
|
||||||
|
to define sig_atomic_t. */
|
||||||
|
#if HAVE_STDDEF_H
|
||||||
|
#include <stddef.h>
|
||||||
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* On some systems we need <sys/types.h> to get sig_atomic_t or
|
||||||
|
size_t or time_t. */
|
||||||
|
#if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && HAVE_SIG_ATOMIC_T_IN_TYPES_H
|
||||||
|
#define USE_TYPES_H 1
|
||||||
|
#else
|
||||||
|
#if ! HAVE_SIZE_T_IN_STDDEF_H && HAVE_SIZE_T_IN_TYPES_H
|
||||||
|
#define USE_TYPES_H 1
|
||||||
|
#else
|
||||||
|
#if ! HAVE_TIME_T_IN_TIME_H && HAVE_TIME_T_IN_TYPES_H
|
||||||
|
#define USE_TYPES_H 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef USE_TYPES_H
|
||||||
|
#define USE_TYPES_H 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make sure we have sig_atomic_t. */
|
||||||
|
#if ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && ! HAVE_SIG_ATOMIC_T_IN_TYPES_H
|
||||||
|
#ifndef SIG_ATOMIC_T
|
||||||
|
/* There is no portable definition for sig_atomic_t. */
|
||||||
|
#define SIG_ATOMIC_T char
|
||||||
|
#endif /* ! defined (SIG_ATOMIC_T) */
|
||||||
|
typedef SIG_ATOMIC_T sig_atomic_t;
|
||||||
|
#endif /* ! HAVE_SIG_ATOMIC_T_IN_SIGNAL_H && ! HAVE_SIG_ATOMIC_T_IN_TYPES_H */
|
||||||
|
|
||||||
|
/* Make sure we have size_t. We use int as the default because the
|
||||||
|
main use of this type is to provide an argument to malloc and
|
||||||
|
realloc. On a system which does not define size_t, int is
|
||||||
|
certainly the correct type to use. */
|
||||||
|
#if ! HAVE_SIZE_T_IN_STDDEF_H && ! HAVE_SIZE_T_IN_TYPES_H
|
||||||
|
#ifndef SIZE_T
|
||||||
|
#define SIZE_T unsigned
|
||||||
|
#endif /* ! defined (SIZE_T) */
|
||||||
|
typedef SIZE_T size_t;
|
||||||
|
#endif /* ! HAVE_SIZE_T_IN_STDDEF_H && ! HAVE_SIZE_T_IN_TYPES_H */
|
||||||
|
|
||||||
|
/* Make sure we have time_t. We use long as the default. We don't
|
||||||
|
bother to let conf.h override this, since on a system which doesn't
|
||||||
|
define time_t long must be correct. */
|
||||||
|
#if ! HAVE_TIME_T_IN_TIME_H && ! HAVE_TIME_T_IN_TYPES_H
|
||||||
|
typedef long time_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set up some definitions for both ANSI C and Classic C.
|
||||||
|
|
||||||
|
P() -- for function prototypes (e.g. extern int foo P((int)) ).
|
||||||
|
pointer -- for a generic pointer (i.e. void *).
|
||||||
|
constpointer -- for a generic pointer to constant data.
|
||||||
|
BUCHAR -- to convert a character to unsigned. */
|
||||||
|
#if ANSI_C
|
||||||
|
#if ! HAVE_VOID || ! HAVE_UNSIGNED_CHAR
|
||||||
|
#error ANSI C compiler without void or unsigned char
|
||||||
|
#endif
|
||||||
|
#define P(x) x
|
||||||
|
typedef void *pointer;
|
||||||
|
typedef const void *constpointer;
|
||||||
|
#define BUCHAR(b) ((unsigned char) (b))
|
||||||
|
#else /* ! ANSI_C */
|
||||||
|
/* Handle uses of const, volatile and void in Classic C. */
|
||||||
|
#define const
|
||||||
|
#define volatile
|
||||||
|
#if ! HAVE_VOID
|
||||||
|
#define void int
|
||||||
|
#endif
|
||||||
|
#define P(x) ()
|
||||||
|
typedef char *pointer;
|
||||||
|
typedef const char *constpointer;
|
||||||
|
#if HAVE_UNSIGNED_CHAR
|
||||||
|
#define BUCHAR(b) ((unsigned char) (b))
|
||||||
|
#else /* ! HAVE_UNSIGNED_CHAR */
|
||||||
|
/* This should work on most systems, but not necessarily all. */
|
||||||
|
#define BUCHAR(b) ((b) & 0xff)
|
||||||
|
#endif /* ! HAVE_UNSIGNED_CHAR */
|
||||||
|
#endif /* ! ANSI_C */
|
||||||
|
|
||||||
|
/* Make sure we have a definition for offsetof. */
|
||||||
|
#ifndef offsetof
|
||||||
|
#define offsetof(type, field) \
|
||||||
|
((size_t) ((char *) &(((type *) 0)->field) - (char *) (type *) 0))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Only use inline with gcc. */
|
||||||
|
#ifndef __GNUC__
|
||||||
|
#define __inline__
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the string functions, which are used throughout the code. */
|
||||||
|
#if HAVE_MEMORY_H
|
||||||
|
#include <memory.h>
|
||||||
|
#else
|
||||||
|
/* We really need a definition for memchr, and this should not
|
||||||
|
conflict with anything in <string.h>. I hope. */
|
||||||
|
extern pointer memchr ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#else /* ! HAVE_STRING_H */
|
||||||
|
#if HAVE_STRINGS_H
|
||||||
|
#include <strings.h>
|
||||||
|
#else /* ! HAVE_STRINGS_H */
|
||||||
|
extern char *strcpy (), *strncpy (), *strchr (), *strrchr (), *strtok ();
|
||||||
|
extern char *strcat (), *strerror (), *strstr ();
|
||||||
|
extern size_t strlen (), strspn (), strcspn ();
|
||||||
|
#if ! HAVE_MEMORY_H
|
||||||
|
extern pointer memcpy (), memchr ();
|
||||||
|
#endif /* ! HAVE_MEMORY_H */
|
||||||
|
#endif /* ! HAVE_STRINGS_H */
|
||||||
|
#endif /* ! HAVE_STRING_H */
|
||||||
|
|
||||||
|
/* Get what we need from <stdlib.h>. */
|
||||||
|
#if HAVE_STDLIB_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#else /* ! HAVE_STDLIB_H */
|
||||||
|
extern pointer malloc (), realloc (), bsearch ();
|
||||||
|
extern long strtol ();
|
||||||
|
extern char *getenv ();
|
||||||
|
#endif /* ! HAVE_STDLIB_H */
|
||||||
|
|
||||||
|
/* NeXT uses <libc.h> to declare a bunch of functions. */
|
||||||
|
#if HAVE_LIBC_H
|
||||||
|
#include <libc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Make sure we have the EXIT_ macros. */
|
||||||
|
#ifndef EXIT_SUCCESS
|
||||||
|
#define EXIT_SUCCESS (0)
|
||||||
|
#endif
|
||||||
|
#ifndef EXIT_FAILURE
|
||||||
|
#define EXIT_FAILURE (1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we need to declare errno, do so. I don't want to always do
|
||||||
|
this, because some system might theoretically have a different
|
||||||
|
declaration for errno. On a POSIX system this is sure to work. */
|
||||||
|
#if ! HAVE_ERRNO_DECLARATION
|
||||||
|
extern int errno;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If the system has the socket call, guess that we can compile the
|
||||||
|
TCP code. */
|
||||||
|
#define HAVE_TCP HAVE_SOCKET
|
||||||
|
|
||||||
|
/* If the system has the t_open call, guess that we can compile the
|
||||||
|
TLI code. */
|
||||||
|
#define HAVE_TLI HAVE_T_OPEN
|
||||||
|
|
||||||
|
/* The boolean type holds boolean values. */
|
||||||
|
typedef int boolean;
|
||||||
|
#undef TRUE
|
||||||
|
#undef FALSE
|
||||||
|
#define TRUE (1)
|
||||||
|
#define FALSE (0)
|
||||||
|
|
||||||
|
/* The openfile_t type holds an open file. This depends on whether we
|
||||||
|
are using stdio or not. */
|
||||||
|
#if USE_STDIO
|
||||||
|
|
||||||
|
typedef FILE *openfile_t;
|
||||||
|
#define EFILECLOSED ((FILE *) NULL)
|
||||||
|
#define ffileisopen(e) ((e) != NULL)
|
||||||
|
#define ffileeof(e) feof (e)
|
||||||
|
#define cfileread(e, z, c) fread ((z), 1, (c), (e))
|
||||||
|
#define ffilereaderror(e, c) ferror (e)
|
||||||
|
#define cfilewrite(e, z, c) fwrite ((z), 1, (c), (e))
|
||||||
|
#ifdef SEEK_SET
|
||||||
|
#define ffileseek(e, i) (fseek ((e), (long) (i), SEEK_SET) == 0)
|
||||||
|
#define ffilerewind(e) (fseek ((e), (long) 0, SEEK_SET) == 0)
|
||||||
|
#else
|
||||||
|
#define ffileseek(e, i) (fseek ((e), (long) (i), 0) == 0)
|
||||||
|
#define ffilerewind(e) (fseek ((e), (long) 0, 0) == 0)
|
||||||
|
#endif
|
||||||
|
#define ffileclose(e) (fclose (e) == 0)
|
||||||
|
|
||||||
|
#else /* ! USE_STDIO */
|
||||||
|
|
||||||
|
#if HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int openfile_t;
|
||||||
|
#define EFILECLOSED (-1)
|
||||||
|
#define ffileisopen(e) ((e) >= 0)
|
||||||
|
#define ffileeof(e) (FALSE)
|
||||||
|
#define cfileread(e, z, c) read ((e), (z), (c))
|
||||||
|
#define ffilereaderror(e, c) ((c) < 0)
|
||||||
|
#define cfilewrite(e, z, c) write ((e), (z), (c))
|
||||||
|
#ifdef SEEK_SET
|
||||||
|
#define ffileseek(e, i) (lseek ((e), (long) i, SEEK_SET) >= 0)
|
||||||
|
#define ffilerewind(e) (lseek ((e), (long) 0, SEEK_SET) >= 0)
|
||||||
|
#else
|
||||||
|
#define ffileseek(e, i) (lseek ((e), (long) i, 0) >= 0)
|
||||||
|
#define ffilerewind(e) (lseek ((e), (long) 0, 0) >= 0)
|
||||||
|
#endif
|
||||||
|
#define ffileclose(e) (close (e) >= 0)
|
||||||
|
|
||||||
|
#endif /* ! USE_STDIO */
|
||||||
|
|
||||||
|
/* A prototype for main to avoid warnings from gcc 2.0
|
||||||
|
-Wmissing-prototype option. */
|
||||||
|
extern int main P((int argc, char **argv));
|
||||||
|
|
||||||
|
/* Some standard routines which we only define if they are not present
|
||||||
|
on the system we are compiling on. */
|
||||||
|
|
||||||
|
#if ! HAVE_GETLINE
|
||||||
|
/* Read a line from a file. */
|
||||||
|
extern int getline P((char **pz, size_t *pc, FILE *e));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_REMOVE
|
||||||
|
/* Erase a file. */
|
||||||
|
#undef remove
|
||||||
|
extern int remove P((const char *zfile));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_STRDUP
|
||||||
|
/* Copy a string into memory. */
|
||||||
|
extern char *strdup P((const char *z));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_STRSTR
|
||||||
|
/* Look for one string within another. */
|
||||||
|
extern char *strstr P((const char *zouter, const char *zinner));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_STRCASECMP
|
||||||
|
#if HAVE_STRICMP
|
||||||
|
#define strcasecmp stricmp
|
||||||
|
#else /* ! HAVE_STRICMP */
|
||||||
|
/* Rename strcasecmp to avoid ANSI C name space. */
|
||||||
|
#define strcasecmp xstrcasecmp
|
||||||
|
extern int strcasecmp P((const char *z1, const char *z2));
|
||||||
|
#endif /* ! HAVE_STRICMP */
|
||||||
|
#endif /* ! HAVE_STRCASECMP */
|
||||||
|
|
||||||
|
#if ! HAVE_STRNCASECMP
|
||||||
|
#if HAVE_STRNICMP
|
||||||
|
#define strncasecmp strnicmp
|
||||||
|
#else /* ! HAVE_STRNICMP */
|
||||||
|
/* Rename strncasecmp to avoid ANSI C name space. */
|
||||||
|
#define strncasecmp xstrncasecmp
|
||||||
|
extern int strncasecmp P((const char *z1, const char *z2, size_t clen));
|
||||||
|
#endif /* ! HAVE_STRNICMP */
|
||||||
|
#endif /* ! HAVE_STRNCASECMP */
|
||||||
|
|
||||||
|
#if ! HAVE_STRERROR
|
||||||
|
/* Get a string corresponding to an error message. */
|
||||||
|
#undef strerror
|
||||||
|
extern char *strerror P((int ierr));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the appropriate definitions for memcmp, memcpy, memchr and
|
||||||
|
bzero. */
|
||||||
|
#if ! HAVE_MEMCMP
|
||||||
|
#if HAVE_BCMP
|
||||||
|
#define memcmp(p1, p2, c) bcmp ((p1), (p2), (c))
|
||||||
|
#else /* ! HAVE_BCMP */
|
||||||
|
extern int memcmp P((constpointer p1, constpointer p2, size_t c));
|
||||||
|
#endif /* ! HAVE_BCMP */
|
||||||
|
#endif /* ! HAVE_MEMCMP */
|
||||||
|
|
||||||
|
#if ! HAVE_MEMCPY
|
||||||
|
#if HAVE_BCOPY
|
||||||
|
#define memcpy(pto, pfrom, c) bcopy ((pfrom), (pto), (c))
|
||||||
|
#else /* ! HAVE_BCOPY */
|
||||||
|
extern pointer memcpy P((pointer pto, constpointer pfrom, size_t c));
|
||||||
|
#endif /* ! HAVE_BCOPY */
|
||||||
|
#endif /* ! HAVE_MEMCPY */
|
||||||
|
|
||||||
|
#if ! HAVE_MEMCHR
|
||||||
|
extern pointer memchr P((constpointer p, int b, size_t c));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_BZERO
|
||||||
|
#if HAVE_MEMSET
|
||||||
|
#define bzero(p, c) memset ((p), 0, (c))
|
||||||
|
#else /* ! HAVE_MEMSET */
|
||||||
|
extern void bzero P((pointer p, int c));
|
||||||
|
#endif /* ! HAVE_MEMSET */
|
||||||
|
#endif /* ! HAVE_BZERO */
|
||||||
|
|
||||||
|
/* Look up a character in a string. */
|
||||||
|
#if ! HAVE_STRCHR
|
||||||
|
#if HAVE_INDEX
|
||||||
|
#define strchr index
|
||||||
|
extern char *index ();
|
||||||
|
#else /* ! HAVE_INDEX */
|
||||||
|
extern char *strchr P((const char *z, int b));
|
||||||
|
#endif /* ! HAVE_INDEX */
|
||||||
|
#endif /* ! HAVE_STRCHR */
|
||||||
|
|
||||||
|
#if ! HAVE_STRRCHR
|
||||||
|
#if HAVE_RINDEX
|
||||||
|
#define strrchr rindex
|
||||||
|
extern char *rindex ();
|
||||||
|
#else /* ! HAVE_RINDEX */
|
||||||
|
extern char *strrchr P((const char *z, int b));
|
||||||
|
#endif /* ! HAVE_RINDEX */
|
||||||
|
#endif /* ! HAVE_STRRCHR */
|
||||||
|
|
||||||
|
/* Turn a string into a long integer. */
|
||||||
|
#if ! HAVE_STRTOL
|
||||||
|
extern long strtol P((const char *, char **, int));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Lookup a key in a sorted array. */
|
||||||
|
#if ! HAVE_BSEARCH
|
||||||
|
extern pointer bsearch P((constpointer pkey, constpointer parray,
|
||||||
|
size_t celes, size_t cbytes,
|
||||||
|
int (*pficmp) P((constpointer, constpointer))));
|
||||||
|
#endif
|
445
gnu/libexec/uucp/common_sources/uudefs.h
Normal file
445
gnu/libexec/uucp/common_sources/uudefs.h
Normal file
@ -0,0 +1,445 @@
|
|||||||
|
/* uudefs.h
|
||||||
|
Miscellaneous definitions for the UUCP package.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ANSI_C
|
||||||
|
/* These structures are used in prototypes but are not defined in this
|
||||||
|
header file. */
|
||||||
|
struct uuconf_system;
|
||||||
|
struct uuconf_timespan;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The tlog enumeration holds the different types of logging. */
|
||||||
|
enum tlog
|
||||||
|
{
|
||||||
|
/* Normal log entry. */
|
||||||
|
LOG_NORMAL,
|
||||||
|
/* Error log entry. */
|
||||||
|
LOG_ERROR,
|
||||||
|
/* Fatal log entry. */
|
||||||
|
LOG_FATAL
|
||||||
|
#if DEBUG > 1
|
||||||
|
,
|
||||||
|
/* Debugging log entry. */
|
||||||
|
LOG_DEBUG,
|
||||||
|
/* Start debugging log entry. */
|
||||||
|
LOG_DEBUG_START,
|
||||||
|
/* Continue debugging log entry. */
|
||||||
|
LOG_DEBUG_CONTINUE,
|
||||||
|
/* End debugging log entry. */
|
||||||
|
LOG_DEBUG_END
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The tstatus_type enumeration holds the kinds of status information
|
||||||
|
we put in the status file. The order of entries here corresponds
|
||||||
|
to the order of entries in the azStatus array. */
|
||||||
|
enum tstatus_type
|
||||||
|
{
|
||||||
|
/* Conversation complete. */
|
||||||
|
STATUS_COMPLETE,
|
||||||
|
/* Port unavailable. */
|
||||||
|
STATUS_PORT_FAILED,
|
||||||
|
/* Dial failed. */
|
||||||
|
STATUS_DIAL_FAILED,
|
||||||
|
/* Login failed. */
|
||||||
|
STATUS_LOGIN_FAILED,
|
||||||
|
/* Handshake failed. */
|
||||||
|
STATUS_HANDSHAKE_FAILED,
|
||||||
|
/* Failed after logging in. */
|
||||||
|
STATUS_FAILED,
|
||||||
|
/* Talking to remote system. */
|
||||||
|
STATUS_TALKING,
|
||||||
|
/* Wrong time to call. */
|
||||||
|
STATUS_WRONG_TIME,
|
||||||
|
/* Number of status values. */
|
||||||
|
STATUS_VALUES
|
||||||
|
};
|
||||||
|
|
||||||
|
/* An array to convert status entries to strings. If more status entries
|
||||||
|
are added, this array must be extended. */
|
||||||
|
extern const char *azStatus[];
|
||||||
|
|
||||||
|
/* The sstatus structure holds the contents of a system status file. */
|
||||||
|
struct sstatus
|
||||||
|
{
|
||||||
|
/* Current status of conversation. */
|
||||||
|
enum tstatus_type ttype;
|
||||||
|
/* Number of failed retries. */
|
||||||
|
int cretries;
|
||||||
|
/* Time of last call in seconds since epoch (determined by
|
||||||
|
ixsysdep_time). */
|
||||||
|
long ilast;
|
||||||
|
/* Number of seconds until a retry is permitted. */
|
||||||
|
int cwait;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* How long we have to wait for the next call, given the number of retries
|
||||||
|
we have already made. This should probably be configurable. */
|
||||||
|
#define CRETRY_WAIT(c) ((c) * 10 * 60)
|
||||||
|
|
||||||
|
/* The scmd structure holds a complete UUCP command. */
|
||||||
|
struct scmd
|
||||||
|
{
|
||||||
|
/* Command ('S' for send, 'R' for receive, 'X' for execute, 'E' for
|
||||||
|
simple execution, 'H' for hangup, 'Y' for hangup confirm, 'N' for
|
||||||
|
hangup deny). */
|
||||||
|
char bcmd;
|
||||||
|
/* At least one compiler needs an explicit padding byte here. */
|
||||||
|
char bdummy;
|
||||||
|
/* Sequence handle for fsysdep_did_work. */
|
||||||
|
pointer pseq;
|
||||||
|
/* File name to transfer from. */
|
||||||
|
const char *zfrom;
|
||||||
|
/* File name to transfer to. */
|
||||||
|
const char *zto;
|
||||||
|
/* User who requested transfer. */
|
||||||
|
const char *zuser;
|
||||||
|
/* Options. */
|
||||||
|
const char *zoptions;
|
||||||
|
/* Temporary file name ('S' and 'E'). */
|
||||||
|
const char *ztemp;
|
||||||
|
/* Mode to give newly created file ('S' and 'E'). */
|
||||||
|
unsigned int imode;
|
||||||
|
/* User to notify on remote system (optional; 'S' and 'E'). */
|
||||||
|
const char *znotify;
|
||||||
|
/* File size (-1 if not supplied) ('S', 'E' and 'R'). */
|
||||||
|
long cbytes;
|
||||||
|
/* Command to execute ('E'). */
|
||||||
|
const char *zcmd;
|
||||||
|
/* Position to restart from ('R'). */
|
||||||
|
long ipos;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
|
||||||
|
/* We allow independent control over several different types of
|
||||||
|
debugging output, using a bit string with individual bits dedicated
|
||||||
|
to particular debugging types. */
|
||||||
|
|
||||||
|
/* The bit string is stored in iDebug. */
|
||||||
|
extern int iDebug;
|
||||||
|
|
||||||
|
/* Debug abnormal events. */
|
||||||
|
#define DEBUG_ABNORMAL (01)
|
||||||
|
/* Debug chat scripts. */
|
||||||
|
#define DEBUG_CHAT (02)
|
||||||
|
/* Debug initial handshake. */
|
||||||
|
#define DEBUG_HANDSHAKE (04)
|
||||||
|
/* Debug UUCP protocol. */
|
||||||
|
#define DEBUG_UUCP_PROTO (010)
|
||||||
|
/* Debug protocols. */
|
||||||
|
#define DEBUG_PROTO (020)
|
||||||
|
/* Debug port actions. */
|
||||||
|
#define DEBUG_PORT (040)
|
||||||
|
/* Debug configuration files. */
|
||||||
|
#define DEBUG_CONFIG (0100)
|
||||||
|
/* Debug spool directory actions. */
|
||||||
|
#define DEBUG_SPOOLDIR (0200)
|
||||||
|
/* Debug executions. */
|
||||||
|
#define DEBUG_EXECUTE (0400)
|
||||||
|
/* Debug incoming data. */
|
||||||
|
#define DEBUG_INCOMING (01000)
|
||||||
|
/* Debug outgoing data. */
|
||||||
|
#define DEBUG_OUTGOING (02000)
|
||||||
|
|
||||||
|
/* Maximum possible value for iDebug. */
|
||||||
|
#define DEBUG_MAX (03777)
|
||||||
|
|
||||||
|
/* Intializer for array of debug names. The index of the name in the
|
||||||
|
array is the corresponding bit position in iDebug. We only check
|
||||||
|
for prefixes, so these names only need to be long enough to
|
||||||
|
distinguish each name from every other. The last entry must be
|
||||||
|
NULL. The string "all" is also recognized to turn on all
|
||||||
|
debugging. */
|
||||||
|
#define DEBUG_NAMES \
|
||||||
|
{ "a", "ch", "h", "u", "pr", "po", "co", "s", "e", "i", "o", NULL }
|
||||||
|
|
||||||
|
/* The prefix to use to turn off all debugging. */
|
||||||
|
#define DEBUG_NONE "n"
|
||||||
|
|
||||||
|
/* Check whether a particular type of debugging is being done. */
|
||||||
|
#define FDEBUGGING(i) ((iDebug & (i)) != 0)
|
||||||
|
|
||||||
|
/* These macros are used to output debugging information. I use
|
||||||
|
several different macros depending on the number of arguments
|
||||||
|
because no macro can take a variable number of arguments and I
|
||||||
|
don't want to use double parentheses. */
|
||||||
|
#define DEBUG_MESSAGE0(i, z) \
|
||||||
|
do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z)); } while (0)
|
||||||
|
#define DEBUG_MESSAGE1(i, z, a1) \
|
||||||
|
do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1)); } while (0)
|
||||||
|
#define DEBUG_MESSAGE2(i, z, a1, a2) \
|
||||||
|
do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1), (a2)); } while (0)
|
||||||
|
#define DEBUG_MESSAGE3(i, z, a1, a2, a3) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (FDEBUGGING (i)) \
|
||||||
|
ulog (LOG_DEBUG, (z), (a1), (a2), (a3)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (FDEBUGGING (i)) \
|
||||||
|
ulog (LOG_DEBUG, (z), (a1), (a2), (a3), (a4)); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
|
||||||
|
#else /* DEBUG <= 1 */
|
||||||
|
|
||||||
|
/* If debugging information is not being compiled, provide versions of
|
||||||
|
the debugging macros which just disappear. */
|
||||||
|
#define DEBUG_MESSAGE0(i, z)
|
||||||
|
#define DEBUG_MESSAGE1(i, z, a1)
|
||||||
|
#define DEBUG_MESSAGE2(i, z, a1, a2)
|
||||||
|
#define DEBUG_MESSAGE3(i, z, a1, a2, a3)
|
||||||
|
#define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4)
|
||||||
|
|
||||||
|
#endif /* DEBUG <= 1 */
|
||||||
|
|
||||||
|
/* Functions. */
|
||||||
|
|
||||||
|
/* Given an unknown system name, return information for an unknown
|
||||||
|
system. If unknown systems are not permitted, this returns FALSE.
|
||||||
|
Otherwise, it translates the name as necessary for the spool
|
||||||
|
directory, and fills in *qsys. */
|
||||||
|
extern boolean funknown_system P((pointer puuconf, const char *zsystem,
|
||||||
|
struct uuconf_system *qsys));
|
||||||
|
|
||||||
|
/* See whether a file belongs in the spool directory. */
|
||||||
|
extern boolean fspool_file P((const char *zfile));
|
||||||
|
|
||||||
|
/* See if the current time matches a time span. If not, return FALSE.
|
||||||
|
Otherwise, return TRUE and set *pival and *pcretry to the values
|
||||||
|
from the matching element of the span. */
|
||||||
|
extern boolean ftimespan_match P((const struct uuconf_timespan *qspan,
|
||||||
|
long *pival, int *pcretry));
|
||||||
|
|
||||||
|
/* Determine the maximum size that may ever be transferred, given a
|
||||||
|
timesize span. If there are any time gaps larger than 1 hour not
|
||||||
|
described by the timesize span, this returns -1. Otherwise it
|
||||||
|
returns the largest size that may be transferred at some time. */
|
||||||
|
extern long cmax_size_ever P((const struct uuconf_timespan *qtimesize));
|
||||||
|
|
||||||
|
/* Send mail about a file transfer. */
|
||||||
|
extern boolean fmail_transfer P((boolean fok, const char *zuser,
|
||||||
|
const char *zmail, const char *zwhy,
|
||||||
|
const char *zfrom, const char *zfromsys,
|
||||||
|
const char *zto, const char *ztosys,
|
||||||
|
const char *zsaved));
|
||||||
|
|
||||||
|
/* See whether a file is in one of a list of directories. The zpubdir
|
||||||
|
argument is used to pass the directory names to zsysdep_local_file.
|
||||||
|
If fcheck is FALSE, this does not check accessibility. Otherwise,
|
||||||
|
if freadable is TRUE, the user zuser must have read access to the
|
||||||
|
file and all appropriate directories; if freadable is FALSE zuser
|
||||||
|
must have write access to the appropriate directories. The zuser
|
||||||
|
argument may be NULL, in which case all users must have the
|
||||||
|
appropriate access (this is used for a remote request). */
|
||||||
|
extern boolean fin_directory_list P((const char *zfile,
|
||||||
|
char **pzdirs,
|
||||||
|
const char *zpubdir,
|
||||||
|
boolean fcheck,
|
||||||
|
boolean freadable,
|
||||||
|
const char *zuser));
|
||||||
|
|
||||||
|
/* Parse a command string. */
|
||||||
|
extern boolean fparse_cmd P((char *zcmd, struct scmd *qcmd));
|
||||||
|
|
||||||
|
/* Make a log entry. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define GNUC_VERSION __GNUC__
|
||||||
|
#else
|
||||||
|
#define GNUC_VERSION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ANSI_C && HAVE_VFPRINTF
|
||||||
|
extern void ulog P((enum tlog ttype, const char *zfmt, ...))
|
||||||
|
#if GNUC_VERSION > 1
|
||||||
|
__attribute__ ((format (printf, 2, 3)))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
#else
|
||||||
|
extern void ulog ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef GNUC_VERSION
|
||||||
|
|
||||||
|
/* Report an error returned by one of the uuconf routines. */
|
||||||
|
extern void ulog_uuconf P((enum tlog ttype, pointer puuconf,
|
||||||
|
int iuuconf));
|
||||||
|
|
||||||
|
/* Set the function to call if a fatal error occurs. */
|
||||||
|
extern void ulog_fatal_fn P((void (*pfn) P((void))));
|
||||||
|
|
||||||
|
/* If ffile is TRUE, send log entries to the log file rather than to
|
||||||
|
stderr. */
|
||||||
|
extern void ulog_to_file P((pointer puuconf, boolean ffile));
|
||||||
|
|
||||||
|
/* Set the ID number used by the logging functions. */
|
||||||
|
extern void ulog_id P((int iid));
|
||||||
|
|
||||||
|
/* Set the system name used by the logging functions. */
|
||||||
|
extern void ulog_system P((const char *zsystem));
|
||||||
|
|
||||||
|
/* Set the system and user name used by the logging functions. */
|
||||||
|
extern void ulog_user P((const char *zuser));
|
||||||
|
|
||||||
|
/* Set the device name used by the logging functions. */
|
||||||
|
extern void ulog_device P((const char *zdevice));
|
||||||
|
|
||||||
|
/* Close the log file. */
|
||||||
|
extern void ulog_close P((void));
|
||||||
|
|
||||||
|
/* Make an entry in the statistics file. */
|
||||||
|
extern void ustats P((boolean fsucceeded, const char *zuser,
|
||||||
|
const char *zsystem, boolean fsent,
|
||||||
|
long cbytes, long csecs, long cmicros,
|
||||||
|
boolean fmaster));
|
||||||
|
|
||||||
|
/* Close the statistics file. */
|
||||||
|
extern void ustats_close P((void));
|
||||||
|
|
||||||
|
#if DEBUG > 1
|
||||||
|
/* A debugging routine to output a buffer. This outputs zhdr, the
|
||||||
|
buffer length clen, and the contents of the buffer in quotation
|
||||||
|
marks. */
|
||||||
|
extern void udebug_buffer P((const char *zhdr, const char *zbuf,
|
||||||
|
size_t clen));
|
||||||
|
|
||||||
|
/* A debugging routine to make a readable version of a character.
|
||||||
|
This takes a buffer at least 5 bytes long, and returns the length
|
||||||
|
of the string it put into it (not counting the null byte). */
|
||||||
|
extern size_t cdebug_char P((char *z, int ichar));
|
||||||
|
|
||||||
|
/* Parse a debugging option string. This can either be a number or a
|
||||||
|
comma separated list of debugging names. This returns a value for
|
||||||
|
iDebug. */
|
||||||
|
extern int idebug_parse P((const char *));
|
||||||
|
|
||||||
|
#endif /* DEBUG <= 1 */
|
||||||
|
|
||||||
|
/* Copy one file to another. */
|
||||||
|
extern boolean fcopy_file P((const char *zfrom, const char *zto,
|
||||||
|
boolean fpublic, boolean fmkdirs));
|
||||||
|
|
||||||
|
/* Copy an open file to another. */
|
||||||
|
extern boolean fcopy_open_file P((openfile_t efrom, const char *zto,
|
||||||
|
boolean fpublic, boolean fmkdirs));
|
||||||
|
|
||||||
|
/* Translate escape sequences in a buffer, leaving the result in the
|
||||||
|
same buffer and returning the length. */
|
||||||
|
extern size_t cescape P((char *zbuf));
|
||||||
|
|
||||||
|
/* Get a buffer to hold a string of a given size. The buffer should
|
||||||
|
be freed with ubuffree. */
|
||||||
|
extern char *zbufalc P((size_t csize));
|
||||||
|
|
||||||
|
/* Call zbufalc to allocate a buffer and copy a string into it. */
|
||||||
|
extern char *zbufcpy P((const char *z));
|
||||||
|
|
||||||
|
/* Free up a buffer returned by zbufalc or zbufcpy. */
|
||||||
|
extern void ubuffree P((char *z));
|
||||||
|
|
||||||
|
/* Allocate memory without fail. */
|
||||||
|
extern pointer xmalloc P((size_t));
|
||||||
|
|
||||||
|
/* Realloc memory without fail. */
|
||||||
|
extern pointer xrealloc P((pointer, size_t));
|
||||||
|
|
||||||
|
/* Free memory (accepts NULL pointers, which some libraries erroneously
|
||||||
|
do not). */
|
||||||
|
extern void xfree P((pointer));
|
||||||
|
|
||||||
|
/* Global variables. */
|
||||||
|
|
||||||
|
/* The name of the program being run. This is statically initialized,
|
||||||
|
although it should perhaps be set from argv[0]. */
|
||||||
|
extern char abProgram[];
|
||||||
|
|
||||||
|
/* When a signal occurs, the signal handlers sets the appropriate
|
||||||
|
element of the arrays afSignal and afLog_signal to TRUE. The
|
||||||
|
afSignal array is used to check whether a signal occurred. The
|
||||||
|
afLog_signal array tells ulog to log the signal; ulog will clear
|
||||||
|
the element after logging it, which means that if a signal comes in
|
||||||
|
at just the right moment it will not be logged. It will always be
|
||||||
|
recorded in afSignal, though. At the moment we handle 5 signals:
|
||||||
|
SIGHUP, SIGINT, SIGQUIT, SIGTERM and SIGPIPE (the Unix code also
|
||||||
|
handles SIGALRM). If we want to handle more, the afSignal array
|
||||||
|
must be extended; I see little point to handling any of the other
|
||||||
|
ANSI C or POSIX signals, as they are either unlikely to occur
|
||||||
|
(SIGABRT, SIGUSR1) or nearly impossible to handle cleanly (SIGILL,
|
||||||
|
SIGSEGV). SIGHUP is only logged if fLog_sighup is TRUE. */
|
||||||
|
#define INDEXSIG_SIGHUP (0)
|
||||||
|
#define INDEXSIG_SIGINT (1)
|
||||||
|
#define INDEXSIG_SIGQUIT (2)
|
||||||
|
#define INDEXSIG_SIGTERM (3)
|
||||||
|
#define INDEXSIG_SIGPIPE (4)
|
||||||
|
#define INDEXSIG_COUNT (5)
|
||||||
|
|
||||||
|
extern volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
|
||||||
|
extern volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
|
||||||
|
extern boolean fLog_sighup;
|
||||||
|
|
||||||
|
/* The names of the signals to use in error messages, as an
|
||||||
|
initializer for an array. */
|
||||||
|
#define INDEXSIG_NAMES \
|
||||||
|
{ "hangup", "interrupt", "quit", "termination", "SIGPIPE" }
|
||||||
|
|
||||||
|
/* Check to see whether we've received a signal. It would be nice if
|
||||||
|
we could use a single variable for this, but we sometimes want to
|
||||||
|
clear our knowledge of a signal and that would cause race
|
||||||
|
conditions (clearing a single element of the array is not a race
|
||||||
|
assuming that we don't care about a particular signal, even if it
|
||||||
|
occurs after we've examined the array). */
|
||||||
|
#define FGOT_SIGNAL() \
|
||||||
|
(afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGINT] \
|
||||||
|
|| afSignal[INDEXSIG_SIGQUIT] || afSignal[INDEXSIG_SIGTERM] \
|
||||||
|
|| afSignal[INDEXSIG_SIGPIPE])
|
||||||
|
|
||||||
|
/* If we get a SIGINT in uucico, we continue the current communication
|
||||||
|
session but don't start any new ones. This macros checks for any
|
||||||
|
signal other than SIGINT, which means we should get out
|
||||||
|
immediately. */
|
||||||
|
#define FGOT_QUIT_SIGNAL() \
|
||||||
|
(afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGQUIT] \
|
||||||
|
|| afSignal[INDEXSIG_SIGTERM] || afSignal[INDEXSIG_SIGPIPE])
|
||||||
|
|
||||||
|
/* File being sent. */
|
||||||
|
extern openfile_t eSendfile;
|
||||||
|
|
||||||
|
/* File being received. */
|
||||||
|
extern openfile_t eRecfile;
|
||||||
|
|
||||||
|
/* Device name to log. This is set by fconn_open. It may be NULL. */
|
||||||
|
extern char *zLdevice;
|
||||||
|
|
||||||
|
/* If not NULL, ulog calls this function before outputting anything.
|
||||||
|
This is used to support cu. */
|
||||||
|
extern void (*pfLstart) P((void));
|
||||||
|
|
||||||
|
/* If not NULL, ulog calls this function after outputting everything.
|
||||||
|
This is used to support cu. */
|
||||||
|
extern void (*pfLend) P((void));
|
108
gnu/libexec/uucp/contrib/Dial.Hayes
Normal file
108
gnu/libexec/uucp/contrib/Dial.Hayes
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#!xchat
|
||||||
|
# @(#) dial.hayes V1.1 Tue Sep 1 13:59:58 1992 (Bob Denny)
|
||||||
|
#
|
||||||
|
# xchat script for dialing a vanilla Hayes modem
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# xchat dial.hayes telno
|
||||||
|
#
|
||||||
|
# where telno is the telephone number, subject to pause and wait
|
||||||
|
# character modification.
|
||||||
|
#
|
||||||
|
# Uncomment the first two lines after "start:" to get debugging
|
||||||
|
# in file "Dial.Log"
|
||||||
|
#
|
||||||
|
# Flush input, zero counter, set telephone number if supplied,
|
||||||
|
# else fail if no telephone number given.
|
||||||
|
#
|
||||||
|
start:
|
||||||
|
### dbgfile Dial.Log
|
||||||
|
### dbgset 15
|
||||||
|
zero
|
||||||
|
flush
|
||||||
|
ifnstr notelno 0
|
||||||
|
telno 0
|
||||||
|
goto initmodem
|
||||||
|
#
|
||||||
|
# Missing telephone number.
|
||||||
|
#
|
||||||
|
notelno:
|
||||||
|
logerr No telephone number given
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# Reset the modem to nonvolatile profile.
|
||||||
|
# Allow 3 sec. for response, as some modems are slow to reset.
|
||||||
|
#
|
||||||
|
initmodem:
|
||||||
|
count
|
||||||
|
ifgtr cantinit 4
|
||||||
|
send ATZ\r
|
||||||
|
timeout initmodem 3000
|
||||||
|
expect setupmodem OK
|
||||||
|
#
|
||||||
|
# No response from modem
|
||||||
|
#
|
||||||
|
cantinit:
|
||||||
|
logerr Can't wake modem
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# Send the stuff needed to initialize the modem to the modes
|
||||||
|
# needed for the particular modem flavor. The string below
|
||||||
|
# is provided as a vanilla example. Allow 2 sec. for the
|
||||||
|
# modem to respond to this command.
|
||||||
|
#
|
||||||
|
setupmodem:
|
||||||
|
sleep 1000
|
||||||
|
send ATM0S7=90S11=120\r
|
||||||
|
timeout setupfail 2000
|
||||||
|
expect setupfail ERROR
|
||||||
|
expect dialnumber OK
|
||||||
|
#
|
||||||
|
# Modem barfed or died on setup command.
|
||||||
|
#
|
||||||
|
setupfail:
|
||||||
|
logerr Error in modem setup string
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# Dial the supplied number. Handle the various errors that
|
||||||
|
# can come back from the modem by logging the error.
|
||||||
|
#
|
||||||
|
dialnumber:
|
||||||
|
sleep 1000
|
||||||
|
send ATDT
|
||||||
|
dial
|
||||||
|
send \r
|
||||||
|
flush
|
||||||
|
timeout timeout 90000
|
||||||
|
expect connected CONNECT
|
||||||
|
expect busy BUSY
|
||||||
|
expect nocarrier NO CARRIER
|
||||||
|
expect noanswer NO ANSWER
|
||||||
|
expect nodialtone NO DIALTONE
|
||||||
|
#
|
||||||
|
# Success!
|
||||||
|
#
|
||||||
|
connected:
|
||||||
|
success
|
||||||
|
#
|
||||||
|
# Handle modem dial failures
|
||||||
|
#
|
||||||
|
timeout:
|
||||||
|
logerr Modem or carrier timeout.
|
||||||
|
failed
|
||||||
|
busy:
|
||||||
|
logerr BUSY
|
||||||
|
failed
|
||||||
|
nocarrier:
|
||||||
|
logerr NO CARRIER
|
||||||
|
failed
|
||||||
|
noanswer:
|
||||||
|
logerr NO ANSWER
|
||||||
|
failed
|
||||||
|
nodialtone:
|
||||||
|
logerr NO DIALTONE
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
|
57
gnu/libexec/uucp/contrib/Hangup.Hayes
Normal file
57
gnu/libexec/uucp/contrib/Hangup.Hayes
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#!xchat
|
||||||
|
# @(#) Hangup.Hayes V1.1 Tue Sep 1 14:04:25 1992 (Bob Denny)
|
||||||
|
#
|
||||||
|
# xchat script for hanging up a Hayes-type modem. When used with Taylor
|
||||||
|
# UUCP, this script should be run as the dialer-complete and dialer-abort
|
||||||
|
# script with xchat.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# xchat Hangup.Hayes [ x ]
|
||||||
|
#
|
||||||
|
# where 'x' is any string. If it is present, this script will log the
|
||||||
|
# modem reset as an ABORT reset, otherwise it will not log anything.
|
||||||
|
#
|
||||||
|
# Uncomment the lines starting with '###' to get debugging log.
|
||||||
|
#
|
||||||
|
start:
|
||||||
|
### dbgfile Hangup.Log
|
||||||
|
### dbgset 15
|
||||||
|
zero
|
||||||
|
sleep 2000 # Wait for trailing garbage
|
||||||
|
flush # Toss it out
|
||||||
|
ifnstr wakemodem 0 # No abort indicator
|
||||||
|
log Hangup on abort
|
||||||
|
#
|
||||||
|
# Get modem's attention via Hayes 'escape' protocol.
|
||||||
|
#
|
||||||
|
wakemodem:
|
||||||
|
sleep 4000
|
||||||
|
send +++
|
||||||
|
sleep 4000
|
||||||
|
send \r
|
||||||
|
timeout reset 2000
|
||||||
|
expect reset OK
|
||||||
|
#
|
||||||
|
# We're (probably) in command mode. Use ATZ (reset) to hang up
|
||||||
|
# as some modems don't behave well with ATH0 command.
|
||||||
|
#
|
||||||
|
reset:
|
||||||
|
send ATZ\r
|
||||||
|
timeout silent 5000
|
||||||
|
expect done OK
|
||||||
|
#
|
||||||
|
# Finished, modem is back in initial state.
|
||||||
|
#
|
||||||
|
done:
|
||||||
|
success
|
||||||
|
#
|
||||||
|
# No response to escape protocol. Log the error and force DTR low
|
||||||
|
# in an attempt to get control of the modem. Then send ATZ just to
|
||||||
|
# make sure.
|
||||||
|
#
|
||||||
|
silent:
|
||||||
|
logerr Hangup: no response from modem
|
||||||
|
hangup # Force DTR low as last gasp
|
||||||
|
send ATZ\r
|
||||||
|
sleep 5000
|
||||||
|
failed
|
137
gnu/libexec/uucp/contrib/Login.LAT
Normal file
137
gnu/libexec/uucp/contrib/Login.LAT
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#!xchat
|
||||||
|
# @(#) login.LAT V1.2 Tue Sep 1 13:25:28 1992
|
||||||
|
#
|
||||||
|
# xchat script for logging into a VMS system through a LAT
|
||||||
|
# terminal server port. If no VMS password parameter supplied,
|
||||||
|
# skips password phase of VMS login. If LAT-password supplied,
|
||||||
|
# will log into LAT server using that password. NOTE: does not
|
||||||
|
# handle the situation where a LAT password is needed but no
|
||||||
|
# VMS password is needed.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# xchat login.LAT sysname username [ password [ LAT-password ] ]
|
||||||
|
#
|
||||||
|
# History:
|
||||||
|
# rbd Fri Aug 14 13:37:06 1992
|
||||||
|
# Changes for Lantronix ETS-16. It says "type help at the Local>
|
||||||
|
# prompt..." then it gives the prompt for real! Prompt may need
|
||||||
|
# to be something other than "Local>". We match the real Local>
|
||||||
|
# prompt by matching the leading newline!
|
||||||
|
#
|
||||||
|
# rbd Tue Sep 1 13:04:32 1992
|
||||||
|
# Remove absolute path name from log file. Now defaults per config.
|
||||||
|
#
|
||||||
|
start:
|
||||||
|
dbgfile Login.Log
|
||||||
|
dbgset 15
|
||||||
|
sleep 2000 # Wait 2 seconds
|
||||||
|
flush # Flush typeahead
|
||||||
|
ifnstr svrstart 3 # Skip server password if not given
|
||||||
|
#
|
||||||
|
# Starting point if server password supplied. Handle situation
|
||||||
|
# where the server line may have been left waiting for username
|
||||||
|
# or at local> prompt.
|
||||||
|
#
|
||||||
|
getsvrpwp:
|
||||||
|
zero
|
||||||
|
l0:
|
||||||
|
count # Get server's password prompt
|
||||||
|
ifgtr deadmux 5 # die if 5 cr's don't do it
|
||||||
|
send \r
|
||||||
|
timeout l0 1000 # Wait and try again
|
||||||
|
expect dosvrpw ssword>
|
||||||
|
expect svrlogin ername>
|
||||||
|
expect connect \nLocal>
|
||||||
|
#
|
||||||
|
# Send server's password. Fail if don't get Username
|
||||||
|
# or Local> prompt.
|
||||||
|
#
|
||||||
|
dosvrpw:
|
||||||
|
zero
|
||||||
|
l2:
|
||||||
|
sendstr 3
|
||||||
|
send \r
|
||||||
|
timeout badsvrpw 5000 # Die if invalid
|
||||||
|
expect svrlogin ername>
|
||||||
|
expect connect \nLocal>
|
||||||
|
#
|
||||||
|
# Starting point if NO server password supplied. Handle situation
|
||||||
|
# where the server line may have been left at local> prompt.
|
||||||
|
#
|
||||||
|
svrstart:
|
||||||
|
zero
|
||||||
|
l1:
|
||||||
|
count # Get username> or local> prompt
|
||||||
|
ifgtr deadmux 5 # Die if 5 cr's don't do it
|
||||||
|
send \r
|
||||||
|
timeout l1 1000 # Wait and try again
|
||||||
|
expect svrlogin ername>
|
||||||
|
expect connect \nLocal>
|
||||||
|
#
|
||||||
|
# Server asked for a username. Just give 'uucp'.
|
||||||
|
#
|
||||||
|
svrlogin:
|
||||||
|
send uucp\r
|
||||||
|
timeout deadmux 2000
|
||||||
|
expect connect \nLocal>
|
||||||
|
#
|
||||||
|
# At this point, we have the Local> prompt. Send the connect
|
||||||
|
# command for the specified LAT host service name, and wait for
|
||||||
|
# VMS "Username:" prompt. Die after 10 seconds.
|
||||||
|
#
|
||||||
|
connect:
|
||||||
|
send c\s
|
||||||
|
sendstr 0
|
||||||
|
send \r
|
||||||
|
timeout nologin 10000
|
||||||
|
expect gotlogin ername:
|
||||||
|
#
|
||||||
|
# Got VMS "Username:" prompt. Send the username. If a password
|
||||||
|
# was given, wait for the "Password:" prompt. Die after 10 seconds.
|
||||||
|
# if no password was given, we're done!
|
||||||
|
#
|
||||||
|
gotlogin:
|
||||||
|
sendstr 1
|
||||||
|
send \r
|
||||||
|
ifnstr done 2
|
||||||
|
timeout nopasswd 10000
|
||||||
|
expect gotpasswd ssword:
|
||||||
|
#
|
||||||
|
# Got VMS "Password:" prompt. Send the password and we're done!
|
||||||
|
#
|
||||||
|
gotpasswd:
|
||||||
|
sendstr 2
|
||||||
|
send \r
|
||||||
|
#
|
||||||
|
# Success!
|
||||||
|
#
|
||||||
|
done:
|
||||||
|
success
|
||||||
|
#
|
||||||
|
# ERROR HANDLERS
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# LAT server appears dead. Fail.
|
||||||
|
#
|
||||||
|
deadmux:
|
||||||
|
logerr No response from LAT server
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# The server password was bad. Fail.
|
||||||
|
#
|
||||||
|
badsvrpw:
|
||||||
|
logerr Invalid LAT server password
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# VMS system appears to be dead. Fail.
|
||||||
|
#
|
||||||
|
nologin:
|
||||||
|
logerr No VMS Username: prompt
|
||||||
|
failed
|
||||||
|
#
|
||||||
|
# Failed to get "Password:" prompt. Fail.
|
||||||
|
#
|
||||||
|
nopasswd:
|
||||||
|
logerr No VMS Password: prompt. Invalid password?
|
||||||
|
failed
|
||||||
|
|
133
gnu/libexec/uucp/contrib/Login.PortSel
Normal file
133
gnu/libexec/uucp/contrib/Login.PortSel
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#!xchat
|
||||||
|
# @(#) Login.PortSelUnix V1.0 Tue Sep 1 14:57:05 1992 (Bob Denny)
|
||||||
|
#
|
||||||
|
# NOTE: Untested with xchat V1.1. Taken from DECUS UUCP.
|
||||||
|
#
|
||||||
|
# From: "Kent C. Brodie" <moocow!brodie@CSD4.MILW.WISC.EDU>
|
||||||
|
# uucp: {uunet!marque,csd4.milw.wisc.edu}!moocow!brodie
|
||||||
|
# special script for "uwmcsd4", have to go through a port selector (and then
|
||||||
|
# log in via standard Unix procedures).
|
||||||
|
#
|
||||||
|
# Also included is the ability to wait in the port selector queue.
|
||||||
|
# Be forwarned that the debug log can get pretty big depending on
|
||||||
|
# how many times you "wait" in the queue.
|
||||||
|
# (C) 1989 Kent C. Brodie - Medical College of Wisconsin
|
||||||
|
|
||||||
|
# P0 is systemname , P1 is username, P2 is password.
|
||||||
|
|
||||||
|
zero
|
||||||
|
|
||||||
|
# send a CR to get the selector's attention. Sleep a little bit
|
||||||
|
# due to large login text of selector. It sends "Which System?"
|
||||||
|
# when it's ready.
|
||||||
|
|
||||||
|
getprtslct:
|
||||||
|
count
|
||||||
|
ifgtr noprtslct 6
|
||||||
|
break
|
||||||
|
send \r
|
||||||
|
sleep 2000
|
||||||
|
flush
|
||||||
|
expect prtslctok ystem?
|
||||||
|
timeout getprtslct 15000
|
||||||
|
|
||||||
|
noprtslct:
|
||||||
|
logerr Sent cr, no "Which System?" from port selector
|
||||||
|
failed
|
||||||
|
|
||||||
|
# Send the system name. We either get "OK" (connected), or we
|
||||||
|
# get "No ports available, would you like to wait?" (wait in queue)
|
||||||
|
|
||||||
|
prtslctok:
|
||||||
|
zero
|
||||||
|
sendstr 0
|
||||||
|
send \r
|
||||||
|
expect connected OK
|
||||||
|
expect prtslctwait wait?
|
||||||
|
timeout noconnect 10000
|
||||||
|
|
||||||
|
# Usually we get "nn Your place in queue" messages. JUST in case we
|
||||||
|
# get a free port right away, check for 'Are you ready?' as well.
|
||||||
|
|
||||||
|
prtslctwait:
|
||||||
|
zero
|
||||||
|
send Y\r
|
||||||
|
expect prtslctque queue
|
||||||
|
expect prtslctrdy ready?
|
||||||
|
timeout prtwaitbad 70000
|
||||||
|
|
||||||
|
prtwaitbad:
|
||||||
|
logerr Sent "Y" to wait in queue, did not get valid response.
|
||||||
|
failed
|
||||||
|
|
||||||
|
# Here's where we wait in the queue. The port selector sends us a status
|
||||||
|
# message about once a minute. We either get "nn Your place in queue"
|
||||||
|
# or we get "System Available. Are you Ready?".
|
||||||
|
# If something goes wrong, we time out waiting for either response.
|
||||||
|
# The reason we don't sleep for 40-50 seconds is because as SOON as the
|
||||||
|
# port is ready, it informs us. If we wait too long, it drops us.
|
||||||
|
# This setup is laid out for a maximum of 20 "tries" which is ABOUT
|
||||||
|
# 20 minutes. Note: This constant retrying can make log files
|
||||||
|
# kind of big....
|
||||||
|
|
||||||
|
prtslctque:
|
||||||
|
count
|
||||||
|
ifgtr prtslcttry 20
|
||||||
|
expect prtslctque queue
|
||||||
|
expect prtslctrdy ready?
|
||||||
|
timeout noportwait 70000
|
||||||
|
|
||||||
|
prtslcttry:
|
||||||
|
logerr Too many (20) wait/retries -- queue too busy.
|
||||||
|
failed
|
||||||
|
|
||||||
|
prtslctrdy:
|
||||||
|
send Y\r
|
||||||
|
expect connected OK
|
||||||
|
timeout noconnect 20000
|
||||||
|
|
||||||
|
|
||||||
|
noportwait:
|
||||||
|
logerr Timed out awaiting place in port queue
|
||||||
|
failed
|
||||||
|
|
||||||
|
noconnect:
|
||||||
|
logerr Sent system name, no "OK" from selector
|
||||||
|
failed
|
||||||
|
|
||||||
|
# standard Unix login stuff. Send cr, expect "ogin:", if no, send a break
|
||||||
|
# (which tells Unix to try the next bit rate) and try again.
|
||||||
|
|
||||||
|
connected:
|
||||||
|
send \r
|
||||||
|
zero
|
||||||
|
goto waitlogin
|
||||||
|
|
||||||
|
sendbreak:
|
||||||
|
count
|
||||||
|
ifgtr nolgi 6
|
||||||
|
flush
|
||||||
|
break
|
||||||
|
|
||||||
|
waitlogin:
|
||||||
|
expect gotlogin ogin:
|
||||||
|
timeout sendbreak 5000
|
||||||
|
|
||||||
|
nolgi:
|
||||||
|
logerr No login: prompt
|
||||||
|
failed
|
||||||
|
|
||||||
|
gotlogin:
|
||||||
|
sendstr 1
|
||||||
|
send \r
|
||||||
|
expect gotword word:
|
||||||
|
timeout nopwd 10000
|
||||||
|
|
||||||
|
nopwd:
|
||||||
|
logerr No password: prompt
|
||||||
|
failed
|
||||||
|
|
||||||
|
gotword:
|
||||||
|
sendstr 2
|
||||||
|
send \r
|
||||||
|
success
|
96
gnu/libexec/uucp/contrib/Login.VMS
Normal file
96
gnu/libexec/uucp/contrib/Login.VMS
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#!xchat
|
||||||
|
# @(#) Login.VMS V1.1 Tue Sep 1 13:24:54 1992 (Bob Denny)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# xchat script for logging into a VMS system. If no VMS password
|
||||||
|
# parameter supplied, skips password phase of VMS login. If syspass
|
||||||
|
# parameter given, will go through steps needed to log into a VMS
|
||||||
|
# system where a "system password" was set on the port.
|
||||||
|
#
|
||||||
|
# Cannot handle situation where system password is required but
|
||||||
|
# no password needed.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# xchat Login.VMS username [ password [ syspass ] ]
|
||||||
|
#
|
||||||
|
# Uncomment the lines starting with "###" to get debug logging.
|
||||||
|
#
|
||||||
|
start:
|
||||||
|
### dbgfile Login.Log
|
||||||
|
### dbgset 15
|
||||||
|
sleep 2000 # Wait 2 seconds
|
||||||
|
zero
|
||||||
|
flush # Flush typeahead
|
||||||
|
ifnstr login 2 # Skip sys passwd if not given
|
||||||
|
#
|
||||||
|
# Need system password. Send <CR> to get bell.
|
||||||
|
# Try 5 times at 2 sec. intervals. Skip to do
|
||||||
|
# username if we see "Username:".
|
||||||
|
#
|
||||||
|
syspass:
|
||||||
|
count
|
||||||
|
ifgtr nobell 5 # Fail after 5 tries
|
||||||
|
send \r
|
||||||
|
timeout syspass 2000 # Wait 2 sec. and try again
|
||||||
|
expect gotbell \007
|
||||||
|
expect gotlogin Username:
|
||||||
|
#
|
||||||
|
# Got the bell. Send the system password. Repeat 5 times
|
||||||
|
# at 2 sec. intervals. Fail if we don't get Username:
|
||||||
|
#
|
||||||
|
gotbell:
|
||||||
|
zero
|
||||||
|
sleep 2000
|
||||||
|
l1:
|
||||||
|
count
|
||||||
|
ifgtr nologin 5 # Fail after 5 tries
|
||||||
|
sendstr 2
|
||||||
|
send \r
|
||||||
|
timeout l1 2000 # Wait 2 sec. and try again
|
||||||
|
expect gotlogin Username:
|
||||||
|
#
|
||||||
|
# Start here if no system password supplied.
|
||||||
|
# Send <CR> until we get Username: Try 5 times at 2 sec. intervals.
|
||||||
|
#
|
||||||
|
login:
|
||||||
|
count
|
||||||
|
ifgtr nologin 5 # Fail after 5 tries
|
||||||
|
send \r
|
||||||
|
timeout login 2000 # Wait 2 sec. and try again
|
||||||
|
expect gotlogin Username:
|
||||||
|
#
|
||||||
|
# Got VMS "Username:" prompt. Send the username. If a password
|
||||||
|
# was given, wait for the "Password:" prompt. Die after 10 seconds.
|
||||||
|
# if no password was given, we're done!
|
||||||
|
#
|
||||||
|
gotlogin:
|
||||||
|
sendstr 0
|
||||||
|
send \r
|
||||||
|
ifnstr done 1
|
||||||
|
timeout nopasswd 10000
|
||||||
|
expect gotpasswd Password:
|
||||||
|
#
|
||||||
|
# Got VMS "Password:" prompt. Send the password and we're done!
|
||||||
|
#
|
||||||
|
gotpasswd:
|
||||||
|
sendstr 1
|
||||||
|
send \r
|
||||||
|
#
|
||||||
|
# Success!
|
||||||
|
#
|
||||||
|
done:
|
||||||
|
success
|
||||||
|
#
|
||||||
|
# ERROR HANDLERS
|
||||||
|
#
|
||||||
|
nobell:
|
||||||
|
logerr No VMS system password prompt (bell)
|
||||||
|
failed
|
||||||
|
nologin:
|
||||||
|
logerr No VMS Username: prompt
|
||||||
|
failed
|
||||||
|
nopasswd:
|
||||||
|
logerr No VMS Password: prompt.
|
||||||
|
failed
|
||||||
|
|
30
gnu/libexec/uucp/contrib/Makefile.uurt
Normal file
30
gnu/libexec/uucp/contrib/Makefile.uurt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#
|
||||||
|
# Makefile for uurate 1.0
|
||||||
|
#
|
||||||
|
|
||||||
|
# Where uurate is installed
|
||||||
|
BIN=/usr/local/bin
|
||||||
|
|
||||||
|
# Flags to use when compiling uurate
|
||||||
|
CFLAGS=-I..
|
||||||
|
|
||||||
|
CC=cc
|
||||||
|
SHELL=/bin/sh
|
||||||
|
PROGS=uurate
|
||||||
|
|
||||||
|
#-----------
|
||||||
|
|
||||||
|
all: $(PROGS)
|
||||||
|
|
||||||
|
install: $(PROGS)
|
||||||
|
@for i in $(PROGS) ; do \
|
||||||
|
echo "Install $$i into $(BIN)..." ; \
|
||||||
|
cp $$i $(BIN) ; \
|
||||||
|
echo "Set ownership and protection..." ; \
|
||||||
|
/bin/chmod 0555 $(BIN)/$$i ; \
|
||||||
|
/bin/chown bin $(BIN)/$$i ; \
|
||||||
|
/bin/chgrp bin $(BIN)/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGS) core
|
31
gnu/libexec/uucp/contrib/Makefile.xchat
Normal file
31
gnu/libexec/uucp/contrib/Makefile.xchat
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Makefile for xchat 1.1
|
||||||
|
#
|
||||||
|
# Bob Denny - Tue Sep 1 15:58:22 1992
|
||||||
|
#
|
||||||
|
CC=cc
|
||||||
|
SHELL=/bin/sh
|
||||||
|
BIN=/usr/local/lib/uucp
|
||||||
|
PROGS=xchat
|
||||||
|
|
||||||
|
#-----------
|
||||||
|
|
||||||
|
all: $(PROGS)
|
||||||
|
|
||||||
|
install: $(PROGS)
|
||||||
|
@for i in $(PROGS) ; do \
|
||||||
|
echo "Install $$i into $(BIN)..." ; \
|
||||||
|
cp $$i $(BIN) ; \
|
||||||
|
echo "Set ownership and protection..." ; \
|
||||||
|
/bin/chmod 0555 $(BIN)/$$i ; \
|
||||||
|
/bin/chown bin $(BIN)/$$i ; \
|
||||||
|
/bin/chgrp bin $(BIN)/$$i ; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(PROGS) core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
46
gnu/libexec/uucp/contrib/README
Normal file
46
gnu/libexec/uucp/contrib/README
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
This is the README file for the Taylor UUCP contrib directory.
|
||||||
|
|
||||||
|
This directory contains contributed shell scripts and programs that
|
||||||
|
you may find useful.
|
||||||
|
|
||||||
|
xchat.c, xchat.man, README-XCHAT, xc-conf.h-dist, Makefile.xchat:
|
||||||
|
A program by Bob Denny that may be invoked by the ``chat-program''
|
||||||
|
command for any of the various types of chat scripts. It is
|
||||||
|
driven by scripts which are written in its own little language.
|
||||||
|
It is a powerful program that can add a lot of flexibility to your
|
||||||
|
chat scripts.
|
||||||
|
|
||||||
|
Dial.Hayes, Hangup.Hayes, Login.LAT, Login.PortSel, Login.VMS:
|
||||||
|
Sample scripts for xchat.
|
||||||
|
|
||||||
|
uurate.c, uurate.man, README-UURATE, Makefile.uurt:
|
||||||
|
A nifty little program by Bob Denny which analyzes the Log and
|
||||||
|
Stats file and prints various sorts of reports.
|
||||||
|
|
||||||
|
uutraf:
|
||||||
|
Another program to produce neat reports from your log files, this
|
||||||
|
one a perl script by Johan Vromans.
|
||||||
|
|
||||||
|
savelog.sh, savelog.man:
|
||||||
|
A handy shell script to rename a log file and cycle old versions
|
||||||
|
through a set of names, throwing away the oldest one. It will
|
||||||
|
also optionally compress the old log files. I believe that this
|
||||||
|
is originally from smail. It was written by Ronald S. Karr and
|
||||||
|
Landon Curt Noll, and was given to me by Bob Denny.
|
||||||
|
|
||||||
|
uureroute:
|
||||||
|
A perl script reroute all mail queued up for one host to another.
|
||||||
|
Written by Bill Campbell and contributed by Francois Pinard.
|
||||||
|
|
||||||
|
stats.sh:
|
||||||
|
A gawk script by Zacharias Beckman which reads the Stats file and
|
||||||
|
prints the last 80 lines as a nicely formatted table.
|
||||||
|
|
||||||
|
uuq.sh:
|
||||||
|
A uuq workalike shell script by Zacharias Beckman.
|
||||||
|
|
||||||
|
tstout.c:
|
||||||
|
A program to remove a user from utmp and wtmp, essentially logging
|
||||||
|
them out. I put this together from BSD code. I need it to use
|
||||||
|
tstuu with the system UUCP on Ultrix 4.0, for reasons that escape
|
||||||
|
me. Most people will have little use for this.
|
20
gnu/libexec/uucp/contrib/README-UURATE
Normal file
20
gnu/libexec/uucp/contrib/README-UURATE
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
uurate V1.2 - Gather and display Taylor UUCP traffic statistics
|
||||||
|
|
||||||
|
Bob Denny (denny@alisa.com) - Thu Sep 3 19:47:41 1992
|
||||||
|
|
||||||
|
See the man page for documentation.
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
------------
|
||||||
|
|
||||||
|
(1) Copy Makefile.uurt to Makefile.
|
||||||
|
|
||||||
|
(2) Edit Makefile: set BIN where you want uurate to be installed, and
|
||||||
|
set CFLAGS to point to the directory containing the UUCP sources
|
||||||
|
(this is .. by default).
|
||||||
|
|
||||||
|
(3) Type ``make'' to compile the program.
|
||||||
|
|
||||||
|
(4) Type ``make install'' to install the program.
|
||||||
|
|
||||||
|
(5) Install the man page if you want. I didn't put that into the Makefile.
|
42
gnu/libexec/uucp/contrib/README-XCHAT
Normal file
42
gnu/libexec/uucp/contrib/README-XCHAT
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
This is xchat V1.1 (Tue Sep 1 15:50:56 1992)
|
||||||
|
|
||||||
|
Introduction:
|
||||||
|
------------
|
||||||
|
|
||||||
|
Xchat is a general-purpose dialing and login program designed for use
|
||||||
|
with Taylor UUCP as a "chat-program", taking the place (or augmenting)
|
||||||
|
the built-in chat scripting facility. It provides the ability to
|
||||||
|
closely control timeouts, multiple simultaneous expect strings with
|
||||||
|
separate actions, extended terminal control, modem command character
|
||||||
|
pacing, and more.
|
||||||
|
|
||||||
|
When used in conjunction with Taylor UUCP's configuration features,
|
||||||
|
xchat can provide you the ability to manage the most intricate login,
|
||||||
|
dial and hangup needs. The scripts are written in a shell-like (well,
|
||||||
|
sort-of) style with labels, commands, and parameters, easing the task
|
||||||
|
of writing procedures for complex terminal communications situations.
|
||||||
|
|
||||||
|
Installation:
|
||||||
|
------------
|
||||||
|
|
||||||
|
(1) Copy xc-conf.h-dist to xc-conf.h, then edit xc-conf.h to reflect
|
||||||
|
your condifuration. A description of the settings is in that file.
|
||||||
|
|
||||||
|
(2) Copy Makefile.xchat to Makefile and edit it to set BIN to where
|
||||||
|
you want xchat installed.
|
||||||
|
|
||||||
|
(2) Do a 'make' to build xchat.
|
||||||
|
|
||||||
|
(3) Do a 'make install' to install it.
|
||||||
|
|
||||||
|
(4) Format and print xchat.8, and install it if you want.
|
||||||
|
|
||||||
|
(5) Print out copies of the scripts in the ./scripts subdirectory.
|
||||||
|
|
||||||
|
(6) Read xchat.8 and the scripts together.
|
||||||
|
|
||||||
|
|
||||||
|
Author:
|
||||||
|
------
|
||||||
|
|
||||||
|
Robert B. Denny (denny@alisa.com)
|
130
gnu/libexec/uucp/contrib/savelog.man
Normal file
130
gnu/libexec/uucp/contrib/savelog.man
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
.\" @(#)man/man8/savelog.an 1.2 24 Oct 1990 05:18:46
|
||||||
|
.de pP
|
||||||
|
.if n .sp 1
|
||||||
|
.if t .sp .4
|
||||||
|
..
|
||||||
|
.de tP
|
||||||
|
.pP
|
||||||
|
.ta \\n(pDu
|
||||||
|
.ti -\\n(pDu
|
||||||
|
..
|
||||||
|
.TH SAVELOG X_MAN8_EXT_X "31 January 1988" "Local"
|
||||||
|
.SH NAME
|
||||||
|
savelog \- cycle and truncate log files
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.na
|
||||||
|
.B X_UTIL_BIN_DIR_X/savelog
|
||||||
|
[
|
||||||
|
.B \-m
|
||||||
|
.I mode
|
||||||
|
] [
|
||||||
|
.B \-u
|
||||||
|
.I user
|
||||||
|
] [
|
||||||
|
.B \-g
|
||||||
|
.I group
|
||||||
|
] [
|
||||||
|
.B \-c
|
||||||
|
.I cycle
|
||||||
|
] [
|
||||||
|
.B \-t
|
||||||
|
] [
|
||||||
|
.B \-l
|
||||||
|
]
|
||||||
|
.I logfile
|
||||||
|
.br
|
||||||
|
.ad
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.I savelog
|
||||||
|
command renames and optionally compresses a log file and cycles it
|
||||||
|
through a set of names based on the original log file, removing the
|
||||||
|
last name in the cycle.
|
||||||
|
.SH OPTIONS
|
||||||
|
The
|
||||||
|
.I savelog
|
||||||
|
command accepts the following options:
|
||||||
|
.TP
|
||||||
|
\fB\-m\fP \fImode\fP
|
||||||
|
Change the permissions mode for renamed log files to
|
||||||
|
.IR mode .
|
||||||
|
By default the mode is unchanged.
|
||||||
|
.TP
|
||||||
|
\fB\-u\fP \fIuser\fP
|
||||||
|
Change the owner for renamed log files to
|
||||||
|
.IR user .
|
||||||
|
By default the owner is unchanged.
|
||||||
|
.TP
|
||||||
|
\fB\-g\fP \fIgroup\fP
|
||||||
|
Change the group for renamed log files to
|
||||||
|
.IR group .
|
||||||
|
By default the group is unchanged.
|
||||||
|
.TP
|
||||||
|
\fB\-c\fP \fIcycle\fP
|
||||||
|
Save
|
||||||
|
.I cycle
|
||||||
|
versions of the logfile, where
|
||||||
|
.I cycle
|
||||||
|
is a decimal number. The default value is 7.
|
||||||
|
.TP
|
||||||
|
.B \-l
|
||||||
|
Do not compress log files. By default, a compression program is used,
|
||||||
|
if one is available.
|
||||||
|
.TP
|
||||||
|
.B \-t
|
||||||
|
Ensure that a new logfile exists when the savelog operation is
|
||||||
|
complete. Use of
|
||||||
|
.BR \-m ,
|
||||||
|
.BR \-u
|
||||||
|
or
|
||||||
|
.BR \-g
|
||||||
|
imply this, ensuring that the logfile will have the designated mode.
|
||||||
|
.SH "OPERATION"
|
||||||
|
The given logfile is cycled through files named:
|
||||||
|
.RS
|
||||||
|
|
||||||
|
OLD/\fIfile\fP.\fInumber\fP
|
||||||
|
|
||||||
|
.RE
|
||||||
|
where
|
||||||
|
.I file
|
||||||
|
is the basename for the logfile and where
|
||||||
|
.I number
|
||||||
|
ranges from 0 to one less then the
|
||||||
|
.I cycle
|
||||||
|
count specified for the command.
|
||||||
|
The
|
||||||
|
.I OLD
|
||||||
|
dirctory is created, as necessary, and is under the same directory as
|
||||||
|
the logfile itself.
|
||||||
|
.PP
|
||||||
|
This cycle operation is accomplished by renaming the file numbered
|
||||||
|
.IR cycle -2
|
||||||
|
to a file numbered
|
||||||
|
.IR cycle -1
|
||||||
|
and so on until the file numbered 0 is renamed to the file numbered 1.
|
||||||
|
If compression is being used, the first cycle file is compressed after
|
||||||
|
being renamed to cycle 1. After the cycle files are moved through the
|
||||||
|
various names, the filefile itself is moved to the cycle 0 file.
|
||||||
|
This cycle normally occurs once every time
|
||||||
|
.I savelog
|
||||||
|
is executed.
|
||||||
|
If the log file does not exist, savelog ignores it and does
|
||||||
|
not cycle the OLD files.
|
||||||
|
.PP
|
||||||
|
If compression is being used, then compressed log files will have an
|
||||||
|
additional suffix appropriate for the compression program that is
|
||||||
|
used.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.IR smail (X_MAN5_EXT_X)
|
||||||
|
and
|
||||||
|
.IR smail (X_MAN8_EXT_X).
|
||||||
|
.SH COPYRIGHT
|
||||||
|
Copyright(C)1987, 1988 Ronald S. Karr and Landon Curt Noll
|
||||||
|
.br
|
||||||
|
See a file COPYING,
|
||||||
|
distributed with the source code,
|
||||||
|
or type
|
||||||
|
.I "smail \-bc"
|
||||||
|
for distribution rights and restrictions
|
||||||
|
associated with this software.
|
247
gnu/libexec/uucp/contrib/savelog.sh
Executable file
247
gnu/libexec/uucp/contrib/savelog.sh
Executable file
@ -0,0 +1,247 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# @(#)util/savelog.sh 1.4 26 Oct 1991 22:49:39
|
||||||
|
#
|
||||||
|
# savelog - save a log file
|
||||||
|
#
|
||||||
|
# Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll
|
||||||
|
#
|
||||||
|
# See the file COPYING, distributed with smail, for restriction
|
||||||
|
# and warranty information.
|
||||||
|
#
|
||||||
|
# usage: savelog [-m mode] [-u user] [-g group] [-t] [-c cycle] [-l] file...
|
||||||
|
#
|
||||||
|
# -m mode - chmod log files to mode
|
||||||
|
# -u user - chown log files to user
|
||||||
|
# -g group - chgrp log files to group
|
||||||
|
# -c cycle - save cycle versions of the logfile (default: 7)
|
||||||
|
# -t - touch file
|
||||||
|
# -l - don't compress any log files (default: compress)
|
||||||
|
# file - log file names
|
||||||
|
#
|
||||||
|
# The savelog command saves and optionally compresses old copies of files
|
||||||
|
# into an 'dir'/OLD sub-directory. The 'dir' directory is determined from
|
||||||
|
# the directory of each 'file'.
|
||||||
|
#
|
||||||
|
# Older version of 'file' are named:
|
||||||
|
#
|
||||||
|
# OLD/'file'.<number><compress_suffix>
|
||||||
|
#
|
||||||
|
# where <number> is the version number, 0 being the newest. By default,
|
||||||
|
# version numbers > 0 are compressed (unless -l prevents it). The
|
||||||
|
# version number 0 is never compressed on the off chance that a process
|
||||||
|
# still has 'file' opened for I/O.
|
||||||
|
#
|
||||||
|
# If the 'file' does not exist or if it is zero length, no further processing
|
||||||
|
# is performed. However if -t was also given, it will be created.
|
||||||
|
#
|
||||||
|
# For files that do exist and have lengths greater than zero, the following
|
||||||
|
# actions are performed.
|
||||||
|
#
|
||||||
|
# 1) Version numered files are cycled. That is version 6 is moved to
|
||||||
|
# version 7, version is moved to becomes version 6, ... and finally
|
||||||
|
# version 0 is moved to version 1. Both compressed names and
|
||||||
|
# uncompressed names are cycled, regardless of -t. Missing version
|
||||||
|
# files are ignored.
|
||||||
|
#
|
||||||
|
# 2) The new OLD/file.1 is compressed and is changed subject to
|
||||||
|
# the -m, -u and -g flags. This step is skipped if the -t flag
|
||||||
|
# was given.
|
||||||
|
#
|
||||||
|
# 3) The main file is moved to OLD/file.0.
|
||||||
|
#
|
||||||
|
# 4) If the -m, -u, -g or -t flags are given, then file is created
|
||||||
|
# (as an empty file) subject to the given flags.
|
||||||
|
#
|
||||||
|
# 5) The new OLD/file.0 is chanegd subject to the -m, -u and -g flags.
|
||||||
|
#
|
||||||
|
# Note: If the OLD sub-directory does not exist, it will be created
|
||||||
|
# with mode 0755.
|
||||||
|
#
|
||||||
|
# Note: If no -m, -u or -g flag is given, then the primary log file is
|
||||||
|
# not created.
|
||||||
|
#
|
||||||
|
# Note: Since the version numbers start with 0, version number <cycle>
|
||||||
|
# is never formed. The <cycle> count must be at least 2.
|
||||||
|
#
|
||||||
|
# Bugs: If a process is still writing to the file.0 and savelog
|
||||||
|
# moved it to file.1 and compresses it, data could be lost.
|
||||||
|
# Smail does not have this problem in general because it
|
||||||
|
# restats files often.
|
||||||
|
|
||||||
|
# common location
|
||||||
|
PATH="X_UTIL_PATH_X:X_SECURE_PATH_X"; export PATH
|
||||||
|
COMPRESS="X_COMPRESS_X"
|
||||||
|
COMP_FLAG="X_COMP_FLAG_X"
|
||||||
|
DOT_Z="X_DOT_Z_X"
|
||||||
|
CHOWN="X_CHOWN_X"
|
||||||
|
GETOPT="X_UTIL_BIN_DIR_X/getopt"
|
||||||
|
|
||||||
|
# parse args
|
||||||
|
exitcode=0 # no problems to far
|
||||||
|
prog=$0
|
||||||
|
mode=
|
||||||
|
user=
|
||||||
|
group=
|
||||||
|
touch=
|
||||||
|
count=7
|
||||||
|
set -- `$GETOPT m:u:g:c:lt $*`
|
||||||
|
if [ $# -eq 0 -o $? -ne 0 ]; then
|
||||||
|
echo "usage: $prog [-m mode][-u user][-g group][-t][-c cycle][-l] file ..." 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
for i in $*; do
|
||||||
|
case $i in
|
||||||
|
-m) mode=$2; shift 2;;
|
||||||
|
-u) user=$2; shift 2;;
|
||||||
|
-g) group=$2; shift 2;;
|
||||||
|
-c) count=$2; shift 2;;
|
||||||
|
-t) touch=1; shift;;
|
||||||
|
-l) COMPRESS=""; shift;;
|
||||||
|
--) shift; break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if [ "$count" -lt 2 ]; then
|
||||||
|
echo "$prog: count must be at least 2" 1>&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# cycle thru filenames
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
|
||||||
|
# get the filename
|
||||||
|
filename=$1
|
||||||
|
shift
|
||||||
|
|
||||||
|
# catch bogus files
|
||||||
|
if [ -b "$filename" -o -c "$filename" -o -d "$filename" ]; then
|
||||||
|
echo "$prog: $filename is not a regular file" 1>&2
|
||||||
|
exitcode=3
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if not a file or empty, do nothing major
|
||||||
|
if [ ! -s $filename ]; then
|
||||||
|
# if -t was given and it does not exist, create it
|
||||||
|
if [ ! -z "$touch" -a ! -f $filename ]; then
|
||||||
|
touch $filename
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo "$prog: could not touch $filename" 1>&2
|
||||||
|
exitcode=4
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ ! -z "$user" ]; then
|
||||||
|
$CHOWN $user $filename
|
||||||
|
fi
|
||||||
|
if [ ! -z "$group" ]; then
|
||||||
|
chgrp $group $filename
|
||||||
|
fi
|
||||||
|
if [ ! -z "$mode" ]; then
|
||||||
|
chmod $mode $filename
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# be sure that the savedir exists and is writable
|
||||||
|
savedir=`expr "$filename" : '\(.*\)/'`
|
||||||
|
if [ -z "$savedir" ]; then
|
||||||
|
savedir=./OLD
|
||||||
|
else
|
||||||
|
savedir=$savedir/OLD
|
||||||
|
fi
|
||||||
|
if [ ! -s $savedir ]; then
|
||||||
|
mkdir $savedir
|
||||||
|
if [ "$?" -ne 0 ]; then
|
||||||
|
echo "$prog: could not mkdir $savedir" 1>&2
|
||||||
|
exitcode=5
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
chmod 0755 $savedir
|
||||||
|
fi
|
||||||
|
if [ ! -d $savedir ]; then
|
||||||
|
echo "$prog: $savedir is not a directory" 1>&2
|
||||||
|
exitcode=6
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if [ ! -w $savedir ]; then
|
||||||
|
echo "$prog: directory $savedir is not writable" 1>&2
|
||||||
|
exitcode=7
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# deterine our uncompressed file names
|
||||||
|
newname=`expr "$filename" : '.*/\(.*\)'`
|
||||||
|
if [ -z "$newname" ]; then
|
||||||
|
newname=$savedir/$filename
|
||||||
|
else
|
||||||
|
newname=$savedir/$newname
|
||||||
|
fi
|
||||||
|
|
||||||
|
# cycle the old compressed log files
|
||||||
|
cycle=`expr $count - 1`
|
||||||
|
rm -f $newname.$cycle $newname.$cycle$DOT_Z
|
||||||
|
while [ "$cycle" -gt 1 ]; do
|
||||||
|
# --cycle
|
||||||
|
oldcycle=$cycle
|
||||||
|
cycle=`expr $cycle - 1`
|
||||||
|
# cycle log
|
||||||
|
if [ -f $newname.$cycle$DOT_Z ]; then
|
||||||
|
mv -f $newname.$cycle$DOT_Z $newname.$oldcycle$DOT_Z
|
||||||
|
fi
|
||||||
|
if [ -f $newname.$cycle ]; then
|
||||||
|
# file was not compressed for some reason move it anyway
|
||||||
|
mv -f $newname.$cycle $newname.$oldcycle
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# compress the old uncompressed log if needed
|
||||||
|
if [ -f $newname.0 ]; then
|
||||||
|
if [ -z "$COMPRESS" ]; then
|
||||||
|
newfile=$newname.1
|
||||||
|
mv $newname.0 $newfile
|
||||||
|
else
|
||||||
|
newfile=$newname.1$DOT_Z
|
||||||
|
$COMPRESS $COMP_FLAG < $newname.0 > $newfile
|
||||||
|
rm -f $newname.0
|
||||||
|
fi
|
||||||
|
if [ ! -z "$user" ]; then
|
||||||
|
$CHOWN $user $newfile
|
||||||
|
fi
|
||||||
|
if [ ! -z "$group" ]; then
|
||||||
|
chgrp $group $newfile
|
||||||
|
fi
|
||||||
|
if [ ! -z "$mode" ]; then
|
||||||
|
chmod $mode $newfile
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# move the file into the file.0 holding place
|
||||||
|
mv -f $filename $newname.0
|
||||||
|
|
||||||
|
# replace file if needed
|
||||||
|
if [ ! -z "$touch" -o ! -z "$user" -o \
|
||||||
|
! -z "$group" -o ! -z "$mode" ]; then
|
||||||
|
touch $filename
|
||||||
|
fi
|
||||||
|
if [ ! -z "$user" ]; then
|
||||||
|
$CHOWN $user $filename
|
||||||
|
fi
|
||||||
|
if [ ! -z "$group" ]; then
|
||||||
|
chgrp $group $filename
|
||||||
|
fi
|
||||||
|
if [ ! -z "$mode" ]; then
|
||||||
|
chmod $mode $filename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# fix the permissions on the holding place file.0 file
|
||||||
|
if [ ! -z "$user" ]; then
|
||||||
|
$CHOWN $user $newname.0
|
||||||
|
fi
|
||||||
|
if [ ! -z "$group" ]; then
|
||||||
|
chgrp $group $newname.0
|
||||||
|
fi
|
||||||
|
if [ ! -z "$mode" ]; then
|
||||||
|
chmod $mode $newname.0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit $exitcode
|
27
gnu/libexec/uucp/contrib/stats.sh
Executable file
27
gnu/libexec/uucp/contrib/stats.sh
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# uuspeed - a script to parse a Taylor UUCP Stats file into pretty results.
|
||||||
|
# Zacharias J. Beckman.
|
||||||
|
|
||||||
|
grep bytes /usr/spool/uucp/Stats | grep -v 'bytes 0.00 secs' | grep -v 'failed after' | tail -80 | \
|
||||||
|
gawk '
|
||||||
|
BEGIN {
|
||||||
|
printf(" UUCP transmission history:\n");
|
||||||
|
format=" %8d bytes %8s(%8s) in %7.2f sec = %5.0f baud, %4.1fK / min\n";
|
||||||
|
average=0.01;
|
||||||
|
samples=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if ($6 > 100) {
|
||||||
|
printf (format, $6, $5, $2, $9, $6/$9*10, ($6/$9*60)/1000);
|
||||||
|
|
||||||
|
average += ($6/$9*10);
|
||||||
|
samples += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END {
|
||||||
|
printf (" average speed %d baud\n", average/samples);
|
||||||
|
}
|
||||||
|
'
|
158
gnu/libexec/uucp/contrib/tstout.c
Normal file
158
gnu/libexec/uucp/contrib/tstout.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/* tstout.c
|
||||||
|
Put together by Ian Lance Taylor <ian@airs.com>
|
||||||
|
|
||||||
|
This program is used to logout a program run by the tstuu program.
|
||||||
|
I needed this because on Ultrix 4.0 I can't get the uucp program
|
||||||
|
to run without invoking it via /bin/login and having it start up
|
||||||
|
as a shell. If I don't do it this way, it gets a SIGSEGV trap
|
||||||
|
for some reason. Most systems probably don't need to do things
|
||||||
|
this way. It will only work on BSD systems anyhow, I suspect.
|
||||||
|
|
||||||
|
The code for this comes from "UNIX Network Programming" by W.
|
||||||
|
Richard Stevens, Prentice-Hall 1990. Most of it is from 4.3BSD, as
|
||||||
|
noted in the comments.
|
||||||
|
|
||||||
|
This program must run suid to root.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
static int logout P((const char *zdev));
|
||||||
|
static void logwtmp P((const char *zdev, const char *zname,
|
||||||
|
const char *zhost));
|
||||||
|
|
||||||
|
int
|
||||||
|
main (argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
char *z;
|
||||||
|
|
||||||
|
if (argc != 2
|
||||||
|
|| strncmp (argv[1], "/dev/", sizeof "/dev/" - 1) != 0)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Usage: tstout device\n");
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
z = argv[1] + 5;
|
||||||
|
|
||||||
|
if (logout (z))
|
||||||
|
logwtmp (z, "", "");
|
||||||
|
|
||||||
|
chmod (argv[1], 0666);
|
||||||
|
chown (argv[1], 0, 0);
|
||||||
|
|
||||||
|
*z = 'p';
|
||||||
|
chmod (argv[1], 0666);
|
||||||
|
chown (argv[1], 0, 0);
|
||||||
|
|
||||||
|
exit (EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1988 The Regents of the University of California.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms are permitted
|
||||||
|
* provided that the above copyright notice and this paragraph are
|
||||||
|
* duplicated in all such forms and that any documentation,
|
||||||
|
* advertising materials, and other materials related to such
|
||||||
|
* distribution and use acknowledge that the software was developed
|
||||||
|
* by the University of California, Berkeley. The name of the
|
||||||
|
* University may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)logout.c 5.2 (Berkeley) 2/17/89";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#define UTMPFILE "/etc/utmp"
|
||||||
|
|
||||||
|
/* 0 on failure, 1 on success */
|
||||||
|
|
||||||
|
static int
|
||||||
|
logout(line)
|
||||||
|
register const char *line;
|
||||||
|
{
|
||||||
|
register FILE *fp;
|
||||||
|
struct utmp ut;
|
||||||
|
int rval;
|
||||||
|
time_t time();
|
||||||
|
|
||||||
|
if (!(fp = fopen(UTMPFILE, "r+")))
|
||||||
|
return(0);
|
||||||
|
rval = 0;
|
||||||
|
while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
|
||||||
|
if (!ut.ut_name[0] ||
|
||||||
|
strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
|
||||||
|
continue;
|
||||||
|
bzero(ut.ut_name, sizeof(ut.ut_name));
|
||||||
|
bzero(ut.ut_host, sizeof(ut.ut_host));
|
||||||
|
(void)time((time_t *)&ut.ut_time);
|
||||||
|
(void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
|
||||||
|
(void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
|
||||||
|
(void)fseek(fp, (long)0, L_INCR);
|
||||||
|
rval = 1;
|
||||||
|
}
|
||||||
|
(void)fclose(fp);
|
||||||
|
return(rval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1988 The Regents of the University of California.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms are permitted
|
||||||
|
* provided that the above copyright notice and this paragraph are
|
||||||
|
* duplicated in all such forms and that any documentation,
|
||||||
|
* advertising materials, and other materials related to such
|
||||||
|
* distribution and use acknowledge that the software was developed
|
||||||
|
* by the University of California, Berkeley. The name of the
|
||||||
|
* University may not be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
static char sccsid[] = "@(#)logwtmp.c 5.2 (Berkeley) 9/20/88";
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#define WTMPFILE "/usr/adm/wtmp"
|
||||||
|
|
||||||
|
static void
|
||||||
|
logwtmp(line, name, host)
|
||||||
|
const char *line, *name, *host;
|
||||||
|
{
|
||||||
|
struct utmp ut;
|
||||||
|
struct stat buf;
|
||||||
|
int fd;
|
||||||
|
time_t time();
|
||||||
|
char *strncpy();
|
||||||
|
|
||||||
|
if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
|
||||||
|
return;
|
||||||
|
if (!fstat(fd, &buf)) {
|
||||||
|
(void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||||
|
(void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
|
||||||
|
(void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
|
||||||
|
(void)time((time_t *)&ut.ut_time);
|
||||||
|
if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
|
||||||
|
sizeof(struct utmp))
|
||||||
|
(void)ftruncate(fd, buf.st_size);
|
||||||
|
}
|
||||||
|
(void)close(fd);
|
||||||
|
}
|
23
gnu/libexec/uucp/contrib/uuclean
Normal file
23
gnu/libexec/uucp/contrib/uuclean
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# This is a sample uuclean shell script
|
||||||
|
# Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
# Do whatever you like with this script.
|
||||||
|
#
|
||||||
|
# Set some variables
|
||||||
|
bindir=/usr/local/bin
|
||||||
|
spooldir=/usr/spool/uucp
|
||||||
|
#
|
||||||
|
# Warn about all mail over two days old
|
||||||
|
$(bindir)/uustat -c rmail -o 48 -N -Q -W"Unable to deliver; will try up to one week"
|
||||||
|
# Return all mail over a week old
|
||||||
|
$(bindir)/uustat -c rmail -o 168 -K -M -N -Q -W"Could not be delivered for over one week"
|
||||||
|
# Throw away other requests over a week old
|
||||||
|
$(bindir)/uustat -o 168 -K -M -N -Q -W"Over one week old"
|
||||||
|
# Throw away any executions over three days old
|
||||||
|
$(bindir)/uustat -o 72 -M -N -Q -W"Unable to execute for three days"
|
||||||
|
#
|
||||||
|
# Now delete any old spool files
|
||||||
|
find $(spooldir) -ctime +8 -name '[CDX].*' -print -exec rm -f \{\} \;
|
||||||
|
# Delete any old temporary files
|
||||||
|
find $(spooldir) -atime +1 -ctime +1 -name 'TM.*' -print -exec rm -f \{\} \;
|
||||||
|
# Delete any old preserved files
|
||||||
|
find $(spooldir)/.Preserve -atime +14 -ctime +14 -print -exec rm -f \{\} \;
|
125
gnu/libexec/uucp/contrib/uuq.sh
Executable file
125
gnu/libexec/uucp/contrib/uuq.sh
Executable file
@ -0,0 +1,125 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# uuq - a script to examine and display the Taylor spool directory contents.
|
||||||
|
# note - uses the uuname script or similar functionality.
|
||||||
|
# Zacharias Beckman
|
||||||
|
|
||||||
|
SPOOLDIR="/usr/spool/uucp"
|
||||||
|
SYSTEMS=`uuname`
|
||||||
|
TMPFILE="/tmp/uuq.tmp"
|
||||||
|
FORSYSTEM=""
|
||||||
|
DELETE=""
|
||||||
|
LONG=0
|
||||||
|
SINGLE=0
|
||||||
|
|
||||||
|
while [ "$1" != "" ]
|
||||||
|
do
|
||||||
|
case $1 in
|
||||||
|
-l) LONG=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-s) shift
|
||||||
|
SYSTEMS=$argv[1]
|
||||||
|
SINGLE=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-d) shift
|
||||||
|
DELETE=$argv[1]
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h) echo "uuq: usage uuq [options]"
|
||||||
|
echo " -l long listing (may take a while)"
|
||||||
|
echo " -s n run uuq only for system n"
|
||||||
|
echo " -d n delete item n from the queue (required -s)"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*) echo "uuq: invalid option"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "${DELETE}" != "" ] && [ ${SINGLE} != 1 ] ; then
|
||||||
|
echo "uuq: you must specify a system to delete the job from:"
|
||||||
|
echo " uuq -s wizard -d D.0004"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ${SPOOLDIR}
|
||||||
|
|
||||||
|
# if we are deleting a job, then do that first and exit without showing
|
||||||
|
# any other queue information
|
||||||
|
|
||||||
|
if [ "${DELETE}" != "" ] ; then
|
||||||
|
if [ -d ${SYSTEMS}/D. ] ; then
|
||||||
|
cd ${SYSTEMS}/C.
|
||||||
|
PACKET=${DELETE}
|
||||||
|
if [ -f ${PACKET} ] ; then
|
||||||
|
EXFILE=../D.X/`awk '{if (NR == 2) print $2}' ${PACKET}`
|
||||||
|
DFILE=../D./`awk '{if (NR == 1) print $2}' ${PACKET}`
|
||||||
|
echo "deleting job ${PACKET}"
|
||||||
|
rm ${PACKET}
|
||||||
|
rm ${EXFILE}
|
||||||
|
rm ${DFILE}
|
||||||
|
else
|
||||||
|
echo "uuq: job ${PACKET} not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "uuq: system ${SYSTEMS} not found"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# use the 'uuname' script to obtain a list of systems for the 'sys' file,
|
||||||
|
# then step through each directory looking for appropriate information.
|
||||||
|
|
||||||
|
if [ ${LONG} -gt 0 ] ; then
|
||||||
|
echo "system"
|
||||||
|
echo -n "job# act size command"
|
||||||
|
fi
|
||||||
|
|
||||||
|
for DESTSYSTEM in ${SYSTEMS} ; do
|
||||||
|
# if there is an existing directory for the named system, cd into it and
|
||||||
|
# "do the right thing."
|
||||||
|
|
||||||
|
if [ -d ${DESTSYSTEM} ] ; then
|
||||||
|
cd ${DESTSYSTEM}/C.
|
||||||
|
|
||||||
|
PACKET=`ls`
|
||||||
|
|
||||||
|
if [ "${PACKET}" != "" ] ; then
|
||||||
|
# if a long listing has been required, extra information is printed
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "${DESTSYSTEM}:"
|
||||||
|
|
||||||
|
# now each packet must be examined and appropriate information is
|
||||||
|
# printed for this system
|
||||||
|
|
||||||
|
if [ ${LONG} -gt 0 ] ; then
|
||||||
|
for PACKET in * ; do
|
||||||
|
EXFILE=../D.X/`awk '{if (NR == 2) print $2}' ${PACKET}`
|
||||||
|
DFILE=../D./`awk '{if (NR == 1) print $2}' ${PACKET}`
|
||||||
|
echo -n "${PACKET} " > ${TMPFILE}
|
||||||
|
gawk '{if (NR == 2) printf(" %s ", $1);}' ${PACKET} >> ${TMPFILE}
|
||||||
|
ls -l ${DFILE}|awk '{printf("%-10d ", $4)}' >> ${TMPFILE}
|
||||||
|
if [ -f ${EXFILE} ] ; then
|
||||||
|
gawk '/U / {printf("(%s)", $2);}\
|
||||||
|
/C / {print substr($0,2,length($0));}' ${EXFILE} >> ${TMPFILE}
|
||||||
|
else
|
||||||
|
echo "---" >> ${TMPFILE}
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat ${TMPFILE}
|
||||||
|
done
|
||||||
|
cat ${SPOOLDIR}/.Status/${DESTSYSTEM}
|
||||||
|
else
|
||||||
|
ls
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd ${SPOOLDIR}
|
||||||
|
done
|
657
gnu/libexec/uucp/contrib/uurate.c
Normal file
657
gnu/libexec/uucp/contrib/uurate.c
Normal file
@ -0,0 +1,657 @@
|
|||||||
|
/*
|
||||||
|
* @(#)uurate.c 1.2 - Thu Sep 3 18:32:46 1992
|
||||||
|
*
|
||||||
|
* This program digests log and stats files in the "Taylor" format
|
||||||
|
* and outputs various statistical data to standard out.
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Bob Denny (denny@alisa.com)
|
||||||
|
* Fri Feb 7 13:38:36 1992
|
||||||
|
*
|
||||||
|
* Original author:
|
||||||
|
* Mark Pizzolato mark@infopiz.UUCP
|
||||||
|
*
|
||||||
|
* Edits:
|
||||||
|
* Bob Denny - Fri Feb 7 15:04:54 1992
|
||||||
|
* Heavy rework for Taylor UUCP. This was the (very old) uurate from
|
||||||
|
* DECUS UUCP, which had a single logfile for activity and stats.
|
||||||
|
* Personally, I would have done things differently, with tables
|
||||||
|
* and case statements, but in the interest of time, I preserved
|
||||||
|
* Mark Pizzolato's techniques and style.
|
||||||
|
*
|
||||||
|
* Bob Denny - Sun Aug 30 14:18:50 1992
|
||||||
|
* Changes to report format suggested by Francois Pinard and others.
|
||||||
|
* Add summary report, format from uutraf.pl (perl script), again
|
||||||
|
* thanks to Francois. Integrate and checkout with 1.03 of Taylor UUCP.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char version[] = "@(#) Taylor UUCP Log File Summary Filter, Version 1.2";
|
||||||
|
|
||||||
|
#include <ctype.h> /* Character Classification */
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define _DEBUG_ 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Direction of Calling and Data Transmission
|
||||||
|
*/
|
||||||
|
#define IN 0 /* Inbound */
|
||||||
|
#define OUT 1 /* Outbound */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data structures used to collect information
|
||||||
|
*/
|
||||||
|
struct File_Stats
|
||||||
|
{
|
||||||
|
int files; /* Files Transferred */
|
||||||
|
unsigned long bytes; /* Data Size Transferred*/
|
||||||
|
double time; /* Transmission Time */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Phone_Call
|
||||||
|
{
|
||||||
|
int calls; /* Call Count */
|
||||||
|
int succs; /* Successful calls */
|
||||||
|
double connect_time; /* Connect Time Spent */
|
||||||
|
struct File_Stats flow[2]; /* Rcvd & Sent Data */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Execution_Command
|
||||||
|
{
|
||||||
|
struct Execution_Command *next;
|
||||||
|
char Commandname[64];
|
||||||
|
int count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Host_entry
|
||||||
|
{
|
||||||
|
struct Host_entry *next;
|
||||||
|
char Hostname[32];
|
||||||
|
struct Execution_Command *cmds; /* Local Activities */
|
||||||
|
struct Phone_Call call[2]; /* In & Out Activities */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stuff for getopt()
|
||||||
|
*/
|
||||||
|
extern int optind; /* GETOPT : Option Index */
|
||||||
|
extern char *optarg; /* GETOPT : Option Value */
|
||||||
|
extern void *calloc();
|
||||||
|
|
||||||
|
static void fmtime();
|
||||||
|
static void fmbytes();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default files to read. Taken from Taylor compile-time configuration.
|
||||||
|
* Must look like an argvec, hence the dummy argv[0].
|
||||||
|
*/
|
||||||
|
static char *(def_logs[3]) = { "", LOGFILE, STATFILE };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Misc. strings for reports
|
||||||
|
*/
|
||||||
|
static char *(file_hdr[2]) = { "\nReceived file statistics:\n",
|
||||||
|
"\nSent file statistics\n" };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BEGIN EXECUTION
|
||||||
|
*/
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
char *p, *s;
|
||||||
|
struct Host_entry *hosts = NULL;
|
||||||
|
struct Host_entry *cur = NULL;
|
||||||
|
struct Host_entry *e;
|
||||||
|
struct Execution_Command *cmd;
|
||||||
|
struct Execution_Command *ec;
|
||||||
|
char Hostname[64];
|
||||||
|
FILE *Log = NULL;
|
||||||
|
char logline[1024];
|
||||||
|
char *logmsg;
|
||||||
|
int sent;
|
||||||
|
int called;
|
||||||
|
int show_files = 0; /* I prefer boolean, but... */
|
||||||
|
int show_calls = 0;
|
||||||
|
int show_commands = 0;
|
||||||
|
int show_efficiency = 0;
|
||||||
|
int show_summary = 0;
|
||||||
|
int have_files = 0;
|
||||||
|
int have_calls = 0;
|
||||||
|
int have_commands = 0;
|
||||||
|
int use_stdin = 0;
|
||||||
|
Hostname[0] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I wish the compiler had the #error directive!
|
||||||
|
*/
|
||||||
|
#if !HAVE_TAYLOR_LOGGING
|
||||||
|
fprintf(stderr, "uurate cannot be used with your configuration of\n");
|
||||||
|
fprintf(stderr, "Taylor UUCP. To use uurate you must be using the\n");
|
||||||
|
fprintf(stderr, "TAYLOR_LOGGING configuration.\n");
|
||||||
|
exit(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process the command line arguments
|
||||||
|
*/
|
||||||
|
while((c = getopt(argc, argv, "h:cfexai")) != EOF)
|
||||||
|
{
|
||||||
|
switch(c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
strcpy(Hostname, optarg);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
show_calls = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
show_files = 1;
|
||||||
|
break;
|
||||||
|
case 'x':
|
||||||
|
show_commands = 1;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
show_efficiency = 1;
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
show_calls = show_files = show_commands = show_efficiency = 1;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
use_stdin = 1;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If no report switches given, show summary report.
|
||||||
|
*/
|
||||||
|
if (show_calls == 0 && show_files == 0
|
||||||
|
&& show_efficiency == 0 && show_commands == 0)
|
||||||
|
show_summary = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust argv and argc to account for the args processed above.
|
||||||
|
*/
|
||||||
|
argc -= (optind - 1);
|
||||||
|
argv += (optind - 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If further args present, Assume rest are logfiles for us to process,
|
||||||
|
* otherwise, take input from Log and Stat files provided in the
|
||||||
|
* compilation environment of Taylor UUCP. If -i was given, Log already
|
||||||
|
* points to stdin and no file args are accepted.
|
||||||
|
*/
|
||||||
|
if(argc == 1) /* No file arguments */
|
||||||
|
{
|
||||||
|
if (use_stdin) /* If -i, read from stdin */
|
||||||
|
{
|
||||||
|
argc = 2;
|
||||||
|
Log = stdin;
|
||||||
|
}
|
||||||
|
else /* Read from current logs */
|
||||||
|
{
|
||||||
|
argc = 3; /* Bash argvec to default log/stat files */
|
||||||
|
argv = &def_logs[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (use_stdin) /* File args with -i is an error */
|
||||||
|
{
|
||||||
|
fprintf(stderr, "uurate (error): file args given with '-i'\n");
|
||||||
|
goto usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _DEBUG_
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MAIN LOGFILE PROCESSING LOOP
|
||||||
|
*/
|
||||||
|
while (argc > 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!use_stdin && (Log = fopen(argv[1], "r")) == NULL)
|
||||||
|
{
|
||||||
|
perror(argv[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _DEBUG_
|
||||||
|
printf("Reading %s...\n", (use_stdin ? "stdin" : argv[1]));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read each line of the logfile and collect information
|
||||||
|
*/
|
||||||
|
while (fgets(logline, sizeof(logline), Log))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The host name of the other end of the connection is
|
||||||
|
* always the second field of the log line, whether we
|
||||||
|
* are reading a Log file or a Stats file. Set 'p' to
|
||||||
|
* point to the second field, null-terminated. Skip
|
||||||
|
* the line if something is funny.
|
||||||
|
*/
|
||||||
|
if (NULL == (p = strchr(logline, ' ')))
|
||||||
|
continue;
|
||||||
|
++p;
|
||||||
|
if (NULL != (s = strchr(p, ' ')))
|
||||||
|
*s = '\0';
|
||||||
|
for (s = p; *s; ++s)
|
||||||
|
if (isupper(*s))
|
||||||
|
*s = tolower(*s);
|
||||||
|
/*
|
||||||
|
* Skip this line if we got -h <host> and
|
||||||
|
* this line does not contain that host name.
|
||||||
|
*/
|
||||||
|
if (Hostname[0] != '\0')
|
||||||
|
if (0 != strcmp(p, Hostname))
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* We are within a call block now. If this line is a file
|
||||||
|
* transfer record, determine the direction. If not then
|
||||||
|
* skip the line if it is not interesting.
|
||||||
|
*/
|
||||||
|
if ((s = strchr(++s, ')')) == NULL)
|
||||||
|
continue;
|
||||||
|
logmsg = s + 2; /* Message is 2 characters after ')' */
|
||||||
|
if (0 == strncmp(logmsg, "sent", 4))
|
||||||
|
sent = OUT;
|
||||||
|
else
|
||||||
|
if (0 == strncmp(logmsg, "received", 8))
|
||||||
|
sent = IN;
|
||||||
|
else
|
||||||
|
if ((0 != strncmp(logmsg, "Call complete", 13)) &&
|
||||||
|
(0 != strncmp(logmsg, "Calling system", 14)) &&
|
||||||
|
(0 != strncmp(logmsg, "Incoming call", 13)) &&
|
||||||
|
(0 != strncmp(logmsg, "Executing", 9)))
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Find the Host_entry for this host, or create a new
|
||||||
|
* one and link it on to the list.
|
||||||
|
*/
|
||||||
|
if ((cur == NULL) || (0 != strcmp(p, cur->Hostname)))
|
||||||
|
{
|
||||||
|
for (cur = hosts; cur != NULL ; cur = cur->next)
|
||||||
|
if (0 == strcmp(cur->Hostname, p))
|
||||||
|
break;
|
||||||
|
if (cur == NULL)
|
||||||
|
{
|
||||||
|
cur = (struct Host_entry *)calloc(1, sizeof(*hosts));
|
||||||
|
strcpy(cur->Hostname, p);
|
||||||
|
if (hosts == NULL)
|
||||||
|
hosts = cur;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (e = hosts; e->next != NULL; e = e->next);
|
||||||
|
e->next = cur;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* OK, if this is a uuxqt record, find the Execution_Command
|
||||||
|
* structure for the command being executed, or create a new
|
||||||
|
* one. Then count an execution of this command.
|
||||||
|
*/
|
||||||
|
if (0 == strncmp(logmsg, "Executing", 9))
|
||||||
|
{
|
||||||
|
if (NULL == (p = strchr(logmsg, '(')))
|
||||||
|
continue;
|
||||||
|
if ((s = strpbrk(++p, " )")) == NULL)
|
||||||
|
continue;
|
||||||
|
*s = '\0';
|
||||||
|
for (cmd = cur->cmds; cmd != NULL; cmd = cmd->next)
|
||||||
|
if (0 == strcmp(cmd->Commandname, p))
|
||||||
|
break;
|
||||||
|
if (cmd == NULL)
|
||||||
|
{
|
||||||
|
cmd = (struct Execution_Command *)calloc(1, sizeof(*cmd));
|
||||||
|
strcpy(cmd->Commandname, p);
|
||||||
|
if (cur->cmds == NULL)
|
||||||
|
cur->cmds = cmd;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (ec = cur->cmds; ec->next != NULL; ec = ec->next);
|
||||||
|
ec->next = cmd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++cmd->count;
|
||||||
|
have_commands = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Count start of outgoing call.
|
||||||
|
*/
|
||||||
|
if (0 == strncmp(logmsg, "Calling system", 14))
|
||||||
|
{
|
||||||
|
called = OUT;
|
||||||
|
cur->call[called].calls += 1;
|
||||||
|
have_calls = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Count start of incoming call.
|
||||||
|
*/
|
||||||
|
if (0 == strncmp(logmsg, "Incoming call", 13))
|
||||||
|
{
|
||||||
|
called = IN;
|
||||||
|
cur->call[called].calls += 1;
|
||||||
|
have_calls = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Handle end of call. Pick up the connect time.
|
||||||
|
*/
|
||||||
|
if (0 == strncmp(logmsg, "Call complete", 13))
|
||||||
|
{
|
||||||
|
cur->call[called].succs += 1;
|
||||||
|
if (NULL == (s = strchr(logmsg, '(')))
|
||||||
|
continue;
|
||||||
|
cur->call[called].connect_time += atof(s+1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If we reached here, this must have been a file transfer
|
||||||
|
* record. Count it in the field corresponding to the
|
||||||
|
* direction of the transfer. Count bytes transferred and
|
||||||
|
* the time to transfer as well.
|
||||||
|
*/
|
||||||
|
have_files = 1;
|
||||||
|
cur->call[called].flow[sent].files += 1;
|
||||||
|
if (NULL == (s = strchr(logmsg, ' ')))
|
||||||
|
continue;
|
||||||
|
cur->call[called].flow[sent].bytes += atol(++s);
|
||||||
|
if (NULL == (s = strchr(s, ' ')))
|
||||||
|
continue;
|
||||||
|
if (NULL == (s = strpbrk(s, "0123456789")))
|
||||||
|
continue;
|
||||||
|
cur->call[called].flow[sent].time += atof(s);
|
||||||
|
}
|
||||||
|
argc -= 1;
|
||||||
|
argv += 1;
|
||||||
|
if(Log != stdin)
|
||||||
|
fclose(Log);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ***********
|
||||||
|
* * REPORTS *
|
||||||
|
* ***********
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Truncate the Hostnames to 8 characters at most.
|
||||||
|
*/
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
cur->Hostname[8] = '\0';
|
||||||
|
|
||||||
|
#if _DEBUG_
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Summary report
|
||||||
|
*
|
||||||
|
* I know, this code could be tightened (rbd)...
|
||||||
|
*/
|
||||||
|
if(show_summary)
|
||||||
|
{
|
||||||
|
char t1[32], t2[32], t3[32], t4[32], t5[32];
|
||||||
|
long ib, ob, b, rf, sf;
|
||||||
|
long t_ib=0, t_ob=0, t_b=0, t_rf=0, t_sf=0;
|
||||||
|
double it, ot, ir, or;
|
||||||
|
double t_it=0.0, t_ot=0.0;
|
||||||
|
int nhosts = 0;
|
||||||
|
|
||||||
|
printf("\n\
|
||||||
|
Remote ------- Bytes -------- --- Time ---- -- Avg CPS -- -- Files --\n");
|
||||||
|
printf("\
|
||||||
|
Host Rcvd Sent Total Rcvd Sent Rcvd Sent Rcvd Sent\n");
|
||||||
|
printf("\
|
||||||
|
-------- ------- ------- ------- ------ ------ ------ ------ ----- -----\n");
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
{
|
||||||
|
ib = (cur->call[IN].flow[IN].bytes +
|
||||||
|
cur->call[OUT].flow[IN].bytes);
|
||||||
|
fmbytes(ib, t1);
|
||||||
|
t_ib += ib;
|
||||||
|
|
||||||
|
ob = (cur->call[IN].flow[OUT].bytes +
|
||||||
|
cur->call[OUT].flow[OUT].bytes);
|
||||||
|
fmbytes(ob, t2);
|
||||||
|
t_ob += ob;
|
||||||
|
|
||||||
|
b = ib + ob;
|
||||||
|
fmbytes(b, t3);
|
||||||
|
t_b += b;
|
||||||
|
|
||||||
|
it = cur->call[IN].flow[IN].time +
|
||||||
|
cur->call[OUT].flow[IN].time;
|
||||||
|
fmtime(it, t4);
|
||||||
|
t_it += it;
|
||||||
|
|
||||||
|
ot = cur->call[IN].flow[OUT].time +
|
||||||
|
cur->call[OUT].flow[OUT].time;
|
||||||
|
fmtime(ot, t5);
|
||||||
|
t_ot += ot;
|
||||||
|
|
||||||
|
rf = cur->call[IN].flow[IN].files +
|
||||||
|
cur->call[OUT].flow[IN].files;
|
||||||
|
t_rf += rf;
|
||||||
|
|
||||||
|
sf = cur->call[IN].flow[OUT].files +
|
||||||
|
cur->call[OUT].flow[OUT].files;
|
||||||
|
t_sf += sf;
|
||||||
|
|
||||||
|
ir = (it == 0.0) ? 0.0 : (ib / it);
|
||||||
|
or = (ot == 0.0) ? 0.0 : (ob / ot);
|
||||||
|
|
||||||
|
printf("%-8s %7s %7s %7s %6s %6s %6.1f %6.1f %5d %5d\n",
|
||||||
|
cur->Hostname,
|
||||||
|
t1, t2, t3, t4, t5,
|
||||||
|
ir, or, rf, sf);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nhosts > 1)
|
||||||
|
{
|
||||||
|
fmbytes(t_ib, t1);
|
||||||
|
fmbytes(t_ob, t2);
|
||||||
|
fmbytes(t_b, t3);
|
||||||
|
fmtime(t_it, t4);
|
||||||
|
fmtime(t_ot, t5);
|
||||||
|
ir = (t_it == 0.0) ? 0.0 : (t_ib / t_it);
|
||||||
|
or = (t_ot == 0.0) ? 0.0 : (t_ob / t_ot);
|
||||||
|
|
||||||
|
printf("\
|
||||||
|
-------- ------- ------- ------- ------ ------ ------ ------ ----- -----\n");
|
||||||
|
printf("\
|
||||||
|
Totals %7s %7s %7s %6s %6s %6.1f %6.1f %5d %5d\n",
|
||||||
|
t1, t2, t3, t4, t5,
|
||||||
|
ir, or, t_rf, t_sf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call statistics report
|
||||||
|
*/
|
||||||
|
if(show_calls && have_calls)
|
||||||
|
{
|
||||||
|
char t1[32], t2[32];
|
||||||
|
|
||||||
|
printf("\nCall statistics:\n");
|
||||||
|
printf("\
|
||||||
|
sysname callto failto totime callfm failfm fmtime\n");
|
||||||
|
printf("\
|
||||||
|
-------- ------ ------ -------- ------ ------ --------\n");
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
{
|
||||||
|
fmtime(cur->call[OUT].connect_time, t1);
|
||||||
|
fmtime(cur->call[IN].connect_time, t2),
|
||||||
|
printf(" %-8s %6d %6d %8s %6d %6d %8s\n",
|
||||||
|
cur->Hostname,
|
||||||
|
cur->call[OUT].calls,
|
||||||
|
cur->call[OUT].calls - cur->call[OUT].succs,
|
||||||
|
t1,
|
||||||
|
cur->call[IN].calls,
|
||||||
|
cur->call[IN].calls - cur->call[IN].succs,
|
||||||
|
t2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File statistics report
|
||||||
|
*/
|
||||||
|
if(show_files && have_files)
|
||||||
|
{
|
||||||
|
char t1[32], t2[32];
|
||||||
|
|
||||||
|
for (sent = IN; sent <= OUT; ++sent)
|
||||||
|
{
|
||||||
|
printf(file_hdr[sent]);
|
||||||
|
printf(" sysname files bytes xfr time byte/s\n");
|
||||||
|
printf(" -------- ------ -------- -------- ------\n");
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
{
|
||||||
|
double rate;
|
||||||
|
double time;
|
||||||
|
|
||||||
|
time = cur->call[IN].flow[sent].time +
|
||||||
|
cur->call[OUT].flow[sent].time;
|
||||||
|
if (time == 0.0)
|
||||||
|
continue;
|
||||||
|
rate = (cur->call[IN].flow[sent].bytes +
|
||||||
|
cur->call[OUT].flow[sent].bytes) / time;
|
||||||
|
fmbytes((cur->call[IN].flow[sent].bytes +
|
||||||
|
cur->call[OUT].flow[sent].bytes), t1);
|
||||||
|
fmtime((cur->call[IN].flow[sent].time +
|
||||||
|
cur->call[OUT].flow[sent].time), t2);
|
||||||
|
printf(" %-8s %6d %8s %8s %6.1f\n",
|
||||||
|
cur->Hostname,
|
||||||
|
cur->call[IN].flow[sent].files +
|
||||||
|
cur->call[OUT].flow[sent].files,
|
||||||
|
t1, t2, rate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Efficiency report
|
||||||
|
*/
|
||||||
|
if (show_efficiency && have_files)
|
||||||
|
{
|
||||||
|
char t1[32], t2[32], t3[32];
|
||||||
|
double total, flow;
|
||||||
|
|
||||||
|
printf("\nEfficiency:\n");
|
||||||
|
printf(" sysname conntime flowtime ovhdtime eff. %%\n");
|
||||||
|
printf(" -------- -------- -------- -------- ------\n");
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
{
|
||||||
|
total = cur->call[IN].connect_time + cur->call[OUT].connect_time;
|
||||||
|
flow = cur->call[IN].flow[IN].time + cur->call[IN].flow[OUT].time +
|
||||||
|
cur->call[OUT].flow[IN].time + cur->call[OUT].flow[OUT].time;
|
||||||
|
fmtime(total, t1);
|
||||||
|
fmtime(flow, t2);
|
||||||
|
fmtime((total-flow), t3);
|
||||||
|
printf(" %-8s %8s %8s %8s %5.1f%%\n",
|
||||||
|
cur->Hostname, t1, t2, t3, ((flow / total) * 100.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command execution report
|
||||||
|
*/
|
||||||
|
if (show_commands & have_commands)
|
||||||
|
{
|
||||||
|
printf("\nCommand executions:\n");
|
||||||
|
printf(" sysname rmail rnews other\n");
|
||||||
|
printf(" -------- ------ ------ ------\n");
|
||||||
|
for (cur = hosts; cur != NULL; cur = cur->next)
|
||||||
|
{
|
||||||
|
int rmail, rnews, other;
|
||||||
|
|
||||||
|
if (cur->cmds == NULL)
|
||||||
|
continue;
|
||||||
|
rmail = rnews = other = 0;
|
||||||
|
for (cmd = cur->cmds; cmd != NULL; cmd = cmd->next)
|
||||||
|
{
|
||||||
|
if (strcmp(cmd->Commandname, "rmail") == 0)
|
||||||
|
rmail += cmd->count;
|
||||||
|
else if (strcmp(cmd->Commandname, "rnews") == 0)
|
||||||
|
rnews += cmd->count;
|
||||||
|
else
|
||||||
|
other += cmd->count;
|
||||||
|
}
|
||||||
|
printf(" %-8s %6d %6d %6d\n", cur->Hostname,
|
||||||
|
rmail, rnews, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage uurate [-cfexai] [-h hostname] [logfile ... logfile]\n");
|
||||||
|
fprintf(stderr,"where:\t-c\tReport call statistics\n");
|
||||||
|
fprintf(stderr, "\t-f\tReport file transfer statistics\n");
|
||||||
|
fprintf(stderr, "\t-e\tReport efficiency statistics\n");
|
||||||
|
fprintf(stderr, "\t-x\tReport command execution statistics\n");
|
||||||
|
fprintf(stderr, "\t-a\tAll of the above reports\n");
|
||||||
|
fprintf(stderr, "\t-h host\tReport activities involving ONLY host\n");
|
||||||
|
fprintf(stderr, "\t-i\tRead log info from standard input\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"If no report options given, a compact summary report is given.\n");
|
||||||
|
fprintf(stderr,
|
||||||
|
"If neither -i nor logfiles given, defaults to reading from\n");
|
||||||
|
fprintf(stderr, "%s and %s\n\n", LOGFILE, STATFILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fmtime() - Format time in hours & minutes;
|
||||||
|
*/
|
||||||
|
static void fmtime(dsec, buf)
|
||||||
|
double dsec;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
long hrs, min, lsec;
|
||||||
|
|
||||||
|
lsec = dsec;
|
||||||
|
hrs = lsec / 3600L;
|
||||||
|
min = (lsec - (hrs * 3600L)) / 60L;
|
||||||
|
|
||||||
|
sprintf(buf, "%02ld:%02ld", hrs, min);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fmbytes - Format size in bytes
|
||||||
|
*/
|
||||||
|
static void fmbytes(n, buf)
|
||||||
|
unsigned long n;
|
||||||
|
char *buf;
|
||||||
|
{
|
||||||
|
char t;
|
||||||
|
double s = n;
|
||||||
|
|
||||||
|
if(s >= 10239897.6) /* More than 9999.9K ? */
|
||||||
|
{
|
||||||
|
s = (double)n / 1048576.0; /* Yes, display in Megabytes */
|
||||||
|
t = 'M';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s = (double)n / 1024.0; /* Display in Kilobytes */
|
||||||
|
t = 'K';
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(buf, "%.1f%c", s, t);
|
||||||
|
}
|
||||||
|
|
217
gnu/libexec/uucp/contrib/uurate.man
Normal file
217
gnu/libexec/uucp/contrib/uurate.man
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
.TH uurate 1
|
||||||
|
.SH NAME
|
||||||
|
uurate \- Report Taylor UUCP statistics
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BR uurate " [ " "\-cfexai" " ] [ " "\-h "
|
||||||
|
.I host
|
||||||
|
.RI " ] [ " "logfile..." " ] "
|
||||||
|
.PP
|
||||||
|
or simply,
|
||||||
|
.PP
|
||||||
|
.B uurate
|
||||||
|
.PP
|
||||||
|
for a traffic summary report.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.I uurate
|
||||||
|
command provides tabular summary reports on the operation of the
|
||||||
|
Taylor UUCP system. Data is taken from the currently active log
|
||||||
|
files, standard input, or from a list of log files given on the
|
||||||
|
command line. Output is in the form of tabular reports summarizing
|
||||||
|
call, file transfer, and command execution
|
||||||
|
.RI "(" "uuxqt" ")"
|
||||||
|
activity.
|
||||||
|
.PP
|
||||||
|
The log files given to
|
||||||
|
.I uurate
|
||||||
|
must be in the ``Taylor'' format. Also, note that call and file
|
||||||
|
transfer activities are logged in separate files, nominally called
|
||||||
|
.I Log
|
||||||
|
and
|
||||||
|
.I Stats,
|
||||||
|
respectively. For reports to be meaningful, the
|
||||||
|
.I Log
|
||||||
|
and
|
||||||
|
.I Stats
|
||||||
|
files should be given to
|
||||||
|
.I uurate
|
||||||
|
together, and cover the same time period.
|
||||||
|
.PP
|
||||||
|
If neither the
|
||||||
|
.B \-i
|
||||||
|
option nor any
|
||||||
|
.I logfile
|
||||||
|
options are given,
|
||||||
|
.I uurate
|
||||||
|
defaults to taking its input from the current Taylor
|
||||||
|
.I Log
|
||||||
|
and
|
||||||
|
.I Stats
|
||||||
|
files, as defined at compilation time.
|
||||||
|
This is the normal mode of operation.
|
||||||
|
.PP
|
||||||
|
The reporting options described below can be used to select
|
||||||
|
the set of reports desired. If no options are given, the
|
||||||
|
.B call
|
||||||
|
and
|
||||||
|
.B file
|
||||||
|
reports are displayed. If there is no relevant data for a particular
|
||||||
|
report or host, that report or host will be supressed.
|
||||||
|
.SH OPTIONS
|
||||||
|
The following options may be given to
|
||||||
|
.I uurate:
|
||||||
|
.TP 5
|
||||||
|
.B \-c
|
||||||
|
Report on call statistics. Requires data from a
|
||||||
|
.I Log
|
||||||
|
file.
|
||||||
|
.TP 5
|
||||||
|
.B \-f
|
||||||
|
Report on file transfer statistics. Requires data from a
|
||||||
|
.I Stats
|
||||||
|
file.
|
||||||
|
.TP 5
|
||||||
|
.B \-e
|
||||||
|
Report on efficiency (total connect time versus time spent transferring
|
||||||
|
files). Requires data from both a
|
||||||
|
.I Log
|
||||||
|
and a
|
||||||
|
.I Stats
|
||||||
|
file, and they must span the same time period.
|
||||||
|
.TP 5
|
||||||
|
.B \-x
|
||||||
|
Report on remote execution requests (e.g.,
|
||||||
|
.IR rmail ")."
|
||||||
|
Requires data from a
|
||||||
|
.I Log
|
||||||
|
file.
|
||||||
|
.TP 5
|
||||||
|
.B \-a
|
||||||
|
All reports. Identical to
|
||||||
|
.B \-cfex.
|
||||||
|
.TP 5
|
||||||
|
.BI "\-h " "host"
|
||||||
|
Restrict report output to
|
||||||
|
.I host.
|
||||||
|
.SH "DESCRIPTION OF REPORTS"
|
||||||
|
There are four reports available: the call, file transfer, efficiency,
|
||||||
|
and remote execution reports. Each may be selected by a command line
|
||||||
|
option. All reports may be selected via the option
|
||||||
|
.B \-a.
|
||||||
|
If no report selection options are given,
|
||||||
|
.I uurate
|
||||||
|
displays a compact traffic summary report (see below).
|
||||||
|
.SS "Summary report"
|
||||||
|
If no report options are given,
|
||||||
|
.I uurate
|
||||||
|
displays a traffic summary report. This is particularly useful in daily
|
||||||
|
.I cron
|
||||||
|
jobs which report on errors and the like. Traffic statistics for each
|
||||||
|
active system is reported on a single line. If more than one system was
|
||||||
|
active, a 'totals' line is included at the end of the report.
|
||||||
|
.SS "Call report"
|
||||||
|
The call report gives statistics on inbound and outbound calls for
|
||||||
|
each active host system. The fields are described below:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +.5i
|
||||||
|
.ta 1.0i
|
||||||
|
.BR "sysname " "UUCP node name of neighbor host system"
|
||||||
|
.BR "callto " "Outbound calls attempted to that system"
|
||||||
|
.BR "failto " "Failed outbound calls to that system"
|
||||||
|
.BR "totime " "Connect time (sec.) on outbound calls"
|
||||||
|
.BR "callfm " "Inbound calls attempted by that system"
|
||||||
|
.BR "failfm " "Failed inbound calls from that system"
|
||||||
|
.BR "fmtime " "Connect time (sec.) on inbound calls"
|
||||||
|
.in -.5
|
||||||
|
.SS "File transfer reports"
|
||||||
|
The file transfer reports give statistics on inbound and
|
||||||
|
outbound file transfers (regardless of which end initiated the transfer)
|
||||||
|
for each active host system. There are two reports, one for files
|
||||||
|
sent to the remote system and one for files received from the remote
|
||||||
|
system. The fields in each report are described below:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +.5i
|
||||||
|
.ta 1.0i
|
||||||
|
.BR "sysname " "UUCP node name of neighbor host system"
|
||||||
|
.BR "files " "Number of files transferred"
|
||||||
|
.BR "bytes " "Total size (bytes) of files transferred"
|
||||||
|
.BR "seconds " "Total time (sec.) to transfer files"
|
||||||
|
.BR "byte/sec " "Average transfer rate (bytes/sec)"
|
||||||
|
.in -.5
|
||||||
|
.SS "Efficiency report"
|
||||||
|
The efficiency report describes the utilization of the links
|
||||||
|
to each active remote system, giving the ratio of total connect time
|
||||||
|
to the time spent actually transferring files.
|
||||||
|
The fields are described below:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +.5i
|
||||||
|
.ta 1.0i
|
||||||
|
.BR "sysname " "UUCP node name of neighbor host system"
|
||||||
|
.BR "conntime " "Total connect time for that system"
|
||||||
|
.BR "flowtime " "Total file transfer time for that system"
|
||||||
|
.BR "ovhdtime " "Connect time not used to transfer files"
|
||||||
|
.BR "effcy (%) " "Ratio of connect time to transfer time"
|
||||||
|
.in -.5
|
||||||
|
.SS "Remote execution report"
|
||||||
|
The remote execution report describes remotely
|
||||||
|
requested command executions from each active host system.
|
||||||
|
Executions of
|
||||||
|
.I rmail
|
||||||
|
and
|
||||||
|
.I rnews
|
||||||
|
are the most common, and are detailed separately. The fields
|
||||||
|
are described below:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +.5i
|
||||||
|
.ta 1.0i
|
||||||
|
.BR "sysname " "UUCP node name of neighbor host system"
|
||||||
|
.BR "rmail " "Number of rmail requests from that system"
|
||||||
|
.BR "rnews " "Number of rnews requests from that system"
|
||||||
|
.BR "other " "Number of other requests from that system"
|
||||||
|
.in -.5i
|
||||||
|
.SS FILES
|
||||||
|
The file names below may be changed at compilation time or by the
|
||||||
|
configuration file, so these are only approximations.
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +.5in
|
||||||
|
.ta 2.0i
|
||||||
|
.IR "/usr/spool/uucp/Log " "Taylor format call/execution log"
|
||||||
|
.IR "/usr/spool/uucp/Stats " "Taylor format file transfer log"
|
||||||
|
.SS "SEE ALSO"
|
||||||
|
.IR uucico "(8)"
|
||||||
|
.SS BUGS
|
||||||
|
Does not understand older (V2, BNU) logging formats. Anyone care to
|
||||||
|
volunteer to add this? I don't use the stuff myself.
|
||||||
|
.PP
|
||||||
|
The entries that Taylor UUCP makes in the log file for incoming calls
|
||||||
|
don't have a host name. This confuses
|
||||||
|
.I uurate
|
||||||
|
into thinking that the calls came in for system "-". This may require
|
||||||
|
a change to Taylor logging.
|
||||||
|
.PP
|
||||||
|
Should check the configuration file to locate the currently active
|
||||||
|
.I Log
|
||||||
|
and
|
||||||
|
.I Stats
|
||||||
|
files when using them for default inputs. Instead, it uses the
|
||||||
|
compile-time settings only.
|
||||||
|
.PP
|
||||||
|
Should report packet protocol error statistics by host and
|
||||||
|
protocol type.
|
||||||
|
.SS AUTHOR
|
||||||
|
Robert B. Denny (denny@alisa.com)
|
||||||
|
.br
|
||||||
|
Loosely based on the DECUS UUCP program
|
||||||
|
.I uurate
|
||||||
|
by Mark Pizzolato.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
91
gnu/libexec/uucp/contrib/uureroute
Executable file
91
gnu/libexec/uucp/contrib/uureroute
Executable file
@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/local/bin/perl
|
||||||
|
eval ' exec /usr/local/bin/perl $0 "$@" '
|
||||||
|
if $running_under_some_shell;
|
||||||
|
|
||||||
|
# From a script by <Bill.Campbell@celestial.com>
|
||||||
|
# Newsgroups: comp.sources.misc
|
||||||
|
# Subject: v28i073: uureroute - Reroute HDB queued mail, Part01/01
|
||||||
|
# Date: 26 Feb 92 02:28:37 GMT
|
||||||
|
#
|
||||||
|
# This is a Honey DanBer specific routine written in perl to reroute all
|
||||||
|
# mail queued up for a specific host. It needs to be run as "root" since
|
||||||
|
# uucp will not allow itself to remove others requests.
|
||||||
|
#
|
||||||
|
# Revision *** 92/21/09: Francois Pinard <pinard@iro.umontreal.ca>
|
||||||
|
# 1. adapted for Taylor UUCP
|
||||||
|
#
|
||||||
|
# Revision 1.3 91/10/08 09:01:21 src
|
||||||
|
# 1. Rewritten in perl
|
||||||
|
# 2. Add -v option for debugging.
|
||||||
|
#
|
||||||
|
# Revision 1.2 91/10/07 23:57:42 root
|
||||||
|
# 1. Fix mail program path.
|
||||||
|
# 2. Truncate directory name to 7 characters
|
||||||
|
|
||||||
|
($progname = $0) =~ s!.*/!!; # save this very early
|
||||||
|
|
||||||
|
$USAGE = "
|
||||||
|
# Reroute uucp mail
|
||||||
|
#
|
||||||
|
# Usage: $progname [-v] host [host...]
|
||||||
|
#
|
||||||
|
# Options Argument Description
|
||||||
|
# -v Verbose (doesn't execute /bin/sh)
|
||||||
|
#
|
||||||
|
";
|
||||||
|
|
||||||
|
$UUSTAT = "/usr/local/bin/uustat";
|
||||||
|
$SHELL = "/bin/sh";
|
||||||
|
$SMAIL = "/bin/smail";
|
||||||
|
|
||||||
|
sub usage
|
||||||
|
{
|
||||||
|
die join ("\n", @_) . "\n$USAGE\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
do "getopts.pl";
|
||||||
|
|
||||||
|
&usage ("Invalid Option") unless do Getopts ("vV");
|
||||||
|
|
||||||
|
$verbose = ($opt_v ? '-v' : ());
|
||||||
|
$suffix = ($verbose ? '' : $$);
|
||||||
|
|
||||||
|
&usage ("No system specified") if $#ARGV < 0;
|
||||||
|
|
||||||
|
if (!$verbose)
|
||||||
|
{
|
||||||
|
open (SHELL, "| $SHELL");
|
||||||
|
select SHELL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ($system = shift)
|
||||||
|
{
|
||||||
|
$sysprefix = substr ($system, 0, 7);
|
||||||
|
$directory = "/usr/spool/uucp/$sysprefix";
|
||||||
|
open (UUSTAT, "$UUSTAT -s $system -c rmail |");
|
||||||
|
print "set -ex\n";
|
||||||
|
while (<UUSTAT>)
|
||||||
|
{
|
||||||
|
($jobid, ) = split;
|
||||||
|
($cfile) = substr ($jobid, length ($jobid) - 5);
|
||||||
|
$cfilename = "$directory/C./C.$cfile";
|
||||||
|
open (CFILE, $cfilename) || die "Cannot open $cfilename\n";
|
||||||
|
$_ = <CFILE>;
|
||||||
|
close CFILE;
|
||||||
|
if (/^E D\.(....) [^ ]+ [^ ]+ -CR D\.\1 0666 [^ ]+ 0 rmail (.*)/)
|
||||||
|
{
|
||||||
|
$datafile = "$directory/D./D.$1";
|
||||||
|
$address = $2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print STDERR;
|
||||||
|
die "Cannot parse previous line from $cfilename\n";
|
||||||
|
}
|
||||||
|
print "$SMAIL -R $system!$address < $datafile && $UUSTAT -k $jobid\n";
|
||||||
|
}
|
||||||
|
close UUSTAT;
|
||||||
|
}
|
||||||
|
close SHELL unless $verbose;
|
||||||
|
|
||||||
|
exit 0;
|
321
gnu/libexec/uucp/contrib/uusnap.c
Normal file
321
gnu/libexec/uucp/contrib/uusnap.c
Normal file
@ -0,0 +1,321 @@
|
|||||||
|
/* uusnap.c
|
||||||
|
(c) 1992 Heiko W.Rupp hwr@pilhuhn.ka.sub.org
|
||||||
|
uusnap is a tool to display the activities of the connected
|
||||||
|
systems.
|
||||||
|
|
||||||
|
Put a file uusnap.systems in NEWCONFIGDIR (see Makefile), in which
|
||||||
|
the systems, you want to monitor are listed, one on a single line.
|
||||||
|
The sequence of the files there determine the sequence of the
|
||||||
|
listing.
|
||||||
|
|
||||||
|
At the moment it only works with taylor config and taylor dirs
|
||||||
|
|
||||||
|
compile it form the Makefile or:
|
||||||
|
cc -c -g -pipe -O -I. -I. -DNEWCONFIGLIB=\"/usr/local/lib/uucp\" uusnap.c
|
||||||
|
cc -o uusnap uusnap.o
|
||||||
|
For this, uusnap.[ch] must be in the same directory as uucp.h and so.
|
||||||
|
|
||||||
|
uusnap must have read access to SPOOLDIR/.Status in order to work.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAXSYS 30 /* maximum number of systems */
|
||||||
|
#define WAIT_NORMAL 10 /* wait period if noone is talking */
|
||||||
|
#define WAIT_TALKING 2 /* refresh display every second if */
|
||||||
|
/* someone is talking with us */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
#if USE_RCS_ID
|
||||||
|
char uusnap_rcsid[] = "$Id: uusnap.c,v 1.1 1993/08/04 19:31:43 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
|
||||||
|
extern char *ctime(time_t*);
|
||||||
|
|
||||||
|
struct sysInfo {
|
||||||
|
char sysname[10]; /* name of the system to watch */
|
||||||
|
char *statfile; /* name of its status file */
|
||||||
|
char *spooldir; /* root of its spooldir */
|
||||||
|
int in; /* number of unprocessed in-files */
|
||||||
|
int out; /* number of files to send them */
|
||||||
|
time_t last; /* last poll time */
|
||||||
|
time_t next; /* time of next poll */
|
||||||
|
time_t lastidir; /* time of last in-spooldir access */
|
||||||
|
time_t lastodir; /* time of last outgoing spd acc */
|
||||||
|
time_t laststat; /* time of last status file access */
|
||||||
|
int status; /* status of the system */
|
||||||
|
int num_retries; /* number of retries */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sysInfo Systems[MAXSYS];
|
||||||
|
|
||||||
|
|
||||||
|
/* I have extend the system status. If time for the specified system
|
||||||
|
is Never, I say so. To get this to work, one also should extend
|
||||||
|
uucico.c. It is not important to do this. With the normal uucico,
|
||||||
|
one only gets no status.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *azStatus[] = /* Status codes as defined by uucico */
|
||||||
|
{ /* listing them here instead of */
|
||||||
|
"Conversation complete", /* including the appropriate file */
|
||||||
|
"Port unavailable", /* reduces the size of the executable */
|
||||||
|
"Dial failed",
|
||||||
|
"Login failed",
|
||||||
|
"Handshake failed",
|
||||||
|
"Call failed",
|
||||||
|
"Talking",
|
||||||
|
"Wrong time to call",
|
||||||
|
"Time to call = Never !"
|
||||||
|
};
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
i=get_systems();
|
||||||
|
display_info(i);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
get_systems()
|
||||||
|
{
|
||||||
|
char filename[1024];
|
||||||
|
char fn[1024];
|
||||||
|
char line[80];
|
||||||
|
FILE *fp;
|
||||||
|
int i=0;
|
||||||
|
int j;
|
||||||
|
struct stat stbuf;
|
||||||
|
struct sysInfo sys;
|
||||||
|
|
||||||
|
strcpy(filename,NEWCONFIGLIB);
|
||||||
|
strcat(filename,"/uusnap.systems");
|
||||||
|
if ((fp=fopen(filename,"r"))!=NULL) {
|
||||||
|
while (fgets(line,80,fp)!=NULL) {
|
||||||
|
*(rindex(line,'\n'))='\0';
|
||||||
|
strcpy(sys.sysname,line); /* get the name of the system */
|
||||||
|
strcpy(fn,SPOOLDIR); /* get the name of the statusfile */
|
||||||
|
strcat(fn,"/.Status/");
|
||||||
|
strcat(fn,line);
|
||||||
|
sys.statfile=malloc(strlen(fn)+1);
|
||||||
|
strcpy(sys.statfile,fn);
|
||||||
|
strcpy(fn,SPOOLDIR); /* get the name of the spooldir */
|
||||||
|
strcat(fn,"/");
|
||||||
|
strcat(fn,line);
|
||||||
|
sys.spooldir=malloc(strlen(fn)+1);
|
||||||
|
strcpy(sys.spooldir,fn);
|
||||||
|
sys.laststat=0;
|
||||||
|
sys.lastidir=sys.lastodir=0;
|
||||||
|
Systems[i]=sys; /* get_stat_for_system needs it */
|
||||||
|
get_stat_for_system(i); /* now get the system status */
|
||||||
|
get_inq_num(i,TRUE); /* number of unprocessed files */
|
||||||
|
get_outq_num(i,TRUE); /* number of files to send */
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"Can't open %s \n",filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
display_info(int numSys)
|
||||||
|
{
|
||||||
|
char *filename;
|
||||||
|
int sysnum;
|
||||||
|
FILE *fp;
|
||||||
|
char contentline[80];
|
||||||
|
char isTalking=FALSE;
|
||||||
|
struct stat stbuf;
|
||||||
|
struct sysInfo sys;
|
||||||
|
time_t time;
|
||||||
|
|
||||||
|
filename = (char*)malloc(1024);
|
||||||
|
if (filename == NULL) {
|
||||||
|
fprintf(stderr, "Can't malloc 1024 bytes");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(TRUE) {
|
||||||
|
display_headline();
|
||||||
|
for (sysnum=0;sysnum<numSys;sysnum++) {
|
||||||
|
sys = Systems[sysnum];
|
||||||
|
stat(sys.statfile,&stbuf);
|
||||||
|
if ((time=stbuf.st_atime) > sys.laststat) {
|
||||||
|
get_stat_for_system(sysnum);
|
||||||
|
}
|
||||||
|
if(display_status_line(sysnum)==1)
|
||||||
|
isTalking=TRUE;
|
||||||
|
}
|
||||||
|
if (isTalking) {
|
||||||
|
sleep(WAIT_TALKING);
|
||||||
|
isTalking = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sleep(WAIT_NORMAL); /* wait a bit */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
display_status_line(int sn)
|
||||||
|
{
|
||||||
|
char *time_s;
|
||||||
|
|
||||||
|
int sys_stat,num_retries,wait;
|
||||||
|
int i;
|
||||||
|
time_t last_time;
|
||||||
|
time_t next_time;
|
||||||
|
|
||||||
|
struct sysInfo sys;
|
||||||
|
|
||||||
|
sys = Systems[sn];
|
||||||
|
|
||||||
|
printf("%10s ",sys.sysname);
|
||||||
|
get_inq_num(sn);
|
||||||
|
if (sys.in==0)
|
||||||
|
printf(" ");
|
||||||
|
else
|
||||||
|
printf("%3d ",sys.in);
|
||||||
|
get_outq_num(sn);
|
||||||
|
if (sys.out==0)
|
||||||
|
printf(" ");
|
||||||
|
else
|
||||||
|
printf("%3d ",sys.out);
|
||||||
|
time_s = ctime(&sys.last);
|
||||||
|
time_s = time_s + 11;
|
||||||
|
*(time_s+8)='\0';
|
||||||
|
printf("%8s ",time_s); /* time of last poll */
|
||||||
|
time_s = ctime(&sys.next);
|
||||||
|
time_s = time_s + 11;
|
||||||
|
*(time_s+8)='\0';
|
||||||
|
if (sys.last == sys.next)
|
||||||
|
printf(" ");
|
||||||
|
else
|
||||||
|
printf("%8s ",time_s); /* time of next poll */
|
||||||
|
if (sys.num_retries==0)
|
||||||
|
printf(" ");
|
||||||
|
else
|
||||||
|
printf("%2d ",sys.num_retries);
|
||||||
|
if (sys_stat==6) /* system is talking */
|
||||||
|
printf("\E[7m"); /* reverse video on */
|
||||||
|
printf("%s",azStatus[sys.status]);
|
||||||
|
if (sys.status==6) {
|
||||||
|
printf("\E[m\n"); /* reverse video off */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
display_headline()
|
||||||
|
{
|
||||||
|
printf("\E[;H\E[2J"); /* clear screen */
|
||||||
|
printf("\E[7muusnap (press CTRL-C to escape)\E[m \n\n");
|
||||||
|
printf(" System #in #out last next #ret Status\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_inq_num(int num,char firstTime)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
char filename[1024];
|
||||||
|
struct stat stbuf;
|
||||||
|
DIR *dirp;
|
||||||
|
|
||||||
|
strcpy(filename,Systems[num].spooldir);
|
||||||
|
strcat(filename,"/X./.");
|
||||||
|
stat(filename,&stbuf);
|
||||||
|
if ((stbuf.st_mtime > Systems[num].lastidir) || (firstTime)) {
|
||||||
|
if ((dirp=opendir(filename))!=NULL) {
|
||||||
|
while(readdir(dirp))
|
||||||
|
i++;
|
||||||
|
closedir(dirp);
|
||||||
|
stat(filename,&stbuf);
|
||||||
|
Systems[num].lastidir=stbuf.st_mtime;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"Can't open %s \n",filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (i>=2)
|
||||||
|
i-=2; /* correct . and .. */
|
||||||
|
Systems[num].in=i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_outq_num(int sys,char firstTime)
|
||||||
|
{
|
||||||
|
int i=0;
|
||||||
|
char filename[1024];
|
||||||
|
struct stat stbuf;
|
||||||
|
DIR *dirp;
|
||||||
|
|
||||||
|
strcpy(filename,Systems[sys].spooldir);
|
||||||
|
strcat(filename,"/C./.");
|
||||||
|
stat(filename,&stbuf);
|
||||||
|
if ((stbuf.st_mtime > Systems[sys].lastodir) || (firstTime)) {
|
||||||
|
if ((dirp=opendir(filename))!=NULL) {
|
||||||
|
while(readdir(dirp))
|
||||||
|
i++;
|
||||||
|
closedir(dirp);
|
||||||
|
stat(filename,&stbuf);
|
||||||
|
Systems[sys].lastodir=stbuf.st_mtime;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fprintf(stderr,"Can't open %s \n",filename);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (i>=2)
|
||||||
|
i-=2; /* correct . and .. */
|
||||||
|
Systems[sys].out=i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_stat_for_system(int i)
|
||||||
|
{
|
||||||
|
char fn[80];
|
||||||
|
struct sysInfo sys;
|
||||||
|
struct stat stbuf;
|
||||||
|
FILE *fp;
|
||||||
|
time_t wait;
|
||||||
|
|
||||||
|
sys = Systems[i];
|
||||||
|
stat(sys.statfile,&stbuf);
|
||||||
|
if (stbuf.st_atime > sys.laststat) {
|
||||||
|
if ((fp=fopen(sys.statfile,"r"))!=NULL) {
|
||||||
|
fgets(fn,80,fp);
|
||||||
|
fclose(fp);
|
||||||
|
sscanf(fn,"%d %d %ld %d",
|
||||||
|
&sys.status,
|
||||||
|
&sys.num_retries,
|
||||||
|
&sys.last,
|
||||||
|
&wait);
|
||||||
|
sys.next=sys.last+wait;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sys.status=0;
|
||||||
|
sys.num_retries=0;
|
||||||
|
sys.last=0;
|
||||||
|
sys.next=0;
|
||||||
|
}
|
||||||
|
stat(sys.statfile,&stbuf);
|
||||||
|
sys.laststat=stbuf.st_atime;
|
||||||
|
}
|
||||||
|
Systems[i] = sys;
|
||||||
|
return 0;
|
||||||
|
}
|
203
gnu/libexec/uucp/contrib/uutraf
Normal file
203
gnu/libexec/uucp/contrib/uutraf
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
#!/usr/local/bin/perl
|
||||||
|
# uutraf.pl -- UUCP Traffic Analyzer
|
||||||
|
# SCCS Status : @(#)@ uutraf 1.7
|
||||||
|
# Author : Johan Vromans
|
||||||
|
# Created On : ***
|
||||||
|
# Last Modified By: Johan Vromans
|
||||||
|
# Last Modified On: Wed Feb 26 08:52:56 1992
|
||||||
|
# Update Count : 4
|
||||||
|
# Status : OK
|
||||||
|
# Requires: : Perl V4 or later
|
||||||
|
|
||||||
|
# Reads UUCP syslog, and generates a report from it.
|
||||||
|
#
|
||||||
|
# Created by Johan Vromans <jv@mh.nl>
|
||||||
|
# Loosely based on an idea by Greg Hackney (hack@texbell.swbt.com)
|
||||||
|
|
||||||
|
# Usage: uutraf [-taylor|-hdb|-bnu|-bsd] [syslog]
|
||||||
|
|
||||||
|
# Logfile formats:
|
||||||
|
#
|
||||||
|
# BSD:
|
||||||
|
#
|
||||||
|
# jv mhres (2/23-5:18) (698818735) received 135 b 2 secs
|
||||||
|
# root mhres (2/23-5:19) (698818742) sent 2365 b 3 secs, Pk: 38, Rxmt: 0
|
||||||
|
#
|
||||||
|
# HDB:
|
||||||
|
#
|
||||||
|
# uunet!uucp M (12/10-09:04:22) (C,16390,1) [ttyXX] <- 2371 / 5.000 secs, \
|
||||||
|
# 474 bytes/sec
|
||||||
|
#
|
||||||
|
# Taylor:
|
||||||
|
#
|
||||||
|
# jv mhres (1992-02-24 20:49:04.06) sent 16234 bytes in 148.780 seconds \
|
||||||
|
# (109 bytes/sec)
|
||||||
|
# jv mhres (1992-02-24 21:04:05.76) received 449 bytes in 6.550 seconds \
|
||||||
|
# (68 bytes/sec)
|
||||||
|
|
||||||
|
$uucp_type = "gnu";
|
||||||
|
|
||||||
|
%hosts = (); # hosts seen
|
||||||
|
%bytes_in = (); # of bytes received from host
|
||||||
|
%bytes_out = (); # of bytes sent to host
|
||||||
|
%secs_in = (); # of seconds connect for recving
|
||||||
|
%secs_out = (); # of seconds connect for sending
|
||||||
|
%files_in = (); # of input requests
|
||||||
|
%files_out = (); # of output requests
|
||||||
|
|
||||||
|
# read info, break the lines and tally
|
||||||
|
|
||||||
|
if ( $ARGV[0] =~ /^-/ ) {
|
||||||
|
($uucp_type = substr (shift (@ARGV), 1)) =~ tr/A-Z/a-z/;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $uucp_type eq "taylor" || $uucp_type eq "gnu" ) {
|
||||||
|
@ARGV = ("/usr/spool/uucp/Stats") unless $#ARGV >= 0;
|
||||||
|
$pat = "^[^ ]+ ([^ ]+) \\(([-0-9:\\/ .]+)\\) " .
|
||||||
|
"(sent|received) (\\d+) bytes in (\\d+)\\.(\\d+) seconds";
|
||||||
|
$uucp_type = 0;
|
||||||
|
$recv = "received";
|
||||||
|
}
|
||||||
|
elsif ( $uucp_type eq "hdb" || $uucp_type eq "bnu" ) {
|
||||||
|
@ARGV = ("/usr/spool/uucp/.Admin/xferstats") unless $#ARGV >= 0;
|
||||||
|
$pat = "^([^!]+)![^(]+\\(([-0-9:\\/]+)\\).+([<>])-? " .
|
||||||
|
"(\\d+) \\/ (\\d+)\\.(\\d+) secs";
|
||||||
|
$uucp_type = 1;
|
||||||
|
$recv = "<";
|
||||||
|
}
|
||||||
|
elsif ( $uucp_type eq "bsd" || $uucp_type eq "v7" ) {
|
||||||
|
@ARGV = ("/usr/spool/uucp/SYSLOG") unless $#ARGV >= 0;
|
||||||
|
$pat = "^[^ ]+ ([^ ]+) \\(([-0-9:\\/]+)\\) \\([^)]+\\) " .
|
||||||
|
"(sent|received) (\\d+) b (\\d+) secs";
|
||||||
|
$uucp_type = 2;
|
||||||
|
$recv = "received";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die ("Unknown UUCP type: $uucp_type\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$garbage = 0;
|
||||||
|
|
||||||
|
while ( <> ) {
|
||||||
|
unless ( /$pat/o ) {
|
||||||
|
print STDERR "Possible garbage: $_";
|
||||||
|
if ( $garbage++ > 10 ) {
|
||||||
|
die ("Too much garbage; wrong UUCP type?\n");
|
||||||
|
}
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
# gather timestamps
|
||||||
|
$last_date = $2;
|
||||||
|
$first_date = $last_date unless defined $first_date;
|
||||||
|
|
||||||
|
# initialize new hosts
|
||||||
|
unless ( defined $hosts{$1} ) {
|
||||||
|
$hosts{$1} = $files_in{$1} = $files_out{$1} =
|
||||||
|
$bytes_in{$1} = $bytes_out{$1} =
|
||||||
|
$secs_in{$1} = $secs_out{$1} = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Taylor and HDB have milliseconds, BSD has not.
|
||||||
|
$secs = ($uucp_type == 2) ? ($5 + ($5 == 0 ? 0.5 : 0)) : ($5 + $6/1000);
|
||||||
|
|
||||||
|
# tally
|
||||||
|
if ( $3 eq $recv ) { # recv
|
||||||
|
$bytes_in{$1} += $4;
|
||||||
|
$files_in{$1}++;
|
||||||
|
$secs_in{$1} += $secs;
|
||||||
|
}
|
||||||
|
else { # xmit
|
||||||
|
$bytes_out{$1} += $4;
|
||||||
|
$files_out{$1}++;
|
||||||
|
$secs_out{$1} += $secs;
|
||||||
|
}
|
||||||
|
$garbage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@hosts = keys (%hosts);
|
||||||
|
die ("No info found, stopped\n") if $#hosts < 0;
|
||||||
|
|
||||||
|
################ report section ################
|
||||||
|
|
||||||
|
$thishost = &gethostname();
|
||||||
|
$thishost = (defined $thishost) ? "on node $thishost" : "report";
|
||||||
|
|
||||||
|
if ( $uucp_type eq 0 ) { # Taylor UUCP
|
||||||
|
substr ($first_date, 16) = "";
|
||||||
|
substr ($last_date, 16) = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
format std_head =
|
||||||
|
@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||
|
"UUCP traffic $thishost from $first_date to $last_date"
|
||||||
|
|
||||||
|
Remote -----------K-Bytes----------- ----Hours---- --Avg CPS-- --Files--
|
||||||
|
Host Recv Sent Total Recv Sent Recv Sent Recv Sent
|
||||||
|
.
|
||||||
|
format std_out =
|
||||||
|
@<<<<<<< @>>>>>>>> @>>>>>>>> @>>>>>>>> @>>>>> @>>>>> @>>>> @>>>> @>>> @>>>
|
||||||
|
$Zhost, $Zi_bytes, $Zo_bytes, $Zt_bytes, $Zi_hrs, $Zo_hrs, $Zi_acps, $Zo_acps, $Zi_count, $Zo_count
|
||||||
|
.
|
||||||
|
|
||||||
|
$^ = "std_head";
|
||||||
|
$~ = "std_out";
|
||||||
|
|
||||||
|
&print_dashes ();
|
||||||
|
|
||||||
|
reset "T"; # reset totals
|
||||||
|
|
||||||
|
foreach $host (@hosts) {
|
||||||
|
&print_line ($host, $bytes_in{$host}, $bytes_out{$host},
|
||||||
|
$secs_in{$host}, $secs_out{$host},
|
||||||
|
$files_in{$host}, $files_out{$host});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
&print_dashes ();
|
||||||
|
&print_line ("Total", $Ti_bytes, $To_bytes,
|
||||||
|
$Ti_secs, $To_secs, $Ti_count, $To_count);
|
||||||
|
|
||||||
|
################ that's it ################
|
||||||
|
|
||||||
|
sub print_line {
|
||||||
|
reset "Z"; # reset print fields
|
||||||
|
local ($Zhost,
|
||||||
|
$Zi_bytes, $Zo_bytes,
|
||||||
|
$Zi_secs, $Zo_secs,
|
||||||
|
$Zi_count, $Zo_count) = @_;
|
||||||
|
$Ti_bytes += $Zi_bytes;
|
||||||
|
$To_bytes += $Zo_bytes;
|
||||||
|
$Zt_bytes = $Zi_bytes + $Zo_bytes;
|
||||||
|
$Tt_bytes += $Zt_bytes;
|
||||||
|
$Zi_acps = ($Zi_secs > 0) ? sprintf ("%.0f", $Zi_bytes/$Zi_secs) : "0";
|
||||||
|
$Zo_acps = ($Zo_secs > 0) ? sprintf ("%.0f", $Zo_bytes/$Zo_secs) : "0";
|
||||||
|
$Zi_bytes = sprintf ("%.1f", $Zi_bytes/1000);
|
||||||
|
$Zo_bytes = sprintf ("%.1f", $Zo_bytes/1000);
|
||||||
|
$Zt_bytes = sprintf ("%.1f", $Zt_bytes/1000);
|
||||||
|
$Zi_hrs = sprintf ("%.1f", $Zi_secs/3600);
|
||||||
|
$Zo_hrs = sprintf ("%.1f", $Zo_secs/3600);
|
||||||
|
$Ti_secs += $Zi_secs;
|
||||||
|
$To_secs += $Zo_secs;
|
||||||
|
$Ti_count += $Zi_count;
|
||||||
|
$To_count += $Zo_count;
|
||||||
|
write;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_dashes {
|
||||||
|
$Zhost = $Zi_bytes = $Zo_bytes = $Zt_bytes =
|
||||||
|
$Zi_hrs = $Zo_hrs = $Zi_acps = $Zo_acps = $Zi_count = $Zo_count =
|
||||||
|
"------------";
|
||||||
|
write;
|
||||||
|
# easy, isn't it?
|
||||||
|
}
|
||||||
|
|
||||||
|
################ missing ################
|
||||||
|
|
||||||
|
sub gethostname {
|
||||||
|
$ENV{"SHELL"} = "/bin/sh";
|
||||||
|
$try = `uuname -l 2>/dev/null`;
|
||||||
|
chop $try;
|
||||||
|
return $+ if $try =~ /^[-.\w]+$/;
|
||||||
|
return undef;
|
||||||
|
}
|
43
gnu/libexec/uucp/contrib/uutry
Normal file
43
gnu/libexec/uucp/contrib/uutry
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# This script was hacked together by Marc Evans (marc@Synergytics.Com)
|
||||||
|
# I claim no copyright to it and don't really care what people do
|
||||||
|
# with it, hence, it is public domain. I take no responsibility for
|
||||||
|
# for happens if you use this script, providing no warentee. This
|
||||||
|
# section of the comments may be removed if you so desire.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# uutry [-x#] systemname
|
||||||
|
# where '-x#' has the value [0-9], higher values providing more detail
|
||||||
|
|
||||||
|
#
|
||||||
|
# The following variables should be gropped from the configuration
|
||||||
|
# files rather then being hard coded here.
|
||||||
|
#
|
||||||
|
Spool=/usr/spool/uucp
|
||||||
|
Lib=/usr/lib/uucp
|
||||||
|
Status=$Spool/.Status
|
||||||
|
Debug=$Spool/Debug
|
||||||
|
Uucico=$lib/uucico
|
||||||
|
#
|
||||||
|
# Default option values
|
||||||
|
#
|
||||||
|
x="-x5"
|
||||||
|
s=""
|
||||||
|
|
||||||
|
for i in $* ; do
|
||||||
|
case $i in
|
||||||
|
-x*) x="$i" ;;
|
||||||
|
*) s="$i" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ $s != "" ]; then
|
||||||
|
rm -f $Status/$s
|
||||||
|
$Uucico -r1 $x -s$s &
|
||||||
|
>$Debug
|
||||||
|
tail -f $Debug
|
||||||
|
else
|
||||||
|
echo "Usage: uutry systemname"
|
||||||
|
exit 1
|
||||||
|
fi
|
38
gnu/libexec/uucp/contrib/xc-conf.h-dist
Normal file
38
gnu/libexec/uucp/contrib/xc-conf.h-dist
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* *************
|
||||||
|
* * XC-CONF.H *
|
||||||
|
* *************
|
||||||
|
*
|
||||||
|
* Configuration file for xchat 1.1. Edit this file prior to make-ing
|
||||||
|
* xchat.
|
||||||
|
*
|
||||||
|
* History:
|
||||||
|
* Bob Denny - Tue Sep 1 11:42:54 1992
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Edit this to reflect the relative location of xchat sources to
|
||||||
|
* the main Taylor UUCP source directory. As distributed, xchat
|
||||||
|
* is in the ./contrib sub-directory under the main Taylor UUCP
|
||||||
|
* directory. Therefore, Taylor's conf.h is in our parent directory.
|
||||||
|
*/
|
||||||
|
#include "../conf.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following definition establishes the default path to the
|
||||||
|
* scripts used by xchat. You may lleave this blank (""), but
|
||||||
|
* the command line given to xchat (e.g., in the 'sys' file entry)
|
||||||
|
* must specify a full (absolute) path name to the script to be
|
||||||
|
* executed. Normally, this is the same place you put your config
|
||||||
|
* and system files for UUCP.
|
||||||
|
*/
|
||||||
|
#define SCRIPT_DIR "/usr/local/conf/uucp/" /* MUST HAVE TRAILING "/" */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following definition establishes the default path to the
|
||||||
|
* log files that are produced by the 'dbgfile' statement. Normally
|
||||||
|
* this is the same location you configured Taylor UUCP to put its
|
||||||
|
* log files.
|
||||||
|
*/
|
||||||
|
#define LOG_DIR "/usr/spool/uucp/" /* MUST HAVE TRAILING "/" */
|
||||||
|
|
1444
gnu/libexec/uucp/contrib/xchat.c
Normal file
1444
gnu/libexec/uucp/contrib/xchat.c
Normal file
File diff suppressed because it is too large
Load Diff
614
gnu/libexec/uucp/contrib/xchat.man
Normal file
614
gnu/libexec/uucp/contrib/xchat.man
Normal file
@ -0,0 +1,614 @@
|
|||||||
|
.TH xchat 8
|
||||||
|
.SH NAME
|
||||||
|
xchat - Extended chat processor
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BI "xchat " "scriptfile"
|
||||||
|
.RI " [ " parameter... " ] "
|
||||||
|
.PP
|
||||||
|
where
|
||||||
|
.I scriptfile
|
||||||
|
is the name of a file containing an
|
||||||
|
.I xchat
|
||||||
|
script. If
|
||||||
|
.I scriptfile
|
||||||
|
begins with ``/'', then it is assumed to be a full path name for the
|
||||||
|
script file. If not, a configuration-dependent default directory path
|
||||||
|
(usually
|
||||||
|
.B "/usr/local/conf/uucp/"
|
||||||
|
) is prepended to the script file name. Normally, the default path
|
||||||
|
is the same as that for the Taylor UUCP configuration files.
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.I Xchat
|
||||||
|
is a general-purpose dialing and login program designed for use
|
||||||
|
with Taylor UUCP as a ``chat-program'', taking the place (or
|
||||||
|
augmenting) the built-in chat scripting facility. It provides the
|
||||||
|
ability to closely control timeouts, multiple simultaneous ``expect''
|
||||||
|
strings with separate actions, extended terminal control, modem
|
||||||
|
command character pacing, and more.
|
||||||
|
.PP
|
||||||
|
When used in conjunction with Taylor UUCP's
|
||||||
|
configuration features,
|
||||||
|
.I xchat
|
||||||
|
can provide you the ability to manage the most intricate login,
|
||||||
|
dial and hangup needs. The scripts are written in a shell-like (well,
|
||||||
|
sort-of) style with labels, commands, and parameters, easing the task
|
||||||
|
of writing procedures for complex terminal communications situations.
|
||||||
|
.PP
|
||||||
|
Because
|
||||||
|
.I xchat
|
||||||
|
assumes that it is connected to the terminal device via stdin/stdout,
|
||||||
|
you can easily debug scripts by invoking it from the shell and
|
||||||
|
responding to the script from the keyboard. A debug logging facility
|
||||||
|
is included, with the debug output going to a separate user-specified
|
||||||
|
file. This makes it easy to debug connection problems without wading
|
||||||
|
through large
|
||||||
|
.I uucico
|
||||||
|
log and debug files.
|
||||||
|
.PP
|
||||||
|
Formally, a script describes a state machine;
|
||||||
|
.I xchat
|
||||||
|
interprets the script and does what the state machine
|
||||||
|
tells it to. This section will be much easier to understand
|
||||||
|
if you obtain listings of the script files supplied with
|
||||||
|
.I xchat.
|
||||||
|
.SH "SCRIPT FILE FORMAT"
|
||||||
|
Script files are ordinary text files containing comments, labels,
|
||||||
|
and statements. Blank lines are ignored.
|
||||||
|
Comments are denoted by leading ``#''
|
||||||
|
characters. Some statements (those which do not end with an
|
||||||
|
``extended string'' argument; see below) can also have trailing
|
||||||
|
comments.
|
||||||
|
.PP
|
||||||
|
.I Labels
|
||||||
|
begin in column one and are ended by colons (:). A label
|
||||||
|
specifies a state name. All lines between a pair of labels are
|
||||||
|
the statements for a single state.
|
||||||
|
.PP
|
||||||
|
Processing always begins at the head of the script (no leading
|
||||||
|
state name is necessary).
|
||||||
|
.PP
|
||||||
|
.I Statements
|
||||||
|
are divided into two categories, ``action'' and ``expect''.
|
||||||
|
When a state is entered, all of its actions are performed in the
|
||||||
|
order in which they appear in the file.
|
||||||
|
.PP
|
||||||
|
A
|
||||||
|
.I transition
|
||||||
|
to another state may occur for any of three reasons:
|
||||||
|
.IP (1) 5
|
||||||
|
One of the actions may cause a transition to
|
||||||
|
another state, in which case the rest of the
|
||||||
|
current state's actions are skipped.
|
||||||
|
Processing resumes with the first action
|
||||||
|
statement of the new state.
|
||||||
|
.IP (2) 5
|
||||||
|
If none of the actions cause a state
|
||||||
|
transition, and there are no expects in the
|
||||||
|
state, processing ``falls through'' to the next
|
||||||
|
state in the file.
|
||||||
|
.IP (3) 5
|
||||||
|
If none of the actions cause a state
|
||||||
|
transition, but there are expects in the
|
||||||
|
state, the state machine pauses until one of
|
||||||
|
the expects is ``satisfied''. It then transitions
|
||||||
|
to the state named in the expect
|
||||||
|
statement.
|
||||||
|
.PP
|
||||||
|
Finally, there are two action statements which, when executed,
|
||||||
|
cause the script to exit.
|
||||||
|
.SH "SCRIPT FILE STATEMENTS"
|
||||||
|
This section describes all of the statements that may appear in script
|
||||||
|
files, except for a few special action statements. Those are described
|
||||||
|
in a later section, ``Overriding Defaults''.
|
||||||
|
.PP
|
||||||
|
Some statements accept one or two arguments, referred to in the
|
||||||
|
following descriptions as
|
||||||
|
.IR int ", " ns ", " str ", or "
|
||||||
|
.IR xstr ", to"
|
||||||
|
indicate whether the argument is an integer, a new state name, a
|
||||||
|
string, or an ``extended string'' (described in a later section).
|
||||||
|
.PP
|
||||||
|
For all statements that accept two arguments, the first is the
|
||||||
|
name of a new state, and the second specifies a condition or
|
||||||
|
reason for changing to the new state.
|
||||||
|
.SS "Termination And Informational Statements"
|
||||||
|
These statements are used to place entries into the Taylor UUCP
|
||||||
|
.I Log
|
||||||
|
file, and to cause
|
||||||
|
.I xchat
|
||||||
|
to exit with successful or failure status. It is also possible to open a
|
||||||
|
separate
|
||||||
|
.I debug
|
||||||
|
log file and control the level of tracing and error reporting that will go
|
||||||
|
into that log file. This is very useful in debugging
|
||||||
|
.I xchat
|
||||||
|
scripts.
|
||||||
|
.br
|
||||||
|
.ta 1.0i 1.5i 2.0i
|
||||||
|
.TP 2.0i
|
||||||
|
.B failed
|
||||||
|
Exit script with ``failed'' status. This causes
|
||||||
|
.I xchat
|
||||||
|
to exit with status 0.
|
||||||
|
.TP 2.0i
|
||||||
|
.B success
|
||||||
|
Exit script with ``success'' status. This causes
|
||||||
|
.I xchat
|
||||||
|
to exit with status 1.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "log " xstr
|
||||||
|
Send informational message
|
||||||
|
.I xstr
|
||||||
|
to standard error. When used with Taylor UUCP, this is the
|
||||||
|
.I Log
|
||||||
|
file for the
|
||||||
|
.I uucico
|
||||||
|
program.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "logerr " xstr
|
||||||
|
Send message
|
||||||
|
.I xstr
|
||||||
|
to standard error, with ``ERROR:'' indicator. When used
|
||||||
|
with Taylor UUCP, this is the
|
||||||
|
.I Log
|
||||||
|
file for the
|
||||||
|
.I uucico
|
||||||
|
program.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "dbgfile " xstr
|
||||||
|
Open script debugging file
|
||||||
|
.I xstr.
|
||||||
|
If
|
||||||
|
.I xstr
|
||||||
|
begins with ``/'', it is assumed to be an absolute path name for the
|
||||||
|
debugging file. If not, then a configuration-dependent default directory
|
||||||
|
path (usually
|
||||||
|
.B "/usr/spool/uucp"
|
||||||
|
) is prepended to
|
||||||
|
.I xstr.
|
||||||
|
Normally the default path is that of the directory where Taylor UUCP
|
||||||
|
puts its log files.
|
||||||
|
The debugging file is used to capture a detailed log of the data sent
|
||||||
|
and received, errors encountered, and a trace of script execution.
|
||||||
|
The various types of logging are controlled by the
|
||||||
|
.I "debug mask,"
|
||||||
|
described next.
|
||||||
|
.B Note:
|
||||||
|
A new log file is created each time
|
||||||
|
.I xchat
|
||||||
|
runs. Use the
|
||||||
|
.B log
|
||||||
|
and
|
||||||
|
.B loge
|
||||||
|
commands to log
|
||||||
|
continuous information onto standard out, which is connected
|
||||||
|
to the Taylor UUCP
|
||||||
|
.I Log
|
||||||
|
file when
|
||||||
|
.I xchat
|
||||||
|
is run by the Taylor
|
||||||
|
.I uucico.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "dbgset " int
|
||||||
|
Set the bits specified in
|
||||||
|
.I int
|
||||||
|
in the debugging mask. The value in
|
||||||
|
.I int
|
||||||
|
is ``or''ed into the mask. Set bit 0 (value \= 1) for error messages,
|
||||||
|
bit 1 (value \= 2) for dial, login and init errors, bit 2 (value \= 4)
|
||||||
|
for dial, login and init trace with character I/O, and bit 3 (value \= 8)
|
||||||
|
for script processing internals. Normally, you will just turn it all on
|
||||||
|
with a value of 15.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "dbgclr " int
|
||||||
|
Clear the bits specified in
|
||||||
|
.I int
|
||||||
|
from the debugging mask.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "debug " xstr
|
||||||
|
Write
|
||||||
|
.I
|
||||||
|
xstr
|
||||||
|
into the debug log. The entry will be enclosed in angle brackets.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "debuge " xstr
|
||||||
|
Write
|
||||||
|
.I xstr
|
||||||
|
into the debug log with ``ERROR: '' prepended. The entry will be enclosed
|
||||||
|
in angle brackets.
|
||||||
|
.SS "Sending Data"
|
||||||
|
These statements are used to transmit data to standard out (the tty or TCP
|
||||||
|
port when used with Taylor UUCP).
|
||||||
|
.I
|
||||||
|
No implied carriage returns are sent.
|
||||||
|
You must include a \\r if you want a carriage return in the string
|
||||||
|
sent by the
|
||||||
|
.B send
|
||||||
|
command. If you want a return sent after
|
||||||
|
.B dial
|
||||||
|
or
|
||||||
|
.B sendstr,
|
||||||
|
you must send it with a separate
|
||||||
|
.B send
|
||||||
|
command.
|
||||||
|
.TP 2.0i
|
||||||
|
.B dial
|
||||||
|
Send the string previously set by the
|
||||||
|
.B telno
|
||||||
|
command to the serial port.
|
||||||
|
.B W
|
||||||
|
and
|
||||||
|
.B P
|
||||||
|
characters in the phone number are
|
||||||
|
converted as described under
|
||||||
|
.B
|
||||||
|
Dial Strings,
|
||||||
|
below. This statement also sets a default
|
||||||
|
timeout value, as described under the
|
||||||
|
.B timeout
|
||||||
|
statement.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "send " xstr
|
||||||
|
Send the string
|
||||||
|
.I xstr
|
||||||
|
to the serial port.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "sendstr " int
|
||||||
|
The argument of this statement is a digit from 0
|
||||||
|
through 7. Send the corresponding string
|
||||||
|
parameter as passed to
|
||||||
|
.I xchat
|
||||||
|
following the script file name. The parameter is interpreted
|
||||||
|
as an extended string.
|
||||||
|
.SS "Special Terminal Control Statements"
|
||||||
|
These statements are used to cause the terminal port to perform some special action, or to change the mode of the port.
|
||||||
|
.I
|
||||||
|
The modes of the port are restored to their original settings
|
||||||
|
.I
|
||||||
|
by xchat before it exits.
|
||||||
|
.TP 2.0i
|
||||||
|
.B flush
|
||||||
|
Flush the terminal port's input buffer.
|
||||||
|
.TP 2.0i
|
||||||
|
.B break
|
||||||
|
Send a break signal.
|
||||||
|
.TP 2.0i
|
||||||
|
.B hangup
|
||||||
|
Momentarily drop Data Terminal Ready (DTR) on the
|
||||||
|
serial port, causing the modem to hang up. (Not
|
||||||
|
usually needed, since
|
||||||
|
.I uucico
|
||||||
|
does this at the end of each call.)
|
||||||
|
.TP 2.0i
|
||||||
|
.B 7bit
|
||||||
|
Change the port to strip incoming characters to 7 bits.
|
||||||
|
.I
|
||||||
|
This is the default mode.
|
||||||
|
This mode
|
||||||
|
is implied when the port has parity enabled, since parity characters
|
||||||
|
are 7-bits wide.
|
||||||
|
.TP 2.0i
|
||||||
|
.B 8bit
|
||||||
|
Change the port to allow incoming 8-bit characters to be passed
|
||||||
|
to the script processor. This mode has no effect if parity is
|
||||||
|
enabled, since parity characters are 7-bits wide.
|
||||||
|
.TP 2.0i
|
||||||
|
.B nopar
|
||||||
|
Change the port to 8-bits, no parity.
|
||||||
|
.I
|
||||||
|
This is the default mode.
|
||||||
|
.TP 2.0i
|
||||||
|
.B evenpar
|
||||||
|
Change the port to 7-bits, even parity.
|
||||||
|
.I
|
||||||
|
Incoming characters with parity errors are discarded.
|
||||||
|
.TP 2.0i
|
||||||
|
.B oddpar
|
||||||
|
Change the port to 7-bits, odd parity.
|
||||||
|
.I
|
||||||
|
Incoming characters with parity errors are discarded.
|
||||||
|
.SS "Counting, Branching, Timing and Testing Statements"
|
||||||
|
These statements are used to control the flow of the
|
||||||
|
.I xchat
|
||||||
|
script itself, including branching, delays, and counter manipulation.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "sleep " int
|
||||||
|
Delay for
|
||||||
|
.I int
|
||||||
|
milliseconds.
|
||||||
|
.TP 2.0i
|
||||||
|
.B zero
|
||||||
|
Clear the counter.
|
||||||
|
.TP 2.0i
|
||||||
|
.B count
|
||||||
|
Add one to the counter.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifgtr " "ns int"
|
||||||
|
Go to state
|
||||||
|
.I ns
|
||||||
|
if counter greater than
|
||||||
|
.I int.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "goto " ns
|
||||||
|
Go to state
|
||||||
|
.I ns
|
||||||
|
unconditionally.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifstr " "ns int"
|
||||||
|
Go to state
|
||||||
|
.I ns
|
||||||
|
if string parameter
|
||||||
|
.I int
|
||||||
|
is nonempty.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifnstr " "ns int"
|
||||||
|
Go to state
|
||||||
|
.I ns
|
||||||
|
if string parameter
|
||||||
|
.I int
|
||||||
|
is empty.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifblind " ns
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if the port is ``blind'' without carrier (CD) asserted.
|
||||||
|
.I
|
||||||
|
This is not yet implemented, the test always fails.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifblgtr " "ns int"
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if the port is ``blind'' without carrier (CD) asserted, and counter
|
||||||
|
is greater then
|
||||||
|
.I int.
|
||||||
|
.I
|
||||||
|
This is not yet implemented, the test always fails.
|
||||||
|
.SS "Expect Statements"
|
||||||
|
Expect statements are usually the last statements that appear in a
|
||||||
|
given state, though in fact they can appear anywhere within the
|
||||||
|
state. Even if they appear at the beginning, the script processor
|
||||||
|
always does all of the action statements first. As a practical
|
||||||
|
matter, the order of these statements is not significant; they are
|
||||||
|
all interpreted ``in parallel''.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "expect " "ns xstr"
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if the string specified by
|
||||||
|
.I xstr
|
||||||
|
is received from standard input (usually the serial port).
|
||||||
|
Case is significant, but high-order bits are not
|
||||||
|
checked.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifcarr " ns
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if Carrier Detect (CD) is true.
|
||||||
|
.I
|
||||||
|
Not currently implemented. Always changes state.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ifhang " ns
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if a data set hangup occurs (SIGHUP signal received).
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "timeout " "ns int"
|
||||||
|
Change to state
|
||||||
|
.I ns
|
||||||
|
if the time (in milliseconds)
|
||||||
|
given by
|
||||||
|
.I int
|
||||||
|
has elapsed without satisfying any
|
||||||
|
expects. If the time specified is 0, a default
|
||||||
|
timeout value (calculated from the length and
|
||||||
|
other characteristics of the most recent dial
|
||||||
|
string) is used.
|
||||||
|
.SH "SCRIPT PROCESSING DETAILS"
|
||||||
|
.SS "Extended Strings"
|
||||||
|
In the statements that accept string arguments, the strings are
|
||||||
|
interpreted as
|
||||||
|
.I
|
||||||
|
extended strings.
|
||||||
|
Extended strings begin with
|
||||||
|
the first nonblank character and continue, including all imbedded
|
||||||
|
and trailing blanks and other whitespace, until (but not
|
||||||
|
including) the end of the line in the script file. (There is no
|
||||||
|
provision for line continuation.) No trailing spaces should be
|
||||||
|
present between the last ``desired'' character of the string and the
|
||||||
|
end of the line, as they will be included in the stored string and
|
||||||
|
sent or expected, just as they appear in the script file. And,
|
||||||
|
obviously, no trailing comments are permitted! They will just be
|
||||||
|
stored as part of the string.
|
||||||
|
.PP
|
||||||
|
Within an extended string, the following ``escape sequences'' will
|
||||||
|
be converted as indicated before being sent or expected:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +0.5i
|
||||||
|
\fB\\d\fR EOT character (control-D)
|
||||||
|
\fB\\N\fR null character
|
||||||
|
\fB\\n\fR line feed
|
||||||
|
\fB\\r\fR carriage return
|
||||||
|
\fB\\s\fR space
|
||||||
|
\fB\\t\fR tab
|
||||||
|
\fB\\\-\fR hyphen
|
||||||
|
\fB\\\\\fR backslash
|
||||||
|
\fB\\ooo\fR character with value ooo (in octal)
|
||||||
|
.in -0.5i
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
Since extended strings in scripts can include embedded spaces,
|
||||||
|
tabs, etc., these escape sequences are only required in strings
|
||||||
|
appearing in systems entries, though they may be used in script
|
||||||
|
files to improve readability.
|
||||||
|
.PP
|
||||||
|
The octal-character specification (\\ooo) may have from one to
|
||||||
|
three octal digits; it is terminated either after the third digit
|
||||||
|
or when a non-octal character is encountered. But if you want to
|
||||||
|
specify one of these followed by something that happens to be a
|
||||||
|
valid octal character (for example, a control-A followed by a 7)
|
||||||
|
make sure to include all three digits after the \\ . So \\0017
|
||||||
|
would become a control-A followed by the Ascii character ``7'', but
|
||||||
|
\\17 or \\017 would become a control-Y (decimal value 25). \\1S
|
||||||
|
would convert to a control-A followed by an ``S''.
|
||||||
|
.PP
|
||||||
|
Extended strings are stored without a trailing carriage return
|
||||||
|
unless one is explicitly present in the string (via \\r).
|
||||||
|
.SS "String Parameters"
|
||||||
|
The
|
||||||
|
.B sendstr
|
||||||
|
statement sends (after conversion from extended string
|
||||||
|
format) one of the parameters given on the
|
||||||
|
.I xchat
|
||||||
|
command line following the script file name.
|
||||||
|
The parameter is selected by the integer
|
||||||
|
argument of the statement.
|
||||||
|
.PP
|
||||||
|
This allows ``generic'' script files to serve
|
||||||
|
for many different systems; the string parameters
|
||||||
|
provide the phone number, username, password, etc. Character
|
||||||
|
substitutions described under ``extended strings'' above are
|
||||||
|
performed on these strings.
|
||||||
|
.PP
|
||||||
|
The ifstr and ifnstr statements allow further generality in script
|
||||||
|
files, by testing whether a particular parameter is present in the
|
||||||
|
systems entry. For example, a single script can be
|
||||||
|
used both for those systems that require a password and
|
||||||
|
those that do not. The password is specified as the last argument
|
||||||
|
in the
|
||||||
|
.xchat
|
||||||
|
command; the script can test for this
|
||||||
|
parameter's existence and skip the password sequence if
|
||||||
|
the parameter is empty.
|
||||||
|
.SS "``Wait'' And ``Pause'' Characters In Dial Strings"
|
||||||
|
An additional conversion is performed on dial strings. Dial strings
|
||||||
|
are interpreted as extended strings. Then the characters
|
||||||
|
.B W
|
||||||
|
and
|
||||||
|
.B P
|
||||||
|
within a dial string are interpreted as ``wait for dial
|
||||||
|
tone'' and ``pause'', and may be converted to other characters. By
|
||||||
|
default,
|
||||||
|
.B W
|
||||||
|
is left alone, and
|
||||||
|
.B P
|
||||||
|
is converted to a comma (,);
|
||||||
|
these are appropriate for Hayes-type modems. The script may
|
||||||
|
specify other substitutions (see below).
|
||||||
|
.PP
|
||||||
|
.B NOTE:
|
||||||
|
The Taylor UUCP documentation states that the ``wait'' and ``pause''
|
||||||
|
characters are ``='' and ``-'', respectively. These are actual characters
|
||||||
|
understood by some modems. When using
|
||||||
|
.I xchat
|
||||||
|
you should put
|
||||||
|
.B W
|
||||||
|
and
|
||||||
|
.B P
|
||||||
|
in the dial strings you specify in the Taylor configuration files.
|
||||||
|
This way, the
|
||||||
|
.I xchat
|
||||||
|
processor can make the substitution appropriate for the particular
|
||||||
|
modem in use. Make a separate
|
||||||
|
.I xchat
|
||||||
|
script for each modem type, e.g.,
|
||||||
|
.I "dial.hayes"
|
||||||
|
and specify the translation there. This way, the phone number strings
|
||||||
|
in the Taylor configuration files can be used with a variety of modems.
|
||||||
|
.SS "Default Timeouts For Dial Strings"
|
||||||
|
When a
|
||||||
|
.B dial
|
||||||
|
statement is executed, a default timeout value is set.
|
||||||
|
This is the timeout value used by a subsequent timeout statement
|
||||||
|
if the statement specifies a timeout value of 0.
|
||||||
|
.PP
|
||||||
|
The default timeout is given by:
|
||||||
|
.br
|
||||||
|
.nf
|
||||||
|
.in +2
|
||||||
|
\fIctime\fR + (\fIndigits\fR * \fIdgttime\fR) + (\fInwchar\fR * \fIwtime\fR) + (\fInpchar\fR * \fI ptime\fR)
|
||||||
|
.in -2
|
||||||
|
.fi
|
||||||
|
.PP
|
||||||
|
where
|
||||||
|
.I
|
||||||
|
ndigits, nwchar,
|
||||||
|
and
|
||||||
|
.I npchar
|
||||||
|
are the number of digits, wait characters, and pause characters in
|
||||||
|
the dial string, and
|
||||||
|
.I ctime, dgttime, wtime,
|
||||||
|
and
|
||||||
|
.I ptime
|
||||||
|
are 45 seconds, 0.1 seconds, 10 seconds, and 2 seconds,
|
||||||
|
respectively.
|
||||||
|
All of these times may be changed as specified below under
|
||||||
|
``Overriding Defaults.''
|
||||||
|
.SS "Trailing Carriage Returns Not Assumed"
|
||||||
|
In the
|
||||||
|
.B dial
|
||||||
|
and
|
||||||
|
.B sendstr
|
||||||
|
statements, the dial string or
|
||||||
|
parameter is sent with no trailing carriage return;
|
||||||
|
if a carriage return must be sent after one of these, a separate
|
||||||
|
send statement must provide it.
|
||||||
|
.SH "OVERRIDING DEFAULTS"
|
||||||
|
The script processor sets several default values. The following
|
||||||
|
statements, which override these defaults, may be useful in
|
||||||
|
certain circumstances.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "chrdly " int
|
||||||
|
Since many modems cannot accept dialing commands
|
||||||
|
at full ``computer speed'', the script processor
|
||||||
|
sends all strings with a brief inter-character
|
||||||
|
delay. This statement specifies the delay time,
|
||||||
|
in milliseconds. The default is 100 (0.1 second).
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "pchar " str
|
||||||
|
Specifies the character to which
|
||||||
|
.BR P s
|
||||||
|
in the
|
||||||
|
dial string should be converted. Default is
|
||||||
|
``,'', for use with Hayes-type modems.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ptime " int
|
||||||
|
Specifies the time, in milliseconds, to allow in
|
||||||
|
the default timeout for each pause character in
|
||||||
|
the dial string. Default is 2000 (2 seconds).
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "wchar " str
|
||||||
|
Specifies the character to which
|
||||||
|
.BR W s
|
||||||
|
in the
|
||||||
|
dial string should be converted. Default is
|
||||||
|
``W'', for Hayes modems.
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "wtime " int
|
||||||
|
Specifies the time, in milliseconds, to allow in
|
||||||
|
the default timeout for each wait-for-dialtone
|
||||||
|
character in the dial string. Default is 10000
|
||||||
|
(10 seconds).
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "dgttime " int
|
||||||
|
Specifies the time, in milliseconds, to allow in
|
||||||
|
the default timeout for each digit character in
|
||||||
|
the dial string. Default is 100 (0.1 second).
|
||||||
|
.TP 2.0i
|
||||||
|
.BI "ctime " int
|
||||||
|
Specifies the time, in milliseconds, to allow in
|
||||||
|
the default timeout for carrier to appear after
|
||||||
|
the dial string is sent. Default is 45000 (45
|
||||||
|
seconds).
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
uucico(8) for Taylor UUCP, and documentation for Taylor UUCP.
|
||||||
|
.SH AUTHOR
|
||||||
|
Robert B. Denny (denny@alisa.com)
|
||||||
|
.SH HISTORY
|
||||||
|
This program is an adaptation of the dial/login script processing
|
||||||
|
code that is a part of DECUS UUCP for VAX/VMS, written by Jamie
|
||||||
|
Hanrahan, et. al.
|
||||||
|
.SH BUGS
|
||||||
|
This version (1.1) does not support BSD terminal facilities. Anyone
|
||||||
|
volunteer to add this?
|
||||||
|
|
16
gnu/libexec/uucp/cu/Makefile
Normal file
16
gnu/libexec/uucp/cu/Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Makefile for cu
|
||||||
|
# $Id: Makefile,v 1.2 1993/08/05 16:14:45 jtc Exp $
|
||||||
|
|
||||||
|
BINDIR= $(bindir)
|
||||||
|
BINOWN= $(owner)
|
||||||
|
BINMODE= 4555
|
||||||
|
|
||||||
|
PROG= cu
|
||||||
|
SRCS= cu.c prot.c log.c chat.c conn.c tcp.c tli.c copy.c
|
||||||
|
LDADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP)
|
||||||
|
DPADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP)
|
||||||
|
CFLAGS+= -I$(.CURDIR)/../common_sources\
|
||||||
|
-DVERSION=\"$(VERSION)\"
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
||||||
|
.PATH: $(.CURDIR)/../common_sources
|
286
gnu/libexec/uucp/cu/cu.1
Normal file
286
gnu/libexec/uucp/cu/cu.1
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
''' $Id: cu.1,v 1.1 1993/08/04 19:31:53 jtc Exp $
|
||||||
|
.TH cu 1 "Taylor UUCP 1.04"
|
||||||
|
.SH NAME
|
||||||
|
cu \- Call up another system
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B cu
|
||||||
|
[ options ] [ system | phone | "dir" ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
The
|
||||||
|
.I cu
|
||||||
|
command is used to call up another system and act as a dial in
|
||||||
|
terminal. It can also do simple file transfers with no error
|
||||||
|
checking.
|
||||||
|
|
||||||
|
.I cu
|
||||||
|
takes a single argument, besides the options. If the argument is the
|
||||||
|
string "dir" cu will make a direct connection to the port. This may
|
||||||
|
only be used by users with write access to the port, as it permits
|
||||||
|
reprogramming the modem.
|
||||||
|
|
||||||
|
Otherwise, if the argument begins with a digit, it is taken to be a
|
||||||
|
phone number to call. Otherwise, it is taken to be the name of a
|
||||||
|
system to call. The
|
||||||
|
.B \-z
|
||||||
|
option may be used to name a system beginning with a digit, and the
|
||||||
|
.B \-c
|
||||||
|
option may be used to name a phone number that does not begin with a
|
||||||
|
digit.
|
||||||
|
|
||||||
|
.I cu
|
||||||
|
locates a port to use in the UUCP configuration files. If a simple
|
||||||
|
system name is given, it will select a port appropriate for that
|
||||||
|
system. The
|
||||||
|
.B \-p, \-l
|
||||||
|
and
|
||||||
|
.B \-s
|
||||||
|
options may be used to control the port selection.
|
||||||
|
|
||||||
|
When a connection is made to the remote system,
|
||||||
|
.I cu
|
||||||
|
forks into two processes. One reads from the port and writes to the
|
||||||
|
terminal, while the other reads from the terminal and writes to the
|
||||||
|
port.
|
||||||
|
|
||||||
|
.I cu
|
||||||
|
provides several commands that may be used during the conversation.
|
||||||
|
The commands all begin with an escape character, initially
|
||||||
|
.B ~
|
||||||
|
(tilde). The escape character is only recognized at the beginning of
|
||||||
|
a line. To send an escape character to the remote system at the start
|
||||||
|
of a line, it must be entered twice. All commands are either a single
|
||||||
|
character or a word beginning with
|
||||||
|
.B %
|
||||||
|
(percent sign).
|
||||||
|
|
||||||
|
.I cu
|
||||||
|
recognizes the following commands:
|
||||||
|
|
||||||
|
.TP 5
|
||||||
|
.B ~.
|
||||||
|
Terminate the conversation.
|
||||||
|
.TP 5
|
||||||
|
.B ~! command
|
||||||
|
Run command in a shell. If command is empty, starts up a shell.
|
||||||
|
.TP 5
|
||||||
|
.B ~$ command
|
||||||
|
Run command, sending the standard output to the remote system.
|
||||||
|
.TP 5
|
||||||
|
.B ~| command
|
||||||
|
Run command, taking the standard input from the remote system.
|
||||||
|
.TP 5
|
||||||
|
.B ~+ command
|
||||||
|
Run command, taking the standard input from the remote system and
|
||||||
|
sending the standard output to the remote system.
|
||||||
|
.TP 5
|
||||||
|
.B ~#, ~%break
|
||||||
|
Send a break signal, if possible.
|
||||||
|
.TP 5
|
||||||
|
.B ~c directory, ~%cd directory
|
||||||
|
Change the local directory.
|
||||||
|
.TP 5
|
||||||
|
.B ~> file
|
||||||
|
Send a file to the remote system. This just dumps the file over the
|
||||||
|
communication line. It is assumed that the remote system is expecting
|
||||||
|
it.
|
||||||
|
.TP 5
|
||||||
|
.B ~<
|
||||||
|
Receive a file from the remote system. This prompts for the local
|
||||||
|
file name and for the remote command to execute to begin the file
|
||||||
|
transfer. It continues accepting data until the contents of the
|
||||||
|
.B eofread
|
||||||
|
variable are seen.
|
||||||
|
.TP 5
|
||||||
|
.B ~p from to, ~%put from to
|
||||||
|
Send a file to a remote Unix system. This runs the appropriate
|
||||||
|
commands on the remote system.
|
||||||
|
.TP 5
|
||||||
|
.B ~t from to, ~%take from to
|
||||||
|
Retrieve a file from a remote Unix system. This runs the appropriate
|
||||||
|
commands on the remote system.
|
||||||
|
.TP 5
|
||||||
|
.B ~s variable value
|
||||||
|
Set a
|
||||||
|
.I cu
|
||||||
|
variable to the given value. If value is not given, the variable is
|
||||||
|
set to
|
||||||
|
.B true.
|
||||||
|
.TP 5
|
||||||
|
.B ~! variable
|
||||||
|
Set a
|
||||||
|
.I cu
|
||||||
|
variable to
|
||||||
|
.B false.
|
||||||
|
.TP 5
|
||||||
|
.B ~z
|
||||||
|
Suspend the cu session. This is only supported on some systems. On
|
||||||
|
systems for which ^Z may be used to suspend a job,
|
||||||
|
.B ~^Z
|
||||||
|
will also suspend the session.
|
||||||
|
.TP 5
|
||||||
|
.B ~%nostop
|
||||||
|
Turn off XON/XOFF handling.
|
||||||
|
.TP 5
|
||||||
|
.B ~%stop
|
||||||
|
Turn on XON/XOFF handling.
|
||||||
|
.TP 5
|
||||||
|
.B ~v
|
||||||
|
List all the variables and their values.
|
||||||
|
.TP 5
|
||||||
|
.B ~?
|
||||||
|
List all commands.
|
||||||
|
|
||||||
|
.I cu
|
||||||
|
also supports several variables. They may be listed with the
|
||||||
|
.B ~v
|
||||||
|
command, and set with the
|
||||||
|
.B ~s
|
||||||
|
or
|
||||||
|
.B ~!
|
||||||
|
commands.
|
||||||
|
|
||||||
|
.TP 5
|
||||||
|
.B escape
|
||||||
|
The escape character. Initially
|
||||||
|
.B ~
|
||||||
|
(tilde).
|
||||||
|
.TP 5
|
||||||
|
.B delay
|
||||||
|
If this variable is true,
|
||||||
|
.I cu
|
||||||
|
will delay for a second after recognizing the escape character before
|
||||||
|
printing the name of the local system. The default is true.
|
||||||
|
.TP 5
|
||||||
|
.B eol
|
||||||
|
The list of characters which are considered to finish a line. The
|
||||||
|
escape character is only recognized after one of these is seen. The
|
||||||
|
default is carriage return, ^U, ^C, ^O, ^D, ^S, ^Q, ^R.
|
||||||
|
.TP 5
|
||||||
|
.B binary
|
||||||
|
Whether to transfer binary data when sending a file. If this is
|
||||||
|
false, then newlines in the file being sent are converted to carriage
|
||||||
|
returns. The default is false.
|
||||||
|
.TP 5
|
||||||
|
.B binary-prefix
|
||||||
|
A string used before sending a binary character in a file transfer, if
|
||||||
|
the
|
||||||
|
.B binary
|
||||||
|
variable is true. The default is ^Z.
|
||||||
|
.TP 5
|
||||||
|
.B echo-check
|
||||||
|
Whether to check file transfers by examining what the remote system
|
||||||
|
echoes back. This probably doesn't work very well. The default is
|
||||||
|
false.
|
||||||
|
.TP 5
|
||||||
|
.B echonl
|
||||||
|
The character to look for after sending each line in a file. The
|
||||||
|
default is carriage return.
|
||||||
|
.TP 5
|
||||||
|
.B timeout
|
||||||
|
The timeout to use, in seconds, when looking for a character, either
|
||||||
|
when doing echo checking or when looking for the
|
||||||
|
.B echonl
|
||||||
|
character. The default is 30.
|
||||||
|
.TP 5
|
||||||
|
.B kill
|
||||||
|
The character to use delete a line if the echo check fails. The
|
||||||
|
default is ^U.
|
||||||
|
.TP 5
|
||||||
|
.B resend
|
||||||
|
The number of times to resend a line if the echo check continues to
|
||||||
|
fail. The default is 10.
|
||||||
|
.TP 5
|
||||||
|
.B eofwrite
|
||||||
|
The string to write after sending a file with the
|
||||||
|
.B ~>
|
||||||
|
command. The default is ^D.
|
||||||
|
.TP 5
|
||||||
|
.B eofread
|
||||||
|
The string to look for when receiving a file with the
|
||||||
|
.B ~<
|
||||||
|
command. The default is $, which is intended to be a typical shell
|
||||||
|
prompt.
|
||||||
|
.TP 5
|
||||||
|
.B verbose
|
||||||
|
Whether to print accumulated information during a file transfer. The
|
||||||
|
default is true.
|
||||||
|
.SH OPTIONS
|
||||||
|
The following options may be given to
|
||||||
|
.I cu.
|
||||||
|
.TP 5
|
||||||
|
.B \-e
|
||||||
|
Use even parity.
|
||||||
|
.TP 5
|
||||||
|
.B \-o
|
||||||
|
Use odd parity. If both
|
||||||
|
.B \-e
|
||||||
|
and
|
||||||
|
.B \-o
|
||||||
|
are used, no parity is used. Otherwise the default parity of the line
|
||||||
|
is used.
|
||||||
|
.TP 5
|
||||||
|
.B \-h
|
||||||
|
Echo characters locally (half-duplex mode).
|
||||||
|
.TP 5
|
||||||
|
.B \-z system
|
||||||
|
The system to call.
|
||||||
|
.TP 5
|
||||||
|
.B \-c phone-number
|
||||||
|
The phone number to call.
|
||||||
|
.TP 5
|
||||||
|
.B \-p port
|
||||||
|
Name the port to use.
|
||||||
|
.TP 5
|
||||||
|
.B \-a port
|
||||||
|
Equivalent to
|
||||||
|
.B \-p port.
|
||||||
|
.TP 5
|
||||||
|
.B \-l line
|
||||||
|
Name the line to use by giving a device name. This may be used to
|
||||||
|
dial out on ports that are not listed in the UUCP configuration files.
|
||||||
|
Write access to the device is required.
|
||||||
|
.TP 5
|
||||||
|
.B \-s speed
|
||||||
|
The speed (baud rate) to use.
|
||||||
|
.TP 5
|
||||||
|
.B \-#
|
||||||
|
Where # is a number, equivalent to
|
||||||
|
.B \-s #.
|
||||||
|
.TP 5
|
||||||
|
.B \-n
|
||||||
|
Prompt for the phone number to use.
|
||||||
|
.TP 5
|
||||||
|
.B \-d
|
||||||
|
Enter debugging mode. Equivalent to
|
||||||
|
.B \-x all.
|
||||||
|
.TP 5
|
||||||
|
.B \-x type
|
||||||
|
Turn on particular debugging types. The following types are
|
||||||
|
recognized: abnormal, chat, handshake, uucp-proto, proto, port,
|
||||||
|
config, spooldir, execute, incoming, outgoing. Only abnormal, chat,
|
||||||
|
handshake, port, config, incoming and outgoing are meaningful for
|
||||||
|
.I cu.
|
||||||
|
|
||||||
|
Multiple types may be given, separated by commas, and the
|
||||||
|
.B \-x
|
||||||
|
option may appear multiple times. A number may also be given, which
|
||||||
|
will turn on that many types from the foregoing list; for example,
|
||||||
|
.B \-x 2
|
||||||
|
is equivalent to
|
||||||
|
.B \-x abnormal,chat.
|
||||||
|
.B \-x all
|
||||||
|
may be used to turn on all debugging options.
|
||||||
|
.TP 5
|
||||||
|
.B \-I file
|
||||||
|
Set configuration file to use. This option may not be available,
|
||||||
|
depending upon how
|
||||||
|
.I cu
|
||||||
|
was compiled.
|
||||||
|
.SH BUGS
|
||||||
|
This program does not work very well.
|
||||||
|
.SH FILES
|
||||||
|
The file name may be changed at compilation time, so this is only an
|
||||||
|
approximation.
|
||||||
|
|
||||||
|
.br
|
||||||
|
/usr/lib/uucp/config - Configuration file.
|
2068
gnu/libexec/uucp/cu/cu.c
Normal file
2068
gnu/libexec/uucp/cu/cu.c
Normal file
File diff suppressed because it is too large
Load Diff
76
gnu/libexec/uucp/libunix/MANIFEST
Normal file
76
gnu/libexec/uucp/libunix/MANIFEST
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
Makefile.in
|
||||||
|
MANIFEST
|
||||||
|
access.c
|
||||||
|
addbas.c
|
||||||
|
app3.c
|
||||||
|
app4.c
|
||||||
|
basnam.c
|
||||||
|
bytfre.c
|
||||||
|
chmod.c
|
||||||
|
cohtty.c
|
||||||
|
cwd.c
|
||||||
|
cusub.c
|
||||||
|
detach.c
|
||||||
|
dirent.c
|
||||||
|
dup2.c
|
||||||
|
efopen.c
|
||||||
|
epopen.c
|
||||||
|
exists.c
|
||||||
|
filnam.c
|
||||||
|
fsusg.c
|
||||||
|
fsusg.h
|
||||||
|
ftw.c
|
||||||
|
getcwd.c
|
||||||
|
indir.c
|
||||||
|
init.c
|
||||||
|
isdir.c
|
||||||
|
isfork.c
|
||||||
|
iswait.c
|
||||||
|
jobid.c
|
||||||
|
lcksys.c
|
||||||
|
link.c
|
||||||
|
locfil.c
|
||||||
|
lock.c
|
||||||
|
loctim.c
|
||||||
|
mail.c
|
||||||
|
mkdir.c
|
||||||
|
mkdirs.c
|
||||||
|
mode.c
|
||||||
|
move.c
|
||||||
|
opensr.c
|
||||||
|
pause.c
|
||||||
|
picksb.c
|
||||||
|
portnm.c
|
||||||
|
proctm.c
|
||||||
|
recep.c
|
||||||
|
remove.c
|
||||||
|
rename.c
|
||||||
|
rmdir.c
|
||||||
|
run.c
|
||||||
|
seq.c
|
||||||
|
serial.c
|
||||||
|
signal.c
|
||||||
|
sindir.c
|
||||||
|
size.c
|
||||||
|
sleep.c
|
||||||
|
splcmd.c
|
||||||
|
splnam.c
|
||||||
|
spool.c
|
||||||
|
spawn.c
|
||||||
|
srmdir.c
|
||||||
|
statsb.c
|
||||||
|
status.c
|
||||||
|
strerr.c
|
||||||
|
time.c
|
||||||
|
tmpfil.c
|
||||||
|
trunc.c
|
||||||
|
uacces.c
|
||||||
|
ufopen.c
|
||||||
|
ultspl.c
|
||||||
|
unknwn.c
|
||||||
|
uuto.c
|
||||||
|
walk.c
|
||||||
|
wldcrd.c
|
||||||
|
work.c
|
||||||
|
xqtfil.c
|
||||||
|
xqtsub.c
|
22
gnu/libexec/uucp/libunix/Makefile
Normal file
22
gnu/libexec/uucp/libunix/Makefile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# This subdirectory contains Unix specific support functions.
|
||||||
|
# $Id: Makefile,v 1.2 1993/08/05 16:14:51 jtc Exp $
|
||||||
|
|
||||||
|
LIB= unix
|
||||||
|
SRCS= access.c addbas.c app3.c app4.c basnam.c bytfre.c cwd.c \
|
||||||
|
chmod.c cohtty.c cusub.c detach.c efopen.c epopen.c exists.c \
|
||||||
|
filnam.c fsusg.c indir.c init.c isdir.c isfork.c iswait.c \
|
||||||
|
jobid.c lcksys.c link.c locfil.c lock.c loctim.c mail.c \
|
||||||
|
mkdirs.c mode.c move.c opensr.c pause.c picksb.c portnm.c \
|
||||||
|
proctm.c recep.c run.c seq.c serial.c signal.c sindir.c size.c \
|
||||||
|
sleep.c spawn.c splcmd.c splnam.c spool.c srmdir.c statsb.c \
|
||||||
|
status.c time.c tmpfil.c trunc.c uacces.c ufopen.c ultspl.c \
|
||||||
|
unknwn.c uuto.c walk.c wldcrd.c work.c xqtfil.c xqtsub.c ftw.c
|
||||||
|
CFLAGS+= -I$(.CURDIR)/../common_sources \
|
||||||
|
-DOWNER=\"$(owner)\" -DSBINDIR=\"$(sbindir)\"
|
||||||
|
|
||||||
|
NOMAN= noman
|
||||||
|
NOPROFILE= noprofile
|
||||||
|
|
||||||
|
install:
|
||||||
|
|
||||||
|
.include <bsd.lib.mk>
|
83
gnu/libexec/uucp/libunix/access.c
Normal file
83
gnu/libexec/uucp/libunix/access.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* access.c
|
||||||
|
Check access to files by the user and by the daemon. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* See if the user has access to a file, to prevent the setuid uucp
|
||||||
|
and uux programs handing out unauthorized access. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_access (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
if (access (zfile, R_OK) == 0)
|
||||||
|
return TRUE;
|
||||||
|
ulog (LOG_ERROR, "%s: %s", zfile, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if the daemon has access to a file. This is called if a file
|
||||||
|
is not being transferred to the spool directory, since if the
|
||||||
|
daemon does not have access the later transfer will fail. We
|
||||||
|
assume that the daemon will have the same euid (or egid) as the one
|
||||||
|
we are running under. If our uid (gid) and euid (egid) are the
|
||||||
|
same, we assume that we have access. Note that is not important
|
||||||
|
for security, since the check will be (implicitly) done again when
|
||||||
|
the daemon tries to transfer the file. This routine should work
|
||||||
|
whether the UUCP programs are installed setuid or setgid. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_daemon_access (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
uid_t ieuid, iuid, iegid, igid;
|
||||||
|
boolean fok;
|
||||||
|
|
||||||
|
ieuid = geteuid ();
|
||||||
|
if (ieuid == 0)
|
||||||
|
return TRUE;
|
||||||
|
iuid = getuid ();
|
||||||
|
iegid = getegid ();
|
||||||
|
igid = getgid ();
|
||||||
|
|
||||||
|
/* If our effective uid and gid are the same as our real uid and
|
||||||
|
gid, we assume the daemon will have access to the file. */
|
||||||
|
if (ieuid == iuid && iegid == igid)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (stat ((char *) zfile, &s) != 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If our euid is not our uid, but it is the file's uid, see if the
|
||||||
|
owner has read access. Otherwise, if our egid is not our gid,
|
||||||
|
but it is the file's gid, see if the group has read access.
|
||||||
|
Otherwise, see if the world has read access. We know from the
|
||||||
|
above check that at least one of our euid and egid are different,
|
||||||
|
so that is the only one we want to check. This check could fail
|
||||||
|
if the UUCP programs were both setuid and setgid, but why would
|
||||||
|
they be? */
|
||||||
|
if (ieuid != iuid && ieuid == s.st_uid)
|
||||||
|
fok = (s.st_mode & S_IRUSR) != 0;
|
||||||
|
else if (iegid != igid && iegid == s.st_gid)
|
||||||
|
fok = (s.st_mode & S_IRGRP) != 0;
|
||||||
|
else
|
||||||
|
fok = (s.st_mode & S_IROTH) != 0;
|
||||||
|
|
||||||
|
if (! fok)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: cannot be read by daemon", zfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
50
gnu/libexec/uucp/libunix/addbas.c
Normal file
50
gnu/libexec/uucp/libunix/addbas.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* addbas.c
|
||||||
|
If we have a directory, add in a base name. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* If we have a directory, add a base name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_add_base (zfile, zname)
|
||||||
|
const char *zfile;
|
||||||
|
const char *zname;
|
||||||
|
{
|
||||||
|
size_t clen;
|
||||||
|
const char *zlook;
|
||||||
|
char *zfree;
|
||||||
|
char *zret;
|
||||||
|
|
||||||
|
#if DEBUG > 0
|
||||||
|
if (*zfile != '/')
|
||||||
|
ulog (LOG_FATAL, "zsysdep_add_base: %s: Can't happen", zfile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
clen = strlen (zfile);
|
||||||
|
|
||||||
|
if (zfile[clen - 1] != '/')
|
||||||
|
{
|
||||||
|
if (! fsysdep_directory (zfile))
|
||||||
|
return zbufcpy (zfile);
|
||||||
|
zfree = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Trim out the trailing '/'. */
|
||||||
|
zfree = zbufcpy (zfile);
|
||||||
|
zfree[clen - 1] = '\0';
|
||||||
|
zfile = zfree;
|
||||||
|
}
|
||||||
|
|
||||||
|
zlook = strrchr (zname, '/');
|
||||||
|
if (zlook != NULL)
|
||||||
|
zname = zlook + 1;
|
||||||
|
|
||||||
|
zret = zsysdep_in_dir (zfile, zname);
|
||||||
|
ubuffree (zfree);
|
||||||
|
return zret;
|
||||||
|
}
|
29
gnu/libexec/uucp/libunix/app3.c
Normal file
29
gnu/libexec/uucp/libunix/app3.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* app3.c
|
||||||
|
Stick two directories and a file name together. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsappend3 (zdir1, zdir2, zfile)
|
||||||
|
const char *zdir1;
|
||||||
|
const char *zdir2;
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
size_t cdir1, cdir2, cfile;
|
||||||
|
char *zret;
|
||||||
|
|
||||||
|
cdir1 = strlen (zdir1);
|
||||||
|
cdir2 = strlen (zdir2);
|
||||||
|
cfile = strlen (zfile);
|
||||||
|
zret = zbufalc (cdir1 + cdir2 + cfile + 3);
|
||||||
|
memcpy (zret, zdir1, cdir1);
|
||||||
|
memcpy (zret + cdir1 + 1, zdir2, cdir2);
|
||||||
|
memcpy (zret + cdir1 + cdir2 + 2, zfile, cfile);
|
||||||
|
zret[cdir1] = '/';
|
||||||
|
zret[cdir1 + cdir2 + 1] = '/';
|
||||||
|
zret[cdir1 + cdir2 + cfile + 2] = '\0';
|
||||||
|
return zret;
|
||||||
|
}
|
33
gnu/libexec/uucp/libunix/app4.c
Normal file
33
gnu/libexec/uucp/libunix/app4.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* app4.c
|
||||||
|
Stick three directories and a file name together. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsappend4 (zdir1, zdir2, zdir3, zfile)
|
||||||
|
const char *zdir1;
|
||||||
|
const char *zdir2;
|
||||||
|
const char *zdir3;
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
size_t cdir1, cdir2, cdir3, cfile;
|
||||||
|
char *zret;
|
||||||
|
|
||||||
|
cdir1 = strlen (zdir1);
|
||||||
|
cdir2 = strlen (zdir2);
|
||||||
|
cdir3 = strlen (zdir3);
|
||||||
|
cfile = strlen (zfile);
|
||||||
|
zret = zbufalc (cdir1 + cdir2 + cdir3 + cfile + 4);
|
||||||
|
memcpy (zret, zdir1, cdir1);
|
||||||
|
memcpy (zret + cdir1 + 1, zdir2, cdir2);
|
||||||
|
memcpy (zret + cdir1 + cdir2 + 2, zdir3, cdir3);
|
||||||
|
memcpy (zret + cdir1 + cdir2 + cdir3 + 3, zfile, cfile);
|
||||||
|
zret[cdir1] = '/';
|
||||||
|
zret[cdir1 + cdir2 + 1] = '/';
|
||||||
|
zret[cdir1 + cdir2 + cdir3 + 2] = '/';
|
||||||
|
zret[cdir1 + cdir2 + cdir3 + cfile + 3] = '\0';
|
||||||
|
return zret;
|
||||||
|
}
|
22
gnu/libexec/uucp/libunix/basnam.c
Normal file
22
gnu/libexec/uucp/libunix/basnam.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* basnam.c
|
||||||
|
Get the base name of a file. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Get the base name of a file name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_base_name (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
const char *z;
|
||||||
|
|
||||||
|
z = strrchr (zfile, '/');
|
||||||
|
if (z != NULL)
|
||||||
|
return zbufcpy (z + 1);
|
||||||
|
return zbufcpy (zfile);
|
||||||
|
}
|
19
gnu/libexec/uucp/libunix/bytfre.c
Normal file
19
gnu/libexec/uucp/libunix/bytfre.c
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* bytfre.c
|
||||||
|
Get the number of bytes free on a file system. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "fsusg.h"
|
||||||
|
|
||||||
|
long
|
||||||
|
csysdep_bytes_free (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
struct fs_usage s;
|
||||||
|
|
||||||
|
if (get_fs_usage ((char *) zfile, (char *) NULL, &s) < 0)
|
||||||
|
return -1;
|
||||||
|
return s.fsu_bavail * (long) 512;
|
||||||
|
}
|
25
gnu/libexec/uucp/libunix/chmod.c
Normal file
25
gnu/libexec/uucp/libunix/chmod.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* chmod.c
|
||||||
|
Change the mode of a file. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* Change the mode of a file. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_change_mode (zfile, imode)
|
||||||
|
const char *zfile;
|
||||||
|
unsigned int imode;
|
||||||
|
{
|
||||||
|
if (chmod ((char *) zfile, imode) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "chmod (%s): %s", zfile, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
244
gnu/libexec/uucp/libunix/cohtty.c
Normal file
244
gnu/libexec/uucp/libunix/cohtty.c
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* Coherent tty locking support. This file was contributed by Bob
|
||||||
|
Hemedinger <bob@dalek.mwc.com> of Mark Williams Corporation and
|
||||||
|
lightly edited by Ian Lance Taylor. */
|
||||||
|
|
||||||
|
/* The bottom part of this file is lock.c.
|
||||||
|
* This is a hacked lock.c. A full lock.c can be found in the libmisc sources
|
||||||
|
* under /usr/src/misc.tar.Z.
|
||||||
|
*
|
||||||
|
* These are for checking for the existence of locks:
|
||||||
|
* lockexist(resource)
|
||||||
|
* lockttyexist(ttyname)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if HAVE_COHERENT_LOCKFILES
|
||||||
|
|
||||||
|
/* cohtty.c: Given a serial device name, read /etc/ttys and determine if
|
||||||
|
* the device is already enabled. If it is, disable the
|
||||||
|
* device and return a string so that it can be re-enabled
|
||||||
|
* at the completion of the uucico session as part of the
|
||||||
|
* function that resets the serial device before uucico
|
||||||
|
* terminates.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <access.h>
|
||||||
|
|
||||||
|
/* fscoherent_disable_tty() is a COHERENT specific function. It takes the name
|
||||||
|
* of a serial device and then scans /etc/ttys for a match. If it finds one,
|
||||||
|
* it checks the first field of the entry. If it is a '1', then it will disable
|
||||||
|
* the port and set a flag. The flag will be checked later when uucico wants to
|
||||||
|
* reset the serial device to see if the device needs to be re-enabled.
|
||||||
|
*/
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fscoherent_disable_tty (zdevice, pzenable)
|
||||||
|
const char *zdevice;
|
||||||
|
char **pzenable;
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
struct ttyentry{ /* this is an /etc/ttys entry */
|
||||||
|
char enable_disable[1];
|
||||||
|
char remote_local[1];
|
||||||
|
char baud_rate[1];
|
||||||
|
char tty_device[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ttyentry sought_tty;
|
||||||
|
|
||||||
|
int x,y,z; /* dummy */
|
||||||
|
FILE * infp; /* this will point to /etc/ttys */
|
||||||
|
char disable_command[66]; /* this will be the disable command
|
||||||
|
* passed to the system.
|
||||||
|
*/
|
||||||
|
char enable_device[16]; /* this will hold our device name
|
||||||
|
* to enable.
|
||||||
|
*/
|
||||||
|
|
||||||
|
*pzenable = NULL;
|
||||||
|
|
||||||
|
strcpy(enable_device,""); /* initialize our strings */
|
||||||
|
strcpy(sought_tty.tty_device,"");
|
||||||
|
|
||||||
|
if( (infp = fopen("/etc/ttys","r")) == NULL){
|
||||||
|
ulog(LOG_ERROR,"Error: check_disable_tty: failed to open /etc/ttys\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (NULL !=(fgets(&sought_tty, sizeof (sought_tty), infp ))){
|
||||||
|
sought_tty.tty_device[strlen(sought_tty.tty_device) -1] = '\0';
|
||||||
|
strcpy(enable_device,sought_tty.tty_device);
|
||||||
|
|
||||||
|
/* we must strip away the suffix to the com port name or
|
||||||
|
* we will never find a match. For example, if we are passed
|
||||||
|
* /dev/com4l to call out with and the port is already enabled,
|
||||||
|
* 9/10 the port enabled will be com4r. After we strip away the
|
||||||
|
* suffix of the port found in /etc/ttys, then we can test
|
||||||
|
* if the base port name appears in the device name string
|
||||||
|
* passed to us.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(z = strlen(sought_tty.tty_device) ; z > 0 ; z--){
|
||||||
|
if(isdigit(sought_tty.tty_device[z])){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y = strlen(sought_tty.tty_device);
|
||||||
|
for(x = z+1 ; x <= y; x++){
|
||||||
|
sought_tty.tty_device[x] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ulog(LOG_NORMAL,"found device {%s}\n",sought_tty.tty_device); */
|
||||||
|
if(strstr(zdevice, sought_tty.tty_device)){
|
||||||
|
if(sought_tty.enable_disable[0] == '1'){
|
||||||
|
ulog(LOG_NORMAL, "coh_tty: Disabling device %s {%s}\n",
|
||||||
|
zdevice, sought_tty.tty_device);
|
||||||
|
sprintf(disable_command, "/etc/disable %s",enable_device);
|
||||||
|
{
|
||||||
|
pid_t ipid;
|
||||||
|
const char *azargs[3];
|
||||||
|
int aidescs[3];
|
||||||
|
|
||||||
|
azargs[0] = "/etc/disable";
|
||||||
|
azargs[1] = enable_device;
|
||||||
|
azargs[2] = NULL;
|
||||||
|
aidescs[0] = SPAWN_NULL;
|
||||||
|
aidescs[1] = SPAWN_NULL;
|
||||||
|
aidescs[2] = SPAWN_NULL;
|
||||||
|
ipid = ixsspawn (azargs, aidescs, TRUE,
|
||||||
|
FALSE,
|
||||||
|
(const char *) NULL, TRUE,
|
||||||
|
TRUE,
|
||||||
|
(const char *) NULL,
|
||||||
|
(const char *) NULL,
|
||||||
|
(const char *) NULL);
|
||||||
|
if (ipid < 0)
|
||||||
|
x = 1;
|
||||||
|
else
|
||||||
|
x = ixswait ((unsigned long) ipid,
|
||||||
|
(const char *) NULL);
|
||||||
|
}
|
||||||
|
*pzenable = zbufalc (sizeof "/dev/"
|
||||||
|
+ strlen (enable_device));
|
||||||
|
sprintf(*pzenable,"/dev/%s", enable_device);
|
||||||
|
/* ulog(LOG_NORMAL,"Enable string is {%s}",*pzenable); */
|
||||||
|
return(x==0? TRUE : FALSE); /* disable either failed
|
||||||
|
or succeded */
|
||||||
|
}else{
|
||||||
|
return FALSE; /* device in tty entry not enabled */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE; /* no ttys entry found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following is COHERENT 4.0 specific. It is used to test for any
|
||||||
|
* existing lockfiles on a port which would have been created by init
|
||||||
|
* when a user logs into a port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCKSIG 9 /* Significant Chars of Lockable Resources. */
|
||||||
|
#define LOKFLEN 64 /* Max Length of UUCP Lock File Name. */
|
||||||
|
|
||||||
|
#define LOCKPRE "LCK.."
|
||||||
|
#define PIDLEN 6 /* Maximum length of string representing a pid. */
|
||||||
|
|
||||||
|
#ifndef LOCKDIR
|
||||||
|
#define LOCKDIR SPOOLDIR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* There is a special version of DEVMASK for the PE multiport driver
|
||||||
|
* because of the peculiar way it uses the minor device number. For
|
||||||
|
* all other drivers, the lower 5 bits describe the physical port--
|
||||||
|
* the upper 3 bits give attributes for the port.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PE_DRIVER 21 /* Major device number for the PE driver. */
|
||||||
|
#define PE_DEVMASK 0x3f /* PE driver minor device mask. */
|
||||||
|
#define DEVMASK 0x1f /* Minor device mask. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generates a resource name for locking, based on the major number
|
||||||
|
* and the lower 4 bits of the minor number of the tty device.
|
||||||
|
*
|
||||||
|
* Builds the name in buff as two "." separated decimal numbers.
|
||||||
|
* Returns NULL on failure, buff on success.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
gen_res_name(path, buff)
|
||||||
|
char *path;
|
||||||
|
char *buff;
|
||||||
|
{
|
||||||
|
struct stat sbuf;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (0 != (status = stat(path, &sbuf))) {
|
||||||
|
/* Can't stat the file. */
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PE_DRIVER == major(sbuf.st_rdev)) {
|
||||||
|
sprintf(buff, "%d.%d", major(sbuf.st_rdev),
|
||||||
|
PE_DEVMASK & minor(sbuf.st_rdev));
|
||||||
|
} else {
|
||||||
|
sprintf(buff, "%d.%d", major(sbuf.st_rdev),
|
||||||
|
DEVMASK & minor(sbuf.st_rdev));
|
||||||
|
}
|
||||||
|
|
||||||
|
return(buff);
|
||||||
|
} /* gen_res_name */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lockexist(resource) char *resource;
|
||||||
|
*
|
||||||
|
* Test for existance of a lock on the given resource.
|
||||||
|
*
|
||||||
|
* Returns: (1) Resource is locked.
|
||||||
|
* (0) Resource is not locked.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
lockexist(resource)
|
||||||
|
const char *resource;
|
||||||
|
{
|
||||||
|
char lockfn[LOKFLEN];
|
||||||
|
|
||||||
|
if ( resource == NULL )
|
||||||
|
return(0);
|
||||||
|
sprintf(lockfn, "%s/%s%.*s", LOCKDIR, LOCKPRE, LOCKSIG, resource);
|
||||||
|
|
||||||
|
return (!access(lockfn, AEXISTS));
|
||||||
|
} /* lockexist() */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lockttyexist(ttyname) char *ttyname;
|
||||||
|
*
|
||||||
|
* Test for existance of a lock on the given tty.
|
||||||
|
*
|
||||||
|
* Returns: (1) Resource is locked.
|
||||||
|
* (0) Resource is not locked.
|
||||||
|
*/
|
||||||
|
boolean
|
||||||
|
lockttyexist(ttyn)
|
||||||
|
const char *ttyn;
|
||||||
|
{
|
||||||
|
char resource[LOKFLEN];
|
||||||
|
char filename[LOKFLEN];
|
||||||
|
|
||||||
|
sprintf(filename, "/dev/%s", ttyn);
|
||||||
|
if (NULL == gen_res_name(filename, resource)){
|
||||||
|
return(0); /* Non-existent tty can not be locked :-) */
|
||||||
|
}
|
||||||
|
|
||||||
|
return(lockexist(resource));
|
||||||
|
} /* lockttyexist() */
|
||||||
|
|
||||||
|
#endif /* HAVE_COHERENT_LOCKFILES */
|
1163
gnu/libexec/uucp/libunix/cusub.c
Normal file
1163
gnu/libexec/uucp/libunix/cusub.c
Normal file
File diff suppressed because it is too large
Load Diff
55
gnu/libexec/uucp/libunix/cwd.c
Normal file
55
gnu/libexec/uucp/libunix/cwd.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* cwd.c
|
||||||
|
Routines dealing with the current working directory. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* See whether running this file through zsysdep_add_cwd would require
|
||||||
|
knowing the current working directory. This is used to avoid
|
||||||
|
determining the cwd if it will not be needed. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_needs_cwd (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
return *zfile != '/' && *zfile != '~';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expand a local file, putting relative pathnames in the current
|
||||||
|
working directory. Note that ~/file is placed in the public
|
||||||
|
directory, rather than in the user's home directory. This is
|
||||||
|
consistent with other UUCP packages. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_local_file_cwd (zfile, zpubdir)
|
||||||
|
const char *zfile;
|
||||||
|
const char *zpubdir;
|
||||||
|
{
|
||||||
|
if (*zfile == '/')
|
||||||
|
return zbufcpy (zfile);
|
||||||
|
else if (*zfile == '~')
|
||||||
|
return zsysdep_local_file (zfile, zpubdir);
|
||||||
|
else
|
||||||
|
return zsysdep_add_cwd (zfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the current working directory to a remote file name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_add_cwd (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
if (*zfile == '/' || *zfile == '~')
|
||||||
|
return zbufcpy (zfile);
|
||||||
|
|
||||||
|
if (zScwd == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "Can't determine current directory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zsysdep_in_dir (zScwd, zfile);
|
||||||
|
}
|
186
gnu/libexec/uucp/libunix/detach.c
Normal file
186
gnu/libexec/uucp/libunix/detach.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/* detach.c
|
||||||
|
Detach from the controlling terminal.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_SYS_IOCTL_H
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIOCNOTTY
|
||||||
|
#define HAVE_TIOCNOTTY 1
|
||||||
|
#else
|
||||||
|
#define HAVE_TIOCNOTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Detach from the controlling terminal. This is called by uucico if
|
||||||
|
it is calling out to another system, so that it can receive SIGHUP
|
||||||
|
signals from the port it calls out on. It is also called by uucico
|
||||||
|
just before it starts uuxqt, so that uuxqt is completely
|
||||||
|
independent of the terminal. */
|
||||||
|
|
||||||
|
void
|
||||||
|
usysdep_detach ()
|
||||||
|
{
|
||||||
|
#if ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY
|
||||||
|
|
||||||
|
pid_t igrp;
|
||||||
|
|
||||||
|
/* First make sure we are not a process group leader. If we have
|
||||||
|
TIOCNOTTY, this doesn't matter, since TIOCNOTTY sets our process
|
||||||
|
group to 0 anyhow. */
|
||||||
|
|
||||||
|
#if HAVE_BSD_PGRP
|
||||||
|
igrp = getpgrp (0);
|
||||||
|
#else
|
||||||
|
igrp = getpgrp ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (igrp == getpid ())
|
||||||
|
{
|
||||||
|
boolean fignored;
|
||||||
|
pid_t ipid;
|
||||||
|
|
||||||
|
/* Ignore SIGHUP, since our process group leader is about to
|
||||||
|
die. */
|
||||||
|
usset_signal (SIGHUP, SIG_IGN, FALSE, &fignored);
|
||||||
|
|
||||||
|
ipid = ixsfork ();
|
||||||
|
if (ipid < 0)
|
||||||
|
ulog (LOG_FATAL, "fork: %s", strerror (errno));
|
||||||
|
|
||||||
|
if (ipid != 0)
|
||||||
|
_exit (EXIT_SUCCESS);
|
||||||
|
|
||||||
|
/* We'll always wind up as a child of process number 1, right?
|
||||||
|
Right? We have to wait for our parent to die before
|
||||||
|
reenabling SIGHUP. */
|
||||||
|
while (getppid () != 1)
|
||||||
|
sleep (1);
|
||||||
|
|
||||||
|
ulog_id (getpid ());
|
||||||
|
|
||||||
|
/* Restore SIGHUP catcher if it wasn't being ignored. */
|
||||||
|
if (! fignored)
|
||||||
|
usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! HAVE_BSD_PGRP || ! HAVE_TIOCNOTTY */
|
||||||
|
|
||||||
|
#if HAVE_TIOCNOTTY
|
||||||
|
/* Lose the original controlling terminal. If standard input has
|
||||||
|
been reopened to /dev/null, this will do no harm. If another
|
||||||
|
port has been opened to become the controlling terminal, it
|
||||||
|
should have been detached when it was closed. */
|
||||||
|
(void) ioctl (0, TIOCNOTTY, (char *) NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Close stdin, stdout and stderr and reopen them on /dev/null, to
|
||||||
|
make sure we have no connection at all to the terminal. */
|
||||||
|
(void) close (0);
|
||||||
|
(void) close (1);
|
||||||
|
(void) close (2);
|
||||||
|
if (open ((char *) "/dev/null", O_RDONLY) != 0
|
||||||
|
|| open ((char *) "/dev/null", O_WRONLY) != 1
|
||||||
|
|| open ((char *) "/dev/null", O_WRONLY) != 2)
|
||||||
|
ulog (LOG_FATAL, "open (/dev/null): %s", strerror (errno));
|
||||||
|
|
||||||
|
#if HAVE_BSD_PGRP
|
||||||
|
|
||||||
|
/* Make sure our process group ID is set to 0. On BSD TIOCNOTTY
|
||||||
|
should already have set it 0, so this will do no harm. On System
|
||||||
|
V we presumably did not execute the TIOCNOTTY call, but the
|
||||||
|
System V setpgrp will detach the controlling terminal anyhow.
|
||||||
|
This lets us use the same code on both BSD and System V, provided
|
||||||
|
it compiles correctly, which life easier for the configure
|
||||||
|
script. We don't output an error if we got EPERM because some
|
||||||
|
BSD variants don't permit this usage of setpgrp (which means they
|
||||||
|
don't provide any way to pick up a new controlling terminal). */
|
||||||
|
|
||||||
|
if (setpgrp (0, 0) < 0)
|
||||||
|
{
|
||||||
|
if (errno != EPERM)
|
||||||
|
ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* ! HAVE_BSD_PGRP */
|
||||||
|
|
||||||
|
#if HAVE_SETSID
|
||||||
|
|
||||||
|
/* Under POSIX the setsid call creates a new session for which we
|
||||||
|
are the process group leader. It also detaches us from our
|
||||||
|
controlling terminal. I'm using the BSD setpgrp call first
|
||||||
|
because they should be equivalent for my purposes, but it turns
|
||||||
|
out that on Ultrix 4.0 setsid prevents us from ever acquiring
|
||||||
|
another controlling terminal (it does not change our process
|
||||||
|
group, and Ultrix 4.0 prevents us from setting our process group
|
||||||
|
to 0). */
|
||||||
|
(void) setsid ();
|
||||||
|
|
||||||
|
#else /* ! HAVE_SETSID */
|
||||||
|
|
||||||
|
#if HAVE_SETPGRP
|
||||||
|
|
||||||
|
/* Now we assume we have the System V setpgrp, which takes no
|
||||||
|
arguments, and we couldn't compile the HAVE_BSD_PGRP code above
|
||||||
|
because there was a prototype somewhere in scope. On System V
|
||||||
|
setpgrp makes us the leader of a new process group and also
|
||||||
|
detaches the controlling terminal. */
|
||||||
|
|
||||||
|
if (setpgrp () < 0)
|
||||||
|
ulog (LOG_ERROR, "setpgrp: %s", strerror (errno));
|
||||||
|
|
||||||
|
#else /* ! HAVE_SETPGRP */
|
||||||
|
|
||||||
|
#error Must detach from controlling terminal
|
||||||
|
|
||||||
|
#endif /* HAVE_SETPGRP */
|
||||||
|
#endif /* ! HAVE_SETSID */
|
||||||
|
#endif /* ! HAVE_BSD_PGRP */
|
||||||
|
|
||||||
|
/* At this point we have completely detached from our controlling
|
||||||
|
terminal. The next terminal device we open will probably become
|
||||||
|
our controlling terminal. */
|
||||||
|
}
|
123
gnu/libexec/uucp/libunix/dirent.c
Normal file
123
gnu/libexec/uucp/libunix/dirent.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/* dirent.c
|
||||||
|
Replacements for opendir, readdir and closedir for the original
|
||||||
|
Unix filesystem only.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Simple emulations of opendir/readdir/closedir for systems which
|
||||||
|
have the original format of Unix directories. It's probably better
|
||||||
|
to get Doug Gwyn's public domain set of emulation functions. */
|
||||||
|
|
||||||
|
DIR *
|
||||||
|
opendir (zdir)
|
||||||
|
const char *zdir;
|
||||||
|
{
|
||||||
|
int o;
|
||||||
|
struct stat s;
|
||||||
|
DIR *qret;
|
||||||
|
|
||||||
|
o = open ((char *) zdir, O_RDONLY | O_NOCTTY, 0);
|
||||||
|
if (o < 0)
|
||||||
|
return NULL;
|
||||||
|
if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0
|
||||||
|
|| fstat (o, &s) < 0)
|
||||||
|
{
|
||||||
|
int isave;
|
||||||
|
|
||||||
|
isave = errno;
|
||||||
|
(void) close (o);
|
||||||
|
errno = isave;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (! S_ISDIR (s.st_mode))
|
||||||
|
{
|
||||||
|
(void) close (o);
|
||||||
|
errno = ENOTDIR;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
qret = (DIR *) xmalloc (sizeof (DIR));
|
||||||
|
qret->o = o;
|
||||||
|
return qret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent *
|
||||||
|
readdir (q)
|
||||||
|
DIR *q;
|
||||||
|
{
|
||||||
|
struct direct sdir;
|
||||||
|
int cgot;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
cgot = read (q->o, &sdir, sizeof (struct direct));
|
||||||
|
if (cgot <= 0)
|
||||||
|
return NULL;
|
||||||
|
if (cgot != sizeof (struct direct))
|
||||||
|
{
|
||||||
|
errno = ENOENT;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (sdir.d_ino == 0);
|
||||||
|
|
||||||
|
strncpy (q->s.d_name, sdir.d_name, DIRSIZ);
|
||||||
|
q->s.d_name[DIRSIZ] = '\0';
|
||||||
|
return &q->s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
closedir (q)
|
||||||
|
DIR *q;
|
||||||
|
{
|
||||||
|
int o;
|
||||||
|
|
||||||
|
o = q->o;
|
||||||
|
xfree (q);
|
||||||
|
return close (o);
|
||||||
|
}
|
69
gnu/libexec/uucp/libunix/dup2.c
Normal file
69
gnu/libexec/uucp/libunix/dup2.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/* dup2.c
|
||||||
|
The Unix dup2 function, for systems which only have dup.
|
||||||
|
|
||||||
|
Copyright (C) 1985, 1986, 1987, 1988, 1990 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* I basically took this from the emacs 18.57 distribution, although I
|
||||||
|
cleaned it up a bit and made it POSIX compliant. */
|
||||||
|
|
||||||
|
int
|
||||||
|
dup2 (oold, onew)
|
||||||
|
int oold;
|
||||||
|
int onew;
|
||||||
|
{
|
||||||
|
if (oold == onew)
|
||||||
|
return onew;
|
||||||
|
(void) close (onew);
|
||||||
|
|
||||||
|
#ifdef F_DUPFD
|
||||||
|
return fcntl (oold, F_DUPFD, onew);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
int onext, oret, isave;
|
||||||
|
|
||||||
|
onext = dup (oold);
|
||||||
|
if (onext == onew)
|
||||||
|
return onext;
|
||||||
|
if (onext < 0)
|
||||||
|
return -1;
|
||||||
|
oret = dup2 (oold, onew);
|
||||||
|
isave = errno;
|
||||||
|
(void) close (onext);
|
||||||
|
errno = isave;
|
||||||
|
return oret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
132
gnu/libexec/uucp/libunix/efopen.c
Normal file
132
gnu/libexec/uucp/libunix/efopen.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/* efopen.c
|
||||||
|
Open a stdio file with appropriate permissions. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_APPEND
|
||||||
|
#ifdef FAPPEND
|
||||||
|
#define O_APPEND FAPPEND
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
esysdep_fopen (zfile, fpublic, fappend, fmkdirs)
|
||||||
|
const char *zfile;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fappend;
|
||||||
|
boolean fmkdirs;
|
||||||
|
{
|
||||||
|
int imode;
|
||||||
|
int o;
|
||||||
|
FILE *e;
|
||||||
|
|
||||||
|
if (fpublic)
|
||||||
|
imode = IPUBLIC_FILE_MODE;
|
||||||
|
else
|
||||||
|
imode = IPRIVATE_FILE_MODE;
|
||||||
|
|
||||||
|
if (! fappend)
|
||||||
|
o = creat ((char *) zfile, imode);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef O_CREAT
|
||||||
|
o = open ((char *) zfile,
|
||||||
|
O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY,
|
||||||
|
imode);
|
||||||
|
#else
|
||||||
|
o = open ((char *) zfile, O_WRONLY | O_NOCTTY);
|
||||||
|
if (o < 0 && errno == ENOENT)
|
||||||
|
o = creat ((char *) zfile, imode);
|
||||||
|
#endif /* ! defined (O_CREAT) */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT && fmkdirs)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zfile, fpublic))
|
||||||
|
return NULL;
|
||||||
|
if (! fappend)
|
||||||
|
o = creat ((char *) zfile, imode);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef O_CREAT
|
||||||
|
o = open ((char *) zfile,
|
||||||
|
O_WRONLY | O_APPEND | O_CREAT | O_NOCTTY,
|
||||||
|
imode);
|
||||||
|
#else
|
||||||
|
o = creat ((char *) zfile, imode);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef O_CREAT
|
||||||
|
#ifdef O_APPEND
|
||||||
|
if (fappend)
|
||||||
|
{
|
||||||
|
if (fcntl (o, F_SETFL, O_APPEND) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (%s, O_APPEND): %s", zfile,
|
||||||
|
strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* defined (O_APPEND) */
|
||||||
|
#endif /* ! defined (O_CREAT) */
|
||||||
|
|
||||||
|
if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (%s, FD_CLOEXEC): %s", zfile,
|
||||||
|
strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fappend)
|
||||||
|
e = fdopen (o, (char *) "a");
|
||||||
|
else
|
||||||
|
e = fdopen (o, (char *) "w");
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fdopen: %s", strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
85
gnu/libexec/uucp/libunix/epopen.c
Normal file
85
gnu/libexec/uucp/libunix/epopen.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* epopen.c
|
||||||
|
A version of popen that goes through ixsspawn.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* A version of popen that goes through ixsspawn. This actually takes
|
||||||
|
an array of arguments rather than a string, and takes a boolean
|
||||||
|
read/write value rather than a string. It sets *pipid to the
|
||||||
|
process ID of the child. */
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
espopen (pazargs, frd, pipid)
|
||||||
|
const char **pazargs;
|
||||||
|
boolean frd;
|
||||||
|
pid_t *pipid;
|
||||||
|
{
|
||||||
|
int aidescs[3];
|
||||||
|
pid_t ipid;
|
||||||
|
FILE *eret;
|
||||||
|
|
||||||
|
if (frd)
|
||||||
|
{
|
||||||
|
aidescs[0] = SPAWN_NULL;
|
||||||
|
aidescs[1] = SPAWN_READ_PIPE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aidescs[0] = SPAWN_WRITE_PIPE;
|
||||||
|
aidescs[1] = SPAWN_NULL;
|
||||||
|
}
|
||||||
|
aidescs[2] = SPAWN_NULL;
|
||||||
|
|
||||||
|
ipid = ixsspawn (pazargs, aidescs, FALSE, FALSE,
|
||||||
|
(const char *) NULL, FALSE, TRUE,
|
||||||
|
(const char *) NULL, (const char *) NULL,
|
||||||
|
(const char *) NULL);
|
||||||
|
if (ipid < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (frd)
|
||||||
|
eret = fdopen (aidescs[1], (char *) "r");
|
||||||
|
else
|
||||||
|
eret = fdopen (aidescs[0], (char *) "w");
|
||||||
|
if (eret == NULL)
|
||||||
|
{
|
||||||
|
int ierr;
|
||||||
|
|
||||||
|
ierr = errno;
|
||||||
|
(void) close (frd ? aidescs[1] : aidescs[0]);
|
||||||
|
(void) kill (ipid, SIGKILL);
|
||||||
|
(void) ixswait ((unsigned long) ipid, (const char *) NULL);
|
||||||
|
errno = ierr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pipid = ipid;
|
||||||
|
|
||||||
|
return eret;
|
||||||
|
}
|
16
gnu/libexec/uucp/libunix/exists.c
Normal file
16
gnu/libexec/uucp/libunix/exists.c
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* exists.c
|
||||||
|
Check whether a file exists. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_file_exists (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
return stat ((char *) zfile, &s) == 0;
|
||||||
|
}
|
376
gnu/libexec/uucp/libunix/filnam.c
Normal file
376
gnu/libexec/uucp/libunix/filnam.c
Normal file
@ -0,0 +1,376 @@
|
|||||||
|
/* filnam.c
|
||||||
|
Get names to use for UUCP files.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We need a definition for SEEK_SET. */
|
||||||
|
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* External functions. */
|
||||||
|
#ifndef lseek
|
||||||
|
extern off_t lseek ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZCHARS \
|
||||||
|
"0123456789ABCDEFGHIJKLMNOPQRTSUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
/* Local functions. */
|
||||||
|
|
||||||
|
static boolean fscmd_seq P((const char *zsystem, char *zseq));
|
||||||
|
static char *zsfile_name P((int btype, const char *zsystem,
|
||||||
|
const char *zlocalname, int bgrade,
|
||||||
|
boolean fxqt, char *ztname, char *zdname,
|
||||||
|
char *zxname));
|
||||||
|
|
||||||
|
/* Get a new command sequence number (this is not a sequence number to
|
||||||
|
be used for communicating with another system, but a sequence
|
||||||
|
number to be used when generating the name of a command file).
|
||||||
|
The sequence number is placed into zseq, which should be five
|
||||||
|
characters long. */
|
||||||
|
|
||||||
|
static boolean
|
||||||
|
fscmd_seq (zsystem, zseq)
|
||||||
|
const char *zsystem;
|
||||||
|
char *zseq;
|
||||||
|
{
|
||||||
|
boolean ferr;
|
||||||
|
char *zfree;
|
||||||
|
const char *zfile;
|
||||||
|
int o;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Lock the sequence file. This may not be correct for all systems,
|
||||||
|
but it only matters if the system UUCP and this UUCP are running
|
||||||
|
at the same time. */
|
||||||
|
while (! fsdo_lock ("LCK..SEQ", TRUE, &ferr))
|
||||||
|
{
|
||||||
|
if (ferr || FGOT_SIGNAL ())
|
||||||
|
return FALSE;
|
||||||
|
sleep (5);
|
||||||
|
}
|
||||||
|
|
||||||
|
zfree = NULL;
|
||||||
|
|
||||||
|
#if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43
|
||||||
|
zfile = "SEQF";
|
||||||
|
#endif
|
||||||
|
#if SPOOLDIR_HDB || SPOOLDIR_SVR4
|
||||||
|
zfree = zsysdep_in_dir (".Sequence", zsystem);
|
||||||
|
zfile = zfree;
|
||||||
|
#endif
|
||||||
|
#if SPOOLDIR_ULTRIX
|
||||||
|
if (! fsultrix_has_spool (zsystem))
|
||||||
|
zfile = "sys/DEFAULT/.SEQF";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zfree = zsappend3 ("sys", zsystem, ".SEQF");
|
||||||
|
zfile = zfree;
|
||||||
|
}
|
||||||
|
#endif /* SPOOLDIR_ULTRIX */
|
||||||
|
#if SPOOLDIR_TAYLOR
|
||||||
|
zfree = zsysdep_in_dir (zsystem, "SEQF");
|
||||||
|
zfile = zfree;
|
||||||
|
#endif /* SPOOLDIR_TAYLOR */
|
||||||
|
|
||||||
|
#ifdef O_CREAT
|
||||||
|
o = open ((char *) zfile, O_RDWR | O_CREAT | O_NOCTTY, IPUBLIC_FILE_MODE);
|
||||||
|
#else
|
||||||
|
o = open ((char *) zfile, O_RDWR | O_NOCTTY);
|
||||||
|
if (o < 0 && errno == ENOENT)
|
||||||
|
{
|
||||||
|
o = creat ((char *) zfile, IPUBLIC_FILE_MODE);
|
||||||
|
if (o >= 0)
|
||||||
|
{
|
||||||
|
(void) close (o);
|
||||||
|
o = open ((char *) zfile, O_RDWR | O_NOCTTY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zfile, FALSE))
|
||||||
|
{
|
||||||
|
(void) fsdo_unlock ("LCK..SEQ", TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#ifdef O_CREAT
|
||||||
|
o = open ((char *) zfile,
|
||||||
|
O_RDWR | O_CREAT | O_NOCTTY,
|
||||||
|
IPUBLIC_FILE_MODE);
|
||||||
|
#else
|
||||||
|
o = creat ((char *) zfile, IPUBLIC_FILE_MODE);
|
||||||
|
if (o >= 0)
|
||||||
|
{
|
||||||
|
(void) close (o);
|
||||||
|
o = open ((char *) zfile, O_RDWR | O_NOCTTY);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno));
|
||||||
|
(void) fsdo_unlock ("LCK..SEQ", TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read (o, zseq, CSEQLEN) != CSEQLEN)
|
||||||
|
strcpy (zseq, "0000");
|
||||||
|
zseq[CSEQLEN] = '\0';
|
||||||
|
|
||||||
|
/* We must add one to the sequence number and return the new value.
|
||||||
|
On Ultrix, arbitrary characters are allowed in the sequence
|
||||||
|
number. On other systems, the sequence number apparently must be
|
||||||
|
in hex. */
|
||||||
|
#if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_HDB || SPOOLDIR_SVR4
|
||||||
|
i = (int) strtol (zseq, (char **) NULL, 16);
|
||||||
|
++i;
|
||||||
|
if (i > 0xffff)
|
||||||
|
i = 0;
|
||||||
|
/* The sprintf argument has CSEQLEN built into it. */
|
||||||
|
sprintf (zseq, "%04x", (unsigned int) i);
|
||||||
|
#endif
|
||||||
|
#if SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR
|
||||||
|
for (i = CSEQLEN - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
const char *zdig;
|
||||||
|
|
||||||
|
zdig = strchr (ZCHARS, zseq[i]);
|
||||||
|
if (zdig == NULL || zdig[0] == '\0' || zdig[1] == '\0')
|
||||||
|
zseq[i] = '0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zseq[i] = zdig[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR */
|
||||||
|
|
||||||
|
if (lseek (o, (off_t) 0, SEEK_SET) < 0
|
||||||
|
|| write (o, zseq, CSEQLEN) != CSEQLEN
|
||||||
|
|| close (o) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "lseek or write or close: %s", strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
(void) fsdo_unlock ("LCK..SEQ", TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) fsdo_unlock ("LCK..SEQ", TRUE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the name of a command or data file for a remote system. The
|
||||||
|
btype argument should be C for a command file or D for a data file.
|
||||||
|
If the grade of a data file is X, it is assumed that this is going
|
||||||
|
to become an execute file on some other system. The zsystem
|
||||||
|
argument is the system that the file will be transferred to. The
|
||||||
|
ztname argument will be set to a file name that could be passed to
|
||||||
|
zsysdep_spool_file_name. The zdname argument, if not NULL, will be
|
||||||
|
set to a data file name appropriate for the remote system. The
|
||||||
|
zxname argument, if not NULL, will be set to the name of an execute
|
||||||
|
file on the remote system. None of the names will be more than 14
|
||||||
|
characters long. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
static char *
|
||||||
|
zsfile_name (btype, zsystem, zlocalname, bgrade, fxqt, ztname, zdname, zxname)
|
||||||
|
int btype;
|
||||||
|
const char *zsystem;
|
||||||
|
const char *zlocalname;
|
||||||
|
int bgrade;
|
||||||
|
boolean fxqt;
|
||||||
|
char *ztname;
|
||||||
|
char *zdname;
|
||||||
|
char *zxname;
|
||||||
|
{
|
||||||
|
char abseq[CSEQLEN + 1];
|
||||||
|
char absimple[11 + CSEQLEN];
|
||||||
|
char *zname;
|
||||||
|
|
||||||
|
if (zlocalname == NULL)
|
||||||
|
zlocalname = zSlocalname;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (! fscmd_seq (zsystem, abseq))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (btype == 'C')
|
||||||
|
{
|
||||||
|
#if ! SPOOLDIR_TAYLOR
|
||||||
|
sprintf (absimple, "C.%.7s%c%s", zsystem, bgrade, abseq);
|
||||||
|
#else
|
||||||
|
sprintf (absimple, "C.%c%s", bgrade, abseq);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (btype == 'D')
|
||||||
|
{
|
||||||
|
/* This name doesn't really matter that much; it's just the
|
||||||
|
name we use on the local system. The name we use on the
|
||||||
|
remote system, which we return in zdname, should contain
|
||||||
|
our system name so that remote UUCP's running SPOOLDIR_V2
|
||||||
|
and the like can distinguish while files come from which
|
||||||
|
systems. */
|
||||||
|
#if SPOOLDIR_HDB || SPOOLDIR_SVR4
|
||||||
|
sprintf (absimple, "D.%.7s%c%s", zsystem, bgrade, abseq);
|
||||||
|
#else /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
|
||||||
|
#if ! SPOOLDIR_TAYLOR
|
||||||
|
sprintf (absimple, "D.%.7s%c%s", zlocalname, bgrade, abseq);
|
||||||
|
#else /* SPOOLDIR_TAYLOR */
|
||||||
|
if (fxqt)
|
||||||
|
sprintf (absimple, "D.X%s", abseq);
|
||||||
|
else
|
||||||
|
sprintf (absimple, "D.%s", abseq);
|
||||||
|
#endif /* SPOOLDIR_TAYLOR */
|
||||||
|
#endif /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */
|
||||||
|
}
|
||||||
|
#if DEBUG > 0
|
||||||
|
else
|
||||||
|
ulog (LOG_FATAL, "zsfile_name: Can't happen");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zname = zsfind_file (absimple, zsystem, bgrade);
|
||||||
|
if (zname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (! fsysdep_file_exists (zname))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ubuffree (zname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ztname != NULL)
|
||||||
|
strcpy (ztname, absimple);
|
||||||
|
|
||||||
|
if (zdname != NULL)
|
||||||
|
sprintf (zdname, "D.%.7s%c%s", zlocalname, bgrade, abseq);
|
||||||
|
|
||||||
|
if (zxname != NULL)
|
||||||
|
sprintf (zxname, "X.%.7s%c%s", zlocalname, bgrade, abseq);
|
||||||
|
|
||||||
|
return zname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a name to use for a data file to be copied to another
|
||||||
|
system. The name returned will be for a real file. The zlocalname
|
||||||
|
argument is the local name as seen by the remote system, the bgrade
|
||||||
|
argument is the file grade, and the fxqt argument is TRUE if this
|
||||||
|
file will become an execution file. The ztname argument, if not
|
||||||
|
NULL, will be set to a name that could be passed to
|
||||||
|
zsysdep_spool_file_name to get back the return value of this
|
||||||
|
function. The zdname argument, if not NULL, will be set to a name
|
||||||
|
that the file could be given on another system. The zxname
|
||||||
|
argument, if not NULL, will be set to a name for an execute file on
|
||||||
|
another system. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_data_file_name (qsys, zlocalname, bgrade, fxqt, ztname, zdname,
|
||||||
|
zxname)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zlocalname;
|
||||||
|
int bgrade;
|
||||||
|
boolean fxqt;
|
||||||
|
char *ztname;
|
||||||
|
char *zdname;
|
||||||
|
char *zxname;
|
||||||
|
{
|
||||||
|
return zsfile_name ('D', qsys->uuconf_zname, zlocalname, bgrade, fxqt,
|
||||||
|
ztname, zdname, zxname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a command file name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zscmd_file (qsys, bgrade)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
int bgrade;
|
||||||
|
{
|
||||||
|
return zsfile_name ('C', qsys->uuconf_zname, (const char *) NULL,
|
||||||
|
bgrade, FALSE, (char *) NULL, (char *) NULL,
|
||||||
|
(char *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a name for an execute file to be created locally. This is
|
||||||
|
used by uux to execute a command locally with remote files. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_xqt_file_name ()
|
||||||
|
{
|
||||||
|
char abseq[CSEQLEN + 1];
|
||||||
|
char absx[11 + CSEQLEN];
|
||||||
|
char *zname;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (! fscmd_seq (zSlocalname, abseq))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sprintf (absx, "X.%.7sX%s", zSlocalname, abseq);
|
||||||
|
|
||||||
|
zname = zsfind_file (absx, zSlocalname, -1);
|
||||||
|
if (zname == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (! fsysdep_file_exists (zname))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ubuffree (zname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zname;
|
||||||
|
}
|
231
gnu/libexec/uucp/libunix/fsusg.c
Normal file
231
gnu/libexec/uucp/libunix/fsusg.c
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
/* fsusage.c -- return space usage of mounted filesystems
|
||||||
|
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
This file was modified slightly by Ian Lance Taylor, December 1992,
|
||||||
|
for use with Taylor UUCP. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "fsusg.h"
|
||||||
|
|
||||||
|
int statfs ();
|
||||||
|
|
||||||
|
#if STAT_STATFS2_BSIZE
|
||||||
|
#ifndef _IBMR2 /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS2_FSIZE /* 4.4BSD. */
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS2_FS_DATA /* Ultrix. */
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_USTAT /* SVR2 and others. */
|
||||||
|
#include <ustat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS4 /* SVR3, Dynix, Irix. */
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#endif
|
||||||
|
#ifdef _AIX
|
||||||
|
#ifdef _IBMR2 /* AIX RS6000. */
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
#ifdef _I386 /* AIX PS/2. */
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/dustat.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATVFS /* SVR4. */
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
int statvfs ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STAT_NONE 0
|
||||||
|
|
||||||
|
#if ! STAT_STATVFS
|
||||||
|
#if ! STAT_STATFS2_BSIZE
|
||||||
|
#if ! STAT_STATFS2_FSIZE
|
||||||
|
#if ! STAT_STATFS2_FS_DATA
|
||||||
|
#if ! STAT_STATFS4
|
||||||
|
#if ! STAT_USTAT
|
||||||
|
#undef STAT_NONE
|
||||||
|
#define STAT_NONE 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! STAT_NONE
|
||||||
|
|
||||||
|
/* Return the number of TOSIZE-byte blocks used by
|
||||||
|
BLOCKS FROMSIZE-byte blocks, rounding up. */
|
||||||
|
|
||||||
|
static long
|
||||||
|
adjust_blocks (blocks, fromsize, tosize)
|
||||||
|
long blocks;
|
||||||
|
int fromsize, tosize;
|
||||||
|
{
|
||||||
|
if (fromsize == tosize) /* E.g., from 512 to 512. */
|
||||||
|
return blocks;
|
||||||
|
else if (fromsize > tosize) /* E.g., from 2048 to 512. */
|
||||||
|
return blocks * (fromsize / tosize);
|
||||||
|
else /* E.g., from 256 to 512. */
|
||||||
|
return (blocks + 1) / (tosize / fromsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Fill in the fields of FSP with information about space usage for
|
||||||
|
the filesystem on which PATH resides.
|
||||||
|
DISK is the device on which PATH is mounted, for space-getting
|
||||||
|
methods that need to know it.
|
||||||
|
Return 0 if successful, -1 if not. */
|
||||||
|
|
||||||
|
int
|
||||||
|
get_fs_usage (path, disk, fsp)
|
||||||
|
char *path, *disk;
|
||||||
|
struct fs_usage *fsp;
|
||||||
|
{
|
||||||
|
#if STAT_NONE
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS2_FS_DATA /* Ultrix. */
|
||||||
|
struct fs_data fsd;
|
||||||
|
|
||||||
|
if (statfs (path, &fsd) != 1)
|
||||||
|
return -1;
|
||||||
|
#define convert_blocks(b) adjust_blocks ((b), 1024, 512)
|
||||||
|
fsp->fsu_blocks = convert_blocks (fsd.fd_req.btot);
|
||||||
|
fsp->fsu_bfree = convert_blocks (fsd.fd_req.bfree);
|
||||||
|
fsp->fsu_bavail = convert_blocks (fsd.fd_req.bfreen);
|
||||||
|
fsp->fsu_files = fsd.fd_req.gtot;
|
||||||
|
fsp->fsu_ffree = fsd.fd_req.gfree;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */
|
||||||
|
struct statfs fsd;
|
||||||
|
|
||||||
|
if (statfs (path, &fsd) < 0)
|
||||||
|
return -1;
|
||||||
|
#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS2_FSIZE /* 4.4BSD. */
|
||||||
|
struct statfs fsd;
|
||||||
|
|
||||||
|
if (statfs (path, &fsd) < 0)
|
||||||
|
return -1;
|
||||||
|
#define convert_blocks(b) adjust_blocks ((b), fsd.f_fsize, 512)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATFS4 /* SVR3, Dynix, Irix. */
|
||||||
|
struct statfs fsd;
|
||||||
|
|
||||||
|
if (statfs (path, &fsd, sizeof fsd, 0) < 0)
|
||||||
|
return -1;
|
||||||
|
/* Empirically, the block counts on most SVR3 and SVR3-derived
|
||||||
|
systems seem to always be in terms of 512-byte blocks,
|
||||||
|
no matter what value f_bsize has. */
|
||||||
|
#define convert_blocks(b) (b)
|
||||||
|
#ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */
|
||||||
|
#define f_bavail f_bfree
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_STATVFS /* SVR4. */
|
||||||
|
struct statvfs fsd;
|
||||||
|
|
||||||
|
if (statvfs (path, &fsd) < 0)
|
||||||
|
return -1;
|
||||||
|
/* f_frsize isn't guaranteed to be supported. */
|
||||||
|
#define convert_blocks(b) \
|
||||||
|
adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STAT_USTAT
|
||||||
|
{
|
||||||
|
struct stat sstat;
|
||||||
|
struct ustat s;
|
||||||
|
|
||||||
|
if (stat (path, &sstat) < 0
|
||||||
|
|| ustat (sstat.st_dev, &s) < 0)
|
||||||
|
return -1;
|
||||||
|
fsp->fsu_blocks = -1;
|
||||||
|
fsp->fsu_bfree = f_tfree;
|
||||||
|
fsp->fsu_bavail = f_tfree;
|
||||||
|
fsp->fsu_files = -1;
|
||||||
|
fsp->fsu_ffree = -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! STAT_STATFS2_FS_DATA /* ! Ultrix */
|
||||||
|
#if ! STAT_USTAT
|
||||||
|
#if ! STAT_NONE
|
||||||
|
fsp->fsu_blocks = convert_blocks (fsd.f_blocks);
|
||||||
|
fsp->fsu_bfree = convert_blocks (fsd.f_bfree);
|
||||||
|
fsp->fsu_bavail = convert_blocks (fsd.f_bavail);
|
||||||
|
fsp->fsu_files = fsd.f_files;
|
||||||
|
fsp->fsu_ffree = fsd.f_ffree;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _AIX
|
||||||
|
#ifdef _I386
|
||||||
|
/* AIX PS/2 does not supply statfs. */
|
||||||
|
|
||||||
|
int
|
||||||
|
statfs (path, fsb)
|
||||||
|
char *path;
|
||||||
|
struct statfs *fsb;
|
||||||
|
{
|
||||||
|
struct stat stats;
|
||||||
|
struct dustat fsd;
|
||||||
|
|
||||||
|
if (stat (path, &stats))
|
||||||
|
return -1;
|
||||||
|
if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd)))
|
||||||
|
return -1;
|
||||||
|
fsb->f_type = 0;
|
||||||
|
fsb->f_bsize = fsd.du_bsize;
|
||||||
|
fsb->f_blocks = fsd.du_fsize - fsd.du_isize;
|
||||||
|
fsb->f_bfree = fsd.du_tfree;
|
||||||
|
fsb->f_bavail = fsd.du_tfree;
|
||||||
|
fsb->f_files = (fsd.du_isize - 2) * fsd.du_inopb;
|
||||||
|
fsb->f_ffree = fsd.du_tinode;
|
||||||
|
fsb->f_fsid.val[0] = fsd.du_site;
|
||||||
|
fsb->f_fsid.val[1] = fsd.du_pckno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _AIX && _I386 */
|
31
gnu/libexec/uucp/libunix/fsusg.h
Normal file
31
gnu/libexec/uucp/libunix/fsusg.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* fsusage.h -- declarations for filesystem space usage info
|
||||||
|
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
any later version.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
This files was modified slightly by Ian Lance Taylor for use with
|
||||||
|
Taylor UUCP. */
|
||||||
|
|
||||||
|
/* Space usage statistics for a filesystem. Blocks are 512-byte. */
|
||||||
|
struct fs_usage
|
||||||
|
{
|
||||||
|
long fsu_blocks; /* Total blocks. */
|
||||||
|
long fsu_bfree; /* Free blocks available to superuser. */
|
||||||
|
long fsu_bavail; /* Free blocks available to non-superuser. */
|
||||||
|
long fsu_files; /* Total file nodes. */
|
||||||
|
long fsu_ffree; /* Free file nodes. */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int get_fs_usage P((char *path, char *disk, struct fs_usage *fsp));
|
250
gnu/libexec/uucp/libunix/ftw.c
Normal file
250
gnu/libexec/uucp/libunix/ftw.c
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ian Lance Taylor (ian@airs.com).
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library 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
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||||
|
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||||
|
Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Modified by Ian Lanc Taylor for Taylor UUCP, June 1992. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SYS_PARAM_H
|
||||||
|
#include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_OPENDIR
|
||||||
|
#if HAVE_DIRENT_H
|
||||||
|
#include <dirent.h>
|
||||||
|
#else /* ! HAVE_DIRENT_H */
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#define dirent direct
|
||||||
|
#endif /* ! HAVE_DIRENT_H */
|
||||||
|
#endif /* HAVE_OPENDIR */
|
||||||
|
|
||||||
|
#if HAVE_FTW_H
|
||||||
|
#include <ftw.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef MAXPATHLEN
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Traverse one level of a directory tree. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
ftw_dir (dirs, level, descriptors, dir, len, func)
|
||||||
|
DIR **dirs;
|
||||||
|
int level;
|
||||||
|
int descriptors;
|
||||||
|
char *dir;
|
||||||
|
size_t len;
|
||||||
|
int (*func) P((const char *file, const struct stat *status, int flag));
|
||||||
|
{
|
||||||
|
int got;
|
||||||
|
struct dirent *entry;
|
||||||
|
|
||||||
|
got = 0;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
while ((entry = readdir (dirs[level])) != NULL)
|
||||||
|
{
|
||||||
|
size_t namlen;
|
||||||
|
struct stat s;
|
||||||
|
int flag, ret, newlev;
|
||||||
|
|
||||||
|
++got;
|
||||||
|
|
||||||
|
namlen = strlen (entry->d_name);
|
||||||
|
if (entry->d_name[0] == '.'
|
||||||
|
&& (namlen == 1 ||
|
||||||
|
(namlen == 2 && entry->d_name[1] == '.')))
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (namlen + len + 1 > PATH_MAX)
|
||||||
|
{
|
||||||
|
#ifdef ENAMETOOLONG
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
#else
|
||||||
|
errno = ENOMEM;
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir[len] = '/';
|
||||||
|
memcpy ((dir + len + 1), entry->d_name, namlen + 1);
|
||||||
|
|
||||||
|
if (stat (dir, &s) < 0)
|
||||||
|
{
|
||||||
|
if (errno != EACCES)
|
||||||
|
return -1;
|
||||||
|
flag = FTW_NS;
|
||||||
|
}
|
||||||
|
else if (S_ISDIR (s.st_mode))
|
||||||
|
{
|
||||||
|
newlev = (level + 1) % descriptors;
|
||||||
|
|
||||||
|
if (dirs[newlev] != NULL)
|
||||||
|
closedir (dirs[newlev]);
|
||||||
|
|
||||||
|
dirs[newlev] = opendir (dir);
|
||||||
|
if (dirs[newlev] != NULL)
|
||||||
|
flag = FTW_D;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (errno != EACCES)
|
||||||
|
return -1;
|
||||||
|
flag = FTW_DNR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flag = FTW_F;
|
||||||
|
|
||||||
|
ret = (*func) (dir, &s, flag);
|
||||||
|
|
||||||
|
if (flag == FTW_D)
|
||||||
|
{
|
||||||
|
if (ret == 0)
|
||||||
|
ret = ftw_dir (dirs, newlev, descriptors, dir,
|
||||||
|
namlen + len + 1, func);
|
||||||
|
if (dirs[newlev] != NULL)
|
||||||
|
{
|
||||||
|
int save;
|
||||||
|
|
||||||
|
save = errno;
|
||||||
|
closedir (dirs[newlev]);
|
||||||
|
errno = save;
|
||||||
|
dirs[newlev] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (dirs[level] == NULL)
|
||||||
|
{
|
||||||
|
int skip;
|
||||||
|
|
||||||
|
dir[len] = '\0';
|
||||||
|
dirs[level] = opendir (dir);
|
||||||
|
if (dirs[level] == NULL)
|
||||||
|
return -1;
|
||||||
|
skip = got;
|
||||||
|
while (skip-- != 0)
|
||||||
|
{
|
||||||
|
errno = 0;
|
||||||
|
if (readdir (dirs[level]) == NULL)
|
||||||
|
return errno == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errno == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call a function on every element in a directory tree. */
|
||||||
|
|
||||||
|
int
|
||||||
|
ftw (dir, func, descriptors)
|
||||||
|
const char *dir;
|
||||||
|
int (*func) P((const char *file, const struct stat *status, int flag));
|
||||||
|
int descriptors;
|
||||||
|
{
|
||||||
|
DIR **dirs;
|
||||||
|
int c;
|
||||||
|
DIR **p;
|
||||||
|
size_t len;
|
||||||
|
char buf[PATH_MAX + 1];
|
||||||
|
struct stat s;
|
||||||
|
int flag, ret;
|
||||||
|
|
||||||
|
if (descriptors <= 0)
|
||||||
|
descriptors = 1;
|
||||||
|
|
||||||
|
dirs = (DIR **) malloc (descriptors * sizeof (DIR *));
|
||||||
|
if (dirs == NULL)
|
||||||
|
return -1;
|
||||||
|
c = descriptors;
|
||||||
|
p = dirs;
|
||||||
|
while (c-- != 0)
|
||||||
|
*p++ = NULL;
|
||||||
|
|
||||||
|
len = strlen (dir);
|
||||||
|
memcpy (buf, dir, len + 1);
|
||||||
|
|
||||||
|
if (stat (dir, &s) < 0)
|
||||||
|
{
|
||||||
|
if (errno != EACCES)
|
||||||
|
{
|
||||||
|
free ((pointer) dirs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
flag = FTW_NS;
|
||||||
|
}
|
||||||
|
else if (S_ISDIR (s.st_mode))
|
||||||
|
{
|
||||||
|
dirs[0] = opendir (dir);
|
||||||
|
if (dirs[0] != NULL)
|
||||||
|
flag = FTW_D;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (errno != EACCES)
|
||||||
|
{
|
||||||
|
free ((pointer) dirs);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
flag = FTW_DNR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flag = FTW_F;
|
||||||
|
|
||||||
|
ret = (*func) (buf, &s, flag);
|
||||||
|
|
||||||
|
if (flag == FTW_D)
|
||||||
|
{
|
||||||
|
if (ret == 0)
|
||||||
|
ret = ftw_dir (dirs, 0, descriptors, buf, len, func);
|
||||||
|
if (dirs[0] != NULL)
|
||||||
|
{
|
||||||
|
int save;
|
||||||
|
|
||||||
|
save = errno;
|
||||||
|
closedir (dirs[0]);
|
||||||
|
errno = save;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free ((pointer) dirs);
|
||||||
|
return ret;
|
||||||
|
}
|
59
gnu/libexec/uucp/libunix/getcwd.c
Normal file
59
gnu/libexec/uucp/libunix/getcwd.c
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* getcwd.c
|
||||||
|
Replacement for the getcwd function that just calls /bin/pwd. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
char *
|
||||||
|
getcwd (zbuf, cbuf)
|
||||||
|
char *zbuf;
|
||||||
|
size_t cbuf;
|
||||||
|
{
|
||||||
|
const char *azargs[2];
|
||||||
|
FILE *e;
|
||||||
|
pid_t ipid;
|
||||||
|
int cread;
|
||||||
|
int ierr;
|
||||||
|
|
||||||
|
azargs[0] = PWD_PROGRAM;
|
||||||
|
azargs[1] = NULL;
|
||||||
|
e = espopen (azargs, TRUE, &ipid);
|
||||||
|
if (e == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ierr = 0;
|
||||||
|
|
||||||
|
cread = fread (zbuf, sizeof (char), cbuf, e);
|
||||||
|
if (cread == 0)
|
||||||
|
ierr = errno;
|
||||||
|
|
||||||
|
(void) fclose (e);
|
||||||
|
|
||||||
|
if (ixswait ((unsigned long) ipid, (const char *) NULL) != 0)
|
||||||
|
{
|
||||||
|
ierr = EACCES;
|
||||||
|
cread = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cread != 0)
|
||||||
|
{
|
||||||
|
if (zbuf[cread - 1] == '\n')
|
||||||
|
zbuf[cread - 1] = '\0';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ierr = ERANGE;
|
||||||
|
cread = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cread == 0)
|
||||||
|
{
|
||||||
|
errno = ierr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return zbuf;
|
||||||
|
}
|
133
gnu/libexec/uucp/libunix/indir.c
Normal file
133
gnu/libexec/uucp/libunix/indir.c
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/* indir.c
|
||||||
|
See if a file is in a directory.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* See whether a file is in a directory, and optionally check access. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_in_directory (zfile, zdir, fcheck, freadable, zuser)
|
||||||
|
const char *zfile;
|
||||||
|
const char *zdir;
|
||||||
|
boolean fcheck;
|
||||||
|
boolean freadable;
|
||||||
|
const char *zuser;
|
||||||
|
{
|
||||||
|
size_t c;
|
||||||
|
char *zcopy, *zslash;
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (*zfile != '/')
|
||||||
|
return FALSE;
|
||||||
|
c = strlen (zdir);
|
||||||
|
if (c > 0 && zdir[c - 1] == '/')
|
||||||
|
c--;
|
||||||
|
if (strncmp (zfile, zdir, c) != 0
|
||||||
|
|| (zfile[c] != '/' && zfile[c] != '\0'))
|
||||||
|
return FALSE;
|
||||||
|
if (strstr (zfile + c, "/../") != NULL)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* If we're not checking access, get out now. */
|
||||||
|
if (! fcheck)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
zcopy = zbufcpy (zfile);
|
||||||
|
|
||||||
|
/* Start checking directories after zdir. Otherwise, we would
|
||||||
|
require that all directories down to /usr/spool/uucppublic be
|
||||||
|
publically searchable; they probably are but it should not be a
|
||||||
|
requirement. */
|
||||||
|
zslash = zcopy + c;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char b;
|
||||||
|
struct stat shold;
|
||||||
|
|
||||||
|
b = *zslash;
|
||||||
|
*zslash = '\0';
|
||||||
|
|
||||||
|
shold = s;
|
||||||
|
if (stat (zcopy, &s) != 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno));
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is the top directory, any problems will be caught
|
||||||
|
later when we try to open it. */
|
||||||
|
if (zslash == zcopy + c)
|
||||||
|
{
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go back and check the last directory for read or write
|
||||||
|
access. */
|
||||||
|
s = shold;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is not a directory, get out of the loop. */
|
||||||
|
if (! S_ISDIR (s.st_mode))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Make sure the directory is searchable. */
|
||||||
|
if (! fsuser_access (&s, X_OK, zuser))
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we've reached the end of the string, get out. */
|
||||||
|
if (b == '\0')
|
||||||
|
break;
|
||||||
|
|
||||||
|
*zslash = b;
|
||||||
|
}
|
||||||
|
while ((zslash = strchr (zslash + 1, '/')) != NULL);
|
||||||
|
|
||||||
|
/* At this point s holds a stat on the last component of the path.
|
||||||
|
We must check it for readability or writeability. */
|
||||||
|
if (! fsuser_access (&s, freadable ? R_OK : W_OK, zuser))
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return TRUE;
|
||||||
|
}
|
394
gnu/libexec/uucp/libunix/init.c
Normal file
394
gnu/libexec/uucp/libunix/init.c
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
/* init.c
|
||||||
|
Initialize the system dependent routines.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ! HAVE_GETHOSTNAME && HAVE_UNAME
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Use getcwd in preference to getwd; if we have neither, we will be
|
||||||
|
using a getcwd replacement. */
|
||||||
|
#if HAVE_GETCWD
|
||||||
|
#undef HAVE_GETWD
|
||||||
|
#define HAVE_GETWD 0
|
||||||
|
#else /* ! HAVE_GETCWD */
|
||||||
|
#if ! HAVE_GETWD
|
||||||
|
#undef HAVE_GETCWD
|
||||||
|
#define HAVE_GETCWD 1
|
||||||
|
#endif /* ! HAVE_GETWD */
|
||||||
|
#endif /* ! HAVE_GETCWD */
|
||||||
|
|
||||||
|
#if HAVE_GETWD
|
||||||
|
/* Get a value for MAXPATHLEN. */
|
||||||
|
#if HAVE_SYS_PARAMS_H
|
||||||
|
#include <sys/params.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
#ifdef PATH_MAX
|
||||||
|
#define MAXPATHLEN PATH_MAX
|
||||||
|
#else /* ! defined (PATH_MAX) */
|
||||||
|
#define MAXPATHLEN 1024
|
||||||
|
#endif /* ! defined (PATH_MAX) */
|
||||||
|
#endif /* ! defined (MAXPATHLEN) */
|
||||||
|
#endif /* HAVE_GETWD */
|
||||||
|
|
||||||
|
/* External functions. */
|
||||||
|
#ifndef getlogin
|
||||||
|
extern char *getlogin ();
|
||||||
|
#endif
|
||||||
|
#if GETPWNAM_DECLARATION_OK
|
||||||
|
#ifndef getpwnam
|
||||||
|
extern struct passwd *getpwnam ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if GETPWUID_DECLARATION_OK
|
||||||
|
#ifndef getpwuid
|
||||||
|
extern struct passwd *getpwuid ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if HAVE_GETCWD
|
||||||
|
#ifndef getcwd
|
||||||
|
extern char *getcwd ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if HAVE_GETWD
|
||||||
|
#ifndef getwd
|
||||||
|
extern char *getwd ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if HAVE_SYSCONF
|
||||||
|
#ifndef sysconf
|
||||||
|
extern long sysconf ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize the system dependent routines. We will probably be running
|
||||||
|
suid to uucp, so we make sure that nothing is obviously wrong. We
|
||||||
|
save the login name since we will be losing the real uid. */
|
||||||
|
static char *zSlogin;
|
||||||
|
|
||||||
|
/* The UUCP spool directory. */
|
||||||
|
const char *zSspooldir;
|
||||||
|
|
||||||
|
/* The UUCP lock directory. */
|
||||||
|
const char *zSlockdir;
|
||||||
|
|
||||||
|
/* The local UUCP name. */
|
||||||
|
const char *zSlocalname;
|
||||||
|
|
||||||
|
/* We save the current directory since we will do a chdir to the
|
||||||
|
spool directory. */
|
||||||
|
char *zScwd;
|
||||||
|
|
||||||
|
/* The maximum length of a system name is controlled by the type of spool
|
||||||
|
directory we use. */
|
||||||
|
#if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX
|
||||||
|
size_t cSysdep_max_name_len = 7;
|
||||||
|
#endif
|
||||||
|
#if SPOOLDIR_HDB || SPOOLDIR_SVR4
|
||||||
|
size_t cSysdep_max_name_len = 14;
|
||||||
|
#endif
|
||||||
|
#if SPOOLDIR_TAYLOR
|
||||||
|
#if HAVE_LONG_FILE_NAMES
|
||||||
|
size_t cSysdep_max_name_len = 255;
|
||||||
|
#else /* ! HAVE_LONG_FILE_NAMES */
|
||||||
|
size_t cSysdep_max_name_len = 14;
|
||||||
|
#endif /* ! HAVE_LONG_FILE_NAMES */
|
||||||
|
#endif /* SPOOLDIR_TAYLOR */
|
||||||
|
|
||||||
|
/* Initialize the system dependent routines. */
|
||||||
|
|
||||||
|
void
|
||||||
|
usysdep_initialize (puuconf,iflags)
|
||||||
|
pointer puuconf;
|
||||||
|
int iflags;
|
||||||
|
{
|
||||||
|
int cdescs;
|
||||||
|
int o;
|
||||||
|
int iuuconf;
|
||||||
|
char *z;
|
||||||
|
struct passwd *q;
|
||||||
|
|
||||||
|
ulog_id (getpid ());
|
||||||
|
|
||||||
|
/* Close everything but stdin, stdout and stderr. */
|
||||||
|
#if HAVE_GETDTABLESIZE
|
||||||
|
cdescs = getdtablesize ();
|
||||||
|
#else
|
||||||
|
#if HAVE_SYSCONF
|
||||||
|
cdescs = sysconf (_SC_OPEN_MAX);
|
||||||
|
#else
|
||||||
|
#ifdef OPEN_MAX
|
||||||
|
cdescs = OPEN_MAX;
|
||||||
|
#else
|
||||||
|
#ifdef NOFILE
|
||||||
|
cdescs = NOFILE;
|
||||||
|
#else
|
||||||
|
cdescs = 20;
|
||||||
|
#endif /* ! defined (NOFILE) */
|
||||||
|
#endif /* ! defined (OPEN_MAX) */
|
||||||
|
#endif /* ! HAVE_SYSCONF */
|
||||||
|
#endif /* ! HAVE_GETDTABLESIZE */
|
||||||
|
|
||||||
|
for (o = 3; o < cdescs; o++)
|
||||||
|
(void) close (o);
|
||||||
|
|
||||||
|
/* Make sure stdin, stdout and stderr are open. */
|
||||||
|
if (fcntl (0, F_GETFD, 0) < 0
|
||||||
|
&& open ((char *) "/dev/null", O_RDONLY, 0) != 0)
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
if (fcntl (1, F_GETFD, 0) < 0
|
||||||
|
&& open ((char *) "/dev/null", O_WRONLY, 0) != 1)
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
if (fcntl (2, F_GETFD, 0) < 0
|
||||||
|
&& open ((char *) "/dev/null", O_WRONLY, 0) != 2)
|
||||||
|
exit (EXIT_FAILURE);
|
||||||
|
|
||||||
|
iuuconf = uuconf_spooldir (puuconf, &zSspooldir);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
iuuconf = uuconf_lockdir (puuconf, &zSlockdir);
|
||||||
|
if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
iuuconf = uuconf_localname (puuconf, &zSlocalname);
|
||||||
|
if (iuuconf == UUCONF_NOT_FOUND)
|
||||||
|
{
|
||||||
|
#if HAVE_GETHOSTNAME
|
||||||
|
char ab[256];
|
||||||
|
|
||||||
|
if (gethostname (ab, sizeof ab - 1) < 0)
|
||||||
|
ulog (LOG_FATAL, "gethostname: %s", strerror (errno));
|
||||||
|
ab[sizeof ab - 1] = '\0';
|
||||||
|
ab[strcspn (ab, ".")] = '\0';
|
||||||
|
zSlocalname = zbufcpy (ab);
|
||||||
|
#else /* ! HAVE_GETHOSTNAME */
|
||||||
|
#if HAVE_UNAME
|
||||||
|
struct utsname s;
|
||||||
|
|
||||||
|
if (uname (&s) < 0)
|
||||||
|
ulog (LOG_FATAL, "uname: %s", strerror (errno));
|
||||||
|
zSlocalname = zbufcpy (s.nodename);
|
||||||
|
#else /* ! HAVE_UNAME */
|
||||||
|
ulog (LOG_FATAL, "Don't know how to get local node name");
|
||||||
|
#endif /* ! HAVE_UNAME */
|
||||||
|
#endif /* ! HAVE_GETHOSTNAME */
|
||||||
|
}
|
||||||
|
else if (iuuconf != UUCONF_SUCCESS)
|
||||||
|
ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
|
||||||
|
|
||||||
|
/* We always set our file modes to exactly what we want. */
|
||||||
|
umask (0);
|
||||||
|
|
||||||
|
/* Get the login name, making sure that it matches the uid. Many
|
||||||
|
systems truncate the getlogin return value to 8 characters, but
|
||||||
|
keep the full name in the password file, so we prefer the name in
|
||||||
|
the password file. */
|
||||||
|
z = getenv ("LOGNAME");
|
||||||
|
if (z == NULL)
|
||||||
|
z = getenv ("USER");
|
||||||
|
if (z == NULL)
|
||||||
|
z = getlogin ();
|
||||||
|
if (z == NULL)
|
||||||
|
q = NULL;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
q = getpwnam (z);
|
||||||
|
if (q != NULL)
|
||||||
|
z = q->pw_name;
|
||||||
|
}
|
||||||
|
if (q == NULL || q->pw_uid != getuid ())
|
||||||
|
{
|
||||||
|
q = getpwuid (getuid ());
|
||||||
|
if (q == NULL)
|
||||||
|
z = NULL;
|
||||||
|
else
|
||||||
|
z = q->pw_name;
|
||||||
|
}
|
||||||
|
if (z != NULL)
|
||||||
|
zSlogin = zbufcpy (z);
|
||||||
|
|
||||||
|
/* On some old systems, an suid program run by root is started with
|
||||||
|
an euid of 0. If this happens, we look up the uid we should have
|
||||||
|
and set ourselves to it manually. This means that on such a
|
||||||
|
system root will not be able to uucp or uux files that are not
|
||||||
|
readable by uucp. */
|
||||||
|
if ((iflags & INIT_SUID) != 0
|
||||||
|
&& geteuid () == 0)
|
||||||
|
{
|
||||||
|
q = getpwnam (OWNER);
|
||||||
|
if (q != NULL)
|
||||||
|
setuid (q->pw_uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((iflags & INIT_GETCWD) != 0)
|
||||||
|
{
|
||||||
|
const char *zenv;
|
||||||
|
struct stat senv, sdot;
|
||||||
|
|
||||||
|
/* Get the current working directory. We have to get it now,
|
||||||
|
since we're about to do a chdir. We use PWD if it's defined
|
||||||
|
and if it really names the working directory, since if it's
|
||||||
|
not the same as whatever getcwd returns it's probably more
|
||||||
|
appropriate. */
|
||||||
|
zenv = getenv ("PWD");
|
||||||
|
if (zenv != NULL
|
||||||
|
&& stat ((char *) zenv, &senv) == 0
|
||||||
|
&& stat ((char *) ".", &sdot) == 0
|
||||||
|
&& senv.st_ino == sdot.st_ino
|
||||||
|
&& senv.st_dev == sdot.st_dev)
|
||||||
|
zScwd = zbufcpy (zenv);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
#if HAVE_GETCWD
|
||||||
|
{
|
||||||
|
size_t c;
|
||||||
|
|
||||||
|
c = 128;
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
zScwd = (char *) xmalloc (c);
|
||||||
|
if (getcwd (zScwd, c) != NULL)
|
||||||
|
break;
|
||||||
|
xfree ((pointer) zScwd);
|
||||||
|
zScwd = NULL;
|
||||||
|
if (errno != ERANGE)
|
||||||
|
break;
|
||||||
|
c <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_GETCWD */
|
||||||
|
|
||||||
|
#if HAVE_GETWD
|
||||||
|
zScwd = (char *) xmalloc (MAXPATHLEN);
|
||||||
|
if (getwd (zScwd) == NULL)
|
||||||
|
{
|
||||||
|
xfree ((pointer) zScwd);
|
||||||
|
zScwd = NULL;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_GETWD */
|
||||||
|
|
||||||
|
if (zScwd != NULL)
|
||||||
|
zScwd = (char *) xrealloc ((pointer) zScwd,
|
||||||
|
strlen (zScwd) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((iflags & INIT_NOCHDIR) == 0)
|
||||||
|
{
|
||||||
|
/* Connect to the spool directory, and create it if it doesn't
|
||||||
|
exist. */
|
||||||
|
if (chdir (zSspooldir) < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT
|
||||||
|
&& mkdir ((char *) zSspooldir, IDIRECTORY_MODE) < 0)
|
||||||
|
ulog (LOG_FATAL, "mkdir (%s): %s", zSspooldir,
|
||||||
|
strerror (errno));
|
||||||
|
if (chdir (zSspooldir) < 0)
|
||||||
|
ulog (LOG_FATAL, "chdir (%s): %s", zSspooldir,
|
||||||
|
strerror (errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit the program. */
|
||||||
|
|
||||||
|
void
|
||||||
|
usysdep_exit (fsuccess)
|
||||||
|
boolean fsuccess;
|
||||||
|
{
|
||||||
|
exit (fsuccess ? EXIT_SUCCESS : EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is called when a non-standard configuration file is used, to
|
||||||
|
make sure the program doesn't hand out privileged file access.
|
||||||
|
This means that to test non-standard configuration files, you
|
||||||
|
should be logged in as uucp. This is called before
|
||||||
|
usysdep_initialize. It ensures that someone can't simply use an
|
||||||
|
alternate configuration file to steal UUCP transfers from other
|
||||||
|
systems. This will still permit people to set up their own
|
||||||
|
configuration file and pretend to be whatever system they choose.
|
||||||
|
The only real security is to use a high level of protection on the
|
||||||
|
modem ports. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean fsysdep_other_config (z)
|
||||||
|
const char *z;
|
||||||
|
{
|
||||||
|
(void) setuid (getuid ());
|
||||||
|
(void) setgid (getgid ());
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the node name to use if it was not specified in the configuration
|
||||||
|
file. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
zsysdep_localname ()
|
||||||
|
{
|
||||||
|
return zSlocalname;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the login name. We actually get the login name in
|
||||||
|
usysdep_initialize, because after that we may switch away from the
|
||||||
|
real uid. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
zsysdep_login_name ()
|
||||||
|
{
|
||||||
|
if (zSlogin == NULL)
|
||||||
|
ulog (LOG_FATAL, "Can't get login name");
|
||||||
|
return zSlogin;
|
||||||
|
}
|
18
gnu/libexec/uucp/libunix/isdir.c
Normal file
18
gnu/libexec/uucp/libunix/isdir.c
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* isdir.c
|
||||||
|
See whether a file exists and is a directory. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_directory (z)
|
||||||
|
const char *z;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (stat ((char *) z, &s) < 0)
|
||||||
|
return FALSE;
|
||||||
|
return S_ISDIR (s.st_mode);
|
||||||
|
}
|
25
gnu/libexec/uucp/libunix/isfork.c
Normal file
25
gnu/libexec/uucp/libunix/isfork.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* isfork.c
|
||||||
|
Retry fork several times before giving up. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
ixsfork ()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
pid_t iret;
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
iret = fork ();
|
||||||
|
if (iret >= 0 || errno != EAGAIN)
|
||||||
|
return iret;
|
||||||
|
sleep (5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iret;
|
||||||
|
}
|
159
gnu/libexec/uucp/libunix/iswait.c
Normal file
159
gnu/libexec/uucp/libunix/iswait.c
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/* iswait.c
|
||||||
|
Wait for a process to finish.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_SYS_WAIT_H
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We use a typedef wait_status for wait (waitpid, wait4) to put
|
||||||
|
results into. We define the POSIX examination functions we need if
|
||||||
|
they are not already defined (if they aren't defined, I assume that
|
||||||
|
we have a standard wait status). */
|
||||||
|
|
||||||
|
#if HAVE_UNION_WAIT
|
||||||
|
typedef union wait wait_status;
|
||||||
|
#ifndef WIFEXITED
|
||||||
|
#define WIFEXITED(u) ((u).w_termsig == 0)
|
||||||
|
#endif
|
||||||
|
#ifndef WEXITSTATUS
|
||||||
|
#define WEXITSTATUS(u) ((u).w_retcode)
|
||||||
|
#endif
|
||||||
|
#ifndef WTERMSIG
|
||||||
|
#define WTERMSIG(u) ((u).w_termsig)
|
||||||
|
#endif
|
||||||
|
#else /* ! HAVE_UNION_WAIT */
|
||||||
|
typedef int wait_status;
|
||||||
|
#ifndef WIFEXITED
|
||||||
|
#define WIFEXITED(i) (((i) & 0xff) == 0)
|
||||||
|
#endif
|
||||||
|
#ifndef WEXITSTATUS
|
||||||
|
#define WEXITSTATUS(i) (((i) >> 8) & 0xff)
|
||||||
|
#endif
|
||||||
|
#ifndef WTERMSIG
|
||||||
|
#define WTERMSIG(i) ((i) & 0x7f)
|
||||||
|
#endif
|
||||||
|
#endif /* ! HAVE_UNION_WAIT */
|
||||||
|
|
||||||
|
/* Wait for a particular process to finish. The ipid argument should
|
||||||
|
be pid_t, but then we couldn't have a prototype. If the zreport
|
||||||
|
argument is not NULL, then a wait error will be logged, and if the
|
||||||
|
exit status is non-zero it will be logged with zreport as the
|
||||||
|
header of the log message. If the zreport argument is NULL, no
|
||||||
|
errors will be logged. This function returns the exit status if
|
||||||
|
the process exited normally, or -1 on error or if the process was
|
||||||
|
killed by a signal (I don't just always return the exit status
|
||||||
|
because then the calling code would have to prepared to handle
|
||||||
|
union wait status vs. int status, and none of the callers care
|
||||||
|
which signal killed the program anyhow).
|
||||||
|
|
||||||
|
This functions keeps waiting until the process finished, even if it
|
||||||
|
is interrupted by a signal. I think this is right for all uses.
|
||||||
|
The controversial one would be when called from uuxqt to wait for a
|
||||||
|
requested process. Hitting uuxqt with SIGKILL will approximate the
|
||||||
|
actions taken if we return from here with an error anyhow. If we
|
||||||
|
do get a signal, we call ulog with a NULL argument to get it in the
|
||||||
|
log file at about the right time. */
|
||||||
|
|
||||||
|
int
|
||||||
|
ixswait (ipid, zreport)
|
||||||
|
unsigned long ipid;
|
||||||
|
const char *zreport;
|
||||||
|
{
|
||||||
|
wait_status istat;
|
||||||
|
|
||||||
|
#if HAVE_WAITPID
|
||||||
|
while (waitpid ((pid_t) ipid, (pointer) &istat, 0) < 0)
|
||||||
|
{
|
||||||
|
if (errno != EINTR)
|
||||||
|
{
|
||||||
|
if (zreport != NULL)
|
||||||
|
ulog (LOG_ERROR, "waitpid: %s", strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ulog (LOG_ERROR, (const char *) NULL);
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_WAITPID */
|
||||||
|
#if HAVE_WAIT4
|
||||||
|
while (wait4 ((pid_t) ipid, (pointer) &istat, 0,
|
||||||
|
(struct rusage *) NULL) < 0)
|
||||||
|
{
|
||||||
|
if (errno != EINTR)
|
||||||
|
{
|
||||||
|
if (zreport != NULL)
|
||||||
|
ulog (LOG_ERROR, "wait4: %s", strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ulog (LOG_ERROR, (const char *) NULL);
|
||||||
|
}
|
||||||
|
#else /* ! HAVE_WAIT4 */
|
||||||
|
pid_t igot;
|
||||||
|
|
||||||
|
/* We could theoretically get the wrong child here if we're in some
|
||||||
|
kind of weird pipeline, so we don't give any error messages for
|
||||||
|
it. */
|
||||||
|
while ((igot = wait ((pointer) &istat)) != (pid_t) ipid)
|
||||||
|
{
|
||||||
|
if (igot < 0)
|
||||||
|
{
|
||||||
|
if (errno != EINTR)
|
||||||
|
{
|
||||||
|
if (zreport != NULL)
|
||||||
|
ulog (LOG_ERROR, "wait: %s", strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ulog (LOG_ERROR, (const char *) NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ! HAVE_WAIT4 */
|
||||||
|
#endif /* ! HAVE_WAITPID */
|
||||||
|
|
||||||
|
DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d",
|
||||||
|
WIFEXITED (istat) ? "Exit status" : "Signal",
|
||||||
|
WIFEXITED (istat) ? WEXITSTATUS (istat) : WTERMSIG (istat));
|
||||||
|
|
||||||
|
if (WIFEXITED (istat) && WEXITSTATUS (istat) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (zreport != NULL)
|
||||||
|
{
|
||||||
|
if (! WIFEXITED (istat))
|
||||||
|
ulog (LOG_ERROR, "%s: Got signal %d", zreport, WTERMSIG (istat));
|
||||||
|
else
|
||||||
|
ulog (LOG_ERROR, "%s: Exit status %d", zreport,
|
||||||
|
WEXITSTATUS (istat));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIFEXITED (istat))
|
||||||
|
return WEXITSTATUS (istat);
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
101
gnu/libexec/uucp/libunix/jobid.c
Normal file
101
gnu/libexec/uucp/libunix/jobid.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* jobid.c
|
||||||
|
Convert file names to jobids and vice versa.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Translate a file name and an associated system into a job id.
|
||||||
|
These job ids are used by uustat. We use the system name attached
|
||||||
|
to the grade and sequence number. This won't work correctly if the
|
||||||
|
file name was actually created by some other version of uucp that
|
||||||
|
uses a different length for the sequence number. Too bad. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsfile_to_jobid (qsys, zfile, bgrade)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zfile;
|
||||||
|
int bgrade;
|
||||||
|
{
|
||||||
|
size_t clen;
|
||||||
|
char *zret;
|
||||||
|
|
||||||
|
clen = strlen (qsys->uuconf_zname);
|
||||||
|
zret = zbufalc (clen + CSEQLEN + 2);
|
||||||
|
memcpy (zret, qsys->uuconf_zname, clen);
|
||||||
|
zret[clen] = bgrade;
|
||||||
|
memcpy (zret + clen + 1, zfile + strlen (zfile) - CSEQLEN, CSEQLEN + 1);
|
||||||
|
return zret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Turn a job id back into a file name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsjobid_to_file (zid, pzsystem, pbgrade)
|
||||||
|
const char *zid;
|
||||||
|
char **pzsystem;
|
||||||
|
char *pbgrade;
|
||||||
|
{
|
||||||
|
size_t clen;
|
||||||
|
const char *zend;
|
||||||
|
char *zsys;
|
||||||
|
char abname[CSEQLEN + 11];
|
||||||
|
char *zret;
|
||||||
|
|
||||||
|
clen = strlen (zid);
|
||||||
|
if (clen <= CSEQLEN)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: Bad job id", zid);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zend = zid + clen - CSEQLEN - 1;
|
||||||
|
|
||||||
|
zsys = zbufalc (clen - CSEQLEN);
|
||||||
|
memcpy (zsys, zid, clen - CSEQLEN - 1);
|
||||||
|
zsys[clen - CSEQLEN - 1] = '\0';
|
||||||
|
|
||||||
|
/* This must correspond to zsfile_name. */
|
||||||
|
#if ! SPOOLDIR_TAYLOR
|
||||||
|
sprintf (abname, "C.%.7s%s", zsys, zend);
|
||||||
|
#else
|
||||||
|
sprintf (abname, "C.%s", zend);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zret = zsfind_file (abname, zsys, *zend);
|
||||||
|
|
||||||
|
if (zret != NULL && pzsystem != NULL)
|
||||||
|
*pzsystem = zsys;
|
||||||
|
else
|
||||||
|
ubuffree (zsys);
|
||||||
|
|
||||||
|
if (pbgrade != NULL)
|
||||||
|
*pbgrade = *zend;
|
||||||
|
|
||||||
|
return zret;
|
||||||
|
}
|
41
gnu/libexec/uucp/libunix/lcksys.c
Normal file
41
gnu/libexec/uucp/libunix/lcksys.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/* lcksys.c
|
||||||
|
Lock and unlock a remote system. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Lock a remote system. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_lock_system (qsys)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
{
|
||||||
|
char *z;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
z = zbufalc (strlen (qsys->uuconf_zname) + sizeof "LCK..");
|
||||||
|
sprintf (z, "LCK..%.8s", qsys->uuconf_zname);
|
||||||
|
fret = fsdo_lock (z, FALSE, (boolean *) NULL);
|
||||||
|
ubuffree (z);
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock a remote system. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_unlock_system (qsys)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
{
|
||||||
|
char *z;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
z = zbufalc (strlen (qsys->uuconf_zname) + sizeof "LCK..");
|
||||||
|
sprintf (z, "LCK..%.8s", qsys->uuconf_zname);
|
||||||
|
fret = fsdo_unlock (z, FALSE);
|
||||||
|
ubuffree (z);
|
||||||
|
return fret;
|
||||||
|
}
|
38
gnu/libexec/uucp/libunix/link.c
Normal file
38
gnu/libexec/uucp/libunix/link.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* link.c
|
||||||
|
Link two files. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_link (zfrom, zto, pfworked)
|
||||||
|
const char *zfrom;
|
||||||
|
const char *zto;
|
||||||
|
boolean *pfworked;
|
||||||
|
{
|
||||||
|
*pfworked = FALSE;
|
||||||
|
if (link (zfrom, zto) == 0)
|
||||||
|
{
|
||||||
|
*pfworked = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zto, TRUE))
|
||||||
|
return FALSE;
|
||||||
|
if (link (zfrom, zto) == 0)
|
||||||
|
{
|
||||||
|
*pfworked = TRUE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno == EXDEV)
|
||||||
|
return TRUE;
|
||||||
|
ulog (LOG_ERROR, "link (%s, %s): %s", zfrom, zto, strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
95
gnu/libexec/uucp/libunix/locfil.c
Normal file
95
gnu/libexec/uucp/libunix/locfil.c
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/* locfil.c
|
||||||
|
Expand a file name on the local system.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#if GETPWNAM_DECLARATION_OK
|
||||||
|
#ifndef getpwnam
|
||||||
|
extern struct passwd *getpwnam ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Turn a file name into an absolute path, by doing tilde expansion
|
||||||
|
and moving any other type of file into the public directory. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_local_file (zfile, zpubdir)
|
||||||
|
const char *zfile;
|
||||||
|
const char *zpubdir;
|
||||||
|
{
|
||||||
|
const char *zdir;
|
||||||
|
|
||||||
|
if (*zfile == '/')
|
||||||
|
return zbufcpy (zfile);
|
||||||
|
|
||||||
|
if (*zfile != '~')
|
||||||
|
zdir = zpubdir;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (zfile[1] == '\0')
|
||||||
|
return zbufcpy (zpubdir);
|
||||||
|
|
||||||
|
if (zfile[1] == '/')
|
||||||
|
{
|
||||||
|
zdir = zpubdir;
|
||||||
|
zfile += 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t cuserlen;
|
||||||
|
char *zcopy;
|
||||||
|
struct passwd *q;
|
||||||
|
|
||||||
|
++zfile;
|
||||||
|
cuserlen = strcspn ((char *) zfile, "/");
|
||||||
|
zcopy = zbufalc (cuserlen + 1);
|
||||||
|
memcpy (zcopy, zfile, cuserlen);
|
||||||
|
zcopy[cuserlen] = '\0';
|
||||||
|
|
||||||
|
q = getpwnam (zcopy);
|
||||||
|
if (q == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "User %s not found", zcopy);
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ubuffree (zcopy);
|
||||||
|
|
||||||
|
if (zfile[cuserlen] == '\0')
|
||||||
|
return zbufcpy (q->pw_dir);
|
||||||
|
|
||||||
|
zdir = q->pw_dir;
|
||||||
|
zfile += cuserlen + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return zsysdep_in_dir (zdir, zfile);
|
||||||
|
}
|
477
gnu/libexec/uucp/libunix/lock.c
Normal file
477
gnu/libexec/uucp/libunix/lock.c
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
/* lock.c
|
||||||
|
Lock and unlock a file name.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char lock_rcsid[] = "$Id: lock.c,v 1.1 1993/08/04 19:32:33 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
#define SEEK_SET 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Lock something. If the fspooldir argument is TRUE, the argument is
|
||||||
|
a file name relative to the spool directory; otherwise the argument
|
||||||
|
is a simple file name which should be created in the system lock
|
||||||
|
directory (under HDB this is /etc/locks). */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsdo_lock (zlock, fspooldir, pferr)
|
||||||
|
const char *zlock;
|
||||||
|
boolean fspooldir;
|
||||||
|
boolean *pferr;
|
||||||
|
{
|
||||||
|
char *zfree;
|
||||||
|
const char *zpath, *zslash;
|
||||||
|
size_t cslash;
|
||||||
|
pid_t ime;
|
||||||
|
char *ztempfile;
|
||||||
|
char abtempfile[sizeof "TMP1234567890"];
|
||||||
|
int o;
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
int i;
|
||||||
|
#else
|
||||||
|
char ab[12];
|
||||||
|
#endif
|
||||||
|
int cwrote;
|
||||||
|
const char *zerr;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
if (pferr != NULL)
|
||||||
|
*pferr = TRUE;
|
||||||
|
|
||||||
|
if (fspooldir)
|
||||||
|
{
|
||||||
|
zfree = NULL;
|
||||||
|
zpath = zlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zfree = zsysdep_in_dir (zSlockdir, zlock);
|
||||||
|
zpath = zfree;
|
||||||
|
}
|
||||||
|
|
||||||
|
ime = getpid ();
|
||||||
|
|
||||||
|
/* We do the actual lock by creating a file and then linking it to
|
||||||
|
the final file name we want. This avoids race conditions due to
|
||||||
|
one process checking the file before we have finished writing it,
|
||||||
|
and also works even if we are somehow running as root.
|
||||||
|
|
||||||
|
First, create the file in the right directory (we must create the
|
||||||
|
file in the same directory since otherwise we might attempt a
|
||||||
|
cross-device link). */
|
||||||
|
zslash = strrchr (zpath, '/');
|
||||||
|
if (zslash == NULL)
|
||||||
|
cslash = 0;
|
||||||
|
else
|
||||||
|
cslash = zslash - zpath + 1;
|
||||||
|
|
||||||
|
sprintf (abtempfile, "TMP%010lx", (unsigned long) ime);
|
||||||
|
ztempfile = zbufalc (cslash + sizeof abtempfile);
|
||||||
|
memcpy (ztempfile, zpath, cslash);
|
||||||
|
memcpy (ztempfile + cslash, abtempfile, sizeof abtempfile);
|
||||||
|
|
||||||
|
o = creat (ztempfile, IPUBLIC_FILE_MODE);
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (ztempfile, FALSE))
|
||||||
|
{
|
||||||
|
ubuffree (zfree);
|
||||||
|
ubuffree (ztempfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
o = creat (ztempfile, IPUBLIC_FILE_MODE);
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "creat (%s): %s", ztempfile, strerror (errno));
|
||||||
|
ubuffree (zfree);
|
||||||
|
ubuffree (ztempfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
i = ime;
|
||||||
|
cwrote = write (o, &i, sizeof i);
|
||||||
|
#else
|
||||||
|
sprintf (ab, "%10d\n", (int) ime);
|
||||||
|
cwrote = write (o, ab, strlen (ab));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
zerr = NULL;
|
||||||
|
if (cwrote < 0)
|
||||||
|
zerr = "write";
|
||||||
|
if (close (o) < 0)
|
||||||
|
zerr = "close";
|
||||||
|
if (zerr != NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s (%s): %s", zerr, ztempfile, strerror (errno));
|
||||||
|
(void) remove (ztempfile);
|
||||||
|
ubuffree (zfree);
|
||||||
|
ubuffree (ztempfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now try to link the file we just created to the lock file that we
|
||||||
|
want. If it fails, try reading the existing file to make sure
|
||||||
|
the process that created it still exists. We do this in a loop
|
||||||
|
to make it easy to retry if the old locking process no longer
|
||||||
|
exists. */
|
||||||
|
fret = TRUE;
|
||||||
|
if (pferr != NULL)
|
||||||
|
*pferr = FALSE;
|
||||||
|
o = -1;
|
||||||
|
zerr = NULL;
|
||||||
|
|
||||||
|
while (link (ztempfile, zpath) != 0)
|
||||||
|
{
|
||||||
|
int cgot;
|
||||||
|
int ipid;
|
||||||
|
boolean freadonly;
|
||||||
|
|
||||||
|
fret = FALSE;
|
||||||
|
|
||||||
|
if (errno != EEXIST)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "link (%s, %s): %s", ztempfile, zpath,
|
||||||
|
strerror (errno));
|
||||||
|
if (pferr != NULL)
|
||||||
|
*pferr = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
freadonly = FALSE;
|
||||||
|
o = open ((char *) zpath, O_RDWR | O_NOCTTY, 0);
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == EACCES)
|
||||||
|
{
|
||||||
|
freadonly = TRUE;
|
||||||
|
o = open ((char *) zpath, O_RDONLY, 0);
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
/* The file was presumably removed between the link
|
||||||
|
and the open. Try the link again. */
|
||||||
|
fret = TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
zerr = "open";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The race starts here. See below for a discussion. */
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
cgot = read (o, &i, sizeof i);
|
||||||
|
#else
|
||||||
|
cgot = read (o, ab, sizeof ab - 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cgot < 0)
|
||||||
|
{
|
||||||
|
zerr = "read";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
ipid = i;
|
||||||
|
#else
|
||||||
|
ab[cgot] = '\0';
|
||||||
|
ipid = strtol (ab, (char **) NULL, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* On NFS, the link might have actually succeeded even though we
|
||||||
|
got a failure return. This can happen if the original
|
||||||
|
acknowledgement was lost or delayed and the operation was
|
||||||
|
retried. In this case the pid will be our own. This
|
||||||
|
introduces a rather improbable race condition: if a stale
|
||||||
|
lock was left with our process ID in it, and another process
|
||||||
|
just did the kill, below, but has not yet changed the lock
|
||||||
|
file to hold its own process ID, we could start up and make
|
||||||
|
it all the way to here and think we have the lock. I'm not
|
||||||
|
going to worry about this possibility. */
|
||||||
|
if (ipid == ime)
|
||||||
|
{
|
||||||
|
fret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the process still exists, we will get EPERM rather than
|
||||||
|
ESRCH. We then return FALSE to indicate that we cannot make
|
||||||
|
the lock. */
|
||||||
|
if (kill (ipid, 0) == 0 || errno == EPERM)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ulog (LOG_ERROR, "Found stale lock %s held by process %d",
|
||||||
|
zpath, ipid);
|
||||||
|
|
||||||
|
/* This is a stale lock, created by a process that no longer
|
||||||
|
exists.
|
||||||
|
|
||||||
|
Now we could remove the file (and, if the file mode disallows
|
||||||
|
writing, that's what we have to do), but we try to avoid
|
||||||
|
doing so since it causes a race condition. If we remove the
|
||||||
|
file, and are interrupted any time after we do the read until
|
||||||
|
we do the remove, another process could get in, open the
|
||||||
|
file, find that it was a stale lock, remove the file and
|
||||||
|
create a new one. When we regained control we would remove
|
||||||
|
the file the other process just created.
|
||||||
|
|
||||||
|
These files are being generated partially for the benefit of
|
||||||
|
cu, and it would be nice to avoid the race however cu avoids
|
||||||
|
it, so that the programs remain compatible. Unfortunately,
|
||||||
|
nobody seems to know how cu avoids the race, or even if it
|
||||||
|
tries to avoid it at all.
|
||||||
|
|
||||||
|
There are a few ways to avoid the race. We could use kernel
|
||||||
|
locking primitives, but they may not be available. We could
|
||||||
|
link to a special file name, but if that file were left lying
|
||||||
|
around then no stale lock could ever be broken (Henry Spencer
|
||||||
|
would think this was a good thing).
|
||||||
|
|
||||||
|
Instead I've implemented the following procedure: seek to the
|
||||||
|
start of the file, write our pid into it, sleep for five
|
||||||
|
seconds, and then make sure our pid is still there. Anybody
|
||||||
|
who checks the file while we're asleep will find our pid
|
||||||
|
there and fail the lock. The only race will come from
|
||||||
|
another process which has done the read by the time we do our
|
||||||
|
write. That process will then have five seconds to do its
|
||||||
|
own write. When we wake up, we'll notice that our pid is no
|
||||||
|
longer in the file, and retry the lock from the beginning.
|
||||||
|
|
||||||
|
This relies on the atomicity of write(2). If it possible for
|
||||||
|
the writes of two processes to be interleaved, the two
|
||||||
|
processes could livelock. POSIX unfortunately leaves this
|
||||||
|
case explicitly undefined; however, given that the write is
|
||||||
|
of less than a disk block, it's difficult to imagine an
|
||||||
|
interleave occurring.
|
||||||
|
|
||||||
|
Note that this is still a race. If it takes the second
|
||||||
|
process more than five seconds to do the kill, the lseek, and
|
||||||
|
the write, both processes will think they have the lock.
|
||||||
|
Perhaps the length of time to sleep should be configurable.
|
||||||
|
Even better, perhaps I should add a configuration option to
|
||||||
|
use a permanent lock file, which eliminates any race and
|
||||||
|
forces the installer to be aware of the existence of the
|
||||||
|
permanent lock file.
|
||||||
|
|
||||||
|
We stat the file after the sleep, to make sure some other
|
||||||
|
program hasn't deleted it for us. */
|
||||||
|
if (freadonly)
|
||||||
|
{
|
||||||
|
(void) close (o);
|
||||||
|
o = -1;
|
||||||
|
(void) remove (zpath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lseek (o, (off_t) 0, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
zerr = "lseek";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
i = ime;
|
||||||
|
cwrote = write (o, &i, sizeof i);
|
||||||
|
#else
|
||||||
|
sprintf (ab, "%10d\n", (int) ime);
|
||||||
|
cwrote = write (o, ab, strlen (ab));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cwrote < 0)
|
||||||
|
{
|
||||||
|
zerr = "write";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) sleep (5);
|
||||||
|
|
||||||
|
if (lseek (o, (off_t) 0, SEEK_SET) != 0)
|
||||||
|
{
|
||||||
|
zerr = "lseek";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
cgot = read (o, &i, sizeof i);
|
||||||
|
#else
|
||||||
|
cgot = read (o, ab, sizeof ab - 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (cgot < 0)
|
||||||
|
{
|
||||||
|
zerr = "read";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_V2_LOCKFILES
|
||||||
|
ipid = i;
|
||||||
|
#else
|
||||||
|
ab[cgot] = '\0';
|
||||||
|
ipid = strtol (ab, (char **) NULL, 10);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ipid == ime)
|
||||||
|
{
|
||||||
|
struct stat sfile, sdescriptor;
|
||||||
|
|
||||||
|
/* It looks like we have the lock. Do the final stat
|
||||||
|
check. */
|
||||||
|
if (stat ((char *) zpath, &sfile) < 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
{
|
||||||
|
zerr = "stat";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* Loop around and try again. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fstat (o, &sdescriptor) < 0)
|
||||||
|
{
|
||||||
|
zerr = "fstat";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sfile.st_ino == sdescriptor.st_ino
|
||||||
|
&& sfile.st_dev == sdescriptor.st_dev)
|
||||||
|
{
|
||||||
|
/* Close the file before assuming we've succeeded to
|
||||||
|
pick up any trailing errors. */
|
||||||
|
if (close (o) < 0)
|
||||||
|
{
|
||||||
|
zerr = "close";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
o = -1;
|
||||||
|
|
||||||
|
/* We have the lock. */
|
||||||
|
fret = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop around and try the lock again. We keep doing this until
|
||||||
|
the lock file holds a pid that exists. */
|
||||||
|
(void) close (o);
|
||||||
|
o = -1;
|
||||||
|
fret = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zerr != NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s (%s): %s", zerr, zpath, strerror (errno));
|
||||||
|
if (pferr != NULL)
|
||||||
|
*pferr = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o >= 0)
|
||||||
|
(void) close (o);
|
||||||
|
|
||||||
|
ubuffree (zfree);
|
||||||
|
|
||||||
|
/* It would be nice if we could leave the temporary file around for
|
||||||
|
future calls, but considering that we create lock files in
|
||||||
|
various different directories it's probably more trouble than
|
||||||
|
it's worth. */
|
||||||
|
if (remove (ztempfile) != 0)
|
||||||
|
ulog (LOG_ERROR, "remove (%s): %s", ztempfile, strerror (errno));
|
||||||
|
|
||||||
|
ubuffree (ztempfile);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock something. The fspooldir argument is as in fsdo_lock. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsdo_unlock (zlock, fspooldir)
|
||||||
|
const char *zlock;
|
||||||
|
boolean fspooldir;
|
||||||
|
{
|
||||||
|
char *zfree;
|
||||||
|
const char *zpath;
|
||||||
|
|
||||||
|
if (fspooldir)
|
||||||
|
{
|
||||||
|
zfree = NULL;
|
||||||
|
zpath = zlock;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
zfree = zsysdep_in_dir (zSlockdir, zlock);
|
||||||
|
zpath = zfree;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove (zpath) == 0
|
||||||
|
|| errno == ENOENT)
|
||||||
|
{
|
||||||
|
ubuffree (zfree);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "remove (%s): %s", zpath, strerror (errno));
|
||||||
|
ubuffree (zfree);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
25
gnu/libexec/uucp/libunix/loctim.c
Normal file
25
gnu/libexec/uucp/libunix/loctim.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* loctim.c
|
||||||
|
Turn a time epoch into a struct tm. This is trivial on Unix. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#ifndef localtime
|
||||||
|
extern struct tm *localtime ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
usysdep_localtime (itime, q)
|
||||||
|
long itime;
|
||||||
|
struct tm *q;
|
||||||
|
{
|
||||||
|
time_t i;
|
||||||
|
|
||||||
|
i = (time_t) itime;
|
||||||
|
*q = *localtime (&i);
|
||||||
|
}
|
85
gnu/libexec/uucp/libunix/mail.c
Normal file
85
gnu/libexec/uucp/libunix/mail.c
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* mail.c
|
||||||
|
Send mail to a user.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ctime
|
||||||
|
extern char *ctime ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Mail a message to a user. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_mail (zto, zsubject, cstrs, paz)
|
||||||
|
const char *zto;
|
||||||
|
const char *zsubject;
|
||||||
|
int cstrs;
|
||||||
|
const char **paz;
|
||||||
|
{
|
||||||
|
const char *az[3];
|
||||||
|
FILE *e;
|
||||||
|
pid_t ipid;
|
||||||
|
time_t itime;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
az[0] = MAIL_PROGRAM;
|
||||||
|
az[1] = zto;
|
||||||
|
az[2] = NULL;
|
||||||
|
|
||||||
|
e = espopen (az, FALSE, &ipid);
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "espopen (%s): %s", MAIL_PROGRAM,
|
||||||
|
strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (e, "Subject: %s\n", zsubject);
|
||||||
|
fprintf (e, "To: %s\n", zto);
|
||||||
|
|
||||||
|
fprintf (e, "\n");
|
||||||
|
|
||||||
|
(void) time (&itime);
|
||||||
|
/* Remember that ctime includes a \n, so this skips a line. */
|
||||||
|
fprintf (e, "Message from UUCP on %s %s\n", zSlocalname,
|
||||||
|
ctime (&itime));
|
||||||
|
|
||||||
|
for (i = 0; i < cstrs; i++)
|
||||||
|
fputs (paz[i], e);
|
||||||
|
|
||||||
|
(void) fclose (e);
|
||||||
|
|
||||||
|
return ixswait ((unsigned long) ipid, MAIL_PROGRAM) == 0;
|
||||||
|
}
|
58
gnu/libexec/uucp/libunix/mkdir.c
Normal file
58
gnu/libexec/uucp/libunix/mkdir.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* mkdir.c
|
||||||
|
Create a directory. We must go through a subsidiary program to
|
||||||
|
force our real uid to be the uucp owner before invoking the setuid
|
||||||
|
/bin/mkdir program. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
mkdir (zdir, imode)
|
||||||
|
const char *zdir;
|
||||||
|
int imode;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
const char *azargs[3];
|
||||||
|
int aidescs[3];
|
||||||
|
pid_t ipid;
|
||||||
|
|
||||||
|
/* Make sure the directory does not exist, since we will otherwise
|
||||||
|
get the wrong errno value. */
|
||||||
|
if (stat (zdir, &s) == 0)
|
||||||
|
{
|
||||||
|
errno = EEXIST;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* /bin/mkdir will create the directory with mode 777, so we set our
|
||||||
|
umask to get the mode we want. */
|
||||||
|
(void) umask ((~ imode) & (S_IRWXU | S_IRWXG | S_IRWXO));
|
||||||
|
|
||||||
|
azargs[0] = UUDIR_PROGRAM;
|
||||||
|
azargs[1] = zdir;
|
||||||
|
azargs[2] = NULL;
|
||||||
|
aidescs[0] = SPAWN_NULL;
|
||||||
|
aidescs[1] = SPAWN_NULL;
|
||||||
|
aidescs[2] = SPAWN_NULL;
|
||||||
|
|
||||||
|
ipid = ixsspawn (azargs, aidescs, FALSE, FALSE, (const char *) NULL,
|
||||||
|
TRUE, FALSE, (const char *) NULL,
|
||||||
|
(const char *) NULL, (const char *) NULL);
|
||||||
|
|
||||||
|
(void) umask (0);
|
||||||
|
|
||||||
|
if (ipid < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ixswait ((unsigned long) ipid, (const char *) NULL) != 0)
|
||||||
|
{
|
||||||
|
/* Make up an errno value. */
|
||||||
|
errno = EACCES;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
49
gnu/libexec/uucp/libunix/mkdirs.c
Normal file
49
gnu/libexec/uucp/libunix/mkdirs.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* mkdirs.c
|
||||||
|
Create any directories needed for a file name. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_make_dirs (zfile, fpublic)
|
||||||
|
const char *zfile;
|
||||||
|
boolean fpublic;
|
||||||
|
{
|
||||||
|
char *zcopy, *z;
|
||||||
|
int imode;
|
||||||
|
|
||||||
|
zcopy = zbufcpy (zfile);
|
||||||
|
|
||||||
|
if (fpublic)
|
||||||
|
imode = IPUBLIC_DIRECTORY_MODE;
|
||||||
|
else
|
||||||
|
imode = IDIRECTORY_MODE;
|
||||||
|
|
||||||
|
for (z = zcopy; *z != '\0'; z++)
|
||||||
|
{
|
||||||
|
if (*z == '/' && z != zcopy)
|
||||||
|
{
|
||||||
|
*z = '\0';
|
||||||
|
if (! fsysdep_directory (zcopy))
|
||||||
|
{
|
||||||
|
if (mkdir (zcopy, imode) != 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "mkdir (%s): %s", zcopy,
|
||||||
|
strerror (errno));
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*z = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuffree (zcopy);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
33
gnu/libexec/uucp/libunix/mode.c
Normal file
33
gnu/libexec/uucp/libunix/mode.c
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/* mode.c
|
||||||
|
Get the Unix file mode of a file. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ixsysdep_file_mode (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
if (stat ((char *) zfile, &s) != 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if S_IRWXU != 0700
|
||||||
|
#error Files modes need to be translated
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* We can't return 0, since that indicate an error. */
|
||||||
|
if ((s.st_mode & 0777) == 0)
|
||||||
|
return 0400;
|
||||||
|
|
||||||
|
return s.st_mode & 0777;
|
||||||
|
}
|
176
gnu/libexec/uucp/libunix/move.c
Normal file
176
gnu/libexec/uucp/libunix/move.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/* move.c
|
||||||
|
Move a file.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Move (rename) a file from one name to another. This routine will
|
||||||
|
optionally create necessary directories, and fpublic indicates
|
||||||
|
whether the new directories should be publically accessible or not.
|
||||||
|
If fcheck is true, it will try to determine whether the named user
|
||||||
|
has write access to the new file. */
|
||||||
|
|
||||||
|
boolean
|
||||||
|
fsysdep_move_file (zorig, zto, fmkdirs, fpublic, fcheck, zuser)
|
||||||
|
const char *zorig;
|
||||||
|
const char *zto;
|
||||||
|
boolean fmkdirs;
|
||||||
|
boolean fpublic;
|
||||||
|
boolean fcheck;
|
||||||
|
const char *zuser;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
int o;
|
||||||
|
|
||||||
|
DEBUG_MESSAGE2 (DEBUG_SPOOLDIR,
|
||||||
|
"fsysdep_move_file: Moving %s to %s", zorig, zto);
|
||||||
|
|
||||||
|
/* Optionally make sure that zuser has write access on the
|
||||||
|
directory. */
|
||||||
|
if (fcheck)
|
||||||
|
{
|
||||||
|
char *zcopy;
|
||||||
|
char *zslash;
|
||||||
|
|
||||||
|
zcopy = zbufcpy (zto);
|
||||||
|
zslash = strrchr (zcopy, '/');
|
||||||
|
if (zslash == zcopy)
|
||||||
|
zslash[1] = '\0';
|
||||||
|
else
|
||||||
|
*zslash = '\0';
|
||||||
|
|
||||||
|
if (stat (zcopy, &s) != 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zcopy, strerror (errno));
|
||||||
|
(void) remove (zorig);
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (! fsuser_access (&s, W_OK, zuser))
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: %s", zcopy, strerror (EACCES));
|
||||||
|
(void) remove (zorig);
|
||||||
|
ubuffree (zcopy);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
ubuffree (zcopy);
|
||||||
|
|
||||||
|
/* A malicious user now has a few milliseconds to change a
|
||||||
|
symbolic link to a directory uucp has write permission on but
|
||||||
|
the user does not (the obvious choice being /usr/lib/uucp).
|
||||||
|
The only certain method I can come up with to close this race
|
||||||
|
is to fork an suid process which takes on the users identity
|
||||||
|
and does the actual copy. This is sufficiently high overhead
|
||||||
|
that I'm not going to do it. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We try to use rename to move the file. */
|
||||||
|
|
||||||
|
if (rename (zorig, zto) == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (fmkdirs && errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zto, fpublic))
|
||||||
|
{
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (rename (zorig, zto) == 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_RENAME
|
||||||
|
/* On some systems the system call rename seems to fail for
|
||||||
|
arbitrary reasons. To get around this, we always try to copy the
|
||||||
|
file by hand if the rename failed. */
|
||||||
|
errno = EXDEV;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If we can't link across devices, we must copy the file by hand. */
|
||||||
|
if (errno != EXDEV)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "rename (%s, %s): %s", zorig, zto,
|
||||||
|
strerror (errno));
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy the file. */
|
||||||
|
if (stat ((char *) zorig, &s) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zorig, strerror (errno));
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the file gets the right mode by creating it before we
|
||||||
|
call fcopy_file. */
|
||||||
|
(void) remove (zto);
|
||||||
|
o = creat ((char *) zto, s.st_mode);
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (fmkdirs && errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zto, fpublic))
|
||||||
|
{
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
o = creat ((char *) zto, s.st_mode);
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "creat (%s): %s", zto, strerror (errno));
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void) close (o);
|
||||||
|
|
||||||
|
if (! fcopy_file (zorig, zto, fpublic, fmkdirs))
|
||||||
|
{
|
||||||
|
(void) remove (zorig);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove (zorig) != 0)
|
||||||
|
ulog (LOG_ERROR, "remove (%s): %s", zorig, strerror (errno));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
244
gnu/libexec/uucp/libunix/opensr.c
Normal file
244
gnu/libexec/uucp/libunix/opensr.c
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* opensr.c
|
||||||
|
Open files for sending and receiving.
|
||||||
|
|
||||||
|
Copyright (C) 1991, 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_RDONLY
|
||||||
|
#define O_RDONLY 0
|
||||||
|
#define O_WRONLY 1
|
||||||
|
#define O_RDWR 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef O_NOCTTY
|
||||||
|
#define O_NOCTTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FD_CLOEXEC
|
||||||
|
#define FD_CLOEXEC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef time
|
||||||
|
extern time_t time ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Open a file to send to another system, and return the mode and
|
||||||
|
the size. */
|
||||||
|
|
||||||
|
openfile_t
|
||||||
|
esysdep_open_send (qsys, zfile, fcheck, zuser)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zfile;
|
||||||
|
boolean fcheck;
|
||||||
|
const char *zuser;
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
openfile_t e;
|
||||||
|
int o;
|
||||||
|
|
||||||
|
if (fsysdep_directory (zfile))
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: is a directory", zfile);
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_STDIO
|
||||||
|
e = fopen (zfile, BINREAD);
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fopen (%s): %s", zfile, strerror (errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
o = fileno (e);
|
||||||
|
#else
|
||||||
|
e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0);
|
||||||
|
if (e == -1)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
o = e;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
|
||||||
|
(void) ffileclose (e);
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fstat (o, &s) == -1)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fstat: %s", strerror (errno));
|
||||||
|
s.st_mode = 0666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We have to recheck the file permission, although we probably
|
||||||
|
checked it already, because otherwise there would be a window in
|
||||||
|
which somebody could change the contents of a symbolic link to
|
||||||
|
point to some file which was only readable by uucp. */
|
||||||
|
if (fcheck)
|
||||||
|
{
|
||||||
|
if (! fsuser_access (&s, R_OK, zuser))
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "%s: %s", zfile, strerror (EACCES));
|
||||||
|
(void) ffileclose (e);
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get a temporary file name to receive into. We use the ztemp
|
||||||
|
argument to pick the file name, so that we relocate the file if the
|
||||||
|
transmission is aborted. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_receive_temp (qsys, zto, ztemp)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zto;
|
||||||
|
const char *ztemp;
|
||||||
|
{
|
||||||
|
if (ztemp != NULL
|
||||||
|
&& *ztemp == 'D'
|
||||||
|
&& strcmp (ztemp, "D.0") != 0)
|
||||||
|
return zsappend3 (".Temp", qsys->uuconf_zname, ztemp);
|
||||||
|
else
|
||||||
|
return zstemp_file (qsys);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open a temporary file to receive into. This should, perhaps, check
|
||||||
|
that we have write permission on the receiving directory, but it
|
||||||
|
doesn't. */
|
||||||
|
|
||||||
|
openfile_t
|
||||||
|
esysdep_open_receive (qsys, zto, ztemp, zreceive, pcrestart)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zto;
|
||||||
|
const char *ztemp;
|
||||||
|
const char *zreceive;
|
||||||
|
long *pcrestart;
|
||||||
|
{
|
||||||
|
int o;
|
||||||
|
openfile_t e;
|
||||||
|
|
||||||
|
/* If we used the ztemp argument in zsysdep_receive_temp, above,
|
||||||
|
then we will have a name consistent across conversations. In
|
||||||
|
that case, we may have already received some portion of this
|
||||||
|
file. */
|
||||||
|
o = -1;
|
||||||
|
*pcrestart = -1;
|
||||||
|
if (ztemp != NULL
|
||||||
|
&& *ztemp == 'D'
|
||||||
|
&& strcmp (ztemp, "D.0") != 0)
|
||||||
|
{
|
||||||
|
o = open ((char *) zreceive, O_WRONLY);
|
||||||
|
if (o >= 0)
|
||||||
|
{
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
/* For safety, we insist on the file being less than 1 week
|
||||||
|
old. This can still catch people, unfortunately. I
|
||||||
|
don't know of any good solution to the problem of old
|
||||||
|
files hanging around. If anybody has a file they want
|
||||||
|
restarted, and they know about this issue, they can touch
|
||||||
|
it to bring it up to date. */
|
||||||
|
if (fstat (o, &s) < 0
|
||||||
|
|| s.st_mtime + 7 * 24 * 60 * 60 < time ((time_t *) NULL))
|
||||||
|
{
|
||||||
|
(void) close (o);
|
||||||
|
o = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_MESSAGE1 (DEBUG_SPOOLDIR,
|
||||||
|
"esysdep_open_receive: Reusing %s",
|
||||||
|
zreceive);
|
||||||
|
*pcrestart = (long) s.st_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o < 0)
|
||||||
|
o = creat ((char *) zreceive, IPRIVATE_FILE_MODE);
|
||||||
|
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (! fsysdep_make_dirs (zreceive, FALSE))
|
||||||
|
return EFILECLOSED;
|
||||||
|
o = creat ((char *) zreceive, IPRIVATE_FILE_MODE);
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "creat (%s): %s", zreceive, strerror (errno));
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
(void) remove (zreceive);
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_STDIO
|
||||||
|
e = fdopen (o, (char *) BINWRITE);
|
||||||
|
|
||||||
|
if (e == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fdopen (%s): %s", zreceive, strerror (errno));
|
||||||
|
(void) close (o);
|
||||||
|
(void) remove (zreceive);
|
||||||
|
return EFILECLOSED;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
e = o;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return e;
|
||||||
|
}
|
96
gnu/libexec/uucp/libunix/pause.c
Normal file
96
gnu/libexec/uucp/libunix/pause.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/* pause.c
|
||||||
|
Pause for half a second. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* Pick a timing routine to use. I somewhat arbitrarily picked usleep
|
||||||
|
above nap above napms above poll above select. */
|
||||||
|
#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS || HAVE_POLL
|
||||||
|
#undef HAVE_SELECT
|
||||||
|
#define HAVE_SELECT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS
|
||||||
|
#undef HAVE_POLL
|
||||||
|
#define HAVE_POLL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_USLEEP || HAVE_NAP
|
||||||
|
#undef HAVE_NAPMS
|
||||||
|
#define HAVE_NAPMS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_USLEEP
|
||||||
|
#undef HAVE_NAP
|
||||||
|
#define HAVE_NAP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_SELECT
|
||||||
|
#include <sys/time.h>
|
||||||
|
#if HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_POLL
|
||||||
|
#if HAVE_STROPTS_H
|
||||||
|
#include <stropts.h>
|
||||||
|
#endif
|
||||||
|
#if HAVE_POLL_H
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
#if ! HAVE_STROPTS_H && ! HAVE_POLL_H
|
||||||
|
/* We need a definition for struct pollfd, although it doesn't matter
|
||||||
|
what it contains. */
|
||||||
|
struct pollfd
|
||||||
|
{
|
||||||
|
int idummy;
|
||||||
|
};
|
||||||
|
#endif /* ! HAVE_STROPTS_H && ! HAVE_POLL_H */
|
||||||
|
#endif /* HAVE_POLL */
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#if HAVE_SYS_TIME_AND_TIME_H || ! USE_SELECT_TIMER
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
usysdep_pause ()
|
||||||
|
{
|
||||||
|
#if HAVE_NAPMS
|
||||||
|
napms (500);
|
||||||
|
#endif /* HAVE_NAPMS */
|
||||||
|
#if HAVE_NAP
|
||||||
|
#if HAVE_HUNDREDTHS_NAP
|
||||||
|
nap (50L);
|
||||||
|
#else
|
||||||
|
nap (500L);
|
||||||
|
#endif /* ! HAVE_HUNDREDTHS_NAP */
|
||||||
|
#endif /* HAVE_NAP */
|
||||||
|
#if HAVE_USLEEP
|
||||||
|
usleep (500 * (long) 1000);
|
||||||
|
#endif /* HAVE_USLEEP */
|
||||||
|
#if HAVE_POLL
|
||||||
|
struct pollfd sdummy;
|
||||||
|
|
||||||
|
/* We need to pass an unused pollfd structure because poll checks
|
||||||
|
the address before checking the number of elements. */
|
||||||
|
poll (&sdummy, 0, 500);
|
||||||
|
#endif /* HAVE_POLL */
|
||||||
|
#if HAVE_SELECT
|
||||||
|
struct timeval s;
|
||||||
|
|
||||||
|
s.tv_sec = 0;
|
||||||
|
s.tv_usec = 500 * (long) 1000;
|
||||||
|
select (0, (pointer) NULL, (pointer) NULL, (pointer) NULL, &s);
|
||||||
|
#endif /* USE_SELECT_TIMER */
|
||||||
|
#if ! HAVE_NAPMS && ! HAVE_NAP && ! HAVE_USLEEP
|
||||||
|
#if ! USE_SELECT_TIMER && ! HAVE_POLL
|
||||||
|
sleep (1);
|
||||||
|
#endif /* ! USE_SELECT_TIMER && ! HAVE_POLL */
|
||||||
|
#endif /* ! HAVE_NAPMS && ! HAVE_NAP && ! HAVE_USLEEP */
|
||||||
|
}
|
230
gnu/libexec/uucp/libunix/picksb.c
Normal file
230
gnu/libexec/uucp/libunix/picksb.c
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
/* picksb.c
|
||||||
|
System dependent routines for uupick.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#if USE_RCS_ID
|
||||||
|
const char picksb_rcsid[] = "$Id: picksb.c,v 1.1 1993/08/04 19:32:42 jtc Exp $";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#if HAVE_OPENDIR
|
||||||
|
#if HAVE_DIRENT_H
|
||||||
|
#include <dirent.h>
|
||||||
|
#else /* ! HAVE_DIRENT_H */
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#define dirent direct
|
||||||
|
#endif /* ! HAVE_DIRENT_H */
|
||||||
|
#endif /* HAVE_OPENDIR */
|
||||||
|
|
||||||
|
#if GETPWUID_DECLARATION_OK
|
||||||
|
#ifndef getpwuid
|
||||||
|
extern struct passwd *getpwuid ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Local variables. */
|
||||||
|
|
||||||
|
/* Directory of ~/receive/USER. */
|
||||||
|
static DIR *qStopdir;
|
||||||
|
|
||||||
|
/* Name of ~/receive/USER. */
|
||||||
|
static char *zStopdir;
|
||||||
|
|
||||||
|
/* Directory of ~/receive/USER/SYSTEM. */
|
||||||
|
static DIR *qSsysdir;
|
||||||
|
|
||||||
|
/* Name of system. */
|
||||||
|
static char *zSsysdir;
|
||||||
|
|
||||||
|
/* Prepare to get a list of all the file to uupick for this user. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fsysdep_uupick_init (zsystem, zpubdir)
|
||||||
|
const char *zsystem;
|
||||||
|
const char *zpubdir;
|
||||||
|
{
|
||||||
|
const char *zuser;
|
||||||
|
|
||||||
|
zuser = zsysdep_login_name ();
|
||||||
|
|
||||||
|
zStopdir = (char *) xmalloc (strlen (zpubdir)
|
||||||
|
+ sizeof "/receive/"
|
||||||
|
+ strlen (zuser));
|
||||||
|
sprintf (zStopdir, "%s/receive/%s", zpubdir, zuser);
|
||||||
|
|
||||||
|
qStopdir = opendir (zStopdir);
|
||||||
|
if (qStopdir == NULL && errno != ENOENT)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "opendir (%s): %s", zStopdir,
|
||||||
|
strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
qSsysdir = NULL;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the next file from the uupick directories. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
char *
|
||||||
|
zsysdep_uupick (zsysarg, zpubdir, pzfrom, pzfull)
|
||||||
|
const char *zsysarg;
|
||||||
|
const char *zpubdir;
|
||||||
|
char **pzfrom;
|
||||||
|
char **pzfull;
|
||||||
|
{
|
||||||
|
struct dirent *qentry;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
while (qSsysdir == NULL)
|
||||||
|
{
|
||||||
|
const char *zsystem;
|
||||||
|
char *zdir;
|
||||||
|
|
||||||
|
if (qStopdir == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (zsysarg != NULL)
|
||||||
|
{
|
||||||
|
closedir (qStopdir);
|
||||||
|
qStopdir = NULL;
|
||||||
|
zsystem = zsysarg;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
qentry = readdir (qStopdir);
|
||||||
|
if (qentry == NULL)
|
||||||
|
{
|
||||||
|
closedir (qStopdir);
|
||||||
|
qStopdir = NULL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (strcmp (qentry->d_name, ".") == 0
|
||||||
|
|| strcmp (qentry->d_name, "..") == 0);
|
||||||
|
|
||||||
|
zsystem = qentry->d_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
zdir = zbufalc (strlen (zStopdir) + strlen (zsystem) + sizeof "/");
|
||||||
|
sprintf (zdir, "%s/%s", zStopdir, zsystem);
|
||||||
|
|
||||||
|
qSsysdir = opendir (zdir);
|
||||||
|
if (qSsysdir == NULL)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT && errno != ENOTDIR)
|
||||||
|
ulog (LOG_ERROR, "opendir (%s): %s", zdir, strerror (errno));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ubuffree (zSsysdir);
|
||||||
|
zSsysdir = zbufcpy (zsystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuffree (zdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
qentry = readdir (qSsysdir);
|
||||||
|
if (qentry == NULL)
|
||||||
|
{
|
||||||
|
closedir (qSsysdir);
|
||||||
|
qSsysdir = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (qentry->d_name, ".") == 0
|
||||||
|
|| strcmp (qentry->d_name, "..") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
*pzfrom = zbufcpy (zSsysdir);
|
||||||
|
*pzfull = zsappend3 (zStopdir, zSsysdir, qentry->d_name);
|
||||||
|
return zbufcpy (qentry->d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fsysdep_uupick_free (zsystem, zpubdir)
|
||||||
|
const char *zsystem;
|
||||||
|
const char *zpubdir;
|
||||||
|
{
|
||||||
|
xfree ((pointer) zStopdir);
|
||||||
|
if (qStopdir != NULL)
|
||||||
|
{
|
||||||
|
closedir (qStopdir);
|
||||||
|
qStopdir = NULL;
|
||||||
|
}
|
||||||
|
ubuffree (zSsysdir);
|
||||||
|
zSsysdir = NULL;
|
||||||
|
if (qSsysdir != NULL)
|
||||||
|
{
|
||||||
|
closedir (qSsysdir);
|
||||||
|
qSsysdir = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expand a local file name for uupick. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
zsysdep_uupick_local_file (zfile)
|
||||||
|
const char *zfile;
|
||||||
|
{
|
||||||
|
struct passwd *q;
|
||||||
|
|
||||||
|
/* If this does not start with a simple ~, pass it to
|
||||||
|
zsysdep_local_file_cwd; as it happens, zsysdep_local_file_cwd
|
||||||
|
only uses the zpubdir argument if the file starts with a simple
|
||||||
|
~, so it doesn't really matter what we pass for zpubdir. */
|
||||||
|
if (zfile[0] != '~'
|
||||||
|
|| (zfile[1] != '/' && zfile[1] != '\0'))
|
||||||
|
return zsysdep_local_file_cwd (zfile, (const char *) NULL);
|
||||||
|
|
||||||
|
q = getpwuid (getuid ());
|
||||||
|
if (q == NULL)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "Can't get home directory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zfile[1] == '\0')
|
||||||
|
return zbufcpy (q->pw_dir);
|
||||||
|
|
||||||
|
return zsysdep_in_dir (q->pw_dir, zfile + 2);
|
||||||
|
}
|
51
gnu/libexec/uucp/libunix/portnm.c
Normal file
51
gnu/libexec/uucp/libunix/portnm.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* portnm.c
|
||||||
|
Get the port name of stdin. */
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#if HAVE_TCP
|
||||||
|
#if HAVE_SYS_TYPES_TCP_H
|
||||||
|
#include <sys/types.tcp.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ttyname
|
||||||
|
extern char *ttyname ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the port name of standard input. I assume that Unix systems
|
||||||
|
generally support ttyname. If they don't, this function can just
|
||||||
|
return NULL. It uses getsockname to see whether standard input is
|
||||||
|
a TCP connection. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
zsysdep_port_name (ftcp_port)
|
||||||
|
boolean *ftcp_port;
|
||||||
|
{
|
||||||
|
const char *z;
|
||||||
|
|
||||||
|
*ftcp_port = FALSE;
|
||||||
|
|
||||||
|
#if HAVE_TCP
|
||||||
|
{
|
||||||
|
size_t clen;
|
||||||
|
struct sockaddr s;
|
||||||
|
|
||||||
|
clen = sizeof (struct sockaddr);
|
||||||
|
if (getsockname (0, &s, &clen) == 0)
|
||||||
|
*ftcp_port = TRUE;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_TCP */
|
||||||
|
|
||||||
|
z = ttyname (0);
|
||||||
|
if (z == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (strncmp (z, "/dev/", sizeof "/dev/" - 1) == 0)
|
||||||
|
return z + sizeof "/dev/" - 1;
|
||||||
|
else
|
||||||
|
return z;
|
||||||
|
}
|
197
gnu/libexec/uucp/libunix/proctm.c
Normal file
197
gnu/libexec/uucp/libunix/proctm.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/* proctm.c
|
||||||
|
Get the time spent in the process.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#if HAVE_SYS_PARAM_H
|
||||||
|
#include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_LIMITS_H
|
||||||
|
#include <limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Prefer gettimeofday to ftime to times. */
|
||||||
|
|
||||||
|
#if HAVE_GETTIMEOFDAY || HAVE_FTIME
|
||||||
|
#undef HAVE_TIMES
|
||||||
|
#define HAVE_TIMES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_GETTIMEOFDAY
|
||||||
|
#undef HAVE_FTIME
|
||||||
|
#define HAVE_FTIME 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TIME_H && (HAVE_SYS_TIME_AND_TIME_H || ! HAVE_GETTIMEOFDAY)
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_GETTIMEOFDAY
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FTIME
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TIMES
|
||||||
|
|
||||||
|
#if HAVE_SYS_TIMES_H
|
||||||
|
#include <sys/times.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TIMES_DECLARATION_OK
|
||||||
|
/* We use a macro to protect this because times really returns clock_t
|
||||||
|
and on some systems, such as Ultrix 4.0, clock_t is int. We don't
|
||||||
|
leave it out entirely because on some systems, such as System III,
|
||||||
|
the declaration is necessary for correct compilation. */
|
||||||
|
#ifndef times
|
||||||
|
extern long times ();
|
||||||
|
#endif
|
||||||
|
#endif /* TIMES_DECLARATION_OK */
|
||||||
|
|
||||||
|
#ifdef _SC_CLK_TCK
|
||||||
|
#define HAVE_SC_CLK_TCK 1
|
||||||
|
#else
|
||||||
|
#define HAVE_SC_CLK_TCK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* TIMES_TICK may have been set in policy.h, or we may be able to get
|
||||||
|
it using sysconf. If neither is the case, try to find a useful
|
||||||
|
definition from the system header files. */
|
||||||
|
#if TIMES_TICK == 0 && (! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK)
|
||||||
|
#ifdef CLK_TCK
|
||||||
|
#undef TIMES_TICK
|
||||||
|
#define TIMES_TICK CLK_TCK
|
||||||
|
#else /* ! defined (CLK_TCK) */
|
||||||
|
#ifdef HZ
|
||||||
|
#undef TIMES_TICK
|
||||||
|
#define TIMES_TICK HZ
|
||||||
|
#endif /* defined (HZ) */
|
||||||
|
#endif /* ! defined (CLK_TCK) */
|
||||||
|
#endif /* TIMES_TICK == 0 && (! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK) */
|
||||||
|
|
||||||
|
#endif /* HAVE_TIMES */
|
||||||
|
|
||||||
|
#ifndef time
|
||||||
|
extern time_t time ();
|
||||||
|
#endif
|
||||||
|
#if HAVE_SYSCONF
|
||||||
|
#ifndef sysconf
|
||||||
|
extern long sysconf ();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the time in seconds and microseconds; this need only work
|
||||||
|
within the process when called from the system independent code.
|
||||||
|
It is also called by ixsysdep_time. */
|
||||||
|
|
||||||
|
long
|
||||||
|
ixsysdep_process_time (pimicros)
|
||||||
|
long *pimicros;
|
||||||
|
{
|
||||||
|
#if HAVE_GETTIMEOFDAY
|
||||||
|
struct timeval stime;
|
||||||
|
struct timezone stz;
|
||||||
|
|
||||||
|
(void) gettimeofday (&stime, &stz);
|
||||||
|
if (pimicros != NULL)
|
||||||
|
*pimicros = (long) stime.tv_usec;
|
||||||
|
return (long) stime.tv_sec;
|
||||||
|
#endif /* HAVE_GETTIMEOFDAY */
|
||||||
|
|
||||||
|
#if HAVE_FTIME
|
||||||
|
static boolean fbad;
|
||||||
|
|
||||||
|
if (! fbad)
|
||||||
|
{
|
||||||
|
struct timeb stime;
|
||||||
|
static struct timeb slast;
|
||||||
|
|
||||||
|
(void) ftime (&stime);
|
||||||
|
|
||||||
|
/* On some systems, such as SCO 3.2.2, ftime can go backwards in
|
||||||
|
time. If we detect this, we switch to using time. */
|
||||||
|
if (slast.time != 0
|
||||||
|
&& (stime.time < slast.time
|
||||||
|
|| (stime.time == slast.time &&
|
||||||
|
stime.millitm < slast.millitm)))
|
||||||
|
fbad = TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slast = stime;
|
||||||
|
if (pimicros != NULL)
|
||||||
|
*pimicros = (long) stime.millitm * (long) 1000;
|
||||||
|
return (long) stime.time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pimicros != NULL)
|
||||||
|
*pimicros = 0;
|
||||||
|
return (long) time ((time_t *) NULL);
|
||||||
|
#endif /* HAVE_FTIME */
|
||||||
|
|
||||||
|
#if HAVE_TIMES
|
||||||
|
struct tms s;
|
||||||
|
long i;
|
||||||
|
static int itick;
|
||||||
|
|
||||||
|
if (itick == 0)
|
||||||
|
{
|
||||||
|
#if TIMES_TICK == 0
|
||||||
|
#if HAVE_SYSCONF && HAVE_SC_CLK_TCK
|
||||||
|
itick = (int) sysconf (_SC_CLK_TCK);
|
||||||
|
#else /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */
|
||||||
|
const char *z;
|
||||||
|
|
||||||
|
z = getenv ("HZ");
|
||||||
|
if (z != NULL)
|
||||||
|
itick = (int) strtol (z, (char **) NULL, 10);
|
||||||
|
|
||||||
|
/* If we really couldn't get anything, just use 60. */
|
||||||
|
if (itick == 0)
|
||||||
|
itick = 60;
|
||||||
|
#endif /* ! HAVE_SYSCONF || ! HAVE_SC_CLK_TCK */
|
||||||
|
#else /* TIMES_TICK != 0 */
|
||||||
|
itick = TIMES_TICK;
|
||||||
|
#endif /* TIMES_TICK == 0 */
|
||||||
|
}
|
||||||
|
|
||||||
|
i = (long) times (&s);
|
||||||
|
if (pimicros != NULL)
|
||||||
|
*pimicros = (i % (long) itick) * ((long) 1000000 / (long) itick);
|
||||||
|
return i / (long) itick;
|
||||||
|
#endif /* HAVE_TIMES */
|
||||||
|
|
||||||
|
#if ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES
|
||||||
|
if (pimicros != NULL)
|
||||||
|
*pimicros = 0;
|
||||||
|
return (long) time ((time_t *) NULL);
|
||||||
|
#endif /* ! HAVE_GETTIMEOFDAY && ! HAVE_FTIME && ! HAVE_TIMES */
|
||||||
|
}
|
197
gnu/libexec/uucp/libunix/recep.c
Normal file
197
gnu/libexec/uucp/libunix/recep.c
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/* recep.c
|
||||||
|
See whether a file has already been received.
|
||||||
|
|
||||||
|
Copyright (C) 1992 Ian Lance Taylor
|
||||||
|
|
||||||
|
This file is part of the Taylor UUCP package.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The author of the program may be contacted at ian@airs.com or
|
||||||
|
c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uucp.h"
|
||||||
|
|
||||||
|
#include "uudefs.h"
|
||||||
|
#include "uuconf.h"
|
||||||
|
#include "sysdep.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if HAVE_TIME_H
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#if HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *zsreceived_name P((const struct uuconf_system *qsys,
|
||||||
|
const char *ztemp));
|
||||||
|
|
||||||
|
/* These routines are used to see whether we have already received a
|
||||||
|
file in a previous UUCP connection. It is possible for the
|
||||||
|
acknowledgement of a received file to be lost. The sending system
|
||||||
|
will then now know that the file was correctly received, and will
|
||||||
|
send it again. This can be a problem particularly with protocols
|
||||||
|
which support channels, since they may send several small files in
|
||||||
|
a single window, all of which may be received correctly although
|
||||||
|
the sending system never sees the acknowledgement. If these files
|
||||||
|
involve an execution, the execution will happen twice, which will
|
||||||
|
be bad.
|
||||||
|
|
||||||
|
We use a simple system. For each file we want to remember, we
|
||||||
|
create an empty file names .Received/SYS/TEMP, where SYS is the
|
||||||
|
name of the system and TEMP is the name of the temporary file used
|
||||||
|
by the sender. If no temporary file is used by the sender, we
|
||||||
|
don't remember that we received the file. This is not perfect, but
|
||||||
|
execution files will always have a temporary file, so the most
|
||||||
|
important case is handled. Also, any file received from Taylor
|
||||||
|
UUCP 1.04 or greater will always have a temporary file. */
|
||||||
|
|
||||||
|
/* Return the name we are going use for the marker, or NULL if we have
|
||||||
|
no name. */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
zsreceived_name (qsys, ztemp)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *ztemp;
|
||||||
|
{
|
||||||
|
if (ztemp != NULL
|
||||||
|
&& *ztemp == 'D'
|
||||||
|
&& strcmp (ztemp, "D.0") != 0)
|
||||||
|
return zsappend3 (".Received", qsys->uuconf_zname, ztemp);
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember that we have already received a file. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fsysdep_remember_reception (qsys, zto, ztemp)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zto;
|
||||||
|
const char *ztemp;
|
||||||
|
{
|
||||||
|
char *zfile;
|
||||||
|
int o;
|
||||||
|
|
||||||
|
zfile = zsreceived_name (qsys, ztemp);
|
||||||
|
if (zfile == NULL)
|
||||||
|
return TRUE;
|
||||||
|
o = creat (zfile, IPUBLIC_FILE_MODE);
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENOENT)
|
||||||
|
{
|
||||||
|
if (fsysdep_make_dirs (zfile, TRUE))
|
||||||
|
{
|
||||||
|
ubuffree (zfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
o = creat (zfile, IPUBLIC_FILE_MODE);
|
||||||
|
}
|
||||||
|
if (o < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "creat (%s): %s", zfile, strerror (errno));
|
||||||
|
ubuffree (zfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuffree (zfile);
|
||||||
|
|
||||||
|
/* We don't have to actually put anything in the file; we just use
|
||||||
|
the name. This is more convenient than keeping a file with a
|
||||||
|
list of names. */
|
||||||
|
if (close (o) < 0)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "fsysdep_remember_reception: close: %s",
|
||||||
|
strerror (errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See if we have already received a file. Note that don't delete the
|
||||||
|
marker file here, because we need to know that the sending system
|
||||||
|
has received our denial first. This function returns TRUE if the
|
||||||
|
file has already been received, FALSE if it has not. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fsysdep_already_received (qsys, zto, ztemp)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zto;
|
||||||
|
const char *ztemp;
|
||||||
|
{
|
||||||
|
char *zfile;
|
||||||
|
struct stat s;
|
||||||
|
boolean fret;
|
||||||
|
|
||||||
|
zfile = zsreceived_name (qsys, ztemp);
|
||||||
|
if (zfile == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (stat (zfile, &s) < 0)
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno));
|
||||||
|
ubuffree (zfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore the file (return FALSE) if it is over one week old. */
|
||||||
|
fret = s.st_mtime + 7 * 24 * 60 * 60 >= time ((time_t *) NULL);
|
||||||
|
|
||||||
|
if (fret)
|
||||||
|
DEBUG_MESSAGE1 (DEBUG_SPOOLDIR, "fsysdep_already_received: Found %s",
|
||||||
|
zfile);
|
||||||
|
|
||||||
|
ubuffree (zfile);
|
||||||
|
|
||||||
|
return fret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forget that we have received a file. */
|
||||||
|
|
||||||
|
/*ARGSUSED*/
|
||||||
|
boolean
|
||||||
|
fsysdep_forget_reception (qsys, zto, ztemp)
|
||||||
|
const struct uuconf_system *qsys;
|
||||||
|
const char *zto;
|
||||||
|
const char *ztemp;
|
||||||
|
{
|
||||||
|
char *zfile;
|
||||||
|
|
||||||
|
zfile = zsreceived_name (qsys, ztemp);
|
||||||
|
if (zfile == NULL)
|
||||||
|
return TRUE;
|
||||||
|
if (remove (zfile) < 0
|
||||||
|
&& errno != ENOENT)
|
||||||
|
{
|
||||||
|
ulog (LOG_ERROR, "remove (%s): %s", zfile, strerror (errno));
|
||||||
|
ubuffree (zfile);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user