Taken on board suggestions of Mathieu Lirzin as per e-mails to the bug-mcron@gnu.org mailing list around September 2015.
This commit is contained in:
parent
024027ae2d
commit
c0a6eb14c2
20 changed files with 1155 additions and 664 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
|
@ -1,9 +1,20 @@
|
|||
*~
|
||||
*.o
|
||||
*.go
|
||||
.deps
|
||||
INSTALL
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
/build-aux/compile
|
||||
/build-aux/config.guess
|
||||
/build-aux/config.sub
|
||||
/build-aux/depcomp
|
||||
/build-aux/install-sh
|
||||
/build-aux/mdate-sh
|
||||
/build-aux/missing
|
||||
/build-aux/texinfo.tex
|
||||
compile
|
||||
config.cache
|
||||
config.log
|
||||
config.scm
|
||||
config.status
|
||||
|
|
@ -20,8 +31,6 @@ install-sh
|
|||
makefile
|
||||
makefile.in
|
||||
/mcron
|
||||
mcron.c
|
||||
/mdate-sh
|
||||
*.o
|
||||
missing
|
||||
texinfo.tex
|
||||
|
|
|
|||
5
AUTHORS
5
AUTHORS
|
|
@ -1,6 +1,6 @@
|
|||
Authors of GNU mcron.
|
||||
|
||||
Copyright (C) 2003, 2005, 2006 Dale Mellor
|
||||
Copyright (C) 2003, 2005, 2006, 2015 Dale Mellor
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
|
|
@ -16,3 +16,6 @@ The section of the manual which describes in detail the syntax for Vixie-style
|
|||
configuration files is copied verbatim from Paul Vixie's own distribution,
|
||||
on the understanding that this is permitted under his copyright notice,
|
||||
which is reproduced in its entirety in this section of the manual.
|
||||
|
||||
Further contributions have been received from Sergey Poznyakoff and Mathieu
|
||||
Lirzin, and incorporated where appropriate.
|
||||
|
|
|
|||
41
ChangeLog
41
ChangeLog
|
|
@ -1,3 +1,16 @@
|
|||
2015-10-22 Dale Mellor <dale@rdmp.org>
|
||||
|
||||
Taken on board suggestions of Mathieu Lirzin. This is mostly
|
||||
cosmetic code re-arranging and refresh for newer features of
|
||||
guile, but also:
|
||||
|
||||
* Eliminate the hacked embedding of the main scheme unit into the
|
||||
C source code.
|
||||
|
||||
* Compile all the guile modules before installation.
|
||||
|
||||
|
||||
|
||||
2015-07-01 Mathieu Lirzin <mthl@openmailbox.org>
|
||||
|
||||
* configure.ac: Fix package name and bug reports email address.
|
||||
|
|
@ -10,7 +23,7 @@
|
|||
* .gitignore: Ignore 'mcron' only in the top-level directory.
|
||||
|
||||
|
||||
2014-05-25 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2014-05-25 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* Juggled build infrastructure so that we can make the minimal man
|
||||
page in the proper autotools way.
|
||||
|
|
@ -18,14 +31,14 @@
|
|||
* configure.ac: version to 1.0.8.
|
||||
|
||||
|
||||
2014-04-28 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2014-04-28 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* We now run against, and require, guile-2.0.
|
||||
|
||||
* configure.ac: version to 1.0.7.
|
||||
|
||||
|
||||
2012-02-04 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2012-02-04 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* main.scm: added search for initial files in
|
||||
$XDG_CONFIG_HOME/cron directory, defaulting to ~/.config/cron if
|
||||
|
|
@ -34,7 +47,7 @@
|
|||
standards).
|
||||
|
||||
|
||||
2010-06-13 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2010-06-13 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* configure.ac: added --enable-no-vixie-clobber argument to
|
||||
configure so that the root user can avoid overwriting a legacy
|
||||
|
|
@ -47,7 +60,7 @@
|
|||
former is not supplied with the latest automake (1.11).
|
||||
|
||||
|
||||
2008-02-21 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2008-02-21 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* ALL FILES: Replaced version 2 GPL notices with version 3 ones.
|
||||
|
||||
|
|
@ -58,7 +71,7 @@
|
|||
* configure.ac: Bumped version to 1.0.4.
|
||||
|
||||
|
||||
2008-01-25 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2008-01-25 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* main.scm (command-type): Files which are listed on the command
|
||||
line are assumed to be guile configurations if they do not end in
|
||||
|
|
@ -76,7 +89,7 @@
|
|||
* Version is currently at 1.0.3.
|
||||
|
||||
|
||||
2005-09-02 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2005-09-02 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* makefile.am, mcron.c.template (main): Modified install-exec-hook
|
||||
so that a proper installation of a Vixie-compatible cron only
|
||||
|
|
@ -93,7 +106,7 @@
|
|||
* Bumped version to 1.0.2.
|
||||
|
||||
|
||||
2004-05-15 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2004-05-15 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* Modified all auxiliary files to reflect that the package is now
|
||||
properly homed at www.gnu.org.
|
||||
|
|
@ -101,7 +114,7 @@
|
|||
* Bumped version to 1.0.1.
|
||||
|
||||
|
||||
2003-12-11 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-12-11 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* Modified all auxiliary files to reflect that we are now a GNU
|
||||
package.
|
||||
|
|
@ -109,7 +122,7 @@
|
|||
* Bumped version to 1.0.0.
|
||||
|
||||
|
||||
2003-12-07 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-12-07 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* configure.ac: Added switches for files and directories used by
|
||||
mcron: --spool-dir, --socket-file, --allow-file, --deny-file,
|
||||
|
|
@ -118,14 +131,14 @@
|
|||
manual).
|
||||
|
||||
|
||||
2003-12-05 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-12-05 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* configure.ac: Added test for guile version >= 1.6.4.
|
||||
|
||||
* bumped version to 0.99.4.
|
||||
|
||||
|
||||
2003-08-03 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-08-03 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* Third cut, fully functional, modular, production quality, still
|
||||
needs testing...
|
||||
|
|
@ -136,7 +149,7 @@
|
|||
* Bumped version to 0.99.3.
|
||||
|
||||
|
||||
2003-07-20 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-07-20 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* Second cut, now _really_ fully functional (100% Vixie
|
||||
compatible), production quality code, still needs lots of testing
|
||||
|
|
@ -154,7 +167,7 @@
|
|||
* Bumped version to 0.99.2.
|
||||
|
||||
|
||||
2003-06-28 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
2003-06-28 Dale Mellor <dale_mellor@users.sourceforge.net>
|
||||
|
||||
* First cut, fully functional, production quality code, just needs
|
||||
testing...
|
||||
|
|
|
|||
9
TODO
9
TODO
|
|
@ -1,5 +1,6 @@
|
|||
GNU mcron --- TODO -*-text-*-
|
||||
|
||||
Copyright (C) 2015 Mathieu Lirzin
|
||||
Copyright (C) 2003, 2005, 2006, 2014 Dale Mellor
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
|
|
@ -19,6 +20,14 @@ Maybe in the near future...
|
|||
core or other users' files up. Then allow scheme code in the system
|
||||
crontabs.
|
||||
|
||||
* Make mcron behavior not depend on the name used to invoke it, to conform
|
||||
to GNU standards.
|
||||
|
||||
* Provide a test suite using SRFI-64 API.
|
||||
<http://srfi.schemers.org/srfi-64/srfi-64.html>.
|
||||
|
||||
* Internationalize Mcron using GNU Gettext and ask the Translation
|
||||
Project to handle the localization.
|
||||
|
||||
|
||||
There are no plans to actually do the following any time soon...
|
||||
|
|
|
|||
25
configure.ac
25
configure.ac
|
|
@ -2,8 +2,7 @@
|
|||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
|
||||
# Copyright (C) 2003, 2005, 2012, 2014 Dale Mellor
|
||||
# Copyright (C) 2015 Mathieu Lirzin
|
||||
# Copyright (C) 2003, 2005, 2012, 2014, 2015 Dale Mellor
|
||||
#
|
||||
# This file is part of GNU mcron.
|
||||
#
|
||||
|
|
@ -24,8 +23,13 @@
|
|||
AC_PREREQ(2.61)
|
||||
AC_INIT([GNU Mcron], [1.0.8], [bug-mcron@gnu.org])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AM_INIT_AUTOMAKE
|
||||
AM_INIT_AUTOMAKE([silent-rules])
|
||||
|
||||
# Enable silent rules by default.
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
guilemoduledir="${datarootdir}/guile/site/2.0"
|
||||
AC_SUBST([guilemoduledir])
|
||||
|
||||
AC_MSG_CHECKING([whether debugging is requested])
|
||||
AC_ARG_ENABLE(debug,
|
||||
|
|
@ -45,12 +49,19 @@ AC_SUBST(CONFIG_DEBUG)
|
|||
# We have no interest (hence a no-op), but Debian wants this.
|
||||
AC_ARG_ENABLE(maintainer-mode)
|
||||
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
AC_PROG_AWK
|
||||
AC_PROG_EGREP
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
PKG_CHECK_MODULES(GUILE, guile-2.0)
|
||||
PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.7])
|
||||
AC_PATH_PROG([GUILE], [guile])
|
||||
|
||||
# search guild
|
||||
AC_PATH_PROG([GUILD], [guild])
|
||||
if test "x$GUILD" = "x"; then
|
||||
AC_MSG_ERROR(['guild' binary not found; please check your guile-2.x installation.])
|
||||
fi
|
||||
|
||||
# Checks for programs.
|
||||
|
||||
|
|
@ -64,10 +75,6 @@ AC_CHECK_PROGS(HEAD, head)
|
|||
if test "x$ac_cv_prog_HEAD" = "x"; then
|
||||
AC_MSG_ERROR(head not found)
|
||||
fi
|
||||
AC_CHECK_PROGS(ED, ed)
|
||||
if test "x$ac_cv_prog_ED" = "x"; then
|
||||
AC_MSG_ERROR(ed not found)
|
||||
fi
|
||||
AC_CHECK_PROGS(WHICH, which)
|
||||
if test "x$ac_cv_prog_WHICH" = "x"; then
|
||||
AC_MSG_ERROR(which not found)
|
||||
|
|
|
|||
505
doc/fdl.texi
Normal file
505
doc/fdl.texi
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
@c The GNU Free Documentation License.
|
||||
@center Version 1.3, 3 November 2008
|
||||
|
||||
@c This file is intended to be included within another document,
|
||||
@c hence no sectioning command or @node.
|
||||
|
||||
@display
|
||||
Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
||||
@uref{http://fsf.org/}
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
@end display
|
||||
|
||||
@enumerate 0
|
||||
@item
|
||||
PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other
|
||||
functional and useful document @dfn{free} in the sense of freedom: to
|
||||
assure everyone the effective freedom to copy and redistribute it,
|
||||
with or without modifying it, either commercially or noncommercially.
|
||||
Secondarily, this License preserves for the author and publisher a way
|
||||
to get credit for their work, while not being considered responsible
|
||||
for modifications made by others.
|
||||
|
||||
This License is a kind of ``copyleft'', which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
@item
|
||||
APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work, in any medium, that
|
||||
contains a notice placed by the copyright holder saying it can be
|
||||
distributed under the terms of this License. Such a notice grants a
|
||||
world-wide, royalty-free license, unlimited in duration, to use that
|
||||
work under the conditions stated herein. The ``Document'', below,
|
||||
refers to any such manual or work. Any member of the public is a
|
||||
licensee, and is addressed as ``you''. You accept the license if you
|
||||
copy, modify or distribute the work in a way requiring permission
|
||||
under copyright law.
|
||||
|
||||
A ``Modified Version'' of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
A ``Secondary Section'' is a named appendix or a front-matter section
|
||||
of the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall
|
||||
subject (or to related matters) and contains nothing that could fall
|
||||
directly within that overall subject. (Thus, if the Document is in
|
||||
part a textbook of mathematics, a Secondary Section may not explain
|
||||
any mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
The ``Invariant Sections'' are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License. If a
|
||||
section does not fit the above definition of Secondary then it is not
|
||||
allowed to be designated as Invariant. The Document may contain zero
|
||||
Invariant Sections. If the Document does not identify any Invariant
|
||||
Sections then there are none.
|
||||
|
||||
The ``Cover Texts'' are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License. A Front-Cover Text may
|
||||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||||
|
||||
A ``Transparent'' copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, that is suitable for revising the document
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup, or absence of markup, has been arranged to thwart
|
||||
or discourage subsequent modification by readers is not Transparent.
|
||||
An image format is not Transparent if used for any substantial amount
|
||||
of text. A copy that is not ``Transparent'' is called ``Opaque''.
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain
|
||||
ASCII without markup, Texinfo input format, La@TeX{} input
|
||||
format, SGML or XML using a publicly available
|
||||
DTD, and standard-conforming simple HTML,
|
||||
PostScript or PDF designed for human modification. Examples
|
||||
of transparent image formats include PNG, XCF and
|
||||
JPG@. Opaque formats include proprietary formats that can be
|
||||
read and edited only by proprietary word processors, SGML or
|
||||
XML for which the DTD and/or processing tools are
|
||||
not generally available, and the machine-generated HTML,
|
||||
PostScript or PDF produced by some word processors for
|
||||
output purposes only.
|
||||
|
||||
The ``Title Page'' means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, ``Title Page'' means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
The ``publisher'' means any person or entity that distributes copies
|
||||
of the Document to the public.
|
||||
|
||||
A section ``Entitled XYZ'' means a named subunit of the Document whose
|
||||
title either is precisely XYZ or contains XYZ in parentheses following
|
||||
text that translates XYZ in another language. (Here XYZ stands for a
|
||||
specific section name mentioned below, such as ``Acknowledgements'',
|
||||
``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
|
||||
of such a section when you modify the Document means that it remains a
|
||||
section ``Entitled XYZ'' according to this definition.
|
||||
|
||||
The Document may include Warranty Disclaimers next to the notice which
|
||||
states that this License applies to the Document. These Warranty
|
||||
Disclaimers are considered to be included by reference in this
|
||||
License, but only as regards disclaiming warranties: any other
|
||||
implication that these Warranty Disclaimers may have is void and has
|
||||
no effect on the meaning of this License.
|
||||
|
||||
@item
|
||||
VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no other
|
||||
conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
@item
|
||||
COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies (or copies in media that commonly have
|
||||
printed covers) of the Document, numbering more than 100, and the
|
||||
Document's license notice requires Cover Texts, you must enclose the
|
||||
copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a computer-network location from which the general network-using
|
||||
public has access to download using public-standard network protocols
|
||||
a complete Transparent copy of the Document, free of added material.
|
||||
If you use the latter option, you must take reasonably prudent steps,
|
||||
when you begin distribution of Opaque copies in quantity, to ensure
|
||||
that this Transparent copy will remain thus accessible at the stated
|
||||
location until at least one year after the last time you distribute an
|
||||
Opaque copy (directly or through your agents or retailers) of that
|
||||
edition to the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to give
|
||||
them a chance to provide you with an updated version of the Document.
|
||||
|
||||
@item
|
||||
MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
@enumerate A
|
||||
@item
|
||||
Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
|
||||
@item
|
||||
List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has fewer than five),
|
||||
unless they release you from this requirement.
|
||||
|
||||
@item
|
||||
State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
|
||||
@item
|
||||
Preserve all the copyright notices of the Document.
|
||||
|
||||
@item
|
||||
Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
|
||||
@item
|
||||
Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
|
||||
@item
|
||||
Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
|
||||
@item
|
||||
Include an unaltered copy of this License.
|
||||
|
||||
@item
|
||||
Preserve the section Entitled ``History'', Preserve its Title, and add
|
||||
to it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section Entitled ``History'' in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
|
||||
@item
|
||||
Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the ``History'' section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
|
||||
@item
|
||||
For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
|
||||
the Title of the section, and preserve in the section all the
|
||||
substance and tone of each of the contributor acknowledgements and/or
|
||||
dedications given therein.
|
||||
|
||||
@item
|
||||
Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
|
||||
@item
|
||||
Delete any section Entitled ``Endorsements''. Such a section
|
||||
may not be included in the Modified Version.
|
||||
|
||||
@item
|
||||
Do not retitle any existing section to be Entitled ``Endorsements'' or
|
||||
to conflict in title with any Invariant Section.
|
||||
|
||||
@item
|
||||
Preserve any Warranty Disclaimers.
|
||||
@end enumerate
|
||||
|
||||
If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section Entitled ``Endorsements'', provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties---for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
@item
|
||||
COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice, and that you preserve all their Warranty Disclaimers.
|
||||
|
||||
The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections Entitled ``History''
|
||||
in the various original documents, forming one section Entitled
|
||||
``History''; likewise combine any sections Entitled ``Acknowledgements'',
|
||||
and any sections Entitled ``Dedications''. You must delete all
|
||||
sections Entitled ``Endorsements.''
|
||||
|
||||
@item
|
||||
COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other documents
|
||||
released under this License, and replace the individual copies of this
|
||||
License in the various documents with a single copy that is included in
|
||||
the collection, provided that you follow the rules of this License for
|
||||
verbatim copying of each of the documents in all other respects.
|
||||
|
||||
You may extract a single document from such a collection, and distribute
|
||||
it individually under this License, provided you insert a copy of this
|
||||
License into the extracted document, and follow this License in all
|
||||
other respects regarding verbatim copying of that document.
|
||||
|
||||
@item
|
||||
AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, is called an ``aggregate'' if the copyright
|
||||
resulting from the compilation is not used to limit the legal rights
|
||||
of the compilation's users beyond what the individual works permit.
|
||||
When the Document is included in an aggregate, this License does not
|
||||
apply to the other works in the aggregate which are not themselves
|
||||
derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one half of
|
||||
the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that bracket the Document within the aggregate, or the
|
||||
electronic equivalent of covers if the Document is in electronic form.
|
||||
Otherwise they must appear on printed covers that bracket the whole
|
||||
aggregate.
|
||||
|
||||
@item
|
||||
TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License, and all the license notices in the
|
||||
Document, and any Warranty Disclaimers, provided that you also include
|
||||
the original English version of this License and the original versions
|
||||
of those notices and disclaimers. In case of a disagreement between
|
||||
the translation and the original version of this License or a notice
|
||||
or disclaimer, the original version will prevail.
|
||||
|
||||
If a section in the Document is Entitled ``Acknowledgements'',
|
||||
``Dedications'', or ``History'', the requirement (section 4) to Preserve
|
||||
its Title (section 1) will typically require changing the actual
|
||||
title.
|
||||
|
||||
@item
|
||||
TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense, or distribute it is void, and
|
||||
will automatically terminate your rights under this License.
|
||||
|
||||
However, if you cease all violation of this License, then your license
|
||||
from a particular copyright holder is reinstated (a) provisionally,
|
||||
unless and until the copyright holder explicitly and finally
|
||||
terminates your license, and (b) permanently, if the copyright holder
|
||||
fails to notify you of the violation by some reasonable means prior to
|
||||
60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, receipt of a copy of some or all of the same material does
|
||||
not give you any rights to use it.
|
||||
|
||||
@item
|
||||
FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions
|
||||
of the GNU Free Documentation 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. See
|
||||
@uref{http://www.gnu.org/copyleft/}.
|
||||
|
||||
Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License ``or any later version'' applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation. If the Document
|
||||
specifies that a proxy can decide which future versions of this
|
||||
License can be used, that proxy's public statement of acceptance of a
|
||||
version permanently authorizes you to choose that version for the
|
||||
Document.
|
||||
|
||||
@item
|
||||
RELICENSING
|
||||
|
||||
``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any
|
||||
World Wide Web server that publishes copyrightable works and also
|
||||
provides prominent facilities for anybody to edit those works. A
|
||||
public wiki that anybody can edit is an example of such a server. A
|
||||
``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the
|
||||
site means any set of copyrightable works thus published on the MMC
|
||||
site.
|
||||
|
||||
``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0
|
||||
license published by Creative Commons Corporation, a not-for-profit
|
||||
corporation with a principal place of business in San Francisco,
|
||||
California, as well as future copyleft versions of that license
|
||||
published by that same organization.
|
||||
|
||||
``Incorporate'' means to publish or republish a Document, in whole or
|
||||
in part, as part of another Document.
|
||||
|
||||
An MMC is ``eligible for relicensing'' if it is licensed under this
|
||||
License, and if all works that were first published under this License
|
||||
somewhere other than this MMC, and subsequently incorporated in whole
|
||||
or in part into the MMC, (1) had no cover texts or invariant sections,
|
||||
and (2) were thus incorporated prior to November 1, 2008.
|
||||
|
||||
The operator of an MMC Site may republish an MMC contained in the site
|
||||
under CC-BY-SA on the same site at any time before August 1, 2009,
|
||||
provided the MMC is eligible for relicensing.
|
||||
|
||||
@end enumerate
|
||||
|
||||
@page
|
||||
@heading ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
Copyright (C) @var{year} @var{your name}.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.3
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
|
||||
Texts. A copy of the license is included in the section entitled ``GNU
|
||||
Free Documentation License''.
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||||
replace the ``with@dots{}Texts.''@: line with this:
|
||||
|
||||
@smallexample
|
||||
@group
|
||||
with the Invariant Sections being @var{list their titles}, with
|
||||
the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
|
||||
being @var{list}.
|
||||
@end group
|
||||
@end smallexample
|
||||
|
||||
If you have Invariant Sections without Cover Texts, or some other
|
||||
combination of the three, merge those two alternatives to suit the
|
||||
situation.
|
||||
|
||||
If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
||||
|
||||
@c Local Variables:
|
||||
@c ispell-local-pdict: "ispell-dict"
|
||||
@c End:
|
||||
|
|
@ -63,6 +63,7 @@ running jobs at scheduled times.
|
|||
* Syntax:: All the possibilities for configuring cron jobs.
|
||||
* Invoking:: What happens when you run the mcron command.
|
||||
* Guile modules:: Incorporating mcron into another Guile program.
|
||||
* GNU Free Documentation License:: The license of this manual.
|
||||
* Index:: The complete index.
|
||||
|
||||
@detailmenu
|
||||
|
|
@ -1329,6 +1330,11 @@ Once this module has been declared in a program, a crontab file can be
|
|||
used to augment the current job list with a call to
|
||||
@code{read-vixie-file}.
|
||||
|
||||
@node GNU Free Documentation License
|
||||
@appendix GNU Free Documentation License
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@node Index, , Guile modules, Top
|
||||
@unnumbered Index
|
||||
|
||||
|
|
|
|||
33
makefile.am
33
makefile.am
|
|
@ -1,6 +1,5 @@
|
|||
## Makefile for the toplevel directory of mcron.
|
||||
## Copyright (C) 2003 Dale Mellor
|
||||
## Copyright (C) 2015 Mathieu Lirzin
|
||||
## Copyright (C) 2003, 2015 Dale Mellor
|
||||
##
|
||||
# This file is part of GNU mcron.
|
||||
#
|
||||
|
|
@ -17,20 +16,13 @@
|
|||
# You should have received a copy of the GNU General Public License along
|
||||
# with GNU mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
## Process this file with automake to produce makefile.in
|
||||
|
||||
SUBDIRS = scm/mcron .
|
||||
|
||||
ED = @ED@ # !!!! Are these needed?
|
||||
CP = @CP@
|
||||
|
||||
MAINTAINERCLEANFILES = configure makefile makefile.in config.guess config.sub \
|
||||
install-sh missing texinfo.tex INSTALL \
|
||||
aclocal.m4 compile depcomp doc/mcron.1
|
||||
|
||||
CLEANFILES = mcron.c
|
||||
|
||||
EXTRA_DIST = makefile.ed mcron.c.template BUGS
|
||||
EXTRA_DIST = BUGS
|
||||
|
||||
info_TEXINFOS = doc/mcron.texi
|
||||
|
||||
|
|
@ -42,14 +34,7 @@ mcron_LDADD = @GUILE_LIBS@
|
|||
|
||||
# The second option is so that we can execute the binary in the local directory,
|
||||
# in turn so that we can do mcron --help during the build process.
|
||||
mcron_CFLAGS = @GUILE_CFLAGS@ -DGUILE_LOAD_PATH=\"$(datadir):./scm:...\"
|
||||
|
||||
|
||||
mcron.c : scm/mcron/main.scm scm/mcron/crontab.scm makefile.ed mcron.c.template
|
||||
@echo 'Building mcron.c...'
|
||||
@$(ED) < makefile.ed > /dev/null 2>&1
|
||||
@rm -f mcron.escaped.scm > /dev/null 2>&1
|
||||
|
||||
mcron_CFLAGS = @GUILE_CFLAGS@ -DGUILE_LOAD_PATH=\"$(datadir):./scm:...\"
|
||||
|
||||
# Full program prefix.
|
||||
fpp = $(DESTDIR)$(bindir)/@real_program_prefix@
|
||||
|
|
@ -79,11 +64,15 @@ uninstall-hook:
|
|||
|
||||
|
||||
# Not part of formal package building, but a rule for manual use to get the
|
||||
# elemental man page. Will only work once the mcron program is installed.
|
||||
$(dist_man_MANS): mcron.c
|
||||
# elemental man page.
|
||||
doc/mcron.1 : mcron
|
||||
$(HELP2MAN) -n 'a program to run tasks at regular (or not) intervals' \
|
||||
./mcron > $@
|
||||
./mcron > doc/mcron.1
|
||||
|
||||
|
||||
MAINTAINERCLEANFILES = configure makefile makefile.in config.guess config.sub \
|
||||
install-sh missing texinfo.tex INSTALL \
|
||||
aclocal.m4 compile depcomp doc/mcron.1
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -r build-aux
|
||||
|
|
|
|||
34
makefile.ed
34
makefile.ed
|
|
@ -1,34 +0,0 @@
|
|||
# Copyright (C) 2003 Dale Mellor
|
||||
#
|
||||
# This file is part of GNU mcron.
|
||||
#
|
||||
# GNU mcron 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 3 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU mcron 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 GNU mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
#
|
||||
#
|
||||
e scm/mcron/main.scm
|
||||
/\(load "crontab.scm"\)/d
|
||||
-1r scm/mcron/crontab.scm
|
||||
%s/\\/\\\\/g
|
||||
%s/"/\\"/g
|
||||
%s/ *;;.*$/ /g
|
||||
g/^ *$/d
|
||||
%s/^/\"/
|
||||
%s/$/\"/
|
||||
w mcron.escaped.scm
|
||||
e mcron.c.template
|
||||
/GUILE_PROGRAM_GOES_HERE/d
|
||||
-1r mcron.escaped.scm
|
||||
w mcron.c
|
||||
q
|
||||
115
mcron.c
Normal file
115
mcron.c
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* mcron.c -- Run the mcron program.
|
||||
*
|
||||
* Copyright (C) 2015 Mathieu Lirzin
|
||||
* Copyright (C) 2003, 2014 Dale Mellor
|
||||
*
|
||||
* This file is part of GNU Mcron.
|
||||
*
|
||||
* GNU Mcron 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU Mcron 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 GNU Mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* This C code represents the thinnest possible wrapper around the Guile code
|
||||
* which constitutes all the functionality of the mcron program. There are
|
||||
* two plus one reasons why we need to do this, and one very unfortunate
|
||||
* consequence.
|
||||
*
|
||||
* Firstly, SUID does not work on an executable script. In the end, it is
|
||||
* the execution of the translator, in our case guile, which determines the
|
||||
* effective user, and it is not wise to make the system guile installation
|
||||
* SUID root!
|
||||
*
|
||||
* Secondly, executable scripts show up in ugly ways in listings of the
|
||||
* system process table. Guile in particular, with its multi-line ``#! ...\
|
||||
* \n -s ...!#'' idiosyncracies shows up in process listings in a way that
|
||||
* is difficult to determine what program is actually running.
|
||||
*
|
||||
* A third reason for the C wrapper which might be mentioned is that a
|
||||
* security-conscious system administrator can choose to only install a
|
||||
* binary, thus removing the possibility of a user studying a guile script
|
||||
* and working out ways of hacking it to his own ends, or worse still
|
||||
* finding a way to modify it to his own ends.
|
||||
*
|
||||
* Unfortunately, running the guile script from inside a C program means
|
||||
* that the sigaction function does not work. Instead, it is necessary to
|
||||
* perform the signal processing in C.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <libguile.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
/* Handle the signal and exit. All signals that mcron handles will produce
|
||||
* the same behavior so we don't need to use the signal value in the
|
||||
* implementation. */
|
||||
|
||||
static void
|
||||
react_to_terminal_signal (int signal)
|
||||
{
|
||||
scm_c_eval_string ("(delete-run-file)");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Set up all the signal handlers as required by the cron personality. This
|
||||
* is necessary to perform the signal processing in C because the sigaction
|
||||
* function won't work when called from Guile; this function is called from
|
||||
* the Guile universe. */
|
||||
|
||||
static SCM
|
||||
set_cron_signals ()
|
||||
{
|
||||
static struct sigaction sa;
|
||||
|
||||
memset (&sa, 0, sizeof (sa));
|
||||
sa.sa_handler = react_to_terminal_signal;
|
||||
sigaction (SIGTERM, &sa, 0);
|
||||
sigaction (SIGINT, &sa, 0);
|
||||
sigaction (SIGQUIT, &sa, 0);
|
||||
sigaction (SIGHUP, &sa, 0);
|
||||
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Launch the Mcron Guile main program. */
|
||||
|
||||
static void
|
||||
inner_main (void *closure, int argc, char **argv)
|
||||
{
|
||||
scm_set_current_module (scm_c_resolve_module ("mcron main"));
|
||||
scm_c_define_gsubr ("c-set-cron-signals", 0, 0, 0, set_cron_signals);
|
||||
scm_c_eval_string ("(main)");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The real main function. Does nothing but start up the guile subsystem. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
setenv ("GUILE_LOAD_PATH", GUILE_LOAD_PATH, 1);
|
||||
scm_boot_guile (argc, argv, inner_main, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
mcron.c.template
120
mcron.c.template
|
|
@ -1,120 +0,0 @@
|
|||
/* -*-c-*- */
|
||||
/*
|
||||
* Copyright (C) 2003, 2014 Dale Mellor
|
||||
*
|
||||
* This file is part of GNU mcron.
|
||||
*
|
||||
* GNU mcron 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 3 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* GNU mcron 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 GNU mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
This C code represents the thinnest possible wrapper around the Guile code
|
||||
which constitutes all the functionality of the mcron program. There are two
|
||||
plus one reasons why we need to do this, and one very unfortunate
|
||||
consequence.
|
||||
|
||||
Firstly, SUID does not work on an executable script. In the end, it is
|
||||
the execution of the translator, in our case guile, which determines the
|
||||
effective user, and it is not wise to make the system guile installation
|
||||
SUID root!
|
||||
|
||||
Secondly, executable scripts show up in ugly ways in listings of the
|
||||
system process table. Guile in particular, with its multi-line
|
||||
#! ...\ \n -s ...!#
|
||||
idiosyncracies shows up in process listings in a way that is difficult
|
||||
to determine what program is actually running.
|
||||
|
||||
A third reason for the C wrapper which might be mentioned is that a
|
||||
security-conscious system administrator can choose to only install a
|
||||
binary, thus removing the possibility of a user studying a guile script
|
||||
and working out ways of hacking it to his own ends, or worse still
|
||||
finding a way to modify it to his own ends.
|
||||
|
||||
Unfortunately, running the guile script from inside a C program means
|
||||
that the sigaction function does not work. Instead, it is necessary to
|
||||
perform the signal processing in C.
|
||||
|
||||
The guile code itself is substituted for the GU1LE_PROGRAM_GOES_HERE (sic)
|
||||
token by the makefile, which processes the scheme to make it look like one
|
||||
big string.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <libguile.h>
|
||||
|
||||
|
||||
|
||||
/* This is a function designed to be installed as a signal handler, for signals
|
||||
which are supposed to initiate shutdown of this program. It calls the scheme
|
||||
procedure (see mcron.scm for details) to do all the work, and then exits. */
|
||||
|
||||
void
|
||||
react_to_terminal_signal (int sig)
|
||||
{
|
||||
scm_c_eval_string ("(delete-run-file)");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This is a function designed to be callable from scheme, and sets up all the
|
||||
signal handlers required by the cron personality. */
|
||||
|
||||
SCM
|
||||
set_cron_signals ()
|
||||
{
|
||||
static struct sigaction sa;
|
||||
memset (&sa, 0, sizeof (sa));
|
||||
sa.sa_handler = react_to_terminal_signal;
|
||||
sigaction (SIGTERM, &sa, 0);
|
||||
sigaction (SIGINT, &sa, 0);
|
||||
sigaction (SIGQUIT, &sa, 0);
|
||||
sigaction (SIGHUP, &sa, 0);
|
||||
|
||||
return SCM_BOOL_T;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The effective main function (i.e. the one that actually does some work). We
|
||||
register the function above with the guile system, and then execute the mcron
|
||||
guile program. */
|
||||
|
||||
void
|
||||
inner_main ()
|
||||
{
|
||||
scm_c_define_gsubr ("c-set-cron-signals", 0, 0, 0, set_cron_signals);
|
||||
|
||||
scm_c_eval_string (
|
||||
GUILE_PROGRAM_GOES_HERE
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* The real main function. Does nothing but start up the guile subsystem. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
setenv ("GUILE_LOAD_PATH", GUILE_LOAD_PATH, 1);
|
||||
|
||||
scm_boot_guile (argc, argv, inner_main, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
;; -*-scheme-*-
|
||||
|
||||
;; Copyright (C) 2015 Mathieu Lirzin
|
||||
;; Copyright (C) 2003 Dale Mellor
|
||||
;;
|
||||
;; This file is part of GNU mcron.
|
||||
|
|
@ -23,8 +24,11 @@
|
|||
(define-module (mcron config))
|
||||
|
||||
(define-public config-debug @CONFIG_DEBUG@)
|
||||
(define-public config-package-name "@PACKAGE_NAME@")
|
||||
(define-public config-package-version "@PACKAGE_VERSION@")
|
||||
(define-public config-package-string "@PACKAGE_STRING@")
|
||||
(define-public config-package-bugreport "@PACKAGE_BUGREPORT@")
|
||||
(define-public config-package-url "@PACKAGE_URL@")
|
||||
(define-public config-sendmail "@SENDMAIL@")
|
||||
|
||||
(define-public config-spool-dir "@CONFIG_SPOOL_DIR@")
|
||||
|
|
|
|||
|
|
@ -221,8 +221,8 @@
|
|||
;; The user is being silly. The message here is identical to the one Vixie cron
|
||||
;; used to put out, for total compatibility.
|
||||
|
||||
(else
|
||||
(mcron-error 15 "usage error: file name must be specified for replace.")))
|
||||
(else (mcron-error 15
|
||||
"usage error: file name must be specified for replace.")))
|
||||
|
||||
|
||||
)) ;; End of file-level let-scopes.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; Copyright (C) 2003 Dale Mellor
|
||||
;; Copyright (C) 2003, 2015 Dale Mellor
|
||||
;;
|
||||
;; This file is part of GNU mcron.
|
||||
;;
|
||||
|
|
@ -31,42 +31,12 @@
|
|||
|
||||
|
||||
(define-module (mcron environment)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:export (modify-environment
|
||||
clear-environment-mods
|
||||
append-environment-mods
|
||||
get-current-environment-mods-copy))
|
||||
|
||||
|
||||
|
||||
|
||||
;; The env-alist is an association list of variable names and values. Variables
|
||||
;; later in the list will take precedence over variables before. We return a
|
||||
;; fixed-up version in which some variables are given specific default values
|
||||
;; (which the user can override), and two variables which the user is not
|
||||
;; allowed to control are added at the end of the list.
|
||||
|
||||
(define (impose-default-environment env-alist passwd-entry)
|
||||
(append `(("HOME" . ,(passwd:dir passwd-entry))
|
||||
("CWD" . ,(passwd:dir passwd-entry))
|
||||
("SHELL" . ,(passwd:shell passwd-entry))
|
||||
("TERM" . #f)
|
||||
("TERMCAP" . #f))
|
||||
env-alist
|
||||
`(("LOGNAME" . ,(passwd:name passwd-entry))
|
||||
("USER" . ,(passwd:name passwd-entry)))))
|
||||
|
||||
|
||||
|
||||
|
||||
;; Modify the UNIX environment for the current process according to the given
|
||||
;; association list of variables, with the default variable values imposed.
|
||||
|
||||
(define (modify-environment env-alist passwd-entry)
|
||||
(for-each (lambda (variable)
|
||||
(setenv (car variable) (cdr variable)))
|
||||
(impose-default-environment env-alist passwd-entry)))
|
||||
|
||||
|
||||
|
||||
|
||||
;; As we parse configuration files, we build up an alist of environment
|
||||
|
|
@ -103,3 +73,24 @@
|
|||
(set! current-environment-mods (append current-environment-mods
|
||||
(list (cons name value))))
|
||||
#t)
|
||||
|
||||
|
||||
|
||||
;; Modify the UNIX environment for the current process according to the given
|
||||
;; association list of variables, with the default variable values imposed.
|
||||
|
||||
(define (modify-environment env-alist passwd-entry)
|
||||
(for-each (lambda (a) (setenv (car a) (cdr a)))
|
||||
(let ((home-dir (passwd:dir passwd-entry))
|
||||
(user-name (passwd:name passwd-entry)))
|
||||
(append
|
||||
;; Default environment variables which can be overidden by ENV.
|
||||
`(("HOME" . ,home-dir)
|
||||
("CWD" . ,home-dir)
|
||||
("SHELL" . ,(passwd:shell passwd-entry))
|
||||
("TERM" . #f)
|
||||
("TERMCAP" . #f))
|
||||
env-alist
|
||||
;; Environment variables with imposed values.
|
||||
`(("LOGNAME" . ,user-name)
|
||||
("USER" . ,user-name))))))
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
set-configuration-time
|
||||
job
|
||||
find-best-next)
|
||||
#:use-module (mcron core)
|
||||
#:use-module (mcron mcron-core)
|
||||
#:use-module (mcron environment)
|
||||
#:use-module (mcron vixie-time)
|
||||
#:re-export (append-environment-mods))
|
||||
|
|
@ -203,11 +203,16 @@
|
|||
(define configuration-user (getpw (getuid)))
|
||||
(define configuration-time (current-time))
|
||||
|
||||
|
||||
|
||||
(define (set-configuration-user user)
|
||||
(set! configuration-user (if (or (string? user)
|
||||
(integer? user))
|
||||
(getpw user)
|
||||
user)))
|
||||
|
||||
|
||||
|
||||
(define (set-configuration-time time) (set! configuration-time time))
|
||||
|
||||
|
||||
|
|
@ -233,10 +238,9 @@
|
|||
((list? action) (lambda () (primitive-eval action)))
|
||||
((string? action) (lambda () (system action)))
|
||||
(else
|
||||
(throw 'mcron-error
|
||||
2
|
||||
"job: invalid second argument (action; should be lambda"
|
||||
" function, string or list)"))))
|
||||
(throw 'mcron-error 2
|
||||
"job: invalid second argument (action; should be lambda "
|
||||
"function, string or list)"))))
|
||||
|
||||
(time-proc
|
||||
(cond ((procedure? time-proc) time-proc)
|
||||
|
|
@ -244,10 +248,9 @@
|
|||
((list? time-proc) (lambda (current-time)
|
||||
(primitive-eval time-proc)))
|
||||
(else
|
||||
(throw 'mcron-error
|
||||
3
|
||||
"job: invalid first argument (next-time-function; should ")
|
||||
"be function, string or list)")))
|
||||
(throw 'mcron-error 3
|
||||
"job: invalid first argument (next-time-function; "
|
||||
"should be function, string or list)"))))
|
||||
(displayable
|
||||
(cond ((not (null? displayable)) (car displayable))
|
||||
((procedure? action) "Lambda function")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; Copyright (C) 2003, 2012 Dale Mellor
|
||||
;; Copyright (C) 2003, 2012, 2015 Dale Mellor
|
||||
;;
|
||||
;; This file is part of GNU mcron.
|
||||
;;
|
||||
|
|
@ -16,34 +16,24 @@
|
|||
;; with GNU mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
;; This is the 'main' routine for the whole system; the top of this file is the
|
||||
;; global entry point (after the minimal C wrapper, mcron.c.template); to all
|
||||
;; intents and purposes the program is pure Guile and starts here.
|
||||
;;
|
||||
;; This file is built into mcron.c.template by the makefile, which stringifies
|
||||
;; the whole lot, and escapes quotation marks and escape characters
|
||||
;; accordingly. Bear this in mind when considering literal multi-line strings.
|
||||
;;
|
||||
;; (l0ad "crontab.scm") (sic) is inlined by the makefile. All other
|
||||
;; functionality comes through modules in .../share/guile/site/mcron/*.scm.
|
||||
(define-module (mcron main)
|
||||
#:use-module (ice-9 getopt-long)
|
||||
#:use-module (ice-9 rdelim)
|
||||
#:use-module (ice-9 regex)
|
||||
#:use-module (mcron config)
|
||||
#:use-module (mcron mcron-core)
|
||||
#:use-module (mcron job-specifier)
|
||||
#:use-module (mcron vixie-specification)
|
||||
#:use-module (srfi srfi-2)
|
||||
#:use-module (srfi srfi-26)
|
||||
#:export (delete-run-file
|
||||
main))
|
||||
|
||||
|
||||
|
||||
;; Pull in some constants set by the builder (via autoconf) at configuration
|
||||
;; time. Turn debugging on if indicated.
|
||||
|
||||
(use-modules (mcron config))
|
||||
(if config-debug (begin (debug-enable 'debug)
|
||||
(debug-enable 'backtrace)))
|
||||
|
||||
|
||||
|
||||
;; To determine the name of the program, scan the first item of the command line
|
||||
;; backwards for the first non-alphabetic character. This allows names like
|
||||
;; in.cron to be accepted as an invocation of the cron command.
|
||||
|
||||
(use-modules (ice-9 regex) (ice-9 rdelim))
|
||||
;; Extract the actual command name from \a command. This returns the last
|
||||
;; part of \a command without any non-alphabetic characters. For example
|
||||
;; "in.cron" and "./mcron" will return respectively "cron" and "mcron".
|
||||
|
||||
(define command-name (match:substring (regexp-exec (make-regexp "[[:alpha:]]*$")
|
||||
(car (command-line)))))
|
||||
|
|
@ -51,49 +41,49 @@
|
|||
|
||||
|
||||
;; Code contributed by Sergey Poznyakoff. Print an error message (made up from
|
||||
;; the parts of rest), and if the error is fatal (present and non-zero) then
|
||||
;; exit to the system with this code.
|
||||
;; the parts of \a rest), and if the \a exit-code error is fatal (present and
|
||||
;; non-zero) then exit to the system with \a exit-code.
|
||||
|
||||
(define (mcron-error exit-code . rest)
|
||||
(with-output-to-port (current-error-port)
|
||||
(lambda ()
|
||||
(for-each display (append (list command-name ": ") rest))
|
||||
(for-each display
|
||||
(cons* command-name ": " rest))
|
||||
(newline)))
|
||||
(if (and exit-code (not (eq? exit-code 0)))
|
||||
(primitive-exit exit-code)))
|
||||
(when (and exit-code
|
||||
(not (eq? exit-code 0)))
|
||||
(primitive-exit exit-code)))
|
||||
|
||||
|
||||
|
||||
;; Code contributed by Sergey Poznyakoff. Execute body. If an 'mcron-error
|
||||
;; Code contributed by Sergey Poznyakoff and improved upon by Mathieu Lirzin
|
||||
;; with newer guile features. Execute the expressions. If an 'mcron-error
|
||||
;; exception occurs, print its diagnostics and exit with its error code.
|
||||
|
||||
(defmacro catch-mcron-error (. body)
|
||||
`(catch 'mcron-error
|
||||
(lambda ()
|
||||
,@body)
|
||||
(lambda (key exit-code . msg)
|
||||
(apply mcron-error exit-code msg))))
|
||||
(define-syntax-rule (catch-mcron-error exp ...)
|
||||
(catch 'mcron-error
|
||||
(lambda () exp ...)
|
||||
(lambda (key exit-code . msg)
|
||||
(apply mcron-error exit-code msg))))
|
||||
|
||||
|
||||
|
||||
;; We will be doing a lot of testing of the command name, so it makes sense to
|
||||
;; perform the string comparisons once and for all here.
|
||||
;; One of the symbols \c mcron, \c crond or \c crontab according to the means
|
||||
;; of our invocation.
|
||||
|
||||
(define command-type (cond ((string=? command-name "mcron") 'mcron)
|
||||
((or (string=? command-name "cron")
|
||||
(string=? command-name "crond")) 'cron)
|
||||
((string=? command-name "crontab") 'crontab)
|
||||
(else
|
||||
(mcron-error 12 "The command name is invalid."))))
|
||||
(define command-type
|
||||
(let ((command=? (cute string=? command-name <>)))
|
||||
(cond ((command=? "mcron") 'mcron)
|
||||
((or (command=? "cron") (command=? "crond")) 'cron)
|
||||
((command=? "crontab") 'crontab)
|
||||
(else (mcron-error 12 "The command name is invalid.")))))
|
||||
|
||||
|
||||
|
||||
;; There are a different set of options for the crontab personality compared to
|
||||
;; all the others, with the --help and --version options common to all the
|
||||
;; There are a different set of options for the crontab personality compared
|
||||
;; to all the others, with the --help and --version options common to all the
|
||||
;; personalities.
|
||||
|
||||
(use-modules (ice-9 getopt-long))
|
||||
|
||||
(define options
|
||||
(catch
|
||||
'misc-error
|
||||
|
|
@ -120,79 +110,86 @@
|
|||
'((version (single-char #\v) (value #f))
|
||||
(help (single-char #\h) (value #f))))))
|
||||
(lambda (key func fmt args . rest)
|
||||
(mcron-error 1 (apply format (append (list #f fmt) args))))))
|
||||
|
||||
;; If the user asked for the version of this program, give it to him and get
|
||||
;; out.
|
||||
|
||||
(if (option-ref options 'version #f)
|
||||
(begin
|
||||
(display (string-append "\n
|
||||
" command-name " (" config-package-string ")\n
|
||||
Written by Dale Mellor\n
|
||||
\n
|
||||
Copyright (C) 2003, 2006, 2014 Dale Mellor\n
|
||||
This is free software; see the source for copying conditions. There is NO\n
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n
|
||||
"))
|
||||
(quit)))
|
||||
(mcron-error 1 (apply format (cons* #f fmt args))))))
|
||||
|
||||
|
||||
|
||||
;; Likewise if the user requested the help text.
|
||||
;; Display version information for \a command and quit.
|
||||
|
||||
(if (option-ref options 'help #f)
|
||||
(begin
|
||||
(display (string-append "
|
||||
Usage: " (car (command-line))
|
||||
(case command-type
|
||||
(define* (show-version #:optional (command command-name))
|
||||
(let* ((name config-package-name)
|
||||
(short-name (cadr (string-split name #\space)))
|
||||
(version config-package-version))
|
||||
(simple-format #t "~a (~a) ~a
|
||||
Copyright (C) 2015 Free Software Foundation, Inc.
|
||||
|
||||
((mcron)
|
||||
" [OPTIONS] [FILES]\n
|
||||
Run an mcron process according to the specifications in the FILES (`-' for\n
|
||||
standard input), or use all the files in ~/.config/cron (or the \n
|
||||
deprecated ~/.cron) with .guile or .vixie extensions.\n
|
||||
\n
|
||||
-v, --version Display version\n
|
||||
-h, --help Display this help message\n
|
||||
-sN, --schedule[=]N Display the next N jobs that will be run by mcron\n
|
||||
-d, --daemon Immediately detach the program from the terminal\n
|
||||
and run as a daemon process\n
|
||||
-i, --stdin=(guile|vixie) Format of data passed as standard input or\n
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.\n"
|
||||
command name version)
|
||||
(quit)))
|
||||
|
||||
|
||||
|
||||
;; Display where to get help and send bug reports.
|
||||
|
||||
(define (show-package-information)
|
||||
(simple-format #t "\nReport bugs to: ~a.
|
||||
~a home page: <~a>
|
||||
General help using GNU software: <http://www.gnu.org/gethelp/>\n"
|
||||
config-package-bugreport
|
||||
config-package-name
|
||||
config-package-url))
|
||||
|
||||
|
||||
|
||||
;; Display usage information and quit.
|
||||
|
||||
(define (show-help)
|
||||
(simple-format #t "Usage: ~a" command-name)
|
||||
(display
|
||||
(case command-type
|
||||
((mcron)
|
||||
" [OPTIONS] [FILES]
|
||||
Run an mcron process according to the specifications in the FILES (`-' for
|
||||
standard input), or use all the files in ~/.config/cron (or the
|
||||
deprecated ~/.cron) with .guile or .vixie extensions.
|
||||
|
||||
-v, --version Display version
|
||||
-h, --help Display this help message
|
||||
-sN, --schedule[=]N Display the next N jobs that will be run by mcron
|
||||
-d, --daemon Immediately detach the program from the terminal
|
||||
and run as a daemon process
|
||||
-i, --stdin=(guile|vixie) Format of data passed as standard input or
|
||||
file arguments (default guile)")
|
||||
((cron)
|
||||
" [OPTIONS]
|
||||
Unless an option is specified, run a cron daemon as a detached process,
|
||||
reading all the information in the users' crontabs and in /etc/crontab.
|
||||
|
||||
((cron)
|
||||
" [OPTIONS]\n
|
||||
Unless an option is specified, run a cron daemon as a detached process, \n
|
||||
reading all the information in the users' crontabs and in /etc/crontab.\n
|
||||
\n
|
||||
-v, --version Display version\n
|
||||
-h, --help Display this help message\n
|
||||
-sN, --schedule[=]N Display the next N jobs that will be run by cron\n
|
||||
-n, --noetc Do not check /etc/crontab for updates (HIGHLY\n
|
||||
-v, --version Display version
|
||||
-h, --help Display this help message
|
||||
-sN, --schedule[=]N Display the next N jobs that will be run by cron
|
||||
-n, --noetc Do not check /etc/crontab for updates (HIGHLY
|
||||
RECOMMENDED).")
|
||||
|
||||
((crontab)
|
||||
(string-append " [-u user] file\n"
|
||||
" " (car (command-line)) " [-u user] { -e | -l | -r }\n"
|
||||
" (default operation is replace, per 1003.2)\n"
|
||||
" -e (edit user's crontab)\n"
|
||||
" -l (list user's crontab)\n"
|
||||
" -r (delete user's crontab)\n"))
|
||||
|
||||
(else "rubbish"))
|
||||
|
||||
"\n\n
|
||||
Report bugs to " config-package-bugreport ".\n
|
||||
"))
|
||||
(quit)))
|
||||
((crontab)
|
||||
" [-u user] file
|
||||
crontab [-u user] { -e | -l | -r }
|
||||
(default operation is replace, per 1003.2)
|
||||
-e (edit user's crontab)
|
||||
-l (list user's crontab)
|
||||
-r (delete user's crontab)")
|
||||
(else "\nrubbish")))
|
||||
(newline)
|
||||
(show-package-information)
|
||||
(quit))
|
||||
|
||||
|
||||
|
||||
;; This is called from the C front-end whenever a terminal signal is
|
||||
;; received. We remove the /var/run/cron.pid file so that crontab and other
|
||||
;; invocations of cron don't get the wrong idea that a daemon is currently
|
||||
;; running.
|
||||
;; Remove the /var/run/cron.pid file so that crontab and other invocations of
|
||||
;; cron don't get the wrong idea that a daemon is currently running. This
|
||||
;; procedure is called from the C front-end whenever a terminal signal is
|
||||
;; received.
|
||||
|
||||
(define (delete-run-file)
|
||||
(catch #t (lambda () (delete-file config-pid-file)
|
||||
|
|
@ -202,47 +199,7 @@ Report bugs to " config-package-bugreport ".\n
|
|||
|
||||
|
||||
|
||||
;; Setup the cron process, if appropriate. If there is already a
|
||||
;; /var/run/cron.pid file, then we must assume a cron daemon is already running
|
||||
;; and refuse to start another one.
|
||||
;;
|
||||
;; Otherwise, clear the MAILTO environment variable so that output from cron
|
||||
;; jobs is sent to the various users (this may still be overridden in the
|
||||
;; configuration files), and call the function in the C wrapper to set up
|
||||
;; terminal signal responses to vector to the procedure above. The PID file will
|
||||
;; be filled in properly later when we have forked our daemon process (but not
|
||||
;; done if we are only viewing the schedules).
|
||||
|
||||
(if (eq? command-type 'cron)
|
||||
(begin
|
||||
(if (not (eqv? (getuid) 0))
|
||||
(mcron-error 16
|
||||
"This program must be run by the root user (and should "
|
||||
"have been installed as such)."))
|
||||
(if (access? config-pid-file F_OK)
|
||||
(mcron-error 1
|
||||
"A cron daemon is already running.\n"
|
||||
" (If you are sure this is not true, remove the file\n"
|
||||
" "
|
||||
config-pid-file
|
||||
".)"))
|
||||
(if (not (option-ref options 'schedule #f))
|
||||
(with-output-to-file config-pid-file noop))
|
||||
(setenv "MAILTO" #f)
|
||||
(c-set-cron-signals)))
|
||||
|
||||
|
||||
|
||||
;; Define the functions available to the configuration files. While we're here,
|
||||
;; we'll get the core loaded as well.
|
||||
|
||||
(use-modules (mcron core)
|
||||
(mcron job-specifier)
|
||||
(mcron vixie-specification))
|
||||
|
||||
|
||||
|
||||
;; Procedure to slurp the standard input into a string.
|
||||
;; Return standard input as a string.
|
||||
|
||||
(define (stdin->string)
|
||||
(with-output-to-string (lambda () (do ((in (read-char) (read-char)))
|
||||
|
|
@ -251,183 +208,83 @@ Report bugs to " config-package-bugreport ".\n
|
|||
|
||||
|
||||
|
||||
;; Now we have the procedures in place for dealing with the contents of
|
||||
;; configuration files, the crontab personality is able to validate such
|
||||
;; files. If the user requested the crontab personality, we load and run the
|
||||
;; code here and then get out.
|
||||
;; Return a thunk which process each file in \a directory with \a proc. The
|
||||
;; \a directory must be a directory name. The \a proc argument must be a
|
||||
;; procedure that takes one file name argument.
|
||||
|
||||
(if (eq? command-type 'crontab)
|
||||
(begin
|
||||
(load "crontab.scm")
|
||||
(quit)))
|
||||
(define (proc-in-directory directory proc)
|
||||
(let ((dir (opendir directory)))
|
||||
(do ((file-name (readdir dir) (readdir dir)))
|
||||
((eof-object? file-name) (closedir dir))
|
||||
(proc file-name))))
|
||||
|
||||
|
||||
|
||||
;; Code contributed by Sergey Poznyakoff. Determine if the given file is a
|
||||
;; regular file or not.
|
||||
;; Process \a file-name according its extension. When \a guile-syntax? is \c
|
||||
;; TRUE, force guile syntax usage. If \a file-name format is not recognized,
|
||||
;; it is silently ignored (this deals properly with most editors' backup
|
||||
;; files, for instance).
|
||||
|
||||
(define (regular-file? file)
|
||||
(catch 'system-error
|
||||
(lambda ()
|
||||
(eq? (stat:type (stat file)) 'regular))
|
||||
(lambda (key call fmt args . rest)
|
||||
(mcron-error 0 (apply format (append (list #f fmt) args)))
|
||||
#f)))
|
||||
(define process-user-file
|
||||
(let ((guile-regexp (make-regexp "\\.gui(le)?$"))
|
||||
(vixie-regexp (make-regexp "\\.vix(ie)?$")))
|
||||
(lambda* (file-path #:optional assume-guile)
|
||||
(cond ((string=? "-" file-path)
|
||||
(if (string=? (option-ref options 'stdin "guile") "vixie")
|
||||
(read-vixie-port (current-input-port))
|
||||
(eval-string (stdin->string))))
|
||||
((regexp-exec vixie-regexp file-path)
|
||||
(read-vixie-file file-path))
|
||||
((or assume-guile
|
||||
(regexp-exec guile-regexp file-path))
|
||||
(load file-path))))))
|
||||
|
||||
|
||||
|
||||
;; Procedure which processes any configuration file according to the
|
||||
;; extension. If a file is not recognized, it is silently ignored (this deals
|
||||
;; properly with most editors' backup files, for instance).
|
||||
|
||||
(define guile-file-regexp (make-regexp "\\.gui(le)?$"))
|
||||
(define vixie-file-regexp (make-regexp "\\.vix(ie)?$"))
|
||||
|
||||
(define (process-user-file file-path . assume-guile)
|
||||
(cond ((string=? file-path "-")
|
||||
(if (string=? (option-ref options 'stdin "guile") "vixie")
|
||||
(read-vixie-port (current-input-port))
|
||||
(eval-string (stdin->string))))
|
||||
((or (not (null? assume-guile))
|
||||
(regexp-exec guile-file-regexp file-path))
|
||||
(load file-path))
|
||||
((regexp-exec vixie-file-regexp file-path)
|
||||
(read-vixie-file file-path))))
|
||||
|
||||
|
||||
|
||||
;; Procedure to run through all the files in a user's ~/.cron and/or
|
||||
;; $XDG_CONFIG_HOME/cron or ~/.config/cron directories (only happens under the
|
||||
;; mcron personality).
|
||||
;; Process files in $XDG_CONFIG_HOME/cron and/or ~/.cron directories (if
|
||||
;; $XDG_CONFIG_HOME is not defined uses ~/.config/cron instead).
|
||||
|
||||
(define (process-files-in-user-directory)
|
||||
(let ((errors 0)
|
||||
(home-directory (passwd:dir (getpw (getuid)))))
|
||||
(map (lambda (config-directory)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(let ((directory (opendir config-directory)))
|
||||
(do ((file-name (readdir directory) (readdir directory)))
|
||||
((eof-object? file-name) (closedir directory))
|
||||
(process-user-file (string-append config-directory
|
||||
"/"
|
||||
file-name)))))
|
||||
(lambda (key . args)
|
||||
(set! errors (1+ errors)))))
|
||||
(list (string-append home-directory "/.cron")
|
||||
(string-append (or (getenv "XDG_CONFIG_HOME")
|
||||
(string-append home-directory "/.config"))
|
||||
"/cron")))
|
||||
(if (eq? 2 errors)
|
||||
(mcron-error 13
|
||||
"Cannot read files in your ~/.config/cron (or ~/.cron) "
|
||||
"directory."))))
|
||||
(map (lambda (dir)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(proc-in-directory
|
||||
dir
|
||||
(lambda (file-name)
|
||||
(process-user-file (string-append dir "/" file-name)))))
|
||||
(lambda (key . args)
|
||||
(set! errors (1+ errors)))))
|
||||
(list (string-append home-directory "/.cron")
|
||||
(string-append (or (getenv "XDG_CONFIG_HOME")
|
||||
(string-append home-directory "/.config"))
|
||||
"/cron")))
|
||||
(when (eq? 2 errors)
|
||||
(mcron-error 13
|
||||
"Cannot read files in your ~/.config/cron (or ~/.cron) directory."))))
|
||||
|
||||
|
||||
|
||||
;; Procedure to check that a user name is in the passwd database (it may happen
|
||||
;; that a user is removed after creating a crontab). If the user name is valid,
|
||||
;; the full passwd entry for that user is returned to the caller.
|
||||
|
||||
(define (valid-user user-name)
|
||||
(setpwent)
|
||||
(do ((entry (getpw) (getpw)))
|
||||
((or (not entry)
|
||||
(string=? (passwd:name entry) user-name))
|
||||
(endpwent)
|
||||
entry)))
|
||||
|
||||
|
||||
|
||||
;; Procedure to process all the files in the crontab directory, making sure that
|
||||
;; each file is for a legitimate user and setting the configuration-user to that
|
||||
;; user. In this way, when the job procedure is run on behalf of the
|
||||
;; configuration files, the jobs are registered with the system with the
|
||||
;; appropriate user. Note that only the root user should be able to perform this
|
||||
;; operation, but we leave it to the permissions on the /var/cron/tabs directory
|
||||
;; to enforce this.
|
||||
|
||||
(use-modules (srfi srfi-2)) ;; For and-let*.
|
||||
;; Process all the files in the crontab directory. When the job procedure is
|
||||
;; run on behalf of the configuration files, the jobs are registered on the
|
||||
;; system with the appropriate user. Only root should be able to perform this
|
||||
;; operation. The permissions on the /var/cron/tabs directory enforce this.
|
||||
|
||||
(define (process-files-in-system-directory)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(let ((directory (opendir config-spool-dir)))
|
||||
(do ((file-name (readdir directory) (readdir directory)))
|
||||
((eof-object? file-name))
|
||||
(and-let* ((user (valid-user file-name)))
|
||||
(set-configuration-user user) ;; / ?? !!!!
|
||||
(catch-mcron-error
|
||||
(read-vixie-file (string-append config-spool-dir
|
||||
"/"
|
||||
file-name)))))))
|
||||
(lambda (key . args)
|
||||
(mcron-error
|
||||
4
|
||||
"You do not have permission to access the system crontabs."))))
|
||||
|
||||
|
||||
|
||||
;; Having defined all the necessary procedures for scanning various sets of
|
||||
;; files, we perform the actual configuration of the program depending on the
|
||||
;; personality we are running as. If it is mcron, we either scan the files
|
||||
;; passed on the command line, or else all the ones in the user's .config/cron
|
||||
;; (or .cron) directory. If we are running under the cron personality, we read
|
||||
;; the /var/cron/tabs directory and also the /etc/crontab file.
|
||||
|
||||
(case command-type
|
||||
((mcron) (if (null? (option-ref options '() '()))
|
||||
(process-files-in-user-directory)
|
||||
(for-each (lambda (file-path)
|
||||
(process-user-file file-path #t))
|
||||
(option-ref options '() '()))))
|
||||
|
||||
((cron) (process-files-in-system-directory)
|
||||
(use-system-job-list)
|
||||
(catch-mcron-error
|
||||
(read-vixie-file "/etc/crontab" parse-system-vixie-line))
|
||||
(use-user-job-list)
|
||||
(if (not (option-ref options 'noetc #f))
|
||||
(begin
|
||||
(display
|
||||
"WARNING: cron will check for updates to /etc/crontab EVERY MINUTE. If you do\n
|
||||
not use this file, or you are prepared to manually restart cron whenever you\n
|
||||
make a change, then it is HIGHLY RECOMMENDED that you use the --noetc\n
|
||||
option.\n")
|
||||
(set-configuration-user "root")
|
||||
(job '(- (next-minute-from (next-minute)) 6)
|
||||
check-system-crontab
|
||||
"/etc/crontab update checker.")))))
|
||||
|
||||
|
||||
|
||||
;; If the user has requested a schedule of jobs that will run, we provide the
|
||||
;; information here and then get out.
|
||||
;;
|
||||
;; Start by determining the number of time points in the future that output is
|
||||
;; required for. This may be provided on the command line as a parameter to the
|
||||
;; --schedule option, or else we assume a default of 8. Finally, ensure that the
|
||||
;; count is some positive integer.
|
||||
|
||||
(and-let* ((count (option-ref options 'schedule #f)))
|
||||
(set! count (string->number count))
|
||||
(display (get-schedule (if (<= count 0) 1 count)))
|
||||
(quit))
|
||||
|
||||
|
||||
|
||||
;; If we are supposed to run as a daemon process (either a --daemon option has
|
||||
;; been explicitly used, or we are running as cron or crond), detach from the
|
||||
;; terminal now. If we are running as cron, we can now write the PID file.
|
||||
|
||||
(if (option-ref options 'daemon (eq? command-type 'cron))
|
||||
(begin
|
||||
(if (not (eqv? (primitive-fork) 0))
|
||||
(quit))
|
||||
(setsid)
|
||||
(if (eq? command-type 'cron)
|
||||
(with-output-to-file config-pid-file
|
||||
(lambda () (display (getpid)) (newline))))))
|
||||
(lambda ()
|
||||
(proc-in-directory
|
||||
config-spool-dir
|
||||
(lambda (user-name)
|
||||
(and-let* ((user (false-if-exception (getpwnam user-name))))
|
||||
(set-configuration-user user)
|
||||
(catch-mcron-error
|
||||
(read-vixie-file
|
||||
(string-append config-spool-dir "/" user-name)))))))
|
||||
(lambda (key . args)
|
||||
(mcron-error 4
|
||||
"You do not have permission to access the system crontabs."))))
|
||||
|
||||
|
||||
|
||||
|
|
@ -436,32 +293,30 @@ option.\n")
|
|||
;; inform the main wait-run-wait execution loop to listen for incoming messages
|
||||
;; on this socket.
|
||||
|
||||
(define fd-list '())
|
||||
|
||||
(if (eq? command-type 'cron)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(let ((socket (socket AF_UNIX SOCK_STREAM 0)))
|
||||
(bind socket AF_UNIX config-socket-file)
|
||||
(listen socket 5)
|
||||
(set! fd-list (list socket))))
|
||||
(lambda (key . args)
|
||||
(delete-file config-pid-file)
|
||||
(mcron-error 1
|
||||
"Cannot bind to UNIX socket "
|
||||
config-socket-file))))
|
||||
|
||||
(define (cron-file-descriptors)
|
||||
(if (eq? command-type 'cron)
|
||||
(catch #t
|
||||
(lambda ()
|
||||
(let ((socket (socket AF_UNIX SOCK_STREAM 0)))
|
||||
(bind socket AF_UNIX config-socket-file)
|
||||
(listen socket 5)
|
||||
(list socket)))
|
||||
(lambda (key . args)
|
||||
(delete-file config-pid-file)
|
||||
(mcron-error 1
|
||||
"Cannot bind to UNIX socket " config-socket-file)))
|
||||
'()))
|
||||
|
||||
|
||||
|
||||
;; This function is called whenever a message comes in on the above socket. We
|
||||
;; read a user name from the socket, dealing with the "/etc/crontab" special
|
||||
;; Read a user name from the socket, dealing with the /etc/crontab special
|
||||
;; case, remove all the user's jobs from the job list, and then re-read the
|
||||
;; user's updated file. In the special case we drop all the system jobs and
|
||||
;; re-read the /etc/crontab file.
|
||||
;; user's updated file. In the special case drop all the system jobs and
|
||||
;; re-read the /etc/crontab file. This function should be called whenever a
|
||||
;; message comes in on the above socket.
|
||||
|
||||
(define (process-update-request)
|
||||
(let* ((socket (car (accept (car fd-list))))
|
||||
(define (process-update-request fd-list)
|
||||
(let* ((socket (car (accept (car fd-list))))
|
||||
(user-name (read-line socket)))
|
||||
(close socket)
|
||||
(set-configuration-time (current-time))
|
||||
|
|
@ -475,29 +330,123 @@ option.\n")
|
|||
(let ((user (getpw user-name)))
|
||||
(remove-user-jobs user)
|
||||
(set-configuration-user user)
|
||||
(read-vixie-file (string-append config-spool-dir "/" user-name)))))))
|
||||
(read-vixie-file
|
||||
(string-append config-spool-dir "/" user-name)))))))
|
||||
|
||||
|
||||
;; Entry point.
|
||||
;;
|
||||
;; This is the 'main' routine for the whole system; this module is the global
|
||||
;; entry point (after the minimal C wrapper); to all intents and purposes the
|
||||
;; program is pure Guile and starts here.
|
||||
|
||||
;; Added by Sergey Poznyakoff. This no-op will collect zombie child processes
|
||||
;; as soon as they die. This is a big improvement as previously they stayed
|
||||
;; around the system until the next time mcron wakes to fire a new job off.
|
||||
(define (main . args)
|
||||
;; Added by Sergey Poznyakoff. This no-op will collect zombie child processes
|
||||
;; as soon as they die. This is a big improvement as previously they stayed
|
||||
;; around the system until the next time mcron wakes to fire a new job off.
|
||||
(when config-debug
|
||||
(debug-enable 'backtrace))
|
||||
(when (option-ref options 'version #f)
|
||||
(show-version))
|
||||
(when (option-ref options 'help #f)
|
||||
(show-help))
|
||||
|
||||
;; Setup the cron process, if appropriate. If there is already a
|
||||
;; /var/run/cron.pid file, then we must assume a cron daemon is already
|
||||
;; running and refuse to start another one.
|
||||
;;
|
||||
;; Otherwise, clear the MAILTO environment variable so that output from cron
|
||||
;; jobs is sent to the various users (this may still be overridden in the
|
||||
;; configuration files), and call the function in the C wrapper to set up
|
||||
;; terminal signal responses to vector to the procedure above. The PID file
|
||||
;; will be filled in properly later when we have forked our daemon process
|
||||
;; (but not done if we are only viewing the schedules).
|
||||
(when (eq? command-type 'cron)
|
||||
(unless (eqv? (getuid) 0)
|
||||
(mcron-error 16
|
||||
"This program must be run by the root user (and should have been "
|
||||
"installed as such)."))
|
||||
(when (access? config-pid-file F_OK)
|
||||
(mcron-error 1
|
||||
"A cron daemon is already running.\n (If you are sure this is not"
|
||||
" true, remove the file\n " config-pid-file ".)"))
|
||||
(unless (option-ref options 'schedule #f)
|
||||
(with-output-to-file config-pid-file noop))
|
||||
(setenv "MAILTO" #f)
|
||||
;; Mathieu Lirzin: At compile time, this yields a "possibly unbound
|
||||
;; variable" warning, but this is OK since it is bound in the C wrapper.
|
||||
(c-set-cron-signals))
|
||||
|
||||
;; Unfortunately it seems to interact badly with the select system call,
|
||||
;; wreaking havoc...
|
||||
;; Now we have the procedures in place for dealing with the contents of
|
||||
;; configuration files, the crontab personality is able to validate such
|
||||
;; files. If the user requested the crontab personality, we load and run the
|
||||
;; code here and then get out.
|
||||
(when (eq? command-type 'crontab)
|
||||
(load "crontab.scm")
|
||||
(quit))
|
||||
|
||||
;; (sigaction SIGCHLD (lambda (sig) noop) SA_RESTART)
|
||||
;; Having defined all the necessary procedures for scanning various sets of
|
||||
;; files, we perform the actual configuration of the program depending on
|
||||
;; the personality we are running as. If it is mcron, we either scan the
|
||||
;; files passed on the command line, or else all the ones in the user's
|
||||
;; .config/cron (or .cron) directory. If we are running under the cron
|
||||
;; personality, we read the /var/cron/tabs directory and also the
|
||||
;; /etc/crontab file.
|
||||
(case command-type
|
||||
((mcron)
|
||||
(if (null? (option-ref options '() '()))
|
||||
(process-files-in-user-directory)
|
||||
(for-each (lambda (file-path) (process-user-file file-path
|
||||
'guile-syntax))
|
||||
(option-ref options '() '()))))
|
||||
((cron)
|
||||
(process-files-in-system-directory)
|
||||
(use-system-job-list)
|
||||
(catch-mcron-error (read-vixie-file "/etc/crontab"
|
||||
parse-system-vixie-line))
|
||||
(use-user-job-list)
|
||||
(unless (option-ref options 'noetc #f)
|
||||
(display "\
|
||||
WARNING: cron will check for updates to /etc/crontab EVERY MINUTE. If you do
|
||||
not use this file, or you are prepared to manually restart cron whenever you
|
||||
make a change, then it is HIGHLY RECOMMENDED that you use the --noetc
|
||||
option.\n")
|
||||
(set-configuration-user "root")
|
||||
(job '(- (next-minute-from (next-minute)) 6)
|
||||
check-system-crontab
|
||||
"/etc/crontab update checker."))))
|
||||
|
||||
;; If the user has requested a schedule of jobs that will run, we provide
|
||||
;; the information here and then get out. Start by determining the number
|
||||
;; of time points in the future that output is required for. This may be
|
||||
;; provided on the command line as a parameter to the --schedule option, or
|
||||
;; else we assume a default of 8. Finally, ensure that the count is some
|
||||
;; positive integer.
|
||||
(and-let* ((count (option-ref options 'schedule #f)))
|
||||
(set! count (string->number count))
|
||||
(display (get-schedule (max 1 count)))
|
||||
(quit))
|
||||
|
||||
|
||||
;; Now the main loop. Forever execute the run-job-loop procedure in the mcron
|
||||
;; core, and when it drops out (can only be because a message has come in on the
|
||||
;; socket) we process the socket request before restarting the loop again.
|
||||
;; Sergey Poznyakoff: we can also drop out of run-job-loop because of a SIGCHLD,
|
||||
;; so must test fd-list.
|
||||
|
||||
(catch-mcron-error
|
||||
(while #t
|
||||
(run-job-loop fd-list)
|
||||
(if (not (null? fd-list))
|
||||
(process-update-request))))
|
||||
;; If we are supposed to run as a daemon process (either a --daemon option
|
||||
;; has been explicitly used, or we are running as cron or crond), detach
|
||||
;; from the terminal now. If we are running as cron, we can now write the
|
||||
;; PID file.
|
||||
(when (option-ref options 'daemon (eq? command-type 'cron))
|
||||
(unless (eqv? (primitive-fork) 0)
|
||||
(quit))
|
||||
(setsid)
|
||||
(when (eq? command-type 'cron)
|
||||
(with-output-to-file config-pid-file
|
||||
(lambda () (display (getpid)) (newline)))))
|
||||
|
||||
;; Now the main loop. Forever execute the run-job-loop procedure in the
|
||||
;; mcron core, and when it drops out (can only be because a message has come
|
||||
;; in on the socket) we process the socket request before restarting the
|
||||
;; loop again. Sergey Poznyakoff: we can also drop out of run-job-loop
|
||||
;; because of a SIGCHLD, so must test fd-list.
|
||||
(catch-mcron-error
|
||||
(let ((fd-list (cron-file-descriptors)))
|
||||
(while #t
|
||||
(run-job-loop fd-list)
|
||||
(unless (null? fd-list)
|
||||
(process-update-request fd-list))))))
|
||||
|
|
|
|||
|
|
@ -1,15 +1,60 @@
|
|||
EXTRA_DIST = main.scm mcron-core.scm vixie-specification.scm \
|
||||
crontab.scm environment.scm job-specifier.scm redirect.scm \
|
||||
vixie-time.scm
|
||||
## Makefile for the scm/mcron directory of mcron.
|
||||
|
||||
pkgdata_DATA = core.scm environment.scm job-specifier.scm redirect.scm \
|
||||
vixie-time.scm vixie-specification.scm config.scm
|
||||
# Copyright (C) 2015 Mathieu Lirzin
|
||||
#
|
||||
# This file is part of GNU mcron.
|
||||
#
|
||||
# GNU mcron 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 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# GNU mcron 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
|
||||
# GNU mcron. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
## Process this file with automake to produce makefile.in.
|
||||
|
||||
|
||||
# If you're wondering, the configure script keeps deleting all files with a name
|
||||
# like core.*, so we have to keep re-making it (I lost a good day's work because
|
||||
# of this).
|
||||
MODULES = environment.scm \
|
||||
job-specifier.scm \
|
||||
main.scm \
|
||||
mcron-core.scm \
|
||||
redirect.scm \
|
||||
vixie-specification.scm \
|
||||
vixie-time.scm
|
||||
|
||||
core.scm : mcron-core.scm
|
||||
$(CP) mcron-core.scm core.scm
|
||||
GOBJECTS = $(MODULES:%.scm=%.go) config.go
|
||||
|
||||
nobase_dist_guilemodule_DATA = $(MODULES) crontab.scm
|
||||
nobase_nodist_guilemodule_DATA = $(GOBJECTS) config.scm
|
||||
|
||||
CLEANFILES = $(GOBJECTS)
|
||||
|
||||
AM_V_GUILEC = $(AM_V_GUILEC_$(V))
|
||||
AM_V_GUILEC_ = $(AM_V_GUILEC_$(AM_DEFAULT_VERBOSITY))
|
||||
AM_V_GUILEC_0 = @echo " GUILEC" $@;
|
||||
|
||||
# Unset 'GUILE_LOAD_COMPILED_PATH' altogether while compiling. Otherwise, if
|
||||
# $GUILE_LOAD_COMPILED_PATH contains $(moduledir), we may find .go files in
|
||||
# there that are newer than the local .scm files (for instance because the
|
||||
# user ran 'make install' recently). When that happens, we end up loading
|
||||
# those previously-installed .go files, which may be stale, thereby breaking
|
||||
# the whole thing.
|
||||
#
|
||||
# XXX: Use the C locale for when Guile lacks
|
||||
# <http://git.sv.gnu.org/cgit/guile.git/commit/?h=stable-2.0&id=e2c6bf3866d1186c60bacfbd4fe5037087ee5e3f>.
|
||||
.scm.go:
|
||||
$(AM_V_GUILEC)$(MKDIR_P) `dirname "$@"` ; \
|
||||
unset GUILE_LOAD_COMPILED_PATH ; \
|
||||
LC_ALL=C \
|
||||
$(GUILD) compile \
|
||||
-L "$(top_builddir)/scm" -L "$(top_srcdir)/scm" \
|
||||
-Wformat -Wunbound-variable -Warity-mismatch \
|
||||
--target="$(host)" \
|
||||
-o "$@" "$<"
|
||||
|
||||
SUFFIXES = .go
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
;; Copyright (C) 2003 Dale Mellor
|
||||
;; Copyright (C) 2003, 2015 Dale Mellor
|
||||
;;
|
||||
;; This file is part of GNU mcron.
|
||||
;;
|
||||
|
|
@ -17,8 +17,9 @@
|
|||
|
||||
|
||||
|
||||
(define-module (mcron core)
|
||||
(define-module (mcron mcron-core)
|
||||
#:use-module (mcron environment)
|
||||
#:use-module (srfi srfi-9)
|
||||
#:export (add-job
|
||||
remove-user-jobs
|
||||
get-schedule
|
||||
|
|
@ -38,7 +39,7 @@
|
|||
|
||||
;; The list of all jobs known to the system. Each element of the list is
|
||||
;;
|
||||
;; (vector user next-time-function action environment displayable next-time)
|
||||
;; (make-job user next-time-function action environment displayable next-time)
|
||||
;;
|
||||
;; where action must be a procedure, and the environment is an alist of
|
||||
;; modifications that need making to the UNIX environment before the action is
|
||||
|
|
@ -60,18 +61,17 @@
|
|||
(define (use-system-job-list) (set! configuration-source 'system))
|
||||
(define (use-user-job-list) (set! configuration-source 'user))
|
||||
|
||||
|
||||
|
||||
;; Convenience functions for getting and setting the elements of a job object.
|
||||
|
||||
(define (job:user job) (vector-ref job 0))
|
||||
(define (job:next-time-function job) (vector-ref job 1))
|
||||
(define (job:action job) (vector-ref job 2))
|
||||
(define (job:environment job) (vector-ref job 3))
|
||||
(define (job:displayable job) (vector-ref job 4))
|
||||
(define (job:next-time job) (vector-ref job 5))
|
||||
|
||||
|
||||
;; A cron job.
|
||||
(define-record-type <job>
|
||||
(make-job user time-proc action environment displayable next-time)
|
||||
job?
|
||||
(user job:user) ;string : user passwd entry
|
||||
(time-proc job:next-time-function) ;proc : with one 'time' parameter
|
||||
(action job:action) ;thunk : user's code
|
||||
(environment job:environment) ;alist : environment variables
|
||||
(displayable job:displayable) ;string : visible in schedule
|
||||
(next-time job:next-time ;number : time in UNIX format
|
||||
job:next-time-set!))
|
||||
|
||||
;; Remove jobs from the user-job-list belonging to this user.
|
||||
|
||||
|
|
@ -97,12 +97,12 @@
|
|||
|
||||
(define (add-job time-proc action displayable configuration-time
|
||||
configuration-user)
|
||||
(let ((entry (vector configuration-user
|
||||
time-proc
|
||||
action
|
||||
(get-current-environment-mods-copy)
|
||||
displayable
|
||||
(time-proc configuration-time))))
|
||||
(let ((entry (make-job configuration-user
|
||||
time-proc
|
||||
action
|
||||
(get-current-environment-mods-copy)
|
||||
displayable
|
||||
(time-proc configuration-time))))
|
||||
(if (eq? configuration-source 'user)
|
||||
(set! user-job-list (cons entry user-job-list))
|
||||
(set! system-job-list (cons entry system-job-list)))))
|
||||
|
|
@ -165,18 +165,17 @@
|
|||
(lambda ()
|
||||
(do ((count count (- count 1)))
|
||||
((eqv? count 0))
|
||||
(and-let* ((next-jobs (find-next-jobs))
|
||||
(time (car next-jobs))
|
||||
(date-string (strftime "%c %z\n" (localtime time))))
|
||||
(for-each (lambda (job)
|
||||
(display date-string)
|
||||
(display (job:displayable job))
|
||||
(newline)(newline)
|
||||
(vector-set! job
|
||||
5
|
||||
((job:next-time-function job)
|
||||
(job:next-time job))))
|
||||
(cdr next-jobs)))))))
|
||||
(and-let*
|
||||
((next-jobs (find-next-jobs))
|
||||
(time (car next-jobs))
|
||||
(date-string (strftime "%c %z\n" (localtime time))))
|
||||
(for-each (lambda (job)
|
||||
(display date-string)
|
||||
(display (job:displayable job))
|
||||
(newline)(newline)
|
||||
(job:next-time-set! job ((job:next-time-function job)
|
||||
(job:next-time job))))
|
||||
(cdr next-jobs)))))))
|
||||
|
||||
|
||||
|
||||
|
|
@ -195,22 +194,21 @@
|
|||
;; to run.
|
||||
|
||||
(define (run-jobs jobs-list)
|
||||
(for-each (lambda (job)
|
||||
(if (eqv? (primitive-fork) 0)
|
||||
(begin
|
||||
(setgid (passwd:gid (job:user job)))
|
||||
(setuid (passwd:uid (job:user job)))
|
||||
(chdir (passwd:dir (job:user job)))
|
||||
(modify-environment (job:environment job) (job:user job))
|
||||
((job:action job))
|
||||
(primitive-exit 0))
|
||||
(begin
|
||||
(set! number-children (+ number-children 1))
|
||||
(vector-set! job
|
||||
5
|
||||
((job:next-time-function job)
|
||||
(current-time))))))
|
||||
jobs-list))
|
||||
(for-each
|
||||
(lambda (job)
|
||||
(if (eqv? (primitive-fork) 0)
|
||||
(begin
|
||||
(setgid (passwd:gid (job:user job)))
|
||||
(setuid (passwd:uid (job:user job)))
|
||||
(chdir (passwd:dir (job:user job)))
|
||||
(modify-environment (job:environment job) (job:user job))
|
||||
((job:action job))
|
||||
(primitive-exit 0))
|
||||
(begin
|
||||
(set! number-children (+ number-children 1))
|
||||
(job:next-time-set! job ((job:next-time-function job)
|
||||
(current-time))))))
|
||||
jobs-list))
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
(define-module (mcron redirect)
|
||||
#:export (with-mail-out)
|
||||
#:use-module (ice-9 regex)
|
||||
#:use-module ((mcron config) :select (config-sendmail))
|
||||
#:use-module (mcron vixie-time))
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
read-vixie-file
|
||||
check-system-crontab)
|
||||
#:use-module ((mcron config) :select (config-socket-file))
|
||||
#:use-module (mcron core)
|
||||
#:use-module (mcron mcron-core)
|
||||
#:use-module (mcron job-specifier)
|
||||
#:use-module (mcron redirect)
|
||||
#:use-module (mcron vixie-time))
|
||||
|
|
@ -162,13 +162,11 @@
|
|||
(parse-vixie-environment line)
|
||||
(parse-vixie-line line)))
|
||||
(lambda (key exit-code . msg)
|
||||
(throw
|
||||
'mcron-error
|
||||
exit-code
|
||||
(apply string-append
|
||||
(number->string report-line)
|
||||
": "
|
||||
msg)))))))))
|
||||
(throw 'mcron-error exit-code
|
||||
(apply string-append
|
||||
(number->string report-line)
|
||||
": "
|
||||
msg)))))))))
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue