summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schulze <joey@finlandia.infodrom.north.de>2001-11-22 21:54:13 +0100
committerMartin Schulze <joey@finlandia.infodrom.north.de>2001-11-22 21:54:13 +0100
commit97afb2c3d2d8a80cfbd7b1d5de2d4f366cea85db (patch)
tree1426f02a0dc78135c32a106958723ff150a567a4
Import uucpsend_1.1.orig.tar.gz
[dgit import orig uucpsend_1.1.orig.tar.gz]
-rw-r--r--COPYING339
-rw-r--r--ChangeLog14
-rw-r--r--Makefile44
-rw-r--r--log.c75
-rw-r--r--log.h37
-rw-r--r--paths.h52
-rw-r--r--readme96
-rw-r--r--uucpsend.8122
-rw-r--r--uucpsend.c620
-rw-r--r--uucpsend.ctl27
-rw-r--r--uucpsend.ctl.5126
11 files changed, 1552 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..e77696a
--- /dev/null
+++ b/COPYING
@@ -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.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..758f92b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,14 @@
+2001-11-22 Martin Schulze <joey@finlandia.infodrom.north.de>
+
+ * Version 1.1 (Bugfix release)
+
+ * Corrected broken makelock() routine
+
+ * Support -c file for an alternative config file
+
+ * Properly ignore empty lines of config file
+
+ * Better error handling with logfile
+
+ * Improved Makefile
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0d553cd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,44 @@
+# Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+
+# Makefile for uucpsend
+
+CC = gcc
+CFLAGS = -O3 -Wall
+DEST=
+MAN=man
+NEWS=news
+OBJS=uucpsend.o log.o
+STRIP=-s
+
+uucpsend: $(OBJS)
+
+clean:
+ rm -f $(OBJS) uucpsend
+
+install:
+ for d in $(DEST)/usr/lib/news/bin $(DEST)/etc/news $(DEST)/usr/man/man{5,8}; \
+ do \
+ if [ ! -d $$d ]; then install -m 755 -o root -g root -d $$d ; fi; \
+ done
+ install -m 755 -o root -g root $(STRIP) uucpsend $(DEST)/usr/lib/news/bin
+ install -m 644 -o $(NEWS) -g $(NEWS) uucpsend.ctl $(DEST)/etc/news
+ install -m 644 -o $(MAN) -g $(MAN) uucpsend.8 $(DEST)/usr/man/man8
+ install -m 644 -o $(MAN) -g $(MAN) uucpsend.ctl.5 $(DEST)/usr/man/man5
+
+
+log.o: log.c log.h
+uucpsend.o: uucpsend.c paths.h
diff --git a/log.c b/log.c
new file mode 100644
index 0000000..ae9f02b
--- /dev/null
+++ b/log.c
@@ -0,0 +1,75 @@
+/*
+ Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+*/
+
+/*
+** Write log into a file and not via syslog
+*/
+
+#include <stdio.h>
+#include <time.h>
+#include <stdarg.h>
+
+FILE *logfile = NULL;
+
+char *months[] =
+{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+void
+openlogfile(char *name)
+{
+ logfile = fopen(name,"a");
+}
+
+void
+closelogfile()
+{
+ if (logfile)
+ (void)fclose(logfile);
+}
+
+void
+filelog(char *format, ...)
+{
+
+ va_list argp;
+ time_t timer;
+ struct tm *loctime;
+
+/* Output should be:
+ * May 21 10:54:18
+ */
+
+ if (logfile) {
+ timer = time ( NULL );
+ loctime = localtime(&timer);
+ fprintf(logfile, "%s %2d %2d:%02d:%02d ",
+ months[loctime->tm_mon], loctime->tm_mday, loctime->tm_hour, loctime->tm_min, loctime->tm_sec);
+ va_start(argp, format);
+ vfprintf(logfile, format, argp);
+ fprintf(logfile, "\n");
+ va_end(argp);
+ fflush(logfile);
+ }
+ else {
+ va_start(argp, format);
+ vfprintf(stderr, format, argp);
+ fprintf (stderr, "\n");
+ va_end(argp);
+ fflush(stderr);
+ }
+}
diff --git a/log.h b/log.h
new file mode 100644
index 0000000..995e4dd
--- /dev/null
+++ b/log.h
@@ -0,0 +1,37 @@
+/*
+ Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+*/
+
+/*
+** Write log into a file and not via syslog
+*/
+
+#ifndef __log_h__
+#define __log_h__
+
+void
+openlogfile(char *name);
+
+void
+closelogfile();
+
+/* Writes into the logfile, using variable number of arguments.
+ */
+void
+filelog(char *format, ...);
+
+#endif /* __log_h__ */
diff --git a/paths.h b/paths.h
new file mode 100644
index 0000000..8045adc
--- /dev/null
+++ b/paths.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+*/
+
+/*
+** Define paths for uucpsend
+*/
+
+#ifndef __paths_h__
+#define __paths_h__
+
+/* All of the following defines are originally made in
+** ~inn-1.5/include/paths.h. This is only a good asumption, it would
+** be better to use the original though.
+*/
+
+#define _PATH_LOCKS "/var/run/innd"
+#define _PATH_BATCHDIR "/var/spool/news/out.going"
+#define _PATH_NEWSBIN "/usr/lib/news/bin"
+#define _PATH_MOST_LOGS "/var/log/news"
+
+/*
+** End of copy
+*/
+
+#define PATH_CTLINND _PATH_NEWSBIN "/ctlinnd"
+#define PATH_MV "/bin/mv"
+#define PATH_CAT "/bin/cat"
+#define PATH_RM "/bin/rm"
+#define PATH_DF "/bin/df"
+#define PATH_DU "/usr/bin/du"
+#define PATH_TOUCH "/usr/bin/touch"
+#define PATH_SORT "/usr/bin/sort"
+#define PATH_UUX "/usr/bin/uux"
+#define PATH_UUSPOOL "/var/spool/uucp"
+#define PATH_UUCPCTL "/etc/news/uucpsend.ctl"
+
+#endif /* __paths_h__ */
diff --git a/readme b/readme
new file mode 100644
index 0000000..24bb581
--- /dev/null
+++ b/readme
@@ -0,0 +1,96 @@
+Welcome to UUCP-Send
+--------------------
+
+This package provides an alternative frontend for batching News with
+INN for delivering over UUCP. You can use it instead of the provided
+send-uucp script.
+
+The program ``uucpsend'' offers a comfortable way to do news batching
+for UUCP connected sited. The program does not do the batching
+itself. Instead it lets commonly used tools do the work. However it
+controls their behaviour. Using ``uucpsend'' you can define detailed
+how batching for each site shall take place in an easy fashion.
+
+An example
+
+Think of the following files in /etc/news:
+
+ uucpsend.ctl:
+
+ /default/:2000:500:cunbatch:compress:-r -n
+ satu:8000:1000:cunbatch:compress:-r -n
+ rakastava:5000:1000:zunbatch:gzip:-r -n
+ kyllikki:1000:500:gunbatch:gzip -9:-r
+
+ uucpsend.ctl-slowlinks:
+
+ malinconia:1000:200:cunbatch:compress:-r -n
+ rakastava:1000:200:cunbatch:compress:-r -n
+ intrada:1000:200:cunbatch:compress:-r -n
+
+Assume you also have the following lines in the crontab of the user
+``news''.
+
+ 5 * * * * uucpsend rakastava kyllikki luonnotar bardi
+ 24,54 * * * * uucpsend satu
+ 7 1 * * * uucpsend -f slow
+
+Decoding this shows that the sites rakastava, kyllikki, luonnotar and
+bardi are fed once an hour. These are big sites that get a lot of
+stuff. But they're still handled differently. While there may be
+stored up to 5MB of UUCP data for rakastava, the spool for kyllikki
+must not exceed 1MB. The next two sites, luonnotar and bardi, are not
+listed in any uucpsend.ctl file so the default settings are used.
+This reads as they may only use up to 2MB of UUCP spool.
+
+The second line in the crontab feeds a very big site that polls this
+server quite often and gets a large amount of olds, err news. Its
+spoll directory may store up to 8MB of data while batching takes place
+twice an hour.
+
+The last line covers a bunch of slow sites that tend to poll the
+server once per night but have only a slow connection. In my case
+this is a non-profit organisation of free radio groups. Since no
+sitenames are specified on the commandline uucpsend loops through the
+file and batches for every site.
+
+
+Compatibility with INN 2
+------------------------
+
+This package currently does not run with INN 2. This is due to the
+inavailability of an INN 2 server for the author. If you are running
+uucpsend and would like to switch to INN 2, please test if this
+package will continue to work and contact me.
+
+ 1. You'll have to fetch the source package and compile a new package
+ for INN 2 on your own.
+
+ 2. Edit the file paths.h and change _PATH_LOCKS to /var/run/news
+
+ 3. Edit the file paths.h and change _PATH_BATCHDIR to
+ /var/spool/news/outgoing
+
+ 4. Recompile and package
+
+ 5. Cross fingers
+
+ 6. Install
+
+ 7. Find out if it works.
+
+
+The author
+----------
+
+I apologize for writing this tool in 1995 but releasing it in 1998.
+However it was linked from my web pages from the beginning.
+
+This package is mentioned publically on the web at
+
+ http://www.infodrom.org/projects/uucpsend/
+
+Please send me comments, patches and good ideas.
+
+Martin Schulze <joey@infodrom.org>
+
diff --git a/uucpsend.8 b/uucpsend.8
new file mode 100644
index 0000000..df579aa
--- /dev/null
+++ b/uucpsend.8
@@ -0,0 +1,122 @@
+.\" Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+.\"
+.TH uucpsend 8 "21 November 2001" "Infodrom" "Programmer's Manual"
+.SH NAME
+uucpsend \- Alternative frontend for uucp batching
+.SH SYNOPSYS
+.B uucpsend
+.RB [ " \-c \fIconfig\fB " ]
+.RB [ " \-f \fIappendix\fB " ]
+.I sitename
+.RI [ " sitename ... " ]
+
+This program offers a comfortable way to do news batching with the INN
+news system. Like the name assumes it is used for sites that are
+connected via UUCP. The idea behind the mechanism is taken from the
+.B nntpsend
+program which is already included in distributions of INN.
+
+The program does not do the batching itself. Instead it lets commonly
+used tools do the work. However it controls their behaviour. Using
+.B uucpsend
+you can define detailed how batching for each site shall take place in
+an easy fashion.
+
+In the file
+.BR uucpsend.ctl (5)
+for each site your server feeds you can specify the size of batches,
+the maximal disk space that may be used by the uucp site, the header
+that should be written in the batch (e.g. funbatch, cunbatch, gunbatch
+etc.), the compression program to use as well as additional arguments
+passed to
+.BR uux (8).
+
+The
+.I sitename
+should be the name of the site as specified in the
+.BR newsfeeds (5)
+file. If no sitenames are passed to the program it will loop over all
+sites that described in the configuration file. This makes it easy to
+maintain sets of sites that are to be batched one after the other -
+contrary to batching through the whole day.
+
+A
+.BR batcher (8)
+is launched for sites with queued news.
+Output is sent to the file
+.\" =()<.IR @<_PATH_MOST_LOGS>@/uucpsend.log .>()=
+.IR /var/log/news/uucpsend.log .
+In order to keep from overwhelming the local system,
+.B uucpsend
+waits five seconds before the next site is fed.
+.B Uucpsend
+expects that the batchfile for a site is named
+.\" =()<.IR @<_PATH_BATCHDIR>@/sitename .>()=
+.IR /var/spool/news/out.going/sitename .
+To prevent batchfile corruption,
+.BR shlock (1)
+is used to ``lock'' these files.
+
+It is useful to have
+.BR cron (8)
+invoke
+.BR uucpsend .
+.PP
+When no
+.I sites
+are given on the command line, any flags given on the command
+completely describe how
+.B batcher
+operate.
+When no sites are given on the command line, then
+the information found in
+.B uucpsend.ctl
+becomes the default flags for that sites.
+.SH OPTIONS
+.TP
+.BI \-f " config"
+Using this parameter you are able to specify a file different to
+PATH_UUCPCTL which defaults to
+.IR /etc/news/uucpsend.ctl .
+.TP
+.BI \-f " appendix"
+With the parameter
+.RB `` -f ''
+you may specify another
+.BR uucpsend.ctl (5)
+file. Information with regard to also given sitenames are read from the
+.IR uucpsend.ctl "\-file."
+Please keep in mind that all default values are still read from the
+main
+.I uucpsend.ctl
+file. This feature has been added to let big sites easily specify a
+different batching behaviour.
+
+
+.SH HISTORY
+Written by Martin Schulze <joey@infodrom.org>, derived mostly from
+.BR nntpsend (8)
+by Landon Curt Noll <chongo@toad.com>
+and Rich $alz <rsalz@uunet.uu.net> for InterNetNews.
+.PP
+.SH "SEE ALSO"
+.BR innxmit (1),
+.BR newsfeeds (5),
+.BR uucpsend.ctl (5),
+.BR nntppsend (8),
+.BR nntppsend.ctl (5),
+.BR shrinkfile (1).
diff --git a/uucpsend.c b/uucpsend.c
new file mode 100644
index 0000000..717f7b3
--- /dev/null
+++ b/uucpsend.c
@@ -0,0 +1,620 @@
+/*
+ Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+*/
+
+/*
+** Read batchfiles and configs and batch them via uucp
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include "paths.h"
+/*#include "libinn.h"*/
+#include "log.h"
+
+#define LINELENGTH 255
+#define DELIMITER ':'
+#define UUXFLAGS "- -gd"
+#define DEFAULT_SITE "/default/"
+#define SPOOLFREE 50 * 1024
+
+struct s_site {
+ char *name;
+ int maxsize;
+ int queuesize;
+ char *header;
+ char *compressor;
+ char *uuxargs;
+ struct s_site *next;
+};
+
+char arg_ctlfile[255] = PATH_UUCPCTL;
+char arg_ctlappendix[255] = "";
+char arg_sites[1024] = "";
+struct s_site *sites = NULL;
+
+int
+makelock(what)
+char *what;
+{
+ char path[255];
+ FILE *lock;
+ struct stat stats;
+
+ if (what[0] == '/')
+ sprintf(path, "%s", what);
+ else
+ sprintf(path, "%s/LOCK.%s", _PATH_LOCKS, what);
+
+ if (stat(path, &stats) == 0) {
+ filelog("Lock file `%s' already exists.", path);
+ return 0;
+ }
+ if (errno == ENOENT) {
+ if (!(lock = fopen(path, "w"))) {
+ filelog("Can't open lock file `%s'.", path);
+ return 0;
+ }
+ fprintf(lock, "%10d\n", getpid());
+ fclose (lock);
+ return 1;
+ }
+ return 0; /* not reached */
+}
+
+void
+removelock(what)
+char *what;
+{
+ char path[255];
+ struct stat stats;
+
+ if (what[0] == '/')
+ sprintf(path, "%s", what);
+ else
+ sprintf(path, "%s/LOCK.%s", _PATH_LOCKS, what);
+
+ if (stat(path, &stats) == 0)
+ unlink(path);
+}
+
+/*
+ * Parse the arguments and fill global data structures
+ */
+static void
+parse_args(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int argch;
+
+ while (EOF != (argch = getopt(argc, argv, "f:c:"))) {
+ switch (argch) {
+ default:
+ printf ("usage();\n");
+ case 'c':
+ strncpy (arg_ctlfile, optarg, sizeof (arg_ctlfile));
+ break;
+ case 'f':
+ strncpy (arg_ctlappendix, optarg, sizeof (arg_ctlappendix));
+ break;
+ }
+ }
+ if (optind < argc) {
+ while (optind < argc) {
+ strcat(arg_sites, argv[optind++]);
+ sprintf(arg_sites, "%s%c", arg_sites, DELIMITER);
+ }
+ arg_sites[strlen(arg_sites)-1] = '\0';
+ }
+}
+
+/* Parse the uucpsend.ctl files
+ * Format:
+ * site:queuesize:max_size:header:compressor:[<args...>]
+ *
+ */
+int
+parse_ctlfile(fname)
+char *fname;
+{
+ FILE *ctlfile;
+ char line[LINELENGTH], field[LINELENGTH];
+ char *cp = line, *cp2;
+ int lcount = 0;
+ struct s_site *tmpsite = NULL;
+
+ if ((ctlfile = fopen(fname, "r")) == NULL) {
+ fprintf(stderr, "Can't open file `%s' for reading.\n", fname);
+ return -1;
+ }
+
+ cp = fgets(line, LINELENGTH, ctlfile);
+ for (; cp != NULL ; cp = fgets(line, LINELENGTH, ctlfile) ) {
+ lcount++;
+
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = '\0';
+
+ /* Skip the rest of the line if there's a comment sign */
+ if ((cp2 = strchr (line, '#')))
+ *cp2 = '\0';
+
+ /* Remove trailing whitespace characters */
+ for (cp2 = line + strlen(line)-1; cp2 >= line && (*cp2 == ' ' || *cp2 == '\t'); cp2--)
+ if (*cp2 == ' ' || *cp2 == '\t')
+ *cp2 = '\0';
+
+ /* Skip comments */
+ if (!strlen(line))
+ continue;
+
+
+ if ((tmpsite = (struct s_site *)malloc(sizeof (struct s_site))) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return -2;
+ }
+ tmpsite->next = NULL;
+
+ /* Fill the structure, one by one */
+ if ((cp2 = index(cp, DELIMITER)) == NULL) {
+ fprintf(stderr, "%s:%d invalid line.\n", fname, lcount);
+ continue;
+ }
+ strncpy(field, cp, (int)cp2 - (int)cp);
+ field[(int)cp2 - (int)cp] = '\0';
+ if ((tmpsite->name = (char *)malloc(strlen(field)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return -2;
+ }
+ strcpy(tmpsite->name, field);
+ cp += strlen(field) +1;
+
+
+ if ((cp2 = index(cp, DELIMITER)) == NULL) {
+ fprintf(stderr, "%s:%d invalid line.\n", fname, lcount);
+ continue;
+ }
+ strncpy(field, cp, (int)cp2 - (int)cp);
+ field[(int)cp2 - (int)cp] = '\0';
+ tmpsite->maxsize = atoi(field);
+ cp += strlen(field) +1;
+
+
+ if ((cp2 = index(cp, DELIMITER)) == NULL) {
+ fprintf(stderr, "%s:%d invalid line.\n", fname, lcount);
+ continue;
+ }
+ strncpy(field, cp, (int)cp2 - (int)cp);
+ field[(int)cp2 - (int)cp] = '\0';
+ tmpsite->queuesize = atoi(field);
+ cp += strlen(field) +1;
+
+
+ if ((cp2 = index(cp, DELIMITER)) == NULL) {
+ fprintf(stderr, "%s:%d invalid line.\n", fname, lcount);
+ continue;
+ }
+ strncpy(field, cp, (int)cp2 - (int)cp);
+ field[(int)cp2 - (int)cp] = '\0';
+ if ((tmpsite->header = (char *)malloc(strlen(field)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return -2;
+ }
+ strcpy(tmpsite->header, field);
+ cp += strlen(field) +1;
+
+
+ if ((cp2 = index(cp, DELIMITER)) == NULL) {
+ fprintf(stderr, "%s:%d invalid line.\n", fname, lcount);
+ continue;
+ }
+ strncpy(field, cp, (int)cp2 - (int)cp);
+ field[(int)cp2 - (int)cp] = '\0';
+ if ((tmpsite->compressor = (char *)malloc(strlen(field)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return -2;
+ }
+ strcpy(tmpsite->compressor, field);
+ cp += strlen(field) +1;
+
+
+ if ((tmpsite->uuxargs = (char *)malloc(strlen(cp)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return -2;
+ }
+ strcpy(tmpsite->uuxargs, cp);
+
+
+ /* Now that we've got an entry, we have to insert it into the
+ * data structure
+ */
+ if (!strcmp(tmpsite->name, DEFAULT_SITE)) {
+ if (sites) { /* missing: replacement of existing /default/ */
+ tmpsite->next = sites;
+ sites = tmpsite;
+ tmpsite = NULL;
+ } else {
+ sites = tmpsite;
+ tmpsite = NULL;
+ }
+ } else {
+ if (!sites) {
+ sites = tmpsite;
+ tmpsite = NULL;
+ } else {
+ if (sites->next) {
+ tmpsite->next = sites->next;
+ sites->next = tmpsite;
+ tmpsite = NULL;
+ } else {
+ sites->next = tmpsite;
+ tmpsite = NULL;
+ }
+ }
+ }
+ }
+
+ fclose (ctlfile);
+ return 0;
+}
+
+void
+free_sites(root)
+struct s_sites *root;
+{
+ struct s_site *act;
+ struct s_site *tmp = NULL;
+
+ (struct s_sites *)act = (struct s_sites *)root;
+
+ while (act) {
+ tmp = act;
+ act = act->next;
+
+ tmp->next = NULL;
+ free(tmp->name);
+ free(tmp->header);
+ free(tmp->compressor);
+ free(tmp->uuxargs);
+ free(tmp);
+ }
+}
+
+struct s_site *
+copy_site(site, name)
+struct s_site *site;
+char *name;
+{
+ struct s_site *tmpsite = NULL;
+
+ if ((tmpsite = (struct s_site *)malloc(sizeof (struct s_site))) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return NULL;
+ }
+ tmpsite->next = NULL;
+
+ if ((tmpsite->name = (char *)malloc(strlen(name)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return NULL;
+ }
+ strcpy(tmpsite->name, name);
+ tmpsite->queuesize = site->queuesize;
+ tmpsite->maxsize = site->maxsize;
+
+ if ((tmpsite->header = (char *)malloc(strlen(site->header)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return NULL;
+ }
+ strcpy(tmpsite->header, site->header);
+
+ if ((tmpsite->compressor = (char *)malloc(strlen(site->compressor)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return NULL;
+ }
+ strcpy(tmpsite->compressor, site->compressor);
+
+ if ((tmpsite->uuxargs = (char *)malloc(strlen(site->uuxargs)+1)) == NULL) {
+ fprintf(stderr, "Can't malloc.\n");
+ return NULL;
+ }
+ strcpy(tmpsite->uuxargs, site->uuxargs);
+
+ return tmpsite;
+}
+
+char *
+extract_site(keep, site)
+char *keep;
+char *site;
+{
+ char tempo1[1024], tempo2[1024];
+ char *cp1, *cp2;
+
+/* printf ("extract keep is '%s'\n", keep);
+ printf ("extract site is '%s'\n", site);*/
+ memset(tempo1, 0, sizeof(tempo1));
+ memset(tempo2, 0, sizeof(tempo2));
+
+ cp1 = keep;
+ if (!(cp2 = strstr(keep, site)))
+ return keep;
+
+ strncpy(tempo1, keep, (int)cp2 - (int)cp1);
+/* printf ("extract cp2 is '%s'\n", cp2);
+ printf ("extract cp2 is '%d'\n", cp2);
+ printf ("extract cp1 is '%d'\n", cp1);
+ printf ("extract cp2-1 is '%d'\n", (int)cp2 - (int)cp1);*/
+ if (tempo1[strlen(tempo1)-1] == DELIMITER) tempo1[strlen(tempo1)-1] = '\0';
+/* printf ("extract tempo1 is '%s'\n", tempo1);*/
+
+ cp2 += strlen(site);
+ if (cp2[0] == DELIMITER) cp2++;
+ sprintf(tempo2, "%s", cp2);
+/* printf ("extract tempo2 is '%s'\n", tempo2);*/
+
+ if (strlen(tempo1) > 0) {
+ if (strlen(tempo2) > 0)
+ sprintf(keep, "%s%c%s", tempo1, DELIMITER, tempo2);
+ else
+ sprintf(keep, "%s", tempo1);
+ }
+ else {
+ if (strlen(tempo2) > 0)
+ sprintf(keep, "%s", tempo2);
+ else
+ keep[0] = '\0';
+ }
+/* printf ("extract tempo1 is '%s'\n", tempo1);
+ printf ("extract tempo2 is '%s'\n", tempo2);
+ printf ("extract -> '%s'\n", keep);*/
+ return keep;
+}
+
+void
+trimm_sites(keep)
+char *keep;
+{
+ struct s_site *newsites = NULL, *tmp = NULL, *act;
+ char *kp = keep, *cp, *cp2;
+ char site[20];
+
+ for (act = sites->next; act; act = act->next) {
+ if (strstr(keep, act->name)) {
+ tmp = copy_site(act, act->name);
+ kp = extract_site(kp, act->name);
+ }
+
+ /* copy the entry */
+ if (tmp) {
+ tmp->next = newsites;
+ newsites = tmp;
+ tmp = NULL;
+ }
+ }
+
+
+ if (strlen(keep) > 0) {
+ for (cp = strchr(keep, DELIMITER); cp ; cp = strchr(keep, DELIMITER)) {
+ cp2 = keep;
+ strncpy(site, keep, (int)cp - (int)cp2);
+ extract_site(keep, site);
+ tmp = copy_site(sites, site);
+
+ /* copy the entry */
+ if (tmp) {
+ tmp->next = newsites;
+ newsites = tmp;
+ tmp = NULL;
+ }
+ }
+ }
+
+ free_sites(sites);
+ sites = newsites;
+}
+
+void
+loopthrough()
+{
+ struct s_site *site;
+ char batchfile[255];
+ char batchtmp[255];
+ char cmd[1024];
+ char uuxcmd[1024];
+ char line[1024];
+ char *cp;
+ int ret;
+ int freespace;
+ int maxsize;
+ struct stat stats;
+ FILE *pcmd;
+
+ for (site = sites;site; site=site->next) {
+ filelog("start %s", site->name);
+ if (makelock(site->name)) {
+
+/* 1st step - Check free space on the partition
+ */
+ sprintf(cmd, "%s -P %s ", PATH_DF, PATH_UUSPOOL);
+ pcmd = popen(cmd, "r");
+
+ cp = fgets(line, 1024, pcmd); /* skip first line */
+ cp = fgets(line, 1024, pcmd);
+ sscanf(line, "%*s %*d %*d %d", &freespace);
+ pclose(pcmd);
+
+ if (freespace < SPOOLFREE) {
+ filelog("No space left on uucp spool device (%s, %d)", PATH_UUSPOOL, freespace);
+ removelock(site->name);
+ filelog("end %s", site->name);
+ continue;
+ }
+
+/* 2nd step - get the batchfile
+ */
+ sprintf(batchfile, "%s/%s.uucp", _PATH_BATCHDIR, site->name);
+ sprintf(batchtmp, "%s/%s.work", _PATH_BATCHDIR, site->name);
+ if (stat(batchtmp, &stats) == 0) {
+ sprintf(cmd, "%s %s >> %s; %s -f %s", PATH_CAT, batchtmp, batchfile, PATH_RM, batchtmp);
+ ret = system(cmd);
+ }
+ sprintf(cmd, "%s -s -t30 flush %s", PATH_CTLINND, site->name);
+ if ((ret = system (cmd))) {
+ filelog("Can't flush %s", site->name);
+ if ((stat(batchfile, &stats) == 0) && (stats.st_size == 0)) {
+ sprintf(cmd, "%s -f %s", PATH_RM, batchfile);
+ ret = system(cmd);
+ }
+ removelock(site->name);
+ filelog("end %s", site->name);
+ continue;
+ }
+ sprintf(cmd, "%s %s/%s %s; %s -s -t30 flush %s", PATH_MV, _PATH_BATCHDIR, site->name, batchtmp, PATH_CTLINND, site->name);
+ ret = system(cmd);
+ if (stat(batchfile, &stats) == 0) {
+ sprintf(cmd, "%s %s >> %s", PATH_CAT, batchfile, batchtmp);
+ ret = system(cmd);
+ }
+ sprintf(cmd, "%s %s | %s > %s; %s -f %s", PATH_CAT, batchtmp, PATH_SORT, batchfile, PATH_RM, batchtmp);
+ ret = system(cmd);
+
+ if ((stat(batchfile, &stats) == 0) && (stats.st_size == 0)) {
+ filelog("No articles for %s.", site->name);
+ sprintf(cmd, "%s -f %s", PATH_RM, batchfile);
+ ret = system(cmd);
+ removelock(site->name);
+ filelog("end %s", site->name);
+ continue;
+ }
+
+
+/* 3rd step - Check the site's queue size
+
+ if [ -n "${QUEUE}" ] ; then
+
+ # Get queue size from directory size
+ #
+ KBYTESQUEUED=`du -s "$UUSPOOL/${SITE}"| ${AWK} '{print $1}'`
+ if [ "${QUEUE}" -lt ${KBYTESQUEUED} ] ; then
+ echo "`date +"%b %d %T"` ${PROGNAME}[$$]: ${SITE} has ${KBYTESQUEUED} kbytes queued." 1>&2
+ rm -f ${LOCK}
+ echo "`date +"%b %d %T"` ${PROGNAME}[$$]: end ${SITE}" 1>&2
+ continue
+ fi
+ fi
+
+ */
+
+ sprintf(cmd, "%s -s %s/%s ", PATH_DU, PATH_UUSPOOL, site->name);
+ pcmd = popen(cmd, "r");
+
+ cp = fgets(line, 1024, pcmd);
+ sscanf(line, "%d", &freespace);
+ pclose(pcmd);
+
+ if (freespace >= site->maxsize) {
+ filelog("No space left for %s", site->name);
+ removelock(site->name);
+ filelog("end %s", site->name);
+ continue;
+ }
+
+ maxsize = site->maxsize - freespace;
+
+/* 4th step - Build the command
+ */
+ sprintf(uuxcmd, "( echo \\\"#! %s\\\" ; %s ) | %s %s %s %s!rnews",
+ site->header, site->compressor, PATH_UUX, UUXFLAGS, site->uuxargs, site->name);
+
+/* 6th step - Create the batches
+
+${NEWSBIN}/feeds/batcher -B ${BATCHBYTES} -b ${MAXBYTES}000 -p "${UUXCOM}" \
+ ${SITE} ${BATCHFILE}
+ */
+
+ sprintf(cmd, "%s/batcher -B%d -b%d -p \"%s\" %s %s",
+ _PATH_NEWSBIN, maxsize * 1024, site->queuesize * 1024, uuxcmd, site->name, batchfile);
+ ret = system(cmd);
+
+ if ((stat(batchfile, &stats) == 0) && (stats.st_size == 0)) {
+ sprintf(cmd, "%s -f %s;", PATH_RM, batchfile);
+ ret = system(cmd);
+ }
+
+ removelock(site->name);
+ filelog("end %s", site->name);
+ }
+
+ sleep(5);
+ }
+}
+
+
+
+/*
+ * --------------- Main routine ---------------
+*/
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ char s[255];
+
+ parse_args(argc, argv);
+ if (parse_ctlfile (arg_ctlfile) < 0)
+ exit (-1);
+
+ sprintf(s, "%s/%s", _PATH_MOST_LOGS, "uucpsend.log");
+ openlogfile(s);
+
+ if (strcmp(sites->name,DEFAULT_SITE)) {
+ filelog("No default line given in control file.");
+ exit (-1);
+ }
+
+ if (strlen(arg_ctlappendix) > 0) {
+ if (strlen(arg_sites) == 0) {
+ free_sites (sites->next);
+ sites->next = NULL;
+ }
+ sprintf(s, "%s-%s", arg_ctlfile, arg_ctlappendix);
+ if (parse_ctlfile (s) < 0)
+ exit (-1);
+ }
+
+ if (strlen(arg_sites) > 0) {
+ trimm_sites(arg_sites);
+ } else {
+ /* site has to be freed, normally ;( */
+ sites = sites->next;
+ }
+
+ loopthrough();
+ free_sites(sites);
+ closelogfile();
+
+ exit (0);
+}
diff --git a/uucpsend.ctl b/uucpsend.ctl
new file mode 100644
index 0000000..b0fcf10
--- /dev/null
+++ b/uucpsend.ctl
@@ -0,0 +1,27 @@
+# Control file for uucpsend.
+#
+# Format:
+# site:queuesize:max_size:header:compressor:[<args...>]
+# <site> The name used in the newsfeeds file for this site;
+# this determines the name of the batchfile, etc.
+# <queuesize> Size of all batches for this system.
+# <max_size> Maximum size of one batch that is sent to this
+# system, see batcher(8).
+# <header> The string that written in the first line of
+# the batch.
+# <compressor> A program that should be used to compress each
+# batch.
+# <args> Other args to pass to uux.
+#
+# Everything after the pound sign is ignored.
+#
+# The default entry is very important. It's the only entry that is really
+# needed.
+#
+
+# First set defaults for all sites. These may be overwritten.
+#
+/default/:20:200:cunbatch:compress:-r -n
+
+#tuonela:200:100:gunbatch:gzip:-r -n
+#escher:2000:300:cunbatch:gzip:-n
diff --git a/uucpsend.ctl.5 b/uucpsend.ctl.5
new file mode 100644
index 0000000..2ca5569
--- /dev/null
+++ b/uucpsend.ctl.5
@@ -0,0 +1,126 @@
+.\" Copyright (c) 1995-8,2001 Martin Schulze <joey@infodrom.org>
+.\"
+.\" This program is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; if not, write to the Free Software
+.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+.\"
+.TH UUCPSEND.CTL 5 "21 November 2001" "Infodrom" "Administration"
+.SH NAME
+uucpsend.ctl \- list of sites to feed via uucpsend
+.SH DESCRIPTION
+The file
+.\" =()<.I @<_PATH_NEWSLIB>@/uucpsend.ctl>()=
+.I /etc/news/uucpsend.ctl
+specifies the default list of sites to be fed by
+.BR uucpsend (8).
+The program is able to read site information from other related
+configuration files as well.
+
+Comments begin with a hash mark (``#'') and continue through the end
+of the line.
+Blank lines and comments are ignored.
+All other lines should consist of six fields separated by a colon.
+Each line looks like
+
+.RS
+.nf
+.IR site : max_size : queue_size : header : compressor : args
+.fi
+.RE
+.PP
+
+The first field
+.I site
+is the name of the site as specified in the
+.BR newsfeeds (5)
+file. This is also the name of the UUCP system connected to this
+site.
+
+The second field
+.I max_size
+describes the maximum size of all batches in kbytes that may be sent
+to this site. If this amount of batches is reached, this site will
+not be batched with this run and a reason will be logged into the
+logfile. This test includs all UUCP jobs, not only the ones sent to
+rnews (performing ``du -s'').
+
+The third field
+.I queue_size
+specifies the maximum size in kbytes of one batch. This argument is
+passed directly to
+.BR batcher (8).
+
+The fourth field
+.I header
+defines the text that shall appear in the command header of every
+batch file. `#! ' is prefixed each batch. Normally you'll need
+.B cunbatch
+for compress,
+.B gunbatch
+or
+.B zunbatch
+for gzip. This header is important since there is not standard way to
+handle gzip'ed batches. Using this and the next argument you're also
+able to use any compressor you like. So you receive a certain amount
+of flexibility by using
+.BR uucpsend .
+If you don't want to have any compression leave the field empty.
+
+The fifth field
+.I compressor
+names a program that reads from stdin and writes to stdout. Normally
+it modifies the input stream by compressing it, such as
+.BR compress (1)
+or
+.BR gzip (1).
+
+The sixth field
+.I args
+consists of additional arguments that are passed directly to uux when
+sending the batch.
+
+One entry in the main configuration file is mandatory. There must
+exist a line containing the default values for all these variables.
+To achieve this the pseudo site
+.I "/default/"
+is used.
+
+One default entry could look like this:
+
+.RS
+.nf
+/default/:2000:200:cunbatch:compress:-r -n
+.fi
+.RE
+
+This reflects a minimal setup. The maximal size that may be used by
+the UUCP spool directory is 2MB. Each batch will be max. 200 kBytes
+big. The header of each batch will contain the string `cunbatch' and
+.BR compress (1)
+is used to compress the batches. `-r -n' is passed to
+.BR uux (1)
+which means no notification will be sent if uux was successful and uux
+won't start the
+.BR uucico (8)
+program when spooling the file.
+.SH HISTORY
+Written by Martin Schulze <joey@infodrom.org> for InterNetNews.
+Most of the work is derived from
+.BR nncpsend.ctl (5)
+by Landon Curt Noll <chongo@toad.com> for InterNetNews.
+
+.SH "SEE ALSO"
+.BR batcher (8),
+.BR newsfeeds (5),
+.BR uucpsend (8),
+.BR uux (1).